aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1997-09-07 05:04:48 +0000
committerBruce Momjian <bruce@momjian.us>1997-09-07 05:04:48 +0000
commit1ccd423235a48739d6f7a4d7889705b5f9ecc69b (patch)
tree8001c4e839dfad8f29ceda7f8c5f5dbb8759b564
parent8fecd4febf8357f3cc20383ed29ced484877d5ac (diff)
downloadpostgresql-1ccd423235a48739d6f7a4d7889705b5f9ecc69b.tar.gz
postgresql-1ccd423235a48739d6f7a4d7889705b5f9ecc69b.zip
Massive commit to run PGINDENT on all *.c and *.h files.
-rw-r--r--contrib/array/array_iterator.c321
-rw-r--r--contrib/datetime/datetime_functions.c113
-rw-r--r--contrib/int8/int8.c378
-rw-r--r--contrib/pginterface/halt.c54
-rw-r--r--contrib/pginterface/halt.h3
-rw-r--r--contrib/pginterface/pginsert.c80
-rw-r--r--contrib/pginterface/pginterface.c147
-rw-r--r--contrib/pginterface/pginterface.h14
-rw-r--r--contrib/pginterface/pgnulltest.c126
-rw-r--r--contrib/pginterface/pgwordcount.c34
-rw-r--r--contrib/soundex/soundex.c142
-rw-r--r--contrib/string/string_io.c518
-rw-r--r--src/backend/access/common/heaptuple.c1603
-rw-r--r--src/backend/access/common/heapvalid.c206
-rw-r--r--src/backend/access/common/indextuple.c758
-rw-r--r--src/backend/access/common/indexvalid.c104
-rw-r--r--src/backend/access/common/printtup.c431
-rw-r--r--src/backend/access/common/scankey.c54
-rw-r--r--src/backend/access/common/tupdesc.c890
-rw-r--r--src/backend/access/gist/gist.c2267
-rw-r--r--src/backend/access/gist/gistget.c644
-rw-r--r--src/backend/access/gist/gistscan.c620
-rw-r--r--src/backend/access/gist/giststrat.c123
-rw-r--r--src/backend/access/hash/hash.c767
-rw-r--r--src/backend/access/hash/hashfunc.c411
-rw-r--r--src/backend/access/hash/hashinsert.c386
-rw-r--r--src/backend/access/hash/hashovfl.c1065
-rw-r--r--src/backend/access/hash/hashpage.c1107
-rw-r--r--src/backend/access/hash/hashscan.c229
-rw-r--r--src/backend/access/hash/hashsearch.c758
-rw-r--r--src/backend/access/hash/hashstrat.c69
-rw-r--r--src/backend/access/hash/hashutil.c161
-rw-r--r--src/backend/access/heap/heapam.c2531
-rw-r--r--src/backend/access/heap/hio.c229
-rw-r--r--src/backend/access/heap/stats.c531
-rw-r--r--src/backend/access/index/genam.c328
-rw-r--r--src/backend/access/index/indexam.c474
-rw-r--r--src/backend/access/index/istrat.c1095
-rw-r--r--src/backend/access/nbtree/nbtcompare.c201
-rw-r--r--src/backend/access/nbtree/nbtinsert.c2923
-rw-r--r--src/backend/access/nbtree/nbtpage.c902
-rw-r--r--src/backend/access/nbtree/nbtree.c927
-rw-r--r--src/backend/access/nbtree/nbtscan.c267
-rw-r--r--src/backend/access/nbtree/nbtsearch.c2617
-rw-r--r--src/backend/access/nbtree/nbtsort.c1926
-rw-r--r--src/backend/access/nbtree/nbtstrat.c156
-rw-r--r--src/backend/access/nbtree/nbtutils.c623
-rw-r--r--src/backend/access/rtree/rtget.c544
-rw-r--r--src/backend/access/rtree/rtproc.c209
-rw-r--r--src/backend/access/rtree/rtree.c1753
-rw-r--r--src/backend/access/rtree/rtscan.c626
-rw-r--r--src/backend/access/rtree/rtstrat.c346
-rw-r--r--src/backend/access/transam/transam.c964
-rw-r--r--src/backend/access/transam/transsup.c1065
-rw-r--r--src/backend/access/transam/varsup.c1019
-rw-r--r--src/backend/access/transam/xact.c2014
-rw-r--r--src/backend/access/transam/xid.c94
-rw-r--r--src/backend/bootstrap/bootstrap.c1683
-rw-r--r--src/backend/catalog/catalog.c253
-rw-r--r--src/backend/catalog/heap.c2747
-rw-r--r--src/backend/catalog/index.c3019
-rw-r--r--src/backend/catalog/indexing.c808
-rw-r--r--src/backend/catalog/pg_aggregate.c555
-rw-r--r--src/backend/catalog/pg_operator.c1926
-rw-r--r--src/backend/catalog/pg_proc.c445
-rw-r--r--src/backend/catalog/pg_type.c1013
-rw-r--r--src/backend/commands/_deadcode/version.c369
-rw-r--r--src/backend/commands/async.c831
-rw-r--r--src/backend/commands/cluster.c580
-rw-r--r--src/backend/commands/command.c827
-rw-r--r--src/backend/commands/copy.c1884
-rw-r--r--src/backend/commands/creatinh.c1112
-rw-r--r--src/backend/commands/defind.c899
-rw-r--r--src/backend/commands/define.c1113
-rw-r--r--src/backend/commands/explain.c353
-rw-r--r--src/backend/commands/purge.c271
-rw-r--r--src/backend/commands/recipe.c2130
-rw-r--r--src/backend/commands/remove.c796
-rw-r--r--src/backend/commands/rename.c401
-rw-r--r--src/backend/commands/sequence.c924
-rw-r--r--src/backend/commands/trigger.c1050
-rw-r--r--src/backend/commands/vacuum.c3920
-rw-r--r--src/backend/commands/view.c427
-rw-r--r--src/backend/executor/execAmi.c693
-rw-r--r--src/backend/executor/execFlatten.c372
-rw-r--r--src/backend/executor/execJunk.c638
-rw-r--r--src/backend/executor/execMain.c2324
-rw-r--r--src/backend/executor/execProcnode.c820
-rw-r--r--src/backend/executor/execQual.c2665
-rw-r--r--src/backend/executor/execScan.c208
-rw-r--r--src/backend/executor/execTuples.c1526
-rw-r--r--src/backend/executor/execUtils.c1816
-rw-r--r--src/backend/executor/functions.c695
-rw-r--r--src/backend/executor/nodeAgg.c1055
-rw-r--r--src/backend/executor/nodeAppend.c852
-rw-r--r--src/backend/executor/nodeGroup.c632
-rw-r--r--src/backend/executor/nodeHash.c1420
-rw-r--r--src/backend/executor/nodeHashjoin.c1377
-rw-r--r--src/backend/executor/nodeIndexscan.c1623
-rw-r--r--src/backend/executor/nodeMaterial.c631
-rw-r--r--src/backend/executor/nodeMergejoin.c2165
-rw-r--r--src/backend/executor/nodeNestloop.c632
-rw-r--r--src/backend/executor/nodeResult.c454
-rw-r--r--src/backend/executor/nodeSeqscan.c726
-rw-r--r--src/backend/executor/nodeSort.c632
-rw-r--r--src/backend/executor/nodeTee.c899
-rw-r--r--src/backend/executor/nodeUnique.c532
-rw-r--r--src/backend/executor/spi.c1537
-rw-r--r--src/backend/lib/bit.c27
-rw-r--r--src/backend/lib/dllist.c246
-rw-r--r--src/backend/lib/fstack.c146
-rw-r--r--src/backend/lib/hasht.c48
-rw-r--r--src/backend/lib/lispsort.c67
-rw-r--r--src/backend/lib/qsort.c186
-rw-r--r--src/backend/lib/stringinfo.c142
-rw-r--r--src/backend/libpq/auth.c838
-rw-r--r--src/backend/libpq/be-dumpdata.c448
-rw-r--r--src/backend/libpq/be-fsstubs.c470
-rw-r--r--src/backend/libpq/be-pqexec.c613
-rw-r--r--src/backend/libpq/hba.c1336
-rw-r--r--src/backend/libpq/password.c190
-rw-r--r--src/backend/libpq/portal.c946
-rw-r--r--src/backend/libpq/portalbuf.c609
-rw-r--r--src/backend/libpq/pqcomm.c1016
-rw-r--r--src/backend/libpq/pqcomprim.c230
-rw-r--r--src/backend/libpq/pqpacket.c361
-rw-r--r--src/backend/libpq/pqsignal.c78
-rw-r--r--src/backend/libpq/util.c98
-rw-r--r--src/backend/main/main.c71
-rw-r--r--src/backend/nodes/copyfuncs.c2634
-rw-r--r--src/backend/nodes/equalfuncs.c1149
-rw-r--r--src/backend/nodes/list.c685
-rw-r--r--src/backend/nodes/makefuncs.c139
-rw-r--r--src/backend/nodes/nodeFuncs.c119
-rw-r--r--src/backend/nodes/nodes.c36
-rw-r--r--src/backend/nodes/outfuncs.c2640
-rw-r--r--src/backend/nodes/print.c582
-rw-r--r--src/backend/nodes/read.c421
-rw-r--r--src/backend/nodes/readfuncs.c3199
-rw-r--r--src/backend/optimizer/geqo/geqo_copy.c40
-rw-r--r--src/backend/optimizer/geqo/geqo_cx.c132
-rw-r--r--src/backend/optimizer/geqo/geqo_erx.c567
-rw-r--r--src/backend/optimizer/geqo/geqo_eval.c985
-rw-r--r--src/backend/optimizer/geqo/geqo_main.c249
-rw-r--r--src/backend/optimizer/geqo/geqo_misc.c347
-rw-r--r--src/backend/optimizer/geqo/geqo_mutation.c65
-rw-r--r--src/backend/optimizer/geqo/geqo_ox1.c122
-rw-r--r--src/backend/optimizer/geqo/geqo_ox2.c146
-rw-r--r--src/backend/optimizer/geqo/geqo_params.c268
-rw-r--r--src/backend/optimizer/geqo/geqo_paths.c190
-rw-r--r--src/backend/optimizer/geqo/geqo_pmx.c281
-rw-r--r--src/backend/optimizer/geqo/geqo_pool.c301
-rw-r--r--src/backend/optimizer/geqo/geqo_px.c121
-rw-r--r--src/backend/optimizer/geqo/geqo_recombination.c93
-rw-r--r--src/backend/optimizer/geqo/geqo_selection.c88
-rw-r--r--src/backend/optimizer/geqo/minspantree.c317
-rw-r--r--src/backend/optimizer/path/allpaths.c609
-rw-r--r--src/backend/optimizer/path/clausesel.c536
-rw-r--r--src/backend/optimizer/path/costsize.c624
-rw-r--r--src/backend/optimizer/path/hashutils.c174
-rw-r--r--src/backend/optimizer/path/indxpath.c2113
-rw-r--r--src/backend/optimizer/path/joinpath.c1097
-rw-r--r--src/backend/optimizer/path/joinrels.c884
-rw-r--r--src/backend/optimizer/path/joinutils.c679
-rw-r--r--src/backend/optimizer/path/mergeutils.c170
-rw-r--r--src/backend/optimizer/path/orindxpath.c430
-rw-r--r--src/backend/optimizer/path/predmig.c1064
-rw-r--r--src/backend/optimizer/path/prune.c284
-rw-r--r--src/backend/optimizer/path/xfunc.c2192
-rw-r--r--src/backend/optimizer/plan/createplan.c2005
-rw-r--r--src/backend/optimizer/plan/initsplan.c579
-rw-r--r--src/backend/optimizer/plan/planmain.c952
-rw-r--r--src/backend/optimizer/plan/planner.c635
-rw-r--r--src/backend/optimizer/plan/setrefs.c1148
-rw-r--r--src/backend/optimizer/prep/archive.c61
-rw-r--r--src/backend/optimizer/prep/prepqual.c980
-rw-r--r--src/backend/optimizer/prep/preptlist.c544
-rw-r--r--src/backend/optimizer/prep/prepunion.c628
-rw-r--r--src/backend/optimizer/util/clauseinfo.c259
-rw-r--r--src/backend/optimizer/util/clauses.c1026
-rw-r--r--src/backend/optimizer/util/indexnode.c113
-rw-r--r--src/backend/optimizer/util/internal.c48
-rw-r--r--src/backend/optimizer/util/joininfo.c132
-rw-r--r--src/backend/optimizer/util/keys.c261
-rw-r--r--src/backend/optimizer/util/ordering.c154
-rw-r--r--src/backend/optimizer/util/pathnode.c867
-rw-r--r--src/backend/optimizer/util/plancat.c969
-rw-r--r--src/backend/optimizer/util/relnode.c182
-rw-r--r--src/backend/optimizer/util/tlist.c834
-rw-r--r--src/backend/optimizer/util/var.c308
-rw-r--r--src/backend/parser/analyze.c4324
-rw-r--r--src/backend/parser/catalog_utils.c2457
-rw-r--r--src/backend/parser/dbcommands.c409
-rw-r--r--src/backend/parser/keywords.c366
-rw-r--r--src/backend/parser/parse_query.c1340
-rw-r--r--src/backend/parser/parser.c844
-rw-r--r--src/backend/parser/scansup.c173
-rw-r--r--src/backend/parser/sysfunc.c51
-rw-r--r--src/backend/port/BSD44_derived/dl.c56
-rw-r--r--src/backend/port/BSD44_derived/port-protos.h26
-rw-r--r--src/backend/port/aix/dlfcn.c393
-rw-r--r--src/backend/port/aix/dlfcn.h37
-rw-r--r--src/backend/port/aix/port-protos.h8
-rw-r--r--src/backend/port/alpha/port-protos.h14
-rw-r--r--src/backend/port/alpha/port.c23
-rw-r--r--src/backend/port/bsdi/dynloader.c123
-rw-r--r--src/backend/port/bsdi/port-protos.h24
-rw-r--r--src/backend/port/dgux/dynloader.c120
-rw-r--r--src/backend/port/dgux/port-protos.h18
-rw-r--r--src/backend/port/dgux/port.c4
-rw-r--r--src/backend/port/hpux/dynloader.c36
-rw-r--r--src/backend/port/hpux/fixade.h63
-rw-r--r--src/backend/port/hpux/port-protos.h20
-rw-r--r--src/backend/port/hpux/port.c32
-rw-r--r--src/backend/port/hpux/rusagestub.h23
-rw-r--r--src/backend/port/i386_solaris/port-protos.h20
-rw-r--r--src/backend/port/i386_solaris/port.c76
-rw-r--r--src/backend/port/i386_solaris/rusagestub.h25
-rw-r--r--src/backend/port/inet_aton.c96
-rw-r--r--src/backend/port/inet_aton.h2
-rw-r--r--src/backend/port/irix5/port-protos.h16
-rw-r--r--src/backend/port/irix5/port.c6
-rw-r--r--src/backend/port/linux/dynloader.c128
-rw-r--r--src/backend/port/linux/port-protos.h32
-rw-r--r--src/backend/port/linux/port.c4
-rw-r--r--src/backend/port/linuxalpha/machine.h4
-rw-r--r--src/backend/port/linuxalpha/port-protos.h16
-rw-r--r--src/backend/port/linuxalpha/port.c4
-rw-r--r--src/backend/port/nextstep/dynloader.c97
-rw-r--r--src/backend/port/nextstep/port-protos.h24
-rw-r--r--src/backend/port/nextstep/port.c75
-rw-r--r--src/backend/port/sco/port-protos.h16
-rw-r--r--src/backend/port/sco/port.c73
-rw-r--r--src/backend/port/sco/rusagestub.h23
-rw-r--r--src/backend/port/sparc_solaris/port-protos.h28
-rw-r--r--src/backend/port/sparc_solaris/port.c81
-rw-r--r--src/backend/port/sparc_solaris/rusagestub.h25
-rw-r--r--src/backend/port/strerror.c27
-rw-r--r--src/backend/port/sunos4/float.h26
-rw-r--r--src/backend/port/sunos4/port-protos.h18
-rw-r--r--src/backend/port/sunos4/strtol.c96
-rw-r--r--src/backend/port/svr4/port-protos.h18
-rw-r--r--src/backend/port/svr4/port.c98
-rw-r--r--src/backend/port/svr4/rusagestub.h23
-rw-r--r--src/backend/port/ultrix4/dl.h143
-rw-r--r--src/backend/port/ultrix4/dynloader.c85
-rw-r--r--src/backend/port/ultrix4/port-protos.h24
-rw-r--r--src/backend/port/ultrix4/port.c8
-rw-r--r--src/backend/port/ultrix4/strdup.c14
-rw-r--r--src/backend/port/univel/frontend-port-protos.h12
-rw-r--r--src/backend/port/univel/port-protos.h22
-rw-r--r--src/backend/port/univel/port.c111
-rw-r--r--src/backend/port/univel/rusagestub.h23
-rw-r--r--src/backend/postmaster/postmaster.c1949
-rw-r--r--src/backend/regex/engine.c823
-rw-r--r--src/backend/regex/regcomp.c1114
-rw-r--r--src/backend/regex/regerror.c197
-rw-r--r--src/backend/regex/regexec.c156
-rw-r--r--src/backend/regex/regfree.c47
-rw-r--r--src/backend/rewrite/locks.c173
-rw-r--r--src/backend/rewrite/rewriteDefine.c399
-rw-r--r--src/backend/rewrite/rewriteHandler.c1066
-rw-r--r--src/backend/rewrite/rewriteManip.c707
-rw-r--r--src/backend/rewrite/rewriteRemove.c257
-rw-r--r--src/backend/rewrite/rewriteSupport.c428
-rw-r--r--src/backend/storage/buffer/buf_init.c407
-rw-r--r--src/backend/storage/buffer/buf_table.c217
-rw-r--r--src/backend/storage/buffer/bufmgr.c2695
-rw-r--r--src/backend/storage/buffer/freelist.c373
-rw-r--r--src/backend/storage/buffer/localbuf.c370
-rw-r--r--src/backend/storage/file/fd.c1177
-rw-r--r--src/backend/storage/ipc/ipc.c991
-rw-r--r--src/backend/storage/ipc/ipci.c178
-rw-r--r--src/backend/storage/ipc/s_lock.c384
-rw-r--r--src/backend/storage/ipc/shmem.c951
-rw-r--r--src/backend/storage/ipc/shmqueue.c274
-rw-r--r--src/backend/storage/ipc/sinval.c222
-rw-r--r--src/backend/storage/ipc/sinvaladt.c1129
-rw-r--r--src/backend/storage/ipc/spin.c246
-rw-r--r--src/backend/storage/large_object/inv_api.c1877
-rw-r--r--src/backend/storage/lmgr/lmgr.c1129
-rw-r--r--src/backend/storage/lmgr/lock.c2137
-rw-r--r--src/backend/storage/lmgr/multi.c615
-rw-r--r--src/backend/storage/lmgr/proc.c1117
-rw-r--r--src/backend/storage/lmgr/single.c93
-rw-r--r--src/backend/storage/page/bufpage.c670
-rw-r--r--src/backend/storage/page/itemptr.c25
-rw-r--r--src/backend/storage/smgr/md.c1088
-rw-r--r--src/backend/storage/smgr/mm.c761
-rw-r--r--src/backend/storage/smgr/smgr.c432
-rw-r--r--src/backend/storage/smgr/smgrtype.c66
-rw-r--r--src/backend/tcop/aclchk.c952
-rw-r--r--src/backend/tcop/dest.c502
-rw-r--r--src/backend/tcop/fastpath.c520
-rw-r--r--src/backend/tcop/postgres.c2789
-rw-r--r--src/backend/tcop/pquery.c563
-rw-r--r--src/backend/tcop/utility.c1212
-rw-r--r--src/backend/tcop/variable.c598
-rw-r--r--src/backend/tioga/Arr_TgRecipe.h68
-rw-r--r--src/backend/tioga/Varray.c54
-rw-r--r--src/backend/tioga/Varray.h33
-rw-r--r--src/backend/tioga/tgRecipe.c1172
-rw-r--r--src/backend/tioga/tgRecipe.h181
-rw-r--r--src/backend/utils/adt/acl.c979
-rw-r--r--src/backend/utils/adt/arrayfuncs.c2706
-rw-r--r--src/backend/utils/adt/arrayutils.c123
-rw-r--r--src/backend/utils/adt/bool.c58
-rw-r--r--src/backend/utils/adt/cash.c734
-rw-r--r--src/backend/utils/adt/char.c518
-rw-r--r--src/backend/utils/adt/chunk.c989
-rw-r--r--src/backend/utils/adt/date.c1421
-rw-r--r--src/backend/utils/adt/datetime.c667
-rw-r--r--src/backend/utils/adt/datum.c221
-rw-r--r--src/backend/utils/adt/dt.c6008
-rw-r--r--src/backend/utils/adt/filename.c187
-rw-r--r--src/backend/utils/adt/float.c2140
-rw-r--r--src/backend/utils/adt/geo_ops.c5111
-rw-r--r--src/backend/utils/adt/geo_selfuncs.c142
-rw-r--r--src/backend/utils/adt/int.c641
-rw-r--r--src/backend/utils/adt/like.c287
-rw-r--r--src/backend/utils/adt/misc.c73
-rw-r--r--src/backend/utils/adt/nabstime.c682
-rw-r--r--src/backend/utils/adt/name.c242
-rw-r--r--src/backend/utils/adt/not_in.c148
-rw-r--r--src/backend/utils/adt/numutils.c687
-rw-r--r--src/backend/utils/adt/oid.c153
-rw-r--r--src/backend/utils/adt/oidint2.c110
-rw-r--r--src/backend/utils/adt/oidint4.c139
-rw-r--r--src/backend/utils/adt/oidname.c115
-rw-r--r--src/backend/utils/adt/oracle_compat.c714
-rw-r--r--src/backend/utils/adt/regexp.c398
-rw-r--r--src/backend/utils/adt/regproc.c229
-rw-r--r--src/backend/utils/adt/selfuncs.c962
-rw-r--r--src/backend/utils/adt/sets.c260
-rw-r--r--src/backend/utils/adt/tid.c109
-rw-r--r--src/backend/utils/adt/timestamp.c126
-rw-r--r--src/backend/utils/adt/varchar.c738
-rw-r--r--src/backend/utils/adt/varlena.c819
-rw-r--r--src/backend/utils/cache/catcache.c1786
-rw-r--r--src/backend/utils/cache/fcache.c481
-rw-r--r--src/backend/utils/cache/inval.c840
-rw-r--r--src/backend/utils/cache/lsyscache.c618
-rw-r--r--src/backend/utils/cache/rel.c57
-rw-r--r--src/backend/utils/cache/relcache.c3493
-rw-r--r--src/backend/utils/cache/syscache.c1057
-rw-r--r--src/backend/utils/error/assert.c86
-rw-r--r--src/backend/utils/error/elog.c392
-rw-r--r--src/backend/utils/error/exc.c229
-rw-r--r--src/backend/utils/error/excabort.c20
-rw-r--r--src/backend/utils/error/excid.c40
-rw-r--r--src/backend/utils/error/format.c30
-rw-r--r--src/backend/utils/fmgr/dfmgr.c441
-rw-r--r--src/backend/utils/fmgr/fmgr.c390
-rw-r--r--src/backend/utils/hash/dynahash.c1382
-rw-r--r--src/backend/utils/hash/hashfn.c212
-rw-r--r--src/backend/utils/init/enbl.c21
-rw-r--r--src/backend/utils/init/findbe.c377
-rw-r--r--src/backend/utils/init/globals.c127
-rw-r--r--src/backend/utils/init/miscinit.c268
-rw-r--r--src/backend/utils/init/postinit.c1064
-rw-r--r--src/backend/utils/misc/superuser.c28
-rw-r--r--src/backend/utils/mmgr/aset.c411
-rw-r--r--src/backend/utils/mmgr/mcxt.c517
-rw-r--r--src/backend/utils/mmgr/oset.c126
-rw-r--r--src/backend/utils/mmgr/palloc.c82
-rw-r--r--src/backend/utils/mmgr/portalmem.c1222
-rw-r--r--src/backend/utils/sort/lselect.c525
-rw-r--r--src/backend/utils/sort/psort.c1311
-rw-r--r--src/backend/utils/time/tqual.c1263
-rw-r--r--src/bin/pg_dump/common.c589
-rw-r--r--src/bin/pg_dump/pg_dump.c4050
-rw-r--r--src/bin/pg_dump/pg_dump.h368
-rw-r--r--src/bin/pg_id/pg_id.c62
-rw-r--r--src/bin/pg_passwd/pg_passwd.c553
-rw-r--r--src/bin/pg_version/pg_version.c41
-rw-r--r--src/bin/pgtclsh/pgtclAppInit.c111
-rw-r--r--src/bin/pgtclsh/pgtkAppInit.c117
-rw-r--r--src/bin/psql/psql.c3771
-rw-r--r--src/bin/psql/psqlHelp.h338
-rw-r--r--src/bin/psql/stringutils.c116
-rw-r--r--src/bin/psql/stringutils.h11
-rw-r--r--src/include/access/attnum.h34
-rw-r--r--src/include/access/funcindex.h21
-rw-r--r--src/include/access/genam.h58
-rw-r--r--src/include/access/gist.h231
-rw-r--r--src/include/access/gistscan.h19
-rw-r--r--src/include/access/giststrat.h9
-rw-r--r--src/include/access/hash.h384
-rw-r--r--src/include/access/heapam.h228
-rw-r--r--src/include/access/hio.h15
-rw-r--r--src/include/access/htup.h101
-rw-r--r--src/include/access/ibit.h25
-rw-r--r--src/include/access/iqual.h15
-rw-r--r--src/include/access/istrat.h62
-rw-r--r--src/include/access/itup.h98
-rw-r--r--src/include/access/nbtree.h388
-rw-r--r--src/include/access/printtup.h20
-rw-r--r--src/include/access/relscan.h92
-rw-r--r--src/include/access/rtree.h167
-rw-r--r--src/include/access/rtscan.h8
-rw-r--r--src/include/access/rtstrat.h11
-rw-r--r--src/include/access/sdir.h35
-rw-r--r--src/include/access/skey.h48
-rw-r--r--src/include/access/strat.h99
-rw-r--r--src/include/access/transam.h212
-rw-r--r--src/include/access/tupdesc.h81
-rw-r--r--src/include/access/tupmacs.h20
-rw-r--r--src/include/access/valid.h24
-rw-r--r--src/include/access/xact.h112
-rw-r--r--src/include/bootstrap/bootstrap.h64
-rw-r--r--src/include/c.h537
-rw-r--r--src/include/catalog/catalog.h16
-rw-r--r--src/include/catalog/catname.h10
-rw-r--r--src/include/catalog/heap.h25
-rw-r--r--src/include/catalog/index.h69
-rw-r--r--src/include/catalog/indexing.h110
-rw-r--r--src/include/catalog/pg_aggregate.h175
-rw-r--r--src/include/catalog/pg_am.h133
-rw-r--r--src/include/catalog/pg_amop.h215
-rw-r--r--src/include/catalog/pg_amproc.h61
-rw-r--r--src/include/catalog/pg_attrdef.h47
-rw-r--r--src/include/catalog/pg_attribute.h917
-rw-r--r--src/include/catalog/pg_class.h248
-rw-r--r--src/include/catalog/pg_database.h49
-rw-r--r--src/include/catalog/pg_defaults.h45
-rw-r--r--src/include/catalog/pg_demon.h57
-rw-r--r--src/include/catalog/pg_group.h30
-rw-r--r--src/include/catalog/pg_hosts.h36
-rw-r--r--src/include/catalog/pg_index.h93
-rw-r--r--src/include/catalog/pg_inheritproc.h47
-rw-r--r--src/include/catalog/pg_inherits.h49
-rw-r--r--src/include/catalog/pg_ipl.h47
-rw-r--r--src/include/catalog/pg_language.h52
-rw-r--r--src/include/catalog/pg_listener.h41
-rw-r--r--src/include/catalog/pg_log.h33
-rw-r--r--src/include/catalog/pg_magic.h45
-rw-r--r--src/include/catalog/pg_opclass.h103
-rw-r--r--src/include/catalog/pg_operator.h1104
-rw-r--r--src/include/catalog/pg_parg.h55
-rw-r--r--src/include/catalog/pg_proc.h1886
-rw-r--r--src/include/catalog/pg_relcheck.h47
-rw-r--r--src/include/catalog/pg_rewrite.h63
-rw-r--r--src/include/catalog/pg_server.h49
-rw-r--r--src/include/catalog/pg_statistic.h57
-rw-r--r--src/include/catalog/pg_time.h31
-rw-r--r--src/include/catalog/pg_trigger.h92
-rw-r--r--src/include/catalog/pg_type.h455
-rw-r--r--src/include/catalog/pg_user.h63
-rw-r--r--src/include/catalog/pg_variable.h33
-rw-r--r--src/include/catalog/pg_version.h49
-rw-r--r--src/include/commands/async.h20
-rw-r--r--src/include/commands/cluster.h16
-rw-r--r--src/include/commands/command.h30
-rw-r--r--src/include/commands/copy.h13
-rw-r--r--src/include/commands/creatinh.h12
-rw-r--r--src/include/commands/defrem.h47
-rw-r--r--src/include/commands/explain.h12
-rw-r--r--src/include/commands/purge.h17
-rw-r--r--src/include/commands/recipe.h8
-rw-r--r--src/include/commands/rename.h24
-rw-r--r--src/include/commands/sequence.h36
-rw-r--r--src/include/commands/trigger.h79
-rw-r--r--src/include/commands/vacuum.h169
-rw-r--r--src/include/commands/version.h8
-rw-r--r--src/include/commands/view.h16
-rw-r--r--src/include/executor/execFlatten.h13
-rw-r--r--src/include/executor/execdebug.h360
-rw-r--r--src/include/executor/execdefs.h44
-rw-r--r--src/include/executor/execdesc.h32
-rw-r--r--src/include/executor/executor.h189
-rw-r--r--src/include/executor/functions.h18
-rw-r--r--src/include/executor/hashjoin.h97
-rw-r--r--src/include/executor/nodeAgg.h18
-rw-r--r--src/include/executor/nodeAppend.h18
-rw-r--r--src/include/executor/nodeGroup.h18
-rw-r--r--src/include/executor/nodeHash.h41
-rw-r--r--src/include/executor/nodeHashjoin.h23
-rw-r--r--src/include/executor/nodeIndexscan.h29
-rw-r--r--src/include/executor/nodeMaterial.h22
-rw-r--r--src/include/executor/nodeMergejoin.h18
-rw-r--r--src/include/executor/nodeNestloop.h18
-rw-r--r--src/include/executor/nodeResult.h18
-rw-r--r--src/include/executor/nodeSeqscan.h24
-rw-r--r--src/include/executor/nodeSort.h22
-rw-r--r--src/include/executor/nodeTee.h20
-rw-r--r--src/include/executor/nodeUnique.h18
-rw-r--r--src/include/executor/spi.h81
-rw-r--r--src/include/executor/tuptable.h76
-rw-r--r--src/include/lib/dllist.h98
-rw-r--r--src/include/lib/fstack.h96
-rw-r--r--src/include/lib/hasht.h14
-rw-r--r--src/include/lib/lispsort.h10
-rw-r--r--src/include/lib/qsort.h20
-rw-r--r--src/include/lib/stringinfo.h31
-rw-r--r--src/include/libpq/auth.h38
-rw-r--r--src/include/libpq/be-fsstubs.h36
-rw-r--r--src/include/libpq/hba.h48
-rw-r--r--src/include/libpq/libpq-be.h36
-rw-r--r--src/include/libpq/libpq-fs.h109
-rw-r--r--src/include/libpq/libpq.h328
-rw-r--r--src/include/libpq/password.h5
-rw-r--r--src/include/libpq/pqcomm.h173
-rw-r--r--src/include/libpq/pqsignal.h12
-rw-r--r--src/include/miscadmin.h177
-rw-r--r--src/include/nodes/execnodes.h1022
-rw-r--r--src/include/nodes/makefuncs.h60
-rw-r--r--src/include/nodes/memnodes.h117
-rw-r--r--src/include/nodes/nodeFuncs.h16
-rw-r--r--src/include/nodes/nodes.h450
-rw-r--r--src/include/nodes/params.h103
-rw-r--r--src/include/nodes/parsenodes.h1148
-rw-r--r--src/include/nodes/pg_list.h144
-rw-r--r--src/include/nodes/plannodes.h375
-rw-r--r--src/include/nodes/primnodes.h448
-rw-r--r--src/include/nodes/print.h27
-rw-r--r--src/include/nodes/readfuncs.h20
-rw-r--r--src/include/nodes/relation.h466
-rw-r--r--src/include/optimizer/clauseinfo.h22
-rw-r--r--src/include/optimizer/clauses.h74
-rw-r--r--src/include/optimizer/cost.h77
-rw-r--r--src/include/optimizer/geqo.h55
-rw-r--r--src/include/optimizer/geqo_copy.h18
-rw-r--r--src/include/optimizer/geqo_gene.h44
-rw-r--r--src/include/optimizer/geqo_misc.h28
-rw-r--r--src/include/optimizer/geqo_mutation.h18
-rw-r--r--src/include/optimizer/geqo_paths.h20
-rw-r--r--src/include/optimizer/geqo_pool.h28
-rw-r--r--src/include/optimizer/geqo_random.h18
-rw-r--r--src/include/optimizer/geqo_recombination.h66
-rw-r--r--src/include/optimizer/geqo_selection.h18
-rw-r--r--src/include/optimizer/internal.h81
-rw-r--r--src/include/optimizer/joininfo.h12
-rw-r--r--src/include/optimizer/keys.h14
-rw-r--r--src/include/optimizer/ordering.h22
-rw-r--r--src/include/optimizer/pathnode.h53
-rw-r--r--src/include/optimizer/paths.h92
-rw-r--r--src/include/optimizer/plancat.h73
-rw-r--r--src/include/optimizer/planmain.h60
-rw-r--r--src/include/optimizer/planner.h10
-rw-r--r--src/include/optimizer/prep.h43
-rw-r--r--src/include/optimizer/tlist.h40
-rw-r--r--src/include/optimizer/var.h14
-rw-r--r--src/include/optimizer/xfunc.h81
-rw-r--r--src/include/parser/catalog_utils.h71
-rw-r--r--src/include/parser/dbcommands.h21
-rw-r--r--src/include/parser/gramparse.h14
-rw-r--r--src/include/parser/keywords.h23
-rw-r--r--src/include/parser/parse_query.h81
-rw-r--r--src/include/parser/parse_state.h31
-rw-r--r--src/include/parser/parsetree.h73
-rw-r--r--src/include/parser/scansup.h9
-rw-r--r--src/include/parser/sysfunc.h9
-rw-r--r--src/include/port/BSD44_derived.h30
-rw-r--r--src/include/port/aix.h18
-rw-r--r--src/include/port/alpha.h14
-rw-r--r--src/include/port/bsdi.h18
-rw-r--r--src/include/port/dgux.h17
-rw-r--r--src/include/port/hpux.h28
-rw-r--r--src/include/port/i386_solaris.h54
-rw-r--r--src/include/port/irix5.h14
-rw-r--r--src/include/port/linux.h59
-rw-r--r--src/include/port/nextstep.h36
-rw-r--r--src/include/port/sco.h8
-rw-r--r--src/include/port/sparc_solaris.h28
-rw-r--r--src/include/port/sunos4.h16
-rw-r--r--src/include/port/svr4.h16
-rw-r--r--src/include/port/ultrix4.h79
-rw-r--r--src/include/port/univel.h38
-rw-r--r--src/include/port/win32.h16
-rw-r--r--src/include/postgres.h197
-rw-r--r--src/include/postgres_ext.h30
-rw-r--r--src/include/regex/cclass.h105
-rw-r--r--src/include/regex/cdefs.h112
-rw-r--r--src/include/regex/cname.h417
-rw-r--r--src/include/regex/regex.h123
-rw-r--r--src/include/regex/regex2.h195
-rw-r--r--src/include/regex/regexp.h56
-rw-r--r--src/include/regex/utils.h34
-rw-r--r--src/include/rewrite/locks.h15
-rw-r--r--src/include/rewrite/prs2lock.h40
-rw-r--r--src/include/rewrite/rewriteDefine.h12
-rw-r--r--src/include/rewrite/rewriteHandler.h35
-rw-r--r--src/include/rewrite/rewriteManip.h35
-rw-r--r--src/include/rewrite/rewriteRemove.h16
-rw-r--r--src/include/rewrite/rewriteSupport.h22
-rw-r--r--src/include/storage/backendid.h23
-rw-r--r--src/include/storage/block.h65
-rw-r--r--src/include/storage/buf.h20
-rw-r--r--src/include/storage/buf_internals.h262
-rw-r--r--src/include/storage/bufmgr.h89
-rw-r--r--src/include/storage/bufpage.h196
-rw-r--r--src/include/storage/fd.h74
-rw-r--r--src/include/storage/ipc.h242
-rw-r--r--src/include/storage/item.h10
-rw-r--r--src/include/storage/itemid.h53
-rw-r--r--src/include/storage/itempos.h39
-rw-r--r--src/include/storage/itemptr.h80
-rw-r--r--src/include/storage/large_object.h60
-rw-r--r--src/include/storage/lmgr.h92
-rw-r--r--src/include/storage/lock.h170
-rw-r--r--src/include/storage/multilev.h38
-rw-r--r--src/include/storage/off.h40
-rw-r--r--src/include/storage/page.h14
-rw-r--r--src/include/storage/pagenum.h14
-rw-r--r--src/include/storage/pos.h32
-rw-r--r--src/include/storage/proc.h113
-rw-r--r--src/include/storage/shmem.h86
-rw-r--r--src/include/storage/sinval.h23
-rw-r--r--src/include/storage/sinvaladt.h176
-rw-r--r--src/include/storage/smgr.h124
-rw-r--r--src/include/storage/spin.h20
-rw-r--r--src/include/strdup.h2
-rw-r--r--src/include/tcop/dest.h88
-rw-r--r--src/include/tcop/fastpath.h22
-rw-r--r--src/include/tcop/pquery.h22
-rw-r--r--src/include/tcop/tcopdebug.h22
-rw-r--r--src/include/tcop/tcopprot.h35
-rw-r--r--src/include/tcop/utility.h8
-rw-r--r--src/include/tcop/variable.h25
-rw-r--r--src/include/utils/acl.h197
-rw-r--r--src/include/utils/array.h162
-rw-r--r--src/include/utils/bit.h24
-rw-r--r--src/include/utils/builtins.h817
-rw-r--r--src/include/utils/cash.h34
-rw-r--r--src/include/utils/catcache.h98
-rw-r--r--src/include/utils/datetime.h6
-rw-r--r--src/include/utils/datum.h19
-rw-r--r--src/include/utils/dt.h373
-rw-r--r--src/include/utils/dynahash.h11
-rw-r--r--src/include/utils/dynamic_loader.h31
-rw-r--r--src/include/utils/elog.h38
-rw-r--r--src/include/utils/exc.h107
-rw-r--r--src/include/utils/excid.h16
-rw-r--r--src/include/utils/fcache.h80
-rw-r--r--src/include/utils/fcache2.h8
-rw-r--r--src/include/utils/fmgrtab.h25
-rw-r--r--src/include/utils/geo_decls.h513
-rw-r--r--src/include/utils/hsearch.h190
-rw-r--r--src/include/utils/inval.h37
-rw-r--r--src/include/utils/lselect.h62
-rw-r--r--src/include/utils/lsyscache.h46
-rw-r--r--src/include/utils/mcxt.h39
-rw-r--r--src/include/utils/memutils.h271
-rw-r--r--src/include/utils/module.h18
-rw-r--r--src/include/utils/nabstime.h96
-rw-r--r--src/include/utils/oidcompos.h68
-rw-r--r--src/include/utils/palloc.h17
-rw-r--r--src/include/utils/portal.h85
-rw-r--r--src/include/utils/psort.h104
-rw-r--r--src/include/utils/rel.h155
-rw-r--r--src/include/utils/rel2.h15
-rw-r--r--src/include/utils/relcache.h26
-rw-r--r--src/include/utils/sets.h10
-rw-r--r--src/include/utils/syscache.h129
-rw-r--r--src/include/utils/tqual.h36
-rw-r--r--src/include/version.h16
-rw-r--r--src/interfaces/libpgtcl/libpgtcl.h12
-rw-r--r--src/interfaces/libpgtcl/pgtcl.c277
-rw-r--r--src/interfaces/libpgtcl/pgtclCmds.c2054
-rw-r--r--src/interfaces/libpgtcl/pgtclCmds.h134
-rw-r--r--src/interfaces/libpgtcl/pgtclId.c260
-rw-r--r--src/interfaces/libpgtcl/pgtclId.h24
-rw-r--r--src/interfaces/libpq/fe-auth.c763
-rw-r--r--src/interfaces/libpq/fe-auth.h34
-rw-r--r--src/interfaces/libpq/fe-connect.c1686
-rw-r--r--src/interfaces/libpq/fe-connect.h12
-rw-r--r--src/interfaces/libpq/fe-exec.c3014
-rw-r--r--src/interfaces/libpq/fe-lobj.c939
-rw-r--r--src/interfaces/libpq/fe-misc.c227
-rw-r--r--src/interfaces/libpq/libpq-fe.h503
-rw-r--r--src/interfaces/libpq/pqsignal.c38
-rw-r--r--src/interfaces/libpq/pqsignal.h12
-rw-r--r--src/lextest/lextest.c6
-rw-r--r--src/test/examples/testlibpq.c213
-rw-r--r--src/test/examples/testlibpq2.c142
-rw-r--r--src/test/examples/testlibpq3.c263
-rw-r--r--src/test/examples/testlibpq4.c240
-rw-r--r--src/test/examples/testlo.c392
-rw-r--r--src/test/examples/testlo2.c378
-rw-r--r--src/test/regress/regress.c375
-rw-r--r--src/tools/entab/entab.c153
-rw-r--r--src/tools/entab/halt.c54
-rw-r--r--src/tutorial/C-code/beard.c68
-rw-r--r--src/tutorial/C-code/complex.c175
-rw-r--r--src/tutorial/C-code/funcs.c89
-rw-r--r--src/utils/strdup.c14
-rw-r--r--src/utils/version.c190
687 files changed, 152157 insertions, 138270 deletions
diff --git a/contrib/array/array_iterator.c b/contrib/array/array_iterator.c
index 95ab119f853..c0c61f0b6a1 100644
--- a/contrib/array/array_iterator.c
+++ b/contrib/array/array_iterator.c
@@ -8,8 +8,8 @@
* For example array_int4eq returns true if some of the elements
* of an array of int4 is equal to the given value:
*
- * array_int4eq({1,2,3}, 1) --> true
- * array_int4eq({1,2,3}, 4) --> false
+ * array_int4eq({1,2,3}, 1) --> true
+ * array_int4eq({1,2,3}, 4) --> false
*
* If we have defined T array types and O scalar operators
* we can define T x O array operators, each of them has a name
@@ -19,10 +19,10 @@
* the array_int4_like because there is no like operator for int4.
* It is now possible to write queries which look inside the arrays:
*
- * create table t(id int4[], txt text[]);
- * select * from t where t.id *= 123;
- * select * from t where t.txt *~ '[a-z]';
- * select * from t where t.txt[1:3] **~ '[a-z]';
+ * create table t(id int4[], txt text[]);
+ * select * from t where t.id *= 123;
+ * select * from t where t.txt *~ '[a-z]';
+ * select * from t where t.txt[1:3] **~ '[a-z]';
*
* Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it>
*/
@@ -40,93 +40,116 @@
#include "utils/builtins.h"
#include "utils/elog.h"
-static int32
-array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
+static int32
+array_iterator(Oid elemtype, Oid proc, int and, ArrayType * array, Datum value)
{
- HeapTuple typ_tuple;
- TypeTupleForm typ_struct;
- bool typbyval;
- int typlen;
- func_ptr proc_fn;
- int pronargs;
- int nitems, i, result;
- int ndim, *dim;
- char *p;
-
- /* Sanity checks */
- if ((array == (ArrayType *) NULL)
- || (ARR_IS_LO(array) == true)) {
- /* elog(NOTICE, "array_iterator: array is null"); */
- return (0);
- }
- ndim = ARR_NDIM(array);
- dim = ARR_DIMS(array);
- nitems = getNitems(ndim, dim);
- if (nitems == 0) {
- /* elog(NOTICE, "array_iterator: nitems = 0"); */
- return (0);
- }
-
- /* Lookup element type information */
- typ_tuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(elemtype),0,0,0);
- if (!HeapTupleIsValid(typ_tuple)) {
- elog(WARN,"array_iterator: cache lookup failed for type %d", elemtype);
- return 0;
- }
- typ_struct = (TypeTupleForm) GETSTRUCT(typ_tuple);
- typlen = typ_struct->typlen;
- typbyval = typ_struct->typbyval;
-
- /* Lookup the function entry point */
- proc_fn == (func_ptr) NULL;
- fmgr_info(proc, &proc_fn, &pronargs);
- if ((proc_fn == NULL) || (pronargs != 2)) {
- elog(WARN, "array_iterator: fmgr_info lookup failed for oid %d", proc);
- return (0);
- }
-
- /* Scan the array and apply the operator to each element */
- result = 0;
- p = ARR_DATA_PTR(array);
- for (i = 0; i < nitems; i++) {
- if (typbyval) {
- switch(typlen) {
- case 1:
- result = (int) (*proc_fn)(*p, value);
- break;
- case 2:
- result = (int) (*proc_fn)(* (int16 *) p, value);
- break;
- case 3:
- case 4:
- result = (int) (*proc_fn)(* (int32 *) p, value);
- break;
- }
- p += typlen;
- } else {
- result = (int) (*proc_fn)(p, value);
- if (typlen > 0) {
- p += typlen;
- } else {
- p += INTALIGN(* (int32 *) p);
- }
- }
- if (result) {
- if (!and) {
- return (1);
- }
- } else {
- if (and) {
+ HeapTuple typ_tuple;
+ TypeTupleForm typ_struct;
+ bool typbyval;
+ int typlen;
+ func_ptr proc_fn;
+ int pronargs;
+ int nitems,
+ i,
+ result;
+ int ndim,
+ *dim;
+ char *p;
+
+ /* Sanity checks */
+ if ((array == (ArrayType *) NULL)
+ || (ARR_IS_LO(array) == true))
+ {
+ /* elog(NOTICE, "array_iterator: array is null"); */
+ return (0);
+ }
+ ndim = ARR_NDIM(array);
+ dim = ARR_DIMS(array);
+ nitems = getNitems(ndim, dim);
+ if (nitems == 0)
+ {
+ /* elog(NOTICE, "array_iterator: nitems = 0"); */
return (0);
- }
}
- }
- if (and && result) {
- return (1);
- } else {
- return (0);
- }
+ /* Lookup element type information */
+ typ_tuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(elemtype), 0, 0, 0);
+ if (!HeapTupleIsValid(typ_tuple))
+ {
+ elog(WARN, "array_iterator: cache lookup failed for type %d", elemtype);
+ return 0;
+ }
+ typ_struct = (TypeTupleForm) GETSTRUCT(typ_tuple);
+ typlen = typ_struct->typlen;
+ typbyval = typ_struct->typbyval;
+
+ /* Lookup the function entry point */
+ proc_fn == (func_ptr) NULL;
+ fmgr_info(proc, &proc_fn, &pronargs);
+ if ((proc_fn == NULL) || (pronargs != 2))
+ {
+ elog(WARN, "array_iterator: fmgr_info lookup failed for oid %d", proc);
+ return (0);
+ }
+
+ /* Scan the array and apply the operator to each element */
+ result = 0;
+ p = ARR_DATA_PTR(array);
+ for (i = 0; i < nitems; i++)
+ {
+ if (typbyval)
+ {
+ switch (typlen)
+ {
+ case 1:
+ result = (int) (*proc_fn) (*p, value);
+ break;
+ case 2:
+ result = (int) (*proc_fn) (*(int16 *) p, value);
+ break;
+ case 3:
+ case 4:
+ result = (int) (*proc_fn) (*(int32 *) p, value);
+ break;
+ }
+ p += typlen;
+ }
+ else
+ {
+ result = (int) (*proc_fn) (p, value);
+ if (typlen > 0)
+ {
+ p += typlen;
+ }
+ else
+ {
+ p += INTALIGN(*(int32 *) p);
+ }
+ }
+ if (result)
+ {
+ if (!and)
+ {
+ return (1);
+ }
+ }
+ else
+ {
+ if (and)
+ {
+ return (0);
+ }
+ }
+ }
+
+ if (and && result)
+ {
+ return (1);
+ }
+ else
+ {
+ return (0);
+ }
}
/*
@@ -134,39 +157,39 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
*/
int32
-array_texteq(ArrayType *array, char* value)
+array_texteq(ArrayType * array, char *value)
{
- return array_iterator((Oid) 25, /* text */
- (Oid) 67, /* texteq */
- 0, /* logical or */
- array, (Datum)value);
+ return array_iterator((Oid) 25, /* text */
+ (Oid) 67, /* texteq */
+ 0, /* logical or */
+ array, (Datum) value);
}
int32
-array_all_texteq(ArrayType *array, char* value)
+array_all_texteq(ArrayType * array, char *value)
{
- return array_iterator((Oid) 25, /* text */
- (Oid) 67, /* texteq */
- 1, /* logical and */
- array, (Datum)value);
+ return array_iterator((Oid) 25, /* text */
+ (Oid) 67, /* texteq */
+ 1, /* logical and */
+ array, (Datum) value);
}
int32
-array_textregexeq(ArrayType *array, char* value)
+array_textregexeq(ArrayType * array, char *value)
{
- return array_iterator((Oid) 25, /* text */
- (Oid) 81, /* textregexeq */
- 0, /* logical or */
- array, (Datum)value);
+ return array_iterator((Oid) 25, /* text */
+ (Oid) 81, /* textregexeq */
+ 0, /* logical or */
+ array, (Datum) value);
}
int32
-array_all_textregexeq(ArrayType *array, char* value)
+array_all_textregexeq(ArrayType * array, char *value)
{
- return array_iterator((Oid) 25, /* text */
- (Oid) 81, /* textregexeq */
- 1, /* logical and */
- array, (Datum)value);
+ return array_iterator((Oid) 25, /* text */
+ (Oid) 81, /* textregexeq */
+ 1, /* logical and */
+ array, (Datum) value);
}
/*
@@ -175,39 +198,39 @@ array_all_textregexeq(ArrayType *array, char* value)
*/
int32
-array_char16eq(ArrayType *array, char* value)
+array_char16eq(ArrayType * array, char *value)
{
- return array_iterator((Oid) 20, /* char16 */
- (Oid) 490, /* char16eq */
- 0, /* logical or */
- array, (Datum)value);
+ return array_iterator((Oid) 20, /* char16 */
+ (Oid) 490, /* char16eq */
+ 0, /* logical or */
+ array, (Datum) value);
}
int32
-array_all_char16eq(ArrayType *array, char* value)
+array_all_char16eq(ArrayType * array, char *value)
{
- return array_iterator((Oid) 20, /* char16 */
- (Oid) 490, /* char16eq */
- 1, /* logical and */
- array, (Datum)value);
+ return array_iterator((Oid) 20, /* char16 */
+ (Oid) 490, /* char16eq */
+ 1, /* logical and */
+ array, (Datum) value);
}
int32
-array_char16regexeq(ArrayType *array, char* value)
+array_char16regexeq(ArrayType * array, char *value)
{
- return array_iterator((Oid) 20, /* char16 */
- (Oid) 700, /* char16regexeq */
- 0, /* logical or */
- array, (Datum)value);
+ return array_iterator((Oid) 20, /* char16 */
+ (Oid) 700, /* char16regexeq */
+ 0, /* logical or */
+ array, (Datum) value);
}
int32
-array_all_char16regexeq(ArrayType *array, char* value)
+array_all_char16regexeq(ArrayType * array, char *value)
{
- return array_iterator((Oid) 20, /* char16 */
- (Oid) 700, /* char16regexeq */
- 1, /* logical and */
- array, (Datum)value);
+ return array_iterator((Oid) 20, /* char16 */
+ (Oid) 700, /* char16regexeq */
+ 1, /* logical and */
+ array, (Datum) value);
}
/*
@@ -215,37 +238,37 @@ array_all_char16regexeq(ArrayType *array, char* value)
*/
int32
-array_int4eq(ArrayType *array, int4 value)
+array_int4eq(ArrayType * array, int4 value)
{
- return array_iterator((Oid) 23, /* int4 */
- (Oid) 65, /* int4eq */
- 0, /* logical or */
- array, (Datum)value);
+ return array_iterator((Oid) 23, /* int4 */
+ (Oid) 65, /* int4eq */
+ 0, /* logical or */
+ array, (Datum) value);
}
int32
-array_all_int4eq(ArrayType *array, int4 value)
+array_all_int4eq(ArrayType * array, int4 value)
{
- return array_iterator((Oid) 23, /* int4 */
- (Oid) 65, /* int4eq */
- 1, /* logical and */
- array, (Datum)value);
+ return array_iterator((Oid) 23, /* int4 */
+ (Oid) 65, /* int4eq */
+ 1, /* logical and */
+ array, (Datum) value);
}
int32
-array_int4gt(ArrayType *array, int4 value)
+array_int4gt(ArrayType * array, int4 value)
{
- return array_iterator((Oid) 23, /* int4 */
- (Oid) 147, /* int4gt */
- 0, /* logical or */
- array, (Datum)value);
+ return array_iterator((Oid) 23, /* int4 */
+ (Oid) 147, /* int4gt */
+ 0, /* logical or */
+ array, (Datum) value);
}
int32
-array_all_int4gt(ArrayType *array, int4 value)
+array_all_int4gt(ArrayType * array, int4 value)
{
- return array_iterator((Oid) 23, /* int4 */
- (Oid) 147, /* int4gt */
- 1, /* logical and */
- array, (Datum)value);
+ return array_iterator((Oid) 23, /* int4 */
+ (Oid) 147, /* int4gt */
+ 1, /* logical and */
+ array, (Datum) value);
}
diff --git a/contrib/datetime/datetime_functions.c b/contrib/datetime/datetime_functions.c
index e684ce58268..08e7250700a 100644
--- a/contrib/datetime/datetime_functions.c
+++ b/contrib/datetime/datetime_functions.c
@@ -13,86 +13,99 @@
#include "utils/datetime.h"
-TimeADT *time_difference(TimeADT * time1, TimeADT * time2)
+TimeADT *
+time_difference(TimeADT * time1, TimeADT * time2)
{
- TimeADT *result = (TimeADT *) palloc(sizeof(TimeADT));
- *result = *time1 - *time2;
- return (result);
+ TimeADT *result = (TimeADT *) palloc(sizeof(TimeADT));
+
+ *result = *time1 - *time2;
+ return (result);
}
-TimeADT *currenttime()
+TimeADT *
+currenttime()
{
- time_t current_time;
- struct tm *tm;
- TimeADT *result = (TimeADT *) palloc(sizeof(TimeADT));
-
- current_time = time(NULL);
- tm = localtime(&current_time);
- *result = ((((tm->tm_hour*60)+tm->tm_min)*60)+tm->tm_sec);
- return (result);
+ time_t current_time;
+ struct tm *tm;
+ TimeADT *result = (TimeADT *) palloc(sizeof(TimeADT));
+
+ current_time = time(NULL);
+ tm = localtime(&current_time);
+ *result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec);
+ return (result);
}
-DateADT currentdate()
+DateADT
+currentdate()
{
- time_t current_time;
- struct tm *tm;
- DateADT result;
- current_time = time(NULL);
- tm = localtime(&current_time);
-
- result = date2j(tm->tm_year,tm->tm_mon + 1,tm->tm_mday) -
- date2j(100,1,1);
- return (result);
+ time_t current_time;
+ struct tm *tm;
+ DateADT result;
+
+ current_time = time(NULL);
+ tm = localtime(&current_time);
+
+ result = date2j(tm->tm_year, tm->tm_mon + 1, tm->tm_mday) -
+ date2j(100, 1, 1);
+ return (result);
}
-int4 hours(TimeADT * time)
+int4
+hours(TimeADT * time)
{
- return(*time / (60*60));
+ return (*time / (60 * 60));
}
-int4 minutes(TimeADT * time)
+int4
+minutes(TimeADT * time)
{
- return(((int) (*time / 60)) % 60);
+ return (((int) (*time / 60)) % 60);
}
-int4 seconds(TimeADT * time)
+int4
+seconds(TimeADT * time)
{
- return(((int) *time) % 60);
+ return (((int) *time) % 60);
}
-int4 day(DateADT *date)
+int4
+day(DateADT * date)
{
- struct tm tm;
+ struct tm tm;
- j2date( (*date + date2j(2000,1,1)),
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
+ j2date((*date + date2j(2000, 1, 1)),
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
- return (tm.tm_mday);
+ return (tm.tm_mday);
}
-int4 month(DateADT *date)
+int4
+month(DateADT * date)
{
- struct tm tm;
+ struct tm tm;
- j2date( (*date + date2j(2000,1,1)),
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
+ j2date((*date + date2j(2000, 1, 1)),
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
- return (tm.tm_mon);
+ return (tm.tm_mon);
}
-int4 year(DateADT *date)
+int4
+year(DateADT * date)
{
- struct tm tm;
+ struct tm tm;
- j2date( (*date + date2j(2000,1,1)),
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
+ j2date((*date + date2j(2000, 1, 1)),
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
- return (tm.tm_year);
+ return (tm.tm_year);
}
-int4 asminutes(TimeADT * time)
+int4
+asminutes(TimeADT * time)
{
- int seconds = (int) *time;
+ int seconds = (int) *time;
- return (seconds / 60);
+ return (seconds / 60);
}
-int4 asseconds(TimeADT * time)
+int4
+asseconds(TimeADT * time)
{
- int seconds = (int) *time;
+ int seconds = (int) *time;
- return (seconds);
+ return (seconds);
}
diff --git a/contrib/int8/int8.c b/contrib/int8/int8.c
index 93822cb480f..a73986beebd 100644
--- a/contrib/int8/int8.c
+++ b/contrib/int8/int8.c
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* int8.c--
- * Internal 64-bit integer operations
+ * Internal 64-bit integer operations
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf proto, etc. */
-#include <stdlib.h> /* for strtod, etc. */
+#include <stdio.h> /* for sprintf proto, etc. */
+#include <stdlib.h> /* for strtod, etc. */
#include <string.h>
#include <ctype.h>
#include <time.h>
@@ -17,7 +17,7 @@
#include "postgres.h"
#include "utils/palloc.h"
-#define MAXINT8LEN 25
+#define MAXINT8LEN 25
#define USE_LOCAL_CODE 1
@@ -26,53 +26,58 @@
#endif
#ifndef HAVE_64BIT_INTS
-typedef char[8] int64;
+typedef char [8] int64;
#elif defined(__alpha)
typedef long int int64;
+
#define INT64_FORMAT "%ld"
#elif defined(__GNUC__)
typedef long long int int64;
+
#define INT64_FORMAT "%Ld"
#else
typedef long int int64;
+
#define INT64_FORMAT "%ld"
#endif
-int64 *int8in(char *str);
-char *int8out(int64 *val);
-
-bool int8eq(int64 *val1, int64 *val2);
-bool int8ne(int64 *val1, int64 *val2);
-bool int8lt(int64 *val1, int64 *val2);
-bool int8gt(int64 *val1, int64 *val2);
-bool int8le(int64 *val1, int64 *val2);
-bool int8ge(int64 *val1, int64 *val2);
-
-bool int84eq(int64 *val1, int32 val2);
-bool int84ne(int64 *val1, int32 val2);
-bool int84lt(int64 *val1, int32 val2);
-bool int84gt(int64 *val1, int32 val2);
-bool int84le(int64 *val1, int32 val2);
-bool int84ge(int64 *val1, int32 val2);
-
-int64 *int8um(int64 *val);
-int64 *int8pl(int64 *val1, int64 *val2);
-int64 *int8mi(int64 *val1, int64 *val2);
-int64 *int8mul(int64 *val1, int64 *val2);
-int64 *int8div(int64 *val1, int64 *val2);
-
-int64 *int48(int32 val);
-int32 int84(int64 *val);
+int64 *int8in(char *str);
+char *int8out(int64 * val);
+
+bool int8eq(int64 * val1, int64 * val2);
+bool int8ne(int64 * val1, int64 * val2);
+bool int8lt(int64 * val1, int64 * val2);
+bool int8gt(int64 * val1, int64 * val2);
+bool int8le(int64 * val1, int64 * val2);
+bool int8ge(int64 * val1, int64 * val2);
+
+bool int84eq(int64 * val1, int32 val2);
+bool int84ne(int64 * val1, int32 val2);
+bool int84lt(int64 * val1, int32 val2);
+bool int84gt(int64 * val1, int32 val2);
+bool int84le(int64 * val1, int32 val2);
+bool int84ge(int64 * val1, int32 val2);
+
+int64 *int8um(int64 * val);
+int64 *int8pl(int64 * val1, int64 * val2);
+int64 *int8mi(int64 * val1, int64 * val2);
+int64 *int8mul(int64 * val1, int64 * val2);
+int64 *int8div(int64 * val1, int64 * val2);
+
+int64 *int48(int32 val);
+int32 int84(int64 * val);
+
#if FALSE
-int64 *int28(int16 val);
-int16 int82(int64 *val);
+int64 *int28(int16 val);
+int16 int82(int64 * val);
+
#endif
-float64 i8tod(int64 *val);
-int64 *dtoi8(float64 val);
+float64 i8tod(int64 * val);
+int64 *dtoi8(float64 val);
#if USE_LOCAL_CODE
@@ -88,7 +93,7 @@ int64 *dtoi8(float64 val);
/***********************************************************************
**
- ** Routines for 64-bit integers.
+ ** Routines for 64-bit integers.
**
***********************************************************************/
@@ -98,264 +103,289 @@ int64 *dtoi8(float64 val);
/* int8in()
*/
-int64 *int8in(char *str)
+int64 *
+int8in(char *str)
{
- int64 *result = PALLOCTYPE(int64);
+ int64 *result = PALLOCTYPE(int64);
#if HAVE_64BIT_INTS
- if (!PointerIsValid(str))
- elog (WARN,"Bad (null) int8 external representation",NULL);
+ if (!PointerIsValid(str))
+ elog(WARN, "Bad (null) int8 external representation", NULL);
- if (sscanf(str, INT64_FORMAT, result) != 1)
- elog(WARN,"Bad int8 external representation '%s'",str);
+ if (sscanf(str, INT64_FORMAT, result) != 1)
+ elog(WARN, "Bad int8 external representation '%s'", str);
#else
- elog(WARN,"64-bit integers are not supported",NULL);
- result = NULL;
+ elog(WARN, "64-bit integers are not supported", NULL);
+ result = NULL;
#endif
- return(result);
-} /* int8in() */
+ return (result);
+} /* int8in() */
/* int8out()
*/
-char *int8out(int64 *val)
+char *
+int8out(int64 * val)
{
- char *result;
+ char *result;
- int len;
- char buf[MAXINT8LEN+1];
+ int len;
+ char buf[MAXINT8LEN + 1];
#if HAVE_64BIT_INTS
- if (!PointerIsValid(val))
- return(NULL);
+ if (!PointerIsValid(val))
+ return (NULL);
- if ((len = snprintf( buf, MAXINT8LEN, INT64_FORMAT, *val)) < 0)
- elog (WARN,"Unable to format int8",NULL);
+ if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, *val)) < 0)
+ elog(WARN, "Unable to format int8", NULL);
- result = PALLOC(len+1);
+ result = PALLOC(len + 1);
- strcpy(result, buf);
+ strcpy(result, buf);
#else
- elog(WARN,"64-bit integers are not supported",NULL);
- result = NULL;
+ elog(WARN, "64-bit integers are not supported", NULL);
+ result = NULL;
#endif
- return( result);
-} /* int8out() */
+ return (result);
+} /* int8out() */
/*----------------------------------------------------------
- * Relational operators for int8s.
+ * Relational operators for int8s.
*---------------------------------------------------------*/
/* int8relop()
* Is val1 relop val2?
*/
-bool int8eq(int64 *val1, int64 *val2)
+bool
+int8eq(int64 * val1, int64 * val2)
{
- return(*val1 == *val2);
-} /* int8eq() */
+ return (*val1 == *val2);
+} /* int8eq() */
-bool int8ne(int64 *val1, int64 *val2)
+bool
+int8ne(int64 * val1, int64 * val2)
{
- return(*val1 != *val2);
-} /* int8ne() */
+ return (*val1 != *val2);
+} /* int8ne() */
-bool int8lt(int64 *val1, int64 *val2)
+bool
+int8lt(int64 * val1, int64 * val2)
{
- return(*val1 < *val2);
-} /* int8lt() */
+ return (*val1 < *val2);
+} /* int8lt() */
-bool int8gt(int64 *val1, int64 *val2)
+bool
+int8gt(int64 * val1, int64 * val2)
{
- return(*val1 > *val2);
-} /* int8gt() */
+ return (*val1 > *val2);
+} /* int8gt() */
-bool int8le(int64 *val1, int64 *val2)
+bool
+int8le(int64 * val1, int64 * val2)
{
- return(*val1 <= *val2);
-} /* int8le() */
+ return (*val1 <= *val2);
+} /* int8le() */
-bool int8ge(int64 *val1, int64 *val2)
+bool
+int8ge(int64 * val1, int64 * val2)
{
- return(*val1 >= *val2);
-} /* int8ge() */
+ return (*val1 >= *val2);
+} /* int8ge() */
/* int84relop()
* Is 64-bit val1 relop 32-bit val2?
*/
-bool int84eq(int64 *val1, int32 val2)
+bool
+int84eq(int64 * val1, int32 val2)
{
- return(*val1 == val2);
-} /* int84eq() */
+ return (*val1 == val2);
+} /* int84eq() */
-bool int84ne(int64 *val1, int32 val2)
+bool
+int84ne(int64 * val1, int32 val2)
{
- return(*val1 != val2);
-} /* int84ne() */
+ return (*val1 != val2);
+} /* int84ne() */
-bool int84lt(int64 *val1, int32 val2)
+bool
+int84lt(int64 * val1, int32 val2)
{
- return(*val1 < val2);
-} /* int84lt() */
+ return (*val1 < val2);
+} /* int84lt() */
-bool int84gt(int64 *val1, int32 val2)
+bool
+int84gt(int64 * val1, int32 val2)
{
- return(*val1 > val2);
-} /* int84gt() */
+ return (*val1 > val2);
+} /* int84gt() */
-bool int84le(int64 *val1, int32 val2)
+bool
+int84le(int64 * val1, int32 val2)
{
- return(*val1 <= val2);
-} /* int84le() */
+ return (*val1 <= val2);
+} /* int84le() */
-bool int84ge(int64 *val1, int32 val2)
+bool
+int84ge(int64 * val1, int32 val2)
{
- return(*val1 >= val2);
-} /* int84ge() */
+ return (*val1 >= val2);
+} /* int84ge() */
/*----------------------------------------------------------
- * Arithmetic operators on 64-bit integers.
+ * Arithmetic operators on 64-bit integers.
*---------------------------------------------------------*/
-int64 *int8um(int64 *val)
+int64 *
+int8um(int64 * val)
{
- int64 *result = PALLOCTYPE(int64);
+ int64 *result = PALLOCTYPE(int64);
- if (!PointerIsValid(val))
- return NULL;
+ if (!PointerIsValid(val))
+ return NULL;
- *result = (- *val);
+ *result = (-*val);
- return(result);
-} /* int8um() */
+ return (result);
+} /* int8um() */
-int64 *int8pl(int64 *val1, int64 *val2)
+int64 *
+int8pl(int64 * val1, int64 * val2)
{
- int64 *result = PALLOCTYPE(int64);
+ int64 *result = PALLOCTYPE(int64);
- if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
- return NULL;
+ if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
+ return NULL;
- *result = *val1 + *val2;
+ *result = *val1 + *val2;
- return(result);
-} /* int8pl() */
+ return (result);
+} /* int8pl() */
-int64 *int8mi(int64 *val1, int64 *val2)
+int64 *
+int8mi(int64 * val1, int64 * val2)
{
- int64 *result = PALLOCTYPE(int64);
+ int64 *result = PALLOCTYPE(int64);
- if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
- return NULL;
+ if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
+ return NULL;
- *result = *val1 - *val2;
+ *result = *val1 - *val2;
- return(result);
-} /* int8mi() */
+ return (result);
+} /* int8mi() */
-int64 *int8mul(int64 *val1, int64 *val2)
+int64 *
+int8mul(int64 * val1, int64 * val2)
{
- int64 *result = PALLOCTYPE(int64);
+ int64 *result = PALLOCTYPE(int64);
- if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
- return NULL;
+ if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
+ return NULL;
- *result = *val1 * *val2;
+ *result = *val1 * *val2;
- return(result);
-} /* int8mul() */
+ return (result);
+} /* int8mul() */
-int64 *int8div(int64 *val1, int64 *val2)
+int64 *
+int8div(int64 * val1, int64 * val2)
{
- int64 *result = PALLOCTYPE(int64);
+ int64 *result = PALLOCTYPE(int64);
- if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
- return NULL;
+ if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
+ return NULL;
- *result = *val1 / *val2;
+ *result = *val1 / *val2;
- return(result);
-} /* int8div() */
+ return (result);
+} /* int8div() */
/*----------------------------------------------------------
- * Conversion operators.
+ * Conversion operators.
*---------------------------------------------------------*/
-int64 *int48(int32 val)
+int64 *
+int48(int32 val)
{
- int64 *result = PALLOCTYPE(int64);
+ int64 *result = PALLOCTYPE(int64);
- *result = val;
+ *result = val;
- return(result);
-} /* int48() */
+ return (result);
+} /* int48() */
-int32 int84(int64 *val)
+int32
+int84(int64 * val)
{
- int32 result;
+ int32 result;
- if (!PointerIsValid(val))
- elog(WARN,"Invalid (null) int64, can't convert int8 to int4",NULL);
+ if (!PointerIsValid(val))
+ elog(WARN, "Invalid (null) int64, can't convert int8 to int4", NULL);
- if ((*val < INT_MIN) || (*val > INT_MAX))
- elog(WARN,"int8 conversion to int4 is out of range",NULL);
+ if ((*val < INT_MIN) || (*val > INT_MAX))
+ elog(WARN, "int8 conversion to int4 is out of range", NULL);
- result = *val;
+ result = *val;
- return(result);
-} /* int84() */
+ return (result);
+} /* int84() */
#if FALSE
-int64 *int28(int16 val)
+int64 *
+int28(int16 val)
{
- int64 *result;
+ int64 *result;
- if (!PointerIsValid(result = PALLOCTYPE(int64)))
- elog(WARN,"Memory allocation failed, can't convert int8 to int2",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(int64)))
+ elog(WARN, "Memory allocation failed, can't convert int8 to int2", NULL);
- *result = val;
+ *result = val;
- return(result);
-} /* int28() */
+ return (result);
+} /* int28() */
-int16 int82(int64 *val)
+int16
+int82(int64 * val)
{
- int16 result;
+ int16 result;
- if (!PointerIsValid(val))
- elog(WARN,"Invalid (null) int8, can't convert to int2",NULL);
+ if (!PointerIsValid(val))
+ elog(WARN, "Invalid (null) int8, can't convert to int2", NULL);
- result = *val;
+ result = *val;
+
+ return (result);
+} /* int82() */
- return(result);
-} /* int82() */
#endif
-float64 i8tod(int64 *val)
+float64
+i8tod(int64 * val)
{
- float64 result = PALLOCTYPE(float64data);
+ float64 result = PALLOCTYPE(float64data);
- *result = *val;
+ *result = *val;
- return(result);
-} /* i8tod() */
+ return (result);
+} /* i8tod() */
-int64 *dtoi8(float64 val)
+int64 *
+dtoi8(float64 val)
{
- int64 *result = PALLOCTYPE(int64);
-
- if ((*val < (-pow(2,64)+1)) || (*val > (pow(2,64)-1)))
- elog(WARN,"Floating point conversion to int64 is out of range",NULL);
+ int64 *result = PALLOCTYPE(int64);
- *result = *val;
+ if ((*val < (-pow(2, 64) + 1)) || (*val > (pow(2, 64) - 1)))
+ elog(WARN, "Floating point conversion to int64 is out of range", NULL);
- return(result);
-} /* dtoi8() */
+ *result = *val;
+ return (result);
+} /* dtoi8() */
diff --git a/contrib/pginterface/halt.c b/contrib/pginterface/halt.c
index 58ca11a5878..000e4a9c409 100644
--- a/contrib/pginterface/halt.c
+++ b/contrib/pginterface/halt.c
@@ -1,8 +1,8 @@
/*
**
-** halt.c
+** halt.c
**
-** This is used to print out error messages and exit
+** This is used to print out error messages and exit
*/
#include <varargs.h>
@@ -15,44 +15,46 @@
/*-------------------------------------------------------------------------
**
-** halt - print error message, and call clean up routine or exit
+** halt - print error message, and call clean up routine or exit
**
**------------------------------------------------------------------------*/
/*VARARGS*/
-void halt(va_alist)
+void
+halt(va_alist)
va_dcl
{
- va_list arg_ptr;
- char *format, *pstr;
- void (*sig_func)();
+ va_list arg_ptr;
+ char *format,
+ *pstr;
+ void (*sig_func) ();
va_start(arg_ptr);
- format = va_arg(arg_ptr,char *);
- if (strncmp(format,"PERROR", 6) != 0)
- vfprintf(stderr,format,arg_ptr);
+ format = va_arg(arg_ptr, char *);
+ if (strncmp(format, "PERROR", 6) != 0)
+ vfprintf(stderr, format, arg_ptr);
else
{
- for (pstr=format+6; *pstr == ' ' || *pstr == ':'; pstr++)
+ for (pstr = format + 6; *pstr == ' ' || *pstr == ':'; pstr++)
;
- vfprintf(stderr,pstr,arg_ptr);
+ vfprintf(stderr, pstr, arg_ptr);
perror("");
- }
+ }
va_end(arg_ptr);
fflush(stderr);
- /* call one clean up function if defined */
- if ( (sig_func = signal(SIGTERM, SIG_DFL)) != SIG_DFL &&
- sig_func != SIG_IGN)
- (*sig_func)(0);
- else if ( (sig_func = signal(SIGHUP, SIG_DFL)) != SIG_DFL &&
- sig_func != SIG_IGN)
- (*sig_func)(0);
- else if ( (sig_func = signal(SIGINT, SIG_DFL)) != SIG_DFL &&
- sig_func != SIG_IGN)
- (*sig_func)(0);
- else if ( (sig_func = signal(SIGQUIT, SIG_DFL)) != SIG_DFL &&
- sig_func != SIG_IGN)
- (*sig_func)(0);
+ /* call one clean up function if defined */
+ if ((sig_func = signal(SIGTERM, SIG_DFL)) != SIG_DFL &&
+ sig_func != SIG_IGN)
+ (*sig_func) (0);
+ else if ((sig_func = signal(SIGHUP, SIG_DFL)) != SIG_DFL &&
+ sig_func != SIG_IGN)
+ (*sig_func) (0);
+ else if ((sig_func = signal(SIGINT, SIG_DFL)) != SIG_DFL &&
+ sig_func != SIG_IGN)
+ (*sig_func) (0);
+ else if ((sig_func = signal(SIGQUIT, SIG_DFL)) != SIG_DFL &&
+ sig_func != SIG_IGN)
+ (*sig_func) (0);
exit(1);
}
diff --git a/contrib/pginterface/halt.h b/contrib/pginterface/halt.h
index cb4ea545b9b..8e1af05e4cf 100644
--- a/contrib/pginterface/halt.h
+++ b/contrib/pginterface/halt.h
@@ -3,5 +3,4 @@
**
*/
-void halt();
-
+void halt();
diff --git a/contrib/pginterface/pginsert.c b/contrib/pginterface/pginsert.c
index 92c869b3832..9946b258ffa 100644
--- a/contrib/pginterface/pginsert.c
+++ b/contrib/pginterface/pginsert.c
@@ -10,20 +10,25 @@
#include "halt.h"
#include "pginterface.h"
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
{
- char query[4000];
- int row =1;
- int aint;
- float afloat;
- double adouble;
- char achar[11], achar16[17], abpchar[11], avarchar[51], atext[51];
- time_t aabstime;
-
+ char query[4000];
+ int row = 1;
+ int aint;
+ float afloat;
+ double adouble;
+ char achar[11],
+ achar16[17],
+ abpchar[11],
+ avarchar[51],
+ atext[51];
+ time_t aabstime;
+
if (argc != 2)
- halt("Usage: %s database\n",argv[0]);
+ halt("Usage: %s database\n", argv[0]);
- connectdb(argv[1],NULL,NULL,NULL,NULL);
+ connectdb(argv[1], NULL, NULL, NULL, NULL);
on_error_continue();
doquery("DROP TABLE testfetch");
@@ -42,9 +47,9 @@ int main(int argc, char **argv)
aabstime abstime) \
");
- while(1)
+ while (1)
{
- sprintf(query,"INSERT INTO testfetch VALUES ( \
+ sprintf(query, "INSERT INTO testfetch VALUES ( \
%d, \
2322.12, \
'923121.0323'::float8, \
@@ -55,44 +60,43 @@ int main(int argc, char **argv)
'Ernie', \
'now' )", row);
doquery(query);
-
+
doquery("BEGIN WORK");
- doquery("DECLARE c_testfetch BINARY CURSOR FOR \
+ doquery("DECLARE c_testfetch BINARY CURSOR FOR \
SELECT * FROM testfetch");
doquery("FETCH ALL IN c_testfetch");
while (fetch(
- &aint,
- &afloat,
- &adouble,
- achar,
- achar16,
- abpchar,
- avarchar,
- atext,
- &aabstime) != END_OF_TUPLES)
- printf("int %d\nfloat %f\ndouble %f\nchar %s\nchar16 %s\n\
+ &aint,
+ &afloat,
+ &adouble,
+ achar,
+ achar16,
+ abpchar,
+ avarchar,
+ atext,
+ &aabstime) != END_OF_TUPLES)
+ printf("int %d\nfloat %f\ndouble %f\nchar %s\nchar16 %s\n\
bpchar %s\nvarchar %s\ntext %s\nabstime %s",
- aint,
- afloat,
- adouble,
- achar,
- achar16,
- abpchar,
- avarchar,
- atext,
- ctime(&aabstime));
+ aint,
+ afloat,
+ adouble,
+ achar,
+ achar16,
+ abpchar,
+ avarchar,
+ atext,
+ ctime(&aabstime));
+
-
doquery("CLOSE c_testfetch");
doquery("COMMIT WORK");
- printf("--- %-d rows inserted so far\n",row);
-
+ printf("--- %-d rows inserted so far\n", row);
+
row++;
}
disconnectdb();
return 0;
}
-
diff --git a/contrib/pginterface/pginterface.c b/contrib/pginterface/pginterface.c
index 7593cd9f97f..f1ade9dcd41 100644
--- a/contrib/pginterface/pginterface.c
+++ b/contrib/pginterface/pginterface.c
@@ -12,77 +12,82 @@
#include "halt.h"
#include "pginterface.h"
-static void sig_disconnect();
-static void set_signals();
+static void sig_disconnect();
+static void set_signals();
#define NUL '\0'
/* GLOBAL VARIABLES */
-static PGconn* conn;
-static PGresult* res = NULL;
+static PGconn *conn;
+static PGresult *res = NULL;
#define ON_ERROR_STOP 0
-#define ON_ERROR_CONTINUE 1
+#define ON_ERROR_CONTINUE 1
-static int on_error_state = ON_ERROR_STOP;
+static int on_error_state = ON_ERROR_STOP;
/* LOCAL VARIABLES */
-static sigset_t block_sigs, unblock_sigs;
-static int tuple;
+static sigset_t block_sigs,
+ unblock_sigs;
+static int tuple;
/*
**
-** connectdb - returns PGconn structure
+** connectdb - returns PGconn structure
**
*/
-PGconn *connectdb( char *dbName,
- char *pghost,
- char *pgport,
- char *pgoptions,
- char *pgtty)
+PGconn *
+connectdb(char *dbName,
+ char *pghost,
+ char *pgport,
+ char *pgoptions,
+ char *pgtty)
{
/* make a connection to the database */
conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
if (PQstatus(conn) == CONNECTION_BAD)
halt("Connection to database '%s' failed.\n%s\n", dbName,
- PQerrorMessage(conn));
+ PQerrorMessage(conn));
set_signals();
return conn;
}
/*
**
-** disconnectdb
+** disconnectdb
**
*/
-void disconnectdb()
+void
+disconnectdb()
{
PQfinish(conn);
}
/*
**
-** doquery - returns PGresult structure
+** doquery - returns PGresult structure
**
*/
-PGresult *doquery(char *query)
+PGresult *
+doquery(char *query)
{
if (res != NULL)
PQclear(res);
- sigprocmask(SIG_SETMASK,&block_sigs,NULL);
+ sigprocmask(SIG_SETMASK, &block_sigs, NULL);
res = PQexec(conn, query);
- sigprocmask(SIG_SETMASK,&unblock_sigs,NULL);
+ sigprocmask(SIG_SETMASK, &unblock_sigs, NULL);
if (on_error_state == ON_ERROR_STOP &&
(res == NULL ||
- PQresultStatus(res) == PGRES_BAD_RESPONSE ||
- PQresultStatus(res) == PGRES_NONFATAL_ERROR ||
- PQresultStatus(res) == PGRES_FATAL_ERROR))
+ PQresultStatus(res) == PGRES_BAD_RESPONSE ||
+ PQresultStatus(res) == PGRES_NONFATAL_ERROR ||
+ PQresultStatus(res) == PGRES_FATAL_ERROR))
{
if (res != NULL)
- fprintf(stderr,"query error: %s\n",PQcmdStatus(res));
- else fprintf(stderr,"connection error: %s\n",PQerrorMessage(conn));
+ fprintf(stderr, "query error: %s\n", PQcmdStatus(res));
+ else
+ fprintf(stderr, "connection error: %s\n", PQerrorMessage(conn));
PQfinish(conn);
halt("failed request: %s\n", query);
}
@@ -92,14 +97,16 @@ PGresult *doquery(char *query)
/*
**
-** fetch - returns tuple number (starts at 0), or the value END_OF_TUPLES
-** NULL pointers are skipped
+** fetch - returns tuple number (starts at 0), or the value END_OF_TUPLES
+** NULL pointers are skipped
**
*/
-int fetch(void *param, ...)
+int
+fetch(void *param,...)
{
- va_list ap;
- int arg, num_fields;
+ va_list ap;
+ int arg,
+ num_fields;
num_fields = PQnfields(res);
@@ -113,11 +120,11 @@ int fetch(void *param, ...)
{
if (PQfsize(res, arg) == -1)
{
- memcpy(param,PQgetvalue(res,tuple,arg),PQgetlength(res,tuple,arg));
- ((char *)param)[PQgetlength(res,tuple,arg)] = NUL;
+ memcpy(param, PQgetvalue(res, tuple, arg), PQgetlength(res, tuple, arg));
+ ((char *) param)[PQgetlength(res, tuple, arg)] = NUL;
}
else
- memcpy(param,PQgetvalue(res,tuple,arg),PQfsize(res,arg));
+ memcpy(param, PQgetvalue(res, tuple, arg), PQfsize(res, arg));
}
param = va_arg(ap, char *);
}
@@ -127,15 +134,17 @@ int fetch(void *param, ...)
/*
**
-** fetchwithnulls - returns tuple number (starts at 0),
-** or the value END_OF_TUPLES
-** Returns true or false into null indicator variables
-** NULL pointers are skipped
+** fetchwithnulls - returns tuple number (starts at 0),
+** or the value END_OF_TUPLES
+** Returns true or false into null indicator variables
+** NULL pointers are skipped
*/
-int fetchwithnulls(void *param, ...)
+int
+fetchwithnulls(void *param,...)
{
- va_list ap;
- int arg, num_fields;
+ va_list ap;
+ int arg,
+ num_fields;
num_fields = PQnfields(res);
@@ -149,17 +158,17 @@ int fetchwithnulls(void *param, ...)
{
if (PQfsize(res, arg) == -1)
{
- memcpy(param,PQgetvalue(res,tuple,arg),PQgetlength(res,tuple,arg));
- ((char *)param)[PQgetlength(res,tuple,arg)] = NUL;
+ memcpy(param, PQgetvalue(res, tuple, arg), PQgetlength(res, tuple, arg));
+ ((char *) param)[PQgetlength(res, tuple, arg)] = NUL;
}
else
- memcpy(param,PQgetvalue(res,tuple,arg),PQfsize(res,arg));
+ memcpy(param, PQgetvalue(res, tuple, arg), PQfsize(res, arg));
}
param = va_arg(ap, char *);
- if (PQgetisnull(res,tuple,arg) != 0)
- *(int *)param = 1;
+ if (PQgetisnull(res, tuple, arg) != 0)
+ *(int *) param = 1;
else
- *(int *)param = 0;
+ *(int *) param = 0;
param = va_arg(ap, char *);
}
va_end(ap);
@@ -168,52 +177,56 @@ int fetchwithnulls(void *param, ...)
/*
**
-** on_error_stop
+** on_error_stop
**
*/
-void on_error_stop()
+void
+on_error_stop()
{
on_error_state = ON_ERROR_STOP;
}
-
+
/*
**
-** on_error_continue
+** on_error_continue
**
*/
-void on_error_continue()
+void
+on_error_continue()
{
on_error_state = ON_ERROR_CONTINUE;
}
-
+
/*
**
-** sig_disconnect
+** sig_disconnect
**
*/
-static void sig_disconnect()
+static void
+sig_disconnect()
{
- fprintf(stderr,"exiting...\n");
+ fprintf(stderr, "exiting...\n");
PQfinish(conn);
exit(1);
}
/*
**
-** set_signals
+** set_signals
**
*/
-static void set_signals()
+static void
+set_signals()
{
sigemptyset(&block_sigs);
sigemptyset(&unblock_sigs);
- sigaddset(&block_sigs,SIGTERM);
- sigaddset(&block_sigs,SIGHUP);
- sigaddset(&block_sigs,SIGINT);
-/* sigaddset(&block_sigs,SIGQUIT); no block */
- sigprocmask(SIG_SETMASK,&unblock_sigs,NULL);
- signal(SIGTERM,sig_disconnect);
- signal(SIGHUP,sig_disconnect);
- signal(SIGINT,sig_disconnect);
- signal(SIGQUIT,sig_disconnect);
+ sigaddset(&block_sigs, SIGTERM);
+ sigaddset(&block_sigs, SIGHUP);
+ sigaddset(&block_sigs, SIGINT);
+/* sigaddset(&block_sigs,SIGQUIT); no block */
+ sigprocmask(SIG_SETMASK, &unblock_sigs, NULL);
+ signal(SIGTERM, sig_disconnect);
+ signal(SIGHUP, sig_disconnect);
+ signal(SIGINT, sig_disconnect);
+ signal(SIGQUIT, sig_disconnect);
}
diff --git a/contrib/pginterface/pginterface.h b/contrib/pginterface/pginterface.h
index 7e9cbdb5eb8..65894eae34e 100644
--- a/contrib/pginterface/pginterface.h
+++ b/contrib/pginterface/pginterface.h
@@ -3,12 +3,12 @@
*
*/
-PGresult *doquery(char *query);
-PGconn *connectdb();
-void disconnectdb();
-int fetch(void *param, ...);
-int fetchwithnulls(void *param, ...);
-void on_error_continue();
-void on_error_stop();
+PGresult *doquery(char *query);
+PGconn *connectdb();
+void disconnectdb();
+int fetch(void *param,...);
+int fetchwithnulls(void *param,...);
+void on_error_continue();
+void on_error_stop();
#define END_OF_TUPLES (-1)
diff --git a/contrib/pginterface/pgnulltest.c b/contrib/pginterface/pgnulltest.c
index 283106f726d..2622edcaf65 100644
--- a/contrib/pginterface/pgnulltest.c
+++ b/contrib/pginterface/pgnulltest.c
@@ -12,29 +12,34 @@
#include <libpq-fe.h>
#include <pginterface.h>
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
{
- char query[4000];
- int row =1;
- int aint;
- float afloat;
- double adouble;
- char achar[11], achar16[17], abpchar[11], avarchar[51], atext[51];
- time_t aabstime;
- int aint_null,
- afloat_null,
- adouble_null,
- achar_null,
- achar16_null,
- abpchar_null,
- avarchar_null,
- atext_null,
- aabstime_null;
+ char query[4000];
+ int row = 1;
+ int aint;
+ float afloat;
+ double adouble;
+ char achar[11],
+ achar16[17],
+ abpchar[11],
+ avarchar[51],
+ atext[51];
+ time_t aabstime;
+ int aint_null,
+ afloat_null,
+ adouble_null,
+ achar_null,
+ achar16_null,
+ abpchar_null,
+ avarchar_null,
+ atext_null,
+ aabstime_null;
if (argc != 2)
- halt("Usage: %s database\n",argv[0]);
+ halt("Usage: %s database\n", argv[0]);
- connectdb(argv[1],NULL,NULL,NULL,NULL);
+ connectdb(argv[1], NULL, NULL, NULL, NULL);
on_error_continue();
doquery("DROP TABLE testfetch");
@@ -54,7 +59,7 @@ int main(int argc, char **argv)
");
#ifdef TEST_NON_NULLS
- sprintf(query,"INSERT INTO testfetch VALUES ( \
+ sprintf(query, "INSERT INTO testfetch VALUES ( \
0, \
0, \
0, \
@@ -65,7 +70,7 @@ int main(int argc, char **argv)
'', \
'');");
#else
- sprintf(query,"INSERT INTO testfetch VALUES ( \
+ sprintf(query, "INSERT INTO testfetch VALUES ( \
NULL, \
NULL, \
NULL, \
@@ -85,55 +90,54 @@ int main(int argc, char **argv)
doquery("FETCH ALL IN c_testfetch");
if (fetchwithnulls(
- &aint,
- &aint_null,
- &afloat,
- &afloat_null,
- &adouble,
- &adouble_null,
- achar,
- &achar_null,
- achar16,
- &achar16_null,
- abpchar,
- &abpchar_null,
- avarchar,
- &avarchar_null,
- atext,
- &atext_null,
- &aabstime,
- &aabstime_null) != END_OF_TUPLES)
- printf("int %d\nfloat %f\ndouble %f\nchar %s\nchar16 %s\n\
+ &aint,
+ &aint_null,
+ &afloat,
+ &afloat_null,
+ &adouble,
+ &adouble_null,
+ achar,
+ &achar_null,
+ achar16,
+ &achar16_null,
+ abpchar,
+ &abpchar_null,
+ avarchar,
+ &avarchar_null,
+ atext,
+ &atext_null,
+ &aabstime,
+ &aabstime_null) != END_OF_TUPLES)
+ printf("int %d\nfloat %f\ndouble %f\nchar %s\nchar16 %s\n\
bpchar %s\nvarchar %s\ntext %s\nabstime %s\n",
- aint,
- afloat,
- adouble,
- achar,
- achar16,
- abpchar,
- avarchar,
- atext,
- ctime(&aabstime));
- printf("NULL:\nint %d\nfloat %d\ndouble %d\nchar %d\nchar16 %d\n\
+ aint,
+ afloat,
+ adouble,
+ achar,
+ achar16,
+ abpchar,
+ avarchar,
+ atext,
+ ctime(&aabstime));
+ printf("NULL:\nint %d\nfloat %d\ndouble %d\nchar %d\nchar16 %d\n\
bpchar %d\nvarchar %d\ntext %d\nabstime %d\n",
- aint_null,
- afloat_null,
- adouble_null,
- achar_null,
- achar16_null,
- abpchar_null,
- avarchar_null,
- atext_null,
- aabstime_null);
+ aint_null,
+ afloat_null,
+ adouble_null,
+ achar_null,
+ achar16_null,
+ abpchar_null,
+ avarchar_null,
+ atext_null,
+ aabstime_null);
doquery("CLOSE c_testfetch");
doquery("COMMIT WORK");
- printf("--- %-d rows inserted so far\n",row);
+ printf("--- %-d rows inserted so far\n", row);
row++;
disconnectdb();
return 0;
}
-
diff --git a/contrib/pginterface/pgwordcount.c b/contrib/pginterface/pgwordcount.c
index f2d2d488fcf..c447cdcaa0b 100644
--- a/contrib/pginterface/pgwordcount.c
+++ b/contrib/pginterface/pgwordcount.c
@@ -10,17 +10,18 @@
#include <libpq-fe.h>
#include "pginterface.h"
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
{
- char query[4000];
- int row = 0;
- int count;
- char line[4000];
-
+ char query[4000];
+ int row = 0;
+ int count;
+ char line[4000];
+
if (argc != 2)
- halt("Usage: %s database\n",argv[0]);
+ halt("Usage: %s database\n", argv[0]);
- connectdb(argv[1],NULL,NULL,NULL,NULL);
+ connectdb(argv[1], NULL, NULL, NULL, NULL);
on_error_continue();
doquery("DROP TABLE words");
on_error_stop();
@@ -35,33 +36,33 @@ int main(int argc, char **argv)
word text_ops )\
");
- while(1)
+ while (1)
{
- if (scanf("%s",line) != 1)
+ if (scanf("%s", line) != 1)
break;
doquery("BEGIN WORK");
- sprintf(query,"\
+ sprintf(query, "\
DECLARE c_words BINARY CURSOR FOR \
SELECT count(*) \
FROM words \
WHERE word = '%s'", line);
doquery(query);
doquery("FETCH ALL IN c_words");
-
+
while (fetch(&count) == END_OF_TUPLES)
count = 0;
doquery("CLOSE c_words");
doquery("COMMIT WORK");
if (count == 0)
- sprintf(query,"\
+ sprintf(query, "\
INSERT INTO words \
- VALUES (1, '%s')", line);
+ VALUES (1, '%s')", line);
else
- sprintf(query,"\
+ sprintf(query, "\
UPDATE words \
SET matches = matches + 1 \
- WHERE word = '%s'", line);
+ WHERE word = '%s'", line);
doquery(query);
row++;
}
@@ -69,4 +70,3 @@ int main(int argc, char **argv)
disconnectdb();
return 0;
}
-
diff --git a/contrib/soundex/soundex.c b/contrib/soundex/soundex.c
index 2ce6ef510f6..44ad25808de 100644
--- a/contrib/soundex/soundex.c
+++ b/contrib/soundex/soundex.c
@@ -4,80 +4,86 @@
#include <string.h>
#include <stdio.h>
-#include "postgres.h" /* for char16, etc. */
-#include "utils/palloc.h" /* for palloc */
-#include "libpq-fe.h" /* for TUPLE */
+#include "postgres.h" /* for char16, etc. */
+#include "utils/palloc.h" /* for palloc */
+#include "libpq-fe.h" /* for TUPLE */
#include <stdio.h>
#include <ctype.h>
/* prototype for soundex function */
-char *soundex(char *instr, char *outstr);
+char *soundex(char *instr, char *outstr);
-text *text_soundex(text *t)
+text *
+text_soundex(text * t)
{
- /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
- char *table = "01230120022455012623010202";
- int count = 0;
- text *new_t;
-
- char outstr[6+1]; /* max length of soundex is 6 */
- char *instr;
-
- /* make a null-terminated string */
- instr=palloc(VARSIZE(t)+1);
- memcpy(instr,VARDATA(t),VARSIZE(t)-VARHDRSZ);
- instr[VARSIZE(t)-VARHDRSZ] = (char)0;
-
- /* load soundex into outstr */
- soundex(instr, outstr);
-
- /* Now the outstr contains the soundex of instr */
- /* copy outstr to new_t */
- new_t = (text *) palloc(strlen(outstr)+VARHDRSZ);
- memset(new_t, 0, strlen(outstr)+1);
- VARSIZE(new_t) = strlen(outstr)+VARHDRSZ;
- memcpy((void *) VARDATA(new_t),
- (void *) outstr,
- strlen(outstr));
-
- /* free instr */
- pfree(instr);
-
- return(new_t);
+ /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
+ char *table = "01230120022455012623010202";
+ int count = 0;
+ text *new_t;
+
+ char outstr[6 + 1]; /* max length of soundex is 6 */
+ char *instr;
+
+ /* make a null-terminated string */
+ instr = palloc(VARSIZE(t) + 1);
+ memcpy(instr, VARDATA(t), VARSIZE(t) - VARHDRSZ);
+ instr[VARSIZE(t) - VARHDRSZ] = (char) 0;
+
+ /* load soundex into outstr */
+ soundex(instr, outstr);
+
+ /* Now the outstr contains the soundex of instr */
+ /* copy outstr to new_t */
+ new_t = (text *) palloc(strlen(outstr) + VARHDRSZ);
+ memset(new_t, 0, strlen(outstr) + 1);
+ VARSIZE(new_t) = strlen(outstr) + VARHDRSZ;
+ memcpy((void *) VARDATA(new_t),
+ (void *) outstr,
+ strlen(outstr));
+
+ /* free instr */
+ pfree(instr);
+
+ return (new_t);
}
-char *soundex(char *instr, char *outstr)
-{ /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
- char *table = "01230120022455012623010202";
- int count = 0;
-
- while(!isalpha(instr[0]) && instr[0])
- ++instr;
-
- if(!instr[0]) { /* Hey! Where'd the string go? */
- outstr[0]=(char)0;
- return outstr;
- }
-
- if(toupper(instr[0]) == 'P' && toupper(instr[1]) == 'H') {
- instr[0] = 'F';
- instr[1] = 'A';
- }
-
- *outstr++ = (char)toupper(*instr++);
-
- while(*instr && count < 5) {
- if(isalpha(*instr) && *instr != *(instr-1)) {
- *outstr = table[toupper(instr[0]) - 'A'];
- if(*outstr != '0') {
- ++outstr;
- ++count;
- }
- }
- ++instr;
- }
-
- *outstr = '\0';
- return(outstr);
+char *
+soundex(char *instr, char *outstr)
+{ /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
+ char *table = "01230120022455012623010202";
+ int count = 0;
+
+ while (!isalpha(instr[0]) && instr[0])
+ ++instr;
+
+ if (!instr[0])
+ { /* Hey! Where'd the string go? */
+ outstr[0] = (char) 0;
+ return outstr;
+ }
+
+ if (toupper(instr[0]) == 'P' && toupper(instr[1]) == 'H')
+ {
+ instr[0] = 'F';
+ instr[1] = 'A';
+ }
+
+ *outstr++ = (char) toupper(*instr++);
+
+ while (*instr && count < 5)
+ {
+ if (isalpha(*instr) && *instr != *(instr - 1))
+ {
+ *outstr = table[toupper(instr[0]) - 'A'];
+ if (*outstr != '0')
+ {
+ ++outstr;
+ ++count;
+ }
+ }
+ ++instr;
+ }
+
+ *outstr = '\0';
+ return (outstr);
}
-
diff --git a/contrib/string/string_io.c b/contrib/string/string_io.c
index b6158c74e43..e2cb2017c68 100644
--- a/contrib/string/string_io.c
+++ b/contrib/string/string_io.c
@@ -17,14 +17,14 @@
/* define this if you want to see iso-8859 characters */
#define ISO8859
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-#define VALUE(char) ((char) - '0')
-#define DIGIT(val) ((val) + '0')
-#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#define VALUE(char) ((char) - '0')
+#define DIGIT(val) ((val) + '0')
+#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
#ifndef ISO8859
-#define NOTPRINTABLE(c) (!isprint(c))
+#define NOTPRINTABLE(c) (!isprint(c))
#else
-#define NOTPRINTABLE(c) (!isprint(c) && ((c) < 0xa0))
+#define NOTPRINTABLE(c) (!isprint(c) && ((c) < 0xa0))
#endif
/*
@@ -36,115 +36,129 @@
* The function is used by output methods of various string types.
*
* Arguments:
- * data - input data (can be NULL)
- * size - optional size of data. A negative value indicates
- * that data is a null terminated string.
+ * data - input data (can be NULL)
+ * size - optional size of data. A negative value indicates
+ * that data is a null terminated string.
*
* Returns:
- * a pointer to a new string containing the printable
- * representation of data.
+ * a pointer to a new string containing the printable
+ * representation of data.
*/
-char *
+char *
string_output(char *data, int size)
{
- register unsigned char c, *p, *r, *result;
- register int l, len;
+ register unsigned char c,
+ *p,
+ *r,
+ *result;
+ register int l,
+ len;
+
+ if (data == NULL)
+ {
+ result = (char *) palloc(2);
+ result[0] = '-';
+ result[1] = '\0';
+ return (result);
+ }
- if (data == NULL) {
- result = (char *) palloc(2);
- result[0] = '-';
- result[1] = '\0';
- return (result);
- }
-
- if (size < 0) {
- size = strlen(data);
- }
-
- /* adjust string length for escapes */
- len = size;
- for (p=data,l=size; l>0; p++,l--) {
- switch (*p) {
- case '\\':
- case '"' :
- case '{':
- case '}':
- case '\b':
- case '\f':
- case '\n':
- case '\r':
- case '\t':
- case '\v':
- len++;
- break;
- default:
- if (NOTPRINTABLE(*p)) {
- len += 3;
- }
+ if (size < 0)
+ {
+ size = strlen(data);
+ }
+
+ /* adjust string length for escapes */
+ len = size;
+ for (p = data, l = size; l > 0; p++, l--)
+ {
+ switch (*p)
+ {
+ case '\\':
+ case '"':
+ case '{':
+ case '}':
+ case '\b':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '\v':
+ len++;
+ break;
+ default:
+ if (NOTPRINTABLE(*p))
+ {
+ len += 3;
+ }
+ }
}
- }
- len++;
-
- result = (char *) palloc(len);
-
- for (p=data,r=result,l=size; (l > 0) && (c = *p); p++,l--) {
- switch (c) {
- case '\\':
- case '"' :
- case '{':
- case '}':
- *r++ = '\\';
- *r++ = c;
- break;
- case '\b':
- *r++ = '\\';
- *r++ = 'b';
- break;
- case '\f':
- *r++ = '\\';
- *r++ = 'f';
- break;
- case '\n':
- *r++ = '\\';
- *r++ = 'n';
- break;
- case '\r':
- *r++ = '\\';
- *r++ = 'r';
- break;
- case '\t':
- *r++ = '\\';
- *r++ = 't';
- break;
- case '\v':
- *r++ = '\\';
- *r++ = 'v';
- break;
- default:
- if (NOTPRINTABLE(c)) {
- *r = '\\';
- r += 3;
- *r-- = DIGIT(c & 07);
- c >>= 3;
- *r-- = DIGIT(c & 07);
- c >>= 3;
- *r = DIGIT(c & 03);
- r += 3;
- } else {
- *r++ = c;
- }
+ len++;
+
+ result = (char *) palloc(len);
+
+ for (p = data, r = result, l = size; (l > 0) && (c = *p); p++, l--)
+ {
+ switch (c)
+ {
+ case '\\':
+ case '"':
+ case '{':
+ case '}':
+ *r++ = '\\';
+ *r++ = c;
+ break;
+ case '\b':
+ *r++ = '\\';
+ *r++ = 'b';
+ break;
+ case '\f':
+ *r++ = '\\';
+ *r++ = 'f';
+ break;
+ case '\n':
+ *r++ = '\\';
+ *r++ = 'n';
+ break;
+ case '\r':
+ *r++ = '\\';
+ *r++ = 'r';
+ break;
+ case '\t':
+ *r++ = '\\';
+ *r++ = 't';
+ break;
+ case '\v':
+ *r++ = '\\';
+ *r++ = 'v';
+ break;
+ default:
+ if (NOTPRINTABLE(c))
+ {
+ *r = '\\';
+ r += 3;
+ *r-- = DIGIT(c & 07);
+ c >>= 3;
+ *r-- = DIGIT(c & 07);
+ c >>= 3;
+ *r = DIGIT(c & 03);
+ r += 3;
+ }
+ else
+ {
+ *r++ = c;
+ }
+ }
}
- }
- *r = '\0';
+ *r = '\0';
- return((char *) result);
+ return ((char *) result);
}
/*
* string_input() --
*
- * This function accepts a C string in input and copies it into a new
+ * This function accepts a C string in input and copies it into a new
* object allocated with palloc() translating all escape sequences.
* An optional header can be allocatd before the string, for example
* to hold the length of a varlena object.
@@ -153,209 +167,231 @@ string_output(char *data, int size)
* receive strings in internal form.
*
* Arguments:
- * str - input string possibly with escapes
- * size - the required size of new data. A value of 0
- * indicates a variable size string, while a
- * negative value indicates a variable size string
- * of size not greater than this absolute value.
- * hdrsize - size of an optional header to be allocated before
- * the data. It must then be filled by the caller.
- * rtn_size - an optional pointer to an int variable where the
- * size of the new string is stored back.
+ * str - input string possibly with escapes
+ * size - the required size of new data. A value of 0
+ * indicates a variable size string, while a
+ * negative value indicates a variable size string
+ * of size not greater than this absolute value.
+ * hdrsize - size of an optional header to be allocated before
+ * the data. It must then be filled by the caller.
+ * rtn_size - an optional pointer to an int variable where the
+ * size of the new string is stored back.
*
* Returns:
- * a pointer to the new string or the header.
+ * a pointer to the new string or the header.
*/
-char *
+char *
string_input(char *str, int size, int hdrsize, int *rtn_size)
{
- register unsigned char *p, *r;
- unsigned char *result;
- int len;
-
- if ((str == NULL) || (hdrsize < 0)) {
- return (char *) NULL;
- }
-
- /* Compute result size */
- len = strlen(str);
- for (p=str; *p; ) {
- if (*p++ == '\\') {
- if (ISOCTAL(*p)) {
- if (ISOCTAL(*(p+1))) {
- p++;
- len--;
- }
- if (ISOCTAL(*(p+1))) {
- p++;
- len--;
+ register unsigned char *p,
+ *r;
+ unsigned char *result;
+ int len;
+
+ if ((str == NULL) || (hdrsize < 0))
+ {
+ return (char *) NULL;
+ }
+
+ /* Compute result size */
+ len = strlen(str);
+ for (p = str; *p;)
+ {
+ if (*p++ == '\\')
+ {
+ if (ISOCTAL(*p))
+ {
+ if (ISOCTAL(*(p + 1)))
+ {
+ p++;
+ len--;
+ }
+ if (ISOCTAL(*(p + 1)))
+ {
+ p++;
+ len--;
+ }
+ }
+ if (*p)
+ p++;
+ len--;
}
- }
- if (*p) p++;
- len--;
}
- }
-
- /* result has variable length */
- if (size == 0) {
- size = len+1;
- } else
-
- /* result has variable length with maximum size */
- if (size < 0) {
- size = MIN(len, - size)+1;
- }
-
- result = (char *) palloc(hdrsize+size);
- memset(result, 0, hdrsize+size);
- if (rtn_size) {
- *rtn_size = size;
- }
-
- r = result + hdrsize;
- for (p=str; *p; ) {
- register unsigned char c;
- if ((c = *p++) == '\\') {
- switch (c = *p++) {
- case '\0':
- p--;
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- c = VALUE(c);
- if (isdigit(*p)) {
- c = (c<<3) + VALUE(*p++);
+
+ /* result has variable length */
+ if (size == 0)
+ {
+ size = len + 1;
+ }
+ else
+ /* result has variable length with maximum size */
+ if (size < 0)
+ {
+ size = MIN(len, -size) + 1;
+ }
+
+ result = (char *) palloc(hdrsize + size);
+ memset(result, 0, hdrsize + size);
+ if (rtn_size)
+ {
+ *rtn_size = size;
+ }
+
+ r = result + hdrsize;
+ for (p = str; *p;)
+ {
+ register unsigned char c;
+
+ if ((c = *p++) == '\\')
+ {
+ switch (c = *p++)
+ {
+ case '\0':
+ p--;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ c = VALUE(c);
+ if (isdigit(*p))
+ {
+ c = (c << 3) + VALUE(*p++);
+ }
+ if (isdigit(*p))
+ {
+ c = (c << 3) + VALUE(*p++);
+ }
+ *r++ = c;
+ break;
+ case 'b':
+ *r++ = '\b';
+ break;
+ case 'f':
+ *r++ = '\f';
+ break;
+ case 'n':
+ *r++ = '\n';
+ break;
+ case 'r':
+ *r++ = '\r';
+ break;
+ case 't':
+ *r++ = '\t';
+ break;
+ case 'v':
+ *r++ = '\v';
+ break;
+ default:
+ *r++ = c;
+ }
}
- if (isdigit(*p)) {
- c = (c<<3) + VALUE(*p++);
+ else
+ {
+ *r++ = c;
}
- *r++ = c;
- break;
- case 'b':
- *r++ = '\b';
- break;
- case 'f':
- *r++ = '\f';
- break;
- case 'n':
- *r++ = '\n';
- break;
- case 'r':
- *r++ = '\r';
- break;
- case 't':
- *r++ = '\t';
- break;
- case 'v':
- *r++ = '\v';
- break;
- default:
- *r++ = c;
- }
- } else {
- *r++ = c;
}
- }
- return((char *) result);
+ return ((char *) result);
}
-char *
+char *
c_charout(int32 c)
{
- char str[2];
+ char str[2];
- str[0] = (char) c;
- str[1] = '\0';
+ str[0] = (char) c;
+ str[1] = '\0';
- return (string_output(str, 1));
+ return (string_output(str, 1));
}
-char *
+char *
c_char2out(uint16 s)
{
- return (string_output((char *) &s, 2));
+ return (string_output((char *) &s, 2));
}
-char *
+char *
c_char4out(uint32 s)
{
- return (string_output((char *) &s, 4));
+ return (string_output((char *) &s, 4));
}
-char *
+char *
c_char8out(char *s)
{
- return (string_output(s, 8));
+ return (string_output(s, 8));
}
-char *
+char *
c_char16out(char *s)
{
- return (string_output(s, 16));
+ return (string_output(s, 16));
}
/*
* This can be used for text, bytea, SET and unknown data types
*/
-char *
-c_textout(struct varlena *vlena)
+char *
+c_textout(struct varlena * vlena)
{
- int len = 0;
- char *s = NULL;
-
- if (vlena) {
- len = VARSIZE(vlena) - VARHDRSZ;
- s = VARDATA(vlena);
- }
- return (string_output(s, len));
+ int len = 0;
+ char *s = NULL;
+
+ if (vlena)
+ {
+ len = VARSIZE(vlena) - VARHDRSZ;
+ s = VARDATA(vlena);
+ }
+ return (string_output(s, len));
}
/*
* This can be used for varchar and bpchar strings
*/
-char *
+char *
c_varcharout(char *s)
{
- int len;
+ int len;
- if (s) {
- len = *(int32*)s - 4;
- s += 4;
- }
- return (string_output(s, len));
+ if (s)
+ {
+ len = *(int32 *) s - 4;
+ s += 4;
+ }
+ return (string_output(s, len));
}
#ifdef 0
struct varlena *
c_textin(char *str)
{
- struct varlena *result;
- int len;
+ struct varlena *result;
+ int len;
- if (str == NULL) {
- return ((struct varlena *) NULL);
- }
+ if (str == NULL)
+ {
+ return ((struct varlena *) NULL);
+ }
- result = (struct varlena *) string_input(str, 0, VARHDRSZ, &len);
- VARSIZE(result) = len;
+ result = (struct varlena *) string_input(str, 0, VARHDRSZ, &len);
+ VARSIZE(result) = len;
- return (result);
+ return (result);
}
-char *
+char *
c_char16in(char *str)
{
- return (string_input(str, 16, 0, NULL));
+ return (string_input(str, 16, 0, NULL));
}
-#endif
+#endif
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
index 60ec3e4d3ab..17257690303 100644
--- a/src/backend/access/common/heaptuple.c
+++ b/src/backend/access/common/heaptuple.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* heaptuple.c--
- * This file contains heap tuple accessor and mutator routines, as well
- * as a few various tuple utilities.
+ * This file contains heap tuple accessor and mutator routines, as well
+ * as a few various tuple utilities.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.21 1997/08/26 23:31:20 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.22 1997/09/07 04:37:30 momjian Exp $
*
* NOTES
- * The old interface functions have been converted to macros
- * and moved to heapam.h
+ * The old interface functions have been converted to macros
+ * and moved to heapam.h
*
*-------------------------------------------------------------------------
*/
@@ -27,9 +27,9 @@
#include <utils/memutils.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
@@ -37,902 +37,991 @@
#if !defined(NO_ASSERT_CHECKING) && defined(sparc) && defined(sunos4)
#define register
-#endif /* !NO_ASSERT_CHECKING && sparc && sunos4 */
+#endif /* !NO_ASSERT_CHECKING && sparc && sunos4 */
/* ----------------------------------------------------------------
- * misc support routines
+ * misc support routines
* ----------------------------------------------------------------
*/
/* ----------------
- * ComputeDataSize
+ * ComputeDataSize
* ----------------
*/
Size
ComputeDataSize(TupleDesc tupleDesc,
- Datum value[],
- char nulls[])
+ Datum value[],
+ char nulls[])
{
- uint32 data_length;
- int i;
- int numberOfAttributes = tupleDesc->natts;
- AttributeTupleForm *att = tupleDesc->attrs;
-
- for (data_length = 0, i = 0; i < numberOfAttributes; i++) {
- if (nulls[i] != ' ') continue;
-
- switch (att[i]->attlen) {
- case -1:
- /*
- * This is the size of the disk representation and so
- * must include the additional sizeof long.
- */
- if (att[i]->attalign == 'd') {
- data_length = DOUBLEALIGN(data_length)
- + VARSIZE(DatumGetPointer(value[i]));
- } else {
- data_length = INTALIGN(data_length)
- + VARSIZE(DatumGetPointer(value[i]));
- }
- break;
- case sizeof(char):
- data_length++;
- break;
- case sizeof(short):
- data_length = SHORTALIGN(data_length + sizeof(short));
- break;
- case sizeof(int32):
- data_length = INTALIGN(data_length + sizeof(int32));
- break;
- default:
- if (att[i]->attlen < sizeof(int32))
- elog(WARN, "ComputeDataSize: attribute %d has len %d",
- i, att[i]->attlen);
- if (att[i]->attalign == 'd')
- data_length = DOUBLEALIGN(data_length) + att[i]->attlen;
- else
- data_length = LONGALIGN(data_length) + att[i]->attlen;
- break;
+ uint32 data_length;
+ int i;
+ int numberOfAttributes = tupleDesc->natts;
+ AttributeTupleForm *att = tupleDesc->attrs;
+
+ for (data_length = 0, i = 0; i < numberOfAttributes; i++)
+ {
+ if (nulls[i] != ' ')
+ continue;
+
+ switch (att[i]->attlen)
+ {
+ case -1:
+
+ /*
+ * This is the size of the disk representation and so must
+ * include the additional sizeof long.
+ */
+ if (att[i]->attalign == 'd')
+ {
+ data_length = DOUBLEALIGN(data_length)
+ + VARSIZE(DatumGetPointer(value[i]));
+ }
+ else
+ {
+ data_length = INTALIGN(data_length)
+ + VARSIZE(DatumGetPointer(value[i]));
+ }
+ break;
+ case sizeof(char):
+ data_length++;
+ break;
+ case sizeof(short):
+ data_length = SHORTALIGN(data_length + sizeof(short));
+ break;
+ case sizeof(int32):
+ data_length = INTALIGN(data_length + sizeof(int32));
+ break;
+ default:
+ if (att[i]->attlen < sizeof(int32))
+ elog(WARN, "ComputeDataSize: attribute %d has len %d",
+ i, att[i]->attlen);
+ if (att[i]->attalign == 'd')
+ data_length = DOUBLEALIGN(data_length) + att[i]->attlen;
+ else
+ data_length = LONGALIGN(data_length) + att[i]->attlen;
+ break;
+ }
}
- }
-
- return data_length;
+
+ return data_length;
}
/* ----------------
- * DataFill
+ * DataFill
* ----------------
*/
void
DataFill(char *data,
- TupleDesc tupleDesc,
- Datum value[],
- char nulls[],
- char *infomask,
- bits8 *bit)
+ TupleDesc tupleDesc,
+ Datum value[],
+ char nulls[],
+ char *infomask,
+ bits8 * bit)
{
- bits8 *bitP = 0;
- int bitmask = 0;
- uint32 data_length;
- int i;
- int numberOfAttributes = tupleDesc->natts;
- AttributeTupleForm *att = tupleDesc->attrs;
-
- if (bit != NULL) {
- bitP = &bit[-1];
- bitmask = CSIGNBIT;
- }
-
- *infomask = 0;
-
- for (i = 0; i < numberOfAttributes; i++) {
- if (bit != NULL) {
- if (bitmask != CSIGNBIT) {
- bitmask <<= 1;
- } else {
- bitP += 1;
- *bitP = 0x0;
- bitmask = 1;
- }
-
- if (nulls[i] == 'n') {
- *infomask |= HEAP_HASNULL;
- continue;
- }
-
- *bitP |= bitmask;
+ bits8 *bitP = 0;
+ int bitmask = 0;
+ uint32 data_length;
+ int i;
+ int numberOfAttributes = tupleDesc->natts;
+ AttributeTupleForm *att = tupleDesc->attrs;
+
+ if (bit != NULL)
+ {
+ bitP = &bit[-1];
+ bitmask = CSIGNBIT;
}
-
- switch (att[i]->attlen) {
- case -1:
- *infomask |= HEAP_HASVARLENA;
- if (att[i]->attalign=='d') {
- data = (char *) DOUBLEALIGN(data);
- } else {
- data = (char *) INTALIGN(data);
- }
- data_length = VARSIZE(DatumGetPointer(value[i]));
- memmove(data, DatumGetPointer(value[i]),data_length);
- data += data_length;
- break;
- case sizeof(char):
- *data = att[i]->attbyval ?
- DatumGetChar(value[i]) : *((char *) value[i]);
- data += sizeof(char);
- break;
- case sizeof(int16):
- data = (char *) SHORTALIGN(data);
- * (short *) data = (att[i]->attbyval ?
- DatumGetInt16(value[i]) :
- *((short *) value[i]));
- data += sizeof(short);
- break;
- case sizeof(int32):
- data = (char *) INTALIGN(data);
- * (int32 *) data = (att[i]->attbyval ?
- DatumGetInt32(value[i]) :
- *((int32 *) value[i]));
- data += sizeof(int32);
- break;
- default:
- if (att[i]->attlen < sizeof(int32))
- elog(WARN, "DataFill: attribute %d has len %d",
- i, att[i]->attlen);
- if (att[i]->attalign == 'd') {
- data = (char *) DOUBLEALIGN(data);
- memmove(data, DatumGetPointer(value[i]),
- att[i]->attlen);
- data += att[i]->attlen;
- } else {
- data = (char *) LONGALIGN(data);
- memmove(data, DatumGetPointer(value[i]),
- att[i]->attlen);
- data += att[i]->attlen;
- }
- break;
+
+ *infomask = 0;
+
+ for (i = 0; i < numberOfAttributes; i++)
+ {
+ if (bit != NULL)
+ {
+ if (bitmask != CSIGNBIT)
+ {
+ bitmask <<= 1;
+ }
+ else
+ {
+ bitP += 1;
+ *bitP = 0x0;
+ bitmask = 1;
+ }
+
+ if (nulls[i] == 'n')
+ {
+ *infomask |= HEAP_HASNULL;
+ continue;
+ }
+
+ *bitP |= bitmask;
+ }
+
+ switch (att[i]->attlen)
+ {
+ case -1:
+ *infomask |= HEAP_HASVARLENA;
+ if (att[i]->attalign == 'd')
+ {
+ data = (char *) DOUBLEALIGN(data);
+ }
+ else
+ {
+ data = (char *) INTALIGN(data);
+ }
+ data_length = VARSIZE(DatumGetPointer(value[i]));
+ memmove(data, DatumGetPointer(value[i]), data_length);
+ data += data_length;
+ break;
+ case sizeof(char):
+ *data = att[i]->attbyval ?
+ DatumGetChar(value[i]) : *((char *) value[i]);
+ data += sizeof(char);
+ break;
+ case sizeof(int16):
+ data = (char *) SHORTALIGN(data);
+ *(short *) data = (att[i]->attbyval ?
+ DatumGetInt16(value[i]) :
+ *((short *) value[i]));
+ data += sizeof(short);
+ break;
+ case sizeof(int32):
+ data = (char *) INTALIGN(data);
+ *(int32 *) data = (att[i]->attbyval ?
+ DatumGetInt32(value[i]) :
+ *((int32 *) value[i]));
+ data += sizeof(int32);
+ break;
+ default:
+ if (att[i]->attlen < sizeof(int32))
+ elog(WARN, "DataFill: attribute %d has len %d",
+ i, att[i]->attlen);
+ if (att[i]->attalign == 'd')
+ {
+ data = (char *) DOUBLEALIGN(data);
+ memmove(data, DatumGetPointer(value[i]),
+ att[i]->attlen);
+ data += att[i]->attlen;
+ }
+ else
+ {
+ data = (char *) LONGALIGN(data);
+ memmove(data, DatumGetPointer(value[i]),
+ att[i]->attlen);
+ data += att[i]->attlen;
+ }
+ break;
+ }
}
- }
}
/* ----------------------------------------------------------------
- * heap tuple interface
+ * heap tuple interface
* ----------------------------------------------------------------
*/
/* ----------------
- * heap_attisnull - returns 1 iff tuple attribute is not present
+ * heap_attisnull - returns 1 iff tuple attribute is not present
* ----------------
*/
int
heap_attisnull(HeapTuple tup, int attnum)
{
- if (attnum > (int)tup->t_natts)
- return (1);
-
- if (HeapTupleNoNulls(tup)) return(0);
-
- if (attnum > 0) {
- return(att_isnull(attnum - 1, tup->t_bits));
- } else
- switch (attnum) {
- case SelfItemPointerAttributeNumber:
- case ObjectIdAttributeNumber:
- case MinTransactionIdAttributeNumber:
- case MinCommandIdAttributeNumber:
- case MaxTransactionIdAttributeNumber:
- case MaxCommandIdAttributeNumber:
- case ChainItemPointerAttributeNumber:
- case AnchorItemPointerAttributeNumber:
- case MinAbsoluteTimeAttributeNumber:
- case MaxAbsoluteTimeAttributeNumber:
- case VersionTypeAttributeNumber:
- break;
-
- case 0:
- elog(WARN, "heap_attisnull: zero attnum disallowed");
-
- default:
- elog(WARN, "heap_attisnull: undefined negative attnum");
+ if (attnum > (int) tup->t_natts)
+ return (1);
+
+ if (HeapTupleNoNulls(tup))
+ return (0);
+
+ if (attnum > 0)
+ {
+ return (att_isnull(attnum - 1, tup->t_bits));
}
-
- return (0);
+ else
+ switch (attnum)
+ {
+ case SelfItemPointerAttributeNumber:
+ case ObjectIdAttributeNumber:
+ case MinTransactionIdAttributeNumber:
+ case MinCommandIdAttributeNumber:
+ case MaxTransactionIdAttributeNumber:
+ case MaxCommandIdAttributeNumber:
+ case ChainItemPointerAttributeNumber:
+ case AnchorItemPointerAttributeNumber:
+ case MinAbsoluteTimeAttributeNumber:
+ case MaxAbsoluteTimeAttributeNumber:
+ case VersionTypeAttributeNumber:
+ break;
+
+ case 0:
+ elog(WARN, "heap_attisnull: zero attnum disallowed");
+
+ default:
+ elog(WARN, "heap_attisnull: undefined negative attnum");
+ }
+
+ return (0);
}
/* ----------------------------------------------------------------
- * system attribute heap tuple support
+ * system attribute heap tuple support
* ----------------------------------------------------------------
*/
/* ----------------
- * heap_sysattrlen
+ * heap_sysattrlen
*
- * This routine returns the length of a system attribute.
+ * This routine returns the length of a system attribute.
* ----------------
*/
int
heap_sysattrlen(AttrNumber attno)
{
- HeapTupleData *f = NULL;
-
- switch (attno) {
- case SelfItemPointerAttributeNumber: return sizeof f->t_ctid;
- case ObjectIdAttributeNumber: return sizeof f->t_oid;
- case MinTransactionIdAttributeNumber: return sizeof f->t_xmin;
- case MinCommandIdAttributeNumber: return sizeof f->t_cmin;
- case MaxTransactionIdAttributeNumber: return sizeof f->t_xmax;
- case MaxCommandIdAttributeNumber: return sizeof f->t_cmax;
- case ChainItemPointerAttributeNumber: return sizeof f->t_chain;
- case MinAbsoluteTimeAttributeNumber: return sizeof f->t_tmin;
- case MaxAbsoluteTimeAttributeNumber: return sizeof f->t_tmax;
- case VersionTypeAttributeNumber: return sizeof f->t_vtype;
-
- case AnchorItemPointerAttributeNumber:
- elog(WARN, "heap_sysattrlen: field t_anchor does not exist!");
- return 0;
-
- default:
- elog(WARN, "sysattrlen: System attribute number %d unknown.", attno);
- return 0;
- }
+ HeapTupleData *f = NULL;
+
+ switch (attno)
+ {
+ case SelfItemPointerAttributeNumber:
+ return sizeof f->t_ctid;
+ case ObjectIdAttributeNumber:
+ return sizeof f->t_oid;
+ case MinTransactionIdAttributeNumber:
+ return sizeof f->t_xmin;
+ case MinCommandIdAttributeNumber:
+ return sizeof f->t_cmin;
+ case MaxTransactionIdAttributeNumber:
+ return sizeof f->t_xmax;
+ case MaxCommandIdAttributeNumber:
+ return sizeof f->t_cmax;
+ case ChainItemPointerAttributeNumber:
+ return sizeof f->t_chain;
+ case MinAbsoluteTimeAttributeNumber:
+ return sizeof f->t_tmin;
+ case MaxAbsoluteTimeAttributeNumber:
+ return sizeof f->t_tmax;
+ case VersionTypeAttributeNumber:
+ return sizeof f->t_vtype;
+
+ case AnchorItemPointerAttributeNumber:
+ elog(WARN, "heap_sysattrlen: field t_anchor does not exist!");
+ return 0;
+
+ default:
+ elog(WARN, "sysattrlen: System attribute number %d unknown.", attno);
+ return 0;
+ }
}
/* ----------------
- * heap_sysattrbyval
+ * heap_sysattrbyval
*
- * This routine returns the "by-value" property of a system attribute.
+ * This routine returns the "by-value" property of a system attribute.
* ----------------
*/
bool
heap_sysattrbyval(AttrNumber attno)
{
- bool byval;
-
- switch (attno) {
- case SelfItemPointerAttributeNumber:
- byval = false;
- break;
- case ObjectIdAttributeNumber:
- byval = true;
- break;
- case MinTransactionIdAttributeNumber:
- byval = true;
- break;
- case MinCommandIdAttributeNumber:
- byval = true;
- break;
- case MaxTransactionIdAttributeNumber:
- byval = true;
- break;
- case MaxCommandIdAttributeNumber:
- byval = true;
- break;
- case ChainItemPointerAttributeNumber:
- byval = false;
- break;
- case AnchorItemPointerAttributeNumber:
- byval = false;
- break;
- case MinAbsoluteTimeAttributeNumber:
- byval = true;
- break;
- case MaxAbsoluteTimeAttributeNumber:
- byval = true;
- break;
- case VersionTypeAttributeNumber:
- byval = true;
- break;
- default:
- byval = true;
- elog(WARN, "sysattrbyval: System attribute number %d unknown.",
- attno);
- break;
- }
-
- return byval;
+ bool byval;
+
+ switch (attno)
+ {
+ case SelfItemPointerAttributeNumber:
+ byval = false;
+ break;
+ case ObjectIdAttributeNumber:
+ byval = true;
+ break;
+ case MinTransactionIdAttributeNumber:
+ byval = true;
+ break;
+ case MinCommandIdAttributeNumber:
+ byval = true;
+ break;
+ case MaxTransactionIdAttributeNumber:
+ byval = true;
+ break;
+ case MaxCommandIdAttributeNumber:
+ byval = true;
+ break;
+ case ChainItemPointerAttributeNumber:
+ byval = false;
+ break;
+ case AnchorItemPointerAttributeNumber:
+ byval = false;
+ break;
+ case MinAbsoluteTimeAttributeNumber:
+ byval = true;
+ break;
+ case MaxAbsoluteTimeAttributeNumber:
+ byval = true;
+ break;
+ case VersionTypeAttributeNumber:
+ byval = true;
+ break;
+ default:
+ byval = true;
+ elog(WARN, "sysattrbyval: System attribute number %d unknown.",
+ attno);
+ break;
+ }
+
+ return byval;
}
/* ----------------
- * heap_getsysattr
+ * heap_getsysattr
* ----------------
*/
-char *
+char *
heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
{
- switch (attnum) {
- case SelfItemPointerAttributeNumber:
- return ((char *)&tup->t_ctid);
- case ObjectIdAttributeNumber:
- return ((char *) (long) tup->t_oid);
- case MinTransactionIdAttributeNumber:
- return ((char *) (long) tup->t_xmin);
- case MinCommandIdAttributeNumber:
- return ((char *) (long) tup->t_cmin);
- case MaxTransactionIdAttributeNumber:
- return ((char *) (long) tup->t_xmax);
- case MaxCommandIdAttributeNumber:
- return ((char *) (long) tup->t_cmax);
- case ChainItemPointerAttributeNumber:
- return ((char *) &tup->t_chain);
- case AnchorItemPointerAttributeNumber:
- elog(WARN, "heap_getsysattr: t_anchor does not exist!");
- break;
-
- /*
- * For tmin and tmax, we need to do some extra work. These don't
- * get filled in until the vacuum cleaner runs (or we manage to flush
- * a page after setting the value correctly below). If the vacuum
- * cleaner hasn't run yet, then the times stored in the tuple are
- * wrong, and we need to look up the commit time of the transaction.
- * We cache this value in the tuple to avoid doing the work more than
- * once.
- */
-
- case MinAbsoluteTimeAttributeNumber:
- if (!AbsoluteTimeIsBackwardCompatiblyValid(tup->t_tmin) &&
- TransactionIdDidCommit(tup->t_xmin))
- tup->t_tmin = TransactionIdGetCommitTime(tup->t_xmin);
- return ((char *) (long) tup->t_tmin);
- case MaxAbsoluteTimeAttributeNumber:
- if (!AbsoluteTimeIsBackwardCompatiblyReal(tup->t_tmax)) {
- if (TransactionIdDidCommit(tup->t_xmax))
- tup->t_tmax = TransactionIdGetCommitTime(tup->t_xmax);
- else
- tup->t_tmax = CURRENT_ABSTIME;
+ switch (attnum)
+ {
+ case SelfItemPointerAttributeNumber:
+ return ((char *) &tup->t_ctid);
+ case ObjectIdAttributeNumber:
+ return ((char *) (long) tup->t_oid);
+ case MinTransactionIdAttributeNumber:
+ return ((char *) (long) tup->t_xmin);
+ case MinCommandIdAttributeNumber:
+ return ((char *) (long) tup->t_cmin);
+ case MaxTransactionIdAttributeNumber:
+ return ((char *) (long) tup->t_xmax);
+ case MaxCommandIdAttributeNumber:
+ return ((char *) (long) tup->t_cmax);
+ case ChainItemPointerAttributeNumber:
+ return ((char *) &tup->t_chain);
+ case AnchorItemPointerAttributeNumber:
+ elog(WARN, "heap_getsysattr: t_anchor does not exist!");
+ break;
+
+ /*
+ * For tmin and tmax, we need to do some extra work. These don't
+ * get filled in until the vacuum cleaner runs (or we manage to
+ * flush a page after setting the value correctly below). If the
+ * vacuum cleaner hasn't run yet, then the times stored in the
+ * tuple are wrong, and we need to look up the commit time of the
+ * transaction. We cache this value in the tuple to avoid doing
+ * the work more than once.
+ */
+
+ case MinAbsoluteTimeAttributeNumber:
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(tup->t_tmin) &&
+ TransactionIdDidCommit(tup->t_xmin))
+ tup->t_tmin = TransactionIdGetCommitTime(tup->t_xmin);
+ return ((char *) (long) tup->t_tmin);
+ case MaxAbsoluteTimeAttributeNumber:
+ if (!AbsoluteTimeIsBackwardCompatiblyReal(tup->t_tmax))
+ {
+ if (TransactionIdDidCommit(tup->t_xmax))
+ tup->t_tmax = TransactionIdGetCommitTime(tup->t_xmax);
+ else
+ tup->t_tmax = CURRENT_ABSTIME;
+ }
+ return ((char *) (long) tup->t_tmax);
+ case VersionTypeAttributeNumber:
+ return ((char *) (long) tup->t_vtype);
+ default:
+ elog(WARN, "heap_getsysattr: undefined attnum %d", attnum);
}
- return ((char *) (long) tup->t_tmax);
- case VersionTypeAttributeNumber:
- return ((char *) (long) tup->t_vtype);
- default:
- elog(WARN, "heap_getsysattr: undefined attnum %d", attnum);
- }
- return(NULL);
+ return (NULL);
}
/* ----------------
- * fastgetattr
+ * fastgetattr
*
- * This is a newer version of fastgetattr which attempts to be
- * faster by caching attribute offsets in the attribute descriptor.
+ * This is a newer version of fastgetattr which attempts to be
+ * faster by caching attribute offsets in the attribute descriptor.
*
- * an alternate way to speed things up would be to cache offsets
- * with the tuple, but that seems more difficult unless you take
- * the storage hit of actually putting those offsets into the
- * tuple you send to disk. Yuck.
+ * an alternate way to speed things up would be to cache offsets
+ * with the tuple, but that seems more difficult unless you take
+ * the storage hit of actually putting those offsets into the
+ * tuple you send to disk. Yuck.
*
- * This scheme will be slightly slower than that, but should
- * preform well for queries which hit large #'s of tuples. After
- * you cache the offsets once, examining all the other tuples using
- * the same attribute descriptor will go much quicker. -cim 5/4/91
+ * This scheme will be slightly slower than that, but should
+ * preform well for queries which hit large #'s of tuples. After
+ * you cache the offsets once, examining all the other tuples using
+ * the same attribute descriptor will go much quicker. -cim 5/4/91
* ----------------
*/
-char *
+char *
fastgetattr(HeapTuple tup,
- int attnum,
- TupleDesc tupleDesc,
- bool *isnull)
+ int attnum,
+ TupleDesc tupleDesc,
+ bool * isnull)
{
- char *tp; /* ptr to att in tuple */
- bits8 *bp = NULL; /* ptr to att in tuple */
- int slow; /* do we have to walk nulls? */
- AttributeTupleForm *att = tupleDesc->attrs;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
-
- Assert(attnum > 0);
-
- /* ----------------
- * Three cases:
- *
- * 1: No nulls and no variable length attributes.
- * 2: Has a null or a varlena AFTER att.
- * 3: Has nulls or varlenas BEFORE att.
- * ----------------
- */
-
- if (isnull)
- *isnull = false;
-
- if (HeapTupleNoNulls(tup)) {
- attnum--;
- if (att[attnum]->attcacheoff > 0) {
- return (char *)
- fetchatt( &(att[attnum]),
- (char *)tup + tup->t_hoff + att[attnum]->attcacheoff);
- } else if (attnum == 0) {
- /*
- * first attribute is always at position zero
- */
- return((char *) fetchatt(&(att[0]), (char *) tup + tup->t_hoff));
- }
-
- tp = (char *) tup + tup->t_hoff;
-
- slow = 0;
- } else {
- /*
- * there's a null somewhere in the tuple
- */
+ char *tp; /* ptr to att in tuple */
+ bits8 *bp = NULL; /* ptr to att in tuple */
+ int slow; /* do we have to walk nulls? */
+ AttributeTupleForm *att = tupleDesc->attrs;
- bp = tup->t_bits;
- tp = (char *) tup + tup->t_hoff;
- slow = 0;
- attnum--;
-
/* ----------------
- * check to see if desired att is null
+ * sanity checks
* ----------------
*/
-
- if (att_isnull(attnum, bp)) {
- if (isnull)
- *isnull = true;
- return NULL;
- }
+
+ Assert(attnum > 0);
/* ----------------
- * Now check to see if any preceeding bits are null...
+ * Three cases:
+ *
+ * 1: No nulls and no variable length attributes.
+ * 2: Has a null or a varlena AFTER att.
+ * 3: Has nulls or varlenas BEFORE att.
* ----------------
*/
-
+
+ if (isnull)
+ *isnull = false;
+
+ if (HeapTupleNoNulls(tup))
{
- register int i = 0; /* current offset in bp */
-
- for (i = 0; i < attnum && !slow; i++) {
- if (att_isnull(i, bp)) slow = 1;
- }
+ attnum--;
+ if (att[attnum]->attcacheoff > 0)
+ {
+ return (char *)
+ fetchatt(&(att[attnum]),
+ (char *) tup + tup->t_hoff + att[attnum]->attcacheoff);
+ }
+ else if (attnum == 0)
+ {
+
+ /*
+ * first attribute is always at position zero
+ */
+ return ((char *) fetchatt(&(att[0]), (char *) tup + tup->t_hoff));
+ }
+
+ tp = (char *) tup + tup->t_hoff;
+
+ slow = 0;
}
- }
-
- /*
- * now check for any non-fixed length attrs before our attribute
- */
- if (!slow) {
- if (att[attnum]->attcacheoff > 0) {
- return (char *)
- fetchatt(&(att[attnum]),
- tp + att[attnum]->attcacheoff);
- } else if (attnum == 0) {
- return (char *)
- fetchatt(&(att[0]), (char *) tup + tup->t_hoff);
- } else if (!HeapTupleAllFixed(tup)) {
- register int j = 0;
-
- for (j = 0; j < attnum && !slow; j++)
- if (att[j]->attlen < 1) slow = 1;
+ else
+ {
+
+ /*
+ * there's a null somewhere in the tuple
+ */
+
+ bp = tup->t_bits;
+ tp = (char *) tup + tup->t_hoff;
+ slow = 0;
+ attnum--;
+
+ /* ----------------
+ * check to see if desired att is null
+ * ----------------
+ */
+
+ if (att_isnull(attnum, bp))
+ {
+ if (isnull)
+ *isnull = true;
+ return NULL;
+ }
+
+ /* ----------------
+ * Now check to see if any preceeding bits are null...
+ * ----------------
+ */
+
+ {
+ register int i = 0; /* current offset in bp */
+
+ for (i = 0; i < attnum && !slow; i++)
+ {
+ if (att_isnull(i, bp))
+ slow = 1;
+ }
+ }
}
- }
-
- /*
- * if slow is zero, and we got here, we know that we have a tuple with
- * no nulls. We also have to initialize the remainder of
- * the attribute cached offset values.
- */
- if (!slow) {
- register int j = 1;
- register long off;
-
+
/*
- * need to set cache for some atts
+ * now check for any non-fixed length attrs before our attribute
*/
-
- att[0]->attcacheoff = 0;
-
- while (att[j]->attcacheoff > 0) j++;
-
- off = att[j-1]->attcacheoff + att[j-1]->attlen;
-
- for (; j < attnum + 1; j++) {
- switch(att[j]->attlen) {
- case -1:
- off = (att[j]->attalign=='d') ?
- DOUBLEALIGN(off) : INTALIGN(off);
- break;
- case sizeof(char):
- break;
- case sizeof(short):
- off = SHORTALIGN(off);
- break;
- case sizeof(int32):
- off = INTALIGN(off);
- break;
- default:
- if (att[j]->attlen < sizeof(int32)) {
- elog(WARN,
- "fastgetattr: attribute %d has len %d",
- j, att[j]->attlen);
+ if (!slow)
+ {
+ if (att[attnum]->attcacheoff > 0)
+ {
+ return (char *)
+ fetchatt(&(att[attnum]),
+ tp + att[attnum]->attcacheoff);
+ }
+ else if (attnum == 0)
+ {
+ return (char *)
+ fetchatt(&(att[0]), (char *) tup + tup->t_hoff);
+ }
+ else if (!HeapTupleAllFixed(tup))
+ {
+ register int j = 0;
+
+ for (j = 0; j < attnum && !slow; j++)
+ if (att[j]->attlen < 1)
+ slow = 1;
}
- if (att[j]->attalign == 'd')
- off = DOUBLEALIGN(off);
- else
- off = LONGALIGN(off);
- break;
- }
-
- att[j]->attcacheoff = off;
- off += att[j]->attlen;
}
-
- return
- (char *)fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff);
- } else {
- register bool usecache = true;
- register int off = 0;
- register int i;
-
+
/*
- * Now we know that we have to walk the tuple CAREFULLY.
- *
- * Note - This loop is a little tricky. On iteration i we
- * first set the offset for attribute i and figure out how much
- * the offset should be incremented. Finally, we need to align the
- * offset based on the size of attribute i+1 (for which the offset
- * has been computed). -mer 12 Dec 1991
+ * if slow is zero, and we got here, we know that we have a tuple with
+ * no nulls. We also have to initialize the remainder of the
+ * attribute cached offset values.
*/
-
- for (i = 0; i < attnum; i++) {
- if (!HeapTupleNoNulls(tup)) {
- if (att_isnull(i, bp)) {
- usecache = false;
- continue;
- }
- }
- switch (att[i]->attlen) {
- case -1:
- off = (att[i]->attalign=='d') ?
- DOUBLEALIGN(off) : INTALIGN(off);
- break;
- case sizeof(char):
- break;
- case sizeof(short):
- off = SHORTALIGN(off);
- break;
- case sizeof(int32):
- off = INTALIGN(off);
- break;
- default:
- if (att[i]->attlen < sizeof(int32))
- elog(WARN,
- "fastgetattr2: attribute %d has len %d",
- i, att[i]->attlen);
- if (att[i]->attalign == 'd')
- off = DOUBLEALIGN(off);
- else
- off = LONGALIGN(off);
- break;
- }
- if (usecache && att[i]->attcacheoff > 0) {
- off = att[i]->attcacheoff;
- if (att[i]->attlen == -1) {
- usecache = false;
+ if (!slow)
+ {
+ register int j = 1;
+ register long off;
+
+ /*
+ * need to set cache for some atts
+ */
+
+ att[0]->attcacheoff = 0;
+
+ while (att[j]->attcacheoff > 0)
+ j++;
+
+ off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
+
+ for (; j < attnum + 1; j++)
+ {
+ switch (att[j]->attlen)
+ {
+ case -1:
+ off = (att[j]->attalign == 'd') ?
+ DOUBLEALIGN(off) : INTALIGN(off);
+ break;
+ case sizeof(char):
+ break;
+ case sizeof(short):
+ off = SHORTALIGN(off);
+ break;
+ case sizeof(int32):
+ off = INTALIGN(off);
+ break;
+ default:
+ if (att[j]->attlen < sizeof(int32))
+ {
+ elog(WARN,
+ "fastgetattr: attribute %d has len %d",
+ j, att[j]->attlen);
+ }
+ if (att[j]->attalign == 'd')
+ off = DOUBLEALIGN(off);
+ else
+ off = LONGALIGN(off);
+ break;
+ }
+
+ att[j]->attcacheoff = off;
+ off += att[j]->attlen;
}
- } else {
- if (usecache) att[i]->attcacheoff = off;
- }
-
- switch(att[i]->attlen) {
- case sizeof(char):
- off++;
- break;
- case sizeof(int16):
- off += sizeof(int16);
- break;
- case sizeof(int32):
- off += sizeof(int32);
- break;
- case -1:
- usecache = false;
- off += VARSIZE(tp + off);
- break;
- default:
- off += att[i]->attlen;
- break;
- }
+
+ return
+ (char *) fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff);
}
- switch (att[attnum]->attlen) {
- case -1:
- off = (att[attnum]->attalign=='d')?
- DOUBLEALIGN(off) : INTALIGN(off);
- break;
- case sizeof(char):
- break;
- case sizeof(short):
- off = SHORTALIGN(off);
- break;
- case sizeof(int32):
- off = INTALIGN(off);
- break;
- default:
- if (att[attnum]->attlen < sizeof(int32))
- elog(WARN, "fastgetattr3: attribute %d has len %d",
- attnum, att[attnum]->attlen);
- if (att[attnum]->attalign == 'd')
- off = DOUBLEALIGN(off);
- else
- off = LONGALIGN(off);
- break;
+ else
+ {
+ register bool usecache = true;
+ register int off = 0;
+ register int i;
+
+ /*
+ * Now we know that we have to walk the tuple CAREFULLY.
+ *
+ * Note - This loop is a little tricky. On iteration i we first set
+ * the offset for attribute i and figure out how much the offset
+ * should be incremented. Finally, we need to align the offset
+ * based on the size of attribute i+1 (for which the offset has
+ * been computed). -mer 12 Dec 1991
+ */
+
+ for (i = 0; i < attnum; i++)
+ {
+ if (!HeapTupleNoNulls(tup))
+ {
+ if (att_isnull(i, bp))
+ {
+ usecache = false;
+ continue;
+ }
+ }
+ switch (att[i]->attlen)
+ {
+ case -1:
+ off = (att[i]->attalign == 'd') ?
+ DOUBLEALIGN(off) : INTALIGN(off);
+ break;
+ case sizeof(char):
+ break;
+ case sizeof(short):
+ off = SHORTALIGN(off);
+ break;
+ case sizeof(int32):
+ off = INTALIGN(off);
+ break;
+ default:
+ if (att[i]->attlen < sizeof(int32))
+ elog(WARN,
+ "fastgetattr2: attribute %d has len %d",
+ i, att[i]->attlen);
+ if (att[i]->attalign == 'd')
+ off = DOUBLEALIGN(off);
+ else
+ off = LONGALIGN(off);
+ break;
+ }
+ if (usecache && att[i]->attcacheoff > 0)
+ {
+ off = att[i]->attcacheoff;
+ if (att[i]->attlen == -1)
+ {
+ usecache = false;
+ }
+ }
+ else
+ {
+ if (usecache)
+ att[i]->attcacheoff = off;
+ }
+
+ switch (att[i]->attlen)
+ {
+ case sizeof(char):
+ off++;
+ break;
+ case sizeof(int16):
+ off += sizeof(int16);
+ break;
+ case sizeof(int32):
+ off += sizeof(int32);
+ break;
+ case -1:
+ usecache = false;
+ off += VARSIZE(tp + off);
+ break;
+ default:
+ off += att[i]->attlen;
+ break;
+ }
+ }
+ switch (att[attnum]->attlen)
+ {
+ case -1:
+ off = (att[attnum]->attalign == 'd') ?
+ DOUBLEALIGN(off) : INTALIGN(off);
+ break;
+ case sizeof(char):
+ break;
+ case sizeof(short):
+ off = SHORTALIGN(off);
+ break;
+ case sizeof(int32):
+ off = INTALIGN(off);
+ break;
+ default:
+ if (att[attnum]->attlen < sizeof(int32))
+ elog(WARN, "fastgetattr3: attribute %d has len %d",
+ attnum, att[attnum]->attlen);
+ if (att[attnum]->attalign == 'd')
+ off = DOUBLEALIGN(off);
+ else
+ off = LONGALIGN(off);
+ break;
+ }
+ return ((char *) fetchatt(&(att[attnum]), tp + off));
}
- return((char *) fetchatt(&(att[attnum]), tp + off));
- }
}
/* ----------------
- * heap_copytuple
+ * heap_copytuple
*
- * returns a copy of an entire tuple
+ * returns a copy of an entire tuple
* ----------------
*/
HeapTuple
heap_copytuple(HeapTuple tuple)
{
- HeapTuple newTuple;
+ HeapTuple newTuple;
- if (! HeapTupleIsValid(tuple))
- return (NULL);
-
- /* XXX For now, just prevent an undetectable executor related error */
- if (tuple->t_len > MAXTUPLEN) {
- elog(WARN, "palloctup: cannot handle length %d tuples",
- tuple->t_len);
- }
-
- newTuple = (HeapTuple) palloc(tuple->t_len);
- memmove((char *) newTuple, (char *) tuple, (int) tuple->t_len);
- return(newTuple);
+ if (!HeapTupleIsValid(tuple))
+ return (NULL);
+
+ /* XXX For now, just prevent an undetectable executor related error */
+ if (tuple->t_len > MAXTUPLEN)
+ {
+ elog(WARN, "palloctup: cannot handle length %d tuples",
+ tuple->t_len);
+ }
+
+ newTuple = (HeapTuple) palloc(tuple->t_len);
+ memmove((char *) newTuple, (char *) tuple, (int) tuple->t_len);
+ return (newTuple);
}
#ifdef NOT_USED
/* ----------------
- * heap_deformtuple
+ * heap_deformtuple
*
- * the inverse of heap_formtuple (see below)
+ * the inverse of heap_formtuple (see below)
* ----------------
*/
void
heap_deformtuple(HeapTuple tuple,
- TupleDesc tdesc,
- Datum values[],
- char nulls[])
+ TupleDesc tdesc,
+ Datum values[],
+ char nulls[])
{
- int i;
- int natts;
-
- Assert(HeapTupleIsValid(tuple));
-
- natts = tuple->t_natts;
- for (i = 0; i<natts; i++) {
- bool isnull;
-
- values[i] = (Datum)heap_getattr(tuple,
- InvalidBuffer,
- i+1,
- tdesc,
- &isnull);
- if (isnull)
- nulls[i] = 'n';
- else
- nulls[i] = ' ';
- }
+ int i;
+ int natts;
+
+ Assert(HeapTupleIsValid(tuple));
+
+ natts = tuple->t_natts;
+ for (i = 0; i < natts; i++)
+ {
+ bool isnull;
+
+ values[i] = (Datum) heap_getattr(tuple,
+ InvalidBuffer,
+ i + 1,
+ tdesc,
+ &isnull);
+ if (isnull)
+ nulls[i] = 'n';
+ else
+ nulls[i] = ' ';
+ }
}
+
#endif
/* ----------------
- * heap_formtuple
+ * heap_formtuple
*
- * constructs a tuple from the given value[] and null[] arrays
+ * constructs a tuple from the given value[] and null[] arrays
*
* old comments
- * Handles alignment by aligning 2 byte attributes on short boundries
- * and 3 or 4 byte attributes on long word boundries on a vax; and
- * aligning non-byte attributes on short boundries on a sun. Does
- * not properly align fixed length arrays of 1 or 2 byte types (yet).
+ * Handles alignment by aligning 2 byte attributes on short boundries
+ * and 3 or 4 byte attributes on long word boundries on a vax; and
+ * aligning non-byte attributes on short boundries on a sun. Does
+ * not properly align fixed length arrays of 1 or 2 byte types (yet).
*
- * Null attributes are indicated by a 'n' in the appropriate byte
- * of the null[]. Non-null attributes are indicated by a ' ' (space).
+ * Null attributes are indicated by a 'n' in the appropriate byte
+ * of the null[]. Non-null attributes are indicated by a ' ' (space).
*
- * Fix me. (Figure that must keep context if debug--allow give oid.)
- * Assumes in order.
+ * Fix me. (Figure that must keep context if debug--allow give oid.)
+ * Assumes in order.
* ----------------
*/
HeapTuple
heap_formtuple(TupleDesc tupleDescriptor,
- Datum value[],
- char nulls[])
+ Datum value[],
+ char nulls[])
{
- char *tp; /* tuple pointer */
- HeapTuple tuple; /* return tuple */
- int bitmaplen;
- long len;
- int hoff;
- bool hasnull = false;
- int i;
- int numberOfAttributes = tupleDescriptor->natts;
-
- len = sizeof *tuple - sizeof tuple->t_bits;
-
- for (i = 0; i < numberOfAttributes && !hasnull; i++) {
- if (nulls[i] != ' ') hasnull = true;
- }
-
- if (numberOfAttributes > MaxHeapAttributeNumber)
- elog(WARN, "heap_formtuple: numberOfAttributes of %d > %d",
- numberOfAttributes, MaxHeapAttributeNumber);
-
- if (hasnull) {
- bitmaplen = BITMAPLEN(numberOfAttributes);
- len += bitmaplen;
- }
-
- hoff = len = DOUBLEALIGN(len); /* be conservative here */
-
- len += ComputeDataSize(tupleDescriptor, value, nulls);
-
- tp = (char *) palloc(len);
- tuple = (HeapTuple) tp;
-
- memset(tp, 0, (int)len);
-
- tuple->t_len = len;
- tuple->t_natts = numberOfAttributes;
- tuple->t_hoff = hoff;
- tuple->t_tmin = INVALID_ABSTIME;
- tuple->t_tmax = CURRENT_ABSTIME;
-
- DataFill((char *)tuple + tuple->t_hoff,
- tupleDescriptor,
- value,
- nulls,
- &tuple->t_infomask,
- (hasnull ? tuple->t_bits : NULL));
-
- return (tuple);
+ char *tp; /* tuple pointer */
+ HeapTuple tuple; /* return tuple */
+ int bitmaplen;
+ long len;
+ int hoff;
+ bool hasnull = false;
+ int i;
+ int numberOfAttributes = tupleDescriptor->natts;
+
+ len = sizeof *tuple - sizeof tuple->t_bits;
+
+ for (i = 0; i < numberOfAttributes && !hasnull; i++)
+ {
+ if (nulls[i] != ' ')
+ hasnull = true;
+ }
+
+ if (numberOfAttributes > MaxHeapAttributeNumber)
+ elog(WARN, "heap_formtuple: numberOfAttributes of %d > %d",
+ numberOfAttributes, MaxHeapAttributeNumber);
+
+ if (hasnull)
+ {
+ bitmaplen = BITMAPLEN(numberOfAttributes);
+ len += bitmaplen;
+ }
+
+ hoff = len = DOUBLEALIGN(len); /* be conservative here */
+
+ len += ComputeDataSize(tupleDescriptor, value, nulls);
+
+ tp = (char *) palloc(len);
+ tuple = (HeapTuple) tp;
+
+ memset(tp, 0, (int) len);
+
+ tuple->t_len = len;
+ tuple->t_natts = numberOfAttributes;
+ tuple->t_hoff = hoff;
+ tuple->t_tmin = INVALID_ABSTIME;
+ tuple->t_tmax = CURRENT_ABSTIME;
+
+ DataFill((char *) tuple + tuple->t_hoff,
+ tupleDescriptor,
+ value,
+ nulls,
+ &tuple->t_infomask,
+ (hasnull ? tuple->t_bits : NULL));
+
+ return (tuple);
}
/* ----------------
- * heap_modifytuple
+ * heap_modifytuple
*
- * forms a new tuple from an old tuple and a set of replacement values.
+ * forms a new tuple from an old tuple and a set of replacement values.
* ----------------
*/
HeapTuple
heap_modifytuple(HeapTuple tuple,
- Buffer buffer,
- Relation relation,
- Datum replValue[],
- char replNull[],
- char repl[])
+ Buffer buffer,
+ Relation relation,
+ Datum replValue[],
+ char replNull[],
+ char repl[])
{
- int attoff;
- int numberOfAttributes;
- Datum *value;
- char *nulls;
- bool isNull;
- HeapTuple newTuple;
- int madecopy;
- uint8 infomask;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(HeapTupleIsValid(tuple));
- Assert(BufferIsValid(buffer) || RelationIsValid(relation));
- Assert(HeapTupleIsValid(tuple));
- Assert(PointerIsValid(replValue));
- Assert(PointerIsValid(replNull));
- Assert(PointerIsValid(repl));
-
- /* ----------------
- * if we're pointing to a disk page, then first
- * make a copy of our tuple so that all the attributes
- * are available. XXX this is inefficient -cim
- * ----------------
- */
- madecopy = 0;
- if (BufferIsValid(buffer) == true) {
- relation = (Relation) BufferGetRelation(buffer);
- tuple = heap_copytuple(tuple);
- madecopy = 1;
- }
-
- numberOfAttributes = RelationGetRelationTupleForm(relation)->relnatts;
-
- /* ----------------
- * allocate and fill value[] and nulls[] arrays from either
- * the tuple or the repl information, as appropriate.
- * ----------------
- */
- value = (Datum *) palloc(numberOfAttributes * sizeof *value);
- nulls = (char *) palloc(numberOfAttributes * sizeof *nulls);
-
- for (attoff = 0;
- attoff < numberOfAttributes;
- attoff += 1) {
-
- if (repl[attoff] == ' ') {
- char *attr;
-
- attr =
- heap_getattr(tuple,
- InvalidBuffer,
- AttrOffsetGetAttrNumber(attoff),
- RelationGetTupleDescriptor(relation),
- &isNull) ;
- value[attoff] = PointerGetDatum(attr);
- nulls[attoff] = (isNull) ? 'n' : ' ';
-
- } else if (repl[attoff] != 'r') {
- elog(WARN, "heap_modifytuple: repl is \\%3d", repl[attoff]);
-
- } else { /* == 'r' */
- value[attoff] = replValue[attoff];
- nulls[attoff] = replNull[attoff];
+ int attoff;
+ int numberOfAttributes;
+ Datum *value;
+ char *nulls;
+ bool isNull;
+ HeapTuple newTuple;
+ int madecopy;
+ uint8 infomask;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(HeapTupleIsValid(tuple));
+ Assert(BufferIsValid(buffer) || RelationIsValid(relation));
+ Assert(HeapTupleIsValid(tuple));
+ Assert(PointerIsValid(replValue));
+ Assert(PointerIsValid(replNull));
+ Assert(PointerIsValid(repl));
+
+ /* ----------------
+ * if we're pointing to a disk page, then first
+ * make a copy of our tuple so that all the attributes
+ * are available. XXX this is inefficient -cim
+ * ----------------
+ */
+ madecopy = 0;
+ if (BufferIsValid(buffer) == true)
+ {
+ relation = (Relation) BufferGetRelation(buffer);
+ tuple = heap_copytuple(tuple);
+ madecopy = 1;
+ }
+
+ numberOfAttributes = RelationGetRelationTupleForm(relation)->relnatts;
+
+ /* ----------------
+ * allocate and fill value[] and nulls[] arrays from either
+ * the tuple or the repl information, as appropriate.
+ * ----------------
+ */
+ value = (Datum *) palloc(numberOfAttributes * sizeof *value);
+ nulls = (char *) palloc(numberOfAttributes * sizeof *nulls);
+
+ for (attoff = 0;
+ attoff < numberOfAttributes;
+ attoff += 1)
+ {
+
+ if (repl[attoff] == ' ')
+ {
+ char *attr;
+
+ attr =
+ heap_getattr(tuple,
+ InvalidBuffer,
+ AttrOffsetGetAttrNumber(attoff),
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+ value[attoff] = PointerGetDatum(attr);
+ nulls[attoff] = (isNull) ? 'n' : ' ';
+
+ }
+ else if (repl[attoff] != 'r')
+ {
+ elog(WARN, "heap_modifytuple: repl is \\%3d", repl[attoff]);
+
+ }
+ else
+ { /* == 'r' */
+ value[attoff] = replValue[attoff];
+ nulls[attoff] = replNull[attoff];
+ }
}
- }
-
- /* ----------------
- * create a new tuple from the values[] and nulls[] arrays
- * ----------------
- */
- newTuple = heap_formtuple(RelationGetTupleDescriptor(relation),
- value,
- nulls);
-
- /* ----------------
- * copy the header except for t_len, t_natts, t_hoff, t_bits, t_infomask
- * ----------------
- */
- infomask = newTuple->t_infomask;
- memmove((char *) &newTuple->t_ctid, /*XXX*/
- (char *) &tuple->t_ctid,
- ((char *) &tuple->t_hoff - (char *) &tuple->t_ctid)); /*XXX*/
- newTuple->t_infomask = infomask;
- newTuple->t_natts = numberOfAttributes; /* fix t_natts just in case */
-
- /* ----------------
- * if we made a copy of the tuple, then free it.
- * ----------------
- */
- if (madecopy)
- pfree(tuple);
-
- return
- newTuple;
+
+ /* ----------------
+ * create a new tuple from the values[] and nulls[] arrays
+ * ----------------
+ */
+ newTuple = heap_formtuple(RelationGetTupleDescriptor(relation),
+ value,
+ nulls);
+
+ /* ----------------
+ * copy the header except for t_len, t_natts, t_hoff, t_bits, t_infomask
+ * ----------------
+ */
+ infomask = newTuple->t_infomask;
+ memmove((char *) &newTuple->t_ctid, /* XXX */
+ (char *) &tuple->t_ctid,
+ ((char *) &tuple->t_hoff - (char *) &tuple->t_ctid)); /* XXX */
+ newTuple->t_infomask = infomask;
+ newTuple->t_natts = numberOfAttributes; /* fix t_natts just in
+ * case */
+
+ /* ----------------
+ * if we made a copy of the tuple, then free it.
+ * ----------------
+ */
+ if (madecopy)
+ pfree(tuple);
+
+ return
+ newTuple;
}
/* ----------------------------------------------------------------
- * other misc functions
+ * other misc functions
* ----------------------------------------------------------------
*/
HeapTuple
heap_addheader(uint32 natts, /* max domain index */
- int structlen, /* its length */
- char *structure) /* pointer to the struct */
+ int structlen, /* its length */
+ char *structure) /* pointer to the struct */
{
- register char *tp; /* tuple data pointer */
- HeapTuple tup;
- long len;
- int hoff;
-
- AssertArg(natts > 0);
-
- len = sizeof (HeapTupleData) - sizeof (tup->t_bits);
-
- hoff = len = DOUBLEALIGN(len); /* be conservative */
- len += structlen;
- tp = (char *) palloc(len);
- tup = (HeapTuple) tp;
- memset((char*)tup, 0, len);
-
- tup->t_len = (short) len; /* XXX */
- tp += tup->t_hoff = hoff;
- tup->t_natts = natts;
- tup->t_infomask = 0;
-
- memmove(tp, structure, structlen);
-
- return (tup);
+ register char *tp; /* tuple data pointer */
+ HeapTuple tup;
+ long len;
+ int hoff;
+
+ AssertArg(natts > 0);
+
+ len = sizeof(HeapTupleData) - sizeof(tup->t_bits);
+
+ hoff = len = DOUBLEALIGN(len); /* be conservative */
+ len += structlen;
+ tp = (char *) palloc(len);
+ tup = (HeapTuple) tp;
+ memset((char *) tup, 0, len);
+
+ tup->t_len = (short) len; /* XXX */
+ tp += tup->t_hoff = hoff;
+ tup->t_natts = natts;
+ tup->t_infomask = 0;
+
+ memmove(tp, structure, structlen);
+
+ return (tup);
}
diff --git a/src/backend/access/common/heapvalid.c b/src/backend/access/common/heapvalid.c
index 186ee654b32..0caeb54e17c 100644
--- a/src/backend/access/common/heapvalid.c
+++ b/src/backend/access/common/heapvalid.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* heapvalid.c--
- * heap tuple qualification validity checking code
+ * heap tuple qualification validity checking code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/Attic/heapvalid.c,v 1.16 1997/08/29 09:12:20 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/Attic/heapvalid.c,v 1.17 1997/09/07 04:37:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,128 +25,138 @@
#include <utils/builtins.h>
/* ----------------
- * heap_keytest
+ * heap_keytest
*
- * Test a heap tuple with respect to a scan key.
+ * Test a heap tuple with respect to a scan key.
* ----------------
*/
bool
heap_keytest(HeapTuple t,
- TupleDesc tupdesc,
- int nkeys,
- ScanKey keys)
+ TupleDesc tupdesc,
+ int nkeys,
+ ScanKey keys)
{
- bool isnull;
- Datum atp;
- int test;
-
- for (; nkeys--; keys++) {
- atp = (Datum)heap_getattr(t, InvalidBuffer,
- keys->sk_attno,
- tupdesc,
- &isnull);
-
- if (isnull)
- /* XXX eventually should check if SK_ISNULL */
- return false;
-
- if (keys->sk_flags & SK_ISNULL) {
- return (false);
+ bool isnull;
+ Datum atp;
+ int test;
+
+ for (; nkeys--; keys++)
+ {
+ atp = (Datum) heap_getattr(t, InvalidBuffer,
+ keys->sk_attno,
+ tupdesc,
+ &isnull);
+
+ if (isnull)
+ /* XXX eventually should check if SK_ISNULL */
+ return false;
+
+ if (keys->sk_flags & SK_ISNULL)
+ {
+ return (false);
+ }
+
+ if (keys->sk_func == (func_ptr) oideq) /* optimization */
+ test = (keys->sk_argument == atp);
+ else if (keys->sk_flags & SK_COMMUTE)
+ test = (long) FMGR_PTR2(keys->sk_func, keys->sk_procedure,
+ keys->sk_argument, atp);
+ else
+ test = (long) FMGR_PTR2(keys->sk_func, keys->sk_procedure,
+ atp, keys->sk_argument);
+
+ if (!test == !(keys->sk_flags & SK_NEGATE))
+ return false;
}
- if (keys->sk_func == (func_ptr)oideq) /* optimization */
- test = (keys->sk_argument == atp);
- else if (keys->sk_flags & SK_COMMUTE)
- test = (long) FMGR_PTR2(keys->sk_func, keys->sk_procedure,
- keys->sk_argument, atp);
- else
- test = (long) FMGR_PTR2(keys->sk_func, keys->sk_procedure,
- atp, keys->sk_argument);
-
- if (!test == !(keys->sk_flags & SK_NEGATE))
- return false;
- }
-
- return true;
+ return true;
}
/* ----------------
- * heap_tuple_satisfies
+ * heap_tuple_satisfies
*
- * Returns a valid HeapTuple if it satisfies the timequal and keytest.
- * Returns NULL otherwise. Used to be heap_satisifies (sic) which
- * returned a boolean. It now returns a tuple so that we can avoid doing two
- * PageGetItem's per tuple.
+ * Returns a valid HeapTuple if it satisfies the timequal and keytest.
+ * Returns NULL otherwise. Used to be heap_satisifies (sic) which
+ * returned a boolean. It now returns a tuple so that we can avoid doing two
+ * PageGetItem's per tuple.
*
- * Complete check of validity including LP_CTUP and keytest.
- * This should perhaps be combined with valid somehow in the
- * future. (Also, additional rule tests/time range tests.)
+ * Complete check of validity including LP_CTUP and keytest.
+ * This should perhaps be combined with valid somehow in the
+ * future. (Also, additional rule tests/time range tests.)
*
- * on 8/21/92 mao says: i rearranged the tests here to do keytest before
- * SatisfiesTimeQual. profiling indicated that even for vacuumed relations,
- * time qual checking was more expensive than key testing. time qual is
- * least likely to fail, too. we should really add the time qual test to
- * the restriction and optimize it in the normal way. this has interactions
- * with joey's expensive function work.
+ * on 8/21/92 mao says: i rearranged the tests here to do keytest before
+ * SatisfiesTimeQual. profiling indicated that even for vacuumed relations,
+ * time qual checking was more expensive than key testing. time qual is
+ * least likely to fail, too. we should really add the time qual test to
+ * the restriction and optimize it in the normal way. this has interactions
+ * with joey's expensive function work.
* ----------------
*/
HeapTuple
heap_tuple_satisfies(ItemId itemId,
- Relation relation,
- Buffer buffer,
- PageHeader disk_page,
- TimeQual qual,
- int nKeys,
- ScanKey key)
+ Relation relation,
+ Buffer buffer,
+ PageHeader disk_page,
+ TimeQual qual,
+ int nKeys,
+ ScanKey key)
{
- HeapTuple tuple, result;
- bool res;
- TransactionId old_tmin, old_tmax;
-
- if (! ItemIdIsUsed(itemId))
- return NULL;
-
- tuple = (HeapTuple) PageGetItem((Page) disk_page, itemId);
-
- if (key != NULL)
- res = heap_keytest(tuple, RelationGetTupleDescriptor(relation),
- nKeys, key);
- else
- res = TRUE;
-
- result = (HeapTuple)NULL;
- if (res) {
- if(relation->rd_rel->relkind == RELKIND_UNCATALOGED) {
- result = tuple;
- } else {
- old_tmin = tuple->t_tmin;
- old_tmax = tuple->t_tmax;
- res = HeapTupleSatisfiesTimeQual(tuple,qual);
- if(tuple->t_tmin != old_tmin ||
- tuple->t_tmax != old_tmax) {
- SetBufferCommitInfoNeedsSave(buffer);
- }
- if(res) {
- result = tuple;
- }
+ HeapTuple tuple,
+ result;
+ bool res;
+ TransactionId old_tmin,
+ old_tmax;
+
+ if (!ItemIdIsUsed(itemId))
+ return NULL;
+
+ tuple = (HeapTuple) PageGetItem((Page) disk_page, itemId);
+
+ if (key != NULL)
+ res = heap_keytest(tuple, RelationGetTupleDescriptor(relation),
+ nKeys, key);
+ else
+ res = TRUE;
+
+ result = (HeapTuple) NULL;
+ if (res)
+ {
+ if (relation->rd_rel->relkind == RELKIND_UNCATALOGED)
+ {
+ result = tuple;
+ }
+ else
+ {
+ old_tmin = tuple->t_tmin;
+ old_tmax = tuple->t_tmax;
+ res = HeapTupleSatisfiesTimeQual(tuple, qual);
+ if (tuple->t_tmin != old_tmin ||
+ tuple->t_tmax != old_tmax)
+ {
+ SetBufferCommitInfoNeedsSave(buffer);
+ }
+ if (res)
+ {
+ result = tuple;
+ }
+ }
}
- }
- return result;
+ return result;
}
/*
- * TupleUpdatedByCurXactAndCmd() -- Returns true if this tuple has
- * already been updated once by the current transaction/command
- * pair.
+ * TupleUpdatedByCurXactAndCmd() -- Returns true if this tuple has
+ * already been updated once by the current transaction/command
+ * pair.
*/
bool
TupleUpdatedByCurXactAndCmd(HeapTuple t)
{
- if (TransactionIdEquals(t->t_xmax,
- GetCurrentTransactionId()) &&
- CommandIdGEScanCommandId (t->t_cmax))
- return true;
-
- return false;
+ if (TransactionIdEquals(t->t_xmax,
+ GetCurrentTransactionId()) &&
+ CommandIdGEScanCommandId(t->t_cmax))
+ return true;
+
+ return false;
}
diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c
index a71fc46dc98..c133693801b 100644
--- a/src/backend/access/common/indextuple.c
+++ b/src/backend/access/common/indextuple.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* indextuple.c--
- * This file contains index tuple accessor and mutator routines,
- * as well as a few various tuple utilities.
+ * This file contains index tuple accessor and mutator routines,
+ * as well as a few various tuple utilities.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.15 1997/08/19 21:28:50 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.16 1997/09/07 04:37:37 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,402 +21,438 @@
#include <access/tupmacs.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static Size IndexInfoFindDataOffset(unsigned short t_info);
-static char *fastgetiattr(IndexTuple tup, int attnum,
- TupleDesc att, bool *isnull);
+static Size IndexInfoFindDataOffset(unsigned short t_info);
+static char *
+fastgetiattr(IndexTuple tup, int attnum,
+ TupleDesc att, bool * isnull);
/* ----------------------------------------------------------------
- * index_ tuple interface routines
+ * index_ tuple interface routines
* ----------------------------------------------------------------
*/
/* ----------------
- * index_formtuple
+ * index_formtuple
* ----------------
*/
IndexTuple
index_formtuple(TupleDesc tupleDescriptor,
- Datum value[],
- char null[])
+ Datum value[],
+ char null[])
{
- register char *tp; /* tuple pointer */
- IndexTuple tuple; /* return tuple */
- Size size, hoff;
- int i;
- unsigned short infomask = 0;
- bool hasnull = false;
- char tupmask = 0;
- int numberOfAttributes = tupleDescriptor->natts;
-
- if (numberOfAttributes > MaxIndexAttributeNumber)
- elog(WARN, "index_formtuple: numberOfAttributes of %d > %d",
- numberOfAttributes, MaxIndexAttributeNumber);
-
-
- for (i = 0; i < numberOfAttributes && !hasnull; i++) {
- if (null[i] != ' ') hasnull = true;
- }
-
- if (hasnull) infomask |= INDEX_NULL_MASK;
-
- hoff = IndexInfoFindDataOffset(infomask);
- size = hoff
- + ComputeDataSize(tupleDescriptor,
- value, null);
- size = DOUBLEALIGN(size); /* be conservative */
-
- tp = (char *) palloc(size);
- tuple = (IndexTuple) tp;
- memset(tp,0,(int)size);
-
- DataFill((char *)tp + hoff,
- tupleDescriptor,
- value,
- null,
- &tupmask,
- (hasnull ? (bits8*)tp + sizeof(*tuple) : NULL));
-
- /*
- * We do this because DataFill wants to initialize a "tupmask" which
- * is used for HeapTuples, but we want an indextuple infomask. The only
- * "relevent" info is the "has variable attributes" field, which is in
- * mask position 0x02. We have already set the null mask above.
- */
-
- if (tupmask & 0x02) infomask |= INDEX_VAR_MASK;
-
- /*
- * Here we make sure that we can actually hold the size. We also want
- * to make sure that size is not aligned oddly. This actually is a
- * rather odd way to make sure the size is not too large overall.
- */
-
- if (size & 0xE000)
- elog(WARN, "index_formtuple: data takes %d bytes: too big", size);
-
-
- infomask |= size;
-
- /* ----------------
- * initialize metadata
- * ----------------
- */
- tuple->t_info = infomask;
- return (tuple);
+ register char *tp; /* tuple pointer */
+ IndexTuple tuple; /* return tuple */
+ Size size,
+ hoff;
+ int i;
+ unsigned short infomask = 0;
+ bool hasnull = false;
+ char tupmask = 0;
+ int numberOfAttributes = tupleDescriptor->natts;
+
+ if (numberOfAttributes > MaxIndexAttributeNumber)
+ elog(WARN, "index_formtuple: numberOfAttributes of %d > %d",
+ numberOfAttributes, MaxIndexAttributeNumber);
+
+
+ for (i = 0; i < numberOfAttributes && !hasnull; i++)
+ {
+ if (null[i] != ' ')
+ hasnull = true;
+ }
+
+ if (hasnull)
+ infomask |= INDEX_NULL_MASK;
+
+ hoff = IndexInfoFindDataOffset(infomask);
+ size = hoff
+ + ComputeDataSize(tupleDescriptor,
+ value, null);
+ size = DOUBLEALIGN(size); /* be conservative */
+
+ tp = (char *) palloc(size);
+ tuple = (IndexTuple) tp;
+ memset(tp, 0, (int) size);
+
+ DataFill((char *) tp + hoff,
+ tupleDescriptor,
+ value,
+ null,
+ &tupmask,
+ (hasnull ? (bits8 *) tp + sizeof(*tuple) : NULL));
+
+ /*
+ * We do this because DataFill wants to initialize a "tupmask" which
+ * is used for HeapTuples, but we want an indextuple infomask. The
+ * only "relevent" info is the "has variable attributes" field, which
+ * is in mask position 0x02. We have already set the null mask above.
+ */
+
+ if (tupmask & 0x02)
+ infomask |= INDEX_VAR_MASK;
+
+ /*
+ * Here we make sure that we can actually hold the size. We also want
+ * to make sure that size is not aligned oddly. This actually is a
+ * rather odd way to make sure the size is not too large overall.
+ */
+
+ if (size & 0xE000)
+ elog(WARN, "index_formtuple: data takes %d bytes: too big", size);
+
+
+ infomask |= size;
+
+ /* ----------------
+ * initialize metadata
+ * ----------------
+ */
+ tuple->t_info = infomask;
+ return (tuple);
}
/* ----------------
- * fastgetiattr
+ * fastgetiattr
*
- * This is a newer version of fastgetiattr which attempts to be
- * faster by caching attribute offsets in the attribute descriptor.
+ * This is a newer version of fastgetiattr which attempts to be
+ * faster by caching attribute offsets in the attribute descriptor.
*
- * an alternate way to speed things up would be to cache offsets
- * with the tuple, but that seems more difficult unless you take
- * the storage hit of actually putting those offsets into the
- * tuple you send to disk. Yuck.
+ * an alternate way to speed things up would be to cache offsets
+ * with the tuple, but that seems more difficult unless you take
+ * the storage hit of actually putting those offsets into the
+ * tuple you send to disk. Yuck.
*
- * This scheme will be slightly slower than that, but should
- * preform well for queries which hit large #'s of tuples. After
- * you cache the offsets once, examining all the other tuples using
- * the same attribute descriptor will go much quicker. -cim 5/4/91
+ * This scheme will be slightly slower than that, but should
+ * preform well for queries which hit large #'s of tuples. After
+ * you cache the offsets once, examining all the other tuples using
+ * the same attribute descriptor will go much quicker. -cim 5/4/91
* ----------------
*/
-static char *
+static char *
fastgetiattr(IndexTuple tup,
- int attnum,
- TupleDesc tupleDesc,
- bool *isnull)
+ int attnum,
+ TupleDesc tupleDesc,
+ bool * isnull)
{
- register char *tp; /* ptr to att in tuple */
- register char *bp = NULL; /* ptr to att in tuple */
- int slow; /* do we have to walk nulls? */
- register int data_off; /* tuple data offset */
- AttributeTupleForm *att = tupleDesc->attrs;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
-
- Assert(PointerIsValid(isnull));
- Assert(attnum > 0);
-
- /* ----------------
- * Three cases:
- *
- * 1: No nulls and no variable length attributes.
- * 2: Has a null or a varlena AFTER att.
- * 3: Has nulls or varlenas BEFORE att.
- * ----------------
- */
-
- *isnull = false;
- data_off = IndexTupleHasMinHeader(tup) ? sizeof *tup :
- IndexInfoFindDataOffset(tup->t_info);
-
- if (IndexTupleNoNulls(tup)) {
-
- /* first attribute is always at position zero */
-
- if (attnum == 1) {
- return(fetchatt(&(att[0]), (char *) tup + data_off));
- }
- attnum--;
-
- if (att[attnum]->attcacheoff > 0) {
- return(fetchatt(&(att[attnum]),
- (char *) tup + data_off +
- att[attnum]->attcacheoff));
- }
-
- tp = (char *) tup + data_off;
-
- slow = 0;
- }else { /* there's a null somewhere in the tuple */
-
- bp = (char *) tup + sizeof(*tup); /* "knows" t_bits are here! */
- slow = 0;
+ register char *tp; /* ptr to att in tuple */
+ register char *bp = NULL; /* ptr to att in tuple */
+ int slow; /* do we have to walk nulls? */
+ register int data_off; /* tuple data offset */
+ AttributeTupleForm *att = tupleDesc->attrs;
+
/* ----------------
- * check to see if desired att is null
+ * sanity checks
* ----------------
*/
-
- attnum--;
- {
- if (att_isnull(attnum, bp)) {
- *isnull = true;
- return NULL;
- }
- }
+
+ Assert(PointerIsValid(isnull));
+ Assert(attnum > 0);
+
/* ----------------
- * Now check to see if any preceeding bits are null...
+ * Three cases:
+ *
+ * 1: No nulls and no variable length attributes.
+ * 2: Has a null or a varlena AFTER att.
+ * 3: Has nulls or varlenas BEFORE att.
* ----------------
*/
+
+ *isnull = false;
+ data_off = IndexTupleHasMinHeader(tup) ? sizeof *tup :
+ IndexInfoFindDataOffset(tup->t_info);
+
+ if (IndexTupleNoNulls(tup))
{
- register int i = 0; /* current offset in bp */
- register int mask; /* bit in byte we're looking at */
- register char n; /* current byte in bp */
- register int byte, finalbit;
-
- byte = attnum >> 3;
- finalbit = attnum & 0x07;
-
- for (; i <= byte; i++) {
- n = bp[i];
- if (i < byte) {
- /* check for nulls in any "earlier" bytes */
- if ((~n) != 0) {
- slow++;
- break;
- }
- } else {
- /* check for nulls "before" final bit of last byte*/
- mask = (finalbit << 1) - 1;
- if ((~n) & mask)
- slow++;
+
+ /* first attribute is always at position zero */
+
+ if (attnum == 1)
+ {
+ return (fetchatt(&(att[0]), (char *) tup + data_off));
+ }
+ attnum--;
+
+ if (att[attnum]->attcacheoff > 0)
+ {
+ return (fetchatt(&(att[attnum]),
+ (char *) tup + data_off +
+ att[attnum]->attcacheoff));
}
- }
+
+ tp = (char *) tup + data_off;
+
+ slow = 0;
}
- tp = (char *) tup + data_off;
- }
-
- /* now check for any non-fixed length attrs before our attribute */
-
- if (!slow) {
- if (att[attnum]->attcacheoff > 0) {
- return(fetchatt(&(att[attnum]),
- tp + att[attnum]->attcacheoff));
- }else if (!IndexTupleAllFixed(tup)) {
- register int j = 0;
-
- for (j = 0; j < attnum && !slow; j++)
- if (att[j]->attlen < 1) slow = 1;
+ else
+ { /* there's a null somewhere in the tuple */
+
+ bp = (char *) tup + sizeof(*tup); /* "knows" t_bits are
+ * here! */
+ slow = 0;
+ /* ----------------
+ * check to see if desired att is null
+ * ----------------
+ */
+
+ attnum--;
+ {
+ if (att_isnull(attnum, bp))
+ {
+ *isnull = true;
+ return NULL;
+ }
+ }
+ /* ----------------
+ * Now check to see if any preceeding bits are null...
+ * ----------------
+ */
+ {
+ register int i = 0; /* current offset in bp */
+ register int mask; /* bit in byte we're looking at */
+ register char n; /* current byte in bp */
+ register int byte,
+ finalbit;
+
+ byte = attnum >> 3;
+ finalbit = attnum & 0x07;
+
+ for (; i <= byte; i++)
+ {
+ n = bp[i];
+ if (i < byte)
+ {
+ /* check for nulls in any "earlier" bytes */
+ if ((~n) != 0)
+ {
+ slow++;
+ break;
+ }
+ }
+ else
+ {
+ /* check for nulls "before" final bit of last byte */
+ mask = (finalbit << 1) - 1;
+ if ((~n) & mask)
+ slow++;
+ }
+ }
+ }
+ tp = (char *) tup + data_off;
}
- }
-
- /*
- * if slow is zero, and we got here, we know that we have a tuple with
- * no nulls. We also know that we have to initialize the remainder of
- * the attribute cached offset values.
- */
-
- if (!slow) {
- register int j = 1;
- register long off;
-
- /*
- * need to set cache for some atts
- */
-
- att[0]->attcacheoff = 0;
-
- while (att[j]->attcacheoff > 0) j++;
-
- off = att[j-1]->attcacheoff +
- att[j-1]->attlen;
-
- for (; j < attnum + 1; j++) {
- /*
- * Fix me when going to a machine with more than a four-byte
- * word!
- */
-
- switch(att[j]->attlen)
+
+ /* now check for any non-fixed length attrs before our attribute */
+
+ if (!slow)
+ {
+ if (att[attnum]->attcacheoff > 0)
{
- case -1:
- off = (att[j]->attalign=='d')?
- DOUBLEALIGN(off):INTALIGN(off);
- break;
- case sizeof(char):
- break;
- case sizeof(short):
- off = SHORTALIGN(off);
- break;
- case sizeof(int32):
- off = INTALIGN(off);
- break;
- default:
- if (att[j]->attlen > sizeof(int32))
- off = (att[j]->attalign=='d')?
- DOUBLEALIGN(off) : LONGALIGN(off);
- else
- elog(WARN, "fastgetiattr: attribute %d has len %d",
- j, att[j]->attlen);
- break;
-
+ return (fetchatt(&(att[attnum]),
+ tp + att[attnum]->attcacheoff));
+ }
+ else if (!IndexTupleAllFixed(tup))
+ {
+ register int j = 0;
+
+ for (j = 0; j < attnum && !slow; j++)
+ if (att[j]->attlen < 1)
+ slow = 1;
}
-
- att[j]->attcacheoff = off;
- off += att[j]->attlen;
}
-
- return(fetchatt( &(att[attnum]),
- tp + att[attnum]->attcacheoff));
- }else {
- register bool usecache = true;
- register int off = 0;
- register int i;
-
+
/*
- * Now we know that we have to walk the tuple CAREFULLY.
+ * if slow is zero, and we got here, we know that we have a tuple with
+ * no nulls. We also know that we have to initialize the remainder of
+ * the attribute cached offset values.
*/
-
- for (i = 0; i < attnum; i++) {
- if (!IndexTupleNoNulls(tup)) {
- if (att_isnull(i, bp)) {
- usecache = false;
- continue;
+
+ if (!slow)
+ {
+ register int j = 1;
+ register long off;
+
+ /*
+ * need to set cache for some atts
+ */
+
+ att[0]->attcacheoff = 0;
+
+ while (att[j]->attcacheoff > 0)
+ j++;
+
+ off = att[j - 1]->attcacheoff +
+ att[j - 1]->attlen;
+
+ for (; j < attnum + 1; j++)
+ {
+
+ /*
+ * Fix me when going to a machine with more than a four-byte
+ * word!
+ */
+
+ switch (att[j]->attlen)
+ {
+ case -1:
+ off = (att[j]->attalign == 'd') ?
+ DOUBLEALIGN(off) : INTALIGN(off);
+ break;
+ case sizeof(char):
+ break;
+ case sizeof(short):
+ off = SHORTALIGN(off);
+ break;
+ case sizeof(int32):
+ off = INTALIGN(off);
+ break;
+ default:
+ if (att[j]->attlen > sizeof(int32))
+ off = (att[j]->attalign == 'd') ?
+ DOUBLEALIGN(off) : LONGALIGN(off);
+ else
+ elog(WARN, "fastgetiattr: attribute %d has len %d",
+ j, att[j]->attlen);
+ break;
+
+ }
+
+ att[j]->attcacheoff = off;
+ off += att[j]->attlen;
}
- }
-
- if (usecache && att[i]->attcacheoff > 0) {
- off = att[i]->attcacheoff;
- if (att[i]->attlen == -1)
- usecache = false;
- else
- continue;
- }
-
- if (usecache) att[i]->attcacheoff = off;
- switch(att[i]->attlen)
+
+ return (fetchatt(&(att[attnum]),
+ tp + att[attnum]->attcacheoff));
+ }
+ else
+ {
+ register bool usecache = true;
+ register int off = 0;
+ register int i;
+
+ /*
+ * Now we know that we have to walk the tuple CAREFULLY.
+ */
+
+ for (i = 0; i < attnum; i++)
{
+ if (!IndexTupleNoNulls(tup))
+ {
+ if (att_isnull(i, bp))
+ {
+ usecache = false;
+ continue;
+ }
+ }
+
+ if (usecache && att[i]->attcacheoff > 0)
+ {
+ off = att[i]->attcacheoff;
+ if (att[i]->attlen == -1)
+ usecache = false;
+ else
+ continue;
+ }
+
+ if (usecache)
+ att[i]->attcacheoff = off;
+ switch (att[i]->attlen)
+ {
+ case sizeof(char):
+ off++;
+ break;
+ case sizeof(short):
+ off = SHORTALIGN(off) +sizeof(short);
+ break;
+ case sizeof(int32):
+ off = INTALIGN(off) + sizeof(int32);
+ break;
+ case -1:
+ usecache = false;
+ off = (att[i]->attalign == 'd') ?
+ DOUBLEALIGN(off) : INTALIGN(off);
+ off += VARSIZE(tp + off);
+ break;
+ default:
+ if (att[i]->attlen > sizeof(int32))
+ off = (att[i]->attalign == 'd') ?
+ DOUBLEALIGN(off) + att[i]->attlen :
+ LONGALIGN(off) + att[i]->attlen;
+ else
+ elog(WARN, "fastgetiattr2: attribute %d has len %d",
+ i, att[i]->attlen);
+
+ break;
+ }
+ }
+
+ /*
+ * I don't know why this code was missed here! I've got it from
+ * heaptuple.c:fastgetattr(). - vadim 06/12/97
+ */
+ switch (att[attnum]->attlen)
+ {
+ case -1:
+ off = (att[attnum]->attalign == 'd') ?
+ DOUBLEALIGN(off) : INTALIGN(off);
+ break;
case sizeof(char):
- off++;
- break;
+ break;
case sizeof(short):
- off = SHORTALIGN(off) + sizeof(short);
- break;
+ off = SHORTALIGN(off);
+ break;
case sizeof(int32):
- off = INTALIGN(off) + sizeof(int32);
- break;
- case -1:
- usecache = false;
- off = (att[i]->attalign=='d')?
- DOUBLEALIGN(off):INTALIGN(off);
- off += VARSIZE(tp + off);
- break;
+ off = INTALIGN(off);
+ break;
default:
- if (att[i]->attlen > sizeof(int32))
- off = (att[i]->attalign=='d') ?
- DOUBLEALIGN(off) + att[i]->attlen :
- LONGALIGN(off) + att[i]->attlen;
- else
- elog(WARN, "fastgetiattr2: attribute %d has len %d",
- i, att[i]->attlen);
-
- break;
+ if (att[attnum]->attlen < sizeof(int32))
+ elog(WARN, "fastgetattr3: attribute %d has len %d",
+ attnum, att[attnum]->attlen);
+ if (att[attnum]->attalign == 'd')
+ off = DOUBLEALIGN(off);
+ else
+ off = LONGALIGN(off);
+ break;
}
+
+ return (fetchatt(&att[attnum], tp + off));
}
- /*
- * I don't know why this code was missed here!
- * I've got it from heaptuple.c:fastgetattr().
- * - vadim 06/12/97
- */
- switch (att[attnum]->attlen) {
- case -1:
- off = (att[attnum]->attalign=='d')?
- DOUBLEALIGN(off) : INTALIGN(off);
- break;
- case sizeof(char):
- break;
- case sizeof(short):
- off = SHORTALIGN(off);
- break;
- case sizeof(int32):
- off = INTALIGN(off);
- break;
- default:
- if (att[attnum]->attlen < sizeof(int32))
- elog(WARN, "fastgetattr3: attribute %d has len %d",
- attnum, att[attnum]->attlen);
- if (att[attnum]->attalign == 'd')
- off = DOUBLEALIGN(off);
- else
- off = LONGALIGN(off);
- break;
- }
-
- return(fetchatt(&att[attnum], tp + off));
- }
}
/* ----------------
- * index_getattr
+ * index_getattr
* ----------------
*/
Datum
index_getattr(IndexTuple tuple,
- AttrNumber attNum,
- TupleDesc tupDesc,
- bool *isNullOutP)
+ AttrNumber attNum,
+ TupleDesc tupDesc,
+ bool * isNullOutP)
{
- Assert (attNum > 0);
+ Assert(attNum > 0);
- return (Datum)
- fastgetiattr(tuple, attNum, tupDesc, isNullOutP);
+ return (Datum)
+ fastgetiattr(tuple, attNum, tupDesc, isNullOutP);
}
RetrieveIndexResult
FormRetrieveIndexResult(ItemPointer indexItemPointer,
- ItemPointer heapItemPointer)
+ ItemPointer heapItemPointer)
{
- RetrieveIndexResult result;
-
- Assert(ItemPointerIsValid(indexItemPointer));
- Assert(ItemPointerIsValid(heapItemPointer));
-
- result = (RetrieveIndexResult) palloc(sizeof *result);
-
- result->index_iptr = *indexItemPointer;
- result->heap_iptr = *heapItemPointer;
-
- return (result);
+ RetrieveIndexResult result;
+
+ Assert(ItemPointerIsValid(indexItemPointer));
+ Assert(ItemPointerIsValid(heapItemPointer));
+
+ result = (RetrieveIndexResult) palloc(sizeof *result);
+
+ result->index_iptr = *indexItemPointer;
+ result->heap_iptr = *heapItemPointer;
+
+ return (result);
}
/*
@@ -425,19 +461,21 @@ FormRetrieveIndexResult(ItemPointer indexItemPointer,
*
* Change me if adding an attribute to IndexTuples!!!!!!!!!!!
*/
-static Size
+static Size
IndexInfoFindDataOffset(unsigned short t_info)
{
- if (!(t_info & INDEX_NULL_MASK))
- return((Size) sizeof(IndexTupleData));
- else {
- Size size = sizeof(IndexTupleData);
-
- if (t_info & INDEX_NULL_MASK) {
- size += sizeof(IndexAttributeBitMapData);
+ if (!(t_info & INDEX_NULL_MASK))
+ return ((Size) sizeof(IndexTupleData));
+ else
+ {
+ Size size = sizeof(IndexTupleData);
+
+ if (t_info & INDEX_NULL_MASK)
+ {
+ size += sizeof(IndexAttributeBitMapData);
+ }
+ return DOUBLEALIGN(size); /* be conservative */
}
- return DOUBLEALIGN(size); /* be conservative */
- }
}
/*
@@ -445,17 +483,17 @@ IndexInfoFindDataOffset(unsigned short t_info)
* we assume we have space that is already palloc'ed.
*/
void
-CopyIndexTuple(IndexTuple source, IndexTuple *target)
+CopyIndexTuple(IndexTuple source, IndexTuple * target)
{
- Size size;
- IndexTuple ret;
-
- size = IndexTupleSize(source);
- if (*target == NULL) {
- *target = (IndexTuple) palloc(size);
- }
-
- ret = *target;
- memmove((char*)ret, (char*)source, size);
-}
+ Size size;
+ IndexTuple ret;
+
+ size = IndexTupleSize(source);
+ if (*target == NULL)
+ {
+ *target = (IndexTuple) palloc(size);
+ }
+ ret = *target;
+ memmove((char *) ret, (char *) source, size);
+}
diff --git a/src/backend/access/common/indexvalid.c b/src/backend/access/common/indexvalid.c
index aff9af42f8d..9f8501beb2e 100644
--- a/src/backend/access/common/indexvalid.c
+++ b/src/backend/access/common/indexvalid.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* indexvalid.c--
- * index tuple qualification validity checking code
+ * index tuple qualification validity checking code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.14 1997/03/18 18:38:19 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.15 1997/09/07 04:37:38 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,64 +21,70 @@
#include <executor/execdebug.h>
/* ----------------------------------------------------------------
- * index scan key qualification code
+ * index scan key qualification code
* ----------------------------------------------------------------
*/
-int NIndexTupleProcessed;
+int NIndexTupleProcessed;
/* ----------------
- * index_keytest
+ * index_keytest
*
* old comments
- * May eventually combine with other tests (like timeranges)?
- * Should have Buffer buffer; as an argument and pass it to amgetattr.
+ * May eventually combine with other tests (like timeranges)?
+ * Should have Buffer buffer; as an argument and pass it to amgetattr.
* ----------------
*/
bool
index_keytest(IndexTuple tuple,
- TupleDesc tupdesc,
- int scanKeySize,
- ScanKey key)
+ TupleDesc tupdesc,
+ int scanKeySize,
+ ScanKey key)
{
- bool isNull;
- Datum datum;
- int test;
-
- IncrIndexProcessed();
-
- while (scanKeySize > 0) {
- datum = index_getattr(tuple,
- key[0].sk_attno,
- tupdesc,
- &isNull);
-
- if (isNull) {
- /* XXX eventually should check if SK_ISNULL */
- return (false);
- }
-
- if (key[0].sk_flags & SK_ISNULL) {
- return (false);
- }
+ bool isNull;
+ Datum datum;
+ int test;
- if (key[0].sk_flags & SK_COMMUTE) {
- test = (*(key[0].sk_func))
- (DatumGetPointer(key[0].sk_argument),
- datum) ? 1 : 0;
- } else {
- test = (*(key[0].sk_func))
- (datum,
- DatumGetPointer(key[0].sk_argument)) ? 1 : 0;
- }
-
- if (!test == !(key[0].sk_flags & SK_NEGATE)) {
- return (false);
+ IncrIndexProcessed();
+
+ while (scanKeySize > 0)
+ {
+ datum = index_getattr(tuple,
+ key[0].sk_attno,
+ tupdesc,
+ &isNull);
+
+ if (isNull)
+ {
+ /* XXX eventually should check if SK_ISNULL */
+ return (false);
+ }
+
+ if (key[0].sk_flags & SK_ISNULL)
+ {
+ return (false);
+ }
+
+ if (key[0].sk_flags & SK_COMMUTE)
+ {
+ test = (*(key[0].sk_func))
+ (DatumGetPointer(key[0].sk_argument),
+ datum) ? 1 : 0;
+ }
+ else
+ {
+ test = (*(key[0].sk_func))
+ (datum,
+ DatumGetPointer(key[0].sk_argument)) ? 1 : 0;
+ }
+
+ if (!test == !(key[0].sk_flags & SK_NEGATE))
+ {
+ return (false);
+ }
+
+ scanKeySize -= 1;
+ key++;
}
-
- scanKeySize -= 1;
- key++;
- }
-
- return (true);
-}
+ return (true);
+}
diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c
index 98fbddc639d..599ac59a455 100644
--- a/src/backend/access/common/printtup.c
+++ b/src/backend/access/common/printtup.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* printtup.c--
- * Routines to print out tuples to the destination (binary or non-binary
- * portals, frontend/interactive backend, etc.).
+ * Routines to print out tuples to the destination (binary or non-binary
+ * portals, frontend/interactive backend, etc.).
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.15 1997/08/26 23:31:23 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.16 1997/09/07 04:37:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,279 +16,304 @@
#include <string.h>
#include <postgres.h>
-#include <fmgr.h>
-#include <access/heapam.h>
-#include <access/printtup.h>
+#include <fmgr.h>
+#include <access/heapam.h>
+#include <access/printtup.h>
#include <catalog/pg_type.h>
#include <libpq/libpq.h>
#include <utils/syscache.h>
/* ----------------------------------------------------------------
- * printtup / debugtup support
+ * printtup / debugtup support
* ----------------------------------------------------------------
*/
/* ----------------
- * typtoout - used by printtup and debugtup
+ * typtoout - used by printtup and debugtup
* ----------------
*/
Oid
typtoout(Oid type)
{
- HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type),
- 0, 0, 0);
-
- if (HeapTupleIsValid(typeTuple))
- return((Oid)
- ((TypeTupleForm) GETSTRUCT(typeTuple))->typoutput);
-
- elog(WARN, "typtoout: Cache lookup of type %d failed", type);
- return(InvalidOid);
+ HeapTuple typeTuple;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+
+ if (HeapTupleIsValid(typeTuple))
+ return ((Oid)
+ ((TypeTupleForm) GETSTRUCT(typeTuple))->typoutput);
+
+ elog(WARN, "typtoout: Cache lookup of type %d failed", type);
+ return (InvalidOid);
}
Oid
gettypelem(Oid type)
{
- HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type),
- 0,0,0);
-
- if (HeapTupleIsValid(typeTuple))
- return((Oid)
- ((TypeTupleForm) GETSTRUCT(typeTuple))->typelem);
-
- elog(WARN, "typtoout: Cache lookup of type %d failed", type);
- return(InvalidOid);
+ HeapTuple typeTuple;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+
+ if (HeapTupleIsValid(typeTuple))
+ return ((Oid)
+ ((TypeTupleForm) GETSTRUCT(typeTuple))->typelem);
+
+ elog(WARN, "typtoout: Cache lookup of type %d failed", type);
+ return (InvalidOid);
}
/* ----------------
- * printtup
+ * printtup
* ----------------
*/
void
printtup(HeapTuple tuple, TupleDesc typeinfo)
{
- int i, j, k;
- char *outputstr, *attr;
- bool isnull;
- Oid typoutput;
-
- /* ----------------
- * tell the frontend to expect new tuple data
- * ----------------
- */
- pq_putnchar("D", 1);
-
- /* ----------------
- * send a bitmap of which attributes are null
- * ----------------
- */
- j = 0;
- k = 1 << 7;
- for (i = 0; i < tuple->t_natts; ) {
- i++; /* heap_getattr is a macro, so no increment */
- attr = heap_getattr(tuple, InvalidBuffer, i, typeinfo, &isnull);
- if (!isnull)
- j |= k;
- k >>= 1;
- if (!(i & 7)) {
- pq_putint(j, 1);
- j = 0;
- k = 1 << 7;
+ int i,
+ j,
+ k;
+ char *outputstr,
+ *attr;
+ bool isnull;
+ Oid typoutput;
+
+ /* ----------------
+ * tell the frontend to expect new tuple data
+ * ----------------
+ */
+ pq_putnchar("D", 1);
+
+ /* ----------------
+ * send a bitmap of which attributes are null
+ * ----------------
+ */
+ j = 0;
+ k = 1 << 7;
+ for (i = 0; i < tuple->t_natts;)
+ {
+ i++; /* heap_getattr is a macro, so no
+ * increment */
+ attr = heap_getattr(tuple, InvalidBuffer, i, typeinfo, &isnull);
+ if (!isnull)
+ j |= k;
+ k >>= 1;
+ if (!(i & 7))
+ {
+ pq_putint(j, 1);
+ j = 0;
+ k = 1 << 7;
+ }
}
- }
- if (i & 7)
- pq_putint(j, 1);
-
- /* ----------------
- * send the attributes of this tuple
- * ----------------
- */
- for (i = 0; i < tuple->t_natts; ++i) {
- attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
- typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
-
- if (!isnull && OidIsValid(typoutput)) {
- outputstr = fmgr(typoutput, attr,
- gettypelem(typeinfo->attrs[i]->atttypid));
- pq_putint(strlen(outputstr)+4, 4);
- pq_putnchar(outputstr, strlen(outputstr));
- pfree(outputstr);
+ if (i & 7)
+ pq_putint(j, 1);
+
+ /* ----------------
+ * send the attributes of this tuple
+ * ----------------
+ */
+ for (i = 0; i < tuple->t_natts; ++i)
+ {
+ attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
+ typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
+
+ if (!isnull && OidIsValid(typoutput))
+ {
+ outputstr = fmgr(typoutput, attr,
+ gettypelem(typeinfo->attrs[i]->atttypid));
+ pq_putint(strlen(outputstr) + 4, 4);
+ pq_putnchar(outputstr, strlen(outputstr));
+ pfree(outputstr);
+ }
}
- }
}
/* ----------------
- * printatt
+ * printatt
* ----------------
*/
static void
printatt(unsigned attributeId,
- AttributeTupleForm attributeP,
- char *value)
+ AttributeTupleForm attributeP,
+ char *value)
{
- printf("\t%2d: %s%s%s%s\t(typeid = %u, len = %d, byval = %c)\n",
- attributeId,
- attributeP->attname.data,
- value != NULL ? " = \"" : "",
- value != NULL ? value : "",
- value != NULL ? "\"" : "",
- (unsigned int) (attributeP->atttypid),
- attributeP->attlen,
- attributeP->attbyval ? 't' : 'f');
+ printf("\t%2d: %s%s%s%s\t(typeid = %u, len = %d, byval = %c)\n",
+ attributeId,
+ attributeP->attname.data,
+ value != NULL ? " = \"" : "",
+ value != NULL ? value : "",
+ value != NULL ? "\"" : "",
+ (unsigned int) (attributeP->atttypid),
+ attributeP->attlen,
+ attributeP->attbyval ? 't' : 'f');
}
/* ----------------
- * showatts
+ * showatts
* ----------------
*/
void
showatts(char *name, TupleDesc tupleDesc)
{
- int i;
- int natts = tupleDesc->natts;
- AttributeTupleForm *attinfo = tupleDesc->attrs;
+ int i;
+ int natts = tupleDesc->natts;
+ AttributeTupleForm *attinfo = tupleDesc->attrs;
- puts(name);
- for (i = 0; i < natts; ++i)
- printatt((unsigned) i+1, attinfo[i], (char *) NULL);
- printf("\t----\n");
+ puts(name);
+ for (i = 0; i < natts; ++i)
+ printatt((unsigned) i + 1, attinfo[i], (char *) NULL);
+ printf("\t----\n");
}
/* ----------------
- * debugtup
+ * debugtup
* ----------------
*/
void
debugtup(HeapTuple tuple, TupleDesc typeinfo)
{
- register int i;
- char *attr, *value;
- bool isnull;
- Oid typoutput;
-
- for (i = 0; i < tuple->t_natts; ++i) {
- attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
- typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
-
- if (!isnull && OidIsValid(typoutput)) {
- value = fmgr(typoutput, attr,
- gettypelem(typeinfo->attrs[i]->atttypid));
- printatt((unsigned) i+1, typeinfo->attrs[i], value);
- pfree(value);
+ register int i;
+ char *attr,
+ *value;
+ bool isnull;
+ Oid typoutput;
+
+ for (i = 0; i < tuple->t_natts; ++i)
+ {
+ attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
+ typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
+
+ if (!isnull && OidIsValid(typoutput))
+ {
+ value = fmgr(typoutput, attr,
+ gettypelem(typeinfo->attrs[i]->atttypid));
+ printatt((unsigned) i + 1, typeinfo->attrs[i], value);
+ pfree(value);
+ }
}
- }
- printf("\t----\n");
+ printf("\t----\n");
}
/* ----------------
- * printtup_internal
- * Protocol expects either T, D, C, E, or N.
- * We use a different data prefix, e.g. 'B' instead of 'D' to
- * indicate a tuple in internal (binary) form.
+ * printtup_internal
+ * Protocol expects either T, D, C, E, or N.
+ * We use a different data prefix, e.g. 'B' instead of 'D' to
+ * indicate a tuple in internal (binary) form.
*
- * This is same as printtup, except we don't use the typout func.
+ * This is same as printtup, except we don't use the typout func.
* ----------------
*/
void
printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
{
- int i, j, k;
- char *attr;
- bool isnull;
-
- /* ----------------
- * tell the frontend to expect new tuple data
- * ----------------
- */
- pq_putnchar("B", 1);
-
- /* ----------------
- * send a bitmap of which attributes are null
- * ----------------
- */
- j = 0;
- k = 1 << 7;
- for (i = 0; i < tuple->t_natts; ) {
- i++; /* heap_getattr is a macro, so no increment */
- attr = heap_getattr(tuple, InvalidBuffer, i, typeinfo, &isnull);
- if (!isnull)
- j |= k;
- k >>= 1;
- if (!(i & 7)) {
- pq_putint(j, 1);
- j = 0;
- k = 1 << 7;
+ int i,
+ j,
+ k;
+ char *attr;
+ bool isnull;
+
+ /* ----------------
+ * tell the frontend to expect new tuple data
+ * ----------------
+ */
+ pq_putnchar("B", 1);
+
+ /* ----------------
+ * send a bitmap of which attributes are null
+ * ----------------
+ */
+ j = 0;
+ k = 1 << 7;
+ for (i = 0; i < tuple->t_natts;)
+ {
+ i++; /* heap_getattr is a macro, so no
+ * increment */
+ attr = heap_getattr(tuple, InvalidBuffer, i, typeinfo, &isnull);
+ if (!isnull)
+ j |= k;
+ k >>= 1;
+ if (!(i & 7))
+ {
+ pq_putint(j, 1);
+ j = 0;
+ k = 1 << 7;
+ }
}
- }
- if (i & 7)
- pq_putint(j, 1);
-
- /* ----------------
- * send the attributes of this tuple
- * ----------------
- */
+ if (i & 7)
+ pq_putint(j, 1);
+
+ /* ----------------
+ * send the attributes of this tuple
+ * ----------------
+ */
#ifdef IPORTAL_DEBUG
- fprintf(stderr, "sending tuple with %d atts\n", tuple->t_natts);
+ fprintf(stderr, "sending tuple with %d atts\n", tuple->t_natts);
#endif
- for (i = 0; i < tuple->t_natts; ++i) {
- int32 len = typeinfo->attrs[i]->attlen;
-
- attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
- if (!isnull) {
- /* # of bytes, and opaque data */
- if (len == -1) {
- /* variable length, assume a varlena structure */
- len = VARSIZE(attr) - VARHDRSZ;
-
- pq_putint(len, sizeof(int32));
- pq_putnchar(VARDATA(attr), len);
-#ifdef IPORTAL_DEBUG
+ for (i = 0; i < tuple->t_natts; ++i)
+ {
+ int32 len = typeinfo->attrs[i]->attlen;
+
+ attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
+ if (!isnull)
{
- char *d = VARDATA(attr);
-
- fprintf(stderr, "length %d data %x%x%x%x\n",
- len, *d, *(d+1), *(d+2), *(d+3));
- }
+ /* # of bytes, and opaque data */
+ if (len == -1)
+ {
+ /* variable length, assume a varlena structure */
+ len = VARSIZE(attr) - VARHDRSZ;
+
+ pq_putint(len, sizeof(int32));
+ pq_putnchar(VARDATA(attr), len);
+#ifdef IPORTAL_DEBUG
+ {
+ char *d = VARDATA(attr);
+
+ fprintf(stderr, "length %d data %x%x%x%x\n",
+ len, *d, *(d + 1), *(d + 2), *(d + 3));
+ }
#endif
- } else {
- /* fixed size */
- if (typeinfo->attrs[i]->attbyval) {
- int8 i8;
- int16 i16;
- int32 i32;
-
- pq_putint(len, sizeof(int32));
- switch (len) {
- case sizeof(int8):
- i8 = DatumGetChar(attr);
- pq_putnchar((char *) &i8, len);
- break;
- case sizeof(int16):
- i16 = DatumGetInt16(attr);
- pq_putnchar((char *) &i16, len);
- break;
- case sizeof(int32):
- i32 = DatumGetInt32(attr);
- pq_putnchar((char *) &i32, len);
- break;
- }
+ }
+ else
+ {
+ /* fixed size */
+ if (typeinfo->attrs[i]->attbyval)
+ {
+ int8 i8;
+ int16 i16;
+ int32 i32;
+
+ pq_putint(len, sizeof(int32));
+ switch (len)
+ {
+ case sizeof(int8):
+ i8 = DatumGetChar(attr);
+ pq_putnchar((char *) &i8, len);
+ break;
+ case sizeof(int16):
+ i16 = DatumGetInt16(attr);
+ pq_putnchar((char *) &i16, len);
+ break;
+ case sizeof(int32):
+ i32 = DatumGetInt32(attr);
+ pq_putnchar((char *) &i32, len);
+ break;
+ }
#ifdef IPORTAL_DEBUG
- fprintf(stderr, "byval length %d data %d\n", len, attr);
+ fprintf(stderr, "byval length %d data %d\n", len, attr);
#endif
- } else {
- pq_putint(len, sizeof(int32));
- pq_putnchar(attr, len);
+ }
+ else
+ {
+ pq_putint(len, sizeof(int32));
+ pq_putnchar(attr, len);
#ifdef IPORTAL_DEBUG
- fprintf(stderr, "byref length %d data %x\n", len, attr);
+ fprintf(stderr, "byref length %d data %x\n", len, attr);
#endif
+ }
+ }
}
- }
}
- }
}
diff --git a/src/backend/access/common/scankey.c b/src/backend/access/common/scankey.c
index fb242497ebc..9fbe264ae5c 100644
--- a/src/backend/access/common/scankey.c
+++ b/src/backend/access/common/scankey.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* scan.c--
- * scan direction and key code
+ * scan direction and key code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.9 1996/11/05 07:42:45 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.10 1997/09/07 04:37:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,49 +19,49 @@
/*
* ScanKeyEntryIsLegal --
- * True iff the scan key entry is legal.
+ * True iff the scan key entry is legal.
*/
#define ScanKeyEntryIsLegal(entry) \
- ((bool) (AssertMacro(PointerIsValid(entry)) && \
- AttributeNumberIsValid(entry->sk_attno)))
+ ((bool) (AssertMacro(PointerIsValid(entry)) && \
+ AttributeNumberIsValid(entry->sk_attno)))
/*
* ScanKeyEntrySetIllegal --
- * Marks a scan key entry as illegal.
+ * Marks a scan key entry as illegal.
*/
void
ScanKeyEntrySetIllegal(ScanKey entry)
{
- Assert(PointerIsValid(entry));
-
- entry->sk_flags = 0; /* just in case... */
- entry->sk_attno = InvalidAttrNumber;
- entry->sk_procedure = 0; /* should be InvalidRegProcedure */
+ Assert(PointerIsValid(entry));
+
+ entry->sk_flags = 0; /* just in case... */
+ entry->sk_attno = InvalidAttrNumber;
+ entry->sk_procedure = 0; /* should be InvalidRegProcedure */
}
/*
* ScanKeyEntryInitialize --
- * Initializes an scan key entry.
+ * Initializes an scan key entry.
*
* Note:
- * Assumes the scan key entry is valid.
- * Assumes the intialized scan key entry will be legal.
+ * Assumes the scan key entry is valid.
+ * Assumes the intialized scan key entry will be legal.
*/
void
ScanKeyEntryInitialize(ScanKey entry,
- bits16 flags,
- AttrNumber attributeNumber,
- RegProcedure procedure,
- Datum argument)
+ bits16 flags,
+ AttrNumber attributeNumber,
+ RegProcedure procedure,
+ Datum argument)
{
- Assert(PointerIsValid(entry));
-
- entry->sk_flags = flags;
- entry->sk_attno = attributeNumber;
- entry->sk_procedure = procedure;
- entry->sk_argument = argument;
- fmgr_info(procedure, &entry->sk_func, &entry->sk_nargs);
-
- Assert(ScanKeyEntryIsLegal(entry));
+ Assert(PointerIsValid(entry));
+
+ entry->sk_flags = flags;
+ entry->sk_attno = attributeNumber;
+ entry->sk_procedure = procedure;
+ entry->sk_argument = argument;
+ fmgr_info(procedure, &entry->sk_func, &entry->sk_nargs);
+
+ Assert(ScanKeyEntryIsLegal(entry));
}
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index a38a5229f28..e616702a8ea 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* tupdesc.c--
- * POSTGRES tuple descriptor support code
+ * POSTGRES tuple descriptor support code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.19 1997/08/22 02:55:39 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.20 1997/09/07 04:37:41 momjian Exp $
*
* NOTES
- * some of the executor utility code such as "ExecTypeFromTL" should be
- * moved here.
+ * some of the executor utility code such as "ExecTypeFromTL" should be
+ * moved here.
*
*-------------------------------------------------------------------------
*/
@@ -28,518 +28,534 @@
#include <utils/syscache.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
/* ----------------------------------------------------------------
- * CreateTemplateTupleDesc
+ * CreateTemplateTupleDesc
*
- * This function allocates and zeros a tuple descriptor structure.
+ * This function allocates and zeros a tuple descriptor structure.
* ----------------------------------------------------------------
*/
TupleDesc
CreateTemplateTupleDesc(int natts)
{
- uint32 size;
- TupleDesc desc;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- AssertArg(natts >= 1);
-
- /* ----------------
- * allocate enough memory for the tuple descriptor and
- * zero it as TupleDescInitEntry assumes that the descriptor
- * is filled with NULL pointers.
- * ----------------
- */
- size = natts * sizeof (AttributeTupleForm);
- desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
- desc->attrs = (AttributeTupleForm*) palloc(size);
- desc->constr = NULL;
- memset(desc->attrs, 0, size);
-
- desc->natts = natts;
-
- return (desc);
+ uint32 size;
+ TupleDesc desc;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ AssertArg(natts >= 1);
+
+ /* ----------------
+ * allocate enough memory for the tuple descriptor and
+ * zero it as TupleDescInitEntry assumes that the descriptor
+ * is filled with NULL pointers.
+ * ----------------
+ */
+ size = natts * sizeof(AttributeTupleForm);
+ desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
+ desc->attrs = (AttributeTupleForm *) palloc(size);
+ desc->constr = NULL;
+ memset(desc->attrs, 0, size);
+
+ desc->natts = natts;
+
+ return (desc);
}
/* ----------------------------------------------------------------
- * CreateTupleDesc
+ * CreateTupleDesc
*
- * This function allocates a new TupleDesc from AttributeTupleForm array
+ * This function allocates a new TupleDesc from AttributeTupleForm array
* ----------------------------------------------------------------
*/
TupleDesc
-CreateTupleDesc(int natts, AttributeTupleForm* attrs)
+CreateTupleDesc(int natts, AttributeTupleForm * attrs)
{
- TupleDesc desc;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- AssertArg(natts >= 1);
-
- desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
- desc->attrs = attrs;
- desc->natts = natts;
- desc->constr = NULL;
-
- return (desc);
+ TupleDesc desc;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ AssertArg(natts >= 1);
+
+ desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
+ desc->attrs = attrs;
+ desc->natts = natts;
+ desc->constr = NULL;
+
+ return (desc);
}
/* ----------------------------------------------------------------
- * CreateTupleDescCopy
+ * CreateTupleDescCopy
*
- * This function creates a new TupleDesc by copying from an existing
- * TupleDesc
- *
- * !!! Constraints are not copied !!!
+ * This function creates a new TupleDesc by copying from an existing
+ * TupleDesc
+ *
+ * !!! Constraints are not copied !!!
* ----------------------------------------------------------------
*/
TupleDesc
CreateTupleDescCopy(TupleDesc tupdesc)
{
- TupleDesc desc;
- int i, size;
-
- desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
- desc->natts = tupdesc->natts;
- size = desc->natts * sizeof (AttributeTupleForm);
- desc->attrs = (AttributeTupleForm*) palloc(size);
- for (i=0;i<desc->natts;i++) {
- desc->attrs[i] =
- (AttributeTupleForm)palloc(ATTRIBUTE_TUPLE_SIZE);
- memmove(desc->attrs[i],
- tupdesc->attrs[i],
- ATTRIBUTE_TUPLE_SIZE);
- desc->attrs[i]->attnotnull = false;
- desc->attrs[i]->atthasdef = false;
- }
- desc->constr = NULL;
-
- return desc;
+ TupleDesc desc;
+ int i,
+ size;
+
+ desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
+ desc->natts = tupdesc->natts;
+ size = desc->natts * sizeof(AttributeTupleForm);
+ desc->attrs = (AttributeTupleForm *) palloc(size);
+ for (i = 0; i < desc->natts; i++)
+ {
+ desc->attrs[i] =
+ (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+ memmove(desc->attrs[i],
+ tupdesc->attrs[i],
+ ATTRIBUTE_TUPLE_SIZE);
+ desc->attrs[i]->attnotnull = false;
+ desc->attrs[i]->atthasdef = false;
+ }
+ desc->constr = NULL;
+
+ return desc;
}
/* ----------------------------------------------------------------
- * CreateTupleDescCopyConstr
+ * CreateTupleDescCopyConstr
+ *
+ * This function creates a new TupleDesc by copying from an existing
+ * TupleDesc (with Constraints)
*
- * This function creates a new TupleDesc by copying from an existing
- * TupleDesc (with Constraints)
- *
* ----------------------------------------------------------------
*/
TupleDesc
CreateTupleDescCopyConstr(TupleDesc tupdesc)
{
- TupleDesc desc;
- TupleConstr *constr = tupdesc->constr;
- int i, size;
-
- desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
- desc->natts = tupdesc->natts;
- size = desc->natts * sizeof (AttributeTupleForm);
- desc->attrs = (AttributeTupleForm*) palloc(size);
- for (i=0;i<desc->natts;i++) {
- desc->attrs[i] =
- (AttributeTupleForm)palloc(ATTRIBUTE_TUPLE_SIZE);
- memmove(desc->attrs[i],
- tupdesc->attrs[i],
- ATTRIBUTE_TUPLE_SIZE);
- }
- if (constr)
- {
- TupleConstr *cpy = (TupleConstr *) palloc(sizeof(TupleConstr));
-
- cpy->has_not_null = constr->has_not_null;
-
- if ( ( cpy->num_defval = constr->num_defval ) > 0 )
- {
- cpy->defval = (AttrDefault *) palloc (cpy->num_defval * sizeof (AttrDefault));
- memcpy (cpy->defval, constr->defval, cpy->num_defval * sizeof (AttrDefault));
- for (i = cpy->num_defval - 1; i >= 0; i--)
- {
- if ( constr->defval[i].adbin )
- cpy->defval[i].adbin = pstrdup (constr->defval[i].adbin);
- if ( constr->defval[i].adsrc )
- cpy->defval[i].adsrc = pstrdup (constr->defval[i].adsrc);
- }
- }
-
- if ( ( cpy->num_check = constr->num_check ) > 0 )
- {
- cpy->check = (ConstrCheck *) palloc (cpy->num_check * sizeof (ConstrCheck));
- memcpy (cpy->check, constr->check, cpy->num_check * sizeof (ConstrCheck));
- for (i = cpy->num_check - 1; i >= 0; i--)
- {
- if ( constr->check[i].ccname )
- cpy->check[i].ccname = pstrdup (constr->check[i].ccname);
- if ( constr->check[i].ccbin )
- cpy->check[i].ccbin = pstrdup (constr->check[i].ccbin);
- if ( constr->check[i].ccsrc )
- cpy->check[i].ccsrc = pstrdup (constr->check[i].ccsrc);
- }
- }
-
- desc->constr = cpy;
- }
- else
- desc->constr = NULL;
-
- return desc;
+ TupleDesc desc;
+ TupleConstr *constr = tupdesc->constr;
+ int i,
+ size;
+
+ desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
+ desc->natts = tupdesc->natts;
+ size = desc->natts * sizeof(AttributeTupleForm);
+ desc->attrs = (AttributeTupleForm *) palloc(size);
+ for (i = 0; i < desc->natts; i++)
+ {
+ desc->attrs[i] =
+ (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+ memmove(desc->attrs[i],
+ tupdesc->attrs[i],
+ ATTRIBUTE_TUPLE_SIZE);
+ }
+ if (constr)
+ {
+ TupleConstr *cpy = (TupleConstr *) palloc(sizeof(TupleConstr));
+
+ cpy->has_not_null = constr->has_not_null;
+
+ if ((cpy->num_defval = constr->num_defval) > 0)
+ {
+ cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault));
+ memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault));
+ for (i = cpy->num_defval - 1; i >= 0; i--)
+ {
+ if (constr->defval[i].adbin)
+ cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin);
+ if (constr->defval[i].adsrc)
+ cpy->defval[i].adsrc = pstrdup(constr->defval[i].adsrc);
+ }
+ }
+
+ if ((cpy->num_check = constr->num_check) > 0)
+ {
+ cpy->check = (ConstrCheck *) palloc(cpy->num_check * sizeof(ConstrCheck));
+ memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck));
+ for (i = cpy->num_check - 1; i >= 0; i--)
+ {
+ if (constr->check[i].ccname)
+ cpy->check[i].ccname = pstrdup(constr->check[i].ccname);
+ if (constr->check[i].ccbin)
+ cpy->check[i].ccbin = pstrdup(constr->check[i].ccbin);
+ if (constr->check[i].ccsrc)
+ cpy->check[i].ccsrc = pstrdup(constr->check[i].ccsrc);
+ }
+ }
+
+ desc->constr = cpy;
+ }
+ else
+ desc->constr = NULL;
+
+ return desc;
}
void
-FreeTupleDesc (TupleDesc tupdesc)
+FreeTupleDesc(TupleDesc tupdesc)
{
- int i;
-
- for (i = 0; i < tupdesc->natts; i++)
- pfree (tupdesc->attrs[i]);
- pfree (tupdesc->attrs);
- if ( tupdesc->constr )
- {
- if ( tupdesc->constr->num_defval > 0 )
- {
- AttrDefault *attrdef = tupdesc->constr->defval;
-
- for (i = tupdesc->constr->num_defval - 1; i >= 0; i--)
- {
- if ( attrdef[i].adbin )
- pfree (attrdef[i].adbin);
- if ( attrdef[i].adsrc )
- pfree (attrdef[i].adsrc);
- }
- pfree (attrdef);
- }
- if ( tupdesc->constr->num_check > 0 )
- {
- ConstrCheck *check = tupdesc->constr->check;
-
- for (i = tupdesc->constr->num_check - 1; i >= 0; i--)
- {
- if ( check[i].ccname )
- pfree (check[i].ccname);
- if ( check[i].ccbin )
- pfree (check[i].ccbin);
- if ( check[i].ccsrc )
- pfree (check[i].ccsrc);
- }
- pfree (check);
- }
- pfree (tupdesc->constr);
- }
-
- pfree (tupdesc);
+ int i;
+
+ for (i = 0; i < tupdesc->natts; i++)
+ pfree(tupdesc->attrs[i]);
+ pfree(tupdesc->attrs);
+ if (tupdesc->constr)
+ {
+ if (tupdesc->constr->num_defval > 0)
+ {
+ AttrDefault *attrdef = tupdesc->constr->defval;
+
+ for (i = tupdesc->constr->num_defval - 1; i >= 0; i--)
+ {
+ if (attrdef[i].adbin)
+ pfree(attrdef[i].adbin);
+ if (attrdef[i].adsrc)
+ pfree(attrdef[i].adsrc);
+ }
+ pfree(attrdef);
+ }
+ if (tupdesc->constr->num_check > 0)
+ {
+ ConstrCheck *check = tupdesc->constr->check;
+
+ for (i = tupdesc->constr->num_check - 1; i >= 0; i--)
+ {
+ if (check[i].ccname)
+ pfree(check[i].ccname);
+ if (check[i].ccbin)
+ pfree(check[i].ccbin);
+ if (check[i].ccsrc)
+ pfree(check[i].ccsrc);
+ }
+ pfree(check);
+ }
+ pfree(tupdesc->constr);
+ }
+
+ pfree(tupdesc);
}
/* ----------------------------------------------------------------
- * TupleDescInitEntry
+ * TupleDescInitEntry
*
- * This function initializes a single attribute structure in
- * a preallocated tuple descriptor.
+ * This function initializes a single attribute structure in
+ * a preallocated tuple descriptor.
* ----------------------------------------------------------------
*/
bool
TupleDescInitEntry(TupleDesc desc,
- AttrNumber attributeNumber,
- char *attributeName,
- char *typeName,
- int attdim,
- bool attisset)
+ AttrNumber attributeNumber,
+ char *attributeName,
+ char *typeName,
+ int attdim,
+ bool attisset)
{
- HeapTuple tuple;
- TypeTupleForm typeForm;
- AttributeTupleForm att;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- AssertArg(PointerIsValid(desc));
- AssertArg(attributeNumber >= 1);
- /* attributeName's are sometimes NULL,
- from resdom's. I don't know why that is, though -- Jolly */
-/* AssertArg(NameIsValid(attributeName));*/
-/* AssertArg(NameIsValid(typeName));*/
-
- AssertArg(!PointerIsValid(desc->attrs[attributeNumber - 1]));
-
-
- /* ----------------
- * allocate storage for this attribute
- * ----------------
- */
-
- att = (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
- desc->attrs[attributeNumber - 1] = att;
-
- /* ----------------
- * initialize some of the attribute fields
- * ----------------
- */
- att->attrelid = 0; /* dummy value */
-
- if (attributeName != NULL)
- namestrcpy(&(att->attname), attributeName);
- else
- memset(att->attname.data,0,NAMEDATALEN);
-
-
- att->attdisbursion = 0; /* dummy value */
- att->attcacheoff = -1;
-
- att->attnum = attributeNumber;
- att->attnelems = attdim;
- att->attisset = attisset;
-
- att->attnotnull = false;
- att->atthasdef = false;
-
- /* ----------------
- * search the system cache for the type tuple of the attribute
- * we are creating so that we can get the typeid and some other
- * stuff.
- *
- * Note: in the special case of
- *
- * create EMP (name = char16, manager = EMP)
- *
- * RelationNameCreateHeapRelation() calls BuildDesc() which
- * calls this routine and since EMP does not exist yet, the
- * system cache lookup below fails. That's fine, but rather
- * then doing a elog(WARN) we just leave that information
- * uninitialized, return false, then fix things up later.
- * -cim 6/14/90
- * ----------------
- */
- tuple = SearchSysCacheTuple(TYPNAME, PointerGetDatum(typeName),
- 0,0,0);
- if (! HeapTupleIsValid(tuple)) {
+ HeapTuple tuple;
+ TypeTupleForm typeForm;
+ AttributeTupleForm att;
+
/* ----------------
- * here type info does not exist yet so we just fill
- * the attribute with dummy information and return false.
+ * sanity checks
* ----------------
*/
- att->atttypid = InvalidOid;
- att->attlen = (int16) 0;
- att->attbyval = (bool) 0;
- att->attalign = 'i';
- return false;
- }
-
- /* ----------------
- * type info exists so we initialize our attribute
- * information from the type tuple we found..
- * ----------------
- */
- typeForm = (TypeTupleForm) GETSTRUCT(tuple);
-
- att->atttypid = tuple->t_oid;
- att->attalign = typeForm->typalign;
-
- /* ------------------------
- If this attribute is a set, what is really stored in the
- attribute is the OID of a tuple in the pg_proc catalog.
- The pg_proc tuple contains the query string which defines
- this set - i.e., the query to run to get the set.
- So the atttypid (just assigned above) refers to the type returned
- by this query, but the actual length of this attribute is the
- length (size) of an OID.
-
- Why not just make the atttypid point to the OID type, instead
- of the type the query returns? Because the executor uses the atttypid
- to tell the front end what type will be returned (in BeginCommand),
- and in the end the type returned will be the result of the query, not
- an OID.
-
- Why not wait until the return type of the set is known (i.e., the
- recursive call to the executor to execute the set has returned)
- before telling the front end what the return type will be? Because
- the executor is a delicate thing, and making sure that the correct
- order of front-end commands is maintained is messy, especially
- considering that target lists may change as inherited attributes
- are considered, etc. Ugh.
- -----------------------------------------
- */
- if (attisset) {
- Type t = type("oid");
- att->attlen = tlen(t);
- att->attbyval = tbyval(t);
- } else {
- att->attlen = typeForm->typlen;
- att->attbyval = typeForm->typbyval;
- }
-
-
- return true;
+ AssertArg(PointerIsValid(desc));
+ AssertArg(attributeNumber >= 1);
+
+ /*
+ * attributeName's are sometimes NULL, from resdom's. I don't know
+ * why that is, though -- Jolly
+ */
+/* AssertArg(NameIsValid(attributeName));*/
+/* AssertArg(NameIsValid(typeName));*/
+
+ AssertArg(!PointerIsValid(desc->attrs[attributeNumber - 1]));
+
+
+ /* ----------------
+ * allocate storage for this attribute
+ * ----------------
+ */
+
+ att = (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+ desc->attrs[attributeNumber - 1] = att;
+
+ /* ----------------
+ * initialize some of the attribute fields
+ * ----------------
+ */
+ att->attrelid = 0; /* dummy value */
+
+ if (attributeName != NULL)
+ namestrcpy(&(att->attname), attributeName);
+ else
+ memset(att->attname.data, 0, NAMEDATALEN);
+
+
+ att->attdisbursion = 0; /* dummy value */
+ att->attcacheoff = -1;
+
+ att->attnum = attributeNumber;
+ att->attnelems = attdim;
+ att->attisset = attisset;
+
+ att->attnotnull = false;
+ att->atthasdef = false;
+
+ /* ----------------
+ * search the system cache for the type tuple of the attribute
+ * we are creating so that we can get the typeid and some other
+ * stuff.
+ *
+ * Note: in the special case of
+ *
+ * create EMP (name = char16, manager = EMP)
+ *
+ * RelationNameCreateHeapRelation() calls BuildDesc() which
+ * calls this routine and since EMP does not exist yet, the
+ * system cache lookup below fails. That's fine, but rather
+ * then doing a elog(WARN) we just leave that information
+ * uninitialized, return false, then fix things up later.
+ * -cim 6/14/90
+ * ----------------
+ */
+ tuple = SearchSysCacheTuple(TYPNAME, PointerGetDatum(typeName),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ {
+ /* ----------------
+ * here type info does not exist yet so we just fill
+ * the attribute with dummy information and return false.
+ * ----------------
+ */
+ att->atttypid = InvalidOid;
+ att->attlen = (int16) 0;
+ att->attbyval = (bool) 0;
+ att->attalign = 'i';
+ return false;
+ }
+
+ /* ----------------
+ * type info exists so we initialize our attribute
+ * information from the type tuple we found..
+ * ----------------
+ */
+ typeForm = (TypeTupleForm) GETSTRUCT(tuple);
+
+ att->atttypid = tuple->t_oid;
+ att->attalign = typeForm->typalign;
+
+ /* ------------------------
+ If this attribute is a set, what is really stored in the
+ attribute is the OID of a tuple in the pg_proc catalog.
+ The pg_proc tuple contains the query string which defines
+ this set - i.e., the query to run to get the set.
+ So the atttypid (just assigned above) refers to the type returned
+ by this query, but the actual length of this attribute is the
+ length (size) of an OID.
+
+ Why not just make the atttypid point to the OID type, instead
+ of the type the query returns? Because the executor uses the atttypid
+ to tell the front end what type will be returned (in BeginCommand),
+ and in the end the type returned will be the result of the query, not
+ an OID.
+
+ Why not wait until the return type of the set is known (i.e., the
+ recursive call to the executor to execute the set has returned)
+ before telling the front end what the return type will be? Because
+ the executor is a delicate thing, and making sure that the correct
+ order of front-end commands is maintained is messy, especially
+ considering that target lists may change as inherited attributes
+ are considered, etc. Ugh.
+ -----------------------------------------
+ */
+ if (attisset)
+ {
+ Type t = type("oid");
+
+ att->attlen = tlen(t);
+ att->attbyval = tbyval(t);
+ }
+ else
+ {
+ att->attlen = typeForm->typlen;
+ att->attbyval = typeForm->typbyval;
+ }
+
+
+ return true;
}
/* ----------------------------------------------------------------
- * TupleDescMakeSelfReference
+ * TupleDescMakeSelfReference
*
- * This function initializes a "self-referential" attribute like
- * manager in "create EMP (name=text, manager = EMP)".
- * It calls TypeShellMake() which inserts a "shell" type
- * tuple into pg_type. A self-reference is one kind of set, so
- * its size and byval are the same as for a set. See the comments
- * above in TupleDescInitEntry.
+ * This function initializes a "self-referential" attribute like
+ * manager in "create EMP (name=text, manager = EMP)".
+ * It calls TypeShellMake() which inserts a "shell" type
+ * tuple into pg_type. A self-reference is one kind of set, so
+ * its size and byval are the same as for a set. See the comments
+ * above in TupleDescInitEntry.
* ----------------------------------------------------------------
*/
static void
TupleDescMakeSelfReference(TupleDesc desc,
- AttrNumber attnum,
- char *relname)
+ AttrNumber attnum,
+ char *relname)
{
- AttributeTupleForm att;
- Type t = type("oid");
-
- att = desc->attrs[attnum-1];
- att->atttypid = TypeShellMake(relname);
- att->attlen = tlen(t);
- att->attbyval = tbyval(t);
- att->attnelems = 0;
+ AttributeTupleForm att;
+ Type t = type("oid");
+
+ att = desc->attrs[attnum - 1];
+ att->atttypid = TypeShellMake(relname);
+ att->attlen = tlen(t);
+ att->attbyval = tbyval(t);
+ att->attnelems = 0;
}
/* ----------------------------------------------------------------
- * BuildDescForRelation
+ * BuildDescForRelation
*
- * This is a general purpose function identical to BuildDesc
- * but is used by the DefineRelation() code to catch the
- * special case where you
+ * This is a general purpose function identical to BuildDesc
+ * but is used by the DefineRelation() code to catch the
+ * special case where you
*
- * create FOO ( ..., x = FOO )
+ * create FOO ( ..., x = FOO )
*
- * here, the initial type lookup for "x = FOO" will fail
- * because FOO isn't in the catalogs yet. But since we
- * are creating FOO, instead of doing an elog() we add
- * a shell type tuple to pg_type and fix things later
- * in amcreate().
+ * here, the initial type lookup for "x = FOO" will fail
+ * because FOO isn't in the catalogs yet. But since we
+ * are creating FOO, instead of doing an elog() we add
+ * a shell type tuple to pg_type and fix things later
+ * in amcreate().
* ----------------------------------------------------------------
*/
TupleDesc
-BuildDescForRelation(List *schema, char *relname)
+BuildDescForRelation(List * schema, char *relname)
{
- int natts;
- AttrNumber attnum;
- List *p;
- TupleDesc desc;
- AttrDefault *attrdef = NULL;
- TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
- char *attname;
- char *typename;
- int attdim;
- int ndef = 0;
- bool attisset;
-
- /* ----------------
- * allocate a new tuple descriptor
- * ----------------
- */
- natts = length(schema);
- desc = CreateTemplateTupleDesc(natts);
- constr->has_not_null = false;
-
- attnum = 0;
-
- typename = palloc(NAMEDATALEN);
-
- foreach(p, schema) {
- ColumnDef *entry;
- List *arry;
+ int natts;
+ AttrNumber attnum;
+ List *p;
+ TupleDesc desc;
+ AttrDefault *attrdef = NULL;
+ TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
+ char *attname;
+ char *typename;
+ int attdim;
+ int ndef = 0;
+ bool attisset;
/* ----------------
- * for each entry in the list, get the name and type
- * information from the list and have TupleDescInitEntry
- * fill in the attribute information we need.
+ * allocate a new tuple descriptor
* ----------------
- */
- attnum++;
-
- entry = lfirst(p);
- attname = entry->colname;
- arry = entry->typename->arrayBounds;
- attisset = entry->typename->setof;
-
- strNcpy(typename, entry->typename->name,NAMEDATALEN-1);
- if (arry != NIL)
- attdim = length(arry);
- else
- attdim = 0;
-
- if (! TupleDescInitEntry(desc, attnum, attname,
- typename, attdim, attisset)) {
- /* ----------------
- * if TupleDescInitEntry() fails, it means there is
- * no type in the system catalogs. So now we check if
- * the type name equals the relation name. If so we
- * have a self reference, otherwise it's an error.
- * ----------------
- */
- if (!strcmp(typename, relname)) {
- TupleDescMakeSelfReference(desc, attnum, relname);
- } else
- elog(WARN, "DefineRelation: no such type %s",
- typename);
- }
-
- /*
- * this is for char() and varchar(). When an entry is of type
- * char() or varchar(), typlen is set to the appropriate length,
- * which we'll use here instead. (The catalog lookup only returns
- * the length of bpchar and varchar which is not what we want!)
- * - ay 6/95
*/
- if (entry->typename->typlen > 0) {
- desc->attrs[attnum - 1]->attlen = entry->typename->typlen;
- }
+ natts = length(schema);
+ desc = CreateTemplateTupleDesc(natts);
+ constr->has_not_null = false;
- /* This is for constraints */
- if (entry->is_not_null)
- constr->has_not_null = true;
- desc->attrs[attnum-1]->attnotnull = entry->is_not_null;
-
- if ( entry->defval != NULL )
+ attnum = 0;
+
+ typename = palloc(NAMEDATALEN);
+
+ foreach(p, schema)
{
- if ( attrdef == NULL )
- attrdef = (AttrDefault*) palloc (natts * sizeof (AttrDefault));
- attrdef[ndef].adnum = attnum;
- attrdef[ndef].adbin = NULL;
- attrdef[ndef].adsrc = entry->defval;
- ndef++;
- desc->attrs[attnum-1]->atthasdef = true;
+ ColumnDef *entry;
+ List *arry;
+
+ /* ----------------
+ * for each entry in the list, get the name and type
+ * information from the list and have TupleDescInitEntry
+ * fill in the attribute information we need.
+ * ----------------
+ */
+ attnum++;
+
+ entry = lfirst(p);
+ attname = entry->colname;
+ arry = entry->typename->arrayBounds;
+ attisset = entry->typename->setof;
+
+ strNcpy(typename, entry->typename->name, NAMEDATALEN - 1);
+ if (arry != NIL)
+ attdim = length(arry);
+ else
+ attdim = 0;
+
+ if (!TupleDescInitEntry(desc, attnum, attname,
+ typename, attdim, attisset))
+ {
+ /* ----------------
+ * if TupleDescInitEntry() fails, it means there is
+ * no type in the system catalogs. So now we check if
+ * the type name equals the relation name. If so we
+ * have a self reference, otherwise it's an error.
+ * ----------------
+ */
+ if (!strcmp(typename, relname))
+ {
+ TupleDescMakeSelfReference(desc, attnum, relname);
+ }
+ else
+ elog(WARN, "DefineRelation: no such type %s",
+ typename);
+ }
+
+ /*
+ * this is for char() and varchar(). When an entry is of type
+ * char() or varchar(), typlen is set to the appropriate length,
+ * which we'll use here instead. (The catalog lookup only returns
+ * the length of bpchar and varchar which is not what we want!) -
+ * ay 6/95
+ */
+ if (entry->typename->typlen > 0)
+ {
+ desc->attrs[attnum - 1]->attlen = entry->typename->typlen;
+ }
+
+ /* This is for constraints */
+ if (entry->is_not_null)
+ constr->has_not_null = true;
+ desc->attrs[attnum - 1]->attnotnull = entry->is_not_null;
+
+ if (entry->defval != NULL)
+ {
+ if (attrdef == NULL)
+ attrdef = (AttrDefault *) palloc(natts * sizeof(AttrDefault));
+ attrdef[ndef].adnum = attnum;
+ attrdef[ndef].adbin = NULL;
+ attrdef[ndef].adsrc = entry->defval;
+ ndef++;
+ desc->attrs[attnum - 1]->atthasdef = true;
+ }
+
}
+ if (constr->has_not_null || ndef > 0)
+ {
+ desc->constr = constr;
- }
- if ( constr->has_not_null || ndef > 0 )
- {
- desc->constr = constr;
-
- if ( ndef > 0 ) /* DEFAULTs */
- {
- if ( ndef < natts )
- constr->defval = (AttrDefault*)
- repalloc (attrdef, ndef * sizeof (AttrDefault));
- else
- constr->defval = attrdef;
- constr->num_defval = ndef;
- }
- else
- constr->num_defval = 0;
- constr->num_check = 0;
- }
- else
- {
- pfree (constr);
- desc->constr = NULL;
- }
- return desc;
+ if (ndef > 0) /* DEFAULTs */
+ {
+ if (ndef < natts)
+ constr->defval = (AttrDefault *)
+ repalloc(attrdef, ndef * sizeof(AttrDefault));
+ else
+ constr->defval = attrdef;
+ constr->num_defval = ndef;
+ }
+ else
+ constr->num_defval = 0;
+ constr->num_check = 0;
+ }
+ else
+ {
+ pfree(constr);
+ desc->constr = NULL;
+ }
+ return desc;
}
-
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index 1d36f340ed6..598f9ed8f02 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* gist.c--
- * interface routines for the postgres GiST index access method.
+ * interface routines for the postgres GiST index access method.
*
*
*
@@ -26,308 +26,345 @@
#include <utils/syscache.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
/* non-export function prototypes */
-static InsertIndexResult gistdoinsert(Relation r, IndexTuple itup,
- GISTSTATE *GISTstate);
-static InsertIndexResult gistentryinsert(Relation r, GISTSTACK *stk,
- IndexTuple tup,
- GISTSTATE *giststate);
-static void gistentryinserttwo(Relation r, GISTSTACK *stk, IndexTuple ltup,
- IndexTuple rtup, GISTSTATE *giststate);
-static void gistAdjustKeys(Relation r, GISTSTACK *stk, BlockNumber blk,
- char *datum, int att_size, GISTSTATE *giststate);
-static void gistintinsert(Relation r, GISTSTACK *stk, IndexTuple ltup,
- IndexTuple rtup, GISTSTATE *giststate);
-static InsertIndexResult gistSplit(Relation r, Buffer buffer,
- GISTSTACK *stack, IndexTuple itup,
- GISTSTATE *giststate);
-static void gistnewroot(GISTSTATE *giststate, Relation r, IndexTuple lt,
+static InsertIndexResult
+gistdoinsert(Relation r, IndexTuple itup,
+ GISTSTATE * GISTstate);
+static InsertIndexResult
+gistentryinsert(Relation r, GISTSTACK * stk,
+ IndexTuple tup,
+ GISTSTATE * giststate);
+static void
+gistentryinserttwo(Relation r, GISTSTACK * stk, IndexTuple ltup,
+ IndexTuple rtup, GISTSTATE * giststate);
+static void
+gistAdjustKeys(Relation r, GISTSTACK * stk, BlockNumber blk,
+ char *datum, int att_size, GISTSTATE * giststate);
+static void
+gistintinsert(Relation r, GISTSTACK * stk, IndexTuple ltup,
+ IndexTuple rtup, GISTSTATE * giststate);
+static InsertIndexResult
+gistSplit(Relation r, Buffer buffer,
+ GISTSTACK * stack, IndexTuple itup,
+ GISTSTATE * giststate);
+static void
+gistnewroot(GISTSTATE * giststate, Relation r, IndexTuple lt,
IndexTuple rt);
-static void GISTInitBuffer(Buffer b, uint32 f);
-static BlockNumber gistChooseSubtree(Relation r, IndexTuple itup, int level,
- GISTSTATE *giststate,
- GISTSTACK **retstack, Buffer *leafbuf);
-static OffsetNumber gistchoose(Relation r, Page p, IndexTuple it,
- GISTSTATE *giststate);
-static int gistnospace(Page p, IndexTuple it);
-void gistdelete(Relation r, ItemPointer tid);
+static void GISTInitBuffer(Buffer b, uint32 f);
+static BlockNumber
+gistChooseSubtree(Relation r, IndexTuple itup, int level,
+ GISTSTATE * giststate,
+ GISTSTACK ** retstack, Buffer * leafbuf);
+static OffsetNumber
+gistchoose(Relation r, Page p, IndexTuple it,
+ GISTSTATE * giststate);
+static int gistnospace(Page p, IndexTuple it);
+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) ;
-static char *int_range_out(INTRANGE *r);
+static void
+gistcentryinit(GISTSTATE * giststate, GISTENTRY * e, char *pr,
+ Relation r, Page pg, OffsetNumber o, int b, bool l);
+static char *int_range_out(INTRANGE * r);
/*
** routine to build an index. Basically calls insert over and over
*/
void
gistbuild(Relation heap,
- Relation index,
- int natts,
- AttrNumber *attnum,
- IndexStrategy istrat,
- uint16 pint,
- Datum *params,
- FuncIndexInfo *finfo,
- PredInfo *predInfo)
+ Relation index,
+ int natts,
+ AttrNumber * attnum,
+ IndexStrategy istrat,
+ uint16 pint,
+ Datum * params,
+ FuncIndexInfo * finfo,
+ PredInfo * predInfo)
{
- HeapScanDesc scan;
- Buffer buffer;
- AttrNumber i;
- HeapTuple htup;
- IndexTuple itup;
- TupleDesc hd, id;
- InsertIndexResult res;
- Datum *d;
- bool *nulls;
- int nb, nh, ni;
+ HeapScanDesc scan;
+ Buffer buffer;
+ AttrNumber i;
+ HeapTuple htup;
+ IndexTuple itup;
+ TupleDesc hd,
+ id;
+ InsertIndexResult res;
+ Datum *d;
+ bool *nulls;
+ int nb,
+ nh,
+ ni;
+
#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext;
- TupleTable tupleTable;
- TupleTableSlot *slot;
+ ExprContext *econtext;
+ TupleTable tupleTable;
+ TupleTableSlot *slot;
+
#endif
- Oid hrelid, irelid;
- Node *pred, *oldPred;
- GISTSTATE giststate;
- GISTENTRY tmpcentry;
- bool *compvec;
-
- /* GiSTs only know how to do stupid locking now */
- RelationSetLockForWrite(index);
-
- setheapoverride(TRUE); /* so we can see the new pg_index tuple */
- initGISTstate(&giststate, index);
- setheapoverride(FALSE);
-
- pred = predInfo->pred;
- oldPred = predInfo->oldPred;
-
- /*
- * We expect to be called exactly once for any index relation.
- * If that's not the case, big trouble's what we have.
- */
-
- if (oldPred == NULL && (nb = RelationGetNumberOfBlocks(index)) != 0)
- elog(WARN, "%.16s already contains data", &(index->rd_rel->relname.data[0]));
-
- /* initialize the root page (if this is a new index) */
- if (oldPred == NULL) {
- buffer = ReadBuffer(index, P_NEW);
- GISTInitBuffer(buffer, F_LEAF);
- WriteBuffer(buffer);
- }
-
- /* init the tuple descriptors and get set for a heap scan */
- hd = RelationGetTupleDescriptor(heap);
- id = RelationGetTupleDescriptor(index);
- d = (Datum *)palloc(natts * sizeof (*d));
- nulls = (bool *)palloc(natts * sizeof (*nulls));
-
- /*
- * If this is a predicate (partial) index, we will need to evaluate the
- * predicate using ExecQual, which requires the current tuple to be in a
- * slot of a TupleTable. In addition, ExecQual must have an ExprContext
- * referring to that slot. Here, we initialize dummy TupleTable and
- * ExprContext objects for this purpose. --Nels, Feb '92
- */
+ Oid hrelid,
+ irelid;
+ Node *pred,
+ *oldPred;
+ GISTSTATE giststate;
+ GISTENTRY tmpcentry;
+ bool *compvec;
+
+ /* GiSTs only know how to do stupid locking now */
+ RelationSetLockForWrite(index);
+
+ setheapoverride(TRUE); /* so we can see the new pg_index tuple */
+ initGISTstate(&giststate, index);
+ setheapoverride(FALSE);
+
+ pred = predInfo->pred;
+ oldPred = predInfo->oldPred;
+
+ /*
+ * We expect to be called exactly once for any index relation. If
+ * that's not the case, big trouble's what we have.
+ */
+
+ if (oldPred == NULL && (nb = RelationGetNumberOfBlocks(index)) != 0)
+ elog(WARN, "%.16s already contains data", &(index->rd_rel->relname.data[0]));
+
+ /* initialize the root page (if this is a new index) */
+ if (oldPred == NULL)
+ {
+ buffer = ReadBuffer(index, P_NEW);
+ GISTInitBuffer(buffer, F_LEAF);
+ WriteBuffer(buffer);
+ }
+
+ /* init the tuple descriptors and get set for a heap scan */
+ hd = RelationGetTupleDescriptor(heap);
+ id = RelationGetTupleDescriptor(index);
+ d = (Datum *) palloc(natts * sizeof(*d));
+ nulls = (bool *) palloc(natts * sizeof(*nulls));
+
+ /*
+ * If this is a predicate (partial) index, we will need to evaluate
+ * the predicate using ExecQual, which requires the current tuple to
+ * be in a slot of a TupleTable. In addition, ExecQual must have an
+ * ExprContext referring to that slot. Here, we initialize dummy
+ * TupleTable and ExprContext objects for this purpose. --Nels, Feb
+ * '92
+ */
#ifndef OMIT_PARTIAL_INDEX
- if (pred != NULL || oldPred != NULL) {
- tupleTable = ExecCreateTupleTable(1);
- slot = ExecAllocTableSlot(tupleTable);
- econtext = makeNode(ExprContext);
- FillDummyExprContext(econtext, slot, hd, buffer);
- }
- else /* shut the compiler up */
+ if (pred != NULL || oldPred != NULL)
+ {
+ tupleTable = ExecCreateTupleTable(1);
+ slot = ExecAllocTableSlot(tupleTable);
+ econtext = makeNode(ExprContext);
+ FillDummyExprContext(econtext, slot, hd, buffer);
+ }
+ else
+/* shut the compiler up */
{
tupleTable = NULL;
slot = NULL;
econtext = NULL;
}
-#endif /* OMIT_PARTIAL_INDEX */
- scan = heap_beginscan(heap, 0, NowTimeQual, 0, (ScanKey) NULL);
- htup = heap_getnext(scan, 0, &buffer);
-
- /* int the tuples as we insert them */
- nh = ni = 0;
-
- for (; HeapTupleIsValid(htup); htup = heap_getnext(scan, 0, &buffer)) {
-
- nh++;
-
- /*
- * If oldPred != NULL, this is an EXTEND INDEX command, so skip
- * this tuple if it was already in the existing partial index
- */
- if (oldPred != NULL) {
+#endif /* OMIT_PARTIAL_INDEX */
+ scan = heap_beginscan(heap, 0, NowTimeQual, 0, (ScanKey) NULL);
+ htup = heap_getnext(scan, 0, &buffer);
+
+ /* int the tuples as we insert them */
+ nh = ni = 0;
+
+ for (; HeapTupleIsValid(htup); htup = heap_getnext(scan, 0, &buffer))
+ {
+
+ nh++;
+
+ /*
+ * If oldPred != NULL, this is an EXTEND INDEX command, so skip
+ * this tuple if it was already in the existing partial index
+ */
+ if (oldPred != NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- /*SetSlotContents(slot, htup); */
- slot->val = htup;
- if (ExecQual((List*)oldPred, econtext) == true) {
+ /* SetSlotContents(slot, htup); */
+ slot->val = htup;
+ if (ExecQual((List *) oldPred, econtext) == true)
+ {
+ ni++;
+ continue;
+ }
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+
+ /*
+ * Skip this tuple if it doesn't satisfy the partial-index
+ * predicate
+ */
+ if (pred != NULL)
+ {
+#ifndef OMIT_PARTIAL_INDEX
+ /* SetSlotContents(slot, htup); */
+ slot->val = htup;
+ if (ExecQual((List *) pred, econtext) == false)
+ continue;
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+
ni++;
- continue;
- }
-#endif /* OMIT_PARTIAL_INDEX */
+
+ /*
+ * For the current heap tuple, extract all the attributes we use
+ * in this index, and note which are null.
+ */
+
+ for (i = 1; i <= natts; i++)
+ {
+ int attoff;
+ bool attnull;
+
+ /*
+ * Offsets are from the start of the tuple, and are
+ * zero-based; indices are one-based. The next call returns i
+ * - 1. That's data hiding for you.
+ */
+
+ attoff = AttrNumberGetAttrOffset(i);
+
+ /*
+ * d[attoff] = HeapTupleGetAttributeValue(htup, buffer,
+ */
+ d[attoff] = GetIndexValue(htup,
+ hd,
+ attoff,
+ attnum,
+ finfo,
+ &attnull,
+ buffer);
+ nulls[attoff] = (attnull ? 'n' : ' ');
+ }
+
+ /* immediately compress keys to normalize */
+ compvec = (bool *) palloc(sizeof(bool) * natts);
+ for (i = 0; i < natts; i++)
+ {
+ gistcentryinit(&giststate, &tmpcentry, (char *) d[i],
+ (Relation) NULL, (Page) NULL, (OffsetNumber) 0,
+ -1 /* size is currently bogus */ , TRUE);
+ if (d[i] != (Datum) tmpcentry.pred && !(giststate.keytypbyval))
+ compvec[i] = TRUE;
+ else
+ compvec[i] = FALSE;
+ d[i] = (Datum) tmpcentry.pred;
+ }
+
+ /* form an index tuple and point it at the heap tuple */
+ itup = index_formtuple(id, &d[0], nulls);
+ itup->t_tid = htup->t_ctid;
+
+ /*
+ * Since we already have the index relation locked, we call
+ * gistdoinsert directly. Normal access method calls dispatch
+ * through gistinsert, which locks the relation for write. This
+ * is the right thing to do if you're inserting single tups, but
+ * not when you're initializing the whole index at once.
+ */
+
+ res = gistdoinsert(index, itup, &giststate);
+ for (i = 0; i < natts; i++)
+ if (compvec[i] == TRUE)
+ pfree((char *) d[i]);
+ pfree(itup);
+ pfree(res);
+ pfree(compvec);
}
-
- /* Skip this tuple if it doesn't satisfy the partial-index predicate */
- if (pred != NULL) {
+
+ /* okay, all heap tuples are indexed */
+ heap_endscan(scan);
+ RelationUnsetLockForWrite(index);
+
+ if (pred != NULL || oldPred != NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- /*SetSlotContents(slot, htup); */
- slot->val = htup;
- if (ExecQual((List*)pred, econtext) == false)
- continue;
-#endif /* OMIT_PARTIAL_INDEX */
+ ExecDestroyTupleTable(tupleTable, true);
+ pfree(econtext);
+#endif /* OMIT_PARTIAL_INDEX */
}
-
- ni++;
-
+
/*
- * For the current heap tuple, extract all the attributes
- * we use in this index, and note which are null.
+ * Since we just inted the tuples in the heap, we update its stats in
+ * pg_relation to guarantee that the planner takes advantage of the
+ * index we just created. UpdateStats() does a
+ * CommandinterIncrement(), which flushes changed entries from the
+ * system relcache. The act of constructing an index changes these
+ * heap and index tuples in the system catalogs, so they need to be
+ * flushed. We close them to guarantee that they will be.
*/
-
- for (i = 1; i <= natts; i++) {
- int attoff;
- bool attnull;
-
- /*
- * Offsets are from the start of the tuple, and are
- * zero-based; indices are one-based. The next call
- * returns i - 1. That's data hiding for you.
- */
-
- attoff = AttrNumberGetAttrOffset(i);
- /*
- d[attoff] = HeapTupleGetAttributeValue(htup, buffer,
- */
- d[attoff] = GetIndexValue(htup,
- hd,
- attoff,
- attnum,
- finfo,
- &attnull,
- buffer);
- nulls[attoff] = (attnull ? 'n' : ' ');
- }
-
- /* immediately compress keys to normalize */
- compvec = (bool *)palloc(sizeof(bool) * natts);
- for (i = 0; i < natts; i++) {
- gistcentryinit(&giststate, &tmpcentry, (char *)d[i],
- (Relation) NULL, (Page) NULL, (OffsetNumber) 0,
- -1 /* size is currently bogus */, TRUE);
- if (d[i] != (Datum)tmpcentry.pred && !(giststate.keytypbyval))
- compvec[i] = TRUE;
- else compvec[i] = FALSE;
- d[i] = (Datum)tmpcentry.pred;
+
+ hrelid = heap->rd_id;
+ irelid = index->rd_id;
+ heap_close(heap);
+ index_close(index);
+
+ UpdateStats(hrelid, nh, true);
+ UpdateStats(irelid, ni, false);
+
+ if (oldPred != NULL)
+ {
+ if (ni == nh)
+ pred = NULL;
+ UpdateIndexPredicate(irelid, oldPred, pred);
}
- /* form an index tuple and point it at the heap tuple */
- itup = index_formtuple(id, &d[0], nulls);
- itup->t_tid = htup->t_ctid;
-
- /*
- * Since we already have the index relation locked, we
- * call gistdoinsert directly. Normal access method calls
- * dispatch through gistinsert, which locks the relation
- * for write. This is the right thing to do if you're
- * inserting single tups, but not when you're initializing
- * the whole index at once.
- */
-
- res = gistdoinsert(index, itup, &giststate);
- for (i = 0; i < natts; i++)
- if (compvec[i] == TRUE) pfree((char *)d[i]);
- pfree(itup);
- pfree(res);
- pfree(compvec);
- }
-
- /* okay, all heap tuples are indexed */
- heap_endscan(scan);
- RelationUnsetLockForWrite(index);
-
- if (pred != NULL || oldPred != NULL) {
-#ifndef OMIT_PARTIAL_INDEX
- ExecDestroyTupleTable(tupleTable, true);
- pfree(econtext);
-#endif /* OMIT_PARTIAL_INDEX */
- }
-
- /*
- * Since we just inted the tuples in the heap, we update its
- * stats in pg_relation to guarantee that the planner takes
- * advantage of the index we just created. UpdateStats() does a
- * CommandinterIncrement(), which flushes changed entries from
- * the system relcache. The act of constructing an index changes
- * these heap and index tuples in the system catalogs, so they
- * need to be flushed. We close them to guarantee that they
- * will be.
- */
-
- hrelid = heap->rd_id;
- irelid = index->rd_id;
- heap_close(heap);
- index_close(index);
-
- UpdateStats(hrelid, nh, true);
- UpdateStats(irelid, ni, false);
-
- if (oldPred != NULL) {
- if (ni == nh) pred = NULL;
- UpdateIndexPredicate(irelid, oldPred, pred);
- }
-
- /* be tidy */
- pfree(nulls);
- pfree(d);
+ /* be tidy */
+ pfree(nulls);
+ pfree(d);
}
/*
- * gistinsert -- wrapper for GiST tuple insertion.
+ * gistinsert -- wrapper for GiST tuple insertion.
*
- * This is the public interface routine for tuple insertion in GiSTs.
- * It doesn't do any work; just locks the relation and passes the buck.
+ * This is the public interface routine for tuple insertion in GiSTs.
+ * It doesn't do any work; just locks the relation and passes the buck.
*/
InsertIndexResult
-gistinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
+gistinsert(Relation r, Datum * datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
{
- InsertIndexResult res;
- IndexTuple itup;
- GISTSTATE giststate;
- GISTENTRY tmpentry;
- int i;
- bool *compvec;
-
- initGISTstate(&giststate, r);
-
- /* immediately compress keys to normalize */
- compvec = (bool *)palloc(sizeof(bool) * r->rd_att->natts);
- for (i = 0; i < r->rd_att->natts; i++) {
- gistcentryinit(&giststate, &tmpentry, (char *)datum[i],
- (Relation) NULL, (Page) NULL, (OffsetNumber) 0,
- -1 /* size is currently bogus */, TRUE);
- if (datum[i] != (Datum)tmpentry.pred && !(giststate.keytypbyval))
- compvec[i] = TRUE;
- else compvec[i] = FALSE;
- datum[i] = (Datum)tmpentry.pred;
- }
- itup = index_formtuple(RelationGetTupleDescriptor(r), datum, nulls);
- itup->t_tid = *ht_ctid;
-
- RelationSetLockForWrite(r);
- res = gistdoinsert(r, itup, &giststate);
- for (i = 0; i < r->rd_att->natts; i++)
- if (compvec[i] == TRUE) pfree((char *)datum[i]);
- pfree(itup);
- pfree(compvec);
-
- /* XXX two-phase locking -- don't unlock the relation until EOT */
- return (res);
+ InsertIndexResult res;
+ IndexTuple itup;
+ GISTSTATE giststate;
+ GISTENTRY tmpentry;
+ int i;
+ bool *compvec;
+
+ initGISTstate(&giststate, r);
+
+ /* immediately compress keys to normalize */
+ compvec = (bool *) palloc(sizeof(bool) * r->rd_att->natts);
+ for (i = 0; i < r->rd_att->natts; i++)
+ {
+ gistcentryinit(&giststate, &tmpentry, (char *) datum[i],
+ (Relation) NULL, (Page) NULL, (OffsetNumber) 0,
+ -1 /* size is currently bogus */ , TRUE);
+ if (datum[i] != (Datum) tmpentry.pred && !(giststate.keytypbyval))
+ compvec[i] = TRUE;
+ else
+ compvec[i] = FALSE;
+ datum[i] = (Datum) tmpentry.pred;
+ }
+ itup = index_formtuple(RelationGetTupleDescriptor(r), datum, nulls);
+ itup->t_tid = *ht_ctid;
+
+ RelationSetLockForWrite(r);
+ res = gistdoinsert(r, itup, &giststate);
+ for (i = 0; i < r->rd_att->natts; i++)
+ if (compvec[i] == TRUE)
+ pfree((char *) datum[i]);
+ pfree(itup);
+ pfree(compvec);
+
+ /* XXX two-phase locking -- don't unlock the relation until EOT */
+ return (res);
}
/*
@@ -336,475 +373,509 @@ gistinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation
** that knowledge (some compression routines may want to fish around
** on the page, for example, or do something special for leaf nodes.)
*/
-static OffsetNumber
-gistPageAddItem(GISTSTATE *giststate,
- Relation r,
- Page page,
- Item item,
- Size size,
- OffsetNumber offsetNumber,
- ItemIdFlags flags,
- GISTENTRY *dentry,
- IndexTuple *newtup)
+static OffsetNumber
+gistPageAddItem(GISTSTATE * giststate,
+ Relation r,
+ Page page,
+ Item item,
+ Size size,
+ OffsetNumber offsetNumber,
+ ItemIdFlags flags,
+ GISTENTRY * dentry,
+ IndexTuple * newtup)
{
- GISTENTRY tmpcentry;
- IndexTuple itup = (IndexTuple)item;
-
- /* recompress the item given that we now know the exact page and
- offset for insertion */
- gistdentryinit(giststate, dentry,
- (((char *) itup) + sizeof(IndexTupleData)),
- (Relation)0, (Page)0, (OffsetNumber)InvalidOffsetNumber,
- IndexTupleSize(itup) - sizeof(IndexTupleData), FALSE);
- gistcentryinit(giststate, &tmpcentry, dentry->pred, r, page,
- offsetNumber, dentry->bytes, FALSE);
- *newtup = gist_tuple_replacekey(r, *dentry, itup);
- /* be tidy */
- if (tmpcentry.pred != dentry->pred
- && tmpcentry.pred != (((char *) itup) + sizeof(IndexTupleData)))
- pfree(tmpcentry.pred);
-
- return(PageAddItem(page, (Item) *newtup, IndexTupleSize(*newtup),
- offsetNumber, flags));
+ GISTENTRY tmpcentry;
+ IndexTuple itup = (IndexTuple) item;
+
+ /*
+ * recompress the item given that we now know the exact page and
+ * offset for insertion
+ */
+ gistdentryinit(giststate, dentry,
+ (((char *) itup) + sizeof(IndexTupleData)),
+ (Relation) 0, (Page) 0, (OffsetNumber) InvalidOffsetNumber,
+ IndexTupleSize(itup) - sizeof(IndexTupleData), FALSE);
+ gistcentryinit(giststate, &tmpcentry, dentry->pred, r, page,
+ offsetNumber, dentry->bytes, FALSE);
+ *newtup = gist_tuple_replacekey(r, *dentry, itup);
+ /* be tidy */
+ if (tmpcentry.pred != dentry->pred
+ && tmpcentry.pred != (((char *) itup) + sizeof(IndexTupleData)))
+ pfree(tmpcentry.pred);
+
+ return (PageAddItem(page, (Item) * newtup, IndexTupleSize(*newtup),
+ offsetNumber, flags));
}
-static InsertIndexResult
-gistdoinsert(Relation r,
- IndexTuple itup, /* itup contains compressed entry */
- GISTSTATE *giststate)
+static InsertIndexResult
+gistdoinsert(Relation r,
+ IndexTuple itup, /* itup contains compressed entry */
+ GISTSTATE * giststate)
{
- GISTENTRY tmpdentry;
- InsertIndexResult res;
- OffsetNumber l;
- GISTSTACK *stack;
- Buffer buffer;
- BlockNumber blk;
- Page page;
- OffsetNumber off;
- IndexTuple newtup;
-
- /* 3rd arg is ignored for now */
- blk = gistChooseSubtree(r, itup, 0, giststate, &stack, &buffer);
- page = (Page) BufferGetPage(buffer);
-
- if (gistnospace(page, itup)) {
- /* need to do a split */
- res = gistSplit(r, buffer, stack, itup, giststate);
+ GISTENTRY tmpdentry;
+ InsertIndexResult res;
+ OffsetNumber l;
+ GISTSTACK *stack;
+ Buffer buffer;
+ BlockNumber blk;
+ Page page;
+ OffsetNumber off;
+ IndexTuple newtup;
+
+ /* 3rd arg is ignored for now */
+ blk = gistChooseSubtree(r, itup, 0, giststate, &stack, &buffer);
+ page = (Page) BufferGetPage(buffer);
+
+ if (gistnospace(page, itup))
+ {
+ /* need to do a split */
+ res = gistSplit(r, buffer, stack, itup, giststate);
+ gistfreestack(stack);
+ WriteBuffer(buffer); /* don't forget to release buffer! */
+ return (res);
+ }
+
+ if (PageIsEmpty(page))
+ off = FirstOffsetNumber;
+ else
+ off = OffsetNumberNext(PageGetMaxOffsetNumber(page));
+
+ /* add the item and write the buffer */
+ l = gistPageAddItem(giststate, r, page, (Item) itup, IndexTupleSize(itup),
+ off, LP_USED, &tmpdentry, &newtup);
+ WriteBuffer(buffer);
+
+ /* now expand the page boundary in the parent to include the new child */
+ gistAdjustKeys(r, stack, blk, tmpdentry.pred, tmpdentry.bytes, giststate);
gistfreestack(stack);
- WriteBuffer(buffer); /* don't forget to release buffer! */
+
+ /* be tidy */
+ if (itup != newtup)
+ pfree(newtup);
+ if (tmpdentry.pred != (((char *) itup) + sizeof(IndexTupleData)))
+ pfree(tmpdentry.pred);
+
+ /* build and return an InsertIndexResult for this insertion */
+ res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
+ ItemPointerSet(&(res->pointerData), blk, l);
+
return (res);
- }
-
- if (PageIsEmpty(page))
- off = FirstOffsetNumber;
- else
- off = OffsetNumberNext(PageGetMaxOffsetNumber(page));
-
- /* add the item and write the buffer */
- l = gistPageAddItem(giststate, r, page, (Item) itup, IndexTupleSize(itup),
- off, LP_USED, &tmpdentry, &newtup);
- WriteBuffer(buffer);
-
- /* now expand the page boundary in the parent to include the new child */
- gistAdjustKeys(r, stack, blk, tmpdentry.pred, tmpdentry.bytes, giststate);
- gistfreestack(stack);
-
- /* be tidy */
- if (itup != newtup)
- pfree(newtup);
- if (tmpdentry.pred != (((char *) itup) + sizeof(IndexTupleData)))
- pfree(tmpdentry.pred);
-
- /* build and return an InsertIndexResult for this insertion */
- res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
- ItemPointerSet(&(res->pointerData), blk, l);
-
- return (res);
}
-static BlockNumber
-gistChooseSubtree(Relation r, IndexTuple itup, /* itup has compressed entry */
- int level,
- GISTSTATE *giststate,
- GISTSTACK **retstack /*out*/,
- Buffer *leafbuf /*out*/)
+static BlockNumber
+gistChooseSubtree(Relation r, IndexTuple itup, /* itup has compressed
+ * entry */
+ int level,
+ GISTSTATE * giststate,
+ GISTSTACK ** retstack /* out */ ,
+ Buffer * leafbuf /* out */ )
{
- Buffer buffer;
- BlockNumber blk;
- GISTSTACK *stack;
- Page page;
- GISTPageOpaque opaque;
- IndexTuple which;
-
- blk = GISTP_ROOT;
- buffer = InvalidBuffer;
- stack = (GISTSTACK *) NULL;
-
- do {
- /* let go of current buffer before getting next */
- if (buffer != InvalidBuffer)
- ReleaseBuffer(buffer);
-
- /* get next buffer */
- buffer = ReadBuffer(r, blk);
- page = (Page) BufferGetPage(buffer);
-
- opaque = (GISTPageOpaque) PageGetSpecialPointer(page);
- if (!(opaque->flags & F_LEAF)) {
- GISTSTACK *n;
- ItemId iid;
-
- n = (GISTSTACK *) palloc(sizeof(GISTSTACK));
- n->gs_parent = stack;
- n->gs_blk = blk;
- n->gs_child = gistchoose(r, page, itup, giststate);
- stack = n;
-
- iid = PageGetItemId(page, n->gs_child);
- which = (IndexTuple) PageGetItem(page, iid);
- blk = ItemPointerGetBlockNumber(&(which->t_tid));
- }
- } while (!(opaque->flags & F_LEAF));
-
- *retstack = stack;
- *leafbuf = buffer;
-
- return(blk);
+ Buffer buffer;
+ BlockNumber blk;
+ GISTSTACK *stack;
+ Page page;
+ GISTPageOpaque opaque;
+ IndexTuple which;
+
+ blk = GISTP_ROOT;
+ buffer = InvalidBuffer;
+ stack = (GISTSTACK *) NULL;
+
+ do
+ {
+ /* let go of current buffer before getting next */
+ if (buffer != InvalidBuffer)
+ ReleaseBuffer(buffer);
+
+ /* get next buffer */
+ buffer = ReadBuffer(r, blk);
+ page = (Page) BufferGetPage(buffer);
+
+ opaque = (GISTPageOpaque) PageGetSpecialPointer(page);
+ if (!(opaque->flags & F_LEAF))
+ {
+ GISTSTACK *n;
+ ItemId iid;
+
+ n = (GISTSTACK *) palloc(sizeof(GISTSTACK));
+ n->gs_parent = stack;
+ n->gs_blk = blk;
+ n->gs_child = gistchoose(r, page, itup, giststate);
+ stack = n;
+
+ iid = PageGetItemId(page, n->gs_child);
+ which = (IndexTuple) PageGetItem(page, iid);
+ blk = ItemPointerGetBlockNumber(&(which->t_tid));
+ }
+ } while (!(opaque->flags & F_LEAF));
+
+ *retstack = stack;
+ *leafbuf = buffer;
+
+ return (blk);
}
static void
gistAdjustKeys(Relation r,
- GISTSTACK *stk,
- BlockNumber blk,
- char *datum, /* datum is uncompressed */
- int att_size,
- GISTSTATE *giststate)
+ GISTSTACK * stk,
+ BlockNumber blk,
+ char *datum, /* datum is uncompressed */
+ int att_size,
+ GISTSTATE * giststate)
{
- char *oldud;
- Page p;
- Buffer b;
- bool result;
- bytea *evec;
- GISTENTRY centry, *ev0p, *ev1p;
- int size, datumsize;
- IndexTuple tid;
-
- if (stk == (GISTSTACK *) NULL)
- return;
-
- b = ReadBuffer(r, stk->gs_blk);
- p = BufferGetPage(b);
-
- oldud = (char *) PageGetItem(p, PageGetItemId(p, stk->gs_child));
- tid = (IndexTuple) oldud;
- size = IndexTupleSize((IndexTuple)oldud) - sizeof(IndexTupleData);
- oldud += sizeof(IndexTupleData);
-
- evec = (bytea *) palloc(2*sizeof(GISTENTRY) + VARHDRSZ);
- VARSIZE(evec) = 2*sizeof(GISTENTRY) + VARHDRSZ;
-
- /* insert decompressed oldud into entry vector */
- gistdentryinit(giststate, &((GISTENTRY *)VARDATA(evec))[0],
- oldud, r, p, stk->gs_child,
- size, FALSE);
- ev0p = &((GISTENTRY *)VARDATA(evec))[0];
-
- /* insert datum entry into entry vector */
- gistentryinit(((GISTENTRY *)VARDATA(evec))[1], datum,
- (Relation)NULL,(Page)NULL,(OffsetNumber)0, att_size, FALSE);
- ev1p = &((GISTENTRY *)VARDATA(evec))[1];
-
- /* form union of decompressed entries */
- datum = (char *) (giststate->unionFn)(evec, &datumsize);
-
- /* did union leave decompressed version of oldud unchanged? */
- (giststate->equalFn)(ev0p->pred, datum, &result);
- if (!result) {
- TupleDesc td = RelationGetTupleDescriptor(r);
-
- /* compress datum for storage on page */
- gistcentryinit(giststate, &centry, datum, ev0p->rel, ev0p->page,
- ev0p->offset, datumsize, FALSE);
- if (td->attrs[0]->attlen >= 0) {
- memmove(oldud, centry.pred, att_size);
- gistAdjustKeys(r, stk->gs_parent, stk->gs_blk, datum, att_size,
- giststate);
+ char *oldud;
+ Page p;
+ Buffer b;
+ bool result;
+ bytea *evec;
+ GISTENTRY centry,
+ *ev0p,
+ *ev1p;
+ int size,
+ datumsize;
+ IndexTuple tid;
+
+ if (stk == (GISTSTACK *) NULL)
+ return;
+
+ b = ReadBuffer(r, stk->gs_blk);
+ p = BufferGetPage(b);
+
+ oldud = (char *) PageGetItem(p, PageGetItemId(p, stk->gs_child));
+ tid = (IndexTuple) oldud;
+ size = IndexTupleSize((IndexTuple) oldud) - sizeof(IndexTupleData);
+ oldud += sizeof(IndexTupleData);
+
+ evec = (bytea *) palloc(2 * sizeof(GISTENTRY) + VARHDRSZ);
+ VARSIZE(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ;
+
+ /* insert decompressed oldud into entry vector */
+ gistdentryinit(giststate, &((GISTENTRY *) VARDATA(evec))[0],
+ oldud, r, p, stk->gs_child,
+ size, FALSE);
+ ev0p = &((GISTENTRY *) VARDATA(evec))[0];
+
+ /* insert datum entry into entry vector */
+ gistentryinit(((GISTENTRY *) VARDATA(evec))[1], datum,
+ (Relation) NULL, (Page) NULL, (OffsetNumber) 0, att_size, FALSE);
+ ev1p = &((GISTENTRY *) VARDATA(evec))[1];
+
+ /* form union of decompressed entries */
+ datum = (char *) (giststate->unionFn) (evec, &datumsize);
+
+ /* did union leave decompressed version of oldud unchanged? */
+ (giststate->equalFn) (ev0p->pred, datum, &result);
+ if (!result)
+ {
+ TupleDesc td = RelationGetTupleDescriptor(r);
+
+ /* compress datum for storage on page */
+ gistcentryinit(giststate, &centry, datum, ev0p->rel, ev0p->page,
+ ev0p->offset, datumsize, FALSE);
+ if (td->attrs[0]->attlen >= 0)
+ {
+ memmove(oldud, centry.pred, att_size);
+ gistAdjustKeys(r, stk->gs_parent, stk->gs_blk, datum, att_size,
+ giststate);
+ }
+ else if (VARSIZE(centry.pred) == VARSIZE(oldud))
+ {
+ memmove(oldud, centry.pred, VARSIZE(centry.pred));
+ gistAdjustKeys(r, stk->gs_parent, stk->gs_blk, datum, att_size,
+ giststate);
+ }
+ else
+ {
+
+ /*
+ * * new datum is not the same size as the old. * We have to
+ * delete the old entry and insert the new * one. Note that
+ * this may cause a split here!
+ */
+ IndexTuple newtup;
+ ItemPointerData oldtid;
+ char *isnull;
+ TupleDesc tupDesc;
+ InsertIndexResult res;
+
+ /* delete old tuple */
+ ItemPointerSet(&oldtid, stk->gs_blk, stk->gs_child);
+ gistdelete(r, (ItemPointer) & oldtid);
+
+ /* generate and insert new tuple */
+ tupDesc = r->rd_att;
+ isnull = (char *) palloc(r->rd_rel->relnatts);
+ memset(isnull, ' ', r->rd_rel->relnatts);
+ newtup = (IndexTuple) index_formtuple(tupDesc,
+ (Datum *) & centry.pred, isnull);
+ pfree(isnull);
+ /* set pointer in new tuple to point to current child */
+ ItemPointerSet(&oldtid, blk, 1);
+ newtup->t_tid = oldtid;
+
+ /* inserting the new entry also adjust keys above */
+ res = gistentryinsert(r, stk, newtup, giststate);
+
+ /* in stack, set info to point to new tuple */
+ stk->gs_blk = ItemPointerGetBlockNumber(&(res->pointerData));
+ stk->gs_child = ItemPointerGetOffsetNumber(&(res->pointerData));
+
+ pfree(res);
+ }
+ WriteBuffer(b);
+
+ if (centry.pred != datum)
+ pfree(datum);
}
- else if (VARSIZE(centry.pred) == VARSIZE(oldud)) {
- memmove(oldud, centry.pred, VARSIZE(centry.pred));
- gistAdjustKeys(r, stk->gs_parent, stk->gs_blk, datum, att_size,
- giststate);
+ else
+ {
+ ReleaseBuffer(b);
}
- else {
- /*
- ** new datum is not the same size as the old.
- ** We have to delete the old entry and insert the new
- ** one. Note that this may cause a split here!
- */
- IndexTuple newtup;
- ItemPointerData oldtid;
- char *isnull;
- TupleDesc tupDesc;
- InsertIndexResult res;
-
- /* delete old tuple */
- ItemPointerSet(&oldtid, stk->gs_blk, stk->gs_child);
- gistdelete(r, (ItemPointer)&oldtid);
-
- /* generate and insert new tuple */
- tupDesc = r->rd_att;
- isnull = (char *) palloc(r->rd_rel->relnatts);
- memset(isnull, ' ', r->rd_rel->relnatts);
- newtup = (IndexTuple) index_formtuple(tupDesc,
- (Datum *) &centry.pred, isnull);
- pfree(isnull);
- /* set pointer in new tuple to point to current child */
- ItemPointerSet(&oldtid, blk, 1);
- newtup->t_tid = oldtid;
-
- /* inserting the new entry also adjust keys above */
- res = gistentryinsert(r, stk, newtup, giststate);
-
- /* in stack, set info to point to new tuple */
- stk->gs_blk = ItemPointerGetBlockNumber(&(res->pointerData));
- stk->gs_child = ItemPointerGetOffsetNumber(&(res->pointerData));
-
- pfree(res);
- }
- WriteBuffer(b);
-
- if (centry.pred != datum)
- pfree(datum);
- }
- else {
- ReleaseBuffer(b);
- }
- pfree(evec);
+ pfree(evec);
}
/*
- * gistSplit -- split a page in the tree.
+ * gistSplit -- split a page in the tree.
*
*/
-static InsertIndexResult
+static InsertIndexResult
gistSplit(Relation r,
- Buffer buffer,
- GISTSTACK *stack,
- IndexTuple itup, /* contains compressed entry */
- GISTSTATE *giststate)
+ Buffer buffer,
+ GISTSTACK * stack,
+ IndexTuple itup, /* contains compressed entry */
+ GISTSTATE * giststate)
{
- Page p;
- Buffer leftbuf, rightbuf;
- Page left, right;
- ItemId itemid;
- IndexTuple item;
- IndexTuple ltup, rtup, newtup;
- OffsetNumber maxoff;
- OffsetNumber i;
- OffsetNumber leftoff, rightoff;
- BlockNumber lbknum, rbknum;
- BlockNumber bufblock;
- GISTPageOpaque opaque;
- int blank;
- InsertIndexResult res;
- char *isnull;
- GIST_SPLITVEC v;
- TupleDesc tupDesc;
- bytea *entryvec;
- bool *decompvec;
- IndexTuple item_1;
- GISTENTRY tmpdentry, tmpentry;
-
- isnull = (char *) palloc(r->rd_rel->relnatts);
- for (blank = 0; blank < r->rd_rel->relnatts; blank++)
- isnull[blank] = ' ';
- p = (Page) BufferGetPage(buffer);
- opaque = (GISTPageOpaque) PageGetSpecialPointer(p);
-
-
- /*
- * The root of the tree is the first block in the relation. If
- * we're about to split the root, we need to do some hocus-pocus
- * to enforce this guarantee.
- */
-
- if (BufferGetBlockNumber(buffer) == GISTP_ROOT) {
- leftbuf = ReadBuffer(r, P_NEW);
- GISTInitBuffer(leftbuf, opaque->flags);
- lbknum = BufferGetBlockNumber(leftbuf);
- left = (Page) BufferGetPage(leftbuf);
- } else {
- leftbuf = buffer;
- IncrBufferRefCount(buffer);
- lbknum = BufferGetBlockNumber(buffer);
- left = (Page) PageGetTempPage(p, sizeof(GISTPageOpaqueData));
- }
-
- rightbuf = ReadBuffer(r, P_NEW);
- GISTInitBuffer(rightbuf, opaque->flags);
- rbknum = BufferGetBlockNumber(rightbuf);
- right = (Page) BufferGetPage(rightbuf);
-
- /* generate the item array */
- maxoff = PageGetMaxOffsetNumber(p);
- entryvec = (bytea *)palloc(VARHDRSZ + (maxoff + 2) * sizeof(GISTENTRY));
- decompvec = (bool *)palloc(VARHDRSZ + (maxoff + 2) * sizeof(bool));
- for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
- item_1 = (IndexTuple) PageGetItem(p, PageGetItemId(p, i));
- gistdentryinit(giststate, &((GISTENTRY *)VARDATA(entryvec))[i],
- (((char *) item_1) + sizeof(IndexTupleData)),
- r, p, i,
- IndexTupleSize(item_1) - sizeof(IndexTupleData), FALSE);
- if ((char *)(((GISTENTRY *)VARDATA(entryvec))[i].pred)
- == (((char *) item_1) + sizeof(IndexTupleData)))
- decompvec[i] = FALSE;
- else decompvec[i] = TRUE;
- }
-
- /* add the new datum as the last entry */
- gistdentryinit(giststate, &(((GISTENTRY *)VARDATA(entryvec))[maxoff+1]),
- (((char *) itup) + sizeof(IndexTupleData)),
- (Relation)NULL, (Page)NULL,
- (OffsetNumber)0, tmpentry.bytes, FALSE);
- if ((char *)(((GISTENTRY *)VARDATA(entryvec))[maxoff+1]).pred !=
- (((char *) itup) + sizeof(IndexTupleData)))
- decompvec[maxoff+1] = TRUE;
- else decompvec[maxoff+1] = FALSE;
-
- VARSIZE(entryvec) = (maxoff + 2) * sizeof(GISTENTRY) + VARHDRSZ;
-
- /* now let the user-defined picksplit function set up the split vector */
- (giststate->picksplitFn)(entryvec, &v);
-
- /* compress ldatum and rdatum */
- gistcentryinit(giststate, &tmpentry, v.spl_ldatum, (Relation)NULL,
- (Page)NULL, (OffsetNumber)0,
- ((GISTENTRY *)VARDATA(entryvec))[i].bytes, FALSE);
- if (v.spl_ldatum != tmpentry.pred)
- pfree(v.spl_ldatum);
- v.spl_ldatum = tmpentry.pred;
-
- gistcentryinit(giststate, &tmpentry, v.spl_rdatum, (Relation)NULL,
- (Page)NULL, (OffsetNumber)0,
- ((GISTENTRY *)VARDATA(entryvec))[i].bytes, FALSE);
- if (v.spl_rdatum != tmpentry.pred)
- pfree(v.spl_rdatum);
- v.spl_rdatum = tmpentry.pred;
-
- /* clean up the entry vector: its preds need to be deleted, too */
- for (i = FirstOffsetNumber; i <= maxoff+1; i = OffsetNumberNext(i))
- if (decompvec[i])
- pfree(((GISTENTRY *)VARDATA(entryvec))[i].pred);
- pfree(entryvec);
- pfree(decompvec);
-
- leftoff = rightoff = FirstOffsetNumber;
- maxoff = PageGetMaxOffsetNumber(p);
- for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
- itemid = PageGetItemId(p, i);
- item = (IndexTuple) PageGetItem(p, itemid);
-
- if (i == *(v.spl_left)) {
- gistPageAddItem(giststate, r, left, (Item) item,
- IndexTupleSize(item),
- leftoff, LP_USED, &tmpdentry, &newtup);
- leftoff = OffsetNumberNext(leftoff);
- v.spl_left++; /* advance in left split vector */
- /* be tidy */
- if (tmpdentry.pred != (((char *) item) + sizeof(IndexTupleData)))
- pfree(tmpdentry.pred);
- if ((IndexTuple)item != newtup)
- pfree(newtup);
- }
- else {
- gistPageAddItem(giststate, r, right, (Item) item,
- IndexTupleSize(item),
- rightoff, LP_USED, &tmpdentry, &newtup);
- rightoff = OffsetNumberNext(rightoff);
- v.spl_right++; /* advance in right split vector */
- /* be tidy */
- if (tmpdentry.pred != (((char *) item) + sizeof(IndexTupleData)))
- pfree(tmpdentry.pred);
- if (item != newtup)
- pfree(newtup);
+ Page p;
+ Buffer leftbuf,
+ rightbuf;
+ Page left,
+ right;
+ ItemId itemid;
+ IndexTuple item;
+ IndexTuple ltup,
+ rtup,
+ newtup;
+ OffsetNumber maxoff;
+ OffsetNumber i;
+ OffsetNumber leftoff,
+ rightoff;
+ BlockNumber lbknum,
+ rbknum;
+ BlockNumber bufblock;
+ GISTPageOpaque opaque;
+ int blank;
+ InsertIndexResult res;
+ char *isnull;
+ GIST_SPLITVEC v;
+ TupleDesc tupDesc;
+ bytea *entryvec;
+ bool *decompvec;
+ IndexTuple item_1;
+ GISTENTRY tmpdentry,
+ tmpentry;
+
+ isnull = (char *) palloc(r->rd_rel->relnatts);
+ for (blank = 0; blank < r->rd_rel->relnatts; blank++)
+ isnull[blank] = ' ';
+ p = (Page) BufferGetPage(buffer);
+ opaque = (GISTPageOpaque) PageGetSpecialPointer(p);
+
+
+ /*
+ * The root of the tree is the first block in the relation. If we're
+ * about to split the root, we need to do some hocus-pocus to enforce
+ * this guarantee.
+ */
+
+ if (BufferGetBlockNumber(buffer) == GISTP_ROOT)
+ {
+ leftbuf = ReadBuffer(r, P_NEW);
+ GISTInitBuffer(leftbuf, opaque->flags);
+ lbknum = BufferGetBlockNumber(leftbuf);
+ left = (Page) BufferGetPage(leftbuf);
}
- }
-
- /* build an InsertIndexResult for this insertion */
- res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
-
- /* now insert the new index tuple */
- if (*(v.spl_left) != FirstOffsetNumber) {
- gistPageAddItem(giststate, r, left, (Item) itup,
- IndexTupleSize(itup),
- leftoff, LP_USED, &tmpdentry, &newtup);
- leftoff = OffsetNumberNext(leftoff);
- ItemPointerSet(&(res->pointerData), lbknum, leftoff);
- /* be tidy */
- if (tmpdentry.pred != (((char *) itup) + sizeof(IndexTupleData)))
- pfree(tmpdentry.pred);
- if (itup != newtup)
- pfree(newtup);
- } else {
- gistPageAddItem(giststate, r, right, (Item) itup,
- IndexTupleSize(itup),
- rightoff, LP_USED, &tmpdentry, &newtup);
- rightoff = OffsetNumberNext(rightoff);
- ItemPointerSet(&(res->pointerData), rbknum, rightoff);
- /* be tidy */
- if (tmpdentry.pred != (((char *) itup) + sizeof(IndexTupleData)))
- pfree(tmpdentry.pred);
- if (itup != newtup)
- pfree(newtup);
- }
-
- if ((bufblock = BufferGetBlockNumber(buffer)) != GISTP_ROOT) {
- PageRestoreTempPage(left, p);
- }
- WriteBuffer(leftbuf);
- WriteBuffer(rightbuf);
-
- /*
- * Okay, the page is split. We have three things left to do:
- *
- * 1) Adjust any active scans on this index to cope with changes
- * we introduced in its structure by splitting this page.
- *
- * 2) "Tighten" the bounding box of the pointer to the left
- * page in the parent node in the tree, if any. Since we
- * moved a bunch of stuff off the left page, we expect it
- * to get smaller. This happens in the internal insertion
- * routine.
- *
- * 3) Insert a pointer to the right page in the parent. This
- * may cause the parent to split. If it does, we need to
- * repeat steps one and two for each split node in the tree.
- */
-
- /* adjust active scans */
- gistadjscans(r, GISTOP_SPLIT, bufblock, FirstOffsetNumber);
-
- tupDesc = r->rd_att;
-
- ltup = (IndexTuple) index_formtuple(tupDesc,
- (Datum *) &(v.spl_ldatum), isnull);
- rtup = (IndexTuple) index_formtuple(tupDesc,
- (Datum *) &(v.spl_rdatum), isnull);
- pfree(isnull);
-
- /* set pointers to new child pages in the internal index tuples */
- ItemPointerSet(&(ltup->t_tid), lbknum, 1);
- ItemPointerSet(&(rtup->t_tid), rbknum, 1);
-
- gistintinsert(r, stack, ltup, rtup, giststate);
-
- pfree(ltup);
- pfree(rtup);
-
- return (res);
+ else
+ {
+ leftbuf = buffer;
+ IncrBufferRefCount(buffer);
+ lbknum = BufferGetBlockNumber(buffer);
+ left = (Page) PageGetTempPage(p, sizeof(GISTPageOpaqueData));
+ }
+
+ rightbuf = ReadBuffer(r, P_NEW);
+ GISTInitBuffer(rightbuf, opaque->flags);
+ rbknum = BufferGetBlockNumber(rightbuf);
+ right = (Page) BufferGetPage(rightbuf);
+
+ /* generate the item array */
+ maxoff = PageGetMaxOffsetNumber(p);
+ entryvec = (bytea *) palloc(VARHDRSZ + (maxoff + 2) * sizeof(GISTENTRY));
+ decompvec = (bool *) palloc(VARHDRSZ + (maxoff + 2) * sizeof(bool));
+ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+ {
+ item_1 = (IndexTuple) PageGetItem(p, PageGetItemId(p, i));
+ gistdentryinit(giststate, &((GISTENTRY *) VARDATA(entryvec))[i],
+ (((char *) item_1) + sizeof(IndexTupleData)),
+ r, p, i,
+ IndexTupleSize(item_1) - sizeof(IndexTupleData), FALSE);
+ if ((char *) (((GISTENTRY *) VARDATA(entryvec))[i].pred)
+ == (((char *) item_1) + sizeof(IndexTupleData)))
+ decompvec[i] = FALSE;
+ else
+ decompvec[i] = TRUE;
+ }
+
+ /* add the new datum as the last entry */
+ gistdentryinit(giststate, &(((GISTENTRY *) VARDATA(entryvec))[maxoff + 1]),
+ (((char *) itup) + sizeof(IndexTupleData)),
+ (Relation) NULL, (Page) NULL,
+ (OffsetNumber) 0, tmpentry.bytes, FALSE);
+ if ((char *) (((GISTENTRY *) VARDATA(entryvec))[maxoff + 1]).pred !=
+ (((char *) itup) + sizeof(IndexTupleData)))
+ decompvec[maxoff + 1] = TRUE;
+ else
+ decompvec[maxoff + 1] = FALSE;
+
+ VARSIZE(entryvec) = (maxoff + 2) * sizeof(GISTENTRY) + VARHDRSZ;
+
+ /* now let the user-defined picksplit function set up the split vector */
+ (giststate->picksplitFn) (entryvec, &v);
+
+ /* compress ldatum and rdatum */
+ gistcentryinit(giststate, &tmpentry, v.spl_ldatum, (Relation) NULL,
+ (Page) NULL, (OffsetNumber) 0,
+ ((GISTENTRY *) VARDATA(entryvec))[i].bytes, FALSE);
+ if (v.spl_ldatum != tmpentry.pred)
+ pfree(v.spl_ldatum);
+ v.spl_ldatum = tmpentry.pred;
+
+ gistcentryinit(giststate, &tmpentry, v.spl_rdatum, (Relation) NULL,
+ (Page) NULL, (OffsetNumber) 0,
+ ((GISTENTRY *) VARDATA(entryvec))[i].bytes, FALSE);
+ if (v.spl_rdatum != tmpentry.pred)
+ pfree(v.spl_rdatum);
+ v.spl_rdatum = tmpentry.pred;
+
+ /* clean up the entry vector: its preds need to be deleted, too */
+ for (i = FirstOffsetNumber; i <= maxoff + 1; i = OffsetNumberNext(i))
+ if (decompvec[i])
+ pfree(((GISTENTRY *) VARDATA(entryvec))[i].pred);
+ pfree(entryvec);
+ pfree(decompvec);
+
+ leftoff = rightoff = FirstOffsetNumber;
+ maxoff = PageGetMaxOffsetNumber(p);
+ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+ {
+ itemid = PageGetItemId(p, i);
+ item = (IndexTuple) PageGetItem(p, itemid);
+
+ if (i == *(v.spl_left))
+ {
+ gistPageAddItem(giststate, r, left, (Item) item,
+ IndexTupleSize(item),
+ leftoff, LP_USED, &tmpdentry, &newtup);
+ leftoff = OffsetNumberNext(leftoff);
+ v.spl_left++; /* advance in left split vector */
+ /* be tidy */
+ if (tmpdentry.pred != (((char *) item) + sizeof(IndexTupleData)))
+ pfree(tmpdentry.pred);
+ if ((IndexTuple) item != newtup)
+ pfree(newtup);
+ }
+ else
+ {
+ gistPageAddItem(giststate, r, right, (Item) item,
+ IndexTupleSize(item),
+ rightoff, LP_USED, &tmpdentry, &newtup);
+ rightoff = OffsetNumberNext(rightoff);
+ v.spl_right++; /* advance in right split vector */
+ /* be tidy */
+ if (tmpdentry.pred != (((char *) item) + sizeof(IndexTupleData)))
+ pfree(tmpdentry.pred);
+ if (item != newtup)
+ pfree(newtup);
+ }
+ }
+
+ /* build an InsertIndexResult for this insertion */
+ res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
+
+ /* now insert the new index tuple */
+ if (*(v.spl_left) != FirstOffsetNumber)
+ {
+ gistPageAddItem(giststate, r, left, (Item) itup,
+ IndexTupleSize(itup),
+ leftoff, LP_USED, &tmpdentry, &newtup);
+ leftoff = OffsetNumberNext(leftoff);
+ ItemPointerSet(&(res->pointerData), lbknum, leftoff);
+ /* be tidy */
+ if (tmpdentry.pred != (((char *) itup) + sizeof(IndexTupleData)))
+ pfree(tmpdentry.pred);
+ if (itup != newtup)
+ pfree(newtup);
+ }
+ else
+ {
+ gistPageAddItem(giststate, r, right, (Item) itup,
+ IndexTupleSize(itup),
+ rightoff, LP_USED, &tmpdentry, &newtup);
+ rightoff = OffsetNumberNext(rightoff);
+ ItemPointerSet(&(res->pointerData), rbknum, rightoff);
+ /* be tidy */
+ if (tmpdentry.pred != (((char *) itup) + sizeof(IndexTupleData)))
+ pfree(tmpdentry.pred);
+ if (itup != newtup)
+ pfree(newtup);
+ }
+
+ if ((bufblock = BufferGetBlockNumber(buffer)) != GISTP_ROOT)
+ {
+ PageRestoreTempPage(left, p);
+ }
+ WriteBuffer(leftbuf);
+ WriteBuffer(rightbuf);
+
+ /*
+ * Okay, the page is split. We have three things left to do:
+ *
+ * 1) Adjust any active scans on this index to cope with changes we
+ * introduced in its structure by splitting this page.
+ *
+ * 2) "Tighten" the bounding box of the pointer to the left page in the
+ * parent node in the tree, if any. Since we moved a bunch of stuff
+ * off the left page, we expect it to get smaller. This happens in
+ * the internal insertion routine.
+ *
+ * 3) Insert a pointer to the right page in the parent. This may cause
+ * the parent to split. If it does, we need to repeat steps one and
+ * two for each split node in the tree.
+ */
+
+ /* adjust active scans */
+ gistadjscans(r, GISTOP_SPLIT, bufblock, FirstOffsetNumber);
+
+ tupDesc = r->rd_att;
+
+ ltup = (IndexTuple) index_formtuple(tupDesc,
+ (Datum *) & (v.spl_ldatum), isnull);
+ rtup = (IndexTuple) index_formtuple(tupDesc,
+ (Datum *) & (v.spl_rdatum), isnull);
+ pfree(isnull);
+
+ /* set pointers to new child pages in the internal index tuples */
+ ItemPointerSet(&(ltup->t_tid), lbknum, 1);
+ ItemPointerSet(&(rtup->t_tid), rbknum, 1);
+
+ gistintinsert(r, stack, ltup, rtup, giststate);
+
+ pfree(ltup);
+ pfree(rtup);
+
+ return (res);
}
/*
@@ -813,22 +884,23 @@ gistSplit(Relation r,
*/
static void
gistintinsert(Relation r,
- GISTSTACK *stk,
- IndexTuple ltup, /* new version of entry for old page */
- IndexTuple rtup, /* entry for new page */
- GISTSTATE *giststate)
+ GISTSTACK * stk,
+ IndexTuple ltup, /* new version of entry for old page */
+ IndexTuple rtup, /* entry for new page */
+ GISTSTATE * giststate)
{
- ItemPointerData ltid;
+ ItemPointerData ltid;
- if (stk == (GISTSTACK *) NULL) {
- gistnewroot(giststate, r, ltup, rtup);
- return;
- }
-
- /* remove old left pointer, insert the 2 new entries */
- ItemPointerSet(&ltid, stk->gs_blk, stk->gs_child);
- gistdelete(r, (ItemPointer)&ltid);
- gistentryinserttwo(r, stk, ltup, rtup, giststate);
+ if (stk == (GISTSTACK *) NULL)
+ {
+ gistnewroot(giststate, r, ltup, rtup);
+ return;
+ }
+
+ /* remove old left pointer, insert the 2 new entries */
+ ItemPointerSet(&ltid, stk->gs_blk, stk->gs_child);
+ gistdelete(r, (ItemPointer) & ltid);
+ gistentryinserttwo(r, stk, ltup, rtup, giststate);
}
@@ -836,280 +908,299 @@ gistintinsert(Relation r,
** Insert two entries onto one page, handling a split for either one!
*/
static void
-gistentryinserttwo(Relation r, GISTSTACK *stk, IndexTuple ltup,
- IndexTuple rtup, GISTSTATE *giststate)
+gistentryinserttwo(Relation r, GISTSTACK * stk, IndexTuple ltup,
+ IndexTuple rtup, GISTSTATE * giststate)
{
- Buffer b;
- Page p;
- InsertIndexResult res;
- GISTENTRY tmpentry;
- IndexTuple newtup;
-
- b = ReadBuffer(r, stk->gs_blk);
- p = BufferGetPage(b);
-
- if (gistnospace(p, ltup)) {
- res = gistSplit(r, b, stk->gs_parent, ltup, giststate);
- WriteBuffer(b); /* don't forget to release buffer! - 01/31/94 */
- pfree(res);
- gistdoinsert(r, rtup, giststate);
- } else {
- gistPageAddItem(giststate, r, p, (Item)ltup,
- IndexTupleSize(ltup), InvalidOffsetNumber,
- LP_USED, &tmpentry, &newtup);
- WriteBuffer(b);
- gistAdjustKeys(r, stk->gs_parent, stk->gs_blk, tmpentry.pred,
- tmpentry.bytes, giststate);
- /* be tidy */
- if (tmpentry.pred != (((char *) ltup) + sizeof(IndexTupleData)))
- pfree(tmpentry.pred);
- if (ltup != newtup)
- pfree(newtup);
- gistentryinsert(r, stk, rtup, giststate);
- }
-}
+ Buffer b;
+ Page p;
+ InsertIndexResult res;
+ GISTENTRY tmpentry;
+ IndexTuple newtup;
+
+ b = ReadBuffer(r, stk->gs_blk);
+ p = BufferGetPage(b);
+
+ if (gistnospace(p, ltup))
+ {
+ res = gistSplit(r, b, stk->gs_parent, ltup, giststate);
+ WriteBuffer(b); /* don't forget to release buffer! -
+ * 01/31/94 */
+ pfree(res);
+ gistdoinsert(r, rtup, giststate);
+ }
+ else
+ {
+ gistPageAddItem(giststate, r, p, (Item) ltup,
+ IndexTupleSize(ltup), InvalidOffsetNumber,
+ LP_USED, &tmpentry, &newtup);
+ WriteBuffer(b);
+ gistAdjustKeys(r, stk->gs_parent, stk->gs_blk, tmpentry.pred,
+ tmpentry.bytes, giststate);
+ /* be tidy */
+ if (tmpentry.pred != (((char *) ltup) + sizeof(IndexTupleData)))
+ pfree(tmpentry.pred);
+ if (ltup != newtup)
+ pfree(newtup);
+ gistentryinsert(r, stk, rtup, giststate);
+ }
+}
/*
** Insert an entry onto a page
*/
-static InsertIndexResult
-gistentryinsert(Relation r, GISTSTACK *stk, IndexTuple tup,
- GISTSTATE *giststate)
+static InsertIndexResult
+gistentryinsert(Relation r, GISTSTACK * stk, IndexTuple tup,
+ GISTSTATE * giststate)
{
- Buffer b;
- Page p;
- InsertIndexResult res;
- OffsetNumber off;
- GISTENTRY tmpentry;
- IndexTuple newtup;
-
- b = ReadBuffer(r, stk->gs_blk);
- p = BufferGetPage(b);
-
- if (gistnospace(p, tup)) {
- res = gistSplit(r, b, stk->gs_parent, tup, giststate);
- WriteBuffer(b); /* don't forget to release buffer! - 01/31/94 */
- return(res);
- }
- else {
- res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
- off = gistPageAddItem(giststate, r, p, (Item) tup, IndexTupleSize(tup),
- InvalidOffsetNumber, LP_USED, &tmpentry, &newtup);
- WriteBuffer(b);
- ItemPointerSet(&(res->pointerData), stk->gs_blk, off);
- gistAdjustKeys(r, stk->gs_parent, stk->gs_blk, tmpentry.pred,
- tmpentry.bytes, giststate);
- /* be tidy */
- if (tmpentry.pred != (((char *) tup) + sizeof(IndexTupleData)))
- pfree(tmpentry.pred);
- if (tup != newtup)
- pfree(newtup);
- return(res);
- }
-}
+ Buffer b;
+ Page p;
+ InsertIndexResult res;
+ OffsetNumber off;
+ GISTENTRY tmpentry;
+ IndexTuple newtup;
+
+ b = ReadBuffer(r, stk->gs_blk);
+ p = BufferGetPage(b);
+
+ if (gistnospace(p, tup))
+ {
+ res = gistSplit(r, b, stk->gs_parent, tup, giststate);
+ WriteBuffer(b); /* don't forget to release buffer! -
+ * 01/31/94 */
+ return (res);
+ }
+ else
+ {
+ res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
+ off = gistPageAddItem(giststate, r, p, (Item) tup, IndexTupleSize(tup),
+ InvalidOffsetNumber, LP_USED, &tmpentry, &newtup);
+ WriteBuffer(b);
+ ItemPointerSet(&(res->pointerData), stk->gs_blk, off);
+ gistAdjustKeys(r, stk->gs_parent, stk->gs_blk, tmpentry.pred,
+ tmpentry.bytes, giststate);
+ /* be tidy */
+ if (tmpentry.pred != (((char *) tup) + sizeof(IndexTupleData)))
+ pfree(tmpentry.pred);
+ if (tup != newtup)
+ pfree(newtup);
+ return (res);
+ }
+}
static void
-gistnewroot(GISTSTATE *giststate, Relation r, IndexTuple lt, IndexTuple rt)
+gistnewroot(GISTSTATE * giststate, Relation r, IndexTuple lt, IndexTuple rt)
{
- Buffer b;
- Page p;
- GISTENTRY tmpentry;
- IndexTuple newtup;
-
- b = ReadBuffer(r, GISTP_ROOT);
- GISTInitBuffer(b, 0);
- p = BufferGetPage(b);
- gistPageAddItem(giststate, r, p, (Item) lt, IndexTupleSize(lt),
- FirstOffsetNumber,
- LP_USED, &tmpentry, &newtup);
- /* be tidy */
- if (tmpentry.pred != (((char *) lt) + sizeof(IndexTupleData)))
- pfree(tmpentry.pred);
- if (lt != newtup)
- pfree(newtup);
- gistPageAddItem(giststate, r, p, (Item) rt, IndexTupleSize(rt),
- OffsetNumberNext(FirstOffsetNumber), LP_USED,
- &tmpentry, &newtup);
- /* be tidy */
- if (tmpentry.pred != (((char *) rt) + sizeof(IndexTupleData)))
- pfree(tmpentry.pred);
- if (rt != newtup)
- pfree(newtup);
- WriteBuffer(b);
+ Buffer b;
+ Page p;
+ GISTENTRY tmpentry;
+ IndexTuple newtup;
+
+ b = ReadBuffer(r, GISTP_ROOT);
+ GISTInitBuffer(b, 0);
+ p = BufferGetPage(b);
+ gistPageAddItem(giststate, r, p, (Item) lt, IndexTupleSize(lt),
+ FirstOffsetNumber,
+ LP_USED, &tmpentry, &newtup);
+ /* be tidy */
+ if (tmpentry.pred != (((char *) lt) + sizeof(IndexTupleData)))
+ pfree(tmpentry.pred);
+ if (lt != newtup)
+ pfree(newtup);
+ gistPageAddItem(giststate, r, p, (Item) rt, IndexTupleSize(rt),
+ OffsetNumberNext(FirstOffsetNumber), LP_USED,
+ &tmpentry, &newtup);
+ /* be tidy */
+ if (tmpentry.pred != (((char *) rt) + sizeof(IndexTupleData)))
+ pfree(tmpentry.pred);
+ if (rt != newtup)
+ pfree(newtup);
+ WriteBuffer(b);
}
static void
GISTInitBuffer(Buffer b, uint32 f)
{
- GISTPageOpaque opaque;
- Page page;
- Size pageSize;
-
- pageSize = BufferGetPageSize(b);
-
- page = BufferGetPage(b);
- memset(page, 0, (int) pageSize);
- PageInit(page, pageSize, sizeof(GISTPageOpaqueData));
-
- opaque = (GISTPageOpaque) PageGetSpecialPointer(page);
- opaque->flags = f;
+ GISTPageOpaque opaque;
+ Page page;
+ Size pageSize;
+
+ pageSize = BufferGetPageSize(b);
+
+ page = BufferGetPage(b);
+ memset(page, 0, (int) pageSize);
+ PageInit(page, pageSize, sizeof(GISTPageOpaqueData));
+
+ opaque = (GISTPageOpaque) PageGetSpecialPointer(page);
+ opaque->flags = f;
}
/*
** find entry with lowest penalty
*/
-static OffsetNumber
-gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */
- GISTSTATE *giststate)
+static OffsetNumber
+gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */
+ GISTSTATE * giststate)
{
- OffsetNumber maxoff;
- OffsetNumber i;
- char *id;
- char *datum;
- float usize;
- OffsetNumber which;
- float which_grow;
- GISTENTRY entry, identry;
- int size, idsize;
-
- idsize = IndexTupleSize(it) - sizeof(IndexTupleData);
- id = ((char *) it) + sizeof(IndexTupleData);
- maxoff = PageGetMaxOffsetNumber(p);
- which_grow = -1.0;
- which = -1;
-
- gistdentryinit(giststate,&identry,id,(Relation)NULL,(Page)NULL,
- (OffsetNumber)0, idsize, FALSE);
-
- for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
- datum = (char *) PageGetItem(p, PageGetItemId(p, i));
- size = IndexTupleSize(datum) - sizeof(IndexTupleData);
- datum += sizeof(IndexTupleData);
- gistdentryinit(giststate,&entry,datum,r,p,i,size,FALSE);
- (giststate->penaltyFn)(&entry, &identry, &usize);
- if (which_grow < 0 || usize < which_grow) {
- which = i;
- which_grow = usize;
- if (which_grow == 0)
- break;
+ OffsetNumber maxoff;
+ OffsetNumber i;
+ char *id;
+ char *datum;
+ float usize;
+ OffsetNumber which;
+ float which_grow;
+ GISTENTRY entry,
+ identry;
+ int size,
+ idsize;
+
+ idsize = IndexTupleSize(it) - sizeof(IndexTupleData);
+ id = ((char *) it) + sizeof(IndexTupleData);
+ maxoff = PageGetMaxOffsetNumber(p);
+ which_grow = -1.0;
+ which = -1;
+
+ gistdentryinit(giststate, &identry, id, (Relation) NULL, (Page) NULL,
+ (OffsetNumber) 0, idsize, FALSE);
+
+ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+ {
+ datum = (char *) PageGetItem(p, PageGetItemId(p, i));
+ size = IndexTupleSize(datum) - sizeof(IndexTupleData);
+ datum += sizeof(IndexTupleData);
+ gistdentryinit(giststate, &entry, datum, r, p, i, size, FALSE);
+ (giststate->penaltyFn) (&entry, &identry, &usize);
+ if (which_grow < 0 || usize < which_grow)
+ {
+ which = i;
+ which_grow = usize;
+ if (which_grow == 0)
+ break;
+ }
+ if (entry.pred != datum)
+ pfree(entry.pred);
}
- if (entry.pred != datum)
- pfree(entry.pred);
- }
- if (identry.pred != id)
- pfree(identry.pred);
-
- return (which);
+ if (identry.pred != id)
+ pfree(identry.pred);
+
+ return (which);
}
static int
gistnospace(Page p, IndexTuple it)
{
- return (PageGetFreeSpace(p) < IndexTupleSize(it));
+ return (PageGetFreeSpace(p) < IndexTupleSize(it));
}
void
-gistfreestack(GISTSTACK *s)
+gistfreestack(GISTSTACK * s)
{
- GISTSTACK *p;
-
- while (s != (GISTSTACK *) NULL) {
- p = s->gs_parent;
- pfree(s);
- s = p;
- }
+ GISTSTACK *p;
+
+ while (s != (GISTSTACK *) NULL)
+ {
+ p = s->gs_parent;
+ pfree(s);
+ s = p;
+ }
}
-/*
-** remove an entry from a page
+/*
+** remove an entry from a page
*/
void
gistdelete(Relation r, ItemPointer tid)
{
- BlockNumber blkno;
- OffsetNumber offnum;
- Buffer buf;
- Page page;
-
- /* must write-lock on delete */
- RelationSetLockForWrite(r);
-
- blkno = ItemPointerGetBlockNumber(tid);
- offnum = ItemPointerGetOffsetNumber(tid);
-
- /* adjust any scans that will be affected by this deletion */
- gistadjscans(r, GISTOP_DEL, blkno, offnum);
-
- /* delete the index tuple */
- buf = ReadBuffer(r, blkno);
- page = BufferGetPage(buf);
-
- PageIndexTupleDelete(page, offnum);
-
- WriteBuffer(buf);
-
- /* XXX -- two-phase locking, don't release the write lock */
+ BlockNumber blkno;
+ OffsetNumber offnum;
+ Buffer buf;
+ Page page;
+
+ /* must write-lock on delete */
+ RelationSetLockForWrite(r);
+
+ blkno = ItemPointerGetBlockNumber(tid);
+ offnum = ItemPointerGetOffsetNumber(tid);
+
+ /* adjust any scans that will be affected by this deletion */
+ gistadjscans(r, GISTOP_DEL, blkno, offnum);
+
+ /* delete the index tuple */
+ buf = ReadBuffer(r, blkno);
+ page = BufferGetPage(buf);
+
+ PageIndexTupleDelete(page, offnum);
+
+ WriteBuffer(buf);
+
+ /* XXX -- two-phase locking, don't release the write lock */
}
-void
-initGISTstate(GISTSTATE *giststate, Relation index)
+void
+initGISTstate(GISTSTATE * giststate, Relation index)
{
- RegProcedure consistent_proc, union_proc, compress_proc, decompress_proc;
- RegProcedure penalty_proc, picksplit_proc, equal_proc;
- func_ptr user_fn;
- int pronargs;
- HeapTuple htup;
- IndexTupleForm itupform;
-
- consistent_proc = index_getprocid(index, 1, GIST_CONSISTENT_PROC);
- union_proc = index_getprocid(index, 1, GIST_UNION_PROC);
- compress_proc = index_getprocid(index, 1, GIST_COMPRESS_PROC);
- decompress_proc = index_getprocid(index, 1, GIST_DECOMPRESS_PROC);
- penalty_proc = index_getprocid(index, 1, GIST_PENALTY_PROC);
- picksplit_proc = index_getprocid(index, 1, GIST_PICKSPLIT_PROC);
- equal_proc = index_getprocid(index, 1, GIST_EQUAL_PROC);
- fmgr_info(consistent_proc, &user_fn, &pronargs);
- giststate->consistentFn = user_fn;
- fmgr_info(union_proc, &user_fn, &pronargs);
- giststate->unionFn = user_fn;
- fmgr_info(compress_proc, &user_fn, &pronargs);
- giststate->compressFn = user_fn;
- fmgr_info(decompress_proc, &user_fn, &pronargs);
- giststate->decompressFn = user_fn;
- fmgr_info(penalty_proc, &user_fn, &pronargs);
- giststate->penaltyFn = user_fn;
- fmgr_info(picksplit_proc, &user_fn, &pronargs);
- giststate->picksplitFn = user_fn;
- fmgr_info(equal_proc, &user_fn, &pronargs);
- giststate->equalFn = user_fn;
-
- /* see if key type is different from type of attribute being indexed */
- htup = SearchSysCacheTuple(INDEXRELID, ObjectIdGetDatum(index->rd_id),
- 0,0,0);
- itupform = (IndexTupleForm)GETSTRUCT(htup);
- if (!HeapTupleIsValid(htup))
- elog(WARN, "initGISTstate: index %d not found", index->rd_id);
- giststate->haskeytype = itupform->indhaskeytype;
- if (giststate->haskeytype) {
- /* key type is different -- is it byval? */
- htup = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(itupform->indexrelid),
- UInt16GetDatum(FirstOffsetNumber),
- 0,0);
- if (!HeapTupleIsValid(htup)) {
- elog(WARN, "initGISTstate: no attribute tuple %d %d",
- itupform->indexrelid, FirstOffsetNumber);
- return;
+ RegProcedure consistent_proc,
+ union_proc,
+ compress_proc,
+ decompress_proc;
+ RegProcedure penalty_proc,
+ picksplit_proc,
+ equal_proc;
+ func_ptr user_fn;
+ int pronargs;
+ HeapTuple htup;
+ IndexTupleForm itupform;
+
+ consistent_proc = index_getprocid(index, 1, GIST_CONSISTENT_PROC);
+ union_proc = index_getprocid(index, 1, GIST_UNION_PROC);
+ compress_proc = index_getprocid(index, 1, GIST_COMPRESS_PROC);
+ decompress_proc = index_getprocid(index, 1, GIST_DECOMPRESS_PROC);
+ penalty_proc = index_getprocid(index, 1, GIST_PENALTY_PROC);
+ picksplit_proc = index_getprocid(index, 1, GIST_PICKSPLIT_PROC);
+ equal_proc = index_getprocid(index, 1, GIST_EQUAL_PROC);
+ fmgr_info(consistent_proc, &user_fn, &pronargs);
+ giststate->consistentFn = user_fn;
+ fmgr_info(union_proc, &user_fn, &pronargs);
+ giststate->unionFn = user_fn;
+ fmgr_info(compress_proc, &user_fn, &pronargs);
+ giststate->compressFn = user_fn;
+ fmgr_info(decompress_proc, &user_fn, &pronargs);
+ giststate->decompressFn = user_fn;
+ fmgr_info(penalty_proc, &user_fn, &pronargs);
+ giststate->penaltyFn = user_fn;
+ fmgr_info(picksplit_proc, &user_fn, &pronargs);
+ giststate->picksplitFn = user_fn;
+ fmgr_info(equal_proc, &user_fn, &pronargs);
+ giststate->equalFn = user_fn;
+
+ /* see if key type is different from type of attribute being indexed */
+ htup = SearchSysCacheTuple(INDEXRELID, ObjectIdGetDatum(index->rd_id),
+ 0, 0, 0);
+ itupform = (IndexTupleForm) GETSTRUCT(htup);
+ if (!HeapTupleIsValid(htup))
+ elog(WARN, "initGISTstate: index %d not found", index->rd_id);
+ giststate->haskeytype = itupform->indhaskeytype;
+ if (giststate->haskeytype)
+ {
+ /* key type is different -- is it byval? */
+ htup = SearchSysCacheTuple(ATTNUM,
+ ObjectIdGetDatum(itupform->indexrelid),
+ UInt16GetDatum(FirstOffsetNumber),
+ 0, 0);
+ if (!HeapTupleIsValid(htup))
+ {
+ elog(WARN, "initGISTstate: no attribute tuple %d %d",
+ itupform->indexrelid, FirstOffsetNumber);
+ return;
+ }
+ giststate->keytypbyval = (((AttributeTupleForm) htup)->attbyval);
}
- giststate->keytypbyval = (((AttributeTupleForm)htup)->attbyval);
- }
- else
- giststate->keytypbyval = FALSE;
- return;
+ else
+ giststate->keytypbyval = FALSE;
+ return;
}
@@ -1118,56 +1209,61 @@ initGISTstate(GISTSTATE *giststate, Relation index)
** the key with another key, which may involve generating a new IndexTuple
** if the sizes don't match
*/
-static IndexTuple
+static IndexTuple
gist_tuple_replacekey(Relation r, GISTENTRY entry, IndexTuple t)
{
- char * datum = (((char *) t) + sizeof(IndexTupleData));
-
- /* if new entry fits in index tuple, copy it in */
- if (entry.bytes < IndexTupleSize(t) - sizeof(IndexTupleData)) {
- memcpy(datum, entry.pred, entry.bytes);
- /* clear out old size */
- t->t_info &= 0xe000;
- /* or in new size */
- t->t_info |= MAXALIGN(entry.bytes + sizeof(IndexTupleData));
-
- return(t);
- }
- else {
- /* generate a new index tuple for the compressed entry */
- TupleDesc tupDesc = r->rd_att;
- IndexTuple newtup;
- char *isnull;
- int blank;
-
- isnull = (char *) palloc(r->rd_rel->relnatts);
- for (blank = 0; blank < r->rd_rel->relnatts; blank++)
- isnull[blank] = ' ';
- newtup = (IndexTuple) index_formtuple(tupDesc,
- (Datum *)&(entry.pred),
- isnull);
- newtup->t_tid = t->t_tid;
- pfree(isnull);
- return(newtup);
- }
+ char *datum = (((char *) t) + sizeof(IndexTupleData));
+
+ /* if new entry fits in index tuple, copy it in */
+ if (entry.bytes < IndexTupleSize(t) - sizeof(IndexTupleData))
+ {
+ memcpy(datum, entry.pred, entry.bytes);
+ /* clear out old size */
+ t->t_info &= 0xe000;
+ /* or in new size */
+ t->t_info |= MAXALIGN(entry.bytes + sizeof(IndexTupleData));
+
+ return (t);
+ }
+ else
+ {
+ /* generate a new index tuple for the compressed entry */
+ TupleDesc tupDesc = r->rd_att;
+ IndexTuple newtup;
+ char *isnull;
+ int blank;
+
+ isnull = (char *) palloc(r->rd_rel->relnatts);
+ for (blank = 0; blank < r->rd_rel->relnatts; blank++)
+ isnull[blank] = ' ';
+ newtup = (IndexTuple) index_formtuple(tupDesc,
+ (Datum *) & (entry.pred),
+ isnull);
+ newtup->t_tid = t->t_tid;
+ pfree(isnull);
+ return (newtup);
+ }
}
-
+
/*
** initialize a GiST entry with a decompressed version of pred
*/
void
-gistdentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, Relation r,
- Page pg, OffsetNumber o, int b, bool l)
-{
- GISTENTRY *dep;
- gistentryinit(*e, pr, r, pg, o, b, l);
- if (giststate->haskeytype) {
- dep = (GISTENTRY *)((giststate->decompressFn)(e));
- gistentryinit(*e, dep->pred, dep->rel, dep->page, dep->offset, dep->bytes,
- dep->leafkey);
- if (dep != e) pfree(dep);
- }
+gistdentryinit(GISTSTATE * giststate, GISTENTRY * e, char *pr, Relation r,
+ Page pg, OffsetNumber o, int b, bool l)
+{
+ GISTENTRY *dep;
+
+ gistentryinit(*e, pr, r, pg, o, b, l);
+ if (giststate->haskeytype)
+ {
+ dep = (GISTENTRY *) ((giststate->decompressFn) (e));
+ gistentryinit(*e, dep->pred, dep->rel, dep->page, dep->offset, dep->bytes,
+ dep->leafkey);
+ if (dep != e)
+ pfree(dep);
+ }
}
@@ -1175,19 +1271,22 @@ gistdentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, Relation r,
** initialize a GiST entry with a compressed version of pred
*/
static void
-gistcentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, Relation r,
- Page pg, OffsetNumber o, int b, bool l)
-{
- GISTENTRY *cep;
- gistentryinit(*e, pr, r, pg, o, b, l);
- if (giststate->haskeytype) {
- cep = (GISTENTRY *)((giststate->compressFn)(e));
- gistentryinit(*e, cep->pred, cep->rel, cep->page, cep->offset, cep->bytes,
- cep->leafkey);
- if (cep != e) pfree(cep);
- }
+gistcentryinit(GISTSTATE * giststate, GISTENTRY * e, char *pr, Relation r,
+ Page pg, OffsetNumber o, int b, bool l)
+{
+ GISTENTRY *cep;
+
+ gistentryinit(*e, pr, r, pg, o, b, l);
+ if (giststate->haskeytype)
+ {
+ cep = (GISTENTRY *) ((giststate->compressFn) (e));
+ gistentryinit(*e, cep->pred, cep->rel, cep->page, cep->offset, cep->bytes,
+ cep->leafkey);
+ if (cep != e)
+ pfree(cep);
+ }
}
-
+
#ifdef GISTDEBUG
@@ -1200,89 +1299,95 @@ gistcentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, Relation r,
void
_gistdump(Relation r)
{
- Buffer buf;
- Page page;
- OffsetNumber offnum, maxoff;
- BlockNumber blkno;
- BlockNumber nblocks;
- GISTPageOpaque po;
- IndexTuple itup;
- BlockNumber itblkno;
- OffsetNumber itoffno;
- char *datum;
- char *itkey;
-
- nblocks = RelationGetNumberOfBlocks(r);
- for (blkno = 0; blkno < nblocks; blkno++) {
- buf = ReadBuffer(r, blkno);
- page = BufferGetPage(buf);
- po = (GISTPageOpaque) PageGetSpecialPointer(page);
- maxoff = PageGetMaxOffsetNumber(page);
- printf("Page %d maxoff %d <%s>\n", blkno, maxoff,
- (po->flags & F_LEAF ? "LEAF" : "INTERNAL"));
-
- if (PageIsEmpty(page)) {
- ReleaseBuffer(buf);
- continue;
- }
-
- for (offnum = FirstOffsetNumber;
- offnum <= maxoff;
- offnum = OffsetNumberNext(offnum)) {
- itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
- itblkno = ItemPointerGetBlockNumber(&(itup->t_tid));
- itoffno = ItemPointerGetOffsetNumber(&(itup->t_tid));
- datum = ((char *) itup);
- datum += sizeof(IndexTupleData);
- /* get out function for type of key, and out it! */
- itkey = (char *) int_range_out((INTRANGE *)datum);
- /* itkey = " unable to print"; */
- printf("\t[%d] size %d heap <%d,%d> key:%s\n",
- offnum, IndexTupleSize(itup), itblkno, itoffno, itkey);
- pfree(itkey);
+ Buffer buf;
+ Page page;
+ OffsetNumber offnum,
+ maxoff;
+ BlockNumber blkno;
+ BlockNumber nblocks;
+ GISTPageOpaque po;
+ IndexTuple itup;
+ BlockNumber itblkno;
+ OffsetNumber itoffno;
+ char *datum;
+ char *itkey;
+
+ nblocks = RelationGetNumberOfBlocks(r);
+ for (blkno = 0; blkno < nblocks; blkno++)
+ {
+ buf = ReadBuffer(r, blkno);
+ page = BufferGetPage(buf);
+ po = (GISTPageOpaque) PageGetSpecialPointer(page);
+ maxoff = PageGetMaxOffsetNumber(page);
+ printf("Page %d maxoff %d <%s>\n", blkno, maxoff,
+ (po->flags & F_LEAF ? "LEAF" : "INTERNAL"));
+
+ if (PageIsEmpty(page))
+ {
+ ReleaseBuffer(buf);
+ continue;
+ }
+
+ for (offnum = FirstOffsetNumber;
+ offnum <= maxoff;
+ offnum = OffsetNumberNext(offnum))
+ {
+ itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
+ itblkno = ItemPointerGetBlockNumber(&(itup->t_tid));
+ itoffno = ItemPointerGetOffsetNumber(&(itup->t_tid));
+ datum = ((char *) itup);
+ datum += sizeof(IndexTupleData);
+ /* get out function for type of key, and out it! */
+ itkey = (char *) int_range_out((INTRANGE *) datum);
+ /* itkey = " unable to print"; */
+ printf("\t[%d] size %d heap <%d,%d> key:%s\n",
+ offnum, IndexTupleSize(itup), itblkno, itoffno, itkey);
+ pfree(itkey);
+ }
+
+ ReleaseBuffer(buf);
}
-
- ReleaseBuffer(buf);
- }
}
#ifdef NOT_USED
-static char *text_range_out(TXTRANGE *r)
+static char *
+text_range_out(TXTRANGE * r)
{
- char *result;
- char *lower, *upper;
-
- if (r == NULL)
- return(NULL);
- result = (char *)palloc(16 + VARSIZE(TRLOWER(r)) + VARSIZE(TRUPPER(r))
- - 2*VARHDRSZ);
-
- lower = (char *)palloc(VARSIZE(TRLOWER(r)) + 1 - VARHDRSZ);
- memcpy(lower, VARDATA(TRLOWER(r)), VARSIZE(TRLOWER(r)) - VARHDRSZ);
- lower[VARSIZE(TRLOWER(r)) - VARHDRSZ] = '\0';
- upper = (char *)palloc(VARSIZE(TRUPPER(r)) + 1 - VARHDRSZ);
- memcpy(upper, VARDATA(TRUPPER(r)), VARSIZE(TRUPPER(r)) - VARHDRSZ);
- upper[VARSIZE(TRUPPER(r)) - VARHDRSZ] = '\0';
-
- sprintf(result, "[%s,%s): %d", lower, upper, r->flag);
- pfree(lower);
- pfree(upper);
- return(result);
+ char *result;
+ char *lower,
+ *upper;
+
+ if (r == NULL)
+ return (NULL);
+ result = (char *) palloc(16 + VARSIZE(TRLOWER(r)) + VARSIZE(TRUPPER(r))
+ - 2 * VARHDRSZ);
+
+ lower = (char *) palloc(VARSIZE(TRLOWER(r)) + 1 - VARHDRSZ);
+ memcpy(lower, VARDATA(TRLOWER(r)), VARSIZE(TRLOWER(r)) - VARHDRSZ);
+ lower[VARSIZE(TRLOWER(r)) - VARHDRSZ] = '\0';
+ upper = (char *) palloc(VARSIZE(TRUPPER(r)) + 1 - VARHDRSZ);
+ memcpy(upper, VARDATA(TRUPPER(r)), VARSIZE(TRUPPER(r)) - VARHDRSZ);
+ upper[VARSIZE(TRUPPER(r)) - VARHDRSZ] = '\0';
+
+ sprintf(result, "[%s,%s): %d", lower, upper, r->flag);
+ pfree(lower);
+ pfree(upper);
+ return (result);
}
+
#endif
-static char *
-int_range_out(INTRANGE *r)
+static char *
+int_range_out(INTRANGE * r)
{
- char *result;
-
- if (r == NULL)
- return(NULL);
- result = (char *)palloc(80);
- sprintf(result, "[%d,%d): %d",r->lower, r->upper, r->flag);
-
- return(result);
-}
+ char *result;
+
+ if (r == NULL)
+ return (NULL);
+ result = (char *) palloc(80);
+ sprintf(result, "[%d,%d): %d", r->lower, r->upper, r->flag);
-#endif /* defined GISTDEBUG */
+ return (result);
+}
+#endif /* defined GISTDEBUG */
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index ac1697e5ed2..cad4cef267e 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* gistget.c--
- * fetch tuples from a GiST scan.
+ * fetch tuples from a GiST scan.
*
*
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/access/gisr/gistget.c,v 1.9.1 1996/11/21 01:00:00 vadim Exp
+ * /usr/local/devel/pglite/cvs/src/backend/access/gisr/gistget.c,v 1.9.1 1996/11/21 01:00:00 vadim Exp
*
*-------------------------------------------------------------------------
*/
@@ -22,350 +22,392 @@
#include <storage/bufmgr.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static OffsetNumber gistfindnext(IndexScanDesc s, Page p, OffsetNumber n,
- ScanDirection dir);
+static OffsetNumber
+gistfindnext(IndexScanDesc s, Page p, OffsetNumber n,
+ ScanDirection dir);
static RetrieveIndexResult gistscancache(IndexScanDesc s, ScanDirection dir);
static RetrieveIndexResult gistfirst(IndexScanDesc s, ScanDirection dir);
static RetrieveIndexResult gistnext(IndexScanDesc s, ScanDirection dir);
static ItemPointer gistheapptr(Relation r, ItemPointer itemp);
-static bool gistindex_keytest(IndexTuple tuple, TupleDesc tupdesc,
- int scanKeySize, ScanKey key, GISTSTATE *giststate,
- Relation r, Page p, OffsetNumber offset);
+static bool
+gistindex_keytest(IndexTuple tuple, TupleDesc tupdesc,
+ int scanKeySize, ScanKey key, GISTSTATE * giststate,
+ Relation r, Page p, OffsetNumber offset);
RetrieveIndexResult
gistgettuple(IndexScanDesc s, ScanDirection dir)
{
- RetrieveIndexResult res;
-
- /* if we have it cached in the scan desc, just return the value */
- if ((res = gistscancache(s, dir)) != (RetrieveIndexResult) NULL)
+ RetrieveIndexResult res;
+
+ /* if we have it cached in the scan desc, just return the value */
+ if ((res = gistscancache(s, dir)) != (RetrieveIndexResult) NULL)
+ return (res);
+
+ /* not cached, so we'll have to do some work */
+ if (ItemPointerIsValid(&(s->currentItemData)))
+ {
+ res = gistnext(s, dir);
+ }
+ else
+ {
+ res = gistfirst(s, dir);
+ }
return (res);
-
- /* not cached, so we'll have to do some work */
- if (ItemPointerIsValid(&(s->currentItemData))) {
- res = gistnext(s, dir);
- } else {
- res = gistfirst(s, dir);
- }
- return (res);
}
-static RetrieveIndexResult
+static RetrieveIndexResult
gistfirst(IndexScanDesc s, ScanDirection dir)
{
- Buffer b;
- Page p;
- OffsetNumber n;
- OffsetNumber maxoff;
- RetrieveIndexResult res;
- GISTPageOpaque po;
- GISTScanOpaque so;
- GISTSTACK *stk;
- BlockNumber blk;
- IndexTuple it;
-
- b = ReadBuffer(s->relation, GISTP_ROOT);
- p = BufferGetPage(b);
- po = (GISTPageOpaque) PageGetSpecialPointer(p);
- so = (GISTScanOpaque) s->opaque;
-
- for (;;) {
- maxoff = PageGetMaxOffsetNumber(p);
- if (ScanDirectionIsBackward(dir))
- n = gistfindnext(s, p, maxoff, dir);
- else
- n = gistfindnext(s, p, FirstOffsetNumber, dir);
-
- while (n < FirstOffsetNumber || n > maxoff) {
-
- ReleaseBuffer(b);
- if (so->s_stack == (GISTSTACK *) NULL)
- return ((RetrieveIndexResult) NULL);
-
- stk = so->s_stack;
- b = ReadBuffer(s->relation, stk->gs_blk);
- p = BufferGetPage(b);
- po = (GISTPageOpaque) PageGetSpecialPointer(p);
- maxoff = PageGetMaxOffsetNumber(p);
-
- if (ScanDirectionIsBackward(dir)) {
- n = OffsetNumberPrev(stk->gs_child);
- } else {
- n = OffsetNumberNext(stk->gs_child);
- }
- so->s_stack = stk->gs_parent;
- pfree(stk);
-
- n = gistfindnext(s, p, n, dir);
- }
- if (po->flags & F_LEAF) {
- ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
-
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
-
- res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
-
- ReleaseBuffer(b);
- return (res);
- } else {
- stk = (GISTSTACK *) palloc(sizeof(GISTSTACK));
- stk->gs_child = n;
- stk->gs_blk = BufferGetBlockNumber(b);
- stk->gs_parent = so->s_stack;
- so->s_stack = stk;
-
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
- blk = ItemPointerGetBlockNumber(&(it->t_tid));
-
- ReleaseBuffer(b);
- b = ReadBuffer(s->relation, blk);
- p = BufferGetPage(b);
- po = (GISTPageOpaque) PageGetSpecialPointer(p);
+ Buffer b;
+ Page p;
+ OffsetNumber n;
+ OffsetNumber maxoff;
+ RetrieveIndexResult res;
+ GISTPageOpaque po;
+ GISTScanOpaque so;
+ GISTSTACK *stk;
+ BlockNumber blk;
+ IndexTuple it;
+
+ b = ReadBuffer(s->relation, GISTP_ROOT);
+ p = BufferGetPage(b);
+ po = (GISTPageOpaque) PageGetSpecialPointer(p);
+ so = (GISTScanOpaque) s->opaque;
+
+ for (;;)
+ {
+ maxoff = PageGetMaxOffsetNumber(p);
+ if (ScanDirectionIsBackward(dir))
+ n = gistfindnext(s, p, maxoff, dir);
+ else
+ n = gistfindnext(s, p, FirstOffsetNumber, dir);
+
+ while (n < FirstOffsetNumber || n > maxoff)
+ {
+
+ ReleaseBuffer(b);
+ if (so->s_stack == (GISTSTACK *) NULL)
+ return ((RetrieveIndexResult) NULL);
+
+ stk = so->s_stack;
+ b = ReadBuffer(s->relation, stk->gs_blk);
+ p = BufferGetPage(b);
+ po = (GISTPageOpaque) PageGetSpecialPointer(p);
+ maxoff = PageGetMaxOffsetNumber(p);
+
+ if (ScanDirectionIsBackward(dir))
+ {
+ n = OffsetNumberPrev(stk->gs_child);
+ }
+ else
+ {
+ n = OffsetNumberNext(stk->gs_child);
+ }
+ so->s_stack = stk->gs_parent;
+ pfree(stk);
+
+ n = gistfindnext(s, p, n, dir);
+ }
+ if (po->flags & F_LEAF)
+ {
+ ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
+
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+
+ res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
+
+ ReleaseBuffer(b);
+ return (res);
+ }
+ else
+ {
+ stk = (GISTSTACK *) palloc(sizeof(GISTSTACK));
+ stk->gs_child = n;
+ stk->gs_blk = BufferGetBlockNumber(b);
+ stk->gs_parent = so->s_stack;
+ so->s_stack = stk;
+
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+ blk = ItemPointerGetBlockNumber(&(it->t_tid));
+
+ ReleaseBuffer(b);
+ b = ReadBuffer(s->relation, blk);
+ p = BufferGetPage(b);
+ po = (GISTPageOpaque) PageGetSpecialPointer(p);
+ }
}
- }
}
-static RetrieveIndexResult
+static RetrieveIndexResult
gistnext(IndexScanDesc s, ScanDirection dir)
{
- Buffer b;
- Page p;
- OffsetNumber n;
- OffsetNumber maxoff;
- RetrieveIndexResult res;
- GISTPageOpaque po;
- GISTScanOpaque so;
- GISTSTACK *stk;
- BlockNumber blk;
- IndexTuple it;
-
- blk = ItemPointerGetBlockNumber(&(s->currentItemData));
- n = ItemPointerGetOffsetNumber(&(s->currentItemData));
-
- if (ScanDirectionIsForward(dir)) {
- n = OffsetNumberNext(n);
- } else {
- n = OffsetNumberPrev(n);
- }
-
- b = ReadBuffer(s->relation, blk);
- p = BufferGetPage(b);
- po = (GISTPageOpaque) PageGetSpecialPointer(p);
- so = (GISTScanOpaque) s->opaque;
-
- for (;;) {
- maxoff = PageGetMaxOffsetNumber(p);
- n = gistfindnext(s, p, n, dir);
-
- while (n < FirstOffsetNumber || n > maxoff) {
-
- ReleaseBuffer(b);
- if (so->s_stack == (GISTSTACK *) NULL)
- return ((RetrieveIndexResult) NULL);
-
- stk = so->s_stack;
- b = ReadBuffer(s->relation, stk->gs_blk);
- p = BufferGetPage(b);
- maxoff = PageGetMaxOffsetNumber(p);
- po = (GISTPageOpaque) PageGetSpecialPointer(p);
-
- if (ScanDirectionIsBackward(dir)) {
- n = OffsetNumberPrev(stk->gs_child);
- } else {
- n = OffsetNumberNext(stk->gs_child);
- }
- so->s_stack = stk->gs_parent;
- pfree(stk);
-
- n = gistfindnext(s, p, n, dir);
+ Buffer b;
+ Page p;
+ OffsetNumber n;
+ OffsetNumber maxoff;
+ RetrieveIndexResult res;
+ GISTPageOpaque po;
+ GISTScanOpaque so;
+ GISTSTACK *stk;
+ BlockNumber blk;
+ IndexTuple it;
+
+ blk = ItemPointerGetBlockNumber(&(s->currentItemData));
+ n = ItemPointerGetOffsetNumber(&(s->currentItemData));
+
+ if (ScanDirectionIsForward(dir))
+ {
+ n = OffsetNumberNext(n);
+ }
+ else
+ {
+ n = OffsetNumberPrev(n);
}
- if (po->flags & F_LEAF) {
- ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
-
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
-
- res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
-
- ReleaseBuffer(b);
- return (res);
- } else {
- stk = (GISTSTACK *) palloc(sizeof(GISTSTACK));
- stk->gs_child = n;
- stk->gs_blk = BufferGetBlockNumber(b);
- stk->gs_parent = so->s_stack;
- so->s_stack = stk;
-
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
- blk = ItemPointerGetBlockNumber(&(it->t_tid));
-
- ReleaseBuffer(b);
- b = ReadBuffer(s->relation, blk);
- p = BufferGetPage(b);
- po = (GISTPageOpaque) PageGetSpecialPointer(p);
-
- if (ScanDirectionIsBackward(dir)) {
- n = PageGetMaxOffsetNumber(p);
- } else {
- n = FirstOffsetNumber;
- }
+
+ b = ReadBuffer(s->relation, blk);
+ p = BufferGetPage(b);
+ po = (GISTPageOpaque) PageGetSpecialPointer(p);
+ so = (GISTScanOpaque) s->opaque;
+
+ for (;;)
+ {
+ maxoff = PageGetMaxOffsetNumber(p);
+ n = gistfindnext(s, p, n, dir);
+
+ while (n < FirstOffsetNumber || n > maxoff)
+ {
+
+ ReleaseBuffer(b);
+ if (so->s_stack == (GISTSTACK *) NULL)
+ return ((RetrieveIndexResult) NULL);
+
+ stk = so->s_stack;
+ b = ReadBuffer(s->relation, stk->gs_blk);
+ p = BufferGetPage(b);
+ maxoff = PageGetMaxOffsetNumber(p);
+ po = (GISTPageOpaque) PageGetSpecialPointer(p);
+
+ if (ScanDirectionIsBackward(dir))
+ {
+ n = OffsetNumberPrev(stk->gs_child);
+ }
+ else
+ {
+ n = OffsetNumberNext(stk->gs_child);
+ }
+ so->s_stack = stk->gs_parent;
+ pfree(stk);
+
+ n = gistfindnext(s, p, n, dir);
+ }
+ if (po->flags & F_LEAF)
+ {
+ ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
+
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+
+ res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
+
+ ReleaseBuffer(b);
+ return (res);
+ }
+ else
+ {
+ stk = (GISTSTACK *) palloc(sizeof(GISTSTACK));
+ stk->gs_child = n;
+ stk->gs_blk = BufferGetBlockNumber(b);
+ stk->gs_parent = so->s_stack;
+ so->s_stack = stk;
+
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+ blk = ItemPointerGetBlockNumber(&(it->t_tid));
+
+ ReleaseBuffer(b);
+ b = ReadBuffer(s->relation, blk);
+ p = BufferGetPage(b);
+ po = (GISTPageOpaque) PageGetSpecialPointer(p);
+
+ if (ScanDirectionIsBackward(dir))
+ {
+ n = PageGetMaxOffsetNumber(p);
+ }
+ else
+ {
+ n = FirstOffsetNumber;
+ }
+ }
}
- }
}
/* Similar to index_keytest, but decompresses the key in the IndexTuple */
-static bool
+static bool
gistindex_keytest(IndexTuple tuple,
- TupleDesc tupdesc,
- int scanKeySize,
- ScanKey key,
- GISTSTATE *giststate,
- Relation r,
- Page p,
- OffsetNumber offset)
+ TupleDesc tupdesc,
+ int scanKeySize,
+ ScanKey key,
+ GISTSTATE * giststate,
+ Relation r,
+ Page p,
+ OffsetNumber offset)
{
- bool isNull;
- Datum datum;
- int test;
- GISTENTRY de;
-
- IncrIndexProcessed();
-
-
- while (scanKeySize > 0) {
- datum = index_getattr(tuple,
- 1,
- tupdesc,
- &isNull);
- gistdentryinit(giststate, &de, (char *)datum, r, p, offset,
- IndexTupleSize(tuple) - sizeof(IndexTupleData),
- FALSE);
-
- if (isNull) {
- /* XXX eventually should check if SK_ISNULL */
- return (false);
- }
-
- if (key[0].sk_flags & SK_COMMUTE) {
- test = (*(key[0].sk_func))
- (DatumGetPointer(key[0].sk_argument),
- &de, key[0].sk_procedure) ? 1 : 0;
- } else {
- test = (*(key[0].sk_func))
- (&de,
- DatumGetPointer(key[0].sk_argument),
- key[0].sk_procedure) ? 1 : 0;
- }
-
- if (!test == !(key[0].sk_flags & SK_NEGATE)) {
- return (false);
+ bool isNull;
+ Datum datum;
+ int test;
+ GISTENTRY de;
+
+ IncrIndexProcessed();
+
+
+ while (scanKeySize > 0)
+ {
+ datum = index_getattr(tuple,
+ 1,
+ tupdesc,
+ &isNull);
+ gistdentryinit(giststate, &de, (char *) datum, r, p, offset,
+ IndexTupleSize(tuple) - sizeof(IndexTupleData),
+ FALSE);
+
+ if (isNull)
+ {
+ /* XXX eventually should check if SK_ISNULL */
+ return (false);
+ }
+
+ if (key[0].sk_flags & SK_COMMUTE)
+ {
+ test = (*(key[0].sk_func))
+ (DatumGetPointer(key[0].sk_argument),
+ &de, key[0].sk_procedure) ? 1 : 0;
+ }
+ else
+ {
+ test = (*(key[0].sk_func))
+ (&de,
+ DatumGetPointer(key[0].sk_argument),
+ key[0].sk_procedure) ? 1 : 0;
+ }
+
+ if (!test == !(key[0].sk_flags & SK_NEGATE))
+ {
+ return (false);
+ }
+
+ scanKeySize -= 1;
+ key++;
}
-
- scanKeySize -= 1;
- key++;
- }
-
- return (true);
+
+ return (true);
}
-static OffsetNumber
+static OffsetNumber
gistfindnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
{
- OffsetNumber maxoff;
- char *it;
- GISTPageOpaque po;
- GISTScanOpaque so;
- GISTSTATE *giststate;
-
- maxoff = PageGetMaxOffsetNumber(p);
- po = (GISTPageOpaque) PageGetSpecialPointer(p);
- so = (GISTScanOpaque) s->opaque;
- giststate = so->giststate;
-
- /*
- * If we modified the index during the scan, we may have a pointer to
- * a ghost tuple, before the scan. If this is the case, back up one.
- */
-
- if (so->s_flags & GS_CURBEFORE) {
- so->s_flags &= ~GS_CURBEFORE;
- n = OffsetNumberPrev(n);
- }
-
- while (n >= FirstOffsetNumber && n <= maxoff) {
- it = (char *) PageGetItem(p, PageGetItemId(p, n));
- if (gistindex_keytest((IndexTuple) it,
- RelationGetTupleDescriptor(s->relation),
- s->numberOfKeys, s->keyData, giststate,
- s->relation, p, n))
- break;
-
- if (ScanDirectionIsBackward(dir)) {
- n = OffsetNumberPrev(n);
- } else {
- n = OffsetNumberNext(n);
+ OffsetNumber maxoff;
+ char *it;
+ GISTPageOpaque po;
+ GISTScanOpaque so;
+ GISTSTATE *giststate;
+
+ maxoff = PageGetMaxOffsetNumber(p);
+ po = (GISTPageOpaque) PageGetSpecialPointer(p);
+ so = (GISTScanOpaque) s->opaque;
+ giststate = so->giststate;
+
+ /*
+ * If we modified the index during the scan, we may have a pointer to
+ * a ghost tuple, before the scan. If this is the case, back up one.
+ */
+
+ if (so->s_flags & GS_CURBEFORE)
+ {
+ so->s_flags &= ~GS_CURBEFORE;
+ n = OffsetNumberPrev(n);
}
- }
-
- return (n);
+
+ while (n >= FirstOffsetNumber && n <= maxoff)
+ {
+ it = (char *) PageGetItem(p, PageGetItemId(p, n));
+ if (gistindex_keytest((IndexTuple) it,
+ RelationGetTupleDescriptor(s->relation),
+ s->numberOfKeys, s->keyData, giststate,
+ s->relation, p, n))
+ break;
+
+ if (ScanDirectionIsBackward(dir))
+ {
+ n = OffsetNumberPrev(n);
+ }
+ else
+ {
+ n = OffsetNumberNext(n);
+ }
+ }
+
+ return (n);
}
-static RetrieveIndexResult
+static RetrieveIndexResult
gistscancache(IndexScanDesc s, ScanDirection dir)
{
- RetrieveIndexResult res;
- ItemPointer ip;
-
- if (!(ScanDirectionIsNoMovement(dir)
- && ItemPointerIsValid(&(s->currentItemData)))) {
-
- return ((RetrieveIndexResult) NULL);
- }
-
- ip = gistheapptr(s->relation, &(s->currentItemData));
-
- if (ItemPointerIsValid(ip))
- res = FormRetrieveIndexResult(&(s->currentItemData), ip);
- else
- res = (RetrieveIndexResult) NULL;
-
- pfree (ip);
-
- return (res);
+ RetrieveIndexResult res;
+ ItemPointer ip;
+
+ if (!(ScanDirectionIsNoMovement(dir)
+ && ItemPointerIsValid(&(s->currentItemData))))
+ {
+
+ return ((RetrieveIndexResult) NULL);
+ }
+
+ ip = gistheapptr(s->relation, &(s->currentItemData));
+
+ if (ItemPointerIsValid(ip))
+ res = FormRetrieveIndexResult(&(s->currentItemData), ip);
+ else
+ res = (RetrieveIndexResult) NULL;
+
+ pfree(ip);
+
+ return (res);
}
/*
- * gistheapptr returns the item pointer to the tuple in the heap relation
- * for which itemp is the index relation item pointer.
+ * gistheapptr returns the item pointer to the tuple in the heap relation
+ * for which itemp is the index relation item pointer.
*/
-static ItemPointer
+static ItemPointer
gistheapptr(Relation r, ItemPointer itemp)
{
- Buffer b;
- Page p;
- IndexTuple it;
- ItemPointer ip;
- OffsetNumber n;
-
- ip = (ItemPointer) palloc(sizeof(ItemPointerData));
- if (ItemPointerIsValid(itemp)) {
- b = ReadBuffer(r, ItemPointerGetBlockNumber(itemp));
- p = BufferGetPage(b);
- n = ItemPointerGetOffsetNumber(itemp);
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
- memmove((char *) ip, (char *) &(it->t_tid),
- sizeof(ItemPointerData));
- ReleaseBuffer(b);
- } else {
- ItemPointerSetInvalid(ip);
- }
-
- return (ip);
+ Buffer b;
+ Page p;
+ IndexTuple it;
+ ItemPointer ip;
+ OffsetNumber n;
+
+ ip = (ItemPointer) palloc(sizeof(ItemPointerData));
+ if (ItemPointerIsValid(itemp))
+ {
+ b = ReadBuffer(r, ItemPointerGetBlockNumber(itemp));
+ p = BufferGetPage(b);
+ n = ItemPointerGetOffsetNumber(itemp);
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+ memmove((char *) ip, (char *) &(it->t_tid),
+ sizeof(ItemPointerData));
+ ReleaseBuffer(b);
+ }
+ else
+ {
+ ItemPointerSetInvalid(ip);
+ }
+
+ return (ip);
}
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c
index c877538472c..ec680558d88 100644
--- a/src/backend/access/gist/gistscan.c
+++ b/src/backend/access/gist/gistscan.c
@@ -1,11 +1,11 @@
/*-------------------------------------------------------------------------
*
* gistscan.c--
- * routines to manage scans on index relations
+ * routines to manage scans on index relations
*
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/access/gist/gistscan.c,v 1.7 1995/06/14 00:10:05 jolly Exp
+ * /usr/local/devel/pglite/cvs/src/backend/access/gist/gistscan.c,v 1.7 1995/06/14 00:10:05 jolly Exp
*
*-------------------------------------------------------------------------
*/
@@ -18,375 +18,411 @@
#include <access/rtree.h>
#include <storage/bufmgr.h>
#include <access/giststrat.h>
-#include <storage/lmgr.h>
+#include <storage/lmgr.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
/* routines defined and used here */
-static void gistregscan(IndexScanDesc s);
-static void gistdropscan(IndexScanDesc s);
-static void gistadjone(IndexScanDesc s, int op, BlockNumber blkno,
- OffsetNumber offnum);
-static void adjuststack(GISTSTACK *stk, BlockNumber blkno,
+static void gistregscan(IndexScanDesc s);
+static void gistdropscan(IndexScanDesc s);
+static void
+gistadjone(IndexScanDesc s, int op, BlockNumber blkno,
+ OffsetNumber offnum);
+static void
+adjuststack(GISTSTACK * stk, BlockNumber blkno,
OffsetNumber offnum);
-static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
- int op, BlockNumber blkno, OffsetNumber offnum);
+static void
+adjustiptr(IndexScanDesc s, ItemPointer iptr,
+ int op, BlockNumber blkno, OffsetNumber offnum);
/*
- * Whenever we start a GiST scan in a backend, we register it in private
- * space. Then if the GiST index gets updated, we check all registered
- * scans and adjust them if the tuple they point at got moved by the
- * update. We only need to do this in private space, because when we update
- * an GiST we have a write lock on the tree, so no other process can have
- * any locks at all on it. A single transaction can have write and read
- * locks on the same object, so that's why we need to handle this case.
+ * Whenever we start a GiST scan in a backend, we register it in private
+ * space. Then if the GiST index gets updated, we check all registered
+ * scans and adjust them if the tuple they point at got moved by the
+ * update. We only need to do this in private space, because when we update
+ * an GiST we have a write lock on the tree, so no other process can have
+ * any locks at all on it. A single transaction can have write and read
+ * locks on the same object, so that's why we need to handle this case.
*/
-typedef struct GISTScanListData {
- IndexScanDesc gsl_scan;
- struct GISTScanListData *gsl_next;
-} GISTScanListData;
+typedef struct GISTScanListData
+{
+ IndexScanDesc gsl_scan;
+ struct GISTScanListData *gsl_next;
+} GISTScanListData;
-typedef GISTScanListData *GISTScanList;
+typedef GISTScanListData *GISTScanList;
/* pointer to list of local scans on GiSTs */
static GISTScanList GISTScans = (GISTScanList) NULL;
-
+
IndexScanDesc
gistbeginscan(Relation r,
- bool fromEnd,
- uint16 nkeys,
- ScanKey key)
+ bool fromEnd,
+ uint16 nkeys,
+ ScanKey key)
{
- IndexScanDesc s;
-
- RelationSetLockForRead(r);
- s = RelationGetIndexScan(r, fromEnd, nkeys, key);
- gistregscan(s);
-
- return (s);
+ IndexScanDesc s;
+
+ RelationSetLockForRead(r);
+ s = RelationGetIndexScan(r, fromEnd, nkeys, key);
+ gistregscan(s);
+
+ return (s);
}
void
gistrescan(IndexScanDesc s, bool fromEnd, ScanKey key)
{
- GISTScanOpaque p;
- int i;
-
- if (!IndexScanIsValid(s)) {
- elog(WARN, "gistrescan: invalid scan.");
- return;
- }
-
- /*
- * Clear all the pointers.
- */
-
- ItemPointerSetInvalid(&s->previousItemData);
- ItemPointerSetInvalid(&s->currentItemData);
- ItemPointerSetInvalid(&s->nextItemData);
- ItemPointerSetInvalid(&s->previousMarkData);
- ItemPointerSetInvalid(&s->currentMarkData);
- ItemPointerSetInvalid(&s->nextMarkData);
-
- /*
- * Set flags.
- */
- if (RelationGetNumberOfBlocks(s->relation) == 0) {
- s->flags = ScanUnmarked;
- } else if (fromEnd) {
- s->flags = ScanUnmarked | ScanUncheckedPrevious;
- } else {
- s->flags = ScanUnmarked | ScanUncheckedNext;
- }
-
- s->scanFromEnd = fromEnd;
-
- if (s->numberOfKeys > 0) {
- memmove(s->keyData,
- key,
- s->numberOfKeys * sizeof(ScanKeyData));
- }
-
- p = (GISTScanOpaque) s->opaque;
- if (p != (GISTScanOpaque) NULL) {
- gistfreestack(p->s_stack);
- gistfreestack(p->s_markstk);
- p->s_stack = p->s_markstk = (GISTSTACK *) NULL;
- p->s_flags = 0x0;
- for (i = 0; i < s->numberOfKeys; i++)
+ GISTScanOpaque p;
+ int i;
+
+ if (!IndexScanIsValid(s))
{
- s->keyData[i].sk_procedure
- = RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
- s->keyData[i].sk_procedure);
- s->keyData[i].sk_func = p->giststate->consistentFn;
+ elog(WARN, "gistrescan: invalid scan.");
+ return;
+ }
+
+ /*
+ * Clear all the pointers.
+ */
+
+ ItemPointerSetInvalid(&s->previousItemData);
+ ItemPointerSetInvalid(&s->currentItemData);
+ ItemPointerSetInvalid(&s->nextItemData);
+ ItemPointerSetInvalid(&s->previousMarkData);
+ ItemPointerSetInvalid(&s->currentMarkData);
+ ItemPointerSetInvalid(&s->nextMarkData);
+
+ /*
+ * Set flags.
+ */
+ if (RelationGetNumberOfBlocks(s->relation) == 0)
+ {
+ s->flags = ScanUnmarked;
+ }
+ else if (fromEnd)
+ {
+ s->flags = ScanUnmarked | ScanUncheckedPrevious;
+ }
+ else
+ {
+ s->flags = ScanUnmarked | ScanUncheckedNext;
+ }
+
+ s->scanFromEnd = fromEnd;
+
+ if (s->numberOfKeys > 0)
+ {
+ memmove(s->keyData,
+ key,
+ s->numberOfKeys * sizeof(ScanKeyData));
+ }
+
+ p = (GISTScanOpaque) s->opaque;
+ if (p != (GISTScanOpaque) NULL)
+ {
+ gistfreestack(p->s_stack);
+ gistfreestack(p->s_markstk);
+ p->s_stack = p->s_markstk = (GISTSTACK *) NULL;
+ p->s_flags = 0x0;
+ for (i = 0; i < s->numberOfKeys; i++)
+ {
+ s->keyData[i].sk_procedure
+ = RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
+ s->keyData[i].sk_procedure);
+ s->keyData[i].sk_func = p->giststate->consistentFn;
+ }
+ }
+ else
+ {
+ /* initialize opaque data */
+ p = (GISTScanOpaque) palloc(sizeof(GISTScanOpaqueData));
+ p->s_stack = p->s_markstk = (GISTSTACK *) NULL;
+ p->s_flags = 0x0;
+ s->opaque = p;
+ p->giststate = (GISTSTATE *) palloc(sizeof(GISTSTATE));
+ initGISTstate(p->giststate, s->relation);
+ if (s->numberOfKeys > 0)
+
+ /*
+ * * Play games here with the scan key to use the Consistent *
+ * function for all comparisons: * 1) the sk_procedure field
+ * will now be used to hold the * strategy number * 2) the
+ * sk_func field will point to the Consistent function
+ */
+ for (i = 0; i < s->numberOfKeys; i++)
+ {
+
+ /*
+ * s->keyData[i].sk_procedure =
+ * index_getprocid(s->relation, 1, GIST_CONSISTENT_PROC);
+ */
+ s->keyData[i].sk_procedure
+ = RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
+ s->keyData[i].sk_procedure);
+ s->keyData[i].sk_func = p->giststate->consistentFn;
+ }
}
- } else {
- /* initialize opaque data */
- p = (GISTScanOpaque) palloc(sizeof(GISTScanOpaqueData));
- p->s_stack = p->s_markstk = (GISTSTACK *) NULL;
- p->s_flags = 0x0;
- s->opaque = p;
- p->giststate = (GISTSTATE *)palloc(sizeof(GISTSTATE));
- initGISTstate(p->giststate, s->relation);
- if (s->numberOfKeys > 0)
- /*
- ** Play games here with the scan key to use the Consistent
- ** function for all comparisons:
- ** 1) the sk_procedure field will now be used to hold the
- ** strategy number
- ** 2) the sk_func field will point to the Consistent function
- */
- for (i = 0; i < s->numberOfKeys; i++) {
- /* s->keyData[i].sk_procedure
- = index_getprocid(s->relation, 1, GIST_CONSISTENT_PROC); */
- s->keyData[i].sk_procedure
- = RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
- s->keyData[i].sk_procedure);
- s->keyData[i].sk_func = p->giststate->consistentFn;
- }
- }
}
void
gistmarkpos(IndexScanDesc s)
{
- GISTScanOpaque p;
- GISTSTACK *o, *n, *tmp;
-
- s->currentMarkData = s->currentItemData;
- p = (GISTScanOpaque) s->opaque;
- if (p->s_flags & GS_CURBEFORE)
- p->s_flags |= GS_MRKBEFORE;
- else
- p->s_flags &= ~GS_MRKBEFORE;
-
- o = (GISTSTACK *) NULL;
- n = p->s_stack;
-
- /* copy the parent stack from the current item data */
- while (n != (GISTSTACK *) NULL) {
- tmp = (GISTSTACK *) palloc(sizeof(GISTSTACK));
- tmp->gs_child = n->gs_child;
- tmp->gs_blk = n->gs_blk;
- tmp->gs_parent = o;
- o = tmp;
- n = n->gs_parent;
- }
-
- gistfreestack(p->s_markstk);
- p->s_markstk = o;
+ GISTScanOpaque p;
+ GISTSTACK *o,
+ *n,
+ *tmp;
+
+ s->currentMarkData = s->currentItemData;
+ p = (GISTScanOpaque) s->opaque;
+ if (p->s_flags & GS_CURBEFORE)
+ p->s_flags |= GS_MRKBEFORE;
+ else
+ p->s_flags &= ~GS_MRKBEFORE;
+
+ o = (GISTSTACK *) NULL;
+ n = p->s_stack;
+
+ /* copy the parent stack from the current item data */
+ while (n != (GISTSTACK *) NULL)
+ {
+ tmp = (GISTSTACK *) palloc(sizeof(GISTSTACK));
+ tmp->gs_child = n->gs_child;
+ tmp->gs_blk = n->gs_blk;
+ tmp->gs_parent = o;
+ o = tmp;
+ n = n->gs_parent;
+ }
+
+ gistfreestack(p->s_markstk);
+ p->s_markstk = o;
}
void
gistrestrpos(IndexScanDesc s)
{
- GISTScanOpaque p;
- GISTSTACK *o, *n, *tmp;
-
- s->currentItemData = s->currentMarkData;
- p = (GISTScanOpaque) s->opaque;
- if (p->s_flags & GS_MRKBEFORE)
- p->s_flags |= GS_CURBEFORE;
- else
- p->s_flags &= ~GS_CURBEFORE;
-
- o = (GISTSTACK *) NULL;
- n = p->s_markstk;
-
- /* copy the parent stack from the current item data */
- while (n != (GISTSTACK *) NULL) {
- tmp = (GISTSTACK *) palloc(sizeof(GISTSTACK));
- tmp->gs_child = n->gs_child;
- tmp->gs_blk = n->gs_blk;
- tmp->gs_parent = o;
- o = tmp;
- n = n->gs_parent;
- }
-
- gistfreestack(p->s_stack);
- p->s_stack = o;
+ GISTScanOpaque p;
+ GISTSTACK *o,
+ *n,
+ *tmp;
+
+ s->currentItemData = s->currentMarkData;
+ p = (GISTScanOpaque) s->opaque;
+ if (p->s_flags & GS_MRKBEFORE)
+ p->s_flags |= GS_CURBEFORE;
+ else
+ p->s_flags &= ~GS_CURBEFORE;
+
+ o = (GISTSTACK *) NULL;
+ n = p->s_markstk;
+
+ /* copy the parent stack from the current item data */
+ while (n != (GISTSTACK *) NULL)
+ {
+ tmp = (GISTSTACK *) palloc(sizeof(GISTSTACK));
+ tmp->gs_child = n->gs_child;
+ tmp->gs_blk = n->gs_blk;
+ tmp->gs_parent = o;
+ o = tmp;
+ n = n->gs_parent;
+ }
+
+ gistfreestack(p->s_stack);
+ p->s_stack = o;
}
void
gistendscan(IndexScanDesc s)
{
- GISTScanOpaque p;
-
- p = (GISTScanOpaque) s->opaque;
-
- if (p != (GISTScanOpaque) NULL) {
- gistfreestack(p->s_stack);
- gistfreestack(p->s_markstk);
- pfree (s->opaque);
- }
-
- gistdropscan(s);
- /* XXX don't unset read lock -- two-phase locking */
+ GISTScanOpaque p;
+
+ p = (GISTScanOpaque) s->opaque;
+
+ if (p != (GISTScanOpaque) NULL)
+ {
+ gistfreestack(p->s_stack);
+ gistfreestack(p->s_markstk);
+ pfree(s->opaque);
+ }
+
+ gistdropscan(s);
+ /* XXX don't unset read lock -- two-phase locking */
}
static void
gistregscan(IndexScanDesc s)
{
- GISTScanList l;
-
- l = (GISTScanList) palloc(sizeof(GISTScanListData));
- l->gsl_scan = s;
- l->gsl_next = GISTScans;
- GISTScans = l;
+ GISTScanList l;
+
+ l = (GISTScanList) palloc(sizeof(GISTScanListData));
+ l->gsl_scan = s;
+ l->gsl_next = GISTScans;
+ GISTScans = l;
}
static void
gistdropscan(IndexScanDesc s)
{
- GISTScanList l;
- GISTScanList prev;
-
- prev = (GISTScanList) NULL;
-
- for (l = GISTScans;
- l != (GISTScanList) NULL && l->gsl_scan != s;
- l = l->gsl_next) {
- prev = l;
- }
-
- if (l == (GISTScanList) NULL)
- elog(WARN, "GiST scan list corrupted -- cannot find 0x%lx", s);
-
- if (prev == (GISTScanList) NULL)
- GISTScans = l->gsl_next;
- else
- prev->gsl_next = l->gsl_next;
-
- pfree(l);
+ GISTScanList l;
+ GISTScanList prev;
+
+ prev = (GISTScanList) NULL;
+
+ for (l = GISTScans;
+ l != (GISTScanList) NULL && l->gsl_scan != s;
+ l = l->gsl_next)
+ {
+ prev = l;
+ }
+
+ if (l == (GISTScanList) NULL)
+ elog(WARN, "GiST scan list corrupted -- cannot find 0x%lx", s);
+
+ if (prev == (GISTScanList) NULL)
+ GISTScans = l->gsl_next;
+ else
+ prev->gsl_next = l->gsl_next;
+
+ pfree(l);
}
void
gistadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum)
{
- GISTScanList l;
- Oid relid;
-
- relid = r->rd_id;
- for (l = GISTScans; l != (GISTScanList) NULL; l = l->gsl_next) {
- if (l->gsl_scan->relation->rd_id == relid)
- gistadjone(l->gsl_scan, op, blkno, offnum);
- }
+ GISTScanList l;
+ Oid relid;
+
+ relid = r->rd_id;
+ for (l = GISTScans; l != (GISTScanList) NULL; l = l->gsl_next)
+ {
+ if (l->gsl_scan->relation->rd_id == relid)
+ gistadjone(l->gsl_scan, op, blkno, offnum);
+ }
}
/*
- * gistadjone() -- adjust one scan for update.
+ * gistadjone() -- adjust one scan for update.
*
- * By here, the scan passed in is on a modified relation. Op tells
- * us what the modification is, and blkno and offind tell us what
- * block and offset index were affected. This routine checks the
- * current and marked positions, and the current and marked stacks,
- * to see if any stored location needs to be changed because of the
- * update. If so, we make the change here.
+ * By here, the scan passed in is on a modified relation. Op tells
+ * us what the modification is, and blkno and offind tell us what
+ * block and offset index were affected. This routine checks the
+ * current and marked positions, and the current and marked stacks,
+ * to see if any stored location needs to be changed because of the
+ * update. If so, we make the change here.
*/
static void
gistadjone(IndexScanDesc s,
- int op,
- BlockNumber blkno,
- OffsetNumber offnum)
+ int op,
+ BlockNumber blkno,
+ OffsetNumber offnum)
{
- GISTScanOpaque so;
-
- adjustiptr(s, &(s->currentItemData), op, blkno, offnum);
- adjustiptr(s, &(s->currentMarkData), op, blkno, offnum);
-
- so = (GISTScanOpaque) s->opaque;
-
- if (op == GISTOP_SPLIT) {
- adjuststack(so->s_stack, blkno, offnum);
- adjuststack(so->s_markstk, blkno, offnum);
- }
+ GISTScanOpaque so;
+
+ adjustiptr(s, &(s->currentItemData), op, blkno, offnum);
+ adjustiptr(s, &(s->currentMarkData), op, blkno, offnum);
+
+ so = (GISTScanOpaque) s->opaque;
+
+ if (op == GISTOP_SPLIT)
+ {
+ adjuststack(so->s_stack, blkno, offnum);
+ adjuststack(so->s_markstk, blkno, offnum);
+ }
}
/*
- * adjustiptr() -- adjust current and marked item pointers in the scan
+ * adjustiptr() -- adjust current and marked item pointers in the scan
*
- * Depending on the type of update and the place it happened, we
- * need to do nothing, to back up one record, or to start over on
- * the same page.
+ * Depending on the type of update and the place it happened, we
+ * need to do nothing, to back up one record, or to start over on
+ * the same page.
*/
static void
adjustiptr(IndexScanDesc s,
- ItemPointer iptr,
- int op,
- BlockNumber blkno,
- OffsetNumber offnum)
+ ItemPointer iptr,
+ int op,
+ BlockNumber blkno,
+ OffsetNumber offnum)
{
- OffsetNumber curoff;
- GISTScanOpaque so;
-
- if (ItemPointerIsValid(iptr)) {
- if (ItemPointerGetBlockNumber(iptr) == blkno) {
- curoff = ItemPointerGetOffsetNumber(iptr);
- so = (GISTScanOpaque) s->opaque;
-
- switch (op) {
- case GISTOP_DEL:
- /* back up one if we need to */
- if (curoff >= offnum) {
-
- if (curoff > FirstOffsetNumber) {
- /* just adjust the item pointer */
- ItemPointerSet(iptr, blkno, OffsetNumberPrev(curoff));
- } else {
- /* remember that we're before the current tuple */
- ItemPointerSet(iptr, blkno, FirstOffsetNumber);
- if (iptr == &(s->currentItemData))
- so->s_flags |= GS_CURBEFORE;
- else
- so->s_flags |= GS_MRKBEFORE;
- }
+ OffsetNumber curoff;
+ GISTScanOpaque so;
+
+ if (ItemPointerIsValid(iptr))
+ {
+ if (ItemPointerGetBlockNumber(iptr) == blkno)
+ {
+ curoff = ItemPointerGetOffsetNumber(iptr);
+ so = (GISTScanOpaque) s->opaque;
+
+ switch (op)
+ {
+ case GISTOP_DEL:
+ /* back up one if we need to */
+ if (curoff >= offnum)
+ {
+
+ if (curoff > FirstOffsetNumber)
+ {
+ /* just adjust the item pointer */
+ ItemPointerSet(iptr, blkno, OffsetNumberPrev(curoff));
+ }
+ else
+ {
+ /* remember that we're before the current tuple */
+ ItemPointerSet(iptr, blkno, FirstOffsetNumber);
+ if (iptr == &(s->currentItemData))
+ so->s_flags |= GS_CURBEFORE;
+ else
+ so->s_flags |= GS_MRKBEFORE;
+ }
+ }
+ break;
+
+ case GISTOP_SPLIT:
+ /* back to start of page on split */
+ ItemPointerSet(iptr, blkno, FirstOffsetNumber);
+ if (iptr == &(s->currentItemData))
+ so->s_flags &= ~GS_CURBEFORE;
+ else
+ so->s_flags &= ~GS_MRKBEFORE;
+ break;
+
+ default:
+ elog(WARN, "Bad operation in GiST scan adjust: %d", op);
+ }
}
- break;
-
- case GISTOP_SPLIT:
- /* back to start of page on split */
- ItemPointerSet(iptr, blkno, FirstOffsetNumber);
- if (iptr == &(s->currentItemData))
- so->s_flags &= ~GS_CURBEFORE;
- else
- so->s_flags &= ~GS_MRKBEFORE;
- break;
-
- default:
- elog(WARN, "Bad operation in GiST scan adjust: %d", op);
- }
}
- }
}
/*
- * adjuststack() -- adjust the supplied stack for a split on a page in
- * the index we're scanning.
+ * adjuststack() -- adjust the supplied stack for a split on a page in
+ * the index we're scanning.
*
- * If a page on our parent stack has split, we need to back up to the
- * beginning of the page and rescan it. The reason for this is that
- * the split algorithm for GiSTs doesn't order tuples in any useful
- * way on a single page. This means on that a split, we may wind up
- * looking at some heap tuples more than once. This is handled in the
- * access method update code for heaps; if we've modified the tuple we
- * are looking at already in this transaction, we ignore the update
- * request.
+ * If a page on our parent stack has split, we need to back up to the
+ * beginning of the page and rescan it. The reason for this is that
+ * the split algorithm for GiSTs doesn't order tuples in any useful
+ * way on a single page. This means on that a split, we may wind up
+ * looking at some heap tuples more than once. This is handled in the
+ * access method update code for heaps; if we've modified the tuple we
+ * are looking at already in this transaction, we ignore the update
+ * request.
*/
/*ARGSUSED*/
static void
-adjuststack(GISTSTACK *stk,
- BlockNumber blkno,
- OffsetNumber offnum)
+adjuststack(GISTSTACK * stk,
+ BlockNumber blkno,
+ OffsetNumber offnum)
{
- while (stk != (GISTSTACK *) NULL) {
- if (stk->gs_blk == blkno)
- stk->gs_child = FirstOffsetNumber;
-
- stk = stk->gs_parent;
- }
+ while (stk != (GISTSTACK *) NULL)
+ {
+ if (stk->gs_blk == blkno)
+ stk->gs_child = FirstOffsetNumber;
+
+ stk = stk->gs_parent;
+ }
}
diff --git a/src/backend/access/gist/giststrat.c b/src/backend/access/gist/giststrat.c
index 8c78ccec3ae..c7a6f9ff784 100644
--- a/src/backend/access/gist/giststrat.c
+++ b/src/backend/access/gist/giststrat.c
@@ -1,116 +1,117 @@
/*-------------------------------------------------------------------------
*
* giststrat.c--
- * strategy map data for GiSTs.
+ * strategy map data for GiSTs.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/access/gist/giststrat.c,v 1.4 1995/06/14 00:10:05 jolly Exp
+ * /usr/local/devel/pglite/cvs/src/backend/access/gist/giststrat.c,v 1.4 1995/06/14 00:10:05 jolly Exp
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <access/gist.h>
#include <access/istrat.h>
/*
- * Note: negate, commute, and negatecommute all assume that operators are
- * ordered as follows in the strategy map:
+ * Note: negate, commute, and negatecommute all assume that operators are
+ * ordered as follows in the strategy map:
*
- * contains, contained-by
+ * contains, contained-by
*
- * The negate, commute, and negatecommute arrays are used by the planner
- * to plan indexed scans over data that appears in the qualificiation in
- * a boolean negation, or whose operands appear in the wrong order. For
- * example, if the operator "<%" means "contains", and the user says
+ * The negate, commute, and negatecommute arrays are used by the planner
+ * to plan indexed scans over data that appears in the qualificiation in
+ * a boolean negation, or whose operands appear in the wrong order. For
+ * example, if the operator "<%" means "contains", and the user says
*
- * where not rel.box <% "(10,10,20,20)"::box
+ * where not rel.box <% "(10,10,20,20)"::box
*
- * the planner can plan an index scan by noting that GiST indices have
- * an operator in their operator class for negating <%.
+ * the planner can plan an index scan by noting that GiST indices have
+ * an operator in their operator class for negating <%.
*
- * Similarly, if the user says something like
+ * Similarly, if the user says something like
*
- * where "(10,10,20,20)"::box <% rel.box
+ * where "(10,10,20,20)"::box <% rel.box
*
- * the planner can see that the GiST index on rel.box has an operator in
- * its opclass for commuting <%, and plan the scan using that operator.
- * This added complexity in the access methods makes the planner a lot easier
- * to write.
+ * the planner can see that the GiST index on rel.box has an operator in
+ * its opclass for commuting <%, and plan the scan using that operator.
+ * This added complexity in the access methods makes the planner a lot easier
+ * to write.
*/
/* if a op b, what operator tells us if (not a op b)? */
-static StrategyNumber GISTNegate[GISTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
- };
+static StrategyNumber GISTNegate[GISTNStrategies] = {
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy
+};
/* if a op_1 b, what is the operator op_2 such that b op_2 a? */
-static StrategyNumber GISTCommute[GISTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
- };
+static StrategyNumber GISTCommute[GISTNStrategies] = {
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy
+};
/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */
-static StrategyNumber GISTNegateCommute[GISTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
- };
+static StrategyNumber GISTNegateCommute[GISTNStrategies] = {
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy
+};
/*
- * GiSTs do not currently support TermData (see rtree/rtstrat.c for
+ * GiSTs do not currently support TermData (see rtree/rtstrat.c for
* discussion of
* TermData) -- such logic must be encoded in the user's Consistent function.
*/
/*
- * If you were sufficiently attentive to detail, you would go through
- * the ExpressionData pain above for every one of the strategies
- * we defined. I am not. Now we declare the StrategyEvaluationData
- * structure that gets shipped around to help the planner and the access
- * method decide what sort of scan it should do, based on (a) what the
- * user asked for, (b) what operators are defined for a particular opclass,
- * and (c) the reams of information we supplied above.
+ * If you were sufficiently attentive to detail, you would go through
+ * the ExpressionData pain above for every one of the strategies
+ * we defined. I am not. Now we declare the StrategyEvaluationData
+ * structure that gets shipped around to help the planner and the access
+ * method decide what sort of scan it should do, based on (a) what the
+ * user asked for, (b) what operators are defined for a particular opclass,
+ * and (c) the reams of information we supplied above.
*
- * The idea of all of this initialized data is to make life easier on the
- * user when he defines a new operator class to use this access method.
- * By filling in all the data, we let him get away with leaving holes in his
- * operator class, and still let him use the index. The added complexity
- * in the access methods just isn't worth the trouble, though.
+ * The idea of all of this initialized data is to make life easier on the
+ * user when he defines a new operator class to use this access method.
+ * By filling in all the data, we let him get away with leaving holes in his
+ * operator class, and still let him use the index. The added complexity
+ * in the access methods just isn't worth the trouble, though.
*/
static StrategyEvaluationData GISTEvaluationData = {
- GISTNStrategies, /* # of strategies */
- (StrategyTransformMap) GISTNegate, /* how to do (not qual) */
- (StrategyTransformMap) GISTCommute, /* how to swap operands */
- (StrategyTransformMap) GISTNegateCommute, /* how to do both */
- { NULL }
+ GISTNStrategies, /* # of strategies */
+ (StrategyTransformMap) GISTNegate, /* how to do (not qual) */
+ (StrategyTransformMap) GISTCommute, /* how to swap operands */
+ (StrategyTransformMap) GISTNegateCommute, /* how to do both */
+ {NULL}
};
StrategyNumber
RelationGetGISTStrategy(Relation r,
- AttrNumber attnum,
- RegProcedure proc)
+ AttrNumber attnum,
+ RegProcedure proc)
{
- return (RelationGetStrategy(r, attnum, &GISTEvaluationData, proc));
+ return (RelationGetStrategy(r, attnum, &GISTEvaluationData, proc));
}
#ifdef NOT_USED
bool
RelationInvokeGISTStrategy(Relation r,
- AttrNumber attnum,
- StrategyNumber s,
- Datum left,
- Datum right)
+ AttrNumber attnum,
+ StrategyNumber s,
+ Datum left,
+ Datum right)
{
- return (RelationInvokeStrategy(r, &GISTEvaluationData, attnum, s,
- left, right));
+ return (RelationInvokeStrategy(r, &GISTEvaluationData, attnum, s,
+ left, right));
}
+
#endif
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index 89f81fc56a5..e13539c4ad9 100644
--- a/src/backend/access/hash/hash.c
+++ b/src/backend/access/hash/hash.c
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* hash.c--
- * Implementation of Margo Seltzer's Hashing package for postgres.
+ * Implementation of Margo Seltzer's Hashing package for postgres.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.12 1997/01/10 09:46:13 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.13 1997/09/07 04:37:49 momjian Exp $
*
* NOTES
- * This file contains only the public interface routines.
+ * This file contains only the public interface routines.
*
*-------------------------------------------------------------------------
*/
@@ -26,452 +26,483 @@
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-bool BuildingHash = false;
+bool BuildingHash = false;
/*
- * hashbuild() -- build a new hash index.
+ * hashbuild() -- build a new hash index.
*
- * We use a global variable to record the fact that we're creating
- * a new index. This is used to avoid high-concurrency locking,
- * since the index won't be visible until this transaction commits
- * and since building is guaranteed to be single-threaded.
+ * We use a global variable to record the fact that we're creating
+ * a new index. This is used to avoid high-concurrency locking,
+ * since the index won't be visible until this transaction commits
+ * and since building is guaranteed to be single-threaded.
*/
void
hashbuild(Relation heap,
- Relation index,
- int natts,
- AttrNumber *attnum,
- IndexStrategy istrat,
- uint16 pcount,
- Datum *params,
- FuncIndexInfo *finfo,
- PredInfo *predInfo)
+ Relation index,
+ int natts,
+ AttrNumber * attnum,
+ IndexStrategy istrat,
+ uint16 pcount,
+ Datum * params,
+ FuncIndexInfo * finfo,
+ PredInfo * predInfo)
{
- HeapScanDesc hscan;
- Buffer buffer;
- HeapTuple htup;
- IndexTuple itup;
- TupleDesc htupdesc, itupdesc;
- Datum *attdata;
- bool *nulls;
- InsertIndexResult res;
- int nhtups, nitups;
- int i;
- HashItem hitem;
+ HeapScanDesc hscan;
+ Buffer buffer;
+ HeapTuple htup;
+ IndexTuple itup;
+ TupleDesc htupdesc,
+ itupdesc;
+ Datum *attdata;
+ bool *nulls;
+ InsertIndexResult res;
+ int nhtups,
+ nitups;
+ int i;
+ HashItem hitem;
+
#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext;
- TupleTable tupleTable;
- TupleTableSlot *slot;
+ ExprContext *econtext;
+ TupleTable tupleTable;
+ TupleTableSlot *slot;
+
#endif
- Oid hrelid, irelid;
- Node *pred, *oldPred;
-
- /* note that this is a new btree */
- BuildingHash = true;
-
- pred = predInfo->pred;
- oldPred = predInfo->oldPred;
-
- /* initialize the hash index metadata page (if this is a new index) */
- if (oldPred == NULL)
- _hash_metapinit(index);
-
- /* get tuple descriptors for heap and index relations */
- htupdesc = RelationGetTupleDescriptor(heap);
- itupdesc = RelationGetTupleDescriptor(index);
-
- /* get space for data items that'll appear in the index tuple */
- attdata = (Datum *) palloc(natts * sizeof(Datum));
- nulls = (bool *) palloc(natts * sizeof(bool));
-
- /*
- * If this is a predicate (partial) index, we will need to evaluate the
- * predicate using ExecQual, which requires the current tuple to be in a
- * slot of a TupleTable. In addition, ExecQual must have an ExprContext
- * referring to that slot. Here, we initialize dummy TupleTable and
- * ExprContext objects for this purpose. --Nels, Feb '92
- */
+ Oid hrelid,
+ irelid;
+ Node *pred,
+ *oldPred;
+
+ /* note that this is a new btree */
+ BuildingHash = true;
+
+ pred = predInfo->pred;
+ oldPred = predInfo->oldPred;
+
+ /* initialize the hash index metadata page (if this is a new index) */
+ if (oldPred == NULL)
+ _hash_metapinit(index);
+
+ /* get tuple descriptors for heap and index relations */
+ htupdesc = RelationGetTupleDescriptor(heap);
+ itupdesc = RelationGetTupleDescriptor(index);
+
+ /* get space for data items that'll appear in the index tuple */
+ attdata = (Datum *) palloc(natts * sizeof(Datum));
+ nulls = (bool *) palloc(natts * sizeof(bool));
+
+ /*
+ * If this is a predicate (partial) index, we will need to evaluate
+ * the predicate using ExecQual, which requires the current tuple to
+ * be in a slot of a TupleTable. In addition, ExecQual must have an
+ * ExprContext referring to that slot. Here, we initialize dummy
+ * TupleTable and ExprContext objects for this purpose. --Nels, Feb
+ * '92
+ */
#ifndef OMIT_PARTIAL_INDEX
- if (pred != NULL || oldPred != NULL) {
- tupleTable = ExecCreateTupleTable(1);
- slot = ExecAllocTableSlot(tupleTable);
- econtext = makeNode(ExprContext);
- FillDummyExprContext(econtext, slot, htupdesc, buffer);
- }
- else /* quiet the compiler */
+ if (pred != NULL || oldPred != NULL)
+ {
+ tupleTable = ExecCreateTupleTable(1);
+ slot = ExecAllocTableSlot(tupleTable);
+ econtext = makeNode(ExprContext);
+ FillDummyExprContext(econtext, slot, htupdesc, buffer);
+ }
+ else
+/* quiet the compiler */
{
econtext = NULL;
tupleTable = 0;
slot = 0;
}
-#endif /* OMIT_PARTIAL_INDEX */
-
- /* start a heap scan */
- hscan = heap_beginscan(heap, 0, NowTimeQual, 0, (ScanKey) NULL);
- htup = heap_getnext(hscan, 0, &buffer);
-
- /* build the index */
- nhtups = nitups = 0;
-
- for (; HeapTupleIsValid(htup); htup = heap_getnext(hscan, 0, &buffer)) {
-
- nhtups++;
-
- /*
- * If oldPred != NULL, this is an EXTEND INDEX command, so skip
- * this tuple if it was already in the existing partial index
- */
- if (oldPred != NULL) {
- /*SetSlotContents(slot, htup); */
+#endif /* OMIT_PARTIAL_INDEX */
+
+ /* start a heap scan */
+ hscan = heap_beginscan(heap, 0, NowTimeQual, 0, (ScanKey) NULL);
+ htup = heap_getnext(hscan, 0, &buffer);
+
+ /* build the index */
+ nhtups = nitups = 0;
+
+ for (; HeapTupleIsValid(htup); htup = heap_getnext(hscan, 0, &buffer))
+ {
+
+ nhtups++;
+
+ /*
+ * If oldPred != NULL, this is an EXTEND INDEX command, so skip
+ * this tuple if it was already in the existing partial index
+ */
+ if (oldPred != NULL)
+ {
+ /* SetSlotContents(slot, htup); */
#ifndef OMIT_PARTIAL_INDEX
- slot->val = htup;
- if (ExecQual((List*)oldPred, econtext) == true) {
+ slot->val = htup;
+ if (ExecQual((List *) oldPred, econtext) == true)
+ {
+ nitups++;
+ continue;
+ }
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+
+ /*
+ * Skip this tuple if it doesn't satisfy the partial-index
+ * predicate
+ */
+ if (pred != NULL)
+ {
+#ifndef OMIT_PARTIAL_INDEX
+ /* SetSlotContents(slot, htup); */
+ slot->val = htup;
+ if (ExecQual((List *) pred, econtext) == false)
+ continue;
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+
nitups++;
- continue;
- }
-#endif /* OMIT_PARTIAL_INDEX */
+
+ /*
+ * For the current heap tuple, extract all the attributes we use
+ * in this index, and note which are null.
+ */
+ for (i = 1; i <= natts; i++)
+ {
+ int attoff;
+ bool attnull;
+
+ /*
+ * Offsets are from the start of the tuple, and are
+ * zero-based; indices are one-based. The next call returns i
+ * - 1. That's data hiding for you.
+ */
+
+ /* attoff = i - 1 */
+ attoff = AttrNumberGetAttrOffset(i);
+
+ /*
+ * below, attdata[attoff] set to equal some datum & attnull is
+ * changed to indicate whether or not the attribute is null
+ * for this tuple
+ */
+ attdata[attoff] = GetIndexValue(htup,
+ htupdesc,
+ attoff,
+ attnum,
+ finfo,
+ &attnull,
+ buffer);
+ nulls[attoff] = (attnull ? 'n' : ' ');
+ }
+
+ /* form an index tuple and point it at the heap tuple */
+ itup = index_formtuple(itupdesc, attdata, nulls);
+
+ /*
+ * If the single index key is null, we don't insert it into the
+ * index. Hash tables support scans on '='. Relational algebra
+ * says that A = B returns null if either A or B is null. This
+ * means that no qualification used in an index scan could ever
+ * return true on a null attribute. It also means that indices
+ * can't be used by ISNULL or NOTNULL scans, but that's an
+ * artifact of the strategy map architecture chosen in 1986, not
+ * of the way nulls are handled here.
+ */
+
+ if (itup->t_info & INDEX_NULL_MASK)
+ {
+ pfree(itup);
+ continue;
+ }
+
+ itup->t_tid = htup->t_ctid;
+ hitem = _hash_formitem(itup);
+ res = _hash_doinsert(index, hitem);
+ pfree(hitem);
+ pfree(itup);
+ pfree(res);
}
-
- /* Skip this tuple if it doesn't satisfy the partial-index predicate */
- if (pred != NULL) {
+
+ /* okay, all heap tuples are indexed */
+ heap_endscan(hscan);
+
+ if (pred != NULL || oldPred != NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- /*SetSlotContents(slot, htup); */
- slot->val = htup;
- if (ExecQual((List*)pred, econtext) == false)
- continue;
-#endif /* OMIT_PARTIAL_INDEX */
-}
-
- nitups++;
-
- /*
- * For the current heap tuple, extract all the attributes
- * we use in this index, and note which are null.
- */
- for (i = 1; i <= natts; i++) {
- int attoff;
- bool attnull;
-
- /*
- * Offsets are from the start of the tuple, and are
- * zero-based; indices are one-based. The next call
- * returns i - 1. That's data hiding for you.
- */
-
- /* attoff = i - 1 */
- attoff = AttrNumberGetAttrOffset(i);
-
- /* below, attdata[attoff] set to equal some datum &
- * attnull is changed to indicate whether or not the attribute
- * is null for this tuple
- */
- attdata[attoff] = GetIndexValue(htup,
- htupdesc,
- attoff,
- attnum,
- finfo,
- &attnull,
- buffer);
- nulls[attoff] = (attnull ? 'n' : ' ');
+ ExecDestroyTupleTable(tupleTable, true);
+ pfree(econtext);
+#endif /* OMIT_PARTIAL_INDEX */
}
-
- /* form an index tuple and point it at the heap tuple */
- itup = index_formtuple(itupdesc, attdata, nulls);
-
+
/*
- * If the single index key is null, we don't insert it into
- * the index. Hash tables support scans on '='.
- * Relational algebra says that A = B
- * returns null if either A or B is null. This
- * means that no qualification used in an index scan could ever
- * return true on a null attribute. It also means that indices
- * can't be used by ISNULL or NOTNULL scans, but that's an
- * artifact of the strategy map architecture chosen in 1986, not
- * of the way nulls are handled here.
+ * 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. Finally, only update statistics during
+ * normal index definitions, not for indices on system catalogs
+ * created during bootstrap processing. We must close the relations
+ * before updatings statistics to guarantee that the relcache entries
+ * are flushed when we increment the command counter in UpdateStats().
*/
-
- if (itup->t_info & INDEX_NULL_MASK) {
- pfree(itup);
- continue;
- }
-
- itup->t_tid = htup->t_ctid;
- hitem = _hash_formitem(itup);
- res = _hash_doinsert(index, hitem);
- pfree(hitem);
- pfree(itup);
- pfree(res);
- }
-
- /* okay, all heap tuples are indexed */
- heap_endscan(hscan);
-
- if (pred != NULL || oldPred != NULL) {
-#ifndef OMIT_PARTIAL_INDEX
- ExecDestroyTupleTable(tupleTable, true);
- pfree(econtext);
-#endif /* OMIT_PARTIAL_INDEX */
- }
-
- /*
- * 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. Finally, only update statistics
- * during normal index definitions, not for indices on system catalogs
- * created during bootstrap processing. We must close the relations
- * before updatings statistics to guarantee that the relcache entries
- * are flushed when we increment the command counter in UpdateStats().
- */
- if (IsNormalProcessingMode())
+ if (IsNormalProcessingMode())
{
- hrelid = heap->rd_id;
- irelid = index->rd_id;
- heap_close(heap);
- index_close(index);
- UpdateStats(hrelid, nhtups, true);
- UpdateStats(irelid, nitups, false);
- if (oldPred != NULL) {
- if (nitups == nhtups) pred = NULL;
- UpdateIndexPredicate(irelid, oldPred, pred);
- }
+ hrelid = heap->rd_id;
+ irelid = index->rd_id;
+ heap_close(heap);
+ index_close(index);
+ UpdateStats(hrelid, nhtups, true);
+ UpdateStats(irelid, nitups, false);
+ if (oldPred != NULL)
+ {
+ if (nitups == nhtups)
+ pred = NULL;
+ UpdateIndexPredicate(irelid, oldPred, pred);
+ }
}
-
- /* be tidy */
- pfree(nulls);
- pfree(attdata);
-
- /* all done */
- BuildingHash = false;
+
+ /* be tidy */
+ pfree(nulls);
+ pfree(attdata);
+
+ /* all done */
+ BuildingHash = false;
}
/*
- * hashinsert() -- insert an index tuple into a hash table.
+ * hashinsert() -- insert an index tuple into a hash table.
*
- * Hash on the index tuple's key, find the appropriate location
- * for the new tuple, put it there, and return an InsertIndexResult
- * to the caller.
+ * Hash on the index tuple's key, find the appropriate location
+ * for the new tuple, put it there, and return an InsertIndexResult
+ * to the caller.
*/
InsertIndexResult
-hashinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
+hashinsert(Relation rel, Datum * datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
{
- HashItem hitem;
- IndexTuple itup;
- InsertIndexResult res;
-
-
- /* generate an index tuple */
- itup = index_formtuple(RelationGetTupleDescriptor(rel), datum, nulls);
- itup->t_tid = *ht_ctid;
-
- if (itup->t_info & INDEX_NULL_MASK)
- return ((InsertIndexResult) NULL);
-
- hitem = _hash_formitem(itup);
-
- res = _hash_doinsert(rel, hitem);
-
- pfree(hitem);
- pfree(itup);
-
- return (res);
+ HashItem hitem;
+ IndexTuple itup;
+ InsertIndexResult res;
+
+
+ /* generate an index tuple */
+ itup = index_formtuple(RelationGetTupleDescriptor(rel), datum, nulls);
+ itup->t_tid = *ht_ctid;
+
+ if (itup->t_info & INDEX_NULL_MASK)
+ return ((InsertIndexResult) NULL);
+
+ hitem = _hash_formitem(itup);
+
+ res = _hash_doinsert(rel, hitem);
+
+ pfree(hitem);
+ pfree(itup);
+
+ return (res);
}
/*
- * hashgettuple() -- Get the next tuple in the scan.
+ * hashgettuple() -- Get the next tuple in the scan.
*/
-char *
+char *
hashgettuple(IndexScanDesc scan, ScanDirection dir)
{
- RetrieveIndexResult res;
-
- /*
- * If we've already initialized this scan, we can just advance it
- * in the appropriate direction. If we haven't done so yet, we
- * call a routine to get the first item in the scan.
- */
-
- if (ItemPointerIsValid(&(scan->currentItemData)))
- res = _hash_next(scan, dir);
- else
- res = _hash_first(scan, dir);
-
- return ((char *) res);
+ RetrieveIndexResult res;
+
+ /*
+ * If we've already initialized this scan, we can just advance it in
+ * the appropriate direction. If we haven't done so yet, we call a
+ * routine to get the first item in the scan.
+ */
+
+ if (ItemPointerIsValid(&(scan->currentItemData)))
+ res = _hash_next(scan, dir);
+ else
+ res = _hash_first(scan, dir);
+
+ return ((char *) res);
}
/*
- * hashbeginscan() -- start a scan on a hash index
+ * hashbeginscan() -- start a scan on a hash index
*/
-char *
+char *
hashbeginscan(Relation rel,
- bool fromEnd,
- uint16 keysz,
- ScanKey scankey)
+ bool fromEnd,
+ uint16 keysz,
+ ScanKey scankey)
{
- IndexScanDesc scan;
- HashScanOpaque so;
-
- scan = RelationGetIndexScan(rel, fromEnd, keysz, scankey);
- so = (HashScanOpaque) palloc(sizeof(HashScanOpaqueData));
- so->hashso_curbuf = so->hashso_mrkbuf = InvalidBuffer;
- scan->opaque = so;
- scan->flags = 0x0;
-
- /* register scan in case we change pages it's using */
- _hash_regscan(scan);
-
- return ((char *) scan);
+ IndexScanDesc scan;
+ HashScanOpaque so;
+
+ scan = RelationGetIndexScan(rel, fromEnd, keysz, scankey);
+ so = (HashScanOpaque) palloc(sizeof(HashScanOpaqueData));
+ so->hashso_curbuf = so->hashso_mrkbuf = InvalidBuffer;
+ scan->opaque = so;
+ scan->flags = 0x0;
+
+ /* register scan in case we change pages it's using */
+ _hash_regscan(scan);
+
+ return ((char *) scan);
}
/*
- * hashrescan() -- rescan an index relation
+ * hashrescan() -- rescan an index relation
*/
void
hashrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey)
{
- ItemPointer iptr;
- HashScanOpaque so;
-
- so = (HashScanOpaque) scan->opaque;
-
- /* we hold a read lock on the current page in the scan */
- if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
- _hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
- so->hashso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
- if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
- _hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
- so->hashso_mrkbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- /* reset the scan key */
- if (scan->numberOfKeys > 0) {
- memmove(scan->keyData,
- scankey,
- scan->numberOfKeys * sizeof(ScanKeyData));
- }
+ ItemPointer iptr;
+ HashScanOpaque so;
+
+ so = (HashScanOpaque) scan->opaque;
+
+ /* we hold a read lock on the current page in the scan */
+ if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
+ {
+ _hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
+ so->hashso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+ if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
+ {
+ _hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
+ so->hashso_mrkbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ /* reset the scan key */
+ if (scan->numberOfKeys > 0)
+ {
+ memmove(scan->keyData,
+ scankey,
+ scan->numberOfKeys * sizeof(ScanKeyData));
+ }
}
/*
- * hashendscan() -- close down a scan
+ * hashendscan() -- close down a scan
*/
void
hashendscan(IndexScanDesc scan)
{
-
- ItemPointer iptr;
- HashScanOpaque so;
-
- so = (HashScanOpaque) scan->opaque;
-
- /* release any locks we still hold */
- if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
- _hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
- so->hashso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
- if (BufferIsValid(so->hashso_mrkbuf))
- _hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
- so->hashso_mrkbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- /* don't need scan registered anymore */
- _hash_dropscan(scan);
-
- /* be tidy */
- pfree (scan->opaque);
+
+ ItemPointer iptr;
+ HashScanOpaque so;
+
+ so = (HashScanOpaque) scan->opaque;
+
+ /* release any locks we still hold */
+ if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
+ {
+ _hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
+ so->hashso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
+ {
+ if (BufferIsValid(so->hashso_mrkbuf))
+ _hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
+ so->hashso_mrkbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ /* don't need scan registered anymore */
+ _hash_dropscan(scan);
+
+ /* be tidy */
+ pfree(scan->opaque);
}
/*
- * hashmarkpos() -- save current scan position
+ * hashmarkpos() -- save current scan position
*
*/
void
hashmarkpos(IndexScanDesc scan)
{
- ItemPointer iptr;
- HashScanOpaque so;
-
- /* see if we ever call this code. if we do, then so_mrkbuf a
- * useful element in the scan->opaque structure. if this procedure
- * is never called, so_mrkbuf should be removed from the scan->opaque
- * structure.
- */
- elog(NOTICE, "Hashmarkpos() called.");
-
- so = (HashScanOpaque) scan->opaque;
-
- /* release lock on old marked data, if any */
- if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
- _hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
- so->hashso_mrkbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- /* bump lock on currentItemData and copy to currentMarkData */
- if (ItemPointerIsValid(&(scan->currentItemData))) {
- so->hashso_mrkbuf = _hash_getbuf(scan->relation,
- BufferGetBlockNumber(so->hashso_curbuf),
- HASH_READ);
- scan->currentMarkData = scan->currentItemData;
- }
+ ItemPointer iptr;
+ HashScanOpaque so;
+
+ /*
+ * see if we ever call this code. if we do, then so_mrkbuf a useful
+ * element in the scan->opaque structure. if this procedure is never
+ * called, so_mrkbuf should be removed from the scan->opaque
+ * structure.
+ */
+ elog(NOTICE, "Hashmarkpos() called.");
+
+ so = (HashScanOpaque) scan->opaque;
+
+ /* release lock on old marked data, if any */
+ if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
+ {
+ _hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
+ so->hashso_mrkbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ /* bump lock on currentItemData and copy to currentMarkData */
+ if (ItemPointerIsValid(&(scan->currentItemData)))
+ {
+ so->hashso_mrkbuf = _hash_getbuf(scan->relation,
+ BufferGetBlockNumber(so->hashso_curbuf),
+ HASH_READ);
+ scan->currentMarkData = scan->currentItemData;
+ }
}
/*
- * hashrestrpos() -- restore scan to last saved position
+ * hashrestrpos() -- restore scan to last saved position
*/
void
hashrestrpos(IndexScanDesc scan)
{
- ItemPointer iptr;
- HashScanOpaque so;
-
- /* see if we ever call this code. if we do, then so_mrkbuf a
- * useful element in the scan->opaque structure. if this procedure
- * is never called, so_mrkbuf should be removed from the scan->opaque
- * structure.
- */
- elog(NOTICE, "Hashrestrpos() called.");
-
- so = (HashScanOpaque) scan->opaque;
-
- /* release lock on current data, if any */
- if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
- _hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
- so->hashso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- /* bump lock on currentMarkData and copy to currentItemData */
- if (ItemPointerIsValid(&(scan->currentMarkData))) {
- so->hashso_curbuf =
- _hash_getbuf(scan->relation,
- BufferGetBlockNumber(so->hashso_mrkbuf),
- HASH_READ);
-
- scan->currentItemData = scan->currentMarkData;
- }
+ ItemPointer iptr;
+ HashScanOpaque so;
+
+ /*
+ * see if we ever call this code. if we do, then so_mrkbuf a useful
+ * element in the scan->opaque structure. if this procedure is never
+ * called, so_mrkbuf should be removed from the scan->opaque
+ * structure.
+ */
+ elog(NOTICE, "Hashrestrpos() called.");
+
+ so = (HashScanOpaque) scan->opaque;
+
+ /* release lock on current data, if any */
+ if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
+ {
+ _hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
+ so->hashso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ /* bump lock on currentMarkData and copy to currentItemData */
+ if (ItemPointerIsValid(&(scan->currentMarkData)))
+ {
+ so->hashso_curbuf =
+ _hash_getbuf(scan->relation,
+ BufferGetBlockNumber(so->hashso_mrkbuf),
+ HASH_READ);
+
+ scan->currentItemData = scan->currentMarkData;
+ }
}
/* stubs */
void
hashdelete(Relation rel, ItemPointer tid)
{
- /* adjust any active scans that will be affected by this deletion */
- _hash_adjscans(rel, tid);
-
- /* delete the data from the page */
- _hash_pagedel(rel, tid);
-}
+ /* adjust any active scans that will be affected by this deletion */
+ _hash_adjscans(rel, tid);
+ /* delete the data from the page */
+ _hash_pagedel(rel, tid);
+}
diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c
index 5862800b21d..a3cbaa1a94c 100644
--- a/src/backend/access/hash/hashfunc.c
+++ b/src/backend/access/hash/hashfunc.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* hashfunc.c--
- * Comparison functions for hash access method.
+ * Comparison functions for hash access method.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.3 1996/11/10 02:57:40 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.4 1997/09/07 04:37:53 momjian Exp $
*
* NOTES
- * These functions are stored in pg_amproc. For each operator class
- * defined on hash tables, they compute the hash value of the argument.
+ * These functions are stored in pg_amproc. For each operator class
+ * defined on hash tables, they compute the hash value of the argument.
*
*-------------------------------------------------------------------------
*/
@@ -20,206 +20,223 @@
#include "access/hash.h"
-uint32 hashint2(int16 key)
+uint32
+hashint2(int16 key)
{
- return ((uint32) ~key);
+ return ((uint32) ~ key);
}
-uint32 hashint4(uint32 key)
+uint32
+hashint4(uint32 key)
{
- return (~key);
+ return (~key);
}
/* Hash function from Chris Torek. */
-uint32 hashfloat4(float32 keyp)
+uint32
+hashfloat4(float32 keyp)
{
- int len;
- int loop;
- uint32 h;
- char *kp = (char *) keyp;
+ int len;
+ int loop;
+ uint32 h;
+ char *kp = (char *) keyp;
- len = sizeof(float32data);
+ len = sizeof(float32data);
-#define HASH4a h = (h << 5) - h + *kp++;
-#define HASH4b h = (h << 5) + h + *kp++;
+#define HASH4a h = (h << 5) - h + *kp++;
+#define HASH4b h = (h << 5) + h + *kp++;
#define HASH4 HASH4b
- h = 0;
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do { /* All fall throughs */
- HASH4;
- case 7:
- HASH4;
- case 6:
- HASH4;
- case 5:
- HASH4;
- case 4:
- HASH4;
- case 3:
- HASH4;
- case 2:
- HASH4;
- case 1:
- HASH4;
- } while (--loop);
+ h = 0;
+ if (len > 0)
+ {
+ loop = (len + 8 - 1) >> 3;
+
+ switch (len & (8 - 1))
+ {
+ case 0:
+ do
+ { /* All fall throughs */
+ HASH4;
+ case 7:
+ HASH4;
+ case 6:
+ HASH4;
+ case 5:
+ HASH4;
+ case 4:
+ HASH4;
+ case 3:
+ HASH4;
+ case 2:
+ HASH4;
+ case 1:
+ HASH4;
+ } while (--loop);
+ }
}
- }
- return (h);
-}
+ return (h);
+}
-uint32 hashfloat8(float64 keyp)
+uint32
+hashfloat8(float64 keyp)
{
- int len;
- int loop;
- uint32 h;
- char *kp = (char *) keyp;
+ int len;
+ int loop;
+ uint32 h;
+ char *kp = (char *) keyp;
- len = sizeof(float64data);
+ len = sizeof(float64data);
-#define HASH4a h = (h << 5) - h + *kp++;
-#define HASH4b h = (h << 5) + h + *kp++;
+#define HASH4a h = (h << 5) - h + *kp++;
+#define HASH4b h = (h << 5) + h + *kp++;
#define HASH4 HASH4b
- h = 0;
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do { /* All fall throughs */
- HASH4;
- case 7:
- HASH4;
- case 6:
- HASH4;
- case 5:
- HASH4;
- case 4:
- HASH4;
- case 3:
- HASH4;
- case 2:
- HASH4;
- case 1:
- HASH4;
- } while (--loop);
+ h = 0;
+ if (len > 0)
+ {
+ loop = (len + 8 - 1) >> 3;
+
+ switch (len & (8 - 1))
+ {
+ case 0:
+ do
+ { /* All fall throughs */
+ HASH4;
+ case 7:
+ HASH4;
+ case 6:
+ HASH4;
+ case 5:
+ HASH4;
+ case 4:
+ HASH4;
+ case 3:
+ HASH4;
+ case 2:
+ HASH4;
+ case 1:
+ HASH4;
+ } while (--loop);
+ }
}
- }
- return (h);
-}
+ return (h);
+}
-uint32 hashoid(Oid key)
+uint32
+hashoid(Oid key)
{
- return ((uint32) ~key);
+ return ((uint32) ~ key);
}
-uint32 hashchar(char key)
+uint32
+hashchar(char key)
{
- int len;
- uint32 h;
+ int len;
+ uint32 h;
+
+ len = sizeof(char);
- len = sizeof(char);
+#define PRIME1 37
+#define PRIME2 1048583
-#define PRIME1 37
-#define PRIME2 1048583
+ h = 0;
+ /* Convert char to integer */
+ h = h * PRIME1 ^ (key - ' ');
+ h %= PRIME2;
- h = 0;
- /* Convert char to integer */
- h = h * PRIME1 ^ (key - ' ');
- h %= PRIME2;
-
- return (h);
+ return (h);
}
-uint32 hashchar2(uint16 intkey)
+uint32
+hashchar2(uint16 intkey)
{
- uint32 h;
- int len;
- char *key = (char *) &intkey;
-
- h = 0;
- len = sizeof(uint16);
- /* Convert string to integer */
- while (len--)
- h = h * PRIME1 ^ (*key++ - ' ');
- h %= PRIME2;
-
- return (h);
+ uint32 h;
+ int len;
+ char *key = (char *) &intkey;
+
+ h = 0;
+ len = sizeof(uint16);
+ /* Convert string to integer */
+ while (len--)
+ h = h * PRIME1 ^ (*key++ - ' ');
+ h %= PRIME2;
+
+ return (h);
}
-uint32 hashchar4(uint32 intkey)
+uint32
+hashchar4(uint32 intkey)
{
- uint32 h;
- int len;
- char *key = (char *) &intkey;
-
- h = 0;
- len = sizeof(uint32);
- /* Convert string to integer */
- while (len--)
- h = h * PRIME1 ^ (*key++ - ' ');
- h %= PRIME2;
-
- return (h);
+ uint32 h;
+ int len;
+ char *key = (char *) &intkey;
+
+ h = 0;
+ len = sizeof(uint32);
+ /* Convert string to integer */
+ while (len--)
+ h = h * PRIME1 ^ (*key++ - ' ');
+ h %= PRIME2;
+
+ return (h);
}
-uint32 hashchar8(char *key)
+uint32
+hashchar8(char *key)
{
- uint32 h;
- int len;
-
- h = 0;
- len = sizeof(char8);
- /* Convert string to integer */
- while (len--)
- h = h * PRIME1 ^ (*key++ - ' ');
- h %= PRIME2;
-
- return (h);
+ uint32 h;
+ int len;
+
+ h = 0;
+ len = sizeof(char8);
+ /* Convert string to integer */
+ while (len--)
+ h = h * PRIME1 ^ (*key++ - ' ');
+ h %= PRIME2;
+
+ return (h);
}
-uint32 hashname(NameData *n)
+uint32
+hashname(NameData * n)
{
- uint32 h;
- int len;
- char *key;
-
- key = n->data;
-
- h = 0;
- len = NAMEDATALEN;
- /* Convert string to integer */
- while (len--)
- h = h * PRIME1 ^ (*key++ - ' ');
- h %= PRIME2;
-
- return (h);
+ uint32 h;
+ int len;
+ char *key;
+
+ key = n->data;
+
+ h = 0;
+ len = NAMEDATALEN;
+ /* Convert string to integer */
+ while (len--)
+ h = h * PRIME1 ^ (*key++ - ' ');
+ h %= PRIME2;
+
+ return (h);
}
-uint32 hashchar16(char *key)
+uint32
+hashchar16(char *key)
{
- uint32 h;
- int len;
-
- h = 0;
- len = sizeof(char16);
- /* Convert string to integer */
- while (len--)
- h = h * PRIME1 ^ (*key++ - ' ');
- h %= PRIME2;
-
- return (h);
+ uint32 h;
+ int len;
+
+ h = 0;
+ len = sizeof(char16);
+ /* Convert string to integer */
+ while (len--)
+ h = h * PRIME1 ^ (*key++ - ' ');
+ h %= PRIME2;
+
+ return (h);
}
@@ -234,45 +251,49 @@ uint32 hashchar16(char *key)
*
* "OZ's original sdbm hash"
*/
-uint32 hashtext(struct varlena *key)
+uint32
+hashtext(struct varlena * key)
{
- int keylen;
- char *keydata;
- uint32 n;
- int loop;
-
- keydata = VARDATA(key);
- keylen = VARSIZE(key);
-
- /* keylen includes the four bytes in which string keylength is stored */
- keylen -= sizeof(VARSIZE(key));
-
-#define HASHC n = *keydata++ + 65599 * n
-
- n = 0;
- if (keylen > 0) {
- loop = (keylen + 8 - 1) >> 3;
-
- switch (keylen & (8 - 1)) {
- case 0:
- do { /* All fall throughs */
- HASHC;
- case 7:
- HASHC;
- case 6:
- HASHC;
- case 5:
- HASHC;
- case 4:
- HASHC;
- case 3:
- HASHC;
- case 2:
- HASHC;
- case 1:
- HASHC;
- } while (--loop);
+ int keylen;
+ char *keydata;
+ uint32 n;
+ int loop;
+
+ keydata = VARDATA(key);
+ keylen = VARSIZE(key);
+
+ /* keylen includes the four bytes in which string keylength is stored */
+ keylen -= sizeof(VARSIZE(key));
+
+#define HASHC n = *keydata++ + 65599 * n
+
+ n = 0;
+ if (keylen > 0)
+ {
+ loop = (keylen + 8 - 1) >> 3;
+
+ switch (keylen & (8 - 1))
+ {
+ case 0:
+ do
+ { /* All fall throughs */
+ HASHC;
+ case 7:
+ HASHC;
+ case 6:
+ HASHC;
+ case 5:
+ HASHC;
+ case 4:
+ HASHC;
+ case 3:
+ HASHC;
+ case 2:
+ HASHC;
+ case 1:
+ HASHC;
+ } while (--loop);
+ }
}
- }
- return (n);
-}
+ return (n);
+}
diff --git a/src/backend/access/hash/hashinsert.c b/src/backend/access/hash/hashinsert.c
index f1233c68b2d..4829093589a 100644
--- a/src/backend/access/hash/hashinsert.c
+++ b/src/backend/access/hash/hashinsert.c
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* hashinsert.c--
- * Item insertion in hash tables for Postgres.
+ * Item insertion in hash tables for Postgres.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hashinsert.c,v 1.8 1997/08/12 22:51:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashinsert.c,v 1.9 1997/09/07 04:37:56 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <access/hash.h>
#include <storage/bufmgr.h>
#include <utils/memutils.h>
@@ -22,211 +22,221 @@ static InsertIndexResult _hash_insertonpg(Relation rel, Buffer buf, int keysz, S
static OffsetNumber _hash_pgaddtup(Relation rel, Buffer buf, int keysz, ScanKey itup_scankey, Size itemsize, HashItem hitem);
/*
- * _hash_doinsert() -- Handle insertion of a single HashItem in the table.
+ * _hash_doinsert() -- Handle insertion of a single HashItem in the table.
*
- * This routine is called by the public interface routines, hashbuild
- * and hashinsert. By here, hashitem is filled in, and has a unique
- * (xid, seqno) pair. The datum to be used as a "key" is in the
- * hashitem.
+ * This routine is called by the public interface routines, hashbuild
+ * and hashinsert. By here, hashitem is filled in, and has a unique
+ * (xid, seqno) pair. The datum to be used as a "key" is in the
+ * hashitem.
*/
InsertIndexResult
_hash_doinsert(Relation rel, HashItem hitem)
{
- Buffer buf;
- Buffer metabuf;
- BlockNumber blkno;
- HashMetaPage metap;
- IndexTuple itup;
- InsertIndexResult res;
- ScanKey itup_scankey;
- int natts;
- Page page;
-
- metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ);
- metap = (HashMetaPage) BufferGetPage(metabuf);
- _hash_checkpage((Page) metap, LH_META_PAGE);
-
- /* we need a scan key to do our search, so build one */
- itup = &(hitem->hash_itup);
- if ((natts = rel->rd_rel->relnatts) != 1)
- elog(WARN, "Hash indices valid for only one index key.");
- itup_scankey = _hash_mkscankey(rel, itup, metap);
-
- /*
- * find the first page in the bucket chain containing this key and
- * place it in buf. _hash_search obtains a read lock for us.
- */
- _hash_search(rel, natts, itup_scankey, &buf, metap);
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE);
-
- /*
- * trade in our read lock for a write lock so that we can do the
- * insertion.
- */
- blkno = BufferGetBlockNumber(buf);
- _hash_relbuf(rel, buf, HASH_READ);
- buf = _hash_getbuf(rel, blkno, HASH_WRITE);
-
-
- /*
- * XXX btree comment (haven't decided what to do in hash): don't
- * think the bucket can be split while we're reading the metapage.
- *
- * If the page was split between the time that we surrendered our
- * read lock and acquired our write lock, then this page may no
- * longer be the right place for the key we want to insert.
- */
-
- /* do the insertion */
- res = _hash_insertonpg(rel, buf, natts, itup_scankey,
- hitem, metabuf);
-
- /* be tidy */
- _hash_freeskey(itup_scankey);
-
- return (res);
+ Buffer buf;
+ Buffer metabuf;
+ BlockNumber blkno;
+ HashMetaPage metap;
+ IndexTuple itup;
+ InsertIndexResult res;
+ ScanKey itup_scankey;
+ int natts;
+ Page page;
+
+ metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ);
+ metap = (HashMetaPage) BufferGetPage(metabuf);
+ _hash_checkpage((Page) metap, LH_META_PAGE);
+
+ /* we need a scan key to do our search, so build one */
+ itup = &(hitem->hash_itup);
+ if ((natts = rel->rd_rel->relnatts) != 1)
+ elog(WARN, "Hash indices valid for only one index key.");
+ itup_scankey = _hash_mkscankey(rel, itup, metap);
+
+ /*
+ * find the first page in the bucket chain containing this key and
+ * place it in buf. _hash_search obtains a read lock for us.
+ */
+ _hash_search(rel, natts, itup_scankey, &buf, metap);
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE);
+
+ /*
+ * trade in our read lock for a write lock so that we can do the
+ * insertion.
+ */
+ blkno = BufferGetBlockNumber(buf);
+ _hash_relbuf(rel, buf, HASH_READ);
+ buf = _hash_getbuf(rel, blkno, HASH_WRITE);
+
+
+ /*
+ * XXX btree comment (haven't decided what to do in hash): don't think
+ * the bucket can be split while we're reading the metapage.
+ *
+ * If the page was split between the time that we surrendered our read
+ * lock and acquired our write lock, then this page may no longer be
+ * the right place for the key we want to insert.
+ */
+
+ /* do the insertion */
+ res = _hash_insertonpg(rel, buf, natts, itup_scankey,
+ hitem, metabuf);
+
+ /* be tidy */
+ _hash_freeskey(itup_scankey);
+
+ return (res);
}
/*
- * _hash_insertonpg() -- Insert a tuple on a particular page in the table.
+ * _hash_insertonpg() -- Insert a tuple on a particular page in the table.
*
- * This recursive procedure does the following things:
+ * This recursive procedure does the following things:
*
- * + if necessary, splits the target page.
- * + inserts the tuple.
+ * + if necessary, splits the target page.
+ * + inserts the tuple.
*
- * On entry, we must have the right buffer on which to do the
- * insertion, and the buffer must be pinned and locked. On return,
- * we will have dropped both the pin and the write lock on the buffer.
+ * On entry, we must have the right buffer on which to do the
+ * insertion, and the buffer must be pinned and locked. On return,
+ * we will have dropped both the pin and the write lock on the buffer.
*
*/
-static InsertIndexResult
+static InsertIndexResult
_hash_insertonpg(Relation rel,
- Buffer buf,
- int keysz,
- ScanKey scankey,
- HashItem hitem,
- Buffer metabuf)
+ Buffer buf,
+ int keysz,
+ ScanKey scankey,
+ HashItem hitem,
+ Buffer metabuf)
{
- InsertIndexResult res;
- Page page;
- BlockNumber itup_blkno;
- OffsetNumber itup_off;
- int itemsz;
- HashPageOpaque pageopaque;
- bool do_expand = false;
- Buffer ovflbuf;
- HashMetaPage metap;
- Bucket bucket;
-
- metap = (HashMetaPage) BufferGetPage(metabuf);
- _hash_checkpage((Page) metap, LH_META_PAGE);
-
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
- pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
- bucket = pageopaque->hasho_bucket;
-
- itemsz = IndexTupleDSize(hitem->hash_itup)
- + (sizeof(HashItemData) - sizeof(IndexTupleData));
- itemsz = DOUBLEALIGN(itemsz);
-
- while (PageGetFreeSpace(page) < itemsz) {
- /*
- * no space on this page; check for an overflow page
- */
- if (BlockNumberIsValid(pageopaque->hasho_nextblkno)) {
- /*
- * ovfl page exists; go get it. if it doesn't have room,
- * we'll find out next pass through the loop test above.
- */
- ovflbuf = _hash_getbuf(rel, pageopaque->hasho_nextblkno,
- HASH_WRITE);
- _hash_relbuf(rel, buf, HASH_WRITE);
- buf = ovflbuf;
- page = BufferGetPage(buf);
- } else {
- /*
- * we're at the end of the bucket chain and we haven't
- * found a page with enough room. allocate a new overflow
- * page.
- */
- do_expand = true;
- ovflbuf = _hash_addovflpage(rel, &metabuf, buf);
- _hash_relbuf(rel, buf, HASH_WRITE);
- buf = ovflbuf;
- page = BufferGetPage(buf);
-
- if (PageGetFreeSpace(page) < itemsz) {
- /* it doesn't fit on an empty page -- give up */
- elog(WARN, "hash item too large");
- }
- }
- _hash_checkpage(page, LH_OVERFLOW_PAGE);
+ InsertIndexResult res;
+ Page page;
+ BlockNumber itup_blkno;
+ OffsetNumber itup_off;
+ int itemsz;
+ HashPageOpaque pageopaque;
+ bool do_expand = false;
+ Buffer ovflbuf;
+ HashMetaPage metap;
+ Bucket bucket;
+
+ metap = (HashMetaPage) BufferGetPage(metabuf);
+ _hash_checkpage((Page) metap, LH_META_PAGE);
+
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
- Assert(pageopaque->hasho_bucket == bucket);
- }
-
- itup_off = _hash_pgaddtup(rel, buf, keysz, scankey, itemsz, hitem);
- itup_blkno = BufferGetBlockNumber(buf);
-
- /* by here, the new tuple is inserted */
- res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
-
- ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
-
- if (res != NULL) {
- /*
- * Increment the number of keys in the table.
- * We switch lock access type just for a moment
- * to allow greater accessibility to the metapage.
- */
- metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf,
- HASH_READ, HASH_WRITE);
- metap->hashm_nkeys += 1;
- metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf,
- HASH_WRITE, HASH_READ);
-
- }
-
- _hash_wrtbuf(rel, buf);
-
- if (do_expand ||
- (metap->hashm_nkeys / (metap->hashm_maxbucket + 1))
- > metap->hashm_ffactor) {
- _hash_expandtable(rel, metabuf);
- }
- _hash_relbuf(rel, metabuf, HASH_READ);
- return (res);
-}
+ bucket = pageopaque->hasho_bucket;
+
+ itemsz = IndexTupleDSize(hitem->hash_itup)
+ + (sizeof(HashItemData) - sizeof(IndexTupleData));
+ itemsz = DOUBLEALIGN(itemsz);
+
+ while (PageGetFreeSpace(page) < itemsz)
+ {
+
+ /*
+ * no space on this page; check for an overflow page
+ */
+ if (BlockNumberIsValid(pageopaque->hasho_nextblkno))
+ {
+
+ /*
+ * ovfl page exists; go get it. if it doesn't have room,
+ * we'll find out next pass through the loop test above.
+ */
+ ovflbuf = _hash_getbuf(rel, pageopaque->hasho_nextblkno,
+ HASH_WRITE);
+ _hash_relbuf(rel, buf, HASH_WRITE);
+ buf = ovflbuf;
+ page = BufferGetPage(buf);
+ }
+ else
+ {
+
+ /*
+ * we're at the end of the bucket chain and we haven't found a
+ * page with enough room. allocate a new overflow page.
+ */
+ do_expand = true;
+ ovflbuf = _hash_addovflpage(rel, &metabuf, buf);
+ _hash_relbuf(rel, buf, HASH_WRITE);
+ buf = ovflbuf;
+ page = BufferGetPage(buf);
+
+ if (PageGetFreeSpace(page) < itemsz)
+ {
+ /* it doesn't fit on an empty page -- give up */
+ elog(WARN, "hash item too large");
+ }
+ }
+ _hash_checkpage(page, LH_OVERFLOW_PAGE);
+ pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
+ Assert(pageopaque->hasho_bucket == bucket);
+ }
+
+ itup_off = _hash_pgaddtup(rel, buf, keysz, scankey, itemsz, hitem);
+ itup_blkno = BufferGetBlockNumber(buf);
+
+ /* by here, the new tuple is inserted */
+ res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
+
+ ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
+
+ if (res != NULL)
+ {
+
+ /*
+ * Increment the number of keys in the table. We switch lock
+ * access type just for a moment to allow greater accessibility to
+ * the metapage.
+ */
+ metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf,
+ HASH_READ, HASH_WRITE);
+ metap->hashm_nkeys += 1;
+ metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf,
+ HASH_WRITE, HASH_READ);
+
+ }
+
+ _hash_wrtbuf(rel, buf);
+
+ if (do_expand ||
+ (metap->hashm_nkeys / (metap->hashm_maxbucket + 1))
+ > metap->hashm_ffactor)
+ {
+ _hash_expandtable(rel, metabuf);
+ }
+ _hash_relbuf(rel, metabuf, HASH_READ);
+ return (res);
+}
/*
- * _hash_pgaddtup() -- add a tuple to a particular page in the index.
+ * _hash_pgaddtup() -- add a tuple to a particular page in the index.
*
- * This routine adds the tuple to the page as requested, and keeps the
- * write lock and reference associated with the page's buffer. It is
- * an error to call pgaddtup() without a write lock and reference.
+ * This routine adds the tuple to the page as requested, and keeps the
+ * write lock and reference associated with the page's buffer. It is
+ * an error to call pgaddtup() without a write lock and reference.
*/
-static OffsetNumber
+static OffsetNumber
_hash_pgaddtup(Relation rel,
- Buffer buf,
- int keysz,
- ScanKey itup_scankey,
- Size itemsize,
- HashItem hitem)
+ Buffer buf,
+ int keysz,
+ ScanKey itup_scankey,
+ Size itemsize,
+ HashItem hitem)
{
- OffsetNumber itup_off;
- Page page;
-
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
-
- itup_off = OffsetNumberNext(PageGetMaxOffsetNumber(page));
- PageAddItem(page, (Item) hitem, itemsize, itup_off, LP_USED);
-
- /* write the buffer, but hold our lock */
- _hash_wrtnorelbuf(rel, buf);
-
- return (itup_off);
+ OffsetNumber itup_off;
+ Page page;
+
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
+
+ itup_off = OffsetNumberNext(PageGetMaxOffsetNumber(page));
+ PageAddItem(page, (Item) hitem, itemsize, itup_off, LP_USED);
+
+ /* write the buffer, but hold our lock */
+ _hash_wrtnorelbuf(rel, buf);
+
+ return (itup_off);
}
diff --git a/src/backend/access/hash/hashovfl.c b/src/backend/access/hash/hashovfl.c
index d976c4818c8..b6882d4d3e1 100644
--- a/src/backend/access/hash/hashovfl.c
+++ b/src/backend/access/hash/hashovfl.c
@@ -1,400 +1,423 @@
/*-------------------------------------------------------------------------
*
* hashovfl.c--
- * Overflow page management code for the Postgres hash access method
+ * Overflow page management code for the Postgres hash access method
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hashovfl.c,v 1.9 1997/08/12 22:51:34 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashovfl.c,v 1.10 1997/09/07 04:37:57 momjian Exp $
*
* NOTES
- * Overflow pages look like ordinary relation pages.
+ * Overflow pages look like ordinary relation pages.
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <access/hash.h>
#include <storage/bufmgr.h>
#include <utils/memutils.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static OverflowPageAddress _hash_getovfladdr(Relation rel, Buffer *metabufp);
-static uint32 _hash_firstfreebit(uint32 map);
+static OverflowPageAddress _hash_getovfladdr(Relation rel, Buffer * metabufp);
+static uint32 _hash_firstfreebit(uint32 map);
/*
- * _hash_addovflpage
+ * _hash_addovflpage
+ *
+ * Add an overflow page to the page currently pointed to by the buffer
+ * argument 'buf'.
*
- * Add an overflow page to the page currently pointed to by the buffer
- * argument 'buf'.
+ * *Metabufp has a read lock upon entering the function; buf has a
+ * write lock.
*
- * *Metabufp has a read lock upon entering the function; buf has a
- * write lock.
- *
*/
Buffer
-_hash_addovflpage(Relation rel, Buffer *metabufp, Buffer buf)
+_hash_addovflpage(Relation rel, Buffer * metabufp, Buffer buf)
{
-
- OverflowPageAddress oaddr;
- BlockNumber ovflblkno;
- Buffer ovflbuf;
- HashMetaPage metap;
- HashPageOpaque ovflopaque;
- HashPageOpaque pageopaque;
- Page page;
- Page ovflpage;
-
- /* this had better be the last page in a bucket chain */
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
- pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
- Assert(!BlockNumberIsValid(pageopaque->hasho_nextblkno));
-
- metap = (HashMetaPage) BufferGetPage(*metabufp);
- _hash_checkpage((Page) metap, LH_META_PAGE);
-
- /* allocate an empty overflow page */
- oaddr = _hash_getovfladdr(rel, metabufp);
- if (oaddr == InvalidOvflAddress) {
- elog(WARN, "_hash_addovflpage: problem with _hash_getovfladdr.");
- }
- ovflblkno = OADDR_TO_BLKNO(OADDR_OF(SPLITNUM(oaddr), OPAGENUM(oaddr)));
- Assert(BlockNumberIsValid(ovflblkno));
- ovflbuf = _hash_getbuf(rel, ovflblkno, HASH_WRITE);
- Assert(BufferIsValid(ovflbuf));
- ovflpage = BufferGetPage(ovflbuf);
-
- /* initialize the new overflow page */
- _hash_pageinit(ovflpage, BufferGetPageSize(ovflbuf));
- ovflopaque = (HashPageOpaque) PageGetSpecialPointer(ovflpage);
- ovflopaque->hasho_prevblkno = BufferGetBlockNumber(buf);
- ovflopaque->hasho_nextblkno = InvalidBlockNumber;
- ovflopaque->hasho_flag = LH_OVERFLOW_PAGE;
- ovflopaque->hasho_oaddr = oaddr;
- ovflopaque->hasho_bucket = pageopaque->hasho_bucket;
- _hash_wrtnorelbuf(rel, ovflbuf);
-
- /* logically chain overflow page to previous page */
- pageopaque->hasho_nextblkno = ovflblkno;
- _hash_wrtnorelbuf(rel, buf);
- return (ovflbuf);
+
+ OverflowPageAddress oaddr;
+ BlockNumber ovflblkno;
+ Buffer ovflbuf;
+ HashMetaPage metap;
+ HashPageOpaque ovflopaque;
+ HashPageOpaque pageopaque;
+ Page page;
+ Page ovflpage;
+
+ /* this had better be the last page in a bucket chain */
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
+ pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
+ Assert(!BlockNumberIsValid(pageopaque->hasho_nextblkno));
+
+ metap = (HashMetaPage) BufferGetPage(*metabufp);
+ _hash_checkpage((Page) metap, LH_META_PAGE);
+
+ /* allocate an empty overflow page */
+ oaddr = _hash_getovfladdr(rel, metabufp);
+ if (oaddr == InvalidOvflAddress)
+ {
+ elog(WARN, "_hash_addovflpage: problem with _hash_getovfladdr.");
+ }
+ ovflblkno = OADDR_TO_BLKNO(OADDR_OF(SPLITNUM(oaddr), OPAGENUM(oaddr)));
+ Assert(BlockNumberIsValid(ovflblkno));
+ ovflbuf = _hash_getbuf(rel, ovflblkno, HASH_WRITE);
+ Assert(BufferIsValid(ovflbuf));
+ ovflpage = BufferGetPage(ovflbuf);
+
+ /* initialize the new overflow page */
+ _hash_pageinit(ovflpage, BufferGetPageSize(ovflbuf));
+ ovflopaque = (HashPageOpaque) PageGetSpecialPointer(ovflpage);
+ ovflopaque->hasho_prevblkno = BufferGetBlockNumber(buf);
+ ovflopaque->hasho_nextblkno = InvalidBlockNumber;
+ ovflopaque->hasho_flag = LH_OVERFLOW_PAGE;
+ ovflopaque->hasho_oaddr = oaddr;
+ ovflopaque->hasho_bucket = pageopaque->hasho_bucket;
+ _hash_wrtnorelbuf(rel, ovflbuf);
+
+ /* logically chain overflow page to previous page */
+ pageopaque->hasho_nextblkno = ovflblkno;
+ _hash_wrtnorelbuf(rel, buf);
+ return (ovflbuf);
}
/*
- * _hash_getovfladdr()
+ * _hash_getovfladdr()
*
- * Find an available overflow page and return its address.
+ * Find an available overflow page and return its address.
*
- * When we enter this function, we have a read lock on *metabufp which
- * we change to a write lock immediately. Before exiting, the write lock
- * is exchanged for a read lock.
+ * When we enter this function, we have a read lock on *metabufp which
+ * we change to a write lock immediately. Before exiting, the write lock
+ * is exchanged for a read lock.
*
*/
-static OverflowPageAddress
-_hash_getovfladdr(Relation rel, Buffer *metabufp)
+static OverflowPageAddress
+_hash_getovfladdr(Relation rel, Buffer * metabufp)
{
- HashMetaPage metap;
- Buffer mapbuf = 0;
- BlockNumber blkno;
- PageOffset offset;
- OverflowPageAddress oaddr;
- SplitNumber splitnum;
- uint32 *freep = NULL;
- uint32 max_free;
- uint32 bit;
- uint32 first_page;
- uint32 free_bit;
- uint32 free_page;
- uint32 in_use_bits;
- uint32 i, j;
-
- metap = (HashMetaPage) _hash_chgbufaccess(rel, metabufp, HASH_READ, HASH_WRITE);
-
- splitnum = metap->OVFL_POINT;
- max_free = metap->SPARES[splitnum];
-
- free_page = (max_free - 1) >> (metap->BSHIFT + BYTE_TO_BIT);
- free_bit = (max_free - 1) & (BMPGSZ_BIT(metap) - 1);
-
- /* Look through all the free maps to find the first free block */
- first_page = metap->LAST_FREED >> (metap->BSHIFT + BYTE_TO_BIT);
- for ( i = first_page; i <= free_page; i++ ) {
- Page mappage;
-
- blkno = metap->hashm_mapp[i];
- mapbuf = _hash_getbuf(rel, blkno, HASH_WRITE);
- mappage = BufferGetPage(mapbuf);
- _hash_checkpage(mappage, LH_BITMAP_PAGE);
- freep = HashPageGetBitmap(mappage);
- Assert(freep);
-
- if (i == free_page)
- in_use_bits = free_bit;
- else
- in_use_bits = BMPGSZ_BIT(metap) - 1;
-
- if (i == first_page) {
- bit = metap->LAST_FREED & (BMPGSZ_BIT(metap) - 1);
- j = bit / BITS_PER_MAP;
- bit = bit & ~(BITS_PER_MAP - 1);
- } else {
- bit = 0;
- j = 0;
+ HashMetaPage metap;
+ Buffer mapbuf = 0;
+ BlockNumber blkno;
+ PageOffset offset;
+ OverflowPageAddress oaddr;
+ SplitNumber splitnum;
+ uint32 *freep = NULL;
+ uint32 max_free;
+ uint32 bit;
+ uint32 first_page;
+ uint32 free_bit;
+ uint32 free_page;
+ uint32 in_use_bits;
+ uint32 i,
+ j;
+
+ metap = (HashMetaPage) _hash_chgbufaccess(rel, metabufp, HASH_READ, HASH_WRITE);
+
+ splitnum = metap->OVFL_POINT;
+ max_free = metap->SPARES[splitnum];
+
+ free_page = (max_free - 1) >> (metap->BSHIFT + BYTE_TO_BIT);
+ free_bit = (max_free - 1) & (BMPGSZ_BIT(metap) - 1);
+
+ /* Look through all the free maps to find the first free block */
+ first_page = metap->LAST_FREED >> (metap->BSHIFT + BYTE_TO_BIT);
+ for (i = first_page; i <= free_page; i++)
+ {
+ Page mappage;
+
+ blkno = metap->hashm_mapp[i];
+ mapbuf = _hash_getbuf(rel, blkno, HASH_WRITE);
+ mappage = BufferGetPage(mapbuf);
+ _hash_checkpage(mappage, LH_BITMAP_PAGE);
+ freep = HashPageGetBitmap(mappage);
+ Assert(freep);
+
+ if (i == free_page)
+ in_use_bits = free_bit;
+ else
+ in_use_bits = BMPGSZ_BIT(metap) - 1;
+
+ if (i == first_page)
+ {
+ bit = metap->LAST_FREED & (BMPGSZ_BIT(metap) - 1);
+ j = bit / BITS_PER_MAP;
+ bit = bit & ~(BITS_PER_MAP - 1);
+ }
+ else
+ {
+ bit = 0;
+ j = 0;
+ }
+ for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
+ if (freep[j] != ALL_SET)
+ goto found;
+ }
+
+ /* No Free Page Found - have to allocate a new page */
+ metap->LAST_FREED = metap->SPARES[splitnum];
+ metap->SPARES[splitnum]++;
+ offset = metap->SPARES[splitnum] -
+ (splitnum ? metap->SPARES[splitnum - 1] : 0);
+
+#define OVMSG "HASH: Out of overflow pages. Out of luck.\n"
+
+ if (offset > SPLITMASK)
+ {
+ if (++splitnum >= NCACHED)
+ {
+ elog(WARN, OVMSG);
+ }
+ metap->OVFL_POINT = splitnum;
+ metap->SPARES[splitnum] = metap->SPARES[splitnum - 1];
+ metap->SPARES[splitnum - 1]--;
+ offset = 0;
}
- for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
- if (freep[j] != ALL_SET)
- goto found;
- }
-
- /* No Free Page Found - have to allocate a new page */
- metap->LAST_FREED = metap->SPARES[splitnum];
- metap->SPARES[splitnum]++;
- offset = metap->SPARES[splitnum] -
- (splitnum ? metap->SPARES[splitnum - 1] : 0);
-
-#define OVMSG "HASH: Out of overflow pages. Out of luck.\n"
-
- if (offset > SPLITMASK) {
- if (++splitnum >= NCACHED) {
- elog(WARN, OVMSG);
+
+ /* Check if we need to allocate a new bitmap page */
+ if (free_bit == BMPGSZ_BIT(metap) - 1)
+ {
+ /* won't be needing old map page */
+
+ _hash_relbuf(rel, mapbuf, HASH_WRITE);
+
+ free_page++;
+ if (free_page >= NCACHED)
+ {
+ elog(WARN, OVMSG);
+ }
+
+ /*
+ * This is tricky. The 1 indicates that you want the new page
+ * allocated with 1 clear bit. Actually, you are going to
+ * allocate 2 pages from this map. The first is going to be the
+ * map page, the second is the overflow page we were looking for.
+ * The init_bitmap routine automatically, sets the first bit of
+ * itself to indicate that the bitmap itself is in use. We would
+ * explicitly set the second bit, but don't have to if we tell
+ * init_bitmap not to leave it clear in the first place.
+ */
+ if (_hash_initbitmap(rel, metap, OADDR_OF(splitnum, offset),
+ 1, free_page))
+ {
+ elog(WARN, "overflow_page: problem with _hash_initbitmap.");
+ }
+ metap->SPARES[splitnum]++;
+ offset++;
+ if (offset > SPLITMASK)
+ {
+ if (++splitnum >= NCACHED)
+ {
+ elog(WARN, OVMSG);
+ }
+ metap->OVFL_POINT = splitnum;
+ metap->SPARES[splitnum] = metap->SPARES[splitnum - 1];
+ metap->SPARES[splitnum - 1]--;
+ offset = 0;
+ }
}
- metap->OVFL_POINT = splitnum;
- metap->SPARES[splitnum] = metap->SPARES[splitnum-1];
- metap->SPARES[splitnum-1]--;
- offset = 0;
- }
-
- /* Check if we need to allocate a new bitmap page */
- if (free_bit == BMPGSZ_BIT(metap) - 1) {
- /* won't be needing old map page */
-
- _hash_relbuf(rel, mapbuf, HASH_WRITE);
-
- free_page++;
- if (free_page >= NCACHED) {
- elog(WARN, OVMSG);
+ else
+ {
+
+ /*
+ * Free_bit addresses the last used bit. Bump it to address the
+ * first available bit.
+ */
+ free_bit++;
+ SETBIT(freep, free_bit);
+ _hash_wrtbuf(rel, mapbuf);
}
-
+
+ /* Calculate address of the new overflow page */
+ oaddr = OADDR_OF(splitnum, offset);
+ _hash_chgbufaccess(rel, metabufp, HASH_WRITE, HASH_READ);
+ return (oaddr);
+
+found:
+ bit = bit + _hash_firstfreebit(freep[j]);
+ SETBIT(freep, bit);
+ _hash_wrtbuf(rel, mapbuf);
+
/*
- * This is tricky. The 1 indicates that you want the new page
- * allocated with 1 clear bit. Actually, you are going to
- * allocate 2 pages from this map. The first is going to be
- * the map page, the second is the overflow page we were
- * looking for. The init_bitmap routine automatically, sets
- * the first bit of itself to indicate that the bitmap itself
- * is in use. We would explicitly set the second bit, but
- * don't have to if we tell init_bitmap not to leave it clear
- * in the first place.
+ * Bits are addressed starting with 0, but overflow pages are
+ * addressed beginning at 1. Bit is a bit addressnumber, so we need to
+ * increment it to convert it to a page number.
*/
- if (_hash_initbitmap(rel, metap, OADDR_OF(splitnum, offset),
- 1, free_page)) {
- elog(WARN, "overflow_page: problem with _hash_initbitmap.");
+
+ bit = 1 + bit + (i * BMPGSZ_BIT(metap));
+ if (bit >= metap->LAST_FREED)
+ {
+ metap->LAST_FREED = bit - 1;
}
- metap->SPARES[splitnum]++;
- offset++;
- if (offset > SPLITMASK) {
- if (++splitnum >= NCACHED) {
+
+ /* Calculate the split number for this page */
+ for (i = 0; (i < splitnum) && (bit > metap->SPARES[i]); i++)
+ ;
+ offset = (i ? bit - metap->SPARES[i - 1] : bit);
+ if (offset >= SPLITMASK)
+ {
elog(WARN, OVMSG);
- }
- metap->OVFL_POINT = splitnum;
- metap->SPARES[splitnum] = metap->SPARES[splitnum-1];
- metap->SPARES[splitnum-1]--;
- offset = 0;
}
- } else {
-
- /*
- * Free_bit addresses the last used bit. Bump it to address
- * the first available bit.
- */
- free_bit++;
- SETBIT(freep, free_bit);
- _hash_wrtbuf(rel, mapbuf);
- }
-
- /* Calculate address of the new overflow page */
- oaddr = OADDR_OF(splitnum, offset);
- _hash_chgbufaccess(rel, metabufp, HASH_WRITE, HASH_READ);
- return (oaddr);
-
- found:
- bit = bit + _hash_firstfreebit(freep[j]);
- SETBIT(freep, bit);
- _hash_wrtbuf(rel, mapbuf);
-
- /*
- * Bits are addressed starting with 0, but overflow pages are addressed
- * beginning at 1. Bit is a bit addressnumber, so we need to increment
- * it to convert it to a page number.
- */
-
- bit = 1 + bit + (i * BMPGSZ_BIT(metap));
- if (bit >= metap->LAST_FREED) {
- metap->LAST_FREED = bit - 1;
- }
-
- /* Calculate the split number for this page */
- for (i = 0; (i < splitnum) && (bit > metap->SPARES[i]); i++)
- ;
- offset = (i ? bit - metap->SPARES[i - 1] : bit);
- if (offset >= SPLITMASK) {
- elog(WARN, OVMSG);
- }
-
- /* initialize this page */
- oaddr = OADDR_OF(i, offset);
- _hash_chgbufaccess(rel, metabufp, HASH_WRITE, HASH_READ);
- return (oaddr);
+
+ /* initialize this page */
+ oaddr = OADDR_OF(i, offset);
+ _hash_chgbufaccess(rel, metabufp, HASH_WRITE, HASH_READ);
+ return (oaddr);
}
/*
- * _hash_firstfreebit()
+ * _hash_firstfreebit()
+ *
+ * Return the first bit that is not set in the argument 'map'. This
+ * function is used to find an available overflow page within a
+ * splitnumber.
*
- * Return the first bit that is not set in the argument 'map'. This
- * function is used to find an available overflow page within a
- * splitnumber.
- *
*/
-static uint32
+static uint32
_hash_firstfreebit(uint32 map)
{
- uint32 i, mask;
-
- mask = 0x1;
- for (i = 0; i < BITS_PER_MAP; i++) {
- if (!(mask & map))
- return (i);
- mask = mask << 1;
- }
- return (i);
+ uint32 i,
+ mask;
+
+ mask = 0x1;
+ for (i = 0; i < BITS_PER_MAP; i++)
+ {
+ if (!(mask & map))
+ return (i);
+ mask = mask << 1;
+ }
+ return (i);
}
/*
- * _hash_freeovflpage() -
+ * _hash_freeovflpage() -
*
- * Mark this overflow page as free and return a buffer with
- * the page that follows it (which may be defined as
- * InvalidBuffer).
+ * Mark this overflow page as free and return a buffer with
+ * the page that follows it (which may be defined as
+ * InvalidBuffer).
*
*/
Buffer
_hash_freeovflpage(Relation rel, Buffer ovflbuf)
{
- HashMetaPage metap;
- Buffer metabuf;
- Buffer mapbuf;
- BlockNumber prevblkno;
- BlockNumber blkno;
- BlockNumber nextblkno;
- HashPageOpaque ovflopaque;
- Page ovflpage;
- Page mappage;
- OverflowPageAddress addr;
- SplitNumber splitnum;
- uint32 *freep;
- uint32 ovflpgno;
- int32 bitmappage, bitmapbit;
- Bucket bucket;
-
- metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE);
- metap = (HashMetaPage) BufferGetPage(metabuf);
- _hash_checkpage((Page) metap, LH_META_PAGE);
-
- ovflpage = BufferGetPage(ovflbuf);
- _hash_checkpage(ovflpage, LH_OVERFLOW_PAGE);
- ovflopaque = (HashPageOpaque) PageGetSpecialPointer(ovflpage);
- addr = ovflopaque->hasho_oaddr;
- nextblkno = ovflopaque->hasho_nextblkno;
- prevblkno = ovflopaque->hasho_prevblkno;
- bucket = ovflopaque->hasho_bucket;
- memset(ovflpage, 0, BufferGetPageSize(ovflbuf));
- _hash_wrtbuf(rel, ovflbuf);
-
- /*
- * fix up the bucket chain. this is a doubly-linked list, so we
- * must fix up the bucket chain members behind and ahead of the
- * overflow page being deleted.
- *
- * XXX this should look like:
- * - lock prev/next
- * - modify/write prev/next (how to do write ordering with a
- * doubly-linked list?)
- * - unlock prev/next
- */
- if (BlockNumberIsValid(prevblkno)) {
- Buffer prevbuf = _hash_getbuf(rel, prevblkno, HASH_WRITE);
- Page prevpage = BufferGetPage(prevbuf);
- HashPageOpaque prevopaque =
- (HashPageOpaque) PageGetSpecialPointer(prevpage);
-
- _hash_checkpage(prevpage, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
- Assert(prevopaque->hasho_bucket == bucket);
- prevopaque->hasho_nextblkno = nextblkno;
- _hash_wrtbuf(rel, prevbuf);
- }
- if (BlockNumberIsValid(nextblkno)) {
- Buffer nextbuf = _hash_getbuf(rel, nextblkno, HASH_WRITE);
- Page nextpage = BufferGetPage(nextbuf);
- HashPageOpaque nextopaque =
- (HashPageOpaque) PageGetSpecialPointer(nextpage);
-
- _hash_checkpage(nextpage, LH_OVERFLOW_PAGE);
- Assert(nextopaque->hasho_bucket == bucket);
- nextopaque->hasho_prevblkno = prevblkno;
- _hash_wrtbuf(rel, nextbuf);
- }
-
- /*
- * Fix up the overflow page bitmap that tracks this particular
- * overflow page. The bitmap can be found in the MetaPageData
- * array element hashm_mapp[bitmappage].
- */
- splitnum = (addr >> SPLITSHIFT);
- ovflpgno =
- (splitnum ? metap->SPARES[splitnum - 1] : 0) + (addr & SPLITMASK) - 1;
-
- if (ovflpgno < metap->LAST_FREED) {
- metap->LAST_FREED = ovflpgno;
- }
-
- bitmappage = (ovflpgno >> (metap->BSHIFT + BYTE_TO_BIT));
- bitmapbit = ovflpgno & (BMPGSZ_BIT(metap) - 1);
-
- blkno = metap->hashm_mapp[bitmappage];
- mapbuf = _hash_getbuf(rel, blkno, HASH_WRITE);
- mappage = BufferGetPage(mapbuf);
- _hash_checkpage(mappage, LH_BITMAP_PAGE);
- freep = HashPageGetBitmap(mappage);
- CLRBIT(freep, bitmapbit);
- _hash_wrtbuf(rel, mapbuf);
-
- _hash_relbuf(rel, metabuf, HASH_WRITE);
-
- /*
- * now instantiate the page that replaced this one,
- * if it exists, and return that buffer with a write lock.
- */
- if (BlockNumberIsValid(nextblkno)) {
- return (_hash_getbuf(rel, nextblkno, HASH_WRITE));
- } else {
- return (InvalidBuffer);
- }
+ HashMetaPage metap;
+ Buffer metabuf;
+ Buffer mapbuf;
+ BlockNumber prevblkno;
+ BlockNumber blkno;
+ BlockNumber nextblkno;
+ HashPageOpaque ovflopaque;
+ Page ovflpage;
+ Page mappage;
+ OverflowPageAddress addr;
+ SplitNumber splitnum;
+ uint32 *freep;
+ uint32 ovflpgno;
+ int32 bitmappage,
+ bitmapbit;
+ Bucket bucket;
+
+ metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE);
+ metap = (HashMetaPage) BufferGetPage(metabuf);
+ _hash_checkpage((Page) metap, LH_META_PAGE);
+
+ ovflpage = BufferGetPage(ovflbuf);
+ _hash_checkpage(ovflpage, LH_OVERFLOW_PAGE);
+ ovflopaque = (HashPageOpaque) PageGetSpecialPointer(ovflpage);
+ addr = ovflopaque->hasho_oaddr;
+ nextblkno = ovflopaque->hasho_nextblkno;
+ prevblkno = ovflopaque->hasho_prevblkno;
+ bucket = ovflopaque->hasho_bucket;
+ memset(ovflpage, 0, BufferGetPageSize(ovflbuf));
+ _hash_wrtbuf(rel, ovflbuf);
+
+ /*
+ * fix up the bucket chain. this is a doubly-linked list, so we must
+ * fix up the bucket chain members behind and ahead of the overflow
+ * page being deleted.
+ *
+ * XXX this should look like: - lock prev/next - modify/write prev/next
+ * (how to do write ordering with a doubly-linked list?) - unlock
+ * prev/next
+ */
+ if (BlockNumberIsValid(prevblkno))
+ {
+ Buffer prevbuf = _hash_getbuf(rel, prevblkno, HASH_WRITE);
+ Page prevpage = BufferGetPage(prevbuf);
+ HashPageOpaque prevopaque =
+ (HashPageOpaque) PageGetSpecialPointer(prevpage);
+
+ _hash_checkpage(prevpage, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
+ Assert(prevopaque->hasho_bucket == bucket);
+ prevopaque->hasho_nextblkno = nextblkno;
+ _hash_wrtbuf(rel, prevbuf);
+ }
+ if (BlockNumberIsValid(nextblkno))
+ {
+ Buffer nextbuf = _hash_getbuf(rel, nextblkno, HASH_WRITE);
+ Page nextpage = BufferGetPage(nextbuf);
+ HashPageOpaque nextopaque =
+ (HashPageOpaque) PageGetSpecialPointer(nextpage);
+
+ _hash_checkpage(nextpage, LH_OVERFLOW_PAGE);
+ Assert(nextopaque->hasho_bucket == bucket);
+ nextopaque->hasho_prevblkno = prevblkno;
+ _hash_wrtbuf(rel, nextbuf);
+ }
+
+ /*
+ * Fix up the overflow page bitmap that tracks this particular
+ * overflow page. The bitmap can be found in the MetaPageData array
+ * element hashm_mapp[bitmappage].
+ */
+ splitnum = (addr >> SPLITSHIFT);
+ ovflpgno =
+ (splitnum ? metap->SPARES[splitnum - 1] : 0) + (addr & SPLITMASK) - 1;
+
+ if (ovflpgno < metap->LAST_FREED)
+ {
+ metap->LAST_FREED = ovflpgno;
+ }
+
+ bitmappage = (ovflpgno >> (metap->BSHIFT + BYTE_TO_BIT));
+ bitmapbit = ovflpgno & (BMPGSZ_BIT(metap) - 1);
+
+ blkno = metap->hashm_mapp[bitmappage];
+ mapbuf = _hash_getbuf(rel, blkno, HASH_WRITE);
+ mappage = BufferGetPage(mapbuf);
+ _hash_checkpage(mappage, LH_BITMAP_PAGE);
+ freep = HashPageGetBitmap(mappage);
+ CLRBIT(freep, bitmapbit);
+ _hash_wrtbuf(rel, mapbuf);
+
+ _hash_relbuf(rel, metabuf, HASH_WRITE);
+
+ /*
+ * now instantiate the page that replaced this one, if it exists, and
+ * return that buffer with a write lock.
+ */
+ if (BlockNumberIsValid(nextblkno))
+ {
+ return (_hash_getbuf(rel, nextblkno, HASH_WRITE));
+ }
+ else
+ {
+ return (InvalidBuffer);
+ }
}
/*
- * _hash_initbitmap()
- *
- * Initialize a new bitmap page. The metapage has a write-lock upon
- * entering the function.
+ * _hash_initbitmap()
+ *
+ * Initialize a new bitmap page. The metapage has a write-lock upon
+ * entering the function.
*
* 'pnum' is the OverflowPageAddress of the new bitmap page.
* 'nbits' is how many bits to clear (i.e., make available) in the new
@@ -404,211 +427,219 @@ _hash_freeovflpage(Relation rel, Buffer ovflbuf)
* metapage's array of bitmap page OverflowPageAddresses.
*/
-#define INT_MASK ((1 << INT_TO_BIT) -1)
+#define INT_MASK ((1 << INT_TO_BIT) -1)
int32
_hash_initbitmap(Relation rel,
- HashMetaPage metap,
- int32 pnum,
- int32 nbits,
- int32 ndx)
+ HashMetaPage metap,
+ int32 pnum,
+ int32 nbits,
+ int32 ndx)
{
- Buffer buf;
- BlockNumber blkno;
- Page pg;
- HashPageOpaque op;
- uint32 *freep;
- int clearbytes, clearints;
-
- blkno = OADDR_TO_BLKNO(pnum);
- buf = _hash_getbuf(rel, blkno, HASH_WRITE);
- pg = BufferGetPage(buf);
- _hash_pageinit(pg, BufferGetPageSize(buf));
- op = (HashPageOpaque) PageGetSpecialPointer(pg);
- op->hasho_oaddr = InvalidOvflAddress;
- op->hasho_prevblkno = InvalidBlockNumber;
- op->hasho_nextblkno = InvalidBlockNumber;
- op->hasho_flag = LH_BITMAP_PAGE;
- op->hasho_bucket = -1;
-
- freep = HashPageGetBitmap(pg);
-
- /* set all of the bits above 'nbits' to 1 */
- clearints = ((nbits - 1) >> INT_TO_BIT) + 1;
- clearbytes = clearints << INT_TO_BYTE;
- memset((char *) freep, 0, clearbytes);
- memset(((char *) freep) + clearbytes, 0xFF,
- BMPGSZ_BYTE(metap) - clearbytes);
- freep[clearints - 1] = ALL_SET << (nbits & INT_MASK);
-
- /* bit 0 represents the new bitmap page */
- SETBIT(freep, 0);
-
- /* metapage already has a write lock */
- metap->hashm_nmaps++;
- metap->hashm_mapp[ndx] = blkno;
-
- /* write out the new bitmap page (releasing its locks) */
- _hash_wrtbuf(rel, buf);
-
- return (0);
+ Buffer buf;
+ BlockNumber blkno;
+ Page pg;
+ HashPageOpaque op;
+ uint32 *freep;
+ int clearbytes,
+ clearints;
+
+ blkno = OADDR_TO_BLKNO(pnum);
+ buf = _hash_getbuf(rel, blkno, HASH_WRITE);
+ pg = BufferGetPage(buf);
+ _hash_pageinit(pg, BufferGetPageSize(buf));
+ op = (HashPageOpaque) PageGetSpecialPointer(pg);
+ op->hasho_oaddr = InvalidOvflAddress;
+ op->hasho_prevblkno = InvalidBlockNumber;
+ op->hasho_nextblkno = InvalidBlockNumber;
+ op->hasho_flag = LH_BITMAP_PAGE;
+ op->hasho_bucket = -1;
+
+ freep = HashPageGetBitmap(pg);
+
+ /* set all of the bits above 'nbits' to 1 */
+ clearints = ((nbits - 1) >> INT_TO_BIT) + 1;
+ clearbytes = clearints << INT_TO_BYTE;
+ memset((char *) freep, 0, clearbytes);
+ memset(((char *) freep) + clearbytes, 0xFF,
+ BMPGSZ_BYTE(metap) - clearbytes);
+ freep[clearints - 1] = ALL_SET << (nbits & INT_MASK);
+
+ /* bit 0 represents the new bitmap page */
+ SETBIT(freep, 0);
+
+ /* metapage already has a write lock */
+ metap->hashm_nmaps++;
+ metap->hashm_mapp[ndx] = blkno;
+
+ /* write out the new bitmap page (releasing its locks) */
+ _hash_wrtbuf(rel, buf);
+
+ return (0);
}
/*
- * _hash_squeezebucket(rel, bucket)
+ * _hash_squeezebucket(rel, bucket)
*
- * Try to squeeze the tuples onto pages occuring earlier in the
- * bucket chain in an attempt to free overflow pages. When we start
- * the "squeezing", the page from which we start taking tuples (the
- * "read" page) is the last bucket in the bucket chain and the page
- * onto which we start squeezing tuples (the "write" page) is the
- * first page in the bucket chain. The read page works backward and
- * the write page works forward; the procedure terminates when the
- * read page and write page are the same page.
+ * Try to squeeze the tuples onto pages occuring earlier in the
+ * bucket chain in an attempt to free overflow pages. When we start
+ * the "squeezing", the page from which we start taking tuples (the
+ * "read" page) is the last bucket in the bucket chain and the page
+ * onto which we start squeezing tuples (the "write" page) is the
+ * first page in the bucket chain. The read page works backward and
+ * the write page works forward; the procedure terminates when the
+ * read page and write page are the same page.
*/
void
_hash_squeezebucket(Relation rel,
- HashMetaPage metap,
- Bucket bucket)
+ HashMetaPage metap,
+ Bucket bucket)
{
- Buffer wbuf;
- Buffer rbuf = 0;
- BlockNumber wblkno;
- BlockNumber rblkno;
- Page wpage;
- Page rpage;
- HashPageOpaque wopaque;
- HashPageOpaque ropaque;
- OffsetNumber woffnum;
- OffsetNumber roffnum;
- HashItem hitem;
- int itemsz;
-
-/* elog(DEBUG, "_hash_squeezebucket: squeezing bucket %d", bucket); */
-
- /*
- * start squeezing into the base bucket page.
- */
- wblkno = BUCKET_TO_BLKNO(bucket);
- wbuf = _hash_getbuf(rel, wblkno, HASH_WRITE);
- wpage = BufferGetPage(wbuf);
- _hash_checkpage(wpage, LH_BUCKET_PAGE);
- wopaque = (HashPageOpaque) PageGetSpecialPointer(wpage);
-
- /*
- * if there aren't any overflow pages, there's nothing to squeeze.
- */
- if (!BlockNumberIsValid(wopaque->hasho_nextblkno)) {
- _hash_relbuf(rel, wbuf, HASH_WRITE);
- return;
- }
-
- /*
- * find the last page in the bucket chain by starting at the base
- * bucket page and working forward.
- *
- * XXX if chains tend to be long, we should probably move forward
- * using HASH_READ and then _hash_chgbufaccess to HASH_WRITE when
- * we reach the end. if they are short we probably don't care
- * very much. if the hash function is working at all, they had
- * better be short..
- */
- ropaque = wopaque;
- do {
- rblkno = ropaque->hasho_nextblkno;
- if (ropaque != wopaque) {
- _hash_relbuf(rel, rbuf, HASH_WRITE);
- }
- rbuf = _hash_getbuf(rel, rblkno, HASH_WRITE);
- rpage = BufferGetPage(rbuf);
- _hash_checkpage(rpage, LH_OVERFLOW_PAGE);
- Assert(!PageIsEmpty(rpage));
- ropaque = (HashPageOpaque) PageGetSpecialPointer(rpage);
- Assert(ropaque->hasho_bucket == bucket);
- } while (BlockNumberIsValid(ropaque->hasho_nextblkno));
-
- /*
- * squeeze the tuples.
- */
- roffnum = FirstOffsetNumber;
- for(;;) {
- hitem = (HashItem) PageGetItem(rpage, PageGetItemId(rpage, roffnum));
- itemsz = IndexTupleDSize(hitem->hash_itup)
- + (sizeof(HashItemData) - sizeof(IndexTupleData));
- itemsz = DOUBLEALIGN(itemsz);
-
+ Buffer wbuf;
+ Buffer rbuf = 0;
+ BlockNumber wblkno;
+ BlockNumber rblkno;
+ Page wpage;
+ Page rpage;
+ HashPageOpaque wopaque;
+ HashPageOpaque ropaque;
+ OffsetNumber woffnum;
+ OffsetNumber roffnum;
+ HashItem hitem;
+ int itemsz;
+
+/* elog(DEBUG, "_hash_squeezebucket: squeezing bucket %d", bucket); */
+
/*
- * walk up the bucket chain, looking for a page big enough for
- * this item.
+ * start squeezing into the base bucket page.
*/
- while (PageGetFreeSpace(wpage) < itemsz) {
- wblkno = wopaque->hasho_nextblkno;
+ wblkno = BUCKET_TO_BLKNO(bucket);
+ wbuf = _hash_getbuf(rel, wblkno, HASH_WRITE);
+ wpage = BufferGetPage(wbuf);
+ _hash_checkpage(wpage, LH_BUCKET_PAGE);
+ wopaque = (HashPageOpaque) PageGetSpecialPointer(wpage);
- _hash_wrtbuf(rel, wbuf);
-
- if (!BlockNumberIsValid(wblkno) || (rblkno == wblkno)) {
- _hash_wrtbuf(rel, rbuf);
- /* wbuf is already released */
+ /*
+ * if there aren't any overflow pages, there's nothing to squeeze.
+ */
+ if (!BlockNumberIsValid(wopaque->hasho_nextblkno))
+ {
+ _hash_relbuf(rel, wbuf, HASH_WRITE);
return;
- }
-
- wbuf = _hash_getbuf(rel, wblkno, HASH_WRITE);
- wpage = BufferGetPage(wbuf);
- _hash_checkpage(wpage, LH_OVERFLOW_PAGE);
- Assert(!PageIsEmpty(wpage));
- wopaque = (HashPageOpaque) PageGetSpecialPointer(wpage);
- Assert(wopaque->hasho_bucket == bucket);
}
-
- /*
- * if we're here, we have found room so insert on the "write"
- * page.
- */
- woffnum = OffsetNumberNext(PageGetMaxOffsetNumber(wpage));
- PageAddItem(wpage, (Item) hitem, itemsz, woffnum, LP_USED);
-
- /*
- * delete the tuple from the "read" page.
- * PageIndexTupleDelete repacks the ItemId array, so 'roffnum'
- * will be "advanced" to the "next" ItemId.
+
+ /*
+ * find the last page in the bucket chain by starting at the base
+ * bucket page and working forward.
+ *
+ * XXX if chains tend to be long, we should probably move forward using
+ * HASH_READ and then _hash_chgbufaccess to HASH_WRITE when we reach
+ * the end. if they are short we probably don't care very much. if
+ * the hash function is working at all, they had better be short..
*/
- PageIndexTupleDelete(rpage, roffnum);
- _hash_wrtnorelbuf(rel, rbuf);
-
+ ropaque = wopaque;
+ do
+ {
+ rblkno = ropaque->hasho_nextblkno;
+ if (ropaque != wopaque)
+ {
+ _hash_relbuf(rel, rbuf, HASH_WRITE);
+ }
+ rbuf = _hash_getbuf(rel, rblkno, HASH_WRITE);
+ rpage = BufferGetPage(rbuf);
+ _hash_checkpage(rpage, LH_OVERFLOW_PAGE);
+ Assert(!PageIsEmpty(rpage));
+ ropaque = (HashPageOpaque) PageGetSpecialPointer(rpage);
+ Assert(ropaque->hasho_bucket == bucket);
+ } while (BlockNumberIsValid(ropaque->hasho_nextblkno));
+
/*
- * if the "read" page is now empty because of the deletion,
- * free it.
+ * squeeze the tuples.
*/
- if (PageIsEmpty(rpage) && (ropaque->hasho_flag & LH_OVERFLOW_PAGE)) {
- rblkno = ropaque->hasho_prevblkno;
- Assert(BlockNumberIsValid(rblkno));
-
- /*
- * free this overflow page. the extra _hash_relbuf is
- * because _hash_freeovflpage gratuitously returns the
- * next page (we want the previous page and will get it
- * ourselves later).
- */
- rbuf = _hash_freeovflpage(rel, rbuf);
- if (BufferIsValid(rbuf)) {
- _hash_relbuf(rel, rbuf, HASH_WRITE);
- }
-
- if (rblkno == wblkno) {
- /* rbuf is already released */
- _hash_wrtbuf(rel, wbuf);
- return;
- }
-
- rbuf = _hash_getbuf(rel, rblkno, HASH_WRITE);
- rpage = BufferGetPage(rbuf);
- _hash_checkpage(rpage, LH_OVERFLOW_PAGE);
- Assert(!PageIsEmpty(rpage));
- ropaque = (HashPageOpaque) PageGetSpecialPointer(rpage);
- Assert(ropaque->hasho_bucket == bucket);
-
- roffnum = FirstOffsetNumber;
+ roffnum = FirstOffsetNumber;
+ for (;;)
+ {
+ hitem = (HashItem) PageGetItem(rpage, PageGetItemId(rpage, roffnum));
+ itemsz = IndexTupleDSize(hitem->hash_itup)
+ + (sizeof(HashItemData) - sizeof(IndexTupleData));
+ itemsz = DOUBLEALIGN(itemsz);
+
+ /*
+ * walk up the bucket chain, looking for a page big enough for
+ * this item.
+ */
+ while (PageGetFreeSpace(wpage) < itemsz)
+ {
+ wblkno = wopaque->hasho_nextblkno;
+
+ _hash_wrtbuf(rel, wbuf);
+
+ if (!BlockNumberIsValid(wblkno) || (rblkno == wblkno))
+ {
+ _hash_wrtbuf(rel, rbuf);
+ /* wbuf is already released */
+ return;
+ }
+
+ wbuf = _hash_getbuf(rel, wblkno, HASH_WRITE);
+ wpage = BufferGetPage(wbuf);
+ _hash_checkpage(wpage, LH_OVERFLOW_PAGE);
+ Assert(!PageIsEmpty(wpage));
+ wopaque = (HashPageOpaque) PageGetSpecialPointer(wpage);
+ Assert(wopaque->hasho_bucket == bucket);
+ }
+
+ /*
+ * if we're here, we have found room so insert on the "write"
+ * page.
+ */
+ woffnum = OffsetNumberNext(PageGetMaxOffsetNumber(wpage));
+ PageAddItem(wpage, (Item) hitem, itemsz, woffnum, LP_USED);
+
+ /*
+ * delete the tuple from the "read" page. PageIndexTupleDelete
+ * repacks the ItemId array, so 'roffnum' will be "advanced" to
+ * the "next" ItemId.
+ */
+ PageIndexTupleDelete(rpage, roffnum);
+ _hash_wrtnorelbuf(rel, rbuf);
+
+ /*
+ * if the "read" page is now empty because of the deletion, free
+ * it.
+ */
+ if (PageIsEmpty(rpage) && (ropaque->hasho_flag & LH_OVERFLOW_PAGE))
+ {
+ rblkno = ropaque->hasho_prevblkno;
+ Assert(BlockNumberIsValid(rblkno));
+
+ /*
+ * free this overflow page. the extra _hash_relbuf is because
+ * _hash_freeovflpage gratuitously returns the next page (we
+ * want the previous page and will get it ourselves later).
+ */
+ rbuf = _hash_freeovflpage(rel, rbuf);
+ if (BufferIsValid(rbuf))
+ {
+ _hash_relbuf(rel, rbuf, HASH_WRITE);
+ }
+
+ if (rblkno == wblkno)
+ {
+ /* rbuf is already released */
+ _hash_wrtbuf(rel, wbuf);
+ return;
+ }
+
+ rbuf = _hash_getbuf(rel, rblkno, HASH_WRITE);
+ rpage = BufferGetPage(rbuf);
+ _hash_checkpage(rpage, LH_OVERFLOW_PAGE);
+ Assert(!PageIsEmpty(rpage));
+ ropaque = (HashPageOpaque) PageGetSpecialPointer(rpage);
+ Assert(ropaque->hasho_bucket == bucket);
+
+ roffnum = FirstOffsetNumber;
+ }
}
- }
}
diff --git a/src/backend/access/hash/hashpage.c b/src/backend/access/hash/hashpage.c
index 49c8f03f524..6c819b652d2 100644
--- a/src/backend/access/hash/hashpage.c
+++ b/src/backend/access/hash/hashpage.c
@@ -1,30 +1,30 @@
/*-------------------------------------------------------------------------
*
* hashpage.c--
- * Hash table page management code for the Postgres hash access method
+ * Hash table page management code for the Postgres hash access method
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v 1.9 1997/08/18 20:51:34 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v 1.10 1997/09/07 04:38:00 momjian Exp $
*
* NOTES
- * Postgres hash pages look like ordinary relation pages. The opaque
- * data at high addresses includes information about the page including
- * whether a page is an overflow page or a true bucket, the block
- * numbers of the preceding and following pages, and the overflow
- * address of the page if it is an overflow page.
+ * Postgres hash pages look like ordinary relation pages. The opaque
+ * data at high addresses includes information about the page including
+ * whether a page is an overflow page or a true bucket, the block
+ * numbers of the preceding and following pages, and the overflow
+ * address of the page if it is an overflow page.
*
- * The first page in a hash relation, page zero, is special -- it stores
- * information describing the hash table; it is referred to as teh
- * "meta page." Pages one and higher store the actual data.
+ * The first page in a hash relation, page zero, is special -- it stores
+ * information describing the hash table; it is referred to as teh
+ * "meta page." Pages one and higher store the actual data.
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <access/hash.h>
#include <storage/bufmgr.h>
#include <miscadmin.h>
@@ -33,411 +33,429 @@
#include <access/genam.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static void _hash_setpagelock(Relation rel, BlockNumber blkno, int access);
-static void _hash_unsetpagelock(Relation rel, BlockNumber blkno, int access);
-static void _hash_splitpage(Relation rel, Buffer metabuf, Bucket obucket, Bucket nbucket);
-
-/*
- * We use high-concurrency locking on hash indices. There are two cases in
- * which we don't do locking. One is when we're building the index.
- * Since the creating transaction has not committed, no one can see
- * the index, and there's no reason to share locks. The second case
- * is when we're just starting up the database system. We use some
- * special-purpose initialization code in the relation cache manager
- * (see utils/cache/relcache.c) to allow us to do indexed scans on
- * the system catalogs before we'd normally be able to. This happens
- * before the lock table is fully initialized, so we can't use it.
- * Strictly speaking, this violates 2pl, but we don't do 2pl on the
- * system catalogs anyway.
+static void _hash_setpagelock(Relation rel, BlockNumber blkno, int access);
+static void _hash_unsetpagelock(Relation rel, BlockNumber blkno, int access);
+static void _hash_splitpage(Relation rel, Buffer metabuf, Bucket obucket, Bucket nbucket);
+
+/*
+ * We use high-concurrency locking on hash indices. There are two cases in
+ * which we don't do locking. One is when we're building the index.
+ * Since the creating transaction has not committed, no one can see
+ * the index, and there's no reason to share locks. The second case
+ * is when we're just starting up the database system. We use some
+ * special-purpose initialization code in the relation cache manager
+ * (see utils/cache/relcache.c) to allow us to do indexed scans on
+ * the system catalogs before we'd normally be able to. This happens
+ * before the lock table is fully initialized, so we can't use it.
+ * Strictly speaking, this violates 2pl, but we don't do 2pl on the
+ * system catalogs anyway.
*/
-#define USELOCKING (!BuildingHash && !IsInitProcessingMode())
+#define USELOCKING (!BuildingHash && !IsInitProcessingMode())
/*
- * _hash_metapinit() -- Initialize the metadata page of a hash index,
- * the two buckets that we begin with and the initial
- * bitmap page.
+ * _hash_metapinit() -- Initialize the metadata page of a hash index,
+ * the two buckets that we begin with and the initial
+ * bitmap page.
*/
void
_hash_metapinit(Relation rel)
{
- HashMetaPage metap;
- HashPageOpaque pageopaque;
- Buffer metabuf;
- Buffer buf;
- Page pg;
- int nbuckets;
- uint32 nelem; /* number elements */
- uint32 lg2nelem; /* _hash_log2(nelem) */
- uint32 nblocks;
- uint16 i;
-
- /* can't be sharing this with anyone, now... */
- if (USELOCKING)
- RelationSetLockForWrite(rel);
-
- if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0) {
- elog(WARN, "Cannot initialize non-empty hash table %s",
- RelationGetRelationName(rel));
- }
-
- metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE);
- pg = BufferGetPage(metabuf);
- metap = (HashMetaPage) pg;
- _hash_pageinit(pg, BufferGetPageSize(metabuf));
-
- metap->hashm_magic = HASH_MAGIC;
- metap->hashm_version = HASH_VERSION;
- metap->hashm_nkeys = 0;
- metap->hashm_nmaps = 0;
- metap->hashm_ffactor = DEFAULT_FFACTOR;
- metap->hashm_bsize = BufferGetPageSize(metabuf);
- metap->hashm_bshift = _hash_log2(metap->hashm_bsize);
- for (i = metap->hashm_bshift; i > 0; --i) {
- if ((1 << i) < (metap->hashm_bsize -
- (DOUBLEALIGN(sizeof(PageHeaderData)) +
- DOUBLEALIGN(sizeof(HashPageOpaqueData))))) {
- break;
+ HashMetaPage metap;
+ HashPageOpaque pageopaque;
+ Buffer metabuf;
+ Buffer buf;
+ Page pg;
+ int nbuckets;
+ uint32 nelem; /* number elements */
+ uint32 lg2nelem; /* _hash_log2(nelem) */
+ uint32 nblocks;
+ uint16 i;
+
+ /* can't be sharing this with anyone, now... */
+ if (USELOCKING)
+ RelationSetLockForWrite(rel);
+
+ if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0)
+ {
+ elog(WARN, "Cannot initialize non-empty hash table %s",
+ RelationGetRelationName(rel));
+ }
+
+ metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE);
+ pg = BufferGetPage(metabuf);
+ metap = (HashMetaPage) pg;
+ _hash_pageinit(pg, BufferGetPageSize(metabuf));
+
+ metap->hashm_magic = HASH_MAGIC;
+ metap->hashm_version = HASH_VERSION;
+ metap->hashm_nkeys = 0;
+ metap->hashm_nmaps = 0;
+ metap->hashm_ffactor = DEFAULT_FFACTOR;
+ metap->hashm_bsize = BufferGetPageSize(metabuf);
+ metap->hashm_bshift = _hash_log2(metap->hashm_bsize);
+ for (i = metap->hashm_bshift; i > 0; --i)
+ {
+ if ((1 << i) < (metap->hashm_bsize -
+ (DOUBLEALIGN(sizeof(PageHeaderData)) +
+ DOUBLEALIGN(sizeof(HashPageOpaqueData)))))
+ {
+ break;
+ }
}
- }
- Assert(i);
- metap->hashm_bmsize = 1 << i;
- metap->hashm_procid = index_getprocid(rel, 1, HASHPROC);
-
- /*
- * Make nelem = 2 rather than 0 so that we end up allocating space
- * for the next greater power of two number of buckets.
- */
- nelem = 2;
- lg2nelem = 1; /*_hash_log2(MAX(nelem, 2)) */
- nbuckets = 2; /*1 << lg2nelem */
-
- memset((char *) metap->hashm_spares, 0, sizeof(metap->hashm_spares));
- memset((char *) metap->hashm_mapp, 0, sizeof(metap->hashm_mapp));
-
- metap->hashm_spares[lg2nelem] = 2; /* lg2nelem + 1 */
- metap->hashm_spares[lg2nelem + 1] = 2; /* lg2nelem + 1 */
- metap->hashm_ovflpoint = 1; /* lg2nelem */
- metap->hashm_lastfreed = 2;
-
- metap->hashm_maxbucket = metap->hashm_lowmask = 1; /* nbuckets - 1 */
- metap->hashm_highmask = 3; /* (nbuckets << 1) - 1 */
-
- pageopaque = (HashPageOpaque) PageGetSpecialPointer(pg);
- pageopaque->hasho_oaddr = InvalidOvflAddress;
- pageopaque->hasho_prevblkno = InvalidBlockNumber;
- pageopaque->hasho_nextblkno = InvalidBlockNumber;
- pageopaque->hasho_flag = LH_META_PAGE;
- pageopaque->hasho_bucket = -1;
-
- /*
- * First bitmap page is at: splitpoint lg2nelem page offset 1 which
- * turns out to be page 3. Couldn't initialize page 3 until we created
- * the first two buckets above.
- */
- if (_hash_initbitmap(rel, metap, OADDR_OF(lg2nelem, 1), lg2nelem + 1, 0))
- elog(WARN, "Problem with _hash_initbitmap.");
-
- /* all done */
- _hash_wrtnorelbuf(rel, metabuf);
-
- /*
- * initialize the first two buckets
- */
- for (i = 0; i <= 1; i++) {
- buf = _hash_getbuf(rel, BUCKET_TO_BLKNO(i), HASH_WRITE);
- pg = BufferGetPage(buf);
- _hash_pageinit(pg, BufferGetPageSize(buf));
+ Assert(i);
+ metap->hashm_bmsize = 1 << i;
+ metap->hashm_procid = index_getprocid(rel, 1, HASHPROC);
+
+ /*
+ * Make nelem = 2 rather than 0 so that we end up allocating space for
+ * the next greater power of two number of buckets.
+ */
+ nelem = 2;
+ lg2nelem = 1; /* _hash_log2(MAX(nelem, 2)) */
+ nbuckets = 2; /* 1 << lg2nelem */
+
+ memset((char *) metap->hashm_spares, 0, sizeof(metap->hashm_spares));
+ memset((char *) metap->hashm_mapp, 0, sizeof(metap->hashm_mapp));
+
+ metap->hashm_spares[lg2nelem] = 2; /* lg2nelem + 1 */
+ metap->hashm_spares[lg2nelem + 1] = 2; /* lg2nelem + 1 */
+ metap->hashm_ovflpoint = 1; /* lg2nelem */
+ metap->hashm_lastfreed = 2;
+
+ metap->hashm_maxbucket = metap->hashm_lowmask = 1; /* nbuckets - 1 */
+ metap->hashm_highmask = 3; /* (nbuckets << 1) - 1 */
+
pageopaque = (HashPageOpaque) PageGetSpecialPointer(pg);
pageopaque->hasho_oaddr = InvalidOvflAddress;
pageopaque->hasho_prevblkno = InvalidBlockNumber;
pageopaque->hasho_nextblkno = InvalidBlockNumber;
- pageopaque->hasho_flag = LH_BUCKET_PAGE;
- pageopaque->hasho_bucket = i;
- _hash_wrtbuf(rel, buf);
- }
-
- _hash_relbuf(rel, metabuf, HASH_WRITE);
-
- if (USELOCKING)
- RelationUnsetLockForWrite(rel);
+ pageopaque->hasho_flag = LH_META_PAGE;
+ pageopaque->hasho_bucket = -1;
+
+ /*
+ * First bitmap page is at: splitpoint lg2nelem page offset 1 which
+ * turns out to be page 3. Couldn't initialize page 3 until we
+ * created the first two buckets above.
+ */
+ if (_hash_initbitmap(rel, metap, OADDR_OF(lg2nelem, 1), lg2nelem + 1, 0))
+ elog(WARN, "Problem with _hash_initbitmap.");
+
+ /* all done */
+ _hash_wrtnorelbuf(rel, metabuf);
+
+ /*
+ * initialize the first two buckets
+ */
+ for (i = 0; i <= 1; i++)
+ {
+ buf = _hash_getbuf(rel, BUCKET_TO_BLKNO(i), HASH_WRITE);
+ pg = BufferGetPage(buf);
+ _hash_pageinit(pg, BufferGetPageSize(buf));
+ pageopaque = (HashPageOpaque) PageGetSpecialPointer(pg);
+ pageopaque->hasho_oaddr = InvalidOvflAddress;
+ pageopaque->hasho_prevblkno = InvalidBlockNumber;
+ pageopaque->hasho_nextblkno = InvalidBlockNumber;
+ pageopaque->hasho_flag = LH_BUCKET_PAGE;
+ pageopaque->hasho_bucket = i;
+ _hash_wrtbuf(rel, buf);
+ }
+
+ _hash_relbuf(rel, metabuf, HASH_WRITE);
+
+ if (USELOCKING)
+ RelationUnsetLockForWrite(rel);
}
/*
- * _hash_getbuf() -- Get a buffer by block number for read or write.
+ * _hash_getbuf() -- Get a buffer by block number for read or write.
*
- * When this routine returns, the appropriate lock is set on the
- * requested buffer its reference count is correct.
+ * When this routine returns, the appropriate lock is set on the
+ * requested buffer its reference count is correct.
*
- * XXX P_NEW is not used because, unlike the tree structures, we
- * need the bucket blocks to be at certain block numbers. we must
- * depend on the caller to call _hash_pageinit on the block if it
- * knows that this is a new block.
+ * XXX P_NEW is not used because, unlike the tree structures, we
+ * need the bucket blocks to be at certain block numbers. we must
+ * depend on the caller to call _hash_pageinit on the block if it
+ * knows that this is a new block.
*/
Buffer
_hash_getbuf(Relation rel, BlockNumber blkno, int access)
{
- Buffer buf;
-
- if (blkno == P_NEW) {
- elog(WARN, "_hash_getbuf: internal error: hash AM does not use P_NEW");
- }
- switch (access) {
- case HASH_WRITE:
- case HASH_READ:
- _hash_setpagelock(rel, blkno, access);
- break;
- default:
- elog(WARN, "_hash_getbuf: invalid access (%d) on new blk: %s",
- access, RelationGetRelationName(rel));
- break;
- }
- buf = ReadBuffer(rel, blkno);
-
- /* ref count and lock type are correct */
- return (buf);
+ Buffer buf;
+
+ if (blkno == P_NEW)
+ {
+ elog(WARN, "_hash_getbuf: internal error: hash AM does not use P_NEW");
+ }
+ switch (access)
+ {
+ case HASH_WRITE:
+ case HASH_READ:
+ _hash_setpagelock(rel, blkno, access);
+ break;
+ default:
+ elog(WARN, "_hash_getbuf: invalid access (%d) on new blk: %s",
+ access, RelationGetRelationName(rel));
+ break;
+ }
+ buf = ReadBuffer(rel, blkno);
+
+ /* ref count and lock type are correct */
+ return (buf);
}
/*
- * _hash_relbuf() -- release a locked buffer.
+ * _hash_relbuf() -- release a locked buffer.
*/
void
_hash_relbuf(Relation rel, Buffer buf, int access)
{
- BlockNumber blkno;
-
- blkno = BufferGetBlockNumber(buf);
-
- switch (access) {
- case HASH_WRITE:
- case HASH_READ:
- _hash_unsetpagelock(rel, blkno, access);
- break;
- default:
- elog(WARN, "_hash_relbuf: invalid access (%d) on blk %x: %s",
- access, blkno, RelationGetRelationName(rel));
- }
-
- ReleaseBuffer(buf);
+ BlockNumber blkno;
+
+ blkno = BufferGetBlockNumber(buf);
+
+ switch (access)
+ {
+ case HASH_WRITE:
+ case HASH_READ:
+ _hash_unsetpagelock(rel, blkno, access);
+ break;
+ default:
+ elog(WARN, "_hash_relbuf: invalid access (%d) on blk %x: %s",
+ access, blkno, RelationGetRelationName(rel));
+ }
+
+ ReleaseBuffer(buf);
}
/*
- * _hash_wrtbuf() -- write a hash page to disk.
+ * _hash_wrtbuf() -- write a hash page to disk.
*
- * This routine releases the lock held on the buffer and our reference
- * to it. It is an error to call _hash_wrtbuf() without a write lock
- * or a reference to the buffer.
+ * This routine releases the lock held on the buffer and our reference
+ * to it. It is an error to call _hash_wrtbuf() without a write lock
+ * or a reference to the buffer.
*/
void
_hash_wrtbuf(Relation rel, Buffer buf)
{
- BlockNumber blkno;
-
- blkno = BufferGetBlockNumber(buf);
- WriteBuffer(buf);
- _hash_unsetpagelock(rel, blkno, HASH_WRITE);
+ BlockNumber blkno;
+
+ blkno = BufferGetBlockNumber(buf);
+ WriteBuffer(buf);
+ _hash_unsetpagelock(rel, blkno, HASH_WRITE);
}
/*
- * _hash_wrtnorelbuf() -- write a hash page to disk, but do not release
- * our reference or lock.
+ * _hash_wrtnorelbuf() -- write a hash page to disk, but do not release
+ * our reference or lock.
*
- * It is an error to call _hash_wrtnorelbuf() without a write lock
- * or a reference to the buffer.
+ * It is an error to call _hash_wrtnorelbuf() without a write lock
+ * or a reference to the buffer.
*/
void
_hash_wrtnorelbuf(Relation rel, Buffer buf)
{
- BlockNumber blkno;
-
- blkno = BufferGetBlockNumber(buf);
- WriteNoReleaseBuffer(buf);
+ BlockNumber blkno;
+
+ blkno = BufferGetBlockNumber(buf);
+ WriteNoReleaseBuffer(buf);
}
Page
_hash_chgbufaccess(Relation rel,
- Buffer *bufp,
- int from_access,
- int to_access)
+ Buffer * bufp,
+ int from_access,
+ int to_access)
{
- BlockNumber blkno;
-
- blkno = BufferGetBlockNumber(*bufp);
-
- switch (from_access) {
- case HASH_WRITE:
- _hash_wrtbuf(rel, *bufp);
- break;
- case HASH_READ:
- _hash_relbuf(rel, *bufp, from_access);
- break;
- default:
- elog(WARN, "_hash_chgbufaccess: invalid access (%d) on blk %x: %s",
- from_access, blkno, RelationGetRelationName(rel));
- break;
- }
- *bufp = _hash_getbuf(rel, blkno, to_access);
- return (BufferGetPage(*bufp));
+ BlockNumber blkno;
+
+ blkno = BufferGetBlockNumber(*bufp);
+
+ switch (from_access)
+ {
+ case HASH_WRITE:
+ _hash_wrtbuf(rel, *bufp);
+ break;
+ case HASH_READ:
+ _hash_relbuf(rel, *bufp, from_access);
+ break;
+ default:
+ elog(WARN, "_hash_chgbufaccess: invalid access (%d) on blk %x: %s",
+ from_access, blkno, RelationGetRelationName(rel));
+ break;
+ }
+ *bufp = _hash_getbuf(rel, blkno, to_access);
+ return (BufferGetPage(*bufp));
}
/*
- * _hash_pageinit() -- Initialize a new page.
+ * _hash_pageinit() -- Initialize a new page.
*/
void
_hash_pageinit(Page page, Size size)
{
- Assert(((PageHeader) page)->pd_lower == 0);
- Assert(((PageHeader) page)->pd_upper == 0);
- Assert(((PageHeader) page)->pd_special == 0);
-
- /*
- * Cargo-cult programming -- don't really need this to be zero, but
- * creating new pages is an infrequent occurrence and it makes me feel
- * good when I know they're empty.
- */
- memset(page, 0, size);
-
- PageInit(page, size, sizeof(HashPageOpaqueData));
+ Assert(((PageHeader) page)->pd_lower == 0);
+ Assert(((PageHeader) page)->pd_upper == 0);
+ Assert(((PageHeader) page)->pd_special == 0);
+
+ /*
+ * Cargo-cult programming -- don't really need this to be zero, but
+ * creating new pages is an infrequent occurrence and it makes me feel
+ * good when I know they're empty.
+ */
+ memset(page, 0, size);
+
+ PageInit(page, size, sizeof(HashPageOpaqueData));
}
static void
_hash_setpagelock(Relation rel,
- BlockNumber blkno,
- int access)
+ BlockNumber blkno,
+ int access)
{
- ItemPointerData iptr;
-
- if (USELOCKING) {
- ItemPointerSet(&iptr, blkno, 1);
-
- switch (access) {
- case HASH_WRITE:
- RelationSetSingleWLockPage(rel, &iptr);
- break;
- case HASH_READ:
- RelationSetSingleRLockPage(rel, &iptr);
- break;
- default:
- elog(WARN, "_hash_setpagelock: invalid access (%d) on blk %x: %s",
- access, blkno, RelationGetRelationName(rel));
- break;
+ ItemPointerData iptr;
+
+ if (USELOCKING)
+ {
+ ItemPointerSet(&iptr, blkno, 1);
+
+ switch (access)
+ {
+ case HASH_WRITE:
+ RelationSetSingleWLockPage(rel, &iptr);
+ break;
+ case HASH_READ:
+ RelationSetSingleRLockPage(rel, &iptr);
+ break;
+ default:
+ elog(WARN, "_hash_setpagelock: invalid access (%d) on blk %x: %s",
+ access, blkno, RelationGetRelationName(rel));
+ break;
+ }
}
- }
}
static void
_hash_unsetpagelock(Relation rel,
- BlockNumber blkno,
- int access)
+ BlockNumber blkno,
+ int access)
{
- ItemPointerData iptr;
-
- if (USELOCKING) {
- ItemPointerSet(&iptr, blkno, 1);
-
- switch (access) {
- case HASH_WRITE:
- RelationUnsetSingleWLockPage(rel, &iptr);
- break;
- case HASH_READ:
- RelationUnsetSingleRLockPage(rel, &iptr);
- break;
- default:
- elog(WARN, "_hash_unsetpagelock: invalid access (%d) on blk %x: %s",
- access, blkno, RelationGetRelationName(rel));
- break;
+ ItemPointerData iptr;
+
+ if (USELOCKING)
+ {
+ ItemPointerSet(&iptr, blkno, 1);
+
+ switch (access)
+ {
+ case HASH_WRITE:
+ RelationUnsetSingleWLockPage(rel, &iptr);
+ break;
+ case HASH_READ:
+ RelationUnsetSingleRLockPage(rel, &iptr);
+ break;
+ default:
+ elog(WARN, "_hash_unsetpagelock: invalid access (%d) on blk %x: %s",
+ access, blkno, RelationGetRelationName(rel));
+ break;
+ }
}
- }
}
void
_hash_pagedel(Relation rel, ItemPointer tid)
{
- Buffer buf;
- Buffer metabuf;
- Page page;
- BlockNumber blkno;
- OffsetNumber offno;
- HashMetaPage metap;
- HashPageOpaque opaque;
-
- blkno = ItemPointerGetBlockNumber(tid);
- offno = ItemPointerGetOffsetNumber(tid);
-
- buf = _hash_getbuf(rel, blkno, HASH_WRITE);
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
- opaque = (HashPageOpaque) PageGetSpecialPointer(page);
-
- PageIndexTupleDelete(page, offno);
- _hash_wrtnorelbuf(rel, buf);
-
- if (PageIsEmpty(page) && (opaque->hasho_flag & LH_OVERFLOW_PAGE)) {
- buf = _hash_freeovflpage(rel, buf);
- if (BufferIsValid(buf)) {
- _hash_relbuf(rel, buf, HASH_WRITE);
+ Buffer buf;
+ Buffer metabuf;
+ Page page;
+ BlockNumber blkno;
+ OffsetNumber offno;
+ HashMetaPage metap;
+ HashPageOpaque opaque;
+
+ blkno = ItemPointerGetBlockNumber(tid);
+ offno = ItemPointerGetOffsetNumber(tid);
+
+ buf = _hash_getbuf(rel, blkno, HASH_WRITE);
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
+ opaque = (HashPageOpaque) PageGetSpecialPointer(page);
+
+ PageIndexTupleDelete(page, offno);
+ _hash_wrtnorelbuf(rel, buf);
+
+ if (PageIsEmpty(page) && (opaque->hasho_flag & LH_OVERFLOW_PAGE))
+ {
+ buf = _hash_freeovflpage(rel, buf);
+ if (BufferIsValid(buf))
+ {
+ _hash_relbuf(rel, buf, HASH_WRITE);
+ }
}
- } else {
- _hash_relbuf(rel, buf, HASH_WRITE);
- }
-
- metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE);
- metap = (HashMetaPage) BufferGetPage(metabuf);
- _hash_checkpage((Page) metap, LH_META_PAGE);
- ++metap->hashm_nkeys;
- _hash_wrtbuf(rel, metabuf);
+ else
+ {
+ _hash_relbuf(rel, buf, HASH_WRITE);
+ }
+
+ metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE);
+ metap = (HashMetaPage) BufferGetPage(metabuf);
+ _hash_checkpage((Page) metap, LH_META_PAGE);
+ ++metap->hashm_nkeys;
+ _hash_wrtbuf(rel, metabuf);
}
void
_hash_expandtable(Relation rel, Buffer metabuf)
{
- HashMetaPage metap;
- Bucket old_bucket;
- Bucket new_bucket;
- uint32 spare_ndx;
-
-/* elog(DEBUG, "_hash_expandtable: expanding..."); */
-
- metap = (HashMetaPage) BufferGetPage(metabuf);
- _hash_checkpage((Page) metap, LH_META_PAGE);
-
- metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_READ, HASH_WRITE);
- new_bucket = ++metap->MAX_BUCKET;
- metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_WRITE, HASH_READ);
- old_bucket = (metap->MAX_BUCKET & metap->LOW_MASK);
-
- /*
- * If the split point is increasing (MAX_BUCKET's log base 2
- * * increases), we need to copy the current contents of the spare
- * split bucket to the next bucket.
- */
- spare_ndx = _hash_log2(metap->MAX_BUCKET + 1);
- if (spare_ndx > metap->OVFL_POINT) {
-
- metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_READ, HASH_WRITE);
- metap->SPARES[spare_ndx] = metap->SPARES[metap->OVFL_POINT];
- metap->OVFL_POINT = spare_ndx;
- metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_WRITE, HASH_READ);
- }
-
- if (new_bucket > metap->HIGH_MASK) {
-
- /* Starting a new doubling */
- metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_READ, HASH_WRITE);
- metap->LOW_MASK = metap->HIGH_MASK;
- metap->HIGH_MASK = new_bucket | metap->LOW_MASK;
- metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_WRITE, HASH_READ);
-
- }
- /* Relocate records to the new bucket */
- _hash_splitpage(rel, metabuf, old_bucket, new_bucket);
+ HashMetaPage metap;
+ Bucket old_bucket;
+ Bucket new_bucket;
+ uint32 spare_ndx;
+
+/* elog(DEBUG, "_hash_expandtable: expanding..."); */
+
+ metap = (HashMetaPage) BufferGetPage(metabuf);
+ _hash_checkpage((Page) metap, LH_META_PAGE);
+
+ metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_READ, HASH_WRITE);
+ new_bucket = ++metap->MAX_BUCKET;
+ metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_WRITE, HASH_READ);
+ old_bucket = (metap->MAX_BUCKET & metap->LOW_MASK);
+
+ /*
+ * If the split point is increasing (MAX_BUCKET's log base 2 *
+ * increases), we need to copy the current contents of the spare split
+ * bucket to the next bucket.
+ */
+ spare_ndx = _hash_log2(metap->MAX_BUCKET + 1);
+ if (spare_ndx > metap->OVFL_POINT)
+ {
+
+ metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_READ, HASH_WRITE);
+ metap->SPARES[spare_ndx] = metap->SPARES[metap->OVFL_POINT];
+ metap->OVFL_POINT = spare_ndx;
+ metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_WRITE, HASH_READ);
+ }
+
+ if (new_bucket > metap->HIGH_MASK)
+ {
+
+ /* Starting a new doubling */
+ metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_READ, HASH_WRITE);
+ metap->LOW_MASK = metap->HIGH_MASK;
+ metap->HIGH_MASK = new_bucket | metap->LOW_MASK;
+ metap = (HashMetaPage) _hash_chgbufaccess(rel, &metabuf, HASH_WRITE, HASH_READ);
+
+ }
+ /* Relocate records to the new bucket */
+ _hash_splitpage(rel, metabuf, old_bucket, new_bucket);
}
@@ -450,224 +468,243 @@ _hash_expandtable(Relation rel, Buffer metabuf)
*/
static void
_hash_splitpage(Relation rel,
- Buffer metabuf,
- Bucket obucket,
- Bucket nbucket)
+ Buffer metabuf,
+ Bucket obucket,
+ Bucket nbucket)
{
- Bucket bucket;
- Buffer obuf;
- Buffer nbuf;
- Buffer ovflbuf;
- BlockNumber oblkno;
- BlockNumber nblkno;
- bool null;
- Datum datum;
- HashItem hitem;
- HashPageOpaque oopaque;
- HashPageOpaque nopaque;
- HashMetaPage metap;
- IndexTuple itup;
- int itemsz;
- OffsetNumber ooffnum;
- OffsetNumber noffnum;
- OffsetNumber omaxoffnum;
- Page opage;
- Page npage;
- TupleDesc itupdesc;
-
-/* elog(DEBUG, "_hash_splitpage: splitting %d into %d,%d",
- obucket, obucket, nbucket);
+ Bucket bucket;
+ Buffer obuf;
+ Buffer nbuf;
+ Buffer ovflbuf;
+ BlockNumber oblkno;
+ BlockNumber nblkno;
+ bool null;
+ Datum datum;
+ HashItem hitem;
+ HashPageOpaque oopaque;
+ HashPageOpaque nopaque;
+ HashMetaPage metap;
+ IndexTuple itup;
+ int itemsz;
+ OffsetNumber ooffnum;
+ OffsetNumber noffnum;
+ OffsetNumber omaxoffnum;
+ Page opage;
+ Page npage;
+ TupleDesc itupdesc;
+
+/* elog(DEBUG, "_hash_splitpage: splitting %d into %d,%d",
+ obucket, obucket, nbucket);
*/
- metap = (HashMetaPage) BufferGetPage(metabuf);
- _hash_checkpage((Page) metap, LH_META_PAGE);
-
- /* get the buffers & pages */
- oblkno = BUCKET_TO_BLKNO(obucket);
- nblkno = BUCKET_TO_BLKNO(nbucket);
- obuf = _hash_getbuf(rel, oblkno, HASH_WRITE);
- nbuf = _hash_getbuf(rel, nblkno, HASH_WRITE);
- opage = BufferGetPage(obuf);
- npage = BufferGetPage(nbuf);
-
- /* initialize the new bucket */
- _hash_pageinit(npage, BufferGetPageSize(nbuf));
- nopaque = (HashPageOpaque) PageGetSpecialPointer(npage);
- nopaque->hasho_prevblkno = InvalidBlockNumber;
- nopaque->hasho_nextblkno = InvalidBlockNumber;
- nopaque->hasho_flag = LH_BUCKET_PAGE;
- nopaque->hasho_oaddr = InvalidOvflAddress;
- nopaque->hasho_bucket = nbucket;
- _hash_wrtnorelbuf(rel, nbuf);
-
- /*
- * make sure the old bucket isn't empty. advance 'opage' and
- * friends through the overflow bucket chain until we find a
- * non-empty page.
- *
- * XXX we should only need this once, if we are careful to
- * preserve the invariant that overflow pages are never empty.
- */
- _hash_checkpage(opage, LH_BUCKET_PAGE);
- oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
- if (PageIsEmpty(opage)) {
- oblkno = oopaque->hasho_nextblkno;
- _hash_relbuf(rel, obuf, HASH_WRITE);
- if (!BlockNumberIsValid(oblkno)) {
- /*
- * the old bucket is completely empty; of course, the new
- * bucket will be as well, but since it's a base bucket
- * page we don't care.
- */
- _hash_relbuf(rel, nbuf, HASH_WRITE);
- return;
- }
+ metap = (HashMetaPage) BufferGetPage(metabuf);
+ _hash_checkpage((Page) metap, LH_META_PAGE);
+
+ /* get the buffers & pages */
+ oblkno = BUCKET_TO_BLKNO(obucket);
+ nblkno = BUCKET_TO_BLKNO(nbucket);
obuf = _hash_getbuf(rel, oblkno, HASH_WRITE);
+ nbuf = _hash_getbuf(rel, nblkno, HASH_WRITE);
opage = BufferGetPage(obuf);
- _hash_checkpage(opage, LH_OVERFLOW_PAGE);
- if (PageIsEmpty(opage)) {
- elog(WARN, "_hash_splitpage: empty overflow page %d", oblkno);
- }
- oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
- }
-
- /*
- * we are now guaranteed that 'opage' is not empty. partition the
- * tuples in the old bucket between the old bucket and the new
- * bucket, advancing along their respective overflow bucket chains
- * and adding overflow pages as needed.
- */
- ooffnum = FirstOffsetNumber;
- omaxoffnum = PageGetMaxOffsetNumber(opage);
- for (;;) {
+ npage = BufferGetPage(nbuf);
+
+ /* initialize the new bucket */
+ _hash_pageinit(npage, BufferGetPageSize(nbuf));
+ nopaque = (HashPageOpaque) PageGetSpecialPointer(npage);
+ nopaque->hasho_prevblkno = InvalidBlockNumber;
+ nopaque->hasho_nextblkno = InvalidBlockNumber;
+ nopaque->hasho_flag = LH_BUCKET_PAGE;
+ nopaque->hasho_oaddr = InvalidOvflAddress;
+ nopaque->hasho_bucket = nbucket;
+ _hash_wrtnorelbuf(rel, nbuf);
+
/*
- * at each iteration through this loop, each of these variables
- * should be up-to-date: obuf opage oopaque ooffnum omaxoffnum
+ * make sure the old bucket isn't empty. advance 'opage' and friends
+ * through the overflow bucket chain until we find a non-empty page.
+ *
+ * XXX we should only need this once, if we are careful to preserve the
+ * invariant that overflow pages are never empty.
*/
+ _hash_checkpage(opage, LH_BUCKET_PAGE);
+ oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
+ if (PageIsEmpty(opage))
+ {
+ oblkno = oopaque->hasho_nextblkno;
+ _hash_relbuf(rel, obuf, HASH_WRITE);
+ if (!BlockNumberIsValid(oblkno))
+ {
- /* check if we're at the end of the page */
- if (ooffnum > omaxoffnum) {
- /* at end of page, but check for overflow page */
- oblkno = oopaque->hasho_nextblkno;
- if (BlockNumberIsValid(oblkno)) {
- /*
- * we ran out of tuples on this particular page, but
- * we have more overflow pages; re-init values.
- */
- _hash_wrtbuf(rel, obuf);
+ /*
+ * the old bucket is completely empty; of course, the new
+ * bucket will be as well, but since it's a base bucket page
+ * we don't care.
+ */
+ _hash_relbuf(rel, nbuf, HASH_WRITE);
+ return;
+ }
obuf = _hash_getbuf(rel, oblkno, HASH_WRITE);
opage = BufferGetPage(obuf);
_hash_checkpage(opage, LH_OVERFLOW_PAGE);
- oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
-
- /* we're guaranteed that an ovfl page has at least 1 tuple */
- if (PageIsEmpty(opage)) {
- elog(WARN, "_hash_splitpage: empty ovfl page %d!",
- oblkno);
+ if (PageIsEmpty(opage))
+ {
+ elog(WARN, "_hash_splitpage: empty overflow page %d", oblkno);
}
- ooffnum = FirstOffsetNumber;
- omaxoffnum = PageGetMaxOffsetNumber(opage);
- } else {
+ oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
+ }
+
+ /*
+ * we are now guaranteed that 'opage' is not empty. partition the
+ * tuples in the old bucket between the old bucket and the new bucket,
+ * advancing along their respective overflow bucket chains and adding
+ * overflow pages as needed.
+ */
+ ooffnum = FirstOffsetNumber;
+ omaxoffnum = PageGetMaxOffsetNumber(opage);
+ for (;;)
+ {
+
/*
- * we're at the end of the bucket chain, so now we're
- * really done with everything. before quitting, call
- * _hash_squeezebucket to ensure the tuples in the
- * bucket (including the overflow pages) are packed as
- * tightly as possible.
+ * at each iteration through this loop, each of these variables
+ * should be up-to-date: obuf opage oopaque ooffnum omaxoffnum
*/
- _hash_wrtbuf(rel, obuf);
- _hash_wrtbuf(rel, nbuf);
- _hash_squeezebucket(rel, metap, obucket);
- return;
- }
- }
-
- /* hash on the tuple */
- hitem = (HashItem) PageGetItem(opage, PageGetItemId(opage, ooffnum));
- itup = &(hitem->hash_itup);
- itupdesc = RelationGetTupleDescriptor(rel);
- datum = index_getattr(itup, 1, itupdesc, &null);
- bucket = _hash_call(rel, metap, datum);
-
- if (bucket == nbucket) {
- /*
- * insert the tuple into the new bucket. if it doesn't
- * fit on the current page in the new bucket, we must
- * allocate a new overflow page and place the tuple on
- * that page instead.
- */
- itemsz = IndexTupleDSize(hitem->hash_itup)
- + (sizeof(HashItemData) - sizeof(IndexTupleData));
-
- itemsz = DOUBLEALIGN(itemsz);
-
- if (PageGetFreeSpace(npage) < itemsz) {
- ovflbuf = _hash_addovflpage(rel, &metabuf, nbuf);
- _hash_wrtbuf(rel, nbuf);
- nbuf = ovflbuf;
- npage = BufferGetPage(nbuf);
- _hash_checkpage(npage, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
- }
-
- noffnum = OffsetNumberNext(PageGetMaxOffsetNumber(npage));
- PageAddItem(npage, (Item) hitem, itemsz, noffnum, LP_USED);
- _hash_wrtnorelbuf(rel, nbuf);
-
- /*
- * now delete the tuple from the old bucket. after this
- * section of code, 'ooffnum' will actually point to the
- * ItemId to which we would point if we had advanced it
- * before the deletion (PageIndexTupleDelete repacks the
- * ItemId array). this also means that 'omaxoffnum' is
- * exactly one less than it used to be, so we really can
- * just decrement it instead of calling
- * PageGetMaxOffsetNumber.
- */
- PageIndexTupleDelete(opage, ooffnum);
- _hash_wrtnorelbuf(rel, obuf);
- omaxoffnum = OffsetNumberPrev(omaxoffnum);
-
- /*
- * tidy up. if the old page was an overflow page and it
- * is now empty, we must free it (we want to preserve the
- * invariant that overflow pages cannot be empty).
- */
- if (PageIsEmpty(opage) &&
- (oopaque->hasho_flag & LH_OVERFLOW_PAGE)) {
- obuf = _hash_freeovflpage(rel, obuf);
-
- /* check that we're not through the bucket chain */
- if (BufferIsInvalid(obuf)) {
- _hash_wrtbuf(rel, nbuf);
- _hash_squeezebucket(rel, metap, obucket);
- return;
+
+ /* check if we're at the end of the page */
+ if (ooffnum > omaxoffnum)
+ {
+ /* at end of page, but check for overflow page */
+ oblkno = oopaque->hasho_nextblkno;
+ if (BlockNumberIsValid(oblkno))
+ {
+
+ /*
+ * we ran out of tuples on this particular page, but we
+ * have more overflow pages; re-init values.
+ */
+ _hash_wrtbuf(rel, obuf);
+ obuf = _hash_getbuf(rel, oblkno, HASH_WRITE);
+ opage = BufferGetPage(obuf);
+ _hash_checkpage(opage, LH_OVERFLOW_PAGE);
+ oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
+
+ /* we're guaranteed that an ovfl page has at least 1 tuple */
+ if (PageIsEmpty(opage))
+ {
+ elog(WARN, "_hash_splitpage: empty ovfl page %d!",
+ oblkno);
+ }
+ ooffnum = FirstOffsetNumber;
+ omaxoffnum = PageGetMaxOffsetNumber(opage);
+ }
+ else
+ {
+
+ /*
+ * we're at the end of the bucket chain, so now we're
+ * really done with everything. before quitting, call
+ * _hash_squeezebucket to ensure the tuples in the bucket
+ * (including the overflow pages) are packed as tightly as
+ * possible.
+ */
+ _hash_wrtbuf(rel, obuf);
+ _hash_wrtbuf(rel, nbuf);
+ _hash_squeezebucket(rel, metap, obucket);
+ return;
+ }
}
-
- /*
- * re-init. again, we're guaranteed that an ovfl page
- * has at least one tuple.
- */
- opage = BufferGetPage(obuf);
- _hash_checkpage(opage, LH_OVERFLOW_PAGE);
- oblkno = BufferGetBlockNumber(obuf);
- oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
- if (PageIsEmpty(opage)) {
- elog(WARN, "_hash_splitpage: empty overflow page %d",
- oblkno);
+
+ /* hash on the tuple */
+ hitem = (HashItem) PageGetItem(opage, PageGetItemId(opage, ooffnum));
+ itup = &(hitem->hash_itup);
+ itupdesc = RelationGetTupleDescriptor(rel);
+ datum = index_getattr(itup, 1, itupdesc, &null);
+ bucket = _hash_call(rel, metap, datum);
+
+ if (bucket == nbucket)
+ {
+
+ /*
+ * insert the tuple into the new bucket. if it doesn't fit on
+ * the current page in the new bucket, we must allocate a new
+ * overflow page and place the tuple on that page instead.
+ */
+ itemsz = IndexTupleDSize(hitem->hash_itup)
+ + (sizeof(HashItemData) - sizeof(IndexTupleData));
+
+ itemsz = DOUBLEALIGN(itemsz);
+
+ if (PageGetFreeSpace(npage) < itemsz)
+ {
+ ovflbuf = _hash_addovflpage(rel, &metabuf, nbuf);
+ _hash_wrtbuf(rel, nbuf);
+ nbuf = ovflbuf;
+ npage = BufferGetPage(nbuf);
+ _hash_checkpage(npage, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
+ }
+
+ noffnum = OffsetNumberNext(PageGetMaxOffsetNumber(npage));
+ PageAddItem(npage, (Item) hitem, itemsz, noffnum, LP_USED);
+ _hash_wrtnorelbuf(rel, nbuf);
+
+ /*
+ * now delete the tuple from the old bucket. after this
+ * section of code, 'ooffnum' will actually point to the
+ * ItemId to which we would point if we had advanced it before
+ * the deletion (PageIndexTupleDelete repacks the ItemId
+ * array). this also means that 'omaxoffnum' is exactly one
+ * less than it used to be, so we really can just decrement it
+ * instead of calling PageGetMaxOffsetNumber.
+ */
+ PageIndexTupleDelete(opage, ooffnum);
+ _hash_wrtnorelbuf(rel, obuf);
+ omaxoffnum = OffsetNumberPrev(omaxoffnum);
+
+ /*
+ * tidy up. if the old page was an overflow page and it is
+ * now empty, we must free it (we want to preserve the
+ * invariant that overflow pages cannot be empty).
+ */
+ if (PageIsEmpty(opage) &&
+ (oopaque->hasho_flag & LH_OVERFLOW_PAGE))
+ {
+ obuf = _hash_freeovflpage(rel, obuf);
+
+ /* check that we're not through the bucket chain */
+ if (BufferIsInvalid(obuf))
+ {
+ _hash_wrtbuf(rel, nbuf);
+ _hash_squeezebucket(rel, metap, obucket);
+ return;
+ }
+
+ /*
+ * re-init. again, we're guaranteed that an ovfl page has
+ * at least one tuple.
+ */
+ opage = BufferGetPage(obuf);
+ _hash_checkpage(opage, LH_OVERFLOW_PAGE);
+ oblkno = BufferGetBlockNumber(obuf);
+ oopaque = (HashPageOpaque) PageGetSpecialPointer(opage);
+ if (PageIsEmpty(opage))
+ {
+ elog(WARN, "_hash_splitpage: empty overflow page %d",
+ oblkno);
+ }
+ ooffnum = FirstOffsetNumber;
+ omaxoffnum = PageGetMaxOffsetNumber(opage);
+ }
+ }
+ else
+ {
+
+ /*
+ * the tuple stays on this page. we didn't move anything, so
+ * we didn't delete anything and therefore we don't have to
+ * change 'omaxoffnum'.
+ *
+ * XXX any hash value from [0, nbucket-1] will map to this
+ * bucket, which doesn't make sense to me.
+ */
+ ooffnum = OffsetNumberNext(ooffnum);
}
- ooffnum = FirstOffsetNumber;
- omaxoffnum = PageGetMaxOffsetNumber(opage);
- }
- } else {
- /*
- * the tuple stays on this page. we didn't move anything,
- * so we didn't delete anything and therefore we don't
- * have to change 'omaxoffnum'.
- *
- * XXX any hash value from [0, nbucket-1] will map to this
- * bucket, which doesn't make sense to me.
- */
- ooffnum = OffsetNumberNext(ooffnum);
}
- }
- /*NOTREACHED*/
+ /* NOTREACHED */
}
diff --git a/src/backend/access/hash/hashscan.c b/src/backend/access/hash/hashscan.c
index bd776d68c0d..79fa33f747c 100644
--- a/src/backend/access/hash/hashscan.c
+++ b/src/backend/access/hash/hashscan.c
@@ -1,160 +1,167 @@
/*-------------------------------------------------------------------------
*
* hashscan.c--
- * manage scans on hash tables
+ * manage scans on hash tables
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.8 1996/11/15 18:36:31 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.9 1997/09/07 04:38:01 momjian Exp $
*
* NOTES
- * Because we can be doing an index scan on a relation while we
- * update it, we need to avoid missing data that moves around in
- * the index. The routines and global variables in this file
- * guarantee that all scans in the local address space stay
- * correctly positioned. This is all we need to worry about, since
- * write locking guarantees that no one else will be on the same
- * page at the same time as we are.
+ * Because we can be doing an index scan on a relation while we
+ * update it, we need to avoid missing data that moves around in
+ * the index. The routines and global variables in this file
+ * guarantee that all scans in the local address space stay
+ * correctly positioned. This is all we need to worry about, since
+ * write locking guarantees that no one else will be on the same
+ * page at the same time as we are.
*
- * The scheme is to manage a list of active scans in the current
- * backend. Whenever we add or remove records from an index, we
- * check the list of active scans to see if any has been affected.
- * A scan is affected only if it is on the same relation, and the
- * same page, as the update.
+ * The scheme is to manage a list of active scans in the current
+ * backend. Whenever we add or remove records from an index, we
+ * check the list of active scans to see if any has been affected.
+ * A scan is affected only if it is on the same relation, and the
+ * same page, as the update.
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <access/hash.h>
-static void _hash_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno);
-static bool _hash_scantouched(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno);
+static void _hash_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno);
+static bool _hash_scantouched(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno);
-typedef struct HashScanListData {
- IndexScanDesc hashsl_scan;
- struct HashScanListData *hashsl_next;
-} HashScanListData;
+typedef struct HashScanListData
+{
+ IndexScanDesc hashsl_scan;
+ struct HashScanListData *hashsl_next;
+} HashScanListData;
-typedef HashScanListData *HashScanList;
+typedef HashScanListData *HashScanList;
-static HashScanList HashScans = (HashScanList) NULL;
+static HashScanList HashScans = (HashScanList) NULL;
/*
- * _Hash_regscan() -- register a new scan.
+ * _Hash_regscan() -- register a new scan.
*/
void
_hash_regscan(IndexScanDesc scan)
{
- HashScanList new_el;
-
- new_el = (HashScanList) palloc(sizeof(HashScanListData));
- new_el->hashsl_scan = scan;
- new_el->hashsl_next = HashScans;
- HashScans = new_el;
+ HashScanList new_el;
+
+ new_el = (HashScanList) palloc(sizeof(HashScanListData));
+ new_el->hashsl_scan = scan;
+ new_el->hashsl_next = HashScans;
+ HashScans = new_el;
}
/*
- * _hash_dropscan() -- drop a scan from the scan list
+ * _hash_dropscan() -- drop a scan from the scan list
*/
void
_hash_dropscan(IndexScanDesc scan)
{
- HashScanList chk, last;
-
- last = (HashScanList) NULL;
- for (chk = HashScans;
- chk != (HashScanList) NULL && chk->hashsl_scan != scan;
- chk = chk->hashsl_next) {
- last = chk;
- }
-
- if (chk == (HashScanList) NULL)
- elog(WARN, "hash scan list trashed; can't find 0x%lx", scan);
-
- if (last == (HashScanList) NULL)
- HashScans = chk->hashsl_next;
- else
- last->hashsl_next = chk->hashsl_next;
-
- pfree (chk);
+ HashScanList chk,
+ last;
+
+ last = (HashScanList) NULL;
+ for (chk = HashScans;
+ chk != (HashScanList) NULL && chk->hashsl_scan != scan;
+ chk = chk->hashsl_next)
+ {
+ last = chk;
+ }
+
+ if (chk == (HashScanList) NULL)
+ elog(WARN, "hash scan list trashed; can't find 0x%lx", scan);
+
+ if (last == (HashScanList) NULL)
+ HashScans = chk->hashsl_next;
+ else
+ last->hashsl_next = chk->hashsl_next;
+
+ pfree(chk);
}
void
_hash_adjscans(Relation rel, ItemPointer tid)
{
- HashScanList l;
- Oid relid;
-
- relid = rel->rd_id;
- for (l = HashScans; l != (HashScanList) NULL; l = l->hashsl_next) {
- if (relid == l->hashsl_scan->relation->rd_id)
- _hash_scandel(l->hashsl_scan, ItemPointerGetBlockNumber(tid),
- ItemPointerGetOffsetNumber(tid));
- }
+ HashScanList l;
+ Oid relid;
+
+ relid = rel->rd_id;
+ for (l = HashScans; l != (HashScanList) NULL; l = l->hashsl_next)
+ {
+ if (relid == l->hashsl_scan->relation->rd_id)
+ _hash_scandel(l->hashsl_scan, ItemPointerGetBlockNumber(tid),
+ ItemPointerGetOffsetNumber(tid));
+ }
}
static void
_hash_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno)
{
- ItemPointer current;
- Buffer buf;
- Buffer metabuf;
- HashScanOpaque so;
-
- if (!_hash_scantouched(scan, blkno, offno))
- return;
-
- metabuf = _hash_getbuf(scan->relation, HASH_METAPAGE, HASH_READ);
-
- so = (HashScanOpaque) scan->opaque;
- buf = so->hashso_curbuf;
-
- current = &(scan->currentItemData);
- if (ItemPointerIsValid(current)
- && ItemPointerGetBlockNumber(current) == blkno
- && ItemPointerGetOffsetNumber(current) >= offno) {
- _hash_step(scan, &buf, BackwardScanDirection, metabuf);
- so->hashso_curbuf = buf;
- }
-
- current = &(scan->currentMarkData);
- if (ItemPointerIsValid(current)
- && ItemPointerGetBlockNumber(current) == blkno
- && ItemPointerGetOffsetNumber(current) >= offno) {
- ItemPointerData tmp;
- tmp = *current;
- *current = scan->currentItemData;
- scan->currentItemData = tmp;
- _hash_step(scan, &buf, BackwardScanDirection, metabuf);
- so->hashso_mrkbuf = buf;
- tmp = *current;
- *current = scan->currentItemData;
- scan->currentItemData = tmp;
- }
+ ItemPointer current;
+ Buffer buf;
+ Buffer metabuf;
+ HashScanOpaque so;
+
+ if (!_hash_scantouched(scan, blkno, offno))
+ return;
+
+ metabuf = _hash_getbuf(scan->relation, HASH_METAPAGE, HASH_READ);
+
+ so = (HashScanOpaque) scan->opaque;
+ buf = so->hashso_curbuf;
+
+ current = &(scan->currentItemData);
+ if (ItemPointerIsValid(current)
+ && ItemPointerGetBlockNumber(current) == blkno
+ && ItemPointerGetOffsetNumber(current) >= offno)
+ {
+ _hash_step(scan, &buf, BackwardScanDirection, metabuf);
+ so->hashso_curbuf = buf;
+ }
+
+ current = &(scan->currentMarkData);
+ if (ItemPointerIsValid(current)
+ && ItemPointerGetBlockNumber(current) == blkno
+ && ItemPointerGetOffsetNumber(current) >= offno)
+ {
+ ItemPointerData tmp;
+
+ tmp = *current;
+ *current = scan->currentItemData;
+ scan->currentItemData = tmp;
+ _hash_step(scan, &buf, BackwardScanDirection, metabuf);
+ so->hashso_mrkbuf = buf;
+ tmp = *current;
+ *current = scan->currentItemData;
+ scan->currentItemData = tmp;
+ }
}
-static bool
+static bool
_hash_scantouched(IndexScanDesc scan,
- BlockNumber blkno,
- OffsetNumber offno)
+ BlockNumber blkno,
+ OffsetNumber offno)
{
- ItemPointer current;
-
- current = &(scan->currentItemData);
- if (ItemPointerIsValid(current)
- && ItemPointerGetBlockNumber(current) == blkno
- && ItemPointerGetOffsetNumber(current) >= offno)
- return (true);
-
- current = &(scan->currentMarkData);
- if (ItemPointerIsValid(current)
- && ItemPointerGetBlockNumber(current) == blkno
- && ItemPointerGetOffsetNumber(current) >= offno)
- return (true);
-
- return (false);
+ ItemPointer current;
+
+ current = &(scan->currentItemData);
+ if (ItemPointerIsValid(current)
+ && ItemPointerGetBlockNumber(current) == blkno
+ && ItemPointerGetOffsetNumber(current) >= offno)
+ return (true);
+
+ current = &(scan->currentMarkData);
+ if (ItemPointerIsValid(current)
+ && ItemPointerGetBlockNumber(current) == blkno
+ && ItemPointerGetOffsetNumber(current) >= offno)
+ return (true);
+
+ return (false);
}
diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c
index bc67b7f5aac..0a42ad05065 100644
--- a/src/backend/access/hash/hashsearch.c
+++ b/src/backend/access/hash/hashsearch.c
@@ -1,423 +1,467 @@
/*-------------------------------------------------------------------------
*
* hashsearch.c--
- * search code for postgres hash tables
+ * search code for postgres hash tables
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.10 1997/06/28 05:45:40 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.11 1997/09/07 04:38:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <access/hash.h>
#include <storage/bufmgr.h>
#ifndef HAVE_MEMMOVE
-# include "regex/utils.h"
+#include "regex/utils.h"
#else
-# include <string.h>
-#endif
+#include <string.h>
+#endif
/*
- * _hash_search() -- Finds the page/bucket that the contains the
- * scankey and loads it into *bufP. the buffer has a read lock.
+ * _hash_search() -- Finds the page/bucket that the contains the
+ * scankey and loads it into *bufP. the buffer has a read lock.
*/
void
_hash_search(Relation rel,
- int keysz,
- ScanKey scankey,
- Buffer *bufP,
- HashMetaPage metap)
+ int keysz,
+ ScanKey scankey,
+ Buffer * bufP,
+ HashMetaPage metap)
{
- BlockNumber blkno;
- Datum keyDatum;
- Bucket bucket;
-
- if (scankey == (ScanKey) NULL ||
- (keyDatum = scankey[0].sk_argument) == (Datum) NULL) {
- /*
- * If the scankey argument is NULL, all tuples will satisfy
- * the scan so we start the scan at the first bucket (bucket
- * 0).
- */
- bucket = 0;
- } else {
- bucket = _hash_call(rel, metap, keyDatum);
- }
-
- blkno = BUCKET_TO_BLKNO(bucket);
-
- *bufP = _hash_getbuf(rel, blkno, HASH_READ);
+ BlockNumber blkno;
+ Datum keyDatum;
+ Bucket bucket;
+
+ if (scankey == (ScanKey) NULL ||
+ (keyDatum = scankey[0].sk_argument) == (Datum) NULL)
+ {
+
+ /*
+ * If the scankey argument is NULL, all tuples will satisfy the
+ * scan so we start the scan at the first bucket (bucket 0).
+ */
+ bucket = 0;
+ }
+ else
+ {
+ bucket = _hash_call(rel, metap, keyDatum);
+ }
+
+ blkno = BUCKET_TO_BLKNO(bucket);
+
+ *bufP = _hash_getbuf(rel, blkno, HASH_READ);
}
/*
- * _hash_next() -- Get the next item in a scan.
+ * _hash_next() -- Get the next item in a scan.
*
- * On entry, we have a valid currentItemData in the scan, and a
- * read lock on the page that contains that item. We do not have
- * the page pinned. We return the next item in the scan. On
- * exit, we have the page containing the next item locked but not
- * pinned.
+ * On entry, we have a valid currentItemData in the scan, and a
+ * read lock on the page that contains that item. We do not have
+ * the page pinned. We return the next item in the scan. On
+ * exit, we have the page containing the next item locked but not
+ * pinned.
*/
RetrieveIndexResult
_hash_next(IndexScanDesc scan, ScanDirection dir)
{
- Relation rel;
- Buffer buf;
- Buffer metabuf;
- Page page;
- OffsetNumber offnum;
- RetrieveIndexResult res;
- ItemPointer current;
- HashItem hitem;
- IndexTuple itup;
- HashScanOpaque so;
-
- rel = scan->relation;
- so = (HashScanOpaque) scan->opaque;
- current = &(scan->currentItemData);
-
- metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ);
-
- /*
- * XXX 10 may 91: somewhere there's a bug in our management of the
- * cached buffer for this scan. wei discovered it. the following
- * is a workaround so he can work until i figure out what's going on.
- */
-
- if (!BufferIsValid(so->hashso_curbuf)) {
- so->hashso_curbuf = _hash_getbuf(rel,
- ItemPointerGetBlockNumber(current),
- HASH_READ);
- }
-
- /* we still have the buffer pinned and locked */
- buf = so->hashso_curbuf;
-
- /*
- * step to next valid tuple. note that _hash_step releases our
- * lock on 'metabuf'; if we switch to a new 'buf' while looking
- * for the next tuple, we come back with a lock on that buffer.
- */
- if (!_hash_step(scan, &buf, dir, metabuf)) {
- return ((RetrieveIndexResult) NULL);
- }
-
- /* if we're here, _hash_step found a valid tuple */
- current = &(scan->currentItemData);
- offnum = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
- hitem = (HashItem) PageGetItem(page, PageGetItemId(page, offnum));
- itup = &hitem->hash_itup;
- res = FormRetrieveIndexResult(current, &(itup->t_tid));
-
- return (res);
+ Relation rel;
+ Buffer buf;
+ Buffer metabuf;
+ Page page;
+ OffsetNumber offnum;
+ RetrieveIndexResult res;
+ ItemPointer current;
+ HashItem hitem;
+ IndexTuple itup;
+ HashScanOpaque so;
+
+ rel = scan->relation;
+ so = (HashScanOpaque) scan->opaque;
+ current = &(scan->currentItemData);
+
+ metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ);
+
+ /*
+ * XXX 10 may 91: somewhere there's a bug in our management of the
+ * cached buffer for this scan. wei discovered it. the following is
+ * a workaround so he can work until i figure out what's going on.
+ */
+
+ if (!BufferIsValid(so->hashso_curbuf))
+ {
+ so->hashso_curbuf = _hash_getbuf(rel,
+ ItemPointerGetBlockNumber(current),
+ HASH_READ);
+ }
+
+ /* we still have the buffer pinned and locked */
+ buf = so->hashso_curbuf;
+
+ /*
+ * step to next valid tuple. note that _hash_step releases our lock
+ * on 'metabuf'; if we switch to a new 'buf' while looking for the
+ * next tuple, we come back with a lock on that buffer.
+ */
+ if (!_hash_step(scan, &buf, dir, metabuf))
+ {
+ return ((RetrieveIndexResult) NULL);
+ }
+
+ /* if we're here, _hash_step found a valid tuple */
+ current = &(scan->currentItemData);
+ offnum = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
+ hitem = (HashItem) PageGetItem(page, PageGetItemId(page, offnum));
+ itup = &hitem->hash_itup;
+ res = FormRetrieveIndexResult(current, &(itup->t_tid));
+
+ return (res);
}
static void
_hash_readnext(Relation rel,
- Buffer *bufp, Page *pagep, HashPageOpaque *opaquep)
+ Buffer * bufp, Page * pagep, HashPageOpaque * opaquep)
{
- BlockNumber blkno;
-
- blkno = (*opaquep)->hasho_nextblkno;
- _hash_relbuf(rel, *bufp, HASH_READ);
- *bufp = InvalidBuffer;
- if (BlockNumberIsValid(blkno)) {
- *bufp = _hash_getbuf(rel, blkno, HASH_READ);
- *pagep = BufferGetPage(*bufp);
- _hash_checkpage(*pagep, LH_OVERFLOW_PAGE);
- *opaquep = (HashPageOpaque) PageGetSpecialPointer(*pagep);
- Assert(!PageIsEmpty(*pagep));
- }
+ BlockNumber blkno;
+
+ blkno = (*opaquep)->hasho_nextblkno;
+ _hash_relbuf(rel, *bufp, HASH_READ);
+ *bufp = InvalidBuffer;
+ if (BlockNumberIsValid(blkno))
+ {
+ *bufp = _hash_getbuf(rel, blkno, HASH_READ);
+ *pagep = BufferGetPage(*bufp);
+ _hash_checkpage(*pagep, LH_OVERFLOW_PAGE);
+ *opaquep = (HashPageOpaque) PageGetSpecialPointer(*pagep);
+ Assert(!PageIsEmpty(*pagep));
+ }
}
static void
_hash_readprev(Relation rel,
- Buffer *bufp, Page *pagep, HashPageOpaque *opaquep)
+ Buffer * bufp, Page * pagep, HashPageOpaque * opaquep)
{
- BlockNumber blkno;
-
- blkno = (*opaquep)->hasho_prevblkno;
- _hash_relbuf(rel, *bufp, HASH_READ);
- *bufp = InvalidBuffer;
- if (BlockNumberIsValid(blkno)) {
- *bufp = _hash_getbuf(rel, blkno, HASH_READ);
- *pagep = BufferGetPage(*bufp);
- _hash_checkpage(*pagep, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
- *opaquep = (HashPageOpaque) PageGetSpecialPointer(*pagep);
- if (PageIsEmpty(*pagep)) {
- Assert((*opaquep)->hasho_flag & LH_BUCKET_PAGE);
- _hash_relbuf(rel, *bufp, HASH_READ);
- *bufp = InvalidBuffer;
+ BlockNumber blkno;
+
+ blkno = (*opaquep)->hasho_prevblkno;
+ _hash_relbuf(rel, *bufp, HASH_READ);
+ *bufp = InvalidBuffer;
+ if (BlockNumberIsValid(blkno))
+ {
+ *bufp = _hash_getbuf(rel, blkno, HASH_READ);
+ *pagep = BufferGetPage(*bufp);
+ _hash_checkpage(*pagep, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
+ *opaquep = (HashPageOpaque) PageGetSpecialPointer(*pagep);
+ if (PageIsEmpty(*pagep))
+ {
+ Assert((*opaquep)->hasho_flag & LH_BUCKET_PAGE);
+ _hash_relbuf(rel, *bufp, HASH_READ);
+ *bufp = InvalidBuffer;
+ }
}
- }
}
/*
- * _hash_first() -- Find the first item in a scan.
+ * _hash_first() -- Find the first item in a scan.
*
- * Return the RetrieveIndexResult of the first item in the tree that
- * satisfies the qualificatin associated with the scan descriptor. On
- * exit, the page containing the current index tuple is read locked
- * and pinned, and the scan's opaque data entry is updated to
- * include the buffer.
+ * Return the RetrieveIndexResult of the first item in the tree that
+ * satisfies the qualificatin associated with the scan descriptor. On
+ * exit, the page containing the current index tuple is read locked
+ * and pinned, and the scan's opaque data entry is updated to
+ * include the buffer.
*/
RetrieveIndexResult
_hash_first(IndexScanDesc scan, ScanDirection dir)
{
- Relation rel;
- Buffer buf;
- Buffer metabuf;
- Page page;
- HashPageOpaque opaque;
- HashMetaPage metap;
- HashItem hitem;
- IndexTuple itup;
- ItemPointer current;
- OffsetNumber offnum;
- RetrieveIndexResult res;
- HashScanOpaque so;
-
- rel = scan->relation;
- so = (HashScanOpaque) scan->opaque;
- current = &(scan->currentItemData);
-
- metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ);
- metap = (HashMetaPage) BufferGetPage(metabuf);
- _hash_checkpage((Page) metap, LH_META_PAGE);
-
- /*
- * XXX -- The attribute number stored in the scan key is the attno
- * in the heap relation. We need to transmogrify this into
- * the index relation attno here. For the moment, we have
- * hardwired attno == 1.
- */
-
- /* find the correct bucket page and load it into buf */
- _hash_search(rel, 1, scan->keyData, &buf, metap);
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE);
- opaque = (HashPageOpaque) PageGetSpecialPointer(page);
-
- /*
- * if we are scanning forward, we need to find the first non-empty
- * page (if any) in the bucket chain. since overflow pages are
- * never empty, this had better be either the bucket page or the
- * first overflow page.
- *
- * if we are scanning backward, we always go all the way to the
- * end of the bucket chain.
- */
- if (PageIsEmpty(page)) {
- if (BlockNumberIsValid(opaque->hasho_nextblkno)) {
- _hash_readnext(rel, &buf, &page, &opaque);
- } else {
- ItemPointerSetInvalid(current);
- so->hashso_curbuf = InvalidBuffer;
- /*
- * If there is no scankeys, all tuples will satisfy
- * the scan - so we continue in _hash_step to get
- * tuples from all buckets. - vadim 04/29/97
- */
- if ( scan->numberOfKeys >= 1 )
- {
- _hash_relbuf(rel, buf, HASH_READ);
- _hash_relbuf(rel, metabuf, HASH_READ);
- return ((RetrieveIndexResult) NULL);
- }
+ Relation rel;
+ Buffer buf;
+ Buffer metabuf;
+ Page page;
+ HashPageOpaque opaque;
+ HashMetaPage metap;
+ HashItem hitem;
+ IndexTuple itup;
+ ItemPointer current;
+ OffsetNumber offnum;
+ RetrieveIndexResult res;
+ HashScanOpaque so;
+
+ rel = scan->relation;
+ so = (HashScanOpaque) scan->opaque;
+ current = &(scan->currentItemData);
+
+ metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ);
+ metap = (HashMetaPage) BufferGetPage(metabuf);
+ _hash_checkpage((Page) metap, LH_META_PAGE);
+
+ /*
+ * XXX -- The attribute number stored in the scan key is the attno in
+ * the heap relation. We need to transmogrify this into the index
+ * relation attno here. For the moment, we have hardwired attno == 1.
+ */
+
+ /* find the correct bucket page and load it into buf */
+ _hash_search(rel, 1, scan->keyData, &buf, metap);
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE);
+ opaque = (HashPageOpaque) PageGetSpecialPointer(page);
+
+ /*
+ * if we are scanning forward, we need to find the first non-empty
+ * page (if any) in the bucket chain. since overflow pages are never
+ * empty, this had better be either the bucket page or the first
+ * overflow page.
+ *
+ * if we are scanning backward, we always go all the way to the end of
+ * the bucket chain.
+ */
+ if (PageIsEmpty(page))
+ {
+ if (BlockNumberIsValid(opaque->hasho_nextblkno))
+ {
+ _hash_readnext(rel, &buf, &page, &opaque);
+ }
+ else
+ {
+ ItemPointerSetInvalid(current);
+ so->hashso_curbuf = InvalidBuffer;
+
+ /*
+ * If there is no scankeys, all tuples will satisfy the scan -
+ * so we continue in _hash_step to get tuples from all
+ * buckets. - vadim 04/29/97
+ */
+ if (scan->numberOfKeys >= 1)
+ {
+ _hash_relbuf(rel, buf, HASH_READ);
+ _hash_relbuf(rel, metabuf, HASH_READ);
+ return ((RetrieveIndexResult) NULL);
+ }
+ }
}
- }
- if (ScanDirectionIsBackward(dir)) {
- while (BlockNumberIsValid(opaque->hasho_nextblkno)) {
- _hash_readnext(rel, &buf, &page, &opaque);
+ if (ScanDirectionIsBackward(dir))
+ {
+ while (BlockNumberIsValid(opaque->hasho_nextblkno))
+ {
+ _hash_readnext(rel, &buf, &page, &opaque);
+ }
+ }
+
+ if (!_hash_step(scan, &buf, dir, metabuf))
+ {
+ return ((RetrieveIndexResult) NULL);
}
- }
-
- if (!_hash_step(scan, &buf, dir, metabuf)) {
- return ((RetrieveIndexResult) NULL);
- }
-
- /* if we're here, _hash_step found a valid tuple */
- current = &(scan->currentItemData);
- offnum = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
- hitem = (HashItem) PageGetItem(page, PageGetItemId(page, offnum));
- itup = &hitem->hash_itup;
- res = FormRetrieveIndexResult(current, &(itup->t_tid));
-
- return (res);
+
+ /* if we're here, _hash_step found a valid tuple */
+ current = &(scan->currentItemData);
+ offnum = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
+ hitem = (HashItem) PageGetItem(page, PageGetItemId(page, offnum));
+ itup = &hitem->hash_itup;
+ res = FormRetrieveIndexResult(current, &(itup->t_tid));
+
+ return (res);
}
/*
- * _hash_step() -- step to the next valid item in a scan in the bucket.
+ * _hash_step() -- step to the next valid item in a scan in the bucket.
*
- * If no valid record exists in the requested direction, return
- * false. Else, return true and set the CurrentItemData for the
- * scan to the right thing.
- *
- * 'bufP' points to the buffer which contains the current page
- * that we'll step through.
+ * If no valid record exists in the requested direction, return
+ * false. Else, return true and set the CurrentItemData for the
+ * scan to the right thing.
*
- * 'metabuf' is released when this returns.
+ * 'bufP' points to the buffer which contains the current page
+ * that we'll step through.
+ *
+ * 'metabuf' is released when this returns.
*/
bool
-_hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf)
+_hash_step(IndexScanDesc scan, Buffer * bufP, ScanDirection dir, Buffer metabuf)
{
- Relation rel;
- ItemPointer current;
- HashScanOpaque so;
- int allbuckets;
- HashMetaPage metap;
- Buffer buf;
- Page page;
- HashPageOpaque opaque;
- OffsetNumber maxoff;
- OffsetNumber offnum;
- Bucket bucket;
- BlockNumber blkno;
- HashItem hitem;
- IndexTuple itup;
-
- rel = scan->relation;
- current = &(scan->currentItemData);
- so = (HashScanOpaque) scan->opaque;
- allbuckets = (scan->numberOfKeys < 1);
-
- metap = (HashMetaPage) BufferGetPage(metabuf);
- _hash_checkpage((Page) metap, LH_META_PAGE);
-
- buf = *bufP;
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE|LH_OVERFLOW_PAGE);
- opaque = (HashPageOpaque) PageGetSpecialPointer(page);
-
- /*
- * If _hash_step is called from _hash_first, current will not be
- * valid, so we can't dereference it. However, in that case, we
- * presumably want to start at the beginning/end of the page...
- */
- maxoff = PageGetMaxOffsetNumber(page);
- if (ItemPointerIsValid(current)) {
- offnum = ItemPointerGetOffsetNumber(current);
- } else {
- offnum = InvalidOffsetNumber;
- }
-
- /*
- * 'offnum' now points to the last tuple we have seen (if any).
- *
- * continue to step through tuples until:
- * 1) we get to the end of the bucket chain or
- * 2) we find a valid tuple.
- */
- do {
- bucket = opaque->hasho_bucket;
-
- switch (dir) {
- case ForwardScanDirection:
- if (offnum != InvalidOffsetNumber) {
- offnum = OffsetNumberNext(offnum); /* move forward */
- } else {
- offnum = FirstOffsetNumber; /* new page */
- }
- while (offnum > maxoff) {
- /*
- * either this page is empty (maxoff ==
- * InvalidOffsetNumber) or we ran off the end.
- */
- _hash_readnext(rel, &buf, &page, &opaque);
- if (BufferIsInvalid(buf)) { /* end of chain */
- if (allbuckets && bucket < metap->hashm_maxbucket) {
- ++bucket;
- blkno = BUCKET_TO_BLKNO(bucket);
- buf = _hash_getbuf(rel, blkno, HASH_READ);
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE);
- opaque = (HashPageOpaque) PageGetSpecialPointer(page);
- Assert(opaque->hasho_bucket == bucket);
- while (PageIsEmpty(page) &&
- BlockNumberIsValid(opaque->hasho_nextblkno)) {
- _hash_readnext(rel, &buf, &page, &opaque);
+ Relation rel;
+ ItemPointer current;
+ HashScanOpaque so;
+ int allbuckets;
+ HashMetaPage metap;
+ Buffer buf;
+ Page page;
+ HashPageOpaque opaque;
+ OffsetNumber maxoff;
+ OffsetNumber offnum;
+ Bucket bucket;
+ BlockNumber blkno;
+ HashItem hitem;
+ IndexTuple itup;
+
+ rel = scan->relation;
+ current = &(scan->currentItemData);
+ so = (HashScanOpaque) scan->opaque;
+ allbuckets = (scan->numberOfKeys < 1);
+
+ metap = (HashMetaPage) BufferGetPage(metabuf);
+ _hash_checkpage((Page) metap, LH_META_PAGE);
+
+ buf = *bufP;
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
+ opaque = (HashPageOpaque) PageGetSpecialPointer(page);
+
+ /*
+ * If _hash_step is called from _hash_first, current will not be
+ * valid, so we can't dereference it. However, in that case, we
+ * presumably want to start at the beginning/end of the page...
+ */
+ maxoff = PageGetMaxOffsetNumber(page);
+ if (ItemPointerIsValid(current))
+ {
+ offnum = ItemPointerGetOffsetNumber(current);
+ }
+ else
+ {
+ offnum = InvalidOffsetNumber;
+ }
+
+ /*
+ * 'offnum' now points to the last tuple we have seen (if any).
+ *
+ * continue to step through tuples until: 1) we get to the end of the
+ * bucket chain or 2) we find a valid tuple.
+ */
+ do
+ {
+ bucket = opaque->hasho_bucket;
+
+ switch (dir)
+ {
+ case ForwardScanDirection:
+ if (offnum != InvalidOffsetNumber)
+ {
+ offnum = OffsetNumberNext(offnum); /* move forward */
}
- maxoff = PageGetMaxOffsetNumber(page);
- offnum = FirstOffsetNumber;
- } else {
- maxoff = offnum = InvalidOffsetNumber;
- break; /* while */
- }
- } else {
- /* _hash_readnext never returns an empty page */
- maxoff = PageGetMaxOffsetNumber(page);
- offnum = FirstOffsetNumber;
- }
- }
- break;
- case BackwardScanDirection:
- if (offnum != InvalidOffsetNumber) {
- offnum = OffsetNumberPrev(offnum); /* move back */
- } else {
- offnum = maxoff; /* new page */
- }
- while (offnum < FirstOffsetNumber) {
- /*
- * either this page is empty (offnum ==
- * InvalidOffsetNumber) or we ran off the end.
- */
- _hash_readprev(rel, &buf, &page, &opaque);
- if (BufferIsInvalid(buf)) { /* end of chain */
- if (allbuckets && bucket > 0) {
- --bucket;
- blkno = BUCKET_TO_BLKNO(bucket);
- buf = _hash_getbuf(rel, blkno, HASH_READ);
- page = BufferGetPage(buf);
- _hash_checkpage(page, LH_BUCKET_PAGE);
- opaque = (HashPageOpaque) PageGetSpecialPointer(page);
- Assert(opaque->hasho_bucket == bucket);
- while (BlockNumberIsValid(opaque->hasho_nextblkno)) {
- _hash_readnext(rel, &buf, &page, &opaque);
+ else
+ {
+ offnum = FirstOffsetNumber; /* new page */
+ }
+ while (offnum > maxoff)
+ {
+
+ /*
+ * either this page is empty (maxoff ==
+ * InvalidOffsetNumber) or we ran off the end.
+ */
+ _hash_readnext(rel, &buf, &page, &opaque);
+ if (BufferIsInvalid(buf))
+ { /* end of chain */
+ if (allbuckets && bucket < metap->hashm_maxbucket)
+ {
+ ++bucket;
+ blkno = BUCKET_TO_BLKNO(bucket);
+ buf = _hash_getbuf(rel, blkno, HASH_READ);
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE);
+ opaque = (HashPageOpaque) PageGetSpecialPointer(page);
+ Assert(opaque->hasho_bucket == bucket);
+ while (PageIsEmpty(page) &&
+ BlockNumberIsValid(opaque->hasho_nextblkno))
+ {
+ _hash_readnext(rel, &buf, &page, &opaque);
+ }
+ maxoff = PageGetMaxOffsetNumber(page);
+ offnum = FirstOffsetNumber;
+ }
+ else
+ {
+ maxoff = offnum = InvalidOffsetNumber;
+ break; /* while */
+ }
+ }
+ else
+ {
+ /* _hash_readnext never returns an empty page */
+ maxoff = PageGetMaxOffsetNumber(page);
+ offnum = FirstOffsetNumber;
+ }
+ }
+ break;
+ case BackwardScanDirection:
+ if (offnum != InvalidOffsetNumber)
+ {
+ offnum = OffsetNumberPrev(offnum); /* move back */
+ }
+ else
+ {
+ offnum = maxoff;/* new page */
}
- maxoff = offnum = PageGetMaxOffsetNumber(page);
- } else {
- maxoff = offnum = InvalidOffsetNumber;
- break; /* while */
- }
- } else {
- /* _hash_readprev never returns an empty page */
- maxoff = offnum = PageGetMaxOffsetNumber(page);
+ while (offnum < FirstOffsetNumber)
+ {
+
+ /*
+ * either this page is empty (offnum ==
+ * InvalidOffsetNumber) or we ran off the end.
+ */
+ _hash_readprev(rel, &buf, &page, &opaque);
+ if (BufferIsInvalid(buf))
+ { /* end of chain */
+ if (allbuckets && bucket > 0)
+ {
+ --bucket;
+ blkno = BUCKET_TO_BLKNO(bucket);
+ buf = _hash_getbuf(rel, blkno, HASH_READ);
+ page = BufferGetPage(buf);
+ _hash_checkpage(page, LH_BUCKET_PAGE);
+ opaque = (HashPageOpaque) PageGetSpecialPointer(page);
+ Assert(opaque->hasho_bucket == bucket);
+ while (BlockNumberIsValid(opaque->hasho_nextblkno))
+ {
+ _hash_readnext(rel, &buf, &page, &opaque);
+ }
+ maxoff = offnum = PageGetMaxOffsetNumber(page);
+ }
+ else
+ {
+ maxoff = offnum = InvalidOffsetNumber;
+ break; /* while */
+ }
+ }
+ else
+ {
+ /* _hash_readprev never returns an empty page */
+ maxoff = offnum = PageGetMaxOffsetNumber(page);
+ }
+ }
+ break;
+ default:
+ /* NoMovementScanDirection */
+ /* this should not be reached */
+ break;
}
- }
- break;
- default:
- /* NoMovementScanDirection */
- /* this should not be reached */
- break;
- }
- /* we ran off the end of the world without finding a match */
- if (offnum == InvalidOffsetNumber) {
- _hash_relbuf(rel, metabuf, HASH_READ);
- *bufP = so->hashso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(current);
- return(false);
- }
-
- /* get ready to check this tuple */
- hitem = (HashItem) PageGetItem(page, PageGetItemId(page, offnum));
- itup = &hitem->hash_itup;
- } while (!_hash_checkqual(scan, itup));
-
- /* if we made it to here, we've found a valid tuple */
- _hash_relbuf(rel, metabuf, HASH_READ);
- blkno = BufferGetBlockNumber(buf);
- *bufP = so->hashso_curbuf = buf;
- ItemPointerSet(current, blkno, offnum);
- return(true);
+ /* we ran off the end of the world without finding a match */
+ if (offnum == InvalidOffsetNumber)
+ {
+ _hash_relbuf(rel, metabuf, HASH_READ);
+ *bufP = so->hashso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(current);
+ return (false);
+ }
+
+ /* get ready to check this tuple */
+ hitem = (HashItem) PageGetItem(page, PageGetItemId(page, offnum));
+ itup = &hitem->hash_itup;
+ } while (!_hash_checkqual(scan, itup));
+
+ /* if we made it to here, we've found a valid tuple */
+ _hash_relbuf(rel, metabuf, HASH_READ);
+ blkno = BufferGetBlockNumber(buf);
+ *bufP = so->hashso_curbuf = buf;
+ ItemPointerSet(current, blkno, offnum);
+ return (true);
}
diff --git a/src/backend/access/hash/hashstrat.c b/src/backend/access/hash/hashstrat.c
index d2f1e513c38..f1bdbdb8a3a 100644
--- a/src/backend/access/hash/hashstrat.c
+++ b/src/backend/access/hash/hashstrat.c
@@ -1,80 +1,83 @@
/*-------------------------------------------------------------------------
*
* btstrat.c--
- * Srategy map entries for the btree indexed access method
+ * Srategy map entries for the btree indexed access method
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/Attic/hashstrat.c,v 1.9 1997/08/20 02:01:42 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/Attic/hashstrat.c,v 1.10 1997/09/07 04:38:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <access/hash.h>
#include <access/istrat.h>
-/*
- * only one valid strategy for hash tables: equality.
+/*
+ * only one valid strategy for hash tables: equality.
*/
#ifdef NOT_USED
-static StrategyNumber HTNegate[1] = {
- InvalidStrategy
+static StrategyNumber HTNegate[1] = {
+ InvalidStrategy
};
-static StrategyNumber HTCommute[1] = {
- HTEqualStrategyNumber
+static StrategyNumber HTCommute[1] = {
+ HTEqualStrategyNumber
};
-static StrategyNumber HTNegateCommute[1] = {
- InvalidStrategy
+static StrategyNumber HTNegateCommute[1] = {
+ InvalidStrategy
};
-static StrategyEvaluationData HTEvaluationData = {
- /* XXX static for simplicity */
+static StrategyEvaluationData HTEvaluationData = {
+ /* XXX static for simplicity */
- HTMaxStrategyNumber,
- (StrategyTransformMap)HTNegate,
- (StrategyTransformMap)HTCommute,
- (StrategyTransformMap)HTNegateCommute,
- {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
+ HTMaxStrategyNumber,
+ (StrategyTransformMap) HTNegate,
+ (StrategyTransformMap) HTCommute,
+ (StrategyTransformMap) HTNegateCommute,
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
+
#endif
/* ----------------------------------------------------------------
- * RelationGetHashStrategy
+ * RelationGetHashStrategy
* ----------------------------------------------------------------
*/
#ifdef NOT_USED
-static StrategyNumber
+static StrategyNumber
_hash_getstrat(Relation rel,
- AttrNumber attno,
- RegProcedure proc)
+ AttrNumber attno,
+ RegProcedure proc)
{
- StrategyNumber strat;
+ StrategyNumber strat;
- strat = RelationGetStrategy(rel, attno, &HTEvaluationData, proc);
+ strat = RelationGetStrategy(rel, attno, &HTEvaluationData, proc);
- Assert(StrategyNumberIsValid(strat));
+ Assert(StrategyNumberIsValid(strat));
- return (strat);
+ return (strat);
}
+
#endif
#ifdef NOT_USED
-static bool
+static bool
_hash_invokestrat(Relation rel,
- AttrNumber attno,
- StrategyNumber strat,
- Datum left,
- Datum right)
+ AttrNumber attno,
+ StrategyNumber strat,
+ Datum left,
+ Datum right)
{
- return (RelationInvokeStrategy(rel, &HTEvaluationData, attno, strat,
- left, right));
+ return (RelationInvokeStrategy(rel, &HTEvaluationData, attno, strat,
+ left, right));
}
+
#endif
diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c
index dd0b4737454..f9fbe0e2d17 100644
--- a/src/backend/access/hash/hashutil.c
+++ b/src/backend/access/hash/hashutil.c
@@ -1,109 +1,110 @@
/*-------------------------------------------------------------------------
*
* btutils.c--
- * Utility code for Postgres btree implementation.
+ * Utility code for Postgres btree implementation.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.9 1997/08/14 05:01:32 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.10 1997/09/07 04:38:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <access/hash.h>
#include <fmgr.h>
#include <utils/memutils.h>
#include <access/iqual.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
ScanKey
_hash_mkscankey(Relation rel, IndexTuple itup, HashMetaPage metap)
{
- ScanKey skey;
- TupleDesc itupdesc;
- int natts;
- AttrNumber i;
- Datum arg;
- RegProcedure proc;
- bool null;
-
- natts = rel->rd_rel->relnatts;
- itupdesc = RelationGetTupleDescriptor(rel);
-
- skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
-
- for (i = 0; i < natts; i++) {
- arg = index_getattr(itup, i + 1, itupdesc, &null);
- proc = metap->hashm_procid;
- ScanKeyEntryInitialize(&skey[i],
- 0x0, (AttrNumber) (i + 1), proc, arg);
- }
-
- return (skey);
-}
+ ScanKey skey;
+ TupleDesc itupdesc;
+ int natts;
+ AttrNumber i;
+ Datum arg;
+ RegProcedure proc;
+ bool null;
+
+ natts = rel->rd_rel->relnatts;
+ itupdesc = RelationGetTupleDescriptor(rel);
+
+ skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
+
+ for (i = 0; i < natts; i++)
+ {
+ arg = index_getattr(itup, i + 1, itupdesc, &null);
+ proc = metap->hashm_procid;
+ ScanKeyEntryInitialize(&skey[i],
+ 0x0, (AttrNumber) (i + 1), proc, arg);
+ }
+
+ return (skey);
+}
void
_hash_freeskey(ScanKey skey)
{
- pfree(skey);
+ pfree(skey);
}
bool
_hash_checkqual(IndexScanDesc scan, IndexTuple itup)
{
- if (scan->numberOfKeys > 0)
- return (index_keytest(itup,
- RelationGetTupleDescriptor(scan->relation),
- scan->numberOfKeys, scan->keyData));
- else
- return (true);
+ if (scan->numberOfKeys > 0)
+ return (index_keytest(itup,
+ RelationGetTupleDescriptor(scan->relation),
+ scan->numberOfKeys, scan->keyData));
+ else
+ return (true);
}
HashItem
_hash_formitem(IndexTuple itup)
{
- int nbytes_hitem;
- HashItem hitem;
- Size tuplen;
-
- /* disallow nulls in hash keys */
- if (itup->t_info & INDEX_NULL_MASK)
- elog(WARN, "hash indices cannot include null keys");
-
- /* make a copy of the index tuple with room for the sequence number */
- tuplen = IndexTupleSize(itup);
- nbytes_hitem = tuplen +
- (sizeof(HashItemData) - sizeof(IndexTupleData));
-
- hitem = (HashItem) palloc(nbytes_hitem);
- memmove((char *) &(hitem->hash_itup), (char *) itup, tuplen);
-
- return (hitem);
+ int nbytes_hitem;
+ HashItem hitem;
+ Size tuplen;
+
+ /* disallow nulls in hash keys */
+ if (itup->t_info & INDEX_NULL_MASK)
+ elog(WARN, "hash indices cannot include null keys");
+
+ /* make a copy of the index tuple with room for the sequence number */
+ tuplen = IndexTupleSize(itup);
+ nbytes_hitem = tuplen +
+ (sizeof(HashItemData) - sizeof(IndexTupleData));
+
+ hitem = (HashItem) palloc(nbytes_hitem);
+ memmove((char *) &(hitem->hash_itup), (char *) itup, tuplen);
+
+ return (hitem);
}
Bucket
_hash_call(Relation rel, HashMetaPage metap, Datum key)
{
- uint32 n;
- Bucket bucket;
- RegProcedure proc;
-
- proc = metap->hashm_procid;
- n = (uint32) fmgr(proc, key);
- bucket = n & metap->hashm_highmask;
- if (bucket > metap->hashm_maxbucket)
- bucket = bucket & metap->hashm_lowmask;
- return (bucket);
+ uint32 n;
+ Bucket bucket;
+ RegProcedure proc;
+
+ proc = metap->hashm_procid;
+ n = (uint32) fmgr(proc, key);
+ bucket = n & metap->hashm_highmask;
+ if (bucket > metap->hashm_maxbucket)
+ bucket = bucket & metap->hashm_lowmask;
+ return (bucket);
}
/*
@@ -112,12 +113,13 @@ _hash_call(Relation rel, HashMetaPage metap, Datum key)
uint32
_hash_log2(uint32 num)
{
- uint32 i, limit;
-
- limit = 1;
- for (i = 0; limit < num; limit = limit << 1, i++)
- ;
- return (i);
+ uint32 i,
+ limit;
+
+ limit = 1;
+ for (i = 0; limit < num; limit = limit << 1, i++)
+ ;
+ return (i);
}
/*
@@ -126,19 +128,20 @@ _hash_log2(uint32 num)
void
_hash_checkpage(Page page, int flags)
{
- HashPageOpaque opaque;
+ HashPageOpaque opaque;
- Assert(page);
- Assert(((PageHeader)(page))->pd_lower >= (sizeof(PageHeaderData) - sizeof(ItemIdData)));
+ Assert(page);
+ Assert(((PageHeader) (page))->pd_lower >= (sizeof(PageHeaderData) - sizeof(ItemIdData)));
#if 1
- Assert(((PageHeader)(page))->pd_upper <=
- (BLCKSZ - DOUBLEALIGN(sizeof(HashPageOpaqueData))));
- Assert(((PageHeader)(page))->pd_special ==
- (BLCKSZ - DOUBLEALIGN(sizeof(HashPageOpaqueData))));
- Assert(((PageHeader)(page))->pd_opaque.od_pagesize == BLCKSZ);
+ Assert(((PageHeader) (page))->pd_upper <=
+ (BLCKSZ - DOUBLEALIGN(sizeof(HashPageOpaqueData))));
+ Assert(((PageHeader) (page))->pd_special ==
+ (BLCKSZ - DOUBLEALIGN(sizeof(HashPageOpaqueData))));
+ Assert(((PageHeader) (page))->pd_opaque.od_pagesize == BLCKSZ);
#endif
- if (flags) {
- opaque = (HashPageOpaque) PageGetSpecialPointer(page);
- Assert(opaque->hasho_flag & flags);
- }
+ if (flags)
+ {
+ opaque = (HashPageOpaque) PageGetSpecialPointer(page);
+ Assert(opaque->hasho_flag & flags);
+ }
}
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index f199803a711..b7ab8625140 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -1,74 +1,74 @@
/*-------------------------------------------------------------------------
*
* heapam.c--
- * heap access method code
+ * heap access method code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.15 1997/08/27 09:00:20 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.16 1997/09/07 04:38:09 momjian Exp $
*
*
* INTERFACE ROUTINES
- * heapgettup - fetch next heap tuple from a scan
- * heap_open - open a heap relation by relationId
- * heap_openr - open a heap relation by name
- * heap_close - close a heap relation
- * heap_beginscan - begin relation scan
- * heap_rescan - restart a relation scan
- * heap_endscan - end relation scan
- * heap_getnext - retrieve next tuple in scan
- * heap_fetch - retrive tuple with tid
- * heap_insert - insert tuple into a relation
- * heap_delete - delete a tuple from a relation
- * heap_replace - replace a tuple in a relation with another tuple
- * heap_markpos - mark scan position
- * heap_restrpos - restore position to marked location
- *
+ * heapgettup - fetch next heap tuple from a scan
+ * heap_open - open a heap relation by relationId
+ * heap_openr - open a heap relation by name
+ * heap_close - close a heap relation
+ * heap_beginscan - begin relation scan
+ * heap_rescan - restart a relation scan
+ * heap_endscan - end relation scan
+ * heap_getnext - retrieve next tuple in scan
+ * heap_fetch - retrive tuple with tid
+ * heap_insert - insert tuple into a relation
+ * heap_delete - delete a tuple from a relation
+ * heap_replace - replace a tuple in a relation with another tuple
+ * heap_markpos - mark scan position
+ * heap_restrpos - restore position to marked location
+ *
* NOTES
- * This file contains the heap_ routines which implement
- * the POSTGRES heap access method used for all POSTGRES
- * relations.
+ * This file contains the heap_ routines which implement
+ * the POSTGRES heap access method used for all POSTGRES
+ * relations.
*
* OLD COMMENTS
- * struct relscan hints: (struct should be made AM independent?)
+ * struct relscan hints: (struct should be made AM independent?)
*
- * rs_ctid is the tid of the last tuple returned by getnext.
- * rs_ptid and rs_ntid are the tids of the previous and next tuples
- * returned by getnext, respectively. NULL indicates an end of
- * scan (either direction); NON indicates an unknow value.
+ * rs_ctid is the tid of the last tuple returned by getnext.
+ * rs_ptid and rs_ntid are the tids of the previous and next tuples
+ * returned by getnext, respectively. NULL indicates an end of
+ * scan (either direction); NON indicates an unknow value.
*
- * possible combinations:
- * rs_p rs_c rs_n interpretation
- * NULL NULL NULL empty scan
- * NULL NULL NON at begining of scan
- * NULL NULL t1 at begining of scan (with cached tid)
- * NON NULL NULL at end of scan
- * t1 NULL NULL at end of scan (with cached tid)
- * NULL t1 NULL just returned only tuple
- * NULL t1 NON just returned first tuple
- * NULL t1 t2 returned first tuple (with cached tid)
- * NON t1 NULL just returned last tuple
- * t2 t1 NULL returned last tuple (with cached tid)
- * t1 t2 NON in the middle of a forward scan
- * NON t2 t1 in the middle of a reverse scan
- * ti tj tk in the middle of a scan (w cached tid)
+ * possible combinations:
+ * rs_p rs_c rs_n interpretation
+ * NULL NULL NULL empty scan
+ * NULL NULL NON at begining of scan
+ * NULL NULL t1 at begining of scan (with cached tid)
+ * NON NULL NULL at end of scan
+ * t1 NULL NULL at end of scan (with cached tid)
+ * NULL t1 NULL just returned only tuple
+ * NULL t1 NON just returned first tuple
+ * NULL t1 t2 returned first tuple (with cached tid)
+ * NON t1 NULL just returned last tuple
+ * t2 t1 NULL returned last tuple (with cached tid)
+ * t1 t2 NON in the middle of a forward scan
+ * NON t2 t1 in the middle of a reverse scan
+ * ti tj tk in the middle of a scan (w cached tid)
*
- * Here NULL is ...tup == NULL && ...buf == InvalidBuffer,
- * and NON is ...tup == NULL && ...buf == UnknownBuffer.
+ * Here NULL is ...tup == NULL && ...buf == InvalidBuffer,
+ * and NON is ...tup == NULL && ...buf == UnknownBuffer.
*
- * Currently, the NONTID values are not cached with their actual
- * values by getnext. Values may be cached by markpos since it stores
- * all three tids.
+ * Currently, the NONTID values are not cached with their actual
+ * values by getnext. Values may be cached by markpos since it stores
+ * all three tids.
*
- * NOTE: the calls to elog() must stop. Should decide on an interface
- * between the general and specific AM calls.
+ * NOTE: the calls to elog() must stop. Should decide on an interface
+ * between the general and specific AM calls.
*
- * XXX probably do not need a free tuple routine for heaps.
- * Huh? Free tuple is not necessary for tuples returned by scans, but
- * is necessary for tuples which are returned by
- * RelationGetTupleByItemPointer. -hirohama
+ * XXX probably do not need a free tuple routine for heaps.
+ * Huh? Free tuple is not necessary for tuples returned by scans, but
+ * is necessary for tuples which are returned by
+ * RelationGetTupleByItemPointer. -hirohama
*
*-------------------------------------------------------------------------
*/
@@ -91,644 +91,706 @@
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static bool ImmediateInvalidation;
+static bool ImmediateInvalidation;
/* ----------------------------------------------------------------
- * heap support routines
+ * heap support routines
* ----------------------------------------------------------------
*/
/* ----------------
- * initsdesc - sdesc code common to heap_beginscan and heap_rescan
+ * initsdesc - sdesc code common to heap_beginscan and heap_rescan
* ----------------
*/
static void
initsdesc(HeapScanDesc sdesc,
- Relation relation,
- int atend,
- unsigned nkeys,
- ScanKey key)
+ Relation relation,
+ int atend,
+ unsigned nkeys,
+ ScanKey key)
{
- if (!RelationGetNumberOfBlocks(relation)) {
- /* ----------------
- * relation is empty
- * ----------------
- */
- sdesc->rs_ntup = sdesc->rs_ctup = sdesc->rs_ptup = NULL;
- sdesc->rs_nbuf = sdesc->rs_cbuf = sdesc->rs_pbuf = InvalidBuffer;
- } else if (atend) {
- /* ----------------
- * reverse scan
- * ----------------
- */
- sdesc->rs_ntup = sdesc->rs_ctup = NULL;
- sdesc->rs_nbuf = sdesc->rs_cbuf = InvalidBuffer;
- sdesc->rs_ptup = NULL;
- sdesc->rs_pbuf = UnknownBuffer;
- } else {
+ if (!RelationGetNumberOfBlocks(relation))
+ {
+ /* ----------------
+ * relation is empty
+ * ----------------
+ */
+ sdesc->rs_ntup = sdesc->rs_ctup = sdesc->rs_ptup = NULL;
+ sdesc->rs_nbuf = sdesc->rs_cbuf = sdesc->rs_pbuf = InvalidBuffer;
+ }
+ else if (atend)
+ {
+ /* ----------------
+ * reverse scan
+ * ----------------
+ */
+ sdesc->rs_ntup = sdesc->rs_ctup = NULL;
+ sdesc->rs_nbuf = sdesc->rs_cbuf = InvalidBuffer;
+ sdesc->rs_ptup = NULL;
+ sdesc->rs_pbuf = UnknownBuffer;
+ }
+ else
+ {
+ /* ----------------
+ * forward scan
+ * ----------------
+ */
+ sdesc->rs_ctup = sdesc->rs_ptup = NULL;
+ sdesc->rs_cbuf = sdesc->rs_pbuf = InvalidBuffer;
+ sdesc->rs_ntup = NULL;
+ sdesc->rs_nbuf = UnknownBuffer;
+ } /* invalid too */
+
+ /* we don't have a marked position... */
+ ItemPointerSetInvalid(&(sdesc->rs_mptid));
+ ItemPointerSetInvalid(&(sdesc->rs_mctid));
+ ItemPointerSetInvalid(&(sdesc->rs_mntid));
+ ItemPointerSetInvalid(&(sdesc->rs_mcd));
+
/* ----------------
- * forward scan
+ * copy the scan key, if appropriate
* ----------------
*/
- sdesc->rs_ctup = sdesc->rs_ptup = NULL;
- sdesc->rs_cbuf = sdesc->rs_pbuf = InvalidBuffer;
- sdesc->rs_ntup = NULL;
- sdesc->rs_nbuf = UnknownBuffer;
- } /* invalid too */
-
- /* we don't have a marked position... */
- ItemPointerSetInvalid(&(sdesc->rs_mptid));
- ItemPointerSetInvalid(&(sdesc->rs_mctid));
- ItemPointerSetInvalid(&(sdesc->rs_mntid));
- ItemPointerSetInvalid(&(sdesc->rs_mcd));
-
- /* ----------------
- * copy the scan key, if appropriate
- * ----------------
- */
- if (key != NULL)
- memmove(sdesc->rs_key, key, nkeys * sizeof(ScanKeyData));
+ if (key != NULL)
+ memmove(sdesc->rs_key, key, nkeys * sizeof(ScanKeyData));
}
/* ----------------
- * unpinsdesc - code common to heap_rescan and heap_endscan
+ * unpinsdesc - code common to heap_rescan and heap_endscan
* ----------------
*/
static void
unpinsdesc(HeapScanDesc sdesc)
{
- if (BufferIsValid(sdesc->rs_pbuf)) {
- ReleaseBuffer(sdesc->rs_pbuf);
- }
-
- /* ------------------------------------
- * Scan will pin buffer one for each non-NULL tuple pointer
- * (ptup, ctup, ntup), so they have to be unpinned multiple
- * times.
- * ------------------------------------
- */
- if (BufferIsValid(sdesc->rs_cbuf)) {
- ReleaseBuffer(sdesc->rs_cbuf);
- }
-
- if (BufferIsValid(sdesc->rs_nbuf)) {
- ReleaseBuffer(sdesc->rs_nbuf);
- }
+ if (BufferIsValid(sdesc->rs_pbuf))
+ {
+ ReleaseBuffer(sdesc->rs_pbuf);
+ }
+
+ /* ------------------------------------
+ * Scan will pin buffer one for each non-NULL tuple pointer
+ * (ptup, ctup, ntup), so they have to be unpinned multiple
+ * times.
+ * ------------------------------------
+ */
+ if (BufferIsValid(sdesc->rs_cbuf))
+ {
+ ReleaseBuffer(sdesc->rs_cbuf);
+ }
+
+ if (BufferIsValid(sdesc->rs_nbuf))
+ {
+ ReleaseBuffer(sdesc->rs_nbuf);
+ }
}
/* ------------------------------------------
- * nextpage
+ * nextpage
*
- * figure out the next page to scan after the current page
- * taking into account of possible adjustment of degrees of
- * parallelism
+ * figure out the next page to scan after the current page
+ * taking into account of possible adjustment of degrees of
+ * parallelism
* ------------------------------------------
*/
static int
nextpage(int page, int dir)
{
- return((dir<0)?page-1:page+1);
+ return ((dir < 0) ? page - 1 : page + 1);
}
/* ----------------
- * heapgettup - fetch next heap tuple
+ * heapgettup - fetch next heap tuple
*
- * routine used by heap_getnext() which does most of the
- * real work in scanning tuples.
+ * routine used by heap_getnext() which does most of the
+ * real work in scanning tuples.
* ----------------
*/
-static HeapTuple
+static HeapTuple
heapgettup(Relation relation,
- ItemPointer tid,
- int dir,
- Buffer *b,
- TimeQual timeQual,
- int nkeys,
- ScanKey key)
+ ItemPointer tid,
+ int dir,
+ Buffer * b,
+ TimeQual timeQual,
+ int nkeys,
+ ScanKey key)
{
- ItemId lpp;
- Page dp;
- int page;
- int pages;
- int lines;
- HeapTuple rtup;
- OffsetNumber lineoff;
- int linesleft;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_heapgettup);
- IncrHeapAccessStat(global_heapgettup);
-
- /* ----------------
- * debugging stuff
- *
- * check validity of arguments, here and for other functions too
- * Note: no locking manipulations needed--this is a local function
- * ----------------
- */
-#ifdef HEAPDEBUGALL
- if (ItemPointerIsValid(tid)) {
- elog(DEBUG, "heapgettup(%.16s, tid=0x%x[%d,%d], dir=%d, ...)",
- RelationGetRelationName(relation), tid, tid->ip_blkid,
- tid->ip_posid, dir);
- } else {
- elog(DEBUG, "heapgettup(%.16s, tid=0x%x, dir=%d, ...)",
- RelationGetRelationName(relation), tid, dir);
- }
- elog(DEBUG, "heapgettup(..., b=0x%x, timeQ=0x%x, nkeys=%d, key=0x%x",
- b, timeQual, nkeys, key);
- if (timeQual == SelfTimeQual) {
- elog(DEBUG, "heapgettup: relation(%c)=`%.16s', SelfTimeQual",
- relation->rd_rel->relkind, &relation->rd_rel->relname);
- } else {
- elog(DEBUG, "heapgettup: relation(%c)=`%.16s', timeQual=%d",
- relation->rd_rel->relkind, &relation->rd_rel->relname,
- timeQual);
- }
-#endif /* !defined(HEAPDEBUGALL) */
-
- if (!ItemPointerIsValid(tid)) {
- Assert(!PointerIsValid(tid));
- }
-
- /* ----------------
- * return null immediately if relation is empty
- * ----------------
- */
- if (!(pages = relation->rd_nblocks))
- return (NULL);
-
- /* ----------------
- * calculate next starting lineoff, given scan direction
- * ----------------
- */
- if (!dir) {
+ ItemId lpp;
+ Page dp;
+ int page;
+ int pages;
+ int lines;
+ HeapTuple rtup;
+ OffsetNumber lineoff;
+ int linesleft;
+
/* ----------------
- * ``no movement'' scan direction
+ * increment access statistics
* ----------------
*/
- /* assume it is a valid TID XXX */
- if (ItemPointerIsValid(tid) == false) {
- *b = InvalidBuffer;
- return (NULL);
- }
- *b = RelationGetBufferWithBuffer(relation,
- ItemPointerGetBlockNumber(tid),
- *b);
-
-#ifndef NO_BUFFERISVALID
- if (!BufferIsValid(*b)) {
- elog(WARN, "heapgettup: failed ReadBuffer");
- }
-#endif
-
- dp = (Page) BufferGetPage(*b);
- lineoff = ItemPointerGetOffsetNumber(tid);
- lpp = PageGetItemId(dp, lineoff);
-
- rtup = (HeapTuple)PageGetItem((Page) dp, lpp);
- return (rtup);
-
- } else if (dir < 0) {
+ IncrHeapAccessStat(local_heapgettup);
+ IncrHeapAccessStat(global_heapgettup);
+
/* ----------------
- * reverse scan direction
+ * debugging stuff
+ *
+ * check validity of arguments, here and for other functions too
+ * Note: no locking manipulations needed--this is a local function
* ----------------
*/
- if (ItemPointerIsValid(tid) == false) {
- tid = NULL;
+#ifdef HEAPDEBUGALL
+ if (ItemPointerIsValid(tid))
+ {
+ elog(DEBUG, "heapgettup(%.16s, tid=0x%x[%d,%d], dir=%d, ...)",
+ RelationGetRelationName(relation), tid, tid->ip_blkid,
+ tid->ip_posid, dir);
}
- if (tid == NULL) {
- page = pages - 1; /* final page */
- } else {
- page = ItemPointerGetBlockNumber(tid); /* current page */
+ else
+ {
+ elog(DEBUG, "heapgettup(%.16s, tid=0x%x, dir=%d, ...)",
+ RelationGetRelationName(relation), tid, dir);
}
- if (page < 0) {
- *b = InvalidBuffer;
- return (NULL);
+ elog(DEBUG, "heapgettup(..., b=0x%x, timeQ=0x%x, nkeys=%d, key=0x%x",
+ b, timeQual, nkeys, key);
+ if (timeQual == SelfTimeQual)
+ {
+ elog(DEBUG, "heapgettup: relation(%c)=`%.16s', SelfTimeQual",
+ relation->rd_rel->relkind, &relation->rd_rel->relname);
}
-
- *b = RelationGetBufferWithBuffer(relation, page, *b);
-#ifndef NO_BUFFERISVALID
- if (!BufferIsValid(*b)) {
- elog(WARN, "heapgettup: failed ReadBuffer");
+ else
+ {
+ elog(DEBUG, "heapgettup: relation(%c)=`%.16s', timeQual=%d",
+ relation->rd_rel->relkind, &relation->rd_rel->relname,
+ timeQual);
}
-#endif
-
- dp = (Page) BufferGetPage(*b);
- lines = PageGetMaxOffsetNumber(dp);
- if (tid == NULL) {
- lineoff = lines; /* final offnum */
- } else {
- lineoff = /* previous offnum */
- OffsetNumberPrev(ItemPointerGetOffsetNumber(tid));
+#endif /* !defined(HEAPDEBUGALL) */
+
+ if (!ItemPointerIsValid(tid))
+ {
+ Assert(!PointerIsValid(tid));
}
- /* page and lineoff now reference the physically previous tid */
- } else {
/* ----------------
- * forward scan direction
+ * return null immediately if relation is empty
* ----------------
*/
- if (ItemPointerIsValid(tid) == false) {
- page = 0; /* first page */
- lineoff = FirstOffsetNumber; /* first offnum */
- } else {
- page = ItemPointerGetBlockNumber(tid); /* current page */
- lineoff = /* next offnum */
- OffsetNumberNext(ItemPointerGetOffsetNumber(tid));
- }
-
- if (page >= pages) {
- *b = InvalidBuffer;
- return (NULL);
- }
- /* page and lineoff now reference the physically next tid */
+ if (!(pages = relation->rd_nblocks))
+ return (NULL);
+
+ /* ----------------
+ * calculate next starting lineoff, given scan direction
+ * ----------------
+ */
+ if (!dir)
+ {
+ /* ----------------
+ * ``no movement'' scan direction
+ * ----------------
+ */
+ /* assume it is a valid TID XXX */
+ if (ItemPointerIsValid(tid) == false)
+ {
+ *b = InvalidBuffer;
+ return (NULL);
+ }
+ *b = RelationGetBufferWithBuffer(relation,
+ ItemPointerGetBlockNumber(tid),
+ *b);
- *b = RelationGetBufferWithBuffer(relation, page, *b);
#ifndef NO_BUFFERISVALID
- if (!BufferIsValid(*b)) {
- elog(WARN, "heapgettup: failed ReadBuffer");
+ if (!BufferIsValid(*b))
+ {
+ elog(WARN, "heapgettup: failed ReadBuffer");
+ }
+#endif
+
+ dp = (Page) BufferGetPage(*b);
+ lineoff = ItemPointerGetOffsetNumber(tid);
+ lpp = PageGetItemId(dp, lineoff);
+
+ rtup = (HeapTuple) PageGetItem((Page) dp, lpp);
+ return (rtup);
+
}
+ else if (dir < 0)
+ {
+ /* ----------------
+ * reverse scan direction
+ * ----------------
+ */
+ if (ItemPointerIsValid(tid) == false)
+ {
+ tid = NULL;
+ }
+ if (tid == NULL)
+ {
+ page = pages - 1; /* final page */
+ }
+ else
+ {
+ page = ItemPointerGetBlockNumber(tid); /* current page */
+ }
+ if (page < 0)
+ {
+ *b = InvalidBuffer;
+ return (NULL);
+ }
+
+ *b = RelationGetBufferWithBuffer(relation, page, *b);
+#ifndef NO_BUFFERISVALID
+ if (!BufferIsValid(*b))
+ {
+ elog(WARN, "heapgettup: failed ReadBuffer");
+ }
#endif
-
- dp = (Page) BufferGetPage(*b);
- lines = PageGetMaxOffsetNumber(dp);
- }
-
- /* 'dir' is now non-zero */
-
- /* ----------------
- * calculate line pointer and number of remaining items
- * to check on this page.
- * ----------------
- */
- lpp = PageGetItemId(dp, lineoff);
- if (dir < 0) {
- linesleft = lineoff - 1;
- } else {
- linesleft = lines - lineoff;
- }
-
- /* ----------------
- * advance the scan until we find a qualifying tuple or
- * run out of stuff to scan
- * ----------------
- */
- for (;;) {
- while (linesleft >= 0) {
- /* ----------------
- * if current tuple qualifies, return it.
- * ----------------
- */
- if ((rtup = heap_tuple_satisfies(lpp, relation, *b, (PageHeader) dp,
- timeQual, nkeys, key)) != NULL) {
- ItemPointer iptr = &(rtup->t_ctid);
- if (ItemPointerGetBlockNumber(iptr) != page) {
- /*
- * set block id to the correct page number
- * --- this is a hack to support the virtual fragment
- * concept
- */
- ItemPointerSetBlockNumber(iptr, page);
+
+ dp = (Page) BufferGetPage(*b);
+ lines = PageGetMaxOffsetNumber(dp);
+ if (tid == NULL)
+ {
+ lineoff = lines; /* final offnum */
}
- return (rtup);
- }
-
- /* ----------------
- * otherwise move to the next item on the page
- * ----------------
- */
- --linesleft;
- if (dir < 0) {
- --lpp; /* move back in this page's ItemId array */
- } else {
- ++lpp; /* move forward in this page's ItemId array */
- }
+ else
+ {
+ lineoff = /* previous offnum */
+ OffsetNumberPrev(ItemPointerGetOffsetNumber(tid));
+ }
+ /* page and lineoff now reference the physically previous tid */
+
+ }
+ else
+ {
+ /* ----------------
+ * forward scan direction
+ * ----------------
+ */
+ if (ItemPointerIsValid(tid) == false)
+ {
+ page = 0; /* first page */
+ lineoff = FirstOffsetNumber; /* first offnum */
+ }
+ else
+ {
+ page = ItemPointerGetBlockNumber(tid); /* current page */
+ lineoff = /* next offnum */
+ OffsetNumberNext(ItemPointerGetOffsetNumber(tid));
+ }
+
+ if (page >= pages)
+ {
+ *b = InvalidBuffer;
+ return (NULL);
+ }
+ /* page and lineoff now reference the physically next tid */
+
+ *b = RelationGetBufferWithBuffer(relation, page, *b);
+#ifndef NO_BUFFERISVALID
+ if (!BufferIsValid(*b))
+ {
+ elog(WARN, "heapgettup: failed ReadBuffer");
+ }
+#endif
+
+ dp = (Page) BufferGetPage(*b);
+ lines = PageGetMaxOffsetNumber(dp);
}
-
+
+ /* 'dir' is now non-zero */
+
/* ----------------
- * if we get here, it means we've exhausted the items on
- * this page and it's time to move to the next..
+ * calculate line pointer and number of remaining items
+ * to check on this page.
* ----------------
*/
- page = nextpage(page, dir);
-
+ lpp = PageGetItemId(dp, lineoff);
+ if (dir < 0)
+ {
+ linesleft = lineoff - 1;
+ }
+ else
+ {
+ linesleft = lines - lineoff;
+ }
+
/* ----------------
- * return NULL if we've exhausted all the pages..
+ * advance the scan until we find a qualifying tuple or
+ * run out of stuff to scan
* ----------------
*/
- if (page < 0 || page >= pages) {
- if (BufferIsValid(*b))
- ReleaseBuffer(*b);
- *b = InvalidBuffer;
- return (NULL);
- }
-
- *b = ReleaseAndReadBuffer(*b, relation, page);
-
+ for (;;)
+ {
+ while (linesleft >= 0)
+ {
+ /* ----------------
+ * if current tuple qualifies, return it.
+ * ----------------
+ */
+ if ((rtup = heap_tuple_satisfies(lpp, relation, *b, (PageHeader) dp,
+ timeQual, nkeys, key)) != NULL)
+ {
+ ItemPointer iptr = &(rtup->t_ctid);
+
+ if (ItemPointerGetBlockNumber(iptr) != page)
+ {
+
+ /*
+ * set block id to the correct page number --- this is
+ * a hack to support the virtual fragment concept
+ */
+ ItemPointerSetBlockNumber(iptr, page);
+ }
+ return (rtup);
+ }
+
+ /* ----------------
+ * otherwise move to the next item on the page
+ * ----------------
+ */
+ --linesleft;
+ if (dir < 0)
+ {
+ --lpp; /* move back in this page's ItemId array */
+ }
+ else
+ {
+ ++lpp; /* move forward in this page's ItemId
+ * array */
+ }
+ }
+
+ /* ----------------
+ * if we get here, it means we've exhausted the items on
+ * this page and it's time to move to the next..
+ * ----------------
+ */
+ page = nextpage(page, dir);
+
+ /* ----------------
+ * return NULL if we've exhausted all the pages..
+ * ----------------
+ */
+ if (page < 0 || page >= pages)
+ {
+ if (BufferIsValid(*b))
+ ReleaseBuffer(*b);
+ *b = InvalidBuffer;
+ return (NULL);
+ }
+
+ *b = ReleaseAndReadBuffer(*b, relation, page);
+
#ifndef NO_BUFFERISVALID
- if (!BufferIsValid(*b)) {
- elog(WARN, "heapgettup: failed ReadBuffer");
- }
+ if (!BufferIsValid(*b))
+ {
+ elog(WARN, "heapgettup: failed ReadBuffer");
+ }
#endif
- dp = (Page) BufferGetPage(*b);
- lines = lineoff = PageGetMaxOffsetNumber((Page) dp);
- linesleft = lines - 1;
- if (dir < 0) {
- lpp = PageGetItemId(dp, lineoff);
- } else {
- lpp = PageGetItemId(dp, FirstOffsetNumber);
+ dp = (Page) BufferGetPage(*b);
+ lines = lineoff = PageGetMaxOffsetNumber((Page) dp);
+ linesleft = lines - 1;
+ if (dir < 0)
+ {
+ lpp = PageGetItemId(dp, lineoff);
+ }
+ else
+ {
+ lpp = PageGetItemId(dp, FirstOffsetNumber);
+ }
}
- }
}
void
doinsert(Relation relation, HeapTuple tup)
{
- RelationPutHeapTupleAtEnd(relation, tup);
- return;
+ RelationPutHeapTupleAtEnd(relation, tup);
+ return;
}
-/*
- * HeapScanIsValid is now a macro in relscan.h -cim 4/27/91
+/*
+ * HeapScanIsValid is now a macro in relscan.h -cim 4/27/91
*/
#ifdef NOT_USED
/* ----------------
- * SetHeapAccessMethodImmediateInvalidation
+ * SetHeapAccessMethodImmediateInvalidation
* ----------------
*/
void
SetHeapAccessMethodImmediateInvalidation(bool on)
{
- ImmediateInvalidation = on;
+ ImmediateInvalidation = on;
}
+
#endif
/* ----------------------------------------------------------------
- * heap access method interface
+ * heap access method interface
* ----------------------------------------------------------------
*/
/* ----------------
- * heap_open - open a heap relation by relationId
+ * heap_open - open a heap relation by relationId
*
- * presently the relcache routines do all the work we need
- * to open/close heap relations.
+ * presently the relcache routines do all the work we need
+ * to open/close heap relations.
* ----------------
*/
Relation
heap_open(Oid relationId)
{
- Relation r;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_open);
- IncrHeapAccessStat(global_open);
-
- r = (Relation) RelationIdGetRelation(relationId);
-
- if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX) {
- elog(WARN, "%s is an index relation", r->rd_rel->relname.data);
- }
-
- return (r);
+ Relation r;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_open);
+ IncrHeapAccessStat(global_open);
+
+ r = (Relation) RelationIdGetRelation(relationId);
+
+ if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX)
+ {
+ elog(WARN, "%s is an index relation", r->rd_rel->relname.data);
+ }
+
+ return (r);
}
/* ----------------
- * heap_openr - open a heap relation by name
+ * heap_openr - open a heap relation by name
*
- * presently the relcache routines do all the work we need
- * to open/close heap relations.
+ * presently the relcache routines do all the work we need
+ * to open/close heap relations.
* ----------------
*/
Relation
heap_openr(char *relationName)
{
- Relation r;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_openr);
- IncrHeapAccessStat(global_openr);
-
- r = RelationNameGetRelation(relationName);
-
- if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX) {
- elog(WARN, "%s is an index relation", r->rd_rel->relname.data);
- }
-
- return (r);
+ Relation r;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_openr);
+ IncrHeapAccessStat(global_openr);
+
+ r = RelationNameGetRelation(relationName);
+
+ if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX)
+ {
+ elog(WARN, "%s is an index relation", r->rd_rel->relname.data);
+ }
+
+ return (r);
}
/* ----------------
- * heap_close - close a heap relation
+ * heap_close - close a heap relation
*
- * presently the relcache routines do all the work we need
- * to open/close heap relations.
+ * presently the relcache routines do all the work we need
+ * to open/close heap relations.
* ----------------
*/
void
heap_close(Relation relation)
{
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_close);
- IncrHeapAccessStat(global_close);
-
- RelationClose(relation);
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_close);
+ IncrHeapAccessStat(global_close);
+
+ RelationClose(relation);
}
/* ----------------
- * heap_beginscan - begin relation scan
+ * heap_beginscan - begin relation scan
* ----------------
*/
HeapScanDesc
heap_beginscan(Relation relation,
- int atend,
- TimeQual timeQual,
- unsigned nkeys,
- ScanKey key)
+ int atend,
+ TimeQual timeQual,
+ unsigned nkeys,
+ ScanKey key)
{
- HeapScanDesc sdesc;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_beginscan);
- IncrHeapAccessStat(global_beginscan);
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- if (RelationIsValid(relation) == false)
- elog(WARN, "heap_beginscan: !RelationIsValid(relation)");
-
- /* ----------------
- * set relation level read lock
- * ----------------
- */
- RelationSetLockForRead(relation);
-
- /* XXX someday assert SelfTimeQual if relkind == RELKIND_UNCATALOGED */
- if (relation->rd_rel->relkind == RELKIND_UNCATALOGED) {
- timeQual = SelfTimeQual;
- }
-
- /* ----------------
- * increment relation ref count while scanning relation
- * ----------------
- */
- RelationIncrementReferenceCount(relation);
-
- /* ----------------
- * allocate and initialize scan descriptor
- * ----------------
- */
- sdesc = (HeapScanDesc) palloc(sizeof(HeapScanDescData));
-
- relation->rd_nblocks = smgrnblocks(relation->rd_rel->relsmgr, relation);
- sdesc->rs_rd = relation;
-
- if (nkeys) {
- /*
- * we do this here instead of in initsdesc() because heap_rescan also
- * calls initsdesc() and we don't want to allocate memory again
+ HeapScanDesc sdesc;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_beginscan);
+ IncrHeapAccessStat(global_beginscan);
+
+ /* ----------------
+ * sanity checks
+ * ----------------
*/
- sdesc->rs_key = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys);
- } else {
- sdesc->rs_key = NULL;
- }
-
- initsdesc(sdesc, relation, atend, nkeys, key);
-
- sdesc->rs_atend = atend;
- sdesc->rs_tr = timeQual;
- sdesc->rs_nkeys = (short)nkeys;
-
- return (sdesc);
+ if (RelationIsValid(relation) == false)
+ elog(WARN, "heap_beginscan: !RelationIsValid(relation)");
+
+ /* ----------------
+ * set relation level read lock
+ * ----------------
+ */
+ RelationSetLockForRead(relation);
+
+ /* XXX someday assert SelfTimeQual if relkind == RELKIND_UNCATALOGED */
+ if (relation->rd_rel->relkind == RELKIND_UNCATALOGED)
+ {
+ timeQual = SelfTimeQual;
+ }
+
+ /* ----------------
+ * increment relation ref count while scanning relation
+ * ----------------
+ */
+ RelationIncrementReferenceCount(relation);
+
+ /* ----------------
+ * allocate and initialize scan descriptor
+ * ----------------
+ */
+ sdesc = (HeapScanDesc) palloc(sizeof(HeapScanDescData));
+
+ relation->rd_nblocks = smgrnblocks(relation->rd_rel->relsmgr, relation);
+ sdesc->rs_rd = relation;
+
+ if (nkeys)
+ {
+
+ /*
+ * we do this here instead of in initsdesc() because heap_rescan
+ * also calls initsdesc() and we don't want to allocate memory
+ * again
+ */
+ sdesc->rs_key = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys);
+ }
+ else
+ {
+ sdesc->rs_key = NULL;
+ }
+
+ initsdesc(sdesc, relation, atend, nkeys, key);
+
+ sdesc->rs_atend = atend;
+ sdesc->rs_tr = timeQual;
+ sdesc->rs_nkeys = (short) nkeys;
+
+ return (sdesc);
}
/* ----------------
- * heap_rescan - restart a relation scan
+ * heap_rescan - restart a relation scan
* ----------------
*/
void
heap_rescan(HeapScanDesc sdesc,
- bool scanFromEnd,
- ScanKey key)
+ bool scanFromEnd,
+ ScanKey key)
{
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_rescan);
- IncrHeapAccessStat(global_rescan);
-
- /* Note: set relation level read lock is still set */
-
- /* ----------------
- * unpin scan buffers
- * ----------------
- */
- unpinsdesc(sdesc);
-
- /* ----------------
- * reinitialize scan descriptor
- * ----------------
- */
- initsdesc(sdesc, sdesc->rs_rd, scanFromEnd, sdesc->rs_nkeys, key);
- sdesc->rs_atend = (bool) scanFromEnd;
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_rescan);
+ IncrHeapAccessStat(global_rescan);
+
+ /* Note: set relation level read lock is still set */
+
+ /* ----------------
+ * unpin scan buffers
+ * ----------------
+ */
+ unpinsdesc(sdesc);
+
+ /* ----------------
+ * reinitialize scan descriptor
+ * ----------------
+ */
+ initsdesc(sdesc, sdesc->rs_rd, scanFromEnd, sdesc->rs_nkeys, key);
+ sdesc->rs_atend = (bool) scanFromEnd;
}
/* ----------------
- * heap_endscan - end relation scan
+ * heap_endscan - end relation scan
*
- * See how to integrate with index scans.
- * Check handling if reldesc caching.
+ * See how to integrate with index scans.
+ * Check handling if reldesc caching.
* ----------------
*/
void
heap_endscan(HeapScanDesc sdesc)
{
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_endscan);
- IncrHeapAccessStat(global_endscan);
-
- /* Note: no locking manipulations needed */
-
- /* ----------------
- * unpin scan buffers
- * ----------------
- */
- unpinsdesc(sdesc);
-
- /* ----------------
- * decrement relation reference count and free scan descriptor storage
- * ----------------
- */
- RelationDecrementReferenceCount(sdesc->rs_rd);
-
- /* ----------------
- * Non 2-phase read locks on catalog relations
- * ----------------
- */
- if ( IsSystemRelationName(RelationGetRelationName(sdesc->rs_rd)->data) )
-
- RelationUnsetLockForRead(sdesc->rs_rd);
-
- pfree(sdesc); /* XXX */
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_endscan);
+ IncrHeapAccessStat(global_endscan);
+
+ /* Note: no locking manipulations needed */
+
+ /* ----------------
+ * unpin scan buffers
+ * ----------------
+ */
+ unpinsdesc(sdesc);
+
+ /* ----------------
+ * decrement relation reference count and free scan descriptor storage
+ * ----------------
+ */
+ RelationDecrementReferenceCount(sdesc->rs_rd);
+
+ /* ----------------
+ * Non 2-phase read locks on catalog relations
+ * ----------------
+ */
+ if (IsSystemRelationName(RelationGetRelationName(sdesc->rs_rd)->data))
+
+ RelationUnsetLockForRead(sdesc->rs_rd);
+
+ pfree(sdesc); /* XXX */
}
/* ----------------
- * heap_getnext - retrieve next tuple in scan
+ * heap_getnext - retrieve next tuple in scan
*
- * Fix to work with index relations.
+ * Fix to work with index relations.
* ----------------
*/
#ifdef HEAPDEBUGALL
#define HEAPDEBUG_1 \
elog(DEBUG, "heap_getnext([%s,nkeys=%d],backw=%d,0x%x) called", \
- sdesc->rs_rd->rd_rel->relname.data, sdesc->rs_nkeys, backw, b)
-
+ sdesc->rs_rd->rd_rel->relname.data, sdesc->rs_nkeys, backw, b)
+
#define HEAPDEBUG_2 \
- elog(DEBUG, "heap_getnext called with backw (no tracing yet)")
-
+ elog(DEBUG, "heap_getnext called with backw (no tracing yet)")
+
#define HEAPDEBUG_3 \
- elog(DEBUG, "heap_getnext returns NULL at end")
-
+ elog(DEBUG, "heap_getnext returns NULL at end")
+
#define HEAPDEBUG_4 \
- elog(DEBUG, "heap_getnext valid buffer UNPIN'd")
-
+ elog(DEBUG, "heap_getnext valid buffer UNPIN'd")
+
#define HEAPDEBUG_5 \
- elog(DEBUG, "heap_getnext next tuple was cached")
-
+ elog(DEBUG, "heap_getnext next tuple was cached")
+
#define HEAPDEBUG_6 \
- elog(DEBUG, "heap_getnext returning EOS")
-
+ elog(DEBUG, "heap_getnext returning EOS")
+
#define HEAPDEBUG_7 \
- elog(DEBUG, "heap_getnext returning tuple");
+ elog(DEBUG, "heap_getnext returning tuple");
#else
#define HEAPDEBUG_1
#define HEAPDEBUG_2
@@ -737,715 +799,759 @@ elog(DEBUG, "heap_getnext([%s,nkeys=%d],backw=%d,0x%x) called", \
#define HEAPDEBUG_5
#define HEAPDEBUG_6
#define HEAPDEBUG_7
-#endif /* !defined(HEAPDEBUGALL) */
-
-
+#endif /* !defined(HEAPDEBUGALL) */
+
+
HeapTuple
heap_getnext(HeapScanDesc scandesc,
- int backw,
- Buffer *b)
+ int backw,
+ Buffer * b)
{
- register HeapScanDesc sdesc = scandesc;
- Buffer localb;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_getnext);
- IncrHeapAccessStat(global_getnext);
-
- /* Note: no locking manipulations needed */
-
- /* ----------------
- * argument checks
- * ----------------
- */
- if (sdesc == NULL)
- elog(WARN, "heap_getnext: NULL relscan");
-
- /* ----------------
- * initialize return buffer to InvalidBuffer
- * ----------------
- */
- if (! PointerIsValid(b)) b = &localb;
- (*b) = InvalidBuffer;
-
- HEAPDEBUG_1; /* heap_getnext( info ) */
-
- if (backw) {
+ register HeapScanDesc sdesc = scandesc;
+ Buffer localb;
+
/* ----------------
- * handle reverse scan
+ * increment access statistics
* ----------------
*/
- HEAPDEBUG_2; /* heap_getnext called with backw */
-
- if (sdesc->rs_ptup == sdesc->rs_ctup &&
- BufferIsInvalid(sdesc->rs_pbuf))
- {
- if (BufferIsValid(sdesc->rs_nbuf))
- ReleaseBuffer(sdesc->rs_nbuf);
- return (NULL);
- }
-
- /*
- * Copy the "current" tuple/buffer
- * to "next". Pin/unpin the buffers
- * accordingly
+ IncrHeapAccessStat(local_getnext);
+ IncrHeapAccessStat(global_getnext);
+
+ /* Note: no locking manipulations needed */
+
+ /* ----------------
+ * argument checks
+ * ----------------
*/
- if (sdesc->rs_nbuf != sdesc->rs_cbuf) {
- if (BufferIsValid(sdesc->rs_nbuf))
- ReleaseBuffer(sdesc->rs_nbuf);
- if (BufferIsValid(sdesc->rs_cbuf))
- IncrBufferRefCount(sdesc->rs_cbuf);
- }
- sdesc->rs_ntup = sdesc->rs_ctup;
- sdesc->rs_nbuf = sdesc->rs_cbuf;
-
- if (sdesc->rs_ptup != NULL) {
- if (sdesc->rs_cbuf != sdesc->rs_pbuf) {
- if (BufferIsValid(sdesc->rs_cbuf))
- ReleaseBuffer(sdesc->rs_cbuf);
- if (BufferIsValid(sdesc->rs_pbuf))
- IncrBufferRefCount(sdesc->rs_pbuf);
- }
- sdesc->rs_ctup = sdesc->rs_ptup;
- sdesc->rs_cbuf = sdesc->rs_pbuf;
- } else { /* NONTUP */
- ItemPointer iptr;
-
- iptr = (sdesc->rs_ctup != NULL) ?
- &(sdesc->rs_ctup->t_ctid) : (ItemPointer) NULL;
-
- /* Don't release sdesc->rs_cbuf at this point, because
- heapgettup doesn't increase PrivateRefCount if it
- is already set. On a backward scan, both rs_ctup and rs_ntup
- usually point to the same buffer page, so
- PrivateRefCount[rs_cbuf] should be 2 (or more, if for instance
- ctup is stored in a TupleTableSlot). - 01/09/94 */
-
- sdesc->rs_ctup = (HeapTuple)
- heapgettup(sdesc->rs_rd,
- iptr,
- -1,
- &(sdesc->rs_cbuf),
- sdesc->rs_tr,
- sdesc->rs_nkeys,
- sdesc->rs_key);
- }
-
- if (sdesc->rs_ctup == NULL && !BufferIsValid(sdesc->rs_cbuf))
- {
+ if (sdesc == NULL)
+ elog(WARN, "heap_getnext: NULL relscan");
+
+ /* ----------------
+ * initialize return buffer to InvalidBuffer
+ * ----------------
+ */
+ if (!PointerIsValid(b))
+ b = &localb;
+ (*b) = InvalidBuffer;
+
+ HEAPDEBUG_1; /* heap_getnext( info ) */
+
+ if (backw)
+ {
+ /* ----------------
+ * handle reverse scan
+ * ----------------
+ */
+ HEAPDEBUG_2; /* heap_getnext called with backw */
+
+ if (sdesc->rs_ptup == sdesc->rs_ctup &&
+ BufferIsInvalid(sdesc->rs_pbuf))
+ {
+ if (BufferIsValid(sdesc->rs_nbuf))
+ ReleaseBuffer(sdesc->rs_nbuf);
+ return (NULL);
+ }
+
+ /*
+ * Copy the "current" tuple/buffer to "next". Pin/unpin the
+ * buffers accordingly
+ */
+ if (sdesc->rs_nbuf != sdesc->rs_cbuf)
+ {
+ if (BufferIsValid(sdesc->rs_nbuf))
+ ReleaseBuffer(sdesc->rs_nbuf);
+ if (BufferIsValid(sdesc->rs_cbuf))
+ IncrBufferRefCount(sdesc->rs_cbuf);
+ }
+ sdesc->rs_ntup = sdesc->rs_ctup;
+ sdesc->rs_nbuf = sdesc->rs_cbuf;
+
+ if (sdesc->rs_ptup != NULL)
+ {
+ if (sdesc->rs_cbuf != sdesc->rs_pbuf)
+ {
+ if (BufferIsValid(sdesc->rs_cbuf))
+ ReleaseBuffer(sdesc->rs_cbuf);
+ if (BufferIsValid(sdesc->rs_pbuf))
+ IncrBufferRefCount(sdesc->rs_pbuf);
+ }
+ sdesc->rs_ctup = sdesc->rs_ptup;
+ sdesc->rs_cbuf = sdesc->rs_pbuf;
+ }
+ else
+ { /* NONTUP */
+ ItemPointer iptr;
+
+ iptr = (sdesc->rs_ctup != NULL) ?
+ &(sdesc->rs_ctup->t_ctid) : (ItemPointer) NULL;
+
+ /*
+ * Don't release sdesc->rs_cbuf at this point, because
+ * heapgettup doesn't increase PrivateRefCount if it is
+ * already set. On a backward scan, both rs_ctup and rs_ntup
+ * usually point to the same buffer page, so
+ * PrivateRefCount[rs_cbuf] should be 2 (or more, if for
+ * instance ctup is stored in a TupleTableSlot). - 01/09/94
+ */
+
+ sdesc->rs_ctup = (HeapTuple)
+ heapgettup(sdesc->rs_rd,
+ iptr,
+ -1,
+ &(sdesc->rs_cbuf),
+ sdesc->rs_tr,
+ sdesc->rs_nkeys,
+ sdesc->rs_key);
+ }
+
+ if (sdesc->rs_ctup == NULL && !BufferIsValid(sdesc->rs_cbuf))
+ {
+ if (BufferIsValid(sdesc->rs_pbuf))
+ ReleaseBuffer(sdesc->rs_pbuf);
+ sdesc->rs_ptup = NULL;
+ sdesc->rs_pbuf = InvalidBuffer;
+ if (BufferIsValid(sdesc->rs_nbuf))
+ ReleaseBuffer(sdesc->rs_nbuf);
+ sdesc->rs_ntup = NULL;
+ sdesc->rs_nbuf = InvalidBuffer;
+ return (NULL);
+ }
+
if (BufferIsValid(sdesc->rs_pbuf))
- ReleaseBuffer(sdesc->rs_pbuf);
+ ReleaseBuffer(sdesc->rs_pbuf);
sdesc->rs_ptup = NULL;
- sdesc->rs_pbuf = InvalidBuffer;
+ sdesc->rs_pbuf = UnknownBuffer;
+
+ }
+ else
+ {
+ /* ----------------
+ * handle forward scan
+ * ----------------
+ */
+ if (sdesc->rs_ctup == sdesc->rs_ntup &&
+ BufferIsInvalid(sdesc->rs_nbuf))
+ {
+ if (BufferIsValid(sdesc->rs_pbuf))
+ ReleaseBuffer(sdesc->rs_pbuf);
+ HEAPDEBUG_3; /* heap_getnext returns NULL at end */
+ return (NULL);
+ }
+
+ /*
+ * Copy the "current" tuple/buffer to "previous". Pin/unpin the
+ * buffers accordingly
+ */
+ if (sdesc->rs_pbuf != sdesc->rs_cbuf)
+ {
+ if (BufferIsValid(sdesc->rs_pbuf))
+ ReleaseBuffer(sdesc->rs_pbuf);
+ if (BufferIsValid(sdesc->rs_cbuf))
+ IncrBufferRefCount(sdesc->rs_cbuf);
+ }
+ sdesc->rs_ptup = sdesc->rs_ctup;
+ sdesc->rs_pbuf = sdesc->rs_cbuf;
+
+ if (sdesc->rs_ntup != NULL)
+ {
+ if (sdesc->rs_cbuf != sdesc->rs_nbuf)
+ {
+ if (BufferIsValid(sdesc->rs_cbuf))
+ ReleaseBuffer(sdesc->rs_cbuf);
+ if (BufferIsValid(sdesc->rs_nbuf))
+ IncrBufferRefCount(sdesc->rs_nbuf);
+ }
+ sdesc->rs_ctup = sdesc->rs_ntup;
+ sdesc->rs_cbuf = sdesc->rs_nbuf;
+ HEAPDEBUG_5; /* heap_getnext next tuple was cached */
+ }
+ else
+ { /* NONTUP */
+ ItemPointer iptr;
+
+ iptr = (sdesc->rs_ctup != NULL) ?
+ &sdesc->rs_ctup->t_ctid : (ItemPointer) NULL;
+
+ /*
+ * Don't release sdesc->rs_cbuf at this point, because
+ * heapgettup doesn't increase PrivateRefCount if it is
+ * already set. On a forward scan, both rs_ctup and rs_ptup
+ * usually point to the same buffer page, so
+ * PrivateRefCount[rs_cbuf] should be 2 (or more, if for
+ * instance ctup is stored in a TupleTableSlot). - 01/09/93
+ */
+
+ sdesc->rs_ctup = (HeapTuple)
+ heapgettup(sdesc->rs_rd,
+ iptr,
+ 1,
+ &sdesc->rs_cbuf,
+ sdesc->rs_tr,
+ sdesc->rs_nkeys,
+ sdesc->rs_key);
+ }
+
+ if (sdesc->rs_ctup == NULL && !BufferIsValid(sdesc->rs_cbuf))
+ {
+ if (BufferIsValid(sdesc->rs_nbuf))
+ ReleaseBuffer(sdesc->rs_nbuf);
+ sdesc->rs_ntup = NULL;
+ sdesc->rs_nbuf = InvalidBuffer;
+ if (BufferIsValid(sdesc->rs_pbuf))
+ ReleaseBuffer(sdesc->rs_pbuf);
+ sdesc->rs_ptup = NULL;
+ sdesc->rs_pbuf = InvalidBuffer;
+ HEAPDEBUG_6; /* heap_getnext returning EOS */
+ return (NULL);
+ }
+
if (BufferIsValid(sdesc->rs_nbuf))
- ReleaseBuffer(sdesc->rs_nbuf);
+ ReleaseBuffer(sdesc->rs_nbuf);
sdesc->rs_ntup = NULL;
- sdesc->rs_nbuf = InvalidBuffer;
- return (NULL);
- }
-
- if (BufferIsValid(sdesc->rs_pbuf))
- ReleaseBuffer(sdesc->rs_pbuf);
- sdesc->rs_ptup = NULL;
- sdesc->rs_pbuf = UnknownBuffer;
-
- } else {
+ sdesc->rs_nbuf = UnknownBuffer;
+ }
+
/* ----------------
- * handle forward scan
+ * if we get here it means we have a new current scan tuple, so
+ * point to the proper return buffer and return the tuple.
* ----------------
*/
- if (sdesc->rs_ctup == sdesc->rs_ntup &&
- BufferIsInvalid(sdesc->rs_nbuf)) {
- if (BufferIsValid(sdesc->rs_pbuf))
- ReleaseBuffer(sdesc->rs_pbuf);
- HEAPDEBUG_3; /* heap_getnext returns NULL at end */
- return (NULL);
- }
-
- /*
- * Copy the "current" tuple/buffer
- * to "previous". Pin/unpin the buffers
- * accordingly
- */
- if (sdesc->rs_pbuf != sdesc->rs_cbuf) {
- if (BufferIsValid(sdesc->rs_pbuf))
- ReleaseBuffer(sdesc->rs_pbuf);
- if (BufferIsValid(sdesc->rs_cbuf))
- IncrBufferRefCount(sdesc->rs_cbuf);
- }
- sdesc->rs_ptup = sdesc->rs_ctup;
- sdesc->rs_pbuf = sdesc->rs_cbuf;
-
- if (sdesc->rs_ntup != NULL) {
- if (sdesc->rs_cbuf != sdesc->rs_nbuf) {
- if (BufferIsValid(sdesc->rs_cbuf))
- ReleaseBuffer(sdesc->rs_cbuf);
- if (BufferIsValid(sdesc->rs_nbuf))
- IncrBufferRefCount(sdesc->rs_nbuf);
- }
- sdesc->rs_ctup = sdesc->rs_ntup;
- sdesc->rs_cbuf = sdesc->rs_nbuf;
- HEAPDEBUG_5; /* heap_getnext next tuple was cached */
- } else { /* NONTUP */
- ItemPointer iptr;
-
- iptr = (sdesc->rs_ctup != NULL) ?
- &sdesc->rs_ctup->t_ctid : (ItemPointer) NULL;
-
- /* Don't release sdesc->rs_cbuf at this point, because
- heapgettup doesn't increase PrivateRefCount if it
- is already set. On a forward scan, both rs_ctup and rs_ptup
- usually point to the same buffer page, so
- PrivateRefCount[rs_cbuf] should be 2 (or more, if for instance
- ctup is stored in a TupleTableSlot). - 01/09/93 */
-
- sdesc->rs_ctup = (HeapTuple)
- heapgettup(sdesc->rs_rd,
- iptr,
- 1,
- &sdesc->rs_cbuf,
- sdesc->rs_tr,
- sdesc->rs_nkeys,
- sdesc->rs_key);
- }
-
- if (sdesc->rs_ctup == NULL && !BufferIsValid(sdesc->rs_cbuf)) {
- if (BufferIsValid(sdesc->rs_nbuf))
- ReleaseBuffer(sdesc->rs_nbuf);
- sdesc->rs_ntup = NULL;
- sdesc->rs_nbuf = InvalidBuffer;
- if (BufferIsValid(sdesc->rs_pbuf))
- ReleaseBuffer(sdesc->rs_pbuf);
- sdesc->rs_ptup = NULL;
- sdesc->rs_pbuf = InvalidBuffer;
- HEAPDEBUG_6; /* heap_getnext returning EOS */
- return (NULL);
- }
-
- if (BufferIsValid(sdesc->rs_nbuf))
- ReleaseBuffer(sdesc->rs_nbuf);
- sdesc->rs_ntup = NULL;
- sdesc->rs_nbuf = UnknownBuffer;
- }
-
- /* ----------------
- * if we get here it means we have a new current scan tuple, so
- * point to the proper return buffer and return the tuple.
- * ----------------
- */
- (*b) = sdesc->rs_cbuf;
-
- HEAPDEBUG_7; /* heap_getnext returning tuple */
-
- return (sdesc->rs_ctup);
+ (*b) = sdesc->rs_cbuf;
+
+ HEAPDEBUG_7; /* heap_getnext returning tuple */
+
+ return (sdesc->rs_ctup);
}
/* ----------------
- * heap_fetch - retrive tuple with tid
+ * heap_fetch - retrive tuple with tid
*
- * Currently ignores LP_IVALID during processing!
+ * Currently ignores LP_IVALID during processing!
* ----------------
*/
HeapTuple
heap_fetch(Relation relation,
- TimeQual timeQual,
- ItemPointer tid,
- Buffer *b)
+ TimeQual timeQual,
+ ItemPointer tid,
+ Buffer * b)
{
- ItemId lp;
- Buffer buffer;
- PageHeader dp;
- HeapTuple tuple;
- OffsetNumber offnum;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_fetch);
- IncrHeapAccessStat(global_fetch);
-
- /*
- * Note: This is collosally expensive - does two system calls per
- * indexscan tuple fetch. Not good, and since we should be doing
- * page level locking by the scanner anyway, it is commented out.
- */
-
- /* RelationSetLockForTupleRead(relation, tid); */
-
- /* ----------------
- * get the buffer from the relation descriptor
- * Note that this does a buffer pin.
- * ----------------
- */
-
- buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
-
+ ItemId lp;
+ Buffer buffer;
+ PageHeader dp;
+ HeapTuple tuple;
+ OffsetNumber offnum;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_fetch);
+ IncrHeapAccessStat(global_fetch);
+
+ /*
+ * Note: This is collosally expensive - does two system calls per
+ * indexscan tuple fetch. Not good, and since we should be doing page
+ * level locking by the scanner anyway, it is commented out.
+ */
+
+ /* RelationSetLockForTupleRead(relation, tid); */
+
+ /* ----------------
+ * get the buffer from the relation descriptor
+ * Note that this does a buffer pin.
+ * ----------------
+ */
+
+ buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
+
#ifndef NO_BUFFERISVALID
- if (!BufferIsValid(buffer)) {
- elog(WARN, "heap_fetch: %s relation: ReadBuffer(%lx) failed",
- &relation->rd_rel->relname, (long)tid);
- }
+ if (!BufferIsValid(buffer))
+ {
+ elog(WARN, "heap_fetch: %s relation: ReadBuffer(%lx) failed",
+ &relation->rd_rel->relname, (long) tid);
+ }
#endif
-
- /* ----------------
- * get the item line pointer corresponding to the requested tid
- * ----------------
- */
- dp = (PageHeader) BufferGetPage(buffer);
- offnum = ItemPointerGetOffsetNumber(tid);
- lp = PageGetItemId(dp, offnum);
-
- /* ----------------
- * more sanity checks
- * ----------------
- */
-
- Assert(ItemIdIsUsed(lp));
-
- /* ----------------
- * check time qualification of tid
- * ----------------
- */
-
- tuple = heap_tuple_satisfies(lp, relation, buffer, dp,
- timeQual, 0,(ScanKey)NULL);
-
- if (tuple == NULL)
+
+ /* ----------------
+ * get the item line pointer corresponding to the requested tid
+ * ----------------
+ */
+ dp = (PageHeader) BufferGetPage(buffer);
+ offnum = ItemPointerGetOffsetNumber(tid);
+ lp = PageGetItemId(dp, offnum);
+
+ /* ----------------
+ * more sanity checks
+ * ----------------
+ */
+
+ Assert(ItemIdIsUsed(lp));
+
+ /* ----------------
+ * check time qualification of tid
+ * ----------------
+ */
+
+ tuple = heap_tuple_satisfies(lp, relation, buffer, dp,
+ timeQual, 0, (ScanKey) NULL);
+
+ if (tuple == NULL)
{
- ReleaseBuffer(buffer);
- return (NULL);
+ ReleaseBuffer(buffer);
+ return (NULL);
}
-
- /* ----------------
- * all checks passed, now either return a copy of the tuple
- * or pin the buffer page and return a pointer, depending on
- * whether caller gave us a valid b.
- * ----------------
- */
-
- if (PointerIsValid(b)) {
- *b = buffer;
- } else {
- tuple = heap_copytuple(tuple);
- ReleaseBuffer(buffer);
- }
- return (tuple);
+
+ /* ----------------
+ * all checks passed, now either return a copy of the tuple
+ * or pin the buffer page and return a pointer, depending on
+ * whether caller gave us a valid b.
+ * ----------------
+ */
+
+ if (PointerIsValid(b))
+ {
+ *b = buffer;
+ }
+ else
+ {
+ tuple = heap_copytuple(tuple);
+ ReleaseBuffer(buffer);
+ }
+ return (tuple);
}
/* ----------------
- * heap_insert - insert tuple
+ * heap_insert - insert tuple
*
- * The assignment of t_min (and thus the others) should be
- * removed eventually.
+ * The assignment of t_min (and thus the others) should be
+ * removed eventually.
*
- * Currently places the tuple onto the last page. If there is no room,
- * it is placed on new pages. (Heap relations)
- * Note that concurrent inserts during a scan will probably have
- * unexpected results, though this will be fixed eventually.
+ * Currently places the tuple onto the last page. If there is no room,
+ * it is placed on new pages. (Heap relations)
+ * Note that concurrent inserts during a scan will probably have
+ * unexpected results, though this will be fixed eventually.
*
- * Fix to work with indexes.
+ * Fix to work with indexes.
* ----------------
*/
Oid
heap_insert(Relation relation, HeapTuple tup)
{
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_insert);
- IncrHeapAccessStat(global_insert);
-
- /* ----------------
- * set relation level write lock. If this is a "local" relation (not
- * visible to others), we don't need to set a write lock.
- * ----------------
- */
- if (!relation->rd_islocal)
- RelationSetLockForWrite(relation);
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_insert);
+ IncrHeapAccessStat(global_insert);
- /* ----------------
- * If the object id of this tuple has already been assigned, trust
- * the caller. There are a couple of ways this can happen. At initial
- * db creation, the backend program sets oids for tuples. When we
- * define an index, we set the oid. Finally, in the future, we may
- * allow users to set their own object ids in order to support a
- * persistent object store (objects need to contain pointers to one
- * another).
- * ----------------
- */
- if (!OidIsValid(tup->t_oid)) {
- tup->t_oid = newoid();
- LastOidProcessed = tup->t_oid;
- }
- else
- CheckMaxObjectId(tup->t_oid);
-
- TransactionIdStore(GetCurrentTransactionId(), &(tup->t_xmin));
- tup->t_cmin = GetCurrentCommandId();
- StoreInvalidTransactionId(&(tup->t_xmax));
- tup->t_tmin = INVALID_ABSTIME;
- tup->t_tmax = CURRENT_ABSTIME;
-
- doinsert(relation, tup);
-
- if ( IsSystemRelationName(RelationGetRelationName(relation)->data)) {
- RelationUnsetLockForWrite(relation);
-
/* ----------------
- * invalidate caches (only works for system relations)
+ * set relation level write lock. If this is a "local" relation (not
+ * visible to others), we don't need to set a write lock.
* ----------------
*/
- SetRefreshWhenInvalidate(ImmediateInvalidation);
- RelationInvalidateHeapTuple(relation, tup);
- SetRefreshWhenInvalidate((bool)!ImmediateInvalidation);
- }
-
- return(tup->t_oid);
+ if (!relation->rd_islocal)
+ RelationSetLockForWrite(relation);
+
+ /* ----------------
+ * If the object id of this tuple has already been assigned, trust
+ * the caller. There are a couple of ways this can happen. At initial
+ * db creation, the backend program sets oids for tuples. When we
+ * define an index, we set the oid. Finally, in the future, we may
+ * allow users to set their own object ids in order to support a
+ * persistent object store (objects need to contain pointers to one
+ * another).
+ * ----------------
+ */
+ if (!OidIsValid(tup->t_oid))
+ {
+ tup->t_oid = newoid();
+ LastOidProcessed = tup->t_oid;
+ }
+ else
+ CheckMaxObjectId(tup->t_oid);
+
+ TransactionIdStore(GetCurrentTransactionId(), &(tup->t_xmin));
+ tup->t_cmin = GetCurrentCommandId();
+ StoreInvalidTransactionId(&(tup->t_xmax));
+ tup->t_tmin = INVALID_ABSTIME;
+ tup->t_tmax = CURRENT_ABSTIME;
+
+ doinsert(relation, tup);
+
+ if (IsSystemRelationName(RelationGetRelationName(relation)->data))
+ {
+ RelationUnsetLockForWrite(relation);
+
+ /* ----------------
+ * invalidate caches (only works for system relations)
+ * ----------------
+ */
+ SetRefreshWhenInvalidate(ImmediateInvalidation);
+ RelationInvalidateHeapTuple(relation, tup);
+ SetRefreshWhenInvalidate((bool) ! ImmediateInvalidation);
+ }
+
+ return (tup->t_oid);
}
/* ----------------
- * heap_delete - delete a tuple
+ * heap_delete - delete a tuple
*
- * Must decide how to handle errors.
+ * Must decide how to handle errors.
* ----------------
*/
int
heap_delete(Relation relation, ItemPointer tid)
{
- ItemId lp;
- HeapTuple tp;
- PageHeader dp;
- Buffer b;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_delete);
- IncrHeapAccessStat(global_delete);
-
- /* ----------------
- * sanity check
- * ----------------
- */
- Assert(ItemPointerIsValid(tid));
-
- /* ----------------
- * set relation level write lock
- * ----------------
- */
- RelationSetLockForWrite(relation);
-
- b = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
-
+ ItemId lp;
+ HeapTuple tp;
+ PageHeader dp;
+ Buffer b;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_delete);
+ IncrHeapAccessStat(global_delete);
+
+ /* ----------------
+ * sanity check
+ * ----------------
+ */
+ Assert(ItemPointerIsValid(tid));
+
+ /* ----------------
+ * set relation level write lock
+ * ----------------
+ */
+ RelationSetLockForWrite(relation);
+
+ b = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
+
#ifndef NO_BUFFERISVALID
- if (!BufferIsValid(b)) { /* XXX L_SH better ??? */
- elog(WARN, "heap_delete: failed ReadBuffer");
- }
-#endif /* NO_BUFFERISVALID */
-
- dp = (PageHeader) BufferGetPage(b);
- lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
-
- /*
- * Just like test against non-functional updates we try to catch
- * non-functional delete attempts. - vadim 05/05/97
- */
- tp = (HeapTuple) PageGetItem((Page)dp, lp);
- Assert(HeapTupleIsValid(tp));
- if (TupleUpdatedByCurXactAndCmd(tp)) {
- elog(NOTICE, "Non-functional delete, tuple already deleted");
- if ( IsSystemRelationName(RelationGetRelationName(relation)->data) )
- RelationUnsetLockForWrite(relation);
- ReleaseBuffer(b);
- return (1);
- }
- /* ----------------
- * check that we're deleteing a valid item
- * ----------------
- */
- if (!(tp = heap_tuple_satisfies(lp, relation, b, dp,
- NowTimeQual, 0, (ScanKey) NULL))) {
-
- /* XXX call something else */
- ReleaseBuffer(b);
-
- elog(WARN, "heap_delete: (am)invalid tid");
- }
-
- /* ----------------
- * get the tuple and lock tell the buffer manager we want
- * exclusive access to the page
- * ----------------
- */
-
- /* ----------------
- * store transaction information of xact deleting the tuple
- * ----------------
- */
- TransactionIdStore(GetCurrentTransactionId(), &(tp->t_xmax));
- tp->t_cmax = GetCurrentCommandId();
- ItemPointerSetInvalid(&tp->t_chain);
-
- /* ----------------
- * invalidate caches
- * ----------------
- */
- SetRefreshWhenInvalidate(ImmediateInvalidation);
- RelationInvalidateHeapTuple(relation, tp);
- SetRefreshWhenInvalidate((bool)!ImmediateInvalidation);
-
- WriteBuffer(b);
- if ( IsSystemRelationName(RelationGetRelationName(relation)->data) )
- RelationUnsetLockForWrite(relation);
-
- return(0);
+ if (!BufferIsValid(b))
+ { /* XXX L_SH better ??? */
+ elog(WARN, "heap_delete: failed ReadBuffer");
+ }
+#endif /* NO_BUFFERISVALID */
+
+ dp = (PageHeader) BufferGetPage(b);
+ lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
+
+ /*
+ * Just like test against non-functional updates we try to catch
+ * non-functional delete attempts. - vadim 05/05/97
+ */
+ tp = (HeapTuple) PageGetItem((Page) dp, lp);
+ Assert(HeapTupleIsValid(tp));
+ if (TupleUpdatedByCurXactAndCmd(tp))
+ {
+ elog(NOTICE, "Non-functional delete, tuple already deleted");
+ if (IsSystemRelationName(RelationGetRelationName(relation)->data))
+ RelationUnsetLockForWrite(relation);
+ ReleaseBuffer(b);
+ return (1);
+ }
+ /* ----------------
+ * check that we're deleteing a valid item
+ * ----------------
+ */
+ if (!(tp = heap_tuple_satisfies(lp, relation, b, dp,
+ NowTimeQual, 0, (ScanKey) NULL)))
+ {
+
+ /* XXX call something else */
+ ReleaseBuffer(b);
+
+ elog(WARN, "heap_delete: (am)invalid tid");
+ }
+
+ /* ----------------
+ * get the tuple and lock tell the buffer manager we want
+ * exclusive access to the page
+ * ----------------
+ */
+
+ /* ----------------
+ * store transaction information of xact deleting the tuple
+ * ----------------
+ */
+ TransactionIdStore(GetCurrentTransactionId(), &(tp->t_xmax));
+ tp->t_cmax = GetCurrentCommandId();
+ ItemPointerSetInvalid(&tp->t_chain);
+
+ /* ----------------
+ * invalidate caches
+ * ----------------
+ */
+ SetRefreshWhenInvalidate(ImmediateInvalidation);
+ RelationInvalidateHeapTuple(relation, tp);
+ SetRefreshWhenInvalidate((bool) ! ImmediateInvalidation);
+
+ WriteBuffer(b);
+ if (IsSystemRelationName(RelationGetRelationName(relation)->data))
+ RelationUnsetLockForWrite(relation);
+
+ return (0);
}
/* ----------------
- * heap_replace - replace a tuple
+ * heap_replace - replace a tuple
+ *
+ * Must decide how to handle errors.
*
- * Must decide how to handle errors.
+ * Fix arguments, work with indexes.
*
- * Fix arguments, work with indexes.
- *
- * 12/30/93 - modified the return value to be 1 when
- * a non-functional update is detected. This
- * prevents the calling routine from updating
- * indices unnecessarily. -kw
+ * 12/30/93 - modified the return value to be 1 when
+ * a non-functional update is detected. This
+ * prevents the calling routine from updating
+ * indices unnecessarily. -kw
*
* ----------------
*/
int
heap_replace(Relation relation, ItemPointer otid, HeapTuple tup)
{
- ItemId lp;
- HeapTuple tp;
- Page dp;
- Buffer buffer;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_replace);
- IncrHeapAccessStat(global_replace);
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(ItemPointerIsValid(otid));
-
- /* ----------------
- * set relation level write lock
- * ----------------
- */
- if (!relation->rd_islocal)
- RelationSetLockForWrite(relation);
-
- buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
+ ItemId lp;
+ HeapTuple tp;
+ Page dp;
+ Buffer buffer;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_replace);
+ IncrHeapAccessStat(global_replace);
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(ItemPointerIsValid(otid));
+
+ /* ----------------
+ * set relation level write lock
+ * ----------------
+ */
+ if (!relation->rd_islocal)
+ RelationSetLockForWrite(relation);
+
+ buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
#ifndef NO_BUFFERISVALID
- if (!BufferIsValid(buffer)) {
- /* XXX L_SH better ??? */
- elog(WARN, "amreplace: failed ReadBuffer");
- }
-#endif /* NO_BUFFERISVALID */
-
- dp = (Page) BufferGetPage(buffer);
- lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(otid));
-
- /* ----------------
- * logically delete old item
- * ----------------
- */
-
- tp = (HeapTuple) PageGetItem(dp, lp);
- Assert(HeapTupleIsValid(tp));
-
- /* -----------------
- * the following test should be able to catch all non-functional
- * update attempts and shut out all ghost tuples.
- * XXX In the future, Spyros may need to update the rule lock on a tuple
- * more than once within the same command and same transaction.
- * He will have to introduce a new flag to override the following check.
- * -- Wei
- *
- * -----------------
- */
-
- if (TupleUpdatedByCurXactAndCmd(tp)) {
- elog(NOTICE, "Non-functional update, only first update is performed");
- if ( IsSystemRelationName(RelationGetRelationName(relation)->data) )
- RelationUnsetLockForWrite(relation);
- ReleaseBuffer(buffer);
- return(1);
- }
-
- /* ----------------
- * check that we're replacing a valid item -
- *
- * NOTE that this check must follow the non-functional update test
- * above as it can happen that we try to 'replace' the same tuple
- * twice in a single transaction. The second time around the
- * tuple will fail the NowTimeQual. We don't want to abort the
- * xact, we only want to flag the 'non-functional' NOTICE. -mer
- * ----------------
- */
- if (!heap_tuple_satisfies(lp,
- relation,
- buffer,
- (PageHeader)dp,
- NowTimeQual,
- 0,
- (ScanKey)NULL))
- {
- ReleaseBuffer(buffer);
- elog(WARN, "heap_replace: (am)invalid otid");
- }
-
- /* XXX order problems if not atomic assignment ??? */
- tup->t_oid = tp->t_oid;
- TransactionIdStore(GetCurrentTransactionId(), &(tup->t_xmin));
- tup->t_cmin = GetCurrentCommandId();
- StoreInvalidTransactionId(&(tup->t_xmax));
- tup->t_tmin = INVALID_ABSTIME;
- tup->t_tmax = CURRENT_ABSTIME;
- ItemPointerSetInvalid(&tup->t_chain);
-
- /* ----------------
- * insert new item
- * ----------------
- */
- if ((unsigned)DOUBLEALIGN(tup->t_len) <= PageGetFreeSpace((Page) dp)) {
- RelationPutHeapTuple(relation, BufferGetBlockNumber(buffer), tup);
- } else {
+ if (!BufferIsValid(buffer))
+ {
+ /* XXX L_SH better ??? */
+ elog(WARN, "amreplace: failed ReadBuffer");
+ }
+#endif /* NO_BUFFERISVALID */
+
+ dp = (Page) BufferGetPage(buffer);
+ lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(otid));
+
/* ----------------
- * new item won't fit on same page as old item, have to look
- * for a new place to put it.
+ * logically delete old item
* ----------------
*/
- doinsert(relation, tup);
- }
-
- /* ----------------
- * new item in place, now record transaction information
- * ----------------
- */
- TransactionIdStore(GetCurrentTransactionId(), &(tp->t_xmax));
- tp->t_cmax = GetCurrentCommandId();
- tp->t_chain = tup->t_ctid;
-
- /* ----------------
- * invalidate caches
- * ----------------
- */
- SetRefreshWhenInvalidate(ImmediateInvalidation);
- RelationInvalidateHeapTuple(relation, tp);
- SetRefreshWhenInvalidate((bool)!ImmediateInvalidation);
-
- WriteBuffer(buffer);
-
- if ( IsSystemRelationName(RelationGetRelationName(relation)->data) )
- RelationUnsetLockForWrite(relation);
-
- return(0);
+
+ tp = (HeapTuple) PageGetItem(dp, lp);
+ Assert(HeapTupleIsValid(tp));
+
+ /* -----------------
+ * the following test should be able to catch all non-functional
+ * update attempts and shut out all ghost tuples.
+ * XXX In the future, Spyros may need to update the rule lock on a tuple
+ * more than once within the same command and same transaction.
+ * He will have to introduce a new flag to override the following check.
+ * -- Wei
+ *
+ * -----------------
+ */
+
+ if (TupleUpdatedByCurXactAndCmd(tp))
+ {
+ elog(NOTICE, "Non-functional update, only first update is performed");
+ if (IsSystemRelationName(RelationGetRelationName(relation)->data))
+ RelationUnsetLockForWrite(relation);
+ ReleaseBuffer(buffer);
+ return (1);
+ }
+
+ /* ----------------
+ * check that we're replacing a valid item -
+ *
+ * NOTE that this check must follow the non-functional update test
+ * above as it can happen that we try to 'replace' the same tuple
+ * twice in a single transaction. The second time around the
+ * tuple will fail the NowTimeQual. We don't want to abort the
+ * xact, we only want to flag the 'non-functional' NOTICE. -mer
+ * ----------------
+ */
+ if (!heap_tuple_satisfies(lp,
+ relation,
+ buffer,
+ (PageHeader) dp,
+ NowTimeQual,
+ 0,
+ (ScanKey) NULL))
+ {
+ ReleaseBuffer(buffer);
+ elog(WARN, "heap_replace: (am)invalid otid");
+ }
+
+ /* XXX order problems if not atomic assignment ??? */
+ tup->t_oid = tp->t_oid;
+ TransactionIdStore(GetCurrentTransactionId(), &(tup->t_xmin));
+ tup->t_cmin = GetCurrentCommandId();
+ StoreInvalidTransactionId(&(tup->t_xmax));
+ tup->t_tmin = INVALID_ABSTIME;
+ tup->t_tmax = CURRENT_ABSTIME;
+ ItemPointerSetInvalid(&tup->t_chain);
+
+ /* ----------------
+ * insert new item
+ * ----------------
+ */
+ if ((unsigned) DOUBLEALIGN(tup->t_len) <= PageGetFreeSpace((Page) dp))
+ {
+ RelationPutHeapTuple(relation, BufferGetBlockNumber(buffer), tup);
+ }
+ else
+ {
+ /* ----------------
+ * new item won't fit on same page as old item, have to look
+ * for a new place to put it.
+ * ----------------
+ */
+ doinsert(relation, tup);
+ }
+
+ /* ----------------
+ * new item in place, now record transaction information
+ * ----------------
+ */
+ TransactionIdStore(GetCurrentTransactionId(), &(tp->t_xmax));
+ tp->t_cmax = GetCurrentCommandId();
+ tp->t_chain = tup->t_ctid;
+
+ /* ----------------
+ * invalidate caches
+ * ----------------
+ */
+ SetRefreshWhenInvalidate(ImmediateInvalidation);
+ RelationInvalidateHeapTuple(relation, tp);
+ SetRefreshWhenInvalidate((bool) ! ImmediateInvalidation);
+
+ WriteBuffer(buffer);
+
+ if (IsSystemRelationName(RelationGetRelationName(relation)->data))
+ RelationUnsetLockForWrite(relation);
+
+ return (0);
}
/* ----------------
- * heap_markpos - mark scan position
+ * heap_markpos - mark scan position
*
- * Note:
- * Should only one mark be maintained per scan at one time.
- * Check if this can be done generally--say calls to get the
- * next/previous tuple and NEVER pass struct scandesc to the
- * user AM's. Now, the mark is sent to the executor for safekeeping.
- * Probably can store this info into a GENERAL scan structure.
+ * Note:
+ * Should only one mark be maintained per scan at one time.
+ * Check if this can be done generally--say calls to get the
+ * next/previous tuple and NEVER pass struct scandesc to the
+ * user AM's. Now, the mark is sent to the executor for safekeeping.
+ * Probably can store this info into a GENERAL scan structure.
*
- * May be best to change this call to store the marked position
- * (up to 2?) in the scan structure itself.
- * Fix to use the proper caching structure.
+ * May be best to change this call to store the marked position
+ * (up to 2?) in the scan structure itself.
+ * Fix to use the proper caching structure.
* ----------------
*/
void
heap_markpos(HeapScanDesc sdesc)
{
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_markpos);
- IncrHeapAccessStat(global_markpos);
-
- /* Note: no locking manipulations needed */
-
- if (sdesc->rs_ptup == NULL &&
- BufferIsUnknown(sdesc->rs_pbuf)) { /* == NONTUP */
- sdesc->rs_ptup = (HeapTuple)
- heapgettup(sdesc->rs_rd,
- (sdesc->rs_ctup == NULL) ?
- (ItemPointer)NULL : &sdesc->rs_ctup->t_ctid,
- -1,
- &sdesc->rs_pbuf,
- sdesc->rs_tr,
- sdesc->rs_nkeys,
- sdesc->rs_key);
-
- } else if (sdesc->rs_ntup == NULL &&
- BufferIsUnknown(sdesc->rs_nbuf)) { /* == NONTUP */
- sdesc->rs_ntup = (HeapTuple)
- heapgettup(sdesc->rs_rd,
- (sdesc->rs_ctup == NULL) ?
- (ItemPointer)NULL : &sdesc->rs_ctup->t_ctid,
- 1,
- &sdesc->rs_nbuf,
- sdesc->rs_tr,
- sdesc->rs_nkeys,
- sdesc->rs_key);
- }
-
- /* ----------------
- * Should not unpin the buffer pages. They may still be in use.
- * ----------------
- */
- if (sdesc->rs_ptup != NULL) {
- sdesc->rs_mptid = sdesc->rs_ptup->t_ctid;
- } else {
- ItemPointerSetInvalid(&sdesc->rs_mptid);
- }
- if (sdesc->rs_ctup != NULL) {
- sdesc->rs_mctid = sdesc->rs_ctup->t_ctid;
- } else {
- ItemPointerSetInvalid(&sdesc->rs_mctid);
- }
- if (sdesc->rs_ntup != NULL) {
- sdesc->rs_mntid = sdesc->rs_ntup->t_ctid;
- } else {
- ItemPointerSetInvalid(&sdesc->rs_mntid);
- }
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_markpos);
+ IncrHeapAccessStat(global_markpos);
+
+ /* Note: no locking manipulations needed */
+
+ if (sdesc->rs_ptup == NULL &&
+ BufferIsUnknown(sdesc->rs_pbuf))
+ { /* == NONTUP */
+ sdesc->rs_ptup = (HeapTuple)
+ heapgettup(sdesc->rs_rd,
+ (sdesc->rs_ctup == NULL) ?
+ (ItemPointer) NULL : &sdesc->rs_ctup->t_ctid,
+ -1,
+ &sdesc->rs_pbuf,
+ sdesc->rs_tr,
+ sdesc->rs_nkeys,
+ sdesc->rs_key);
+
+ }
+ else if (sdesc->rs_ntup == NULL &&
+ BufferIsUnknown(sdesc->rs_nbuf))
+ { /* == NONTUP */
+ sdesc->rs_ntup = (HeapTuple)
+ heapgettup(sdesc->rs_rd,
+ (sdesc->rs_ctup == NULL) ?
+ (ItemPointer) NULL : &sdesc->rs_ctup->t_ctid,
+ 1,
+ &sdesc->rs_nbuf,
+ sdesc->rs_tr,
+ sdesc->rs_nkeys,
+ sdesc->rs_key);
+ }
+
+ /* ----------------
+ * Should not unpin the buffer pages. They may still be in use.
+ * ----------------
+ */
+ if (sdesc->rs_ptup != NULL)
+ {
+ sdesc->rs_mptid = sdesc->rs_ptup->t_ctid;
+ }
+ else
+ {
+ ItemPointerSetInvalid(&sdesc->rs_mptid);
+ }
+ if (sdesc->rs_ctup != NULL)
+ {
+ sdesc->rs_mctid = sdesc->rs_ctup->t_ctid;
+ }
+ else
+ {
+ ItemPointerSetInvalid(&sdesc->rs_mctid);
+ }
+ if (sdesc->rs_ntup != NULL)
+ {
+ sdesc->rs_mntid = sdesc->rs_ntup->t_ctid;
+ }
+ else
+ {
+ ItemPointerSetInvalid(&sdesc->rs_mntid);
+ }
}
/* ----------------
- * heap_restrpos - restore position to marked location
+ * heap_restrpos - restore position to marked location
*
- * Note: there are bad side effects here. If we were past the end
- * of a relation when heapmarkpos is called, then if the relation is
- * extended via insert, then the next call to heaprestrpos will set
- * cause the added tuples to be visible when the scan continues.
- * Problems also arise if the TID's are rearranged!!!
+ * Note: there are bad side effects here. If we were past the end
+ * of a relation when heapmarkpos is called, then if the relation is
+ * extended via insert, then the next call to heaprestrpos will set
+ * cause the added tuples to be visible when the scan continues.
+ * Problems also arise if the TID's are rearranged!!!
*
- * Now pins buffer once for each valid tuple pointer (rs_ptup,
- * rs_ctup, rs_ntup) referencing it.
- * - 01/13/94
+ * Now pins buffer once for each valid tuple pointer (rs_ptup,
+ * rs_ctup, rs_ntup) referencing it.
+ * - 01/13/94
*
* XXX might be better to do direct access instead of
- * using the generality of heapgettup().
+ * using the generality of heapgettup().
*
* XXX It is very possible that when a scan is restored, that a tuple
* XXX which previously qualified may fail for time range purposes, unless
@@ -1455,60 +1561,69 @@ heap_markpos(HeapScanDesc sdesc)
void
heap_restrpos(HeapScanDesc sdesc)
{
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_restrpos);
- IncrHeapAccessStat(global_restrpos);
-
- /* XXX no amrestrpos checking that ammarkpos called */
-
- /* Note: no locking manipulations needed */
-
- unpinsdesc(sdesc);
-
- /* force heapgettup to pin buffer for each loaded tuple */
- sdesc->rs_pbuf = InvalidBuffer;
- sdesc->rs_cbuf = InvalidBuffer;
- sdesc->rs_nbuf = InvalidBuffer;
-
- if (!ItemPointerIsValid(&sdesc->rs_mptid)) {
- sdesc->rs_ptup = NULL;
- } else {
- sdesc->rs_ptup = (HeapTuple)
- heapgettup(sdesc->rs_rd,
- &sdesc->rs_mptid,
- 0,
- &sdesc->rs_pbuf,
- NowTimeQual,
- 0,
- (ScanKey) NULL);
- }
-
- if (!ItemPointerIsValid(&sdesc->rs_mctid)) {
- sdesc->rs_ctup = NULL;
- } else {
- sdesc->rs_ctup = (HeapTuple)
- heapgettup(sdesc->rs_rd,
- &sdesc->rs_mctid,
- 0,
- &sdesc->rs_cbuf,
- NowTimeQual,
- 0,
- (ScanKey) NULL);
- }
-
- if (!ItemPointerIsValid(&sdesc->rs_mntid)) {
- sdesc->rs_ntup = NULL;
- } else {
- sdesc->rs_ntup = (HeapTuple)
- heapgettup(sdesc->rs_rd,
- &sdesc->rs_mntid,
- 0,
- &sdesc->rs_nbuf,
- NowTimeQual,
- 0,
- (ScanKey) NULL);
- }
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_restrpos);
+ IncrHeapAccessStat(global_restrpos);
+
+ /* XXX no amrestrpos checking that ammarkpos called */
+
+ /* Note: no locking manipulations needed */
+
+ unpinsdesc(sdesc);
+
+ /* force heapgettup to pin buffer for each loaded tuple */
+ sdesc->rs_pbuf = InvalidBuffer;
+ sdesc->rs_cbuf = InvalidBuffer;
+ sdesc->rs_nbuf = InvalidBuffer;
+
+ if (!ItemPointerIsValid(&sdesc->rs_mptid))
+ {
+ sdesc->rs_ptup = NULL;
+ }
+ else
+ {
+ sdesc->rs_ptup = (HeapTuple)
+ heapgettup(sdesc->rs_rd,
+ &sdesc->rs_mptid,
+ 0,
+ &sdesc->rs_pbuf,
+ NowTimeQual,
+ 0,
+ (ScanKey) NULL);
+ }
+
+ if (!ItemPointerIsValid(&sdesc->rs_mctid))
+ {
+ sdesc->rs_ctup = NULL;
+ }
+ else
+ {
+ sdesc->rs_ctup = (HeapTuple)
+ heapgettup(sdesc->rs_rd,
+ &sdesc->rs_mctid,
+ 0,
+ &sdesc->rs_cbuf,
+ NowTimeQual,
+ 0,
+ (ScanKey) NULL);
+ }
+
+ if (!ItemPointerIsValid(&sdesc->rs_mntid))
+ {
+ sdesc->rs_ntup = NULL;
+ }
+ else
+ {
+ sdesc->rs_ntup = (HeapTuple)
+ heapgettup(sdesc->rs_rd,
+ &sdesc->rs_mntid,
+ 0,
+ &sdesc->rs_nbuf,
+ NowTimeQual,
+ 0,
+ (ScanKey) NULL);
+ }
}
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index f172a404708..0854b69bf0b 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* hio.c--
- * POSTGRES heap access method input/output code.
+ * POSTGRES heap access method input/output code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Id: hio.c,v 1.9 1996/11/05 09:53:02 scrappy Exp $
+ * $Id: hio.c,v 1.10 1997/09/07 04:38:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,64 +21,65 @@
/*
* amputunique - place tuple at tid
- * Currently on errors, calls elog. Perhaps should return -1?
- * Possible errors include the addition of a tuple to the page
- * between the time the linep is chosen and the page is L_UP'd.
+ * Currently on errors, calls elog. Perhaps should return -1?
+ * Possible errors include the addition of a tuple to the page
+ * between the time the linep is chosen and the page is L_UP'd.
*
- * This should be coordinated with the B-tree code.
- * Probably needs to have an amdelunique to allow for
- * internal index records to be deleted and reordered as needed.
- * For the heap AM, this should never be needed.
+ * This should be coordinated with the B-tree code.
+ * Probably needs to have an amdelunique to allow for
+ * internal index records to be deleted and reordered as needed.
+ * For the heap AM, this should never be needed.
*/
void
RelationPutHeapTuple(Relation relation,
- BlockNumber blockIndex,
- HeapTuple tuple)
+ BlockNumber blockIndex,
+ HeapTuple tuple)
{
- Buffer buffer;
- Page pageHeader;
- BlockNumber numberOfBlocks;
- OffsetNumber offnum;
- unsigned int len;
- ItemId itemId;
- Item item;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_RelationPutHeapTuple);
- IncrHeapAccessStat(global_RelationPutHeapTuple);
-
- Assert(RelationIsValid(relation));
- Assert(HeapTupleIsValid(tuple));
-
- numberOfBlocks = RelationGetNumberOfBlocks(relation);
- Assert(blockIndex < numberOfBlocks);
-
- buffer = ReadBuffer(relation, blockIndex);
+ Buffer buffer;
+ Page pageHeader;
+ BlockNumber numberOfBlocks;
+ OffsetNumber offnum;
+ unsigned int len;
+ ItemId itemId;
+ Item item;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_RelationPutHeapTuple);
+ IncrHeapAccessStat(global_RelationPutHeapTuple);
+
+ Assert(RelationIsValid(relation));
+ Assert(HeapTupleIsValid(tuple));
+
+ numberOfBlocks = RelationGetNumberOfBlocks(relation);
+ Assert(blockIndex < numberOfBlocks);
+
+ buffer = ReadBuffer(relation, blockIndex);
#ifndef NO_BUFFERISVALID
- if (!BufferIsValid(buffer)) {
- elog(WARN, "RelationPutHeapTuple: no buffer for %ld in %s",
- blockIndex, &relation->rd_rel->relname);
- }
+ if (!BufferIsValid(buffer))
+ {
+ elog(WARN, "RelationPutHeapTuple: no buffer for %ld in %s",
+ blockIndex, &relation->rd_rel->relname);
+ }
#endif
-
- pageHeader = (Page)BufferGetPage(buffer);
- len = (unsigned)DOUBLEALIGN(tuple->t_len); /* be conservative */
- Assert((int)len <= PageGetFreeSpace(pageHeader));
-
- offnum = PageAddItem((Page)pageHeader, (Item)tuple,
- tuple->t_len, InvalidOffsetNumber, LP_USED);
-
- itemId = PageGetItemId((Page)pageHeader, offnum);
- item = PageGetItem((Page)pageHeader, itemId);
-
- ItemPointerSet(&((HeapTuple)item)->t_ctid, blockIndex, offnum);
-
- WriteBuffer(buffer);
- /* return an accurate tuple */
- ItemPointerSet(&tuple->t_ctid, blockIndex, offnum);
+
+ pageHeader = (Page) BufferGetPage(buffer);
+ len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */
+ Assert((int) len <= PageGetFreeSpace(pageHeader));
+
+ offnum = PageAddItem((Page) pageHeader, (Item) tuple,
+ tuple->t_len, InvalidOffsetNumber, LP_USED);
+
+ itemId = PageGetItemId((Page) pageHeader, offnum);
+ item = PageGetItem((Page) pageHeader, itemId);
+
+ ItemPointerSet(&((HeapTuple) item)->t_ctid, blockIndex, offnum);
+
+ WriteBuffer(buffer);
+ /* return an accurate tuple */
+ ItemPointerSet(&tuple->t_ctid, blockIndex, offnum);
}
/*
@@ -91,7 +92,7 @@ RelationPutHeapTuple(Relation relation,
* Eventually, we should cache the number of blocks in a relation somewhere.
* Until that time, this code will have to do an lseek to determine the number
* of blocks in a relation.
- *
+ *
* This code should ideally do at most 4 semops, 1 lseek, and possibly 1 write
* to do an append; it's possible to eliminate 2 of the semops if we do direct
* buffer stuff (!); the lseek and the write can go if we get
@@ -107,70 +108,70 @@ RelationPutHeapTuple(Relation relation,
void
RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
{
- Buffer buffer;
- Page pageHeader;
- BlockNumber lastblock;
- OffsetNumber offnum;
- unsigned int len;
- ItemId itemId;
- Item item;
-
- Assert(RelationIsValid(relation));
- Assert(HeapTupleIsValid(tuple));
-
- /*
- * XXX This does an lseek - VERY expensive - but at the moment it
- * is the only way to accurately determine how many blocks are in
- * a relation. A good optimization would be to get this to actually
- * work properly.
- */
-
- lastblock = RelationGetNumberOfBlocks(relation);
-
- if (lastblock == 0)
+ Buffer buffer;
+ Page pageHeader;
+ BlockNumber lastblock;
+ OffsetNumber offnum;
+ unsigned int len;
+ ItemId itemId;
+ Item item;
+
+ Assert(RelationIsValid(relation));
+ Assert(HeapTupleIsValid(tuple));
+
+ /*
+ * XXX This does an lseek - VERY expensive - but at the moment it is
+ * the only way to accurately determine how many blocks are in a
+ * relation. A good optimization would be to get this to actually
+ * work properly.
+ */
+
+ lastblock = RelationGetNumberOfBlocks(relation);
+
+ if (lastblock == 0)
{
- buffer = ReadBuffer(relation, lastblock);
- pageHeader = (Page)BufferGetPage(buffer);
- if (PageIsNew((PageHeader) pageHeader))
+ buffer = ReadBuffer(relation, lastblock);
+ pageHeader = (Page) BufferGetPage(buffer);
+ if (PageIsNew((PageHeader) pageHeader))
{
- buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
- pageHeader = (Page)BufferGetPage(buffer);
- PageInit(pageHeader, BufferGetPageSize(buffer), 0);
+ buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
+ pageHeader = (Page) BufferGetPage(buffer);
+ PageInit(pageHeader, BufferGetPageSize(buffer), 0);
}
}
- else
- buffer = ReadBuffer(relation, lastblock - 1);
-
- pageHeader = (Page)BufferGetPage(buffer);
- len = (unsigned)DOUBLEALIGN(tuple->t_len); /* be conservative */
-
- /*
- * Note that this is true if the above returned a bogus page, which
- * it will do for a completely empty relation.
- */
-
- if (len > PageGetFreeSpace(pageHeader))
+ else
+ buffer = ReadBuffer(relation, lastblock - 1);
+
+ pageHeader = (Page) BufferGetPage(buffer);
+ len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */
+
+ /*
+ * Note that this is true if the above returned a bogus page, which it
+ * will do for a completely empty relation.
+ */
+
+ if (len > PageGetFreeSpace(pageHeader))
{
- buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
- pageHeader = (Page)BufferGetPage(buffer);
- PageInit(pageHeader, BufferGetPageSize(buffer), 0);
-
- if (len > PageGetFreeSpace(pageHeader))
- elog(WARN, "Tuple is too big: size %d", len);
+ buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
+ pageHeader = (Page) BufferGetPage(buffer);
+ PageInit(pageHeader, BufferGetPageSize(buffer), 0);
+
+ if (len > PageGetFreeSpace(pageHeader))
+ elog(WARN, "Tuple is too big: size %d", len);
}
-
- offnum = PageAddItem((Page)pageHeader, (Item)tuple,
- tuple->t_len, InvalidOffsetNumber, LP_USED);
-
- itemId = PageGetItemId((Page)pageHeader, offnum);
- item = PageGetItem((Page)pageHeader, itemId);
-
- lastblock = BufferGetBlockNumber(buffer);
-
- ItemPointerSet(&((HeapTuple)item)->t_ctid, lastblock, offnum);
-
- /* return an accurate tuple */
- ItemPointerSet(&tuple->t_ctid, lastblock, offnum);
-
- WriteBuffer(buffer);
+
+ offnum = PageAddItem((Page) pageHeader, (Item) tuple,
+ tuple->t_len, InvalidOffsetNumber, LP_USED);
+
+ itemId = PageGetItemId((Page) pageHeader, offnum);
+ item = PageGetItem((Page) pageHeader, itemId);
+
+ lastblock = BufferGetBlockNumber(buffer);
+
+ ItemPointerSet(&((HeapTuple) item)->t_ctid, lastblock, offnum);
+
+ /* return an accurate tuple */
+ ItemPointerSet(&tuple->t_ctid, lastblock, offnum);
+
+ WriteBuffer(buffer);
}
diff --git a/src/backend/access/heap/stats.c b/src/backend/access/heap/stats.c
index ae8273ac81c..aa16803779c 100644
--- a/src/backend/access/heap/stats.c
+++ b/src/backend/access/heap/stats.c
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* stats.c--
- * heap access method debugging statistic collection routines
+ * heap access method debugging statistic collection routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.11 1997/08/19 21:29:21 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.12 1997/09/07 04:38:13 momjian Exp $
*
* NOTES
- * initam should be moved someplace else.
+ * initam should be moved someplace else.
*
*-------------------------------------------------------------------------
*/
@@ -23,322 +23,327 @@
#include <utils/mcxt.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static void InitHeapAccessStatistics(void);
+static void InitHeapAccessStatistics(void);
/* ----------------
- * InitHeapAccessStatistics
+ * InitHeapAccessStatistics
* ----------------
*/
HeapAccessStatistics heap_access_stats = (HeapAccessStatistics) NULL;
-
+
static void
-InitHeapAccessStatistics()
+InitHeapAccessStatistics()
{
- MemoryContext oldContext;
- HeapAccessStatistics stats;
-
- /* ----------------
- * make sure we don't initialize things twice
- * ----------------
- */
- if (heap_access_stats != NULL)
- return;
-
- /* ----------------
- * allocate statistics structure from the top memory context
- * ----------------
- */
- oldContext = MemoryContextSwitchTo(TopMemoryContext);
-
- stats = (HeapAccessStatistics)
- palloc(sizeof(HeapAccessStatisticsData));
-
- /* ----------------
- * initialize fields to default values
- * ----------------
- */
- stats->global_open = 0;
- stats->global_openr = 0;
- stats->global_close = 0;
- stats->global_beginscan = 0;
- stats->global_rescan = 0;
- stats->global_endscan = 0;
- stats->global_getnext = 0;
- stats->global_fetch = 0;
- stats->global_insert = 0;
- stats->global_delete = 0;
- stats->global_replace = 0;
- stats->global_markpos = 0;
- stats->global_restrpos = 0;
- stats->global_BufferGetRelation = 0;
- stats->global_RelationIdGetRelation = 0;
- stats->global_RelationIdGetRelation_Buf = 0;
- stats->global_getreldesc = 0;
- stats->global_heapgettup = 0;
- stats->global_RelationPutHeapTuple = 0;
- stats->global_RelationPutLongHeapTuple = 0;
-
- stats->local_open = 0;
- stats->local_openr = 0;
- stats->local_close = 0;
- stats->local_beginscan = 0;
- stats->local_rescan = 0;
- stats->local_endscan = 0;
- stats->local_getnext = 0;
- stats->local_fetch = 0;
- stats->local_insert = 0;
- stats->local_delete = 0;
- stats->local_replace = 0;
- stats->local_markpos = 0;
- stats->local_restrpos = 0;
- stats->local_BufferGetRelation = 0;
- stats->local_RelationIdGetRelation = 0;
- stats->local_RelationIdGetRelation_Buf = 0;
- stats->local_getreldesc = 0;
- stats->local_heapgettup = 0;
- stats->local_RelationPutHeapTuple = 0;
- stats->local_RelationPutLongHeapTuple = 0;
- stats->local_RelationNameGetRelation = 0;
- stats->global_RelationNameGetRelation = 0;
-
- /* ----------------
- * record init times
- * ----------------
- */
- time(&stats->init_global_timestamp);
- time(&stats->local_reset_timestamp);
- time(&stats->last_request_timestamp);
-
- /* ----------------
- * return to old memory context
- * ----------------
- */
- MemoryContextSwitchTo(oldContext);
-
- heap_access_stats = stats;
+ MemoryContext oldContext;
+ HeapAccessStatistics stats;
+
+ /* ----------------
+ * make sure we don't initialize things twice
+ * ----------------
+ */
+ if (heap_access_stats != NULL)
+ return;
+
+ /* ----------------
+ * allocate statistics structure from the top memory context
+ * ----------------
+ */
+ oldContext = MemoryContextSwitchTo(TopMemoryContext);
+
+ stats = (HeapAccessStatistics)
+ palloc(sizeof(HeapAccessStatisticsData));
+
+ /* ----------------
+ * initialize fields to default values
+ * ----------------
+ */
+ stats->global_open = 0;
+ stats->global_openr = 0;
+ stats->global_close = 0;
+ stats->global_beginscan = 0;
+ stats->global_rescan = 0;
+ stats->global_endscan = 0;
+ stats->global_getnext = 0;
+ stats->global_fetch = 0;
+ stats->global_insert = 0;
+ stats->global_delete = 0;
+ stats->global_replace = 0;
+ stats->global_markpos = 0;
+ stats->global_restrpos = 0;
+ stats->global_BufferGetRelation = 0;
+ stats->global_RelationIdGetRelation = 0;
+ stats->global_RelationIdGetRelation_Buf = 0;
+ stats->global_getreldesc = 0;
+ stats->global_heapgettup = 0;
+ stats->global_RelationPutHeapTuple = 0;
+ stats->global_RelationPutLongHeapTuple = 0;
+
+ stats->local_open = 0;
+ stats->local_openr = 0;
+ stats->local_close = 0;
+ stats->local_beginscan = 0;
+ stats->local_rescan = 0;
+ stats->local_endscan = 0;
+ stats->local_getnext = 0;
+ stats->local_fetch = 0;
+ stats->local_insert = 0;
+ stats->local_delete = 0;
+ stats->local_replace = 0;
+ stats->local_markpos = 0;
+ stats->local_restrpos = 0;
+ stats->local_BufferGetRelation = 0;
+ stats->local_RelationIdGetRelation = 0;
+ stats->local_RelationIdGetRelation_Buf = 0;
+ stats->local_getreldesc = 0;
+ stats->local_heapgettup = 0;
+ stats->local_RelationPutHeapTuple = 0;
+ stats->local_RelationPutLongHeapTuple = 0;
+ stats->local_RelationNameGetRelation = 0;
+ stats->global_RelationNameGetRelation = 0;
+
+ /* ----------------
+ * record init times
+ * ----------------
+ */
+ time(&stats->init_global_timestamp);
+ time(&stats->local_reset_timestamp);
+ time(&stats->last_request_timestamp);
+
+ /* ----------------
+ * return to old memory context
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldContext);
+
+ heap_access_stats = stats;
}
#ifdef NOT_USED
/* ----------------
- * ResetHeapAccessStatistics
+ * ResetHeapAccessStatistics
* ----------------
*/
void
-ResetHeapAccessStatistics()
+ResetHeapAccessStatistics()
{
- HeapAccessStatistics stats;
-
- /* ----------------
- * do nothing if stats aren't initialized
- * ----------------
- */
- if (heap_access_stats == NULL)
- return;
-
- stats = heap_access_stats;
-
- /* ----------------
- * reset local counts
- * ----------------
- */
- stats->local_open = 0;
- stats->local_openr = 0;
- stats->local_close = 0;
- stats->local_beginscan = 0;
- stats->local_rescan = 0;
- stats->local_endscan = 0;
- stats->local_getnext = 0;
- stats->local_fetch = 0;
- stats->local_insert = 0;
- stats->local_delete = 0;
- stats->local_replace = 0;
- stats->local_markpos = 0;
- stats->local_restrpos = 0;
- stats->local_BufferGetRelation = 0;
- stats->local_RelationIdGetRelation = 0;
- stats->local_RelationIdGetRelation_Buf = 0;
- stats->local_getreldesc = 0;
- stats->local_heapgettup = 0;
- stats->local_RelationPutHeapTuple = 0;
- stats->local_RelationPutLongHeapTuple = 0;
-
- /* ----------------
- * reset local timestamps
- * ----------------
- */
- time(&stats->local_reset_timestamp);
- time(&stats->last_request_timestamp);
+ HeapAccessStatistics stats;
+
+ /* ----------------
+ * do nothing if stats aren't initialized
+ * ----------------
+ */
+ if (heap_access_stats == NULL)
+ return;
+
+ stats = heap_access_stats;
+
+ /* ----------------
+ * reset local counts
+ * ----------------
+ */
+ stats->local_open = 0;
+ stats->local_openr = 0;
+ stats->local_close = 0;
+ stats->local_beginscan = 0;
+ stats->local_rescan = 0;
+ stats->local_endscan = 0;
+ stats->local_getnext = 0;
+ stats->local_fetch = 0;
+ stats->local_insert = 0;
+ stats->local_delete = 0;
+ stats->local_replace = 0;
+ stats->local_markpos = 0;
+ stats->local_restrpos = 0;
+ stats->local_BufferGetRelation = 0;
+ stats->local_RelationIdGetRelation = 0;
+ stats->local_RelationIdGetRelation_Buf = 0;
+ stats->local_getreldesc = 0;
+ stats->local_heapgettup = 0;
+ stats->local_RelationPutHeapTuple = 0;
+ stats->local_RelationPutLongHeapTuple = 0;
+
+ /* ----------------
+ * reset local timestamps
+ * ----------------
+ */
+ time(&stats->local_reset_timestamp);
+ time(&stats->last_request_timestamp);
}
+
#endif
#ifdef NOT_USED
/* ----------------
- * GetHeapAccessStatistics
+ * GetHeapAccessStatistics
* ----------------
*/
-HeapAccessStatistics GetHeapAccessStatistics()
+HeapAccessStatistics
+GetHeapAccessStatistics()
{
- HeapAccessStatistics stats;
-
- /* ----------------
- * return nothing if stats aren't initialized
- * ----------------
- */
- if (heap_access_stats == NULL)
- return NULL;
-
- /* ----------------
- * record the current request time
- * ----------------
- */
- time(&heap_access_stats->last_request_timestamp);
-
- /* ----------------
- * allocate a copy of the stats and return it to the caller.
- * ----------------
- */
- stats = (HeapAccessStatistics)
- palloc(sizeof(HeapAccessStatisticsData));
-
- memmove(stats,
- heap_access_stats,
- sizeof(HeapAccessStatisticsData));
-
- return stats;
+ HeapAccessStatistics stats;
+
+ /* ----------------
+ * return nothing if stats aren't initialized
+ * ----------------
+ */
+ if (heap_access_stats == NULL)
+ return NULL;
+
+ /* ----------------
+ * record the current request time
+ * ----------------
+ */
+ time(&heap_access_stats->last_request_timestamp);
+
+ /* ----------------
+ * allocate a copy of the stats and return it to the caller.
+ * ----------------
+ */
+ stats = (HeapAccessStatistics)
+ palloc(sizeof(HeapAccessStatisticsData));
+
+ memmove(stats,
+ heap_access_stats,
+ sizeof(HeapAccessStatisticsData));
+
+ return stats;
}
+
#endif
#ifdef NOT_USED
/* ----------------
- * PrintHeapAccessStatistics
+ * PrintHeapAccessStatistics
* ----------------
*/
void
PrintHeapAccessStatistics(HeapAccessStatistics stats)
{
- /* ----------------
- * return nothing if stats aren't valid
- * ----------------
- */
- if (stats == NULL)
- return;
-
- printf("======== heap am statistics ========\n");
- printf("init_global_timestamp: %s",
- ctime(&(stats->init_global_timestamp)));
-
- printf("local_reset_timestamp: %s",
- ctime(&(stats->local_reset_timestamp)));
-
- printf("last_request_timestamp: %s",
- ctime(&(stats->last_request_timestamp)));
-
- printf("local/global_open: %6d/%6d\n",
- stats->local_open, stats->global_open);
-
- printf("local/global_openr: %6d/%6d\n",
- stats->local_openr, stats->global_openr);
-
- printf("local/global_close: %6d/%6d\n",
- stats->local_close, stats->global_close);
-
- printf("local/global_beginscan: %6d/%6d\n",
- stats->local_beginscan, stats->global_beginscan);
-
- printf("local/global_rescan: %6d/%6d\n",
- stats->local_rescan, stats->global_rescan);
-
- printf("local/global_endscan: %6d/%6d\n",
- stats->local_endscan, stats->global_endscan);
-
- printf("local/global_getnext: %6d/%6d\n",
- stats->local_getnext, stats->global_getnext);
-
- printf("local/global_fetch: %6d/%6d\n",
- stats->local_fetch, stats->global_fetch);
-
- printf("local/global_insert: %6d/%6d\n",
- stats->local_insert, stats->global_insert);
-
- printf("local/global_delete: %6d/%6d\n",
- stats->local_delete, stats->global_delete);
-
- printf("local/global_replace: %6d/%6d\n",
- stats->local_replace, stats->global_replace);
-
- printf("local/global_markpos: %6d/%6d\n",
- stats->local_markpos, stats->global_markpos);
-
- printf("local/global_restrpos: %6d/%6d\n",
- stats->local_restrpos, stats->global_restrpos);
-
- printf("================\n");
-
- printf("local/global_BufferGetRelation: %6d/%6d\n",
- stats->local_BufferGetRelation,
- stats->global_BufferGetRelation);
-
- printf("local/global_RelationIdGetRelation: %6d/%6d\n",
- stats->local_RelationIdGetRelation,
- stats->global_RelationIdGetRelation);
-
- printf("local/global_RelationIdGetRelation_Buf: %6d/%6d\n",
- stats->local_RelationIdGetRelation_Buf,
- stats->global_RelationIdGetRelation_Buf);
-
- printf("local/global_getreldesc: %6d/%6d\n",
- stats->local_getreldesc, stats->global_getreldesc);
-
- printf("local/global_heapgettup: %6d/%6d\n",
- stats->local_heapgettup, stats->global_heapgettup);
-
- printf("local/global_RelationPutHeapTuple: %6d/%6d\n",
- stats->local_RelationPutHeapTuple,
- stats->global_RelationPutHeapTuple);
-
- printf("local/global_RelationPutLongHeapTuple: %6d/%6d\n",
- stats->local_RelationPutLongHeapTuple,
- stats->global_RelationPutLongHeapTuple);
-
- printf("===================================\n");
-
- printf("\n");
+ /* ----------------
+ * return nothing if stats aren't valid
+ * ----------------
+ */
+ if (stats == NULL)
+ return;
+
+ printf("======== heap am statistics ========\n");
+ printf("init_global_timestamp: %s",
+ ctime(&(stats->init_global_timestamp)));
+
+ printf("local_reset_timestamp: %s",
+ ctime(&(stats->local_reset_timestamp)));
+
+ printf("last_request_timestamp: %s",
+ ctime(&(stats->last_request_timestamp)));
+
+ printf("local/global_open: %6d/%6d\n",
+ stats->local_open, stats->global_open);
+
+ printf("local/global_openr: %6d/%6d\n",
+ stats->local_openr, stats->global_openr);
+
+ printf("local/global_close: %6d/%6d\n",
+ stats->local_close, stats->global_close);
+
+ printf("local/global_beginscan: %6d/%6d\n",
+ stats->local_beginscan, stats->global_beginscan);
+
+ printf("local/global_rescan: %6d/%6d\n",
+ stats->local_rescan, stats->global_rescan);
+
+ printf("local/global_endscan: %6d/%6d\n",
+ stats->local_endscan, stats->global_endscan);
+
+ printf("local/global_getnext: %6d/%6d\n",
+ stats->local_getnext, stats->global_getnext);
+
+ printf("local/global_fetch: %6d/%6d\n",
+ stats->local_fetch, stats->global_fetch);
+
+ printf("local/global_insert: %6d/%6d\n",
+ stats->local_insert, stats->global_insert);
+
+ printf("local/global_delete: %6d/%6d\n",
+ stats->local_delete, stats->global_delete);
+
+ printf("local/global_replace: %6d/%6d\n",
+ stats->local_replace, stats->global_replace);
+
+ printf("local/global_markpos: %6d/%6d\n",
+ stats->local_markpos, stats->global_markpos);
+
+ printf("local/global_restrpos: %6d/%6d\n",
+ stats->local_restrpos, stats->global_restrpos);
+
+ printf("================\n");
+
+ printf("local/global_BufferGetRelation: %6d/%6d\n",
+ stats->local_BufferGetRelation,
+ stats->global_BufferGetRelation);
+
+ printf("local/global_RelationIdGetRelation: %6d/%6d\n",
+ stats->local_RelationIdGetRelation,
+ stats->global_RelationIdGetRelation);
+
+ printf("local/global_RelationIdGetRelation_Buf: %6d/%6d\n",
+ stats->local_RelationIdGetRelation_Buf,
+ stats->global_RelationIdGetRelation_Buf);
+
+ printf("local/global_getreldesc: %6d/%6d\n",
+ stats->local_getreldesc, stats->global_getreldesc);
+
+ printf("local/global_heapgettup: %6d/%6d\n",
+ stats->local_heapgettup, stats->global_heapgettup);
+
+ printf("local/global_RelationPutHeapTuple: %6d/%6d\n",
+ stats->local_RelationPutHeapTuple,
+ stats->global_RelationPutHeapTuple);
+
+ printf("local/global_RelationPutLongHeapTuple: %6d/%6d\n",
+ stats->local_RelationPutLongHeapTuple,
+ stats->global_RelationPutLongHeapTuple);
+
+ printf("===================================\n");
+
+ printf("\n");
}
+
#endif
#ifdef NOT_USED
/* ----------------
- * PrintAndFreeHeapAccessStatistics
+ * PrintAndFreeHeapAccessStatistics
* ----------------
*/
void
PrintAndFreeHeapAccessStatistics(HeapAccessStatistics stats)
{
- PrintHeapAccessStatistics(stats);
- if (stats != NULL)
- pfree(stats);
+ PrintHeapAccessStatistics(stats);
+ if (stats != NULL)
+ pfree(stats);
}
+
#endif
/* ----------------------------------------------------------------
- * access method initialization
+ * access method initialization
* ----------------------------------------------------------------
*/
/* ----------------
- * initam should someday be moved someplace else.
+ * initam should someday be moved someplace else.
* ----------------
*/
void
initam(void)
{
- /* ----------------
- * initialize heap statistics.
- * ----------------
- */
- InitHeapAccessStatistics();
+ /* ----------------
+ * initialize heap statistics.
+ * ----------------
+ */
+ InitHeapAccessStatistics();
}
diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
index 52b7b1473bf..da7fc0dc09f 100644
--- a/src/backend/access/index/genam.c
+++ b/src/backend/access/index/genam.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* genam.c--
- * general index access method routines
+ * general index access method routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.7 1997/08/19 21:29:26 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.8 1997/09/07 04:38:17 momjian Exp $
*
* NOTES
- * many of the old access method routines have been turned into
- * macros and moved to genam.h -cim 4/30/91
+ * many of the old access method routines have been turned into
+ * macros and moved to genam.h -cim 4/30/91
*
*-------------------------------------------------------------------------
*/
@@ -29,18 +29,18 @@
* previous, current, next. Note that the case of reverse scans works
* identically.
*
- * State Result
- * (1) + + - + 0 0 (if the next item pointer is invalid)
- * (2) + X - (otherwise)
- * (3) * 0 0 * 0 0 (no change)
- * (4) + X 0 X 0 0 (shift)
- * (5) * + X + X - (shift, add unknown)
+ * State Result
+ * (1) + + - + 0 0 (if the next item pointer is invalid)
+ * (2) + X - (otherwise)
+ * (3) * 0 0 * 0 0 (no change)
+ * (4) + X 0 X 0 0 (shift)
+ * (5) * + X + X - (shift, add unknown)
*
* All other states cannot occur.
*
* Note:
*It would be possible to cache the status of the previous and
- * next item pointer using the flags.
+ * next item pointer using the flags.
* ----------------------------------------------------------------
*/
@@ -51,220 +51,234 @@
#include <storage/bufmgr.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
/* ----------------------------------------------------------------
- * general access method routines
+ * general access method routines
*
- * All indexed access methods use an identical scan structure.
- * We don't know how the various AMs do locking, however, so we don't
- * do anything about that here.
+ * All indexed access methods use an identical scan structure.
+ * We don't know how the various AMs do locking, however, so we don't
+ * do anything about that here.
*
- * The intent is that an AM implementor will define a front-end routine
- * that calls this one, to fill in the scan, and then does whatever kind
- * of locking he wants.
+ * The intent is that an AM implementor will define a front-end routine
+ * that calls this one, to fill in the scan, and then does whatever kind
+ * of locking he wants.
* ----------------------------------------------------------------
*/
/* ----------------
- * RelationGetIndexScan -- Create and fill an IndexScanDesc.
+ * RelationGetIndexScan -- Create and fill an IndexScanDesc.
*
- * This routine creates an index scan structure and sets its contents
- * up correctly. This routine calls AMrescan to set up the scan with
- * the passed key.
+ * This routine creates an index scan structure and sets its contents
+ * up correctly. This routine calls AMrescan to set up the scan with
+ * the passed key.
*
- * Parameters:
- * relation -- index relation for scan.
- * scanFromEnd -- if true, begin scan at one of the index's
- * endpoints.
- * numberOfKeys -- count of scan keys (more than one won't
- * necessarily do anything useful, yet).
- * key -- the ScanKey for the starting position of the scan.
+ * Parameters:
+ * relation -- index relation for scan.
+ * scanFromEnd -- if true, begin scan at one of the index's
+ * endpoints.
+ * numberOfKeys -- count of scan keys (more than one won't
+ * necessarily do anything useful, yet).
+ * key -- the ScanKey for the starting position of the scan.
*
- * Returns:
- * An initialized IndexScanDesc.
+ * Returns:
+ * An initialized IndexScanDesc.
+ *
+ * Side Effects:
+ * Bumps the ref count on the relation to keep it in the cache.
*
- * Side Effects:
- * Bumps the ref count on the relation to keep it in the cache.
- *
* ----------------
*/
IndexScanDesc
RelationGetIndexScan(Relation relation,
- bool scanFromEnd,
- uint16 numberOfKeys,
- ScanKey key)
+ bool scanFromEnd,
+ uint16 numberOfKeys,
+ ScanKey key)
{
- IndexScanDesc scan;
-
- if (! RelationIsValid(relation))
- elog(WARN, "RelationGetIndexScan: relation invalid");
-
- scan = (IndexScanDesc) palloc(sizeof(IndexScanDescData));
-
- scan->relation = relation;
- scan->opaque = NULL;
- scan->numberOfKeys = numberOfKeys;
-
- ItemPointerSetInvalid(&scan->previousItemData);
- ItemPointerSetInvalid(&scan->currentItemData);
- ItemPointerSetInvalid(&scan->nextItemData);
- ItemPointerSetInvalid(&scan->previousMarkData);
- ItemPointerSetInvalid(&scan->currentMarkData);
- ItemPointerSetInvalid(&scan->nextMarkData);
+ IndexScanDesc scan;
+
+ if (!RelationIsValid(relation))
+ elog(WARN, "RelationGetIndexScan: relation invalid");
+
+ scan = (IndexScanDesc) palloc(sizeof(IndexScanDescData));
- if (numberOfKeys > 0) {
- scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * numberOfKeys);
- } else {
- scan->keyData = NULL;
- }
+ scan->relation = relation;
+ scan->opaque = NULL;
+ scan->numberOfKeys = numberOfKeys;
+
+ ItemPointerSetInvalid(&scan->previousItemData);
+ ItemPointerSetInvalid(&scan->currentItemData);
+ ItemPointerSetInvalid(&scan->nextItemData);
+ ItemPointerSetInvalid(&scan->previousMarkData);
+ ItemPointerSetInvalid(&scan->currentMarkData);
+ ItemPointerSetInvalid(&scan->nextMarkData);
+
+ if (numberOfKeys > 0)
+ {
+ scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * numberOfKeys);
+ }
+ else
+ {
+ scan->keyData = NULL;
+ }
- index_rescan(scan, scanFromEnd, key);
-
- return (scan);
+ index_rescan(scan, scanFromEnd, key);
+
+ return (scan);
}
#ifdef NOT_USED
/* ----------------
- * IndexScanRestart -- Restart an index scan.
+ * IndexScanRestart -- Restart an index scan.
*
- * This routine isn't used by any existing access method. It's
- * appropriate if relation level locks are what you want.
+ * This routine isn't used by any existing access method. It's
+ * appropriate if relation level locks are what you want.
*
- * Returns:
- * None.
+ * Returns:
+ * None.
*
- * Side Effects:
- * None.
+ * Side Effects:
+ * None.
* ----------------
*/
void
IndexScanRestart(IndexScanDesc scan,
- bool scanFromEnd,
- ScanKey key)
+ bool scanFromEnd,
+ ScanKey key)
{
- if (! IndexScanIsValid(scan))
- elog(WARN, "IndexScanRestart: invalid scan");
-
- ItemPointerSetInvalid(&scan->previousItemData);
- ItemPointerSetInvalid(&scan->currentItemData);
- ItemPointerSetInvalid(&scan->nextItemData);
-
- if (RelationGetNumberOfBlocks(scan->relation) == 0)
- scan->flags = ScanUnmarked;
- else if (scanFromEnd)
- scan->flags = ScanUnmarked | ScanUncheckedPrevious;
- else
- scan->flags = ScanUnmarked | ScanUncheckedNext;
-
- scan->scanFromEnd = (bool) scanFromEnd;
-
- if (scan->numberOfKeys > 0)
- memmove(scan->keyData,
- key,
- scan->numberOfKeys * sizeof(ScanKeyData));
+ if (!IndexScanIsValid(scan))
+ elog(WARN, "IndexScanRestart: invalid scan");
+
+ ItemPointerSetInvalid(&scan->previousItemData);
+ ItemPointerSetInvalid(&scan->currentItemData);
+ ItemPointerSetInvalid(&scan->nextItemData);
+
+ if (RelationGetNumberOfBlocks(scan->relation) == 0)
+ scan->flags = ScanUnmarked;
+ else if (scanFromEnd)
+ scan->flags = ScanUnmarked | ScanUncheckedPrevious;
+ else
+ scan->flags = ScanUnmarked | ScanUncheckedNext;
+
+ scan->scanFromEnd = (bool) scanFromEnd;
+
+ if (scan->numberOfKeys > 0)
+ memmove(scan->keyData,
+ key,
+ scan->numberOfKeys * sizeof(ScanKeyData));
}
+
#endif
#ifdef NOT_USED
/* ----------------
- * IndexScanEnd -- End and index scan.
+ * IndexScanEnd -- End and index scan.
*
- * This routine is not used by any existing access method, but is
- * suitable for use if you don't want to do sophisticated locking.
+ * This routine is not used by any existing access method, but is
+ * suitable for use if you don't want to do sophisticated locking.
*
- * Returns:
- * None.
+ * Returns:
+ * None.
*
- * Side Effects:
- * None.
+ * Side Effects:
+ * None.
* ----------------
*/
void
IndexScanEnd(IndexScanDesc scan)
{
- if (! IndexScanIsValid(scan))
- elog(WARN, "IndexScanEnd: invalid scan");
-
- pfree(scan);
+ if (!IndexScanIsValid(scan))
+ elog(WARN, "IndexScanEnd: invalid scan");
+
+ pfree(scan);
}
+
#endif
/* ----------------
- * IndexScanMarkPosition -- Mark current position in a scan.
+ * IndexScanMarkPosition -- Mark current position in a scan.
*
- * This routine isn't used by any existing access method, but is the
- * one that AM implementors should use, if they don't want to do any
- * special locking. If relation-level locking is sufficient, this is
- * the routine for you.
+ * This routine isn't used by any existing access method, but is the
+ * one that AM implementors should use, if they don't want to do any
+ * special locking. If relation-level locking is sufficient, this is
+ * the routine for you.
*
- * Returns:
- * None.
+ * Returns:
+ * None.
*
- * Side Effects:
- * None.
+ * Side Effects:
+ * None.
* ----------------
*/
void
IndexScanMarkPosition(IndexScanDesc scan)
{
- RetrieveIndexResult result;
-
- if (scan->flags & ScanUncheckedPrevious) {
- result =
- index_getnext(scan, BackwardScanDirection);
-
- if (result != NULL) {
- scan->previousItemData = result->index_iptr;
- } else {
- ItemPointerSetInvalid(&scan->previousItemData);
+ RetrieveIndexResult result;
+
+ if (scan->flags & ScanUncheckedPrevious)
+ {
+ result =
+ index_getnext(scan, BackwardScanDirection);
+
+ if (result != NULL)
+ {
+ scan->previousItemData = result->index_iptr;
+ }
+ else
+ {
+ ItemPointerSetInvalid(&scan->previousItemData);
+ }
+
}
-
- } else if (scan->flags & ScanUncheckedNext) {
- result = (RetrieveIndexResult)
- index_getnext(scan, ForwardScanDirection);
-
- if (result != NULL) {
- scan->nextItemData = result->index_iptr;
- } else {
- ItemPointerSetInvalid(&scan->nextItemData);
+ else if (scan->flags & ScanUncheckedNext)
+ {
+ result = (RetrieveIndexResult)
+ index_getnext(scan, ForwardScanDirection);
+
+ if (result != NULL)
+ {
+ scan->nextItemData = result->index_iptr;
+ }
+ else
+ {
+ ItemPointerSetInvalid(&scan->nextItemData);
+ }
}
- }
-
- scan->previousMarkData = scan->previousItemData;
- scan->currentMarkData = scan->currentItemData;
- scan->nextMarkData = scan->nextItemData;
-
- scan->flags = 0x0; /* XXX should have a symbolic name */
+
+ scan->previousMarkData = scan->previousItemData;
+ scan->currentMarkData = scan->currentItemData;
+ scan->nextMarkData = scan->nextItemData;
+
+ scan->flags = 0x0; /* XXX should have a symbolic name */
}
/* ----------------
- * IndexScanRestorePosition -- Restore position on a marked scan.
+ * IndexScanRestorePosition -- Restore position on a marked scan.
*
- * This routine isn't used by any existing access method, but is the
- * one that AM implementors should use if they don't want to do any
- * special locking. If relation-level locking is sufficient, then
- * this is the one you want.
+ * This routine isn't used by any existing access method, but is the
+ * one that AM implementors should use if they don't want to do any
+ * special locking. If relation-level locking is sufficient, then
+ * this is the one you want.
*
- * Returns:
- * None.
+ * Returns:
+ * None.
*
- * Side Effects:
- * None.
+ * Side Effects:
+ * None.
* ----------------
*/
void
IndexScanRestorePosition(IndexScanDesc scan)
-{
- if (scan->flags & ScanUnmarked)
- elog(WARN, "IndexScanRestorePosition: no mark to restore");
-
- scan->previousItemData = scan->previousMarkData;
- scan->currentItemData = scan->currentMarkData;
- scan->nextItemData = scan->nextMarkData;
-
- scan->flags = 0x0; /* XXX should have a symbolic name */
+{
+ if (scan->flags & ScanUnmarked)
+ elog(WARN, "IndexScanRestorePosition: no mark to restore");
+
+ scan->previousItemData = scan->previousMarkData;
+ scan->currentItemData = scan->currentMarkData;
+ scan->nextItemData = scan->nextMarkData;
+
+ scan->flags = 0x0; /* XXX should have a symbolic name */
}
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 3068f7cceed..6841899fa39 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -1,80 +1,80 @@
/*-------------------------------------------------------------------------
*
* indexam.c--
- * general index access method routines
+ * general index access method routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.13 1997/08/26 23:31:28 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.14 1997/09/07 04:38:26 momjian Exp $
*
* INTERFACE ROUTINES
- * index_open - open an index relation by relationId
- * index_openr - open a index relation by name
- * index_close - close a index relation
- * index_beginscan - start a scan of an index
- * index_rescan - restart a scan of an index
- * index_endscan - end a scan
- * index_insert - insert an index tuple into a relation
- * index_delete - delete an item from an index relation
- * index_markpos - mark a scan position
- * index_restrpos - restore a scan position
- * index_getnext - get the next tuple from a scan
- * ** index_fetch - retrieve tuple with tid
+ * index_open - open an index relation by relationId
+ * index_openr - open a index relation by name
+ * index_close - close a index relation
+ * index_beginscan - start a scan of an index
+ * index_rescan - restart a scan of an index
+ * index_endscan - end a scan
+ * index_insert - insert an index tuple into a relation
+ * index_delete - delete an item from an index relation
+ * index_markpos - mark a scan position
+ * index_restrpos - restore a scan position
+ * index_getnext - get the next tuple from a scan
+ * ** index_fetch - retrieve tuple with tid
* ** index_replace - replace a tuple
* ** index_getattr - get an attribute from an index tuple
- * index_getprocid - get a support procedure id from the rel tuple
- *
- * IndexScanIsValid - check index scan
+ * index_getprocid - get a support procedure id from the rel tuple
+ *
+ * IndexScanIsValid - check index scan
*
* NOTES
- * This file contains the index_ routines which used
- * to be a scattered collection of stuff in access/genam.
+ * This file contains the index_ routines which used
+ * to be a scattered collection of stuff in access/genam.
*
- * The ** routines: index_fetch, index_replace, and index_getattr
- * have not yet been implemented. They may not be needed.
+ * The ** routines: index_fetch, index_replace, and index_getattr
+ * have not yet been implemented. They may not be needed.
*
* old comments
- * Scans are implemented as follows:
+ * Scans are implemented as follows:
*
- * `0' represents an invalid item pointer.
- * `-' represents an unknown item pointer.
- * `X' represents a known item pointers.
- * `+' represents known or invalid item pointers.
- * `*' represents any item pointers.
+ * `0' represents an invalid item pointer.
+ * `-' represents an unknown item pointer.
+ * `X' represents a known item pointers.
+ * `+' represents known or invalid item pointers.
+ * `*' represents any item pointers.
*
- * State is represented by a triple of these symbols in the order of
- * previous, current, next. Note that the case of reverse scans works
- * identically.
+ * State is represented by a triple of these symbols in the order of
+ * previous, current, next. Note that the case of reverse scans works
+ * identically.
*
- * State Result
- * (1) + + - + 0 0 (if the next item pointer is invalid)
- * (2) + X - (otherwise)
- * (3) * 0 0 * 0 0 (no change)
- * (4) + X 0 X 0 0 (shift)
- * (5) * + X + X - (shift, add unknown)
+ * State Result
+ * (1) + + - + 0 0 (if the next item pointer is invalid)
+ * (2) + X - (otherwise)
+ * (3) * 0 0 * 0 0 (no change)
+ * (4) + X 0 X 0 0 (shift)
+ * (5) * + X + X - (shift, add unknown)
*
- * All other states cannot occur.
+ * All other states cannot occur.
*
- * Note: It would be possible to cache the status of the previous and
- * next item pointer using the flags.
+ * Note: It would be possible to cache the status of the previous and
+ * next item pointer using the flags.
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
-#include <access/genam.h>
+
+#include <access/genam.h>
#include <utils/relcache.h>
#include <fmgr.h>
#include <storage/lmgr.h>
#include <access/heapam.h>
/* ----------------
- * undefine macros we aren't going to use that would otherwise
- * get in our way.. delete is defined in c.h and the am's are
- * defined in heapam.h
+ * undefine macros we aren't going to use that would otherwise
+ * get in our way.. delete is defined in c.h and the am's are
+ * defined in heapam.h
* ----------------
*/
#undef delete
@@ -88,314 +88,320 @@
#undef amgettuple
/* ----------------------------------------------------------------
- * macros used in index_ routines
+ * macros used in index_ routines
* ----------------------------------------------------------------
*/
#define RELATION_CHECKS \
Assert(RelationIsValid(relation)); \
- Assert(PointerIsValid(relation->rd_am))
-
+ Assert(PointerIsValid(relation->rd_am))
+
#define SCAN_CHECKS \
- Assert(IndexScanIsValid(scan)); \
- Assert(RelationIsValid(scan->relation)); \
- Assert(PointerIsValid(scan->relation->rd_am))
-
+ Assert(IndexScanIsValid(scan)); \
+ Assert(RelationIsValid(scan->relation)); \
+ Assert(PointerIsValid(scan->relation->rd_am))
+
#define GET_REL_PROCEDURE(x,y) \
- procedure = relation->rd_am->y; \
- if (! RegProcedureIsValid(procedure)) \
- elog(WARN, "index_%s: invalid %s regproc", \
- CppAsString(x), CppAsString(y))
-
+ procedure = relation->rd_am->y; \
+ if (! RegProcedureIsValid(procedure)) \
+ elog(WARN, "index_%s: invalid %s regproc", \
+ CppAsString(x), CppAsString(y))
+
#define GET_SCAN_PROCEDURE(x,y) \
- procedure = scan->relation->rd_am->y; \
- if (! RegProcedureIsValid(procedure)) \
- elog(WARN, "index_%s: invalid %s regproc", \
- CppAsString(x), CppAsString(y))
-
-
+ procedure = scan->relation->rd_am->y; \
+ if (! RegProcedureIsValid(procedure)) \
+ elog(WARN, "index_%s: invalid %s regproc", \
+ CppAsString(x), CppAsString(y))
+
+
/* ----------------------------------------------------------------
- * index_ interface functions
+ * index_ interface functions
* ----------------------------------------------------------------
*/
/* ----------------
- * index_open - open an index relation by relationId
+ * index_open - open an index relation by relationId
*
- * presently the relcache routines do all the work we need
- * to open/close index relations.
+ * presently the relcache routines do all the work we need
+ * to open/close index relations.
* ----------------
*/
Relation
index_open(Oid relationId)
{
- return RelationIdGetRelation(relationId);
+ return RelationIdGetRelation(relationId);
}
/* ----------------
- * index_openr - open a index relation by name
+ * index_openr - open a index relation by name
*
- * presently the relcache routines do all the work we need
- * to open/close index relations.
+ * presently the relcache routines do all the work we need
+ * to open/close index relations.
* ----------------
*/
Relation
index_openr(char *relationName)
{
- return RelationNameGetRelation(relationName);
+ return RelationNameGetRelation(relationName);
}
/* ----------------
- * index_close - close a index relation
+ * index_close - close a index relation
*
- * presently the relcache routines do all the work we need
- * to open/close index relations.
+ * presently the relcache routines do all the work we need
+ * to open/close index relations.
* ----------------
*/
void
index_close(Relation relation)
{
- RelationClose(relation);
+ RelationClose(relation);
}
/* ----------------
- * index_insert - insert an index tuple into a relation
+ * index_insert - insert an index tuple into a relation
* ----------------
*/
InsertIndexResult
index_insert(Relation relation,
- Datum *datum,
- char *nulls,
- ItemPointer heap_t_ctid,
- Relation heapRel)
+ Datum * datum,
+ char *nulls,
+ ItemPointer heap_t_ctid,
+ Relation heapRel)
{
- RegProcedure procedure;
- InsertIndexResult specificResult;
-
- RELATION_CHECKS;
- GET_REL_PROCEDURE(insert,aminsert);
-
- /* ----------------
- * have the am's insert proc do all the work.
- * ----------------
- */
- specificResult = (InsertIndexResult)
- fmgr(procedure, relation, datum, nulls, heap_t_ctid, heapRel, NULL);
-
- /* ----------------
- * the insert proc is supposed to return a "specific result" and
- * this routine has to return a "general result" so after we get
- * something back from the insert proc, we allocate a
- * "general result" and copy some crap between the two.
- *
- * As far as I'm concerned all this result shit is needlessly c
- * omplicated and should be eliminated. -cim 1/19/91
- *
- * mao concurs. regardless of how we feel here, however, it is
- * important to free memory we don't intend to return to anyone.
- * 2/28/91
- *
- * this "general result" crap is now gone. -ay 3/6/95
- * ----------------
- */
-
- return (specificResult);
+ RegProcedure procedure;
+ InsertIndexResult specificResult;
+
+ RELATION_CHECKS;
+ GET_REL_PROCEDURE(insert, aminsert);
+
+ /* ----------------
+ * have the am's insert proc do all the work.
+ * ----------------
+ */
+ specificResult = (InsertIndexResult)
+ fmgr(procedure, relation, datum, nulls, heap_t_ctid, heapRel, NULL);
+
+ /* ----------------
+ * the insert proc is supposed to return a "specific result" and
+ * this routine has to return a "general result" so after we get
+ * something back from the insert proc, we allocate a
+ * "general result" and copy some crap between the two.
+ *
+ * As far as I'm concerned all this result shit is needlessly c
+ * omplicated and should be eliminated. -cim 1/19/91
+ *
+ * mao concurs. regardless of how we feel here, however, it is
+ * important to free memory we don't intend to return to anyone.
+ * 2/28/91
+ *
+ * this "general result" crap is now gone. -ay 3/6/95
+ * ----------------
+ */
+
+ return (specificResult);
}
/* ----------------
- * index_delete - delete an item from an index relation
+ * index_delete - delete an item from an index relation
* ----------------
*/
void
index_delete(Relation relation, ItemPointer indexItem)
{
- RegProcedure procedure;
-
- RELATION_CHECKS;
- GET_REL_PROCEDURE(delete,amdelete);
-
- fmgr(procedure, relation, indexItem);
+ RegProcedure procedure;
+
+ RELATION_CHECKS;
+ GET_REL_PROCEDURE(delete, amdelete);
+
+ fmgr(procedure, relation, indexItem);
}
/* ----------------
- * index_beginscan - start a scan of an index
+ * index_beginscan - start a scan of an index
* ----------------
*/
IndexScanDesc
index_beginscan(Relation relation,
- bool scanFromEnd,
- uint16 numberOfKeys,
- ScanKey key)
+ bool scanFromEnd,
+ uint16 numberOfKeys,
+ ScanKey key)
{
- IndexScanDesc scandesc;
- RegProcedure procedure;
-
- RELATION_CHECKS;
- GET_REL_PROCEDURE(beginscan,ambeginscan);
-
- RelationSetRIntentLock(relation);
-
- scandesc = (IndexScanDesc)
- fmgr(procedure, relation, scanFromEnd, numberOfKeys, key);
-
- return scandesc;
+ IndexScanDesc scandesc;
+ RegProcedure procedure;
+
+ RELATION_CHECKS;
+ GET_REL_PROCEDURE(beginscan, ambeginscan);
+
+ RelationSetRIntentLock(relation);
+
+ scandesc = (IndexScanDesc)
+ fmgr(procedure, relation, scanFromEnd, numberOfKeys, key);
+
+ return scandesc;
}
/* ----------------
- * index_rescan - restart a scan of an index
+ * index_rescan - restart a scan of an index
* ----------------
*/
void
index_rescan(IndexScanDesc scan, bool scanFromEnd, ScanKey key)
{
- RegProcedure procedure;
-
- SCAN_CHECKS;
- GET_SCAN_PROCEDURE(rescan,amrescan);
-
- fmgr(procedure, scan, scanFromEnd, key);
+ RegProcedure procedure;
+
+ SCAN_CHECKS;
+ GET_SCAN_PROCEDURE(rescan, amrescan);
+
+ fmgr(procedure, scan, scanFromEnd, key);
}
/* ----------------
- * index_endscan - end a scan
+ * index_endscan - end a scan
* ----------------
*/
void
index_endscan(IndexScanDesc scan)
{
- RegProcedure procedure;
-
- SCAN_CHECKS;
- GET_SCAN_PROCEDURE(endscan,amendscan);
-
- fmgr(procedure, scan);
-
- RelationUnsetRIntentLock(scan->relation);
+ RegProcedure procedure;
+
+ SCAN_CHECKS;
+ GET_SCAN_PROCEDURE(endscan, amendscan);
+
+ fmgr(procedure, scan);
+
+ RelationUnsetRIntentLock(scan->relation);
}
#ifdef NOT_USED
/* ----------------
- * index_markpos - mark a scan position
+ * index_markpos - mark a scan position
* ----------------
*/
void
index_markpos(IndexScanDesc scan)
{
- RegProcedure procedure;
-
- SCAN_CHECKS;
- GET_SCAN_PROCEDURE(markpos,ammarkpos);
-
- fmgr(procedure, scan);
+ RegProcedure procedure;
+
+ SCAN_CHECKS;
+ GET_SCAN_PROCEDURE(markpos, ammarkpos);
+
+ fmgr(procedure, scan);
}
+
#endif
#ifdef NOT_USED
/* ----------------
- * index_restrpos - restore a scan position
+ * index_restrpos - restore a scan position
* ----------------
*/
void
index_restrpos(IndexScanDesc scan)
{
- RegProcedure procedure;
-
- SCAN_CHECKS;
- GET_SCAN_PROCEDURE(restrpos,amrestrpos);
-
- fmgr(procedure, scan);
+ RegProcedure procedure;
+
+ SCAN_CHECKS;
+ GET_SCAN_PROCEDURE(restrpos, amrestrpos);
+
+ fmgr(procedure, scan);
}
+
#endif
/* ----------------
- * index_getnext - get the next tuple from a scan
+ * index_getnext - get the next tuple from a scan
*
- * A RetrieveIndexResult is a index tuple/heap tuple pair
+ * A RetrieveIndexResult is a index tuple/heap tuple pair
* ----------------
*/
RetrieveIndexResult
index_getnext(IndexScanDesc scan,
- ScanDirection direction)
+ ScanDirection direction)
{
- RegProcedure procedure;
- RetrieveIndexResult result;
-
- SCAN_CHECKS;
- GET_SCAN_PROCEDURE(getnext,amgettuple);
-
- /* ----------------
- * have the am's gettuple proc do all the work.
- * ----------------
- */
- result = (RetrieveIndexResult)
- fmgr(procedure, scan, direction);
-
- return result;
+ RegProcedure procedure;
+ RetrieveIndexResult result;
+
+ SCAN_CHECKS;
+ GET_SCAN_PROCEDURE(getnext, amgettuple);
+
+ /* ----------------
+ * have the am's gettuple proc do all the work.
+ * ----------------
+ */
+ result = (RetrieveIndexResult)
+ fmgr(procedure, scan, direction);
+
+ return result;
}
/* ----------------
- * index_getprocid
+ * index_getprocid
*
- * Some indexed access methods may require support routines that are
- * not in the operator class/operator model imposed by pg_am. These
- * access methods may store the OIDs of registered procedures they
- * need in pg_amproc. These registered procedure OIDs are ordered in
- * a way that makes sense to the access method, and used only by the
- * access method. The general index code doesn't know anything about
- * the routines involved; it just builds an ordered list of them for
- * each attribute on which an index is defined.
+ * Some indexed access methods may require support routines that are
+ * not in the operator class/operator model imposed by pg_am. These
+ * access methods may store the OIDs of registered procedures they
+ * need in pg_amproc. These registered procedure OIDs are ordered in
+ * a way that makes sense to the access method, and used only by the
+ * access method. The general index code doesn't know anything about
+ * the routines involved; it just builds an ordered list of them for
+ * each attribute on which an index is defined.
*
- * This routine returns the requested procedure OID for a particular
- * indexed attribute.
+ * This routine returns the requested procedure OID for a particular
+ * indexed attribute.
* ----------------
*/
RegProcedure
index_getprocid(Relation irel,
- AttrNumber attnum,
- uint16 procnum)
+ AttrNumber attnum,
+ uint16 procnum)
{
- RegProcedure *loc;
- int natts;
-
- natts = irel->rd_rel->relnatts;
-
- loc = irel->rd_support;
-
- Assert(loc != NULL);
-
- return (loc[(natts * (procnum - 1)) + (attnum - 1)]);
+ RegProcedure *loc;
+ int natts;
+
+ natts = irel->rd_rel->relnatts;
+
+ loc = irel->rd_support;
+
+ Assert(loc != NULL);
+
+ return (loc[(natts * (procnum - 1)) + (attnum - 1)]);
}
Datum
GetIndexValue(HeapTuple tuple,
- TupleDesc hTupDesc,
- int attOff,
- AttrNumber attrNums[],
- FuncIndexInfo *fInfo,
- bool *attNull,
- Buffer buffer)
+ TupleDesc hTupDesc,
+ int attOff,
+ AttrNumber attrNums[],
+ FuncIndexInfo * fInfo,
+ bool * attNull,
+ Buffer buffer)
{
- Datum returnVal;
- bool isNull;
-
- if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid) {
- int i;
- Datum *attData = (Datum *)palloc(FIgetnArgs(fInfo)*sizeof(Datum));
-
- for (i = 0; i < FIgetnArgs(fInfo); i++) {
- attData[i] = (Datum) heap_getattr(tuple,
- buffer,
- attrNums[i],
- hTupDesc,
- attNull);
+ Datum returnVal;
+ bool isNull;
+
+ if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid)
+ {
+ int i;
+ Datum *attData = (Datum *) palloc(FIgetnArgs(fInfo) * sizeof(Datum));
+
+ for (i = 0; i < FIgetnArgs(fInfo); i++)
+ {
+ attData[i] = (Datum) heap_getattr(tuple,
+ buffer,
+ attrNums[i],
+ hTupDesc,
+ attNull);
+ }
+ returnVal = (Datum) fmgr_array_args(FIgetProcOid(fInfo),
+ FIgetnArgs(fInfo),
+ (char **) attData,
+ &isNull);
+ pfree(attData);
+ *attNull = FALSE;
+ }
+ else
+ {
+ returnVal = (Datum) heap_getattr(tuple, buffer, attrNums[attOff],
+ hTupDesc, attNull);
}
- returnVal = (Datum)fmgr_array_args(FIgetProcOid(fInfo),
- FIgetnArgs(fInfo),
- (char **) attData,
- &isNull);
- pfree(attData);
- *attNull = FALSE;
- }else {
- returnVal = (Datum) heap_getattr(tuple, buffer, attrNums[attOff],
- hTupDesc, attNull);
- }
- return returnVal;
+ return returnVal;
}
diff --git a/src/backend/access/index/istrat.c b/src/backend/access/index/istrat.c
index 5c143f0aa5f..35158c22170 100644
--- a/src/backend/access/index/istrat.c
+++ b/src/backend/access/index/istrat.c
@@ -1,689 +1,730 @@
/*-------------------------------------------------------------------------
*
* istrat.c--
- * index scan strategy manipulation code and index strategy manipulation
- * operator code.
+ * index scan strategy manipulation code and index strategy manipulation
+ * operator code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.9 1997/08/22 16:48:14 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.10 1997/09/07 04:38:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <catalog/pg_proc.h>
#include <catalog/pg_operator.h>
#include <catalog/catname.h>
#include <catalog/pg_index.h>
#include <catalog/pg_amop.h>
#include <catalog/pg_amproc.h>
-#include <utils/memutils.h> /* could have been access/itup.h */
+#include <utils/memutils.h> /* could have been access/itup.h */
#include <access/heapam.h>
#include <access/istrat.h>
#include <fmgr.h>
-#ifndef NO_ASSERT_CHECKING
-static bool StrategyEvaluationIsValid(StrategyEvaluation evaluation);
-static bool StrategyExpressionIsValid(StrategyExpression expression,
- StrategyNumber maxStrategy);
-static ScanKey StrategyMapGetScanKeyEntry(StrategyMap map,
- StrategyNumber strategyNumber);
-static bool StrategyOperatorIsValid(StrategyOperator operator,
- StrategyNumber maxStrategy);
-static bool StrategyTermIsValid(StrategyTerm term,
- StrategyNumber maxStrategy);
+#ifndef NO_ASSERT_CHECKING
+static bool StrategyEvaluationIsValid(StrategyEvaluation evaluation);
+static bool
+StrategyExpressionIsValid(StrategyExpression expression,
+ StrategyNumber maxStrategy);
+static ScanKey
+StrategyMapGetScanKeyEntry(StrategyMap map,
+ StrategyNumber strategyNumber);
+static bool
+StrategyOperatorIsValid(StrategyOperator operator,
+ StrategyNumber maxStrategy);
+static bool
+StrategyTermIsValid(StrategyTerm term,
+ StrategyNumber maxStrategy);
+
#endif
/* ----------------------------------------------------------------
- * misc strategy support routines
+ * misc strategy support routines
* ----------------------------------------------------------------
*/
-
-/*
- * StrategyNumberIsValid
- * StrategyNumberIsInBounds
- * StrategyMapIsValid
- * StrategyTransformMapIsValid
- * IndexStrategyIsValid
+
+/*
+ * StrategyNumberIsValid
+ * StrategyNumberIsInBounds
+ * StrategyMapIsValid
+ * StrategyTransformMapIsValid
+ * IndexStrategyIsValid
*
- * ... are now macros in istrat.h -cim 4/27/91
+ * ... are now macros in istrat.h -cim 4/27/91
*/
-
+
/*
* StrategyMapGetScanKeyEntry --
- * Returns a scan key entry of a index strategy mapping member.
+ * Returns a scan key entry of a index strategy mapping member.
*
* Note:
- * Assumes that the index strategy mapping is valid.
- * Assumes that the index strategy number is valid.
- * Bounds checking should be done outside this routine.
+ * Assumes that the index strategy mapping is valid.
+ * Assumes that the index strategy number is valid.
+ * Bounds checking should be done outside this routine.
*/
-static ScanKey
+static ScanKey
StrategyMapGetScanKeyEntry(StrategyMap map,
- StrategyNumber strategyNumber)
+ StrategyNumber strategyNumber)
{
- Assert(StrategyMapIsValid(map));
- Assert(StrategyNumberIsValid(strategyNumber));
- return (&map->entry[strategyNumber - 1]);
+ Assert(StrategyMapIsValid(map));
+ Assert(StrategyNumberIsValid(strategyNumber));
+ return (&map->entry[strategyNumber - 1]);
}
/*
* IndexStrategyGetStrategyMap --
- * Returns an index strategy mapping of an index strategy.
+ * Returns an index strategy mapping of an index strategy.
*
* Note:
- * Assumes that the index strategy is valid.
- * Assumes that the number of index strategies is valid.
- * Bounds checking should be done outside this routine.
+ * Assumes that the index strategy is valid.
+ * Assumes that the number of index strategies is valid.
+ * Bounds checking should be done outside this routine.
*/
StrategyMap
IndexStrategyGetStrategyMap(IndexStrategy indexStrategy,
- StrategyNumber maxStrategyNum,
- AttrNumber attrNum)
+ StrategyNumber maxStrategyNum,
+ AttrNumber attrNum)
{
- Assert(IndexStrategyIsValid(indexStrategy));
- Assert(StrategyNumberIsValid(maxStrategyNum));
- Assert(AttributeNumberIsValid(attrNum));
-
- maxStrategyNum = AMStrategies(maxStrategyNum); /* XXX */
- return
- &indexStrategy->strategyMapData[maxStrategyNum * (attrNum - 1)];
+ Assert(IndexStrategyIsValid(indexStrategy));
+ Assert(StrategyNumberIsValid(maxStrategyNum));
+ Assert(AttributeNumberIsValid(attrNum));
+
+ maxStrategyNum = AMStrategies(maxStrategyNum); /* XXX */
+ return
+ &indexStrategy->strategyMapData[maxStrategyNum * (attrNum - 1)];
}
/*
* AttributeNumberGetIndexStrategySize --
- * Computes the size of an index strategy.
+ * Computes the size of an index strategy.
*/
Size
AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber,
- StrategyNumber maxStrategyNumber)
+ StrategyNumber maxStrategyNumber)
{
- maxStrategyNumber = AMStrategies(maxStrategyNumber); /* XXX */
- return
- maxAttributeNumber * maxStrategyNumber * sizeof (ScanKeyData);
+ maxStrategyNumber = AMStrategies(maxStrategyNumber); /* XXX */
+ return
+ maxAttributeNumber * maxStrategyNumber * sizeof(ScanKeyData);
}
-#ifndef NO_ASSERT_CHECKING
-/*
+#ifndef NO_ASSERT_CHECKING
+/*
* StrategyTransformMapIsValid is now a macro in istrat.h -cim 4/27/91
*/
/* ----------------
- * StrategyOperatorIsValid
+ * StrategyOperatorIsValid
* ----------------
*/
-static bool
+static bool
StrategyOperatorIsValid(StrategyOperator operator,
- StrategyNumber maxStrategy)
+ StrategyNumber maxStrategy)
{
- return (bool)
+ return (bool)
(PointerIsValid(operator) &&
StrategyNumberIsInBounds(operator->strategy, maxStrategy) &&
!(operator->flags & ~(SK_NEGATE | SK_COMMUTE)));
}
/* ----------------
- * StrategyTermIsValid
+ * StrategyTermIsValid
* ----------------
*/
-static bool
+static bool
StrategyTermIsValid(StrategyTerm term,
- StrategyNumber maxStrategy)
+ StrategyNumber maxStrategy)
{
- Index index;
-
- if (! PointerIsValid(term) || term->degree == 0)
- return false;
-
- for (index = 0; index < term->degree; index += 1) {
- if (! StrategyOperatorIsValid(&term->operatorData[index],
- maxStrategy)) {
-
- return false;
+ Index index;
+
+ if (!PointerIsValid(term) || term->degree == 0)
+ return false;
+
+ for (index = 0; index < term->degree; index += 1)
+ {
+ if (!StrategyOperatorIsValid(&term->operatorData[index],
+ maxStrategy))
+ {
+
+ return false;
+ }
}
- }
-
- return true;
+
+ return true;
}
/* ----------------
- * StrategyExpressionIsValid
+ * StrategyExpressionIsValid
* ----------------
*/
-static bool
+static bool
StrategyExpressionIsValid(StrategyExpression expression,
- StrategyNumber maxStrategy)
+ StrategyNumber maxStrategy)
{
- StrategyTerm *termP;
-
- if (!PointerIsValid(expression))
- return true;
-
- if (!StrategyTermIsValid(expression->term[0], maxStrategy))
- return false;
-
- termP = &expression->term[1];
- while (StrategyTermIsValid(*termP, maxStrategy))
- termP += 1;
-
- return (bool)
- (! PointerIsValid(*termP));
+ StrategyTerm *termP;
+
+ if (!PointerIsValid(expression))
+ return true;
+
+ if (!StrategyTermIsValid(expression->term[0], maxStrategy))
+ return false;
+
+ termP = &expression->term[1];
+ while (StrategyTermIsValid(*termP, maxStrategy))
+ termP += 1;
+
+ return (bool)
+ (!PointerIsValid(*termP));
}
/* ----------------
- * StrategyEvaluationIsValid
+ * StrategyEvaluationIsValid
* ----------------
*/
-static bool
+static bool
StrategyEvaluationIsValid(StrategyEvaluation evaluation)
{
- Index index;
-
- if (! PointerIsValid(evaluation) ||
- ! StrategyNumberIsValid(evaluation->maxStrategy) ||
- ! StrategyTransformMapIsValid(evaluation->negateTransform) ||
- ! StrategyTransformMapIsValid(evaluation->commuteTransform) ||
- ! StrategyTransformMapIsValid(evaluation->negateCommuteTransform)) {
-
- return false;
- }
-
- for (index = 0; index < evaluation->maxStrategy; index += 1) {
- if (! StrategyExpressionIsValid(evaluation->expression[index],
- evaluation->maxStrategy)) {
-
- return false;
+ Index index;
+
+ if (!PointerIsValid(evaluation) ||
+ !StrategyNumberIsValid(evaluation->maxStrategy) ||
+ !StrategyTransformMapIsValid(evaluation->negateTransform) ||
+ !StrategyTransformMapIsValid(evaluation->commuteTransform) ||
+ !StrategyTransformMapIsValid(evaluation->negateCommuteTransform))
+ {
+
+ return false;
}
- }
- return true;
+
+ for (index = 0; index < evaluation->maxStrategy; index += 1)
+ {
+ if (!StrategyExpressionIsValid(evaluation->expression[index],
+ evaluation->maxStrategy))
+ {
+
+ return false;
+ }
+ }
+ return true;
}
+
#endif
/* ----------------
- * StrategyTermEvaluate
+ * StrategyTermEvaluate
* ----------------
*/
-static bool
+static bool
StrategyTermEvaluate(StrategyTerm term,
- StrategyMap map,
- Datum left,
- Datum right)
+ StrategyMap map,
+ Datum left,
+ Datum right)
{
- Index index;
- long tmpres = 0;
- bool result = 0;
- StrategyOperator operator;
- ScanKey entry;
-
- for (index = 0, operator = &term->operatorData[0];
- index < term->degree; index += 1, operator += 1) {
-
- entry = &map->entry[operator->strategy - 1];
-
- Assert(RegProcedureIsValid(entry->sk_procedure));
-
- switch (operator->flags ^ entry->sk_flags) {
- case 0x0:
- tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
- left, right);
- break;
-
- case SK_NEGATE:
- tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure,
- left, right);
- break;
-
- case SK_COMMUTE:
- tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
- right, left);
- break;
-
- case SK_NEGATE | SK_COMMUTE:
- tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure,
- right, left);
- break;
-
- default:
- elog(FATAL, "StrategyTermEvaluate: impossible case %d",
- operator->flags ^ entry->sk_flags);
+ Index index;
+ long tmpres = 0;
+ bool result = 0;
+ StrategyOperator operator;
+ ScanKey entry;
+
+ for (index = 0, operator = &term->operatorData[0];
+ index < term->degree; index += 1, operator += 1)
+ {
+
+ entry = &map->entry[operator->strategy - 1];
+
+ Assert(RegProcedureIsValid(entry->sk_procedure));
+
+ switch (operator->flags ^ entry->sk_flags)
+ {
+ case 0x0:
+ tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
+ left, right);
+ break;
+
+ case SK_NEGATE:
+ tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure,
+ left, right);
+ break;
+
+ case SK_COMMUTE:
+ tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
+ right, left);
+ break;
+
+ case SK_NEGATE | SK_COMMUTE:
+ tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure,
+ right, left);
+ break;
+
+ default:
+ elog(FATAL, "StrategyTermEvaluate: impossible case %d",
+ operator->flags ^ entry->sk_flags);
+ }
+
+ result = (bool) tmpres;
+ if (!result)
+ return result;
}
-
- result = (bool) tmpres;
- if (!result)
- return result;
- }
-
- return result;
+
+ return result;
}
/* ----------------
- * RelationGetStrategy
+ * RelationGetStrategy
* ----------------
*/
StrategyNumber
RelationGetStrategy(Relation relation,
- AttrNumber attributeNumber,
- StrategyEvaluation evaluation,
- RegProcedure procedure)
+ AttrNumber attributeNumber,
+ StrategyEvaluation evaluation,
+ RegProcedure procedure)
{
- StrategyNumber strategy;
- StrategyMap strategyMap;
- ScanKey entry;
- Index index;
- int numattrs;
-
- Assert(RelationIsValid(relation));
- numattrs = RelationGetNumberOfAttributes(relation);
-
- Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */
- Assert(AttributeNumberIsValid(attributeNumber));
- Assert( (attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
-
- Assert(StrategyEvaluationIsValid(evaluation));
- Assert(RegProcedureIsValid(procedure));
-
- strategyMap =
- IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
- evaluation->maxStrategy,
- attributeNumber);
-
- /* get a strategy number for the procedure ignoring flags for now */
- for (index = 0; index < evaluation->maxStrategy; index += 1) {
- if (strategyMap->entry[index].sk_procedure == procedure) {
- break;
+ StrategyNumber strategy;
+ StrategyMap strategyMap;
+ ScanKey entry;
+ Index index;
+ int numattrs;
+
+ Assert(RelationIsValid(relation));
+ numattrs = RelationGetNumberOfAttributes(relation);
+
+ Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */
+ Assert(AttributeNumberIsValid(attributeNumber));
+ Assert((attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
+
+ Assert(StrategyEvaluationIsValid(evaluation));
+ Assert(RegProcedureIsValid(procedure));
+
+ strategyMap =
+ IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
+ evaluation->maxStrategy,
+ attributeNumber);
+
+ /* get a strategy number for the procedure ignoring flags for now */
+ for (index = 0; index < evaluation->maxStrategy; index += 1)
+ {
+ if (strategyMap->entry[index].sk_procedure == procedure)
+ {
+ break;
+ }
}
- }
-
- if (index == evaluation->maxStrategy)
- return InvalidStrategy;
-
- strategy = 1 + index;
- entry = StrategyMapGetScanKeyEntry(strategyMap, strategy);
-
- Assert(!(entry->sk_flags & ~(SK_NEGATE | SK_COMMUTE)));
-
- switch (entry->sk_flags & (SK_NEGATE | SK_COMMUTE)) {
- case 0x0:
- return strategy;
-
- case SK_NEGATE:
- strategy = evaluation->negateTransform->strategy[strategy - 1];
- break;
-
- case SK_COMMUTE:
- strategy = evaluation->commuteTransform->strategy[strategy - 1];
- break;
-
- case SK_NEGATE | SK_COMMUTE:
- strategy = evaluation->negateCommuteTransform->strategy[strategy - 1];
- break;
-
- default:
- elog(FATAL, "RelationGetStrategy: impossible case %d", entry->sk_flags);
- }
-
-
- if (! StrategyNumberIsInBounds(strategy, evaluation->maxStrategy)) {
- if (! StrategyNumberIsValid(strategy)) {
- elog(WARN, "RelationGetStrategy: corrupted evaluation");
+
+ if (index == evaluation->maxStrategy)
+ return InvalidStrategy;
+
+ strategy = 1 + index;
+ entry = StrategyMapGetScanKeyEntry(strategyMap, strategy);
+
+ Assert(!(entry->sk_flags & ~(SK_NEGATE | SK_COMMUTE)));
+
+ switch (entry->sk_flags & (SK_NEGATE | SK_COMMUTE))
+ {
+ case 0x0:
+ return strategy;
+
+ case SK_NEGATE:
+ strategy = evaluation->negateTransform->strategy[strategy - 1];
+ break;
+
+ case SK_COMMUTE:
+ strategy = evaluation->commuteTransform->strategy[strategy - 1];
+ break;
+
+ case SK_NEGATE | SK_COMMUTE:
+ strategy = evaluation->negateCommuteTransform->strategy[strategy - 1];
+ break;
+
+ default:
+ elog(FATAL, "RelationGetStrategy: impossible case %d", entry->sk_flags);
}
- }
-
- return strategy;
+
+
+ if (!StrategyNumberIsInBounds(strategy, evaluation->maxStrategy))
+ {
+ if (!StrategyNumberIsValid(strategy))
+ {
+ elog(WARN, "RelationGetStrategy: corrupted evaluation");
+ }
+ }
+
+ return strategy;
}
/* ----------------
- * RelationInvokeStrategy
+ * RelationInvokeStrategy
* ----------------
*/
-bool /* XXX someday, this may return Datum */
+bool /* XXX someday, this may return Datum */
RelationInvokeStrategy(Relation relation,
- StrategyEvaluation evaluation,
- AttrNumber attributeNumber,
- StrategyNumber strategy,
- Datum left,
- Datum right)
+ StrategyEvaluation evaluation,
+ AttrNumber attributeNumber,
+ StrategyNumber strategy,
+ Datum left,
+ Datum right)
{
- StrategyNumber newStrategy;
- StrategyMap strategyMap;
- ScanKey entry;
- StrategyTermData termData;
- int numattrs;
-
- Assert(RelationIsValid(relation));
- Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */
- numattrs = RelationGetNumberOfAttributes(relation);
-
- Assert(StrategyEvaluationIsValid(evaluation));
- Assert(AttributeNumberIsValid(attributeNumber));
- Assert( (attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
-
- Assert(StrategyNumberIsInBounds(strategy, evaluation->maxStrategy));
-
- termData.degree = 1;
-
- strategyMap =
- IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
- evaluation->maxStrategy,
- attributeNumber);
-
- entry = StrategyMapGetScanKeyEntry(strategyMap, strategy);
-
- if (RegProcedureIsValid(entry->sk_procedure)) {
- termData.operatorData[0].strategy = strategy;
- termData.operatorData[0].flags = 0x0;
-
- return
- StrategyTermEvaluate(&termData, strategyMap, left, right);
- }
-
-
- newStrategy = evaluation->negateTransform->strategy[strategy - 1];
- if (newStrategy != strategy && StrategyNumberIsValid(newStrategy)) {
-
- entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
-
- if (RegProcedureIsValid(entry->sk_procedure)) {
- termData.operatorData[0].strategy = newStrategy;
- termData.operatorData[0].flags = SK_NEGATE;
-
- return
- StrategyTermEvaluate(&termData, strategyMap, left, right);
+ StrategyNumber newStrategy;
+ StrategyMap strategyMap;
+ ScanKey entry;
+ StrategyTermData termData;
+ int numattrs;
+
+ Assert(RelationIsValid(relation));
+ Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */
+ numattrs = RelationGetNumberOfAttributes(relation);
+
+ Assert(StrategyEvaluationIsValid(evaluation));
+ Assert(AttributeNumberIsValid(attributeNumber));
+ Assert((attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
+
+ Assert(StrategyNumberIsInBounds(strategy, evaluation->maxStrategy));
+
+ termData.degree = 1;
+
+ strategyMap =
+ IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
+ evaluation->maxStrategy,
+ attributeNumber);
+
+ entry = StrategyMapGetScanKeyEntry(strategyMap, strategy);
+
+ if (RegProcedureIsValid(entry->sk_procedure))
+ {
+ termData.operatorData[0].strategy = strategy;
+ termData.operatorData[0].flags = 0x0;
+
+ return
+ StrategyTermEvaluate(&termData, strategyMap, left, right);
}
- }
-
- newStrategy = evaluation->commuteTransform->strategy[strategy - 1];
- if (newStrategy != strategy && StrategyNumberIsValid(newStrategy)) {
-
- entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
-
- if (RegProcedureIsValid(entry->sk_procedure)) {
- termData.operatorData[0].strategy = newStrategy;
- termData.operatorData[0].flags = SK_COMMUTE;
-
- return
- StrategyTermEvaluate(&termData, strategyMap, left, right);
+
+
+ newStrategy = evaluation->negateTransform->strategy[strategy - 1];
+ if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
+ {
+
+ entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
+
+ if (RegProcedureIsValid(entry->sk_procedure))
+ {
+ termData.operatorData[0].strategy = newStrategy;
+ termData.operatorData[0].flags = SK_NEGATE;
+
+ return
+ StrategyTermEvaluate(&termData, strategyMap, left, right);
+ }
}
- }
-
- newStrategy = evaluation->negateCommuteTransform->strategy[strategy - 1];
- if (newStrategy != strategy && StrategyNumberIsValid(newStrategy)) {
-
- entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
-
- if (RegProcedureIsValid(entry->sk_procedure)) {
- termData.operatorData[0].strategy = newStrategy;
- termData.operatorData[0].flags = SK_NEGATE | SK_COMMUTE;
-
- return
- StrategyTermEvaluate(&termData, strategyMap, left, right);
+
+ newStrategy = evaluation->commuteTransform->strategy[strategy - 1];
+ if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
+ {
+
+ entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
+
+ if (RegProcedureIsValid(entry->sk_procedure))
+ {
+ termData.operatorData[0].strategy = newStrategy;
+ termData.operatorData[0].flags = SK_COMMUTE;
+
+ return
+ StrategyTermEvaluate(&termData, strategyMap, left, right);
+ }
}
- }
-
- if (PointerIsValid(evaluation->expression[strategy - 1])) {
- StrategyTerm *termP;
-
- termP = &evaluation->expression[strategy - 1]->term[0];
- while (PointerIsValid(*termP)) {
- Index index;
-
- for (index = 0; index < (*termP)->degree; index += 1) {
- entry = StrategyMapGetScanKeyEntry(strategyMap,
- (*termP)->operatorData[index].strategy);
-
- if (! RegProcedureIsValid(entry->sk_procedure)) {
- break;
+
+ newStrategy = evaluation->negateCommuteTransform->strategy[strategy - 1];
+ if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
+ {
+
+ entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
+
+ if (RegProcedureIsValid(entry->sk_procedure))
+ {
+ termData.operatorData[0].strategy = newStrategy;
+ termData.operatorData[0].flags = SK_NEGATE | SK_COMMUTE;
+
+ return
+ StrategyTermEvaluate(&termData, strategyMap, left, right);
}
- }
-
- if (index == (*termP)->degree) {
- return
- StrategyTermEvaluate(*termP, strategyMap, left, right);
- }
-
- termP += 1;
}
- }
-
- elog(WARN, "RelationInvokeStrategy: cannot evaluate strategy %d",
- strategy);
- /* not reached, just to make compiler happy */
- return FALSE;
+ if (PointerIsValid(evaluation->expression[strategy - 1]))
+ {
+ StrategyTerm *termP;
+
+ termP = &evaluation->expression[strategy - 1]->term[0];
+ while (PointerIsValid(*termP))
+ {
+ Index index;
+
+ for (index = 0; index < (*termP)->degree; index += 1)
+ {
+ entry = StrategyMapGetScanKeyEntry(strategyMap,
+ (*termP)->operatorData[index].strategy);
+
+ if (!RegProcedureIsValid(entry->sk_procedure))
+ {
+ break;
+ }
+ }
+
+ if (index == (*termP)->degree)
+ {
+ return
+ StrategyTermEvaluate(*termP, strategyMap, left, right);
+ }
+
+ termP += 1;
+ }
+ }
+
+ elog(WARN, "RelationInvokeStrategy: cannot evaluate strategy %d",
+ strategy);
+
+ /* not reached, just to make compiler happy */
+ return FALSE;
}
/* ----------------
- * OperatorRelationFillScanKeyEntry
+ * OperatorRelationFillScanKeyEntry
* ----------------
*/
static void
OperatorRelationFillScanKeyEntry(Relation operatorRelation,
- Oid operatorObjectId,
- ScanKey entry)
+ Oid operatorObjectId,
+ ScanKey entry)
{
- HeapScanDesc scan;
- ScanKeyData scanKeyData;
- HeapTuple tuple;
-
- ScanKeyEntryInitialize(&scanKeyData, 0,
- ObjectIdAttributeNumber,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(operatorObjectId));
-
- scan = heap_beginscan(operatorRelation, false, NowTimeQual,
- 1, &scanKeyData);
-
- tuple = heap_getnext(scan, false, (Buffer *)NULL);
- if (! HeapTupleIsValid(tuple)) {
- elog(WARN, "OperatorObjectIdFillScanKeyEntry: unknown operator %lu",
- (uint32) operatorObjectId);
- }
-
- entry->sk_flags = 0;
- entry->sk_procedure =
- ((OperatorTupleForm) GETSTRUCT(tuple))->oprcode;
- fmgr_info(entry->sk_procedure, &entry->sk_func, &entry->sk_nargs);
-
- if (! RegProcedureIsValid(entry->sk_procedure)) {
- elog(WARN,
- "OperatorObjectIdFillScanKeyEntry: no procedure for operator %lu",
- (uint32) operatorObjectId);
- }
-
- heap_endscan(scan);
+ HeapScanDesc scan;
+ ScanKeyData scanKeyData;
+ HeapTuple tuple;
+
+ ScanKeyEntryInitialize(&scanKeyData, 0,
+ ObjectIdAttributeNumber,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(operatorObjectId));
+
+ scan = heap_beginscan(operatorRelation, false, NowTimeQual,
+ 1, &scanKeyData);
+
+ tuple = heap_getnext(scan, false, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN, "OperatorObjectIdFillScanKeyEntry: unknown operator %lu",
+ (uint32) operatorObjectId);
+ }
+
+ entry->sk_flags = 0;
+ entry->sk_procedure =
+ ((OperatorTupleForm) GETSTRUCT(tuple))->oprcode;
+ fmgr_info(entry->sk_procedure, &entry->sk_func, &entry->sk_nargs);
+
+ if (!RegProcedureIsValid(entry->sk_procedure))
+ {
+ elog(WARN,
+ "OperatorObjectIdFillScanKeyEntry: no procedure for operator %lu",
+ (uint32) operatorObjectId);
+ }
+
+ heap_endscan(scan);
}
/*
* IndexSupportInitialize --
- * Initializes an index strategy and associated support procedures.
+ * Initializes an index strategy and associated support procedures.
*/
void
IndexSupportInitialize(IndexStrategy indexStrategy,
- RegProcedure *indexSupport,
- Oid indexObjectId,
- Oid accessMethodObjectId,
- StrategyNumber maxStrategyNumber,
- StrategyNumber maxSupportNumber,
- AttrNumber maxAttributeNumber)
+ RegProcedure * indexSupport,
+ Oid indexObjectId,
+ Oid accessMethodObjectId,
+ StrategyNumber maxStrategyNumber,
+ StrategyNumber maxSupportNumber,
+ AttrNumber maxAttributeNumber)
{
- Relation relation;
- Relation operatorRelation;
- HeapScanDesc scan;
- HeapTuple tuple;
- ScanKeyData entry[2];
- StrategyMap map;
- AttrNumber attributeNumber;
- int attributeIndex;
- Oid operatorClassObjectId[ MaxIndexAttributeNumber ];
-
- maxStrategyNumber = AMStrategies(maxStrategyNumber);
-
- ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_index_indexrelid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(indexObjectId));
-
- relation = heap_openr(IndexRelationName);
- scan = heap_beginscan(relation, false, NowTimeQual, 1, entry);
- tuple = heap_getnext(scan, 0, (Buffer *)NULL);
- if (! HeapTupleIsValid(tuple))
- elog(WARN, "IndexSupportInitialize: corrupted catalogs");
-
- /*
- * XXX note that the following assumes the INDEX tuple is well formed and
- * that the key[] and class[] are 0 terminated.
- */
- for (attributeIndex=0; attributeIndex<maxAttributeNumber; attributeIndex++)
+ Relation relation;
+ Relation operatorRelation;
+ HeapScanDesc scan;
+ HeapTuple tuple;
+ ScanKeyData entry[2];
+ StrategyMap map;
+ AttrNumber attributeNumber;
+ int attributeIndex;
+ Oid operatorClassObjectId[MaxIndexAttributeNumber];
+
+ maxStrategyNumber = AMStrategies(maxStrategyNumber);
+
+ ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_index_indexrelid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(indexObjectId));
+
+ relation = heap_openr(IndexRelationName);
+ scan = heap_beginscan(relation, false, NowTimeQual, 1, entry);
+ tuple = heap_getnext(scan, 0, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ elog(WARN, "IndexSupportInitialize: corrupted catalogs");
+
+ /*
+ * XXX note that the following assumes the INDEX tuple is well formed
+ * and that the key[] and class[] are 0 terminated.
+ */
+ for (attributeIndex = 0; attributeIndex < maxAttributeNumber; attributeIndex++)
{
- IndexTupleForm iform;
-
- iform = (IndexTupleForm) GETSTRUCT(tuple);
-
- if (!OidIsValid(iform->indkey[attributeIndex])) {
- if (attributeIndex == 0) {
- elog(WARN, "IndexSupportInitialize: no pg_index tuple");
+ IndexTupleForm iform;
+
+ iform = (IndexTupleForm) GETSTRUCT(tuple);
+
+ if (!OidIsValid(iform->indkey[attributeIndex]))
+ {
+ if (attributeIndex == 0)
+ {
+ elog(WARN, "IndexSupportInitialize: no pg_index tuple");
+ }
+ break;
}
- break;
- }
-
- operatorClassObjectId[attributeIndex]
- = iform->indclass[attributeIndex];
+
+ operatorClassObjectId[attributeIndex]
+ = iform->indclass[attributeIndex];
}
-
- heap_endscan(scan);
- heap_close(relation);
-
- /* if support routines exist for this access method, load them */
- if (maxSupportNumber > 0) {
-
- ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amproc_amid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(accessMethodObjectId));
-
- ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amproc_amopclaid,
- ObjectIdEqualRegProcedure, 0);
-
-/* relation = heap_openr(Name_pg_amproc); */
- relation = heap_openr(AccessMethodProcedureRelationName);
-
-
+
+ heap_endscan(scan);
+ heap_close(relation);
+
+ /* if support routines exist for this access method, load them */
+ if (maxSupportNumber > 0)
+ {
+
+ ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amproc_amid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(accessMethodObjectId));
+
+ ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amproc_amopclaid,
+ ObjectIdEqualRegProcedure, 0);
+
+/* relation = heap_openr(Name_pg_amproc); */
+ relation = heap_openr(AccessMethodProcedureRelationName);
+
+
+ for (attributeNumber = maxAttributeNumber; attributeNumber > 0;
+ attributeNumber--)
+ {
+
+ int16 support;
+ Form_pg_amproc form;
+ RegProcedure *loc;
+
+ loc = &indexSupport[((attributeNumber - 1) * maxSupportNumber)];
+
+ for (support = maxSupportNumber; --support >= 0;)
+ {
+ loc[support] = InvalidOid;
+ }
+
+ entry[1].sk_argument =
+ ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]);
+
+ scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
+
+ while (tuple = heap_getnext(scan, 0, (Buffer *) NULL),
+ HeapTupleIsValid(tuple))
+ {
+
+ form = (Form_pg_amproc) GETSTRUCT(tuple);
+ loc[(form->amprocnum - 1)] = form->amproc;
+ }
+
+ heap_endscan(scan);
+ }
+ heap_close(relation);
+ }
+
+ ScanKeyEntryInitialize(&entry[0], 0,
+ Anum_pg_amop_amopid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(accessMethodObjectId));
+
+ ScanKeyEntryInitialize(&entry[1], 0,
+ Anum_pg_amop_amopclaid,
+ ObjectIdEqualRegProcedure, 0);
+
+ relation = heap_openr(AccessMethodOperatorRelationName);
+ operatorRelation = heap_openr(OperatorRelationName);
+
for (attributeNumber = maxAttributeNumber; attributeNumber > 0;
- attributeNumber--) {
-
- int16 support;
- Form_pg_amproc form;
- RegProcedure *loc;
-
- loc = &indexSupport[((attributeNumber - 1) * maxSupportNumber)];
-
- for (support = maxSupportNumber; --support >= 0; ) {
- loc[support] = InvalidOid;
- }
-
- entry[1].sk_argument =
- ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]);
-
- scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
-
- while (tuple = heap_getnext(scan, 0, (Buffer *)NULL),
- HeapTupleIsValid(tuple)) {
-
- form = (Form_pg_amproc) GETSTRUCT(tuple);
- loc[(form->amprocnum - 1)] = form->amproc;
- }
-
- heap_endscan(scan);
+ attributeNumber--)
+ {
+
+ StrategyNumber strategy;
+
+ entry[1].sk_argument =
+ ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]);
+
+ map = IndexStrategyGetStrategyMap(indexStrategy,
+ maxStrategyNumber,
+ attributeNumber);
+
+ for (strategy = 1; strategy <= maxStrategyNumber; strategy++)
+ ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy));
+
+ scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
+
+ while (tuple = heap_getnext(scan, 0, (Buffer *) NULL),
+ HeapTupleIsValid(tuple))
+ {
+ Form_pg_amop form;
+
+ form = (Form_pg_amop) GETSTRUCT(tuple);
+
+ OperatorRelationFillScanKeyEntry(operatorRelation,
+ form->amopopr,
+ StrategyMapGetScanKeyEntry(map, form->amopstrategy));
+ }
+
+ heap_endscan(scan);
}
+
+ heap_close(operatorRelation);
heap_close(relation);
- }
-
- ScanKeyEntryInitialize(&entry[0], 0,
- Anum_pg_amop_amopid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(accessMethodObjectId));
-
- ScanKeyEntryInitialize(&entry[1], 0,
- Anum_pg_amop_amopclaid,
- ObjectIdEqualRegProcedure, 0);
-
- relation = heap_openr(AccessMethodOperatorRelationName);
- operatorRelation = heap_openr(OperatorRelationName);
-
- for (attributeNumber = maxAttributeNumber; attributeNumber > 0;
- attributeNumber--) {
-
- StrategyNumber strategy;
-
- entry[1].sk_argument =
- ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]);
-
- map = IndexStrategyGetStrategyMap(indexStrategy,
- maxStrategyNumber,
- attributeNumber);
-
- for (strategy = 1; strategy <= maxStrategyNumber; strategy++)
- ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy));
-
- scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
-
- while (tuple = heap_getnext(scan, 0, (Buffer *)NULL),
- HeapTupleIsValid(tuple)) {
- Form_pg_amop form;
-
- form = (Form_pg_amop) GETSTRUCT(tuple);
-
- OperatorRelationFillScanKeyEntry(operatorRelation,
- form->amopopr,
- StrategyMapGetScanKeyEntry(map, form->amopstrategy));
- }
-
- heap_endscan(scan);
- }
-
- heap_close(operatorRelation);
- heap_close(relation);
}
/* ----------------
- * IndexStrategyDisplay
+ * IndexStrategyDisplay
* ----------------
*/
#ifdef ISTRATDEBUG
int
IndexStrategyDisplay(IndexStrategy indexStrategy,
- StrategyNumber numberOfStrategies,
- int numberOfAttributes)
+ StrategyNumber numberOfStrategies,
+ int numberOfAttributes)
{
- StrategyMap strategyMap;
- AttrNumber attributeNumber;
- StrategyNumber strategyNumber;
-
- for (attributeNumber = 1; attributeNumber <= numberOfAttributes;
- attributeNumber += 1) {
-
- strategyMap = IndexStrategyGetStrategyMap(indexStrategy,
- numberOfStrategies,
- attributeNumber);
-
- for (strategyNumber = 1;
- strategyNumber <= AMStrategies(numberOfStrategies);
- strategyNumber += 1) {
-
- printf(":att %d\t:str %d\t:opr 0x%x(%d)\n",
- attributeNumber, strategyNumber,
- strategyMap->entry[strategyNumber - 1].sk_procedure,
- strategyMap->entry[strategyNumber - 1].sk_procedure);
+ StrategyMap strategyMap;
+ AttrNumber attributeNumber;
+ StrategyNumber strategyNumber;
+
+ for (attributeNumber = 1; attributeNumber <= numberOfAttributes;
+ attributeNumber += 1)
+ {
+
+ strategyMap = IndexStrategyGetStrategyMap(indexStrategy,
+ numberOfStrategies,
+ attributeNumber);
+
+ for (strategyNumber = 1;
+ strategyNumber <= AMStrategies(numberOfStrategies);
+ strategyNumber += 1)
+ {
+
+ printf(":att %d\t:str %d\t:opr 0x%x(%d)\n",
+ attributeNumber, strategyNumber,
+ strategyMap->entry[strategyNumber - 1].sk_procedure,
+ strategyMap->entry[strategyNumber - 1].sk_procedure);
+ }
}
- }
}
-#endif /* defined(ISTRATDEBUG) */
-
+#endif /* defined(ISTRATDEBUG) */
diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c
index f005509be07..0312bbb69d7 100644
--- a/src/backend/access/nbtree/nbtcompare.c
+++ b/src/backend/access/nbtree/nbtcompare.c
@@ -1,22 +1,22 @@
/*-------------------------------------------------------------------------
*
* nbtcompare.c--
- * Comparison functions for btree access method.
+ * Comparison functions for btree access method.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.10 1997/06/11 05:20:05 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.11 1997/09/07 04:38:39 momjian Exp $
*
- * NOTES
- * These functions are stored in pg_amproc. For each operator class
- * defined on btrees, they compute
+ * NOTES
+ * These functions are stored in pg_amproc. For each operator class
+ * defined on btrees, they compute
*
- * compare(a, b):
- * < 0 if a < b,
- * = 0 if a == b,
- * > 0 if a > b.
+ * compare(a, b):
+ * < 0 if a < b,
+ * = 0 if a == b,
+ * > 0 if a > b.
*-------------------------------------------------------------------------
*/
@@ -30,168 +30,171 @@
int32
btint2cmp(int16 a, int16 b)
{
- return ((int32) (a - b));
+ return ((int32) (a - b));
}
int32
btint4cmp(int32 a, int32 b)
{
- return (a - b);
+ return (a - b);
}
int32
btint24cmp(int16 a, int32 b)
{
- return (((int32) a) - b);
+ return (((int32) a) - b);
}
int32
btint42cmp(int32 a, int16 b)
{
- return (a - ((int32) b));
+ return (a - ((int32) b));
}
int32
btfloat4cmp(float32 a, float32 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
btfloat8cmp(float64 a, float64 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
btoidcmp(Oid a, Oid 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
btabstimecmp(AbsoluteTime a, AbsoluteTime b)
{
- if (AbsoluteTimeIsBefore(a, b))
- return (-1);
- else if (AbsoluteTimeIsBefore(b, a))
- return (1);
- else
- return (0);
+ if (AbsoluteTimeIsBefore(a, b))
+ return (-1);
+ else if (AbsoluteTimeIsBefore(b, a))
+ return (1);
+ else
+ return (0);
}
int32
btcharcmp(char a, char b)
{
- return ((int32) ((uint8)a - (uint8)b));
+ return ((int32) ((uint8) a - (uint8) b));
}
int32
btchar2cmp(uint16 a, uint16 b)
{
- return (strncmp((char *) &a, (char *) &b, 2));
+ return (strncmp((char *) &a, (char *) &b, 2));
}
int32
btchar4cmp(uint32 a, uint32 b)
{
- return (strncmp((char *) &a, (char *) &b, 4));
+ return (strncmp((char *) &a, (char *) &b, 4));
}
int32
btchar8cmp(char *a, char *b)
{
- return (strncmp(a, b, 8));
+ return (strncmp(a, b, 8));
}
int32
btchar16cmp(char *a, char *b)
{
- return (strncmp(a, b, 16));
+ return (strncmp(a, b, 16));
}
int32
-btnamecmp(NameData *a, NameData *b)
+btnamecmp(NameData * a, NameData * b)
{
- return (strncmp(a->data, b->data, NAMEDATALEN));
+ return (strncmp(a->data, b->data, NAMEDATALEN));
}
int32
-bttextcmp(struct varlena *a, struct varlena *b)
+bttextcmp(struct varlena * a, struct varlena * b)
{
- int res;
- unsigned char *ap, *bp;
+ int res;
+ unsigned char *ap,
+ *bp;
#ifdef USE_LOCALE
- int la = VARSIZE(a) - VARHDRSZ;
- int lb = VARSIZE(b) - VARHDRSZ;
-
- ap = (unsigned char *) palloc (la + 1);
- bp = (unsigned char *) palloc (lb + 1);
-
- memcpy(ap, VARDATA(a), la);
- *(ap + la) = '\0';
- memcpy(bp, VARDATA(b), lb);
- *(bp + lb) = '\0';
-
- res = strcoll (ap, bp);
-
- pfree (ap);
- pfree (bp);
+ int la = VARSIZE(a) - VARHDRSZ;
+ int lb = VARSIZE(b) - VARHDRSZ;
+
+ ap = (unsigned char *) palloc(la + 1);
+ bp = (unsigned char *) palloc(lb + 1);
+
+ memcpy(ap, VARDATA(a), la);
+ *(ap + la) = '\0';
+ memcpy(bp, VARDATA(b), lb);
+ *(bp + lb) = '\0';
+
+ res = strcoll(ap, bp);
+
+ pfree(ap);
+ pfree(bp);
#else
- int len = VARSIZE(a);
-
- /* len is the length of the shorter of the two strings */
- if ( len > VARSIZE(b) )
- len = VARSIZE(b);
-
- len -= VARHDRSZ;
-
- ap = (unsigned char *) VARDATA(a);
- bp = (unsigned char *) VARDATA(b);
-
- /*
- * If the two strings differ in the first len bytes, or if they're
- * the same in the first len bytes and they're both len bytes long,
- * we're done.
- */
-
- res = 0;
- if (len > 0) {
- do {
- res = (int) (*ap++ - *bp++);
- len--;
- } while (res == 0 && len != 0);
- }
+ int len = VARSIZE(a);
+
+ /* len is the length of the shorter of the two strings */
+ if (len > VARSIZE(b))
+ len = VARSIZE(b);
+
+ len -= VARHDRSZ;
+
+ ap = (unsigned char *) VARDATA(a);
+ bp = (unsigned char *) VARDATA(b);
+
+ /*
+ * If the two strings differ in the first len bytes, or if they're the
+ * same in the first len bytes and they're both len bytes long, we're
+ * done.
+ */
+
+ res = 0;
+ if (len > 0)
+ {
+ do
+ {
+ res = (int) (*ap++ - *bp++);
+ len--;
+ } while (res == 0 && len != 0);
+ }
#endif
-
- if (res != 0 || VARSIZE(a) == VARSIZE(b))
- return (res);
-
- /*
- * The two strings are the same in the first len bytes, and they
- * are of different lengths.
- */
-
- if (VARSIZE(a) < VARSIZE(b))
- return (-1);
- else
- return (1);
+
+ if (res != 0 || VARSIZE(a) == VARSIZE(b))
+ return (res);
+
+ /*
+ * The two strings are the same in the first len bytes, and they are
+ * of different lengths.
+ */
+
+ if (VARSIZE(a) < VARSIZE(b))
+ return (-1);
+ else
+ return (1);
}
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index 4dfa6fd2558..4bafbc2ddbb 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* btinsert.c--
- * Item insertion in Lehman and Yao btrees for Postgres.
+ * Item insertion in Lehman and Yao btrees for Postgres.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.17 1997/08/20 14:53:15 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.18 1997/09/07 04:38:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,1386 +22,1437 @@
#include <fmgr.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
static InsertIndexResult _bt_insertonpg(Relation rel, Buffer buf, BTStack stack, int keysz, ScanKey scankey, BTItem btitem, BTItem afteritem);
-static Buffer _bt_split(Relation rel, Buffer buf, OffsetNumber firstright);
+static Buffer _bt_split(Relation rel, Buffer buf, OffsetNumber firstright);
static OffsetNumber _bt_findsplitloc(Relation rel, Page page, OffsetNumber start, OffsetNumber maxoff, Size llimit);
-static void _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf);
+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);
-static void _bt_updateitem(Relation rel, Size keysz, Buffer buf, BTItem oldItem, BTItem newItem);
-static bool _bt_isequal (TupleDesc itupdesc, Page page, OffsetNumber offnum, int keysz, ScanKey scankey);
+static bool _bt_goesonpg(Relation rel, Buffer buf, Size keysz, ScanKey scankey, BTItem afteritem);
+static void _bt_updateitem(Relation rel, Size keysz, Buffer buf, BTItem oldItem, BTItem newItem);
+static bool _bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum, int keysz, ScanKey scankey);
/*
- * _bt_doinsert() -- Handle insertion of a single btitem in the tree.
+ * _bt_doinsert() -- Handle insertion of a single btitem in the tree.
*
- * This routine is called by the public interface routines, btbuild
- * and btinsert. By here, btitem is filled in, and has a unique
- * (xid, seqno) pair.
+ * This routine is called by the public interface routines, btbuild
+ * and btinsert. By here, btitem is filled in, and has a unique
+ * (xid, seqno) pair.
*/
InsertIndexResult
_bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel)
{
- ScanKey itup_scankey;
- IndexTuple itup;
- BTStack stack;
- Buffer buf;
- BlockNumber blkno;
- int natts = rel->rd_rel->relnatts;
- InsertIndexResult res;
-
- itup = &(btitem->bti_itup);
-
- /* we need a scan key to do our search, so build one */
- itup_scankey = _bt_mkscankey(rel, itup);
-
- /* find the page containing this key */
- stack = _bt_search(rel, natts, itup_scankey, &buf);
-
- blkno = BufferGetBlockNumber(buf);
-
- /* trade in our read lock for a write lock */
- _bt_relbuf(rel, buf, BT_READ);
- buf = _bt_getbuf(rel, blkno, BT_WRITE);
-
- /*
- * If the page was split between the time that we surrendered our
- * read lock and acquired our write lock, then this page may no
- * longer be the right place for the key we want to insert. In this
- * case, we need to move right in the tree. See Lehman and Yao for
- * an excruciatingly precise description.
- */
-
- buf = _bt_moveright(rel, buf, natts, itup_scankey, BT_WRITE);
-
- /* if we're not allowing duplicates, make sure the key isn't */
- /* already in the node */
- if ( index_is_unique )
- {
- OffsetNumber offset, maxoff;
- Page page;
+ ScanKey itup_scankey;
+ IndexTuple itup;
+ BTStack stack;
+ Buffer buf;
+ BlockNumber blkno;
+ int natts = rel->rd_rel->relnatts;
+ InsertIndexResult res;
- page = BufferGetPage(buf);
- maxoff = PageGetMaxOffsetNumber (page);
+ itup = &(btitem->bti_itup);
+
+ /* we need a scan key to do our search, so build one */
+ itup_scankey = _bt_mkscankey(rel, itup);
+
+ /* find the page containing this key */
+ stack = _bt_search(rel, natts, itup_scankey, &buf);
- offset = _bt_binsrch(rel, buf, natts, itup_scankey, BT_DESCENT);
+ blkno = BufferGetBlockNumber(buf);
- /* make sure the offset we're given points to an actual */
- /* key on the page before trying to compare it */
- if ( !PageIsEmpty (page) && offset <= maxoff )
+ /* trade in our read lock for a write lock */
+ _bt_relbuf(rel, buf, BT_READ);
+ buf = _bt_getbuf(rel, blkno, BT_WRITE);
+
+ /*
+ * If the page was split between the time that we surrendered our read
+ * lock and acquired our write lock, then this page may no longer be
+ * the right place for the key we want to insert. In this case, we
+ * need to move right in the tree. See Lehman and Yao for an
+ * excruciatingly precise description.
+ */
+
+ buf = _bt_moveright(rel, buf, natts, itup_scankey, BT_WRITE);
+
+ /* if we're not allowing duplicates, make sure the key isn't */
+ /* already in the node */
+ if (index_is_unique)
{
- TupleDesc itupdesc;
- BTItem btitem;
- IndexTuple itup;
- HeapTuple htup;
- BTPageOpaque opaque;
- Buffer nbuf;
- BlockNumber blkno;
-
- itupdesc = RelationGetTupleDescriptor(rel);
- nbuf = InvalidBuffer;
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- /*
- * _bt_compare returns 0 for (1,NULL) and (1,NULL) -
- * this's how we handling NULLs - and so we must not use
- * _bt_compare in real comparison, but only for
- * ordering/finding items on pages. - vadim 03/24/97
-
- while ( !_bt_compare (rel, itupdesc, page,
- natts, itup_scankey, offset) )
- */
- while ( _bt_isequal (itupdesc, page, offset, natts, itup_scankey) )
- { /* they're equal */
- btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offset));
- itup = &(btitem->bti_itup);
- htup = heap_fetch (heapRel, SelfTimeQual, &(itup->t_tid), NULL);
- if ( htup != (HeapTuple) NULL )
- { /* it is a duplicate */
- elog(WARN, "Cannot insert a duplicate key into a unique index.");
- }
- /* get next offnum */
- if ( offset < maxoff )
- {
- offset = OffsetNumberNext(offset);
- }
- else
- { /* move right ? */
- if ( P_RIGHTMOST (opaque) )
- break;
- if ( !_bt_isequal (itupdesc, page, P_HIKEY,
- natts, itup_scankey) )
- break;
- /*
- * min key of the right page is the same,
- * ooh - so many dead duplicates...
- */
- blkno = opaque->btpo_next;
- if ( nbuf != InvalidBuffer )
- _bt_relbuf (rel, nbuf, BT_READ);
- for (nbuf = InvalidBuffer; ; )
- {
- nbuf = _bt_getbuf (rel, blkno, BT_READ);
- page = BufferGetPage (nbuf);
- maxoff = PageGetMaxOffsetNumber(page);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- offset = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
- if ( ! PageIsEmpty (page) && offset <= maxoff )
- { /* Found some key */
- break;
- }
- else
- { /* Empty or "pseudo"-empty page - get next */
- blkno = opaque->btpo_next;
- _bt_relbuf (rel, nbuf, BT_READ);
- nbuf = InvalidBuffer;
- if ( blkno == P_NONE )
- break;
+ OffsetNumber offset,
+ maxoff;
+ Page page;
+
+ page = BufferGetPage(buf);
+ maxoff = PageGetMaxOffsetNumber(page);
+
+ offset = _bt_binsrch(rel, buf, natts, itup_scankey, BT_DESCENT);
+
+ /* make sure the offset we're given points to an actual */
+ /* key on the page before trying to compare it */
+ if (!PageIsEmpty(page) && offset <= maxoff)
+ {
+ TupleDesc itupdesc;
+ BTItem btitem;
+ IndexTuple itup;
+ HeapTuple htup;
+ BTPageOpaque opaque;
+ Buffer nbuf;
+ BlockNumber blkno;
+
+ itupdesc = RelationGetTupleDescriptor(rel);
+ nbuf = InvalidBuffer;
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+
+ /*
+ * _bt_compare returns 0 for (1,NULL) and (1,NULL) - this's
+ * how we handling NULLs - and so we must not use _bt_compare
+ * in real comparison, but only for ordering/finding items on
+ * pages. - vadim 03/24/97
+ *
+ * while ( !_bt_compare (rel, itupdesc, page, natts,
+ * itup_scankey, offset) )
+ */
+ while (_bt_isequal(itupdesc, page, offset, natts, itup_scankey))
+ { /* they're equal */
+ btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offset));
+ itup = &(btitem->bti_itup);
+ htup = heap_fetch(heapRel, SelfTimeQual, &(itup->t_tid), NULL);
+ if (htup != (HeapTuple) NULL)
+ { /* it is a duplicate */
+ elog(WARN, "Cannot insert a duplicate key into a unique index.");
+ }
+ /* get next offnum */
+ if (offset < maxoff)
+ {
+ offset = OffsetNumberNext(offset);
+ }
+ else
+ { /* move right ? */
+ if (P_RIGHTMOST(opaque))
+ break;
+ if (!_bt_isequal(itupdesc, page, P_HIKEY,
+ natts, itup_scankey))
+ break;
+
+ /*
+ * min key of the right page is the same, ooh - so
+ * many dead duplicates...
+ */
+ blkno = opaque->btpo_next;
+ if (nbuf != InvalidBuffer)
+ _bt_relbuf(rel, nbuf, BT_READ);
+ for (nbuf = InvalidBuffer;;)
+ {
+ nbuf = _bt_getbuf(rel, blkno, BT_READ);
+ page = BufferGetPage(nbuf);
+ maxoff = PageGetMaxOffsetNumber(page);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ offset = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+ if (!PageIsEmpty(page) && offset <= maxoff)
+ { /* Found some key */
+ break;
+ }
+ else
+ { /* Empty or "pseudo"-empty page - get next */
+ blkno = opaque->btpo_next;
+ _bt_relbuf(rel, nbuf, BT_READ);
+ nbuf = InvalidBuffer;
+ if (blkno == P_NONE)
+ break;
+ }
+ }
+ if (nbuf == InvalidBuffer)
+ break;
+ }
}
- }
- if ( nbuf == InvalidBuffer )
- break;
- }
- }
- if ( nbuf != InvalidBuffer )
- _bt_relbuf(rel, nbuf, BT_READ);
+ if (nbuf != InvalidBuffer)
+ _bt_relbuf(rel, nbuf, BT_READ);
+ }
}
- }
-
- /* do the insertion */
- res = _bt_insertonpg(rel, buf, stack, natts, itup_scankey,
- btitem, (BTItem) NULL);
-
- /* be tidy */
- _bt_freestack(stack);
- _bt_freeskey(itup_scankey);
-
- return (res);
+
+ /* do the insertion */
+ res = _bt_insertonpg(rel, buf, stack, natts, itup_scankey,
+ btitem, (BTItem) NULL);
+
+ /* be tidy */
+ _bt_freestack(stack);
+ _bt_freeskey(itup_scankey);
+
+ return (res);
}
/*
- * _bt_insertonpg() -- Insert a tuple on a particular page in the index.
+ * _bt_insertonpg() -- Insert a tuple on a particular page in the index.
*
- * This recursive procedure does the following things:
+ * This recursive procedure does the following things:
*
- * + if necessary, splits the target page.
- * + finds the right place to insert the tuple (taking into
- * account any changes induced by a split).
- * + inserts the tuple.
- * + if the page was split, pops the parent stack, and finds the
- * right place to insert the new child pointer (by walking
- * right using information stored in the parent stack).
- * + invoking itself with the appropriate tuple for the right
- * child page on the parent.
+ * + if necessary, splits the target page.
+ * + finds the right place to insert the tuple (taking into
+ * account any changes induced by a split).
+ * + inserts the tuple.
+ * + if the page was split, pops the parent stack, and finds the
+ * right place to insert the new child pointer (by walking
+ * right using information stored in the parent stack).
+ * + invoking itself with the appropriate tuple for the right
+ * child page on the parent.
*
- * On entry, we must have the right buffer on which to do the
- * insertion, and the buffer must be pinned and locked. On return,
- * we will have dropped both the pin and the write lock on the buffer.
+ * On entry, we must have the right buffer on which to do the
+ * insertion, and the buffer must be pinned and locked. On return,
+ * we will have dropped both the pin and the write lock on the buffer.
*
- * The locking interactions in this code are critical. You should
- * grok Lehman and Yao's paper before making any changes. In addition,
- * you need to understand how we disambiguate duplicate keys in this
- * implementation, in order to be able to find our location using
- * L&Y "move right" operations. Since we may insert duplicate user
- * keys, and since these dups may propogate up the tree, we use the
- * 'afteritem' parameter to position ourselves correctly for the
- * insertion on internal pages.
+ * The locking interactions in this code are critical. You should
+ * grok Lehman and Yao's paper before making any changes. In addition,
+ * you need to understand how we disambiguate duplicate keys in this
+ * implementation, in order to be able to find our location using
+ * L&Y "move right" operations. Since we may insert duplicate user
+ * keys, and since these dups may propogate up the tree, we use the
+ * 'afteritem' parameter to position ourselves correctly for the
+ * insertion on internal pages.
*/
-static InsertIndexResult
+static InsertIndexResult
_bt_insertonpg(Relation rel,
- Buffer buf,
- BTStack stack,
- int keysz,
- ScanKey scankey,
- BTItem btitem,
- BTItem afteritem)
+ Buffer buf,
+ BTStack stack,
+ int keysz,
+ ScanKey scankey,
+ BTItem btitem,
+ BTItem afteritem)
{
- InsertIndexResult res;
- Page page;
- BTPageOpaque lpageop;
- BlockNumber itup_blkno;
- OffsetNumber itup_off;
- OffsetNumber firstright = InvalidOffsetNumber;
- int itemsz;
- bool do_split = false;
- bool keys_equal = false;
-
- page = BufferGetPage(buf);
- lpageop = (BTPageOpaque) PageGetSpecialPointer(page);
-
- itemsz = IndexTupleDSize(btitem->bti_itup)
- + (sizeof(BTItemData) - sizeof(IndexTupleData));
-
- itemsz = DOUBLEALIGN(itemsz); /* be safe, PageAddItem will do this
- but we need to be consistent */
- /*
- * If we have to insert item on the leftmost page which is the first
- * page in the chain of duplicates then:
- * 1. if scankey == hikey (i.e. - new duplicate item) then
- * insert it here;
- * 2. if scankey < hikey then:
- * 2.a if there is duplicate key(s) here - we force splitting;
- * 2.b else - we may "eat" this page from duplicates chain.
- */
- if ( lpageop->btpo_flags & BTP_CHAIN )
- {
- OffsetNumber maxoff = PageGetMaxOffsetNumber (page);
- ItemId hitemid;
- BTItem hitem;
-
- Assert ( !P_RIGHTMOST(lpageop) );
- hitemid = PageGetItemId(page, P_HIKEY);
- hitem = (BTItem) PageGetItem(page, hitemid);
- if ( maxoff > P_HIKEY &&
- !_bt_itemcmp (rel, keysz, hitem,
- (BTItem) PageGetItem(page, PageGetItemId(page, P_FIRSTKEY)),
- BTEqualStrategyNumber) )
- elog (FATAL, "btree: bad key on the page in the chain of duplicates");
-
- if ( !_bt_skeycmp (rel, keysz, scankey, page, hitemid,
- BTEqualStrategyNumber) )
- {
- if ( !P_LEFTMOST(lpageop) )
- elog (FATAL, "btree: attempt to insert bad key on the non-leftmost page in the chain of duplicates");
- if ( !_bt_skeycmp (rel, keysz, scankey, page, hitemid,
- BTLessStrategyNumber) )
- elog (FATAL, "btree: attempt to insert higher key on the leftmost page in the chain of duplicates");
- if ( maxoff > P_HIKEY ) /* have duplicate(s) */
- {
- firstright = P_FIRSTKEY;
- do_split = true;
- }
- else /* "eat" page */
- {
- Buffer pbuf;
- Page ppage;
-
- itup_blkno = BufferGetBlockNumber(buf);
- itup_off = PageAddItem(page, (Item) btitem, itemsz,
- P_FIRSTKEY, LP_USED);
- if ( itup_off == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add item");
- lpageop->btpo_flags &= ~BTP_CHAIN;
- pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
- ppage = BufferGetPage(pbuf);
- PageIndexTupleDelete(ppage, stack->bts_offset);
- pfree(stack->bts_btitem);
- stack->bts_btitem = _bt_formitem(&(btitem->bti_itup));
- ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
- itup_blkno, P_HIKEY);
- _bt_wrtbuf(rel, buf);
- res = _bt_insertonpg(rel, pbuf, stack->bts_parent,
- keysz, scankey, stack->bts_btitem,
- NULL);
- ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
- return (res);
- }
- }
- else
- {
- keys_equal = true;
- if ( PageGetFreeSpace(page) < itemsz )
- do_split = true;
- }
- }
- else if ( PageGetFreeSpace(page) < itemsz )
- do_split = true;
- else if ( PageGetFreeSpace(page) < 3*itemsz + 2*sizeof(ItemIdData) )
- {
- OffsetNumber offnum = (P_RIGHTMOST(lpageop)) ? P_HIKEY : P_FIRSTKEY;
- OffsetNumber maxoff = PageGetMaxOffsetNumber (page);
- ItemId itid;
- BTItem previtem, chkitem;
- Size maxsize;
- Size currsize;
-
- itid = PageGetItemId(page, offnum);
- previtem = (BTItem) PageGetItem(page, itid);
- maxsize = currsize = (ItemIdGetLength(itid) + sizeof(ItemIdData));
- for (offnum = OffsetNumberNext(offnum);
- offnum <= maxoff; offnum = OffsetNumberNext(offnum) )
- {
- itid = PageGetItemId(page, offnum);
- chkitem = (BTItem) PageGetItem(page, itid);
- if ( !_bt_itemcmp (rel, keysz, previtem, chkitem,
- BTEqualStrategyNumber) )
- {
- if ( currsize > maxsize )
- maxsize = currsize;
- currsize = 0;
- previtem = chkitem;
- }
- currsize += (ItemIdGetLength(itid) + sizeof(ItemIdData));
- }
- if ( currsize > maxsize )
- maxsize = currsize;
- maxsize += sizeof (PageHeaderData) +
- DOUBLEALIGN (sizeof (BTPageOpaqueData));
- if ( maxsize >= PageGetPageSize (page) / 2 )
- do_split = true;
- }
-
- if ( do_split )
- {
- Buffer rbuf;
- Page rpage;
- BTItem ritem;
- BlockNumber rbknum;
- BTPageOpaque rpageop;
- Buffer pbuf;
- Page ppage;
- BTPageOpaque ppageop;
- BlockNumber bknum = BufferGetBlockNumber(buf);
- BTItem lowLeftItem;
- OffsetNumber maxoff;
- bool shifted = false;
- bool left_chained = ( lpageop->btpo_flags & BTP_CHAIN ) ? true : false;
-
- /*
- * If we have to split leaf page in the chain of duplicates by
- * new duplicate then we try to look at our right sibling first.
- */
- if ( ( lpageop->btpo_flags & BTP_CHAIN ) &&
- ( lpageop->btpo_flags & BTP_LEAF ) && keys_equal )
- {
- bool use_left = true;
-
- rbuf = _bt_getbuf(rel, lpageop->btpo_next, BT_WRITE);
- rpage = BufferGetPage(rbuf);
- rpageop = (BTPageOpaque) PageGetSpecialPointer(rpage);
- if ( !P_RIGHTMOST (rpageop) ) /* non-rightmost page */
- { /*
- * If we have the same hikey here then it's
- * yet another page in chain.
- */
- if ( _bt_skeycmp (rel, keysz, scankey, rpage,
- PageGetItemId(rpage, P_HIKEY),
- BTEqualStrategyNumber) )
- {
- if ( !( rpageop->btpo_flags & BTP_CHAIN ) )
- elog (FATAL, "btree: lost page in the chain of duplicates");
- }
- else if ( _bt_skeycmp (rel, keysz, scankey, rpage,
- PageGetItemId(rpage, P_HIKEY),
- 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
- */
- elog (FATAL, "btree: lost last page in the chain of duplicates");
-
- /* if there is room here then we use this page. */
- if ( PageGetFreeSpace (rpage) > itemsz )
- use_left = false;
- }
- else /* rightmost page */
- {
- Assert ( !( rpageop->btpo_flags & BTP_CHAIN ) );
- /* if there is room here then we use this page. */
- if ( PageGetFreeSpace (rpage) > itemsz )
- use_left = false;
- }
- if ( !use_left ) /* insert on the right page */
- {
- _bt_relbuf(rel, buf, BT_WRITE);
- return ( _bt_insertonpg(rel, rbuf, stack, keysz,
- scankey, btitem, afteritem) );
- }
- _bt_relbuf(rel, rbuf, BT_WRITE);
- }
+ InsertIndexResult res;
+ Page page;
+ BTPageOpaque lpageop;
+ BlockNumber itup_blkno;
+ OffsetNumber itup_off;
+ OffsetNumber firstright = InvalidOffsetNumber;
+ int itemsz;
+ bool do_split = false;
+ bool keys_equal = false;
+
+ page = BufferGetPage(buf);
+ lpageop = (BTPageOpaque) PageGetSpecialPointer(page);
+
+ itemsz = IndexTupleDSize(btitem->bti_itup)
+ + (sizeof(BTItemData) - sizeof(IndexTupleData));
+
+ itemsz = DOUBLEALIGN(itemsz); /* be safe, PageAddItem will do
+ * this but we need to be
+ * consistent */
+
/*
- * If after splitting un-chained page we'll got chain of pages
- * with duplicates then we want to know
- * 1. on which of two pages new btitem will go (current
- * _bt_findsplitloc is quite bad);
- * 2. what parent (if there's one) thinking about it
- * (remember about deletions)
+ * If we have to insert item on the leftmost page which is the first
+ * page in the chain of duplicates then: 1. if scankey == hikey (i.e.
+ * - new duplicate item) then insert it here; 2. if scankey < hikey
+ * then: 2.a if there is duplicate key(s) here - we force splitting;
+ * 2.b else - we may "eat" this page from duplicates chain.
*/
- else if ( !( lpageop->btpo_flags & BTP_CHAIN ) )
+ if (lpageop->btpo_flags & BTP_CHAIN)
{
- OffsetNumber start = ( P_RIGHTMOST(lpageop) ) ? P_HIKEY : P_FIRSTKEY;
- Size llimit;
-
- maxoff = PageGetMaxOffsetNumber (page);
- llimit = PageGetPageSize(page) - sizeof (PageHeaderData) -
- DOUBLEALIGN (sizeof (BTPageOpaqueData))
- + sizeof(ItemIdData);
- llimit /= 2;
- firstright = _bt_findsplitloc(rel, page, start, maxoff, llimit);
-
- if ( _bt_itemcmp (rel, keysz,
- (BTItem) PageGetItem(page, PageGetItemId(page, start)),
- (BTItem) PageGetItem(page, PageGetItemId(page, firstright)),
- BTEqualStrategyNumber) )
- {
- if ( _bt_skeycmp (rel, keysz, scankey, page,
- PageGetItemId(page, firstright),
- BTLessStrategyNumber) )
- /*
- * force moving current items to the new page:
- * new item will go on the current page.
- */
- firstright = start;
- else
- /*
- * new btitem >= firstright, start item == firstright -
- * new chain of duplicates: if this non-leftmost leaf
- * page and parent item < start item then force moving
- * all items to the new page - current page will be
- * "empty" after it.
- */
- {
- if ( !P_LEFTMOST (lpageop) &&
- ( lpageop->btpo_flags & BTP_LEAF ) )
- {
- ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
- bknum, P_HIKEY);
- pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
- if ( _bt_itemcmp (rel, keysz, stack->bts_btitem,
- (BTItem) PageGetItem(page,
- PageGetItemId(page, start)),
- BTLessStrategyNumber) )
- {
- firstright = start;
- shifted = true;
- }
- _bt_relbuf(rel, pbuf, BT_WRITE);
- }
- }
- } /* else - no new chain if start item < firstright one */
- }
-
- /* split the buffer into left and right halves */
- rbuf = _bt_split(rel, buf, firstright);
-
- /* which new page (left half or right half) gets the tuple? */
- if (_bt_goesonpg(rel, buf, keysz, scankey, afteritem)) {
- /* left page */
- itup_off = _bt_pgaddtup(rel, buf, keysz, scankey,
- itemsz, btitem, afteritem);
- itup_blkno = BufferGetBlockNumber(buf);
- } else {
- /* right page */
- itup_off = _bt_pgaddtup(rel, rbuf, keysz, scankey,
- itemsz, btitem, afteritem);
- itup_blkno = BufferGetBlockNumber(rbuf);
+ OffsetNumber maxoff = PageGetMaxOffsetNumber(page);
+ ItemId hitemid;
+ BTItem hitem;
+
+ Assert(!P_RIGHTMOST(lpageop));
+ hitemid = PageGetItemId(page, P_HIKEY);
+ hitem = (BTItem) PageGetItem(page, hitemid);
+ if (maxoff > P_HIKEY &&
+ !_bt_itemcmp(rel, keysz, hitem,
+ (BTItem) PageGetItem(page, PageGetItemId(page, P_FIRSTKEY)),
+ BTEqualStrategyNumber))
+ elog(FATAL, "btree: bad key on the page in the chain of duplicates");
+
+ if (!_bt_skeycmp(rel, keysz, scankey, page, hitemid,
+ BTEqualStrategyNumber))
+ {
+ if (!P_LEFTMOST(lpageop))
+ elog(FATAL, "btree: attempt to insert bad key on the non-leftmost page in the chain of duplicates");
+ if (!_bt_skeycmp(rel, keysz, scankey, page, hitemid,
+ BTLessStrategyNumber))
+ elog(FATAL, "btree: attempt to insert higher key on the leftmost page in the chain of duplicates");
+ if (maxoff > P_HIKEY) /* have duplicate(s) */
+ {
+ firstright = P_FIRSTKEY;
+ do_split = true;
+ }
+ else
+/* "eat" page */
+ {
+ Buffer pbuf;
+ Page ppage;
+
+ itup_blkno = BufferGetBlockNumber(buf);
+ itup_off = PageAddItem(page, (Item) btitem, itemsz,
+ P_FIRSTKEY, LP_USED);
+ if (itup_off == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add item");
+ lpageop->btpo_flags &= ~BTP_CHAIN;
+ pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
+ ppage = BufferGetPage(pbuf);
+ PageIndexTupleDelete(ppage, stack->bts_offset);
+ pfree(stack->bts_btitem);
+ stack->bts_btitem = _bt_formitem(&(btitem->bti_itup));
+ ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
+ itup_blkno, P_HIKEY);
+ _bt_wrtbuf(rel, buf);
+ res = _bt_insertonpg(rel, pbuf, stack->bts_parent,
+ keysz, scankey, stack->bts_btitem,
+ NULL);
+ ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
+ return (res);
+ }
+ }
+ else
+ {
+ keys_equal = true;
+ if (PageGetFreeSpace(page) < itemsz)
+ do_split = true;
+ }
}
-
- maxoff = PageGetMaxOffsetNumber (page);
- if ( shifted )
- {
- if ( maxoff > P_FIRSTKEY )
- elog (FATAL, "btree: shifted page is not empty");
- lowLeftItem = (BTItem) NULL;
- }
- else
- {
- if ( maxoff < P_FIRSTKEY )
- elog (FATAL, "btree: un-shifted page is empty");
- lowLeftItem = (BTItem) PageGetItem(page,
- PageGetItemId(page, P_FIRSTKEY));
- if ( _bt_itemcmp (rel, keysz, lowLeftItem,
- (BTItem) PageGetItem(page, PageGetItemId(page, P_HIKEY)),
- BTEqualStrategyNumber) )
- lpageop->btpo_flags |= BTP_CHAIN;
+ else if (PageGetFreeSpace(page) < itemsz)
+ do_split = true;
+ else if (PageGetFreeSpace(page) < 3 * itemsz + 2 * sizeof(ItemIdData))
+ {
+ OffsetNumber offnum = (P_RIGHTMOST(lpageop)) ? P_HIKEY : P_FIRSTKEY;
+ OffsetNumber maxoff = PageGetMaxOffsetNumber(page);
+ ItemId itid;
+ BTItem previtem,
+ chkitem;
+ Size maxsize;
+ Size currsize;
+
+ itid = PageGetItemId(page, offnum);
+ previtem = (BTItem) PageGetItem(page, itid);
+ maxsize = currsize = (ItemIdGetLength(itid) + sizeof(ItemIdData));
+ for (offnum = OffsetNumberNext(offnum);
+ offnum <= maxoff; offnum = OffsetNumberNext(offnum))
+ {
+ itid = PageGetItemId(page, offnum);
+ chkitem = (BTItem) PageGetItem(page, itid);
+ if (!_bt_itemcmp(rel, keysz, previtem, chkitem,
+ BTEqualStrategyNumber))
+ {
+ if (currsize > maxsize)
+ maxsize = currsize;
+ currsize = 0;
+ previtem = chkitem;
+ }
+ currsize += (ItemIdGetLength(itid) + sizeof(ItemIdData));
+ }
+ if (currsize > maxsize)
+ maxsize = currsize;
+ maxsize += sizeof(PageHeaderData) +
+ DOUBLEALIGN(sizeof(BTPageOpaqueData));
+ if (maxsize >= PageGetPageSize(page) / 2)
+ do_split = true;
}
- /*
- * By here,
- *
- * + our target page has been split;
- * + the original tuple has been inserted;
- * + we have write locks on both the old (left half) and new
- * (right half) buffers, after the split; and
- * + we have the key we want to insert into the parent.
- *
- * Do the parent insertion. We need to hold onto the locks for
- * the child pages until we locate the parent, but we can release
- * them before doing the actual insertion (see Lehman and Yao for
- * the reasoning).
- */
-
- if (stack == (BTStack) NULL) {
-
- /* create a new root node and release the split buffers */
- _bt_newroot(rel, buf, rbuf);
- _bt_relbuf(rel, buf, BT_WRITE);
- _bt_relbuf(rel, rbuf, BT_WRITE);
-
- } else {
- ScanKey newskey;
- InsertIndexResult newres;
- BTItem new_item;
- OffsetNumber upditem_offset = P_HIKEY;
- bool do_update = false;
- bool update_in_place = true;
- bool parent_chained;
-
- /* form a index tuple that points at the new right page */
- rbknum = BufferGetBlockNumber(rbuf);
- rpage = BufferGetPage(rbuf);
- rpageop = (BTPageOpaque) PageGetSpecialPointer(rpage);
-
- /*
- * By convention, the first entry (1) on every
- * non-rightmost page is the high key for that page. In
- * order to get the lowest key on the new right page, we
- * actually look at its second (2) entry.
- */
-
- if (! P_RIGHTMOST(rpageop))
- {
- ritem = (BTItem) PageGetItem(rpage,
- PageGetItemId(rpage, P_FIRSTKEY));
- if ( _bt_itemcmp (rel, keysz, ritem,
- (BTItem) PageGetItem(rpage,
- PageGetItemId(rpage, P_HIKEY)),
- BTEqualStrategyNumber) )
- rpageop->btpo_flags |= BTP_CHAIN;
- }
- else
- ritem = (BTItem) PageGetItem(rpage,
- PageGetItemId(rpage, P_HIKEY));
-
- /* get a unique btitem for this key */
- new_item = _bt_formitem(&(ritem->bti_itup));
-
- ItemPointerSet(&(new_item->bti_itup.t_tid), rbknum, P_HIKEY);
-
- /*
- * Find the parent buffer and get the parent page.
- *
- * Oops - if we were moved right then we need to
- * change stack item! We want to find parent pointing to
- * where we are, right ? - vadim 05/27/97
- */
- ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
- bknum, P_HIKEY);
- pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
- ppage = BufferGetPage(pbuf);
- ppageop = (BTPageOpaque) PageGetSpecialPointer(ppage);
- parent_chained = (( ppageop->btpo_flags & BTP_CHAIN )) ? true : false;
-
- if ( parent_chained && !left_chained )
- elog (FATAL, "nbtree: unexpected chained parent of unchained page");
-
- /*
- * If the key of new_item is < than the key of the item
- * in the parent page pointing to the left page
- * (stack->bts_btitem), we have to update the latter key;
- * otherwise the keys on the parent page wouldn't be
- * monotonically increasing after we inserted the new
- * pointer to the right page (new_item). This only
- * happens if our left page is the leftmost page and a
- * new minimum key had been inserted before, which is not
- * reflected in the parent page but didn't matter so
- * far. If there are duplicate keys and this new minimum
- * key spills over to our new right page, we get an
- * inconsistency if we don't update the left key in the
- * parent page.
- *
- * Also, new duplicates handling code require us to update
- * parent item if some smaller items left on the left page
- * (which is possible in splitting leftmost page) and
- * current parent item == new_item. - vadim 05/27/97
- */
- if ( _bt_itemcmp (rel, keysz, stack->bts_btitem, new_item,
- BTGreaterStrategyNumber) ||
- ( !shifted &&
- _bt_itemcmp(rel, keysz, stack->bts_btitem,
- new_item, BTEqualStrategyNumber) &&
- _bt_itemcmp(rel, keysz, lowLeftItem,
- new_item, BTLessStrategyNumber) ) )
- {
- do_update = true;
- /*
- * figure out which key is leftmost (if the parent page
- * is rightmost, too, it must be the root)
+ if (do_split)
+ {
+ Buffer rbuf;
+ Page rpage;
+ BTItem ritem;
+ BlockNumber rbknum;
+ BTPageOpaque rpageop;
+ Buffer pbuf;
+ Page ppage;
+ BTPageOpaque ppageop;
+ BlockNumber bknum = BufferGetBlockNumber(buf);
+ BTItem lowLeftItem;
+ OffsetNumber maxoff;
+ bool shifted = false;
+ bool left_chained = (lpageop->btpo_flags & BTP_CHAIN) ? true : false;
+
+ /*
+ * If we have to split leaf page in the chain of duplicates by new
+ * duplicate then we try to look at our right sibling first.
*/
- if(P_RIGHTMOST(ppageop))
- upditem_offset = P_HIKEY;
+ if ((lpageop->btpo_flags & BTP_CHAIN) &&
+ (lpageop->btpo_flags & BTP_LEAF) && keys_equal)
+ {
+ bool use_left = true;
+
+ rbuf = _bt_getbuf(rel, lpageop->btpo_next, BT_WRITE);
+ rpage = BufferGetPage(rbuf);
+ rpageop = (BTPageOpaque) PageGetSpecialPointer(rpage);
+ if (!P_RIGHTMOST(rpageop)) /* non-rightmost page */
+ { /* If we have the same hikey here then
+ * it's yet another page in chain. */
+ if (_bt_skeycmp(rel, keysz, scankey, rpage,
+ PageGetItemId(rpage, P_HIKEY),
+ BTEqualStrategyNumber))
+ {
+ if (!(rpageop->btpo_flags & BTP_CHAIN))
+ elog(FATAL, "btree: lost page in the chain of duplicates");
+ }
+ else if (_bt_skeycmp(rel, keysz, scankey, rpage,
+ PageGetItemId(rpage, P_HIKEY),
+ 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
+ */
+ elog(FATAL, "btree: lost last page in the chain of duplicates");
+
+ /* if there is room here then we use this page. */
+ if (PageGetFreeSpace(rpage) > itemsz)
+ use_left = false;
+ }
+ else
+/* rightmost page */
+ {
+ Assert(!(rpageop->btpo_flags & BTP_CHAIN));
+ /* if there is room here then we use this page. */
+ if (PageGetFreeSpace(rpage) > itemsz)
+ use_left = false;
+ }
+ if (!use_left) /* insert on the right page */
+ {
+ _bt_relbuf(rel, buf, BT_WRITE);
+ return (_bt_insertonpg(rel, rbuf, stack, keysz,
+ scankey, btitem, afteritem));
+ }
+ _bt_relbuf(rel, rbuf, BT_WRITE);
+ }
+
+ /*
+ * If after splitting un-chained page we'll got chain of pages
+ * with duplicates then we want to know 1. on which of two pages
+ * new btitem will go (current _bt_findsplitloc is quite bad); 2.
+ * what parent (if there's one) thinking about it (remember about
+ * deletions)
+ */
+ else if (!(lpageop->btpo_flags & BTP_CHAIN))
+ {
+ OffsetNumber start = (P_RIGHTMOST(lpageop)) ? P_HIKEY : P_FIRSTKEY;
+ Size llimit;
+
+ maxoff = PageGetMaxOffsetNumber(page);
+ llimit = PageGetPageSize(page) - sizeof(PageHeaderData) -
+ DOUBLEALIGN(sizeof(BTPageOpaqueData))
+ + sizeof(ItemIdData);
+ llimit /= 2;
+ firstright = _bt_findsplitloc(rel, page, start, maxoff, llimit);
+
+ if (_bt_itemcmp(rel, keysz,
+ (BTItem) PageGetItem(page, PageGetItemId(page, start)),
+ (BTItem) PageGetItem(page, PageGetItemId(page, firstright)),
+ BTEqualStrategyNumber))
+ {
+ if (_bt_skeycmp(rel, keysz, scankey, page,
+ PageGetItemId(page, firstright),
+ BTLessStrategyNumber))
+
+ /*
+ * force moving current items to the new page: new
+ * item will go on the current page.
+ */
+ firstright = start;
+ else
+
+ /*
+ * new btitem >= firstright, start item == firstright
+ * - new chain of duplicates: if this non-leftmost
+ * leaf page and parent item < start item then force
+ * moving all items to the new page - current page
+ * will be "empty" after it.
+ */
+ {
+ if (!P_LEFTMOST(lpageop) &&
+ (lpageop->btpo_flags & BTP_LEAF))
+ {
+ ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
+ bknum, P_HIKEY);
+ pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
+ if (_bt_itemcmp(rel, keysz, stack->bts_btitem,
+ (BTItem) PageGetItem(page,
+ PageGetItemId(page, start)),
+ BTLessStrategyNumber))
+ {
+ firstright = start;
+ shifted = true;
+ }
+ _bt_relbuf(rel, pbuf, BT_WRITE);
+ }
+ }
+ } /* else - no new chain if start item <
+ * firstright one */
+ }
+
+ /* split the buffer into left and right halves */
+ rbuf = _bt_split(rel, buf, firstright);
+
+ /* which new page (left half or right half) gets the tuple? */
+ if (_bt_goesonpg(rel, buf, keysz, scankey, afteritem))
+ {
+ /* left page */
+ itup_off = _bt_pgaddtup(rel, buf, keysz, scankey,
+ itemsz, btitem, afteritem);
+ itup_blkno = BufferGetBlockNumber(buf);
+ }
else
- upditem_offset = P_FIRSTKEY;
- if ( !P_LEFTMOST(lpageop) ||
- stack->bts_offset != upditem_offset )
- elog (FATAL, "btree: items are out of order (leftmost %d, stack %u, update %u)",
- P_LEFTMOST(lpageop), stack->bts_offset, upditem_offset);
- }
-
- if ( do_update )
- {
- if ( shifted )
- elog (FATAL, "btree: attempt to update parent for shifted page");
- /*
- * Try to update in place. If out parent page is chained
- * then we must forse insertion.
+ {
+ /* right page */
+ itup_off = _bt_pgaddtup(rel, rbuf, keysz, scankey,
+ itemsz, btitem, afteritem);
+ itup_blkno = BufferGetBlockNumber(rbuf);
+ }
+
+ maxoff = PageGetMaxOffsetNumber(page);
+ if (shifted)
+ {
+ if (maxoff > P_FIRSTKEY)
+ elog(FATAL, "btree: shifted page is not empty");
+ lowLeftItem = (BTItem) NULL;
+ }
+ else
+ {
+ if (maxoff < P_FIRSTKEY)
+ elog(FATAL, "btree: un-shifted page is empty");
+ lowLeftItem = (BTItem) PageGetItem(page,
+ PageGetItemId(page, P_FIRSTKEY));
+ if (_bt_itemcmp(rel, keysz, lowLeftItem,
+ (BTItem) PageGetItem(page, PageGetItemId(page, P_HIKEY)),
+ BTEqualStrategyNumber))
+ lpageop->btpo_flags |= BTP_CHAIN;
+ }
+
+ /*
+ * By here,
+ *
+ * + our target page has been split; + the original tuple has been
+ * inserted; + we have write locks on both the old (left half)
+ * and new (right half) buffers, after the split; and + we have
+ * the key we want to insert into the parent.
+ *
+ * Do the parent insertion. We need to hold onto the locks for the
+ * child pages until we locate the parent, but we can release them
+ * before doing the actual insertion (see Lehman and Yao for the
+ * reasoning).
*/
- if ( !parent_chained &&
- DOUBLEALIGN (IndexTupleDSize (lowLeftItem->bti_itup)) ==
- DOUBLEALIGN (IndexTupleDSize (stack->bts_btitem->bti_itup)) )
- {
- _bt_updateitem(rel, keysz, pbuf,
- stack->bts_btitem, lowLeftItem);
- _bt_relbuf(rel, buf, BT_WRITE);
- _bt_relbuf(rel, rbuf, BT_WRITE);
+
+ if (stack == (BTStack) NULL)
+ {
+
+ /* create a new root node and release the split buffers */
+ _bt_newroot(rel, buf, rbuf);
+ _bt_relbuf(rel, buf, BT_WRITE);
+ _bt_relbuf(rel, rbuf, BT_WRITE);
+
}
else
{
- update_in_place = false;
- PageIndexTupleDelete(ppage, upditem_offset);
-
- /*
- * don't write anything out yet--we still have the write
- * lock, and now we call another _bt_insertonpg to
- * insert the correct key.
- * First, make a new item, using the tuple data from
- * lowLeftItem. Point it to the left child.
- * Update it on the stack at the same time.
- */
- pfree(stack->bts_btitem);
- stack->bts_btitem = _bt_formitem(&(lowLeftItem->bti_itup));
- ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
- bknum, P_HIKEY);
-
- /*
- * Unlock the children before doing this
- *
- * Mmm ... I foresee problems here. - vadim 06/10/97
- */
- _bt_relbuf(rel, buf, BT_WRITE);
- _bt_relbuf(rel, rbuf, BT_WRITE);
-
- /*
- * A regular _bt_binsrch should find the right place to
- * put the new entry, since it should be lower than any
- * other key on the page.
- * Therefore set afteritem to NULL.
- */
- newskey = _bt_mkscankey(rel, &(stack->bts_btitem->bti_itup));
- newres = _bt_insertonpg(rel, pbuf, stack->bts_parent,
- keysz, newskey, stack->bts_btitem,
- NULL);
-
- pfree(newres);
- pfree(newskey);
-
- /*
- * we have now lost our lock on the parent buffer, and
- * need to get it back.
- */
- pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
+ ScanKey newskey;
+ InsertIndexResult newres;
+ BTItem new_item;
+ OffsetNumber upditem_offset = P_HIKEY;
+ bool do_update = false;
+ bool update_in_place = true;
+ bool parent_chained;
+
+ /* form a index tuple that points at the new right page */
+ rbknum = BufferGetBlockNumber(rbuf);
+ rpage = BufferGetPage(rbuf);
+ rpageop = (BTPageOpaque) PageGetSpecialPointer(rpage);
+
+ /*
+ * By convention, the first entry (1) on every non-rightmost
+ * page is the high key for that page. In order to get the
+ * lowest key on the new right page, we actually look at its
+ * second (2) entry.
+ */
+
+ if (!P_RIGHTMOST(rpageop))
+ {
+ ritem = (BTItem) PageGetItem(rpage,
+ PageGetItemId(rpage, P_FIRSTKEY));
+ if (_bt_itemcmp(rel, keysz, ritem,
+ (BTItem) PageGetItem(rpage,
+ PageGetItemId(rpage, P_HIKEY)),
+ BTEqualStrategyNumber))
+ rpageop->btpo_flags |= BTP_CHAIN;
+ }
+ else
+ ritem = (BTItem) PageGetItem(rpage,
+ PageGetItemId(rpage, P_HIKEY));
+
+ /* get a unique btitem for this key */
+ new_item = _bt_formitem(&(ritem->bti_itup));
+
+ ItemPointerSet(&(new_item->bti_itup.t_tid), rbknum, P_HIKEY);
+
+ /*
+ * Find the parent buffer and get the parent page.
+ *
+ * Oops - if we were moved right then we need to change stack
+ * item! We want to find parent pointing to where we are,
+ * right ? - vadim 05/27/97
+ */
+ ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
+ bknum, P_HIKEY);
+ pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
+ ppage = BufferGetPage(pbuf);
+ ppageop = (BTPageOpaque) PageGetSpecialPointer(ppage);
+ parent_chained = ((ppageop->btpo_flags & BTP_CHAIN)) ? true : false;
+
+ if (parent_chained && !left_chained)
+ elog(FATAL, "nbtree: unexpected chained parent of unchained page");
+
+ /*
+ * If the key of new_item is < than the key of the item in the
+ * parent page pointing to the left page (stack->bts_btitem),
+ * we have to update the latter key; otherwise the keys on the
+ * parent page wouldn't be monotonically increasing after we
+ * inserted the new pointer to the right page (new_item). This
+ * only happens if our left page is the leftmost page and a
+ * new minimum key had been inserted before, which is not
+ * reflected in the parent page but didn't matter so far. If
+ * there are duplicate keys and this new minimum key spills
+ * over to our new right page, we get an inconsistency if we
+ * don't update the left key in the parent page.
+ *
+ * Also, new duplicates handling code require us to update parent
+ * item if some smaller items left on the left page (which is
+ * possible in splitting leftmost page) and current parent
+ * item == new_item. - vadim 05/27/97
+ */
+ if (_bt_itemcmp(rel, keysz, stack->bts_btitem, new_item,
+ BTGreaterStrategyNumber) ||
+ (!shifted &&
+ _bt_itemcmp(rel, keysz, stack->bts_btitem,
+ new_item, BTEqualStrategyNumber) &&
+ _bt_itemcmp(rel, keysz, lowLeftItem,
+ new_item, BTLessStrategyNumber)))
+ {
+ do_update = true;
+
+ /*
+ * figure out which key is leftmost (if the parent page is
+ * rightmost, too, it must be the root)
+ */
+ if (P_RIGHTMOST(ppageop))
+ upditem_offset = P_HIKEY;
+ else
+ upditem_offset = P_FIRSTKEY;
+ if (!P_LEFTMOST(lpageop) ||
+ stack->bts_offset != upditem_offset)
+ elog(FATAL, "btree: items are out of order (leftmost %d, stack %u, update %u)",
+ P_LEFTMOST(lpageop), stack->bts_offset, upditem_offset);
+ }
+
+ if (do_update)
+ {
+ if (shifted)
+ elog(FATAL, "btree: attempt to update parent for shifted page");
+
+ /*
+ * Try to update in place. If out parent page is chained
+ * then we must forse insertion.
+ */
+ if (!parent_chained &&
+ DOUBLEALIGN(IndexTupleDSize(lowLeftItem->bti_itup)) ==
+ DOUBLEALIGN(IndexTupleDSize(stack->bts_btitem->bti_itup)))
+ {
+ _bt_updateitem(rel, keysz, pbuf,
+ stack->bts_btitem, lowLeftItem);
+ _bt_relbuf(rel, buf, BT_WRITE);
+ _bt_relbuf(rel, rbuf, BT_WRITE);
+ }
+ else
+ {
+ update_in_place = false;
+ PageIndexTupleDelete(ppage, upditem_offset);
+
+ /*
+ * don't write anything out yet--we still have the
+ * write lock, and now we call another _bt_insertonpg
+ * to insert the correct key. First, make a new item,
+ * using the tuple data from lowLeftItem. Point it to
+ * the left child. Update it on the stack at the same
+ * time.
+ */
+ pfree(stack->bts_btitem);
+ stack->bts_btitem = _bt_formitem(&(lowLeftItem->bti_itup));
+ ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
+ bknum, P_HIKEY);
+
+ /*
+ * Unlock the children before doing this
+ *
+ * Mmm ... I foresee problems here. - vadim 06/10/97
+ */
+ _bt_relbuf(rel, buf, BT_WRITE);
+ _bt_relbuf(rel, rbuf, BT_WRITE);
+
+ /*
+ * A regular _bt_binsrch should find the right place
+ * to put the new entry, since it should be lower than
+ * any other key on the page. Therefore set afteritem
+ * to NULL.
+ */
+ newskey = _bt_mkscankey(rel, &(stack->bts_btitem->bti_itup));
+ newres = _bt_insertonpg(rel, pbuf, stack->bts_parent,
+ keysz, newskey, stack->bts_btitem,
+ NULL);
+
+ pfree(newres);
+ pfree(newskey);
+
+ /*
+ * we have now lost our lock on the parent buffer, and
+ * need to get it back.
+ */
+ pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
+ }
+ }
+ else
+ {
+ _bt_relbuf(rel, buf, BT_WRITE);
+ _bt_relbuf(rel, rbuf, BT_WRITE);
+ }
+
+ newskey = _bt_mkscankey(rel, &(new_item->bti_itup));
+
+ afteritem = stack->bts_btitem;
+ if (parent_chained && !update_in_place)
+ {
+ ppage = BufferGetPage(pbuf);
+ ppageop = (BTPageOpaque) PageGetSpecialPointer(ppage);
+ if (ppageop->btpo_flags & BTP_CHAIN)
+ elog(FATAL, "btree: unexpected BTP_CHAIN flag in parent after update");
+ if (P_RIGHTMOST(ppageop))
+ elog(FATAL, "btree: chained parent is RIGHTMOST after update");
+ maxoff = PageGetMaxOffsetNumber(ppage);
+ if (maxoff != P_FIRSTKEY)
+ elog(FATAL, "btree: FIRSTKEY was unexpected in parent after update");
+ if (_bt_skeycmp(rel, keysz, newskey, ppage,
+ PageGetItemId(ppage, P_FIRSTKEY),
+ BTLessEqualStrategyNumber))
+ elog(FATAL, "btree: parent FIRSTKEY is >= duplicate key after update");
+ if (!_bt_skeycmp(rel, keysz, newskey, ppage,
+ PageGetItemId(ppage, P_HIKEY),
+ BTEqualStrategyNumber))
+ elog(FATAL, "btree: parent HIGHKEY is not equal duplicate key after update");
+ afteritem = (BTItem) NULL;
+ }
+ else if (left_chained && !update_in_place)
+ {
+ ppage = BufferGetPage(pbuf);
+ ppageop = (BTPageOpaque) PageGetSpecialPointer(ppage);
+ if (!P_RIGHTMOST(ppageop) &&
+ _bt_skeycmp(rel, keysz, newskey, ppage,
+ PageGetItemId(ppage, P_HIKEY),
+ BTGreaterStrategyNumber))
+ afteritem = (BTItem) NULL;
+ }
+ if (afteritem == (BTItem) NULL)
+ {
+ rbuf = _bt_getbuf(rel, ppageop->btpo_next, BT_WRITE);
+ _bt_relbuf(rel, pbuf, BT_WRITE);
+ pbuf = rbuf;
+ }
+
+ newres = _bt_insertonpg(rel, pbuf, stack->bts_parent,
+ keysz, newskey, new_item,
+ afteritem);
+
+ /* be tidy */
+ pfree(newres);
+ pfree(newskey);
+ pfree(new_item);
}
- }
- else
- {
- _bt_relbuf(rel, buf, BT_WRITE);
- _bt_relbuf(rel, rbuf, BT_WRITE);
- }
-
- newskey = _bt_mkscankey(rel, &(new_item->bti_itup));
-
- afteritem = stack->bts_btitem;
- if ( parent_chained && !update_in_place )
- {
- ppage = BufferGetPage(pbuf);
- ppageop = (BTPageOpaque) PageGetSpecialPointer(ppage);
- if ( ppageop->btpo_flags & BTP_CHAIN )
- elog (FATAL, "btree: unexpected BTP_CHAIN flag in parent after update");
- if ( P_RIGHTMOST (ppageop) )
- elog (FATAL, "btree: chained parent is RIGHTMOST after update");
- maxoff = PageGetMaxOffsetNumber (ppage);
- if ( maxoff != P_FIRSTKEY )
- elog (FATAL, "btree: FIRSTKEY was unexpected in parent after update");
- if ( _bt_skeycmp (rel, keysz, newskey, ppage,
- PageGetItemId(ppage, P_FIRSTKEY),
- BTLessEqualStrategyNumber) )
- elog (FATAL, "btree: parent FIRSTKEY is >= duplicate key after update");
- if ( !_bt_skeycmp (rel, keysz, newskey, ppage,
- PageGetItemId(ppage, P_HIKEY),
- BTEqualStrategyNumber) )
- elog (FATAL, "btree: parent HIGHKEY is not equal duplicate key after update");
- afteritem = (BTItem) NULL;
- }
- else if ( left_chained && !update_in_place )
- {
- ppage = BufferGetPage(pbuf);
- ppageop = (BTPageOpaque) PageGetSpecialPointer(ppage);
- if ( !P_RIGHTMOST (ppageop) &&
- _bt_skeycmp (rel, keysz, newskey, ppage,
- PageGetItemId(ppage, P_HIKEY),
- BTGreaterStrategyNumber) )
- afteritem = (BTItem) NULL;
- }
- if ( afteritem == (BTItem) NULL)
- {
- rbuf = _bt_getbuf(rel, ppageop->btpo_next, BT_WRITE);
- _bt_relbuf(rel, pbuf, BT_WRITE);
- pbuf = rbuf;
- }
-
- newres = _bt_insertonpg(rel, pbuf, stack->bts_parent,
- keysz, newskey, new_item,
- afteritem);
-
- /* be tidy */
- pfree(newres);
- pfree(newskey);
- pfree(new_item);
}
- } else {
- itup_off = _bt_pgaddtup(rel, buf, keysz, scankey,
- itemsz, btitem, afteritem);
- itup_blkno = BufferGetBlockNumber(buf);
-
- _bt_relbuf(rel, buf, BT_WRITE);
- }
-
- /* by here, the new tuple is inserted */
- res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
- ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
-
- return (res);
+ else
+ {
+ itup_off = _bt_pgaddtup(rel, buf, keysz, scankey,
+ itemsz, btitem, afteritem);
+ itup_blkno = BufferGetBlockNumber(buf);
+
+ _bt_relbuf(rel, buf, BT_WRITE);
+ }
+
+ /* by here, the new tuple is inserted */
+ res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
+ ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
+
+ return (res);
}
/*
- * _bt_split() -- split a page in the btree.
+ * _bt_split() -- split a page in the btree.
*
- * On entry, buf is the page to split, and is write-locked and pinned.
- * Returns the new right sibling of buf, pinned and write-locked. The
- * pin and lock on buf are maintained.
+ * On entry, buf is the page to split, and is write-locked and pinned.
+ * Returns the new right sibling of buf, pinned and write-locked. The
+ * pin and lock on buf are maintained.
*/
-static Buffer
+static Buffer
_bt_split(Relation rel, Buffer buf, OffsetNumber firstright)
{
- Buffer rbuf;
- Page origpage;
- Page leftpage, rightpage;
- BTPageOpaque ropaque, lopaque, oopaque;
- Buffer sbuf;
- Page spage;
- BTPageOpaque sopaque;
- Size itemsz;
- ItemId itemid;
- BTItem item;
- OffsetNumber leftoff, rightoff;
- OffsetNumber start;
- OffsetNumber maxoff;
- OffsetNumber i;
-
- rbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
- origpage = BufferGetPage(buf);
- leftpage = PageGetTempPage(origpage, sizeof(BTPageOpaqueData));
- rightpage = BufferGetPage(rbuf);
-
- _bt_pageinit(rightpage, BufferGetPageSize(rbuf));
- _bt_pageinit(leftpage, BufferGetPageSize(buf));
-
- /* init btree private data */
- oopaque = (BTPageOpaque) PageGetSpecialPointer(origpage);
- lopaque = (BTPageOpaque) PageGetSpecialPointer(leftpage);
- ropaque = (BTPageOpaque) PageGetSpecialPointer(rightpage);
-
- /* if we're splitting this page, it won't be the root when we're done */
- oopaque->btpo_flags &= ~BTP_ROOT;
- oopaque->btpo_flags &= ~BTP_CHAIN;
- lopaque->btpo_flags = ropaque->btpo_flags = oopaque->btpo_flags;
- lopaque->btpo_prev = oopaque->btpo_prev;
- ropaque->btpo_prev = BufferGetBlockNumber(buf);
- lopaque->btpo_next = BufferGetBlockNumber(rbuf);
- ropaque->btpo_next = oopaque->btpo_next;
-
- /*
- * If the page we're splitting is not the rightmost page at its
- * level in the tree, then the first (0) entry on the page is the
- * high key for the page. We need to copy that to the right
- * half. Otherwise (meaning the rightmost page case), we should
- * treat the line pointers beginning at zero as user data.
- *
- * We leave a blank space at the start of the line table for the
- * left page. We'll come back later and fill it in with the high
- * key item we get from the right key.
- */
-
- leftoff = P_FIRSTKEY;
- ropaque->btpo_next = oopaque->btpo_next;
- if (! P_RIGHTMOST(oopaque)) {
- /* splitting a non-rightmost page, start at the first data item */
- start = P_FIRSTKEY;
-
- itemid = PageGetItemId(origpage, P_HIKEY);
- itemsz = ItemIdGetLength(itemid);
- item = (BTItem) PageGetItem(origpage, itemid);
- if ( PageAddItem(rightpage, (Item) item, itemsz, P_HIKEY, LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add hikey to the right sibling");
- rightoff = P_FIRSTKEY;
- } else {
- /* splitting a rightmost page, "high key" is the first data item */
- start = P_HIKEY;
-
- /* the new rightmost page will not have a high key */
- rightoff = P_HIKEY;
- }
- maxoff = PageGetMaxOffsetNumber(origpage);
- if ( firstright == InvalidOffsetNumber )
- {
- Size llimit = PageGetFreeSpace(leftpage) / 2;
- firstright = _bt_findsplitloc(rel, origpage, start, maxoff, llimit);
- }
-
- for (i = start; i <= maxoff; i = OffsetNumberNext(i)) {
- itemid = PageGetItemId(origpage, i);
+ Buffer rbuf;
+ Page origpage;
+ Page leftpage,
+ rightpage;
+ BTPageOpaque ropaque,
+ lopaque,
+ oopaque;
+ Buffer sbuf;
+ Page spage;
+ BTPageOpaque sopaque;
+ Size itemsz;
+ ItemId itemid;
+ BTItem item;
+ OffsetNumber leftoff,
+ rightoff;
+ OffsetNumber start;
+ OffsetNumber maxoff;
+ OffsetNumber i;
+
+ rbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
+ origpage = BufferGetPage(buf);
+ leftpage = PageGetTempPage(origpage, sizeof(BTPageOpaqueData));
+ rightpage = BufferGetPage(rbuf);
+
+ _bt_pageinit(rightpage, BufferGetPageSize(rbuf));
+ _bt_pageinit(leftpage, BufferGetPageSize(buf));
+
+ /* init btree private data */
+ oopaque = (BTPageOpaque) PageGetSpecialPointer(origpage);
+ lopaque = (BTPageOpaque) PageGetSpecialPointer(leftpage);
+ ropaque = (BTPageOpaque) PageGetSpecialPointer(rightpage);
+
+ /* if we're splitting this page, it won't be the root when we're done */
+ oopaque->btpo_flags &= ~BTP_ROOT;
+ oopaque->btpo_flags &= ~BTP_CHAIN;
+ lopaque->btpo_flags = ropaque->btpo_flags = oopaque->btpo_flags;
+ lopaque->btpo_prev = oopaque->btpo_prev;
+ ropaque->btpo_prev = BufferGetBlockNumber(buf);
+ lopaque->btpo_next = BufferGetBlockNumber(rbuf);
+ ropaque->btpo_next = oopaque->btpo_next;
+
+ /*
+ * If the page we're splitting is not the rightmost page at its level
+ * in the tree, then the first (0) entry on the page is the high key
+ * for the page. We need to copy that to the right half. Otherwise
+ * (meaning the rightmost page case), we should treat the line
+ * pointers beginning at zero as user data.
+ *
+ * We leave a blank space at the start of the line table for the left
+ * page. We'll come back later and fill it in with the high key item
+ * we get from the right key.
+ */
+
+ leftoff = P_FIRSTKEY;
+ ropaque->btpo_next = oopaque->btpo_next;
+ if (!P_RIGHTMOST(oopaque))
+ {
+ /* splitting a non-rightmost page, start at the first data item */
+ start = P_FIRSTKEY;
+
+ itemid = PageGetItemId(origpage, P_HIKEY);
+ itemsz = ItemIdGetLength(itemid);
+ item = (BTItem) PageGetItem(origpage, itemid);
+ if (PageAddItem(rightpage, (Item) item, itemsz, P_HIKEY, LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add hikey to the right sibling");
+ rightoff = P_FIRSTKEY;
+ }
+ else
+ {
+ /* splitting a rightmost page, "high key" is the first data item */
+ start = P_HIKEY;
+
+ /* the new rightmost page will not have a high key */
+ rightoff = P_HIKEY;
+ }
+ maxoff = PageGetMaxOffsetNumber(origpage);
+ if (firstright == InvalidOffsetNumber)
+ {
+ Size llimit = PageGetFreeSpace(leftpage) / 2;
+
+ firstright = _bt_findsplitloc(rel, origpage, start, maxoff, llimit);
+ }
+
+ for (i = start; i <= maxoff; i = OffsetNumberNext(i))
+ {
+ itemid = PageGetItemId(origpage, i);
+ itemsz = ItemIdGetLength(itemid);
+ item = (BTItem) PageGetItem(origpage, itemid);
+
+ /* decide which page to put it on */
+ if (i < firstright)
+ {
+ if (PageAddItem(leftpage, (Item) item, itemsz, leftoff,
+ LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add item to the left sibling");
+ leftoff = OffsetNumberNext(leftoff);
+ }
+ else
+ {
+ if (PageAddItem(rightpage, (Item) item, itemsz, rightoff,
+ LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add item to the right sibling");
+ rightoff = OffsetNumberNext(rightoff);
+ }
+ }
+
+ /*
+ * Okay, page has been split, high key on right page is correct. Now
+ * set the high key on the left page to be the min key on the right
+ * page.
+ */
+
+ if (P_RIGHTMOST(ropaque))
+ {
+ itemid = PageGetItemId(rightpage, P_HIKEY);
+ }
+ else
+ {
+ itemid = PageGetItemId(rightpage, P_FIRSTKEY);
+ }
itemsz = ItemIdGetLength(itemid);
- item = (BTItem) PageGetItem(origpage, itemid);
-
- /* decide which page to put it on */
- if (i < firstright) {
- if ( PageAddItem(leftpage, (Item) item, itemsz, leftoff,
- LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add item to the left sibling");
- leftoff = OffsetNumberNext(leftoff);
- } else {
- if ( PageAddItem(rightpage, (Item) item, itemsz, rightoff,
- LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add item to the right sibling");
- rightoff = OffsetNumberNext(rightoff);
+ item = (BTItem) PageGetItem(rightpage, itemid);
+
+ /*
+ * We left a hole for the high key on the left page; fill it. The
+ * modal crap is to tell the page manager to put the new item on the
+ * page and not screw around with anything else. Whoever designed
+ * this interface has presumably crawled back into the dung heap they
+ * came from. No one here will admit to it.
+ */
+
+ PageManagerModeSet(OverwritePageManagerMode);
+ if (PageAddItem(leftpage, (Item) item, itemsz, P_HIKEY, LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add hikey to the left sibling");
+ PageManagerModeSet(ShufflePageManagerMode);
+
+ /*
+ * By here, the original data page has been split into two new halves,
+ * and these are correct. The algorithm requires that the left page
+ * never move during a split, so we copy the new left page back on top
+ * of the original. Note that this is not a waste of time, since we
+ * also require (in the page management code) that the center of a
+ * page always be clean, and the most efficient way to guarantee this
+ * is just to compact the data by reinserting it into a new left page.
+ */
+
+ PageRestoreTempPage(leftpage, origpage);
+
+ /* write these guys out */
+ _bt_wrtnorelbuf(rel, rbuf);
+ _bt_wrtnorelbuf(rel, buf);
+
+ /*
+ * Finally, we need to grab the right sibling (if any) and fix the
+ * prev pointer there. We are guaranteed that this is deadlock-free
+ * since no other writer will be moving holding a lock on that page
+ * and trying to move left, and all readers release locks on a page
+ * before trying to fetch its neighbors.
+ */
+
+ if (!P_RIGHTMOST(ropaque))
+ {
+ sbuf = _bt_getbuf(rel, ropaque->btpo_next, BT_WRITE);
+ spage = BufferGetPage(sbuf);
+ sopaque = (BTPageOpaque) PageGetSpecialPointer(spage);
+ sopaque->btpo_prev = BufferGetBlockNumber(rbuf);
+
+ /* write and release the old right sibling */
+ _bt_wrtbuf(rel, sbuf);
}
- }
-
- /*
- * Okay, page has been split, high key on right page is correct. Now
- * set the high key on the left page to be the min key on the right
- * page.
- */
-
- if (P_RIGHTMOST(ropaque)) {
- itemid = PageGetItemId(rightpage, P_HIKEY);
- } else {
- itemid = PageGetItemId(rightpage, P_FIRSTKEY);
- }
- itemsz = ItemIdGetLength(itemid);
- item = (BTItem) PageGetItem(rightpage, itemid);
-
- /*
- * We left a hole for the high key on the left page; fill it. The
- * modal crap is to tell the page manager to put the new item on the
- * page and not screw around with anything else. Whoever designed
- * this interface has presumably crawled back into the dung heap they
- * came from. No one here will admit to it.
- */
-
- PageManagerModeSet(OverwritePageManagerMode);
- if ( PageAddItem(leftpage, (Item) item, itemsz, P_HIKEY, LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add hikey to the left sibling");
- PageManagerModeSet(ShufflePageManagerMode);
-
- /*
- * By here, the original data page has been split into two new halves,
- * and these are correct. The algorithm requires that the left page
- * never move during a split, so we copy the new left page back on top
- * of the original. Note that this is not a waste of time, since we
- * also require (in the page management code) that the center of a
- * page always be clean, and the most efficient way to guarantee this
- * is just to compact the data by reinserting it into a new left page.
- */
-
- PageRestoreTempPage(leftpage, origpage);
-
- /* write these guys out */
- _bt_wrtnorelbuf(rel, rbuf);
- _bt_wrtnorelbuf(rel, buf);
-
- /*
- * Finally, we need to grab the right sibling (if any) and fix the
- * prev pointer there. We are guaranteed that this is deadlock-free
- * since no other writer will be moving holding a lock on that page
- * and trying to move left, and all readers release locks on a page
- * before trying to fetch its neighbors.
- */
-
- if (! P_RIGHTMOST(ropaque)) {
- sbuf = _bt_getbuf(rel, ropaque->btpo_next, BT_WRITE);
- spage = BufferGetPage(sbuf);
- sopaque = (BTPageOpaque) PageGetSpecialPointer(spage);
- sopaque->btpo_prev = BufferGetBlockNumber(rbuf);
-
- /* write and release the old right sibling */
- _bt_wrtbuf(rel, sbuf);
- }
-
- /* split's done */
- return (rbuf);
+
+ /* split's done */
+ return (rbuf);
}
/*
- * _bt_findsplitloc() -- find a safe place to split a page.
+ * _bt_findsplitloc() -- find a safe place to split a page.
*
- * In order to guarantee the proper handling of searches for duplicate
- * keys, the first duplicate in the chain must either be the first
- * item on the page after the split, or the entire chain must be on
- * one of the two pages. That is,
- * [1 2 2 2 3 4 5]
- * must become
- * [1] [2 2 2 3 4 5]
- * or
- * [1 2 2 2] [3 4 5]
- * but not
- * [1 2 2] [2 3 4 5].
- * However,
- * [2 2 2 2 2 3 4]
- * may be split as
- * [2 2 2 2] [2 3 4].
+ * In order to guarantee the proper handling of searches for duplicate
+ * keys, the first duplicate in the chain must either be the first
+ * item on the page after the split, or the entire chain must be on
+ * one of the two pages. That is,
+ * [1 2 2 2 3 4 5]
+ * must become
+ * [1] [2 2 2 3 4 5]
+ * or
+ * [1 2 2 2] [3 4 5]
+ * but not
+ * [1 2 2] [2 3 4 5].
+ * However,
+ * [2 2 2 2 2 3 4]
+ * may be split as
+ * [2 2 2 2] [2 3 4].
*/
-static OffsetNumber
+static OffsetNumber
_bt_findsplitloc(Relation rel,
- Page page,
- OffsetNumber start,
- OffsetNumber maxoff,
- Size llimit)
+ Page page,
+ OffsetNumber start,
+ OffsetNumber maxoff,
+ Size llimit)
{
- OffsetNumber i;
- OffsetNumber saferight;
- ItemId nxtitemid, safeitemid;
- BTItem safeitem, nxtitem;
- Size nbytes;
- int natts;
-
- if ( start >= maxoff )
- elog (FATAL, "btree: cannot split if start (%d) >= maxoff (%d)",
- start, maxoff);
- natts = rel->rd_rel->relnatts;
- saferight = start;
- safeitemid = PageGetItemId(page, saferight);
- nbytes = ItemIdGetLength(safeitemid) + sizeof(ItemIdData);
- safeitem = (BTItem) PageGetItem(page, safeitemid);
-
- i = OffsetNumberNext(start);
-
- while (nbytes < llimit)
- {
- /* check the next item on the page */
- nxtitemid = PageGetItemId(page, i);
- nbytes += (ItemIdGetLength(nxtitemid) + sizeof(ItemIdData));
- nxtitem = (BTItem) PageGetItem(page, nxtitemid);
-
- /*
- * Test against last known safe item:
- * if the tuple we're looking at isn't equal to the last safe
- * one we saw, then it's our new safe tuple.
- */
- if ( !_bt_itemcmp (rel, natts,
- safeitem, nxtitem, BTEqualStrategyNumber) )
+ OffsetNumber i;
+ OffsetNumber saferight;
+ ItemId nxtitemid,
+ safeitemid;
+ BTItem safeitem,
+ nxtitem;
+ Size nbytes;
+ int natts;
+
+ if (start >= maxoff)
+ elog(FATAL, "btree: cannot split if start (%d) >= maxoff (%d)",
+ start, maxoff);
+ natts = rel->rd_rel->relnatts;
+ saferight = start;
+ safeitemid = PageGetItemId(page, saferight);
+ nbytes = ItemIdGetLength(safeitemid) + sizeof(ItemIdData);
+ safeitem = (BTItem) PageGetItem(page, safeitemid);
+
+ i = OffsetNumberNext(start);
+
+ while (nbytes < llimit)
{
- safeitem = nxtitem;
- saferight = i;
+ /* check the next item on the page */
+ nxtitemid = PageGetItemId(page, i);
+ nbytes += (ItemIdGetLength(nxtitemid) + sizeof(ItemIdData));
+ nxtitem = (BTItem) PageGetItem(page, nxtitemid);
+
+ /*
+ * Test against last known safe item: if the tuple we're looking
+ * at isn't equal to the last safe one we saw, then it's our new
+ * safe tuple.
+ */
+ if (!_bt_itemcmp(rel, natts,
+ safeitem, nxtitem, BTEqualStrategyNumber))
+ {
+ safeitem = nxtitem;
+ saferight = i;
+ }
+ if (i < maxoff)
+ i = OffsetNumberNext(i);
+ else
+ break;
}
- if ( i < maxoff )
- i = OffsetNumberNext(i);
- else
- break;
- }
-
- /*
- * If the chain of dups starts at the beginning of the page and extends
- * past the halfway mark, we can split it in the middle.
- */
-
- if (saferight == start)
- saferight = i;
-
- if ( saferight == maxoff && ( maxoff - start ) > 1 )
- saferight = start + ( maxoff - start ) / 2;
-
- return (saferight);
+
+ /*
+ * If the chain of dups starts at the beginning of the page and
+ * extends past the halfway mark, we can split it in the middle.
+ */
+
+ if (saferight == start)
+ saferight = i;
+
+ if (saferight == maxoff && (maxoff - start) > 1)
+ saferight = start + (maxoff - start) / 2;
+
+ return (saferight);
}
/*
- * _bt_newroot() -- Create a new root page for the index.
+ * _bt_newroot() -- Create a new root page for the index.
*
- * We've just split the old root page and need to create a new one.
- * In order to do this, we add a new root page to the file, then lock
- * the metadata page and update it. This is guaranteed to be deadlock-
- * free, because all readers release their locks on the metadata page
- * before trying to lock the root, and all writers lock the root before
- * trying to lock the metadata page. We have a write lock on the old
- * root page, so we have not introduced any cycles into the waits-for
- * graph.
+ * We've just split the old root page and need to create a new one.
+ * In order to do this, we add a new root page to the file, then lock
+ * the metadata page and update it. This is guaranteed to be deadlock-
+ * free, because all readers release their locks on the metadata page
+ * before trying to lock the root, and all writers lock the root before
+ * trying to lock the metadata page. We have a write lock on the old
+ * root page, so we have not introduced any cycles into the waits-for
+ * graph.
*
- * On entry, lbuf (the old root) and rbuf (its new peer) are write-
- * locked. We don't drop the locks in this routine; that's done by
- * the caller. On exit, a new root page exists with entries for the
- * two new children. The new root page is neither pinned nor locked.
+ * On entry, lbuf (the old root) and rbuf (its new peer) are write-
+ * locked. We don't drop the locks in this routine; that's done by
+ * the caller. On exit, a new root page exists with entries for the
+ * two new children. The new root page is neither pinned nor locked.
*/
static void
_bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
{
- Buffer rootbuf;
- Page lpage, rpage, rootpage;
- BlockNumber lbkno, rbkno;
- BlockNumber rootbknum;
- BTPageOpaque rootopaque;
- ItemId itemid;
- BTItem item;
- Size itemsz;
- BTItem new_item;
-
- /* get a new root page */
- rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
- rootpage = BufferGetPage(rootbuf);
- _bt_pageinit(rootpage, BufferGetPageSize(rootbuf));
-
- /* set btree special data */
- rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpage);
- rootopaque->btpo_prev = rootopaque->btpo_next = P_NONE;
- rootopaque->btpo_flags |= BTP_ROOT;
-
- /*
- * Insert the internal tuple pointers.
- */
-
- lbkno = BufferGetBlockNumber(lbuf);
- rbkno = BufferGetBlockNumber(rbuf);
- lpage = BufferGetPage(lbuf);
- rpage = BufferGetPage(rbuf);
-
- /*
- * step over the high key on the left page while building the
- * left page pointer.
- */
- itemid = PageGetItemId(lpage, P_FIRSTKEY);
- itemsz = ItemIdGetLength(itemid);
- item = (BTItem) PageGetItem(lpage, itemid);
- new_item = _bt_formitem(&(item->bti_itup));
- ItemPointerSet(&(new_item->bti_itup.t_tid), lbkno, P_HIKEY);
-
- /*
- * insert the left page pointer into the new root page. the root
- * page is the rightmost page on its level so the "high key" item
- * is the first data item.
- */
- if ( PageAddItem(rootpage, (Item) new_item, itemsz, P_HIKEY, LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add leftkey to new root page");
- pfree(new_item);
-
- /*
- * the right page is the rightmost page on the second level, so
- * the "high key" item is the first data item on that page as well.
- */
- itemid = PageGetItemId(rpage, P_HIKEY);
- itemsz = ItemIdGetLength(itemid);
- item = (BTItem) PageGetItem(rpage, itemid);
- new_item = _bt_formitem(&(item->bti_itup));
- ItemPointerSet(&(new_item->bti_itup.t_tid), rbkno, P_HIKEY);
-
- /*
- * insert the right page pointer into the new root page.
- */
- if ( PageAddItem(rootpage, (Item) new_item, itemsz, P_FIRSTKEY, LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add rightkey to new root page");
- pfree(new_item);
-
- /* write and let go of the root buffer */
- rootbknum = BufferGetBlockNumber(rootbuf);
- _bt_wrtbuf(rel, rootbuf);
-
- /* update metadata page with new root block number */
- _bt_metaproot(rel, rootbknum, 0);
+ Buffer rootbuf;
+ Page lpage,
+ rpage,
+ rootpage;
+ BlockNumber lbkno,
+ rbkno;
+ BlockNumber rootbknum;
+ BTPageOpaque rootopaque;
+ ItemId itemid;
+ BTItem item;
+ Size itemsz;
+ BTItem new_item;
+
+ /* get a new root page */
+ rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
+ rootpage = BufferGetPage(rootbuf);
+ _bt_pageinit(rootpage, BufferGetPageSize(rootbuf));
+
+ /* set btree special data */
+ rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpage);
+ rootopaque->btpo_prev = rootopaque->btpo_next = P_NONE;
+ rootopaque->btpo_flags |= BTP_ROOT;
+
+ /*
+ * Insert the internal tuple pointers.
+ */
+
+ lbkno = BufferGetBlockNumber(lbuf);
+ rbkno = BufferGetBlockNumber(rbuf);
+ lpage = BufferGetPage(lbuf);
+ rpage = BufferGetPage(rbuf);
+
+ /*
+ * step over the high key on the left page while building the left
+ * page pointer.
+ */
+ itemid = PageGetItemId(lpage, P_FIRSTKEY);
+ itemsz = ItemIdGetLength(itemid);
+ item = (BTItem) PageGetItem(lpage, itemid);
+ new_item = _bt_formitem(&(item->bti_itup));
+ ItemPointerSet(&(new_item->bti_itup.t_tid), lbkno, P_HIKEY);
+
+ /*
+ * insert the left page pointer into the new root page. the root page
+ * is the rightmost page on its level so the "high key" item is the
+ * first data item.
+ */
+ if (PageAddItem(rootpage, (Item) new_item, itemsz, P_HIKEY, LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add leftkey to new root page");
+ pfree(new_item);
+
+ /*
+ * the right page is the rightmost page on the second level, so the
+ * "high key" item is the first data item on that page as well.
+ */
+ itemid = PageGetItemId(rpage, P_HIKEY);
+ itemsz = ItemIdGetLength(itemid);
+ item = (BTItem) PageGetItem(rpage, itemid);
+ new_item = _bt_formitem(&(item->bti_itup));
+ ItemPointerSet(&(new_item->bti_itup.t_tid), rbkno, P_HIKEY);
+
+ /*
+ * insert the right page pointer into the new root page.
+ */
+ if (PageAddItem(rootpage, (Item) new_item, itemsz, P_FIRSTKEY, LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add rightkey to new root page");
+ pfree(new_item);
+
+ /* write and let go of the root buffer */
+ rootbknum = BufferGetBlockNumber(rootbuf);
+ _bt_wrtbuf(rel, rootbuf);
+
+ /* update metadata page with new root block number */
+ _bt_metaproot(rel, rootbknum, 0);
}
/*
- * _bt_pgaddtup() -- add a tuple to a particular page in the index.
+ * _bt_pgaddtup() -- add a tuple to a particular page in the index.
*
- * This routine adds the tuple to the page as requested, and keeps the
- * write lock and reference associated with the page's buffer. It is
- * an error to call pgaddtup() without a write lock and reference. If
- * afteritem is non-null, it's the item that we expect our new item
- * to follow. Otherwise, we do a binary search for the correct place
- * and insert the new item there.
+ * This routine adds the tuple to the page as requested, and keeps the
+ * write lock and reference associated with the page's buffer. It is
+ * an error to call pgaddtup() without a write lock and reference. If
+ * afteritem is non-null, it's the item that we expect our new item
+ * to follow. Otherwise, we do a binary search for the correct place
+ * and insert the new item there.
*/
-static OffsetNumber
+static OffsetNumber
_bt_pgaddtup(Relation rel,
- Buffer buf,
- int keysz,
- ScanKey itup_scankey,
- Size itemsize,
- BTItem btitem,
- BTItem afteritem)
+ Buffer buf,
+ int keysz,
+ ScanKey itup_scankey,
+ Size itemsize,
+ BTItem btitem,
+ BTItem afteritem)
{
- OffsetNumber itup_off;
- OffsetNumber first;
- Page page;
- BTPageOpaque opaque;
- BTItem chkitem;
-
- page = BufferGetPage(buf);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- first = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
-
- if (afteritem == (BTItem) NULL) {
- itup_off = _bt_binsrch(rel, buf, keysz, itup_scankey, BT_INSERTION);
- } else {
- itup_off = first;
-
- do {
- chkitem =
- (BTItem) PageGetItem(page, PageGetItemId(page, itup_off));
- itup_off = OffsetNumberNext(itup_off);
- } while ( ! BTItemSame (chkitem, afteritem) );
- }
-
- if ( PageAddItem(page, (Item) btitem, itemsize, itup_off, LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add item to the page");
-
- /* write the buffer, but hold our lock */
- _bt_wrtnorelbuf(rel, buf);
-
- return (itup_off);
+ OffsetNumber itup_off;
+ OffsetNumber first;
+ Page page;
+ BTPageOpaque opaque;
+ BTItem chkitem;
+
+ page = BufferGetPage(buf);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ first = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+
+ if (afteritem == (BTItem) NULL)
+ {
+ itup_off = _bt_binsrch(rel, buf, keysz, itup_scankey, BT_INSERTION);
+ }
+ else
+ {
+ itup_off = first;
+
+ do
+ {
+ chkitem =
+ (BTItem) PageGetItem(page, PageGetItemId(page, itup_off));
+ itup_off = OffsetNumberNext(itup_off);
+ } while (!BTItemSame(chkitem, afteritem));
+ }
+
+ if (PageAddItem(page, (Item) btitem, itemsize, itup_off, LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add item to the page");
+
+ /* write the buffer, but hold our lock */
+ _bt_wrtnorelbuf(rel, buf);
+
+ return (itup_off);
}
/*
- * _bt_goesonpg() -- Does a new tuple belong on this page?
+ * _bt_goesonpg() -- Does a new tuple belong on this page?
*
- * This is part of the complexity introduced by allowing duplicate
- * keys into the index. The tuple belongs on this page if:
+ * This is part of the complexity introduced by allowing duplicate
+ * keys into the index. The tuple belongs on this page if:
*
- * + there is no page to the right of this one; or
- * + it is less than the high key on the page; or
- * + the item it is to follow ("afteritem") appears on this
- * page.
+ * + there is no page to the right of this one; or
+ * + it is less than the high key on the page; or
+ * + the item it is to follow ("afteritem") appears on this
+ * page.
*/
-static bool
+static bool
_bt_goesonpg(Relation rel,
- Buffer buf,
- Size keysz,
- ScanKey scankey,
- BTItem afteritem)
+ Buffer buf,
+ Size keysz,
+ ScanKey scankey,
+ BTItem afteritem)
{
- Page page;
- ItemId hikey;
- BTPageOpaque opaque;
- BTItem chkitem;
- OffsetNumber offnum, maxoff;
- bool found;
-
- page = BufferGetPage(buf);
-
- /* no right neighbor? */
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- if (P_RIGHTMOST(opaque))
- return (true);
-
- /*
- * this is a non-rightmost page, so it must have a high key item.
- *
- * If the scan key is < the high key (the min key on the next page),
- * then it for sure belongs here.
- */
- hikey = PageGetItemId(page, P_HIKEY);
- if (_bt_skeycmp(rel, keysz, scankey, page, hikey, BTLessStrategyNumber))
- return (true);
-
- /*
- * If the scan key is > the high key, then it for sure doesn't belong
- * here.
- */
-
- if (_bt_skeycmp(rel, keysz, scankey, page, hikey, BTGreaterStrategyNumber))
- return (false);
-
- /*
- * If we have no adjacency information, and the item is equal to the
- * high key on the page (by here it is), then the item does not belong
- * on this page.
- *
- * Now it's not true in all cases. - vadim 06/10/97
- */
-
- if (afteritem == (BTItem) NULL)
- {
- if ( opaque->btpo_flags & BTP_LEAF )
- return (false);
- if ( opaque->btpo_flags & BTP_CHAIN )
- return (true);
- if ( _bt_skeycmp (rel, keysz, scankey, page,
- PageGetItemId(page, P_FIRSTKEY),
- BTEqualStrategyNumber) )
- return (true);
- return (false);
- }
-
- /* damn, have to work for it. i hate that. */
- maxoff = PageGetMaxOffsetNumber(page);
-
- /*
- * Search the entire page for the afteroid. We need to do this, rather
- * than doing a binary search and starting from there, because if the
- * key we're searching for is the leftmost key in the tree at this
- * level, then a binary search will do the wrong thing. Splits are
- * pretty infrequent, so the cost isn't as bad as it could be.
- */
-
- found = false;
- for (offnum = P_FIRSTKEY;
- offnum <= maxoff;
- offnum = OffsetNumberNext(offnum)) {
- chkitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
-
- if ( BTItemSame (chkitem, afteritem) ) {
- found = true;
- break;
+ Page page;
+ ItemId hikey;
+ BTPageOpaque opaque;
+ BTItem chkitem;
+ OffsetNumber offnum,
+ maxoff;
+ bool found;
+
+ page = BufferGetPage(buf);
+
+ /* no right neighbor? */
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ if (P_RIGHTMOST(opaque))
+ return (true);
+
+ /*
+ * this is a non-rightmost page, so it must have a high key item.
+ *
+ * If the scan key is < the high key (the min key on the next page), then
+ * it for sure belongs here.
+ */
+ hikey = PageGetItemId(page, P_HIKEY);
+ if (_bt_skeycmp(rel, keysz, scankey, page, hikey, BTLessStrategyNumber))
+ return (true);
+
+ /*
+ * If the scan key is > the high key, then it for sure doesn't belong
+ * here.
+ */
+
+ if (_bt_skeycmp(rel, keysz, scankey, page, hikey, BTGreaterStrategyNumber))
+ return (false);
+
+ /*
+ * If we have no adjacency information, and the item is equal to the
+ * high key on the page (by here it is), then the item does not belong
+ * on this page.
+ *
+ * Now it's not true in all cases. - vadim 06/10/97
+ */
+
+ if (afteritem == (BTItem) NULL)
+ {
+ if (opaque->btpo_flags & BTP_LEAF)
+ return (false);
+ if (opaque->btpo_flags & BTP_CHAIN)
+ return (true);
+ if (_bt_skeycmp(rel, keysz, scankey, page,
+ PageGetItemId(page, P_FIRSTKEY),
+ BTEqualStrategyNumber))
+ return (true);
+ return (false);
+ }
+
+ /* damn, have to work for it. i hate that. */
+ maxoff = PageGetMaxOffsetNumber(page);
+
+ /*
+ * Search the entire page for the afteroid. We need to do this,
+ * rather than doing a binary search and starting from there, because
+ * if the key we're searching for is the leftmost key in the tree at
+ * this level, then a binary search will do the wrong thing. Splits
+ * are pretty infrequent, so the cost isn't as bad as it could be.
+ */
+
+ found = false;
+ for (offnum = P_FIRSTKEY;
+ offnum <= maxoff;
+ offnum = OffsetNumberNext(offnum))
+ {
+ chkitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
+
+ if (BTItemSame(chkitem, afteritem))
+ {
+ found = true;
+ break;
+ }
}
- }
-
- return (found);
+
+ return (found);
}
/*
- * _bt_itemcmp() -- compare item1 to item2 using a requested
- * strategy (<, <=, =, >=, >)
+ * _bt_itemcmp() -- compare item1 to item2 using a requested
+ * strategy (<, <=, =, >=, >)
*
*/
bool
_bt_itemcmp(Relation rel,
- Size keysz,
- BTItem item1,
- BTItem item2,
- StrategyNumber strat)
+ Size keysz,
+ BTItem item1,
+ BTItem item2,
+ StrategyNumber strat)
{
- TupleDesc tupDes;
- IndexTuple indexTuple1, indexTuple2;
- Datum attrDatum1, attrDatum2;
- int i;
- bool isFirstNull, isSecondNull;
- bool compare;
- bool useEqual = false;
-
- if ( strat == BTLessEqualStrategyNumber )
- {
- useEqual = true;
- strat = BTLessStrategyNumber;
- }
- else if ( strat == BTGreaterEqualStrategyNumber )
- {
- useEqual = true;
- strat = BTGreaterStrategyNumber;
- }
-
- tupDes = RelationGetTupleDescriptor(rel);
- indexTuple1 = &(item1->bti_itup);
- indexTuple2 = &(item2->bti_itup);
-
- for (i = 1; i <= keysz; i++) {
- attrDatum1 = index_getattr(indexTuple1, i, tupDes, &isFirstNull);
- attrDatum2 = index_getattr(indexTuple2, i, tupDes, &isSecondNull);
-
- /* see comments about NULLs handling in btbuild */
- if ( isFirstNull ) /* attr in item1 is NULL */
+ TupleDesc tupDes;
+ IndexTuple indexTuple1,
+ indexTuple2;
+ Datum attrDatum1,
+ attrDatum2;
+ int i;
+ bool isFirstNull,
+ isSecondNull;
+ bool compare;
+ bool useEqual = false;
+
+ if (strat == BTLessEqualStrategyNumber)
{
- if ( isSecondNull ) /* attr in item2 is NULL too */
- compare = ( strat == BTEqualStrategyNumber ) ? true : false;
- else
- compare = ( strat == BTGreaterStrategyNumber ) ? true : false;
- }
- else if ( isSecondNull ) /* attr in item1 is NOT_NULL and */
- { /* and attr in item2 is NULL */
- compare = ( strat == BTLessStrategyNumber ) ? true : false;
- }
- else
- {
- compare = _bt_invokestrat(rel, i, strat, attrDatum1, attrDatum2);
+ useEqual = true;
+ strat = BTLessStrategyNumber;
}
-
- if ( compare ) /* true for one of ">, <, =" */
+ else if (strat == BTGreaterEqualStrategyNumber)
{
- if ( strat != BTEqualStrategyNumber )
- return (true);
+ useEqual = true;
+ strat = BTGreaterStrategyNumber;
}
- else /* false for one of ">, <, =" */
+
+ tupDes = RelationGetTupleDescriptor(rel);
+ indexTuple1 = &(item1->bti_itup);
+ indexTuple2 = &(item2->bti_itup);
+
+ for (i = 1; i <= keysz; i++)
{
- if ( strat == BTEqualStrategyNumber )
- return (false);
- /*
- * if original strat was "<=, >=" OR
- * "<, >" but some attribute(s) left
- * - need to test for Equality
- */
- if ( useEqual || i < keysz )
- {
- if ( isFirstNull || isSecondNull )
- compare = ( isFirstNull && isSecondNull ) ? true : false;
- else
- compare = _bt_invokestrat(rel, i, BTEqualStrategyNumber,
- attrDatum1, attrDatum2);
- if ( compare ) /* item1' and item2' attributes are equal */
- continue; /* - try to compare next attributes */
- }
- return (false);
+ attrDatum1 = index_getattr(indexTuple1, i, tupDes, &isFirstNull);
+ attrDatum2 = index_getattr(indexTuple2, i, tupDes, &isSecondNull);
+
+ /* see comments about NULLs handling in btbuild */
+ if (isFirstNull) /* attr in item1 is NULL */
+ {
+ if (isSecondNull) /* attr in item2 is NULL too */
+ compare = (strat == BTEqualStrategyNumber) ? true : false;
+ else
+ compare = (strat == BTGreaterStrategyNumber) ? true : false;
+ }
+ else if (isSecondNull) /* attr in item1 is NOT_NULL and */
+ { /* and attr in item2 is NULL */
+ compare = (strat == BTLessStrategyNumber) ? true : false;
+ }
+ else
+ {
+ compare = _bt_invokestrat(rel, i, strat, attrDatum1, attrDatum2);
+ }
+
+ if (compare) /* true for one of ">, <, =" */
+ {
+ if (strat != BTEqualStrategyNumber)
+ return (true);
+ }
+ else
+/* false for one of ">, <, =" */
+ {
+ if (strat == BTEqualStrategyNumber)
+ return (false);
+
+ /*
+ * if original strat was "<=, >=" OR "<, >" but some
+ * attribute(s) left - need to test for Equality
+ */
+ if (useEqual || i < keysz)
+ {
+ if (isFirstNull || isSecondNull)
+ compare = (isFirstNull && isSecondNull) ? true : false;
+ else
+ compare = _bt_invokestrat(rel, i, BTEqualStrategyNumber,
+ attrDatum1, attrDatum2);
+ if (compare) /* item1' and item2' attributes are equal */
+ continue; /* - try to compare next attributes */
+ }
+ return (false);
+ }
}
- }
- return (true);
+ return (true);
}
/*
- * _bt_updateitem() -- updates the key of the item identified by the
- * oid with the key of newItem (done in place if
- * possible)
+ * _bt_updateitem() -- updates the key of the item identified by the
+ * oid with the key of newItem (done in place if
+ * possible)
*
*/
static void
_bt_updateitem(Relation rel,
- Size keysz,
- Buffer buf,
- BTItem oldItem,
- BTItem newItem)
+ Size keysz,
+ Buffer buf,
+ BTItem oldItem,
+ BTItem newItem)
{
- Page page;
- OffsetNumber maxoff;
- OffsetNumber i;
- ItemPointerData itemPtrData;
- BTItem item;
- IndexTuple oldIndexTuple, newIndexTuple;
- int first;
-
- page = BufferGetPage(buf);
- maxoff = PageGetMaxOffsetNumber(page);
-
- /* locate item on the page */
- first = P_RIGHTMOST((BTPageOpaque) PageGetSpecialPointer(page))
- ? P_HIKEY : P_FIRSTKEY;
- i = first;
- do {
- item = (BTItem) PageGetItem(page, PageGetItemId(page, i));
- i = OffsetNumberNext(i);
- } while (i <= maxoff && ! BTItemSame (item, oldItem));
-
- /* this should never happen (in theory) */
- if ( ! BTItemSame (item, oldItem) ) {
- elog(FATAL, "_bt_getstackbuf was lying!!");
- }
-
- /*
- * It's defined by caller (_bt_insertonpg)
- */
- /*
- if(IndexTupleDSize(newItem->bti_itup) >
- IndexTupleDSize(item->bti_itup)) {
- elog(NOTICE, "trying to overwrite a smaller value with a bigger one in _bt_updateitem");
- elog(WARN, "this is not good.");
- }
- */
-
- oldIndexTuple = &(item->bti_itup);
- newIndexTuple = &(newItem->bti_itup);
+ Page page;
+ OffsetNumber maxoff;
+ OffsetNumber i;
+ ItemPointerData itemPtrData;
+ BTItem item;
+ IndexTuple oldIndexTuple,
+ newIndexTuple;
+ int first;
+
+ page = BufferGetPage(buf);
+ maxoff = PageGetMaxOffsetNumber(page);
+
+ /* locate item on the page */
+ first = P_RIGHTMOST((BTPageOpaque) PageGetSpecialPointer(page))
+ ? P_HIKEY : P_FIRSTKEY;
+ i = first;
+ do
+ {
+ item = (BTItem) PageGetItem(page, PageGetItemId(page, i));
+ i = OffsetNumberNext(i);
+ } while (i <= maxoff && !BTItemSame(item, oldItem));
+
+ /* this should never happen (in theory) */
+ if (!BTItemSame(item, oldItem))
+ {
+ elog(FATAL, "_bt_getstackbuf was lying!!");
+ }
+
+ /*
+ * It's defined by caller (_bt_insertonpg)
+ */
+
+ /*
+ * if(IndexTupleDSize(newItem->bti_itup) >
+ * IndexTupleDSize(item->bti_itup)) { elog(NOTICE, "trying to
+ * overwrite a smaller value with a bigger one in _bt_updateitem");
+ * elog(WARN, "this is not good."); }
+ */
+
+ oldIndexTuple = &(item->bti_itup);
+ newIndexTuple = &(newItem->bti_itup);
/* keep the original item pointer */
- ItemPointerCopy(&(oldIndexTuple->t_tid), &itemPtrData);
- CopyIndexTuple(newIndexTuple, &oldIndexTuple);
- ItemPointerCopy(&itemPtrData, &(oldIndexTuple->t_tid));
-
+ ItemPointerCopy(&(oldIndexTuple->t_tid), &itemPtrData);
+ CopyIndexTuple(newIndexTuple, &oldIndexTuple);
+ ItemPointerCopy(&itemPtrData, &(oldIndexTuple->t_tid));
+
}
/*
@@ -1409,177 +1460,179 @@ _bt_updateitem(Relation rel,
*
* Rule is simple: NOT_NULL not equal NULL, NULL not_equal NULL too.
*/
-static bool
-_bt_isequal (TupleDesc itupdesc, Page page, OffsetNumber offnum,
- int keysz, ScanKey scankey)
+static bool
+_bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum,
+ int keysz, ScanKey scankey)
{
- Datum datum;
- BTItem btitem;
- IndexTuple itup;
- ScanKey entry;
- AttrNumber attno;
- long result;
- int i;
- bool null;
-
- btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
- itup = &(btitem->bti_itup);
-
- for (i = 1; i <= keysz; i++)
- {
- entry = &scankey[i - 1];
- attno = entry->sk_attno;
- Assert (attno == i);
- datum = index_getattr(itup, attno, itupdesc, &null);
-
- /* NULLs are not equal */
- if ( entry->sk_flags & SK_ISNULL || null )
- return (false);
-
- result = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
- entry->sk_argument, datum);
- if (result != 0)
- return (false);
- }
-
- /* by here, the keys are equal */
- return (true);
+ Datum datum;
+ BTItem btitem;
+ IndexTuple itup;
+ ScanKey entry;
+ AttrNumber attno;
+ long result;
+ int i;
+ bool null;
+
+ btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
+ itup = &(btitem->bti_itup);
+
+ for (i = 1; i <= keysz; i++)
+ {
+ entry = &scankey[i - 1];
+ attno = entry->sk_attno;
+ Assert(attno == i);
+ datum = index_getattr(itup, attno, itupdesc, &null);
+
+ /* NULLs are not equal */
+ if (entry->sk_flags & SK_ISNULL || null)
+ return (false);
+
+ result = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
+ entry->sk_argument, datum);
+ if (result != 0)
+ return (false);
+ }
+
+ /* by here, the keys are equal */
+ return (true);
}
#ifdef NOT_USED
/*
- * _bt_shift - insert btitem on the passed page after shifting page
- * to the right in the tree.
+ * _bt_shift - insert btitem on the passed page after shifting page
+ * to the right in the tree.
*
* NOTE: tested for shifting leftmost page only, having btitem < hikey.
*/
-static InsertIndexResult
-_bt_shift (Relation rel, Buffer buf, BTStack stack, int keysz,
- ScanKey scankey, BTItem btitem, BTItem hikey)
+static InsertIndexResult
+_bt_shift(Relation rel, Buffer buf, BTStack stack, int keysz,
+ ScanKey scankey, BTItem btitem, BTItem hikey)
{
- InsertIndexResult res;
- int itemsz;
- Page page;
- BlockNumber bknum;
- BTPageOpaque pageop;
- Buffer rbuf;
- Page rpage;
- BTPageOpaque rpageop;
- Buffer pbuf;
- Page ppage;
- BTPageOpaque ppageop;
- Buffer nbuf;
- Page npage;
- BTPageOpaque npageop;
- BlockNumber nbknum;
- BTItem nitem;
- OffsetNumber afteroff;
-
- btitem = _bt_formitem(&(btitem->bti_itup));
- hikey = _bt_formitem(&(hikey->bti_itup));
-
- page = BufferGetPage(buf);
-
- /* grab new page */
- nbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
- nbknum = BufferGetBlockNumber(nbuf);
- npage = BufferGetPage(nbuf);
- _bt_pageinit(npage, BufferGetPageSize(nbuf));
- npageop = (BTPageOpaque) PageGetSpecialPointer(npage);
-
- /* copy content of the passed page */
- memmove ((char *) npage, (char *) page, BufferGetPageSize(buf));
-
- /* re-init old (passed) page */
- _bt_pageinit(page, BufferGetPageSize(buf));
- pageop = (BTPageOpaque) PageGetSpecialPointer(page);
-
- /* init old page opaque */
- pageop->btpo_flags = npageop->btpo_flags; /* restore flags */
- pageop->btpo_flags &= ~BTP_CHAIN;
- if ( _bt_itemcmp (rel, keysz, hikey, btitem, BTEqualStrategyNumber) )
- pageop->btpo_flags |= BTP_CHAIN;
- pageop->btpo_prev = npageop->btpo_prev; /* restore prev */
- pageop->btpo_next = nbknum; /* next points to the new page */
-
- /* init shifted page opaque */
- npageop->btpo_prev = bknum = BufferGetBlockNumber(buf);
-
- /* shifted page is ok, populate old page */
-
- /* add passed hikey */
- itemsz = IndexTupleDSize(hikey->bti_itup)
- + (sizeof(BTItemData) - sizeof(IndexTupleData));
- itemsz = DOUBLEALIGN(itemsz);
- if ( PageAddItem(page, (Item) hikey, itemsz, P_HIKEY, LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add hikey in _bt_shift");
- pfree (hikey);
-
- /* add btitem */
- itemsz = IndexTupleDSize(btitem->bti_itup)
- + (sizeof(BTItemData) - sizeof(IndexTupleData));
- itemsz = DOUBLEALIGN(itemsz);
- if ( PageAddItem(page, (Item) btitem, itemsz, P_FIRSTKEY, LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add firstkey in _bt_shift");
- pfree (btitem);
- nitem = (BTItem) PageGetItem(page, PageGetItemId(page, P_FIRSTKEY));
- btitem = _bt_formitem(&(nitem->bti_itup));
- ItemPointerSet(&(btitem->bti_itup.t_tid), bknum, P_HIKEY);
-
- /* ok, write them out */
- _bt_wrtnorelbuf(rel, nbuf);
- _bt_wrtnorelbuf(rel, buf);
-
- /* fix btpo_prev on right sibling of old page */
- if ( !P_RIGHTMOST (npageop) )
- {
- rbuf = _bt_getbuf(rel, npageop->btpo_next, BT_WRITE);
- rpage = BufferGetPage(rbuf);
- rpageop = (BTPageOpaque) PageGetSpecialPointer(rpage);
- rpageop->btpo_prev = nbknum;
- _bt_wrtbuf(rel, rbuf);
- }
-
- /* get parent pointing to the old page */
- ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
- bknum, P_HIKEY);
- pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
- ppage = BufferGetPage(pbuf);
- ppageop = (BTPageOpaque) PageGetSpecialPointer(ppage);
-
- _bt_relbuf(rel, nbuf, BT_WRITE);
- _bt_relbuf(rel, buf, BT_WRITE);
-
- /* re-set parent' pointer - we shifted our page to the right ! */
- nitem = (BTItem) PageGetItem (ppage,
- PageGetItemId (ppage, stack->bts_offset));
- ItemPointerSet(&(nitem->bti_itup.t_tid), nbknum, P_HIKEY);
- ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid), nbknum, P_HIKEY);
- _bt_wrtnorelbuf(rel, pbuf);
-
- /*
- * Now we want insert into the parent pointer to our old page. It has to
- * be inserted before the pointer to new page. You may get problems here
- * (in the _bt_goesonpg and/or _bt_pgaddtup), but may be not - I don't
- * know. It works if old page is leftmost (nitem is NULL) and
- * btitem < hikey and it's all what we need currently. - vadim 05/30/97
- */
- nitem = NULL;
- afteroff = P_FIRSTKEY;
- if ( !P_RIGHTMOST (ppageop) )
- afteroff = OffsetNumberNext (afteroff);
- if ( stack->bts_offset >= afteroff )
- {
- afteroff = OffsetNumberPrev (stack->bts_offset);
- nitem = (BTItem) PageGetItem (ppage, PageGetItemId (ppage, afteroff));
- nitem = _bt_formitem(&(nitem->bti_itup));
- }
- res = _bt_insertonpg(rel, pbuf, stack->bts_parent,
- keysz, scankey, btitem, nitem);
- pfree (btitem);
-
- ItemPointerSet(&(res->pointerData), nbknum, P_HIKEY);
-
- return (res);
+ InsertIndexResult res;
+ int itemsz;
+ Page page;
+ BlockNumber bknum;
+ BTPageOpaque pageop;
+ Buffer rbuf;
+ Page rpage;
+ BTPageOpaque rpageop;
+ Buffer pbuf;
+ Page ppage;
+ BTPageOpaque ppageop;
+ Buffer nbuf;
+ Page npage;
+ BTPageOpaque npageop;
+ BlockNumber nbknum;
+ BTItem nitem;
+ OffsetNumber afteroff;
+
+ btitem = _bt_formitem(&(btitem->bti_itup));
+ hikey = _bt_formitem(&(hikey->bti_itup));
+
+ page = BufferGetPage(buf);
+
+ /* grab new page */
+ nbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
+ nbknum = BufferGetBlockNumber(nbuf);
+ npage = BufferGetPage(nbuf);
+ _bt_pageinit(npage, BufferGetPageSize(nbuf));
+ npageop = (BTPageOpaque) PageGetSpecialPointer(npage);
+
+ /* copy content of the passed page */
+ memmove((char *) npage, (char *) page, BufferGetPageSize(buf));
+
+ /* re-init old (passed) page */
+ _bt_pageinit(page, BufferGetPageSize(buf));
+ pageop = (BTPageOpaque) PageGetSpecialPointer(page);
+
+ /* init old page opaque */
+ pageop->btpo_flags = npageop->btpo_flags; /* restore flags */
+ pageop->btpo_flags &= ~BTP_CHAIN;
+ if (_bt_itemcmp(rel, keysz, hikey, btitem, BTEqualStrategyNumber))
+ pageop->btpo_flags |= BTP_CHAIN;
+ pageop->btpo_prev = npageop->btpo_prev; /* restore prev */
+ pageop->btpo_next = nbknum; /* next points to the new page */
+
+ /* init shifted page opaque */
+ npageop->btpo_prev = bknum = BufferGetBlockNumber(buf);
+
+ /* shifted page is ok, populate old page */
+
+ /* add passed hikey */
+ itemsz = IndexTupleDSize(hikey->bti_itup)
+ + (sizeof(BTItemData) - sizeof(IndexTupleData));
+ itemsz = DOUBLEALIGN(itemsz);
+ if (PageAddItem(page, (Item) hikey, itemsz, P_HIKEY, LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add hikey in _bt_shift");
+ pfree(hikey);
+
+ /* add btitem */
+ itemsz = IndexTupleDSize(btitem->bti_itup)
+ + (sizeof(BTItemData) - sizeof(IndexTupleData));
+ itemsz = DOUBLEALIGN(itemsz);
+ if (PageAddItem(page, (Item) btitem, itemsz, P_FIRSTKEY, LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add firstkey in _bt_shift");
+ pfree(btitem);
+ nitem = (BTItem) PageGetItem(page, PageGetItemId(page, P_FIRSTKEY));
+ btitem = _bt_formitem(&(nitem->bti_itup));
+ ItemPointerSet(&(btitem->bti_itup.t_tid), bknum, P_HIKEY);
+
+ /* ok, write them out */
+ _bt_wrtnorelbuf(rel, nbuf);
+ _bt_wrtnorelbuf(rel, buf);
+
+ /* fix btpo_prev on right sibling of old page */
+ if (!P_RIGHTMOST(npageop))
+ {
+ rbuf = _bt_getbuf(rel, npageop->btpo_next, BT_WRITE);
+ rpage = BufferGetPage(rbuf);
+ rpageop = (BTPageOpaque) PageGetSpecialPointer(rpage);
+ rpageop->btpo_prev = nbknum;
+ _bt_wrtbuf(rel, rbuf);
+ }
+
+ /* get parent pointing to the old page */
+ ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
+ bknum, P_HIKEY);
+ pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
+ ppage = BufferGetPage(pbuf);
+ ppageop = (BTPageOpaque) PageGetSpecialPointer(ppage);
+
+ _bt_relbuf(rel, nbuf, BT_WRITE);
+ _bt_relbuf(rel, buf, BT_WRITE);
+
+ /* re-set parent' pointer - we shifted our page to the right ! */
+ nitem = (BTItem) PageGetItem(ppage,
+ PageGetItemId(ppage, stack->bts_offset));
+ ItemPointerSet(&(nitem->bti_itup.t_tid), nbknum, P_HIKEY);
+ ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid), nbknum, P_HIKEY);
+ _bt_wrtnorelbuf(rel, pbuf);
+
+ /*
+ * Now we want insert into the parent pointer to our old page. It has
+ * to be inserted before the pointer to new page. You may get problems
+ * here (in the _bt_goesonpg and/or _bt_pgaddtup), but may be not - I
+ * don't know. It works if old page is leftmost (nitem is NULL) and
+ * btitem < hikey and it's all what we need currently. - vadim
+ * 05/30/97
+ */
+ nitem = NULL;
+ afteroff = P_FIRSTKEY;
+ if (!P_RIGHTMOST(ppageop))
+ afteroff = OffsetNumberNext(afteroff);
+ if (stack->bts_offset >= afteroff)
+ {
+ afteroff = OffsetNumberPrev(stack->bts_offset);
+ nitem = (BTItem) PageGetItem(ppage, PageGetItemId(ppage, afteroff));
+ nitem = _bt_formitem(&(nitem->bti_itup));
+ }
+ res = _bt_insertonpg(rel, pbuf, stack->bts_parent,
+ keysz, scankey, btitem, nitem);
+ pfree(btitem);
+
+ ItemPointerSet(&(res->pointerData), nbknum, P_HIKEY);
+
+ return (res);
}
+
#endif
diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c
index 9142c557378..6551af4c17c 100644
--- a/src/backend/access/nbtree/nbtpage.c
+++ b/src/backend/access/nbtree/nbtpage.c
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nbtpage.c--
- * BTree-specific page management code for the Postgres btree access
- * method.
+ * BTree-specific page management code for the Postgres btree access
+ * method.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.9 1997/08/19 21:29:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.10 1997/09/07 04:38:52 momjian Exp $
*
- * NOTES
- * Postgres btree pages look like ordinary relation pages. The opaque
- * data at high addresses includes pointers to left and right siblings
- * and flag data describing page state. The first page in a btree, page
- * zero, is special -- it stores meta-information describing the tree.
- * Pages one and higher store the actual tree data.
+ * NOTES
+ * Postgres btree pages look like ordinary relation pages. The opaque
+ * data at high addresses includes pointers to left and right siblings
+ * and flag data describing page state. The first page in a btree, page
+ * zero, is special -- it stores meta-information describing the tree.
+ * Pages one and higher store the actual tree data.
*
*-------------------------------------------------------------------------
*/
@@ -31,16 +31,16 @@
#include <storage/lmgr.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static void _bt_setpagelock(Relation rel, BlockNumber blkno, int access);
-static void _bt_unsetpagelock(Relation rel, BlockNumber blkno, int access);
+static void _bt_setpagelock(Relation rel, BlockNumber blkno, int access);
+static void _bt_unsetpagelock(Relation rel, BlockNumber blkno, int access);
#define BTREE_METAPAGE 0
-#define BTREE_MAGIC 0x053162
+#define BTREE_MAGIC 0x053162
#ifdef BTREE_VERSION_1
#define BTREE_VERSION 1
@@ -48,546 +48,574 @@ static void _bt_unsetpagelock(Relation rel, BlockNumber blkno, int access);
#define BTREE_VERSION 0
#endif
-typedef struct BTMetaPageData {
- uint32 btm_magic;
- uint32 btm_version;
- BlockNumber btm_root;
+typedef struct BTMetaPageData
+{
+ uint32 btm_magic;
+ uint32 btm_version;
+ BlockNumber btm_root;
#ifdef BTREE_VERSION_1
- int32 btm_level;
+ int32 btm_level;
#endif
-} BTMetaPageData;
+} BTMetaPageData;
-#define BTPageGetMeta(p) \
- ((BTMetaPageData *) &((PageHeader) p)->pd_linp[0])
+#define BTPageGetMeta(p) \
+ ((BTMetaPageData *) &((PageHeader) p)->pd_linp[0])
-extern bool BuildingBtree;
+extern bool BuildingBtree;
/*
- * We use high-concurrency locking on btrees. There are two cases in
- * which we don't do locking. One is when we're building the btree.
- * Since the creating transaction has not committed, no one can see
- * the index, and there's no reason to share locks. The second case
- * is when we're just starting up the database system. We use some
- * special-purpose initialization code in the relation cache manager
- * (see utils/cache/relcache.c) to allow us to do indexed scans on
- * the system catalogs before we'd normally be able to. This happens
- * before the lock table is fully initialized, so we can't use it.
- * Strictly speaking, this violates 2pl, but we don't do 2pl on the
- * system catalogs anyway, so I declare this to be okay.
+ * We use high-concurrency locking on btrees. There are two cases in
+ * which we don't do locking. One is when we're building the btree.
+ * Since the creating transaction has not committed, no one can see
+ * the index, and there's no reason to share locks. The second case
+ * is when we're just starting up the database system. We use some
+ * special-purpose initialization code in the relation cache manager
+ * (see utils/cache/relcache.c) to allow us to do indexed scans on
+ * the system catalogs before we'd normally be able to. This happens
+ * before the lock table is fully initialized, so we can't use it.
+ * Strictly speaking, this violates 2pl, but we don't do 2pl on the
+ * system catalogs anyway, so I declare this to be okay.
*/
-#define USELOCKING (!BuildingBtree && !IsInitProcessingMode())
+#define USELOCKING (!BuildingBtree && !IsInitProcessingMode())
/*
- * _bt_metapinit() -- Initialize the metadata page of a btree.
+ * _bt_metapinit() -- Initialize the metadata page of a btree.
*/
void
_bt_metapinit(Relation rel)
{
- Buffer buf;
- Page pg;
- int nblocks;
- BTMetaPageData metad;
- BTPageOpaque op;
-
- /* can't be sharing this with anyone, now... */
- if (USELOCKING)
- RelationSetLockForWrite(rel);
-
- if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0) {
- elog(WARN, "Cannot initialize non-empty btree %s",
- RelationGetRelationName(rel));
- }
-
- buf = ReadBuffer(rel, P_NEW);
- pg = BufferGetPage(buf);
- _bt_pageinit(pg, BufferGetPageSize(buf));
-
- metad.btm_magic = BTREE_MAGIC;
- metad.btm_version = BTREE_VERSION;
- metad.btm_root = P_NONE;
+ Buffer buf;
+ Page pg;
+ int nblocks;
+ BTMetaPageData metad;
+ BTPageOpaque op;
+
+ /* can't be sharing this with anyone, now... */
+ if (USELOCKING)
+ RelationSetLockForWrite(rel);
+
+ if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0)
+ {
+ elog(WARN, "Cannot initialize non-empty btree %s",
+ RelationGetRelationName(rel));
+ }
+
+ buf = ReadBuffer(rel, P_NEW);
+ pg = BufferGetPage(buf);
+ _bt_pageinit(pg, BufferGetPageSize(buf));
+
+ metad.btm_magic = BTREE_MAGIC;
+ metad.btm_version = BTREE_VERSION;
+ metad.btm_root = P_NONE;
#ifdef BTREE_VERSION_1
- metad.btm_level = 0;
+ metad.btm_level = 0;
#endif
- memmove((char *) BTPageGetMeta(pg), (char *) &metad, sizeof(metad));
-
- op = (BTPageOpaque) PageGetSpecialPointer(pg);
- op->btpo_flags = BTP_META;
-
- WriteBuffer(buf);
-
- /* all done */
- if (USELOCKING)
- RelationUnsetLockForWrite(rel);
+ memmove((char *) BTPageGetMeta(pg), (char *) &metad, sizeof(metad));
+
+ op = (BTPageOpaque) PageGetSpecialPointer(pg);
+ op->btpo_flags = BTP_META;
+
+ WriteBuffer(buf);
+
+ /* all done */
+ if (USELOCKING)
+ RelationUnsetLockForWrite(rel);
}
#ifdef NOT_USED
/*
- * _bt_checkmeta() -- Verify that the metadata stored in a btree are
- * reasonable.
+ * _bt_checkmeta() -- Verify that the metadata stored in a btree are
+ * reasonable.
*/
void
_bt_checkmeta(Relation rel)
{
- Buffer metabuf;
- Page metap;
- BTMetaPageData *metad;
- BTPageOpaque op;
- int nblocks;
-
- /* if the relation is empty, this is init time; don't complain */
- if ((nblocks = RelationGetNumberOfBlocks(rel)) == 0)
- return;
-
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
- metap = BufferGetPage(metabuf);
- op = (BTPageOpaque) PageGetSpecialPointer(metap);
- if (!(op->btpo_flags & BTP_META)) {
- elog(WARN, "Invalid metapage for index %s",
- RelationGetRelationName(rel));
- }
- metad = BTPageGetMeta(metap);
-
- if (metad->btm_magic != BTREE_MAGIC) {
- elog(WARN, "Index %s is not a btree",
- RelationGetRelationName(rel));
- }
-
- if (metad->btm_version != BTREE_VERSION) {
- elog(WARN, "Version mismatch on %s: version %d file, version %d code",
- RelationGetRelationName(rel),
- metad->btm_version, BTREE_VERSION);
- }
-
- _bt_relbuf(rel, metabuf, BT_READ);
+ Buffer metabuf;
+ Page metap;
+ BTMetaPageData *metad;
+ BTPageOpaque op;
+ int nblocks;
+
+ /* if the relation is empty, this is init time; don't complain */
+ if ((nblocks = RelationGetNumberOfBlocks(rel)) == 0)
+ return;
+
+ metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
+ metap = BufferGetPage(metabuf);
+ op = (BTPageOpaque) PageGetSpecialPointer(metap);
+ if (!(op->btpo_flags & BTP_META))
+ {
+ elog(WARN, "Invalid metapage for index %s",
+ RelationGetRelationName(rel));
+ }
+ metad = BTPageGetMeta(metap);
+
+ if (metad->btm_magic != BTREE_MAGIC)
+ {
+ elog(WARN, "Index %s is not a btree",
+ RelationGetRelationName(rel));
+ }
+
+ if (metad->btm_version != BTREE_VERSION)
+ {
+ elog(WARN, "Version mismatch on %s: version %d file, version %d code",
+ RelationGetRelationName(rel),
+ metad->btm_version, BTREE_VERSION);
+ }
+
+ _bt_relbuf(rel, metabuf, BT_READ);
}
+
#endif
/*
- * _bt_getroot() -- Get the root page of the btree.
+ * _bt_getroot() -- Get the root page of the btree.
*
- * Since the root page can move around the btree file, we have to read
- * its location from the metadata page, and then read the root page
- * itself. If no root page exists yet, we have to create one. The
- * standard class of race conditions exists here; I think I covered
- * them all in the Hopi Indian rain dance of lock requests below.
+ * Since the root page can move around the btree file, we have to read
+ * its location from the metadata page, and then read the root page
+ * itself. If no root page exists yet, we have to create one. The
+ * standard class of race conditions exists here; I think I covered
+ * them all in the Hopi Indian rain dance of lock requests below.
*
- * We pass in the access type (BT_READ or BT_WRITE), and return the
- * root page's buffer with the appropriate lock type set. Reference
- * count on the root page gets bumped by ReadBuffer. The metadata
- * page is unlocked and unreferenced by this process when this routine
- * returns.
+ * We pass in the access type (BT_READ or BT_WRITE), and return the
+ * root page's buffer with the appropriate lock type set. Reference
+ * count on the root page gets bumped by ReadBuffer. The metadata
+ * page is unlocked and unreferenced by this process when this routine
+ * returns.
*/
Buffer
_bt_getroot(Relation rel, int access)
{
- Buffer metabuf;
- Page metapg;
- BTPageOpaque metaopaque;
- Buffer rootbuf;
- Page rootpg;
- BTPageOpaque rootopaque;
- BlockNumber rootblkno;
- BTMetaPageData *metad;
-
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
- metapg = BufferGetPage(metabuf);
- metaopaque = (BTPageOpaque) PageGetSpecialPointer(metapg);
- Assert(metaopaque->btpo_flags & BTP_META);
- metad = BTPageGetMeta(metapg);
-
- if (metad->btm_magic != BTREE_MAGIC) {
- elog(WARN, "Index %s is not a btree",
- RelationGetRelationName(rel));
- }
-
- if (metad->btm_version != BTREE_VERSION) {
- elog(WARN, "Version mismatch on %s: version %d file, version %d code",
- RelationGetRelationName(rel),
- metad->btm_version, BTREE_VERSION);
- }
-
- /* if no root page initialized yet, do it */
- if (metad->btm_root == P_NONE) {
-
- /* turn our read lock in for a write lock */
- _bt_relbuf(rel, metabuf, BT_READ);
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE);
+ Buffer metabuf;
+ Page metapg;
+ BTPageOpaque metaopaque;
+ Buffer rootbuf;
+ Page rootpg;
+ BTPageOpaque rootopaque;
+ BlockNumber rootblkno;
+ BTMetaPageData *metad;
+
+ metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ);
metapg = BufferGetPage(metabuf);
metaopaque = (BTPageOpaque) PageGetSpecialPointer(metapg);
Assert(metaopaque->btpo_flags & BTP_META);
metad = BTPageGetMeta(metapg);
-
- /*
- * Race condition: if someone else initialized the metadata between
- * the time we released the read lock and acquired the write lock,
- * above, we want to avoid doing it again.
- */
-
- if (metad->btm_root == P_NONE) {
-
- /*
- * Get, initialize, write, and leave a lock of the appropriate
- * type on the new root page. Since this is the first page in
- * the tree, it's a leaf.
- */
-
- rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
- rootblkno = BufferGetBlockNumber(rootbuf);
- rootpg = BufferGetPage(rootbuf);
- metad->btm_root = rootblkno;
+
+ if (metad->btm_magic != BTREE_MAGIC)
+ {
+ elog(WARN, "Index %s is not a btree",
+ RelationGetRelationName(rel));
+ }
+
+ if (metad->btm_version != BTREE_VERSION)
+ {
+ elog(WARN, "Version mismatch on %s: version %d file, version %d code",
+ RelationGetRelationName(rel),
+ metad->btm_version, BTREE_VERSION);
+ }
+
+ /* if no root page initialized yet, do it */
+ if (metad->btm_root == P_NONE)
+ {
+
+ /* turn our read lock in for a write lock */
+ _bt_relbuf(rel, metabuf, BT_READ);
+ metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE);
+ metapg = BufferGetPage(metabuf);
+ metaopaque = (BTPageOpaque) PageGetSpecialPointer(metapg);
+ Assert(metaopaque->btpo_flags & BTP_META);
+ metad = BTPageGetMeta(metapg);
+
+ /*
+ * Race condition: if someone else initialized the metadata
+ * between the time we released the read lock and acquired the
+ * write lock, above, we want to avoid doing it again.
+ */
+
+ if (metad->btm_root == P_NONE)
+ {
+
+ /*
+ * Get, initialize, write, and leave a lock of the appropriate
+ * type on the new root page. Since this is the first page in
+ * the tree, it's a leaf.
+ */
+
+ rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
+ rootblkno = BufferGetBlockNumber(rootbuf);
+ rootpg = BufferGetPage(rootbuf);
+ metad->btm_root = rootblkno;
#ifdef BTREE_VERSION_1
- metad->btm_level = 1;
+ metad->btm_level = 1;
#endif
- _bt_pageinit(rootpg, BufferGetPageSize(rootbuf));
- rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpg);
- rootopaque->btpo_flags |= (BTP_LEAF | BTP_ROOT);
- _bt_wrtnorelbuf(rel, rootbuf);
-
- /* swap write lock for read lock, if appropriate */
- if (access != BT_WRITE) {
- _bt_setpagelock(rel, rootblkno, BT_READ);
- _bt_unsetpagelock(rel, rootblkno, BT_WRITE);
- }
-
- /* okay, metadata is correct */
- _bt_wrtbuf(rel, metabuf);
- } else {
-
- /*
- * Metadata initialized by someone else. In order to guarantee
- * no deadlocks, we have to release the metadata page and start
- * all over again.
- */
-
- _bt_relbuf(rel, metabuf, BT_WRITE);
- return (_bt_getroot(rel, access));
+ _bt_pageinit(rootpg, BufferGetPageSize(rootbuf));
+ rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpg);
+ rootopaque->btpo_flags |= (BTP_LEAF | BTP_ROOT);
+ _bt_wrtnorelbuf(rel, rootbuf);
+
+ /* swap write lock for read lock, if appropriate */
+ if (access != BT_WRITE)
+ {
+ _bt_setpagelock(rel, rootblkno, BT_READ);
+ _bt_unsetpagelock(rel, rootblkno, BT_WRITE);
+ }
+
+ /* okay, metadata is correct */
+ _bt_wrtbuf(rel, metabuf);
+ }
+ else
+ {
+
+ /*
+ * Metadata initialized by someone else. In order to
+ * guarantee no deadlocks, we have to release the metadata
+ * page and start all over again.
+ */
+
+ _bt_relbuf(rel, metabuf, BT_WRITE);
+ return (_bt_getroot(rel, access));
+ }
}
- } else {
- rootbuf = _bt_getbuf(rel, metad->btm_root, access);
-
- /* done with the meta page */
- _bt_relbuf(rel, metabuf, BT_READ);
- }
-
- /*
- * Race condition: If the root page split between the time we looked
- * at the metadata page and got the root buffer, then we got the wrong
- * buffer.
- */
-
- rootpg = BufferGetPage(rootbuf);
- rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpg);
- if (!(rootopaque->btpo_flags & BTP_ROOT)) {
-
- /* it happened, try again */
- _bt_relbuf(rel, rootbuf, access);
- return (_bt_getroot(rel, access));
- }
-
- /*
- * By here, we have a correct lock on the root block, its reference
- * count is correct, and we have no lock set on the metadata page.
- * Return the root block.
- */
-
- return (rootbuf);
+ else
+ {
+ rootbuf = _bt_getbuf(rel, metad->btm_root, access);
+
+ /* done with the meta page */
+ _bt_relbuf(rel, metabuf, BT_READ);
+ }
+
+ /*
+ * Race condition: If the root page split between the time we looked
+ * at the metadata page and got the root buffer, then we got the wrong
+ * buffer.
+ */
+
+ rootpg = BufferGetPage(rootbuf);
+ rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpg);
+ if (!(rootopaque->btpo_flags & BTP_ROOT))
+ {
+
+ /* it happened, try again */
+ _bt_relbuf(rel, rootbuf, access);
+ return (_bt_getroot(rel, access));
+ }
+
+ /*
+ * By here, we have a correct lock on the root block, its reference
+ * count is correct, and we have no lock set on the metadata page.
+ * Return the root block.
+ */
+
+ return (rootbuf);
}
/*
- * _bt_getbuf() -- Get a buffer by block number for read or write.
+ * _bt_getbuf() -- Get a buffer by block number for read or write.
*
- * When this routine returns, the appropriate lock is set on the
- * requested buffer its reference count is correct.
+ * When this routine returns, the appropriate lock is set on the
+ * requested buffer its reference count is correct.
*/
Buffer
_bt_getbuf(Relation rel, BlockNumber blkno, int access)
{
- Buffer buf;
- Page page;
-
- /*
- * If we want a new block, we can't set a lock of the appropriate type
- * until we've instantiated the buffer.
- */
-
- if (blkno != P_NEW) {
- if (access == BT_WRITE)
- _bt_setpagelock(rel, blkno, BT_WRITE);
- else
- _bt_setpagelock(rel, blkno, BT_READ);
-
- buf = ReadBuffer(rel, blkno);
- } else {
- buf = ReadBuffer(rel, blkno);
- blkno = BufferGetBlockNumber(buf);
- page = BufferGetPage(buf);
- _bt_pageinit(page, BufferGetPageSize(buf));
-
- if (access == BT_WRITE)
- _bt_setpagelock(rel, blkno, BT_WRITE);
+ Buffer buf;
+ Page page;
+
+ /*
+ * If we want a new block, we can't set a lock of the appropriate type
+ * until we've instantiated the buffer.
+ */
+
+ if (blkno != P_NEW)
+ {
+ if (access == BT_WRITE)
+ _bt_setpagelock(rel, blkno, BT_WRITE);
+ else
+ _bt_setpagelock(rel, blkno, BT_READ);
+
+ buf = ReadBuffer(rel, blkno);
+ }
else
- _bt_setpagelock(rel, blkno, BT_READ);
- }
-
- /* ref count and lock type are correct */
- return (buf);
+ {
+ buf = ReadBuffer(rel, blkno);
+ blkno = BufferGetBlockNumber(buf);
+ page = BufferGetPage(buf);
+ _bt_pageinit(page, BufferGetPageSize(buf));
+
+ if (access == BT_WRITE)
+ _bt_setpagelock(rel, blkno, BT_WRITE);
+ else
+ _bt_setpagelock(rel, blkno, BT_READ);
+ }
+
+ /* ref count and lock type are correct */
+ return (buf);
}
/*
- * _bt_relbuf() -- release a locked buffer.
+ * _bt_relbuf() -- release a locked buffer.
*/
void
_bt_relbuf(Relation rel, Buffer buf, int access)
{
- BlockNumber blkno;
-
- blkno = BufferGetBlockNumber(buf);
-
- /* access had better be one of read or write */
- if (access == BT_WRITE)
- _bt_unsetpagelock(rel, blkno, BT_WRITE);
- else
- _bt_unsetpagelock(rel, blkno, BT_READ);
-
- ReleaseBuffer(buf);
+ BlockNumber blkno;
+
+ blkno = BufferGetBlockNumber(buf);
+
+ /* access had better be one of read or write */
+ if (access == BT_WRITE)
+ _bt_unsetpagelock(rel, blkno, BT_WRITE);
+ else
+ _bt_unsetpagelock(rel, blkno, BT_READ);
+
+ ReleaseBuffer(buf);
}
/*
- * _bt_wrtbuf() -- write a btree page to disk.
+ * _bt_wrtbuf() -- write a btree page to disk.
*
- * This routine releases the lock held on the buffer and our reference
- * to it. It is an error to call _bt_wrtbuf() without a write lock
- * or a reference to the buffer.
+ * This routine releases the lock held on the buffer and our reference
+ * to it. It is an error to call _bt_wrtbuf() without a write lock
+ * or a reference to the buffer.
*/
void
_bt_wrtbuf(Relation rel, Buffer buf)
{
- BlockNumber blkno;
-
- blkno = BufferGetBlockNumber(buf);
- WriteBuffer(buf);
- _bt_unsetpagelock(rel, blkno, BT_WRITE);
+ BlockNumber blkno;
+
+ blkno = BufferGetBlockNumber(buf);
+ WriteBuffer(buf);
+ _bt_unsetpagelock(rel, blkno, BT_WRITE);
}
/*
- * _bt_wrtnorelbuf() -- write a btree page to disk, but do not release
- * our reference or lock.
+ * _bt_wrtnorelbuf() -- write a btree page to disk, but do not release
+ * our reference or lock.
*
- * It is an error to call _bt_wrtnorelbuf() without a write lock
- * or a reference to the buffer.
+ * It is an error to call _bt_wrtnorelbuf() without a write lock
+ * or a reference to the buffer.
*/
void
_bt_wrtnorelbuf(Relation rel, Buffer buf)
{
- BlockNumber blkno;
-
- blkno = BufferGetBlockNumber(buf);
- WriteNoReleaseBuffer(buf);
+ BlockNumber blkno;
+
+ blkno = BufferGetBlockNumber(buf);
+ WriteNoReleaseBuffer(buf);
}
/*
- * _bt_pageinit() -- Initialize a new page.
+ * _bt_pageinit() -- Initialize a new page.
*/
void
_bt_pageinit(Page page, Size size)
{
- /*
- * Cargo-cult programming -- don't really need this to be zero, but
- * creating new pages is an infrequent occurrence and it makes me feel
- * good when I know they're empty.
- */
-
- memset(page, 0, size);
-
- PageInit(page, size, sizeof(BTPageOpaqueData));
+
+ /*
+ * Cargo-cult programming -- don't really need this to be zero, but
+ * creating new pages is an infrequent occurrence and it makes me feel
+ * good when I know they're empty.
+ */
+
+ memset(page, 0, size);
+
+ PageInit(page, size, sizeof(BTPageOpaqueData));
}
/*
- * _bt_metaproot() -- Change the root page of the btree.
+ * _bt_metaproot() -- Change the root page of the btree.
*
- * Lehman and Yao require that the root page move around in order to
- * guarantee deadlock-free short-term, fine-granularity locking. When
- * we split the root page, we record the new parent in the metadata page
- * for the relation. This routine does the work.
+ * Lehman and Yao require that the root page move around in order to
+ * guarantee deadlock-free short-term, fine-granularity locking. When
+ * we split the root page, we record the new parent in the metadata page
+ * for the relation. This routine does the work.
*
- * No direct preconditions, but if you don't have the a write lock on
- * at least the old root page when you call this, you're making a big
- * mistake. On exit, metapage data is correct and we no longer have
- * a reference to or lock on the metapage.
+ * No direct preconditions, but if you don't have the a write lock on
+ * at least the old root page when you call this, you're making a big
+ * mistake. On exit, metapage data is correct and we no longer have
+ * a reference to or lock on the metapage.
*/
void
_bt_metaproot(Relation rel, BlockNumber rootbknum, int level)
{
- Buffer metabuf;
- Page metap;
- BTPageOpaque metaopaque;
- BTMetaPageData *metad;
-
- metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE);
- metap = BufferGetPage(metabuf);
- metaopaque = (BTPageOpaque) PageGetSpecialPointer(metap);
- Assert(metaopaque->btpo_flags & BTP_META);
- metad = BTPageGetMeta(metap);
- metad->btm_root = rootbknum;
+ Buffer metabuf;
+ Page metap;
+ BTPageOpaque metaopaque;
+ BTMetaPageData *metad;
+
+ metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE);
+ metap = BufferGetPage(metabuf);
+ metaopaque = (BTPageOpaque) PageGetSpecialPointer(metap);
+ Assert(metaopaque->btpo_flags & BTP_META);
+ metad = BTPageGetMeta(metap);
+ metad->btm_root = rootbknum;
#ifdef BTREE_VERSION_1
- if ( level == 0 ) /* called from _do_insert */
- metad->btm_level += 1;
- else
- metad->btm_level = level; /* called from btsort */
+ if (level == 0) /* called from _do_insert */
+ metad->btm_level += 1;
+ else
+ metad->btm_level = level; /* called from btsort */
#endif
- _bt_wrtbuf(rel, metabuf);
+ _bt_wrtbuf(rel, metabuf);
}
/*
- * _bt_getstackbuf() -- Walk back up the tree one step, and find the item
- * we last looked at in the parent.
+ * _bt_getstackbuf() -- Walk back up the tree one step, and find the item
+ * we last looked at in the parent.
*
- * This is possible because we save a bit image of the last item
- * we looked at in the parent, and the update algorithm guarantees
- * that if items above us in the tree move, they only move right.
+ * This is possible because we save a bit image of the last item
+ * we looked at in the parent, and the update algorithm guarantees
+ * that if items above us in the tree move, they only move right.
*
- * Also, re-set bts_blkno & bts_offset if changed and
- * bts_btitem (it may be changed - see _bt_insertonpg).
+ * Also, re-set bts_blkno & bts_offset if changed and
+ * bts_btitem (it may be changed - see _bt_insertonpg).
*/
Buffer
_bt_getstackbuf(Relation rel, BTStack stack, int access)
{
- Buffer buf;
- BlockNumber blkno;
- OffsetNumber start, offnum, maxoff;
- OffsetNumber i;
- Page page;
- ItemId itemid;
- BTItem item;
- BTPageOpaque opaque;
- BTItem item_save;
- int item_nbytes;
-
- blkno = stack->bts_blkno;
- buf = _bt_getbuf(rel, blkno, access);
- page = BufferGetPage(buf);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- maxoff = PageGetMaxOffsetNumber(page);
-
- if (maxoff >= stack->bts_offset) {
- itemid = PageGetItemId(page, stack->bts_offset);
- item = (BTItem) PageGetItem(page, itemid);
-
- /* if the item is where we left it, we're done */
- if ( BTItemSame (item, stack->bts_btitem) )
- {
- pfree(stack->bts_btitem);
- item_nbytes = ItemIdGetLength(itemid);
- item_save = (BTItem) palloc(item_nbytes);
- memmove((char *) item_save, (char *) item, item_nbytes);
- stack->bts_btitem = item_save;
- return (buf);
- }
-
- /* if the item has just moved right on this page, we're done */
- for (i = OffsetNumberNext(stack->bts_offset);
- i <= maxoff;
- i = OffsetNumberNext(i)) {
- itemid = PageGetItemId(page, i);
- item = (BTItem) PageGetItem(page, itemid);
-
- /* if the item is where we left it, we're done */
- if ( BTItemSame (item, stack->bts_btitem) )
- {
- stack->bts_offset = i;
- pfree(stack->bts_btitem);
- item_nbytes = ItemIdGetLength(itemid);
- item_save = (BTItem) palloc(item_nbytes);
- memmove((char *) item_save, (char *) item, item_nbytes);
- stack->bts_btitem = item_save;
- return (buf);
- }
- }
- }
-
- /* by here, the item we're looking for moved right at least one page */
- for (;;) {
- blkno = opaque->btpo_next;
- if (P_RIGHTMOST(opaque))
- elog(FATAL, "my bits moved right off the end of the world!");
-
- _bt_relbuf(rel, buf, access);
+ Buffer buf;
+ BlockNumber blkno;
+ OffsetNumber start,
+ offnum,
+ maxoff;
+ OffsetNumber i;
+ Page page;
+ ItemId itemid;
+ BTItem item;
+ BTPageOpaque opaque;
+ BTItem item_save;
+ int item_nbytes;
+
+ blkno = stack->bts_blkno;
buf = _bt_getbuf(rel, blkno, access);
page = BufferGetPage(buf);
- maxoff = PageGetMaxOffsetNumber(page);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
-
- /* if we have a right sibling, step over the high key */
- start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
-
- /* see if it's on this page */
- for (offnum = start;
- offnum <= maxoff;
- offnum = OffsetNumberNext(offnum)) {
- itemid = PageGetItemId(page, offnum);
- item = (BTItem) PageGetItem(page, itemid);
- if ( BTItemSame (item, stack->bts_btitem) )
- {
- stack->bts_offset = offnum;
- stack->bts_blkno = blkno;
- pfree(stack->bts_btitem);
- item_nbytes = ItemIdGetLength(itemid);
- item_save = (BTItem) palloc(item_nbytes);
- memmove((char *) item_save, (char *) item, item_nbytes);
- stack->bts_btitem = item_save;
- return (buf);
- }
+ maxoff = PageGetMaxOffsetNumber(page);
+
+ if (maxoff >= stack->bts_offset)
+ {
+ itemid = PageGetItemId(page, stack->bts_offset);
+ item = (BTItem) PageGetItem(page, itemid);
+
+ /* if the item is where we left it, we're done */
+ if (BTItemSame(item, stack->bts_btitem))
+ {
+ pfree(stack->bts_btitem);
+ item_nbytes = ItemIdGetLength(itemid);
+ item_save = (BTItem) palloc(item_nbytes);
+ memmove((char *) item_save, (char *) item, item_nbytes);
+ stack->bts_btitem = item_save;
+ return (buf);
+ }
+
+ /* if the item has just moved right on this page, we're done */
+ for (i = OffsetNumberNext(stack->bts_offset);
+ i <= maxoff;
+ i = OffsetNumberNext(i))
+ {
+ itemid = PageGetItemId(page, i);
+ item = (BTItem) PageGetItem(page, itemid);
+
+ /* if the item is where we left it, we're done */
+ if (BTItemSame(item, stack->bts_btitem))
+ {
+ stack->bts_offset = i;
+ pfree(stack->bts_btitem);
+ item_nbytes = ItemIdGetLength(itemid);
+ item_save = (BTItem) palloc(item_nbytes);
+ memmove((char *) item_save, (char *) item, item_nbytes);
+ stack->bts_btitem = item_save;
+ return (buf);
+ }
+ }
+ }
+
+ /* by here, the item we're looking for moved right at least one page */
+ for (;;)
+ {
+ blkno = opaque->btpo_next;
+ if (P_RIGHTMOST(opaque))
+ elog(FATAL, "my bits moved right off the end of the world!");
+
+ _bt_relbuf(rel, buf, access);
+ buf = _bt_getbuf(rel, blkno, access);
+ page = BufferGetPage(buf);
+ maxoff = PageGetMaxOffsetNumber(page);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+
+ /* if we have a right sibling, step over the high key */
+ start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+
+ /* see if it's on this page */
+ for (offnum = start;
+ offnum <= maxoff;
+ offnum = OffsetNumberNext(offnum))
+ {
+ itemid = PageGetItemId(page, offnum);
+ item = (BTItem) PageGetItem(page, itemid);
+ if (BTItemSame(item, stack->bts_btitem))
+ {
+ stack->bts_offset = offnum;
+ stack->bts_blkno = blkno;
+ pfree(stack->bts_btitem);
+ item_nbytes = ItemIdGetLength(itemid);
+ item_save = (BTItem) palloc(item_nbytes);
+ memmove((char *) item_save, (char *) item, item_nbytes);
+ stack->bts_btitem = item_save;
+ return (buf);
+ }
+ }
}
- }
}
static void
_bt_setpagelock(Relation rel, BlockNumber blkno, int access)
{
- ItemPointerData iptr;
-
- if (USELOCKING) {
- ItemPointerSet(&iptr, blkno, P_HIKEY);
-
- if (access == BT_WRITE)
- RelationSetSingleWLockPage(rel, &iptr);
- else
- RelationSetSingleRLockPage(rel, &iptr);
- }
+ ItemPointerData iptr;
+
+ if (USELOCKING)
+ {
+ ItemPointerSet(&iptr, blkno, P_HIKEY);
+
+ if (access == BT_WRITE)
+ RelationSetSingleWLockPage(rel, &iptr);
+ else
+ RelationSetSingleRLockPage(rel, &iptr);
+ }
}
static void
_bt_unsetpagelock(Relation rel, BlockNumber blkno, int access)
{
- ItemPointerData iptr;
-
- if (USELOCKING) {
- ItemPointerSet(&iptr, blkno, P_HIKEY);
-
- if (access == BT_WRITE)
- RelationUnsetSingleWLockPage(rel, &iptr);
- else
- RelationUnsetSingleRLockPage(rel, &iptr);
- }
+ ItemPointerData iptr;
+
+ if (USELOCKING)
+ {
+ ItemPointerSet(&iptr, blkno, P_HIKEY);
+
+ if (access == BT_WRITE)
+ RelationUnsetSingleWLockPage(rel, &iptr);
+ else
+ RelationUnsetSingleRLockPage(rel, &iptr);
+ }
}
void
_bt_pagedel(Relation rel, ItemPointer tid)
{
- Buffer buf;
- Page page;
- BlockNumber blkno;
- OffsetNumber offno;
-
- blkno = ItemPointerGetBlockNumber(tid);
- offno = ItemPointerGetOffsetNumber(tid);
-
- buf = _bt_getbuf(rel, blkno, BT_WRITE);
- page = BufferGetPage(buf);
-
- PageIndexTupleDelete(page, offno);
-
- /* write the buffer and release the lock */
- _bt_wrtbuf(rel, buf);
+ Buffer buf;
+ Page page;
+ BlockNumber blkno;
+ OffsetNumber offno;
+
+ blkno = ItemPointerGetBlockNumber(tid);
+ offno = ItemPointerGetOffsetNumber(tid);
+
+ buf = _bt_getbuf(rel, blkno, BT_WRITE);
+ page = BufferGetPage(buf);
+
+ PageIndexTupleDelete(page, offno);
+
+ /* write the buffer and release the lock */
+ _bt_wrtbuf(rel, buf);
}
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index b672901f8db..dccbd77b355 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* btree.c--
- * Implementation of Lehman and Yao's btree management algorithm for
- * Postgres.
+ * Implementation of Lehman and Yao's btree management algorithm for
+ * Postgres.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.19 1997/05/05 03:41:17 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.20 1997/09/07 04:38:54 momjian Exp $
*
* NOTES
- * This file contains only the public interface routines.
+ * This file contains only the public interface routines.
*
*-------------------------------------------------------------------------
*/
@@ -28,546 +28,579 @@
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
#ifdef BTREE_BUILD_STATS
#include <tcop/tcopprot.h>
-extern int ShowExecutorStats;
+extern int ShowExecutorStats;
+
#endif
-bool BuildingBtree = false; /* see comment in btbuild() */
-bool FastBuild = true; /* use sort/build instead of insertion build */
+bool BuildingBtree = false; /* see comment in btbuild() */
+bool FastBuild = true; /* use sort/build instead of
+ * insertion build */
/*
- * btbuild() -- build a new btree index.
+ * btbuild() -- build a new btree index.
*
- * We use a global variable to record the fact that we're creating
- * a new index. This is used to avoid high-concurrency locking,
- * since the index won't be visible until this transaction commits
- * and since building is guaranteed to be single-threaded.
+ * We use a global variable to record the fact that we're creating
+ * a new index. This is used to avoid high-concurrency locking,
+ * since the index won't be visible until this transaction commits
+ * and since building is guaranteed to be single-threaded.
*/
void
btbuild(Relation heap,
- Relation index,
- int natts,
- AttrNumber *attnum,
- IndexStrategy istrat,
- uint16 pcount,
- Datum *params,
- FuncIndexInfo *finfo,
- PredInfo *predInfo)
+ Relation index,
+ int natts,
+ AttrNumber * attnum,
+ IndexStrategy istrat,
+ uint16 pcount,
+ Datum * params,
+ FuncIndexInfo * finfo,
+ PredInfo * predInfo)
{
- HeapScanDesc hscan;
- Buffer buffer;
- HeapTuple htup;
- IndexTuple itup;
- TupleDesc htupdesc, itupdesc;
- Datum *attdata;
- bool *nulls;
- InsertIndexResult res = 0;
- int nhtups, nitups;
- int i;
- BTItem btitem;
+ HeapScanDesc hscan;
+ Buffer buffer;
+ HeapTuple htup;
+ IndexTuple itup;
+ TupleDesc htupdesc,
+ itupdesc;
+ Datum *attdata;
+ bool *nulls;
+ InsertIndexResult res = 0;
+ int nhtups,
+ nitups;
+ int i;
+ BTItem btitem;
+
#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext = (ExprContext *) NULL;
- TupleTable tupleTable = (TupleTable) NULL;
- TupleTableSlot *slot = (TupleTableSlot *) NULL;
-#endif
- Oid hrelid, irelid;
- Node *pred, *oldPred;
- void *spool = (void *) NULL;
- bool isunique;
- bool usefast;
-
- /* note that this is a new btree */
- BuildingBtree = true;
-
- pred = predInfo->pred;
- oldPred = predInfo->oldPred;
-
- /*
- * bootstrap processing does something strange, so don't use
- * sort/build for initial catalog indices. at some point i need
- * to look harder at this. (there is some kind of incremental
- * processing going on there.) -- pma 08/29/95
- */
- usefast = (FastBuild && IsNormalProcessingMode());
+ ExprContext *econtext = (ExprContext *) NULL;
+ TupleTable tupleTable = (TupleTable) NULL;
+ TupleTableSlot *slot = (TupleTableSlot *) NULL;
-#ifdef BTREE_BUILD_STATS
- if ( ShowExecutorStats )
- ResetUsage ();
#endif
+ Oid hrelid,
+ irelid;
+ Node *pred,
+ *oldPred;
+ void *spool = (void *) NULL;
+ bool isunique;
+ bool usefast;
- /* see if index is unique */
- isunique = IndexIsUniqueNoCache(RelationGetRelationId(index));
-
- /* initialize the btree index metadata page (if this is a new index) */
- if (oldPred == NULL)
- _bt_metapinit(index);
-
- /* get tuple descriptors for heap and index relations */
- htupdesc = RelationGetTupleDescriptor(heap);
- itupdesc = RelationGetTupleDescriptor(index);
-
- /* get space for data items that'll appear in the index tuple */
- attdata = (Datum *) palloc(natts * sizeof(Datum));
- nulls = (bool *) palloc(natts * sizeof(bool));
-
- /*
- * If this is a predicate (partial) index, we will need to evaluate the
- * predicate using ExecQual, which requires the current tuple to be in a
- * slot of a TupleTable. In addition, ExecQual must have an ExprContext
- * referring to that slot. Here, we initialize dummy TupleTable and
- * ExprContext objects for this purpose. --Nels, Feb '92
- */
-#ifndef OMIT_PARTIAL_INDEX
- if (pred != NULL || oldPred != NULL) {
- tupleTable = ExecCreateTupleTable(1);
- slot = ExecAllocTableSlot(tupleTable);
- econtext = makeNode(ExprContext);
- FillDummyExprContext(econtext, slot, htupdesc, InvalidBuffer);
+ /* note that this is a new btree */
+ BuildingBtree = true;
+
+ pred = predInfo->pred;
+ oldPred = predInfo->oldPred;
/*
- * we never want to use sort/build if we are extending an
- * existing partial index -- it works by inserting the
- * newly-qualifying tuples into the existing index.
- * (sort/build would overwrite the existing index with one
- * consisting of the newly-qualifying tuples.)
+ * bootstrap processing does something strange, so don't use
+ * sort/build for initial catalog indices. at some point i need to
+ * look harder at this. (there is some kind of incremental processing
+ * going on there.) -- pma 08/29/95
*/
- usefast = false;
- }
-#endif /* OMIT_PARTIAL_INDEX */
-
- /* start a heap scan */
- hscan = heap_beginscan(heap, 0, NowTimeQual, 0, (ScanKey) NULL);
- htup = heap_getnext(hscan, 0, &buffer);
-
- /* build the index */
- nhtups = nitups = 0;
-
- if (usefast) {
- spool = _bt_spoolinit(index, 7, isunique);
- res = (InsertIndexResult) NULL;
- }
-
- for (; HeapTupleIsValid(htup); htup = heap_getnext(hscan, 0, &buffer)) {
-
- nhtups++;
-
+ usefast = (FastBuild && IsNormalProcessingMode());
+
+#ifdef BTREE_BUILD_STATS
+ if (ShowExecutorStats)
+ ResetUsage();
+#endif
+
+ /* see if index is unique */
+ isunique = IndexIsUniqueNoCache(RelationGetRelationId(index));
+
+ /* initialize the btree index metadata page (if this is a new index) */
+ if (oldPred == NULL)
+ _bt_metapinit(index);
+
+ /* get tuple descriptors for heap and index relations */
+ htupdesc = RelationGetTupleDescriptor(heap);
+ itupdesc = RelationGetTupleDescriptor(index);
+
+ /* get space for data items that'll appear in the index tuple */
+ attdata = (Datum *) palloc(natts * sizeof(Datum));
+ nulls = (bool *) palloc(natts * sizeof(bool));
+
/*
- * If oldPred != NULL, this is an EXTEND INDEX command, so skip
- * this tuple if it was already in the existing partial index
+ * If this is a predicate (partial) index, we will need to evaluate
+ * the predicate using ExecQual, which requires the current tuple to
+ * be in a slot of a TupleTable. In addition, ExecQual must have an
+ * ExprContext referring to that slot. Here, we initialize dummy
+ * TupleTable and ExprContext objects for this purpose. --Nels, Feb
+ * '92
*/
- if (oldPred != NULL) {
+#ifndef OMIT_PARTIAL_INDEX
+ if (pred != NULL || oldPred != NULL)
+ {
+ tupleTable = ExecCreateTupleTable(1);
+ slot = ExecAllocTableSlot(tupleTable);
+ econtext = makeNode(ExprContext);
+ FillDummyExprContext(econtext, slot, htupdesc, InvalidBuffer);
+
+ /*
+ * we never want to use sort/build if we are extending an existing
+ * partial index -- it works by inserting the newly-qualifying
+ * tuples into the existing index. (sort/build would overwrite the
+ * existing index with one consisting of the newly-qualifying
+ * tuples.)
+ */
+ usefast = false;
+ }
+#endif /* OMIT_PARTIAL_INDEX */
+
+ /* start a heap scan */
+ hscan = heap_beginscan(heap, 0, NowTimeQual, 0, (ScanKey) NULL);
+ htup = heap_getnext(hscan, 0, &buffer);
+
+ /* build the index */
+ nhtups = nitups = 0;
+
+ if (usefast)
+ {
+ spool = _bt_spoolinit(index, 7, isunique);
+ res = (InsertIndexResult) NULL;
+ }
+
+ for (; HeapTupleIsValid(htup); htup = heap_getnext(hscan, 0, &buffer))
+ {
+
+ nhtups++;
+
+ /*
+ * If oldPred != NULL, this is an EXTEND INDEX command, so skip
+ * this tuple if it was already in the existing partial index
+ */
+ if (oldPred != NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- /*SetSlotContents(slot, htup);*/
- slot->val = htup;
- if (ExecQual((List*)oldPred, econtext) == true) {
+ /* SetSlotContents(slot, htup); */
+ slot->val = htup;
+ if (ExecQual((List *) oldPred, econtext) == true)
+ {
+ nitups++;
+ continue;
+ }
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+
+ /*
+ * Skip this tuple if it doesn't satisfy the partial-index
+ * predicate
+ */
+ if (pred != NULL)
+ {
+#ifndef OMIT_PARTIAL_INDEX
+ /* SetSlotContents(slot, htup); */
+ slot->val = htup;
+ if (ExecQual((List *) pred, econtext) == false)
+ continue;
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+
nitups++;
- continue;
- }
-#endif /* OMIT_PARTIAL_INDEX */
+
+ /*
+ * For the current heap tuple, extract all the attributes we use
+ * in this index, and note which are null.
+ */
+
+ for (i = 1; i <= natts; i++)
+ {
+ int attoff;
+ bool attnull;
+
+ /*
+ * Offsets are from the start of the tuple, and are
+ * zero-based; indices are one-based. The next call returns i
+ * - 1. That's data hiding for you.
+ */
+
+ attoff = AttrNumberGetAttrOffset(i);
+ attdata[attoff] = GetIndexValue(htup,
+ htupdesc,
+ attoff,
+ attnum,
+ finfo,
+ &attnull,
+ buffer);
+ nulls[attoff] = (attnull ? 'n' : ' ');
+ }
+
+ /* form an index tuple and point it at the heap tuple */
+ itup = index_formtuple(itupdesc, attdata, nulls);
+
+ /*
+ * If the single index key is null, we don't insert it into the
+ * index. Btrees support scans on <, <=, =, >=, and >. Relational
+ * algebra says that A op B (where op is one of the operators
+ * above) returns null if either A or B is null. This means that
+ * no qualification used in an index scan could ever return true
+ * on a null attribute. It also means that indices can't be used
+ * by ISNULL or NOTNULL scans, but that's an artifact of the
+ * strategy map architecture chosen in 1986, not of the way nulls
+ * are handled here.
+ */
+
+ /*
+ * New comments: NULLs handling. While we can't do NULL
+ * comparison, we can follow simple rule for ordering items on
+ * btree pages - NULLs greater NOT_NULLs and NULL = NULL is TRUE.
+ * Sure, it's just rule for placing/finding items and no more -
+ * keytest'll return FALSE for a = 5 for items having 'a' isNULL.
+ * Look at _bt_skeycmp, _bt_compare and _bt_itemcmp for how it
+ * works. - vadim 03/23/97
+ *
+ * if (itup->t_info & INDEX_NULL_MASK) { pfree(itup); continue; }
+ */
+
+ itup->t_tid = htup->t_ctid;
+ btitem = _bt_formitem(itup);
+
+ /*
+ * if we are doing bottom-up btree build, we insert the index into
+ * a spool page for subsequent processing. otherwise, we insert
+ * into the btree.
+ */
+ if (usefast)
+ {
+ _bt_spool(index, btitem, spool);
+ }
+ else
+ {
+ res = _bt_doinsert(index, btitem, isunique, heap);
+ }
+
+ pfree(btitem);
+ pfree(itup);
+ if (res)
+ {
+ pfree(res);
+ }
}
-
- /* Skip this tuple if it doesn't satisfy the partial-index predicate */
- if (pred != NULL) {
+
+ /* okay, all heap tuples are indexed */
+ heap_endscan(hscan);
+
+ if (pred != NULL || oldPred != NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- /* SetSlotContents(slot, htup); */
- slot->val = htup;
- if (ExecQual((List*)pred, econtext) == false)
- continue;
-#endif /* OMIT_PARTIAL_INDEX */
+ ExecDestroyTupleTable(tupleTable, true);
+ pfree(econtext);
+#endif /* OMIT_PARTIAL_INDEX */
}
-
- nitups++;
-
+
/*
- * For the current heap tuple, extract all the attributes
- * we use in this index, and note which are null.
+ * if we are doing bottom-up btree build, we now have a bunch of
+ * sorted runs in the spool pages. finish the build by (1) merging
+ * the runs, (2) inserting the sorted tuples into btree pages and (3)
+ * building the upper levels.
*/
-
- for (i = 1; i <= natts; i++) {
- int attoff;
- bool attnull;
-
- /*
- * Offsets are from the start of the tuple, and are
- * zero-based; indices are one-based. The next call
- * returns i - 1. That's data hiding for you.
- */
-
- attoff = AttrNumberGetAttrOffset(i);
- attdata[attoff] = GetIndexValue(htup,
- htupdesc,
- attoff,
- attnum,
- finfo,
- &attnull,
- buffer);
- nulls[attoff] = (attnull ? 'n' : ' ');
+ if (usefast)
+ {
+ _bt_spool(index, (BTItem) NULL, spool); /* flush the spool */
+ _bt_leafbuild(index, spool);
+ _bt_spooldestroy(spool);
}
-
- /* form an index tuple and point it at the heap tuple */
- itup = index_formtuple(itupdesc, attdata, nulls);
-
- /*
- * If the single index key is null, we don't insert it into
- * the index. Btrees support scans on <, <=, =, >=, and >.
- * Relational algebra says that A op B (where op is one of the
- * operators above) returns null if either A or B is null. This
- * means that no qualification used in an index scan could ever
- * return true on a null attribute. It also means that indices
- * can't be used by ISNULL or NOTNULL scans, but that's an
- * artifact of the strategy map architecture chosen in 1986, not
- * of the way nulls are handled here.
- */
- /*
- * New comments: NULLs handling.
- * While we can't do NULL comparison, we can follow simple
- * rule for ordering items on btree pages - NULLs greater
- * NOT_NULLs and NULL = NULL is TRUE. Sure, it's just rule
- * for placing/finding items and no more - keytest'll return
- * FALSE for a = 5 for items having 'a' isNULL.
- * Look at _bt_skeycmp, _bt_compare and _bt_itemcmp for
- * how it works. - vadim 03/23/97
-
- if (itup->t_info & INDEX_NULL_MASK) {
- pfree(itup);
- continue;
+
+#ifdef BTREE_BUILD_STATS
+ if (ShowExecutorStats)
+ {
+ fprintf(stderr, "! BtreeBuild Stats:\n");
+ ShowUsage();
+ ResetUsage();
}
- */
-
- itup->t_tid = htup->t_ctid;
- btitem = _bt_formitem(itup);
+#endif
/*
- * if we are doing bottom-up btree build, we insert the index
- * into a spool page for subsequent processing. otherwise, we
- * insert into the btree.
+ * 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. Finally, only update statistics during
+ * normal index definitions, not for indices on system catalogs
+ * created during bootstrap processing. We must close the relations
+ * before updatings statistics to guarantee that the relcache entries
+ * are flushed when we increment the command counter in UpdateStats().
*/
- if (usefast) {
- _bt_spool(index, btitem, spool);
- } else {
- res = _bt_doinsert(index, btitem, isunique, heap);
+ if (IsNormalProcessingMode())
+ {
+ hrelid = heap->rd_id;
+ irelid = index->rd_id;
+ heap_close(heap);
+ index_close(index);
+ UpdateStats(hrelid, nhtups, true);
+ UpdateStats(irelid, nitups, false);
+ if (oldPred != NULL)
+ {
+ if (nitups == nhtups)
+ pred = NULL;
+ UpdateIndexPredicate(irelid, oldPred, pred);
+ }
}
- pfree(btitem);
- pfree(itup);
- if (res) {
- pfree(res);
- }
- }
-
- /* okay, all heap tuples are indexed */
- heap_endscan(hscan);
-
- if (pred != NULL || oldPred != NULL) {
-#ifndef OMIT_PARTIAL_INDEX
- ExecDestroyTupleTable(tupleTable, true);
- pfree(econtext);
-#endif /* OMIT_PARTIAL_INDEX */
- }
-
- /*
- * if we are doing bottom-up btree build, we now have a bunch of
- * sorted runs in the spool pages. finish the build by (1)
- * merging the runs, (2) inserting the sorted tuples into btree
- * pages and (3) building the upper levels.
- */
- if (usefast) {
- _bt_spool(index, (BTItem) NULL, spool); /* flush the spool */
- _bt_leafbuild(index, spool);
- _bt_spooldestroy(spool);
- }
+ pfree(nulls);
+ pfree(attdata);
-#ifdef BTREE_BUILD_STATS
- if ( ShowExecutorStats )
- {
- fprintf(stderr, "! BtreeBuild Stats:\n");
- ShowUsage ();
- ResetUsage ();
- }
-#endif
-
- /*
- * 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. Finally, only update statistics
- * during normal index definitions, not for indices on system catalogs
- * created during bootstrap processing. We must close the relations
- * before updatings statistics to guarantee that the relcache entries
- * are flushed when we increment the command counter in UpdateStats().
- */
- if (IsNormalProcessingMode())
- {
- hrelid = heap->rd_id;
- irelid = index->rd_id;
- heap_close(heap);
- index_close(index);
- UpdateStats(hrelid, nhtups, true);
- UpdateStats(irelid, nitups, false);
- if (oldPred != NULL) {
- if (nitups == nhtups) pred = NULL;
- UpdateIndexPredicate(irelid, oldPred, pred);
- }
- }
-
- pfree(nulls);
- pfree(attdata);
-
- /* all done */
- BuildingBtree = false;
+ /* all done */
+ BuildingBtree = false;
}
/*
- * btinsert() -- insert an index tuple into a btree.
+ * btinsert() -- insert an index tuple into a btree.
*
- * Descend the tree recursively, find the appropriate location for our
- * new tuple, put it there, set its unique OID as appropriate, and
- * return an InsertIndexResult to the caller.
+ * Descend the tree recursively, find the appropriate location for our
+ * new tuple, put it there, set its unique OID as appropriate, and
+ * return an InsertIndexResult to the caller.
*/
InsertIndexResult
-btinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
+btinsert(Relation rel, Datum * datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
{
- BTItem btitem;
- IndexTuple itup;
- InsertIndexResult res;
-
- /* generate an index tuple */
- itup = index_formtuple(RelationGetTupleDescriptor(rel), datum, nulls);
- itup->t_tid = *ht_ctid;
-
- /*
- * See comments in btbuild.
-
- if (itup->t_info & INDEX_NULL_MASK)
- return ((InsertIndexResult) NULL);
- */
-
- btitem = _bt_formitem(itup);
-
- res = _bt_doinsert(rel, btitem,
- IndexIsUnique(RelationGetRelationId(rel)), heapRel);
-
- pfree(btitem);
- pfree(itup);
-
- /* adjust any active scans that will be affected by this insertion */
- _bt_adjscans(rel, &(res->pointerData), BT_INSERT);
-
- return (res);
+ BTItem btitem;
+ IndexTuple itup;
+ InsertIndexResult res;
+
+ /* generate an index tuple */
+ itup = index_formtuple(RelationGetTupleDescriptor(rel), datum, nulls);
+ itup->t_tid = *ht_ctid;
+
+ /*
+ * See comments in btbuild.
+ *
+ * if (itup->t_info & INDEX_NULL_MASK) return ((InsertIndexResult) NULL);
+ */
+
+ btitem = _bt_formitem(itup);
+
+ res = _bt_doinsert(rel, btitem,
+ IndexIsUnique(RelationGetRelationId(rel)), heapRel);
+
+ pfree(btitem);
+ pfree(itup);
+
+ /* adjust any active scans that will be affected by this insertion */
+ _bt_adjscans(rel, &(res->pointerData), BT_INSERT);
+
+ return (res);
}
/*
- * btgettuple() -- Get the next tuple in the scan.
+ * btgettuple() -- Get the next tuple in the scan.
*/
-char *
+char *
btgettuple(IndexScanDesc scan, ScanDirection dir)
{
- RetrieveIndexResult res;
-
- /*
- * If we've already initialized this scan, we can just advance it
- * in the appropriate direction. If we haven't done so yet, we
- * call a routine to get the first item in the scan.
- */
-
- if (ItemPointerIsValid(&(scan->currentItemData)))
- res = _bt_next(scan, dir);
- else
- res = _bt_first(scan, dir);
-
- return ((char *) res);
+ RetrieveIndexResult res;
+
+ /*
+ * If we've already initialized this scan, we can just advance it in
+ * the appropriate direction. If we haven't done so yet, we call a
+ * routine to get the first item in the scan.
+ */
+
+ if (ItemPointerIsValid(&(scan->currentItemData)))
+ res = _bt_next(scan, dir);
+ else
+ res = _bt_first(scan, dir);
+
+ return ((char *) res);
}
/*
- * btbeginscan() -- start a scan on a btree index
+ * btbeginscan() -- start a scan on a btree index
*/
-char *
+char *
btbeginscan(Relation rel, bool fromEnd, uint16 keysz, ScanKey scankey)
{
- IndexScanDesc scan;
-
- /* get the scan */
- scan = RelationGetIndexScan(rel, fromEnd, keysz, scankey);
-
- /* register scan in case we change pages it's using */
- _bt_regscan(scan);
-
- return ((char *) scan);
+ IndexScanDesc scan;
+
+ /* get the scan */
+ scan = RelationGetIndexScan(rel, fromEnd, keysz, scankey);
+
+ /* register scan in case we change pages it's using */
+ _bt_regscan(scan);
+
+ return ((char *) scan);
}
/*
- * btrescan() -- rescan an index relation
+ * btrescan() -- rescan an index relation
*/
void
btrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey)
{
- ItemPointer iptr;
- BTScanOpaque so;
-
- so = (BTScanOpaque) scan->opaque;
-
- /* we hold a read lock on the current page in the scan */
- if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
- _bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
- so->btso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- /* and we hold a read lock on the last marked item in the scan */
- if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
- _bt_relbuf(scan->relation, so->btso_mrkbuf, BT_READ);
- so->btso_mrkbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- if ( so == NULL ) /* if called from btbeginscan */
- {
- so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData));
- so->btso_curbuf = so->btso_mrkbuf = InvalidBuffer;
- so->keyData = (ScanKey) NULL;
- if ( scan->numberOfKeys > 0)
- so->keyData = (ScanKey) palloc (scan->numberOfKeys * sizeof(ScanKeyData));
- scan->opaque = so;
- scan->flags = 0x0;
- }
-
- /*
- * Reset the scan keys. Note that keys ordering stuff
- * moved to _bt_first. - vadim 05/05/97
- */
- so->numberOfKeys = scan->numberOfKeys;
- if (scan->numberOfKeys > 0) {
- memmove(scan->keyData,
- scankey,
- scan->numberOfKeys * sizeof(ScanKeyData));
- memmove(so->keyData,
- scankey,
- so->numberOfKeys * sizeof(ScanKeyData));
- }
+ ItemPointer iptr;
+ BTScanOpaque so;
+
+ so = (BTScanOpaque) scan->opaque;
+
+ /* we hold a read lock on the current page in the scan */
+ if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
+ {
+ _bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
+ so->btso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ /* and we hold a read lock on the last marked item in the scan */
+ if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
+ {
+ _bt_relbuf(scan->relation, so->btso_mrkbuf, BT_READ);
+ so->btso_mrkbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ if (so == NULL) /* if called from btbeginscan */
+ {
+ so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData));
+ so->btso_curbuf = so->btso_mrkbuf = InvalidBuffer;
+ so->keyData = (ScanKey) NULL;
+ if (scan->numberOfKeys > 0)
+ so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData));
+ scan->opaque = so;
+ scan->flags = 0x0;
+ }
+
+ /*
+ * Reset the scan keys. Note that keys ordering stuff moved to
+ * _bt_first. - vadim 05/05/97
+ */
+ so->numberOfKeys = scan->numberOfKeys;
+ if (scan->numberOfKeys > 0)
+ {
+ memmove(scan->keyData,
+ scankey,
+ scan->numberOfKeys * sizeof(ScanKeyData));
+ memmove(so->keyData,
+ scankey,
+ so->numberOfKeys * sizeof(ScanKeyData));
+ }
}
void
btmovescan(IndexScanDesc scan, Datum v)
{
- ItemPointer iptr;
- BTScanOpaque so;
-
- so = (BTScanOpaque) scan->opaque;
-
- /* release any locks we still hold */
- if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
- _bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
- so->btso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
-/* scan->keyData[0].sk_argument = v; */
- so->keyData[0].sk_argument = v;
+ ItemPointer iptr;
+ BTScanOpaque so;
+
+ so = (BTScanOpaque) scan->opaque;
+
+ /* release any locks we still hold */
+ if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
+ {
+ _bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
+ so->btso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+/* scan->keyData[0].sk_argument = v; */
+ so->keyData[0].sk_argument = v;
}
/*
- * btendscan() -- close down a scan
+ * btendscan() -- close down a scan
*/
void
btendscan(IndexScanDesc scan)
{
- ItemPointer iptr;
- BTScanOpaque so;
-
- so = (BTScanOpaque) scan->opaque;
-
- /* release any locks we still hold */
- if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
- if (BufferIsValid(so->btso_curbuf))
- _bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
- so->btso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
- if (BufferIsValid(so->btso_mrkbuf))
- _bt_relbuf(scan->relation, so->btso_mrkbuf, BT_READ);
- so->btso_mrkbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- if ( so->keyData != (ScanKey) NULL )
- pfree (so->keyData);
- pfree (so);
-
- _bt_dropscan(scan);
+ ItemPointer iptr;
+ BTScanOpaque so;
+
+ so = (BTScanOpaque) scan->opaque;
+
+ /* release any locks we still hold */
+ if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
+ {
+ if (BufferIsValid(so->btso_curbuf))
+ _bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
+ so->btso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
+ {
+ if (BufferIsValid(so->btso_mrkbuf))
+ _bt_relbuf(scan->relation, so->btso_mrkbuf, BT_READ);
+ so->btso_mrkbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ if (so->keyData != (ScanKey) NULL)
+ pfree(so->keyData);
+ pfree(so);
+
+ _bt_dropscan(scan);
}
/*
- * btmarkpos() -- save current scan position
+ * btmarkpos() -- save current scan position
*/
void
btmarkpos(IndexScanDesc scan)
{
- ItemPointer iptr;
- BTScanOpaque so;
-
- so = (BTScanOpaque) scan->opaque;
-
- /* release lock on old marked data, if any */
- if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) {
- _bt_relbuf(scan->relation, so->btso_mrkbuf, BT_READ);
- so->btso_mrkbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- /* bump lock on currentItemData and copy to currentMarkData */
- if (ItemPointerIsValid(&(scan->currentItemData))) {
- so->btso_mrkbuf = _bt_getbuf(scan->relation,
- BufferGetBlockNumber(so->btso_curbuf),
- BT_READ);
- scan->currentMarkData = scan->currentItemData;
- }
+ ItemPointer iptr;
+ BTScanOpaque so;
+
+ so = (BTScanOpaque) scan->opaque;
+
+ /* release lock on old marked data, if any */
+ if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
+ {
+ _bt_relbuf(scan->relation, so->btso_mrkbuf, BT_READ);
+ so->btso_mrkbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ /* bump lock on currentItemData and copy to currentMarkData */
+ if (ItemPointerIsValid(&(scan->currentItemData)))
+ {
+ so->btso_mrkbuf = _bt_getbuf(scan->relation,
+ BufferGetBlockNumber(so->btso_curbuf),
+ BT_READ);
+ scan->currentMarkData = scan->currentItemData;
+ }
}
/*
- * btrestrpos() -- restore scan to last saved position
+ * btrestrpos() -- restore scan to last saved position
*/
void
btrestrpos(IndexScanDesc scan)
{
- ItemPointer iptr;
- BTScanOpaque so;
-
- so = (BTScanOpaque) scan->opaque;
-
- /* release lock on current data, if any */
- if (ItemPointerIsValid(iptr = &(scan->currentItemData))) {
- _bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
- so->btso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(iptr);
- }
-
- /* bump lock on currentMarkData and copy to currentItemData */
- if (ItemPointerIsValid(&(scan->currentMarkData))) {
- so->btso_curbuf = _bt_getbuf(scan->relation,
- BufferGetBlockNumber(so->btso_mrkbuf),
- BT_READ);
-
- scan->currentItemData = scan->currentMarkData;
- }
+ ItemPointer iptr;
+ BTScanOpaque so;
+
+ so = (BTScanOpaque) scan->opaque;
+
+ /* release lock on current data, if any */
+ if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
+ {
+ _bt_relbuf(scan->relation, so->btso_curbuf, BT_READ);
+ so->btso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(iptr);
+ }
+
+ /* bump lock on currentMarkData and copy to currentItemData */
+ if (ItemPointerIsValid(&(scan->currentMarkData)))
+ {
+ so->btso_curbuf = _bt_getbuf(scan->relation,
+ BufferGetBlockNumber(so->btso_mrkbuf),
+ BT_READ);
+
+ scan->currentItemData = scan->currentMarkData;
+ }
}
/* stubs */
void
btdelete(Relation rel, ItemPointer tid)
{
- /* adjust any active scans that will be affected by this deletion */
- _bt_adjscans(rel, tid, BT_DELETE);
-
- /* delete the data from the page */
- _bt_pagedel(rel, tid);
+ /* adjust any active scans that will be affected by this deletion */
+ _bt_adjscans(rel, tid, BT_DELETE);
+
+ /* delete the data from the page */
+ _bt_pagedel(rel, tid);
}
diff --git a/src/backend/access/nbtree/nbtscan.c b/src/backend/access/nbtree/nbtscan.c
index 5e23fe13d7b..8a2042403ad 100644
--- a/src/backend/access/nbtree/nbtscan.c
+++ b/src/backend/access/nbtree/nbtscan.c
@@ -1,28 +1,28 @@
/*-------------------------------------------------------------------------
*
* btscan.c--
- * manage scans on btrees.
+ * manage scans on btrees.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.7 1997/02/18 17:13:45 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.8 1997/09/07 04:38:57 momjian Exp $
*
*
* NOTES
- * Because we can be doing an index scan on a relation while we update
- * it, we need to avoid missing data that moves around in the index.
- * The routines and global variables in this file guarantee that all
- * scans in the local address space stay correctly positioned. This
- * is all we need to worry about, since write locking guarantees that
- * no one else will be on the same page at the same time as we are.
+ * Because we can be doing an index scan on a relation while we update
+ * it, we need to avoid missing data that moves around in the index.
+ * The routines and global variables in this file guarantee that all
+ * scans in the local address space stay correctly positioned. This
+ * is all we need to worry about, since write locking guarantees that
+ * no one else will be on the same page at the same time as we are.
*
- * The scheme is to manage a list of active scans in the current backend.
- * Whenever we add or remove records from an index, or whenever we
- * split a leaf page, we check the list of active scans to see if any
- * has been affected. A scan is affected only if it is on the same
- * relation, and the same page, as the update.
+ * The scheme is to manage a list of active scans in the current backend.
+ * Whenever we add or remove records from an index, or whenever we
+ * split a leaf page, we check the list of active scans to see if any
+ * has been affected. A scan is affected only if it is on the same
+ * relation, and the same page, as the update.
*
*-------------------------------------------------------------------------
*/
@@ -32,83 +32,87 @@
#include <storage/bufpage.h>
#include <access/nbtree.h>
-typedef struct BTScanListData {
- IndexScanDesc btsl_scan;
- struct BTScanListData *btsl_next;
-} BTScanListData;
+typedef struct BTScanListData
+{
+ IndexScanDesc btsl_scan;
+ struct BTScanListData *btsl_next;
+} BTScanListData;
-typedef BTScanListData *BTScanList;
+typedef BTScanListData *BTScanList;
-static BTScanList BTScans = (BTScanList) NULL;
+static BTScanList BTScans = (BTScanList) NULL;
-static void _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno);
-static bool _bt_scantouched(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno);
+static void _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno);
+static bool _bt_scantouched(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno);
/*
- * _bt_regscan() -- register a new scan.
+ * _bt_regscan() -- register a new scan.
*/
void
_bt_regscan(IndexScanDesc scan)
{
- BTScanList new_el;
-
- new_el = (BTScanList) palloc(sizeof(BTScanListData));
- new_el->btsl_scan = scan;
- new_el->btsl_next = BTScans;
- BTScans = new_el;
+ BTScanList new_el;
+
+ new_el = (BTScanList) palloc(sizeof(BTScanListData));
+ new_el->btsl_scan = scan;
+ new_el->btsl_next = BTScans;
+ BTScans = new_el;
}
/*
- * _bt_dropscan() -- drop a scan from the scan list
+ * _bt_dropscan() -- drop a scan from the scan list
*/
void
_bt_dropscan(IndexScanDesc scan)
{
- BTScanList chk, last;
-
- last = (BTScanList) NULL;
- for (chk = BTScans;
- chk != (BTScanList) NULL && chk->btsl_scan != scan;
- chk = chk->btsl_next) {
- last = chk;
- }
-
- if (chk == (BTScanList) NULL)
- elog(WARN, "btree scan list trashed; can't find 0x%lx", scan);
-
- if (last == (BTScanList) NULL)
- BTScans = chk->btsl_next;
- else
- last->btsl_next = chk->btsl_next;
-
- pfree (chk);
+ BTScanList chk,
+ last;
+
+ last = (BTScanList) NULL;
+ for (chk = BTScans;
+ chk != (BTScanList) NULL && chk->btsl_scan != scan;
+ chk = chk->btsl_next)
+ {
+ last = chk;
+ }
+
+ if (chk == (BTScanList) NULL)
+ elog(WARN, "btree scan list trashed; can't find 0x%lx", scan);
+
+ if (last == (BTScanList) NULL)
+ BTScans = chk->btsl_next;
+ else
+ last->btsl_next = chk->btsl_next;
+
+ pfree(chk);
}
/*
- * _bt_adjscans() -- adjust all scans in the scan list to compensate
- * for a given deletion or insertion
+ * _bt_adjscans() -- adjust all scans in the scan list to compensate
+ * for a given deletion or insertion
*/
void
_bt_adjscans(Relation rel, ItemPointer tid, int op)
{
- BTScanList l;
- Oid relid;
-
- relid = rel->rd_id;
- for (l = BTScans; l != (BTScanList) NULL; l = l->btsl_next) {
- if (relid == l->btsl_scan->relation->rd_id)
- _bt_scandel(l->btsl_scan, op,
- ItemPointerGetBlockNumber(tid),
- ItemPointerGetOffsetNumber(tid));
- }
+ BTScanList l;
+ Oid relid;
+
+ relid = rel->rd_id;
+ for (l = BTScans; l != (BTScanList) NULL; l = l->btsl_next)
+ {
+ if (relid == l->btsl_scan->relation->rd_id)
+ _bt_scandel(l->btsl_scan, op,
+ ItemPointerGetBlockNumber(tid),
+ ItemPointerGetOffsetNumber(tid));
+ }
}
/*
- * _bt_scandel() -- adjust a single scan
+ * _bt_scandel() -- adjust a single scan
*
* because each index page is always maintained as an ordered array of
* index tuples, the index tuples on a given page shift beneath any
- * given scan. an index modification "behind" a scan position (i.e.,
+ * given scan. an index modification "behind" a scan position (i.e.,
* same page, lower or equal offset number) will therefore force us to
* adjust the scan in the following ways:
*
@@ -126,80 +130,85 @@ _bt_adjscans(Relation rel, ItemPointer tid, int op)
static void
_bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
{
- ItemPointer current;
- Buffer buf;
- BTScanOpaque so;
-
- if (!_bt_scantouched(scan, blkno, offno))
- return;
-
- so = (BTScanOpaque) scan->opaque;
- buf = so->btso_curbuf;
-
- current = &(scan->currentItemData);
- if (ItemPointerIsValid(current)
- && ItemPointerGetBlockNumber(current) == blkno
- && ItemPointerGetOffsetNumber(current) >= offno) {
- switch (op) {
- case BT_INSERT:
- _bt_step(scan, &buf, ForwardScanDirection);
- break;
- case BT_DELETE:
- _bt_step(scan, &buf, BackwardScanDirection);
- break;
- default:
- elog(WARN, "_bt_scandel: bad operation '%d'", op);
- /*NOTREACHED*/
+ ItemPointer current;
+ Buffer buf;
+ BTScanOpaque so;
+
+ if (!_bt_scantouched(scan, blkno, offno))
+ return;
+
+ so = (BTScanOpaque) scan->opaque;
+ buf = so->btso_curbuf;
+
+ current = &(scan->currentItemData);
+ if (ItemPointerIsValid(current)
+ && ItemPointerGetBlockNumber(current) == blkno
+ && ItemPointerGetOffsetNumber(current) >= offno)
+ {
+ switch (op)
+ {
+ case BT_INSERT:
+ _bt_step(scan, &buf, ForwardScanDirection);
+ break;
+ case BT_DELETE:
+ _bt_step(scan, &buf, BackwardScanDirection);
+ break;
+ default:
+ elog(WARN, "_bt_scandel: bad operation '%d'", op);
+ /* NOTREACHED */
+ }
+ so->btso_curbuf = buf;
}
- so->btso_curbuf = buf;
- }
-
- current = &(scan->currentMarkData);
- if (ItemPointerIsValid(current)
- && ItemPointerGetBlockNumber(current) == blkno
- && ItemPointerGetOffsetNumber(current) >= offno) {
- ItemPointerData tmp;
- tmp = *current;
- *current = scan->currentItemData;
- scan->currentItemData = tmp;
- switch (op) {
- case BT_INSERT:
- _bt_step(scan, &buf, ForwardScanDirection);
- break;
- case BT_DELETE:
- _bt_step(scan, &buf, BackwardScanDirection);
- break;
- default:
- elog(WARN, "_bt_scandel: bad operation '%d'", op);
- /*NOTREACHED*/
+
+ current = &(scan->currentMarkData);
+ if (ItemPointerIsValid(current)
+ && ItemPointerGetBlockNumber(current) == blkno
+ && ItemPointerGetOffsetNumber(current) >= offno)
+ {
+ ItemPointerData tmp;
+
+ tmp = *current;
+ *current = scan->currentItemData;
+ scan->currentItemData = tmp;
+ switch (op)
+ {
+ case BT_INSERT:
+ _bt_step(scan, &buf, ForwardScanDirection);
+ break;
+ case BT_DELETE:
+ _bt_step(scan, &buf, BackwardScanDirection);
+ break;
+ default:
+ elog(WARN, "_bt_scandel: bad operation '%d'", op);
+ /* NOTREACHED */
+ }
+ so->btso_mrkbuf = buf;
+ tmp = *current;
+ *current = scan->currentItemData;
+ scan->currentItemData = tmp;
}
- so->btso_mrkbuf = buf;
- tmp = *current;
- *current = scan->currentItemData;
- scan->currentItemData = tmp;
- }
}
/*
- * _bt_scantouched() -- check to see if a scan is affected by a given
- * change to the index
+ * _bt_scantouched() -- check to see if a scan is affected by a given
+ * change to the index
*/
-static bool
+static bool
_bt_scantouched(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno)
{
- ItemPointer current;
-
- current = &(scan->currentItemData);
- if (ItemPointerIsValid(current)
- && ItemPointerGetBlockNumber(current) == blkno
- && ItemPointerGetOffsetNumber(current) >= offno)
- return (true);
-
- current = &(scan->currentMarkData);
- if (ItemPointerIsValid(current)
- && ItemPointerGetBlockNumber(current) == blkno
- && ItemPointerGetOffsetNumber(current) >= offno)
- return (true);
-
- return (false);
+ ItemPointer current;
+
+ current = &(scan->currentItemData);
+ if (ItemPointerIsValid(current)
+ && ItemPointerGetBlockNumber(current) == blkno
+ && ItemPointerGetOffsetNumber(current) >= offno)
+ return (true);
+
+ current = &(scan->currentMarkData);
+ if (ItemPointerIsValid(current)
+ && ItemPointerGetBlockNumber(current) == blkno
+ && ItemPointerGetOffsetNumber(current) >= offno)
+ return (true);
+
+ return (false);
}
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index 1d1c8072b93..8b1f75b7533 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* btsearch.c--
- * search code for postgres btrees.
+ * search code for postgres btrees.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.23 1997/08/19 21:29:42 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.24 1997/09/07 04:38:58 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,1435 +22,1516 @@
#include <catalog/pg_proc.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static BTStack
-_bt_searchr(Relation rel, int keysz, ScanKey scankey,
- Buffer *bufP, BTStack stack_in);
-static OffsetNumber
-_bt_firsteq(Relation rel, TupleDesc itupdesc, Page page,
- Size keysz, ScanKey scankey, OffsetNumber offnum);
-static int
-_bt_compare(Relation rel, TupleDesc itupdesc, Page page,
- int keysz, ScanKey scankey, OffsetNumber offnum);
-static bool
-_bt_twostep(IndexScanDesc scan, Buffer *bufP, ScanDirection dir);
-static RetrieveIndexResult
-_bt_endpoint(IndexScanDesc scan, ScanDirection dir);
+static BTStack
+_bt_searchr(Relation rel, int keysz, ScanKey scankey,
+ Buffer * bufP, BTStack stack_in);
+static OffsetNumber
+_bt_firsteq(Relation rel, TupleDesc itupdesc, Page page,
+ Size keysz, ScanKey scankey, OffsetNumber offnum);
+static int
+_bt_compare(Relation rel, TupleDesc itupdesc, Page page,
+ int keysz, ScanKey scankey, OffsetNumber offnum);
+static bool
+ _bt_twostep(IndexScanDesc scan, Buffer * bufP, ScanDirection dir);
+static RetrieveIndexResult
+ _bt_endpoint(IndexScanDesc scan, ScanDirection dir);
/*
- * _bt_search() -- Search for a scan key in the index.
+ * _bt_search() -- Search for a scan key in the index.
*
- * This routine is actually just a helper that sets things up and
- * calls a recursive-descent search routine on the tree.
+ * This routine is actually just a helper that sets things up and
+ * calls a recursive-descent search routine on the tree.
*/
BTStack
-_bt_search(Relation rel, int keysz, ScanKey scankey, Buffer *bufP)
+_bt_search(Relation rel, int keysz, ScanKey scankey, Buffer * bufP)
{
- *bufP = _bt_getroot(rel, BT_READ);
- return (_bt_searchr(rel, keysz, scankey, bufP, (BTStack) NULL));
+ *bufP = _bt_getroot(rel, BT_READ);
+ return (_bt_searchr(rel, keysz, scankey, bufP, (BTStack) NULL));
}
/*
- * _bt_searchr() -- Search the tree recursively for a particular scankey.
+ * _bt_searchr() -- Search the tree recursively for a particular scankey.
*/
-static BTStack
+static BTStack
_bt_searchr(Relation rel,
- int keysz,
- ScanKey scankey,
- Buffer *bufP,
- BTStack stack_in)
+ int keysz,
+ ScanKey scankey,
+ Buffer * bufP,
+ BTStack stack_in)
{
- BTStack stack;
- OffsetNumber offnum;
- Page page;
- BTPageOpaque opaque;
- BlockNumber par_blkno;
- BlockNumber blkno;
- ItemId itemid;
- BTItem btitem;
- BTItem item_save;
- int item_nbytes;
- IndexTuple itup;
-
- /* if this is a leaf page, we're done */
- page = BufferGetPage(*bufP);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- if (opaque->btpo_flags & BTP_LEAF)
- return (stack_in);
-
- /*
- * Find the appropriate item on the internal page, and get the child
- * page that it points to.
- */
-
- par_blkno = BufferGetBlockNumber(*bufP);
- offnum = _bt_binsrch(rel, *bufP, keysz, scankey, BT_DESCENT);
- itemid = PageGetItemId(page, offnum);
- btitem = (BTItem) PageGetItem(page, itemid);
- itup = &(btitem->bti_itup);
- blkno = ItemPointerGetBlockNumber(&(itup->t_tid));
-
- /*
- * We need to save the bit image of the index entry we chose in the
- * parent page on a stack. In case we split the tree, we'll use this
- * bit image to figure out what our real parent page is, in case the
- * parent splits while we're working lower in the tree. See the paper
- * by Lehman and Yao for how this is detected and handled. (We use
- * unique OIDs to disambiguate duplicate keys in the index -- Lehman
- * and Yao disallow duplicate keys).
- */
-
- item_nbytes = ItemIdGetLength(itemid);
- item_save = (BTItem) palloc(item_nbytes);
- memmove((char *) item_save, (char *) btitem, item_nbytes);
- stack = (BTStack) palloc(sizeof(BTStackData));
- stack->bts_blkno = par_blkno;
- stack->bts_offset = offnum;
- stack->bts_btitem = item_save;
- stack->bts_parent = stack_in;
-
- /* drop the read lock on the parent page and acquire one on the child */
- _bt_relbuf(rel, *bufP, BT_READ);
- *bufP = _bt_getbuf(rel, blkno, BT_READ);
-
- /*
- * Race -- the page we just grabbed may have split since we read its
- * pointer in the parent. If it has, we may need to move right to its
- * new sibling. Do that.
- */
-
- *bufP = _bt_moveright(rel, *bufP, keysz, scankey, BT_READ);
-
- /* okay, all set to move down a level */
- return (_bt_searchr(rel, keysz, scankey, bufP, stack));
+ BTStack stack;
+ OffsetNumber offnum;
+ Page page;
+ BTPageOpaque opaque;
+ BlockNumber par_blkno;
+ BlockNumber blkno;
+ ItemId itemid;
+ BTItem btitem;
+ BTItem item_save;
+ int item_nbytes;
+ IndexTuple itup;
+
+ /* if this is a leaf page, we're done */
+ page = BufferGetPage(*bufP);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ if (opaque->btpo_flags & BTP_LEAF)
+ return (stack_in);
+
+ /*
+ * Find the appropriate item on the internal page, and get the child
+ * page that it points to.
+ */
+
+ par_blkno = BufferGetBlockNumber(*bufP);
+ offnum = _bt_binsrch(rel, *bufP, keysz, scankey, BT_DESCENT);
+ itemid = PageGetItemId(page, offnum);
+ btitem = (BTItem) PageGetItem(page, itemid);
+ itup = &(btitem->bti_itup);
+ blkno = ItemPointerGetBlockNumber(&(itup->t_tid));
+
+ /*
+ * We need to save the bit image of the index entry we chose in the
+ * parent page on a stack. In case we split the tree, we'll use this
+ * bit image to figure out what our real parent page is, in case the
+ * parent splits while we're working lower in the tree. See the paper
+ * by Lehman and Yao for how this is detected and handled. (We use
+ * unique OIDs to disambiguate duplicate keys in the index -- Lehman
+ * and Yao disallow duplicate keys).
+ */
+
+ item_nbytes = ItemIdGetLength(itemid);
+ item_save = (BTItem) palloc(item_nbytes);
+ memmove((char *) item_save, (char *) btitem, item_nbytes);
+ stack = (BTStack) palloc(sizeof(BTStackData));
+ stack->bts_blkno = par_blkno;
+ stack->bts_offset = offnum;
+ stack->bts_btitem = item_save;
+ stack->bts_parent = stack_in;
+
+ /* drop the read lock on the parent page and acquire one on the child */
+ _bt_relbuf(rel, *bufP, BT_READ);
+ *bufP = _bt_getbuf(rel, blkno, BT_READ);
+
+ /*
+ * Race -- the page we just grabbed may have split since we read its
+ * pointer in the parent. If it has, we may need to move right to its
+ * new sibling. Do that.
+ */
+
+ *bufP = _bt_moveright(rel, *bufP, keysz, scankey, BT_READ);
+
+ /* okay, all set to move down a level */
+ return (_bt_searchr(rel, keysz, scankey, bufP, stack));
}
/*
- * _bt_moveright() -- move right in the btree if necessary.
+ * _bt_moveright() -- move right in the btree if necessary.
*
- * When we drop and reacquire a pointer to a page, it is possible that
- * the page has changed in the meanwhile. If this happens, we're
- * guaranteed that the page has "split right" -- that is, that any
- * data that appeared on the page originally is either on the page
- * or strictly to the right of it.
+ * When we drop and reacquire a pointer to a page, it is possible that
+ * the page has changed in the meanwhile. If this happens, we're
+ * guaranteed that the page has "split right" -- that is, that any
+ * data that appeared on the page originally is either on the page
+ * or strictly to the right of it.
*
- * This routine decides whether or not we need to move right in the
- * tree by examining the high key entry on the page. If that entry
- * is strictly less than one we expect to be on the page, then our
- * picture of the page is incorrect and we need to move right.
+ * This routine decides whether or not we need to move right in the
+ * tree by examining the high key entry on the page. If that entry
+ * is strictly less than one we expect to be on the page, then our
+ * picture of the page is incorrect and we need to move right.
*
- * On entry, we have the buffer pinned and a lock of the proper type.
- * If we move right, we release the buffer and lock and acquire the
- * same on the right sibling.
+ * On entry, we have the buffer pinned and a lock of the proper type.
+ * If we move right, we release the buffer and lock and acquire the
+ * same on the right sibling.
*/
Buffer
_bt_moveright(Relation rel,
- Buffer buf,
- int keysz,
- ScanKey scankey,
- int access)
+ Buffer buf,
+ int keysz,
+ ScanKey scankey,
+ int access)
{
- Page page;
- BTPageOpaque opaque;
- ItemId hikey;
- BlockNumber rblkno;
- int natts = rel->rd_rel->relnatts;
-
- page = BufferGetPage(buf);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
-
- /* if we're on a rightmost page, we don't need to move right */
- if (P_RIGHTMOST(opaque))
- return (buf);
-
- /* by convention, item 0 on non-rightmost pages is the high key */
- hikey = PageGetItemId(page, P_HIKEY);
-
- /*
- * If the scan key that brought us to this page is >= the high key
- * stored on the page, then the page has split and we need to move
- * right.
- */
-
- if (_bt_skeycmp(rel, keysz, scankey, page, hikey,
- BTGreaterEqualStrategyNumber))
- {
- /* move right as long as we need to */
- do
+ Page page;
+ BTPageOpaque opaque;
+ ItemId hikey;
+ BlockNumber rblkno;
+ int natts = rel->rd_rel->relnatts;
+
+ page = BufferGetPage(buf);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+
+ /* if we're on a rightmost page, we don't need to move right */
+ if (P_RIGHTMOST(opaque))
+ return (buf);
+
+ /* by convention, item 0 on non-rightmost pages is the high key */
+ hikey = PageGetItemId(page, P_HIKEY);
+
+ /*
+ * If the scan key that brought us to this page is >= the high key
+ * stored on the page, then the page has split and we need to move
+ * right.
+ */
+
+ if (_bt_skeycmp(rel, keysz, scankey, page, hikey,
+ BTGreaterEqualStrategyNumber))
{
- OffsetNumber offmax = PageGetMaxOffsetNumber(page);
- /*
- * If this page consists of all duplicate keys (hikey and first
- * key on the page have the same value), then we don't need to
- * step right.
- *
- * NOTE for multi-column indices: we may do scan using
- * keys not for all attrs. But we handle duplicates
- * using all attrs in _bt_insert/_bt_spool code.
- * And so we've to compare scankey with _last_ item
- * on this page to do not lose "good" tuples if number
- * of attrs > keysize. Example: (2,0) - last items on
- * this page, (2,1) - first item on next page (hikey),
- * our scankey is x = 2. Scankey == (2,1) because of
- * we compare first attrs only, but we shouldn't to move
- * right of here. - vadim 04/15/97
- */
-
- if ( _bt_skeycmp (rel, keysz, scankey, page, hikey,
- BTEqualStrategyNumber) )
- {
- if ( opaque->btpo_flags & BTP_CHAIN )
- {
- Assert ( ( opaque->btpo_flags & BTP_LEAF ) || offmax > P_HIKEY );
- break;
- }
- if ( offmax > P_HIKEY )
- {
- if ( natts == keysz ) /* sanity checks */
- {
- if ( _bt_skeycmp (rel, keysz, scankey, page,
- PageGetItemId (page, P_FIRSTKEY),
- BTEqualStrategyNumber) )
- elog (FATAL, "btree: BTP_CHAIN flag was expected");
- if ( _bt_skeycmp (rel, keysz, scankey, page,
- PageGetItemId (page, offmax),
- BTEqualStrategyNumber) )
- elog (FATAL, "btree: unexpected equal last item");
- if ( _bt_skeycmp (rel, keysz, scankey, page,
- PageGetItemId (page, offmax),
- BTLessStrategyNumber) )
- elog (FATAL, "btree: unexpected greater last item");
- /* move right */
- }
- else if ( _bt_skeycmp (rel, keysz, scankey, page,
- PageGetItemId (page, offmax),
- BTLessEqualStrategyNumber) )
- break;
- }
- }
-
- /* step right one page */
- rblkno = opaque->btpo_next;
- _bt_relbuf(rel, buf, access);
- buf = _bt_getbuf(rel, rblkno, access);
- page = BufferGetPage(buf);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- hikey = PageGetItemId(page, P_HIKEY);
-
- } while (! P_RIGHTMOST(opaque)
- && _bt_skeycmp(rel, keysz, scankey, page, hikey,
- BTGreaterEqualStrategyNumber));
- }
- return (buf);
+ /* move right as long as we need to */
+ do
+ {
+ OffsetNumber offmax = PageGetMaxOffsetNumber(page);
+
+ /*
+ * If this page consists of all duplicate keys (hikey and
+ * first key on the page have the same value), then we don't
+ * need to step right.
+ *
+ * NOTE for multi-column indices: we may do scan using keys not
+ * for all attrs. But we handle duplicates using all attrs in
+ * _bt_insert/_bt_spool code. And so we've to compare scankey
+ * with _last_ item on this page to do not lose "good" tuples
+ * if number of attrs > keysize. Example: (2,0) - last items
+ * on this page, (2,1) - first item on next page (hikey), our
+ * scankey is x = 2. Scankey == (2,1) because of we compare
+ * first attrs only, but we shouldn't to move right of here.
+ * - vadim 04/15/97
+ */
+
+ if (_bt_skeycmp(rel, keysz, scankey, page, hikey,
+ BTEqualStrategyNumber))
+ {
+ if (opaque->btpo_flags & BTP_CHAIN)
+ {
+ Assert((opaque->btpo_flags & BTP_LEAF) || offmax > P_HIKEY);
+ break;
+ }
+ if (offmax > P_HIKEY)
+ {
+ if (natts == keysz) /* sanity checks */
+ {
+ if (_bt_skeycmp(rel, keysz, scankey, page,
+ PageGetItemId(page, P_FIRSTKEY),
+ BTEqualStrategyNumber))
+ elog(FATAL, "btree: BTP_CHAIN flag was expected");
+ if (_bt_skeycmp(rel, keysz, scankey, page,
+ PageGetItemId(page, offmax),
+ BTEqualStrategyNumber))
+ elog(FATAL, "btree: unexpected equal last item");
+ if (_bt_skeycmp(rel, keysz, scankey, page,
+ PageGetItemId(page, offmax),
+ BTLessStrategyNumber))
+ elog(FATAL, "btree: unexpected greater last item");
+ /* move right */
+ }
+ else if (_bt_skeycmp(rel, keysz, scankey, page,
+ PageGetItemId(page, offmax),
+ BTLessEqualStrategyNumber))
+ break;
+ }
+ }
+
+ /* step right one page */
+ rblkno = opaque->btpo_next;
+ _bt_relbuf(rel, buf, access);
+ buf = _bt_getbuf(rel, rblkno, access);
+ page = BufferGetPage(buf);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ hikey = PageGetItemId(page, P_HIKEY);
+
+ } while (!P_RIGHTMOST(opaque)
+ && _bt_skeycmp(rel, keysz, scankey, page, hikey,
+ BTGreaterEqualStrategyNumber));
+ }
+ return (buf);
}
/*
- * _bt_skeycmp() -- compare a scan key to a particular item on a page using
- * a requested strategy (<, <=, =, >=, >).
+ * _bt_skeycmp() -- compare a scan key to a particular item on a page using
+ * a requested strategy (<, <=, =, >=, >).
*
- * We ignore the unique OIDs stored in the btree item here. Those
- * numbers are intended for use internally only, in repositioning a
- * scan after a page split. They do not impose any meaningful ordering.
+ * We ignore the unique OIDs stored in the btree item here. Those
+ * numbers are intended for use internally only, in repositioning a
+ * scan after a page split. They do not impose any meaningful ordering.
*
- * The comparison is A <op> B, where A is the scan key and B is the
- * tuple pointed at by itemid on page.
+ * The comparison is A <op> B, where A is the scan key and B is the
+ * tuple pointed at by itemid on page.
*/
bool
_bt_skeycmp(Relation rel,
- Size keysz,
- ScanKey scankey,
- Page page,
- ItemId itemid,
- StrategyNumber strat)
+ Size keysz,
+ ScanKey scankey,
+ Page page,
+ ItemId itemid,
+ StrategyNumber strat)
{
- BTItem item;
- IndexTuple indexTuple;
- TupleDesc tupDes;
- ScanKey entry;
- int i;
- Datum attrDatum;
- Datum keyDatum;
- bool compare;
- bool isNull;
- bool useEqual = false;
- bool keyNull;
-
- if ( strat == BTLessEqualStrategyNumber )
- {
- useEqual = true;
- strat = BTLessStrategyNumber;
- }
- else if ( strat == BTGreaterEqualStrategyNumber )
- {
- useEqual = true;
- strat = BTGreaterStrategyNumber;
- }
-
- item = (BTItem) PageGetItem(page, itemid);
- indexTuple = &(item->bti_itup);
-
- tupDes = RelationGetTupleDescriptor(rel);
-
- /* see if the comparison is true for all of the key attributes */
- for (i=1; i <= keysz; i++) {
-
- entry = &scankey[i-1];
- Assert ( entry->sk_attno == i );
- attrDatum = index_getattr(indexTuple,
- entry->sk_attno,
- tupDes,
- &isNull);
- keyDatum = entry->sk_argument;
-
- /* see comments about NULLs handling in btbuild */
- if ( entry->sk_flags & SK_ISNULL ) /* key is NULL */
+ BTItem item;
+ IndexTuple indexTuple;
+ TupleDesc tupDes;
+ ScanKey entry;
+ int i;
+ Datum attrDatum;
+ Datum keyDatum;
+ bool compare;
+ bool isNull;
+ bool useEqual = false;
+ bool keyNull;
+
+ if (strat == BTLessEqualStrategyNumber)
{
- Assert ( entry->sk_procedure == NullValueRegProcedure );
- keyNull = true;
- if ( isNull )
- compare = ( strat == BTEqualStrategyNumber ) ? true : false;
- else
- compare = ( strat == BTGreaterStrategyNumber ) ? true : false;
- }
- else if ( isNull ) /* key is NOT_NULL and item is NULL */
- {
- keyNull = false;
- compare = ( strat == BTLessStrategyNumber ) ? true : false;
- }
- else
- {
- keyNull = false;
- compare = _bt_invokestrat(rel, i, strat, keyDatum, attrDatum);
+ useEqual = true;
+ strat = BTLessStrategyNumber;
}
-
- if ( compare ) /* true for one of ">, <, =" */
+ else if (strat == BTGreaterEqualStrategyNumber)
{
- if ( strat != BTEqualStrategyNumber )
- return (true);
+ useEqual = true;
+ strat = BTGreaterStrategyNumber;
}
- else /* false for one of ">, <, =" */
+
+ item = (BTItem) PageGetItem(page, itemid);
+ indexTuple = &(item->bti_itup);
+
+ tupDes = RelationGetTupleDescriptor(rel);
+
+ /* see if the comparison is true for all of the key attributes */
+ for (i = 1; i <= keysz; i++)
{
- if ( strat == BTEqualStrategyNumber )
- return (false);
- /*
- * if original strat was "<=, >=" OR
- * "<, >" but some attribute(s) left
- * - need to test for Equality
- */
- if ( useEqual || i < keysz )
- {
- if ( keyNull || isNull )
- compare = ( keyNull && isNull ) ? true : false;
- else
- compare = _bt_invokestrat(rel, i, BTEqualStrategyNumber,
- keyDatum, attrDatum);
- if ( compare ) /* key' and item' attributes are equal */
- continue; /* - try to compare next attributes */
- }
- return (false);
+
+ entry = &scankey[i - 1];
+ Assert(entry->sk_attno == i);
+ attrDatum = index_getattr(indexTuple,
+ entry->sk_attno,
+ tupDes,
+ &isNull);
+ keyDatum = entry->sk_argument;
+
+ /* see comments about NULLs handling in btbuild */
+ if (entry->sk_flags & SK_ISNULL) /* key is NULL */
+ {
+ Assert(entry->sk_procedure == NullValueRegProcedure);
+ keyNull = true;
+ if (isNull)
+ compare = (strat == BTEqualStrategyNumber) ? true : false;
+ else
+ compare = (strat == BTGreaterStrategyNumber) ? true : false;
+ }
+ else if (isNull) /* key is NOT_NULL and item is NULL */
+ {
+ keyNull = false;
+ compare = (strat == BTLessStrategyNumber) ? true : false;
+ }
+ else
+ {
+ keyNull = false;
+ compare = _bt_invokestrat(rel, i, strat, keyDatum, attrDatum);
+ }
+
+ if (compare) /* true for one of ">, <, =" */
+ {
+ if (strat != BTEqualStrategyNumber)
+ return (true);
+ }
+ else
+/* false for one of ">, <, =" */
+ {
+ if (strat == BTEqualStrategyNumber)
+ return (false);
+
+ /*
+ * if original strat was "<=, >=" OR "<, >" but some
+ * attribute(s) left - need to test for Equality
+ */
+ if (useEqual || i < keysz)
+ {
+ if (keyNull || isNull)
+ compare = (keyNull && isNull) ? true : false;
+ else
+ compare = _bt_invokestrat(rel, i, BTEqualStrategyNumber,
+ keyDatum, attrDatum);
+ if (compare) /* key' and item' attributes are equal */
+ continue; /* - try to compare next attributes */
+ }
+ return (false);
+ }
}
- }
-
- return (true);
+
+ return (true);
}
/*
- * _bt_binsrch() -- Do a binary search for a key on a particular page.
+ * _bt_binsrch() -- Do a binary search for a key on a particular page.
*
- * The scankey we get has the compare function stored in the procedure
- * entry of each data struct. We invoke this regproc to do the
- * comparison for every key in the scankey. _bt_binsrch() returns
- * the OffsetNumber of the first matching key on the page, or the
- * OffsetNumber at which the matching key would appear if it were
- * on this page.
+ * The scankey we get has the compare function stored in the procedure
+ * entry of each data struct. We invoke this regproc to do the
+ * comparison for every key in the scankey. _bt_binsrch() returns
+ * the OffsetNumber of the first matching key on the page, or the
+ * OffsetNumber at which the matching key would appear if it were
+ * on this page.
*
- * By the time this procedure is called, we're sure we're looking
- * at the right page -- don't need to walk right. _bt_binsrch() has
- * no lock or refcount side effects on the buffer.
+ * By the time this procedure is called, we're sure we're looking
+ * at the right page -- don't need to walk right. _bt_binsrch() has
+ * no lock or refcount side effects on the buffer.
*/
OffsetNumber
_bt_binsrch(Relation rel,
- Buffer buf,
- int keysz,
- ScanKey scankey,
- int srchtype)
+ Buffer buf,
+ int keysz,
+ ScanKey scankey,
+ int srchtype)
{
- TupleDesc itupdesc;
- Page page;
- BTPageOpaque opaque;
- OffsetNumber low, mid, high;
- int natts = rel->rd_rel->relnatts;
- int result;
-
- itupdesc = RelationGetTupleDescriptor(rel);
- page = BufferGetPage(buf);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
-
- /* by convention, item 1 on any non-rightmost page is the high key */
- low = mid = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
-
- high = PageGetMaxOffsetNumber(page);
-
- /*
- * Since for non-rightmost pages, the first item on the page is the
- * high key, there are two notions of emptiness. One is if nothing
- * appears on the page. The other is if nothing but the high key does.
- * The reason we test high <= low, rather than high == low, is that
- * after vacuuming there may be nothing *but* the high key on a page.
- * In that case, given the scheme above, low = 2 and high = 1.
- */
-
- if ( PageIsEmpty (page) )
- return (low);
- if ( (! P_RIGHTMOST(opaque) && high <= low))
- {
- if ( high < low ||
- (srchtype == BT_DESCENT && !(opaque->btpo_flags & BTP_LEAF)) )
- return (low);
- /* It's insertion and high == low == 2 */
- result = _bt_compare(rel, itupdesc, page, keysz, scankey, low);
- if ( result > 0 )
- return ( OffsetNumberNext (low) );
- return (low);
- }
-
- while ((high - low) > 1) {
- mid = low + ((high - low) / 2);
- result = _bt_compare(rel, itupdesc, page, keysz, scankey, mid);
-
- if (result > 0)
- low = mid;
- else if (result < 0)
- high = mid - 1;
- else
+ TupleDesc itupdesc;
+ Page page;
+ BTPageOpaque opaque;
+ OffsetNumber low,
+ mid,
+ high;
+ int natts = rel->rd_rel->relnatts;
+ int result;
+
+ itupdesc = RelationGetTupleDescriptor(rel);
+ page = BufferGetPage(buf);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+
+ /* by convention, item 1 on any non-rightmost page is the high key */
+ low = mid = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+
+ high = PageGetMaxOffsetNumber(page);
+
+ /*
+ * Since for non-rightmost pages, the first item on the page is the
+ * high key, there are two notions of emptiness. One is if nothing
+ * appears on the page. The other is if nothing but the high key
+ * does. The reason we test high <= low, rather than high == low, is
+ * that after vacuuming there may be nothing *but* the high key on a
+ * page. In that case, given the scheme above, low = 2 and high = 1.
+ */
+
+ if (PageIsEmpty(page))
+ return (low);
+ if ((!P_RIGHTMOST(opaque) && high <= low))
{
- mid = _bt_firsteq(rel, itupdesc, page, keysz, scankey, mid);
- /*
- * NOTE for multi-column indices: we may do scan using
- * keys not for all attrs. But we handle duplicates using
- * all attrs in _bt_insert/_bt_spool code. And so while
- * searching on internal pages having number of attrs > keysize
- * we want to point at the last item < the scankey, not at the
- * first item = the scankey (!!!), and let _bt_moveright
- * decide later whether to move right or not (see comments and
- * example there). Note also that INSERTions are not affected
- * by this code (natts == keysz). - vadim 04/15/97
- */
- if ( natts == keysz || opaque->btpo_flags & BTP_LEAF )
- return (mid);
- low = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
- if ( mid == low )
- return (mid);
- return (OffsetNumberPrev(mid));
+ if (high < low ||
+ (srchtype == BT_DESCENT && !(opaque->btpo_flags & BTP_LEAF)))
+ return (low);
+ /* It's insertion and high == low == 2 */
+ result = _bt_compare(rel, itupdesc, page, keysz, scankey, low);
+ if (result > 0)
+ return (OffsetNumberNext(low));
+ return (low);
}
- }
-
- /*
- * We terminated because the endpoints got too close together. There
- * are two cases to take care of.
- *
- * For non-insertion searches on internal pages, we want to point at
- * the last key <, or first key =, the scankey on the page. This
- * guarantees that we'll descend the tree correctly.
- * (NOTE comments above for multi-column indices).
- *
- * For all other cases, we want to point at the first key >=
- * the scankey on the page. This guarantees that scans and
- * insertions will happen correctly.
- */
-
- if (!(opaque->btpo_flags & BTP_LEAF) && srchtype == BT_DESCENT)
- { /*
- * We want the last key <, or first key ==, the scan key.
- */
- result = _bt_compare(rel, itupdesc, page, keysz, scankey, high);
-
- if (result == 0)
+
+ while ((high - low) > 1)
{
- mid = _bt_firsteq(rel, itupdesc, page, keysz, scankey, high);
- /*
- * If natts > keysz we want last item < the scan key.
- * See comments above for multi-column indices.
- */
- if ( natts == keysz )
- return (mid);
- low = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
- if ( mid == low )
- return (mid);
- return (OffsetNumberPrev(mid));
+ mid = low + ((high - low) / 2);
+ result = _bt_compare(rel, itupdesc, page, keysz, scankey, mid);
+
+ if (result > 0)
+ low = mid;
+ else if (result < 0)
+ high = mid - 1;
+ else
+ {
+ mid = _bt_firsteq(rel, itupdesc, page, keysz, scankey, mid);
+
+ /*
+ * NOTE for multi-column indices: we may do scan using keys
+ * not for all attrs. But we handle duplicates using all attrs
+ * in _bt_insert/_bt_spool code. And so while searching on
+ * internal pages having number of attrs > keysize we want to
+ * point at the last item < the scankey, not at the first item
+ * = the scankey (!!!), and let _bt_moveright decide later
+ * whether to move right or not (see comments and example
+ * there). Note also that INSERTions are not affected by this
+ * code (natts == keysz). - vadim 04/15/97
+ */
+ if (natts == keysz || opaque->btpo_flags & BTP_LEAF)
+ return (mid);
+ low = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+ if (mid == low)
+ return (mid);
+ return (OffsetNumberPrev(mid));
+ }
+ }
+
+ /*
+ * We terminated because the endpoints got too close together. There
+ * are two cases to take care of.
+ *
+ * For non-insertion searches on internal pages, we want to point at the
+ * last key <, or first key =, the scankey on the page. This
+ * guarantees that we'll descend the tree correctly. (NOTE comments
+ * above for multi-column indices).
+ *
+ * For all other cases, we want to point at the first key >= the scankey
+ * on the page. This guarantees that scans and insertions will happen
+ * correctly.
+ */
+
+ if (!(opaque->btpo_flags & BTP_LEAF) && srchtype == BT_DESCENT)
+ { /* We want the last key <, or first key
+ * ==, the scan key. */
+ result = _bt_compare(rel, itupdesc, page, keysz, scankey, high);
+
+ if (result == 0)
+ {
+ mid = _bt_firsteq(rel, itupdesc, page, keysz, scankey, high);
+
+ /*
+ * If natts > keysz we want last item < the scan key. See
+ * comments above for multi-column indices.
+ */
+ if (natts == keysz)
+ return (mid);
+ low = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+ if (mid == low)
+ return (mid);
+ return (OffsetNumberPrev(mid));
+ }
+ else if (result > 0)
+ return (high);
+ else
+ return (low);
}
- else if (result > 0)
- return (high);
- else
- return (low);
- }
- else /* we want the first key >= the scan key */
- {
- result = _bt_compare(rel, itupdesc, page, keysz, scankey, low);
- if (result <= 0)
- return (low);
else
+/* we want the first key >= the scan key */
{
- if (low == high)
- return (OffsetNumberNext(low));
-
- result = _bt_compare(rel, itupdesc, page, keysz, scankey, high);
- if (result <= 0)
- return (high);
- else
- return (OffsetNumberNext(high));
+ result = _bt_compare(rel, itupdesc, page, keysz, scankey, low);
+ if (result <= 0)
+ return (low);
+ else
+ {
+ if (low == high)
+ return (OffsetNumberNext(low));
+
+ result = _bt_compare(rel, itupdesc, page, keysz, scankey, high);
+ if (result <= 0)
+ return (high);
+ else
+ return (OffsetNumberNext(high));
+ }
}
- }
}
-static OffsetNumber
+static OffsetNumber
_bt_firsteq(Relation rel,
- TupleDesc itupdesc,
- Page page,
- Size keysz,
- ScanKey scankey,
- OffsetNumber offnum)
+ TupleDesc itupdesc,
+ Page page,
+ Size keysz,
+ ScanKey scankey,
+ OffsetNumber offnum)
{
- BTPageOpaque opaque;
- OffsetNumber limit;
-
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
-
- /* skip the high key, if any */
- limit = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
-
- /* walk backwards looking for the first key in the chain of duplicates */
- while (offnum > limit
- && _bt_compare(rel, itupdesc, page,
- keysz, scankey, OffsetNumberPrev(offnum)) == 0) {
- offnum = OffsetNumberPrev(offnum);
- }
-
- return (offnum);
+ BTPageOpaque opaque;
+ OffsetNumber limit;
+
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+
+ /* skip the high key, if any */
+ limit = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+
+ /* walk backwards looking for the first key in the chain of duplicates */
+ while (offnum > limit
+ && _bt_compare(rel, itupdesc, page,
+ keysz, scankey, OffsetNumberPrev(offnum)) == 0)
+ {
+ offnum = OffsetNumberPrev(offnum);
+ }
+
+ return (offnum);
}
/*
- * _bt_compare() -- Compare scankey to a particular tuple on the page.
+ * _bt_compare() -- Compare scankey to a particular tuple on the page.
*
- * This routine returns:
- * -1 if scankey < tuple at offnum;
- * 0 if scankey == tuple at offnum;
- * +1 if scankey > tuple at offnum.
+ * This routine returns:
+ * -1 if scankey < tuple at offnum;
+ * 0 if scankey == tuple at offnum;
+ * +1 if scankey > tuple at offnum.
*
- * -- Old comments:
- * In order to avoid having to propagate changes up the tree any time
- * a new minimal key is inserted, the leftmost entry on the leftmost
- * page is less than all possible keys, by definition.
+ * -- Old comments:
+ * In order to avoid having to propagate changes up the tree any time
+ * a new minimal key is inserted, the leftmost entry on the leftmost
+ * page is less than all possible keys, by definition.
*
- * -- New ones:
- * New insertion code (fix against updating _in_place_ if new minimal
- * key has bigger size than old one) may delete P_HIKEY entry on the
- * root page in order to insert new minimal key - and so this definition
- * does not work properly in this case and breaks key' order on root
- * page. BTW, this propagation occures only while page' splitting,
- * but not "any time a new min key is inserted" (see _bt_insertonpg).
- * - vadim 12/05/96
+ * -- New ones:
+ * New insertion code (fix against updating _in_place_ if new minimal
+ * key has bigger size than old one) may delete P_HIKEY entry on the
+ * root page in order to insert new minimal key - and so this definition
+ * does not work properly in this case and breaks key' order on root
+ * page. BTW, this propagation occures only while page' splitting,
+ * but not "any time a new min key is inserted" (see _bt_insertonpg).
+ * - vadim 12/05/96
*/
static int
_bt_compare(Relation rel,
- TupleDesc itupdesc,
- Page page,
- int keysz,
- ScanKey scankey,
- OffsetNumber offnum)
+ TupleDesc itupdesc,
+ Page page,
+ int keysz,
+ ScanKey scankey,
+ OffsetNumber offnum)
{
- Datum datum;
- BTItem btitem;
- ItemId itemid;
- IndexTuple itup;
- BTPageOpaque opaque;
- ScanKey entry;
- AttrNumber attno;
- int result;
- int i;
- bool null;
-
- /*
- * If this is a leftmost internal page, and if our comparison is
- * with the first key on the page, then the item at that position is
- * by definition less than the scan key.
- *
- * - see new comments above...
- */
-
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- if (!(opaque->btpo_flags & BTP_LEAF)
- && P_LEFTMOST(opaque)
- && offnum == P_HIKEY) {
- itemid = PageGetItemId(page, offnum);
-
+ Datum datum;
+ BTItem btitem;
+ ItemId itemid;
+ IndexTuple itup;
+ BTPageOpaque opaque;
+ ScanKey entry;
+ AttrNumber attno;
+ int result;
+ int i;
+ bool null;
+
/*
- * we just have to believe that this will only be called with
- * offnum == P_HIKEY when P_HIKEY is the OffsetNumber of the
- * first actual data key (i.e., this is also a rightmost
- * page). there doesn't seem to be any code that implies
- * that the leftmost page is normally missing a high key as
- * well as the rightmost page. but that implies that this
- * code path only applies to the root -- which seems
- * unlikely..
+ * If this is a leftmost internal page, and if our comparison is with
+ * the first key on the page, then the item at that position is by
+ * definition less than the scan key.
*
- * - see new comments above...
+ * - see new comments above...
*/
- if (! P_RIGHTMOST(opaque)) {
- elog(WARN, "_bt_compare: invalid comparison to high key");
- }
+
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ if (!(opaque->btpo_flags & BTP_LEAF)
+ && P_LEFTMOST(opaque)
+ && offnum == P_HIKEY)
+ {
+ itemid = PageGetItemId(page, offnum);
+
+ /*
+ * we just have to believe that this will only be called with
+ * offnum == P_HIKEY when P_HIKEY is the OffsetNumber of the first
+ * actual data key (i.e., this is also a rightmost page). there
+ * doesn't seem to be any code that implies that the leftmost page
+ * is normally missing a high key as well as the rightmost page.
+ * but that implies that this code path only applies to the root
+ * -- which seems unlikely..
+ *
+ * - see new comments above...
+ */
+ if (!P_RIGHTMOST(opaque))
+ {
+ elog(WARN, "_bt_compare: invalid comparison to high key");
+ }
#if 0
+
+ /*
+ * We just have to belive that right answer will not break
+ * anything. I've checked code and all seems to be ok. See new
+ * comments above...
+ *
+ * -- Old comments If the item on the page is equal to the scankey,
+ * that's okay to admit. We just can't claim that the first key
+ * on the page is greater than anything.
+ */
+
+ if (_bt_skeycmp(rel, keysz, scankey, page, itemid,
+ BTEqualStrategyNumber))
+ {
+ return (0);
+ }
+ return (1);
+#endif
+ }
+
+ btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
+ itup = &(btitem->bti_itup);
+
/*
- * We just have to belive that right answer will not
- * break anything. I've checked code and all seems to be ok.
- * See new comments above...
+ * The scan key is set up with the attribute number associated with
+ * each term in the key. It is important that, if the index is
+ * multi-key, the scan contain the first k key attributes, and that
+ * they be in order. If you think about how multi-key ordering works,
+ * you'll understand why this is.
*
- * -- Old comments
- * If the item on the page is equal to the scankey, that's
- * okay to admit. We just can't claim that the first key on
- * the page is greater than anything.
+ * We don't test for violation of this condition here.
*/
-
- if (_bt_skeycmp(rel, keysz, scankey, page, itemid,
- BTEqualStrategyNumber)) {
- return (0);
- }
- return (1);
-#endif
- }
-
- btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
- itup = &(btitem->bti_itup);
-
- /*
- * The scan key is set up with the attribute number associated with each
- * term in the key. It is important that, if the index is multi-key,
- * the scan contain the first k key attributes, and that they be in
- * order. If you think about how multi-key ordering works, you'll
- * understand why this is.
- *
- * We don't test for violation of this condition here.
- */
-
- for (i = 1; i <= keysz; i++) {
- long tmpres;
-
- entry = &scankey[i - 1];
- attno = entry->sk_attno;
- datum = index_getattr(itup, attno, itupdesc, &null);
-
- /* see comments about NULLs handling in btbuild */
- if ( entry->sk_flags & SK_ISNULL ) /* key is NULL */
+
+ for (i = 1; i <= keysz; i++)
{
- Assert ( entry->sk_procedure == NullValueRegProcedure );
- if ( null )
- tmpres = (long) 0; /* NULL "=" NULL */
- else
- tmpres = (long) 1; /* NULL ">" NOT_NULL */
- }
- else if ( null ) /* key is NOT_NULL and item is NULL */
- {
- tmpres = (long) -1; /* NOT_NULL "<" NULL */
- }
- else
- {
- tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
- entry->sk_argument, datum);
+ long tmpres;
+
+ entry = &scankey[i - 1];
+ attno = entry->sk_attno;
+ datum = index_getattr(itup, attno, itupdesc, &null);
+
+ /* see comments about NULLs handling in btbuild */
+ if (entry->sk_flags & SK_ISNULL) /* key is NULL */
+ {
+ Assert(entry->sk_procedure == NullValueRegProcedure);
+ if (null)
+ tmpres = (long) 0; /* NULL "=" NULL */
+ else
+ tmpres = (long) 1; /* NULL ">" NOT_NULL */
+ }
+ else if (null) /* key is NOT_NULL and item is NULL */
+ {
+ tmpres = (long) -1; /* NOT_NULL "<" NULL */
+ }
+ else
+ {
+ tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
+ entry->sk_argument, datum);
+ }
+ result = tmpres;
+
+ /* if the keys are unequal, return the difference */
+ if (result != 0)
+ return (result);
}
- result = tmpres;
-
- /* if the keys are unequal, return the difference */
- if (result != 0)
- return (result);
- }
-
- /* by here, the keys are equal */
- return (0);
+
+ /* by here, the keys are equal */
+ return (0);
}
/*
- * _bt_next() -- Get the next item in a scan.
+ * _bt_next() -- Get the next item in a scan.
*
- * On entry, we have a valid currentItemData in the scan, and a
- * read lock on the page that contains that item. We do not have
- * the page pinned. We return the next item in the scan. On
- * exit, we have the page containing the next item locked but not
- * pinned.
+ * On entry, we have a valid currentItemData in the scan, and a
+ * read lock on the page that contains that item. We do not have
+ * the page pinned. We return the next item in the scan. On
+ * exit, we have the page containing the next item locked but not
+ * pinned.
*/
RetrieveIndexResult
_bt_next(IndexScanDesc scan, ScanDirection dir)
{
- Relation rel;
- Buffer buf;
- Page page;
- OffsetNumber offnum;
- RetrieveIndexResult res;
- ItemPointer current;
- BTItem btitem;
- IndexTuple itup;
- BTScanOpaque so;
- Size keysok;
-
- rel = scan->relation;
- so = (BTScanOpaque) scan->opaque;
- current = &(scan->currentItemData);
-
- /*
- * XXX 10 may 91: somewhere there's a bug in our management of the
- * cached buffer for this scan. wei discovered it. the following
- * is a workaround so he can work until i figure out what's going on.
- */
-
- if (!BufferIsValid(so->btso_curbuf))
- so->btso_curbuf = _bt_getbuf(rel, ItemPointerGetBlockNumber(current),
- BT_READ);
-
- /* we still have the buffer pinned and locked */
- buf = so->btso_curbuf;
-
- do
- {
- /* step one tuple in the appropriate direction */
- if (!_bt_step(scan, &buf, dir))
- return ((RetrieveIndexResult) NULL);
-
- /* by here, current is the tuple we want to return */
- offnum = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(buf);
- btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
- itup = &btitem->bti_itup;
-
- if ( _bt_checkkeys (scan, itup, &keysok) )
- {
- Assert (keysok == so->numberOfKeys);
- res = FormRetrieveIndexResult(current, &(itup->t_tid));
-
- /* remember which buffer we have pinned and locked */
- so->btso_curbuf = buf;
- return (res);
- }
+ Relation rel;
+ Buffer buf;
+ Page page;
+ OffsetNumber offnum;
+ RetrieveIndexResult res;
+ ItemPointer current;
+ BTItem btitem;
+ IndexTuple itup;
+ BTScanOpaque so;
+ Size keysok;
+
+ rel = scan->relation;
+ so = (BTScanOpaque) scan->opaque;
+ current = &(scan->currentItemData);
+
+ /*
+ * XXX 10 may 91: somewhere there's a bug in our management of the
+ * cached buffer for this scan. wei discovered it. the following is
+ * a workaround so he can work until i figure out what's going on.
+ */
+
+ if (!BufferIsValid(so->btso_curbuf))
+ so->btso_curbuf = _bt_getbuf(rel, ItemPointerGetBlockNumber(current),
+ BT_READ);
+
+ /* we still have the buffer pinned and locked */
+ buf = so->btso_curbuf;
+
+ do
+ {
+ /* step one tuple in the appropriate direction */
+ if (!_bt_step(scan, &buf, dir))
+ return ((RetrieveIndexResult) NULL);
- } while ( keysok >= so->numberOfFirstKeys );
+ /* by here, current is the tuple we want to return */
+ offnum = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
+ itup = &btitem->bti_itup;
+
+ if (_bt_checkkeys(scan, itup, &keysok))
+ {
+ Assert(keysok == so->numberOfKeys);
+ res = FormRetrieveIndexResult(current, &(itup->t_tid));
+
+ /* remember which buffer we have pinned and locked */
+ so->btso_curbuf = buf;
+ return (res);
+ }
+
+ } while (keysok >= so->numberOfFirstKeys);
- ItemPointerSetInvalid(current);
- so->btso_curbuf = InvalidBuffer;
- _bt_relbuf(rel, buf, BT_READ);
-
- return ((RetrieveIndexResult) NULL);
+ ItemPointerSetInvalid(current);
+ so->btso_curbuf = InvalidBuffer;
+ _bt_relbuf(rel, buf, BT_READ);
+
+ return ((RetrieveIndexResult) NULL);
}
/*
- * _bt_first() -- Find the first item in a scan.
+ * _bt_first() -- Find the first item in a scan.
*
- * We need to be clever about the type of scan, the operation it's
- * performing, and the tree ordering. We return the RetrieveIndexResult
- * of the first item in the tree that satisfies the qualification
- * associated with the scan descriptor. On exit, the page containing
- * the current index tuple is read locked and pinned, and the scan's
- * opaque data entry is updated to include the buffer.
+ * We need to be clever about the type of scan, the operation it's
+ * performing, and the tree ordering. We return the RetrieveIndexResult
+ * of the first item in the tree that satisfies the qualification
+ * associated with the scan descriptor. On exit, the page containing
+ * the current index tuple is read locked and pinned, and the scan's
+ * opaque data entry is updated to include the buffer.
*/
RetrieveIndexResult
_bt_first(IndexScanDesc scan, ScanDirection dir)
{
- Relation rel;
- TupleDesc itupdesc;
- Buffer buf;
- Page page;
- BTPageOpaque pop;
- BTStack stack;
- OffsetNumber offnum, maxoff;
- bool offGmax = false;
- BTItem btitem;
- IndexTuple itup;
- ItemPointer current;
- BlockNumber blkno;
- StrategyNumber strat;
- RetrieveIndexResult res;
- RegProcedure proc;
- int result;
- BTScanOpaque so;
- ScanKeyData skdata;
- Size keysok;
-
- rel = scan->relation;
- so = (BTScanOpaque) scan->opaque;
-
- /*
- * Order the keys in the qualification and be sure
- * that the scan exploits the tree order.
- */
- so->numberOfFirstKeys = 0; /* may be changed by _bt_orderkeys */
- so->qual_ok = 1; /* may be changed by _bt_orderkeys */
- scan->scanFromEnd = false;
- if ( so->numberOfKeys > 0 )
- {
- _bt_orderkeys(rel, so);
-
- strat = _bt_getstrat(rel, 1, so->keyData[0].sk_procedure);
+ Relation rel;
+ TupleDesc itupdesc;
+ Buffer buf;
+ Page page;
+ BTPageOpaque pop;
+ BTStack stack;
+ OffsetNumber offnum,
+ maxoff;
+ bool offGmax = false;
+ BTItem btitem;
+ IndexTuple itup;
+ ItemPointer current;
+ BlockNumber blkno;
+ StrategyNumber strat;
+ RetrieveIndexResult res;
+ RegProcedure proc;
+ int result;
+ BTScanOpaque so;
+ ScanKeyData skdata;
+ Size keysok;
- /* NOTE: it assumes ForwardScanDirection */
- if ( strat == BTLessStrategyNumber ||
- strat == BTLessEqualStrategyNumber )
- scan->scanFromEnd = true;
- }
- else
- scan->scanFromEnd = true;
-
- if ( so->qual_ok == 0 )
- return ((RetrieveIndexResult) NULL);
-
- /* if we just need to walk down one edge of the tree, do that */
- if (scan->scanFromEnd)
- return (_bt_endpoint(scan, dir));
-
- itupdesc = RelationGetTupleDescriptor(rel);
- current = &(scan->currentItemData);
-
- /*
- * Okay, we want something more complicated. What we'll do is use
- * the first item in the scan key passed in (which has been correctly
- * ordered to take advantage of index ordering) to position ourselves
- * at the right place in the scan.
- */
- /* _bt_orderkeys disallows it, but it's place to add some code latter */
- if ( so->keyData[0].sk_flags & SK_ISNULL )
- {
- elog (WARN, "_bt_first: btree doesn't support is(not)null, yet");
- return ((RetrieveIndexResult) NULL);
- }
- proc = index_getprocid(rel, 1, BTORDER_PROC);
- ScanKeyEntryInitialize(&skdata, so->keyData[0].sk_flags, 1, proc,
- so->keyData[0].sk_argument);
-
- stack = _bt_search(rel, 1, &skdata, &buf);
- _bt_freestack(stack);
-
- blkno = BufferGetBlockNumber(buf);
- page = BufferGetPage(buf);
-
- /*
- * This will happen if the tree we're searching is entirely empty,
- * or if we're doing a search for a key that would appear on an
- * entirely empty internal page. In either case, there are no
- * matching tuples in the index.
- */
-
- if (PageIsEmpty(page)) {
- ItemPointerSetInvalid(current);
- so->btso_curbuf = InvalidBuffer;
- _bt_relbuf(rel, buf, BT_READ);
- return ((RetrieveIndexResult) NULL);
- }
- maxoff = PageGetMaxOffsetNumber(page);
- pop = (BTPageOpaque) PageGetSpecialPointer(page);
-
- /*
- * Now _bt_moveright doesn't move from non-rightmost leaf page
- * if scankey == hikey and there is only hikey there. It's
- * good for insertion, but we need to do work for scan here.
- * - vadim 05/27/97
- */
-
- while ( maxoff == P_HIKEY && !P_RIGHTMOST(pop) &&
- _bt_skeycmp(rel, 1, &skdata, page,
- PageGetItemId(page, P_HIKEY),
- BTGreaterEqualStrategyNumber) )
- {
- /* step right one page */
- blkno = pop->btpo_next;
- _bt_relbuf(rel, buf, BT_READ);
- buf = _bt_getbuf(rel, blkno, BT_READ);
+ rel = scan->relation;
+ so = (BTScanOpaque) scan->opaque;
+
+ /*
+ * Order the keys in the qualification and be sure that the scan
+ * exploits the tree order.
+ */
+ so->numberOfFirstKeys = 0; /* may be changed by _bt_orderkeys */
+ so->qual_ok = 1; /* may be changed by _bt_orderkeys */
+ scan->scanFromEnd = false;
+ if (so->numberOfKeys > 0)
+ {
+ _bt_orderkeys(rel, so);
+
+ strat = _bt_getstrat(rel, 1, so->keyData[0].sk_procedure);
+
+ /* NOTE: it assumes ForwardScanDirection */
+ if (strat == BTLessStrategyNumber ||
+ strat == BTLessEqualStrategyNumber)
+ scan->scanFromEnd = true;
+ }
+ else
+ scan->scanFromEnd = true;
+
+ if (so->qual_ok == 0)
+ return ((RetrieveIndexResult) NULL);
+
+ /* if we just need to walk down one edge of the tree, do that */
+ if (scan->scanFromEnd)
+ return (_bt_endpoint(scan, dir));
+
+ itupdesc = RelationGetTupleDescriptor(rel);
+ current = &(scan->currentItemData);
+
+ /*
+ * Okay, we want something more complicated. What we'll do is use the
+ * first item in the scan key passed in (which has been correctly
+ * ordered to take advantage of index ordering) to position ourselves
+ * at the right place in the scan.
+ */
+ /* _bt_orderkeys disallows it, but it's place to add some code latter */
+ if (so->keyData[0].sk_flags & SK_ISNULL)
+ {
+ elog(WARN, "_bt_first: btree doesn't support is(not)null, yet");
+ return ((RetrieveIndexResult) NULL);
+ }
+ proc = index_getprocid(rel, 1, BTORDER_PROC);
+ ScanKeyEntryInitialize(&skdata, so->keyData[0].sk_flags, 1, proc,
+ so->keyData[0].sk_argument);
+
+ stack = _bt_search(rel, 1, &skdata, &buf);
+ _bt_freestack(stack);
+
+ blkno = BufferGetBlockNumber(buf);
page = BufferGetPage(buf);
- if (PageIsEmpty(page)) {
- ItemPointerSetInvalid(current);
- so->btso_curbuf = InvalidBuffer;
- _bt_relbuf(rel, buf, BT_READ);
- return ((RetrieveIndexResult) NULL);
+
+ /*
+ * This will happen if the tree we're searching is entirely empty, or
+ * if we're doing a search for a key that would appear on an entirely
+ * empty internal page. In either case, there are no matching tuples
+ * in the index.
+ */
+
+ if (PageIsEmpty(page))
+ {
+ ItemPointerSetInvalid(current);
+ so->btso_curbuf = InvalidBuffer;
+ _bt_relbuf(rel, buf, BT_READ);
+ return ((RetrieveIndexResult) NULL);
}
- maxoff = PageGetMaxOffsetNumber(page);
+ maxoff = PageGetMaxOffsetNumber(page);
pop = (BTPageOpaque) PageGetSpecialPointer(page);
- }
-
-
- /* find the nearest match to the manufactured scan key on the page */
- offnum = _bt_binsrch(rel, buf, 1, &skdata, BT_DESCENT);
-
- if (offnum > maxoff)
- {
- offnum = maxoff;
- offGmax = true;
- }
-
- ItemPointerSet(current, blkno, offnum);
-
- /*
- * Now find the right place to start the scan. Result is the
- * value we're looking for minus the value we're looking at
- * in the index.
- */
-
- result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
-
- /* it's yet other place to add some code latter for is(not)null */
-
- strat = _bt_getstrat(rel, 1, so->keyData[0].sk_procedure);
-
- switch (strat) {
- case BTLessStrategyNumber:
- if (result <= 0) {
- do {
- if (!_bt_twostep(scan, &buf, BackwardScanDirection))
- break;
-
- offnum = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(buf);
- result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
- } while (result <= 0);
-
- /* if this is true, the key we just looked at is gone */
- if (result > 0)
- _bt_twostep(scan, &buf, ForwardScanDirection);
- }
- break;
-
- case BTLessEqualStrategyNumber:
- if (result >= 0) {
- do {
- if (!_bt_twostep(scan, &buf, ForwardScanDirection))
- break;
-
- offnum = ItemPointerGetOffsetNumber(current);
+
+ /*
+ * Now _bt_moveright doesn't move from non-rightmost leaf page if
+ * scankey == hikey and there is only hikey there. It's good for
+ * insertion, but we need to do work for scan here. - vadim 05/27/97
+ */
+
+ while (maxoff == P_HIKEY && !P_RIGHTMOST(pop) &&
+ _bt_skeycmp(rel, 1, &skdata, page,
+ PageGetItemId(page, P_HIKEY),
+ BTGreaterEqualStrategyNumber))
+ {
+ /* step right one page */
+ blkno = pop->btpo_next;
+ _bt_relbuf(rel, buf, BT_READ);
+ buf = _bt_getbuf(rel, blkno, BT_READ);
page = BufferGetPage(buf);
- result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
- } while (result >= 0);
-
- if (result < 0)
- _bt_twostep(scan, &buf, BackwardScanDirection);
+ if (PageIsEmpty(page))
+ {
+ ItemPointerSetInvalid(current);
+ so->btso_curbuf = InvalidBuffer;
+ _bt_relbuf(rel, buf, BT_READ);
+ return ((RetrieveIndexResult) NULL);
+ }
+ maxoff = PageGetMaxOffsetNumber(page);
+ pop = (BTPageOpaque) PageGetSpecialPointer(page);
}
- break;
-
- case BTEqualStrategyNumber:
- if (result != 0) {
- _bt_relbuf(scan->relation, buf, BT_READ);
- so->btso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(&(scan->currentItemData));
- return ((RetrieveIndexResult) NULL);
+
+
+ /* find the nearest match to the manufactured scan key on the page */
+ offnum = _bt_binsrch(rel, buf, 1, &skdata, BT_DESCENT);
+
+ if (offnum > maxoff)
+ {
+ offnum = maxoff;
+ offGmax = true;
}
- break;
-
- case BTGreaterEqualStrategyNumber:
- if ( offGmax )
+
+ ItemPointerSet(current, blkno, offnum);
+
+ /*
+ * Now find the right place to start the scan. Result is the value
+ * we're looking for minus the value we're looking at in the index.
+ */
+
+ result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
+
+ /* it's yet other place to add some code latter for is(not)null */
+
+ strat = _bt_getstrat(rel, 1, so->keyData[0].sk_procedure);
+
+ switch (strat)
{
- if (result < 0)
- {
- Assert ( !P_RIGHTMOST(pop) && maxoff == P_HIKEY );
- if ( !_bt_step(scan, &buf, ForwardScanDirection) )
- {
- _bt_relbuf(scan->relation, buf, BT_READ);
- so->btso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(&(scan->currentItemData));
- return ((RetrieveIndexResult) NULL);
+ case BTLessStrategyNumber:
+ if (result <= 0)
+ {
+ do
+ {
+ if (!_bt_twostep(scan, &buf, BackwardScanDirection))
+ break;
+
+ offnum = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
+ } while (result <= 0);
+
+ /* if this is true, the key we just looked at is gone */
+ if (result > 0)
+ _bt_twostep(scan, &buf, ForwardScanDirection);
}
- }
- else if (result > 0)
- { /*
- * Just remember: _bt_binsrch() returns the OffsetNumber of
- * the first matching key on the page, or the OffsetNumber at
- * which the matching key WOULD APPEAR IF IT WERE on this page.
- * No key on this page, but offnum from _bt_binsrch() greater
- * maxoff - have to move right. - vadim 12/06/96
- */
- _bt_twostep(scan, &buf, ForwardScanDirection);
- }
+ break;
+
+ case BTLessEqualStrategyNumber:
+ if (result >= 0)
+ {
+ do
+ {
+ if (!_bt_twostep(scan, &buf, ForwardScanDirection))
+ break;
+
+ offnum = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
+ } while (result >= 0);
+
+ if (result < 0)
+ _bt_twostep(scan, &buf, BackwardScanDirection);
+ }
+ break;
+
+ case BTEqualStrategyNumber:
+ if (result != 0)
+ {
+ _bt_relbuf(scan->relation, buf, BT_READ);
+ so->btso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(&(scan->currentItemData));
+ return ((RetrieveIndexResult) NULL);
+ }
+ break;
+
+ case BTGreaterEqualStrategyNumber:
+ if (offGmax)
+ {
+ if (result < 0)
+ {
+ Assert(!P_RIGHTMOST(pop) && maxoff == P_HIKEY);
+ if (!_bt_step(scan, &buf, ForwardScanDirection))
+ {
+ _bt_relbuf(scan->relation, buf, BT_READ);
+ so->btso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(&(scan->currentItemData));
+ return ((RetrieveIndexResult) NULL);
+ }
+ }
+ else if (result > 0)
+ { /* Just remember: _bt_binsrch() returns
+ * the OffsetNumber of the first matching
+ * key on the page, or the OffsetNumber at
+ * which the matching key WOULD APPEAR IF
+ * IT WERE on this page. No key on this
+ * page, but offnum from _bt_binsrch()
+ * greater maxoff - have to move right. -
+ * vadim 12/06/96 */
+ _bt_twostep(scan, &buf, ForwardScanDirection);
+ }
+ }
+ else if (result < 0)
+ {
+ do
+ {
+ if (!_bt_twostep(scan, &buf, BackwardScanDirection))
+ break;
+
+ page = BufferGetPage(buf);
+ offnum = ItemPointerGetOffsetNumber(current);
+ result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
+ } while (result < 0);
+
+ if (result > 0)
+ _bt_twostep(scan, &buf, ForwardScanDirection);
+ }
+ break;
+
+ case BTGreaterStrategyNumber:
+ /* offGmax helps as above */
+ if (result >= 0 || offGmax)
+ {
+ do
+ {
+ if (!_bt_twostep(scan, &buf, ForwardScanDirection))
+ break;
+
+ offnum = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
+ } while (result >= 0);
+ }
+ break;
}
- else if (result < 0)
+
+ /* okay, current item pointer for the scan is right */
+ offnum = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
+ itup = &btitem->bti_itup;
+
+ if (_bt_checkkeys(scan, itup, &keysok))
{
- do {
- if (!_bt_twostep(scan, &buf, BackwardScanDirection))
- break;
-
- page = BufferGetPage(buf);
- offnum = ItemPointerGetOffsetNumber(current);
- result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
- } while (result < 0);
-
- if (result > 0)
- _bt_twostep(scan, &buf, ForwardScanDirection);
+ res = FormRetrieveIndexResult(current, &(itup->t_tid));
+
+ /* remember which buffer we have pinned */
+ so->btso_curbuf = buf;
}
- break;
-
- case BTGreaterStrategyNumber:
- /* offGmax helps as above */
- if (result >= 0 || offGmax) {
- do {
- if (!_bt_twostep(scan, &buf, ForwardScanDirection))
- break;
-
- offnum = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(buf);
- result = _bt_compare(rel, itupdesc, page, 1, &skdata, offnum);
- } while (result >= 0);
+ else if (keysok >= so->numberOfFirstKeys)
+ {
+ so->btso_curbuf = buf;
+ return (_bt_next(scan, dir));
}
- break;
- }
-
- /* okay, current item pointer for the scan is right */
- offnum = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(buf);
- btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
- itup = &btitem->bti_itup;
-
- if ( _bt_checkkeys (scan, itup, &keysok) )
- {
- res = FormRetrieveIndexResult(current, &(itup->t_tid));
-
- /* remember which buffer we have pinned */
- so->btso_curbuf = buf;
- }
- else if ( keysok >= so->numberOfFirstKeys )
- {
- so->btso_curbuf = buf;
- return (_bt_next (scan, dir));
- }
- else
- {
- ItemPointerSetInvalid(current);
- so->btso_curbuf = InvalidBuffer;
- _bt_relbuf(rel, buf, BT_READ);
- res = (RetrieveIndexResult) NULL;
- }
-
- return (res);
+ else
+ {
+ ItemPointerSetInvalid(current);
+ so->btso_curbuf = InvalidBuffer;
+ _bt_relbuf(rel, buf, BT_READ);
+ res = (RetrieveIndexResult) NULL;
+ }
+
+ return (res);
}
/*
- * _bt_step() -- Step one item in the requested direction in a scan on
- * the tree.
+ * _bt_step() -- Step one item in the requested direction in a scan on
+ * the tree.
*
- * If no adjacent record exists in the requested direction, return
- * false. Else, return true and set the currentItemData for the
- * scan to the right thing.
+ * If no adjacent record exists in the requested direction, return
+ * false. Else, return true and set the currentItemData for the
+ * scan to the right thing.
*/
bool
-_bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
+_bt_step(IndexScanDesc scan, Buffer * bufP, ScanDirection dir)
{
- Page page;
- BTPageOpaque opaque;
- OffsetNumber offnum, maxoff;
- OffsetNumber start;
- BlockNumber blkno;
- BlockNumber obknum;
- BTScanOpaque so;
- ItemPointer current;
- Relation rel;
-
- rel = scan->relation;
- current = &(scan->currentItemData);
- offnum = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(*bufP);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- so = (BTScanOpaque) scan->opaque;
- maxoff = PageGetMaxOffsetNumber(page);
-
- /* get the next tuple */
- if (ScanDirectionIsForward(dir)) {
- if (!PageIsEmpty(page) && offnum < maxoff) {
- offnum = OffsetNumberNext(offnum);
- } else {
-
- /* if we're at end of scan, release the buffer and return */
- blkno = opaque->btpo_next;
- if (P_RIGHTMOST(opaque)) {
- _bt_relbuf(rel, *bufP, BT_READ);
- ItemPointerSetInvalid(current);
- *bufP = so->btso_curbuf = InvalidBuffer;
- return (false);
- } else {
-
- /* walk right to the next page with data */
- _bt_relbuf(rel, *bufP, BT_READ);
- for (;;) {
- *bufP = _bt_getbuf(rel, blkno, BT_READ);
- page = BufferGetPage(*bufP);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- maxoff = PageGetMaxOffsetNumber(page);
- start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
-
- if (!PageIsEmpty(page) && start <= maxoff) {
- break;
- } else {
+ Page page;
+ BTPageOpaque opaque;
+ OffsetNumber offnum,
+ maxoff;
+ OffsetNumber start;
+ BlockNumber blkno;
+ BlockNumber obknum;
+ BTScanOpaque so;
+ ItemPointer current;
+ Relation rel;
+
+ rel = scan->relation;
+ current = &(scan->currentItemData);
+ offnum = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(*bufP);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ so = (BTScanOpaque) scan->opaque;
+ maxoff = PageGetMaxOffsetNumber(page);
+
+ /* get the next tuple */
+ if (ScanDirectionIsForward(dir))
+ {
+ if (!PageIsEmpty(page) && offnum < maxoff)
+ {
+ offnum = OffsetNumberNext(offnum);
+ }
+ else
+ {
+
+ /* if we're at end of scan, release the buffer and return */
blkno = opaque->btpo_next;
- _bt_relbuf(rel, *bufP, BT_READ);
- if (blkno == P_NONE) {
- *bufP = so->btso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(current);
- return (false);
+ if (P_RIGHTMOST(opaque))
+ {
+ _bt_relbuf(rel, *bufP, BT_READ);
+ ItemPointerSetInvalid(current);
+ *bufP = so->btso_curbuf = InvalidBuffer;
+ return (false);
+ }
+ else
+ {
+
+ /* walk right to the next page with data */
+ _bt_relbuf(rel, *bufP, BT_READ);
+ for (;;)
+ {
+ *bufP = _bt_getbuf(rel, blkno, BT_READ);
+ page = BufferGetPage(*bufP);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ maxoff = PageGetMaxOffsetNumber(page);
+ start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+
+ if (!PageIsEmpty(page) && start <= maxoff)
+ {
+ break;
+ }
+ else
+ {
+ blkno = opaque->btpo_next;
+ _bt_relbuf(rel, *bufP, BT_READ);
+ if (blkno == P_NONE)
+ {
+ *bufP = so->btso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(current);
+ return (false);
+ }
+ }
+ }
+ offnum = start;
}
- }
}
- offnum = start;
- }
}
- } else if (ScanDirectionIsBackward(dir)) {
-
- /* remember that high key is item zero on non-rightmost pages */
- start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+ else if (ScanDirectionIsBackward(dir))
+ {
- if (offnum > start) {
- offnum = OffsetNumberPrev(offnum);
- } else {
-
- /* if we're at end of scan, release the buffer and return */
- blkno = opaque->btpo_prev;
- if (P_LEFTMOST(opaque)) {
- _bt_relbuf(rel, *bufP, BT_READ);
- *bufP = so->btso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(current);
- return (false);
- } else {
-
- obknum = BufferGetBlockNumber(*bufP);
-
- /* walk right to the next page with data */
- _bt_relbuf(rel, *bufP, BT_READ);
- for (;;) {
- *bufP = _bt_getbuf(rel, blkno, BT_READ);
- page = BufferGetPage(*bufP);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- maxoff = PageGetMaxOffsetNumber(page);
-
- /*
- * If the adjacent page just split, then we may have the
- * wrong block. Handle this case. Because pages only
- * split right, we don't have to worry about this failing
- * to terminate.
- */
-
- while (opaque->btpo_next != obknum) {
- blkno = opaque->btpo_next;
- _bt_relbuf(rel, *bufP, BT_READ);
- *bufP = _bt_getbuf(rel, blkno, BT_READ);
- page = BufferGetPage(*bufP);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- maxoff = PageGetMaxOffsetNumber(page);
- }
-
- /* don't consider the high key */
- start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
-
- /* anything to look at here? */
- if (!PageIsEmpty(page) && maxoff >= start) {
- break;
- } else {
+ /* remember that high key is item zero on non-rightmost pages */
+ start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+
+ if (offnum > start)
+ {
+ offnum = OffsetNumberPrev(offnum);
+ }
+ else
+ {
+
+ /* if we're at end of scan, release the buffer and return */
blkno = opaque->btpo_prev;
- obknum = BufferGetBlockNumber(*bufP);
- _bt_relbuf(rel, *bufP, BT_READ);
- if (blkno == P_NONE) {
- *bufP = so->btso_curbuf = InvalidBuffer;
- ItemPointerSetInvalid(current);
- return (false);
+ if (P_LEFTMOST(opaque))
+ {
+ _bt_relbuf(rel, *bufP, BT_READ);
+ *bufP = so->btso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(current);
+ return (false);
+ }
+ else
+ {
+
+ obknum = BufferGetBlockNumber(*bufP);
+
+ /* walk right to the next page with data */
+ _bt_relbuf(rel, *bufP, BT_READ);
+ for (;;)
+ {
+ *bufP = _bt_getbuf(rel, blkno, BT_READ);
+ page = BufferGetPage(*bufP);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ maxoff = PageGetMaxOffsetNumber(page);
+
+ /*
+ * If the adjacent page just split, then we may have
+ * the wrong block. Handle this case. Because pages
+ * only split right, we don't have to worry about this
+ * failing to terminate.
+ */
+
+ while (opaque->btpo_next != obknum)
+ {
+ blkno = opaque->btpo_next;
+ _bt_relbuf(rel, *bufP, BT_READ);
+ *bufP = _bt_getbuf(rel, blkno, BT_READ);
+ page = BufferGetPage(*bufP);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ maxoff = PageGetMaxOffsetNumber(page);
+ }
+
+ /* don't consider the high key */
+ start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+
+ /* anything to look at here? */
+ if (!PageIsEmpty(page) && maxoff >= start)
+ {
+ break;
+ }
+ else
+ {
+ blkno = opaque->btpo_prev;
+ obknum = BufferGetBlockNumber(*bufP);
+ _bt_relbuf(rel, *bufP, BT_READ);
+ if (blkno == P_NONE)
+ {
+ *bufP = so->btso_curbuf = InvalidBuffer;
+ ItemPointerSetInvalid(current);
+ return (false);
+ }
+ }
+ }
+ offnum = maxoff;/* XXX PageIsEmpty? */
}
- }
}
- offnum = maxoff; /* XXX PageIsEmpty? */
- }
}
- }
- blkno = BufferGetBlockNumber(*bufP);
- so->btso_curbuf = *bufP;
- ItemPointerSet(current, blkno, offnum);
-
- return (true);
+ blkno = BufferGetBlockNumber(*bufP);
+ so->btso_curbuf = *bufP;
+ ItemPointerSet(current, blkno, offnum);
+
+ return (true);
}
/*
- * _bt_twostep() -- Move to an adjacent record in a scan on the tree,
- * if an adjacent record exists.
+ * _bt_twostep() -- Move to an adjacent record in a scan on the tree,
+ * if an adjacent record exists.
*
- * This is like _bt_step, except that if no adjacent record exists
- * it restores us to where we were before trying the step. This is
- * only hairy when you cross page boundaries, since the page you cross
- * from could have records inserted or deleted, or could even split.
- * This is unlikely, but we try to handle it correctly here anyway.
+ * This is like _bt_step, except that if no adjacent record exists
+ * it restores us to where we were before trying the step. This is
+ * only hairy when you cross page boundaries, since the page you cross
+ * from could have records inserted or deleted, or could even split.
+ * This is unlikely, but we try to handle it correctly here anyway.
*
- * This routine contains the only case in which our changes to Lehman
- * and Yao's algorithm.
+ * This routine contains the only case in which our changes to Lehman
+ * and Yao's algorithm.
*
- * Like step, this routine leaves the scan's currentItemData in the
- * proper state and acquires a lock and pin on *bufP. If the twostep
- * succeeded, we return true; otherwise, we return false.
+ * Like step, this routine leaves the scan's currentItemData in the
+ * proper state and acquires a lock and pin on *bufP. If the twostep
+ * succeeded, we return true; otherwise, we return false.
*/
-static bool
-_bt_twostep(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
+static bool
+_bt_twostep(IndexScanDesc scan, Buffer * bufP, ScanDirection dir)
{
- Page page;
- BTPageOpaque opaque;
- OffsetNumber offnum, maxoff;
- OffsetNumber start;
- ItemPointer current;
- ItemId itemid;
- int itemsz;
- BTItem btitem;
- BTItem svitem;
- BlockNumber blkno;
-
- blkno = BufferGetBlockNumber(*bufP);
- page = BufferGetPage(*bufP);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- maxoff = PageGetMaxOffsetNumber(page);
- current = &(scan->currentItemData);
- offnum = ItemPointerGetOffsetNumber(current);
-
- start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
-
- /* if we're safe, just do it */
- if (ScanDirectionIsForward(dir) && offnum < maxoff) { /* XXX PageIsEmpty? */
- ItemPointerSet(current, blkno, OffsetNumberNext(offnum));
- return (true);
- } else if (ScanDirectionIsBackward(dir) && offnum > start) {
- ItemPointerSet(current, blkno, OffsetNumberPrev(offnum));
- return (true);
- }
-
- /* if we've hit end of scan we don't have to do any work */
- if (ScanDirectionIsForward(dir) && P_RIGHTMOST(opaque)) {
- return (false);
- } else if (ScanDirectionIsBackward(dir) && P_LEFTMOST(opaque)) {
- return (false);
- }
-
- /*
- * Okay, it's off the page; let _bt_step() do the hard work, and we'll
- * try to remember where we were. This is not guaranteed to work; this
- * is the only place in the code where concurrency can screw us up,
- * and it's because we want to be able to move in two directions in
- * the scan.
- */
-
- itemid = PageGetItemId(page, offnum);
- itemsz = ItemIdGetLength(itemid);
- btitem = (BTItem) PageGetItem(page, itemid);
- svitem = (BTItem) palloc(itemsz);
- memmove((char *) svitem, (char *) btitem, itemsz);
-
- if (_bt_step(scan, bufP, dir)) {
- pfree(svitem);
- return (true);
- }
-
- /* try to find our place again */
- *bufP = _bt_getbuf(scan->relation, blkno, BT_READ);
- page = BufferGetPage(*bufP);
- maxoff = PageGetMaxOffsetNumber(page);
-
- while (offnum <= maxoff) {
+ Page page;
+ BTPageOpaque opaque;
+ OffsetNumber offnum,
+ maxoff;
+ OffsetNumber start;
+ ItemPointer current;
+ ItemId itemid;
+ int itemsz;
+ BTItem btitem;
+ BTItem svitem;
+ BlockNumber blkno;
+
+ blkno = BufferGetBlockNumber(*bufP);
+ page = BufferGetPage(*bufP);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ maxoff = PageGetMaxOffsetNumber(page);
+ current = &(scan->currentItemData);
+ offnum = ItemPointerGetOffsetNumber(current);
+
+ start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+
+ /* if we're safe, just do it */
+ if (ScanDirectionIsForward(dir) && offnum < maxoff)
+ { /* XXX PageIsEmpty? */
+ ItemPointerSet(current, blkno, OffsetNumberNext(offnum));
+ return (true);
+ }
+ else if (ScanDirectionIsBackward(dir) && offnum > start)
+ {
+ ItemPointerSet(current, blkno, OffsetNumberPrev(offnum));
+ return (true);
+ }
+
+ /* if we've hit end of scan we don't have to do any work */
+ if (ScanDirectionIsForward(dir) && P_RIGHTMOST(opaque))
+ {
+ return (false);
+ }
+ else if (ScanDirectionIsBackward(dir) && P_LEFTMOST(opaque))
+ {
+ return (false);
+ }
+
+ /*
+ * Okay, it's off the page; let _bt_step() do the hard work, and we'll
+ * try to remember where we were. This is not guaranteed to work;
+ * this is the only place in the code where concurrency can screw us
+ * up, and it's because we want to be able to move in two directions
+ * in the scan.
+ */
+
itemid = PageGetItemId(page, offnum);
+ itemsz = ItemIdGetLength(itemid);
btitem = (BTItem) PageGetItem(page, itemid);
- if ( BTItemSame (btitem, svitem) ) {
- pfree(svitem);
- ItemPointerSet(current, blkno, offnum);
- return (false);
+ svitem = (BTItem) palloc(itemsz);
+ memmove((char *) svitem, (char *) btitem, itemsz);
+
+ if (_bt_step(scan, bufP, dir))
+ {
+ pfree(svitem);
+ return (true);
+ }
+
+ /* try to find our place again */
+ *bufP = _bt_getbuf(scan->relation, blkno, BT_READ);
+ page = BufferGetPage(*bufP);
+ maxoff = PageGetMaxOffsetNumber(page);
+
+ while (offnum <= maxoff)
+ {
+ itemid = PageGetItemId(page, offnum);
+ btitem = (BTItem) PageGetItem(page, itemid);
+ if (BTItemSame(btitem, svitem))
+ {
+ pfree(svitem);
+ ItemPointerSet(current, blkno, offnum);
+ return (false);
+ }
}
- }
-
- /*
- * XXX crash and burn -- can't find our place. We can be a little
- * smarter -- walk to the next page to the right, for example, since
- * that's the only direction that splits happen in. Deletions screw
- * us up less often since they're only done by the vacuum daemon.
- */
-
- elog(WARN, "btree synchronization error: concurrent update botched scan");
-
- return (false);
+
+ /*
+ * XXX crash and burn -- can't find our place. We can be a little
+ * smarter -- walk to the next page to the right, for example, since
+ * that's the only direction that splits happen in. Deletions screw
+ * us up less often since they're only done by the vacuum daemon.
+ */
+
+ elog(WARN, "btree synchronization error: concurrent update botched scan");
+
+ return (false);
}
/*
- * _bt_endpoint() -- Find the first or last key in the index.
+ * _bt_endpoint() -- Find the first or last key in the index.
*/
-static RetrieveIndexResult
+static RetrieveIndexResult
_bt_endpoint(IndexScanDesc scan, ScanDirection dir)
{
- Relation rel;
- Buffer buf;
- Page page;
- BTPageOpaque opaque;
- ItemPointer current;
- OffsetNumber offnum, maxoff;
- OffsetNumber start = 0;
- BlockNumber blkno;
- BTItem btitem;
- IndexTuple itup;
- BTScanOpaque so;
- RetrieveIndexResult res;
- Size keysok;
-
- rel = scan->relation;
- current = &(scan->currentItemData);
- so = (BTScanOpaque) scan->opaque;
-
- buf = _bt_getroot(rel, BT_READ);
- blkno = BufferGetBlockNumber(buf);
- page = BufferGetPage(buf);
- opaque = (BTPageOpaque) PageGetSpecialPointer(page);
-
- for (;;) {
- if (opaque->btpo_flags & BTP_LEAF)
- break;
-
- if (ScanDirectionIsForward(dir)) {
- offnum = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
- } else {
- offnum = PageGetMaxOffsetNumber(page);
- }
-
- btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
- itup = &(btitem->bti_itup);
-
- blkno = ItemPointerGetBlockNumber(&(itup->t_tid));
-
- _bt_relbuf(rel, buf, BT_READ);
- buf = _bt_getbuf(rel, blkno, BT_READ);
+ Relation rel;
+ Buffer buf;
+ Page page;
+ BTPageOpaque opaque;
+ ItemPointer current;
+ OffsetNumber offnum,
+ maxoff;
+ OffsetNumber start = 0;
+ BlockNumber blkno;
+ BTItem btitem;
+ IndexTuple itup;
+ BTScanOpaque so;
+ RetrieveIndexResult res;
+ Size keysok;
+
+ rel = scan->relation;
+ current = &(scan->currentItemData);
+ so = (BTScanOpaque) scan->opaque;
+
+ buf = _bt_getroot(rel, BT_READ);
+ blkno = BufferGetBlockNumber(buf);
page = BufferGetPage(buf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
-
- /*
- * Race condition: If the child page we just stepped onto is
- * in the process of being split, we need to make sure we're
- * all the way at the right edge of the tree. See the paper
- * by Lehman and Yao.
- */
-
- if (ScanDirectionIsBackward(dir) && ! P_RIGHTMOST(opaque)) {
- do {
- blkno = opaque->btpo_next;
+
+ for (;;)
+ {
+ if (opaque->btpo_flags & BTP_LEAF)
+ break;
+
+ if (ScanDirectionIsForward(dir))
+ {
+ offnum = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+ }
+ else
+ {
+ offnum = PageGetMaxOffsetNumber(page);
+ }
+
+ btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
+ itup = &(btitem->bti_itup);
+
+ blkno = ItemPointerGetBlockNumber(&(itup->t_tid));
+
_bt_relbuf(rel, buf, BT_READ);
buf = _bt_getbuf(rel, blkno, BT_READ);
page = BufferGetPage(buf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
- } while (! P_RIGHTMOST(opaque));
+
+ /*
+ * Race condition: If the child page we just stepped onto is in
+ * the process of being split, we need to make sure we're all the
+ * way at the right edge of the tree. See the paper by Lehman and
+ * Yao.
+ */
+
+ if (ScanDirectionIsBackward(dir) && !P_RIGHTMOST(opaque))
+ {
+ do
+ {
+ blkno = opaque->btpo_next;
+ _bt_relbuf(rel, buf, BT_READ);
+ buf = _bt_getbuf(rel, blkno, BT_READ);
+ page = BufferGetPage(buf);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ } while (!P_RIGHTMOST(opaque));
+ }
}
- }
-
- /* okay, we've got the {left,right}-most page in the tree */
- maxoff = PageGetMaxOffsetNumber(page);
-
- if (ScanDirectionIsForward(dir)) {
- if ( !P_LEFTMOST(opaque) ) /* non-leftmost page ? */
- elog (WARN, "_bt_endpoint: leftmost page (%u) has not leftmost flag", blkno);
- start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
- /*
- * I don't understand this stuff! It doesn't work for non-rightmost
- * pages with only one element (P_HIKEY) which we have after
- * deletion itups by vacuum (it's case of start > maxoff).
- * Scanning in BackwardScanDirection is not understandable at all.
- * Well - new stuff. - vadim 12/06/96
- */
+
+ /* okay, we've got the {left,right}-most page in the tree */
+ maxoff = PageGetMaxOffsetNumber(page);
+
+ if (ScanDirectionIsForward(dir))
+ {
+ if (!P_LEFTMOST(opaque))/* non-leftmost page ? */
+ elog(WARN, "_bt_endpoint: leftmost page (%u) has not leftmost flag", blkno);
+ start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+
+ /*
+ * I don't understand this stuff! It doesn't work for
+ * non-rightmost pages with only one element (P_HIKEY) which we
+ * have after deletion itups by vacuum (it's case of start >
+ * maxoff). Scanning in BackwardScanDirection is not
+ * understandable at all. Well - new stuff. - vadim 12/06/96
+ */
#if 0
- if (PageIsEmpty(page) || start > maxoff) {
- ItemPointerSet(current, blkno, maxoff);
- if (!_bt_step(scan, &buf, BackwardScanDirection))
- return ((RetrieveIndexResult) NULL);
-
- start = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(buf);
- }
+ if (PageIsEmpty(page) || start > maxoff)
+ {
+ ItemPointerSet(current, blkno, maxoff);
+ if (!_bt_step(scan, &buf, BackwardScanDirection))
+ return ((RetrieveIndexResult) NULL);
+
+ start = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ }
#endif
- if ( PageIsEmpty (page) )
+ if (PageIsEmpty(page))
+ {
+ if (start != P_HIKEY) /* non-rightmost page */
+ elog(WARN, "_bt_endpoint: non-rightmost page (%u) is empty", blkno);
+
+ /*
+ * It's left- & right- most page - root page, - and it's
+ * empty...
+ */
+ _bt_relbuf(rel, buf, BT_READ);
+ ItemPointerSetInvalid(current);
+ so->btso_curbuf = InvalidBuffer;
+ return ((RetrieveIndexResult) NULL);
+ }
+ if (start > maxoff) /* start == 2 && maxoff == 1 */
+ {
+ ItemPointerSet(current, blkno, maxoff);
+ if (!_bt_step(scan, &buf, ForwardScanDirection))
+ return ((RetrieveIndexResult) NULL);
+
+ start = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ }
+ /* new stuff ends here */
+ else
+ {
+ ItemPointerSet(current, blkno, start);
+ }
+ }
+ else if (ScanDirectionIsBackward(dir))
{
- if ( start != P_HIKEY ) /* non-rightmost page */
- elog (WARN, "_bt_endpoint: non-rightmost page (%u) is empty", blkno);
- /* It's left- & right- most page - root page, - and it's empty... */
- _bt_relbuf(rel, buf, BT_READ);
- ItemPointerSetInvalid(current);
- so->btso_curbuf = InvalidBuffer;
- return ((RetrieveIndexResult) NULL);
+
+ /*
+ * I don't understand this stuff too! If RIGHT-most leaf page is
+ * empty why do scanning in ForwardScanDirection ??? Well - new
+ * stuff. - vadim 12/06/96
+ */
+#if 0
+ if (PageIsEmpty(page))
+ {
+ ItemPointerSet(current, blkno, FirstOffsetNumber);
+ if (!_bt_step(scan, &buf, ForwardScanDirection))
+ return ((RetrieveIndexResult) NULL);
+
+ start = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ }
+#endif
+ if (PageIsEmpty(page))
+ {
+ /* If it's leftmost page too - it's empty root page... */
+ if (P_LEFTMOST(opaque))
+ {
+ _bt_relbuf(rel, buf, BT_READ);
+ ItemPointerSetInvalid(current);
+ so->btso_curbuf = InvalidBuffer;
+ return ((RetrieveIndexResult) NULL);
+ }
+ /* Go back ! */
+ ItemPointerSet(current, blkno, FirstOffsetNumber);
+ if (!_bt_step(scan, &buf, BackwardScanDirection))
+ return ((RetrieveIndexResult) NULL);
+
+ start = ItemPointerGetOffsetNumber(current);
+ page = BufferGetPage(buf);
+ }
+ /* new stuff ends here */
+ else
+ {
+ start = PageGetMaxOffsetNumber(page);
+ ItemPointerSet(current, blkno, start);
+ }
}
- if ( start > maxoff ) /* start == 2 && maxoff == 1 */
+ else
{
- ItemPointerSet(current, blkno, maxoff);
- if (!_bt_step(scan, &buf, ForwardScanDirection))
- return ((RetrieveIndexResult) NULL);
-
- start = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(buf);
+ elog(WARN, "Illegal scan direction %d", dir);
}
- /* new stuff ends here */
- else {
- ItemPointerSet(current, blkno, start);
+
+ btitem = (BTItem) PageGetItem(page, PageGetItemId(page, start));
+ itup = &(btitem->bti_itup);
+
+ /* see if we picked a winner */
+ if (_bt_checkkeys(scan, itup, &keysok))
+ {
+ res = FormRetrieveIndexResult(current, &(itup->t_tid));
+
+ /* remember which buffer we have pinned */
+ so->btso_curbuf = buf;
}
- } else if (ScanDirectionIsBackward(dir)) {
- /*
- * I don't understand this stuff too! If RIGHT-most leaf page is
- * empty why do scanning in ForwardScanDirection ???
- * Well - new stuff. - vadim 12/06/96
- */
-#if 0
- if (PageIsEmpty(page)) {
- ItemPointerSet(current, blkno, FirstOffsetNumber);
- if (!_bt_step(scan, &buf, ForwardScanDirection))
- return ((RetrieveIndexResult) NULL);
-
- start = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(buf);
+ else if (keysok >= so->numberOfFirstKeys)
+ {
+ so->btso_curbuf = buf;
+ return (_bt_next(scan, dir));
}
-#endif
- if (PageIsEmpty(page))
+ else
{
- /* If it's leftmost page too - it's empty root page... */
- if ( P_LEFTMOST(opaque) )
- {
- _bt_relbuf(rel, buf, BT_READ);
ItemPointerSetInvalid(current);
so->btso_curbuf = InvalidBuffer;
- return ((RetrieveIndexResult) NULL);
- }
- /* Go back ! */
- ItemPointerSet(current, blkno, FirstOffsetNumber);
- if (!_bt_step(scan, &buf, BackwardScanDirection))
- return ((RetrieveIndexResult) NULL);
-
- start = ItemPointerGetOffsetNumber(current);
- page = BufferGetPage(buf);
- }
- /* new stuff ends here */
- else {
- start = PageGetMaxOffsetNumber(page);
- ItemPointerSet(current, blkno, start);
+ _bt_relbuf(rel, buf, BT_READ);
+ res = (RetrieveIndexResult) NULL;
}
- } else {
- elog(WARN, "Illegal scan direction %d", dir);
- }
-
- btitem = (BTItem) PageGetItem(page, PageGetItemId(page, start));
- itup = &(btitem->bti_itup);
-
- /* see if we picked a winner */
- if ( _bt_checkkeys (scan, itup, &keysok) )
- {
- res = FormRetrieveIndexResult(current, &(itup->t_tid));
-
- /* remember which buffer we have pinned */
- so->btso_curbuf = buf;
- }
- else if ( keysok >= so->numberOfFirstKeys )
- {
- so->btso_curbuf = buf;
- return (_bt_next (scan, dir));
- }
- else
- {
- ItemPointerSetInvalid(current);
- so->btso_curbuf = InvalidBuffer;
- _bt_relbuf(rel, buf, BT_READ);
- res = (RetrieveIndexResult) NULL;
- }
-
- return (res);
+
+ return (res);
}
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index 8e054d24abf..09cb43769f2 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -5,30 +5,30 @@
*
*
* IDENTIFICATION
- * $Id: nbtsort.c,v 1.19 1997/08/19 21:29:46 momjian Exp $
+ * $Id: nbtsort.c,v 1.20 1997/09/07 04:39:02 momjian Exp $
*
* NOTES
*
* what we do is:
* - generate a set of initial one-block runs, distributed round-robin
- * between the output tapes.
+ * between the output tapes.
* - for each pass,
- * - swap input and output tape sets, rewinding both and truncating
- * the output tapes.
- * - merge the current run in each input tape to the current output
- * tape.
- * - when each input run has been exhausted, switch to another output
- * tape and start processing another run.
+ * - swap input and output tape sets, rewinding both and truncating
+ * the output tapes.
+ * - merge the current run in each input tape to the current output
+ * tape.
+ * - when each input run has been exhausted, switch to another output
+ * tape and start processing another run.
* - when we have fewer runs than tapes, we know we are ready to start
- * merging into the btree leaf pages. (i.e., we do not have to wait
- * until we have exactly one tape.)
+ * merging into the btree leaf pages. (i.e., we do not have to wait
+ * until we have exactly one tape.)
* - as we extract tuples from the final runs, we build the pages 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.
+ * 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.
*
* conventions:
* - external interface routines take in and return "void *" for their
- * opaque handles. this is for modularity reasons.
+ * opaque handles. this is for modularity reasons.
*
* this code is moderately slow (~10% slower) compared to the regular
* btree (insertion) build code on sorted or well-clustered data. on
@@ -58,20 +58,21 @@
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
#ifdef BTREE_BUILD_STATS
#include <tcop/tcopprot.h>
-extern int ShowExecutorStats;
+extern int ShowExecutorStats;
+
#endif
-static BTItem _bt_buildadd(Relation index, void *pstate, BTItem bti, int flags);
-static BTItem _bt_minitem(Page opage, BlockNumber oblkno, int atend);
-static void *_bt_pagestate(Relation index, int flags, int level, bool doupper);
-static void _bt_uppershutdown(Relation index, BTPageState *state);
+static BTItem _bt_buildadd(Relation index, void *pstate, BTItem bti, int flags);
+static BTItem _bt_minitem(Page opage, BlockNumber oblkno, int atend);
+static void *_bt_pagestate(Relation index, int flags, int level, bool doupper);
+static void _bt_uppershutdown(Relation index, BTPageState * state);
/*
* turn on debugging output.
@@ -83,18 +84,18 @@ static void _bt_uppershutdown(Relation index, BTPageState *state);
#define FASTBUILD_SPOOL
#define FASTBUILD_MERGE
-#define MAXTAPES (7)
-#define TAPEBLCKSZ (MAXBLCKSZ << 2)
-#define TAPETEMP "pg_btsortXXXXXX"
+#define MAXTAPES (7)
+#define TAPEBLCKSZ (MAXBLCKSZ << 2)
+#define TAPETEMP "pg_btsortXXXXXX"
-extern int NDirectFileRead;
-extern int NDirectFileWrite;
-extern char *mktemp(char *template);
+extern int NDirectFileRead;
+extern int NDirectFileWrite;
+extern char *mktemp(char *template);
/*
- * this is what we use to shovel BTItems in and out of memory. it's
+ * this is what we use to shovel BTItems in and out of memory. it's
* bigger than a standard block because we are doing a lot of strictly
- * sequential i/o. this is obviously something of a tradeoff since we
+ * sequential i/o. this is obviously something of a tradeoff since we
* are potentially reading a bunch of zeroes off of disk in many
* cases.
*
@@ -104,14 +105,15 @@ extern char *mktemp(char *template);
* the only thing like that so i'm not going to worry about wasting a
* few bytes.
*/
-typedef struct {
- int bttb_magic; /* magic number */
- int bttb_fd; /* file descriptor */
- int bttb_top; /* top of free space within bttb_data */
- short bttb_ntup; /* number of tuples in this block */
- short bttb_eor; /* End-Of-Run marker */
- char bttb_data[TAPEBLCKSZ - 2 * sizeof(double)];
-} BTTapeBlock;
+typedef struct
+{
+ int bttb_magic; /* magic number */
+ int bttb_fd; /* file descriptor */
+ int bttb_top; /* top of free space within bttb_data */
+ short bttb_ntup; /* number of tuples in this block */
+ short bttb_eor; /* End-Of-Run marker */
+ char bttb_data[TAPEBLCKSZ - 2 * sizeof(double)];
+} BTTapeBlock;
/*
* this structure holds the bookkeeping for a simple balanced multiway
@@ -120,13 +122,14 @@ typedef struct {
* right now. though if psort was in a condition that i could hack it
* to do this, you bet i would.)
*/
-typedef struct {
- int bts_ntapes;
- int bts_tape;
- BTTapeBlock **bts_itape; /* input tape blocks */
- BTTapeBlock **bts_otape; /* output tape blocks */
- bool isunique;
-} BTSpool;
+typedef struct
+{
+ int bts_ntapes;
+ int bts_tape;
+ BTTapeBlock **bts_itape; /* input tape blocks */
+ BTTapeBlock **bts_otape; /* output tape blocks */
+ bool isunique;
+} BTSpool;
/*-------------------------------------------------------------------------
* sorting comparison routine - returns {-1,0,1} depending on whether
@@ -146,101 +149,102 @@ typedef struct {
* what the heck.
* *-------------------------------------------------------------------------
*/
-typedef struct {
- Datum *btsk_datum;
- char *btsk_nulls;
- BTItem btsk_item;
-} BTSortKey;
+typedef struct
+{
+ Datum *btsk_datum;
+ char *btsk_nulls;
+ BTItem btsk_item;
+} BTSortKey;
static Relation _bt_sortrel;
-static int _bt_nattr;
-static BTSpool * _bt_inspool;
+static int _bt_nattr;
+static BTSpool *_bt_inspool;
static void
-_bt_isortcmpinit(Relation index, BTSpool *spool)
+_bt_isortcmpinit(Relation index, BTSpool * spool)
{
- _bt_sortrel = index;
- _bt_inspool = spool;
- _bt_nattr = index->rd_att->natts;
+ _bt_sortrel = index;
+ _bt_inspool = spool;
+ _bt_nattr = index->rd_att->natts;
}
static int
-_bt_isortcmp(BTSortKey *k1, BTSortKey *k2)
+_bt_isortcmp(BTSortKey * k1, BTSortKey * k2)
{
- Datum *k1_datum = k1->btsk_datum;
- Datum *k2_datum = k2->btsk_datum;
- char *k1_nulls = k1->btsk_nulls;
- char *k2_nulls = k2->btsk_nulls;
- bool equal_isnull = false;
- int i;
-
- if (k1->btsk_item == (BTItem) NULL)
- {
- if (k2->btsk_item == (BTItem) NULL)
- return(0); /* 1 = 2 */
- return(1); /* 1 > 2 */
- }
- else if (k2->btsk_item == (BTItem) NULL)
- return(-1); /* 1 < 2 */
-
- for (i = 0; i < _bt_nattr; i++)
- {
- if ( k1_nulls[i] != ' ' ) /* k1 attr is NULL */
+ Datum *k1_datum = k1->btsk_datum;
+ Datum *k2_datum = k2->btsk_datum;
+ char *k1_nulls = k1->btsk_nulls;
+ char *k2_nulls = k2->btsk_nulls;
+ bool equal_isnull = false;
+ int i;
+
+ if (k1->btsk_item == (BTItem) NULL)
{
- if ( k2_nulls[i] != ' ' ) /* the same for k2 */
- {
- equal_isnull = true;
- continue;
- }
- return (1); /* NULL ">" NOT_NULL */
+ if (k2->btsk_item == (BTItem) NULL)
+ return (0); /* 1 = 2 */
+ return (1); /* 1 > 2 */
}
- else if ( k2_nulls[i] != ' ' ) /* k2 attr is NULL */
- return (-1); /* NOT_NULL "<" NULL */
-
- if (_bt_invokestrat(_bt_sortrel, i+1, BTGreaterStrategyNumber,
- k1_datum[i], k2_datum[i]))
- return(1); /* 1 > 2 */
- else if (_bt_invokestrat(_bt_sortrel, i+1, BTGreaterStrategyNumber,
- k2_datum[i], k1_datum[i]))
- return(-1); /* 1 < 2 */
- }
-
- if ( _bt_inspool->isunique && !equal_isnull )
- {
- _bt_spooldestroy ((void*)_bt_inspool);
- elog (WARN, "Cannot create unique index. Table contains non-unique values");
- }
- return(0); /* 1 = 2 */
+ else if (k2->btsk_item == (BTItem) NULL)
+ return (-1); /* 1 < 2 */
+
+ for (i = 0; i < _bt_nattr; i++)
+ {
+ if (k1_nulls[i] != ' ') /* k1 attr is NULL */
+ {
+ if (k2_nulls[i] != ' ') /* the same for k2 */
+ {
+ equal_isnull = true;
+ continue;
+ }
+ return (1); /* NULL ">" NOT_NULL */
+ }
+ else if (k2_nulls[i] != ' ') /* k2 attr is NULL */
+ return (-1); /* NOT_NULL "<" NULL */
+
+ if (_bt_invokestrat(_bt_sortrel, i + 1, BTGreaterStrategyNumber,
+ k1_datum[i], k2_datum[i]))
+ return (1); /* 1 > 2 */
+ else if (_bt_invokestrat(_bt_sortrel, i + 1, BTGreaterStrategyNumber,
+ k2_datum[i], k1_datum[i]))
+ return (-1); /* 1 < 2 */
+ }
+
+ if (_bt_inspool->isunique && !equal_isnull)
+ {
+ _bt_spooldestroy((void *) _bt_inspool);
+ elog(WARN, "Cannot create unique index. Table contains non-unique values");
+ }
+ return (0); /* 1 = 2 */
}
static void
-_bt_setsortkey(Relation index, BTItem bti, BTSortKey *sk)
+_bt_setsortkey(Relation index, BTItem bti, BTSortKey * sk)
{
- sk->btsk_item = (BTItem) NULL;
- sk->btsk_datum = (Datum*) NULL;
- sk->btsk_nulls = (char*) NULL;
-
- if (bti != (BTItem) NULL)
- {
- IndexTuple it = &(bti->bti_itup);
- TupleDesc itdesc = index->rd_att;
- Datum *dp = (Datum*) palloc (_bt_nattr * sizeof (Datum));
- char *np = (char*) palloc (_bt_nattr * sizeof (char));
- bool isnull;
- int i;
-
- for (i = 0; i < _bt_nattr; i++)
- {
- dp[i] = index_getattr(it, i+1, itdesc, &isnull);
- if ( isnull )
- np[i] = 'n';
- else
- np[i] = ' ';
+ sk->btsk_item = (BTItem) NULL;
+ sk->btsk_datum = (Datum *) NULL;
+ sk->btsk_nulls = (char *) NULL;
+
+ if (bti != (BTItem) NULL)
+ {
+ IndexTuple it = &(bti->bti_itup);
+ TupleDesc itdesc = index->rd_att;
+ Datum *dp = (Datum *) palloc(_bt_nattr * sizeof(Datum));
+ char *np = (char *) palloc(_bt_nattr * sizeof(char));
+ bool isnull;
+ int i;
+
+ for (i = 0; i < _bt_nattr; i++)
+ {
+ dp[i] = index_getattr(it, i + 1, itdesc, &isnull);
+ if (isnull)
+ np[i] = 'n';
+ else
+ np[i] = ' ';
+ }
+ sk->btsk_item = bti;
+ sk->btsk_datum = dp;
+ sk->btsk_nulls = np;
}
- sk->btsk_item = bti;
- sk->btsk_datum = dp;
- sk->btsk_nulls = np;
- }
}
/*-------------------------------------------------------------------------
@@ -254,84 +258,100 @@ _bt_setsortkey(Relation index, BTItem bti, BTSortKey *sk)
* XXX these probably ought to be generic library functions.
*-------------------------------------------------------------------------
*/
-typedef struct {
- int btpqe_tape; /* tape identifier */
- BTSortKey btpqe_item; /* pointer to BTItem in tape buffer */
-} BTPriQueueElem;
-
-#define MAXELEM MAXTAPES
-typedef struct {
- int btpq_nelem;
- BTPriQueueElem btpq_queue[MAXELEM];
- Relation btpq_rel;
-} BTPriQueue;
+typedef struct
+{
+ int btpqe_tape; /* tape identifier */
+ BTSortKey btpqe_item; /* pointer to BTItem in tape buffer */
+} BTPriQueueElem;
+
+#define MAXELEM MAXTAPES
+typedef struct
+{
+ int btpq_nelem;
+ BTPriQueueElem btpq_queue[MAXELEM];
+ Relation btpq_rel;
+} BTPriQueue;
/* be sure to call _bt_isortcmpinit first */
#define GREATER(a, b) \
- (_bt_isortcmp(&((a)->btpqe_item), &((b)->btpqe_item)) > 0)
+ (_bt_isortcmp(&((a)->btpqe_item), &((b)->btpqe_item)) > 0)
static void
-_bt_pqsift(BTPriQueue *q, int parent)
+_bt_pqsift(BTPriQueue * q, int parent)
{
- int child;
- BTPriQueueElem e;
-
- for (child = parent * 2 + 1;
- child < q->btpq_nelem;
- child = parent * 2 + 1) {
- if (child < q->btpq_nelem - 1) {
- if (GREATER(&(q->btpq_queue[child]), &(q->btpq_queue[child+1]))) {
- ++child;
- }
- }
- if (GREATER(&(q->btpq_queue[parent]), &(q->btpq_queue[child]))) {
- e = q->btpq_queue[child]; /* struct = */
- q->btpq_queue[child] = q->btpq_queue[parent]; /* struct = */
- q->btpq_queue[parent] = e; /* struct = */
- parent = child;
- } else {
- parent = child + 1;
+ int child;
+ BTPriQueueElem e;
+
+ for (child = parent * 2 + 1;
+ child < q->btpq_nelem;
+ child = parent * 2 + 1)
+ {
+ if (child < q->btpq_nelem - 1)
+ {
+ if (GREATER(&(q->btpq_queue[child]), &(q->btpq_queue[child + 1])))
+ {
+ ++child;
+ }
+ }
+ if (GREATER(&(q->btpq_queue[parent]), &(q->btpq_queue[child])))
+ {
+ e = q->btpq_queue[child]; /* struct = */
+ q->btpq_queue[child] = q->btpq_queue[parent]; /* struct = */
+ q->btpq_queue[parent] = e; /* struct = */
+ parent = child;
+ }
+ else
+ {
+ parent = child + 1;
+ }
}
- }
}
static int
-_bt_pqnext(BTPriQueue *q, BTPriQueueElem *e)
+_bt_pqnext(BTPriQueue * q, BTPriQueueElem * e)
{
- if (q->btpq_nelem < 1) { /* already empty */
- return(-1);
- }
- *e = q->btpq_queue[0]; /* struct = */
-
- if (--q->btpq_nelem < 1) { /* now empty, don't sift */
- return(0);
- }
- q->btpq_queue[0] = q->btpq_queue[q->btpq_nelem]; /* struct = */
- _bt_pqsift(q, 0);
- return(0);
+ if (q->btpq_nelem < 1)
+ { /* already empty */
+ return (-1);
+ }
+ *e = q->btpq_queue[0]; /* struct = */
+
+ if (--q->btpq_nelem < 1)
+ { /* now empty, don't sift */
+ return (0);
+ }
+ q->btpq_queue[0] = q->btpq_queue[q->btpq_nelem]; /* struct = */
+ _bt_pqsift(q, 0);
+ return (0);
}
static void
-_bt_pqadd(BTPriQueue *q, BTPriQueueElem *e)
+_bt_pqadd(BTPriQueue * q, BTPriQueueElem * e)
{
- int child, parent;
-
- if (q->btpq_nelem >= MAXELEM) {
- elog(WARN, "_bt_pqadd: queue overflow");
- }
-
- child = q->btpq_nelem++;
- while (child > 0) {
- parent = child / 2;
- if (GREATER(e, &(q->btpq_queue[parent]))) {
- break;
- } else {
- q->btpq_queue[child] = q->btpq_queue[parent]; /* struct = */
- child = parent;
+ int child,
+ parent;
+
+ if (q->btpq_nelem >= MAXELEM)
+ {
+ elog(WARN, "_bt_pqadd: queue overflow");
+ }
+
+ child = q->btpq_nelem++;
+ while (child > 0)
+ {
+ parent = child / 2;
+ if (GREATER(e, &(q->btpq_queue[parent])))
+ {
+ break;
+ }
+ else
+ {
+ q->btpq_queue[child] = q->btpq_queue[parent]; /* struct = */
+ child = parent;
+ }
}
- }
- q->btpq_queue[child] = *e; /* struct = */
+ q->btpq_queue[child] = *e; /* struct = */
}
/*-------------------------------------------------------------------------
@@ -339,37 +359,37 @@ _bt_pqadd(BTPriQueue *q, BTPriQueueElem *e)
*-------------------------------------------------------------------------
*/
-#define BTITEMSZ(btitem) \
- ((btitem) ? \
- (IndexTupleDSize((btitem)->bti_itup) + \
- (sizeof(BTItemData) - sizeof(IndexTupleData))) : \
- 0)
-#define SPCLEFT(tape) \
- (sizeof((tape)->bttb_data) - (tape)->bttb_top)
-#define EMPTYTAPE(tape) \
- ((tape)->bttb_ntup <= 0)
-#define BTTAPEMAGIC 0x19660226
+#define BTITEMSZ(btitem) \
+ ((btitem) ? \
+ (IndexTupleDSize((btitem)->bti_itup) + \
+ (sizeof(BTItemData) - sizeof(IndexTupleData))) : \
+ 0)
+#define SPCLEFT(tape) \
+ (sizeof((tape)->bttb_data) - (tape)->bttb_top)
+#define EMPTYTAPE(tape) \
+ ((tape)->bttb_ntup <= 0)
+#define BTTAPEMAGIC 0x19660226
/*
* reset the tape header for its next use without doing anything to
- * the physical tape file. (setting bttb_top to 0 makes the block
+ * the physical tape file. (setting bttb_top to 0 makes the block
* empty.)
*/
static void
-_bt_tapereset(BTTapeBlock *tape)
+_bt_tapereset(BTTapeBlock * tape)
{
- tape->bttb_eor = 0;
- tape->bttb_top = 0;
- tape->bttb_ntup = 0;
+ tape->bttb_eor = 0;
+ tape->bttb_top = 0;
+ tape->bttb_ntup = 0;
}
/*
* rewind the physical tape file.
*/
static void
-_bt_taperewind(BTTapeBlock *tape)
+_bt_taperewind(BTTapeBlock * tape)
{
- FileSeek(tape->bttb_fd, 0, SEEK_SET);
+ FileSeek(tape->bttb_fd, 0, SEEK_SET);
}
/*
@@ -382,17 +402,17 @@ _bt_taperewind(BTTapeBlock *tape)
* least you don't have to delete and reinsert the directory entries.
*/
static void
-_bt_tapeclear(BTTapeBlock *tape)
+_bt_tapeclear(BTTapeBlock * tape)
{
- /* blow away the contents of the old file */
- _bt_taperewind(tape);
+ /* blow away the contents of the old file */
+ _bt_taperewind(tape);
#if 0
- FileSync(tape->bttb_fd);
+ FileSync(tape->bttb_fd);
#endif
- FileTruncate(tape->bttb_fd, 0);
+ FileTruncate(tape->bttb_fd, 0);
- /* reset the buffer */
- _bt_tapereset(tape);
+ /* reset the buffer */
+ _bt_tapereset(tape);
}
/*
@@ -402,43 +422,44 @@ _bt_tapeclear(BTTapeBlock *tape)
static BTTapeBlock *
_bt_tapecreate(char *fname)
{
- BTTapeBlock *tape = (BTTapeBlock *) palloc(sizeof(BTTapeBlock));
+ BTTapeBlock *tape = (BTTapeBlock *) palloc(sizeof(BTTapeBlock));
- if (tape == (BTTapeBlock *) NULL) {
- elog(WARN, "_bt_tapecreate: out of memory");
- }
+ if (tape == (BTTapeBlock *) NULL)
+ {
+ elog(WARN, "_bt_tapecreate: out of memory");
+ }
- tape->bttb_magic = BTTAPEMAGIC;
+ tape->bttb_magic = BTTAPEMAGIC;
- tape->bttb_fd = FileNameOpenFile(fname, O_RDWR|O_CREAT|O_TRUNC, 0600);
- Assert(tape->bttb_fd >= 0);
+ tape->bttb_fd = FileNameOpenFile(fname, O_RDWR | O_CREAT | O_TRUNC, 0600);
+ Assert(tape->bttb_fd >= 0);
- /* initialize the buffer */
- _bt_tapereset(tape);
+ /* initialize the buffer */
+ _bt_tapereset(tape);
- return(tape);
+ return (tape);
}
/*
* destroy the BTTapeBlock structure and its physical tape file.
*/
static void
-_bt_tapedestroy(BTTapeBlock *tape)
+_bt_tapedestroy(BTTapeBlock * tape)
{
- FileUnlink(tape->bttb_fd);
- pfree((void *) tape);
+ FileUnlink(tape->bttb_fd);
+ pfree((void *) tape);
}
/*
* flush the tape block to the file, marking End-Of-Run if requested.
*/
static void
-_bt_tapewrite(BTTapeBlock *tape, int eor)
+_bt_tapewrite(BTTapeBlock * tape, int eor)
{
- tape->bttb_eor = eor;
- FileWrite(tape->bttb_fd, (char *) tape, TAPEBLCKSZ);
- NDirectFileWrite += TAPEBLCKSZ/MAXBLCKSZ;
- _bt_tapereset(tape);
+ tape->bttb_eor = eor;
+ FileWrite(tape->bttb_fd, (char *) tape, TAPEBLCKSZ);
+ NDirectFileWrite += TAPEBLCKSZ / MAXBLCKSZ;
+ _bt_tapereset(tape);
}
/*
@@ -447,34 +468,36 @@ _bt_tapewrite(BTTapeBlock *tape, int eor)
*
* returns:
* - 0 if there are no more blocks in the tape or in this run (call
- * _bt_tapereset to clear the End-Of-Run marker)
+ * _bt_tapereset to clear the End-Of-Run marker)
* - 1 if a valid block was read
*/
static int
-_bt_taperead(BTTapeBlock *tape)
+_bt_taperead(BTTapeBlock * tape)
{
- int fd;
- int nread;
-
- if (tape->bttb_eor) {
- return(0); /* we are already at End-Of-Run */
- }
-
- /*
- * we're clobbering the old tape block, but we do need to save the
- * VFD (the one in the block we're reading is bogus).
- */
- fd = tape->bttb_fd;
- nread = FileRead(fd, (char *) tape, TAPEBLCKSZ);
- tape->bttb_fd = fd;
-
- if (nread != TAPEBLCKSZ) {
- Assert(nread == 0); /* we are at EOF */
- return(0);
- }
- Assert(tape->bttb_magic == BTTAPEMAGIC);
- NDirectFileRead += TAPEBLCKSZ/MAXBLCKSZ;
- return(1);
+ int fd;
+ int nread;
+
+ if (tape->bttb_eor)
+ {
+ return (0); /* we are already at End-Of-Run */
+ }
+
+ /*
+ * we're clobbering the old tape block, but we do need to save the VFD
+ * (the one in the block we're reading is bogus).
+ */
+ fd = tape->bttb_fd;
+ nread = FileRead(fd, (char *) tape, TAPEBLCKSZ);
+ tape->bttb_fd = fd;
+
+ if (nread != TAPEBLCKSZ)
+ {
+ Assert(nread == 0); /* we are at EOF */
+ return (0);
+ }
+ Assert(tape->bttb_magic == BTTAPEMAGIC);
+ NDirectFileRead += TAPEBLCKSZ / MAXBLCKSZ;
+ return (1);
}
/*
@@ -487,19 +510,20 @@ _bt_taperead(BTTapeBlock *tape)
* side effects:
* - sets 'pos' to the current position within the block.
*/
-static BTItem
-_bt_tapenext(BTTapeBlock *tape, char **pos)
+static BTItem
+_bt_tapenext(BTTapeBlock * tape, char **pos)
{
- Size itemsz;
- BTItem bti;
-
- if (*pos >= tape->bttb_data + tape->bttb_top) {
- return((BTItem) NULL);
- }
- bti = (BTItem) *pos;
- itemsz = BTITEMSZ(bti);
- *pos += DOUBLEALIGN(itemsz);
- return(bti);
+ Size itemsz;
+ BTItem bti;
+
+ if (*pos >= tape->bttb_data + tape->bttb_top)
+ {
+ return ((BTItem) NULL);
+ }
+ bti = (BTItem) * pos;
+ itemsz = BTITEMSZ(bti);
+ *pos += DOUBLEALIGN(itemsz);
+ return (bti);
}
/*
@@ -514,11 +538,11 @@ _bt_tapenext(BTTapeBlock *tape, char **pos)
* the beginning of free space.
*/
static void
-_bt_tapeadd(BTTapeBlock *tape, BTItem item, int itemsz)
+_bt_tapeadd(BTTapeBlock * tape, BTItem item, int itemsz)
{
- memcpy(tape->bttb_data + tape->bttb_top, item, itemsz);
- ++tape->bttb_ntup;
- tape->bttb_top += DOUBLEALIGN(itemsz);
+ memcpy(tape->bttb_data + tape->bttb_top, item, itemsz);
+ ++tape->bttb_ntup;
+ tape->bttb_top += DOUBLEALIGN(itemsz);
}
/*-------------------------------------------------------------------------
@@ -530,41 +554,44 @@ _bt_tapeadd(BTTapeBlock *tape, BTItem item, int itemsz)
* create and initialize a spool structure, including the underlying
* files.
*/
-void *
+void *
_bt_spoolinit(Relation index, int ntapes, bool isunique)
{
- BTSpool *btspool = (BTSpool *) palloc(sizeof(BTSpool));
- int i;
- char *fname = (char *) palloc(sizeof(TAPETEMP) + 1);
-
- if (btspool == (BTSpool *) NULL || fname == (char *) NULL) {
- elog(WARN, "_bt_spoolinit: out of memory");
- }
- memset((char *) btspool, 0, sizeof(BTSpool));
- btspool->bts_ntapes = ntapes;
- btspool->bts_tape = 0;
- btspool->isunique = isunique;
-
- btspool->bts_itape =
- (BTTapeBlock **) palloc(sizeof(BTTapeBlock *) * ntapes);
- btspool->bts_otape =
- (BTTapeBlock **) palloc(sizeof(BTTapeBlock *) * ntapes);
- if (btspool->bts_itape == (BTTapeBlock **) NULL ||
- btspool->bts_otape == (BTTapeBlock **) NULL) {
- elog(WARN, "_bt_spoolinit: out of memory");
- }
-
- for (i = 0; i < ntapes; ++i) {
- btspool->bts_itape[i] =
- _bt_tapecreate(mktemp(strcpy(fname, TAPETEMP)));
- btspool->bts_otape[i] =
- _bt_tapecreate(mktemp(strcpy(fname, TAPETEMP)));
- }
- pfree((void *) fname);
-
- _bt_isortcmpinit(index, btspool);
-
- return((void *) btspool);
+ BTSpool *btspool = (BTSpool *) palloc(sizeof(BTSpool));
+ int i;
+ char *fname = (char *) palloc(sizeof(TAPETEMP) + 1);
+
+ if (btspool == (BTSpool *) NULL || fname == (char *) NULL)
+ {
+ elog(WARN, "_bt_spoolinit: out of memory");
+ }
+ memset((char *) btspool, 0, sizeof(BTSpool));
+ btspool->bts_ntapes = ntapes;
+ btspool->bts_tape = 0;
+ btspool->isunique = isunique;
+
+ btspool->bts_itape =
+ (BTTapeBlock **) palloc(sizeof(BTTapeBlock *) * ntapes);
+ btspool->bts_otape =
+ (BTTapeBlock **) palloc(sizeof(BTTapeBlock *) * ntapes);
+ if (btspool->bts_itape == (BTTapeBlock **) NULL ||
+ btspool->bts_otape == (BTTapeBlock **) NULL)
+ {
+ elog(WARN, "_bt_spoolinit: out of memory");
+ }
+
+ for (i = 0; i < ntapes; ++i)
+ {
+ btspool->bts_itape[i] =
+ _bt_tapecreate(mktemp(strcpy(fname, TAPETEMP)));
+ btspool->bts_otape[i] =
+ _bt_tapecreate(mktemp(strcpy(fname, TAPETEMP)));
+ }
+ pfree((void *) fname);
+
+ _bt_isortcmpinit(index, btspool);
+
+ return ((void *) btspool);
}
/*
@@ -573,29 +600,32 @@ _bt_spoolinit(Relation index, int ntapes, bool isunique)
void
_bt_spooldestroy(void *spool)
{
- BTSpool *btspool = (BTSpool *) spool;
- int i;
-
- for (i = 0; i < btspool->bts_ntapes; ++i) {
- _bt_tapedestroy(btspool->bts_otape[i]);
- _bt_tapedestroy(btspool->bts_itape[i]);
- }
- pfree((void *) btspool);
+ BTSpool *btspool = (BTSpool *) spool;
+ int i;
+
+ for (i = 0; i < btspool->bts_ntapes; ++i)
+ {
+ _bt_tapedestroy(btspool->bts_otape[i]);
+ _bt_tapedestroy(btspool->bts_itape[i]);
+ }
+ pfree((void *) btspool);
}
/*
* flush out any dirty output tape blocks
*/
static void
-_bt_spoolflush(BTSpool *btspool)
+_bt_spoolflush(BTSpool * btspool)
{
- int i;
+ int i;
- for (i = 0; i < btspool->bts_ntapes; ++i) {
- if (!EMPTYTAPE(btspool->bts_otape[i])) {
- _bt_tapewrite(btspool->bts_otape[i], 1);
+ for (i = 0; i < btspool->bts_ntapes; ++i)
+ {
+ if (!EMPTYTAPE(btspool->bts_otape[i]))
+ {
+ _bt_tapewrite(btspool->bts_otape[i], 1);
+ }
}
- }
}
/*
@@ -605,36 +635,37 @@ _bt_spoolflush(BTSpool *btspool)
* output tapes.
*/
static void
-_bt_spoolswap(BTSpool *btspool)
+_bt_spoolswap(BTSpool * btspool)
{
- File tmpfd;
- BTTapeBlock *itape;
- BTTapeBlock *otape;
- int i;
+ File tmpfd;
+ BTTapeBlock *itape;
+ BTTapeBlock *otape;
+ int i;
- for (i = 0; i < btspool->bts_ntapes; ++i) {
- itape = btspool->bts_itape[i];
- otape = btspool->bts_otape[i];
+ for (i = 0; i < btspool->bts_ntapes; ++i)
+ {
+ itape = btspool->bts_itape[i];
+ otape = btspool->bts_otape[i];
- /*
- * swap the input and output VFDs.
- */
- tmpfd = itape->bttb_fd;
- itape->bttb_fd = otape->bttb_fd;
- otape->bttb_fd = tmpfd;
+ /*
+ * swap the input and output VFDs.
+ */
+ tmpfd = itape->bttb_fd;
+ itape->bttb_fd = otape->bttb_fd;
+ otape->bttb_fd = tmpfd;
- /*
- * rewind the new input tape.
- */
- _bt_taperewind(itape);
- _bt_tapereset(itape);
+ /*
+ * rewind the new input tape.
+ */
+ _bt_taperewind(itape);
+ _bt_tapereset(itape);
- /*
- * clear the new output tape -- it's ok to throw away the old
- * inputs.
- */
- _bt_tapeclear(otape);
- }
+ /*
+ * clear the new output tape -- it's ok to throw away the old
+ * inputs.
+ */
+ _bt_tapeclear(otape);
+ }
}
/*-------------------------------------------------------------------------
@@ -643,7 +674,7 @@ _bt_spoolswap(BTSpool *btspool)
*/
/*
- * spool 'btitem' into an initial run. as tape blocks are filled, the
+ * spool 'btitem' into an initial run. as tape blocks are filled, the
* block BTItems are qsorted and written into some output tape (it
* doesn't matter which; we go round-robin for simplicity). the
* initial runs are therefore always just one block.
@@ -651,134 +682,137 @@ _bt_spoolswap(BTSpool *btspool)
void
_bt_spool(Relation index, BTItem btitem, void *spool)
{
- BTSpool *btspool = (BTSpool *) spool;
- BTTapeBlock *itape;
- Size itemsz;
-
- _bt_isortcmpinit (index, btspool);
-
- itape = btspool->bts_itape[btspool->bts_tape];
- itemsz = BTITEMSZ(btitem);
- itemsz = DOUBLEALIGN(itemsz);
-
- /*
- * if this buffer is too full for this BTItemData, or if we have
- * run out of BTItems, we need to sort the buffer and write it
- * out. in this case, the BTItemData will go into the next tape's
- * buffer.
- */
- if (btitem == (BTItem) NULL || SPCLEFT(itape) < itemsz) {
- BTSortKey *parray = (BTSortKey *) NULL;
- BTTapeBlock *otape;
- BTItem bti;
- char *pos;
- int btisz;
- int it_ntup = itape->bttb_ntup;
- int i;
+ BTSpool *btspool = (BTSpool *) spool;
+ BTTapeBlock *itape;
+ Size itemsz;
- /*
- * build an array of pointers to the BTItemDatas on the input
- * block.
- */
- if (it_ntup > 0) {
- parray =
- (BTSortKey *) palloc(it_ntup * sizeof(BTSortKey));
- pos = itape->bttb_data;
- for (i = 0; i < it_ntup; ++i) {
- _bt_setsortkey(index, _bt_tapenext(itape, &pos), &(parray[i]));
- }
-
- /*
- * qsort the pointer array.
- */
- qsort((void *) parray, it_ntup, sizeof(BTSortKey),
- (int (*)(const void *,const void *))_bt_isortcmp);
- }
+ _bt_isortcmpinit(index, btspool);
+
+ itape = btspool->bts_itape[btspool->bts_tape];
+ itemsz = BTITEMSZ(btitem);
+ itemsz = DOUBLEALIGN(itemsz);
/*
- * write the spooled run into the output tape. we copy the
- * BTItemDatas in the order dictated by the sorted array of
- * BTItems, not the original order.
- *
- * (since everything was DOUBLEALIGN'd and is all on a single
- * tape block, everything had *better* still fit on one tape
- * block..)
+ * if this buffer is too full for this BTItemData, or if we have run
+ * out of BTItems, we need to sort the buffer and write it out. in
+ * this case, the BTItemData will go into the next tape's buffer.
*/
- otape = btspool->bts_otape[btspool->bts_tape];
- for (i = 0; i < it_ntup; ++i) {
- bti = parray[i].btsk_item;
- btisz = BTITEMSZ(bti);
- btisz = DOUBLEALIGN(btisz);
- _bt_tapeadd(otape, bti, btisz);
+ if (btitem == (BTItem) NULL || SPCLEFT(itape) < itemsz)
+ {
+ BTSortKey *parray = (BTSortKey *) NULL;
+ BTTapeBlock *otape;
+ BTItem bti;
+ char *pos;
+ int btisz;
+ int it_ntup = itape->bttb_ntup;
+ int i;
+
+ /*
+ * build an array of pointers to the BTItemDatas on the input
+ * block.
+ */
+ if (it_ntup > 0)
+ {
+ parray =
+ (BTSortKey *) palloc(it_ntup * sizeof(BTSortKey));
+ pos = itape->bttb_data;
+ for (i = 0; i < it_ntup; ++i)
+ {
+ _bt_setsortkey(index, _bt_tapenext(itape, &pos), &(parray[i]));
+ }
+
+ /*
+ * qsort the pointer array.
+ */
+ qsort((void *) parray, it_ntup, sizeof(BTSortKey),
+ (int (*) (const void *, const void *)) _bt_isortcmp);
+ }
+
+ /*
+ * write the spooled run into the output tape. we copy the
+ * BTItemDatas in the order dictated by the sorted array of
+ * BTItems, not the original order.
+ *
+ * (since everything was DOUBLEALIGN'd and is all on a single tape
+ * block, everything had *better* still fit on one tape block..)
+ */
+ otape = btspool->bts_otape[btspool->bts_tape];
+ for (i = 0; i < it_ntup; ++i)
+ {
+ bti = parray[i].btsk_item;
+ btisz = BTITEMSZ(bti);
+ btisz = DOUBLEALIGN(btisz);
+ _bt_tapeadd(otape, bti, btisz);
#if defined(FASTBUILD_DEBUG) && defined(FASTBUILD_SPOOL)
- {
- bool isnull;
- Datum d = index_getattr(&(bti->bti_itup), 1, index->rd_att,
- &isnull);
- printf("_bt_spool: inserted <%x> into output tape %d\n",
- d, btspool->bts_tape);
- }
-#endif /* FASTBUILD_DEBUG && FASTBUILD_SPOOL */
- }
+ {
+ bool isnull;
+ Datum d = index_getattr(&(bti->bti_itup), 1, index->rd_att,
+ &isnull);
- /*
- * the initial runs are always single tape blocks. flush the
- * output block, marking End-Of-Run.
- */
- _bt_tapewrite(otape, 1);
+ printf("_bt_spool: inserted <%x> into output tape %d\n",
+ d, btspool->bts_tape);
+ }
+#endif /* FASTBUILD_DEBUG && FASTBUILD_SPOOL */
+ }
- /*
- * reset the input buffer for the next run. we don't have to
- * write it out or anything -- we only use it to hold the
- * unsorted BTItemDatas, the output tape contains all the
- * sorted stuff.
- *
- * changing bts_tape changes the output tape and input tape;
- * we change itape for the code below.
- */
- _bt_tapereset(itape);
- btspool->bts_tape = (btspool->bts_tape + 1) % btspool->bts_ntapes;
- itape = btspool->bts_itape[btspool->bts_tape];
+ /*
+ * the initial runs are always single tape blocks. flush the
+ * output block, marking End-Of-Run.
+ */
+ _bt_tapewrite(otape, 1);
- /*
- * destroy the pointer array.
- */
- if (parray != (BTSortKey *) NULL)
- {
- for (i = 0; i < it_ntup; i++)
- {
- if ( parray[i].btsk_datum != (Datum*) NULL )
- pfree ((void*)(parray[i].btsk_datum));
- if ( parray[i].btsk_nulls != (char*) NULL )
- pfree ((void*)(parray[i].btsk_nulls));
- }
- pfree((void *) parray);
+ /*
+ * reset the input buffer for the next run. we don't have to
+ * write it out or anything -- we only use it to hold the unsorted
+ * BTItemDatas, the output tape contains all the sorted stuff.
+ *
+ * changing bts_tape changes the output tape and input tape; we
+ * change itape for the code below.
+ */
+ _bt_tapereset(itape);
+ btspool->bts_tape = (btspool->bts_tape + 1) % btspool->bts_ntapes;
+ itape = btspool->bts_itape[btspool->bts_tape];
+
+ /*
+ * destroy the pointer array.
+ */
+ if (parray != (BTSortKey *) NULL)
+ {
+ for (i = 0; i < it_ntup; i++)
+ {
+ if (parray[i].btsk_datum != (Datum *) NULL)
+ pfree((void *) (parray[i].btsk_datum));
+ if (parray[i].btsk_nulls != (char *) NULL)
+ pfree((void *) (parray[i].btsk_nulls));
+ }
+ pfree((void *) parray);
+ }
}
- }
- /* insert this item into the current buffer */
- if (btitem != (BTItem) NULL) {
- _bt_tapeadd(itape, btitem, itemsz);
- }
+ /* insert this item into the current buffer */
+ if (btitem != (BTItem) NULL)
+ {
+ _bt_tapeadd(itape, btitem, itemsz);
+ }
}
/*
* allocate a new, clean btree page, not linked to any siblings.
*/
static void
-_bt_blnewpage(Relation index, Buffer *buf, Page *page, int flags)
+_bt_blnewpage(Relation index, Buffer * buf, Page * page, int flags)
{
- BTPageOpaque opaque;
+ BTPageOpaque opaque;
- *buf = _bt_getbuf(index, P_NEW, BT_WRITE);
+ *buf = _bt_getbuf(index, P_NEW, BT_WRITE);
#if 0
- printf("\tblk=%d\n", BufferGetBlockNumber(*buf));
+ printf("\tblk=%d\n", BufferGetBlockNumber(*buf));
#endif
- *page = BufferGetPage(*buf);
- _bt_pageinit(*page, BufferGetPageSize(*buf));
- opaque = (BTPageOpaque) PageGetSpecialPointer(*page);
- opaque->btpo_prev = opaque->btpo_next = P_NONE;
- opaque->btpo_flags = flags;
+ *page = BufferGetPage(*buf);
+ _bt_pageinit(*page, BufferGetPageSize(*buf));
+ opaque = (BTPageOpaque) PageGetSpecialPointer(*page);
+ opaque->btpo_prev = opaque->btpo_next = P_NONE;
+ opaque->btpo_flags = flags;
}
/*
@@ -790,42 +824,44 @@ _bt_blnewpage(Relation index, Buffer *buf, Page *page, int flags)
static void
_bt_slideleft(Relation index, Buffer buf, Page page)
{
- OffsetNumber off;
- OffsetNumber maxoff;
- ItemId previi;
- ItemId thisii;
-
- if (!PageIsEmpty(page)) {
- maxoff = PageGetMaxOffsetNumber(page);
- previi = PageGetItemId(page, P_HIKEY);
- for (off = P_FIRSTKEY; off <= maxoff; off = OffsetNumberNext(off)) {
- thisii = PageGetItemId(page, off);
- *previi = *thisii;
- previi = thisii;
+ OffsetNumber off;
+ OffsetNumber maxoff;
+ ItemId previi;
+ ItemId thisii;
+
+ if (!PageIsEmpty(page))
+ {
+ maxoff = PageGetMaxOffsetNumber(page);
+ previi = PageGetItemId(page, P_HIKEY);
+ for (off = P_FIRSTKEY; off <= maxoff; off = OffsetNumberNext(off))
+ {
+ thisii = PageGetItemId(page, off);
+ *previi = *thisii;
+ previi = thisii;
+ }
+ ((PageHeader) page)->pd_lower -= sizeof(ItemIdData);
}
- ((PageHeader) page)->pd_lower -= sizeof(ItemIdData);
- }
}
/*
* allocate and initialize a new BTPageState. the returned structure
* is suitable for immediate use by _bt_buildadd.
*/
-static void *
+static void *
_bt_pagestate(Relation index, int flags, int level, bool doupper)
{
- BTPageState *state = (BTPageState *) palloc(sizeof(BTPageState));
-
- memset((char *) state, 0, sizeof(BTPageState));
- _bt_blnewpage(index, &(state->btps_buf), &(state->btps_page), flags);
- state->btps_firstoff = InvalidOffsetNumber;
- state->btps_lastoff = P_HIKEY;
- state->btps_lastbti = (BTItem) NULL;
- state->btps_next = (BTPageState *) NULL;
- state->btps_level = level;
- state->btps_doupper = doupper;
-
- return((void *) state);
+ BTPageState *state = (BTPageState *) palloc(sizeof(BTPageState));
+
+ memset((char *) state, 0, sizeof(BTPageState));
+ _bt_blnewpage(index, &(state->btps_buf), &(state->btps_page), flags);
+ state->btps_firstoff = InvalidOffsetNumber;
+ state->btps_lastoff = P_HIKEY;
+ state->btps_lastbti = (BTItem) NULL;
+ state->btps_next = (BTPageState *) NULL;
+ state->btps_level = level;
+ state->btps_doupper = doupper;
+
+ return ((void *) state);
}
/*
@@ -834,19 +870,19 @@ _bt_pagestate(Relation index, int flags, int level, bool doupper)
* the page to which the item used to point, e.g., a heap page if
* 'opage' is a leaf page).
*/
-static BTItem
+static BTItem
_bt_minitem(Page opage, BlockNumber oblkno, int atend)
{
- OffsetNumber off;
- BTItem obti;
- BTItem nbti;
+ OffsetNumber off;
+ BTItem obti;
+ BTItem nbti;
- off = atend ? P_HIKEY : P_FIRSTKEY;
- obti = (BTItem) PageGetItem(opage, PageGetItemId(opage, off));
- nbti = _bt_formitem(&(obti->bti_itup));
- ItemPointerSet(&(nbti->bti_itup.t_tid), oblkno, P_HIKEY);
+ off = atend ? P_HIKEY : P_FIRSTKEY;
+ obti = (BTItem) PageGetItem(opage, PageGetItemId(opage, off));
+ nbti = _bt_formitem(&(obti->bti_itup));
+ ItemPointerSet(&(nbti->bti_itup.t_tid), oblkno, P_HIKEY);
- return(nbti);
+ return (nbti);
}
/*
@@ -855,26 +891,26 @@ _bt_minitem(Page opage, BlockNumber oblkno, int atend)
* we must be careful to observe the following restrictions, placed
* upon us by the conventions in nbtsearch.c:
* - rightmost pages start data items at P_HIKEY instead of at
- * P_FIRSTKEY.
+ * P_FIRSTKEY.
* - duplicates cannot be split among pages unless the chain of
- * duplicates starts at the first data item.
+ * duplicates starts at the first data item.
*
* a leaf page being built looks like:
*
* +----------------+---------------------------------+
- * | PageHeaderData | linp0 linp1 linp2 ... |
+ * | PageHeaderData | linp0 linp1 linp2 ... |
* +-----------+----+---------------------------------+
- * | ... linpN | ^ first |
+ * | ... linpN | ^ first |
* +-----------+--------------------------------------+
- * | ^ last |
- * | |
- * | v last |
+ * | ^ last |
+ * | |
+ * | v last |
* +-------------+------------------------------------+
- * | | itemN ... |
+ * | | itemN ... |
* +-------------+------------------+-----------------+
- * | ... item3 item2 item1 | "special space" |
+ * | ... item3 item2 item1 | "special space" |
* +--------------------------------+-----------------+
- * ^ first
+ * ^ first
*
* contrast this with the diagram in bufpage.h; note the mismatch
* between linps and items. this is because we reserve linp0 as a
@@ -888,216 +924,230 @@ _bt_minitem(Page opage, BlockNumber oblkno, int atend)
*
* if all keys are unique, 'first' will always be the same as 'last'.
*/
-static BTItem
+static BTItem
_bt_buildadd(Relation index, void *pstate, BTItem bti, int flags)
{
- BTPageState *state = (BTPageState *) pstate;
- Buffer nbuf;
- Page npage;
- BTItem last_bti;
- OffsetNumber first_off;
- OffsetNumber last_off;
- OffsetNumber off;
- Size pgspc;
- Size btisz;
-
- nbuf = state->btps_buf;
- npage = state->btps_page;
- first_off = state->btps_firstoff;
- last_off = state->btps_lastoff;
- last_bti = state->btps_lastbti;
-
- pgspc = PageGetFreeSpace(npage);
- btisz = BTITEMSZ(bti);
- btisz = DOUBLEALIGN(btisz);
- if (pgspc < btisz) {
- Buffer obuf = nbuf;
- Page opage = npage;
- OffsetNumber o, n;
- ItemId ii;
- ItemId hii;
-
- _bt_blnewpage(index, &nbuf, &npage, flags);
+ BTPageState *state = (BTPageState *) pstate;
+ Buffer nbuf;
+ Page npage;
+ BTItem last_bti;
+ OffsetNumber first_off;
+ OffsetNumber last_off;
+ OffsetNumber off;
+ Size pgspc;
+ Size btisz;
+
+ nbuf = state->btps_buf;
+ npage = state->btps_page;
+ first_off = state->btps_firstoff;
+ last_off = state->btps_lastoff;
+ last_bti = state->btps_lastbti;
+
+ pgspc = PageGetFreeSpace(npage);
+ btisz = BTITEMSZ(bti);
+ btisz = DOUBLEALIGN(btisz);
+ if (pgspc < btisz)
+ {
+ Buffer obuf = nbuf;
+ Page opage = npage;
+ OffsetNumber o,
+ n;
+ ItemId ii;
+ ItemId hii;
- /*
- * if 'last' is part of a chain of duplicates that does not
- * start at the beginning of the old page, the entire chain is
- * copied to the new page; we delete all of the duplicates
- * from the old page except the first, which becomes the high
- * key item of the old page.
- *
- * if the chain starts at the beginning of the page or there
- * is no chain ('first' == 'last'), we need only copy 'last'
- * to the new page. again, 'first' (== 'last') becomes the
- * high key of the old page.
- *
- * note that in either case, we copy at least one item to the
- * new page, so 'last_bti' will always be valid. 'bti' will
- * never be the first data item on the new page.
- */
- if (first_off == P_FIRSTKEY) {
- Assert(last_off != P_FIRSTKEY);
- first_off = last_off;
- }
- for (o = first_off, n = P_FIRSTKEY;
- o <= last_off;
- o = OffsetNumberNext(o), n = OffsetNumberNext(n)) {
- ii = PageGetItemId(opage, o);
- if ( PageAddItem(npage, PageGetItem(opage, ii),
- ii->lp_len, n, LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add item to the page in _bt_sort (1)");
+ _bt_blnewpage(index, &nbuf, &npage, flags);
+
+ /*
+ * if 'last' is part of a chain of duplicates that does not start
+ * at the beginning of the old page, the entire chain is copied to
+ * the new page; we delete all of the duplicates from the old page
+ * except the first, which becomes the high key item of the old
+ * page.
+ *
+ * if the chain starts at the beginning of the page or there is no
+ * chain ('first' == 'last'), we need only copy 'last' to the new
+ * page. again, 'first' (== 'last') becomes the high key of the
+ * old page.
+ *
+ * note that in either case, we copy at least one item to the new
+ * page, so 'last_bti' will always be valid. 'bti' will never be
+ * the first data item on the new page.
+ */
+ if (first_off == P_FIRSTKEY)
+ {
+ Assert(last_off != P_FIRSTKEY);
+ first_off = last_off;
+ }
+ for (o = first_off, n = P_FIRSTKEY;
+ o <= last_off;
+ o = OffsetNumberNext(o), n = OffsetNumberNext(n))
+ {
+ ii = PageGetItemId(opage, o);
+ if (PageAddItem(npage, PageGetItem(opage, ii),
+ ii->lp_len, n, LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add item to the page in _bt_sort (1)");
#if 0
#if defined(FASTBUILD_DEBUG) && defined(FASTBUILD_MERGE)
- {
- bool isnull;
- BTItem tmpbti =
- (BTItem) PageGetItem(npage, PageGetItemId(npage, n));
- Datum d = index_getattr(&(tmpbti->bti_itup), 1,
- index->rd_att, &isnull);
- printf("_bt_buildadd: moved <%x> to offset %d at level %d\n",
- d, n, state->btps_level);
- }
-#endif /* FASTBUILD_DEBUG && FASTBUILD_MERGE */
+ {
+ bool isnull;
+ BTItem tmpbti =
+ (BTItem) PageGetItem(npage, PageGetItemId(npage, n));
+ Datum d = index_getattr(&(tmpbti->bti_itup), 1,
+ index->rd_att, &isnull);
+
+ printf("_bt_buildadd: moved <%x> to offset %d at level %d\n",
+ d, n, state->btps_level);
+ }
+#endif /* FASTBUILD_DEBUG && FASTBUILD_MERGE */
#endif
- }
- /*
- * this loop is backward because PageIndexTupleDelete shuffles
- * the tuples to fill holes in the page -- by starting at the
- * end and working back, we won't create holes (and thereby
- * avoid shuffling).
- */
- for (o = last_off; o > first_off; o = OffsetNumberPrev(o)) {
- PageIndexTupleDelete(opage, o);
- }
- hii = PageGetItemId(opage, P_HIKEY);
- ii = PageGetItemId(opage, first_off);
- *hii = *ii;
- ii->lp_flags &= ~LP_USED;
- ((PageHeader) opage)->pd_lower -= sizeof(ItemIdData);
+ }
- first_off = P_FIRSTKEY;
- last_off = PageGetMaxOffsetNumber(npage);
- last_bti = (BTItem) PageGetItem(npage, PageGetItemId(npage, last_off));
+ /*
+ * this loop is backward because PageIndexTupleDelete shuffles the
+ * tuples to fill holes in the page -- by starting at the end and
+ * working back, we won't create holes (and thereby avoid
+ * shuffling).
+ */
+ for (o = last_off; o > first_off; o = OffsetNumberPrev(o))
+ {
+ PageIndexTupleDelete(opage, o);
+ }
+ hii = PageGetItemId(opage, P_HIKEY);
+ ii = PageGetItemId(opage, first_off);
+ *hii = *ii;
+ ii->lp_flags &= ~LP_USED;
+ ((PageHeader) opage)->pd_lower -= sizeof(ItemIdData);
- /*
- * set the page (side link) pointers.
- */
- {
- BTPageOpaque oopaque = (BTPageOpaque) PageGetSpecialPointer(opage);
- BTPageOpaque nopaque = (BTPageOpaque) PageGetSpecialPointer(npage);
-
- oopaque->btpo_next = BufferGetBlockNumber(nbuf);
- nopaque->btpo_prev = BufferGetBlockNumber(obuf);
- nopaque->btpo_next = P_NONE;
-
- if ( _bt_itemcmp(index, _bt_nattr,
- (BTItem) PageGetItem(opage, PageGetItemId(opage, P_HIKEY)),
- (BTItem) PageGetItem(opage, PageGetItemId(opage, P_FIRSTKEY)),
- BTEqualStrategyNumber) )
- oopaque->btpo_flags |= BTP_CHAIN;
- }
+ first_off = P_FIRSTKEY;
+ last_off = PageGetMaxOffsetNumber(npage);
+ last_bti = (BTItem) PageGetItem(npage, PageGetItemId(npage, last_off));
- /*
- * copy the old buffer's minimum key to its parent. if we
- * don't have a parent, we have to create one; this adds a new
- * btree level.
- */
- if (state->btps_doupper) {
- BTItem nbti;
-
- if (state->btps_next == (BTPageState *) NULL) {
- state->btps_next =
- _bt_pagestate(index, 0, state->btps_level + 1, true);
- }
- nbti = _bt_minitem(opage, BufferGetBlockNumber(obuf), 0);
- _bt_buildadd(index, state->btps_next, nbti, 0);
- pfree((void *) nbti);
+ /*
+ * set the page (side link) pointers.
+ */
+ {
+ BTPageOpaque oopaque = (BTPageOpaque) PageGetSpecialPointer(opage);
+ BTPageOpaque nopaque = (BTPageOpaque) PageGetSpecialPointer(npage);
+
+ oopaque->btpo_next = BufferGetBlockNumber(nbuf);
+ nopaque->btpo_prev = BufferGetBlockNumber(obuf);
+ nopaque->btpo_next = P_NONE;
+
+ if (_bt_itemcmp(index, _bt_nattr,
+ (BTItem) PageGetItem(opage, PageGetItemId(opage, P_HIKEY)),
+ (BTItem) PageGetItem(opage, PageGetItemId(opage, P_FIRSTKEY)),
+ BTEqualStrategyNumber))
+ oopaque->btpo_flags |= BTP_CHAIN;
+ }
+
+ /*
+ * copy the old buffer's minimum key to its parent. if we don't
+ * have a parent, we have to create one; this adds a new btree
+ * level.
+ */
+ if (state->btps_doupper)
+ {
+ BTItem nbti;
+
+ if (state->btps_next == (BTPageState *) NULL)
+ {
+ state->btps_next =
+ _bt_pagestate(index, 0, state->btps_level + 1, true);
+ }
+ nbti = _bt_minitem(opage, BufferGetBlockNumber(obuf), 0);
+ _bt_buildadd(index, state->btps_next, nbti, 0);
+ pfree((void *) nbti);
+ }
+
+ /*
+ * write out the old stuff. we never want to see it again, so we
+ * can give up our lock (if we had one; BuildingBtree is set, so
+ * we aren't locking).
+ */
+ _bt_wrtbuf(index, obuf);
}
/*
- * write out the old stuff. we never want to see it again, so
- * we can give up our lock (if we had one; BuildingBtree is
- * set, so we aren't locking).
+ * if this item is different from the last item added, we start a new
+ * chain of duplicates.
*/
- _bt_wrtbuf(index, obuf);
- }
-
- /*
- * if this item is different from the last item added, we start a
- * new chain of duplicates.
- */
- off = OffsetNumberNext(last_off);
- if ( PageAddItem(npage, (Item) bti, btisz, off, LP_USED) == InvalidOffsetNumber )
- elog (FATAL, "btree: failed to add item to the page in _bt_sort (2)");
+ off = OffsetNumberNext(last_off);
+ if (PageAddItem(npage, (Item) bti, btisz, off, LP_USED) == InvalidOffsetNumber)
+ elog(FATAL, "btree: failed to add item to the page in _bt_sort (2)");
#if 0
#if defined(FASTBUILD_DEBUG) && defined(FASTBUILD_MERGE)
- {
- bool isnull;
- Datum d = index_getattr(&(bti->bti_itup), 1, index->rd_att, &isnull);
- printf("_bt_buildadd: inserted <%x> at offset %d at level %d\n",
- d, off, state->btps_level);
- }
-#endif /* FASTBUILD_DEBUG && FASTBUILD_MERGE */
+ {
+ bool isnull;
+ Datum d = index_getattr(&(bti->bti_itup), 1, index->rd_att, &isnull);
+
+ printf("_bt_buildadd: inserted <%x> at offset %d at level %d\n",
+ d, off, state->btps_level);
+ }
+#endif /* FASTBUILD_DEBUG && FASTBUILD_MERGE */
#endif
- if (last_bti == (BTItem) NULL)
- {
- first_off = P_FIRSTKEY;
- }
- else if ( !_bt_itemcmp(index, _bt_nattr,
- bti, last_bti, BTEqualStrategyNumber) )
- {
- first_off = off;
- }
- last_off = off;
- last_bti = (BTItem) PageGetItem(npage, PageGetItemId(npage, off));
-
- state->btps_buf = nbuf;
- state->btps_page = npage;
- state->btps_lastbti = last_bti;
- state->btps_lastoff = last_off;
- state->btps_firstoff = first_off;
-
- return(last_bti);
+ if (last_bti == (BTItem) NULL)
+ {
+ first_off = P_FIRSTKEY;
+ }
+ else if (!_bt_itemcmp(index, _bt_nattr,
+ bti, last_bti, BTEqualStrategyNumber))
+ {
+ first_off = off;
+ }
+ last_off = off;
+ last_bti = (BTItem) PageGetItem(npage, PageGetItemId(npage, off));
+
+ state->btps_buf = nbuf;
+ state->btps_page = npage;
+ state->btps_lastbti = last_bti;
+ state->btps_lastoff = last_off;
+ state->btps_firstoff = first_off;
+
+ return (last_bti);
}
static void
-_bt_uppershutdown(Relation index, BTPageState *state)
+_bt_uppershutdown(Relation index, BTPageState * state)
{
- BTPageState *s;
- BlockNumber blkno;
- BTPageOpaque opaque;
- BTItem bti;
+ BTPageState *s;
+ BlockNumber blkno;
+ BTPageOpaque opaque;
+ BTItem bti;
- for (s = state; s != (BTPageState *) NULL; s = s->btps_next) {
- blkno = BufferGetBlockNumber(s->btps_buf);
- opaque = (BTPageOpaque) PageGetSpecialPointer(s->btps_page);
+ for (s = state; s != (BTPageState *) NULL; s = s->btps_next)
+ {
+ blkno = BufferGetBlockNumber(s->btps_buf);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(s->btps_page);
- /*
- * if this is the root, attach it to the metapage. otherwise,
- * stick the minimum key of the last page on this level (which
- * has not been split, or else it wouldn't be the last page)
- * into its parent. this may cause the last page of upper
- * levels to split, but that's not a problem -- we haven't
- * gotten to them yet.
- */
- if (s->btps_doupper) {
- if (s->btps_next == (BTPageState *) NULL) {
- opaque->btpo_flags |= BTP_ROOT;
- _bt_metaproot(index, blkno, s->btps_level + 1);
- } else {
- bti = _bt_minitem(s->btps_page, blkno, 0);
- _bt_buildadd(index, s->btps_next, bti, 0);
- pfree((void *) bti);
- }
- }
+ /*
+ * if this is the root, attach it to the metapage. otherwise,
+ * stick the minimum key of the last page on this level (which has
+ * not been split, or else it wouldn't be the last page) into its
+ * parent. this may cause the last page of upper levels to split,
+ * but that's not a problem -- we haven't gotten to them yet.
+ */
+ if (s->btps_doupper)
+ {
+ if (s->btps_next == (BTPageState *) NULL)
+ {
+ opaque->btpo_flags |= BTP_ROOT;
+ _bt_metaproot(index, blkno, s->btps_level + 1);
+ }
+ else
+ {
+ bti = _bt_minitem(s->btps_page, blkno, 0);
+ _bt_buildadd(index, s->btps_next, bti, 0);
+ pfree((void *) bti);
+ }
+ }
- /*
- * this is the rightmost page, so the ItemId array needs to be
- * slid back one slot.
- */
- _bt_slideleft(index, s->btps_buf, s->btps_page);
- _bt_wrtbuf(index, s->btps_buf);
- }
+ /*
+ * this is the rightmost page, so the ItemId array needs to be
+ * slid back one slot.
+ */
+ _bt_slideleft(index, s->btps_buf, s->btps_page);
+ _bt_wrtbuf(index, s->btps_buf);
+ }
}
/*
@@ -1105,203 +1155,230 @@ _bt_uppershutdown(Relation index, BTPageState *state)
* merging passes until at most one run is left in each tape. at that
* point, merge the final tape runs into a set of btree leaves.
*
- * XXX three nested loops? gross. cut me up into smaller routines.
+ * XXX three nested loops? gross. cut me up into smaller routines.
*/
static void
-_bt_merge(Relation index, BTSpool *btspool)
+_bt_merge(Relation index, BTSpool * btspool)
{
- BTPageState *state;
- BTPriQueue q;
- BTPriQueueElem e;
- BTSortKey btsk;
- BTItem bti;
- BTTapeBlock *itape;
- BTTapeBlock *otape;
- char *tapepos[MAXTAPES];
- int tapedone[MAXTAPES];
- int t;
- int goodtapes;
- int npass;
- int nruns;
- Size btisz;
- bool doleaf = false;
-
- /*
- * initialize state needed for the merge into the btree leaf pages.
- */
- state = (BTPageState *) _bt_pagestate(index, BTP_LEAF, 0, true);
-
- npass = 0;
- do { /* pass */
+ BTPageState *state;
+ BTPriQueue q;
+ BTPriQueueElem e;
+ BTSortKey btsk;
+ BTItem bti;
+ BTTapeBlock *itape;
+ BTTapeBlock *otape;
+ char *tapepos[MAXTAPES];
+ int tapedone[MAXTAPES];
+ int t;
+ int goodtapes;
+ int npass;
+ int nruns;
+ Size btisz;
+ bool doleaf = false;
+
/*
- * each pass starts by flushing the previous outputs and
- * swapping inputs and outputs. flushing sets End-of-Run for
- * any dirty output tapes. swapping clears the new output
- * tapes and rewinds the new input tapes.
+ * initialize state needed for the merge into the btree leaf pages.
*/
- btspool->bts_tape = btspool->bts_ntapes - 1;
- _bt_spoolflush(btspool);
- _bt_spoolswap(btspool);
-
- ++npass;
- nruns = 0;
-
- for (;;) { /* run */
- /*
- * each run starts by selecting a new output tape. the
- * merged results of a given run are always sent to this
- * one tape.
- */
- btspool->bts_tape = (btspool->bts_tape + 1) % btspool->bts_ntapes;
- otape = btspool->bts_otape[btspool->bts_tape];
-
- /*
- * initialize the priority queue by loading it with the
- * first element of the given run in each tape. since we
- * are starting a new run, we reset the tape (clearing the
- * End-Of-Run marker) before reading it. this means that
- * _bt_taperead will return 0 only if the tape is actually
- * at EOF.
- */
- memset((char *) &q, 0, sizeof(BTPriQueue));
- goodtapes = 0;
- for (t = 0; t < btspool->bts_ntapes; ++t) {
- itape = btspool->bts_itape[t];
- tapepos[t] = itape->bttb_data;
- tapedone[t] = 0;
- _bt_tapereset(itape);
- do {
- if (_bt_taperead(itape) == 0) {
- tapedone[t] = 1;
- }
- } while (!tapedone[t] && EMPTYTAPE(itape));
- if (!tapedone[t]) {
- ++goodtapes;
- e.btpqe_tape = t;
- _bt_setsortkey(index, _bt_tapenext(itape, &tapepos[t]),
- &(e.btpqe_item));
- if (e.btpqe_item.btsk_item != (BTItem) NULL) {
- _bt_pqadd(&q, &e);
- }
- }
- }
- /*
- * if we don't have any tapes with any input (i.e., they
- * are all at EOF), there is no work to do in this run --
- * we must be done with this pass.
- */
- if (goodtapes == 0) {
- break; /* for */
- }
- ++nruns;
-
- /*
- * output the smallest element from the queue until there
- * are no more.
- */
- while (_bt_pqnext(&q, &e) >= 0) { /* item */
+ state = (BTPageState *) _bt_pagestate(index, BTP_LEAF, 0, true);
+
+ npass = 0;
+ do
+ { /* pass */
+
/*
- * replace the element taken from priority queue,
- * fetching a new block if needed. a tape can run out
- * if it hits either End-Of-Run or EOF.
+ * each pass starts by flushing the previous outputs and swapping
+ * inputs and outputs. flushing sets End-of-Run for any dirty
+ * output tapes. swapping clears the new output tapes and rewinds
+ * the new input tapes.
*/
- t = e.btpqe_tape;
- btsk = e.btpqe_item;
- bti = btsk.btsk_item;
- if (bti != (BTItem) NULL) {
- btisz = BTITEMSZ(bti);
- btisz = DOUBLEALIGN(btisz);
- if (doleaf) {
- _bt_buildadd(index, state, bti, BTP_LEAF);
-#if defined(FASTBUILD_DEBUG) && defined(FASTBUILD_MERGE)
+ btspool->bts_tape = btspool->bts_ntapes - 1;
+ _bt_spoolflush(btspool);
+ _bt_spoolswap(btspool);
+
+ ++npass;
+ nruns = 0;
+
+ for (;;)
+ { /* run */
+
+ /*
+ * each run starts by selecting a new output tape. the merged
+ * results of a given run are always sent to this one tape.
+ */
+ btspool->bts_tape = (btspool->bts_tape + 1) % btspool->bts_ntapes;
+ otape = btspool->bts_otape[btspool->bts_tape];
+
+ /*
+ * initialize the priority queue by loading it with the first
+ * element of the given run in each tape. since we are
+ * starting a new run, we reset the tape (clearing the
+ * End-Of-Run marker) before reading it. this means that
+ * _bt_taperead will return 0 only if the tape is actually at
+ * EOF.
+ */
+ memset((char *) &q, 0, sizeof(BTPriQueue));
+ goodtapes = 0;
+ for (t = 0; t < btspool->bts_ntapes; ++t)
{
- bool isnull;
- Datum d = index_getattr(&(bti->bti_itup), 1,
- index->rd_att, &isnull);
- printf("_bt_merge: [pass %d run %d] inserted <%x> from tape %d into block %d\n",
- npass, nruns, d, t,
- BufferGetBlockNumber(state->btps_buf));
+ itape = btspool->bts_itape[t];
+ tapepos[t] = itape->bttb_data;
+ tapedone[t] = 0;
+ _bt_tapereset(itape);
+ do
+ {
+ if (_bt_taperead(itape) == 0)
+ {
+ tapedone[t] = 1;
+ }
+ } while (!tapedone[t] && EMPTYTAPE(itape));
+ if (!tapedone[t])
+ {
+ ++goodtapes;
+ e.btpqe_tape = t;
+ _bt_setsortkey(index, _bt_tapenext(itape, &tapepos[t]),
+ &(e.btpqe_item));
+ if (e.btpqe_item.btsk_item != (BTItem) NULL)
+ {
+ _bt_pqadd(&q, &e);
+ }
+ }
}
-#endif /* FASTBUILD_DEBUG && FASTBUILD_MERGE */
- } else {
- if (SPCLEFT(otape) < btisz) {
- /*
- * if it's full, write it out and add the
- * item to the next block. (since we will
- * be adding another tuple immediately
- * after this, we can be sure that there
- * will be at least one more block in this
- * run and so we know we do *not* want to
- * set End-Of-Run here.)
- */
- _bt_tapewrite(otape, 0);
- }
- _bt_tapeadd(otape, bti, btisz);
-#if defined(FASTBUILD_DEBUG) && defined(FASTBUILD_MERGE)
+
+ /*
+ * if we don't have any tapes with any input (i.e., they are
+ * all at EOF), there is no work to do in this run -- we must
+ * be done with this pass.
+ */
+ if (goodtapes == 0)
{
- bool isnull;
- Datum d = index_getattr(&(bti->bti_itup), 1,
- index->rd_att, &isnull);
- printf("_bt_merge: [pass %d run %d] inserted <%x> from tape %d into output tape %d\n",
- npass, nruns, d, t,
- btspool->bts_tape);
- }
-#endif /* FASTBUILD_DEBUG && FASTBUILD_MERGE */
- }
-
- if ( btsk.btsk_datum != (Datum*) NULL )
- pfree ((void*)(btsk.btsk_datum));
- if ( btsk.btsk_nulls != (char*) NULL )
- pfree ((void*)(btsk.btsk_nulls));
-
- }
- itape = btspool->bts_itape[t];
- if (!tapedone[t]) {
- BTItem newbti = _bt_tapenext(itape, &tapepos[t]);
-
- if (newbti == (BTItem) NULL) {
- do {
- if (_bt_taperead(itape) == 0) {
- tapedone[t] = 1;
- }
- } while (!tapedone[t] && EMPTYTAPE(itape));
- if (!tapedone[t]) {
- tapepos[t] = itape->bttb_data;
- newbti = _bt_tapenext(itape, &tapepos[t]);
+ break; /* for */
}
- }
- if (newbti != (BTItem) NULL) {
- BTPriQueueElem nexte;
-
- nexte.btpqe_tape = t;
- _bt_setsortkey(index, newbti, &(nexte.btpqe_item));
- _bt_pqadd(&q, &nexte);
- }
+ ++nruns;
+
+ /*
+ * output the smallest element from the queue until there are
+ * no more.
+ */
+ while (_bt_pqnext(&q, &e) >= 0)
+ { /* item */
+
+ /*
+ * replace the element taken from priority queue, fetching
+ * a new block if needed. a tape can run out if it hits
+ * either End-Of-Run or EOF.
+ */
+ t = e.btpqe_tape;
+ btsk = e.btpqe_item;
+ bti = btsk.btsk_item;
+ if (bti != (BTItem) NULL)
+ {
+ btisz = BTITEMSZ(bti);
+ btisz = DOUBLEALIGN(btisz);
+ if (doleaf)
+ {
+ _bt_buildadd(index, state, bti, BTP_LEAF);
+#if defined(FASTBUILD_DEBUG) && defined(FASTBUILD_MERGE)
+ {
+ bool isnull;
+ Datum d = index_getattr(&(bti->bti_itup), 1,
+ index->rd_att, &isnull);
+
+ printf("_bt_merge: [pass %d run %d] inserted <%x> from tape %d into block %d\n",
+ npass, nruns, d, t,
+ BufferGetBlockNumber(state->btps_buf));
+ }
+#endif /* FASTBUILD_DEBUG && FASTBUILD_MERGE */
+ }
+ else
+ {
+ if (SPCLEFT(otape) < btisz)
+ {
+
+ /*
+ * if it's full, write it out and add the item
+ * to the next block. (since we will be
+ * adding another tuple immediately after
+ * this, we can be sure that there will be at
+ * least one more block in this run and so we
+ * know we do *not* want to set End-Of-Run
+ * here.)
+ */
+ _bt_tapewrite(otape, 0);
+ }
+ _bt_tapeadd(otape, bti, btisz);
+#if defined(FASTBUILD_DEBUG) && defined(FASTBUILD_MERGE)
+ {
+ bool isnull;
+ Datum d = index_getattr(&(bti->bti_itup), 1,
+ index->rd_att, &isnull);
+
+ printf("_bt_merge: [pass %d run %d] inserted <%x> from tape %d into output tape %d\n",
+ npass, nruns, d, t,
+ btspool->bts_tape);
+ }
+#endif /* FASTBUILD_DEBUG && FASTBUILD_MERGE */
+ }
+
+ if (btsk.btsk_datum != (Datum *) NULL)
+ pfree((void *) (btsk.btsk_datum));
+ if (btsk.btsk_nulls != (char *) NULL)
+ pfree((void *) (btsk.btsk_nulls));
+
+ }
+ itape = btspool->bts_itape[t];
+ if (!tapedone[t])
+ {
+ BTItem newbti = _bt_tapenext(itape, &tapepos[t]);
+
+ if (newbti == (BTItem) NULL)
+ {
+ do
+ {
+ if (_bt_taperead(itape) == 0)
+ {
+ tapedone[t] = 1;
+ }
+ } while (!tapedone[t] && EMPTYTAPE(itape));
+ if (!tapedone[t])
+ {
+ tapepos[t] = itape->bttb_data;
+ newbti = _bt_tapenext(itape, &tapepos[t]);
+ }
+ }
+ if (newbti != (BTItem) NULL)
+ {
+ BTPriQueueElem nexte;
+
+ nexte.btpqe_tape = t;
+ _bt_setsortkey(index, newbti, &(nexte.btpqe_item));
+ _bt_pqadd(&q, &nexte);
+ }
+ }
+ } /* item */
+
+ /*
+ * that's it for this run. flush the output tape, marking
+ * End-of-Run.
+ */
+ _bt_tapewrite(otape, 1);
+ } /* run */
+
+ /*
+ * we are here because we ran out of input on all of the input
+ * tapes.
+ *
+ * if this pass did not generate more actual output runs than we have
+ * tapes, we know we have at most one run in each tape. this
+ * means that we are ready to merge into the final btree leaf
+ * pages instead of merging into a tape file.
+ */
+ if (nruns <= btspool->bts_ntapes)
+ {
+ doleaf = true;
}
- } /* item */
-
- /*
- * that's it for this run. flush the output tape, marking
- * End-of-Run.
- */
- _bt_tapewrite(otape, 1);
- } /* run */
-
- /*
- * we are here because we ran out of input on all of the input
- * tapes.
- *
- * if this pass did not generate more actual output runs than
- * we have tapes, we know we have at most one run in each
- * tape. this means that we are ready to merge into the final
- * btree leaf pages instead of merging into a tape file.
- */
- if (nruns <= btspool->bts_ntapes) {
- doleaf = true;
- }
- } while (nruns > 0); /* pass */
+ } while (nruns > 0); /* pass */
- _bt_uppershutdown(index, state);
+ _bt_uppershutdown(index, state);
}
@@ -1320,62 +1397,65 @@ _bt_merge(Relation index, BTSpool *btspool)
void
_bt_upperbuild(Relation index)
{
- Buffer rbuf;
- BlockNumber blk;
- Page rpage;
- BTPageOpaque ropaque;
- BTPageState *state;
- BTItem nbti;
-
- /*
- * find the first leaf block. while we're at it, clear the
- * BTP_ROOT flag that we set while building it (so we could find
- * it later).
- */
- rbuf = _bt_getroot(index, BT_WRITE);
- blk = BufferGetBlockNumber(rbuf);
- rpage = BufferGetPage(rbuf);
- ropaque = (BTPageOpaque) PageGetSpecialPointer(rpage);
- ropaque->btpo_flags &= ~BTP_ROOT;
- _bt_wrtbuf(index, rbuf);
-
- state = (BTPageState *) _bt_pagestate(index, 0, 0, true);
-
- /* for each page... */
- do {
-#if 0
- printf("\t\tblk=%d\n", blk);
-#endif
- rbuf = _bt_getbuf(index, blk, BT_READ);
+ Buffer rbuf;
+ BlockNumber blk;
+ Page rpage;
+ BTPageOpaque ropaque;
+ BTPageState *state;
+ BTItem nbti;
+
+ /*
+ * find the first leaf block. while we're at it, clear the BTP_ROOT
+ * flag that we set while building it (so we could find it later).
+ */
+ rbuf = _bt_getroot(index, BT_WRITE);
+ blk = BufferGetBlockNumber(rbuf);
rpage = BufferGetPage(rbuf);
ropaque = (BTPageOpaque) PageGetSpecialPointer(rpage);
-
- /* for each item... */
- if (!PageIsEmpty(rpage)) {
- /*
- * form a new index tuple corresponding to the minimum key
- * of the lower page and insert it into a page at this
- * level.
- */
- nbti = _bt_minitem(rpage, blk, P_RIGHTMOST(ropaque));
+ ropaque->btpo_flags &= ~BTP_ROOT;
+ _bt_wrtbuf(index, rbuf);
+
+ state = (BTPageState *) _bt_pagestate(index, 0, 0, true);
+
+ /* for each page... */
+ do
+ {
+#if 0
+ printf("\t\tblk=%d\n", blk);
+#endif
+ rbuf = _bt_getbuf(index, blk, BT_READ);
+ rpage = BufferGetPage(rbuf);
+ ropaque = (BTPageOpaque) PageGetSpecialPointer(rpage);
+
+ /* for each item... */
+ if (!PageIsEmpty(rpage))
+ {
+
+ /*
+ * form a new index tuple corresponding to the minimum key of
+ * the lower page and insert it into a page at this level.
+ */
+ nbti = _bt_minitem(rpage, blk, P_RIGHTMOST(ropaque));
#if defined(FASTBUILD_DEBUG) && defined(FASTBUILD_MERGE)
- {
- bool isnull;
- Datum d = index_getattr(&(nbti->bti_itup), 1, index->rd_att,
- &isnull);
- printf("_bt_upperbuild: inserting <%x> at %d\n",
- d, state->btps_level);
- }
-#endif /* FASTBUILD_DEBUG && FASTBUILD_MERGE */
- _bt_buildadd(index, state, nbti, 0);
- pfree((void *) nbti);
- }
- blk = ropaque->btpo_next;
- _bt_relbuf(index, rbuf, BT_READ);
- } while (blk != P_NONE);
-
- _bt_uppershutdown(index, state);
+ {
+ bool isnull;
+ Datum d = index_getattr(&(nbti->bti_itup), 1, index->rd_att,
+ &isnull);
+
+ printf("_bt_upperbuild: inserting <%x> at %d\n",
+ d, state->btps_level);
+ }
+#endif /* FASTBUILD_DEBUG && FASTBUILD_MERGE */
+ _bt_buildadd(index, state, nbti, 0);
+ pfree((void *) nbti);
+ }
+ blk = ropaque->btpo_next;
+ _bt_relbuf(index, rbuf, BT_READ);
+ } while (blk != P_NONE);
+
+ _bt_uppershutdown(index, state);
}
+
#endif
/*
@@ -1385,17 +1465,17 @@ _bt_upperbuild(Relation index)
void
_bt_leafbuild(Relation index, void *spool)
{
- _bt_isortcmpinit (index, (BTSpool *) spool);
+ _bt_isortcmpinit(index, (BTSpool *) spool);
#ifdef BTREE_BUILD_STATS
- if ( ShowExecutorStats )
- {
- fprintf(stderr, "! BtreeBuild (Spool) Stats:\n");
- ShowUsage ();
- ResetUsage ();
- }
+ if (ShowExecutorStats)
+ {
+ fprintf(stderr, "! BtreeBuild (Spool) Stats:\n");
+ ShowUsage();
+ ResetUsage();
+ }
#endif
- _bt_merge(index, (BTSpool *) spool);
+ _bt_merge(index, (BTSpool *) spool);
}
diff --git a/src/backend/access/nbtree/nbtstrat.c b/src/backend/access/nbtree/nbtstrat.c
index 6de003c06a9..5215d2000d8 100644
--- a/src/backend/access/nbtree/nbtstrat.c
+++ b/src/backend/access/nbtree/nbtstrat.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* btstrat.c--
- * Srategy map entries for the btree indexed access method
+ * Srategy map entries for the btree indexed access method
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtstrat.c,v 1.4 1996/11/05 10:35:37 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtstrat.c,v 1.5 1997/09/07 04:39:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,111 +20,111 @@
/*
* Note:
- * StrategyNegate, StrategyCommute, and StrategyNegateCommute
- * assume <, <=, ==, >=, > ordering.
+ * StrategyNegate, StrategyCommute, and StrategyNegateCommute
+ * assume <, <=, ==, >=, > ordering.
*/
-static StrategyNumber BTNegate[5] = {
- BTGreaterEqualStrategyNumber,
- BTGreaterStrategyNumber,
- InvalidStrategy,
- BTLessStrategyNumber,
- BTLessEqualStrategyNumber
+static StrategyNumber BTNegate[5] = {
+ BTGreaterEqualStrategyNumber,
+ BTGreaterStrategyNumber,
+ InvalidStrategy,
+ BTLessStrategyNumber,
+ BTLessEqualStrategyNumber
};
-static StrategyNumber BTCommute[5] = {
- BTGreaterStrategyNumber,
- BTGreaterEqualStrategyNumber,
- InvalidStrategy,
- BTLessEqualStrategyNumber,
- BTLessStrategyNumber
+static StrategyNumber BTCommute[5] = {
+ BTGreaterStrategyNumber,
+ BTGreaterEqualStrategyNumber,
+ InvalidStrategy,
+ BTLessEqualStrategyNumber,
+ BTLessStrategyNumber
};
-static StrategyNumber BTNegateCommute[5] = {
- BTLessEqualStrategyNumber,
- BTLessStrategyNumber,
- InvalidStrategy,
- BTGreaterStrategyNumber,
- BTGreaterEqualStrategyNumber
+static StrategyNumber BTNegateCommute[5] = {
+ BTLessEqualStrategyNumber,
+ BTLessStrategyNumber,
+ InvalidStrategy,
+ BTGreaterStrategyNumber,
+ BTGreaterEqualStrategyNumber
};
-static uint16 BTLessTermData[] = { /* XXX type clash */
- 2,
- BTLessStrategyNumber,
- SK_NEGATE,
- BTLessStrategyNumber,
- SK_NEGATE | SK_COMMUTE
+static uint16 BTLessTermData[] = { /* XXX type clash */
+ 2,
+ BTLessStrategyNumber,
+ SK_NEGATE,
+ BTLessStrategyNumber,
+ SK_NEGATE | SK_COMMUTE
};
-static uint16 BTLessEqualTermData[] = { /* XXX type clash */
- 2,
- BTLessEqualStrategyNumber,
- 0x0,
- BTLessEqualStrategyNumber,
- SK_COMMUTE
+static uint16 BTLessEqualTermData[] = { /* XXX type clash */
+ 2,
+ BTLessEqualStrategyNumber,
+ 0x0,
+ BTLessEqualStrategyNumber,
+ SK_COMMUTE
};
static uint16 BTGreaterEqualTermData[] = { /* XXX type clash */
- 2,
- BTGreaterEqualStrategyNumber,
- 0x0,
- BTGreaterEqualStrategyNumber,
- SK_COMMUTE
- };
-
-static uint16 BTGreaterTermData[] = { /* XXX type clash */
- 2,
- BTGreaterStrategyNumber,
- SK_NEGATE,
- BTGreaterStrategyNumber,
- SK_NEGATE | SK_COMMUTE
+ 2,
+ BTGreaterEqualStrategyNumber,
+ 0x0,
+ BTGreaterEqualStrategyNumber,
+ SK_COMMUTE
};
-static StrategyTerm BTEqualExpressionData[] = {
- (StrategyTerm)BTLessTermData, /* XXX */
- (StrategyTerm)BTLessEqualTermData, /* XXX */
- (StrategyTerm)BTGreaterEqualTermData, /* XXX */
- (StrategyTerm)BTGreaterTermData, /* XXX */
- NULL
+static uint16 BTGreaterTermData[] = { /* XXX type clash */
+ 2,
+ BTGreaterStrategyNumber,
+ SK_NEGATE,
+ BTGreaterStrategyNumber,
+ SK_NEGATE | SK_COMMUTE
};
-static StrategyEvaluationData BTEvaluationData = {
- /* XXX static for simplicity */
-
- BTMaxStrategyNumber,
- (StrategyTransformMap)BTNegate, /* XXX */
- (StrategyTransformMap)BTCommute, /* XXX */
- (StrategyTransformMap)BTNegateCommute, /* XXX */
+static StrategyTerm BTEqualExpressionData[] = {
+ (StrategyTerm) BTLessTermData, /* XXX */
+ (StrategyTerm) BTLessEqualTermData, /* XXX */
+ (StrategyTerm) BTGreaterEqualTermData, /* XXX */
+ (StrategyTerm) BTGreaterTermData, /* XXX */
+ NULL
+};
+
+static StrategyEvaluationData BTEvaluationData = {
+ /* XXX static for simplicity */
+
+ BTMaxStrategyNumber,
+ (StrategyTransformMap) BTNegate, /* XXX */
+ (StrategyTransformMap) BTCommute, /* XXX */
+ (StrategyTransformMap) BTNegateCommute, /* XXX */
- { NULL, NULL, (StrategyExpression)BTEqualExpressionData, NULL, NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL}
+ {NULL, NULL, (StrategyExpression) BTEqualExpressionData, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
/* ----------------------------------------------------------------
- * RelationGetBTStrategy
+ * RelationGetBTStrategy
* ----------------------------------------------------------------
*/
StrategyNumber
_bt_getstrat(Relation rel,
- AttrNumber attno,
- RegProcedure proc)
+ AttrNumber attno,
+ RegProcedure proc)
{
- StrategyNumber strat;
-
- strat = RelationGetStrategy(rel, attno, &BTEvaluationData, proc);
-
- Assert(StrategyNumberIsValid(strat));
-
- return (strat);
+ StrategyNumber strat;
+
+ strat = RelationGetStrategy(rel, attno, &BTEvaluationData, proc);
+
+ Assert(StrategyNumberIsValid(strat));
+
+ return (strat);
}
bool
_bt_invokestrat(Relation rel,
- AttrNumber attno,
- StrategyNumber strat,
- Datum left,
- Datum right)
+ AttrNumber attno,
+ StrategyNumber strat,
+ Datum left,
+ Datum right)
{
- return (RelationInvokeStrategy(rel, &BTEvaluationData, attno, strat,
- left, right));
+ return (RelationInvokeStrategy(rel, &BTEvaluationData, attno, strat,
+ left, right));
}
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 738e55dbccd..096f1d2691e 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* btutils.c--
- * Utility code for Postgres btree implementation.
+ * Utility code for Postgres btree implementation.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.11 1997/08/19 21:29:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.12 1997/09/07 04:39:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,367 +23,384 @@
#include <catalog/pg_proc.h>
#include <executor/execdebug.h>
-extern int NIndexTupleProcessed;
+extern int NIndexTupleProcessed;
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-ScanKey
+ScanKey
_bt_mkscankey(Relation rel, IndexTuple itup)
-{
- ScanKey skey;
- TupleDesc itupdesc;
- int natts;
- int i;
- Datum arg;
- RegProcedure proc;
- bool null;
- bits16 flag;
-
- natts = rel->rd_rel->relnatts;
- itupdesc = RelationGetTupleDescriptor(rel);
-
- skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
-
- for (i = 0; i < natts; i++) {
- arg = index_getattr(itup, i + 1, itupdesc, &null);
- if ( null )
- {
- proc = NullValueRegProcedure;
- flag = SK_ISNULL;
- }
- else
+{
+ ScanKey skey;
+ TupleDesc itupdesc;
+ int natts;
+ int i;
+ Datum arg;
+ RegProcedure proc;
+ bool null;
+ bits16 flag;
+
+ natts = rel->rd_rel->relnatts;
+ itupdesc = RelationGetTupleDescriptor(rel);
+
+ skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
+
+ for (i = 0; i < natts; i++)
{
- proc = index_getprocid(rel, i + 1, BTORDER_PROC);
- flag = 0x0;
+ arg = index_getattr(itup, i + 1, itupdesc, &null);
+ if (null)
+ {
+ proc = NullValueRegProcedure;
+ flag = SK_ISNULL;
+ }
+ else
+ {
+ proc = index_getprocid(rel, i + 1, BTORDER_PROC);
+ flag = 0x0;
+ }
+ ScanKeyEntryInitialize(&skey[i],
+ flag, (AttrNumber) (i + 1), proc, arg);
}
- ScanKeyEntryInitialize(&skey[i],
- flag, (AttrNumber) (i + 1), proc, arg);
- }
-
- return (skey);
+
+ return (skey);
}
void
_bt_freeskey(ScanKey skey)
{
- pfree(skey);
+ pfree(skey);
}
void
_bt_freestack(BTStack stack)
{
- BTStack ostack;
-
- while (stack != (BTStack) NULL) {
- ostack = stack;
- stack = stack->bts_parent;
- pfree(ostack->bts_btitem);
- pfree(ostack);
- }
+ BTStack ostack;
+
+ while (stack != (BTStack) NULL)
+ {
+ ostack = stack;
+ stack = stack->bts_parent;
+ pfree(ostack->bts_btitem);
+ pfree(ostack);
+ }
}
/*
- * _bt_orderkeys() -- Put keys in a sensible order for conjunctive quals.
+ * _bt_orderkeys() -- Put keys in a sensible order for conjunctive quals.
*
- * The order of the keys in the qual match the ordering imposed by
- * the index. This routine only needs to be called if there are
- * more than one qual clauses using this index.
+ * The order of the keys in the qual match the ordering imposed by
+ * the index. This routine only needs to be called if there are
+ * more than one qual clauses using this index.
*/
void
_bt_orderkeys(Relation relation, BTScanOpaque so)
{
- ScanKey xform;
- ScanKeyData *cur;
- StrategyMap map;
- int nbytes;
- long test;
- int i, j;
- int init[BTMaxStrategyNumber+1];
- ScanKey key;
- uint16 numberOfKeys = so->numberOfKeys;
- uint16 new_numberOfKeys = 0;
- AttrNumber attno = 1;
-
- if ( numberOfKeys < 1 )
- return;
-
- key = so->keyData;
-
- cur = &key[0];
- if ( cur->sk_attno != 1 )
- elog (WARN, "_bt_orderkeys: key(s) for attribute 1 missed");
-
- if ( numberOfKeys == 1 )
- {
- /*
- * We don't use indices for 'A is null' and 'A is not null'
- * currently and 'A < = > <> NULL' is non-sense' - so
- * qual is not Ok. - vadim 03/21/97
- */
- if ( cur->sk_flags & SK_ISNULL )
- so->qual_ok = 0;
- so->numberOfFirstKeys = 1;
- return;
- }
-
- /* get space for the modified array of keys */
- nbytes = BTMaxStrategyNumber * sizeof(ScanKeyData);
- xform = (ScanKey) palloc(nbytes);
-
- memset(xform, 0, nbytes);
- map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
- BTMaxStrategyNumber,
- attno);
- for (j = 0; j <= BTMaxStrategyNumber; j++)
- init[j] = 0;
-
- /* check each key passed in */
- for (i = 0; ; )
- {
- if ( i < numberOfKeys )
- cur = &key[i];
-
- if ( cur->sk_flags & SK_ISNULL ) /* see comments above */
- so->qual_ok = 0;
-
- if ( i == numberOfKeys || cur->sk_attno != attno )
+ ScanKey xform;
+ ScanKeyData *cur;
+ StrategyMap map;
+ int nbytes;
+ long test;
+ int i,
+ j;
+ int init[BTMaxStrategyNumber + 1];
+ ScanKey key;
+ uint16 numberOfKeys = so->numberOfKeys;
+ uint16 new_numberOfKeys = 0;
+ AttrNumber attno = 1;
+
+ if (numberOfKeys < 1)
+ return;
+
+ key = so->keyData;
+
+ cur = &key[0];
+ if (cur->sk_attno != 1)
+ elog(WARN, "_bt_orderkeys: key(s) for attribute 1 missed");
+
+ if (numberOfKeys == 1)
{
- if ( cur->sk_attno != attno + 1 && i < numberOfKeys )
- {
- elog (WARN, "_bt_orderkeys: key(s) for attribute %d missed", attno + 1);
- }
- /*
- * 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 0
- */
- if (init[BTEqualStrategyNumber - 1])
- {
- ScanKeyData *eq, *chk;
-
- eq = &xform[BTEqualStrategyNumber - 1];
- for (j = BTMaxStrategyNumber; --j >= 0; )
- {
- if ( j == (BTEqualStrategyNumber - 1) || init[j] == 0 )
- continue;
- chk = &xform[j];
- test = (long) fmgr(chk->sk_procedure, eq->sk_argument, chk->sk_argument);
- if (!test)
- so->qual_ok = 0;
- }
- init[BTLessStrategyNumber - 1] = 0;
- init[BTLessEqualStrategyNumber - 1] = 0;
- init[BTGreaterEqualStrategyNumber - 1] = 0;
- init[BTGreaterStrategyNumber - 1] = 0;
- }
-
- /* only one of <, <= */
- if (init[BTLessStrategyNumber - 1]
- && init[BTLessEqualStrategyNumber - 1])
- {
- ScanKeyData *lt, *le;
-
- lt = &xform[BTLessStrategyNumber - 1];
- le = &xform[BTLessEqualStrategyNumber - 1];
+
/*
- * DO NOT use the cached function stuff here -- this is key
- * ordering, happens only when the user expresses a hokey
- * qualification, and gets executed only once, anyway. The
- * transform maps are hard-coded, and can't be initialized
- * in the correct way.
+ * We don't use indices for 'A is null' and 'A is not null'
+ * currently and 'A < = > <> NULL' is non-sense' - so qual is not
+ * Ok. - vadim 03/21/97
*/
- test = (long) fmgr(le->sk_procedure, lt->sk_argument, le->sk_argument);
- if (test)
- init[BTLessEqualStrategyNumber - 1] = 0;
- else
- init[BTLessStrategyNumber - 1] = 0;
- }
-
- /* only one of >, >= */
- if (init[BTGreaterStrategyNumber - 1]
- && init[BTGreaterEqualStrategyNumber - 1])
- {
- ScanKeyData *gt, *ge;
-
- gt = &xform[BTGreaterStrategyNumber - 1];
- ge = &xform[BTGreaterEqualStrategyNumber - 1];
-
- /* see note above on function cache */
- test = (long) fmgr(ge->sk_procedure, gt->sk_argument, ge->sk_argument);
- if (test)
- init[BTGreaterEqualStrategyNumber - 1] = 0;
- else
- init[BTGreaterStrategyNumber - 1] = 0;
- }
-
- /* okay, reorder and count */
- for (j = BTMaxStrategyNumber; --j >= 0; )
- if (init[j])
- key[new_numberOfKeys++] = xform[j];
-
- if ( attno == 1 )
- so->numberOfFirstKeys = new_numberOfKeys;
-
- if ( i == numberOfKeys )
- break;
-
- /* initialization for new attno */
- attno = cur->sk_attno;
- memset(xform, 0, nbytes);
- map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
- BTMaxStrategyNumber,
- attno);
- /* haven't looked at any strategies yet */
- for (j = 0; j <= BTMaxStrategyNumber; j++)
- init[j] = 0;
+ if (cur->sk_flags & SK_ISNULL)
+ so->qual_ok = 0;
+ so->numberOfFirstKeys = 1;
+ return;
}
- for (j = BTMaxStrategyNumber; --j >= 0; )
- {
- if (cur->sk_procedure == map->entry[j].sk_procedure)
- break;
- }
-
- /* have we seen one of these before? */
- if (init[j])
- {
- /* yup, use the appropriate value */
- test =
- (long) FMGR_PTR2(cur->sk_func, cur->sk_procedure,
- cur->sk_argument, xform[j].sk_argument);
- if (test)
- xform[j].sk_argument = cur->sk_argument;
- else if ( j == (BTEqualStrategyNumber - 1) )
- so->qual_ok = 0; /* key == a && key == b, but a != b */
- } else
+ /* get space for the modified array of keys */
+ nbytes = BTMaxStrategyNumber * sizeof(ScanKeyData);
+ xform = (ScanKey) palloc(nbytes);
+
+ memset(xform, 0, nbytes);
+ map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
+ BTMaxStrategyNumber,
+ attno);
+ for (j = 0; j <= BTMaxStrategyNumber; j++)
+ init[j] = 0;
+
+ /* check each key passed in */
+ for (i = 0;;)
{
- /* nope, use this value */
- memmove(&xform[j], cur, sizeof(*cur));
- init[j] = 1;
+ if (i < numberOfKeys)
+ cur = &key[i];
+
+ if (cur->sk_flags & SK_ISNULL) /* see comments above */
+ so->qual_ok = 0;
+
+ if (i == numberOfKeys || cur->sk_attno != attno)
+ {
+ if (cur->sk_attno != attno + 1 && i < numberOfKeys)
+ {
+ elog(WARN, "_bt_orderkeys: key(s) for attribute %d missed", attno + 1);
+ }
+
+ /*
+ * 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
+ * 0
+ */
+ if (init[BTEqualStrategyNumber - 1])
+ {
+ ScanKeyData *eq,
+ *chk;
+
+ eq = &xform[BTEqualStrategyNumber - 1];
+ for (j = BTMaxStrategyNumber; --j >= 0;)
+ {
+ if (j == (BTEqualStrategyNumber - 1) || init[j] == 0)
+ continue;
+ chk = &xform[j];
+ test = (long) fmgr(chk->sk_procedure, eq->sk_argument, chk->sk_argument);
+ if (!test)
+ so->qual_ok = 0;
+ }
+ init[BTLessStrategyNumber - 1] = 0;
+ init[BTLessEqualStrategyNumber - 1] = 0;
+ init[BTGreaterEqualStrategyNumber - 1] = 0;
+ init[BTGreaterStrategyNumber - 1] = 0;
+ }
+
+ /* only one of <, <= */
+ if (init[BTLessStrategyNumber - 1]
+ && init[BTLessEqualStrategyNumber - 1])
+ {
+ ScanKeyData *lt,
+ *le;
+
+ lt = &xform[BTLessStrategyNumber - 1];
+ le = &xform[BTLessEqualStrategyNumber - 1];
+
+ /*
+ * DO NOT use the cached function stuff here -- this is
+ * key ordering, happens only when the user expresses a
+ * hokey qualification, and gets executed only once,
+ * anyway. The transform maps are hard-coded, and can't
+ * be initialized in the correct way.
+ */
+ test = (long) fmgr(le->sk_procedure, lt->sk_argument, le->sk_argument);
+ if (test)
+ init[BTLessEqualStrategyNumber - 1] = 0;
+ else
+ init[BTLessStrategyNumber - 1] = 0;
+ }
+
+ /* only one of >, >= */
+ if (init[BTGreaterStrategyNumber - 1]
+ && init[BTGreaterEqualStrategyNumber - 1])
+ {
+ ScanKeyData *gt,
+ *ge;
+
+ gt = &xform[BTGreaterStrategyNumber - 1];
+ ge = &xform[BTGreaterEqualStrategyNumber - 1];
+
+ /* see note above on function cache */
+ test = (long) fmgr(ge->sk_procedure, gt->sk_argument, ge->sk_argument);
+ if (test)
+ init[BTGreaterEqualStrategyNumber - 1] = 0;
+ else
+ init[BTGreaterStrategyNumber - 1] = 0;
+ }
+
+ /* okay, reorder and count */
+ for (j = BTMaxStrategyNumber; --j >= 0;)
+ if (init[j])
+ key[new_numberOfKeys++] = xform[j];
+
+ if (attno == 1)
+ so->numberOfFirstKeys = new_numberOfKeys;
+
+ if (i == numberOfKeys)
+ break;
+
+ /* initialization for new attno */
+ attno = cur->sk_attno;
+ memset(xform, 0, nbytes);
+ map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
+ BTMaxStrategyNumber,
+ attno);
+ /* haven't looked at any strategies yet */
+ for (j = 0; j <= BTMaxStrategyNumber; j++)
+ init[j] = 0;
+ }
+
+ for (j = BTMaxStrategyNumber; --j >= 0;)
+ {
+ if (cur->sk_procedure == map->entry[j].sk_procedure)
+ break;
+ }
+
+ /* have we seen one of these before? */
+ if (init[j])
+ {
+ /* yup, use the appropriate value */
+ test =
+ (long) FMGR_PTR2(cur->sk_func, cur->sk_procedure,
+ cur->sk_argument, xform[j].sk_argument);
+ if (test)
+ xform[j].sk_argument = cur->sk_argument;
+ else if (j == (BTEqualStrategyNumber - 1))
+ so->qual_ok = 0;/* key == a && key == b, but a != b */
+ }
+ else
+ {
+ /* nope, use this value */
+ memmove(&xform[j], cur, sizeof(*cur));
+ init[j] = 1;
+ }
+
+ i++;
}
-
- i++;
- }
-
- so->numberOfKeys = new_numberOfKeys;
-
- pfree(xform);
+
+ so->numberOfKeys = new_numberOfKeys;
+
+ pfree(xform);
}
BTItem
_bt_formitem(IndexTuple itup)
{
- int nbytes_btitem;
- BTItem btitem;
- Size tuplen;
- extern Oid newoid();
-
- /* see comments in btbuild
-
- if (itup->t_info & INDEX_NULL_MASK)
- elog(WARN, "btree indices cannot include null keys");
- */
-
- /* make a copy of the index tuple with room for the sequence number */
- tuplen = IndexTupleSize(itup);
- nbytes_btitem = tuplen +
- (sizeof(BTItemData) - sizeof(IndexTupleData));
-
- btitem = (BTItem) palloc(nbytes_btitem);
- memmove((char *) &(btitem->bti_itup), (char *) itup, tuplen);
-
+ int nbytes_btitem;
+ BTItem btitem;
+ Size tuplen;
+ extern Oid newoid();
+
+ /*
+ * see comments in btbuild
+ *
+ * if (itup->t_info & INDEX_NULL_MASK) elog(WARN, "btree indices cannot
+ * include null keys");
+ */
+
+ /* make a copy of the index tuple with room for the sequence number */
+ tuplen = IndexTupleSize(itup);
+ nbytes_btitem = tuplen +
+ (sizeof(BTItemData) - sizeof(IndexTupleData));
+
+ btitem = (BTItem) palloc(nbytes_btitem);
+ memmove((char *) &(btitem->bti_itup), (char *) itup, tuplen);
+
#ifndef BTREE_VERSION_1
- btitem->bti_oid = newoid();
+ btitem->bti_oid = newoid();
#endif
- return (btitem);
+ return (btitem);
}
#ifdef NOT_USED
bool
_bt_checkqual(IndexScanDesc scan, IndexTuple itup)
{
- BTScanOpaque so;
-
- so = (BTScanOpaque) scan->opaque;
- if (so->numberOfKeys > 0)
- return (index_keytest(itup, RelationGetTupleDescriptor(scan->relation),
- so->numberOfKeys, so->keyData));
- else
- return (true);
+ BTScanOpaque so;
+
+ so = (BTScanOpaque) scan->opaque;
+ if (so->numberOfKeys > 0)
+ return (index_keytest(itup, RelationGetTupleDescriptor(scan->relation),
+ so->numberOfKeys, so->keyData));
+ else
+ return (true);
}
+
#endif
#ifdef NOT_USED
bool
_bt_checkforkeys(IndexScanDesc scan, IndexTuple itup, Size keysz)
{
- BTScanOpaque so;
-
- so = (BTScanOpaque) scan->opaque;
- if ( keysz > 0 && so->numberOfKeys >= keysz )
- return (index_keytest(itup, RelationGetTupleDescriptor(scan->relation),
- keysz, so->keyData));
- else
- return (true);
+ BTScanOpaque so;
+
+ so = (BTScanOpaque) scan->opaque;
+ if (keysz > 0 && so->numberOfKeys >= keysz)
+ return (index_keytest(itup, RelationGetTupleDescriptor(scan->relation),
+ keysz, so->keyData));
+ else
+ return (true);
}
+
#endif
bool
-_bt_checkkeys (IndexScanDesc scan, IndexTuple tuple, Size *keysok)
+_bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, Size * keysok)
{
- BTScanOpaque so = (BTScanOpaque) scan->opaque;
- Size keysz = so->numberOfKeys;
- TupleDesc tupdesc;
- ScanKey key;
- Datum datum;
- bool isNull;
- int test;
-
- *keysok = 0;
- if ( keysz == 0 )
- return (true);
-
- key = so->keyData;
- tupdesc = RelationGetTupleDescriptor(scan->relation);
-
- IncrIndexProcessed();
-
- while (keysz > 0)
- {
- datum = index_getattr(tuple,
- key[0].sk_attno,
- tupdesc,
- &isNull);
-
- /* btree doesn't support 'A is null' clauses, yet */
- if ( isNull || key[0].sk_flags & SK_ISNULL )
+ BTScanOpaque so = (BTScanOpaque) scan->opaque;
+ Size keysz = so->numberOfKeys;
+ TupleDesc tupdesc;
+ ScanKey key;
+ Datum datum;
+ bool isNull;
+ int test;
+
+ *keysok = 0;
+ if (keysz == 0)
+ return (true);
+
+ key = so->keyData;
+ tupdesc = RelationGetTupleDescriptor(scan->relation);
+
+ IncrIndexProcessed();
+
+ while (keysz > 0)
{
- return (false);
- }
+ datum = index_getattr(tuple,
+ key[0].sk_attno,
+ tupdesc,
+ &isNull);
- if (key[0].sk_flags & SK_COMMUTE) {
- test = (int) (*(key[0].sk_func))
- (DatumGetPointer(key[0].sk_argument),
- datum);
- } else {
- test = (int) (*(key[0].sk_func))
- (datum,
- DatumGetPointer(key[0].sk_argument));
- }
-
- if (!test == !(key[0].sk_flags & SK_NEGATE)) {
- return (false);
+ /* btree doesn't support 'A is null' clauses, yet */
+ if (isNull || key[0].sk_flags & SK_ISNULL)
+ {
+ return (false);
+ }
+
+ if (key[0].sk_flags & SK_COMMUTE)
+ {
+ test = (int) (*(key[0].sk_func))
+ (DatumGetPointer(key[0].sk_argument),
+ datum);
+ }
+ else
+ {
+ test = (int) (*(key[0].sk_func))
+ (datum,
+ DatumGetPointer(key[0].sk_argument));
+ }
+
+ if (!test == !(key[0].sk_flags & SK_NEGATE))
+ {
+ return (false);
+ }
+
+ keysz -= 1;
+ key++;
+ (*keysok)++;
}
-
- keysz -= 1;
- key++;
- (*keysok)++;
- }
-
- return (true);
+
+ return (true);
}
diff --git a/src/backend/access/rtree/rtget.c b/src/backend/access/rtree/rtget.c
index 09f10f1aa98..eaf16c1ae9d 100644
--- a/src/backend/access/rtree/rtget.c
+++ b/src/backend/access/rtree/rtget.c
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* rtget.c--
- * fetch tuples from an rtree scan.
+ * fetch tuples from an rtree scan.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtget.c,v 1.7 1996/11/21 06:13:43 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtget.c,v 1.8 1997/09/07 04:39:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <storage/bufmgr.h>
#include <access/sdir.h>
#include <access/relscan.h>
@@ -21,14 +21,15 @@
#include <access/rtree.h>
#include <storage/bufpage.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static OffsetNumber findnext(IndexScanDesc s, Page p, OffsetNumber n,
- ScanDirection dir);
+static OffsetNumber
+findnext(IndexScanDesc s, Page p, OffsetNumber n,
+ ScanDirection dir);
static RetrieveIndexResult rtscancache(IndexScanDesc s, ScanDirection dir);
static RetrieveIndexResult rtfirst(IndexScanDesc s, ScanDirection dir);
static RetrieveIndexResult rtnext(IndexScanDesc s, ScanDirection dir);
@@ -38,278 +39,315 @@ static ItemPointer rtheapptr(Relation r, ItemPointer itemp);
RetrieveIndexResult
rtgettuple(IndexScanDesc s, ScanDirection dir)
{
- RetrieveIndexResult res;
-
- /* if we have it cached in the scan desc, just return the value */
- if ((res = rtscancache(s, dir)) != (RetrieveIndexResult) NULL)
+ RetrieveIndexResult res;
+
+ /* if we have it cached in the scan desc, just return the value */
+ if ((res = rtscancache(s, dir)) != (RetrieveIndexResult) NULL)
+ return (res);
+
+ /* not cached, so we'll have to do some work */
+ if (ItemPointerIsValid(&(s->currentItemData)))
+ {
+ res = rtnext(s, dir);
+ }
+ else
+ {
+ res = rtfirst(s, dir);
+ }
return (res);
-
- /* not cached, so we'll have to do some work */
- if (ItemPointerIsValid(&(s->currentItemData))) {
- res = rtnext(s, dir);
- } else {
- res = rtfirst(s, dir);
- }
- return (res);
}
-static RetrieveIndexResult
+static RetrieveIndexResult
rtfirst(IndexScanDesc s, ScanDirection dir)
{
- Buffer b;
- Page p;
- OffsetNumber n;
- OffsetNumber maxoff;
- RetrieveIndexResult res;
- RTreePageOpaque po;
- RTreeScanOpaque so;
- RTSTACK *stk;
- BlockNumber blk;
- IndexTuple it;
-
- b = ReadBuffer(s->relation, P_ROOT);
- p = BufferGetPage(b);
- po = (RTreePageOpaque) PageGetSpecialPointer(p);
- so = (RTreeScanOpaque) s->opaque;
-
- for (;;) {
- maxoff = PageGetMaxOffsetNumber(p);
- if (ScanDirectionIsBackward(dir))
- n = findnext(s, p, maxoff, dir);
- else
- n = findnext(s, p, FirstOffsetNumber, dir);
-
- while (n < FirstOffsetNumber || n > maxoff) {
-
- ReleaseBuffer(b);
- if (so->s_stack == (RTSTACK *) NULL)
- return ((RetrieveIndexResult) NULL);
-
- stk = so->s_stack;
- b = ReadBuffer(s->relation, stk->rts_blk);
- p = BufferGetPage(b);
- po = (RTreePageOpaque) PageGetSpecialPointer(p);
- maxoff = PageGetMaxOffsetNumber(p);
-
- if (ScanDirectionIsBackward(dir)) {
- n = OffsetNumberPrev(stk->rts_child);
- } else {
- n = OffsetNumberNext(stk->rts_child);
- }
- so->s_stack = stk->rts_parent;
- pfree(stk);
-
- n = findnext(s, p, n, dir);
- }
- if (po->flags & F_LEAF) {
- ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
-
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
-
- res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
-
- ReleaseBuffer(b);
- return (res);
- } else {
- stk = (RTSTACK *) palloc(sizeof(RTSTACK));
- stk->rts_child = n;
- stk->rts_blk = BufferGetBlockNumber(b);
- stk->rts_parent = so->s_stack;
- so->s_stack = stk;
-
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
- blk = ItemPointerGetBlockNumber(&(it->t_tid));
-
- ReleaseBuffer(b);
- b = ReadBuffer(s->relation, blk);
- p = BufferGetPage(b);
- po = (RTreePageOpaque) PageGetSpecialPointer(p);
+ Buffer b;
+ Page p;
+ OffsetNumber n;
+ OffsetNumber maxoff;
+ RetrieveIndexResult res;
+ RTreePageOpaque po;
+ RTreeScanOpaque so;
+ RTSTACK *stk;
+ BlockNumber blk;
+ IndexTuple it;
+
+ b = ReadBuffer(s->relation, P_ROOT);
+ p = BufferGetPage(b);
+ po = (RTreePageOpaque) PageGetSpecialPointer(p);
+ so = (RTreeScanOpaque) s->opaque;
+
+ for (;;)
+ {
+ maxoff = PageGetMaxOffsetNumber(p);
+ if (ScanDirectionIsBackward(dir))
+ n = findnext(s, p, maxoff, dir);
+ else
+ n = findnext(s, p, FirstOffsetNumber, dir);
+
+ while (n < FirstOffsetNumber || n > maxoff)
+ {
+
+ ReleaseBuffer(b);
+ if (so->s_stack == (RTSTACK *) NULL)
+ return ((RetrieveIndexResult) NULL);
+
+ stk = so->s_stack;
+ b = ReadBuffer(s->relation, stk->rts_blk);
+ p = BufferGetPage(b);
+ po = (RTreePageOpaque) PageGetSpecialPointer(p);
+ maxoff = PageGetMaxOffsetNumber(p);
+
+ if (ScanDirectionIsBackward(dir))
+ {
+ n = OffsetNumberPrev(stk->rts_child);
+ }
+ else
+ {
+ n = OffsetNumberNext(stk->rts_child);
+ }
+ so->s_stack = stk->rts_parent;
+ pfree(stk);
+
+ n = findnext(s, p, n, dir);
+ }
+ if (po->flags & F_LEAF)
+ {
+ ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
+
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+
+ res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
+
+ ReleaseBuffer(b);
+ return (res);
+ }
+ else
+ {
+ stk = (RTSTACK *) palloc(sizeof(RTSTACK));
+ stk->rts_child = n;
+ stk->rts_blk = BufferGetBlockNumber(b);
+ stk->rts_parent = so->s_stack;
+ so->s_stack = stk;
+
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+ blk = ItemPointerGetBlockNumber(&(it->t_tid));
+
+ ReleaseBuffer(b);
+ b = ReadBuffer(s->relation, blk);
+ p = BufferGetPage(b);
+ po = (RTreePageOpaque) PageGetSpecialPointer(p);
+ }
}
- }
}
-static RetrieveIndexResult
+static RetrieveIndexResult
rtnext(IndexScanDesc s, ScanDirection dir)
{
- Buffer b;
- Page p;
- OffsetNumber n;
- OffsetNumber maxoff;
- RetrieveIndexResult res;
- RTreePageOpaque po;
- RTreeScanOpaque so;
- RTSTACK *stk;
- BlockNumber blk;
- IndexTuple it;
-
- blk = ItemPointerGetBlockNumber(&(s->currentItemData));
- n = ItemPointerGetOffsetNumber(&(s->currentItemData));
-
- if (ScanDirectionIsForward(dir)) {
- n = OffsetNumberNext(n);
- } else {
- n = OffsetNumberPrev(n);
- }
-
- b = ReadBuffer(s->relation, blk);
- p = BufferGetPage(b);
- po = (RTreePageOpaque) PageGetSpecialPointer(p);
- so = (RTreeScanOpaque) s->opaque;
-
- for (;;) {
- maxoff = PageGetMaxOffsetNumber(p);
- n = findnext(s, p, n, dir);
-
- while (n < FirstOffsetNumber || n > maxoff) {
-
- ReleaseBuffer(b);
- if (so->s_stack == (RTSTACK *) NULL)
- return ((RetrieveIndexResult) NULL);
-
- stk = so->s_stack;
- b = ReadBuffer(s->relation, stk->rts_blk);
- p = BufferGetPage(b);
- maxoff = PageGetMaxOffsetNumber(p);
- po = (RTreePageOpaque) PageGetSpecialPointer(p);
-
- if (ScanDirectionIsBackward(dir)) {
- n = OffsetNumberPrev(stk->rts_child);
- } else {
- n = OffsetNumberNext(stk->rts_child);
- }
- so->s_stack = stk->rts_parent;
- pfree(stk);
-
- n = findnext(s, p, n, dir);
+ Buffer b;
+ Page p;
+ OffsetNumber n;
+ OffsetNumber maxoff;
+ RetrieveIndexResult res;
+ RTreePageOpaque po;
+ RTreeScanOpaque so;
+ RTSTACK *stk;
+ BlockNumber blk;
+ IndexTuple it;
+
+ blk = ItemPointerGetBlockNumber(&(s->currentItemData));
+ n = ItemPointerGetOffsetNumber(&(s->currentItemData));
+
+ if (ScanDirectionIsForward(dir))
+ {
+ n = OffsetNumberNext(n);
+ }
+ else
+ {
+ n = OffsetNumberPrev(n);
}
- if (po->flags & F_LEAF) {
- ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
-
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
-
- res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
-
- ReleaseBuffer(b);
- return (res);
- } else {
- stk = (RTSTACK *) palloc(sizeof(RTSTACK));
- stk->rts_child = n;
- stk->rts_blk = BufferGetBlockNumber(b);
- stk->rts_parent = so->s_stack;
- so->s_stack = stk;
-
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
- blk = ItemPointerGetBlockNumber(&(it->t_tid));
-
- ReleaseBuffer(b);
- b = ReadBuffer(s->relation, blk);
- p = BufferGetPage(b);
- po = (RTreePageOpaque) PageGetSpecialPointer(p);
-
- if (ScanDirectionIsBackward(dir)) {
- n = PageGetMaxOffsetNumber(p);
- } else {
- n = FirstOffsetNumber;
- }
+
+ b = ReadBuffer(s->relation, blk);
+ p = BufferGetPage(b);
+ po = (RTreePageOpaque) PageGetSpecialPointer(p);
+ so = (RTreeScanOpaque) s->opaque;
+
+ for (;;)
+ {
+ maxoff = PageGetMaxOffsetNumber(p);
+ n = findnext(s, p, n, dir);
+
+ while (n < FirstOffsetNumber || n > maxoff)
+ {
+
+ ReleaseBuffer(b);
+ if (so->s_stack == (RTSTACK *) NULL)
+ return ((RetrieveIndexResult) NULL);
+
+ stk = so->s_stack;
+ b = ReadBuffer(s->relation, stk->rts_blk);
+ p = BufferGetPage(b);
+ maxoff = PageGetMaxOffsetNumber(p);
+ po = (RTreePageOpaque) PageGetSpecialPointer(p);
+
+ if (ScanDirectionIsBackward(dir))
+ {
+ n = OffsetNumberPrev(stk->rts_child);
+ }
+ else
+ {
+ n = OffsetNumberNext(stk->rts_child);
+ }
+ so->s_stack = stk->rts_parent;
+ pfree(stk);
+
+ n = findnext(s, p, n, dir);
+ }
+ if (po->flags & F_LEAF)
+ {
+ ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n);
+
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+
+ res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
+
+ ReleaseBuffer(b);
+ return (res);
+ }
+ else
+ {
+ stk = (RTSTACK *) palloc(sizeof(RTSTACK));
+ stk->rts_child = n;
+ stk->rts_blk = BufferGetBlockNumber(b);
+ stk->rts_parent = so->s_stack;
+ so->s_stack = stk;
+
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+ blk = ItemPointerGetBlockNumber(&(it->t_tid));
+
+ ReleaseBuffer(b);
+ b = ReadBuffer(s->relation, blk);
+ p = BufferGetPage(b);
+ po = (RTreePageOpaque) PageGetSpecialPointer(p);
+
+ if (ScanDirectionIsBackward(dir))
+ {
+ n = PageGetMaxOffsetNumber(p);
+ }
+ else
+ {
+ n = FirstOffsetNumber;
+ }
+ }
}
- }
}
-static OffsetNumber
+static OffsetNumber
findnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
{
- OffsetNumber maxoff;
- IndexTuple it;
- RTreePageOpaque po;
- RTreeScanOpaque so;
-
- maxoff = PageGetMaxOffsetNumber(p);
- po = (RTreePageOpaque) PageGetSpecialPointer(p);
- so = (RTreeScanOpaque) s->opaque;
-
- /*
- * If we modified the index during the scan, we may have a pointer to
- * a ghost tuple, before the scan. If this is the case, back up one.
- */
-
- if (so->s_flags & RTS_CURBEFORE) {
- so->s_flags &= ~RTS_CURBEFORE;
- n = OffsetNumberPrev(n);
- }
-
- while (n >= FirstOffsetNumber && n <= maxoff) {
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
- if (po->flags & F_LEAF) {
- if (index_keytest(it,
- RelationGetTupleDescriptor(s->relation),
- s->numberOfKeys, s->keyData))
- break;
- } else {
- if (index_keytest(it,
- RelationGetTupleDescriptor(s->relation),
- so->s_internalNKey, so->s_internalKey))
- break;
+ OffsetNumber maxoff;
+ IndexTuple it;
+ RTreePageOpaque po;
+ RTreeScanOpaque so;
+
+ maxoff = PageGetMaxOffsetNumber(p);
+ po = (RTreePageOpaque) PageGetSpecialPointer(p);
+ so = (RTreeScanOpaque) s->opaque;
+
+ /*
+ * If we modified the index during the scan, we may have a pointer to
+ * a ghost tuple, before the scan. If this is the case, back up one.
+ */
+
+ if (so->s_flags & RTS_CURBEFORE)
+ {
+ so->s_flags &= ~RTS_CURBEFORE;
+ n = OffsetNumberPrev(n);
}
-
- if (ScanDirectionIsBackward(dir)) {
- n = OffsetNumberPrev(n);
- } else {
- n = OffsetNumberNext(n);
+
+ while (n >= FirstOffsetNumber && n <= maxoff)
+ {
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+ if (po->flags & F_LEAF)
+ {
+ if (index_keytest(it,
+ RelationGetTupleDescriptor(s->relation),
+ s->numberOfKeys, s->keyData))
+ break;
+ }
+ else
+ {
+ if (index_keytest(it,
+ RelationGetTupleDescriptor(s->relation),
+ so->s_internalNKey, so->s_internalKey))
+ break;
+ }
+
+ if (ScanDirectionIsBackward(dir))
+ {
+ n = OffsetNumberPrev(n);
+ }
+ else
+ {
+ n = OffsetNumberNext(n);
+ }
}
- }
-
- return (n);
+
+ return (n);
}
-static RetrieveIndexResult
+static RetrieveIndexResult
rtscancache(IndexScanDesc s, ScanDirection dir)
{
- RetrieveIndexResult res;
- ItemPointer ip;
-
- if (!(ScanDirectionIsNoMovement(dir)
- && ItemPointerIsValid(&(s->currentItemData)))) {
-
- return ((RetrieveIndexResult) NULL);
- }
-
- ip = rtheapptr(s->relation, &(s->currentItemData));
-
- if (ItemPointerIsValid(ip))
- res = FormRetrieveIndexResult(&(s->currentItemData), ip);
- else
- res = (RetrieveIndexResult) NULL;
-
- pfree (ip);
-
- return (res);
+ RetrieveIndexResult res;
+ ItemPointer ip;
+
+ if (!(ScanDirectionIsNoMovement(dir)
+ && ItemPointerIsValid(&(s->currentItemData))))
+ {
+
+ return ((RetrieveIndexResult) NULL);
+ }
+
+ ip = rtheapptr(s->relation, &(s->currentItemData));
+
+ if (ItemPointerIsValid(ip))
+ res = FormRetrieveIndexResult(&(s->currentItemData), ip);
+ else
+ res = (RetrieveIndexResult) NULL;
+
+ pfree(ip);
+
+ return (res);
}
/*
- * rtheapptr returns the item pointer to the tuple in the heap relation
- * for which itemp is the index relation item pointer.
+ * rtheapptr returns the item pointer to the tuple in the heap relation
+ * for which itemp is the index relation item pointer.
*/
-static ItemPointer
+static ItemPointer
rtheapptr(Relation r, ItemPointer itemp)
{
- Buffer b;
- Page p;
- IndexTuple it;
- ItemPointer ip;
- OffsetNumber n;
-
- ip = (ItemPointer) palloc(sizeof(ItemPointerData));
- if (ItemPointerIsValid(itemp)) {
- b = ReadBuffer(r, ItemPointerGetBlockNumber(itemp));
- p = BufferGetPage(b);
- n = ItemPointerGetOffsetNumber(itemp);
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
- memmove((char *) ip, (char *) &(it->t_tid),
- sizeof(ItemPointerData));
- ReleaseBuffer(b);
- } else {
- ItemPointerSetInvalid(ip);
- }
-
- return (ip);
+ Buffer b;
+ Page p;
+ IndexTuple it;
+ ItemPointer ip;
+ OffsetNumber n;
+
+ ip = (ItemPointer) palloc(sizeof(ItemPointerData));
+ if (ItemPointerIsValid(itemp))
+ {
+ b = ReadBuffer(r, ItemPointerGetBlockNumber(itemp));
+ p = BufferGetPage(b);
+ n = ItemPointerGetOffsetNumber(itemp);
+ it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
+ memmove((char *) ip, (char *) &(it->t_tid),
+ sizeof(ItemPointerData));
+ ReleaseBuffer(b);
+ }
+ else
+ {
+ ItemPointerSetInvalid(ip);
+ }
+
+ return (ip);
}
diff --git a/src/backend/access/rtree/rtproc.c b/src/backend/access/rtree/rtproc.c
index ac7a3abfecf..4b7a9f2a266 100644
--- a/src/backend/access/rtree/rtproc.c
+++ b/src/backend/access/rtree/rtproc.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rtproc.c--
- * pg_amproc entries for rtrees.
+ * pg_amproc entries for rtrees.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.7 1997/04/22 17:31:23 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.8 1997/09/07 04:39:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,136 +17,139 @@
#include <utils/builtins.h>
#include <utils/geo_decls.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
BOX
-*rt_box_union(BOX *a, BOX *b)
+* rt_box_union(BOX * a, BOX * b)
{
- BOX *n;
-
- if ((n = (BOX *) palloc(sizeof (*n))) == (BOX *) NULL)
- elog(WARN, "Cannot allocate box for union");
-
- n->high.x = Max(a->high.x, b->high.x);
- n->high.y = Max(a->high.y, b->high.y);
- n->low.x = Min(a->low.x, b->low.x);
- n->low.y = Min(a->low.y, b->low.y);
-
- return (n);
+ BOX *n;
+
+ if ((n = (BOX *) palloc(sizeof(*n))) == (BOX *) NULL)
+ elog(WARN, "Cannot allocate box for union");
+
+ n->high.x = Max(a->high.x, b->high.x);
+ n->high.y = Max(a->high.y, b->high.y);
+ n->low.x = Min(a->low.x, b->low.x);
+ n->low.y = Min(a->low.y, b->low.y);
+
+ return (n);
}
-BOX *
-rt_box_inter(BOX *a, BOX *b)
+BOX *
+rt_box_inter(BOX * a, BOX * b)
{
- BOX *n;
-
- if ((n = (BOX *) palloc(sizeof (*n))) == (BOX *) NULL)
- elog(WARN, "Cannot allocate box for union");
-
- n->high.x = Min(a->high.x, b->high.x);
- n->high.y = Min(a->high.y, b->high.y);
- n->low.x = Max(a->low.x, b->low.x);
- n->low.y = Max(a->low.y, b->low.y);
-
- if (n->high.x < n->low.x || n->high.y < n->low.y) {
- pfree(n);
- return ((BOX *) NULL);
- }
-
- return (n);
+ BOX *n;
+
+ if ((n = (BOX *) palloc(sizeof(*n))) == (BOX *) NULL)
+ elog(WARN, "Cannot allocate box for union");
+
+ n->high.x = Min(a->high.x, b->high.x);
+ n->high.y = Min(a->high.y, b->high.y);
+ n->low.x = Max(a->low.x, b->low.x);
+ n->low.y = Max(a->low.y, b->low.y);
+
+ if (n->high.x < n->low.x || n->high.y < n->low.y)
+ {
+ pfree(n);
+ return ((BOX *) NULL);
+ }
+
+ return (n);
}
void
-rt_box_size(BOX *a, float *size)
+rt_box_size(BOX * a, float *size)
{
- if (a == (BOX *) NULL || a->high.x <= a->low.x || a->high.y <= a->low.y)
- *size = 0.0;
- else
- *size = (float) ((a->high.x - a->low.x) * (a->high.y - a->low.y));
-
- return;
+ if (a == (BOX *) NULL || a->high.x <= a->low.x || a->high.y <= a->low.y)
+ *size = 0.0;
+ else
+ *size = (float) ((a->high.x - a->low.x) * (a->high.y - a->low.y));
+
+ return;
}
/*
- * rt_bigbox_size() -- Compute a size for big boxes.
+ * rt_bigbox_size() -- Compute a size for big boxes.
*
- * In an earlier release of the system, this routine did something
- * different from rt_box_size. We now use floats, rather than ints,
- * as the return type for the size routine, so we no longer need to
- * have a special return type for big boxes.
+ * In an earlier release of the system, this routine did something
+ * different from rt_box_size. We now use floats, rather than ints,
+ * as the return type for the size routine, so we no longer need to
+ * have a special return type for big boxes.
*/
void
-rt_bigbox_size(BOX *a, float *size)
+rt_bigbox_size(BOX * a, float *size)
{
- rt_box_size(a, size);
+ rt_box_size(a, size);
}
-POLYGON *
-rt_poly_union(POLYGON *a, POLYGON *b)
+POLYGON *
+rt_poly_union(POLYGON * a, POLYGON * b)
{
- POLYGON *p;
-
- p = (POLYGON *)PALLOCTYPE(POLYGON);
-
- if (!PointerIsValid(p))
- elog(WARN, "Cannot allocate polygon for union");
-
- memset((char *) p, 0, sizeof(POLYGON)); /* zero any holes */
- p->size = sizeof(POLYGON);
- p->npts = 0;
- p->boundbox.high.x = Max(a->boundbox.high.x, b->boundbox.high.x);
- p->boundbox.high.y = Max(a->boundbox.high.y, b->boundbox.high.y);
- p->boundbox.low.x = Min(a->boundbox.low.x, b->boundbox.low.x);
- p->boundbox.low.y = Min(a->boundbox.low.y, b->boundbox.low.y);
- return p;
+ POLYGON *p;
+
+ p = (POLYGON *) PALLOCTYPE(POLYGON);
+
+ if (!PointerIsValid(p))
+ elog(WARN, "Cannot allocate polygon for union");
+
+ memset((char *) p, 0, sizeof(POLYGON)); /* zero any holes */
+ p->size = sizeof(POLYGON);
+ p->npts = 0;
+ p->boundbox.high.x = Max(a->boundbox.high.x, b->boundbox.high.x);
+ p->boundbox.high.y = Max(a->boundbox.high.y, b->boundbox.high.y);
+ p->boundbox.low.x = Min(a->boundbox.low.x, b->boundbox.low.x);
+ p->boundbox.low.y = Min(a->boundbox.low.y, b->boundbox.low.y);
+ return p;
}
void
-rt_poly_size(POLYGON *a, float *size)
+rt_poly_size(POLYGON * a, float *size)
{
- double xdim, ydim;
-
- size = (float *) palloc(sizeof(float));
- if (a == (POLYGON *) NULL ||
- a->boundbox.high.x <= a->boundbox.low.x ||
- a->boundbox.high.y <= a->boundbox.low.y)
- *size = 0.0;
- else {
- xdim = (a->boundbox.high.x - a->boundbox.low.x);
- ydim = (a->boundbox.high.y - a->boundbox.low.y);
-
- *size = (float) (xdim * ydim);
- }
-
- return;
+ double xdim,
+ ydim;
+
+ size = (float *) palloc(sizeof(float));
+ if (a == (POLYGON *) NULL ||
+ a->boundbox.high.x <= a->boundbox.low.x ||
+ a->boundbox.high.y <= a->boundbox.low.y)
+ *size = 0.0;
+ else
+ {
+ xdim = (a->boundbox.high.x - a->boundbox.low.x);
+ ydim = (a->boundbox.high.y - a->boundbox.low.y);
+
+ *size = (float) (xdim * ydim);
+ }
+
+ return;
}
-POLYGON *
-rt_poly_inter(POLYGON *a, POLYGON *b)
+POLYGON *
+rt_poly_inter(POLYGON * a, POLYGON * b)
{
- POLYGON *p;
-
- p = (POLYGON *) PALLOCTYPE(POLYGON);
-
- if (!PointerIsValid(p))
- elog(WARN, "Cannot allocate polygon for intersection");
-
- memset((char *) p, 0, sizeof(POLYGON)); /* zero any holes */
- p->size = sizeof(POLYGON);
- p->npts = 0;
- p->boundbox.high.x = Min(a->boundbox.high.x, b->boundbox.high.x);
- p->boundbox.high.y = Min(a->boundbox.high.y, b->boundbox.high.y);
- p->boundbox.low.x = Max(a->boundbox.low.x, b->boundbox.low.x);
- p->boundbox.low.y = Max(a->boundbox.low.y, b->boundbox.low.y);
-
- if (p->boundbox.high.x < p->boundbox.low.x || p->boundbox.high.y < p->boundbox.low.y)
+ POLYGON *p;
+
+ p = (POLYGON *) PALLOCTYPE(POLYGON);
+
+ if (!PointerIsValid(p))
+ elog(WARN, "Cannot allocate polygon for intersection");
+
+ memset((char *) p, 0, sizeof(POLYGON)); /* zero any holes */
+ p->size = sizeof(POLYGON);
+ p->npts = 0;
+ p->boundbox.high.x = Min(a->boundbox.high.x, b->boundbox.high.x);
+ p->boundbox.high.y = Min(a->boundbox.high.y, b->boundbox.high.y);
+ p->boundbox.low.x = Max(a->boundbox.low.x, b->boundbox.low.x);
+ p->boundbox.low.y = Max(a->boundbox.low.y, b->boundbox.low.y);
+
+ if (p->boundbox.high.x < p->boundbox.low.x || p->boundbox.high.y < p->boundbox.low.y)
{
- pfree(p);
- return ((POLYGON *) NULL);
+ pfree(p);
+ return ((POLYGON *) NULL);
}
-
- return (p);
+
+ return (p);
}
diff --git a/src/backend/access/rtree/rtree.c b/src/backend/access/rtree/rtree.c
index 4cd0580c973..ae92ea20136 100644
--- a/src/backend/access/rtree/rtree.c
+++ b/src/backend/access/rtree/rtree.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rtree.c--
- * interface routines for the postgres rtree indexed access method.
+ * interface routines for the postgres rtree indexed access method.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.13 1997/08/12 22:51:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.14 1997/09/07 04:39:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,886 +27,983 @@
#include <storage/bufpage.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-typedef struct SPLITVEC {
- OffsetNumber *spl_left;
- int spl_nleft;
- char *spl_ldatum;
- OffsetNumber *spl_right;
- int spl_nright;
- char *spl_rdatum;
-} SPLITVEC;
-
-typedef struct RTSTATE {
- func_ptr unionFn; /* union function */
- func_ptr sizeFn; /* size function */
- func_ptr interFn; /* intersection function */
-} RTSTATE;
+typedef struct SPLITVEC
+{
+ OffsetNumber *spl_left;
+ int spl_nleft;
+ char *spl_ldatum;
+ OffsetNumber *spl_right;
+ int spl_nright;
+ char *spl_rdatum;
+} SPLITVEC;
+
+typedef struct RTSTATE
+{
+ func_ptr unionFn; /* union function */
+ func_ptr sizeFn; /* size function */
+ func_ptr interFn; /* intersection function */
+} RTSTATE;
/* non-export function prototypes */
-static InsertIndexResult rtdoinsert(Relation r, IndexTuple itup,
- RTSTATE *rtstate);
-static void rttighten(Relation r, RTSTACK *stk, char *datum, int att_size,
- RTSTATE *rtstate);
-static InsertIndexResult dosplit(Relation r, Buffer buffer, RTSTACK *stack,
- IndexTuple itup, RTSTATE *rtstate);
-static void rtintinsert(Relation r, RTSTACK *stk, IndexTuple ltup,
- IndexTuple rtup, RTSTATE *rtstate);
-static void rtnewroot(Relation r, IndexTuple lt, IndexTuple rt);
-static void picksplit(Relation r, Page page, SPLITVEC *v, IndexTuple itup,
- RTSTATE *rtstate);
-static void RTInitBuffer(Buffer b, uint32 f);
-static OffsetNumber choose(Relation r, Page p, IndexTuple it,
- RTSTATE *rtstate);
-static int nospace(Page p, IndexTuple it);
-static void initRtstate(RTSTATE *rtstate, Relation index);
+static InsertIndexResult
+rtdoinsert(Relation r, IndexTuple itup,
+ RTSTATE * rtstate);
+static void
+rttighten(Relation r, RTSTACK * stk, char *datum, int att_size,
+ RTSTATE * rtstate);
+static InsertIndexResult
+dosplit(Relation r, Buffer buffer, RTSTACK * stack,
+ IndexTuple itup, RTSTATE * rtstate);
+static void
+rtintinsert(Relation r, RTSTACK * stk, IndexTuple ltup,
+ IndexTuple rtup, RTSTATE * rtstate);
+static void rtnewroot(Relation r, IndexTuple lt, IndexTuple rt);
+static void
+picksplit(Relation r, Page page, SPLITVEC * v, IndexTuple itup,
+ RTSTATE * rtstate);
+static void RTInitBuffer(Buffer b, uint32 f);
+static OffsetNumber
+choose(Relation r, Page p, IndexTuple it,
+ RTSTATE * rtstate);
+static int nospace(Page p, IndexTuple it);
+static void initRtstate(RTSTATE * rtstate, Relation index);
void
rtbuild(Relation heap,
- Relation index,
- int natts,
- AttrNumber *attnum,
- IndexStrategy istrat,
- uint16 pcount,
- Datum *params,
- FuncIndexInfo *finfo,
- PredInfo *predInfo)
+ Relation index,
+ int natts,
+ AttrNumber * attnum,
+ IndexStrategy istrat,
+ uint16 pcount,
+ Datum * params,
+ FuncIndexInfo * finfo,
+ PredInfo * predInfo)
{
- HeapScanDesc scan;
- Buffer buffer;
- AttrNumber i;
- HeapTuple htup;
- IndexTuple itup;
- TupleDesc hd, id;
- InsertIndexResult res;
- Datum *d;
- bool *nulls;
- int nb, nh, ni;
+ HeapScanDesc scan;
+ Buffer buffer;
+ AttrNumber i;
+ HeapTuple htup;
+ IndexTuple itup;
+ TupleDesc hd,
+ id;
+ InsertIndexResult res;
+ Datum *d;
+ bool *nulls;
+ int nb,
+ nh,
+ ni;
+
#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext;
- TupleTable tupleTable;
- TupleTableSlot *slot;
+ ExprContext *econtext;
+ TupleTable tupleTable;
+ TupleTableSlot *slot;
+
#endif
- Oid hrelid, irelid;
- Node *pred, *oldPred;
- RTSTATE rtState;
-
- initRtstate(&rtState, index);
-
- /* rtrees only know how to do stupid locking now */
- RelationSetLockForWrite(index);
-
- pred = predInfo->pred;
- oldPred = predInfo->oldPred;
-
- /*
- * We expect to be called exactly once for any index relation.
- * If that's not the case, big trouble's what we have.
- */
-
- if (oldPred == NULL && (nb = RelationGetNumberOfBlocks(index)) != 0)
- elog(WARN, "%s already contains data", index->rd_rel->relname.data);
-
- /* initialize the root page (if this is a new index) */
- if (oldPred == NULL) {
- buffer = ReadBuffer(index, P_NEW);
- RTInitBuffer(buffer, F_LEAF);
- WriteBuffer(buffer);
- }
-
- /* init the tuple descriptors and get set for a heap scan */
- hd = RelationGetTupleDescriptor(heap);
- id = RelationGetTupleDescriptor(index);
- d = (Datum *)palloc(natts * sizeof (*d));
- nulls = (bool *)palloc(natts * sizeof (*nulls));
-
- /*
- * If this is a predicate (partial) index, we will need to evaluate the
- * predicate using ExecQual, which requires the current tuple to be in a
- * slot of a TupleTable. In addition, ExecQual must have an ExprContext
- * referring to that slot. Here, we initialize dummy TupleTable and
- * ExprContext objects for this purpose. --Nels, Feb '92
- */
+ Oid hrelid,
+ irelid;
+ Node *pred,
+ *oldPred;
+ RTSTATE rtState;
+
+ initRtstate(&rtState, index);
+
+ /* rtrees only know how to do stupid locking now */
+ RelationSetLockForWrite(index);
+
+ pred = predInfo->pred;
+ oldPred = predInfo->oldPred;
+
+ /*
+ * We expect to be called exactly once for any index relation. If
+ * that's not the case, big trouble's what we have.
+ */
+
+ if (oldPred == NULL && (nb = RelationGetNumberOfBlocks(index)) != 0)
+ elog(WARN, "%s already contains data", index->rd_rel->relname.data);
+
+ /* initialize the root page (if this is a new index) */
+ if (oldPred == NULL)
+ {
+ buffer = ReadBuffer(index, P_NEW);
+ RTInitBuffer(buffer, F_LEAF);
+ WriteBuffer(buffer);
+ }
+
+ /* init the tuple descriptors and get set for a heap scan */
+ hd = RelationGetTupleDescriptor(heap);
+ id = RelationGetTupleDescriptor(index);
+ d = (Datum *) palloc(natts * sizeof(*d));
+ nulls = (bool *) palloc(natts * sizeof(*nulls));
+
+ /*
+ * If this is a predicate (partial) index, we will need to evaluate
+ * the predicate using ExecQual, which requires the current tuple to
+ * be in a slot of a TupleTable. In addition, ExecQual must have an
+ * ExprContext referring to that slot. Here, we initialize dummy
+ * TupleTable and ExprContext objects for this purpose. --Nels, Feb
+ * '92
+ */
#ifndef OMIT_PARTIAL_INDEX
- if (pred != NULL || oldPred != NULL) {
- tupleTable = ExecCreateTupleTable(1);
- slot = ExecAllocTableSlot(tupleTable);
- econtext = makeNode(ExprContext);
- FillDummyExprContext(econtext, slot, hd, buffer);
- }
+ if (pred != NULL || oldPred != NULL)
+ {
+ tupleTable = ExecCreateTupleTable(1);
+ slot = ExecAllocTableSlot(tupleTable);
+ econtext = makeNode(ExprContext);
+ FillDummyExprContext(econtext, slot, hd, buffer);
+ }
else
{
econtext = NULL;
tupleTable = NULL;
slot = NULL;
}
-#endif /* OMIT_PARTIAL_INDEX */
- scan = heap_beginscan(heap, 0, NowTimeQual, 0, (ScanKey) NULL);
- htup = heap_getnext(scan, 0, &buffer);
-
- /* count the tuples as we insert them */
- nh = ni = 0;
-
- for (; HeapTupleIsValid(htup); htup = heap_getnext(scan, 0, &buffer)) {
-
- nh++;
-
- /*
- * If oldPred != NULL, this is an EXTEND INDEX command, so skip
- * this tuple if it was already in the existing partial index
- */
- if (oldPred != NULL) {
+#endif /* OMIT_PARTIAL_INDEX */
+ scan = heap_beginscan(heap, 0, NowTimeQual, 0, (ScanKey) NULL);
+ htup = heap_getnext(scan, 0, &buffer);
+
+ /* count the tuples as we insert them */
+ nh = ni = 0;
+
+ for (; HeapTupleIsValid(htup); htup = heap_getnext(scan, 0, &buffer))
+ {
+
+ nh++;
+
+ /*
+ * If oldPred != NULL, this is an EXTEND INDEX command, so skip
+ * this tuple if it was already in the existing partial index
+ */
+ if (oldPred != NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- /*SetSlotContents(slot, htup); */
- slot->val = htup;
- if (ExecQual((List*)oldPred, econtext) == true) {
+ /* SetSlotContents(slot, htup); */
+ slot->val = htup;
+ if (ExecQual((List *) oldPred, econtext) == true)
+ {
+ ni++;
+ continue;
+ }
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+
+ /*
+ * Skip this tuple if it doesn't satisfy the partial-index
+ * predicate
+ */
+ if (pred != NULL)
+ {
+#ifndef OMIT_PARTIAL_INDEX
+ /* SetSlotContents(slot, htup); */
+ slot->val = htup;
+ if (ExecQual((List *) pred, econtext) == false)
+ continue;
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+
ni++;
- continue;
- }
-#endif /* OMIT_PARTIAL_INDEX */
+
+ /*
+ * For the current heap tuple, extract all the attributes we use
+ * in this index, and note which are null.
+ */
+
+ for (i = 1; i <= natts; i++)
+ {
+ int attoff;
+ bool attnull;
+
+ /*
+ * Offsets are from the start of the tuple, and are
+ * zero-based; indices are one-based. The next call returns i
+ * - 1. That's data hiding for you.
+ */
+
+ attoff = AttrNumberGetAttrOffset(i);
+
+ /*
+ * d[attoff] = HeapTupleGetAttributeValue(htup, buffer,
+ */
+ d[attoff] = GetIndexValue(htup,
+ hd,
+ attoff,
+ attnum,
+ finfo,
+ &attnull,
+ buffer);
+ nulls[attoff] = (attnull ? 'n' : ' ');
+ }
+
+ /* form an index tuple and point it at the heap tuple */
+ itup = index_formtuple(id, &d[0], nulls);
+ itup->t_tid = htup->t_ctid;
+
+ /*
+ * Since we already have the index relation locked, we call
+ * rtdoinsert directly. Normal access method calls dispatch
+ * through rtinsert, which locks the relation for write. This is
+ * the right thing to do if you're inserting single tups, but not
+ * when you're initializing the whole index at once.
+ */
+
+ res = rtdoinsert(index, itup, &rtState);
+ pfree(itup);
+ pfree(res);
}
-
- /* Skip this tuple if it doesn't satisfy the partial-index predicate */
- if (pred != NULL) {
+
+ /* okay, all heap tuples are indexed */
+ heap_endscan(scan);
+ RelationUnsetLockForWrite(index);
+
+ if (pred != NULL || oldPred != NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- /*SetSlotContents(slot, htup); */
- slot->val = htup;
- if (ExecQual((List*)pred, econtext) == false)
- continue;
-#endif /* OMIT_PARTIAL_INDEX */
+ ExecDestroyTupleTable(tupleTable, true);
+ pfree(econtext);
+#endif /* OMIT_PARTIAL_INDEX */
}
-
- ni++;
-
+
/*
- * For the current heap tuple, extract all the attributes
- * we use in this index, and note which are null.
+ * Since we just counted the tuples in the heap, we update its stats
+ * in pg_relation to guarantee that the planner takes advantage of the
+ * index we just created. UpdateStats() does a
+ * CommandCounterIncrement(), which flushes changed entries from the
+ * system relcache. The act of constructing an index changes these
+ * heap and index tuples in the system catalogs, so they need to be
+ * flushed. We close them to guarantee that they will be.
*/
-
- for (i = 1; i <= natts; i++) {
- int attoff;
- bool attnull;
-
- /*
- * Offsets are from the start of the tuple, and are
- * zero-based; indices are one-based. The next call
- * returns i - 1. That's data hiding for you.
- */
-
- attoff = AttrNumberGetAttrOffset(i);
- /*
- d[attoff] = HeapTupleGetAttributeValue(htup, buffer,
- */
- d[attoff] = GetIndexValue(htup,
- hd,
- attoff,
- attnum,
- finfo,
- &attnull,
- buffer);
- nulls[attoff] = (attnull ? 'n' : ' ');
+
+ hrelid = heap->rd_id;
+ irelid = index->rd_id;
+ heap_close(heap);
+ index_close(index);
+
+ UpdateStats(hrelid, nh, true);
+ UpdateStats(irelid, ni, false);
+
+ if (oldPred != NULL)
+ {
+ if (ni == nh)
+ pred = NULL;
+ UpdateIndexPredicate(irelid, oldPred, pred);
}
-
- /* form an index tuple and point it at the heap tuple */
- itup = index_formtuple(id, &d[0], nulls);
- itup->t_tid = htup->t_ctid;
-
- /*
- * Since we already have the index relation locked, we
- * call rtdoinsert directly. Normal access method calls
- * dispatch through rtinsert, which locks the relation
- * for write. This is the right thing to do if you're
- * inserting single tups, but not when you're initializing
- * the whole index at once.
- */
-
- res = rtdoinsert(index, itup, &rtState);
- pfree(itup);
- pfree(res);
- }
-
- /* okay, all heap tuples are indexed */
- heap_endscan(scan);
- RelationUnsetLockForWrite(index);
-
- if (pred != NULL || oldPred != NULL) {
-#ifndef OMIT_PARTIAL_INDEX
- ExecDestroyTupleTable(tupleTable, true);
- pfree(econtext);
-#endif /* OMIT_PARTIAL_INDEX */
- }
-
- /*
- * Since we just counted the tuples in the heap, we update its
- * stats in pg_relation to guarantee that the planner takes
- * advantage of the index we just created. UpdateStats() does a
- * CommandCounterIncrement(), which flushes changed entries from
- * the system relcache. The act of constructing an index changes
- * these heap and index tuples in the system catalogs, so they
- * need to be flushed. We close them to guarantee that they
- * will be.
- */
-
- hrelid = heap->rd_id;
- irelid = index->rd_id;
- heap_close(heap);
- index_close(index);
-
- UpdateStats(hrelid, nh, true);
- UpdateStats(irelid, ni, false);
-
- if (oldPred != NULL) {
- if (ni == nh) pred = NULL;
- UpdateIndexPredicate(irelid, oldPred, pred);
- }
-
- /* be tidy */
- pfree(nulls);
- pfree(d);
+
+ /* be tidy */
+ pfree(nulls);
+ pfree(d);
}
/*
- * rtinsert -- wrapper for rtree tuple insertion.
+ * rtinsert -- wrapper for rtree tuple insertion.
*
- * This is the public interface routine for tuple insertion in rtrees.
- * It doesn't do any work; just locks the relation and passes the buck.
+ * This is the public interface routine for tuple insertion in rtrees.
+ * It doesn't do any work; just locks the relation and passes the buck.
*/
InsertIndexResult
-rtinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
+rtinsert(Relation r, Datum * datum, char *nulls, ItemPointer ht_ctid, Relation heapRel)
{
- InsertIndexResult res;
- IndexTuple itup;
- RTSTATE rtState;
-
- /* generate an index tuple */
- itup = index_formtuple(RelationGetTupleDescriptor(r), datum, nulls);
- itup->t_tid = *ht_ctid;
- initRtstate(&rtState, r);
-
- RelationSetLockForWrite(r);
- res = rtdoinsert(r, itup, &rtState);
-
- /* XXX two-phase locking -- don't unlock the relation until EOT */
- return (res);
+ InsertIndexResult res;
+ IndexTuple itup;
+ RTSTATE rtState;
+
+ /* generate an index tuple */
+ itup = index_formtuple(RelationGetTupleDescriptor(r), datum, nulls);
+ itup->t_tid = *ht_ctid;
+ initRtstate(&rtState, r);
+
+ RelationSetLockForWrite(r);
+ res = rtdoinsert(r, itup, &rtState);
+
+ /* XXX two-phase locking -- don't unlock the relation until EOT */
+ return (res);
}
-static InsertIndexResult
-rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
+static InsertIndexResult
+rtdoinsert(Relation r, IndexTuple itup, RTSTATE * rtstate)
{
- Page page;
- Buffer buffer;
- BlockNumber blk;
- IndexTuple which;
- OffsetNumber l;
- RTSTACK *stack;
- InsertIndexResult res;
- RTreePageOpaque opaque;
- char *datum;
-
- blk = P_ROOT;
- buffer = InvalidBuffer;
- stack = (RTSTACK *) NULL;
-
- do {
- /* let go of current buffer before getting next */
- if (buffer != InvalidBuffer)
- ReleaseBuffer(buffer);
-
- /* get next buffer */
- buffer = ReadBuffer(r, blk);
- page = (Page) BufferGetPage(buffer);
-
- opaque = (RTreePageOpaque) PageGetSpecialPointer(page);
- if (!(opaque->flags & F_LEAF)) {
- RTSTACK *n;
- ItemId iid;
-
- n = (RTSTACK *) palloc(sizeof(RTSTACK));
- n->rts_parent = stack;
- n->rts_blk = blk;
- n->rts_child = choose(r, page, itup, rtstate);
- stack = n;
-
- iid = PageGetItemId(page, n->rts_child);
- which = (IndexTuple) PageGetItem(page, iid);
- blk = ItemPointerGetBlockNumber(&(which->t_tid));
+ Page page;
+ Buffer buffer;
+ BlockNumber blk;
+ IndexTuple which;
+ OffsetNumber l;
+ RTSTACK *stack;
+ InsertIndexResult res;
+ RTreePageOpaque opaque;
+ char *datum;
+
+ blk = P_ROOT;
+ buffer = InvalidBuffer;
+ stack = (RTSTACK *) NULL;
+
+ do
+ {
+ /* let go of current buffer before getting next */
+ if (buffer != InvalidBuffer)
+ ReleaseBuffer(buffer);
+
+ /* get next buffer */
+ buffer = ReadBuffer(r, blk);
+ page = (Page) BufferGetPage(buffer);
+
+ opaque = (RTreePageOpaque) PageGetSpecialPointer(page);
+ if (!(opaque->flags & F_LEAF))
+ {
+ RTSTACK *n;
+ ItemId iid;
+
+ n = (RTSTACK *) palloc(sizeof(RTSTACK));
+ n->rts_parent = stack;
+ n->rts_blk = blk;
+ n->rts_child = choose(r, page, itup, rtstate);
+ stack = n;
+
+ iid = PageGetItemId(page, n->rts_child);
+ which = (IndexTuple) PageGetItem(page, iid);
+ blk = ItemPointerGetBlockNumber(&(which->t_tid));
+ }
+ } while (!(opaque->flags & F_LEAF));
+
+ if (nospace(page, itup))
+ {
+ /* need to do a split */
+ res = dosplit(r, buffer, stack, itup, rtstate);
+ freestack(stack);
+ WriteBuffer(buffer); /* don't forget to release buffer! */
+ return (res);
+ }
+
+ /* add the item and write the buffer */
+ if (PageIsEmpty(page))
+ {
+ l = PageAddItem(page, (Item) itup, IndexTupleSize(itup),
+ FirstOffsetNumber,
+ LP_USED);
}
- } while (!(opaque->flags & F_LEAF));
-
- if (nospace(page, itup)) {
- /* need to do a split */
- res = dosplit(r, buffer, stack, itup, rtstate);
+ else
+ {
+ l = PageAddItem(page, (Item) itup, IndexTupleSize(itup),
+ OffsetNumberNext(PageGetMaxOffsetNumber(page)),
+ LP_USED);
+ }
+
+ WriteBuffer(buffer);
+
+ datum = (((char *) itup) + sizeof(IndexTupleData));
+
+ /* now expand the page boundary in the parent to include the new child */
+ rttighten(r, stack, datum,
+ (IndexTupleSize(itup) - sizeof(IndexTupleData)), rtstate);
freestack(stack);
- WriteBuffer(buffer); /* don't forget to release buffer! */
+
+ /* build and return an InsertIndexResult for this insertion */
+ res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
+ ItemPointerSet(&(res->pointerData), blk, l);
+
return (res);
- }
-
- /* add the item and write the buffer */
- if (PageIsEmpty(page)) {
- l = PageAddItem(page, (Item) itup, IndexTupleSize(itup),
- FirstOffsetNumber,
- LP_USED);
- } else {
- l = PageAddItem(page, (Item) itup, IndexTupleSize(itup),
- OffsetNumberNext(PageGetMaxOffsetNumber(page)),
- LP_USED);
- }
-
- WriteBuffer(buffer);
-
- datum = (((char *) itup) + sizeof(IndexTupleData));
-
- /* now expand the page boundary in the parent to include the new child */
- rttighten(r, stack, datum,
- (IndexTupleSize(itup) - sizeof(IndexTupleData)), rtstate);
- freestack(stack);
-
- /* build and return an InsertIndexResult for this insertion */
- res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
- ItemPointerSet(&(res->pointerData), blk, l);
-
- return (res);
}
static void
rttighten(Relation r,
- RTSTACK *stk,
- char *datum,
- int att_size,
- RTSTATE *rtstate)
+ RTSTACK * stk,
+ char *datum,
+ int att_size,
+ RTSTATE * rtstate)
{
- char *oldud;
- char *tdatum;
- Page p;
- float old_size, newd_size;
- Buffer b;
-
- if (stk == (RTSTACK *) NULL)
- return;
-
- b = ReadBuffer(r, stk->rts_blk);
- p = BufferGetPage(b);
-
- oldud = (char *) PageGetItem(p, PageGetItemId(p, stk->rts_child));
- oldud += sizeof(IndexTupleData);
-
- (*rtstate->sizeFn)(oldud, &old_size);
- datum = (char *) (*rtstate->unionFn)(oldud, datum);
-
- (*rtstate->sizeFn)(datum, &newd_size);
-
- if (newd_size != old_size) {
- TupleDesc td = RelationGetTupleDescriptor(r);
-
- if (td->attrs[0]->attlen < 0) {
- /*
- * This is an internal page, so 'oldud' had better be a
- * union (constant-length) key, too. (See comment below.)
- */
- Assert(VARSIZE(datum) == VARSIZE(oldud));
- memmove(oldud, datum, VARSIZE(datum));
- } else {
- memmove(oldud, datum, att_size);
+ char *oldud;
+ char *tdatum;
+ Page p;
+ float old_size,
+ newd_size;
+ Buffer b;
+
+ if (stk == (RTSTACK *) NULL)
+ return;
+
+ b = ReadBuffer(r, stk->rts_blk);
+ p = BufferGetPage(b);
+
+ oldud = (char *) PageGetItem(p, PageGetItemId(p, stk->rts_child));
+ oldud += sizeof(IndexTupleData);
+
+ (*rtstate->sizeFn) (oldud, &old_size);
+ datum = (char *) (*rtstate->unionFn) (oldud, datum);
+
+ (*rtstate->sizeFn) (datum, &newd_size);
+
+ if (newd_size != old_size)
+ {
+ TupleDesc td = RelationGetTupleDescriptor(r);
+
+ if (td->attrs[0]->attlen < 0)
+ {
+
+ /*
+ * This is an internal page, so 'oldud' had better be a union
+ * (constant-length) key, too. (See comment below.)
+ */
+ Assert(VARSIZE(datum) == VARSIZE(oldud));
+ memmove(oldud, datum, VARSIZE(datum));
+ }
+ else
+ {
+ memmove(oldud, datum, att_size);
+ }
+ WriteBuffer(b);
+
+ /*
+ * The user may be defining an index on variable-sized data (like
+ * polygons). If so, we need to get a constant-sized datum for
+ * insertion on the internal page. We do this by calling the
+ * union proc, which is guaranteed to return a rectangle.
+ */
+
+ tdatum = (char *) (*rtstate->unionFn) (datum, datum);
+ rttighten(r, stk->rts_parent, tdatum, att_size, rtstate);
+ pfree(tdatum);
}
- WriteBuffer(b);
-
- /*
- * The user may be defining an index on variable-sized data (like
- * polygons). If so, we need to get a constant-sized datum for
- * insertion on the internal page. We do this by calling the union
- * proc, which is guaranteed to return a rectangle.
- */
-
- tdatum = (char *) (*rtstate->unionFn)(datum, datum);
- rttighten(r, stk->rts_parent, tdatum, att_size, rtstate);
- pfree(tdatum);
- } else {
- ReleaseBuffer(b);
- }
- pfree(datum);
+ else
+ {
+ ReleaseBuffer(b);
+ }
+ pfree(datum);
}
/*
- * dosplit -- split a page in the tree.
+ * dosplit -- split a page in the tree.
*
- * This is the quadratic-cost split algorithm Guttman describes in
- * his paper. The reason we chose it is that you can implement this
- * with less information about the data types on which you're operating.
+ * This is the quadratic-cost split algorithm Guttman describes in
+ * his paper. The reason we chose it is that you can implement this
+ * with less information about the data types on which you're operating.
*/
-static InsertIndexResult
+static InsertIndexResult
dosplit(Relation r,
- Buffer buffer,
- RTSTACK *stack,
- IndexTuple itup,
- RTSTATE *rtstate)
+ Buffer buffer,
+ RTSTACK * stack,
+ IndexTuple itup,
+ RTSTATE * rtstate)
{
- Page p;
- Buffer leftbuf, rightbuf;
- Page left, right;
- ItemId itemid;
- IndexTuple item;
- IndexTuple ltup, rtup;
- OffsetNumber maxoff;
- OffsetNumber i;
- OffsetNumber leftoff, rightoff;
- BlockNumber lbknum, rbknum;
- BlockNumber bufblock;
- RTreePageOpaque opaque;
- int blank;
- InsertIndexResult res;
- char *isnull;
- SPLITVEC v;
- TupleDesc tupDesc;
-
- isnull = (char *) palloc(r->rd_rel->relnatts);
- for (blank = 0; blank < r->rd_rel->relnatts; blank++)
- isnull[blank] = ' ';
- p = (Page) BufferGetPage(buffer);
- opaque = (RTreePageOpaque) PageGetSpecialPointer(p);
-
- /*
- * The root of the tree is the first block in the relation. If
- * we're about to split the root, we need to do some hocus-pocus
- * to enforce this guarantee.
- */
-
- if (BufferGetBlockNumber(buffer) == P_ROOT) {
- leftbuf = ReadBuffer(r, P_NEW);
- RTInitBuffer(leftbuf, opaque->flags);
- lbknum = BufferGetBlockNumber(leftbuf);
- left = (Page) BufferGetPage(leftbuf);
- } else {
- leftbuf = buffer;
- IncrBufferRefCount(buffer);
- lbknum = BufferGetBlockNumber(buffer);
- left = (Page) PageGetTempPage(p, sizeof(RTreePageOpaqueData));
- }
-
- rightbuf = ReadBuffer(r, P_NEW);
- RTInitBuffer(rightbuf, opaque->flags);
- rbknum = BufferGetBlockNumber(rightbuf);
- right = (Page) BufferGetPage(rightbuf);
-
- picksplit(r, p, &v, itup, rtstate);
-
- leftoff = rightoff = FirstOffsetNumber;
- maxoff = PageGetMaxOffsetNumber(p);
- for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
- itemid = PageGetItemId(p, i);
- item = (IndexTuple) PageGetItem(p, itemid);
-
- if (i == *(v.spl_left)) {
- PageAddItem(left, (Item) item, IndexTupleSize(item),
- leftoff, LP_USED);
- leftoff = OffsetNumberNext(leftoff);
- v.spl_left++; /* advance in left split vector */
- } else {
- PageAddItem(right, (Item) item, IndexTupleSize(item),
- rightoff, LP_USED);
- rightoff = OffsetNumberNext(rightoff);
- v.spl_right++; /* advance in right split vector */
+ Page p;
+ Buffer leftbuf,
+ rightbuf;
+ Page left,
+ right;
+ ItemId itemid;
+ IndexTuple item;
+ IndexTuple ltup,
+ rtup;
+ OffsetNumber maxoff;
+ OffsetNumber i;
+ OffsetNumber leftoff,
+ rightoff;
+ BlockNumber lbknum,
+ rbknum;
+ BlockNumber bufblock;
+ RTreePageOpaque opaque;
+ int blank;
+ InsertIndexResult res;
+ char *isnull;
+ SPLITVEC v;
+ TupleDesc tupDesc;
+
+ isnull = (char *) palloc(r->rd_rel->relnatts);
+ for (blank = 0; blank < r->rd_rel->relnatts; blank++)
+ isnull[blank] = ' ';
+ p = (Page) BufferGetPage(buffer);
+ opaque = (RTreePageOpaque) PageGetSpecialPointer(p);
+
+ /*
+ * The root of the tree is the first block in the relation. If we're
+ * about to split the root, we need to do some hocus-pocus to enforce
+ * this guarantee.
+ */
+
+ if (BufferGetBlockNumber(buffer) == P_ROOT)
+ {
+ leftbuf = ReadBuffer(r, P_NEW);
+ RTInitBuffer(leftbuf, opaque->flags);
+ lbknum = BufferGetBlockNumber(leftbuf);
+ left = (Page) BufferGetPage(leftbuf);
}
- }
-
- /* build an InsertIndexResult for this insertion */
- res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
-
- /* now insert the new index tuple */
- if (*(v.spl_left) != FirstOffsetNumber) {
- PageAddItem(left, (Item) itup, IndexTupleSize(itup),
- leftoff, LP_USED);
- leftoff = OffsetNumberNext(leftoff);
- ItemPointerSet(&(res->pointerData), lbknum, leftoff);
- } else {
- PageAddItem(right, (Item) itup, IndexTupleSize(itup),
- rightoff, LP_USED);
- rightoff = OffsetNumberNext(rightoff);
- ItemPointerSet(&(res->pointerData), rbknum, rightoff);
- }
-
- if ((bufblock = BufferGetBlockNumber(buffer)) != P_ROOT) {
- PageRestoreTempPage(left, p);
- }
- WriteBuffer(leftbuf);
- WriteBuffer(rightbuf);
-
- /*
- * Okay, the page is split. We have three things left to do:
- *
- * 1) Adjust any active scans on this index to cope with changes
- * we introduced in its structure by splitting this page.
- *
- * 2) "Tighten" the bounding box of the pointer to the left
- * page in the parent node in the tree, if any. Since we
- * moved a bunch of stuff off the left page, we expect it
- * to get smaller. This happens in the internal insertion
- * routine.
- *
- * 3) Insert a pointer to the right page in the parent. This
- * may cause the parent to split. If it does, we need to
- * repeat steps one and two for each split node in the tree.
- */
-
- /* adjust active scans */
- rtadjscans(r, RTOP_SPLIT, bufblock, FirstOffsetNumber);
-
- tupDesc = r->rd_att;
- ltup = (IndexTuple) index_formtuple(tupDesc,
- (Datum *) &(v.spl_ldatum), isnull);
- rtup = (IndexTuple) index_formtuple(tupDesc,
- (Datum *) &(v.spl_rdatum), isnull);
- pfree(isnull);
-
- /* set pointers to new child pages in the internal index tuples */
- ItemPointerSet(&(ltup->t_tid), lbknum, 1);
- ItemPointerSet(&(rtup->t_tid), rbknum, 1);
-
- rtintinsert(r, stack, ltup, rtup, rtstate);
-
- pfree(ltup);
- pfree(rtup);
-
- return (res);
+ else
+ {
+ leftbuf = buffer;
+ IncrBufferRefCount(buffer);
+ lbknum = BufferGetBlockNumber(buffer);
+ left = (Page) PageGetTempPage(p, sizeof(RTreePageOpaqueData));
+ }
+
+ rightbuf = ReadBuffer(r, P_NEW);
+ RTInitBuffer(rightbuf, opaque->flags);
+ rbknum = BufferGetBlockNumber(rightbuf);
+ right = (Page) BufferGetPage(rightbuf);
+
+ picksplit(r, p, &v, itup, rtstate);
+
+ leftoff = rightoff = FirstOffsetNumber;
+ maxoff = PageGetMaxOffsetNumber(p);
+ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+ {
+ itemid = PageGetItemId(p, i);
+ item = (IndexTuple) PageGetItem(p, itemid);
+
+ if (i == *(v.spl_left))
+ {
+ PageAddItem(left, (Item) item, IndexTupleSize(item),
+ leftoff, LP_USED);
+ leftoff = OffsetNumberNext(leftoff);
+ v.spl_left++; /* advance in left split vector */
+ }
+ else
+ {
+ PageAddItem(right, (Item) item, IndexTupleSize(item),
+ rightoff, LP_USED);
+ rightoff = OffsetNumberNext(rightoff);
+ v.spl_right++; /* advance in right split vector */
+ }
+ }
+
+ /* build an InsertIndexResult for this insertion */
+ res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
+
+ /* now insert the new index tuple */
+ if (*(v.spl_left) != FirstOffsetNumber)
+ {
+ PageAddItem(left, (Item) itup, IndexTupleSize(itup),
+ leftoff, LP_USED);
+ leftoff = OffsetNumberNext(leftoff);
+ ItemPointerSet(&(res->pointerData), lbknum, leftoff);
+ }
+ else
+ {
+ PageAddItem(right, (Item) itup, IndexTupleSize(itup),
+ rightoff, LP_USED);
+ rightoff = OffsetNumberNext(rightoff);
+ ItemPointerSet(&(res->pointerData), rbknum, rightoff);
+ }
+
+ if ((bufblock = BufferGetBlockNumber(buffer)) != P_ROOT)
+ {
+ PageRestoreTempPage(left, p);
+ }
+ WriteBuffer(leftbuf);
+ WriteBuffer(rightbuf);
+
+ /*
+ * Okay, the page is split. We have three things left to do:
+ *
+ * 1) Adjust any active scans on this index to cope with changes we
+ * introduced in its structure by splitting this page.
+ *
+ * 2) "Tighten" the bounding box of the pointer to the left page in the
+ * parent node in the tree, if any. Since we moved a bunch of stuff
+ * off the left page, we expect it to get smaller. This happens in
+ * the internal insertion routine.
+ *
+ * 3) Insert a pointer to the right page in the parent. This may cause
+ * the parent to split. If it does, we need to repeat steps one and
+ * two for each split node in the tree.
+ */
+
+ /* adjust active scans */
+ rtadjscans(r, RTOP_SPLIT, bufblock, FirstOffsetNumber);
+
+ tupDesc = r->rd_att;
+ ltup = (IndexTuple) index_formtuple(tupDesc,
+ (Datum *) & (v.spl_ldatum), isnull);
+ rtup = (IndexTuple) index_formtuple(tupDesc,
+ (Datum *) & (v.spl_rdatum), isnull);
+ pfree(isnull);
+
+ /* set pointers to new child pages in the internal index tuples */
+ ItemPointerSet(&(ltup->t_tid), lbknum, 1);
+ ItemPointerSet(&(rtup->t_tid), rbknum, 1);
+
+ rtintinsert(r, stack, ltup, rtup, rtstate);
+
+ pfree(ltup);
+ pfree(rtup);
+
+ return (res);
}
static void
rtintinsert(Relation r,
- RTSTACK *stk,
- IndexTuple ltup,
- IndexTuple rtup,
- RTSTATE *rtstate)
+ RTSTACK * stk,
+ IndexTuple ltup,
+ IndexTuple rtup,
+ RTSTATE * rtstate)
{
- IndexTuple old;
- Buffer b;
- Page p;
- char *ldatum, *rdatum, *newdatum;
- InsertIndexResult res;
-
- if (stk == (RTSTACK *) NULL) {
- rtnewroot(r, ltup, rtup);
- return;
- }
-
- b = ReadBuffer(r, stk->rts_blk);
- p = BufferGetPage(b);
- old = (IndexTuple) PageGetItem(p, PageGetItemId(p, stk->rts_child));
-
- /*
- * This is a hack. Right now, we force rtree keys to be constant size.
- * To fix this, need delete the old key and add both left and right
- * for the two new pages. The insertion of left may force a split if
- * the new left key is bigger than the old key.
- */
-
- if (IndexTupleSize(old) != IndexTupleSize(ltup))
- elog(WARN, "Variable-length rtree keys are not supported.");
-
- /* install pointer to left child */
- memmove(old, ltup,IndexTupleSize(ltup));
-
- if (nospace(p, rtup)) {
- newdatum = (((char *) ltup) + sizeof(IndexTupleData));
- rttighten(r, stk->rts_parent, newdatum,
- (IndexTupleSize(ltup) - sizeof(IndexTupleData)), rtstate);
- res = dosplit(r, b, stk->rts_parent, rtup, rtstate);
- WriteBuffer(b); /* don't forget to release buffer! - 01/31/94 */
- pfree(res);
- } else {
- PageAddItem(p, (Item) rtup, IndexTupleSize(rtup),
- PageGetMaxOffsetNumber(p), LP_USED);
- WriteBuffer(b);
- ldatum = (((char *) ltup) + sizeof(IndexTupleData));
- rdatum = (((char *) rtup) + sizeof(IndexTupleData));
- newdatum = (char *) (*rtstate->unionFn)(ldatum, rdatum);
-
- rttighten(r, stk->rts_parent, newdatum,
- (IndexTupleSize(rtup) - sizeof(IndexTupleData)), rtstate);
-
- pfree(newdatum);
- }
+ IndexTuple old;
+ Buffer b;
+ Page p;
+ char *ldatum,
+ *rdatum,
+ *newdatum;
+ InsertIndexResult res;
+
+ if (stk == (RTSTACK *) NULL)
+ {
+ rtnewroot(r, ltup, rtup);
+ return;
+ }
+
+ b = ReadBuffer(r, stk->rts_blk);
+ p = BufferGetPage(b);
+ old = (IndexTuple) PageGetItem(p, PageGetItemId(p, stk->rts_child));
+
+ /*
+ * This is a hack. Right now, we force rtree keys to be constant
+ * size. To fix this, need delete the old key and add both left and
+ * right for the two new pages. The insertion of left may force a
+ * split if the new left key is bigger than the old key.
+ */
+
+ if (IndexTupleSize(old) != IndexTupleSize(ltup))
+ elog(WARN, "Variable-length rtree keys are not supported.");
+
+ /* install pointer to left child */
+ memmove(old, ltup, IndexTupleSize(ltup));
+
+ if (nospace(p, rtup))
+ {
+ newdatum = (((char *) ltup) + sizeof(IndexTupleData));
+ rttighten(r, stk->rts_parent, newdatum,
+ (IndexTupleSize(ltup) - sizeof(IndexTupleData)), rtstate);
+ res = dosplit(r, b, stk->rts_parent, rtup, rtstate);
+ WriteBuffer(b); /* don't forget to release buffer! -
+ * 01/31/94 */
+ pfree(res);
+ }
+ else
+ {
+ PageAddItem(p, (Item) rtup, IndexTupleSize(rtup),
+ PageGetMaxOffsetNumber(p), LP_USED);
+ WriteBuffer(b);
+ ldatum = (((char *) ltup) + sizeof(IndexTupleData));
+ rdatum = (((char *) rtup) + sizeof(IndexTupleData));
+ newdatum = (char *) (*rtstate->unionFn) (ldatum, rdatum);
+
+ rttighten(r, stk->rts_parent, newdatum,
+ (IndexTupleSize(rtup) - sizeof(IndexTupleData)), rtstate);
+
+ pfree(newdatum);
+ }
}
static void
rtnewroot(Relation r, IndexTuple lt, IndexTuple rt)
{
- Buffer b;
- Page p;
-
- b = ReadBuffer(r, P_ROOT);
- RTInitBuffer(b, 0);
- p = BufferGetPage(b);
- PageAddItem(p, (Item) lt, IndexTupleSize(lt),
- FirstOffsetNumber, LP_USED);
- PageAddItem(p, (Item) rt, IndexTupleSize(rt),
- OffsetNumberNext(FirstOffsetNumber), LP_USED);
- WriteBuffer(b);
+ Buffer b;
+ Page p;
+
+ b = ReadBuffer(r, P_ROOT);
+ RTInitBuffer(b, 0);
+ p = BufferGetPage(b);
+ PageAddItem(p, (Item) lt, IndexTupleSize(lt),
+ FirstOffsetNumber, LP_USED);
+ PageAddItem(p, (Item) rt, IndexTupleSize(rt),
+ OffsetNumberNext(FirstOffsetNumber), LP_USED);
+ WriteBuffer(b);
}
static void
picksplit(Relation r,
- Page page,
- SPLITVEC *v,
- IndexTuple itup,
- RTSTATE *rtstate)
+ Page page,
+ SPLITVEC * v,
+ IndexTuple itup,
+ RTSTATE * rtstate)
{
- OffsetNumber maxoff;
- OffsetNumber i, j;
- IndexTuple item_1, item_2;
- char *datum_alpha, *datum_beta;
- char *datum_l, *datum_r;
- char *union_d, *union_dl, *union_dr;
- char *inter_d;
- bool firsttime;
- float size_alpha, size_beta, size_union, size_inter;
- float size_waste, waste;
- float size_l, size_r;
- int nbytes;
- OffsetNumber seed_1 = 0, seed_2 = 0;
- OffsetNumber *left, *right;
-
- maxoff = PageGetMaxOffsetNumber(page);
-
- nbytes = (maxoff + 2) * sizeof(OffsetNumber);
- v->spl_left = (OffsetNumber *) palloc(nbytes);
- v->spl_right = (OffsetNumber *) palloc(nbytes);
-
- firsttime = true;
- waste = 0.0;
-
- for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) {
- item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));
- datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
- for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) {
- item_2 = (IndexTuple) PageGetItem(page, PageGetItemId(page, j));
- datum_beta = ((char *) item_2) + sizeof(IndexTupleData);
-
- /* compute the wasted space by unioning these guys */
- union_d = (char *)(rtstate->unionFn)(datum_alpha, datum_beta);
- (rtstate->sizeFn)(union_d, &size_union);
- inter_d = (char *)(rtstate->interFn)(datum_alpha, datum_beta);
- (rtstate->sizeFn)(inter_d, &size_inter);
- size_waste = size_union - size_inter;
-
- pfree(union_d);
-
- if (inter_d != (char *) NULL)
- pfree(inter_d);
-
- /*
- * are these a more promising split that what we've
- * already seen?
- */
-
- if (size_waste > waste || firsttime) {
- waste = size_waste;
- seed_1 = i;
- seed_2 = j;
- firsttime = false;
- }
+ OffsetNumber maxoff;
+ OffsetNumber i,
+ j;
+ IndexTuple item_1,
+ item_2;
+ char *datum_alpha,
+ *datum_beta;
+ char *datum_l,
+ *datum_r;
+ char *union_d,
+ *union_dl,
+ *union_dr;
+ char *inter_d;
+ bool firsttime;
+ float size_alpha,
+ size_beta,
+ size_union,
+ size_inter;
+ float size_waste,
+ waste;
+ float size_l,
+ size_r;
+ int nbytes;
+ OffsetNumber seed_1 = 0,
+ seed_2 = 0;
+ OffsetNumber *left,
+ *right;
+
+ maxoff = PageGetMaxOffsetNumber(page);
+
+ nbytes = (maxoff + 2) * sizeof(OffsetNumber);
+ v->spl_left = (OffsetNumber *) palloc(nbytes);
+ v->spl_right = (OffsetNumber *) palloc(nbytes);
+
+ firsttime = true;
+ waste = 0.0;
+
+ for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
+ {
+ item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));
+ datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
+ for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
+ {
+ item_2 = (IndexTuple) PageGetItem(page, PageGetItemId(page, j));
+ datum_beta = ((char *) item_2) + sizeof(IndexTupleData);
+
+ /* compute the wasted space by unioning these guys */
+ union_d = (char *) (rtstate->unionFn) (datum_alpha, datum_beta);
+ (rtstate->sizeFn) (union_d, &size_union);
+ inter_d = (char *) (rtstate->interFn) (datum_alpha, datum_beta);
+ (rtstate->sizeFn) (inter_d, &size_inter);
+ size_waste = size_union - size_inter;
+
+ pfree(union_d);
+
+ if (inter_d != (char *) NULL)
+ pfree(inter_d);
+
+ /*
+ * are these a more promising split that what we've already
+ * seen?
+ */
+
+ if (size_waste > waste || firsttime)
+ {
+ waste = size_waste;
+ seed_1 = i;
+ seed_2 = j;
+ firsttime = false;
+ }
+ }
}
- }
-
- left = v->spl_left;
- v->spl_nleft = 0;
- right = v->spl_right;
- v->spl_nright = 0;
-
- item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, seed_1));
- datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
- datum_l = (char *)(*rtstate->unionFn)(datum_alpha, datum_alpha);
- (*rtstate->sizeFn)(datum_l, &size_l);
- item_2 = (IndexTuple) PageGetItem(page, PageGetItemId(page, seed_2));
- datum_beta = ((char *) item_2) + sizeof(IndexTupleData);
- datum_r = (char *)(*rtstate->unionFn)(datum_beta, datum_beta);
- (*rtstate->sizeFn)(datum_r, &size_r);
-
- /*
- * Now split up the regions between the two seeds. An important
- * property of this split algorithm is that the split vector v
- * has the indices of items to be split in order in its left and
- * right vectors. We exploit this property by doing a merge in
- * the code that actually splits the page.
- *
- * For efficiency, we also place the new index tuple in this loop.
- * This is handled at the very end, when we have placed all the
- * existing tuples and i == maxoff + 1.
- */
-
- maxoff = OffsetNumberNext(maxoff);
- for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
-
+
+ left = v->spl_left;
+ v->spl_nleft = 0;
+ right = v->spl_right;
+ v->spl_nright = 0;
+
+ item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, seed_1));
+ datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
+ datum_l = (char *) (*rtstate->unionFn) (datum_alpha, datum_alpha);
+ (*rtstate->sizeFn) (datum_l, &size_l);
+ item_2 = (IndexTuple) PageGetItem(page, PageGetItemId(page, seed_2));
+ datum_beta = ((char *) item_2) + sizeof(IndexTupleData);
+ datum_r = (char *) (*rtstate->unionFn) (datum_beta, datum_beta);
+ (*rtstate->sizeFn) (datum_r, &size_r);
+
/*
- * If we've already decided where to place this item, just
- * put it on the right list. Otherwise, we need to figure
- * out which page needs the least enlargement in order to
- * store the item.
+ * Now split up the regions between the two seeds. An important
+ * property of this split algorithm is that the split vector v has the
+ * indices of items to be split in order in its left and right
+ * vectors. We exploit this property by doing a merge in the code
+ * that actually splits the page.
+ *
+ * For efficiency, we also place the new index tuple in this loop. This
+ * is handled at the very end, when we have placed all the existing
+ * tuples and i == maxoff + 1.
*/
-
- if (i == seed_1) {
- *left++ = i;
- v->spl_nleft++;
- continue;
- } else if (i == seed_2) {
- *right++ = i;
- v->spl_nright++;
- continue;
- }
-
- /* okay, which page needs least enlargement? */
- if (i == maxoff) {
- item_1 = itup;
- } else {
- item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));
- }
-
- datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
- union_dl = (char *)(*rtstate->unionFn)(datum_l, datum_alpha);
- union_dr = (char *)(*rtstate->unionFn)(datum_r, datum_alpha);
- (*rtstate->sizeFn)(union_dl, &size_alpha);
- (*rtstate->sizeFn)(union_dr, &size_beta);
-
- /* pick which page to add it to */
- if (size_alpha - size_l < size_beta - size_r) {
- pfree(datum_l);
- pfree(union_dr);
- datum_l = union_dl;
- size_l = size_alpha;
- *left++ = i;
- v->spl_nleft++;
- } else {
- pfree(datum_r);
- pfree(union_dl);
- datum_r = union_dr;
- size_r = size_alpha;
- *right++ = i;
- v->spl_nright++;
+
+ maxoff = OffsetNumberNext(maxoff);
+ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+ {
+
+ /*
+ * If we've already decided where to place this item, just put it
+ * on the right list. Otherwise, we need to figure out which page
+ * needs the least enlargement in order to store the item.
+ */
+
+ if (i == seed_1)
+ {
+ *left++ = i;
+ v->spl_nleft++;
+ continue;
+ }
+ else if (i == seed_2)
+ {
+ *right++ = i;
+ v->spl_nright++;
+ continue;
+ }
+
+ /* okay, which page needs least enlargement? */
+ if (i == maxoff)
+ {
+ item_1 = itup;
+ }
+ else
+ {
+ item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));
+ }
+
+ datum_alpha = ((char *) item_1) + sizeof(IndexTupleData);
+ union_dl = (char *) (*rtstate->unionFn) (datum_l, datum_alpha);
+ union_dr = (char *) (*rtstate->unionFn) (datum_r, datum_alpha);
+ (*rtstate->sizeFn) (union_dl, &size_alpha);
+ (*rtstate->sizeFn) (union_dr, &size_beta);
+
+ /* pick which page to add it to */
+ if (size_alpha - size_l < size_beta - size_r)
+ {
+ pfree(datum_l);
+ pfree(union_dr);
+ datum_l = union_dl;
+ size_l = size_alpha;
+ *left++ = i;
+ v->spl_nleft++;
+ }
+ else
+ {
+ pfree(datum_r);
+ pfree(union_dl);
+ datum_r = union_dr;
+ size_r = size_alpha;
+ *right++ = i;
+ v->spl_nright++;
+ }
}
- }
- *left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */
-
- v->spl_ldatum = datum_l;
- v->spl_rdatum = datum_r;
+ *left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */
+
+ v->spl_ldatum = datum_l;
+ v->spl_rdatum = datum_r;
}
static void
RTInitBuffer(Buffer b, uint32 f)
{
- RTreePageOpaque opaque;
- Page page;
- Size pageSize;
-
- pageSize = BufferGetPageSize(b);
-
- page = BufferGetPage(b);
- memset(page, 0, (int) pageSize);
- PageInit(page, pageSize, sizeof(RTreePageOpaqueData));
-
- opaque = (RTreePageOpaque) PageGetSpecialPointer(page);
- opaque->flags = f;
+ RTreePageOpaque opaque;
+ Page page;
+ Size pageSize;
+
+ pageSize = BufferGetPageSize(b);
+
+ page = BufferGetPage(b);
+ memset(page, 0, (int) pageSize);
+ PageInit(page, pageSize, sizeof(RTreePageOpaqueData));
+
+ opaque = (RTreePageOpaque) PageGetSpecialPointer(page);
+ opaque->flags = f;
}
-static OffsetNumber
-choose(Relation r, Page p, IndexTuple it, RTSTATE *rtstate)
+static OffsetNumber
+choose(Relation r, Page p, IndexTuple it, RTSTATE * rtstate)
{
- OffsetNumber maxoff;
- OffsetNumber i;
- char *ud, *id;
- char *datum;
- float usize, dsize;
- OffsetNumber which;
- float which_grow;
-
- id = ((char *) it) + sizeof(IndexTupleData);
- maxoff = PageGetMaxOffsetNumber(p);
- which_grow = -1.0;
- which = -1;
-
- for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) {
- datum = (char *) PageGetItem(p, PageGetItemId(p, i));
- datum += sizeof(IndexTupleData);
- (*rtstate->sizeFn)(datum, &dsize);
- ud = (char *) (*rtstate->unionFn)(datum, id);
- (*rtstate->sizeFn)(ud, &usize);
- pfree(ud);
- if (which_grow < 0 || usize - dsize < which_grow) {
- which = i;
- which_grow = usize - dsize;
- if (which_grow == 0)
- break;
+ OffsetNumber maxoff;
+ OffsetNumber i;
+ char *ud,
+ *id;
+ char *datum;
+ float usize,
+ dsize;
+ OffsetNumber which;
+ float which_grow;
+
+ id = ((char *) it) + sizeof(IndexTupleData);
+ maxoff = PageGetMaxOffsetNumber(p);
+ which_grow = -1.0;
+ which = -1;
+
+ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+ {
+ datum = (char *) PageGetItem(p, PageGetItemId(p, i));
+ datum += sizeof(IndexTupleData);
+ (*rtstate->sizeFn) (datum, &dsize);
+ ud = (char *) (*rtstate->unionFn) (datum, id);
+ (*rtstate->sizeFn) (ud, &usize);
+ pfree(ud);
+ if (which_grow < 0 || usize - dsize < which_grow)
+ {
+ which = i;
+ which_grow = usize - dsize;
+ if (which_grow == 0)
+ break;
+ }
}
- }
-
- return (which);
+
+ return (which);
}
static int
nospace(Page p, IndexTuple it)
{
- return (PageGetFreeSpace(p) < IndexTupleSize(it));
+ return (PageGetFreeSpace(p) < IndexTupleSize(it));
}
void
-freestack(RTSTACK *s)
+freestack(RTSTACK * s)
{
- RTSTACK *p;
-
- while (s != (RTSTACK *) NULL) {
- p = s->rts_parent;
- pfree(s);
- s = p;
- }
+ RTSTACK *p;
+
+ while (s != (RTSTACK *) NULL)
+ {
+ p = s->rts_parent;
+ pfree(s);
+ s = p;
+ }
}
-char *
+char *
rtdelete(Relation r, ItemPointer tid)
{
- BlockNumber blkno;
- OffsetNumber offnum;
- Buffer buf;
- Page page;
-
- /* must write-lock on delete */
- RelationSetLockForWrite(r);
-
- blkno = ItemPointerGetBlockNumber(tid);
- offnum = ItemPointerGetOffsetNumber(tid);
-
- /* adjust any scans that will be affected by this deletion */
- rtadjscans(r, RTOP_DEL, blkno, offnum);
-
- /* delete the index tuple */
- buf = ReadBuffer(r, blkno);
- page = BufferGetPage(buf);
-
- PageIndexTupleDelete(page, offnum);
-
- WriteBuffer(buf);
-
- /* XXX -- two-phase locking, don't release the write lock */
- return ((char *) NULL);
+ BlockNumber blkno;
+ OffsetNumber offnum;
+ Buffer buf;
+ Page page;
+
+ /* must write-lock on delete */
+ RelationSetLockForWrite(r);
+
+ blkno = ItemPointerGetBlockNumber(tid);
+ offnum = ItemPointerGetOffsetNumber(tid);
+
+ /* adjust any scans that will be affected by this deletion */
+ rtadjscans(r, RTOP_DEL, blkno, offnum);
+
+ /* delete the index tuple */
+ buf = ReadBuffer(r, blkno);
+ page = BufferGetPage(buf);
+
+ PageIndexTupleDelete(page, offnum);
+
+ WriteBuffer(buf);
+
+ /* XXX -- two-phase locking, don't release the write lock */
+ return ((char *) NULL);
}
-static void initRtstate(RTSTATE *rtstate, Relation index)
+static void
+initRtstate(RTSTATE * rtstate, Relation index)
{
- RegProcedure union_proc, size_proc, inter_proc;
- func_ptr user_fn;
- int pronargs;
-
- union_proc = index_getprocid(index, 1, RT_UNION_PROC);
- size_proc = index_getprocid(index, 1, RT_SIZE_PROC);
- inter_proc = index_getprocid(index, 1, RT_INTER_PROC);
- fmgr_info(union_proc, &user_fn, &pronargs);
- rtstate->unionFn = user_fn;
- fmgr_info(size_proc, &user_fn, &pronargs);
- rtstate->sizeFn = user_fn;
- fmgr_info(inter_proc, &user_fn, &pronargs);
- rtstate->interFn = user_fn;
- return;
+ RegProcedure union_proc,
+ size_proc,
+ inter_proc;
+ func_ptr user_fn;
+ int pronargs;
+
+ union_proc = index_getprocid(index, 1, RT_UNION_PROC);
+ size_proc = index_getprocid(index, 1, RT_SIZE_PROC);
+ inter_proc = index_getprocid(index, 1, RT_INTER_PROC);
+ fmgr_info(union_proc, &user_fn, &pronargs);
+ rtstate->unionFn = user_fn;
+ fmgr_info(size_proc, &user_fn, &pronargs);
+ rtstate->sizeFn = user_fn;
+ fmgr_info(inter_proc, &user_fn, &pronargs);
+ rtstate->interFn = user_fn;
+ return;
}
#ifdef RTDEBUG
@@ -914,48 +1011,52 @@ static void initRtstate(RTSTATE *rtstate, Relation index)
void
_rtdump(Relation r)
{
- Buffer buf;
- Page page;
- OffsetNumber offnum, maxoff;
- BlockNumber blkno;
- BlockNumber nblocks;
- RTreePageOpaque po;
- IndexTuple itup;
- BlockNumber itblkno;
- OffsetNumber itoffno;
- char *datum;
- char *itkey;
-
- nblocks = RelationGetNumberOfBlocks(r);
- for (blkno = 0; blkno < nblocks; blkno++) {
- buf = ReadBuffer(r, blkno);
- page = BufferGetPage(buf);
- po = (RTreePageOpaque) PageGetSpecialPointer(page);
- maxoff = PageGetMaxOffsetNumber(page);
- printf("Page %d maxoff %d <%s>\n", blkno, maxoff,
- (po->flags & F_LEAF ? "LEAF" : "INTERNAL"));
-
- if (PageIsEmpty(page)) {
- ReleaseBuffer(buf);
- continue;
- }
-
- for (offnum = FirstOffsetNumber;
- offnum <= maxoff;
- offnum = OffsetNumberNext(offnum)) {
- itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
- itblkno = ItemPointerGetBlockNumber(&(itup->t_tid));
- itoffno = ItemPointerGetOffsetNumber(&(itup->t_tid));
- datum = ((char *) itup);
- datum += sizeof(IndexTupleData);
- itkey = (char *) box_out((BOX *) datum);
- printf("\t[%d] size %d heap <%d,%d> key:%s\n",
- offnum, IndexTupleSize(itup), itblkno, itoffno, itkey);
- pfree(itkey);
+ Buffer buf;
+ Page page;
+ OffsetNumber offnum,
+ maxoff;
+ BlockNumber blkno;
+ BlockNumber nblocks;
+ RTreePageOpaque po;
+ IndexTuple itup;
+ BlockNumber itblkno;
+ OffsetNumber itoffno;
+ char *datum;
+ char *itkey;
+
+ nblocks = RelationGetNumberOfBlocks(r);
+ for (blkno = 0; blkno < nblocks; blkno++)
+ {
+ buf = ReadBuffer(r, blkno);
+ page = BufferGetPage(buf);
+ po = (RTreePageOpaque) PageGetSpecialPointer(page);
+ maxoff = PageGetMaxOffsetNumber(page);
+ printf("Page %d maxoff %d <%s>\n", blkno, maxoff,
+ (po->flags & F_LEAF ? "LEAF" : "INTERNAL"));
+
+ if (PageIsEmpty(page))
+ {
+ ReleaseBuffer(buf);
+ continue;
+ }
+
+ for (offnum = FirstOffsetNumber;
+ offnum <= maxoff;
+ offnum = OffsetNumberNext(offnum))
+ {
+ itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
+ itblkno = ItemPointerGetBlockNumber(&(itup->t_tid));
+ itoffno = ItemPointerGetOffsetNumber(&(itup->t_tid));
+ datum = ((char *) itup);
+ datum += sizeof(IndexTupleData);
+ itkey = (char *) box_out((BOX *) datum);
+ printf("\t[%d] size %d heap <%d,%d> key:%s\n",
+ offnum, IndexTupleSize(itup), itblkno, itoffno, itkey);
+ pfree(itkey);
+ }
+
+ ReleaseBuffer(buf);
}
-
- ReleaseBuffer(buf);
- }
}
-#endif /* defined RTDEBUG */
+#endif /* defined RTDEBUG */
diff --git a/src/backend/access/rtree/rtscan.c b/src/backend/access/rtree/rtscan.c
index bb8e1dcc719..26590059d6c 100644
--- a/src/backend/access/rtree/rtscan.c
+++ b/src/backend/access/rtree/rtscan.c
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* rtscan.c--
- * routines to manage scans on index relations
+ * routines to manage scans on index relations
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.10 1997/05/20 10:29:30 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.11 1997/09/07 04:39:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <storage/bufmgr.h>
#include <access/genam.h>
#include <storage/lmgr.h>
@@ -21,377 +21,411 @@
#include <access/rtree.h>
#include <access/rtstrat.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-
+
/* routines defined and used here */
-static void rtregscan(IndexScanDesc s);
-static void rtdropscan(IndexScanDesc s);
-static void rtadjone(IndexScanDesc s, int op, BlockNumber blkno,
- OffsetNumber offnum);
-static void adjuststack(RTSTACK *stk, BlockNumber blkno,
+static void rtregscan(IndexScanDesc s);
+static void rtdropscan(IndexScanDesc s);
+static void
+rtadjone(IndexScanDesc s, int op, BlockNumber blkno,
+ OffsetNumber offnum);
+static void
+adjuststack(RTSTACK * stk, BlockNumber blkno,
OffsetNumber offnum);
-static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
- int op, BlockNumber blkno, OffsetNumber offnum);
+static void
+adjustiptr(IndexScanDesc s, ItemPointer iptr,
+ int op, BlockNumber blkno, OffsetNumber offnum);
/*
- * Whenever we start an rtree scan in a backend, we register it in private
- * space. Then if the rtree index gets updated, we check all registered
- * scans and adjust them if the tuple they point at got moved by the
- * update. We only need to do this in private space, because when we update
- * an rtree we have a write lock on the tree, so no other process can have
- * any locks at all on it. A single transaction can have write and read
- * locks on the same object, so that's why we need to handle this case.
+ * Whenever we start an rtree scan in a backend, we register it in private
+ * space. Then if the rtree index gets updated, we check all registered
+ * scans and adjust them if the tuple they point at got moved by the
+ * update. We only need to do this in private space, because when we update
+ * an rtree we have a write lock on the tree, so no other process can have
+ * any locks at all on it. A single transaction can have write and read
+ * locks on the same object, so that's why we need to handle this case.
*/
-typedef struct RTScanListData {
- IndexScanDesc rtsl_scan;
- struct RTScanListData *rtsl_next;
-} RTScanListData;
+typedef struct RTScanListData
+{
+ IndexScanDesc rtsl_scan;
+ struct RTScanListData *rtsl_next;
+} RTScanListData;
-typedef RTScanListData *RTScanList;
+typedef RTScanListData *RTScanList;
/* pointer to list of local scans on rtrees */
static RTScanList RTScans = (RTScanList) NULL;
-
+
IndexScanDesc
rtbeginscan(Relation r,
- bool fromEnd,
- uint16 nkeys,
- ScanKey key)
+ bool fromEnd,
+ uint16 nkeys,
+ ScanKey key)
{
- IndexScanDesc s;
-
- RelationSetLockForRead(r);
- s = RelationGetIndexScan(r, fromEnd, nkeys, key);
- rtregscan(s);
-
- return (s);
+ IndexScanDesc s;
+
+ RelationSetLockForRead(r);
+ s = RelationGetIndexScan(r, fromEnd, nkeys, key);
+ rtregscan(s);
+
+ return (s);
}
void
rtrescan(IndexScanDesc s, bool fromEnd, ScanKey key)
{
- RTreeScanOpaque p;
- RegProcedure internal_proc;
- int i;
-
- if (!IndexScanIsValid(s)) {
- elog(WARN, "rtrescan: invalid scan.");
- return;
- }
-
- /*
- * Clear all the pointers.
- */
-
- ItemPointerSetInvalid(&s->previousItemData);
- ItemPointerSetInvalid(&s->currentItemData);
- ItemPointerSetInvalid(&s->nextItemData);
- ItemPointerSetInvalid(&s->previousMarkData);
- ItemPointerSetInvalid(&s->currentMarkData);
- ItemPointerSetInvalid(&s->nextMarkData);
-
- /*
- * Set flags.
- */
- if (RelationGetNumberOfBlocks(s->relation) == 0) {
- s->flags = ScanUnmarked;
- } else if (fromEnd) {
- s->flags = ScanUnmarked | ScanUncheckedPrevious;
- } else {
- s->flags = ScanUnmarked | ScanUncheckedNext;
- }
-
- s->scanFromEnd = fromEnd;
-
- if (s->numberOfKeys > 0) {
- memmove(s->keyData,
- key,
- s->numberOfKeys * sizeof(ScanKeyData));
- }
-
- p = (RTreeScanOpaque) s->opaque;
- if (p != (RTreeScanOpaque) NULL) {
- freestack(p->s_stack);
- freestack(p->s_markstk);
- p->s_stack = p->s_markstk = (RTSTACK *) NULL;
- p->s_flags = 0x0;
- for (i = 0; i < s->numberOfKeys; i++)
+ RTreeScanOpaque p;
+ RegProcedure internal_proc;
+ int i;
+
+ if (!IndexScanIsValid(s))
+ {
+ elog(WARN, "rtrescan: invalid scan.");
+ return;
+ }
+
+ /*
+ * Clear all the pointers.
+ */
+
+ ItemPointerSetInvalid(&s->previousItemData);
+ ItemPointerSetInvalid(&s->currentItemData);
+ ItemPointerSetInvalid(&s->nextItemData);
+ ItemPointerSetInvalid(&s->previousMarkData);
+ ItemPointerSetInvalid(&s->currentMarkData);
+ ItemPointerSetInvalid(&s->nextMarkData);
+
+ /*
+ * Set flags.
+ */
+ if (RelationGetNumberOfBlocks(s->relation) == 0)
+ {
+ s->flags = ScanUnmarked;
+ }
+ else if (fromEnd)
+ {
+ s->flags = ScanUnmarked | ScanUncheckedPrevious;
+ }
+ else
+ {
+ s->flags = ScanUnmarked | ScanUncheckedNext;
+ }
+
+ s->scanFromEnd = fromEnd;
+
+ if (s->numberOfKeys > 0)
{
- p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument;
+ memmove(s->keyData,
+ key,
+ s->numberOfKeys * sizeof(ScanKeyData));
}
- } else {
- /* initialize opaque data */
- p = (RTreeScanOpaque) palloc(sizeof(RTreeScanOpaqueData));
- p->s_stack = p->s_markstk = (RTSTACK *) NULL;
- p->s_internalNKey = s->numberOfKeys;
- p->s_flags = 0x0;
- s->opaque = p;
- if (s->numberOfKeys > 0) {
- p->s_internalKey =
- (ScanKey) palloc(sizeof(ScanKeyData) * s->numberOfKeys);
-
- /*
- * Scans on internal pages use different operators than they
- * do on leaf pages. For example, if the user wants all boxes
- * that exactly match (x1,y1,x2,y2), then on internal pages
- * we need to find all boxes that contain (x1,y1,x2,y2).
- */
-
- for (i = 0; i < s->numberOfKeys; i++) {
- p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument;
- internal_proc = RTMapOperator(s->relation,
- s->keyData[i].sk_attno,
- s->keyData[i].sk_procedure);
- ScanKeyEntryInitialize(&(p->s_internalKey[i]),
- s->keyData[i].sk_flags,
- s->keyData[i].sk_attno,
- internal_proc,
- s->keyData[i].sk_argument);
- }
+
+ p = (RTreeScanOpaque) s->opaque;
+ if (p != (RTreeScanOpaque) NULL)
+ {
+ freestack(p->s_stack);
+ freestack(p->s_markstk);
+ p->s_stack = p->s_markstk = (RTSTACK *) NULL;
+ p->s_flags = 0x0;
+ for (i = 0; i < s->numberOfKeys; i++)
+ {
+ p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument;
+ }
+ }
+ else
+ {
+ /* initialize opaque data */
+ p = (RTreeScanOpaque) palloc(sizeof(RTreeScanOpaqueData));
+ p->s_stack = p->s_markstk = (RTSTACK *) NULL;
+ p->s_internalNKey = s->numberOfKeys;
+ p->s_flags = 0x0;
+ s->opaque = p;
+ if (s->numberOfKeys > 0)
+ {
+ p->s_internalKey =
+ (ScanKey) palloc(sizeof(ScanKeyData) * s->numberOfKeys);
+
+ /*
+ * Scans on internal pages use different operators than they
+ * do on leaf pages. For example, if the user wants all boxes
+ * that exactly match (x1,y1,x2,y2), then on internal pages we
+ * need to find all boxes that contain (x1,y1,x2,y2).
+ */
+
+ for (i = 0; i < s->numberOfKeys; i++)
+ {
+ p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument;
+ internal_proc = RTMapOperator(s->relation,
+ s->keyData[i].sk_attno,
+ s->keyData[i].sk_procedure);
+ ScanKeyEntryInitialize(&(p->s_internalKey[i]),
+ s->keyData[i].sk_flags,
+ s->keyData[i].sk_attno,
+ internal_proc,
+ s->keyData[i].sk_argument);
+ }
+ }
}
- }
}
void
rtmarkpos(IndexScanDesc s)
{
- RTreeScanOpaque p;
- RTSTACK *o, *n, *tmp;
-
- s->currentMarkData = s->currentItemData;
- p = (RTreeScanOpaque) s->opaque;
- if (p->s_flags & RTS_CURBEFORE)
- p->s_flags |= RTS_MRKBEFORE;
- else
- p->s_flags &= ~RTS_MRKBEFORE;
-
- o = (RTSTACK *) NULL;
- n = p->s_stack;
-
- /* copy the parent stack from the current item data */
- while (n != (RTSTACK *) NULL) {
- tmp = (RTSTACK *) palloc(sizeof(RTSTACK));
- tmp->rts_child = n->rts_child;
- tmp->rts_blk = n->rts_blk;
- tmp->rts_parent = o;
- o = tmp;
- n = n->rts_parent;
- }
-
- freestack(p->s_markstk);
- p->s_markstk = o;
+ RTreeScanOpaque p;
+ RTSTACK *o,
+ *n,
+ *tmp;
+
+ s->currentMarkData = s->currentItemData;
+ p = (RTreeScanOpaque) s->opaque;
+ if (p->s_flags & RTS_CURBEFORE)
+ p->s_flags |= RTS_MRKBEFORE;
+ else
+ p->s_flags &= ~RTS_MRKBEFORE;
+
+ o = (RTSTACK *) NULL;
+ n = p->s_stack;
+
+ /* copy the parent stack from the current item data */
+ while (n != (RTSTACK *) NULL)
+ {
+ tmp = (RTSTACK *) palloc(sizeof(RTSTACK));
+ tmp->rts_child = n->rts_child;
+ tmp->rts_blk = n->rts_blk;
+ tmp->rts_parent = o;
+ o = tmp;
+ n = n->rts_parent;
+ }
+
+ freestack(p->s_markstk);
+ p->s_markstk = o;
}
void
rtrestrpos(IndexScanDesc s)
{
- RTreeScanOpaque p;
- RTSTACK *o, *n, *tmp;
-
- s->currentItemData = s->currentMarkData;
- p = (RTreeScanOpaque) s->opaque;
- if (p->s_flags & RTS_MRKBEFORE)
- p->s_flags |= RTS_CURBEFORE;
- else
- p->s_flags &= ~RTS_CURBEFORE;
-
- o = (RTSTACK *) NULL;
- n = p->s_markstk;
-
- /* copy the parent stack from the current item data */
- while (n != (RTSTACK *) NULL) {
- tmp = (RTSTACK *) palloc(sizeof(RTSTACK));
- tmp->rts_child = n->rts_child;
- tmp->rts_blk = n->rts_blk;
- tmp->rts_parent = o;
- o = tmp;
- n = n->rts_parent;
- }
-
- freestack(p->s_stack);
- p->s_stack = o;
+ RTreeScanOpaque p;
+ RTSTACK *o,
+ *n,
+ *tmp;
+
+ s->currentItemData = s->currentMarkData;
+ p = (RTreeScanOpaque) s->opaque;
+ if (p->s_flags & RTS_MRKBEFORE)
+ p->s_flags |= RTS_CURBEFORE;
+ else
+ p->s_flags &= ~RTS_CURBEFORE;
+
+ o = (RTSTACK *) NULL;
+ n = p->s_markstk;
+
+ /* copy the parent stack from the current item data */
+ while (n != (RTSTACK *) NULL)
+ {
+ tmp = (RTSTACK *) palloc(sizeof(RTSTACK));
+ tmp->rts_child = n->rts_child;
+ tmp->rts_blk = n->rts_blk;
+ tmp->rts_parent = o;
+ o = tmp;
+ n = n->rts_parent;
+ }
+
+ freestack(p->s_stack);
+ p->s_stack = o;
}
void
rtendscan(IndexScanDesc s)
{
- RTreeScanOpaque p;
-
- p = (RTreeScanOpaque) s->opaque;
-
- if (p != (RTreeScanOpaque) NULL) {
- freestack(p->s_stack);
- freestack(p->s_markstk);
- pfree (s->opaque);
- }
-
- rtdropscan(s);
- /* XXX don't unset read lock -- two-phase locking */
+ RTreeScanOpaque p;
+
+ p = (RTreeScanOpaque) s->opaque;
+
+ if (p != (RTreeScanOpaque) NULL)
+ {
+ freestack(p->s_stack);
+ freestack(p->s_markstk);
+ pfree(s->opaque);
+ }
+
+ rtdropscan(s);
+ /* XXX don't unset read lock -- two-phase locking */
}
static void
rtregscan(IndexScanDesc s)
{
- RTScanList l;
-
- l = (RTScanList) palloc(sizeof(RTScanListData));
- l->rtsl_scan = s;
- l->rtsl_next = RTScans;
- RTScans = l;
+ RTScanList l;
+
+ l = (RTScanList) palloc(sizeof(RTScanListData));
+ l->rtsl_scan = s;
+ l->rtsl_next = RTScans;
+ RTScans = l;
}
static void
rtdropscan(IndexScanDesc s)
{
- RTScanList l;
- RTScanList prev;
-
- prev = (RTScanList) NULL;
-
- for (l = RTScans;
- l != (RTScanList) NULL && l->rtsl_scan != s;
- l = l->rtsl_next) {
- prev = l;
- }
-
- if (l == (RTScanList) NULL)
- elog(WARN, "rtree scan list corrupted -- cannot find 0x%lx", s);
-
- if (prev == (RTScanList) NULL)
- RTScans = l->rtsl_next;
- else
- prev->rtsl_next = l->rtsl_next;
-
- pfree(l);
+ RTScanList l;
+ RTScanList prev;
+
+ prev = (RTScanList) NULL;
+
+ for (l = RTScans;
+ l != (RTScanList) NULL && l->rtsl_scan != s;
+ l = l->rtsl_next)
+ {
+ prev = l;
+ }
+
+ if (l == (RTScanList) NULL)
+ elog(WARN, "rtree scan list corrupted -- cannot find 0x%lx", s);
+
+ if (prev == (RTScanList) NULL)
+ RTScans = l->rtsl_next;
+ else
+ prev->rtsl_next = l->rtsl_next;
+
+ pfree(l);
}
void
rtadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum)
{
- RTScanList l;
- Oid relid;
-
- relid = r->rd_id;
- for (l = RTScans; l != (RTScanList) NULL; l = l->rtsl_next) {
- if (l->rtsl_scan->relation->rd_id == relid)
- rtadjone(l->rtsl_scan, op, blkno, offnum);
- }
+ RTScanList l;
+ Oid relid;
+
+ relid = r->rd_id;
+ for (l = RTScans; l != (RTScanList) NULL; l = l->rtsl_next)
+ {
+ if (l->rtsl_scan->relation->rd_id == relid)
+ rtadjone(l->rtsl_scan, op, blkno, offnum);
+ }
}
/*
- * rtadjone() -- adjust one scan for update.
+ * rtadjone() -- adjust one scan for update.
*
- * By here, the scan passed in is on a modified relation. Op tells
- * us what the modification is, and blkno and offind tell us what
- * block and offset index were affected. This routine checks the
- * current and marked positions, and the current and marked stacks,
- * to see if any stored location needs to be changed because of the
- * update. If so, we make the change here.
+ * By here, the scan passed in is on a modified relation. Op tells
+ * us what the modification is, and blkno and offind tell us what
+ * block and offset index were affected. This routine checks the
+ * current and marked positions, and the current and marked stacks,
+ * to see if any stored location needs to be changed because of the
+ * update. If so, we make the change here.
*/
static void
rtadjone(IndexScanDesc s,
- int op,
- BlockNumber blkno,
- OffsetNumber offnum)
+ int op,
+ BlockNumber blkno,
+ OffsetNumber offnum)
{
- RTreeScanOpaque so;
-
- adjustiptr(s, &(s->currentItemData), op, blkno, offnum);
- adjustiptr(s, &(s->currentMarkData), op, blkno, offnum);
-
- so = (RTreeScanOpaque) s->opaque;
-
- if (op == RTOP_SPLIT) {
- adjuststack(so->s_stack, blkno, offnum);
- adjuststack(so->s_markstk, blkno, offnum);
- }
+ RTreeScanOpaque so;
+
+ adjustiptr(s, &(s->currentItemData), op, blkno, offnum);
+ adjustiptr(s, &(s->currentMarkData), op, blkno, offnum);
+
+ so = (RTreeScanOpaque) s->opaque;
+
+ if (op == RTOP_SPLIT)
+ {
+ adjuststack(so->s_stack, blkno, offnum);
+ adjuststack(so->s_markstk, blkno, offnum);
+ }
}
/*
- * adjustiptr() -- adjust current and marked item pointers in the scan
+ * adjustiptr() -- adjust current and marked item pointers in the scan
*
- * Depending on the type of update and the place it happened, we
- * need to do nothing, to back up one record, or to start over on
- * the same page.
+ * Depending on the type of update and the place it happened, we
+ * need to do nothing, to back up one record, or to start over on
+ * the same page.
*/
static void
adjustiptr(IndexScanDesc s,
- ItemPointer iptr,
- int op,
- BlockNumber blkno,
- OffsetNumber offnum)
+ ItemPointer iptr,
+ int op,
+ BlockNumber blkno,
+ OffsetNumber offnum)
{
- OffsetNumber curoff;
- RTreeScanOpaque so;
-
- if (ItemPointerIsValid(iptr)) {
- if (ItemPointerGetBlockNumber(iptr) == blkno) {
- curoff = ItemPointerGetOffsetNumber(iptr);
- so = (RTreeScanOpaque) s->opaque;
-
- switch (op) {
- case RTOP_DEL:
- /* back up one if we need to */
- if (curoff >= offnum) {
-
- if (curoff > FirstOffsetNumber) {
- /* just adjust the item pointer */
- ItemPointerSet(iptr, blkno, OffsetNumberPrev(curoff));
- } else {
- /* remember that we're before the current tuple */
- ItemPointerSet(iptr, blkno, FirstOffsetNumber);
- if (iptr == &(s->currentItemData))
- so->s_flags |= RTS_CURBEFORE;
- else
- so->s_flags |= RTS_MRKBEFORE;
- }
+ OffsetNumber curoff;
+ RTreeScanOpaque so;
+
+ if (ItemPointerIsValid(iptr))
+ {
+ if (ItemPointerGetBlockNumber(iptr) == blkno)
+ {
+ curoff = ItemPointerGetOffsetNumber(iptr);
+ so = (RTreeScanOpaque) s->opaque;
+
+ switch (op)
+ {
+ case RTOP_DEL:
+ /* back up one if we need to */
+ if (curoff >= offnum)
+ {
+
+ if (curoff > FirstOffsetNumber)
+ {
+ /* just adjust the item pointer */
+ ItemPointerSet(iptr, blkno, OffsetNumberPrev(curoff));
+ }
+ else
+ {
+ /* remember that we're before the current tuple */
+ ItemPointerSet(iptr, blkno, FirstOffsetNumber);
+ if (iptr == &(s->currentItemData))
+ so->s_flags |= RTS_CURBEFORE;
+ else
+ so->s_flags |= RTS_MRKBEFORE;
+ }
+ }
+ break;
+
+ case RTOP_SPLIT:
+ /* back to start of page on split */
+ ItemPointerSet(iptr, blkno, FirstOffsetNumber);
+ if (iptr == &(s->currentItemData))
+ so->s_flags &= ~RTS_CURBEFORE;
+ else
+ so->s_flags &= ~RTS_MRKBEFORE;
+ break;
+
+ default:
+ elog(WARN, "Bad operation in rtree scan adjust: %d", op);
+ }
}
- break;
-
- case RTOP_SPLIT:
- /* back to start of page on split */
- ItemPointerSet(iptr, blkno, FirstOffsetNumber);
- if (iptr == &(s->currentItemData))
- so->s_flags &= ~RTS_CURBEFORE;
- else
- so->s_flags &= ~RTS_MRKBEFORE;
- break;
-
- default:
- elog(WARN, "Bad operation in rtree scan adjust: %d", op);
- }
}
- }
}
/*
- * adjuststack() -- adjust the supplied stack for a split on a page in
- * the index we're scanning.
+ * adjuststack() -- adjust the supplied stack for a split on a page in
+ * the index we're scanning.
*
- * If a page on our parent stack has split, we need to back up to the
- * beginning of the page and rescan it. The reason for this is that
- * the split algorithm for rtrees doesn't order tuples in any useful
- * way on a single page. This means on that a split, we may wind up
- * looking at some heap tuples more than once. This is handled in the
- * access method update code for heaps; if we've modified the tuple we
- * are looking at already in this transaction, we ignore the update
- * request.
+ * If a page on our parent stack has split, we need to back up to the
+ * beginning of the page and rescan it. The reason for this is that
+ * the split algorithm for rtrees doesn't order tuples in any useful
+ * way on a single page. This means on that a split, we may wind up
+ * looking at some heap tuples more than once. This is handled in the
+ * access method update code for heaps; if we've modified the tuple we
+ * are looking at already in this transaction, we ignore the update
+ * request.
*/
/*ARGSUSED*/
static void
-adjuststack(RTSTACK *stk,
- BlockNumber blkno,
- OffsetNumber offnum)
+adjuststack(RTSTACK * stk,
+ BlockNumber blkno,
+ OffsetNumber offnum)
{
- while (stk != (RTSTACK *) NULL) {
- if (stk->rts_blk == blkno)
- stk->rts_child = FirstOffsetNumber;
-
- stk = stk->rts_parent;
- }
+ while (stk != (RTSTACK *) NULL)
+ {
+ if (stk->rts_blk == blkno)
+ stk->rts_child = FirstOffsetNumber;
+
+ stk = stk->rts_parent;
+ }
}
diff --git a/src/backend/access/rtree/rtstrat.c b/src/backend/access/rtree/rtstrat.c
index 7025a30999d..c71059d3f09 100644
--- a/src/backend/access/rtree/rtstrat.c
+++ b/src/backend/access/rtree/rtstrat.c
@@ -1,241 +1,243 @@
/*-------------------------------------------------------------------------
*
* rtstrat.c--
- * strategy map data for rtrees.
+ * strategy map data for rtrees.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.6 1997/08/19 21:29:52 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.7 1997/09/07 04:39:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <utils/rel.h>
#include <access/rtree.h>
#include <access/istrat.h>
-static StrategyNumber RelationGetRTStrategy(Relation r,
- AttrNumber attnum, RegProcedure proc);
+static StrategyNumber
+RelationGetRTStrategy(Relation r,
+ AttrNumber attnum, RegProcedure proc);
/*
- * Note: negate, commute, and negatecommute all assume that operators are
- * ordered as follows in the strategy map:
+ * Note: negate, commute, and negatecommute all assume that operators are
+ * ordered as follows in the strategy map:
*
- * left, left-or-overlap, overlap, right-or-overlap, right, same,
- * contains, contained-by
+ * left, left-or-overlap, overlap, right-or-overlap, right, same,
+ * contains, contained-by
*
- * The negate, commute, and negatecommute arrays are used by the planner
- * to plan indexed scans over data that appears in the qualificiation in
- * a boolean negation, or whose operands appear in the wrong order. For
- * example, if the operator "<%" means "contains", and the user says
+ * The negate, commute, and negatecommute arrays are used by the planner
+ * to plan indexed scans over data that appears in the qualificiation in
+ * a boolean negation, or whose operands appear in the wrong order. For
+ * example, if the operator "<%" means "contains", and the user says
*
- * where not rel.box <% "(10,10,20,20)"::box
+ * where not rel.box <% "(10,10,20,20)"::box
*
- * the planner can plan an index scan by noting that rtree indices have
- * an operator in their operator class for negating <%.
+ * the planner can plan an index scan by noting that rtree indices have
+ * an operator in their operator class for negating <%.
*
- * Similarly, if the user says something like
+ * Similarly, if the user says something like
*
- * where "(10,10,20,20)"::box <% rel.box
+ * where "(10,10,20,20)"::box <% rel.box
*
- * the planner can see that the rtree index on rel.box has an operator in
- * its opclass for commuting <%, and plan the scan using that operator.
- * This added complexity in the access methods makes the planner a lot easier
- * to write.
+ * the planner can see that the rtree index on rel.box has an operator in
+ * its opclass for commuting <%, and plan the scan using that operator.
+ * This added complexity in the access methods makes the planner a lot easier
+ * to write.
*/
/* if a op b, what operator tells us if (not a op b)? */
-static StrategyNumber RTNegate[RTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
- };
+static StrategyNumber RTNegate[RTNStrategies] = {
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy
+};
/* if a op_1 b, what is the operator op_2 such that b op_2 a? */
-static StrategyNumber RTCommute[RTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
- };
+static StrategyNumber RTCommute[RTNStrategies] = {
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy
+};
/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */
-static StrategyNumber RTNegateCommute[RTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
- };
+static StrategyNumber RTNegateCommute[RTNStrategies] = {
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy,
+ InvalidStrategy
+};
/*
- * Now do the TermData arrays. These exist in case the user doesn't give
- * us a full set of operators for a particular operator class. The idea
- * is that by making multiple comparisons using any one of the supplied
- * operators, we can decide whether two n-dimensional polygons are equal.
- * For example, if a contains b and b contains a, we may conclude that
- * a and b are equal.
- *
- * The presence of the TermData arrays in all this is a historical accident.
- * Early in the development of the POSTGRES access methods, it was believed
- * that writing functions was harder than writing arrays. This is wrong;
- * TermData is hard to understand and hard to get right. In general, when
- * someone populates a new operator class, the populate it completely. If
- * Mike Hirohama had forced Cimarron Taylor to populate the strategy map
- * for btree int2_ops completely in 1988, you wouldn't have to deal with
- * all this now. Too bad for you.
- *
- * Since you can't necessarily do this in all cases (for example, you can't
- * do it given only "intersects" or "disjoint"), TermData arrays for some
- * operators don't appear below.
- *
- * Note that if you DO supply all the operators required in a given opclass
- * by inserting them into the pg_opclass system catalog, you can get away
- * without doing all this TermData stuff. Since the rtree code is intended
- * to be a reference for access method implementors, I'm doing TermData
- * correctly here.
- *
- * Note on style: these are all actually of type StrategyTermData, but
- * since those have variable-length data at the end of the struct we can't
- * properly initialize them if we declare them to be what they are.
+ * Now do the TermData arrays. These exist in case the user doesn't give
+ * us a full set of operators for a particular operator class. The idea
+ * is that by making multiple comparisons using any one of the supplied
+ * operators, we can decide whether two n-dimensional polygons are equal.
+ * For example, if a contains b and b contains a, we may conclude that
+ * a and b are equal.
+ *
+ * The presence of the TermData arrays in all this is a historical accident.
+ * Early in the development of the POSTGRES access methods, it was believed
+ * that writing functions was harder than writing arrays. This is wrong;
+ * TermData is hard to understand and hard to get right. In general, when
+ * someone populates a new operator class, the populate it completely. If
+ * Mike Hirohama had forced Cimarron Taylor to populate the strategy map
+ * for btree int2_ops completely in 1988, you wouldn't have to deal with
+ * all this now. Too bad for you.
+ *
+ * Since you can't necessarily do this in all cases (for example, you can't
+ * do it given only "intersects" or "disjoint"), TermData arrays for some
+ * operators don't appear below.
+ *
+ * Note that if you DO supply all the operators required in a given opclass
+ * by inserting them into the pg_opclass system catalog, you can get away
+ * without doing all this TermData stuff. Since the rtree code is intended
+ * to be a reference for access method implementors, I'm doing TermData
+ * correctly here.
+ *
+ * Note on style: these are all actually of type StrategyTermData, but
+ * since those have variable-length data at the end of the struct we can't
+ * properly initialize them if we declare them to be what they are.
*/
/* if you only have "contained-by", how do you determine equality? */
-static uint16 RTContainedByTermData[] = {
- 2, /* make two comparisons */
- RTContainedByStrategyNumber, /* use "a contained-by b" */
- 0x0, /* without any magic */
- RTContainedByStrategyNumber, /* then use contained-by, */
- SK_COMMUTE /* swapping a and b */
- };
+static uint16 RTContainedByTermData[] = {
+ 2, /* make two comparisons */
+ RTContainedByStrategyNumber,/* use "a contained-by b" */
+ 0x0, /* without any magic */
+ RTContainedByStrategyNumber,/* then use contained-by, */
+ SK_COMMUTE /* swapping a and b */
+};
/* if you only have "contains", how do you determine equality? */
-static uint16 RTContainsTermData[] = {
- 2, /* make two comparisons */
- RTContainsStrategyNumber, /* use "a contains b" */
- 0x0, /* without any magic */
- RTContainsStrategyNumber, /* then use contains again, */
- SK_COMMUTE /* swapping a and b */
- };
+static uint16 RTContainsTermData[] = {
+ 2, /* make two comparisons */
+ RTContainsStrategyNumber, /* use "a contains b" */
+ 0x0, /* without any magic */
+ RTContainsStrategyNumber, /* then use contains again, */
+ SK_COMMUTE /* swapping a and b */
+};
/* now put all that together in one place for the planner */
static StrategyTerm RTEqualExpressionData[] = {
- (StrategyTerm) RTContainedByTermData,
- (StrategyTerm) RTContainsTermData,
- NULL
- };
+ (StrategyTerm) RTContainedByTermData,
+ (StrategyTerm) RTContainsTermData,
+ NULL
+};
/*
- * If you were sufficiently attentive to detail, you would go through
- * the ExpressionData pain above for every one of the seven strategies
- * we defined. I am not. Now we declare the StrategyEvaluationData
- * structure that gets shipped around to help the planner and the access
- * method decide what sort of scan it should do, based on (a) what the
- * user asked for, (b) what operators are defined for a particular opclass,
- * and (c) the reams of information we supplied above.
- *
- * The idea of all of this initialized data is to make life easier on the
- * user when he defines a new operator class to use this access method.
- * By filling in all the data, we let him get away with leaving holes in his
- * operator class, and still let him use the index. The added complexity
- * in the access methods just isn't worth the trouble, though.
+ * If you were sufficiently attentive to detail, you would go through
+ * the ExpressionData pain above for every one of the seven strategies
+ * we defined. I am not. Now we declare the StrategyEvaluationData
+ * structure that gets shipped around to help the planner and the access
+ * method decide what sort of scan it should do, based on (a) what the
+ * user asked for, (b) what operators are defined for a particular opclass,
+ * and (c) the reams of information we supplied above.
+ *
+ * The idea of all of this initialized data is to make life easier on the
+ * user when he defines a new operator class to use this access method.
+ * By filling in all the data, we let him get away with leaving holes in his
+ * operator class, and still let him use the index. The added complexity
+ * in the access methods just isn't worth the trouble, though.
*/
static StrategyEvaluationData RTEvaluationData = {
- RTNStrategies, /* # of strategies */
- (StrategyTransformMap) RTNegate, /* how to do (not qual) */
- (StrategyTransformMap) RTCommute, /* how to swap operands */
- (StrategyTransformMap) RTNegateCommute, /* how to do both */
- {
- NULL, /* express left */
- NULL, /* express overleft */
- NULL, /* express over */
- NULL, /* express overright */
- NULL, /* express right */
- (StrategyExpression) RTEqualExpressionData, /* express same */
- NULL, /* express contains */
- NULL, /* express contained-by */
- NULL,
- NULL,
- NULL
- }
+ RTNStrategies, /* # of strategies */
+ (StrategyTransformMap) RTNegate, /* how to do (not qual) */
+ (StrategyTransformMap) RTCommute, /* how to swap operands */
+ (StrategyTransformMap) RTNegateCommute, /* how to do both */
+ {
+ NULL, /* express left */
+ NULL, /* express overleft */
+ NULL, /* express over */
+ NULL, /* express overright */
+ NULL, /* express right */
+ (StrategyExpression) RTEqualExpressionData, /* express same */
+ NULL, /* express contains */
+ NULL, /* express contained-by */
+ NULL,
+ NULL,
+ NULL
+ }
};
/*
- * Okay, now something peculiar to rtrees that doesn't apply to most other
- * indexing structures: When we're searching a tree for a given value, we
- * can't do the same sorts of comparisons on internal node entries as we
- * do at leaves. The reason is that if we're looking for (say) all boxes
- * that are the same as (0,0,10,10), then we need to find all leaf pages
- * that overlap that region. So internally we search for overlap, and at
- * the leaf we search for equality.
- *
- * This array maps leaf search operators to the internal search operators.
- * We assume the normal ordering on operators:
- *
- * left, left-or-overlap, overlap, right-or-overlap, right, same,
- * contains, contained-by
+ * Okay, now something peculiar to rtrees that doesn't apply to most other
+ * indexing structures: When we're searching a tree for a given value, we
+ * can't do the same sorts of comparisons on internal node entries as we
+ * do at leaves. The reason is that if we're looking for (say) all boxes
+ * that are the same as (0,0,10,10), then we need to find all leaf pages
+ * that overlap that region. So internally we search for overlap, and at
+ * the leaf we search for equality.
+ *
+ * This array maps leaf search operators to the internal search operators.
+ * We assume the normal ordering on operators:
+ *
+ * left, left-or-overlap, overlap, right-or-overlap, right, same,
+ * contains, contained-by
*/
static StrategyNumber RTOperMap[RTNStrategies] = {
- RTOverLeftStrategyNumber,
- RTOverLeftStrategyNumber,
- RTOverlapStrategyNumber,
- RTOverRightStrategyNumber,
- RTOverRightStrategyNumber,
- RTContainsStrategyNumber,
- RTContainsStrategyNumber,
- RTOverlapStrategyNumber
- };
+ RTOverLeftStrategyNumber,
+ RTOverLeftStrategyNumber,
+ RTOverlapStrategyNumber,
+ RTOverRightStrategyNumber,
+ RTOverRightStrategyNumber,
+ RTContainsStrategyNumber,
+ RTContainsStrategyNumber,
+ RTOverlapStrategyNumber
+};
-static StrategyNumber
+static StrategyNumber
RelationGetRTStrategy(Relation r,
- AttrNumber attnum,
- RegProcedure proc)
+ AttrNumber attnum,
+ RegProcedure proc)
{
- return (RelationGetStrategy(r, attnum, &RTEvaluationData, proc));
+ return (RelationGetStrategy(r, attnum, &RTEvaluationData, proc));
}
#ifdef NOT_USED
bool
RelationInvokeRTStrategy(Relation r,
- AttrNumber attnum,
- StrategyNumber s,
- Datum left,
- Datum right)
+ AttrNumber attnum,
+ StrategyNumber s,
+ Datum left,
+ Datum right)
{
- return (RelationInvokeStrategy(r, &RTEvaluationData, attnum, s,
- left, right));
+ return (RelationInvokeStrategy(r, &RTEvaluationData, attnum, s,
+ left, right));
}
+
#endif
RegProcedure
RTMapOperator(Relation r,
- AttrNumber attnum,
- RegProcedure proc)
+ AttrNumber attnum,
+ RegProcedure proc)
{
- StrategyNumber procstrat;
- StrategyMap strategyMap;
-
- procstrat = RelationGetRTStrategy(r, attnum, proc);
- strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(r),
- RTNStrategies,
- attnum);
-
- return (strategyMap->entry[RTOperMap[procstrat - 1] - 1].sk_procedure);
+ StrategyNumber procstrat;
+ StrategyMap strategyMap;
+
+ procstrat = RelationGetRTStrategy(r, attnum, proc);
+ strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(r),
+ RTNStrategies,
+ attnum);
+
+ return (strategyMap->entry[RTOperMap[procstrat - 1] - 1].sk_procedure);
}
diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c
index 9087e50bc40..6d721fe96af 100644
--- a/src/backend/access/transam/transam.c
+++ b/src/backend/access/transam/transam.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* transam.c--
- * postgres transaction log/time interface routines
+ * postgres transaction log/time interface routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.9 1997/08/19 21:29:59 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.10 1997/09/07 04:39:29 momjian Exp $
*
* NOTES
- * This file contains the high level access-method interface to the
- * transaction system.
- *
+ * This file contains the high level access-method interface to the
+ * transaction system.
+ *
*-------------------------------------------------------------------------
*/
@@ -26,659 +26,671 @@
#include <storage/spin.h>
#include <commands/vacuum.h>
-static int RecoveryCheckingEnabled(void);
-static void TransRecover(Relation logRelation);
-static bool TransactionLogTest(TransactionId transactionId, XidStatus status);
-static void TransactionLogUpdate(TransactionId transactionId,
- XidStatus status);
+static int RecoveryCheckingEnabled(void);
+static void TransRecover(Relation logRelation);
+static bool TransactionLogTest(TransactionId transactionId, XidStatus status);
+static void
+TransactionLogUpdate(TransactionId transactionId,
+ XidStatus status);
/* ----------------
- * global variables holding pointers to relations used
- * by the transaction system. These are initialized by
- * InitializeTransactionLog().
+ * global variables holding pointers to relations used
+ * by the transaction system. These are initialized by
+ * InitializeTransactionLog().
* ----------------
*/
-Relation LogRelation = (Relation) NULL;
-Relation TimeRelation = (Relation) NULL;
-Relation VariableRelation = (Relation) NULL;
+Relation LogRelation = (Relation) NULL;
+Relation TimeRelation = (Relation) NULL;
+Relation VariableRelation = (Relation) NULL;
/* ----------------
- * global variables holding cached transaction id's and statuses.
+ * global variables holding cached transaction id's and statuses.
* ----------------
*/
TransactionId cachedGetCommitTimeXid;
AbsoluteTime cachedGetCommitTime;
TransactionId cachedTestXid;
-XidStatus cachedTestXidStatus;
+XidStatus cachedTestXidStatus;
/* ----------------
- * transaction system constants
+ * transaction system constants
* ----------------
*/
/* ----------------------------------------------------------------
- * transaction system constants
+ * transaction system constants
*
- * read the comments for GetNewTransactionId in order to
- * understand the initial values for AmiTransactionId and
- * FirstTransactionId. -cim 3/23/90
+ * read the comments for GetNewTransactionId in order to
+ * understand the initial values for AmiTransactionId and
+ * FirstTransactionId. -cim 3/23/90
* ----------------------------------------------------------------
*/
-TransactionId NullTransactionId = (TransactionId) 0;
+TransactionId NullTransactionId = (TransactionId) 0;
-TransactionId AmiTransactionId = (TransactionId) 512;
+TransactionId AmiTransactionId = (TransactionId) 512;
-TransactionId FirstTransactionId = (TransactionId) 514;
+TransactionId FirstTransactionId = (TransactionId) 514;
/* ----------------
- * transaction recovery state variables
- *
- * When the transaction system is initialized, we may
- * need to do recovery checking. This decision is decided
- * by the postmaster or the user by supplying the backend
- * with a special flag. In general, we want to do recovery
- * checking whenever we are running without a postmaster
- * or when the number of backends running under the postmaster
- * goes from zero to one. -cim 3/21/90
+ * transaction recovery state variables
+ *
+ * When the transaction system is initialized, we may
+ * need to do recovery checking. This decision is decided
+ * by the postmaster or the user by supplying the backend
+ * with a special flag. In general, we want to do recovery
+ * checking whenever we are running without a postmaster
+ * or when the number of backends running under the postmaster
+ * goes from zero to one. -cim 3/21/90
* ----------------
*/
-int RecoveryCheckingEnableState = 0;
+int RecoveryCheckingEnableState = 0;
/* ------------------
- * spinlock for oid generation
+ * spinlock for oid generation
* -----------------
*/
-extern int OidGenLockId;
+extern int OidGenLockId;
/* ----------------
- * globals that must be reset at abort
+ * globals that must be reset at abort
* ----------------
*/
-extern bool BuildingBtree;
+extern bool BuildingBtree;
/* ----------------
- * recovery checking accessors
+ * recovery checking accessors
* ----------------
*/
static int
RecoveryCheckingEnabled(void)
-{
- return RecoveryCheckingEnableState;
+{
+ return RecoveryCheckingEnableState;
}
#ifdef NOT_USED
static void
SetRecoveryCheckingEnabled(bool state)
-{
- RecoveryCheckingEnableState = (state == true);
+{
+ RecoveryCheckingEnableState = (state == true);
}
+
#endif
/* ----------------------------------------------------------------
- * postgres log/time access method interface
- *
- * TransactionLogTest
- * TransactionLogUpdate
- * ========
- * these functions do work for the interface
- * functions - they search/retrieve and append/update
- * information in the log and time relations.
+ * postgres log/time access method interface
+ *
+ * TransactionLogTest
+ * TransactionLogUpdate
+ * ========
+ * these functions do work for the interface
+ * functions - they search/retrieve and append/update
+ * information in the log and time relations.
* ----------------------------------------------------------------
*/
/* --------------------------------
- * TransactionLogTest
+ * TransactionLogTest
* --------------------------------
*/
-static bool /* true/false: does transaction id have specified status? */
-TransactionLogTest(TransactionId transactionId, /* transaction id to test */
- XidStatus status) /* transaction status */
+static bool /* true/false: does transaction id have
+ * specified status? */
+TransactionLogTest(TransactionId transactionId, /* transaction id to test */
+ XidStatus status) /* transaction status */
{
- BlockNumber blockNumber;
- XidStatus xidstatus; /* recorded status of xid */
- bool fail = false; /* success/failure */
-
- /* ----------------
- * during initialization consider all transactions
- * as having been committed
- * ----------------
- */
- if (! RelationIsValid(LogRelation))
- return (bool) (status == XID_COMMIT);
-
- /* ----------------
- * before going to the buffer manager, check our single
- * item cache to see if we didn't just check the transaction
- * status a moment ago.
- * ----------------
- */
- if (TransactionIdEquals(transactionId, cachedTestXid))
- return (bool)
- (status == cachedTestXidStatus);
-
- /* ----------------
- * compute the item pointer corresponding to the
- * page containing our transaction id. We save the item in
- * our cache to speed up things if we happen to ask for the
- * same xid's status more than once.
- * ----------------
- */
- TransComputeBlockNumber(LogRelation, transactionId, &blockNumber);
- xidstatus = TransBlockNumberGetXidStatus(LogRelation,
- blockNumber,
- transactionId,
- &fail);
-
- if (! fail) {
- TransactionIdStore(transactionId, &cachedTestXid);
- cachedTestXidStatus = xidstatus;
- return (bool)
- (status == xidstatus);
- }
-
- /* ----------------
- * here the block didn't contain the information we wanted
- * ----------------
- */
- elog(WARN, "TransactionLogTest: failed to get xidstatus");
-
- /*
- * so lint is happy...
- */
- return(false);
+ BlockNumber blockNumber;
+ XidStatus xidstatus; /* recorded status of xid */
+ bool fail = false; /* success/failure */
+
+ /* ----------------
+ * during initialization consider all transactions
+ * as having been committed
+ * ----------------
+ */
+ if (!RelationIsValid(LogRelation))
+ return (bool) (status == XID_COMMIT);
+
+ /* ----------------
+ * before going to the buffer manager, check our single
+ * item cache to see if we didn't just check the transaction
+ * status a moment ago.
+ * ----------------
+ */
+ if (TransactionIdEquals(transactionId, cachedTestXid))
+ return (bool)
+ (status == cachedTestXidStatus);
+
+ /* ----------------
+ * compute the item pointer corresponding to the
+ * page containing our transaction id. We save the item in
+ * our cache to speed up things if we happen to ask for the
+ * same xid's status more than once.
+ * ----------------
+ */
+ TransComputeBlockNumber(LogRelation, transactionId, &blockNumber);
+ xidstatus = TransBlockNumberGetXidStatus(LogRelation,
+ blockNumber,
+ transactionId,
+ &fail);
+
+ if (!fail)
+ {
+ TransactionIdStore(transactionId, &cachedTestXid);
+ cachedTestXidStatus = xidstatus;
+ return (bool)
+ (status == xidstatus);
+ }
+
+ /* ----------------
+ * here the block didn't contain the information we wanted
+ * ----------------
+ */
+ elog(WARN, "TransactionLogTest: failed to get xidstatus");
+
+ /*
+ * so lint is happy...
+ */
+ return (false);
}
/* --------------------------------
- * TransactionLogUpdate
+ * TransactionLogUpdate
* --------------------------------
*/
static void
-TransactionLogUpdate(TransactionId transactionId, /* trans id to update */
- XidStatus status) /* new trans status */
+TransactionLogUpdate(TransactionId transactionId, /* trans id to update */
+ XidStatus status) /* new trans status */
{
- BlockNumber blockNumber;
- bool fail = false; /* success/failure */
- AbsoluteTime currentTime; /* time of this transaction */
-
- /* ----------------
- * during initialization we don't record any updates.
- * ----------------
- */
- if (! RelationIsValid(LogRelation))
- return;
-
- /* ----------------
- * get the transaction commit time
- * ----------------
- */
- currentTime = getSystemTime();
-
- /* ----------------
- * update the log relation
- * ----------------
- */
- TransComputeBlockNumber(LogRelation, transactionId, &blockNumber);
- TransBlockNumberSetXidStatus(LogRelation,
- blockNumber,
- transactionId,
- status,
- &fail);
-
- /* ----------------
- * update (invalidate) our single item TransactionLogTest cache.
- * ----------------
- */
- TransactionIdStore(transactionId, &cachedTestXid);
- cachedTestXidStatus = status;
-
- /* ----------------
- * now we update the time relation, if necessary
- * (we only record commit times)
- * ----------------
- */
- if (RelationIsValid(TimeRelation) && status == XID_COMMIT) {
- TransComputeBlockNumber(TimeRelation, transactionId, &blockNumber);
- TransBlockNumberSetCommitTime(TimeRelation,
- blockNumber,
- transactionId,
- currentTime,
- &fail);
+ BlockNumber blockNumber;
+ bool fail = false; /* success/failure */
+ AbsoluteTime currentTime;/* time of this transaction */
+
+ /* ----------------
+ * during initialization we don't record any updates.
+ * ----------------
+ */
+ if (!RelationIsValid(LogRelation))
+ return;
+
/* ----------------
- * update (invalidate) our single item GetCommitTime cache.
+ * get the transaction commit time
* ----------------
*/
- TransactionIdStore(transactionId, &cachedGetCommitTimeXid);
- cachedGetCommitTime = currentTime;
- }
-
- /* ----------------
- * now we update the "last committed transaction" field
- * in the variable relation if we are recording a commit.
- * ----------------
- */
- if (RelationIsValid(VariableRelation) && status == XID_COMMIT)
- UpdateLastCommittedXid(transactionId);
+ currentTime = getSystemTime();
+
+ /* ----------------
+ * update the log relation
+ * ----------------
+ */
+ TransComputeBlockNumber(LogRelation, transactionId, &blockNumber);
+ TransBlockNumberSetXidStatus(LogRelation,
+ blockNumber,
+ transactionId,
+ status,
+ &fail);
+
+ /* ----------------
+ * update (invalidate) our single item TransactionLogTest cache.
+ * ----------------
+ */
+ TransactionIdStore(transactionId, &cachedTestXid);
+ cachedTestXidStatus = status;
+
+ /* ----------------
+ * now we update the time relation, if necessary
+ * (we only record commit times)
+ * ----------------
+ */
+ if (RelationIsValid(TimeRelation) && status == XID_COMMIT)
+ {
+ TransComputeBlockNumber(TimeRelation, transactionId, &blockNumber);
+ TransBlockNumberSetCommitTime(TimeRelation,
+ blockNumber,
+ transactionId,
+ currentTime,
+ &fail);
+ /* ----------------
+ * update (invalidate) our single item GetCommitTime cache.
+ * ----------------
+ */
+ TransactionIdStore(transactionId, &cachedGetCommitTimeXid);
+ cachedGetCommitTime = currentTime;
+ }
+
+ /* ----------------
+ * now we update the "last committed transaction" field
+ * in the variable relation if we are recording a commit.
+ * ----------------
+ */
+ if (RelationIsValid(VariableRelation) && status == XID_COMMIT)
+ UpdateLastCommittedXid(transactionId);
}
/* --------------------------------
- * TransactionIdGetCommitTime
+ * TransactionIdGetCommitTime
* --------------------------------
*/
-AbsoluteTime /* commit time of transaction id */
-TransactionIdGetCommitTime(TransactionId transactionId) /* transaction id to test */
+AbsoluteTime /* commit time of transaction id */
+TransactionIdGetCommitTime(TransactionId transactionId) /* transaction id to
+ * test */
{
- BlockNumber blockNumber;
- AbsoluteTime commitTime; /* commit time */
- bool fail = false; /* success/failure */
-
- /* ----------------
- * return invalid if we aren't running yet...
- * ----------------
- */
- if (! RelationIsValid(TimeRelation))
- return INVALID_ABSTIME;
-
- /* ----------------
- * before going to the buffer manager, check our single
- * item cache to see if we didn't just get the commit time
- * a moment ago.
- * ----------------
- */
- if (TransactionIdEquals(transactionId, cachedGetCommitTimeXid))
- return cachedGetCommitTime;
-
- /* ----------------
- * compute the item pointer corresponding to the
- * page containing our transaction commit time
- * ----------------
- */
- TransComputeBlockNumber(TimeRelation, transactionId, &blockNumber);
- commitTime = TransBlockNumberGetCommitTime(TimeRelation,
- blockNumber,
- transactionId,
- &fail);
-
- /* ----------------
- * update our cache and return the transaction commit time
- * ----------------
- */
- if (! fail) {
- TransactionIdStore(transactionId, &cachedGetCommitTimeXid);
- cachedGetCommitTime = commitTime;
- return commitTime;
- } else
- return INVALID_ABSTIME;
+ BlockNumber blockNumber;
+ AbsoluteTime commitTime; /* commit time */
+ bool fail = false; /* success/failure */
+
+ /* ----------------
+ * return invalid if we aren't running yet...
+ * ----------------
+ */
+ if (!RelationIsValid(TimeRelation))
+ return INVALID_ABSTIME;
+
+ /* ----------------
+ * before going to the buffer manager, check our single
+ * item cache to see if we didn't just get the commit time
+ * a moment ago.
+ * ----------------
+ */
+ if (TransactionIdEquals(transactionId, cachedGetCommitTimeXid))
+ return cachedGetCommitTime;
+
+ /* ----------------
+ * compute the item pointer corresponding to the
+ * page containing our transaction commit time
+ * ----------------
+ */
+ TransComputeBlockNumber(TimeRelation, transactionId, &blockNumber);
+ commitTime = TransBlockNumberGetCommitTime(TimeRelation,
+ blockNumber,
+ transactionId,
+ &fail);
+
+ /* ----------------
+ * update our cache and return the transaction commit time
+ * ----------------
+ */
+ if (!fail)
+ {
+ TransactionIdStore(transactionId, &cachedGetCommitTimeXid);
+ cachedGetCommitTime = commitTime;
+ return commitTime;
+ }
+ else
+ return INVALID_ABSTIME;
}
/* ----------------------------------------------------------------
- * transaction recovery code
+ * transaction recovery code
* ----------------------------------------------------------------
*/
/* --------------------------------
- * TransRecover
+ * TransRecover
*
- * preform transaction recovery checking.
+ * preform transaction recovery checking.
*
- * Note: this should only be preformed if no other backends
- * are running. This is known by the postmaster and
- * conveyed by the postmaster passing a "do recovery checking"
- * flag to the backend.
+ * Note: this should only be preformed if no other backends
+ * are running. This is known by the postmaster and
+ * conveyed by the postmaster passing a "do recovery checking"
+ * flag to the backend.
*
- * here we get the last recorded transaction from the log,
- * get the "last" and "next" transactions from the variable relation
- * and then preform some integrity tests:
+ * here we get the last recorded transaction from the log,
+ * get the "last" and "next" transactions from the variable relation
+ * and then preform some integrity tests:
*
- * 1) No transaction may exist higher then the "next" available
- * transaction recorded in the variable relation. If this is the
- * case then it means either the log or the variable relation
- * has become corrupted.
+ * 1) No transaction may exist higher then the "next" available
+ * transaction recorded in the variable relation. If this is the
+ * case then it means either the log or the variable relation
+ * has become corrupted.
*
- * 2) The last committed transaction may not be higher then the
- * next available transaction for the same reason.
+ * 2) The last committed transaction may not be higher then the
+ * next available transaction for the same reason.
*
- * 3) The last recorded transaction may not be lower then the
- * last committed transaction. (the reverse is ok - it means
- * that some transactions have aborted since the last commit)
+ * 3) The last recorded transaction may not be lower then the
+ * last committed transaction. (the reverse is ok - it means
+ * that some transactions have aborted since the last commit)
*
- * Here is what the proper situation looks like. The line
- * represents the data stored in the log. 'c' indicates the
- * transaction was recorded as committed, 'a' indicates an
- * abortted transaction and '.' represents information not
- * recorded. These may correspond to in progress transactions.
+ * Here is what the proper situation looks like. The line
+ * represents the data stored in the log. 'c' indicates the
+ * transaction was recorded as committed, 'a' indicates an
+ * abortted transaction and '.' represents information not
+ * recorded. These may correspond to in progress transactions.
*
- * c c a c . . a . . . . . . . . . .
- * | |
- * last next
+ * c c a c . . a . . . . . . . . . .
+ * | |
+ * last next
*
- * Since "next" is only incremented by GetNewTransactionId() which
- * is called when transactions are started. Hence if there
- * are commits or aborts after "next", then it means we committed
- * or aborted BEFORE we started the transaction. This is the
- * rational behind constraint (1).
+ * Since "next" is only incremented by GetNewTransactionId() which
+ * is called when transactions are started. Hence if there
+ * are commits or aborts after "next", then it means we committed
+ * or aborted BEFORE we started the transaction. This is the
+ * rational behind constraint (1).
*
- * Likewise, "last" should never greater then "next" for essentially
- * the same reason - it would imply we committed before we started.
- * This is the reasoning for (2).
+ * Likewise, "last" should never greater then "next" for essentially
+ * the same reason - it would imply we committed before we started.
+ * This is the reasoning for (2).
*
- * (3) implies we may never have a situation such as:
+ * (3) implies we may never have a situation such as:
*
- * c c a c . . a c . . . . . . . . .
- * | |
- * last next
+ * c c a c . . a c . . . . . . . . .
+ * | |
+ * last next
*
- * where there is a 'c' greater then "last".
+ * where there is a 'c' greater then "last".
*
- * Recovery checking is more difficult in the case where
- * several backends are executing concurrently because the
- * transactions may be executing in the other backends.
- * So, we only do recovery stuff when the backend is explicitly
- * passed a flag on the command line.
+ * Recovery checking is more difficult in the case where
+ * several backends are executing concurrently because the
+ * transactions may be executing in the other backends.
+ * So, we only do recovery stuff when the backend is explicitly
+ * passed a flag on the command line.
* --------------------------------
*/
static void
TransRecover(Relation logRelation)
{
-#if 0
- /* ----------------
- * first get the last recorded transaction in the log.
- * ----------------
- */
- TransGetLastRecordedTransaction(logRelation, logLastXid, &fail);
- if (fail == true)
- elog(WARN, "TransRecover: failed TransGetLastRecordedTransaction");
-
- /* ----------------
- * next get the "last" and "next" variables
- * ----------------
- */
- VariableRelationGetLastXid(&varLastXid);
- VariableRelationGetNextXid(&varNextXid);
-
- /* ----------------
- * intregity test (1)
- * ----------------
- */
- if (TransactionIdIsLessThan(varNextXid, logLastXid))
- elog(WARN, "TransRecover: varNextXid < logLastXid");
-
- /* ----------------
- * intregity test (2)
- * ----------------
- */
-
- /* ----------------
- * intregity test (3)
- * ----------------
- */
-
- /* ----------------
- * here we have a valid "
- *
- * **** RESUME HERE ****
- * ----------------
- */
- varNextXid = TransactionIdDup(varLastXid);
- TransactionIdIncrement(&varNextXid);
-
- VarPut(var, VAR_PUT_LASTXID, varLastXid);
- VarPut(var, VAR_PUT_NEXTXID, varNextXid);
+#if 0
+ /* ----------------
+ * first get the last recorded transaction in the log.
+ * ----------------
+ */
+ TransGetLastRecordedTransaction(logRelation, logLastXid, &fail);
+ if (fail == true)
+ elog(WARN, "TransRecover: failed TransGetLastRecordedTransaction");
+
+ /* ----------------
+ * next get the "last" and "next" variables
+ * ----------------
+ */
+ VariableRelationGetLastXid(&varLastXid);
+ VariableRelationGetNextXid(&varNextXid);
+
+ /* ----------------
+ * intregity test (1)
+ * ----------------
+ */
+ if (TransactionIdIsLessThan(varNextXid, logLastXid))
+ elog(WARN, "TransRecover: varNextXid < logLastXid");
+
+ /* ----------------
+ * intregity test (2)
+ * ----------------
+ */
+
+ /* ----------------
+ * intregity test (3)
+ * ----------------
+ */
+
+ /* ----------------
+ * here we have a valid "
+ *
+ * **** RESUME HERE ****
+ * ----------------
+ */
+ varNextXid = TransactionIdDup(varLastXid);
+ TransactionIdIncrement(&varNextXid);
+
+ VarPut(var, VAR_PUT_LASTXID, varLastXid);
+ VarPut(var, VAR_PUT_NEXTXID, varNextXid);
#endif
}
/* ----------------------------------------------------------------
- * Interface functions
- *
- * InitializeTransactionLog
- * ========
- * this function (called near cinit) initializes
- * the transaction log, time and variable relations.
- *
- * TransactionId DidCommit
- * TransactionId DidAbort
- * TransactionId IsInProgress
- * ========
- * these functions test the transaction status of
- * a specified transaction id.
- *
- * TransactionId Commit
- * TransactionId Abort
- * TransactionId SetInProgress
- * ========
- * these functions set the transaction status
- * of the specified xid. TransactionIdCommit() also
- * records the current time in the time relation
- * and updates the variable relation counter.
+ * Interface functions
+ *
+ * InitializeTransactionLog
+ * ========
+ * this function (called near cinit) initializes
+ * the transaction log, time and variable relations.
+ *
+ * TransactionId DidCommit
+ * TransactionId DidAbort
+ * TransactionId IsInProgress
+ * ========
+ * these functions test the transaction status of
+ * a specified transaction id.
+ *
+ * TransactionId Commit
+ * TransactionId Abort
+ * TransactionId SetInProgress
+ * ========
+ * these functions set the transaction status
+ * of the specified xid. TransactionIdCommit() also
+ * records the current time in the time relation
+ * and updates the variable relation counter.
*
* ----------------------------------------------------------------
*/
/*
* InitializeTransactionLog --
- * Initializes transaction logging.
+ * Initializes transaction logging.
*/
void
InitializeTransactionLog(void)
{
- Relation logRelation;
- Relation timeRelation;
- MemoryContext oldContext;
-
- /* ----------------
- * don't do anything during bootstrapping
- * ----------------
- */
- if (AMI_OVERRIDE)
- return;
-
- /* ----------------
- * disable the transaction system so the access methods
- * don't interfere during initialization.
- * ----------------
- */
- OverrideTransactionSystem(true);
-
- /* ----------------
- * make sure allocations occur within the top memory context
- * so that our log management structures are protected from
- * garbage collection at the end of every transaction.
- * ----------------
- */
- oldContext = MemoryContextSwitchTo(TopMemoryContext);
-
- /* ----------------
- * first open the log and time relations
- * (these are created by amiint so they are guaranteed to exist)
- * ----------------
- */
- logRelation = heap_openr(LogRelationName);
- timeRelation = heap_openr(TimeRelationName);
- VariableRelation = heap_openr(VariableRelationName);
- /* ----------------
- * XXX TransactionLogUpdate requires that LogRelation
- * and TimeRelation are valid so we temporarily set
- * them so we can initialize things properly.
- * This could be done cleaner.
- * ----------------
- */
- LogRelation = logRelation;
- TimeRelation = timeRelation;
-
- /* ----------------
- * if we have a virgin database, we initialize the log and time
- * relation by committing the AmiTransactionId (id 512) and we
- * initialize the variable relation by setting the next available
- * transaction id to FirstTransactionId (id 514). OID initialization
- * happens as a side effect of bootstrapping in varsup.c.
- * ----------------
- */
- SpinAcquire(OidGenLockId);
- if (!TransactionIdDidCommit(AmiTransactionId)) {
-
+ Relation logRelation;
+ Relation timeRelation;
+ MemoryContext oldContext;
+
+ /* ----------------
+ * don't do anything during bootstrapping
+ * ----------------
+ */
+ if (AMI_OVERRIDE)
+ return;
+
+ /* ----------------
+ * disable the transaction system so the access methods
+ * don't interfere during initialization.
+ * ----------------
+ */
+ OverrideTransactionSystem(true);
+
/* ----------------
- * SOMEDAY initialize the information stored in
- * the headers of the log/time/variable relations.
+ * make sure allocations occur within the top memory context
+ * so that our log management structures are protected from
+ * garbage collection at the end of every transaction.
* ----------------
*/
- TransactionLogUpdate(AmiTransactionId, XID_COMMIT);
- VariableRelationPutNextXid(FirstTransactionId);
-
- } else if (RecoveryCheckingEnabled()) {
+ oldContext = MemoryContextSwitchTo(TopMemoryContext);
+
/* ----------------
- * if we have a pre-initialized database and if the
- * perform recovery checking flag was passed then we
- * do our database integrity checking.
+ * first open the log and time relations
+ * (these are created by amiint so they are guaranteed to exist)
* ----------------
*/
- TransRecover(logRelation);
- }
- LogRelation = (Relation) NULL;
- TimeRelation = (Relation) NULL;
- SpinRelease(OidGenLockId);
-
- /* ----------------
- * now re-enable the transaction system
- * ----------------
- */
- OverrideTransactionSystem(false);
-
- /* ----------------
- * instantiate the global variables
- * ----------------
- */
- LogRelation = logRelation;
- TimeRelation = timeRelation;
-
- /* ----------------
- * restore the memory context to the previous context
- * before we return from initialization.
- * ----------------
- */
- MemoryContextSwitchTo(oldContext);
+ logRelation = heap_openr(LogRelationName);
+ timeRelation = heap_openr(TimeRelationName);
+ VariableRelation = heap_openr(VariableRelationName);
+ /* ----------------
+ * XXX TransactionLogUpdate requires that LogRelation
+ * and TimeRelation are valid so we temporarily set
+ * them so we can initialize things properly.
+ * This could be done cleaner.
+ * ----------------
+ */
+ LogRelation = logRelation;
+ TimeRelation = timeRelation;
+
+ /* ----------------
+ * if we have a virgin database, we initialize the log and time
+ * relation by committing the AmiTransactionId (id 512) and we
+ * initialize the variable relation by setting the next available
+ * transaction id to FirstTransactionId (id 514). OID initialization
+ * happens as a side effect of bootstrapping in varsup.c.
+ * ----------------
+ */
+ SpinAcquire(OidGenLockId);
+ if (!TransactionIdDidCommit(AmiTransactionId))
+ {
+
+ /* ----------------
+ * SOMEDAY initialize the information stored in
+ * the headers of the log/time/variable relations.
+ * ----------------
+ */
+ TransactionLogUpdate(AmiTransactionId, XID_COMMIT);
+ VariableRelationPutNextXid(FirstTransactionId);
+
+ }
+ else if (RecoveryCheckingEnabled())
+ {
+ /* ----------------
+ * if we have a pre-initialized database and if the
+ * perform recovery checking flag was passed then we
+ * do our database integrity checking.
+ * ----------------
+ */
+ TransRecover(logRelation);
+ }
+ LogRelation = (Relation) NULL;
+ TimeRelation = (Relation) NULL;
+ SpinRelease(OidGenLockId);
+
+ /* ----------------
+ * now re-enable the transaction system
+ * ----------------
+ */
+ OverrideTransactionSystem(false);
+
+ /* ----------------
+ * instantiate the global variables
+ * ----------------
+ */
+ LogRelation = logRelation;
+ TimeRelation = timeRelation;
+
+ /* ----------------
+ * restore the memory context to the previous context
+ * before we return from initialization.
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldContext);
}
/* --------------------------------
- * TransactionId DidCommit
- * TransactionId DidAbort
- * TransactionId IsInProgress
+ * TransactionId DidCommit
+ * TransactionId DidAbort
+ * TransactionId IsInProgress
* --------------------------------
*/
/*
* TransactionIdDidCommit --
- * True iff transaction associated with the identifier did commit.
+ * True iff transaction associated with the identifier did commit.
*
* Note:
- * Assumes transaction identifier is valid.
+ * Assumes transaction identifier is valid.
*/
-bool /* true if given transaction committed */
+bool /* true if given transaction committed */
TransactionIdDidCommit(TransactionId transactionId)
{
- if (AMI_OVERRIDE)
- return true;
-
- return
- TransactionLogTest(transactionId, XID_COMMIT);
+ if (AMI_OVERRIDE)
+ return true;
+
+ return
+ TransactionLogTest(transactionId, XID_COMMIT);
}
/*
* TransactionIdDidAborted --
- * True iff transaction associated with the identifier did abort.
+ * True iff transaction associated with the identifier did abort.
*
* Note:
- * Assumes transaction identifier is valid.
- * XXX Is this unneeded?
+ * Assumes transaction identifier is valid.
+ * XXX Is this unneeded?
*/
-bool /* true if given transaction aborted */
+bool /* true if given transaction aborted */
TransactionIdDidAbort(TransactionId transactionId)
{
- if (AMI_OVERRIDE)
- return false;
-
- return
- TransactionLogTest(transactionId, XID_ABORT);
+ if (AMI_OVERRIDE)
+ return false;
+
+ return
+ TransactionLogTest(transactionId, XID_ABORT);
}
-/*
+/*
* Now this func in shmem.c and gives quality answer by scanning
* PROC structures of all running backend. - vadim 11/26/96
*
* Old comments:
- * true if given transaction neither committed nor aborted
-
+ * true if given transaction neither committed nor aborted
+
bool
TransactionIdIsInProgress(TransactionId transactionId)
{
- if (AMI_OVERRIDE)
- return false;
-
- return
- TransactionLogTest(transactionId, XID_INPROGRESS);
+ if (AMI_OVERRIDE)
+ return false;
+
+ return
+ TransactionLogTest(transactionId, XID_INPROGRESS);
}
*/
/* --------------------------------
- * TransactionId Commit
- * TransactionId Abort
- * TransactionId SetInProgress
+ * TransactionId Commit
+ * TransactionId Abort
+ * TransactionId SetInProgress
* --------------------------------
*/
/*
* TransactionIdCommit --
- * Commits the transaction associated with the identifier.
+ * Commits the transaction associated with the identifier.
*
* Note:
- * Assumes transaction identifier is valid.
+ * Assumes transaction identifier is valid.
*/
void
TransactionIdCommit(TransactionId transactionId)
{
- if (AMI_OVERRIDE)
- return;
-
- /*
- * Within TransactionLogUpdate we call UpdateLastCommited()
- * which assumes we have exclusive access to pg_variable.
- * Therefore we need to get exclusive access before calling
- * TransactionLogUpdate. -mer 18 Aug 1992
- */
- SpinAcquire(OidGenLockId);
- TransactionLogUpdate(transactionId, XID_COMMIT);
- SpinRelease(OidGenLockId);
+ if (AMI_OVERRIDE)
+ return;
+
+ /*
+ * Within TransactionLogUpdate we call UpdateLastCommited() which
+ * assumes we have exclusive access to pg_variable. Therefore we need
+ * to get exclusive access before calling TransactionLogUpdate. -mer
+ * 18 Aug 1992
+ */
+ SpinAcquire(OidGenLockId);
+ TransactionLogUpdate(transactionId, XID_COMMIT);
+ SpinRelease(OidGenLockId);
}
/*
* TransactionIdAbort --
- * Aborts the transaction associated with the identifier.
+ * Aborts the transaction associated with the identifier.
*
* Note:
- * Assumes transaction identifier is valid.
+ * Assumes transaction identifier is valid.
*/
void
TransactionIdAbort(TransactionId transactionId)
{
- BuildingBtree = false;
-
- if (VacuumRunning)
- vc_abort();
-
- if (AMI_OVERRIDE)
- return;
-
- TransactionLogUpdate(transactionId, XID_ABORT);
+ BuildingBtree = false;
+
+ if (VacuumRunning)
+ vc_abort();
+
+ if (AMI_OVERRIDE)
+ return;
+
+ TransactionLogUpdate(transactionId, XID_ABORT);
}
#ifdef NOT_USED
void
TransactionIdSetInProgress(TransactionId transactionId)
{
- if (AMI_OVERRIDE)
- return;
-
- TransactionLogUpdate(transactionId, XID_INPROGRESS);
+ if (AMI_OVERRIDE)
+ return;
+
+ TransactionLogUpdate(transactionId, XID_INPROGRESS);
}
+
#endif
diff --git a/src/backend/access/transam/transsup.c b/src/backend/access/transam/transsup.c
index c3f1d4fc9fc..9809190c942 100644
--- a/src/backend/access/transam/transsup.c
+++ b/src/backend/access/transam/transsup.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* transsup.c--
- * postgres transaction access method support code
+ * postgres transaction access method support code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/transsup.c,v 1.9 1997/08/19 21:30:12 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/transsup.c,v 1.10 1997/09/07 04:39:32 momjian Exp $
*
* NOTES
- * This file contains support functions for the high
- * level access method interface routines found in transam.c
+ * This file contains support functions for the high
+ * level access method interface routines found in transam.c
*
*-------------------------------------------------------------------------
*/
@@ -23,644 +23,659 @@
#include <access/xact.h>
#include <storage/lmgr.h>
-static AbsoluteTime TransBlockGetCommitTime(Block tblock,
- TransactionId transactionId);
-static XidStatus TransBlockGetXidStatus(Block tblock,
- TransactionId transactionId);
-static void TransBlockSetCommitTime(Block tblock,
- TransactionId transactionId, AbsoluteTime commitTime);
-static void TransBlockSetXidStatus(Block tblock,
- TransactionId transactionId, XidStatus xstatus);
+static AbsoluteTime
+TransBlockGetCommitTime(Block tblock,
+ TransactionId transactionId);
+static XidStatus
+TransBlockGetXidStatus(Block tblock,
+ TransactionId transactionId);
+static void
+TransBlockSetCommitTime(Block tblock,
+ TransactionId transactionId, AbsoluteTime commitTime);
+static void
+TransBlockSetXidStatus(Block tblock,
+ TransactionId transactionId, XidStatus xstatus);
/* ----------------------------------------------------------------
- * general support routines
+ * general support routines
* ----------------------------------------------------------------
*/
/* --------------------------------
- * AmiTransactionOverride
+ * AmiTransactionOverride
*
- * This function is used to manipulate the bootstrap flag.
+ * This function is used to manipulate the bootstrap flag.
* --------------------------------
*/
void
AmiTransactionOverride(bool flag)
{
- AMI_OVERRIDE = flag;
+ AMI_OVERRIDE = flag;
}
/* --------------------------------
- * TransComputeBlockNumber
+ * TransComputeBlockNumber
* --------------------------------
*/
void
-TransComputeBlockNumber(Relation relation, /* relation to test */
- TransactionId transactionId, /* transaction id to test */
- BlockNumber *blockNumberOutP)
+TransComputeBlockNumber(Relation relation, /* relation to test */
+ TransactionId transactionId, /* transaction id to
+ * test */
+ BlockNumber * blockNumberOutP)
{
- long itemsPerBlock = 0;
-
- /* ----------------
- * we calculate the block number of our transaction
- * by dividing the transaction id by the number of
- * transaction things per block.
- * ----------------
- */
- if (relation == LogRelation)
- itemsPerBlock = TP_NumXidStatusPerBlock;
- else if (relation == TimeRelation)
- itemsPerBlock = TP_NumTimePerBlock;
- else
- elog(WARN, "TransComputeBlockNumber: unknown relation");
-
- /* ----------------
- * warning! if the transaction id's get too large
- * then a BlockNumber may not be large enough to hold the results
- * of our division.
- *
- * XXX this will all vanish soon when we implement an improved
- * transaction id schema -cim 3/23/90
- *
- * This has vanished now that xid's are 4 bytes (no longer 5).
- * -mer 5/24/92
- * ----------------
- */
- (*blockNumberOutP) = transactionId / itemsPerBlock;
+ long itemsPerBlock = 0;
+
+ /* ----------------
+ * we calculate the block number of our transaction
+ * by dividing the transaction id by the number of
+ * transaction things per block.
+ * ----------------
+ */
+ if (relation == LogRelation)
+ itemsPerBlock = TP_NumXidStatusPerBlock;
+ else if (relation == TimeRelation)
+ itemsPerBlock = TP_NumTimePerBlock;
+ else
+ elog(WARN, "TransComputeBlockNumber: unknown relation");
+
+ /* ----------------
+ * warning! if the transaction id's get too large
+ * then a BlockNumber may not be large enough to hold the results
+ * of our division.
+ *
+ * XXX this will all vanish soon when we implement an improved
+ * transaction id schema -cim 3/23/90
+ *
+ * This has vanished now that xid's are 4 bytes (no longer 5).
+ * -mer 5/24/92
+ * ----------------
+ */
+ (*blockNumberOutP) = transactionId / itemsPerBlock;
}
/* ----------------------------------------------------------------
- * trans block support routines
+ * trans block support routines
* ----------------------------------------------------------------
*/
/* --------------------------------
- * TransBlockGetLastTransactionIdStatus
+ * TransBlockGetLastTransactionIdStatus
*
- * This returns the status and transaction id of the last
- * transaction information recorded on the given TransBlock.
+ * This returns the status and transaction id of the last
+ * transaction information recorded on the given TransBlock.
* --------------------------------
*/
#ifdef NOT_USED
-static XidStatus
+static XidStatus
TransBlockGetLastTransactionIdStatus(Block tblock,
- TransactionId baseXid,
- TransactionId *returnXidP)
+ TransactionId baseXid,
+ TransactionId * returnXidP)
{
- Index index;
- Index maxIndex;
- bits8 bit1;
- bits8 bit2;
- BitIndex offset;
- XidStatus xstatus;
-
- /* ----------------
- * sanity check
- * ----------------
- */
- Assert((tblock != NULL));
-
- /* ----------------
- * search downward from the top of the block data, looking
- * for the first Non-in progress transaction status. Since we
- * are scanning backward, this will be last recorded transaction
- * status on the block.
- * ----------------
- */
- maxIndex = TP_NumXidStatusPerBlock;
- for (index = maxIndex; index > 0; index--) {
- offset = BitIndexOf(index-1);
- bit1 = ((bits8) BitArrayBitIsSet((BitArray) tblock, offset++)) << 1;
- bit2 = (bits8) BitArrayBitIsSet((BitArray) tblock, offset);
-
- xstatus = (bit1 | bit2) ;
-
- /* ----------------
- * here we have the status of some transaction, so test
- * if the status is recorded as "in progress". If so, then
- * we save the transaction id in the place specified by the caller.
- * ----------------
- */
- if (xstatus != XID_INPROGRESS) {
- if (returnXidP != NULL) {
- TransactionIdStore(baseXid, returnXidP);
- TransactionIdAdd(returnXidP, index - 1);
- }
- break;
+ Index index;
+ Index maxIndex;
+ bits8 bit1;
+ bits8 bit2;
+ BitIndex offset;
+ XidStatus xstatus;
+
+ /* ----------------
+ * sanity check
+ * ----------------
+ */
+ Assert((tblock != NULL));
+
+ /* ----------------
+ * search downward from the top of the block data, looking
+ * for the first Non-in progress transaction status. Since we
+ * are scanning backward, this will be last recorded transaction
+ * status on the block.
+ * ----------------
+ */
+ maxIndex = TP_NumXidStatusPerBlock;
+ for (index = maxIndex; index > 0; index--)
+ {
+ offset = BitIndexOf(index - 1);
+ bit1 = ((bits8) BitArrayBitIsSet((BitArray) tblock, offset++)) << 1;
+ bit2 = (bits8) BitArrayBitIsSet((BitArray) tblock, offset);
+
+ xstatus = (bit1 | bit2);
+
+ /* ----------------
+ * here we have the status of some transaction, so test
+ * if the status is recorded as "in progress". If so, then
+ * we save the transaction id in the place specified by the caller.
+ * ----------------
+ */
+ if (xstatus != XID_INPROGRESS)
+ {
+ if (returnXidP != NULL)
+ {
+ TransactionIdStore(baseXid, returnXidP);
+ TransactionIdAdd(returnXidP, index - 1);
+ }
+ break;
+ }
}
- }
-
- /* ----------------
- * if we get here and index is 0 it means we couldn't find
- * a non-inprogress transaction on the block. For now we just
- * return this info to the user. They can check if the return
- * status is "in progress" to know this condition has arisen.
- * ----------------
- */
- if (index == 0) {
- if (returnXidP != NULL)
- TransactionIdStore(baseXid, returnXidP);
- }
-
- /* ----------------
- * return the status to the user
- * ----------------
- */
- return xstatus;
+
+ /* ----------------
+ * if we get here and index is 0 it means we couldn't find
+ * a non-inprogress transaction on the block. For now we just
+ * return this info to the user. They can check if the return
+ * status is "in progress" to know this condition has arisen.
+ * ----------------
+ */
+ if (index == 0)
+ {
+ if (returnXidP != NULL)
+ TransactionIdStore(baseXid, returnXidP);
+ }
+
+ /* ----------------
+ * return the status to the user
+ * ----------------
+ */
+ return xstatus;
}
+
#endif
/* --------------------------------
- * TransBlockGetXidStatus
+ * TransBlockGetXidStatus
*
- * This returns the status of the desired transaction
+ * This returns the status of the desired transaction
* --------------------------------
*/
-static XidStatus
+static XidStatus
TransBlockGetXidStatus(Block tblock,
- TransactionId transactionId)
+ TransactionId transactionId)
{
- Index index;
- bits8 bit1;
- bits8 bit2;
- BitIndex offset;
-
- /* ----------------
- * sanity check
- * ----------------
- */
- if (tblock == NULL) {
- return XID_INVALID;
- }
-
- /* ----------------
- * calculate the index into the transaction data where
- * our transaction status is located
- *
- * XXX this will be replaced soon when we move to the
- * new transaction id scheme -cim 3/23/90
- *
- * The old system has now been replaced. -mer 5/24/92
- * ----------------
- */
- index = transactionId % TP_NumXidStatusPerBlock;
-
- /* ----------------
- * get the data at the specified index
- * ----------------
- */
- offset = BitIndexOf(index);
- bit1 = ((bits8) BitArrayBitIsSet((BitArray) tblock, offset++)) << 1;
- bit2 = (bits8) BitArrayBitIsSet((BitArray) tblock, offset);
-
- /* ----------------
- * return the transaction status to the caller
- * ----------------
- */
- return (XidStatus)
- (bit1 | bit2);
+ Index index;
+ bits8 bit1;
+ bits8 bit2;
+ BitIndex offset;
+
+ /* ----------------
+ * sanity check
+ * ----------------
+ */
+ if (tblock == NULL)
+ {
+ return XID_INVALID;
+ }
+
+ /* ----------------
+ * calculate the index into the transaction data where
+ * our transaction status is located
+ *
+ * XXX this will be replaced soon when we move to the
+ * new transaction id scheme -cim 3/23/90
+ *
+ * The old system has now been replaced. -mer 5/24/92
+ * ----------------
+ */
+ index = transactionId % TP_NumXidStatusPerBlock;
+
+ /* ----------------
+ * get the data at the specified index
+ * ----------------
+ */
+ offset = BitIndexOf(index);
+ bit1 = ((bits8) BitArrayBitIsSet((BitArray) tblock, offset++)) << 1;
+ bit2 = (bits8) BitArrayBitIsSet((BitArray) tblock, offset);
+
+ /* ----------------
+ * return the transaction status to the caller
+ * ----------------
+ */
+ return (XidStatus)
+ (bit1 | bit2);
}
/* --------------------------------
- * TransBlockSetXidStatus
+ * TransBlockSetXidStatus
*
- * This sets the status of the desired transaction
+ * This sets the status of the desired transaction
* --------------------------------
*/
static void
TransBlockSetXidStatus(Block tblock,
- TransactionId transactionId,
- XidStatus xstatus)
+ TransactionId transactionId,
+ XidStatus xstatus)
{
- Index index;
- BitIndex offset;
-
- /* ----------------
- * sanity check
- * ----------------
- */
- if (tblock == NULL)
- return;
-
- /* ----------------
- * calculate the index into the transaction data where
- * we sould store our transaction status.
- *
- * XXX this will be replaced soon when we move to the
- * new transaction id scheme -cim 3/23/90
- *
- * The new scheme is here -mer 5/24/92
- * ----------------
- */
- index = transactionId % TP_NumXidStatusPerBlock;
-
- offset = BitIndexOf(index);
-
- /* ----------------
- * store the transaction value at the specified offset
- * ----------------
- */
- switch(xstatus) {
- case XID_COMMIT: /* set 10 */
- BitArraySetBit((BitArray) tblock, offset);
- BitArrayClearBit((BitArray) tblock, offset + 1);
- break;
- case XID_ABORT: /* set 01 */
- BitArrayClearBit((BitArray) tblock, offset);
- BitArraySetBit((BitArray) tblock, offset + 1);
- break;
- case XID_INPROGRESS: /* set 00 */
- BitArrayClearBit((BitArray) tblock, offset);
- BitArrayClearBit((BitArray) tblock, offset + 1);
- break;
- default:
- elog(NOTICE,
- "TransBlockSetXidStatus: invalid status: %d (ignored)",
- xstatus);
- break;
- }
+ Index index;
+ BitIndex offset;
+
+ /* ----------------
+ * sanity check
+ * ----------------
+ */
+ if (tblock == NULL)
+ return;
+
+ /* ----------------
+ * calculate the index into the transaction data where
+ * we sould store our transaction status.
+ *
+ * XXX this will be replaced soon when we move to the
+ * new transaction id scheme -cim 3/23/90
+ *
+ * The new scheme is here -mer 5/24/92
+ * ----------------
+ */
+ index = transactionId % TP_NumXidStatusPerBlock;
+
+ offset = BitIndexOf(index);
+
+ /* ----------------
+ * store the transaction value at the specified offset
+ * ----------------
+ */
+ switch (xstatus)
+ {
+ case XID_COMMIT: /* set 10 */
+ BitArraySetBit((BitArray) tblock, offset);
+ BitArrayClearBit((BitArray) tblock, offset + 1);
+ break;
+ case XID_ABORT: /* set 01 */
+ BitArrayClearBit((BitArray) tblock, offset);
+ BitArraySetBit((BitArray) tblock, offset + 1);
+ break;
+ case XID_INPROGRESS: /* set 00 */
+ BitArrayClearBit((BitArray) tblock, offset);
+ BitArrayClearBit((BitArray) tblock, offset + 1);
+ break;
+ default:
+ elog(NOTICE,
+ "TransBlockSetXidStatus: invalid status: %d (ignored)",
+ xstatus);
+ break;
+ }
}
/* --------------------------------
- * TransBlockGetCommitTime
+ * TransBlockGetCommitTime
*
- * This returns the transaction commit time for the
- * specified transaction id in the trans block.
+ * This returns the transaction commit time for the
+ * specified transaction id in the trans block.
* --------------------------------
*/
-static AbsoluteTime
+static AbsoluteTime
TransBlockGetCommitTime(Block tblock,
- TransactionId transactionId)
+ TransactionId transactionId)
{
- Index index;
- AbsoluteTime *timeArray;
-
- /* ----------------
- * sanity check
- * ----------------
- */
- if (tblock == NULL)
- return INVALID_ABSTIME;
-
- /* ----------------
- * calculate the index into the transaction data where
- * our transaction commit time is located
- *
- * XXX this will be replaced soon when we move to the
- * new transaction id scheme -cim 3/23/90
- *
- * The new scheme is here. -mer 5/24/92
- * ----------------
- */
- index = transactionId % TP_NumTimePerBlock;
-
- /* ----------------
- * return the commit time to the caller
- * ----------------
- */
- timeArray = (AbsoluteTime *) tblock;
- return (AbsoluteTime)
- timeArray[ index ];
+ Index index;
+ AbsoluteTime *timeArray;
+
+ /* ----------------
+ * sanity check
+ * ----------------
+ */
+ if (tblock == NULL)
+ return INVALID_ABSTIME;
+
+ /* ----------------
+ * calculate the index into the transaction data where
+ * our transaction commit time is located
+ *
+ * XXX this will be replaced soon when we move to the
+ * new transaction id scheme -cim 3/23/90
+ *
+ * The new scheme is here. -mer 5/24/92
+ * ----------------
+ */
+ index = transactionId % TP_NumTimePerBlock;
+
+ /* ----------------
+ * return the commit time to the caller
+ * ----------------
+ */
+ timeArray = (AbsoluteTime *) tblock;
+ return (AbsoluteTime)
+ timeArray[index];
}
/* --------------------------------
- * TransBlockSetCommitTime
+ * TransBlockSetCommitTime
*
- * This sets the commit time of the specified transaction
+ * This sets the commit time of the specified transaction
* --------------------------------
*/
static void
TransBlockSetCommitTime(Block tblock,
- TransactionId transactionId,
- AbsoluteTime commitTime)
+ TransactionId transactionId,
+ AbsoluteTime commitTime)
{
- Index index;
- AbsoluteTime *timeArray;
-
- /* ----------------
- * sanity check
- * ----------------
- */
- if (tblock == NULL)
- return;
-
-
- /* ----------------
- * calculate the index into the transaction data where
- * we sould store our transaction status.
- *
- * XXX this will be replaced soon when we move to the
- * new transaction id scheme -cim 3/23/90
- *
- * The new scheme is here. -mer 5/24/92
- * ----------------
- */
- index = transactionId % TP_NumTimePerBlock;
-
- /* ----------------
- * store the transaction commit time at the specified index
- * ----------------
- */
- timeArray = (AbsoluteTime *) tblock;
- timeArray[ index ] = commitTime;
+ Index index;
+ AbsoluteTime *timeArray;
+
+ /* ----------------
+ * sanity check
+ * ----------------
+ */
+ if (tblock == NULL)
+ return;
+
+
+ /* ----------------
+ * calculate the index into the transaction data where
+ * we sould store our transaction status.
+ *
+ * XXX this will be replaced soon when we move to the
+ * new transaction id scheme -cim 3/23/90
+ *
+ * The new scheme is here. -mer 5/24/92
+ * ----------------
+ */
+ index = transactionId % TP_NumTimePerBlock;
+
+ /* ----------------
+ * store the transaction commit time at the specified index
+ * ----------------
+ */
+ timeArray = (AbsoluteTime *) tblock;
+ timeArray[index] = commitTime;
}
/* ----------------------------------------------------------------
- * transam i/o support routines
+ * transam i/o support routines
* ----------------------------------------------------------------
*/
/* --------------------------------
- * TransBlockNumberGetXidStatus
+ * TransBlockNumberGetXidStatus
* --------------------------------
*/
XidStatus
TransBlockNumberGetXidStatus(Relation relation,
- BlockNumber blockNumber,
- TransactionId xid,
- bool *failP)
+ BlockNumber blockNumber,
+ TransactionId xid,
+ bool * failP)
{
- Buffer buffer; /* buffer associated with block */
- Block block; /* block containing xstatus */
- XidStatus xstatus; /* recorded status of xid */
- bool localfail; /* bool used if failP = NULL */
-
- /* ----------------
- * SOMEDAY place a read lock on the log relation
- * That someday is today 5 Aug 1991 -mer
- * ----------------
- */
- RelationSetLockForRead(relation);
-
- /* ----------------
- * get the page containing the transaction information
- * ----------------
- */
- buffer = ReadBuffer(relation, blockNumber);
- block = BufferGetBlock(buffer);
-
- /* ----------------
- * get the status from the block. note, for now we always
- * return false in failP.
- * ----------------
- */
- if (failP == NULL)
- failP = &localfail;
- (*failP) = false;
-
- xstatus = TransBlockGetXidStatus(block, xid);
-
- /* ----------------
- * release the buffer and return the status
- * ----------------
- */
- ReleaseBuffer(buffer);
-
- /* ----------------
- * SOMEDAY release our lock on the log relation
- * ----------------
- */
- RelationUnsetLockForRead(relation);
-
- return
- xstatus;
+ Buffer buffer; /* buffer associated with block */
+ Block block; /* block containing xstatus */
+ XidStatus xstatus; /* recorded status of xid */
+ bool localfail; /* bool used if failP = NULL */
+
+ /* ----------------
+ * SOMEDAY place a read lock on the log relation
+ * That someday is today 5 Aug 1991 -mer
+ * ----------------
+ */
+ RelationSetLockForRead(relation);
+
+ /* ----------------
+ * get the page containing the transaction information
+ * ----------------
+ */
+ buffer = ReadBuffer(relation, blockNumber);
+ block = BufferGetBlock(buffer);
+
+ /* ----------------
+ * get the status from the block. note, for now we always
+ * return false in failP.
+ * ----------------
+ */
+ if (failP == NULL)
+ failP = &localfail;
+ (*failP) = false;
+
+ xstatus = TransBlockGetXidStatus(block, xid);
+
+ /* ----------------
+ * release the buffer and return the status
+ * ----------------
+ */
+ ReleaseBuffer(buffer);
+
+ /* ----------------
+ * SOMEDAY release our lock on the log relation
+ * ----------------
+ */
+ RelationUnsetLockForRead(relation);
+
+ return
+ xstatus;
}
/* --------------------------------
- * TransBlockNumberSetXidStatus
+ * TransBlockNumberSetXidStatus
* --------------------------------
*/
void
TransBlockNumberSetXidStatus(Relation relation,
- BlockNumber blockNumber,
- TransactionId xid,
- XidStatus xstatus,
- bool *failP)
+ BlockNumber blockNumber,
+ TransactionId xid,
+ XidStatus xstatus,
+ bool * failP)
{
- Buffer buffer; /* buffer associated with block */
- Block block; /* block containing xstatus */
- bool localfail; /* bool used if failP = NULL */
-
- /* ----------------
- * SOMEDAY gain exclusive access to the log relation
- *
- * That someday is today 5 Aug 1991 -mer
- * ----------------
- */
- RelationSetLockForWrite(relation);
-
- /* ----------------
- * get the block containing the transaction status
- * ----------------
- */
- buffer = ReadBuffer(relation, blockNumber);
- block = BufferGetBlock(buffer);
-
- /* ----------------
- * attempt to update the status of the transaction on the block.
- * if we are successful, write the block. otherwise release the buffer.
- * note, for now we always return false in failP.
- * ----------------
- */
- if (failP == NULL)
- failP = &localfail;
- (*failP) = false;
-
- TransBlockSetXidStatus(block, xid, xstatus);
-
- if ((*failP) == false)
- WriteBuffer(buffer);
- else
- ReleaseBuffer(buffer);
-
- /* ----------------
- * SOMEDAY release our lock on the log relation
- * ----------------
- */
- RelationUnsetLockForWrite(relation);
+ Buffer buffer; /* buffer associated with block */
+ Block block; /* block containing xstatus */
+ bool localfail; /* bool used if failP = NULL */
+
+ /* ----------------
+ * SOMEDAY gain exclusive access to the log relation
+ *
+ * That someday is today 5 Aug 1991 -mer
+ * ----------------
+ */
+ RelationSetLockForWrite(relation);
+
+ /* ----------------
+ * get the block containing the transaction status
+ * ----------------
+ */
+ buffer = ReadBuffer(relation, blockNumber);
+ block = BufferGetBlock(buffer);
+
+ /* ----------------
+ * attempt to update the status of the transaction on the block.
+ * if we are successful, write the block. otherwise release the buffer.
+ * note, for now we always return false in failP.
+ * ----------------
+ */
+ if (failP == NULL)
+ failP = &localfail;
+ (*failP) = false;
+
+ TransBlockSetXidStatus(block, xid, xstatus);
+
+ if ((*failP) == false)
+ WriteBuffer(buffer);
+ else
+ ReleaseBuffer(buffer);
+
+ /* ----------------
+ * SOMEDAY release our lock on the log relation
+ * ----------------
+ */
+ RelationUnsetLockForWrite(relation);
}
/* --------------------------------
- * TransBlockNumberGetCommitTime
+ * TransBlockNumberGetCommitTime
* --------------------------------
*/
AbsoluteTime
TransBlockNumberGetCommitTime(Relation relation,
- BlockNumber blockNumber,
- TransactionId xid,
- bool *failP)
+ BlockNumber blockNumber,
+ TransactionId xid,
+ bool * failP)
{
- Buffer buffer; /* buffer associated with block */
- Block block; /* block containing commit time */
- bool localfail; /* bool used if failP = NULL */
- AbsoluteTime xtime; /* commit time */
-
- /* ----------------
- * SOMEDAY place a read lock on the time relation
- *
- * That someday is today 5 Aug. 1991 -mer
- * ----------------
- */
- RelationSetLockForRead(relation);
-
- /* ----------------
- * get the block containing the transaction information
- * ----------------
- */
- buffer = ReadBuffer(relation, blockNumber);
- block = BufferGetBlock(buffer);
-
- /* ----------------
- * get the commit time from the block
- * note, for now we always return false in failP.
- * ----------------
- */
- if (failP == NULL)
- failP = &localfail;
- (*failP) = false;
-
- xtime = TransBlockGetCommitTime(block, xid);
-
- /* ----------------
- * release the buffer and return the commit time
- * ----------------
- */
- ReleaseBuffer(buffer);
-
- /* ----------------
- * SOMEDAY release our lock on the time relation
- * ----------------
- */
- RelationUnsetLockForRead(relation);
-
- if ((*failP) == false)
- return xtime;
- else
- return INVALID_ABSTIME;
-
+ Buffer buffer; /* buffer associated with block */
+ Block block; /* block containing commit time */
+ bool localfail; /* bool used if failP = NULL */
+ AbsoluteTime xtime; /* commit time */
+
+ /* ----------------
+ * SOMEDAY place a read lock on the time relation
+ *
+ * That someday is today 5 Aug. 1991 -mer
+ * ----------------
+ */
+ RelationSetLockForRead(relation);
+
+ /* ----------------
+ * get the block containing the transaction information
+ * ----------------
+ */
+ buffer = ReadBuffer(relation, blockNumber);
+ block = BufferGetBlock(buffer);
+
+ /* ----------------
+ * get the commit time from the block
+ * note, for now we always return false in failP.
+ * ----------------
+ */
+ if (failP == NULL)
+ failP = &localfail;
+ (*failP) = false;
+
+ xtime = TransBlockGetCommitTime(block, xid);
+
+ /* ----------------
+ * release the buffer and return the commit time
+ * ----------------
+ */
+ ReleaseBuffer(buffer);
+
+ /* ----------------
+ * SOMEDAY release our lock on the time relation
+ * ----------------
+ */
+ RelationUnsetLockForRead(relation);
+
+ if ((*failP) == false)
+ return xtime;
+ else
+ return INVALID_ABSTIME;
+
}
/* --------------------------------
- * TransBlockNumberSetCommitTime
+ * TransBlockNumberSetCommitTime
* --------------------------------
*/
void
TransBlockNumberSetCommitTime(Relation relation,
- BlockNumber blockNumber,
- TransactionId xid,
- AbsoluteTime xtime,
- bool *failP)
+ BlockNumber blockNumber,
+ TransactionId xid,
+ AbsoluteTime xtime,
+ bool * failP)
{
- Buffer buffer; /* buffer associated with block */
- Block block; /* block containing commit time */
- bool localfail; /* bool used if failP = NULL */
-
- /* ----------------
- * SOMEDAY gain exclusive access to the time relation
- *
- * That someday is today 5 Aug. 1991 -mer
- * ----------------
- */
- RelationSetLockForWrite(relation);
-
- /* ----------------
- * get the block containing our commit time
- * ----------------
- */
- buffer = ReadBuffer(relation, blockNumber);
- block = BufferGetBlock(buffer);
-
- /* ----------------
- * attempt to update the commit time of the transaction on the block.
- * if we are successful, write the block. otherwise release the buffer.
- * note, for now we always return false in failP.
- * ----------------
- */
- if (failP == NULL)
- failP = &localfail;
- (*failP) = false;
-
- TransBlockSetCommitTime(block, xid, xtime);
-
- if ((*failP) == false)
- WriteBuffer(buffer);
- else
- ReleaseBuffer(buffer);
-
- /* ----------------
- * SOMEDAY release our lock on the time relation
- * ----------------
- */
- RelationUnsetLockForWrite(relation);
-
+ Buffer buffer; /* buffer associated with block */
+ Block block; /* block containing commit time */
+ bool localfail; /* bool used if failP = NULL */
+
+ /* ----------------
+ * SOMEDAY gain exclusive access to the time relation
+ *
+ * That someday is today 5 Aug. 1991 -mer
+ * ----------------
+ */
+ RelationSetLockForWrite(relation);
+
+ /* ----------------
+ * get the block containing our commit time
+ * ----------------
+ */
+ buffer = ReadBuffer(relation, blockNumber);
+ block = BufferGetBlock(buffer);
+
+ /* ----------------
+ * attempt to update the commit time of the transaction on the block.
+ * if we are successful, write the block. otherwise release the buffer.
+ * note, for now we always return false in failP.
+ * ----------------
+ */
+ if (failP == NULL)
+ failP = &localfail;
+ (*failP) = false;
+
+ TransBlockSetCommitTime(block, xid, xtime);
+
+ if ((*failP) == false)
+ WriteBuffer(buffer);
+ else
+ ReleaseBuffer(buffer);
+
+ /* ----------------
+ * SOMEDAY release our lock on the time relation
+ * ----------------
+ */
+ RelationUnsetLockForWrite(relation);
+
}
/* --------------------------------
- * TransGetLastRecordedTransaction
+ * TransGetLastRecordedTransaction
* --------------------------------
*/
#ifdef NOT_USED
void
TransGetLastRecordedTransaction(Relation relation,
- TransactionId xid, /* return: transaction id */
- bool *failP)
+ TransactionId xid, /* return: transaction
+ * id */
+ bool * failP)
{
- BlockNumber blockNumber; /* block number */
- Buffer buffer; /* buffer associated with block */
- Block block; /* block containing xid status */
- BlockNumber n; /* number of blocks in the relation */
- TransactionId baseXid;
-
- (*failP) = false;
-
- /* ----------------
- * SOMEDAY gain exclusive access to the log relation
- *
- * That someday is today 5 Aug. 1991 -mer
- * It looks to me like we only need to set a read lock here, despite
- * the above comment about exclusive access. The block is never
- * actually written into, we only check status bits.
- * ----------------
- */
- RelationSetLockForRead(relation);
-
- /* ----------------
- * we assume the last block of the log contains the last
- * recorded transaction. If the relation is empty we return
- * failure to the user.
- * ----------------
- */
- n = RelationGetNumberOfBlocks(relation);
- if (n == 0) {
- (*failP) = true;
- return;
- }
-
- /* ----------------
- * get the block containing the transaction information
- * ----------------
- */
- blockNumber = n-1;
- buffer = ReadBuffer(relation, blockNumber);
- block = BufferGetBlock(buffer);
-
- /* ----------------
- * get the last xid on the block
- * ----------------
- */
- baseXid = blockNumber * TP_NumXidStatusPerBlock;
+ BlockNumber blockNumber;/* block number */
+ Buffer buffer; /* buffer associated with block */
+ Block block; /* block containing xid status */
+ BlockNumber n; /* number of blocks in the relation */
+ TransactionId baseXid;
+
+ (*failP) = false;
+
+ /* ----------------
+ * SOMEDAY gain exclusive access to the log relation
+ *
+ * That someday is today 5 Aug. 1991 -mer
+ * It looks to me like we only need to set a read lock here, despite
+ * the above comment about exclusive access. The block is never
+ * actually written into, we only check status bits.
+ * ----------------
+ */
+ RelationSetLockForRead(relation);
+
+ /* ----------------
+ * we assume the last block of the log contains the last
+ * recorded transaction. If the relation is empty we return
+ * failure to the user.
+ * ----------------
+ */
+ n = RelationGetNumberOfBlocks(relation);
+ if (n == 0)
+ {
+ (*failP) = true;
+ return;
+ }
+
+ /* ----------------
+ * get the block containing the transaction information
+ * ----------------
+ */
+ blockNumber = n - 1;
+ buffer = ReadBuffer(relation, blockNumber);
+ block = BufferGetBlock(buffer);
+
+ /* ----------------
+ * get the last xid on the block
+ * ----------------
+ */
+ baseXid = blockNumber * TP_NumXidStatusPerBlock;
/* XXX ???? xid won't get returned! - AY '94 */
- TransBlockGetLastTransactionIdStatus(block, baseXid, &xid);
-
- ReleaseBuffer(buffer);
-
- /* ----------------
- * SOMEDAY release our lock on the log relation
- * ----------------
- */
- RelationUnsetLockForRead(relation);
+ TransBlockGetLastTransactionIdStatus(block, baseXid, &xid);
+
+ ReleaseBuffer(buffer);
+
+ /* ----------------
+ * SOMEDAY release our lock on the log relation
+ * ----------------
+ */
+ RelationUnsetLockForRead(relation);
}
+
#endif
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index ba60ca35941..8b4b8557eb2 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* varsup.c--
- * postgres variable relation support routines
+ * postgres variable relation support routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.9 1997/08/19 21:30:16 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.10 1997/09/07 04:39:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,640 +20,647 @@
#include <access/heapam.h>
#include <catalog/catname.h>
-static void GetNewObjectIdBlock(Oid *oid_return, int oid_block_size);
-static void VariableRelationGetNextOid(Oid *oid_return);
-static void VariableRelationGetNextXid(TransactionId *xidP);
-static void VariableRelationPutLastXid(TransactionId xid);
-static void VariableRelationPutNextOid(Oid *oidP);
-static void VariableRelationGetLastXid(TransactionId *xidP);
+static void GetNewObjectIdBlock(Oid * oid_return, int oid_block_size);
+static void VariableRelationGetNextOid(Oid * oid_return);
+static void VariableRelationGetNextXid(TransactionId * xidP);
+static void VariableRelationPutLastXid(TransactionId xid);
+static void VariableRelationPutNextOid(Oid * oidP);
+static void VariableRelationGetLastXid(TransactionId * xidP);
/* ---------------------
- * spin lock for oid generation
+ * spin lock for oid generation
* ---------------------
*/
-int OidGenLockId;
+int OidGenLockId;
/* ----------------------------------------------------------------
- * variable relation query/update routines
+ * variable relation query/update routines
* ----------------------------------------------------------------
*/
/* --------------------------------
- * VariableRelationGetNextXid
+ * VariableRelationGetNextXid
* --------------------------------
*/
static void
-VariableRelationGetNextXid(TransactionId *xidP)
+VariableRelationGetNextXid(TransactionId * xidP)
{
- Buffer buf;
- VariableRelationContents var;
-
- /* ----------------
- * We assume that a spinlock has been acquire to guarantee
- * exclusive access to the variable relation.
- * ----------------
- */
-
- /* ----------------
- * do nothing before things are initialized
- * ----------------
- */
- if (! RelationIsValid(VariableRelation))
- return;
-
- /* ----------------
- * read the variable page, get the the nextXid field and
- * release the buffer
- * ----------------
- */
- buf = ReadBuffer(VariableRelation, 0);
-
- if (! BufferIsValid(buf))
+ Buffer buf;
+ VariableRelationContents var;
+
+ /* ----------------
+ * We assume that a spinlock has been acquire to guarantee
+ * exclusive access to the variable relation.
+ * ----------------
+ */
+
+ /* ----------------
+ * do nothing before things are initialized
+ * ----------------
+ */
+ if (!RelationIsValid(VariableRelation))
+ return;
+
+ /* ----------------
+ * read the variable page, get the the nextXid field and
+ * release the buffer
+ * ----------------
+ */
+ buf = ReadBuffer(VariableRelation, 0);
+
+ if (!BufferIsValid(buf))
{
- SpinRelease(OidGenLockId);
- elog(WARN, "VariableRelationGetNextXid: ReadBuffer failed");
+ SpinRelease(OidGenLockId);
+ elog(WARN, "VariableRelationGetNextXid: ReadBuffer failed");
}
-
- var = (VariableRelationContents) BufferGetBlock(buf);
-
- TransactionIdStore(var->nextXidData, xidP);
- ReleaseBuffer(buf);
+
+ var = (VariableRelationContents) BufferGetBlock(buf);
+
+ TransactionIdStore(var->nextXidData, xidP);
+ ReleaseBuffer(buf);
}
/* --------------------------------
- * VariableRelationGetLastXid
+ * VariableRelationGetLastXid
* --------------------------------
*/
static void
-VariableRelationGetLastXid(TransactionId *xidP)
+VariableRelationGetLastXid(TransactionId * xidP)
{
- Buffer buf;
- VariableRelationContents var;
-
- /* ----------------
- * We assume that a spinlock has been acquire to guarantee
- * exclusive access to the variable relation.
- * ----------------
- */
-
- /* ----------------
- * do nothing before things are initialized
- * ----------------
- */
- if (! RelationIsValid(VariableRelation))
- return;
-
- /* ----------------
- * read the variable page, get the the lastXid field and
- * release the buffer
- * ----------------
- */
- buf = ReadBuffer(VariableRelation, 0);
-
- if (! BufferIsValid(buf))
+ Buffer buf;
+ VariableRelationContents var;
+
+ /* ----------------
+ * We assume that a spinlock has been acquire to guarantee
+ * exclusive access to the variable relation.
+ * ----------------
+ */
+
+ /* ----------------
+ * do nothing before things are initialized
+ * ----------------
+ */
+ if (!RelationIsValid(VariableRelation))
+ return;
+
+ /* ----------------
+ * read the variable page, get the the lastXid field and
+ * release the buffer
+ * ----------------
+ */
+ buf = ReadBuffer(VariableRelation, 0);
+
+ if (!BufferIsValid(buf))
{
- SpinRelease(OidGenLockId);
- elog(WARN, "VariableRelationGetNextXid: ReadBuffer failed");
+ SpinRelease(OidGenLockId);
+ elog(WARN, "VariableRelationGetNextXid: ReadBuffer failed");
}
-
- var = (VariableRelationContents) BufferGetBlock(buf);
-
- TransactionIdStore(var->lastXidData, xidP);
-
- ReleaseBuffer(buf);
+
+ var = (VariableRelationContents) BufferGetBlock(buf);
+
+ TransactionIdStore(var->lastXidData, xidP);
+
+ ReleaseBuffer(buf);
}
/* --------------------------------
- * VariableRelationPutNextXid
+ * VariableRelationPutNextXid
* --------------------------------
*/
void
VariableRelationPutNextXid(TransactionId xid)
{
- Buffer buf;
- VariableRelationContents var;
- int flushmode;
-
- /* ----------------
- * We assume that a spinlock has been acquire to guarantee
- * exclusive access to the variable relation.
- * ----------------
- */
-
- /* ----------------
- * do nothing before things are initialized
- * ----------------
- */
- if (! RelationIsValid(VariableRelation))
- return;
-
- /* ----------------
- * read the variable page, update the nextXid field and
- * write the page back out to disk.
- * ----------------
- */
- buf = ReadBuffer(VariableRelation, 0);
-
- if (! BufferIsValid(buf))
+ Buffer buf;
+ VariableRelationContents var;
+ int flushmode;
+
+ /* ----------------
+ * We assume that a spinlock has been acquire to guarantee
+ * exclusive access to the variable relation.
+ * ----------------
+ */
+
+ /* ----------------
+ * do nothing before things are initialized
+ * ----------------
+ */
+ if (!RelationIsValid(VariableRelation))
+ return;
+
+ /* ----------------
+ * read the variable page, update the nextXid field and
+ * write the page back out to disk.
+ * ----------------
+ */
+ buf = ReadBuffer(VariableRelation, 0);
+
+ if (!BufferIsValid(buf))
{
- SpinRelease(OidGenLockId);
- elog(WARN, "VariableRelationPutNextXid: ReadBuffer failed");
+ SpinRelease(OidGenLockId);
+ elog(WARN, "VariableRelationPutNextXid: ReadBuffer failed");
}
-
- var = (VariableRelationContents) BufferGetBlock(buf);
-
- TransactionIdStore(xid, &(var->nextXidData));
-
- flushmode = SetBufferWriteMode (BUFFER_FLUSH_WRITE);
- WriteBuffer(buf);
- SetBufferWriteMode (flushmode);
+
+ var = (VariableRelationContents) BufferGetBlock(buf);
+
+ TransactionIdStore(xid, &(var->nextXidData));
+
+ flushmode = SetBufferWriteMode(BUFFER_FLUSH_WRITE);
+ WriteBuffer(buf);
+ SetBufferWriteMode(flushmode);
}
/* --------------------------------
- * VariableRelationPutLastXid
+ * VariableRelationPutLastXid
* --------------------------------
*/
static void
VariableRelationPutLastXid(TransactionId xid)
{
- Buffer buf;
- VariableRelationContents var;
-
- /* ----------------
- * We assume that a spinlock has been acquire to guarantee
- * exclusive access to the variable relation.
- * ----------------
- */
-
- /* ----------------
- * do nothing before things are initialized
- * ----------------
- */
- if (! RelationIsValid(VariableRelation))
- return;
-
- /* ----------------
- * read the variable page, update the lastXid field and
- * force the page back out to disk.
- * ----------------
- */
- buf = ReadBuffer(VariableRelation, 0);
-
- if (! BufferIsValid(buf))
+ Buffer buf;
+ VariableRelationContents var;
+
+ /* ----------------
+ * We assume that a spinlock has been acquire to guarantee
+ * exclusive access to the variable relation.
+ * ----------------
+ */
+
+ /* ----------------
+ * do nothing before things are initialized
+ * ----------------
+ */
+ if (!RelationIsValid(VariableRelation))
+ return;
+
+ /* ----------------
+ * read the variable page, update the lastXid field and
+ * force the page back out to disk.
+ * ----------------
+ */
+ buf = ReadBuffer(VariableRelation, 0);
+
+ if (!BufferIsValid(buf))
{
- SpinRelease(OidGenLockId);
- elog(WARN, "VariableRelationPutLastXid: ReadBuffer failed");
+ SpinRelease(OidGenLockId);
+ elog(WARN, "VariableRelationPutLastXid: ReadBuffer failed");
}
-
- var = (VariableRelationContents) BufferGetBlock(buf);
-
- TransactionIdStore(xid, &(var->lastXidData));
-
- WriteBuffer(buf);
+
+ var = (VariableRelationContents) BufferGetBlock(buf);
+
+ TransactionIdStore(xid, &(var->lastXidData));
+
+ WriteBuffer(buf);
}
/* --------------------------------
- * VariableRelationGetNextOid
+ * VariableRelationGetNextOid
* --------------------------------
*/
static void
-VariableRelationGetNextOid(Oid *oid_return)
+VariableRelationGetNextOid(Oid * oid_return)
{
- Buffer buf;
- VariableRelationContents var;
-
- /* ----------------
- * We assume that a spinlock has been acquire to guarantee
- * exclusive access to the variable relation.
- * ----------------
- */
-
- /* ----------------
- * if the variable relation is not initialized, then we
- * assume we are running at bootstrap time and so we return
- * an invalid object id -- during this time GetNextBootstrapObjectId
- * should be called instead..
- * ----------------
- */
- if (! RelationIsValid(VariableRelation)) {
+ Buffer buf;
+ VariableRelationContents var;
+
+ /* ----------------
+ * We assume that a spinlock has been acquire to guarantee
+ * exclusive access to the variable relation.
+ * ----------------
+ */
+
+ /* ----------------
+ * if the variable relation is not initialized, then we
+ * assume we are running at bootstrap time and so we return
+ * an invalid object id -- during this time GetNextBootstrapObjectId
+ * should be called instead..
+ * ----------------
+ */
+ if (!RelationIsValid(VariableRelation))
+ {
+ if (PointerIsValid(oid_return))
+ (*oid_return) = InvalidOid;
+ return;
+ }
+
+ /* ----------------
+ * read the variable page, get the the nextOid field and
+ * release the buffer
+ * ----------------
+ */
+ buf = ReadBuffer(VariableRelation, 0);
+
+ if (!BufferIsValid(buf))
+ {
+ SpinRelease(OidGenLockId);
+ elog(WARN, "VariableRelationGetNextXid: ReadBuffer failed");
+ }
+
+ var = (VariableRelationContents) BufferGetBlock(buf);
+
if (PointerIsValid(oid_return))
- (*oid_return) = InvalidOid;
- return;
- }
-
- /* ----------------
- * read the variable page, get the the nextOid field and
- * release the buffer
- * ----------------
- */
- buf = ReadBuffer(VariableRelation, 0);
-
- if (! BufferIsValid(buf))
{
- SpinRelease(OidGenLockId);
- elog(WARN, "VariableRelationGetNextXid: ReadBuffer failed");
+
+ /* ----------------
+ * nothing up my sleeve... what's going on here is that this code
+ * is guaranteed never to be called until all files in data/base/
+ * are created, and the template database exists. at that point,
+ * we want to append a pg_database tuple. the first time we do
+ * this, the oid stored in pg_variable will be bogus, so we use
+ * a bootstrap value defined at the top of this file.
+ *
+ * this comment no longer holds true. This code is called before
+ * all of the files in data/base are created and you can't rely
+ * on system oid's to be less than BootstrapObjectIdData. mer 9/18/91
+ * ----------------
+ */
+ if (OidIsValid(var->nextOid))
+ (*oid_return) = var->nextOid;
+ else
+ (*oid_return) = BootstrapObjectIdData;
}
-
- var = (VariableRelationContents) BufferGetBlock(buf);
-
- if (PointerIsValid(oid_return)) {
-
- /* ----------------
- * nothing up my sleeve... what's going on here is that this code
- * is guaranteed never to be called until all files in data/base/
- * are created, and the template database exists. at that point,
- * we want to append a pg_database tuple. the first time we do
- * this, the oid stored in pg_variable will be bogus, so we use
- * a bootstrap value defined at the top of this file.
- *
- * this comment no longer holds true. This code is called before
- * all of the files in data/base are created and you can't rely
- * on system oid's to be less than BootstrapObjectIdData. mer 9/18/91
- * ----------------
- */
- if (OidIsValid(var->nextOid))
- (*oid_return) = var->nextOid;
- else
- (*oid_return) = BootstrapObjectIdData;
- }
-
- ReleaseBuffer(buf);
+
+ ReleaseBuffer(buf);
}
/* --------------------------------
- * VariableRelationPutNextOid
+ * VariableRelationPutNextOid
* --------------------------------
*/
static void
-VariableRelationPutNextOid(Oid *oidP)
+VariableRelationPutNextOid(Oid * oidP)
{
- Buffer buf;
- VariableRelationContents var;
-
- /* ----------------
- * We assume that a spinlock has been acquire to guarantee
- * exclusive access to the variable relation.
- * ----------------
- */
-
- /* ----------------
- * do nothing before things are initialized
- * ----------------
- */
- if (! RelationIsValid(VariableRelation))
- return;
-
- /* ----------------
- * sanity check
- * ----------------
- */
- if (! PointerIsValid(oidP))
+ Buffer buf;
+ VariableRelationContents var;
+
+ /* ----------------
+ * We assume that a spinlock has been acquire to guarantee
+ * exclusive access to the variable relation.
+ * ----------------
+ */
+
+ /* ----------------
+ * do nothing before things are initialized
+ * ----------------
+ */
+ if (!RelationIsValid(VariableRelation))
+ return;
+
+ /* ----------------
+ * sanity check
+ * ----------------
+ */
+ if (!PointerIsValid(oidP))
{
- SpinRelease(OidGenLockId);
- elog(WARN, "VariableRelationPutNextOid: invalid oid pointer");
+ SpinRelease(OidGenLockId);
+ elog(WARN, "VariableRelationPutNextOid: invalid oid pointer");
}
-
- /* ----------------
- * read the variable page, update the nextXid field and
- * write the page back out to disk.
- * ----------------
- */
- buf = ReadBuffer(VariableRelation, 0);
-
- if (! BufferIsValid(buf))
+
+ /* ----------------
+ * read the variable page, update the nextXid field and
+ * write the page back out to disk.
+ * ----------------
+ */
+ buf = ReadBuffer(VariableRelation, 0);
+
+ if (!BufferIsValid(buf))
{
- SpinRelease(OidGenLockId);
- elog(WARN, "VariableRelationPutNextOid: ReadBuffer failed");
+ SpinRelease(OidGenLockId);
+ elog(WARN, "VariableRelationPutNextOid: ReadBuffer failed");
}
-
- var = (VariableRelationContents) BufferGetBlock(buf);
-
- var->nextOid = (*oidP);
-
- WriteBuffer(buf);
+
+ var = (VariableRelationContents) BufferGetBlock(buf);
+
+ var->nextOid = (*oidP);
+
+ WriteBuffer(buf);
}
/* ----------------------------------------------------------------
- * transaction id generation support
+ * transaction id generation support
* ----------------------------------------------------------------
*/
/* ----------------
- * GetNewTransactionId
+ * GetNewTransactionId
*
- * In the version 2 transaction system, transaction id's are
- * restricted in several ways.
+ * In the version 2 transaction system, transaction id's are
+ * restricted in several ways.
*
- * First, all transaction id's are even numbers (4, 88, 121342, etc).
- * This means the binary representation of the number will never
- * have the least significent bit set. This bit is reserved to
- * indicate that the transaction id does not in fact hold an XID,
- * but rather a commit time. This makes it possible for the
- * vaccuum daemon to disgard information from the log and time
- * relations for committed tuples. This is important when archiving
- * tuples to an optical disk because tuples with commit times
- * stored in their xid fields will not need to consult the log
- * and time relations.
+ * First, all transaction id's are even numbers (4, 88, 121342, etc).
+ * This means the binary representation of the number will never
+ * have the least significent bit set. This bit is reserved to
+ * indicate that the transaction id does not in fact hold an XID,
+ * but rather a commit time. This makes it possible for the
+ * vaccuum daemon to disgard information from the log and time
+ * relations for committed tuples. This is important when archiving
+ * tuples to an optical disk because tuples with commit times
+ * stored in their xid fields will not need to consult the log
+ * and time relations.
*
- * Second, since we may someday preform compression of the data
- * in the log and time relations, we cause the numbering of the
- * transaction ids to begin at 512. This means that some space
- * on the page of the log and time relations corresponding to
- * transaction id's 0 - 510 will never be used. This space is
- * in fact used to store the version number of the postgres
- * transaction log and will someday store compression information
- * about the log.
+ * Second, since we may someday preform compression of the data
+ * in the log and time relations, we cause the numbering of the
+ * transaction ids to begin at 512. This means that some space
+ * on the page of the log and time relations corresponding to
+ * transaction id's 0 - 510 will never be used. This space is
+ * in fact used to store the version number of the postgres
+ * transaction log and will someday store compression information
+ * about the log.
*
- * Lastly, rather then access the variable relation each time
- * a backend requests a new transction id, we "prefetch" 32
- * transaction id's by incrementing the nextXid stored in the
- * var relation by 64 (remember only even xid's are legal) and then
- * returning these id's one at a time until they are exhausted.
- * This means we reduce the number of accesses to the variable
- * relation by 32 for each backend.
+ * Lastly, rather then access the variable relation each time
+ * a backend requests a new transction id, we "prefetch" 32
+ * transaction id's by incrementing the nextXid stored in the
+ * var relation by 64 (remember only even xid's are legal) and then
+ * returning these id's one at a time until they are exhausted.
+ * This means we reduce the number of accesses to the variable
+ * relation by 32 for each backend.
*
- * Note: 32 has no special significance. We don't want the
- * number to be too large because if when the backend
- * terminates, we lose the xid's we cached.
+ * Note: 32 has no special significance. We don't want the
+ * number to be too large because if when the backend
+ * terminates, we lose the xid's we cached.
*
* ----------------
*/
-#define VAR_XID_PREFETCH 32
+#define VAR_XID_PREFETCH 32
-static int prefetched_xid_count = 0;
+static int prefetched_xid_count = 0;
static TransactionId next_prefetched_xid;
void
-GetNewTransactionId(TransactionId *xid)
+GetNewTransactionId(TransactionId * xid)
{
- TransactionId nextid;
-
- /* ----------------
- * during bootstrap initialization, we return the special
- * bootstrap transaction id.
- * ----------------
- */
- if (AMI_OVERRIDE) {
- TransactionIdStore(AmiTransactionId, xid);
- return;
- }
-
- /* ----------------
- * if we run out of prefetched xids, then we get some
- * more before handing them out to the caller.
- * ----------------
- */
-
- if (prefetched_xid_count == 0) {
- /* ----------------
- * obtain exclusive access to the variable relation page
- *
- * get the "next" xid from the variable relation
- * and save it in the prefetched id.
+ TransactionId nextid;
+
+ /* ----------------
+ * during bootstrap initialization, we return the special
+ * bootstrap transaction id.
* ----------------
*/
- SpinAcquire(OidGenLockId);
- VariableRelationGetNextXid(&nextid);
- TransactionIdStore(nextid, &next_prefetched_xid);
-
+ if (AMI_OVERRIDE)
+ {
+ TransactionIdStore(AmiTransactionId, xid);
+ return;
+ }
+
/* ----------------
- * now increment the variable relation's next xid
- * and reset the prefetched_xid_count. We multiply
- * the id by two because our xid's are always even.
+ * if we run out of prefetched xids, then we get some
+ * more before handing them out to the caller.
* ----------------
*/
- prefetched_xid_count = VAR_XID_PREFETCH;
- TransactionIdAdd(&nextid, prefetched_xid_count);
- VariableRelationPutNextXid(nextid);
- SpinRelease(OidGenLockId);
- }
-
- /* ----------------
- * return the next prefetched xid in the pointer passed by
- * the user and decrement the prefetch count. We add two
- * to id we return the next time this is called because our
- * transaction ids are always even.
- *
- * XXX Transaction Ids used to be even as the low order bit was
- * used to determine commit status. This is no long true so
- * we now use even and odd transaction ids. -mer 5/26/92
- * ----------------
- */
- TransactionIdStore(next_prefetched_xid, xid);
- TransactionIdAdd(&next_prefetched_xid, 1);
- prefetched_xid_count--;
+
+ if (prefetched_xid_count == 0)
+ {
+ /* ----------------
+ * obtain exclusive access to the variable relation page
+ *
+ * get the "next" xid from the variable relation
+ * and save it in the prefetched id.
+ * ----------------
+ */
+ SpinAcquire(OidGenLockId);
+ VariableRelationGetNextXid(&nextid);
+ TransactionIdStore(nextid, &next_prefetched_xid);
+
+ /* ----------------
+ * now increment the variable relation's next xid
+ * and reset the prefetched_xid_count. We multiply
+ * the id by two because our xid's are always even.
+ * ----------------
+ */
+ prefetched_xid_count = VAR_XID_PREFETCH;
+ TransactionIdAdd(&nextid, prefetched_xid_count);
+ VariableRelationPutNextXid(nextid);
+ SpinRelease(OidGenLockId);
+ }
+
+ /* ----------------
+ * return the next prefetched xid in the pointer passed by
+ * the user and decrement the prefetch count. We add two
+ * to id we return the next time this is called because our
+ * transaction ids are always even.
+ *
+ * XXX Transaction Ids used to be even as the low order bit was
+ * used to determine commit status. This is no long true so
+ * we now use even and odd transaction ids. -mer 5/26/92
+ * ----------------
+ */
+ TransactionIdStore(next_prefetched_xid, xid);
+ TransactionIdAdd(&next_prefetched_xid, 1);
+ prefetched_xid_count--;
}
/* ----------------
- * UpdateLastCommittedXid
+ * UpdateLastCommittedXid
* ----------------
*/
void
UpdateLastCommittedXid(TransactionId xid)
{
- TransactionId lastid;
-
-
- /* we assume that spinlock OidGenLockId has been acquired
- * prior to entering this function
- */
-
- /* ----------------
- * get the "last committed" transaction id from
- * the variable relation page.
- * ----------------
- */
- VariableRelationGetLastXid(&lastid);
-
- /* ----------------
- * if the transaction id is greater than the last committed
- * transaction then we update the last committed transaction
- * in the variable relation.
- * ----------------
- */
- if (TransactionIdIsLessThan(lastid, xid))
- VariableRelationPutLastXid(xid);
-
+ TransactionId lastid;
+
+
+ /*
+ * we assume that spinlock OidGenLockId has been acquired prior to
+ * entering this function
+ */
+
+ /* ----------------
+ * get the "last committed" transaction id from
+ * the variable relation page.
+ * ----------------
+ */
+ VariableRelationGetLastXid(&lastid);
+
+ /* ----------------
+ * if the transaction id is greater than the last committed
+ * transaction then we update the last committed transaction
+ * in the variable relation.
+ * ----------------
+ */
+ if (TransactionIdIsLessThan(lastid, xid))
+ VariableRelationPutLastXid(xid);
+
}
/* ----------------------------------------------------------------
- * object id generation support
+ * object id generation support
* ----------------------------------------------------------------
*/
/* ----------------
- * GetNewObjectIdBlock
+ * GetNewObjectIdBlock
*
- * This support function is used to allocate a block of object ids
- * of the given size. applications wishing to do their own object
- * id assignments should use this
+ * This support function is used to allocate a block of object ids
+ * of the given size. applications wishing to do their own object
+ * id assignments should use this
* ----------------
*/
static void
-GetNewObjectIdBlock(Oid *oid_return, /* place to return the new object id */
- int oid_block_size) /* number of oids desired */
+GetNewObjectIdBlock(Oid * oid_return, /* place to return the new object
+ * id */
+ int oid_block_size) /* number of oids desired */
{
- Oid nextoid;
-
- /* ----------------
- * SOMEDAY obtain exclusive access to the variable relation page
- * That someday is today -mer 6 Aug 1992
- * ----------------
- */
- SpinAcquire(OidGenLockId);
-
- /* ----------------
- * get the "next" oid from the variable relation
- * and give it to the caller.
- * ----------------
- */
- VariableRelationGetNextOid(&nextoid);
- if (PointerIsValid(oid_return))
- (*oid_return) = nextoid;
-
- /* ----------------
- * now increment the variable relation's next oid
- * field by the size of the oid block requested.
- * ----------------
- */
- nextoid += oid_block_size;
- VariableRelationPutNextOid(&nextoid);
-
- /* ----------------
- * SOMEDAY relinquish our lock on the variable relation page
- * That someday is today -mer 6 Apr 1992
- * ----------------
- */
- SpinRelease(OidGenLockId);
+ Oid nextoid;
+
+ /* ----------------
+ * SOMEDAY obtain exclusive access to the variable relation page
+ * That someday is today -mer 6 Aug 1992
+ * ----------------
+ */
+ SpinAcquire(OidGenLockId);
+
+ /* ----------------
+ * get the "next" oid from the variable relation
+ * and give it to the caller.
+ * ----------------
+ */
+ VariableRelationGetNextOid(&nextoid);
+ if (PointerIsValid(oid_return))
+ (*oid_return) = nextoid;
+
+ /* ----------------
+ * now increment the variable relation's next oid
+ * field by the size of the oid block requested.
+ * ----------------
+ */
+ nextoid += oid_block_size;
+ VariableRelationPutNextOid(&nextoid);
+
+ /* ----------------
+ * SOMEDAY relinquish our lock on the variable relation page
+ * That someday is today -mer 6 Apr 1992
+ * ----------------
+ */
+ SpinRelease(OidGenLockId);
}
/* ----------------
- * GetNewObjectId
+ * GetNewObjectId
*
- * This function allocates and parses out object ids. Like
- * GetNewTransactionId(), it "prefetches" 32 object ids by
- * incrementing the nextOid stored in the var relation by 32 and then
- * returning these id's one at a time until they are exhausted.
- * This means we reduce the number of accesses to the variable
- * relation by 32 for each backend.
+ * This function allocates and parses out object ids. Like
+ * GetNewTransactionId(), it "prefetches" 32 object ids by
+ * incrementing the nextOid stored in the var relation by 32 and then
+ * returning these id's one at a time until they are exhausted.
+ * This means we reduce the number of accesses to the variable
+ * relation by 32 for each backend.
*
- * Note: 32 has no special significance. We don't want the
- * number to be too large because if when the backend
- * terminates, we lose the oids we cached.
+ * Note: 32 has no special significance. We don't want the
+ * number to be too large because if when the backend
+ * terminates, we lose the oids we cached.
*
* ----------------
*/
-#define VAR_OID_PREFETCH 32
+#define VAR_OID_PREFETCH 32
-static int prefetched_oid_count = 0;
-static Oid next_prefetched_oid;
+static int prefetched_oid_count = 0;
+static Oid next_prefetched_oid;
void
-GetNewObjectId(Oid *oid_return) /* place to return the new object id */
+GetNewObjectId(Oid * oid_return)/* place to return the new object id */
{
- /* ----------------
- * if we run out of prefetched oids, then we get some
- * more before handing them out to the caller.
- * ----------------
- */
-
- if (prefetched_oid_count == 0) {
- int oid_block_size = VAR_OID_PREFETCH;
-
- /* ----------------
- * during bootstrap time, we want to allocate oids
- * one at a time. Otherwise there might be some
- * bootstrap oid's left in the block we prefetch which
- * would be passed out after the variable relation was
- * initialized. This would be bad.
- * ----------------
- */
- if (! RelationIsValid(VariableRelation))
- VariableRelation = heap_openr(VariableRelationName);
-
- /* ----------------
- * get a new block of prefetched object ids.
- * ----------------
- */
- GetNewObjectIdBlock(&next_prefetched_oid, oid_block_size);
-
- /* ----------------
- * now reset the prefetched_oid_count.
- * ----------------
- */
- prefetched_oid_count = oid_block_size;
- }
-
- /* ----------------
- * return the next prefetched oid in the pointer passed by
- * the user and decrement the prefetch count.
- * ----------------
- */
- if (PointerIsValid(oid_return))
- (*oid_return) = next_prefetched_oid;
-
- next_prefetched_oid++;
- prefetched_oid_count--;
+ /* ----------------
+ * if we run out of prefetched oids, then we get some
+ * more before handing them out to the caller.
+ * ----------------
+ */
+
+ if (prefetched_oid_count == 0)
+ {
+ int oid_block_size = VAR_OID_PREFETCH;
+
+ /* ----------------
+ * during bootstrap time, we want to allocate oids
+ * one at a time. Otherwise there might be some
+ * bootstrap oid's left in the block we prefetch which
+ * would be passed out after the variable relation was
+ * initialized. This would be bad.
+ * ----------------
+ */
+ if (!RelationIsValid(VariableRelation))
+ VariableRelation = heap_openr(VariableRelationName);
+
+ /* ----------------
+ * get a new block of prefetched object ids.
+ * ----------------
+ */
+ GetNewObjectIdBlock(&next_prefetched_oid, oid_block_size);
+
+ /* ----------------
+ * now reset the prefetched_oid_count.
+ * ----------------
+ */
+ prefetched_oid_count = oid_block_size;
+ }
+
+ /* ----------------
+ * return the next prefetched oid in the pointer passed by
+ * the user and decrement the prefetch count.
+ * ----------------
+ */
+ if (PointerIsValid(oid_return))
+ (*oid_return) = next_prefetched_oid;
+
+ next_prefetched_oid++;
+ prefetched_oid_count--;
}
void
CheckMaxObjectId(Oid assigned_oid)
{
-Oid pass_oid;
-
-
- if (prefetched_oid_count == 0) /* make sure next/max is set, or reload */
- GetNewObjectId(&pass_oid);
-
- /* ----------------
- * If we are below prefetched limits, do nothing
- * ----------------
- */
-
- if (assigned_oid < next_prefetched_oid)
- return;
-
- /* ----------------
- * If we are here, we are coming from a 'copy from' with oid's
- *
- * If we are in the prefetched oid range, just bump it up
- *
- * ----------------
- */
-
- if (assigned_oid <= next_prefetched_oid + prefetched_oid_count - 1)
- {
- prefetched_oid_count -= assigned_oid - next_prefetched_oid + 1;
- next_prefetched_oid = assigned_oid + 1;
- return;
- }
-
- /* ----------------
- * We have exceeded the prefetch oid range
- *
- * We should lock the database and kill all other backends
- * but we are loading oid's that we can not guarantee are unique
- * anyway, so we must rely on the user
- *
- *
- * We now:
- * set the variable relation with the new max oid
- * force the backend to reload its oid cache
- *
- * We use the oid cache so we don't have to update the variable
- * relation every time
- *
- * ----------------
- */
-
- pass_oid = assigned_oid;
- VariableRelationPutNextOid(&pass_oid); /* not modified */
- prefetched_oid_count = 0; /* force reload */
- pass_oid = assigned_oid;
- GetNewObjectId(&pass_oid); /* throw away returned oid */
+ Oid pass_oid;
-}
+ if (prefetched_oid_count == 0) /* make sure next/max is set, or
+ * reload */
+ GetNewObjectId(&pass_oid);
+
+ /* ----------------
+ * If we are below prefetched limits, do nothing
+ * ----------------
+ */
+
+ if (assigned_oid < next_prefetched_oid)
+ return;
+
+ /* ----------------
+ * If we are here, we are coming from a 'copy from' with oid's
+ *
+ * If we are in the prefetched oid range, just bump it up
+ *
+ * ----------------
+ */
+
+ if (assigned_oid <= next_prefetched_oid + prefetched_oid_count - 1)
+ {
+ prefetched_oid_count -= assigned_oid - next_prefetched_oid + 1;
+ next_prefetched_oid = assigned_oid + 1;
+ return;
+ }
+
+ /* ----------------
+ * We have exceeded the prefetch oid range
+ *
+ * We should lock the database and kill all other backends
+ * but we are loading oid's that we can not guarantee are unique
+ * anyway, so we must rely on the user
+ *
+ *
+ * We now:
+ * set the variable relation with the new max oid
+ * force the backend to reload its oid cache
+ *
+ * We use the oid cache so we don't have to update the variable
+ * relation every time
+ *
+ * ----------------
+ */
+
+ pass_oid = assigned_oid;
+ VariableRelationPutNextOid(&pass_oid); /* not modified */
+ prefetched_oid_count = 0; /* force reload */
+ pass_oid = assigned_oid;
+ GetNewObjectId(&pass_oid); /* throw away returned oid */
+
+}
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 5ac4a42c7c7..da32570d87b 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -1,138 +1,138 @@
/*-------------------------------------------------------------------------
*
* xact.c--
- * top level transaction system support routines
+ * top level transaction system support routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.13 1997/08/29 09:02:11 vadim Exp $
- *
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.14 1997/09/07 04:39:38 momjian Exp $
+ *
* NOTES
- * Transaction aborts can now occur two ways:
+ * Transaction aborts can now occur two ways:
*
- * 1) system dies from some internal cause (Assert, etc..)
- * 2) user types abort
+ * 1) system dies from some internal cause (Assert, etc..)
+ * 2) user types abort
*
- * These two cases used to be treated identically, but now
- * we need to distinguish them. Why? consider the following
- * two situatuons:
+ * These two cases used to be treated identically, but now
+ * we need to distinguish them. Why? consider the following
+ * two situatuons:
*
- * case 1 case 2
- * ------ ------
- * 1) user types BEGIN 1) user types BEGIN
- * 2) user does something 2) user does something
- * 3) user does not like what 3) system aborts for some reason
- * she shes and types ABORT
+ * case 1 case 2
+ * ------ ------
+ * 1) user types BEGIN 1) user types BEGIN
+ * 2) user does something 2) user does something
+ * 3) user does not like what 3) system aborts for some reason
+ * she shes and types ABORT
*
- * In case 1, we want to abort the transaction and return to the
- * default state. In case 2, there may be more commands coming
- * our way which are part of the same transaction block and we have
- * to ignore these commands until we see an END transaction.
- * (or an ABORT! --djm)
+ * In case 1, we want to abort the transaction and return to the
+ * default state. In case 2, there may be more commands coming
+ * our way which are part of the same transaction block and we have
+ * to ignore these commands until we see an END transaction.
+ * (or an ABORT! --djm)
*
- * Internal aborts are now handled by AbortTransactionBlock(), just as
- * they always have been, and user aborts are now handled by
- * UserAbortTransactionBlock(). Both of them rely on AbortTransaction()
- * to do all the real work. The only difference is what state we
- * enter after AbortTransaction() does it's work:
- *
- * * AbortTransactionBlock() leaves us in TBLOCK_ABORT and
- * * UserAbortTransactionBlock() leaves us in TBLOCK_ENDABORT
- *
- * NOTES
- * This file is an attempt at a redesign of the upper layer
- * of the V1 transaction system which was too poorly thought
- * out to describe. This new system hopes to be both simpler
- * in design, simpler to extend and needs to contain added
- * functionality to solve problems beyond the scope of the V1
- * system. (In particuler, communication of transaction
- * information between parallel backends has to be supported)
+ * Internal aborts are now handled by AbortTransactionBlock(), just as
+ * they always have been, and user aborts are now handled by
+ * UserAbortTransactionBlock(). Both of them rely on AbortTransaction()
+ * to do all the real work. The only difference is what state we
+ * enter after AbortTransaction() does it's work:
*
- * The essential aspects of the transaction system are:
+ * * AbortTransactionBlock() leaves us in TBLOCK_ABORT and
+ * * UserAbortTransactionBlock() leaves us in TBLOCK_ENDABORT
*
- * o transaction id generation
- * o transaction log updating
- * o memory cleanup
- * o cache invalidation
- * o lock cleanup
+ * NOTES
+ * This file is an attempt at a redesign of the upper layer
+ * of the V1 transaction system which was too poorly thought
+ * out to describe. This new system hopes to be both simpler
+ * in design, simpler to extend and needs to contain added
+ * functionality to solve problems beyond the scope of the V1
+ * system. (In particuler, communication of transaction
+ * information between parallel backends has to be supported)
*
- * Hence, the functional division of the transaction code is
- * based on what of the above things need to be done during
- * a start/commit/abort transaction. For instance, the
- * routine AtCommit_Memory() takes care of all the memory
- * cleanup stuff done at commit time.
+ * The essential aspects of the transaction system are:
*
- * The code is layered as follows:
+ * o transaction id generation
+ * o transaction log updating
+ * o memory cleanup
+ * o cache invalidation
+ * o lock cleanup
*
- * StartTransaction
- * CommitTransaction
- * AbortTransaction
- * UserAbortTransaction
+ * Hence, the functional division of the transaction code is
+ * based on what of the above things need to be done during
+ * a start/commit/abort transaction. For instance, the
+ * routine AtCommit_Memory() takes care of all the memory
+ * cleanup stuff done at commit time.
*
- * are provided to do the lower level work like recording
- * the transaction status in the log and doing memory cleanup.
- * above these routines are another set of functions:
+ * The code is layered as follows:
*
- * StartTransactionCommand
- * CommitTransactionCommand
- * AbortCurrentTransaction
+ * StartTransaction
+ * CommitTransaction
+ * AbortTransaction
+ * UserAbortTransaction
*
- * These are the routines used in the postgres main processing
- * loop. They are sensitive to the current transaction block state
- * and make calls to the lower level routines appropriately.
+ * are provided to do the lower level work like recording
+ * the transaction status in the log and doing memory cleanup.
+ * above these routines are another set of functions:
*
- * Support for transaction blocks is provided via the functions:
+ * StartTransactionCommand
+ * CommitTransactionCommand
+ * AbortCurrentTransaction
*
- * StartTransactionBlock
- * CommitTransactionBlock
- * AbortTransactionBlock
+ * These are the routines used in the postgres main processing
+ * loop. They are sensitive to the current transaction block state
+ * and make calls to the lower level routines appropriately.
+ *
+ * Support for transaction blocks is provided via the functions:
+ *
+ * StartTransactionBlock
+ * CommitTransactionBlock
+ * AbortTransactionBlock
*
- * These are invoked only in responce to a user "BEGIN", "END",
- * or "ABORT" command. The tricky part about these functions
- * is that they are called within the postgres main loop, in between
- * the StartTransactionCommand() and CommitTransactionCommand().
+ * These are invoked only in responce to a user "BEGIN", "END",
+ * or "ABORT" command. The tricky part about these functions
+ * is that they are called within the postgres main loop, in between
+ * the StartTransactionCommand() and CommitTransactionCommand().
*
- * For example, consider the following sequence of user commands:
+ * For example, consider the following sequence of user commands:
*
- * 1) begin
- * 2) retrieve (foo.all)
- * 3) append foo (bar = baz)
- * 4) end
+ * 1) begin
+ * 2) retrieve (foo.all)
+ * 3) append foo (bar = baz)
+ * 4) end
*
- * in the main processing loop, this results in the following
- * transaction sequence:
+ * in the main processing loop, this results in the following
+ * transaction sequence:
*
- * / StartTransactionCommand();
- * 1) / ProcessUtility(); << begin
- * \ StartTransactionBlock();
- * \ CommitTransactionCommand();
+ * / StartTransactionCommand();
+ * 1) / ProcessUtility(); << begin
+ * \ StartTransactionBlock();
+ * \ CommitTransactionCommand();
*
- * / StartTransactionCommand();
- * 2) < ProcessQuery(); << retrieve (foo.all)
- * \ CommitTransactionCommand();
+ * / StartTransactionCommand();
+ * 2) < ProcessQuery(); << retrieve (foo.all)
+ * \ CommitTransactionCommand();
*
- * / StartTransactionCommand();
- * 3) < ProcessQuery(); << append foo (bar = baz)
- * \ CommitTransactionCommand();
+ * / StartTransactionCommand();
+ * 3) < ProcessQuery(); << append foo (bar = baz)
+ * \ CommitTransactionCommand();
*
- * / StartTransactionCommand();
- * 4) / ProcessUtility(); << end
- * \ CommitTransactionBlock();
- * \ CommitTransactionCommand();
+ * / StartTransactionCommand();
+ * 4) / ProcessUtility(); << end
+ * \ CommitTransactionBlock();
+ * \ CommitTransactionCommand();
*
- * The point of this example is to demonstrate the need for
- * StartTransactionCommand() and CommitTransactionCommand() to
- * be state smart -- they should do nothing in between the calls
- * to StartTransactionBlock() and EndTransactionBlock() and
- * outside these calls they need to do normal start/commit
- * processing.
+ * The point of this example is to demonstrate the need for
+ * StartTransactionCommand() and CommitTransactionCommand() to
+ * be state smart -- they should do nothing in between the calls
+ * to StartTransactionBlock() and EndTransactionBlock() and
+ * outside these calls they need to do normal start/commit
+ * processing.
*
- * Furthermore, suppose the "retrieve (foo.all)" caused an abort
- * condition. We would then want to abort the transaction and
- * ignore all subsequent commands up to the "end".
- * -cim 3/23/90
+ * Furthermore, suppose the "retrieve (foo.all)" caused an abort
+ * condition. We would then want to abort the transaction and
+ * ignore all subsequent commands up to the "end".
+ * -cim 3/23/90
*
*-------------------------------------------------------------------------
*/
@@ -142,7 +142,7 @@
#include <access/xact.h>
#include <utils/inval.h>
#include <utils/portal.h>
-#include <access/transam.h>
+#include <access/transam.h>
#include <storage/proc.h>
#include <utils/mcxt.h>
#include <catalog/heap.h>
@@ -151,683 +151,700 @@
#include <commands/async.h>
#include <commands/sequence.h>
-static void AbortTransaction(void);
-static void AtAbort_Cache(void);
-static void AtAbort_Locks(void);
-static void AtAbort_Memory(void);
-static void AtCommit_Cache(void);
-static void AtCommit_Locks(void);
-static void AtCommit_Memory(void);
-static void AtStart_Cache(void);
-static void AtStart_Locks(void);
-static void AtStart_Memory(void);
-static void CommitTransaction(void);
-static void RecordTransactionAbort(void);
-static void RecordTransactionCommit(void);
-static void StartTransaction(void);
+static void AbortTransaction(void);
+static void AtAbort_Cache(void);
+static void AtAbort_Locks(void);
+static void AtAbort_Memory(void);
+static void AtCommit_Cache(void);
+static void AtCommit_Locks(void);
+static void AtCommit_Memory(void);
+static void AtStart_Cache(void);
+static void AtStart_Locks(void);
+static void AtStart_Memory(void);
+static void CommitTransaction(void);
+static void RecordTransactionAbort(void);
+static void RecordTransactionCommit(void);
+static void StartTransaction(void);
/* ----------------
- * global variables holding the current transaction state.
+ * global variables holding the current transaction state.
*
- * Note: when we are running several slave processes, the
- * current transaction state data is copied into shared memory
- * and the CurrentTransactionState pointer changed to
- * point to the shared copy. All this occurrs in slaves.c
+ * Note: when we are running several slave processes, the
+ * current transaction state data is copied into shared memory
+ * and the CurrentTransactionState pointer changed to
+ * point to the shared copy. All this occurrs in slaves.c
* ----------------
*/
TransactionStateData CurrentTransactionStateData = {
- 0, /* transaction id */
- FirstCommandId, /* command id */
- 0x0, /* start time */
- TRANS_DEFAULT, /* transaction state */
- TBLOCK_DEFAULT /* transaction block state */
- };
+ 0, /* transaction id */
+ FirstCommandId, /* command id */
+ 0x0, /* start time */
+ TRANS_DEFAULT, /* transaction state */
+ TBLOCK_DEFAULT /* transaction block state */
+};
TransactionState CurrentTransactionState =
- &CurrentTransactionStateData;
+&CurrentTransactionStateData;
/* ----------------
- * info returned when the system is disabled
+ * info returned when the system is disabled
*
* Apparently a lot of this code is inherited from other prototype systems.
* For DisabledStartTime, use a symbolic value to make the relationships clearer.
* The old value of 1073741823 corresponds to a date in y2004, which is coming closer
- * every day. It appears that if we return a value guaranteed larger than
- * any real time associated with a transaction then comparisons in other
- * modules will still be correct. Let's use BIG_ABSTIME for this. tgl 2/14/97
+ * every day. It appears that if we return a value guaranteed larger than
+ * any real time associated with a transaction then comparisons in other
+ * modules will still be correct. Let's use BIG_ABSTIME for this. tgl 2/14/97
*
- * Note: I have no idea what the significance of the
- * 1073741823 in DisabledStartTime.. I just carried
- * this over when converting things from the old
- * V1 transaction system. -cim 3/18/90
+ * Note: I have no idea what the significance of the
+ * 1073741823 in DisabledStartTime.. I just carried
+ * this over when converting things from the old
+ * V1 transaction system. -cim 3/18/90
* ----------------
*/
-TransactionId DisabledTransactionId = (TransactionId)-1;
-
-CommandId DisabledCommandId = (CommandId) -1;
-
-AbsoluteTime DisabledStartTime = (AbsoluteTime) BIG_ABSTIME; /* 1073741823; */
-
+TransactionId DisabledTransactionId = (TransactionId) - 1;
+
+CommandId DisabledCommandId = (CommandId) - 1;
+
+AbsoluteTime DisabledStartTime = (AbsoluteTime) BIG_ABSTIME; /* 1073741823; */
+
/* ----------------
- * overflow flag
+ * overflow flag
* ----------------
*/
-bool CommandIdCounterOverflowFlag;
-
+bool CommandIdCounterOverflowFlag;
+
/* ----------------
- * catalog creation transaction bootstrapping flag.
- * This should be eliminated and added to the transaction
- * state stuff. -cim 3/19/90
+ * catalog creation transaction bootstrapping flag.
+ * This should be eliminated and added to the transaction
+ * state stuff. -cim 3/19/90
* ----------------
*/
-bool AMI_OVERRIDE = false;
-
+bool AMI_OVERRIDE = false;
+
/* ----------------------------------------------------------------
- * transaction state accessors
+ * transaction state accessors
* ----------------------------------------------------------------
*/
-
+
/* --------------------------------
- * TranactionFlushEnabled()
- * SetTranactionFlushEnabled()
+ * TranactionFlushEnabled()
+ * SetTranactionFlushEnabled()
*
- * These are used to test and set the "TransactionFlushState"
- * varable. If this variable is true (the default), then
- * the system will flush all dirty buffers to disk at the end
- * of each transaction. If false then we are assuming the
- * buffer pool resides in stable main memory, in which case we
- * only do writes as necessary.
+ * These are used to test and set the "TransactionFlushState"
+ * varable. If this variable is true (the default), then
+ * the system will flush all dirty buffers to disk at the end
+ * of each transaction. If false then we are assuming the
+ * buffer pool resides in stable main memory, in which case we
+ * only do writes as necessary.
* --------------------------------
*/
-static int TransactionFlushState = 1;
+static int TransactionFlushState = 1;
int
TransactionFlushEnabled(void)
-{
- return TransactionFlushState;
+{
+ return TransactionFlushState;
}
#ifdef NOT_USED
void
SetTransactionFlushEnabled(bool state)
-{
- TransactionFlushState = (state == true);
+{
+ TransactionFlushState = (state == true);
}
+
#endif
/* --------------------------------
- * IsTransactionState
+ * IsTransactionState
*
- * This returns true if we are currently running a query
- * within an executing transaction.
+ * This returns true if we are currently running a query
+ * within an executing transaction.
* --------------------------------
*/
bool
IsTransactionState(void)
{
- TransactionState s = CurrentTransactionState;
-
- switch (s->state) {
- case TRANS_DEFAULT: return false;
- case TRANS_START: return true;
- case TRANS_INPROGRESS: return true;
- case TRANS_COMMIT: return true;
- case TRANS_ABORT: return true;
- case TRANS_DISABLED: return false;
- }
- /*
- * Shouldn't get here, but lint is not happy with this...
- */
- return(false);
+ TransactionState s = CurrentTransactionState;
+
+ switch (s->state)
+ {
+ case TRANS_DEFAULT:
+ return false;
+ case TRANS_START:
+ return true;
+ case TRANS_INPROGRESS:
+ return true;
+ case TRANS_COMMIT:
+ return true;
+ case TRANS_ABORT:
+ return true;
+ case TRANS_DISABLED:
+ return false;
+ }
+
+ /*
+ * Shouldn't get here, but lint is not happy with this...
+ */
+ return (false);
}
/* --------------------------------
- * IsAbortedTransactionBlockState
+ * IsAbortedTransactionBlockState
*
- * This returns true if we are currently running a query
- * within an aborted transaction block.
+ * This returns true if we are currently running a query
+ * within an aborted transaction block.
* --------------------------------
*/
bool
IsAbortedTransactionBlockState()
{
- TransactionState s = CurrentTransactionState;
-
- if (s->blockState == TBLOCK_ABORT)
- return true;
-
- return false;
+ TransactionState s = CurrentTransactionState;
+
+ if (s->blockState == TBLOCK_ABORT)
+ return true;
+
+ return false;
}
/* --------------------------------
- * OverrideTransactionSystem
+ * OverrideTransactionSystem
*
- * This is used to temporarily disable the transaction
- * processing system in order to do initialization of
- * the transaction system data structures and relations
- * themselves.
+ * This is used to temporarily disable the transaction
+ * processing system in order to do initialization of
+ * the transaction system data structures and relations
+ * themselves.
* --------------------------------
*/
-int SavedTransactionState;
+int SavedTransactionState;
void
OverrideTransactionSystem(bool flag)
{
- TransactionState s = CurrentTransactionState;
-
- if (flag == true) {
- if (s->state == TRANS_DISABLED)
- return;
-
- SavedTransactionState = s->state;
- s->state = TRANS_DISABLED;
- } else {
- if (s->state != TRANS_DISABLED)
- return;
-
- s->state = SavedTransactionState;
- }
+ TransactionState s = CurrentTransactionState;
+
+ if (flag == true)
+ {
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ SavedTransactionState = s->state;
+ s->state = TRANS_DISABLED;
+ }
+ else
+ {
+ if (s->state != TRANS_DISABLED)
+ return;
+
+ s->state = SavedTransactionState;
+ }
}
/* --------------------------------
- * GetCurrentTransactionId
+ * GetCurrentTransactionId
*
- * This returns the id of the current transaction, or
- * the id of the "disabled" transaction.
+ * This returns the id of the current transaction, or
+ * the id of the "disabled" transaction.
* --------------------------------
*/
TransactionId
GetCurrentTransactionId()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * if the transaction system is disabled, we return
- * the special "disabled" transaction id.
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return (TransactionId) DisabledTransactionId;
-
- /* ----------------
- * otherwise return the current transaction id.
- * ----------------
- */
- return (TransactionId) s->transactionIdData;
+ TransactionState s = CurrentTransactionState;
+
+ /* ----------------
+ * if the transaction system is disabled, we return
+ * the special "disabled" transaction id.
+ * ----------------
+ */
+ if (s->state == TRANS_DISABLED)
+ return (TransactionId) DisabledTransactionId;
+
+ /* ----------------
+ * otherwise return the current transaction id.
+ * ----------------
+ */
+ return (TransactionId) s->transactionIdData;
}
/* --------------------------------
- * GetCurrentCommandId
+ * GetCurrentCommandId
* --------------------------------
*/
CommandId
GetCurrentCommandId()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * if the transaction system is disabled, we return
- * the special "disabled" command id.
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return (CommandId) DisabledCommandId;
-
- return s->commandId;
+ TransactionState s = CurrentTransactionState;
+
+ /* ----------------
+ * if the transaction system is disabled, we return
+ * the special "disabled" command id.
+ * ----------------
+ */
+ if (s->state == TRANS_DISABLED)
+ return (CommandId) DisabledCommandId;
+
+ return s->commandId;
}
CommandId
GetScanCommandId()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * if the transaction system is disabled, we return
- * the special "disabled" command id.
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return (CommandId) DisabledCommandId;
-
- return s->scanCommandId;
+ TransactionState s = CurrentTransactionState;
+
+ /* ----------------
+ * if the transaction system is disabled, we return
+ * the special "disabled" command id.
+ * ----------------
+ */
+ if (s->state == TRANS_DISABLED)
+ return (CommandId) DisabledCommandId;
+
+ return s->scanCommandId;
}
/* --------------------------------
- * GetCurrentTransactionStartTime
+ * GetCurrentTransactionStartTime
* --------------------------------
*/
AbsoluteTime
GetCurrentTransactionStartTime()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * if the transaction system is disabled, we return
- * the special "disabled" starting time.
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return (AbsoluteTime) DisabledStartTime;
-
- return s->startTime;
+ TransactionState s = CurrentTransactionState;
+
+ /* ----------------
+ * if the transaction system is disabled, we return
+ * the special "disabled" starting time.
+ * ----------------
+ */
+ if (s->state == TRANS_DISABLED)
+ return (AbsoluteTime) DisabledStartTime;
+
+ return s->startTime;
}
/* --------------------------------
- * TransactionIdIsCurrentTransactionId
+ * TransactionIdIsCurrentTransactionId
* --------------------------------
*/
bool
TransactionIdIsCurrentTransactionId(TransactionId xid)
{
- TransactionState s = CurrentTransactionState;
-
- if (AMI_OVERRIDE)
- return false;
-
- return (bool)
- TransactionIdEquals(xid, s->transactionIdData);
+ TransactionState s = CurrentTransactionState;
+
+ if (AMI_OVERRIDE)
+ return false;
+
+ return (bool)
+ TransactionIdEquals(xid, s->transactionIdData);
}
/* --------------------------------
- * CommandIdIsCurrentCommandId
+ * CommandIdIsCurrentCommandId
* --------------------------------
*/
bool
CommandIdIsCurrentCommandId(CommandId cid)
{
- TransactionState s = CurrentTransactionState;
-
- if (AMI_OVERRIDE)
- return false;
-
- return
- (cid == s->commandId) ? true : false;
+ TransactionState s = CurrentTransactionState;
+
+ if (AMI_OVERRIDE)
+ return false;
+
+ return
+ (cid == s->commandId) ? true : false;
}
bool
CommandIdGEScanCommandId(CommandId cid)
{
- TransactionState s = CurrentTransactionState;
-
- if (AMI_OVERRIDE)
- return false;
-
- return
- (cid >= s->scanCommandId) ? true : false;
+ TransactionState s = CurrentTransactionState;
+
+ if (AMI_OVERRIDE)
+ return false;
+
+ return
+ (cid >= s->scanCommandId) ? true : false;
}
/* --------------------------------
- * ClearCommandIdCounterOverflowFlag
+ * ClearCommandIdCounterOverflowFlag
* --------------------------------
*/
#ifdef NOT_USED
void
ClearCommandIdCounterOverflowFlag()
{
- CommandIdCounterOverflowFlag = false;
+ CommandIdCounterOverflowFlag = false;
}
+
#endif
/* --------------------------------
- * CommandCounterIncrement
+ * CommandCounterIncrement
* --------------------------------
*/
void
CommandCounterIncrement()
{
- CurrentTransactionStateData.commandId += 1;
- if (CurrentTransactionStateData.commandId == FirstCommandId) {
- CommandIdCounterOverflowFlag = true;
- elog(WARN, "You may only have 65535 commands per transaction");
- }
-
- CurrentTransactionStateData.scanCommandId =
- CurrentTransactionStateData.commandId;
-
- /* make cache changes visible to me */
- AtCommit_Cache();
- AtStart_Cache();
+ CurrentTransactionStateData.commandId += 1;
+ if (CurrentTransactionStateData.commandId == FirstCommandId)
+ {
+ CommandIdCounterOverflowFlag = true;
+ elog(WARN, "You may only have 65535 commands per transaction");
+ }
+
+ CurrentTransactionStateData.scanCommandId =
+ CurrentTransactionStateData.commandId;
+
+ /* make cache changes visible to me */
+ AtCommit_Cache();
+ AtStart_Cache();
}
-void
-SetScanCommandId (CommandId savedId)
+void
+SetScanCommandId(CommandId savedId)
{
- CurrentTransactionStateData.scanCommandId = savedId;
-
+ CurrentTransactionStateData.scanCommandId = savedId;
+
}
/* ----------------------------------------------------------------
- * initialization stuff
+ * initialization stuff
* ----------------------------------------------------------------
*/
void
InitializeTransactionSystem()
{
- InitializeTransactionLog();
+ InitializeTransactionLog();
}
/* ----------------------------------------------------------------
- * StartTransaction stuff
+ * StartTransaction stuff
* ----------------------------------------------------------------
*/
/* --------------------------------
- * AtStart_Cache
+ * AtStart_Cache
* --------------------------------
*/
static void
-AtStart_Cache()
+AtStart_Cache()
{
- DiscardInvalid();
+ DiscardInvalid();
}
/* --------------------------------
- * AtStart_Locks
+ * AtStart_Locks
* --------------------------------
*/
static void
-AtStart_Locks()
+AtStart_Locks()
{
- /*
- * at present, it is unknown to me what belongs here -cim 3/18/90
- *
- * There isn't anything to do at the start of a xact for locks.
- * -mer 5/24/92
- */
+
+ /*
+ * at present, it is unknown to me what belongs here -cim 3/18/90
+ *
+ * There isn't anything to do at the start of a xact for locks. -mer
+ * 5/24/92
+ */
}
/* --------------------------------
- * AtStart_Memory
+ * AtStart_Memory
* --------------------------------
*/
static void
-AtStart_Memory()
+AtStart_Memory()
{
- Portal portal;
- MemoryContext portalContext;
-
- /* ----------------
- * get the blank portal and its memory context
- * ----------------
- */
- portal = GetPortalByName(NULL);
- portalContext = (MemoryContext) PortalGetHeapMemory(portal);
-
- /* ----------------
- * tell system to allocate in the blank portal context
- * ----------------
- */
- MemoryContextSwitchTo(portalContext);
- StartPortalAllocMode(DefaultAllocMode, 0);
+ Portal portal;
+ MemoryContext portalContext;
+
+ /* ----------------
+ * get the blank portal and its memory context
+ * ----------------
+ */
+ portal = GetPortalByName(NULL);
+ portalContext = (MemoryContext) PortalGetHeapMemory(portal);
+
+ /* ----------------
+ * tell system to allocate in the blank portal context
+ * ----------------
+ */
+ MemoryContextSwitchTo(portalContext);
+ StartPortalAllocMode(DefaultAllocMode, 0);
}
/* ----------------------------------------------------------------
- * CommitTransaction stuff
+ * CommitTransaction stuff
* ----------------------------------------------------------------
*/
/* --------------------------------
- * RecordTransactionCommit
+ * RecordTransactionCommit
*
- * Note: the two calls to BufferManagerFlush() exist to ensure
- * that data pages are written before log pages. These
- * explicit calls should be replaced by a more efficient
- * ordered page write scheme in the buffer manager
- * -cim 3/18/90
+ * Note: the two calls to BufferManagerFlush() exist to ensure
+ * that data pages are written before log pages. These
+ * explicit calls should be replaced by a more efficient
+ * ordered page write scheme in the buffer manager
+ * -cim 3/18/90
* --------------------------------
*/
static void
-RecordTransactionCommit()
+RecordTransactionCommit()
{
- TransactionId xid;
- int leak;
-
- /* ----------------
- * get the current transaction id
- * ----------------
- */
- xid = GetCurrentTransactionId();
-
- /* ----------------
- * flush the buffer manager pages. Note: if we have stable
- * main memory, dirty shared buffers are not flushed
- * plai 8/7/90
- * ----------------
- */
- leak = BufferPoolCheckLeak();
- FlushBufferPool(!TransactionFlushEnabled());
- if (leak) ResetBufferPool();
-
- /* ----------------
- * have the transaction access methods record the status
- * of this transaction id in the pg_log / pg_time relations.
- * ----------------
- */
- TransactionIdCommit(xid);
-
- /* ----------------
- * Now write the log/time info to the disk too.
- * ----------------
- */
- leak = BufferPoolCheckLeak();
- FlushBufferPool(!TransactionFlushEnabled());
- if (leak) ResetBufferPool();
+ TransactionId xid;
+ int leak;
+
+ /* ----------------
+ * get the current transaction id
+ * ----------------
+ */
+ xid = GetCurrentTransactionId();
+
+ /* ----------------
+ * flush the buffer manager pages. Note: if we have stable
+ * main memory, dirty shared buffers are not flushed
+ * plai 8/7/90
+ * ----------------
+ */
+ leak = BufferPoolCheckLeak();
+ FlushBufferPool(!TransactionFlushEnabled());
+ if (leak)
+ ResetBufferPool();
+
+ /* ----------------
+ * have the transaction access methods record the status
+ * of this transaction id in the pg_log / pg_time relations.
+ * ----------------
+ */
+ TransactionIdCommit(xid);
+
+ /* ----------------
+ * Now write the log/time info to the disk too.
+ * ----------------
+ */
+ leak = BufferPoolCheckLeak();
+ FlushBufferPool(!TransactionFlushEnabled());
+ if (leak)
+ ResetBufferPool();
}
/* --------------------------------
- * AtCommit_Cache
+ * AtCommit_Cache
* --------------------------------
*/
static void
AtCommit_Cache()
{
- /* ----------------
- * Make catalog changes visible to me for the next command.
- * Other backends will not process my invalidation messages until
- * after I commit and free my locks--though they will do
- * unnecessary work if I abort.
- * ----------------
- */
- RegisterInvalid(true);
+ /* ----------------
+ * Make catalog changes visible to me for the next command.
+ * Other backends will not process my invalidation messages until
+ * after I commit and free my locks--though they will do
+ * unnecessary work if I abort.
+ * ----------------
+ */
+ RegisterInvalid(true);
}
/* --------------------------------
- * AtCommit_Locks
+ * AtCommit_Locks
* --------------------------------
*/
static void
-AtCommit_Locks()
+AtCommit_Locks()
{
- /* ----------------
- * XXX What if ProcReleaseLocks fails? (race condition?)
- *
- * Then you're up a creek! -mer 5/24/92
- * ----------------
- */
- ProcReleaseLocks();
+ /* ----------------
+ * XXX What if ProcReleaseLocks fails? (race condition?)
+ *
+ * Then you're up a creek! -mer 5/24/92
+ * ----------------
+ */
+ ProcReleaseLocks();
}
/* --------------------------------
- * AtCommit_Memory
+ * AtCommit_Memory
* --------------------------------
*/
static void
-AtCommit_Memory()
+AtCommit_Memory()
{
- /* ----------------
- * now that we're "out" of a transaction, have the
- * system allocate things in the top memory context instead
- * of the blank portal memory context.
- * ----------------
- */
- EndPortalAllocMode();
- MemoryContextSwitchTo(TopMemoryContext);
+ /* ----------------
+ * now that we're "out" of a transaction, have the
+ * system allocate things in the top memory context instead
+ * of the blank portal memory context.
+ * ----------------
+ */
+ EndPortalAllocMode();
+ MemoryContextSwitchTo(TopMemoryContext);
}
/* ----------------------------------------------------------------
- * AbortTransaction stuff
+ * AbortTransaction stuff
* ----------------------------------------------------------------
*/
/* --------------------------------
- * RecordTransactionAbort
+ * RecordTransactionAbort
* --------------------------------
*/
static void
-RecordTransactionAbort()
+RecordTransactionAbort()
{
- TransactionId xid;
-
- /* ----------------
- * get the current transaction id
- * ----------------
- */
- xid = GetCurrentTransactionId();
-
- /* ----------------
- * have the transaction access methods record the status
- * of this transaction id in the pg_log / pg_time relations.
- * ----------------
- */
- TransactionIdAbort(xid);
-
- /* ----------------
- * flush the buffer manager pages. Note: if we have stable
- * main memory, dirty shared buffers are not flushed
- * plai 8/7/90
- * ----------------
- */
- ResetBufferPool();
+ TransactionId xid;
+
+ /* ----------------
+ * get the current transaction id
+ * ----------------
+ */
+ xid = GetCurrentTransactionId();
+
+ /* ----------------
+ * have the transaction access methods record the status
+ * of this transaction id in the pg_log / pg_time relations.
+ * ----------------
+ */
+ TransactionIdAbort(xid);
+
+ /* ----------------
+ * flush the buffer manager pages. Note: if we have stable
+ * main memory, dirty shared buffers are not flushed
+ * plai 8/7/90
+ * ----------------
+ */
+ ResetBufferPool();
}
/* --------------------------------
- * AtAbort_Cache
+ * AtAbort_Cache
* --------------------------------
*/
static void
-AtAbort_Cache()
+AtAbort_Cache()
{
- RegisterInvalid(false);
+ RegisterInvalid(false);
}
/* --------------------------------
- * AtAbort_Locks
+ * AtAbort_Locks
* --------------------------------
*/
static void
-AtAbort_Locks()
+AtAbort_Locks()
{
- /* ----------------
- * XXX What if ProcReleaseLocks() fails? (race condition?)
- *
- * Then you're up a creek without a paddle! -mer
- * ----------------
- */
- ProcReleaseLocks();
+ /* ----------------
+ * XXX What if ProcReleaseLocks() fails? (race condition?)
+ *
+ * Then you're up a creek without a paddle! -mer
+ * ----------------
+ */
+ ProcReleaseLocks();
}
/* --------------------------------
- * AtAbort_Memory
+ * AtAbort_Memory
* --------------------------------
*/
static void
-AtAbort_Memory()
+AtAbort_Memory()
{
- /* ----------------
- * after doing an abort transaction, make certain the
- * system uses the top memory context rather then the
- * portal memory context (until the next transaction).
- * ----------------
- */
- MemoryContextSwitchTo(TopMemoryContext);
+ /* ----------------
+ * after doing an abort transaction, make certain the
+ * system uses the top memory context rather then the
+ * portal memory context (until the next transaction).
+ * ----------------
+ */
+ MemoryContextSwitchTo(TopMemoryContext);
}
/* ----------------------------------------------------------------
- * interface routines
+ * interface routines
* ----------------------------------------------------------------
*/
/* --------------------------------
- * StartTransaction
+ * StartTransaction
*
* --------------------------------
*/
static void
StartTransaction()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * Check the current transaction state. If the transaction system
- * is switched off, or if we're already in a transaction, do nothing.
- * We're already in a transaction when the monitor sends a null
- * command to the backend to flush the comm channel. This is a
- * hacky fix to a communications problem, and we keep having to
- * deal with it here. We should fix the comm channel code. mao 080891
- * ----------------
- */
- if (s->state == TRANS_DISABLED || s->state == TRANS_INPROGRESS)
- return;
-
- /* ----------------
- * set the current transaction state information
- * appropriately during start processing
- * ----------------
- */
- s->state = TRANS_START;
-
- /* ----------------
- * generate a new transaction id
- * ----------------
- */
- GetNewTransactionId(&(s->transactionIdData));
-
- /* ----------------
- * initialize current transaction state fields
- * ----------------
- */
- s->commandId = FirstCommandId;
- s->scanCommandId = FirstCommandId;
- s->startTime = GetCurrentAbsoluteTime();
-
- /* ----------------
- * initialize the various transaction subsystems
- * ----------------
- */
- AtStart_Cache();
- AtStart_Locks();
- AtStart_Memory();
-
- /* --------------
- initialize temporary relations list
- the tempRelList is a list of temporary relations that
- are created in the course of the transactions
- they need to be destroyed properly at the end of the transactions
- */
- InitTempRelList();
-
- /* ----------------
- * done with start processing, set current transaction
- * state to "in progress"
- * ----------------
- */
- s->state = TRANS_INPROGRESS;
-
- /*
- * Let others to know about current transaction is in progress
- * - vadim 11/26/96
- */
- if ( MyProc != (PROC*) NULL )
- MyProc->xid = s->transactionIdData;
+ TransactionState s = CurrentTransactionState;
+
+ /* ----------------
+ * Check the current transaction state. If the transaction system
+ * is switched off, or if we're already in a transaction, do nothing.
+ * We're already in a transaction when the monitor sends a null
+ * command to the backend to flush the comm channel. This is a
+ * hacky fix to a communications problem, and we keep having to
+ * deal with it here. We should fix the comm channel code. mao 080891
+ * ----------------
+ */
+ if (s->state == TRANS_DISABLED || s->state == TRANS_INPROGRESS)
+ return;
+
+ /* ----------------
+ * set the current transaction state information
+ * appropriately during start processing
+ * ----------------
+ */
+ s->state = TRANS_START;
+
+ /* ----------------
+ * generate a new transaction id
+ * ----------------
+ */
+ GetNewTransactionId(&(s->transactionIdData));
+
+ /* ----------------
+ * initialize current transaction state fields
+ * ----------------
+ */
+ s->commandId = FirstCommandId;
+ s->scanCommandId = FirstCommandId;
+ s->startTime = GetCurrentAbsoluteTime();
+
+ /* ----------------
+ * initialize the various transaction subsystems
+ * ----------------
+ */
+ AtStart_Cache();
+ AtStart_Locks();
+ AtStart_Memory();
+
+ /* --------------
+ initialize temporary relations list
+ the tempRelList is a list of temporary relations that
+ are created in the course of the transactions
+ they need to be destroyed properly at the end of the transactions
+ */
+ InitTempRelList();
+
+ /* ----------------
+ * done with start processing, set current transaction
+ * state to "in progress"
+ * ----------------
+ */
+ s->state = TRANS_INPROGRESS;
+
+ /*
+ * Let others to know about current transaction is in progress - vadim
+ * 11/26/96
+ */
+ if (MyProc != (PROC *) NULL)
+ MyProc->xid = s->transactionIdData;
}
@@ -838,591 +855,604 @@ StartTransaction()
bool
CurrentXactInProgress()
{
- return (CurrentTransactionState->state == TRANS_INPROGRESS);
+ return (CurrentTransactionState->state == TRANS_INPROGRESS);
}
/* --------------------------------
- * CommitTransaction
+ * CommitTransaction
*
* --------------------------------
*/
static void
CommitTransaction()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- if (s->state != TRANS_INPROGRESS)
- elog(NOTICE, "CommitTransaction and not in in-progress state ");
-
- /* ----------------
- * set the current transaction state information
- * appropriately during the abort processing
- * ----------------
- */
- s->state = TRANS_COMMIT;
-
- /* ----------------
- * do commit processing
- * ----------------
- */
- CloseSequences ();
- DestroyTempRels();
- AtEOXact_portals();
- RecordTransactionCommit();
- RelationPurgeLocalRelation(true);
- AtCommit_Cache();
- AtCommit_Locks();
- AtCommit_Memory();
-
- /* ----------------
- * done with commit processing, set current transaction
- * state back to default
- * ----------------
- */
- s->state = TRANS_DEFAULT;
- { /* want this after commit */
- if (IsNormalProcessingMode())
- Async_NotifyAtCommit();
- }
-
- /*
- * Let others to know about no transaction in progress
- * - vadim 11/26/96
- */
- if ( MyProc != (PROC*) NULL )
- MyProc->xid = InvalidTransactionId;
-}
+ TransactionState s = CurrentTransactionState;
-/* --------------------------------
- * AbortTransaction
- *
- * --------------------------------
- */
-static void
-AbortTransaction()
-{
- TransactionState s = CurrentTransactionState;
-
- /*
- * Let others to know about no transaction in progress
- * - vadim 11/26/96
- */
- if ( MyProc != (PROC*) NULL )
- MyProc->xid = InvalidTransactionId;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- if (s->state != TRANS_INPROGRESS)
- elog(NOTICE, "AbortTransaction and not in in-progress state ");
-
- /* ----------------
- * set the current transaction state information
- * appropriately during the abort processing
- * ----------------
- */
- s->state = TRANS_ABORT;
-
- /* ----------------
- * do abort processing
- * ----------------
- */
- CloseSequences ();
- AtEOXact_portals();
- RecordTransactionAbort();
- RelationPurgeLocalRelation(false);
- DestroyTempRels();
- AtAbort_Cache();
- AtAbort_Locks();
- AtAbort_Memory();
-
- /* ----------------
- * done with abort processing, set current transaction
- * state back to default
- * ----------------
- */
- s->state = TRANS_DEFAULT;
- {
- /* We need to do this in case another process notified us while
- we are in the middle of an aborted transaction. We need to
- notify our frontend after we finish the current transaction.
- -- jw, 1/3/94
- */
- if (IsNormalProcessingMode())
- Async_NotifyAtAbort();
- }
-}
-
-/* --------------------------------
- * StartTransactionCommand
- * --------------------------------
- */
-void
-StartTransactionCommand()
-{
- TransactionState s = CurrentTransactionState;
-
- switch(s->blockState) {
/* ----------------
- * if we aren't in a transaction block, we
- * just do our usual start transaction.
+ * check the current transaction state
* ----------------
*/
- case TBLOCK_DEFAULT:
- StartTransaction();
- break;
-
- /* ----------------
- * We should never experience this -- if we do it
- * means the BEGIN state was not changed in the previous
- * CommitTransactionCommand(). If we get it, we print
- * a warning and change to the in-progress state.
- * ----------------
- */
- case TBLOCK_BEGIN:
- elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_BEGIN");
- s->blockState = TBLOCK_INPROGRESS;
- break;
-
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ if (s->state != TRANS_INPROGRESS)
+ elog(NOTICE, "CommitTransaction and not in in-progress state ");
+
/* ----------------
- * This is the case when are somewhere in a transaction
- * block and about to start a new command. For now we
- * do nothing but someday we may do command-local resource
- * initialization.
+ * set the current transaction state information
+ * appropriately during the abort processing
* ----------------
*/
- case TBLOCK_INPROGRESS:
- break;
-
+ s->state = TRANS_COMMIT;
+
/* ----------------
- * As with BEGIN, we should never experience this --
- * if we do it means the END state was not changed in the
- * previous CommitTransactionCommand(). If we get it, we
- * print a warning, commit the transaction, start a new
- * transaction and change to the default state.
+ * do commit processing
* ----------------
*/
- case TBLOCK_END:
- elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_END");
- s->blockState = TBLOCK_DEFAULT;
- CommitTransaction();
- StartTransaction();
- break;
-
+ CloseSequences();
+ DestroyTempRels();
+ AtEOXact_portals();
+ RecordTransactionCommit();
+ RelationPurgeLocalRelation(true);
+ AtCommit_Cache();
+ AtCommit_Locks();
+ AtCommit_Memory();
+
/* ----------------
- * Here we are in the middle of a transaction block but
- * one of the commands caused an abort so we do nothing
- * but remain in the abort state. Eventually we will get
- * to the "END TRANSACTION" which will set things straight.
+ * done with commit processing, set current transaction
+ * state back to default
* ----------------
*/
- case TBLOCK_ABORT:
- break;
-
- /* ----------------
- * This means we somehow aborted and the last call to
- * CommitTransactionCommand() didn't clear the state so
- * we remain in the ENDABORT state and mabey next time
- * we get to CommitTransactionCommand() the state will
- * get reset to default.
- * ----------------
+ s->state = TRANS_DEFAULT;
+ { /* want this after commit */
+ if (IsNormalProcessingMode())
+ Async_NotifyAtCommit();
+ }
+
+ /*
+ * Let others to know about no transaction in progress - vadim
+ * 11/26/96
*/
- case TBLOCK_ENDABORT:
- elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_ENDABORT");
- break;
- }
+ if (MyProc != (PROC *) NULL)
+ MyProc->xid = InvalidTransactionId;
}
+
/* --------------------------------
- * CommitTransactionCommand
+ * AbortTransaction
+ *
* --------------------------------
*/
-void
-CommitTransactionCommand()
+static void
+AbortTransaction()
{
- TransactionState s = CurrentTransactionState;
-
- switch(s->blockState) {
- /* ----------------
- * if we aren't in a transaction block, we
- * just do our usual transaction commit
- * ----------------
- */
- case TBLOCK_DEFAULT:
- CommitTransaction();
- break;
-
- /* ----------------
- * This is the case right after we get a "BEGIN TRANSACTION"
- * command, but the user hasn't done anything else yet, so
- * we change to the "transaction block in progress" state
- * and return.
- * ----------------
+ TransactionState s = CurrentTransactionState;
+
+ /*
+ * Let others to know about no transaction in progress - vadim
+ * 11/26/96
*/
- case TBLOCK_BEGIN:
- s->blockState = TBLOCK_INPROGRESS;
- break;
-
+ if (MyProc != (PROC *) NULL)
+ MyProc->xid = InvalidTransactionId;
+
/* ----------------
- * This is the case when we have finished executing a command
- * someplace within a transaction block. We increment the
- * command counter and return. Someday we may free resources
- * local to the command.
- *
- * That someday is today, at least for memory allocated by
- * command in the BlankPortal' HeapMemory context.
- * - vadim 03/25/97
+ * check the current transaction state
* ----------------
*/
- case TBLOCK_INPROGRESS:
- CommandCounterIncrement();
-#ifdef TBL_FREE_CMD_MEMORY
- EndPortalAllocMode ();
- StartPortalAllocMode (DefaultAllocMode, 0);
-#endif
- break;
-
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ if (s->state != TRANS_INPROGRESS)
+ elog(NOTICE, "AbortTransaction and not in in-progress state ");
+
/* ----------------
- * This is the case when we just got the "END TRANSACTION"
- * statement, so we go back to the default state and
- * commit the transaction.
+ * set the current transaction state information
+ * appropriately during the abort processing
* ----------------
*/
- case TBLOCK_END:
- s->blockState = TBLOCK_DEFAULT;
- CommitTransaction();
- break;
-
+ s->state = TRANS_ABORT;
+
/* ----------------
- * Here we are in the middle of a transaction block but
- * one of the commands caused an abort so we do nothing
- * but remain in the abort state. Eventually we will get
- * to the "END TRANSACTION" which will set things straight.
+ * do abort processing
* ----------------
*/
- case TBLOCK_ABORT:
- break;
-
+ CloseSequences();
+ AtEOXact_portals();
+ RecordTransactionAbort();
+ RelationPurgeLocalRelation(false);
+ DestroyTempRels();
+ AtAbort_Cache();
+ AtAbort_Locks();
+ AtAbort_Memory();
+
/* ----------------
- * Here we were in an aborted transaction block which
- * just processed the "END TRANSACTION" command from the
- * user, so now we return the to default state.
+ * done with abort processing, set current transaction
+ * state back to default
* ----------------
*/
- case TBLOCK_ENDABORT:
- s->blockState = TBLOCK_DEFAULT;
- break;
- }
+ s->state = TRANS_DEFAULT;
+ {
+
+ /*
+ * We need to do this in case another process notified us while we
+ * are in the middle of an aborted transaction. We need to notify
+ * our frontend after we finish the current transaction. -- jw,
+ * 1/3/94
+ */
+ if (IsNormalProcessingMode())
+ Async_NotifyAtAbort();
+ }
+}
+
+/* --------------------------------
+ * StartTransactionCommand
+ * --------------------------------
+ */
+void
+StartTransactionCommand()
+{
+ TransactionState s = CurrentTransactionState;
+
+ switch (s->blockState)
+ {
+ /* ----------------
+ * if we aren't in a transaction block, we
+ * just do our usual start transaction.
+ * ----------------
+ */
+ case TBLOCK_DEFAULT:
+ StartTransaction();
+ break;
+
+ /* ----------------
+ * We should never experience this -- if we do it
+ * means the BEGIN state was not changed in the previous
+ * CommitTransactionCommand(). If we get it, we print
+ * a warning and change to the in-progress state.
+ * ----------------
+ */
+ case TBLOCK_BEGIN:
+ elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_BEGIN");
+ s->blockState = TBLOCK_INPROGRESS;
+ break;
+
+ /* ----------------
+ * This is the case when are somewhere in a transaction
+ * block and about to start a new command. For now we
+ * do nothing but someday we may do command-local resource
+ * initialization.
+ * ----------------
+ */
+ case TBLOCK_INPROGRESS:
+ break;
+
+ /* ----------------
+ * As with BEGIN, we should never experience this --
+ * if we do it means the END state was not changed in the
+ * previous CommitTransactionCommand(). If we get it, we
+ * print a warning, commit the transaction, start a new
+ * transaction and change to the default state.
+ * ----------------
+ */
+ case TBLOCK_END:
+ elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_END");
+ s->blockState = TBLOCK_DEFAULT;
+ CommitTransaction();
+ StartTransaction();
+ break;
+
+ /* ----------------
+ * Here we are in the middle of a transaction block but
+ * one of the commands caused an abort so we do nothing
+ * but remain in the abort state. Eventually we will get
+ * to the "END TRANSACTION" which will set things straight.
+ * ----------------
+ */
+ case TBLOCK_ABORT:
+ break;
+
+ /* ----------------
+ * This means we somehow aborted and the last call to
+ * CommitTransactionCommand() didn't clear the state so
+ * we remain in the ENDABORT state and mabey next time
+ * we get to CommitTransactionCommand() the state will
+ * get reset to default.
+ * ----------------
+ */
+ case TBLOCK_ENDABORT:
+ elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_ENDABORT");
+ break;
+ }
+}
+
+/* --------------------------------
+ * CommitTransactionCommand
+ * --------------------------------
+ */
+void
+CommitTransactionCommand()
+{
+ TransactionState s = CurrentTransactionState;
+
+ switch (s->blockState)
+ {
+ /* ----------------
+ * if we aren't in a transaction block, we
+ * just do our usual transaction commit
+ * ----------------
+ */
+ case TBLOCK_DEFAULT:
+ CommitTransaction();
+ break;
+
+ /* ----------------
+ * This is the case right after we get a "BEGIN TRANSACTION"
+ * command, but the user hasn't done anything else yet, so
+ * we change to the "transaction block in progress" state
+ * and return.
+ * ----------------
+ */
+ case TBLOCK_BEGIN:
+ s->blockState = TBLOCK_INPROGRESS;
+ break;
+
+ /* ----------------
+ * This is the case when we have finished executing a command
+ * someplace within a transaction block. We increment the
+ * command counter and return. Someday we may free resources
+ * local to the command.
+ *
+ * That someday is today, at least for memory allocated by
+ * command in the BlankPortal' HeapMemory context.
+ * - vadim 03/25/97
+ * ----------------
+ */
+ case TBLOCK_INPROGRESS:
+ CommandCounterIncrement();
+#ifdef TBL_FREE_CMD_MEMORY
+ EndPortalAllocMode();
+ StartPortalAllocMode(DefaultAllocMode, 0);
+#endif
+ break;
+
+ /* ----------------
+ * This is the case when we just got the "END TRANSACTION"
+ * statement, so we go back to the default state and
+ * commit the transaction.
+ * ----------------
+ */
+ case TBLOCK_END:
+ s->blockState = TBLOCK_DEFAULT;
+ CommitTransaction();
+ break;
+
+ /* ----------------
+ * Here we are in the middle of a transaction block but
+ * one of the commands caused an abort so we do nothing
+ * but remain in the abort state. Eventually we will get
+ * to the "END TRANSACTION" which will set things straight.
+ * ----------------
+ */
+ case TBLOCK_ABORT:
+ break;
+
+ /* ----------------
+ * Here we were in an aborted transaction block which
+ * just processed the "END TRANSACTION" command from the
+ * user, so now we return the to default state.
+ * ----------------
+ */
+ case TBLOCK_ENDABORT:
+ s->blockState = TBLOCK_DEFAULT;
+ break;
+ }
}
/* --------------------------------
- * AbortCurrentTransaction
+ * AbortCurrentTransaction
* --------------------------------
*/
void
AbortCurrentTransaction()
{
- TransactionState s = CurrentTransactionState;
-
- switch(s->blockState) {
- /* ----------------
- * if we aren't in a transaction block, we
- * just do our usual abort transaction.
- * ----------------
- */
- case TBLOCK_DEFAULT:
- AbortTransaction();
- break;
-
- /* ----------------
- * If we are in the TBLOCK_BEGIN it means something
- * screwed up right after reading "BEGIN TRANSACTION"
- * so we enter the abort state. Eventually an "END
- * TRANSACTION" will fix things.
- * ----------------
- */
- case TBLOCK_BEGIN:
- s->blockState = TBLOCK_ABORT;
- AbortTransaction();
- break;
-
+ TransactionState s = CurrentTransactionState;
+
+ switch (s->blockState)
+ {
+ /* ----------------
+ * if we aren't in a transaction block, we
+ * just do our usual abort transaction.
+ * ----------------
+ */
+ case TBLOCK_DEFAULT:
+ AbortTransaction();
+ break;
+
+ /* ----------------
+ * If we are in the TBLOCK_BEGIN it means something
+ * screwed up right after reading "BEGIN TRANSACTION"
+ * so we enter the abort state. Eventually an "END
+ * TRANSACTION" will fix things.
+ * ----------------
+ */
+ case TBLOCK_BEGIN:
+ s->blockState = TBLOCK_ABORT;
+ AbortTransaction();
+ break;
+
+ /* ----------------
+ * This is the case when are somewhere in a transaction
+ * block which aborted so we abort the transaction and
+ * set the ABORT state. Eventually an "END TRANSACTION"
+ * will fix things and restore us to a normal state.
+ * ----------------
+ */
+ case TBLOCK_INPROGRESS:
+ s->blockState = TBLOCK_ABORT;
+ AbortTransaction();
+ break;
+
+ /* ----------------
+ * Here, the system was fouled up just after the
+ * user wanted to end the transaction block so we
+ * abort the transaction and put us back into the
+ * default state.
+ * ----------------
+ */
+ case TBLOCK_END:
+ s->blockState = TBLOCK_DEFAULT;
+ AbortTransaction();
+ break;
+
+ /* ----------------
+ * Here, we are already in an aborted transaction
+ * state and are waiting for an "END TRANSACTION" to
+ * come along and lo and behold, we abort again!
+ * So we just remain in the abort state.
+ * ----------------
+ */
+ case TBLOCK_ABORT:
+ break;
+
+ /* ----------------
+ * Here we were in an aborted transaction block which
+ * just processed the "END TRANSACTION" command but somehow
+ * aborted again.. since we must have done the abort
+ * processing, we return to the default state.
+ * ----------------
+ */
+ case TBLOCK_ENDABORT:
+ s->blockState = TBLOCK_DEFAULT;
+ break;
+ }
+}
+
+/* ----------------------------------------------------------------
+ * transaction block support
+ * ----------------------------------------------------------------
+ */
+/* --------------------------------
+ * BeginTransactionBlock
+ * --------------------------------
+ */
+void
+BeginTransactionBlock(void)
+{
+ TransactionState s = CurrentTransactionState;
+
/* ----------------
- * This is the case when are somewhere in a transaction
- * block which aborted so we abort the transaction and
- * set the ABORT state. Eventually an "END TRANSACTION"
- * will fix things and restore us to a normal state.
+ * check the current transaction state
* ----------------
*/
- case TBLOCK_INPROGRESS:
- s->blockState = TBLOCK_ABORT;
- AbortTransaction();
- break;
-
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ if (s->blockState != TBLOCK_DEFAULT)
+ elog(NOTICE, "BeginTransactionBlock and not in default state ");
+
/* ----------------
- * Here, the system was fouled up just after the
- * user wanted to end the transaction block so we
- * abort the transaction and put us back into the
- * default state.
+ * set the current transaction block state information
+ * appropriately during begin processing
* ----------------
*/
- case TBLOCK_END:
- s->blockState = TBLOCK_DEFAULT;
- AbortTransaction();
- break;
-
+ s->blockState = TBLOCK_BEGIN;
+
/* ----------------
- * Here, we are already in an aborted transaction
- * state and are waiting for an "END TRANSACTION" to
- * come along and lo and behold, we abort again!
- * So we just remain in the abort state.
+ * do begin processing
* ----------------
*/
- case TBLOCK_ABORT:
- break;
-
+
/* ----------------
- * Here we were in an aborted transaction block which
- * just processed the "END TRANSACTION" command but somehow
- * aborted again.. since we must have done the abort
- * processing, we return to the default state.
+ * done with begin processing, set block state to inprogress
* ----------------
*/
- case TBLOCK_ENDABORT:
- s->blockState = TBLOCK_DEFAULT;
- break;
- }
-}
-
-/* ----------------------------------------------------------------
- * transaction block support
- * ----------------------------------------------------------------
- */
-/* --------------------------------
- * BeginTransactionBlock
- * --------------------------------
- */
-void
-BeginTransactionBlock(void)
-{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- if (s->blockState != TBLOCK_DEFAULT)
- elog(NOTICE, "BeginTransactionBlock and not in default state ");
-
- /* ----------------
- * set the current transaction block state information
- * appropriately during begin processing
- * ----------------
- */
- s->blockState = TBLOCK_BEGIN;
-
- /* ----------------
- * do begin processing
- * ----------------
- */
-
- /* ----------------
- * done with begin processing, set block state to inprogress
- * ----------------
- */
- s->blockState = TBLOCK_INPROGRESS;
+ s->blockState = TBLOCK_INPROGRESS;
}
/* --------------------------------
- * EndTransactionBlock
+ * EndTransactionBlock
* --------------------------------
*/
void
EndTransactionBlock(void)
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- if (s->blockState == TBLOCK_INPROGRESS) {
+ TransactionState s = CurrentTransactionState;
+
/* ----------------
- * here we are in a transaction block which should commit
- * when we get to the upcoming CommitTransactionCommand()
- * so we set the state to "END". CommitTransactionCommand()
- * will recognize this and commit the transaction and return
- * us to the default state
+ * check the current transaction state
* ----------------
*/
- s->blockState = TBLOCK_END;
- return;
- }
-
- if (s->blockState == TBLOCK_ABORT) {
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ if (s->blockState == TBLOCK_INPROGRESS)
+ {
+ /* ----------------
+ * here we are in a transaction block which should commit
+ * when we get to the upcoming CommitTransactionCommand()
+ * so we set the state to "END". CommitTransactionCommand()
+ * will recognize this and commit the transaction and return
+ * us to the default state
+ * ----------------
+ */
+ s->blockState = TBLOCK_END;
+ return;
+ }
+
+ if (s->blockState == TBLOCK_ABORT)
+ {
+ /* ----------------
+ * here, we are in a transaction block which aborted
+ * and since the AbortTransaction() was already done,
+ * we do whatever is needed and change to the special
+ * "END ABORT" state. The upcoming CommitTransactionCommand()
+ * will recognise this and then put us back in the default
+ * state.
+ * ----------------
+ */
+ s->blockState = TBLOCK_ENDABORT;
+ return;
+ }
+
/* ----------------
- * here, we are in a transaction block which aborted
- * and since the AbortTransaction() was already done,
- * we do whatever is needed and change to the special
- * "END ABORT" state. The upcoming CommitTransactionCommand()
- * will recognise this and then put us back in the default
- * state.
+ * We should not get here, but if we do, we go to the ENDABORT
+ * state after printing a warning. The upcoming call to
+ * CommitTransactionCommand() will then put us back into the
+ * default state.
* ----------------
*/
+ elog(NOTICE, "EndTransactionBlock and not inprogress/abort state ");
s->blockState = TBLOCK_ENDABORT;
- return;
- }
-
- /* ----------------
- * We should not get here, but if we do, we go to the ENDABORT
- * state after printing a warning. The upcoming call to
- * CommitTransactionCommand() will then put us back into the
- * default state.
- * ----------------
- */
- elog(NOTICE, "EndTransactionBlock and not inprogress/abort state ");
- s->blockState = TBLOCK_ENDABORT;
}
/* --------------------------------
- * AbortTransactionBlock
+ * AbortTransactionBlock
* --------------------------------
*/
#ifdef NOT_USED
static void
AbortTransactionBlock(void)
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- if (s->blockState == TBLOCK_INPROGRESS) {
+ TransactionState s = CurrentTransactionState;
+
/* ----------------
- * here we were inside a transaction block something
- * screwed up inside the system so we enter the abort state,
- * do the abort processing and then return.
- * We remain in the abort state until we see the upcoming
- * END TRANSACTION command.
+ * check the current transaction state
* ----------------
*/
- s->blockState = TBLOCK_ABORT;
-
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ if (s->blockState == TBLOCK_INPROGRESS)
+ {
+ /* ----------------
+ * here we were inside a transaction block something
+ * screwed up inside the system so we enter the abort state,
+ * do the abort processing and then return.
+ * We remain in the abort state until we see the upcoming
+ * END TRANSACTION command.
+ * ----------------
+ */
+ s->blockState = TBLOCK_ABORT;
+
+ /* ----------------
+ * do abort processing and return
+ * ----------------
+ */
+ AbortTransaction();
+ return;
+ }
+
/* ----------------
- * do abort processing and return
+ * this case should not be possible, because it would mean
+ * the user entered an "abort" from outside a transaction block.
+ * So we print an error message, abort the transaction and
+ * enter the "ENDABORT" state so we will end up in the default
+ * state after the upcoming CommitTransactionCommand().
* ----------------
*/
+ elog(NOTICE, "AbortTransactionBlock and not in in-progress state");
AbortTransaction();
- return;
- }
-
- /* ----------------
- * this case should not be possible, because it would mean
- * the user entered an "abort" from outside a transaction block.
- * So we print an error message, abort the transaction and
- * enter the "ENDABORT" state so we will end up in the default
- * state after the upcoming CommitTransactionCommand().
- * ----------------
- */
- elog(NOTICE, "AbortTransactionBlock and not in in-progress state");
- AbortTransaction();
- s->blockState = TBLOCK_ENDABORT;
+ s->blockState = TBLOCK_ENDABORT;
}
+
#endif
/* --------------------------------
- * UserAbortTransactionBlock
+ * UserAbortTransactionBlock
* --------------------------------
*/
void
UserAbortTransactionBlock()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- /*
- * if the transaction has already been automatically aborted with an error,
- * and the user subsequently types 'abort', allow it. (the behavior is
- * the same as if they had typed 'end'.)
- */
- if (s->blockState == TBLOCK_ABORT) {
- s->blockState = TBLOCK_ENDABORT;
- return;
- }
-
- if (s->blockState == TBLOCK_INPROGRESS) {
+ TransactionState s = CurrentTransactionState;
+
/* ----------------
- * here we were inside a transaction block and we
- * got an abort command from the user, so we move to
- * the abort state, do the abort processing and
- * then change to the ENDABORT state so we will end up
- * in the default state after the upcoming
- * CommitTransactionCommand().
+ * check the current transaction state
* ----------------
*/
- s->blockState = TBLOCK_ABORT;
-
- /* ----------------
- * do abort processing
- * ----------------
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ /*
+ * if the transaction has already been automatically aborted with an
+ * error, and the user subsequently types 'abort', allow it. (the
+ * behavior is the same as if they had typed 'end'.)
*/
- AbortTransaction();
-
+ if (s->blockState == TBLOCK_ABORT)
+ {
+ s->blockState = TBLOCK_ENDABORT;
+ return;
+ }
+
+ if (s->blockState == TBLOCK_INPROGRESS)
+ {
+ /* ----------------
+ * here we were inside a transaction block and we
+ * got an abort command from the user, so we move to
+ * the abort state, do the abort processing and
+ * then change to the ENDABORT state so we will end up
+ * in the default state after the upcoming
+ * CommitTransactionCommand().
+ * ----------------
+ */
+ s->blockState = TBLOCK_ABORT;
+
+ /* ----------------
+ * do abort processing
+ * ----------------
+ */
+ AbortTransaction();
+
+ /* ----------------
+ * change to the end abort state and return
+ * ----------------
+ */
+ s->blockState = TBLOCK_ENDABORT;
+ return;
+ }
+
/* ----------------
- * change to the end abort state and return
+ * this case should not be possible, because it would mean
+ * the user entered an "abort" from outside a transaction block.
+ * So we print an error message, abort the transaction and
+ * enter the "ENDABORT" state so we will end up in the default
+ * state after the upcoming CommitTransactionCommand().
* ----------------
*/
+ elog(NOTICE, "UserAbortTransactionBlock and not in in-progress state");
+ AbortTransaction();
s->blockState = TBLOCK_ENDABORT;
- return;
- }
-
- /* ----------------
- * this case should not be possible, because it would mean
- * the user entered an "abort" from outside a transaction block.
- * So we print an error message, abort the transaction and
- * enter the "ENDABORT" state so we will end up in the default
- * state after the upcoming CommitTransactionCommand().
- * ----------------
- */
- elog(NOTICE, "UserAbortTransactionBlock and not in in-progress state");
- AbortTransaction();
- s->blockState = TBLOCK_ENDABORT;
}
bool
IsTransactionBlock()
{
- TransactionState s = CurrentTransactionState;
-
- if (s->blockState == TBLOCK_INPROGRESS
- || s->blockState == TBLOCK_ENDABORT) {
- return (true);
- }
-
- return (false);
+ TransactionState s = CurrentTransactionState;
+
+ if (s->blockState == TBLOCK_INPROGRESS
+ || s->blockState == TBLOCK_ENDABORT)
+ {
+ return (true);
+ }
+
+ return (false);
}
diff --git a/src/backend/access/transam/xid.c b/src/backend/access/transam/xid.c
index 16e55e26411..910d6ac7320 100644
--- a/src/backend/access/transam/xid.c
+++ b/src/backend/access/transam/xid.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* xid.c--
- * POSTGRES transaction identifier code.
+ * POSTGRES transaction identifier code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/xid.c,v 1.7 1997/08/19 21:30:20 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/xid.c,v 1.8 1997/09/07 04:39:40 momjian Exp $
*
* OLD COMMENTS
* XXX WARNING
- * Much of this file will change when we change our representation
- * of transaction ids -cim 3/23/90
+ * Much of this file will change when we change our representation
+ * of transaction ids -cim 3/23/90
*
* It is time to make the switch from 5 byte to 4 byte transaction ids
* This file was totally reworked. -mer 5/22/92
@@ -31,127 +31,127 @@ extern TransactionId AmiTransactionId;
extern TransactionId FirstTransactionId;
/* ----------------------------------------------------------------
- * TransactionIdIsValid
+ * TransactionIdIsValid
*
- * Macro-ize me.
+ * Macro-ize me.
* ----------------------------------------------------------------
*/
bool
TransactionIdIsValid(TransactionId transactionId)
{
- return ((bool) (transactionId != NullTransactionId) );
+ return ((bool) (transactionId != NullTransactionId));
}
/* XXX char16 name for catalogs */
TransactionId
xidin(char *representation)
{
- return (atol(representation));
+ return (atol(representation));
}
/* XXX char16 name for catalogs */
-char*
+char *
xidout(TransactionId transactionId)
{
-/* return(TransactionIdFormString(transactionId)); */
- char *representation;
-
- /* maximum 32 bit unsigned integer representation takes 10 chars */
- representation = palloc(11);
-
- sprintf(representation, "%u", transactionId);
-
- return (representation);
+/* return(TransactionIdFormString(transactionId)); */
+ char *representation;
+
+ /* maximum 32 bit unsigned integer representation takes 10 chars */
+ representation = palloc(11);
+
+ sprintf(representation, "%u", transactionId);
+
+ return (representation);
}
/* ----------------------------------------------------------------
- * StoreInvalidTransactionId
+ * StoreInvalidTransactionId
*
- * Maybe do away with Pointer types in these routines.
- * Macro-ize this one.
+ * Maybe do away with Pointer types in these routines.
+ * Macro-ize this one.
* ----------------------------------------------------------------
*/
void
-StoreInvalidTransactionId(TransactionId *destination)
+StoreInvalidTransactionId(TransactionId * destination)
{
- *destination = NullTransactionId;
+ *destination = NullTransactionId;
}
/* ----------------------------------------------------------------
- * TransactionIdStore
+ * TransactionIdStore
*
- * Macro-ize this one.
+ * Macro-ize this one.
* ----------------------------------------------------------------
*/
void
TransactionIdStore(TransactionId transactionId,
- TransactionId *destination)
+ TransactionId * destination)
{
- *destination = transactionId;
+ *destination = transactionId;
}
/* ----------------------------------------------------------------
- * TransactionIdEquals
+ * TransactionIdEquals
* ----------------------------------------------------------------
*/
bool
TransactionIdEquals(TransactionId id1, TransactionId id2)
{
- return ((bool) (id1 == id2));
+ return ((bool) (id1 == id2));
}
/* ----------------------------------------------------------------
- * TransactionIdIsLessThan
+ * TransactionIdIsLessThan
* ----------------------------------------------------------------
*/
bool
TransactionIdIsLessThan(TransactionId id1, TransactionId id2)
{
- return ((bool)(id1 < id2));
+ return ((bool) (id1 < id2));
}
/* ----------------------------------------------------------------
- * xideq
+ * xideq
* ----------------------------------------------------------------
*/
/*
- * xideq - returns 1, iff xid1 == xid2
- * 0 else;
+ * xideq - returns 1, iff xid1 == xid2
+ * 0 else;
*/
bool
xideq(TransactionId xid1, TransactionId xid2)
{
- return( (bool) (xid1 == xid2) );
+ return ((bool) (xid1 == xid2));
}
/* ----------------------------------------------------------------
- * TransactionIdIncrement
+ * TransactionIdIncrement
* ----------------------------------------------------------------
*/
#ifdef NOT_USED
void
-TransactionIdIncrement(TransactionId *transactionId)
+TransactionIdIncrement(TransactionId * transactionId)
{
-
- (*transactionId)++;
- if (*transactionId == DisabledTransactionId)
- elog(FATAL, "TransactionIdIncrement: exhausted XID's");
- return;
+
+ (*transactionId)++;
+ if (*transactionId == DisabledTransactionId)
+ elog(FATAL, "TransactionIdIncrement: exhausted XID's");
+ return;
}
+
#endif
/* ----------------------------------------------------------------
- * TransactionIdAdd
+ * TransactionIdAdd
* ----------------------------------------------------------------
*/
void
-TransactionIdAdd(TransactionId *xid, int value)
+TransactionIdAdd(TransactionId * xid, int value)
{
- *xid += value;
- return;
+ *xid += value;
+ return;
}
-
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 6b27010d3a9..9fd4bf719b3 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -1,23 +1,23 @@
/*-------------------------------------------------------------------------
*
* bootstrap.c--
- * routines to support running postgres in 'bootstrap' mode
- * bootstrap mode is used to create the initial template database
+ * routines to support running postgres in 'bootstrap' mode
+ * bootstrap mode is used to create the initial template database
*
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.21 1997/08/19 21:30:24 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.22 1997/09/07 04:39:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <unistd.h> /* For getopt() */
+#include <unistd.h> /* For getopt() */
#include <time.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
-#define BOOTSTRAP_INCLUDE /* mask out stuff in tcop/tcopprot.h */
+#define BOOTSTRAP_INCLUDE /* mask out stuff in tcop/tcopprot.h */
#include "postgres.h"
@@ -41,7 +41,7 @@
#include "utils/nabstime.h"
#include "access/htup.h"
#include "utils/tqual.h"
-#include "storage/buf.h"
+#include "storage/buf.h"
#include "access/relscan.h"
#include "access/heapam.h"
@@ -55,7 +55,7 @@
#include "catalog/pg_type.h"
-#include "access/itup.h"
+#include "access/itup.h"
#include "bootstrap/bootstrap.h"
#include "tcop/tcopprot.h"
@@ -69,7 +69,7 @@
#include "access/xact.h"
#ifndef HAVE_MEMMOVE
-# include "regex/utils.h"
+#include "regex/utils.h"
#endif
#include <string.h>
@@ -100,20 +100,20 @@
#include "utils/palloc.h"
-#define ALLOC(t, c) (t *)calloc((unsigned)(c), sizeof(t))
-#define FIRST_TYPE_OID 16 /* OID of the first type */
+#define ALLOC(t, c) (t *)calloc((unsigned)(c), sizeof(t))
+#define FIRST_TYPE_OID 16 /* OID of the first type */
-extern int Int_yyparse (void);
+extern int Int_yyparse(void);
static hashnode *AddStr(char *str, int strlength, int mderef);
static AttributeTupleForm AllocateAttribute(void);
-static bool BootstrapAlreadySeen(Oid id);
-static int CompHash (char *str, int len);
-static hashnode *FindStr (char *str, int length, hashnode *mderef);
-static int gettype(char *type);
-static void cleanup(void);
+static bool BootstrapAlreadySeen(Oid id);
+static int CompHash(char *str, int len);
+static hashnode *FindStr(char *str, int length, hashnode * mderef);
+static int gettype(char *type);
+static void cleanup(void);
/* ----------------
- * global variables
+ * global variables
* ----------------
*/
/*
@@ -126,130 +126,138 @@ static void cleanup(void);
* position of its string pointer in the array of string pointers.
*/
-#define STRTABLESIZE 10000
-#define HASHTABLESIZE 503
+#define STRTABLESIZE 10000
+#define HASHTABLESIZE 503
/* Hash function numbers */
-#define NUM 23
-#define NUMSQR 529
+#define NUM 23
+#define NUMSQR 529
#define NUMCUBE 12167
-char *strtable [STRTABLESIZE];
-hashnode *hashtable [HASHTABLESIZE];
+char *strtable[STRTABLESIZE];
+hashnode *hashtable[HASHTABLESIZE];
-static int strtable_end = -1; /* Tells us last occupied string space */
+static int strtable_end = -1; /* Tells us last occupied string
+ * space */
/*-
* Basic information associated with each type. This is used before
* pg_type is created.
*
- * XXX several of these input/output functions do catalog scans
- * (e.g., F_REGPROCIN scans pg_proc). this obviously creates some
- * order dependencies in the catalog creation process.
+ * XXX several of these input/output functions do catalog scans
+ * (e.g., F_REGPROCIN scans pg_proc). this obviously creates some
+ * order dependencies in the catalog creation process.
*/
-struct typinfo {
- char name[NAMEDATALEN];
- Oid oid;
- Oid elem;
- int16 len;
- Oid inproc;
- Oid outproc;
+struct typinfo
+{
+ char name[NAMEDATALEN];
+ Oid oid;
+ Oid elem;
+ int16 len;
+ Oid inproc;
+ Oid outproc;
};
static struct typinfo Procid[] = {
- { "bool", 16, 0, 1, F_BOOLIN, F_BOOLOUT },
- { "bytea", 17, 0, -1, F_BYTEAIN, F_BYTEAOUT },
- { "char", 18, 0, 1, F_CHARIN, F_CHAROUT },
- { "name", 19, 0, NAMEDATALEN, F_NAMEIN, F_NAMEOUT },
- { "char16", 20, 0, 16, F_CHAR16IN, F_CHAR16OUT},
-/* { "dt", 20, 0, 4, F_DTIN, F_DTOUT}, */
- { "int2", 21, 0, 2, F_INT2IN, F_INT2OUT },
- { "int28", 22, 0, 16, F_INT28IN, F_INT28OUT },
- { "int4", 23, 0, 4, F_INT4IN, F_INT4OUT },
- { "regproc", 24, 0, 4, F_REGPROCIN, F_REGPROCOUT },
- { "text", 25, 0, -1, F_TEXTIN, F_TEXTOUT },
- { "oid", 26, 0, 4, F_INT4IN, F_INT4OUT },
- { "tid", 27, 0, 6, F_TIDIN, F_TIDOUT },
- { "xid", 28, 0, 5, F_XIDIN, F_XIDOUT },
- { "iid", 29, 0, 1, F_CIDIN, F_CIDOUT },
- { "oid8", 30, 0, 32, F_OID8IN, F_OID8OUT },
- { "smgr", 210, 0, 2, F_SMGRIN, F_SMGROUT },
- { "_int4", 1007, 23, -1, F_ARRAY_IN, F_ARRAY_OUT },
- { "_aclitem", 1034, 1033, -1, F_ARRAY_IN, F_ARRAY_OUT }
+ {"bool", 16, 0, 1, F_BOOLIN, F_BOOLOUT},
+ {"bytea", 17, 0, -1, F_BYTEAIN, F_BYTEAOUT},
+ {"char", 18, 0, 1, F_CHARIN, F_CHAROUT},
+ {"name", 19, 0, NAMEDATALEN, F_NAMEIN, F_NAMEOUT},
+ {"char16", 20, 0, 16, F_CHAR16IN, F_CHAR16OUT},
+/* { "dt", 20, 0, 4, F_DTIN, F_DTOUT}, */
+ {"int2", 21, 0, 2, F_INT2IN, F_INT2OUT},
+ {"int28", 22, 0, 16, F_INT28IN, F_INT28OUT},
+ {"int4", 23, 0, 4, F_INT4IN, F_INT4OUT},
+ {"regproc", 24, 0, 4, F_REGPROCIN, F_REGPROCOUT},
+ {"text", 25, 0, -1, F_TEXTIN, F_TEXTOUT},
+ {"oid", 26, 0, 4, F_INT4IN, F_INT4OUT},
+ {"tid", 27, 0, 6, F_TIDIN, F_TIDOUT},
+ {"xid", 28, 0, 5, F_XIDIN, F_XIDOUT},
+ {"iid", 29, 0, 1, F_CIDIN, F_CIDOUT},
+ {"oid8", 30, 0, 32, F_OID8IN, F_OID8OUT},
+ {"smgr", 210, 0, 2, F_SMGRIN, F_SMGROUT},
+ {"_int4", 1007, 23, -1, F_ARRAY_IN, F_ARRAY_OUT},
+ {"_aclitem", 1034, 1033, -1, F_ARRAY_IN, F_ARRAY_OUT}
};
-static int n_types = sizeof(Procid) / sizeof(struct typinfo);
+static int n_types = sizeof(Procid) / sizeof(struct typinfo);
-struct typmap { /* a hack */
- Oid am_oid;
- TypeTupleFormData am_typ;
+struct typmap
+{ /* a hack */
+ Oid am_oid;
+ TypeTupleFormData am_typ;
};
-static struct typmap **Typ = (struct typmap **)NULL;
-static struct typmap *Ap = (struct typmap *)NULL;
-
-static int Warnings = 0;
-static char Blanks[MAXATTR];
-
-static char *relname; /* current relation name */
+static struct typmap **Typ = (struct typmap **) NULL;
+static struct typmap *Ap = (struct typmap *) NULL;
+
+static int Warnings = 0;
+static char Blanks[MAXATTR];
+
+static char *relname; /* current relation name */
-AttributeTupleForm attrtypes[MAXATTR]; /* points to attribute info */
-static char *values[MAXATTR]; /* cooresponding attribute values */
-int numattr; /* number of attributes for cur. rel */
-extern int fsyncOff; /* do not fsync the database */
+AttributeTupleForm attrtypes[MAXATTR]; /* points to attribute info */
+static char *values[MAXATTR];/* cooresponding attribute values */
+int numattr; /* number of attributes for cur. rel */
+extern int fsyncOff; /* do not fsync the database */
#ifndef HAVE_SIGSETJMP
-static jmp_buf Warn_restart;
-#define sigsetjmp(x,y) setjmp(x)
+static jmp_buf Warn_restart;
+
+#define sigsetjmp(x,y) setjmp(x)
#define siglongjmp longjmp
#else
static sigjmp_buf Warn_restart;
+
#endif
-int DebugMode;
-static GlobalMemory nogc = (GlobalMemory) NULL; /* special no-gc mem context */
+int DebugMode;
+static GlobalMemory nogc = (GlobalMemory) NULL; /* special no-gc mem
+ * context */
+
+extern int optind;
+extern char *optarg;
-extern int optind;
-extern char *optarg;
-
/*
- * At bootstrap time, we first declare all the indices to be built, and
- * then build them. The IndexList structure stores enough information
- * to allow us to build the indices after they've been declared.
+ * At bootstrap time, we first declare all the indices to be built, and
+ * then build them. The IndexList structure stores enough information
+ * to allow us to build the indices after they've been declared.
*/
-typedef struct _IndexList {
- char* il_heap;
- char* il_ind;
- int il_natts;
- AttrNumber *il_attnos;
- uint16 il_nparams;
- Datum * il_params;
- FuncIndexInfo *il_finfo;
- PredInfo *il_predInfo;
- struct _IndexList *il_next;
-} IndexList;
+typedef struct _IndexList
+{
+ char *il_heap;
+ char *il_ind;
+ int il_natts;
+ AttrNumber *il_attnos;
+ uint16 il_nparams;
+ Datum *il_params;
+ FuncIndexInfo *il_finfo;
+ PredInfo *il_predInfo;
+ struct _IndexList *il_next;
+} IndexList;
static IndexList *ILHead = (IndexList *) NULL;
-
-typedef void (*sig_func)();
+
+typedef void (*sig_func) ();
+
+
-
/* ----------------------------------------------------------------
- * misc functions
+ * misc functions
* ----------------------------------------------------------------
*/
/* ----------------
- * error handling / abort routines
+ * error handling / abort routines
* ----------------
*/
void
err_out(void)
{
- Warnings++;
- cleanup();
+ Warnings++;
+ cleanup();
}
/* usage:
@@ -258,15 +266,15 @@ err_out(void)
static void
usage(void)
{
- fprintf(stderr,"Usage: postgres -boot [-d] [-C] [-F] [-O] [-Q] ");
- fprintf(stderr,"[-P portno] [dbName]\n");
- fprintf(stderr," d: debug mode\n");
- fprintf(stderr," C: disable version checking\n");
- fprintf(stderr," F: turn off fsync\n");
- fprintf(stderr," O: set BootstrapProcessing mode\n");
- fprintf(stderr," P portno: specify port number\n");
-
- exitpg(1);
+ fprintf(stderr, "Usage: postgres -boot [-d] [-C] [-F] [-O] [-Q] ");
+ fprintf(stderr, "[-P portno] [dbName]\n");
+ fprintf(stderr, " d: debug mode\n");
+ fprintf(stderr, " C: disable version checking\n");
+ fprintf(stderr, " F: turn off fsync\n");
+ fprintf(stderr, " O: set BootstrapProcessing mode\n");
+ fprintf(stderr, " P portno: specify port number\n");
+
+ exitpg(1);
}
@@ -274,286 +282,316 @@ usage(void)
int
BootstrapMain(int argc, char *argv[])
/* ----------------------------------------------------------------
- * The main loop for handling the backend in bootstrap mode
- * the bootstrap mode is used to initialize the template database
- * the bootstrap backend doesn't speak SQL, but instead expects
- * commands in a special bootstrap language.
+ * The main loop for handling the backend in bootstrap mode
+ * the bootstrap mode is used to initialize the template database
+ * the bootstrap backend doesn't speak SQL, but instead expects
+ * commands in a special bootstrap language.
*
- * The arguments passed in to BootstrapMain are the run-time arguments
- * without the argument '-boot', the caller is required to have
- * removed -boot from the run-time args
+ * The arguments passed in to BootstrapMain are the run-time arguments
+ * without the argument '-boot', the caller is required to have
+ * removed -boot from the run-time args
* ----------------------------------------------------------------
*/
{
- int i;
- int portFd = -1;
- char *dbName;
- int flag;
- int override = 1; /* use BootstrapProcessing or InitProcessing mode */
-
- extern int optind;
- extern char *optarg;
-
- /* ----------------
- * initialize signal handlers
- * ----------------
- */
- pqsignal(SIGINT, (sig_func) die);
+ int i;
+ int portFd = -1;
+ char *dbName;
+ int flag;
+ int override = 1; /* use BootstrapProcessing or
+ * InitProcessing mode */
+
+ extern int optind;
+ extern char *optarg;
+
+ /* ----------------
+ * initialize signal handlers
+ * ----------------
+ */
+ pqsignal(SIGINT, (sig_func) die);
#ifndef win32
- pqsignal(SIGHUP, (sig_func) die);
- pqsignal(SIGTERM, (sig_func) die);
-#endif /* win32 */
-
- /* --------------------
- * initialize globals
- * -------------------
- */
-
- MasterPid = getpid();
-
- /* ----------------
- * process command arguments
- * ----------------
- */
-
- /* Set defaults, to be overriden by explicit options below */
- Quiet = 0;
- Noversion = 0;
- dbName = NULL;
- DataDir = getenv("PGDATA"); /* Null if no PGDATA variable */
-
- while ((flag = getopt(argc, argv, "D:dCOQP:F")) != EOF) {
- switch (flag) {
- case 'D':
- DataDir = optarg;
- break;
- case 'd':
- DebugMode = 1; /* print out debugging info while parsing */
- break;
- case 'C':
- Noversion = 1;
- break;
- case 'F':
- fsyncOff = 1;
- break;
- case 'O':
- override = true;
- break;
- case 'Q':
- Quiet = 1;
- break;
- case 'P':/* specify port */
- portFd = atoi(optarg);
- break;
- default:
- usage();
- break;
- }
- } /* while */
-
- if (argc - optind > 1) {
- usage();
- } else
- if (argc - optind == 1) {
- dbName = argv[optind];
- }
-
- if (!DataDir) {
- fprintf(stderr, "%s does not know where to find the database system "
- "data. You must specify the directory that contains the "
- "database system either by specifying the -D invocation "
- "option or by setting the PGDATA environment variable.\n\n",
- argv[0]);
- exitpg(1);
- }
-
- if (dbName == NULL) {
- dbName = getenv("USER");
- if (dbName == NULL) {
- fputs("bootstrap backend: failed, no db name specified\n", stderr);
- fputs(" and no USER enviroment variable\n", stderr);
- exitpg(1);
- }
- }
-
- /* ----------------
- * initialize input fd
- * ----------------
- */
- if (IsUnderPostmaster == true && portFd < 0) {
- fputs("backend: failed, no -P option with -postmaster opt.\n", stderr);
- exitpg(1);
- }
-
+ pqsignal(SIGHUP, (sig_func) die);
+ pqsignal(SIGTERM, (sig_func) die);
+#endif /* win32 */
+
+ /* --------------------
+ * initialize globals
+ * -------------------
+ */
+
+ MasterPid = getpid();
+
+ /* ----------------
+ * process command arguments
+ * ----------------
+ */
+
+ /* Set defaults, to be overriden by explicit options below */
+ Quiet = 0;
+ Noversion = 0;
+ dbName = NULL;
+ DataDir = getenv("PGDATA"); /* Null if no PGDATA variable */
+
+ while ((flag = getopt(argc, argv, "D:dCOQP:F")) != EOF)
+ {
+ switch (flag)
+ {
+ case 'D':
+ DataDir = optarg;
+ break;
+ case 'd':
+ DebugMode = 1; /* print out debugging info while parsing */
+ break;
+ case 'C':
+ Noversion = 1;
+ break;
+ case 'F':
+ fsyncOff = 1;
+ break;
+ case 'O':
+ override = true;
+ break;
+ case 'Q':
+ Quiet = 1;
+ break;
+ case 'P': /* specify port */
+ portFd = atoi(optarg);
+ break;
+ default:
+ usage();
+ break;
+ }
+ } /* while */
+
+ if (argc - optind > 1)
+ {
+ usage();
+ }
+ else if (argc - optind == 1)
+ {
+ dbName = argv[optind];
+ }
+
+ if (!DataDir)
+ {
+ fprintf(stderr, "%s does not know where to find the database system "
+ "data. You must specify the directory that contains the "
+ "database system either by specifying the -D invocation "
+ "option or by setting the PGDATA environment variable.\n\n",
+ argv[0]);
+ exitpg(1);
+ }
+
+ if (dbName == NULL)
+ {
+ dbName = getenv("USER");
+ if (dbName == NULL)
+ {
+ fputs("bootstrap backend: failed, no db name specified\n", stderr);
+ fputs(" and no USER enviroment variable\n", stderr);
+ exitpg(1);
+ }
+ }
+
+ /* ----------------
+ * initialize input fd
+ * ----------------
+ */
+ if (IsUnderPostmaster == true && portFd < 0)
+ {
+ fputs("backend: failed, no -P option with -postmaster opt.\n", stderr);
+ exitpg(1);
+ }
+
#ifdef win32
- _nt_init();
- _nt_attach();
-#endif /* win32 */
-
-
- /* ----------------
- * backend initialization
- * ----------------
- */
- SetProcessingMode((override) ? BootstrapProcessing : InitProcessing);
- InitPostgres(dbName);
- LockDisable(true);
-
- for (i = 0 ; i < MAXATTR; i++) {
- attrtypes[i]=(AttributeTupleForm )NULL;
- Blanks[i] = ' ';
- }
- for(i = 0; i < STRTABLESIZE; ++i)
- strtable[i] = NULL;
- for(i = 0; i < HASHTABLESIZE; ++i)
- hashtable[i] = NULL;
-
- /* ----------------
- * abort processing resumes here - What to do in WIN32?
- * ----------------
- */
-#ifndef win32
- pqsignal(SIGHUP, handle_warn);
-
- if (sigsetjmp(Warn_restart, 1) != 0) {
+ _nt_init();
+ _nt_attach();
+#endif /* win32 */
+
+
+ /* ----------------
+ * backend initialization
+ * ----------------
+ */
+ SetProcessingMode((override) ? BootstrapProcessing : InitProcessing);
+ InitPostgres(dbName);
+ LockDisable(true);
+
+ for (i = 0; i < MAXATTR; i++)
+ {
+ attrtypes[i] = (AttributeTupleForm) NULL;
+ Blanks[i] = ' ';
+ }
+ for (i = 0; i < STRTABLESIZE; ++i)
+ strtable[i] = NULL;
+ for (i = 0; i < HASHTABLESIZE; ++i)
+ hashtable[i] = NULL;
+
+ /* ----------------
+ * abort processing resumes here - What to do in WIN32?
+ * ----------------
+ */
+#ifndef win32
+ pqsignal(SIGHUP, handle_warn);
+
+ if (sigsetjmp(Warn_restart, 1) != 0)
+ {
#else
- if (setjmp(Warn_restart) != 0) {
-#endif /* win32 */
- Warnings++;
- AbortCurrentTransaction();
- }
-
- /* ----------------
- * process input.
- * ----------------
- */
-
- /* the sed script boot.sed renamed yyparse to Int_yyparse
- for the bootstrap parser to avoid conflicts with the normal SQL
- parser */
- Int_yyparse();
-
- /* clean up processing */
- StartTransactionCommand();
- cleanup();
-
- /* not reached, here to make compiler happy */
- return 0;
+ if (setjmp(Warn_restart) != 0)
+ {
+#endif /* win32 */
+ Warnings++;
+ AbortCurrentTransaction();
+ }
+
+ /* ----------------
+ * process input.
+ * ----------------
+ */
+
+ /*
+ * the sed script boot.sed renamed yyparse to Int_yyparse for the
+ * bootstrap parser to avoid conflicts with the normal SQL parser
+ */
+ Int_yyparse();
+
+ /* clean up processing */
+ StartTransactionCommand();
+ cleanup();
+
+ /* not reached, here to make compiler happy */
+ return 0;
}
/* ----------------------------------------------------------------
- * MANUAL BACKEND INTERACTIVE INTERFACE COMMANDS
+ * MANUAL BACKEND INTERACTIVE INTERFACE COMMANDS
* ----------------------------------------------------------------
*/
/* ----------------
- * boot_openrel
+ * boot_openrel
* ----------------
*/
void
boot_openrel(char *relname)
{
- int i;
- struct typmap **app;
- Relation rdesc;
- HeapScanDesc sdesc;
- HeapTuple tup;
-
- if (strlen(relname) > 15)
- relname[15] ='\000';
-
- if (Typ == (struct typmap **)NULL) {
- StartPortalAllocMode(DefaultAllocMode, 0);
- rdesc = heap_openr(TypeRelationName);
- sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL);
- for (i=0; PointerIsValid(tup=heap_getnext(sdesc,0,(Buffer *)NULL)); ++i);
- heap_endscan(sdesc);
- app = Typ = ALLOC(struct typmap *, i + 1);
- while (i-- > 0)
- *app++ = ALLOC(struct typmap, 1);
- *app = (struct typmap *)NULL;
- sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL);
- app = Typ;
- while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) {
- (*app)->am_oid = tup->t_oid;
- memmove((char *)&(*app++)->am_typ,
- (char *)GETSTRUCT(tup),
- sizeof ((*app)->am_typ));
- }
- heap_endscan(sdesc);
- heap_close(rdesc);
- EndPortalAllocMode();
- }
-
- if (reldesc != NULL) {
- closerel(NULL);
- }
-
- if (!Quiet)
- printf("Amopen: relation %s. attrsize %d\n", relname ? relname : "(null)",
- (int)ATTRIBUTE_TUPLE_SIZE);
-
- reldesc = heap_openr(relname);
- Assert(reldesc);
- numattr = reldesc->rd_rel->relnatts;
- for (i = 0; i < numattr; i++) {
- if (attrtypes[i] == NULL) {
- attrtypes[i] = AllocateAttribute();
- }
- memmove((char *)attrtypes[i],
- (char *)reldesc->rd_att->attrs[i],
- ATTRIBUTE_TUPLE_SIZE);
-
- /* Some old pg_attribute tuples might not have attisset. */
- /* If the attname is attisset, don't look for it - it may
- not be defined yet.
- */
- if (namestrcmp(&attrtypes[i]->attname, "attisset") == 0)
- attrtypes[i]->attisset = get_attisset(reldesc->rd_id,
- attrtypes[i]->attname.data);
- else
- attrtypes[i]->attisset = false;
-
- if (DebugMode) {
- AttributeTupleForm at = attrtypes[i];
- printf("create attribute %d name %s len %d num %d type %d\n",
- i, at->attname.data, at->attlen, at->attnum,
- at->atttypid
- );
- fflush(stdout);
- }
- }
+ int i;
+ struct typmap **app;
+ Relation rdesc;
+ HeapScanDesc sdesc;
+ HeapTuple tup;
+
+ if (strlen(relname) > 15)
+ relname[15] = '\000';
+
+ if (Typ == (struct typmap **) NULL)
+ {
+ StartPortalAllocMode(DefaultAllocMode, 0);
+ rdesc = heap_openr(TypeRelationName);
+ sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL);
+ for (i = 0; PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL)); ++i);
+ heap_endscan(sdesc);
+ app = Typ = ALLOC(struct typmap *, i + 1);
+ while (i-- > 0)
+ *app++ = ALLOC(struct typmap, 1);
+ *app = (struct typmap *) NULL;
+ sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL);
+ app = Typ;
+ while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL)))
+ {
+ (*app)->am_oid = tup->t_oid;
+ memmove((char *) &(*app++)->am_typ,
+ (char *) GETSTRUCT(tup),
+ sizeof((*app)->am_typ));
+ }
+ heap_endscan(sdesc);
+ heap_close(rdesc);
+ EndPortalAllocMode();
+ }
+
+ if (reldesc != NULL)
+ {
+ closerel(NULL);
+ }
+
+ if (!Quiet)
+ printf("Amopen: relation %s. attrsize %d\n", relname ? relname : "(null)",
+ (int) ATTRIBUTE_TUPLE_SIZE);
+
+ reldesc = heap_openr(relname);
+ Assert(reldesc);
+ numattr = reldesc->rd_rel->relnatts;
+ for (i = 0; i < numattr; i++)
+ {
+ if (attrtypes[i] == NULL)
+ {
+ attrtypes[i] = AllocateAttribute();
+ }
+ memmove((char *) attrtypes[i],
+ (char *) reldesc->rd_att->attrs[i],
+ ATTRIBUTE_TUPLE_SIZE);
+
+ /* Some old pg_attribute tuples might not have attisset. */
+
+ /*
+ * If the attname is attisset, don't look for it - it may not be
+ * defined yet.
+ */
+ if (namestrcmp(&attrtypes[i]->attname, "attisset") == 0)
+ attrtypes[i]->attisset = get_attisset(reldesc->rd_id,
+ attrtypes[i]->attname.data);
+ else
+ attrtypes[i]->attisset = false;
+
+ if (DebugMode)
+ {
+ AttributeTupleForm at = attrtypes[i];
+
+ printf("create attribute %d name %s len %d num %d type %d\n",
+ i, at->attname.data, at->attlen, at->attnum,
+ at->atttypid
+ );
+ fflush(stdout);
+ }
+ }
}
/* ----------------
- * closerel
+ * closerel
* ----------------
*/
void
closerel(char *name)
{
- if (name) {
- if (reldesc) {
- if (namestrcmp(RelationGetRelationName(reldesc), name) != 0)
- elog(WARN,"closerel: close of '%s' when '%s' was expected",
- name, relname ? relname : "(null)");
- } else
- elog(WARN,"closerel: close of '%s' before any relation was opened",
- name);
-
- }
-
- if (reldesc == NULL) {
- elog(WARN,"Warning: no opened relation to close.\n");
- } else {
- if (!Quiet) printf("Amclose: relation %s.\n", relname ? relname : "(null)");
- heap_close(reldesc);
- reldesc = (Relation)NULL;
- }
+ if (name)
+ {
+ if (reldesc)
+ {
+ if (namestrcmp(RelationGetRelationName(reldesc), name) != 0)
+ elog(WARN, "closerel: close of '%s' when '%s' was expected",
+ name, relname ? relname : "(null)");
+ }
+ else
+ elog(WARN, "closerel: close of '%s' before any relation was opened",
+ name);
+
+ }
+
+ if (reldesc == NULL)
+ {
+ elog(WARN, "Warning: no opened relation to close.\n");
+ }
+ else
+ {
+ if (!Quiet)
+ printf("Amclose: relation %s.\n", relname ? relname : "(null)");
+ heap_close(reldesc);
+ reldesc = (Relation) NULL;
+ }
}
-
+
+
/* ----------------
* DEFINEATTR()
*
@@ -565,563 +603,626 @@ closerel(char *name)
void
DefineAttr(char *name, char *type, int attnum)
{
- int attlen;
- int t;
-
- if (reldesc != NULL) {
- fputs("Warning: no open relations allowed with 't' command.\n",stderr);
- closerel(relname);
- }
-
- t = gettype(type);
- if (attrtypes[attnum] == (AttributeTupleForm )NULL)
- attrtypes[attnum] = AllocateAttribute();
- if (Typ != (struct typmap **)NULL) {
- attrtypes[attnum]->atttypid = Ap->am_oid;
- namestrcpy(&attrtypes[attnum]->attname, name);
- if (!Quiet) printf("<%s %s> ", attrtypes[attnum]->attname.data, type);
- attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
- attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen;
- attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
- } else {
- attrtypes[attnum]->atttypid = Procid[t].oid;
- namestrcpy(&attrtypes[attnum]->attname,name);
- if (!Quiet) printf("<%s %s> ", attrtypes[attnum]->attname.data, type);
- attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
- attlen = attrtypes[attnum]->attlen = Procid[t].len;
- attrtypes[attnum]->attbyval = (attlen==1) || (attlen==2)||(attlen==4);
- }
+ int attlen;
+ int t;
+
+ if (reldesc != NULL)
+ {
+ fputs("Warning: no open relations allowed with 't' command.\n", stderr);
+ closerel(relname);
+ }
+
+ t = gettype(type);
+ if (attrtypes[attnum] == (AttributeTupleForm) NULL)
+ attrtypes[attnum] = AllocateAttribute();
+ if (Typ != (struct typmap **) NULL)
+ {
+ attrtypes[attnum]->atttypid = Ap->am_oid;
+ namestrcpy(&attrtypes[attnum]->attname, name);
+ if (!Quiet)
+ printf("<%s %s> ", attrtypes[attnum]->attname.data, type);
+ attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
+ attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen;
+ attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
+ }
+ else
+ {
+ attrtypes[attnum]->atttypid = Procid[t].oid;
+ namestrcpy(&attrtypes[attnum]->attname, name);
+ if (!Quiet)
+ printf("<%s %s> ", attrtypes[attnum]->attname.data, type);
+ attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
+ attlen = attrtypes[attnum]->attlen = Procid[t].len;
+ attrtypes[attnum]->attbyval = (attlen == 1) || (attlen == 2) || (attlen == 4);
+ }
}
/* ----------------
- * InsertOneTuple
- * assumes that 'oid' will not be zero.
+ * InsertOneTuple
+ * assumes that 'oid' will not be zero.
* ----------------
*/
void
InsertOneTuple(Oid objectid)
{
- HeapTuple tuple;
- TupleDesc tupDesc;
-
- int i;
-
- if (DebugMode) {
- printf("InsertOneTuple oid %d, %d attrs\n", objectid, numattr);
- fflush(stdout);
- }
-
- tupDesc = CreateTupleDesc(numattr,attrtypes);
- tuple = heap_formtuple(tupDesc,(Datum*)values,Blanks);
- pfree(tupDesc); /* just free's tupDesc, not the attrtypes */
-
- if(objectid !=(Oid)0) {
- tuple->t_oid=objectid;
- }
- heap_insert(reldesc, tuple);
- pfree(tuple);
- if (DebugMode) {
- printf("End InsertOneTuple, objectid=%d\n", objectid);
- fflush(stdout);
- }
- /*
- * Reset blanks for next tuple
- */
- for (i = 0; i<numattr; i++)
- Blanks[i] = ' ';
+ HeapTuple tuple;
+ TupleDesc tupDesc;
+
+ int i;
+
+ if (DebugMode)
+ {
+ printf("InsertOneTuple oid %d, %d attrs\n", objectid, numattr);
+ fflush(stdout);
+ }
+
+ tupDesc = CreateTupleDesc(numattr, attrtypes);
+ tuple = heap_formtuple(tupDesc, (Datum *) values, Blanks);
+ pfree(tupDesc); /* just free's tupDesc, not the attrtypes */
+
+ if (objectid != (Oid) 0)
+ {
+ tuple->t_oid = objectid;
+ }
+ heap_insert(reldesc, tuple);
+ pfree(tuple);
+ if (DebugMode)
+ {
+ printf("End InsertOneTuple, objectid=%d\n", objectid);
+ fflush(stdout);
+ }
+
+ /*
+ * Reset blanks for next tuple
+ */
+ for (i = 0; i < numattr; i++)
+ Blanks[i] = ' ';
}
/* ----------------
- * InsertOneValue
+ * InsertOneValue
* ----------------
*/
void
InsertOneValue(Oid objectid, char *value, int i)
{
- int typeindex;
- char *prt;
- struct typmap **app;
-
- if (DebugMode)
- printf("Inserting value: '%s'\n", value);
- if (i < 0 || i >= MAXATTR) {
- printf("i out of range: %d\n", i);
- Assert(0);
- }
-
- if (Typ != (struct typmap **)NULL) {
- struct typmap *ap;
- if (DebugMode)
- puts("Typ != NULL");
- app = Typ;
- while (*app && (*app)->am_oid != reldesc->rd_att->attrs[i]->atttypid)
- ++app;
- ap = *app;
- if (ap == NULL) {
- printf("Unable to find atttypid in Typ list! %d\n",
- reldesc->rd_att->attrs[i]->atttypid
- );
- Assert(0);
- }
- values[i] = fmgr(ap->am_typ.typinput,
- value,
- ap->am_typ.typelem,
- -1); /* shouldn't have char() or varchar() types
- during boostrapping but just to be safe */
- prt = fmgr(ap->am_typ.typoutput, values[i],
- ap->am_typ.typelem);
- if (!Quiet) printf("%s ", prt);
- pfree(prt);
- } else {
- typeindex = attrtypes[i]->atttypid - FIRST_TYPE_OID;
- if (DebugMode)
- printf("Typ == NULL, typeindex = %d idx = %d\n", typeindex, i);
- values[i] = fmgr(Procid[typeindex].inproc, value,
- Procid[typeindex].elem, -1);
- prt = fmgr(Procid[typeindex].outproc, values[i],
- Procid[typeindex].elem);
- if (!Quiet) printf("%s ", prt);
- pfree(prt);
- }
- if (DebugMode) {
- puts("End InsertValue");
- fflush(stdout);
- }
+ int typeindex;
+ char *prt;
+ struct typmap **app;
+
+ if (DebugMode)
+ printf("Inserting value: '%s'\n", value);
+ if (i < 0 || i >= MAXATTR)
+ {
+ printf("i out of range: %d\n", i);
+ Assert(0);
+ }
+
+ if (Typ != (struct typmap **) NULL)
+ {
+ struct typmap *ap;
+
+ if (DebugMode)
+ puts("Typ != NULL");
+ app = Typ;
+ while (*app && (*app)->am_oid != reldesc->rd_att->attrs[i]->atttypid)
+ ++app;
+ ap = *app;
+ if (ap == NULL)
+ {
+ printf("Unable to find atttypid in Typ list! %d\n",
+ reldesc->rd_att->attrs[i]->atttypid
+ );
+ Assert(0);
+ }
+ values[i] = fmgr(ap->am_typ.typinput,
+ value,
+ ap->am_typ.typelem,
+ -1); /* shouldn't have char() or varchar()
+ * types during boostrapping but just to
+ * be safe */
+ prt = fmgr(ap->am_typ.typoutput, values[i],
+ ap->am_typ.typelem);
+ if (!Quiet)
+ printf("%s ", prt);
+ pfree(prt);
+ }
+ else
+ {
+ typeindex = attrtypes[i]->atttypid - FIRST_TYPE_OID;
+ if (DebugMode)
+ printf("Typ == NULL, typeindex = %d idx = %d\n", typeindex, i);
+ values[i] = fmgr(Procid[typeindex].inproc, value,
+ Procid[typeindex].elem, -1);
+ prt = fmgr(Procid[typeindex].outproc, values[i],
+ Procid[typeindex].elem);
+ if (!Quiet)
+ printf("%s ", prt);
+ pfree(prt);
+ }
+ if (DebugMode)
+ {
+ puts("End InsertValue");
+ fflush(stdout);
+ }
}
/* ----------------
- * InsertOneNull
+ * InsertOneNull
* ----------------
*/
void
InsertOneNull(int i)
{
- if (DebugMode)
- printf("Inserting null\n");
- if (i < 0 || i >= MAXATTR) {
- elog(FATAL, "i out of range (too many attrs): %d\n", i);
- }
- values[i] = (char *)NULL;
- Blanks[i] = 'n';
+ if (DebugMode)
+ printf("Inserting null\n");
+ if (i < 0 || i >= MAXATTR)
+ {
+ elog(FATAL, "i out of range (too many attrs): %d\n", i);
+ }
+ values[i] = (char *) NULL;
+ Blanks[i] = 'n';
}
#define MORE_THAN_THE_NUMBER_OF_CATALOGS 256
-static bool
+static bool
BootstrapAlreadySeen(Oid id)
{
- static Oid seenArray[MORE_THAN_THE_NUMBER_OF_CATALOGS];
- static int nseen = 0;
- bool seenthis;
- int i;
-
- seenthis = false;
-
- for (i=0; i < nseen; i++) {
- if (seenArray[i] == id) {
- seenthis = true;
- break;
- }
- }
- if (!seenthis) {
- seenArray[nseen] = id;
- nseen++;
- }
- return (seenthis);
+ static Oid seenArray[MORE_THAN_THE_NUMBER_OF_CATALOGS];
+ static int nseen = 0;
+ bool seenthis;
+ int i;
+
+ seenthis = false;
+
+ for (i = 0; i < nseen; i++)
+ {
+ if (seenArray[i] == id)
+ {
+ seenthis = true;
+ break;
+ }
+ }
+ if (!seenthis)
+ {
+ seenArray[nseen] = id;
+ nseen++;
+ }
+ return (seenthis);
}
/* ----------------
- * cleanup
+ * cleanup
* ----------------
*/
static void
cleanup()
{
- static int beenhere = 0;
-
- if (!beenhere)
- beenhere = 1;
- else {
- elog(FATAL,"Memory manager fault: cleanup called twice.\n", stderr);
- exitpg(1);
- }
- if (reldesc != (Relation)NULL) {
- heap_close(reldesc);
- }
- CommitTransactionCommand();
- exitpg(Warnings);
+ static int beenhere = 0;
+
+ if (!beenhere)
+ beenhere = 1;
+ else
+ {
+ elog(FATAL, "Memory manager fault: cleanup called twice.\n", stderr);
+ exitpg(1);
+ }
+ if (reldesc != (Relation) NULL)
+ {
+ heap_close(reldesc);
+ }
+ CommitTransactionCommand();
+ exitpg(Warnings);
}
/* ----------------
- * gettype
+ * gettype
* ----------------
*/
static int
gettype(char *type)
{
- int i;
- Relation rdesc;
- HeapScanDesc sdesc;
- HeapTuple tup;
- struct typmap **app;
-
- if (Typ != (struct typmap **)NULL) {
- for (app = Typ; *app != (struct typmap *)NULL; app++) {
- if (strncmp((*app)->am_typ.typname.data, type, NAMEDATALEN) == 0) {
- Ap = *app;
- return((*app)->am_oid);
- }
- }
- } else {
- for (i = 0; i <= n_types; i++) {
- if (strncmp(type, Procid[i].name, NAMEDATALEN) == 0) {
- return(i);
- }
- }
- if (DebugMode)
- printf("bootstrap.c: External Type: %s\n", type);
- rdesc = heap_openr(TypeRelationName);
- sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL);
- i = 0;
- while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL)))
- ++i;
- heap_endscan(sdesc);
- app = Typ = ALLOC(struct typmap *, i + 1);
- while (i-- > 0)
- *app++ = ALLOC(struct typmap, 1);
- *app = (struct typmap *)NULL;
- sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL);
- app = Typ;
- while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) {
- (*app)->am_oid = tup->t_oid;
- memmove((char *)&(*app++)->am_typ,
- (char *)GETSTRUCT(tup),
- sizeof ((*app)->am_typ));
- }
- heap_endscan(sdesc);
- heap_close(rdesc);
- return(gettype(type));
- }
- elog(WARN, "Error: unknown type '%s'.\n", type);
- err_out();
- /* not reached, here to make compiler happy */
- return 0;
+ int i;
+ Relation rdesc;
+ HeapScanDesc sdesc;
+ HeapTuple tup;
+ struct typmap **app;
+
+ if (Typ != (struct typmap **) NULL)
+ {
+ for (app = Typ; *app != (struct typmap *) NULL; app++)
+ {
+ if (strncmp((*app)->am_typ.typname.data, type, NAMEDATALEN) == 0)
+ {
+ Ap = *app;
+ return ((*app)->am_oid);
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i <= n_types; i++)
+ {
+ if (strncmp(type, Procid[i].name, NAMEDATALEN) == 0)
+ {
+ return (i);
+ }
+ }
+ if (DebugMode)
+ printf("bootstrap.c: External Type: %s\n", type);
+ rdesc = heap_openr(TypeRelationName);
+ sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL);
+ i = 0;
+ while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL)))
+ ++i;
+ heap_endscan(sdesc);
+ app = Typ = ALLOC(struct typmap *, i + 1);
+ while (i-- > 0)
+ *app++ = ALLOC(struct typmap, 1);
+ *app = (struct typmap *) NULL;
+ sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL);
+ app = Typ;
+ while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL)))
+ {
+ (*app)->am_oid = tup->t_oid;
+ memmove((char *) &(*app++)->am_typ,
+ (char *) GETSTRUCT(tup),
+ sizeof((*app)->am_typ));
+ }
+ heap_endscan(sdesc);
+ heap_close(rdesc);
+ return (gettype(type));
+ }
+ elog(WARN, "Error: unknown type '%s'.\n", type);
+ err_out();
+ /* not reached, here to make compiler happy */
+ return 0;
}
/* ----------------
- * AllocateAttribute
+ * AllocateAttribute
* ----------------
*/
-static AttributeTupleForm /* XXX */
+static AttributeTupleForm /* XXX */
AllocateAttribute()
{
- AttributeTupleForm attribute =
- (AttributeTupleForm)malloc(ATTRIBUTE_TUPLE_SIZE);
-
- if (!PointerIsValid(attribute)) {
- elog(FATAL, "AllocateAttribute: malloc failed");
- }
- memset(attribute, 0, ATTRIBUTE_TUPLE_SIZE);
-
- return (attribute);
+ AttributeTupleForm attribute =
+ (AttributeTupleForm) malloc(ATTRIBUTE_TUPLE_SIZE);
+
+ if (!PointerIsValid(attribute))
+ {
+ elog(FATAL, "AllocateAttribute: malloc failed");
+ }
+ memset(attribute, 0, ATTRIBUTE_TUPLE_SIZE);
+
+ return (attribute);
}
/* ----------------
- * MapArrayTypeName
+ * MapArrayTypeName
* XXX arrays of "basetype" are always "_basetype".
- * this is an evil hack inherited from rel. 3.1.
+ * this is an evil hack inherited from rel. 3.1.
* XXX array dimension is thrown away because we
- * don't support fixed-dimension arrays. again,
- * sickness from 3.1.
- *
- * the string passed in must have a '[' character in it
+ * don't support fixed-dimension arrays. again,
+ * sickness from 3.1.
+ *
+ * the string passed in must have a '[' character in it
*
* the string returned is a pointer to static storage and should NOT
* be freed by the CALLER.
* ----------------
*/
-char*
+char *
MapArrayTypeName(char *s)
{
- int i, j;
- static char newStr[NAMEDATALEN]; /* array type names < NAMEDATALEN long */
+ int i,
+ j;
+ static char newStr[NAMEDATALEN]; /* array type names <
+ * NAMEDATALEN long */
- if (s == NULL || s[0] == '\0')
- return s;
+ if (s == NULL || s[0] == '\0')
+ return s;
- j = 1;
- newStr[0] = '_';
- for (i=0; i<NAMEDATALEN-1 && s[i] != '['; i++, j++)
- newStr[j] = s[i];
-
- newStr[j] = '\0';
+ j = 1;
+ newStr[0] = '_';
+ for (i = 0; i < NAMEDATALEN - 1 && s[i] != '['; i++, j++)
+ newStr[j] = s[i];
- return newStr;
+ newStr[j] = '\0';
+
+ return newStr;
}
/* ----------------
- * EnterString
- * returns the string table position of the identifier
- * passed to it. We add it to the table if we can't find it.
+ * EnterString
+ * returns the string table position of the identifier
+ * passed to it. We add it to the table if we can't find it.
* ----------------
*/
int
-EnterString (char *str)
+EnterString(char *str)
{
- hashnode *node;
- int len;
-
- len= strlen(str);
-
- node = FindStr(str, len, 0);
- if (node) {
- return (node->strnum);
- } else {
- node = AddStr(str, len, 0);
- return (node->strnum);
- }
+ hashnode *node;
+ int len;
+
+ len = strlen(str);
+
+ node = FindStr(str, len, 0);
+ if (node)
+ {
+ return (node->strnum);
+ }
+ else
+ {
+ node = AddStr(str, len, 0);
+ return (node->strnum);
+ }
}
/* ----------------
- * LexIDStr
- * when given an idnum into the 'string-table' return the string
- * associated with the idnum
+ * LexIDStr
+ * when given an idnum into the 'string-table' return the string
+ * associated with the idnum
* ----------------
*/
-char *
-LexIDStr(int ident_num)
+char *
+LexIDStr(int ident_num)
{
- return(strtable[ident_num]);
-}
+ return (strtable[ident_num]);
+}
/* ----------------
- * CompHash
+ * CompHash
*
- * Compute a hash function for a given string. We look at the first,
- * the last, and the middle character of a string to try to get spread
- * the strings out. The function is rather arbitrary, except that we
- * are mod'ing by a prime number.
+ * Compute a hash function for a given string. We look at the first,
+ * the last, and the middle character of a string to try to get spread
+ * the strings out. The function is rather arbitrary, except that we
+ * are mod'ing by a prime number.
* ----------------
*/
static int
CompHash(char *str, int len)
{
- register int result;
-
- result =(NUM * str[0] + NUMSQR * str[len-1] + NUMCUBE * str[(len-1)/2]);
-
- return (result % HASHTABLESIZE);
-
+ register int result;
+
+ result = (NUM * str[0] + NUMSQR * str[len - 1] + NUMCUBE * str[(len - 1) / 2]);
+
+ return (result % HASHTABLESIZE);
+
}
/* ----------------
- * FindStr
+ * FindStr
*
- * This routine looks for the specified string in the hash
- * table. It returns a pointer to the hash node found,
- * or NULL if the string is not in the table.
+ * This routine looks for the specified string in the hash
+ * table. It returns a pointer to the hash node found,
+ * or NULL if the string is not in the table.
* ----------------
*/
static hashnode *
-FindStr(char *str, int length, hashnode *mderef)
+FindStr(char *str, int length, hashnode * mderef)
{
- hashnode *node;
- node = hashtable [CompHash (str, length)];
- while (node != NULL) {
- /*
- * We must differentiate between string constants that
- * might have the same value as a identifier
- * and the identifier itself.
- */
- if (!strcmp(str, strtable[node->strnum])) {
- return(node); /* no need to check */
- } else {
- node = node->next;
- }
- }
- /* Couldn't find it in the list */
- return (NULL);
+ hashnode *node;
+
+ node = hashtable[CompHash(str, length)];
+ while (node != NULL)
+ {
+
+ /*
+ * We must differentiate between string constants that might have
+ * the same value as a identifier and the identifier itself.
+ */
+ if (!strcmp(str, strtable[node->strnum]))
+ {
+ return (node); /* no need to check */
+ }
+ else
+ {
+ node = node->next;
+ }
+ }
+ /* Couldn't find it in the list */
+ return (NULL);
}
/* ----------------
- * AddStr
+ * AddStr
*
- * This function adds the specified string, along with its associated
- * data, to the hash table and the string table. We return the node
- * so that the calling routine can find out the unique id that AddStr
- * has assigned to this string.
+ * This function adds the specified string, along with its associated
+ * data, to the hash table and the string table. We return the node
+ * so that the calling routine can find out the unique id that AddStr
+ * has assigned to this string.
* ----------------
*/
static hashnode *
AddStr(char *str, int strlength, int mderef)
{
- hashnode *temp, *trail, *newnode;
- int hashresult;
- int len;
-
- if (++strtable_end == STRTABLESIZE) {
- /* Error, string table overflow, so we Punt */
- elog(FATAL,
- "There are too many string constants and identifiers for the compiler to handle.");
-
-
- }
-
- /*
- * Some of the utilites (eg, define type, create relation) assume
- * that the string they're passed is a NAMEDATALEN. We get array bound
- * read violations from purify if we don't allocate at least NAMEDATALEN
- * bytes for strings of this sort. Because we're lazy, we allocate
- * at least NAMEDATALEN bytes all the time.
- */
-
- if ((len = strlength + 1) < NAMEDATALEN)
- len = NAMEDATALEN;
-
- strtable [strtable_end] = malloc((unsigned) len);
- strcpy (strtable[strtable_end], str);
-
- /* Now put a node in the hash table */
-
- newnode = (hashnode*)malloc(sizeof(hashnode)*1);
- newnode->strnum = strtable_end;
- newnode->next = NULL;
-
- /* Find out where it goes */
-
- hashresult = CompHash (str, strlength);
- if (hashtable [hashresult] == NULL) {
- hashtable [hashresult] = newnode;
- } else { /* There is something in the list */
- trail = hashtable [hashresult];
- temp = trail->next;
- while (temp != NULL) {
- trail = temp;
- temp = temp->next;
- }
- trail->next = newnode;
- }
- return (newnode);
+ hashnode *temp,
+ *trail,
+ *newnode;
+ int hashresult;
+ int len;
+
+ if (++strtable_end == STRTABLESIZE)
+ {
+ /* Error, string table overflow, so we Punt */
+ elog(FATAL,
+ "There are too many string constants and identifiers for the compiler to handle.");
+
+
+ }
+
+ /*
+ * Some of the utilites (eg, define type, create relation) assume that
+ * the string they're passed is a NAMEDATALEN. We get array bound
+ * read violations from purify if we don't allocate at least
+ * NAMEDATALEN bytes for strings of this sort. Because we're lazy, we
+ * allocate at least NAMEDATALEN bytes all the time.
+ */
+
+ if ((len = strlength + 1) < NAMEDATALEN)
+ len = NAMEDATALEN;
+
+ strtable[strtable_end] = malloc((unsigned) len);
+ strcpy(strtable[strtable_end], str);
+
+ /* Now put a node in the hash table */
+
+ newnode = (hashnode *) malloc(sizeof(hashnode) * 1);
+ newnode->strnum = strtable_end;
+ newnode->next = NULL;
+
+ /* Find out where it goes */
+
+ hashresult = CompHash(str, strlength);
+ if (hashtable[hashresult] == NULL)
+ {
+ hashtable[hashresult] = newnode;
+ }
+ else
+ { /* There is something in the list */
+ trail = hashtable[hashresult];
+ temp = trail->next;
+ while (temp != NULL)
+ {
+ trail = temp;
+ temp = temp->next;
+ }
+ trail->next = newnode;
+ }
+ return (newnode);
}
/*
- * index_register() -- record an index that has been set up for building
- * later.
+ * index_register() -- record an index that has been set up for building
+ * later.
*
- * At bootstrap time, we define a bunch of indices on system catalogs.
- * We postpone actually building the indices until just before we're
- * finished with initialization, however. This is because more classes
- * and indices may be defined, and we want to be sure that all of them
- * are present in the index.
+ * At bootstrap time, we define a bunch of indices on system catalogs.
+ * We postpone actually building the indices until just before we're
+ * finished with initialization, however. This is because more classes
+ * and indices may be defined, and we want to be sure that all of them
+ * are present in the index.
*/
void
index_register(char *heap,
- char *ind,
- int natts,
- AttrNumber *attnos,
- uint16 nparams,
- Datum *params,
- FuncIndexInfo *finfo,
- PredInfo *predInfo)
+ char *ind,
+ int natts,
+ AttrNumber * attnos,
+ uint16 nparams,
+ Datum * params,
+ FuncIndexInfo * finfo,
+ PredInfo * predInfo)
{
- Datum *v;
- IndexList *newind;
- int len;
- MemoryContext oldcxt;
-
- /*
- * XXX mao 10/31/92 -- don't gc index reldescs, associated info
- * at bootstrap time. we'll declare the indices now, but want to
- * create them later.
- */
-
- if (nogc == (GlobalMemory) NULL)
- nogc = CreateGlobalMemory("BootstrapNoGC");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext) nogc);
-
- newind = (IndexList *) palloc(sizeof(IndexList));
- newind->il_heap = pstrdup(heap);
- newind->il_ind = pstrdup(ind);
- newind->il_natts = natts;
-
- if (PointerIsValid(finfo))
- len = FIgetnArgs(finfo) * sizeof(AttrNumber);
- else
- len = natts * sizeof(AttrNumber);
-
- newind->il_attnos = (AttrNumber *) palloc(len);
- memmove(newind->il_attnos, attnos, len);
-
- if ((newind->il_nparams = nparams) > 0) {
- v = newind->il_params = (Datum *) palloc(2 * nparams * sizeof(Datum));
- nparams *= 2;
- while (nparams-- > 0) {
- *v = (Datum) palloc(strlen((char *)(*params)) + 1);
- strcpy((char *) *v++, (char *) *params++);
- }
- } else {
- newind->il_params = (Datum *) NULL;
- }
-
- if (finfo != (FuncIndexInfo *) NULL) {
- newind->il_finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
- memmove(newind->il_finfo, finfo, sizeof(FuncIndexInfo));
- } else {
- newind->il_finfo = (FuncIndexInfo *) NULL;
- }
-
- if (predInfo != NULL) {
- newind->il_predInfo = (PredInfo*)palloc(sizeof(PredInfo));
- newind->il_predInfo->pred = predInfo->pred;
- newind->il_predInfo->oldPred = predInfo->oldPred;
- } else {
- newind->il_predInfo = NULL;
- }
-
- newind->il_next = ILHead;
-
- ILHead = newind;
-
- MemoryContextSwitchTo(oldcxt);
+ Datum *v;
+ IndexList *newind;
+ int len;
+ MemoryContext oldcxt;
+
+ /*
+ * XXX mao 10/31/92 -- don't gc index reldescs, associated info at
+ * bootstrap time. we'll declare the indices now, but want to create
+ * them later.
+ */
+
+ if (nogc == (GlobalMemory) NULL)
+ nogc = CreateGlobalMemory("BootstrapNoGC");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) nogc);
+
+ newind = (IndexList *) palloc(sizeof(IndexList));
+ newind->il_heap = pstrdup(heap);
+ newind->il_ind = pstrdup(ind);
+ newind->il_natts = natts;
+
+ if (PointerIsValid(finfo))
+ len = FIgetnArgs(finfo) * sizeof(AttrNumber);
+ else
+ len = natts * sizeof(AttrNumber);
+
+ newind->il_attnos = (AttrNumber *) palloc(len);
+ memmove(newind->il_attnos, attnos, len);
+
+ if ((newind->il_nparams = nparams) > 0)
+ {
+ v = newind->il_params = (Datum *) palloc(2 * nparams * sizeof(Datum));
+ nparams *= 2;
+ while (nparams-- > 0)
+ {
+ *v = (Datum) palloc(strlen((char *) (*params)) + 1);
+ strcpy((char *) *v++, (char *) *params++);
+ }
+ }
+ else
+ {
+ newind->il_params = (Datum *) NULL;
+ }
+
+ if (finfo != (FuncIndexInfo *) NULL)
+ {
+ newind->il_finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
+ memmove(newind->il_finfo, finfo, sizeof(FuncIndexInfo));
+ }
+ else
+ {
+ newind->il_finfo = (FuncIndexInfo *) NULL;
+ }
+
+ if (predInfo != NULL)
+ {
+ newind->il_predInfo = (PredInfo *) palloc(sizeof(PredInfo));
+ newind->il_predInfo->pred = predInfo->pred;
+ newind->il_predInfo->oldPred = predInfo->oldPred;
+ }
+ else
+ {
+ newind->il_predInfo = NULL;
+ }
+
+ newind->il_next = ILHead;
+
+ ILHead = newind;
+
+ MemoryContextSwitchTo(oldcxt);
}
void
build_indices()
{
- Relation heap;
- Relation ind;
-
- for ( ; ILHead != (IndexList *) NULL; ILHead = ILHead->il_next) {
- heap = heap_openr(ILHead->il_heap);
- ind = index_openr(ILHead->il_ind);
- index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos,
- ILHead->il_nparams, ILHead->il_params, ILHead->il_finfo,
- ILHead->il_predInfo);
-
- /*
- * All of the rest of this routine is needed only because in bootstrap
- * processing we don't increment xact id's. The normal DefineIndex
- * code replaces a pg_class tuple with updated info including the
- * relhasindex flag (which we need to have updated). Unfortunately,
- * there are always two indices defined on each catalog causing us to
- * update the same pg_class tuple twice for each catalog getting an
- * index during bootstrap resulting in the ghost tuple problem (see
- * heap_replace). To get around this we change the relhasindex
- * field ourselves in this routine keeping track of what catalogs we
- * already changed so that we don't modify those tuples twice. The
- * normal mechanism for updating pg_class is disabled during bootstrap.
- *
- * -mer
- */
- heap = heap_openr(ILHead->il_heap);
-
- if (!BootstrapAlreadySeen(heap->rd_id))
- UpdateStats(heap->rd_id, 0, true);
- }
+ Relation heap;
+ Relation ind;
+
+ for (; ILHead != (IndexList *) NULL; ILHead = ILHead->il_next)
+ {
+ heap = heap_openr(ILHead->il_heap);
+ ind = index_openr(ILHead->il_ind);
+ index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos,
+ ILHead->il_nparams, ILHead->il_params, ILHead->il_finfo,
+ ILHead->il_predInfo);
+
+ /*
+ * All of the rest of this routine is needed only because in
+ * bootstrap processing we don't increment xact id's. The normal
+ * DefineIndex code replaces a pg_class tuple with updated info
+ * including the relhasindex flag (which we need to have updated).
+ * Unfortunately, there are always two indices defined on each
+ * catalog causing us to update the same pg_class tuple twice for
+ * each catalog getting an index during bootstrap resulting in the
+ * ghost tuple problem (see heap_replace). To get around this we
+ * change the relhasindex field ourselves in this routine keeping
+ * track of what catalogs we already changed so that we don't
+ * modify those tuples twice. The normal mechanism for updating
+ * pg_class is disabled during bootstrap.
+ *
+ * -mer
+ */
+ heap = heap_openr(ILHead->il_heap);
+
+ if (!BootstrapAlreadySeen(heap->rd_id))
+ UpdateStats(heap->rd_id, 0, true);
+ }
}
-
diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c
index 90e6dedc18d..a8abbb01eee 100644
--- a/src/backend/catalog/catalog.c
+++ b/src/backend/catalog/catalog.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* catalog.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.7 1997/08/18 20:51:59 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.8 1997/09/07 04:40:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,7 +15,7 @@
#include <postgres.h>
-#include <miscadmin.h> /* for DataDir */
+#include <miscadmin.h> /* for DataDir */
#include <utils/syscache.h>
#include <catalog/catname.h> /* NameIs{,Shared}SystemRelationName */
#include <catalog/pg_type.h>
@@ -23,175 +23,188 @@
#include <access/transam.h>
/*
- * relpath - path to the relation
- * Perhaps this should be in-line code in relopen().
+ * relpath - path to the relation
+ * Perhaps this should be in-line code in relopen().
*/
-char *
+char *
relpath(char relname[])
{
- char *path;
-
- if (IsSharedSystemRelationName(relname)) {
- path = (char *) palloc(strlen(DataDir) + sizeof(NameData) + 2);
- sprintf(path, "%s/%s", DataDir, relname);
- return (path);
- }
- return(relname);
+ char *path;
+
+ if (IsSharedSystemRelationName(relname))
+ {
+ path = (char *) palloc(strlen(DataDir) + sizeof(NameData) + 2);
+ sprintf(path, "%s/%s", DataDir, relname);
+ return (path);
+ }
+ return (relname);
}
#ifdef NOT_USED
/*
- * issystem - returns non-zero iff relname is a system catalog
+ * issystem - returns non-zero iff relname is a system catalog
*
- * We now make a new requirement where system catalog relns must begin
- * with pg_ while user relns are forbidden to do so. Make the test
- * trivial and instantaneous.
+ * We now make a new requirement where system catalog relns must begin
+ * with pg_ while user relns are forbidden to do so. Make the test
+ * trivial and instantaneous.
*
- * XXX this is way bogus. -- pma
+ * XXX this is way bogus. -- pma
*/
bool
issystem(char relname[])
{
- if (relname[0] && relname[1] && relname[2])
- return (relname[0] == 'p' &&
- relname[1] == 'g' &&
- relname[2] == '_');
- else
- return FALSE;
+ if (relname[0] && relname[1] && relname[2])
+ return (relname[0] == 'p' &&
+ relname[1] == 'g' &&
+ relname[2] == '_');
+ else
+ return FALSE;
}
+
#endif
/*
* IsSystemRelationName --
- * True iff name is the name of a system catalog relation.
+ * True iff name is the name of a system catalog relation.
*
- * We now make a new requirement where system catalog relns must begin
- * with pg_ while user relns are forbidden to do so. Make the test
- * trivial and instantaneous.
+ * We now make a new requirement where system catalog relns must begin
+ * with pg_ while user relns are forbidden to do so. Make the test
+ * trivial and instantaneous.
*
- * XXX this is way bogus. -- pma
+ * XXX this is way bogus. -- pma
*/
bool
IsSystemRelationName(char *relname)
{
- if (relname[0] && relname[1] && relname[2])
- return (relname[0] == 'p' &&
- relname[1] == 'g' &&
- relname[2] == '_');
- else
- return FALSE;
+ if (relname[0] && relname[1] && relname[2])
+ return (relname[0] == 'p' &&
+ relname[1] == 'g' &&
+ relname[2] == '_');
+ else
+ return FALSE;
}
/*
* IsSharedSystemRelationName --
- * True iff name is the name of a shared system catalog relation.
+ * True iff name is the name of a shared system catalog relation.
*/
bool
IsSharedSystemRelationName(char *relname)
{
- int i;
-
- /*
- * Quick out: if it's not a system relation, it can't be a shared
- * system relation.
- */
- if (!IsSystemRelationName(relname))
+ int i;
+
+ /*
+ * Quick out: if it's not a system relation, it can't be a shared
+ * system relation.
+ */
+ if (!IsSystemRelationName(relname))
+ return FALSE;
+
+ i = 0;
+ while (SharedSystemRelationNames[i] != NULL)
+ {
+ if (strcmp(SharedSystemRelationNames[i], relname) == 0)
+ return TRUE;
+ i++;
+ }
return FALSE;
-
- i = 0;
- while ( SharedSystemRelationNames[i] != NULL) {
- if (strcmp(SharedSystemRelationNames[i],relname) == 0)
- return TRUE;
- i++;
- }
- return FALSE;
}
/*
- * newoid - returns a unique identifier across all catalogs.
+ * newoid - returns a unique identifier across all catalogs.
*
- * Object Id allocation is now done by GetNewObjectID in
- * access/transam/varsup.c. oids are now allocated correctly.
+ * Object Id allocation is now done by GetNewObjectID in
+ * access/transam/varsup.c. oids are now allocated correctly.
*
* old comments:
- * This needs to change soon, it fails if there are too many more
- * than one call per second when postgres restarts after it dies.
+ * This needs to change soon, it fails if there are too many more
+ * than one call per second when postgres restarts after it dies.
*
- * The distribution of OID's should be done by the POSTMASTER.
- * Also there needs to be a facility to preallocate OID's. Ie.,
- * for a block of OID's to be declared as invalid ones to allow
- * user programs to use them for temporary object identifiers.
+ * The distribution of OID's should be done by the POSTMASTER.
+ * Also there needs to be a facility to preallocate OID's. Ie.,
+ * for a block of OID's to be declared as invalid ones to allow
+ * user programs to use them for temporary object identifiers.
*/
-Oid newoid()
+Oid
+newoid()
{
- Oid lastoid;
-
- GetNewObjectId(&lastoid);
- if (! OidIsValid(lastoid))
- elog(WARN, "newoid: GetNewObjectId returns invalid oid");
- return lastoid;
+ Oid lastoid;
+
+ GetNewObjectId(&lastoid);
+ if (!OidIsValid(lastoid))
+ elog(WARN, "newoid: GetNewObjectId returns invalid oid");
+ return lastoid;
}
/*
- * fillatt - fills the ATTRIBUTE relation fields from the TYP
+ * fillatt - fills the ATTRIBUTE relation fields from the TYP
*
- * Expects that the atttypid domain is set for each att[].
- * Returns with the attnum, and attlen domains set.
- * attnum, attproc, atttyparg, ... should be set by the user.
+ * Expects that the atttypid domain is set for each att[].
+ * Returns with the attnum, and attlen domains set.
+ * attnum, attproc, atttyparg, ... should be set by the user.
*
- * In the future, attnum may not be set?!? or may be passed as an arg?!?
+ * In the future, attnum may not be set?!? or may be passed as an arg?!?
*
- * Current implementation is very inefficient--should cashe the
- * information if this is at all possible.
+ * Current implementation is very inefficient--should cashe the
+ * information if this is at all possible.
*
- * Check to see if this is really needed, and especially in the case
- * of index tuples.
+ * Check to see if this is really needed, and especially in the case
+ * of index tuples.
*/
void
fillatt(TupleDesc tupleDesc)
{
- AttributeTupleForm *attributeP;
- register TypeTupleForm typp;
- HeapTuple tuple;
- int i;
- int natts = tupleDesc->natts;
- AttributeTupleForm *att = tupleDesc->attrs;
-
- if (natts < 0 || natts > MaxHeapAttributeNumber)
- elog(WARN, "fillatt: %d attributes is too large", natts);
- if (natts == 0) {
- elog(DEBUG, "fillatt: called with natts == 0");
- return;
- }
-
- attributeP = &att[0];
-
- for (i = 0; i < natts;) {
- tuple = SearchSysCacheTuple(TYPOID,
- Int32GetDatum((*attributeP)->atttypid),
- 0,0,0);
- if (!HeapTupleIsValid(tuple)) {
- elog(WARN, "fillatt: unknown atttypid %ld",
- (*attributeP)->atttypid);
- } else {
- (*attributeP)->attnum = (int16) ++i;
- /* Check if the attr is a set before messing with the length
- and byval, since those were already set in
- TupleDescInitEntry. In fact, this seems redundant
- here, but who knows what I'll break if I take it out...
-
- same for char() and varchar() stuff. I share the same
- sentiments. This function is poorly written anyway. -ay 6/95
- */
- if (!(*attributeP)->attisset &&
- (*attributeP)->atttypid!=BPCHAROID &&
- (*attributeP)->atttypid!=VARCHAROID) {
-
- typp = (TypeTupleForm) GETSTRUCT(tuple); /* XXX */
- (*attributeP)->attlen = typp->typlen;
- (*attributeP)->attbyval = typp->typbyval;
- }
+ AttributeTupleForm *attributeP;
+ register TypeTupleForm typp;
+ HeapTuple tuple;
+ int i;
+ int natts = tupleDesc->natts;
+ AttributeTupleForm *att = tupleDesc->attrs;
+
+ if (natts < 0 || natts > MaxHeapAttributeNumber)
+ elog(WARN, "fillatt: %d attributes is too large", natts);
+ if (natts == 0)
+ {
+ elog(DEBUG, "fillatt: called with natts == 0");
+ return;
+ }
+
+ attributeP = &att[0];
+
+ for (i = 0; i < natts;)
+ {
+ tuple = SearchSysCacheTuple(TYPOID,
+ Int32GetDatum((*attributeP)->atttypid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN, "fillatt: unknown atttypid %ld",
+ (*attributeP)->atttypid);
+ }
+ else
+ {
+ (*attributeP)->attnum = (int16)++ i;
+
+ /*
+ * Check if the attr is a set before messing with the length
+ * and byval, since those were already set in
+ * TupleDescInitEntry. In fact, this seems redundant here,
+ * but who knows what I'll break if I take it out...
+ *
+ * same for char() and varchar() stuff. I share the same
+ * sentiments. This function is poorly written anyway. -ay
+ * 6/95
+ */
+ if (!(*attributeP)->attisset &&
+ (*attributeP)->atttypid != BPCHAROID &&
+ (*attributeP)->atttypid != VARCHAROID)
+ {
+
+ typp = (TypeTupleForm) GETSTRUCT(tuple); /* XXX */
+ (*attributeP)->attlen = typp->typlen;
+ (*attributeP)->attbyval = typp->typbyval;
+ }
+ }
+ attributeP += 1;
}
- attributeP += 1;
- }
}
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index cbbbd9df004..c80ddb9727e 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -1,26 +1,26 @@
/*-------------------------------------------------------------------------
*
* heap.c--
- * code to create and destroy POSTGRES heap relations
+ * code to create and destroy POSTGRES heap relations
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.24 1997/09/05 18:13:45 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.25 1997/09/07 04:40:10 momjian Exp $
*
* INTERFACE ROUTINES
- * heap_creatr() - Create an uncataloged heap relation
- * heap_create() - Create a cataloged relation
- * heap_destroy() - Removes named relation from catalogs
+ * heap_creatr() - Create an uncataloged heap relation
+ * heap_create() - Create a cataloged relation
+ * heap_destroy() - Removes named relation from catalogs
*
* NOTES
- * this code taken from access/heap/create.c, which contains
- * the old heap_creater, amcreate, and amdestroy. those routines
- * will soon call these routines using the function manager,
- * just like the poorly named "NewXXX" routines do. The
- * "New" routines are all going to die soon, once and for all!
- * -cim 1/13/91
+ * this code taken from access/heap/create.c, which contains
+ * the old heap_creater, amcreate, and amdestroy. those routines
+ * will soon call these routines using the function manager,
+ * just like the poorly named "NewXXX" routines do. The
+ * "New" routines are all going to die soon, once and for all!
+ * -cim 1/13/91
*
*-------------------------------------------------------------------------
*/
@@ -53,103 +53,104 @@
#include <utils/relcache.h>
#include <nodes/plannodes.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static void AddPgRelationTuple(Relation pg_class_desc,
- Relation new_rel_desc, Oid new_rel_oid, int arch, unsigned natts);
-static void AddToTempRelList(Relation r);
-static void DeletePgAttributeTuples(Relation rdesc);
-static void DeletePgRelationTuple(Relation rdesc);
-static void DeletePgTypeTuple(Relation rdesc);
-static int RelationAlreadyExists(Relation pg_class_desc, char relname[]);
-static void RelationRemoveIndexes(Relation relation);
-static void RelationRemoveInheritance(Relation relation);
-static void RemoveFromTempRelList(Relation r);
-static void addNewRelationType(char *typeName, Oid new_rel_oid);
-static void StoreConstraints (Relation rel);
-static void RemoveConstraints (Relation rel);
+static void
+AddPgRelationTuple(Relation pg_class_desc,
+ Relation new_rel_desc, Oid new_rel_oid, int arch, unsigned natts);
+static void AddToTempRelList(Relation r);
+static void DeletePgAttributeTuples(Relation rdesc);
+static void DeletePgRelationTuple(Relation rdesc);
+static void DeletePgTypeTuple(Relation rdesc);
+static int RelationAlreadyExists(Relation pg_class_desc, char relname[]);
+static void RelationRemoveIndexes(Relation relation);
+static void RelationRemoveInheritance(Relation relation);
+static void RemoveFromTempRelList(Relation r);
+static void addNewRelationType(char *typeName, Oid new_rel_oid);
+static void StoreConstraints(Relation rel);
+static void RemoveConstraints(Relation rel);
/* ----------------------------------------------------------------
- * XXX UGLY HARD CODED BADNESS FOLLOWS XXX
+ * XXX UGLY HARD CODED BADNESS FOLLOWS XXX
*
- * these should all be moved to someplace in the lib/catalog
- * module, if not obliterated first.
+ * these should all be moved to someplace in the lib/catalog
+ * module, if not obliterated first.
* ----------------------------------------------------------------
*/
/*
* Note:
- * Should the executor special case these attributes in the future?
- * Advantage: consume 1/2 the space in the ATTRIBUTE relation.
- * Disadvantage: having rules to compute values in these tuples may
- * be more difficult if not impossible.
+ * Should the executor special case these attributes in the future?
+ * Advantage: consume 1/2 the space in the ATTRIBUTE relation.
+ * Disadvantage: having rules to compute values in these tuples may
+ * be more difficult if not impossible.
*/
-static FormData_pg_attribute a1 = {
- 0xffffffff, {"ctid"}, 27l, 0l, sizeof (ItemPointerData),
- SelfItemPointerAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
+static FormData_pg_attribute a1 = {
+ 0xffffffff, {"ctid"}, 27l, 0l, sizeof(ItemPointerData),
+ SelfItemPointerAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
};
-static FormData_pg_attribute a2 = {
- 0xffffffff, {"oid"}, 26l, 0l, sizeof(Oid),
- ObjectIdAttributeNumber, 0, -1, '\001', '\0', 'i', '\0', '\0'
+static FormData_pg_attribute a2 = {
+ 0xffffffff, {"oid"}, 26l, 0l, sizeof(Oid),
+ ObjectIdAttributeNumber, 0, -1, '\001', '\0', 'i', '\0', '\0'
};
-static FormData_pg_attribute a3 = {
- 0xffffffff, {"xmin"}, 28l, 0l, sizeof (TransactionId),
- MinTransactionIdAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
+static FormData_pg_attribute a3 = {
+ 0xffffffff, {"xmin"}, 28l, 0l, sizeof(TransactionId),
+ MinTransactionIdAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
};
-static FormData_pg_attribute a4 = {
- 0xffffffff, {"cmin"}, 29l, 0l, sizeof (CommandId),
- MinCommandIdAttributeNumber, 0, -1, '\001', '\0', 's', '\0', '\0'
+static FormData_pg_attribute a4 = {
+ 0xffffffff, {"cmin"}, 29l, 0l, sizeof(CommandId),
+ MinCommandIdAttributeNumber, 0, -1, '\001', '\0', 's', '\0', '\0'
};
-static FormData_pg_attribute a5 = {
- 0xffffffff, {"xmax"}, 28l, 0l, sizeof (TransactionId),
- MaxTransactionIdAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
+static FormData_pg_attribute a5 = {
+ 0xffffffff, {"xmax"}, 28l, 0l, sizeof(TransactionId),
+ MaxTransactionIdAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
};
-static FormData_pg_attribute a6 = {
- 0xffffffff, {"cmax"}, 29l, 0l, sizeof (CommandId),
- MaxCommandIdAttributeNumber, 0, -1, '\001', '\0', 's', '\0', '\0'
+static FormData_pg_attribute a6 = {
+ 0xffffffff, {"cmax"}, 29l, 0l, sizeof(CommandId),
+ MaxCommandIdAttributeNumber, 0, -1, '\001', '\0', 's', '\0', '\0'
};
-static FormData_pg_attribute a7 = {
- 0xffffffff, {"chain"}, 27l, 0l, sizeof (ItemPointerData),
- ChainItemPointerAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
+static FormData_pg_attribute a7 = {
+ 0xffffffff, {"chain"}, 27l, 0l, sizeof(ItemPointerData),
+ ChainItemPointerAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
};
-static FormData_pg_attribute a8 = {
- 0xffffffff, {"anchor"}, 27l, 0l, sizeof (ItemPointerData),
- AnchorItemPointerAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
+static FormData_pg_attribute a8 = {
+ 0xffffffff, {"anchor"}, 27l, 0l, sizeof(ItemPointerData),
+ AnchorItemPointerAttributeNumber, 0, -1, '\0', '\0', 'i', '\0', '\0'
};
-static FormData_pg_attribute a9 = {
- 0xffffffff, {"tmin"}, 702l, 0l, sizeof (AbsoluteTime),
- MinAbsoluteTimeAttributeNumber, 0, -1, '\001', '\0', 'i', '\0', '\0'
+static FormData_pg_attribute a9 = {
+ 0xffffffff, {"tmin"}, 702l, 0l, sizeof(AbsoluteTime),
+ MinAbsoluteTimeAttributeNumber, 0, -1, '\001', '\0', 'i', '\0', '\0'
};
-static FormData_pg_attribute a10 = {
- 0xffffffff, {"tmax"}, 702l, 0l, sizeof (AbsoluteTime),
- MaxAbsoluteTimeAttributeNumber, 0, -1, '\001', '\0', 'i', '\0', '\0'
+static FormData_pg_attribute a10 = {
+ 0xffffffff, {"tmax"}, 702l, 0l, sizeof(AbsoluteTime),
+ MaxAbsoluteTimeAttributeNumber, 0, -1, '\001', '\0', 'i', '\0', '\0'
};
-static FormData_pg_attribute a11 = {
- 0xffffffff, {"vtype"}, 18l, 0l, sizeof (char),
- VersionTypeAttributeNumber, 0, -1, '\001', '\0', 'c', '\0', '\0'
+static FormData_pg_attribute a11 = {
+ 0xffffffff, {"vtype"}, 18l, 0l, sizeof(char),
+ VersionTypeAttributeNumber, 0, -1, '\001', '\0', 'c', '\0', '\0'
};
-static AttributeTupleForm HeapAtt[] =
-{ &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11 };
+static AttributeTupleForm HeapAtt[] =
+{&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11};
/* ----------------------------------------------------------------
- * XXX END OF UGLY HARD CODED BADNESS XXX
+ * XXX END OF UGLY HARD CODED BADNESS XXX
* ----------------------------------------------------------------
*/
@@ -157,1227 +158,1261 @@ static AttributeTupleForm HeapAtt[] =
the list of temporary uncatalogued relations that are created.
these relations should be destroyed at the end of transactions
*/
-typedef struct tempRelList {
- Relation *rels; /* array of relation descriptors */
- int num; /* number of temporary relations */
- int size; /* size of space allocated for the rels array */
-} TempRelList;
+typedef struct tempRelList
+{
+ Relation *rels; /* array of relation descriptors */
+ int num; /* number of temporary relations */
+ int size; /* size of space allocated for the rels
+ * array */
+} TempRelList;
-#define TEMP_REL_LIST_SIZE 32
+#define TEMP_REL_LIST_SIZE 32
-static TempRelList *tempRels = NULL;
+static TempRelList *tempRels = NULL;
/* ----------------------------------------------------------------
- * heap_creatr - Create an uncataloged heap relation
+ * heap_creatr - Create an uncataloged heap relation
*
- * Fields relpages, reltuples, reltuples, relkeys, relhistory,
- * relisindexed, and relkind of rdesc->rd_rel are initialized
- * to all zeros, as are rd_last and rd_hook. Rd_refcnt is set to 1.
+ * Fields relpages, reltuples, reltuples, relkeys, relhistory,
+ * relisindexed, and relkind of rdesc->rd_rel are initialized
+ * to all zeros, as are rd_last and rd_hook. Rd_refcnt is set to 1.
*
- * Remove the system relation specific code to elsewhere eventually.
+ * Remove the system relation specific code to elsewhere eventually.
+ *
+ * Eventually, must place information about this temporary relation
+ * into the transaction context block.
*
- * Eventually, must place information about this temporary relation
- * into the transaction context block.
*
- *
* if heap_creatr is called with "" as the name, then heap_creatr will create a
- * temporary name "temp_$RELOID" for the relation
+ * temporary name "temp_$RELOID" for the relation
* ----------------------------------------------------------------
*/
Relation
-heap_creatr(char *name,
- unsigned smgr,
- TupleDesc tupDesc)
+heap_creatr(char *name,
+ unsigned smgr,
+ TupleDesc tupDesc)
{
- register unsigned i;
- Oid relid;
- Relation rdesc;
- int len;
- bool nailme = false;
- char* relname = name;
- char tempname[40];
- int isTemp = 0;
- int natts = tupDesc->natts;
-/* AttributeTupleForm *att = tupDesc->attrs; */
-
- extern GlobalMemory CacheCxt;
- MemoryContext oldcxt;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- AssertArg(natts > 0);
-
- if (IsSystemRelationName(relname) && IsNormalProcessingMode())
+ register unsigned i;
+ Oid relid;
+ Relation rdesc;
+ int len;
+ bool nailme = false;
+ char *relname = name;
+ char tempname[40];
+ int isTemp = 0;
+ int natts = tupDesc->natts;
+
+/* AttributeTupleForm *att = tupDesc->attrs; */
+
+ extern GlobalMemory CacheCxt;
+ MemoryContext oldcxt;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ AssertArg(natts > 0);
+
+ if (IsSystemRelationName(relname) && IsNormalProcessingMode())
{
- elog(WARN,
+ elog(WARN,
"Illegal class name: %s -- pg_ is reserved for system catalogs",
- relname);
+ relname);
+ }
+
+ /* ----------------
+ * switch to the cache context so that we don't lose
+ * allocations at the end of this transaction, I guess.
+ * -cim 6/14/90
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * real ugly stuff to assign the proper relid in the relation
+ * descriptor follows.
+ * ----------------
+ */
+ if (!strcmp(RelationRelationName, relname))
+ {
+ relid = RelOid_pg_class;
+ nailme = true;
}
-
- /* ----------------
- * switch to the cache context so that we don't lose
- * allocations at the end of this transaction, I guess.
- * -cim 6/14/90
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * real ugly stuff to assign the proper relid in the relation
- * descriptor follows.
- * ----------------
- */
- if (! strcmp(RelationRelationName,relname))
+ else if (!strcmp(AttributeRelationName, relname))
{
- relid = RelOid_pg_class;
- nailme = true;
+ relid = RelOid_pg_attribute;
+ nailme = true;
}
- else if (! strcmp(AttributeRelationName,relname))
+ else if (!strcmp(ProcedureRelationName, relname))
{
- relid = RelOid_pg_attribute;
- nailme = true;
+ relid = RelOid_pg_proc;
+ nailme = true;
}
- else if (! strcmp(ProcedureRelationName, relname))
+ else if (!strcmp(TypeRelationName, relname))
{
- relid = RelOid_pg_proc;
- nailme = true;
+ relid = RelOid_pg_type;
+ nailme = true;
}
- else if (! strcmp(TypeRelationName,relname))
+ else
{
- relid = RelOid_pg_type;
- nailme = true;
+ relid = newoid();
+
+ if (name[0] == '\0')
+ {
+ sprintf(tempname, "temp_%d", relid);
+ relname = tempname;
+ isTemp = 1;
+ }
}
- else
- {
- relid = newoid();
-
- if (name[0] == '\0')
- {
- sprintf(tempname, "temp_%d", relid);
- relname = tempname;
- isTemp = 1;
- }
- }
-
- /* ----------------
- * allocate a new relation descriptor.
- *
- * XXX the length computation may be incorrect, handle elsewhere
- * ----------------
- */
- len = sizeof(RelationData);
-
- rdesc = (Relation) palloc(len);
- memset((char *)rdesc, 0,len);
-
- /* ----------
- create a new tuple descriptor from the one passed in
- */
- rdesc->rd_att = CreateTupleDescCopyConstr(tupDesc);
-
- /* ----------------
- * initialize the fields of our new relation descriptor
- * ----------------
- */
-
- /* ----------------
- * nail the reldesc if this is a bootstrap create reln and
- * we may need it in the cache later on in the bootstrap
- * process so we don't ever want it kicked out. e.g. pg_attribute!!!
- * ----------------
- */
- if (nailme)
- rdesc->rd_isnailed = true;
-
- RelationSetReferenceCount(rdesc, 1);
-
- rdesc->rd_rel = (Form_pg_class)palloc(sizeof *rdesc->rd_rel);
-
- memset((char *)rdesc->rd_rel, 0,
- sizeof *rdesc->rd_rel);
- namestrcpy(&(rdesc->rd_rel->relname), relname);
- rdesc->rd_rel->relkind = RELKIND_UNCATALOGED;
- rdesc->rd_rel->relnatts = natts;
- rdesc->rd_rel->relsmgr = smgr;
- if ( tupDesc->constr )
- rdesc->rd_rel->relchecks = tupDesc->constr->num_check;
-
- for (i = 0; i < natts; i++) {
- rdesc->rd_att->attrs[i]->attrelid = relid;
- }
-
- rdesc->rd_id = relid;
-
- if (nailme) {
- /* for system relations, set the reltype field here */
- rdesc->rd_rel->reltype = relid;
- }
-
- /* ----------------
- * remember if this is a temp relation
- * ----------------
- */
-
- rdesc->rd_istemp = isTemp;
-
- /* ----------------
- * have the storage manager create the relation.
- * ----------------
- */
-
- rdesc->rd_tmpunlinked = TRUE; /* change once table is created */
- rdesc->rd_fd = (File)smgrcreate(smgr, rdesc);
- rdesc->rd_tmpunlinked = FALSE;
-
- RelationRegisterRelation(rdesc);
-
- MemoryContextSwitchTo(oldcxt);
-
- /* add all temporary relations to the tempRels list
- so they can be properly disposed of at the end of transaction
- */
- if (isTemp)
- AddToTempRelList(rdesc);
-
- return (rdesc);
+
+ /* ----------------
+ * allocate a new relation descriptor.
+ *
+ * XXX the length computation may be incorrect, handle elsewhere
+ * ----------------
+ */
+ len = sizeof(RelationData);
+
+ rdesc = (Relation) palloc(len);
+ memset((char *) rdesc, 0, len);
+
+ /* ----------
+ create a new tuple descriptor from the one passed in
+ */
+ rdesc->rd_att = CreateTupleDescCopyConstr(tupDesc);
+
+ /* ----------------
+ * initialize the fields of our new relation descriptor
+ * ----------------
+ */
+
+ /* ----------------
+ * nail the reldesc if this is a bootstrap create reln and
+ * we may need it in the cache later on in the bootstrap
+ * process so we don't ever want it kicked out. e.g. pg_attribute!!!
+ * ----------------
+ */
+ if (nailme)
+ rdesc->rd_isnailed = true;
+
+ RelationSetReferenceCount(rdesc, 1);
+
+ rdesc->rd_rel = (Form_pg_class) palloc(sizeof *rdesc->rd_rel);
+
+ memset((char *) rdesc->rd_rel, 0,
+ sizeof *rdesc->rd_rel);
+ namestrcpy(&(rdesc->rd_rel->relname), relname);
+ rdesc->rd_rel->relkind = RELKIND_UNCATALOGED;
+ rdesc->rd_rel->relnatts = natts;
+ rdesc->rd_rel->relsmgr = smgr;
+ if (tupDesc->constr)
+ rdesc->rd_rel->relchecks = tupDesc->constr->num_check;
+
+ for (i = 0; i < natts; i++)
+ {
+ rdesc->rd_att->attrs[i]->attrelid = relid;
+ }
+
+ rdesc->rd_id = relid;
+
+ if (nailme)
+ {
+ /* for system relations, set the reltype field here */
+ rdesc->rd_rel->reltype = relid;
+ }
+
+ /* ----------------
+ * remember if this is a temp relation
+ * ----------------
+ */
+
+ rdesc->rd_istemp = isTemp;
+
+ /* ----------------
+ * have the storage manager create the relation.
+ * ----------------
+ */
+
+ rdesc->rd_tmpunlinked = TRUE; /* change once table is created */
+ rdesc->rd_fd = (File) smgrcreate(smgr, rdesc);
+ rdesc->rd_tmpunlinked = FALSE;
+
+ RelationRegisterRelation(rdesc);
+
+ MemoryContextSwitchTo(oldcxt);
+
+ /*
+ * add all temporary relations to the tempRels list so they can be
+ * properly disposed of at the end of transaction
+ */
+ if (isTemp)
+ AddToTempRelList(rdesc);
+
+ return (rdesc);
}
/* ----------------------------------------------------------------
- * heap_create - Create a cataloged relation
+ * heap_create - Create a cataloged relation
*
- * this is done in 6 steps:
+ * this is done in 6 steps:
*
- * 1) CheckAttributeNames() is used to make certain the tuple
- * descriptor contains a valid set of attribute names
+ * 1) CheckAttributeNames() is used to make certain the tuple
+ * descriptor contains a valid set of attribute names
*
- * 2) pg_class is opened and RelationAlreadyExists()
- * preforms a scan to ensure that no relation with the
- * same name already exists.
+ * 2) pg_class is opened and RelationAlreadyExists()
+ * preforms a scan to ensure that no relation with the
+ * same name already exists.
*
- * 3) heap_creater() is called to create the new relation on
- * disk.
+ * 3) heap_creater() is called to create the new relation on
+ * disk.
*
- * 4) TypeDefine() is called to define a new type corresponding
- * to the new relation.
+ * 4) TypeDefine() is called to define a new type corresponding
+ * to the new relation.
*
- * 5) AddNewAttributeTuples() is called to register the
- * new relation's schema in pg_attribute.
+ * 5) AddNewAttributeTuples() is called to register the
+ * new relation's schema in pg_attribute.
*
- * 6) AddPgRelationTuple() is called to register the
- * relation itself in the catalogs.
- *
- * 7) StoreConstraints is called () - vadim 08/22/97
+ * 6) AddPgRelationTuple() is called to register the
+ * relation itself in the catalogs.
*
- * 8) the relations are closed and the new relation's oid
- * is returned.
+ * 7) StoreConstraints is called () - vadim 08/22/97
+ *
+ * 8) the relations are closed and the new relation's oid
+ * is returned.
*
* old comments:
- * A new relation is inserted into the RELATION relation
- * with the specified attribute(s) (newly inserted into
- * the ATTRIBUTE relation). How does concurrency control
- * work? Is it automatic now? Expects the caller to have
- * attname, atttypid, atttyparg, attproc, and attlen domains filled.
- * Create fills the attnum domains sequentually from zero,
- * fills the attdisbursion domains with zeros, and fills the
- * attrelid fields with the relid.
+ * A new relation is inserted into the RELATION relation
+ * with the specified attribute(s) (newly inserted into
+ * the ATTRIBUTE relation). How does concurrency control
+ * work? Is it automatic now? Expects the caller to have
+ * attname, atttypid, atttyparg, attproc, and attlen domains filled.
+ * Create fills the attnum domains sequentually from zero,
+ * fills the attdisbursion domains with zeros, and fills the
+ * attrelid fields with the relid.
+ *
+ * scan relation catalog for name conflict
+ * scan type catalog for typids (if not arg)
+ * create and insert attribute(s) into attribute catalog
+ * create new relation
+ * insert new relation into attribute catalog
*
- * scan relation catalog for name conflict
- * scan type catalog for typids (if not arg)
- * create and insert attribute(s) into attribute catalog
- * create new relation
- * insert new relation into attribute catalog
+ * Should coordinate with heap_creater(). Either it should
+ * not be called or there should be a way to prevent
+ * the relation from being removed at the end of the
+ * transaction if it is successful ('u'/'r' may be enough).
+ * Also, if the transaction does not commit, then the
+ * relation should be removed.
*
- * Should coordinate with heap_creater(). Either it should
- * not be called or there should be a way to prevent
- * the relation from being removed at the end of the
- * transaction if it is successful ('u'/'r' may be enough).
- * Also, if the transaction does not commit, then the
- * relation should be removed.
+ * XXX amcreate ignores "off" when inserting (for now).
+ * XXX amcreate (like the other utilities) needs to understand indexes.
*
- * XXX amcreate ignores "off" when inserting (for now).
- * XXX amcreate (like the other utilities) needs to understand indexes.
- *
* ----------------------------------------------------------------
*/
/* --------------------------------
- * CheckAttributeNames
+ * CheckAttributeNames
*
- * this is used to make certain the tuple descriptor contains a
- * valid set of attribute names. a problem simply generates
- * elog(WARN) which aborts the current transaction.
+ * this is used to make certain the tuple descriptor contains a
+ * valid set of attribute names. a problem simply generates
+ * elog(WARN) which aborts the current transaction.
* --------------------------------
*/
static void
CheckAttributeNames(TupleDesc tupdesc)
{
- unsigned i;
- unsigned j;
- int natts = tupdesc->natts;
-
- /* ----------------
- * first check for collision with system attribute names
- * ----------------
- *
- * also, warn user if attribute to be created has
- * an unknown typid (usually as a result of a 'retrieve into'
- * - jolly
- */
- for (i = 0; i < natts; i += 1) {
- for (j = 0; j < sizeof HeapAtt / sizeof HeapAtt[0]; j += 1) {
- if (nameeq(&(HeapAtt[j]->attname),
- &(tupdesc->attrs[i]->attname))) {
- elog(WARN,
- "create: system attribute named \"%s\"",
- HeapAtt[j]->attname.data);
- }
+ unsigned i;
+ unsigned j;
+ int natts = tupdesc->natts;
+
+ /* ----------------
+ * first check for collision with system attribute names
+ * ----------------
+ *
+ * also, warn user if attribute to be created has
+ * an unknown typid (usually as a result of a 'retrieve into'
+ * - jolly
+ */
+ for (i = 0; i < natts; i += 1)
+ {
+ for (j = 0; j < sizeof HeapAtt / sizeof HeapAtt[0]; j += 1)
+ {
+ if (nameeq(&(HeapAtt[j]->attname),
+ &(tupdesc->attrs[i]->attname)))
+ {
+ elog(WARN,
+ "create: system attribute named \"%s\"",
+ HeapAtt[j]->attname.data);
+ }
+ }
+ if (tupdesc->attrs[i]->atttypid == UNKNOWNOID)
+ {
+ elog(NOTICE,
+ "create: attribute named \"%s\" has an unknown type",
+ tupdesc->attrs[i]->attname.data);
+ }
}
- if (tupdesc->attrs[i]->atttypid == UNKNOWNOID)
- {
- elog(NOTICE,
- "create: attribute named \"%s\" has an unknown type",
- tupdesc->attrs[i]->attname.data);
- }
- }
-
- /* ----------------
- * next check for repeated attribute names
- * ----------------
- */
- for (i = 1; i < natts; i += 1) {
- for (j = 0; j < i; j += 1) {
- if (nameeq(&(tupdesc->attrs[j]->attname),
- &(tupdesc->attrs[i]->attname))) {
- elog(WARN,
- "create: repeated attribute \"%s\"",
- tupdesc->attrs[j]->attname.data);
- }
+
+ /* ----------------
+ * next check for repeated attribute names
+ * ----------------
+ */
+ for (i = 1; i < natts; i += 1)
+ {
+ for (j = 0; j < i; j += 1)
+ {
+ if (nameeq(&(tupdesc->attrs[j]->attname),
+ &(tupdesc->attrs[i]->attname)))
+ {
+ elog(WARN,
+ "create: repeated attribute \"%s\"",
+ tupdesc->attrs[j]->attname.data);
+ }
+ }
}
- }
}
/* --------------------------------
- * RelationAlreadyExists
+ * RelationAlreadyExists
*
- * this preforms a scan of pg_class to ensure that
- * no relation with the same name already exists. The caller
- * has to open pg_class and pass an open descriptor.
+ * this preforms a scan of pg_class to ensure that
+ * no relation with the same name already exists. The caller
+ * has to open pg_class and pass an open descriptor.
* --------------------------------
*/
static int
RelationAlreadyExists(Relation pg_class_desc, char relname[])
{
- ScanKeyData key;
- HeapScanDesc pg_class_scan;
- HeapTuple tup;
-
- /*
- * If this is not bootstrap (initdb) time, use the catalog index
- * on pg_class.
- */
-
- if (!IsBootstrapProcessingMode()) {
- tup = ClassNameIndexScan(pg_class_desc, relname);
- if (HeapTupleIsValid(tup)) {
- pfree(tup);
- return ((int) true);
- } else
- return ((int) false);
- }
-
- /* ----------------
- * At bootstrap time, we have to do this the hard way. Form the
- * scan key.
- * ----------------
- */
- ScanKeyEntryInitialize(&key,
- 0,
- (AttrNumber)Anum_pg_class_relname,
- (RegProcedure)NameEqualRegProcedure,
- (Datum) relname);
-
- /* ----------------
- * begin the scan
- * ----------------
- */
- pg_class_scan = heap_beginscan(pg_class_desc,
- 0,
- NowTimeQual,
- 1,
- &key);
-
- /* ----------------
- * get a tuple. if the tuple is NULL then it means we
- * didn't find an existing relation.
- * ----------------
- */
- tup = heap_getnext(pg_class_scan, 0, (Buffer *)NULL);
-
- /* ----------------
- * end the scan and return existance of relation.
- * ----------------
- */
- heap_endscan(pg_class_scan);
-
- return
- (PointerIsValid(tup) == true);
+ ScanKeyData key;
+ HeapScanDesc pg_class_scan;
+ HeapTuple tup;
+
+ /*
+ * If this is not bootstrap (initdb) time, use the catalog index on
+ * pg_class.
+ */
+
+ if (!IsBootstrapProcessingMode())
+ {
+ tup = ClassNameIndexScan(pg_class_desc, relname);
+ if (HeapTupleIsValid(tup))
+ {
+ pfree(tup);
+ return ((int) true);
+ }
+ else
+ return ((int) false);
+ }
+
+ /* ----------------
+ * At bootstrap time, we have to do this the hard way. Form the
+ * scan key.
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&key,
+ 0,
+ (AttrNumber) Anum_pg_class_relname,
+ (RegProcedure) NameEqualRegProcedure,
+ (Datum) relname);
+
+ /* ----------------
+ * begin the scan
+ * ----------------
+ */
+ pg_class_scan = heap_beginscan(pg_class_desc,
+ 0,
+ NowTimeQual,
+ 1,
+ &key);
+
+ /* ----------------
+ * get a tuple. if the tuple is NULL then it means we
+ * didn't find an existing relation.
+ * ----------------
+ */
+ tup = heap_getnext(pg_class_scan, 0, (Buffer *) NULL);
+
+ /* ----------------
+ * end the scan and return existance of relation.
+ * ----------------
+ */
+ heap_endscan(pg_class_scan);
+
+ return
+ (PointerIsValid(tup) == true);
}
/* --------------------------------
- * AddNewAttributeTuples
+ * AddNewAttributeTuples
*
- * this registers the new relation's schema by adding
- * tuples to pg_attribute.
+ * this registers the new relation's schema by adding
+ * tuples to pg_attribute.
* --------------------------------
*/
static void
AddNewAttributeTuples(Oid new_rel_oid,
- TupleDesc tupdesc)
+ TupleDesc tupdesc)
{
- AttributeTupleForm *dpp;
- unsigned i;
- HeapTuple tup;
- Relation rdesc;
- bool hasindex;
- Relation idescs[Num_pg_attr_indices];
- int natts = tupdesc->natts;
-
- /* ----------------
- * open pg_attribute
- * ----------------
- */
- rdesc = heap_openr(AttributeRelationName);
-
- /* -----------------
- * Check if we have any indices defined on pg_attribute.
- * -----------------
- */
- Assert(rdesc);
- Assert(rdesc->rd_rel);
- hasindex = RelationGetRelationTupleForm(rdesc)->relhasindex;
- if (hasindex)
- CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
-
- /* ----------------
- * initialize tuple descriptor. Note we use setheapoverride()
- * so that we can see the effects of our TypeDefine() done
- * previously.
- * ----------------
- */
- setheapoverride(true);
- fillatt(tupdesc);
- setheapoverride(false);
-
- /* ----------------
- * first we add the user attributes..
- * ----------------
- */
- dpp = tupdesc->attrs;
- for (i = 0; i < natts; i++) {
- (*dpp)->attrelid = new_rel_oid;
- (*dpp)->attdisbursion = 0;
-
- tup = heap_addheader(Natts_pg_attribute,
- ATTRIBUTE_TUPLE_SIZE,
- (char *) *dpp);
-
- heap_insert(rdesc, tup);
+ AttributeTupleForm *dpp;
+ unsigned i;
+ HeapTuple tup;
+ Relation rdesc;
+ bool hasindex;
+ Relation idescs[Num_pg_attr_indices];
+ int natts = tupdesc->natts;
+
+ /* ----------------
+ * open pg_attribute
+ * ----------------
+ */
+ rdesc = heap_openr(AttributeRelationName);
+
+ /* -----------------
+ * Check if we have any indices defined on pg_attribute.
+ * -----------------
+ */
+ Assert(rdesc);
+ Assert(rdesc->rd_rel);
+ hasindex = RelationGetRelationTupleForm(rdesc)->relhasindex;
if (hasindex)
- CatalogIndexInsert(idescs, Num_pg_attr_indices, rdesc, tup);
-
- pfree(tup);
- dpp++;
- }
-
- /* ----------------
- * next we add the system attributes..
- * ----------------
- */
- dpp = HeapAtt;
- for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++) {
- (*dpp)->attrelid = new_rel_oid;
- /* (*dpp)->attdisbursion = 0; unneeded */
-
- tup = heap_addheader(Natts_pg_attribute,
- ATTRIBUTE_TUPLE_SIZE,
- (char *)*dpp);
-
- heap_insert(rdesc, tup);
-
+ CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
+
+ /* ----------------
+ * initialize tuple descriptor. Note we use setheapoverride()
+ * so that we can see the effects of our TypeDefine() done
+ * previously.
+ * ----------------
+ */
+ setheapoverride(true);
+ fillatt(tupdesc);
+ setheapoverride(false);
+
+ /* ----------------
+ * first we add the user attributes..
+ * ----------------
+ */
+ dpp = tupdesc->attrs;
+ for (i = 0; i < natts; i++)
+ {
+ (*dpp)->attrelid = new_rel_oid;
+ (*dpp)->attdisbursion = 0;
+
+ tup = heap_addheader(Natts_pg_attribute,
+ ATTRIBUTE_TUPLE_SIZE,
+ (char *) *dpp);
+
+ heap_insert(rdesc, tup);
+ if (hasindex)
+ CatalogIndexInsert(idescs, Num_pg_attr_indices, rdesc, tup);
+
+ pfree(tup);
+ dpp++;
+ }
+
+ /* ----------------
+ * next we add the system attributes..
+ * ----------------
+ */
+ dpp = HeapAtt;
+ for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)
+ {
+ (*dpp)->attrelid = new_rel_oid;
+ /* (*dpp)->attdisbursion = 0; unneeded */
+
+ tup = heap_addheader(Natts_pg_attribute,
+ ATTRIBUTE_TUPLE_SIZE,
+ (char *) *dpp);
+
+ heap_insert(rdesc, tup);
+
+ if (hasindex)
+ CatalogIndexInsert(idescs, Num_pg_attr_indices, rdesc, tup);
+
+ pfree(tup);
+ dpp++;
+ }
+
+ heap_close(rdesc);
+
+ /*
+ * close pg_attribute indices
+ */
if (hasindex)
- CatalogIndexInsert(idescs, Num_pg_attr_indices, rdesc, tup);
-
- pfree(tup);
- dpp++;
- }
-
- heap_close(rdesc);
-
- /*
- * close pg_attribute indices
- */
- if (hasindex)
- CatalogCloseIndices(Num_pg_attr_indices, idescs);
+ CatalogCloseIndices(Num_pg_attr_indices, idescs);
}
/* --------------------------------
- * AddPgRelationTuple
+ * AddPgRelationTuple
*
- * this registers the new relation in the catalogs by
- * adding a tuple to pg_class.
+ * this registers the new relation in the catalogs by
+ * adding a tuple to pg_class.
* --------------------------------
*/
static void
AddPgRelationTuple(Relation pg_class_desc,
- Relation new_rel_desc,
- Oid new_rel_oid,
- int arch,
- unsigned natts)
+ Relation new_rel_desc,
+ Oid new_rel_oid,
+ int arch,
+ unsigned natts)
{
- Form_pg_class new_rel_reltup;
- HeapTuple tup;
- Relation idescs[Num_pg_class_indices];
- bool isBootstrap;
- extern bool ItsSequenceCreation; /* It's hack, I know...
- * - vadim 03/28/97 */
- /* ----------------
- * first we munge some of the information in our
- * uncataloged relation's relation descriptor.
- * ----------------
- */
- new_rel_reltup = new_rel_desc->rd_rel;
-
- /* CHECK should get new_rel_oid first via an insert then use XXX */
- /* new_rel_reltup->reltuples = 1; */ /* XXX */
-
- new_rel_reltup->relowner = GetUserId();
- if ( ItsSequenceCreation )
- new_rel_reltup->relkind = RELKIND_SEQUENCE;
- else
- new_rel_reltup->relkind = RELKIND_RELATION;
- new_rel_reltup->relarch = arch;
- new_rel_reltup->relnatts = natts;
-
- /* ----------------
- * now form a tuple to add to pg_class
- * XXX Natts_pg_class_fixed is a hack - see pg_class.h
- * ----------------
- */
- tup = heap_addheader(Natts_pg_class_fixed,
- CLASS_TUPLE_SIZE,
- (char *) new_rel_reltup);
- tup->t_oid = new_rel_oid;
-
- /* ----------------
- * finally insert the new tuple and free it.
- *
- * Note: I have no idea why we do a
- * SetProcessingMode(BootstrapProcessing);
- * here -cim 6/14/90
- * ----------------
- */
- isBootstrap = IsBootstrapProcessingMode() ? true : false;
-
- SetProcessingMode(BootstrapProcessing);
-
- heap_insert(pg_class_desc, tup);
-
- if (! isBootstrap) {
- /*
- * First, open the catalog indices and insert index tuples for
- * the new relation.
- */
-
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class_desc, tup);
- CatalogCloseIndices(Num_pg_class_indices, idescs);
-
- /* now restore processing mode */
- SetProcessingMode(NormalProcessing);
- }
-
- pfree(tup);
+ Form_pg_class new_rel_reltup;
+ HeapTuple tup;
+ Relation idescs[Num_pg_class_indices];
+ bool isBootstrap;
+ extern bool ItsSequenceCreation; /* It's hack, I know... -
+ * vadim 03/28/97 */
+
+ /* ----------------
+ * first we munge some of the information in our
+ * uncataloged relation's relation descriptor.
+ * ----------------
+ */
+ new_rel_reltup = new_rel_desc->rd_rel;
+
+ /* CHECK should get new_rel_oid first via an insert then use XXX */
+ /* new_rel_reltup->reltuples = 1; *//* XXX */
+
+ new_rel_reltup->relowner = GetUserId();
+ if (ItsSequenceCreation)
+ new_rel_reltup->relkind = RELKIND_SEQUENCE;
+ else
+ new_rel_reltup->relkind = RELKIND_RELATION;
+ new_rel_reltup->relarch = arch;
+ new_rel_reltup->relnatts = natts;
+
+ /* ----------------
+ * now form a tuple to add to pg_class
+ * XXX Natts_pg_class_fixed is a hack - see pg_class.h
+ * ----------------
+ */
+ tup = heap_addheader(Natts_pg_class_fixed,
+ CLASS_TUPLE_SIZE,
+ (char *) new_rel_reltup);
+ tup->t_oid = new_rel_oid;
+
+ /* ----------------
+ * finally insert the new tuple and free it.
+ *
+ * Note: I have no idea why we do a
+ * SetProcessingMode(BootstrapProcessing);
+ * here -cim 6/14/90
+ * ----------------
+ */
+ isBootstrap = IsBootstrapProcessingMode() ? true : false;
+
+ SetProcessingMode(BootstrapProcessing);
+
+ heap_insert(pg_class_desc, tup);
+
+ if (!isBootstrap)
+ {
+
+ /*
+ * First, open the catalog indices and insert index tuples for the
+ * new relation.
+ */
+
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class_desc, tup);
+ CatalogCloseIndices(Num_pg_class_indices, idescs);
+
+ /* now restore processing mode */
+ SetProcessingMode(NormalProcessing);
+ }
+
+ pfree(tup);
}
/* --------------------------------
- * addNewRelationType -
+ * addNewRelationType -
*
- * define a complex type corresponding to the new relation
+ * define a complex type corresponding to the new relation
* --------------------------------
*/
static void
addNewRelationType(char *typeName, Oid new_rel_oid)
{
- Oid new_type_oid;
-
- /* The sizes are set to oid size because it makes implementing sets MUCH
- * easier, and no one (we hope) uses these fields to figure out
- * how much space to allocate for the type.
- * An oid is the type used for a set definition. When a user
- * requests a set, what they actually get is the oid of a tuple in
- * the pg_proc catalog, so the size of the "set" is the size
- * of an oid.
- * Similarly, byval being true makes sets much easier, and
- * it isn't used by anything else.
- * Note the assumption that OIDs are the same size as int4s.
- */
- new_type_oid = TypeCreate(typeName, /* type name */
- new_rel_oid, /* relation oid */
- tlen(type("oid")), /* internal size */
- tlen(type("oid")), /* external size */
- 'c', /* type-type (catalog) */
- ',', /* default array delimiter */
- "int4in", /* input procedure */
- "int4out", /* output procedure */
- "int4in", /* send procedure */
- "int4out", /* receive procedure */
- NULL, /* array element type - irrelevent */
- "-", /* default type value */
- (bool) 1, /* passed by value */
- 'i'); /* default alignment */
+ Oid new_type_oid;
+
+ /*
+ * The sizes are set to oid size because it makes implementing sets
+ * MUCH easier, and no one (we hope) uses these fields to figure out
+ * how much space to allocate for the type. An oid is the type used
+ * for a set definition. When a user requests a set, what they
+ * actually get is the oid of a tuple in the pg_proc catalog, so the
+ * size of the "set" is the size of an oid. Similarly, byval being
+ * true makes sets much easier, and it isn't used by anything else.
+ * Note the assumption that OIDs are the same size as int4s.
+ */
+ new_type_oid = TypeCreate(typeName, /* type name */
+ new_rel_oid, /* relation oid */
+ tlen(type("oid")), /* internal size */
+ tlen(type("oid")), /* external size */
+ 'c', /* type-type (catalog) */
+ ',', /* default array delimiter */
+ "int4in", /* input procedure */
+ "int4out", /* output procedure */
+ "int4in", /* send procedure */
+ "int4out", /* receive procedure */
+ NULL, /* array element type - irrelevent */
+ "-", /* default type value */
+ (bool) 1, /* passed by value */
+ 'i'); /* default alignment */
}
/* --------------------------------
- * heap_create
+ * heap_create
*
- * creates a new cataloged relation. see comments above.
+ * creates a new cataloged relation. see comments above.
* --------------------------------
*/
Oid
heap_create(char relname[],
- char *typename, /* not used currently */
- int arch,
- unsigned smgr,
- TupleDesc tupdesc)
+ char *typename, /* not used currently */
+ int arch,
+ unsigned smgr,
+ TupleDesc tupdesc)
{
- Relation pg_class_desc;
- Relation new_rel_desc;
- Oid new_rel_oid;
-/* NameData typeNameData; */
- int natts = tupdesc->natts;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- AssertState(IsNormalProcessingMode() || IsBootstrapProcessingMode());
- if (natts == 0 || natts > MaxHeapAttributeNumber)
- elog(WARN, "amcreate: from 1 to %d attributes must be specified",
- MaxHeapAttributeNumber);
-
- CheckAttributeNames(tupdesc);
-
- /* ----------------
- * open pg_class and see that the relation doesn't
- * already exist.
- * ----------------
- */
- pg_class_desc = heap_openr(RelationRelationName);
-
- if (RelationAlreadyExists(pg_class_desc, relname)) {
+ Relation pg_class_desc;
+ Relation new_rel_desc;
+ Oid new_rel_oid;
+
+/* NameData typeNameData; */
+ int natts = tupdesc->natts;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ AssertState(IsNormalProcessingMode() || IsBootstrapProcessingMode());
+ if (natts == 0 || natts > MaxHeapAttributeNumber)
+ elog(WARN, "amcreate: from 1 to %d attributes must be specified",
+ MaxHeapAttributeNumber);
+
+ CheckAttributeNames(tupdesc);
+
+ /* ----------------
+ * open pg_class and see that the relation doesn't
+ * already exist.
+ * ----------------
+ */
+ pg_class_desc = heap_openr(RelationRelationName);
+
+ if (RelationAlreadyExists(pg_class_desc, relname))
+ {
+ heap_close(pg_class_desc);
+ elog(WARN, "amcreate: %s relation already exists", relname);
+ }
+
+ /* ----------------
+ * ok, relation does not already exist so now we
+ * create an uncataloged relation and pull its relation oid
+ * from the newly formed relation descriptor.
+ *
+ * Note: The call to heap_creatr() does all the "real" work
+ * of creating the disk file for the relation.
+ * ----------------
+ */
+ new_rel_desc = heap_creatr(relname, smgr, tupdesc);
+ new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
+
+ /* ----------------
+ * since defining a relation also defines a complex type,
+ * we add a new system type corresponding to the new relation.
+ * ----------------
+ */
+/* namestrcpy(&typeNameData, relname);*/
+/* addNewRelationType(&typeNameData, new_rel_oid);*/
+ addNewRelationType(relname, new_rel_oid);
+
+ /* ----------------
+ * now add tuples to pg_attribute for the attributes in
+ * our new relation.
+ * ----------------
+ */
+ AddNewAttributeTuples(new_rel_oid, tupdesc);
+
+ /* ----------------
+ * now update the information in pg_class.
+ * ----------------
+ */
+ AddPgRelationTuple(pg_class_desc,
+ new_rel_desc,
+ new_rel_oid,
+ arch,
+ natts);
+
+ StoreConstraints(new_rel_desc);
+
+ /* ----------------
+ * ok, the relation has been cataloged, so close our relations
+ * and return the oid of the newly created relation.
+ *
+ * SOMEDAY: fill the STATISTIC relation properly.
+ * ----------------
+ */
+ heap_close(new_rel_desc);
heap_close(pg_class_desc);
- elog(WARN, "amcreate: %s relation already exists", relname);
- }
-
- /* ----------------
- * ok, relation does not already exist so now we
- * create an uncataloged relation and pull its relation oid
- * from the newly formed relation descriptor.
- *
- * Note: The call to heap_creatr() does all the "real" work
- * of creating the disk file for the relation.
- * ----------------
- */
- new_rel_desc = heap_creatr(relname, smgr, tupdesc);
- new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
-
- /* ----------------
- * since defining a relation also defines a complex type,
- * we add a new system type corresponding to the new relation.
- * ----------------
- */
-/* namestrcpy(&typeNameData, relname);*/
-/* addNewRelationType(&typeNameData, new_rel_oid);*/
- addNewRelationType(relname, new_rel_oid);
-
- /* ----------------
- * now add tuples to pg_attribute for the attributes in
- * our new relation.
- * ----------------
- */
- AddNewAttributeTuples(new_rel_oid, tupdesc);
-
- /* ----------------
- * now update the information in pg_class.
- * ----------------
- */
- AddPgRelationTuple(pg_class_desc,
- new_rel_desc,
- new_rel_oid,
- arch,
- natts);
-
- StoreConstraints (new_rel_desc);
-
- /* ----------------
- * ok, the relation has been cataloged, so close our relations
- * and return the oid of the newly created relation.
- *
- * SOMEDAY: fill the STATISTIC relation properly.
- * ----------------
- */
- heap_close(new_rel_desc);
- heap_close(pg_class_desc);
-
- return new_rel_oid;
+
+ return new_rel_oid;
}
/* ----------------------------------------------------------------
- * heap_destroy - removes all record of named relation from catalogs
+ * heap_destroy - removes all record of named relation from catalogs
*
- * 1) open relation, check for existence, etc.
- * 2) remove inheritance information
- * 3) remove indexes
- * 4) remove pg_class tuple
- * 5) remove pg_attribute tuples
- * 6) remove pg_type tuples
- * 7) RemoveConstraints ()
- * 8) unlink relation
+ * 1) open relation, check for existence, etc.
+ * 2) remove inheritance information
+ * 3) remove indexes
+ * 4) remove pg_class tuple
+ * 5) remove pg_attribute tuples
+ * 6) remove pg_type tuples
+ * 7) RemoveConstraints ()
+ * 8) unlink relation
*
* old comments
- * Except for vital relations, removes relation from
- * relation catalog, and related attributes from
- * attribute catalog (needed?). (Anything else?)
+ * Except for vital relations, removes relation from
+ * relation catalog, and related attributes from
+ * attribute catalog (needed?). (Anything else?)
*
- * get proper relation from relation catalog (if not arg)
- * check if relation is vital (strcmp()/reltype?)
- * scan attribute catalog deleting attributes of reldesc
- * (necessary?)
- * delete relation from relation catalog
- * (How are the tuples of the relation discarded?)
+ * get proper relation from relation catalog (if not arg)
+ * check if relation is vital (strcmp()/reltype?)
+ * scan attribute catalog deleting attributes of reldesc
+ * (necessary?)
+ * delete relation from relation catalog
+ * (How are the tuples of the relation discarded?)
*
- * XXX Must fix to work with indexes.
- * There may be a better order for doing things.
- * Problems with destroying a deleted database--cannot create
- * a struct reldesc without having an open file descriptor.
+ * XXX Must fix to work with indexes.
+ * There may be a better order for doing things.
+ * Problems with destroying a deleted database--cannot create
+ * a struct reldesc without having an open file descriptor.
* ----------------------------------------------------------------
*/
/* --------------------------------
- * RelationRemoveInheritance
+ * RelationRemoveInheritance
*
- * Note: for now, we cause an exception if relation is a
- * superclass. Someday, we may want to allow this and merge
- * the type info into subclass procedures.... this seems like
- * lots of work.
+ * Note: for now, we cause an exception if relation is a
+ * superclass. Someday, we may want to allow this and merge
+ * the type info into subclass procedures.... this seems like
+ * lots of work.
* --------------------------------
*/
static void
RelationRemoveInheritance(Relation relation)
{
- Relation catalogRelation;
- HeapTuple tuple;
- HeapScanDesc scan;
- ScanKeyData entry;
-
- /* ----------------
- * open pg_inherits
- * ----------------
- */
- catalogRelation = heap_openr(InheritsRelationName);
-
- /* ----------------
- * form a scan key for the subclasses of this class
- * and begin scanning
- * ----------------
- */
- ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_inherits_inhparent,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(RelationGetRelationId(relation)));
-
- scan = heap_beginscan(catalogRelation,
- false,
- NowTimeQual,
- 1,
- &entry);
-
- /* ----------------
- * if any subclasses exist, then we disallow the deletion.
- * ----------------
- */
- tuple = heap_getnext(scan, 0, (Buffer *)NULL);
- if (HeapTupleIsValid(tuple)) {
+ Relation catalogRelation;
+ HeapTuple tuple;
+ HeapScanDesc scan;
+ ScanKeyData entry;
+
+ /* ----------------
+ * open pg_inherits
+ * ----------------
+ */
+ catalogRelation = heap_openr(InheritsRelationName);
+
+ /* ----------------
+ * form a scan key for the subclasses of this class
+ * and begin scanning
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_inherits_inhparent,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(RelationGetRelationId(relation)));
+
+ scan = heap_beginscan(catalogRelation,
+ false,
+ NowTimeQual,
+ 1,
+ &entry);
+
+ /* ----------------
+ * if any subclasses exist, then we disallow the deletion.
+ * ----------------
+ */
+ tuple = heap_getnext(scan, 0, (Buffer *) NULL);
+ if (HeapTupleIsValid(tuple))
+ {
+ heap_endscan(scan);
+ heap_close(catalogRelation);
+
+ elog(WARN, "relation <%d> inherits \"%s\"",
+ ((InheritsTupleForm) GETSTRUCT(tuple))->inhrel,
+ RelationGetRelationName(relation));
+ }
+
+ /* ----------------
+ * If we get here, it means the relation has no subclasses
+ * so we can trash it. First we remove dead INHERITS tuples.
+ * ----------------
+ */
+ entry.sk_attno = Anum_pg_inherits_inhrel;
+
+ scan = heap_beginscan(catalogRelation,
+ false,
+ NowTimeQual,
+ 1,
+ &entry);
+
+ for (;;)
+ {
+ tuple = heap_getnext(scan, 0, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ break;
+ }
+ heap_delete(catalogRelation, &tuple->t_ctid);
+ }
+
heap_endscan(scan);
heap_close(catalogRelation);
-
- elog(WARN, "relation <%d> inherits \"%s\"",
- ((InheritsTupleForm) GETSTRUCT(tuple))->inhrel,
- RelationGetRelationName(relation));
- }
-
- /* ----------------
- * If we get here, it means the relation has no subclasses
- * so we can trash it. First we remove dead INHERITS tuples.
- * ----------------
- */
- entry.sk_attno = Anum_pg_inherits_inhrel;
-
- scan = heap_beginscan(catalogRelation,
- false,
- NowTimeQual,
- 1,
- &entry);
-
- for (;;) {
- tuple = heap_getnext(scan, 0, (Buffer *)NULL);
- if (!HeapTupleIsValid(tuple)) {
- break;
- }
- heap_delete(catalogRelation, &tuple->t_ctid);
- }
-
- heap_endscan(scan);
- heap_close(catalogRelation);
-
- /* ----------------
- * now remove dead IPL tuples
- * ----------------
- */
- catalogRelation =
- heap_openr(InheritancePrecidenceListRelationName);
-
- entry.sk_attno = Anum_pg_ipl_iplrel;
-
- scan = heap_beginscan(catalogRelation,
- false,
- NowTimeQual,
- 1,
- &entry);
-
- for (;;) {
- tuple = heap_getnext(scan, 0, (Buffer *)NULL);
- if (!HeapTupleIsValid(tuple)) {
- break;
+
+ /* ----------------
+ * now remove dead IPL tuples
+ * ----------------
+ */
+ catalogRelation =
+ heap_openr(InheritancePrecidenceListRelationName);
+
+ entry.sk_attno = Anum_pg_ipl_iplrel;
+
+ scan = heap_beginscan(catalogRelation,
+ false,
+ NowTimeQual,
+ 1,
+ &entry);
+
+ for (;;)
+ {
+ tuple = heap_getnext(scan, 0, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ break;
+ }
+ heap_delete(catalogRelation, &tuple->t_ctid);
}
- heap_delete(catalogRelation, &tuple->t_ctid);
- }
-
- heap_endscan(scan);
- heap_close(catalogRelation);
+
+ heap_endscan(scan);
+ heap_close(catalogRelation);
}
/* --------------------------------
- * RelationRemoveIndexes
- *
+ * RelationRemoveIndexes
+ *
* --------------------------------
*/
static void
RelationRemoveIndexes(Relation relation)
{
- Relation indexRelation;
- HeapTuple tuple;
- HeapScanDesc scan;
- ScanKeyData entry;
-
- indexRelation = heap_openr(IndexRelationName);
-
- ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_index_indrelid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(RelationGetRelationId(relation)));
-
- scan = heap_beginscan(indexRelation,
- false,
- NowTimeQual,
- 1,
- &entry);
-
- for (;;) {
- tuple = heap_getnext(scan, 0, (Buffer *)NULL);
- if (!HeapTupleIsValid(tuple)) {
- break;
+ Relation indexRelation;
+ HeapTuple tuple;
+ HeapScanDesc scan;
+ ScanKeyData entry;
+
+ indexRelation = heap_openr(IndexRelationName);
+
+ ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_index_indrelid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(RelationGetRelationId(relation)));
+
+ scan = heap_beginscan(indexRelation,
+ false,
+ NowTimeQual,
+ 1,
+ &entry);
+
+ for (;;)
+ {
+ tuple = heap_getnext(scan, 0, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ break;
+ }
+
+ index_destroy(((IndexTupleForm) GETSTRUCT(tuple))->indexrelid);
}
-
- index_destroy(((IndexTupleForm)GETSTRUCT(tuple))->indexrelid);
- }
-
- heap_endscan(scan);
- heap_close(indexRelation);
+
+ heap_endscan(scan);
+ heap_close(indexRelation);
}
/* --------------------------------
- * DeletePgRelationTuple
+ * DeletePgRelationTuple
*
* --------------------------------
*/
static void
DeletePgRelationTuple(Relation rdesc)
{
- Relation pg_class_desc;
- HeapScanDesc pg_class_scan;
- ScanKeyData key;
- HeapTuple tup;
-
- /* ----------------
- * open pg_class
- * ----------------
- */
- pg_class_desc = heap_openr(RelationRelationName);
-
- /* ----------------
- * create a scan key to locate the relation oid of the
- * relation to delete
- * ----------------
- */
- ScanKeyEntryInitialize(&key, 0, ObjectIdAttributeNumber,
- F_INT4EQ, rdesc->rd_att->attrs[0]->attrelid);
-
- pg_class_scan = heap_beginscan(pg_class_desc,
- 0,
- NowTimeQual,
- 1,
- &key);
-
- /* ----------------
- * use heap_getnext() to fetch the pg_class tuple. If this
- * tuple is not valid then something's wrong.
- * ----------------
- */
- tup = heap_getnext(pg_class_scan, 0, (Buffer *) NULL);
-
- if (! PointerIsValid(tup)) {
+ Relation pg_class_desc;
+ HeapScanDesc pg_class_scan;
+ ScanKeyData key;
+ HeapTuple tup;
+
+ /* ----------------
+ * open pg_class
+ * ----------------
+ */
+ pg_class_desc = heap_openr(RelationRelationName);
+
+ /* ----------------
+ * create a scan key to locate the relation oid of the
+ * relation to delete
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&key, 0, ObjectIdAttributeNumber,
+ F_INT4EQ, rdesc->rd_att->attrs[0]->attrelid);
+
+ pg_class_scan = heap_beginscan(pg_class_desc,
+ 0,
+ NowTimeQual,
+ 1,
+ &key);
+
+ /* ----------------
+ * use heap_getnext() to fetch the pg_class tuple. If this
+ * tuple is not valid then something's wrong.
+ * ----------------
+ */
+ tup = heap_getnext(pg_class_scan, 0, (Buffer *) NULL);
+
+ if (!PointerIsValid(tup))
+ {
+ heap_endscan(pg_class_scan);
+ heap_close(pg_class_desc);
+ elog(WARN, "DeletePgRelationTuple: %s relation nonexistent",
+ &rdesc->rd_rel->relname);
+ }
+
+ /* ----------------
+ * delete the relation tuple from pg_class, and finish up.
+ * ----------------
+ */
heap_endscan(pg_class_scan);
+ heap_delete(pg_class_desc, &tup->t_ctid);
+
heap_close(pg_class_desc);
- elog(WARN, "DeletePgRelationTuple: %s relation nonexistent",
- &rdesc->rd_rel->relname);
- }
-
- /* ----------------
- * delete the relation tuple from pg_class, and finish up.
- * ----------------
- */
- heap_endscan(pg_class_scan);
- heap_delete(pg_class_desc, &tup->t_ctid);
-
- heap_close(pg_class_desc);
}
/* --------------------------------
- * DeletePgAttributeTuples
+ * DeletePgAttributeTuples
*
* --------------------------------
*/
static void
DeletePgAttributeTuples(Relation rdesc)
{
- Relation pg_attribute_desc;
- HeapScanDesc pg_attribute_scan;
- ScanKeyData key;
- HeapTuple tup;
-
- /* ----------------
- * open pg_attribute
- * ----------------
- */
- pg_attribute_desc = heap_openr(AttributeRelationName);
-
- /* ----------------
- * create a scan key to locate the attribute tuples to delete
- * and begin the scan.
- * ----------------
- */
- ScanKeyEntryInitialize(&key, 0, Anum_pg_attribute_attrelid,
- F_INT4EQ, rdesc->rd_att->attrs[0]->attrelid);
-
- /* -----------------
- * Get a write lock _before_ getting the read lock in the scan
- * ----------------
- */
- RelationSetLockForWrite(pg_attribute_desc);
-
- pg_attribute_scan = heap_beginscan(pg_attribute_desc,
- 0,
- NowTimeQual,
- 1,
- &key);
-
- /* ----------------
- * use heap_getnext() / amdelete() until all attribute tuples
- * have been deleted.
- * ----------------
- */
- while (tup = heap_getnext(pg_attribute_scan, 0, (Buffer *)NULL),
- PointerIsValid(tup)) {
-
- heap_delete(pg_attribute_desc, &tup->t_ctid);
- }
-
- /* ----------------
- * finish up.
- * ----------------
- */
- heap_endscan(pg_attribute_scan);
-
- /* ----------------
- * Release the write lock
- * ----------------
- */
- RelationUnsetLockForWrite(pg_attribute_desc);
- heap_close(pg_attribute_desc);
+ Relation pg_attribute_desc;
+ HeapScanDesc pg_attribute_scan;
+ ScanKeyData key;
+ HeapTuple tup;
+
+ /* ----------------
+ * open pg_attribute
+ * ----------------
+ */
+ pg_attribute_desc = heap_openr(AttributeRelationName);
+
+ /* ----------------
+ * create a scan key to locate the attribute tuples to delete
+ * and begin the scan.
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_attribute_attrelid,
+ F_INT4EQ, rdesc->rd_att->attrs[0]->attrelid);
+
+ /* -----------------
+ * Get a write lock _before_ getting the read lock in the scan
+ * ----------------
+ */
+ RelationSetLockForWrite(pg_attribute_desc);
+
+ pg_attribute_scan = heap_beginscan(pg_attribute_desc,
+ 0,
+ NowTimeQual,
+ 1,
+ &key);
+
+ /* ----------------
+ * use heap_getnext() / amdelete() until all attribute tuples
+ * have been deleted.
+ * ----------------
+ */
+ while (tup = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL),
+ PointerIsValid(tup))
+ {
+
+ heap_delete(pg_attribute_desc, &tup->t_ctid);
+ }
+
+ /* ----------------
+ * finish up.
+ * ----------------
+ */
+ heap_endscan(pg_attribute_scan);
+
+ /* ----------------
+ * Release the write lock
+ * ----------------
+ */
+ RelationUnsetLockForWrite(pg_attribute_desc);
+ heap_close(pg_attribute_desc);
}
/* --------------------------------
- * DeletePgTypeTuple
+ * DeletePgTypeTuple
*
- * If the user attempts to destroy a relation and there
- * exists attributes in other relations of type
- * "relation we are deleting", then we have to do something
- * special. presently we disallow the destroy.
+ * If the user attempts to destroy a relation and there
+ * exists attributes in other relations of type
+ * "relation we are deleting", then we have to do something
+ * special. presently we disallow the destroy.
* --------------------------------
*/
static void
DeletePgTypeTuple(Relation rdesc)
{
- Relation pg_type_desc;
- HeapScanDesc pg_type_scan;
- Relation pg_attribute_desc;
- HeapScanDesc pg_attribute_scan;
- ScanKeyData key;
- ScanKeyData attkey;
- HeapTuple tup;
- HeapTuple atttup;
- Oid typoid;
-
- /* ----------------
- * open pg_type
- * ----------------
- */
- pg_type_desc = heap_openr(TypeRelationName);
-
- /* ----------------
- * create a scan key to locate the type tuple corresponding
- * to this relation.
- * ----------------
- */
- ScanKeyEntryInitialize(&key, 0, Anum_pg_type_typrelid, F_INT4EQ,
- rdesc->rd_att->attrs[0]->attrelid);
-
- pg_type_scan = heap_beginscan(pg_type_desc,
- 0,
- NowTimeQual,
- 1,
- &key);
-
- /* ----------------
- * use heap_getnext() to fetch the pg_type tuple. If this
- * tuple is not valid then something's wrong.
- * ----------------
- */
- tup = heap_getnext(pg_type_scan, 0, (Buffer *)NULL);
-
- if (! PointerIsValid(tup)) {
- heap_endscan(pg_type_scan);
- heap_close(pg_type_desc);
- elog(WARN, "DeletePgTypeTuple: %s type nonexistent",
- &rdesc->rd_rel->relname);
- }
-
- /* ----------------
- * now scan pg_attribute. if any other relations have
- * attributes of the type of the relation we are deleteing
- * then we have to disallow the deletion. should talk to
- * stonebraker about this. -cim 6/19/90
- * ----------------
- */
- typoid = tup->t_oid;
-
- pg_attribute_desc = heap_openr(AttributeRelationName);
-
- ScanKeyEntryInitialize(&attkey,
- 0, Anum_pg_attribute_atttypid, F_INT4EQ,
- typoid);
-
- pg_attribute_scan = heap_beginscan(pg_attribute_desc,
- 0,
- NowTimeQual,
- 1,
- &attkey);
-
- /* ----------------
- * try and get a pg_attribute tuple. if we succeed it means
- * we cant delete the relation because something depends on
- * the schema.
- * ----------------
- */
- atttup = heap_getnext(pg_attribute_scan, 0, (Buffer *)NULL);
-
- if (PointerIsValid(atttup)) {
- Oid relid = ((AttributeTupleForm) GETSTRUCT(atttup))->attrelid;
-
- heap_endscan(pg_type_scan);
- heap_close(pg_type_desc);
+ Relation pg_type_desc;
+ HeapScanDesc pg_type_scan;
+ Relation pg_attribute_desc;
+ HeapScanDesc pg_attribute_scan;
+ ScanKeyData key;
+ ScanKeyData attkey;
+ HeapTuple tup;
+ HeapTuple atttup;
+ Oid typoid;
+
+ /* ----------------
+ * open pg_type
+ * ----------------
+ */
+ pg_type_desc = heap_openr(TypeRelationName);
+
+ /* ----------------
+ * create a scan key to locate the type tuple corresponding
+ * to this relation.
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_type_typrelid, F_INT4EQ,
+ rdesc->rd_att->attrs[0]->attrelid);
+
+ pg_type_scan = heap_beginscan(pg_type_desc,
+ 0,
+ NowTimeQual,
+ 1,
+ &key);
+
+ /* ----------------
+ * use heap_getnext() to fetch the pg_type tuple. If this
+ * tuple is not valid then something's wrong.
+ * ----------------
+ */
+ tup = heap_getnext(pg_type_scan, 0, (Buffer *) NULL);
+
+ if (!PointerIsValid(tup))
+ {
+ heap_endscan(pg_type_scan);
+ heap_close(pg_type_desc);
+ elog(WARN, "DeletePgTypeTuple: %s type nonexistent",
+ &rdesc->rd_rel->relname);
+ }
+
+ /* ----------------
+ * now scan pg_attribute. if any other relations have
+ * attributes of the type of the relation we are deleteing
+ * then we have to disallow the deletion. should talk to
+ * stonebraker about this. -cim 6/19/90
+ * ----------------
+ */
+ typoid = tup->t_oid;
+
+ pg_attribute_desc = heap_openr(AttributeRelationName);
+
+ ScanKeyEntryInitialize(&attkey,
+ 0, Anum_pg_attribute_atttypid, F_INT4EQ,
+ typoid);
+
+ pg_attribute_scan = heap_beginscan(pg_attribute_desc,
+ 0,
+ NowTimeQual,
+ 1,
+ &attkey);
+
+ /* ----------------
+ * try and get a pg_attribute tuple. if we succeed it means
+ * we cant delete the relation because something depends on
+ * the schema.
+ * ----------------
+ */
+ atttup = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL);
+
+ if (PointerIsValid(atttup))
+ {
+ Oid relid = ((AttributeTupleForm) GETSTRUCT(atttup))->attrelid;
+
+ heap_endscan(pg_type_scan);
+ heap_close(pg_type_desc);
+ heap_endscan(pg_attribute_scan);
+ heap_close(pg_attribute_desc);
+
+ elog(WARN, "DeletePgTypeTuple: att of type %s exists in relation %d",
+ &rdesc->rd_rel->relname, relid);
+ }
heap_endscan(pg_attribute_scan);
heap_close(pg_attribute_desc);
-
- elog(WARN, "DeletePgTypeTuple: att of type %s exists in relation %d",
- &rdesc->rd_rel->relname, relid);
- }
- heap_endscan(pg_attribute_scan);
- heap_close(pg_attribute_desc);
-
- /* ----------------
- * Ok, it's safe so we delete the relation tuple
- * from pg_type and finish up. But first end the scan so that
- * we release the read lock on pg_type. -mer 13 Aug 1991
- * ----------------
- */
- heap_endscan(pg_type_scan);
- heap_delete(pg_type_desc, &tup->t_ctid);
-
- heap_close(pg_type_desc);
+
+ /* ----------------
+ * Ok, it's safe so we delete the relation tuple
+ * from pg_type and finish up. But first end the scan so that
+ * we release the read lock on pg_type. -mer 13 Aug 1991
+ * ----------------
+ */
+ heap_endscan(pg_type_scan);
+ heap_delete(pg_type_desc, &tup->t_ctid);
+
+ heap_close(pg_type_desc);
}
/* --------------------------------
- * heap_destroy
+ * heap_destroy
*
* --------------------------------
*/
void
heap_destroy(char *relname)
{
- Relation rdesc;
- Oid rid;
-
- /* ----------------
- * first open the relation. if the relation does exist,
- * heap_openr() returns NULL.
- * ----------------
- */
- rdesc = heap_openr(relname);
- if ( rdesc == NULL )
- elog (WARN, "Relation %s Does Not Exist!", relname);
-
- RelationSetLockForWrite(rdesc);
- rid = rdesc->rd_id;
-
- /* ----------------
- * prevent deletion of system relations
- * ----------------
- */
- if (IsSystemRelationName(RelationGetRelationName(rdesc)->data))
- elog(WARN, "amdestroy: cannot destroy %s relation",
- &rdesc->rd_rel->relname);
-
- /* ----------------
- * remove inheritance information
- * ----------------
- */
- RelationRemoveInheritance(rdesc);
-
- /* ----------------
- * remove indexes if necessary
- * ----------------
- */
- if (rdesc->rd_rel->relhasindex) {
- RelationRemoveIndexes(rdesc);
- }
-
- /* ----------------
- * remove rules if necessary
- * ----------------
- */
- if (rdesc->rd_rules != NULL) {
- RelationRemoveRules(rid);
- }
-
- /* triggers */
- if ( rdesc->rd_rel->reltriggers > 0 )
- RelationRemoveTriggers (rdesc);
-
- /* ----------------
- * delete attribute tuples
- * ----------------
- */
- DeletePgAttributeTuples(rdesc);
-
- /* ----------------
- * delete type tuple. here we want to see the effects
- * of the deletions we just did, so we use setheapoverride().
- * ----------------
- */
- setheapoverride(true);
- DeletePgTypeTuple(rdesc);
- setheapoverride(false);
-
- /* ----------------
- * delete relation tuple
- * ----------------
- */
- DeletePgRelationTuple(rdesc);
-
- /*
- * release dirty buffers of this relation
- */
- ReleaseRelationBuffers (rdesc);
-
- /* ----------------
- * flush the relation from the relcache
- * ----------------
- * Does nothing!!! Flushing moved below. - vadim 06/04/97
- RelationIdInvalidateRelationCacheByRelationId(rdesc->rd_id);
- */
-
- RemoveConstraints (rdesc);
-
- /* ----------------
- * unlink the relation and finish up.
- * ----------------
- */
- if ( !(rdesc->rd_istemp) || !(rdesc->rd_tmpunlinked) )
- {
- smgrunlink(rdesc->rd_rel->relsmgr, rdesc);
- }
- rdesc->rd_tmpunlinked = TRUE;
-
- RelationUnsetLockForWrite(rdesc);
-
- heap_close(rdesc);
-
- /* ok - flush the relation from the relcache */
- RelationForgetRelation (rid);
+ Relation rdesc;
+ Oid rid;
+
+ /* ----------------
+ * first open the relation. if the relation does exist,
+ * heap_openr() returns NULL.
+ * ----------------
+ */
+ rdesc = heap_openr(relname);
+ if (rdesc == NULL)
+ elog(WARN, "Relation %s Does Not Exist!", relname);
+
+ RelationSetLockForWrite(rdesc);
+ rid = rdesc->rd_id;
+
+ /* ----------------
+ * prevent deletion of system relations
+ * ----------------
+ */
+ if (IsSystemRelationName(RelationGetRelationName(rdesc)->data))
+ elog(WARN, "amdestroy: cannot destroy %s relation",
+ &rdesc->rd_rel->relname);
+
+ /* ----------------
+ * remove inheritance information
+ * ----------------
+ */
+ RelationRemoveInheritance(rdesc);
+
+ /* ----------------
+ * remove indexes if necessary
+ * ----------------
+ */
+ if (rdesc->rd_rel->relhasindex)
+ {
+ RelationRemoveIndexes(rdesc);
+ }
+
+ /* ----------------
+ * remove rules if necessary
+ * ----------------
+ */
+ if (rdesc->rd_rules != NULL)
+ {
+ RelationRemoveRules(rid);
+ }
+
+ /* triggers */
+ if (rdesc->rd_rel->reltriggers > 0)
+ RelationRemoveTriggers(rdesc);
+
+ /* ----------------
+ * delete attribute tuples
+ * ----------------
+ */
+ DeletePgAttributeTuples(rdesc);
+
+ /* ----------------
+ * delete type tuple. here we want to see the effects
+ * of the deletions we just did, so we use setheapoverride().
+ * ----------------
+ */
+ setheapoverride(true);
+ DeletePgTypeTuple(rdesc);
+ setheapoverride(false);
+
+ /* ----------------
+ * delete relation tuple
+ * ----------------
+ */
+ DeletePgRelationTuple(rdesc);
+
+ /*
+ * release dirty buffers of this relation
+ */
+ ReleaseRelationBuffers(rdesc);
+
+ /* ----------------
+ * flush the relation from the relcache
+ * ----------------
+ * Does nothing!!! Flushing moved below. - vadim 06/04/97
+ RelationIdInvalidateRelationCacheByRelationId(rdesc->rd_id);
+ */
+
+ RemoveConstraints(rdesc);
+
+ /* ----------------
+ * unlink the relation and finish up.
+ * ----------------
+ */
+ if (!(rdesc->rd_istemp) || !(rdesc->rd_tmpunlinked))
+ {
+ smgrunlink(rdesc->rd_rel->relsmgr, rdesc);
+ }
+ rdesc->rd_tmpunlinked = TRUE;
+
+ RelationUnsetLockForWrite(rdesc);
+
+ heap_close(rdesc);
+
+ /* ok - flush the relation from the relcache */
+ RelationForgetRelation(rid);
}
/*
* heap_destroyr
- * destroy and close temporary relations
+ * destroy and close temporary relations
*
*/
-void
+void
heap_destroyr(Relation rdesc)
{
- ReleaseRelationBuffers(rdesc);
- if ( !(rdesc->rd_istemp) || !(rdesc->rd_tmpunlinked) )
- {
- smgrunlink(rdesc->rd_rel->relsmgr, rdesc);
- }
- rdesc->rd_tmpunlinked = TRUE;
- heap_close(rdesc);
- RemoveFromTempRelList(rdesc);
+ ReleaseRelationBuffers(rdesc);
+ if (!(rdesc->rd_istemp) || !(rdesc->rd_tmpunlinked))
+ {
+ smgrunlink(rdesc->rd_rel->relsmgr, rdesc);
+ }
+ rdesc->rd_tmpunlinked = TRUE;
+ heap_close(rdesc);
+ RemoveFromTempRelList(rdesc);
}
/**************************************************************
- functions to deal with the list of temporary relations
+ functions to deal with the list of temporary relations
**************************************************************/
/* --------------
@@ -1393,46 +1428,49 @@ heap_destroyr(Relation rdesc)
>> NOTE <<
malloc is used instead of palloc because we KNOW when we are
- going to free these things. Keeps us away from the memory context
+ going to free these things. Keeps us away from the memory context
hairyness
*/
void
InitTempRelList(void)
{
- if (tempRels) {
- free(tempRels->rels);
- free(tempRels);
- }
+ if (tempRels)
+ {
+ free(tempRels->rels);
+ free(tempRels);
+ }
- tempRels = (TempRelList*)malloc(sizeof(TempRelList));
- tempRels->size = TEMP_REL_LIST_SIZE;
- tempRels->rels = (Relation*)malloc(sizeof(Relation) * tempRels->size);
- memset(tempRels->rels, 0, sizeof(Relation) * tempRels->size);
- tempRels->num = 0;
+ tempRels = (TempRelList *) malloc(sizeof(TempRelList));
+ tempRels->size = TEMP_REL_LIST_SIZE;
+ tempRels->rels = (Relation *) malloc(sizeof(Relation) * tempRels->size);
+ memset(tempRels->rels, 0, sizeof(Relation) * tempRels->size);
+ tempRels->num = 0;
}
/*
removes a relation from the TempRelList
MODIFIES the global variable tempRels
- we don't really remove it, just mark it as NULL
- and DestroyTempRels will look for NULLs
+ we don't really remove it, just mark it as NULL
+ and DestroyTempRels will look for NULLs
*/
static void
RemoveFromTempRelList(Relation r)
{
- int i;
+ int i;
- if (!tempRels)
- return;
+ if (!tempRels)
+ return;
- for (i=0; i<tempRels->num; i++) {
- if (tempRels->rels[i] == r) {
- tempRels->rels[i] = NULL;
- break;
+ for (i = 0; i < tempRels->num; i++)
+ {
+ if (tempRels->rels[i] == r)
+ {
+ tempRels->rels[i] = NULL;
+ break;
+ }
}
- }
}
/*
@@ -1443,16 +1481,17 @@ RemoveFromTempRelList(Relation r)
static void
AddToTempRelList(Relation r)
{
- if (!tempRels)
- return;
+ if (!tempRels)
+ return;
- if (tempRels->num == tempRels->size) {
- tempRels->size += TEMP_REL_LIST_SIZE;
- tempRels->rels = realloc(tempRels->rels,
- sizeof(Relation) * tempRels->size);
- }
- tempRels->rels[tempRels->num] = r;
- tempRels->num++;
+ if (tempRels->num == tempRels->size)
+ {
+ tempRels->size += TEMP_REL_LIST_SIZE;
+ tempRels->rels = realloc(tempRels->rels,
+ sizeof(Relation) * tempRels->size);
+ }
+ tempRels->rels[tempRels->num] = r;
+ tempRels->num++;
}
/*
@@ -1461,251 +1500,253 @@ AddToTempRelList(Relation r)
void
DestroyTempRels(void)
{
- int i;
- Relation rdesc;
+ int i;
+ Relation rdesc;
- if (!tempRels)
- return;
+ if (!tempRels)
+ return;
- for (i=0;i<tempRels->num;i++) {
- rdesc = tempRels->rels[i];
- /* rdesc may be NULL if it has been removed from the list already */
- if (rdesc)
- heap_destroyr(rdesc);
- }
- free(tempRels->rels);
- free(tempRels);
- tempRels = NULL;
+ for (i = 0; i < tempRels->num; i++)
+ {
+ rdesc = tempRels->rels[i];
+ /* rdesc may be NULL if it has been removed from the list already */
+ if (rdesc)
+ heap_destroyr(rdesc);
+ }
+ free(tempRels->rels);
+ free(tempRels);
+ tempRels = NULL;
}
-extern List *flatten_tlist(List *tlist);
-extern List *pg_plan(char *query_string, Oid *typev, int nargs,
- QueryTreeList **queryListP, CommandDest dest);
+extern List *flatten_tlist(List * tlist);
+extern List *
+pg_plan(char *query_string, Oid * typev, int nargs,
+ QueryTreeList ** queryListP, CommandDest dest);
-static void
-StoreAttrDefault (Relation rel, AttrDefault *attrdef)
+static void
+StoreAttrDefault(Relation rel, AttrDefault * attrdef)
{
- char str[MAX_PARSE_BUFFER];
- char cast[2*NAMEDATALEN] = {0};
- AttributeTupleForm atp = rel->rd_att->attrs[attrdef->adnum - 1];
- QueryTreeList *queryTree_list;
- Query *query;
- List *planTree_list;
- TargetEntry *te;
- Resdom *resdom;
- Node *expr;
- char *adbin;
- MemoryContext oldcxt;
- Relation adrel;
- Relation idescs[Num_pg_attrdef_indices];
- HeapTuple tuple;
- Datum values[4];
- char nulls[4] = {' ', ' ', ' ', ' '};
- extern GlobalMemory CacheCxt;
-
+ char str[MAX_PARSE_BUFFER];
+ char cast[2 * NAMEDATALEN] = {0};
+ AttributeTupleForm atp = rel->rd_att->attrs[attrdef->adnum - 1];
+ QueryTreeList *queryTree_list;
+ Query *query;
+ List *planTree_list;
+ TargetEntry *te;
+ Resdom *resdom;
+ Node *expr;
+ char *adbin;
+ MemoryContext oldcxt;
+ Relation adrel;
+ Relation idescs[Num_pg_attrdef_indices];
+ HeapTuple tuple;
+ Datum values[4];
+ char nulls[4] = {' ', ' ', ' ', ' '};
+ extern GlobalMemory CacheCxt;
+
start:;
- sprintf (str, "select %s%s from %.*s", attrdef->adsrc, cast,
- NAMEDATALEN, rel->rd_rel->relname.data);
- setheapoverride(true);
- planTree_list = (List*) pg_plan (str, NULL, 0, &queryTree_list, None);
- setheapoverride(false);
- query = (Query*) (queryTree_list->qtrees[0]);
-
- if ( length (query->rtable) > 1 ||
- flatten_tlist (query->targetList) != NIL )
- elog (WARN, "DEFAULT: cannot use attribute(s)");
- te = (TargetEntry *) lfirst (query->targetList);
- resdom = te->resdom;
- expr = te->expr;
-
- if ( IsA (expr, Const) )
- {
- if ( ((Const*)expr)->consttype != atp->atttypid )
- {
- if ( *cast != 0 )
- elog (WARN, "DEFAULT: const type mismatched");
- sprintf (cast, ":: %s", get_id_typname (atp->atttypid));
- goto start;
- }
- }
- else if ( exprType (expr) != atp->atttypid )
- elog (WARN, "DEFAULT: type mismatched");
-
- adbin = nodeToString (expr);
- oldcxt = MemoryContextSwitchTo ((MemoryContext) CacheCxt);
- attrdef->adbin = (char*) palloc (strlen (adbin) + 1);
- strcpy (attrdef->adbin, adbin);
- (void) MemoryContextSwitchTo (oldcxt);
- pfree (adbin);
-
- values[Anum_pg_attrdef_adrelid - 1] = rel->rd_id;
- values[Anum_pg_attrdef_adnum - 1] = attrdef->adnum;
- values[Anum_pg_attrdef_adbin - 1] = PointerGetDatum (textin (attrdef->adbin));
- values[Anum_pg_attrdef_adsrc - 1] = PointerGetDatum (textin (attrdef->adsrc));
- adrel = heap_openr (AttrDefaultRelationName);
- tuple = heap_formtuple (adrel->rd_att, values, nulls);
- CatalogOpenIndices (Num_pg_attrdef_indices, Name_pg_attrdef_indices, idescs);
- heap_insert (adrel, tuple);
- CatalogIndexInsert (idescs, Num_pg_attrdef_indices, adrel, tuple);
- CatalogCloseIndices (Num_pg_attrdef_indices, idescs);
- heap_close (adrel);
-
- pfree (DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
- pfree (DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
- pfree (tuple);
+ sprintf(str, "select %s%s from %.*s", attrdef->adsrc, cast,
+ NAMEDATALEN, rel->rd_rel->relname.data);
+ setheapoverride(true);
+ planTree_list = (List *) pg_plan(str, NULL, 0, &queryTree_list, None);
+ setheapoverride(false);
+ query = (Query *) (queryTree_list->qtrees[0]);
+
+ if (length(query->rtable) > 1 ||
+ flatten_tlist(query->targetList) != NIL)
+ elog(WARN, "DEFAULT: cannot use attribute(s)");
+ te = (TargetEntry *) lfirst(query->targetList);
+ resdom = te->resdom;
+ expr = te->expr;
+
+ if (IsA(expr, Const))
+ {
+ if (((Const *) expr)->consttype != atp->atttypid)
+ {
+ if (*cast != 0)
+ elog(WARN, "DEFAULT: const type mismatched");
+ sprintf(cast, ":: %s", get_id_typname(atp->atttypid));
+ goto start;
+ }
+ }
+ else if (exprType(expr) != atp->atttypid)
+ elog(WARN, "DEFAULT: type mismatched");
+
+ adbin = nodeToString(expr);
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ attrdef->adbin = (char *) palloc(strlen(adbin) + 1);
+ strcpy(attrdef->adbin, adbin);
+ (void) MemoryContextSwitchTo(oldcxt);
+ pfree(adbin);
+
+ values[Anum_pg_attrdef_adrelid - 1] = rel->rd_id;
+ values[Anum_pg_attrdef_adnum - 1] = attrdef->adnum;
+ values[Anum_pg_attrdef_adbin - 1] = PointerGetDatum(textin(attrdef->adbin));
+ values[Anum_pg_attrdef_adsrc - 1] = PointerGetDatum(textin(attrdef->adsrc));
+ adrel = heap_openr(AttrDefaultRelationName);
+ tuple = heap_formtuple(adrel->rd_att, values, nulls);
+ CatalogOpenIndices(Num_pg_attrdef_indices, Name_pg_attrdef_indices, idescs);
+ heap_insert(adrel, tuple);
+ CatalogIndexInsert(idescs, Num_pg_attrdef_indices, adrel, tuple);
+ CatalogCloseIndices(Num_pg_attrdef_indices, idescs);
+ heap_close(adrel);
+
+ pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
+ pfree(DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
+ pfree(tuple);
}
-static void
-StoreRelCheck (Relation rel, ConstrCheck *check)
+static void
+StoreRelCheck(Relation rel, ConstrCheck * check)
{
- char str[MAX_PARSE_BUFFER];
- QueryTreeList *queryTree_list;
- Query *query;
- List *planTree_list;
- Plan *plan;
- List *qual;
- char *ccbin;
- MemoryContext oldcxt;
- Relation rcrel;
- Relation idescs[Num_pg_relcheck_indices];
- HeapTuple tuple;
- Datum values[4];
- char nulls[4] = {' ', ' ', ' ', ' '};
- extern GlobalMemory CacheCxt;
-
- sprintf (str, "select 1 from %.*s where %s",
- NAMEDATALEN, rel->rd_rel->relname.data, check->ccsrc);
- setheapoverride(true);
- planTree_list = (List*) pg_plan (str, NULL, 0, &queryTree_list, None);
- setheapoverride(false);
- query = (Query*) (queryTree_list->qtrees[0]);
-
- if ( length (query->rtable) > 1 )
- elog (WARN, "CHECK: only relation %.*s can be referenced",
- NAMEDATALEN, rel->rd_rel->relname.data);
-
- plan = (Plan*) lfirst(planTree_list);
- qual = plan->qual;
-
- ccbin = nodeToString (qual);
- oldcxt = MemoryContextSwitchTo ((MemoryContext) CacheCxt);
- check->ccbin = (char*) palloc (strlen (ccbin) + 1);
- strcpy (check->ccbin, ccbin);
- (void) MemoryContextSwitchTo (oldcxt);
- pfree (ccbin);
-
- values[Anum_pg_relcheck_rcrelid - 1] = rel->rd_id;
- values[Anum_pg_relcheck_rcname - 1] = PointerGetDatum (namein (check->ccname));
- values[Anum_pg_relcheck_rcbin - 1] = PointerGetDatum (textin (check->ccbin));
- values[Anum_pg_relcheck_rcsrc - 1] = PointerGetDatum (textin (check->ccsrc));
- rcrel = heap_openr (RelCheckRelationName);
- tuple = heap_formtuple (rcrel->rd_att, values, nulls);
- CatalogOpenIndices (Num_pg_relcheck_indices, Name_pg_relcheck_indices, idescs);
- heap_insert (rcrel, tuple);
- CatalogIndexInsert (idescs, Num_pg_relcheck_indices, rcrel, tuple);
- CatalogCloseIndices (Num_pg_relcheck_indices, idescs);
- heap_close (rcrel);
-
- pfree (DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
- pfree (DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
- pfree (DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
- pfree (tuple);
-
- return;
+ char str[MAX_PARSE_BUFFER];
+ QueryTreeList *queryTree_list;
+ Query *query;
+ List *planTree_list;
+ Plan *plan;
+ List *qual;
+ char *ccbin;
+ MemoryContext oldcxt;
+ Relation rcrel;
+ Relation idescs[Num_pg_relcheck_indices];
+ HeapTuple tuple;
+ Datum values[4];
+ char nulls[4] = {' ', ' ', ' ', ' '};
+ extern GlobalMemory CacheCxt;
+
+ sprintf(str, "select 1 from %.*s where %s",
+ NAMEDATALEN, rel->rd_rel->relname.data, check->ccsrc);
+ setheapoverride(true);
+ planTree_list = (List *) pg_plan(str, NULL, 0, &queryTree_list, None);
+ setheapoverride(false);
+ query = (Query *) (queryTree_list->qtrees[0]);
+
+ if (length(query->rtable) > 1)
+ elog(WARN, "CHECK: only relation %.*s can be referenced",
+ NAMEDATALEN, rel->rd_rel->relname.data);
+
+ plan = (Plan *) lfirst(planTree_list);
+ qual = plan->qual;
+
+ ccbin = nodeToString(qual);
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ check->ccbin = (char *) palloc(strlen(ccbin) + 1);
+ strcpy(check->ccbin, ccbin);
+ (void) MemoryContextSwitchTo(oldcxt);
+ pfree(ccbin);
+
+ values[Anum_pg_relcheck_rcrelid - 1] = rel->rd_id;
+ values[Anum_pg_relcheck_rcname - 1] = PointerGetDatum(namein(check->ccname));
+ values[Anum_pg_relcheck_rcbin - 1] = PointerGetDatum(textin(check->ccbin));
+ values[Anum_pg_relcheck_rcsrc - 1] = PointerGetDatum(textin(check->ccsrc));
+ rcrel = heap_openr(RelCheckRelationName);
+ tuple = heap_formtuple(rcrel->rd_att, values, nulls);
+ CatalogOpenIndices(Num_pg_relcheck_indices, Name_pg_relcheck_indices, idescs);
+ heap_insert(rcrel, tuple);
+ CatalogIndexInsert(idescs, Num_pg_relcheck_indices, rcrel, tuple);
+ CatalogCloseIndices(Num_pg_relcheck_indices, idescs);
+ heap_close(rcrel);
+
+ pfree(DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
+ pfree(DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
+ pfree(DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
+ pfree(tuple);
+
+ return;
}
-static void
-StoreConstraints (Relation rel)
+static void
+StoreConstraints(Relation rel)
{
- TupleConstr *constr = rel->rd_att->constr;
- int i;
-
- if ( !constr )
- return;
-
- if ( constr->num_defval > 0 )
- {
- for (i = 0; i < constr->num_defval; i++)
- StoreAttrDefault (rel, &(constr->defval[i]));
- }
-
- if ( constr->num_check > 0 )
- {
- for (i = 0; i < constr->num_check; i++)
- StoreRelCheck (rel, &(constr->check[i]));
- }
-
- return;
+ TupleConstr *constr = rel->rd_att->constr;
+ int i;
+
+ if (!constr)
+ return;
+
+ if (constr->num_defval > 0)
+ {
+ for (i = 0; i < constr->num_defval; i++)
+ StoreAttrDefault(rel, &(constr->defval[i]));
+ }
+
+ if (constr->num_check > 0)
+ {
+ for (i = 0; i < constr->num_check; i++)
+ StoreRelCheck(rel, &(constr->check[i]));
+ }
+
+ return;
}
-static void
-RemoveAttrDefault (Relation rel)
+static void
+RemoveAttrDefault(Relation rel)
{
- Relation adrel;
- HeapScanDesc adscan;
- ScanKeyData key;
- HeapTuple tup;
-
- adrel = heap_openr (AttrDefaultRelationName);
-
- ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid,
- ObjectIdEqualRegProcedure, rel->rd_id);
-
- RelationSetLockForWrite (adrel);
-
- adscan = heap_beginscan(adrel, 0, NowTimeQual, 1, &key);
-
- while (tup = heap_getnext (adscan, 0, (Buffer *)NULL), PointerIsValid(tup))
- heap_delete (adrel, &tup->t_ctid);
-
- heap_endscan (adscan);
-
- RelationUnsetLockForWrite (adrel);
- heap_close (adrel);
+ Relation adrel;
+ HeapScanDesc adscan;
+ ScanKeyData key;
+ HeapTuple tup;
+
+ adrel = heap_openr(AttrDefaultRelationName);
+
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid,
+ ObjectIdEqualRegProcedure, rel->rd_id);
+
+ RelationSetLockForWrite(adrel);
+
+ adscan = heap_beginscan(adrel, 0, NowTimeQual, 1, &key);
+
+ while (tup = heap_getnext(adscan, 0, (Buffer *) NULL), PointerIsValid(tup))
+ heap_delete(adrel, &tup->t_ctid);
+
+ heap_endscan(adscan);
+
+ RelationUnsetLockForWrite(adrel);
+ heap_close(adrel);
}
-static void
-RemoveRelCheck (Relation rel)
+static void
+RemoveRelCheck(Relation rel)
{
- Relation rcrel;
- HeapScanDesc rcscan;
- ScanKeyData key;
- HeapTuple tup;
-
- rcrel = heap_openr (RelCheckRelationName);
-
- ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
- ObjectIdEqualRegProcedure, rel->rd_id);
-
- RelationSetLockForWrite (rcrel);
-
- rcscan = heap_beginscan(rcrel, 0, NowTimeQual, 1, &key);
-
- while (tup = heap_getnext (rcscan, 0, (Buffer *)NULL), PointerIsValid(tup))
- heap_delete (rcrel, &tup->t_ctid);
-
- heap_endscan (rcscan);
-
- RelationUnsetLockForWrite (rcrel);
- heap_close (rcrel);
+ Relation rcrel;
+ HeapScanDesc rcscan;
+ ScanKeyData key;
+ HeapTuple tup;
+
+ rcrel = heap_openr(RelCheckRelationName);
+
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
+ ObjectIdEqualRegProcedure, rel->rd_id);
+
+ RelationSetLockForWrite(rcrel);
+
+ rcscan = heap_beginscan(rcrel, 0, NowTimeQual, 1, &key);
+
+ while (tup = heap_getnext(rcscan, 0, (Buffer *) NULL), PointerIsValid(tup))
+ heap_delete(rcrel, &tup->t_ctid);
+
+ heap_endscan(rcscan);
+
+ RelationUnsetLockForWrite(rcrel);
+ heap_close(rcrel);
}
-static void
-RemoveConstraints (Relation rel)
+static void
+RemoveConstraints(Relation rel)
{
- TupleConstr *constr = rel->rd_att->constr;
-
- if ( !constr )
- return;
-
- if ( constr->num_defval > 0 )
- RemoveAttrDefault (rel);
-
- if ( constr->num_check > 0 )
- RemoveRelCheck (rel);
-
- return;
+ TupleConstr *constr = rel->rd_att->constr;
+
+ if (!constr)
+ return;
+
+ if (constr->num_defval > 0)
+ RemoveAttrDefault(rel);
+
+ if (constr->num_check > 0)
+ RemoveRelCheck(rel);
+
+ return;
}
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index b2071f814f2..6dd75742798 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* index.c--
- * code to create and destroy POSTGRES index relations
+ * code to create and destroy POSTGRES index relations
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.19 1997/08/22 14:10:26 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.20 1997/09/07 04:40:19 momjian Exp $
*
*
* INTERFACE ROUTINES
- * index_create() - Create a cataloged index relation
- * index_destroy() - Removes index relation from catalogs
+ * index_create() - Create a cataloged index relation
+ * index_destroy() - Removes index relation from catalogs
*
* NOTES
- * Much of this code uses hardcoded sequential heap relation scans
- * to fetch information from the catalogs. These should all be
- * rewritten to use the system caches lookup routines like
- * SearchSysCacheTuple, which can do efficient lookup and
- * caching.
+ * Much of this code uses hardcoded sequential heap relation scans
+ * to fetch information from the catalogs. These should all be
+ * rewritten to use the system caches lookup routines like
+ * SearchSysCacheTuple, which can do efficient lookup and
+ * caching.
*
*-------------------------------------------------------------------------
*/
@@ -51,9 +51,9 @@
#include <access/istrat.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
/*
@@ -63,70 +63,75 @@
#define NTUPLES_PER_PAGE(natts) (BLCKSZ/((natts)*AVG_TUPLE_SIZE))
/* non-export function prototypes */
-static Oid RelationNameGetObjectId(char *relationName, Relation pg_class,
- bool setHasIndexAttribute);
-static Oid GetHeapRelationOid(char *heapRelationName, char *indexRelationName);
-static TupleDesc BuildFuncTupleDesc(FuncIndexInfo *funcInfo);
-static TupleDesc ConstructTupleDescriptor(Oid heapoid, Relation heapRelation,
- List *attributeList,
- int numatts, AttrNumber attNums[]);
-
-static void ConstructIndexReldesc(Relation indexRelation, Oid amoid);
-static Oid UpdateRelationRelation(Relation indexRelation);
-static void InitializeAttributeOids(Relation indexRelation,
- int numatts,
- Oid indexoid);
+static Oid
+RelationNameGetObjectId(char *relationName, Relation pg_class,
+ bool setHasIndexAttribute);
+static Oid GetHeapRelationOid(char *heapRelationName, char *indexRelationName);
+static TupleDesc BuildFuncTupleDesc(FuncIndexInfo * funcInfo);
+static TupleDesc
+ConstructTupleDescriptor(Oid heapoid, Relation heapRelation,
+ List * attributeList,
+ int numatts, AttrNumber attNums[]);
+
+static void ConstructIndexReldesc(Relation indexRelation, Oid amoid);
+static Oid UpdateRelationRelation(Relation indexRelation);
+static void
+InitializeAttributeOids(Relation indexRelation,
+ 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);
-static void DefaultBuild(Relation heapRelation, Relation indexRelation,
- int numberOfAttributes, AttrNumber attributeNumber[],
- IndexStrategy indexStrategy, uint16 parameterCount,
- Datum parameter[], FuncIndexInfoPtr funcInfo, PredInfo *predInfo);
+ 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);
+static void
+DefaultBuild(Relation heapRelation, Relation indexRelation,
+ int numberOfAttributes, AttrNumber attributeNumber[],
+ IndexStrategy indexStrategy, uint16 parameterCount,
+ Datum parameter[], FuncIndexInfoPtr funcInfo, PredInfo * predInfo);
/* ----------------------------------------------------------------
- * sysatts is a structure containing attribute tuple forms
- * for system attributes (numbered -1, -2, ...). This really
- * should be generated or eliminated or moved elsewhere. -cim 1/19/91
+ * sysatts is a structure containing attribute tuple forms
+ * for system attributes (numbered -1, -2, ...). This really
+ * should be generated or eliminated or moved elsewhere. -cim 1/19/91
*
* typedef struct FormData_pg_attribute {
- * Oid attrelid;
- * NameData attname;
- * Oid atttypid;
- * uint32 attnvals;
- * int16 attlen;
- * AttrNumber attnum;
- * uint32 attnelems;
- * int32 attcacheoff;
- * bool attbyval;
- * bool attisset;
- * char attalign;
- * bool attnotnull;
- * bool atthasdef;
+ * Oid attrelid;
+ * NameData attname;
+ * Oid atttypid;
+ * uint32 attnvals;
+ * int16 attlen;
+ * AttrNumber attnum;
+ * uint32 attnelems;
+ * int32 attcacheoff;
+ * bool attbyval;
+ * bool attisset;
+ * char attalign;
+ * bool attnotnull;
+ * bool atthasdef;
* } FormData_pg_attribute;
*
* ----------------------------------------------------------------
*/
-static FormData_pg_attribute sysatts[] = {
- { 0l, {"ctid"}, 27l, 0l, 6, -1, 0, -1, '\0', '\0', 'i', '\0', '\0' },
- { 0l, {"oid"}, 26l, 0l, 4, -2, 0, -1, '\001', '\0', 'i', '\0', '\0' },
- { 0l, {"xmin"}, 28l, 0l, 4, -3, 0, -1, '\0', '\0', 'i', '\0', '\0' },
- { 0l, {"cmin"}, 29l, 0l, 2, -4, 0, -1, '\001', '\0', 's', '\0', '\0' },
- { 0l, {"xmax"}, 28l, 0l, 4, -5, 0, -1, '\0', '\0', 'i', '\0', '\0' },
- { 0l, {"cmax"}, 29l, 0l, 2, -6, 0, -1, '\001', '\0', 's', '\0', '\0' },
- { 0l, {"chain"}, 27l, 0l, 6, -7, 0, -1, '\0', '\0', 'i', '\0', '\0' },
- { 0l, {"anchor"}, 27l, 0l, 6, -8, 0, -1, '\0', '\0', 'i', '\0', '\0' },
- { 0l, {"tmin"}, 702l, 0l, 4, -9, 0, -1, '\001', '\0', 'i', '\0', '\0' },
- { 0l, {"tmax"}, 702l, 0l, 4, -10, 0, -1, '\001', '\0', 'i', '\0', '\0' },
- { 0l, {"vtype"}, 18l, 0l, 1, -11, 0, -1, '\001', '\0', 'c', '\0', '\0' },
+static FormData_pg_attribute sysatts[] = {
+ {0l, {"ctid"}, 27l, 0l, 6, -1, 0, -1, '\0', '\0', 'i', '\0', '\0'},
+ {0l, {"oid"}, 26l, 0l, 4, -2, 0, -1, '\001', '\0', 'i', '\0', '\0'},
+ {0l, {"xmin"}, 28l, 0l, 4, -3, 0, -1, '\0', '\0', 'i', '\0', '\0'},
+ {0l, {"cmin"}, 29l, 0l, 2, -4, 0, -1, '\001', '\0', 's', '\0', '\0'},
+ {0l, {"xmax"}, 28l, 0l, 4, -5, 0, -1, '\0', '\0', 'i', '\0', '\0'},
+ {0l, {"cmax"}, 29l, 0l, 2, -6, 0, -1, '\001', '\0', 's', '\0', '\0'},
+ {0l, {"chain"}, 27l, 0l, 6, -7, 0, -1, '\0', '\0', 'i', '\0', '\0'},
+ {0l, {"anchor"}, 27l, 0l, 6, -8, 0, -1, '\0', '\0', 'i', '\0', '\0'},
+ {0l, {"tmin"}, 702l, 0l, 4, -9, 0, -1, '\001', '\0', 'i', '\0', '\0'},
+ {0l, {"tmax"}, 702l, 0l, 4, -10, 0, -1, '\001', '\0', 'i', '\0', '\0'},
+ {0l, {"vtype"}, 18l, 0l, 1, -11, 0, -1, '\001', '\0', 'c', '\0', '\0'},
};
/* ----------------------------------------------------------------
* RelationNameGetObjectId --
- * Returns the object identifier for a relation given its name.
+ * Returns the object identifier for a relation given its name.
*
* > The HASINDEX attribute for the relation with this name will
* > be set if it exists and if it is indicated by the call argument.
@@ -135,1574 +140,1638 @@ static FormData_pg_attribute sysatts[] = {
* probably be replaced by SearchSysCacheTuple. -cim 1/19/91
*
* Note:
- * Assumes relation name is valid.
- * Assumes relation descriptor is valid.
+ * Assumes relation name is valid.
+ * Assumes relation descriptor is valid.
* ----------------------------------------------------------------
*/
-static Oid
+static Oid
RelationNameGetObjectId(char *relationName,
- Relation pg_class,
- bool setHasIndexAttribute)
-{
- HeapScanDesc pg_class_scan;
- HeapTuple pg_class_tuple;
- Oid relationObjectId;
- Buffer buffer;
- ScanKeyData key;
-
- /*
- * If this isn't bootstrap time, we can use the system catalogs to
- * speed this up.
- */
-
- if (!IsBootstrapProcessingMode()) {
- pg_class_tuple = ClassNameIndexScan(pg_class, relationName);
- if (HeapTupleIsValid(pg_class_tuple)) {
- relationObjectId = pg_class_tuple->t_oid;
- pfree(pg_class_tuple);
- } else
- relationObjectId = InvalidOid;
-
- return (relationObjectId);
- }
-
- /* ----------------
- * Bootstrap time, do this the hard way.
- * begin a scan of pg_class for the named relation
- * ----------------
- */
- ScanKeyEntryInitialize(&key, 0, Anum_pg_class_relname,
- NameEqualRegProcedure,
- PointerGetDatum(relationName));
-
- pg_class_scan = heap_beginscan(pg_class, 0, NowTimeQual, 1, &key);
-
- /* ----------------
- * if we find the named relation, fetch its relation id
- * (the oid of the tuple we found).
- * ----------------
- */
- pg_class_tuple = heap_getnext(pg_class_scan, 0, &buffer);
-
- if (! HeapTupleIsValid(pg_class_tuple)) {
- relationObjectId = InvalidOid;
- } else {
- relationObjectId = pg_class_tuple->t_oid;
- ReleaseBuffer(buffer);
- }
-
- /* ----------------
- * cleanup and return results
- * ----------------
- */
- heap_endscan(pg_class_scan);
-
- return
- relationObjectId;
+ Relation pg_class,
+ bool setHasIndexAttribute)
+{
+ HeapScanDesc pg_class_scan;
+ HeapTuple pg_class_tuple;
+ Oid relationObjectId;
+ Buffer buffer;
+ ScanKeyData key;
+
+ /*
+ * If this isn't bootstrap time, we can use the system catalogs to
+ * speed this up.
+ */
+
+ if (!IsBootstrapProcessingMode())
+ {
+ pg_class_tuple = ClassNameIndexScan(pg_class, relationName);
+ if (HeapTupleIsValid(pg_class_tuple))
+ {
+ relationObjectId = pg_class_tuple->t_oid;
+ pfree(pg_class_tuple);
+ }
+ else
+ relationObjectId = InvalidOid;
+
+ return (relationObjectId);
+ }
+
+ /* ----------------
+ * Bootstrap time, do this the hard way.
+ * begin a scan of pg_class for the named relation
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_class_relname,
+ NameEqualRegProcedure,
+ PointerGetDatum(relationName));
+
+ pg_class_scan = heap_beginscan(pg_class, 0, NowTimeQual, 1, &key);
+
+ /* ----------------
+ * if we find the named relation, fetch its relation id
+ * (the oid of the tuple we found).
+ * ----------------
+ */
+ pg_class_tuple = heap_getnext(pg_class_scan, 0, &buffer);
+
+ if (!HeapTupleIsValid(pg_class_tuple))
+ {
+ relationObjectId = InvalidOid;
+ }
+ else
+ {
+ relationObjectId = pg_class_tuple->t_oid;
+ ReleaseBuffer(buffer);
+ }
+
+ /* ----------------
+ * cleanup and return results
+ * ----------------
+ */
+ heap_endscan(pg_class_scan);
+
+ return
+ relationObjectId;
}
/* ----------------------------------------------------------------
- * GetHeapRelationOid
+ * GetHeapRelationOid
* ----------------------------------------------------------------
*/
-static Oid
+static Oid
GetHeapRelationOid(char *heapRelationName, char *indexRelationName)
{
- Relation pg_class;
- Oid indoid;
- Oid heapoid;
-
- /* ----------------
- * XXX ADD INDEXING HERE
- * ----------------
- */
- /* ----------------
- * open pg_class and get the oid of the relation
- * corresponding to the name of the index relation.
- * ----------------
- */
- pg_class = heap_openr(RelationRelationName);
-
- indoid = RelationNameGetObjectId(indexRelationName,
- pg_class,
- false);
-
- if (OidIsValid(indoid))
- elog(WARN, "Cannot create index: '%s' already exists",
- indexRelationName);
-
- /* ----------------
- * get the object id of the heap relation
- * ----------------
- */
- heapoid = RelationNameGetObjectId(heapRelationName,
- pg_class,
- true);
-
- /* ----------------
- * check that the heap relation exists..
- * ----------------
- */
- if (! OidIsValid(heapoid))
- elog(WARN, "Cannot create index on '%s': relation does not exist",
- heapRelationName);
-
- /* ----------------
- * close pg_class and return the heap relation oid
- * ----------------
- */
- heap_close(pg_class);
-
- return heapoid;
+ Relation pg_class;
+ Oid indoid;
+ Oid heapoid;
+
+ /* ----------------
+ * XXX ADD INDEXING HERE
+ * ----------------
+ */
+ /* ----------------
+ * open pg_class and get the oid of the relation
+ * corresponding to the name of the index relation.
+ * ----------------
+ */
+ pg_class = heap_openr(RelationRelationName);
+
+ indoid = RelationNameGetObjectId(indexRelationName,
+ pg_class,
+ false);
+
+ if (OidIsValid(indoid))
+ elog(WARN, "Cannot create index: '%s' already exists",
+ indexRelationName);
+
+ /* ----------------
+ * get the object id of the heap relation
+ * ----------------
+ */
+ heapoid = RelationNameGetObjectId(heapRelationName,
+ pg_class,
+ true);
+
+ /* ----------------
+ * check that the heap relation exists..
+ * ----------------
+ */
+ if (!OidIsValid(heapoid))
+ elog(WARN, "Cannot create index on '%s': relation does not exist",
+ heapRelationName);
+
+ /* ----------------
+ * close pg_class and return the heap relation oid
+ * ----------------
+ */
+ heap_close(pg_class);
+
+ return heapoid;
}
-static TupleDesc
-BuildFuncTupleDesc(FuncIndexInfo *funcInfo)
+static TupleDesc
+BuildFuncTupleDesc(FuncIndexInfo * funcInfo)
{
- HeapTuple tuple;
- TupleDesc funcTupDesc;
- Oid retType;
- char *funcname;
- int4 nargs;
- Oid *argtypes;
-
- /*
- * Allocate and zero a tuple descriptor.
- */
- funcTupDesc = CreateTemplateTupleDesc(1);
- funcTupDesc->attrs[0] = (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
- memset(funcTupDesc->attrs[0], 0, ATTRIBUTE_TUPLE_SIZE);
-
- /*
- * Lookup the function for the return type.
- */
- funcname = FIgetname(funcInfo);
- nargs = FIgetnArgs(funcInfo);
- argtypes = FIgetArglist(funcInfo);
- tuple = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(funcname),
- Int32GetDatum(nargs),
- PointerGetDatum(argtypes),
- 0);
-
- if (!HeapTupleIsValid(tuple))
- func_error("BuildFuncTupleDesc", funcname, nargs, argtypes);
-
- retType = ((Form_pg_proc)GETSTRUCT(tuple))->prorettype;
-
- /*
- * Look up the return type in pg_type for the type length.
- */
- tuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(retType),
- 0,0,0);
- if (!HeapTupleIsValid(tuple))
- elog(WARN,"Function %s return type does not exist",FIgetname(funcInfo));
-
- /*
- * Assign some of the attributes values. Leave the rest as 0.
- */
- funcTupDesc->attrs[0]->attlen = ((TypeTupleForm)GETSTRUCT(tuple))->typlen;
- funcTupDesc->attrs[0]->atttypid = retType;
- funcTupDesc->attrs[0]->attnum = 1;
- funcTupDesc->attrs[0]->attbyval = ((TypeTupleForm)GETSTRUCT(tuple))->typbyval;
-
- /*
- * make the attributes name the same as the functions
- */
- namestrcpy(&funcTupDesc->attrs[0]->attname, funcname);
-
- return (funcTupDesc);
+ HeapTuple tuple;
+ TupleDesc funcTupDesc;
+ Oid retType;
+ char *funcname;
+ int4 nargs;
+ Oid *argtypes;
+
+ /*
+ * Allocate and zero a tuple descriptor.
+ */
+ funcTupDesc = CreateTemplateTupleDesc(1);
+ funcTupDesc->attrs[0] = (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+ memset(funcTupDesc->attrs[0], 0, ATTRIBUTE_TUPLE_SIZE);
+
+ /*
+ * Lookup the function for the return type.
+ */
+ funcname = FIgetname(funcInfo);
+ nargs = FIgetnArgs(funcInfo);
+ argtypes = FIgetArglist(funcInfo);
+ tuple = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(funcname),
+ Int32GetDatum(nargs),
+ PointerGetDatum(argtypes),
+ 0);
+
+ if (!HeapTupleIsValid(tuple))
+ func_error("BuildFuncTupleDesc", funcname, nargs, argtypes);
+
+ retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype;
+
+ /*
+ * Look up the return type in pg_type for the type length.
+ */
+ tuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(retType),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ elog(WARN, "Function %s return type does not exist", FIgetname(funcInfo));
+
+ /*
+ * Assign some of the attributes values. Leave the rest as 0.
+ */
+ funcTupDesc->attrs[0]->attlen = ((TypeTupleForm) GETSTRUCT(tuple))->typlen;
+ funcTupDesc->attrs[0]->atttypid = retType;
+ funcTupDesc->attrs[0]->attnum = 1;
+ funcTupDesc->attrs[0]->attbyval = ((TypeTupleForm) GETSTRUCT(tuple))->typbyval;
+
+ /*
+ * make the attributes name the same as the functions
+ */
+ namestrcpy(&funcTupDesc->attrs[0]->attname, funcname);
+
+ return (funcTupDesc);
}
/* ----------------------------------------------------------------
- * ConstructTupleDescriptor
+ * ConstructTupleDescriptor
* ----------------------------------------------------------------
*/
-static TupleDesc
+static TupleDesc
ConstructTupleDescriptor(Oid heapoid,
- Relation heapRelation,
- List *attributeList,
- int numatts,
- AttrNumber attNums[])
+ Relation heapRelation,
+ List * attributeList,
+ int numatts,
+ AttrNumber attNums[])
{
- TupleDesc heapTupDesc;
- TupleDesc indexTupDesc;
- IndexElem *IndexKey;
- TypeName *IndexKeyType;
- AttrNumber atnum; /* attributeNumber[attributeOffset] */
- AttrNumber atind;
- int natts; /* RelationTupleForm->relnatts */
- char *from; /* used to simplify memcpy below */
- char *to; /* used to simplify memcpy below */
- int i;
-
- /* ----------------
- * allocate the new tuple descriptor
- * ----------------
- */
- natts = RelationGetRelationTupleForm(heapRelation)->relnatts;
-
- indexTupDesc = CreateTemplateTupleDesc(numatts);
-
- /* ----------------
- *
- * ----------------
- */
-
- /* ----------------
- * for each attribute we are indexing, obtain its attribute
- * tuple form from either the static table of system attribute
- * tuple forms or the relation tuple descriptor
- * ----------------
- */
- for (i = 0; i < numatts; i += 1) {
-
+ TupleDesc heapTupDesc;
+ TupleDesc indexTupDesc;
+ IndexElem *IndexKey;
+ TypeName *IndexKeyType;
+ AttrNumber atnum; /* attributeNumber[attributeOffset] */
+ AttrNumber atind;
+ int natts; /* RelationTupleForm->relnatts */
+ char *from; /* used to simplify memcpy below */
+ char *to; /* used to simplify memcpy below */
+ int i;
+
/* ----------------
- * get the attribute number and make sure it's valid
+ * allocate the new tuple descriptor
* ----------------
*/
- atnum = attNums[i];
- if (atnum > natts)
- elog(WARN, "Cannot create index: attribute %d does not exist",
- atnum);
- if (attributeList) {
- IndexKey = (IndexElem*) lfirst(attributeList);
- attributeList = lnext(attributeList);
- IndexKeyType = IndexKey->tname;
- } else {
- IndexKeyType = NULL;
- }
-
- indexTupDesc->attrs[i] = (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
-
+ natts = RelationGetRelationTupleForm(heapRelation)->relnatts;
+
+ indexTupDesc = CreateTemplateTupleDesc(numatts);
+
/* ----------------
- * determine which tuple descriptor to copy
+ *
* ----------------
*/
- if (!AttrNumberIsForUserDefinedAttr(atnum)) {
-
- /* ----------------
- * here we are indexing on a system attribute (-1...-12)
- * so we convert atnum into a usable index 0...11 so we can
- * use it to dereference the array sysatts[] which stores
- * tuple descriptor information for system attributes.
- * ----------------
- */
- if (atnum <= FirstLowInvalidHeapAttributeNumber || atnum >= 0 )
- elog(WARN, "Cannot create index on system attribute: attribute number out of range (%d)", atnum);
- atind = (-atnum) - 1;
-
- from = (char *) (& sysatts[atind]);
-
- } else {
- /* ----------------
- * here we are indexing on a normal attribute (1...n)
- * ----------------
- */
-
- heapTupDesc = RelationGetTupleDescriptor(heapRelation);
- atind = AttrNumberGetAttrOffset(atnum);
-
- from = (char *) (heapTupDesc->attrs[ atind ]);
- }
-
+
/* ----------------
- * now that we've determined the "from", let's copy
- * the tuple desc data...
+ * for each attribute we are indexing, obtain its attribute
+ * tuple form from either the static table of system attribute
+ * tuple forms or the relation tuple descriptor
* ----------------
*/
-
- to = (char *) (indexTupDesc->attrs[ i ]);
- memcpy(to, from, ATTRIBUTE_TUPLE_SIZE);
-
- ((AttributeTupleForm) to)->attnum = i+1;
- ((AttributeTupleForm) to)->attcacheoff = -1;
-
- ((AttributeTupleForm) to)->attnotnull = false;
- ((AttributeTupleForm) to)->atthasdef = false;
-
- /* if the keytype is defined, we need to change the tuple form's
- atttypid & attlen field to match that of the key's type */
- if (IndexKeyType != NULL) {
- HeapTuple tup;
-
- tup = SearchSysCacheTuple(TYPNAME,
- PointerGetDatum(IndexKeyType->name),
- 0,0,0);
- if(!HeapTupleIsValid(tup))
- elog(WARN, "create index: type '%s' undefined",
- IndexKeyType->name);
- ((AttributeTupleForm) to)->atttypid = tup->t_oid;
- ((AttributeTupleForm) to)->attbyval =
- ((TypeTupleForm) ((char *)tup + tup->t_hoff))->typbyval;
- if (IndexKeyType->typlen > 0)
- ((AttributeTupleForm) to)->attlen = IndexKeyType->typlen;
- else ((AttributeTupleForm) to)->attlen =
- ((TypeTupleForm) ((char *)tup + tup->t_hoff))->typlen;
+ for (i = 0; i < numatts; i += 1)
+ {
+
+ /* ----------------
+ * get the attribute number and make sure it's valid
+ * ----------------
+ */
+ atnum = attNums[i];
+ if (atnum > natts)
+ elog(WARN, "Cannot create index: attribute %d does not exist",
+ atnum);
+ if (attributeList)
+ {
+ IndexKey = (IndexElem *) lfirst(attributeList);
+ attributeList = lnext(attributeList);
+ IndexKeyType = IndexKey->tname;
+ }
+ else
+ {
+ IndexKeyType = NULL;
+ }
+
+ indexTupDesc->attrs[i] = (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+
+ /* ----------------
+ * determine which tuple descriptor to copy
+ * ----------------
+ */
+ if (!AttrNumberIsForUserDefinedAttr(atnum))
+ {
+
+ /* ----------------
+ * here we are indexing on a system attribute (-1...-12)
+ * so we convert atnum into a usable index 0...11 so we can
+ * use it to dereference the array sysatts[] which stores
+ * tuple descriptor information for system attributes.
+ * ----------------
+ */
+ if (atnum <= FirstLowInvalidHeapAttributeNumber || atnum >= 0)
+ elog(WARN, "Cannot create index on system attribute: attribute number out of range (%d)", atnum);
+ atind = (-atnum) - 1;
+
+ from = (char *) (&sysatts[atind]);
+
+ }
+ else
+ {
+ /* ----------------
+ * here we are indexing on a normal attribute (1...n)
+ * ----------------
+ */
+
+ heapTupDesc = RelationGetTupleDescriptor(heapRelation);
+ atind = AttrNumberGetAttrOffset(atnum);
+
+ from = (char *) (heapTupDesc->attrs[atind]);
+ }
+
+ /* ----------------
+ * now that we've determined the "from", let's copy
+ * the tuple desc data...
+ * ----------------
+ */
+
+ to = (char *) (indexTupDesc->attrs[i]);
+ memcpy(to, from, ATTRIBUTE_TUPLE_SIZE);
+
+ ((AttributeTupleForm) to)->attnum = i + 1;
+ ((AttributeTupleForm) to)->attcacheoff = -1;
+
+ ((AttributeTupleForm) to)->attnotnull = false;
+ ((AttributeTupleForm) to)->atthasdef = false;
+
+ /*
+ * if the keytype is defined, we need to change the tuple form's
+ * atttypid & attlen field to match that of the key's type
+ */
+ if (IndexKeyType != NULL)
+ {
+ HeapTuple tup;
+
+ tup = SearchSysCacheTuple(TYPNAME,
+ PointerGetDatum(IndexKeyType->name),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(WARN, "create index: type '%s' undefined",
+ IndexKeyType->name);
+ ((AttributeTupleForm) to)->atttypid = tup->t_oid;
+ ((AttributeTupleForm) to)->attbyval =
+ ((TypeTupleForm) ((char *) tup + tup->t_hoff))->typbyval;
+ if (IndexKeyType->typlen > 0)
+ ((AttributeTupleForm) to)->attlen = IndexKeyType->typlen;
+ else
+ ((AttributeTupleForm) to)->attlen =
+ ((TypeTupleForm) ((char *) tup + tup->t_hoff))->typlen;
+ }
+
+
+ /* ----------------
+ * now we have to drop in the proper relation descriptor
+ * into the copied tuple form's attrelid and we should be
+ * all set.
+ * ----------------
+ */
+ ((AttributeTupleForm) to)->attrelid = heapoid;
}
-
- /* ----------------
- * now we have to drop in the proper relation descriptor
- * into the copied tuple form's attrelid and we should be
- * all set.
- * ----------------
- */
- ((AttributeTupleForm) to)->attrelid = heapoid;
- }
-
- return indexTupDesc;
+ return indexTupDesc;
}
/* ----------------------------------------------------------------
* AccessMethodObjectIdGetAccessMethodTupleForm --
- * Returns the formated access method tuple given its object identifier.
+ * Returns the formated access method tuple given its object identifier.
*
* XXX ADD INDEXING
*
* Note:
- * Assumes object identifier is valid.
+ * Assumes object identifier is valid.
* ----------------------------------------------------------------
*/
Form_pg_am
AccessMethodObjectIdGetAccessMethodTupleForm(Oid accessMethodObjectId)
{
- Relation pg_am_desc;
- HeapScanDesc pg_am_scan;
- HeapTuple pg_am_tuple;
- ScanKeyData key;
- Form_pg_am form;
-
- /* ----------------
- * form a scan key for the pg_am relation
- * ----------------
- */
- ScanKeyEntryInitialize(&key, 0, ObjectIdAttributeNumber,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(accessMethodObjectId));
-
- /* ----------------
- * fetch the desired access method tuple
- * ----------------
- */
- pg_am_desc = heap_openr(AccessMethodRelationName);
- pg_am_scan = heap_beginscan(pg_am_desc, 0, NowTimeQual, 1, &key);
-
- pg_am_tuple = heap_getnext(pg_am_scan, 0, (Buffer *)NULL);
-
- /* ----------------
- * return NULL if not found
- * ----------------
- */
- if (! HeapTupleIsValid(pg_am_tuple)) {
+ Relation pg_am_desc;
+ HeapScanDesc pg_am_scan;
+ HeapTuple pg_am_tuple;
+ ScanKeyData key;
+ Form_pg_am form;
+
+ /* ----------------
+ * form a scan key for the pg_am relation
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&key, 0, ObjectIdAttributeNumber,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(accessMethodObjectId));
+
+ /* ----------------
+ * fetch the desired access method tuple
+ * ----------------
+ */
+ pg_am_desc = heap_openr(AccessMethodRelationName);
+ pg_am_scan = heap_beginscan(pg_am_desc, 0, NowTimeQual, 1, &key);
+
+ pg_am_tuple = heap_getnext(pg_am_scan, 0, (Buffer *) NULL);
+
+ /* ----------------
+ * return NULL if not found
+ * ----------------
+ */
+ if (!HeapTupleIsValid(pg_am_tuple))
+ {
+ heap_endscan(pg_am_scan);
+ heap_close(pg_am_desc);
+ return (NULL);
+ }
+
+ /* ----------------
+ * if found am tuple, then copy the form and return the copy
+ * ----------------
+ */
+ form = (Form_pg_am) palloc(sizeof *form);
+ memcpy(form, GETSTRUCT(pg_am_tuple), sizeof *form);
+
heap_endscan(pg_am_scan);
heap_close(pg_am_desc);
- return (NULL);
- }
-
- /* ----------------
- * if found am tuple, then copy the form and return the copy
- * ----------------
- */
- form = (Form_pg_am)palloc(sizeof *form);
- memcpy(form, GETSTRUCT(pg_am_tuple), sizeof *form);
-
- heap_endscan(pg_am_scan);
- heap_close(pg_am_desc);
-
- return (form);
+
+ return (form);
}
/* ----------------------------------------------------------------
- * ConstructIndexReldesc
+ * ConstructIndexReldesc
* ----------------------------------------------------------------
*/
static void
ConstructIndexReldesc(Relation indexRelation, Oid amoid)
{
- extern GlobalMemory CacheCxt;
- MemoryContext oldcxt;
-
- /* ----------------
- * here we make certain to allocate the access method
- * tuple within the cache context lest it vanish when the
- * context changes
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- indexRelation->rd_am =
- AccessMethodObjectIdGetAccessMethodTupleForm(amoid);
-
- MemoryContextSwitchTo(oldcxt);
-
- /* ----------------
- * XXX missing the initialization of some other fields
- * ----------------
- */
-
- indexRelation->rd_rel->relowner = GetUserId();
-
- indexRelation->rd_rel->relam = amoid;
- indexRelation->rd_rel->reltuples = 1; /* XXX */
- indexRelation->rd_rel->relexpires = 0; /* XXX */
- indexRelation->rd_rel->relpreserved = 0; /* XXX */
- indexRelation->rd_rel->relkind = RELKIND_INDEX;
- indexRelation->rd_rel->relarch = 'n'; /* XXX */
+ extern GlobalMemory CacheCxt;
+ MemoryContext oldcxt;
+
+ /* ----------------
+ * here we make certain to allocate the access method
+ * tuple within the cache context lest it vanish when the
+ * context changes
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ indexRelation->rd_am =
+ AccessMethodObjectIdGetAccessMethodTupleForm(amoid);
+
+ MemoryContextSwitchTo(oldcxt);
+
+ /* ----------------
+ * XXX missing the initialization of some other fields
+ * ----------------
+ */
+
+ indexRelation->rd_rel->relowner = GetUserId();
+
+ indexRelation->rd_rel->relam = amoid;
+ indexRelation->rd_rel->reltuples = 1; /* XXX */
+ indexRelation->rd_rel->relexpires = 0; /* XXX */
+ indexRelation->rd_rel->relpreserved = 0; /* XXX */
+ indexRelation->rd_rel->relkind = RELKIND_INDEX;
+ indexRelation->rd_rel->relarch = 'n'; /* XXX */
}
/* ----------------------------------------------------------------
- * UpdateRelationRelation
+ * UpdateRelationRelation
* ----------------------------------------------------------------
*/
-static Oid
+static Oid
UpdateRelationRelation(Relation indexRelation)
{
- Relation pg_class;
- HeapTuple tuple;
- Oid tupleOid;
- Relation idescs[Num_pg_class_indices];
-
- pg_class = heap_openr(RelationRelationName);
-
- /* XXX Natts_pg_class_fixed is a hack - see pg_class.h */
- tuple = heap_addheader(Natts_pg_class_fixed,
- sizeof(*indexRelation->rd_rel),
- (char *) indexRelation->rd_rel);
-
- /* ----------------
- * the new tuple must have the same oid as the relcache entry for the
- * index. sure would be embarassing to do this sort of thing in polite
- * company.
- * ----------------
- */
- tuple->t_oid = indexRelation->rd_id;
- heap_insert(pg_class, tuple);
-
- /*
- * During normal processing, we need to make sure that the system
- * catalog indices are correct. Bootstrap (initdb) time doesn't
- * require this, because we make sure that the indices are correct
- * just before exiting.
- */
-
- if (!IsBootstrapProcessingMode()) {
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, tuple);
- CatalogCloseIndices(Num_pg_class_indices, idescs);
- }
-
- tupleOid = tuple->t_oid;
- pfree(tuple);
- heap_close(pg_class);
-
- return(tupleOid);
+ Relation pg_class;
+ HeapTuple tuple;
+ Oid tupleOid;
+ Relation idescs[Num_pg_class_indices];
+
+ pg_class = heap_openr(RelationRelationName);
+
+ /* XXX Natts_pg_class_fixed is a hack - see pg_class.h */
+ tuple = heap_addheader(Natts_pg_class_fixed,
+ sizeof(*indexRelation->rd_rel),
+ (char *) indexRelation->rd_rel);
+
+ /* ----------------
+ * the new tuple must have the same oid as the relcache entry for the
+ * index. sure would be embarassing to do this sort of thing in polite
+ * company.
+ * ----------------
+ */
+ tuple->t_oid = indexRelation->rd_id;
+ heap_insert(pg_class, tuple);
+
+ /*
+ * During normal processing, we need to make sure that the system
+ * catalog indices are correct. Bootstrap (initdb) time doesn't
+ * require this, because we make sure that the indices are correct
+ * just before exiting.
+ */
+
+ if (!IsBootstrapProcessingMode())
+ {
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, tuple);
+ CatalogCloseIndices(Num_pg_class_indices, idescs);
+ }
+
+ tupleOid = tuple->t_oid;
+ pfree(tuple);
+ heap_close(pg_class);
+
+ return (tupleOid);
}
/* ----------------------------------------------------------------
- * InitializeAttributeOids
+ * InitializeAttributeOids
* ----------------------------------------------------------------
*/
static void
InitializeAttributeOids(Relation indexRelation,
- int numatts,
- Oid indexoid)
+ int numatts,
+ Oid indexoid)
{
- TupleDesc tupleDescriptor;
- int i;
-
- tupleDescriptor = RelationGetTupleDescriptor(indexRelation);
-
- for (i = 0; i < numatts; i += 1)
- tupleDescriptor->attrs[i]->attrelid = indexoid;
+ TupleDesc tupleDescriptor;
+ int i;
+
+ tupleDescriptor = RelationGetTupleDescriptor(indexRelation);
+
+ for (i = 0; i < numatts; i += 1)
+ tupleDescriptor->attrs[i]->attrelid = indexoid;
}
/* ----------------------------------------------------------------
- * AppendAttributeTuples
+ * AppendAttributeTuples
*
- * XXX For now, only change the ATTNUM attribute value
+ * XXX For now, only change the ATTNUM attribute value
* ----------------------------------------------------------------
*/
static void
AppendAttributeTuples(Relation indexRelation, int numatts)
{
- Relation pg_attribute;
- HeapTuple tuple;
- HeapTuple newtuple;
- bool hasind;
- Relation idescs[Num_pg_attr_indices];
-
- Datum value[ Natts_pg_attribute ];
- char nullv[ Natts_pg_attribute ];
- char replace[ Natts_pg_attribute ];
-
- TupleDesc indexTupDesc;
- int i;
-
- /* ----------------
- * open the attribute relation
- * XXX ADD INDEXING
- * ----------------
- */
- pg_attribute = heap_openr(AttributeRelationName);
-
- /* ----------------
- * initialize null[], replace[] and value[]
- * ----------------
- */
- memset(nullv, ' ', Natts_pg_attribute);
- memset(replace, ' ', Natts_pg_attribute);
-
- /* ----------------
- * create the first attribute tuple.
- * XXX For now, only change the ATTNUM attribute value
- * ----------------
- */
- replace[ Anum_pg_attribute_attnum - 1 ] = 'r';
- replace[ Anum_pg_attribute_attcacheoff - 1 ] = 'r';
-
- value[ Anum_pg_attribute_attnum - 1 ] = Int16GetDatum(1);
- value[ Anum_pg_attribute_attcacheoff - 1 ] = Int32GetDatum(-1);
-
- tuple = heap_addheader(Natts_pg_attribute,
- sizeof *(indexRelation->rd_att->attrs[0]),
- (char *)(indexRelation->rd_att->attrs[0]));
-
- hasind = false;
- if (!IsBootstrapProcessingMode() && pg_attribute->rd_rel->relhasindex) {
- hasind = true;
- CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
- }
-
- /* ----------------
- * insert the first attribute tuple.
- * ----------------
- */
- tuple = heap_modifytuple(tuple,
- InvalidBuffer,
- pg_attribute,
- value,
- nullv,
- replace);
-
- heap_insert(pg_attribute, tuple);
- if (hasind)
- CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, tuple);
-
- /* ----------------
- * now we use the information in the index tuple
- * descriptor to form the remaining attribute tuples.
- * ----------------
- */
- indexTupDesc = RelationGetTupleDescriptor(indexRelation);
-
- for (i = 1; i < numatts; i += 1) {
+ Relation pg_attribute;
+ HeapTuple tuple;
+ HeapTuple newtuple;
+ bool hasind;
+ Relation idescs[Num_pg_attr_indices];
+
+ Datum value[Natts_pg_attribute];
+ char nullv[Natts_pg_attribute];
+ char replace[Natts_pg_attribute];
+
+ TupleDesc indexTupDesc;
+ int i;
+
/* ----------------
- * process the remaining attributes...
+ * open the attribute relation
+ * XXX ADD INDEXING
* ----------------
*/
- memmove(GETSTRUCT(tuple),
- (char *)indexTupDesc->attrs[i],
- sizeof (FormData_pg_attribute));
-
- value[ Anum_pg_attribute_attnum - 1 ] = Int16GetDatum(i + 1);
-
- newtuple = heap_modifytuple(tuple,
- InvalidBuffer,
- pg_attribute,
- value,
- nullv,
- replace);
-
- heap_insert(pg_attribute, newtuple);
+ pg_attribute = heap_openr(AttributeRelationName);
+
+ /* ----------------
+ * initialize null[], replace[] and value[]
+ * ----------------
+ */
+ memset(nullv, ' ', Natts_pg_attribute);
+ memset(replace, ' ', Natts_pg_attribute);
+
+ /* ----------------
+ * create the first attribute tuple.
+ * XXX For now, only change the ATTNUM attribute value
+ * ----------------
+ */
+ replace[Anum_pg_attribute_attnum - 1] = 'r';
+ replace[Anum_pg_attribute_attcacheoff - 1] = 'r';
+
+ value[Anum_pg_attribute_attnum - 1] = Int16GetDatum(1);
+ value[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1);
+
+ tuple = heap_addheader(Natts_pg_attribute,
+ sizeof *(indexRelation->rd_att->attrs[0]),
+ (char *) (indexRelation->rd_att->attrs[0]));
+
+ hasind = false;
+ if (!IsBootstrapProcessingMode() && pg_attribute->rd_rel->relhasindex)
+ {
+ hasind = true;
+ CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
+ }
+
+ /* ----------------
+ * insert the first attribute tuple.
+ * ----------------
+ */
+ tuple = heap_modifytuple(tuple,
+ InvalidBuffer,
+ pg_attribute,
+ value,
+ nullv,
+ replace);
+
+ heap_insert(pg_attribute, tuple);
if (hasind)
- CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, newtuple);
-
+ CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, tuple);
+
+ /* ----------------
+ * now we use the information in the index tuple
+ * descriptor to form the remaining attribute tuples.
+ * ----------------
+ */
+ indexTupDesc = RelationGetTupleDescriptor(indexRelation);
+
+ for (i = 1; i < numatts; i += 1)
+ {
+ /* ----------------
+ * process the remaining attributes...
+ * ----------------
+ */
+ memmove(GETSTRUCT(tuple),
+ (char *) indexTupDesc->attrs[i],
+ sizeof(FormData_pg_attribute));
+
+ value[Anum_pg_attribute_attnum - 1] = Int16GetDatum(i + 1);
+
+ newtuple = heap_modifytuple(tuple,
+ InvalidBuffer,
+ pg_attribute,
+ value,
+ nullv,
+ replace);
+
+ heap_insert(pg_attribute, newtuple);
+ if (hasind)
+ CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, newtuple);
+
+ /* ----------------
+ * ModifyHeapTuple returns a new copy of a tuple
+ * so we free the original and use the copy..
+ * ----------------
+ */
+ pfree(tuple);
+ tuple = newtuple;
+ }
+
/* ----------------
- * ModifyHeapTuple returns a new copy of a tuple
- * so we free the original and use the copy..
+ * close the attribute relation and free the tuple
* ----------------
*/
+ heap_close(pg_attribute);
+
+ if (hasind)
+ CatalogCloseIndices(Num_pg_attr_indices, idescs);
+
pfree(tuple);
- tuple = newtuple;
- }
-
- /* ----------------
- * close the attribute relation and free the tuple
- * ----------------
- */
- heap_close(pg_attribute);
-
- if (hasind)
- CatalogCloseIndices(Num_pg_attr_indices, idescs);
-
- pfree(tuple);
}
/* ----------------------------------------------------------------
- * UpdateIndexRelation
+ * UpdateIndexRelation
* ----------------------------------------------------------------
*/
static void
UpdateIndexRelation(Oid indexoid,
- Oid heapoid,
- FuncIndexInfo *funcInfo,
- int natts,
- AttrNumber attNums[],
- Oid classOids[],
- Node *predicate,
- List *attributeList,
- bool islossy,
- bool unique)
+ Oid heapoid,
+ FuncIndexInfo * funcInfo,
+ int natts,
+ AttrNumber attNums[],
+ Oid classOids[],
+ Node * predicate,
+ List * attributeList,
+ bool islossy,
+ bool unique)
{
- IndexTupleForm indexForm;
- IndexElem *IndexKey;
- char *predString;
- text *predText;
- int predLen, itupLen;
- Relation pg_index;
- HeapTuple tuple;
- int i;
-
- /* ----------------
- * allocate an IndexTupleForm big enough to hold the
- * index-predicate (if any) in string form
- * ----------------
- */
- if (predicate != NULL) {
- predString = nodeToString(predicate);
- predText = (text *)fmgr(F_TEXTIN, predString);
- pfree(predString);
- } else {
- predText = (text *)fmgr(F_TEXTIN, "");
- }
- predLen = VARSIZE(predText);
- itupLen = predLen + sizeof(FormData_pg_index);
- indexForm = (IndexTupleForm) palloc(itupLen);
-
- memmove((char *)& indexForm->indpred, (char *)predText, predLen);
-
- /* ----------------
- * store the oid information into the index tuple form
- * ----------------
- */
- indexForm->indrelid = heapoid;
- indexForm->indexrelid = indexoid;
- indexForm->indproc = (PointerIsValid(funcInfo)) ?
- FIgetProcOid(funcInfo) : InvalidOid;
- indexForm->indislossy = islossy;
- indexForm->indisunique = unique;
-
- indexForm->indhaskeytype = 0;
- while (attributeList != NIL )
- {
- IndexKey = (IndexElem*) lfirst(attributeList);
- if ( IndexKey->tname != NULL )
+ IndexTupleForm indexForm;
+ IndexElem *IndexKey;
+ char *predString;
+ text *predText;
+ int predLen,
+ itupLen;
+ Relation pg_index;
+ HeapTuple tuple;
+ int i;
+
+ /* ----------------
+ * allocate an IndexTupleForm big enough to hold the
+ * index-predicate (if any) in string form
+ * ----------------
+ */
+ if (predicate != NULL)
{
- indexForm->indhaskeytype = 1;
- break;
- }
- attributeList = lnext(attributeList);
- }
-
- memset((char *)& indexForm->indkey[0], 0, sizeof indexForm->indkey);
- memset((char *)& indexForm->indclass[0], 0, sizeof indexForm->indclass);
-
- /* ----------------
- * copy index key and op class information
- * ----------------
- */
- for (i = 0; i < natts; i += 1) {
- indexForm->indkey[i] = attNums[i];
- indexForm->indclass[i] = classOids[i];
- }
- /*
- * If we have a functional index, add all attribute arguments
- */
- if (PointerIsValid(funcInfo))
+ predString = nodeToString(predicate);
+ predText = (text *) fmgr(F_TEXTIN, predString);
+ pfree(predString);
+ }
+ else
{
- for (i=1; i < FIgetnArgs(funcInfo); i++)
- indexForm->indkey[i] = attNums[i];
+ predText = (text *) fmgr(F_TEXTIN, "");
}
-
- indexForm->indisclustered = '\0'; /* XXX constant */
- indexForm->indisarchived = '\0'; /* XXX constant */
-
- /* ----------------
- * open the system catalog index relation
- * ----------------
- */
- pg_index = heap_openr(IndexRelationName);
-
- /* ----------------
- * form a tuple to insert into pg_index
- * ----------------
- */
- tuple = heap_addheader(Natts_pg_index,
- itupLen,
- (char *)indexForm);
-
- /* ----------------
- * insert the tuple into the pg_index
- * XXX ADD INDEX TUPLES TOO
- * ----------------
- */
- heap_insert(pg_index, tuple);
-
- /* ----------------
- * close the relation and free the tuple
- * ----------------
- */
- heap_close(pg_index);
- pfree(predText);
- pfree(indexForm);
- pfree(tuple);
+ predLen = VARSIZE(predText);
+ itupLen = predLen + sizeof(FormData_pg_index);
+ indexForm = (IndexTupleForm) palloc(itupLen);
+
+ memmove((char *) &indexForm->indpred, (char *) predText, predLen);
+
+ /* ----------------
+ * store the oid information into the index tuple form
+ * ----------------
+ */
+ indexForm->indrelid = heapoid;
+ indexForm->indexrelid = indexoid;
+ indexForm->indproc = (PointerIsValid(funcInfo)) ?
+ FIgetProcOid(funcInfo) : InvalidOid;
+ indexForm->indislossy = islossy;
+ indexForm->indisunique = unique;
+
+ indexForm->indhaskeytype = 0;
+ while (attributeList != NIL)
+ {
+ IndexKey = (IndexElem *) lfirst(attributeList);
+ if (IndexKey->tname != NULL)
+ {
+ indexForm->indhaskeytype = 1;
+ break;
+ }
+ attributeList = lnext(attributeList);
+ }
+
+ memset((char *) &indexForm->indkey[0], 0, sizeof indexForm->indkey);
+ memset((char *) &indexForm->indclass[0], 0, sizeof indexForm->indclass);
+
+ /* ----------------
+ * copy index key and op class information
+ * ----------------
+ */
+ for (i = 0; i < natts; i += 1)
+ {
+ indexForm->indkey[i] = attNums[i];
+ indexForm->indclass[i] = classOids[i];
+ }
+
+ /*
+ * If we have a functional index, add all attribute arguments
+ */
+ if (PointerIsValid(funcInfo))
+ {
+ for (i = 1; i < FIgetnArgs(funcInfo); i++)
+ indexForm->indkey[i] = attNums[i];
+ }
+
+ indexForm->indisclustered = '\0'; /* XXX constant */
+ indexForm->indisarchived = '\0'; /* XXX constant */
+
+ /* ----------------
+ * open the system catalog index relation
+ * ----------------
+ */
+ pg_index = heap_openr(IndexRelationName);
+
+ /* ----------------
+ * form a tuple to insert into pg_index
+ * ----------------
+ */
+ tuple = heap_addheader(Natts_pg_index,
+ itupLen,
+ (char *) indexForm);
+
+ /* ----------------
+ * insert the tuple into the pg_index
+ * XXX ADD INDEX TUPLES TOO
+ * ----------------
+ */
+ heap_insert(pg_index, tuple);
+
+ /* ----------------
+ * close the relation and free the tuple
+ * ----------------
+ */
+ heap_close(pg_index);
+ pfree(predText);
+ pfree(indexForm);
+ pfree(tuple);
}
/* ----------------------------------------------------------------
- * UpdateIndexPredicate
+ * UpdateIndexPredicate
* ----------------------------------------------------------------
*/
void
-UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
+UpdateIndexPredicate(Oid indexoid, Node * oldPred, Node * predicate)
{
- Node *newPred;
- char *predString;
- text *predText;
- Relation pg_index;
- HeapTuple tuple;
- HeapTuple newtup;
- ScanKeyData entry;
- HeapScanDesc scan;
- Buffer buffer;
- int i;
- Datum values[Natts_pg_index];
- char nulls[Natts_pg_index];
- char replace[Natts_pg_index];
-
- /*
- * Construct newPred as a CNF expression equivalent to the OR of the
- * original partial-index predicate ("oldPred") and the extension
- * predicate ("predicate").
- *
- * This should really try to process the result to change things like
- * "a>2 OR a>1" to simply "a>1", but for now all it does is make sure
- * that if the extension predicate is NULL (i.e., it is being extended
- * to be a complete index), then newPred will be NULL - in effect,
- * changing "a>2 OR TRUE" to "TRUE". --Nels, Jan '93
- */
- newPred = NULL;
- if (predicate != NULL) {
- newPred =
- (Node*)make_orclause(lcons(make_andclause((List*)predicate),
- lcons(make_andclause((List*)oldPred),
- NIL)));
- newPred = (Node*)cnfify((Expr*)newPred, true);
- }
-
- /* translate the index-predicate to string form */
- if (newPred != NULL) {
- predString = nodeToString(newPred);
- predText = (text *)fmgr(F_TEXTIN, predString);
- pfree(predString);
- } else {
- predText = (text *)fmgr(F_TEXTIN, "");
- }
-
- /* open the index system catalog relation */
- pg_index = heap_openr(IndexRelationName);
-
- ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_index_indexrelid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(indexoid));
-
- scan = heap_beginscan(pg_index, 0, NowTimeQual, 1, &entry);
- tuple = heap_getnext(scan, 0, &buffer);
- heap_endscan(scan);
-
- for (i = 0; i < Natts_pg_index; i++) {
- nulls[i] = heap_attisnull(tuple, i+1) ? 'n' : ' ';
- replace[i] = ' ';
- values[i] = (Datum) NULL;
- }
-
- replace[Anum_pg_index_indpred - 1] = 'r';
- values[Anum_pg_index_indpred - 1] = (Datum) predText;
-
- newtup = heap_modifytuple(tuple, buffer, pg_index, values, nulls, replace);
-
- heap_replace(pg_index, &(newtup->t_ctid), newtup);
-
- heap_close(pg_index);
- pfree(predText);
+ Node *newPred;
+ char *predString;
+ text *predText;
+ Relation pg_index;
+ HeapTuple tuple;
+ HeapTuple newtup;
+ ScanKeyData entry;
+ HeapScanDesc scan;
+ Buffer buffer;
+ int i;
+ Datum values[Natts_pg_index];
+ char nulls[Natts_pg_index];
+ char replace[Natts_pg_index];
+
+ /*
+ * Construct newPred as a CNF expression equivalent to the OR of the
+ * original partial-index predicate ("oldPred") and the extension
+ * predicate ("predicate").
+ *
+ * This should really try to process the result to change things like
+ * "a>2 OR a>1" to simply "a>1", but for now all it does is make sure
+ * that if the extension predicate is NULL (i.e., it is being extended
+ * to be a complete index), then newPred will be NULL - in effect,
+ * changing "a>2 OR TRUE" to "TRUE". --Nels, Jan '93
+ */
+ newPred = NULL;
+ if (predicate != NULL)
+ {
+ newPred =
+ (Node *) make_orclause(lcons(make_andclause((List *) predicate),
+ lcons(make_andclause((List *) oldPred),
+ NIL)));
+ newPred = (Node *) cnfify((Expr *) newPred, true);
+ }
+
+ /* translate the index-predicate to string form */
+ if (newPred != NULL)
+ {
+ predString = nodeToString(newPred);
+ predText = (text *) fmgr(F_TEXTIN, predString);
+ pfree(predString);
+ }
+ else
+ {
+ predText = (text *) fmgr(F_TEXTIN, "");
+ }
+
+ /* open the index system catalog relation */
+ pg_index = heap_openr(IndexRelationName);
+
+ ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_index_indexrelid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(indexoid));
+
+ scan = heap_beginscan(pg_index, 0, NowTimeQual, 1, &entry);
+ tuple = heap_getnext(scan, 0, &buffer);
+ heap_endscan(scan);
+
+ for (i = 0; i < Natts_pg_index; i++)
+ {
+ nulls[i] = heap_attisnull(tuple, i + 1) ? 'n' : ' ';
+ replace[i] = ' ';
+ values[i] = (Datum) NULL;
+ }
+
+ replace[Anum_pg_index_indpred - 1] = 'r';
+ values[Anum_pg_index_indpred - 1] = (Datum) predText;
+
+ newtup = heap_modifytuple(tuple, buffer, pg_index, values, nulls, replace);
+
+ heap_replace(pg_index, &(newtup->t_ctid), newtup);
+
+ heap_close(pg_index);
+ pfree(predText);
}
/* ----------------------------------------------------------------
- * InitIndexStrategy
+ * InitIndexStrategy
* ----------------------------------------------------------------
*/
void
InitIndexStrategy(int numatts,
- Relation indexRelation,
- Oid accessMethodObjectId)
+ Relation indexRelation,
+ Oid accessMethodObjectId)
{
- IndexStrategy strategy;
- RegProcedure *support;
- uint16 amstrategies;
- uint16 amsupport;
- Oid attrelid;
- Size strsize;
- extern GlobalMemory CacheCxt;
-
- /* ----------------
- * get information from the index relation descriptor
- * ----------------
- */
- attrelid = indexRelation->rd_att->attrs[0]->attrelid;
- amstrategies = indexRelation->rd_am->amstrategies;
- amsupport = indexRelation->rd_am->amsupport;
-
- /* ----------------
- * get the size of the strategy
- * ----------------
- */
- strsize = AttributeNumberGetIndexStrategySize(numatts, amstrategies);
-
- /* ----------------
- * allocate the new index strategy structure
- *
- * the index strategy has to be allocated in the same
- * context as the relation descriptor cache or else
- * it will be lost at the end of the transaction.
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- strategy = (IndexStrategy)
- MemoryContextAlloc((MemoryContext)CacheCxt, strsize);
-
- if (amsupport > 0) {
- strsize = numatts * (amsupport * sizeof(RegProcedure));
- support = (RegProcedure *) MemoryContextAlloc((MemoryContext)CacheCxt,
- strsize);
- } else {
- support = (RegProcedure *) NULL;
- }
-
- /* ----------------
- * fill in the index strategy structure with information
- * from the catalogs. Note: we use heap override mode
- * in order to be allowed to see the correct information in the
- * catalogs, even though our transaction has not yet committed.
- * ----------------
- */
- setheapoverride(1);
-
- IndexSupportInitialize(strategy, support,
- attrelid, accessMethodObjectId,
- amstrategies, amsupport, numatts);
-
- setheapoverride(0);
-
- /* ----------------
- * store the strategy information in the index reldesc
- * ----------------
- */
- RelationSetIndexSupport(indexRelation, strategy, support);
+ IndexStrategy strategy;
+ RegProcedure *support;
+ uint16 amstrategies;
+ uint16 amsupport;
+ Oid attrelid;
+ Size strsize;
+ extern GlobalMemory CacheCxt;
+
+ /* ----------------
+ * get information from the index relation descriptor
+ * ----------------
+ */
+ attrelid = indexRelation->rd_att->attrs[0]->attrelid;
+ amstrategies = indexRelation->rd_am->amstrategies;
+ amsupport = indexRelation->rd_am->amsupport;
+
+ /* ----------------
+ * get the size of the strategy
+ * ----------------
+ */
+ strsize = AttributeNumberGetIndexStrategySize(numatts, amstrategies);
+
+ /* ----------------
+ * allocate the new index strategy structure
+ *
+ * the index strategy has to be allocated in the same
+ * context as the relation descriptor cache or else
+ * it will be lost at the end of the transaction.
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ strategy = (IndexStrategy)
+ MemoryContextAlloc((MemoryContext) CacheCxt, strsize);
+
+ if (amsupport > 0)
+ {
+ strsize = numatts * (amsupport * sizeof(RegProcedure));
+ support = (RegProcedure *) MemoryContextAlloc((MemoryContext) CacheCxt,
+ strsize);
+ }
+ else
+ {
+ support = (RegProcedure *) NULL;
+ }
+
+ /* ----------------
+ * fill in the index strategy structure with information
+ * from the catalogs. Note: we use heap override mode
+ * in order to be allowed to see the correct information in the
+ * catalogs, even though our transaction has not yet committed.
+ * ----------------
+ */
+ setheapoverride(1);
+
+ IndexSupportInitialize(strategy, support,
+ attrelid, accessMethodObjectId,
+ amstrategies, amsupport, numatts);
+
+ setheapoverride(0);
+
+ /* ----------------
+ * store the strategy information in the index reldesc
+ * ----------------
+ */
+ RelationSetIndexSupport(indexRelation, strategy, support);
}
/* ----------------------------------------------------------------
- * index_create
+ * index_create
* ----------------------------------------------------------------
*/
void
index_create(char *heapRelationName,
- char *indexRelationName,
- FuncIndexInfo *funcInfo,
- List *attributeList,
- Oid accessMethodObjectId,
- int numatts,
- AttrNumber attNums[],
- Oid classObjectId[],
- uint16 parameterCount,
- Datum *parameter,
- Node *predicate,
- bool islossy,
- bool unique)
+ char *indexRelationName,
+ FuncIndexInfo * funcInfo,
+ List * attributeList,
+ Oid accessMethodObjectId,
+ int numatts,
+ AttrNumber attNums[],
+ Oid classObjectId[],
+ uint16 parameterCount,
+ Datum * parameter,
+ Node * predicate,
+ bool islossy,
+ bool unique)
{
- Relation heapRelation;
- Relation indexRelation;
- TupleDesc indexTupDesc;
- Oid heapoid;
- Oid indexoid;
- PredInfo *predInfo;
-
- /* ----------------
- * check parameters
- * ----------------
- */
- if (numatts < 1)
- elog(WARN, "must index at least one attribute");
-
- /* ----------------
- * get heap relation oid and open the heap relation
- * XXX ADD INDEXING
- * ----------------
- */
- heapoid = GetHeapRelationOid(heapRelationName, indexRelationName);
-
- heapRelation = heap_open(heapoid);
-
- /* ----------------
- * write lock heap to guarantee exclusive access
- * ----------------
- */
-
- RelationSetLockForWrite(heapRelation);
-
- /* ----------------
- * construct new tuple descriptor
- * ----------------
- */
- if (PointerIsValid(funcInfo))
- indexTupDesc = BuildFuncTupleDesc(funcInfo);
- else
- indexTupDesc = ConstructTupleDescriptor(heapoid,
- heapRelation,
- attributeList,
- numatts,
- attNums);
-
- /* ----------------
- * create the index relation
- * ----------------
- */
- indexRelation = heap_creatr(indexRelationName,
- DEFAULT_SMGR,
- indexTupDesc);
-
- /* ----------------
- * construct the index relation descriptor
- *
- * XXX should have a proper way to create cataloged relations
- * ----------------
- */
- ConstructIndexReldesc(indexRelation, accessMethodObjectId);
-
- /* ----------------
- * add index to catalogs
- * (append RELATION tuple)
- * ----------------
- */
- indexoid = UpdateRelationRelation(indexRelation);
-
- /* ----------------
- * Now get the index procedure (only relevant for functional indices).
- * ----------------
- */
-
- if (PointerIsValid(funcInfo))
+ Relation heapRelation;
+ Relation indexRelation;
+ TupleDesc indexTupDesc;
+ Oid heapoid;
+ Oid indexoid;
+ PredInfo *predInfo;
+
+ /* ----------------
+ * check parameters
+ * ----------------
+ */
+ if (numatts < 1)
+ elog(WARN, "must index at least one attribute");
+
+ /* ----------------
+ * get heap relation oid and open the heap relation
+ * XXX ADD INDEXING
+ * ----------------
+ */
+ heapoid = GetHeapRelationOid(heapRelationName, indexRelationName);
+
+ heapRelation = heap_open(heapoid);
+
+ /* ----------------
+ * write lock heap to guarantee exclusive access
+ * ----------------
+ */
+
+ RelationSetLockForWrite(heapRelation);
+
+ /* ----------------
+ * construct new tuple descriptor
+ * ----------------
+ */
+ if (PointerIsValid(funcInfo))
+ indexTupDesc = BuildFuncTupleDesc(funcInfo);
+ else
+ indexTupDesc = ConstructTupleDescriptor(heapoid,
+ heapRelation,
+ attributeList,
+ numatts,
+ attNums);
+
+ /* ----------------
+ * create the index relation
+ * ----------------
+ */
+ indexRelation = heap_creatr(indexRelationName,
+ DEFAULT_SMGR,
+ indexTupDesc);
+
+ /* ----------------
+ * construct the index relation descriptor
+ *
+ * XXX should have a proper way to create cataloged relations
+ * ----------------
+ */
+ ConstructIndexReldesc(indexRelation, accessMethodObjectId);
+
+ /* ----------------
+ * add index to catalogs
+ * (append RELATION tuple)
+ * ----------------
+ */
+ indexoid = UpdateRelationRelation(indexRelation);
+
+ /* ----------------
+ * Now get the index procedure (only relevant for functional indices).
+ * ----------------
+ */
+
+ if (PointerIsValid(funcInfo))
{
- HeapTuple proc_tup;
-
- proc_tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(FIgetname(funcInfo)),
- Int32GetDatum(FIgetnArgs(funcInfo)),
- PointerGetDatum(FIgetArglist(funcInfo)),
- 0);
-
- if (!HeapTupleIsValid(proc_tup)) {
- func_error("index_create", FIgetname(funcInfo),
- FIgetnArgs(funcInfo),
- FIgetArglist(funcInfo));
- }
- FIgetProcOid(funcInfo) = proc_tup->t_oid;
+ HeapTuple proc_tup;
+
+ proc_tup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(FIgetname(funcInfo)),
+ Int32GetDatum(FIgetnArgs(funcInfo)),
+ PointerGetDatum(FIgetArglist(funcInfo)),
+ 0);
+
+ if (!HeapTupleIsValid(proc_tup))
+ {
+ func_error("index_create", FIgetname(funcInfo),
+ FIgetnArgs(funcInfo),
+ FIgetArglist(funcInfo));
+ }
+ FIgetProcOid(funcInfo) = proc_tup->t_oid;
+ }
+
+ /* ----------------
+ * now update the object id's of all the attribute
+ * tuple forms in the index relation's tuple descriptor
+ * ----------------
+ */
+ InitializeAttributeOids(indexRelation, numatts, indexoid);
+
+ /* ----------------
+ * append ATTRIBUTE tuples
+ * ----------------
+ */
+ AppendAttributeTuples(indexRelation, numatts);
+
+ /* ----------------
+ * update pg_index
+ * (append INDEX tuple)
+ *
+ * Note that this stows away a representation of "predicate".
+ * (Or, could define a rule to maintain the predicate) --Nels, Feb '92
+ * ----------------
+ */
+ UpdateIndexRelation(indexoid, heapoid, funcInfo,
+ numatts, attNums, classObjectId, predicate,
+ attributeList, islossy, unique);
+
+ predInfo = (PredInfo *) palloc(sizeof(PredInfo));
+ predInfo->pred = predicate;
+ predInfo->oldPred = NULL;
+
+ /* ----------------
+ * initialize the index strategy
+ * ----------------
+ */
+ InitIndexStrategy(numatts, indexRelation, accessMethodObjectId);
+
+ /*
+ * If this is bootstrap (initdb) time, then we don't actually fill in
+ * the index yet. We'll be creating more indices and classes later,
+ * so we delay filling them in until just before we're done with
+ * bootstrapping. Otherwise, we call the routine that constructs the
+ * index. The heap and index relations are closed by index_build().
+ */
+ if (IsBootstrapProcessingMode())
+ {
+ index_register(heapRelationName, indexRelationName, numatts, attNums,
+ parameterCount, parameter, funcInfo, predInfo);
+ }
+ else
+ {
+ heapRelation = heap_openr(heapRelationName);
+ index_build(heapRelation, indexRelation, numatts, attNums,
+ parameterCount, parameter, funcInfo, predInfo);
}
-
- /* ----------------
- * now update the object id's of all the attribute
- * tuple forms in the index relation's tuple descriptor
- * ----------------
- */
- InitializeAttributeOids(indexRelation, numatts, indexoid);
-
- /* ----------------
- * append ATTRIBUTE tuples
- * ----------------
- */
- AppendAttributeTuples(indexRelation, numatts);
-
- /* ----------------
- * update pg_index
- * (append INDEX tuple)
- *
- * Note that this stows away a representation of "predicate".
- * (Or, could define a rule to maintain the predicate) --Nels, Feb '92
- * ----------------
- */
- UpdateIndexRelation(indexoid, heapoid, funcInfo,
- numatts, attNums, classObjectId, predicate,
- attributeList, islossy, unique);
-
- predInfo = (PredInfo*)palloc(sizeof(PredInfo));
- predInfo->pred = predicate;
- predInfo->oldPred = NULL;
-
- /* ----------------
- * initialize the index strategy
- * ----------------
- */
- InitIndexStrategy(numatts, indexRelation, accessMethodObjectId);
-
- /*
- * If this is bootstrap (initdb) time, then we don't actually
- * fill in the index yet. We'll be creating more indices and classes
- * later, so we delay filling them in until just before we're done
- * with bootstrapping. Otherwise, we call the routine that constructs
- * the index. The heap and index relations are closed by index_build().
- */
- if (IsBootstrapProcessingMode()) {
- index_register(heapRelationName, indexRelationName, numatts, attNums,
- parameterCount, parameter, funcInfo, predInfo);
- } else {
- heapRelation = heap_openr(heapRelationName);
- index_build(heapRelation, indexRelation, numatts, attNums,
- parameterCount, parameter, funcInfo, predInfo);
- }
}
/* ----------------------------------------------------------------
- * index_destroy
+ * index_destroy
*
- * XXX break into modules like index_create
+ * XXX break into modules like index_create
* ----------------------------------------------------------------
*/
void
index_destroy(Oid indexId)
{
- Relation indexRelation;
- Relation catalogRelation;
- HeapTuple tuple;
- HeapScanDesc scan;
- ScanKeyData entry;
-
- Assert(OidIsValid(indexId));
-
- indexRelation = index_open(indexId);
-
- /* ----------------
- * fix RELATION relation
- * ----------------
- */
- catalogRelation = heap_openr(RelationRelationName);
-
- ScanKeyEntryInitialize(&entry, 0x0, ObjectIdAttributeNumber,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(indexId));;
-
- scan = heap_beginscan(catalogRelation, 0, NowTimeQual, 1, &entry);
- tuple = heap_getnext(scan, 0, (Buffer *)NULL);
-
- AssertState(HeapTupleIsValid(tuple));
-
- heap_delete(catalogRelation, &tuple->t_ctid);
- heap_endscan(scan);
- heap_close(catalogRelation);
-
- /* ----------------
- * fix ATTRIBUTE relation
- * ----------------
- */
- catalogRelation = heap_openr(AttributeRelationName);
-
- entry.sk_attno = Anum_pg_attribute_attrelid;
-
- scan = heap_beginscan(catalogRelation, 0, NowTimeQual, 1, &entry);
-
- while (tuple = heap_getnext(scan, 0, (Buffer *)NULL),
- HeapTupleIsValid(tuple)) {
-
+ Relation indexRelation;
+ Relation catalogRelation;
+ HeapTuple tuple;
+ HeapScanDesc scan;
+ ScanKeyData entry;
+
+ Assert(OidIsValid(indexId));
+
+ indexRelation = index_open(indexId);
+
+ /* ----------------
+ * fix RELATION relation
+ * ----------------
+ */
+ catalogRelation = heap_openr(RelationRelationName);
+
+ ScanKeyEntryInitialize(&entry, 0x0, ObjectIdAttributeNumber,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(indexId));;
+
+ scan = heap_beginscan(catalogRelation, 0, NowTimeQual, 1, &entry);
+ tuple = heap_getnext(scan, 0, (Buffer *) NULL);
+
+ AssertState(HeapTupleIsValid(tuple));
+
+ heap_delete(catalogRelation, &tuple->t_ctid);
+ heap_endscan(scan);
+ heap_close(catalogRelation);
+
+ /* ----------------
+ * fix ATTRIBUTE relation
+ * ----------------
+ */
+ catalogRelation = heap_openr(AttributeRelationName);
+
+ entry.sk_attno = Anum_pg_attribute_attrelid;
+
+ scan = heap_beginscan(catalogRelation, 0, NowTimeQual, 1, &entry);
+
+ while (tuple = heap_getnext(scan, 0, (Buffer *) NULL),
+ HeapTupleIsValid(tuple))
+ {
+
+ heap_delete(catalogRelation, &tuple->t_ctid);
+ }
+ heap_endscan(scan);
+ heap_close(catalogRelation);
+
+ /* ----------------
+ * fix INDEX relation
+ * ----------------
+ */
+ catalogRelation = heap_openr(IndexRelationName);
+
+ entry.sk_attno = Anum_pg_index_indexrelid;
+
+ scan = heap_beginscan(catalogRelation, 0, NowTimeQual, 1, &entry);
+ tuple = heap_getnext(scan, 0, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(NOTICE, "IndexRelationDestroy: %s's INDEX tuple missing",
+ RelationGetRelationName(indexRelation));
+ }
heap_delete(catalogRelation, &tuple->t_ctid);
- }
- heap_endscan(scan);
- heap_close(catalogRelation);
-
- /* ----------------
- * fix INDEX relation
- * ----------------
- */
- catalogRelation = heap_openr(IndexRelationName);
-
- entry.sk_attno = Anum_pg_index_indexrelid;
-
- scan = heap_beginscan(catalogRelation, 0, NowTimeQual, 1, &entry);
- tuple = heap_getnext(scan, 0, (Buffer *)NULL);
- if (! HeapTupleIsValid(tuple)) {
- elog(NOTICE, "IndexRelationDestroy: %s's INDEX tuple missing",
- RelationGetRelationName(indexRelation));
- }
- heap_delete(catalogRelation, &tuple->t_ctid);
- heap_endscan(scan);
- heap_close(catalogRelation);
-
- /*
- * physically remove the file
- */
- if (FileNameUnlink(relpath(indexRelation->rd_rel->relname.data)) < 0)
- elog(WARN, "amdestroyr: unlink: %m");
-
- index_close(indexRelation);
+ heap_endscan(scan);
+ heap_close(catalogRelation);
+
+ /*
+ * physically remove the file
+ */
+ if (FileNameUnlink(relpath(indexRelation->rd_rel->relname.data)) < 0)
+ elog(WARN, "amdestroyr: unlink: %m");
+
+ index_close(indexRelation);
}
/* ----------------------------------------------------------------
- * index_build support
+ * index_build support
* ----------------------------------------------------------------
*/
/* ----------------
- * FormIndexDatum
+ * FormIndexDatum
* ----------------
*/
void
FormIndexDatum(int numberOfAttributes,
- AttrNumber attributeNumber[],
- HeapTuple heapTuple,
- TupleDesc heapDescriptor,
- Buffer buffer,
- Datum *datum,
- char *nullv,
- FuncIndexInfoPtr fInfo)
+ AttrNumber attributeNumber[],
+ HeapTuple heapTuple,
+ TupleDesc heapDescriptor,
+ Buffer buffer,
+ Datum * datum,
+ char *nullv,
+ FuncIndexInfoPtr fInfo)
{
- AttrNumber i;
- int offset;
- bool isNull;
-
- /* ----------------
- * for each attribute we need from the heap tuple,
- * get the attribute and stick it into the datum and
- * null arrays.
- * ----------------
- */
-
- for (i = 1; i <= numberOfAttributes; i += 1) {
- offset = AttrNumberGetAttrOffset(i);
-
- datum[ offset ] =
- PointerGetDatum( GetIndexValue(heapTuple,
- heapDescriptor,
- offset,
- attributeNumber,
- fInfo,
- &isNull,
- buffer) );
-
- nullv[ offset ] = (isNull) ? 'n' : ' ';
- }
+ AttrNumber i;
+ int offset;
+ bool isNull;
+
+ /* ----------------
+ * for each attribute we need from the heap tuple,
+ * get the attribute and stick it into the datum and
+ * null arrays.
+ * ----------------
+ */
+
+ for (i = 1; i <= numberOfAttributes; i += 1)
+ {
+ offset = AttrNumberGetAttrOffset(i);
+
+ datum[offset] =
+ PointerGetDatum(GetIndexValue(heapTuple,
+ heapDescriptor,
+ offset,
+ attributeNumber,
+ fInfo,
+ &isNull,
+ buffer));
+
+ nullv[offset] = (isNull) ? 'n' : ' ';
+ }
}
/* ----------------
- * UpdateStats
+ * UpdateStats
* ----------------
*/
void
UpdateStats(Oid relid, long reltuples, bool hasindex)
{
- Relation whichRel;
- Relation pg_class;
- HeapScanDesc pg_class_scan;
- HeapTuple htup;
- HeapTuple newtup;
- long relpages;
- Buffer buffer;
- int i;
- Form_pg_class rd_rel;
- Relation idescs[Num_pg_class_indices];
-
- static ScanKeyData key[1] = {
- { 0, ObjectIdAttributeNumber, ObjectIdEqualRegProcedure }
- };
- Datum values[Natts_pg_class];
- char nulls[Natts_pg_class];
- char replace[Natts_pg_class];
-
- fmgr_info(ObjectIdEqualRegProcedure, (func_ptr *) &key[0].sk_func,
- &key[0].sk_nargs);
-
- /* ----------------
- * This routine handles updates for both the heap and index relation
- * statistics. In order to guarantee that we're able to *see* the index
- * relation tuple, we bump the command counter id here. The index
- * relation tuple was created in the current transaction.
- * ----------------
- */
- CommandCounterIncrement();
-
- /* ----------------
- * CommandCounterIncrement() flushes invalid cache entries, including
- * those for the heap and index relations for which we're updating
- * statistics. Now that the cache is flushed, it's safe to open the
- * relation again. We need the relation open in order to figure out
- * how many blocks it contains.
- * ----------------
- */
-
- whichRel = RelationIdGetRelation(relid);
-
- if (!RelationIsValid(whichRel))
- elog(WARN, "UpdateStats: cannot open relation id %d", relid);
-
- /* ----------------
- * Find the RELATION relation tuple for the given relation.
- * ----------------
- */
- pg_class = heap_openr(RelationRelationName);
- if (! RelationIsValid(pg_class)) {
- elog(WARN, "UpdateStats: could not open RELATION relation");
- }
- key[0].sk_argument = ObjectIdGetDatum(relid);
-
- pg_class_scan =
- heap_beginscan(pg_class, 0, NowTimeQual, 1, key);
-
- if (! HeapScanIsValid(pg_class_scan)) {
- heap_close(pg_class);
- elog(WARN, "UpdateStats: cannot scan RELATION relation");
- }
-
- /* if the heap_open above succeeded, then so will this heap_getnext() */
- htup = heap_getnext(pg_class_scan, 0, &buffer);
- heap_endscan(pg_class_scan);
-
- /* ----------------
- * update statistics
- * ----------------
- */
- relpages = RelationGetNumberOfBlocks(whichRel);
-
- /*
- * We shouldn't have to do this, but we do... Modify the reldesc
- * in place with the new values so that the cache contains the
- * latest copy.
- */
-
- whichRel->rd_rel->relhasindex = hasindex;
- whichRel->rd_rel->relpages = relpages;
- whichRel->rd_rel->reltuples = reltuples;
-
- for (i = 0; i < Natts_pg_class; i++) {
- nulls[i] = heap_attisnull(htup, i+1) ? 'n' : ' ';
- replace[i] = ' ';
- values[i] = (Datum) NULL;
- }
-
- /*
- * If reltuples wasn't supplied take an educated guess.
- */
- if (reltuples == 0)
- reltuples = relpages*NTUPLES_PER_PAGE(whichRel->rd_rel->relnatts);
-
- if (IsBootstrapProcessingMode()) {
-
+ Relation whichRel;
+ Relation pg_class;
+ HeapScanDesc pg_class_scan;
+ HeapTuple htup;
+ HeapTuple newtup;
+ long relpages;
+ Buffer buffer;
+ int i;
+ Form_pg_class rd_rel;
+ Relation idescs[Num_pg_class_indices];
+
+ static ScanKeyData key[1] = {
+ {0, ObjectIdAttributeNumber, ObjectIdEqualRegProcedure}
+ };
+ Datum values[Natts_pg_class];
+ char nulls[Natts_pg_class];
+ char replace[Natts_pg_class];
+
+ fmgr_info(ObjectIdEqualRegProcedure, (func_ptr *) & key[0].sk_func,
+ &key[0].sk_nargs);
+
+ /* ----------------
+ * This routine handles updates for both the heap and index relation
+ * statistics. In order to guarantee that we're able to *see* the index
+ * relation tuple, we bump the command counter id here. The index
+ * relation tuple was created in the current transaction.
+ * ----------------
+ */
+ CommandCounterIncrement();
+
+ /* ----------------
+ * CommandCounterIncrement() flushes invalid cache entries, including
+ * those for the heap and index relations for which we're updating
+ * statistics. Now that the cache is flushed, it's safe to open the
+ * relation again. We need the relation open in order to figure out
+ * how many blocks it contains.
+ * ----------------
+ */
+
+ whichRel = RelationIdGetRelation(relid);
+
+ if (!RelationIsValid(whichRel))
+ elog(WARN, "UpdateStats: cannot open relation id %d", relid);
+
+ /* ----------------
+ * Find the RELATION relation tuple for the given relation.
+ * ----------------
+ */
+ pg_class = heap_openr(RelationRelationName);
+ if (!RelationIsValid(pg_class))
+ {
+ elog(WARN, "UpdateStats: could not open RELATION relation");
+ }
+ key[0].sk_argument = ObjectIdGetDatum(relid);
+
+ pg_class_scan =
+ heap_beginscan(pg_class, 0, NowTimeQual, 1, key);
+
+ if (!HeapScanIsValid(pg_class_scan))
+ {
+ heap_close(pg_class);
+ elog(WARN, "UpdateStats: cannot scan RELATION relation");
+ }
+
+ /* if the heap_open above succeeded, then so will this heap_getnext() */
+ htup = heap_getnext(pg_class_scan, 0, &buffer);
+ heap_endscan(pg_class_scan);
+
+ /* ----------------
+ * update statistics
+ * ----------------
+ */
+ relpages = RelationGetNumberOfBlocks(whichRel);
+
+ /*
+ * We shouldn't have to do this, but we do... Modify the reldesc in
+ * place with the new values so that the cache contains the latest
+ * copy.
+ */
+
+ whichRel->rd_rel->relhasindex = hasindex;
+ whichRel->rd_rel->relpages = relpages;
+ whichRel->rd_rel->reltuples = reltuples;
+
+ for (i = 0; i < Natts_pg_class; i++)
+ {
+ nulls[i] = heap_attisnull(htup, i + 1) ? 'n' : ' ';
+ replace[i] = ' ';
+ values[i] = (Datum) NULL;
+ }
+
/*
- * At bootstrap time, we don't need to worry about concurrency
- * or visibility of changes, so we cheat.
- */
-
- rd_rel = (Form_pg_class) GETSTRUCT(htup);
- rd_rel->relpages = relpages;
- rd_rel->reltuples = reltuples;
- rd_rel->relhasindex = hasindex;
- } else {
- /* during normal processing, work harder */
- replace[Anum_pg_class_relpages - 1] = 'r';
- values[Anum_pg_class_relpages - 1] = (Datum)relpages;
- replace[Anum_pg_class_reltuples - 1] = 'r';
- values[Anum_pg_class_reltuples - 1] = (Datum)reltuples;
- replace[Anum_pg_class_relhasindex - 1] = 'r';
- values[Anum_pg_class_relhasindex - 1] = CharGetDatum(hasindex);
-
- newtup = heap_modifytuple(htup, buffer, pg_class, values,
- nulls, replace);
- heap_replace(pg_class, &(newtup->t_ctid), newtup);
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, newtup);
- CatalogCloseIndices(Num_pg_class_indices, idescs);
- }
-
- heap_close(pg_class);
- heap_close(whichRel);
+ * If reltuples wasn't supplied take an educated guess.
+ */
+ if (reltuples == 0)
+ reltuples = relpages * NTUPLES_PER_PAGE(whichRel->rd_rel->relnatts);
+
+ if (IsBootstrapProcessingMode())
+ {
+
+ /*
+ * At bootstrap time, we don't need to worry about concurrency or
+ * visibility of changes, so we cheat.
+ */
+
+ rd_rel = (Form_pg_class) GETSTRUCT(htup);
+ rd_rel->relpages = relpages;
+ rd_rel->reltuples = reltuples;
+ rd_rel->relhasindex = hasindex;
+ }
+ else
+ {
+ /* during normal processing, work harder */
+ replace[Anum_pg_class_relpages - 1] = 'r';
+ values[Anum_pg_class_relpages - 1] = (Datum) relpages;
+ replace[Anum_pg_class_reltuples - 1] = 'r';
+ values[Anum_pg_class_reltuples - 1] = (Datum) reltuples;
+ replace[Anum_pg_class_relhasindex - 1] = 'r';
+ values[Anum_pg_class_relhasindex - 1] = CharGetDatum(hasindex);
+
+ newtup = heap_modifytuple(htup, buffer, pg_class, values,
+ nulls, replace);
+ heap_replace(pg_class, &(newtup->t_ctid), newtup);
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, newtup);
+ CatalogCloseIndices(Num_pg_class_indices, idescs);
+ }
+
+ heap_close(pg_class);
+ heap_close(whichRel);
}
/* -------------------------
- * FillDummyExprContext
- * Sets up dummy ExprContext and TupleTableSlot objects for use
- * with ExecQual.
+ * FillDummyExprContext
+ * Sets up dummy ExprContext and TupleTableSlot objects for use
+ * with ExecQual.
* -------------------------
*/
void
-FillDummyExprContext(ExprContext *econtext,
- TupleTableSlot *slot,
- TupleDesc tupdesc,
- Buffer buffer)
+FillDummyExprContext(ExprContext * econtext,
+ TupleTableSlot * slot,
+ TupleDesc tupdesc,
+ Buffer buffer)
{
- econtext->ecxt_scantuple = slot;
- econtext->ecxt_innertuple = NULL;
- econtext->ecxt_outertuple = NULL;
- econtext->ecxt_param_list_info = NULL;
- econtext->ecxt_range_table = NULL;
-
- slot->ttc_tupleDescriptor = tupdesc;
- slot->ttc_buffer = buffer;
- slot->ttc_shouldFree = false;
+ econtext->ecxt_scantuple = slot;
+ econtext->ecxt_innertuple = NULL;
+ econtext->ecxt_outertuple = NULL;
+ econtext->ecxt_param_list_info = NULL;
+ econtext->ecxt_range_table = NULL;
+
+ slot->ttc_tupleDescriptor = tupdesc;
+ slot->ttc_buffer = buffer;
+ slot->ttc_shouldFree = false;
}
/* ----------------
- * DefaultBuild
+ * DefaultBuild
* ----------------
*/
static void
DefaultBuild(Relation heapRelation,
- Relation indexRelation,
- int numberOfAttributes,
- AttrNumber attributeNumber[],
- IndexStrategy indexStrategy, /* not used */
- uint16 parameterCount, /* not used */
- Datum parameter[], /* not used */
- FuncIndexInfoPtr funcInfo,
- PredInfo *predInfo)
+ Relation indexRelation,
+ int numberOfAttributes,
+ AttrNumber attributeNumber[],
+ IndexStrategy indexStrategy, /* not used */
+ uint16 parameterCount, /* not used */
+ Datum parameter[], /* not used */
+ FuncIndexInfoPtr funcInfo,
+ PredInfo * predInfo)
{
- HeapScanDesc scan;
- HeapTuple heapTuple;
- Buffer buffer;
-
- IndexTuple indexTuple;
- TupleDesc heapDescriptor;
- TupleDesc indexDescriptor;
- Datum *datum;
- char *nullv;
- long reltuples, indtuples;
+ HeapScanDesc scan;
+ HeapTuple heapTuple;
+ Buffer buffer;
+
+ IndexTuple indexTuple;
+ TupleDesc heapDescriptor;
+ TupleDesc indexDescriptor;
+ Datum *datum;
+ char *nullv;
+ long reltuples,
+ indtuples;
+
#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext;
- TupleTable tupleTable;
- TupleTableSlot *slot;
+ ExprContext *econtext;
+ TupleTable tupleTable;
+ TupleTableSlot *slot;
+
#endif
- Node *predicate;
- Node *oldPred;
-
- InsertIndexResult insertResult;
-
- /* ----------------
- * more & better checking is needed
- * ----------------
- */
- Assert(OidIsValid(indexRelation->rd_rel->relam)); /* XXX */
-
- /* ----------------
- * get the tuple descriptors from the relations so we know
- * how to form the index tuples..
- * ----------------
- */
- heapDescriptor = RelationGetTupleDescriptor(heapRelation);
- indexDescriptor = RelationGetTupleDescriptor(indexRelation);
-
- /* ----------------
- * datum and null are arrays in which we collect the index attributes
- * when forming a new index tuple.
- * ----------------
- */
- datum = (Datum *) palloc(numberOfAttributes * sizeof *datum);
- nullv = (char *) palloc(numberOfAttributes * sizeof *nullv);
-
- /*
- * If this is a predicate (partial) index, we will need to evaluate the
- * predicate using ExecQual, which requires the current tuple to be in a
- * slot of a TupleTable. In addition, ExecQual must have an ExprContext
- * referring to that slot. Here, we initialize dummy TupleTable and
- * ExprContext objects for this purpose. --Nels, Feb '92
- */
-
- predicate = predInfo->pred;
- oldPred = predInfo->oldPred;
+ Node *predicate;
+ Node *oldPred;
+
+ InsertIndexResult insertResult;
+
+ /* ----------------
+ * more & better checking is needed
+ * ----------------
+ */
+ Assert(OidIsValid(indexRelation->rd_rel->relam)); /* XXX */
+
+ /* ----------------
+ * get the tuple descriptors from the relations so we know
+ * how to form the index tuples..
+ * ----------------
+ */
+ heapDescriptor = RelationGetTupleDescriptor(heapRelation);
+ indexDescriptor = RelationGetTupleDescriptor(indexRelation);
+
+ /* ----------------
+ * datum and null are arrays in which we collect the index attributes
+ * when forming a new index tuple.
+ * ----------------
+ */
+ datum = (Datum *) palloc(numberOfAttributes * sizeof *datum);
+ nullv = (char *) palloc(numberOfAttributes * sizeof *nullv);
+
+ /*
+ * If this is a predicate (partial) index, we will need to evaluate
+ * the predicate using ExecQual, which requires the current tuple to
+ * be in a slot of a TupleTable. In addition, ExecQual must have an
+ * ExprContext referring to that slot. Here, we initialize dummy
+ * TupleTable and ExprContext objects for this purpose. --Nels, Feb
+ * '92
+ */
+
+ predicate = predInfo->pred;
+ oldPred = predInfo->oldPred;
#ifndef OMIT_PARTIAL_INDEX
- if (predicate != NULL || oldPred != NULL) {
- tupleTable = ExecCreateTupleTable(1);
- slot = ExecAllocTableSlot(tupleTable);
- econtext = makeNode(ExprContext);
- FillDummyExprContext(econtext, slot, heapDescriptor, buffer);
- }
+ if (predicate != NULL || oldPred != NULL)
+ {
+ tupleTable = ExecCreateTupleTable(1);
+ slot = ExecAllocTableSlot(tupleTable);
+ econtext = makeNode(ExprContext);
+ FillDummyExprContext(econtext, slot, heapDescriptor, buffer);
+ }
else
{
econtext = NULL;
tupleTable = 0;
slot = NULL;
}
-#endif /* OMIT_PARTIAL_INDEX */
-
- /* ----------------
- * Ok, begin our scan of the base relation.
- * ----------------
- */
- scan = heap_beginscan(heapRelation, /* relation */
- 0, /* start at end */
- NowTimeQual, /* time range */
- 0, /* number of keys */
- (ScanKey) NULL); /* scan key */
-
- reltuples = indtuples = 0;
-
- /* ----------------
- * for each tuple in the base relation, we create an index
- * tuple and add it to the index relation. We keep a running
- * count of the number of tuples so that we can update pg_class
- * with correct statistics when we're done building the index.
- * ----------------
- */
- while (heapTuple = heap_getnext(scan, 0, &buffer),
- HeapTupleIsValid(heapTuple)) {
-
- reltuples++;
-
- /*
- * If oldPred != NULL, this is an EXTEND INDEX command, so skip
- * this tuple if it was already in the existing partial index
+#endif /* OMIT_PARTIAL_INDEX */
+
+ /* ----------------
+ * Ok, begin our scan of the base relation.
+ * ----------------
*/
- if (oldPred != NULL) {
+ scan = heap_beginscan(heapRelation, /* relation */
+ 0, /* start at end */
+ NowTimeQual, /* time range */
+ 0, /* number of keys */
+ (ScanKey) NULL); /* scan key */
+
+ reltuples = indtuples = 0;
+
+ /* ----------------
+ * for each tuple in the base relation, we create an index
+ * tuple and add it to the index relation. We keep a running
+ * count of the number of tuples so that we can update pg_class
+ * with correct statistics when we're done building the index.
+ * ----------------
+ */
+ while (heapTuple = heap_getnext(scan, 0, &buffer),
+ HeapTupleIsValid(heapTuple))
+ {
+
+ reltuples++;
+
+ /*
+ * If oldPred != NULL, this is an EXTEND INDEX command, so skip
+ * this tuple if it was already in the existing partial index
+ */
+ if (oldPred != NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- /*SetSlotContents(slot, heapTuple); */
- slot->val = heapTuple;
- if (ExecQual((List*)oldPred, econtext) == true) {
+ /* SetSlotContents(slot, heapTuple); */
+ slot->val = heapTuple;
+ if (ExecQual((List *) oldPred, econtext) == true)
+ {
+ indtuples++;
+ continue;
+ }
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+
+ /*
+ * Skip this tuple if it doesn't satisfy the partial-index
+ * predicate
+ */
+ if (predicate != NULL)
+ {
+#ifndef OMIT_PARTIAL_INDEX
+ /* SetSlotContents(slot, heapTuple); */
+ slot->val = heapTuple;
+ if (ExecQual((List *) predicate, econtext) == false)
+ continue;
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+
indtuples++;
- continue;
- }
-#endif /* OMIT_PARTIAL_INDEX */
+
+ /* ----------------
+ * FormIndexDatum fills in its datum and null parameters
+ * with attribute information taken from the given heap tuple.
+ * ----------------
+ */
+ FormIndexDatum(numberOfAttributes, /* num attributes */
+ attributeNumber, /* array of att nums to extract */
+ heapTuple, /* tuple from base relation */
+ heapDescriptor, /* heap tuple's descriptor */
+ buffer, /* buffer used in the scan */
+ datum, /* return: array of attributes */
+ nullv, /* return: array of char's */
+ funcInfo);
+
+ indexTuple = index_formtuple(indexDescriptor,
+ datum,
+ nullv);
+
+ indexTuple->t_tid = heapTuple->t_ctid;
+
+ insertResult = index_insert(indexRelation, datum, nullv,
+ &(heapTuple->t_ctid), heapRelation);
+
+ if (insertResult)
+ pfree(insertResult);
+ pfree(indexTuple);
}
-
- /* Skip this tuple if it doesn't satisfy the partial-index predicate */
- if (predicate != NULL) {
+
+ heap_endscan(scan);
+
+ if (predicate != NULL || oldPred != NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- /*SetSlotContents(slot, heapTuple); */
- slot->val = heapTuple;
- if (ExecQual((List*)predicate, econtext) == false)
- continue;
-#endif /* OMIT_PARTIAL_INDEX */
+ ExecDestroyTupleTable(tupleTable, false);
+#endif /* OMIT_PARTIAL_INDEX */
}
-
- indtuples++;
-
- /* ----------------
- * FormIndexDatum fills in its datum and null parameters
- * with attribute information taken from the given heap tuple.
- * ----------------
+
+ pfree(nullv);
+ pfree(datum);
+
+ /*
+ * Okay, now update the reltuples and relpages statistics for both the
+ * heap relation and the index. These statistics are used by the
+ * planner to choose a scan type. They are maintained generally by
+ * the vacuum daemon, but we update them here to make the index useful
+ * as soon as possible.
*/
- FormIndexDatum(numberOfAttributes, /* num attributes */
- attributeNumber, /* array of att nums to extract */
- heapTuple, /* tuple from base relation */
- heapDescriptor, /* heap tuple's descriptor */
- buffer, /* buffer used in the scan */
- datum, /* return: array of attributes */
- nullv, /* return: array of char's */
- funcInfo);
-
- indexTuple = index_formtuple(indexDescriptor,
- datum,
- nullv);
-
- indexTuple->t_tid = heapTuple->t_ctid;
-
- insertResult = index_insert(indexRelation, datum, nullv,
- &(heapTuple->t_ctid), heapRelation);
-
- if (insertResult) pfree(insertResult);
- pfree(indexTuple);
- }
-
- heap_endscan(scan);
-
- if (predicate != NULL || oldPred != NULL) {
-#ifndef OMIT_PARTIAL_INDEX
- ExecDestroyTupleTable(tupleTable, false);
-#endif /* OMIT_PARTIAL_INDEX */
- }
-
- pfree(nullv);
- pfree(datum);
-
- /*
- * Okay, now update the reltuples and relpages statistics for both
- * the heap relation and the index. These statistics are used by
- * the planner to choose a scan type. They are maintained generally
- * by the vacuum daemon, but we update them here to make the index
- * useful as soon as possible.
- */
- UpdateStats(heapRelation->rd_id, reltuples, true);
- UpdateStats(indexRelation->rd_id, indtuples, false);
- if (oldPred != NULL) {
- if (indtuples == reltuples) predicate = NULL;
- UpdateIndexPredicate(indexRelation->rd_id, oldPred, predicate);
- }
+ UpdateStats(heapRelation->rd_id, reltuples, true);
+ UpdateStats(indexRelation->rd_id, indtuples, false);
+ if (oldPred != NULL)
+ {
+ if (indtuples == reltuples)
+ predicate = NULL;
+ UpdateIndexPredicate(indexRelation->rd_id, oldPred, predicate);
+ }
}
/* ----------------
- * index_build
+ * index_build
* ----------------
*/
void
index_build(Relation heapRelation,
- Relation indexRelation,
- int numberOfAttributes,
- AttrNumber attributeNumber[],
- uint16 parameterCount,
- Datum *parameter,
- FuncIndexInfo *funcInfo,
- PredInfo *predInfo)
+ Relation indexRelation,
+ int numberOfAttributes,
+ AttrNumber attributeNumber[],
+ uint16 parameterCount,
+ Datum * parameter,
+ FuncIndexInfo * funcInfo,
+ PredInfo * predInfo)
{
- RegProcedure procedure;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(indexRelation));
- Assert(PointerIsValid(indexRelation->rd_am));
-
- procedure = indexRelation->rd_am->ambuild;
-
- /* ----------------
- * use the access method build procedure if supplied..
- * ----------------
- */
- if (RegProcedureIsValid(procedure))
- fmgr(procedure,
- heapRelation,
- indexRelation,
- numberOfAttributes,
- attributeNumber,
- RelationGetIndexStrategy(indexRelation),
- parameterCount,
- parameter,
- funcInfo,
- predInfo);
- else
- DefaultBuild(heapRelation,
- indexRelation,
- numberOfAttributes,
- attributeNumber,
- RelationGetIndexStrategy(indexRelation),
- parameterCount,
- parameter,
- funcInfo,
- predInfo);
+ RegProcedure procedure;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(indexRelation));
+ Assert(PointerIsValid(indexRelation->rd_am));
+
+ procedure = indexRelation->rd_am->ambuild;
+
+ /* ----------------
+ * use the access method build procedure if supplied..
+ * ----------------
+ */
+ if (RegProcedureIsValid(procedure))
+ fmgr(procedure,
+ heapRelation,
+ indexRelation,
+ numberOfAttributes,
+ attributeNumber,
+ RelationGetIndexStrategy(indexRelation),
+ parameterCount,
+ parameter,
+ funcInfo,
+ predInfo);
+ else
+ DefaultBuild(heapRelation,
+ indexRelation,
+ numberOfAttributes,
+ attributeNumber,
+ RelationGetIndexStrategy(indexRelation),
+ parameterCount,
+ parameter,
+ funcInfo,
+ predInfo);
}
/*
@@ -1712,20 +1781,21 @@ index_build(Relation heapRelation,
bool
IndexIsUnique(Oid indexId)
{
- HeapTuple tuple;
- IndexTupleForm index;
-
- tuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexId),
- 0,0,0);
- if(!HeapTupleIsValid(tuple)) {
- elog(WARN, "IndexIsUnique: can't find index id %d",
- indexId);
- }
- index = (IndexTupleForm)GETSTRUCT(tuple);
- Assert(index->indexrelid == indexId);
-
- return index->indisunique;
+ HeapTuple tuple;
+ IndexTupleForm index;
+
+ tuple = SearchSysCacheTuple(INDEXRELID,
+ ObjectIdGetDatum(indexId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN, "IndexIsUnique: can't find index id %d",
+ indexId);
+ }
+ index = (IndexTupleForm) GETSTRUCT(tuple);
+ Assert(index->indexrelid == indexId);
+
+ return index->indisunique;
}
/*
@@ -1743,32 +1813,33 @@ IndexIsUnique(Oid indexId)
bool
IndexIsUniqueNoCache(Oid indexId)
{
- Relation pg_index;
- ScanKeyData skey[1];
- HeapScanDesc scandesc;
- HeapTuple tuple;
- IndexTupleForm index;
- bool isunique;
-
- pg_index = heap_openr(IndexRelationName);
-
- ScanKeyEntryInitialize(&skey[0], (bits16)0x0,
- Anum_pg_index_indexrelid,
- (RegProcedure)ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(indexId));
-
- scandesc = heap_beginscan(pg_index, 0, SelfTimeQual, 1, skey);
-
- tuple = heap_getnext(scandesc, 0, NULL);
- if(!HeapTupleIsValid(tuple)) {
- elog(WARN, "IndexIsUniqueNoCache: can't find index id %d",
- indexId);
- }
- index = (IndexTupleForm)GETSTRUCT(tuple);
- Assert(index->indexrelid == indexId);
- isunique = index->indisunique;
-
- heap_endscan (scandesc);
- heap_close (pg_index);
- return isunique;
+ Relation pg_index;
+ ScanKeyData skey[1];
+ HeapScanDesc scandesc;
+ HeapTuple tuple;
+ IndexTupleForm index;
+ bool isunique;
+
+ pg_index = heap_openr(IndexRelationName);
+
+ ScanKeyEntryInitialize(&skey[0], (bits16) 0x0,
+ Anum_pg_index_indexrelid,
+ (RegProcedure) ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(indexId));
+
+ scandesc = heap_beginscan(pg_index, 0, SelfTimeQual, 1, skey);
+
+ tuple = heap_getnext(scandesc, 0, NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN, "IndexIsUniqueNoCache: can't find index id %d",
+ indexId);
+ }
+ index = (IndexTupleForm) GETSTRUCT(tuple);
+ Assert(index->indexrelid == indexId);
+ isunique = index->indisunique;
+
+ heap_endscan(scandesc);
+ heap_close(pg_index);
+ return isunique;
}
diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
index 2d769d58615..6a89258d972 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* indexing.c--
- * This file contains routines to support indices defined on system
- * catalogs.
+ * This file contains routines to support indices defined on system
+ * catalogs.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.11 1997/08/31 09:56:18 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.12 1997/09/07 04:40:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,36 +34,37 @@
/*
* Names of indices on the following system catalogs:
*
- * pg_attribute
- * pg_proc
- * pg_type
- * pg_naming
- * pg_class
- * pg_attrdef
- * pg_relcheck
- * pg_trigger
+ * pg_attribute
+ * pg_proc
+ * pg_type
+ * pg_naming
+ * pg_class
+ * pg_attrdef
+ * pg_relcheck
+ * pg_trigger
*/
-char *Name_pg_attr_indices[Num_pg_attr_indices] = {AttributeNameIndex,
- AttributeNumIndex,
- AttributeRelidIndex};
-char *Name_pg_proc_indices[Num_pg_proc_indices] = { ProcedureNameIndex,
- ProcedureOidIndex,
- ProcedureSrcIndex};
-char *Name_pg_type_indices[Num_pg_type_indices] = { TypeNameIndex,
- TypeOidIndex};
-char *Name_pg_class_indices[Num_pg_class_indices]= { ClassNameIndex,
- ClassOidIndex};
-char *Name_pg_attrdef_indices[Num_pg_attrdef_indices]= { AttrDefaultIndex };
+char *Name_pg_attr_indices[Num_pg_attr_indices] = {AttributeNameIndex,
+ AttributeNumIndex,
+AttributeRelidIndex};
+char *Name_pg_proc_indices[Num_pg_proc_indices] = {ProcedureNameIndex,
+ ProcedureOidIndex,
+ProcedureSrcIndex};
+char *Name_pg_type_indices[Num_pg_type_indices] = {TypeNameIndex,
+TypeOidIndex};
+char *Name_pg_class_indices[Num_pg_class_indices] = {ClassNameIndex,
+ClassOidIndex};
+char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] = {AttrDefaultIndex};
-char *Name_pg_relcheck_indices[Num_pg_relcheck_indices]= { RelCheckIndex };
+char *Name_pg_relcheck_indices[Num_pg_relcheck_indices] = {RelCheckIndex};
-char *Name_pg_trigger_indices[Num_pg_trigger_indices]= { TriggerRelidIndex };
+char *Name_pg_trigger_indices[Num_pg_trigger_indices] = {TriggerRelidIndex};
-static HeapTuple CatalogIndexFetchTuple(Relation heapRelation,
- Relation idesc,
- ScanKey skey);
+static HeapTuple
+CatalogIndexFetchTuple(Relation heapRelation,
+ Relation idesc,
+ ScanKey skey);
/*
@@ -75,11 +76,11 @@ static HeapTuple CatalogIndexFetchTuple(Relation heapRelation,
void
CatalogOpenIndices(int nIndices, char *names[], Relation idescs[])
{
- int i;
-
- for (i=0; i<nIndices; i++)
+ int i;
+
+ for (i = 0; i < nIndices; i++)
{
- idescs[i] = index_openr(names[i]);
+ idescs[i] = index_openr(names[i]);
}
}
@@ -87,83 +88,84 @@ CatalogOpenIndices(int nIndices, char *names[], Relation idescs[])
* This is the inverse routine to CatalogOpenIndices()
*/
void
-CatalogCloseIndices(int nIndices, Relation *idescs)
+CatalogCloseIndices(int nIndices, Relation * idescs)
{
- int i;
-
- for (i=0; i<nIndices; i++)
- index_close(idescs[i]);
+ int i;
+
+ for (i = 0; i < nIndices; i++)
+ index_close(idescs[i]);
}
/*
* For the same reasons outlined above CatalogOpenIndices() we need a routine
- * that takes a new catalog tuple and inserts an associated index tuple into
+ * that takes a new catalog tuple and inserts an associated index tuple into
* each catalog index.
*/
void
-CatalogIndexInsert(Relation *idescs,
- int nIndices,
- Relation heapRelation,
- HeapTuple heapTuple)
+CatalogIndexInsert(Relation * idescs,
+ int nIndices,
+ Relation heapRelation,
+ HeapTuple heapTuple)
{
- HeapTuple pgIndexTup;
- TupleDesc heapDescriptor;
- IndexTupleForm pgIndexP;
- Datum datum;
- int natts;
- AttrNumber *attnumP;
- FuncIndexInfo finfo, *finfoP;
- char nulls[INDEX_MAX_KEYS];
- int i;
-
- heapDescriptor = RelationGetTupleDescriptor(heapRelation);
-
- for (i=0; i<nIndices; i++)
+ HeapTuple pgIndexTup;
+ TupleDesc heapDescriptor;
+ IndexTupleForm pgIndexP;
+ Datum datum;
+ int natts;
+ AttrNumber *attnumP;
+ FuncIndexInfo finfo,
+ *finfoP;
+ char nulls[INDEX_MAX_KEYS];
+ int i;
+
+ heapDescriptor = RelationGetTupleDescriptor(heapRelation);
+
+ for (i = 0; i < nIndices; i++)
{
- TupleDesc indexDescriptor;
- InsertIndexResult indexRes;
-
- indexDescriptor = RelationGetTupleDescriptor(idescs[i]);
- pgIndexTup = SearchSysCacheTuple(INDEXRELID,
- Int32GetDatum(idescs[i]->rd_id),
- 0,0,0);
- Assert(pgIndexTup);
- pgIndexP = (IndexTupleForm)GETSTRUCT(pgIndexTup);
-
- /*
- * Compute the number of attributes we are indexing upon.
- * very important - can't assume one if this is a functional
- * index.
- */
- for (attnumP=(&pgIndexP->indkey[0]), natts=0;
- *attnumP != InvalidAttrNumber;
- attnumP++, natts++)
- ;
-
- if (pgIndexP->indproc != InvalidOid)
+ TupleDesc indexDescriptor;
+ InsertIndexResult indexRes;
+
+ indexDescriptor = RelationGetTupleDescriptor(idescs[i]);
+ pgIndexTup = SearchSysCacheTuple(INDEXRELID,
+ Int32GetDatum(idescs[i]->rd_id),
+ 0, 0, 0);
+ Assert(pgIndexTup);
+ pgIndexP = (IndexTupleForm) GETSTRUCT(pgIndexTup);
+
+ /*
+ * Compute the number of attributes we are indexing upon. very
+ * important - can't assume one if this is a functional index.
+ */
+ for (attnumP = (&pgIndexP->indkey[0]), natts = 0;
+ *attnumP != InvalidAttrNumber;
+ attnumP++, natts++)
+ ;
+
+ if (pgIndexP->indproc != InvalidOid)
{
- FIgetnArgs(&finfo) = natts;
- natts = 1;
- FIgetProcOid(&finfo) = pgIndexP->indproc;
- *(FIgetname(&finfo)) = '\0';
- finfoP = &finfo;
+ FIgetnArgs(&finfo) = natts;
+ natts = 1;
+ FIgetProcOid(&finfo) = pgIndexP->indproc;
+ *(FIgetname(&finfo)) = '\0';
+ finfoP = &finfo;
}
- else
- finfoP = (FuncIndexInfo *)NULL;
-
- FormIndexDatum(natts,
- (AttrNumber *)&pgIndexP->indkey[0],
- heapTuple,
- heapDescriptor,
- InvalidBuffer,
- &datum,
- nulls,
- finfoP);
-
- indexRes = index_insert(idescs[i], &datum, nulls,
- &(heapTuple->t_ctid), heapRelation);
- if (indexRes) pfree(indexRes);
+ else
+ finfoP = (FuncIndexInfo *) NULL;
+
+ FormIndexDatum(natts,
+ (AttrNumber *) & pgIndexP->indkey[0],
+ heapTuple,
+ heapDescriptor,
+ InvalidBuffer,
+ &datum,
+ nulls,
+ finfoP);
+
+ indexRes = index_insert(idescs[i], &datum, nulls,
+ &(heapTuple->t_ctid), heapRelation);
+ if (indexRes)
+ pfree(indexRes);
}
}
@@ -174,81 +176,88 @@ CatalogIndexInsert(Relation *idescs,
bool
CatalogHasIndex(char *catName, Oid catId)
{
- Relation pg_class;
- HeapTuple htup;
- Form_pg_class pgRelP;
- int i;
-
- Assert(IsSystemRelationName(catName));
-
- /*
- * If we're bootstraping we don't have pg_class (or any indices).
- */
- if (IsBootstrapProcessingMode())
- return false;
-
- if (IsInitProcessingMode()) {
- for (i = 0; IndexedCatalogNames[i] != NULL; i++) {
- if ( strcmp(IndexedCatalogNames[i], catName) == 0)
- return (true);
+ Relation pg_class;
+ HeapTuple htup;
+ Form_pg_class pgRelP;
+ int i;
+
+ Assert(IsSystemRelationName(catName));
+
+ /*
+ * If we're bootstraping we don't have pg_class (or any indices).
+ */
+ if (IsBootstrapProcessingMode())
+ return false;
+
+ if (IsInitProcessingMode())
+ {
+ for (i = 0; IndexedCatalogNames[i] != NULL; i++)
+ {
+ if (strcmp(IndexedCatalogNames[i], catName) == 0)
+ return (true);
+ }
+ return (false);
}
- return (false);
- }
-
- pg_class = heap_openr(RelationRelationName);
- htup = ClassOidIndexScan(pg_class, catId);
- heap_close(pg_class);
-
- if (! HeapTupleIsValid(htup)) {
- elog(NOTICE, "CatalogHasIndex: no relation with oid %d", catId);
- return false;
- }
-
- pgRelP = (Form_pg_class)GETSTRUCT(htup);
- return (pgRelP->relhasindex);
+
+ pg_class = heap_openr(RelationRelationName);
+ htup = ClassOidIndexScan(pg_class, catId);
+ heap_close(pg_class);
+
+ if (!HeapTupleIsValid(htup))
+ {
+ elog(NOTICE, "CatalogHasIndex: no relation with oid %d", catId);
+ return false;
+ }
+
+ pgRelP = (Form_pg_class) GETSTRUCT(htup);
+ return (pgRelP->relhasindex);
}
/*
- * CatalogIndexFetchTuple() -- Get a tuple that satisfies a scan key
- * from a catalog relation.
+ * CatalogIndexFetchTuple() -- Get a tuple that satisfies a scan key
+ * from a catalog relation.
*
- * Since the index may contain pointers to dead tuples, we need to
- * iterate until we find a tuple that's valid and satisfies the scan
- * key.
+ * Since the index may contain pointers to dead tuples, we need to
+ * iterate until we find a tuple that's valid and satisfies the scan
+ * key.
*/
-static HeapTuple
+static HeapTuple
CatalogIndexFetchTuple(Relation heapRelation,
- Relation idesc,
- ScanKey skey)
+ Relation idesc,
+ ScanKey skey)
{
- IndexScanDesc sd;
- RetrieveIndexResult indexRes;
- HeapTuple tuple;
- Buffer buffer;
-
- sd = index_beginscan(idesc, false, 1, skey);
- tuple = (HeapTuple)NULL;
-
- do {
- indexRes = index_getnext(sd, ForwardScanDirection);
- if (indexRes) {
- ItemPointer iptr;
-
- iptr = &indexRes->heap_iptr;
- tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
- pfree(indexRes);
- } else
- break;
- } while (!HeapTupleIsValid(tuple));
-
- if (HeapTupleIsValid(tuple)) {
- tuple = heap_copytuple(tuple);
- ReleaseBuffer(buffer);
- }
-
- index_endscan(sd);
- pfree(sd);
- return (tuple);
+ IndexScanDesc sd;
+ RetrieveIndexResult indexRes;
+ HeapTuple tuple;
+ Buffer buffer;
+
+ sd = index_beginscan(idesc, false, 1, skey);
+ tuple = (HeapTuple) NULL;
+
+ do
+ {
+ indexRes = index_getnext(sd, ForwardScanDirection);
+ if (indexRes)
+ {
+ ItemPointer iptr;
+
+ iptr = &indexRes->heap_iptr;
+ tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
+ pfree(indexRes);
+ }
+ else
+ break;
+ } while (!HeapTupleIsValid(tuple));
+
+ if (HeapTupleIsValid(tuple))
+ {
+ tuple = heap_copytuple(tuple);
+ ReleaseBuffer(buffer);
+ }
+
+ index_endscan(sd);
+ pfree(sd);
+ return (tuple);
}
/*
@@ -259,276 +268,295 @@ CatalogIndexFetchTuple(Relation heapRelation,
*/
HeapTuple
AttributeNameIndexScan(Relation heapRelation,
- Oid relid,
- char *attname)
+ Oid relid,
+ char *attname)
{
- Relation idesc;
- ScanKeyData skey;
- OidName keyarg;
- HeapTuple tuple;
-
- keyarg = mkoidname(relid, attname);
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)OidNameEqRegProcedure,
- (Datum)keyarg);
-
- idesc = index_openr(AttributeNameIndex);
- tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
-
- index_close(idesc);
- pfree(keyarg);
-
- return tuple;
+ Relation idesc;
+ ScanKeyData skey;
+ OidName keyarg;
+ HeapTuple tuple;
+
+ keyarg = mkoidname(relid, attname);
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) OidNameEqRegProcedure,
+ (Datum) keyarg);
+
+ idesc = index_openr(AttributeNameIndex);
+ tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
+
+ index_close(idesc);
+ pfree(keyarg);
+
+ return tuple;
}
HeapTuple
AttributeNumIndexScan(Relation heapRelation,
- Oid relid,
- AttrNumber attnum)
+ Oid relid,
+ AttrNumber attnum)
{
- Relation idesc;
- ScanKeyData skey;
- OidInt2 keyarg;
- HeapTuple tuple;
-
- keyarg = mkoidint2(relid, (uint16)attnum);
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)OidInt2EqRegProcedure,
- (Datum)keyarg);
-
- idesc = index_openr(AttributeNumIndex);
- tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
-
- index_close(idesc);
- pfree(keyarg);
-
- return tuple;
+ Relation idesc;
+ ScanKeyData skey;
+ OidInt2 keyarg;
+ HeapTuple tuple;
+
+ keyarg = mkoidint2(relid, (uint16) attnum);
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) OidInt2EqRegProcedure,
+ (Datum) keyarg);
+
+ idesc = index_openr(AttributeNumIndex);
+ tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
+
+ index_close(idesc);
+ pfree(keyarg);
+
+ return tuple;
}
HeapTuple
ProcedureOidIndexScan(Relation heapRelation, Oid procId)
{
- Relation idesc;
- ScanKeyData skey;
- HeapTuple tuple;
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)ObjectIdEqualRegProcedure,
- (Datum)procId);
-
- idesc = index_openr(ProcedureOidIndex);
- tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
-
- index_close(idesc);
-
- return tuple;
+ Relation idesc;
+ ScanKeyData skey;
+ HeapTuple tuple;
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) ObjectIdEqualRegProcedure,
+ (Datum) procId);
+
+ idesc = index_openr(ProcedureOidIndex);
+ tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
+
+ index_close(idesc);
+
+ return tuple;
}
HeapTuple
ProcedureNameIndexScan(Relation heapRelation,
- char *procName,
- int nargs,
- Oid *argTypes)
+ char *procName,
+ int nargs,
+ Oid * argTypes)
{
- Relation idesc;
- ScanKeyData skey;
- HeapTuple tuple; /* tuple being tested */
- HeapTuple return_tuple; /* The tuple pointer we eventually return */
- IndexScanDesc sd;
- RetrieveIndexResult indexRes;
- Buffer buffer;
- Form_pg_proc pgProcP;
- bool ScanComplete;
- /* The index scan is complete, i.e. we've scanned everything there
- is to scan.
- */
- bool FoundMatch;
- /* In scanning pg_proc, we have found a row that meets our search
- criteria.
- */
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)NameEqualRegProcedure,
- (Datum)procName);
-
- idesc = index_openr(ProcedureNameIndex);
-
- sd = index_beginscan(idesc, false, 1, &skey);
-
- /*
- * for now, we do the work usually done by CatalogIndexFetchTuple
- * by hand, so that we can check that the other keys match. when
- * multi-key indices are added, they will be used here.
- */
- tuple = (HeapTuple) NULL; /* initial value */
- ScanComplete = false; /* Scan hasn't begun yet */
- FoundMatch = false; /* No match yet; haven't even looked. */
- while (!FoundMatch && !ScanComplete) {
- indexRes = index_getnext(sd, ForwardScanDirection);
- if (indexRes) {
- ItemPointer iptr;
-
- iptr = &indexRes->heap_iptr;
- tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
- pfree(indexRes);
- if (HeapTupleIsValid(tuple)) {
- /* Here's a row for a procedure that has the sought procedure
- name. To be a match, though, we need it to have the
- right number and type of arguments too, so we check that
- now.
- */
- pgProcP = (Form_pg_proc)GETSTRUCT(tuple);
- if (pgProcP->pronargs == nargs &&
- oid8eq(&(pgProcP->proargtypes[0]), argTypes))
- FoundMatch = true;
- else ReleaseBuffer(buffer);
- }
- } else ScanComplete = true;
- }
-
- if (FoundMatch) {
- Assert(HeapTupleIsValid(tuple));
- return_tuple = heap_copytuple(tuple);
- ReleaseBuffer(buffer);
- } else return_tuple = (HeapTuple)NULL;
-
- index_endscan(sd);
- index_close(idesc);
-
- return return_tuple;
+ Relation idesc;
+ ScanKeyData skey;
+ HeapTuple tuple; /* tuple being tested */
+ HeapTuple return_tuple; /* The tuple pointer we eventually
+ * return */
+ IndexScanDesc sd;
+ RetrieveIndexResult indexRes;
+ Buffer buffer;
+ Form_pg_proc pgProcP;
+ bool ScanComplete;
+
+ /*
+ * The index scan is complete, i.e. we've scanned everything there is
+ * to scan.
+ */
+ bool FoundMatch;
+
+ /*
+ * In scanning pg_proc, we have found a row that meets our search
+ * criteria.
+ */
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) NameEqualRegProcedure,
+ (Datum) procName);
+
+ idesc = index_openr(ProcedureNameIndex);
+
+ sd = index_beginscan(idesc, false, 1, &skey);
+
+ /*
+ * for now, we do the work usually done by CatalogIndexFetchTuple by
+ * hand, so that we can check that the other keys match. when
+ * multi-key indices are added, they will be used here.
+ */
+ tuple = (HeapTuple) NULL; /* initial value */
+ ScanComplete = false; /* Scan hasn't begun yet */
+ FoundMatch = false; /* No match yet; haven't even looked. */
+ while (!FoundMatch && !ScanComplete)
+ {
+ indexRes = index_getnext(sd, ForwardScanDirection);
+ if (indexRes)
+ {
+ ItemPointer iptr;
+
+ iptr = &indexRes->heap_iptr;
+ tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
+ pfree(indexRes);
+ if (HeapTupleIsValid(tuple))
+ {
+
+ /*
+ * Here's a row for a procedure that has the sought
+ * procedure name. To be a match, though, we need it to
+ * have the right number and type of arguments too, so we
+ * check that now.
+ */
+ pgProcP = (Form_pg_proc) GETSTRUCT(tuple);
+ if (pgProcP->pronargs == nargs &&
+ oid8eq(&(pgProcP->proargtypes[0]), argTypes))
+ FoundMatch = true;
+ else
+ ReleaseBuffer(buffer);
+ }
+ }
+ else
+ ScanComplete = true;
+ }
+
+ if (FoundMatch)
+ {
+ Assert(HeapTupleIsValid(tuple));
+ return_tuple = heap_copytuple(tuple);
+ ReleaseBuffer(buffer);
+ }
+ else
+ return_tuple = (HeapTuple) NULL;
+
+ index_endscan(sd);
+ index_close(idesc);
+
+ return return_tuple;
}
HeapTuple
-ProcedureSrcIndexScan(Relation heapRelation, text *procSrc)
+ProcedureSrcIndexScan(Relation heapRelation, text * procSrc)
{
- Relation idesc;
- IndexScanDesc sd;
- ScanKeyData skey;
- RetrieveIndexResult indexRes;
- HeapTuple tuple;
- Buffer buffer;
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)Anum_pg_proc_prosrc,
- (RegProcedure)TextEqualRegProcedure,
- (Datum)procSrc);
-
- idesc = index_openr(ProcedureSrcIndex);
- sd = index_beginscan(idesc, false, 1, &skey);
-
- indexRes = index_getnext(sd, ForwardScanDirection);
- if (indexRes) {
- ItemPointer iptr;
-
- iptr = &indexRes->heap_iptr;
- tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
- pfree(indexRes);
- } else
- tuple = (HeapTuple)NULL;
-
- if (HeapTupleIsValid(tuple)) {
- tuple = heap_copytuple(tuple);
- ReleaseBuffer(buffer);
- }
-
- index_endscan(sd);
-
- return tuple;
+ Relation idesc;
+ IndexScanDesc sd;
+ ScanKeyData skey;
+ RetrieveIndexResult indexRes;
+ HeapTuple tuple;
+ Buffer buffer;
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) Anum_pg_proc_prosrc,
+ (RegProcedure) TextEqualRegProcedure,
+ (Datum) procSrc);
+
+ idesc = index_openr(ProcedureSrcIndex);
+ sd = index_beginscan(idesc, false, 1, &skey);
+
+ indexRes = index_getnext(sd, ForwardScanDirection);
+ if (indexRes)
+ {
+ ItemPointer iptr;
+
+ iptr = &indexRes->heap_iptr;
+ tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
+ pfree(indexRes);
+ }
+ else
+ tuple = (HeapTuple) NULL;
+
+ if (HeapTupleIsValid(tuple))
+ {
+ tuple = heap_copytuple(tuple);
+ ReleaseBuffer(buffer);
+ }
+
+ index_endscan(sd);
+
+ return tuple;
}
HeapTuple
TypeOidIndexScan(Relation heapRelation, Oid typeId)
{
- Relation idesc;
- ScanKeyData skey;
- HeapTuple tuple;
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)ObjectIdEqualRegProcedure,
- (Datum)typeId);
-
- idesc = index_openr(TypeOidIndex);
- tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
-
- index_close(idesc);
-
- return tuple;
+ Relation idesc;
+ ScanKeyData skey;
+ HeapTuple tuple;
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) ObjectIdEqualRegProcedure,
+ (Datum) typeId);
+
+ idesc = index_openr(TypeOidIndex);
+ tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
+
+ index_close(idesc);
+
+ return tuple;
}
HeapTuple
TypeNameIndexScan(Relation heapRelation, char *typeName)
{
- Relation idesc;
- ScanKeyData skey;
- HeapTuple tuple;
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)NameEqualRegProcedure,
- (Datum)typeName);
-
- idesc = index_openr(TypeNameIndex);
- tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
-
- index_close(idesc);
-
- return tuple;
+ Relation idesc;
+ ScanKeyData skey;
+ HeapTuple tuple;
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) NameEqualRegProcedure,
+ (Datum) typeName);
+
+ idesc = index_openr(TypeNameIndex);
+ tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
+
+ index_close(idesc);
+
+ return tuple;
}
HeapTuple
ClassNameIndexScan(Relation heapRelation, char *relName)
{
- Relation idesc;
- ScanKeyData skey;
- HeapTuple tuple;
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)NameEqualRegProcedure,
- (Datum)relName);
-
- idesc = index_openr(ClassNameIndex);
-
- tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
-
- index_close(idesc);
- return tuple;
+ Relation idesc;
+ ScanKeyData skey;
+ HeapTuple tuple;
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) NameEqualRegProcedure,
+ (Datum) relName);
+
+ idesc = index_openr(ClassNameIndex);
+
+ tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
+
+ index_close(idesc);
+ return tuple;
}
HeapTuple
ClassOidIndexScan(Relation heapRelation, Oid relId)
{
- Relation idesc;
- ScanKeyData skey;
- HeapTuple tuple;
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)ObjectIdEqualRegProcedure,
- (Datum)relId);
-
- idesc = index_openr(ClassOidIndex);
- tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
-
- index_close(idesc);
-
- return tuple;
+ Relation idesc;
+ ScanKeyData skey;
+ HeapTuple tuple;
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) ObjectIdEqualRegProcedure,
+ (Datum) relId);
+
+ idesc = index_openr(ClassOidIndex);
+ tuple = CatalogIndexFetchTuple(heapRelation, idesc, &skey);
+
+ index_close(idesc);
+
+ return tuple;
}
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 13a3c48e9f4..540350bac9b 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* pg_aggregate.c--
- * routines to support manipulation of the pg_aggregate relation
+ * routines to support manipulation of the pg_aggregate relation
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.5 1997/07/24 20:11:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.6 1997/09/07 04:40:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,9 +24,9 @@
#include <catalog/pg_aggregate.h>
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
/* ----------------
@@ -34,288 +34,303 @@
*
* aggregates overloading has been added. Instead of the full
* overload support we have for functions, aggregate overloading only
- * applies to exact basetype matches. That is, we don't check the
+ * applies to exact basetype matches. That is, we don't check the
* the inheritance hierarchy
*
* OLD COMMENTS:
- * Currently, redefining aggregates using the same name is not
- * supported. In such a case, a warning is printed that the
- * aggregate already exists. If such is not the case, a new tuple
- * is created and inserted in the aggregate relation. The fields
- * of this tuple are aggregate name, owner id, 2 transition functions
- * (called aggtransfn1 and aggtransfn2), final function (aggfinalfn),
- * type of data on which aggtransfn1 operates (aggbasetype), return
- * types of the two transition functions (aggtranstype1 and
- * aggtranstype2), final return type (aggfinaltype), and initial values
- * for the two state transition functions (agginitval1 and agginitval2).
- * All types and functions must have been defined
- * prior to defining the aggregate.
- *
+ * Currently, redefining aggregates using the same name is not
+ * supported. In such a case, a warning is printed that the
+ * aggregate already exists. If such is not the case, a new tuple
+ * is created and inserted in the aggregate relation. The fields
+ * of this tuple are aggregate name, owner id, 2 transition functions
+ * (called aggtransfn1 and aggtransfn2), final function (aggfinalfn),
+ * type of data on which aggtransfn1 operates (aggbasetype), return
+ * types of the two transition functions (aggtranstype1 and
+ * aggtranstype2), final return type (aggfinaltype), and initial values
+ * for the two state transition functions (agginitval1 and agginitval2).
+ * All types and functions must have been defined
+ * prior to defining the aggregate.
+ *
* ---------------
*/
void
AggregateCreate(char *aggName,
- char *aggtransfn1Name,
- char *aggtransfn2Name,
- char *aggfinalfnName,
- char *aggbasetypeName,
- char *aggtransfn1typeName,
- char *aggtransfn2typeName,
- char *agginitval1,
- char *agginitval2)
+ char *aggtransfn1Name,
+ char *aggtransfn2Name,
+ char *aggfinalfnName,
+ char *aggbasetypeName,
+ char *aggtransfn1typeName,
+ char *aggtransfn2typeName,
+ char *agginitval1,
+ char *agginitval2)
{
- register i;
- Relation aggdesc;
- HeapTuple tup;
- char nulls[Natts_pg_aggregate];
- Datum values[Natts_pg_aggregate];
- Form_pg_proc proc;
- Oid xfn1 = InvalidOid;
- Oid xfn2 = InvalidOid;
- Oid ffn = InvalidOid;
- Oid xbase = InvalidOid;
- Oid xret1 = InvalidOid;
- Oid xret2 = InvalidOid;
- Oid fret = InvalidOid;
- Oid fnArgs[8];
- TupleDesc tupDesc;
-
- memset(fnArgs, 0, 8 * sizeof(Oid));
-
- /* sanity checks */
- if (!aggName)
- elog(WARN, "AggregateCreate: no aggregate name supplied");
-
- if (!aggtransfn1Name && !aggtransfn2Name)
- elog(WARN, "AggregateCreate: aggregate must have at least one transition function");
-
- tup = SearchSysCacheTuple(TYPNAME,
- PointerGetDatum(aggbasetypeName),
- 0,0,0);
- if(!HeapTupleIsValid(tup))
- elog(WARN, "AggregateCreate: Type '%s' undefined",aggbasetypeName);
- xbase = tup->t_oid;
+ register i;
+ Relation aggdesc;
+ HeapTuple tup;
+ char nulls[Natts_pg_aggregate];
+ Datum values[Natts_pg_aggregate];
+ Form_pg_proc proc;
+ Oid xfn1 = InvalidOid;
+ Oid xfn2 = InvalidOid;
+ Oid ffn = InvalidOid;
+ Oid xbase = InvalidOid;
+ Oid xret1 = InvalidOid;
+ Oid xret2 = InvalidOid;
+ Oid fret = InvalidOid;
+ Oid fnArgs[8];
+ TupleDesc tupDesc;
+
+ memset(fnArgs, 0, 8 * sizeof(Oid));
+
+ /* sanity checks */
+ if (!aggName)
+ elog(WARN, "AggregateCreate: no aggregate name supplied");
+
+ if (!aggtransfn1Name && !aggtransfn2Name)
+ elog(WARN, "AggregateCreate: aggregate must have at least one transition function");
+
+ tup = SearchSysCacheTuple(TYPNAME,
+ PointerGetDatum(aggbasetypeName),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(WARN, "AggregateCreate: Type '%s' undefined", aggbasetypeName);
+ xbase = tup->t_oid;
+
+ if (aggtransfn1Name)
+ {
+ tup = SearchSysCacheTuple(TYPNAME,
+ PointerGetDatum(aggtransfn1typeName),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(WARN, "AggregateCreate: Type '%s' undefined",
+ aggtransfn1typeName);
+ xret1 = tup->t_oid;
+
+ fnArgs[0] = xret1;
+ fnArgs[1] = xbase;
+ tup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(aggtransfn1Name),
+ Int32GetDatum(2),
+ PointerGetDatum(fnArgs),
+ 0);
+ if (!HeapTupleIsValid(tup))
+ elog(WARN, "AggregateCreate: '%s('%s', '%s') does not exist",
+ aggtransfn1Name, aggtransfn1typeName, aggbasetypeName);
+ if (((Form_pg_proc) GETSTRUCT(tup))->prorettype != xret1)
+ elog(WARN, "AggregateCreate: return type of '%s' is not '%s'",
+ aggtransfn1Name,
+ aggtransfn1typeName);
+ xfn1 = tup->t_oid;
+ if (!OidIsValid(xfn1) || !OidIsValid(xret1) ||
+ !OidIsValid(xbase))
+ elog(WARN, "AggregateCreate: bogus function '%s'", aggfinalfnName);
+ }
+
+ if (aggtransfn2Name)
+ {
+ tup = SearchSysCacheTuple(TYPNAME,
+ PointerGetDatum(aggtransfn2typeName),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(WARN, "AggregateCreate: Type '%s' undefined",
+ aggtransfn2typeName);
+ xret2 = tup->t_oid;
+
+ fnArgs[0] = xret2;
+ fnArgs[1] = 0;
+ tup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(aggtransfn2Name),
+ Int32GetDatum(1),
+ PointerGetDatum(fnArgs),
+ 0);
+ if (!HeapTupleIsValid(tup))
+ elog(WARN, "AggregateCreate: '%s'('%s') does not exist",
+ aggtransfn2Name, aggtransfn2typeName);
+ if (((Form_pg_proc) GETSTRUCT(tup))->prorettype != xret2)
+ elog(WARN, "AggregateCreate: return type of '%s' is not '%s'",
+ aggtransfn2Name, aggtransfn2typeName);
+ xfn2 = tup->t_oid;
+ if (!OidIsValid(xfn2) || !OidIsValid(xret2))
+ elog(WARN, "AggregateCreate: bogus function '%s'", aggfinalfnName);
+ }
+
+ tup = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggName),
+ ObjectIdGetDatum(xbase),
+ 0, 0);
+ if (HeapTupleIsValid(tup))
+ elog(WARN,
+ "AggregateCreate: aggregate '%s' with base type '%s' already exists",
+ aggName, aggbasetypeName);
+
+ /* more sanity checks */
+ if (aggtransfn1Name && aggtransfn2Name && !aggfinalfnName)
+ elog(WARN, "AggregateCreate: Aggregate must have final function with both transition functions");
- if (aggtransfn1Name) {
- tup = SearchSysCacheTuple(TYPNAME,
- PointerGetDatum(aggtransfn1typeName),
- 0,0,0);
- if(!HeapTupleIsValid(tup))
- elog(WARN, "AggregateCreate: Type '%s' undefined",
- aggtransfn1typeName);
- xret1 = tup->t_oid;
-
- fnArgs[0] = xret1;
- fnArgs[1] = xbase;
- tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(aggtransfn1Name),
- Int32GetDatum(2),
- PointerGetDatum(fnArgs),
- 0);
- if(!HeapTupleIsValid(tup))
- elog(WARN, "AggregateCreate: '%s('%s', '%s') does not exist",
- aggtransfn1Name, aggtransfn1typeName, aggbasetypeName);
- if (((Form_pg_proc) GETSTRUCT(tup))->prorettype != xret1)
- elog(WARN, "AggregateCreate: return type of '%s' is not '%s'",
- aggtransfn1Name,
- aggtransfn1typeName);
- xfn1 = tup->t_oid;
- if (!OidIsValid(xfn1) || !OidIsValid(xret1) ||
- !OidIsValid(xbase))
- elog(WARN, "AggregateCreate: bogus function '%s'", aggfinalfnName);
- }
-
- if (aggtransfn2Name) {
- tup = SearchSysCacheTuple(TYPNAME,
- PointerGetDatum(aggtransfn2typeName),
- 0,0,0);
- if(!HeapTupleIsValid(tup))
- elog(WARN, "AggregateCreate: Type '%s' undefined",
- aggtransfn2typeName);
- xret2 = tup->t_oid;
-
- fnArgs[0] = xret2;
- fnArgs[1] = 0;
- tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(aggtransfn2Name),
- Int32GetDatum(1),
- PointerGetDatum(fnArgs),
- 0);
- if(!HeapTupleIsValid(tup))
- elog(WARN, "AggregateCreate: '%s'('%s') does not exist",
- aggtransfn2Name, aggtransfn2typeName);
- if (((Form_pg_proc) GETSTRUCT(tup))->prorettype != xret2)
- elog(WARN, "AggregateCreate: return type of '%s' is not '%s'",
- aggtransfn2Name, aggtransfn2typeName);
- xfn2 = tup->t_oid;
- if (!OidIsValid(xfn2) || !OidIsValid(xret2))
- elog(WARN, "AggregateCreate: bogus function '%s'",aggfinalfnName);
- }
-
- tup = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggName),
- ObjectIdGetDatum(xbase),
- 0,0);
- if (HeapTupleIsValid(tup))
- elog(WARN,
- "AggregateCreate: aggregate '%s' with base type '%s' already exists",
- aggName, aggbasetypeName);
+ if ((!aggtransfn1Name || !aggtransfn2Name) && aggfinalfnName)
+ elog(WARN, "AggregateCreate: Aggregate cannot have final function without both transition functions");
- /* more sanity checks */
- if (aggtransfn1Name && aggtransfn2Name && !aggfinalfnName)
- elog(WARN, "AggregateCreate: Aggregate must have final function with both transition functions");
-
- if ((!aggtransfn1Name || !aggtransfn2Name) && aggfinalfnName)
- elog(WARN, "AggregateCreate: Aggregate cannot have final function without both transition functions");
-
- if (aggfinalfnName) {
- fnArgs[0] = xret1;
- fnArgs[1] = xret2;
- tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(aggfinalfnName),
- Int32GetDatum(2),
- PointerGetDatum(fnArgs),
- 0);
- if(!HeapTupleIsValid(tup))
- elog(WARN, "AggregateCreate: '%s'('%s','%s') does not exist",
- aggfinalfnName, aggtransfn1typeName, aggtransfn2typeName);
- ffn = tup->t_oid;
- proc = (Form_pg_proc) GETSTRUCT(tup);
- fret = proc->prorettype;
- if (!OidIsValid(ffn) || !OidIsValid(fret))
- elog(WARN, "AggregateCreate: bogus function '%s'", aggfinalfnName);
- }
-
- /*
- * If transition function 2 is defined, it must have an initial value,
- * whereas transition function 1 does not, which allows man and min
- * aggregates to return NULL if they are evaluated on empty sets.
- */
- if (OidIsValid(xfn2) && !agginitval2)
- elog(WARN, "AggregateCreate: transition function 2 MUST have an initial value");
-
- /* initialize nulls and values */
- for(i=0; i < Natts_pg_aggregate; i++) {
- nulls[i] = ' ';
- values[i] = (Datum)NULL;
- }
- values[Anum_pg_aggregate_aggname-1] = PointerGetDatum(aggName);
- values[Anum_pg_aggregate_aggowner-1] =
- Int32GetDatum(GetUserId());
- values[Anum_pg_aggregate_aggtransfn1-1] =
- ObjectIdGetDatum(xfn1);
- values[Anum_pg_aggregate_aggtransfn2-1] =
- ObjectIdGetDatum(xfn2);
- values[Anum_pg_aggregate_aggfinalfn-1] =
- ObjectIdGetDatum(ffn);
-
- values[Anum_pg_aggregate_aggbasetype-1] =
- ObjectIdGetDatum(xbase);
- if (!OidIsValid(xfn1)) {
- values[Anum_pg_aggregate_aggtranstype1-1] =
- ObjectIdGetDatum(InvalidOid);
- values[Anum_pg_aggregate_aggtranstype2-1] =
- ObjectIdGetDatum(xret2);
- values[Anum_pg_aggregate_aggfinaltype-1] =
- ObjectIdGetDatum(xret2);
- }
- else if (!OidIsValid(xfn2)) {
- values[Anum_pg_aggregate_aggtranstype1-1] =
- ObjectIdGetDatum(xret1);
- values[Anum_pg_aggregate_aggtranstype2-1] =
- ObjectIdGetDatum(InvalidOid);
- values[Anum_pg_aggregate_aggfinaltype-1] =
- ObjectIdGetDatum(xret1);
- }
- else {
- values[Anum_pg_aggregate_aggtranstype1-1] =
- ObjectIdGetDatum(xret1);
- values[Anum_pg_aggregate_aggtranstype2-1] =
- ObjectIdGetDatum(xret2);
- values[Anum_pg_aggregate_aggfinaltype-1] =
- ObjectIdGetDatum(fret);
- }
-
- if (agginitval1)
- values[Anum_pg_aggregate_agginitval1-1] = PointerGetDatum(textin(agginitval1));
- else
- nulls[Anum_pg_aggregate_agginitval1-1] = 'n';
-
- if (agginitval2)
- values[Anum_pg_aggregate_agginitval2-1] = PointerGetDatum(textin(agginitval2));
- else
- nulls[Anum_pg_aggregate_agginitval2-1] = 'n';
-
- if (!RelationIsValid(aggdesc = heap_openr(AggregateRelationName)))
- elog(WARN, "AggregateCreate: could not open '%s'",
- AggregateRelationName);
+ if (aggfinalfnName)
+ {
+ fnArgs[0] = xret1;
+ fnArgs[1] = xret2;
+ tup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(aggfinalfnName),
+ Int32GetDatum(2),
+ PointerGetDatum(fnArgs),
+ 0);
+ if (!HeapTupleIsValid(tup))
+ elog(WARN, "AggregateCreate: '%s'('%s','%s') does not exist",
+ aggfinalfnName, aggtransfn1typeName, aggtransfn2typeName);
+ ffn = tup->t_oid;
+ proc = (Form_pg_proc) GETSTRUCT(tup);
+ fret = proc->prorettype;
+ if (!OidIsValid(ffn) || !OidIsValid(fret))
+ elog(WARN, "AggregateCreate: bogus function '%s'", aggfinalfnName);
+ }
- tupDesc = aggdesc->rd_att;
- if (!HeapTupleIsValid(tup = heap_formtuple(tupDesc,
- values,
- nulls)))
- elog(WARN, "AggregateCreate: heap_formtuple failed");
- if (!OidIsValid(heap_insert(aggdesc, tup)))
- elog(WARN, "AggregateCreate: heap_insert failed");
- heap_close(aggdesc);
+ /*
+ * If transition function 2 is defined, it must have an initial value,
+ * whereas transition function 1 does not, which allows man and min
+ * aggregates to return NULL if they are evaluated on empty sets.
+ */
+ if (OidIsValid(xfn2) && !agginitval2)
+ elog(WARN, "AggregateCreate: transition function 2 MUST have an initial value");
+
+ /* initialize nulls and values */
+ for (i = 0; i < Natts_pg_aggregate; i++)
+ {
+ nulls[i] = ' ';
+ values[i] = (Datum) NULL;
+ }
+ values[Anum_pg_aggregate_aggname - 1] = PointerGetDatum(aggName);
+ values[Anum_pg_aggregate_aggowner - 1] =
+ Int32GetDatum(GetUserId());
+ values[Anum_pg_aggregate_aggtransfn1 - 1] =
+ ObjectIdGetDatum(xfn1);
+ values[Anum_pg_aggregate_aggtransfn2 - 1] =
+ ObjectIdGetDatum(xfn2);
+ values[Anum_pg_aggregate_aggfinalfn - 1] =
+ ObjectIdGetDatum(ffn);
+
+ values[Anum_pg_aggregate_aggbasetype - 1] =
+ ObjectIdGetDatum(xbase);
+ if (!OidIsValid(xfn1))
+ {
+ values[Anum_pg_aggregate_aggtranstype1 - 1] =
+ ObjectIdGetDatum(InvalidOid);
+ values[Anum_pg_aggregate_aggtranstype2 - 1] =
+ ObjectIdGetDatum(xret2);
+ values[Anum_pg_aggregate_aggfinaltype - 1] =
+ ObjectIdGetDatum(xret2);
+ }
+ else if (!OidIsValid(xfn2))
+ {
+ values[Anum_pg_aggregate_aggtranstype1 - 1] =
+ ObjectIdGetDatum(xret1);
+ values[Anum_pg_aggregate_aggtranstype2 - 1] =
+ ObjectIdGetDatum(InvalidOid);
+ values[Anum_pg_aggregate_aggfinaltype - 1] =
+ ObjectIdGetDatum(xret1);
+ }
+ else
+ {
+ values[Anum_pg_aggregate_aggtranstype1 - 1] =
+ ObjectIdGetDatum(xret1);
+ values[Anum_pg_aggregate_aggtranstype2 - 1] =
+ ObjectIdGetDatum(xret2);
+ values[Anum_pg_aggregate_aggfinaltype - 1] =
+ ObjectIdGetDatum(fret);
+ }
+
+ if (agginitval1)
+ values[Anum_pg_aggregate_agginitval1 - 1] = PointerGetDatum(textin(agginitval1));
+ else
+ nulls[Anum_pg_aggregate_agginitval1 - 1] = 'n';
+
+ if (agginitval2)
+ values[Anum_pg_aggregate_agginitval2 - 1] = PointerGetDatum(textin(agginitval2));
+ else
+ nulls[Anum_pg_aggregate_agginitval2 - 1] = 'n';
+
+ if (!RelationIsValid(aggdesc = heap_openr(AggregateRelationName)))
+ elog(WARN, "AggregateCreate: could not open '%s'",
+ AggregateRelationName);
+
+ tupDesc = aggdesc->rd_att;
+ if (!HeapTupleIsValid(tup = heap_formtuple(tupDesc,
+ values,
+ nulls)))
+ elog(WARN, "AggregateCreate: heap_formtuple failed");
+ if (!OidIsValid(heap_insert(aggdesc, tup)))
+ elog(WARN, "AggregateCreate: heap_insert failed");
+ heap_close(aggdesc);
}
-char *
-AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
+char *
+AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool * isNull)
{
- HeapTuple tup;
- Relation aggRel;
- int initValAttno;
- Oid transtype;
- text *textInitVal;
- char *strInitVal, *initVal;
-
- Assert(PointerIsValid(aggName));
- Assert(PointerIsValid(isNull));
- Assert(xfuncno == 1 || xfuncno == 2);
+ HeapTuple tup;
+ Relation aggRel;
+ int initValAttno;
+ Oid transtype;
+ text *textInitVal;
+ char *strInitVal,
+ *initVal;
+
+ Assert(PointerIsValid(aggName));
+ Assert(PointerIsValid(isNull));
+ Assert(xfuncno == 1 || xfuncno == 2);
+
+ tup = SearchSysCacheTuple(AGGNAME,
+ PointerGetDatum(aggName),
+ PointerGetDatum(basetype),
+ 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(WARN, "AggNameGetInitVal: cache lookup failed for aggregate '%s'",
+ aggName);
+ if (xfuncno == 1)
+ {
+ transtype = ((Form_pg_aggregate) GETSTRUCT(tup))->aggtranstype1;
+ initValAttno = Anum_pg_aggregate_agginitval1;
+ }
+ else
+ /* can only be 1 or 2 */
+ {
+ transtype = ((Form_pg_aggregate) GETSTRUCT(tup))->aggtranstype2;
+ initValAttno = Anum_pg_aggregate_agginitval2;
+ }
- tup = SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(aggName),
- PointerGetDatum(basetype),
- 0,0);
- if (!HeapTupleIsValid(tup))
- elog(WARN, "AggNameGetInitVal: cache lookup failed for aggregate '%s'",
- aggName);
- if (xfuncno == 1) {
- transtype = ((Form_pg_aggregate) GETSTRUCT(tup))->aggtranstype1;
- initValAttno = Anum_pg_aggregate_agginitval1;
- }
- else /* can only be 1 or 2 */ {
- transtype = ((Form_pg_aggregate) GETSTRUCT(tup))->aggtranstype2;
- initValAttno = Anum_pg_aggregate_agginitval2;
- }
-
- aggRel = heap_openr(AggregateRelationName);
- if (!RelationIsValid(aggRel))
- elog(WARN, "AggNameGetInitVal: could not open \"%-.*s\"",
- AggregateRelationName);
- /*
- * must use fastgetattr in case one or other of the init values is NULL
- */
- textInitVal = (text *) fastgetattr(tup, initValAttno,
- RelationGetTupleDescriptor(aggRel),
- isNull);
- if (!PointerIsValid(textInitVal))
- *isNull = true;
- if (*isNull) {
+ aggRel = heap_openr(AggregateRelationName);
+ if (!RelationIsValid(aggRel))
+ elog(WARN, "AggNameGetInitVal: could not open \"%-.*s\"",
+ AggregateRelationName);
+
+ /*
+ * must use fastgetattr in case one or other of the init values is
+ * NULL
+ */
+ textInitVal = (text *) fastgetattr(tup, initValAttno,
+ RelationGetTupleDescriptor(aggRel),
+ isNull);
+ if (!PointerIsValid(textInitVal))
+ *isNull = true;
+ if (*isNull)
+ {
+ heap_close(aggRel);
+ return ((char *) NULL);
+ }
+ strInitVal = textout(textInitVal);
heap_close(aggRel);
- return((char *) NULL);
- }
- strInitVal = textout(textInitVal);
- heap_close(aggRel);
-
- tup = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(transtype),
- 0,0,0);
- if (!HeapTupleIsValid(tup)) {
+
+ tup = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(transtype),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ {
+ pfree(strInitVal);
+ elog(WARN, "AggNameGetInitVal: cache lookup failed on aggregate transition function return type");
+ }
+ initVal = fmgr(((TypeTupleForm) GETSTRUCT(tup))->typinput, strInitVal, -1);
pfree(strInitVal);
- elog(WARN, "AggNameGetInitVal: cache lookup failed on aggregate transition function return type");
- }
- initVal = fmgr(((TypeTupleForm) GETSTRUCT(tup))->typinput, strInitVal, -1);
- pfree(strInitVal);
- return(initVal);
+ return (initVal);
}
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 1151f9f2e69..67a3a2f1495 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_operator.c--
- * routines to support manipulation of the pg_operator relation
+ * routines to support manipulation of the pg_operator relation
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.11 1997/08/18 20:52:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.12 1997/09/07 04:40:27 momjian Exp $
*
* NOTES
- * these routines moved here from commands/define.c and somewhat cleaned up.
- *
+ * these routines moved here from commands/define.c and somewhat cleaned up.
+ *
*-------------------------------------------------------------------------
*/
#include <postgres.h>
@@ -26,28 +26,33 @@
#include <fmgr.h>
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static Oid OperatorGetWithOpenRelation(Relation pg_operator_desc,
- const char *operatorName,
- Oid leftObjectId,
- Oid rightObjectId );
-static Oid OperatorGet(char *operatorName,
- char *leftTypeName,
- char *rightTypeName );
-
-static Oid OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
- char *operatorName,
- Oid leftObjectId,
- Oid rightObjectId );
-static Oid OperatorShellMake(char *operatorName,
- char *leftTypeName,
- char *rightTypeName );
-
-static void OperatorDef(char *operatorName,
+static Oid
+OperatorGetWithOpenRelation(Relation pg_operator_desc,
+ const char *operatorName,
+ Oid leftObjectId,
+ Oid rightObjectId);
+static Oid
+OperatorGet(char *operatorName,
+ char *leftTypeName,
+ char *rightTypeName);
+
+static Oid
+OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
+ char *operatorName,
+ Oid leftObjectId,
+ Oid rightObjectId);
+static Oid
+OperatorShellMake(char *operatorName,
+ char *leftTypeName,
+ char *rightTypeName);
+
+static void
+OperatorDef(char *operatorName,
int definedOK,
char *leftTypeName,
char *rightTypeName,
@@ -60,289 +65,292 @@ static void OperatorDef(char *operatorName,
char *oinName,
bool canHash,
char *leftSortName,
- char *rightSortName );
-static void OperatorUpd(Oid baseId , Oid commId , Oid negId );
-
+ char *rightSortName);
+static void OperatorUpd(Oid baseId, Oid commId, Oid negId);
+
/* ----------------------------------------------------------------
- * OperatorGetWithOpenRelation
+ * OperatorGetWithOpenRelation
*
- * preforms a scan on pg_operator for an operator tuple
- * with given name and left/right type oids.
+ * preforms a scan on pg_operator for an operator tuple
+ * with given name and left/right type oids.
* ----------------------------------------------------------------
- * pg_operator_desc -- reldesc for pg_operator
- * operatorName -- name of operator to fetch
- * leftObjectId -- left oid of operator to fetch
- * rightObjectId -- right oid of operator to fetch
+ * pg_operator_desc -- reldesc for pg_operator
+ * operatorName -- name of operator to fetch
+ * leftObjectId -- left oid of operator to fetch
+ * rightObjectId -- right oid of operator to fetch
*/
-static Oid
+static Oid
OperatorGetWithOpenRelation(Relation pg_operator_desc,
- const char *operatorName,
- Oid leftObjectId,
- Oid rightObjectId)
+ const char *operatorName,
+ Oid leftObjectId,
+ Oid rightObjectId)
{
- HeapScanDesc pg_operator_scan;
- Oid operatorObjectId;
- HeapTuple tup;
-
- static ScanKeyData opKey[3] = {
- { 0, Anum_pg_operator_oprname, NameEqualRegProcedure },
- { 0, Anum_pg_operator_oprleft, ObjectIdEqualRegProcedure },
- { 0, Anum_pg_operator_oprright, ObjectIdEqualRegProcedure },
- };
-
- fmgr_info(NameEqualRegProcedure,
- &opKey[0].sk_func, &opKey[0].sk_nargs);
- fmgr_info(ObjectIdEqualRegProcedure,
- &opKey[1].sk_func, &opKey[1].sk_nargs);
- fmgr_info(ObjectIdEqualRegProcedure,
- &opKey[2].sk_func, &opKey[2].sk_nargs);
-
- /* ----------------
- * form scan key
- * ----------------
- */
- opKey[0].sk_argument = PointerGetDatum(operatorName);
- opKey[1].sk_argument = ObjectIdGetDatum(leftObjectId);
- opKey[2].sk_argument = ObjectIdGetDatum(rightObjectId);
-
- /* ----------------
- * begin the scan
- * ----------------
- */
- pg_operator_scan = heap_beginscan(pg_operator_desc,
- 0,
- SelfTimeQual,
- 3,
- opKey);
-
- /* ----------------
- * fetch the operator tuple, if it exists, and determine
- * the proper return oid value.
- * ----------------
- */
- tup = heap_getnext(pg_operator_scan, 0, (Buffer *) 0);
- operatorObjectId = HeapTupleIsValid(tup) ? tup->t_oid : InvalidOid;
-
- /* ----------------
- * close the scan and return the oid.
- * ----------------
- */
- heap_endscan(pg_operator_scan);
-
- return
- operatorObjectId;
+ HeapScanDesc pg_operator_scan;
+ Oid operatorObjectId;
+ HeapTuple tup;
+
+ static ScanKeyData opKey[3] = {
+ {0, Anum_pg_operator_oprname, NameEqualRegProcedure},
+ {0, Anum_pg_operator_oprleft, ObjectIdEqualRegProcedure},
+ {0, Anum_pg_operator_oprright, ObjectIdEqualRegProcedure},
+ };
+
+ fmgr_info(NameEqualRegProcedure,
+ &opKey[0].sk_func, &opKey[0].sk_nargs);
+ fmgr_info(ObjectIdEqualRegProcedure,
+ &opKey[1].sk_func, &opKey[1].sk_nargs);
+ fmgr_info(ObjectIdEqualRegProcedure,
+ &opKey[2].sk_func, &opKey[2].sk_nargs);
+
+ /* ----------------
+ * form scan key
+ * ----------------
+ */
+ opKey[0].sk_argument = PointerGetDatum(operatorName);
+ opKey[1].sk_argument = ObjectIdGetDatum(leftObjectId);
+ opKey[2].sk_argument = ObjectIdGetDatum(rightObjectId);
+
+ /* ----------------
+ * begin the scan
+ * ----------------
+ */
+ pg_operator_scan = heap_beginscan(pg_operator_desc,
+ 0,
+ SelfTimeQual,
+ 3,
+ opKey);
+
+ /* ----------------
+ * fetch the operator tuple, if it exists, and determine
+ * the proper return oid value.
+ * ----------------
+ */
+ tup = heap_getnext(pg_operator_scan, 0, (Buffer *) 0);
+ operatorObjectId = HeapTupleIsValid(tup) ? tup->t_oid : InvalidOid;
+
+ /* ----------------
+ * close the scan and return the oid.
+ * ----------------
+ */
+ heap_endscan(pg_operator_scan);
+
+ return
+ operatorObjectId;
}
/* ----------------------------------------------------------------
- * OperatorGet
+ * OperatorGet
*
- * finds the operator associated with the specified name
- * and left and right type names.
+ * finds the operator associated with the specified name
+ * and left and right type names.
* ----------------------------------------------------------------
*/
-static Oid
+static Oid
OperatorGet(char *operatorName,
- char *leftTypeName,
- char *rightTypeName)
+ char *leftTypeName,
+ char *rightTypeName)
{
- Relation pg_operator_desc;
-
- Oid operatorObjectId;
- Oid leftObjectId = InvalidOid;
- Oid rightObjectId = InvalidOid;
- bool leftDefined = false;
- bool rightDefined = false;
-
- /* ----------------
- * look up the operator types.
- *
- * Note: types must be defined before operators
- * ----------------
- */
- if (leftTypeName) {
- leftObjectId = TypeGet(leftTypeName, &leftDefined);
-
- if (!OidIsValid(leftObjectId) || !leftDefined)
- elog(WARN, "OperatorGet: left type '%s' nonexistent",leftTypeName);
- }
-
- if (rightTypeName) {
- rightObjectId = TypeGet(rightTypeName, &rightDefined);
-
- if (!OidIsValid(rightObjectId) || !rightDefined)
- elog(WARN, "OperatorGet: right type '%s' nonexistent",
- rightTypeName);
- }
-
- if (!((OidIsValid(leftObjectId) && leftDefined) ||
- (OidIsValid(rightObjectId) && rightDefined)))
- elog(WARN, "OperatorGet: no argument types??");
-
- /* ----------------
- * open the pg_operator relation
- * ----------------
- */
- pg_operator_desc = heap_openr(OperatorRelationName);
-
- /* ----------------
- * get the oid for the operator with the appropriate name
- * and left/right types.
- * ----------------
- */
- operatorObjectId = OperatorGetWithOpenRelation(pg_operator_desc,
- operatorName,
- leftObjectId,
- rightObjectId);
-
- /* ----------------
- * close the relation and return the operator oid.
- * ----------------
- */
- heap_close(pg_operator_desc);
-
- return
- operatorObjectId;
+ Relation pg_operator_desc;
+
+ Oid operatorObjectId;
+ Oid leftObjectId = InvalidOid;
+ Oid rightObjectId = InvalidOid;
+ bool leftDefined = false;
+ bool rightDefined = false;
+
+ /* ----------------
+ * look up the operator types.
+ *
+ * Note: types must be defined before operators
+ * ----------------
+ */
+ if (leftTypeName)
+ {
+ leftObjectId = TypeGet(leftTypeName, &leftDefined);
+
+ if (!OidIsValid(leftObjectId) || !leftDefined)
+ elog(WARN, "OperatorGet: left type '%s' nonexistent", leftTypeName);
+ }
+
+ if (rightTypeName)
+ {
+ rightObjectId = TypeGet(rightTypeName, &rightDefined);
+
+ if (!OidIsValid(rightObjectId) || !rightDefined)
+ elog(WARN, "OperatorGet: right type '%s' nonexistent",
+ rightTypeName);
+ }
+
+ if (!((OidIsValid(leftObjectId) && leftDefined) ||
+ (OidIsValid(rightObjectId) && rightDefined)))
+ elog(WARN, "OperatorGet: no argument types??");
+
+ /* ----------------
+ * open the pg_operator relation
+ * ----------------
+ */
+ pg_operator_desc = heap_openr(OperatorRelationName);
+
+ /* ----------------
+ * get the oid for the operator with the appropriate name
+ * and left/right types.
+ * ----------------
+ */
+ operatorObjectId = OperatorGetWithOpenRelation(pg_operator_desc,
+ operatorName,
+ leftObjectId,
+ rightObjectId);
+
+ /* ----------------
+ * close the relation and return the operator oid.
+ * ----------------
+ */
+ heap_close(pg_operator_desc);
+
+ return
+ operatorObjectId;
}
/* ----------------------------------------------------------------
- * OperatorShellMakeWithOpenRelation
+ * OperatorShellMakeWithOpenRelation
*
* ----------------------------------------------------------------
*/
-static Oid
+static Oid
OperatorShellMakeWithOpenRelation(Relation pg_operator_desc,
- char *operatorName,
- Oid leftObjectId,
- Oid rightObjectId)
+ char *operatorName,
+ Oid leftObjectId,
+ Oid rightObjectId)
{
- register int i;
- HeapTuple tup;
- Datum values[ Natts_pg_operator ];
- char nulls[ Natts_pg_operator ];
- Oid operatorObjectId;
- TupleDesc tupDesc;
-
- /* ----------------
- * initialize our nulls[] and values[] arrays
- * ----------------
- */
- for (i = 0; i < Natts_pg_operator; ++i) {
- nulls[i] = ' ';
- values[i] = (Datum)NULL; /* redundant, but safe */
- }
-
- /* ----------------
- * initialize values[] with the type name and
- * ----------------
- */
- i = 0;
- values[i++] = PointerGetDatum(operatorName);
- values[i++] = Int32GetDatum(GetUserId());
- values[i++] = (Datum) (uint16) 0;
-
- values[i++] = (Datum)'b'; /* fill oprkind with a bogus value */
-
- values[i++] = (Datum) (bool) 0;
- values[i++] = (Datum) (bool) 0;
- values[i++] = ObjectIdGetDatum(leftObjectId); /* <-- left oid */
- values[i++] = ObjectIdGetDatum(rightObjectId); /* <-- right oid */
- values[i++] = ObjectIdGetDatum(InvalidOid);
- values[i++] = ObjectIdGetDatum(InvalidOid);
- values[i++] = ObjectIdGetDatum(InvalidOid);
- values[i++] = ObjectIdGetDatum(InvalidOid);
- values[i++] = ObjectIdGetDatum(InvalidOid);
- values[i++] = ObjectIdGetDatum(InvalidOid);
- values[i++] = ObjectIdGetDatum(InvalidOid);
- values[i++] = ObjectIdGetDatum(InvalidOid);
-
- /* ----------------
- * create a new operator tuple
- * ----------------
- */
- tupDesc = pg_operator_desc->rd_att;
-
- tup = heap_formtuple(tupDesc,
- values,
- nulls);
-
- /* ----------------
- * insert our "shell" operator tuple and
- * close the relation
- * ----------------
- */
- heap_insert(pg_operator_desc, tup);
- operatorObjectId = tup->t_oid;
-
- /* ----------------
- * free the tuple and return the operator oid
- * ----------------
- */
- pfree(tup);
-
- return
- operatorObjectId;
+ register int i;
+ HeapTuple tup;
+ Datum values[Natts_pg_operator];
+ char nulls[Natts_pg_operator];
+ Oid operatorObjectId;
+ TupleDesc tupDesc;
+
+ /* ----------------
+ * initialize our nulls[] and values[] arrays
+ * ----------------
+ */
+ for (i = 0; i < Natts_pg_operator; ++i)
+ {
+ nulls[i] = ' ';
+ values[i] = (Datum) NULL; /* redundant, but safe */
+ }
+
+ /* ----------------
+ * initialize values[] with the type name and
+ * ----------------
+ */
+ i = 0;
+ values[i++] = PointerGetDatum(operatorName);
+ values[i++] = Int32GetDatum(GetUserId());
+ values[i++] = (Datum) (uint16) 0;
+
+ values[i++] = (Datum) 'b'; /* fill oprkind with a bogus value */
+
+ values[i++] = (Datum) (bool) 0;
+ values[i++] = (Datum) (bool) 0;
+ values[i++] = ObjectIdGetDatum(leftObjectId); /* <-- left oid */
+ values[i++] = ObjectIdGetDatum(rightObjectId); /* <-- right oid */
+ values[i++] = ObjectIdGetDatum(InvalidOid);
+ values[i++] = ObjectIdGetDatum(InvalidOid);
+ values[i++] = ObjectIdGetDatum(InvalidOid);
+ values[i++] = ObjectIdGetDatum(InvalidOid);
+ values[i++] = ObjectIdGetDatum(InvalidOid);
+ values[i++] = ObjectIdGetDatum(InvalidOid);
+ values[i++] = ObjectIdGetDatum(InvalidOid);
+ values[i++] = ObjectIdGetDatum(InvalidOid);
+
+ /* ----------------
+ * create a new operator tuple
+ * ----------------
+ */
+ tupDesc = pg_operator_desc->rd_att;
+
+ tup = heap_formtuple(tupDesc,
+ values,
+ nulls);
+
+ /* ----------------
+ * insert our "shell" operator tuple and
+ * close the relation
+ * ----------------
+ */
+ heap_insert(pg_operator_desc, tup);
+ operatorObjectId = tup->t_oid;
+
+ /* ----------------
+ * free the tuple and return the operator oid
+ * ----------------
+ */
+ pfree(tup);
+
+ return
+ operatorObjectId;
}
/* ----------------------------------------------------------------
- * OperatorShellMake
+ * OperatorShellMake
*
- * Specify operator name and left and right type names,
- * fill an operator struct with this info and NULL's,
- * call heap_insert and return the Oid
- * to the caller.
+ * Specify operator name and left and right type names,
+ * fill an operator struct with this info and NULL's,
+ * call heap_insert and return the Oid
+ * to the caller.
* ----------------------------------------------------------------
*/
-static Oid
+static Oid
OperatorShellMake(char *operatorName,
- char *leftTypeName,
- char *rightTypeName)
-{
- Relation pg_operator_desc;
- Oid operatorObjectId;
-
- Oid leftObjectId = InvalidOid;
- Oid rightObjectId = InvalidOid;
- bool leftDefined = false;
- bool rightDefined = false;
-
- /* ----------------
- * get the left and right type oid's for this operator
- * ----------------
- */
- if (leftTypeName)
- leftObjectId = TypeGet(leftTypeName, &leftDefined);
-
- if (rightTypeName)
- rightObjectId = TypeGet(rightTypeName, &rightDefined);
-
- if (!((OidIsValid(leftObjectId) && leftDefined) ||
- (OidIsValid(rightObjectId) && rightDefined)))
- elog(WARN, "OperatorShellMake: no valid argument types??");
-
- /* ----------------
- * open pg_operator
- * ----------------
- */
- pg_operator_desc = heap_openr(OperatorRelationName);
-
- /* ----------------
- * add a "shell" operator tuple to the operator relation
- * and recover the shell tuple's oid.
- * ----------------
- */
- operatorObjectId =
- OperatorShellMakeWithOpenRelation(pg_operator_desc,
- operatorName,
- leftObjectId,
- rightObjectId);
- /* ----------------
- * close the operator relation and return the oid.
- * ----------------
- */
- heap_close(pg_operator_desc);
-
- return
- operatorObjectId;
+ char *leftTypeName,
+ char *rightTypeName)
+{
+ Relation pg_operator_desc;
+ Oid operatorObjectId;
+
+ Oid leftObjectId = InvalidOid;
+ Oid rightObjectId = InvalidOid;
+ bool leftDefined = false;
+ bool rightDefined = false;
+
+ /* ----------------
+ * get the left and right type oid's for this operator
+ * ----------------
+ */
+ if (leftTypeName)
+ leftObjectId = TypeGet(leftTypeName, &leftDefined);
+
+ if (rightTypeName)
+ rightObjectId = TypeGet(rightTypeName, &rightDefined);
+
+ if (!((OidIsValid(leftObjectId) && leftDefined) ||
+ (OidIsValid(rightObjectId) && rightDefined)))
+ elog(WARN, "OperatorShellMake: no valid argument types??");
+
+ /* ----------------
+ * open pg_operator
+ * ----------------
+ */
+ pg_operator_desc = heap_openr(OperatorRelationName);
+
+ /* ----------------
+ * add a "shell" operator tuple to the operator relation
+ * and recover the shell tuple's oid.
+ * ----------------
+ */
+ operatorObjectId =
+ OperatorShellMakeWithOpenRelation(pg_operator_desc,
+ operatorName,
+ leftObjectId,
+ rightObjectId);
+ /* ----------------
+ * close the operator relation and return the oid.
+ * ----------------
+ */
+ heap_close(pg_operator_desc);
+
+ return
+ operatorObjectId;
}
/* --------------------------------
@@ -352,7 +360,7 @@ OperatorShellMake(char *operatorName,
* specify operators that do not exist. For example, if operator
* "op" is being defined, the negator operator "negop" and the
* commutator "commop" can also be defined without specifying
- * any information other than their names. Since in order to
+ * any information other than their names. Since in order to
* add "op" to the PG_OPERATOR catalog, all the Oid's for these
* operators must be placed in the fields of "op", a forward
* declaration is done on the commutator and negator operators.
@@ -363,518 +371,552 @@ OperatorShellMake(char *operatorName,
* not available to the user as it is for type definition.
*
* Algorithm:
- *
- * check if operator already defined
- * if so issue error if not definedOk, this is a duplicate
- * but if definedOk, save the Oid -- filling in a shell
+ *
+ * check if operator already defined
+ * if so issue error if not definedOk, this is a duplicate
+ * but if definedOk, save the Oid -- filling in a shell
* get the attribute types from relation descriptor for pg_operator
* assign values to the fields of the operator:
- * operatorName
- * owner id (simply the user id of the caller)
- * precedence
- * operator "kind" either "b" for binary or "l" for left unary
- * isLeftAssociative boolean
- * canHash boolean
- * leftTypeObjectId -- type must already be defined
- * rightTypeObjectId -- this is optional, enter ObjectId=0 if none specified
- * resultType -- defer this, since it must be determined from
- * the pg_procedure catalog
- * commutatorObjectId -- if this is NULL, enter ObjectId=0
- * else if this already exists, enter it's ObjectId
- * else if this does not yet exist, and is not
- * the same as the main operatorName, then create
- * a shell and enter the new ObjectId
- * else if this does not exist but IS the same
- * name as the main operator, set the ObjectId=0.
- * Later OperatorCreate will make another call
- * to OperatorDef which will cause this field
- * to be filled in (because even though the names
- * will be switched, they are the same name and
- * at this point this ObjectId will then be defined)
- * negatorObjectId -- same as for commutatorObjectId
- * leftSortObjectId -- same as for commutatorObjectId
- * rightSortObjectId -- same as for commutatorObjectId
- * operatorProcedure -- must access the pg_procedure catalog to get the
- * ObjectId of the procedure that actually does the operator
- * actions this is required. Do an amgetattr to find out the
- * return type of the procedure
- * restrictionProcedure -- must access the pg_procedure catalog to get
- * the ObjectId but this is optional
- * joinProcedure -- same as restrictionProcedure
+ * operatorName
+ * owner id (simply the user id of the caller)
+ * precedence
+ * operator "kind" either "b" for binary or "l" for left unary
+ * isLeftAssociative boolean
+ * canHash boolean
+ * leftTypeObjectId -- type must already be defined
+ * rightTypeObjectId -- this is optional, enter ObjectId=0 if none specified
+ * resultType -- defer this, since it must be determined from
+ * the pg_procedure catalog
+ * commutatorObjectId -- if this is NULL, enter ObjectId=0
+ * else if this already exists, enter it's ObjectId
+ * else if this does not yet exist, and is not
+ * the same as the main operatorName, then create
+ * a shell and enter the new ObjectId
+ * else if this does not exist but IS the same
+ * name as the main operator, set the ObjectId=0.
+ * Later OperatorCreate will make another call
+ * to OperatorDef which will cause this field
+ * to be filled in (because even though the names
+ * will be switched, they are the same name and
+ * at this point this ObjectId will then be defined)
+ * negatorObjectId -- same as for commutatorObjectId
+ * leftSortObjectId -- same as for commutatorObjectId
+ * rightSortObjectId -- same as for commutatorObjectId
+ * operatorProcedure -- must access the pg_procedure catalog to get the
+ * ObjectId of the procedure that actually does the operator
+ * actions this is required. Do an amgetattr to find out the
+ * return type of the procedure
+ * restrictionProcedure -- must access the pg_procedure catalog to get
+ * the ObjectId but this is optional
+ * joinProcedure -- same as restrictionProcedure
* now either insert or replace the operator into the pg_operator catalog
* if the operator shell is being filled in
- * access the catalog in order to get a valid buffer
- * create a tuple using ModifyHeapTuple
- * get the t_ctid from the modified tuple and call RelationReplaceHeapTuple
+ * access the catalog in order to get a valid buffer
+ * create a tuple using ModifyHeapTuple
+ * get the t_ctid from the modified tuple and call RelationReplaceHeapTuple
* else if a new operator is being created
- * create a tuple using heap_formtuple
- * call heap_insert
+ * create a tuple using heap_formtuple
+ * call heap_insert
* --------------------------------
- * "X" indicates an optional argument (i.e. one that can be NULL)
- * operatorName; -- operator name
- * definedOK; -- operator can already have an oid?
- * leftTypeName; -- X left type name
- * rightTypeName; -- X right type name
- * procedureName; -- procedure oid for operator code
- * precedence; -- operator precedence
- * isLeftAssociative; -- operator is left associative?
- * commutatorName; -- X commutator operator name
- * negatorName; -- X negator operator name
- * restrictionName; -- X restriction sel. procedure name
- * joinName; -- X join sel. procedure name
- * canHash; -- possible hash operator?
- * leftSortName; -- X left sort operator
- * rightSortName; -- X right sort operator
+ * "X" indicates an optional argument (i.e. one that can be NULL)
+ * operatorName; -- operator name
+ * definedOK; -- operator can already have an oid?
+ * leftTypeName; -- X left type name
+ * rightTypeName; -- X right type name
+ * procedureName; -- procedure oid for operator code
+ * precedence; -- operator precedence
+ * isLeftAssociative; -- operator is left associative?
+ * commutatorName; -- X commutator operator name
+ * negatorName; -- X negator operator name
+ * restrictionName; -- X restriction sel. procedure name
+ * joinName; -- X join sel. procedure name
+ * canHash; -- possible hash operator?
+ * leftSortName; -- X left sort operator
+ * rightSortName; -- X right sort operator
*/
static void
OperatorDef(char *operatorName,
- int definedOK,
- char *leftTypeName,
- char *rightTypeName,
- char *procedureName,
- uint16 precedence,
- bool isLeftAssociative,
- char *commutatorName,
- char *negatorName,
- char *restrictionName,
- char *joinName,
- bool canHash,
- char *leftSortName,
- char *rightSortName)
+ int definedOK,
+ char *leftTypeName,
+ char *rightTypeName,
+ char *procedureName,
+ uint16 precedence,
+ bool isLeftAssociative,
+ char *commutatorName,
+ char *negatorName,
+ char *restrictionName,
+ char *joinName,
+ bool canHash,
+ char *leftSortName,
+ char *rightSortName)
{
- register i, j;
- Relation pg_operator_desc;
-
- HeapScanDesc pg_operator_scan;
- HeapTuple tup;
- Buffer buffer;
- ItemPointerData itemPointerData;
- char nulls[ Natts_pg_operator ];
- char replaces[ Natts_pg_operator ];
- Datum values[ Natts_pg_operator ];
- Oid other_oid = 0;
- Oid operatorObjectId;
- Oid leftTypeId = InvalidOid;
- Oid rightTypeId = InvalidOid;
- Oid commutatorId = InvalidOid;
- Oid negatorId = InvalidOid;
- bool leftDefined = false;
- bool rightDefined = false;
- char *name[4];
- Oid typeId[8];
- int nargs;
- TupleDesc tupDesc;
-
- static ScanKeyData opKey[3] = {
- { 0, Anum_pg_operator_oprname, NameEqualRegProcedure },
- { 0, Anum_pg_operator_oprleft, ObjectIdEqualRegProcedure },
- { 0, Anum_pg_operator_oprright, ObjectIdEqualRegProcedure },
- };
-
- fmgr_info(NameEqualRegProcedure,
- &opKey[0].sk_func, &opKey[0].sk_nargs);
- fmgr_info(ObjectIdEqualRegProcedure,
- &opKey[1].sk_func, &opKey[1].sk_nargs);
- fmgr_info(ObjectIdEqualRegProcedure,
- &opKey[2].sk_func, &opKey[2].sk_nargs);
-
- operatorObjectId = OperatorGet(operatorName,
- leftTypeName,
- rightTypeName);
-
- if (OidIsValid(operatorObjectId) && !definedOK)
- elog(WARN, "OperatorDef: operator \"%s\" already defined",
- operatorName);
-
- if (leftTypeName)
- leftTypeId = TypeGet(leftTypeName, &leftDefined);
-
- if (rightTypeName)
- rightTypeId = TypeGet(rightTypeName, &rightDefined);
-
- if (!((OidIsValid(leftTypeId && leftDefined)) ||
- (OidIsValid(rightTypeId && rightDefined))))
- elog(WARN, "OperatorGet: no argument types??");
-
- for (i = 0; i < Natts_pg_operator; ++i) {
- values[i] = (Datum)NULL;
- replaces[i] = 'r';
- nulls[i] = ' ';
- }
-
- /* ----------------
- * Look up registered procedures -- find the return type
- * of procedureName to place in "result" field.
- * Do this before shells are created so we don't
- * have to worry about deleting them later.
- * ----------------
- */
- memset(typeId, 0, 8 * sizeof(Oid));
- if (!leftTypeName) {
- typeId[0] = rightTypeId;
- nargs = 1;
- }
- else if (!rightTypeName) {
- typeId[0] = leftTypeId;
- nargs = 1;
- }
- else {
- typeId[0] = leftTypeId;
- typeId[1] = rightTypeId;
- nargs = 2;
- }
- tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(procedureName),
- Int32GetDatum(nargs),
- PointerGetDatum(typeId),
- 0);
-
- if (!PointerIsValid(tup))
- func_error("OperatorDef", procedureName, nargs, typeId);
-
- values[ Anum_pg_operator_oprcode-1 ] = ObjectIdGetDatum(tup->t_oid);
- values[ Anum_pg_operator_oprresult-1 ] =
- ObjectIdGetDatum(((Form_pg_proc)
- GETSTRUCT(tup))->prorettype);
-
- /* ----------------
- * find restriction
- * ----------------
- */
- if (restrictionName) { /* optional */
- memset(typeId, 0, 8 * sizeof(Oid));
- typeId[0] = OIDOID; /* operator OID */
- typeId[1] = OIDOID; /* relation OID */
- typeId[2] = INT2OID; /* attribute number */
- typeId[3] = 0; /* value - can be any type */
- typeId[4] = INT4OID; /* flags - left or right selectivity */
- tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(restrictionName),
- Int32GetDatum(5),
- PointerGetDatum(typeId),
- 0);
- if (!HeapTupleIsValid(tup))
- func_error("OperatorDef", restrictionName, 5, typeId);
-
- values[ Anum_pg_operator_oprrest-1 ] = ObjectIdGetDatum(tup->t_oid);
- } else
- values[ Anum_pg_operator_oprrest-1 ] = ObjectIdGetDatum(InvalidOid);
-
- /* ----------------
- * find join - only valid for binary operators
- * ----------------
- */
- if (joinName) { /* optional */
+ register i,
+ j;
+ Relation pg_operator_desc;
+
+ HeapScanDesc pg_operator_scan;
+ HeapTuple tup;
+ Buffer buffer;
+ ItemPointerData itemPointerData;
+ char nulls[Natts_pg_operator];
+ char replaces[Natts_pg_operator];
+ Datum values[Natts_pg_operator];
+ Oid other_oid = 0;
+ Oid operatorObjectId;
+ Oid leftTypeId = InvalidOid;
+ Oid rightTypeId = InvalidOid;
+ Oid commutatorId = InvalidOid;
+ Oid negatorId = InvalidOid;
+ bool leftDefined = false;
+ bool rightDefined = false;
+ char *name[4];
+ Oid typeId[8];
+ int nargs;
+ TupleDesc tupDesc;
+
+ static ScanKeyData opKey[3] = {
+ {0, Anum_pg_operator_oprname, NameEqualRegProcedure},
+ {0, Anum_pg_operator_oprleft, ObjectIdEqualRegProcedure},
+ {0, Anum_pg_operator_oprright, ObjectIdEqualRegProcedure},
+ };
+
+ fmgr_info(NameEqualRegProcedure,
+ &opKey[0].sk_func, &opKey[0].sk_nargs);
+ fmgr_info(ObjectIdEqualRegProcedure,
+ &opKey[1].sk_func, &opKey[1].sk_nargs);
+ fmgr_info(ObjectIdEqualRegProcedure,
+ &opKey[2].sk_func, &opKey[2].sk_nargs);
+
+ operatorObjectId = OperatorGet(operatorName,
+ leftTypeName,
+ rightTypeName);
+
+ if (OidIsValid(operatorObjectId) && !definedOK)
+ elog(WARN, "OperatorDef: operator \"%s\" already defined",
+ operatorName);
+
+ if (leftTypeName)
+ leftTypeId = TypeGet(leftTypeName, &leftDefined);
+
+ if (rightTypeName)
+ rightTypeId = TypeGet(rightTypeName, &rightDefined);
+
+ if (!((OidIsValid(leftTypeId && leftDefined)) ||
+ (OidIsValid(rightTypeId && rightDefined))))
+ elog(WARN, "OperatorGet: no argument types??");
+
+ for (i = 0; i < Natts_pg_operator; ++i)
+ {
+ values[i] = (Datum) NULL;
+ replaces[i] = 'r';
+ nulls[i] = ' ';
+ }
+
+ /* ----------------
+ * Look up registered procedures -- find the return type
+ * of procedureName to place in "result" field.
+ * Do this before shells are created so we don't
+ * have to worry about deleting them later.
+ * ----------------
+ */
memset(typeId, 0, 8 * sizeof(Oid));
- typeId[0] = OIDOID; /* operator OID */
- typeId[1] = OIDOID; /* relation OID 1 */
- typeId[2] = INT2OID; /* attribute number 1 */
- typeId[3] = OIDOID; /* relation OID 2 */
- typeId[4] = INT2OID; /* attribute number 2 */
-
+ if (!leftTypeName)
+ {
+ typeId[0] = rightTypeId;
+ nargs = 1;
+ }
+ else if (!rightTypeName)
+ {
+ typeId[0] = leftTypeId;
+ nargs = 1;
+ }
+ else
+ {
+ typeId[0] = leftTypeId;
+ typeId[1] = rightTypeId;
+ nargs = 2;
+ }
tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(joinName),
- Int32GetDatum(5),
- PointerGetDatum(typeId),
- 0);
- if (!HeapTupleIsValid(tup))
- func_error("OperatorDef", joinName, 5, typeId);
-
- values[Anum_pg_operator_oprjoin-1] = ObjectIdGetDatum(tup->t_oid);
- } else
- values[Anum_pg_operator_oprjoin-1] = ObjectIdGetDatum(InvalidOid);
-
- /* ----------------
- * set up values in the operator tuple
- * ----------------
- */
- i = 0;
- values[i++] = PointerGetDatum(operatorName);
- values[i++] = Int32GetDatum(GetUserId());
- values[i++] = UInt16GetDatum(precedence);
- values[i++] = leftTypeName ? (rightTypeName ? 'b' : 'r') : 'l';
- values[i++] = Int8GetDatum(isLeftAssociative);
- values[i++] = Int8GetDatum(canHash);
- values[i++] = ObjectIdGetDatum(leftTypeId);
- values[i++] = ObjectIdGetDatum(rightTypeId);
-
- ++i; /* Skip "prorettype", this was done above */
-
- /*
- * Set up the other operators. If they do not currently exist,
- * set up shells in order to get ObjectId's and call OperatorDef
- * again later to fill in the shells.
- */
- name[0] = commutatorName;
- name[1] = negatorName;
- name[2] = leftSortName;
- name[3] = rightSortName;
-
- for (j = 0; j < 4; ++j) {
- if (name[j]) {
-
- /* for the commutator, switch order of arguments */
- if (j == 0) {
- other_oid = OperatorGet(name[j], rightTypeName,leftTypeName);
- commutatorId = other_oid;
- } else {
- other_oid = OperatorGet(name[j], leftTypeName,rightTypeName);
- if (j == 1)
- negatorId = other_oid;
- }
-
- if (OidIsValid(other_oid)) /* already in catalogs */
- values[i++] = ObjectIdGetDatum(other_oid);
- else if (strcmp(operatorName, name[j]) != 0) {
- /* not in catalogs, different from operator */
-
- /* for the commutator, switch order of arguments */
- if (j == 0) {
- other_oid = OperatorShellMake(name[j],
- rightTypeName,
- leftTypeName);
- } else {
- other_oid = OperatorShellMake(name[j],
- leftTypeName,
- rightTypeName);
+ PointerGetDatum(procedureName),
+ Int32GetDatum(nargs),
+ PointerGetDatum(typeId),
+ 0);
+
+ if (!PointerIsValid(tup))
+ func_error("OperatorDef", procedureName, nargs, typeId);
+
+ values[Anum_pg_operator_oprcode - 1] = ObjectIdGetDatum(tup->t_oid);
+ values[Anum_pg_operator_oprresult - 1] =
+ ObjectIdGetDatum(((Form_pg_proc)
+ GETSTRUCT(tup))->prorettype);
+
+ /* ----------------
+ * find restriction
+ * ----------------
+ */
+ if (restrictionName)
+ { /* optional */
+ memset(typeId, 0, 8 * sizeof(Oid));
+ typeId[0] = OIDOID; /* operator OID */
+ typeId[1] = OIDOID; /* relation OID */
+ typeId[2] = INT2OID; /* attribute number */
+ typeId[3] = 0; /* value - can be any type */
+ typeId[4] = INT4OID; /* flags - left or right selectivity */
+ tup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(restrictionName),
+ Int32GetDatum(5),
+ PointerGetDatum(typeId),
+ 0);
+ if (!HeapTupleIsValid(tup))
+ func_error("OperatorDef", restrictionName, 5, typeId);
+
+ values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(tup->t_oid);
+ }
+ else
+ values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(InvalidOid);
+
+ /* ----------------
+ * find join - only valid for binary operators
+ * ----------------
+ */
+ if (joinName)
+ { /* optional */
+ memset(typeId, 0, 8 * sizeof(Oid));
+ typeId[0] = OIDOID; /* operator OID */
+ typeId[1] = OIDOID; /* relation OID 1 */
+ typeId[2] = INT2OID; /* attribute number 1 */
+ typeId[3] = OIDOID; /* relation OID 2 */
+ typeId[4] = INT2OID; /* attribute number 2 */
+
+ tup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(joinName),
+ Int32GetDatum(5),
+ PointerGetDatum(typeId),
+ 0);
+ if (!HeapTupleIsValid(tup))
+ func_error("OperatorDef", joinName, 5, typeId);
+
+ values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(tup->t_oid);
+ }
+ else
+ values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(InvalidOid);
+
+ /* ----------------
+ * set up values in the operator tuple
+ * ----------------
+ */
+ i = 0;
+ values[i++] = PointerGetDatum(operatorName);
+ values[i++] = Int32GetDatum(GetUserId());
+ values[i++] = UInt16GetDatum(precedence);
+ values[i++] = leftTypeName ? (rightTypeName ? 'b' : 'r') : 'l';
+ values[i++] = Int8GetDatum(isLeftAssociative);
+ values[i++] = Int8GetDatum(canHash);
+ values[i++] = ObjectIdGetDatum(leftTypeId);
+ values[i++] = ObjectIdGetDatum(rightTypeId);
+
+ ++i; /* Skip "prorettype", this was done above */
+
+ /*
+ * Set up the other operators. If they do not currently exist, set up
+ * shells in order to get ObjectId's and call OperatorDef again later
+ * to fill in the shells.
+ */
+ name[0] = commutatorName;
+ name[1] = negatorName;
+ name[2] = leftSortName;
+ name[3] = rightSortName;
+
+ for (j = 0; j < 4; ++j)
+ {
+ if (name[j])
+ {
+
+ /* for the commutator, switch order of arguments */
+ if (j == 0)
+ {
+ other_oid = OperatorGet(name[j], rightTypeName, leftTypeName);
+ commutatorId = other_oid;
+ }
+ else
+ {
+ other_oid = OperatorGet(name[j], leftTypeName, rightTypeName);
+ if (j == 1)
+ negatorId = other_oid;
+ }
+
+ if (OidIsValid(other_oid)) /* already in catalogs */
+ values[i++] = ObjectIdGetDatum(other_oid);
+ else if (strcmp(operatorName, name[j]) != 0)
+ {
+ /* not in catalogs, different from operator */
+
+ /* for the commutator, switch order of arguments */
+ if (j == 0)
+ {
+ other_oid = OperatorShellMake(name[j],
+ rightTypeName,
+ leftTypeName);
+ }
+ else
+ {
+ other_oid = OperatorShellMake(name[j],
+ leftTypeName,
+ rightTypeName);
+ }
+
+ if (!OidIsValid(other_oid))
+ elog(WARN,
+ "OperatorDef: can't create operator '%s'",
+ name[j]);
+ values[i++] = ObjectIdGetDatum(other_oid);
+
+ }
+ else
+/* not in catalogs, same as operator ??? */
+ values[i++] = ObjectIdGetDatum(InvalidOid);
+
}
-
- if (!OidIsValid(other_oid))
- elog(WARN,
- "OperatorDef: can't create operator '%s'",
- name[j]);
- values[i++] = ObjectIdGetDatum(other_oid);
-
- } else /* not in catalogs, same as operator ??? */
- values[i++] = ObjectIdGetDatum(InvalidOid);
-
- } else /* new operator is optional */
- values[i++] = ObjectIdGetDatum(InvalidOid);
- }
-
- /* last three fields were filled in first */
-
- /*
- * If we are adding to an operator shell, get its t_ctid and a
- * buffer.
- */
- pg_operator_desc = heap_openr(OperatorRelationName);
-
- if (operatorObjectId) {
- opKey[0].sk_argument = PointerGetDatum(operatorName);
- opKey[1].sk_argument = ObjectIdGetDatum(leftTypeId);
- opKey[2].sk_argument = ObjectIdGetDatum(rightTypeId);
-
- pg_operator_scan = heap_beginscan(pg_operator_desc,
- 0,
- SelfTimeQual,
- 3,
- opKey);
-
- tup = heap_getnext(pg_operator_scan, 0, &buffer);
- if (HeapTupleIsValid(tup)) {
- tup = heap_modifytuple(tup,
- buffer,
- pg_operator_desc,
- values,
- nulls,
- replaces);
-
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
- setheapoverride(true);
- heap_replace(pg_operator_desc, &itemPointerData, tup);
- setheapoverride(false);
- } else
- elog(WARN, "OperatorDef: no operator %d", other_oid);
-
- heap_endscan(pg_operator_scan);
-
- } else {
- tupDesc = pg_operator_desc->rd_att;
- tup = heap_formtuple(tupDesc, values, nulls);
-
- heap_insert(pg_operator_desc, tup);
- operatorObjectId = tup->t_oid;
- }
-
- heap_close(pg_operator_desc);
-
- /*
- * It's possible that we're creating a skeleton operator here for
- * the commute or negate attributes of a real operator. If we are,
- * then we're done. If not, we may need to update the negator and
- * commutator for this attribute. The reason for this is that the
- * user may want to create two operators (say < and >=). When he
- * defines <, if he uses >= as the negator or commutator, he won't
- * be able to insert it later, since (for some reason) define operator
- * defines it for him. So what he does is to define > without a
- * negator or commutator. Then he defines >= with < as the negator
- * and commutator. As a side effect, this will update the > tuple
- * if it has no commutator or negator defined.
- *
- * Alstublieft, Tom Vijlbrief.
- */
- if (!definedOK)
- OperatorUpd(operatorObjectId, commutatorId, negatorId);
+ else
+/* new operator is optional */
+ values[i++] = ObjectIdGetDatum(InvalidOid);
+ }
+
+ /* last three fields were filled in first */
+
+ /*
+ * If we are adding to an operator shell, get its t_ctid and a buffer.
+ */
+ pg_operator_desc = heap_openr(OperatorRelationName);
+
+ if (operatorObjectId)
+ {
+ opKey[0].sk_argument = PointerGetDatum(operatorName);
+ opKey[1].sk_argument = ObjectIdGetDatum(leftTypeId);
+ opKey[2].sk_argument = ObjectIdGetDatum(rightTypeId);
+
+ pg_operator_scan = heap_beginscan(pg_operator_desc,
+ 0,
+ SelfTimeQual,
+ 3,
+ opKey);
+
+ tup = heap_getnext(pg_operator_scan, 0, &buffer);
+ if (HeapTupleIsValid(tup))
+ {
+ tup = heap_modifytuple(tup,
+ buffer,
+ pg_operator_desc,
+ values,
+ nulls,
+ replaces);
+
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+ setheapoverride(true);
+ heap_replace(pg_operator_desc, &itemPointerData, tup);
+ setheapoverride(false);
+ }
+ else
+ elog(WARN, "OperatorDef: no operator %d", other_oid);
+
+ heap_endscan(pg_operator_scan);
+
+ }
+ else
+ {
+ tupDesc = pg_operator_desc->rd_att;
+ tup = heap_formtuple(tupDesc, values, nulls);
+
+ heap_insert(pg_operator_desc, tup);
+ operatorObjectId = tup->t_oid;
+ }
+
+ heap_close(pg_operator_desc);
+
+ /*
+ * It's possible that we're creating a skeleton operator here for the
+ * commute or negate attributes of a real operator. If we are, then
+ * we're done. If not, we may need to update the negator and
+ * commutator for this attribute. The reason for this is that the
+ * user may want to create two operators (say < and >=). When he
+ * defines <, if he uses >= as the negator or commutator, he won't be
+ * able to insert it later, since (for some reason) define operator
+ * defines it for him. So what he does is to define > without a
+ * negator or commutator. Then he defines >= with < as the negator
+ * and commutator. As a side effect, this will update the > tuple if
+ * it has no commutator or negator defined.
+ *
+ * Alstublieft, Tom Vijlbrief.
+ */
+ if (!definedOK)
+ OperatorUpd(operatorObjectId, commutatorId, negatorId);
}
/* ----------------------------------------------------------------
* OperatorUpd
*
- * For a given operator, look up its negator and commutator operators.
- * If they are defined, but their negator and commutator operators
- * (respectively) are not, then use the new operator for neg and comm.
- * This solves a problem for users who need to insert two new operators
- * which are the negator or commutator of each other.
- * ----------------------------------------------------------------
+ * For a given operator, look up its negator and commutator operators.
+ * If they are defined, but their negator and commutator operators
+ * (respectively) are not, then use the new operator for neg and comm.
+ * This solves a problem for users who need to insert two new operators
+ * which are the negator or commutator of each other.
+ * ----------------------------------------------------------------
*/
static void
OperatorUpd(Oid baseId, Oid commId, Oid negId)
{
- register i;
- Relation pg_operator_desc;
- HeapScanDesc pg_operator_scan;
- HeapTuple tup;
- Buffer buffer;
- ItemPointerData itemPointerData;
- char nulls[ Natts_pg_operator ];
- char replaces[ Natts_pg_operator ];
- Datum values[ Natts_pg_operator ];
-
- static ScanKeyData opKey[1] = {
- { 0, ObjectIdAttributeNumber, ObjectIdEqualRegProcedure },
- };
-
- fmgr_info(ObjectIdEqualRegProcedure,
- &opKey[0].sk_func, &opKey[0].sk_nargs);
-
- for (i = 0; i < Natts_pg_operator; ++i) {
- values[i] = (Datum)NULL;
- replaces[i] = ' ';
- nulls[i] = ' ';
- }
-
- pg_operator_desc = heap_openr(OperatorRelationName);
-
- /* check and update the commutator, if necessary */
- opKey[0].sk_argument = ObjectIdGetDatum(commId);
-
- pg_operator_scan = heap_beginscan(pg_operator_desc,
- 0,
- SelfTimeQual,
- 1,
- opKey);
-
- tup = heap_getnext(pg_operator_scan, 0, &buffer);
-
- /* if the commutator and negator are the same operator, do one update */
- if (commId == negId) {
- if (HeapTupleIsValid(tup)) {
- OperatorTupleForm t;
-
- t = (OperatorTupleForm) GETSTRUCT(tup);
- if (!OidIsValid(t->oprcom)
- || !OidIsValid(t->oprnegate)) {
-
- if (!OidIsValid(t->oprnegate)) {
- values[Anum_pg_operator_oprnegate - 1] =
- ObjectIdGetDatum(baseId);
- replaces[ Anum_pg_operator_oprnegate - 1 ] = 'r';
- }
-
- if (!OidIsValid(t->oprcom)) {
- values[Anum_pg_operator_oprcom - 1] =
- ObjectIdGetDatum(baseId);
- replaces[ Anum_pg_operator_oprcom - 1 ] = 'r';
+ register i;
+ Relation pg_operator_desc;
+ HeapScanDesc pg_operator_scan;
+ HeapTuple tup;
+ Buffer buffer;
+ ItemPointerData itemPointerData;
+ char nulls[Natts_pg_operator];
+ char replaces[Natts_pg_operator];
+ Datum values[Natts_pg_operator];
+
+ static ScanKeyData opKey[1] = {
+ {0, ObjectIdAttributeNumber, ObjectIdEqualRegProcedure},
+ };
+
+ fmgr_info(ObjectIdEqualRegProcedure,
+ &opKey[0].sk_func, &opKey[0].sk_nargs);
+
+ for (i = 0; i < Natts_pg_operator; ++i)
+ {
+ values[i] = (Datum) NULL;
+ replaces[i] = ' ';
+ nulls[i] = ' ';
+ }
+
+ pg_operator_desc = heap_openr(OperatorRelationName);
+
+ /* check and update the commutator, if necessary */
+ opKey[0].sk_argument = ObjectIdGetDatum(commId);
+
+ pg_operator_scan = heap_beginscan(pg_operator_desc,
+ 0,
+ SelfTimeQual,
+ 1,
+ opKey);
+
+ tup = heap_getnext(pg_operator_scan, 0, &buffer);
+
+ /* if the commutator and negator are the same operator, do one update */
+ if (commId == negId)
+ {
+ if (HeapTupleIsValid(tup))
+ {
+ OperatorTupleForm t;
+
+ t = (OperatorTupleForm) GETSTRUCT(tup);
+ if (!OidIsValid(t->oprcom)
+ || !OidIsValid(t->oprnegate))
+ {
+
+ if (!OidIsValid(t->oprnegate))
+ {
+ values[Anum_pg_operator_oprnegate - 1] =
+ ObjectIdGetDatum(baseId);
+ replaces[Anum_pg_operator_oprnegate - 1] = 'r';
+ }
+
+ if (!OidIsValid(t->oprcom))
+ {
+ values[Anum_pg_operator_oprcom - 1] =
+ ObjectIdGetDatum(baseId);
+ replaces[Anum_pg_operator_oprcom - 1] = 'r';
+ }
+
+ tup = heap_modifytuple(tup,
+ buffer,
+ pg_operator_desc,
+ values,
+ nulls,
+ replaces);
+
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+
+ setheapoverride(true);
+ heap_replace(pg_operator_desc, &itemPointerData, tup);
+ setheapoverride(false);
+
+ }
}
-
+ heap_endscan(pg_operator_scan);
+
+ heap_close(pg_operator_desc);
+
+ /* release the buffer properly */
+ if (BufferIsValid(buffer))
+ ReleaseBuffer(buffer);
+
+ return;
+ }
+
+ /* if commutator and negator are different, do two updates */
+ if (HeapTupleIsValid(tup) &&
+ !(OidIsValid(((OperatorTupleForm) GETSTRUCT(tup))->oprcom)))
+ {
+ values[Anum_pg_operator_oprcom - 1] = ObjectIdGetDatum(baseId);
+ replaces[Anum_pg_operator_oprcom - 1] = 'r';
tup = heap_modifytuple(tup,
- buffer,
- pg_operator_desc,
- values,
- nulls,
- replaces);
-
+ buffer,
+ pg_operator_desc,
+ values,
+ nulls,
+ replaces);
+
ItemPointerCopy(&tup->t_ctid, &itemPointerData);
-
setheapoverride(true);
heap_replace(pg_operator_desc, &itemPointerData, tup);
setheapoverride(false);
- }
+ values[Anum_pg_operator_oprcom - 1] = (Datum) NULL;
+ replaces[Anum_pg_operator_oprcom - 1] = ' ';
+
+ /* release the buffer properly */
+ if (BufferIsValid(buffer))
+ ReleaseBuffer(buffer);
+
+ }
+
+ /* check and update the negator, if necessary */
+ opKey[0].sk_argument = ObjectIdGetDatum(negId);
+
+ pg_operator_scan = heap_beginscan(pg_operator_desc,
+ 0,
+ SelfTimeQual,
+ 1,
+ opKey);
+
+ tup = heap_getnext(pg_operator_scan, 0, &buffer);
+ if (HeapTupleIsValid(tup) &&
+ !(OidIsValid(((OperatorTupleForm) GETSTRUCT(tup))->oprnegate)))
+ {
+ values[Anum_pg_operator_oprnegate - 1] = ObjectIdGetDatum(baseId);
+ replaces[Anum_pg_operator_oprnegate - 1] = 'r';
+ tup = heap_modifytuple(tup,
+ buffer,
+ pg_operator_desc,
+ values,
+ nulls,
+ replaces);
+
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+
+ setheapoverride(true);
+ heap_replace(pg_operator_desc, &itemPointerData, tup);
+ setheapoverride(false);
}
- heap_endscan(pg_operator_scan);
-
- heap_close(pg_operator_desc);
-
- /* release the buffer properly */
- if (BufferIsValid(buffer))
- ReleaseBuffer(buffer);
-
- return;
- }
-
- /* if commutator and negator are different, do two updates */
- if (HeapTupleIsValid(tup) &&
- !(OidIsValid(((OperatorTupleForm) GETSTRUCT(tup))->oprcom))) {
- values[ Anum_pg_operator_oprcom - 1] = ObjectIdGetDatum(baseId);
- replaces[ Anum_pg_operator_oprcom - 1] = 'r';
- tup = heap_modifytuple(tup,
- buffer,
- pg_operator_desc,
- values,
- nulls,
- replaces);
-
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
- setheapoverride(true);
- heap_replace(pg_operator_desc, &itemPointerData, tup);
- setheapoverride(false);
-
- values[ Anum_pg_operator_oprcom - 1 ] = (Datum)NULL;
- replaces[ Anum_pg_operator_oprcom - 1 ] = ' ';
/* release the buffer properly */
if (BufferIsValid(buffer))
- ReleaseBuffer(buffer);
-
- }
-
- /* check and update the negator, if necessary */
- opKey[0].sk_argument = ObjectIdGetDatum(negId);
-
- pg_operator_scan = heap_beginscan(pg_operator_desc,
- 0,
- SelfTimeQual,
- 1,
- opKey);
-
- tup = heap_getnext(pg_operator_scan, 0, &buffer);
- if (HeapTupleIsValid(tup) &&
- !(OidIsValid(((OperatorTupleForm) GETSTRUCT(tup))->oprnegate))) {
- values[Anum_pg_operator_oprnegate-1] = ObjectIdGetDatum(baseId);
- replaces[ Anum_pg_operator_oprnegate - 1 ] = 'r';
- tup = heap_modifytuple(tup,
- buffer,
- pg_operator_desc,
- values,
- nulls,
- replaces);
-
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
-
- setheapoverride(true);
- heap_replace(pg_operator_desc, &itemPointerData, tup);
- setheapoverride(false);
- }
-
- /* release the buffer properly */
- if (BufferIsValid(buffer))
- ReleaseBuffer(buffer);
-
- heap_endscan(pg_operator_scan);
-
- heap_close(pg_operator_desc);
+ ReleaseBuffer(buffer);
+
+ heap_endscan(pg_operator_scan);
+
+ heap_close(pg_operator_desc);
}
@@ -883,196 +925,202 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
*
* Algorithm:
*
- * Since the commutator, negator, leftsortoperator, and rightsortoperator
- * can be defined implicitly through OperatorCreate, must check before
- * the main operator is added to see if they already exist. If they
- * do not already exist, OperatorDef makes a "shell" for each undefined
- * one, and then OperatorCreate must call OperatorDef again to fill in
- * each shell. All this is necessary in order to get the right ObjectId's
- * filled into the right fields.
+ * Since the commutator, negator, leftsortoperator, and rightsortoperator
+ * can be defined implicitly through OperatorCreate, must check before
+ * the main operator is added to see if they already exist. If they
+ * do not already exist, OperatorDef makes a "shell" for each undefined
+ * one, and then OperatorCreate must call OperatorDef again to fill in
+ * each shell. All this is necessary in order to get the right ObjectId's
+ * filled into the right fields.
+ *
+ * The "definedOk" flag indicates that OperatorDef can be called on
+ * the operator even though it already has an entry in the PG_OPERATOR
+ * relation. This allows shells to be filled in. The user cannot
+ * forward declare operators, this is strictly an internal capability.
*
- * The "definedOk" flag indicates that OperatorDef can be called on
- * the operator even though it already has an entry in the PG_OPERATOR
- * relation. This allows shells to be filled in. The user cannot
- * forward declare operators, this is strictly an internal capability.
+ * When the shells are filled in by subsequent calls to OperatorDef,
+ * all the fields are the same as the definition of the original operator
+ * except that the target operator name and the original operatorName
+ * are switched. In the case of commutator and negator, special flags
+ * are set to indicate their status, telling the executor(?) that
+ * the operands are to be switched, or the outcome of the procedure
+ * negated.
*
- * When the shells are filled in by subsequent calls to OperatorDef,
- * all the fields are the same as the definition of the original operator
- * except that the target operator name and the original operatorName
- * are switched. In the case of commutator and negator, special flags
- * are set to indicate their status, telling the executor(?) that
- * the operands are to be switched, or the outcome of the procedure
- * negated.
- *
* ************************* NOTE NOTE NOTE ******************************
- *
- * If the execution of this utility is interrupted, the pg_operator
- * catalog may be left in an inconsistent state. Similarly, if
- * something is removed from the pg_operator, pg_type, or pg_procedure
- * catalog while this is executing, the results may be inconsistent.
+ *
+ * If the execution of this utility is interrupted, the pg_operator
+ * catalog may be left in an inconsistent state. Similarly, if
+ * something is removed from the pg_operator, pg_type, or pg_procedure
+ * catalog while this is executing, the results may be inconsistent.
* ----------------------------------------------------------------
*
- * "X" indicates an optional argument (i.e. one that can be NULL)
- * operatorName; -- operator name
- * leftTypeName; -- X left type name
- * rightTypeName; -- X right type name
- * procedureName; -- procedure for operator
- * precedence; -- operator precedence
- * isLeftAssociative; -- operator is left associative
- * commutatorName; -- X commutator operator name
- * negatorName; -- X negator operator name
- * restrictionName; -- X restriction sel. procedure
- * joinName; -- X join sel. procedure name
- * canHash; -- operator hashes
- * leftSortName; -- X left sort operator
- * rightSortName; -- X right sort operator
- *
+ * "X" indicates an optional argument (i.e. one that can be NULL)
+ * operatorName; -- operator name
+ * leftTypeName; -- X left type name
+ * rightTypeName; -- X right type name
+ * procedureName; -- procedure for operator
+ * precedence; -- operator precedence
+ * isLeftAssociative; -- operator is left associative
+ * commutatorName; -- X commutator operator name
+ * negatorName; -- X negator operator name
+ * restrictionName; -- X restriction sel. procedure
+ * joinName; -- X join sel. procedure name
+ * canHash; -- operator hashes
+ * leftSortName; -- X left sort operator
+ * rightSortName; -- X right sort operator
+ *
*/
void
OperatorCreate(char *operatorName,
- char *leftTypeName,
- char *rightTypeName,
- char *procedureName,
- uint16 precedence,
- bool isLeftAssociative,
- char *commutatorName,
- char *negatorName,
- char *restrictionName,
- char *joinName,
- bool canHash,
- char *leftSortName,
- char *rightSortName)
+ char *leftTypeName,
+ char *rightTypeName,
+ char *procedureName,
+ uint16 precedence,
+ bool isLeftAssociative,
+ char *commutatorName,
+ char *negatorName,
+ char *restrictionName,
+ char *joinName,
+ bool canHash,
+ char *leftSortName,
+ char *rightSortName)
{
- Oid commObjectId, negObjectId;
- Oid leftSortObjectId, rightSortObjectId;
- int definedOK;
-
- if (!leftTypeName && !rightTypeName)
- elog(WARN, "OperatorCreate : at least one of leftarg or rightarg must be defined");
-
- /* ----------------
- * get the oid's of the operator's associated operators, if possible.
- * ----------------
- */
- if (commutatorName)
- commObjectId = OperatorGet(commutatorName, /* commute type order */
- rightTypeName,
- leftTypeName);
- else commObjectId = 0;
-
- if (negatorName)
- negObjectId = OperatorGet(negatorName,
- leftTypeName,
- rightTypeName);
- else negObjectId = 0;
-
- if (leftSortName)
- leftSortObjectId = OperatorGet(leftSortName,
- leftTypeName,
- rightTypeName);
- else leftSortObjectId = 0;
-
- if (rightSortName)
- rightSortObjectId = OperatorGet(rightSortName,
+ Oid commObjectId,
+ negObjectId;
+ Oid leftSortObjectId,
+ rightSortObjectId;
+ int definedOK;
+
+ if (!leftTypeName && !rightTypeName)
+ elog(WARN, "OperatorCreate : at least one of leftarg or rightarg must be defined");
+
+ /* ----------------
+ * get the oid's of the operator's associated operators, if possible.
+ * ----------------
+ */
+ if (commutatorName)
+ commObjectId = OperatorGet(commutatorName, /* commute type order */
+ rightTypeName,
+ leftTypeName);
+ else
+ commObjectId = 0;
+
+ if (negatorName)
+ negObjectId = OperatorGet(negatorName,
+ leftTypeName,
+ rightTypeName);
+ else
+ negObjectId = 0;
+
+ if (leftSortName)
+ leftSortObjectId = OperatorGet(leftSortName,
+ leftTypeName,
+ rightTypeName);
+ else
+ leftSortObjectId = 0;
+
+ if (rightSortName)
+ rightSortObjectId = OperatorGet(rightSortName,
+ rightTypeName,
+ leftTypeName);
+ else
+ rightSortObjectId = 0;
+
+ /* ----------------
+ * Use OperatorDef() to define the specified operator and
+ * also create shells for the operator's associated operators
+ * if they don't already exist.
+ *
+ * This operator should not be defined yet.
+ * ----------------
+ */
+ definedOK = 0;
+
+ OperatorDef(operatorName,
+ definedOK,
+ leftTypeName,
+ rightTypeName,
+ procedureName,
+ precedence,
+ isLeftAssociative,
+ commutatorName,
+ negatorName,
+ restrictionName,
+ joinName,
+ canHash,
+ leftSortName,
+ rightSortName);
+
+ /* ----------------
+ * Now fill in information in the operator's associated
+ * operators.
+ *
+ * These operators should be defined or have shells defined.
+ * ----------------
+ */
+ definedOK = 1;
+
+ if (!OidIsValid(commObjectId) && commutatorName)
+ OperatorDef(commutatorName,
+ definedOK,
+ leftTypeName, /* should eventually */
+ rightTypeName, /* commute order */
+ procedureName,
+ precedence,
+ isLeftAssociative,
+ operatorName, /* commutator */
+ negatorName,
+ restrictionName,
+ joinName,
+ canHash,
+ rightSortName,
+ leftSortName);
+
+ if (negatorName && !OidIsValid(negObjectId))
+ OperatorDef(negatorName,
+ definedOK,
+ leftTypeName,
+ rightTypeName,
+ procedureName,
+ precedence,
+ isLeftAssociative,
+ commutatorName,
+ operatorName, /* negator */
+ restrictionName,
+ joinName,
+ canHash,
+ leftSortName,
+ rightSortName);
+
+ if (leftSortName && !OidIsValid(leftSortObjectId))
+ OperatorDef(leftSortName,
+ definedOK,
+ leftTypeName,
+ rightTypeName,
+ procedureName,
+ precedence,
+ isLeftAssociative,
+ commutatorName,
+ negatorName,
+ restrictionName,
+ joinName,
+ canHash,
+ operatorName, /* left sort */
+ rightSortName);
+
+ if (rightSortName && !OidIsValid(rightSortObjectId))
+ OperatorDef(rightSortName,
+ definedOK,
+ leftTypeName,
rightTypeName,
- leftTypeName);
- else rightSortObjectId = 0;
-
- /* ----------------
- * Use OperatorDef() to define the specified operator and
- * also create shells for the operator's associated operators
- * if they don't already exist.
- *
- * This operator should not be defined yet.
- * ----------------
- */
- definedOK = 0;
-
- OperatorDef(operatorName,
- definedOK,
- leftTypeName,
- rightTypeName,
- procedureName,
- precedence,
- isLeftAssociative,
- commutatorName,
- negatorName,
- restrictionName,
- joinName,
- canHash,
- leftSortName,
- rightSortName);
-
- /* ----------------
- * Now fill in information in the operator's associated
- * operators.
- *
- * These operators should be defined or have shells defined.
- * ----------------
- */
- definedOK = 1;
-
- if (!OidIsValid(commObjectId) && commutatorName)
- OperatorDef(commutatorName,
- definedOK,
- leftTypeName, /* should eventually */
- rightTypeName, /* commute order */
- procedureName,
- precedence,
- isLeftAssociative,
- operatorName, /* commutator */
- negatorName,
- restrictionName,
- joinName,
- canHash,
- rightSortName,
- leftSortName);
-
- if (negatorName && !OidIsValid(negObjectId))
- OperatorDef(negatorName,
- definedOK,
- leftTypeName,
- rightTypeName,
- procedureName,
- precedence,
- isLeftAssociative,
- commutatorName,
- operatorName, /* negator */
- restrictionName,
- joinName,
- canHash,
- leftSortName,
- rightSortName);
-
- if (leftSortName && !OidIsValid(leftSortObjectId))
- OperatorDef(leftSortName,
- definedOK,
- leftTypeName,
- rightTypeName,
- procedureName,
- precedence,
- isLeftAssociative,
- commutatorName,
- negatorName,
- restrictionName,
- joinName,
- canHash,
- operatorName, /* left sort */
- rightSortName);
-
- if (rightSortName && !OidIsValid(rightSortObjectId))
- OperatorDef(rightSortName,
- definedOK,
- leftTypeName,
- rightTypeName,
- procedureName,
- precedence,
- isLeftAssociative,
- commutatorName,
- negatorName,
- restrictionName,
- joinName,
- canHash,
- leftSortName,
- operatorName); /* right sort */
+ procedureName,
+ precedence,
+ isLeftAssociative,
+ commutatorName,
+ negatorName,
+ restrictionName,
+ joinName,
+ canHash,
+ leftSortName,
+ operatorName); /* right sort */
}
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 947bdc6051b..1dd1b0867c3 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* pg_proc.c--
- * routines to support manipulation of the pg_proc relation
+ * routines to support manipulation of the pg_proc relation
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.5 1996/11/08 00:44:34 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.6 1997/09/07 04:40:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,231 +30,252 @@
#include <utils/lsyscache.h>
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
/* ----------------------------------------------------------------
- * ProcedureDefine
+ * ProcedureDefine
* ----------------------------------------------------------------
*/
Oid
ProcedureCreate(char *procedureName,
- bool returnsSet,
- char *returnTypeName,
- char *languageName,
- char *prosrc,
- char *probin,
- bool canCache,
- bool trusted,
- int32 byte_pct,
- int32 perbyte_cpu,
- int32 percall_cpu,
- int32 outin_ratio,
- List *argList,
- CommandDest dest)
+ bool returnsSet,
+ char *returnTypeName,
+ char *languageName,
+ char *prosrc,
+ char *probin,
+ bool canCache,
+ bool trusted,
+ int32 byte_pct,
+ int32 perbyte_cpu,
+ int32 percall_cpu,
+ int32 outin_ratio,
+ List * argList,
+ CommandDest dest)
{
- register i;
- Relation rdesc;
- HeapTuple tup;
- bool defined;
- uint16 parameterCount;
- char nulls[ Natts_pg_proc ];
- Datum values[ Natts_pg_proc ];
- Oid languageObjectId;
- Oid typeObjectId;
- List *x;
- QueryTreeList *querytree_list;
- List *plan_list;
- Oid typev[8];
- Oid relid;
- Oid toid;
- text *prosrctext;
- TupleDesc tupDesc;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(PointerIsValid(prosrc));
- Assert(PointerIsValid(probin));
-
- parameterCount = 0;
- memset(typev, 0, 8 * sizeof(Oid));
- foreach (x, argList) {
- Value *t = lfirst(x);
-
- if (parameterCount == 8)
- elog(WARN, "Procedures cannot take more than 8 arguments");
-
- if (strcmp(strVal(t), "opaque") == 0) {
- if (strcmp(languageName, "sql") == 0) {
- elog(WARN, "ProcedureDefine: sql functions cannot take type \"opaque\"");
- }
- toid = 0;
- } else {
- toid = TypeGet(strVal(t), &defined);
-
- if (!OidIsValid(toid)) {
- elog(WARN, "ProcedureCreate: arg type '%s' is not defined",
- strVal(t));
- }
-
- if (!defined) {
- elog(NOTICE, "ProcedureCreate: arg type '%s' is only a shell",
- strVal(t));
- }
- }
-
- typev[parameterCount++] = toid;
- }
-
- tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(procedureName),
- UInt16GetDatum(parameterCount),
- PointerGetDatum(typev),
- 0);
-
- if (HeapTupleIsValid(tup))
- elog(WARN, "ProcedureCreate: procedure %s already exists with same arguments",
- procedureName);
-
- if (!strcmp(languageName, "sql")) {
- /* If this call is defining a set, check if the set is already
- * defined by looking to see whether this call's function text
- * matches a function already in pg_proc. If so just return the
- * OID of the existing set.
+ register i;
+ Relation rdesc;
+ HeapTuple tup;
+ bool defined;
+ uint16 parameterCount;
+ char nulls[Natts_pg_proc];
+ Datum values[Natts_pg_proc];
+ Oid languageObjectId;
+ Oid typeObjectId;
+ List *x;
+ QueryTreeList *querytree_list;
+ List *plan_list;
+ Oid typev[8];
+ Oid relid;
+ Oid toid;
+ text *prosrctext;
+ TupleDesc tupDesc;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
*/
- if (!strcmp(procedureName, GENERICSETNAME)) {
- prosrctext = textin(prosrc);
- tup = SearchSysCacheTuple(PROSRC,
- PointerGetDatum(prosrctext),
- 0,0,0);
- if (HeapTupleIsValid(tup))
- return tup->t_oid;
+ Assert(PointerIsValid(prosrc));
+ Assert(PointerIsValid(probin));
+
+ parameterCount = 0;
+ memset(typev, 0, 8 * sizeof(Oid));
+ foreach(x, argList)
+ {
+ Value *t = lfirst(x);
+
+ if (parameterCount == 8)
+ elog(WARN, "Procedures cannot take more than 8 arguments");
+
+ if (strcmp(strVal(t), "opaque") == 0)
+ {
+ if (strcmp(languageName, "sql") == 0)
+ {
+ elog(WARN, "ProcedureDefine: sql functions cannot take type \"opaque\"");
+ }
+ toid = 0;
+ }
+ else
+ {
+ toid = TypeGet(strVal(t), &defined);
+
+ if (!OidIsValid(toid))
+ {
+ elog(WARN, "ProcedureCreate: arg type '%s' is not defined",
+ strVal(t));
+ }
+
+ if (!defined)
+ {
+ elog(NOTICE, "ProcedureCreate: arg type '%s' is only a shell",
+ strVal(t));
+ }
+ }
+
+ typev[parameterCount++] = toid;
+ }
+
+ tup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(procedureName),
+ UInt16GetDatum(parameterCount),
+ PointerGetDatum(typev),
+ 0);
+
+ if (HeapTupleIsValid(tup))
+ elog(WARN, "ProcedureCreate: procedure %s already exists with same arguments",
+ procedureName);
+
+ if (!strcmp(languageName, "sql"))
+ {
+
+ /*
+ * If this call is defining a set, check if the set is already
+ * defined by looking to see whether this call's function text
+ * matches a function already in pg_proc. If so just return the
+ * OID of the existing set.
+ */
+ if (!strcmp(procedureName, GENERICSETNAME))
+ {
+ prosrctext = textin(prosrc);
+ tup = SearchSysCacheTuple(PROSRC,
+ PointerGetDatum(prosrctext),
+ 0, 0, 0);
+ if (HeapTupleIsValid(tup))
+ return tup->t_oid;
+ }
}
- }
-
- tup = SearchSysCacheTuple(LANNAME,
- PointerGetDatum(languageName),
- 0,0,0);
-
- if (!HeapTupleIsValid(tup))
- elog(WARN, "ProcedureCreate: no such language %s",
- languageName);
-
- languageObjectId = tup->t_oid;
-
- if (strcmp(returnTypeName, "opaque") == 0) {
- if (strcmp(languageName, "sql") == 0) {
- elog(WARN, "ProcedureCreate: sql functions cannot return type \"opaque\"");
+
+ tup = SearchSysCacheTuple(LANNAME,
+ PointerGetDatum(languageName),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup))
+ elog(WARN, "ProcedureCreate: no such language %s",
+ languageName);
+
+ languageObjectId = tup->t_oid;
+
+ if (strcmp(returnTypeName, "opaque") == 0)
+ {
+ if (strcmp(languageName, "sql") == 0)
+ {
+ elog(WARN, "ProcedureCreate: sql functions cannot return type \"opaque\"");
+ }
+ typeObjectId = 0;
}
- typeObjectId = 0;
- }
-
- else {
- typeObjectId = TypeGet(returnTypeName, &defined);
-
- if (!OidIsValid(typeObjectId)) {
- elog(NOTICE, "ProcedureCreate: type '%s' is not yet defined",
- returnTypeName);
+
+ else
+ {
+ typeObjectId = TypeGet(returnTypeName, &defined);
+
+ if (!OidIsValid(typeObjectId))
+ {
+ elog(NOTICE, "ProcedureCreate: type '%s' is not yet defined",
+ returnTypeName);
#if 0
- elog(NOTICE, "ProcedureCreate: creating a shell for type '%s'",
- returnTypeName);
-#endif
- typeObjectId = TypeShellMake(returnTypeName);
- if (!OidIsValid(typeObjectId)) {
- elog(WARN, "ProcedureCreate: could not create type '%s'",
- returnTypeName);
- }
+ elog(NOTICE, "ProcedureCreate: creating a shell for type '%s'",
+ returnTypeName);
+#endif
+ typeObjectId = TypeShellMake(returnTypeName);
+ if (!OidIsValid(typeObjectId))
+ {
+ elog(WARN, "ProcedureCreate: could not create type '%s'",
+ returnTypeName);
+ }
+ }
+
+ else if (!defined)
+ {
+ elog(NOTICE, "ProcedureCreate: return type '%s' is only a shell",
+ returnTypeName);
+ }
}
-
- else if (!defined) {
- elog(NOTICE, "ProcedureCreate: return type '%s' is only a shell",
- returnTypeName);
+
+ /*
+ * don't allow functions of complex types that have the same name as
+ * existing attributes of the type
+ */
+ if (parameterCount == 1 &&
+ (toid = TypeGet(strVal(lfirst(argList)), &defined)) &&
+ defined &&
+ (relid = typeid_get_relid(toid)) != 0 &&
+ get_attnum(relid, procedureName) != InvalidAttrNumber)
+ elog(WARN, "method %s already an attribute of type %s",
+ procedureName, strVal(lfirst(argList)));
+
+
+ /*
+ * If this is a postquel procedure, we parse it here in order to be
+ * sure that it contains no syntax errors. We should store the plan
+ * in an Inversion file for use later, but for now, we just store the
+ * procedure's text in the prosrc attribute.
+ */
+
+ if (strcmp(languageName, "sql") == 0)
+ {
+ plan_list = pg_plan(prosrc, typev, parameterCount,
+ &querytree_list, dest);
+
+ /* typecheck return value */
+ pg_checkretval(typeObjectId, querytree_list);
}
- }
-
- /* don't allow functions of complex types that have the same name as
- existing attributes of the type */
- if (parameterCount == 1 &&
- (toid = TypeGet(strVal(lfirst(argList)), &defined)) &&
- defined &&
- (relid = typeid_get_relid(toid)) != 0 &&
- get_attnum(relid, procedureName) != InvalidAttrNumber)
- elog(WARN, "method %s already an attribute of type %s",
- procedureName, strVal(lfirst(argList)));
-
-
- /*
- * If this is a postquel procedure, we parse it here in order to
- * be sure that it contains no syntax errors. We should store
- * the plan in an Inversion file for use later, but for now, we
- * just store the procedure's text in the prosrc attribute.
- */
-
- if (strcmp(languageName, "sql") == 0) {
- plan_list = pg_plan(prosrc, typev, parameterCount,
- &querytree_list, dest);
-
- /* typecheck return value */
- pg_checkretval(typeObjectId, querytree_list);
- }
-
- for (i = 0; i < Natts_pg_proc; ++i) {
- nulls[i] = ' ';
- values[i] = (Datum)NULL;
- }
-
- i = 0;
- values[i++] = PointerGetDatum(procedureName);
- values[i++] = Int32GetDatum(GetUserId());
- values[i++] = ObjectIdGetDatum(languageObjectId);
-
- /* XXX isinherited is always false for now */
-
- values[i++] = Int8GetDatum((bool) 0);
-
- /* XXX istrusted is always false for now */
-
- values[i++] = Int8GetDatum(trusted);
- values[i++] = Int8GetDatum(canCache);
- values[i++] = UInt16GetDatum(parameterCount);
- values[i++] = Int8GetDatum(returnsSet);
- values[i++] = ObjectIdGetDatum(typeObjectId);
-
- values[i++] = (Datum) typev;
- /*
- * The following assignments of constants are made. The real values
- * will have to be extracted from the arglist someday soon.
- */
- values[i++] = Int32GetDatum(byte_pct); /* probyte_pct */
- values[i++] = Int32GetDatum(perbyte_cpu); /* properbyte_cpu */
- values[i++] = Int32GetDatum(percall_cpu); /* propercall_cpu */
- values[i++] = Int32GetDatum(outin_ratio); /* prooutin_ratio */
-
- values[i++] = (Datum)fmgr(TextInRegProcedure, prosrc); /* prosrc */
- values[i++] = (Datum)fmgr(TextInRegProcedure, probin); /* probin */
-
- rdesc = heap_openr(ProcedureRelationName);
-
- tupDesc = rdesc->rd_att;
- tup = heap_formtuple(tupDesc,
- values,
- nulls);
-
- heap_insert(rdesc, tup);
-
- if (RelationGetRelationTupleForm(rdesc)->relhasindex)
+
+ for (i = 0; i < Natts_pg_proc; ++i)
{
- Relation idescs[Num_pg_proc_indices];
-
- CatalogOpenIndices(Num_pg_proc_indices, Name_pg_proc_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_proc_indices, rdesc, tup);
- CatalogCloseIndices(Num_pg_proc_indices, idescs);
+ nulls[i] = ' ';
+ values[i] = (Datum) NULL;
}
- heap_close(rdesc);
- return tup->t_oid;
-}
+ i = 0;
+ values[i++] = PointerGetDatum(procedureName);
+ values[i++] = Int32GetDatum(GetUserId());
+ values[i++] = ObjectIdGetDatum(languageObjectId);
+
+ /* XXX isinherited is always false for now */
+
+ values[i++] = Int8GetDatum((bool) 0);
+
+ /* XXX istrusted is always false for now */
+
+ values[i++] = Int8GetDatum(trusted);
+ values[i++] = Int8GetDatum(canCache);
+ values[i++] = UInt16GetDatum(parameterCount);
+ values[i++] = Int8GetDatum(returnsSet);
+ values[i++] = ObjectIdGetDatum(typeObjectId);
+
+ values[i++] = (Datum) typev;
+
+ /*
+ * The following assignments of constants are made. The real values
+ * will have to be extracted from the arglist someday soon.
+ */
+ values[i++] = Int32GetDatum(byte_pct); /* probyte_pct */
+ values[i++] = Int32GetDatum(perbyte_cpu); /* properbyte_cpu */
+ values[i++] = Int32GetDatum(percall_cpu); /* propercall_cpu */
+ values[i++] = Int32GetDatum(outin_ratio); /* prooutin_ratio */
+
+ values[i++] = (Datum) fmgr(TextInRegProcedure, prosrc); /* prosrc */
+ values[i++] = (Datum) fmgr(TextInRegProcedure, probin); /* probin */
+
+ rdesc = heap_openr(ProcedureRelationName);
+
+ tupDesc = rdesc->rd_att;
+ tup = heap_formtuple(tupDesc,
+ values,
+ nulls);
+
+ heap_insert(rdesc, tup);
+
+ if (RelationGetRelationTupleForm(rdesc)->relhasindex)
+ {
+ Relation idescs[Num_pg_proc_indices];
+
+ CatalogOpenIndices(Num_pg_proc_indices, Name_pg_proc_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_proc_indices, rdesc, tup);
+ CatalogCloseIndices(Num_pg_proc_indices, idescs);
+ }
+ heap_close(rdesc);
+ return tup->t_oid;
+}
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index caf53b03ea6..9a31030421c 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* pg_type.c--
- * routines to support manipulation of the pg_type relation
+ * routines to support manipulation of the pg_type relation
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.7 1997/08/19 21:30:38 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.8 1997/09/07 04:40:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,572 +25,595 @@
#include <storage/lmgr.h>
#include <miscadmin.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static Oid TypeShellMakeWithOpenRelation(Relation pg_type_desc,
- char *typeName);
+static Oid
+TypeShellMakeWithOpenRelation(Relation pg_type_desc,
+ char *typeName);
/* ----------------------------------------------------------------
- * TypeGetWithOpenRelation
+ * TypeGetWithOpenRelation
*
- * preforms a scan on pg_type for a type tuple with the
- * given type name.
+ * preforms a scan on pg_type for a type tuple with the
+ * given type name.
* ----------------------------------------------------------------
- * pg_type_desc -- reldesc for pg_type
- * typeName -- name of type to be fetched
- * defined -- has the type been defined?
+ * pg_type_desc -- reldesc for pg_type
+ * typeName -- name of type to be fetched
+ * defined -- has the type been defined?
*/
-static Oid
+static Oid
TypeGetWithOpenRelation(Relation pg_type_desc,
- char* typeName,
- bool *defined)
+ char *typeName,
+ bool * defined)
{
- HeapScanDesc scan;
- HeapTuple tup;
-
- static ScanKeyData typeKey[1] = {
- { 0, Anum_pg_type_typname, NameEqualRegProcedure }
- };
-
- /* ----------------
- * initialize the scan key and begin a scan of pg_type
- * ----------------
- */
- fmgr_info(NameEqualRegProcedure,
- &typeKey[0].sk_func, &typeKey[0].sk_nargs);
- typeKey[0].sk_argument = PointerGetDatum(typeName);
-
- scan = heap_beginscan(pg_type_desc,
- 0,
- SelfTimeQual,
- 1,
- typeKey);
-
- /* ----------------
- * get the type tuple, if it exists.
- * ----------------
- */
- tup = heap_getnext(scan, 0, (Buffer *) 0);
-
- /* ----------------
- * if no type tuple exists for the given type name, then
- * end the scan and return appropriate information.
- * ----------------
- */
- if (! HeapTupleIsValid(tup)) {
+ HeapScanDesc scan;
+ HeapTuple tup;
+
+ static ScanKeyData typeKey[1] = {
+ {0, Anum_pg_type_typname, NameEqualRegProcedure}
+ };
+
+ /* ----------------
+ * initialize the scan key and begin a scan of pg_type
+ * ----------------
+ */
+ fmgr_info(NameEqualRegProcedure,
+ &typeKey[0].sk_func, &typeKey[0].sk_nargs);
+ typeKey[0].sk_argument = PointerGetDatum(typeName);
+
+ scan = heap_beginscan(pg_type_desc,
+ 0,
+ SelfTimeQual,
+ 1,
+ typeKey);
+
+ /* ----------------
+ * get the type tuple, if it exists.
+ * ----------------
+ */
+ tup = heap_getnext(scan, 0, (Buffer *) 0);
+
+ /* ----------------
+ * if no type tuple exists for the given type name, then
+ * end the scan and return appropriate information.
+ * ----------------
+ */
+ if (!HeapTupleIsValid(tup))
+ {
+ heap_endscan(scan);
+ *defined = false;
+ return InvalidOid;
+ }
+
+ /* ----------------
+ * here, the type tuple does exist so we pull information from
+ * the typisdefined field of the tuple and return the tuple's
+ * oid, which is the oid of the type.
+ * ----------------
+ */
heap_endscan(scan);
- *defined = false;
- return InvalidOid;
- }
-
- /* ----------------
- * here, the type tuple does exist so we pull information from
- * the typisdefined field of the tuple and return the tuple's
- * oid, which is the oid of the type.
- * ----------------
- */
- heap_endscan(scan);
- *defined = (bool) ((TypeTupleForm) GETSTRUCT(tup))->typisdefined;
-
- return
- tup->t_oid;
+ *defined = (bool) ((TypeTupleForm) GETSTRUCT(tup))->typisdefined;
+
+ return
+ tup->t_oid;
}
/* ----------------------------------------------------------------
- * TypeGet
+ * TypeGet
*
- * Finds the ObjectId of a type, even if uncommitted; "defined"
- * is only set if the type has actually been defined, i.e., if
- * the type tuple is not a shell.
+ * Finds the ObjectId of a type, even if uncommitted; "defined"
+ * is only set if the type has actually been defined, i.e., if
+ * the type tuple is not a shell.
*
- * Note: the meat of this function is now in the function
- * TypeGetWithOpenRelation(). -cim 6/15/90
+ * Note: the meat of this function is now in the function
+ * TypeGetWithOpenRelation(). -cim 6/15/90
*
- * Also called from util/remove.c
+ * Also called from util/remove.c
* ----------------------------------------------------------------
*/
Oid
-TypeGet(char* typeName, /* name of type to be fetched */
- bool *defined) /* has the type been defined? */
+TypeGet(char *typeName, /* name of type to be fetched */
+ bool * defined) /* has the type been defined? */
{
- Relation pg_type_desc;
- Oid typeoid;
-
- /* ----------------
- * open the pg_type relation
- * ----------------
- */
- pg_type_desc = heap_openr(TypeRelationName);
-
- /* ----------------
- * scan the type relation for the information we want
- * ----------------
- */
- typeoid = TypeGetWithOpenRelation(pg_type_desc,
- typeName,
- defined);
-
- /* ----------------
- * close the type relation and return the type oid.
- * ----------------
- */
- heap_close(pg_type_desc);
-
- return
- typeoid;
+ Relation pg_type_desc;
+ Oid typeoid;
+
+ /* ----------------
+ * open the pg_type relation
+ * ----------------
+ */
+ pg_type_desc = heap_openr(TypeRelationName);
+
+ /* ----------------
+ * scan the type relation for the information we want
+ * ----------------
+ */
+ typeoid = TypeGetWithOpenRelation(pg_type_desc,
+ typeName,
+ defined);
+
+ /* ----------------
+ * close the type relation and return the type oid.
+ * ----------------
+ */
+ heap_close(pg_type_desc);
+
+ return
+ typeoid;
}
/* ----------------------------------------------------------------
- * TypeShellMakeWithOpenRelation
+ * TypeShellMakeWithOpenRelation
*
* ----------------------------------------------------------------
*/
-static Oid
+static Oid
TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
{
- register int i;
- HeapTuple tup;
- Datum values[ Natts_pg_type ];
- char nulls[ Natts_pg_type ];
- Oid typoid;
- TupleDesc tupDesc;
-
- /* ----------------
- * initialize our nulls[] and values[] arrays
- * ----------------
- */
- for (i = 0; i < Natts_pg_type; ++i) {
- nulls[i] = ' ';
- values[i] = (Datum)NULL; /* redundant, but safe */
- }
-
- /* ----------------
- * initialize values[] with the type name and
- * ----------------
- */
- i = 0;
- values[i++] = (Datum) typeName; /* 1 */
- values[i++] = (Datum) InvalidOid; /* 2 */
- values[i++] = (Datum) (int16) 0; /* 3 */
- values[i++] = (Datum) (int16) 0; /* 4 */
- values[i++] = (Datum) (bool) 0; /* 5 */
- values[i++] = (Datum) (bool) 0; /* 6 */
- values[i++] = (Datum) (bool) 0; /* 7 */
- values[i++] = (Datum) (bool) 0; /* 8 */
- values[i++] = (Datum) InvalidOid; /* 9 */
- values[i++] = (Datum) InvalidOid; /* 10 */
- values[i++] = (Datum) InvalidOid; /* 11 */
- values[i++] = (Datum) InvalidOid; /* 12 */
- values[i++] = (Datum) InvalidOid; /* 13 */
- values[i++] = (Datum) InvalidOid; /* 14 */
- values[i++] = (Datum) 'i'; /* 15 */
-
- /*
- * ... and fill typdefault with a bogus value
- */
- values[i++] =
- (Datum)fmgr(TextInRegProcedure, typeName); /* 15 */
-
- /* ----------------
- * create a new type tuple with FormHeapTuple
- * ----------------
- */
- tupDesc = pg_type_desc->rd_att;
-
- tup = heap_formtuple(tupDesc, values, nulls);
-
- /* ----------------
- * insert the tuple in the relation and get the tuple's oid.
- * ----------------
- */
- heap_insert(pg_type_desc, tup);
- typoid = tup->t_oid;
-
- if (RelationGetRelationTupleForm(pg_type_desc)->relhasindex)
+ register int i;
+ HeapTuple tup;
+ Datum values[Natts_pg_type];
+ char nulls[Natts_pg_type];
+ Oid typoid;
+ TupleDesc tupDesc;
+
+ /* ----------------
+ * initialize our nulls[] and values[] arrays
+ * ----------------
+ */
+ for (i = 0; i < Natts_pg_type; ++i)
+ {
+ nulls[i] = ' ';
+ values[i] = (Datum) NULL; /* redundant, but safe */
+ }
+
+ /* ----------------
+ * initialize values[] with the type name and
+ * ----------------
+ */
+ i = 0;
+ values[i++] = (Datum) typeName; /* 1 */
+ values[i++] = (Datum) InvalidOid; /* 2 */
+ values[i++] = (Datum) (int16) 0; /* 3 */
+ values[i++] = (Datum) (int16) 0; /* 4 */
+ values[i++] = (Datum) (bool) 0; /* 5 */
+ values[i++] = (Datum) (bool) 0; /* 6 */
+ values[i++] = (Datum) (bool) 0; /* 7 */
+ values[i++] = (Datum) (bool) 0; /* 8 */
+ values[i++] = (Datum) InvalidOid; /* 9 */
+ values[i++] = (Datum) InvalidOid; /* 10 */
+ values[i++] = (Datum) InvalidOid; /* 11 */
+ values[i++] = (Datum) InvalidOid; /* 12 */
+ values[i++] = (Datum) InvalidOid; /* 13 */
+ values[i++] = (Datum) InvalidOid; /* 14 */
+ values[i++] = (Datum) 'i'; /* 15 */
+
+ /*
+ * ... and fill typdefault with a bogus value
+ */
+ values[i++] =
+ (Datum) fmgr(TextInRegProcedure, typeName); /* 15 */
+
+ /* ----------------
+ * create a new type tuple with FormHeapTuple
+ * ----------------
+ */
+ tupDesc = pg_type_desc->rd_att;
+
+ tup = heap_formtuple(tupDesc, values, nulls);
+
+ /* ----------------
+ * insert the tuple in the relation and get the tuple's oid.
+ * ----------------
+ */
+ heap_insert(pg_type_desc, tup);
+ typoid = tup->t_oid;
+
+ if (RelationGetRelationTupleForm(pg_type_desc)->relhasindex)
{
- Relation idescs[Num_pg_type_indices];
-
- CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup);
- CatalogCloseIndices(Num_pg_type_indices, idescs);
+ Relation idescs[Num_pg_type_indices];
+
+ CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup);
+ CatalogCloseIndices(Num_pg_type_indices, idescs);
}
- /* ----------------
- * free the tuple and return the type-oid
- * ----------------
- */
- pfree(tup);
-
- return
- typoid;
+ /* ----------------
+ * free the tuple and return the type-oid
+ * ----------------
+ */
+ pfree(tup);
+
+ return
+ typoid;
}
/* ----------------------------------------------------------------
- * TypeShellMake
+ * TypeShellMake
*
- * This procedure inserts a "shell" tuple into the type
- * relation. The type tuple inserted has invalid values
- * and in particular, the "typisdefined" field is false.
+ * This procedure inserts a "shell" tuple into the type
+ * relation. The type tuple inserted has invalid values
+ * and in particular, the "typisdefined" field is false.
*
- * This is used so that a tuple exists in the catalogs.
- * The invalid fields should be fixed up sometime after
- * this routine is called, and then the "typeisdefined"
- * field is set to true. -cim 6/15/90
+ * This is used so that a tuple exists in the catalogs.
+ * The invalid fields should be fixed up sometime after
+ * this routine is called, and then the "typeisdefined"
+ * field is set to true. -cim 6/15/90
* ----------------------------------------------------------------
*/
Oid
TypeShellMake(char *typeName)
{
- Relation pg_type_desc;
- Oid typoid;
-
- Assert(PointerIsValid(typeName));
-
- /* ----------------
- * open pg_type
- * ----------------
- */
- pg_type_desc = heap_openr(TypeRelationName);
-
- /* ----------------
- * insert the shell tuple
- * ----------------
- */
- typoid = TypeShellMakeWithOpenRelation(pg_type_desc, typeName);
-
- /* ----------------
- * close pg_type and return the tuple's oid.
- * ----------------
- */
- heap_close(pg_type_desc);
-
- return
- typoid;
+ Relation pg_type_desc;
+ Oid typoid;
+
+ Assert(PointerIsValid(typeName));
+
+ /* ----------------
+ * open pg_type
+ * ----------------
+ */
+ pg_type_desc = heap_openr(TypeRelationName);
+
+ /* ----------------
+ * insert the shell tuple
+ * ----------------
+ */
+ typoid = TypeShellMakeWithOpenRelation(pg_type_desc, typeName);
+
+ /* ----------------
+ * close pg_type and return the tuple's oid.
+ * ----------------
+ */
+ heap_close(pg_type_desc);
+
+ return
+ typoid;
}
/* ----------------------------------------------------------------
- * TypeCreate
+ * TypeCreate
*
- * This does all the necessary work needed to define a new type.
+ * This does all the necessary work needed to define a new type.
* ----------------------------------------------------------------
*/
Oid
TypeCreate(char *typeName,
- Oid relationOid, /* only for 'c'atalog typeTypes */
- int16 internalSize,
- int16 externalSize,
- char typeType,
- char typDelim,
- char *inputProcedure,
- char *outputProcedure,
- char *sendProcedure,
- char *receiveProcedure,
- char *elementTypeName,
- char *defaultTypeValue, /* internal rep */
- bool passedByValue,
- char alignment)
+ Oid relationOid, /* only for 'c'atalog typeTypes */
+ int16 internalSize,
+ int16 externalSize,
+ char typeType,
+ char typDelim,
+ char *inputProcedure,
+ char *outputProcedure,
+ char *sendProcedure,
+ char *receiveProcedure,
+ char *elementTypeName,
+ char *defaultTypeValue, /* internal rep */
+ bool passedByValue,
+ char alignment)
{
- register i, j;
- Relation pg_type_desc;
- HeapScanDesc pg_type_scan;
-
- Oid typeObjectId;
- Oid elementObjectId = InvalidOid;
-
- HeapTuple tup;
- char nulls[Natts_pg_type];
- char replaces[Natts_pg_type];
- Datum values[Natts_pg_type];
-
- Buffer buffer;
- char *procname;
- char *procs[4];
- bool defined;
- ItemPointerData itemPointerData;
- TupleDesc tupDesc;
-
- Oid argList[8];
-
-
- static ScanKeyData typeKey[1] = {
- { 0, Anum_pg_type_typname, NameEqualRegProcedure }
- };
-
- fmgr_info(NameEqualRegProcedure,
- &typeKey[0].sk_func, &typeKey[0].sk_nargs);
-
- /* ----------------
- * check that the type is not already defined.
- * ----------------
- */
- typeObjectId = TypeGet(typeName, &defined);
- if (OidIsValid(typeObjectId) && defined) {
- elog(WARN, "TypeCreate: type %s already defined", typeName);
- }
-
- /* ----------------
- * if this type has an associated elementType, then we check that
- * it is defined.
- * ----------------
- */
- if (elementTypeName) {
- elementObjectId = TypeGet(elementTypeName, &defined);
- if (!defined) {
- elog(WARN, "TypeCreate: type %s is not defined", elementTypeName);
+ register i,
+ j;
+ Relation pg_type_desc;
+ HeapScanDesc pg_type_scan;
+
+ Oid typeObjectId;
+ Oid elementObjectId = InvalidOid;
+
+ HeapTuple tup;
+ char nulls[Natts_pg_type];
+ char replaces[Natts_pg_type];
+ Datum values[Natts_pg_type];
+
+ Buffer buffer;
+ char *procname;
+ char *procs[4];
+ bool defined;
+ ItemPointerData itemPointerData;
+ TupleDesc tupDesc;
+
+ Oid argList[8];
+
+
+ static ScanKeyData typeKey[1] = {
+ {0, Anum_pg_type_typname, NameEqualRegProcedure}
+ };
+
+ fmgr_info(NameEqualRegProcedure,
+ &typeKey[0].sk_func, &typeKey[0].sk_nargs);
+
+ /* ----------------
+ * check that the type is not already defined.
+ * ----------------
+ */
+ typeObjectId = TypeGet(typeName, &defined);
+ if (OidIsValid(typeObjectId) && defined)
+ {
+ elog(WARN, "TypeCreate: type %s already defined", typeName);
+ }
+
+ /* ----------------
+ * if this type has an associated elementType, then we check that
+ * it is defined.
+ * ----------------
+ */
+ if (elementTypeName)
+ {
+ elementObjectId = TypeGet(elementTypeName, &defined);
+ if (!defined)
+ {
+ elog(WARN, "TypeCreate: type %s is not defined", elementTypeName);
+ }
+ }
+
+ /* ----------------
+ * XXX comment me
+ * ----------------
+ */
+ if (externalSize == 0)
+ {
+ externalSize = -1; /* variable length */
+ }
+
+ /* ----------------
+ * initialize arrays needed by FormHeapTuple
+ * ----------------
+ */
+ for (i = 0; i < Natts_pg_type; ++i)
+ {
+ nulls[i] = ' ';
+ replaces[i] = 'r';
+ values[i] = (Datum) NULL; /* redundant, but nice */
}
- }
-
- /* ----------------
- * XXX comment me
- * ----------------
- */
- if (externalSize == 0) {
- externalSize = -1; /* variable length */
- }
-
- /* ----------------
- * initialize arrays needed by FormHeapTuple
- * ----------------
- */
- for (i = 0; i < Natts_pg_type; ++i) {
- nulls[i] = ' ';
- replaces[i] = 'r';
- values[i] = (Datum)NULL; /* redundant, but nice */
- }
-
- /*
- * XXX
- *
- * Do this so that user-defined types have size -1 instead of zero if
- * they are variable-length - this is so that everything else in the
- * backend works.
- */
-
- if (internalSize == 0)
- internalSize = -1;
-
- /* ----------------
- * initialize the values[] information
- * ----------------
- */
- i = 0;
- values[i++] = PointerGetDatum(typeName); /* 1 */
- values[i++] = (Datum) GetUserId(); /* 2 */
- values[i++] = (Datum) internalSize; /* 3 */
- values[i++] = (Datum) externalSize; /* 4 */
- values[i++] = (Datum) passedByValue; /* 5 */
- values[i++] = (Datum) typeType; /* 6 */
- values[i++] = (Datum) (bool) 1; /* 7 */
- values[i++] = (Datum) typDelim; /* 8 */
- values[i++] = (Datum) (typeType == 'c' ? relationOid : InvalidOid); /* 9 */
- values[i++] = (Datum) elementObjectId; /* 10 */
-
- /*
- * arguments to type input and output functions must be 0
- */
- memset(argList, 0, 8 * sizeof(Oid));
-
- procs[0] = inputProcedure;
- procs[1] = outputProcedure;
- procs[2] = (receiveProcedure) ? receiveProcedure : inputProcedure;
- procs[3] = (sendProcedure) ? sendProcedure : outputProcedure;
-
- for (j = 0; j < 4; ++j) {
- procname = procs[j];
-
- tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(procname),
- Int32GetDatum(1),
- PointerGetDatum(argList),
- 0);
-
- if (!HeapTupleIsValid(tup)) {
- /*
- * it is possible for the input/output procedure
- * to take two arguments, where the second argument
- * is the element type (eg array_in/array_out)
- */
- if (OidIsValid(elementObjectId)) {
+
+ /*
+ * XXX
+ *
+ * Do this so that user-defined types have size -1 instead of zero if
+ * they are variable-length - this is so that everything else in the
+ * backend works.
+ */
+
+ if (internalSize == 0)
+ internalSize = -1;
+
+ /* ----------------
+ * initialize the values[] information
+ * ----------------
+ */
+ i = 0;
+ values[i++] = PointerGetDatum(typeName); /* 1 */
+ values[i++] = (Datum) GetUserId(); /* 2 */
+ values[i++] = (Datum) internalSize; /* 3 */
+ values[i++] = (Datum) externalSize; /* 4 */
+ values[i++] = (Datum) passedByValue; /* 5 */
+ values[i++] = (Datum) typeType; /* 6 */
+ values[i++] = (Datum) (bool) 1; /* 7 */
+ values[i++] = (Datum) typDelim; /* 8 */
+ values[i++] = (Datum) (typeType == 'c' ? relationOid : InvalidOid); /* 9 */
+ values[i++] = (Datum) elementObjectId; /* 10 */
+
+ /*
+ * arguments to type input and output functions must be 0
+ */
+ memset(argList, 0, 8 * sizeof(Oid));
+
+ procs[0] = inputProcedure;
+ procs[1] = outputProcedure;
+ procs[2] = (receiveProcedure) ? receiveProcedure : inputProcedure;
+ procs[3] = (sendProcedure) ? sendProcedure : outputProcedure;
+
+ for (j = 0; j < 4; ++j)
+ {
+ procname = procs[j];
+
tup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(procname),
- Int32GetDatum(2),
- PointerGetDatum(argList),
- 0);
- }
- if (!HeapTupleIsValid(tup)) {
- func_error("TypeCreate", procname, 1, argList);
- }
+ PointerGetDatum(procname),
+ Int32GetDatum(1),
+ PointerGetDatum(argList),
+ 0);
+
+ if (!HeapTupleIsValid(tup))
+ {
+
+ /*
+ * it is possible for the input/output procedure to take two
+ * arguments, where the second argument is the element type
+ * (eg array_in/array_out)
+ */
+ if (OidIsValid(elementObjectId))
+ {
+ tup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(procname),
+ Int32GetDatum(2),
+ PointerGetDatum(argList),
+ 0);
+ }
+ if (!HeapTupleIsValid(tup))
+ {
+ func_error("TypeCreate", procname, 1, argList);
+ }
+ }
+
+ values[i++] = (Datum) tup->t_oid; /* 11 - 14 */
}
-
- values[i++] = (Datum)tup->t_oid; /* 11 - 14 */
- }
-
- /* ----------------
- * set default alignment
- * ----------------
- */
- values[i++] = (Datum)alignment; /* 15 */
-
- /* ----------------
- * initialize the default value for this type.
- * ----------------
- */
- values[i] = (Datum)fmgr(TextInRegProcedure, /* 16 */
- PointerIsValid(defaultTypeValue)
- ? defaultTypeValue : "-"); /* XXX default typdefault */
-
- /* ----------------
- * open pg_type and begin a scan for the type name.
- * ----------------
- */
- pg_type_desc = heap_openr(TypeRelationName);
-
- /* -----------------
- * Set a write lock initially so as not upgrade a read to a write
- * when the heap_insert() or heap_replace() is called.
- * -----------------
- */
- RelationSetLockForWrite(pg_type_desc);
-
- typeKey[0].sk_argument = PointerGetDatum(typeName);
- pg_type_scan = heap_beginscan(pg_type_desc,
- 0,
- SelfTimeQual,
- 1,
- typeKey);
-
- /* ----------------
- * define the type either by adding a tuple to the type
- * relation, or by updating the fields of the "shell" tuple
- * already there.
- * ----------------
- */
- tup = heap_getnext(pg_type_scan, 0, &buffer);
- if (HeapTupleIsValid(tup)) {
- tup = heap_modifytuple(tup,
- buffer,
- pg_type_desc,
- values,
- nulls,
- replaces);
-
- /* XXX may not be necessary */
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
-
- setheapoverride(true);
- heap_replace(pg_type_desc, &itemPointerData, tup);
- setheapoverride(false);
-
- typeObjectId = tup->t_oid;
- } else {
- tupDesc = pg_type_desc->rd_att;
- tup = heap_formtuple(tupDesc,
- values,
- nulls);
-
- heap_insert(pg_type_desc, tup);
-
- typeObjectId = tup->t_oid;
- }
-
- /* ----------------
- * finish up
- * ----------------
- */
- heap_endscan(pg_type_scan);
-
- if (RelationGetRelationTupleForm(pg_type_desc)->relhasindex)
+ /* ----------------
+ * set default alignment
+ * ----------------
+ */
+ values[i++] = (Datum) alignment; /* 15 */
+
+ /* ----------------
+ * initialize the default value for this type.
+ * ----------------
+ */
+ values[i] = (Datum) fmgr(TextInRegProcedure, /* 16 */
+ PointerIsValid(defaultTypeValue)
+ ? defaultTypeValue : "-"); /* XXX default
+ * typdefault */
+
+ /* ----------------
+ * open pg_type and begin a scan for the type name.
+ * ----------------
+ */
+ pg_type_desc = heap_openr(TypeRelationName);
+
+ /* -----------------
+ * Set a write lock initially so as not upgrade a read to a write
+ * when the heap_insert() or heap_replace() is called.
+ * -----------------
+ */
+ RelationSetLockForWrite(pg_type_desc);
+
+ typeKey[0].sk_argument = PointerGetDatum(typeName);
+ pg_type_scan = heap_beginscan(pg_type_desc,
+ 0,
+ SelfTimeQual,
+ 1,
+ typeKey);
+
+ /* ----------------
+ * define the type either by adding a tuple to the type
+ * relation, or by updating the fields of the "shell" tuple
+ * already there.
+ * ----------------
+ */
+ tup = heap_getnext(pg_type_scan, 0, &buffer);
+ if (HeapTupleIsValid(tup))
+ {
+ tup = heap_modifytuple(tup,
+ buffer,
+ pg_type_desc,
+ values,
+ nulls,
+ replaces);
+
+ /* XXX may not be necessary */
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+
+ setheapoverride(true);
+ heap_replace(pg_type_desc, &itemPointerData, tup);
+ setheapoverride(false);
+
+ typeObjectId = tup->t_oid;
+ }
+ else
+ {
+ tupDesc = pg_type_desc->rd_att;
+
+ tup = heap_formtuple(tupDesc,
+ values,
+ nulls);
+
+ heap_insert(pg_type_desc, tup);
+
+ typeObjectId = tup->t_oid;
+ }
+
+ /* ----------------
+ * finish up
+ * ----------------
+ */
+ heap_endscan(pg_type_scan);
+
+ if (RelationGetRelationTupleForm(pg_type_desc)->relhasindex)
{
- Relation idescs[Num_pg_type_indices];
-
- CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup);
- CatalogCloseIndices(Num_pg_type_indices, idescs);
+ Relation idescs[Num_pg_type_indices];
+
+ CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup);
+ CatalogCloseIndices(Num_pg_type_indices, idescs);
}
- RelationUnsetLockForWrite(pg_type_desc);
- heap_close(pg_type_desc);
-
-
- return
- typeObjectId;
+ RelationUnsetLockForWrite(pg_type_desc);
+ heap_close(pg_type_desc);
+
+
+ return
+ typeObjectId;
}
/* ----------------------------------------------------------------
- * TypeRename
+ * TypeRename
*
- * This renames a type
+ * This renames a type
* ----------------------------------------------------------------
*/
void
TypeRename(char *oldTypeName, char *newTypeName)
{
- Relation pg_type_desc;
- Relation idescs[Num_pg_type_indices];
- Oid type_oid;
- HeapTuple tup;
- bool defined;
- ItemPointerData itemPointerData;
-
- /* check that that the new type is not already defined */
- type_oid = TypeGet(newTypeName, &defined);
- if (OidIsValid(type_oid) && defined) {
- elog(WARN, "TypeRename: type %s already defined", newTypeName);
- }
-
- /* get the type tuple from the catalog index scan manager */
- pg_type_desc = heap_openr(TypeRelationName);
- tup = TypeNameIndexScan(pg_type_desc, oldTypeName);
-
- /* ----------------
- * change the name of the type
- * ----------------
- */
- if (HeapTupleIsValid(tup)) {
-
- namestrcpy(& (((TypeTupleForm) GETSTRUCT(tup))->typname),newTypeName);
-
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
-
- setheapoverride(true);
- heap_replace(pg_type_desc, &itemPointerData, tup);
- setheapoverride(false);
-
- /* update the system catalog indices */
- CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup);
- CatalogCloseIndices(Num_pg_type_indices, idescs);
-
- /* all done */
- pfree(tup);
-
- } else {
- elog(WARN, "TypeRename: type %s not defined", oldTypeName);
- }
-
- /* finish up */
- heap_close(pg_type_desc);
+ Relation pg_type_desc;
+ Relation idescs[Num_pg_type_indices];
+ Oid type_oid;
+ HeapTuple tup;
+ bool defined;
+ ItemPointerData itemPointerData;
+
+ /* check that that the new type is not already defined */
+ type_oid = TypeGet(newTypeName, &defined);
+ if (OidIsValid(type_oid) && defined)
+ {
+ elog(WARN, "TypeRename: type %s already defined", newTypeName);
+ }
+
+ /* get the type tuple from the catalog index scan manager */
+ pg_type_desc = heap_openr(TypeRelationName);
+ tup = TypeNameIndexScan(pg_type_desc, oldTypeName);
+
+ /* ----------------
+ * change the name of the type
+ * ----------------
+ */
+ if (HeapTupleIsValid(tup))
+ {
+
+ namestrcpy(&(((TypeTupleForm) GETSTRUCT(tup))->typname), newTypeName);
+
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+
+ setheapoverride(true);
+ heap_replace(pg_type_desc, &itemPointerData, tup);
+ setheapoverride(false);
+
+ /* update the system catalog indices */
+ CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup);
+ CatalogCloseIndices(Num_pg_type_indices, idescs);
+
+ /* all done */
+ pfree(tup);
+
+ }
+ else
+ {
+ elog(WARN, "TypeRename: type %s not defined", oldTypeName);
+ }
+
+ /* finish up */
+ heap_close(pg_type_desc);
}
/*
* makeArrayTypeName(typeName);
- * - given a base type name, make an array of type name out of it
+ * - given a base type name, make an array of type name out of it
*
- * the CALLER is responsible for pfreeing the
+ * the CALLER is responsible for pfreeing the
*/
-char*
-makeArrayTypeName(char* typeName)
+char *
+makeArrayTypeName(char *typeName)
{
- char *arr;
+ char *arr;
+
+ if (!typeName)
+ return NULL;
+ arr = palloc(strlen(typeName) + 2);
+ arr[0] = '_';
+ strcpy(arr + 1, typeName);
- if (!typeName) return NULL;
- arr = palloc (strlen(typeName) + 2);
- arr[0] = '_';
- strcpy(arr+1, typeName);
+ return arr;
- return arr;
-
}
diff --git a/src/backend/commands/_deadcode/version.c b/src/backend/commands/_deadcode/version.c
index bac35cd4f87..c3eb6f47797 100644
--- a/src/backend/commands/_deadcode/version.c
+++ b/src/backend/commands/_deadcode/version.c
@@ -1,23 +1,23 @@
/*-------------------------------------------------------------------------
*
* version.c--
- * This file contains all the rules that govern all version semantics.
+ * This file contains all the rules that govern all version semantics.
*
* Copyright (c) 1994, Regents of the University of California
*
- * The version stuff has not been tested under postgres95 and probably doesn't
- * work! - jolly 8/19/95
- *
+ * The version stuff has not been tested under postgres95 and probably doesn't
+ * work! - jolly 8/19/95
+ *
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/_deadcode/Attic/version.c,v 1.5 1997/08/19 21:30:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/_deadcode/Attic/version.c,v 1.6 1997/09/07 04:41:04 momjian Exp $
*
* NOTES
- * At the point the version is defined, 2 physical relations are created
- * <vname>_added and <vname>_deleted.
+ * At the point the version is defined, 2 physical relations are created
+ * <vname>_added and <vname>_deleted.
*
- * In addition, 4 rules are defined which govern the semantics of versions
- * w.r.t retrieves, appends, replaces and deletes.
+ * In addition, 4 rules are defined which govern the semantics of versions
+ * w.r.t retrieves, appends, replaces and deletes.
*
*-------------------------------------------------------------------------
*/
@@ -34,29 +34,31 @@
#define MAX_QUERY_LEN 1024
-char rule_buf[MAX_QUERY_LEN];
+char rule_buf[MAX_QUERY_LEN];
+
#ifdef NOT_USED
-static char attr_list[MAX_QUERY_LEN];
+static char attr_list[MAX_QUERY_LEN];
+
#endif
/*
* problem: the version system assumes that the rules it declares will
- * be fired in the order of declaration, it also assumes
- * goh's silly instead semantics. Unfortunately, it is a pain
- * to make the version system work with the new semantics.
- * However the whole problem can be solved, and some nice
- * functionality can be achieved if we get multiple action rules
- * to work. So thats what I did -- glass
+ * be fired in the order of declaration, it also assumes
+ * goh's silly instead semantics. Unfortunately, it is a pain
+ * to make the version system work with the new semantics.
+ * However the whole problem can be solved, and some nice
+ * functionality can be achieved if we get multiple action rules
+ * to work. So thats what I did -- glass
*
* Well, at least they've been working for about 20 minutes.
- *
+ *
* So any comments in this code about 1 rule per transction are false...:)
*
*/
/*
- * This is needed because the rule system only allows
- * *1* rule to be defined per transaction.
+ * This is needed because the rule system only allows
+ * *1* rule to be defined per transaction.
*
* NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
* OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
@@ -80,267 +82,282 @@ static char attr_list[MAX_QUERY_LEN];
* a strange memory bug instead of watching the "Get Smart" marathon
* in NICK !
* DO NOT COMMIT THE XACT, just increase the Cid counter!
- * _sp.
+ * _sp.
*/
#ifdef NOT_USED
static void
eval_as_new_xact(char *query)
{
- /* WARNING! do not uncomment the following lines WARNING!
- * CommitTransactionCommand();
- * StartTransactionCommand();
- */
- CommandCounterIncrement();
- pg_eval(query, (char **) NULL, (Oid *) NULL, 0);
+
+ /*
+ * WARNING! do not uncomment the following lines WARNING!
+ * CommitTransactionCommand(); StartTransactionCommand();
+ */
+ CommandCounterIncrement();
+ pg_eval(query, (char **) NULL, (Oid *) NULL, 0);
}
+
#endif
/*
- * Define a version.
+ * Define a version.
*/
#ifdef NOT_USED
void
DefineVersion(char *name, char *fromRelname, char *date)
{
- char *bname;
- static char saved_basename[512];
- static char saved_snapshot[512];
-
- if (date == NULL) {
- /* no time ranges */
- bname = fromRelname;
- strcpy(saved_basename, (char *) bname);
- *saved_snapshot = (char)NULL;
- } else {
- /* version is a snapshot */
- bname = fromRelname;
- strcpy(saved_basename, (char *) bname);
- sprintf(saved_snapshot, "['%s']", date);
- }
-
-
- /*
- * Calls the routine ``GetAttrList'' get the list of attributes
- * from the base relation.
- * Code is put here so that we only need to look up the attribute once for
- * both appends and replaces.
- */
- setAttrList(bname);
-
- VersionCreate (name, saved_basename);
- VersionAppend (name, saved_basename);
- VersionDelete (name, saved_basename,saved_snapshot);
- VersionReplace (name, saved_basename,saved_snapshot);
- VersionRetrieve (name, saved_basename, saved_snapshot);
+ char *bname;
+ static char saved_basename[512];
+ static char saved_snapshot[512];
+
+ if (date == NULL)
+ {
+ /* no time ranges */
+ bname = fromRelname;
+ strcpy(saved_basename, (char *) bname);
+ *saved_snapshot = (char) NULL;
+ }
+ else
+ {
+ /* version is a snapshot */
+ bname = fromRelname;
+ strcpy(saved_basename, (char *) bname);
+ sprintf(saved_snapshot, "['%s']", date);
+ }
+
+
+ /*
+ * Calls the routine ``GetAttrList'' get the list of attributes from
+ * the base relation. Code is put here so that we only need to look up
+ * the attribute once for both appends and replaces.
+ */
+ setAttrList(bname);
+
+ VersionCreate(name, saved_basename);
+ VersionAppend(name, saved_basename);
+ VersionDelete(name, saved_basename, saved_snapshot);
+ VersionReplace(name, saved_basename, saved_snapshot);
+ VersionRetrieve(name, saved_basename, saved_snapshot);
}
+
#endif
/*
- * Creates the deltas.
+ * Creates the deltas.
*/
#ifdef NOT_USED
void
VersionCreate(char *vname, char *bname)
{
- static char query_buf [MAX_QUERY_LEN];
-
- /*
- * Creating the dummy version relation for triggering rules.
- */
- sprintf(query_buf, "SELECT * INTO TABLE %s from %s where 1 =2",
- vname, bname);
-
- pg_eval (query_buf, (char **) NULL, (Oid *) NULL, 0);
-
- /*
- * Creating the ``v_added'' relation
- */
- sprintf (query_buf, "SELECT * INTO TABLE %s_added from %s where 1 = 2",
- vname, bname);
- eval_as_new_xact (query_buf);
-
- /*
- * Creating the ``v_deleted'' relation.
- */
- sprintf (query_buf, "CREATE TABLE %s_del (DOID oid)", vname);
- eval_as_new_xact (query_buf);
+ static char query_buf[MAX_QUERY_LEN];
+
+ /*
+ * Creating the dummy version relation for triggering rules.
+ */
+ sprintf(query_buf, "SELECT * INTO TABLE %s from %s where 1 =2",
+ vname, bname);
+
+ pg_eval(query_buf, (char **) NULL, (Oid *) NULL, 0);
+
+ /*
+ * Creating the ``v_added'' relation
+ */
+ sprintf(query_buf, "SELECT * INTO TABLE %s_added from %s where 1 = 2",
+ vname, bname);
+ eval_as_new_xact(query_buf);
+
+ /*
+ * Creating the ``v_deleted'' relation.
+ */
+ sprintf(query_buf, "CREATE TABLE %s_del (DOID oid)", vname);
+ eval_as_new_xact(query_buf);
}
+
#endif
/*
* Given the relation name, does a catalog lookup for that relation and
* sets the global variable 'attr_list' with the list of attributes (names)
- * for that relation.
+ * for that relation.
*/
#ifdef NOT_USED
static void
setAttrList(char *bname)
{
- Relation rdesc;
- int i = 0;
- int maxattrs = 0;
- char *attrname;
- char temp_buf[512];
- int notfirst = 0;
-
- rdesc = heap_openr(bname);
- if (rdesc == NULL ) {
- elog(WARN,"Unable to expand all -- amopenr failed ");
- return;
- }
- maxattrs = RelationGetNumberOfAttributes(rdesc);
-
- attr_list[0] = '\0';
-
- for ( i = maxattrs-1 ; i > -1 ; --i ) {
- attrname = (rdesc->rd_att->attrs[i]->attname).data;
-
- if (notfirst == 1) {
- sprintf(temp_buf, ", %s = new.%s", attrname, attrname);
- } else {
- sprintf(temp_buf, "%s = new.%s", attrname, attrname);
- notfirst = 1;
+ Relation rdesc;
+ int i = 0;
+ int maxattrs = 0;
+ char *attrname;
+ char temp_buf[512];
+ int notfirst = 0;
+
+ rdesc = heap_openr(bname);
+ if (rdesc == NULL)
+ {
+ elog(WARN, "Unable to expand all -- amopenr failed ");
+ return;
+ }
+ maxattrs = RelationGetNumberOfAttributes(rdesc);
+
+ attr_list[0] = '\0';
+
+ for (i = maxattrs - 1; i > -1; --i)
+ {
+ attrname = (rdesc->rd_att->attrs[i]->attname).data;
+
+ if (notfirst == 1)
+ {
+ sprintf(temp_buf, ", %s = new.%s", attrname, attrname);
+ }
+ else
+ {
+ sprintf(temp_buf, "%s = new.%s", attrname, attrname);
+ notfirst = 1;
+ }
+ strcat(attr_list, temp_buf);
}
- strcat(attr_list, temp_buf);
- }
-
- heap_close(rdesc);
-
- return;
+
+ heap_close(rdesc);
+
+ return;
}
+
#endif
/*
* This routine defines the rule governing the append semantics of
- * versions. All tuples appended to a version gets appended to the
+ * versions. All tuples appended to a version gets appended to the
* <vname>_added relation.
*/
#ifdef NOT_USED
static void
VersionAppend(char *vname, char *bname)
{
- sprintf(rule_buf,
- "define rewrite rule %s_append is on INSERT to %s do instead append %s_added(%s)",
- vname, vname, vname, attr_list);
-
- eval_as_new_xact(rule_buf);
+ sprintf(rule_buf,
+ "define rewrite rule %s_append is on INSERT to %s do instead append %s_added(%s)",
+ vname, vname, vname, attr_list);
+
+ eval_as_new_xact(rule_buf);
}
+
#endif
/*
* This routine defines the rule governing the retrieval semantics of
* versions. To retrieve tuples from a version , we need to:
*
- * 1. Retrieve all tuples in the <vname>_added relation.
- * 2. Retrieve all tuples in the base relation which are not in
- * the <vname>_del relation.
+ * 1. Retrieve all tuples in the <vname>_added relation.
+ * 2. Retrieve all tuples in the base relation which are not in
+ * the <vname>_del relation.
*/
#ifdef NOT_USED
void
VersionRetrieve(char *vname, char *bname, char *snapshot)
{
-
- sprintf(rule_buf,
- "define rewrite rule %s_retrieve is on SELECT to %s do instead\n\
+
+ sprintf(rule_buf,
+ "define rewrite rule %s_retrieve is on SELECT to %s do instead\n\
SELECT %s_1.oid, %s_1.* from _%s in %s%s, %s_1 in (%s_added | _%s) \
where _%s.oid !!= '%s_del.DOID'",
- vname, vname, vname, vname, bname,
- bname, snapshot,
- vname, vname, bname, bname, vname);
-
- eval_as_new_xact(rule_buf);
-
- /* printf("%s\n",rule_buf); */
-
+ vname, vname, vname, vname, bname,
+ bname, snapshot,
+ vname, vname, bname, bname, vname);
+
+ eval_as_new_xact(rule_buf);
+
+ /* printf("%s\n",rule_buf); */
+
}
+
#endif
/*
- * This routine defines the rules that govern the delete semantics of
+ * This routine defines the rules that govern the delete semantics of
* versions. Two things happens when we delete a tuple from a version:
*
- * 1. If the tuple to be deleted was added to the version *after*
- * the version was created, then we simply delete the tuple
- * from the <vname>_added relation.
- * 2. If the tuple to be deleted is actually in the base relation,
- * then we have to mark that tuple as being deleted by adding
- * it to the <vname>_del relation.
+ * 1. If the tuple to be deleted was added to the version *after*
+ * the version was created, then we simply delete the tuple
+ * from the <vname>_added relation.
+ * 2. If the tuple to be deleted is actually in the base relation,
+ * then we have to mark that tuple as being deleted by adding
+ * it to the <vname>_del relation.
*/
#ifdef NOT_USED
void
VersionDelete(char *vname, char *bname, char *snapshot)
{
-
- sprintf(rule_buf,
- "define rewrite rule %s_delete1 is on delete to %s do instead\n \
+
+ sprintf(rule_buf,
+ "define rewrite rule %s_delete1 is on delete to %s do instead\n \
[delete %s_added where current.oid = %s_added.oid\n \
append %s_del(DOID = current.oid) from _%s in %s%s \
where current.oid = _%s.oid] \n",
- vname,vname,vname,vname,vname,
-bname,bname,snapshot,bname);
+ vname, vname, vname, vname, vname,
+ bname, bname, snapshot, bname);
- eval_as_new_xact(rule_buf);
+ eval_as_new_xact(rule_buf);
#ifdef OLD_REWRITE
- sprintf(rule_buf,
- "define rewrite rule %s_delete2 is on delete to %s do instead \n \
+ sprintf(rule_buf,
+ "define rewrite rule %s_delete2 is on delete to %s do instead \n \
append %s_del(DOID = current.oid) from _%s in %s%s \
where current.oid = _%s.oid \n",
- vname,vname,vname,bname,bname,snapshot,bname);
+ vname, vname, vname, bname, bname, snapshot, bname);
- eval_as_new_xact(rule_buf);
-#endif /* OLD_REWRITE */
+ eval_as_new_xact(rule_buf);
+#endif /* OLD_REWRITE */
}
+
#endif
/*
- * This routine defines the rules that govern the update semantics
- * of versions. To update a tuple in a version:
+ * This routine defines the rules that govern the update semantics
+ * of versions. To update a tuple in a version:
*
- * 1. If the tuple is in <vname>_added, we simply ``replace''
- * the tuple (as per postgres style).
- * 2. if the tuple is in the base relation, then two things have to
- * happen:
- * 2.1 The tuple is marked ``deleted'' from the base relation by
- * adding the tuple to the <vname>_del relation.
- * 2.2 A copy of the tuple is appended to the <vname>_added relation
+ * 1. If the tuple is in <vname>_added, we simply ``replace''
+ * the tuple (as per postgres style).
+ * 2. if the tuple is in the base relation, then two things have to
+ * happen:
+ * 2.1 The tuple is marked ``deleted'' from the base relation by
+ * adding the tuple to the <vname>_del relation.
+ * 2.2 A copy of the tuple is appended to the <vname>_added relation
*/
#ifdef NOT_USED
void
VersionReplace(char *vname, char *bname, char *snapshot)
{
- sprintf(rule_buf,
- "define rewrite rule %s_replace1 is on replace to %s do instead \n\
+ sprintf(rule_buf,
+ "define rewrite rule %s_replace1 is on replace to %s do instead \n\
[replace %s_added(%s) where current.oid = %s_added.oid \n\
append %s_del(DOID = current.oid) from _%s in %s%s \
where current.oid = _%s.oid\n\
append %s_added(%s) from _%s in %s%s \
where current.oid !!= '%s_added.oid' and current.oid = _%s.oid]\n",
- vname,vname,vname,attr_list,vname,
- vname,bname,bname,snapshot,bname,
-vname,attr_list,bname,bname,snapshot,vname,bname);
+ vname, vname, vname, attr_list, vname,
+ vname, bname, bname, snapshot, bname,
+ vname, attr_list, bname, bname, snapshot, vname, bname);
- eval_as_new_xact(rule_buf);
+ eval_as_new_xact(rule_buf);
-/* printf("%s\n",rule_buf); */
+/* printf("%s\n",rule_buf); */
#ifdef OLD_REWRITE
- sprintf(rule_buf,
- "define rewrite rule %s_replace2 is on replace to %s do \n\
+ sprintf(rule_buf,
+ "define rewrite rule %s_replace2 is on replace to %s do \n\
append %s_del(DOID = current.oid) from _%s in %s%s \
where current.oid = _%s.oid\n",
- vname,vname,vname,bname,bname,snapshot,bname);
+ vname, vname, vname, bname, bname, snapshot, bname);
- eval_as_new_xact(rule_buf);
+ eval_as_new_xact(rule_buf);
- sprintf(rule_buf,
- "define rewrite rule %s_replace3 is on replace to %s do instead\n\
+ sprintf(rule_buf,
+ "define rewrite rule %s_replace3 is on replace to %s do instead\n\
append %s_added(%s) from _%s in %s%s \
where current.oid !!= '%s_added.oid' and current.oid = \
_%s.oid\n",
- vname,vname, vname,attr_list,bname,bname,snapshot,vname,bname);
+ vname, vname, vname, attr_list, bname, bname, snapshot, vname, bname);
- eval_as_new_xact(rule_buf);
-#endif /* OLD_REWRITE */
-/* printf("%s\n",rule_buf); */
+ eval_as_new_xact(rule_buf);
+#endif /* OLD_REWRITE */
+/* printf("%s\n",rule_buf); */
}
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 8a1e6d59b57..42d440a8676 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -1,35 +1,35 @@
/*-------------------------------------------------------------------------
*
* async.c--
- * Asynchronous notification
+ * Asynchronous notification
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.17 1997/08/19 21:30:42 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.18 1997/09/07 04:40:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* New Async Notification Model:
* 1. Multiple backends on same machine. Multiple backends listening on
- * one relation.
+ * one relation.
*
* 2. One of the backend does a 'notify <relname>'. For all backends that
- * are listening to this relation (all notifications take place at the
- * end of commit),
- * 2.a If the process is the same as the backend process that issued
- * notification (we are notifying something that we are listening),
- * signal the corresponding frontend over the comm channel using the
- * out-of-band channel.
- * 2.b For all other listening processes, we send kill(2) to wake up
- * the listening backend.
+ * are listening to this relation (all notifications take place at the
+ * end of commit),
+ * 2.a If the process is the same as the backend process that issued
+ * notification (we are notifying something that we are listening),
+ * signal the corresponding frontend over the comm channel using the
+ * out-of-band channel.
+ * 2.b For all other listening processes, we send kill(2) to wake up
+ * the listening backend.
* 3. Upon receiving a kill(2) signal from another backend process notifying
- * that one of the relation that we are listening is being notified,
- * we can be in either of two following states:
- * 3.a We are sleeping, wake up and signal our frontend.
- * 3.b We are in middle of another transaction, wait until the end of
- * of the current transaction and signal our frontend.
+ * that one of the relation that we are listening is being notified,
+ * we can be in either of two following states:
+ * 3.a We are sleeping, wake up and signal our frontend.
+ * 3.b We are in middle of another transaction, wait until the end of
+ * of the current transaction and signal our frontend.
* 4. Each frontend receives this notification and prcesses accordingly.
*
* -- jw, 12/28/93
@@ -42,16 +42,16 @@
* Model is:
* 1. Multiple backends on same machine.
*
- * 2. Query on one backend sends stuff over an asynchronous portal by
- * appending to a relation, and then doing an async. notification
- * (which takes place after commit) to all listeners on this relation.
+ * 2. Query on one backend sends stuff over an asynchronous portal by
+ * appending to a relation, and then doing an async. notification
+ * (which takes place after commit) to all listeners on this relation.
*
- * 3. Async. notification results in all backends listening on relation
- * to be woken up, by a process signal kill(2), with name of relation
- * passed in shared memory.
+ * 3. Async. notification results in all backends listening on relation
+ * to be woken up, by a process signal kill(2), with name of relation
+ * passed in shared memory.
*
* 4. Each backend notifies its respective frontend over the comm
- * channel using the out-of-band channel.
+ * channel using the out-of-band channel.
*
* 5. Each frontend receives this notification and processes accordingly.
*
@@ -62,7 +62,7 @@
#include <signal.h>
#include <string.h>
#include <errno.h>
-#include <sys/types.h> /* Needed by in.h on Ultrix */
+#include <sys/types.h> /* Needed by in.h on Ultrix */
#include <netinet/in.h>
#include <postgres.h>
@@ -75,546 +75,585 @@
#include <catalog/pg_proc.h>
#include <catalog/catname.h>
#include <catalog/pg_listener.h>
-#include <access/heapam.h>
+#include <access/heapam.h>
#include <storage/bufmgr.h>
#include <nodes/memnodes.h>
#include <utils/mcxt.h>
#include <commands/async.h>
#include <libpq/libpq.h>
-#include <port-protos.h> /* for strdup() */
+#include <port-protos.h> /* for strdup() */
#include <storage/lmgr.h>
-static int notifyFrontEndPending = 0;
-static int notifyIssued = 0;
-static Dllist *pendingNotifies = NULL;
+static int notifyFrontEndPending = 0;
+static int notifyIssued = 0;
+static Dllist *pendingNotifies = NULL;
-static int AsyncExistsPendingNotify(char *);
-static void ClearPendingNotify(void);
-static void Async_NotifyFrontEnd(void);
-static void Async_Unlisten(char *relname, int pid);
-static void Async_UnlistenOnExit(int code, char *relname);
-
+static int AsyncExistsPendingNotify(char *);
+static void ClearPendingNotify(void);
+static void Async_NotifyFrontEnd(void);
+static void Async_Unlisten(char *relname, int pid);
+static void Async_UnlistenOnExit(int code, char *relname);
+
/*
*--------------------------------------------------------------
* Async_NotifyHandler --
*
- * This is the signal handler for SIGUSR2. When the backend
- * is signaled, the backend can be in two states.
- * 1. If the backend is in the middle of another transaction,
- * we set the flag, notifyFrontEndPending, and wait until
- * the end of the transaction to notify the front end.
- * 2. If the backend is not in the middle of another transaction,
- * we notify the front end immediately.
+ * This is the signal handler for SIGUSR2. When the backend
+ * is signaled, the backend can be in two states.
+ * 1. If the backend is in the middle of another transaction,
+ * we set the flag, notifyFrontEndPending, and wait until
+ * the end of the transaction to notify the front end.
+ * 2. If the backend is not in the middle of another transaction,
+ * we notify the front end immediately.
*
- * -- jw, 12/28/93
+ * -- jw, 12/28/93
* Results:
- * none
+ * none
*
* Side effects:
- * none
+ * none
*/
void
Async_NotifyHandler(SIGNAL_ARGS)
{
- extern TransactionState CurrentTransactionState;
-
- if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
- (CurrentTransactionState->blockState == TRANS_DEFAULT)) {
+ extern TransactionState CurrentTransactionState;
+
+ if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
+ (CurrentTransactionState->blockState == TRANS_DEFAULT))
+ {
#ifdef ASYNC_DEBUG
- elog(DEBUG, "Waking up sleeping backend process");
+ elog(DEBUG, "Waking up sleeping backend process");
#endif
- Async_NotifyFrontEnd();
+ Async_NotifyFrontEnd();
- }else {
+ }
+ else
+ {
#ifdef ASYNC_DEBUG
- elog(DEBUG, "Process is in the middle of another transaction, state = %d, block state = %d",
- CurrentTransactionState->state,
- CurrentTransactionState->blockState);
+ elog(DEBUG, "Process is in the middle of another transaction, state = %d, block state = %d",
+ CurrentTransactionState->state,
+ CurrentTransactionState->blockState);
#endif
- notifyFrontEndPending = 1;
- }
+ notifyFrontEndPending = 1;
+ }
}
/*
*--------------------------------------------------------------
* Async_Notify --
*
- * Adds the relation to the list of pending notifies.
- * All notification happens at end of commit.
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * Adds the relation to the list of pending notifies.
+ * All notification happens at end of commit.
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*
- * All notification of backend processes happens here,
- * then each backend notifies its corresponding front end at
- * the end of commit.
+ * All notification of backend processes happens here,
+ * then each backend notifies its corresponding front end at
+ * the end of commit.
*
- * This correspond to 'notify <relname>' command
- * -- jw, 12/28/93
+ * This correspond to 'notify <relname>' command
+ * -- jw, 12/28/93
*
* Results:
- * XXX
+ * XXX
*
* Side effects:
- * All tuples for relname in pg_listener are updated.
+ * All tuples for relname in pg_listener are updated.
*
*--------------------------------------------------------------
*/
void
Async_Notify(char *relname)
{
-
- HeapTuple lTuple, rTuple;
- Relation lRel;
- HeapScanDesc sRel;
- TupleDesc tdesc;
- ScanKeyData key;
- Buffer b;
- Datum d, value[3];
- bool isnull;
- char repl[3], nulls[3];
-
- char *notifyName;
-
+
+ HeapTuple lTuple,
+ rTuple;
+ Relation lRel;
+ HeapScanDesc sRel;
+ TupleDesc tdesc;
+ ScanKeyData key;
+ Buffer b;
+ Datum d,
+ value[3];
+ bool isnull;
+ char repl[3],
+ nulls[3];
+
+ char *notifyName;
+
#ifdef ASYNC_DEBUG
- elog(DEBUG,"Async_Notify: %s",relname);
+ elog(DEBUG, "Async_Notify: %s", relname);
#endif
-
- if (!pendingNotifies)
- pendingNotifies = DLNewList();
-
- /*
- * Allocate memory from the global malloc pool because it needs to be
- * referenced also when the transaction is finished. DZ - 26-08-1996
- */
- notifyName = strdup(relname);
- DLAddHead(pendingNotifies, DLNewElem(notifyName));
-
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_listener_relname,
- NameEqualRegProcedure,
- PointerGetDatum(notifyName));
-
- lRel = heap_openr(ListenerRelationName);
- tdesc = RelationGetTupleDescriptor(lRel);
- RelationSetLockForWrite(lRel);
- sRel = heap_beginscan(lRel, 0, NowTimeQual, 1, &key);
-
- nulls[0] = nulls[1] = nulls[2] = ' ';
- repl[0] = repl[1] = repl[2] = ' ';
- repl[Anum_pg_listener_notify - 1] = 'r';
- value[0] = value[1] = value[2] = (Datum) 0;
- value[Anum_pg_listener_notify - 1] = Int32GetDatum(1);
-
- while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b))) {
- d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_notify,
- tdesc, &isnull);
- if (!DatumGetInt32(d)) {
- rTuple = heap_modifytuple(lTuple, b, lRel, value, nulls, repl);
- heap_replace(lRel, &lTuple->t_ctid, rTuple);
+
+ if (!pendingNotifies)
+ pendingNotifies = DLNewList();
+
+ /*
+ * Allocate memory from the global malloc pool because it needs to be
+ * referenced also when the transaction is finished. DZ - 26-08-1996
+ */
+ notifyName = strdup(relname);
+ DLAddHead(pendingNotifies, DLNewElem(notifyName));
+
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_listener_relname,
+ NameEqualRegProcedure,
+ PointerGetDatum(notifyName));
+
+ lRel = heap_openr(ListenerRelationName);
+ tdesc = RelationGetTupleDescriptor(lRel);
+ RelationSetLockForWrite(lRel);
+ sRel = heap_beginscan(lRel, 0, NowTimeQual, 1, &key);
+
+ nulls[0] = nulls[1] = nulls[2] = ' ';
+ repl[0] = repl[1] = repl[2] = ' ';
+ repl[Anum_pg_listener_notify - 1] = 'r';
+ value[0] = value[1] = value[2] = (Datum) 0;
+ value[Anum_pg_listener_notify - 1] = Int32GetDatum(1);
+
+ while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b)))
+ {
+ d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_notify,
+ tdesc, &isnull);
+ if (!DatumGetInt32(d))
+ {
+ rTuple = heap_modifytuple(lTuple, b, lRel, value, nulls, repl);
+ heap_replace(lRel, &lTuple->t_ctid, rTuple);
+ }
+ ReleaseBuffer(b);
}
- ReleaseBuffer(b);
- }
- heap_endscan(sRel);
- RelationUnsetLockForWrite(lRel);
- heap_close(lRel);
- notifyIssued = 1;
+ heap_endscan(sRel);
+ RelationUnsetLockForWrite(lRel);
+ heap_close(lRel);
+ notifyIssued = 1;
}
/*
*--------------------------------------------------------------
* Async_NotifyAtCommit --
*
- * Signal our corresponding frontend process on relations that
- * were notified. Signal all other backend process that
- * are listening also.
+ * Signal our corresponding frontend process on relations that
+ * were notified. Signal all other backend process that
+ * are listening also.
*
- * -- jw, 12/28/93
+ * -- jw, 12/28/93
*
* Results:
- * XXX
+ * XXX
*
* Side effects:
- * Tuples in pg_listener that has our listenerpid are updated so
- * that the notification is 0. We do not want to notify frontend
- * more than once.
+ * Tuples in pg_listener that has our listenerpid are updated so
+ * that the notification is 0. We do not want to notify frontend
+ * more than once.
*
- * -- jw, 12/28/93
+ * -- jw, 12/28/93
*
*--------------------------------------------------------------
*/
void
Async_NotifyAtCommit()
{
- HeapTuple lTuple;
- Relation lRel;
- HeapScanDesc sRel;
- TupleDesc tdesc;
- ScanKeyData key;
- Datum d;
- int ourpid;
- bool isnull;
- Buffer b;
- extern TransactionState CurrentTransactionState;
-
- if (!pendingNotifies)
- pendingNotifies = DLNewList();
-
- if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
- (CurrentTransactionState->blockState == TRANS_DEFAULT)) {
-
- if (notifyIssued) { /* 'notify <relname>' issued by us */
- notifyIssued = 0;
- StartTransactionCommand();
+ HeapTuple lTuple;
+ Relation lRel;
+ HeapScanDesc sRel;
+ TupleDesc tdesc;
+ ScanKeyData key;
+ Datum d;
+ int ourpid;
+ bool isnull;
+ Buffer b;
+ extern TransactionState CurrentTransactionState;
+
+ if (!pendingNotifies)
+ pendingNotifies = DLNewList();
+
+ if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
+ (CurrentTransactionState->blockState == TRANS_DEFAULT))
+ {
+
+ if (notifyIssued)
+ { /* 'notify <relname>' issued by us */
+ notifyIssued = 0;
+ StartTransactionCommand();
#ifdef ASYNC_DEBUG
- elog(DEBUG, "Async_NotifyAtCommit.");
+ elog(DEBUG, "Async_NotifyAtCommit.");
#endif
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_listener_notify,
- Integer32EqualRegProcedure,
- Int32GetDatum(1));
- lRel = heap_openr(ListenerRelationName);
- RelationSetLockForWrite(lRel);
- sRel = heap_beginscan(lRel, 0, NowTimeQual, 1, &key);
- tdesc = RelationGetTupleDescriptor(lRel);
- ourpid = getpid();
-
- while (HeapTupleIsValid(lTuple = heap_getnext(sRel,0, &b))) {
- d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_relname,
- tdesc, &isnull);
-
- if (AsyncExistsPendingNotify((char *) DatumGetPointer(d))) {
- d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_pid,
- tdesc, &isnull);
-
- if (ourpid == DatumGetInt32(d)) {
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_listener_notify,
+ Integer32EqualRegProcedure,
+ Int32GetDatum(1));
+ lRel = heap_openr(ListenerRelationName);
+ RelationSetLockForWrite(lRel);
+ sRel = heap_beginscan(lRel, 0, NowTimeQual, 1, &key);
+ tdesc = RelationGetTupleDescriptor(lRel);
+ ourpid = getpid();
+
+ while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b)))
+ {
+ d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_relname,
+ tdesc, &isnull);
+
+ if (AsyncExistsPendingNotify((char *) DatumGetPointer(d)))
+ {
+ d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_pid,
+ tdesc, &isnull);
+
+ if (ourpid == DatumGetInt32(d))
+ {
#ifdef ASYNC_DEBUG
- elog(DEBUG, "Notifying self, setting notifyFronEndPending to 1");
+ elog(DEBUG, "Notifying self, setting notifyFronEndPending to 1");
#endif
- notifyFrontEndPending = 1;
- } else {
+ notifyFrontEndPending = 1;
+ }
+ else
+ {
#ifdef ASYNC_DEBUG
- elog(DEBUG, "Notifying others");
+ elog(DEBUG, "Notifying others");
#endif
#ifdef HAVE_KILL
- if (kill(DatumGetInt32(d), SIGUSR2) < 0) {
- if (errno == ESRCH) {
- heap_delete(lRel, &lTuple->t_ctid);
- }
+ if (kill(DatumGetInt32(d), SIGUSR2) < 0)
+ {
+ if (errno == ESRCH)
+ {
+ heap_delete(lRel, &lTuple->t_ctid);
+ }
+ }
+#endif
+ }
+ }
+ ReleaseBuffer(b);
}
-#endif
- }
+ heap_endscan(sRel);
+ RelationUnsetLockForWrite(lRel);
+ heap_close(lRel);
+
+ CommitTransactionCommand();
+ ClearPendingNotify();
}
- ReleaseBuffer(b);
- }
- heap_endscan(sRel);
- RelationUnsetLockForWrite(lRel);
- heap_close(lRel);
- CommitTransactionCommand();
- ClearPendingNotify();
- }
-
- if (notifyFrontEndPending) { /* we need to notify the frontend of
- all pending notifies. */
- notifyFrontEndPending = 1;
- Async_NotifyFrontEnd();
+ if (notifyFrontEndPending)
+ { /* we need to notify the frontend of all
+ * pending notifies. */
+ notifyFrontEndPending = 1;
+ Async_NotifyFrontEnd();
+ }
}
- }
}
/*
*--------------------------------------------------------------
* Async_NotifyAtAbort --
*
- * Gets rid of pending notifies. List elements are automatically
- * freed through memory context.
- *
+ * Gets rid of pending notifies. List elements are automatically
+ * freed through memory context.
+ *
*
* Results:
- * XXX
+ * XXX
*
* Side effects:
- * XXX
+ * XXX
*
*--------------------------------------------------------------
*/
void
Async_NotifyAtAbort()
{
- extern TransactionState CurrentTransactionState;
-
- if (notifyIssued) {
- ClearPendingNotify();
- }
- notifyIssued = 0;
- if (pendingNotifies)
- DLFreeList(pendingNotifies);
- pendingNotifies = DLNewList();
-
- if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
- (CurrentTransactionState->blockState == TRANS_DEFAULT)) {
- if (notifyFrontEndPending) { /* don't forget to notify front end */
- Async_NotifyFrontEnd();
+ extern TransactionState CurrentTransactionState;
+
+ if (notifyIssued)
+ {
+ ClearPendingNotify();
+ }
+ notifyIssued = 0;
+ if (pendingNotifies)
+ DLFreeList(pendingNotifies);
+ pendingNotifies = DLNewList();
+
+ if ((CurrentTransactionState->state == TRANS_DEFAULT) &&
+ (CurrentTransactionState->blockState == TRANS_DEFAULT))
+ {
+ if (notifyFrontEndPending)
+ { /* don't forget to notify front end */
+ Async_NotifyFrontEnd();
+ }
}
- }
}
/*
*--------------------------------------------------------------
* Async_Listen --
*
- * Register a backend (identified by its Unix PID) as listening
- * on the specified relation.
+ * Register a backend (identified by its Unix PID) as listening
+ * on the specified relation.
*
- * This corresponds to the 'listen <relation>' command in SQL
+ * This corresponds to the 'listen <relation>' command in SQL
*
- * One listener per relation, pg_listener relation is keyed
- * on (relname,pid) to provide multiple listeners in future.
+ * One listener per relation, pg_listener relation is keyed
+ * on (relname,pid) to provide multiple listeners in future.
*
* Results:
- * pg_listeners is updated.
+ * pg_listeners is updated.
*
* Side effects:
- * XXX
+ * XXX
*
*--------------------------------------------------------------
*/
void
Async_Listen(char *relname, int pid)
{
- Datum values[Natts_pg_listener];
- char nulls[Natts_pg_listener];
- TupleDesc tdesc;
- HeapScanDesc s;
- HeapTuple htup,tup;
- Relation lDesc;
- Buffer b;
- Datum d;
- int i;
- bool isnull;
- int alreadyListener = 0;
- int ourPid = getpid();
- char *relnamei;
- TupleDesc tupDesc;
-
+ Datum values[Natts_pg_listener];
+ char nulls[Natts_pg_listener];
+ TupleDesc tdesc;
+ HeapScanDesc s;
+ HeapTuple htup,
+ tup;
+ Relation lDesc;
+ Buffer b;
+ Datum d;
+ int i;
+ bool isnull;
+ int alreadyListener = 0;
+ int ourPid = getpid();
+ char *relnamei;
+ TupleDesc tupDesc;
+
#ifdef ASYNC_DEBUG
- elog(DEBUG,"Async_Listen: %s",relname);
+ elog(DEBUG, "Async_Listen: %s", relname);
#endif
- for (i = 0 ; i < Natts_pg_listener; i++) {
- nulls[i] = ' ';
- values[i] = PointerGetDatum(NULL);
- }
-
- i = 0;
- values[i++] = (Datum) relname;
- values[i++] = (Datum) pid;
- values[i++] = (Datum) 0; /* no notifies pending */
-
- lDesc = heap_openr(ListenerRelationName);
- RelationSetLockForWrite(lDesc);
-
- /* is someone already listening. One listener per relation */
- tdesc = RelationGetTupleDescriptor(lDesc);
- s = heap_beginscan(lDesc,0,NowTimeQual,0,(ScanKey)NULL);
- while (HeapTupleIsValid(htup = heap_getnext(s,0,&b))) {
- d = (Datum) heap_getattr(htup,b,Anum_pg_listener_relname,tdesc,
- &isnull);
- relnamei = DatumGetPointer(d);
- if (!strncmp(relnamei,relname, NAMEDATALEN)) {
- d = (Datum) heap_getattr(htup,b,Anum_pg_listener_pid,tdesc,&isnull);
- pid = DatumGetInt32(d);
- if (pid == ourPid) {
- alreadyListener = 1;
- }
+ for (i = 0; i < Natts_pg_listener; i++)
+ {
+ nulls[i] = ' ';
+ values[i] = PointerGetDatum(NULL);
}
- ReleaseBuffer(b);
- }
- heap_endscan(s);
-
- if (alreadyListener) {
- elog(NOTICE, "Async_Listen: We are already listening on %s",
- relname);
- return;
- }
-
- tupDesc = lDesc->rd_att;
- tup = heap_formtuple(tupDesc,
- values,
- nulls);
- heap_insert(lDesc, tup);
-
- pfree(tup);
- /* if (alreadyListener) {
- elog(NOTICE,"Async_Listen: already one listener on %s (possibly dead)",relname);
- }*/
-
- RelationUnsetLockForWrite(lDesc);
- heap_close(lDesc);
-
- /*
- * now that we are listening, we should make a note to ourselves
- * to unlisten prior to dying.
- */
- relnamei = malloc(NAMEDATALEN); /* persists to process exit */
- strNcpy(relnamei, relname, NAMEDATALEN-1);
- on_exitpg(Async_UnlistenOnExit, (caddr_t) relnamei);
+
+ i = 0;
+ values[i++] = (Datum) relname;
+ values[i++] = (Datum) pid;
+ values[i++] = (Datum) 0; /* no notifies pending */
+
+ lDesc = heap_openr(ListenerRelationName);
+ RelationSetLockForWrite(lDesc);
+
+ /* is someone already listening. One listener per relation */
+ tdesc = RelationGetTupleDescriptor(lDesc);
+ s = heap_beginscan(lDesc, 0, NowTimeQual, 0, (ScanKey) NULL);
+ while (HeapTupleIsValid(htup = heap_getnext(s, 0, &b)))
+ {
+ d = (Datum) heap_getattr(htup, b, Anum_pg_listener_relname, tdesc,
+ &isnull);
+ relnamei = DatumGetPointer(d);
+ if (!strncmp(relnamei, relname, NAMEDATALEN))
+ {
+ d = (Datum) heap_getattr(htup, b, Anum_pg_listener_pid, tdesc, &isnull);
+ pid = DatumGetInt32(d);
+ if (pid == ourPid)
+ {
+ alreadyListener = 1;
+ }
+ }
+ ReleaseBuffer(b);
+ }
+ heap_endscan(s);
+
+ if (alreadyListener)
+ {
+ elog(NOTICE, "Async_Listen: We are already listening on %s",
+ relname);
+ return;
+ }
+
+ tupDesc = lDesc->rd_att;
+ tup = heap_formtuple(tupDesc,
+ values,
+ nulls);
+ heap_insert(lDesc, tup);
+
+ pfree(tup);
+
+ /*
+ * if (alreadyListener) { elog(NOTICE,"Async_Listen: already one
+ * listener on %s (possibly dead)",relname); }
+ */
+
+ RelationUnsetLockForWrite(lDesc);
+ heap_close(lDesc);
+
+ /*
+ * now that we are listening, we should make a note to ourselves to
+ * unlisten prior to dying.
+ */
+ relnamei = malloc(NAMEDATALEN); /* persists to process exit */
+ strNcpy(relnamei, relname, NAMEDATALEN - 1);
+ on_exitpg(Async_UnlistenOnExit, (caddr_t) relnamei);
}
/*
*--------------------------------------------------------------
* Async_Unlisten --
*
- * Remove the backend from the list of listening backends
- * for the specified relation.
- *
- * This would correspond to the 'unlisten <relation>'
- * command, but there isn't one yet.
+ * Remove the backend from the list of listening backends
+ * for the specified relation.
+ *
+ * This would correspond to the 'unlisten <relation>'
+ * command, but there isn't one yet.
*
* Results:
- * pg_listeners is updated.
+ * pg_listeners is updated.
*
* Side effects:
- * XXX
+ * XXX
*
*--------------------------------------------------------------
*/
static void
Async_Unlisten(char *relname, int pid)
{
- Relation lDesc;
- HeapTuple lTuple;
-
- lTuple = SearchSysCacheTuple(LISTENREL, PointerGetDatum(relname),
- Int32GetDatum(pid),
- 0,0);
- lDesc = heap_openr(ListenerRelationName);
- RelationSetLockForWrite(lDesc);
-
- if (lTuple != NULL) {
- heap_delete(lDesc,&lTuple->t_ctid);
- }
-
- RelationUnsetLockForWrite(lDesc);
- heap_close(lDesc);
+ Relation lDesc;
+ HeapTuple lTuple;
+
+ lTuple = SearchSysCacheTuple(LISTENREL, PointerGetDatum(relname),
+ Int32GetDatum(pid),
+ 0, 0);
+ lDesc = heap_openr(ListenerRelationName);
+ RelationSetLockForWrite(lDesc);
+
+ if (lTuple != NULL)
+ {
+ heap_delete(lDesc, &lTuple->t_ctid);
+ }
+
+ RelationUnsetLockForWrite(lDesc);
+ heap_close(lDesc);
}
static void
Async_UnlistenOnExit(int code, /* from exitpg */
- char *relname)
+ char *relname)
{
- Async_Unlisten((char *) relname, getpid());
+ Async_Unlisten((char *) relname, getpid());
}
/*
* --------------------------------------------------------------
* Async_NotifyFrontEnd --
*
- * Perform an asynchronous notification to front end over
- * portal comm channel. The name of the relation which contains the
- * data is sent to the front end.
+ * Perform an asynchronous notification to front end over
+ * portal comm channel. The name of the relation which contains the
+ * data is sent to the front end.
*
- * We remove the notification flag from the pg_listener tuple
- * associated with our process.
+ * We remove the notification flag from the pg_listener tuple
+ * associated with our process.
*
* Results:
- * XXX
+ * XXX
*
* Side effects:
*
- * We make use of the out-of-band channel to transmit the
- * notification to the front end. The actual data transfer takes
- * place at the front end's request.
+ * We make use of the out-of-band channel to transmit the
+ * notification to the front end. The actual data transfer takes
+ * place at the front end's request.
*
* --------------------------------------------------------------
*/
-GlobalMemory notifyContext = NULL;
+GlobalMemory notifyContext = NULL;
static void
Async_NotifyFrontEnd()
{
- extern CommandDest whereToSendOutput;
- HeapTuple lTuple, rTuple;
- Relation lRel;
- HeapScanDesc sRel;
- TupleDesc tdesc;
- ScanKeyData key[2];
- Datum d, value[3];
- char repl[3], nulls[3];
- Buffer b;
- int ourpid;
- bool isnull;
-
- notifyFrontEndPending = 0;
-
+ extern CommandDest whereToSendOutput;
+ HeapTuple lTuple,
+ rTuple;
+ Relation lRel;
+ HeapScanDesc sRel;
+ TupleDesc tdesc;
+ ScanKeyData key[2];
+ Datum d,
+ value[3];
+ char repl[3],
+ nulls[3];
+ Buffer b;
+ int ourpid;
+ bool isnull;
+
+ notifyFrontEndPending = 0;
+
#ifdef ASYNC_DEBUG
- elog(DEBUG, "Async_NotifyFrontEnd: notifying front end.");
+ elog(DEBUG, "Async_NotifyFrontEnd: notifying front end.");
#endif
-
- StartTransactionCommand();
- ourpid = getpid();
- ScanKeyEntryInitialize(&key[0], 0,
- Anum_pg_listener_notify,
- Integer32EqualRegProcedure,
- Int32GetDatum(1));
- ScanKeyEntryInitialize(&key[1], 0,
- Anum_pg_listener_pid,
- Integer32EqualRegProcedure,
- Int32GetDatum(ourpid));
- lRel = heap_openr(ListenerRelationName);
- RelationSetLockForWrite(lRel);
- tdesc = RelationGetTupleDescriptor(lRel);
- sRel = heap_beginscan(lRel, 0, NowTimeQual, 2, key);
-
- nulls[0] = nulls[1] = nulls[2] = ' ';
- repl[0] = repl[1] = repl[2] = ' ';
- repl[Anum_pg_listener_notify - 1] = 'r';
- value[0] = value[1] = value[2] = (Datum) 0;
- value[Anum_pg_listener_notify - 1] = Int32GetDatum(0);
-
- while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0,&b))) {
- d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_relname,
- tdesc, &isnull);
- rTuple = heap_modifytuple(lTuple, b, lRel, value, nulls, repl);
- heap_replace(lRel, &lTuple->t_ctid, rTuple);
-
- /* notifying the front end */
-
- if (whereToSendOutput == Remote) {
- pq_putnchar("A", 1);
- pq_putint(ourpid, 4);
- pq_putstr(DatumGetName(d)->data);
- pq_flush();
- } else {
- elog(NOTICE, "Async_NotifyFrontEnd: no asynchronous notification to frontend on interactive sessions");
+
+ StartTransactionCommand();
+ ourpid = getpid();
+ ScanKeyEntryInitialize(&key[0], 0,
+ Anum_pg_listener_notify,
+ Integer32EqualRegProcedure,
+ Int32GetDatum(1));
+ ScanKeyEntryInitialize(&key[1], 0,
+ Anum_pg_listener_pid,
+ Integer32EqualRegProcedure,
+ Int32GetDatum(ourpid));
+ lRel = heap_openr(ListenerRelationName);
+ RelationSetLockForWrite(lRel);
+ tdesc = RelationGetTupleDescriptor(lRel);
+ sRel = heap_beginscan(lRel, 0, NowTimeQual, 2, key);
+
+ nulls[0] = nulls[1] = nulls[2] = ' ';
+ repl[0] = repl[1] = repl[2] = ' ';
+ repl[Anum_pg_listener_notify - 1] = 'r';
+ value[0] = value[1] = value[2] = (Datum) 0;
+ value[Anum_pg_listener_notify - 1] = Int32GetDatum(0);
+
+ while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b)))
+ {
+ d = (Datum) heap_getattr(lTuple, b, Anum_pg_listener_relname,
+ tdesc, &isnull);
+ rTuple = heap_modifytuple(lTuple, b, lRel, value, nulls, repl);
+ heap_replace(lRel, &lTuple->t_ctid, rTuple);
+
+ /* notifying the front end */
+
+ if (whereToSendOutput == Remote)
+ {
+ pq_putnchar("A", 1);
+ pq_putint(ourpid, 4);
+ pq_putstr(DatumGetName(d)->data);
+ pq_flush();
+ }
+ else
+ {
+ elog(NOTICE, "Async_NotifyFrontEnd: no asynchronous notification to frontend on interactive sessions");
+ }
+ ReleaseBuffer(b);
}
- ReleaseBuffer(b);
- }
- CommitTransactionCommand();
+ CommitTransactionCommand();
}
static int
AsyncExistsPendingNotify(char *relname)
{
- Dlelem* p;
- for (p = DLGetHead(pendingNotifies);
- p != NULL;
- p = DLGetSucc(p)) {
- /* Use NAMEDATALEN for relname comparison. DZ - 26-08-1996 */
- if (!strncmp(DLE_VAL(p), relname, NAMEDATALEN))
- return 1;
- }
-
- return 0;
+ Dlelem *p;
+
+ for (p = DLGetHead(pendingNotifies);
+ p != NULL;
+ p = DLGetSucc(p))
+ {
+ /* Use NAMEDATALEN for relname comparison. DZ - 26-08-1996 */
+ if (!strncmp(DLE_VAL(p), relname, NAMEDATALEN))
+ return 1;
+ }
+
+ return 0;
}
static void
ClearPendingNotify()
{
- Dlelem* p;
- while ( (p = DLRemHead(pendingNotifies)) != NULL)
- free(DLE_VAL(p));
-}
+ Dlelem *p;
+ while ((p = DLRemHead(pendingNotifies)) != NULL)
+ free(DLE_VAL(p));
+}
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 65a9c041643..2b18cb46df0 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* cluster.c--
- * Paul Brown's implementation of cluster index.
+ * Paul Brown's implementation of cluster index.
*
- * I am going to use the rename function as a model for this in the
- * parser and executor, and the vacuum code as an example in this
- * file. As I go - in contrast to the rest of postgres - there will
- * be BUCKETS of comments. This is to allow reviewers to understand
- * my (probably bogus) assumptions about the way this works.
- * [pbrown '94]
+ * I am going to use the rename function as a model for this in the
+ * parser and executor, and the vacuum code as an example in this
+ * file. As I go - in contrast to the rest of postgres - there will
+ * be BUCKETS of comments. This is to allow reviewers to understand
+ * my (probably bogus) assumptions about the way this works.
+ * [pbrown '94]
*
* Copyright (c) 1994-5, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.13 1997/08/19 21:30:45 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.14 1997/09/07 04:40:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -47,307 +47,323 @@
#include <optimizer/internal.h>
#ifndef NO_SECURITY
#include <utils/acl.h>
-#endif /* !NO_SECURITY */
+#endif /* !NO_SECURITY */
static Relation copy_heap(Oid OIDOldHeap);
-static void copy_index(Oid OIDOldIndex, Oid OIDNewHeap);
-static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex);
+static void copy_index(Oid OIDOldIndex, Oid OIDNewHeap);
+static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex);
/*
* cluster
*
- * Check that the relation is a relation in the appropriate user
- * ACL. I will use the same security that limits users on the
- * renamerel() function.
+ * Check that the relation is a relation in the appropriate user
+ * ACL. I will use the same security that limits users on the
+ * renamerel() function.
*
- * Check that the index specified is appropriate for the task
- * ( ie it's an index over this relation ). This is trickier.
+ * Check that the index specified is appropriate for the task
+ * ( ie it's an index over this relation ). This is trickier.
*
- * Create a list of all the other indicies on this relation. Because
- * the cluster will wreck all the tids, I'll need to destroy bogus
- * indicies. The user will have to re-create them. Not nice, but
- * I'm not a nice guy. The alternative is to try some kind of post
- * destroy re-build. This may be possible. I'll check out what the
- * index create functiond want in the way of paramaters. On the other
- * hand, re-creating n indicies may blow out the space.
+ * Create a list of all the other indicies on this relation. Because
+ * the cluster will wreck all the tids, I'll need to destroy bogus
+ * indicies. The user will have to re-create them. Not nice, but
+ * I'm not a nice guy. The alternative is to try some kind of post
+ * destroy re-build. This may be possible. I'll check out what the
+ * index create functiond want in the way of paramaters. On the other
+ * hand, re-creating n indicies may blow out the space.
*
- * Create new (temporary) relations for the base heap and the new
- * index.
- *
- * Exclusively lock the relations.
- *
- * Create new clustered index and base heap relation.
+ * Create new (temporary) relations for the base heap and the new
+ * index.
+ *
+ * Exclusively lock the relations.
+ *
+ * Create new clustered index and base heap relation.
*
*/
void
cluster(char oldrelname[], char oldindexname[])
{
- Oid OIDOldHeap, OIDOldIndex, OIDNewHeap;
-
- Relation OldHeap, OldIndex;
- Relation NewHeap;
-
- char NewIndexName[NAMEDATALEN];
- char NewHeapName[NAMEDATALEN];
- char saveoldrelname[NAMEDATALEN];
- char saveoldindexname[NAMEDATALEN];
-
-
- /* Save the old names because they will get lost when the old relations
- * are destroyed.
- */
- strcpy(saveoldrelname, oldrelname);
- strcpy(saveoldindexname, oldindexname);
-
- /*
- *
- * I'm going to force all checking back into the commands.c function.
- *
- * Get the list if indicies for this relation. If the index we want
- * is among them, do not add it to the 'kill' list, as it will be
- * handled by the 'clean up' code which commits this transaction.
- *
- * I'm not using the SysCache, because this will happen but
- * once, and the slow way is the sure way in this case.
- *
- */
- /*
- * Like vacuum, cluster spans transactions, so I'm going to handle it in
- * the same way.
- */
-
- /* matches the StartTransaction in PostgresMain() */
-
- OldHeap = heap_openr(oldrelname);
- if (!RelationIsValid(OldHeap)) {
- elog(WARN, "cluster: unknown relation: \"%s\"",
- oldrelname);
- }
- OIDOldHeap = OldHeap->rd_id; /* Get OID for the index scan */
-
- OldIndex=index_openr(oldindexname);/* Open old index relation */
- if (!RelationIsValid(OldIndex)) {
- elog(WARN, "cluster: unknown index: \"%s\"",
- oldindexname);
- }
- OIDOldIndex = OldIndex->rd_id; /* OID for the index scan */
-
- heap_close(OldHeap);
- index_close(OldIndex);
-
- /*
- * I need to build the copies of the heap and the index. The Commit()
- * between here is *very* bogus. If someone is appending stuff, they will
- * get the lock after being blocked and add rows which won't be present in
- * the new table. Bleagh! I'd be best to try and ensure that no-one's
- * in the tables for the entire duration of this process with a pg_vlock.
- */
- NewHeap = copy_heap(OIDOldHeap);
- OIDNewHeap = NewHeap->rd_id;
- strcpy(NewHeapName,NewHeap->rd_rel->relname.data);
-
-
- /* To make the new heap visible (which is until now empty). */
- CommandCounterIncrement();
-
- rebuildheap(OIDNewHeap, OIDOldHeap, OIDOldIndex);
-
- /* To flush the filled new heap (and the statistics about it). */
- CommandCounterIncrement();
-
- /* Create new index over the tuples of the new heap. */
- copy_index(OIDOldIndex, OIDNewHeap);
- sprintf(NewIndexName, "temp_%x", OIDOldIndex);
-
- /*
- * make this really happen. Flush all the buffers.
- * (Believe me, it is necessary ... ended up in a mess without it.)
- */
- CommitTransactionCommand();
- StartTransactionCommand();
-
-
- /* Destroy old heap (along with its index) and rename new. */
- heap_destroy(oldrelname);
-
- renamerel(NewHeapName, saveoldrelname);
- TypeRename(NewHeapName, saveoldrelname);
-
- renamerel(NewIndexName, saveoldindexname);
-
- /*
- * Again flush all the buffers.
- */
- CommitTransactionCommand();
- StartTransactionCommand();
+ Oid OIDOldHeap,
+ OIDOldIndex,
+ OIDNewHeap;
+
+ Relation OldHeap,
+ OldIndex;
+ Relation NewHeap;
+
+ char NewIndexName[NAMEDATALEN];
+ char NewHeapName[NAMEDATALEN];
+ char saveoldrelname[NAMEDATALEN];
+ char saveoldindexname[NAMEDATALEN];
+
+
+ /*
+ * Save the old names because they will get lost when the old
+ * relations are destroyed.
+ */
+ strcpy(saveoldrelname, oldrelname);
+ strcpy(saveoldindexname, oldindexname);
+
+ /*
+ * I'm going to force all checking back into the commands.c function.
+ *
+ * Get the list if indicies for this relation. If the index we want is
+ * among them, do not add it to the 'kill' list, as it will be handled
+ * by the 'clean up' code which commits this transaction.
+ *
+ * I'm not using the SysCache, because this will happen but once, and the
+ * slow way is the sure way in this case.
+ *
+ */
+
+ /*
+ * Like vacuum, cluster spans transactions, so I'm going to handle it
+ * in the same way.
+ */
+
+ /* matches the StartTransaction in PostgresMain() */
+
+ OldHeap = heap_openr(oldrelname);
+ if (!RelationIsValid(OldHeap))
+ {
+ elog(WARN, "cluster: unknown relation: \"%s\"",
+ oldrelname);
+ }
+ OIDOldHeap = OldHeap->rd_id;/* Get OID for the index scan */
+
+ OldIndex = index_openr(oldindexname); /* Open old index relation */
+ if (!RelationIsValid(OldIndex))
+ {
+ elog(WARN, "cluster: unknown index: \"%s\"",
+ oldindexname);
+ }
+ OIDOldIndex = OldIndex->rd_id; /* OID for the index scan */
+
+ heap_close(OldHeap);
+ index_close(OldIndex);
+
+ /*
+ * I need to build the copies of the heap and the index. The Commit()
+ * between here is *very* bogus. If someone is appending stuff, they
+ * will get the lock after being blocked and add rows which won't be
+ * present in the new table. Bleagh! I'd be best to try and ensure
+ * that no-one's in the tables for the entire duration of this process
+ * with a pg_vlock.
+ */
+ NewHeap = copy_heap(OIDOldHeap);
+ OIDNewHeap = NewHeap->rd_id;
+ strcpy(NewHeapName, NewHeap->rd_rel->relname.data);
+
+
+ /* To make the new heap visible (which is until now empty). */
+ CommandCounterIncrement();
+
+ rebuildheap(OIDNewHeap, OIDOldHeap, OIDOldIndex);
+
+ /* To flush the filled new heap (and the statistics about it). */
+ CommandCounterIncrement();
+
+ /* Create new index over the tuples of the new heap. */
+ copy_index(OIDOldIndex, OIDNewHeap);
+ sprintf(NewIndexName, "temp_%x", OIDOldIndex);
+
+ /*
+ * make this really happen. Flush all the buffers. (Believe me, it is
+ * necessary ... ended up in a mess without it.)
+ */
+ CommitTransactionCommand();
+ StartTransactionCommand();
+
+
+ /* Destroy old heap (along with its index) and rename new. */
+ heap_destroy(oldrelname);
+
+ renamerel(NewHeapName, saveoldrelname);
+ TypeRename(NewHeapName, saveoldrelname);
+
+ renamerel(NewIndexName, saveoldindexname);
+
+ /*
+ * Again flush all the buffers.
+ */
+ CommitTransactionCommand();
+ StartTransactionCommand();
}
-static Relation
+static Relation
copy_heap(Oid OIDOldHeap)
{
- char NewName[NAMEDATALEN];
- TupleDesc OldHeapDesc, tupdesc;
- Oid OIDNewHeap;
- Relation NewHeap, OldHeap;
-
- /*
- * Create a new heap relation with a temporary name, which has the
- * same tuple description as the old one.
- */
- sprintf(NewName,"temp_%x", OIDOldHeap);
-
- OldHeap= heap_open(OIDOldHeap);
- OldHeapDesc= RelationGetTupleDescriptor(OldHeap);
-
- /*
- * Need to make a copy of the tuple descriptor, heap_create modifies
- * it.
- */
-
- tupdesc = CreateTupleDescCopy(OldHeapDesc);
-
- OIDNewHeap=heap_create(NewName,
- NULL,
- OldHeap->rd_rel->relarch,
- OldHeap->rd_rel->relsmgr,
- tupdesc);
-
- if (!OidIsValid(OIDNewHeap))
- elog(WARN,"clusterheap: cannot create temporary heap relation\n");
-
- NewHeap=heap_open(OIDNewHeap);
-
- heap_close(NewHeap);
- heap_close(OldHeap);
-
- return NewHeap;
+ char NewName[NAMEDATALEN];
+ TupleDesc OldHeapDesc,
+ tupdesc;
+ Oid OIDNewHeap;
+ Relation NewHeap,
+ OldHeap;
+
+ /*
+ * Create a new heap relation with a temporary name, which has the
+ * same tuple description as the old one.
+ */
+ sprintf(NewName, "temp_%x", OIDOldHeap);
+
+ OldHeap = heap_open(OIDOldHeap);
+ OldHeapDesc = RelationGetTupleDescriptor(OldHeap);
+
+ /*
+ * Need to make a copy of the tuple descriptor, heap_create modifies
+ * it.
+ */
+
+ tupdesc = CreateTupleDescCopy(OldHeapDesc);
+
+ OIDNewHeap = heap_create(NewName,
+ NULL,
+ OldHeap->rd_rel->relarch,
+ OldHeap->rd_rel->relsmgr,
+ tupdesc);
+
+ if (!OidIsValid(OIDNewHeap))
+ elog(WARN, "clusterheap: cannot create temporary heap relation\n");
+
+ NewHeap = heap_open(OIDNewHeap);
+
+ heap_close(NewHeap);
+ heap_close(OldHeap);
+
+ return NewHeap;
}
static void
copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
{
- Relation OldIndex, NewHeap;
- HeapTuple Old_pg_index_Tuple, Old_pg_index_relation_Tuple, pg_proc_Tuple;
- IndexTupleForm Old_pg_index_Form;
- Form_pg_class Old_pg_index_relation_Form;
- Form_pg_proc pg_proc_Form;
- char *NewIndexName;
- AttrNumber *attnumP;
- int natts;
- FuncIndexInfo * finfo;
-
- NewHeap = heap_open(OIDNewHeap);
- OldIndex = index_open(OIDOldIndex);
-
- /*
- * OK. Create a new (temporary) index for the one that's already
- * here. To do this I get the info from pg_index, re-build the
- * FunctInfo if I have to, and add a new index with a temporary
- * name.
- */
- Old_pg_index_Tuple =
- SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(OldIndex->rd_id),
- 0,0,0);
-
- Assert(Old_pg_index_Tuple);
- Old_pg_index_Form = (IndexTupleForm)GETSTRUCT(Old_pg_index_Tuple);
-
- Old_pg_index_relation_Tuple =
- SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(OldIndex->rd_id),
- 0,0,0);
-
- Assert(Old_pg_index_relation_Tuple);
- Old_pg_index_relation_Form =
- (Form_pg_class)GETSTRUCT(Old_pg_index_relation_Tuple);
-
- NewIndexName = palloc(NAMEDATALEN); /* XXX */
- sprintf(NewIndexName, "temp_%x", OIDOldIndex); /* Set the name. */
-
- /*
- * Ugly as it is, the only way I have of working out the number of
- * attribues is to count them. Mostly there'll be just one but
- * I've got to be sure.
- */
- for (attnumP = &(Old_pg_index_Form->indkey[0]), natts = 0;
- *attnumP != InvalidAttrNumber;
- attnumP++, natts++);
-
- /*
- * If this is a functional index, I need to rebuild the functional
- * component to pass it to the defining procedure.
- */
- if (Old_pg_index_Form->indproc != InvalidOid) {
- finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
- FIgetnArgs(finfo) = natts;
- FIgetProcOid(finfo) = Old_pg_index_Form->indproc;
-
- pg_proc_Tuple =
- SearchSysCacheTuple(PROOID,
- ObjectIdGetDatum(Old_pg_index_Form->indproc),
- 0,0,0);
-
- Assert(pg_proc_Tuple);
- pg_proc_Form = (Form_pg_proc)GETSTRUCT(pg_proc_Tuple);
- namecpy(&(finfo->funcName), &(pg_proc_Form->proname));
- } else {
- finfo = (FuncIndexInfo *) NULL;
- natts = 1;
- }
-
- index_create((NewHeap->rd_rel->relname).data,
- NewIndexName,
- finfo,
- NULL, /* type info is in the old index */
- Old_pg_index_relation_Form->relam,
- natts,
- Old_pg_index_Form->indkey,
- Old_pg_index_Form->indclass,
- (uint16)0, (Datum) NULL, NULL,
- Old_pg_index_Form->indislossy,
- Old_pg_index_Form->indisunique);
-
- heap_close(OldIndex);
- heap_close(NewHeap);
+ Relation OldIndex,
+ NewHeap;
+ HeapTuple Old_pg_index_Tuple,
+ Old_pg_index_relation_Tuple,
+ pg_proc_Tuple;
+ IndexTupleForm Old_pg_index_Form;
+ Form_pg_class Old_pg_index_relation_Form;
+ Form_pg_proc pg_proc_Form;
+ char *NewIndexName;
+ AttrNumber *attnumP;
+ int natts;
+ FuncIndexInfo *finfo;
+
+ NewHeap = heap_open(OIDNewHeap);
+ OldIndex = index_open(OIDOldIndex);
+
+ /*
+ * OK. Create a new (temporary) index for the one that's already here.
+ * To do this I get the info from pg_index, re-build the FunctInfo if
+ * I have to, and add a new index with a temporary name.
+ */
+ Old_pg_index_Tuple =
+ SearchSysCacheTuple(INDEXRELID,
+ ObjectIdGetDatum(OldIndex->rd_id),
+ 0, 0, 0);
+
+ Assert(Old_pg_index_Tuple);
+ Old_pg_index_Form = (IndexTupleForm) GETSTRUCT(Old_pg_index_Tuple);
+
+ Old_pg_index_relation_Tuple =
+ SearchSysCacheTuple(RELOID,
+ ObjectIdGetDatum(OldIndex->rd_id),
+ 0, 0, 0);
+
+ Assert(Old_pg_index_relation_Tuple);
+ Old_pg_index_relation_Form =
+ (Form_pg_class) GETSTRUCT(Old_pg_index_relation_Tuple);
+
+ NewIndexName = palloc(NAMEDATALEN); /* XXX */
+ sprintf(NewIndexName, "temp_%x", OIDOldIndex); /* Set the name. */
+
+ /*
+ * Ugly as it is, the only way I have of working out the number of
+ * attribues is to count them. Mostly there'll be just one but I've
+ * got to be sure.
+ */
+ for (attnumP = &(Old_pg_index_Form->indkey[0]), natts = 0;
+ *attnumP != InvalidAttrNumber;
+ attnumP++, natts++);
+
+ /*
+ * If this is a functional index, I need to rebuild the functional
+ * component to pass it to the defining procedure.
+ */
+ if (Old_pg_index_Form->indproc != InvalidOid)
+ {
+ finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
+ FIgetnArgs(finfo) = natts;
+ FIgetProcOid(finfo) = Old_pg_index_Form->indproc;
+
+ pg_proc_Tuple =
+ SearchSysCacheTuple(PROOID,
+ ObjectIdGetDatum(Old_pg_index_Form->indproc),
+ 0, 0, 0);
+
+ Assert(pg_proc_Tuple);
+ pg_proc_Form = (Form_pg_proc) GETSTRUCT(pg_proc_Tuple);
+ namecpy(&(finfo->funcName), &(pg_proc_Form->proname));
+ }
+ else
+ {
+ finfo = (FuncIndexInfo *) NULL;
+ natts = 1;
+ }
+
+ index_create((NewHeap->rd_rel->relname).data,
+ NewIndexName,
+ finfo,
+ NULL, /* type info is in the old index */
+ Old_pg_index_relation_Form->relam,
+ natts,
+ Old_pg_index_Form->indkey,
+ Old_pg_index_Form->indclass,
+ (uint16) 0, (Datum) NULL, NULL,
+ Old_pg_index_Form->indislossy,
+ Old_pg_index_Form->indisunique);
+
+ heap_close(OldIndex);
+ heap_close(NewHeap);
}
static void
rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
{
- Relation LocalNewHeap, LocalOldHeap, LocalOldIndex;
- IndexScanDesc ScanDesc;
- RetrieveIndexResult ScanResult;
- ItemPointer HeapTid;
- HeapTuple LocalHeapTuple;
- Buffer LocalBuffer;
- Oid OIDNewHeapInsert;
-
- /*
- * Open the relations I need. Scan through the OldHeap on the OldIndex and
- * insert each tuple into the NewHeap.
- */
- LocalNewHeap=(Relation)heap_open(OIDNewHeap);
- LocalOldHeap=(Relation)heap_open(OIDOldHeap);
- LocalOldIndex=(Relation)index_open(OIDOldIndex);
-
- ScanDesc=index_beginscan(LocalOldIndex, false, 0, (ScanKey) NULL);
-
- while ((ScanResult =
- index_getnext(ScanDesc, ForwardScanDirection)) != NULL) {
-
- HeapTid = &ScanResult->heap_iptr;
- LocalHeapTuple = heap_fetch(LocalOldHeap, 0, HeapTid, &LocalBuffer);
- OIDNewHeapInsert =
- heap_insert(LocalNewHeap, LocalHeapTuple);
- pfree(ScanResult);
- ReleaseBuffer(LocalBuffer);
- }
- index_endscan(ScanDesc);
-
- index_close(LocalOldIndex);
- heap_close(LocalOldHeap);
- heap_close(LocalNewHeap);
+ Relation LocalNewHeap,
+ LocalOldHeap,
+ LocalOldIndex;
+ IndexScanDesc ScanDesc;
+ RetrieveIndexResult ScanResult;
+ ItemPointer HeapTid;
+ HeapTuple LocalHeapTuple;
+ Buffer LocalBuffer;
+ Oid OIDNewHeapInsert;
+
+ /*
+ * Open the relations I need. Scan through the OldHeap on the OldIndex
+ * and insert each tuple into the NewHeap.
+ */
+ LocalNewHeap = (Relation) heap_open(OIDNewHeap);
+ LocalOldHeap = (Relation) heap_open(OIDOldHeap);
+ LocalOldIndex = (Relation) index_open(OIDOldIndex);
+
+ ScanDesc = index_beginscan(LocalOldIndex, false, 0, (ScanKey) NULL);
+
+ while ((ScanResult =
+ index_getnext(ScanDesc, ForwardScanDirection)) != NULL)
+ {
+
+ HeapTid = &ScanResult->heap_iptr;
+ LocalHeapTuple = heap_fetch(LocalOldHeap, 0, HeapTid, &LocalBuffer);
+ OIDNewHeapInsert =
+ heap_insert(LocalNewHeap, LocalHeapTuple);
+ pfree(ScanResult);
+ ReleaseBuffer(LocalBuffer);
+ }
+ index_endscan(ScanDesc);
+
+ index_close(LocalOldIndex);
+ heap_close(LocalOldHeap);
+ heap_close(LocalNewHeap);
}
-
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index 376bd3ae5fa..7af9b37c072 100644
--- a/src/backend/commands/command.c
+++ b/src/backend/commands/command.c
@@ -1,29 +1,29 @@
/*-------------------------------------------------------------------------
*
* command.c--
- * random postgres portal and utility support code
+ * random postgres portal and utility support code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.13 1997/08/22 14:22:07 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.14 1997/09/07 04:40:38 momjian Exp $
*
* NOTES
- * The PortalExecutorHeapMemory crap needs to be eliminated
- * by designing a better executor / portal processing memory
- * interface.
- *
- * The PerformAddAttribute() code, like most of the relation
- * manipulating code in the commands/ directory, should go
- * someplace closer to the lib/catalog code.
- *
+ * The PortalExecutorHeapMemory crap needs to be eliminated
+ * by designing a better executor / portal processing memory
+ * interface.
+ *
+ * The PerformAddAttribute() code, like most of the relation
+ * manipulating code in the commands/ directory, should go
+ * someplace closer to the lib/catalog code.
+ *
*-------------------------------------------------------------------------
*/
#include <postgres.h>
#include <access/relscan.h>
-#include <utils/portal.h>
+#include <utils/portal.h>
#include <commands/command.h>
#include <utils/mcxt.h>
#include <executor/executor.h>
@@ -31,7 +31,7 @@
#include <catalog/indexing.h>
#include <utils/syscache.h>
#include <catalog/catalog.h>
-#include <access/heapam.h>
+#include <access/heapam.h>
#include <utils/array.h>
#include <utils/acl.h>
#include <optimizer/prep.h>
@@ -41,443 +41,468 @@
#include <utils/builtins.h>
/* ----------------
- * PortalExecutorHeapMemory stuff
+ * PortalExecutorHeapMemory stuff
*
- * This is where the XXXSuperDuperHacky code was. -cim 3/15/90
+ * This is where the XXXSuperDuperHacky code was. -cim 3/15/90
* ----------------
*/
-MemoryContext PortalExecutorHeapMemory = NULL;
+MemoryContext PortalExecutorHeapMemory = NULL;
/* --------------------------------
- * PortalCleanup
+ * PortalCleanup
* --------------------------------
*/
void
PortalCleanup(Portal portal)
{
- MemoryContext context;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- AssertArg(PortalIsValid(portal));
- AssertArg(portal->cleanup == PortalCleanup);
-
- /* ----------------
- * set proper portal-executor context before calling ExecMain.
- * ----------------
- */
- context = MemoryContextSwitchTo((MemoryContext) PortalGetHeapMemory(portal));
- PortalExecutorHeapMemory = (MemoryContext)
- PortalGetHeapMemory(portal);
-
- /* ----------------
- * tell the executor to shutdown the query
- * ----------------
- */
- ExecutorEnd(PortalGetQueryDesc(portal), PortalGetState(portal));
-
- /* ----------------
- * switch back to previous context
- * ----------------
- */
- MemoryContextSwitchTo(context);
- PortalExecutorHeapMemory = (MemoryContext) NULL;
+ MemoryContext context;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ AssertArg(PortalIsValid(portal));
+ AssertArg(portal->cleanup == PortalCleanup);
+
+ /* ----------------
+ * set proper portal-executor context before calling ExecMain.
+ * ----------------
+ */
+ context = MemoryContextSwitchTo((MemoryContext) PortalGetHeapMemory(portal));
+ PortalExecutorHeapMemory = (MemoryContext)
+ PortalGetHeapMemory(portal);
+
+ /* ----------------
+ * tell the executor to shutdown the query
+ * ----------------
+ */
+ ExecutorEnd(PortalGetQueryDesc(portal), PortalGetState(portal));
+
+ /* ----------------
+ * switch back to previous context
+ * ----------------
+ */
+ MemoryContextSwitchTo(context);
+ PortalExecutorHeapMemory = (MemoryContext) NULL;
}
/* --------------------------------
- * PerformPortalFetch
+ * PerformPortalFetch
* --------------------------------
*/
void
PerformPortalFetch(char *name,
- bool forward,
- int count,
- char *tag,
- CommandDest dest)
+ bool forward,
+ int count,
+ char *tag,
+ CommandDest dest)
{
- Portal portal;
- int feature;
- QueryDesc *queryDesc;
- MemoryContext context;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- if (name == NULL) {
- elog(NOTICE, "PerformPortalFetch: blank portal unsupported");
- return;
- }
-
- /* ----------------
- * get the portal from the portal name
- * ----------------
- */
- portal = GetPortalByName(name);
- if (! PortalIsValid(portal)) {
- elog(NOTICE, "PerformPortalFetch: portal \"%s\" not found",
- name);
- return;
- }
-
- /* ----------------
- * switch into the portal context
- * ----------------
- */
- context= MemoryContextSwitchTo((MemoryContext)PortalGetHeapMemory(portal));
-
- AssertState(context ==
- (MemoryContext)PortalGetHeapMemory(GetPortalByName(NULL)));
-
- /* ----------------
- * setup "feature" to tell the executor what direction and
- * how many tuples to fetch.
- * ----------------
- */
- if (forward)
- feature = EXEC_FOR;
- else
- feature = EXEC_BACK;
-
- /* ----------------
- * tell the destination to prepare to recieve some tuples
- * ----------------
- */
- queryDesc = PortalGetQueryDesc(portal);
- BeginCommand(name,
- queryDesc->operation,
- portal->attinfo,/* QueryDescGetTypeInfo(queryDesc), */
- false, /* portal fetches don't end up in relations */
- false, /* this is a portal fetch, not a "retrieve portal" */
- tag,
- dest);
-
- /* ----------------
- * execute the portal fetch operation
- * ----------------
- */
- PortalExecutorHeapMemory = (MemoryContext)
- PortalGetHeapMemory(portal);
-
- ExecutorRun(queryDesc, PortalGetState(portal), feature, count);
-
- /* ----------------
- * Note: the "end-of-command" tag is returned by higher-level
- * utility code
- *
- * Return blank portal for now.
- * Otherwise, this named portal will be cleaned.
- * Note: portals will only be supported within a BEGIN...END
- * block in the near future. Later, someone will fix it to
- * do what is possible across transaction boundries.
- * ----------------
- */
- MemoryContextSwitchTo(
- (MemoryContext)PortalGetHeapMemory(GetPortalByName(NULL)));
+ Portal portal;
+ int feature;
+ QueryDesc *queryDesc;
+ MemoryContext context;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ if (name == NULL)
+ {
+ elog(NOTICE, "PerformPortalFetch: blank portal unsupported");
+ return;
+ }
+
+ /* ----------------
+ * get the portal from the portal name
+ * ----------------
+ */
+ portal = GetPortalByName(name);
+ if (!PortalIsValid(portal))
+ {
+ elog(NOTICE, "PerformPortalFetch: portal \"%s\" not found",
+ name);
+ return;
+ }
+
+ /* ----------------
+ * switch into the portal context
+ * ----------------
+ */
+ context = MemoryContextSwitchTo((MemoryContext) PortalGetHeapMemory(portal));
+
+ AssertState(context ==
+ (MemoryContext) PortalGetHeapMemory(GetPortalByName(NULL)));
+
+ /* ----------------
+ * setup "feature" to tell the executor what direction and
+ * how many tuples to fetch.
+ * ----------------
+ */
+ if (forward)
+ feature = EXEC_FOR;
+ else
+ feature = EXEC_BACK;
+
+ /* ----------------
+ * tell the destination to prepare to recieve some tuples
+ * ----------------
+ */
+ queryDesc = PortalGetQueryDesc(portal);
+ BeginCommand(name,
+ queryDesc->operation,
+ portal->attinfo, /* QueryDescGetTypeInfo(queryDesc),
+ * */
+ false, /* portal fetches don't end up in
+ * relations */
+ false, /* this is a portal fetch, not a "retrieve
+ * portal" */
+ tag,
+ dest);
+
+ /* ----------------
+ * execute the portal fetch operation
+ * ----------------
+ */
+ PortalExecutorHeapMemory = (MemoryContext)
+ PortalGetHeapMemory(portal);
+
+ ExecutorRun(queryDesc, PortalGetState(portal), feature, count);
+
+ /* ----------------
+ * Note: the "end-of-command" tag is returned by higher-level
+ * utility code
+ *
+ * Return blank portal for now.
+ * Otherwise, this named portal will be cleaned.
+ * Note: portals will only be supported within a BEGIN...END
+ * block in the near future. Later, someone will fix it to
+ * do what is possible across transaction boundries.
+ * ----------------
+ */
+ MemoryContextSwitchTo(
+ (MemoryContext) PortalGetHeapMemory(GetPortalByName(NULL)));
}
/* --------------------------------
- * PerformPortalClose
+ * PerformPortalClose
* --------------------------------
*/
void
PerformPortalClose(char *name, CommandDest dest)
{
- Portal portal;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- if (name == NULL) {
- elog(NOTICE, "PerformPortalClose: blank portal unsupported");
- return;
- }
-
- /* ----------------
- * get the portal from the portal name
- * ----------------
- */
- portal = GetPortalByName(name);
- if (! PortalIsValid(portal)) {
- elog(NOTICE, "PerformPortalClose: portal \"%s\" not found",
- name);
- return;
- }
-
- /* ----------------
- * Note: PortalCleanup is called as a side-effect
- * ----------------
- */
- PortalDestroy(&portal);
+ Portal portal;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ if (name == NULL)
+ {
+ elog(NOTICE, "PerformPortalClose: blank portal unsupported");
+ return;
+ }
+
+ /* ----------------
+ * get the portal from the portal name
+ * ----------------
+ */
+ portal = GetPortalByName(name);
+ if (!PortalIsValid(portal))
+ {
+ elog(NOTICE, "PerformPortalClose: portal \"%s\" not found",
+ name);
+ return;
+ }
+
+ /* ----------------
+ * Note: PortalCleanup is called as a side-effect
+ * ----------------
+ */
+ PortalDestroy(&portal);
}
/* ----------------
- * PerformAddAttribute
+ * PerformAddAttribute
*
- * adds an additional attribute to a relation
+ * adds an additional attribute to a relation
*
- * Adds attribute field(s) to a relation. Each new attribute
- * is given attnums in sequential order and is added to the
- * ATTRIBUTE relation. If the AMI fails, defunct tuples will
- * remain in the ATTRIBUTE relation for later vacuuming.
- * Later, there may be some reserved attribute names???
+ * Adds attribute field(s) to a relation. Each new attribute
+ * is given attnums in sequential order and is added to the
+ * ATTRIBUTE relation. If the AMI fails, defunct tuples will
+ * remain in the ATTRIBUTE relation for later vacuuming.
+ * Later, there may be some reserved attribute names???
*
- * (If needed, can instead use elog to handle exceptions.)
+ * (If needed, can instead use elog to handle exceptions.)
*
- * Note:
- * Initial idea of ordering the tuple attributes so that all
- * the variable length domains occured last was scratched. Doing
- * so would not speed access too much (in general) and would create
- * many complications in formtuple, amgetattr, and addattribute.
+ * Note:
+ * Initial idea of ordering the tuple attributes so that all
+ * the variable length domains occured last was scratched. Doing
+ * so would not speed access too much (in general) and would create
+ * many complications in formtuple, amgetattr, and addattribute.
*
- * scan attribute catalog for name conflict (within rel)
- * scan type catalog for absence of data type (if not arg)
- * create attnum magically???
- * create attribute tuple
- * insert attribute in attribute catalog
- * modify reldesc
- * create new relation tuple
- * insert new relation in relation catalog
- * delete original relation from relation catalog
+ * scan attribute catalog for name conflict (within rel)
+ * scan type catalog for absence of data type (if not arg)
+ * create attnum magically???
+ * create attribute tuple
+ * insert attribute in attribute catalog
+ * modify reldesc
+ * create new relation tuple
+ * insert new relation in relation catalog
+ * delete original relation from relation catalog
* ----------------
*/
void
PerformAddAttribute(char *relationName,
- char *userName,
- bool inherits,
- ColumnDef *colDef)
-{
- Relation relrdesc, attrdesc;
- HeapScanDesc attsdesc;
- HeapTuple reltup;
- HeapTuple attributeTuple;
- AttributeTupleForm attribute;
- FormData_pg_attribute attributeD;
- int i;
- int minattnum, maxatts;
- HeapTuple tup;
- ScanKeyData key[2];
- ItemPointerData oldTID;
- Relation idescs[Num_pg_attr_indices];
- Relation ridescs[Num_pg_class_indices];
- bool hasindex;
-
- /*
- * permissions checking. this would normally be done in utility.c,
- * but this particular routine is recursive.
- *
- * normally, only the owner of a class can change its schema.
- */
- if (IsSystemRelationName(relationName))
- elog(WARN, "PerformAddAttribute: class \"%s\" is a system catalog",
- relationName);
+ char *userName,
+ bool inherits,
+ ColumnDef * colDef)
+{
+ Relation relrdesc,
+ attrdesc;
+ HeapScanDesc attsdesc;
+ HeapTuple reltup;
+ HeapTuple attributeTuple;
+ AttributeTupleForm attribute;
+ FormData_pg_attribute attributeD;
+ int i;
+ int minattnum,
+ maxatts;
+ HeapTuple tup;
+ ScanKeyData key[2];
+ ItemPointerData oldTID;
+ Relation idescs[Num_pg_attr_indices];
+ Relation ridescs[Num_pg_class_indices];
+ bool hasindex;
+
+ /*
+ * permissions checking. this would normally be done in utility.c,
+ * but this particular routine is recursive.
+ *
+ * normally, only the owner of a class can change its schema.
+ */
+ if (IsSystemRelationName(relationName))
+ elog(WARN, "PerformAddAttribute: class \"%s\" is a system catalog",
+ relationName);
#ifndef NO_SECURITY
- if (!pg_ownercheck(userName, relationName, RELNAME))
- elog(WARN, "PerformAddAttribute: you do not own class \"%s\"",
- relationName);
+ if (!pg_ownercheck(userName, relationName, RELNAME))
+ elog(WARN, "PerformAddAttribute: you do not own class \"%s\"",
+ relationName);
#endif
- /*
- * we can't add a not null attribute
- */
- if (colDef->is_not_null)
- elog(WARN,"Can't add a not null attribute to a existent relation");
- if (colDef->defval)
- elog(WARN,"ADD ATTRIBUTE: DEFAULT is not implemented, yet");
- /*
- * if the first element in the 'schema' list is a "*" then we are
- * supposed to add this attribute to all classes that inherit from
- * 'relationName' (as well as to 'relationName').
- *
- * any permissions or problems with duplicate attributes will cause
- * the whole transaction to abort, which is what we want -- all or
- * nothing.
- */
- if (colDef != NULL) {
- if (inherits) {
- Oid myrelid, childrelid;
- List *child, *children;
-
- relrdesc = heap_openr(relationName);
- if (!RelationIsValid(relrdesc)) {
- elog(WARN, "PerformAddAttribute: unknown relation: \"%s\"",
- relationName);
- }
- myrelid = relrdesc->rd_id;
- heap_close(relrdesc);
-
- /* this routine is actually in the planner */
- children = find_all_inheritors(lconsi(myrelid,NIL), NIL);
-
- /*
- * 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) {
- childrelid = lfirsti(child);
- if (childrelid == myrelid)
- continue;
- relrdesc = heap_open(childrelid);
- if (!RelationIsValid(relrdesc)) {
- elog(WARN, "PerformAddAttribute: can't find catalog entry for inheriting class with oid %d",
- childrelid);
+
+ /*
+ * we can't add a not null attribute
+ */
+ if (colDef->is_not_null)
+ elog(WARN, "Can't add a not null attribute to a existent relation");
+ if (colDef->defval)
+ elog(WARN, "ADD ATTRIBUTE: DEFAULT is not implemented, yet");
+
+ /*
+ * if the first element in the 'schema' list is a "*" then we are
+ * supposed to add this attribute to all classes that inherit from
+ * 'relationName' (as well as to 'relationName').
+ *
+ * any permissions or problems with duplicate attributes will cause the
+ * whole transaction to abort, which is what we want -- all or
+ * nothing.
+ */
+ if (colDef != NULL)
+ {
+ if (inherits)
+ {
+ Oid myrelid,
+ childrelid;
+ List *child,
+ *children;
+
+ relrdesc = heap_openr(relationName);
+ if (!RelationIsValid(relrdesc))
+ {
+ elog(WARN, "PerformAddAttribute: unknown relation: \"%s\"",
+ relationName);
+ }
+ myrelid = relrdesc->rd_id;
+ heap_close(relrdesc);
+
+ /* this routine is actually in the planner */
+ children = find_all_inheritors(lconsi(myrelid, NIL), NIL);
+
+ /*
+ * 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)
+ {
+ childrelid = lfirsti(child);
+ if (childrelid == myrelid)
+ continue;
+ relrdesc = heap_open(childrelid);
+ if (!RelationIsValid(relrdesc))
+ {
+ elog(WARN, "PerformAddAttribute: can't find catalog entry for inheriting class with oid %d",
+ childrelid);
+ }
+ PerformAddAttribute((relrdesc->rd_rel->relname).data,
+ userName, false, colDef);
+ heap_close(relrdesc);
+ }
}
- PerformAddAttribute((relrdesc->rd_rel->relname).data,
- userName, false, colDef);
+ }
+
+ relrdesc = heap_openr(RelationRelationName);
+ reltup = ClassNameIndexScan(relrdesc, relationName);
+
+ if (!PointerIsValid(reltup))
+ {
heap_close(relrdesc);
- }
+ elog(WARN, "PerformAddAttribute: relation \"%s\" not found",
+ relationName);
}
- }
-
- relrdesc = heap_openr(RelationRelationName);
- reltup = ClassNameIndexScan(relrdesc, relationName);
-
- if (!PointerIsValid(reltup)) {
- heap_close(relrdesc);
- elog(WARN, "PerformAddAttribute: relation \"%s\" not found",
- relationName);
- }
- /*
- * XXX is the following check sufficient?
- */
- if (((Form_pg_class) GETSTRUCT(reltup))->relkind == RELKIND_INDEX) {
- elog(WARN, "PerformAddAttribute: index relation \"%s\" not changed",
- relationName);
- return;
- }
-
- minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
- maxatts = minattnum + 1;
- if (maxatts > MaxHeapAttributeNumber) {
- pfree(reltup); /* XXX temp */
- heap_close(relrdesc); /* XXX temp */
- elog(WARN, "PerformAddAttribute: relations limited to %d attributes",
- MaxHeapAttributeNumber);
- return;
- }
-
- attrdesc = heap_openr(AttributeRelationName);
-
- Assert(attrdesc);
- Assert(RelationGetRelationTupleForm(attrdesc));
-
- /*
- * Open all (if any) pg_attribute indices
- */
- hasindex = RelationGetRelationTupleForm(attrdesc)->relhasindex;
- if (hasindex)
- CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
-
- ScanKeyEntryInitialize(&key[0],
- (bits16) NULL,
- (AttrNumber) Anum_pg_attribute_attrelid,
- (RegProcedure)ObjectIdEqualRegProcedure,
- (Datum) reltup->t_oid);
-
- ScanKeyEntryInitialize(&key[1],
- (bits16) NULL,
- (AttrNumber) Anum_pg_attribute_attname,
- (RegProcedure)NameEqualRegProcedure,
- (Datum) NULL);
-
- attributeD.attrelid = reltup->t_oid;
- attributeD.attdisbursion = 0; /* XXX temporary */
- attributeD.attcacheoff = -1;
-
- attributeTuple = heap_addheader(Natts_pg_attribute,
- sizeof attributeD,
- (char *)&attributeD);
-
- attribute = (AttributeTupleForm)GETSTRUCT(attributeTuple);
-
- i = 1 + minattnum;
-
- {
- HeapTuple typeTuple;
- TypeTupleForm form;
- char *p;
- int attnelems;
-
+
/*
- * XXX use syscache here as an optimization
+ * XXX is the following check sufficient?
*/
- key[1].sk_argument = (Datum)colDef->colname;
- attsdesc = heap_beginscan(attrdesc, 0, NowTimeQual, 2, key);
-
-
- tup = heap_getnext(attsdesc, 0, (Buffer *) NULL);
- if (HeapTupleIsValid(tup)) {
- pfree(reltup); /* XXX temp */
- heap_endscan(attsdesc); /* XXX temp */
- heap_close(attrdesc); /* XXX temp */
- heap_close(relrdesc); /* XXX temp */
- elog(WARN, "PerformAddAttribute: attribute \"%s\" already exists in class \"%s\"",
- key[1].sk_argument,
- relationName);
- return;
+ if (((Form_pg_class) GETSTRUCT(reltup))->relkind == RELKIND_INDEX)
+ {
+ elog(WARN, "PerformAddAttribute: index relation \"%s\" not changed",
+ relationName);
+ return;
+ }
+
+ minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
+ maxatts = minattnum + 1;
+ if (maxatts > MaxHeapAttributeNumber)
+ {
+ pfree(reltup); /* XXX temp */
+ heap_close(relrdesc); /* XXX temp */
+ elog(WARN, "PerformAddAttribute: relations limited to %d attributes",
+ MaxHeapAttributeNumber);
+ return;
}
- heap_endscan(attsdesc);
-
+
+ attrdesc = heap_openr(AttributeRelationName);
+
+ Assert(attrdesc);
+ Assert(RelationGetRelationTupleForm(attrdesc));
+
/*
- * check to see if it is an array attribute.
+ * Open all (if any) pg_attribute indices
*/
-
- p = colDef->typename->name;
-
- if (colDef->typename->arrayBounds)
- {
- attnelems = length(colDef->typename->arrayBounds);
- p = makeArrayTypeName(colDef->typename->name);
- }
- else
- attnelems = 0;
-
- typeTuple = SearchSysCacheTuple(TYPNAME,
- PointerGetDatum(p),
- 0,0,0);
- form = (TypeTupleForm)GETSTRUCT(typeTuple);
-
- if (!HeapTupleIsValid(typeTuple)) {
- elog(WARN, "Add: type \"%s\" nonexistent", p);
+ hasindex = RelationGetRelationTupleForm(attrdesc)->relhasindex;
+ if (hasindex)
+ CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
+
+ ScanKeyEntryInitialize(&key[0],
+ (bits16) NULL,
+ (AttrNumber) Anum_pg_attribute_attrelid,
+ (RegProcedure) ObjectIdEqualRegProcedure,
+ (Datum) reltup->t_oid);
+
+ ScanKeyEntryInitialize(&key[1],
+ (bits16) NULL,
+ (AttrNumber) Anum_pg_attribute_attname,
+ (RegProcedure) NameEqualRegProcedure,
+ (Datum) NULL);
+
+ attributeD.attrelid = reltup->t_oid;
+ attributeD.attdisbursion = 0; /* XXX temporary */
+ attributeD.attcacheoff = -1;
+
+ attributeTuple = heap_addheader(Natts_pg_attribute,
+ sizeof attributeD,
+ (char *) &attributeD);
+
+ attribute = (AttributeTupleForm) GETSTRUCT(attributeTuple);
+
+ i = 1 + minattnum;
+
+ {
+ HeapTuple typeTuple;
+ TypeTupleForm form;
+ char *p;
+ int attnelems;
+
+ /*
+ * XXX use syscache here as an optimization
+ */
+ key[1].sk_argument = (Datum) colDef->colname;
+ attsdesc = heap_beginscan(attrdesc, 0, NowTimeQual, 2, key);
+
+
+ tup = heap_getnext(attsdesc, 0, (Buffer *) NULL);
+ if (HeapTupleIsValid(tup))
+ {
+ pfree(reltup); /* XXX temp */
+ heap_endscan(attsdesc); /* XXX temp */
+ heap_close(attrdesc); /* XXX temp */
+ heap_close(relrdesc); /* XXX temp */
+ elog(WARN, "PerformAddAttribute: attribute \"%s\" already exists in class \"%s\"",
+ key[1].sk_argument,
+ relationName);
+ return;
+ }
+ heap_endscan(attsdesc);
+
+ /*
+ * check to see if it is an array attribute.
+ */
+
+ p = colDef->typename->name;
+
+ if (colDef->typename->arrayBounds)
+ {
+ attnelems = length(colDef->typename->arrayBounds);
+ p = makeArrayTypeName(colDef->typename->name);
+ }
+ else
+ attnelems = 0;
+
+ typeTuple = SearchSysCacheTuple(TYPNAME,
+ PointerGetDatum(p),
+ 0, 0, 0);
+ form = (TypeTupleForm) GETSTRUCT(typeTuple);
+
+ if (!HeapTupleIsValid(typeTuple))
+ {
+ elog(WARN, "Add: type \"%s\" nonexistent", p);
+ }
+ namestrcpy(&(attribute->attname), (char *) key[1].sk_argument);
+ attribute->atttypid = typeTuple->t_oid;
+ if (colDef->typename->typlen > 0)
+ attribute->attlen = colDef->typename->typlen;
+ else
+/* bpchar, varchar, text */
+ attribute->attlen = form->typlen;
+ attribute->attnum = i;
+ attribute->attbyval = form->typbyval;
+ attribute->attnelems = attnelems;
+ attribute->attcacheoff = -1;
+ attribute->attisset = (bool) (form->typtype == 'c');
+ attribute->attalign = form->typalign;
+ attribute->attnotnull = false;
+
+ heap_insert(attrdesc, attributeTuple);
+ if (hasindex)
+ CatalogIndexInsert(idescs,
+ Num_pg_attr_indices,
+ attrdesc,
+ attributeTuple);
}
- namestrcpy(&(attribute->attname), (char*) key[1].sk_argument);
- attribute->atttypid = typeTuple->t_oid;
- if (colDef->typename->typlen > 0)
- attribute->attlen = colDef->typename->typlen;
- else /* bpchar, varchar, text */
- attribute->attlen = form->typlen;
- attribute->attnum = i;
- attribute->attbyval = form->typbyval;
- attribute->attnelems = attnelems;
- attribute->attcacheoff = -1;
- attribute->attisset = (bool) (form->typtype == 'c');
- attribute->attalign = form->typalign;
- attribute->attnotnull = false;
-
- heap_insert(attrdesc, attributeTuple);
+
if (hasindex)
- CatalogIndexInsert(idescs,
- Num_pg_attr_indices,
- attrdesc,
- attributeTuple);
- }
-
- if (hasindex)
- CatalogCloseIndices(Num_pg_attr_indices, idescs);
- heap_close(attrdesc);
-
- ((Form_pg_class) GETSTRUCT(reltup))->relnatts = maxatts;
- oldTID = reltup->t_ctid;
- heap_replace(relrdesc, &oldTID, reltup);
-
- /* keep catalog indices current */
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
- CatalogIndexInsert(ridescs, Num_pg_class_indices, relrdesc, reltup);
- CatalogCloseIndices(Num_pg_class_indices, ridescs);
-
- pfree(reltup);
- heap_close(relrdesc);
+ CatalogCloseIndices(Num_pg_attr_indices, idescs);
+ heap_close(attrdesc);
+
+ ((Form_pg_class) GETSTRUCT(reltup))->relnatts = maxatts;
+ oldTID = reltup->t_ctid;
+ heap_replace(relrdesc, &oldTID, reltup);
+
+ /* keep catalog indices current */
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
+ CatalogIndexInsert(ridescs, Num_pg_class_indices, relrdesc, reltup);
+ CatalogCloseIndices(Num_pg_class_indices, ridescs);
+
+ pfree(reltup);
+ heap_close(relrdesc);
}
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 687cd1eb12e..795e9f5584f 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.29 1997/09/04 13:18:59 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.30 1997/09/07 04:40:40 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -42,736 +42,857 @@
/* non-export function prototypes */
-static void CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim);
-static void CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim);
-static Oid GetOutputFunction(Oid type);
-static Oid GetTypeElement(Oid type);
-static Oid GetInputFunction(Oid type);
-static Oid IsTypeByVal(Oid type);
-static void GetIndexRelations(Oid main_relation_oid,
- int *n_indices,
- Relation **index_rels);
+static void CopyTo(Relation rel, bool binary, bool oids, FILE * fp, char *delim);
+static void CopyFrom(Relation rel, bool binary, bool oids, FILE * fp, char *delim);
+static Oid GetOutputFunction(Oid type);
+static Oid GetTypeElement(Oid type);
+static Oid GetInputFunction(Oid type);
+static Oid IsTypeByVal(Oid type);
+static void
+GetIndexRelations(Oid main_relation_oid,
+ int *n_indices,
+ Relation ** index_rels);
+
#ifdef COPY_PATCH
-static void CopyReadNewline(FILE *fp, int *newline);
-static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline);
+static void CopyReadNewline(FILE * fp, int *newline);
+static char *CopyReadAttribute(FILE * fp, bool * isnull, char *delim, int *newline);
+
#else
-static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim);
+static char *CopyReadAttribute(FILE * fp, bool * isnull, char *delim);
+
#endif
-static void CopyAttributeOut(FILE *fp, char *string, char *delim);
-static int CountTuples(Relation relation);
+static void CopyAttributeOut(FILE * fp, char *string, char *delim);
+static int CountTuples(Relation relation);
-extern FILE *Pfout, *Pfin;
+extern FILE *Pfout,
+ *Pfin;
#ifdef COPY_DEBUG
-static int lineno;
+static int lineno;
+
#endif
-
+
/*
- * DoCopy executes a the SQL COPY statement.
+ * DoCopy executes a the SQL COPY statement.
*/
void
-DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
- char *filename, char *delim) {
+DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
+ char *filename, char *delim)
+{
/*----------------------------------------------------------------------------
Either unload or reload contents of class <relname>, depending on <from>.
If <pipe> is false, transfer is between the class and the file named
<filename>. Otherwise, transfer is between the class and our regular
- input/output stream. The latter could be either stdin/stdout or a
+ input/output stream. The latter could be either stdin/stdout or a
socket, depending on whether we're running under Postmaster control.
Iff <binary>, unload or reload in the binary format, as opposed to the
- more wasteful but more robust and portable text format.
+ more wasteful but more robust and portable text format.
- If in the text format, delimit columns with delimiter <delim>.
+ If in the text format, delimit columns with delimiter <delim>.
When loading in the text format from an input stream (as opposed to
- a file), recognize a "." on a line by itself as EOF. Also recognize
+ a file), recognize a "." on a line by itself as EOF. Also recognize
a stream EOF. When unloading in the text format to an output stream,
write a "." on a line by itself at the end of the data.
Iff <oids>, unload or reload the format that includes OID information.
Do not allow a Postgres user without superuser privilege to read from
- or write to a file.
+ or write to a file.
Do not allow the copy if user doesn't have proper permission to access
the class.
----------------------------------------------------------------------------*/
- FILE *fp;
- Relation rel;
- extern char *UserName; /* defined in global.c */
- const AclMode required_access = from ? ACL_WR : ACL_RD;
- int result;
-
- rel = heap_openr(relname);
- if (rel == NULL) elog(WARN, "COPY command failed. Class %s "
- "does not exist.", relname);
-
- result = pg_aclcheck(relname, UserName, required_access);
- if(result != ACLCHECK_OK)
- elog(WARN, "%s: %s", relname, aclcheck_error_strings[result]);
- /* Above should not return */
- else if (!superuser() && !pipe)
- elog(WARN, "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.");
- /* Above should not return. */
- else {
- if (from) { /* copy from file to database */
- if ( rel->rd_rel->relkind == RELKIND_SEQUENCE )
- elog (WARN, "You can't change sequence relation %s", relname);
- if (pipe) {
- if (IsUnderPostmaster) {
- ReceiveCopyBegin();
- fp = Pfin;
- } else fp = stdin;
- } else {
- fp = AllocateFile(filename, "r");
- if (fp == NULL)
- elog(WARN, "COPY command, running in backend with "
- "effective uid %d, could not open file '%s' for "
- "reading. Errno = %s (%d).",
- geteuid(), filename, strerror(errno), errno);
- /* Above should not return */
- }
- CopyFrom(rel, binary, oids, fp, delim);
- } else { /* copy from database to file */
- if (pipe) {
- if (IsUnderPostmaster) {
- SendCopyBegin();
- fp = Pfout;
- } else fp = stdout;
- } else {
- mode_t oumask; /* Pre-existing umask value */
- oumask = umask((mode_t) 0);
- fp = AllocateFile(filename, "w");
- umask(oumask);
- if (fp == NULL)
- elog(WARN, "COPY command, running in backend with "
- "effective uid %d, could not open file '%s' for "
- "writing. Errno = %s (%d).",
- geteuid(), filename, strerror(errno), errno);
- /* Above should not return */
- }
- CopyTo(rel, binary, oids, fp, delim);
- }
- if (!pipe)
- FreeFile(fp);
- else if (!from && !binary) {
- fputs("\\.\n", fp);
- if (IsUnderPostmaster) fflush(Pfout);
- }
- }
+ FILE *fp;
+ Relation rel;
+ extern char *UserName; /* defined in global.c */
+ const AclMode required_access = from ? ACL_WR : ACL_RD;
+ int result;
+
+ rel = heap_openr(relname);
+ if (rel == NULL)
+ elog(WARN, "COPY command failed. Class %s "
+ "does not exist.", relname);
+
+ result = pg_aclcheck(relname, UserName, required_access);
+ if (result != ACLCHECK_OK)
+ elog(WARN, "%s: %s", relname, aclcheck_error_strings[result]);
+ /* Above should not return */
+ else if (!superuser() && !pipe)
+ elog(WARN, "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.");
+ /* Above should not return. */
+ else
+ {
+ if (from)
+ { /* copy from file to database */
+ if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
+ elog(WARN, "You can't change sequence relation %s", relname);
+ if (pipe)
+ {
+ if (IsUnderPostmaster)
+ {
+ ReceiveCopyBegin();
+ fp = Pfin;
+ }
+ else
+ fp = stdin;
+ }
+ else
+ {
+ fp = AllocateFile(filename, "r");
+ if (fp == NULL)
+ elog(WARN, "COPY command, running in backend with "
+ "effective uid %d, could not open file '%s' for "
+ "reading. Errno = %s (%d).",
+ geteuid(), filename, strerror(errno), errno);
+ /* Above should not return */
+ }
+ CopyFrom(rel, binary, oids, fp, delim);
+ }
+ else
+ { /* copy from database to file */
+ if (pipe)
+ {
+ if (IsUnderPostmaster)
+ {
+ SendCopyBegin();
+ fp = Pfout;
+ }
+ else
+ fp = stdout;
+ }
+ else
+ {
+ mode_t oumask; /* Pre-existing umask value */
+
+ oumask = umask((mode_t) 0);
+ fp = AllocateFile(filename, "w");
+ umask(oumask);
+ if (fp == NULL)
+ elog(WARN, "COPY command, running in backend with "
+ "effective uid %d, could not open file '%s' for "
+ "writing. Errno = %s (%d).",
+ geteuid(), filename, strerror(errno), errno);
+ /* Above should not return */
+ }
+ CopyTo(rel, binary, oids, fp, delim);
+ }
+ if (!pipe)
+ FreeFile(fp);
+ else if (!from && !binary)
+ {
+ fputs("\\.\n", fp);
+ if (IsUnderPostmaster)
+ fflush(Pfout);
+ }
+ }
}
static void
-CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
+CopyTo(Relation rel, bool binary, bool oids, FILE * fp, char *delim)
{
- HeapTuple tuple;
- HeapScanDesc scandesc;
-
- int32 attr_count, i;
- AttributeTupleForm *attr;
- func_ptr *out_functions;
- int dummy;
- Oid out_func_oid;
- Oid *elements;
- Datum value;
- bool isnull; /* The attribute we are copying is null */
- char *nulls;
- /* <nulls> is a (dynamically allocated) array with one character
- per attribute in the instance being copied. nulls[I-1] is
- 'n' if Attribute Number I is null, and ' ' otherwise.
-
- <nulls> is meaningful only if we are doing a binary copy.
- */
- char *string;
- int32 ntuples;
- TupleDesc tupDesc;
-
- scandesc = heap_beginscan(rel, 0, NULL, 0, NULL);
-
- attr_count = rel->rd_att->natts;
- attr = rel->rd_att->attrs;
- tupDesc = rel->rd_att;
-
- if (!binary) {
- out_functions = (func_ptr *) palloc(attr_count * sizeof(func_ptr));
- elements = (Oid *) palloc(attr_count * sizeof(Oid));
- for (i = 0; i < attr_count; i++) {
- out_func_oid = (Oid) GetOutputFunction(attr[i]->atttypid);
- fmgr_info(out_func_oid, &out_functions[i], &dummy);
- elements[i] = GetTypeElement(attr[i]->atttypid);
- }
- nulls = NULL; /* meaningless, but compiler doesn't know that */
- }else {
- elements = NULL;
- out_functions = NULL;
- nulls = (char *) palloc(attr_count);
- for (i = 0; i < attr_count; i++) nulls[i] = ' ';
-
- /* XXX expensive */
-
- ntuples = CountTuples(rel);
- fwrite(&ntuples, sizeof(int32), 1, fp);
- }
-
- for (tuple = heap_getnext(scandesc, 0, NULL);
- tuple != NULL;
- tuple = heap_getnext(scandesc, 0, NULL)) {
-
- if (oids && !binary) {
- fputs(oidout(tuple->t_oid),fp);
- fputc(delim[0], fp);
- }
-
- for (i = 0; i < attr_count; i++) {
- value = (Datum)
- heap_getattr(tuple, InvalidBuffer, i+1, tupDesc, &isnull);
- if (!binary) {
- if (!isnull) {
- string = (char *) (out_functions[i]) (value, elements[i]);
- CopyAttributeOut(fp, string, delim);
- pfree(string);
- }
- else
- fputs("\\N", fp); /* null indicator */
-
- if (i == attr_count - 1) {
- fputc('\n', fp);
- }else {
- /* when copying out, only use the first char of the delim
- string */
- fputc(delim[0], fp);
- }
- }else {
- /*
- * only interesting thing heap_getattr tells us in this case
- * is if we have a null attribute or not.
- */
- if (isnull) nulls[i] = 'n';
- }
- }
-
- if (binary) {
- int32 null_ct = 0, length;
-
- for (i = 0; i < attr_count; i++) {
- if (nulls[i] == 'n') null_ct++;
- }
-
- length = tuple->t_len - tuple->t_hoff;
- fwrite(&length, sizeof(int32), 1, fp);
- if (oids)
- fwrite((char *) &tuple->t_oid, sizeof(int32), 1, fp);
-
- fwrite(&null_ct, sizeof(int32), 1, fp);
- if (null_ct > 0) {
- for (i = 0; i < attr_count; i++) {
- if (nulls[i] == 'n') {
- fwrite(&i, sizeof(int32), 1, fp);
- nulls[i] = ' ';
- }
- }
- }
- fwrite((char *) tuple + tuple->t_hoff, length, 1, fp);
- }
- }
-
- heap_endscan(scandesc);
- if (binary) {
- pfree(nulls);
- }else {
- pfree(out_functions);
- pfree(elements);
- }
-
- heap_close(rel);
+ HeapTuple tuple;
+ HeapScanDesc scandesc;
+
+ int32 attr_count,
+ i;
+ AttributeTupleForm *attr;
+ func_ptr *out_functions;
+ int dummy;
+ Oid out_func_oid;
+ Oid *elements;
+ Datum value;
+ bool isnull; /* The attribute we are copying is null */
+ char *nulls;
+
+ /*
+ * <nulls> is a (dynamically allocated) array with one character per
+ * attribute in the instance being copied. nulls[I-1] is 'n' if
+ * Attribute Number I is null, and ' ' otherwise.
+ *
+ * <nulls> is meaningful only if we are doing a binary copy.
+ */
+ char *string;
+ int32 ntuples;
+ TupleDesc tupDesc;
+
+ scandesc = heap_beginscan(rel, 0, NULL, 0, NULL);
+
+ attr_count = rel->rd_att->natts;
+ attr = rel->rd_att->attrs;
+ tupDesc = rel->rd_att;
+
+ if (!binary)
+ {
+ out_functions = (func_ptr *) palloc(attr_count * sizeof(func_ptr));
+ elements = (Oid *) palloc(attr_count * sizeof(Oid));
+ for (i = 0; i < attr_count; i++)
+ {
+ out_func_oid = (Oid) GetOutputFunction(attr[i]->atttypid);
+ fmgr_info(out_func_oid, &out_functions[i], &dummy);
+ elements[i] = GetTypeElement(attr[i]->atttypid);
+ }
+ nulls = NULL; /* meaningless, but compiler doesn't know
+ * that */
+ }
+ else
+ {
+ elements = NULL;
+ out_functions = NULL;
+ nulls = (char *) palloc(attr_count);
+ for (i = 0; i < attr_count; i++)
+ nulls[i] = ' ';
+
+ /* XXX expensive */
+
+ ntuples = CountTuples(rel);
+ fwrite(&ntuples, sizeof(int32), 1, fp);
+ }
+
+ for (tuple = heap_getnext(scandesc, 0, NULL);
+ tuple != NULL;
+ tuple = heap_getnext(scandesc, 0, NULL))
+ {
+
+ if (oids && !binary)
+ {
+ fputs(oidout(tuple->t_oid), fp);
+ fputc(delim[0], fp);
+ }
+
+ for (i = 0; i < attr_count; i++)
+ {
+ value = (Datum)
+ heap_getattr(tuple, InvalidBuffer, i + 1, tupDesc, &isnull);
+ if (!binary)
+ {
+ if (!isnull)
+ {
+ string = (char *) (out_functions[i]) (value, elements[i]);
+ CopyAttributeOut(fp, string, delim);
+ pfree(string);
+ }
+ else
+ fputs("\\N", fp); /* null indicator */
+
+ if (i == attr_count - 1)
+ {
+ fputc('\n', fp);
+ }
+ else
+ {
+
+ /*
+ * when copying out, only use the first char of the
+ * delim string
+ */
+ fputc(delim[0], fp);
+ }
+ }
+ else
+ {
+
+ /*
+ * only interesting thing heap_getattr tells us in this
+ * case is if we have a null attribute or not.
+ */
+ if (isnull)
+ nulls[i] = 'n';
+ }
+ }
+
+ if (binary)
+ {
+ int32 null_ct = 0,
+ length;
+
+ for (i = 0; i < attr_count; i++)
+ {
+ if (nulls[i] == 'n')
+ null_ct++;
+ }
+
+ length = tuple->t_len - tuple->t_hoff;
+ fwrite(&length, sizeof(int32), 1, fp);
+ if (oids)
+ fwrite((char *) &tuple->t_oid, sizeof(int32), 1, fp);
+
+ fwrite(&null_ct, sizeof(int32), 1, fp);
+ if (null_ct > 0)
+ {
+ for (i = 0; i < attr_count; i++)
+ {
+ if (nulls[i] == 'n')
+ {
+ fwrite(&i, sizeof(int32), 1, fp);
+ nulls[i] = ' ';
+ }
+ }
+ }
+ fwrite((char *) tuple + tuple->t_hoff, length, 1, fp);
+ }
+ }
+
+ heap_endscan(scandesc);
+ if (binary)
+ {
+ pfree(nulls);
+ }
+ else
+ {
+ pfree(out_functions);
+ pfree(elements);
+ }
+
+ heap_close(rel);
}
static void
-CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
+CopyFrom(Relation rel, bool binary, bool oids, FILE * fp, char *delim)
{
- HeapTuple tuple;
- AttrNumber attr_count;
- AttributeTupleForm *attr;
- func_ptr *in_functions;
- int i, dummy;
- Oid in_func_oid;
- Datum *values;
- char *nulls, *index_nulls;
- bool *byval;
- bool isnull;
- bool has_index;
- int done = 0;
- char *string = NULL, *ptr;
- Relation *index_rels;
- int32 len, null_ct, null_id;
- int32 ntuples, tuples_read = 0;
- bool reading_to_eof = true;
- Oid *elements;
- FuncIndexInfo *finfo, **finfoP = NULL;
- TupleDesc *itupdescArr;
- HeapTuple pgIndexTup;
- IndexTupleForm *pgIndexP = NULL;
- int *indexNatts = NULL;
- char *predString;
- Node **indexPred = NULL;
- TupleDesc rtupdesc;
- ExprContext *econtext = NULL;
+ HeapTuple tuple;
+ AttrNumber attr_count;
+ AttributeTupleForm *attr;
+ func_ptr *in_functions;
+ int i,
+ dummy;
+ Oid in_func_oid;
+ Datum *values;
+ char *nulls,
+ *index_nulls;
+ bool *byval;
+ bool isnull;
+ bool has_index;
+ int done = 0;
+ char *string = NULL,
+ *ptr;
+ Relation *index_rels;
+ int32 len,
+ null_ct,
+ null_id;
+ int32 ntuples,
+ tuples_read = 0;
+ bool reading_to_eof = true;
+ Oid *elements;
+ FuncIndexInfo *finfo,
+ **finfoP = NULL;
+ TupleDesc *itupdescArr;
+ HeapTuple pgIndexTup;
+ IndexTupleForm *pgIndexP = NULL;
+ int *indexNatts = NULL;
+ char *predString;
+ Node **indexPred = NULL;
+ TupleDesc rtupdesc;
+ ExprContext *econtext = NULL;
+
#ifndef OMIT_PARTIAL_INDEX
- TupleTable tupleTable;
- TupleTableSlot *slot = NULL;
+ TupleTable tupleTable;
+ TupleTableSlot *slot = NULL;
+
#endif
- int natts;
- AttrNumber *attnumP;
- Datum *idatum;
- int n_indices;
- InsertIndexResult indexRes;
- TupleDesc tupDesc;
- Oid loaded_oid;
- bool skip_tuple = false;
-
- tupDesc = RelationGetTupleDescriptor(rel);
- attr = tupDesc->attrs;
- attr_count = tupDesc->natts;
-
- has_index = false;
-
- /*
- * This may be a scalar or a functional index. We initialize all
- * kinds of arrays here to avoid doing extra work at every tuple
- * copy.
- */
-
- if (rel->rd_rel->relhasindex) {
- GetIndexRelations(rel->rd_id, &n_indices, &index_rels);
- if (n_indices > 0) {
- has_index = true;
- itupdescArr =
- (TupleDesc *)palloc(n_indices * sizeof(TupleDesc));
- pgIndexP =
- (IndexTupleForm *)palloc(n_indices * sizeof(IndexTupleForm));
- indexNatts = (int *) palloc(n_indices * sizeof(int));
- finfo = (FuncIndexInfo *) palloc(n_indices * sizeof(FuncIndexInfo));
- finfoP = (FuncIndexInfo **) palloc(n_indices * sizeof(FuncIndexInfo *));
- indexPred = (Node **) palloc(n_indices * sizeof(Node*));
- econtext = NULL;
- for (i = 0; i < n_indices; i++) {
- itupdescArr[i] = RelationGetTupleDescriptor(index_rels[i]);
- pgIndexTup =
- SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(index_rels[i]->rd_id),
- 0,0,0);
- Assert(pgIndexTup);
- pgIndexP[i] = (IndexTupleForm)GETSTRUCT(pgIndexTup);
- for (attnumP = &(pgIndexP[i]->indkey[0]), natts = 0;
- *attnumP != InvalidAttrNumber;
- attnumP++, natts++);
- if (pgIndexP[i]->indproc != InvalidOid) {
- FIgetnArgs(&finfo[i]) = natts;
- natts = 1;
- FIgetProcOid(&finfo[i]) = pgIndexP[i]->indproc;
- *(FIgetname(&finfo[i])) = '\0';
- finfoP[i] = &finfo[i];
- } else
- finfoP[i] = (FuncIndexInfo *) NULL;
- indexNatts[i] = natts;
- if (VARSIZE(&pgIndexP[i]->indpred) != 0) {
- predString = fmgr(F_TEXTOUT, &pgIndexP[i]->indpred);
- indexPred[i] = stringToNode(predString);
- pfree(predString);
- /* make dummy ExprContext for use by ExecQual */
- if (econtext == NULL) {
+ int natts;
+ AttrNumber *attnumP;
+ Datum *idatum;
+ int n_indices;
+ InsertIndexResult indexRes;
+ TupleDesc tupDesc;
+ Oid loaded_oid;
+ bool skip_tuple = false;
+
+ tupDesc = RelationGetTupleDescriptor(rel);
+ attr = tupDesc->attrs;
+ attr_count = tupDesc->natts;
+
+ has_index = false;
+
+ /*
+ * This may be a scalar or a functional index. We initialize all
+ * kinds of arrays here to avoid doing extra work at every tuple copy.
+ */
+
+ if (rel->rd_rel->relhasindex)
+ {
+ GetIndexRelations(rel->rd_id, &n_indices, &index_rels);
+ if (n_indices > 0)
+ {
+ has_index = true;
+ itupdescArr =
+ (TupleDesc *) palloc(n_indices * sizeof(TupleDesc));
+ pgIndexP =
+ (IndexTupleForm *) palloc(n_indices * sizeof(IndexTupleForm));
+ indexNatts = (int *) palloc(n_indices * sizeof(int));
+ finfo = (FuncIndexInfo *) palloc(n_indices * sizeof(FuncIndexInfo));
+ finfoP = (FuncIndexInfo **) palloc(n_indices * sizeof(FuncIndexInfo *));
+ indexPred = (Node **) palloc(n_indices * sizeof(Node *));
+ econtext = NULL;
+ for (i = 0; i < n_indices; i++)
+ {
+ itupdescArr[i] = RelationGetTupleDescriptor(index_rels[i]);
+ pgIndexTup =
+ SearchSysCacheTuple(INDEXRELID,
+ ObjectIdGetDatum(index_rels[i]->rd_id),
+ 0, 0, 0);
+ Assert(pgIndexTup);
+ pgIndexP[i] = (IndexTupleForm) GETSTRUCT(pgIndexTup);
+ for (attnumP = &(pgIndexP[i]->indkey[0]), natts = 0;
+ *attnumP != InvalidAttrNumber;
+ attnumP++, natts++);
+ if (pgIndexP[i]->indproc != InvalidOid)
+ {
+ FIgetnArgs(&finfo[i]) = natts;
+ natts = 1;
+ FIgetProcOid(&finfo[i]) = pgIndexP[i]->indproc;
+ *(FIgetname(&finfo[i])) = '\0';
+ finfoP[i] = &finfo[i];
+ }
+ else
+ finfoP[i] = (FuncIndexInfo *) NULL;
+ indexNatts[i] = natts;
+ if (VARSIZE(&pgIndexP[i]->indpred) != 0)
+ {
+ predString = fmgr(F_TEXTOUT, &pgIndexP[i]->indpred);
+ indexPred[i] = stringToNode(predString);
+ pfree(predString);
+ /* make dummy ExprContext for use by ExecQual */
+ if (econtext == NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- tupleTable = ExecCreateTupleTable(1);
- slot = ExecAllocTableSlot(tupleTable);
- econtext = makeNode(ExprContext);
- econtext->ecxt_scantuple = slot;
- rtupdesc = RelationGetTupleDescriptor(rel);
- slot->ttc_tupleDescriptor = rtupdesc;
- /*
- * There's no buffer associated with heap tuples here,
- * so I set the slot's buffer to NULL. Currently, it
- * appears that the only way a buffer could be needed
- * would be if the partial index predicate referred to
- * the "lock" system attribute. If it did, then
- * heap_getattr would call HeapTupleGetRuleLock, which
- * uses the buffer's descriptor to get the relation id.
- * Rather than try to fix this, I'll just disallow
- * partial indexes on "lock", which wouldn't be useful
- * anyway. --Nels, Nov '92
- */
- /* SetSlotBuffer(slot, (Buffer) NULL); */
- /* SetSlotShouldFree(slot, false); */
- slot->ttc_buffer = (Buffer)NULL;
- slot->ttc_shouldFree = false;
-#endif /* OMIT_PARTIAL_INDEX */
- }
- } else {
- indexPred[i] = NULL;
- }
- }
- }
- }
-
- if (!binary)
- {
- in_functions = (func_ptr *) palloc(attr_count * sizeof(func_ptr));
- elements = (Oid *) palloc(attr_count * sizeof(Oid));
- for (i = 0; i < attr_count; i++)
- {
- in_func_oid = (Oid) GetInputFunction(attr[i]->atttypid);
- fmgr_info(in_func_oid, &in_functions[i], &dummy);
- elements[i] = GetTypeElement(attr[i]->atttypid);
- }
- }
- else
- {
- in_functions = NULL;
- elements = NULL;
- fread(&ntuples, sizeof(int32), 1, fp);
- if (ntuples != 0) reading_to_eof = false;
- }
-
- values = (Datum *) palloc(sizeof(Datum) * attr_count);
- nulls = (char *) palloc(attr_count);
- index_nulls = (char *) palloc(attr_count);
- idatum = (Datum *) palloc(sizeof(Datum) * attr_count);
- byval = (bool *) palloc(attr_count * sizeof(bool));
-
- for (i = 0; i < attr_count; i++) {
- nulls[i] = ' ';
- index_nulls[i] = ' ';
- byval[i] = (bool) IsTypeByVal(attr[i]->atttypid);
- }
-
+ tupleTable = ExecCreateTupleTable(1);
+ slot = ExecAllocTableSlot(tupleTable);
+ econtext = makeNode(ExprContext);
+ econtext->ecxt_scantuple = slot;
+ rtupdesc = RelationGetTupleDescriptor(rel);
+ slot->ttc_tupleDescriptor = rtupdesc;
+
+ /*
+ * There's no buffer associated with heap tuples
+ * here, so I set the slot's buffer to NULL.
+ * Currently, it appears that the only way a
+ * buffer could be needed would be if the partial
+ * index predicate referred to the "lock" system
+ * attribute. If it did, then heap_getattr would
+ * call HeapTupleGetRuleLock, which uses the
+ * buffer's descriptor to get the relation id.
+ * Rather than try to fix this, I'll just disallow
+ * partial indexes on "lock", which wouldn't be
+ * useful anyway. --Nels, Nov '92
+ */
+ /* SetSlotBuffer(slot, (Buffer) NULL); */
+ /* SetSlotShouldFree(slot, false); */
+ slot->ttc_buffer = (Buffer) NULL;
+ slot->ttc_shouldFree = false;
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+ }
+ else
+ {
+ indexPred[i] = NULL;
+ }
+ }
+ }
+ }
+
+ if (!binary)
+ {
+ in_functions = (func_ptr *) palloc(attr_count * sizeof(func_ptr));
+ elements = (Oid *) palloc(attr_count * sizeof(Oid));
+ for (i = 0; i < attr_count; i++)
+ {
+ in_func_oid = (Oid) GetInputFunction(attr[i]->atttypid);
+ fmgr_info(in_func_oid, &in_functions[i], &dummy);
+ elements[i] = GetTypeElement(attr[i]->atttypid);
+ }
+ }
+ else
+ {
+ in_functions = NULL;
+ elements = NULL;
+ fread(&ntuples, sizeof(int32), 1, fp);
+ if (ntuples != 0)
+ reading_to_eof = false;
+ }
+
+ values = (Datum *) palloc(sizeof(Datum) * attr_count);
+ nulls = (char *) palloc(attr_count);
+ index_nulls = (char *) palloc(attr_count);
+ idatum = (Datum *) palloc(sizeof(Datum) * attr_count);
+ byval = (bool *) palloc(attr_count * sizeof(bool));
+
+ for (i = 0; i < attr_count; i++)
+ {
+ nulls[i] = ' ';
+ index_nulls[i] = ' ';
+ byval[i] = (bool) IsTypeByVal(attr[i]->atttypid);
+ }
+
#ifdef COPY_DEBUG
- lineno = 0;
+ lineno = 0;
#endif
- while (!done) {
- if (!binary) {
+ while (!done)
+ {
+ if (!binary)
+ {
#ifdef COPY_PATCH
- int newline = 0;
+ int newline = 0;
+
#endif
#ifdef COPY_DEBUG
- lineno++;
- elog(DEBUG, "line %d", lineno);
+ lineno++;
+ elog(DEBUG, "line %d", lineno);
#endif
- if (oids) {
+ if (oids)
+ {
#ifdef COPY_PATCH
- string = CopyReadAttribute(fp, &isnull, delim, &newline);
+ string = CopyReadAttribute(fp, &isnull, delim, &newline);
#else
- string = CopyReadAttribute(fp, &isnull, delim);
+ string = CopyReadAttribute(fp, &isnull, delim);
#endif
- if (string == NULL)
- done = 1;
- else {
- loaded_oid = oidin(string);
- if (loaded_oid < BootstrapObjectIdData)
- elog(WARN, "COPY TEXT: Invalid Oid");
- }
- }
- for (i = 0; i < attr_count && !done; i++) {
+ if (string == NULL)
+ done = 1;
+ else
+ {
+ loaded_oid = oidin(string);
+ if (loaded_oid < BootstrapObjectIdData)
+ elog(WARN, "COPY TEXT: Invalid Oid");
+ }
+ }
+ for (i = 0; i < attr_count && !done; i++)
+ {
#ifdef COPY_PATCH
- string = CopyReadAttribute(fp, &isnull, delim, &newline);
+ string = CopyReadAttribute(fp, &isnull, delim, &newline);
#else
- string = CopyReadAttribute(fp, &isnull, delim);
+ string = CopyReadAttribute(fp, &isnull, delim);
#endif
- if (isnull) {
- values[i] = PointerGetDatum(NULL);
- nulls[i] = 'n';
- }else if (string == NULL) {
- done = 1;
- }else {
- values[i] =
- (Datum)(in_functions[i])(string,
- elements[i],
- attr[i]->attlen);
- /*
- * Sanity check - by reference attributes cannot return
- * NULL
- */
- if (!PointerIsValid(values[i]) &&
- !(rel->rd_att->attrs[i]->attbyval)) {
+ if (isnull)
+ {
+ values[i] = PointerGetDatum(NULL);
+ nulls[i] = 'n';
+ }
+ else if (string == NULL)
+ {
+ done = 1;
+ }
+ else
+ {
+ values[i] =
+ (Datum) (in_functions[i]) (string,
+ elements[i],
+ attr[i]->attlen);
+
+ /*
+ * Sanity check - by reference attributes cannot
+ * return NULL
+ */
+ if (!PointerIsValid(values[i]) &&
+ !(rel->rd_att->attrs[i]->attbyval))
+ {
#ifdef COPY_DEBUG
- elog(WARN,
- "copy from: line %d - Bad file format", lineno);
+ elog(WARN,
+ "copy from: line %d - Bad file format", lineno);
#else
- elog(WARN, "copy from: Bad file format");
+ elog(WARN, "copy from: Bad file format");
#endif
- }
- }
- }
+ }
+ }
+ }
#ifdef COPY_PATCH
- if (!done) {
- CopyReadNewline(fp, &newline);
- }
+ if (!done)
+ {
+ CopyReadNewline(fp, &newline);
+ }
#endif
- }else { /* binary */
- fread(&len, sizeof(int32), 1, fp);
- if (feof(fp)) {
- done = 1;
- }else {
- if (oids) {
- fread(&loaded_oid, sizeof(int32), 1, fp);
- if (loaded_oid < BootstrapObjectIdData)
- elog(WARN, "COPY BINARY: Invalid Oid");
- }
- fread(&null_ct, sizeof(int32), 1, fp);
- if (null_ct > 0) {
- for (i = 0; i < null_ct; i++) {
- fread(&null_id, sizeof(int32), 1, fp);
- nulls[null_id] = 'n';
- }
- }
-
- string = (char *) palloc(len);
- fread(string, len, 1, fp);
-
- ptr = string;
-
- for (i = 0; i < attr_count; i++) {
- if (byval[i] && nulls[i] != 'n') {
-
- switch(attr[i]->attlen) {
- case sizeof(char):
- values[i] = (Datum) *(unsigned char *) ptr;
- ptr += sizeof(char);
- break;
- case sizeof(short):
- ptr = (char *) SHORTALIGN(ptr);
- values[i] = (Datum) *(unsigned short *) ptr;
- ptr += sizeof(short);
- break;
- case sizeof(int32):
- ptr = (char *) INTALIGN(ptr);
- values[i] = (Datum) *(uint32 *) ptr;
- ptr += sizeof(int32);
- break;
- default:
- elog(WARN, "COPY BINARY: impossible size!");
- break;
- }
- }else if (nulls[i] != 'n') {
- switch (attr[i]->attlen) {
- case -1:
- if (attr[i]->attalign == 'd')
- ptr = (char *)DOUBLEALIGN(ptr);
- else
- ptr = (char *)INTALIGN(ptr);
- values[i] = (Datum) ptr;
- ptr += * (uint32 *) ptr;
- break;
- case sizeof(char):
- values[i] = (Datum)ptr;
- ptr += attr[i]->attlen;
- break;
- case sizeof(short):
- ptr = (char*)SHORTALIGN(ptr);
- values[i] = (Datum)ptr;
- ptr += attr[i]->attlen;
- break;
- case sizeof(int32):
- ptr = (char*)INTALIGN(ptr);
- values[i] = (Datum)ptr;
- ptr += attr[i]->attlen;
- break;
- default:
- if (attr[i]->attalign == 'd')
- ptr = (char *)DOUBLEALIGN(ptr);
- else
- ptr = (char *)LONGALIGN(ptr);
- values[i] = (Datum) ptr;
- ptr += attr[i]->attlen;
- }
- }
- }
- }
- }
- if (done) continue;
+ }
+ else
+ { /* binary */
+ fread(&len, sizeof(int32), 1, fp);
+ if (feof(fp))
+ {
+ done = 1;
+ }
+ else
+ {
+ if (oids)
+ {
+ fread(&loaded_oid, sizeof(int32), 1, fp);
+ if (loaded_oid < BootstrapObjectIdData)
+ elog(WARN, "COPY BINARY: Invalid Oid");
+ }
+ fread(&null_ct, sizeof(int32), 1, fp);
+ if (null_ct > 0)
+ {
+ for (i = 0; i < null_ct; i++)
+ {
+ fread(&null_id, sizeof(int32), 1, fp);
+ nulls[null_id] = 'n';
+ }
+ }
- /*
- * Does it have any sence ? - vadim 12/14/96
- *
- tupDesc = CreateTupleDesc(attr_count, attr);
- */
- tuple = heap_formtuple(tupDesc, values, nulls);
- if (oids)
- tuple->t_oid = loaded_oid;
-
- skip_tuple = false;
- /* BEFORE ROW INSERT Triggers */
- if ( rel->trigdesc &&
- rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] > 0 )
- {
- HeapTuple newtuple;
-
- newtuple = ExecBRInsertTriggers (rel, tuple);
-
- if ( newtuple == NULL ) /* "do nothing" */
- skip_tuple = true;
- else if ( newtuple != tuple ) /* modified by Trigger(s) */
- {
- pfree (tuple);
- tuple = newtuple;
- }
- }
-
- if ( !skip_tuple )
- {
- /* ----------------
- * Check the constraints of a tuple
- * ----------------
- */
-
- if ( rel->rd_att->constr )
- {
- HeapTuple newtuple;
-
- newtuple = ExecConstraints ("CopyFrom", rel, tuple);
-
- if ( newtuple != tuple )
- {
- pfree (tuple);
- tuple = newtuple;
- }
- }
-
- heap_insert(rel, tuple);
-
- if (has_index)
- {
- for (i = 0; i < n_indices; i++)
- {
- if (indexPred[i] != NULL)
- {
+ string = (char *) palloc(len);
+ fread(string, len, 1, fp);
+
+ ptr = string;
+
+ for (i = 0; i < attr_count; i++)
+ {
+ if (byval[i] && nulls[i] != 'n')
+ {
+
+ switch (attr[i]->attlen)
+ {
+ case sizeof(char):
+ values[i] = (Datum) * (unsigned char *) ptr;
+ ptr += sizeof(char);
+ break;
+ case sizeof(short):
+ ptr = (char *) SHORTALIGN(ptr);
+ values[i] = (Datum) * (unsigned short *) ptr;
+ ptr += sizeof(short);
+ break;
+ case sizeof(int32):
+ ptr = (char *) INTALIGN(ptr);
+ values[i] = (Datum) * (uint32 *) ptr;
+ ptr += sizeof(int32);
+ break;
+ default:
+ elog(WARN, "COPY BINARY: impossible size!");
+ break;
+ }
+ }
+ else if (nulls[i] != 'n')
+ {
+ switch (attr[i]->attlen)
+ {
+ case -1:
+ if (attr[i]->attalign == 'd')
+ ptr = (char *) DOUBLEALIGN(ptr);
+ else
+ ptr = (char *) INTALIGN(ptr);
+ values[i] = (Datum) ptr;
+ ptr += *(uint32 *) ptr;
+ break;
+ case sizeof(char):
+ values[i] = (Datum) ptr;
+ ptr += attr[i]->attlen;
+ break;
+ case sizeof(short):
+ ptr = (char *) SHORTALIGN(ptr);
+ values[i] = (Datum) ptr;
+ ptr += attr[i]->attlen;
+ break;
+ case sizeof(int32):
+ ptr = (char *) INTALIGN(ptr);
+ values[i] = (Datum) ptr;
+ ptr += attr[i]->attlen;
+ break;
+ default:
+ if (attr[i]->attalign == 'd')
+ ptr = (char *) DOUBLEALIGN(ptr);
+ else
+ ptr = (char *) LONGALIGN(ptr);
+ values[i] = (Datum) ptr;
+ ptr += attr[i]->attlen;
+ }
+ }
+ }
+ }
+ }
+ if (done)
+ continue;
+
+ /*
+ * Does it have any sence ? - vadim 12/14/96
+ *
+ * tupDesc = CreateTupleDesc(attr_count, attr);
+ */
+ tuple = heap_formtuple(tupDesc, values, nulls);
+ if (oids)
+ tuple->t_oid = loaded_oid;
+
+ skip_tuple = false;
+ /* BEFORE ROW INSERT Triggers */
+ if (rel->trigdesc &&
+ rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
+ {
+ HeapTuple newtuple;
+
+ newtuple = ExecBRInsertTriggers(rel, tuple);
+
+ if (newtuple == NULL) /* "do nothing" */
+ skip_tuple = true;
+ else if (newtuple != tuple) /* modified by Trigger(s) */
+ {
+ pfree(tuple);
+ tuple = newtuple;
+ }
+ }
+
+ if (!skip_tuple)
+ {
+ /* ----------------
+ * Check the constraints of a tuple
+ * ----------------
+ */
+
+ if (rel->rd_att->constr)
+ {
+ HeapTuple newtuple;
+
+ newtuple = ExecConstraints("CopyFrom", rel, tuple);
+
+ if (newtuple != tuple)
+ {
+ pfree(tuple);
+ tuple = newtuple;
+ }
+ }
+
+ heap_insert(rel, tuple);
+
+ if (has_index)
+ {
+ for (i = 0; i < n_indices; i++)
+ {
+ if (indexPred[i] != NULL)
+ {
#ifndef OMIT_PARTIAL_INDEX
- /*
- * if tuple doesn't satisfy predicate,
- * don't update index
- */
- slot->val = tuple;
- /*SetSlotContents(slot, tuple); */
- if (ExecQual((List*)indexPred[i], econtext) == false)
- continue;
-#endif /* OMIT_PARTIAL_INDEX */
- }
- FormIndexDatum(indexNatts[i],
- (AttrNumber *)&(pgIndexP[i]->indkey[0]),
- tuple,
- tupDesc,
- InvalidBuffer,
- idatum,
- index_nulls,
- finfoP[i]);
- indexRes = index_insert(index_rels[i], idatum, index_nulls,
- &(tuple->t_ctid), rel);
- if (indexRes) pfree(indexRes);
- }
- }
- /* AFTER ROW INSERT Triggers */
- if ( rel->trigdesc &&
- rel->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0 )
- ExecARInsertTriggers (rel, tuple);
- }
-
- if (binary) pfree(string);
-
- for (i = 0; i < attr_count; i++) {
- if (!byval[i] && nulls[i] != 'n') {
- if (!binary) pfree((void*)values[i]);
- }else if (nulls[i] == 'n') {
- nulls[i] = ' ';
- }
- }
-
- pfree(tuple);
- tuples_read++;
-
- if (!reading_to_eof && ntuples == tuples_read) done = true;
- }
- pfree(values);
- if (!binary) pfree(in_functions);
- pfree(nulls);
- pfree(byval);
- heap_close(rel);
+
+ /*
+ * if tuple doesn't satisfy predicate, don't
+ * update index
+ */
+ slot->val = tuple;
+ /* SetSlotContents(slot, tuple); */
+ if (ExecQual((List *) indexPred[i], econtext) == false)
+ continue;
+#endif /* OMIT_PARTIAL_INDEX */
+ }
+ FormIndexDatum(indexNatts[i],
+ (AttrNumber *) & (pgIndexP[i]->indkey[0]),
+ tuple,
+ tupDesc,
+ InvalidBuffer,
+ idatum,
+ index_nulls,
+ finfoP[i]);
+ indexRes = index_insert(index_rels[i], idatum, index_nulls,
+ &(tuple->t_ctid), rel);
+ if (indexRes)
+ pfree(indexRes);
+ }
+ }
+ /* AFTER ROW INSERT Triggers */
+ if (rel->trigdesc &&
+ rel->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0)
+ ExecARInsertTriggers(rel, tuple);
+ }
+
+ if (binary)
+ pfree(string);
+
+ for (i = 0; i < attr_count; i++)
+ {
+ if (!byval[i] && nulls[i] != 'n')
+ {
+ if (!binary)
+ pfree((void *) values[i]);
+ }
+ else if (nulls[i] == 'n')
+ {
+ nulls[i] = ' ';
+ }
+ }
+
+ pfree(tuple);
+ tuples_read++;
+
+ if (!reading_to_eof && ntuples == tuples_read)
+ done = true;
+ }
+ pfree(values);
+ if (!binary)
+ pfree(in_functions);
+ pfree(nulls);
+ pfree(byval);
+ heap_close(rel);
}
-static Oid
+static Oid
GetOutputFunction(Oid type)
{
- HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type),
- 0,0,0);
-
- if (HeapTupleIsValid(typeTuple))
- return((int) ((TypeTupleForm) GETSTRUCT(typeTuple))->typoutput);
-
- elog(WARN, "GetOutputFunction: Cache lookup of type %d failed", type);
- return(InvalidOid);
+ HeapTuple typeTuple;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+
+ if (HeapTupleIsValid(typeTuple))
+ return ((int) ((TypeTupleForm) GETSTRUCT(typeTuple))->typoutput);
+
+ elog(WARN, "GetOutputFunction: Cache lookup of type %d failed", type);
+ return (InvalidOid);
}
-static Oid
+static Oid
GetTypeElement(Oid type)
{
- HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type),
- 0,0,0);
-
-
- if (HeapTupleIsValid(typeTuple))
- return((int) ((TypeTupleForm) GETSTRUCT(typeTuple))->typelem);
-
- elog(WARN, "GetOutputFunction: Cache lookup of type %d failed", type);
- return(InvalidOid);
+ HeapTuple typeTuple;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+
+
+ if (HeapTupleIsValid(typeTuple))
+ return ((int) ((TypeTupleForm) GETSTRUCT(typeTuple))->typelem);
+
+ elog(WARN, "GetOutputFunction: Cache lookup of type %d failed", type);
+ return (InvalidOid);
}
-static Oid
+static Oid
GetInputFunction(Oid type)
{
- HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type),
- 0,0,0);
-
- if (HeapTupleIsValid(typeTuple))
- return((int) ((TypeTupleForm) GETSTRUCT(typeTuple))->typinput);
-
- elog(WARN, "GetInputFunction: Cache lookup of type %d failed", type);
- return(InvalidOid);
+ HeapTuple typeTuple;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+
+ if (HeapTupleIsValid(typeTuple))
+ return ((int) ((TypeTupleForm) GETSTRUCT(typeTuple))->typinput);
+
+ elog(WARN, "GetInputFunction: Cache lookup of type %d failed", type);
+ return (InvalidOid);
}
-static Oid
+static Oid
IsTypeByVal(Oid type)
{
- HeapTuple typeTuple;
-
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type),
- 0,0,0);
-
- if (HeapTupleIsValid(typeTuple))
- return((int) ((TypeTupleForm) GETSTRUCT(typeTuple))->typbyval);
-
- elog(WARN, "GetInputFunction: Cache lookup of type %d failed", type);
-
- return(InvalidOid);
+ HeapTuple typeTuple;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type),
+ 0, 0, 0);
+
+ if (HeapTupleIsValid(typeTuple))
+ return ((int) ((TypeTupleForm) GETSTRUCT(typeTuple))->typbyval);
+
+ elog(WARN, "GetInputFunction: Cache lookup of type %d failed", type);
+
+ return (InvalidOid);
}
-/*
+/*
* Given the OID of a relation, return an array of index relation descriptors
* and the number of index relations. These relation descriptors are open
* using heap_open().
@@ -779,71 +900,77 @@ IsTypeByVal(Oid type)
* Space for the array itself is palloc'ed.
*/
-typedef struct rel_list {
- Oid index_rel_oid;
- struct rel_list *next;
-} RelationList;
+typedef struct rel_list
+{
+ Oid index_rel_oid;
+ struct rel_list *next;
+} RelationList;
static void
GetIndexRelations(Oid main_relation_oid,
- int *n_indices,
- Relation **index_rels)
+ int *n_indices,
+ Relation ** index_rels)
{
- RelationList *head, *scan;
- Relation pg_index_rel;
- HeapScanDesc scandesc;
- Oid index_relation_oid;
- HeapTuple tuple;
- TupleDesc tupDesc;
- int i;
- bool isnull;
-
- pg_index_rel = heap_openr(IndexRelationName);
- scandesc = heap_beginscan(pg_index_rel, 0, NULL, 0, NULL);
- tupDesc = RelationGetTupleDescriptor(pg_index_rel);
-
- *n_indices = 0;
-
- head = (RelationList *) palloc(sizeof(RelationList));
- scan = head;
- head->next = NULL;
-
- for (tuple = heap_getnext(scandesc, 0, NULL);
- tuple != NULL;
- tuple = heap_getnext(scandesc, 0, NULL)) {
-
- index_relation_oid =
- (Oid) DatumGetInt32(heap_getattr(tuple, InvalidBuffer, 2,
- tupDesc, &isnull));
- if (index_relation_oid == main_relation_oid) {
- scan->index_rel_oid =
- (Oid) DatumGetInt32(heap_getattr(tuple, InvalidBuffer,
- Anum_pg_index_indexrelid,
- tupDesc, &isnull));
- (*n_indices)++;
- scan->next = (RelationList *) palloc(sizeof(RelationList));
- scan = scan->next;
- }
- }
-
- heap_endscan(scandesc);
- heap_close(pg_index_rel);
-
- /* We cannot trust to relhasindex of the main_relation now, so... */
- if ( *n_indices == 0 )
- return;
-
- *index_rels = (Relation *) palloc(*n_indices * sizeof(Relation));
-
- for (i = 0, scan = head; i < *n_indices; i++, scan = scan->next) {
- (*index_rels)[i] = index_open(scan->index_rel_oid);
- }
-
- for (i = 0, scan = head; i < *n_indices + 1; i++) {
- scan = head->next;
- pfree(head);
- head = scan;
- }
+ RelationList *head,
+ *scan;
+ Relation pg_index_rel;
+ HeapScanDesc scandesc;
+ Oid index_relation_oid;
+ HeapTuple tuple;
+ TupleDesc tupDesc;
+ int i;
+ bool isnull;
+
+ pg_index_rel = heap_openr(IndexRelationName);
+ scandesc = heap_beginscan(pg_index_rel, 0, NULL, 0, NULL);
+ tupDesc = RelationGetTupleDescriptor(pg_index_rel);
+
+ *n_indices = 0;
+
+ head = (RelationList *) palloc(sizeof(RelationList));
+ scan = head;
+ head->next = NULL;
+
+ for (tuple = heap_getnext(scandesc, 0, NULL);
+ tuple != NULL;
+ tuple = heap_getnext(scandesc, 0, NULL))
+ {
+
+ index_relation_oid =
+ (Oid) DatumGetInt32(heap_getattr(tuple, InvalidBuffer, 2,
+ tupDesc, &isnull));
+ if (index_relation_oid == main_relation_oid)
+ {
+ scan->index_rel_oid =
+ (Oid) DatumGetInt32(heap_getattr(tuple, InvalidBuffer,
+ Anum_pg_index_indexrelid,
+ tupDesc, &isnull));
+ (*n_indices)++;
+ scan->next = (RelationList *) palloc(sizeof(RelationList));
+ scan = scan->next;
+ }
+ }
+
+ heap_endscan(scandesc);
+ heap_close(pg_index_rel);
+
+ /* We cannot trust to relhasindex of the main_relation now, so... */
+ if (*n_indices == 0)
+ return;
+
+ *index_rels = (Relation *) palloc(*n_indices * sizeof(Relation));
+
+ for (i = 0, scan = head; i < *n_indices; i++, scan = scan->next)
+ {
+ (*index_rels)[i] = index_open(scan->index_rel_oid);
+ }
+
+ for (i = 0, scan = head; i < *n_indices + 1; i++)
+ {
+ scan = head->next;
+ pfree(head);
+ head = scan;
+ }
}
#define EXT_ATTLEN 5*8192
@@ -851,20 +978,22 @@ GetIndexRelations(Oid main_relation_oid,
/*
returns 1 is c is in s
*/
-static bool
-inString(char c, char* s)
+static bool
+inString(char c, char *s)
{
- int i;
-
- if (s) {
- i = 0;
- while (s[i] != '\0') {
- if (s[i] == c)
- return 1;
- i++;
- }
- }
- return 0;
+ int i;
+
+ if (s)
+ {
+ i = 0;
+ while (s[i] != '\0')
+ {
+ if (s[i] == c)
+ return 1;
+ i++;
+ }
+ }
+ return 0;
}
#ifdef COPY_PATCH
@@ -873,19 +1002,21 @@ inString(char c, char* s)
*/
void
-CopyReadNewline(FILE *fp, int *newline)
+CopyReadNewline(FILE * fp, int *newline)
{
- if (!*newline) {
+ if (!*newline)
+ {
#ifdef COPY_DEBUG
- elog(NOTICE, "CopyReadNewline: line %d - extra fields ignored",
- lineno);
+ elog(NOTICE, "CopyReadNewline: line %d - extra fields ignored",
+ lineno);
#else
- elog(NOTICE, "CopyReadNewline: line - extra fields ignored");
+ elog(NOTICE, "CopyReadNewline: line - extra fields ignored");
#endif
- while (!feof(fp) && (getc(fp) != '\n'));
- }
- *newline = 0;
+ while (!feof(fp) && (getc(fp) != '\n'));
+ }
+ *newline = 0;
}
+
#endif
/*
@@ -895,148 +1026,167 @@ CopyReadNewline(FILE *fp, int *newline)
* can be used as standard input.
*/
-static char *
+static char *
#ifdef COPY_PATCH
-CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline)
+CopyReadAttribute(FILE * fp, bool * isnull, char *delim, int *newline)
#else
-CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
+CopyReadAttribute(FILE * fp, bool * isnull, char *delim)
#endif
{
- static char attribute[EXT_ATTLEN];
- char c;
- int done = 0;
- int i = 0;
-
+ static char attribute[EXT_ATTLEN];
+ char c;
+ int done = 0;
+ int i = 0;
+
#ifdef COPY_PATCH
- /* if last delimiter was a newline return a NULL attribute */
- if (*newline) {
- *isnull = (bool) true;
- return(NULL);
- }
+ /* if last delimiter was a newline return a NULL attribute */
+ if (*newline)
+ {
+ *isnull = (bool) true;
+ return (NULL);
+ }
#endif
- *isnull = (bool) false; /* set default */
- if (feof(fp))
- return(NULL);
-
- while (!done) {
- c = getc(fp);
-
- if (feof(fp))
- return(NULL);
- else if (c == '\\') {
- c = getc(fp);
- if (feof(fp))
- return(NULL);
- switch (c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7': {
- int val;
- val = VALUE(c);
- c = getc(fp);
- if (ISOCTAL(c)) {
- val = (val<<3) + VALUE(c);
- c = getc(fp);
- if (ISOCTAL(c)) {
- val = (val<<3) + VALUE(c);
- } else {
- if (feof(fp))
- return(NULL);
- ungetc(c, fp);
- }
- } else {
- if (feof(fp))
- return(NULL);
- ungetc(c, fp);
- }
- c = val & 0377;
- }
- break;
- case 'b':
- c = '\b';
- break;
- case 'f':
- c = '\f';
- break;
- case 'n':
- c = '\n';
- break;
- case 'r':
- c = '\r';
- break;
- case 't':
- c = '\t';
- break;
- case 'v':
- c = '\v';
- break;
- case 'N':
- attribute[0] = '\0'; /* just to be safe */
- *isnull = (bool) true;
- break;
- case '.':
- c = getc(fp);
- if (c != '\n')
- elog(WARN, "CopyReadAttribute - end of record marker corrupted");
- return(NULL);
- break;
- }
- }else if (inString(c,delim) || c == '\n') {
+ *isnull = (bool) false; /* set default */
+ if (feof(fp))
+ return (NULL);
+
+ while (!done)
+ {
+ c = getc(fp);
+
+ if (feof(fp))
+ return (NULL);
+ else if (c == '\\')
+ {
+ c = getc(fp);
+ if (feof(fp))
+ return (NULL);
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ {
+ int val;
+
+ val = VALUE(c);
+ c = getc(fp);
+ if (ISOCTAL(c))
+ {
+ val = (val << 3) + VALUE(c);
+ c = getc(fp);
+ if (ISOCTAL(c))
+ {
+ val = (val << 3) + VALUE(c);
+ }
+ else
+ {
+ if (feof(fp))
+ return (NULL);
+ ungetc(c, fp);
+ }
+ }
+ else
+ {
+ if (feof(fp))
+ return (NULL);
+ ungetc(c, fp);
+ }
+ c = val & 0377;
+ }
+ break;
+ case 'b':
+ c = '\b';
+ break;
+ case 'f':
+ c = '\f';
+ break;
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ case 'v':
+ c = '\v';
+ break;
+ case 'N':
+ attribute[0] = '\0'; /* just to be safe */
+ *isnull = (bool) true;
+ break;
+ case '.':
+ c = getc(fp);
+ if (c != '\n')
+ elog(WARN, "CopyReadAttribute - end of record marker corrupted");
+ return (NULL);
+ break;
+ }
+ }
+ else if (inString(c, delim) || c == '\n')
+ {
#ifdef COPY_PATCH
- if (c == '\n') {
- *newline = 1;
- }
+ if (c == '\n')
+ {
+ *newline = 1;
+ }
#endif
- done = 1;
- }
- if (!done) attribute[i++] = c;
- if (i == EXT_ATTLEN - 1)
- elog(WARN, "CopyReadAttribute - attribute length too long");
- }
- attribute[i] = '\0';
- return(&attribute[0]);
+ done = 1;
+ }
+ if (!done)
+ attribute[i++] = c;
+ if (i == EXT_ATTLEN - 1)
+ elog(WARN, "CopyReadAttribute - attribute length too long");
+ }
+ attribute[i] = '\0';
+ return (&attribute[0]);
}
static void
-CopyAttributeOut(FILE *fp, char *string, char *delim)
+CopyAttributeOut(FILE * fp, char *string, char *delim)
{
- char c;
- int is_array = false;
- int len = strlen(string);
-
- /* XXX - This is a kludge, we should check the data type */
- if (len && (string[0] == '{') && (string[len-1] == '}'))
- is_array = true;
-
- for ( ; (c = *string) != '\0'; string++) {
- if (c == delim[0] || c == '\n' ||
- (c == '\\' && !is_array))
- fputc('\\', fp);
- else
- if (c == '\\' && is_array)
- if (*(string+1) == '\\') {
- /* translate \\ to \\\\ */
- fputc('\\', fp);
- fputc('\\', fp);
- fputc('\\', fp);
- string++;
- } else if (*(string+1) == '"') {
- /* translate \" to \\\" */
- fputc('\\', fp);
- fputc('\\', fp);
- }
- fputc(*string, fp);
- }
+ char c;
+ int is_array = false;
+ int len = strlen(string);
+
+ /* XXX - This is a kludge, we should check the data type */
+ if (len && (string[0] == '{') && (string[len - 1] == '}'))
+ is_array = true;
+
+ for (; (c = *string) != '\0'; string++)
+ {
+ if (c == delim[0] || c == '\n' ||
+ (c == '\\' && !is_array))
+ fputc('\\', fp);
+ else if (c == '\\' && is_array)
+ if (*(string + 1) == '\\')
+ {
+ /* translate \\ to \\\\ */
+ fputc('\\', fp);
+ fputc('\\', fp);
+ fputc('\\', fp);
+ string++;
+ }
+ else if (*(string + 1) == '"')
+ {
+ /* translate \" to \\\" */
+ fputc('\\', fp);
+ fputc('\\', fp);
+ }
+ fputc(*string, fp);
+ }
}
/*
- * Returns the number of tuples in a relation. Unfortunately, currently
+ * Returns the number of tuples in a relation. Unfortunately, currently
* must do a scan of the entire relation to determine this.
*
* relation is expected to be an open relation descriptor.
@@ -1044,17 +1194,17 @@ CopyAttributeOut(FILE *fp, char *string, char *delim)
static int
CountTuples(Relation relation)
{
- HeapScanDesc scandesc;
- HeapTuple tuple;
-
- int i;
-
- scandesc = heap_beginscan(relation, 0, NULL, 0, NULL);
-
- for (tuple = heap_getnext(scandesc, 0, NULL), i = 0;
- tuple != NULL;
- tuple = heap_getnext(scandesc, 0, NULL), i++)
- ;
- heap_endscan(scandesc);
- return(i);
+ HeapScanDesc scandesc;
+ HeapTuple tuple;
+
+ int i;
+
+ scandesc = heap_beginscan(relation, 0, NULL, 0, NULL);
+
+ for (tuple = heap_getnext(scandesc, 0, NULL), i = 0;
+ tuple != NULL;
+ tuple = heap_getnext(scandesc, 0, NULL), i++)
+ ;
+ heap_endscan(scandesc);
+ return (i);
}
diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c
index 248aaa3e768..92641ca70d6 100644
--- a/src/backend/commands/creatinh.c
+++ b/src/backend/commands/creatinh.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* creatinh.c--
- * POSTGRES create/destroy relation with inheritance utility code.
+ * POSTGRES create/destroy relation with inheritance utility code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.14 1997/08/22 03:03:56 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.15 1997/09/07 04:40:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,623 +29,661 @@
#include <catalog/pg_ipl.h>
/* ----------------
- * local stuff
+ * local stuff
* ----------------
*/
-static int checkAttrExists(char *attributeName,
- char *attributeType, List *schema);
-static List *MergeAttributes(List *schema, List *supers, List **supconstr);
-static void StoreCatalogInheritance(Oid relationId, List *supers);
+static int
+checkAttrExists(char *attributeName,
+ char *attributeType, List * schema);
+static List *MergeAttributes(List * schema, List * supers, List ** supconstr);
+static void StoreCatalogInheritance(Oid relationId, List * supers);
/* ----------------------------------------------------------------
- * DefineRelation --
- * Creates a new relation.
+ * DefineRelation --
+ * Creates a new relation.
* ----------------------------------------------------------------
*/
void
-DefineRelation(CreateStmt *stmt)
+DefineRelation(CreateStmt * stmt)
{
- char *relname = palloc(NAMEDATALEN);
- List *schema = stmt->tableElts;
- int numberOfAttributes;
- Oid relationId;
- char archChar;
- List *inheritList = NULL;
- char *archiveName = NULL;
- TupleDesc descriptor;
- List *constraints;
- int heaploc, archloc;
-
- char* typename = NULL; /* the typename of this relation. not useod for now */
-
- if ( strlen(stmt->relname) >= NAMEDATALEN)
- elog(WARN, "the relation name %s is >= %d characters long", stmt->relname,
- NAMEDATALEN);
- strNcpy(relname,stmt->relname,NAMEDATALEN-1); /* make full length for copy */
-
- /* ----------------
- * Handle parameters
- * XXX parameter handling missing below.
- * ----------------
- */
- inheritList = stmt->inhRelnames;
-
- /* ----------------
- * determine archive mode
- * XXX use symbolic constants...
- * ----------------
- */
- archChar = 'n';
-
- switch (stmt->archiveType) {
- case ARCH_NONE:
+ char *relname = palloc(NAMEDATALEN);
+ List *schema = stmt->tableElts;
+ int numberOfAttributes;
+ Oid relationId;
+ char archChar;
+ List *inheritList = NULL;
+ char *archiveName = NULL;
+ TupleDesc descriptor;
+ List *constraints;
+ int heaploc,
+ archloc;
+
+ char *typename = NULL; /* the typename of this relation.
+ * not useod for now */
+
+ if (strlen(stmt->relname) >= NAMEDATALEN)
+ elog(WARN, "the relation name %s is >= %d characters long", stmt->relname,
+ NAMEDATALEN);
+ strNcpy(relname, stmt->relname, NAMEDATALEN - 1); /* make full length for
+ * copy */
+
+ /* ----------------
+ * Handle parameters
+ * XXX parameter handling missing below.
+ * ----------------
+ */
+ inheritList = stmt->inhRelnames;
+
+ /* ----------------
+ * determine archive mode
+ * XXX use symbolic constants...
+ * ----------------
+ */
archChar = 'n';
- break;
- case ARCH_LIGHT:
- archChar = 'l';
- break;
- case ARCH_HEAVY:
- archChar = 'h';
- break;
- default:
- elog(WARN, "Botched archive mode %d, ignoring",
- stmt->archiveType);
- break;
- }
-
- if (stmt->location == -1)
- heaploc = 0;
- else
- heaploc = stmt->location;
-
- /*
- * For now, any user-defined relation defaults to the magnetic
- * disk storgage manager. --mao 2 july 91
- */
- if (stmt->archiveLoc == -1) {
- archloc = 0;
- } else {
- if (archChar == 'n') {
- elog(WARN, "Set archive location, but not mode, for %s",
- relname);
+
+ switch (stmt->archiveType)
+ {
+ case ARCH_NONE:
+ archChar = 'n';
+ break;
+ case ARCH_LIGHT:
+ archChar = 'l';
+ break;
+ case ARCH_HEAVY:
+ archChar = 'h';
+ break;
+ default:
+ elog(WARN, "Botched archive mode %d, ignoring",
+ stmt->archiveType);
+ break;
+ }
+
+ if (stmt->location == -1)
+ heaploc = 0;
+ else
+ heaploc = stmt->location;
+
+ /*
+ * For now, any user-defined relation defaults to the magnetic disk
+ * storgage manager. --mao 2 july 91
+ */
+ if (stmt->archiveLoc == -1)
+ {
+ archloc = 0;
+ }
+ else
+ {
+ if (archChar == 'n')
+ {
+ elog(WARN, "Set archive location, but not mode, for %s",
+ relname);
+ }
+ archloc = stmt->archiveLoc;
+ }
+
+ /* ----------------
+ * generate relation schema, including inherited attributes.
+ * ----------------
+ */
+ schema = MergeAttributes(schema, inheritList, &constraints);
+ constraints = nconc(constraints, stmt->constraints);
+
+ numberOfAttributes = length(schema);
+ if (numberOfAttributes <= 0)
+ {
+ elog(WARN, "DefineRelation: %s",
+ "please inherit from a relation or define an attribute");
}
- archloc = stmt->archiveLoc;
- }
-
- /* ----------------
- * generate relation schema, including inherited attributes.
- * ----------------
- */
- schema = MergeAttributes(schema, inheritList, &constraints);
- constraints = nconc (constraints, stmt->constraints);
-
- numberOfAttributes = length(schema);
- if (numberOfAttributes <= 0) {
- elog(WARN, "DefineRelation: %s",
- "please inherit from a relation or define an attribute");
- }
-
- /* ----------------
- * create a relation descriptor from the relation schema
- * and create the relation.
- * ----------------
- */
- descriptor = BuildDescForRelation(schema, relname);
-
- if ( constraints != NIL )
- {
- List *entry;
- int nconstr = length (constraints);
- ConstrCheck *check = (ConstrCheck *) palloc (nconstr * sizeof (ConstrCheck));
- int ncheck = 0;
- int i;
-
- foreach (entry, constraints)
- {
- ConstraintDef *cdef = (ConstraintDef *) lfirst (entry);
-
- if ( cdef->type == CONSTR_CHECK )
- {
- if ( cdef->name != NULL )
- {
- for (i = 0; i < ncheck; i++)
- {
- if ( strcmp (check[i].ccname, cdef->name) == 0 )
- elog (WARN, "DefineRelation: name (%s) of CHECK constraint duplicated", cdef->name);
- }
- check[ncheck].ccname = cdef->name;
- }
- else
- {
- check[ncheck].ccname = (char*) palloc (NAMEDATALEN);
- sprintf (check[ncheck].ccname, "$%d", ncheck + 1);
- }
- check[ncheck].ccbin = NULL;
- check[ncheck].ccsrc = (char*) cdef->def;
- ncheck++;
- }
- }
- if ( ncheck > 0 )
- {
- if ( ncheck < nconstr )
- check = (ConstrCheck *) repalloc (check, ncheck * sizeof (ConstrCheck));
- if ( descriptor->constr == NULL )
- {
- descriptor->constr = (TupleConstr *) palloc(sizeof(TupleConstr));
- descriptor->constr->num_defval = 0;
- descriptor->constr->has_not_null = false;
- }
- descriptor->constr->num_check = ncheck;
- descriptor->constr->check = check;
- }
- }
-
- relationId = heap_create(relname,
- typename,
- archChar,
- heaploc,
- descriptor);
-
- StoreCatalogInheritance(relationId, inheritList);
-
- /*
- * create an archive relation if necessary
- */
- if (archChar != 'n')
- {
- TupleDesc tupdesc;
+
+ /* ----------------
+ * create a relation descriptor from the relation schema
+ * and create the relation.
+ * ----------------
+ */
+ descriptor = BuildDescForRelation(schema, relname);
+
+ if (constraints != NIL)
+ {
+ List *entry;
+ int nconstr = length(constraints);
+ ConstrCheck *check = (ConstrCheck *) palloc(nconstr * sizeof(ConstrCheck));
+ int ncheck = 0;
+ int i;
+
+ foreach(entry, constraints)
+ {
+ ConstraintDef *cdef = (ConstraintDef *) lfirst(entry);
+
+ if (cdef->type == CONSTR_CHECK)
+ {
+ if (cdef->name != NULL)
+ {
+ for (i = 0; i < ncheck; i++)
+ {
+ if (strcmp(check[i].ccname, cdef->name) == 0)
+ elog(WARN, "DefineRelation: name (%s) of CHECK constraint duplicated", cdef->name);
+ }
+ check[ncheck].ccname = cdef->name;
+ }
+ else
+ {
+ check[ncheck].ccname = (char *) palloc(NAMEDATALEN);
+ sprintf(check[ncheck].ccname, "$%d", ncheck + 1);
+ }
+ check[ncheck].ccbin = NULL;
+ check[ncheck].ccsrc = (char *) cdef->def;
+ ncheck++;
+ }
+ }
+ if (ncheck > 0)
+ {
+ if (ncheck < nconstr)
+ check = (ConstrCheck *) repalloc(check, ncheck * sizeof(ConstrCheck));
+ if (descriptor->constr == NULL)
+ {
+ descriptor->constr = (TupleConstr *) palloc(sizeof(TupleConstr));
+ descriptor->constr->num_defval = 0;
+ descriptor->constr->has_not_null = false;
+ }
+ descriptor->constr->num_check = ncheck;
+ descriptor->constr->check = check;
+ }
+ }
+
+ relationId = heap_create(relname,
+ typename,
+ archChar,
+ heaploc,
+ descriptor);
+
+ StoreCatalogInheritance(relationId, inheritList);
+
/*
- * Need to create an archive relation for this heap relation.
- * We cobble up the command by hand, and increment the command
- * counter ourselves.
+ * create an archive relation if necessary
*/
-
- CommandCounterIncrement();
- archiveName = MakeArchiveName(relationId);
-
- tupdesc = CreateTupleDescCopy (descriptor); /* get rid of constraints */
- (void) heap_create(archiveName,
- typename,
- 'n', /* archive isn't archived */
- archloc,
- tupdesc);
-
- FreeTupleDesc (tupdesc);
- FreeTupleDesc (descriptor);
- pfree(archiveName);
- }
+ if (archChar != 'n')
+ {
+ TupleDesc tupdesc;
+
+ /*
+ * Need to create an archive relation for this heap relation. We
+ * cobble up the command by hand, and increment the command
+ * counter ourselves.
+ */
+
+ CommandCounterIncrement();
+ archiveName = MakeArchiveName(relationId);
+
+ tupdesc = CreateTupleDescCopy(descriptor); /* get rid of
+ * constraints */
+ (void) heap_create(archiveName,
+ typename,
+ 'n', /* archive isn't archived */
+ archloc,
+ tupdesc);
+
+ FreeTupleDesc(tupdesc);
+ FreeTupleDesc(descriptor);
+ pfree(archiveName);
+ }
}
/*
* RemoveRelation --
- * Deletes a new relation.
+ * Deletes a new relation.
*
* Exceptions:
- * BadArg if name is invalid.
+ * BadArg if name is invalid.
*
* Note:
- * If the relation has indices defined on it, then the index relations
+ * If the relation has indices defined on it, then the index relations
* themselves will be destroyed, too.
*/
void
RemoveRelation(char *name)
{
- AssertArg(name);
- heap_destroy(name);
+ AssertArg(name);
+ heap_destroy(name);
}
/*
* MergeAttributes --
- * Returns new schema given initial schema and supers.
+ * Returns new schema given initial schema and supers.
*
*
* 'schema' is the column/attribute definition for the table. (It's a list
- * of ColumnDef's.) It is destructively changed.
+ * of ColumnDef's.) It is destructively changed.
* 'inheritList' is the list of inherited relations (a list of Value(str)'s).
*
* Notes:
- * The order in which the attributes are inherited is very important.
- * Intuitively, the inherited attributes should come first. If a table
- * inherits from multiple parents, the order of those attributes are
- * according to the order of the parents specified in CREATE TABLE.
+ * The order in which the attributes are inherited is very important.
+ * Intuitively, the inherited attributes should come first. If a table
+ * inherits from multiple parents, the order of those attributes are
+ * according to the order of the parents specified in CREATE TABLE.
*
- * Here's an example:
+ * Here's an example:
*
- * create table person (name text, age int4, location point);
- * create table emp (salary int4, manager char16) inherits(person);
- * create table student (gpa float8) inherits (person);
- * create table stud_emp (percent int4) inherits (emp, student);
+ * create table person (name text, age int4, location point);
+ * create table emp (salary int4, manager char16) inherits(person);
+ * create table student (gpa float8) inherits (person);
+ * create table stud_emp (percent int4) inherits (emp, student);
*
- * the order of the attributes of stud_emp is as follow:
+ * the order of the attributes of stud_emp is as follow:
*
*
- * person {1:name, 2:age, 3:location}
- * / \
- * {6:gpa} student emp {4:salary, 5:manager}
- * \ /
- * stud_emp {7:percent}
+ * person {1:name, 2:age, 3:location}
+ * / \
+ * {6:gpa} student emp {4:salary, 5:manager}
+ * \ /
+ * stud_emp {7:percent}
*/
-static List *
-MergeAttributes(List *schema, List *supers, List **supconstr)
+static List *
+MergeAttributes(List * schema, List * supers, List ** supconstr)
{
- List *entry;
- List *inhSchema = NIL;
- List *constraints = NIL;
-
- /*
- * Validates that there are no duplications.
- * Validity checking of types occurs later.
- */
- foreach (entry, schema) {
- List *rest;
- ColumnDef *coldef = lfirst(entry);
-
- foreach (rest, lnext(entry)) {
- /*
- * check for duplicated relation names
- */
- ColumnDef *restdef = lfirst(rest);
-
- if (!strcmp(coldef->colname, restdef->colname)) {
- elog(WARN, "attribute \"%s\" duplicated",
- coldef->colname);
- }
- }
- }
- foreach (entry, supers) {
- List *rest;
-
- foreach (rest, lnext(entry)) {
- if (!strcmp(strVal(lfirst(entry)), strVal(lfirst(rest)))) {
- elog(WARN, "relation \"%s\" duplicated",
- strVal(lfirst(entry)));
- }
- }
- }
-
- /*
- * merge the inherited attributes into the schema
- */
- foreach (entry, supers) {
- char *name = strVal(lfirst(entry));
- Relation relation;
- List *partialResult = NIL;
- AttrNumber attrno;
- TupleDesc tupleDesc;
- TupleConstr *constr;
-
- relation = heap_openr(name);
- if (relation==NULL) {
- elog(WARN,
- "MergeAttr: Can't inherit from non-existent superclass '%s'",
- name);
- }
- if ( relation->rd_rel->relkind == 'S' )
+ List *entry;
+ List *inhSchema = NIL;
+ List *constraints = NIL;
+
+ /*
+ * Validates that there are no duplications. Validity checking of
+ * types occurs later.
+ */
+ foreach(entry, schema)
{
- elog(WARN, "MergeAttr: Can't inherit from sequence superclass '%s'",
- name);
- }
- tupleDesc = RelationGetTupleDescriptor(relation);
- constr = tupleDesc->constr;
-
- for (attrno = relation->rd_rel->relnatts - 1; attrno >= 0; attrno--) {
- AttributeTupleForm attribute = tupleDesc->attrs[attrno];
- char *attributeName;
- char *attributeType;
- HeapTuple tuple;
- ColumnDef *def;
- TypeName *typename;
-
- /*
- * form name, type and constraints
- */
- attributeName = (attribute->attname).data;
- tuple =
- SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(attribute->atttypid),
- 0,0,0);
- AssertState(HeapTupleIsValid(tuple));
- attributeType =
- (((TypeTupleForm)GETSTRUCT(tuple))->typname).data;
- /*
- * check validity
- *
- */
- if (checkAttrExists(attributeName, attributeType, inhSchema) ||
- checkAttrExists(attributeName, attributeType, schema)) {
- /*
- * this entry already exists
- */
- continue;
- }
-
- /*
- * add an entry to the schema
- */
- def = makeNode(ColumnDef);
- typename = makeNode(TypeName);
- def->colname = pstrdup(attributeName);
- typename->name = pstrdup(attributeType);
- def->typename = typename;
- def->is_not_null = attribute->attnotnull;
- def->defval = NULL;
- if ( attribute->atthasdef )
- {
- AttrDefault *attrdef = constr->defval;
- int i;
-
- Assert ( constr != NULL && constr->num_defval > 0 );
-
- for (i = 0; i < constr->num_defval; i++)
- {
- if ( attrdef[i].adnum != attrno + 1 )
- continue;
- def->defval = pstrdup (attrdef[i].adsrc);
- break;
- }
- Assert ( def->defval != NULL );
- }
- partialResult = lcons(def, partialResult);
+ List *rest;
+ ColumnDef *coldef = lfirst(entry);
+
+ foreach(rest, lnext(entry))
+ {
+
+ /*
+ * check for duplicated relation names
+ */
+ ColumnDef *restdef = lfirst(rest);
+
+ if (!strcmp(coldef->colname, restdef->colname))
+ {
+ elog(WARN, "attribute \"%s\" duplicated",
+ coldef->colname);
+ }
+ }
}
-
- if ( constr && constr->num_check > 0 )
+ foreach(entry, supers)
{
- ConstrCheck *check = constr->check;
- int i;
-
- for (i = 0; i < constr->num_check; i++)
- {
- ConstraintDef *cdef = (ConstraintDef *) palloc (sizeof (ConstraintDef));
-
- cdef->type = CONSTR_CHECK;
- if ( check[i].ccname[0] == '$' )
- cdef->name = NULL;
- else
- cdef->name = pstrdup (check[i].ccname);
- cdef->def = (void*) pstrdup (check[i].ccsrc);
- constraints = lappend (constraints, cdef);
- }
+ List *rest;
+
+ foreach(rest, lnext(entry))
+ {
+ if (!strcmp(strVal(lfirst(entry)), strVal(lfirst(rest))))
+ {
+ elog(WARN, "relation \"%s\" duplicated",
+ strVal(lfirst(entry)));
+ }
+ }
}
-
+
/*
- * iteration cleanup and result collection
+ * merge the inherited attributes into the schema
*/
- heap_close(relation);
+ foreach(entry, supers)
+ {
+ char *name = strVal(lfirst(entry));
+ Relation relation;
+ List *partialResult = NIL;
+ AttrNumber attrno;
+ TupleDesc tupleDesc;
+ TupleConstr *constr;
+
+ relation = heap_openr(name);
+ if (relation == NULL)
+ {
+ elog(WARN,
+ "MergeAttr: Can't inherit from non-existent superclass '%s'",
+ name);
+ }
+ if (relation->rd_rel->relkind == 'S')
+ {
+ elog(WARN, "MergeAttr: Can't inherit from sequence superclass '%s'",
+ name);
+ }
+ tupleDesc = RelationGetTupleDescriptor(relation);
+ constr = tupleDesc->constr;
+
+ for (attrno = relation->rd_rel->relnatts - 1; attrno >= 0; attrno--)
+ {
+ AttributeTupleForm attribute = tupleDesc->attrs[attrno];
+ char *attributeName;
+ char *attributeType;
+ HeapTuple tuple;
+ ColumnDef *def;
+ TypeName *typename;
+
+ /*
+ * form name, type and constraints
+ */
+ attributeName = (attribute->attname).data;
+ tuple =
+ SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(attribute->atttypid),
+ 0, 0, 0);
+ AssertState(HeapTupleIsValid(tuple));
+ attributeType =
+ (((TypeTupleForm) GETSTRUCT(tuple))->typname).data;
+
+ /*
+ * check validity
+ *
+ */
+ if (checkAttrExists(attributeName, attributeType, inhSchema) ||
+ checkAttrExists(attributeName, attributeType, schema))
+ {
+
+ /*
+ * this entry already exists
+ */
+ continue;
+ }
+
+ /*
+ * add an entry to the schema
+ */
+ def = makeNode(ColumnDef);
+ typename = makeNode(TypeName);
+ def->colname = pstrdup(attributeName);
+ typename->name = pstrdup(attributeType);
+ def->typename = typename;
+ def->is_not_null = attribute->attnotnull;
+ def->defval = NULL;
+ if (attribute->atthasdef)
+ {
+ AttrDefault *attrdef = constr->defval;
+ int i;
+
+ Assert(constr != NULL && constr->num_defval > 0);
+
+ for (i = 0; i < constr->num_defval; i++)
+ {
+ if (attrdef[i].adnum != attrno + 1)
+ continue;
+ def->defval = pstrdup(attrdef[i].adsrc);
+ break;
+ }
+ Assert(def->defval != NULL);
+ }
+ partialResult = lcons(def, partialResult);
+ }
+
+ if (constr && constr->num_check > 0)
+ {
+ ConstrCheck *check = constr->check;
+ int i;
+
+ for (i = 0; i < constr->num_check; i++)
+ {
+ ConstraintDef *cdef = (ConstraintDef *) palloc(sizeof(ConstraintDef));
+
+ cdef->type = CONSTR_CHECK;
+ if (check[i].ccname[0] == '$')
+ cdef->name = NULL;
+ else
+ cdef->name = pstrdup(check[i].ccname);
+ cdef->def = (void *) pstrdup(check[i].ccsrc);
+ constraints = lappend(constraints, cdef);
+ }
+ }
+
+ /*
+ * iteration cleanup and result collection
+ */
+ heap_close(relation);
+
+ /*
+ * wants the inherited schema to appear in the order they are
+ * specified in CREATE TABLE
+ */
+ inhSchema = nconc(inhSchema, partialResult);
+ }
/*
- * wants the inherited schema to appear in the order they are
- * specified in CREATE TABLE
+ * put the inherited schema before our the schema for this table
*/
- inhSchema = nconc(inhSchema, partialResult);
- }
-
- /*
- * put the inherited schema before our the schema for this table
- */
- schema = nconc(inhSchema, schema);
- *supconstr = constraints;
- return (schema);
+ schema = nconc(inhSchema, schema);
+ *supconstr = constraints;
+ return (schema);
}
/*
* StoreCatalogInheritance --
- * Updates the system catalogs with proper inheritance information.
+ * Updates the system catalogs with proper inheritance information.
*/
static void
-StoreCatalogInheritance(Oid relationId, List *supers)
+StoreCatalogInheritance(Oid relationId, List * supers)
{
- Relation relation;
- TupleDesc desc;
- int16 seqNumber;
- List *entry;
- List *idList;
- HeapTuple tuple;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- AssertArg(OidIsValid(relationId));
-
- if (supers==NIL)
- return;
-
- /* ----------------
- * Catalog INHERITS information.
- * ----------------
- */
- relation = heap_openr( InheritsRelationName );
- desc = RelationGetTupleDescriptor(relation);
-
- seqNumber = 1;
- idList = NIL;
- foreach (entry, supers) {
- Datum datum[ Natts_pg_inherits ];
- char nullarr[ Natts_pg_inherits ];
-
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(strVal(lfirst(entry))),
- 0,0,0);
- AssertArg(HeapTupleIsValid(tuple));
-
- /*
- * build idList for use below
- */
- idList = lappendi(idList, tuple->t_oid);
-
- datum[0] = ObjectIdGetDatum(relationId); /* inhrel */
- datum[1] = ObjectIdGetDatum(tuple->t_oid); /* inhparent */
- datum[2] = Int16GetDatum(seqNumber); /* inhseqno */
-
- nullarr[0] = ' ';
- nullarr[1] = ' ';
- nullarr[2] = ' ';
-
- tuple = heap_formtuple(desc,datum, nullarr);
-
- heap_insert(relation, tuple);
- pfree(tuple);
-
- seqNumber += 1;
- }
-
- heap_close(relation);
-
- /* ----------------
- * Catalog IPL information.
- *
- * Algorithm:
- * 0. list superclasses (by Oid) in order given (see idList).
- * 1. append after each relationId, its superclasses, recursively.
- * 3. remove all but last of duplicates.
- * 4. store result.
- * ----------------
- */
-
- /* ----------------
- * 1.
- * ----------------
- */
- foreach (entry, idList) {
+ Relation relation;
+ TupleDesc desc;
+ int16 seqNumber;
+ List *entry;
+ List *idList;
HeapTuple tuple;
- Oid id;
- int16 number;
- List *next;
- List *current;
-
- id = (Oid)lfirsti(entry);
- current = entry;
- next = lnext(entry);
-
- for (number = 1; ; number += 1) {
- tuple = SearchSysCacheTuple(INHRELID,
- ObjectIdGetDatum(id),
- Int16GetDatum(number),
- 0,0);
-
- if (! HeapTupleIsValid(tuple))
- break;
-
- lnext(current) =
- lconsi(((InheritsTupleForm)
- GETSTRUCT(tuple))->inhparent,
- NIL);
-
- current = lnext(current);
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ AssertArg(OidIsValid(relationId));
+
+ if (supers == NIL)
+ return;
+
+ /* ----------------
+ * Catalog INHERITS information.
+ * ----------------
+ */
+ relation = heap_openr(InheritsRelationName);
+ desc = RelationGetTupleDescriptor(relation);
+
+ seqNumber = 1;
+ idList = NIL;
+ foreach(entry, supers)
+ {
+ Datum datum[Natts_pg_inherits];
+ char nullarr[Natts_pg_inherits];
+
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(strVal(lfirst(entry))),
+ 0, 0, 0);
+ AssertArg(HeapTupleIsValid(tuple));
+
+ /*
+ * build idList for use below
+ */
+ idList = lappendi(idList, tuple->t_oid);
+
+ datum[0] = ObjectIdGetDatum(relationId); /* inhrel */
+ datum[1] = ObjectIdGetDatum(tuple->t_oid); /* inhparent */
+ datum[2] = Int16GetDatum(seqNumber); /* inhseqno */
+
+ nullarr[0] = ' ';
+ nullarr[1] = ' ';
+ nullarr[2] = ' ';
+
+ tuple = heap_formtuple(desc, datum, nullarr);
+
+ heap_insert(relation, tuple);
+ pfree(tuple);
+
+ seqNumber += 1;
}
- lnext(current) = next;
- }
-
- /* ----------------
- * 2.
- * ----------------
- */
- foreach (entry, idList) {
- Oid name;
- List *rest;
- bool found = false;
-
- again:
- name = lfirsti(entry);
- foreach (rest, lnext(entry)) {
- if (name == lfirsti(rest)) {
- found = true;
- break;
- }
+
+ heap_close(relation);
+
+ /* ----------------
+ * Catalog IPL information.
+ *
+ * Algorithm:
+ * 0. list superclasses (by Oid) in order given (see idList).
+ * 1. append after each relationId, its superclasses, recursively.
+ * 3. remove all but last of duplicates.
+ * 4. store result.
+ * ----------------
+ */
+
+ /* ----------------
+ * 1.
+ * ----------------
+ */
+ foreach(entry, idList)
+ {
+ HeapTuple tuple;
+ Oid id;
+ int16 number;
+ List *next;
+ List *current;
+
+ id = (Oid) lfirsti(entry);
+ current = entry;
+ next = lnext(entry);
+
+ for (number = 1;; number += 1)
+ {
+ tuple = SearchSysCacheTuple(INHRELID,
+ ObjectIdGetDatum(id),
+ Int16GetDatum(number),
+ 0, 0);
+
+ if (!HeapTupleIsValid(tuple))
+ break;
+
+ lnext(current) =
+ lconsi(((InheritsTupleForm)
+ GETSTRUCT(tuple))->inhparent,
+ NIL);
+
+ current = lnext(current);
+ }
+ lnext(current) = next;
}
- if (found) {
- /*
- * entry list must be of length >= 2 or else no match
- *
- * so, remove this entry.
- */
- lfirst(entry) = lfirst(lnext(entry));
- lnext(entry) = lnext(lnext(entry));
-
- found = false;
- goto again;
+
+ /* ----------------
+ * 2.
+ * ----------------
+ */
+ foreach(entry, idList)
+ {
+ Oid name;
+ List *rest;
+ bool found = false;
+
+again:
+ name = lfirsti(entry);
+ foreach(rest, lnext(entry))
+ {
+ if (name == lfirsti(rest))
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ {
+
+ /*
+ * entry list must be of length >= 2 or else no match
+ *
+ * so, remove this entry.
+ */
+ lfirst(entry) = lfirst(lnext(entry));
+ lnext(entry) = lnext(lnext(entry));
+
+ found = false;
+ goto again;
+ }
}
- }
-
- /* ----------------
- * 3.
- * ----------------
- */
- relation = heap_openr( InheritancePrecidenceListRelationName );
- desc = RelationGetTupleDescriptor(relation);
-
- seqNumber = 1;
-
- foreach (entry, idList) {
- Datum datum[ Natts_pg_ipl ];
- char nullarr[ Natts_pg_ipl ];
-
- datum[0] = ObjectIdGetDatum(relationId); /* iplrel */
- datum[1] = ObjectIdGetDatum(lfirsti(entry));
- /*iplinherits*/
- datum[2] = Int16GetDatum(seqNumber); /* iplseqno */
-
- nullarr[0] = ' ';
- nullarr[1] = ' ';
- nullarr[2] = ' ';
-
- tuple = heap_formtuple( desc, datum, nullarr);
-
- heap_insert(relation, tuple);
- pfree(tuple);
-
- seqNumber += 1;
- }
-
- heap_close(relation);
+
+ /* ----------------
+ * 3.
+ * ----------------
+ */
+ relation = heap_openr(InheritancePrecidenceListRelationName);
+ desc = RelationGetTupleDescriptor(relation);
+
+ seqNumber = 1;
+
+ foreach(entry, idList)
+ {
+ Datum datum[Natts_pg_ipl];
+ char nullarr[Natts_pg_ipl];
+
+ datum[0] = ObjectIdGetDatum(relationId); /* iplrel */
+ datum[1] = ObjectIdGetDatum(lfirsti(entry));
+ /* iplinherits */
+ datum[2] = Int16GetDatum(seqNumber); /* iplseqno */
+
+ nullarr[0] = ' ';
+ nullarr[1] = ' ';
+ nullarr[2] = ' ';
+
+ tuple = heap_formtuple(desc, datum, nullarr);
+
+ heap_insert(relation, tuple);
+ pfree(tuple);
+
+ seqNumber += 1;
+ }
+
+ heap_close(relation);
}
/*
* returns 1 if attribute already exists in schema, 0 otherwise.
*/
static int
-checkAttrExists(char *attributeName, char *attributeType, List *schema)
+checkAttrExists(char *attributeName, char *attributeType, List * schema)
{
- List *s;
-
- foreach (s, schema) {
- ColumnDef *def = lfirst(s);
-
- if (!strcmp(attributeName, def->colname)) {
- /*
- * attribute exists. Make sure the types are the same.
- */
- if (strcmp(attributeType, def->typename->name) != 0) {
- elog(WARN, "%s and %s conflict for %s",
- attributeType, def->typename->name, attributeName);
- }
- return 1;
+ List *s;
+
+ foreach(s, schema)
+ {
+ ColumnDef *def = lfirst(s);
+
+ if (!strcmp(attributeName, def->colname))
+ {
+
+ /*
+ * attribute exists. Make sure the types are the same.
+ */
+ if (strcmp(attributeType, def->typename->name) != 0)
+ {
+ elog(WARN, "%s and %s conflict for %s",
+ attributeType, def->typename->name, attributeName);
+ }
+ return 1;
+ }
}
- }
- return 0;
+ return 0;
}
/*
* MakeArchiveName
- * make an archive rel name out of a regular rel name
+ * make an archive rel name out of a regular rel name
*
* the CALLER is responsible for freeing the memory allocated
*/
-char*
+char *
MakeArchiveName(Oid relationId)
{
- char *arch;
+ char *arch;
- /*
- * Archive relations are named a,XXXXX where XXXXX == the OID
- * of the relation they archive. Create a string containing
- * this name and find the reldesc for the archive relation.
- */
- arch = palloc(NAMEDATALEN);
- sprintf(arch, "a,%d",relationId);
+ /*
+ * Archive relations are named a,XXXXX where XXXXX == the OID of the
+ * relation they archive. Create a string containing this name and
+ * find the reldesc for the archive relation.
+ */
+ arch = palloc(NAMEDATALEN);
+ sprintf(arch, "a,%d", relationId);
- return arch;
+ return arch;
}
diff --git a/src/backend/commands/defind.c b/src/backend/commands/defind.c
index c6b293fec68..9b8c5a0218a 100644
--- a/src/backend/commands/defind.c
+++ b/src/backend/commands/defind.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* defind.c--
- * POSTGRES define, extend and remove index code.
+ * POSTGRES define, extend and remove index code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/defind.c,v 1.12 1997/03/26 03:05:28 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/defind.c,v 1.13 1997/09/07 04:40:43 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,7 +30,7 @@
#include <utils/relcache.h>
#include <utils/lsyscache.h>
#include <commands/defrem.h>
-#include <parser/parsetree.h> /* for getrelid() */
+#include <parser/parsetree.h> /* for getrelid() */
#include <optimizer/prep.h>
#include <optimizer/clauses.h>
#include <storage/lmgr.h>
@@ -39,508 +39,543 @@
#define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args!=NULL)
/* non-export function prototypes */
-static void CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid);
-static void CheckPredExpr(Node *predicate, List *rangeTable,
+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, AttrNumber *attNumP,
- Oid *argTypes, Oid *opOidP, Oid relId);
-static void NormIndexAttrs(List *attList, AttrNumber *attNumP,
- Oid *opOidP, Oid relId);
-static char *GetDefaultOpClass(Oid atttypid);
+ CheckPredClause(Expr * predicate, List * rangeTable, Oid baseRelOid);
+static void
+FuncIndexArgs(IndexElem * funcIndex, AttrNumber * attNumP,
+ Oid * argTypes, Oid * opOidP, Oid relId);
+static void
+NormIndexAttrs(List * attList, AttrNumber * attNumP,
+ Oid * opOidP, Oid relId);
+static char *GetDefaultOpClass(Oid atttypid);
/*
* DefineIndex --
- * Creates a new index.
+ * Creates a new index.
*
* 'attributeList' is a list of IndexElem specifying either a functional
- * index or a list of attributes to index on.
+ * index or a list of attributes to index on.
* 'parameterList' is a list of ParamString specified in the with clause.
* 'predicate' is the qual specified in the where clause.
* 'rangetable' is for the predicate
*
* Exceptions:
- * XXX
+ * XXX
*/
void
DefineIndex(char *heapRelationName,
- char *indexRelationName,
- char *accessMethodName,
- List *attributeList,
- List *parameterList,
- bool unique,
- Expr *predicate,
- List *rangetable)
+ char *indexRelationName,
+ char *accessMethodName,
+ List * attributeList,
+ List * parameterList,
+ bool unique,
+ Expr * predicate,
+ List * rangetable)
{
- Oid *classObjectId;
- Oid accessMethodId;
- Oid relationId;
- int numberOfAttributes;
- AttrNumber *attributeNumberA;
- HeapTuple tuple;
- uint16 parameterCount = 0;
- Datum *parameterA = NULL;
- FuncIndexInfo fInfo;
- List *cnfPred = NULL;
- bool lossy = FALSE;
- List *pl;
-
- /*
- * Handle attributes
- */
- numberOfAttributes = length(attributeList);
- if (numberOfAttributes <= 0) {
- elog(WARN, "DefineIndex: must specify at least one attribute");
- }
-
- /*
- * compute heap relation id
- */
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(heapRelationName),
- 0,0,0);
- if (!HeapTupleIsValid(tuple)) {
- elog(WARN, "DefineIndex: %s relation not found",
- heapRelationName);
- }
- relationId = tuple->t_oid;
-
- if (unique && strcmp(accessMethodName,"btree") != 0)
- elog(WARN, "DefineIndex: unique indices are only available with the btree access method");
-
- if (numberOfAttributes > 1 && strcmp(accessMethodName,"btree") != 0)
- elog(WARN, "DefineIndex: multi-column indices are only available with the btree access method");
-
- /*
- * compute access method id
- */
- tuple = SearchSysCacheTuple(AMNAME, PointerGetDatum(accessMethodName),
- 0,0,0);
- if (!HeapTupleIsValid(tuple)) {
- elog(WARN, "DefineIndex: %s access method not found",
- accessMethodName);
- }
- accessMethodId = tuple->t_oid;
-
-
- /*
- * Handle parameters
- * [param list is now different (NOT USED, really) - ay 10/94]
- *
- * WITH clause reinstated to handle lossy indices.
- * -- JMH, 7/22/96
- */
- foreach(pl, parameterList) {
- ParamString *param = (ParamString*)lfirst(pl);
-
- if (!strcasecmp(param->name, "islossy"))
- lossy = TRUE;
- }
-
-
- /*
- * Convert the partial-index predicate from parsetree form to plan
- * form, so it can be readily evaluated during index creation.
- * Note: "predicate" comes in as a list containing (1) the predicate
- * itself (a where_clause), and (2) a corresponding range table.
- *
- * [(1) is 'predicate' and (2) is 'rangetable' now. - ay 10/94]
- */
- if (predicate != NULL && rangetable != NIL) {
- cnfPred = cnfify((Expr*)copyObject(predicate), true);
- fix_opids(cnfPred);
- CheckPredicate(cnfPred, rangetable, relationId);
- }
-
- if (IsFuncIndex(attributeList)) {
- IndexElem *funcIndex= lfirst(attributeList);
- int nargs;
-
- nargs = length(funcIndex->args);
- if (nargs > INDEX_MAX_KEYS) {
- elog(WARN,
- "Too many args to function, limit of %d",
- INDEX_MAX_KEYS);
+ Oid *classObjectId;
+ Oid accessMethodId;
+ Oid relationId;
+ int numberOfAttributes;
+ AttrNumber *attributeNumberA;
+ HeapTuple tuple;
+ uint16 parameterCount = 0;
+ Datum *parameterA = NULL;
+ FuncIndexInfo fInfo;
+ List *cnfPred = NULL;
+ bool lossy = FALSE;
+ List *pl;
+
+ /*
+ * Handle attributes
+ */
+ numberOfAttributes = length(attributeList);
+ if (numberOfAttributes <= 0)
+ {
+ elog(WARN, "DefineIndex: must specify at least one attribute");
+ }
+
+ /*
+ * compute heap relation id
+ */
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(heapRelationName),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN, "DefineIndex: %s relation not found",
+ heapRelationName);
}
-
- FIsetnArgs(&fInfo,nargs);
+ relationId = tuple->t_oid;
- strcpy(FIgetname(&fInfo), funcIndex->name);
+ if (unique && strcmp(accessMethodName, "btree") != 0)
+ elog(WARN, "DefineIndex: unique indices are only available with the btree access method");
- attributeNumberA =
- (AttrNumber *)palloc(nargs * sizeof attributeNumberA[0]);
-
- classObjectId = (Oid *)palloc(sizeof classObjectId[0]);
-
-
- FuncIndexArgs(funcIndex, attributeNumberA,
- &(FIgetArg(&fInfo, 0)),
- classObjectId, relationId);
-
- index_create(heapRelationName,
- indexRelationName,
- &fInfo, NULL, accessMethodId,
- numberOfAttributes, attributeNumberA,
- classObjectId, parameterCount, parameterA, (Node*)cnfPred,
- lossy, unique);
- }else {
- attributeNumberA =
- (AttrNumber *)palloc(numberOfAttributes *
- sizeof attributeNumberA[0]);
-
- classObjectId =
- (Oid *)palloc(numberOfAttributes * sizeof classObjectId[0]);
-
- NormIndexAttrs(attributeList, attributeNumberA,
- classObjectId, relationId);
-
- index_create(heapRelationName, indexRelationName, NULL,
- attributeList,
- accessMethodId, numberOfAttributes, attributeNumberA,
- classObjectId, parameterCount, parameterA, (Node*)cnfPred,
- lossy, unique);
- }
+ if (numberOfAttributes > 1 && strcmp(accessMethodName, "btree") != 0)
+ elog(WARN, "DefineIndex: multi-column indices are only available with the btree access method");
+
+ /*
+ * compute access method id
+ */
+ tuple = SearchSysCacheTuple(AMNAME, PointerGetDatum(accessMethodName),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN, "DefineIndex: %s access method not found",
+ accessMethodName);
+ }
+ accessMethodId = tuple->t_oid;
+
+
+ /*
+ * Handle parameters [param list is now different (NOT USED, really) -
+ * ay 10/94]
+ *
+ * WITH clause reinstated to handle lossy indices. -- JMH, 7/22/96
+ */
+ foreach(pl, parameterList)
+ {
+ ParamString *param = (ParamString *) lfirst(pl);
+
+ if (!strcasecmp(param->name, "islossy"))
+ lossy = TRUE;
+ }
+
+
+ /*
+ * Convert the partial-index predicate from parsetree form to plan
+ * form, so it can be readily evaluated during index creation. Note:
+ * "predicate" comes in as a list containing (1) the predicate itself
+ * (a where_clause), and (2) a corresponding range table.
+ *
+ * [(1) is 'predicate' and (2) is 'rangetable' now. - ay 10/94]
+ */
+ if (predicate != NULL && rangetable != NIL)
+ {
+ cnfPred = cnfify((Expr *) copyObject(predicate), true);
+ fix_opids(cnfPred);
+ CheckPredicate(cnfPred, rangetable, relationId);
+ }
+
+ if (IsFuncIndex(attributeList))
+ {
+ IndexElem *funcIndex = lfirst(attributeList);
+ int nargs;
+
+ nargs = length(funcIndex->args);
+ if (nargs > INDEX_MAX_KEYS)
+ {
+ elog(WARN,
+ "Too many args to function, limit of %d",
+ INDEX_MAX_KEYS);
+ }
+
+ FIsetnArgs(&fInfo, nargs);
+
+ strcpy(FIgetname(&fInfo), funcIndex->name);
+
+ attributeNumberA =
+ (AttrNumber *) palloc(nargs * sizeof attributeNumberA[0]);
+
+ classObjectId = (Oid *) palloc(sizeof classObjectId[0]);
+
+
+ FuncIndexArgs(funcIndex, attributeNumberA,
+ &(FIgetArg(&fInfo, 0)),
+ classObjectId, relationId);
+
+ index_create(heapRelationName,
+ indexRelationName,
+ &fInfo, NULL, accessMethodId,
+ numberOfAttributes, attributeNumberA,
+ classObjectId, parameterCount, parameterA, (Node *) cnfPred,
+ lossy, unique);
+ }
+ else
+ {
+ attributeNumberA =
+ (AttrNumber *) palloc(numberOfAttributes *
+ sizeof attributeNumberA[0]);
+
+ classObjectId =
+ (Oid *) palloc(numberOfAttributes * sizeof classObjectId[0]);
+
+ NormIndexAttrs(attributeList, attributeNumberA,
+ classObjectId, relationId);
+
+ index_create(heapRelationName, indexRelationName, NULL,
+ attributeList,
+ accessMethodId, numberOfAttributes, attributeNumberA,
+ classObjectId, parameterCount, parameterA, (Node *) cnfPred,
+ lossy, unique);
+ }
}
/*
* ExtendIndex --
- * Extends a partial index.
+ * Extends a partial index.
*
* Exceptions:
- * XXX
+ * XXX
*/
void
-ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
+ExtendIndex(char *indexRelationName, Expr * predicate, List * rangetable)
{
- Oid *classObjectId;
- Oid accessMethodId;
- Oid indexId, relationId;
- Oid indproc;
- int numberOfAttributes;
- AttrNumber *attributeNumberA;
- HeapTuple tuple;
- FuncIndexInfo fInfo;
- FuncIndexInfo *funcInfo = NULL;
- IndexTupleForm index;
- Node *oldPred = NULL;
- List *cnfPred = NULL;
- PredInfo *predInfo;
- Relation heapRelation;
- Relation indexRelation;
- int i;
-
- /*
- * compute index relation id and access method id
- */
- tuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(indexRelationName),
- 0,0,0);
- if (!HeapTupleIsValid(tuple)) {
- elog(WARN, "ExtendIndex: %s index not found",
- indexRelationName);
- }
- indexId = tuple->t_oid;
- accessMethodId = ((Form_pg_class) GETSTRUCT(tuple))->relam;
-
- /*
- * find pg_index tuple
- */
- tuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexId),
- 0,0,0);
- if (!HeapTupleIsValid(tuple)) {
- elog(WARN, "ExtendIndex: %s is not an index",
- indexRelationName);
- }
-
- /*
- * Extract info from the pg_index tuple
- */
- index = (IndexTupleForm)GETSTRUCT(tuple);
- Assert(index->indexrelid == indexId);
- relationId = index->indrelid;
- indproc = index->indproc;
-
- for (i=0; i<INDEX_MAX_KEYS; i++)
- if (index->indkey[i] == 0) break;
- numberOfAttributes = i;
-
- if (VARSIZE(&index->indpred) != 0) {
- char *predString;
-
- predString = fmgr(F_TEXTOUT, &index->indpred);
- oldPred = stringToNode(predString);
- pfree(predString);
- }
- if (oldPred == NULL)
- elog(WARN, "ExtendIndex: %s is not a partial index",
- indexRelationName);
-
- /*
- * Convert the extension predicate from parsetree form to plan
- * form, so it can be readily evaluated during index creation.
- * Note: "predicate" comes in as a list containing (1) the predicate
- * itself (a where_clause), and (2) a corresponding range table.
- */
- if (rangetable != NIL) {
- cnfPred = cnfify((Expr*)copyObject(predicate), true);
- fix_opids(cnfPred);
- CheckPredicate(cnfPred, rangetable, relationId);
- }
-
- /* make predInfo list to pass to index_build */
- predInfo = (PredInfo*)palloc(sizeof(PredInfo));
- predInfo->pred = (Node*)cnfPred;
- predInfo->oldPred = oldPred;
-
- attributeNumberA =
- (AttrNumber *)palloc(numberOfAttributes*
- sizeof attributeNumberA[0]);
- classObjectId =
- (Oid *)palloc(numberOfAttributes * sizeof classObjectId[0]);
-
-
- for (i=0; i<numberOfAttributes; i++) {
- attributeNumberA[i] = index->indkey[i];
- classObjectId[i] = index->indclass[i];
- }
-
- if (indproc != InvalidOid) {
- funcInfo = &fInfo;
-/* FIgetnArgs(funcInfo) = numberOfAttributes; */
- FIsetnArgs(funcInfo,numberOfAttributes);
-
- tuple = SearchSysCacheTuple(PROOID,
- ObjectIdGetDatum(indproc),
- 0,0,0);
+ Oid *classObjectId;
+ Oid accessMethodId;
+ Oid indexId,
+ relationId;
+ Oid indproc;
+ int numberOfAttributes;
+ AttrNumber *attributeNumberA;
+ HeapTuple tuple;
+ FuncIndexInfo fInfo;
+ FuncIndexInfo *funcInfo = NULL;
+ IndexTupleForm index;
+ Node *oldPred = NULL;
+ List *cnfPred = NULL;
+ PredInfo *predInfo;
+ Relation heapRelation;
+ Relation indexRelation;
+ int i;
+
+ /*
+ * compute index relation id and access method id
+ */
+ tuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(indexRelationName),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN, "ExtendIndex: %s index not found",
+ indexRelationName);
+ }
+ indexId = tuple->t_oid;
+ accessMethodId = ((Form_pg_class) GETSTRUCT(tuple))->relam;
+
+ /*
+ * find pg_index tuple
+ */
+ tuple = SearchSysCacheTuple(INDEXRELID,
+ ObjectIdGetDatum(indexId),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
- elog(WARN, "ExtendIndex: index procedure not found");
-
- namecpy(&(funcInfo->funcName),
- &(((Form_pg_proc) GETSTRUCT(tuple))->proname));
-
- FIsetProcOid(funcInfo,tuple->t_oid);
- }
-
- heapRelation = heap_open(relationId);
- indexRelation = index_open(indexId);
-
- RelationSetLockForWrite(heapRelation);
-
- InitIndexStrategy(numberOfAttributes, indexRelation, accessMethodId);
-
- index_build(heapRelation, indexRelation, numberOfAttributes,
- attributeNumberA, 0, NULL, funcInfo, predInfo);
+ {
+ elog(WARN, "ExtendIndex: %s is not an index",
+ indexRelationName);
+ }
+
+ /*
+ * Extract info from the pg_index tuple
+ */
+ index = (IndexTupleForm) GETSTRUCT(tuple);
+ Assert(index->indexrelid == indexId);
+ relationId = index->indrelid;
+ indproc = index->indproc;
+
+ for (i = 0; i < INDEX_MAX_KEYS; i++)
+ if (index->indkey[i] == 0)
+ break;
+ numberOfAttributes = i;
+
+ if (VARSIZE(&index->indpred) != 0)
+ {
+ char *predString;
+
+ predString = fmgr(F_TEXTOUT, &index->indpred);
+ oldPred = stringToNode(predString);
+ pfree(predString);
+ }
+ if (oldPred == NULL)
+ elog(WARN, "ExtendIndex: %s is not a partial index",
+ indexRelationName);
+
+ /*
+ * Convert the extension predicate from parsetree form to plan form,
+ * so it can be readily evaluated during index creation. Note:
+ * "predicate" comes in as a list containing (1) the predicate itself
+ * (a where_clause), and (2) a corresponding range table.
+ */
+ if (rangetable != NIL)
+ {
+ cnfPred = cnfify((Expr *) copyObject(predicate), true);
+ fix_opids(cnfPred);
+ CheckPredicate(cnfPred, rangetable, relationId);
+ }
+
+ /* make predInfo list to pass to index_build */
+ predInfo = (PredInfo *) palloc(sizeof(PredInfo));
+ predInfo->pred = (Node *) cnfPred;
+ predInfo->oldPred = oldPred;
+
+ attributeNumberA =
+ (AttrNumber *) palloc(numberOfAttributes *
+ sizeof attributeNumberA[0]);
+ classObjectId =
+ (Oid *) palloc(numberOfAttributes * sizeof classObjectId[0]);
+
+
+ for (i = 0; i < numberOfAttributes; i++)
+ {
+ attributeNumberA[i] = index->indkey[i];
+ classObjectId[i] = index->indclass[i];
+ }
+
+ if (indproc != InvalidOid)
+ {
+ funcInfo = &fInfo;
+/* FIgetnArgs(funcInfo) = numberOfAttributes; */
+ FIsetnArgs(funcInfo, numberOfAttributes);
+
+ tuple = SearchSysCacheTuple(PROOID,
+ ObjectIdGetDatum(indproc),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ elog(WARN, "ExtendIndex: index procedure not found");
+
+ namecpy(&(funcInfo->funcName),
+ &(((Form_pg_proc) GETSTRUCT(tuple))->proname));
+
+ FIsetProcOid(funcInfo, tuple->t_oid);
+ }
+
+ heapRelation = heap_open(relationId);
+ indexRelation = index_open(indexId);
+
+ RelationSetLockForWrite(heapRelation);
+
+ InitIndexStrategy(numberOfAttributes, indexRelation, accessMethodId);
+
+ index_build(heapRelation, indexRelation, numberOfAttributes,
+ attributeNumberA, 0, NULL, funcInfo, predInfo);
}
/*
* CheckPredicate
- * Checks that the given list of partial-index predicates refer
- * (via the given range table) only to the given base relation oid,
- * and that they're in a form the planner can handle, i.e.,
- * boolean combinations of "ATTR OP CONST" (yes, for now, the ATTR
- * has to be on the left).
+ * Checks that the given list of partial-index predicates refer
+ * (via the given range table) only to the given base relation oid,
+ * and that they're in a form the planner can handle, i.e.,
+ * boolean combinations of "ATTR OP CONST" (yes, for now, the ATTR
+ * has to be on the left).
*/
static void
-CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid)
+CheckPredicate(List * predList, List * rangeTable, Oid baseRelOid)
{
- List *item;
-
- foreach (item, predList) {
- CheckPredExpr(lfirst(item), rangeTable, baseRelOid);
- }
+ List *item;
+
+ foreach(item, predList)
+ {
+ CheckPredExpr(lfirst(item), rangeTable, baseRelOid);
+ }
}
static void
-CheckPredExpr(Node *predicate, List *rangeTable, Oid baseRelOid)
+CheckPredExpr(Node * predicate, List * rangeTable, Oid baseRelOid)
{
- List *clauses = NIL, *clause;
-
- if (is_opclause(predicate)) {
- CheckPredClause((Expr*)predicate, rangeTable, baseRelOid);
- return;
- } else if (or_clause(predicate))
- clauses = ((Expr*)predicate)->args;
- else if (and_clause(predicate))
- clauses = ((Expr*)predicate)->args;
- else
- elog(WARN, "Unsupported partial-index predicate expression type");
-
- foreach (clause, clauses) {
- CheckPredExpr(lfirst(clause), rangeTable, baseRelOid);
- }
+ List *clauses = NIL,
+ *clause;
+
+ if (is_opclause(predicate))
+ {
+ CheckPredClause((Expr *) predicate, rangeTable, baseRelOid);
+ return;
+ }
+ else if (or_clause(predicate))
+ clauses = ((Expr *) predicate)->args;
+ else if (and_clause(predicate))
+ clauses = ((Expr *) predicate)->args;
+ else
+ elog(WARN, "Unsupported partial-index predicate expression type");
+
+ foreach(clause, clauses)
+ {
+ CheckPredExpr(lfirst(clause), rangeTable, baseRelOid);
+ }
}
static void
-CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid)
+CheckPredClause(Expr * predicate, List * rangeTable, Oid baseRelOid)
{
- Var *pred_var;
- Const *pred_const;
-
- pred_var = (Var *)get_leftop(predicate);
- pred_const = (Const *)get_rightop(predicate);
-
- if (!IsA(predicate->oper,Oper) ||
- !IsA(pred_var,Var) ||
- !IsA(pred_const,Const)) {
- elog(WARN, "Unsupported partial-index predicate clause type");
- }
-
- if (getrelid(pred_var->varno, rangeTable) != baseRelOid)
- elog(WARN,
- "Partial-index predicates may refer only to the base relation");
+ Var *pred_var;
+ Const *pred_const;
+
+ pred_var = (Var *) get_leftop(predicate);
+ pred_const = (Const *) get_rightop(predicate);
+
+ if (!IsA(predicate->oper, Oper) ||
+ !IsA(pred_var, Var) ||
+ !IsA(pred_const, Const))
+ {
+ elog(WARN, "Unsupported partial-index predicate clause type");
+ }
+
+ if (getrelid(pred_var->varno, rangeTable) != baseRelOid)
+ elog(WARN,
+ "Partial-index predicates may refer only to the base relation");
}
-static void
-FuncIndexArgs(IndexElem *funcIndex,
- AttrNumber *attNumP,
- Oid *argTypes,
- Oid *opOidP,
- Oid relId)
+static void
+FuncIndexArgs(IndexElem * funcIndex,
+ AttrNumber * attNumP,
+ Oid * argTypes,
+ Oid * opOidP,
+ Oid relId)
{
- List *rest;
- HeapTuple tuple;
- AttributeTupleForm att;
-
- tuple = SearchSysCacheTuple(CLANAME,
- PointerGetDatum(funcIndex->class),
- 0,0,0);
-
- if (!HeapTupleIsValid(tuple))
+ List *rest;
+ HeapTuple tuple;
+ AttributeTupleForm att;
+
+ tuple = SearchSysCacheTuple(CLANAME,
+ PointerGetDatum(funcIndex->class),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tuple))
{
- elog(WARN, "DefineIndex: %s class not found",
- funcIndex->class);
+ elog(WARN, "DefineIndex: %s class not found",
+ funcIndex->class);
}
- *opOidP = tuple->t_oid;
-
- memset(argTypes, 0, 8 * sizeof(Oid));
-
- /*
- * process the function arguments
- */
- for (rest=funcIndex->args; rest != NIL; rest = lnext(rest)) {
- char *arg;
-
- arg = strVal(lfirst(rest));
-
- tuple = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(relId),
- PointerGetDatum(arg),0,0);
-
- if (!HeapTupleIsValid(tuple)) {
- elog(WARN,
- "DefineIndex: attribute \"%s\" not found",
- arg);
+ *opOidP = tuple->t_oid;
+
+ memset(argTypes, 0, 8 * sizeof(Oid));
+
+ /*
+ * process the function arguments
+ */
+ for (rest = funcIndex->args; rest != NIL; rest = lnext(rest))
+ {
+ char *arg;
+
+ arg = strVal(lfirst(rest));
+
+ tuple = SearchSysCacheTuple(ATTNAME,
+ ObjectIdGetDatum(relId),
+ PointerGetDatum(arg), 0, 0);
+
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN,
+ "DefineIndex: attribute \"%s\" not found",
+ arg);
+ }
+ att = (AttributeTupleForm) GETSTRUCT(tuple);
+ *attNumP++ = att->attnum;
+ *argTypes++ = att->atttypid;
}
- att = (AttributeTupleForm)GETSTRUCT(tuple);
- *attNumP++ = att->attnum;
- *argTypes++ = att->atttypid;
- }
}
-static void
-NormIndexAttrs(List *attList, /* list of IndexElem's */
- AttrNumber *attNumP,
- Oid *opOidP,
- Oid relId)
+static void
+NormIndexAttrs(List * attList, /* list of IndexElem's */
+ AttrNumber * attNumP,
+ Oid * opOidP,
+ Oid relId)
{
- List *rest;
- HeapTuple tuple;
-
- /*
- * process attributeList
- */
-
- for (rest=attList; rest != NIL; rest = lnext(rest)) {
- IndexElem *attribute;
- AttributeTupleForm attform;
-
- attribute = lfirst(rest);
-
- if (attribute->name == NULL)
- elog(WARN, "missing attribute for define index");
-
- tuple = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(relId),
- PointerGetDatum(attribute->name),
- 0,0);
- if (!HeapTupleIsValid(tuple)) {
- elog(WARN,
- "DefineIndex: attribute \"%s\" not found",
- attribute->name);
- }
+ List *rest;
+ HeapTuple tuple;
- attform = (AttributeTupleForm)GETSTRUCT(tuple);
- *attNumP++ = attform->attnum;
-
- if (attribute->class == NULL) {
- /* no operator class specified, so find the default */
- attribute->class = GetDefaultOpClass(attform->atttypid);
- if(attribute->class == NULL) {
- elog(WARN,
- "Can't find a default operator class for type %d.",
- attform->atttypid);
- }
- }
-
- tuple = SearchSysCacheTuple(CLANAME,
- PointerGetDatum(attribute->class),
- 0,0,0);
-
- if (!HeapTupleIsValid(tuple)) {
- elog(WARN, "DefineIndex: %s class not found",
- attribute->class);
+ /*
+ * process attributeList
+ */
+
+ for (rest = attList; rest != NIL; rest = lnext(rest))
+ {
+ IndexElem *attribute;
+ AttributeTupleForm attform;
+
+ attribute = lfirst(rest);
+
+ if (attribute->name == NULL)
+ elog(WARN, "missing attribute for define index");
+
+ tuple = SearchSysCacheTuple(ATTNAME,
+ ObjectIdGetDatum(relId),
+ PointerGetDatum(attribute->name),
+ 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN,
+ "DefineIndex: attribute \"%s\" not found",
+ attribute->name);
+ }
+
+ attform = (AttributeTupleForm) GETSTRUCT(tuple);
+ *attNumP++ = attform->attnum;
+
+ if (attribute->class == NULL)
+ {
+ /* no operator class specified, so find the default */
+ attribute->class = GetDefaultOpClass(attform->atttypid);
+ if (attribute->class == NULL)
+ {
+ elog(WARN,
+ "Can't find a default operator class for type %d.",
+ attform->atttypid);
+ }
+ }
+
+ tuple = SearchSysCacheTuple(CLANAME,
+ PointerGetDatum(attribute->class),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN, "DefineIndex: %s class not found",
+ attribute->class);
+ }
+ *opOidP++ = tuple->t_oid;
}
- *opOidP++ = tuple->t_oid;
- }
}
-static char *
+static char *
GetDefaultOpClass(Oid atttypid)
{
- HeapTuple tuple;
+ HeapTuple tuple;
- tuple = SearchSysCacheTuple(CLADEFTYPE,
- ObjectIdGetDatum(atttypid),
- 0, 0, 0);
- if(!HeapTupleIsValid(tuple)) {
- return 0;
- }
+ tuple = SearchSysCacheTuple(CLADEFTYPE,
+ ObjectIdGetDatum(atttypid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ {
+ return 0;
+ }
- return nameout(&(((Form_pg_opclass)GETSTRUCT(tuple))->opcname));
+ return nameout(&(((Form_pg_opclass) GETSTRUCT(tuple))->opcname));
}
/*
* RemoveIndex --
- * Deletes an index.
+ * Deletes an index.
*
* Exceptions:
- * BadArg if name is invalid.
- * "WARN" if index nonexistent.
- * ...
+ * BadArg if name is invalid.
+ * "WARN" if index nonexistent.
+ * ...
*/
void
RemoveIndex(char *name)
{
- HeapTuple tuple;
-
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(name),
- 0,0,0);
-
- if (!HeapTupleIsValid(tuple)) {
- elog(WARN, "index \"%s\" nonexistent", name);
- }
-
- if (((Form_pg_class)GETSTRUCT(tuple))->relkind != RELKIND_INDEX) {
- elog(WARN, "relation \"%s\" is of type \"%c\"",
- name,
- ((Form_pg_class)GETSTRUCT(tuple))->relkind);
- }
-
- index_destroy(tuple->t_oid);
+ HeapTuple tuple;
+
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(name),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN, "index \"%s\" nonexistent", name);
+ }
+
+ if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
+ {
+ elog(WARN, "relation \"%s\" is of type \"%c\"",
+ name,
+ ((Form_pg_class) GETSTRUCT(tuple))->relkind);
+ }
+
+ index_destroy(tuple->t_oid);
}
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index 800d85a48b8..fb1df213cec 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -2,33 +2,33 @@
*
* define.c--
*
- * These routines execute some of the CREATE statements. In an earlier
- * version of Postgres, these were "define" statements.
+ * These routines execute some of the CREATE statements. In an earlier
+ * version of Postgres, these were "define" statements.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.13 1997/08/12 22:52:23 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.14 1997/09/07 04:40:46 momjian Exp $
*
* DESCRIPTION
- * The "DefineFoo" routines take the parse tree and pick out the
- * appropriate arguments/flags, passing the results to the
- * corresponding "FooDefine" routines (in src/catalog) that do
- * the actual catalog-munging. These routines also verify permission
- * of the user to execute the command.
+ * The "DefineFoo" routines take the parse tree and pick out the
+ * appropriate arguments/flags, passing the results to the
+ * corresponding "FooDefine" routines (in src/catalog) that do
+ * the actual catalog-munging. These routines also verify permission
+ * of the user to execute the command.
*
* NOTES
- * These things must be defined and committed in the following order:
- * "create function":
- * input/output, recv/send procedures
- * "create type":
- * type
- * "create operator":
- * operators
+ * These things must be defined and committed in the following order:
+ * "create function":
+ * input/output, recv/send procedures
+ * "create type":
+ * type
+ * "create operator":
+ * operators
*
- * Most of the parse-tree manipulation routines are defined in
- * commands/manip.c.
+ * Most of the parse-tree manipulation routines are defined in
+ * commands/manip.c.
*
*-------------------------------------------------------------------------
*/
@@ -46,209 +46,259 @@
#include <catalog/pg_proc.h>
#include <catalog/pg_type.h>
#include <utils/syscache.h>
-#include <fmgr.h> /* for fmgr */
-#include <utils/builtins.h> /* prototype for textin() */
+#include <fmgr.h> /* for fmgr */
+#include <utils/builtins.h> /* prototype for textin() */
#include <commands/defrem.h>
#include <optimizer/xfunc.h>
#include <tcop/dest.h>
#include <catalog/pg_user.h>
-static char *defGetString(DefElem *def);
-static int defGetTypeLength(DefElem *def);
+static char *defGetString(DefElem * def);
+static int defGetTypeLength(DefElem * def);
-#define DEFAULT_TYPDELIM ','
+#define DEFAULT_TYPDELIM ','
static void
-case_translate_language_name(const char *input, char *output) {
+case_translate_language_name(const char *input, char *output)
+{
/*-------------------------------------------------------------------------
Translate the input language name to lower case, except if it's C,
- translate to upper case.
+ translate to upper case.
--------------------------------------------------------------------------*/
- int i;
+ int i;
- for (i = 0; i < NAMEDATALEN && input[i] != '\0'; ++i)
- output[i] = tolower(input[i]);
+ for (i = 0; i < NAMEDATALEN && input[i] != '\0'; ++i)
+ output[i] = tolower(input[i]);
- output[i] = '\0';
+ output[i] = '\0';
- if (strcmp(output, "c") == 0) output[0] = 'C';
-}
+ if (strcmp(output, "c") == 0)
+ output[0] = 'C';
+}
static void
-compute_return_type(const Node *returnType,
- char **prorettype_p, bool *returnsSet_p) {
+compute_return_type(const Node * returnType,
+ char **prorettype_p, bool * returnsSet_p)
+{
/*---------------------------------------------------------------------------
- Examine the "returns" clause returnType of the CREATE FUNCTION statement
+ Examine the "returns" clause returnType of the CREATE FUNCTION statement
and return information about it as **prorettype_p and **returnsSet.
----------------------------------------------------------------------------*/
- if (nodeTag(returnType) == T_TypeName) {
- /* a set of values */
- TypeName *setType = (TypeName *)returnType;
- *prorettype_p = setType->name;
- *returnsSet_p = true;
- }else {
- /* singleton */
- *prorettype_p = strVal(returnType);
- *returnsSet_p = false;
- }
+ if (nodeTag(returnType) == T_TypeName)
+ {
+ /* a set of values */
+ TypeName *setType = (TypeName *) returnType;
+
+ *prorettype_p = setType->name;
+ *returnsSet_p = true;
+ }
+ else
+ {
+ /* singleton */
+ *prorettype_p = strVal(returnType);
+ *returnsSet_p = false;
+ }
}
-
-static void
-compute_full_attributes(const List *parameters, int32 *byte_pct_p,
- int32 *perbyte_cpu_p, int32 *percall_cpu_p,
- int32 *outin_ratio_p, bool *canCache_p) {
+
+static void
+compute_full_attributes(const List * parameters, int32 * byte_pct_p,
+ int32 * perbyte_cpu_p, int32 * percall_cpu_p,
+ int32 * outin_ratio_p, bool * canCache_p)
+{
/*--------------------------------------------------------------------------
Interpret the parameters *parameters and return their contents as
*byte_pct_p, etc.
These are the full parameters of a C or internal function.
---------------------------------------------------------------------------*/
- List *pl;
-
- /* the defaults */
- *byte_pct_p = BYTE_PCT;
- *perbyte_cpu_p = PERBYTE_CPU;
- *percall_cpu_p = PERCALL_CPU;
- *outin_ratio_p = OUTIN_RATIO;
-
- foreach(pl, (List *)parameters) {
- ParamString *param = (ParamString*)lfirst(pl);
-
- if (strcasecmp(param->name, "iscachable") == 0) {
- *canCache_p = true;
- } else if (strcasecmp(param->name, "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
- */
- elog(WARN, "untrusted function has been decommissioned.");
- } else if (strcasecmp(param->name, "byte_pct") == 0) {
- /*
- ** handle expensive function parameters
- */
- *byte_pct_p = atoi(param->val);
- } else if (strcasecmp(param->name, "perbyte_cpu") == 0) {
- if (sscanf(param->val, "%d", perbyte_cpu_p) == 0) {
- int count;
- char *ptr;
- for (count = 0, ptr = param->val; *ptr != '\0'; ptr++)
- if (*ptr == '!') count++;
- *perbyte_cpu_p = (int) pow(10.0, (double) count);
- }
- } else if (strcasecmp(param->name, "percall_cpu") == 0) {
- if (sscanf(param->val, "%d", percall_cpu_p) == 0) {
- int count;
- char *ptr;
- for (count = 0, ptr = param->val; *ptr != '\0'; ptr++)
- if (*ptr == '!') count++;
- *percall_cpu_p = (int) pow(10.0, (double) count);
- }
- } else if (strcasecmp(param->name, "outin_ratio") == 0) {
- *outin_ratio_p = atoi(param->val);
- }
- }
+ List *pl;
+
+ /* the defaults */
+ *byte_pct_p = BYTE_PCT;
+ *perbyte_cpu_p = PERBYTE_CPU;
+ *percall_cpu_p = PERCALL_CPU;
+ *outin_ratio_p = OUTIN_RATIO;
+
+ foreach(pl, (List *) parameters)
+ {
+ ParamString *param = (ParamString *) lfirst(pl);
+
+ if (strcasecmp(param->name, "iscachable") == 0)
+ {
+ *canCache_p = true;
+ }
+ else if (strcasecmp(param->name, "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
+ */
+ elog(WARN, "untrusted function has been decommissioned.");
+ }
+ else if (strcasecmp(param->name, "byte_pct") == 0)
+ {
+
+ /*
+ * * handle expensive function parameters
+ */
+ *byte_pct_p = atoi(param->val);
+ }
+ else if (strcasecmp(param->name, "perbyte_cpu") == 0)
+ {
+ if (sscanf(param->val, "%d", perbyte_cpu_p) == 0)
+ {
+ int count;
+ char *ptr;
+
+ for (count = 0, ptr = param->val; *ptr != '\0'; ptr++)
+ if (*ptr == '!')
+ count++;
+ *perbyte_cpu_p = (int) pow(10.0, (double) count);
+ }
+ }
+ else if (strcasecmp(param->name, "percall_cpu") == 0)
+ {
+ if (sscanf(param->val, "%d", percall_cpu_p) == 0)
+ {
+ int count;
+ char *ptr;
+
+ for (count = 0, ptr = param->val; *ptr != '\0'; ptr++)
+ if (*ptr == '!')
+ count++;
+ *percall_cpu_p = (int) pow(10.0, (double) count);
+ }
+ }
+ else if (strcasecmp(param->name, "outin_ratio") == 0)
+ {
+ *outin_ratio_p = atoi(param->val);
+ }
+ }
}
static void
interpret_AS_clause(const char languageName[], const char as[],
- char **prosrc_str_p, char **probin_str_p) {
-
- if ( strcmp(languageName, "C") == 0 ||
- strcmp(languageName, "internal") == 0 ) {
- *prosrc_str_p = "-";
- *probin_str_p = (char *)as;
- } else {
- *prosrc_str_p = (char *)as;
- *probin_str_p = "-";
- }
+ char **prosrc_str_p, char **probin_str_p)
+{
+
+ if (strcmp(languageName, "C") == 0 ||
+ strcmp(languageName, "internal") == 0)
+ {
+ *prosrc_str_p = "-";
+ *probin_str_p = (char *) as;
+ }
+ else
+ {
+ *prosrc_str_p = (char *) as;
+ *probin_str_p = "-";
+ }
}
/*
* CreateFunction --
- * Execute a CREATE FUNCTION utility statement.
+ * Execute a CREATE FUNCTION utility statement.
*
*/
void
-CreateFunction(ProcedureStmt *stmt, CommandDest dest)
+CreateFunction(ProcedureStmt * stmt, CommandDest dest)
{
- char *probin_str;
- /* pathname of executable file that executes this function, if any */
- char *prosrc_str;
- /* SQL that executes this function, if any */
- char *prorettype;
- /* Type of return value (or member of set of values) from function */
- char languageName[NAMEDATALEN];
- /* name of language of function, with case adjusted:
- "C", "internal", or "SQL"
- */
- /* The following are attributes of the function, as expressed in the
- CREATE FUNCTION statement, where applicable.
- */
- int32 byte_pct, perbyte_cpu, percall_cpu, outin_ratio;
- bool canCache;
- bool returnsSet;
- /* The function returns a set of values, as opposed to a singleton. */
-
-
- case_translate_language_name(stmt->language, languageName);
-
- compute_return_type(stmt->returnType, &prorettype, &returnsSet);
-
- if ( strcmp(languageName, "C") == 0 ||
- strcmp(languageName, "internal") == 0 ) {
- compute_full_attributes(stmt->withClause,
- &byte_pct, &perbyte_cpu, &percall_cpu,
- &outin_ratio, &canCache);
- } else if (strcmp(languageName, "sql") == 0) {
- /* query optimizer groks sql, these are meaningless */
- perbyte_cpu = percall_cpu = 0;
- byte_pct = outin_ratio = 100;
- canCache = false;
- } else {
- elog(WARN,
- "Unrecognized language specified in a CREATE FUNCTION: "
- "'%s'. Recognized languages are sql, C, and internal.",
- languageName);
- }
-
- interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str);
-
- if (strcmp(languageName, "sql") != 0 && !superuser())
- elog(WARN,
- "Only users with Postgres superuser privilege are permitted "
- "to create a function "
- "in the '%s' language. Others may use the 'sql' language.",
- languageName);
- /* Above does not return. */
- else {
- /* 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 */
- canCache,
- true, /* (obsolete "trusted") */
- byte_pct,
- perbyte_cpu,
- percall_cpu,
- outin_ratio,
- stmt->defArgs,
- dest);
- }
+ char *probin_str;
+
+ /* pathname of executable file that executes this function, if any */
+ char *prosrc_str;
+
+ /* SQL that executes this function, if any */
+ char *prorettype;
+
+ /* Type of return value (or member of set of values) from function */
+ char languageName[NAMEDATALEN];
+
+ /*
+ * name of language of function, with case adjusted: "C", "internal",
+ * or "SQL"
+ */
+
+ /*
+ * The following are attributes of the function, as expressed in the
+ * CREATE FUNCTION statement, where applicable.
+ */
+ int32 byte_pct,
+ perbyte_cpu,
+ percall_cpu,
+ outin_ratio;
+ bool canCache;
+ bool returnsSet;
+
+ /* The function returns a set of values, as opposed to a singleton. */
+
+
+ case_translate_language_name(stmt->language, languageName);
+
+ compute_return_type(stmt->returnType, &prorettype, &returnsSet);
+
+ if (strcmp(languageName, "C") == 0 ||
+ strcmp(languageName, "internal") == 0)
+ {
+ compute_full_attributes(stmt->withClause,
+ &byte_pct, &perbyte_cpu, &percall_cpu,
+ &outin_ratio, &canCache);
+ }
+ else if (strcmp(languageName, "sql") == 0)
+ {
+ /* query optimizer groks sql, these are meaningless */
+ perbyte_cpu = percall_cpu = 0;
+ byte_pct = outin_ratio = 100;
+ canCache = false;
+ }
+ else
+ {
+ elog(WARN,
+ "Unrecognized language specified in a CREATE FUNCTION: "
+ "'%s'. Recognized languages are sql, C, and internal.",
+ languageName);
+ }
+
+ interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str);
+
+ if (strcmp(languageName, "sql") != 0 && !superuser())
+ elog(WARN,
+ "Only users with Postgres superuser privilege are permitted "
+ "to create a function "
+ "in the '%s' language. Others may use the 'sql' language.",
+ languageName);
+ /* Above does not return. */
+ else
+ {
+
+ /*
+ * 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 */
+ canCache,
+ true, /* (obsolete "trusted") */
+ byte_pct,
+ perbyte_cpu,
+ percall_cpu,
+ outin_ratio,
+ stmt->defArgs,
+ dest);
+ }
}
@@ -256,344 +306,437 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
/* --------------------------------
* DefineOperator--
*
- * this function extracts all the information from the
- * parameter list generated by the parser and then has
- * OperatorCreate() do all the actual work.
+ * this function extracts all the information from the
+ * parameter list generated by the parser and then has
+ * OperatorCreate() do all the actual work.
*
* 'parameters' is a list of DefElem
* --------------------------------
*/
void
-DefineOperator(char *oprName,
- List *parameters)
+DefineOperator(char *oprName,
+ List * parameters)
{
- uint16 precedence=0; /* operator precedence */
- bool canHash=false; /* operator hashes */
- bool isLeftAssociative=true; /* operator is left associative */
- char *functionName=NULL; /* function for operator */
- char *typeName1=NULL; /* first type name */
- char *typeName2=NULL; /* second type name */
- char *commutatorName=NULL; /* optional commutator operator name */
- char *negatorName=NULL; /* optional negator operator name */
- char *restrictionName=NULL; /* optional restrict. sel. procedure */
- char *joinName=NULL; /* optional join sel. procedure name */
- char *sortName1=NULL; /* optional first sort operator */
- char *sortName2=NULL; /* optional second sort operator */
- List *pl;
-
- /*
- * loop over the definition list and extract the information we need.
- */
- foreach (pl, parameters) {
- DefElem *defel = (DefElem *)lfirst(pl);
-
- if (!strcasecmp(defel->defname, "leftarg")) {
- /* see gram.y, must be setof */
- if (nodeTag(defel->arg)==T_TypeName)
- elog(WARN, "setof type not implemented for leftarg");
-
- if (nodeTag(defel->arg)==T_String) {
- typeName1 = defGetString(defel);
- }else {
- elog(WARN, "type for leftarg is malformed.");
- }
- } else if (!strcasecmp(defel->defname, "rightarg")) {
- /* see gram.y, must be setof */
- if (nodeTag(defel->arg)==T_TypeName)
- elog(WARN, "setof type not implemented for rightarg");
-
- if (nodeTag(defel->arg)==T_String) {
- typeName2 = defGetString(defel);
- }else {
- elog(WARN, "type for rightarg is malformed.");
- }
- } else if (!strcasecmp(defel->defname, "procedure")) {
- functionName = defGetString(defel);
- } else if (!strcasecmp(defel->defname, "precedence")) {
- /* NOT IMPLEMENTED (never worked in v4.2) */
- elog(NOTICE, "CREATE OPERATOR: precedence not implemented");
- } else if (!strcasecmp(defel->defname, "associativity")) {
- /* NOT IMPLEMENTED (never worked in v4.2) */
- elog(NOTICE, "CREATE OPERATOR: associativity not implemented");
- } else if (!strcasecmp(defel->defname, "commutator")) {
- commutatorName = defGetString(defel);
- } else if (!strcasecmp(defel->defname, "negator")) {
- negatorName = defGetString(defel);
- } else if (!strcasecmp(defel->defname, "restrict")) {
- restrictionName = defGetString(defel);
- } else if (!strcasecmp(defel->defname, "join")) {
- joinName = defGetString(defel);
- } else if (!strcasecmp(defel->defname, "hashes")) {
- canHash = TRUE;
- } else if (!strcasecmp(defel->defname, "sort1")) {
- /* ----------------
- * XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... )
- * XXX is undocumented in the reference manual source as of
- * 89/8/22.
- * ----------------
- */
- sortName1 = defGetString(defel);
- } else if (!strcasecmp(defel->defname, "sort2")) {
- sortName2 = defGetString(defel);
- } else {
- elog(NOTICE, "DefineOperator: attribute \"%s\" not recognized",
- defel->defname);
- }
- }
-
- /*
- * make sure we have our required definitions
- */
- if (functionName==NULL) {
- elog(WARN, "Define: \"procedure\" unspecified");
- }
-
- /* ----------------
- * now have OperatorCreate do all the work..
- * ----------------
- */
- OperatorCreate(oprName, /* operator name */
- typeName1, /* first type name */
- typeName2, /* second type name */
- functionName, /* function for operator */
- precedence, /* operator precedence */
- isLeftAssociative, /* operator is left associative */
- commutatorName, /* optional commutator operator name */
- negatorName, /* optional negator operator name */
- restrictionName, /* optional restrict. sel. procedure */
- joinName, /* optional join sel. procedure name */
- canHash, /* operator hashes */
- sortName1, /* optional first sort operator */
- sortName2); /* optional second sort operator */
-
+ uint16 precedence = 0; /* operator precedence */
+ bool canHash = false; /* operator hashes */
+ bool isLeftAssociative = true; /* operator is left
+ * associative */
+ char *functionName = NULL; /* function for operator */
+ char *typeName1 = NULL; /* first type name */
+ char *typeName2 = NULL; /* second type name */
+ char *commutatorName = NULL; /* optional commutator
+ * operator name */
+ char *negatorName = NULL; /* optional negator operator name */
+ char *restrictionName = NULL; /* optional restrict. sel.
+ * procedure */
+ char *joinName = NULL; /* optional join sel. procedure
+ * name */
+ char *sortName1 = NULL; /* optional first sort operator */
+ char *sortName2 = NULL; /* optional second sort operator */
+ List *pl;
+
+ /*
+ * loop over the definition list and extract the information we need.
+ */
+ foreach(pl, parameters)
+ {
+ DefElem *defel = (DefElem *) lfirst(pl);
+
+ if (!strcasecmp(defel->defname, "leftarg"))
+ {
+ /* see gram.y, must be setof */
+ if (nodeTag(defel->arg) == T_TypeName)
+ elog(WARN, "setof type not implemented for leftarg");
+
+ if (nodeTag(defel->arg) == T_String)
+ {
+ typeName1 = defGetString(defel);
+ }
+ else
+ {
+ elog(WARN, "type for leftarg is malformed.");
+ }
+ }
+ else if (!strcasecmp(defel->defname, "rightarg"))
+ {
+ /* see gram.y, must be setof */
+ if (nodeTag(defel->arg) == T_TypeName)
+ elog(WARN, "setof type not implemented for rightarg");
+
+ if (nodeTag(defel->arg) == T_String)
+ {
+ typeName2 = defGetString(defel);
+ }
+ else
+ {
+ elog(WARN, "type for rightarg is malformed.");
+ }
+ }
+ else if (!strcasecmp(defel->defname, "procedure"))
+ {
+ functionName = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "precedence"))
+ {
+ /* NOT IMPLEMENTED (never worked in v4.2) */
+ elog(NOTICE, "CREATE OPERATOR: precedence not implemented");
+ }
+ else if (!strcasecmp(defel->defname, "associativity"))
+ {
+ /* NOT IMPLEMENTED (never worked in v4.2) */
+ elog(NOTICE, "CREATE OPERATOR: associativity not implemented");
+ }
+ else if (!strcasecmp(defel->defname, "commutator"))
+ {
+ commutatorName = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "negator"))
+ {
+ negatorName = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "restrict"))
+ {
+ restrictionName = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "join"))
+ {
+ joinName = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "hashes"))
+ {
+ canHash = TRUE;
+ }
+ else if (!strcasecmp(defel->defname, "sort1"))
+ {
+ /* ----------------
+ * XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... )
+ * XXX is undocumented in the reference manual source as of
+ * 89/8/22.
+ * ----------------
+ */
+ sortName1 = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "sort2"))
+ {
+ sortName2 = defGetString(defel);
+ }
+ else
+ {
+ elog(NOTICE, "DefineOperator: attribute \"%s\" not recognized",
+ defel->defname);
+ }
+ }
+
+ /*
+ * make sure we have our required definitions
+ */
+ if (functionName == NULL)
+ {
+ elog(WARN, "Define: \"procedure\" unspecified");
+ }
+
+ /* ----------------
+ * now have OperatorCreate do all the work..
+ * ----------------
+ */
+ OperatorCreate(oprName, /* operator name */
+ typeName1, /* first type name */
+ typeName2, /* second type name */
+ functionName,/* function for operator */
+ precedence, /* operator precedence */
+ isLeftAssociative, /* operator is left associative */
+ commutatorName, /* optional commutator operator
+ * name */
+ negatorName, /* optional negator operator name */
+ restrictionName, /* optional restrict. sel.
+ * procedure */
+ joinName, /* optional join sel. procedure name */
+ canHash, /* operator hashes */
+ sortName1, /* optional first sort operator */
+ sortName2); /* optional second sort operator */
+
}
/* -------------------
- * DefineAggregate
+ * DefineAggregate
* ------------------
*/
void
-DefineAggregate(char *aggName, List *parameters)
+DefineAggregate(char *aggName, List * parameters)
{
- char *stepfunc1Name = NULL;
- char *stepfunc2Name = NULL;
- char *finalfuncName = NULL;
- char *baseType = NULL;
- char *stepfunc1Type = NULL;
- char *stepfunc2Type = NULL;
- char *init1 = NULL;
- char *init2 = NULL;
- List *pl;
-
- foreach (pl, parameters) {
- DefElem *defel = (DefElem *)lfirst(pl);
-
- /*
- * sfunc1
- */
- if (!strcasecmp(defel->defname, "sfunc1")) {
- stepfunc1Name = defGetString(defel);
- } else if (!strcasecmp(defel->defname, "basetype")) {
- baseType = defGetString(defel);
- } else if (!strcasecmp(defel->defname, "stype1")) {
- stepfunc1Type = defGetString(defel);
-
- /*
- * sfunc2
- */
- } else if (!strcasecmp(defel->defname, "sfunc2")) {
- stepfunc2Name = defGetString(defel);
- } else if (!strcasecmp(defel->defname, "stype2")) {
- stepfunc2Type = defGetString(defel);
- /*
- * final
- */
- } else if (!strcasecmp(defel->defname, "finalfunc")) {
- finalfuncName = defGetString(defel);
- /*
- * initial conditions
- */
- } else if (!strcasecmp(defel->defname, "initcond1")) {
- init1 = defGetString(defel);
- } else if (!strcasecmp(defel->defname, "initcond2")) {
- init2 = defGetString(defel);
- } else {
- elog(NOTICE, "DefineAggregate: attribute \"%s\" not recognized",
- defel->defname);
- }
- }
-
- /*
- * make sure we have our required definitions
- */
- if (baseType==NULL)
- elog(WARN, "Define: \"basetype\" unspecified");
- if (stepfunc1Name!=NULL) {
- if (stepfunc1Type==NULL)
- elog(WARN, "Define: \"stype1\" unspecified");
- }
- if (stepfunc2Name!=NULL) {
- if (stepfunc2Type==NULL)
- elog(WARN, "Define: \"stype2\" unspecified");
- }
-
- /*
- * Most of the argument-checking is done inside of AggregateCreate
- */
- AggregateCreate(aggName, /* aggregate name */
- stepfunc1Name, /* first step function name */
- stepfunc2Name, /* second step function name */
- finalfuncName, /* final function name */
- baseType, /* type of object being aggregated */
- stepfunc1Type, /* return type of first function */
- stepfunc2Type, /* return type of second function */
- init1, /* first initial condition */
- init2); /* second initial condition */
-
- /* XXX free palloc'd memory */
+ char *stepfunc1Name = NULL;
+ char *stepfunc2Name = NULL;
+ char *finalfuncName = NULL;
+ char *baseType = NULL;
+ char *stepfunc1Type = NULL;
+ char *stepfunc2Type = NULL;
+ char *init1 = NULL;
+ char *init2 = NULL;
+ List *pl;
+
+ foreach(pl, parameters)
+ {
+ DefElem *defel = (DefElem *) lfirst(pl);
+
+ /*
+ * sfunc1
+ */
+ if (!strcasecmp(defel->defname, "sfunc1"))
+ {
+ stepfunc1Name = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "basetype"))
+ {
+ baseType = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "stype1"))
+ {
+ stepfunc1Type = defGetString(defel);
+
+ /*
+ * sfunc2
+ */
+ }
+ else if (!strcasecmp(defel->defname, "sfunc2"))
+ {
+ stepfunc2Name = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "stype2"))
+ {
+ stepfunc2Type = defGetString(defel);
+
+ /*
+ * final
+ */
+ }
+ else if (!strcasecmp(defel->defname, "finalfunc"))
+ {
+ finalfuncName = defGetString(defel);
+
+ /*
+ * initial conditions
+ */
+ }
+ else if (!strcasecmp(defel->defname, "initcond1"))
+ {
+ init1 = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "initcond2"))
+ {
+ init2 = defGetString(defel);
+ }
+ else
+ {
+ elog(NOTICE, "DefineAggregate: attribute \"%s\" not recognized",
+ defel->defname);
+ }
+ }
+
+ /*
+ * make sure we have our required definitions
+ */
+ if (baseType == NULL)
+ elog(WARN, "Define: \"basetype\" unspecified");
+ if (stepfunc1Name != NULL)
+ {
+ if (stepfunc1Type == NULL)
+ elog(WARN, "Define: \"stype1\" unspecified");
+ }
+ if (stepfunc2Name != NULL)
+ {
+ if (stepfunc2Type == NULL)
+ elog(WARN, "Define: \"stype2\" unspecified");
+ }
+
+ /*
+ * Most of the argument-checking is done inside of AggregateCreate
+ */
+ AggregateCreate(aggName, /* aggregate name */
+ stepfunc1Name, /* first step function name */
+ stepfunc2Name, /* second step function name */
+ finalfuncName, /* final function name */
+ baseType, /* type of object being aggregated */
+ stepfunc1Type, /* return type of first function */
+ stepfunc2Type, /* return type of second function */
+ init1, /* first initial condition */
+ init2); /* second initial condition */
+
+ /* XXX free palloc'd memory */
}
/*
* DefineType --
- * Registers a new type.
+ * Registers a new type.
*
*/
void
-DefineType(char *typeName, List *parameters)
+DefineType(char *typeName, List * parameters)
{
- int16 internalLength= 0; /* int2 */
- int16 externalLength= 0; /* int2 */
- char *elemName = NULL;
- char *inputName = NULL;
- char *outputName = NULL;
- char *sendName = NULL;
- char *receiveName = NULL;
- char *defaultValue = NULL; /* Datum */
- bool byValue = false;
- char delimiter = DEFAULT_TYPDELIM;
- char *shadow_type;
- List *pl;
- char alignment = 'i'; /* default alignment */
-
- /*
- * Type names can only be 15 characters long, so that the shadow type
- * can be created using the 16th character as necessary.
- */
- if (strlen(typeName) >= (NAMEDATALEN - 1)) {
- elog(WARN, "DefineType: type names must be %d characters or less",
- NAMEDATALEN - 1);
- }
-
- foreach(pl, parameters) {
- DefElem *defel = (DefElem*)lfirst(pl);
-
- if (!strcasecmp(defel->defname, "internallength")) {
- internalLength = defGetTypeLength(defel);
- }else if (!strcasecmp(defel->defname, "externallength")) {
- externalLength = defGetTypeLength(defel);
- }else if (!strcasecmp(defel->defname, "input")) {
- inputName = defGetString(defel);
- }else if (!strcasecmp(defel->defname, "output")) {
- outputName = defGetString(defel);
- }else if (!strcasecmp(defel->defname, "send")) {
- sendName = defGetString(defel);
- }else if (!strcasecmp(defel->defname, "delimiter")) {
- char *p = defGetString(defel);
- delimiter = p[0];
- }else if (!strcasecmp(defel->defname, "receive")) {
- receiveName = defGetString(defel);
- }else if (!strcasecmp(defel->defname, "element")) {
- elemName = defGetString(defel);
- }else if (!strcasecmp(defel->defname, "default")) {
- defaultValue = defGetString(defel);
- }else if (!strcasecmp(defel->defname, "passedbyvalue")) {
- byValue = true;
- }else if (!strcasecmp(defel->defname, "alignment")) {
- char *a = defGetString(defel);
- if (!strcasecmp(a, "double")) {
- alignment = 'd';
- } else if (!strcasecmp(a, "int")) {
- alignment = 'i';
- } else {
- elog(WARN, "DefineType: \"%s\" alignment not recognized",
- a);
- }
- }else {
- elog(NOTICE, "DefineType: attribute \"%s\" not recognized",
- defel->defname);
- }
- }
-
- /*
- * make sure we have our required definitions
- */
- if (inputName==NULL)
- elog(WARN, "Define: \"input\" unspecified");
- if (outputName==NULL)
- elog(WARN, "Define: \"output\" unspecified");
-
- /* ----------------
- * now have TypeCreate do all the real work.
- * ----------------
- */
- TypeCreate(typeName, /* type name */
- InvalidOid, /* relation oid (n/a here) */
- internalLength, /* internal size */
- externalLength, /* external size */
- 'b', /* type-type (base type) */
- delimiter, /* array element delimiter */
- inputName, /* input procedure */
- outputName, /* output procedure */
- sendName, /* send procedure */
- receiveName, /* receive procedure */
- elemName, /* element type name */
- defaultValue, /* default type value */
- byValue, /* passed by value */
- alignment);
-
- /* ----------------
- * When we create a true type (as opposed to a complex type)
- * we need to have an shadow array entry for it in pg_type as well.
- * ----------------
- */
- shadow_type = makeArrayTypeName(typeName);
-
- TypeCreate(shadow_type, /* type name */
- InvalidOid, /* relation oid (n/a here) */
- -1, /* internal size */
- -1, /* external size */
- 'b', /* type-type (base type) */
- DEFAULT_TYPDELIM, /* array element delimiter */
- "array_in", /* input procedure */
- "array_out", /* output procedure */
- "array_out", /* send procedure */
- "array_in", /* receive procedure */
- typeName, /* element type name */
- defaultValue, /* default type value */
- false, /* never passed by value */
- alignment);
-
- pfree(shadow_type);
+ int16 internalLength = 0; /* int2 */
+ int16 externalLength = 0; /* int2 */
+ char *elemName = NULL;
+ char *inputName = NULL;
+ char *outputName = NULL;
+ char *sendName = NULL;
+ char *receiveName = NULL;
+ char *defaultValue = NULL; /* Datum */
+ bool byValue = false;
+ char delimiter = DEFAULT_TYPDELIM;
+ char *shadow_type;
+ List *pl;
+ char alignment = 'i'; /* default alignment */
+
+ /*
+ * Type names can only be 15 characters long, so that the shadow type
+ * can be created using the 16th character as necessary.
+ */
+ if (strlen(typeName) >= (NAMEDATALEN - 1))
+ {
+ elog(WARN, "DefineType: type names must be %d characters or less",
+ NAMEDATALEN - 1);
+ }
+
+ foreach(pl, parameters)
+ {
+ DefElem *defel = (DefElem *) lfirst(pl);
+
+ if (!strcasecmp(defel->defname, "internallength"))
+ {
+ internalLength = defGetTypeLength(defel);
+ }
+ else if (!strcasecmp(defel->defname, "externallength"))
+ {
+ externalLength = defGetTypeLength(defel);
+ }
+ else if (!strcasecmp(defel->defname, "input"))
+ {
+ inputName = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "output"))
+ {
+ outputName = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "send"))
+ {
+ sendName = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "delimiter"))
+ {
+ char *p = defGetString(defel);
+
+ delimiter = p[0];
+ }
+ else if (!strcasecmp(defel->defname, "receive"))
+ {
+ receiveName = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "element"))
+ {
+ elemName = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "default"))
+ {
+ defaultValue = defGetString(defel);
+ }
+ else if (!strcasecmp(defel->defname, "passedbyvalue"))
+ {
+ byValue = true;
+ }
+ else if (!strcasecmp(defel->defname, "alignment"))
+ {
+ char *a = defGetString(defel);
+
+ if (!strcasecmp(a, "double"))
+ {
+ alignment = 'd';
+ }
+ else if (!strcasecmp(a, "int"))
+ {
+ alignment = 'i';
+ }
+ else
+ {
+ elog(WARN, "DefineType: \"%s\" alignment not recognized",
+ a);
+ }
+ }
+ else
+ {
+ elog(NOTICE, "DefineType: attribute \"%s\" not recognized",
+ defel->defname);
+ }
+ }
+
+ /*
+ * make sure we have our required definitions
+ */
+ if (inputName == NULL)
+ elog(WARN, "Define: \"input\" unspecified");
+ if (outputName == NULL)
+ elog(WARN, "Define: \"output\" unspecified");
+
+ /* ----------------
+ * now have TypeCreate do all the real work.
+ * ----------------
+ */
+ TypeCreate(typeName, /* type name */
+ InvalidOid, /* relation oid (n/a here) */
+ internalLength, /* internal size */
+ externalLength, /* external size */
+ 'b', /* type-type (base type) */
+ delimiter, /* array element delimiter */
+ inputName, /* input procedure */
+ outputName, /* output procedure */
+ sendName, /* send procedure */
+ receiveName, /* receive procedure */
+ elemName, /* element type name */
+ defaultValue, /* default type value */
+ byValue, /* passed by value */
+ alignment);
+
+ /* ----------------
+ * When we create a true type (as opposed to a complex type)
+ * we need to have an shadow array entry for it in pg_type as well.
+ * ----------------
+ */
+ shadow_type = makeArrayTypeName(typeName);
+
+ TypeCreate(shadow_type, /* type name */
+ InvalidOid, /* relation oid (n/a here) */
+ -1, /* internal size */
+ -1, /* external size */
+ 'b', /* type-type (base type) */
+ DEFAULT_TYPDELIM,/* array element delimiter */
+ "array_in", /* input procedure */
+ "array_out", /* output procedure */
+ "array_out", /* send procedure */
+ "array_in", /* receive procedure */
+ typeName, /* element type name */
+ defaultValue, /* default type value */
+ false, /* never passed by value */
+ alignment);
+
+ pfree(shadow_type);
}
-static char *
-defGetString(DefElem *def)
+static char *
+defGetString(DefElem * def)
{
- if (nodeTag(def->arg)!=T_String)
- elog(WARN, "Define: \"%s\" = what?", def->defname);
- return (strVal(def->arg));
+ if (nodeTag(def->arg) != T_String)
+ elog(WARN, "Define: \"%s\" = what?", def->defname);
+ return (strVal(def->arg));
}
-static int
-defGetTypeLength(DefElem *def)
+static int
+defGetTypeLength(DefElem * def)
{
- if (nodeTag(def->arg)==T_Integer)
- return (intVal(def->arg));
- else if (nodeTag(def->arg)==T_String &&
- !strcasecmp(strVal(def->arg),"variable"))
- return -1; /* variable length */
-
- elog(WARN, "Define: \"%s\" = what?", def->defname);
- return -1;
+ if (nodeTag(def->arg) == T_Integer)
+ return (intVal(def->arg));
+ else if (nodeTag(def->arg) == T_String &&
+ !strcasecmp(strVal(def->arg), "variable"))
+ return -1; /* variable length */
+
+ elog(WARN, "Define: \"%s\" = what?", def->defname);
+ return -1;
}
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 7d1f34d0327..192076e3911 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* explain.c--
- * Explain the query execution plan
+ * Explain the query execution plan
*
* Copyright (c) 1994-5, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.10 1997/08/18 20:52:17 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.11 1997/09/07 04:40:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,7 @@
#include <postgres.h>
#include <parser/catalog_utils.h>
-#include <parser/parse_query.h> /* for MakeTimeRange() */
+#include <parser/parse_query.h> /* for MakeTimeRange() */
#include <nodes/plannodes.h>
#include <tcop/tcopprot.h>
#include <lib/stringinfo.h>
@@ -25,79 +25,86 @@
#include <optimizer/planner.h>
#include <access/xact.h>
-typedef struct ExplainState {
- /* options */
- bool printCost; /* print cost */
- bool printNodes; /* do nodeToString() instead */
- /* other states */
- List *rtable; /* range table */
-} ExplainState;
+typedef struct ExplainState
+{
+ /* options */
+ bool printCost; /* print cost */
+ bool printNodes; /* do nodeToString() instead */
+ /* other states */
+ List *rtable; /* range table */
+} ExplainState;
-static char *Explain_PlanToString(Plan *plan, ExplainState *es);
+static char *Explain_PlanToString(Plan * plan, ExplainState * es);
/*
* ExplainQuery -
- * print out the execution plan for a given query
+ * print out the execution plan for a given query
*
*/
void
-ExplainQuery(Query *query, bool verbose, CommandDest dest)
+ExplainQuery(Query * query, bool verbose, CommandDest dest)
{
- char *s = NULL, *s2;
- Plan *plan;
- ExplainState *es;
- int len;
-
- if (IsAbortedTransactionBlockState()) {
- char *tag = "*ABORT STATE*";
- EndCommand(tag, dest);
-
- elog(NOTICE, "(transaction aborted): %s",
- "queries ignored until END");
-
- return;
- }
+ char *s = NULL,
+ *s2;
+ Plan *plan;
+ ExplainState *es;
+ int len;
- /* plan the queries (XXX we've ignored rewrite!!) */
- plan = planner(query);
+ if (IsAbortedTransactionBlockState())
+ {
+ char *tag = "*ABORT STATE*";
- /* pg_plan could have failed */
- if (plan == NULL)
- return;
+ EndCommand(tag, dest);
+
+ elog(NOTICE, "(transaction aborted): %s",
+ "queries ignored until END");
+
+ return;
+ }
- es = (ExplainState*)malloc(sizeof(ExplainState));
- memset(es, 0, sizeof(ExplainState));
+ /* plan the queries (XXX we've ignored rewrite!!) */
+ plan = planner(query);
- es->printCost = true; /* default */
+ /* pg_plan could have failed */
+ if (plan == NULL)
+ return;
- if (verbose)
- es->printNodes = true;
+ es = (ExplainState *) malloc(sizeof(ExplainState));
+ memset(es, 0, sizeof(ExplainState));
- es->rtable = query->rtable;
+ es->printCost = true; /* default */
- if (es->printNodes)
- s = nodeToString(plan);
+ if (verbose)
+ es->printNodes = true;
- if (es->printCost) {
- s2 = Explain_PlanToString(plan, es);
- if (s == NULL)
- s = s2;
- else {
- strcat(s, "\n\n");
- strcat(s, s2);
+ es->rtable = query->rtable;
+
+ if (es->printNodes)
+ s = nodeToString(plan);
+
+ if (es->printCost)
+ {
+ s2 = Explain_PlanToString(plan, es);
+ if (s == NULL)
+ s = s2;
+ else
+ {
+ strcat(s, "\n\n");
+ strcat(s, s2);
+ }
}
- }
-
- /* output the plan */
- len = strlen(s);
- elog(NOTICE, "QUERY PLAN:\n\n%.*s", ELOG_MAXLEN-64, s);
- len -= ELOG_MAXLEN-64;
- while (len > 0) {
- s += ELOG_MAXLEN-64;
- elog(NOTICE, "%.*s", ELOG_MAXLEN-64, s);
- len -= ELOG_MAXLEN-64;
- }
- free(es);
+
+ /* output the plan */
+ len = strlen(s);
+ elog(NOTICE, "QUERY PLAN:\n\n%.*s", ELOG_MAXLEN - 64, s);
+ len -= ELOG_MAXLEN - 64;
+ while (len > 0)
+ {
+ s += ELOG_MAXLEN - 64;
+ elog(NOTICE, "%.*s", ELOG_MAXLEN - 64, s);
+ len -= ELOG_MAXLEN - 64;
+ }
+ free(es);
}
/*****************************************************************************
@@ -106,122 +113,130 @@ ExplainQuery(Query *query, bool verbose, CommandDest dest)
/*
* explain_outNode -
- * converts a Node into ascii string and append it to 'str'
+ * converts a Node into ascii string and append it to 'str'
*/
static void
-explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
+explain_outNode(StringInfo str, Plan * plan, int indent, ExplainState * es)
{
- char *pname;
- char buf[1000];
- int i;
-
- if (plan==NULL) {
+ char *pname;
+ char buf[1000];
+ int i;
+
+ if (plan == NULL)
+ {
+ appendStringInfo(str, "\n");
+ return;
+ }
+
+ switch (nodeTag(plan))
+ {
+ case T_Result:
+ pname = "Result";
+ break;
+ case T_Append:
+ pname = "Append";
+ break;
+ case T_NestLoop:
+ pname = "Nested Loop";
+ break;
+ case T_MergeJoin:
+ pname = "Merge Join";
+ break;
+ case T_HashJoin:
+ pname = "Hash Join";
+ break;
+ case T_SeqScan:
+ pname = "Seq Scan";
+ break;
+ case T_IndexScan:
+ pname = "Index Scan";
+ break;
+ case T_Temp:
+ pname = "Temp Scan";
+ break;
+ case T_Sort:
+ pname = "Sort";
+ break;
+ case T_Group:
+ pname = "Group";
+ break;
+ case T_Agg:
+ pname = "Aggregate";
+ break;
+ case T_Unique:
+ pname = "Unique";
+ break;
+ case T_Hash:
+ pname = "Hash";
+ break;
+ case T_Tee:
+ pname = "Tee";
+ break;
+ default:
+ pname = "";
+ break;
+ }
+
+ for (i = 0; i < indent; i++)
+ appendStringInfo(str, " ");
+
+ appendStringInfo(str, pname);
+ switch (nodeTag(plan))
+ {
+ case T_SeqScan:
+ case T_IndexScan:
+ if (((Scan *) plan)->scanrelid > 0)
+ {
+ RangeTblEntry *rte = nth(((Scan *) plan)->scanrelid - 1, es->rtable);
+
+ sprintf(buf, " on %s", rte->refname);
+ appendStringInfo(str, buf);
+ }
+ break;
+ default:
+ break;
+ }
+ if (es->printCost)
+ {
+ sprintf(buf, " (cost=%.2f size=%d width=%d)",
+ plan->cost, plan->plan_size, plan->plan_width);
+ appendStringInfo(str, buf);
+ }
appendStringInfo(str, "\n");
- return;
- }
-
- switch(nodeTag(plan)) {
- case T_Result:
- pname = "Result";
- break;
- case T_Append:
- pname = "Append";
- break;
- case T_NestLoop:
- pname = "Nested Loop";
- break;
- case T_MergeJoin:
- pname = "Merge Join";
- break;
- case T_HashJoin:
- pname = "Hash Join";
- break;
- case T_SeqScan:
- pname = "Seq Scan";
- break;
- case T_IndexScan:
- pname = "Index Scan";
- break;
- case T_Temp:
- pname = "Temp Scan";
- break;
- case T_Sort:
- pname = "Sort";
- break;
- case T_Group:
- pname = "Group";
- break;
- case T_Agg:
- pname = "Aggregate";
- break;
- case T_Unique:
- pname = "Unique";
- break;
- case T_Hash:
- pname = "Hash";
- break;
- case T_Tee:
- pname = "Tee";
- break;
- default:
- pname = "";
- break;
- }
-
- for(i=0; i < indent; i++)
- appendStringInfo(str, " ");
-
- appendStringInfo(str, pname);
- switch(nodeTag(plan)) {
- case T_SeqScan:
- case T_IndexScan:
- if (((Scan*)plan)->scanrelid > 0) {
- RangeTblEntry *rte = nth(((Scan*)plan)->scanrelid-1, es->rtable);
- sprintf(buf, " on %s", rte->refname);
- appendStringInfo(str, buf);
+
+ /* lefttree */
+ if (outerPlan(plan))
+ {
+ for (i = 0; i < indent; i++)
+ appendStringInfo(str, " ");
+ appendStringInfo(str, " -> ");
+ explain_outNode(str, outerPlan(plan), indent + 1, es);
}
- break;
- default:
- break;
- }
- if (es->printCost) {
- sprintf(buf, " (cost=%.2f size=%d width=%d)",
- plan->cost, plan->plan_size, plan->plan_width);
- appendStringInfo(str, buf);
- }
- appendStringInfo(str, "\n");
-
- /* lefttree */
- if (outerPlan(plan)) {
- for(i=0; i < indent; i++)
- appendStringInfo(str, " ");
- appendStringInfo(str, " -> ");
- explain_outNode(str, outerPlan(plan), indent+1, es);
- }
-
- /* righttree */
- if (innerPlan(plan)) {
- for(i=0; i < indent; i++)
- appendStringInfo(str, " ");
- appendStringInfo(str, " -> ");
- explain_outNode(str, innerPlan(plan), indent+1, es);
- }
- return;
+
+ /* righttree */
+ if (innerPlan(plan))
+ {
+ for (i = 0; i < indent; i++)
+ appendStringInfo(str, " ");
+ appendStringInfo(str, " -> ");
+ explain_outNode(str, innerPlan(plan), indent + 1, es);
+ }
+ return;
}
-static char *
-Explain_PlanToString(Plan *plan, ExplainState *es)
+static char *
+Explain_PlanToString(Plan * plan, ExplainState * es)
{
- StringInfo str;
- char *s;
-
- if (plan==NULL)
- return "";
- Assert(plan!=NULL);
- str = makeStringInfo();
- explain_outNode(str, plan, 0, es);
- s = str->data;
- pfree(str);
-
- return s;
+ StringInfo str;
+ char *s;
+
+ if (plan == NULL)
+ return "";
+ Assert(plan != NULL);
+ str = makeStringInfo();
+ explain_outNode(str, plan, 0, es);
+ s = str->data;
+ pfree(str);
+
+ return s;
}
diff --git a/src/backend/commands/purge.c b/src/backend/commands/purge.c
index 5c514fc8675..8000bbc7352 100644
--- a/src/backend/commands/purge.c
+++ b/src/backend/commands/purge.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* purge.c--
- * the POSTGRES purge command.
+ * the POSTGRES purge command.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/purge.c,v 1.6 1997/08/12 22:52:25 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/purge.c,v 1.7 1997/09/07 04:40:51 momjian Exp $
*
* Note:
- * XXX There are many instances of int32 instead of ...Time. These
- * should be changed once it is decided the signed'ness will be.
+ * XXX There are many instances of int32 instead of ...Time. These
+ * should be changed once it is decided the signed'ness will be.
*
*-------------------------------------------------------------------------
*/
@@ -21,145 +21,156 @@
#include <access/heapam.h>
#include <access/xact.h>
-#include <utils/tqual.h> /* for NowTimeQual */
+#include <utils/tqual.h> /* for NowTimeQual */
#include <catalog/catname.h>
#include <catalog/indexing.h>
#include <fmgr.h>
#include <commands/purge.h>
-#include <utils/builtins.h> /* for isreltime() */
+#include <utils/builtins.h> /* for isreltime() */
-static char cmdname[] = "RelationPurge";
+static char cmdname[] = "RelationPurge";
-#define RELATIVE 01
-#define ABSOLUTE 02
+#define RELATIVE 01
+#define ABSOLUTE 02
int32
RelationPurge(char *relationName,
- char *absoluteTimeString,
- char *relativeTimeString)
+ char *absoluteTimeString,
+ char *relativeTimeString)
{
- register i;
- AbsoluteTime absoluteTime = INVALID_ABSTIME;
- RelativeTime relativeTime = INVALID_RELTIME;
- bits8 dateTag;
- Relation relation;
- HeapScanDesc scan;
- static ScanKeyData key[1] = {
- { 0, Anum_pg_class_relname, F_NAMEEQ }
- };
- Buffer buffer;
- HeapTuple newTuple, oldTuple;
- AbsoluteTime currentTime;
- char *values[Natts_pg_class];
- char nulls[Natts_pg_class];
- char replace[Natts_pg_class];
- Relation idescs[Num_pg_class_indices];
-
- /*
- * XXX for some reason getmyrelids (in inval.c) barfs when
- * you heap_replace tuples from these classes. i thought
- * setheapoverride would fix it but it didn't. for now,
- * just disallow purge on these classes.
- */
- if (strcmp(RelationRelationName, relationName) == 0 ||
- strcmp(AttributeRelationName, relationName) == 0 ||
- strcmp(AccessMethodRelationName, relationName) == 0 ||
- strcmp(AccessMethodOperatorRelationName, relationName) == 0) {
- elog(WARN, "%s: cannot purge catalog \"%s\"",
- cmdname, relationName);
- }
-
- if (PointerIsValid(absoluteTimeString)) {
- absoluteTime = (int32) nabstimein(absoluteTimeString);
- absoluteTimeString[0] = '\0';
- if (absoluteTime == INVALID_ABSTIME) {
- elog(NOTICE, "%s: bad absolute time string \"%s\"",
- cmdname, absoluteTimeString);
- elog(WARN, "purge not executed");
+ register i;
+ AbsoluteTime absoluteTime = INVALID_ABSTIME;
+ RelativeTime relativeTime = INVALID_RELTIME;
+ bits8 dateTag;
+ Relation relation;
+ HeapScanDesc scan;
+ static ScanKeyData key[1] = {
+ {0, Anum_pg_class_relname, F_NAMEEQ}
+ };
+ Buffer buffer;
+ HeapTuple newTuple,
+ oldTuple;
+ AbsoluteTime currentTime;
+ char *values[Natts_pg_class];
+ char nulls[Natts_pg_class];
+ char replace[Natts_pg_class];
+ Relation idescs[Num_pg_class_indices];
+
+ /*
+ * XXX for some reason getmyrelids (in inval.c) barfs when you
+ * heap_replace tuples from these classes. i thought setheapoverride
+ * would fix it but it didn't. for now, just disallow purge on these
+ * classes.
+ */
+ if (strcmp(RelationRelationName, relationName) == 0 ||
+ strcmp(AttributeRelationName, relationName) == 0 ||
+ strcmp(AccessMethodRelationName, relationName) == 0 ||
+ strcmp(AccessMethodOperatorRelationName, relationName) == 0)
+ {
+ elog(WARN, "%s: cannot purge catalog \"%s\"",
+ cmdname, relationName);
}
- }
-
-#ifdef PURGEDEBUG
- elog(DEBUG, "%s: absolute time `%s' is %d.",
- cmdname, absoluteTimeString, absoluteTime);
-#endif /* defined(PURGEDEBUG) */
-
- if (PointerIsValid(relativeTimeString)) {
- if (isreltime(relativeTimeString) != 1) {
- elog(WARN, "%s: bad relative time string \"%s\"",
- cmdname, relativeTimeString);
+
+ if (PointerIsValid(absoluteTimeString))
+ {
+ absoluteTime = (int32) nabstimein(absoluteTimeString);
+ absoluteTimeString[0] = '\0';
+ if (absoluteTime == INVALID_ABSTIME)
+ {
+ elog(NOTICE, "%s: bad absolute time string \"%s\"",
+ cmdname, absoluteTimeString);
+ elog(WARN, "purge not executed");
+ }
}
- relativeTime = reltimein(relativeTimeString);
-
+
+#ifdef PURGEDEBUG
+ elog(DEBUG, "%s: absolute time `%s' is %d.",
+ cmdname, absoluteTimeString, absoluteTime);
+#endif /* defined(PURGEDEBUG) */
+
+ if (PointerIsValid(relativeTimeString))
+ {
+ if (isreltime(relativeTimeString) != 1)
+ {
+ elog(WARN, "%s: bad relative time string \"%s\"",
+ cmdname, relativeTimeString);
+ }
+ relativeTime = reltimein(relativeTimeString);
+
#ifdef PURGEDEBUG
- elog(DEBUG, "%s: relative time `%s' is %d.",
- cmdname, relativeTimeString, relativeTime);
-#endif /* defined(PURGEDEBUG) */
- }
-
- /*
- * Find the RELATION relation tuple for the given relation.
- */
- relation = heap_openr(RelationRelationName);
- key[0].sk_argument = PointerGetDatum(relationName);
- fmgr_info(key[0].sk_procedure, &key[0].sk_func, &key[0].sk_nargs);
-
- scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
- oldTuple = heap_getnext(scan, 0, &buffer);
- if (!HeapTupleIsValid(oldTuple)) {
+ elog(DEBUG, "%s: relative time `%s' is %d.",
+ cmdname, relativeTimeString, relativeTime);
+#endif /* defined(PURGEDEBUG) */
+ }
+
+ /*
+ * Find the RELATION relation tuple for the given relation.
+ */
+ relation = heap_openr(RelationRelationName);
+ key[0].sk_argument = PointerGetDatum(relationName);
+ fmgr_info(key[0].sk_procedure, &key[0].sk_func, &key[0].sk_nargs);
+
+ scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
+ oldTuple = heap_getnext(scan, 0, &buffer);
+ if (!HeapTupleIsValid(oldTuple))
+ {
+ heap_endscan(scan);
+ heap_close(relation);
+ elog(WARN, "%s: no such relation: %s", cmdname, relationName);
+ return (0);
+ }
+
+ /*
+ * Dig around in the tuple.
+ */
+ currentTime = GetCurrentTransactionStartTime();
+ if (!RelativeTimeIsValid(relativeTime))
+ {
+ dateTag = ABSOLUTE;
+ if (!AbsoluteTimeIsValid(absoluteTime))
+ absoluteTime = currentTime;
+ }
+ else if (!AbsoluteTimeIsValid(absoluteTime))
+ dateTag = RELATIVE;
+ else
+ dateTag = ABSOLUTE | RELATIVE;
+
+ for (i = 0; i < Natts_pg_class; ++i)
+ {
+ nulls[i] = heap_attisnull(oldTuple, i + 1) ? 'n' : ' ';
+ values[i] = NULL;
+ replace[i] = ' ';
+ }
+ if (dateTag & ABSOLUTE)
+ {
+ values[Anum_pg_class_relexpires - 1] =
+ (char *) UInt32GetDatum(absoluteTime);
+ replace[Anum_pg_class_relexpires - 1] = 'r';
+ }
+ if (dateTag & RELATIVE)
+ {
+ values[Anum_pg_class_relpreserved - 1] =
+ (char *) UInt32GetDatum(relativeTime);
+ replace[Anum_pg_class_relpreserved - 1] = 'r';
+ }
+
+ /*
+ * Change the RELATION relation tuple for the given relation.
+ */
+ newTuple = heap_modifytuple(oldTuple, buffer, relation, (Datum *) values,
+ nulls, replace);
+
+ /* XXX How do you detect an insertion error?? */
+ heap_replace(relation, &newTuple->t_ctid, newTuple);
+
+ /* keep the system catalog indices current */
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, relation, newTuple);
+ CatalogCloseIndices(Num_pg_class_indices, idescs);
+
+ pfree(newTuple);
+
heap_endscan(scan);
heap_close(relation);
- elog(WARN, "%s: no such relation: %s", cmdname, relationName);
- return(0);
- }
-
- /*
- * Dig around in the tuple.
- */
- currentTime = GetCurrentTransactionStartTime();
- if (!RelativeTimeIsValid(relativeTime)) {
- dateTag = ABSOLUTE;
- if (!AbsoluteTimeIsValid(absoluteTime))
- absoluteTime = currentTime;
- } else if (!AbsoluteTimeIsValid(absoluteTime))
- dateTag = RELATIVE;
- else
- dateTag = ABSOLUTE | RELATIVE;
-
- for (i = 0; i < Natts_pg_class; ++i) {
- nulls[i] = heap_attisnull(oldTuple, i+1) ? 'n' : ' ';
- values[i] = NULL;
- replace[i] = ' ';
- }
- if (dateTag & ABSOLUTE) {
- values[Anum_pg_class_relexpires-1] =
- (char *) UInt32GetDatum(absoluteTime);
- replace[Anum_pg_class_relexpires-1] = 'r';
- }
- if (dateTag & RELATIVE) {
- values[Anum_pg_class_relpreserved-1] =
- (char *) UInt32GetDatum(relativeTime);
- replace[Anum_pg_class_relpreserved-1] = 'r';
- }
-
- /*
- * Change the RELATION relation tuple for the given relation.
- */
- newTuple = heap_modifytuple(oldTuple, buffer, relation, (Datum*)values,
- nulls, replace);
-
- /* XXX How do you detect an insertion error?? */
- heap_replace(relation, &newTuple->t_ctid, newTuple);
-
- /* keep the system catalog indices current */
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_class_indices, relation, newTuple);
- CatalogCloseIndices(Num_pg_class_indices, idescs);
-
- pfree(newTuple);
-
- heap_endscan(scan);
- heap_close(relation);
- return(1);
+ return (1);
}
-
diff --git a/src/backend/commands/recipe.c b/src/backend/commands/recipe.c
index e6aa009bd33..bf05c293d13 100644
--- a/src/backend/commands/recipe.c
+++ b/src/backend/commands/recipe.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* recipe.c--
- * routines for handling execution of Tioga recipes
+ * routines for handling execution of Tioga recipes
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/recipe.c,v 1.6 1997/08/12 20:15:11 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/recipe.c,v 1.7 1997/09/07 04:40:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,7 +21,7 @@
#include <commands/recipe.h>
#include <libpq/libpq-be.h>
#include <utils/builtins.h>
-#include <utils/relcache.h> /* for RelationNameGetRelation*/
+#include <utils/relcache.h> /* for RelationNameGetRelation */
#include <parser/parse_query.h>
#include <rewrite/rewriteHandler.h>
#include <rewrite/rewriteManip.h>
@@ -35,9 +35,12 @@ extern CommandDest whereToSendOutput;
#ifndef TIOGA
-void beginRecipe(RecipeStmt *stmt) {
- elog(NOTICE,"You must compile with TIOGA defined in order to use recipes\n");
+void
+beginRecipe(RecipeStmt * stmt)
+{
+ elog(NOTICE, "You must compile with TIOGA defined in order to use recipes\n");
}
+
#else
#include <tioga/tgRecipe.h>
@@ -45,49 +48,59 @@ void beginRecipe(RecipeStmt *stmt) {
#define DEBUG_RECIPE 1
/* structure to keep track of the tee node plans */
-typedef struct _teePlanInfo {
- char* tpi_relName;
- Query* tpi_parsetree;
- Plan* tpi_plan;
-} TeePlanInfo;
-
-typedef struct _teeInfo {
- int num;
- TeePlanInfo *val;
-} TeeInfo;
-
-QueryTreeList *appendQlist(QueryTreeList *q1, QueryTreeList *q2);
-void OffsetVarAttno(Node* node, int varno, int offset);
-
-static void appendTeeQuery(TeeInfo *teeInfo,
- QueryTreeList *q,
- char* teeNodeName);
-
-static Plan* replaceTeeScans(Plan* plan,
- Query* parsetree,
- TeeInfo *teeInfo);
-static void replaceSeqScan(Plan* plan,
- Plan* parent,
- int rt_ind,
- Plan* tplan);
-
-static void tg_rewriteQuery(TgRecipe* r, TgNode *n,
- QueryTreeList *q,
- QueryTreeList *inputQlist);
-static Node *tg_replaceNumberedParam(Node* expression,
- int pnum,
- int rt_ind,
- char *teeRelName);
-static Node *tg_rewriteParamsInExpr(Node *expression,
- QueryTreeList *inputQlist);
-static QueryTreeList *tg_parseSubQuery(TgRecipe* r,
- TgNode* n,
- TeeInfo* teeInfo);
-static QueryTreeList* tg_parseTeeNode(TgRecipe *r,
- TgNode *n,
- int i,
- QueryTreeList *qList,
- TeeInfo* teeInfo);
+typedef struct _teePlanInfo
+{
+ char *tpi_relName;
+ Query *tpi_parsetree;
+ Plan *tpi_plan;
+} TeePlanInfo;
+
+typedef struct _teeInfo
+{
+ int num;
+ TeePlanInfo *val;
+} TeeInfo;
+
+QueryTreeList *appendQlist(QueryTreeList * q1, QueryTreeList * q2);
+void OffsetVarAttno(Node * node, int varno, int offset);
+
+static void
+appendTeeQuery(TeeInfo * teeInfo,
+ QueryTreeList * q,
+ char *teeNodeName);
+
+static Plan *
+replaceTeeScans(Plan * plan,
+ Query * parsetree,
+ TeeInfo * teeInfo);
+static void
+replaceSeqScan(Plan * plan,
+ Plan * parent,
+ int rt_ind,
+ Plan * tplan);
+
+static void
+tg_rewriteQuery(TgRecipe * r, TgNode * n,
+ QueryTreeList * q,
+ QueryTreeList * inputQlist);
+static Node *
+tg_replaceNumberedParam(Node * expression,
+ int pnum,
+ int rt_ind,
+ char *teeRelName);
+static Node *
+tg_rewriteParamsInExpr(Node * expression,
+ QueryTreeList * inputQlist);
+static QueryTreeList *
+tg_parseSubQuery(TgRecipe * r,
+ TgNode * n,
+ TeeInfo * teeInfo);
+static QueryTreeList *
+tg_parseTeeNode(TgRecipe * r,
+ TgNode * n,
+ int i,
+ QueryTreeList * qList,
+ TeeInfo * teeInfo);
/*
@@ -96,172 +109,192 @@ static QueryTreeList* tg_parseTeeNode(TgRecipe *r,
To parse a Tioga recipe, we start from an eye node and go backwards through
its input nodes. To rewrite a Tioga node, we do the following:
- 1) parse the node we're at in the standard way (calling parser() )
- 2) rewrite its input nodes recursively using Tioga rewrite
- 3) now, with the rewritten input parse trees and the original parse tree
- of the node, we rewrite the the node.
- To do the rewrite, we use the target lists, range tables, and
- qualifications of the input parse trees
+ 1) parse the node we're at in the standard way (calling parser() )
+ 2) rewrite its input nodes recursively using Tioga rewrite
+ 3) now, with the rewritten input parse trees and the original parse tree
+ of the node, we rewrite the the node.
+ To do the rewrite, we use the target lists, range tables, and
+ qualifications of the input parse trees
*/
/*
* beginRecipe:
- * this is the main function to recipe execution
- * this function is invoked for EXECUTE RECIPE ... statements
- *
- * takes in a RecipeStmt structure from the parser
+ * this is the main function to recipe execution
+ * this function is invoked for EXECUTE RECIPE ... statements
+ *
+ * takes in a RecipeStmt structure from the parser
* and returns a list of cursor names
*/
void
-beginRecipe(RecipeStmt* stmt)
+beginRecipe(RecipeStmt * stmt)
{
- TgRecipe* r;
- int i;
- QueryTreeList *qList;
- char portalName[1024];
-
- Plan *plan;
- TupleDesc attinfo;
- QueryDesc *queryDesc;
- Query *parsetree;
-
- int numTees;
- TeeInfo* teeInfo;
-
- /* retrieveRecipe() reads the recipe from the database
- and returns a TgRecipe* structure we can work with */
-
- r = retrieveRecipe(stmt->recipeName);
-
- if (r == NULL) return;
-
- /* find the number of tees in the recipe */
- numTees = r->tees->num;
-
- if (numTees > 0) {
- /* allocate a teePlan structure */
- teeInfo = (TeeInfo*)malloc(sizeof(TeeInfo));
- teeInfo->num = numTees;
- teeInfo->val = (TeePlanInfo*)malloc(numTees * sizeof(TeePlanInfo));
- for (i=0;i<numTees;i++) {
- teeInfo->val[i].tpi_relName = r->tees->val[i]->nodeName;
- teeInfo->val[i].tpi_parsetree = NULL;
- teeInfo->val[i].tpi_plan = NULL;
- }
- } else
- teeInfo = NULL;
-
- /*
- * for each viewer in the recipe, go backwards from each viewer input
- * and generate a plan. Attach the plan to cursors.
- **/
- for (i=0;i<r->eyes->num;i++) {
- TgNodePtr e;
-
- e = r->eyes->val[i];
- if (e->inNodes->num > 1) {
- elog(NOTICE,
- "beginRecipe: Currently eyes cannot have more than one input");
- }
- if (e->inNodes->num == 0) {
- /* no input to this eye, skip it */
- continue;
- }
+ TgRecipe *r;
+ int i;
+ QueryTreeList *qList;
+ char portalName[1024];
+
+ Plan *plan;
+ TupleDesc attinfo;
+ QueryDesc *queryDesc;
+ Query *parsetree;
+
+ int numTees;
+ TeeInfo *teeInfo;
+
+ /*
+ * retrieveRecipe() reads the recipe from the database and returns a
+ * TgRecipe* structure we can work with
+ */
+
+ r = retrieveRecipe(stmt->recipeName);
+
+ if (r == NULL)
+ return;
+
+ /* find the number of tees in the recipe */
+ numTees = r->tees->num;
+
+ if (numTees > 0)
+ {
+ /* allocate a teePlan structure */
+ teeInfo = (TeeInfo *) malloc(sizeof(TeeInfo));
+ teeInfo->num = numTees;
+ teeInfo->val = (TeePlanInfo *) malloc(numTees * sizeof(TeePlanInfo));
+ for (i = 0; i < numTees; i++)
+ {
+ teeInfo->val[i].tpi_relName = r->tees->val[i]->nodeName;
+ teeInfo->val[i].tpi_parsetree = NULL;
+ teeInfo->val[i].tpi_plan = NULL;
+ }
+ }
+ else
+ teeInfo = NULL;
+
+ /*
+ * for each viewer in the recipe, go backwards from each viewer input
+ * and generate a plan. Attach the plan to cursors.
+ */
+ for (i = 0; i < r->eyes->num; i++)
+ {
+ TgNodePtr e;
+
+ e = r->eyes->val[i];
+ if (e->inNodes->num > 1)
+ {
+ elog(NOTICE,
+ "beginRecipe: Currently eyes cannot have more than one input");
+ }
+ if (e->inNodes->num == 0)
+ {
+ /* no input to this eye, skip it */
+ continue;
+ }
#ifdef DEBUG_RECIPE
- elog(NOTICE,"beginRecipe: eyes[%d] = %s\n", i, e->nodeName);
-#endif /* DEBUG_RECIPE */
-
- qList = tg_parseSubQuery(r,e->inNodes->val[0], teeInfo);
-
- if (qList == NULL) {
- /* eye is directly connected to a tee node */
- /* XXX TODO: handle this case */
- }
-
- /* now, plan the queries */
- /* should really do everything pg_plan() does, but for now,
- we skip the rule rewrite and time qual stuff */
-
- /* ----------------------------------------------------------
- * 1) plan the main query, everything from an eye node back to
- a Tee
- * ---------------------------------------------------------- */
- parsetree = qList->qtrees[0];
-
- /* before we plan, we want to see all the changes
- we did, during the rewrite phase, such as
- creating the tee tables,
- setheapoverride() allows us to see the changes */
- setheapoverride(true);
- plan = planner(parsetree);
-
- /* ----------------------------------------------------------
- * 2) plan the tee queries, (subgraphs rooted from a Tee)
- by the time the eye is processed, all tees that contribute
- to that eye will have been included in the teeInfo list
- * ---------------------------------------------------------- */
- if (teeInfo) {
- int t;
- Plan* tplan;
- Tee* newplan;
-
- for (t=0; t<teeInfo->num;t++) {
- if (teeInfo->val[t].tpi_plan == NULL) {
- /* plan it in the usual fashion */
- tplan = planner(teeInfo->val[t].tpi_parsetree);
-
- /* now add a tee node to the root of the plan */
-elog(NOTICE, "adding tee plan node to the root of the %s\n",
- teeInfo->val[t].tpi_relName);
- newplan = (Tee*)makeNode(Tee);
- newplan->plan.targetlist = tplan->targetlist;
- newplan->plan.qual = NULL; /* tplan->qual; */
- newplan->plan.lefttree = tplan;
- newplan->plan.righttree = NULL;
- newplan->leftParent = NULL;
- newplan->rightParent = NULL;
- /* the range table of the tee is the range table
- of the tplan */
- newplan->rtentries = teeInfo->val[t].tpi_parsetree->rtable;
- strcpy(newplan->teeTableName,
- teeInfo->val[t].tpi_relName);
- teeInfo->val[t].tpi_plan = (Plan*)newplan;
- }
- }
-
- /* ----------------------------------------------------------
- * 3) replace the tee table scans in the main plan with
- actual tee plannodes
- * ---------------------------------------------------------- */
-
- plan = replaceTeeScans(plan, parsetree, teeInfo);
-
- } /* if (teeInfo) */
-
- setheapoverride(false);
-
- /* define a portal for this viewer input */
- /* for now, eyes can only have one input */
- sprintf(portalName, "%s%d",e->nodeName,0);
-
- queryDesc = CreateQueryDesc(parsetree,
- plan,
- whereToSendOutput);
- /* ----------------
- * call ExecStart to prepare the plan for execution
- * ----------------
- */
- attinfo = ExecutorStart(queryDesc,NULL);
-
- ProcessPortal(portalName,
- parsetree,
- plan,
- attinfo,
- whereToSendOutput);
-elog(NOTICE, "beginRecipe: cursor named %s is now available", portalName);
- }
+ elog(NOTICE, "beginRecipe: eyes[%d] = %s\n", i, e->nodeName);
+#endif /* DEBUG_RECIPE */
+
+ qList = tg_parseSubQuery(r, e->inNodes->val[0], teeInfo);
+
+ if (qList == NULL)
+ {
+ /* eye is directly connected to a tee node */
+ /* XXX TODO: handle this case */
+ }
+
+ /* now, plan the queries */
+
+ /*
+ * should really do everything pg_plan() does, but for now, we
+ * skip the rule rewrite and time qual stuff
+ */
+
+ /* ----------------------------------------------------------
+ * 1) plan the main query, everything from an eye node back to
+ a Tee
+ * ---------------------------------------------------------- */
+ parsetree = qList->qtrees[0];
+
+ /*
+ * before we plan, we want to see all the changes we did, during
+ * the rewrite phase, such as creating the tee tables,
+ * setheapoverride() allows us to see the changes
+ */
+ setheapoverride(true);
+ plan = planner(parsetree);
+
+ /* ----------------------------------------------------------
+ * 2) plan the tee queries, (subgraphs rooted from a Tee)
+ by the time the eye is processed, all tees that contribute
+ to that eye will have been included in the teeInfo list
+ * ---------------------------------------------------------- */
+ if (teeInfo)
+ {
+ int t;
+ Plan *tplan;
+ Tee *newplan;
+
+ for (t = 0; t < teeInfo->num; t++)
+ {
+ if (teeInfo->val[t].tpi_plan == NULL)
+ {
+ /* plan it in the usual fashion */
+ tplan = planner(teeInfo->val[t].tpi_parsetree);
+
+ /* now add a tee node to the root of the plan */
+ elog(NOTICE, "adding tee plan node to the root of the %s\n",
+ teeInfo->val[t].tpi_relName);
+ newplan = (Tee *) makeNode(Tee);
+ newplan->plan.targetlist = tplan->targetlist;
+ newplan->plan.qual = NULL; /* tplan->qual; */
+ newplan->plan.lefttree = tplan;
+ newplan->plan.righttree = NULL;
+ newplan->leftParent = NULL;
+ newplan->rightParent = NULL;
+
+ /*
+ * the range table of the tee is the range table of
+ * the tplan
+ */
+ newplan->rtentries = teeInfo->val[t].tpi_parsetree->rtable;
+ strcpy(newplan->teeTableName,
+ teeInfo->val[t].tpi_relName);
+ teeInfo->val[t].tpi_plan = (Plan *) newplan;
+ }
+ }
+
+ /* ----------------------------------------------------------
+ * 3) replace the tee table scans in the main plan with
+ actual tee plannodes
+ * ---------------------------------------------------------- */
+
+ plan = replaceTeeScans(plan, parsetree, teeInfo);
+
+ } /* if (teeInfo) */
+
+ setheapoverride(false);
+
+ /* define a portal for this viewer input */
+ /* for now, eyes can only have one input */
+ sprintf(portalName, "%s%d", e->nodeName, 0);
+
+ queryDesc = CreateQueryDesc(parsetree,
+ plan,
+ whereToSendOutput);
+ /* ----------------
+ * call ExecStart to prepare the plan for execution
+ * ----------------
+ */
+ attinfo = ExecutorStart(queryDesc, NULL);
+
+ ProcessPortal(portalName,
+ parsetree,
+ plan,
+ attinfo,
+ whereToSendOutput);
+ elog(NOTICE, "beginRecipe: cursor named %s is now available", portalName);
+ }
}
@@ -269,109 +302,122 @@ elog(NOTICE, "beginRecipe: cursor named %s is now available", portalName);
/*
* tg_rewriteQuery -
- * r - the recipe being rewritten
- * n - the node that we're current at
- * q - a QueryTree List containing the parse tree of the node
- * inputQlist - the parsetrees of its input nodes,
- * the size of inputQlist must be the same as the
- * number of input nodes. Some elements in the inpuQlist
- * may be null if the inputs to those nodes are unconnected
+ * r - the recipe being rewritten
+ * n - the node that we're current at
+ * q - a QueryTree List containing the parse tree of the node
+ * inputQlist - the parsetrees of its input nodes,
+ * the size of inputQlist must be the same as the
+ * number of input nodes. Some elements in the inpuQlist
+ * may be null if the inputs to those nodes are unconnected
*
- * this is the main routine for rewriting the recipe queries
- * the original query tree 'q' is modified
+ * this is the main routine for rewriting the recipe queries
+ * the original query tree 'q' is modified
*/
-static void
-tg_rewriteQuery(TgRecipe* r,
- TgNode *n,
- QueryTreeList *q,
- QueryTreeList *inputQlist)
+static void
+tg_rewriteQuery(TgRecipe * r,
+ TgNode * n,
+ QueryTreeList * q,
+ QueryTreeList * inputQlist)
{
- Query* orig;
- Query* inputQ;
- int i;
- List *rtable;
- List *input_rtable;
- int rt_length;
-
- /* orig is the original parse tree of the node */
- orig = q->qtrees[0];
-
-
- /*-------------------------------------------------------------------
- step 1:
-
- form a combined range table from all the range tables in the original
- query as well as the input nodes
-
- form a combined qualification from the qual in the original plus
- the quals of the input nodes
- -------------------------------------------------------------------
- */
-
- /* start with the original range table */
- rtable = orig->rtable;
- rt_length = length(rtable);
-
- for (i=0;i<n->inNodes->num;i++) {
- if (n->inNodes->val[i] != NULL &&
- n->inNodes->val[i]->nodeType != TG_TEE_NODE) {
- inputQ = inputQlist->qtrees[i];
- input_rtable = inputQ->rtable;
-
- /* need to offset the var nodes in the qual and targetlist
- because they are indexed off the original rtable */
- OffsetVarNodes((Node*)inputQ->qual, rt_length);
- OffsetVarNodes((Node*)inputQ->targetList, rt_length);
-
- /* append the range tables from the children nodes */
- rtable = nconc (rtable, input_rtable);
-
- /* append the qualifications of the child node into the
- original qual list */
- AddQual(orig, inputQ->qual);
+ Query *orig;
+ Query *inputQ;
+ int i;
+ List *rtable;
+ List *input_rtable;
+ int rt_length;
+
+ /* orig is the original parse tree of the node */
+ orig = q->qtrees[0];
+
+
+ /*-------------------------------------------------------------------
+ step 1:
+
+ form a combined range table from all the range tables in the original
+ query as well as the input nodes
+
+ form a combined qualification from the qual in the original plus
+ the quals of the input nodes
+ -------------------------------------------------------------------
+ */
+
+ /* start with the original range table */
+ rtable = orig->rtable;
+ rt_length = length(rtable);
+
+ for (i = 0; i < n->inNodes->num; i++)
+ {
+ if (n->inNodes->val[i] != NULL &&
+ n->inNodes->val[i]->nodeType != TG_TEE_NODE)
+ {
+ inputQ = inputQlist->qtrees[i];
+ input_rtable = inputQ->rtable;
+
+ /*
+ * need to offset the var nodes in the qual and targetlist
+ * because they are indexed off the original rtable
+ */
+ OffsetVarNodes((Node *) inputQ->qual, rt_length);
+ OffsetVarNodes((Node *) inputQ->targetList, rt_length);
+
+ /* append the range tables from the children nodes */
+ rtable = nconc(rtable, input_rtable);
+
+ /*
+ * append the qualifications of the child node into the
+ * original qual list
+ */
+ AddQual(orig, inputQ->qual);
+ }
}
- }
- orig->rtable = rtable;
-
- /* step 2:
- rewrite the target list of the original parse tree
- if there are any references to params, replace them with
- the appropriate target list entry of the children node
- */
- if (orig->targetList != NIL) {
- List *tl;
- TargetEntry *tle;
-
- foreach (tl, orig->targetList) {
- tle = lfirst(tl);
- if (tle->resdom != NULL) {
- tle->expr = tg_rewriteParamsInExpr(tle->expr, inputQlist);
- }
- }
- }
-
- /* step 3:
- rewrite the qual of the original parse tree
- if there are any references to params, replace them with
- the appropriate target list entry of the children node
- */
- if (orig->qual) {
- if (nodeTag(orig->qual) == T_List) {
- elog(WARN, "tg_rewriteQuery: Whoa! why is my qual a List???");
+ orig->rtable = rtable;
+
+ /*
+ * step 2: rewrite the target list of the original parse tree if there
+ * are any references to params, replace them with the appropriate
+ * target list entry of the children node
+ */
+ if (orig->targetList != NIL)
+ {
+ List *tl;
+ TargetEntry *tle;
+
+ foreach(tl, orig->targetList)
+ {
+ tle = lfirst(tl);
+ if (tle->resdom != NULL)
+ {
+ tle->expr = tg_rewriteParamsInExpr(tle->expr, inputQlist);
+ }
+ }
+ }
+
+ /*
+ * step 3: rewrite the qual of the original parse tree if there are
+ * any references to params, replace them with the appropriate target
+ * list entry of the children node
+ */
+ if (orig->qual)
+ {
+ if (nodeTag(orig->qual) == T_List)
+ {
+ elog(WARN, "tg_rewriteQuery: Whoa! why is my qual a List???");
+ }
+ orig->qual = tg_rewriteParamsInExpr(orig->qual, inputQlist);
}
- orig->qual = tg_rewriteParamsInExpr(orig->qual, inputQlist);
- }
- /* at this point, we're done with the rewrite, the querytreelist q
- has been modified */
+ /*
+ * at this point, we're done with the rewrite, the querytreelist q has
+ * been modified
+ */
}
/* tg_replaceNumberedParam:
- this procedure replaces the specified numbered param with a
+ this procedure replaces the specified numbered param with a
reference to a range table
this procedure recursively calls itself
@@ -379,104 +425,137 @@ tg_rewriteQuery(TgRecipe* r,
it returns a (possibly modified) Node*.
*/
-static Node*
-tg_replaceNumberedParam(Node *expression,
- int pnum, /* the number of the parameter */
- int rt_ind, /* the range table index */
- char *teeRelName) /* the relname of the tee table */
+static Node *
+tg_replaceNumberedParam(Node * expression,
+ int pnum, /* the number of the parameter */
+ int rt_ind, /* the range table index */
+ char *teeRelName) /* the relname of the tee
+ * table */
{
- TargetEntry *param_tle;
- Param* p;
- Var *newVar,*oldVar;
-
- if (expression == NULL) return NULL;
-
- switch (nodeTag(expression)) {
- case T_Param:
- {
- /* the node is a parameter,
- substitute the entry from the target list of the child that
- corresponds to the parameter number*/
- p = (Param*)expression;
-
- /* we only deal with the case of numbered parameters */
- if (p->paramkind == PARAM_NUM && p->paramid == pnum) {
-
- if (p->param_tlist) {
- /* we have a parameter with an attribute like $N.foo
- so replace it with a new var node */
-
- /* param tlist can only have one entry in them! */
- param_tle = (TargetEntry*)(lfirst(p->param_tlist));
- oldVar = (Var*)param_tle->expr;
- oldVar->varno = rt_ind;
- oldVar->varnoold = rt_ind;
- return (Node*)oldVar;
- } else {
- /* we have $N without the .foo */
- bool defined;
- bool isRel;
- /* TODO here, we need to check to see whether the type of the
- tee is a complex type (relation) or a simple type */
- /* if it is a simple type, then we need to get the "result"
- attribute from the tee relation */
-
- isRel = (typeid_get_relid(p->paramtype) != 0);
- if (isRel) {
- newVar = makeVar(rt_ind,
- 0, /* the whole tuple */
- TypeGet(teeRelName,&defined),
- rt_ind,
- 0);
- return (Node*)newVar;
- } else
- newVar = makeVar(rt_ind,
- 1, /* just the first field, which is 'result' */
- TypeGet(teeRelName,&defined),
- rt_ind,
- 0);
- return (Node*)newVar;
-
- }
- }
- else {
- elog(NOTICE, "tg_replaceNumberedParam: unexpected paramkind value of %d", p->paramkind);
- }
- }
- break;
- case T_Expr:
- {
- /* the node is an expression, we need to recursively
- call ourselves until we find parameter nodes */
- List *l;
- Expr *expr = (Expr*)expression;
- List *newArgs;
-
- /* we have to make a new args lists because Params
- can be replaced by Var nodes in tg_replaceNumberedParam()*/
- newArgs = NIL;
-
- /* we only care about argument to expressions,
- it doesn't matter when the opType is */
- /* recursively rewrite the arguments of this expression */
- foreach (l, expr->args) {
- newArgs = lappend(newArgs,
- tg_replaceNumberedParam(lfirst(l),
- pnum,
- rt_ind,
- teeRelName));
- }
- /* change the arguments of the expression */
- expr->args = newArgs;
- }
- break;
- default:
- {
- /* ignore other expr types */
- }
- }
-
- return expression;
+ TargetEntry *param_tle;
+ Param *p;
+ Var *newVar,
+ *oldVar;
+
+ if (expression == NULL)
+ return NULL;
+
+ switch (nodeTag(expression))
+ {
+ case T_Param:
+ {
+
+ /*
+ * the node is a parameter, substitute the entry from the
+ * target list of the child that corresponds to the parameter
+ * number
+ */
+ p = (Param *) expression;
+
+ /* we only deal with the case of numbered parameters */
+ if (p->paramkind == PARAM_NUM && p->paramid == pnum)
+ {
+
+ if (p->param_tlist)
+ {
+
+ /*
+ * we have a parameter with an attribute like $N.foo
+ * so replace it with a new var node
+ */
+
+ /* param tlist can only have one entry in them! */
+ param_tle = (TargetEntry *) (lfirst(p->param_tlist));
+ oldVar = (Var *) param_tle->expr;
+ oldVar->varno = rt_ind;
+ oldVar->varnoold = rt_ind;
+ return (Node *) oldVar;
+ }
+ else
+ {
+ /* we have $N without the .foo */
+ bool defined;
+ bool isRel;
+
+ /*
+ * TODO here, we need to check to see whether the type
+ * of the tee is a complex type (relation) or a simple
+ * type
+ */
+
+ /*
+ * if it is a simple type, then we need to get the
+ * "result" attribute from the tee relation
+ */
+
+ isRel = (typeid_get_relid(p->paramtype) != 0);
+ if (isRel)
+ {
+ newVar = makeVar(rt_ind,
+ 0, /* the whole tuple */
+ TypeGet(teeRelName, &defined),
+ rt_ind,
+ 0);
+ return (Node *) newVar;
+ }
+ else
+ newVar = makeVar(rt_ind,
+ 1, /* just the first field,
+ * which is 'result' */
+ TypeGet(teeRelName, &defined),
+ rt_ind,
+ 0);
+ return (Node *) newVar;
+
+ }
+ }
+ else
+ {
+ elog(NOTICE, "tg_replaceNumberedParam: unexpected paramkind value of %d", p->paramkind);
+ }
+ }
+ break;
+ case T_Expr:
+ {
+
+ /*
+ * the node is an expression, we need to recursively call
+ * ourselves until we find parameter nodes
+ */
+ List *l;
+ Expr *expr = (Expr *) expression;
+ List *newArgs;
+
+ /*
+ * we have to make a new args lists because Params can be
+ * replaced by Var nodes in tg_replaceNumberedParam()
+ */
+ newArgs = NIL;
+
+ /*
+ * we only care about argument to expressions, it doesn't
+ * matter when the opType is
+ */
+ /* recursively rewrite the arguments of this expression */
+ foreach(l, expr->args)
+ {
+ newArgs = lappend(newArgs,
+ tg_replaceNumberedParam(lfirst(l),
+ pnum,
+ rt_ind,
+ teeRelName));
+ }
+ /* change the arguments of the expression */
+ expr->args = newArgs;
+ }
+ break;
+ default:
+ {
+ /* ignore other expr types */
+ }
+ }
+
+ return expression;
}
@@ -485,694 +564,817 @@ tg_replaceNumberedParam(Node *expression,
/* tg_rewriteParamsInExpr:
- rewrite the params in expressions by using the targetlist entries
- from the input parsetrees
+ rewrite the params in expressions by using the targetlist entries
+ from the input parsetrees
this procedure recursively calls itself
it returns a (possibly modified) Node*.
*/
-static Node*
-tg_rewriteParamsInExpr(Node *expression, QueryTreeList *inputQlist)
+static Node *
+tg_rewriteParamsInExpr(Node * expression, QueryTreeList * inputQlist)
{
- List *tl;
- TargetEntry *param_tle, *tle;
- Param* p;
- int childno;
- char *resname;
-
- if (expression == NULL) return NULL;
-
- switch (nodeTag(expression)) {
- case T_Param:
- {
- /* the node is a parameter,
- substitute the entry from the target list of the child that
- corresponds to the parameter number*/
- p = (Param*)expression;
-
- /* we only deal with the case of numbered parameters */
- if (p->paramkind == PARAM_NUM) {
- /* paramid's start from 1*/
- childno = p->paramid - 1;
-
- if (p->param_tlist) {
- /* we have a parameter with an attribute like $N.foo
- so match the resname "foo" against the target list
- of the (N-1)th inputQlist */
-
- /* param tlist can only have one entry in them! */
- param_tle = (TargetEntry*)(lfirst(p->param_tlist));
- resname = param_tle->resdom->resname;
-
- if (inputQlist->qtrees[childno]) {
- foreach (tl, inputQlist->qtrees[childno]->targetList) {
- tle = lfirst(tl);
- if (strcmp(resname, tle->resdom->resname) == 0) {
- return tle->expr;
- }
- }
- }
- else {
- elog(WARN,"tg_rewriteParamsInExpr:can't substitute for parameter %d when that input is unconnected", p->paramid);
- }
-
- } else {
- /* we have $N without the .foo */
- /* use the first resdom in the targetlist of the */
- /* appropriate child query */
- tl = inputQlist->qtrees[childno]->targetList;
- tle = lfirst(tl);
- return tle->expr;
- }
- }
- else {
- elog(NOTICE, "tg_rewriteParamsInExpr: unexpected paramkind value of %d", p->paramkind);
- }
- }
- break;
- case T_Expr:
- {
- /* the node is an expression, we need to recursively
- call ourselves until we find parameter nodes */
- List *l;
- Expr *expr = (Expr*)expression;
- List *newArgs;
-
- /* we have to make a new args lists because Params
- can be replaced by Var nodes in tg_rewriteParamsInExpr()*/
- newArgs = NIL;
-
- /* we only care about argument to expressions,
- it doesn't matter when the opType is */
- /* recursively rewrite the arguments of this expression */
- foreach (l, expr->args) {
- newArgs = lappend(newArgs,
- tg_rewriteParamsInExpr(lfirst(l), inputQlist));
- }
- /* change the arguments of the expression */
- expr->args = newArgs;
- }
- break;
- default:
- {
- /* ignore other expr types */
- }
- }
-
- return expression;
+ List *tl;
+ TargetEntry *param_tle,
+ *tle;
+ Param *p;
+ int childno;
+ char *resname;
+
+ if (expression == NULL)
+ return NULL;
+
+ switch (nodeTag(expression))
+ {
+ case T_Param:
+ {
+
+ /*
+ * the node is a parameter, substitute the entry from the
+ * target list of the child that corresponds to the parameter
+ * number
+ */
+ p = (Param *) expression;
+
+ /* we only deal with the case of numbered parameters */
+ if (p->paramkind == PARAM_NUM)
+ {
+ /* paramid's start from 1 */
+ childno = p->paramid - 1;
+
+ if (p->param_tlist)
+ {
+
+ /*
+ * we have a parameter with an attribute like $N.foo
+ * so match the resname "foo" against the target list
+ * of the (N-1)th inputQlist
+ */
+
+ /* param tlist can only have one entry in them! */
+ param_tle = (TargetEntry *) (lfirst(p->param_tlist));
+ resname = param_tle->resdom->resname;
+
+ if (inputQlist->qtrees[childno])
+ {
+ foreach(tl, inputQlist->qtrees[childno]->targetList)
+ {
+ tle = lfirst(tl);
+ if (strcmp(resname, tle->resdom->resname) == 0)
+ {
+ return tle->expr;
+ }
+ }
+ }
+ else
+ {
+ elog(WARN, "tg_rewriteParamsInExpr:can't substitute for parameter %d when that input is unconnected", p->paramid);
+ }
+
+ }
+ else
+ {
+ /* we have $N without the .foo */
+ /* use the first resdom in the targetlist of the */
+ /* appropriate child query */
+ tl = inputQlist->qtrees[childno]->targetList;
+ tle = lfirst(tl);
+ return tle->expr;
+ }
+ }
+ else
+ {
+ elog(NOTICE, "tg_rewriteParamsInExpr: unexpected paramkind value of %d", p->paramkind);
+ }
+ }
+ break;
+ case T_Expr:
+ {
+
+ /*
+ * the node is an expression, we need to recursively call
+ * ourselves until we find parameter nodes
+ */
+ List *l;
+ Expr *expr = (Expr *) expression;
+ List *newArgs;
+
+ /*
+ * we have to make a new args lists because Params can be
+ * replaced by Var nodes in tg_rewriteParamsInExpr()
+ */
+ newArgs = NIL;
+
+ /*
+ * we only care about argument to expressions, it doesn't
+ * matter when the opType is
+ */
+ /* recursively rewrite the arguments of this expression */
+ foreach(l, expr->args)
+ {
+ newArgs = lappend(newArgs,
+ tg_rewriteParamsInExpr(lfirst(l), inputQlist));
+ }
+ /* change the arguments of the expression */
+ expr->args = newArgs;
+ }
+ break;
+ default:
+ {
+ /* ignore other expr types */
+ }
+ }
+
+ return expression;
}
/*
getParamTypes:
- given an element, finds its parameter types.
- the typev array argument is set to the parameter types.
- the parameterCount is returned
-
- this code is very similar to ProcedureDefine() in pg_proc.c
+ given an element, finds its parameter types.
+ the typev array argument is set to the parameter types.
+ the parameterCount is returned
+
+ this code is very similar to ProcedureDefine() in pg_proc.c
*/
static int
-getParamTypes (TgElement *elem, Oid typev[])
+getParamTypes(TgElement * elem, Oid typev[])
{
- /* this code is similar to ProcedureDefine() */
- int16 parameterCount;
- bool defined;
- Oid toid;
- char *t;
- int i,j;
-
- parameterCount = 0;
- for (i=0;i<8;i++) {
- typev[i] = 0;
- }
- for (j=0;j<elem->inTypes->num;j++) {
- if (parameterCount == 8) {
- elog(WARN,
- "getParamTypes: Ingredients cannot take > 8 arguments");
+ /* this code is similar to ProcedureDefine() */
+ int16 parameterCount;
+ bool defined;
+ Oid toid;
+ char *t;
+ int i,
+ j;
+
+ parameterCount = 0;
+ for (i = 0; i < 8; i++)
+ {
+ typev[i] = 0;
}
- t = elem->inTypes->val[j];
- if (strcmp(t,"opaque") == 0) {
- elog(WARN,
- "getParamTypes: Ingredient functions cannot take type 'opaque'");
- } else {
- toid = TypeGet(elem->inTypes->val[j], &defined);
- if (!OidIsValid(toid)) {
- elog(WARN, "getParamTypes: arg type '%s' is not defined",t);
- }
- if (!defined) {
- elog(NOTICE, "getParamTypes: arg type '%s' is only a shell",t);
- }
+ for (j = 0; j < elem->inTypes->num; j++)
+ {
+ if (parameterCount == 8)
+ {
+ elog(WARN,
+ "getParamTypes: Ingredients cannot take > 8 arguments");
+ }
+ t = elem->inTypes->val[j];
+ if (strcmp(t, "opaque") == 0)
+ {
+ elog(WARN,
+ "getParamTypes: Ingredient functions cannot take type 'opaque'");
+ }
+ else
+ {
+ toid = TypeGet(elem->inTypes->val[j], &defined);
+ if (!OidIsValid(toid))
+ {
+ elog(WARN, "getParamTypes: arg type '%s' is not defined", t);
+ }
+ if (!defined)
+ {
+ elog(NOTICE, "getParamTypes: arg type '%s' is only a shell", t);
+ }
+ }
+ typev[parameterCount++] = toid;
}
- typev[parameterCount++] = toid;
- }
- return parameterCount;
+ return parameterCount;
}
/*
* tg_parseTeeNode
- *
- * handles the parsing of the tee node
- *
+ *
+ * handles the parsing of the tee node
+ *
*
*/
-static QueryTreeList*
-tg_parseTeeNode(TgRecipe *r,
- TgNode *n, /* the tee node */
- int i, /* which input this node is to its parent */
- QueryTreeList *qList,
- TeeInfo* teeInfo)
+static QueryTreeList *
+tg_parseTeeNode(TgRecipe * r,
+ TgNode * n, /* the tee node */
+ int i, /* which input this node is to its parent */
+ QueryTreeList * qList,
+ TeeInfo * teeInfo)
{
- QueryTreeList *q;
- char* tt;
- int rt_ind;
- Query* orig;
-
- /* the input Node is a tee node, so we need to do the following:
- * we need to parse the child of the tee node,
- we add that to our query tree list
- * we need the name of the tee node table
- the tee node table is the table into which the tee node
- may materialize results. Call it TT
- * we add a range table to our existing query with TT in it
- * we need to replace the parameter $i with TT
- (otherwise the optimizer won't know to use the table
- on expression containining $i)
- After that rewrite, the optimizer will generate
- sequential scans of TT
-
- Later, in the glue phase, we replace all instances of TT
- sequential scans with the actual Tee node
- */
- q = tg_parseSubQuery(r,n, teeInfo);
-
- /* tt is the name of the tee node table */
- tt = n->nodeName;
-
- if (q)
- appendTeeQuery(teeInfo,q,tt);
-
- orig = qList->qtrees[0];
- rt_ind = RangeTablePosn(orig->rtable,tt);
- /* check to see that this table is not part of
- the range table already. This usually only
- happens if multiple inputs are connected to the
- same Tee. */
- if (rt_ind == 0) {
- orig->rtable = lappend(orig->rtable,
- addRangeTableEntry(NULL,
- tt,
- tt,
- FALSE,
- FALSE,
- NULL));
- rt_ind = length(orig->rtable);
- }
-
- orig->qual = tg_replaceNumberedParam(orig->qual,
- i+1, /* params start at 1*/
- rt_ind,
- tt);
- return qList;
+ QueryTreeList *q;
+ char *tt;
+ int rt_ind;
+ Query *orig;
+
+ /*
+ * the input Node is a tee node, so we need to do the following: we
+ * need to parse the child of the tee node, we add that to our query
+ * tree list we need the name of the tee node table the tee node table
+ * is the table into which the tee node may materialize results. Call
+ * it TT we add a range table to our existing query with TT in it we
+ * need to replace the parameter $i with TT (otherwise the optimizer
+ * won't know to use the table on expression containining $i) After
+ * that rewrite, the optimizer will generate sequential scans of TT
+ *
+ * Later, in the glue phase, we replace all instances of TT sequential
+ * scans with the actual Tee node
+ */
+ q = tg_parseSubQuery(r, n, teeInfo);
+
+ /* tt is the name of the tee node table */
+ tt = n->nodeName;
+
+ if (q)
+ appendTeeQuery(teeInfo, q, tt);
+
+ orig = qList->qtrees[0];
+ rt_ind = RangeTablePosn(orig->rtable, tt);
+
+ /*
+ * check to see that this table is not part of the range table
+ * already. This usually only happens if multiple inputs are
+ * connected to the same Tee.
+ */
+ if (rt_ind == 0)
+ {
+ orig->rtable = lappend(orig->rtable,
+ addRangeTableEntry(NULL,
+ tt,
+ tt,
+ FALSE,
+ FALSE,
+ NULL));
+ rt_ind = length(orig->rtable);
+ }
+
+ orig->qual = tg_replaceNumberedParam(orig->qual,
+ i + 1, /* params start at 1 */
+ rt_ind,
+ tt);
+ return qList;
}
/*
* tg_parseSubQuery:
- * go backwards from a node and parse the query
+ * go backwards from a node and parse the query
*
- * the result parse tree is passed back
- *
- * could return NULL if trying to parse a teeNode
+ * the result parse tree is passed back
+ *
+ * could return NULL if trying to parse a teeNode
* that's already been processed by another parent
- *
+ *
*/
-static QueryTreeList*
-tg_parseSubQuery(TgRecipe* r, TgNode* n, TeeInfo* teeInfo)
+static QueryTreeList *
+tg_parseSubQuery(TgRecipe * r, TgNode * n, TeeInfo * teeInfo)
{
- TgElement *elem;
- char* funcName;
- Oid typev[8]; /* eight arguments maximum */
- int i;
- int parameterCount;
-
- QueryTreeList *qList; /* the parse tree of the nodeElement */
- QueryTreeList *inputQlist; /* the list of parse trees for the
- inputs to this node */
- QueryTreeList *q;
- Oid relid;
- TgNode* child;
- Relation rel;
- unsigned int len;
- TupleDesc tupdesc;
-
- qList = NULL;
-
- if (n->nodeType == TG_INGRED_NODE) {
- /* parse each ingredient node in turn */
-
- elem = n->nodeElem;
- switch (elem->srcLang) {
- case TG_SQL:
- {
- /* for SQL ingredients, the SQL query is contained in the
- 'src' field */
+ TgElement *elem;
+ char *funcName;
+ Oid typev[8]; /* eight arguments maximum */
+ int i;
+ int parameterCount;
+
+ QueryTreeList *qList; /* the parse tree of the nodeElement */
+ QueryTreeList *inputQlist; /* the list of parse trees for the inputs
+ * to this node */
+ QueryTreeList *q;
+ Oid relid;
+ TgNode *child;
+ Relation rel;
+ unsigned int len;
+ TupleDesc tupdesc;
+
+ qList = NULL;
+
+ if (n->nodeType == TG_INGRED_NODE)
+ {
+ /* parse each ingredient node in turn */
+
+ elem = n->nodeElem;
+ switch (elem->srcLang)
+ {
+ case TG_SQL:
+ {
+
+ /*
+ * for SQL ingredients, the SQL query is contained in the
+ * 'src' field
+ */
#ifdef DEBUG_RECIPE
-elog(NOTICE,"calling parser with %s",elem->src);
-#endif /* DEBUG_RECIPE */
+ elog(NOTICE, "calling parser with %s", elem->src);
+#endif /* DEBUG_RECIPE */
- parameterCount = getParamTypes(elem,typev);
+ parameterCount = getParamTypes(elem, typev);
- qList = parser(elem->src,typev,parameterCount);
+ qList = parser(elem->src, typev, parameterCount);
- if (qList->len > 1) {
- elog(NOTICE,
- "tg_parseSubQuery: parser produced > 1 query tree");
- }
- }
- break;
- case TG_C:
- {
- /* C ingredients are registered functions in postgres */
- /* we create a new query string by using the function name
- (found in the 'src' field) and adding parameters to it
- so if the function was FOOBAR and took in two arguments,
- we would create a string
- select FOOBAR($1,$2)
- */
- char newquery[1000];
-
- funcName = elem->src;
- parameterCount = getParamTypes(elem,typev);
-
- if (parameterCount > 0) {
- int i;
- sprintf(newquery,"select %s($1",funcName);
- for (i=1;i<parameterCount;i++) {
- sprintf(newquery,"%s,$%d",newquery,i);
- }
- sprintf(newquery,"%s)",newquery);
- } else
- sprintf(newquery,"select %s()",funcName);
+ if (qList->len > 1)
+ {
+ elog(NOTICE,
+ "tg_parseSubQuery: parser produced > 1 query tree");
+ }
+ }
+ break;
+ case TG_C:
+ {
+ /* C ingredients are registered functions in postgres */
+
+ /*
+ * we create a new query string by using the function name
+ * (found in the 'src' field) and adding parameters to it
+ * so if the function was FOOBAR and took in two
+ * arguments, we would create a string select
+ * FOOBAR($1,$2)
+ */
+ char newquery[1000];
+
+ funcName = elem->src;
+ parameterCount = getParamTypes(elem, typev);
+
+ if (parameterCount > 0)
+ {
+ int i;
+
+ sprintf(newquery, "select %s($1", funcName);
+ for (i = 1; i < parameterCount; i++)
+ {
+ sprintf(newquery, "%s,$%d", newquery, i);
+ }
+ sprintf(newquery, "%s)", newquery);
+ }
+ else
+ sprintf(newquery, "select %s()", funcName);
#ifdef DEBUG_RECIPE
-elog(NOTICE,"calling parser with %s", newquery);
-#endif /* DEBUG_RECIPE */
+ elog(NOTICE, "calling parser with %s", newquery);
+#endif /* DEBUG_RECIPE */
+
+ qList = parser(newquery, typev, parameterCount);
+ if (qList->len > 1)
+ {
+ elog(NOTICE,
+ "tg_parseSubQuery: parser produced > 1 query tree");
+ }
+ }
+ break;
+ case TG_RECIPE_GRAPH:
+ elog(NOTICE, "tg_parseSubQuery: can't parse recipe graph ingredients yet!");
+ break;
+ case TG_COMPILED:
+ elog(NOTICE, "tg_parseSubQuery: can't parse compiled ingredients yet!");
+ break;
+ default:
+ elog(NOTICE, "tg_parseSubQuery: unknown srcLang: %d", elem->srcLang);
+ }
+
+ /* parse each of the subrecipes that are input to this node */
+
+ if (n->inNodes->num > 0)
+ {
+ inputQlist = malloc(sizeof(QueryTreeList));
+ inputQlist->len = n->inNodes->num + 1;
+ inputQlist->qtrees = (Query **) malloc(inputQlist->len * sizeof(Query *));
+ for (i = 0; i < n->inNodes->num; i++)
+ {
+
+ inputQlist->qtrees[i] = NULL;
+ if (n->inNodes->val[i])
+ {
+ if (n->inNodes->val[i]->nodeType == TG_TEE_NODE)
+ {
+ qList = tg_parseTeeNode(r, n->inNodes->val[i],
+ i, qList, teeInfo);
+ }
+ else
+ { /* input node is not a Tee */
+ q = tg_parseSubQuery(r, n->inNodes->val[i],
+ teeInfo);
+ Assert(q->len == 1);
+ inputQlist->qtrees[i] = q->qtrees[0];
+ }
+ }
+ }
- qList = parser(newquery,typev,parameterCount);
- if (qList->len > 1) {
- elog(NOTICE,
- "tg_parseSubQuery: parser produced > 1 query tree");
+ /* now, we have all the query trees from our input nodes */
+ /* transform the original parse tree appropriately */
+ tg_rewriteQuery(r, n, qList, inputQlist);
}
- }
- break;
- case TG_RECIPE_GRAPH:
- elog(NOTICE,"tg_parseSubQuery: can't parse recipe graph ingredients yet!");
- break;
- case TG_COMPILED:
- elog(NOTICE,"tg_parseSubQuery: can't parse compiled ingredients yet!");
- break;
- default:
- elog(NOTICE,"tg_parseSubQuery: unknown srcLang: %d",elem->srcLang);
}
+ else if (n->nodeType == TG_EYE_NODE)
+ {
- /* parse each of the subrecipes that are input to this node*/
-
- if (n->inNodes->num > 0) {
- inputQlist = malloc(sizeof(QueryTreeList));
- inputQlist->len = n->inNodes->num + 1 ;
- inputQlist->qtrees = (Query**)malloc(inputQlist->len * sizeof(Query*));
- for (i=0;i<n->inNodes->num;i++) {
-
- inputQlist->qtrees[i] = NULL;
- if (n->inNodes->val[i]) {
- if (n->inNodes->val[i]->nodeType == TG_TEE_NODE) {
- qList = tg_parseTeeNode(r,n->inNodes->val[i],
- i,qList,teeInfo);
- }
- else
- { /* input node is not a Tee */
- q = tg_parseSubQuery(r,n->inNodes->val[i],
- teeInfo);
- Assert (q->len == 1);
- inputQlist->qtrees[i] = q->qtrees[0];
- }
+ /*
+ * if we hit an eye, we need to stop and make what we have into a
+ * subrecipe query block
+ */
+ elog(NOTICE, "tg_parseSubQuery: can't handle eye nodes yet");
+ }
+ else if (n->nodeType == TG_TEE_NODE)
+ {
+
+ /*
+ * if we hit a tee, check to see if the parsing has been done for
+ * this tee already by the other parent
+ */
+
+ rel = RelationNameGetRelation(n->nodeName);
+ if (RelationIsValid(rel))
+ {
+
+ /*
+ * this tee has already been visited, no need to do any
+ * further processing
+ */
+ return NULL;
}
- }
+ else
+ {
+ /* we need to process the child of the tee first, */
+ child = n->inNodes->val[0];
+
+ if (child->nodeType == TG_TEE_NODE)
+ {
+ /* nested Tee nodes */
+ qList = tg_parseTeeNode(r, child, 0, qList, teeInfo);
+ return qList;
+ }
- /* now, we have all the query trees from our input nodes */
- /* transform the original parse tree appropriately */
- tg_rewriteQuery(r,n,qList,inputQlist);
+ Assert(child != NULL);
+
+ /* parse the input node */
+ q = tg_parseSubQuery(r, child, teeInfo);
+ Assert(q->len == 1);
+
+ /* add the parsed query to the main list of queries */
+ qList = appendQlist(qList, q);
+
+ /* need to create the tee table here */
+
+ /*
+ * the tee table created is used both for materializing the
+ * values at the tee node, and for parsing and optimization.
+ * The optimization needs to have a real table before it will
+ * consider scans on it
+ */
+
+ /*
+ * first, find the type of the tuples being produced by the
+ * tee. The type is the same as the output type of the child
+ * node.
+ *
+ * NOTE: we are assuming that the child node only has a single
+ * output here!
+ */
+ getParamTypes(child->nodeElem, typev);
+
+ /*
+ * the output type is either a complex type, (and is thus a
+ * relation) or is a simple type
+ */
+
+ rel = RelationNameGetRelation(child->nodeElem->outTypes->val[0]);
+
+ if (RelationIsValid(rel))
+ {
+
+ /*
+ * for complex types, create new relation with the same
+ * tuple descriptor as the output table type
+ */
+ len = length(q->qtrees[0]->targetList);
+ tupdesc = rel->rd_att;
+
+ relid = heap_create(child->nodeElem->outTypes->val[0],
+ NULL, /* XXX */
+ 'n',
+ DEFAULT_SMGR,
+ tupdesc);
+ }
+ else
+ {
+
+ /*
+ * we have to create a relation with one attribute of the
+ * simple base type. That attribute will have an attr
+ * name of "result"
+ */
+ /* NOTE: ignore array types for the time being */
+
+ len = 1;
+ tupdesc = CreateTemplateTupleDesc(len);
+
+ if (!TupleDescInitEntry(tupdesc, 1,
+ "result",
+ NULL,
+ 0, false))
+ {
+ elog(NOTICE, "tg_parseSubQuery: unexpected result from TupleDescInitEntry");
+ }
+ else
+ {
+ relid = heap_create(child->nodeElem->outTypes->val[0],
+ NULL, /* XXX */
+ 'n',
+ DEFAULT_SMGR,
+ tupdesc);
+ }
+ }
+ }
}
- }
- else if (n->nodeType == TG_EYE_NODE) {
- /* if we hit an eye, we need to stop and make what we have
- into a subrecipe query block*/
- elog(NOTICE,"tg_parseSubQuery: can't handle eye nodes yet");
- }
- else if (n->nodeType == TG_TEE_NODE) {
- /* if we hit a tee, check to see if the parsing has been done
- for this tee already by the other parent */
-
- rel = RelationNameGetRelation(n->nodeName);
- if (RelationIsValid(rel)) {
- /* this tee has already been visited,
- no need to do any further processing */
- return NULL;
- } else {
- /* we need to process the child of the tee first, */
- child = n->inNodes->val[0];
-
- if (child->nodeType == TG_TEE_NODE) {
- /* nested Tee nodes */
- qList = tg_parseTeeNode(r,child,0,qList,teeInfo);
- return qList;
- }
-
- Assert (child != NULL);
-
- /* parse the input node */
- q = tg_parseSubQuery(r,child, teeInfo);
- Assert (q->len == 1);
-
- /* add the parsed query to the main list of queries */
- qList = appendQlist(qList,q);
-
- /* need to create the tee table here */
- /* the tee table created is used both for materializing the values
- at the tee node, and for parsing and optimization.
- The optimization needs to have a real table before it will
- consider scans on it */
-
- /* first, find the type of the tuples being produced by the
- tee. The type is the same as the output type of
- the child node.
-
- NOTE: we are assuming that the child node only has a single
- output here! */
- getParamTypes(child->nodeElem,typev);
-
- /* the output type is either a complex type,
- (and is thus a relation) or is a simple type */
-
- rel = RelationNameGetRelation(child->nodeElem->outTypes->val[0]);
-
- if (RelationIsValid(rel)) {
- /* for complex types, create new relation with the same
- tuple descriptor as the output table type*/
- len = length(q->qtrees[0]->targetList);
- tupdesc = rel->rd_att;
-
- relid = heap_create(child->nodeElem->outTypes->val[0],
- NULL, /* XXX */
- 'n',
- DEFAULT_SMGR,
- tupdesc);
- }
- else {
- /* we have to create a relation with one attribute of
- the simple base type. That attribute will have
- an attr name of "result" */
- /*NOTE: ignore array types for the time being */
-
- len = 1;
- tupdesc = CreateTemplateTupleDesc(len);
-
- if ( !TupleDescInitEntry(tupdesc,1,
- "result",
- NULL,
- 0, false)) {
- elog(NOTICE,"tg_parseSubQuery: unexpected result from TupleDescInitEntry");
- } else {
- relid = heap_create(child->nodeElem->outTypes->val[0],
- NULL, /* XXX */
- 'n',
- DEFAULT_SMGR,
- tupdesc);
- }
- }
+ else if (n->nodeType == TG_RECIPE_NODE)
+ {
+ elog(NOTICE, "tg_parseSubQuery: can't handle embedded recipes yet!");
}
- }
- else if (n->nodeType == TG_RECIPE_NODE) {
- elog(NOTICE,"tg_parseSubQuery: can't handle embedded recipes yet!");
- } else
- elog (NOTICE, "unknown nodeType: %d", n->nodeType);
+ else
+ elog(NOTICE, "unknown nodeType: %d", n->nodeType);
- return qList;
+ return qList;
}
/*
* OffsetVarAttno -
- * recursively find all the var nodes with the specified varno
+ * recursively find all the var nodes with the specified varno
* and offset their varattno with the offset
- *
- * code is similar to OffsetVarNodes in rewriteManip.c
+ *
+ * code is similar to OffsetVarNodes in rewriteManip.c
*/
void
-OffsetVarAttno(Node* node, int varno, int offset)
+OffsetVarAttno(Node * node, int varno, int offset)
{
- if (node == NULL) return;
- switch (nodeTag(node)) {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
- OffsetVarAttno(tle->expr, varno, offset);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr*)node;
- OffsetVarAttno((Node*)expr->args, varno, offset);
- }
- break;
- case T_Var:
+ if (node == NULL)
+ return;
+ switch (nodeTag(node))
{
- Var *var = (Var*)node;
- if (var->varno == varno)
- var->varattno += offset;
- }
- break;
- case T_List:
- {
- List *l;
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ OffsetVarAttno(tle->expr, varno, offset);
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ OffsetVarAttno((Node *) expr->args, varno, offset);
+ }
+ break;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
- foreach(l, (List*)node) {
- OffsetVarAttno(lfirst(l), varno, offset);
- }
+ if (var->varno == varno)
+ var->varattno += offset;
+ }
+ break;
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ OffsetVarAttno(lfirst(l), varno, offset);
+ }
+ }
+ break;
+ default:
+ /* ignore the others */
+ break;
}
- break;
- default:
- /* ignore the others */
- break;
- }
}
/*
- * appendQlist
- * add the contents of a QueryTreeList q2 to the end of the QueryTreeList
- * q1
+ * appendQlist
+ * add the contents of a QueryTreeList q2 to the end of the QueryTreeList
+ * q1
*
- * returns a new querytree list
+ * returns a new querytree list
*/
-QueryTreeList*
-appendQlist(QueryTreeList *q1, QueryTreeList *q2)
+QueryTreeList *
+appendQlist(QueryTreeList * q1, QueryTreeList * q2)
{
- QueryTreeList* newq;
- int i,j;
- int newlen;
-
- if (q1 == NULL)
- return q2;
-
- if (q2 == NULL)
- return q1;
-
- newlen = q1->len + q2->len;
- newq = (QueryTreeList*)malloc(sizeof(QueryTreeList));
- newq->len = newlen;
- newq->qtrees = (Query**)malloc(newlen * sizeof(Query*));
- for (i=0;i<q1->len;i++)
- newq->qtrees[i] = q1->qtrees[i];
- for (j=0;j<q2->len;j++) {
- newq->qtrees[i + j] = q2->qtrees[j];
- }
- return newq;
+ QueryTreeList *newq;
+ int i,
+ j;
+ int newlen;
+
+ if (q1 == NULL)
+ return q2;
+
+ if (q2 == NULL)
+ return q1;
+
+ newlen = q1->len + q2->len;
+ newq = (QueryTreeList *) malloc(sizeof(QueryTreeList));
+ newq->len = newlen;
+ newq->qtrees = (Query **) malloc(newlen * sizeof(Query *));
+ for (i = 0; i < q1->len; i++)
+ newq->qtrees[i] = q1->qtrees[i];
+ for (j = 0; j < q2->len; j++)
+ {
+ newq->qtrees[i + j] = q2->qtrees[j];
+ }
+ return newq;
}
/*
- * appendTeeQuery
- *
- * modify the query field of the teeInfo list of the particular tee node
+ * appendTeeQuery
+ *
+ * modify the query field of the teeInfo list of the particular tee node
*/
static void
-appendTeeQuery(TeeInfo *teeInfo, QueryTreeList *q, char* teeNodeName)
+appendTeeQuery(TeeInfo * teeInfo, QueryTreeList * q, char *teeNodeName)
{
- int i;
-
- Assert(teeInfo);
+ int i;
- for (i=0;i<teeInfo->num;i++) {
- if ( strcmp(teeInfo->val[i].tpi_relName, teeNodeName) == 0) {
+ Assert(teeInfo);
+
+ for (i = 0; i < teeInfo->num; i++)
+ {
+ if (strcmp(teeInfo->val[i].tpi_relName, teeNodeName) == 0)
+ {
- Assert(q->len == 1);
- teeInfo->val[i].tpi_parsetree = q->qtrees[0];
- return;
+ Assert(q->len == 1);
+ teeInfo->val[i].tpi_parsetree = q->qtrees[0];
+ return;
+ }
}
- }
- elog(NOTICE, "appendTeeQuery: teeNodeName '%s' not found in teeInfo");
+ elog(NOTICE, "appendTeeQuery: teeNodeName '%s' not found in teeInfo");
}
/*
- * replaceSeqScan
- * replaces sequential scans of a specified relation with the tee plan
- * the relation is specified by its index in the range table, rt_ind
+ * replaceSeqScan
+ * replaces sequential scans of a specified relation with the tee plan
+ * the relation is specified by its index in the range table, rt_ind
*
* returns the modified plan
* the offset_attno is the offset that needs to be added to the parent's
* qual or targetlist because the child plan has been replaced with a tee node
*/
static void
-replaceSeqScan(Plan* plan, Plan* parent,
- int rt_ind, Plan* tplan)
+replaceSeqScan(Plan * plan, Plan * parent,
+ int rt_ind, Plan * tplan)
{
- Scan* snode;
- Tee* teePlan;
- Result* newPlan;
-
- if (plan == NULL) {
- return;
- }
-
- if (plan->type == T_SeqScan) {
- snode = (Scan*)plan;
- if (snode->scanrelid == rt_ind) {
- /* found the sequential scan that should be replaced
- with the tplan. */
- /* we replace the plan, but we also need to modify its parent*/
-
- /* replace the sequential scan with a Result node
- the reason we use a result node is so that we get the proper
- projection behavior. The Result node is simply (ab)used as
- a projection node */
-
- newPlan = makeNode(Result);
- newPlan->plan.cost = 0.0;
- newPlan->plan.state = (EState*)NULL;
- newPlan->plan.targetlist = plan->targetlist;
- newPlan->plan.lefttree = tplan;
- newPlan->plan.righttree = NULL;
- newPlan->resconstantqual = NULL;
- newPlan->resstate = NULL;
-
- /* change all the varno's to 1*/
- ChangeVarNodes((Node*)newPlan->plan.targetlist,
- snode->scanrelid, 1);
-
- if (parent) {
- teePlan = (Tee*)tplan;
-
- if (parent->lefttree == plan)
- parent->lefttree = (Plan*)newPlan;
- else
- parent->righttree = (Plan*)newPlan;
-
+ Scan *snode;
+ Tee *teePlan;
+ Result *newPlan;
- if (teePlan->leftParent == NULL)
- teePlan->leftParent = (Plan*)newPlan;
- else
- teePlan->rightParent = (Plan*)newPlan;
+ if (plan == NULL)
+ {
+ return;
+ }
+
+ if (plan->type == T_SeqScan)
+ {
+ snode = (Scan *) plan;
+ if (snode->scanrelid == rt_ind)
+ {
+
+ /*
+ * found the sequential scan that should be replaced with the
+ * tplan.
+ */
+ /* we replace the plan, but we also need to modify its parent */
+
+ /*
+ * replace the sequential scan with a Result node the reason
+ * we use a result node is so that we get the proper
+ * projection behavior. The Result node is simply (ab)used as
+ * a projection node
+ */
+
+ newPlan = makeNode(Result);
+ newPlan->plan.cost = 0.0;
+ newPlan->plan.state = (EState *) NULL;
+ newPlan->plan.targetlist = plan->targetlist;
+ newPlan->plan.lefttree = tplan;
+ newPlan->plan.righttree = NULL;
+ newPlan->resconstantqual = NULL;
+ newPlan->resstate = NULL;
+
+ /* change all the varno's to 1 */
+ ChangeVarNodes((Node *) newPlan->plan.targetlist,
+ snode->scanrelid, 1);
+
+ if (parent)
+ {
+ teePlan = (Tee *) tplan;
+
+ if (parent->lefttree == plan)
+ parent->lefttree = (Plan *) newPlan;
+ else
+ parent->righttree = (Plan *) newPlan;
+
+
+ if (teePlan->leftParent == NULL)
+ teePlan->leftParent = (Plan *) newPlan;
+ else
+ teePlan->rightParent = (Plan *) newPlan;
/* comment for now to test out executor-stuff
- if (parent->state) {
- ExecInitNode((Plan*)newPlan, parent->state, (Plan*)newPlan);
- }
+ if (parent->state) {
+ ExecInitNode((Plan*)newPlan, parent->state, (Plan*)newPlan);
+ }
*/
- }
- }
+ }
+ }
- } else {
- if (plan->lefttree) {
- replaceSeqScan(plan->lefttree, plan, rt_ind, tplan);
}
- if (plan->righttree) {
- replaceSeqScan(plan->righttree, plan, rt_ind, tplan);
+ else
+ {
+ if (plan->lefttree)
+ {
+ replaceSeqScan(plan->lefttree, plan, rt_ind, tplan);
+ }
+ if (plan->righttree)
+ {
+ replaceSeqScan(plan->righttree, plan, rt_ind, tplan);
+ }
}
- }
}
/*
- * replaceTeeScans
- * places the sequential scans of the Tee table with
+ * replaceTeeScans
+ * places the sequential scans of the Tee table with
* a connection to the actual tee plan node
*/
-static Plan*
-replaceTeeScans(Plan* plan, Query* parsetree, TeeInfo *teeInfo)
+static Plan *
+replaceTeeScans(Plan * plan, Query * parsetree, TeeInfo * teeInfo)
{
- int i;
- List* rtable;
- RangeTblEntry *rte;
- char prefix[5];
- int rt_ind;
- Plan* tplan;
-
- rtable = parsetree->rtable;
- if (rtable == NULL)
- return plan;
+ int i;
+ List *rtable;
+ RangeTblEntry *rte;
+ char prefix[5];
+ int rt_ind;
+ Plan *tplan;
+
+ rtable = parsetree->rtable;
+ if (rtable == NULL)
+ return plan;
+
+ /*
+ * look through the range table for the tee relation entry, that will
+ * give use the varno we need to detect which sequential scans need to
+ * be replaced with tee nodes
+ */
+
+ rt_ind = 0;
+ while (rtable != NIL)
+ {
+ rte = lfirst(rtable);
+ rtable = lnext(rtable);
+ rt_ind++; /* range table references in varno fields
+ * start w/ 1 */
+
+ /*
+ * look for the "tee_" prefix in the refname, also check to see
+ * that the relname and the refname are the same this should
+ * eliminate any user-specified table and leave us with the tee
+ * table entries only
+ */
+ if ((strlen(rte->refname) < 4) ||
+ (strcmp(rte->relname, rte->refname) != 0))
+ continue;
+ strNcpy(prefix, rte->refname, 4);
+ if (strcmp(prefix, "tee_") == 0)
+ {
+ /* okay, we found a tee node entry in the range table */
+
+ /* find the appropriate plan in the teeInfo list */
+ tplan = NULL;
+ for (i = 0; i < teeInfo->num; i++)
+ {
+ if (strcmp(teeInfo->val[i].tpi_relName,
+ rte->refname) == 0)
+ {
+ tplan = teeInfo->val[i].tpi_plan;
+ }
+ }
+ if (tplan == NULL)
+ {
+ elog(NOTICE, "replaceTeeScans didn't find the corresponding tee plan");
+ }
- /* look through the range table for the tee relation entry,
- that will give use the varno we need to detect which
- sequential scans need to be replaced with tee nodes*/
-
- rt_ind = 0;
- while (rtable != NIL) {
- rte = lfirst(rtable);
- rtable = lnext(rtable);
- rt_ind++; /* range table references in varno fields start w/ 1 */
-
- /* look for the "tee_" prefix in the refname,
- also check to see that the relname and the refname are the same
- this should eliminate any user-specified table and leave
- us with the tee table entries only*/
- if ((strlen(rte->refname) < 4) ||
- (strcmp (rte->relname, rte->refname) != 0))
- continue;
- strNcpy(prefix,rte->refname,4);
- if (strcmp(prefix,"tee_") == 0) {
- /* okay, we found a tee node entry in the range table */
-
- /* find the appropriate plan in the teeInfo list */
- tplan = NULL;
- for (i=0;i<teeInfo->num;i++) {
- if (strcmp(teeInfo->val[i].tpi_relName,
- rte->refname) == 0) {
- tplan = teeInfo->val[i].tpi_plan;
+ /*
+ * replace the sequential scan node with that var number with
+ * the tee plan node
+ */
+ replaceSeqScan(plan, NULL, rt_ind, tplan);
}
- }
- if (tplan == NULL) {
- elog(NOTICE, "replaceTeeScans didn't find the corresponding tee plan"); }
-
- /* replace the sequential scan node with that var number
- with the tee plan node */
- replaceSeqScan(plan, NULL, rt_ind, tplan);
}
- }
- return plan;
+ return plan;
}
-#endif /* TIOGA */
+#endif /* TIOGA */
diff --git a/src/backend/commands/remove.c b/src/backend/commands/remove.c
index 7f0198a10b7..cafe4d09710 100644
--- a/src/backend/commands/remove.c
+++ b/src/backend/commands/remove.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* remove.c--
- * POSTGRES remove (function | type | operator ) utilty code.
+ * POSTGRES remove (function | type | operator ) utilty code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.10 1997/08/18 20:52:17 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.11 1997/09/07 04:40:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,100 +28,112 @@
#include <storage/bufmgr.h>
#include <fmgr.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
/*
* RemoveOperator --
- * Deletes an operator.
+ * Deletes an operator.
*
* Exceptions:
- * BadArg if name is invalid.
- * BadArg if type1 is invalid.
- * "WARN" if operator nonexistent.
- * ...
+ * BadArg if name is invalid.
+ * BadArg if type1 is invalid.
+ * "WARN" if operator nonexistent.
+ * ...
*/
void
-RemoveOperator(char *operatorName, /* operator name */
- char *typeName1, /* first type name */
- char *typeName2) /* optional second type name */
+RemoveOperator(char *operatorName, /* operator name */
+ char *typeName1, /* first type name */
+ char *typeName2) /* optional second type name */
{
- Relation relation;
- HeapScanDesc scan;
- HeapTuple tup;
- Oid typeId1 = InvalidOid;
- Oid typeId2 = InvalidOid;
- bool defined;
- ItemPointerData itemPointerData;
- Buffer buffer;
- ScanKeyData operatorKey[3];
- char *userName;
-
- if (typeName1) {
- typeId1 = TypeGet(typeName1, &defined);
- if (!OidIsValid(typeId1)) {
- elog(WARN, "RemoveOperator: type '%s' does not exist", typeName1);
- return;
+ Relation relation;
+ HeapScanDesc scan;
+ HeapTuple tup;
+ Oid typeId1 = InvalidOid;
+ Oid typeId2 = InvalidOid;
+ bool defined;
+ ItemPointerData itemPointerData;
+ Buffer buffer;
+ ScanKeyData operatorKey[3];
+ char *userName;
+
+ if (typeName1)
+ {
+ typeId1 = TypeGet(typeName1, &defined);
+ if (!OidIsValid(typeId1))
+ {
+ elog(WARN, "RemoveOperator: type '%s' does not exist", typeName1);
+ return;
+ }
}
- }
-
- if (typeName2) {
- typeId2 = TypeGet(typeName2, &defined);
- if (!OidIsValid(typeId2)) {
- elog(WARN, "RemoveOperator: type '%s' does not exist", typeName2);
- return;
+
+ if (typeName2)
+ {
+ typeId2 = TypeGet(typeName2, &defined);
+ if (!OidIsValid(typeId2))
+ {
+ elog(WARN, "RemoveOperator: type '%s' does not exist", typeName2);
+ return;
+ }
}
- }
-
- ScanKeyEntryInitialize(&operatorKey[0], 0x0,
- Anum_pg_operator_oprname,
- NameEqualRegProcedure,
- PointerGetDatum(operatorName));
-
- ScanKeyEntryInitialize(&operatorKey[1], 0x0,
- Anum_pg_operator_oprleft,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(typeId1));
-
- ScanKeyEntryInitialize(&operatorKey[2], 0x0,
- Anum_pg_operator_oprright,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(typeId2));
-
- relation = heap_openr(OperatorRelationName);
- scan = heap_beginscan(relation, 0, NowTimeQual, 3, operatorKey);
- tup = heap_getnext(scan, 0, &buffer);
- if (HeapTupleIsValid(tup)) {
+
+ ScanKeyEntryInitialize(&operatorKey[0], 0x0,
+ Anum_pg_operator_oprname,
+ NameEqualRegProcedure,
+ PointerGetDatum(operatorName));
+
+ ScanKeyEntryInitialize(&operatorKey[1], 0x0,
+ Anum_pg_operator_oprleft,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(typeId1));
+
+ ScanKeyEntryInitialize(&operatorKey[2], 0x0,
+ Anum_pg_operator_oprright,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(typeId2));
+
+ relation = heap_openr(OperatorRelationName);
+ scan = heap_beginscan(relation, 0, NowTimeQual, 3, operatorKey);
+ tup = heap_getnext(scan, 0, &buffer);
+ if (HeapTupleIsValid(tup))
+ {
#ifndef NO_SECURITY
- userName = GetPgUserName();
- if (!pg_ownercheck(userName,
- (char *) ObjectIdGetDatum(tup->t_oid),
- OPROID))
- elog(WARN, "RemoveOperator: operator '%s': permission denied",
- operatorName);
+ userName = GetPgUserName();
+ if (!pg_ownercheck(userName,
+ (char *) ObjectIdGetDatum(tup->t_oid),
+ OPROID))
+ elog(WARN, "RemoveOperator: operator '%s': permission denied",
+ operatorName);
#endif
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
- heap_delete(relation, &itemPointerData);
- } else {
- if (OidIsValid(typeId1) && OidIsValid(typeId2)) {
- elog(WARN, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist",
- operatorName,
- typeName1,
- typeName2);
- } else if (OidIsValid(typeId1)) {
- elog(WARN, "RemoveOperator: right unary operator '%s' taking '%s' does not exist",
- operatorName,
- typeName1);
- } else {
- elog(WARN, "RemoveOperator: left unary operator '%s' taking '%s' does not exist",
- operatorName,
- typeName2);
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+ heap_delete(relation, &itemPointerData);
}
- }
- heap_endscan(scan);
- heap_close(relation);
+ else
+ {
+ if (OidIsValid(typeId1) && OidIsValid(typeId2))
+ {
+ elog(WARN, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist",
+ operatorName,
+ typeName1,
+ typeName2);
+ }
+ else if (OidIsValid(typeId1))
+ {
+ elog(WARN, "RemoveOperator: right unary operator '%s' taking '%s' does not exist",
+ operatorName,
+ typeName1);
+ }
+ else
+ {
+ elog(WARN, "RemoveOperator: left unary operator '%s' taking '%s' does not exist",
+ operatorName,
+ typeName2);
+ }
+ }
+ heap_endscan(scan);
+ heap_close(relation);
}
#ifdef NOTYET
@@ -130,353 +142,379 @@ RemoveOperator(char *operatorName, /* operator name */
* don't use it - pma 2/1/94
*/
/*
- * SingleOpOperatorRemove
- * Removes all operators that have operands or a result of type 'typeOid'.
+ * SingleOpOperatorRemove
+ * Removes all operators that have operands or a result of type 'typeOid'.
*/
static void
SingleOpOperatorRemove(Oid typeOid)
{
- Relation rdesc;
- ScanKeyData key[3];
- HeapScanDesc sdesc;
- HeapTuple tup;
- ItemPointerData itemPointerData;
- Buffer buffer;
- static attnums[3] = { 7, 8, 9 }; /* left, right, return */
- register i;
-
- ScanKeyEntryInitialize(&key[0],
- 0, 0, ObjectIdEqualRegProcedure, (Datum)typeOid);
- rdesc = heap_openr(OperatorRelationName);
- for (i = 0; i < 3; ++i) {
- key[0].sk_attno = attnums[i];
- sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
- while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer))) {
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
- /* XXX LOCK not being passed */
- heap_delete(rdesc, &itemPointerData);
+ Relation rdesc;
+ ScanKeyData key[3];
+ HeapScanDesc sdesc;
+ HeapTuple tup;
+ ItemPointerData itemPointerData;
+ Buffer buffer;
+ static attnums[3] = {7, 8, 9}; /* left, right, return */
+ register i;
+
+ ScanKeyEntryInitialize(&key[0],
+ 0, 0, ObjectIdEqualRegProcedure, (Datum) typeOid);
+ rdesc = heap_openr(OperatorRelationName);
+ for (i = 0; i < 3; ++i)
+ {
+ key[0].sk_attno = attnums[i];
+ sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
+ while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer)))
+ {
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+ /* XXX LOCK not being passed */
+ heap_delete(rdesc, &itemPointerData);
+ }
+ heap_endscan(sdesc);
}
- heap_endscan(sdesc);
- }
- heap_close(rdesc);
+ heap_close(rdesc);
}
/*
- * AttributeAndRelationRemove
- * Removes all entries in the attribute and relation relations
- * that contain entries of type 'typeOid'.
- * Currently nothing calls this code, it is untested.
+ * AttributeAndRelationRemove
+ * Removes all entries in the attribute and relation relations
+ * that contain entries of type 'typeOid'.
+ * Currently nothing calls this code, it is untested.
*/
static void
AttributeAndRelationRemove(Oid typeOid)
{
- struct oidlist {
- Oid reloid;
- struct oidlist *next;
- };
- struct oidlist *oidptr, *optr;
- Relation rdesc;
- ScanKeyData key[1];
- HeapScanDesc sdesc;
- HeapTuple tup;
- ItemPointerData itemPointerData;
- Buffer buffer;
-
- /*
- * Get the oid's of the relations to be removed by scanning the
- * entire attribute relation.
- * We don't need to remove the attributes here,
- * because amdestroy will remove all attributes of the relation.
- * XXX should check for duplicate relations
- */
-
- ScanKeyEntryInitialize(&key[0],
- 0, 3, ObjectIdEqualRegProcedure, (Datum)typeOid);
-
- oidptr = (struct oidlist *) palloc(sizeof(*oidptr));
- oidptr->next = NULL;
- optr = oidptr;
- rdesc = heap_openr(AttributeRelationName);
- sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
- while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer))) {
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
- optr->reloid = ((AttributeTupleForm)GETSTRUCT(tup))->attrelid;
- optr->next = (struct oidlist *) palloc(sizeof(*oidptr));
- optr = optr->next;
- }
- optr->next = NULL;
- heap_endscan(sdesc);
- heap_close(rdesc);
-
-
- ScanKeyEntryInitialize(&key[0], 0,
- ObjectIdAttributeNumber,
- ObjectIdEqualRegProcedure, (Datum)0);
- optr = oidptr;
- rdesc = heap_openr(RelationRelationName);
- while (PointerIsValid((char *) optr->next)) {
- key[0].sk_argument = (Datum) (optr++)->reloid;
+ struct oidlist
+ {
+ Oid reloid;
+ struct oidlist *next;
+ };
+ struct oidlist *oidptr,
+ *optr;
+ Relation rdesc;
+ ScanKeyData key[1];
+ HeapScanDesc sdesc;
+ HeapTuple tup;
+ ItemPointerData itemPointerData;
+ Buffer buffer;
+
+ /*
+ * Get the oid's of the relations to be removed by scanning the entire
+ * attribute relation. We don't need to remove the attributes here,
+ * because amdestroy will remove all attributes of the relation. XXX
+ * should check for duplicate relations
+ */
+
+ ScanKeyEntryInitialize(&key[0],
+ 0, 3, ObjectIdEqualRegProcedure, (Datum) typeOid);
+
+ oidptr = (struct oidlist *) palloc(sizeof(*oidptr));
+ oidptr->next = NULL;
+ optr = oidptr;
+ rdesc = heap_openr(AttributeRelationName);
sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
- tup = heap_getnext(sdesc, 0, &buffer);
- if (PointerIsValid(tup)) {
- char *name;
-
- name = (((Form_pg_class)GETSTRUCT(tup))->relname).data;
- heap_destroy(name);
+ while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer)))
+ {
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+ optr->reloid = ((AttributeTupleForm) GETSTRUCT(tup))->attrelid;
+ optr->next = (struct oidlist *) palloc(sizeof(*oidptr));
+ optr = optr->next;
}
- }
- heap_endscan(sdesc);
- heap_close(rdesc);
+ optr->next = NULL;
+ heap_endscan(sdesc);
+ heap_close(rdesc);
+
+
+ ScanKeyEntryInitialize(&key[0], 0,
+ ObjectIdAttributeNumber,
+ ObjectIdEqualRegProcedure, (Datum) 0);
+ optr = oidptr;
+ rdesc = heap_openr(RelationRelationName);
+ while (PointerIsValid((char *) optr->next))
+ {
+ key[0].sk_argument = (Datum) (optr++)->reloid;
+ sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
+ tup = heap_getnext(sdesc, 0, &buffer);
+ if (PointerIsValid(tup))
+ {
+ char *name;
+
+ name = (((Form_pg_class) GETSTRUCT(tup))->relname).data;
+ heap_destroy(name);
+ }
+ }
+ heap_endscan(sdesc);
+ heap_close(rdesc);
}
-#endif /* NOTYET */
+
+#endif /* NOTYET */
/*
- * TypeRemove
- * Removes the type 'typeName' and all attributes and relations that
- * use it.
+ * TypeRemove
+ * Removes the type 'typeName' and all attributes and relations that
+ * use it.
*/
void
-RemoveType(char *typeName) /* type name to be removed */
+RemoveType(char *typeName) /* type name to be removed */
{
- Relation relation;
- HeapScanDesc scan;
- HeapTuple tup;
- Oid typeOid;
- ItemPointerData itemPointerData;
- static ScanKeyData typeKey[1] = {
- { 0, Anum_pg_type_typname, NameEqualRegProcedure }
- };
- char *shadow_type;
- char *userName;
-
+ Relation relation;
+ HeapScanDesc scan;
+ HeapTuple tup;
+ Oid typeOid;
+ ItemPointerData itemPointerData;
+ static ScanKeyData typeKey[1] = {
+ {0, Anum_pg_type_typname, NameEqualRegProcedure}
+ };
+ char *shadow_type;
+ char *userName;
+
#ifndef NO_SECURITY
- userName = GetPgUserName();
- if (!pg_ownercheck(userName, typeName, TYPNAME))
- elog(WARN, "RemoveType: type '%s': permission denied",
- typeName);
+ userName = GetPgUserName();
+ if (!pg_ownercheck(userName, typeName, TYPNAME))
+ elog(WARN, "RemoveType: type '%s': permission denied",
+ typeName);
#endif
-
- relation = heap_openr(TypeRelationName);
- fmgr_info(typeKey[0].sk_procedure, &typeKey[0].sk_func,
- &typeKey[0].sk_nargs);
-
- /* Delete the primary type */
-
- typeKey[0].sk_argument = PointerGetDatum(typeName);
-
- scan = heap_beginscan(relation, 0, NowTimeQual, 1, typeKey);
- tup = heap_getnext(scan, 0, (Buffer *) 0);
- if (!HeapTupleIsValid(tup)) {
+
+ relation = heap_openr(TypeRelationName);
+ fmgr_info(typeKey[0].sk_procedure, &typeKey[0].sk_func,
+ &typeKey[0].sk_nargs);
+
+ /* Delete the primary type */
+
+ typeKey[0].sk_argument = PointerGetDatum(typeName);
+
+ scan = heap_beginscan(relation, 0, NowTimeQual, 1, typeKey);
+ tup = heap_getnext(scan, 0, (Buffer *) 0);
+ if (!HeapTupleIsValid(tup))
+ {
+ heap_endscan(scan);
+ heap_close(relation);
+ elog(WARN, "RemoveType: type '%s' does not exist",
+ typeName);
+ }
+ typeOid = tup->t_oid;
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+ heap_delete(relation, &itemPointerData);
heap_endscan(scan);
- heap_close(relation);
- elog(WARN, "RemoveType: type '%s' does not exist",
- typeName);
- }
- typeOid = tup->t_oid;
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
- heap_delete(relation, &itemPointerData);
- heap_endscan(scan);
-
- /* Now, Delete the "array of" that type */
- shadow_type = makeArrayTypeName(typeName);
- typeKey[0].sk_argument = NameGetDatum(shadow_type);
-
- scan = heap_beginscan(relation, 0, NowTimeQual,
- 1, (ScanKey) typeKey);
- tup = heap_getnext(scan, 0, (Buffer *) 0);
-
- if (!HeapTupleIsValid(tup))
+
+ /* Now, Delete the "array of" that type */
+ shadow_type = makeArrayTypeName(typeName);
+ typeKey[0].sk_argument = NameGetDatum(shadow_type);
+
+ scan = heap_beginscan(relation, 0, NowTimeQual,
+ 1, (ScanKey) typeKey);
+ tup = heap_getnext(scan, 0, (Buffer *) 0);
+
+ if (!HeapTupleIsValid(tup))
{
- elog(WARN, "RemoveType: type '%s': array stub not found",
- typeName);
+ elog(WARN, "RemoveType: type '%s': array stub not found",
+ typeName);
}
- typeOid = tup->t_oid;
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
- heap_delete(relation, &itemPointerData);
- heap_endscan(scan);
-
- heap_close(relation);
+ typeOid = tup->t_oid;
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+ heap_delete(relation, &itemPointerData);
+ heap_endscan(scan);
+
+ heap_close(relation);
}
/*
* RemoveFunction --
- * Deletes a function.
+ * Deletes a function.
*
* Exceptions:
- * BadArg if name is invalid.
- * "WARN" if function nonexistent.
- * ...
+ * BadArg if name is invalid.
+ * "WARN" if function nonexistent.
+ * ...
*/
void
-RemoveFunction(char *functionName, /* function name to be removed */
- int nargs,
- List *argNameList /* list of TypeNames */)
+RemoveFunction(char *functionName, /* function name to be removed */
+ int nargs,
+ List * argNameList /* list of TypeNames */ )
{
- Relation relation;
- HeapScanDesc scan;
- HeapTuple tup;
- Buffer buffer = InvalidBuffer;
- bool bufferUsed = FALSE;
- Oid argList[8];
- Form_pg_proc the_proc = NULL;
- ItemPointerData itemPointerData;
- static ScanKeyData key[3] = {
- { 0, Anum_pg_proc_proname, NameEqualRegProcedure }
- };
- char *userName;
- char *typename;
- int i;
-
- memset(argList, 0, 8 * sizeof(Oid));
- for (i=0; i<nargs; i++) {
-/* typename = ((TypeName*)(lfirst(argNameList)))->name; */
- typename = strVal(lfirst(argNameList));
- argNameList = lnext(argNameList);
-
- if (strcmp(typename, "opaque") == 0)
- argList[i] = 0;
- else {
- tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(typename),
- 0,0,0);
-
- if (!HeapTupleIsValid(tup)) {
- elog(WARN, "RemoveFunction: type '%s' not found",typename);
- }
- argList[i] = tup->t_oid;
+ Relation relation;
+ HeapScanDesc scan;
+ HeapTuple tup;
+ Buffer buffer = InvalidBuffer;
+ bool bufferUsed = FALSE;
+ Oid argList[8];
+ Form_pg_proc the_proc = NULL;
+ ItemPointerData itemPointerData;
+ static ScanKeyData key[3] = {
+ {0, Anum_pg_proc_proname, NameEqualRegProcedure}
+ };
+ char *userName;
+ char *typename;
+ int i;
+
+ memset(argList, 0, 8 * sizeof(Oid));
+ for (i = 0; i < nargs; i++)
+ {
+/* typename = ((TypeName*)(lfirst(argNameList)))->name; */
+ typename = strVal(lfirst(argNameList));
+ argNameList = lnext(argNameList);
+
+ if (strcmp(typename, "opaque") == 0)
+ argList[i] = 0;
+ else
+ {
+ tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(typename),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup))
+ {
+ elog(WARN, "RemoveFunction: type '%s' not found", typename);
+ }
+ argList[i] = tup->t_oid;
+ }
}
- }
-
- tup = SearchSysCacheTuple(PRONAME, PointerGetDatum(functionName),
- Int32GetDatum(nargs),
- PointerGetDatum(argList),0);
- if (!HeapTupleIsValid(tup))
- func_error("RemoveFunction", functionName, nargs, argList);
-
+
+ tup = SearchSysCacheTuple(PRONAME, PointerGetDatum(functionName),
+ Int32GetDatum(nargs),
+ PointerGetDatum(argList), 0);
+ if (!HeapTupleIsValid(tup))
+ func_error("RemoveFunction", functionName, nargs, argList);
+
#ifndef NO_SECURITY
- userName = GetPgUserName();
- if (!pg_func_ownercheck(userName, functionName, nargs, argList)) {
- elog(WARN, "RemoveFunction: function '%s': permission denied",
- functionName);
- }
-#endif
-
- key[0].sk_argument = PointerGetDatum(functionName);
-
- fmgr_info(key[0].sk_procedure, &key[0].sk_func, &key[0].sk_nargs);
-
- relation = heap_openr(ProcedureRelationName);
- scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
-
- do { /* hope this is ok because it's indexed */
- if (bufferUsed) {
- ReleaseBuffer(buffer);
- bufferUsed = FALSE;
+ userName = GetPgUserName();
+ if (!pg_func_ownercheck(userName, functionName, nargs, argList))
+ {
+ elog(WARN, "RemoveFunction: function '%s': permission denied",
+ functionName);
}
- tup = heap_getnext(scan, 0, (Buffer *) &buffer);
- if (!HeapTupleIsValid(tup))
- break;
- bufferUsed = TRUE;
- the_proc = (Form_pg_proc) GETSTRUCT(tup);
- } while ( (namestrcmp(&(the_proc->proname), functionName) == 0) &&
- (the_proc->pronargs != nargs ||
- !oid8eq(&(the_proc->proargtypes[0]), &argList[0])));
-
-
- if (!HeapTupleIsValid(tup) || namestrcmp(&(the_proc->proname),
- functionName) != 0)
- {
- heap_endscan(scan);
- heap_close(relation);
- func_error("RemoveFunction", functionName,nargs, argList);
+#endif
+
+ key[0].sk_argument = PointerGetDatum(functionName);
+
+ fmgr_info(key[0].sk_procedure, &key[0].sk_func, &key[0].sk_nargs);
+
+ relation = heap_openr(ProcedureRelationName);
+ scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
+
+ do
+ { /* hope this is ok because it's indexed */
+ if (bufferUsed)
+ {
+ ReleaseBuffer(buffer);
+ bufferUsed = FALSE;
+ }
+ tup = heap_getnext(scan, 0, (Buffer *) & buffer);
+ if (!HeapTupleIsValid(tup))
+ break;
+ bufferUsed = TRUE;
+ the_proc = (Form_pg_proc) GETSTRUCT(tup);
+ } while ((namestrcmp(&(the_proc->proname), functionName) == 0) &&
+ (the_proc->pronargs != nargs ||
+ !oid8eq(&(the_proc->proargtypes[0]), &argList[0])));
+
+
+ if (!HeapTupleIsValid(tup) || namestrcmp(&(the_proc->proname),
+ functionName) != 0)
+ {
+ heap_endscan(scan);
+ heap_close(relation);
+ func_error("RemoveFunction", functionName, nargs, argList);
}
-
- /* ok, function has been found */
-
- if (the_proc->prolang == INTERNALlanguageId)
- elog(WARN, "RemoveFunction: function \"%s\" is built-in",
- functionName);
-
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
- heap_delete(relation, &itemPointerData);
- heap_endscan(scan);
- heap_close(relation);
+
+ /* ok, function has been found */
+
+ if (the_proc->prolang == INTERNALlanguageId)
+ elog(WARN, "RemoveFunction: function \"%s\" is built-in",
+ functionName);
+
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+ heap_delete(relation, &itemPointerData);
+ heap_endscan(scan);
+ heap_close(relation);
}
void
RemoveAggregate(char *aggName, char *aggType)
{
- Relation relation;
- HeapScanDesc scan;
- HeapTuple tup;
- ItemPointerData itemPointerData;
- char *userName;
- Oid basetypeID = InvalidOid;
- bool defined;
- ScanKeyData aggregateKey[3];
-
-
- /*
- * if a basetype is passed in, then attempt to find an aggregate for that
- * specific type.
- *
- * else if the basetype is blank, then attempt to find an aggregate with a
- * basetype of zero. This is valid. It means that the aggregate is to apply
- * to all basetypes. ie, a counter of some sort.
- *
- */
-
- if (aggType) {
- basetypeID = TypeGet(aggType, &defined);
- if (!OidIsValid(basetypeID)) {
- elog(WARN, "RemoveAggregate: type '%s' does not exist", aggType);
- }
- } else {
- basetypeID = 0;
- }
+ Relation relation;
+ HeapScanDesc scan;
+ HeapTuple tup;
+ ItemPointerData itemPointerData;
+ char *userName;
+ Oid basetypeID = InvalidOid;
+ bool defined;
+ ScanKeyData aggregateKey[3];
+
+
+ /*
+ * if a basetype is passed in, then attempt to find an aggregate for
+ * that specific type.
+ *
+ * else if the basetype is blank, then attempt to find an aggregate with
+ * a basetype of zero. This is valid. It means that the aggregate is
+ * to apply to all basetypes. ie, a counter of some sort.
+ *
+ */
+
+ if (aggType)
+ {
+ basetypeID = TypeGet(aggType, &defined);
+ if (!OidIsValid(basetypeID))
+ {
+ elog(WARN, "RemoveAggregate: type '%s' does not exist", aggType);
+ }
+ }
+ else
+ {
+ basetypeID = 0;
+ }
/*
#ifndef NO_SECURITY
*/
- userName = GetPgUserName();
- if (!pg_aggr_ownercheck(userName, aggName, basetypeID)) {
- if (aggType) {
- elog(WARN, "RemoveAggregate: aggregate '%s' on type '%s': permission denied",
- aggName, aggType);
- } else {
- elog(WARN, "RemoveAggregate: aggregate '%s': permission denied",
- aggName);
- }
- }
+ userName = GetPgUserName();
+ if (!pg_aggr_ownercheck(userName, aggName, basetypeID))
+ {
+ if (aggType)
+ {
+ elog(WARN, "RemoveAggregate: aggregate '%s' on type '%s': permission denied",
+ aggName, aggType);
+ }
+ else
+ {
+ elog(WARN, "RemoveAggregate: aggregate '%s': permission denied",
+ aggName);
+ }
+ }
/*
#endif
*/
- ScanKeyEntryInitialize(&aggregateKey[0], 0x0,
- Anum_pg_aggregate_aggname,
- NameEqualRegProcedure,
- PointerGetDatum(aggName));
-
- ScanKeyEntryInitialize(&aggregateKey[1], 0x0,
- Anum_pg_aggregate_aggbasetype,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(basetypeID));
-
- relation = heap_openr(AggregateRelationName);
- scan = heap_beginscan(relation, 0, NowTimeQual, 2, aggregateKey);
- tup = heap_getnext(scan, 0, (Buffer *) 0);
- if (!HeapTupleIsValid(tup)) {
- heap_endscan(scan);
- heap_close(relation);
- if (aggType) {
- elog(WARN, "RemoveAggregate: aggregate '%s' for '%s' does not exist",
- aggName, aggType);
- } else {
- elog(WARN, "RemoveAggregate: aggregate '%s' for all types does not exist",
- aggName);
- }
- }
- ItemPointerCopy(&tup->t_ctid, &itemPointerData);
- heap_delete(relation, &itemPointerData);
- heap_endscan(scan);
- heap_close(relation);
+ ScanKeyEntryInitialize(&aggregateKey[0], 0x0,
+ Anum_pg_aggregate_aggname,
+ NameEqualRegProcedure,
+ PointerGetDatum(aggName));
+
+ ScanKeyEntryInitialize(&aggregateKey[1], 0x0,
+ Anum_pg_aggregate_aggbasetype,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(basetypeID));
+
+ relation = heap_openr(AggregateRelationName);
+ scan = heap_beginscan(relation, 0, NowTimeQual, 2, aggregateKey);
+ tup = heap_getnext(scan, 0, (Buffer *) 0);
+ if (!HeapTupleIsValid(tup))
+ {
+ heap_endscan(scan);
+ heap_close(relation);
+ if (aggType)
+ {
+ elog(WARN, "RemoveAggregate: aggregate '%s' for '%s' does not exist",
+ aggName, aggType);
+ }
+ else
+ {
+ elog(WARN, "RemoveAggregate: aggregate '%s' for all types does not exist",
+ aggName);
+ }
+ }
+ ItemPointerCopy(&tup->t_ctid, &itemPointerData);
+ heap_delete(relation, &itemPointerData);
+ heap_endscan(scan);
+ heap_close(relation);
}
diff --git a/src/backend/commands/rename.c b/src/backend/commands/rename.c
index 5d4e4ab2bb8..9b8df698346 100644
--- a/src/backend/commands/rename.c
+++ b/src/backend/commands/rename.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rename.c--
- * renameatt() and renamerel() reside here.
+ * renameatt() and renamerel() reside here.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.7 1997/08/18 20:52:18 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.8 1997/09/07 04:40:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,227 +32,246 @@
#include <catalog/pg_proc.h>
#include <catalog/pg_class.h>
#include <optimizer/internal.h>
-#include <optimizer/prep.h> /* for find_all_inheritors */
+#include <optimizer/prep.h> /* for find_all_inheritors */
#ifndef NO_SECURITY
-# include <utils/acl.h>
-#endif /* !NO_SECURITY */
+#include <utils/acl.h>
+#endif /* !NO_SECURITY */
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
/*
- * renameatt - changes the name of a attribute in a relation
+ * renameatt - changes the name of a attribute in a relation
*
- * Attname attribute is changed in attribute catalog.
- * No record of the previous attname is kept (correct?).
+ * Attname attribute is changed in attribute catalog.
+ * No record of the previous attname is kept (correct?).
*
- * get proper reldesc from relation catalog (if not arg)
- * scan attribute catalog
- * for name conflict (within rel)
- * for original attribute (if not arg)
- * modify attname in attribute tuple
- * insert modified attribute in attribute catalog
- * delete original attribute from attribute catalog
+ * get proper reldesc from relation catalog (if not arg)
+ * scan attribute catalog
+ * for name conflict (within rel)
+ * for original attribute (if not arg)
+ * modify attname in attribute tuple
+ * insert modified attribute in attribute catalog
+ * delete original attribute from attribute catalog
*
- * XXX Renaming an indexed attribute must (eventually) also change
- * the attribute name in the associated indexes.
+ * XXX Renaming an indexed attribute must (eventually) also change
+ * the attribute name in the associated indexes.
*/
void
renameatt(char *relname,
- char *oldattname,
- char *newattname,
- char *userName,
- int recurse)
+ char *oldattname,
+ char *newattname,
+ char *userName,
+ int recurse)
{
- Relation relrdesc, attrdesc;
- HeapTuple reltup, oldatttup, newatttup;
- ItemPointerData oldTID;
- Relation idescs[Num_pg_attr_indices];
-
- /*
- * permissions checking. this would normally be done in utility.c,
- * but this particular routine is recursive.
- *
- * normally, only the owner of a class can change its schema.
- */
- if (IsSystemRelationName(relname))
- elog(WARN, "renameatt: class \"%s\" is a system catalog",
- relname);
+ Relation relrdesc,
+ attrdesc;
+ HeapTuple reltup,
+ oldatttup,
+ newatttup;
+ ItemPointerData oldTID;
+ Relation idescs[Num_pg_attr_indices];
+
+ /*
+ * permissions checking. this would normally be done in utility.c,
+ * but this particular routine is recursive.
+ *
+ * normally, only the owner of a class can change its schema.
+ */
+ if (IsSystemRelationName(relname))
+ elog(WARN, "renameatt: class \"%s\" is a system catalog",
+ relname);
#ifndef NO_SECURITY
- if (!IsBootstrapProcessingMode() &&
- !pg_ownercheck(userName, relname, RELNAME))
- elog(WARN, "renameatt: you do not own class \"%s\"",
- relname);
+ if (!IsBootstrapProcessingMode() &&
+ !pg_ownercheck(userName, relname, RELNAME))
+ elog(WARN, "renameatt: you do not own class \"%s\"",
+ relname);
#endif
-
- /*
- * if the 'recurse' flag is set then we are supposed to rename this
- * attribute in all classes that inherit from 'relname' (as well as
- * in 'relname').
- *
- * any permissions or problems with duplicate attributes will cause
- * the whole transaction to abort, which is what we want -- all or
- * nothing.
- */
- if (recurse) {
- Oid myrelid, childrelid;
- List *child, *children;
-
- relrdesc = heap_openr(relname);
- if (!RelationIsValid(relrdesc)) {
- elog(WARN, "renameatt: unknown relation: \"%s\"",
- relname);
- }
- myrelid = relrdesc->rd_id;
- heap_close(relrdesc);
-
- /* this routine is actually in the planner */
- children = find_all_inheritors(lconsi(myrelid, NIL), NIL);
-
/*
- * 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.
+ * if the 'recurse' flag is set then we are supposed to rename this
+ * attribute in all classes that inherit from 'relname' (as well as in
+ * 'relname').
+ *
+ * any permissions or problems with duplicate attributes will cause the
+ * whole transaction to abort, which is what we want -- all or
+ * nothing.
*/
- foreach (child, children) {
- char *childname;
-
- childrelid = lfirsti(child);
- if (childrelid == myrelid)
- continue;
- relrdesc = heap_open(childrelid);
- if (!RelationIsValid(relrdesc)) {
- elog(WARN, "renameatt: can't find catalog entry for inheriting class with oid %d",
- childrelid);
- }
- childname = (relrdesc->rd_rel->relname).data;
- heap_close(relrdesc);
- renameatt(childname, oldattname, newattname,
- userName, 0); /* no more recursion! */
+ if (recurse)
+ {
+ Oid myrelid,
+ childrelid;
+ List *child,
+ *children;
+
+ relrdesc = heap_openr(relname);
+ if (!RelationIsValid(relrdesc))
+ {
+ elog(WARN, "renameatt: unknown relation: \"%s\"",
+ relname);
+ }
+ myrelid = relrdesc->rd_id;
+ heap_close(relrdesc);
+
+ /* this routine is actually in the planner */
+ children = find_all_inheritors(lconsi(myrelid, NIL), NIL);
+
+
+ /*
+ * 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)
+ {
+ char *childname;
+
+ childrelid = lfirsti(child);
+ if (childrelid == myrelid)
+ continue;
+ relrdesc = heap_open(childrelid);
+ if (!RelationIsValid(relrdesc))
+ {
+ elog(WARN, "renameatt: can't find catalog entry for inheriting class with oid %d",
+ childrelid);
+ }
+ childname = (relrdesc->rd_rel->relname).data;
+ heap_close(relrdesc);
+ renameatt(childname, oldattname, newattname,
+ userName, 0); /* no more recursion! */
+ }
+ }
+
+ relrdesc = heap_openr(RelationRelationName);
+ reltup = ClassNameIndexScan(relrdesc, relname);
+ if (!PointerIsValid(reltup))
+ {
+ heap_close(relrdesc);
+ elog(WARN, "renameatt: relation \"%s\" nonexistent",
+ relname);
+ return;
}
- }
-
- relrdesc = heap_openr(RelationRelationName);
- reltup = ClassNameIndexScan(relrdesc, relname);
- if (!PointerIsValid(reltup)) {
heap_close(relrdesc);
- elog(WARN, "renameatt: relation \"%s\" nonexistent",
- relname);
- return;
- }
- heap_close(relrdesc);
-
- attrdesc = heap_openr(AttributeRelationName);
- oldatttup = AttributeNameIndexScan(attrdesc, reltup->t_oid, oldattname);
- if (!PointerIsValid(oldatttup)) {
+
+ attrdesc = heap_openr(AttributeRelationName);
+ oldatttup = AttributeNameIndexScan(attrdesc, reltup->t_oid, oldattname);
+ if (!PointerIsValid(oldatttup))
+ {
+ heap_close(attrdesc);
+ elog(WARN, "renameatt: attribute \"%s\" nonexistent",
+ oldattname);
+ }
+ if (((AttributeTupleForm) GETSTRUCT(oldatttup))->attnum < 0)
+ {
+ elog(WARN, "renameatt: system attribute \"%s\" not renamed",
+ oldattname);
+ }
+
+ newatttup = AttributeNameIndexScan(attrdesc, reltup->t_oid, newattname);
+ if (PointerIsValid(newatttup))
+ {
+ pfree(oldatttup);
+ heap_close(attrdesc);
+ elog(WARN, "renameatt: attribute \"%s\" exists",
+ newattname);
+ }
+
+ namestrcpy(&(((AttributeTupleForm) (GETSTRUCT(oldatttup)))->attname),
+ newattname);
+ oldTID = oldatttup->t_ctid;
+
+ /* insert "fixed" tuple */
+ heap_replace(attrdesc, &oldTID, oldatttup);
+
+ /* keep system catalog indices current */
+ CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_attr_indices, attrdesc, oldatttup);
+ CatalogCloseIndices(Num_pg_attr_indices, idescs);
+
heap_close(attrdesc);
- elog(WARN, "renameatt: attribute \"%s\" nonexistent",
- oldattname);
- }
- if (((AttributeTupleForm ) GETSTRUCT(oldatttup))->attnum < 0) {
- elog(WARN, "renameatt: system attribute \"%s\" not renamed",
- oldattname);
- }
-
- newatttup = AttributeNameIndexScan(attrdesc, reltup->t_oid, newattname);
- if (PointerIsValid(newatttup)) {
pfree(oldatttup);
- heap_close(attrdesc);
- elog(WARN, "renameatt: attribute \"%s\" exists",
- newattname);
- }
-
- namestrcpy(&(((AttributeTupleForm)(GETSTRUCT(oldatttup)))->attname),
- newattname);
- oldTID = oldatttup->t_ctid;
-
- /* insert "fixed" tuple */
- heap_replace(attrdesc, &oldTID, oldatttup);
-
- /* keep system catalog indices current */
- CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_attr_indices, attrdesc, oldatttup);
- CatalogCloseIndices(Num_pg_attr_indices, idescs);
-
- heap_close(attrdesc);
- pfree(oldatttup);
}
/*
- * renamerel - change the name of a relation
+ * renamerel - change the name of a relation
*
- * Relname attribute is changed in relation catalog.
- * No record of the previous relname is kept (correct?).
+ * Relname attribute is changed in relation catalog.
+ * No record of the previous relname is kept (correct?).
*
- * scan relation catalog
- * for name conflict
- * for original relation (if not arg)
- * modify relname in relation tuple
- * insert modified relation in relation catalog
- * delete original relation from relation catalog
+ * scan relation catalog
+ * for name conflict
+ * for original relation (if not arg)
+ * modify relname in relation tuple
+ * insert modified relation in relation catalog
+ * delete original relation from relation catalog
*
- * XXX Will currently lose track of a relation if it is unable to
- * properly replace the new relation tuple.
+ * XXX Will currently lose track of a relation if it is unable to
+ * properly replace the new relation tuple.
*/
void
renamerel(char oldrelname[], char newrelname[])
{
- Relation relrdesc; /* for RELATION relation */
- HeapTuple oldreltup, newreltup;
- ItemPointerData oldTID;
- char oldpath[MAXPGPATH], newpath[MAXPGPATH];
- Relation idescs[Num_pg_class_indices];
-
- if (IsSystemRelationName(oldrelname)) {
- elog(WARN, "renamerel: system relation \"%s\" not renamed",
- oldrelname);
- return;
- }
- if (IsSystemRelationName(newrelname)) {
- elog(WARN, "renamerel: Illegal class name: \"%s\" -- pg_ is reserved for system catalogs",
- newrelname);
- return;
- }
-
- relrdesc = heap_openr(RelationRelationName);
- oldreltup = ClassNameIndexScan(relrdesc, oldrelname);
-
- if (!PointerIsValid(oldreltup)) {
- heap_close(relrdesc);
- elog(WARN, "renamerel: relation \"%s\" does not exist",
- oldrelname);
- }
-
- newreltup = ClassNameIndexScan(relrdesc, newrelname);
- if (PointerIsValid(newreltup)) {
+ Relation relrdesc; /* for RELATION relation */
+ HeapTuple oldreltup,
+ newreltup;
+ ItemPointerData oldTID;
+ char oldpath[MAXPGPATH],
+ newpath[MAXPGPATH];
+ Relation idescs[Num_pg_class_indices];
+
+ if (IsSystemRelationName(oldrelname))
+ {
+ elog(WARN, "renamerel: system relation \"%s\" not renamed",
+ oldrelname);
+ return;
+ }
+ if (IsSystemRelationName(newrelname))
+ {
+ elog(WARN, "renamerel: Illegal class name: \"%s\" -- pg_ is reserved for system catalogs",
+ newrelname);
+ return;
+ }
+
+ relrdesc = heap_openr(RelationRelationName);
+ oldreltup = ClassNameIndexScan(relrdesc, oldrelname);
+
+ if (!PointerIsValid(oldreltup))
+ {
+ heap_close(relrdesc);
+ elog(WARN, "renamerel: relation \"%s\" does not exist",
+ oldrelname);
+ }
+
+ newreltup = ClassNameIndexScan(relrdesc, newrelname);
+ if (PointerIsValid(newreltup))
+ {
+ pfree(oldreltup);
+ heap_close(relrdesc);
+ elog(WARN, "renamerel: relation \"%s\" exists",
+ newrelname);
+ }
+
+ /* rename the directory first, so if this fails the rename's not done */
+ strcpy(oldpath, relpath(oldrelname));
+ strcpy(newpath, relpath(newrelname));
+ if (rename(oldpath, newpath) < 0)
+ elog(WARN, "renamerel: unable to rename file: %m");
+
+ memmove((char *) (((Form_pg_class) GETSTRUCT(oldreltup))->relname.data),
+ newrelname,
+ NAMEDATALEN);
+ oldTID = oldreltup->t_ctid;
+
+ /* insert fixed rel tuple */
+ heap_replace(relrdesc, &oldTID, oldreltup);
+
+ /* keep the system catalog indices current */
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, relrdesc, oldreltup);
+ CatalogCloseIndices(Num_pg_class_indices, idescs);
+
pfree(oldreltup);
heap_close(relrdesc);
- elog(WARN, "renamerel: relation \"%s\" exists",
- newrelname);
- }
-
- /* rename the directory first, so if this fails the rename's not done */
- strcpy(oldpath, relpath(oldrelname));
- strcpy(newpath, relpath(newrelname));
- if (rename(oldpath, newpath) < 0)
- elog(WARN, "renamerel: unable to rename file: %m");
-
- memmove((char *) (((Form_pg_class) GETSTRUCT(oldreltup))->relname.data),
- newrelname,
- NAMEDATALEN);
- oldTID = oldreltup->t_ctid;
-
- /* insert fixed rel tuple */
- heap_replace(relrdesc, &oldTID, oldreltup);
-
- /* keep the system catalog indices current */
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_class_indices, relrdesc, oldreltup);
- CatalogCloseIndices(Num_pg_class_indices, idescs);
-
- pfree(oldreltup);
- heap_close(relrdesc);
}
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 5d35f7b60f5..c4bd8c40dcf 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* sequence.c--
- * PostgreSQL sequences support code.
+ * PostgreSQL sequences support code.
*
*-------------------------------------------------------------------------
*/
@@ -19,523 +19,539 @@
#include <commands/sequence.h>
#include <utils/builtins.h>
-#define SEQ_MAGIC 0x1717
+#define SEQ_MAGIC 0x1717
#define SEQ_MAXVALUE ((int4)0x7FFFFFFF)
#define SEQ_MINVALUE -(SEQ_MAXVALUE)
-bool ItsSequenceCreation = false;
+bool ItsSequenceCreation = false;
-typedef struct FormData_pg_sequence {
- NameData sequence_name;
- int4 last_value;
- int4 increment_by;
- int4 max_value;
- int4 min_value;
- int4 cache_value;
- char is_cycled;
- char is_called;
-} FormData_pg_sequence;
-
-typedef FormData_pg_sequence *SequenceTupleForm;
-
-typedef struct sequence_magic {
- uint32 magic;
-} sequence_magic;
+typedef struct FormData_pg_sequence
+{
+ NameData sequence_name;
+ int4 last_value;
+ int4 increment_by;
+ int4 max_value;
+ int4 min_value;
+ int4 cache_value;
+ char is_cycled;
+ char is_called;
+} FormData_pg_sequence;
+
+typedef FormData_pg_sequence *SequenceTupleForm;
+
+typedef struct sequence_magic
+{
+ uint32 magic;
+} sequence_magic;
-typedef struct SeqTableData {
- char *name;
- Oid relid;
+typedef struct SeqTableData
+{
+ char *name;
+ Oid relid;
Relation rel;
int4 cached;
int4 last;
int4 increment;
- struct SeqTableData *next;
-} SeqTableData;
+ struct SeqTableData *next;
+} SeqTableData;
typedef SeqTableData *SeqTable;
static SeqTable seqtab = NULL;
-static SeqTable init_sequence (char *caller, char *name);
-static SequenceTupleForm read_info (char * caller, SeqTable elm, Buffer * buf);
-static void init_params (CreateSeqStmt *seq, SequenceTupleForm new);
-static int get_param (DefElem *def);
+static SeqTable init_sequence(char *caller, char *name);
+static SequenceTupleForm read_info(char *caller, SeqTable elm, Buffer * buf);
+static void init_params(CreateSeqStmt * seq, SequenceTupleForm new);
+static int get_param(DefElem * def);
/*
* DefineSequence --
- * Creates a new sequence relation
+ * Creates a new sequence relation
*/
void
-DefineSequence (CreateSeqStmt *seq)
+DefineSequence(CreateSeqStmt * seq)
{
- FormData_pg_sequence new;
- CreateStmt *stmt = makeNode (CreateStmt);
- ColumnDef *coldef;
- TypeName *typnam;
- Relation rel;
- Buffer buf;
- PageHeader page;
- sequence_magic *sm;
- HeapTuple tuple;
- TupleDesc tupDesc;
- Datum value[SEQ_COL_LASTCOL];
- char null[SEQ_COL_LASTCOL];
- int i;
-
- /* Check and set values */
- init_params (seq, &new);
-
- /*
- * Create relation (and fill null[] & value[])
- */
- stmt->tableElts = NIL;
- for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
- {
- typnam = makeNode(TypeName);
- typnam->setof = FALSE;
- typnam->arrayBounds = NULL;
- coldef = makeNode(ColumnDef);
- coldef->typename = typnam;
- coldef->defval = NULL;
- coldef->is_not_null = false;
- null[i-1] = ' ';
-
- switch (i)
+ FormData_pg_sequence new;
+ CreateStmt *stmt = makeNode(CreateStmt);
+ ColumnDef *coldef;
+ TypeName *typnam;
+ Relation rel;
+ Buffer buf;
+ PageHeader page;
+ sequence_magic *sm;
+ HeapTuple tuple;
+ TupleDesc tupDesc;
+ Datum value[SEQ_COL_LASTCOL];
+ char null[SEQ_COL_LASTCOL];
+ int i;
+
+ /* Check and set values */
+ init_params(seq, &new);
+
+ /*
+ * Create relation (and fill null[] & value[])
+ */
+ stmt->tableElts = NIL;
+ for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
{
- case SEQ_COL_NAME:
- typnam->name = "name";
- coldef->colname = "sequence_name";
- value[i-1] = PointerGetDatum (seq->seqname);
- break;
- case SEQ_COL_LASTVAL:
- typnam->name = "int4";
- coldef->colname = "last_value";
- value[i-1] = Int32GetDatum (new.last_value);
- break;
- case SEQ_COL_INCBY:
- typnam->name = "int4";
- coldef->colname = "increment_by";
- value[i-1] = Int32GetDatum (new.increment_by);
- break;
- case SEQ_COL_MAXVALUE:
- typnam->name = "int4";
- coldef->colname = "max_value";
- value[i-1] = Int32GetDatum (new.max_value);
- break;
- case SEQ_COL_MINVALUE:
- typnam->name = "int4";
- coldef->colname = "min_value";
- value[i-1] = Int32GetDatum (new.min_value);
- break;
- case SEQ_COL_CACHE:
- typnam->name = "int4";
- coldef->colname = "cache_value";
- value[i-1] = Int32GetDatum (new.cache_value);
- break;
- case SEQ_COL_CYCLE:
- typnam->name = "char";
- coldef->colname = "is_cycled";
- value[i-1] = CharGetDatum (new.is_cycled);
- break;
- case SEQ_COL_CALLED:
- typnam->name = "char";
- coldef->colname = "is_called";
- value[i-1] = CharGetDatum ('f');
- break;
- }
- stmt->tableElts = lappend (stmt->tableElts, coldef);
- }
-
- stmt->relname = seq->seqname;
- stmt->archiveLoc = -1; /* default */
- stmt->archiveType = ARCH_NONE;
- stmt->inhRelnames = NIL;
- stmt->constraints = NIL;
-
- ItsSequenceCreation = true; /* hack */
-
- DefineRelation (stmt);
-
- /* Xact abort calls CloseSequences, which turns ItsSequenceCreation off */
- ItsSequenceCreation = false; /* hack */
-
- rel = heap_openr (seq->seqname);
- Assert ( RelationIsValid (rel) );
-
- RelationSetLockForWrite (rel);
-
- tupDesc = RelationGetTupleDescriptor(rel);
-
- Assert ( RelationGetNumberOfBlocks (rel) == 0 );
- buf = ReadBuffer (rel, P_NEW);
-
- if ( !BufferIsValid (buf) )
- elog (WARN, "DefineSequence: ReadBuffer failed");
-
- page = (PageHeader) BufferGetPage (buf);
-
- PageInit((Page)page, BufferGetPageSize(buf), sizeof(sequence_magic));
- sm = (sequence_magic *) PageGetSpecialPointer (page);
- sm->magic = SEQ_MAGIC;
-
- /* Now - form & insert sequence tuple */
- tuple = heap_formtuple (tupDesc, value, null);
- heap_insert (rel, tuple);
-
- if ( WriteBuffer (buf) == STATUS_ERROR )
- elog (WARN, "DefineSequence: WriteBuffer failed");
-
- RelationUnsetLockForWrite (rel);
- heap_close (rel);
-
- return;
+ typnam = makeNode(TypeName);
+ typnam->setof = FALSE;
+ typnam->arrayBounds = NULL;
+ coldef = makeNode(ColumnDef);
+ coldef->typename = typnam;
+ coldef->defval = NULL;
+ coldef->is_not_null = false;
+ null[i - 1] = ' ';
+
+ switch (i)
+ {
+ case SEQ_COL_NAME:
+ typnam->name = "name";
+ coldef->colname = "sequence_name";
+ value[i - 1] = PointerGetDatum(seq->seqname);
+ break;
+ case SEQ_COL_LASTVAL:
+ typnam->name = "int4";
+ coldef->colname = "last_value";
+ value[i - 1] = Int32GetDatum(new.last_value);
+ break;
+ case SEQ_COL_INCBY:
+ typnam->name = "int4";
+ coldef->colname = "increment_by";
+ value[i - 1] = Int32GetDatum(new.increment_by);
+ break;
+ case SEQ_COL_MAXVALUE:
+ typnam->name = "int4";
+ coldef->colname = "max_value";
+ value[i - 1] = Int32GetDatum(new.max_value);
+ break;
+ case SEQ_COL_MINVALUE:
+ typnam->name = "int4";
+ coldef->colname = "min_value";
+ value[i - 1] = Int32GetDatum(new.min_value);
+ break;
+ case SEQ_COL_CACHE:
+ typnam->name = "int4";
+ coldef->colname = "cache_value";
+ value[i - 1] = Int32GetDatum(new.cache_value);
+ break;
+ case SEQ_COL_CYCLE:
+ typnam->name = "char";
+ coldef->colname = "is_cycled";
+ value[i - 1] = CharGetDatum(new.is_cycled);
+ break;
+ case SEQ_COL_CALLED:
+ typnam->name = "char";
+ coldef->colname = "is_called";
+ value[i - 1] = CharGetDatum('f');
+ break;
+ }
+ stmt->tableElts = lappend(stmt->tableElts, coldef);
+ }
+
+ stmt->relname = seq->seqname;
+ stmt->archiveLoc = -1; /* default */
+ stmt->archiveType = ARCH_NONE;
+ stmt->inhRelnames = NIL;
+ stmt->constraints = NIL;
+
+ ItsSequenceCreation = true; /* hack */
+
+ DefineRelation(stmt);
+
+ /*
+ * Xact abort calls CloseSequences, which turns ItsSequenceCreation
+ * off
+ */
+ ItsSequenceCreation = false;/* hack */
+
+ rel = heap_openr(seq->seqname);
+ Assert(RelationIsValid(rel));
+
+ RelationSetLockForWrite(rel);
+
+ tupDesc = RelationGetTupleDescriptor(rel);
+
+ Assert(RelationGetNumberOfBlocks(rel) == 0);
+ buf = ReadBuffer(rel, P_NEW);
+
+ if (!BufferIsValid(buf))
+ elog(WARN, "DefineSequence: ReadBuffer failed");
+
+ page = (PageHeader) BufferGetPage(buf);
+
+ PageInit((Page) page, BufferGetPageSize(buf), sizeof(sequence_magic));
+ sm = (sequence_magic *) PageGetSpecialPointer(page);
+ sm->magic = SEQ_MAGIC;
+
+ /* Now - form & insert sequence tuple */
+ tuple = heap_formtuple(tupDesc, value, null);
+ heap_insert(rel, tuple);
+
+ if (WriteBuffer(buf) == STATUS_ERROR)
+ elog(WARN, "DefineSequence: WriteBuffer failed");
+
+ RelationUnsetLockForWrite(rel);
+ heap_close(rel);
+
+ return;
}
int4
-nextval (struct varlena * seqin)
+nextval(struct varlena * seqin)
{
- char *seqname = textout(seqin);
- SeqTable elm;
- Buffer buf;
- SequenceTupleForm seq;
- ItemPointerData iptr;
- int4 incby, maxv, minv, cache;
- int4 result, next, rescnt = 0;
-
- /* open and WIntentLock sequence */
- elm = init_sequence ("nextval", seqname);
- pfree (seqname);
-
- if ( elm->last != elm->cached ) /* some numbers were cached */
- {
- elm->last += elm->increment;
- return (elm->last);
- }
-
- seq = read_info ("nextval", elm, &buf); /* lock page and read tuple */
-
- next = result = seq->last_value;
- incby = seq->increment_by;
- maxv = seq->max_value;
- minv = seq->min_value;
- cache = seq->cache_value;
-
- if ( seq->is_called != 't' )
- rescnt++; /* last_value if not called */
-
- while ( rescnt < cache ) /* try to fetch cache numbers */
- {
- /*
- * Check MAXVALUE for ascending sequences
- * and MINVALUE for descending sequences
- */
- if ( incby > 0 ) /* ascending sequence */
- {
- if ( ( maxv >= 0 && next > maxv - incby) ||
- ( maxv < 0 && next + incby > maxv ) )
- {
- if ( rescnt > 0 )
- break; /* stop caching */
- if ( seq->is_cycled != 't' )
- elog (WARN, "%s.nextval: got MAXVALUE (%d)",
- elm->name, maxv);
- next = minv;
- }
- else
- next += incby;
+ char *seqname = textout(seqin);
+ SeqTable elm;
+ Buffer buf;
+ SequenceTupleForm seq;
+ ItemPointerData iptr;
+ int4 incby,
+ maxv,
+ minv,
+ cache;
+ int4 result,
+ next,
+ rescnt = 0;
+
+ /* open and WIntentLock sequence */
+ elm = init_sequence("nextval", seqname);
+ pfree(seqname);
+
+ if (elm->last != elm->cached) /* some numbers were cached */
+ {
+ elm->last += elm->increment;
+ return (elm->last);
}
- else /* descending sequence */
+
+ seq = read_info("nextval", elm, &buf); /* lock page and read
+ * tuple */
+
+ next = result = seq->last_value;
+ incby = seq->increment_by;
+ maxv = seq->max_value;
+ minv = seq->min_value;
+ cache = seq->cache_value;
+
+ if (seq->is_called != 't')
+ rescnt++; /* last_value if not called */
+
+ while (rescnt < cache) /* try to fetch cache numbers */
{
- if ( ( minv < 0 && next < minv - incby ) ||
- ( minv >= 0 && next + incby < minv ) )
- {
- if ( rescnt > 0 )
- break; /* stop caching */
- if ( seq->is_cycled != 't' )
- elog (WARN, "%s.nextval: got MINVALUE (%d)",
- elm->name, minv);
- next = maxv;
- }
- else
- next += incby;
- }
- rescnt++; /* got result */
- if ( rescnt == 1 ) /* if it's first one - */
- result = next; /* it's what to return */
- }
-
- /* save info in local cache */
- elm->last = result; /* last returned number */
- elm->cached = next; /* last cached number */
-
- /* save info in sequence relation */
- seq->last_value = next; /* last fetched number */
- seq->is_called = 't';
-
- if ( WriteBuffer (buf) == STATUS_ERROR )
- elog (WARN, "%s.nextval: WriteBuffer failed", elm->name);
-
- ItemPointerSet(&iptr, 0, FirstOffsetNumber);
- RelationUnsetSingleWLockPage (elm->rel, &iptr);
-
- return (result);
-
+
+ /*
+ * Check MAXVALUE for ascending sequences and MINVALUE for
+ * descending sequences
+ */
+ if (incby > 0) /* ascending sequence */
+ {
+ if ((maxv >= 0 && next > maxv - incby) ||
+ (maxv < 0 && next + incby > maxv))
+ {
+ if (rescnt > 0)
+ break; /* stop caching */
+ if (seq->is_cycled != 't')
+ elog(WARN, "%s.nextval: got MAXVALUE (%d)",
+ elm->name, maxv);
+ next = minv;
+ }
+ else
+ next += incby;
+ }
+ else
+/* descending sequence */
+ {
+ if ((minv < 0 && next < minv - incby) ||
+ (minv >= 0 && next + incby < minv))
+ {
+ if (rescnt > 0)
+ break; /* stop caching */
+ if (seq->is_cycled != 't')
+ elog(WARN, "%s.nextval: got MINVALUE (%d)",
+ elm->name, minv);
+ next = maxv;
+ }
+ else
+ next += incby;
+ }
+ rescnt++; /* got result */
+ if (rescnt == 1) /* if it's first one - */
+ result = next; /* it's what to return */
+ }
+
+ /* save info in local cache */
+ elm->last = result; /* last returned number */
+ elm->cached = next; /* last cached number */
+
+ /* save info in sequence relation */
+ seq->last_value = next; /* last fetched number */
+ seq->is_called = 't';
+
+ if (WriteBuffer(buf) == STATUS_ERROR)
+ elog(WARN, "%s.nextval: WriteBuffer failed", elm->name);
+
+ ItemPointerSet(&iptr, 0, FirstOffsetNumber);
+ RelationUnsetSingleWLockPage(elm->rel, &iptr);
+
+ return (result);
+
}
int4
-currval (struct varlena * seqin)
+currval(struct varlena * seqin)
{
- char *seqname = textout(seqin);
- SeqTable elm;
- int4 result;
-
- /* open and WIntentLock sequence */
- elm = init_sequence ("currval", seqname);
- pfree (seqname);
-
- if ( elm->increment == 0 ) /* nextval/read_info were not called */
- {
- elog (WARN, "%s.currval is not yet defined in this session", elm->name);
- }
-
- result = elm->last;
-
- return (result);
-
+ char *seqname = textout(seqin);
+ SeqTable elm;
+ int4 result;
+
+ /* open and WIntentLock sequence */
+ elm = init_sequence("currval", seqname);
+ pfree(seqname);
+
+ if (elm->increment == 0) /* nextval/read_info were not called */
+ {
+ elog(WARN, "%s.currval is not yet defined in this session", elm->name);
+ }
+
+ result = elm->last;
+
+ return (result);
+
}
-static SequenceTupleForm
-read_info (char * caller, SeqTable elm, Buffer * buf)
+static SequenceTupleForm
+read_info(char *caller, SeqTable elm, Buffer * buf)
{
- ItemPointerData iptr;
- PageHeader page;
- ItemId lp;
- HeapTuple tuple;
- sequence_magic *sm;
- SequenceTupleForm seq;
-
- ItemPointerSet(&iptr, 0, FirstOffsetNumber);
- RelationSetSingleWLockPage (elm->rel, &iptr);
-
- if ( RelationGetNumberOfBlocks (elm->rel) != 1 )
- elog (WARN, "%s.%s: invalid number of blocks in sequence",
- elm->name, caller);
-
- *buf = ReadBuffer (elm->rel, 0);
- if ( !BufferIsValid (*buf) )
- elog (WARN, "%s.%s: ReadBuffer failed", elm->name, caller);
-
- page = (PageHeader) BufferGetPage (*buf);
- sm = (sequence_magic *) PageGetSpecialPointer (page);
-
- if ( sm->magic != SEQ_MAGIC )
- elog (WARN, "%s.%s: bad magic (%08X)", elm->name, caller, sm->magic);
-
- lp = PageGetItemId (page, FirstOffsetNumber);
- Assert (ItemIdIsUsed (lp));
- tuple = (HeapTuple) PageGetItem ((Page) page, lp);
-
- seq = (SequenceTupleForm) GETSTRUCT(tuple);
-
- elm->increment = seq->increment_by;
-
- return (seq);
+ ItemPointerData iptr;
+ PageHeader page;
+ ItemId lp;
+ HeapTuple tuple;
+ sequence_magic *sm;
+ SequenceTupleForm seq;
+
+ ItemPointerSet(&iptr, 0, FirstOffsetNumber);
+ RelationSetSingleWLockPage(elm->rel, &iptr);
+
+ if (RelationGetNumberOfBlocks(elm->rel) != 1)
+ elog(WARN, "%s.%s: invalid number of blocks in sequence",
+ elm->name, caller);
+
+ *buf = ReadBuffer(elm->rel, 0);
+ if (!BufferIsValid(*buf))
+ elog(WARN, "%s.%s: ReadBuffer failed", elm->name, caller);
+
+ page = (PageHeader) BufferGetPage(*buf);
+ sm = (sequence_magic *) PageGetSpecialPointer(page);
+
+ if (sm->magic != SEQ_MAGIC)
+ elog(WARN, "%s.%s: bad magic (%08X)", elm->name, caller, sm->magic);
+
+ lp = PageGetItemId(page, FirstOffsetNumber);
+ Assert(ItemIdIsUsed(lp));
+ tuple = (HeapTuple) PageGetItem((Page) page, lp);
+
+ seq = (SequenceTupleForm) GETSTRUCT(tuple);
+
+ elm->increment = seq->increment_by;
+
+ return (seq);
}
-static SeqTable
-init_sequence (char * caller, char * name)
+static SeqTable
+init_sequence(char *caller, char *name)
{
- SeqTable elm, priv = (SeqTable) NULL;
- SeqTable temp;
-
- for (elm = seqtab; elm != (SeqTable) NULL; )
- {
- if ( strcmp (elm->name, name) == 0 )
- break;
- priv = elm;
- elm = elm->next;
- }
-
- if ( elm == (SeqTable) NULL ) /* not found */
- {
- temp = (SeqTable) malloc (sizeof(SeqTableData));
- temp->name = malloc (strlen(name) + 1);
- strcpy (temp->name, name);
- temp->rel = (Relation) NULL;
- temp->cached = temp->last = temp->increment = 0;
- temp->next = (SeqTable) NULL;
- }
- else /* found */
- {
- if ( elm->rel != (Relation) NULL) /* already opened */
- return (elm);
- temp = elm;
- }
-
- temp->rel = heap_openr (name);
-
- if ( ! RelationIsValid (temp->rel) )
- elog (WARN, "%s.%s: sequence does not exist", name, caller);
-
- RelationSetWIntentLock (temp->rel);
-
- if ( temp->rel->rd_rel->relkind != RELKIND_SEQUENCE )
- elog (WARN, "%s.%s: %s is not sequence !", name, caller, name);
-
- if ( elm != (SeqTable) NULL ) /* we opened sequence from our */
- { /* SeqTable - check relid ! */
- if ( RelationGetRelationId (elm->rel) != elm->relid )
- {
- elog (NOTICE, "%s.%s: sequence was re-created",
- name, caller, name);
- elm->cached = elm->last = elm->increment = 0;
- elm->relid = RelationGetRelationId (elm->rel);
- }
- }
- else
- {
- elm = temp;
- elm->relid = RelationGetRelationId (elm->rel);
- if ( seqtab == (SeqTable) NULL )
- seqtab = elm;
- else
- priv->next = elm;
- }
-
- return (elm);
-
+ SeqTable elm,
+ priv = (SeqTable) NULL;
+ SeqTable temp;
+
+ for (elm = seqtab; elm != (SeqTable) NULL;)
+ {
+ if (strcmp(elm->name, name) == 0)
+ break;
+ priv = elm;
+ elm = elm->next;
+ }
+
+ if (elm == (SeqTable) NULL) /* not found */
+ {
+ temp = (SeqTable) malloc(sizeof(SeqTableData));
+ temp->name = malloc(strlen(name) + 1);
+ strcpy(temp->name, name);
+ temp->rel = (Relation) NULL;
+ temp->cached = temp->last = temp->increment = 0;
+ temp->next = (SeqTable) NULL;
+ }
+ else
+/* found */
+ {
+ if (elm->rel != (Relation) NULL) /* already opened */
+ return (elm);
+ temp = elm;
+ }
+
+ temp->rel = heap_openr(name);
+
+ if (!RelationIsValid(temp->rel))
+ elog(WARN, "%s.%s: sequence does not exist", name, caller);
+
+ RelationSetWIntentLock(temp->rel);
+
+ if (temp->rel->rd_rel->relkind != RELKIND_SEQUENCE)
+ elog(WARN, "%s.%s: %s is not sequence !", name, caller, name);
+
+ if (elm != (SeqTable) NULL) /* we opened sequence from our */
+ { /* SeqTable - check relid ! */
+ if (RelationGetRelationId(elm->rel) != elm->relid)
+ {
+ elog(NOTICE, "%s.%s: sequence was re-created",
+ name, caller, name);
+ elm->cached = elm->last = elm->increment = 0;
+ elm->relid = RelationGetRelationId(elm->rel);
+ }
+ }
+ else
+ {
+ elm = temp;
+ elm->relid = RelationGetRelationId(elm->rel);
+ if (seqtab == (SeqTable) NULL)
+ seqtab = elm;
+ else
+ priv->next = elm;
+ }
+
+ return (elm);
+
}
/*
* CloseSequences --
- * is calling by xact mgr at commit/abort.
+ * is calling by xact mgr at commit/abort.
*/
void
-CloseSequences (void)
+CloseSequences(void)
{
- SeqTable elm;
- Relation rel;
-
- ItsSequenceCreation = false;
-
- for (elm = seqtab; elm != (SeqTable) NULL; )
- {
- if ( elm->rel != (Relation) NULL ) /* opened in current xact */
+ SeqTable elm;
+ Relation rel;
+
+ ItsSequenceCreation = false;
+
+ for (elm = seqtab; elm != (SeqTable) NULL;)
{
- rel = elm->rel;
- elm->rel = (Relation) NULL;
- RelationUnsetWIntentLock (rel);
- heap_close (rel);
- }
- elm = elm->next;
- }
-
- return;
-
+ if (elm->rel != (Relation) NULL) /* opened in current xact */
+ {
+ rel = elm->rel;
+ elm->rel = (Relation) NULL;
+ RelationUnsetWIntentLock(rel);
+ heap_close(rel);
+ }
+ elm = elm->next;
+ }
+
+ return;
+
}
-static void
-init_params (CreateSeqStmt *seq, SequenceTupleForm new)
+static void
+init_params(CreateSeqStmt * seq, SequenceTupleForm new)
{
- DefElem *last_value = NULL;
- DefElem *increment_by = NULL;
- DefElem *max_value = NULL;
- DefElem *min_value = NULL;
- DefElem *cache_value = NULL;
- List *option;
-
- new->is_cycled = 'f';
- foreach (option, seq->options)
- {
- DefElem *defel = (DefElem *)lfirst(option);
-
- if ( !strcasecmp(defel->defname, "increment") )
- increment_by = defel;
- else if ( !strcasecmp(defel->defname, "start") )
- last_value = defel;
- else if ( !strcasecmp(defel->defname, "maxvalue") )
- max_value = defel;
- else if ( !strcasecmp(defel->defname, "minvalue") )
- min_value = defel;
- else if ( !strcasecmp(defel->defname, "cache") )
- cache_value = defel;
- else if ( !strcasecmp(defel->defname, "cycle") )
- {
- if ( defel->arg != (Node*) NULL )
- elog (WARN, "DefineSequence: CYCLE ??");
- new->is_cycled = 't';
- }
- else
- elog (WARN, "DefineSequence: option \"%s\" not recognized",
- defel->defname);
- }
-
- if ( increment_by == (DefElem*) NULL ) /* INCREMENT BY */
- new->increment_by = 1;
- else if ( ( new->increment_by = get_param (increment_by) ) == 0 )
- elog (WARN, "DefineSequence: can't INCREMENT by 0");
-
- if ( max_value == (DefElem*) NULL ) /* MAXVALUE */
- if ( new->increment_by > 0 )
- new->max_value = SEQ_MAXVALUE; /* ascending seq */
+ DefElem *last_value = NULL;
+ DefElem *increment_by = NULL;
+ DefElem *max_value = NULL;
+ DefElem *min_value = NULL;
+ DefElem *cache_value = NULL;
+ List *option;
+
+ new->is_cycled = 'f';
+ foreach(option, seq->options)
+ {
+ DefElem *defel = (DefElem *) lfirst(option);
+
+ if (!strcasecmp(defel->defname, "increment"))
+ increment_by = defel;
+ else if (!strcasecmp(defel->defname, "start"))
+ last_value = defel;
+ else if (!strcasecmp(defel->defname, "maxvalue"))
+ max_value = defel;
+ else if (!strcasecmp(defel->defname, "minvalue"))
+ min_value = defel;
+ else if (!strcasecmp(defel->defname, "cache"))
+ cache_value = defel;
+ else if (!strcasecmp(defel->defname, "cycle"))
+ {
+ if (defel->arg != (Node *) NULL)
+ elog(WARN, "DefineSequence: CYCLE ??");
+ new->is_cycled = 't';
+ }
+ else
+ elog(WARN, "DefineSequence: option \"%s\" not recognized",
+ defel->defname);
+ }
+
+ if (increment_by == (DefElem *) NULL) /* INCREMENT BY */
+ new->increment_by = 1;
+ else if ((new->increment_by = get_param(increment_by)) == 0)
+ elog(WARN, "DefineSequence: can't INCREMENT by 0");
+
+ if (max_value == (DefElem *) NULL) /* MAXVALUE */
+ if (new->increment_by > 0)
+ new->max_value = SEQ_MAXVALUE; /* ascending seq */
+ else
+ new->max_value = -1;/* descending seq */
else
- new->max_value = -1; /* descending seq */
- else
- new->max_value = get_param (max_value);
+ new->max_value = get_param(max_value);
- if ( min_value == (DefElem*) NULL ) /* MINVALUE */
- if ( new->increment_by > 0 )
- new->min_value = 1; /* ascending seq */
+ if (min_value == (DefElem *) NULL) /* MINVALUE */
+ if (new->increment_by > 0)
+ new->min_value = 1; /* ascending seq */
+ else
+ new->min_value = SEQ_MINVALUE; /* descending seq */
else
- new->min_value = SEQ_MINVALUE; /* descending seq */
- else
- new->min_value = get_param (min_value);
-
- if ( new->min_value >= new->max_value )
- elog (WARN, "DefineSequence: MINVALUE (%d) can't be >= MAXVALUE (%d)",
- new->min_value, new->max_value);
-
- if ( last_value == (DefElem*) NULL ) /* START WITH */
- if ( new->increment_by > 0 )
- new->last_value = new->min_value; /* ascending seq */
+ new->min_value = get_param(min_value);
+
+ if (new->min_value >= new->max_value)
+ elog(WARN, "DefineSequence: MINVALUE (%d) can't be >= MAXVALUE (%d)",
+ new->min_value, new->max_value);
+
+ if (last_value == (DefElem *) NULL) /* START WITH */
+ if (new->increment_by > 0)
+ new->last_value = new->min_value; /* ascending seq */
+ else
+ new->last_value = new->max_value; /* descending seq */
else
- new->last_value = new->max_value; /* descending seq */
- else
- new->last_value = get_param (last_value);
-
- if ( new->last_value < new->min_value )
- elog (WARN, "DefineSequence: START value (%d) can't be < MINVALUE (%d)",
- new->last_value, new->min_value);
- if ( new->last_value > new->max_value )
- elog (WARN, "DefineSequence: START value (%d) can't be > MAXVALUE (%d)",
- new->last_value, new->max_value);
-
- if ( cache_value == (DefElem*) NULL ) /* CACHE */
- new->cache_value = 1;
- else if ( ( new->cache_value = get_param (cache_value) ) <= 0 )
- elog (WARN, "DefineSequence: CACHE (%d) can't be <= 0",
- new->cache_value);
+ new->last_value = get_param(last_value);
+
+ if (new->last_value < new->min_value)
+ elog(WARN, "DefineSequence: START value (%d) can't be < MINVALUE (%d)",
+ new->last_value, new->min_value);
+ if (new->last_value > new->max_value)
+ elog(WARN, "DefineSequence: START value (%d) can't be > MAXVALUE (%d)",
+ new->last_value, new->max_value);
+
+ if (cache_value == (DefElem *) NULL) /* CACHE */
+ new->cache_value = 1;
+ else if ((new->cache_value = get_param(cache_value)) <= 0)
+ elog(WARN, "DefineSequence: CACHE (%d) can't be <= 0",
+ new->cache_value);
}
static int
-get_param (DefElem *def)
+get_param(DefElem * def)
{
- if ( def->arg == (Node*) NULL )
- elog (WARN, "DefineSequence: \"%s\" value unspecified", def->defname);
-
- if ( nodeTag (def->arg) == T_Integer )
- return (intVal (def->arg));
-
- elog (WARN, "DefineSequence: \"%s\" is to be integer", def->defname);
- return (-1);
+ if (def->arg == (Node *) NULL)
+ elog(WARN, "DefineSequence: \"%s\" value unspecified", def->defname);
+
+ if (nodeTag(def->arg) == T_Integer)
+ return (intVal(def->arg));
+
+ elog(WARN, "DefineSequence: \"%s\" is to be integer", def->defname);
+ return (-1);
}
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 2919df473fd..53ab1838cfe 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* trigger.c--
- * PostgreSQL TRIGGERs support code.
+ * PostgreSQL TRIGGERs support code.
*
*-------------------------------------------------------------------------
*/
@@ -32,581 +32,587 @@
#include "utils/syscache.h"
#endif
-TriggerData *CurrentTriggerData = NULL;
+TriggerData *CurrentTriggerData = NULL;
-void RelationBuildTriggers (Relation relation);
-void FreeTriggerDesc (Relation relation);
+void RelationBuildTriggers(Relation relation);
+void FreeTriggerDesc(Relation relation);
-static void DescribeTrigger (TriggerDesc *trigdesc, Trigger *trigger);
+static void DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger);
-extern void fmgr_info(Oid procedureId, func_ptr *function, int *nargs);
+extern void fmgr_info(Oid procedureId, func_ptr * function, int *nargs);
extern GlobalMemory CacheCxt;
void
-CreateTrigger (CreateTrigStmt *stmt)
+CreateTrigger(CreateTrigStmt * stmt)
{
- int16 tgtype;
- int16 tgattr[8] = {0};
- Datum values[Natts_pg_trigger];
- char nulls[Natts_pg_trigger];
- Relation rel;
- Relation tgrel;
- HeapScanDesc tgscan;
- ScanKeyData key;
- Relation relrdesc;
- HeapTuple tuple;
- ItemPointerData oldTID;
- Relation idescs[Num_pg_trigger_indices];
- Relation ridescs[Num_pg_class_indices];
- MemoryContext oldcxt;
- Oid fargtypes[8];
- int found = 0;
- int i;
-
- if ( IsSystemRelationName (stmt->relname) )
- elog(WARN, "CreateTrigger: can't create trigger for system relation %s", stmt->relname);
+ int16 tgtype;
+ int16 tgattr[8] = {0};
+ Datum values[Natts_pg_trigger];
+ char nulls[Natts_pg_trigger];
+ Relation rel;
+ Relation tgrel;
+ HeapScanDesc tgscan;
+ ScanKeyData key;
+ Relation relrdesc;
+ HeapTuple tuple;
+ ItemPointerData oldTID;
+ Relation idescs[Num_pg_trigger_indices];
+ Relation ridescs[Num_pg_class_indices];
+ MemoryContext oldcxt;
+ Oid fargtypes[8];
+ int found = 0;
+ int i;
+
+ if (IsSystemRelationName(stmt->relname))
+ elog(WARN, "CreateTrigger: can't create trigger for system relation %s", stmt->relname);
#ifndef NO_SECURITY
- if ( !pg_ownercheck (GetPgUserName (), stmt->relname, RELNAME))
- elog(WARN, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+ if (!pg_ownercheck(GetPgUserName(), stmt->relname, RELNAME))
+ elog(WARN, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
#endif
-
- rel = heap_openr (stmt->relname);
- if ( !RelationIsValid (rel) )
- elog (WARN, "CreateTrigger: there is no relation %s", stmt->relname);
-
- RelationSetLockForWrite (rel);
-
- TRIGGER_CLEAR_TYPE (tgtype);
- if ( stmt->before )
- TRIGGER_SETT_BEFORE (tgtype);
- if ( stmt->row )
- TRIGGER_SETT_ROW (tgtype);
- for (i = 0; i < 3 && stmt->actions[i]; i++)
- {
- switch ( stmt->actions[i] )
- {
- case 'i':
- if ( TRIGGER_FOR_INSERT (tgtype) )
- elog (WARN, "CreateTrigger: double INSERT event specified");
- TRIGGER_SETT_INSERT (tgtype);
- break;
- case 'd':
- if ( TRIGGER_FOR_DELETE (tgtype) )
- elog (WARN, "CreateTrigger: double DELETE event specified");
- TRIGGER_SETT_DELETE (tgtype);
- break;
- case 'u':
- if ( TRIGGER_FOR_UPDATE (tgtype) )
- elog (WARN, "CreateTrigger: double UPDATE event specified");
- TRIGGER_SETT_UPDATE (tgtype);
- break;
- default:
- elog (WARN, "CreateTrigger: unknown event specified");
- break;
- }
- }
-
- /* Scan pg_trigger */
- tgrel = heap_openr (TriggerRelationName);
- RelationSetLockForWrite (tgrel);
- ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
- ObjectIdEqualRegProcedure, rel->rd_id);
- tgscan = heap_beginscan (tgrel, 0, NowTimeQual, 1, &key);
- while (tuple = heap_getnext (tgscan, 0, (Buffer *)NULL), PointerIsValid(tuple))
- {
- Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT (tuple);
- if ( namestrcmp (&(pg_trigger->tgname), stmt->trigname) == 0 )
- elog (WARN, "CreateTrigger: trigger %s already defined on relation %s",
- stmt->trigname, stmt->relname);
- else
- found++;
- }
- heap_endscan (tgscan);
-
- memset (fargtypes, 0, 8 * sizeof(Oid));
- tuple = SearchSysCacheTuple (PRONAME,
- PointerGetDatum (stmt->funcname),
- 0, PointerGetDatum (fargtypes), 0);
- if ( !HeapTupleIsValid (tuple) ||
- ((Form_pg_proc)GETSTRUCT(tuple))->prorettype != 0 ||
- ((Form_pg_proc)GETSTRUCT(tuple))->pronargs != 0 )
- elog (WARN, "CreateTrigger: function %s () does not exist", stmt->funcname);
-
- if ( ((Form_pg_proc)GETSTRUCT(tuple))->prolang != ClanguageId )
- elog (WARN, "CreateTrigger: only C functions are supported");
-
- memset (nulls, ' ', Natts_pg_trigger * sizeof (char));
-
- values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum (rel->rd_id);
- values[Anum_pg_trigger_tgname - 1] = NameGetDatum (namein (stmt->trigname));
- values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum (tuple->t_oid);
- values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum (tgtype);
- if ( stmt->args )
- {
- List *le;
- char *args;
- int16 nargs = length (stmt->args);
- int len = 0;
-
- foreach (le, stmt->args)
- {
- char *ar = (char *) lfirst (le);
- len += strlen (ar) + 4;
- }
- args = (char *) palloc (len + 1);
- args[0] = 0;
- foreach (le, stmt->args)
- sprintf (args + strlen (args), "%s\\000", (char *)lfirst (le));
- values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum (nargs);
- values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum (byteain (args));
- }
- else
- {
- values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum (0);
- values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum (byteain (""));
- }
- values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum (tgattr);
-
- tuple = heap_formtuple (tgrel->rd_att, values, nulls);
- heap_insert (tgrel, tuple);
- CatalogOpenIndices (Num_pg_trigger_indices, Name_pg_trigger_indices, idescs);
- CatalogIndexInsert (idescs, Num_pg_trigger_indices, tgrel, tuple);
- CatalogCloseIndices (Num_pg_trigger_indices, idescs);
- pfree (tuple);
- RelationUnsetLockForWrite (tgrel);
- heap_close (tgrel);
-
- pfree (DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
- pfree (DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
-
- /* update pg_class */
- relrdesc = heap_openr (RelationRelationName);
- tuple = ClassNameIndexScan (relrdesc, stmt->relname);
- if ( !PointerIsValid (tuple) )
- {
+
+ rel = heap_openr(stmt->relname);
+ if (!RelationIsValid(rel))
+ elog(WARN, "CreateTrigger: there is no relation %s", stmt->relname);
+
+ RelationSetLockForWrite(rel);
+
+ TRIGGER_CLEAR_TYPE(tgtype);
+ if (stmt->before)
+ TRIGGER_SETT_BEFORE(tgtype);
+ if (stmt->row)
+ TRIGGER_SETT_ROW(tgtype);
+ for (i = 0; i < 3 && stmt->actions[i]; i++)
+ {
+ switch (stmt->actions[i])
+ {
+ case 'i':
+ if (TRIGGER_FOR_INSERT(tgtype))
+ elog(WARN, "CreateTrigger: double INSERT event specified");
+ TRIGGER_SETT_INSERT(tgtype);
+ break;
+ case 'd':
+ if (TRIGGER_FOR_DELETE(tgtype))
+ elog(WARN, "CreateTrigger: double DELETE event specified");
+ TRIGGER_SETT_DELETE(tgtype);
+ break;
+ case 'u':
+ if (TRIGGER_FOR_UPDATE(tgtype))
+ elog(WARN, "CreateTrigger: double UPDATE event specified");
+ TRIGGER_SETT_UPDATE(tgtype);
+ break;
+ default:
+ elog(WARN, "CreateTrigger: unknown event specified");
+ break;
+ }
+ }
+
+ /* Scan pg_trigger */
+ tgrel = heap_openr(TriggerRelationName);
+ RelationSetLockForWrite(tgrel);
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
+ ObjectIdEqualRegProcedure, rel->rd_id);
+ tgscan = heap_beginscan(tgrel, 0, NowTimeQual, 1, &key);
+ while (tuple = heap_getnext(tgscan, 0, (Buffer *) NULL), PointerIsValid(tuple))
+ {
+ Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
+
+ if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
+ elog(WARN, "CreateTrigger: trigger %s already defined on relation %s",
+ stmt->trigname, stmt->relname);
+ else
+ found++;
+ }
+ heap_endscan(tgscan);
+
+ memset(fargtypes, 0, 8 * sizeof(Oid));
+ tuple = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(stmt->funcname),
+ 0, PointerGetDatum(fargtypes), 0);
+ if (!HeapTupleIsValid(tuple) ||
+ ((Form_pg_proc) GETSTRUCT(tuple))->prorettype != 0 ||
+ ((Form_pg_proc) GETSTRUCT(tuple))->pronargs != 0)
+ elog(WARN, "CreateTrigger: function %s () does not exist", stmt->funcname);
+
+ if (((Form_pg_proc) GETSTRUCT(tuple))->prolang != ClanguageId)
+ elog(WARN, "CreateTrigger: only C functions are supported");
+
+ memset(nulls, ' ', Natts_pg_trigger * sizeof(char));
+
+ values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(rel->rd_id);
+ values[Anum_pg_trigger_tgname - 1] = NameGetDatum(namein(stmt->trigname));
+ values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(tuple->t_oid);
+ values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum(tgtype);
+ if (stmt->args)
+ {
+ List *le;
+ char *args;
+ int16 nargs = length(stmt->args);
+ int len = 0;
+
+ foreach(le, stmt->args)
+ {
+ char *ar = (char *) lfirst(le);
+
+ len += strlen(ar) + 4;
+ }
+ args = (char *) palloc(len + 1);
+ args[0] = 0;
+ foreach(le, stmt->args)
+ sprintf(args + strlen(args), "%s\\000", (char *) lfirst(le));
+ values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(nargs);
+ values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(byteain(args));
+ }
+ else
+ {
+ values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(0);
+ values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(byteain(""));
+ }
+ values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);
+
+ tuple = heap_formtuple(tgrel->rd_att, values, nulls);
+ heap_insert(tgrel, tuple);
+ CatalogOpenIndices(Num_pg_trigger_indices, Name_pg_trigger_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_trigger_indices, tgrel, tuple);
+ CatalogCloseIndices(Num_pg_trigger_indices, idescs);
+ pfree(tuple);
+ RelationUnsetLockForWrite(tgrel);
+ heap_close(tgrel);
+
+ pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
+ pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
+
+ /* update pg_class */
+ relrdesc = heap_openr(RelationRelationName);
+ tuple = ClassNameIndexScan(relrdesc, stmt->relname);
+ if (!PointerIsValid(tuple))
+ {
+ heap_close(relrdesc);
+ elog(WARN, "CreateTrigger: relation %s not found in pg_class", stmt->relname);
+ }
+ ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;
+ RelationInvalidateHeapTuple(relrdesc, tuple);
+ oldTID = tuple->t_ctid;
+ heap_replace(relrdesc, &oldTID, tuple);
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
+ CatalogIndexInsert(ridescs, Num_pg_class_indices, relrdesc, tuple);
+ CatalogCloseIndices(Num_pg_class_indices, ridescs);
+ pfree(tuple);
heap_close(relrdesc);
- elog(WARN, "CreateTrigger: relation %s not found in pg_class", stmt->relname);
- }
- ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;
- RelationInvalidateHeapTuple (relrdesc, tuple);
- oldTID = tuple->t_ctid;
- heap_replace (relrdesc, &oldTID, tuple);
- CatalogOpenIndices (Num_pg_class_indices, Name_pg_class_indices, ridescs);
- CatalogIndexInsert (ridescs, Num_pg_class_indices, relrdesc, tuple);
- CatalogCloseIndices (Num_pg_class_indices, ridescs);
- pfree(tuple);
- heap_close(relrdesc);
-
- CommandCounterIncrement ();
- oldcxt = MemoryContextSwitchTo ((MemoryContext)CacheCxt);
- FreeTriggerDesc (rel);
- rel->rd_rel->reltriggers = found + 1;
- RelationBuildTriggers (rel);
- MemoryContextSwitchTo (oldcxt);
- heap_close (rel);
- return;
+
+ CommandCounterIncrement();
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ FreeTriggerDesc(rel);
+ rel->rd_rel->reltriggers = found + 1;
+ RelationBuildTriggers(rel);
+ MemoryContextSwitchTo(oldcxt);
+ heap_close(rel);
+ return;
}
void
-DropTrigger (DropTrigStmt *stmt)
+DropTrigger(DropTrigStmt * stmt)
{
- Relation rel;
- Relation tgrel;
- HeapScanDesc tgscan;
- ScanKeyData key;
- Relation relrdesc;
- HeapTuple tuple;
- ItemPointerData oldTID;
- Relation ridescs[Num_pg_class_indices];
- MemoryContext oldcxt;
- int found = 0;
- int tgfound = 0;
-
+ Relation rel;
+ Relation tgrel;
+ HeapScanDesc tgscan;
+ ScanKeyData key;
+ Relation relrdesc;
+ HeapTuple tuple;
+ ItemPointerData oldTID;
+ Relation ridescs[Num_pg_class_indices];
+ MemoryContext oldcxt;
+ int found = 0;
+ int tgfound = 0;
+
#ifndef NO_SECURITY
- if ( !pg_ownercheck (GetPgUserName (), stmt->relname, RELNAME))
- elog(WARN, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+ if (!pg_ownercheck(GetPgUserName(), stmt->relname, RELNAME))
+ elog(WARN, "%s: %s", stmt->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
#endif
-
- rel = heap_openr (stmt->relname);
- if ( !RelationIsValid (rel) )
- elog (WARN, "DropTrigger: there is no relation %s", stmt->relname);
-
- RelationSetLockForWrite (rel);
-
- tgrel = heap_openr (TriggerRelationName);
- RelationSetLockForWrite (tgrel);
- ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
- ObjectIdEqualRegProcedure, rel->rd_id);
- tgscan = heap_beginscan (tgrel, 0, NowTimeQual, 1, &key);
- while (tuple = heap_getnext (tgscan, 0, (Buffer *)NULL), PointerIsValid(tuple))
- {
- Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT (tuple);
- if ( namestrcmp (&(pg_trigger->tgname), stmt->trigname) == 0 )
- {
- heap_delete (tgrel, &tuple->t_ctid);
- tgfound++;
- }
- else
- found++;
- }
- if ( tgfound == 0 )
- elog (WARN, "DropTrigger: there is no trigger %s on relation %s",
- stmt->trigname, stmt->relname);
- if ( tgfound > 1 )
- elog (NOTICE, "DropTrigger: found (and deleted) %d trigger %s on relation %s",
- tgfound, stmt->trigname, stmt->relname);
- heap_endscan (tgscan);
- RelationUnsetLockForWrite (tgrel);
- heap_close (tgrel);
-
- /* update pg_class */
- relrdesc = heap_openr (RelationRelationName);
- tuple = ClassNameIndexScan (relrdesc, stmt->relname);
- if ( !PointerIsValid (tuple) )
- {
+
+ rel = heap_openr(stmt->relname);
+ if (!RelationIsValid(rel))
+ elog(WARN, "DropTrigger: there is no relation %s", stmt->relname);
+
+ RelationSetLockForWrite(rel);
+
+ tgrel = heap_openr(TriggerRelationName);
+ RelationSetLockForWrite(tgrel);
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
+ ObjectIdEqualRegProcedure, rel->rd_id);
+ tgscan = heap_beginscan(tgrel, 0, NowTimeQual, 1, &key);
+ while (tuple = heap_getnext(tgscan, 0, (Buffer *) NULL), PointerIsValid(tuple))
+ {
+ Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
+
+ if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
+ {
+ heap_delete(tgrel, &tuple->t_ctid);
+ tgfound++;
+ }
+ else
+ found++;
+ }
+ if (tgfound == 0)
+ elog(WARN, "DropTrigger: there is no trigger %s on relation %s",
+ stmt->trigname, stmt->relname);
+ if (tgfound > 1)
+ elog(NOTICE, "DropTrigger: found (and deleted) %d trigger %s on relation %s",
+ tgfound, stmt->trigname, stmt->relname);
+ heap_endscan(tgscan);
+ RelationUnsetLockForWrite(tgrel);
+ heap_close(tgrel);
+
+ /* update pg_class */
+ relrdesc = heap_openr(RelationRelationName);
+ tuple = ClassNameIndexScan(relrdesc, stmt->relname);
+ if (!PointerIsValid(tuple))
+ {
+ heap_close(relrdesc);
+ elog(WARN, "DropTrigger: relation %s not found in pg_class", stmt->relname);
+ }
+ ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found;
+ RelationInvalidateHeapTuple(relrdesc, tuple);
+ oldTID = tuple->t_ctid;
+ heap_replace(relrdesc, &oldTID, tuple);
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
+ CatalogIndexInsert(ridescs, Num_pg_class_indices, relrdesc, tuple);
+ CatalogCloseIndices(Num_pg_class_indices, ridescs);
+ pfree(tuple);
heap_close(relrdesc);
- elog(WARN, "DropTrigger: relation %s not found in pg_class", stmt->relname);
- }
- ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found;
- RelationInvalidateHeapTuple (relrdesc, tuple);
- oldTID = tuple->t_ctid;
- heap_replace (relrdesc, &oldTID, tuple);
- CatalogOpenIndices (Num_pg_class_indices, Name_pg_class_indices, ridescs);
- CatalogIndexInsert (ridescs, Num_pg_class_indices, relrdesc, tuple);
- CatalogCloseIndices (Num_pg_class_indices, ridescs);
- pfree(tuple);
- heap_close(relrdesc);
-
- CommandCounterIncrement ();
- oldcxt = MemoryContextSwitchTo ((MemoryContext)CacheCxt);
- FreeTriggerDesc (rel);
- rel->rd_rel->reltriggers = found;
- if ( found > 0 )
- RelationBuildTriggers (rel);
- MemoryContextSwitchTo (oldcxt);
- heap_close (rel);
- return;
+
+ CommandCounterIncrement();
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ FreeTriggerDesc(rel);
+ rel->rd_rel->reltriggers = found;
+ if (found > 0)
+ RelationBuildTriggers(rel);
+ MemoryContextSwitchTo(oldcxt);
+ heap_close(rel);
+ return;
}
-void
-RelationRemoveTriggers (Relation rel)
+void
+RelationRemoveTriggers(Relation rel)
{
- Relation tgrel;
- HeapScanDesc tgscan;
- ScanKeyData key;
- HeapTuple tup;
-
- tgrel = heap_openr (TriggerRelationName);
- RelationSetLockForWrite (tgrel);
- ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
- ObjectIdEqualRegProcedure, rel->rd_id);
-
- tgscan = heap_beginscan (tgrel, 0, NowTimeQual, 1, &key);
-
- while (tup = heap_getnext (tgscan, 0, (Buffer *)NULL), PointerIsValid(tup))
- heap_delete (tgrel, &tup->t_ctid);
-
- heap_endscan (tgscan);
- RelationUnsetLockForWrite (tgrel);
- heap_close (tgrel);
+ Relation tgrel;
+ HeapScanDesc tgscan;
+ ScanKeyData key;
+ HeapTuple tup;
+
+ tgrel = heap_openr(TriggerRelationName);
+ RelationSetLockForWrite(tgrel);
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
+ ObjectIdEqualRegProcedure, rel->rd_id);
+
+ tgscan = heap_beginscan(tgrel, 0, NowTimeQual, 1, &key);
+
+ while (tup = heap_getnext(tgscan, 0, (Buffer *) NULL), PointerIsValid(tup))
+ heap_delete(tgrel, &tup->t_ctid);
+
+ heap_endscan(tgscan);
+ RelationUnsetLockForWrite(tgrel);
+ heap_close(tgrel);
}
void
-RelationBuildTriggers (Relation relation)
+RelationBuildTriggers(Relation relation)
{
- TriggerDesc *trigdesc = (TriggerDesc *) palloc (sizeof (TriggerDesc));
- int ntrigs = relation->rd_rel->reltriggers;
- Trigger *triggers = NULL;
- Trigger *build;
- Relation tgrel;
- Form_pg_trigger pg_trigger;
- Relation irel;
- ScanKeyData skey;
- HeapTuple tuple;
- IndexScanDesc sd;
- RetrieveIndexResult indexRes;
- Buffer buffer;
- ItemPointer iptr;
- struct varlena *val;
- bool isnull;
- int found;
-
- memset (trigdesc, 0, sizeof (TriggerDesc));
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relation->rd_id));
-
- tgrel = heap_openr(TriggerRelationName);
- RelationSetLockForRead (tgrel);
- irel = index_openr(TriggerRelidIndex);
- sd = index_beginscan(irel, false, 1, &skey);
-
- for (found = 0; ; )
- {
- indexRes = index_getnext(sd, ForwardScanDirection);
- if (!indexRes)
- break;
-
- iptr = &indexRes->heap_iptr;
- tuple = heap_fetch(tgrel, NowTimeQual, iptr, &buffer);
- pfree(indexRes);
- if (!HeapTupleIsValid(tuple))
- continue;
- if ( found == ntrigs )
- elog (WARN, "RelationBuildTriggers: unexpected record found for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
-
- pg_trigger = (Form_pg_trigger) GETSTRUCT (tuple);
-
- if ( triggers == NULL )
- triggers = (Trigger *) palloc (sizeof (Trigger));
- else
- triggers = (Trigger *) repalloc (triggers, (found + 1) * sizeof (Trigger));
- build = &(triggers[found]);
-
- build->tgname = nameout (&(pg_trigger->tgname));
- build->tgfoid = pg_trigger->tgfoid;
- build->tgfunc = NULL;
- build->tgtype = pg_trigger->tgtype;
- build->tgnargs = pg_trigger->tgnargs;
- memcpy (build->tgattr, &(pg_trigger->tgattr), 8 * sizeof (int16));
- val = (struct varlena*) fastgetattr (tuple,
- Anum_pg_trigger_tgargs,
- tgrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "RelationBuildTriggers: tgargs IS NULL for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
- if ( build->tgnargs > 0 )
- {
- char *p;
- int i;
-
- val = (struct varlena*) fastgetattr (tuple,
- Anum_pg_trigger_tgargs,
- tgrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "RelationBuildTriggers: tgargs IS NULL for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
- p = (char *) VARDATA (val);
- build->tgargs = (char**) palloc (build->tgnargs * sizeof (char*));
- for (i = 0; i < build->tgnargs; i++)
- {
- build->tgargs[i] = (char*) palloc (strlen (p) + 1);
- strcpy (build->tgargs[i], p);
- p += strlen (p) + 1;
- }
- }
- else
- build->tgargs = NULL;
-
- found++;
- ReleaseBuffer(buffer);
- }
-
- if ( found < ntrigs )
- elog (WARN, "RelationBuildTriggers: %d record not found for rel %.*s",
- ntrigs - found,
- NAMEDATALEN, relation->rd_rel->relname.data);
-
- index_endscan (sd);
- pfree (sd);
- index_close (irel);
- RelationUnsetLockForRead (tgrel);
- heap_close (tgrel);
-
- /* Build trigdesc */
- trigdesc->triggers = triggers;
- for (found = 0; found < ntrigs; found++)
- {
- build = &(triggers[found]);
- DescribeTrigger (trigdesc, build);
- }
-
- relation->trigdesc = trigdesc;
-
+ TriggerDesc *trigdesc = (TriggerDesc *) palloc(sizeof(TriggerDesc));
+ int ntrigs = relation->rd_rel->reltriggers;
+ Trigger *triggers = NULL;
+ Trigger *build;
+ Relation tgrel;
+ Form_pg_trigger pg_trigger;
+ Relation irel;
+ ScanKeyData skey;
+ HeapTuple tuple;
+ IndexScanDesc sd;
+ RetrieveIndexResult indexRes;
+ Buffer buffer;
+ ItemPointer iptr;
+ struct varlena *val;
+ bool isnull;
+ int found;
+
+ memset(trigdesc, 0, sizeof(TriggerDesc));
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relation->rd_id));
+
+ tgrel = heap_openr(TriggerRelationName);
+ RelationSetLockForRead(tgrel);
+ irel = index_openr(TriggerRelidIndex);
+ sd = index_beginscan(irel, false, 1, &skey);
+
+ for (found = 0;;)
+ {
+ indexRes = index_getnext(sd, ForwardScanDirection);
+ if (!indexRes)
+ break;
+
+ iptr = &indexRes->heap_iptr;
+ tuple = heap_fetch(tgrel, NowTimeQual, iptr, &buffer);
+ pfree(indexRes);
+ if (!HeapTupleIsValid(tuple))
+ continue;
+ if (found == ntrigs)
+ elog(WARN, "RelationBuildTriggers: unexpected record found for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+
+ pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
+
+ if (triggers == NULL)
+ triggers = (Trigger *) palloc(sizeof(Trigger));
+ else
+ triggers = (Trigger *) repalloc(triggers, (found + 1) * sizeof(Trigger));
+ build = &(triggers[found]);
+
+ build->tgname = nameout(&(pg_trigger->tgname));
+ build->tgfoid = pg_trigger->tgfoid;
+ build->tgfunc = NULL;
+ build->tgtype = pg_trigger->tgtype;
+ build->tgnargs = pg_trigger->tgnargs;
+ memcpy(build->tgattr, &(pg_trigger->tgattr), 8 * sizeof(int16));
+ val = (struct varlena *) fastgetattr(tuple,
+ Anum_pg_trigger_tgargs,
+ tgrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "RelationBuildTriggers: tgargs IS NULL for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ if (build->tgnargs > 0)
+ {
+ char *p;
+ int i;
+
+ val = (struct varlena *) fastgetattr(tuple,
+ Anum_pg_trigger_tgargs,
+ tgrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "RelationBuildTriggers: tgargs IS NULL for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ p = (char *) VARDATA(val);
+ build->tgargs = (char **) palloc(build->tgnargs * sizeof(char *));
+ for (i = 0; i < build->tgnargs; i++)
+ {
+ build->tgargs[i] = (char *) palloc(strlen(p) + 1);
+ strcpy(build->tgargs[i], p);
+ p += strlen(p) + 1;
+ }
+ }
+ else
+ build->tgargs = NULL;
+
+ found++;
+ ReleaseBuffer(buffer);
+ }
+
+ if (found < ntrigs)
+ elog(WARN, "RelationBuildTriggers: %d record not found for rel %.*s",
+ ntrigs - found,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+
+ index_endscan(sd);
+ pfree(sd);
+ index_close(irel);
+ RelationUnsetLockForRead(tgrel);
+ heap_close(tgrel);
+
+ /* Build trigdesc */
+ trigdesc->triggers = triggers;
+ for (found = 0; found < ntrigs; found++)
+ {
+ build = &(triggers[found]);
+ DescribeTrigger(trigdesc, build);
+ }
+
+ relation->trigdesc = trigdesc;
+
}
-void
-FreeTriggerDesc (Relation relation)
+void
+FreeTriggerDesc(Relation relation)
{
- TriggerDesc *trigdesc = relation->trigdesc;
- Trigger ***t;
- Trigger *trigger;
- int i;
-
- if ( trigdesc == NULL )
- return;
-
- t = trigdesc->tg_before_statement;
- for (i = 0; i < 3; i++)
- if ( t[i] != NULL )
- pfree (t[i]);
- t = trigdesc->tg_before_row;
- for (i = 0; i < 3; i++)
- if ( t[i] != NULL )
- pfree (t[i]);
- t = trigdesc->tg_after_row;
- for (i = 0; i < 3; i++)
- if ( t[i] != NULL )
- pfree (t[i]);
- t = trigdesc->tg_after_statement;
- for (i = 0; i < 3; i++)
- if ( t[i] != NULL )
- pfree (t[i]);
-
- trigger = trigdesc->triggers;
- for (i = 0; i < relation->rd_rel->reltriggers; i++)
- {
- pfree (trigger->tgname);
- if ( trigger->tgnargs > 0 )
- {
- while ( --(trigger->tgnargs) >= 0 )
- pfree (trigger->tgargs[trigger->tgnargs]);
- pfree (trigger->tgargs);
- }
- trigger++;
- }
- pfree (trigdesc->triggers);
- pfree (trigdesc);
- relation->trigdesc = NULL;
- return;
+ TriggerDesc *trigdesc = relation->trigdesc;
+ Trigger ***t;
+ Trigger *trigger;
+ int i;
+
+ if (trigdesc == NULL)
+ return;
+
+ t = trigdesc->tg_before_statement;
+ for (i = 0; i < 3; i++)
+ if (t[i] != NULL)
+ pfree(t[i]);
+ t = trigdesc->tg_before_row;
+ for (i = 0; i < 3; i++)
+ if (t[i] != NULL)
+ pfree(t[i]);
+ t = trigdesc->tg_after_row;
+ for (i = 0; i < 3; i++)
+ if (t[i] != NULL)
+ pfree(t[i]);
+ t = trigdesc->tg_after_statement;
+ for (i = 0; i < 3; i++)
+ if (t[i] != NULL)
+ pfree(t[i]);
+
+ trigger = trigdesc->triggers;
+ for (i = 0; i < relation->rd_rel->reltriggers; i++)
+ {
+ pfree(trigger->tgname);
+ if (trigger->tgnargs > 0)
+ {
+ while (--(trigger->tgnargs) >= 0)
+ pfree(trigger->tgargs[trigger->tgnargs]);
+ pfree(trigger->tgargs);
+ }
+ trigger++;
+ }
+ pfree(trigdesc->triggers);
+ pfree(trigdesc);
+ relation->trigdesc = NULL;
+ return;
}
static void
-DescribeTrigger (TriggerDesc *trigdesc, Trigger *trigger)
+DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger)
{
- uint16 *n;
- Trigger ***t, ***tp;
-
- if ( TRIGGER_FOR_ROW (trigger->tgtype) ) /* Is ROW/STATEMENT trigger */
- {
- if ( TRIGGER_FOR_BEFORE (trigger->tgtype) )
- {
- n = trigdesc->n_before_row;
- t = trigdesc->tg_before_row;
- }
- else
- {
- n = trigdesc->n_after_row;
- t = trigdesc->tg_after_row;
- }
- }
- else /* STATEMENT (NI) */
- {
- if ( TRIGGER_FOR_BEFORE (trigger->tgtype) )
- {
- n = trigdesc->n_before_statement;
- t = trigdesc->tg_before_statement;
- }
- else
- {
- n = trigdesc->n_after_statement;
- t = trigdesc->tg_after_statement;
- }
- }
-
- if ( TRIGGER_FOR_INSERT (trigger->tgtype) )
- {
- tp = &(t[TRIGGER_EVENT_INSERT]);
- if ( *tp == NULL )
- *tp = (Trigger **) palloc (sizeof (Trigger *));
- else
- *tp = (Trigger **) repalloc (*tp, (n[TRIGGER_EVENT_INSERT] + 1) *
- sizeof (Trigger *));
- (*tp)[n[TRIGGER_EVENT_INSERT]] = trigger;
- (n[TRIGGER_EVENT_INSERT])++;
- }
-
- if ( TRIGGER_FOR_DELETE (trigger->tgtype) )
- {
- tp = &(t[TRIGGER_EVENT_DELETE]);
- if ( *tp == NULL )
- *tp = (Trigger **) palloc (sizeof (Trigger *));
- else
- *tp = (Trigger **) repalloc (*tp, (n[TRIGGER_EVENT_DELETE] + 1) *
- sizeof (Trigger *));
- (*tp)[n[TRIGGER_EVENT_DELETE]] = trigger;
- (n[TRIGGER_EVENT_DELETE])++;
- }
-
- if ( TRIGGER_FOR_UPDATE (trigger->tgtype) )
- {
- tp = &(t[TRIGGER_EVENT_UPDATE]);
- if ( *tp == NULL )
- *tp = (Trigger **) palloc (sizeof (Trigger *));
- else
- *tp = (Trigger **) repalloc (*tp, (n[TRIGGER_EVENT_UPDATE] + 1) *
- sizeof (Trigger *));
- (*tp)[n[TRIGGER_EVENT_UPDATE]] = trigger;
- (n[TRIGGER_EVENT_UPDATE])++;
- }
-
+ uint16 *n;
+ Trigger ***t,
+ ***tp;
+
+ if (TRIGGER_FOR_ROW(trigger->tgtype)) /* Is ROW/STATEMENT
+ * trigger */
+ {
+ if (TRIGGER_FOR_BEFORE(trigger->tgtype))
+ {
+ n = trigdesc->n_before_row;
+ t = trigdesc->tg_before_row;
+ }
+ else
+ {
+ n = trigdesc->n_after_row;
+ t = trigdesc->tg_after_row;
+ }
+ }
+ else
+/* STATEMENT (NI) */
+ {
+ if (TRIGGER_FOR_BEFORE(trigger->tgtype))
+ {
+ n = trigdesc->n_before_statement;
+ t = trigdesc->tg_before_statement;
+ }
+ else
+ {
+ n = trigdesc->n_after_statement;
+ t = trigdesc->tg_after_statement;
+ }
+ }
+
+ if (TRIGGER_FOR_INSERT(trigger->tgtype))
+ {
+ tp = &(t[TRIGGER_EVENT_INSERT]);
+ if (*tp == NULL)
+ *tp = (Trigger **) palloc(sizeof(Trigger *));
+ else
+ *tp = (Trigger **) repalloc(*tp, (n[TRIGGER_EVENT_INSERT] + 1) *
+ sizeof(Trigger *));
+ (*tp)[n[TRIGGER_EVENT_INSERT]] = trigger;
+ (n[TRIGGER_EVENT_INSERT])++;
+ }
+
+ if (TRIGGER_FOR_DELETE(trigger->tgtype))
+ {
+ tp = &(t[TRIGGER_EVENT_DELETE]);
+ if (*tp == NULL)
+ *tp = (Trigger **) palloc(sizeof(Trigger *));
+ else
+ *tp = (Trigger **) repalloc(*tp, (n[TRIGGER_EVENT_DELETE] + 1) *
+ sizeof(Trigger *));
+ (*tp)[n[TRIGGER_EVENT_DELETE]] = trigger;
+ (n[TRIGGER_EVENT_DELETE])++;
+ }
+
+ if (TRIGGER_FOR_UPDATE(trigger->tgtype))
+ {
+ tp = &(t[TRIGGER_EVENT_UPDATE]);
+ if (*tp == NULL)
+ *tp = (Trigger **) palloc(sizeof(Trigger *));
+ else
+ *tp = (Trigger **) repalloc(*tp, (n[TRIGGER_EVENT_UPDATE] + 1) *
+ sizeof(Trigger *));
+ (*tp)[n[TRIGGER_EVENT_UPDATE]] = trigger;
+ (n[TRIGGER_EVENT_UPDATE])++;
+ }
+
}
-HeapTuple
-ExecBRInsertTriggers (Relation rel, HeapTuple tuple)
+HeapTuple
+ExecBRInsertTriggers(Relation rel, HeapTuple tuple)
{
- int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT];
- Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
- HeapTuple newtuple = tuple;
- int nargs;
- int i;
-
- CurrentTriggerData = (TriggerData *) palloc (sizeof (TriggerData));
- CurrentTriggerData->tg_event = TRIGGER_EVENT_INSERT|TRIGGER_EVENT_ROW;
- CurrentTriggerData->tg_relation = rel;
- CurrentTriggerData->tg_newtuple = NULL;
- for (i = 0; i < ntrigs; i++)
- {
- CurrentTriggerData->tg_trigtuple = newtuple;
- CurrentTriggerData->tg_trigger = trigger[i];
- if ( trigger[i]->tgfunc == NULL )
- fmgr_info (trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
- newtuple = (HeapTuple) ( (*(trigger[i]->tgfunc)) () );
- if ( newtuple == NULL )
- break;
- }
- pfree (CurrentTriggerData);
- CurrentTriggerData = NULL;
- return (newtuple);
+ int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT];
+ Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
+ HeapTuple newtuple = tuple;
+ int nargs;
+ int i;
+
+ CurrentTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
+ CurrentTriggerData->tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
+ CurrentTriggerData->tg_relation = rel;
+ CurrentTriggerData->tg_newtuple = NULL;
+ for (i = 0; i < ntrigs; i++)
+ {
+ CurrentTriggerData->tg_trigtuple = newtuple;
+ CurrentTriggerData->tg_trigger = trigger[i];
+ if (trigger[i]->tgfunc == NULL)
+ fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
+ newtuple = (HeapTuple) ((*(trigger[i]->tgfunc)) ());
+ if (newtuple == NULL)
+ break;
+ }
+ pfree(CurrentTriggerData);
+ CurrentTriggerData = NULL;
+ return (newtuple);
}
void
-ExecARInsertTriggers (Relation rel, HeapTuple tuple)
+ExecARInsertTriggers(Relation rel, HeapTuple tuple)
{
-
- return;
+
+ return;
}
bool
-ExecBRDeleteTriggers (Relation rel, ItemPointer tupleid)
+ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid)
{
-
- return (true);
+
+ return (true);
}
void
-ExecARDeleteTriggers (Relation rel, ItemPointer tupleid)
+ExecARDeleteTriggers(Relation rel, ItemPointer tupleid)
{
-
- return;
+
+ return;
}
HeapTuple
-ExecBRUpdateTriggers (Relation rel, ItemPointer tupleid, HeapTuple tuple)
+ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple)
{
-
- return (tuple);
+
+ return (tuple);
}
void
-ExecARUpdateTriggers (Relation rel, ItemPointer tupleid, HeapTuple tuple)
+ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple)
{
-
- return;
+
+ return;
}
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 0c480581179..30690f0f32b 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* vacuum.c--
- * the postgres vacuum cleaner
+ * the postgres vacuum cleaner
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.42 1997/08/22 04:13:08 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.43 1997/09/07 04:41:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -48,2220 +48,2364 @@
#include <storage/bufpage.h>
#include "storage/shmem.h"
#ifndef HAVE_GETRUSAGE
-# include <rusagestub.h>
-#else
-# include <sys/time.h>
-# include <sys/resource.h>
-#endif
+#include <rusagestub.h>
+#else
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
#include <port-protos.h>
-bool VacuumRunning = false;
+bool VacuumRunning = false;
-static Portal vc_portal;
+static Portal vc_portal;
-static int MESSAGE_LEVEL; /* message level */
+static int MESSAGE_LEVEL; /* message level */
#define swapLong(a,b) {long tmp; tmp=a; a=b; b=tmp;}
#define swapInt(a,b) {int tmp; tmp=a; a=b; b=tmp;}
#define swapDatum(a,b) {Datum tmp; tmp=a; a=b; b=tmp;}
#define VacAttrStatsEqValid(stats) ( stats->f_cmpeq != NULL )
#define VacAttrStatsLtGtValid(stats) ( stats->f_cmplt != NULL && \
- stats->f_cmpgt != NULL && \
- RegProcedureIsValid(stats->outfunc) )
-
+ stats->f_cmpgt != NULL && \
+ RegProcedureIsValid(stats->outfunc) )
+
/* non-export function prototypes */
-static void vc_init(void);
-static void vc_shutdown(void);
-static void vc_vacuum(NameData *VacRelP, bool analyze, List *va_cols);
-static VRelList vc_getrels(NameData *VacRelP);
-static void vc_vacone (Oid relid, bool analyze, List *va_cols);
-static void vc_scanheap (VRelStats *vacrelstats, Relation onerel, VPageList Vvpl, VPageList Fvpl);
-static void vc_rpfheap (VRelStats *vacrelstats, Relation onerel, VPageList Vvpl, VPageList Fvpl, int nindices, Relation *Irel);
-static void vc_vacheap (VRelStats *vacrelstats, Relation onerel, VPageList vpl);
-static void vc_vacpage (Page page, VPageDescr vpd, Relation archrel);
-static void vc_vaconeind (VPageList vpl, Relation indrel, int nhtups);
-static void vc_scanoneind (Relation indrel, int nhtups);
-static void vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple htup);
-static void vc_bucketcpy(AttributeTupleForm attr, Datum value, Datum *bucket, int16 *bucket_len);
-static void vc_updstats(Oid relid, int npages, int ntups, bool hasindex, VRelStats *vacrelstats);
-static void vc_delhilowstats (Oid relid, int attcnt, int *attnums);
-static void vc_setpagelock(Relation rel, BlockNumber blkno);
-static VPageDescr vc_tidreapped (ItemPointer itemptr, VPageList vpl);
-static void vc_reappage (VPageList vpl, VPageDescr vpc);
-static void vc_vpinsert (VPageList vpl, VPageDescr vpnew);
-static void vc_free(VRelList vrl);
-static void vc_getindices (Oid relid, int *nindices, Relation **Irel);
-static void vc_clsindices (int nindices, Relation *Irel);
+static void vc_init(void);
+static void vc_shutdown(void);
+static void vc_vacuum(NameData * VacRelP, bool analyze, List * va_cols);
+static VRelList vc_getrels(NameData * VacRelP);
+static void vc_vacone(Oid relid, bool analyze, List * va_cols);
+static void vc_scanheap(VRelStats * vacrelstats, Relation onerel, VPageList Vvpl, VPageList Fvpl);
+static void vc_rpfheap(VRelStats * vacrelstats, Relation onerel, VPageList Vvpl, VPageList Fvpl, int nindices, Relation * Irel);
+static void vc_vacheap(VRelStats * vacrelstats, Relation onerel, VPageList vpl);
+static void vc_vacpage(Page page, VPageDescr vpd, Relation archrel);
+static void vc_vaconeind(VPageList vpl, Relation indrel, int nhtups);
+static void vc_scanoneind(Relation indrel, int nhtups);
+static void vc_attrstats(Relation onerel, VRelStats * vacrelstats, HeapTuple htup);
+static void vc_bucketcpy(AttributeTupleForm attr, Datum value, Datum * bucket, int16 * bucket_len);
+static void vc_updstats(Oid relid, int npages, int ntups, bool hasindex, VRelStats * vacrelstats);
+static void vc_delhilowstats(Oid relid, int attcnt, int *attnums);
+static void vc_setpagelock(Relation rel, BlockNumber blkno);
+static VPageDescr vc_tidreapped(ItemPointer itemptr, VPageList vpl);
+static void vc_reappage(VPageList vpl, VPageDescr vpc);
+static void vc_vpinsert(VPageList vpl, VPageDescr vpnew);
+static void vc_free(VRelList vrl);
+static void vc_getindices(Oid relid, int *nindices, Relation ** Irel);
+static void vc_clsindices(int nindices, Relation * Irel);
static Relation vc_getarchrel(Relation heaprel);
-static void vc_archive(Relation archrel, HeapTuple htup);
-static bool vc_isarchrel(char *rname);
-static void vc_mkindesc (Relation onerel, int nindices, Relation *Irel, IndDesc **Idesc);
-static char * vc_find_eq (char *bot, int nelem, int size, char *elm, int (*compar)(char *, char *));
-static int vc_cmp_blk (char *left, char *right);
-static int vc_cmp_offno (char *left, char *right);
-static bool vc_enough_space (VPageDescr vpd, Size len);
+static void vc_archive(Relation archrel, HeapTuple htup);
+static bool vc_isarchrel(char *rname);
+static void vc_mkindesc(Relation onerel, int nindices, Relation * Irel, IndDesc ** Idesc);
+static char *vc_find_eq(char *bot, int nelem, int size, char *elm, int (*compar) (char *, char *));
+static int vc_cmp_blk(char *left, char *right);
+static int vc_cmp_offno(char *left, char *right);
+static bool vc_enough_space(VPageDescr vpd, Size len);
void
-vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
+vacuum(char *vacrel, bool verbose, bool analyze, List * va_spec)
{
- char *pname;
- MemoryContext old;
- PortalVariableMemory pmem;
- NameData VacRel;
- List *le;
- List *va_cols = NIL;
-
- /*
- * Create a portal for safe memory across transctions. We need to
- * palloc the name space for it because our hash function expects
- * the name to be on a longword boundary. CreatePortal copies the
- * name to safe storage for us.
- */
- pname = (char *) palloc(strlen(VACPNAME) + 1);
- strcpy(pname, VACPNAME);
- vc_portal = CreatePortal(pname);
- pfree(pname);
-
- if (verbose)
- MESSAGE_LEVEL = NOTICE;
- else
- MESSAGE_LEVEL = DEBUG;
-
- /* vacrel gets de-allocated on transaction commit */
- if (vacrel)
- strcpy(VacRel.data,vacrel);
-
- pmem = PortalGetVariableMemory(vc_portal);
- old = MemoryContextSwitchTo((MemoryContext)pmem);
-
- Assert ( va_spec == NIL || analyze );
- foreach (le, va_spec)
- {
- char *col = (char*)lfirst(le);
- char *dest;
-
- dest = (char*) palloc (strlen (col) + 1);
- strcpy (dest, col);
- va_cols = lappend (va_cols, dest);
- }
- MemoryContextSwitchTo(old);
-
- /* initialize vacuum cleaner */
- vc_init();
-
- /* vacuum the database */
- if (vacrel)
- vc_vacuum (&VacRel, analyze, va_cols);
- else
- vc_vacuum (NULL, analyze, NIL);
-
- PortalDestroy (&vc_portal);
-
- /* clean up */
- vc_shutdown();
+ char *pname;
+ MemoryContext old;
+ PortalVariableMemory pmem;
+ NameData VacRel;
+ List *le;
+ List *va_cols = NIL;
+
+ /*
+ * Create a portal for safe memory across transctions. We need to
+ * palloc the name space for it because our hash function expects the
+ * name to be on a longword boundary. CreatePortal copies the name to
+ * safe storage for us.
+ */
+ pname = (char *) palloc(strlen(VACPNAME) + 1);
+ strcpy(pname, VACPNAME);
+ vc_portal = CreatePortal(pname);
+ pfree(pname);
+
+ if (verbose)
+ MESSAGE_LEVEL = NOTICE;
+ else
+ MESSAGE_LEVEL = DEBUG;
+
+ /* vacrel gets de-allocated on transaction commit */
+ if (vacrel)
+ strcpy(VacRel.data, vacrel);
+
+ pmem = PortalGetVariableMemory(vc_portal);
+ old = MemoryContextSwitchTo((MemoryContext) pmem);
+
+ Assert(va_spec == NIL || analyze);
+ foreach(le, va_spec)
+ {
+ char *col = (char *) lfirst(le);
+ char *dest;
+
+ dest = (char *) palloc(strlen(col) + 1);
+ strcpy(dest, col);
+ va_cols = lappend(va_cols, dest);
+ }
+ MemoryContextSwitchTo(old);
+
+ /* initialize vacuum cleaner */
+ vc_init();
+
+ /* vacuum the database */
+ if (vacrel)
+ vc_vacuum(&VacRel, analyze, va_cols);
+ else
+ vc_vacuum(NULL, analyze, NIL);
+
+ PortalDestroy(&vc_portal);
+
+ /* clean up */
+ vc_shutdown();
}
/*
- * vc_init(), vc_shutdown() -- start up and shut down the vacuum cleaner.
+ * vc_init(), vc_shutdown() -- start up and shut down the vacuum cleaner.
*
- * We run exactly one vacuum cleaner at a time. We use the file system
- * to guarantee an exclusive lock on vacuuming, since a single vacuum
- * cleaner instantiation crosses transaction boundaries, and we'd lose
- * postgres-style locks at the end of every transaction.
+ * We run exactly one vacuum cleaner at a time. We use the file system
+ * to guarantee an exclusive lock on vacuuming, since a single vacuum
+ * cleaner instantiation crosses transaction boundaries, and we'd lose
+ * postgres-style locks at the end of every transaction.
*
- * The strangeness with committing and starting transactions in the
- * init and shutdown routines is due to the fact that the vacuum cleaner
- * is invoked via a sql command, and so is already executing inside
- * a transaction. We need to leave ourselves in a predictable state
- * on entry and exit to the vacuum cleaner. We commit the transaction
- * started in PostgresMain() inside vc_init(), and start one in
- * vc_shutdown() to match the commit waiting for us back in
- * PostgresMain().
+ * The strangeness with committing and starting transactions in the
+ * init and shutdown routines is due to the fact that the vacuum cleaner
+ * is invoked via a sql command, and so is already executing inside
+ * a transaction. We need to leave ourselves in a predictable state
+ * on entry and exit to the vacuum cleaner. We commit the transaction
+ * started in PostgresMain() inside vc_init(), and start one in
+ * vc_shutdown() to match the commit waiting for us back in
+ * PostgresMain().
*/
static void
vc_init()
{
- int fd;
+ int fd;
- if ((fd = open("pg_vlock", O_CREAT|O_EXCL, 0600)) < 0)
- elog(WARN, "can't create lock file -- another vacuum cleaner running?");
+ if ((fd = open("pg_vlock", O_CREAT | O_EXCL, 0600)) < 0)
+ elog(WARN, "can't create lock file -- another vacuum cleaner running?");
- close(fd);
+ close(fd);
- /*
- * By here, exclusive open on the lock file succeeded. If we abort
- * for any reason during vacuuming, we need to remove the lock file.
- * This global variable is checked in the transaction manager on xact
- * abort, and the routine vc_abort() is called if necessary.
- */
+ /*
+ * By here, exclusive open on the lock file succeeded. If we abort
+ * for any reason during vacuuming, we need to remove the lock file.
+ * This global variable is checked in the transaction manager on xact
+ * abort, and the routine vc_abort() is called if necessary.
+ */
- VacuumRunning = true;
+ VacuumRunning = true;
- /* matches the StartTransaction in PostgresMain() */
- CommitTransactionCommand();
+ /* matches the StartTransaction in PostgresMain() */
+ CommitTransactionCommand();
}
static void
vc_shutdown()
{
- /* on entry, not in a transaction */
- if (unlink("pg_vlock") < 0)
- elog(WARN, "vacuum: can't destroy lock file!");
+ /* on entry, not in a transaction */
+ if (unlink("pg_vlock") < 0)
+ elog(WARN, "vacuum: can't destroy lock file!");
- /* okay, we're done */
- VacuumRunning = false;
+ /* okay, we're done */
+ VacuumRunning = false;
- /* matches the CommitTransaction in PostgresMain() */
- StartTransactionCommand();
+ /* matches the CommitTransaction in PostgresMain() */
+ StartTransactionCommand();
}
void
vc_abort()
{
- /* on abort, remove the vacuum cleaner lock file */
- unlink("pg_vlock");
+ /* on abort, remove the vacuum cleaner lock file */
+ unlink("pg_vlock");
- VacuumRunning = false;
+ VacuumRunning = false;
}
/*
- * vc_vacuum() -- vacuum the database.
+ * vc_vacuum() -- vacuum the database.
*
- * This routine builds a list of relations to vacuum, and then calls
- * code that vacuums them one at a time. We are careful to vacuum each
- * relation in a separate transaction in order to avoid holding too many
- * locks at one time.
+ * This routine builds a list of relations to vacuum, and then calls
+ * code that vacuums them one at a time. We are careful to vacuum each
+ * relation in a separate transaction in order to avoid holding too many
+ * locks at one time.
*/
static void
-vc_vacuum(NameData *VacRelP, bool analyze, List *va_cols)
+vc_vacuum(NameData * VacRelP, bool analyze, List * va_cols)
{
- VRelList vrl, cur;
+ VRelList vrl,
+ cur;
+
+ /* get list of relations */
+ vrl = vc_getrels(VacRelP);
- /* get list of relations */
- vrl = vc_getrels(VacRelP);
+ if (analyze && VacRelP == NULL && vrl != NULL)
+ vc_delhilowstats(InvalidOid, 0, NULL);
- if ( analyze && VacRelP == NULL && vrl != NULL )
- vc_delhilowstats (InvalidOid, 0, NULL);
-
- /* vacuum each heap relation */
- for (cur = vrl; cur != (VRelList) NULL; cur = cur->vrl_next)
- vc_vacone (cur->vrl_relid, analyze, va_cols);
+ /* vacuum each heap relation */
+ for (cur = vrl; cur != (VRelList) NULL; cur = cur->vrl_next)
+ vc_vacone(cur->vrl_relid, analyze, va_cols);
- vc_free(vrl);
+ vc_free(vrl);
}
-static VRelList
-vc_getrels(NameData *VacRelP)
+static VRelList
+vc_getrels(NameData * VacRelP)
{
- Relation pgclass;
- TupleDesc pgcdesc;
- HeapScanDesc pgcscan;
- HeapTuple pgctup;
- Buffer buf;
- PortalVariableMemory portalmem;
- MemoryContext old;
- VRelList vrl, cur;
- Datum d;
- char *rname;
- char rkind;
- int16 smgrno;
- bool n;
- ScanKeyData pgckey;
- bool found = false;
-
- StartTransactionCommand();
-
- if (VacRelP->data) {
- ScanKeyEntryInitialize(&pgckey, 0x0, Anum_pg_class_relname,
- NameEqualRegProcedure,
- PointerGetDatum(VacRelP->data));
- } else {
- ScanKeyEntryInitialize(&pgckey, 0x0, Anum_pg_class_relkind,
- CharacterEqualRegProcedure, CharGetDatum('r'));
- }
-
- portalmem = PortalGetVariableMemory(vc_portal);
- vrl = cur = (VRelList) NULL;
-
- pgclass = heap_openr(RelationRelationName);
- pgcdesc = RelationGetTupleDescriptor(pgclass);
-
- pgcscan = heap_beginscan(pgclass, false, NowTimeQual, 1, &pgckey);
-
- while (HeapTupleIsValid(pgctup = heap_getnext(pgcscan, 0, &buf))) {
-
- found = true;
-
- /*
- * We have to be careful not to vacuum the archive (since it
- * already contains vacuumed tuples), and not to vacuum
- * relations on write-once storage managers like the Sony
- * jukebox at Berkeley.
- */
+ Relation pgclass;
+ TupleDesc pgcdesc;
+ HeapScanDesc pgcscan;
+ HeapTuple pgctup;
+ Buffer buf;
+ PortalVariableMemory portalmem;
+ MemoryContext old;
+ VRelList vrl,
+ cur;
+ Datum d;
+ char *rname;
+ char rkind;
+ int16 smgrno;
+ bool n;
+ ScanKeyData pgckey;
+ bool found = false;
+
+ StartTransactionCommand();
+
+ if (VacRelP->data)
+ {
+ ScanKeyEntryInitialize(&pgckey, 0x0, Anum_pg_class_relname,
+ NameEqualRegProcedure,
+ PointerGetDatum(VacRelP->data));
+ }
+ else
+ {
+ ScanKeyEntryInitialize(&pgckey, 0x0, Anum_pg_class_relkind,
+ CharacterEqualRegProcedure, CharGetDatum('r'));
+ }
- d = (Datum) heap_getattr(pgctup, buf, Anum_pg_class_relname,
- pgcdesc, &n);
- rname = (char*)d;
+ portalmem = PortalGetVariableMemory(vc_portal);
+ vrl = cur = (VRelList) NULL;
- /* skip archive relations */
- if (vc_isarchrel(rname)) {
- ReleaseBuffer(buf);
- continue;
- }
+ pgclass = heap_openr(RelationRelationName);
+ pgcdesc = RelationGetTupleDescriptor(pgclass);
+
+ pgcscan = heap_beginscan(pgclass, false, NowTimeQual, 1, &pgckey);
- /* don't vacuum large objects for now - something breaks when we do */
- if ( (strlen(rname) >= 5) && rname[0] == 'x' &&
- rname[1] == 'i' && rname[2] == 'n' &&
- (rname[3] == 'v' || rname[3] == 'x') &&
- rname[4] >= '0' && rname[4] <= '9')
+ while (HeapTupleIsValid(pgctup = heap_getnext(pgcscan, 0, &buf)))
{
- elog (NOTICE, "Rel %s: can't vacuum LargeObjects now",
- rname);
- ReleaseBuffer(buf);
- continue;
- }
- d = (Datum) heap_getattr(pgctup, buf, Anum_pg_class_relsmgr,
- pgcdesc, &n);
- smgrno = DatumGetInt16(d);
+ found = true;
- /* skip write-once storage managers */
- if (smgriswo(smgrno)) {
- ReleaseBuffer(buf);
- continue;
- }
+ /*
+ * We have to be careful not to vacuum the archive (since it
+ * already contains vacuumed tuples), and not to vacuum relations
+ * on write-once storage managers like the Sony jukebox at
+ * Berkeley.
+ */
- d = (Datum) heap_getattr(pgctup, buf, Anum_pg_class_relkind,
- pgcdesc, &n);
+ d = (Datum) heap_getattr(pgctup, buf, Anum_pg_class_relname,
+ pgcdesc, &n);
+ rname = (char *) d;
- rkind = DatumGetChar(d);
+ /* skip archive relations */
+ if (vc_isarchrel(rname))
+ {
+ ReleaseBuffer(buf);
+ continue;
+ }
- /* skip system relations */
- if (rkind != 'r') {
- ReleaseBuffer(buf);
- elog(NOTICE, "Vacuum: can not process index and certain system tables" );
- continue;
- }
-
- /* get a relation list entry for this guy */
- old = MemoryContextSwitchTo((MemoryContext)portalmem);
- if (vrl == (VRelList) NULL) {
- vrl = cur = (VRelList) palloc(sizeof(VRelListData));
- } else {
- cur->vrl_next = (VRelList) palloc(sizeof(VRelListData));
- cur = cur->vrl_next;
- }
- MemoryContextSwitchTo(old);
+ /*
+ * don't vacuum large objects for now - something breaks when we
+ * do
+ */
+ if ((strlen(rname) >= 5) && rname[0] == 'x' &&
+ rname[1] == 'i' && rname[2] == 'n' &&
+ (rname[3] == 'v' || rname[3] == 'x') &&
+ rname[4] >= '0' && rname[4] <= '9')
+ {
+ elog(NOTICE, "Rel %s: can't vacuum LargeObjects now",
+ rname);
+ ReleaseBuffer(buf);
+ continue;
+ }
+
+ d = (Datum) heap_getattr(pgctup, buf, Anum_pg_class_relsmgr,
+ pgcdesc, &n);
+ smgrno = DatumGetInt16(d);
+
+ /* skip write-once storage managers */
+ if (smgriswo(smgrno))
+ {
+ ReleaseBuffer(buf);
+ continue;
+ }
+
+ d = (Datum) heap_getattr(pgctup, buf, Anum_pg_class_relkind,
+ pgcdesc, &n);
+
+ rkind = DatumGetChar(d);
+
+ /* skip system relations */
+ if (rkind != 'r')
+ {
+ ReleaseBuffer(buf);
+ elog(NOTICE, "Vacuum: can not process index and certain system tables");
+ continue;
+ }
- cur->vrl_relid = pgctup->t_oid;
- cur->vrl_next = (VRelList) NULL;
+ /* get a relation list entry for this guy */
+ old = MemoryContextSwitchTo((MemoryContext) portalmem);
+ if (vrl == (VRelList) NULL)
+ {
+ vrl = cur = (VRelList) palloc(sizeof(VRelListData));
+ }
+ else
+ {
+ cur->vrl_next = (VRelList) palloc(sizeof(VRelListData));
+ cur = cur->vrl_next;
+ }
+ MemoryContextSwitchTo(old);
- /* wei hates it if you forget to do this */
- ReleaseBuffer(buf);
- }
- if (found == false)
- elog(NOTICE, "Vacuum: table not found" );
+ cur->vrl_relid = pgctup->t_oid;
+ cur->vrl_next = (VRelList) NULL;
-
- heap_endscan(pgcscan);
- heap_close(pgclass);
+ /* wei hates it if you forget to do this */
+ ReleaseBuffer(buf);
+ }
+ if (found == false)
+ elog(NOTICE, "Vacuum: table not found");
+
+
+ heap_endscan(pgcscan);
+ heap_close(pgclass);
- CommitTransactionCommand();
+ CommitTransactionCommand();
- return (vrl);
+ return (vrl);
}
/*
- * vc_vacone() -- vacuum one heap relation
+ * vc_vacone() -- vacuum one heap relation
*
- * This routine vacuums a single heap, cleans out its indices, and
- * updates its statistics npages and ntups statistics.
+ * This routine vacuums a single heap, cleans out its indices, and
+ * updates its statistics npages and ntups statistics.
*
- * Doing one heap at a time incurs extra overhead, since we need to
- * check that the heap exists again just before we vacuum it. The
- * reason that we do this is so that vacuuming can be spread across
- * many small transactions. Otherwise, two-phase locking would require
- * us to lock the entire database during one pass of the vacuum cleaner.
+ * Doing one heap at a time incurs extra overhead, since we need to
+ * check that the heap exists again just before we vacuum it. The
+ * reason that we do this is so that vacuuming can be spread across
+ * many small transactions. Otherwise, two-phase locking would require
+ * us to lock the entire database during one pass of the vacuum cleaner.
*/
static void
-vc_vacone (Oid relid, bool analyze, List *va_cols)
+vc_vacone(Oid relid, bool analyze, List * va_cols)
{
- Relation pgclass;
- TupleDesc pgcdesc;
- HeapTuple pgctup, pgttup;
- Buffer pgcbuf;
- HeapScanDesc pgcscan;
- Relation onerel;
- ScanKeyData pgckey;
- VPageListData Vvpl; /* List of pages to vacuum and/or clean indices */
- VPageListData Fvpl; /* List of pages with space enough for re-using */
- VPageDescr *vpp;
- Relation *Irel;
- int32 nindices, i;
- VRelStats *vacrelstats;
-
- StartTransactionCommand();
-
- ScanKeyEntryInitialize(&pgckey, 0x0, ObjectIdAttributeNumber,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relid));
-
- pgclass = heap_openr(RelationRelationName);
- pgcdesc = RelationGetTupleDescriptor(pgclass);
- pgcscan = heap_beginscan(pgclass, false, NowTimeQual, 1, &pgckey);
-
- /*
- * Race condition -- if the pg_class tuple has gone away since the
- * last time we saw it, we don't need to vacuum it.
- */
-
- if (!HeapTupleIsValid(pgctup = heap_getnext(pgcscan, 0, &pgcbuf))) {
+ Relation pgclass;
+ TupleDesc pgcdesc;
+ HeapTuple pgctup,
+ pgttup;
+ Buffer pgcbuf;
+ HeapScanDesc pgcscan;
+ Relation onerel;
+ ScanKeyData pgckey;
+ VPageListData Vvpl; /* List of pages to vacuum and/or clean
+ * indices */
+ VPageListData Fvpl; /* List of pages with space enough for
+ * re-using */
+ VPageDescr *vpp;
+ Relation *Irel;
+ int32 nindices,
+ i;
+ VRelStats *vacrelstats;
+
+ StartTransactionCommand();
+
+ ScanKeyEntryInitialize(&pgckey, 0x0, ObjectIdAttributeNumber,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relid));
+
+ pgclass = heap_openr(RelationRelationName);
+ pgcdesc = RelationGetTupleDescriptor(pgclass);
+ pgcscan = heap_beginscan(pgclass, false, NowTimeQual, 1, &pgckey);
+
+ /*
+ * Race condition -- if the pg_class tuple has gone away since the
+ * last time we saw it, we don't need to vacuum it.
+ */
+
+ if (!HeapTupleIsValid(pgctup = heap_getnext(pgcscan, 0, &pgcbuf)))
+ {
+ heap_endscan(pgcscan);
+ heap_close(pgclass);
+ CommitTransactionCommand();
+ return;
+ }
+
+ /* now open the class and vacuum it */
+ onerel = heap_open(relid);
+
+ vacrelstats = (VRelStats *) palloc(sizeof(VRelStats));
+ vacrelstats->relid = relid;
+ vacrelstats->npages = vacrelstats->ntups = 0;
+ vacrelstats->hasindex = false;
+ if (analyze && !IsSystemRelationName((RelationGetRelationName(onerel))->data))
+ {
+ int attr_cnt,
+ *attnums = NULL;
+ AttributeTupleForm *attr;
+
+ attr_cnt = onerel->rd_att->natts;
+ attr = onerel->rd_att->attrs;
+
+ if (va_cols != NIL)
+ {
+ int tcnt = 0;
+ List *le;
+
+ if (length(va_cols) > attr_cnt)
+ elog(WARN, "vacuum: too many attributes specified for relation %s",
+ (RelationGetRelationName(onerel))->data);
+ attnums = (int *) palloc(attr_cnt * sizeof(int));
+ foreach(le, va_cols)
+ {
+ char *col = (char *) lfirst(le);
+
+ for (i = 0; i < attr_cnt; i++)
+ {
+ if (namestrcmp(&(attr[i]->attname), col) == 0)
+ break;
+ }
+ if (i < attr_cnt) /* found */
+ attnums[tcnt++] = i;
+ else
+ {
+ elog(WARN, "vacuum: there is no attribute %s in %s",
+ col, (RelationGetRelationName(onerel))->data);
+ }
+ }
+ attr_cnt = tcnt;
+ }
+
+ vacrelstats->vacattrstats =
+ (VacAttrStats *) palloc(attr_cnt * sizeof(VacAttrStats));
+
+ for (i = 0; i < attr_cnt; i++)
+ {
+ Operator func_operator;
+ OperatorTupleForm pgopform;
+ VacAttrStats *stats;
+
+ stats = &vacrelstats->vacattrstats[i];
+ stats->attr = palloc(ATTRIBUTE_TUPLE_SIZE);
+ memmove(stats->attr, attr[((attnums) ? attnums[i] : i)], ATTRIBUTE_TUPLE_SIZE);
+ stats->best = stats->guess1 = stats->guess2 = 0;
+ stats->max = stats->min = 0;
+ stats->best_len = stats->guess1_len = stats->guess2_len = 0;
+ stats->max_len = stats->min_len = 0;
+ stats->initialized = false;
+ stats->best_cnt = stats->guess1_cnt = stats->guess1_hits = stats->guess2_hits = 0;
+ stats->max_cnt = stats->min_cnt = stats->null_cnt = stats->nonnull_cnt = 0;
+
+ func_operator = oper("=", stats->attr->atttypid, stats->attr->atttypid, true);
+ if (func_operator != NULL)
+ {
+ int nargs;
+
+ pgopform = (OperatorTupleForm) GETSTRUCT(func_operator);
+ fmgr_info(pgopform->oprcode, &(stats->f_cmpeq), &nargs);
+ }
+ else
+ stats->f_cmpeq = NULL;
+
+ func_operator = oper("<", stats->attr->atttypid, stats->attr->atttypid, true);
+ if (func_operator != NULL)
+ {
+ int nargs;
+
+ pgopform = (OperatorTupleForm) GETSTRUCT(func_operator);
+ fmgr_info(pgopform->oprcode, &(stats->f_cmplt), &nargs);
+ }
+ else
+ stats->f_cmplt = NULL;
+
+ func_operator = oper(">", stats->attr->atttypid, stats->attr->atttypid, true);
+ if (func_operator != NULL)
+ {
+ int nargs;
+
+ pgopform = (OperatorTupleForm) GETSTRUCT(func_operator);
+ fmgr_info(pgopform->oprcode, &(stats->f_cmpgt), &nargs);
+ }
+ else
+ stats->f_cmpgt = NULL;
+
+ pgttup = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(stats->attr->atttypid),
+ 0, 0, 0);
+ if (HeapTupleIsValid(pgttup))
+ stats->outfunc = ((TypeTupleForm) GETSTRUCT(pgttup))->typoutput;
+ else
+ stats->outfunc = InvalidOid;
+ }
+ vacrelstats->va_natts = attr_cnt;
+ vc_delhilowstats(relid, ((attnums) ? attr_cnt : 0), attnums);
+ if (attnums)
+ pfree(attnums);
+ }
+ else
+ {
+ vacrelstats->va_natts = 0;
+ vacrelstats->vacattrstats = (VacAttrStats *) NULL;
+ }
+
+ /* we require the relation to be locked until the indices are cleaned */
+ RelationSetLockForWrite(onerel);
+
+ /* scan it */
+ Vvpl.vpl_npages = Fvpl.vpl_npages = 0;
+ vc_scanheap(vacrelstats, onerel, &Vvpl, &Fvpl);
+
+ /* Now open indices */
+ Irel = (Relation *) NULL;
+ vc_getindices(vacrelstats->relid, &nindices, &Irel);
+
+ if (nindices > 0)
+ vacrelstats->hasindex = true;
+ else
+ vacrelstats->hasindex = false;
+
+ /* Clean/scan index relation(s) */
+ if (Irel != (Relation *) NULL)
+ {
+ if (Vvpl.vpl_npages > 0)
+ {
+ for (i = 0; i < nindices; i++)
+ vc_vaconeind(&Vvpl, Irel[i], vacrelstats->ntups);
+ }
+ else
+/* just scan indices to update statistic */
+ {
+ for (i = 0; i < nindices; i++)
+ vc_scanoneind(Irel[i], vacrelstats->ntups);
+ }
+ }
+
+ if (Fvpl.vpl_npages > 0) /* Try to shrink heap */
+ vc_rpfheap(vacrelstats, onerel, &Vvpl, &Fvpl, nindices, Irel);
+ else
+ {
+ if (Irel != (Relation *) NULL)
+ vc_clsindices(nindices, Irel);
+ if (Vvpl.vpl_npages > 0)/* Clean pages from Vvpl list */
+ vc_vacheap(vacrelstats, onerel, &Vvpl);
+ }
+
+ /* ok - free Vvpl list of reapped pages */
+ if (Vvpl.vpl_npages > 0)
+ {
+ vpp = Vvpl.vpl_pgdesc;
+ for (i = 0; i < Vvpl.vpl_npages; i++, vpp++)
+ pfree(*vpp);
+ pfree(Vvpl.vpl_pgdesc);
+ if (Fvpl.vpl_npages > 0)
+ pfree(Fvpl.vpl_pgdesc);
+ }
+
+ /* all done with this class */
+ heap_close(onerel);
heap_endscan(pgcscan);
heap_close(pgclass);
- CommitTransactionCommand();
- return;
- }
-
- /* now open the class and vacuum it */
- onerel = heap_open(relid);
-
- vacrelstats = (VRelStats *) palloc(sizeof(VRelStats));
- vacrelstats->relid = relid;
- vacrelstats->npages = vacrelstats->ntups = 0;
- vacrelstats->hasindex = false;
- if ( analyze && !IsSystemRelationName ((RelationGetRelationName (onerel))->data) )
- {
- int attr_cnt, *attnums = NULL;
- AttributeTupleForm *attr;
-
- attr_cnt = onerel->rd_att->natts;
- attr = onerel->rd_att->attrs;
-
- if ( va_cols != NIL )
- {
- int tcnt = 0;
- List *le;
-
- if ( length (va_cols) > attr_cnt )
- elog (WARN, "vacuum: too many attributes specified for relation %s",
- (RelationGetRelationName(onerel))->data);
- attnums = (int*) palloc (attr_cnt * sizeof (int));
- foreach (le, va_cols)
- {
- char *col = (char*) lfirst(le);
-
- for (i = 0; i < attr_cnt; i++)
- {
- if ( namestrcmp (&(attr[i]->attname), col) == 0 )
- break;
- }
- if ( i < attr_cnt ) /* found */
- attnums[tcnt++] = i;
- else
- {
- elog (WARN, "vacuum: there is no attribute %s in %s",
- col, (RelationGetRelationName(onerel))->data);
- }
- }
- attr_cnt = tcnt;
- }
-
- vacrelstats->vacattrstats =
- (VacAttrStats *) palloc (attr_cnt * sizeof(VacAttrStats));
-
- for (i = 0; i < attr_cnt; i++)
- {
- Operator func_operator;
- OperatorTupleForm pgopform;
- VacAttrStats *stats;
-
- stats = &vacrelstats->vacattrstats[i];
- stats->attr = palloc(ATTRIBUTE_TUPLE_SIZE);
- memmove (stats->attr, attr[((attnums) ? attnums[i] : i)], ATTRIBUTE_TUPLE_SIZE);
- stats->best = stats->guess1 = stats->guess2 = 0;
- stats->max = stats->min = 0;
- stats->best_len = stats->guess1_len = stats->guess2_len = 0;
- stats->max_len = stats->min_len = 0;
- stats->initialized = false;
- stats->best_cnt = stats->guess1_cnt = stats->guess1_hits = stats->guess2_hits = 0;
- stats->max_cnt = stats->min_cnt = stats->null_cnt = stats->nonnull_cnt = 0;
-
- func_operator = oper("=",stats->attr->atttypid,stats->attr->atttypid,true);
- if (func_operator != NULL)
- {
- int nargs;
-
- pgopform = (OperatorTupleForm) GETSTRUCT(func_operator);
- fmgr_info (pgopform->oprcode, &(stats->f_cmpeq), &nargs);
- }
- else
- stats->f_cmpeq = NULL;
-
- func_operator = oper("<",stats->attr->atttypid,stats->attr->atttypid,true);
- if (func_operator != NULL)
- {
- int nargs;
-
- pgopform = (OperatorTupleForm) GETSTRUCT(func_operator);
- fmgr_info (pgopform->oprcode, &(stats->f_cmplt), &nargs);
- }
- else
- stats->f_cmplt = NULL;
-
- func_operator = oper(">",stats->attr->atttypid,stats->attr->atttypid,true);
- if (func_operator != NULL)
- {
- int nargs;
-
- pgopform = (OperatorTupleForm) GETSTRUCT(func_operator);
- fmgr_info (pgopform->oprcode, &(stats->f_cmpgt), &nargs);
- }
- else
- stats->f_cmpgt = NULL;
-
- pgttup = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(stats->attr->atttypid),
- 0,0,0);
- if (HeapTupleIsValid(pgttup))
- stats->outfunc = ((TypeTupleForm) GETSTRUCT(pgttup))->typoutput;
- else
- stats->outfunc = InvalidOid;
- }
- vacrelstats->va_natts = attr_cnt;
- vc_delhilowstats (relid, ((attnums) ? attr_cnt : 0), attnums);
- if ( attnums )
- pfree (attnums);
- }
- else
- {
- vacrelstats->va_natts = 0;
- vacrelstats->vacattrstats = (VacAttrStats *) NULL;
- }
-
- /* we require the relation to be locked until the indices are cleaned */
- RelationSetLockForWrite(onerel);
-
- /* scan it */
- Vvpl.vpl_npages = Fvpl.vpl_npages = 0;
- vc_scanheap(vacrelstats, onerel, &Vvpl, &Fvpl);
-
- /* Now open indices */
- Irel = (Relation *) NULL;
- vc_getindices(vacrelstats->relid, &nindices, &Irel);
-
- if ( nindices > 0 )
- vacrelstats->hasindex = true;
- else
- vacrelstats->hasindex = false;
- /* Clean/scan index relation(s) */
- if ( Irel != (Relation*) NULL )
- {
- if ( Vvpl.vpl_npages > 0 )
- {
- for (i = 0; i < nindices; i++)
- vc_vaconeind (&Vvpl, Irel[i], vacrelstats->ntups);
- }
- else /* just scan indices to update statistic */
- {
- for (i = 0; i < nindices; i++)
- vc_scanoneind (Irel[i], vacrelstats->ntups);
- }
- }
-
- if ( Fvpl.vpl_npages > 0 ) /* Try to shrink heap */
- vc_rpfheap (vacrelstats, onerel, &Vvpl, &Fvpl, nindices, Irel);
- else
- {
- if ( Irel != (Relation*) NULL )
- vc_clsindices (nindices, Irel);
- if ( Vvpl.vpl_npages > 0 ) /* Clean pages from Vvpl list */
- vc_vacheap (vacrelstats, onerel, &Vvpl);
- }
-
- /* ok - free Vvpl list of reapped pages */
- if ( Vvpl.vpl_npages > 0 )
- {
- vpp = Vvpl.vpl_pgdesc;
- for (i = 0; i < Vvpl.vpl_npages; i++, vpp++)
- pfree(*vpp);
- pfree (Vvpl.vpl_pgdesc);
- if ( Fvpl.vpl_npages > 0 )
- pfree (Fvpl.vpl_pgdesc);
- }
-
- /* all done with this class */
- heap_close(onerel);
- heap_endscan(pgcscan);
- heap_close(pgclass);
-
- /* update statistics in pg_class */
- vc_updstats(vacrelstats->relid, vacrelstats->npages, vacrelstats->ntups,
- vacrelstats->hasindex, vacrelstats);
-
- /* next command frees attribute stats */
-
- CommitTransactionCommand();
+ /* update statistics in pg_class */
+ vc_updstats(vacrelstats->relid, vacrelstats->npages, vacrelstats->ntups,
+ vacrelstats->hasindex, vacrelstats);
+
+ /* next command frees attribute stats */
+
+ CommitTransactionCommand();
}
/*
- * vc_scanheap() -- scan an open heap relation
+ * vc_scanheap() -- scan an open heap relation
*
- * This routine sets commit times, constructs Vvpl list of
- * empty/uninitialized pages and pages with dead tuples and
- * ~LP_USED line pointers, constructs Fvpl list of pages
- * appropriate for purposes of shrinking and maintains statistics
- * on the number of live tuples in a heap.
+ * This routine sets commit times, constructs Vvpl list of
+ * empty/uninitialized pages and pages with dead tuples and
+ * ~LP_USED line pointers, constructs Fvpl list of pages
+ * appropriate for purposes of shrinking and maintains statistics
+ * on the number of live tuples in a heap.
*/
static void
-vc_scanheap (VRelStats *vacrelstats, Relation onerel,
+vc_scanheap(VRelStats * vacrelstats, Relation onerel,
VPageList Vvpl, VPageList Fvpl)
{
- int nblocks, blkno;
- ItemId itemid;
- ItemPointer itemptr;
- HeapTuple htup;
- Buffer buf;
- Page page, tempPage = NULL;
- OffsetNumber offnum, maxoff;
- bool pgchanged, tupgone, dobufrel, notup;
- char *relname;
- VPageDescr vpc, vp;
- uint32 nvac, ntups, nunused, ncrash, nempg, nnepg, nchpg, nemend;
- Size frsize, frsusf;
- Size min_tlen = MAXTUPLEN;
- Size max_tlen = 0;
- int32 i/*, attr_cnt*/;
- struct rusage ru0, ru1;
- bool do_shrinking = true;
-
- getrusage(RUSAGE_SELF, &ru0);
-
- nvac = ntups = nunused = ncrash = nempg = nnepg = nchpg = nemend = 0;
- frsize = frsusf = 0;
-
- relname = (RelationGetRelationName(onerel))->data;
-
- nblocks = RelationGetNumberOfBlocks(onerel);
-
- vpc = (VPageDescr) palloc (sizeof(VPageDescrData) + MaxOffsetNumber*sizeof(OffsetNumber));
- vpc->vpd_nusd = 0;
-
- for (blkno = 0; blkno < nblocks; blkno++) {
- buf = ReadBuffer(onerel, blkno);
- page = BufferGetPage(buf);
- vpc->vpd_blkno = blkno;
- vpc->vpd_noff = 0;
-
- if (PageIsNew(page)) {
- elog (NOTICE, "Rel %s: Uninitialized page %u - fixing",
- relname, blkno);
- PageInit (page, BufferGetPageSize (buf), 0);
- vpc->vpd_free = ((PageHeader)page)->pd_upper - ((PageHeader)page)->pd_lower;
- frsize += (vpc->vpd_free - sizeof (ItemIdData));
- nnepg++;
- nemend++;
- vc_reappage (Vvpl, vpc);
- WriteBuffer(buf);
- continue;
- }
-
- if (PageIsEmpty(page)) {
- vpc->vpd_free = ((PageHeader)page)->pd_upper - ((PageHeader)page)->pd_lower;
- frsize += (vpc->vpd_free - sizeof (ItemIdData));
- nempg++;
- nemend++;
- vc_reappage (Vvpl, vpc);
- ReleaseBuffer(buf);
- continue;
- }
+ int nblocks,
+ blkno;
+ ItemId itemid;
+ ItemPointer itemptr;
+ HeapTuple htup;
+ Buffer buf;
+ Page page,
+ tempPage = NULL;
+ OffsetNumber offnum,
+ maxoff;
+ bool pgchanged,
+ tupgone,
+ dobufrel,
+ notup;
+ char *relname;
+ VPageDescr vpc,
+ vp;
+ uint32 nvac,
+ ntups,
+ nunused,
+ ncrash,
+ nempg,
+ nnepg,
+ nchpg,
+ nemend;
+ Size frsize,
+ frsusf;
+ Size min_tlen = MAXTUPLEN;
+ Size max_tlen = 0;
+ int32 i /* , attr_cnt */ ;
+ struct rusage ru0,
+ ru1;
+ bool do_shrinking = true;
+
+ getrusage(RUSAGE_SELF, &ru0);
+
+ nvac = ntups = nunused = ncrash = nempg = nnepg = nchpg = nemend = 0;
+ frsize = frsusf = 0;
+
+ relname = (RelationGetRelationName(onerel))->data;
+
+ nblocks = RelationGetNumberOfBlocks(onerel);
+
+ vpc = (VPageDescr) palloc(sizeof(VPageDescrData) + MaxOffsetNumber * sizeof(OffsetNumber));
+ vpc->vpd_nusd = 0;
+
+ for (blkno = 0; blkno < nblocks; blkno++)
+ {
+ buf = ReadBuffer(onerel, blkno);
+ page = BufferGetPage(buf);
+ vpc->vpd_blkno = blkno;
+ vpc->vpd_noff = 0;
- pgchanged = false;
- notup = true;
- maxoff = PageGetMaxOffsetNumber(page);
- for (offnum = FirstOffsetNumber;
- offnum <= maxoff;
- offnum = OffsetNumberNext(offnum)) {
- itemid = PageGetItemId(page, offnum);
-
- /*
- * Collect un-used items too - it's possible to have
- * indices pointing here after crash.
- */
- if (!ItemIdIsUsed(itemid)) {
- vpc->vpd_voff[vpc->vpd_noff++] = offnum;
- nunused++;
- continue;
- }
-
- htup = (HeapTuple) PageGetItem(page, itemid);
- tupgone = false;
-
- if (!AbsoluteTimeIsBackwardCompatiblyValid(htup->t_tmin) &&
- TransactionIdIsValid((TransactionId)htup->t_xmin)) {
-
- if (TransactionIdDidAbort(htup->t_xmin)) {
- tupgone = true;
- } else if (TransactionIdDidCommit(htup->t_xmin)) {
- htup->t_tmin = TransactionIdGetCommitTime(htup->t_xmin);
- pgchanged = true;
- } else if ( !TransactionIdIsInProgress (htup->t_xmin) ) {
- /*
- * Not Aborted, Not Committed, Not in Progress -
- * so it from crashed process. - vadim 11/26/96
- */
- ncrash++;
- tupgone = true;
+ if (PageIsNew(page))
+ {
+ elog(NOTICE, "Rel %s: Uninitialized page %u - fixing",
+ relname, blkno);
+ PageInit(page, BufferGetPageSize(buf), 0);
+ vpc->vpd_free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
+ frsize += (vpc->vpd_free - sizeof(ItemIdData));
+ nnepg++;
+ nemend++;
+ vc_reappage(Vvpl, vpc);
+ WriteBuffer(buf);
+ continue;
}
- else
+
+ if (PageIsEmpty(page))
{
- elog (NOTICE, "Rel %s: TID %u/%u: InsertTransactionInProgress %u - can't shrink relation",
- relname, blkno, offnum, htup->t_xmin);
- do_shrinking = false;
+ vpc->vpd_free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
+ frsize += (vpc->vpd_free - sizeof(ItemIdData));
+ nempg++;
+ nemend++;
+ vc_reappage(Vvpl, vpc);
+ ReleaseBuffer(buf);
+ continue;
}
- }
- if (TransactionIdIsValid((TransactionId)htup->t_xmax))
- {
- if (TransactionIdDidAbort(htup->t_xmax))
+ pgchanged = false;
+ notup = true;
+ maxoff = PageGetMaxOffsetNumber(page);
+ for (offnum = FirstOffsetNumber;
+ offnum <= maxoff;
+ offnum = OffsetNumberNext(offnum))
{
- StoreInvalidTransactionId(&(htup->t_xmax));
- pgchanged = true;
+ itemid = PageGetItemId(page, offnum);
+
+ /*
+ * Collect un-used items too - it's possible to have indices
+ * pointing here after crash.
+ */
+ if (!ItemIdIsUsed(itemid))
+ {
+ vpc->vpd_voff[vpc->vpd_noff++] = offnum;
+ nunused++;
+ continue;
+ }
+
+ htup = (HeapTuple) PageGetItem(page, itemid);
+ tupgone = false;
+
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(htup->t_tmin) &&
+ TransactionIdIsValid((TransactionId) htup->t_xmin))
+ {
+
+ if (TransactionIdDidAbort(htup->t_xmin))
+ {
+ tupgone = true;
+ }
+ else if (TransactionIdDidCommit(htup->t_xmin))
+ {
+ htup->t_tmin = TransactionIdGetCommitTime(htup->t_xmin);
+ pgchanged = true;
+ }
+ else if (!TransactionIdIsInProgress(htup->t_xmin))
+ {
+
+ /*
+ * Not Aborted, Not Committed, Not in Progress - so it
+ * from crashed process. - vadim 11/26/96
+ */
+ ncrash++;
+ tupgone = true;
+ }
+ else
+ {
+ elog(NOTICE, "Rel %s: TID %u/%u: InsertTransactionInProgress %u - can't shrink relation",
+ relname, blkno, offnum, htup->t_xmin);
+ do_shrinking = false;
+ }
+ }
+
+ if (TransactionIdIsValid((TransactionId) htup->t_xmax))
+ {
+ if (TransactionIdDidAbort(htup->t_xmax))
+ {
+ StoreInvalidTransactionId(&(htup->t_xmax));
+ pgchanged = true;
+ }
+ else if (TransactionIdDidCommit(htup->t_xmax))
+ tupgone = true;
+ else if (!TransactionIdIsInProgress(htup->t_xmax))
+ {
+
+ /*
+ * Not Aborted, Not Committed, Not in Progress - so it
+ * from crashed process. - vadim 06/02/97
+ */
+ StoreInvalidTransactionId(&(htup->t_xmax));
+ pgchanged = true;
+ }
+ else
+ {
+ elog(NOTICE, "Rel %s: TID %u/%u: DeleteTransactionInProgress %u - can't shrink relation",
+ relname, blkno, offnum, htup->t_xmax);
+ do_shrinking = false;
+ }
+ }
+
+ /*
+ * Is it possible at all ? - vadim 11/26/96
+ */
+ if (!TransactionIdIsValid((TransactionId) htup->t_xmin))
+ {
+ elog(NOTICE, "Rel %s: TID %u/%u: INSERT_TRANSACTION_ID IS INVALID. \
+DELETE_TRANSACTION_ID_VALID %d, TUPGONE %d.",
+ relname, blkno, offnum,
+ TransactionIdIsValid((TransactionId) htup->t_xmax),
+ tupgone);
+ }
+
+ /*
+ * It's possibly! But from where it comes ? And should we fix
+ * it ? - vadim 11/28/96
+ */
+ itemptr = &(htup->t_ctid);
+ if (!ItemPointerIsValid(itemptr) ||
+ BlockIdGetBlockNumber(&(itemptr->ip_blkid)) != blkno)
+ {
+ elog(NOTICE, "Rel %s: TID %u/%u: TID IN TUPLEHEADER %u/%u IS NOT THE SAME. TUPGONE %d.",
+ relname, blkno, offnum,
+ BlockIdGetBlockNumber(&(itemptr->ip_blkid)),
+ itemptr->ip_posid, tupgone);
+ }
+
+ /*
+ * Other checks...
+ */
+ if (htup->t_len != itemid->lp_len)
+ {
+ elog(NOTICE, "Rel %s: TID %u/%u: TUPLE_LEN IN PAGEHEADER %u IS NOT THE SAME AS IN TUPLEHEADER %u. TUPGONE %d.",
+ relname, blkno, offnum,
+ itemid->lp_len, htup->t_len, tupgone);
+ }
+ if (!OidIsValid(htup->t_oid))
+ {
+ elog(NOTICE, "Rel %s: TID %u/%u: OID IS INVALID. TUPGONE %d.",
+ relname, blkno, offnum, tupgone);
+ }
+
+ if (tupgone)
+ {
+ ItemId lpp;
+
+ if (tempPage == (Page) NULL)
+ {
+ Size pageSize;
+
+ pageSize = PageGetPageSize(page);
+ tempPage = (Page) palloc(pageSize);
+ memmove(tempPage, page, pageSize);
+ }
+
+ lpp = &(((PageHeader) tempPage)->pd_linp[offnum - 1]);
+
+ /* mark it unused */
+ lpp->lp_flags &= ~LP_USED;
+
+ vpc->vpd_voff[vpc->vpd_noff++] = offnum;
+ nvac++;
+
+ }
+ else
+ {
+ ntups++;
+ notup = false;
+ if (htup->t_len < min_tlen)
+ min_tlen = htup->t_len;
+ if (htup->t_len > max_tlen)
+ max_tlen = htup->t_len;
+ vc_attrstats(onerel, vacrelstats, htup);
+ }
}
- else if (TransactionIdDidCommit(htup->t_xmax))
- tupgone = true;
- else if ( !TransactionIdIsInProgress (htup->t_xmax) ) {
- /*
- * Not Aborted, Not Committed, Not in Progress -
- * so it from crashed process. - vadim 06/02/97
- */
- StoreInvalidTransactionId(&(htup->t_xmax));
- pgchanged = true;
+
+ if (pgchanged)
+ {
+ WriteBuffer(buf);
+ dobufrel = false;
+ nchpg++;
}
else
- {
- elog (NOTICE, "Rel %s: TID %u/%u: DeleteTransactionInProgress %u - can't shrink relation",
- relname, blkno, offnum, htup->t_xmax);
- do_shrinking = false;
+ dobufrel = true;
+ if (tempPage != (Page) NULL)
+ { /* Some tuples are gone */
+ PageRepairFragmentation(tempPage);
+ vpc->vpd_free = ((PageHeader) tempPage)->pd_upper - ((PageHeader) tempPage)->pd_lower;
+ frsize += vpc->vpd_free;
+ vc_reappage(Vvpl, vpc);
+ pfree(tempPage);
+ tempPage = (Page) NULL;
}
- }
-
- /*
- * Is it possible at all ? - vadim 11/26/96
- */
- if ( !TransactionIdIsValid((TransactionId)htup->t_xmin) )
- {
- elog (NOTICE, "Rel %s: TID %u/%u: INSERT_TRANSACTION_ID IS INVALID. \
-DELETE_TRANSACTION_ID_VALID %d, TUPGONE %d.",
- relname, blkno, offnum,
- TransactionIdIsValid((TransactionId)htup->t_xmax),
- tupgone);
- }
-
- /*
- * It's possibly! But from where it comes ?
- * And should we fix it ? - vadim 11/28/96
- */
- itemptr = &(htup->t_ctid);
- if ( !ItemPointerIsValid (itemptr) ||
- BlockIdGetBlockNumber(&(itemptr->ip_blkid)) != blkno )
- {
- elog (NOTICE, "Rel %s: TID %u/%u: TID IN TUPLEHEADER %u/%u IS NOT THE SAME. TUPGONE %d.",
- relname, blkno, offnum,
- BlockIdGetBlockNumber(&(itemptr->ip_blkid)),
- itemptr->ip_posid, tupgone);
- }
-
- /*
- * Other checks...
- */
- if ( htup->t_len != itemid->lp_len )
- {
- elog (NOTICE, "Rel %s: TID %u/%u: TUPLE_LEN IN PAGEHEADER %u IS NOT THE SAME AS IN TUPLEHEADER %u. TUPGONE %d.",
- relname, blkno, offnum,
- itemid->lp_len, htup->t_len, tupgone);
- }
- if ( !OidIsValid(htup->t_oid) )
- {
- elog (NOTICE, "Rel %s: TID %u/%u: OID IS INVALID. TUPGONE %d.",
- relname, blkno, offnum, tupgone);
- }
-
- if (tupgone) {
- ItemId lpp;
-
- if ( tempPage == (Page) NULL )
- {
- Size pageSize;
-
- pageSize = PageGetPageSize(page);
- tempPage = (Page) palloc(pageSize);
- memmove (tempPage, page, pageSize);
+ else if (vpc->vpd_noff > 0)
+ { /* there are only ~LP_USED line pointers */
+ vpc->vpd_free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
+ frsize += vpc->vpd_free;
+ vc_reappage(Vvpl, vpc);
}
-
- lpp = &(((PageHeader) tempPage)->pd_linp[offnum - 1]);
-
- /* mark it unused */
- lpp->lp_flags &= ~LP_USED;
-
- vpc->vpd_voff[vpc->vpd_noff++] = offnum;
- nvac++;
-
- } else {
- ntups++;
- notup = false;
- if ( htup->t_len < min_tlen )
- min_tlen = htup->t_len;
- if ( htup->t_len > max_tlen )
- max_tlen = htup->t_len;
- vc_attrstats(onerel, vacrelstats, htup);
- }
+ if (dobufrel)
+ ReleaseBuffer(buf);
+ if (notup)
+ nemend++;
+ else
+ nemend = 0;
}
- if (pgchanged) {
- WriteBuffer(buf);
- dobufrel = false;
- nchpg++;
- }
- else
- dobufrel = true;
- if ( tempPage != (Page) NULL )
- { /* Some tuples are gone */
- PageRepairFragmentation(tempPage);
- vpc->vpd_free = ((PageHeader)tempPage)->pd_upper - ((PageHeader)tempPage)->pd_lower;
- frsize += vpc->vpd_free;
- vc_reappage (Vvpl, vpc);
- pfree (tempPage);
- tempPage = (Page) NULL;
- }
- else if ( vpc->vpd_noff > 0 )
- { /* there are only ~LP_USED line pointers */
- vpc->vpd_free = ((PageHeader)page)->pd_upper - ((PageHeader)page)->pd_lower;
- frsize += vpc->vpd_free;
- vc_reappage (Vvpl, vpc);
- }
- if ( dobufrel )
- ReleaseBuffer(buf);
- if ( notup )
- nemend++;
- else
- nemend = 0;
- }
-
- pfree (vpc);
-
- /* save stats in the rel list for use later */
- vacrelstats->ntups = ntups;
- vacrelstats->npages = nblocks;
-/* vacrelstats->natts = attr_cnt;*/
- if ( ntups == 0 )
- min_tlen = max_tlen = 0;
- vacrelstats->min_tlen = min_tlen;
- vacrelstats->max_tlen = max_tlen;
-
- Vvpl->vpl_nemend = nemend;
- Fvpl->vpl_nemend = nemend;
-
- /*
- * Try to make Fvpl keeping in mind that we can't use free space
- * of "empty" end-pages and last page if it reapped.
- */
- if ( do_shrinking && Vvpl->vpl_npages - nemend > 0 )
- {
- int nusf; /* blocks usefull for re-using */
-
- nusf = Vvpl->vpl_npages - nemend;
- if ( (Vvpl->vpl_pgdesc[nusf-1])->vpd_blkno == nblocks - nemend - 1 )
- nusf--;
-
- for (i = 0; i < nusf; i++)
- {
- vp = Vvpl->vpl_pgdesc[i];
- if ( vc_enough_space (vp, min_tlen) )
- {
- vc_vpinsert (Fvpl, vp);
- frsusf += vp->vpd_free;
- }
+ pfree(vpc);
+
+ /* save stats in the rel list for use later */
+ vacrelstats->ntups = ntups;
+ vacrelstats->npages = nblocks;
+/* vacrelstats->natts = attr_cnt;*/
+ if (ntups == 0)
+ min_tlen = max_tlen = 0;
+ vacrelstats->min_tlen = min_tlen;
+ vacrelstats->max_tlen = max_tlen;
+
+ Vvpl->vpl_nemend = nemend;
+ Fvpl->vpl_nemend = nemend;
+
+ /*
+ * Try to make Fvpl keeping in mind that we can't use free space of
+ * "empty" end-pages and last page if it reapped.
+ */
+ if (do_shrinking && Vvpl->vpl_npages - nemend > 0)
+ {
+ int nusf; /* blocks usefull for re-using */
+
+ nusf = Vvpl->vpl_npages - nemend;
+ if ((Vvpl->vpl_pgdesc[nusf - 1])->vpd_blkno == nblocks - nemend - 1)
+ nusf--;
+
+ for (i = 0; i < nusf; i++)
+ {
+ vp = Vvpl->vpl_pgdesc[i];
+ if (vc_enough_space(vp, min_tlen))
+ {
+ vc_vpinsert(Fvpl, vp);
+ frsusf += vp->vpd_free;
+ }
+ }
}
- }
- getrusage(RUSAGE_SELF, &ru1);
-
- elog (MESSAGE_LEVEL, "Rel %s: Pages %u: Changed %u, Reapped %u, Empty %u, New %u; \
+ getrusage(RUSAGE_SELF, &ru1);
+
+ elog(MESSAGE_LEVEL, "Rel %s: Pages %u: Changed %u, Reapped %u, Empty %u, New %u; \
Tup %u: Vac %u, Crash %u, UnUsed %u, MinLen %u, MaxLen %u; Re-using: Free/Avail. Space %u/%u; EndEmpty/Avail. Pages %u/%u. Elapsed %u/%u sec.",
- relname,
- nblocks, nchpg, Vvpl->vpl_npages, nempg, nnepg,
- ntups, nvac, ncrash, nunused, min_tlen, max_tlen,
- frsize, frsusf, nemend, Fvpl->vpl_npages,
- ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
- ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
+ relname,
+ nblocks, nchpg, Vvpl->vpl_npages, nempg, nnepg,
+ ntups, nvac, ncrash, nunused, min_tlen, max_tlen,
+ frsize, frsusf, nemend, Fvpl->vpl_npages,
+ ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
+ ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
-} /* vc_scanheap */
+} /* vc_scanheap */
/*
- * vc_rpfheap() -- try to repaire relation' fragmentation
+ * vc_rpfheap() -- try to repaire relation' fragmentation
*
- * This routine marks dead tuples as unused and tries re-use dead space
- * by moving tuples (and inserting indices if needed). It constructs
- * Nvpl list of free-ed pages (moved tuples) and clean indices
- * for them after committing (in hack-manner - without losing locks
- * and freeing memory!) current transaction. It truncates relation
- * if some end-blocks are gone away.
+ * This routine marks dead tuples as unused and tries re-use dead space
+ * by moving tuples (and inserting indices if needed). It constructs
+ * Nvpl list of free-ed pages (moved tuples) and clean indices
+ * for them after committing (in hack-manner - without losing locks
+ * and freeing memory!) current transaction. It truncates relation
+ * if some end-blocks are gone away.
*/
static void
-vc_rpfheap (VRelStats *vacrelstats, Relation onerel,
- VPageList Vvpl, VPageList Fvpl, int nindices, Relation *Irel)
+vc_rpfheap(VRelStats * vacrelstats, Relation onerel,
+ VPageList Vvpl, VPageList Fvpl, int nindices, Relation * Irel)
{
- TransactionId myXID;
- CommandId myCID;
- AbsoluteTime myCTM = 0;
- Buffer buf, ToBuf;
- int nblocks, blkno;
- Page page, ToPage = NULL;
- OffsetNumber offnum = 0, maxoff = 0, newoff, moff;
- ItemId itemid, newitemid;
- HeapTuple htup, newtup;
- TupleDesc tupdesc = NULL;
- Datum *idatum = NULL;
- char *inulls = NULL;
- InsertIndexResult iresult;
- VPageListData Nvpl;
- VPageDescr ToVpd = NULL, Fvplast, Vvplast, vpc, *vpp;
- int ToVpI = 0;
- IndDesc *Idesc, *idcur;
- int Fblklast, Vblklast, i;
- Size tlen;
- int nmoved, Fnpages, Vnpages;
- int nchkmvd, ntups;
- bool isempty, dowrite;
- Relation archrel;
- struct rusage ru0, ru1;
-
- getrusage(RUSAGE_SELF, &ru0);
-
- myXID = GetCurrentTransactionId();
- myCID = GetCurrentCommandId();
-
- if ( Irel != (Relation*) NULL ) /* preparation for index' inserts */
- {
- vc_mkindesc (onerel, nindices, Irel, &Idesc);
- tupdesc = RelationGetTupleDescriptor(onerel);
- idatum = (Datum *) palloc(INDEX_MAX_KEYS * sizeof (*idatum));
- inulls = (char *) palloc(INDEX_MAX_KEYS * sizeof (*inulls));
- }
-
- /* if the relation has an archive, open it */
- if (onerel->rd_rel->relarch != 'n')
- {
- archrel = vc_getarchrel(onerel);
- /* Archive tuples from "empty" end-pages */
- for ( vpp = Vvpl->vpl_pgdesc + Vvpl->vpl_npages - 1,
- i = Vvpl->vpl_nemend; i > 0; i--, vpp-- )
+ TransactionId myXID;
+ CommandId myCID;
+ AbsoluteTime myCTM = 0;
+ Buffer buf,
+ ToBuf;
+ int nblocks,
+ blkno;
+ Page page,
+ ToPage = NULL;
+ OffsetNumber offnum = 0,
+ maxoff = 0,
+ newoff,
+ moff;
+ ItemId itemid,
+ newitemid;
+ HeapTuple htup,
+ newtup;
+ TupleDesc tupdesc = NULL;
+ Datum *idatum = NULL;
+ char *inulls = NULL;
+ InsertIndexResult iresult;
+ VPageListData Nvpl;
+ VPageDescr ToVpd = NULL,
+ Fvplast,
+ Vvplast,
+ vpc,
+ *vpp;
+ int ToVpI = 0;
+ IndDesc *Idesc,
+ *idcur;
+ int Fblklast,
+ Vblklast,
+ i;
+ Size tlen;
+ int nmoved,
+ Fnpages,
+ Vnpages;
+ int nchkmvd,
+ ntups;
+ bool isempty,
+ dowrite;
+ Relation archrel;
+ struct rusage ru0,
+ ru1;
+
+ getrusage(RUSAGE_SELF, &ru0);
+
+ myXID = GetCurrentTransactionId();
+ myCID = GetCurrentCommandId();
+
+ if (Irel != (Relation *) NULL) /* preparation for index' inserts */
{
- if ( (*vpp)->vpd_noff > 0 )
- {
- buf = ReadBuffer(onerel, (*vpp)->vpd_blkno);
- page = BufferGetPage(buf);
- Assert ( !PageIsEmpty(page) );
- vc_vacpage (page, *vpp, archrel);
- WriteBuffer (buf);
- }
+ vc_mkindesc(onerel, nindices, Irel, &Idesc);
+ tupdesc = RelationGetTupleDescriptor(onerel);
+ idatum = (Datum *) palloc(INDEX_MAX_KEYS * sizeof(*idatum));
+ inulls = (char *) palloc(INDEX_MAX_KEYS * sizeof(*inulls));
}
- }
- else
- archrel = (Relation) NULL;
-
- Nvpl.vpl_npages = 0;
- Fnpages = Fvpl->vpl_npages;
- Fvplast = Fvpl->vpl_pgdesc[Fnpages - 1];
- Fblklast = Fvplast->vpd_blkno;
- Assert ( Vvpl->vpl_npages > Vvpl->vpl_nemend );
- Vnpages = Vvpl->vpl_npages - Vvpl->vpl_nemend;
- Vvplast = Vvpl->vpl_pgdesc[Vnpages - 1];
- Vblklast = Vvplast->vpd_blkno;
- Assert ( Vblklast >= Fblklast );
- ToBuf = InvalidBuffer;
- nmoved = 0;
-
- vpc = (VPageDescr) palloc (sizeof(VPageDescrData) + MaxOffsetNumber*sizeof(OffsetNumber));
- vpc->vpd_nusd = vpc->vpd_noff = 0;
-
- nblocks = vacrelstats->npages;
- for (blkno = nblocks - Vvpl->vpl_nemend - 1; ; blkno--)
- {
- /* if it's reapped page and it was used by me - quit */
- if ( blkno == Fblklast && Fvplast->vpd_nusd > 0 )
- break;
-
- buf = ReadBuffer(onerel, blkno);
- page = BufferGetPage(buf);
-
- vpc->vpd_noff = 0;
-
- isempty = PageIsEmpty(page);
-
- dowrite = false;
- if ( blkno == Vblklast ) /* it's reapped page */
+
+ /* if the relation has an archive, open it */
+ if (onerel->rd_rel->relarch != 'n')
{
- if ( Vvplast->vpd_noff > 0 ) /* there are dead tuples */
- { /* on this page - clean */
- Assert ( ! isempty );
- vc_vacpage (page, Vvplast, archrel);
- dowrite = true;
- }
- else
- {
- Assert ( isempty );
- }
- --Vnpages;
- Assert ( Vnpages > 0 );
- /* get prev reapped page from Vvpl */
- Vvplast = Vvpl->vpl_pgdesc[Vnpages - 1];
- Vblklast = Vvplast->vpd_blkno;
- if ( blkno == Fblklast ) /* this page in Fvpl too */
- {
- --Fnpages;
- Assert ( Fnpages > 0 );
- Assert ( Fvplast->vpd_nusd == 0 );
- /* get prev reapped page from Fvpl */
- Fvplast = Fvpl->vpl_pgdesc[Fnpages - 1];
- Fblklast = Fvplast->vpd_blkno;
- }
- Assert ( Fblklast <= Vblklast );
- if ( isempty )
- {
- ReleaseBuffer(buf);
- continue;
- }
+ archrel = vc_getarchrel(onerel);
+ /* Archive tuples from "empty" end-pages */
+ for (vpp = Vvpl->vpl_pgdesc + Vvpl->vpl_npages - 1,
+ i = Vvpl->vpl_nemend; i > 0; i--, vpp--)
+ {
+ if ((*vpp)->vpd_noff > 0)
+ {
+ buf = ReadBuffer(onerel, (*vpp)->vpd_blkno);
+ page = BufferGetPage(buf);
+ Assert(!PageIsEmpty(page));
+ vc_vacpage(page, *vpp, archrel);
+ WriteBuffer(buf);
+ }
+ }
}
else
+ archrel = (Relation) NULL;
+
+ Nvpl.vpl_npages = 0;
+ Fnpages = Fvpl->vpl_npages;
+ Fvplast = Fvpl->vpl_pgdesc[Fnpages - 1];
+ Fblklast = Fvplast->vpd_blkno;
+ Assert(Vvpl->vpl_npages > Vvpl->vpl_nemend);
+ Vnpages = Vvpl->vpl_npages - Vvpl->vpl_nemend;
+ Vvplast = Vvpl->vpl_pgdesc[Vnpages - 1];
+ Vblklast = Vvplast->vpd_blkno;
+ Assert(Vblklast >= Fblklast);
+ ToBuf = InvalidBuffer;
+ nmoved = 0;
+
+ vpc = (VPageDescr) palloc(sizeof(VPageDescrData) + MaxOffsetNumber * sizeof(OffsetNumber));
+ vpc->vpd_nusd = vpc->vpd_noff = 0;
+
+ nblocks = vacrelstats->npages;
+ for (blkno = nblocks - Vvpl->vpl_nemend - 1;; blkno--)
{
- Assert ( ! isempty );
- }
+ /* if it's reapped page and it was used by me - quit */
+ if (blkno == Fblklast && Fvplast->vpd_nusd > 0)
+ break;
- vpc->vpd_blkno = blkno;
- maxoff = PageGetMaxOffsetNumber(page);
- for (offnum = FirstOffsetNumber;
- offnum <= maxoff;
- offnum = OffsetNumberNext(offnum))
- {
- itemid = PageGetItemId(page, offnum);
-
- if (!ItemIdIsUsed(itemid))
- continue;
-
- htup = (HeapTuple) PageGetItem(page, itemid);
- tlen = htup->t_len;
-
- /* try to find new page for this tuple */
- if ( ToBuf == InvalidBuffer ||
- ! vc_enough_space (ToVpd, tlen) )
- {
- if ( ToBuf != InvalidBuffer )
+ buf = ReadBuffer(onerel, blkno);
+ page = BufferGetPage(buf);
+
+ vpc->vpd_noff = 0;
+
+ isempty = PageIsEmpty(page);
+
+ dowrite = false;
+ if (blkno == Vblklast) /* it's reapped page */
{
- WriteBuffer(ToBuf);
- ToBuf = InvalidBuffer;
- /*
- * If no one tuple can't be added to this page -
- * remove page from Fvpl. - vadim 11/27/96
- */
- if ( !vc_enough_space (ToVpd, vacrelstats->min_tlen) )
- {
- if ( ToVpd != Fvplast )
- {
- Assert ( Fnpages > ToVpI + 1 );
- memmove (Fvpl->vpl_pgdesc + ToVpI,
- Fvpl->vpl_pgdesc + ToVpI + 1,
- sizeof (VPageDescr*) * (Fnpages - ToVpI - 1));
- }
- Assert ( Fnpages >= 1 );
- Fnpages--;
- if ( Fnpages == 0 )
- break;
- /* get prev reapped page from Fvpl */
- Fvplast = Fvpl->vpl_pgdesc[Fnpages - 1];
- Fblklast = Fvplast->vpd_blkno;
- }
- }
- for (i=0; i < Fnpages; i++)
+ if (Vvplast->vpd_noff > 0) /* there are dead tuples */
+ { /* on this page - clean */
+ Assert(!isempty);
+ vc_vacpage(page, Vvplast, archrel);
+ dowrite = true;
+ }
+ else
+ {
+ Assert(isempty);
+ }
+ --Vnpages;
+ Assert(Vnpages > 0);
+ /* get prev reapped page from Vvpl */
+ Vvplast = Vvpl->vpl_pgdesc[Vnpages - 1];
+ Vblklast = Vvplast->vpd_blkno;
+ if (blkno == Fblklast) /* this page in Fvpl too */
+ {
+ --Fnpages;
+ Assert(Fnpages > 0);
+ Assert(Fvplast->vpd_nusd == 0);
+ /* get prev reapped page from Fvpl */
+ Fvplast = Fvpl->vpl_pgdesc[Fnpages - 1];
+ Fblklast = Fvplast->vpd_blkno;
+ }
+ Assert(Fblklast <= Vblklast);
+ if (isempty)
+ {
+ ReleaseBuffer(buf);
+ continue;
+ }
+ }
+ else
{
- if ( vc_enough_space (Fvpl->vpl_pgdesc[i], tlen) )
- break;
+ Assert(!isempty);
}
- if ( i == Fnpages )
- break; /* can't move item anywhere */
- ToVpI = i;
- ToVpd = Fvpl->vpl_pgdesc[ToVpI];
- ToBuf = ReadBuffer(onerel, ToVpd->vpd_blkno);
- ToPage = BufferGetPage(ToBuf);
- /* if this page was not used before - clean it */
- if ( ! PageIsEmpty(ToPage) && ToVpd->vpd_nusd == 0 )
- vc_vacpage (ToPage, ToVpd, archrel);
- }
-
- /* copy tuple */
- newtup = (HeapTuple) palloc (tlen);
- memmove((char *) newtup, (char *) htup, tlen);
-
- /* store transaction information */
- TransactionIdStore(myXID, &(newtup->t_xmin));
- newtup->t_cmin = myCID;
- StoreInvalidTransactionId(&(newtup->t_xmax));
- newtup->t_tmin = INVALID_ABSTIME;
- newtup->t_tmax = CURRENT_ABSTIME;
- ItemPointerSetInvalid(&newtup->t_chain);
-
- /* add tuple to the page */
- newoff = PageAddItem (ToPage, (Item)newtup, tlen,
- InvalidOffsetNumber, LP_USED);
- if ( newoff == InvalidOffsetNumber )
- {
- elog (WARN, "\
+
+ vpc->vpd_blkno = blkno;
+ maxoff = PageGetMaxOffsetNumber(page);
+ for (offnum = FirstOffsetNumber;
+ offnum <= maxoff;
+ offnum = OffsetNumberNext(offnum))
+ {
+ itemid = PageGetItemId(page, offnum);
+
+ if (!ItemIdIsUsed(itemid))
+ continue;
+
+ htup = (HeapTuple) PageGetItem(page, itemid);
+ tlen = htup->t_len;
+
+ /* try to find new page for this tuple */
+ if (ToBuf == InvalidBuffer ||
+ !vc_enough_space(ToVpd, tlen))
+ {
+ if (ToBuf != InvalidBuffer)
+ {
+ WriteBuffer(ToBuf);
+ ToBuf = InvalidBuffer;
+
+ /*
+ * If no one tuple can't be added to this page -
+ * remove page from Fvpl. - vadim 11/27/96
+ */
+ if (!vc_enough_space(ToVpd, vacrelstats->min_tlen))
+ {
+ if (ToVpd != Fvplast)
+ {
+ Assert(Fnpages > ToVpI + 1);
+ memmove(Fvpl->vpl_pgdesc + ToVpI,
+ Fvpl->vpl_pgdesc + ToVpI + 1,
+ sizeof(VPageDescr *) * (Fnpages - ToVpI - 1));
+ }
+ Assert(Fnpages >= 1);
+ Fnpages--;
+ if (Fnpages == 0)
+ break;
+ /* get prev reapped page from Fvpl */
+ Fvplast = Fvpl->vpl_pgdesc[Fnpages - 1];
+ Fblklast = Fvplast->vpd_blkno;
+ }
+ }
+ for (i = 0; i < Fnpages; i++)
+ {
+ if (vc_enough_space(Fvpl->vpl_pgdesc[i], tlen))
+ break;
+ }
+ if (i == Fnpages)
+ break; /* can't move item anywhere */
+ ToVpI = i;
+ ToVpd = Fvpl->vpl_pgdesc[ToVpI];
+ ToBuf = ReadBuffer(onerel, ToVpd->vpd_blkno);
+ ToPage = BufferGetPage(ToBuf);
+ /* if this page was not used before - clean it */
+ if (!PageIsEmpty(ToPage) && ToVpd->vpd_nusd == 0)
+ vc_vacpage(ToPage, ToVpd, archrel);
+ }
+
+ /* copy tuple */
+ newtup = (HeapTuple) palloc(tlen);
+ memmove((char *) newtup, (char *) htup, tlen);
+
+ /* store transaction information */
+ TransactionIdStore(myXID, &(newtup->t_xmin));
+ newtup->t_cmin = myCID;
+ StoreInvalidTransactionId(&(newtup->t_xmax));
+ newtup->t_tmin = INVALID_ABSTIME;
+ newtup->t_tmax = CURRENT_ABSTIME;
+ ItemPointerSetInvalid(&newtup->t_chain);
+
+ /* add tuple to the page */
+ newoff = PageAddItem(ToPage, (Item) newtup, tlen,
+ InvalidOffsetNumber, LP_USED);
+ if (newoff == InvalidOffsetNumber)
+ {
+ elog(WARN, "\
failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
- tlen, ToVpd->vpd_blkno, ToVpd->vpd_free,
- ToVpd->vpd_nusd, ToVpd->vpd_noff);
- }
- newitemid = PageGetItemId(ToPage, newoff);
- pfree (newtup);
- newtup = (HeapTuple) PageGetItem(ToPage, newitemid);
- ItemPointerSet(&(newtup->t_ctid), ToVpd->vpd_blkno, newoff);
-
- /* now logically delete end-tuple */
- TransactionIdStore(myXID, &(htup->t_xmax));
- htup->t_cmax = myCID;
- memmove ((char*)&(htup->t_chain), (char*)&(newtup->t_ctid), sizeof (newtup->t_ctid));
-
- ToVpd->vpd_nusd++;
- nmoved++;
- ToVpd->vpd_free = ((PageHeader)ToPage)->pd_upper - ((PageHeader)ToPage)->pd_lower;
- vpc->vpd_voff[vpc->vpd_noff++] = offnum;
-
- /* insert index' tuples if needed */
- if ( Irel != (Relation*) NULL )
- {
- for (i = 0, idcur = Idesc; i < nindices; i++, idcur++)
+ tlen, ToVpd->vpd_blkno, ToVpd->vpd_free,
+ ToVpd->vpd_nusd, ToVpd->vpd_noff);
+ }
+ newitemid = PageGetItemId(ToPage, newoff);
+ pfree(newtup);
+ newtup = (HeapTuple) PageGetItem(ToPage, newitemid);
+ ItemPointerSet(&(newtup->t_ctid), ToVpd->vpd_blkno, newoff);
+
+ /* now logically delete end-tuple */
+ TransactionIdStore(myXID, &(htup->t_xmax));
+ htup->t_cmax = myCID;
+ memmove((char *) &(htup->t_chain), (char *) &(newtup->t_ctid), sizeof(newtup->t_ctid));
+
+ ToVpd->vpd_nusd++;
+ nmoved++;
+ ToVpd->vpd_free = ((PageHeader) ToPage)->pd_upper - ((PageHeader) ToPage)->pd_lower;
+ vpc->vpd_voff[vpc->vpd_noff++] = offnum;
+
+ /* insert index' tuples if needed */
+ if (Irel != (Relation *) NULL)
+ {
+ for (i = 0, idcur = Idesc; i < nindices; i++, idcur++)
+ {
+ FormIndexDatum(
+ idcur->natts,
+ (AttrNumber *) & (idcur->tform->indkey[0]),
+ newtup,
+ tupdesc,
+ InvalidBuffer,
+ idatum,
+ inulls,
+ idcur->finfoP);
+ iresult = index_insert(
+ Irel[i],
+ idatum,
+ inulls,
+ &(newtup->t_ctid),
+ onerel);
+ if (iresult)
+ pfree(iresult);
+ }
+ }
+
+ } /* walk along page */
+
+ if (vpc->vpd_noff > 0) /* some tuples were moved */
{
- FormIndexDatum (
- idcur->natts,
- (AttrNumber *)&(idcur->tform->indkey[0]),
- newtup,
- tupdesc,
- InvalidBuffer,
- idatum,
- inulls,
- idcur->finfoP);
- iresult = index_insert (
- Irel[i],
- idatum,
- inulls,
- &(newtup->t_ctid),
- onerel);
- if (iresult) pfree(iresult);
+ vc_reappage(&Nvpl, vpc);
+ WriteBuffer(buf);
}
- }
-
- } /* walk along page */
+ else if (dowrite)
+ WriteBuffer(buf);
+ else
+ ReleaseBuffer(buf);
- if ( vpc->vpd_noff > 0 ) /* some tuples were moved */
+ if (offnum <= maxoff)
+ break; /* some item(s) left */
+
+ } /* walk along relation */
+
+ blkno++; /* new number of blocks */
+
+ if (ToBuf != InvalidBuffer)
{
- vc_reappage (&Nvpl, vpc);
- WriteBuffer(buf);
+ Assert(nmoved > 0);
+ WriteBuffer(ToBuf);
}
- else if ( dowrite )
- WriteBuffer(buf);
- else
- ReleaseBuffer(buf);
-
- if ( offnum <= maxoff )
- break; /* some item(s) left */
-
- } /* walk along relation */
-
- blkno++; /* new number of blocks */
-
- if ( ToBuf != InvalidBuffer )
- {
- Assert (nmoved > 0);
- WriteBuffer(ToBuf);
- }
-
- if ( nmoved > 0 )
- {
- /*
- * We have to commit our tuple' movings before we'll truncate
- * relation, but we shouldn't lose our locks. And so - quick hack:
- * flush buffers and record status of current transaction
- * as committed, and continue. - vadim 11/13/96
- */
- FlushBufferPool(!TransactionFlushEnabled());
- TransactionIdCommit(myXID);
- FlushBufferPool(!TransactionFlushEnabled());
- myCTM = TransactionIdGetCommitTime(myXID);
- }
-
- /*
- * Clean uncleaned reapped pages from Vvpl list
- * and set commit' times for inserted tuples
- */
- nchkmvd = 0;
- for (i = 0, vpp = Vvpl->vpl_pgdesc; i < Vnpages; i++, vpp++)
- {
- Assert ( (*vpp)->vpd_blkno < blkno );
- buf = ReadBuffer(onerel, (*vpp)->vpd_blkno);
- page = BufferGetPage(buf);
- if ( (*vpp)->vpd_nusd == 0 ) /* this page was not used */
+
+ if (nmoved > 0)
{
- /* noff == 0 in empty pages only - such pages should be re-used */
- Assert ( (*vpp)->vpd_noff > 0 );
- vc_vacpage (page, *vpp, archrel);
+
+ /*
+ * We have to commit our tuple' movings before we'll truncate
+ * relation, but we shouldn't lose our locks. And so - quick hack:
+ * flush buffers and record status of current transaction as
+ * committed, and continue. - vadim 11/13/96
+ */
+ FlushBufferPool(!TransactionFlushEnabled());
+ TransactionIdCommit(myXID);
+ FlushBufferPool(!TransactionFlushEnabled());
+ myCTM = TransactionIdGetCommitTime(myXID);
}
- else /* this page was used */
+
+ /*
+ * Clean uncleaned reapped pages from Vvpl list and set commit' times
+ * for inserted tuples
+ */
+ nchkmvd = 0;
+ for (i = 0, vpp = Vvpl->vpl_pgdesc; i < Vnpages; i++, vpp++)
{
- ntups = 0;
- moff = PageGetMaxOffsetNumber(page);
- for (newoff = FirstOffsetNumber;
- newoff <= moff;
- newoff = OffsetNumberNext(newoff))
- {
- itemid = PageGetItemId(page, newoff);
- if (!ItemIdIsUsed(itemid))
- continue;
- htup = (HeapTuple) PageGetItem(page, itemid);
- if ( TransactionIdEquals((TransactionId)htup->t_xmin, myXID) )
- {
- htup->t_tmin = myCTM;
- ntups++;
- }
- }
- Assert ( (*vpp)->vpd_nusd == ntups );
- nchkmvd += ntups;
+ Assert((*vpp)->vpd_blkno < blkno);
+ buf = ReadBuffer(onerel, (*vpp)->vpd_blkno);
+ page = BufferGetPage(buf);
+ if ((*vpp)->vpd_nusd == 0) /* this page was not used */
+ {
+
+ /*
+ * noff == 0 in empty pages only - such pages should be
+ * re-used
+ */
+ Assert((*vpp)->vpd_noff > 0);
+ vc_vacpage(page, *vpp, archrel);
+ }
+ else
+/* this page was used */
+ {
+ ntups = 0;
+ moff = PageGetMaxOffsetNumber(page);
+ for (newoff = FirstOffsetNumber;
+ newoff <= moff;
+ newoff = OffsetNumberNext(newoff))
+ {
+ itemid = PageGetItemId(page, newoff);
+ if (!ItemIdIsUsed(itemid))
+ continue;
+ htup = (HeapTuple) PageGetItem(page, itemid);
+ if (TransactionIdEquals((TransactionId) htup->t_xmin, myXID))
+ {
+ htup->t_tmin = myCTM;
+ ntups++;
+ }
+ }
+ Assert((*vpp)->vpd_nusd == ntups);
+ nchkmvd += ntups;
+ }
+ WriteBuffer(buf);
}
- WriteBuffer (buf);
- }
- Assert ( nmoved == nchkmvd );
+ Assert(nmoved == nchkmvd);
+
+ getrusage(RUSAGE_SELF, &ru1);
- getrusage(RUSAGE_SELF, &ru1);
-
- elog (MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u; Tuple(s) moved: %u. \
+ elog(MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u; Tuple(s) moved: %u. \
Elapsed %u/%u sec.",
- (RelationGetRelationName(onerel))->data,
- nblocks, blkno, nmoved,
- ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
- ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
-
- if ( Nvpl.vpl_npages > 0 )
- {
- /* vacuum indices again if needed */
- if ( Irel != (Relation*) NULL )
+ (RelationGetRelationName(onerel))->data,
+ nblocks, blkno, nmoved,
+ ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
+ ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
+
+ if (Nvpl.vpl_npages > 0)
{
- VPageDescr *vpleft, *vpright, vpsave;
-
- /* re-sort Nvpl.vpl_pgdesc */
- for (vpleft = Nvpl.vpl_pgdesc,
- vpright = Nvpl.vpl_pgdesc + Nvpl.vpl_npages - 1;
- vpleft < vpright; vpleft++, vpright--)
- {
- vpsave = *vpleft; *vpleft = *vpright; *vpright = vpsave;
- }
- for (i = 0; i < nindices; i++)
- vc_vaconeind (&Nvpl, Irel[i], vacrelstats->ntups);
+ /* vacuum indices again if needed */
+ if (Irel != (Relation *) NULL)
+ {
+ VPageDescr *vpleft,
+ *vpright,
+ vpsave;
+
+ /* re-sort Nvpl.vpl_pgdesc */
+ for (vpleft = Nvpl.vpl_pgdesc,
+ vpright = Nvpl.vpl_pgdesc + Nvpl.vpl_npages - 1;
+ vpleft < vpright; vpleft++, vpright--)
+ {
+ vpsave = *vpleft;
+ *vpleft = *vpright;
+ *vpright = vpsave;
+ }
+ for (i = 0; i < nindices; i++)
+ vc_vaconeind(&Nvpl, Irel[i], vacrelstats->ntups);
+ }
+
+ /*
+ * clean moved tuples from last page in Nvpl list if some tuples
+ * left there
+ */
+ if (vpc->vpd_noff > 0 && offnum <= maxoff)
+ {
+ Assert(vpc->vpd_blkno == blkno - 1);
+ buf = ReadBuffer(onerel, vpc->vpd_blkno);
+ page = BufferGetPage(buf);
+ ntups = 0;
+ maxoff = offnum;
+ for (offnum = FirstOffsetNumber;
+ offnum < maxoff;
+ offnum = OffsetNumberNext(offnum))
+ {
+ itemid = PageGetItemId(page, offnum);
+ if (!ItemIdIsUsed(itemid))
+ continue;
+ htup = (HeapTuple) PageGetItem(page, itemid);
+ Assert(TransactionIdEquals((TransactionId) htup->t_xmax, myXID));
+ itemid->lp_flags &= ~LP_USED;
+ ntups++;
+ }
+ Assert(vpc->vpd_noff == ntups);
+ PageRepairFragmentation(page);
+ WriteBuffer(buf);
+ }
+
+ /* now - free new list of reapped pages */
+ vpp = Nvpl.vpl_pgdesc;
+ for (i = 0; i < Nvpl.vpl_npages; i++, vpp++)
+ pfree(*vpp);
+ pfree(Nvpl.vpl_pgdesc);
}
- /*
- * clean moved tuples from last page in Nvpl list
- * if some tuples left there
- */
- if ( vpc->vpd_noff > 0 && offnum <= maxoff )
+ /* truncate relation */
+ if (blkno < nblocks)
{
- Assert (vpc->vpd_blkno == blkno - 1);
- buf = ReadBuffer(onerel, vpc->vpd_blkno);
- page = BufferGetPage (buf);
- ntups = 0;
- maxoff = offnum;
- for (offnum = FirstOffsetNumber;
- offnum < maxoff;
- offnum = OffsetNumberNext(offnum))
- {
- itemid = PageGetItemId(page, offnum);
- if (!ItemIdIsUsed(itemid))
- continue;
- htup = (HeapTuple) PageGetItem(page, itemid);
- Assert ( TransactionIdEquals((TransactionId)htup->t_xmax, myXID) );
- itemid->lp_flags &= ~LP_USED;
- ntups++;
- }
- Assert ( vpc->vpd_noff == ntups );
- PageRepairFragmentation(page);
- WriteBuffer (buf);
+ blkno = smgrtruncate(onerel->rd_rel->relsmgr, onerel, blkno);
+ Assert(blkno >= 0);
+ vacrelstats->npages = blkno; /* set new number of blocks */
+ }
+
+ if (archrel != (Relation) NULL)
+ heap_close(archrel);
+
+ if (Irel != (Relation *) NULL) /* pfree index' allocations */
+ {
+ pfree(Idesc);
+ pfree(idatum);
+ pfree(inulls);
+ vc_clsindices(nindices, Irel);
}
- /* now - free new list of reapped pages */
- vpp = Nvpl.vpl_pgdesc;
- for (i = 0; i < Nvpl.vpl_npages; i++, vpp++)
- pfree(*vpp);
- pfree (Nvpl.vpl_pgdesc);
- }
-
- /* truncate relation */
- if ( blkno < nblocks )
- {
- blkno = smgrtruncate (onerel->rd_rel->relsmgr, onerel, blkno);
- Assert ( blkno >= 0 );
- vacrelstats->npages = blkno; /* set new number of blocks */
- }
-
- if ( archrel != (Relation) NULL )
- heap_close(archrel);
-
- if ( Irel != (Relation*) NULL ) /* pfree index' allocations */
- {
- pfree (Idesc);
- pfree (idatum);
- pfree (inulls);
- vc_clsindices (nindices, Irel);
- }
-
- pfree (vpc);
-
-} /* vc_rpfheap */
+ pfree(vpc);
+
+} /* vc_rpfheap */
/*
- * vc_vacheap() -- free dead tuples
+ * vc_vacheap() -- free dead tuples
*
- * This routine marks dead tuples as unused and truncates relation
- * if there are "empty" end-blocks.
+ * This routine marks dead tuples as unused and truncates relation
+ * if there are "empty" end-blocks.
*/
static void
-vc_vacheap (VRelStats *vacrelstats, Relation onerel, VPageList Vvpl)
+vc_vacheap(VRelStats * vacrelstats, Relation onerel, VPageList Vvpl)
{
- Buffer buf;
- Page page;
- VPageDescr *vpp;
- Relation archrel;
- int nblocks;
- int i;
-
- nblocks = Vvpl->vpl_npages;
- /* if the relation has an archive, open it */
- if (onerel->rd_rel->relarch != 'n')
- archrel = vc_getarchrel(onerel);
- else
- {
- archrel = (Relation) NULL;
- nblocks -= Vvpl->vpl_nemend; /* nothing to do with them */
- }
-
- for (i = 0, vpp = Vvpl->vpl_pgdesc; i < nblocks; i++, vpp++)
- {
- if ( (*vpp)->vpd_noff > 0 )
+ Buffer buf;
+ Page page;
+ VPageDescr *vpp;
+ Relation archrel;
+ int nblocks;
+ int i;
+
+ nblocks = Vvpl->vpl_npages;
+ /* if the relation has an archive, open it */
+ if (onerel->rd_rel->relarch != 'n')
+ archrel = vc_getarchrel(onerel);
+ else
{
- buf = ReadBuffer(onerel, (*vpp)->vpd_blkno);
- page = BufferGetPage (buf);
- vc_vacpage (page, *vpp, archrel);
- WriteBuffer (buf);
+ archrel = (Relation) NULL;
+ nblocks -= Vvpl->vpl_nemend; /* nothing to do with them */
+ }
+
+ for (i = 0, vpp = Vvpl->vpl_pgdesc; i < nblocks; i++, vpp++)
+ {
+ if ((*vpp)->vpd_noff > 0)
+ {
+ buf = ReadBuffer(onerel, (*vpp)->vpd_blkno);
+ page = BufferGetPage(buf);
+ vc_vacpage(page, *vpp, archrel);
+ WriteBuffer(buf);
+ }
}
- }
-
- /* truncate relation if there are some empty end-pages */
- if ( Vvpl->vpl_nemend > 0 )
- {
- Assert ( vacrelstats->npages >= Vvpl->vpl_nemend );
- nblocks = vacrelstats->npages - Vvpl->vpl_nemend;
- elog (MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u.",
- (RelationGetRelationName(onerel))->data,
- vacrelstats->npages, nblocks);
-
- /*
- * we have to flush "empty" end-pages (if changed, but who knows it)
- * before truncation
- */
- FlushBufferPool(!TransactionFlushEnabled());
- nblocks = smgrtruncate (onerel->rd_rel->relsmgr, onerel, nblocks);
- Assert ( nblocks >= 0 );
- vacrelstats->npages = nblocks; /* set new number of blocks */
- }
+ /* truncate relation if there are some empty end-pages */
+ if (Vvpl->vpl_nemend > 0)
+ {
+ Assert(vacrelstats->npages >= Vvpl->vpl_nemend);
+ nblocks = vacrelstats->npages - Vvpl->vpl_nemend;
+ elog(MESSAGE_LEVEL, "Rel %s: Pages: %u --> %u.",
+ (RelationGetRelationName(onerel))->data,
+ vacrelstats->npages, nblocks);
+
+ /*
+ * we have to flush "empty" end-pages (if changed, but who knows
+ * it) before truncation
+ */
+ FlushBufferPool(!TransactionFlushEnabled());
+
+ nblocks = smgrtruncate(onerel->rd_rel->relsmgr, onerel, nblocks);
+ Assert(nblocks >= 0);
+ vacrelstats->npages = nblocks; /* set new number of blocks */
+ }
- if ( archrel != (Relation) NULL )
- heap_close(archrel);
+ if (archrel != (Relation) NULL)
+ heap_close(archrel);
-} /* vc_vacheap */
+} /* vc_vacheap */
/*
- * vc_vacpage() -- free (and archive if needed) dead tuples on a page
- * and repaire its fragmentation.
+ * vc_vacpage() -- free (and archive if needed) dead tuples on a page
+ * and repaire its fragmentation.
*/
static void
-vc_vacpage (Page page, VPageDescr vpd, Relation archrel)
+vc_vacpage(Page page, VPageDescr vpd, Relation archrel)
{
- ItemId itemid;
- HeapTuple htup;
- int i;
-
- Assert ( vpd->vpd_nusd == 0 );
- for (i=0; i < vpd->vpd_noff; i++)
- {
- itemid = &(((PageHeader) page)->pd_linp[vpd->vpd_voff[i] - 1]);
- if ( archrel != (Relation) NULL && ItemIdIsUsed(itemid) )
+ ItemId itemid;
+ HeapTuple htup;
+ int i;
+
+ Assert(vpd->vpd_nusd == 0);
+ for (i = 0; i < vpd->vpd_noff; i++)
{
- htup = (HeapTuple) PageGetItem (page, itemid);
- vc_archive (archrel, htup);
+ itemid = &(((PageHeader) page)->pd_linp[vpd->vpd_voff[i] - 1]);
+ if (archrel != (Relation) NULL && ItemIdIsUsed(itemid))
+ {
+ htup = (HeapTuple) PageGetItem(page, itemid);
+ vc_archive(archrel, htup);
+ }
+ itemid->lp_flags &= ~LP_USED;
}
- itemid->lp_flags &= ~LP_USED;
- }
- PageRepairFragmentation(page);
+ PageRepairFragmentation(page);
-} /* vc_vacpage */
+} /* vc_vacpage */
/*
- * _vc_scanoneind() -- scan one index relation to update statistic.
+ * _vc_scanoneind() -- scan one index relation to update statistic.
*
*/
static void
-vc_scanoneind (Relation indrel, int nhtups)
+vc_scanoneind(Relation indrel, int nhtups)
{
- RetrieveIndexResult res;
- IndexScanDesc iscan;
- int nitups;
- int nipages;
- struct rusage ru0, ru1;
+ RetrieveIndexResult res;
+ IndexScanDesc iscan;
+ int nitups;
+ int nipages;
+ struct rusage ru0,
+ ru1;
- getrusage(RUSAGE_SELF, &ru0);
+ getrusage(RUSAGE_SELF, &ru0);
- /* walk through the entire index */
- iscan = index_beginscan(indrel, false, 0, (ScanKey) NULL);
- nitups = 0;
+ /* walk through the entire index */
+ iscan = index_beginscan(indrel, false, 0, (ScanKey) NULL);
+ nitups = 0;
- while ((res = index_getnext(iscan, ForwardScanDirection))
- != (RetrieveIndexResult) NULL)
- {
- nitups++;
- pfree(res);
- }
+ while ((res = index_getnext(iscan, ForwardScanDirection))
+ != (RetrieveIndexResult) NULL)
+ {
+ nitups++;
+ pfree(res);
+ }
- index_endscan(iscan);
+ index_endscan(iscan);
- /* now update statistics in pg_class */
- nipages = RelationGetNumberOfBlocks(indrel);
- vc_updstats(indrel->rd_id, nipages, nitups, false, NULL);
+ /* now update statistics in pg_class */
+ nipages = RelationGetNumberOfBlocks(indrel);
+ vc_updstats(indrel->rd_id, nipages, nitups, false, NULL);
- getrusage(RUSAGE_SELF, &ru1);
+ getrusage(RUSAGE_SELF, &ru1);
- elog (MESSAGE_LEVEL, "Ind %s: Pages %u; Tuples %u. Elapsed %u/%u sec.",
- indrel->rd_rel->relname.data, nipages, nitups,
- ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
- ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
+ elog(MESSAGE_LEVEL, "Ind %s: Pages %u; Tuples %u. Elapsed %u/%u sec.",
+ indrel->rd_rel->relname.data, nipages, nitups,
+ ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
+ ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
- if ( nitups != nhtups )
- elog (NOTICE, "Ind %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)",
- indrel->rd_rel->relname.data, nitups, nhtups);
+ if (nitups != nhtups)
+ elog(NOTICE, "Ind %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)",
+ indrel->rd_rel->relname.data, nitups, nhtups);
-} /* vc_scanoneind */
+} /* vc_scanoneind */
/*
- * vc_vaconeind() -- vacuum one index relation.
+ * vc_vaconeind() -- vacuum one index relation.
*
- * Vpl is the VPageList of the heap we're currently vacuuming.
- * It's locked. Indrel is an index relation on the vacuumed heap.
- * We don't set locks on the index relation here, since the indexed
- * access methods support locking at different granularities.
- * We let them handle it.
+ * Vpl is the VPageList of the heap we're currently vacuuming.
+ * It's locked. Indrel is an index relation on the vacuumed heap.
+ * We don't set locks on the index relation here, since the indexed
+ * access methods support locking at different granularities.
+ * We let them handle it.
*
- * Finally, we arrange to update the index relation's statistics in
- * pg_class.
+ * Finally, we arrange to update the index relation's statistics in
+ * pg_class.
*/
static void
vc_vaconeind(VPageList vpl, Relation indrel, int nhtups)
{
- RetrieveIndexResult res;
- IndexScanDesc iscan;
- ItemPointer heapptr;
- int nvac;
- int nitups;
- int nipages;
- VPageDescr vp;
- struct rusage ru0, ru1;
-
- getrusage(RUSAGE_SELF, &ru0);
-
- /* walk through the entire index */
- iscan = index_beginscan(indrel, false, 0, (ScanKey) NULL);
- nvac = 0;
- nitups = 0;
-
- while ((res = index_getnext(iscan, ForwardScanDirection))
- != (RetrieveIndexResult) NULL) {
- heapptr = &res->heap_iptr;
-
- if ( (vp = vc_tidreapped (heapptr, vpl)) != (VPageDescr) NULL)
+ RetrieveIndexResult res;
+ IndexScanDesc iscan;
+ ItemPointer heapptr;
+ int nvac;
+ int nitups;
+ int nipages;
+ VPageDescr vp;
+ struct rusage ru0,
+ ru1;
+
+ getrusage(RUSAGE_SELF, &ru0);
+
+ /* walk through the entire index */
+ iscan = index_beginscan(indrel, false, 0, (ScanKey) NULL);
+ nvac = 0;
+ nitups = 0;
+
+ while ((res = index_getnext(iscan, ForwardScanDirection))
+ != (RetrieveIndexResult) NULL)
{
+ heapptr = &res->heap_iptr;
+
+ if ((vp = vc_tidreapped(heapptr, vpl)) != (VPageDescr) NULL)
+ {
#if 0
- elog(DEBUG, "<%x,%x> -> <%x,%x>",
- ItemPointerGetBlockNumber(&(res->index_iptr)),
- ItemPointerGetOffsetNumber(&(res->index_iptr)),
- ItemPointerGetBlockNumber(&(res->heap_iptr)),
- ItemPointerGetOffsetNumber(&(res->heap_iptr)));
+ elog(DEBUG, "<%x,%x> -> <%x,%x>",
+ ItemPointerGetBlockNumber(&(res->index_iptr)),
+ ItemPointerGetOffsetNumber(&(res->index_iptr)),
+ ItemPointerGetBlockNumber(&(res->heap_iptr)),
+ ItemPointerGetOffsetNumber(&(res->heap_iptr)));
#endif
- if ( vp->vpd_noff == 0 )
- { /* this is EmptyPage !!! */
- elog (NOTICE, "Ind %s: pointer to EmptyPage (blk %u off %u) - fixing",
- indrel->rd_rel->relname.data,
- vp->vpd_blkno, ItemPointerGetOffsetNumber(heapptr));
- }
- ++nvac;
- index_delete(indrel, &res->index_iptr);
- } else {
- nitups++;
- }
+ if (vp->vpd_noff == 0)
+ { /* this is EmptyPage !!! */
+ elog(NOTICE, "Ind %s: pointer to EmptyPage (blk %u off %u) - fixing",
+ indrel->rd_rel->relname.data,
+ vp->vpd_blkno, ItemPointerGetOffsetNumber(heapptr));
+ }
+ ++nvac;
+ index_delete(indrel, &res->index_iptr);
+ }
+ else
+ {
+ nitups++;
+ }
- /* be tidy */
- pfree(res);
- }
+ /* be tidy */
+ pfree(res);
+ }
- index_endscan(iscan);
+ index_endscan(iscan);
- /* now update statistics in pg_class */
- nipages = RelationGetNumberOfBlocks(indrel);
- vc_updstats(indrel->rd_id, nipages, nitups, false, NULL);
+ /* now update statistics in pg_class */
+ nipages = RelationGetNumberOfBlocks(indrel);
+ vc_updstats(indrel->rd_id, nipages, nitups, false, NULL);
- getrusage(RUSAGE_SELF, &ru1);
+ getrusage(RUSAGE_SELF, &ru1);
- elog (MESSAGE_LEVEL, "Ind %s: Pages %u; Tuples %u: Deleted %u. Elapsed %u/%u sec.",
- indrel->rd_rel->relname.data, nipages, nitups, nvac,
- ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
- ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
+ elog(MESSAGE_LEVEL, "Ind %s: Pages %u; Tuples %u: Deleted %u. Elapsed %u/%u sec.",
+ indrel->rd_rel->relname.data, nipages, nitups, nvac,
+ ru1.ru_stime.tv_sec - ru0.ru_stime.tv_sec,
+ ru1.ru_utime.tv_sec - ru0.ru_utime.tv_sec);
- if ( nitups != nhtups )
- elog (NOTICE, "Ind %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)",
- indrel->rd_rel->relname.data, nitups, nhtups);
+ if (nitups != nhtups)
+ elog(NOTICE, "Ind %s: NUMBER OF INDEX' TUPLES (%u) IS NOT THE SAME AS HEAP' (%u)",
+ indrel->rd_rel->relname.data, nitups, nhtups);
-} /* vc_vaconeind */
+} /* vc_vaconeind */
/*
- * vc_tidreapped() -- is a particular tid reapped?
+ * vc_tidreapped() -- is a particular tid reapped?
*
- * vpl->VPageDescr_array is sorted in right order.
+ * vpl->VPageDescr_array is sorted in right order.
*/
-static VPageDescr
+static VPageDescr
vc_tidreapped(ItemPointer itemptr, VPageList vpl)
{
- OffsetNumber ioffno;
- OffsetNumber *voff;
- VPageDescr vp, *vpp;
- VPageDescrData vpd;
-
- vpd.vpd_blkno = ItemPointerGetBlockNumber(itemptr);
- ioffno = ItemPointerGetOffsetNumber(itemptr);
-
- vp = &vpd;
- vpp = (VPageDescr*) vc_find_eq ((char*)(vpl->vpl_pgdesc),
- vpl->vpl_npages, sizeof (VPageDescr), (char*)&vp,
- vc_cmp_blk);
-
- if ( vpp == (VPageDescr*) NULL )
- return ((VPageDescr)NULL);
- vp = *vpp;
-
- /* ok - we are on true page */
-
- if ( vp->vpd_noff == 0 ) { /* this is EmptyPage !!! */
- return (vp);
- }
-
- voff = (OffsetNumber*) vc_find_eq ((char*)(vp->vpd_voff),
- vp->vpd_noff, sizeof (OffsetNumber), (char*)&ioffno,
- vc_cmp_offno);
+ OffsetNumber ioffno;
+ OffsetNumber *voff;
+ VPageDescr vp,
+ *vpp;
+ VPageDescrData vpd;
- if ( voff == (OffsetNumber*) NULL )
- return ((VPageDescr)NULL);
+ vpd.vpd_blkno = ItemPointerGetBlockNumber(itemptr);
+ ioffno = ItemPointerGetOffsetNumber(itemptr);
- return (vp);
+ vp = &vpd;
+ vpp = (VPageDescr *) vc_find_eq((char *) (vpl->vpl_pgdesc),
+ vpl->vpl_npages, sizeof(VPageDescr), (char *) &vp,
+ vc_cmp_blk);
-} /* vc_tidreapped */
+ if (vpp == (VPageDescr *) NULL)
+ return ((VPageDescr) NULL);
+ vp = *vpp;
+
+ /* ok - we are on true page */
+
+ if (vp->vpd_noff == 0)
+ { /* this is EmptyPage !!! */
+ return (vp);
+ }
+
+ voff = (OffsetNumber *) vc_find_eq((char *) (vp->vpd_voff),
+ vp->vpd_noff, sizeof(OffsetNumber), (char *) &ioffno,
+ vc_cmp_offno);
+
+ if (voff == (OffsetNumber *) NULL)
+ return ((VPageDescr) NULL);
+
+ return (vp);
+
+} /* vc_tidreapped */
/*
- * vc_attrstats() -- compute column statistics used by the optimzer
+ * vc_attrstats() -- compute column statistics used by the optimzer
*
- * We compute the column min, max, null and non-null counts.
- * Plus we attempt to find the count of the value that occurs most
- * frequently in each column
- * These figures are used to compute the selectivity of the column
+ * We compute the column min, max, null and non-null counts.
+ * Plus we attempt to find the count of the value that occurs most
+ * frequently in each column
+ * These figures are used to compute the selectivity of the column
*
- * We use a three-bucked cache to get the most frequent item
- * The 'guess' buckets count hits. A cache miss causes guess1
- * to get the most hit 'guess' item in the most recent cycle, and
- * the new item goes into guess2. Whenever the total count of hits
- * of a 'guess' entry is larger than 'best', 'guess' becomes 'best'.
+ * We use a three-bucked cache to get the most frequent item
+ * The 'guess' buckets count hits. A cache miss causes guess1
+ * to get the most hit 'guess' item in the most recent cycle, and
+ * the new item goes into guess2. Whenever the total count of hits
+ * of a 'guess' entry is larger than 'best', 'guess' becomes 'best'.
*
- * This method works perfectly for columns with unique values, and columns
- * with only two unique values, plus nulls.
+ * This method works perfectly for columns with unique values, and columns
+ * with only two unique values, plus nulls.
*
- * It becomes less perfect as the number of unique values increases and
- * their distribution in the table becomes more random.
+ * It becomes less perfect as the number of unique values increases and
+ * their distribution in the table becomes more random.
*
*/
static void
-vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple htup)
+vc_attrstats(Relation onerel, VRelStats * vacrelstats, HeapTuple htup)
{
- int i, attr_cnt = vacrelstats->va_natts;
- VacAttrStats *vacattrstats = vacrelstats->vacattrstats;
- TupleDesc tupDesc = onerel->rd_att;
- Datum value;
- bool isnull;
-
- for (i = 0; i < attr_cnt; i++) {
- VacAttrStats *stats = &vacattrstats[i];
- bool value_hit = true;
-
- value = (Datum) heap_getattr (htup, InvalidBuffer,
- stats->attr->attnum, tupDesc, &isnull);
-
- if (!VacAttrStatsEqValid(stats))
- continue;
-
- if (isnull)
- stats->null_cnt++;
- else {
- stats->nonnull_cnt++;
- if (stats->initialized == false) {
- vc_bucketcpy(stats->attr, value, &stats->best, &stats->best_len);
- /* best_cnt gets incremented later */
- vc_bucketcpy(stats->attr, value, &stats->guess1, &stats->guess1_len);
- stats->guess1_cnt = stats->guess1_hits = 1;
- vc_bucketcpy(stats->attr, value, &stats->guess2, &stats->guess2_len);
- stats->guess2_hits = 1;
- if (VacAttrStatsLtGtValid(stats)) {
- vc_bucketcpy(stats->attr, value, &stats->max , &stats->max_len);
- vc_bucketcpy(stats->attr, value, &stats->min, &stats->min_len);
+ int i,
+ attr_cnt = vacrelstats->va_natts;
+ VacAttrStats *vacattrstats = vacrelstats->vacattrstats;
+ TupleDesc tupDesc = onerel->rd_att;
+ Datum value;
+ bool isnull;
+
+ for (i = 0; i < attr_cnt; i++)
+ {
+ VacAttrStats *stats = &vacattrstats[i];
+ bool value_hit = true;
+
+ value = (Datum) heap_getattr(htup, InvalidBuffer,
+ stats->attr->attnum, tupDesc, &isnull);
+
+ if (!VacAttrStatsEqValid(stats))
+ continue;
+
+ if (isnull)
+ stats->null_cnt++;
+ else
+ {
+ stats->nonnull_cnt++;
+ if (stats->initialized == false)
+ {
+ vc_bucketcpy(stats->attr, value, &stats->best, &stats->best_len);
+ /* best_cnt gets incremented later */
+ vc_bucketcpy(stats->attr, value, &stats->guess1, &stats->guess1_len);
+ stats->guess1_cnt = stats->guess1_hits = 1;
+ vc_bucketcpy(stats->attr, value, &stats->guess2, &stats->guess2_len);
+ stats->guess2_hits = 1;
+ if (VacAttrStatsLtGtValid(stats))
+ {
+ vc_bucketcpy(stats->attr, value, &stats->max, &stats->max_len);
+ vc_bucketcpy(stats->attr, value, &stats->min, &stats->min_len);
+ }
+ stats->initialized = true;
+ }
+ if (VacAttrStatsLtGtValid(stats))
+ {
+ if ((*(stats->f_cmplt)) (value, stats->min))
+ {
+ vc_bucketcpy(stats->attr, value, &stats->min, &stats->min_len);
+ stats->min_cnt = 0;
+ }
+ if ((*(stats->f_cmpgt)) (value, stats->max))
+ {
+ vc_bucketcpy(stats->attr, value, &stats->max, &stats->max_len);
+ stats->max_cnt = 0;
+ }
+ if ((*(stats->f_cmpeq)) (value, stats->min))
+ stats->min_cnt++;
+ else if ((*(stats->f_cmpeq)) (value, stats->max))
+ stats->max_cnt++;
+ }
+ if ((*(stats->f_cmpeq)) (value, stats->best))
+ stats->best_cnt++;
+ else if ((*(stats->f_cmpeq)) (value, stats->guess1))
+ {
+ stats->guess1_cnt++;
+ stats->guess1_hits++;
+ }
+ else if ((*(stats->f_cmpeq)) (value, stats->guess2))
+ stats->guess2_hits++;
+ else
+ value_hit = false;
+
+ if (stats->guess2_hits > stats->guess1_hits)
+ {
+ swapDatum(stats->guess1, stats->guess2);
+ swapInt(stats->guess1_len, stats->guess2_len);
+ stats->guess1_cnt = stats->guess2_hits;
+ swapLong(stats->guess1_hits, stats->guess2_hits);
+ }
+ if (stats->guess1_cnt > stats->best_cnt)
+ {
+ swapDatum(stats->best, stats->guess1);
+ swapInt(stats->best_len, stats->guess1_len);
+ swapLong(stats->best_cnt, stats->guess1_cnt);
+ stats->guess1_hits = 1;
+ stats->guess2_hits = 1;
+ }
+ if (!value_hit)
+ {
+ vc_bucketcpy(stats->attr, value, &stats->guess2, &stats->guess2_len);
+ stats->guess1_hits = 1;
+ stats->guess2_hits = 1;
+ }
}
- stats->initialized = true;
- }
- if (VacAttrStatsLtGtValid(stats)) {
- if ( (*(stats->f_cmplt)) (value,stats->min) ) {
- vc_bucketcpy(stats->attr, value, &stats->min, &stats->min_len);
- stats->min_cnt = 0;
- }
- if ( (*(stats->f_cmpgt)) (value,stats->max) ) {
- vc_bucketcpy(stats->attr, value, &stats->max, &stats->max_len);
- stats->max_cnt = 0;
- }
- if ( (*(stats->f_cmpeq)) (value,stats->min) )
- stats->min_cnt++;
- else if ( (*(stats->f_cmpeq)) (value,stats->max) )
- stats->max_cnt++;
- }
- if ( (*(stats->f_cmpeq)) (value,stats->best) )
- stats->best_cnt++;
- else if ( (*(stats->f_cmpeq)) (value,stats->guess1) ) {
- stats->guess1_cnt++;
- stats->guess1_hits++;
- }
- else if ( (*(stats->f_cmpeq)) (value,stats->guess2) )
- stats->guess2_hits++;
- else value_hit = false;
-
- if (stats->guess2_hits > stats->guess1_hits) {
- swapDatum(stats->guess1,stats->guess2);
- swapInt(stats->guess1_len,stats->guess2_len);
- stats->guess1_cnt = stats->guess2_hits;
- swapLong(stats->guess1_hits, stats->guess2_hits);
- }
- if (stats->guess1_cnt > stats->best_cnt) {
- swapDatum(stats->best,stats->guess1);
- swapInt(stats->best_len,stats->guess1_len);
- swapLong(stats->best_cnt,stats->guess1_cnt);
- stats->guess1_hits = 1;
- stats->guess2_hits = 1;
- }
- if (!value_hit) {
- vc_bucketcpy(stats->attr, value, &stats->guess2, &stats->guess2_len);
- stats->guess1_hits = 1;
- stats->guess2_hits = 1;
- }
}
- }
- return;
+ return;
}
/*
- * vc_bucketcpy() -- update pg_class statistics for one relation
+ * vc_bucketcpy() -- update pg_class statistics for one relation
*
*/
static void
-vc_bucketcpy(AttributeTupleForm attr, Datum value, Datum *bucket, int16 *bucket_len)
+vc_bucketcpy(AttributeTupleForm attr, Datum value, Datum * bucket, int16 * bucket_len)
{
- if (attr->attbyval && attr->attlen != -1)
- *bucket = value;
- else {
- int len = (attr->attlen != -1 ? attr->attlen : VARSIZE(value));
-
- if (len > *bucket_len)
- {
- if (*bucket_len != 0)
- pfree(DatumGetPointer(*bucket));
- *bucket = PointerGetDatum(palloc(len));
- *bucket_len = len;
+ if (attr->attbyval && attr->attlen != -1)
+ *bucket = value;
+ else
+ {
+ int len = (attr->attlen != -1 ? attr->attlen : VARSIZE(value));
+
+ if (len > *bucket_len)
+ {
+ if (*bucket_len != 0)
+ pfree(DatumGetPointer(*bucket));
+ *bucket = PointerGetDatum(palloc(len));
+ *bucket_len = len;
+ }
+ memmove(DatumGetPointer(*bucket), DatumGetPointer(value), len);
}
- memmove(DatumGetPointer(*bucket), DatumGetPointer(value), len);
- }
}
/*
- * vc_updstats() -- update pg_class statistics for one relation
+ * vc_updstats() -- update pg_class statistics for one relation
*
- * This routine works for both index and heap relation entries in
- * pg_class. We violate no-overwrite semantics here by storing new
- * values for ntups, npages, and hasindex directly in the pg_class
- * tuple that's already on the page. The reason for this is that if
- * we updated these tuples in the usual way, then every tuple in pg_class
- * would be replaced every day. This would make planning and executing
- * historical queries very expensive.
+ * This routine works for both index and heap relation entries in
+ * pg_class. We violate no-overwrite semantics here by storing new
+ * values for ntups, npages, and hasindex directly in the pg_class
+ * tuple that's already on the page. The reason for this is that if
+ * we updated these tuples in the usual way, then every tuple in pg_class
+ * would be replaced every day. This would make planning and executing
+ * historical queries very expensive.
*/
static void
-vc_updstats(Oid relid, int npages, int ntups, bool hasindex, VRelStats *vacrelstats)
+vc_updstats(Oid relid, int npages, int ntups, bool hasindex, VRelStats * vacrelstats)
{
- Relation rd, ad, sd;
- HeapScanDesc rsdesc, asdesc;
- TupleDesc sdesc;
- HeapTuple rtup, atup, stup;
- Buffer rbuf, abuf;
- Form_pg_class pgcform;
- ScanKeyData rskey, askey;
- AttributeTupleForm attp;
-
- /*
- * update number of tuples and number of pages in pg_class
- */
- ScanKeyEntryInitialize(&rskey, 0x0, ObjectIdAttributeNumber,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relid));
-
- rd = heap_openr(RelationRelationName);
- rsdesc = heap_beginscan(rd, false, NowTimeQual, 1, &rskey);
-
- if (!HeapTupleIsValid(rtup = heap_getnext(rsdesc, 0, &rbuf)))
- elog(WARN, "pg_class entry for relid %d vanished during vacuuming",
- relid);
-
- /* overwrite the existing statistics in the tuple */
- vc_setpagelock(rd, BufferGetBlockNumber(rbuf));
- pgcform = (Form_pg_class) GETSTRUCT(rtup);
- pgcform->reltuples = ntups;
- pgcform->relpages = npages;
- pgcform->relhasindex = hasindex;
-
- if ( vacrelstats != NULL && vacrelstats->va_natts > 0 )
- {
- VacAttrStats *vacattrstats = vacrelstats->vacattrstats;
- int natts = vacrelstats->va_natts;
-
- ad = heap_openr(AttributeRelationName);
- sd = heap_openr(StatisticRelationName);
- ScanKeyEntryInitialize(&askey, 0, Anum_pg_attribute_attrelid,
- F_INT4EQ, relid);
-
- asdesc = heap_beginscan(ad, false, NowTimeQual, 1, &askey);
-
- while (HeapTupleIsValid(atup = heap_getnext(asdesc, 0, &abuf)))
+ Relation rd,
+ ad,
+ sd;
+ HeapScanDesc rsdesc,
+ asdesc;
+ TupleDesc sdesc;
+ HeapTuple rtup,
+ atup,
+ stup;
+ Buffer rbuf,
+ abuf;
+ Form_pg_class pgcform;
+ ScanKeyData rskey,
+ askey;
+ AttributeTupleForm attp;
+
+ /*
+ * update number of tuples and number of pages in pg_class
+ */
+ ScanKeyEntryInitialize(&rskey, 0x0, ObjectIdAttributeNumber,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relid));
+
+ rd = heap_openr(RelationRelationName);
+ rsdesc = heap_beginscan(rd, false, NowTimeQual, 1, &rskey);
+
+ if (!HeapTupleIsValid(rtup = heap_getnext(rsdesc, 0, &rbuf)))
+ elog(WARN, "pg_class entry for relid %d vanished during vacuuming",
+ relid);
+
+ /* overwrite the existing statistics in the tuple */
+ vc_setpagelock(rd, BufferGetBlockNumber(rbuf));
+ pgcform = (Form_pg_class) GETSTRUCT(rtup);
+ pgcform->reltuples = ntups;
+ pgcform->relpages = npages;
+ pgcform->relhasindex = hasindex;
+
+ if (vacrelstats != NULL && vacrelstats->va_natts > 0)
{
- int i;
- float32data selratio; /* average ratio of rows selected for a random constant */
- VacAttrStats *stats;
- Datum values[ Natts_pg_statistic ];
- char nulls[ Natts_pg_statistic ];
-
- attp = (AttributeTupleForm) GETSTRUCT(atup);
- if ( attp->attnum <= 0) /* skip system attributes for now, */
- /* they are unique anyway */
- continue;
-
- for (i = 0; i < natts; i++)
- {
- if ( attp->attnum == vacattrstats[i].attr->attnum )
- break;
- }
- if ( i >= natts )
- continue;
- stats = &(vacattrstats[i]);
-
- /* overwrite the existing statistics in the tuple */
- if (VacAttrStatsEqValid(stats)) {
-
- vc_setpagelock(ad, BufferGetBlockNumber(abuf));
-
- if (stats->nonnull_cnt + stats->null_cnt == 0 ||
- (stats->null_cnt <= 1 && stats->best_cnt == 1))
- selratio = 0;
- else if (VacAttrStatsLtGtValid(stats) && stats->min_cnt + stats->max_cnt == stats->nonnull_cnt)
+ VacAttrStats *vacattrstats = vacrelstats->vacattrstats;
+ int natts = vacrelstats->va_natts;
+
+ ad = heap_openr(AttributeRelationName);
+ sd = heap_openr(StatisticRelationName);
+ ScanKeyEntryInitialize(&askey, 0, Anum_pg_attribute_attrelid,
+ F_INT4EQ, relid);
+
+ asdesc = heap_beginscan(ad, false, NowTimeQual, 1, &askey);
+
+ while (HeapTupleIsValid(atup = heap_getnext(asdesc, 0, &abuf)))
{
- double min_cnt_d = stats->min_cnt,
- max_cnt_d = stats->max_cnt,
- null_cnt_d = stats->null_cnt,
- nonnullcnt_d = stats->nonnull_cnt; /* prevent overflow */
- selratio = (min_cnt_d*min_cnt_d+max_cnt_d*max_cnt_d+null_cnt_d*null_cnt_d)/
- (nonnullcnt_d+null_cnt_d)/(nonnullcnt_d+null_cnt_d);
+ int i;
+ float32data selratio; /* average ratio of rows selected
+ * for a random constant */
+ VacAttrStats *stats;
+ Datum values[Natts_pg_statistic];
+ char nulls[Natts_pg_statistic];
+
+ attp = (AttributeTupleForm) GETSTRUCT(atup);
+ if (attp->attnum <= 0) /* skip system attributes for now, */
+ /* they are unique anyway */
+ continue;
+
+ for (i = 0; i < natts; i++)
+ {
+ if (attp->attnum == vacattrstats[i].attr->attnum)
+ break;
+ }
+ if (i >= natts)
+ continue;
+ stats = &(vacattrstats[i]);
+
+ /* overwrite the existing statistics in the tuple */
+ if (VacAttrStatsEqValid(stats))
+ {
+
+ vc_setpagelock(ad, BufferGetBlockNumber(abuf));
+
+ if (stats->nonnull_cnt + stats->null_cnt == 0 ||
+ (stats->null_cnt <= 1 && stats->best_cnt == 1))
+ selratio = 0;
+ else if (VacAttrStatsLtGtValid(stats) && stats->min_cnt + stats->max_cnt == stats->nonnull_cnt)
+ {
+ double min_cnt_d = stats->min_cnt,
+ max_cnt_d = stats->max_cnt,
+ null_cnt_d = stats->null_cnt,
+ nonnullcnt_d = stats->nonnull_cnt; /* prevent overflow */
+
+ selratio = (min_cnt_d * min_cnt_d + max_cnt_d * max_cnt_d + null_cnt_d * null_cnt_d) /
+ (nonnullcnt_d + null_cnt_d) / (nonnullcnt_d + null_cnt_d);
+ }
+ else
+ {
+ double most = (double) (stats->best_cnt > stats->null_cnt ? stats->best_cnt : stats->null_cnt);
+ double total = ((double) stats->nonnull_cnt) + ((double) stats->null_cnt);
+
+ /*
+ * we assume count of other values are 20% of best
+ * count in table
+ */
+ selratio = (most * most + 0.20 * most * (total - most)) / total / total;
+ }
+ if (selratio > 1.0)
+ selratio = 1.0;
+ attp->attdisbursion = selratio;
+ WriteNoReleaseBuffer(abuf);
+
+ /* DO PG_STATISTIC INSERTS */
+
+ /*
+ * doing system relations, especially pg_statistic is a
+ * problem
+ */
+ if (VacAttrStatsLtGtValid(stats) && stats->initialized /* &&
+ * !IsSystemRelationName(
+ * pgcform->relname.data)
+ */ )
+ {
+ func_ptr out_function;
+ char *out_string;
+ int dummy;
+
+ for (i = 0; i < Natts_pg_statistic; ++i)
+ nulls[i] = ' ';
+
+ /* ----------------
+ * initialize values[]
+ * ----------------
+ */
+ i = 0;
+ values[i++] = (Datum) relid; /* 1 */
+ values[i++] = (Datum) attp->attnum; /* 2 */
+ values[i++] = (Datum) InvalidOid; /* 3 */
+ fmgr_info(stats->outfunc, &out_function, &dummy);
+ out_string = (*out_function) (stats->min, stats->attr->atttypid);
+ values[i++] = (Datum) fmgr(TextInRegProcedure, out_string);
+ pfree(out_string);
+ out_string = (char *) (*out_function) (stats->max, stats->attr->atttypid);
+ values[i++] = (Datum) fmgr(TextInRegProcedure, out_string);
+ pfree(out_string);
+
+ sdesc = sd->rd_att;
+
+ stup = heap_formtuple(sdesc, values, nulls);
+
+ /* ----------------
+ * insert the tuple in the relation and get the tuple's oid.
+ * ----------------
+ */
+ heap_insert(sd, stup);
+ pfree(DatumGetPointer(values[3]));
+ pfree(DatumGetPointer(values[4]));
+ pfree(stup);
+ }
+ }
}
- else {
- double most = (double)(stats->best_cnt > stats->null_cnt ? stats->best_cnt : stats->null_cnt);
- double total = ((double)stats->nonnull_cnt)+((double)stats->null_cnt);
- /* we assume count of other values are 20%
- of best count in table */
- selratio = (most*most + 0.20*most*(total-most))/total/total;
- }
- if (selratio > 1.0)
- selratio = 1.0;
- attp->attdisbursion = selratio;
- WriteNoReleaseBuffer(abuf);
-
- /* DO PG_STATISTIC INSERTS */
-
- /* doing system relations, especially pg_statistic is a problem */
- if (VacAttrStatsLtGtValid(stats) && stats->initialized /* &&
- !IsSystemRelationName(pgcform->relname.data)*/) {
- func_ptr out_function;
- char *out_string;
- int dummy;
-
- for (i = 0; i < Natts_pg_statistic; ++i) nulls[i] = ' ';
-
- /* ----------------
- * initialize values[]
- * ----------------
- */
- i = 0;
- values[i++] = (Datum) relid; /* 1 */
- values[i++] = (Datum) attp->attnum; /* 2 */
- values[i++] = (Datum) InvalidOid; /* 3 */
- fmgr_info(stats->outfunc, &out_function, &dummy);
- out_string = (*out_function)(stats->min, stats->attr->atttypid);
- values[i++] = (Datum) fmgr(TextInRegProcedure,out_string);
- pfree(out_string);
- out_string = (char *)(*out_function)(stats->max, stats->attr->atttypid);
- values[i++] = (Datum) fmgr(TextInRegProcedure,out_string);
- pfree(out_string);
-
- sdesc = sd->rd_att;
-
- stup = heap_formtuple(sdesc, values, nulls);
-
- /* ----------------
- * insert the tuple in the relation and get the tuple's oid.
- * ----------------
- */
- heap_insert(sd, stup);
- pfree(DatumGetPointer(values[3]));
- pfree(DatumGetPointer(values[4]));
- pfree(stup);
- }
- }
+ heap_endscan(asdesc);
+ heap_close(ad);
+ heap_close(sd);
}
- heap_endscan(asdesc);
- heap_close(ad);
- heap_close(sd);
- }
-
- /* XXX -- after write, should invalidate relcache in other backends */
- WriteNoReleaseBuffer(rbuf); /* heap_endscan release scan' buffers ? */
-
- /* invalidating system relations confuses the function cache
- of pg_operator and pg_opclass */
- if ( !IsSystemRelationName(pgcform->relname.data))
- RelationInvalidateHeapTuple(rd, rtup);
-
- /* that's all, folks */
- heap_endscan(rsdesc);
- heap_close(rd);
+
+ /* XXX -- after write, should invalidate relcache in other backends */
+ WriteNoReleaseBuffer(rbuf); /* heap_endscan release scan' buffers ? */
+
+ /*
+ * invalidating system relations confuses the function cache of
+ * pg_operator and pg_opclass
+ */
+ if (!IsSystemRelationName(pgcform->relname.data))
+ RelationInvalidateHeapTuple(rd, rtup);
+
+ /* that's all, folks */
+ heap_endscan(rsdesc);
+ heap_close(rd);
}
/*
- * vc_delhilowstats() -- delete pg_statistics rows
+ * vc_delhilowstats() -- delete pg_statistics rows
*
*/
static void
vc_delhilowstats(Oid relid, int attcnt, int *attnums)
{
- Relation pgstatistic;
- HeapScanDesc pgsscan;
- HeapTuple pgstup;
- ScanKeyData pgskey;
-
- pgstatistic = heap_openr(StatisticRelationName);
-
- if (relid != InvalidOid ) {
- ScanKeyEntryInitialize(&pgskey, 0x0, Anum_pg_statistic_starelid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relid));
- pgsscan = heap_beginscan(pgstatistic, false, NowTimeQual, 1, &pgskey);
- }
- else
- pgsscan = heap_beginscan(pgstatistic, false, NowTimeQual, 0, NULL);
-
- while (HeapTupleIsValid(pgstup = heap_getnext(pgsscan, 0, NULL)))
- {
- if ( attcnt > 0 )
- {
- Form_pg_statistic pgs = (Form_pg_statistic) GETSTRUCT (pgstup);
- int i;
-
- for (i = 0; i < attcnt; i++)
- {
- if ( pgs->staattnum == attnums[i] + 1 )
- break;
- }
- if ( i >= attcnt )
- continue; /* don't delete it */
- }
- heap_delete(pgstatistic, &pgstup->t_ctid);
- }
-
- heap_endscan(pgsscan);
- heap_close(pgstatistic);
+ Relation pgstatistic;
+ HeapScanDesc pgsscan;
+ HeapTuple pgstup;
+ ScanKeyData pgskey;
+
+ pgstatistic = heap_openr(StatisticRelationName);
+
+ if (relid != InvalidOid)
+ {
+ ScanKeyEntryInitialize(&pgskey, 0x0, Anum_pg_statistic_starelid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relid));
+ pgsscan = heap_beginscan(pgstatistic, false, NowTimeQual, 1, &pgskey);
+ }
+ else
+ pgsscan = heap_beginscan(pgstatistic, false, NowTimeQual, 0, NULL);
+
+ while (HeapTupleIsValid(pgstup = heap_getnext(pgsscan, 0, NULL)))
+ {
+ if (attcnt > 0)
+ {
+ Form_pg_statistic pgs = (Form_pg_statistic) GETSTRUCT(pgstup);
+ int i;
+
+ for (i = 0; i < attcnt; i++)
+ {
+ if (pgs->staattnum == attnums[i] + 1)
+ break;
+ }
+ if (i >= attcnt)
+ continue; /* don't delete it */
+ }
+ heap_delete(pgstatistic, &pgstup->t_ctid);
+ }
+
+ heap_endscan(pgsscan);
+ heap_close(pgstatistic);
}
-static void vc_setpagelock(Relation rel, BlockNumber blkno)
+static void
+vc_setpagelock(Relation rel, BlockNumber blkno)
{
- ItemPointerData itm;
+ ItemPointerData itm;
- ItemPointerSet(&itm, blkno, 1);
+ ItemPointerSet(&itm, blkno, 1);
- RelationSetLockForWritePage(rel, &itm);
+ RelationSetLockForWritePage(rel, &itm);
}
/*
- * vc_reappage() -- save a page on the array of reapped pages.
+ * vc_reappage() -- save a page on the array of reapped pages.
*
- * As a side effect of the way that the vacuuming loop for a given
- * relation works, higher pages come after lower pages in the array
- * (and highest tid on a page is last).
+ * As a side effect of the way that the vacuuming loop for a given
+ * relation works, higher pages come after lower pages in the array
+ * (and highest tid on a page is last).
*/
-static void
+static void
vc_reappage(VPageList vpl, VPageDescr vpc)
{
- VPageDescr newvpd;
+ VPageDescr newvpd;
- /* allocate a VPageDescrData entry */
- newvpd = (VPageDescr) palloc(sizeof(VPageDescrData) + vpc->vpd_noff*sizeof(OffsetNumber));
+ /* allocate a VPageDescrData entry */
+ newvpd = (VPageDescr) palloc(sizeof(VPageDescrData) + vpc->vpd_noff * sizeof(OffsetNumber));
- /* fill it in */
- if ( vpc->vpd_noff > 0 )
- memmove (newvpd->vpd_voff, vpc->vpd_voff, vpc->vpd_noff*sizeof(OffsetNumber));
- newvpd->vpd_blkno = vpc->vpd_blkno;
- newvpd->vpd_free = vpc->vpd_free;
- newvpd->vpd_nusd = vpc->vpd_nusd;
- newvpd->vpd_noff = vpc->vpd_noff;
+ /* fill it in */
+ if (vpc->vpd_noff > 0)
+ memmove(newvpd->vpd_voff, vpc->vpd_voff, vpc->vpd_noff * sizeof(OffsetNumber));
+ newvpd->vpd_blkno = vpc->vpd_blkno;
+ newvpd->vpd_free = vpc->vpd_free;
+ newvpd->vpd_nusd = vpc->vpd_nusd;
+ newvpd->vpd_noff = vpc->vpd_noff;
- /* insert this page into vpl list */
- vc_vpinsert (vpl, newvpd);
-
-} /* vc_reappage */
+ /* insert this page into vpl list */
+ vc_vpinsert(vpl, newvpd);
+
+} /* vc_reappage */
static void
-vc_vpinsert (VPageList vpl, VPageDescr vpnew)
+vc_vpinsert(VPageList vpl, VPageDescr vpnew)
{
- /* allocate a VPageDescr entry if needed */
- if ( vpl->vpl_npages == 0 )
- vpl->vpl_pgdesc = (VPageDescr*) palloc(100*sizeof(VPageDescr));
- else if ( vpl->vpl_npages % 100 == 0 )
- vpl->vpl_pgdesc = (VPageDescr*) repalloc(vpl->vpl_pgdesc, (vpl->vpl_npages+100)*sizeof(VPageDescr));
- vpl->vpl_pgdesc[vpl->vpl_npages] = vpnew;
- (vpl->vpl_npages)++;
-
+ /* allocate a VPageDescr entry if needed */
+ if (vpl->vpl_npages == 0)
+ vpl->vpl_pgdesc = (VPageDescr *) palloc(100 * sizeof(VPageDescr));
+ else if (vpl->vpl_npages % 100 == 0)
+ vpl->vpl_pgdesc = (VPageDescr *) repalloc(vpl->vpl_pgdesc, (vpl->vpl_npages + 100) * sizeof(VPageDescr));
+ vpl->vpl_pgdesc[vpl->vpl_npages] = vpnew;
+ (vpl->vpl_npages)++;
+
}
static void
vc_free(VRelList vrl)
{
- VRelList p_vrl;
- MemoryContext old;
- PortalVariableMemory pmem;
+ VRelList p_vrl;
+ MemoryContext old;
+ PortalVariableMemory pmem;
- pmem = PortalGetVariableMemory(vc_portal);
- old = MemoryContextSwitchTo((MemoryContext)pmem);
+ pmem = PortalGetVariableMemory(vc_portal);
+ old = MemoryContextSwitchTo((MemoryContext) pmem);
- while (vrl != (VRelList) NULL) {
+ while (vrl != (VRelList) NULL)
+ {
- /* free rel list entry */
- p_vrl = vrl;
- vrl = vrl->vrl_next;
- pfree(p_vrl);
- }
+ /* free rel list entry */
+ p_vrl = vrl;
+ vrl = vrl->vrl_next;
+ pfree(p_vrl);
+ }
- MemoryContextSwitchTo(old);
+ MemoryContextSwitchTo(old);
}
/*
- * vc_getarchrel() -- open the archive relation for a heap relation
+ * vc_getarchrel() -- open the archive relation for a heap relation
*
- * The archive relation is named 'a,XXXXX' for the heap relation
- * whose relid is XXXXX.
+ * The archive relation is named 'a,XXXXX' for the heap relation
+ * whose relid is XXXXX.
*/
#define ARCHIVE_PREFIX "a,"
-static Relation
+static Relation
vc_getarchrel(Relation heaprel)
{
- Relation archrel;
- char *archrelname;
+ Relation archrel;
+ char *archrelname;
- archrelname = palloc(sizeof(ARCHIVE_PREFIX) + NAMEDATALEN); /* bogus */
- sprintf(archrelname, "%s%d", ARCHIVE_PREFIX, heaprel->rd_id);
+ archrelname = palloc(sizeof(ARCHIVE_PREFIX) + NAMEDATALEN); /* bogus */
+ sprintf(archrelname, "%s%d", ARCHIVE_PREFIX, heaprel->rd_id);
- archrel = heap_openr(archrelname);
+ archrel = heap_openr(archrelname);
- pfree(archrelname);
- return (archrel);
+ pfree(archrelname);
+ return (archrel);
}
/*
- * vc_archive() -- write a tuple to an archive relation
+ * vc_archive() -- write a tuple to an archive relation
*
- * In the future, this will invoke the archived accessd method. For
- * now, archive relations are on mag disk.
+ * In the future, this will invoke the archived accessd method. For
+ * now, archive relations are on mag disk.
*/
static void
vc_archive(Relation archrel, HeapTuple htup)
{
- doinsert(archrel, htup);
+ doinsert(archrel, htup);
}
-static bool
+static bool
vc_isarchrel(char *rname)
{
- if (strncmp(ARCHIVE_PREFIX, rname,strlen(ARCHIVE_PREFIX)) == 0)
- return (true);
+ if (strncmp(ARCHIVE_PREFIX, rname, strlen(ARCHIVE_PREFIX)) == 0)
+ return (true);
- return (false);
+ return (false);
}
-static char *
-vc_find_eq (char *bot, int nelem, int size, char *elm, int (*compar)(char *, char *))
+static char *
+vc_find_eq(char *bot, int nelem, int size, char *elm, int (*compar) (char *, char *))
{
- int res;
- int last = nelem - 1;
- int celm = nelem / 2;
- bool last_move, first_move;
-
- last_move = first_move = true;
- for ( ; ; )
- {
- if ( first_move == true )
+ int res;
+ int last = nelem - 1;
+ int celm = nelem / 2;
+ bool last_move,
+ first_move;
+
+ last_move = first_move = true;
+ for (;;)
{
- res = compar (bot, elm);
- if ( res > 0 )
- return (NULL);
- if ( res == 0 )
- return (bot);
- first_move = false;
- }
- if ( last_move == true )
- {
- res = compar (elm, bot + last*size);
- if ( res > 0 )
- return (NULL);
- if ( res == 0 )
- return (bot + last*size);
- last_move = false;
- }
- res = compar (elm, bot + celm*size);
- if ( res == 0 )
- return (bot + celm*size);
- if ( res < 0 )
- {
- if ( celm == 0 )
- return (NULL);
- last = celm - 1;
- celm = celm / 2;
- last_move = true;
- continue;
+ if (first_move == true)
+ {
+ res = compar(bot, elm);
+ if (res > 0)
+ return (NULL);
+ if (res == 0)
+ return (bot);
+ first_move = false;
+ }
+ if (last_move == true)
+ {
+ res = compar(elm, bot + last * size);
+ if (res > 0)
+ return (NULL);
+ if (res == 0)
+ return (bot + last * size);
+ last_move = false;
+ }
+ res = compar(elm, bot + celm * size);
+ if (res == 0)
+ return (bot + celm * size);
+ if (res < 0)
+ {
+ if (celm == 0)
+ return (NULL);
+ last = celm - 1;
+ celm = celm / 2;
+ last_move = true;
+ continue;
+ }
+
+ if (celm == last)
+ return (NULL);
+
+ last = last - celm - 1;
+ bot = bot + (celm + 1) * size;
+ celm = (last + 1) / 2;
+ first_move = true;
}
-
- if ( celm == last )
- return (NULL);
-
- last = last - celm - 1;
- bot = bot + (celm+1)*size;
- celm = (last + 1) / 2;
- first_move = true;
- }
-
-} /* vc_find_eq */
-
-static int
-vc_cmp_blk (char *left, char *right)
+
+} /* vc_find_eq */
+
+static int
+vc_cmp_blk(char *left, char *right)
{
- BlockNumber lblk, rblk;
+ BlockNumber lblk,
+ rblk;
- lblk = (*((VPageDescr*)left))->vpd_blkno;
- rblk = (*((VPageDescr*)right))->vpd_blkno;
+ lblk = (*((VPageDescr *) left))->vpd_blkno;
+ rblk = (*((VPageDescr *) right))->vpd_blkno;
- if ( lblk < rblk )
- return (-1);
- if ( lblk == rblk )
- return (0);
- return (1);
+ if (lblk < rblk)
+ return (-1);
+ if (lblk == rblk)
+ return (0);
+ return (1);
-} /* vc_cmp_blk */
+} /* vc_cmp_blk */
-static int
-vc_cmp_offno (char *left, char *right)
+static int
+vc_cmp_offno(char *left, char *right)
{
- if ( *(OffsetNumber*)left < *(OffsetNumber*)right )
- return (-1);
- if ( *(OffsetNumber*)left == *(OffsetNumber*)right )
- return (0);
- return (1);
+ if (*(OffsetNumber *) left < *(OffsetNumber *) right)
+ return (-1);
+ if (*(OffsetNumber *) left == *(OffsetNumber *) right)
+ return (0);
+ return (1);
-} /* vc_cmp_offno */
+} /* vc_cmp_offno */
static void
-vc_getindices (Oid relid, int *nindices, Relation **Irel)
+vc_getindices(Oid relid, int *nindices, Relation ** Irel)
{
- Relation pgindex;
- Relation irel;
- TupleDesc pgidesc;
- HeapTuple pgitup;
- HeapScanDesc pgiscan;
- Datum d;
- int i, k;
- bool n;
- ScanKeyData pgikey;
- Oid *ioid;
-
- *nindices = i = 0;
-
- ioid = (Oid *) palloc(10*sizeof(Oid));
-
- /* prepare a heap scan on the pg_index relation */
- pgindex = heap_openr(IndexRelationName);
- pgidesc = RelationGetTupleDescriptor(pgindex);
-
- ScanKeyEntryInitialize(&pgikey, 0x0, Anum_pg_index_indrelid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relid));
-
- pgiscan = heap_beginscan(pgindex, false, NowTimeQual, 1, &pgikey);
-
- while (HeapTupleIsValid(pgitup = heap_getnext(pgiscan, 0, NULL))) {
- d = (Datum) heap_getattr(pgitup, InvalidBuffer, Anum_pg_index_indexrelid,
- pgidesc, &n);
- i++;
- if ( i % 10 == 0 )
- ioid = (Oid *) repalloc(ioid, (i+10)*sizeof(Oid));
- ioid[i-1] = DatumGetObjectId(d);
- }
-
- heap_endscan(pgiscan);
- heap_close(pgindex);
-
- if ( i == 0 ) { /* No one index found */
- pfree(ioid);
- return;
- }
-
- if ( Irel != (Relation **) NULL )
- *Irel = (Relation *) palloc(i * sizeof(Relation));
-
- for (k = 0; i > 0; )
- {
- irel = index_open(ioid[--i]);
- if ( irel != (Relation) NULL )
+ Relation pgindex;
+ Relation irel;
+ TupleDesc pgidesc;
+ HeapTuple pgitup;
+ HeapScanDesc pgiscan;
+ Datum d;
+ int i,
+ k;
+ bool n;
+ ScanKeyData pgikey;
+ Oid *ioid;
+
+ *nindices = i = 0;
+
+ ioid = (Oid *) palloc(10 * sizeof(Oid));
+
+ /* prepare a heap scan on the pg_index relation */
+ pgindex = heap_openr(IndexRelationName);
+ pgidesc = RelationGetTupleDescriptor(pgindex);
+
+ ScanKeyEntryInitialize(&pgikey, 0x0, Anum_pg_index_indrelid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relid));
+
+ pgiscan = heap_beginscan(pgindex, false, NowTimeQual, 1, &pgikey);
+
+ while (HeapTupleIsValid(pgitup = heap_getnext(pgiscan, 0, NULL)))
{
- if ( Irel != (Relation **) NULL )
- (*Irel)[k] = irel;
- else
- index_close (irel);
- k++;
+ d = (Datum) heap_getattr(pgitup, InvalidBuffer, Anum_pg_index_indexrelid,
+ pgidesc, &n);
+ i++;
+ if (i % 10 == 0)
+ ioid = (Oid *) repalloc(ioid, (i + 10) * sizeof(Oid));
+ ioid[i - 1] = DatumGetObjectId(d);
}
- else
- elog (NOTICE, "CAN't OPEN INDEX %u - SKIP IT", ioid[i]);
- }
- *nindices = k;
- pfree(ioid);
- if ( Irel != (Relation **) NULL && *nindices == 0 )
- {
- pfree (*Irel);
- *Irel = (Relation *) NULL;
- }
+ heap_endscan(pgiscan);
+ heap_close(pgindex);
+
+ if (i == 0)
+ { /* No one index found */
+ pfree(ioid);
+ return;
+ }
+
+ if (Irel != (Relation **) NULL)
+ *Irel = (Relation *) palloc(i * sizeof(Relation));
+
+ for (k = 0; i > 0;)
+ {
+ irel = index_open(ioid[--i]);
+ if (irel != (Relation) NULL)
+ {
+ if (Irel != (Relation **) NULL)
+ (*Irel)[k] = irel;
+ else
+ index_close(irel);
+ k++;
+ }
+ else
+ elog(NOTICE, "CAN't OPEN INDEX %u - SKIP IT", ioid[i]);
+ }
+ *nindices = k;
+ pfree(ioid);
-} /* vc_getindices */
+ if (Irel != (Relation **) NULL && *nindices == 0)
+ {
+ pfree(*Irel);
+ *Irel = (Relation *) NULL;
+ }
+
+} /* vc_getindices */
static void
-vc_clsindices (int nindices, Relation *Irel)
+vc_clsindices(int nindices, Relation * Irel)
{
- if ( Irel == (Relation*) NULL )
- return;
+ if (Irel == (Relation *) NULL)
+ return;
- while (nindices--) {
- index_close (Irel[nindices]);
- }
- pfree (Irel);
+ while (nindices--)
+ {
+ index_close(Irel[nindices]);
+ }
+ pfree(Irel);
-} /* vc_clsindices */
+} /* vc_clsindices */
static void
-vc_mkindesc (Relation onerel, int nindices, Relation *Irel, IndDesc **Idesc)
+vc_mkindesc(Relation onerel, int nindices, Relation * Irel, IndDesc ** Idesc)
{
- IndDesc *idcur;
- HeapTuple pgIndexTup;
- AttrNumber *attnumP;
- int natts;
- int i;
-
- *Idesc = (IndDesc *) palloc (nindices * sizeof (IndDesc));
-
- for (i = 0, idcur = *Idesc; i < nindices; i++, idcur++) {
- pgIndexTup =
- SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(Irel[i]->rd_id),
- 0,0,0);
- Assert(pgIndexTup);
- idcur->tform = (IndexTupleForm)GETSTRUCT(pgIndexTup);
- for (attnumP = &(idcur->tform->indkey[0]), natts = 0;
- *attnumP != InvalidAttrNumber && natts != INDEX_MAX_KEYS;
- attnumP++, natts++);
- if (idcur->tform->indproc != InvalidOid) {
- idcur->finfoP = &(idcur->finfo);
- FIgetnArgs(idcur->finfoP) = natts;
- natts = 1;
- FIgetProcOid(idcur->finfoP) = idcur->tform->indproc;
- *(FIgetname(idcur->finfoP)) = '\0';
- } else
- idcur->finfoP = (FuncIndexInfo *) NULL;
-
- idcur->natts = natts;
- }
-
-} /* vc_mkindesc */
-
-
-static bool
-vc_enough_space (VPageDescr vpd, Size len)
+ IndDesc *idcur;
+ HeapTuple pgIndexTup;
+ AttrNumber *attnumP;
+ int natts;
+ int i;
+
+ *Idesc = (IndDesc *) palloc(nindices * sizeof(IndDesc));
+
+ for (i = 0, idcur = *Idesc; i < nindices; i++, idcur++)
+ {
+ pgIndexTup =
+ SearchSysCacheTuple(INDEXRELID,
+ ObjectIdGetDatum(Irel[i]->rd_id),
+ 0, 0, 0);
+ Assert(pgIndexTup);
+ idcur->tform = (IndexTupleForm) GETSTRUCT(pgIndexTup);
+ for (attnumP = &(idcur->tform->indkey[0]), natts = 0;
+ *attnumP != InvalidAttrNumber && natts != INDEX_MAX_KEYS;
+ attnumP++, natts++);
+ if (idcur->tform->indproc != InvalidOid)
+ {
+ idcur->finfoP = &(idcur->finfo);
+ FIgetnArgs(idcur->finfoP) = natts;
+ natts = 1;
+ FIgetProcOid(idcur->finfoP) = idcur->tform->indproc;
+ *(FIgetname(idcur->finfoP)) = '\0';
+ }
+ else
+ idcur->finfoP = (FuncIndexInfo *) NULL;
+
+ idcur->natts = natts;
+ }
+
+} /* vc_mkindesc */
+
+
+static bool
+vc_enough_space(VPageDescr vpd, Size len)
{
- len = DOUBLEALIGN(len);
-
- if ( len > vpd->vpd_free )
- return (false);
-
- if ( vpd->vpd_nusd < vpd->vpd_noff ) /* there are free itemid(s) */
- return (true); /* and len <= free_space */
-
- /* ok. noff_usd >= noff_free and so we'll have to allocate new itemid */
- if ( len <= vpd->vpd_free - sizeof (ItemIdData) )
- return (true);
-
- return (false);
-
-} /* vc_enough_space */
+ len = DOUBLEALIGN(len);
+
+ if (len > vpd->vpd_free)
+ return (false);
+
+ if (vpd->vpd_nusd < vpd->vpd_noff) /* there are free itemid(s) */
+ return (true); /* and len <= free_space */
+
+ /* ok. noff_usd >= noff_free and so we'll have to allocate new itemid */
+ if (len <= vpd->vpd_free - sizeof(ItemIdData))
+ return (true);
+
+ return (false);
+
+} /* vc_enough_space */
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index 3cd011ace25..99439de9ce3 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* view.c--
- * use rewrite rules to construct views
+ * use rewrite rules to construct views
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.8 1997/08/22 14:22:14 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.9 1997/09/07 04:41:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include <postgres.h>
@@ -42,69 +42,74 @@
*---------------------------------------------------------------------
*/
static void
-DefineVirtualRelation(char *relname, List *tlist)
+DefineVirtualRelation(char *relname, List * tlist)
{
- CreateStmt createStmt;
- List *attrList, *t;
- TargetEntry *entry;
- Resdom *res;
- char *resname;
- char *restypename;
-
- /*
- * create a list with one entry per attribute of this relation.
- * Each entry is a two element list. The first element is the
- * name of the attribute (a string) and the second the name of the type
- * (NOTE: a string, not a type id!).
- */
- attrList = NIL;
- if (tlist!=NIL) {
- foreach (t, tlist ) {
- ColumnDef *def = makeNode(ColumnDef);
- TypeName *typename;
-
- /*
- * find the names of the attribute & its type
- */
- entry = lfirst(t);
- res = entry->resdom;
- resname = res->resname;
- restypename = tname(get_id_type(res->restype));
-
- typename = makeNode(TypeName);
-
- typename->name = pstrdup(restypename);
- def->colname = pstrdup(resname);
-
- def->typename = typename;
-
- def->is_not_null = false;
- def->defval = (char*) NULL;
-
- attrList = lappend(attrList, def);
+ CreateStmt createStmt;
+ List *attrList,
+ *t;
+ TargetEntry *entry;
+ Resdom *res;
+ char *resname;
+ char *restypename;
+
+ /*
+ * create a list with one entry per attribute of this relation. Each
+ * entry is a two element list. The first element is the name of the
+ * attribute (a string) and the second the name of the type (NOTE: a
+ * string, not a type id!).
+ */
+ attrList = NIL;
+ if (tlist != NIL)
+ {
+ foreach(t, tlist)
+ {
+ ColumnDef *def = makeNode(ColumnDef);
+ TypeName *typename;
+
+ /*
+ * find the names of the attribute & its type
+ */
+ entry = lfirst(t);
+ res = entry->resdom;
+ resname = res->resname;
+ restypename = tname(get_id_type(res->restype));
+
+ typename = makeNode(TypeName);
+
+ typename->name = pstrdup(restypename);
+ def->colname = pstrdup(resname);
+
+ def->typename = typename;
+
+ def->is_not_null = false;
+ def->defval = (char *) NULL;
+
+ attrList = lappend(attrList, def);
+ }
}
- } else {
- elog ( WARN, "attempted to define virtual relation with no attrs");
- }
-
- /*
- * now create the parametesr for keys/inheritance etc.
- * All of them are nil...
- */
- createStmt.relname = relname;
- createStmt.tableElts = attrList;
-/* createStmt.tableType = NULL;*/
- createStmt.inhRelnames = NIL;
- createStmt.archiveType = ARCH_NONE;
- createStmt.location = -1;
- createStmt.archiveLoc = -1;
- createStmt.constraints = NIL;
-
- /*
- * finally create the relation...
- */
- DefineRelation(&createStmt);
-}
+ else
+ {
+ elog(WARN, "attempted to define virtual relation with no attrs");
+ }
+
+ /*
+ * now create the parametesr for keys/inheritance etc. All of them are
+ * nil...
+ */
+ createStmt.relname = relname;
+ createStmt.tableElts = attrList;
+/* createStmt.tableType = NULL;*/
+ createStmt.inhRelnames = NIL;
+ createStmt.archiveType = ARCH_NONE;
+ createStmt.location = -1;
+ createStmt.archiveLoc = -1;
+ createStmt.constraints = NIL;
+
+ /*
+ * finally create the relation...
+ */
+ DefineRelation(&createStmt);
+}
/*------------------------------------------------------------------
* makeViewRetrieveRuleName
@@ -118,84 +123,87 @@ DefineVirtualRelation(char *relname, List *tlist)
* XXX it also means viewName cannot be 16 chars long! - ay 11/94
*------------------------------------------------------------------
*/
-char *
+char *
MakeRetrieveViewRuleName(char *viewName)
{
/*
- char buf[100];
+ char buf[100];
- memset(buf, 0, sizeof(buf));
- sprintf(buf, "_RET%.*s", NAMEDATALEN, viewName->data);
- buf[15] = '\0';
- namestrcpy(rule_name, buf);
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, "_RET%.*s", NAMEDATALEN, viewName->data);
+ buf[15] = '\0';
+ namestrcpy(rule_name, buf);
*/
- char *buf;
- buf = palloc(strlen(viewName) + 5);
- sprintf(buf, "_RET%s",viewName);
- return buf;
+ char *buf;
+
+ buf = palloc(strlen(viewName) + 5);
+ sprintf(buf, "_RET%s", viewName);
+ return buf;
}
static RuleStmt *
-FormViewRetrieveRule(char *viewName, Query *viewParse)
+FormViewRetrieveRule(char *viewName, Query * viewParse)
{
- RuleStmt *rule;
- char *rname;
- Attr *attr;
-
- /*
- * Create a RuleStmt that corresponds to the suitable
- * rewrite rule args for DefineQueryRewrite();
- */
- rule = makeNode(RuleStmt);
- rname = MakeRetrieveViewRuleName(viewName);
-
- attr = makeNode(Attr);
- attr->relname = pstrdup(viewName);
-/* attr->refname = pstrdup(viewName);*/
- rule->rulename = pstrdup(rname);
- rule->whereClause = NULL;
- rule->event = CMD_SELECT;
- rule->object = attr;
- rule->instead = true;
- rule->actions = lcons(viewParse, NIL);
-
- return rule;
+ RuleStmt *rule;
+ char *rname;
+ Attr *attr;
+
+ /*
+ * Create a RuleStmt that corresponds to the suitable rewrite rule
+ * args for DefineQueryRewrite();
+ */
+ rule = makeNode(RuleStmt);
+ rname = MakeRetrieveViewRuleName(viewName);
+
+ attr = makeNode(Attr);
+ attr->relname = pstrdup(viewName);
+/* attr->refname = pstrdup(viewName);*/
+ rule->rulename = pstrdup(rname);
+ rule->whereClause = NULL;
+ rule->event = CMD_SELECT;
+ rule->object = attr;
+ rule->instead = true;
+ rule->actions = lcons(viewParse, NIL);
+
+ return rule;
}
static void
-DefineViewRules(char *viewName, Query *viewParse)
+DefineViewRules(char *viewName, Query * viewParse)
{
- RuleStmt *retrieve_rule = NULL;
+ RuleStmt *retrieve_rule = NULL;
+
#ifdef NOTYET
- RuleStmt *replace_rule = NULL;
- RuleStmt *append_rule = NULL;
- RuleStmt *delete_rule = NULL;
+ RuleStmt *replace_rule = NULL;
+ RuleStmt *append_rule = NULL;
+ RuleStmt *delete_rule = NULL;
+
#endif
-
- retrieve_rule =
- FormViewRetrieveRule(viewName, viewParse);
-
+
+ retrieve_rule =
+ FormViewRetrieveRule(viewName, viewParse);
+
#ifdef NOTYET
-
- replace_rule =
- FormViewReplaceRule(viewName, viewParse);
- append_rule =
- FormViewAppendRule(viewName, viewParse);
- delete_rule =
- FormViewDeleteRule(viewName, viewParse);
-
+
+ replace_rule =
+ FormViewReplaceRule(viewName, viewParse);
+ append_rule =
+ FormViewAppendRule(viewName, viewParse);
+ delete_rule =
+ FormViewDeleteRule(viewName, viewParse);
+
#endif
-
- DefineQueryRewrite(retrieve_rule);
+
+ DefineQueryRewrite(retrieve_rule);
#ifdef NOTYET
- DefineQueryRewrite(replace_rule);
- DefineQueryRewrite(append_rule);
- DefineQueryRewrite(delete_rule);
+ DefineQueryRewrite(replace_rule);
+ DefineQueryRewrite(append_rule);
+ DefineQueryRewrite(delete_rule);
#endif
-
-}
+
+}
/*---------------------------------------------------------------
* UpdateRangeTableOfViewParse
@@ -216,88 +224,84 @@ DefineViewRules(char *viewName, Query *viewParse)
*---------------------------------------------------------------
*/
static void
-UpdateRangeTableOfViewParse(char *viewName, Query *viewParse)
+UpdateRangeTableOfViewParse(char *viewName, Query * viewParse)
{
- List *old_rt;
- List *new_rt;
- RangeTblEntry *rt_entry1, *rt_entry2;
-
- /*
- * first offset all var nodes by 2
- */
- OffsetVarNodes((Node*)viewParse->targetList, 2);
- OffsetVarNodes(viewParse->qual, 2);
-
- /*
- * find the old range table...
- */
- old_rt = viewParse->rtable;
-
- /*
- * create the 2 new range table entries and form the new
- * range table...
- * CURRENT first, then NEW....
- */
- rt_entry1 =
- addRangeTableEntry(NULL, (char*)viewName, "*CURRENT*",
- FALSE, FALSE, NULL);
- rt_entry2 =
- addRangeTableEntry(NULL, (char*)viewName, "*NEW*",
- FALSE, FALSE, NULL);
- new_rt = lcons(rt_entry2, old_rt);
- new_rt = lcons(rt_entry1, new_rt);
-
- /*
- * Now the tricky part....
- * Update the range table in place... Be careful here, or
- * hell breaks loooooooooooooOOOOOOOOOOOOOOOOOOSE!
- */
- viewParse->rtable = new_rt;
+ List *old_rt;
+ List *new_rt;
+ RangeTblEntry *rt_entry1,
+ *rt_entry2;
+
+ /*
+ * first offset all var nodes by 2
+ */
+ OffsetVarNodes((Node *) viewParse->targetList, 2);
+ OffsetVarNodes(viewParse->qual, 2);
+
+ /*
+ * find the old range table...
+ */
+ old_rt = viewParse->rtable;
+
+ /*
+ * create the 2 new range table entries and form the new range
+ * table... CURRENT first, then NEW....
+ */
+ rt_entry1 =
+ addRangeTableEntry(NULL, (char *) viewName, "*CURRENT*",
+ FALSE, FALSE, NULL);
+ rt_entry2 =
+ addRangeTableEntry(NULL, (char *) viewName, "*NEW*",
+ FALSE, FALSE, NULL);
+ new_rt = lcons(rt_entry2, old_rt);
+ new_rt = lcons(rt_entry1, new_rt);
+
+ /*
+ * Now the tricky part.... Update the range table in place... Be
+ * careful here, or hell breaks loooooooooooooOOOOOOOOOOOOOOOOOOSE!
+ */
+ viewParse->rtable = new_rt;
}
/*-------------------------------------------------------------------
* DefineView
*
- * - takes a "viewname", "parsetree" pair and then
- * 1) construct the "virtual" relation
- * 2) commit the command but NOT the transaction,
- * so that the relation exists
- * before the rules are defined.
- * 2) define the "n" rules specified in the PRS2 paper
- * over the "virtual" relation
+ * - takes a "viewname", "parsetree" pair and then
+ * 1) construct the "virtual" relation
+ * 2) commit the command but NOT the transaction,
+ * so that the relation exists
+ * before the rules are defined.
+ * 2) define the "n" rules specified in the PRS2 paper
+ * over the "virtual" relation
*-------------------------------------------------------------------
*/
void
-DefineView(char *viewName, Query *viewParse)
+DefineView(char *viewName, Query * viewParse)
{
- List *viewTlist;
-
- viewTlist = viewParse->targetList;
-
- /*
- * Create the "view" relation
- * NOTE: if it already exists, the xaxt will be aborted.
- */
- DefineVirtualRelation(viewName, viewTlist);
-
- /*
- * The relation we have just created is not visible
- * to any other commands running with the same transaction &
- * command id.
- * So, increment the command id counter (but do NOT pfree any
- * memory!!!!)
- */
- CommandCounterIncrement();
-
- /*
- * The range table of 'viewParse' does not contain entries
- * for the "CURRENT" and "NEW" relations.
- * So... add them!
- * NOTE: we make the update in place! After this call 'viewParse'
- * will never be what it used to be...
- */
- UpdateRangeTableOfViewParse(viewName, viewParse);
- DefineViewRules(viewName, viewParse);
+ List *viewTlist;
+
+ viewTlist = viewParse->targetList;
+
+ /*
+ * Create the "view" relation NOTE: if it already exists, the xaxt
+ * will be aborted.
+ */
+ DefineVirtualRelation(viewName, viewTlist);
+
+ /*
+ * The relation we have just created is not visible to any other
+ * commands running with the same transaction & command id. So,
+ * increment the command id counter (but do NOT pfree any memory!!!!)
+ */
+ CommandCounterIncrement();
+
+ /*
+ * The range table of 'viewParse' does not contain entries for the
+ * "CURRENT" and "NEW" relations. So... add them! NOTE: we make the
+ * update in place! After this call 'viewParse' will never be what it
+ * used to be...
+ */
+ UpdateRangeTableOfViewParse(viewName, viewParse);
+ DefineViewRules(viewName, viewParse);
}
/*------------------------------------------------------------------
@@ -309,23 +313,22 @@ DefineView(char *viewName, Query *viewParse)
void
RemoveView(char *viewName)
{
- char* rname;
-
- /*
- * first remove all the "view" rules...
- * Currently we only have one!
- */
- rname = MakeRetrieveViewRuleName(viewName);
- RemoveRewriteRule(rname);
-
- /*
- * we don't really need that, but just in case...
- */
- CommandCounterIncrement();
-
- /*
- * now remove the relation.
- */
- heap_destroy(viewName);
- pfree(rname);
+ char *rname;
+
+ /*
+ * first remove all the "view" rules... Currently we only have one!
+ */
+ rname = MakeRetrieveViewRuleName(viewName);
+ RemoveRewriteRule(rname);
+
+ /*
+ * we don't really need that, but just in case...
+ */
+ CommandCounterIncrement();
+
+ /*
+ * now remove the relation.
+ */
+ heap_destroy(viewName);
+ pfree(rname);
}
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c
index 84b33d4f1e1..401924485e0 100644
--- a/src/backend/executor/execAmi.c
+++ b/src/backend/executor/execAmi.c
@@ -1,32 +1,32 @@
/*-------------------------------------------------------------------------
*
* execAmi.c--
- * miscellanious executor access method routines
+ * miscellanious executor access method routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.5 1997/08/19 21:30:51 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.6 1997/09/07 04:41:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * INTERFACE ROUTINES
+ * INTERFACE ROUTINES
*
- * ExecOpenScanR \ / amopen
- * ExecBeginScan \ / ambeginscan
- * ExecCloseR \ / amclose
- * ExecInsert \ executor interface / aminsert
- * ExecReScanNode / to access methods \ amrescan
- * ExecReScanR / \ amrescan
- * ExecMarkPos / \ ammarkpos
- * ExecRestrPos / \ amrestpos
+ * ExecOpenScanR \ / amopen
+ * ExecBeginScan \ / ambeginscan
+ * ExecCloseR \ / amclose
+ * ExecInsert \ executor interface / aminsert
+ * ExecReScanNode / to access methods \ amrescan
+ * ExecReScanR / \ amrescan
+ * ExecMarkPos / \ ammarkpos
+ * ExecRestrPos / \ amrestpos
*
- * ExecCreatR function to create temporary relations
+ * ExecCreatR function to create temporary relations
*
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include "postgres.h"
@@ -43,409 +43,430 @@
#include "access/heapam.h"
#include "catalog/heap.h"
-static Pointer ExecBeginScan(Relation relation, int nkeys, ScanKey skeys,
- bool isindex, ScanDirection dir, TimeQual time_range);
+static Pointer
+ExecBeginScan(Relation relation, int nkeys, ScanKey skeys,
+ bool isindex, ScanDirection dir, TimeQual time_range);
static Relation ExecOpenR(Oid relationOid, bool isindex);
/* ----------------------------------------------------------------
- * ExecOpenScanR
+ * ExecOpenScanR
*
* old comments:
- * Parameters:
- * relation -- relation to be opened and scanned.
- * nkeys -- number of keys
- * skeys -- keys to restrict scanning
- * isindex -- if this is true, the relation is the relid of
- * an index relation, else it is an index into the
- * range table.
- * Returns the relation as(relDesc scanDesc)
- * If this structure is changed, need to modify the access macros
- * defined in execInt.h.
+ * Parameters:
+ * relation -- relation to be opened and scanned.
+ * nkeys -- number of keys
+ * skeys -- keys to restrict scanning
+ * isindex -- if this is true, the relation is the relid of
+ * an index relation, else it is an index into the
+ * range table.
+ * Returns the relation as(relDesc scanDesc)
+ * If this structure is changed, need to modify the access macros
+ * defined in execInt.h.
* ----------------------------------------------------------------
*/
void
ExecOpenScanR(Oid relOid,
- int nkeys,
- ScanKey skeys,
- bool isindex,
- ScanDirection dir,
- TimeQual timeRange,
- Relation *returnRelation, /* return */
- Pointer *returnScanDesc) /* return */
+ int nkeys,
+ ScanKey skeys,
+ bool isindex,
+ ScanDirection dir,
+ TimeQual timeRange,
+ Relation * returnRelation, /* return */
+ Pointer * returnScanDesc) /* return */
{
- Relation relation;
- Pointer scanDesc;
-
- /* ----------------
- * note: scanDesc returned by ExecBeginScan can be either
- * a HeapScanDesc or an IndexScanDesc so for now we
- * make it a Pointer. There should be a better scan
- * abstraction someday -cim 9/9/89
- * ----------------
- */
- relation = ExecOpenR(relOid, isindex);
- scanDesc = ExecBeginScan(relation,
- nkeys,
- skeys,
- isindex,
- dir,
- timeRange);
-
- if (returnRelation != NULL)
- *returnRelation = relation;
- if (scanDesc != NULL)
- *returnScanDesc = scanDesc;
+ Relation relation;
+ Pointer scanDesc;
+
+ /* ----------------
+ * note: scanDesc returned by ExecBeginScan can be either
+ * a HeapScanDesc or an IndexScanDesc so for now we
+ * make it a Pointer. There should be a better scan
+ * abstraction someday -cim 9/9/89
+ * ----------------
+ */
+ relation = ExecOpenR(relOid, isindex);
+ scanDesc = ExecBeginScan(relation,
+ nkeys,
+ skeys,
+ isindex,
+ dir,
+ timeRange);
+
+ if (returnRelation != NULL)
+ *returnRelation = relation;
+ if (scanDesc != NULL)
+ *returnScanDesc = scanDesc;
}
-
+
/* ----------------------------------------------------------------
- * ExecOpenR
+ * ExecOpenR
*
- * returns a relation descriptor given an object id.
+ * returns a relation descriptor given an object id.
* ----------------------------------------------------------------
*/
-static Relation
+static Relation
ExecOpenR(Oid relationOid, bool isindex)
{
- Relation relation;
- relation = (Relation) NULL;
-
- /* ----------------
- * open the relation with the correct call depending
- * on whether this is a heap relation or an index relation.
- * ----------------
- */
- if (isindex) {
- relation = index_open(relationOid);
- } else
- relation = heap_open(relationOid);
-
- if (relation == NULL)
- elog(DEBUG, "ExecOpenR: relation == NULL, heap_open failed.");
-
- return relation;
+ Relation relation;
+
+ relation = (Relation) NULL;
+
+ /* ----------------
+ * open the relation with the correct call depending
+ * on whether this is a heap relation or an index relation.
+ * ----------------
+ */
+ if (isindex)
+ {
+ relation = index_open(relationOid);
+ }
+ else
+ relation = heap_open(relationOid);
+
+ if (relation == NULL)
+ elog(DEBUG, "ExecOpenR: relation == NULL, heap_open failed.");
+
+ return relation;
}
-
+
/* ----------------------------------------------------------------
- * ExecBeginScan
+ * ExecBeginScan
*
- * beginscans a relation in current direction.
+ * beginscans a relation in current direction.
*
- * XXX fix parameters to AMbeginscan (and btbeginscan)
- * currently we need to pass a flag stating whether
- * or not the scan should begin at an endpoint of
- * the relation.. Right now we always pass false
- * -cim 9/14/89
+ * XXX fix parameters to AMbeginscan (and btbeginscan)
+ * currently we need to pass a flag stating whether
+ * or not the scan should begin at an endpoint of
+ * the relation.. Right now we always pass false
+ * -cim 9/14/89
* ----------------------------------------------------------------
*/
-static Pointer
+static Pointer
ExecBeginScan(Relation relation,
- int nkeys,
- ScanKey skeys,
- bool isindex,
- ScanDirection dir,
- TimeQual time_range)
+ int nkeys,
+ ScanKey skeys,
+ bool isindex,
+ ScanDirection dir,
+ TimeQual time_range)
{
- Pointer scanDesc;
-
- scanDesc = NULL;
-
- /* ----------------
- * open the appropriate type of scan.
- *
- * Note: ambeginscan()'s second arg is a boolean indicating
- * that the scan should be done in reverse.. That is,
- * if you pass it true, then the scan is backward.
- * ----------------
- */
- if (isindex) {
- scanDesc = (Pointer) index_beginscan(relation,
- false, /* see above comment */
- nkeys,
- skeys);
- } else {
- scanDesc = (Pointer) heap_beginscan(relation,
- ScanDirectionIsBackward(dir),
- time_range,
- nkeys,
- skeys);
- }
-
- if (scanDesc == NULL)
- elog(DEBUG, "ExecBeginScan: scanDesc = NULL, heap_beginscan failed.");
-
-
- return scanDesc;
+ Pointer scanDesc;
+
+ scanDesc = NULL;
+
+ /* ----------------
+ * open the appropriate type of scan.
+ *
+ * Note: ambeginscan()'s second arg is a boolean indicating
+ * that the scan should be done in reverse.. That is,
+ * if you pass it true, then the scan is backward.
+ * ----------------
+ */
+ if (isindex)
+ {
+ scanDesc = (Pointer) index_beginscan(relation,
+ false, /* see above comment */
+ nkeys,
+ skeys);
+ }
+ else
+ {
+ scanDesc = (Pointer) heap_beginscan(relation,
+ ScanDirectionIsBackward(dir),
+ time_range,
+ nkeys,
+ skeys);
+ }
+
+ if (scanDesc == NULL)
+ elog(DEBUG, "ExecBeginScan: scanDesc = NULL, heap_beginscan failed.");
+
+
+ return scanDesc;
}
-
+
/* ----------------------------------------------------------------
- * ExecCloseR
+ * ExecCloseR
*
- * closes the relation and scan descriptor for a scan or sort
- * node. Also closes index relations and scans for index scans.
+ * closes the relation and scan descriptor for a scan or sort
+ * node. Also closes index relations and scans for index scans.
*
* old comments
- * closes the relation indicated in 'relID'
+ * closes the relation indicated in 'relID'
* ----------------------------------------------------------------
*/
void
-ExecCloseR(Plan *node)
+ExecCloseR(Plan * node)
{
- CommonScanState *state;
- Relation relation;
- HeapScanDesc scanDesc;
-
- /* ----------------
- * shut down the heap scan and close the heap relation
- * ----------------
- */
- switch (nodeTag(node)) {
-
- case T_SeqScan:
- state = ((SeqScan *)node)->scanstate;
- break;
-
- case T_IndexScan:
- state = ((IndexScan *)node)->scan.scanstate;
- break;
-
- case T_Material:
- state = &(((Material *)node)->matstate->csstate);
- break;
-
- case T_Sort:
- state = &(((Sort *)node)->sortstate->csstate);
- break;
-
- case T_Agg:
- state = &(((Agg *)node)->aggstate->csstate);
- break;
-
- default:
- elog(DEBUG, "ExecCloseR: not a scan, material, or sort node!");
- return;
- }
-
- relation = state->css_currentRelation;
- scanDesc = state->css_currentScanDesc;
-
- if (scanDesc != NULL)
- heap_endscan(scanDesc);
-
- if (relation != NULL)
- heap_close(relation);
-
- /* ----------------
- * if this is an index scan then we have to take care
- * of the index relations as well..
- * ----------------
- */
- if (nodeTag(node) == T_IndexScan) {
- IndexScan *iscan= (IndexScan *)node;
- IndexScanState *indexstate;
- int numIndices;
- RelationPtr indexRelationDescs;
- IndexScanDescPtr indexScanDescs;
- int i;
-
- indexstate = iscan->indxstate;
- numIndices = indexstate->iss_NumIndices;
- indexRelationDescs = indexstate->iss_RelationDescs;
- indexScanDescs = indexstate->iss_ScanDescs;
-
- for (i = 0; i<numIndices; i++) {
- /* ----------------
- * shut down each of the scans and
- * close each of the index relations
- * ----------------
- */
- if (indexScanDescs[i] != NULL)
- index_endscan(indexScanDescs[i]);
-
- if (indexRelationDescs[i] != NULL)
- index_close(indexRelationDescs[i]);
+ CommonScanState *state;
+ Relation relation;
+ HeapScanDesc scanDesc;
+
+ /* ----------------
+ * shut down the heap scan and close the heap relation
+ * ----------------
+ */
+ switch (nodeTag(node))
+ {
+
+ case T_SeqScan:
+ state = ((SeqScan *) node)->scanstate;
+ break;
+
+ case T_IndexScan:
+ state = ((IndexScan *) node)->scan.scanstate;
+ break;
+
+ case T_Material:
+ state = &(((Material *) node)->matstate->csstate);
+ break;
+
+ case T_Sort:
+ state = &(((Sort *) node)->sortstate->csstate);
+ break;
+
+ case T_Agg:
+ state = &(((Agg *) node)->aggstate->csstate);
+ break;
+
+ default:
+ elog(DEBUG, "ExecCloseR: not a scan, material, or sort node!");
+ return;
+ }
+
+ relation = state->css_currentRelation;
+ scanDesc = state->css_currentScanDesc;
+
+ if (scanDesc != NULL)
+ heap_endscan(scanDesc);
+
+ if (relation != NULL)
+ heap_close(relation);
+
+ /* ----------------
+ * if this is an index scan then we have to take care
+ * of the index relations as well..
+ * ----------------
+ */
+ if (nodeTag(node) == T_IndexScan)
+ {
+ IndexScan *iscan = (IndexScan *) node;
+ IndexScanState *indexstate;
+ int numIndices;
+ RelationPtr indexRelationDescs;
+ IndexScanDescPtr indexScanDescs;
+ int i;
+
+ indexstate = iscan->indxstate;
+ numIndices = indexstate->iss_NumIndices;
+ indexRelationDescs = indexstate->iss_RelationDescs;
+ indexScanDescs = indexstate->iss_ScanDescs;
+
+ for (i = 0; i < numIndices; i++)
+ {
+ /* ----------------
+ * shut down each of the scans and
+ * close each of the index relations
+ * ----------------
+ */
+ if (indexScanDescs[i] != NULL)
+ index_endscan(indexScanDescs[i]);
+
+ if (indexRelationDescs[i] != NULL)
+ index_close(indexRelationDescs[i]);
+ }
}
- }
}
-
+
/* ----------------------------------------------------------------
- * ExecReScan
+ * ExecReScan
*
- * XXX this should be extended to cope with all the node types..
+ * XXX this should be extended to cope with all the node types..
*
- * takes the new expression context as an argument, so that
- * index scans needn't have their scan keys updated separately
- * - marcel 09/20/94
+ * takes the new expression context as an argument, so that
+ * index scans needn't have their scan keys updated separately
+ * - marcel 09/20/94
* ----------------------------------------------------------------
*/
void
-ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
+ExecReScan(Plan * node, ExprContext * exprCtxt, Plan * parent)
{
- switch(nodeTag(node)) {
- case T_SeqScan:
- ExecSeqReScan((SeqScan *) node, exprCtxt, parent);
- return;
-
- case T_IndexScan:
- ExecIndexReScan((IndexScan *) node, exprCtxt, parent);
- return;
+ switch (nodeTag(node))
+ {
+ case T_SeqScan:
+ ExecSeqReScan((SeqScan *) node, exprCtxt, parent);
+ return;
- case T_Material:
- /* the first call to ExecReScan should have no effect because
- * everything is initialized properly already. the following
- * calls will be handled by ExecSeqReScan() because the nodes
- * below the Material node have already been materialized into
- * a temp relation.
- */
- return;
+ case T_IndexScan:
+ ExecIndexReScan((IndexScan *) node, exprCtxt, parent);
+ return;
- case T_Tee:
- ExecTeeReScan((Tee*) node, exprCtxt, parent);
- break;
+ case T_Material:
- default:
- elog(WARN, "ExecReScan: not a seqscan or indexscan node.");
- return;
- }
+ /*
+ * the first call to ExecReScan should have no effect because
+ * everything is initialized properly already. the following
+ * calls will be handled by ExecSeqReScan() because the nodes
+ * below the Material node have already been materialized into a
+ * temp relation.
+ */
+ return;
+
+ case T_Tee:
+ ExecTeeReScan((Tee *) node, exprCtxt, parent);
+ break;
+
+ default:
+ elog(WARN, "ExecReScan: not a seqscan or indexscan node.");
+ return;
+ }
}
-
+
/* ----------------------------------------------------------------
- * ExecReScanR
+ * ExecReScanR
*
- * XXX this does not do the right thing with indices yet.
+ * XXX this does not do the right thing with indices yet.
* ----------------------------------------------------------------
*/
HeapScanDesc
-ExecReScanR(Relation relDesc, /* LLL relDesc unused */
- HeapScanDesc scanDesc,
- ScanDirection direction,
- int nkeys, /* LLL nkeys unused */
- ScanKey skeys)
+ExecReScanR(Relation relDesc, /* LLL relDesc unused */
+ HeapScanDesc scanDesc,
+ ScanDirection direction,
+ int nkeys, /* LLL nkeys unused */
+ ScanKey skeys)
{
- if (scanDesc != NULL)
- heap_rescan(scanDesc, /* scan desc */
- ScanDirectionIsBackward(direction), /* backward flag */
- skeys); /* scan keys */
-
- return scanDesc;
+ if (scanDesc != NULL)
+ heap_rescan(scanDesc, /* scan desc */
+ ScanDirectionIsBackward(direction), /* backward flag */
+ skeys); /* scan keys */
+
+ return scanDesc;
}
-
+
/* ----------------------------------------------------------------
- * ExecMarkPos
+ * ExecMarkPos
*
- * Marks the current scan position.
+ * Marks the current scan position.
*
- * XXX Needs to be extended to include all the node types.
+ * XXX Needs to be extended to include all the node types.
* ----------------------------------------------------------------
*/
void
-ExecMarkPos(Plan *node)
+ExecMarkPos(Plan * node)
{
- switch(nodeTag(node)) {
- case T_SeqScan:
- ExecSeqMarkPos((SeqScan *) node);
- break;
-
- case T_IndexScan:
- ExecIndexMarkPos((IndexScan *) node);
- break;
-
- case T_Sort:
- ExecSortMarkPos((Sort *) node);
- break;
-
- default:
- /* elog(DEBUG, "ExecMarkPos: unsupported node type"); */
- break;
- }
- return;
+ switch (nodeTag(node))
+ {
+ case T_SeqScan:
+ ExecSeqMarkPos((SeqScan *) node);
+ break;
+
+ case T_IndexScan:
+ ExecIndexMarkPos((IndexScan *) node);
+ break;
+
+ case T_Sort:
+ ExecSortMarkPos((Sort *) node);
+ break;
+
+ default:
+ /* elog(DEBUG, "ExecMarkPos: unsupported node type"); */
+ break;
+ }
+ return;
}
-
+
/* ----------------------------------------------------------------
- * ExecRestrPos
+ * ExecRestrPos
*
- * restores the scan position previously saved with ExecMarkPos()
+ * restores the scan position previously saved with ExecMarkPos()
* ----------------------------------------------------------------
*/
void
-ExecRestrPos(Plan *node)
+ExecRestrPos(Plan * node)
{
- switch(nodeTag(node)) {
- case T_SeqScan:
- ExecSeqRestrPos((SeqScan *) node);
- return;
-
- case T_IndexScan:
- ExecIndexRestrPos((IndexScan *) node);
- return;
-
- case T_Sort:
- ExecSortRestrPos((Sort *) node);
- return;
+ switch (nodeTag(node))
+ {
+ case T_SeqScan:
+ ExecSeqRestrPos((SeqScan *) node);
+ return;
- default:
- /* elog(DEBUG, "ExecRestrPos: node type not supported"); */
- return;
- }
+ case T_IndexScan:
+ ExecIndexRestrPos((IndexScan *) node);
+ return;
+
+ case T_Sort:
+ ExecSortRestrPos((Sort *) node);
+ return;
+
+ default:
+ /* elog(DEBUG, "ExecRestrPos: node type not supported"); */
+ return;
+ }
}
-
+
/* ----------------------------------------------------------------
- * ExecCreatR
+ * ExecCreatR
*
* old comments
- * Creates a relation.
+ * Creates a relation.
*
- * Parameters:
- * attrType -- type information on the attributes.
- * accessMtd -- access methods used to access the created relation.
- * relation -- optional. Either an index to the range table or
- * negative number indicating a temporary relation.
- * A temporary relation is assume is this field is absent.
+ * Parameters:
+ * attrType -- type information on the attributes.
+ * accessMtd -- access methods used to access the created relation.
+ * relation -- optional. Either an index to the range table or
+ * negative number indicating a temporary relation.
+ * A temporary relation is assume is this field is absent.
* ----------------------------------------------------------------
*/
Relation
ExecCreatR(TupleDesc tupType,
- Oid relationOid)
+ Oid relationOid)
{
- Relation relDesc;
-
- EU3_printf("ExecCreatR: %s type=%d oid=%d\n",
- "entering: ", tupType, relationOid);
- CXT1_printf("ExecCreatR: context is %d\n", CurrentMemoryContext);
-
- relDesc = NULL;
-
- if (relationOid == _TEMP_RELATION_ID_ ) {
- /* ----------------
- * create a temporary relation
- * (currently the planner always puts a _TEMP_RELATION_ID
- * in the relation argument so we expect this to be the case although
- * it's possible that someday we'll get the name from
- * from the range table.. -cim 10/12/89)
- * ----------------
- */
+ Relation relDesc;
+
+ EU3_printf("ExecCreatR: %s type=%d oid=%d\n",
+ "entering: ", tupType, relationOid);
+ CXT1_printf("ExecCreatR: context is %d\n", CurrentMemoryContext);
+
+ relDesc = NULL;
+
+ if (relationOid == _TEMP_RELATION_ID_)
+ {
+ /* ----------------
+ * create a temporary relation
+ * (currently the planner always puts a _TEMP_RELATION_ID
+ * in the relation argument so we expect this to be the case although
+ * it's possible that someday we'll get the name from
+ * from the range table.. -cim 10/12/89)
+ * ----------------
+ */
/*
- sprintf(tempname, "temp_%d.%d", getpid(), tmpcnt++);
- EU1_printf("ExecCreatR: attempting to create %s\n", tempname);
+ sprintf(tempname, "temp_%d.%d", getpid(), tmpcnt++);
+ EU1_printf("ExecCreatR: attempting to create %s\n", tempname);
*/
- /* heap_creatr creates a name if the argument to heap_creatr is '\0 ' */
- relDesc = heap_creatr("",
- DEFAULT_SMGR,
- tupType);
- } else {
- /* ----------------
- * use a relation from the range table
- * ----------------
- */
- elog(DEBUG, "ExecCreatR: %s",
- "stuff using range table id's is not functional");
- }
-
- if (relDesc == NULL)
- elog(DEBUG, "ExecCreatR: failed to create relation.");
-
- EU1_printf("ExecCreatR: returning relDesc=%d\n", relDesc);
-
- return relDesc;
+
+ /*
+ * heap_creatr creates a name if the argument to heap_creatr is
+ * '\0 '
+ */
+ relDesc = heap_creatr("",
+ DEFAULT_SMGR,
+ tupType);
+ }
+ else
+ {
+ /* ----------------
+ * use a relation from the range table
+ * ----------------
+ */
+ elog(DEBUG, "ExecCreatR: %s",
+ "stuff using range table id's is not functional");
+ }
+
+ if (relDesc == NULL)
+ elog(DEBUG, "ExecCreatR: failed to create relation.");
+
+ EU1_printf("ExecCreatR: returning relDesc=%d\n", relDesc);
+
+ return relDesc;
}
-
diff --git a/src/backend/executor/execFlatten.c b/src/backend/executor/execFlatten.c
index c9bde2ff663..43d616712fa 100644
--- a/src/backend/executor/execFlatten.c
+++ b/src/backend/executor/execFlatten.c
@@ -1,29 +1,29 @@
/*-------------------------------------------------------------------------
*
* execFlatten.c--
- * This file handles the nodes associated with flattening sets in the
- * target list of queries containing functions returning sets.
+ * This file handles the nodes associated with flattening sets in the
+ * target list of queries containing functions returning sets.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/Attic/execFlatten.c,v 1.2 1997/08/19 21:30:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/Attic/execFlatten.c,v 1.3 1997/09/07 04:41:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* ExecEvalIter() -
- * Iterate through the all return tuples/base types from a function one
- * at time (i.e. one per ExecEvalIter call). Not really needed for
- * postquel functions, but for reasons of orthogonality, these nodes
- * exist above pq functions as well as c functions.
+ * Iterate through the all return tuples/base types from a function one
+ * at time (i.e. one per ExecEvalIter call). Not really needed for
+ * postquel functions, but for reasons of orthogonality, these nodes
+ * exist above pq functions as well as c functions.
*
* ExecEvalFjoin() -
- * Given N Iter nodes return a vector of all combinations of results
- * one at a time (i.e. one result vector per ExecEvalFjoin call). This
- * node does the actual flattening work.
+ * Given N Iter nodes return a vector of all combinations of results
+ * one at a time (i.e. one result vector per ExecEvalFjoin call). This
+ * node does the actual flattening work.
*/
#include "postgres.h"
#include "nodes/primnodes.h"
@@ -33,208 +33,216 @@
#include "executor/execFlatten.h"
#ifdef SETS_FIXED
-static bool FjoinBumpOuterNodes(TargetEntry *tlist, ExprContext *econtext,
- DatumPtr results, char *nulls);
+static bool
+FjoinBumpOuterNodes(TargetEntry * tlist, ExprContext * econtext,
+ DatumPtr results, char *nulls);
+
#endif
Datum
-ExecEvalIter(Iter *iterNode,
- ExprContext *econtext,
- bool *resultIsNull,
- bool *iterIsDone)
+ExecEvalIter(Iter * iterNode,
+ ExprContext * econtext,
+ bool * resultIsNull,
+ bool * iterIsDone)
{
- Node *expression;
-
- expression = iterNode->iterexpr;
-
- /*
- * Really Iter nodes are only needed for C functions, postquel function
- * by their nature return 1 result at a time. For now we are only worrying
- * about postquel functions, c functions will come later.
- */
- return ExecEvalExpr(expression, econtext, resultIsNull, iterIsDone);
+ Node *expression;
+
+ expression = iterNode->iterexpr;
+
+ /*
+ * Really Iter nodes are only needed for C functions, postquel
+ * function by their nature return 1 result at a time. For now we are
+ * only worrying about postquel functions, c functions will come
+ * later.
+ */
+ return ExecEvalExpr(expression, econtext, resultIsNull, iterIsDone);
}
void
-ExecEvalFjoin(TargetEntry *tlist,
- ExprContext *econtext,
- bool *isNullVect,
- bool *fj_isDone)
+ExecEvalFjoin(TargetEntry * tlist,
+ ExprContext * econtext,
+ bool * isNullVect,
+ bool * fj_isDone)
{
#ifdef SETS_FIXED
- bool isDone;
- int curNode;
- List *tlistP;
-
- Fjoin *fjNode = tlist->fjoin;
- DatumPtr resVect = fjNode->fj_results;
- BoolPtr alwaysDone = fjNode->fj_alwaysDone;
-
- if (fj_isDone) *fj_isDone = false;
- /*
- * For the next tuple produced by the plan, we need to re-initialize
- * the Fjoin node.
- */
- if (!fjNode->fj_initialized)
+ bool isDone;
+ int curNode;
+ List *tlistP;
+
+ Fjoin *fjNode = tlist->fjoin;
+ DatumPtr resVect = fjNode->fj_results;
+ BoolPtr alwaysDone = fjNode->fj_alwaysDone;
+
+ if (fj_isDone)
+ *fj_isDone = false;
+
+ /*
+ * For the next tuple produced by the plan, we need to re-initialize
+ * the Fjoin node.
+ */
+ if (!fjNode->fj_initialized)
{
- /*
- * Initialize all of the Outer nodes
- */
- curNode = 1;
- foreach(tlistP, lnext(tlist))
+
+ /*
+ * Initialize all of the Outer nodes
+ */
+ curNode = 1;
+ foreach(tlistP, lnext(tlist))
{
- TargetEntry *tle = lfirst(tlistP);
-
- resVect[curNode] = ExecEvalIter((Iter*)tle->expr,
- econtext,
- &isNullVect[curNode],
- &isDone);
- if (isDone)
- isNullVect[curNode] = alwaysDone[curNode] = true;
- else
- alwaysDone[curNode] = false;
-
- curNode++;
+ TargetEntry *tle = lfirst(tlistP);
+
+ resVect[curNode] = ExecEvalIter((Iter *) tle->expr,
+ econtext,
+ &isNullVect[curNode],
+ &isDone);
+ if (isDone)
+ isNullVect[curNode] = alwaysDone[curNode] = true;
+ else
+ alwaysDone[curNode] = false;
+
+ curNode++;
}
-
- /*
- * Initialize the inner node
- */
- resVect[0] = ExecEvalIter((Iter*)fjNode->fj_innerNode->expr,
- econtext,
- &isNullVect[0],
- &isDone);
- if (isDone)
- isNullVect[0] = alwaysDone[0] = true;
- else
- alwaysDone[0] = false;
-
- /*
- * Mark the Fjoin as initialized now.
- */
- fjNode->fj_initialized = TRUE;
-
- /*
- * If the inner node is always done, then we are done for now
- */
- if (isDone)
- return;
+
+ /*
+ * Initialize the inner node
+ */
+ resVect[0] = ExecEvalIter((Iter *) fjNode->fj_innerNode->expr,
+ econtext,
+ &isNullVect[0],
+ &isDone);
+ if (isDone)
+ isNullVect[0] = alwaysDone[0] = true;
+ else
+ alwaysDone[0] = false;
+
+ /*
+ * Mark the Fjoin as initialized now.
+ */
+ fjNode->fj_initialized = TRUE;
+
+ /*
+ * If the inner node is always done, then we are done for now
+ */
+ if (isDone)
+ return;
}
- else
+ else
{
- /*
- * If we're already initialized, all we need to do is get the
- * next inner result and pair it up with the existing outer node
- * result vector. Watch out for the degenerate case, where the
- * inner node never returns results.
- */
-
- /*
- * Fill in nulls for every function that is always done.
- */
- for (curNode=fjNode->fj_nNodes-1; curNode >= 0; curNode--)
- isNullVect[curNode] = alwaysDone[curNode];
-
- if (alwaysDone[0] == true)
+
+ /*
+ * If we're already initialized, all we need to do is get the next
+ * inner result and pair it up with the existing outer node result
+ * vector. Watch out for the degenerate case, where the inner
+ * node never returns results.
+ */
+
+ /*
+ * Fill in nulls for every function that is always done.
+ */
+ for (curNode = fjNode->fj_nNodes - 1; curNode >= 0; curNode--)
+ isNullVect[curNode] = alwaysDone[curNode];
+
+ if (alwaysDone[0] == true)
{
- *fj_isDone = FjoinBumpOuterNodes(tlist,
- econtext,
- resVect,
- isNullVect);
- return;
+ *fj_isDone = FjoinBumpOuterNodes(tlist,
+ econtext,
+ resVect,
+ isNullVect);
+ return;
}
- else
- resVect[0] = ExecEvalIter((Iter*)fjNode->fj_innerNode->expr,
- econtext,
- &isNullVect[0],
- &isDone);
+ else
+ resVect[0] = ExecEvalIter((Iter *) fjNode->fj_innerNode->expr,
+ econtext,
+ &isNullVect[0],
+ &isDone);
}
-
- /*
- * if the inner node is done
- */
- if (isDone)
+
+ /*
+ * if the inner node is done
+ */
+ if (isDone)
{
- *fj_isDone = FjoinBumpOuterNodes(tlist,
- econtext,
- resVect,
- isNullVect);
- if (*fj_isDone)
- return;
-
- resVect[0] = ExecEvalIter((Iter*)fjNode->fj_innerNode->expr,
- econtext,
- &isNullVect[0],
- &isDone);
-
+ *fj_isDone = FjoinBumpOuterNodes(tlist,
+ econtext,
+ resVect,
+ isNullVect);
+ if (*fj_isDone)
+ return;
+
+ resVect[0] = ExecEvalIter((Iter *) fjNode->fj_innerNode->expr,
+ econtext,
+ &isNullVect[0],
+ &isDone);
+
}
#endif
- return;
+ return;
}
#ifdef SETS_FIXED
-static bool
-FjoinBumpOuterNodes(TargetEntry *tlist,
- ExprContext *econtext,
- DatumPtr results,
- char *nulls)
+static bool
+FjoinBumpOuterNodes(TargetEntry * tlist,
+ ExprContext * econtext,
+ DatumPtr results,
+ char *nulls)
{
- bool funcIsDone = true;
- Fjoin *fjNode = tlist->fjoin;
- char *alwaysDone = fjNode->fj_alwaysDone;
- List *outerList = lnext(tlist);
- List *trailers = lnext(tlist);
- int trailNode = 1;
- int curNode = 1;
-
- /*
- * Run through list of functions until we get to one that isn't yet
- * done returning values. Watch out for funcs that are always done.
- */
- while ((funcIsDone == true) && (outerList != NIL))
+ bool funcIsDone = true;
+ Fjoin *fjNode = tlist->fjoin;
+ char *alwaysDone = fjNode->fj_alwaysDone;
+ List *outerList = lnext(tlist);
+ List *trailers = lnext(tlist);
+ int trailNode = 1;
+ int curNode = 1;
+
+ /*
+ * Run through list of functions until we get to one that isn't yet
+ * done returning values. Watch out for funcs that are always done.
+ */
+ while ((funcIsDone == true) && (outerList != NIL))
{
- TargetEntry *tle = lfirst(outerList);
-
- if (alwaysDone[curNode] == true)
- nulls[curNode] = 'n';
- else
- results[curNode] = ExecEvalIter((Iter)tle->expr,
- econtext,
- &nulls[curNode],
- &funcIsDone);
- curNode++;
- outerList = lnext(outerList);
+ TargetEntry *tle = lfirst(outerList);
+
+ if (alwaysDone[curNode] == true)
+ nulls[curNode] = 'n';
+ else
+ results[curNode] = ExecEvalIter((Iter) tle->expr,
+ econtext,
+ &nulls[curNode],
+ &funcIsDone);
+ curNode++;
+ outerList = lnext(outerList);
}
-
- /*
- * If every function is done, then we are done flattening.
- * Mark the Fjoin node unitialized, it is time to get the
- * next tuple from the plan and redo all of the flattening.
- */
- if (funcIsDone)
+
+ /*
+ * If every function is done, then we are done flattening. Mark the
+ * Fjoin node unitialized, it is time to get the next tuple from the
+ * plan and redo all of the flattening.
+ */
+ if (funcIsDone)
{
- set_fj_initialized(fjNode, false);
- return (true);
+ set_fj_initialized(fjNode, false);
+ return (true);
}
-
- /*
- * We found a function that wasn't done. Now re-run every function
- * before it. As usual watch out for functions that are always done.
- */
- trailNode = 1;
- while (trailNode != curNode-1)
+
+ /*
+ * We found a function that wasn't done. Now re-run every function
+ * before it. As usual watch out for functions that are always done.
+ */
+ trailNode = 1;
+ while (trailNode != curNode - 1)
{
- TargetEntry *tle = lfirst(trailers);
-
- if (alwaysDone[trailNode] != true)
- results[trailNode] = ExecEvalIter((Iter)tle->expr,
- econtext,
- &nulls[trailNode],
- &funcIsDone);
- trailNode++;
- trailers = lnext(trailers);
+ TargetEntry *tle = lfirst(trailers);
+
+ if (alwaysDone[trailNode] != true)
+ results[trailNode] = ExecEvalIter((Iter) tle->expr,
+ econtext,
+ &nulls[trailNode],
+ &funcIsDone);
+ trailNode++;
+ trailers = lnext(trailers);
}
- return false;
+ return false;
}
+
#endif
diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c
index 8779647a113..3ad41bd393f 100644
--- a/src/backend/executor/execJunk.c
+++ b/src/backend/executor/execJunk.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* junk.c--
- * Junk attribute support stuff....
+ * Junk attribute support stuff....
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.5 1997/08/26 23:31:37 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.6 1997/09/07 04:41:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,37 +20,37 @@
#include "access/heapam.h"
#include "executor/executor.h"
#include "nodes/relation.h"
-#include "optimizer/tlist.h" /* for MakeTLE */
+#include "optimizer/tlist.h" /* for MakeTLE */
/*-------------------------------------------------------------------------
- * XXX this stuff should be rewritten to take advantage
- * of ExecProject() and the ProjectionInfo node.
- * -cim 6/3/91
- *
+ * XXX this stuff should be rewritten to take advantage
+ * of ExecProject() and the ProjectionInfo node.
+ * -cim 6/3/91
+ *
* An attribute of a tuple living inside the executor, can be
* either a normal attribute or a "junk" attribute. "junk" attributes
* never make it out of the executor, i.e. they are never printed,
* returned or stored in disk. Their only purpose in life is to
* store some information useful only to the executor, mainly the values
* of some system attributes like "ctid" or rule locks.
- *
+ *
* The general idea is the following: A target list consists of a list of
* Resdom nodes & expression pairs. Each Resdom node has an attribute
* called 'resjunk'. If the value of this attribute is 1 then the
* corresponding attribute is a "junk" attribute.
- *
+ *
* When we initialize a plan we call 'ExecInitJunkFilter' to create
* and store the appropriate information in the 'es_junkFilter' attribute of
* EState.
- *
+ *
* We then execute the plan ignoring the "resjunk" attributes.
- *
+ *
* Finally, when at the top level we get back a tuple, we can call
* 'ExecGetJunkAttribute' to retrieve the value of the junk attributes we
* are interested in, and 'ExecRemoveJunk' to remove all the junk attributes
* from a tuple. This new "clean" tuple is then printed, replaced, deleted
* or inserted.
- *
+ *
*-------------------------------------------------------------------------
*/
@@ -60,174 +60,196 @@
* Initialize the Junk filter.
*-------------------------------------------------------------------------
*/
-JunkFilter *
-ExecInitJunkFilter(List *targetList)
+JunkFilter *
+ExecInitJunkFilter(List * targetList)
{
- JunkFilter *junkfilter;
- List *cleanTargetList;
- int len, cleanLength;
- TupleDesc tupType, cleanTupType;
- List *t;
- TargetEntry *tle;
- Resdom *resdom, *cleanResdom;
- int resjunk;
- AttrNumber cleanResno;
- AttrNumber *cleanMap;
- Size size;
- Node *expr;
-
- /* ---------------------
- * First find the "clean" target list, i.e. all the entries
- * in the original target list which have a zero 'resjunk'
- * NOTE: make copy of the Resdom nodes, because we have
- * to change the 'resno's...
- * ---------------------
- */
- cleanTargetList = NIL;
- cleanResno = 1;
-
- foreach (t, targetList) {
- TargetEntry *rtarget = lfirst(t);
- if (rtarget->resdom != NULL) {
- resdom = rtarget->resdom;
- expr = rtarget->expr;
- resjunk = resdom->resjunk;
- if (resjunk == 0) {
- /*
- * make a copy of the resdom node, changing its resno.
- */
- cleanResdom = (Resdom *) copyObject(resdom);
- cleanResdom->resno = cleanResno;
- cleanResno ++;
- /*
- * create a new target list entry
- */
- tle = makeNode(TargetEntry);
- tle->resdom = cleanResdom;
- tle->expr = expr;
- cleanTargetList = lappend(cleanTargetList, tle);
- }
- }
- else {
+ JunkFilter *junkfilter;
+ List *cleanTargetList;
+ int len,
+ cleanLength;
+ TupleDesc tupType,
+ cleanTupType;
+ List *t;
+ TargetEntry *tle;
+ Resdom *resdom,
+ *cleanResdom;
+ int resjunk;
+ AttrNumber cleanResno;
+ AttrNumber *cleanMap;
+ Size size;
+ Node *expr;
+
+ /* ---------------------
+ * First find the "clean" target list, i.e. all the entries
+ * in the original target list which have a zero 'resjunk'
+ * NOTE: make copy of the Resdom nodes, because we have
+ * to change the 'resno's...
+ * ---------------------
+ */
+ cleanTargetList = NIL;
+ cleanResno = 1;
+
+ foreach(t, targetList)
+ {
+ TargetEntry *rtarget = lfirst(t);
+
+ if (rtarget->resdom != NULL)
+ {
+ resdom = rtarget->resdom;
+ expr = rtarget->expr;
+ resjunk = resdom->resjunk;
+ if (resjunk == 0)
+ {
+
+ /*
+ * make a copy of the resdom node, changing its resno.
+ */
+ cleanResdom = (Resdom *) copyObject(resdom);
+ cleanResdom->resno = cleanResno;
+ cleanResno++;
+
+ /*
+ * create a new target list entry
+ */
+ tle = makeNode(TargetEntry);
+ tle->resdom = cleanResdom;
+ tle->expr = expr;
+ cleanTargetList = lappend(cleanTargetList, tle);
+ }
+ }
+ else
+ {
#ifdef SETS_FIXED
- List *fjListP;
- Fjoin *cleanFjoin;
- List *cleanFjList;
- List *fjList = lfirst(t);
- Fjoin *fjNode = (Fjoin *)tl_node(fjList);
-
- cleanFjoin = (Fjoin)copyObject((Node) fjNode);
- cleanFjList = lcons(cleanFjoin, NIL);
-
- resdom = (Resdom) lfirst(get_fj_innerNode(fjNode));
- expr = lsecond(get_fj_innerNode(fjNode));
- cleanResdom = (Resdom) copyObject((Node) resdom);
- set_resno(cleanResdom, cleanResno);
- cleanResno++;
- tle = (List) MakeTLE(cleanResdom, (Expr) expr);
- set_fj_innerNode(cleanFjoin, tle);
-
- foreach(fjListP, lnext(fjList)) {
- TargetEntry *tle = lfirst(fjListP);
-
- resdom = tle->resdom;
- expr = tle->expr;
- cleanResdom = (Resdom*) copyObject((Node) resdom);
- cleanResno++;
- cleanResdom->Resno = cleanResno;
- /*
- * create a new target list entry
- */
- tle = (List) MakeTLE(cleanResdom, (Expr) expr);
- cleanFjList = lappend(cleanFjList, tle);
- }
- lappend(cleanTargetList, cleanFjList);
+ List *fjListP;
+ Fjoin *cleanFjoin;
+ List *cleanFjList;
+ List *fjList = lfirst(t);
+ Fjoin *fjNode = (Fjoin *) tl_node(fjList);
+
+ cleanFjoin = (Fjoin) copyObject((Node) fjNode);
+ cleanFjList = lcons(cleanFjoin, NIL);
+
+ resdom = (Resdom) lfirst(get_fj_innerNode(fjNode));
+ expr = lsecond(get_fj_innerNode(fjNode));
+ cleanResdom = (Resdom) copyObject((Node) resdom);
+ set_resno(cleanResdom, cleanResno);
+ cleanResno++;
+ tle = (List) MakeTLE(cleanResdom, (Expr) expr);
+ set_fj_innerNode(cleanFjoin, tle);
+
+ foreach(fjListP, lnext(fjList))
+ {
+ TargetEntry *tle = lfirst(fjListP);
+
+ resdom = tle->resdom;
+ expr = tle->expr;
+ cleanResdom = (Resdom *) copyObject((Node) resdom);
+ cleanResno++;
+ cleanResdom->Resno = cleanResno;
+
+ /*
+ * create a new target list entry
+ */
+ tle = (List) MakeTLE(cleanResdom, (Expr) expr);
+ cleanFjList = lappend(cleanFjList, tle);
+ }
+ lappend(cleanTargetList, cleanFjList);
#endif
- }
- }
-
- /* ---------------------
- * Now calculate the tuple types for the original and the clean tuple
- *
- * XXX ExecTypeFromTL should be used sparingly. Don't we already
- * have the tupType corresponding to the targetlist we are passed?
- * -cim 5/31/91
- * ---------------------
- */
- tupType = (TupleDesc) ExecTypeFromTL(targetList);
- cleanTupType = (TupleDesc) ExecTypeFromTL(cleanTargetList);
-
- len = ExecTargetListLength(targetList);
- cleanLength = ExecTargetListLength(cleanTargetList);
-
- /* ---------------------
- * Now calculate the "map" between the original tuples attributes
- * and the "clean" tuple's attributes.
- *
- * The "map" is an array of "cleanLength" attribute numbers, i.e.
- * one entry for every attribute of the "clean" tuple.
- * The value of this entry is the attribute number of the corresponding
- * attribute of the "original" tuple.
- * ---------------------
- */
- if (cleanLength > 0) {
- size = cleanLength * sizeof(AttrNumber);
- cleanMap = (AttrNumber*) palloc(size);
- cleanResno = 1;
- foreach (t, targetList) {
- TargetEntry *tle = lfirst(t);
- if (tle->resdom != NULL) {
- resdom = tle->resdom;
- expr = tle->expr;
- resjunk = resdom->resjunk;
- if (resjunk == 0) {
- cleanMap[cleanResno-1] = resdom->resno;
- cleanResno ++;
}
- } else {
+ }
+
+ /* ---------------------
+ * Now calculate the tuple types for the original and the clean tuple
+ *
+ * XXX ExecTypeFromTL should be used sparingly. Don't we already
+ * have the tupType corresponding to the targetlist we are passed?
+ * -cim 5/31/91
+ * ---------------------
+ */
+ tupType = (TupleDesc) ExecTypeFromTL(targetList);
+ cleanTupType = (TupleDesc) ExecTypeFromTL(cleanTargetList);
+
+ len = ExecTargetListLength(targetList);
+ cleanLength = ExecTargetListLength(cleanTargetList);
+
+ /* ---------------------
+ * Now calculate the "map" between the original tuples attributes
+ * and the "clean" tuple's attributes.
+ *
+ * The "map" is an array of "cleanLength" attribute numbers, i.e.
+ * one entry for every attribute of the "clean" tuple.
+ * The value of this entry is the attribute number of the corresponding
+ * attribute of the "original" tuple.
+ * ---------------------
+ */
+ if (cleanLength > 0)
+ {
+ size = cleanLength * sizeof(AttrNumber);
+ cleanMap = (AttrNumber *) palloc(size);
+ cleanResno = 1;
+ foreach(t, targetList)
+ {
+ TargetEntry *tle = lfirst(t);
+
+ if (tle->resdom != NULL)
+ {
+ resdom = tle->resdom;
+ expr = tle->expr;
+ resjunk = resdom->resjunk;
+ if (resjunk == 0)
+ {
+ cleanMap[cleanResno - 1] = resdom->resno;
+ cleanResno++;
+ }
+ }
+ else
+ {
#ifdef SETS_FIXED
- List fjListP;
- List fjList = lfirst(t);
- Fjoin fjNode = (Fjoin)lfirst(fjList);
+ List fjListP;
+ List fjList = lfirst(t);
+ Fjoin fjNode = (Fjoin) lfirst(fjList);
- /* what the hell is this????? */
- resdom = (Resdom) lfirst(get_fj_innerNode(fjNode));
+ /* what the hell is this????? */
+ resdom = (Resdom) lfirst(get_fj_innerNode(fjNode));
#endif
- cleanMap[cleanResno-1] = tle->resdom->resno;
- cleanResno++;
+ cleanMap[cleanResno - 1] = tle->resdom->resno;
+ cleanResno++;
#ifdef SETS_FIXED
- foreach(fjListP, lnext(fjList)) {
- TargetEntry *tle = lfirst(fjListP);
+ foreach(fjListP, lnext(fjList))
+ {
+ TargetEntry *tle = lfirst(fjListP);
- resdom = tle->resdom;
- cleanMap[cleanResno-1] = resdom->resno;
- cleanResno++;
- }
+ resdom = tle->resdom;
+ cleanMap[cleanResno - 1] = resdom->resno;
+ cleanResno++;
+ }
#endif
- }
+ }
+ }
+ }
+ else
+ {
+ cleanMap = NULL;
}
- } else {
- cleanMap = NULL;
- }
-
- /* ---------------------
- * Finally create and initialize the JunkFilter.
- * ---------------------
- */
- junkfilter = makeNode(JunkFilter);
-
- junkfilter->jf_targetList = targetList;
- junkfilter->jf_length = len;
- junkfilter->jf_tupType = tupType;
- junkfilter->jf_cleanTargetList = cleanTargetList;
- junkfilter->jf_cleanLength = cleanLength;
- junkfilter->jf_cleanTupType = cleanTupType;
- junkfilter->jf_cleanMap = cleanMap;
-
- return(junkfilter);
-
+
+ /* ---------------------
+ * Finally create and initialize the JunkFilter.
+ * ---------------------
+ */
+ junkfilter = makeNode(JunkFilter);
+
+ junkfilter->jf_targetList = targetList;
+ junkfilter->jf_length = len;
+ junkfilter->jf_tupType = tupType;
+ junkfilter->jf_cleanTargetList = cleanTargetList;
+ junkfilter->jf_cleanLength = cleanLength;
+ junkfilter->jf_cleanTupType = cleanTupType;
+ junkfilter->jf_cleanMap = cleanMap;
+
+ return (junkfilter);
+
}
/*-------------------------------------------------------------------------
@@ -242,57 +264,61 @@ ExecInitJunkFilter(List *targetList)
*-------------------------------------------------------------------------
*/
bool
-ExecGetJunkAttribute(JunkFilter *junkfilter,
- TupleTableSlot *slot,
- char *attrName,
- Datum *value,
- bool *isNull)
+ExecGetJunkAttribute(JunkFilter * junkfilter,
+ TupleTableSlot * slot,
+ char *attrName,
+ Datum * value,
+ bool * isNull)
{
- List *targetList;
- List *t;
- Resdom *resdom;
- AttrNumber resno;
- char *resname;
- int resjunk;
- TupleDesc tupType;
- HeapTuple tuple;
-
- /* ---------------------
- * first look in the junkfilter's target list for
- * an attribute with the given name
- * ---------------------
- */
- resno = InvalidAttrNumber;
- targetList = junkfilter->jf_targetList;
-
- foreach (t, targetList) {
- TargetEntry *tle = lfirst(t);
- resdom = tle->resdom;
- resname = resdom->resname;
- resjunk = resdom->resjunk;
- if (resjunk != 0 && (strcmp(resname, attrName) == 0)) {
- /* We found it ! */
- resno = resdom->resno;
- break;
+ List *targetList;
+ List *t;
+ Resdom *resdom;
+ AttrNumber resno;
+ char *resname;
+ int resjunk;
+ TupleDesc tupType;
+ HeapTuple tuple;
+
+ /* ---------------------
+ * first look in the junkfilter's target list for
+ * an attribute with the given name
+ * ---------------------
+ */
+ resno = InvalidAttrNumber;
+ targetList = junkfilter->jf_targetList;
+
+ foreach(t, targetList)
+ {
+ TargetEntry *tle = lfirst(t);
+
+ resdom = tle->resdom;
+ resname = resdom->resname;
+ resjunk = resdom->resjunk;
+ if (resjunk != 0 && (strcmp(resname, attrName) == 0))
+ {
+ /* We found it ! */
+ resno = resdom->resno;
+ break;
+ }
+ }
+
+ if (resno == InvalidAttrNumber)
+ {
+ /* Ooops! We couldn't find this attribute... */
+ return (false);
}
- }
-
- if (resno == InvalidAttrNumber) {
- /* Ooops! We couldn't find this attribute... */
- return(false);
- }
-
- /* ---------------------
- * Now extract the attribute value from the tuple.
- * ---------------------
- */
- tuple = slot->val;
- tupType = (TupleDesc) junkfilter->jf_tupType;
-
- *value = (Datum)
- heap_getattr(tuple, InvalidBuffer, resno, tupType, isNull);
-
- return true;
+
+ /* ---------------------
+ * Now extract the attribute value from the tuple.
+ * ---------------------
+ */
+ tuple = slot->val;
+ tupType = (TupleDesc) junkfilter->jf_tupType;
+
+ *value = (Datum)
+ heap_getattr(tuple, InvalidBuffer, resno, tupType, isNull);
+
+ return true;
}
/*-------------------------------------------------------------------------
@@ -302,94 +328,98 @@ ExecGetJunkAttribute(JunkFilter *junkfilter,
*-------------------------------------------------------------------------
*/
HeapTuple
-ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
+ExecRemoveJunk(JunkFilter * junkfilter, TupleTableSlot * slot)
{
- HeapTuple tuple;
- HeapTuple cleanTuple;
- AttrNumber *cleanMap;
- TupleDesc cleanTupType;
- TupleDesc tupType;
- int cleanLength;
- bool isNull;
- int i;
- Size size;
- Datum *values;
- char *nulls;
- Datum values_array[64];
- char nulls_array[64];
-
- /* ----------------
- * get info from the slot and the junk filter
- * ----------------
- */
- tuple = slot->val;
-
- tupType = (TupleDesc) junkfilter->jf_tupType;
- cleanTupType = (TupleDesc) junkfilter->jf_cleanTupType;
- cleanLength = junkfilter->jf_cleanLength;
- cleanMap = junkfilter->jf_cleanMap;
-
- /* ---------------------
- * Handle the trivial case first.
- * ---------------------
- */
- if (cleanLength == 0)
- return (HeapTuple) NULL;
-
- /* ---------------------
- * Create the arrays that will hold the attribute values
- * and the null information for the new "clean" tuple.
- *
- * Note: we use memory on the stack to optimize things when
- * we are dealing with a small number of tuples.
- * for large tuples we just use palloc.
- * ---------------------
- */
- if (cleanLength > 64) {
- size = cleanLength * sizeof(Datum);
- values = (Datum *) palloc(size);
-
- size = cleanLength * sizeof(char);
- nulls = (char *) palloc(size);
- } else {
- values = values_array;
- nulls = nulls_array;
- }
-
- /* ---------------------
- * Exctract one by one all the values of the "clean" tuple.
- * ---------------------
- */
- for (i=0; i<cleanLength; i++) {
- Datum d = (Datum)
- heap_getattr(tuple, InvalidBuffer, cleanMap[i], tupType, &isNull);
-
- values[i] = d;
-
- if (isNull)
- nulls[i] = 'n';
+ HeapTuple tuple;
+ HeapTuple cleanTuple;
+ AttrNumber *cleanMap;
+ TupleDesc cleanTupType;
+ TupleDesc tupType;
+ int cleanLength;
+ bool isNull;
+ int i;
+ Size size;
+ Datum *values;
+ char *nulls;
+ Datum values_array[64];
+ char nulls_array[64];
+
+ /* ----------------
+ * get info from the slot and the junk filter
+ * ----------------
+ */
+ tuple = slot->val;
+
+ tupType = (TupleDesc) junkfilter->jf_tupType;
+ cleanTupType = (TupleDesc) junkfilter->jf_cleanTupType;
+ cleanLength = junkfilter->jf_cleanLength;
+ cleanMap = junkfilter->jf_cleanMap;
+
+ /* ---------------------
+ * Handle the trivial case first.
+ * ---------------------
+ */
+ if (cleanLength == 0)
+ return (HeapTuple) NULL;
+
+ /* ---------------------
+ * Create the arrays that will hold the attribute values
+ * and the null information for the new "clean" tuple.
+ *
+ * Note: we use memory on the stack to optimize things when
+ * we are dealing with a small number of tuples.
+ * for large tuples we just use palloc.
+ * ---------------------
+ */
+ if (cleanLength > 64)
+ {
+ size = cleanLength * sizeof(Datum);
+ values = (Datum *) palloc(size);
+
+ size = cleanLength * sizeof(char);
+ nulls = (char *) palloc(size);
+ }
else
- nulls[i] = ' ';
- }
-
- /* ---------------------
- * Now form the new tuple.
- * ---------------------
- */
- cleanTuple = heap_formtuple(cleanTupType,
- values,
- nulls);
-
- /* ---------------------
- * We are done. Free any space allocated for 'values' and 'nulls'
- * and return the new tuple.
- * ---------------------
- */
- if (cleanLength > 64) {
- pfree(values);
- pfree(nulls);
- }
-
- return(cleanTuple);
-}
+ {
+ values = values_array;
+ nulls = nulls_array;
+ }
+
+ /* ---------------------
+ * Exctract one by one all the values of the "clean" tuple.
+ * ---------------------
+ */
+ for (i = 0; i < cleanLength; i++)
+ {
+ Datum d = (Datum)
+ heap_getattr(tuple, InvalidBuffer, cleanMap[i], tupType, &isNull);
+ values[i] = d;
+
+ if (isNull)
+ nulls[i] = 'n';
+ else
+ nulls[i] = ' ';
+ }
+
+ /* ---------------------
+ * Now form the new tuple.
+ * ---------------------
+ */
+ cleanTuple = heap_formtuple(cleanTupType,
+ values,
+ nulls);
+
+ /* ---------------------
+ * We are done. Free any space allocated for 'values' and 'nulls'
+ * and return the new tuple.
+ * ---------------------
+ */
+ if (cleanLength > 64)
+ {
+ pfree(values);
+ pfree(nulls);
+ }
+
+ return (cleanTuple);
+}
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 48bf84ba095..2bf0edaf35e 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1,32 +1,32 @@
/*-------------------------------------------------------------------------
*
* execMain.c--
- * top level executor interface routines
+ * top level executor interface routines
*
* INTERFACE ROUTINES
- * ExecutorStart()
- * ExecutorRun()
- * ExecutorEnd()
+ * ExecutorStart()
+ * ExecutorRun()
+ * ExecutorEnd()
*
- * The old ExecutorMain() has been replaced by ExecutorStart(),
- * ExecutorRun() and ExecutorEnd()
+ * The old ExecutorMain() has been replaced by ExecutorStart(),
+ * ExecutorRun() and ExecutorEnd()
+ *
+ * These three procedures are the external interfaces to the executor.
+ * In each case, the query descriptor and the execution state is required
+ * as arguments
+ *
+ * ExecutorStart() must be called at the beginning of any execution of any
+ * query plan and ExecutorEnd() should always be called at the end of
+ * execution of a plan.
+ *
+ * ExecutorRun accepts 'feature' and 'count' arguments that specify whether
+ * the plan is to be executed forwards, backwards, and for how many tuples.
*
- * These three procedures are the external interfaces to the executor.
- * In each case, the query descriptor and the execution state is required
- * as arguments
- *
- * ExecutorStart() must be called at the beginning of any execution of any
- * query plan and ExecutorEnd() should always be called at the end of
- * execution of a plan.
- *
- * ExecutorRun accepts 'feature' and 'count' arguments that specify whether
- * the plan is to be executed forwards, backwards, and for how many tuples.
- *
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.22 1997/09/04 13:22:36 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.23 1997/09/07 04:41:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -42,7 +42,7 @@
#include "utils/palloc.h"
#include "utils/acl.h"
#include "utils/syscache.h"
-#include "parser/parsetree.h" /* rt_fetch() */
+#include "parser/parsetree.h" /* rt_fetch() */
#include "storage/bufmgr.h"
#include "storage/lmgr.h"
#include "storage/smgr.h"
@@ -56,28 +56,35 @@
/* decls for local routines only used within this module */
-static void ExecCheckPerms(CmdType operation, int resultRelation, List *rangeTable,
- Query *parseTree);
-static TupleDesc InitPlan(CmdType operation, Query *parseTree,
- Plan *plan, EState *estate);
-static void EndPlan(Plan *plan, EState *estate);
-static TupleTableSlot *ExecutePlan(EState *estate, Plan *plan,
- Query *parseTree, CmdType operation,
- int numberTuples, ScanDirection direction,
- void (*printfunc)());
-static void ExecRetrieve(TupleTableSlot *slot, void (*printfunc)(),
- EState *estate);
-static void ExecAppend(TupleTableSlot *slot,ItemPointer tupleid,
- EState *estate);
-static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
- EState *estate);
-static void ExecReplace(TupleTableSlot *slot, ItemPointer tupleid,
- EState *estate, Query *parseTree);
+static void
+ExecCheckPerms(CmdType operation, int resultRelation, List * rangeTable,
+ Query * parseTree);
+static TupleDesc
+InitPlan(CmdType operation, Query * parseTree,
+ Plan * plan, EState * estate);
+static void EndPlan(Plan * plan, EState * estate);
+static TupleTableSlot *
+ExecutePlan(EState * estate, Plan * plan,
+ Query * parseTree, CmdType operation,
+ int numberTuples, ScanDirection direction,
+ void (*printfunc) ());
+static void ExecRetrieve(TupleTableSlot * slot, void (*printfunc) (),
+ EState * estate);
+static void
+ExecAppend(TupleTableSlot * slot, ItemPointer tupleid,
+ EState * estate);
+static void
+ExecDelete(TupleTableSlot * slot, ItemPointer tupleid,
+ EState * estate);
+static void
+ExecReplace(TupleTableSlot * slot, ItemPointer tupleid,
+ EState * estate, Query * parseTree);
/* end of local decls */
#ifdef QUERY_LIMIT
-static int queryLimit = ALL_TUPLES;
+static int queryLimit = ALL_TUPLES;
+
#undef ALL_TUPLES
#define ALL_TUPLES queryLimit
@@ -85,574 +92,605 @@ static int queryLimit = ALL_TUPLES;
int
ExecutorLimit(int limit)
{
- return queryLimit = limit;
+ return queryLimit = limit;
}
+
#endif
#endif
/* ----------------------------------------------------------------
- * ExecutorStart
- *
- * This routine must be called at the beginning of any execution of any
- * query plan
- *
- * returns (AttrInfo*) which describes the attributes of the tuples to
- * be returned by the query.
+ * ExecutorStart
+ *
+ * This routine must be called at the beginning of any execution of any
+ * query plan
+ *
+ * returns (AttrInfo*) which describes the attributes of the tuples to
+ * be returned by the query.
*
* ----------------------------------------------------------------
*/
TupleDesc
-ExecutorStart(QueryDesc *queryDesc, EState *estate)
+ExecutorStart(QueryDesc * queryDesc, EState * estate)
{
- TupleDesc result;
-
- /* sanity checks */
- Assert(queryDesc!=NULL);
-
- result = InitPlan(queryDesc->operation,
- queryDesc->parsetree,
- queryDesc->plantree,
- estate);
-
- /* reset buffer refcount. the current refcounts
- * are saved and will be restored when ExecutorEnd is called
- *
- * this makes sure that when ExecutorRun's are
- * called recursively as for postquel functions,
- * the buffers pinned by one ExecutorRun will not be
- * unpinned by another ExecutorRun.
- */
- BufferRefCountReset(estate->es_refcount);
-
- return result;
+ TupleDesc result;
+
+ /* sanity checks */
+ Assert(queryDesc != NULL);
+
+ result = InitPlan(queryDesc->operation,
+ queryDesc->parsetree,
+ queryDesc->plantree,
+ estate);
+
+ /*
+ * reset buffer refcount. the current refcounts are saved and will be
+ * restored when ExecutorEnd is called
+ *
+ * this makes sure that when ExecutorRun's are called recursively as for
+ * postquel functions, the buffers pinned by one ExecutorRun will not
+ * be unpinned by another ExecutorRun.
+ */
+ BufferRefCountReset(estate->es_refcount);
+
+ return result;
}
/* ----------------------------------------------------------------
- * ExecutorRun
- *
- * This is the main routine of the executor module. It accepts
- * the query descriptor from the traffic cop and executes the
- * query plan.
- *
- * ExecutorStart must have been called already.
+ * ExecutorRun
+ *
+ * This is the main routine of the executor module. It accepts
+ * the query descriptor from the traffic cop and executes the
+ * query plan.
+ *
+ * ExecutorStart must have been called already.
*
- * the different features supported are:
- * EXEC_RUN: retrieve all tuples in the forward direction
- * EXEC_FOR: retrieve 'count' number of tuples in the forward dir
- * EXEC_BACK: retrieve 'count' number of tuples in the backward dir
- * EXEC_RETONE: return one tuple but don't 'retrieve' it
- * used in postquel function processing
+ * the different features supported are:
+ * EXEC_RUN: retrieve all tuples in the forward direction
+ * EXEC_FOR: retrieve 'count' number of tuples in the forward dir
+ * EXEC_BACK: retrieve 'count' number of tuples in the backward dir
+ * EXEC_RETONE: return one tuple but don't 'retrieve' it
+ * used in postquel function processing
*
*
* ----------------------------------------------------------------
*/
-TupleTableSlot*
-ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
+TupleTableSlot *
+ExecutorRun(QueryDesc * queryDesc, EState * estate, int feature, int count)
{
- CmdType operation;
- Query *parseTree;
- Plan *plan;
- TupleTableSlot *result;
- CommandDest dest;
- void (*destination)();
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(queryDesc!=NULL);
-
- /* ----------------
- * extract information from the query descriptor
- * and the query feature.
- * ----------------
- */
- operation = queryDesc->operation;
- parseTree = queryDesc->parsetree;
- plan = queryDesc->plantree;
- dest = queryDesc->dest;
- destination = (void (*)()) DestToFunction(dest);
- estate->es_processed = 0;
- estate->es_lastoid = InvalidOid;
+ CmdType operation;
+ Query *parseTree;
+ Plan *plan;
+ TupleTableSlot *result;
+ CommandDest dest;
+ void (*destination) ();
-#if 0
- /*
- * It doesn't work in common case (i.g. if function has a aggregate).
- * Now we store parameter values before ExecutorStart. - vadim 01/22/97
- */
-#ifdef INDEXSCAN_PATCH
- /*
- * If the plan is an index scan and some of the scan key are
- * function arguments rescan the indices after the parameter
- * values have been stored in the execution state. DZ - 27-8-1996
- */
- if ((nodeTag(plan) == T_IndexScan) &&
- (((IndexScan *)plan)->indxstate->iss_RuntimeKeyInfo != NULL)) {
- ExprContext *econtext;
- econtext = ((IndexScan *)plan)->scan.scanstate->cstate.cs_ExprContext;
- ExecIndexReScan((IndexScan *)plan, econtext, plan);
- }
-#endif
-#endif
-
- switch(feature) {
-
- case EXEC_RUN:
- result = ExecutePlan(estate,
- plan,
- parseTree,
- operation,
- ALL_TUPLES,
- ForwardScanDirection,
- destination);
- break;
- case EXEC_FOR:
- result = ExecutePlan(estate,
- plan,
- parseTree,
- operation,
- count,
- ForwardScanDirection,
- destination);
- break;
-
/* ----------------
- * retrieve next n "backward" tuples
+ * sanity checks
* ----------------
*/
- case EXEC_BACK:
- result = ExecutePlan(estate,
- plan,
- parseTree,
- operation,
- count,
- BackwardScanDirection,
- destination);
- break;
-
+ Assert(queryDesc != NULL);
+
/* ----------------
- * return one tuple but don't "retrieve" it.
- * (this is used by the rule manager..) -cim 9/14/89
+ * extract information from the query descriptor
+ * and the query feature.
* ----------------
*/
- case EXEC_RETONE:
- result = ExecutePlan(estate,
- plan,
- parseTree,
- operation,
- ONE_TUPLE,
- ForwardScanDirection,
- destination);
- break;
- default:
- result = NULL;
- elog(DEBUG, "ExecutorRun: Unknown feature %d", feature);
- break;
- }
+ operation = queryDesc->operation;
+ parseTree = queryDesc->parsetree;
+ plan = queryDesc->plantree;
+ dest = queryDesc->dest;
+ destination = (void (*) ()) DestToFunction(dest);
+ estate->es_processed = 0;
+ estate->es_lastoid = InvalidOid;
+
+#if 0
+
+ /*
+ * It doesn't work in common case (i.g. if function has a aggregate).
+ * Now we store parameter values before ExecutorStart. - vadim
+ * 01/22/97
+ */
+#ifdef INDEXSCAN_PATCH
+
+ /*
+ * If the plan is an index scan and some of the scan key are function
+ * arguments rescan the indices after the parameter values have been
+ * stored in the execution state. DZ - 27-8-1996
+ */
+ if ((nodeTag(plan) == T_IndexScan) &&
+ (((IndexScan *) plan)->indxstate->iss_RuntimeKeyInfo != NULL))
+ {
+ ExprContext *econtext;
+
+ econtext = ((IndexScan *) plan)->scan.scanstate->cstate.cs_ExprContext;
+ ExecIndexReScan((IndexScan *) plan, econtext, plan);
+ }
+#endif
+#endif
+
+ switch (feature)
+ {
+
+ case EXEC_RUN:
+ result = ExecutePlan(estate,
+ plan,
+ parseTree,
+ operation,
+ ALL_TUPLES,
+ ForwardScanDirection,
+ destination);
+ break;
+ case EXEC_FOR:
+ result = ExecutePlan(estate,
+ plan,
+ parseTree,
+ operation,
+ count,
+ ForwardScanDirection,
+ destination);
+ break;
- return result;
+ /* ----------------
+ * retrieve next n "backward" tuples
+ * ----------------
+ */
+ case EXEC_BACK:
+ result = ExecutePlan(estate,
+ plan,
+ parseTree,
+ operation,
+ count,
+ BackwardScanDirection,
+ destination);
+ break;
+
+ /* ----------------
+ * return one tuple but don't "retrieve" it.
+ * (this is used by the rule manager..) -cim 9/14/89
+ * ----------------
+ */
+ case EXEC_RETONE:
+ result = ExecutePlan(estate,
+ plan,
+ parseTree,
+ operation,
+ ONE_TUPLE,
+ ForwardScanDirection,
+ destination);
+ break;
+ default:
+ result = NULL;
+ elog(DEBUG, "ExecutorRun: Unknown feature %d", feature);
+ break;
+ }
+
+ return result;
}
/* ----------------------------------------------------------------
- * ExecutorEnd
- *
- * This routine must be called at the end of any execution of any
- * query plan
- *
- * returns (AttrInfo*) which describes the attributes of the tuples to
- * be returned by the query.
+ * ExecutorEnd
+ *
+ * This routine must be called at the end of any execution of any
+ * query plan
+ *
+ * returns (AttrInfo*) which describes the attributes of the tuples to
+ * be returned by the query.
*
* ----------------------------------------------------------------
*/
void
-ExecutorEnd(QueryDesc *queryDesc, EState *estate)
+ExecutorEnd(QueryDesc * queryDesc, EState * estate)
{
- /* sanity checks */
- Assert(queryDesc!=NULL);
+ /* sanity checks */
+ Assert(queryDesc != NULL);
- EndPlan(queryDesc->plantree, estate);
+ EndPlan(queryDesc->plantree, estate);
- /* restore saved refcounts. */
- BufferRefCountRestore(estate->es_refcount);
+ /* restore saved refcounts. */
+ BufferRefCountRestore(estate->es_refcount);
}
/* ===============================================================
* ===============================================================
- static routines follow
+ static routines follow
* ===============================================================
* ===============================================================
*/
static void
ExecCheckPerms(CmdType operation,
- int resultRelation,
- List *rangeTable,
- Query *parseTree)
+ int resultRelation,
+ List * rangeTable,
+ Query * parseTree)
{
- int i = 1;
- Oid relid;
- HeapTuple htp;
- List *lp;
- List *qvars, *tvars;
- int32 ok = 1, aclcheck_result = -1;
- char *opstr;
- NameData rname;
- char *userName;
-
-#define CHECK(MODE) pg_aclcheck(rname.data, userName, MODE)
-
- userName = GetPgUserName();
-
- foreach (lp, rangeTable) {
- RangeTblEntry *rte = lfirst(lp);
-
- relid = rte->relid;
- htp = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relid),
- 0,0,0);
- if (!HeapTupleIsValid(htp))
- elog(WARN, "ExecCheckPerms: bogus RT relid: %d",
- relid);
- strNcpy(rname.data,
- ((Form_pg_class) GETSTRUCT(htp))->relname.data,
- NAMEDATALEN-1);
- if (i == resultRelation) { /* this is the result relation */
- qvars = pull_varnos(parseTree->qual);
- tvars = pull_varnos((Node*)parseTree->targetList);
- if (intMember(resultRelation, qvars) ||
- intMember(resultRelation, tvars)) {
- /* result relation is scanned */
- ok = ((aclcheck_result = CHECK(ACL_RD)) == ACLCHECK_OK);
- opstr = "read";
+ int i = 1;
+ Oid relid;
+ HeapTuple htp;
+ List *lp;
+ List *qvars,
+ *tvars;
+ int32 ok = 1,
+ aclcheck_result = -1;
+ char *opstr;
+ NameData rname;
+ char *userName;
+
+#define CHECK(MODE) pg_aclcheck(rname.data, userName, MODE)
+
+ userName = GetPgUserName();
+
+ foreach(lp, rangeTable)
+ {
+ RangeTblEntry *rte = lfirst(lp);
+
+ relid = rte->relid;
+ htp = SearchSysCacheTuple(RELOID,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "ExecCheckPerms: bogus RT relid: %d",
+ relid);
+ strNcpy(rname.data,
+ ((Form_pg_class) GETSTRUCT(htp))->relname.data,
+ NAMEDATALEN - 1);
+ if (i == resultRelation)
+ { /* this is the result relation */
+ qvars = pull_varnos(parseTree->qual);
+ tvars = pull_varnos((Node *) parseTree->targetList);
+ if (intMember(resultRelation, qvars) ||
+ intMember(resultRelation, tvars))
+ {
+ /* result relation is scanned */
+ ok = ((aclcheck_result = CHECK(ACL_RD)) == ACLCHECK_OK);
+ opstr = "read";
+ if (!ok)
+ break;
+ }
+ switch (operation)
+ {
+ case CMD_INSERT:
+ ok = ((aclcheck_result = CHECK(ACL_AP)) == ACLCHECK_OK) ||
+ ((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
+ opstr = "append";
+ break;
+ case CMD_NOTIFY: /* what does this mean?? -- jw, 1/6/94 */
+ case CMD_DELETE:
+ case CMD_UPDATE:
+ ok = ((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
+ opstr = "write";
+ break;
+ default:
+ elog(WARN, "ExecCheckPerms: bogus operation %d",
+ operation);
+ }
+ }
+ else
+ {
+ /* XXX NOTIFY?? */
+ ok = ((aclcheck_result = CHECK(ACL_RD)) == ACLCHECK_OK);
+ opstr = "read";
+ }
if (!ok)
- break;
- }
- switch (operation) {
- case CMD_INSERT:
- ok = ((aclcheck_result = CHECK(ACL_AP)) == ACLCHECK_OK) ||
- ((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
- opstr = "append";
- break;
- case CMD_NOTIFY: /* what does this mean?? -- jw, 1/6/94 */
- case CMD_DELETE:
- case CMD_UPDATE:
- ok = ((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
- opstr = "write";
- break;
- default:
- elog(WARN, "ExecCheckPerms: bogus operation %d",
- operation);
- }
- } else {
- /* XXX NOTIFY?? */
- ok = ((aclcheck_result = CHECK(ACL_RD)) == ACLCHECK_OK);
- opstr = "read";
+ break;
+ ++i;
}
if (!ok)
- break;
- ++i;
- }
- if (!ok) {
- elog(WARN, "%s: %s", rname.data, aclcheck_error_strings[aclcheck_result]);
- }
+ {
+ elog(WARN, "%s: %s", rname.data, aclcheck_error_strings[aclcheck_result]);
+ }
}
/* ----------------------------------------------------------------
- * InitPlan
- *
- * Initializes the query plan: open files, allocate storage
- * and start up the rule manager
+ * InitPlan
+ *
+ * Initializes the query plan: open files, allocate storage
+ * and start up the rule manager
* ----------------------------------------------------------------
*/
-static TupleDesc
-InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
-{
- List *rangeTable;
- int resultRelation;
- Relation intoRelationDesc;
-
- TupleDesc tupType;
- List *targetList;
- int len;
-
- /* ----------------
- * get information from query descriptor
- * ----------------
- */
- rangeTable = parseTree->rtable;
- resultRelation = parseTree->resultRelation;
-
- /* ----------------
- * initialize the node's execution state
- * ----------------
- */
- estate->es_range_table = rangeTable;
-
- /* ----------------
- * initialize the BaseId counter so node base_id's
- * are assigned correctly. Someday baseid's will have to
- * be stored someplace other than estate because they
- * should be unique per query planned.
- * ----------------
- */
- estate->es_BaseId = 1;
-
- /* ----------------
- * initialize result relation stuff
- * ----------------
- */
-
- if (resultRelation != 0 && operation != CMD_SELECT) {
- /* ----------------
- * if we have a result relation, open it and
+static TupleDesc
+InitPlan(CmdType operation, Query * parseTree, Plan * plan, EState * estate)
+{
+ List *rangeTable;
+ int resultRelation;
+ Relation intoRelationDesc;
+
+ TupleDesc tupType;
+ List *targetList;
+ int len;
- * initialize the result relation info stuff.
+ /* ----------------
+ * get information from query descriptor
* ----------------
*/
- RelationInfo *resultRelationInfo;
- Index resultRelationIndex;
- RangeTblEntry *rtentry;
- Oid resultRelationOid;
- Relation resultRelationDesc;
-
- resultRelationIndex = resultRelation;
- rtentry = rt_fetch(resultRelationIndex, rangeTable);
- resultRelationOid = rtentry->relid;
- resultRelationDesc = heap_open(resultRelationOid);
-
- if ( resultRelationDesc->rd_rel->relkind == RELKIND_SEQUENCE )
- elog (WARN, "You can't change sequence relation %s",
- resultRelationDesc->rd_rel->relname.data);
-
- /* Write-lock the result relation right away: if the relation
- is used in a subsequent scan, we won't have to elevate the
- read-lock set by heap_beginscan to a write-lock (needed by
- heap_insert, heap_delete and heap_replace).
- This will hopefully prevent some deadlocks. - 01/24/94 */
- RelationSetLockForWrite(resultRelationDesc);
-
- resultRelationInfo = makeNode(RelationInfo);
- resultRelationInfo->ri_RangeTableIndex = resultRelationIndex;
- resultRelationInfo->ri_RelationDesc = resultRelationDesc;
- resultRelationInfo->ri_NumIndices = 0;
- resultRelationInfo->ri_IndexRelationDescs = NULL;
- resultRelationInfo->ri_IndexRelationInfo = NULL;
+ rangeTable = parseTree->rtable;
+ resultRelation = parseTree->resultRelation;
/* ----------------
- * open indices on result relation and save descriptors
- * in the result relation information..
+ * initialize the node's execution state
* ----------------
*/
- ExecOpenIndices(resultRelationOid, resultRelationInfo);
-
- estate->es_result_relation_info = resultRelationInfo;
- } else {
+ estate->es_range_table = rangeTable;
+
/* ----------------
- * if no result relation, then set state appropriately
+ * initialize the BaseId counter so node base_id's
+ * are assigned correctly. Someday baseid's will have to
+ * be stored someplace other than estate because they
+ * should be unique per query planned.
* ----------------
*/
- estate->es_result_relation_info = NULL;
- }
+ estate->es_BaseId = 1;
-#ifndef NO_SECURITY
- ExecCheckPerms(operation, resultRelation, rangeTable, parseTree);
-#endif
+ /* ----------------
+ * initialize result relation stuff
+ * ----------------
+ */
- /* ----------------
- * initialize the executor "tuple" table.
- * ----------------
- */
- {
- int nSlots = ExecCountSlotsNode(plan);
- TupleTable tupleTable = ExecCreateTupleTable(nSlots+10); /* why add ten? - jolly */
-
- estate->es_tupleTable = tupleTable;
- }
-
- /* ----------------
- * initialize the private state information for
- * all the nodes in the query tree. This opens
- * files, allocates storage and leaves us ready
- * to start processing tuples..
- * ----------------
- */
- ExecInitNode(plan, estate, NULL);
-
- /* ----------------
- * get the tuple descriptor describing the type
- * of tuples to return.. (this is especially important
- * if we are creating a relation with "retrieve into")
- * ----------------
- */
- tupType = ExecGetTupType(plan); /* tuple descriptor */
- targetList = plan->targetlist;
- len = ExecTargetListLength(targetList); /* number of attributes */
-
- /* ----------------
- * now that we have the target list, initialize the junk filter
- * if this is a REPLACE or a DELETE query.
- * We also init the junk filter if this is an append query
- * (there might be some rule lock info there...)
- * NOTE: in the future we might want to initialize the junk
- * filter for all queries.
- * ----------------
- */
- if (operation == CMD_UPDATE || operation == CMD_DELETE ||
- operation == CMD_INSERT) {
-
- JunkFilter *j = (JunkFilter*) ExecInitJunkFilter(targetList);
- estate->es_junkFilter = j;
- } else
- estate->es_junkFilter = NULL;
-
- /* ----------------
- * initialize the "into" relation
- * ----------------
- */
- intoRelationDesc = (Relation) NULL;
-
- if (operation == CMD_SELECT) {
- char *intoName;
- char archiveMode;
- Oid intoRelationId;
- TupleDesc tupdesc;
-
- if (!parseTree->isPortal) {
- /*
- * a select into table
- */
- if (parseTree->into != NULL) {
+ if (resultRelation != 0 && operation != CMD_SELECT)
+ {
/* ----------------
- * create the "into" relation
- *
- * note: there is currently no way for the user to
- * specify the desired archive mode of the
- * "into" relation...
+ * if we have a result relation, open it and
+
+ * initialize the result relation info stuff.
* ----------------
*/
- intoName = parseTree->into;
- archiveMode = 'n';
-
+ RelationInfo *resultRelationInfo;
+ Index resultRelationIndex;
+ RangeTblEntry *rtentry;
+ Oid resultRelationOid;
+ Relation resultRelationDesc;
+
+ resultRelationIndex = resultRelation;
+ rtentry = rt_fetch(resultRelationIndex, rangeTable);
+ resultRelationOid = rtentry->relid;
+ resultRelationDesc = heap_open(resultRelationOid);
+
+ if (resultRelationDesc->rd_rel->relkind == RELKIND_SEQUENCE)
+ elog(WARN, "You can't change sequence relation %s",
+ resultRelationDesc->rd_rel->relname.data);
+
/*
- * have to copy tupType to get rid of constraints
+ * Write-lock the result relation right away: if the relation is
+ * used in a subsequent scan, we won't have to elevate the
+ * read-lock set by heap_beginscan to a write-lock (needed by
+ * heap_insert, heap_delete and heap_replace). This will hopefully
+ * prevent some deadlocks. - 01/24/94
*/
- tupdesc = CreateTupleDescCopy (tupType);
-
- /* fixup to prevent zero-length columns in create */
- setVarAttrLenForCreateTable(tupdesc, targetList, rangeTable);
-
- intoRelationId = heap_create(intoName,
- intoName, /* not used */
- archiveMode,
- DEFAULT_SMGR,
- tupdesc);
-#ifdef NOT_USED /* it's copy ... */
- resetVarAttrLenForCreateTable(tupdesc);
-#endif
- FreeTupleDesc (tupdesc);
+ RelationSetLockForWrite(resultRelationDesc);
+
+ resultRelationInfo = makeNode(RelationInfo);
+ resultRelationInfo->ri_RangeTableIndex = resultRelationIndex;
+ resultRelationInfo->ri_RelationDesc = resultRelationDesc;
+ resultRelationInfo->ri_NumIndices = 0;
+ resultRelationInfo->ri_IndexRelationDescs = NULL;
+ resultRelationInfo->ri_IndexRelationInfo = NULL;
/* ----------------
- * XXX rather than having to call setheapoverride(true)
- * and then back to false, we should change the
- * arguments to heap_open() instead..
+ * open indices on result relation and save descriptors
+ * in the result relation information..
* ----------------
*/
- setheapoverride(true);
-
- intoRelationDesc = heap_open(intoRelationId);
-
- setheapoverride(false);
- }
+ ExecOpenIndices(resultRelationOid, resultRelationInfo);
+
+ estate->es_result_relation_info = resultRelationInfo;
}
- }
+ else
+ {
+ /* ----------------
+ * if no result relation, then set state appropriately
+ * ----------------
+ */
+ estate->es_result_relation_info = NULL;
+ }
+
+#ifndef NO_SECURITY
+ ExecCheckPerms(operation, resultRelation, rangeTable, parseTree);
+#endif
+
+ /* ----------------
+ * initialize the executor "tuple" table.
+ * ----------------
+ */
+ {
+ int nSlots = ExecCountSlotsNode(plan);
+ TupleTable tupleTable = ExecCreateTupleTable(nSlots + 10); /* why add ten? - jolly */
- estate->es_into_relation_descriptor = intoRelationDesc;
+ estate->es_tupleTable = tupleTable;
+ }
- /* ----------------
- * return the type information..
- * ----------------
- */
+ /* ----------------
+ * initialize the private state information for
+ * all the nodes in the query tree. This opens
+ * files, allocates storage and leaves us ready
+ * to start processing tuples..
+ * ----------------
+ */
+ ExecInitNode(plan, estate, NULL);
+
+ /* ----------------
+ * get the tuple descriptor describing the type
+ * of tuples to return.. (this is especially important
+ * if we are creating a relation with "retrieve into")
+ * ----------------
+ */
+ tupType = ExecGetTupType(plan); /* tuple descriptor */
+ targetList = plan->targetlist;
+ len = ExecTargetListLength(targetList); /* number of attributes */
+
+ /* ----------------
+ * now that we have the target list, initialize the junk filter
+ * if this is a REPLACE or a DELETE query.
+ * We also init the junk filter if this is an append query
+ * (there might be some rule lock info there...)
+ * NOTE: in the future we might want to initialize the junk
+ * filter for all queries.
+ * ----------------
+ */
+ if (operation == CMD_UPDATE || operation == CMD_DELETE ||
+ operation == CMD_INSERT)
+ {
+
+ JunkFilter *j = (JunkFilter *) ExecInitJunkFilter(targetList);
+
+ estate->es_junkFilter = j;
+ }
+ else
+ estate->es_junkFilter = NULL;
+
+ /* ----------------
+ * initialize the "into" relation
+ * ----------------
+ */
+ intoRelationDesc = (Relation) NULL;
+
+ if (operation == CMD_SELECT)
+ {
+ char *intoName;
+ char archiveMode;
+ Oid intoRelationId;
+ TupleDesc tupdesc;
+
+ if (!parseTree->isPortal)
+ {
+
+ /*
+ * a select into table
+ */
+ if (parseTree->into != NULL)
+ {
+ /* ----------------
+ * create the "into" relation
+ *
+ * note: there is currently no way for the user to
+ * specify the desired archive mode of the
+ * "into" relation...
+ * ----------------
+ */
+ intoName = parseTree->into;
+ archiveMode = 'n';
+
+ /*
+ * have to copy tupType to get rid of constraints
+ */
+ tupdesc = CreateTupleDescCopy(tupType);
+
+ /* fixup to prevent zero-length columns in create */
+ setVarAttrLenForCreateTable(tupdesc, targetList, rangeTable);
+
+ intoRelationId = heap_create(intoName,
+ intoName, /* not used */
+ archiveMode,
+ DEFAULT_SMGR,
+ tupdesc);
+#ifdef NOT_USED /* it's copy ... */
+ resetVarAttrLenForCreateTable(tupdesc);
+#endif
+ FreeTupleDesc(tupdesc);
+
+ /* ----------------
+ * XXX rather than having to call setheapoverride(true)
+ * and then back to false, we should change the
+ * arguments to heap_open() instead..
+ * ----------------
+ */
+ setheapoverride(true);
+
+ intoRelationDesc = heap_open(intoRelationId);
+
+ setheapoverride(false);
+ }
+ }
+ }
+
+ estate->es_into_relation_descriptor = intoRelationDesc;
+
+ /* ----------------
+ * return the type information..
+ * ----------------
+ */
/*
- attinfo = (AttrInfo *)palloc(sizeof(AttrInfo));
- attinfo->numAttr = len;
- attinfo->attrs = tupType->attrs;
+ attinfo = (AttrInfo *)palloc(sizeof(AttrInfo));
+ attinfo->numAttr = len;
+ attinfo->attrs = tupType->attrs;
*/
- return tupType;
+ return tupType;
}
/* ----------------------------------------------------------------
- * EndPlan
- *
- * Cleans up the query plan -- closes files and free up storages
+ * EndPlan
+ *
+ * Cleans up the query plan -- closes files and free up storages
* ----------------------------------------------------------------
*/
static void
-EndPlan(Plan *plan, EState *estate)
+EndPlan(Plan * plan, EState * estate)
{
- RelationInfo *resultRelationInfo;
- Relation intoRelationDesc;
-
- /* ----------------
- * get information from state
- * ----------------
- */
- resultRelationInfo = estate->es_result_relation_info;
- intoRelationDesc = estate->es_into_relation_descriptor;
-
- /* ----------------
- * shut down the query
- * ----------------
- */
- ExecEndNode(plan, plan);
-
- /* ----------------
- * destroy the executor "tuple" table.
- * ----------------
- */
- {
- TupleTable tupleTable = (TupleTable) estate->es_tupleTable;
- ExecDestroyTupleTable(tupleTable,true); /* was missing last arg */
- estate->es_tupleTable = NULL;
- }
-
- /* ----------------
- * close the result relations if necessary
- * ----------------
- */
- if (resultRelationInfo != NULL) {
- Relation resultRelationDesc;
-
- resultRelationDesc = resultRelationInfo->ri_RelationDesc;
- heap_close(resultRelationDesc);
-
+ RelationInfo *resultRelationInfo;
+ Relation intoRelationDesc;
+
/* ----------------
- * close indices on the result relation
+ * get information from state
* ----------------
*/
- ExecCloseIndices(resultRelationInfo);
- }
-
- /* ----------------
- * close the "into" relation if necessary
- * ----------------
- */
- if (intoRelationDesc != NULL) {
- heap_close(intoRelationDesc);
- }
+ resultRelationInfo = estate->es_result_relation_info;
+ intoRelationDesc = estate->es_into_relation_descriptor;
+
+ /* ----------------
+ * shut down the query
+ * ----------------
+ */
+ ExecEndNode(plan, plan);
+
+ /* ----------------
+ * destroy the executor "tuple" table.
+ * ----------------
+ */
+ {
+ TupleTable tupleTable = (TupleTable) estate->es_tupleTable;
+
+ ExecDestroyTupleTable(tupleTable, true); /* was missing last arg */
+ estate->es_tupleTable = NULL;
+ }
+
+ /* ----------------
+ * close the result relations if necessary
+ * ----------------
+ */
+ if (resultRelationInfo != NULL)
+ {
+ Relation resultRelationDesc;
+
+ resultRelationDesc = resultRelationInfo->ri_RelationDesc;
+ heap_close(resultRelationDesc);
+
+ /* ----------------
+ * close indices on the result relation
+ * ----------------
+ */
+ ExecCloseIndices(resultRelationInfo);
+ }
+
+ /* ----------------
+ * close the "into" relation if necessary
+ * ----------------
+ */
+ if (intoRelationDesc != NULL)
+ {
+ heap_close(intoRelationDesc);
+ }
}
/* ----------------------------------------------------------------
- * ExecutePlan
- *
- * processes the query plan to retrieve 'tupleCount' tuples in the
- * direction specified.
- * Retrieves all tuples if tupleCount is 0
+ * ExecutePlan
+ *
+ * processes the query plan to retrieve 'tupleCount' tuples in the
+ * direction specified.
+ * Retrieves all tuples if tupleCount is 0
+ *
+ * result is either a slot containing a tuple in the case
+ * of a RETRIEVE or NULL otherwise.
*
- * result is either a slot containing a tuple in the case
- * of a RETRIEVE or NULL otherwise.
- *
* ----------------------------------------------------------------
*/
@@ -660,688 +698,704 @@ EndPlan(Plan *plan, EState *estate)
user can see it*/
static TupleTableSlot *
-ExecutePlan(EState *estate,
- Plan *plan,
- Query *parseTree,
- CmdType operation,
- int numberTuples,
- ScanDirection direction,
- void (*printfunc)())
+ExecutePlan(EState * estate,
+ Plan * plan,
+ Query * parseTree,
+ CmdType operation,
+ int numberTuples,
+ ScanDirection direction,
+ void (*printfunc) ())
{
- JunkFilter *junkfilter;
-
- TupleTableSlot *slot;
- ItemPointer tupleid = NULL;
- ItemPointerData tuple_ctid;
- int current_tuple_count;
- TupleTableSlot *result;
-
- /* ----------------
- * initialize local variables
- * ----------------
- */
- slot = NULL;
- current_tuple_count = 0;
- result = NULL;
-
- /* ----------------
- * Set the direction.
- * ----------------
- */
- estate->es_direction = direction;
-
- /* ----------------
- * Loop until we've processed the proper number
- * of tuples from the plan..
- * ----------------
- */
-
- for(;;) {
- if (operation != CMD_NOTIFY) {
- /* ----------------
- * Execute the plan and obtain a tuple
- * ----------------
- */
- /* at the top level, the parent of a plan (2nd arg) is itself */
- slot = ExecProcNode(plan,plan);
-
- /* ----------------
- * if the tuple is null, then we assume
- * there is nothing more to process so
- * we just return null...
- * ----------------
- */
- if (TupIsNull(slot)) {
- result = NULL;
- break;
- }
- }
-
+ JunkFilter *junkfilter;
+
+ TupleTableSlot *slot;
+ ItemPointer tupleid = NULL;
+ ItemPointerData tuple_ctid;
+ int current_tuple_count;
+ TupleTableSlot *result;
+
/* ----------------
- * if we have a junk filter, then project a new
- * tuple with the junk removed.
- *
- * Store this new "clean" tuple in the place of the
- * original tuple.
- *
- * Also, extract all the junk ifnormation we need.
+ * initialize local variables
* ----------------
*/
- if ((junkfilter = estate->es_junkFilter) != (JunkFilter*)NULL) {
- Datum datum;
-/* NameData attrName; */
- HeapTuple newTuple;
- bool isNull;
-
- /* ---------------
- * extract the 'ctid' junk attribute.
- * ---------------
- */
- if (operation == CMD_UPDATE || operation == CMD_DELETE) {
- if (! ExecGetJunkAttribute(junkfilter,
- slot,
- "ctid",
- &datum,
- &isNull))
- elog(WARN,"ExecutePlan: NO (junk) `ctid' was found!");
-
- if (isNull)
- elog(WARN,"ExecutePlan: (junk) `ctid' is NULL!");
-
- tupleid = (ItemPointer) DatumGetPointer(datum);
- tuple_ctid = *tupleid; /* make sure we don't free the ctid!! */
- tupleid = &tuple_ctid;
- }
-
- /* ---------------
- * Finally create a new "clean" tuple with all junk attributes
- * removed
- * ---------------
- */
- newTuple = ExecRemoveJunk(junkfilter, slot);
-
- slot = ExecStoreTuple(newTuple, /* tuple to store */
- slot, /* destination slot */
- InvalidBuffer,/* this tuple has no buffer */
- true); /* tuple should be pfreed */
- } /* if (junkfilter... */
-
+ slot = NULL;
+ current_tuple_count = 0;
+ result = NULL;
+
/* ----------------
- * now that we have a tuple, do the appropriate thing
- * with it.. either return it to the user, add
- * it to a relation someplace, delete it from a
- * relation, or modify some of it's attributes.
+ * Set the direction.
* ----------------
*/
-
- switch(operation) {
- case CMD_SELECT:
- ExecRetrieve(slot, /* slot containing tuple */
- printfunc, /* print function */
- estate); /* */
- result = slot;
- break;
-
- case CMD_INSERT:
- ExecAppend(slot, tupleid, estate);
- result = NULL;
- break;
-
- case CMD_DELETE:
- ExecDelete(slot, tupleid, estate);
- result = NULL;
- break;
-
- case CMD_UPDATE:
- ExecReplace(slot, tupleid, estate, parseTree);
- result = NULL;
- break;
-
- /* Total hack. I'm ignoring any accessor functions for
- Relation, RelationTupleForm, NameData.
- Assuming that NameData.data has offset 0.
- */
- case CMD_NOTIFY: {
- RelationInfo *rInfo = estate->es_result_relation_info;
- Relation rDesc = rInfo->ri_RelationDesc;
- Async_Notify(rDesc->rd_rel->relname.data);
- result = NULL;
- current_tuple_count = 0;
- numberTuples = 1;
- elog(DEBUG, "ExecNotify %s",&rDesc->rd_rel->relname);
- }
- break;
-
- default:
- elog(DEBUG, "ExecutePlan: unknown operation in queryDesc");
- result = NULL;
- break;
+ estate->es_direction = direction;
+
+ /* ----------------
+ * Loop until we've processed the proper number
+ * of tuples from the plan..
+ * ----------------
+ */
+
+ for (;;)
+ {
+ if (operation != CMD_NOTIFY)
+ {
+ /* ----------------
+ * Execute the plan and obtain a tuple
+ * ----------------
+ */
+ /* at the top level, the parent of a plan (2nd arg) is itself */
+ slot = ExecProcNode(plan, plan);
+
+ /* ----------------
+ * if the tuple is null, then we assume
+ * there is nothing more to process so
+ * we just return null...
+ * ----------------
+ */
+ if (TupIsNull(slot))
+ {
+ result = NULL;
+ break;
+ }
+ }
+
+ /* ----------------
+ * if we have a junk filter, then project a new
+ * tuple with the junk removed.
+ *
+ * Store this new "clean" tuple in the place of the
+ * original tuple.
+ *
+ * Also, extract all the junk ifnormation we need.
+ * ----------------
+ */
+ if ((junkfilter = estate->es_junkFilter) != (JunkFilter *) NULL)
+ {
+ Datum datum;
+
+/* NameData attrName; */
+ HeapTuple newTuple;
+ bool isNull;
+
+ /* ---------------
+ * extract the 'ctid' junk attribute.
+ * ---------------
+ */
+ if (operation == CMD_UPDATE || operation == CMD_DELETE)
+ {
+ if (!ExecGetJunkAttribute(junkfilter,
+ slot,
+ "ctid",
+ &datum,
+ &isNull))
+ elog(WARN, "ExecutePlan: NO (junk) `ctid' was found!");
+
+ if (isNull)
+ elog(WARN, "ExecutePlan: (junk) `ctid' is NULL!");
+
+ tupleid = (ItemPointer) DatumGetPointer(datum);
+ tuple_ctid = *tupleid; /* make sure we don't free the
+ * ctid!! */
+ tupleid = &tuple_ctid;
+ }
+
+ /* ---------------
+ * Finally create a new "clean" tuple with all junk attributes
+ * removed
+ * ---------------
+ */
+ newTuple = ExecRemoveJunk(junkfilter, slot);
+
+ slot = ExecStoreTuple(newTuple, /* tuple to store */
+ slot, /* destination slot */
+ InvalidBuffer, /* this tuple has no
+ * buffer */
+ true); /* tuple should be pfreed */
+ } /* if (junkfilter... */
+
+ /* ----------------
+ * now that we have a tuple, do the appropriate thing
+ * with it.. either return it to the user, add
+ * it to a relation someplace, delete it from a
+ * relation, or modify some of it's attributes.
+ * ----------------
+ */
+
+ switch (operation)
+ {
+ case CMD_SELECT:
+ ExecRetrieve(slot, /* slot containing tuple */
+ printfunc, /* print function */
+ estate); /* */
+ result = slot;
+ break;
+
+ case CMD_INSERT:
+ ExecAppend(slot, tupleid, estate);
+ result = NULL;
+ break;
+
+ case CMD_DELETE:
+ ExecDelete(slot, tupleid, estate);
+ result = NULL;
+ break;
+
+ case CMD_UPDATE:
+ ExecReplace(slot, tupleid, estate, parseTree);
+ result = NULL;
+ break;
+
+ /*
+ * Total hack. I'm ignoring any accessor functions for
+ * Relation, RelationTupleForm, NameData. Assuming that
+ * NameData.data has offset 0.
+ */
+ case CMD_NOTIFY:
+ {
+ RelationInfo *rInfo = estate->es_result_relation_info;
+ Relation rDesc = rInfo->ri_RelationDesc;
+
+ Async_Notify(rDesc->rd_rel->relname.data);
+ result = NULL;
+ current_tuple_count = 0;
+ numberTuples = 1;
+ elog(DEBUG, "ExecNotify %s", &rDesc->rd_rel->relname);
+ }
+ break;
+
+ default:
+ elog(DEBUG, "ExecutePlan: unknown operation in queryDesc");
+ result = NULL;
+ break;
+ }
+ /* ----------------
+ * check our tuple count.. if we've returned the
+ * proper number then return, else loop again and
+ * process more tuples..
+ * ----------------
+ */
+ current_tuple_count += 1;
+ if (numberTuples == current_tuple_count)
+ break;
}
+
/* ----------------
- * check our tuple count.. if we've returned the
- * proper number then return, else loop again and
- * process more tuples..
+ * here, result is either a slot containing a tuple in the case
+ * of a RETRIEVE or NULL otherwise.
* ----------------
*/
- current_tuple_count += 1;
- if (numberTuples == current_tuple_count)
- break;
- }
-
- /* ----------------
- * here, result is either a slot containing a tuple in the case
- * of a RETRIEVE or NULL otherwise.
- * ----------------
- */
- return result;
+ return result;
}
/* ----------------------------------------------------------------
- * ExecRetrieve
+ * ExecRetrieve
*
- * RETRIEVEs are easy.. we just pass the tuple to the appropriate
- * print function. The only complexity is when we do a
- * "retrieve into", in which case we insert the tuple into
- * the appropriate relation (note: this is a newly created relation
- * so we don't need to worry about indices or locks.)
+ * RETRIEVEs are easy.. we just pass the tuple to the appropriate
+ * print function. The only complexity is when we do a
+ * "retrieve into", in which case we insert the tuple into
+ * the appropriate relation (note: this is a newly created relation
+ * so we don't need to worry about indices or locks.)
* ----------------------------------------------------------------
*/
static void
-ExecRetrieve(TupleTableSlot *slot,
- void (*printfunc)(),
- EState *estate)
+ExecRetrieve(TupleTableSlot * slot,
+ void (*printfunc) (),
+ EState * estate)
{
- HeapTuple tuple;
- TupleDesc attrtype;
-
- /* ----------------
- * get the heap tuple out of the tuple table slot
- * ----------------
- */
- tuple = slot->val;
- attrtype = slot->ttc_tupleDescriptor;
-
- /* ----------------
- * insert the tuple into the "into relation"
- * ----------------
- */
- if ( estate->es_into_relation_descriptor != NULL )
- {
- heap_insert (estate->es_into_relation_descriptor, tuple);
- IncrAppended();
- }
-
- /* ----------------
- * send the tuple to the front end (or the screen)
- * ----------------
- */
- (*printfunc)(tuple, attrtype);
- IncrRetrieved();
- (estate->es_processed)++;
+ HeapTuple tuple;
+ TupleDesc attrtype;
+
+ /* ----------------
+ * get the heap tuple out of the tuple table slot
+ * ----------------
+ */
+ tuple = slot->val;
+ attrtype = slot->ttc_tupleDescriptor;
+
+ /* ----------------
+ * insert the tuple into the "into relation"
+ * ----------------
+ */
+ if (estate->es_into_relation_descriptor != NULL)
+ {
+ heap_insert(estate->es_into_relation_descriptor, tuple);
+ IncrAppended();
+ }
+
+ /* ----------------
+ * send the tuple to the front end (or the screen)
+ * ----------------
+ */
+ (*printfunc) (tuple, attrtype);
+ IncrRetrieved();
+ (estate->es_processed)++;
}
/* ----------------------------------------------------------------
- * ExecAppend
+ * ExecAppend
*
- * APPENDs are trickier.. we have to insert the tuple into
- * the base relation and insert appropriate tuples into the
- * index relations.
+ * APPENDs are trickier.. we have to insert the tuple into
+ * the base relation and insert appropriate tuples into the
+ * index relations.
* ----------------------------------------------------------------
*/
static void
-ExecAppend(TupleTableSlot *slot,
- ItemPointer tupleid,
- EState *estate)
+ExecAppend(TupleTableSlot * slot,
+ ItemPointer tupleid,
+ EState * estate)
{
- HeapTuple tuple;
- RelationInfo *resultRelationInfo;
- Relation resultRelationDesc;
- int numIndices;
- Oid newId;
-
- /* ----------------
- * get the heap tuple out of the tuple table slot
- * ----------------
- */
- tuple = slot->val;
-
- /* ----------------
- * get information on the result relation
- * ----------------
- */
- resultRelationInfo = estate->es_result_relation_info;
- resultRelationDesc = resultRelationInfo->ri_RelationDesc;
-
- /* ----------------
- * have to add code to preform unique checking here.
- * cim -12/1/89
- * ----------------
- */
-
- /* BEFORE ROW INSERT Triggers */
- if ( resultRelationDesc->trigdesc &&
- resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] > 0 )
- {
- HeapTuple newtuple;
-
- newtuple = ExecBRInsertTriggers (resultRelationDesc, tuple);
-
- if ( newtuple == NULL ) /* "do nothing" */
- return;
-
- if ( newtuple != tuple ) /* modified by Trigger(s) */
- {
- Assert ( slot->ttc_shouldFree );
- pfree (tuple);
- slot->val = tuple = newtuple;
- }
- }
-
- /* ----------------
- * Check the constraints of a tuple
- * ----------------
- */
-
- if ( resultRelationDesc->rd_att->constr )
- {
- HeapTuple newtuple;
-
- newtuple = ExecConstraints ("ExecAppend", resultRelationDesc, tuple);
-
- if ( newtuple != tuple ) /* modified by DEFAULT */
- {
- Assert ( slot->ttc_shouldFree );
- pfree (tuple);
- slot->val = tuple = newtuple;
- }
- }
-
- /* ----------------
- * insert the tuple
- * ----------------
- */
- newId = heap_insert(resultRelationDesc, /* relation desc */
- tuple); /* heap tuple */
- IncrAppended();
-
- /* ----------------
- * process indices
- *
- * Note: heap_insert adds a new tuple to a relation. As a side
- * effect, the tupleid of the new tuple is placed in the new
- * tuple's t_ctid field.
- * ----------------
- */
- numIndices = resultRelationInfo->ri_NumIndices;
- if (numIndices > 0) {
- ExecInsertIndexTuples(slot, &(tuple->t_ctid), estate, false);
- }
- (estate->es_processed)++;
- estate->es_lastoid = newId;
-
- /* AFTER ROW INSERT Triggers */
- if ( resultRelationDesc->trigdesc &&
- resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0 )
- ExecARInsertTriggers (resultRelationDesc, tuple);
+ HeapTuple tuple;
+ RelationInfo *resultRelationInfo;
+ Relation resultRelationDesc;
+ int numIndices;
+ Oid newId;
+
+ /* ----------------
+ * get the heap tuple out of the tuple table slot
+ * ----------------
+ */
+ tuple = slot->val;
+
+ /* ----------------
+ * get information on the result relation
+ * ----------------
+ */
+ resultRelationInfo = estate->es_result_relation_info;
+ resultRelationDesc = resultRelationInfo->ri_RelationDesc;
+
+ /* ----------------
+ * have to add code to preform unique checking here.
+ * cim -12/1/89
+ * ----------------
+ */
+
+ /* BEFORE ROW INSERT Triggers */
+ if (resultRelationDesc->trigdesc &&
+ resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
+ {
+ HeapTuple newtuple;
+
+ newtuple = ExecBRInsertTriggers(resultRelationDesc, tuple);
+
+ if (newtuple == NULL) /* "do nothing" */
+ return;
+
+ if (newtuple != tuple) /* modified by Trigger(s) */
+ {
+ Assert(slot->ttc_shouldFree);
+ pfree(tuple);
+ slot->val = tuple = newtuple;
+ }
+ }
+
+ /* ----------------
+ * Check the constraints of a tuple
+ * ----------------
+ */
+
+ if (resultRelationDesc->rd_att->constr)
+ {
+ HeapTuple newtuple;
+
+ newtuple = ExecConstraints("ExecAppend", resultRelationDesc, tuple);
+
+ if (newtuple != tuple) /* modified by DEFAULT */
+ {
+ Assert(slot->ttc_shouldFree);
+ pfree(tuple);
+ slot->val = tuple = newtuple;
+ }
+ }
+
+ /* ----------------
+ * insert the tuple
+ * ----------------
+ */
+ newId = heap_insert(resultRelationDesc, /* relation desc */
+ tuple); /* heap tuple */
+ IncrAppended();
+
+ /* ----------------
+ * process indices
+ *
+ * Note: heap_insert adds a new tuple to a relation. As a side
+ * effect, the tupleid of the new tuple is placed in the new
+ * tuple's t_ctid field.
+ * ----------------
+ */
+ numIndices = resultRelationInfo->ri_NumIndices;
+ if (numIndices > 0)
+ {
+ ExecInsertIndexTuples(slot, &(tuple->t_ctid), estate, false);
+ }
+ (estate->es_processed)++;
+ estate->es_lastoid = newId;
+
+ /* AFTER ROW INSERT Triggers */
+ if (resultRelationDesc->trigdesc &&
+ resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0)
+ ExecARInsertTriggers(resultRelationDesc, tuple);
}
/* ----------------------------------------------------------------
- * ExecDelete
+ * ExecDelete
*
- * DELETE is like append, we delete the tuple and its
- * index tuples.
+ * DELETE is like append, we delete the tuple and its
+ * index tuples.
* ----------------------------------------------------------------
*/
static void
-ExecDelete(TupleTableSlot *slot,
- ItemPointer tupleid,
- EState *estate)
+ExecDelete(TupleTableSlot * slot,
+ ItemPointer tupleid,
+ EState * estate)
{
- RelationInfo *resultRelationInfo;
- Relation resultRelationDesc;
-
- /* ----------------
- * get the result relation information
- * ----------------
- */
- resultRelationInfo = estate->es_result_relation_info;
- resultRelationDesc = resultRelationInfo->ri_RelationDesc;
-
- /* BEFORE ROW DELETE Triggers */
- if ( resultRelationDesc->trigdesc &&
- resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_DELETE] > 0 )
- {
- bool dodelete;
-
- dodelete = ExecBRDeleteTriggers (resultRelationDesc, tupleid);
-
- if ( !dodelete ) /* "do nothing" */
- return;
- }
-
- /* ----------------
- * delete the tuple
- * ----------------
- */
- if ( heap_delete(resultRelationDesc, /* relation desc */
- tupleid) ) /* item pointer to tuple */
- return;
-
- IncrDeleted();
- (estate->es_processed)++;
-
- /* ----------------
- * Note: Normally one would think that we have to
- * delete index tuples associated with the
- * heap tuple now..
- *
- * ... but in POSTGRES, we have no need to do this
- * because the vacuum daemon automatically
- * opens an index scan and deletes index tuples
- * when it finds deleted heap tuples. -cim 9/27/89
- * ----------------
- */
-
- /* AFTER ROW DELETE Triggers */
- if ( resultRelationDesc->trigdesc &&
- resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0 )
- ExecARDeleteTriggers (resultRelationDesc, tupleid);
+ RelationInfo *resultRelationInfo;
+ Relation resultRelationDesc;
+
+ /* ----------------
+ * get the result relation information
+ * ----------------
+ */
+ resultRelationInfo = estate->es_result_relation_info;
+ resultRelationDesc = resultRelationInfo->ri_RelationDesc;
+
+ /* BEFORE ROW DELETE Triggers */
+ if (resultRelationDesc->trigdesc &&
+ resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_DELETE] > 0)
+ {
+ bool dodelete;
+
+ dodelete = ExecBRDeleteTriggers(resultRelationDesc, tupleid);
+
+ if (!dodelete) /* "do nothing" */
+ return;
+ }
+
+ /* ----------------
+ * delete the tuple
+ * ----------------
+ */
+ if (heap_delete(resultRelationDesc, /* relation desc */
+ tupleid)) /* item pointer to tuple */
+ return;
+
+ IncrDeleted();
+ (estate->es_processed)++;
+
+ /* ----------------
+ * Note: Normally one would think that we have to
+ * delete index tuples associated with the
+ * heap tuple now..
+ *
+ * ... but in POSTGRES, we have no need to do this
+ * because the vacuum daemon automatically
+ * opens an index scan and deletes index tuples
+ * when it finds deleted heap tuples. -cim 9/27/89
+ * ----------------
+ */
+
+ /* AFTER ROW DELETE Triggers */
+ if (resultRelationDesc->trigdesc &&
+ resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0)
+ ExecARDeleteTriggers(resultRelationDesc, tupleid);
}
/* ----------------------------------------------------------------
- * ExecReplace
+ * ExecReplace
*
- * note: we can't run replace queries with transactions
- * off because replaces are actually appends and our
- * scan will mistakenly loop forever, replacing the tuple
- * it just appended.. This should be fixed but until it
- * is, we don't want to get stuck in an infinite loop
- * which corrupts your database..
+ * note: we can't run replace queries with transactions
+ * off because replaces are actually appends and our
+ * scan will mistakenly loop forever, replacing the tuple
+ * it just appended.. This should be fixed but until it
+ * is, we don't want to get stuck in an infinite loop
+ * which corrupts your database..
* ----------------------------------------------------------------
*/
static void
-ExecReplace(TupleTableSlot *slot,
- ItemPointer tupleid,
- EState *estate,
- Query *parseTree)
+ExecReplace(TupleTableSlot * slot,
+ ItemPointer tupleid,
+ EState * estate,
+ Query * parseTree)
{
- HeapTuple tuple;
- RelationInfo *resultRelationInfo;
- Relation resultRelationDesc;
- int numIndices;
-
- /* ----------------
- * abort the operation if not running transactions
- * ----------------
- */
- if (IsBootstrapProcessingMode()) {
- elog(DEBUG, "ExecReplace: replace can't run without transactions");
- return;
- }
-
- /* ----------------
- * get the heap tuple out of the tuple table slot
- * ----------------
- */
- tuple = slot->val;
-
- /* ----------------
- * get the result relation information
- * ----------------
- */
- resultRelationInfo = estate->es_result_relation_info;
- resultRelationDesc = resultRelationInfo->ri_RelationDesc;
-
- /* ----------------
- * have to add code to preform unique checking here.
- * in the event of unique tuples, this becomes a deletion
- * of the original tuple affected by the replace.
- * cim -12/1/89
- * ----------------
- */
-
- /* BEFORE ROW UPDATE Triggers */
- if ( resultRelationDesc->trigdesc &&
- resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE] > 0 )
- {
- HeapTuple newtuple;
-
- newtuple = ExecBRUpdateTriggers (resultRelationDesc, tupleid, tuple);
-
- if ( newtuple == NULL ) /* "do nothing" */
- return;
-
- if ( newtuple != tuple ) /* modified by Trigger(s) */
- {
- Assert ( slot->ttc_shouldFree );
- pfree (tuple);
- slot->val = tuple = newtuple;
- }
- }
-
- /* ----------------
- * Check the constraints of a tuple
- * ----------------
- */
-
- if ( resultRelationDesc->rd_att->constr )
- {
- HeapTuple newtuple;
-
- newtuple = ExecConstraints ("ExecReplace", resultRelationDesc, tuple);
-
- if ( newtuple != tuple ) /* modified by DEFAULT */
- {
- Assert ( slot->ttc_shouldFree );
- pfree (tuple);
- slot->val = tuple = newtuple;
- }
- }
-
- /* ----------------
- * replace the heap tuple
- *
- * Don't want to continue if our heap_replace didn't actually
- * do a replace. This would be the case if heap_replace
- * detected a non-functional update. -kw 12/30/93
- * ----------------
- */
- if (heap_replace(resultRelationDesc, /* relation desc */
- tupleid, /* item ptr of tuple to replace */
- tuple)) { /* replacement heap tuple */
- return;
- }
-
- IncrReplaced();
- (estate->es_processed)++;
-
- /* ----------------
- * Note: instead of having to update the old index tuples
- * associated with the heap tuple, all we do is form
- * and insert new index tuples.. This is because
- * replaces are actually deletes and inserts and
- * index tuple deletion is done automagically by
- * the vaccuum deamon.. All we do is insert new
- * index tuples. -cim 9/27/89
- * ----------------
- */
-
- /* ----------------
- * process indices
- *
- * heap_replace updates a tuple in the base relation by invalidating
- * it and then appending a new tuple to the relation. As a side
- * effect, the tupleid of the new tuple is placed in the new
- * tuple's t_ctid field. So we now insert index tuples using
- * the new tupleid stored there.
- * ----------------
- */
-
- numIndices = resultRelationInfo->ri_NumIndices;
- if (numIndices > 0) {
- ExecInsertIndexTuples(slot, &(tuple->t_ctid), estate, true);
- }
-
- /* AFTER ROW UPDATE Triggers */
- if ( resultRelationDesc->trigdesc &&
- resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0 )
- ExecARUpdateTriggers (resultRelationDesc, tupleid, tuple);
+ HeapTuple tuple;
+ RelationInfo *resultRelationInfo;
+ Relation resultRelationDesc;
+ int numIndices;
+
+ /* ----------------
+ * abort the operation if not running transactions
+ * ----------------
+ */
+ if (IsBootstrapProcessingMode())
+ {
+ elog(DEBUG, "ExecReplace: replace can't run without transactions");
+ return;
+ }
+
+ /* ----------------
+ * get the heap tuple out of the tuple table slot
+ * ----------------
+ */
+ tuple = slot->val;
+
+ /* ----------------
+ * get the result relation information
+ * ----------------
+ */
+ resultRelationInfo = estate->es_result_relation_info;
+ resultRelationDesc = resultRelationInfo->ri_RelationDesc;
+
+ /* ----------------
+ * have to add code to preform unique checking here.
+ * in the event of unique tuples, this becomes a deletion
+ * of the original tuple affected by the replace.
+ * cim -12/1/89
+ * ----------------
+ */
+
+ /* BEFORE ROW UPDATE Triggers */
+ if (resultRelationDesc->trigdesc &&
+ resultRelationDesc->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE] > 0)
+ {
+ HeapTuple newtuple;
+
+ newtuple = ExecBRUpdateTriggers(resultRelationDesc, tupleid, tuple);
+
+ if (newtuple == NULL) /* "do nothing" */
+ return;
+
+ if (newtuple != tuple) /* modified by Trigger(s) */
+ {
+ Assert(slot->ttc_shouldFree);
+ pfree(tuple);
+ slot->val = tuple = newtuple;
+ }
+ }
+
+ /* ----------------
+ * Check the constraints of a tuple
+ * ----------------
+ */
+
+ if (resultRelationDesc->rd_att->constr)
+ {
+ HeapTuple newtuple;
+
+ newtuple = ExecConstraints("ExecReplace", resultRelationDesc, tuple);
+
+ if (newtuple != tuple) /* modified by DEFAULT */
+ {
+ Assert(slot->ttc_shouldFree);
+ pfree(tuple);
+ slot->val = tuple = newtuple;
+ }
+ }
+
+ /* ----------------
+ * replace the heap tuple
+ *
+ * Don't want to continue if our heap_replace didn't actually
+ * do a replace. This would be the case if heap_replace
+ * detected a non-functional update. -kw 12/30/93
+ * ----------------
+ */
+ if (heap_replace(resultRelationDesc, /* relation desc */
+ tupleid, /* item ptr of tuple to replace */
+ tuple))
+ { /* replacement heap tuple */
+ return;
+ }
+
+ IncrReplaced();
+ (estate->es_processed)++;
+
+ /* ----------------
+ * Note: instead of having to update the old index tuples
+ * associated with the heap tuple, all we do is form
+ * and insert new index tuples.. This is because
+ * replaces are actually deletes and inserts and
+ * index tuple deletion is done automagically by
+ * the vaccuum deamon.. All we do is insert new
+ * index tuples. -cim 9/27/89
+ * ----------------
+ */
+
+ /* ----------------
+ * process indices
+ *
+ * heap_replace updates a tuple in the base relation by invalidating
+ * it and then appending a new tuple to the relation. As a side
+ * effect, the tupleid of the new tuple is placed in the new
+ * tuple's t_ctid field. So we now insert index tuples using
+ * the new tupleid stored there.
+ * ----------------
+ */
+
+ numIndices = resultRelationInfo->ri_NumIndices;
+ if (numIndices > 0)
+ {
+ ExecInsertIndexTuples(slot, &(tuple->t_ctid), estate, true);
+ }
+
+ /* AFTER ROW UPDATE Triggers */
+ if (resultRelationDesc->trigdesc &&
+ resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0)
+ ExecARUpdateTriggers(resultRelationDesc, tupleid, tuple);
}
-static HeapTuple
-ExecAttrDefault (Relation rel, HeapTuple tuple)
+static HeapTuple
+ExecAttrDefault(Relation rel, HeapTuple tuple)
{
- int ndef = rel->rd_att->constr->num_defval;
- AttrDefault *attrdef = rel->rd_att->constr->defval;
- ExprContext *econtext = makeNode (ExprContext);
- HeapTuple newtuple;
- Node *expr;
- bool isnull;
- bool isdone;
- Datum val;
- Datum *replValue = NULL;
- char *replNull = NULL;
- char *repl = NULL;
- int i;
-
- econtext->ecxt_scantuple = NULL; /* scan tuple slot */
- econtext->ecxt_innertuple = NULL; /* inner tuple slot */
- econtext->ecxt_outertuple = NULL; /* outer tuple slot */
- econtext->ecxt_relation = NULL; /* relation */
- econtext->ecxt_relid = 0; /* relid */
- econtext->ecxt_param_list_info = NULL; /* param list info */
- econtext->ecxt_range_table = NULL; /* range table */
- for (i = 0; i < ndef; i++)
- {
- if ( !heap_attisnull (tuple, attrdef[i].adnum) )
- continue;
- expr = (Node*) stringToNode (attrdef[i].adbin);
-
- val = ExecEvalExpr (expr, econtext, &isnull, &isdone);
-
- pfree (expr);
-
- if ( isnull )
- continue;
-
- if ( repl == NULL )
- {
- repl = (char*) palloc (rel->rd_att->natts * sizeof (char));
- replNull = (char*) palloc (rel->rd_att->natts * sizeof (char));
- replValue = (Datum*) palloc (rel->rd_att->natts * sizeof (Datum));
- memset (repl, ' ', rel->rd_att->natts * sizeof (char));
- }
-
- repl[attrdef[i].adnum - 1] = 'r';
- replNull[attrdef[i].adnum - 1] = ' ';
- replValue[attrdef[i].adnum - 1] = val;
-
- }
-
- pfree (econtext);
-
- if ( repl == NULL )
- return (tuple);
-
- newtuple = heap_modifytuple (tuple, InvalidBuffer, rel, replValue, replNull, repl);
-
- pfree (repl);
- pfree (replNull);
- pfree (replValue);
-
- return (newtuple);
-
+ int ndef = rel->rd_att->constr->num_defval;
+ AttrDefault *attrdef = rel->rd_att->constr->defval;
+ ExprContext *econtext = makeNode(ExprContext);
+ HeapTuple newtuple;
+ Node *expr;
+ bool isnull;
+ bool isdone;
+ Datum val;
+ Datum *replValue = NULL;
+ char *replNull = NULL;
+ char *repl = NULL;
+ int i;
+
+ econtext->ecxt_scantuple = NULL; /* scan tuple slot */
+ econtext->ecxt_innertuple = NULL; /* inner tuple slot */
+ econtext->ecxt_outertuple = NULL; /* outer tuple slot */
+ econtext->ecxt_relation = NULL; /* relation */
+ econtext->ecxt_relid = 0; /* relid */
+ econtext->ecxt_param_list_info = NULL; /* param list info */
+ econtext->ecxt_range_table = NULL; /* range table */
+ for (i = 0; i < ndef; i++)
+ {
+ if (!heap_attisnull(tuple, attrdef[i].adnum))
+ continue;
+ expr = (Node *) stringToNode(attrdef[i].adbin);
+
+ val = ExecEvalExpr(expr, econtext, &isnull, &isdone);
+
+ pfree(expr);
+
+ if (isnull)
+ continue;
+
+ if (repl == NULL)
+ {
+ repl = (char *) palloc(rel->rd_att->natts * sizeof(char));
+ replNull = (char *) palloc(rel->rd_att->natts * sizeof(char));
+ replValue = (Datum *) palloc(rel->rd_att->natts * sizeof(Datum));
+ memset(repl, ' ', rel->rd_att->natts * sizeof(char));
+ }
+
+ repl[attrdef[i].adnum - 1] = 'r';
+ replNull[attrdef[i].adnum - 1] = ' ';
+ replValue[attrdef[i].adnum - 1] = val;
+
+ }
+
+ pfree(econtext);
+
+ if (repl == NULL)
+ return (tuple);
+
+ newtuple = heap_modifytuple(tuple, InvalidBuffer, rel, replValue, replNull, repl);
+
+ pfree(repl);
+ pfree(replNull);
+ pfree(replValue);
+
+ return (newtuple);
+
}
-static char *
-ExecRelCheck (Relation rel, HeapTuple tuple)
+static char *
+ExecRelCheck(Relation rel, HeapTuple tuple)
{
- int ncheck = rel->rd_att->constr->num_check;
- ConstrCheck *check = rel->rd_att->constr->check;
- ExprContext *econtext = makeNode (ExprContext);
- TupleTableSlot *slot = makeNode (TupleTableSlot);
- RangeTblEntry *rte = makeNode (RangeTblEntry);
- List *rtlist;
- List *qual;
- bool res;
- int i;
-
- slot->val = tuple;
- slot->ttc_shouldFree = false;
- slot->ttc_descIsNew = true;
- slot->ttc_tupleDescriptor = rel->rd_att;
- slot->ttc_buffer = InvalidBuffer;
- slot->ttc_whichplan = -1;
- rte->relname = nameout (&(rel->rd_rel->relname));
- rte->timeRange = NULL;
- rte->refname = rte->relname;
- rte->relid = rel->rd_id;
- rte->inh = false;
- rte->archive = false;
- rte->inFromCl = true;
- rte->timeQual = NULL;
- rtlist = lcons (rte, NIL);
- econtext->ecxt_scantuple = slot; /* scan tuple slot */
- econtext->ecxt_innertuple = NULL; /* inner tuple slot */
- econtext->ecxt_outertuple = NULL; /* outer tuple slot */
- econtext->ecxt_relation = rel; /* relation */
- econtext->ecxt_relid = 0; /* relid */
- econtext->ecxt_param_list_info = NULL; /* param list info */
- econtext->ecxt_range_table = rtlist; /* range table */
-
- for (i = 0; i < ncheck; i++)
- {
- qual = (List*) stringToNode (check[i].ccbin);
-
- res = ExecQual (qual, econtext);
-
- pfree (qual);
-
- if ( !res )
- return (check[i].ccname);
- }
-
- pfree (slot);
- pfree (rte->relname);
- pfree (rte);
- pfree (rtlist);
- pfree (econtext);
-
- return ((char *) NULL);
-
+ int ncheck = rel->rd_att->constr->num_check;
+ ConstrCheck *check = rel->rd_att->constr->check;
+ ExprContext *econtext = makeNode(ExprContext);
+ TupleTableSlot *slot = makeNode(TupleTableSlot);
+ RangeTblEntry *rte = makeNode(RangeTblEntry);
+ List *rtlist;
+ List *qual;
+ bool res;
+ int i;
+
+ slot->val = tuple;
+ slot->ttc_shouldFree = false;
+ slot->ttc_descIsNew = true;
+ slot->ttc_tupleDescriptor = rel->rd_att;
+ slot->ttc_buffer = InvalidBuffer;
+ slot->ttc_whichplan = -1;
+ rte->relname = nameout(&(rel->rd_rel->relname));
+ rte->timeRange = NULL;
+ rte->refname = rte->relname;
+ rte->relid = rel->rd_id;
+ rte->inh = false;
+ rte->archive = false;
+ rte->inFromCl = true;
+ rte->timeQual = NULL;
+ rtlist = lcons(rte, NIL);
+ econtext->ecxt_scantuple = slot; /* scan tuple slot */
+ econtext->ecxt_innertuple = NULL; /* inner tuple slot */
+ econtext->ecxt_outertuple = NULL; /* outer tuple slot */
+ econtext->ecxt_relation = rel; /* relation */
+ econtext->ecxt_relid = 0; /* relid */
+ econtext->ecxt_param_list_info = NULL; /* param list info */
+ econtext->ecxt_range_table = rtlist; /* range table */
+
+ for (i = 0; i < ncheck; i++)
+ {
+ qual = (List *) stringToNode(check[i].ccbin);
+
+ res = ExecQual(qual, econtext);
+
+ pfree(qual);
+
+ if (!res)
+ return (check[i].ccname);
+ }
+
+ pfree(slot);
+ pfree(rte->relname);
+ pfree(rte);
+ pfree(rtlist);
+ pfree(econtext);
+
+ return ((char *) NULL);
+
}
HeapTuple
-ExecConstraints (char *caller, Relation rel, HeapTuple tuple)
+ExecConstraints(char *caller, Relation rel, HeapTuple tuple)
{
- HeapTuple newtuple = tuple;
-
- Assert ( rel->rd_att->constr );
-
- if ( rel->rd_att->constr->num_defval > 0 )
- newtuple = tuple = ExecAttrDefault (rel, tuple);
-
- if ( rel->rd_att->constr->has_not_null )
- {
- int attrChk;
-
- for (attrChk = 1; attrChk <= rel->rd_att->natts; attrChk++)
+ HeapTuple newtuple = tuple;
+
+ Assert(rel->rd_att->constr);
+
+ if (rel->rd_att->constr->num_defval > 0)
+ newtuple = tuple = ExecAttrDefault(rel, tuple);
+
+ if (rel->rd_att->constr->has_not_null)
{
- if (rel->rd_att->attrs[attrChk-1]->attnotnull && heap_attisnull (tuple,attrChk))
- elog(WARN,"%s: Fail to add null value in not null attribute %s",
- caller, rel->rd_att->attrs[attrChk-1]->attname.data);
- }
- }
-
- if ( rel->rd_att->constr->num_check > 0 )
- {
- char *failed;
-
- if ( ( failed = ExecRelCheck (rel, tuple) ) != NULL )
- elog(WARN,"%s: rejected due to CHECK constraint %s", caller, failed);
- }
-
- return (newtuple);
+ int attrChk;
+
+ for (attrChk = 1; attrChk <= rel->rd_att->natts; attrChk++)
+ {
+ if (rel->rd_att->attrs[attrChk - 1]->attnotnull && heap_attisnull(tuple, attrChk))
+ elog(WARN, "%s: Fail to add null value in not null attribute %s",
+ caller, rel->rd_att->attrs[attrChk - 1]->attname.data);
+ }
+ }
+
+ if (rel->rd_att->constr->num_check > 0)
+ {
+ char *failed;
+
+ if ((failed = ExecRelCheck(rel, tuple)) != NULL)
+ elog(WARN, "%s: rejected due to CHECK constraint %s", caller, failed);
+ }
+
+ return (newtuple);
}
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index f9e18d948f0..89caefd162e 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -1,75 +1,75 @@
/*-------------------------------------------------------------------------
*
* execProcnode.c--
- * contains dispatch functions which call the appropriate "initialize",
- * "get a tuple", and "cleanup" routines for the given node type.
- * If the node has children, then it will presumably call ExecInitNode,
- * ExecProcNode, or ExecEndNode on it's subnodes and do the appropriate
- * processing..
+ * contains dispatch functions which call the appropriate "initialize",
+ * "get a tuple", and "cleanup" routines for the given node type.
+ * If the node has children, then it will presumably call ExecInitNode,
+ * ExecProcNode, or ExecEndNode on it's subnodes and do the appropriate
+ * processing..
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.2 1996/10/31 10:11:27 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.3 1997/09/07 04:41:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * INTERFACE ROUTINES
- * ExecInitNode - initialize a plan node and it's subplans
- * ExecProcNode - get a tuple by executing the plan node
- * ExecEndNode - shut down a plan node and it's subplans
+ * INTERFACE ROUTINES
+ * ExecInitNode - initialize a plan node and it's subplans
+ * ExecProcNode - get a tuple by executing the plan node
+ * ExecEndNode - shut down a plan node and it's subplans
*
- * NOTES
- * This used to be three files. It is now all combined into
- * one file so that it is easier to keep ExecInitNode, ExecProcNode,
- * and ExecEndNode in sync when new nodes are added.
- *
- * EXAMPLE
- * suppose we want the age of the manager of the shoe department and
- * the number of employees in that department. so we have the query:
+ * NOTES
+ * This used to be three files. It is now all combined into
+ * one file so that it is easier to keep ExecInitNode, ExecProcNode,
+ * and ExecEndNode in sync when new nodes are added.
*
- * retrieve (DEPT.no_emps, EMP.age)
- * where EMP.name = DEPT.mgr and
- * DEPT.name = "shoe"
- *
- * Suppose the planner gives us the following plan:
- *
- * Nest Loop (DEPT.mgr = EMP.name)
- * / \
- * / \
- * Seq Scan Seq Scan
- * DEPT EMP
- * (name = "shoe")
- *
- * ExecStart() is called first.
- * It calls InitPlan() which calls ExecInitNode() on
- * the root of the plan -- the nest loop node.
+ * EXAMPLE
+ * suppose we want the age of the manager of the shoe department and
+ * the number of employees in that department. so we have the query:
*
- * * ExecInitNode() notices that it is looking at a nest loop and
- * as the code below demonstrates, it calls ExecInitNestLoop().
- * Eventually this calls ExecInitNode() on the right and left subplans
- * and so forth until the entire plan is initialized.
- *
- * * Then when ExecRun() is called, it calls ExecutePlan() which
- * calls ExecProcNode() repeatedly on the top node of the plan.
- * Each time this happens, ExecProcNode() will end up calling
- * ExecNestLoop(), which calls ExecProcNode() on its subplans.
- * Each of these subplans is a sequential scan so ExecSeqScan() is
- * called. The slots returned by ExecSeqScan() may contain
- * tuples which contain the attributes ExecNestLoop() uses to
- * form the tuples it returns.
+ * retrieve (DEPT.no_emps, EMP.age)
+ * where EMP.name = DEPT.mgr and
+ * DEPT.name = "shoe"
*
- * * Eventually ExecSeqScan() stops returning tuples and the nest
- * loop join ends. Lastly, ExecEnd() calls ExecEndNode() which
- * calls ExecEndNestLoop() which in turn calls ExecEndNode() on
- * its subplans which result in ExecEndSeqScan().
+ * Suppose the planner gives us the following plan:
*
- * This should show how the executor works by having
- * ExecInitNode(), ExecProcNode() and ExecEndNode() dispatch
- * their work to the appopriate node support routines which may
- * in turn call these routines themselves on their subplans.
+ * Nest Loop (DEPT.mgr = EMP.name)
+ * / \
+ * / \
+ * Seq Scan Seq Scan
+ * DEPT EMP
+ * (name = "shoe")
+ *
+ * ExecStart() is called first.
+ * It calls InitPlan() which calls ExecInitNode() on
+ * the root of the plan -- the nest loop node.
+ *
+ * * ExecInitNode() notices that it is looking at a nest loop and
+ * as the code below demonstrates, it calls ExecInitNestLoop().
+ * Eventually this calls ExecInitNode() on the right and left subplans
+ * and so forth until the entire plan is initialized.
+ *
+ * * Then when ExecRun() is called, it calls ExecutePlan() which
+ * calls ExecProcNode() repeatedly on the top node of the plan.
+ * Each time this happens, ExecProcNode() will end up calling
+ * ExecNestLoop(), which calls ExecProcNode() on its subplans.
+ * Each of these subplans is a sequential scan so ExecSeqScan() is
+ * called. The slots returned by ExecSeqScan() may contain
+ * tuples which contain the attributes ExecNestLoop() uses to
+ * form the tuples it returns.
+ *
+ * * Eventually ExecSeqScan() stops returning tuples and the nest
+ * loop join ends. Lastly, ExecEnd() calls ExecEndNode() which
+ * calls ExecEndNestLoop() which in turn calls ExecEndNode() on
+ * its subplans which result in ExecEndSeqScan().
+ *
+ * This should show how the executor works by having
+ * ExecInitNode(), ExecProcNode() and ExecEndNode() dispatch
+ * their work to the appopriate node support routines which may
+ * in turn call these routines themselves on their subplans.
*
*/
#include "postgres.h"
@@ -91,389 +91,393 @@
#include "executor/nodeTee.h"
/* ------------------------------------------------------------------------
- * ExecInitNode
- *
- * Recursively initializes all the nodes in the plan rooted
- * at 'node'.
- *
- * Initial States:
- * 'node' is the plan produced by the query planner
- *
- * returns TRUE/FALSE on whether the plan was successfully initialized
+ * ExecInitNode
+ *
+ * Recursively initializes all the nodes in the plan rooted
+ * at 'node'.
+ *
+ * Initial States:
+ * 'node' is the plan produced by the query planner
+ *
+ * returns TRUE/FALSE on whether the plan was successfully initialized
* ------------------------------------------------------------------------
*/
bool
-ExecInitNode(Plan *node, EState *estate, Plan *parent)
+ExecInitNode(Plan * node, EState * estate, Plan * parent)
{
- bool result;
-
- /* ----------------
- * do nothing when we get to the end
- * of a leaf on tree.
- * ----------------
- */
- if (node == NULL)
- return FALSE;
-
- switch(nodeTag(node)) {
- /* ----------------
- * control nodes
- * ----------------
- */
- case T_Result:
- result = ExecInitResult((Result *)node, estate, parent);
- break;
-
- case T_Append:
- result = ExecInitAppend((Append *)node, estate, parent);
- break;
-
- /* ----------------
- * scan nodes
- * ----------------
- */
- case T_SeqScan:
- result = ExecInitSeqScan((SeqScan *)node, estate, parent);
- break;
-
- case T_IndexScan:
- result = ExecInitIndexScan((IndexScan *)node, estate, parent);
- break;
-
- /* ----------------
- * join nodes
- * ----------------
- */
- case T_NestLoop:
- result = ExecInitNestLoop((NestLoop *)node, estate, parent);
- break;
-
- case T_MergeJoin:
- result = ExecInitMergeJoin((MergeJoin *)node, estate, parent);
- break;
-
+ bool result;
+
/* ----------------
- * materialization nodes
+ * do nothing when we get to the end
+ * of a leaf on tree.
* ----------------
*/
- case T_Material:
- result = ExecInitMaterial((Material *)node, estate, parent);
- break;
-
- case T_Sort:
- result = ExecInitSort((Sort *)node, estate, parent);
- break;
-
- case T_Unique:
- result = ExecInitUnique((Unique *)node, estate, parent);
- break;
-
- case T_Group:
- result = ExecInitGroup((Group *)node, estate, parent);
- break;
-
- case T_Agg:
- result = ExecInitAgg((Agg *)node, estate, parent);
- break;
-
- case T_Hash:
- result = ExecInitHash((Hash *)node, estate, parent);
- break;
-
- case T_HashJoin:
- result = ExecInitHashJoin((HashJoin *)node, estate, parent);
- break;
-
- case T_Tee:
- result = ExecInitTee((Tee*)node, estate, parent);
- break;
-
- default:
- elog(DEBUG, "ExecInitNode: node not yet supported: %d",
- nodeTag(node));
- result = FALSE;
- }
-
- return result;
+ if (node == NULL)
+ return FALSE;
+
+ switch (nodeTag(node))
+ {
+ /* ----------------
+ * control nodes
+ * ----------------
+ */
+ case T_Result:
+ result = ExecInitResult((Result *) node, estate, parent);
+ break;
+
+ case T_Append:
+ result = ExecInitAppend((Append *) node, estate, parent);
+ break;
+
+ /* ----------------
+ * scan nodes
+ * ----------------
+ */
+ case T_SeqScan:
+ result = ExecInitSeqScan((SeqScan *) node, estate, parent);
+ break;
+
+ case T_IndexScan:
+ result = ExecInitIndexScan((IndexScan *) node, estate, parent);
+ break;
+
+ /* ----------------
+ * join nodes
+ * ----------------
+ */
+ case T_NestLoop:
+ result = ExecInitNestLoop((NestLoop *) node, estate, parent);
+ break;
+
+ case T_MergeJoin:
+ result = ExecInitMergeJoin((MergeJoin *) node, estate, parent);
+ break;
+
+ /* ----------------
+ * materialization nodes
+ * ----------------
+ */
+ case T_Material:
+ result = ExecInitMaterial((Material *) node, estate, parent);
+ break;
+
+ case T_Sort:
+ result = ExecInitSort((Sort *) node, estate, parent);
+ break;
+
+ case T_Unique:
+ result = ExecInitUnique((Unique *) node, estate, parent);
+ break;
+
+ case T_Group:
+ result = ExecInitGroup((Group *) node, estate, parent);
+ break;
+
+ case T_Agg:
+ result = ExecInitAgg((Agg *) node, estate, parent);
+ break;
+
+ case T_Hash:
+ result = ExecInitHash((Hash *) node, estate, parent);
+ break;
+
+ case T_HashJoin:
+ result = ExecInitHashJoin((HashJoin *) node, estate, parent);
+ break;
+
+ case T_Tee:
+ result = ExecInitTee((Tee *) node, estate, parent);
+ break;
+
+ default:
+ elog(DEBUG, "ExecInitNode: node not yet supported: %d",
+ nodeTag(node));
+ result = FALSE;
+ }
+
+ return result;
}
/* ----------------------------------------------------------------
- * ExecProcNode
- *
- * Initial States:
- * the query tree must be initialized once by calling ExecInit.
+ * ExecProcNode
+ *
+ * Initial States:
+ * the query tree must be initialized once by calling ExecInit.
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecProcNode(Plan *node, Plan *parent)
+ExecProcNode(Plan * node, Plan * parent)
{
- TupleTableSlot *result;
-
- /* ----------------
- * deal with NULL nodes..
- * ----------------
- */
- if (node == NULL)
- return NULL;
-
- switch(nodeTag(node)) {
- /* ----------------
- * control nodes
- * ----------------
- */
- case T_Result:
- result = ExecResult((Result *)node);
- break;
-
- case T_Append:
- result = ExecProcAppend((Append *)node);
- break;
-
- /* ----------------
- * scan nodes
- * ----------------
- */
- case T_SeqScan:
- result = ExecSeqScan((SeqScan *)node);
- break;
-
- case T_IndexScan:
- result = ExecIndexScan((IndexScan *)node);
- break;
-
- /* ----------------
- * join nodes
- * ----------------
- */
- case T_NestLoop:
- result = ExecNestLoop((NestLoop *)node, parent);
- break;
-
- case T_MergeJoin:
- result = ExecMergeJoin((MergeJoin *)node);
- break;
-
+ TupleTableSlot *result;
+
/* ----------------
- * materialization nodes
+ * deal with NULL nodes..
* ----------------
*/
- case T_Material:
- result = ExecMaterial((Material *)node);
- break;
-
- case T_Sort:
- result = ExecSort((Sort *)node);
- break;
-
- case T_Unique:
- result = ExecUnique((Unique *)node);
- break;
-
- case T_Group:
- result = ExecGroup((Group *)node);
- break;
-
- case T_Agg:
- result = ExecAgg((Agg *)node);
- break;
-
- case T_Hash:
- result = ExecHash((Hash *)node);
- break;
-
- case T_HashJoin:
- result = ExecHashJoin((HashJoin *)node);
- break;
-
- case T_Tee:
- result = ExecTee((Tee*)node, parent);
- break;
-
- default:
- elog(DEBUG, "ExecProcNode: node not yet supported: %d",
- nodeTag(node));
- result = FALSE;
- }
-
- return result;
+ if (node == NULL)
+ return NULL;
+
+ switch (nodeTag(node))
+ {
+ /* ----------------
+ * control nodes
+ * ----------------
+ */
+ case T_Result:
+ result = ExecResult((Result *) node);
+ break;
+
+ case T_Append:
+ result = ExecProcAppend((Append *) node);
+ break;
+
+ /* ----------------
+ * scan nodes
+ * ----------------
+ */
+ case T_SeqScan:
+ result = ExecSeqScan((SeqScan *) node);
+ break;
+
+ case T_IndexScan:
+ result = ExecIndexScan((IndexScan *) node);
+ break;
+
+ /* ----------------
+ * join nodes
+ * ----------------
+ */
+ case T_NestLoop:
+ result = ExecNestLoop((NestLoop *) node, parent);
+ break;
+
+ case T_MergeJoin:
+ result = ExecMergeJoin((MergeJoin *) node);
+ break;
+
+ /* ----------------
+ * materialization nodes
+ * ----------------
+ */
+ case T_Material:
+ result = ExecMaterial((Material *) node);
+ break;
+
+ case T_Sort:
+ result = ExecSort((Sort *) node);
+ break;
+
+ case T_Unique:
+ result = ExecUnique((Unique *) node);
+ break;
+
+ case T_Group:
+ result = ExecGroup((Group *) node);
+ break;
+
+ case T_Agg:
+ result = ExecAgg((Agg *) node);
+ break;
+
+ case T_Hash:
+ result = ExecHash((Hash *) node);
+ break;
+
+ case T_HashJoin:
+ result = ExecHashJoin((HashJoin *) node);
+ break;
+
+ case T_Tee:
+ result = ExecTee((Tee *) node, parent);
+ break;
+
+ default:
+ elog(DEBUG, "ExecProcNode: node not yet supported: %d",
+ nodeTag(node));
+ result = FALSE;
+ }
+
+ return result;
}
int
-ExecCountSlotsNode(Plan *node)
+ExecCountSlotsNode(Plan * node)
{
- if (node == (Plan *)NULL)
- return 0;
-
- switch(nodeTag(node)) {
- /* ----------------
- * control nodes
- * ----------------
- */
- case T_Result:
- return ExecCountSlotsResult((Result *)node);
-
- case T_Append:
- return ExecCountSlotsAppend((Append *)node);
-
- /* ----------------
- * scan nodes
- * ----------------
- */
- case T_SeqScan:
- return ExecCountSlotsSeqScan((SeqScan *)node);
+ if (node == (Plan *) NULL)
+ return 0;
- case T_IndexScan:
- return ExecCountSlotsIndexScan((IndexScan *)node);
-
- /* ----------------
- * join nodes
- * ----------------
- */
- case T_NestLoop:
- return ExecCountSlotsNestLoop((NestLoop *)node);
-
- case T_MergeJoin:
- return ExecCountSlotsMergeJoin((MergeJoin *)node);
-
- /* ----------------
- * materialization nodes
- * ----------------
- */
- case T_Material:
- return ExecCountSlotsMaterial((Material *)node);
-
- case T_Sort:
- return ExecCountSlotsSort((Sort *)node);
-
- case T_Unique:
- return ExecCountSlotsUnique((Unique *)node);
-
- case T_Group:
- return ExecCountSlotsGroup((Group *)node);
-
- case T_Agg:
- return ExecCountSlotsAgg((Agg *)node);
-
- case T_Hash:
- return ExecCountSlotsHash((Hash *)node);
-
- case T_HashJoin:
- return ExecCountSlotsHashJoin((HashJoin *)node);
-
- case T_Tee:
- return ExecCountSlotsTee((Tee*)node);
-
- default:
- elog(WARN, "ExecCountSlotsNode: node not yet supported: %d",
- nodeTag(node));
- break;
- }
- return 0;
+ switch (nodeTag(node))
+ {
+ /* ----------------
+ * control nodes
+ * ----------------
+ */
+ case T_Result:
+ return ExecCountSlotsResult((Result *) node);
+
+ case T_Append:
+ return ExecCountSlotsAppend((Append *) node);
+
+ /* ----------------
+ * scan nodes
+ * ----------------
+ */
+ case T_SeqScan:
+ return ExecCountSlotsSeqScan((SeqScan *) node);
+
+ case T_IndexScan:
+ return ExecCountSlotsIndexScan((IndexScan *) node);
+
+ /* ----------------
+ * join nodes
+ * ----------------
+ */
+ case T_NestLoop:
+ return ExecCountSlotsNestLoop((NestLoop *) node);
+
+ case T_MergeJoin:
+ return ExecCountSlotsMergeJoin((MergeJoin *) node);
+
+ /* ----------------
+ * materialization nodes
+ * ----------------
+ */
+ case T_Material:
+ return ExecCountSlotsMaterial((Material *) node);
+
+ case T_Sort:
+ return ExecCountSlotsSort((Sort *) node);
+
+ case T_Unique:
+ return ExecCountSlotsUnique((Unique *) node);
+
+ case T_Group:
+ return ExecCountSlotsGroup((Group *) node);
+
+ case T_Agg:
+ return ExecCountSlotsAgg((Agg *) node);
+
+ case T_Hash:
+ return ExecCountSlotsHash((Hash *) node);
+
+ case T_HashJoin:
+ return ExecCountSlotsHashJoin((HashJoin *) node);
+
+ case T_Tee:
+ return ExecCountSlotsTee((Tee *) node);
+
+ default:
+ elog(WARN, "ExecCountSlotsNode: node not yet supported: %d",
+ nodeTag(node));
+ break;
+ }
+ return 0;
}
-/* ----------------------------------------------------------------
- * ExecEndNode
- *
- * Recursively cleans up all the nodes in the plan rooted
- * at 'node'.
+/* ----------------------------------------------------------------
+ * ExecEndNode
*
- * After this operation, the query plan will not be able to
- * processed any further. This should be called only after
- * the query plan has been fully executed.
- * ----------------------------------------------------------------
+ * Recursively cleans up all the nodes in the plan rooted
+ * at 'node'.
+ *
+ * After this operation, the query plan will not be able to
+ * processed any further. This should be called only after
+ * the query plan has been fully executed.
+ * ----------------------------------------------------------------
*/
void
-ExecEndNode(Plan *node, Plan *parent)
+ExecEndNode(Plan * node, Plan * parent)
{
- /* ----------------
- * do nothing when we get to the end
- * of a leaf on tree.
- * ----------------
- */
- if (node == NULL)
- return;
-
- switch(nodeTag(node)) {
- /* ----------------
- * control nodes
- * ----------------
- */
- case T_Result:
- ExecEndResult((Result *)node);
- break;
-
- case T_Append:
- ExecEndAppend((Append *)node);
- break;
-
- /* ----------------
- * scan nodes
- * ----------------
- */
- case T_SeqScan:
- ExecEndSeqScan((SeqScan *)node);
- break;
-
- case T_IndexScan:
- ExecEndIndexScan((IndexScan *)node);
- break;
-
/* ----------------
- * join nodes
+ * do nothing when we get to the end
+ * of a leaf on tree.
* ----------------
*/
- case T_NestLoop:
- ExecEndNestLoop((NestLoop *)node);
- break;
-
- case T_MergeJoin:
- ExecEndMergeJoin((MergeJoin *)node);
- break;
-
- /* ----------------
- * materialization nodes
- * ----------------
- */
- case T_Material:
- ExecEndMaterial((Material *)node);
- break;
-
- case T_Sort:
- ExecEndSort((Sort *)node);
- break;
-
- case T_Unique:
- ExecEndUnique((Unique *)node);
- break;
-
- case T_Group:
- ExecEndGroup((Group *)node);
- break;
-
- case T_Agg:
- ExecEndAgg((Agg *)node);
- break;
-
- /* ----------------
- * XXX add hooks to these
- * ----------------
- */
- case T_Hash:
- ExecEndHash((Hash *) node);
- break;
-
- case T_HashJoin:
- ExecEndHashJoin((HashJoin *) node);
- break;
-
- case T_Tee:
- ExecEndTee((Tee*) node, parent);
- break;
-
- default:
- elog(DEBUG, "ExecEndNode: node not yet supported",
- nodeTag(node));
- break;
- }
+ if (node == NULL)
+ return;
+
+ switch (nodeTag(node))
+ {
+ /* ----------------
+ * control nodes
+ * ----------------
+ */
+ case T_Result:
+ ExecEndResult((Result *) node);
+ break;
+
+ case T_Append:
+ ExecEndAppend((Append *) node);
+ break;
+
+ /* ----------------
+ * scan nodes
+ * ----------------
+ */
+ case T_SeqScan:
+ ExecEndSeqScan((SeqScan *) node);
+ break;
+
+ case T_IndexScan:
+ ExecEndIndexScan((IndexScan *) node);
+ break;
+
+ /* ----------------
+ * join nodes
+ * ----------------
+ */
+ case T_NestLoop:
+ ExecEndNestLoop((NestLoop *) node);
+ break;
+
+ case T_MergeJoin:
+ ExecEndMergeJoin((MergeJoin *) node);
+ break;
+
+ /* ----------------
+ * materialization nodes
+ * ----------------
+ */
+ case T_Material:
+ ExecEndMaterial((Material *) node);
+ break;
+
+ case T_Sort:
+ ExecEndSort((Sort *) node);
+ break;
+
+ case T_Unique:
+ ExecEndUnique((Unique *) node);
+ break;
+
+ case T_Group:
+ ExecEndGroup((Group *) node);
+ break;
+
+ case T_Agg:
+ ExecEndAgg((Agg *) node);
+ break;
+
+ /* ----------------
+ * XXX add hooks to these
+ * ----------------
+ */
+ case T_Hash:
+ ExecEndHash((Hash *) node);
+ break;
+
+ case T_HashJoin:
+ ExecEndHashJoin((HashJoin *) node);
+ break;
+
+ case T_Tee:
+ ExecEndTee((Tee *) node, parent);
+ break;
+
+ default:
+ elog(DEBUG, "ExecEndNode: node not yet supported",
+ nodeTag(node));
+ break;
+ }
}
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 536b0068342..7b8cb18ef25 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -1,32 +1,32 @@
/*-------------------------------------------------------------------------
*
* execQual.c--
- * Routines to evaluate qualification and targetlist expressions
+ * Routines to evaluate qualification and targetlist expressions
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.12 1997/08/19 21:31:03 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.13 1997/09/07 04:41:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * INTERFACE ROUTINES
- * ExecEvalExpr - evaluate an expression and return a datum
- * ExecQual - return true/false if qualification is satisified
- * ExecTargetList - form a new tuple by projecting the given tuple
+ * INTERFACE ROUTINES
+ * ExecEvalExpr - evaluate an expression and return a datum
+ * ExecQual - return true/false if qualification is satisified
+ * ExecTargetList - form a new tuple by projecting the given tuple
*
- * NOTES
- * ExecEvalExpr() and ExecEvalVar() are hotspots. making these faster
- * will speed up the entire system. Unfortunately they are currently
- * implemented recursively.. Eliminating the recursion is bound to
- * improve the speed of the executor.
+ * NOTES
+ * ExecEvalExpr() and ExecEvalVar() are hotspots. making these faster
+ * will speed up the entire system. Unfortunately they are currently
+ * implemented recursively.. Eliminating the recursion is bound to
+ * improve the speed of the executor.
*
- * ExecTargetList() is used to make tuple projections. Rather then
- * trying to speed it up, the execution plan should be pre-processed
- * to facilitate attribute sharing between nodes wherever possible,
- * instead of doing needless copying. -cim 5/31/91
+ * ExecTargetList() is used to make tuple projections. Rather then
+ * trying to speed it up, the execution plan should be pre-processed
+ * to facilitate attribute sharing between nodes wherever possible,
+ * instead of doing needless copying. -cim 5/31/91
*
*/
#include <string.h>
@@ -56,7 +56,7 @@
#include "utils/mcxt.h"
/* ----------------
- * externs and constants
+ * externs and constants
* ----------------
*/
@@ -65,1492 +65,1577 @@
* Currently only used by ExecHashGetBucket and set only by ExecMakeVarConst
* and by ExecEvalArrayRef.
*/
-bool execConstByVal;
-int execConstLen;
+bool execConstByVal;
+int execConstLen;
/* static functions decls */
-static Datum ExecEvalAggreg(Aggreg *agg, ExprContext *econtext, bool *isNull);
-static Datum ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
- bool *isNull, bool *isDone);
-static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
-static Datum ExecEvalFunc(Expr *funcClause, ExprContext *econtext,
- bool *isNull, bool *isDone);
-static void ExecEvalFuncArgs(FunctionCachePtr fcache, ExprContext *econtext,
- List *argList, Datum argV[], bool *argIsDone);
-static Datum ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull);
-static Datum ExecEvalOper(Expr *opClause, ExprContext *econtext,
- bool *isNull);
-static Datum ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull);
-static Datum ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull);
-static Datum ExecMakeFunctionResult(Node *node, List *arguments,
- ExprContext *econtext, bool *isNull, bool *isDone);
-static bool ExecQualClause(Node *clause, ExprContext *econtext);
+static Datum ExecEvalAggreg(Aggreg * agg, ExprContext * econtext, bool * isNull);
+static Datum
+ExecEvalArrayRef(ArrayRef * arrayRef, ExprContext * econtext,
+ bool * isNull, bool * isDone);
+static Datum ExecEvalAnd(Expr * andExpr, ExprContext * econtext, bool * isNull);
+static Datum
+ExecEvalFunc(Expr * funcClause, ExprContext * econtext,
+ bool * isNull, bool * isDone);
+static void
+ExecEvalFuncArgs(FunctionCachePtr fcache, ExprContext * econtext,
+ List * argList, Datum argV[], bool * argIsDone);
+static Datum ExecEvalNot(Expr * notclause, ExprContext * econtext, bool * isNull);
+static Datum
+ExecEvalOper(Expr * opClause, ExprContext * econtext,
+ bool * isNull);
+static Datum ExecEvalOr(Expr * orExpr, ExprContext * econtext, bool * isNull);
+static Datum ExecEvalVar(Var * variable, ExprContext * econtext, bool * isNull);
+static Datum
+ExecMakeFunctionResult(Node * node, List * arguments,
+ ExprContext * econtext, bool * isNull, bool * isDone);
+static bool ExecQualClause(Node * clause, ExprContext * econtext);
/* --------------------------------
- * ExecEvalArrayRef
+ * ExecEvalArrayRef
*
- * This function takes an ArrayRef and returns a Const Node if it
- * is an array reference or returns the changed Array Node if it is
- * an array assignment.
+ * This function takes an ArrayRef and returns a Const Node if it
+ * is an array reference or returns the changed Array Node if it is
+ * an array assignment.
*
* --------------------------------
*/
-static Datum
-ExecEvalArrayRef(ArrayRef *arrayRef,
- ExprContext *econtext,
- bool *isNull,
- bool *isDone)
+static Datum
+ExecEvalArrayRef(ArrayRef * arrayRef,
+ ExprContext * econtext,
+ bool * isNull,
+ bool * isDone)
{
- bool dummy;
- int i = 0, j = 0;
- ArrayType *array_scanner;
- List *upperIndexpr, *lowerIndexpr;
- Node *assgnexpr;
- List *elt;
- IntArray upper, lower;
- int *lIndex;
- char *dataPtr;
-
- *isNull = false;
- array_scanner = (ArrayType*)ExecEvalExpr(arrayRef->refexpr,
- econtext,
- isNull,
- isDone);
- if (*isNull) return (Datum)NULL;
-
- upperIndexpr = arrayRef->refupperindexpr;
-
- foreach (elt, upperIndexpr) {
- upper.indx[i++] = (int32)ExecEvalExpr((Node*)lfirst(elt),
- econtext,
- isNull,
- &dummy);
- if (*isNull) return (Datum)NULL;
- }
-
- lowerIndexpr = arrayRef->reflowerindexpr;
- lIndex = NULL;
- if (lowerIndexpr != NIL) {
- foreach (elt, lowerIndexpr) {
- lower.indx[j++] = (int32)ExecEvalExpr((Node*)lfirst(elt),
- econtext,
- isNull,
- &dummy);
- if (*isNull) return (Datum)NULL;
+ bool dummy;
+ int i = 0,
+ j = 0;
+ ArrayType *array_scanner;
+ List *upperIndexpr,
+ *lowerIndexpr;
+ Node *assgnexpr;
+ List *elt;
+ IntArray upper,
+ lower;
+ int *lIndex;
+ char *dataPtr;
+
+ *isNull = false;
+ array_scanner = (ArrayType *) ExecEvalExpr(arrayRef->refexpr,
+ econtext,
+ isNull,
+ isDone);
+ if (*isNull)
+ return (Datum) NULL;
+
+ upperIndexpr = arrayRef->refupperindexpr;
+
+ foreach(elt, upperIndexpr)
+ {
+ upper.indx[i++] = (int32) ExecEvalExpr((Node *) lfirst(elt),
+ econtext,
+ isNull,
+ &dummy);
+ if (*isNull)
+ return (Datum) NULL;
+ }
+
+ lowerIndexpr = arrayRef->reflowerindexpr;
+ lIndex = NULL;
+ if (lowerIndexpr != NIL)
+ {
+ foreach(elt, lowerIndexpr)
+ {
+ lower.indx[j++] = (int32) ExecEvalExpr((Node *) lfirst(elt),
+ econtext,
+ isNull,
+ &dummy);
+ if (*isNull)
+ return (Datum) NULL;
+ }
+ if (i != j)
+ elog(WARN,
+ "ExecEvalArrayRef: upper and lower indices mismatch");
+ lIndex = lower.indx;
}
- if (i != j)
- elog(WARN,
- "ExecEvalArrayRef: upper and lower indices mismatch");
- lIndex = lower.indx;
- }
-
- assgnexpr = arrayRef->refassgnexpr;
- if (assgnexpr != NULL) {
- dataPtr = (char*)ExecEvalExpr((Node *)
- assgnexpr, econtext,
- isNull, &dummy);
- if (*isNull) return (Datum)NULL;
- execConstByVal = arrayRef->refelembyval;
- execConstLen = arrayRef->refelemlength;
+
+ assgnexpr = arrayRef->refassgnexpr;
+ if (assgnexpr != NULL)
+ {
+ dataPtr = (char *) ExecEvalExpr((Node *)
+ assgnexpr, econtext,
+ isNull, &dummy);
+ if (*isNull)
+ return (Datum) NULL;
+ execConstByVal = arrayRef->refelembyval;
+ execConstLen = arrayRef->refelemlength;
+ if (lIndex == NULL)
+ return (Datum) array_set(array_scanner, i, upper.indx, dataPtr,
+ arrayRef->refelembyval,
+ arrayRef->refelemlength,
+ arrayRef->refattrlength, isNull);
+ return (Datum) array_assgn(array_scanner, i, upper.indx,
+ lower.indx,
+ (ArrayType *) dataPtr,
+ arrayRef->refelembyval,
+ arrayRef->refelemlength, isNull);
+ }
+ execConstByVal = arrayRef->refelembyval;
+ execConstLen = arrayRef->refelemlength;
if (lIndex == NULL)
- return (Datum) array_set(array_scanner, i, upper.indx, dataPtr,
- arrayRef->refelembyval,
- arrayRef->refelemlength,
- arrayRef->refattrlength, isNull);
- return (Datum) array_assgn(array_scanner, i, upper.indx,
- lower.indx,
- (ArrayType*)dataPtr,
- arrayRef->refelembyval,
- arrayRef->refelemlength, isNull);
- }
- execConstByVal = arrayRef->refelembyval;
- execConstLen = arrayRef->refelemlength;
- if (lIndex == NULL)
- return (Datum) array_ref(array_scanner, i, upper.indx,
- arrayRef->refelembyval,
- arrayRef->refelemlength,
- arrayRef->refattrlength, isNull);
- return (Datum) array_clip(array_scanner, i, upper.indx, lower.indx,
- arrayRef->refelembyval,
- arrayRef->refelemlength, isNull);
+ return (Datum) array_ref(array_scanner, i, upper.indx,
+ arrayRef->refelembyval,
+ arrayRef->refelemlength,
+ arrayRef->refattrlength, isNull);
+ return (Datum) array_clip(array_scanner, i, upper.indx, lower.indx,
+ arrayRef->refelembyval,
+ arrayRef->refelemlength, isNull);
}
/* ----------------------------------------------------------------
- * ExecEvalAggreg
- *
- * Returns a Datum whose value is the value of the precomputed
- * aggregate found in the given expression context.
+ * ExecEvalAggreg
+ *
+ * Returns a Datum whose value is the value of the precomputed
+ * aggregate found in the given expression context.
* ----------------------------------------------------------------
*/
-static Datum
-ExecEvalAggreg(Aggreg *agg, ExprContext *econtext, bool *isNull)
+static Datum
+ExecEvalAggreg(Aggreg * agg, ExprContext * econtext, bool * isNull)
{
-
- *isNull = econtext->ecxt_nulls[agg->aggno];
- return econtext->ecxt_values[agg->aggno];
+
+ *isNull = econtext->ecxt_nulls[agg->aggno];
+ return econtext->ecxt_values[agg->aggno];
}
/* ----------------------------------------------------------------
- * ExecEvalVar
- *
- * Returns a Datum whose value is the value of a range
- * variable with respect to given expression context.
+ * ExecEvalVar
+ *
+ * Returns a Datum whose value is the value of a range
+ * variable with respect to given expression context.
+ *
+ *
+ * As an entry condition, we expect that the the datatype the
+ * plan expects to get (as told by our "variable" argument) is in
+ * fact the datatype of the attribute the plan says to fetch (as
+ * seen in the current context, identified by our "econtext"
+ * argument).
+ *
+ * If we fetch a Type A attribute and Caller treats it as if it
+ * were Type B, there will be undefined results (e.g. crash).
+ * One way these might mismatch now is that we're accessing a
+ * catalog class and the type information in the pg_attribute
+ * class does not match the hardcoded pg_attribute information
+ * (in pg_attribute.h) for the class in question.
*
+ * We have an Assert to make sure this entry condition is met.
*
- * As an entry condition, we expect that the the datatype the
- * plan expects to get (as told by our "variable" argument) is in
- * fact the datatype of the attribute the plan says to fetch (as
- * seen in the current context, identified by our "econtext"
- * argument).
- *
- * If we fetch a Type A attribute and Caller treats it as if it
- * were Type B, there will be undefined results (e.g. crash).
- * One way these might mismatch now is that we're accessing a
- * catalog class and the type information in the pg_attribute
- * class does not match the hardcoded pg_attribute information
- * (in pg_attribute.h) for the class in question.
- *
- * We have an Assert to make sure this entry condition is met.
- *
* ---------------------------------------------------------------- */
-static Datum
-ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
+static Datum
+ExecEvalVar(Var * variable, ExprContext * econtext, bool * isNull)
{
- Datum result;
- TupleTableSlot *slot;
- AttrNumber attnum;
- HeapTuple heapTuple;
- TupleDesc tuple_type;
- Buffer buffer;
- bool byval;
- int16 len;
-
- /* ----------------
- * get the slot we want
- * ----------------
- */
- switch(variable->varno) {
- case INNER: /* get the tuple from the inner node */
- slot = econtext->ecxt_innertuple;
- break;
-
- case OUTER: /* get the tuple from the outer node */
- slot = econtext->ecxt_outertuple;
- break;
-
- default: /* get the tuple from the relation being scanned */
- slot = econtext->ecxt_scantuple;
- break;
- }
-
- /* ----------------
- * extract tuple information from the slot
- * ----------------
- */
- heapTuple = slot->val;
- tuple_type = slot->ttc_tupleDescriptor;
- buffer = slot->ttc_buffer;
-
- attnum = variable->varattno;
-
- /* (See prolog for explanation of this Assert) */
- Assert(attnum <= 0 ||
- (attnum - 1 <= tuple_type->natts - 1 &&
- tuple_type->attrs[attnum-1] != NULL &&
- variable->vartype == tuple_type->attrs[attnum-1]->atttypid))
-
- /*
- * If the attribute number is invalid, then we are supposed to
- * return the entire tuple, we give back a whole slot so that
- * callers know what the tuple looks like.
- */
- if (attnum == InvalidAttrNumber)
+ Datum result;
+ TupleTableSlot *slot;
+ AttrNumber attnum;
+ HeapTuple heapTuple;
+ TupleDesc tuple_type;
+ Buffer buffer;
+ bool byval;
+ int16 len;
+
+ /* ----------------
+ * get the slot we want
+ * ----------------
+ */
+ switch (variable->varno)
+ {
+ case INNER: /* get the tuple from the inner node */
+ slot = econtext->ecxt_innertuple;
+ break;
+
+ case OUTER: /* get the tuple from the outer node */
+ slot = econtext->ecxt_outertuple;
+ break;
+
+ default: /* get the tuple from the relation being
+ * scanned */
+ slot = econtext->ecxt_scantuple;
+ break;
+ }
+
+ /* ----------------
+ * extract tuple information from the slot
+ * ----------------
+ */
+ heapTuple = slot->val;
+ tuple_type = slot->ttc_tupleDescriptor;
+ buffer = slot->ttc_buffer;
+
+ attnum = variable->varattno;
+
+ /* (See prolog for explanation of this Assert) */
+ Assert(attnum <= 0 ||
+ (attnum - 1 <= tuple_type->natts - 1 &&
+ tuple_type->attrs[attnum - 1] != NULL &&
+ variable->vartype == tuple_type->attrs[attnum - 1]->atttypid))
+
+ /*
+ * If the attribute number is invalid, then we are supposed to return
+ * the entire tuple, we give back a whole slot so that callers know
+ * what the tuple looks like.
+ */
+ if (attnum == InvalidAttrNumber)
{
- TupleTableSlot *tempSlot;
- TupleDesc td;
- HeapTuple tup;
-
- tempSlot = makeNode(TupleTableSlot);
- tempSlot->ttc_shouldFree = false;
- tempSlot->ttc_descIsNew = true;
- tempSlot->ttc_tupleDescriptor = (TupleDesc)NULL,
- tempSlot->ttc_buffer = InvalidBuffer;
- tempSlot->ttc_whichplan = -1;
-
- tup = heap_copytuple(slot->val);
- td = CreateTupleDescCopy(slot->ttc_tupleDescriptor);
-
- ExecSetSlotDescriptor(tempSlot, td);
-
- ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
- return (Datum) tempSlot;
+ TupleTableSlot *tempSlot;
+ TupleDesc td;
+ HeapTuple tup;
+
+ tempSlot = makeNode(TupleTableSlot);
+ tempSlot->ttc_shouldFree = false;
+ tempSlot->ttc_descIsNew = true;
+ tempSlot->ttc_tupleDescriptor = (TupleDesc) NULL,
+ tempSlot->ttc_buffer = InvalidBuffer;
+ tempSlot->ttc_whichplan = -1;
+
+ tup = heap_copytuple(slot->val);
+ td = CreateTupleDescCopy(slot->ttc_tupleDescriptor);
+
+ ExecSetSlotDescriptor(tempSlot, td);
+
+ ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
+ return (Datum) tempSlot;
}
-
- result = (Datum)
- heap_getattr(heapTuple, /* tuple containing attribute */
- buffer, /* buffer associated with tuple */
- attnum, /* attribute number of desired attribute */
- tuple_type, /* tuple descriptor of tuple */
- isNull); /* return: is attribute null? */
-
- /* ----------------
- * return null if att is null
- * ----------------
- */
- if (*isNull)
- return (Datum) NULL;
-
- /* ----------------
- * get length and type information..
- * ??? what should we do about variable length attributes
- * - variable length attributes have their length stored
- * in the first 4 bytes of the memory pointed to by the
- * returned value.. If we can determine that the type
- * is a variable length type, we can do the right thing.
- * -cim 9/15/89
- * ----------------
- */
- if (attnum < 0) {
+
+ result = (Datum)
+ heap_getattr(heapTuple, /* tuple containing attribute */
+ buffer, /* buffer associated with tuple */
+ attnum, /* attribute number of desired attribute */
+ tuple_type,/* tuple descriptor of tuple */
+ isNull); /* return: is attribute null? */
+
/* ----------------
- * If this is a pseudo-att, we get the type and fake the length.
- * There ought to be a routine to return the real lengths, so
- * we'll mark this one ... XXX -mao
+ * return null if att is null
* ----------------
*/
- len = heap_sysattrlen(attnum); /* XXX see -mao above */
- byval = heap_sysattrbyval(attnum); /* XXX see -mao above */
- } else {
- len = tuple_type->attrs[ attnum-1 ]->attlen;
- byval = tuple_type->attrs[ attnum-1 ]->attbyval ? true : false ;
- }
-
- execConstByVal = byval;
- execConstLen = len;
-
- return result;
+ if (*isNull)
+ return (Datum) NULL;
+
+ /* ----------------
+ * get length and type information..
+ * ??? what should we do about variable length attributes
+ * - variable length attributes have their length stored
+ * in the first 4 bytes of the memory pointed to by the
+ * returned value.. If we can determine that the type
+ * is a variable length type, we can do the right thing.
+ * -cim 9/15/89
+ * ----------------
+ */
+ if (attnum < 0)
+ {
+ /* ----------------
+ * If this is a pseudo-att, we get the type and fake the length.
+ * There ought to be a routine to return the real lengths, so
+ * we'll mark this one ... XXX -mao
+ * ----------------
+ */
+ len = heap_sysattrlen(attnum); /* XXX see -mao above */
+ byval = heap_sysattrbyval(attnum); /* XXX see -mao above */
+ }
+ else
+ {
+ len = tuple_type->attrs[attnum - 1]->attlen;
+ byval = tuple_type->attrs[attnum - 1]->attbyval ? true : false;
+ }
+
+ execConstByVal = byval;
+ execConstLen = len;
+
+ return result;
}
/* ----------------------------------------------------------------
- * ExecEvalParam
+ * ExecEvalParam
*
- * Returns the value of a parameter. A param node contains
- * something like ($.name) and the expression context contains
- * the current parameter bindings (name = "sam") (age = 34)...
- * so our job is to replace the param node with the datum
- * containing the appropriate information ("sam").
+ * Returns the value of a parameter. A param node contains
+ * something like ($.name) and the expression context contains
+ * the current parameter bindings (name = "sam") (age = 34)...
+ * so our job is to replace the param node with the datum
+ * containing the appropriate information ("sam").
*
- * Q: if we have a parameter ($.foo) without a binding, i.e.
- * there is no (foo = xxx) in the parameter list info,
- * is this a fatal error or should this be a "not available"
- * (in which case we shoud return a Const node with the
- * isnull flag) ? -cim 10/13/89
+ * Q: if we have a parameter ($.foo) without a binding, i.e.
+ * there is no (foo = xxx) in the parameter list info,
+ * is this a fatal error or should this be a "not available"
+ * (in which case we shoud return a Const node with the
+ * isnull flag) ? -cim 10/13/89
*
- * Minor modification: Param nodes now have an extra field,
- * `paramkind' which specifies the type of parameter
- * (see params.h). So while searching the paramList for
- * a paramname/value pair, we have also to check for `kind'.
- *
- * NOTE: The last entry in `paramList' is always an
- * entry with kind == PARAM_INVALID.
+ * Minor modification: Param nodes now have an extra field,
+ * `paramkind' which specifies the type of parameter
+ * (see params.h). So while searching the paramList for
+ * a paramname/value pair, we have also to check for `kind'.
+ *
+ * NOTE: The last entry in `paramList' is always an
+ * entry with kind == PARAM_INVALID.
* ----------------------------------------------------------------
*/
Datum
-ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
+ExecEvalParam(Param * expression, ExprContext * econtext, bool * isNull)
{
-
- char *thisParameterName;
- int thisParameterKind;
- AttrNumber thisParameterId;
- int matchFound;
- ParamListInfo paramList;
-
- thisParameterName = expression->paramname;
- thisParameterKind = expression->paramkind;
- thisParameterId = expression->paramid;
- paramList = econtext->ecxt_param_list_info;
-
- *isNull = false;
- /*
- * search the list with the parameter info to find a matching name.
- * An entry with an InvalidName denotes the last element in the array.
- */
- matchFound = 0;
- if (paramList != NULL) {
+
+ char *thisParameterName;
+ int thisParameterKind;
+ AttrNumber thisParameterId;
+ int matchFound;
+ ParamListInfo paramList;
+
+ thisParameterName = expression->paramname;
+ thisParameterKind = expression->paramkind;
+ thisParameterId = expression->paramid;
+ paramList = econtext->ecxt_param_list_info;
+
+ *isNull = false;
+
/*
- * search for an entry in 'paramList' that matches
- * the `expression'.
+ * search the list with the parameter info to find a matching name. An
+ * entry with an InvalidName denotes the last element in the array.
*/
- while(paramList->kind != PARAM_INVALID && !matchFound) {
- switch (thisParameterKind) {
- case PARAM_NAMED:
- if (thisParameterKind == paramList->kind &&
- strcmp(paramList->name, thisParameterName) == 0){
- matchFound = 1;
- }
- break;
- case PARAM_NUM:
- if (thisParameterKind == paramList->kind &&
- paramList->id == thisParameterId) {
- matchFound = 1;
- }
- break;
- case PARAM_OLD:
- case PARAM_NEW:
- if (thisParameterKind == paramList->kind &&
- paramList->id == thisParameterId)
- {
- matchFound = 1;
- /*
- * sanity check
- */
- if (strcmp(paramList->name, thisParameterName) != 0){
- elog(WARN,
- "ExecEvalParam: new/old params with same id & diff names");
+ matchFound = 0;
+ if (paramList != NULL)
+ {
+
+ /*
+ * search for an entry in 'paramList' that matches the
+ * `expression'.
+ */
+ while (paramList->kind != PARAM_INVALID && !matchFound)
+ {
+ switch (thisParameterKind)
+ {
+ case PARAM_NAMED:
+ if (thisParameterKind == paramList->kind &&
+ strcmp(paramList->name, thisParameterName) == 0)
+ {
+ matchFound = 1;
+ }
+ break;
+ case PARAM_NUM:
+ if (thisParameterKind == paramList->kind &&
+ paramList->id == thisParameterId)
+ {
+ matchFound = 1;
+ }
+ break;
+ case PARAM_OLD:
+ case PARAM_NEW:
+ if (thisParameterKind == paramList->kind &&
+ paramList->id == thisParameterId)
+ {
+ matchFound = 1;
+
+ /*
+ * sanity check
+ */
+ if (strcmp(paramList->name, thisParameterName) != 0)
+ {
+ elog(WARN,
+ "ExecEvalParam: new/old params with same id & diff names");
+ }
+ }
+ break;
+ default:
+
+ /*
+ * oops! this is not supposed to happen!
+ */
+ elog(WARN, "ExecEvalParam: invalid paramkind %d",
+ thisParameterKind);
}
- }
- break;
- default:
+ if (!matchFound)
+ {
+ paramList++;
+ }
+ } /* while */
+ } /* if */
+
+ if (!matchFound)
+ {
+
/*
- * oops! this is not supposed to happen!
+ * ooops! we couldn't find this parameter in the parameter list.
+ * Signal an error
*/
- elog(WARN, "ExecEvalParam: invalid paramkind %d",
- thisParameterKind);
- }
- if (! matchFound) {
- paramList++;
- }
- } /*while*/
- } /*if*/
-
- if (!matchFound) {
+ elog(WARN, "ExecEvalParam: Unknown value for parameter %s",
+ thisParameterName);
+ }
+
/*
- * ooops! we couldn't find this parameter
- * in the parameter list. Signal an error
+ * return the value.
*/
- elog(WARN, "ExecEvalParam: Unknown value for parameter %s",
- thisParameterName);
- }
-
- /*
- * return the value.
- */
- if (paramList->isnull)
+ if (paramList->isnull)
{
- *isNull = true;
- return (Datum)NULL;
+ *isNull = true;
+ return (Datum) NULL;
}
-
- if (expression->param_tlist != NIL)
+
+ if (expression->param_tlist != NIL)
{
- HeapTuple tup;
- Datum value;
- List *tlist = expression->param_tlist;
- TargetEntry *tle = (TargetEntry *)lfirst(tlist);
- TupleTableSlot *slot = (TupleTableSlot *)paramList->value;
-
- tup = slot->val;
- value = ProjectAttribute(slot->ttc_tupleDescriptor,
- tle, tup, isNull);
- return value;
+ HeapTuple tup;
+ Datum value;
+ List *tlist = expression->param_tlist;
+ TargetEntry *tle = (TargetEntry *) lfirst(tlist);
+ TupleTableSlot *slot = (TupleTableSlot *) paramList->value;
+
+ tup = slot->val;
+ value = ProjectAttribute(slot->ttc_tupleDescriptor,
+ tle, tup, isNull);
+ return value;
}
- return(paramList->value);
+ return (paramList->value);
}
/* ----------------------------------------------------------------
- * ExecEvalOper / ExecEvalFunc support routines
+ * ExecEvalOper / ExecEvalFunc support routines
* ----------------------------------------------------------------
*/
/* ----------------
- * GetAttributeByName
- * GetAttributeByNum
+ * GetAttributeByName
+ * GetAttributeByNum
*
- * These are functions which return the value of the
- * named attribute out of the tuple from the arg slot. User defined
- * C functions which take a tuple as an argument are expected
- * to use this. Ex: overpaid(EMP) might call GetAttributeByNum().
+ * These are functions which return the value of the
+ * named attribute out of the tuple from the arg slot. User defined
+ * C functions which take a tuple as an argument are expected
+ * to use this. Ex: overpaid(EMP) might call GetAttributeByNum().
* ----------------
*/
#ifdef NOT_USED
-static char *
-GetAttributeByNum(TupleTableSlot *slot,
- AttrNumber attrno,
- bool *isNull)
+static char *
+GetAttributeByNum(TupleTableSlot * slot,
+ AttrNumber attrno,
+ bool * isNull)
{
- Datum retval;
-
- if (!AttributeNumberIsValid(attrno))
- elog(WARN, "GetAttributeByNum: Invalid attribute number");
-
- if (!AttrNumberIsForUserDefinedAttr(attrno))
- elog(WARN, "GetAttributeByNum: cannot access system attributes here");
-
- if (isNull == (bool *)NULL)
- elog(WARN, "GetAttributeByNum: a NULL isNull flag was passed");
-
- if (TupIsNull(slot))
+ Datum retval;
+
+ if (!AttributeNumberIsValid(attrno))
+ elog(WARN, "GetAttributeByNum: Invalid attribute number");
+
+ if (!AttrNumberIsForUserDefinedAttr(attrno))
+ elog(WARN, "GetAttributeByNum: cannot access system attributes here");
+
+ if (isNull == (bool *) NULL)
+ elog(WARN, "GetAttributeByNum: a NULL isNull flag was passed");
+
+ if (TupIsNull(slot))
{
- *isNull = true;
- return (char *) NULL;
+ *isNull = true;
+ return (char *) NULL;
}
-
- retval = (Datum)
- heap_getattr(slot->val,
- slot->ttc_buffer,
- attrno,
- slot->ttc_tupleDescriptor,
- isNull);
- if (*isNull)
- return (char *) NULL;
- return (char *) retval;
+
+ retval = (Datum)
+ heap_getattr(slot->val,
+ slot->ttc_buffer,
+ attrno,
+ slot->ttc_tupleDescriptor,
+ isNull);
+ if (*isNull)
+ return (char *) NULL;
+ return (char *) retval;
}
+
#endif
/* XXX char16 name for catalogs */
#ifdef NOT_USED
-char *
-att_by_num(TupleTableSlot *slot,
- AttrNumber attrno,
- bool *isNull)
+char *
+att_by_num(TupleTableSlot * slot,
+ AttrNumber attrno,
+ bool * isNull)
{
- return(GetAttributeByNum(slot, attrno, isNull));
+ return (GetAttributeByNum(slot, attrno, isNull));
}
+
#endif
-char *
-GetAttributeByName(TupleTableSlot *slot, char *attname, bool *isNull)
+char *
+GetAttributeByName(TupleTableSlot * slot, char *attname, bool * isNull)
{
- AttrNumber attrno;
- TupleDesc tupdesc;
- HeapTuple tuple;
- Datum retval;
- int natts;
- int i;
-
- if (attname == NULL)
- elog(WARN, "GetAttributeByName: Invalid attribute name");
-
- if (isNull == (bool *)NULL)
- elog(WARN, "GetAttributeByName: a NULL isNull flag was passed");
-
- if (TupIsNull(slot))
+ AttrNumber attrno;
+ TupleDesc tupdesc;
+ HeapTuple tuple;
+ Datum retval;
+ int natts;
+ int i;
+
+ if (attname == NULL)
+ elog(WARN, "GetAttributeByName: Invalid attribute name");
+
+ if (isNull == (bool *) NULL)
+ elog(WARN, "GetAttributeByName: a NULL isNull flag was passed");
+
+ if (TupIsNull(slot))
{
- *isNull = true;
- return (char *) NULL;
+ *isNull = true;
+ return (char *) NULL;
}
-
- tupdesc = slot->ttc_tupleDescriptor;
- tuple = slot->val;
-
- natts = tuple->t_natts;
-
- attrno = InvalidAttrNumber;
- for (i=0;i<tupdesc->natts;i++) {
- if (namestrcmp(&(tupdesc->attrs[i]->attname), attname) == 0) {
- attrno = tupdesc->attrs[i]->attnum;
- break;
+
+ tupdesc = slot->ttc_tupleDescriptor;
+ tuple = slot->val;
+
+ natts = tuple->t_natts;
+
+ attrno = InvalidAttrNumber;
+ for (i = 0; i < tupdesc->natts; i++)
+ {
+ if (namestrcmp(&(tupdesc->attrs[i]->attname), attname) == 0)
+ {
+ attrno = tupdesc->attrs[i]->attnum;
+ break;
+ }
}
- }
-
- if (attrno == InvalidAttrNumber)
- elog(WARN, "GetAttributeByName: attribute %s not found", attname);
-
- retval = (Datum)
- heap_getattr(slot->val,
- slot->ttc_buffer,
- attrno,
- tupdesc,
- isNull);
- if (*isNull)
- return (char *) NULL;
- return (char *) retval;
+
+ if (attrno == InvalidAttrNumber)
+ elog(WARN, "GetAttributeByName: attribute %s not found", attname);
+
+ retval = (Datum)
+ heap_getattr(slot->val,
+ slot->ttc_buffer,
+ attrno,
+ tupdesc,
+ isNull);
+ if (*isNull)
+ return (char *) NULL;
+ return (char *) retval;
}
/* XXX char16 name for catalogs */
#ifdef NOT_USED
-char *
-att_by_name(TupleTableSlot *slot, char *attname, bool *isNull)
+char *
+att_by_name(TupleTableSlot * slot, char *attname, bool * isNull)
{
- return(GetAttributeByName(slot, attname, isNull));
+ return (GetAttributeByName(slot, attname, isNull));
}
+
#endif
static void
ExecEvalFuncArgs(FunctionCachePtr fcache,
- ExprContext *econtext,
- List *argList,
- Datum argV[],
- bool *argIsDone)
+ ExprContext * econtext,
+ List * argList,
+ Datum argV[],
+ bool * argIsDone)
{
- int i;
- bool argIsNull, *nullVect;
- List *arg;
-
- nullVect = fcache->nullVect;
-
- i = 0;
- foreach (arg, argList) {
- /* ----------------
- * evaluate the expression, in general functions cannot take
- * sets as arguments but we make an exception in the case of
- * nested dot expressions. We have to watch out for this case
- * here.
- * ----------------
- */
- argV[i] = (Datum)
- ExecEvalExpr((Node *) lfirst(arg),
- econtext,
- &argIsNull,
- argIsDone);
- if (! (*argIsDone))
- {
- Assert(i == 0);
- fcache->setArg = (char *)argV[0];
- fcache->hasSetArg = true;
- }
- if (argIsNull)
- nullVect[i] = true;
- else
- nullVect[i] = false;
- i++;
- }
+ int i;
+ bool argIsNull,
+ *nullVect;
+ List *arg;
+
+ nullVect = fcache->nullVect;
+
+ i = 0;
+ foreach(arg, argList)
+ {
+ /* ----------------
+ * evaluate the expression, in general functions cannot take
+ * sets as arguments but we make an exception in the case of
+ * nested dot expressions. We have to watch out for this case
+ * here.
+ * ----------------
+ */
+ argV[i] = (Datum)
+ ExecEvalExpr((Node *) lfirst(arg),
+ econtext,
+ &argIsNull,
+ argIsDone);
+ if (!(*argIsDone))
+ {
+ Assert(i == 0);
+ fcache->setArg = (char *) argV[0];
+ fcache->hasSetArg = true;
+ }
+ if (argIsNull)
+ nullVect[i] = true;
+ else
+ nullVect[i] = false;
+ i++;
+ }
}
/* ----------------
- * ExecMakeFunctionResult
+ * ExecMakeFunctionResult
* ----------------
*/
-static Datum
-ExecMakeFunctionResult(Node *node,
- List *arguments,
- ExprContext *econtext,
- bool *isNull,
- bool *isDone)
+static Datum
+ExecMakeFunctionResult(Node * node,
+ List * arguments,
+ ExprContext * econtext,
+ bool * isNull,
+ bool * isDone)
{
- Datum argv[MAXFMGRARGS];
- FunctionCachePtr fcache;
- Func *funcNode = NULL;
- Oper *operNode = NULL;
- bool funcisset = false;
-
- /*
- * This is kind of ugly, Func nodes now have targetlists so that
- * we know when and what to project out from postquel function results.
- * This means we have to pass the func node all the way down instead
- * of using only the fcache struct as before. ExecMakeFunctionResult
- * becomes a little bit more of a dual personality as a result.
- */
- if (IsA(node,Func))
+ Datum argv[MAXFMGRARGS];
+ FunctionCachePtr fcache;
+ Func *funcNode = NULL;
+ Oper *operNode = NULL;
+ bool funcisset = false;
+
+ /*
+ * This is kind of ugly, Func nodes now have targetlists so that we
+ * know when and what to project out from postquel function results.
+ * This means we have to pass the func node all the way down instead
+ * of using only the fcache struct as before. ExecMakeFunctionResult
+ * becomes a little bit more of a dual personality as a result.
+ */
+ if (IsA(node, Func))
{
- funcNode = (Func *)node;
- fcache = funcNode->func_fcache;
+ funcNode = (Func *) node;
+ fcache = funcNode->func_fcache;
}
- else
+ else
{
- operNode = (Oper *)node;
- fcache = operNode->op_fcache;
+ operNode = (Oper *) node;
+ fcache = operNode->op_fcache;
}
-
- /* ----------------
- * arguments is a list of expressions to evaluate
- * before passing to the function manager.
- * We collect the results of evaluating the expressions
- * into a datum array (argv) and pass this array to arrayFmgr()
- * ----------------
- */
- if (fcache->nargs != 0) {
- bool argDone;
-
- if (fcache->nargs > MAXFMGRARGS)
- elog(WARN, "ExecMakeFunctionResult: too many arguments");
-
- /*
- * If the setArg in the fcache is set we have an argument
- * returning a set of tuples (i.e. a nested dot expression). We
- * don't want to evaluate the arguments again until the function
- * is done. hasSetArg will always be false until we eval the args
- * for the first time. We should set this in the parser.
+
+ /* ----------------
+ * arguments is a list of expressions to evaluate
+ * before passing to the function manager.
+ * We collect the results of evaluating the expressions
+ * into a datum array (argv) and pass this array to arrayFmgr()
+ * ----------------
*/
- if ((fcache->hasSetArg) && fcache->setArg != NULL)
- {
- argv[0] = (Datum)fcache->setArg;
- argDone = false;
- }
- else
- ExecEvalFuncArgs(fcache, econtext, arguments, argv, &argDone);
-
- if ((fcache->hasSetArg) && (argDone)) {
- if (isDone) *isDone = true;
- return (Datum)NULL;
- }
- }
-
- /* If this function is really a set, we have to diddle with things.
- * If the function has already been called at least once, then the
- * setArg field of the fcache holds
- * the OID of this set in pg_proc. (This is not quite legit, since
- * the setArg field is really for functions which take sets of tuples
- * as input - set functions take no inputs at all. But it's a nice
- * place to stash this value, for now.)
- *
- * If this is the first call of the set's function, then
- * the call to ExecEvalFuncArgs above just returned the OID of
- * the pg_proc tuple which defines this set. So replace the existing
- * funcid in the funcnode with the set's OID. Also, we want a new
- * fcache which points to the right function, so get that, now that
- * we have the right OID. Also zero out the argv, since the real
- * set doesn't take any arguments.
- */
- if (((Func *)node)->funcid == SetEvalRegProcedure) {
- funcisset = true;
- if (fcache->setArg) {
- argv[0] = 0;
-
- ((Func *)node)->funcid = (Oid) PointerGetDatum(fcache->setArg);
-
- } else {
- ((Func *)node)->funcid = (Oid) argv[0];
- setFcache(node, argv[0], NIL,econtext);
- fcache = ((Func *)node)->func_fcache;
- fcache->setArg = (char*)argv[0];
- argv[0] = (Datum)0;
+ if (fcache->nargs != 0)
+ {
+ bool argDone;
+
+ if (fcache->nargs > MAXFMGRARGS)
+ elog(WARN, "ExecMakeFunctionResult: too many arguments");
+
+ /*
+ * If the setArg in the fcache is set we have an argument
+ * returning a set of tuples (i.e. a nested dot expression). We
+ * don't want to evaluate the arguments again until the function
+ * is done. hasSetArg will always be false until we eval the args
+ * for the first time. We should set this in the parser.
+ */
+ if ((fcache->hasSetArg) && fcache->setArg != NULL)
+ {
+ argv[0] = (Datum) fcache->setArg;
+ argDone = false;
+ }
+ else
+ ExecEvalFuncArgs(fcache, econtext, arguments, argv, &argDone);
+
+ if ((fcache->hasSetArg) && (argDone))
+ {
+ if (isDone)
+ *isDone = true;
+ return (Datum) NULL;
+ }
}
- }
-
- /* ----------------
- * now return the value gotten by calling the function manager,
- * passing the function the evaluated parameter values.
- * ----------------
- */
- if (fcache->language == SQLlanguageId) {
- Datum result;
-
- Assert(funcNode);
- result = postquel_function (funcNode, (char **) argv, isNull, isDone);
+
/*
- * finagle the situation where we are iterating through all results
- * in a nested dot function (whose argument function returns a set
- * of tuples) and the current function finally finishes. We need to
- * get the next argument in the set and run the function all over
- * again. This is getting unclean.
+ * If this function is really a set, we have to diddle with things. If
+ * the function has already been called at least once, then the setArg
+ * field of the fcache holds the OID of this set in pg_proc. (This is
+ * not quite legit, since the setArg field is really for functions
+ * which take sets of tuples as input - set functions take no inputs
+ * at all. But it's a nice place to stash this value, for now.)
+ *
+ * If this is the first call of the set's function, then the call to
+ * ExecEvalFuncArgs above just returned the OID of the pg_proc tuple
+ * which defines this set. So replace the existing funcid in the
+ * funcnode with the set's OID. Also, we want a new fcache which
+ * points to the right function, so get that, now that we have the
+ * right OID. Also zero out the argv, since the real set doesn't take
+ * any arguments.
*/
- if ((*isDone) && (fcache->hasSetArg)) {
- bool argDone;
-
- ExecEvalFuncArgs(fcache, econtext, arguments, argv, &argDone);
-
- if (argDone) {
- fcache->setArg = (char *)NULL;
- *isDone = true;
- result = (Datum)NULL;
- }
- else
- result = postquel_function(funcNode,
- (char **) argv,
- isNull,
- isDone);
+ if (((Func *) node)->funcid == SetEvalRegProcedure)
+ {
+ funcisset = true;
+ if (fcache->setArg)
+ {
+ argv[0] = 0;
+
+ ((Func *) node)->funcid = (Oid) PointerGetDatum(fcache->setArg);
+
+ }
+ else
+ {
+ ((Func *) node)->funcid = (Oid) argv[0];
+ setFcache(node, argv[0], NIL, econtext);
+ fcache = ((Func *) node)->func_fcache;
+ fcache->setArg = (char *) argv[0];
+ argv[0] = (Datum) 0;
+ }
}
- if (funcisset) {
- /* reset the funcid so that next call to this routine will
- * still recognize this func as a set.
- * Note that for now we assume that the set function in
- * pg_proc must be a Postquel function - the funcid is
- * not reset below for C functions.
- */
- ((Func *)node)->funcid = SetEvalRegProcedure;
- /* If we're done with the results of this function, get rid
- * of its func cache.
- */
- if (*isDone) {
- ((Func *)node)->func_fcache = NULL;
- }
+
+ /* ----------------
+ * now return the value gotten by calling the function manager,
+ * passing the function the evaluated parameter values.
+ * ----------------
+ */
+ if (fcache->language == SQLlanguageId)
+ {
+ Datum result;
+
+ Assert(funcNode);
+ result = postquel_function(funcNode, (char **) argv, isNull, isDone);
+
+ /*
+ * finagle the situation where we are iterating through all
+ * results in a nested dot function (whose argument function
+ * returns a set of tuples) and the current function finally
+ * finishes. We need to get the next argument in the set and run
+ * the function all over again. This is getting unclean.
+ */
+ if ((*isDone) && (fcache->hasSetArg))
+ {
+ bool argDone;
+
+ ExecEvalFuncArgs(fcache, econtext, arguments, argv, &argDone);
+
+ if (argDone)
+ {
+ fcache->setArg = (char *) NULL;
+ *isDone = true;
+ result = (Datum) NULL;
+ }
+ else
+ result = postquel_function(funcNode,
+ (char **) argv,
+ isNull,
+ isDone);
+ }
+ if (funcisset)
+ {
+
+ /*
+ * reset the funcid so that next call to this routine will
+ * still recognize this func as a set. Note that for now we
+ * assume that the set function in pg_proc must be a Postquel
+ * function - the funcid is not reset below for C functions.
+ */
+ ((Func *) node)->funcid = SetEvalRegProcedure;
+
+ /*
+ * If we're done with the results of this function, get rid of
+ * its func cache.
+ */
+ if (*isDone)
+ {
+ ((Func *) node)->func_fcache = NULL;
+ }
+ }
+ return result;
}
- return result;
- }
- else
+ else
{
- int i;
-
- if (isDone) *isDone = true;
- for (i = 0; i < fcache->nargs; i++)
- if (fcache->nullVect[i] == true) *isNull = true;
-
- return((Datum) fmgr_c(fcache->func, fcache->foid, fcache->nargs,
- (FmgrValues *) argv, isNull));
+ int i;
+
+ if (isDone)
+ *isDone = true;
+ for (i = 0; i < fcache->nargs; i++)
+ if (fcache->nullVect[i] == true)
+ *isNull = true;
+
+ return ((Datum) fmgr_c(fcache->func, fcache->foid, fcache->nargs,
+ (FmgrValues *) argv, isNull));
}
}
/* ----------------------------------------------------------------
- * ExecEvalOper
- * ExecEvalFunc
- *
- * Evaluate the functional result of a list of arguments by calling the
- * function manager. Note that in the case of operator expressions, the
- * optimizer had better have already replaced the operator OID with the
- * appropriate function OID or we're hosed.
+ * ExecEvalOper
+ * ExecEvalFunc
+ *
+ * Evaluate the functional result of a list of arguments by calling the
+ * function manager. Note that in the case of operator expressions, the
+ * optimizer had better have already replaced the operator OID with the
+ * appropriate function OID or we're hosed.
*
* old comments
- * Presumably the function manager will not take null arguments, so we
- * check for null arguments before sending the arguments to (fmgr).
- *
- * Returns the value of the functional expression.
+ * Presumably the function manager will not take null arguments, so we
+ * check for null arguments before sending the arguments to (fmgr).
+ *
+ * Returns the value of the functional expression.
* ----------------------------------------------------------------
*/
/* ----------------------------------------------------------------
- * ExecEvalOper
+ * ExecEvalOper
* ----------------------------------------------------------------
*/
-static Datum
-ExecEvalOper(Expr *opClause, ExprContext *econtext, bool *isNull)
+static Datum
+ExecEvalOper(Expr * opClause, ExprContext * econtext, bool * isNull)
{
- Oper *op;
- List *argList;
- FunctionCachePtr fcache;
- bool isDone;
-
- /* ----------------
- * an opclause is a list (op args). (I think)
- *
- * we extract the oid of the function associated with
- * the op and then pass the work onto ExecMakeFunctionResult
- * which evaluates the arguments and returns the result of
- * calling the function on the evaluated arguments.
- * ----------------
- */
- op = (Oper *) opClause->oper;
- argList = opClause->args;
-
- /*
- * get the fcache from the Oper node.
- * If it is NULL, then initialize it
- */
- fcache = op->op_fcache;
- if (fcache == NULL) {
- setFcache((Node*)op, op->opid, argList, econtext);
- fcache = op->op_fcache;
- }
-
- /* -----------
- * call ExecMakeFunctionResult() with a dummy isDone that we ignore.
- * We don't have operator whose arguments are sets.
- * -----------
- */
- return
- ExecMakeFunctionResult((Node *)op, argList, econtext, isNull, &isDone);
+ Oper *op;
+ List *argList;
+ FunctionCachePtr fcache;
+ bool isDone;
+
+ /* ----------------
+ * an opclause is a list (op args). (I think)
+ *
+ * we extract the oid of the function associated with
+ * the op and then pass the work onto ExecMakeFunctionResult
+ * which evaluates the arguments and returns the result of
+ * calling the function on the evaluated arguments.
+ * ----------------
+ */
+ op = (Oper *) opClause->oper;
+ argList = opClause->args;
+
+ /*
+ * get the fcache from the Oper node. If it is NULL, then initialize
+ * it
+ */
+ fcache = op->op_fcache;
+ if (fcache == NULL)
+ {
+ setFcache((Node *) op, op->opid, argList, econtext);
+ fcache = op->op_fcache;
+ }
+
+ /* -----------
+ * call ExecMakeFunctionResult() with a dummy isDone that we ignore.
+ * We don't have operator whose arguments are sets.
+ * -----------
+ */
+ return
+ ExecMakeFunctionResult((Node *) op, argList, econtext, isNull, &isDone);
}
/* ----------------------------------------------------------------
- * ExecEvalFunc
+ * ExecEvalFunc
* ----------------------------------------------------------------
*/
-static Datum
-ExecEvalFunc(Expr *funcClause,
- ExprContext *econtext,
- bool *isNull,
- bool *isDone)
+static Datum
+ExecEvalFunc(Expr * funcClause,
+ ExprContext * econtext,
+ bool * isNull,
+ bool * isDone)
{
- Func *func;
- List *argList;
- FunctionCachePtr fcache;
-
- /* ----------------
- * an funcclause is a list (func args). (I think)
- *
- * we extract the oid of the function associated with
- * the func node and then pass the work onto ExecMakeFunctionResult
- * which evaluates the arguments and returns the result of
- * calling the function on the evaluated arguments.
- *
- * this is nearly identical to the ExecEvalOper code.
- * ----------------
- */
- func = (Func *)funcClause->oper;
- argList = funcClause->args;
-
- /*
- * get the fcache from the Func node.
- * If it is NULL, then initialize it
- */
- fcache = func->func_fcache;
- if (fcache == NULL) {
- setFcache((Node*)func, func->funcid, argList, econtext);
- fcache = func->func_fcache;
- }
-
- return
- ExecMakeFunctionResult((Node*)func, argList, econtext, isNull, isDone);
+ Func *func;
+ List *argList;
+ FunctionCachePtr fcache;
+
+ /* ----------------
+ * an funcclause is a list (func args). (I think)
+ *
+ * we extract the oid of the function associated with
+ * the func node and then pass the work onto ExecMakeFunctionResult
+ * which evaluates the arguments and returns the result of
+ * calling the function on the evaluated arguments.
+ *
+ * this is nearly identical to the ExecEvalOper code.
+ * ----------------
+ */
+ func = (Func *) funcClause->oper;
+ argList = funcClause->args;
+
+ /*
+ * get the fcache from the Func node. If it is NULL, then initialize
+ * it
+ */
+ fcache = func->func_fcache;
+ if (fcache == NULL)
+ {
+ setFcache((Node *) func, func->funcid, argList, econtext);
+ fcache = func->func_fcache;
+ }
+
+ return
+ ExecMakeFunctionResult((Node *) func, argList, econtext, isNull, isDone);
}
/* ----------------------------------------------------------------
- * ExecEvalNot
- * ExecEvalOr
- * ExecEvalAnd
- *
- * Evaluate boolean expressions. Evaluation of 'or' is
- * short-circuited when the first true (or null) value is found.
+ * ExecEvalNot
+ * ExecEvalOr
+ * ExecEvalAnd
*
- * The query planner reformulates clause expressions in the
- * qualification to conjunctive normal form. If we ever get
- * an AND to evaluate, we can be sure that it's not a top-level
- * clause in the qualification, but appears lower (as a function
- * argument, for example), or in the target list. Not that you
- * need to know this, mind you...
+ * Evaluate boolean expressions. Evaluation of 'or' is
+ * short-circuited when the first true (or null) value is found.
+ *
+ * The query planner reformulates clause expressions in the
+ * qualification to conjunctive normal form. If we ever get
+ * an AND to evaluate, we can be sure that it's not a top-level
+ * clause in the qualification, but appears lower (as a function
+ * argument, for example), or in the target list. Not that you
+ * need to know this, mind you...
* ----------------------------------------------------------------
*/
-static Datum
-ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull)
+static Datum
+ExecEvalNot(Expr * notclause, ExprContext * econtext, bool * isNull)
{
- Datum expr_value;
- Node *clause;
- bool isDone;
-
- clause = lfirst(notclause->args);
-
- /* ----------------
- * We don't iterate over sets in the quals, so pass in an isDone
- * flag, but ignore it.
- * ----------------
- */
- expr_value = ExecEvalExpr(clause, econtext, isNull, &isDone);
-
- /* ----------------
- * if the expression evaluates to null, then we just
- * cascade the null back to whoever called us.
- * ----------------
- */
- if (*isNull)
- return expr_value;
-
- /* ----------------
- * evaluation of 'not' is simple.. expr is false, then
- * return 'true' and vice versa.
- * ----------------
- */
- if (DatumGetInt32(expr_value) == 0)
- return (Datum) true;
-
- return (Datum) false;
-}
+ Datum expr_value;
+ Node *clause;
+ bool isDone;
+
+ clause = lfirst(notclause->args);
-/* ----------------------------------------------------------------
- * ExecEvalOr
- * ----------------------------------------------------------------
- */
-static Datum
-ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
-{
- List *clauses;
- List *clause;
- bool isDone;
- bool IsNull;
- Datum const_value = 0;
-
- IsNull = false;
- clauses = orExpr->args;
-
- /* ----------------
- * we use three valued logic functions here...
- * we evaluate each of the clauses in turn,
- * as soon as one is true we return that
- * value. If none is true and none of the
- * clauses evaluate to NULL we return
- * the value of the last clause evaluated (which
- * should be false) with *isNull set to false else
- * if none is true and at least one clause evaluated
- * to NULL we set *isNull flag to true -
- * ----------------
- */
- foreach (clause, clauses) {
-
/* ----------------
- * We don't iterate over sets in the quals, so pass in an isDone
- * flag, but ignore it.
+ * We don't iterate over sets in the quals, so pass in an isDone
+ * flag, but ignore it.
* ----------------
*/
- const_value = ExecEvalExpr((Node *) lfirst(clause),
- econtext,
- isNull,
- &isDone);
-
+ expr_value = ExecEvalExpr(clause, econtext, isNull, &isDone);
+
/* ----------------
- * if the expression evaluates to null, then we
- * remember it in the local IsNull flag, if none of the
- * clauses are true then we need to set *isNull
- * to true again.
+ * if the expression evaluates to null, then we just
+ * cascade the null back to whoever called us.
* ----------------
*/
if (*isNull)
- IsNull = *isNull;
-
+ return expr_value;
+
/* ----------------
- * if we have a true result, then we return it.
+ * evaluation of 'not' is simple.. expr is false, then
+ * return 'true' and vice versa.
* ----------------
*/
- if (DatumGetInt32(const_value) != 0)
- return const_value;
- }
-
- /* IsNull is true if at least one clause evaluated to NULL */
- *isNull = IsNull;
- return const_value;
+ if (DatumGetInt32(expr_value) == 0)
+ return (Datum) true;
+
+ return (Datum) false;
}
/* ----------------------------------------------------------------
- * ExecEvalAnd
+ * ExecEvalOr
* ----------------------------------------------------------------
*/
-static Datum
-ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
+static Datum
+ExecEvalOr(Expr * orExpr, ExprContext * econtext, bool * isNull)
{
- List *clauses;
- List *clause;
- Datum const_value = 0;
- bool isDone;
- bool IsNull;
-
- IsNull = false;
-
- clauses = andExpr->args;
-
- /* ----------------
- * we evaluate each of the clauses in turn,
- * as soon as one is false we return that
- * value. If none are false or NULL then we return
- * the value of the last clause evaluated, which
- * should be true.
- * ----------------
- */
- foreach (clause, clauses) {
-
- /* ----------------
- * We don't iterate over sets in the quals, so pass in an isDone
- * flag, but ignore it.
- * ----------------
- */
- const_value = ExecEvalExpr((Node *) lfirst(clause),
- econtext,
- isNull,
- &isDone);
-
+ List *clauses;
+ List *clause;
+ bool isDone;
+ bool IsNull;
+ Datum const_value = 0;
+
+ IsNull = false;
+ clauses = orExpr->args;
+
/* ----------------
- * if the expression evaluates to null, then we
- * remember it in IsNull, if none of the clauses after
- * this evaluates to false we will have to set *isNull
- * to true again.
+ * we use three valued logic functions here...
+ * we evaluate each of the clauses in turn,
+ * as soon as one is true we return that
+ * value. If none is true and none of the
+ * clauses evaluate to NULL we return
+ * the value of the last clause evaluated (which
+ * should be false) with *isNull set to false else
+ * if none is true and at least one clause evaluated
+ * to NULL we set *isNull flag to true -
* ----------------
*/
- if (*isNull)
- IsNull = *isNull;
-
+ foreach(clause, clauses)
+ {
+
+ /* ----------------
+ * We don't iterate over sets in the quals, so pass in an isDone
+ * flag, but ignore it.
+ * ----------------
+ */
+ const_value = ExecEvalExpr((Node *) lfirst(clause),
+ econtext,
+ isNull,
+ &isDone);
+
+ /* ----------------
+ * if the expression evaluates to null, then we
+ * remember it in the local IsNull flag, if none of the
+ * clauses are true then we need to set *isNull
+ * to true again.
+ * ----------------
+ */
+ if (*isNull)
+ IsNull = *isNull;
+
+ /* ----------------
+ * if we have a true result, then we return it.
+ * ----------------
+ */
+ if (DatumGetInt32(const_value) != 0)
+ return const_value;
+ }
+
+ /* IsNull is true if at least one clause evaluated to NULL */
+ *isNull = IsNull;
+ return const_value;
+}
+
+/* ----------------------------------------------------------------
+ * ExecEvalAnd
+ * ----------------------------------------------------------------
+ */
+static Datum
+ExecEvalAnd(Expr * andExpr, ExprContext * econtext, bool * isNull)
+{
+ List *clauses;
+ List *clause;
+ Datum const_value = 0;
+ bool isDone;
+ bool IsNull;
+
+ IsNull = false;
+
+ clauses = andExpr->args;
+
/* ----------------
- * if we have a false result, then we return it, since the
- * conjunction must be false.
+ * we evaluate each of the clauses in turn,
+ * as soon as one is false we return that
+ * value. If none are false or NULL then we return
+ * the value of the last clause evaluated, which
+ * should be true.
* ----------------
*/
- if (DatumGetInt32(const_value) == 0)
- return const_value;
- }
-
- *isNull = IsNull;
- return const_value;
+ foreach(clause, clauses)
+ {
+
+ /* ----------------
+ * We don't iterate over sets in the quals, so pass in an isDone
+ * flag, but ignore it.
+ * ----------------
+ */
+ const_value = ExecEvalExpr((Node *) lfirst(clause),
+ econtext,
+ isNull,
+ &isDone);
+
+ /* ----------------
+ * if the expression evaluates to null, then we
+ * remember it in IsNull, if none of the clauses after
+ * this evaluates to false we will have to set *isNull
+ * to true again.
+ * ----------------
+ */
+ if (*isNull)
+ IsNull = *isNull;
+
+ /* ----------------
+ * if we have a false result, then we return it, since the
+ * conjunction must be false.
+ * ----------------
+ */
+ if (DatumGetInt32(const_value) == 0)
+ return const_value;
+ }
+
+ *isNull = IsNull;
+ return const_value;
}
-/* ----------------------------------------------------------------
- * ExecEvalExpr
- *
- * Recursively evaluate a targetlist or qualification expression.
+/* ----------------------------------------------------------------
+ * ExecEvalExpr
+ *
+ * Recursively evaluate a targetlist or qualification expression.
*
- * This routine is an inner loop routine and should be as fast
- * as possible.
+ * This routine is an inner loop routine and should be as fast
+ * as possible.
*
- * Node comparison functions were replaced by macros for speed and to plug
- * memory leaks incurred by using the planner's Lispy stuff for
- * comparisons. Order of evaluation of node comparisons IS IMPORTANT;
- * the macros do no checks. Order of evaluation:
- *
- * o an isnull check, largely to avoid coredumps since greg doubts this
- * routine is called with a null ptr anyway in proper operation, but is
- * not completely sure...
- * o ExactNodeType checks.
- * o clause checks or other checks where we look at the lfirst of something.
+ * Node comparison functions were replaced by macros for speed and to plug
+ * memory leaks incurred by using the planner's Lispy stuff for
+ * comparisons. Order of evaluation of node comparisons IS IMPORTANT;
+ * the macros do no checks. Order of evaluation:
+ *
+ * o an isnull check, largely to avoid coredumps since greg doubts this
+ * routine is called with a null ptr anyway in proper operation, but is
+ * not completely sure...
+ * o ExactNodeType checks.
+ * o clause checks or other checks where we look at the lfirst of something.
* ----------------------------------------------------------------
*/
Datum
-ExecEvalExpr(Node *expression,
- ExprContext *econtext,
- bool *isNull,
- bool *isDone)
+ExecEvalExpr(Node * expression,
+ ExprContext * econtext,
+ bool * isNull,
+ bool * isDone)
{
- Datum retDatum = 0;
-
- *isNull = false;
-
- /*
- * Some callers don't care about is done and only want 1 result. They
- * indicate this by passing NULL
- */
- if (isDone)
- *isDone = true;
-
- /* ----------------
- * here we dispatch the work to the appropriate type
- * of function given the type of our expression.
- * ----------------
- */
- if (expression == NULL) {
- *isNull = true;
- return (Datum) true;
- }
-
- switch(nodeTag(expression)) {
- case T_Var:
- retDatum = (Datum) ExecEvalVar((Var *) expression, econtext, isNull);
- break;
- case T_Const: {
- Const *con = (Const *)expression;
-
- if (con->constisnull)
- *isNull = true;
- retDatum = con->constvalue;
- break;
- }
- case T_Param:
- retDatum = (Datum)ExecEvalParam((Param *)expression, econtext, isNull);
- break;
- case T_Iter:
- retDatum = (Datum) ExecEvalIter((Iter *) expression,
- econtext,
- isNull,
- isDone);
- break;
- case T_Aggreg:
- retDatum = (Datum) ExecEvalAggreg((Aggreg *)expression,
- econtext,
- isNull);
- break;
- case T_ArrayRef:
- retDatum = (Datum) ExecEvalArrayRef((ArrayRef *) expression,
- econtext,
- isNull,
- isDone);
- break;
- case T_Expr: {
- Expr *expr = (Expr *)expression;
- switch (expr->opType) {
- case OP_EXPR:
- retDatum = (Datum) ExecEvalOper(expr, econtext, isNull);
- break;
- case FUNC_EXPR:
- retDatum = (Datum) ExecEvalFunc(expr, econtext, isNull, isDone);
- break;
- case OR_EXPR:
- retDatum = (Datum) ExecEvalOr(expr, econtext, isNull);
- break;
- case AND_EXPR:
- retDatum = (Datum) ExecEvalAnd(expr, econtext, isNull);
- break;
- case NOT_EXPR:
- retDatum = (Datum) ExecEvalNot(expr, econtext, isNull);
- break;
+ Datum retDatum = 0;
+
+ *isNull = false;
+
+ /*
+ * Some callers don't care about is done and only want 1 result. They
+ * indicate this by passing NULL
+ */
+ if (isDone)
+ *isDone = true;
+
+ /* ----------------
+ * here we dispatch the work to the appropriate type
+ * of function given the type of our expression.
+ * ----------------
+ */
+ if (expression == NULL)
+ {
+ *isNull = true;
+ return (Datum) true;
+ }
+
+ switch (nodeTag(expression))
+ {
+ case T_Var:
+ retDatum = (Datum) ExecEvalVar((Var *) expression, econtext, isNull);
+ break;
+ case T_Const:
+ {
+ Const *con = (Const *) expression;
+
+ if (con->constisnull)
+ *isNull = true;
+ retDatum = con->constvalue;
+ break;
+ }
+ case T_Param:
+ retDatum = (Datum) ExecEvalParam((Param *) expression, econtext, isNull);
+ break;
+ case T_Iter:
+ retDatum = (Datum) ExecEvalIter((Iter *) expression,
+ econtext,
+ isNull,
+ isDone);
+ break;
+ case T_Aggreg:
+ retDatum = (Datum) ExecEvalAggreg((Aggreg *) expression,
+ econtext,
+ isNull);
+ break;
+ case T_ArrayRef:
+ retDatum = (Datum) ExecEvalArrayRef((ArrayRef *) expression,
+ econtext,
+ isNull,
+ isDone);
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) expression;
+
+ switch (expr->opType)
+ {
+ case OP_EXPR:
+ retDatum = (Datum) ExecEvalOper(expr, econtext, isNull);
+ break;
+ case FUNC_EXPR:
+ retDatum = (Datum) ExecEvalFunc(expr, econtext, isNull, isDone);
+ break;
+ case OR_EXPR:
+ retDatum = (Datum) ExecEvalOr(expr, econtext, isNull);
+ break;
+ case AND_EXPR:
+ retDatum = (Datum) ExecEvalAnd(expr, econtext, isNull);
+ break;
+ case NOT_EXPR:
+ retDatum = (Datum) ExecEvalNot(expr, econtext, isNull);
+ break;
+ default:
+ elog(WARN, "ExecEvalExpr: unknown expression type");
+ break;
+ }
+ break;
+ }
default:
- elog(WARN, "ExecEvalExpr: unknown expression type");
- break;
+ elog(WARN, "ExecEvalExpr: unknown expression type");
+ break;
}
- break;
- }
- default:
- elog(WARN, "ExecEvalExpr: unknown expression type");
- break;
- }
-
- return retDatum;
+
+ return retDatum;
}
/* ----------------------------------------------------------------
- * ExecQual / ExecTargetList
+ * ExecQual / ExecTargetList
* ----------------------------------------------------------------
*/
/* ----------------------------------------------------------------
- * ExecQualClause
+ * ExecQualClause
*
- * this is a workhorse for ExecQual. ExecQual has to deal
- * with a list of qualifications, so it passes each qualification
- * in the list to this function one at a time. ExecQualClause
- * returns true when the qualification *fails* and false if
- * the qualification succeeded (meaning we have to test the
- * rest of the qualification)
+ * this is a workhorse for ExecQual. ExecQual has to deal
+ * with a list of qualifications, so it passes each qualification
+ * in the list to this function one at a time. ExecQualClause
+ * returns true when the qualification *fails* and false if
+ * the qualification succeeded (meaning we have to test the
+ * rest of the qualification)
* ----------------------------------------------------------------
*/
-static bool
-ExecQualClause(Node *clause, ExprContext *econtext)
+static bool
+ExecQualClause(Node * clause, ExprContext * econtext)
{
- Datum expr_value;
- bool isNull;
- bool isDone;
-
- /* when there is a null clause, consider the qualification to be true */
- if (clause == NULL)
- return true;
-
- /*
- * pass isDone, but ignore it. We don't iterate over multiple
- * returns in the qualifications.
- */
- expr_value = (Datum)
- ExecEvalExpr(clause, econtext, &isNull, &isDone);
-
- /* ----------------
- * this is interesting behaviour here. When a clause evaluates
- * to null, then we consider this as passing the qualification.
- * it seems kind of like, if the qual is NULL, then there's no
- * qual..
- * ----------------
- */
- if (isNull)
- return true;
-
- /* ----------------
- * remember, we return true when the qualification fails..
- * ----------------
- */
- if (DatumGetInt32(expr_value) == 0)
- return true;
-
- return false;
+ Datum expr_value;
+ bool isNull;
+ bool isDone;
+
+ /* when there is a null clause, consider the qualification to be true */
+ if (clause == NULL)
+ return true;
+
+ /*
+ * pass isDone, but ignore it. We don't iterate over multiple returns
+ * in the qualifications.
+ */
+ expr_value = (Datum)
+ ExecEvalExpr(clause, econtext, &isNull, &isDone);
+
+ /* ----------------
+ * this is interesting behaviour here. When a clause evaluates
+ * to null, then we consider this as passing the qualification.
+ * it seems kind of like, if the qual is NULL, then there's no
+ * qual..
+ * ----------------
+ */
+ if (isNull)
+ return true;
+
+ /* ----------------
+ * remember, we return true when the qualification fails..
+ * ----------------
+ */
+ if (DatumGetInt32(expr_value) == 0)
+ return true;
+
+ return false;
}
/* ----------------------------------------------------------------
- * ExecQual
- *
- * Evaluates a conjunctive boolean expression and returns t
- * iff none of the subexpressions are false (or null).
+ * ExecQual
+ *
+ * Evaluates a conjunctive boolean expression and returns t
+ * iff none of the subexpressions are false (or null).
* ----------------------------------------------------------------
*/
bool
-ExecQual(List *qual, ExprContext *econtext)
+ExecQual(List * qual, ExprContext * econtext)
{
- List *clause;
- bool result;
-
- /* ----------------
- * debugging stuff
- * ----------------
- */
- EV_printf("ExecQual: qual is ");
- EV_nodeDisplay(qual);
- EV_printf("\n");
-
- IncrProcessed();
-
- /* ----------------
- * return true immediately if no qual
- * ----------------
- */
- if (qual == NIL)
- return true;
-
- /* ----------------
- * a "qual" is a list of clauses. To evaluate the
- * qual, we evaluate each of the clauses in the list.
- *
- * ExecQualClause returns true when we know the qualification
- * *failed* so we just pass each clause in qual to it until
- * we know the qual failed or there are no more clauses.
- * ----------------
- */
- result = false;
- foreach (clause, qual) {
- result = ExecQualClause((Node *)lfirst(clause), econtext);
+ List *clause;
+ bool result;
+
+ /* ----------------
+ * debugging stuff
+ * ----------------
+ */
+ EV_printf("ExecQual: qual is ");
+ EV_nodeDisplay(qual);
+ EV_printf("\n");
+
+ IncrProcessed();
+
+ /* ----------------
+ * return true immediately if no qual
+ * ----------------
+ */
+ if (qual == NIL)
+ return true;
+
+ /* ----------------
+ * a "qual" is a list of clauses. To evaluate the
+ * qual, we evaluate each of the clauses in the list.
+ *
+ * ExecQualClause returns true when we know the qualification
+ * *failed* so we just pass each clause in qual to it until
+ * we know the qual failed or there are no more clauses.
+ * ----------------
+ */
+ result = false;
+ foreach(clause, qual)
+ {
+ result = ExecQualClause((Node *) lfirst(clause), econtext);
+ if (result == true)
+ break;
+ }
+
+ /* ----------------
+ * if result is true, then it means a clause failed so we
+ * return false. if result is false then it means no clause
+ * failed so we return true.
+ * ----------------
+ */
if (result == true)
- break;
- }
-
- /* ----------------
- * if result is true, then it means a clause failed so we
- * return false. if result is false then it means no clause
- * failed so we return true.
- * ----------------
- */
- if (result == true)
- return false;
-
- return true;
+ return false;
+
+ return true;
}
int
-ExecTargetListLength(List *targetlist)
+ExecTargetListLength(List * targetlist)
{
- int len;
- List *tl;
- TargetEntry *curTle;
-
- len = 0;
- foreach (tl, targetlist) {
- curTle = lfirst(tl);
-
- if (curTle->resdom != NULL)
- len++;
- else
- len += curTle->fjoin->fj_nNodes;
- }
- return len;
+ int len;
+ List *tl;
+ TargetEntry *curTle;
+
+ len = 0;
+ foreach(tl, targetlist)
+ {
+ curTle = lfirst(tl);
+
+ if (curTle->resdom != NULL)
+ len++;
+ else
+ len += curTle->fjoin->fj_nNodes;
+ }
+ return len;
}
/* ----------------------------------------------------------------
- * ExecTargetList
- *
- * Evaluates a targetlist with respect to the current
- * expression context and return a tuple.
+ * ExecTargetList
+ *
+ * Evaluates a targetlist with respect to the current
+ * expression context and return a tuple.
* ----------------------------------------------------------------
*/
-static HeapTuple
-ExecTargetList(List *targetlist,
- int nodomains,
- TupleDesc targettype,
- Datum *values,
- ExprContext *econtext,
- bool *isDone)
+static HeapTuple
+ExecTargetList(List * targetlist,
+ int nodomains,
+ TupleDesc targettype,
+ Datum * values,
+ ExprContext * econtext,
+ bool * isDone)
{
- char nulls_array[64];
- bool fjNullArray[64];
- bool *fjIsNull;
- char *null_head;
- List *tl;
- TargetEntry *tle;
- Node *expr;
- Resdom *resdom;
- AttrNumber resind;
- Datum constvalue;
- HeapTuple newTuple;
- bool isNull;
-
- /* ----------------
- * debugging stuff
- * ----------------
- */
- EV_printf("ExecTargetList: tl is ");
- EV_nodeDisplay(targetlist);
- EV_printf("\n");
-
- /* ----------------
- * Return a dummy tuple if the targetlist is empty .
- * the dummy tuple is necessary to differentiate
- * between passing and failing the qualification.
- * ----------------
- */
- if (targetlist == NIL) {
+ char nulls_array[64];
+ bool fjNullArray[64];
+ bool *fjIsNull;
+ char *null_head;
+ List *tl;
+ TargetEntry *tle;
+ Node *expr;
+ Resdom *resdom;
+ AttrNumber resind;
+ Datum constvalue;
+ HeapTuple newTuple;
+ bool isNull;
+
/* ----------------
- * I now think that the only time this makes
- * any sence is when we run a delete query. Then
- * we need to return something other than nil
- * so we know to delete the tuple associated
- * with the saved tupleid.. see what ExecutePlan
- * does with the returned tuple.. -cim 9/21/89
- *
- * It could also happen in queries like:
- * retrieve (foo.all) where bar.a = 3
- *
- * is this a new phenomenon? it might cause bogus behavior
- * if we try to free this tuple later!! I put a hook in
- * ExecProject to watch out for this case -mer 24 Aug 1992
+ * debugging stuff
* ----------------
*/
- CXT1_printf("ExecTargetList: context is %d\n", CurrentMemoryContext);
- *isDone = true;
- return (HeapTuple) true;
- }
-
- /* ----------------
- * allocate an array of char's to hold the "null" information
- * only if we have a really large targetlist. otherwise we use
- * the stack.
- * ----------------
- */
- if (nodomains > 64) {
- null_head = (char *) palloc(nodomains+1);
- fjIsNull = (bool *) palloc(nodomains+1);
- } else {
- null_head = &nulls_array[0];
- fjIsNull = &fjNullArray[0];
- }
-
- /* ----------------
- * evaluate all the expressions in the target list
- * ----------------
- */
- EV_printf("ExecTargetList: setting target list values\n");
-
- *isDone = true;
- foreach (tl, targetlist) {
+ EV_printf("ExecTargetList: tl is ");
+ EV_nodeDisplay(targetlist);
+ EV_printf("\n");
+
/* ----------------
- * remember, a target list is a list of lists:
- *
- * ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
- *
- * tl is a pointer to successive cdr's of the targetlist
- * tle is a pointer to the target list entry in tl
+ * Return a dummy tuple if the targetlist is empty .
+ * the dummy tuple is necessary to differentiate
+ * between passing and failing the qualification.
+ * ----------------
+ */
+ if (targetlist == NIL)
+ {
+ /* ----------------
+ * I now think that the only time this makes
+ * any sence is when we run a delete query. Then
+ * we need to return something other than nil
+ * so we know to delete the tuple associated
+ * with the saved tupleid.. see what ExecutePlan
+ * does with the returned tuple.. -cim 9/21/89
+ *
+ * It could also happen in queries like:
+ * retrieve (foo.all) where bar.a = 3
+ *
+ * is this a new phenomenon? it might cause bogus behavior
+ * if we try to free this tuple later!! I put a hook in
+ * ExecProject to watch out for this case -mer 24 Aug 1992
+ * ----------------
+ */
+ CXT1_printf("ExecTargetList: context is %d\n", CurrentMemoryContext);
+ *isDone = true;
+ return (HeapTuple) true;
+ }
+
+ /* ----------------
+ * allocate an array of char's to hold the "null" information
+ * only if we have a really large targetlist. otherwise we use
+ * the stack.
* ----------------
*/
- tle = lfirst(tl);
-
- if (tle->resdom != NULL) {
- expr = tle->expr;
- resdom = tle->resdom;
- resind = resdom->resno - 1;
- constvalue = (Datum) ExecEvalExpr(expr,
- econtext,
- &isNull,
- isDone);
-
- if ((IsA(expr,Iter)) && (*isDone))
- return (HeapTuple)NULL;
-
- values[resind] = constvalue;
-
- if (!isNull)
- null_head[resind] = ' ';
- else
- null_head[resind] = 'n';
- }else {
- int curNode;
- Resdom *fjRes;
- List *fjTlist = (List *)tle->expr;
- Fjoin *fjNode = tle->fjoin;
- int nNodes = fjNode->fj_nNodes;
- DatumPtr results = fjNode->fj_results;
-
- ExecEvalFjoin(tle, econtext, fjIsNull, isDone);
- if (*isDone)
- return (HeapTuple)NULL;
-
- /*
- * get the result from the inner node
- */
- fjRes = (Resdom *)fjNode->fj_innerNode;
- resind = fjRes->resno - 1;
- if (fjIsNull[0])
- null_head[resind] = 'n';
- else {
- null_head[resind] = ' ';
- values[resind] = results[0];
- }
-
- /*
- * Get results from all of the outer nodes
- */
- for (curNode = 1;
- curNode < nNodes;
- curNode++, fjTlist = lnext(fjTlist))
+ if (nodomains > 64)
+ {
+ null_head = (char *) palloc(nodomains + 1);
+ fjIsNull = (bool *) palloc(nodomains + 1);
+ }
+ else
+ {
+ null_head = &nulls_array[0];
+ fjIsNull = &fjNullArray[0];
+ }
+
+ /* ----------------
+ * evaluate all the expressions in the target list
+ * ----------------
+ */
+ EV_printf("ExecTargetList: setting target list values\n");
+
+ *isDone = true;
+ foreach(tl, targetlist)
+ {
+ /* ----------------
+ * remember, a target list is a list of lists:
+ *
+ * ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
+ *
+ * tl is a pointer to successive cdr's of the targetlist
+ * tle is a pointer to the target list entry in tl
+ * ----------------
+ */
+ tle = lfirst(tl);
+
+ if (tle->resdom != NULL)
+ {
+ expr = tle->expr;
+ resdom = tle->resdom;
+ resind = resdom->resno - 1;
+ constvalue = (Datum) ExecEvalExpr(expr,
+ econtext,
+ &isNull,
+ isDone);
+
+ if ((IsA(expr, Iter)) && (*isDone))
+ return (HeapTuple) NULL;
+
+ values[resind] = constvalue;
+
+ if (!isNull)
+ null_head[resind] = ' ';
+ else
+ null_head[resind] = 'n';
+ }
+ else
{
-#if 0 /* what is this?? */
- Node *outernode = lfirst(fjTlist);
- fjRes = (Resdom *)outernode->iterexpr;
-#endif
- resind = fjRes->resno - 1;
- if (fjIsNull[curNode]) {
- null_head[resind] = 'n';
- }else {
- null_head[resind] = ' ';
- values[resind] = results[curNode];
- }
+ int curNode;
+ Resdom *fjRes;
+ List *fjTlist = (List *) tle->expr;
+ Fjoin *fjNode = tle->fjoin;
+ int nNodes = fjNode->fj_nNodes;
+ DatumPtr results = fjNode->fj_results;
+
+ ExecEvalFjoin(tle, econtext, fjIsNull, isDone);
+ if (*isDone)
+ return (HeapTuple) NULL;
+
+ /*
+ * get the result from the inner node
+ */
+ fjRes = (Resdom *) fjNode->fj_innerNode;
+ resind = fjRes->resno - 1;
+ if (fjIsNull[0])
+ null_head[resind] = 'n';
+ else
+ {
+ null_head[resind] = ' ';
+ values[resind] = results[0];
+ }
+
+ /*
+ * Get results from all of the outer nodes
+ */
+ for (curNode = 1;
+ curNode < nNodes;
+ curNode++, fjTlist = lnext(fjTlist))
+ {
+#if 0 /* what is this?? */
+ Node *outernode = lfirst(fjTlist);
+
+ fjRes = (Resdom *) outernode->iterexpr;
+#endif
+ resind = fjRes->resno - 1;
+ if (fjIsNull[curNode])
+ {
+ null_head[resind] = 'n';
+ }
+ else
+ {
+ null_head[resind] = ' ';
+ values[resind] = results[curNode];
+ }
+ }
}
}
- }
-
- /* ----------------
- * form the new result tuple (in the "normal" context)
- * ----------------
- */
- newTuple = (HeapTuple)
- heap_formtuple(targettype, values, null_head);
-
- /* ----------------
- * free the nulls array if we allocated one..
- * ----------------
- */
- if (nodomains > 64) pfree(null_head);
-
- return
- newTuple;
+
+ /* ----------------
+ * form the new result tuple (in the "normal" context)
+ * ----------------
+ */
+ newTuple = (HeapTuple)
+ heap_formtuple(targettype, values, null_head);
+
+ /* ----------------
+ * free the nulls array if we allocated one..
+ * ----------------
+ */
+ if (nodomains > 64)
+ pfree(null_head);
+
+ return
+ newTuple;
}
/* ----------------------------------------------------------------
- * ExecProject
- *
- * projects a tuple based in projection info and stores
- * it in the specified tuple table slot.
+ * ExecProject
+ *
+ * projects a tuple based in projection info and stores
+ * it in the specified tuple table slot.
*
- * Note: someday soon the executor can be extended to eliminate
- * redundant projections by storing pointers to datums
- * in the tuple table and then passing these around when
- * possible. this should make things much quicker.
- * -cim 6/3/91
+ * Note: someday soon the executor can be extended to eliminate
+ * redundant projections by storing pointers to datums
+ * in the tuple table and then passing these around when
+ * possible. this should make things much quicker.
+ * -cim 6/3/91
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecProject(ProjectionInfo *projInfo, bool *isDone)
+ExecProject(ProjectionInfo * projInfo, bool * isDone)
{
- TupleTableSlot *slot;
- List *targetlist;
- int len;
- TupleDesc tupType;
- Datum *tupValue;
- ExprContext *econtext;
- HeapTuple newTuple;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- if (projInfo == NULL)
- return (TupleTableSlot *) NULL;
-
- /* ----------------
- * get the projection info we want
- * ----------------
- */
- slot = projInfo->pi_slot;
- targetlist = projInfo->pi_targetlist;
- len = projInfo->pi_len;
- tupType = slot->ttc_tupleDescriptor;
-
- tupValue = projInfo->pi_tupValue;
- econtext = projInfo->pi_exprContext;
-
- if (targetlist == NIL) {
- *isDone = true;
- return (TupleTableSlot *) NULL;
- }
-
- /* ----------------
- * form a new (result) tuple
- * ----------------
- */
- newTuple = ExecTargetList(targetlist,
- len,
- tupType,
- tupValue,
- econtext,
- isDone);
-
- /* ----------------
- * store the tuple in the projection slot and return the slot.
- *
- * If there's no projection target list we don't want to pfree
- * the bogus tuple that ExecTargetList passes back to us.
- * -mer 24 Aug 1992
- * ----------------
- */
- return (TupleTableSlot *)
- ExecStoreTuple(newTuple, /* tuple to store */
- slot, /* slot to store in */
- InvalidBuffer, /* tuple has no buffer */
- true);
-}
+ TupleTableSlot *slot;
+ List *targetlist;
+ int len;
+ TupleDesc tupType;
+ Datum *tupValue;
+ ExprContext *econtext;
+ HeapTuple newTuple;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ if (projInfo == NULL)
+ return (TupleTableSlot *) NULL;
+ /* ----------------
+ * get the projection info we want
+ * ----------------
+ */
+ slot = projInfo->pi_slot;
+ targetlist = projInfo->pi_targetlist;
+ len = projInfo->pi_len;
+ tupType = slot->ttc_tupleDescriptor;
+
+ tupValue = projInfo->pi_tupValue;
+ econtext = projInfo->pi_exprContext;
+
+ if (targetlist == NIL)
+ {
+ *isDone = true;
+ return (TupleTableSlot *) NULL;
+ }
+
+ /* ----------------
+ * form a new (result) tuple
+ * ----------------
+ */
+ newTuple = ExecTargetList(targetlist,
+ len,
+ tupType,
+ tupValue,
+ econtext,
+ isDone);
+
+ /* ----------------
+ * store the tuple in the projection slot and return the slot.
+ *
+ * If there's no projection target list we don't want to pfree
+ * the bogus tuple that ExecTargetList passes back to us.
+ * -mer 24 Aug 1992
+ * ----------------
+ */
+ return (TupleTableSlot *)
+ ExecStoreTuple(newTuple,/* tuple to store */
+ slot, /* slot to store in */
+ InvalidBuffer, /* tuple has no buffer */
+ true);
+}
diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c
index 8e69f491731..6ea50bb2a93 100644
--- a/src/backend/executor/execScan.c
+++ b/src/backend/executor/execScan.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* execScan.c--
- * This code provides support for generalized relation scans. ExecScan
- * is passed a node and a pointer to a function to "do the right thing"
- * and return a tuple from the relation. ExecScan then does the tedious
- * stuff - checking the qualification and projecting the tuple
- * appropriately.
+ * This code provides support for generalized relation scans. ExecScan
+ * is passed a node and a pointer to a function to "do the right thing"
+ * and return a tuple from the relation. ExecScan then does the tedious
+ * stuff - checking the qualification and projecting the tuple
+ * appropriately.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execScan.c,v 1.3 1997/07/28 00:53:51 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execScan.c,v 1.4 1997/09/07 04:41:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,117 +23,123 @@
#include "executor/executor.h"
/* ----------------------------------------------------------------
- * ExecScan
- *
- * Scans the relation using the 'access method' indicated and
- * returns the next qualifying tuple in the direction specified
- * in the global variable ExecDirection.
- * The access method returns the next tuple and execScan() is
- * responisble for checking the tuple returned against the qual-clause.
- *
- * Conditions:
- * -- the "cursor" maintained by the AMI is positioned at the tuple
- * returned previously.
- *
- * Initial States:
- * -- the relation indicated is opened for scanning so that the
- * "cursor" is positioned before the first qualifying tuple.
+ * ExecScan
*
- * May need to put startmmgr and endmmgr in here.
+ * Scans the relation using the 'access method' indicated and
+ * returns the next qualifying tuple in the direction specified
+ * in the global variable ExecDirection.
+ * The access method returns the next tuple and execScan() is
+ * responisble for checking the tuple returned against the qual-clause.
+ *
+ * Conditions:
+ * -- the "cursor" maintained by the AMI is positioned at the tuple
+ * returned previously.
+ *
+ * Initial States:
+ * -- the relation indicated is opened for scanning so that the
+ * "cursor" is positioned before the first qualifying tuple.
+ *
+ * May need to put startmmgr and endmmgr in here.
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecScan(Scan *node,
- TupleTableSlot* (*accessMtd)()) /* function returning a tuple */
+ExecScan(Scan * node,
+ TupleTableSlot * (*accessMtd) ()) /* function returning a
+ * tuple */
{
- CommonScanState *scanstate;
- EState *estate;
- List *qual;
- bool isDone;
-
- TupleTableSlot *slot;
- TupleTableSlot *resultSlot;
- HeapTuple newTuple;
-
- ExprContext *econtext;
- ProjectionInfo *projInfo;
-
-
- /* ----------------
- * initialize misc variables
- * ----------------
- */
- newTuple = NULL;
- slot = NULL;
-
- estate = node->plan.state;
- scanstate = node->scanstate;
-
- /* ----------------
- * get the expression context
- * ----------------
- */
- econtext = scanstate->cstate.cs_ExprContext;
-
- /* ----------------
- * initialize fields in ExprContext which don't change
- * in the course of the scan..
- * ----------------
- */
- qual = node->plan.qual;
- econtext->ecxt_relation = scanstate->css_currentRelation;
- econtext->ecxt_relid = node->scanrelid;
-
- if (scanstate->cstate.cs_TupFromTlist) {
- projInfo = scanstate->cstate.cs_ProjInfo;
- resultSlot = ExecProject(projInfo, &isDone);
- if (!isDone)
- return resultSlot;
- }
- /*
- * get a tuple from the access method
- * loop until we obtain a tuple which passes the qualification.
- */
- for(;;) {
- slot = (TupleTableSlot *) (*accessMtd)(node);
+ CommonScanState *scanstate;
+ EState *estate;
+ List *qual;
+ bool isDone;
+
+ TupleTableSlot *slot;
+ TupleTableSlot *resultSlot;
+ HeapTuple newTuple;
+
+ ExprContext *econtext;
+ ProjectionInfo *projInfo;
+
/* ----------------
- * if the slot returned by the accessMtd contains
- * NULL, then it means there is nothing more to scan
- * so we just return the empty slot.
+ * initialize misc variables
* ----------------
*/
- if (TupIsNull(slot)) return slot;
-
+ newTuple = NULL;
+ slot = NULL;
+
+ estate = node->plan.state;
+ scanstate = node->scanstate;
+
/* ----------------
- * place the current tuple into the expr context
+ * get the expression context
* ----------------
*/
- econtext->ecxt_scantuple = slot;
-
+ econtext = scanstate->cstate.cs_ExprContext;
+
/* ----------------
- * check that the current tuple satisfies the qual-clause
- * if our qualification succeeds then we
- * leave the loop.
+ * initialize fields in ExprContext which don't change
+ * in the course of the scan..
* ----------------
*/
+ qual = node->plan.qual;
+ econtext->ecxt_relation = scanstate->css_currentRelation;
+ econtext->ecxt_relid = node->scanrelid;
+
+ if (scanstate->cstate.cs_TupFromTlist)
+ {
+ projInfo = scanstate->cstate.cs_ProjInfo;
+ resultSlot = ExecProject(projInfo, &isDone);
+ if (!isDone)
+ return resultSlot;
+ }
+
+ /*
+ * get a tuple from the access method loop until we obtain a tuple
+ * which passes the qualification.
+ */
+ for (;;)
+ {
+ slot = (TupleTableSlot *) (*accessMtd) (node);
+
+ /* ----------------
+ * if the slot returned by the accessMtd contains
+ * NULL, then it means there is nothing more to scan
+ * so we just return the empty slot.
+ * ----------------
+ */
+ if (TupIsNull(slot))
+ return slot;
+
+ /* ----------------
+ * place the current tuple into the expr context
+ * ----------------
+ */
+ econtext->ecxt_scantuple = slot;
+
+ /* ----------------
+ * check that the current tuple satisfies the qual-clause
+ * if our qualification succeeds then we
+ * leave the loop.
+ * ----------------
+ */
+
+ /*
+ * add a check for non-nil qual here to avoid a function call to
+ * ExecQual() when the qual is nil
+ */
+ if (!qual || ExecQual(qual, econtext) == true)
+ break;
+ }
- /* add a check for non-nil qual here to avoid a
- function call to ExecQual() when the qual is nil */
- if (!qual || ExecQual(qual, econtext) == true)
- break;
- }
-
- /* ----------------
- * form a projection tuple, store it in the result tuple
- * slot and return it.
- * ----------------
- */
- projInfo = scanstate->cstate.cs_ProjInfo;
+ /* ----------------
+ * form a projection tuple, store it in the result tuple
+ * slot and return it.
+ * ----------------
+ */
+ projInfo = scanstate->cstate.cs_ProjInfo;
- resultSlot = ExecProject(projInfo, &isDone);
- scanstate->cstate.cs_TupFromTlist = !isDone;
+ resultSlot = ExecProject(projInfo, &isDone);
+ scanstate->cstate.cs_TupFromTlist = !isDone;
- return resultSlot;
+ return resultSlot;
}
-
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 0d5e7fda9fb..287f75699af 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -1,119 +1,119 @@
/*-------------------------------------------------------------------------
*
* execTuples.c--
- * Routines dealing with the executor tuple tables. These are used to
- * ensure that the executor frees copies of tuples (made by
- * ExecTargetList) properly.
+ * Routines dealing with the executor tuple tables. These are used to
+ * ensure that the executor frees copies of tuples (made by
+ * ExecTargetList) properly.
+ *
+ * Routines dealing with the type information for tuples. Currently,
+ * the type information for a tuple is an array of FormData_pg_attribute.
+ * This information is needed by routines manipulating tuples
+ * (getattribute, formtuple, etc.).
*
- * Routines dealing with the type information for tuples. Currently,
- * the type information for a tuple is an array of FormData_pg_attribute.
- * This information is needed by routines manipulating tuples
- * (getattribute, formtuple, etc.).
- *
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.6 1997/08/19 21:31:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.7 1997/09/07 04:41:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
*
- * TABLE CREATE/DELETE
- * ExecCreateTupleTable - create a new tuple table
- * ExecDestroyTupleTable - destroy a table
+ * TABLE CREATE/DELETE
+ * ExecCreateTupleTable - create a new tuple table
+ * ExecDestroyTupleTable - destroy a table
*
- * SLOT RESERVERATION
- * ExecAllocTableSlot - find an available slot in the table
+ * SLOT RESERVERATION
+ * ExecAllocTableSlot - find an available slot in the table
*
- * SLOT ACCESSORS
- * ExecStoreTuple - store a tuple in the table
- * ExecFetchTuple - fetch a tuple from the table
- * ExecClearTuple - clear contents of a table slot
- * ExecSlotPolicy - return slot's tuple pfree policy
- * ExecSetSlotPolicy - diddle the slot policy
- * ExecSlotDescriptor - type of tuple in a slot
- * ExecSetSlotDescriptor - set a slot's tuple descriptor
- * ExecSetSlotDescriptorIsNew - diddle the slot-desc-is-new flag
- * ExecSetNewSlotDescriptor - set a desc and the is-new-flag all at once
- * ExecSlotBuffer - return buffer of tuple in slot
- * ExecSetSlotBuffer - set the buffer for tuple in slot
- * ExecIncrSlotBufferRefcnt - bump the refcnt of the slot buffer
+ * SLOT ACCESSORS
+ * ExecStoreTuple - store a tuple in the table
+ * ExecFetchTuple - fetch a tuple from the table
+ * ExecClearTuple - clear contents of a table slot
+ * ExecSlotPolicy - return slot's tuple pfree policy
+ * ExecSetSlotPolicy - diddle the slot policy
+ * ExecSlotDescriptor - type of tuple in a slot
+ * ExecSetSlotDescriptor - set a slot's tuple descriptor
+ * ExecSetSlotDescriptorIsNew - diddle the slot-desc-is-new flag
+ * ExecSetNewSlotDescriptor - set a desc and the is-new-flag all at once
+ * ExecSlotBuffer - return buffer of tuple in slot
+ * ExecSetSlotBuffer - set the buffer for tuple in slot
+ * ExecIncrSlotBufferRefcnt - bump the refcnt of the slot buffer
*
- * SLOT STATUS PREDICATES
- * TupIsNull - true when slot contains no tuple
- * ExecSlotDescriptorIsNew - true if we're now storing a different
- * type of tuple in a slot
+ * SLOT STATUS PREDICATES
+ * TupIsNull - true when slot contains no tuple
+ * ExecSlotDescriptorIsNew - true if we're now storing a different
+ * type of tuple in a slot
*
- * CONVENIENCE INITIALIZATION ROUTINES
- * ExecInitResultTupleSlot \ convience routines to initialize
- * ExecInitScanTupleSlot \ the various tuple slots for nodes
- * ExecInitMarkedTupleSlot / which store copies of tuples.
- * ExecInitOuterTupleSlot /
- * ExecInitHashTupleSlot /
+ * CONVENIENCE INITIALIZATION ROUTINES
+ * ExecInitResultTupleSlot \ convience routines to initialize
+ * ExecInitScanTupleSlot \ the various tuple slots for nodes
+ * ExecInitMarkedTupleSlot / which store copies of tuples.
+ * ExecInitOuterTupleSlot /
+ * ExecInitHashTupleSlot /
*
- * old routines:
- * ExecGetTupType - get type of tuple returned by this node
- * ExecTypeFromTL - form a TupleDesc from a target list
+ * old routines:
+ * ExecGetTupType - get type of tuple returned by this node
+ * ExecTypeFromTL - form a TupleDesc from a target list
*
- * EXAMPLE OF HOW TABLE ROUTINES WORK
- * Suppose we have a query such as retrieve (EMP.name) and we have
- * a single SeqScan node in the query plan.
+ * EXAMPLE OF HOW TABLE ROUTINES WORK
+ * Suppose we have a query such as retrieve (EMP.name) and we have
+ * a single SeqScan node in the query plan.
*
- * At ExecStart()
- * ----------------
- * - InitPlan() calls ExecCreateTupleTable() to create the tuple
- * table which will hold tuples processed by the executor.
+ * At ExecStart()
+ * ----------------
+ * - InitPlan() calls ExecCreateTupleTable() to create the tuple
+ * table which will hold tuples processed by the executor.
*
- * - ExecInitSeqScan() calls ExecInitScanTupleSlot() and
- * ExecInitResultTupleSlot() to reserve places in the tuple
- * table for the tuples returned by the access methods and the
- * tuples resulting from preforming target list projections.
+ * - ExecInitSeqScan() calls ExecInitScanTupleSlot() and
+ * ExecInitResultTupleSlot() to reserve places in the tuple
+ * table for the tuples returned by the access methods and the
+ * tuples resulting from preforming target list projections.
*
- * During ExecRun()
- * ----------------
- * - SeqNext() calls ExecStoreTuple() to place the tuple returned
- * by the access methods into the scan tuple slot.
+ * During ExecRun()
+ * ----------------
+ * - SeqNext() calls ExecStoreTuple() to place the tuple returned
+ * by the access methods into the scan tuple slot.
*
- * - ExecSeqScan() calls ExecStoreTuple() to take the result
- * tuple from ExecTargetList() and place it into the result tuple
- * slot.
+ * - ExecSeqScan() calls ExecStoreTuple() to take the result
+ * tuple from ExecTargetList() and place it into the result tuple
+ * slot.
*
- * - ExecutePlan() calls ExecRetrieve() which gets the tuple out of
- * the slot passed to it by calling ExecFetchTuple(). this tuple
- * is then returned.
+ * - ExecutePlan() calls ExecRetrieve() which gets the tuple out of
+ * the slot passed to it by calling ExecFetchTuple(). this tuple
+ * is then returned.
*
- * At ExecEnd()
- * ----------------
- * - EndPlan() calls ExecDestroyTupleTable() to clean up any remaining
- * tuples left over from executing the query.
+ * At ExecEnd()
+ * ----------------
+ * - EndPlan() calls ExecDestroyTupleTable() to clean up any remaining
+ * tuples left over from executing the query.
*
- * The important thing to watch in the executor code is how pointers
- * to the slots containing tuples are passed instead of the tuples
- * themselves. This facilitates the communication of related information
- * (such as whether or not a tuple should be pfreed, what buffer contains
- * this tuple, the tuple's tuple descriptor, etc). Note that much of
- * this information is also kept in the ExprContext of each node.
- * Soon the executor will be redesigned and ExprContext's will contain
- * only slot pointers. -cim 3/14/91
+ * The important thing to watch in the executor code is how pointers
+ * to the slots containing tuples are passed instead of the tuples
+ * themselves. This facilitates the communication of related information
+ * (such as whether or not a tuple should be pfreed, what buffer contains
+ * this tuple, the tuple's tuple descriptor, etc). Note that much of
+ * this information is also kept in the ExprContext of each node.
+ * Soon the executor will be redesigned and ExprContext's will contain
+ * only slot pointers. -cim 3/14/91
*
- * NOTES
- * The tuple table stuff is relatively new, put here to alleviate
- * the process growth problems in the executor. The other routines
- * are old (from the original lisp system) and may someday become
- * obsolete. -cim 6/23/90
+ * NOTES
+ * The tuple table stuff is relatively new, put here to alleviate
+ * the process growth problems in the executor. The other routines
+ * are old (from the original lisp system) and may someday become
+ * obsolete. -cim 6/23/90
*
- * In the implementation of nested-dot queries such as
- * "retrieve (EMP.hobbies.all)", a single scan may return tuples
- * of many types, so now we return pointers to tuple descriptors
- * along with tuples returned via the tuple table. This means
- * we now have a bunch of routines to diddle the slot descriptors
- * too. -cim 1/18/90
+ * In the implementation of nested-dot queries such as
+ * "retrieve (EMP.hobbies.all)", a single scan may return tuples
+ * of many types, so now we return pointers to tuple descriptors
+ * along with tuples returned via the tuple table. This means
+ * we now have a bunch of routines to diddle the slot descriptors
+ * too. -cim 1/18/90
*
- * The tuple table stuff depends on the executor/tuptable.h macros,
- * and the TupleTableSlot node in execnodes.h.
+ * The tuple table stuff depends on the executor/tuptable.h macros,
+ * and the TupleTableSlot node in execnodes.h.
*
*/
#include <string.h>
@@ -131,902 +131,938 @@
#include "parser/catalog_utils.h"
#include "catalog/pg_type.h"
-static TupleTableSlot *NodeGetResultTupleSlot(Plan *node);
+static TupleTableSlot *NodeGetResultTupleSlot(Plan * node);
/* ----------------------------------------------------------------
- * tuple table create/delete functions
+ * tuple table create/delete functions
* ----------------------------------------------------------------
*/
/* --------------------------------
- * ExecCreateTupleTable
+ * ExecCreateTupleTable
*
- * This creates a new tuple table of the specified initial
- * size. If the size is insufficient, ExecAllocTableSlot()
- * will grow the table as necessary.
+ * This creates a new tuple table of the specified initial
+ * size. If the size is insufficient, ExecAllocTableSlot()
+ * will grow the table as necessary.
*
- * This should be used by InitPlan() to allocate the table.
- * The table's address will be stored in the EState structure.
+ * This should be used by InitPlan() to allocate the table.
+ * The table's address will be stored in the EState structure.
* --------------------------------
*/
-TupleTable /* return: address of table */
-ExecCreateTupleTable(int initialSize) /* initial number of slots in table */
+TupleTable /* return: address of table */
+ExecCreateTupleTable(int initialSize) /* initial number of slots
+ * in table */
{
- TupleTable newtable; /* newly allocated table */
- TupleTableSlot* array; /* newly allocated slot array */
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(initialSize >= 1);
-
- /* ----------------
- * Now allocate our new table along with space for the pointers
- * to the tuples.
- */
-
- newtable = (TupleTable) palloc(sizeof(TupleTableData));
- array = (TupleTableSlot*) palloc(initialSize * sizeof(TupleTableSlot));
-
- /* ----------------
- * clean out the slots we just allocated
- * ----------------
- */
- memset(array, 0, initialSize * sizeof(TupleTableSlot));
-
- /* ----------------
- * initialize the new table and return it to the caller.
- * ----------------
- */
- newtable->size = initialSize;
- newtable->next = 0;
- newtable->array = array;
-
- return newtable;
+ TupleTable newtable; /* newly allocated table */
+ TupleTableSlot *array; /* newly allocated slot array */
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(initialSize >= 1);
+
+ /* ----------------
+ * Now allocate our new table along with space for the pointers
+ * to the tuples.
+ */
+
+ newtable = (TupleTable) palloc(sizeof(TupleTableData));
+ array = (TupleTableSlot *) palloc(initialSize * sizeof(TupleTableSlot));
+
+ /* ----------------
+ * clean out the slots we just allocated
+ * ----------------
+ */
+ memset(array, 0, initialSize * sizeof(TupleTableSlot));
+
+ /* ----------------
+ * initialize the new table and return it to the caller.
+ * ----------------
+ */
+ newtable->size = initialSize;
+ newtable->next = 0;
+ newtable->array = array;
+
+ return newtable;
}
/* --------------------------------
- * ExecDestroyTupleTable
+ * ExecDestroyTupleTable
*
- * This pfrees the storage assigned to the tuple table and
- * optionally pfrees the contents of the table also.
- * It is expected that this routine be called by EndPlan().
+ * This pfrees the storage assigned to the tuple table and
+ * optionally pfrees the contents of the table also.
+ * It is expected that this routine be called by EndPlan().
* --------------------------------
*/
void
-ExecDestroyTupleTable(TupleTable table, /* tuple table */
- bool shouldFree) /* true if we should free slot contents */
+ExecDestroyTupleTable(TupleTable table, /* tuple table */
+ bool shouldFree) /* true if we should free slot
+ * contents */
{
- int next; /* next avaliable slot */
- TupleTableSlot *array; /* start of table array */
- int i; /* counter */
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(table != NULL);
-
- /* ----------------
- * get information from the table
- * ----------------
- */
- array = table->array;
- next = table->next;
-
- /* ----------------
- * first free all the valid pointers in the tuple array
- * if that's what the caller wants..
- *
- * Note: we do nothing about the Buffer and Tuple Descriptor's
- * we store in the slots. This may have to change (ex: we should
- * probably worry about pfreeing tuple descs too) -cim 3/14/91
- * ----------------
- */
- if (shouldFree)
- for (i = 0; i < next; i++) {
- TupleTableSlot slot;
- HeapTuple tuple;
-
- slot = array[i];
- tuple = slot.val;
-
- if (tuple != NULL) {
- slot.val = (HeapTuple)NULL;
- if (slot.ttc_shouldFree) {
- /* ----------------
- * since a tuple may contain a pointer to
- * lock information allocated along with the
- * tuple, we have to be careful to free any
- * rule locks also -cim 1/17/90
- * ----------------
- */
- pfree(tuple);
+ int next; /* next avaliable slot */
+ TupleTableSlot *array; /* start of table array */
+ int i; /* counter */
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(table != NULL);
+
+ /* ----------------
+ * get information from the table
+ * ----------------
+ */
+ array = table->array;
+ next = table->next;
+
+ /* ----------------
+ * first free all the valid pointers in the tuple array
+ * if that's what the caller wants..
+ *
+ * Note: we do nothing about the Buffer and Tuple Descriptor's
+ * we store in the slots. This may have to change (ex: we should
+ * probably worry about pfreeing tuple descs too) -cim 3/14/91
+ * ----------------
+ */
+ if (shouldFree)
+ for (i = 0; i < next; i++)
+ {
+ TupleTableSlot slot;
+ HeapTuple tuple;
+
+ slot = array[i];
+ tuple = slot.val;
+
+ if (tuple != NULL)
+ {
+ slot.val = (HeapTuple) NULL;
+ if (slot.ttc_shouldFree)
+ {
+ /* ----------------
+ * since a tuple may contain a pointer to
+ * lock information allocated along with the
+ * tuple, we have to be careful to free any
+ * rule locks also -cim 1/17/90
+ * ----------------
+ */
+ pfree(tuple);
+ }
+ }
}
- }
- }
-
- /* ----------------
- * finally free the tuple array and the table itself.
- * ----------------
- */
- pfree(array);
- pfree(table);
-
+
+ /* ----------------
+ * finally free the tuple array and the table itself.
+ * ----------------
+ */
+ pfree(array);
+ pfree(table);
+
}
/* ----------------------------------------------------------------
- * tuple table slot reservation functions
+ * tuple table slot reservation functions
* ----------------------------------------------------------------
*/
/* --------------------------------
- * ExecAllocTableSlot
+ * ExecAllocTableSlot
*
- * This routine is used to reserve slots in the table for
- * use by the various plan nodes. It is expected to be
- * called by the node init routines (ex: ExecInitNestLoop).
- * once per slot needed by the node. Not all nodes need
- * slots (some just pass tuples around).
+ * This routine is used to reserve slots in the table for
+ * use by the various plan nodes. It is expected to be
+ * called by the node init routines (ex: ExecInitNestLoop).
+ * once per slot needed by the node. Not all nodes need
+ * slots (some just pass tuples around).
* --------------------------------
*/
-TupleTableSlot* /* return: the slot allocated in the tuple table */
+TupleTableSlot * /* return: the slot allocated in the tuple
+ * table */
ExecAllocTableSlot(TupleTable table)
{
- int slotnum; /* new slot number */
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(table != NULL);
-
- /* ----------------
- * if our table is full we have to allocate a larger
- * size table. Since ExecAllocTableSlot() is only called
- * before the table is ever used to store tuples, we don't
- * have to worry about the contents of the old table.
- * If this changes, then we will have to preserve the contents.
- * -cim 6/23/90
- *
- * Unfortunately, we *cannot* do this. All of the nodes in
- * the plan that have already initialized their slots will have
- * pointers into _freed_ memory. This leads to bad ends. We
- * now count the number of slots we will need and create all the
- * slots we will need ahead of time. The if below should never
- * happen now. Give a WARN if it does. -mer 4 Aug 1992
- * ----------------
- */
- if (table->next >= table->size) {
- /*
- * int newsize = NewTableSize(table->size);
+ int slotnum; /* new slot number */
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(table != NULL);
+
+ /* ----------------
+ * if our table is full we have to allocate a larger
+ * size table. Since ExecAllocTableSlot() is only called
+ * before the table is ever used to store tuples, we don't
+ * have to worry about the contents of the old table.
+ * If this changes, then we will have to preserve the contents.
+ * -cim 6/23/90
*
- * pfree(table->array);
- * table->array = (Pointer) palloc(newsize * TableSlotSize);
- * bzero(table->array, newsize * TableSlotSize);
- * table->size = newsize;
+ * Unfortunately, we *cannot* do this. All of the nodes in
+ * the plan that have already initialized their slots will have
+ * pointers into _freed_ memory. This leads to bad ends. We
+ * now count the number of slots we will need and create all the
+ * slots we will need ahead of time. The if below should never
+ * happen now. Give a WARN if it does. -mer 4 Aug 1992
+ * ----------------
*/
- elog(NOTICE, "Plan requires more slots than are available");
- elog(WARN, "send mail to your local executor guru to fix this");
- }
-
- /* ----------------
- * at this point, space in the table is guaranteed so we
- * reserve the next slot, initialize and return it.
- * ----------------
- */
- slotnum = table->next;
- table->next++;
-
- table->array[slotnum].type = T_TupleTableSlot;
-
- return &(table->array[slotnum]);
+ if (table->next >= table->size)
+ {
+
+ /*
+ * int newsize = NewTableSize(table->size);
+ *
+ * pfree(table->array); table->array = (Pointer) palloc(newsize *
+ * TableSlotSize); bzero(table->array, newsize * TableSlotSize);
+ * table->size = newsize;
+ */
+ elog(NOTICE, "Plan requires more slots than are available");
+ elog(WARN, "send mail to your local executor guru to fix this");
+ }
+
+ /* ----------------
+ * at this point, space in the table is guaranteed so we
+ * reserve the next slot, initialize and return it.
+ * ----------------
+ */
+ slotnum = table->next;
+ table->next++;
+
+ table->array[slotnum].type = T_TupleTableSlot;
+
+ return &(table->array[slotnum]);
}
/* ----------------------------------------------------------------
- * tuple table slot accessor functions
+ * tuple table slot accessor functions
* ----------------------------------------------------------------
*/
/* --------------------------------
- * ExecStoreTuple
+ * ExecStoreTuple
*
- * This function is used to store a tuple into a specified
- * slot in the tuple table. Note: the only slots which should
- * be called with shouldFree == false are those slots used to
- * store tuples not allocated with pfree(). Currently the
- * seqscan and indexscan nodes use this for the tuples returned
- * by amgetattr, which are actually pointers onto disk pages.
+ * This function is used to store a tuple into a specified
+ * slot in the tuple table. Note: the only slots which should
+ * be called with shouldFree == false are those slots used to
+ * store tuples not allocated with pfree(). Currently the
+ * seqscan and indexscan nodes use this for the tuples returned
+ * by amgetattr, which are actually pointers onto disk pages.
* --------------------------------
*/
-TupleTableSlot* /* return: slot passed */
-ExecStoreTuple(HeapTuple tuple, /* tuple to store */
- TupleTableSlot* slot, /* slot in which to store tuple */
- Buffer buffer, /* buffer associated with tuple */
- bool shouldFree) /* true if we call pfree() when we gc. */
+TupleTableSlot * /* return: slot passed */
+ExecStoreTuple(HeapTuple tuple, /* tuple to store */
+ TupleTableSlot * slot, /* slot in which to store tuple */
+ Buffer buffer, /* buffer associated with tuple */
+ bool shouldFree) /* true if we call pfree() when we gc. */
{
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(slot != NULL);
-
- /* clear out the slot first */
- ExecClearTuple(slot);
-
- /* ----------------
- * store the new tuple into the specified slot and
- * return the slot into which we stored the tuple.
- * ----------------
- */
- slot->val = tuple;
- slot->ttc_buffer = buffer;
- slot->ttc_shouldFree = shouldFree;
-
- return slot;
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(slot != NULL);
+
+ /* clear out the slot first */
+ ExecClearTuple(slot);
+
+ /* ----------------
+ * store the new tuple into the specified slot and
+ * return the slot into which we stored the tuple.
+ * ----------------
+ */
+ slot->val = tuple;
+ slot->ttc_buffer = buffer;
+ slot->ttc_shouldFree = shouldFree;
+
+ return slot;
}
/* --------------------------------
- * ExecClearTuple
+ * ExecClearTuple
*
- * This function is used to clear out a slot in the tuple table.
+ * This function is used to clear out a slot in the tuple table.
* --------------------------------
*/
-TupleTableSlot* /* return: slot passed */
-ExecClearTuple(TupleTableSlot* slot) /* slot in which to store tuple */
+TupleTableSlot * /* return: slot passed */
+ExecClearTuple(TupleTableSlot * slot) /* slot in which to store tuple */
{
- HeapTuple oldtuple; /* prior contents of slot */
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(slot != NULL);
-
- /* ----------------
- * get information from the tuple table
- * ----------------
- */
- oldtuple = slot->val;
-
- /* ----------------
- * free the old contents of the specified slot if necessary.
- * ----------------
- */
- if (slot->ttc_shouldFree && oldtuple != NULL) {
+ HeapTuple oldtuple; /* prior contents of slot */
+
/* ----------------
- * since a tuple may contain a pointer to
- * lock information allocated along with the
- * tuple, we have to be careful to free any
- * rule locks also -cim 1/17/90
+ * sanity checks
* ----------------
*/
- pfree(oldtuple);
- }
-
- /* ----------------
- * store NULL into the specified slot and return the slot.
- * - also set buffer to InvalidBuffer -cim 3/14/91
- * ----------------
- */
- slot->val = (HeapTuple)NULL;
-
- if (BufferIsValid(slot->ttc_buffer))
- ReleaseBuffer(slot->ttc_buffer);
-
- slot->ttc_buffer = InvalidBuffer;
- slot->ttc_shouldFree = true;
-
- return slot;
+ Assert(slot != NULL);
+
+ /* ----------------
+ * get information from the tuple table
+ * ----------------
+ */
+ oldtuple = slot->val;
+
+ /* ----------------
+ * free the old contents of the specified slot if necessary.
+ * ----------------
+ */
+ if (slot->ttc_shouldFree && oldtuple != NULL)
+ {
+ /* ----------------
+ * since a tuple may contain a pointer to
+ * lock information allocated along with the
+ * tuple, we have to be careful to free any
+ * rule locks also -cim 1/17/90
+ * ----------------
+ */
+ pfree(oldtuple);
+ }
+
+ /* ----------------
+ * store NULL into the specified slot and return the slot.
+ * - also set buffer to InvalidBuffer -cim 3/14/91
+ * ----------------
+ */
+ slot->val = (HeapTuple) NULL;
+
+ if (BufferIsValid(slot->ttc_buffer))
+ ReleaseBuffer(slot->ttc_buffer);
+
+ slot->ttc_buffer = InvalidBuffer;
+ slot->ttc_shouldFree = true;
+
+ return slot;
}
/* --------------------------------
- * ExecSlotPolicy
+ * ExecSlotPolicy
*
- * This function is used to get the call/don't call pfree
- * setting of a slot. Most executor routines don't need this.
- * It's only when you do tricky things like marking tuples for
- * merge joins that you need to diddle the slot policy.
+ * This function is used to get the call/don't call pfree
+ * setting of a slot. Most executor routines don't need this.
+ * It's only when you do tricky things like marking tuples for
+ * merge joins that you need to diddle the slot policy.
* --------------------------------
*/
#ifdef NOT_USED
-bool /* return: slot policy */
-ExecSlotPolicy(TupleTableSlot* slot) /* slot to inspect */
+bool /* return: slot policy */
+ExecSlotPolicy(TupleTableSlot * slot) /* slot to inspect */
{
- return slot->ttc_shouldFree;
+ return slot->ttc_shouldFree;
}
+
#endif
/* --------------------------------
- * ExecSetSlotPolicy
+ * ExecSetSlotPolicy
*
- * This function is used to change the call/don't call pfree
- * setting of a slot. Most executor routines don't need this.
- * It's only when you do tricky things like marking tuples for
- * merge joins that you need to diddle the slot policy.
+ * This function is used to change the call/don't call pfree
+ * setting of a slot. Most executor routines don't need this.
+ * It's only when you do tricky things like marking tuples for
+ * merge joins that you need to diddle the slot policy.
* --------------------------------
*/
-bool /* return: old slot policy */
-ExecSetSlotPolicy(TupleTableSlot* slot, /* slot to change */
- bool shouldFree) /* true if we call pfree() when we gc. */
+bool /* return: old slot policy */
+ExecSetSlotPolicy(TupleTableSlot * slot, /* slot to change */
+ bool shouldFree) /* true if we call pfree() when we
+ * gc. */
{
- bool old_shouldFree = slot->ttc_shouldFree;
- slot->ttc_shouldFree = shouldFree;
+ bool old_shouldFree = slot->ttc_shouldFree;
- return old_shouldFree;
+ slot->ttc_shouldFree = shouldFree;
+
+ return old_shouldFree;
}
/* --------------------------------
- * ExecSlotDescriptor
+ * ExecSlotDescriptor
*
- * This function is used to get the tuple descriptor associated
- * with the slot's tuple.
+ * This function is used to get the tuple descriptor associated
+ * with the slot's tuple.
*
* Now a macro in tuptable.h -mer 5 March 1992
* --------------------------------
*/
/* --------------------------------
- * ExecSetSlotDescriptor
+ * ExecSetSlotDescriptor
*
- * This function is used to set the tuple descriptor associated
- * with the slot's tuple.
+ * This function is used to set the tuple descriptor associated
+ * with the slot's tuple.
* --------------------------------
*/
-TupleDesc /* return: old slot tuple descriptor */
-ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */
- TupleDesc tupdesc) /* tuple descriptor */
+TupleDesc /* return: old slot tuple descriptor */
+ExecSetSlotDescriptor(TupleTableSlot * slot, /* slot to change */
+ TupleDesc tupdesc) /* tuple descriptor */
{
- TupleDesc old_tupdesc = slot->ttc_tupleDescriptor;
+ TupleDesc old_tupdesc = slot->ttc_tupleDescriptor;
- slot->ttc_tupleDescriptor = tupdesc;
- return old_tupdesc;
+ slot->ttc_tupleDescriptor = tupdesc;
+ return old_tupdesc;
}
/* --------------------------------
- * ExecSetSlotDescriptorIsNew
+ * ExecSetSlotDescriptorIsNew
*
- * This function is used to change the setting of the "isNew" flag
+ * This function is used to change the setting of the "isNew" flag
* --------------------------------
*/
void
-ExecSetSlotDescriptorIsNew(TupleTableSlot *slot,/* slot to change */
- bool isNew) /* "isNew" setting */
+ExecSetSlotDescriptorIsNew(TupleTableSlot * slot, /* slot to change */
+ bool isNew) /* "isNew" setting */
{
- slot->ttc_descIsNew = isNew;
+ slot->ttc_descIsNew = isNew;
}
/* --------------------------------
- * ExecSetNewSlotDescriptor
+ * ExecSetNewSlotDescriptor
*
- * This function is used to set the tuple descriptor associated
- * with the slot's tuple, and set the "isNew" flag at the same time.
+ * This function is used to set the tuple descriptor associated
+ * with the slot's tuple, and set the "isNew" flag at the same time.
* --------------------------------
*/
#ifdef NOT_USED
-TupleDesc /* return: old slot tuple descriptor */
-ExecSetNewSlotDescriptor(TupleTableSlot *slot, /* slot to change */
- TupleDesc tupdesc) /* tuple descriptor */
+TupleDesc /* return: old slot tuple descriptor */
+ExecSetNewSlotDescriptor(TupleTableSlot * slot, /* slot to change */
+ TupleDesc tupdesc) /* tuple descriptor */
{
- TupleDesc old_tupdesc = slot->ttc_tupleDescriptor;
- slot->ttc_tupleDescriptor = tupdesc;
- slot->ttc_descIsNew = true;
-
- return old_tupdesc;
+ TupleDesc old_tupdesc = slot->ttc_tupleDescriptor;
+
+ slot->ttc_tupleDescriptor = tupdesc;
+ slot->ttc_descIsNew = true;
+
+ return old_tupdesc;
}
+
#endif
/* --------------------------------
- * ExecSlotBuffer
+ * ExecSlotBuffer
*
- * This function is used to get the tuple descriptor associated
- * with the slot's tuple. Be very careful with this as it does not
- * balance the reference counts. If the buffer returned is stored
- * someplace else, then also use ExecIncrSlotBufferRefcnt().
+ * This function is used to get the tuple descriptor associated
+ * with the slot's tuple. Be very careful with this as it does not
+ * balance the reference counts. If the buffer returned is stored
+ * someplace else, then also use ExecIncrSlotBufferRefcnt().
*
* Now a macro in tuptable.h
* --------------------------------
*/
/* --------------------------------
- * ExecSetSlotBuffer
+ * ExecSetSlotBuffer
*
- * This function is used to set the tuple descriptor associated
- * with the slot's tuple. Be very careful with this as it does not
- * balance the reference counts. If we're using this then we should
- * also use ExecIncrSlotBufferRefcnt().
+ * This function is used to set the tuple descriptor associated
+ * with the slot's tuple. Be very careful with this as it does not
+ * balance the reference counts. If we're using this then we should
+ * also use ExecIncrSlotBufferRefcnt().
* --------------------------------
*/
#ifdef NOT_USED
-Buffer /* return: old slot buffer */
-ExecSetSlotBuffer(TupleTableSlot *slot, /* slot to change */
- Buffer b) /* tuple descriptor */
+Buffer /* return: old slot buffer */
+ExecSetSlotBuffer(TupleTableSlot * slot, /* slot to change */
+ Buffer b) /* tuple descriptor */
{
- Buffer oldb = slot->ttc_buffer;
- slot->ttc_buffer = b;
-
- return oldb;
+ Buffer oldb = slot->ttc_buffer;
+
+ slot->ttc_buffer = b;
+
+ return oldb;
}
+
#endif
/* --------------------------------
- * ExecIncrSlotBufferRefcnt
+ * ExecIncrSlotBufferRefcnt
*
- * When we pass around buffers in the tuple table, we have to
- * be careful to increment reference counts appropriately.
- * This is used mainly in the mergejoin code.
+ * When we pass around buffers in the tuple table, we have to
+ * be careful to increment reference counts appropriately.
+ * This is used mainly in the mergejoin code.
* --------------------------------
*/
void
-ExecIncrSlotBufferRefcnt(TupleTableSlot *slot) /* slot to bump refcnt */
+ExecIncrSlotBufferRefcnt(TupleTableSlot * slot) /* slot to bump refcnt */
{
-/* Buffer b = SlotBuffer((TupleTableSlot*) slot); */
- Buffer b = slot->ttc_buffer;
- if (BufferIsValid(b))
- IncrBufferRefCount(b);
+/* Buffer b = SlotBuffer((TupleTableSlot*) slot); */
+ Buffer b = slot->ttc_buffer;
+
+ if (BufferIsValid(b))
+ IncrBufferRefCount(b);
}
/* ----------------------------------------------------------------
- * tuple table slot status predicates
+ * tuple table slot status predicates
* ----------------------------------------------------------------
*/
/* ----------------
- * TupIsNull
+ * TupIsNull
*
- * This is used mainly to detect when there are no more
- * tuples to process.
+ * This is used mainly to detect when there are no more
+ * tuples to process.
* ----------------
*/
-bool /* return: true if tuple in slot is NULL */
-TupIsNull(TupleTableSlot* slot) /* slot to check */
+bool /* return: true if tuple in slot is NULL */
+TupIsNull(TupleTableSlot * slot) /* slot to check */
{
- HeapTuple tuple; /* contents of slot (returned) */
-
- /* ----------------
- * if the slot itself is null then we return true
- * ----------------
- */
- if (slot == NULL)
- return true;
-
- /* ----------------
- * get information from the slot and return true or
- * false depending on the contents of the slot.
- * ----------------
- */
- tuple = slot->val;
-
- return
- (tuple == NULL ? true : false);
+ HeapTuple tuple; /* contents of slot (returned) */
+
+ /* ----------------
+ * if the slot itself is null then we return true
+ * ----------------
+ */
+ if (slot == NULL)
+ return true;
+
+ /* ----------------
+ * get information from the slot and return true or
+ * false depending on the contents of the slot.
+ * ----------------
+ */
+ tuple = slot->val;
+
+ return
+ (tuple == NULL ? true : false);
}
/* --------------------------------
- * ExecSlotDescriptorIsNew
+ * ExecSlotDescriptorIsNew
*
- * This function is used to check if the tuple descriptor
- * associated with this slot has just changed. ie: we are
- * now storing a new type of tuple in this slot
+ * This function is used to check if the tuple descriptor
+ * associated with this slot has just changed. ie: we are
+ * now storing a new type of tuple in this slot
* --------------------------------
*/
#ifdef NOT_USED
-bool /* return: descriptor "is new" */
-ExecSlotDescriptorIsNew(TupleTableSlot *slot) /* slot to inspect */
+bool /* return: descriptor "is new" */
+ExecSlotDescriptorIsNew(TupleTableSlot * slot) /* slot to inspect */
{
-/* bool isNew = SlotTupleDescriptorIsNew((TupleTableSlot*) slot);
- return isNew; */
- return slot->ttc_descIsNew;
+/* bool isNew = SlotTupleDescriptorIsNew((TupleTableSlot*) slot);
+ return isNew; */
+ return slot->ttc_descIsNew;
}
+
#endif
/* ----------------------------------------------------------------
- * convenience initialization routines
+ * convenience initialization routines
* ----------------------------------------------------------------
*/
/* --------------------------------
- * ExecInit{Result,Scan,Raw,Marked,Outer,Hash}TupleSlot
+ * ExecInit{Result,Scan,Raw,Marked,Outer,Hash}TupleSlot
*
- * These are convenience routines to initialize the specfied slot
- * in nodes inheriting the appropriate state.
+ * These are convenience routines to initialize the specfied slot
+ * in nodes inheriting the appropriate state.
* --------------------------------
*/
#define INIT_SLOT_DEFS \
- TupleTable tupleTable; \
- TupleTableSlot* slot
-
+ TupleTable tupleTable; \
+ TupleTableSlot* slot
+
#define INIT_SLOT_ALLOC \
- tupleTable = (TupleTable) estate->es_tupleTable; \
- slot = ExecAllocTableSlot(tupleTable); \
- slot->val = (HeapTuple)NULL; \
- slot->ttc_shouldFree = true; \
- slot->ttc_tupleDescriptor = (TupleDesc)NULL; \
- slot->ttc_whichplan = -1;\
- slot->ttc_descIsNew = true;
+ tupleTable = (TupleTable) estate->es_tupleTable; \
+ slot = ExecAllocTableSlot(tupleTable); \
+ slot->val = (HeapTuple)NULL; \
+ slot->ttc_shouldFree = true; \
+ slot->ttc_tupleDescriptor = (TupleDesc)NULL; \
+ slot->ttc_whichplan = -1;\
+ slot->ttc_descIsNew = true;
/* ----------------
- * ExecInitResultTupleSlot
+ * ExecInitResultTupleSlot
* ----------------
*/
void
-ExecInitResultTupleSlot(EState *estate, CommonState *commonstate)
+ExecInitResultTupleSlot(EState * estate, CommonState * commonstate)
{
- INIT_SLOT_DEFS;
- INIT_SLOT_ALLOC;
- commonstate->cs_ResultTupleSlot = (TupleTableSlot *) slot;
+ INIT_SLOT_DEFS;
+ INIT_SLOT_ALLOC;
+ commonstate->cs_ResultTupleSlot = (TupleTableSlot *) slot;
}
/* ----------------
- * ExecInitScanTupleSlot
+ * ExecInitScanTupleSlot
* ----------------
*/
void
-ExecInitScanTupleSlot(EState *estate, CommonScanState *commonscanstate)
+ExecInitScanTupleSlot(EState * estate, CommonScanState * commonscanstate)
{
- INIT_SLOT_DEFS;
- INIT_SLOT_ALLOC;
- commonscanstate->css_ScanTupleSlot = (TupleTableSlot *)slot;
+ INIT_SLOT_DEFS;
+ INIT_SLOT_ALLOC;
+ commonscanstate->css_ScanTupleSlot = (TupleTableSlot *) slot;
}
/* ----------------
- * ExecInitMarkedTupleSlot
+ * ExecInitMarkedTupleSlot
* ----------------
*/
void
-ExecInitMarkedTupleSlot(EState *estate, MergeJoinState *mergestate)
+ExecInitMarkedTupleSlot(EState * estate, MergeJoinState * mergestate)
{
- INIT_SLOT_DEFS;
- INIT_SLOT_ALLOC;
- mergestate->mj_MarkedTupleSlot = (TupleTableSlot *) slot;
+ INIT_SLOT_DEFS;
+ INIT_SLOT_ALLOC;
+ mergestate->mj_MarkedTupleSlot = (TupleTableSlot *) slot;
}
/* ----------------
- * ExecInitOuterTupleSlot
+ * ExecInitOuterTupleSlot
* ----------------
*/
void
-ExecInitOuterTupleSlot(EState *estate, HashJoinState *hashstate)
+ExecInitOuterTupleSlot(EState * estate, HashJoinState * hashstate)
{
- INIT_SLOT_DEFS;
- INIT_SLOT_ALLOC;
- hashstate->hj_OuterTupleSlot = slot;
+ INIT_SLOT_DEFS;
+ INIT_SLOT_ALLOC;
+ hashstate->hj_OuterTupleSlot = slot;
}
/* ----------------
- * ExecInitHashTupleSlot
+ * ExecInitHashTupleSlot
* ----------------
*/
#ifdef NOT_USED
void
-ExecInitHashTupleSlot(EState *estate, HashJoinState *hashstate)
+ExecInitHashTupleSlot(EState * estate, HashJoinState * hashstate)
{
- INIT_SLOT_DEFS;
- INIT_SLOT_ALLOC;
- hashstate->hj_HashTupleSlot = slot;
+ INIT_SLOT_DEFS;
+ INIT_SLOT_ALLOC;
+ hashstate->hj_HashTupleSlot = slot;
}
+
#endif
static TupleTableSlot *
-NodeGetResultTupleSlot(Plan *node)
+NodeGetResultTupleSlot(Plan * node)
{
- TupleTableSlot *slot;
-
- switch(nodeTag(node)) {
-
- case T_Result:
- {
- ResultState *resstate = ((Result *)node)->resstate;
- slot = resstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_SeqScan:
- {
- CommonScanState *scanstate = ((SeqScan *)node)->scanstate;
- slot = scanstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_NestLoop:
- {
- NestLoopState *nlstate = ((NestLoop *)node)->nlstate;
- slot = nlstate->jstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Append:
- {
- Append *n = (Append *)node;
- AppendState *unionstate;
- List *unionplans;
- int whichplan;
- Plan *subplan;
-
- unionstate = n->unionstate;
- unionplans = n->unionplans;
- whichplan = unionstate->as_whichplan;
-
- subplan = (Plan*) nth(whichplan, unionplans);
- slot = NodeGetResultTupleSlot(subplan);
- break;
- }
-
- case T_IndexScan:
- {
- CommonScanState *scanstate = ((IndexScan *)node)->scan.scanstate;
- slot = scanstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Material:
- {
- MaterialState *matstate = ((Material *)node)->matstate;
- slot = matstate->csstate.css_ScanTupleSlot;
- }
- break;
-
- case T_Sort:
- {
- SortState *sortstate = ((Sort *)node)->sortstate;
- slot = sortstate->csstate.css_ScanTupleSlot;
- }
- break;
-
- case T_Agg:
- {
- AggState *aggstate = ((Agg *)node)->aggstate;
- slot = aggstate->csstate.cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Group:
- {
- GroupState *grpstate = ((Group *)node)->grpstate;
- slot = grpstate->csstate.cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Hash:
- {
- HashState *hashstate = ((Hash *)node)->hashstate;
- slot = hashstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Unique:
- {
- UniqueState *uniquestate = ((Unique *)node)->uniquestate;
- slot = uniquestate->cs_ResultTupleSlot;
- }
- break;
-
- case T_MergeJoin:
- {
- MergeJoinState *mergestate = ((MergeJoin *)node)->mergestate;
- slot = mergestate->jstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_HashJoin:
+ TupleTableSlot *slot;
+
+ switch (nodeTag(node))
{
- HashJoinState *hashjoinstate = ((HashJoin *)node)->hashjoinstate;
- slot = hashjoinstate->jstate.cs_ResultTupleSlot;
+
+ case T_Result:
+ {
+ ResultState *resstate = ((Result *) node)->resstate;
+
+ slot = resstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_SeqScan:
+ {
+ CommonScanState *scanstate = ((SeqScan *) node)->scanstate;
+
+ slot = scanstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_NestLoop:
+ {
+ NestLoopState *nlstate = ((NestLoop *) node)->nlstate;
+
+ slot = nlstate->jstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Append:
+ {
+ Append *n = (Append *) node;
+ AppendState *unionstate;
+ List *unionplans;
+ int whichplan;
+ Plan *subplan;
+
+ unionstate = n->unionstate;
+ unionplans = n->unionplans;
+ whichplan = unionstate->as_whichplan;
+
+ subplan = (Plan *) nth(whichplan, unionplans);
+ slot = NodeGetResultTupleSlot(subplan);
+ break;
+ }
+
+ case T_IndexScan:
+ {
+ CommonScanState *scanstate = ((IndexScan *) node)->scan.scanstate;
+
+ slot = scanstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Material:
+ {
+ MaterialState *matstate = ((Material *) node)->matstate;
+
+ slot = matstate->csstate.css_ScanTupleSlot;
+ }
+ break;
+
+ case T_Sort:
+ {
+ SortState *sortstate = ((Sort *) node)->sortstate;
+
+ slot = sortstate->csstate.css_ScanTupleSlot;
+ }
+ break;
+
+ case T_Agg:
+ {
+ AggState *aggstate = ((Agg *) node)->aggstate;
+
+ slot = aggstate->csstate.cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Group:
+ {
+ GroupState *grpstate = ((Group *) node)->grpstate;
+
+ slot = grpstate->csstate.cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Hash:
+ {
+ HashState *hashstate = ((Hash *) node)->hashstate;
+
+ slot = hashstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Unique:
+ {
+ UniqueState *uniquestate = ((Unique *) node)->uniquestate;
+
+ slot = uniquestate->cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_MergeJoin:
+ {
+ MergeJoinState *mergestate = ((MergeJoin *) node)->mergestate;
+
+ slot = mergestate->jstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_HashJoin:
+ {
+ HashJoinState *hashjoinstate = ((HashJoin *) node)->hashjoinstate;
+
+ slot = hashjoinstate->jstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Tee:
+ {
+ TeeState *teestate = ((Tee *) node)->teestate;
+
+ slot = teestate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ default:
+ /* ----------------
+ * should never get here
+ * ----------------
+ */
+ elog(WARN, "NodeGetResultTupleSlot: node not yet supported: %d ",
+ nodeTag(node));
+
+ return NULL;
}
- break;
-
- case T_Tee:
- {
- TeeState *teestate = ((Tee*)node)->teestate;
- slot = teestate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- default:
- /* ----------------
- * should never get here
- * ----------------
- */
- elog(WARN, "NodeGetResultTupleSlot: node not yet supported: %d ",
- nodeTag(node));
-
- return NULL;
- }
- return slot;
+ return slot;
}
/* ----------------------------------------------------------------
- * ExecGetTupType
+ * ExecGetTupType
*
- * this gives you the tuple descriptor for tuples returned
- * by this node. I really wish I could ditch this routine,
- * but since not all nodes store their type info in the same
- * place, we have to do something special for each node type.
+ * this gives you the tuple descriptor for tuples returned
+ * by this node. I really wish I could ditch this routine,
+ * but since not all nodes store their type info in the same
+ * place, we have to do something special for each node type.
*
- * Soon, the system will have to adapt to deal with changing
- * tuple descriptors as we deal with dynamic tuple types
- * being returned from procedure nodes. Perhaps then this
- * routine can be retired. -cim 6/3/91
+ * Soon, the system will have to adapt to deal with changing
+ * tuple descriptors as we deal with dynamic tuple types
+ * being returned from procedure nodes. Perhaps then this
+ * routine can be retired. -cim 6/3/91
*
* old comments
- * This routine just gets the type information out of the
- * node's state. If you already have a node's state, you
- * can get this information directly, but this is a useful
- * routine if you want to get the type information from
- * the node's inner or outer subplan easily without having
- * to inspect the subplan.. -cim 10/16/89
+ * This routine just gets the type information out of the
+ * node's state. If you already have a node's state, you
+ * can get this information directly, but this is a useful
+ * routine if you want to get the type information from
+ * the node's inner or outer subplan easily without having
+ * to inspect the subplan.. -cim 10/16/89
*
- * Assume that for existential nodes, we get the targetlist out
- * of the right node's targetlist
+ * Assume that for existential nodes, we get the targetlist out
+ * of the right node's targetlist
* ----------------------------------------------------------------
*/
TupleDesc
-ExecGetTupType(Plan *node)
+ExecGetTupType(Plan * node)
{
- TupleTableSlot *slot;
- TupleDesc tupType;
-
- if (node == NULL)
- return NULL;
-
- slot = NodeGetResultTupleSlot(node);
- tupType = slot->ttc_tupleDescriptor;
- return tupType;
+ TupleTableSlot *slot;
+ TupleDesc tupType;
+
+ if (node == NULL)
+ return NULL;
+
+ slot = NodeGetResultTupleSlot(node);
+ tupType = slot->ttc_tupleDescriptor;
+ return tupType;
}
/*
TupleDesc
-ExecCopyTupType(TupleDesc td, int natts)
+ExecCopyTupType(TupleDesc td, int natts)
{
- TupleDesc newTd;
- int i;
-
- newTd = CreateTemplateTupleDesc(natts);
- i = 0;
- while (i < natts)
- {
- newTd[i] =
- (AttributeTupleForm)palloc(sizeof(FormData_pg_attribute));
- memmove(newTd[i], td[i], sizeof(FormData_pg_attribute));
- i++;
- }
- return newTd;
+ TupleDesc newTd;
+ int i;
+
+ newTd = CreateTemplateTupleDesc(natts);
+ i = 0;
+ while (i < natts)
+ {
+ newTd[i] =
+ (AttributeTupleForm)palloc(sizeof(FormData_pg_attribute));
+ memmove(newTd[i], td[i], sizeof(FormData_pg_attribute));
+ i++;
+ }
+ return newTd;
}
*/
/* ----------------------------------------------------------------
- * ExecTypeFromTL
- *
- * Currently there are about 4 different places where we create
- * TupleDescriptors. They should all be merged, or perhaps
- * be rewritten to call BuildDesc().
- *
- * old comments
- * Forms attribute type info from the target list in the node.
- * It assumes all domains are individually specified in the target list.
- * It fails if the target list contains something like Emp.all
- * which represents all the attributes from EMP relation.
- *
- * Conditions:
- * The inner and outer subtrees should be initialized because it
- * might be necessary to know the type infos of the subtrees.
+ * ExecTypeFromTL
+ *
+ * Currently there are about 4 different places where we create
+ * TupleDescriptors. They should all be merged, or perhaps
+ * be rewritten to call BuildDesc().
+ *
+ * old comments
+ * Forms attribute type info from the target list in the node.
+ * It assumes all domains are individually specified in the target list.
+ * It fails if the target list contains something like Emp.all
+ * which represents all the attributes from EMP relation.
+ *
+ * Conditions:
+ * The inner and outer subtrees should be initialized because it
+ * might be necessary to know the type infos of the subtrees.
* ----------------------------------------------------------------
*/
TupleDesc
-ExecTypeFromTL(List *targetList)
+ExecTypeFromTL(List * targetList)
{
- List *tlcdr;
- TupleDesc typeInfo;
- Resdom *resdom;
- Oid restype;
- int len;
-
- /* ----------------
- * examine targetlist - if empty then return NULL
- * ----------------
- */
- len = ExecTargetListLength(targetList);
-
- if (len == 0)
- return NULL;
-
- /* ----------------
- * allocate a new typeInfo
- * ----------------
- */
- typeInfo = CreateTemplateTupleDesc(len);
-
- /* ----------------
- * notes: get resdom from (resdom expr)
- * get_typbyval comes from src/lib/l-lisp/lsyscache.c
- * ----------------
- */
- tlcdr = targetList;
- while (tlcdr != NIL) {
- TargetEntry *tle = lfirst(tlcdr);
- if (tle->resdom != NULL) {
- resdom = tle->resdom;
- restype = resdom->restype;
-
- TupleDescInitEntry(typeInfo,
- resdom->resno,
- resdom->resname,
- /* fix for SELECT NULL ... */
- get_id_typname(restype?restype:UNKNOWNOID),
- 0,
- false);
+ List *tlcdr;
+ TupleDesc typeInfo;
+ Resdom *resdom;
+ Oid restype;
+ int len;
+
+ /* ----------------
+ * examine targetlist - if empty then return NULL
+ * ----------------
+ */
+ len = ExecTargetListLength(targetList);
+
+ if (len == 0)
+ return NULL;
+
+ /* ----------------
+ * allocate a new typeInfo
+ * ----------------
+ */
+ typeInfo = CreateTemplateTupleDesc(len);
+
+ /* ----------------
+ * notes: get resdom from (resdom expr)
+ * get_typbyval comes from src/lib/l-lisp/lsyscache.c
+ * ----------------
+ */
+ tlcdr = targetList;
+ while (tlcdr != NIL)
+ {
+ TargetEntry *tle = lfirst(tlcdr);
+
+ if (tle->resdom != NULL)
+ {
+ resdom = tle->resdom;
+ restype = resdom->restype;
+
+ TupleDescInitEntry(typeInfo,
+ resdom->resno,
+ resdom->resname,
+ /* fix for SELECT NULL ... */
+ get_id_typname(restype ? restype : UNKNOWNOID),
+ 0,
+ false);
/*
- ExecSetTypeInfo(resdom->resno - 1,
- typeInfo,
- (Oid) restype,
- resdom->resno,
- resdom->reslen,
- resdom->resname->data,
- get_typbyval(restype),
- get_typalign(restype));
+ ExecSetTypeInfo(resdom->resno - 1,
+ typeInfo,
+ (Oid) restype,
+ resdom->resno,
+ resdom->reslen,
+ resdom->resname->data,
+ get_typbyval(restype),
+ get_typalign(restype));
*/
- }
- else {
- Resdom *fjRes;
- List *fjTlistP;
- List *fjList = lfirst(tlcdr);
+ }
+ else
+ {
+ Resdom *fjRes;
+ List *fjTlistP;
+ List *fjList = lfirst(tlcdr);
+
#ifdef SETS_FIXED
- TargetEntry *tle;
- Fjoin *fjNode = ((TargetEntry *)lfirst(fjList))->fjoin;
+ TargetEntry *tle;
+ Fjoin *fjNode = ((TargetEntry *) lfirst(fjList))->fjoin;
- tle = fjNode->fj_innerNode; /* ??? */
+ tle = fjNode->fj_innerNode; /* ??? */
#endif
- fjRes = tle->resdom;
- restype = fjRes->restype;
-
- TupleDescInitEntry(typeInfo,
- fjRes->resno,
- fjRes->resname,
- get_id_typname(restype),
- 0,
- false);
+ fjRes = tle->resdom;
+ restype = fjRes->restype;
+
+ TupleDescInitEntry(typeInfo,
+ fjRes->resno,
+ fjRes->resname,
+ get_id_typname(restype),
+ 0,
+ false);
/*
- ExecSetTypeInfo(fjRes->resno - 1,
- typeInfo,
- (Oid) restype,
- fjRes->resno,
- fjRes->reslen,
- (char *) fjRes->resname,
- get_typbyval(restype),
- get_typalign(restype));
+ ExecSetTypeInfo(fjRes->resno - 1,
+ typeInfo,
+ (Oid) restype,
+ fjRes->resno,
+ fjRes->reslen,
+ (char *) fjRes->resname,
+ get_typbyval(restype),
+ get_typalign(restype));
*/
-
- foreach(fjTlistP, lnext(fjList)) {
- TargetEntry *fjTle = lfirst(fjTlistP);
-
- fjRes = fjTle->resdom;
-
- TupleDescInitEntry(typeInfo,
- fjRes->resno,
- fjRes->resname,
- get_id_typname(restype),
- 0,
- false);
-
+
+ foreach(fjTlistP, lnext(fjList))
+ {
+ TargetEntry *fjTle = lfirst(fjTlistP);
+
+ fjRes = fjTle->resdom;
+
+ TupleDescInitEntry(typeInfo,
+ fjRes->resno,
+ fjRes->resname,
+ get_id_typname(restype),
+ 0,
+ false);
+
/*
- ExecSetTypeInfo(fjRes->resno - 1,
- typeInfo,
- (Oid) fjRes->restype,
- fjRes->resno,
- fjRes->reslen,
- (char *) fjRes->resname,
- get_typbyval(fjRes->restype),
- get_typalign(fjRes->restype));
+ ExecSetTypeInfo(fjRes->resno - 1,
+ typeInfo,
+ (Oid) fjRes->restype,
+ fjRes->resno,
+ fjRes->reslen,
+ (char *) fjRes->resname,
+ get_typbyval(fjRes->restype),
+ get_typalign(fjRes->restype));
*/
- }
- }
-
- tlcdr = lnext(tlcdr);
- }
-
- return typeInfo;
-}
+ }
+ }
+ tlcdr = lnext(tlcdr);
+ }
+ return typeInfo;
+}
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index ac2d3516036..3795c2d1018 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -1,43 +1,43 @@
/*-------------------------------------------------------------------------
*
* execUtils.c--
- * miscellanious executor utility routines
+ * miscellanious executor utility routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.14 1997/08/22 03:12:19 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.15 1997/09/07 04:41:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * ExecAssignNodeBaseInfo \
- * ExecAssignDebugHooks > preforms misc work done in all the
- * ExecAssignExprContext / init node routines.
+ * ExecAssignNodeBaseInfo \
+ * ExecAssignDebugHooks > preforms misc work done in all the
+ * ExecAssignExprContext / init node routines.
*
- * ExecGetTypeInfo | old execCStructs interface
- * ExecMakeTypeInfo | code from the version 1
- * ExecOrderTypeInfo | lisp system. These should
- * ExecSetTypeInfo | go away or be updated soon.
- * ExecFreeTypeInfo | -cim 11/1/89
- * ExecTupleAttributes /
+ * ExecGetTypeInfo | old execCStructs interface
+ * ExecMakeTypeInfo | code from the version 1
+ * ExecOrderTypeInfo | lisp system. These should
+ * ExecSetTypeInfo | go away or be updated soon.
+ * ExecFreeTypeInfo | -cim 11/1/89
+ * ExecTupleAttributes /
*
- * QueryDescGetTypeInfo - moved here from main.c
- * am not sure what uses it -cim 10/12/89
+ * QueryDescGetTypeInfo - moved here from main.c
+ * am not sure what uses it -cim 10/12/89
*
- * ExecGetIndexKeyInfo \
- * ExecOpenIndices | referenced by InitPlan, EndPlan,
- * ExecCloseIndices | ExecAppend, ExecReplace
- * ExecFormIndexTuple |
- * ExecInsertIndexTuple /
+ * ExecGetIndexKeyInfo \
+ * ExecOpenIndices | referenced by InitPlan, EndPlan,
+ * ExecCloseIndices | ExecAppend, ExecReplace
+ * ExecFormIndexTuple |
+ * ExecInsertIndexTuple /
+ *
+ * NOTES
+ * This file has traditionally been the place to stick misc.
+ * executor support stuff that doesn't really go anyplace else.
*
- * NOTES
- * This file has traditionally been the place to stick misc.
- * executor support stuff that doesn't really go anyplace else.
- *
*/
#include "postgres.h"
@@ -58,1149 +58,1195 @@
#include "catalog/pg_type.h"
#include "parser/parsetree.h"
-static void ExecGetIndexKeyInfo(IndexTupleForm indexTuple, int *numAttsOutP,
- AttrNumber **attsOutP, FuncIndexInfoPtr fInfoP);
+static void
+ExecGetIndexKeyInfo(IndexTupleForm indexTuple, int *numAttsOutP,
+ AttrNumber ** attsOutP, FuncIndexInfoPtr fInfoP);
/* ----------------------------------------------------------------
- * global counters for number of tuples processed, retrieved,
- * appended, replaced, deleted.
+ * global counters for number of tuples processed, retrieved,
+ * appended, replaced, deleted.
* ----------------------------------------------------------------
*/
-int NTupleProcessed;
-int NTupleRetrieved;
-int NTupleReplaced;
-int NTupleAppended;
-int NTupleDeleted;
-int NIndexTupleInserted;
-extern int NIndexTupleProcessed; /* have to be defined in the access
- method level so that the cinterface.a
- will link ok. */
+int NTupleProcessed;
+int NTupleRetrieved;
+int NTupleReplaced;
+int NTupleAppended;
+int NTupleDeleted;
+int NIndexTupleInserted;
+extern int NIndexTupleProcessed; /* have to be defined in the
+ * access method level so that the
+ * cinterface.a will link ok. */
/* ----------------------------------------------------------------
- * statistic functions
+ * statistic functions
* ----------------------------------------------------------------
*/
/* ----------------------------------------------------------------
- * ResetTupleCount
+ * ResetTupleCount
* ----------------------------------------------------------------
*/
#ifdef NOT_USED
void
ResetTupleCount(void)
{
- NTupleProcessed = 0;
- NTupleRetrieved = 0;
- NTupleAppended = 0;
- NTupleDeleted = 0;
- NTupleReplaced = 0;
- NIndexTupleProcessed = 0;
+ NTupleProcessed = 0;
+ NTupleRetrieved = 0;
+ NTupleAppended = 0;
+ NTupleDeleted = 0;
+ NTupleReplaced = 0;
+ NIndexTupleProcessed = 0;
}
+
#endif
/* ----------------------------------------------------------------
- * PrintTupleCount
+ * PrintTupleCount
* ----------------------------------------------------------------
*/
#ifdef NOT_USED
void
-DisplayTupleCount(FILE *statfp)
+DisplayTupleCount(FILE * statfp)
{
- if (NTupleProcessed > 0)
- fprintf(statfp, "!\t%d tuple%s processed, ", NTupleProcessed,
- (NTupleProcessed == 1) ? "" : "s");
- else {
- fprintf(statfp, "!\tno tuples processed.\n");
- return;
- }
- if (NIndexTupleProcessed > 0)
- fprintf(statfp, "%d indextuple%s processed, ", NIndexTupleProcessed,
- (NIndexTupleProcessed == 1) ? "" : "s");
- if (NIndexTupleInserted > 0)
- fprintf(statfp, "%d indextuple%s inserted, ", NIndexTupleInserted,
- (NIndexTupleInserted == 1) ? "" : "s");
- if (NTupleRetrieved > 0)
- fprintf(statfp, "%d tuple%s retrieved. ", NTupleRetrieved,
- (NTupleRetrieved == 1) ? "" : "s");
- if (NTupleAppended > 0)
- fprintf(statfp, "%d tuple%s appended. ", NTupleAppended,
- (NTupleAppended == 1) ? "" : "s");
- if (NTupleDeleted > 0)
- fprintf(statfp, "%d tuple%s deleted. ", NTupleDeleted,
- (NTupleDeleted == 1) ? "" : "s");
- if (NTupleReplaced > 0)
- fprintf(statfp, "%d tuple%s replaced. ", NTupleReplaced,
- (NTupleReplaced == 1) ? "" : "s");
- fprintf(statfp, "\n");
+ if (NTupleProcessed > 0)
+ fprintf(statfp, "!\t%d tuple%s processed, ", NTupleProcessed,
+ (NTupleProcessed == 1) ? "" : "s");
+ else
+ {
+ fprintf(statfp, "!\tno tuples processed.\n");
+ return;
+ }
+ if (NIndexTupleProcessed > 0)
+ fprintf(statfp, "%d indextuple%s processed, ", NIndexTupleProcessed,
+ (NIndexTupleProcessed == 1) ? "" : "s");
+ if (NIndexTupleInserted > 0)
+ fprintf(statfp, "%d indextuple%s inserted, ", NIndexTupleInserted,
+ (NIndexTupleInserted == 1) ? "" : "s");
+ if (NTupleRetrieved > 0)
+ fprintf(statfp, "%d tuple%s retrieved. ", NTupleRetrieved,
+ (NTupleRetrieved == 1) ? "" : "s");
+ if (NTupleAppended > 0)
+ fprintf(statfp, "%d tuple%s appended. ", NTupleAppended,
+ (NTupleAppended == 1) ? "" : "s");
+ if (NTupleDeleted > 0)
+ fprintf(statfp, "%d tuple%s deleted. ", NTupleDeleted,
+ (NTupleDeleted == 1) ? "" : "s");
+ if (NTupleReplaced > 0)
+ fprintf(statfp, "%d tuple%s replaced. ", NTupleReplaced,
+ (NTupleReplaced == 1) ? "" : "s");
+ fprintf(statfp, "\n");
}
+
#endif
/* ----------------------------------------------------------------
- * miscellanious init node support functions
+ * miscellanious init node support functions
*
- * ExecAssignNodeBaseInfo - assigns the baseid field of the node
- * ExecAssignDebugHooks - assigns the node's debugging hooks
- * ExecAssignExprContext - assigns the node's expression context
+ * ExecAssignNodeBaseInfo - assigns the baseid field of the node
+ * ExecAssignDebugHooks - assigns the node's debugging hooks
+ * ExecAssignExprContext - assigns the node's expression context
* ----------------------------------------------------------------
*/
/* ----------------
- * ExecAssignNodeBaseInfo
+ * ExecAssignNodeBaseInfo
*
- * as it says, this assigns the baseid field of the node and
- * increments the counter in the estate. In addition, it initializes
- * the base_parent field of the basenode.
+ * as it says, this assigns the baseid field of the node and
+ * increments the counter in the estate. In addition, it initializes
+ * the base_parent field of the basenode.
* ----------------
*/
void
-ExecAssignNodeBaseInfo(EState *estate, CommonState *cstate, Plan *parent)
+ExecAssignNodeBaseInfo(EState * estate, CommonState * cstate, Plan * parent)
{
- int baseId;
-
- baseId = estate->es_BaseId;
- cstate->cs_base_id = baseId;
- estate->es_BaseId = baseId + 1;
+ int baseId;
+
+ baseId = estate->es_BaseId;
+ cstate->cs_base_id = baseId;
+ estate->es_BaseId = baseId + 1;
}
/* ----------------
- * ExecAssignExprContext
+ * ExecAssignExprContext
*
- * This initializes the ExprContext field. It is only necessary
- * to do this for nodes which use ExecQual or ExecTargetList
- * because those routines depend on econtext. Other nodes which
- * dont have to evaluate expressions don't need to do this.
+ * This initializes the ExprContext field. It is only necessary
+ * to do this for nodes which use ExecQual or ExecTargetList
+ * because those routines depend on econtext. Other nodes which
+ * dont have to evaluate expressions don't need to do this.
* ----------------
*/
void
-ExecAssignExprContext(EState *estate, CommonState *commonstate)
+ExecAssignExprContext(EState * estate, CommonState * commonstate)
{
- ExprContext *econtext;
- ParamListInfo paraminfo;
- List *rangeTable;
-
- paraminfo = estate->es_param_list_info;
- rangeTable = estate->es_range_table;
-
- econtext = makeNode(ExprContext);
- econtext->ecxt_scantuple = NULL; /* scan tuple slot */
- econtext->ecxt_innertuple = NULL; /* inner tuple slot */
- econtext->ecxt_outertuple = NULL; /* outer tuple slot */
- econtext->ecxt_relation = NULL; /* relation */
- econtext->ecxt_relid = 0; /* relid */
- econtext->ecxt_param_list_info = paraminfo; /* param list info */
- econtext->ecxt_range_table = rangeTable; /* range table */
-
- commonstate->cs_ExprContext = econtext;
+ ExprContext *econtext;
+ ParamListInfo paraminfo;
+ List *rangeTable;
+
+ paraminfo = estate->es_param_list_info;
+ rangeTable = estate->es_range_table;
+
+ econtext = makeNode(ExprContext);
+ econtext->ecxt_scantuple = NULL; /* scan tuple slot */
+ econtext->ecxt_innertuple = NULL; /* inner tuple slot */
+ econtext->ecxt_outertuple = NULL; /* outer tuple slot */
+ econtext->ecxt_relation = NULL; /* relation */
+ econtext->ecxt_relid = 0; /* relid */
+ econtext->ecxt_param_list_info = paraminfo; /* param list info */
+ econtext->ecxt_range_table = rangeTable; /* range table */
+
+ commonstate->cs_ExprContext = econtext;
}
/* ----------------------------------------------------------------
- * Result slot tuple type and ProjectionInfo support
+ * Result slot tuple type and ProjectionInfo support
* ----------------------------------------------------------------
*/
/* ----------------
- * ExecAssignResultType
+ * ExecAssignResultType
* ----------------
*/
void
-ExecAssignResultType(CommonState *commonstate,
- TupleDesc tupDesc)
+ExecAssignResultType(CommonState * commonstate,
+ TupleDesc tupDesc)
{
- TupleTableSlot *slot;
-
- slot = commonstate->cs_ResultTupleSlot;
- slot->ttc_tupleDescriptor = tupDesc;
+ TupleTableSlot *slot;
+
+ slot = commonstate->cs_ResultTupleSlot;
+ slot->ttc_tupleDescriptor = tupDesc;
}
/* ----------------
- * ExecAssignResultTypeFromOuterPlan
+ * ExecAssignResultTypeFromOuterPlan
* ----------------
*/
void
-ExecAssignResultTypeFromOuterPlan(Plan *node, CommonState *commonstate)
+ExecAssignResultTypeFromOuterPlan(Plan * node, CommonState * commonstate)
{
- Plan *outerPlan;
- TupleDesc tupDesc;
-
- outerPlan = outerPlan(node);
- tupDesc = ExecGetTupType(outerPlan);
-
- ExecAssignResultType(commonstate, tupDesc);
+ Plan *outerPlan;
+ TupleDesc tupDesc;
+
+ outerPlan = outerPlan(node);
+ tupDesc = ExecGetTupType(outerPlan);
+
+ ExecAssignResultType(commonstate, tupDesc);
}
/* ----------------
- * ExecAssignResultTypeFromTL
+ * ExecAssignResultTypeFromTL
* ----------------
*/
void
-ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate)
+ExecAssignResultTypeFromTL(Plan * node, CommonState * commonstate)
{
- List *targetList;
- int i;
- int len;
- List *tl;
- TargetEntry *tle;
- List *fjtl;
- TupleDesc origTupDesc;
-
- targetList = node->targetlist;
- origTupDesc = ExecTypeFromTL(targetList);
- len = ExecTargetListLength(targetList);
-
- fjtl = NIL;
- tl = targetList;
- i = 0;
- while (tl != NIL || fjtl != NIL) {
- if (fjtl != NIL) {
- tle = lfirst(fjtl);
- fjtl = lnext(fjtl);
- }
- else {
- tle = lfirst(tl);
- tl = lnext(tl);
- }
+ List *targetList;
+ int i;
+ int len;
+ List *tl;
+ TargetEntry *tle;
+ List *fjtl;
+ TupleDesc origTupDesc;
+
+ targetList = node->targetlist;
+ origTupDesc = ExecTypeFromTL(targetList);
+ len = ExecTargetListLength(targetList);
+
+ fjtl = NIL;
+ tl = targetList;
+ i = 0;
+ while (tl != NIL || fjtl != NIL)
+ {
+ if (fjtl != NIL)
+ {
+ tle = lfirst(fjtl);
+ fjtl = lnext(fjtl);
+ }
+ else
+ {
+ tle = lfirst(tl);
+ tl = lnext(tl);
+ }
#ifdef SETS_FIXED
- if (!tl_is_resdom(tle)) {
- Fjoin *fj = (Fjoin *)lfirst(tle);
- /* it is a FJoin */
- fjtl = lnext(tle);
- tle = fj->fj_innerNode;
- }
+ if (!tl_is_resdom(tle))
+ {
+ Fjoin *fj = (Fjoin *) lfirst(tle);
+
+ /* it is a FJoin */
+ fjtl = lnext(tle);
+ tle = fj->fj_innerNode;
+ }
#endif
- i++;
- }
- if (len > 0) {
- ExecAssignResultType(commonstate,
- origTupDesc);
- }
- else
- ExecAssignResultType(commonstate,
- (TupleDesc)NULL);
+ i++;
+ }
+ if (len > 0)
+ {
+ ExecAssignResultType(commonstate,
+ origTupDesc);
+ }
+ else
+ ExecAssignResultType(commonstate,
+ (TupleDesc) NULL);
}
/* ----------------
- * ExecGetResultType
+ * ExecGetResultType
* ----------------
*/
TupleDesc
-ExecGetResultType(CommonState *commonstate)
+ExecGetResultType(CommonState * commonstate)
{
- TupleTableSlot *slot = commonstate->cs_ResultTupleSlot;
-
- return slot->ttc_tupleDescriptor;
+ TupleTableSlot *slot = commonstate->cs_ResultTupleSlot;
+
+ return slot->ttc_tupleDescriptor;
}
/* ----------------
- * ExecFreeResultType
+ * ExecFreeResultType
* ----------------
*/
#ifdef NOT_USED
void
-ExecFreeResultType(CommonState *commonstate)
+ExecFreeResultType(CommonState * commonstate)
{
- TupleTableSlot *slot;
- TupleDesc tupType;
-
- slot = commonstate->cs_ResultTupleSlot;
- tupType = slot->ttc_tupleDescriptor;
-
-/* ExecFreeTypeInfo(tupType); */
- pfree(tupType);
+ TupleTableSlot *slot;
+ TupleDesc tupType;
+
+ slot = commonstate->cs_ResultTupleSlot;
+ tupType = slot->ttc_tupleDescriptor;
+
+/* ExecFreeTypeInfo(tupType); */
+ pfree(tupType);
}
+
#endif
/* ----------------
- * ExecAssignProjectionInfo
- forms the projection information from the node's targetlist
+ * ExecAssignProjectionInfo
+ forms the projection information from the node's targetlist
* ----------------
*/
void
-ExecAssignProjectionInfo(Plan *node, CommonState *commonstate)
+ExecAssignProjectionInfo(Plan * node, CommonState * commonstate)
{
- ProjectionInfo *projInfo;
- List *targetList;
- int len;
-
- targetList = node->targetlist;
- len = ExecTargetListLength(targetList);
-
- projInfo = makeNode(ProjectionInfo);
- projInfo->pi_targetlist = targetList;
- projInfo->pi_len = len;
- projInfo->pi_tupValue =
- (len <= 0) ? NULL : (Datum *) palloc(sizeof(Datum) * len);
- projInfo->pi_exprContext = commonstate->cs_ExprContext;
- projInfo->pi_slot = commonstate->cs_ResultTupleSlot;
-
- commonstate->cs_ProjInfo = projInfo;
+ ProjectionInfo *projInfo;
+ List *targetList;
+ int len;
+
+ targetList = node->targetlist;
+ len = ExecTargetListLength(targetList);
+
+ projInfo = makeNode(ProjectionInfo);
+ projInfo->pi_targetlist = targetList;
+ projInfo->pi_len = len;
+ projInfo->pi_tupValue =
+ (len <= 0) ? NULL : (Datum *) palloc(sizeof(Datum) * len);
+ projInfo->pi_exprContext = commonstate->cs_ExprContext;
+ projInfo->pi_slot = commonstate->cs_ResultTupleSlot;
+
+ commonstate->cs_ProjInfo = projInfo;
}
/* ----------------
- * ExecFreeProjectionInfo
+ * ExecFreeProjectionInfo
* ----------------
*/
void
-ExecFreeProjectionInfo(CommonState *commonstate)
+ExecFreeProjectionInfo(CommonState * commonstate)
{
- ProjectionInfo *projInfo;
-
- /* ----------------
- * get projection info. if NULL then this node has
- * none so we just return.
- * ----------------
- */
- projInfo = commonstate->cs_ProjInfo;
- if (projInfo == NULL)
- return;
-
- /* ----------------
- * clean up memory used.
- * ----------------
- */
- if (projInfo->pi_tupValue != NULL)
- pfree(projInfo->pi_tupValue);
-
- pfree(projInfo);
- commonstate->cs_ProjInfo = NULL;
+ ProjectionInfo *projInfo;
+
+ /* ----------------
+ * get projection info. if NULL then this node has
+ * none so we just return.
+ * ----------------
+ */
+ projInfo = commonstate->cs_ProjInfo;
+ if (projInfo == NULL)
+ return;
+
+ /* ----------------
+ * clean up memory used.
+ * ----------------
+ */
+ if (projInfo->pi_tupValue != NULL)
+ pfree(projInfo->pi_tupValue);
+
+ pfree(projInfo);
+ commonstate->cs_ProjInfo = NULL;
}
/* ----------------------------------------------------------------
- * the following scan type support functions are for
- * those nodes which are stubborn and return tuples in
- * their Scan tuple slot instead of their Result tuple
- * slot.. luck fur us, these nodes do not do projections
- * so we don't have to worry about getting the ProjectionInfo
- * right for them... -cim 6/3/91
+ * the following scan type support functions are for
+ * those nodes which are stubborn and return tuples in
+ * their Scan tuple slot instead of their Result tuple
+ * slot.. luck fur us, these nodes do not do projections
+ * so we don't have to worry about getting the ProjectionInfo
+ * right for them... -cim 6/3/91
* ----------------------------------------------------------------
*/
/* ----------------
- * ExecGetScanType
+ * ExecGetScanType
* ----------------
*/
TupleDesc
-ExecGetScanType(CommonScanState *csstate)
+ExecGetScanType(CommonScanState * csstate)
{
- TupleTableSlot *slot = csstate->css_ScanTupleSlot;
- return slot->ttc_tupleDescriptor;
+ TupleTableSlot *slot = csstate->css_ScanTupleSlot;
+
+ return slot->ttc_tupleDescriptor;
}
/* ----------------
- * ExecFreeScanType
+ * ExecFreeScanType
* ----------------
*/
#ifdef NOT_USED
void
-ExecFreeScanType(CommonScanState *csstate)
+ExecFreeScanType(CommonScanState * csstate)
{
- TupleTableSlot *slot;
- TupleDesc tupType;
-
- slot = csstate->css_ScanTupleSlot;
- tupType = slot->ttc_tupleDescriptor;
-
-/* ExecFreeTypeInfo(tupType); */
- pfree(tupType);
+ TupleTableSlot *slot;
+ TupleDesc tupType;
+
+ slot = csstate->css_ScanTupleSlot;
+ tupType = slot->ttc_tupleDescriptor;
+
+/* ExecFreeTypeInfo(tupType); */
+ pfree(tupType);
}
+
#endif
/* ----------------
- * ExecAssignScanType
+ * ExecAssignScanType
* ----------------
*/
void
-ExecAssignScanType(CommonScanState *csstate,
- TupleDesc tupDesc)
+ExecAssignScanType(CommonScanState * csstate,
+ TupleDesc tupDesc)
{
- TupleTableSlot *slot;
-
- slot = (TupleTableSlot *) csstate->css_ScanTupleSlot;
- slot->ttc_tupleDescriptor = tupDesc;
+ TupleTableSlot *slot;
+
+ slot = (TupleTableSlot *) csstate->css_ScanTupleSlot;
+ slot->ttc_tupleDescriptor = tupDesc;
}
/* ----------------
- * ExecAssignScanTypeFromOuterPlan
+ * ExecAssignScanTypeFromOuterPlan
* ----------------
*/
void
-ExecAssignScanTypeFromOuterPlan(Plan *node, CommonScanState *csstate)
+ExecAssignScanTypeFromOuterPlan(Plan * node, CommonScanState * csstate)
{
- Plan *outerPlan;
- TupleDesc tupDesc;
-
- outerPlan = outerPlan(node);
- tupDesc = ExecGetTupType(outerPlan);
+ Plan *outerPlan;
+ TupleDesc tupDesc;
+
+ outerPlan = outerPlan(node);
+ tupDesc = ExecGetTupType(outerPlan);
- ExecAssignScanType(csstate, tupDesc);
+ ExecAssignScanType(csstate, tupDesc);
}
/* ----------------------------------------------------------------
- * ExecTypeFromTL support routines.
+ * ExecTypeFromTL support routines.
*
- * these routines are used mainly from ExecTypeFromTL.
- * -cim 6/12/90
+ * these routines are used mainly from ExecTypeFromTL.
+ * -cim 6/12/90
*
* old comments
- * Routines dealing with the structure 'attribute' which conatains
- * the type information about attributes in a tuple:
+ * Routines dealing with the structure 'attribute' which conatains
+ * the type information about attributes in a tuple:
*
- * ExecMakeTypeInfo(noType) --
- * returns pointer to array of 'noType' structure 'attribute'.
- * ExecSetTypeInfo(index, typeInfo, attNum, attLen) --
- * sets the element indexed by 'index' in typeInfo with
- * the values: attNum, attLen.
- * ExecFreeTypeInfo(typeInfo) --
- * frees the structure 'typeInfo'.
+ * ExecMakeTypeInfo(noType) --
+ * returns pointer to array of 'noType' structure 'attribute'.
+ * ExecSetTypeInfo(index, typeInfo, attNum, attLen) --
+ * sets the element indexed by 'index' in typeInfo with
+ * the values: attNum, attLen.
+ * ExecFreeTypeInfo(typeInfo) --
+ * frees the structure 'typeInfo'.
* ----------------------------------------------------------------
*/
/* ----------------
- * ExecSetTypeInfo
+ * ExecSetTypeInfo
*
- * This initializes fields of a single attribute in a
- * tuple descriptor from the specified parameters.
+ * This initializes fields of a single attribute in a
+ * tuple descriptor from the specified parameters.
*
- * XXX this duplicates much of the functionality of TupleDescInitEntry.
- * the routines should be moved to the same place and be rewritten
- * to share common code.
+ * XXX this duplicates much of the functionality of TupleDescInitEntry.
+ * the routines should be moved to the same place and be rewritten
+ * to share common code.
* ----------------
*/
-#ifdef NOT_USED
+#ifdef NOT_USED
void
ExecSetTypeInfo(int index,
- TupleDesc typeInfo,
- Oid typeID,
- int attNum,
- int attLen,
- char *attName,
- bool attbyVal,
- char attalign)
+ TupleDesc typeInfo,
+ Oid typeID,
+ int attNum,
+ int attLen,
+ char *attName,
+ bool attbyVal,
+ char attalign)
{
- AttributeTupleForm att;
-
- /* ----------------
- * get attribute pointer and preform a sanity check..
- * ----------------
- */
- att = typeInfo[index];
- if (att == NULL)
- elog(WARN, "ExecSetTypeInfo: trying to assign through NULL");
-
- /* ----------------
- * assign values to the tuple descriptor, being careful not
- * to copy a null attName..
- *
- * XXX it is unknown exactly what information is needed to
- * initialize the attribute struct correctly so for now
- * we use 0. this should be fixed -- otherwise we run the
- * risk of using garbage data. -cim 5/5/91
- * ----------------
- */
- att->attrelid = 0; /* dummy value */
-
- if (attName != (char *) NULL)
- strNcpy(att->attname.data, attName, NAMEDATALEN-1);
- else
- memset(att->attname.data,0,NAMEDATALEN);
-
- att->atttypid = typeID;
- att->attdefrel = 0; /* dummy value */
- att->attdisbursion = 0; /* dummy value */
- att->atttyparg = 0; /* dummy value */
- att->attlen = attLen;
- att->attnum = attNum;
- att->attbound = 0; /* dummy value */
- att->attbyval = attbyVal;
- att->attcanindex = 0; /* dummy value */
- att->attproc = 0; /* dummy value */
- att->attnelems = 0; /* dummy value */
- att->attcacheoff = -1;
- att->attisset = false;
- att->attalign = attalign;
+ AttributeTupleForm att;
+
+ /* ----------------
+ * get attribute pointer and preform a sanity check..
+ * ----------------
+ */
+ att = typeInfo[index];
+ if (att == NULL)
+ elog(WARN, "ExecSetTypeInfo: trying to assign through NULL");
+
+ /* ----------------
+ * assign values to the tuple descriptor, being careful not
+ * to copy a null attName..
+ *
+ * XXX it is unknown exactly what information is needed to
+ * initialize the attribute struct correctly so for now
+ * we use 0. this should be fixed -- otherwise we run the
+ * risk of using garbage data. -cim 5/5/91
+ * ----------------
+ */
+ att->attrelid = 0; /* dummy value */
+
+ if (attName != (char *) NULL)
+ strNcpy(att->attname.data, attName, NAMEDATALEN - 1);
+ else
+ memset(att->attname.data, 0, NAMEDATALEN);
+
+ att->atttypid = typeID;
+ att->attdefrel = 0; /* dummy value */
+ att->attdisbursion = 0; /* dummy value */
+ att->atttyparg = 0; /* dummy value */
+ att->attlen = attLen;
+ att->attnum = attNum;
+ att->attbound = 0; /* dummy value */
+ att->attbyval = attbyVal;
+ att->attcanindex = 0; /* dummy value */
+ att->attproc = 0; /* dummy value */
+ att->attnelems = 0; /* dummy value */
+ att->attcacheoff = -1;
+ att->attisset = false;
+ att->attalign = attalign;
}
/* ----------------
- * ExecFreeTypeInfo frees the array of attrbutes
- * created by ExecMakeTypeInfo and returned by ExecTypeFromTL...
+ * ExecFreeTypeInfo frees the array of attrbutes
+ * created by ExecMakeTypeInfo and returned by ExecTypeFromTL...
* ----------------
*/
void
ExecFreeTypeInfo(TupleDesc typeInfo)
{
- /* ----------------
- * do nothing if asked to free a null pointer
- * ----------------
- */
- if (typeInfo == NULL)
- return;
-
- /* ----------------
- * the entire array of typeinfo pointers created by
- * ExecMakeTypeInfo was allocated with a single palloc()
- * so we can deallocate the whole array with a single pfree().
- * (we should not try and free all the elements in the array)
- * -cim 6/12/90
- * ----------------
- */
- pfree(typeInfo);
+ /* ----------------
+ * do nothing if asked to free a null pointer
+ * ----------------
+ */
+ if (typeInfo == NULL)
+ return;
+
+ /* ----------------
+ * the entire array of typeinfo pointers created by
+ * ExecMakeTypeInfo was allocated with a single palloc()
+ * so we can deallocate the whole array with a single pfree().
+ * (we should not try and free all the elements in the array)
+ * -cim 6/12/90
+ * ----------------
+ */
+ pfree(typeInfo);
}
/* ----------------------------------------------------------------
- * QueryDescGetTypeInfo
+ * QueryDescGetTypeInfo
*
- *| I don't know how this is used, all I know is that it
- *| appeared one day in main.c so I moved it here. -cim 11/1/89
+ *| I don't know how this is used, all I know is that it
+ *| appeared one day in main.c so I moved it here. -cim 11/1/89
* ----------------------------------------------------------------
*/
TupleDesc
-QueryDescGetTypeInfo(QueryDesc *queryDesc)
+QueryDescGetTypeInfo(QueryDesc * queryDesc)
{
- Plan *plan;
- TupleDesc tupleType;
- List *targetList;
- AttrInfo *attinfo = (AttrInfo *)palloc(sizeof(AttrInfo));
-
- plan = queryDesc->plantree;
- tupleType = (TupleDesc) ExecGetTupType(plan);
+ Plan *plan;
+ TupleDesc tupleType;
+ List *targetList;
+ AttrInfo *attinfo = (AttrInfo *) palloc(sizeof(AttrInfo));
+
+ plan = queryDesc->plantree;
+ tupleType = (TupleDesc) ExecGetTupType(plan);
/*
- targetList = plan->targetlist;
+ targetList = plan->targetlist;
- attinfo->numAttr = ExecTargetListLength(targetList);
- attinfo->attrs = tupleType;
+ attinfo->numAttr = ExecTargetListLength(targetList);
+ attinfo->attrs = tupleType;
*/
- attinfo->numAttr = tupleType->natts;
- attinfo->attrs = tupleType->attrs;
- return attinfo;
+ attinfo->numAttr = tupleType->natts;
+ attinfo->attrs = tupleType->attrs;
+ return attinfo;
}
+
#endif
/* ----------------------------------------------------------------
- * ExecInsertIndexTuples support
+ * ExecInsertIndexTuples support
* ----------------------------------------------------------------
*/
/* ----------------------------------------------------------------
- * ExecGetIndexKeyInfo
+ * ExecGetIndexKeyInfo
*
- * Extracts the index key attribute numbers from
- * an index tuple form (i.e. a tuple from the pg_index relation)
- * into an array of attribute numbers. The array and the
- * size of the array are returned to the caller via return
- * parameters.
+ * Extracts the index key attribute numbers from
+ * an index tuple form (i.e. a tuple from the pg_index relation)
+ * into an array of attribute numbers. The array and the
+ * size of the array are returned to the caller via return
+ * parameters.
* ----------------------------------------------------------------
*/
static void
ExecGetIndexKeyInfo(IndexTupleForm indexTuple,
- int *numAttsOutP,
- AttrNumber **attsOutP,
- FuncIndexInfoPtr fInfoP)
+ int *numAttsOutP,
+ AttrNumber ** attsOutP,
+ FuncIndexInfoPtr fInfoP)
{
- int i;
- int numKeys;
- AttrNumber *attKeys;
-
- /* ----------------
- * check parameters
- * ----------------
- */
- if (numAttsOutP == NULL && attsOutP == NULL) {
- elog(DEBUG, "ExecGetIndexKeyInfo: %s",
- "invalid parameters: numAttsOutP and attsOutP must be non-NULL");
- }
-
- /* ----------------
- * set the procid for a possible functional index.
- * ----------------
- */
- FIsetProcOid(fInfoP, indexTuple->indproc);
-
- /* ----------------
- * count the number of keys..
- * ----------------
- */
- numKeys = 0;
- for (i=0; i<8 && indexTuple->indkey[i] != 0; i++)
- numKeys++;
-
- /* ----------------
- * place number keys in callers return area
- * or the number of arguments for a functional index.
- *
- * If we have a functional index then the number of
- * attributes defined in the index must 1 (the function's
- * single return value).
- * ----------------
- */
- if (FIgetProcOid(fInfoP) != InvalidOid) {
- FIsetnArgs(fInfoP, numKeys);
- (*numAttsOutP) = 1;
- }
- else
- (*numAttsOutP) = numKeys;
-
- if (numKeys < 1) {
- elog(DEBUG, "ExecGetIndexKeyInfo: %s",
- "all index key attribute numbers are zero!");
- (*attsOutP) = NULL;
- return;
- }
-
- /* ----------------
- * allocate and fill in array of key attribute numbers
- * ----------------
- */
- CXT1_printf("ExecGetIndexKeyInfo: context is %d\n", CurrentMemoryContext);
-
- attKeys = (AttrNumber*)
- palloc(numKeys * sizeof(AttrNumber));
-
- for (i=0; i<numKeys; i++)
- attKeys[i] = indexTuple->indkey[i];
-
- /* ----------------
- * return array to caller.
- * ----------------
- */
- (*attsOutP) = attKeys;
-}
+ int i;
+ int numKeys;
+ AttrNumber *attKeys;
-/* ----------------------------------------------------------------
- * ExecOpenIndices
- *
- * Here we scan the pg_index relation to find indices
- * associated with a given heap relation oid. Since we
- * don't know in advance how many indices we have, we
- * form lists containing the information we need from
- * pg_index and then process these lists.
- *
- * Note: much of this code duplicates effort done by
- * the IndexCatalogInformation function in plancat.c
- * because IndexCatalogInformation is poorly written.
- *
- * It would be much better the functionality provided
- * by this function and IndexCatalogInformation was
- * in the form of a small set of orthogonal routines..
- * If you are trying to understand this, I suggest you
- * look at the code to IndexCatalogInformation and
- * FormIndexTuple.. -cim 9/27/89
- * ----------------------------------------------------------------
- */
-void
-ExecOpenIndices(Oid resultRelationOid,
- RelationInfo *resultRelationInfo)
-{
- Relation indexRd;
- HeapScanDesc indexSd;
- ScanKeyData key;
- HeapTuple tuple;
- IndexTupleForm indexStruct;
- Oid indexOid;
- List *oidList;
- List *nkeyList;
- List *keyList;
- List *fiList;
- char *predString;
- List *predList;
- List *indexoid;
- List *numkeys;
- List *indexkeys;
- List *indexfuncs;
- List *indexpreds;
- int len;
-
- RelationPtr relationDescs;
- IndexInfo **indexInfoArray;
- FuncIndexInfoPtr fInfoP;
- int numKeyAtts;
- AttrNumber *indexKeyAtts;
- PredInfo *predicate;
- int i;
-
- /* ----------------
- * open pg_index
- * ----------------
- */
- indexRd = heap_openr(IndexRelationName);
-
- /* ----------------
- * form a scan key
- * ----------------
- */
- ScanKeyEntryInitialize(&key, 0, Anum_pg_index_indrelid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(resultRelationOid));
-
- /* ----------------
- * scan the index relation, looking for indices for our
- * result relation..
- * ----------------
- */
- indexSd = heap_beginscan(indexRd, /* scan desc */
- false, /* scan backward flag */
- NowTimeQual, /* time qual */
- 1, /* number scan keys */
- &key); /* scan keys */
-
- oidList = NIL;
- nkeyList = NIL;
- keyList = NIL;
- fiList = NIL;
- predList = NIL;
-
- while(tuple = heap_getnext(indexSd, /* scan desc */
- false, /* scan backward flag */
- NULL), /* return: buffer */
- HeapTupleIsValid(tuple)) {
-
/* ----------------
- * For each index relation we find, extract the information
- * we need and store it in a list..
- *
- * first get the oid of the index relation from the tuple
+ * check parameters
* ----------------
*/
- indexStruct = (IndexTupleForm) GETSTRUCT(tuple);
- indexOid = indexStruct->indexrelid;
-
+ if (numAttsOutP == NULL && attsOutP == NULL)
+ {
+ elog(DEBUG, "ExecGetIndexKeyInfo: %s",
+ "invalid parameters: numAttsOutP and attsOutP must be non-NULL");
+ }
+
/* ----------------
- * allocate space for functional index information.
+ * set the procid for a possible functional index.
* ----------------
*/
- fInfoP = (FuncIndexInfoPtr)palloc( sizeof(*fInfoP) );
-
+ FIsetProcOid(fInfoP, indexTuple->indproc);
+
/* ----------------
- * next get the index key information from the tuple
+ * count the number of keys..
* ----------------
*/
- ExecGetIndexKeyInfo(indexStruct,
- &numKeyAtts,
- &indexKeyAtts,
- fInfoP);
-
+ numKeys = 0;
+ for (i = 0; i < 8 && indexTuple->indkey[i] != 0; i++)
+ numKeys++;
+
/* ----------------
- * next get the index predicate from the tuple
+ * place number keys in callers return area
+ * or the number of arguments for a functional index.
+ *
+ * If we have a functional index then the number of
+ * attributes defined in the index must 1 (the function's
+ * single return value).
* ----------------
*/
- if (VARSIZE(&indexStruct->indpred) != 0) {
- predString = fmgr(F_TEXTOUT, &indexStruct->indpred);
- predicate = (PredInfo*)stringToNode(predString);
- pfree(predString);
- } else {
- predicate = NULL;
+ if (FIgetProcOid(fInfoP) != InvalidOid)
+ {
+ FIsetnArgs(fInfoP, numKeys);
+ (*numAttsOutP) = 1;
+ }
+ else
+ (*numAttsOutP) = numKeys;
+
+ if (numKeys < 1)
+ {
+ elog(DEBUG, "ExecGetIndexKeyInfo: %s",
+ "all index key attribute numbers are zero!");
+ (*attsOutP) = NULL;
+ return;
}
-
+
/* ----------------
- * save the index information into lists
+ * allocate and fill in array of key attribute numbers
* ----------------
*/
- oidList = lconsi(indexOid, oidList);
- nkeyList = lconsi(numKeyAtts, nkeyList);
- keyList = lcons(indexKeyAtts, keyList);
- fiList = lcons(fInfoP, fiList);
- predList = lcons(predicate, predList);
- }
-
- /* ----------------
- * we have the info we need so close the pg_index relation..
- * ----------------
- */
- heap_endscan(indexSd);
- heap_close(indexRd);
-
- /* ----------------
- * Now that we've collected the index information into three
- * lists, we open the index relations and store the descriptors
- * and the key information into arrays.
- * ----------------
- */
- len = length(oidList);
- if (len > 0) {
+ CXT1_printf("ExecGetIndexKeyInfo: context is %d\n", CurrentMemoryContext);
+
+ attKeys = (AttrNumber *)
+ palloc(numKeys * sizeof(AttrNumber));
+
+ for (i = 0; i < numKeys; i++)
+ attKeys[i] = indexTuple->indkey[i];
+
/* ----------------
- * allocate space for relation descs
+ * return array to caller.
* ----------------
*/
- CXT1_printf("ExecOpenIndices: context is %d\n", CurrentMemoryContext);
- relationDescs = (RelationPtr)
- palloc(len * sizeof(Relation));
-
+ (*attsOutP) = attKeys;
+}
+
+/* ----------------------------------------------------------------
+ * ExecOpenIndices
+ *
+ * Here we scan the pg_index relation to find indices
+ * associated with a given heap relation oid. Since we
+ * don't know in advance how many indices we have, we
+ * form lists containing the information we need from
+ * pg_index and then process these lists.
+ *
+ * Note: much of this code duplicates effort done by
+ * the IndexCatalogInformation function in plancat.c
+ * because IndexCatalogInformation is poorly written.
+ *
+ * It would be much better the functionality provided
+ * by this function and IndexCatalogInformation was
+ * in the form of a small set of orthogonal routines..
+ * If you are trying to understand this, I suggest you
+ * look at the code to IndexCatalogInformation and
+ * FormIndexTuple.. -cim 9/27/89
+ * ----------------------------------------------------------------
+ */
+void
+ExecOpenIndices(Oid resultRelationOid,
+ RelationInfo * resultRelationInfo)
+{
+ Relation indexRd;
+ HeapScanDesc indexSd;
+ ScanKeyData key;
+ HeapTuple tuple;
+ IndexTupleForm indexStruct;
+ Oid indexOid;
+ List *oidList;
+ List *nkeyList;
+ List *keyList;
+ List *fiList;
+ char *predString;
+ List *predList;
+ List *indexoid;
+ List *numkeys;
+ List *indexkeys;
+ List *indexfuncs;
+ List *indexpreds;
+ int len;
+
+ RelationPtr relationDescs;
+ IndexInfo **indexInfoArray;
+ FuncIndexInfoPtr fInfoP;
+ int numKeyAtts;
+ AttrNumber *indexKeyAtts;
+ PredInfo *predicate;
+ int i;
+
/* ----------------
- * initialize index info array
+ * open pg_index
* ----------------
*/
- CXT1_printf("ExecOpenIndices: context is %d\n", CurrentMemoryContext);
- indexInfoArray = (IndexInfo**)
- palloc(len * sizeof(IndexInfo*));
-
- for (i=0; i<len; i++) {
- IndexInfo *ii = makeNode(IndexInfo);
- ii->ii_NumKeyAttributes = 0;
- ii->ii_KeyAttributeNumbers = (AttrNumber*) NULL;
- ii->ii_FuncIndexInfo = (FuncIndexInfoPtr) NULL;
- ii->ii_Predicate = NULL;
- indexInfoArray[i] = ii;
- }
-
+ indexRd = heap_openr(IndexRelationName);
+
/* ----------------
- * attempt to open each of the indices. If we succeed,
- * then store the index relation descriptor into the
- * relation descriptor array.
+ * form a scan key
* ----------------
*/
- i = 0;
- foreach (indexoid, oidList) {
- Relation indexDesc;
-
- indexOid = lfirsti(indexoid);
- indexDesc = index_open(indexOid);
- if (indexDesc != NULL)
- relationDescs[i++] = indexDesc;
+ ScanKeyEntryInitialize(&key, 0, Anum_pg_index_indrelid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(resultRelationOid));
+
+ /* ----------------
+ * scan the index relation, looking for indices for our
+ * result relation..
+ * ----------------
+ */
+ indexSd = heap_beginscan(indexRd, /* scan desc */
+ false, /* scan backward flag */
+ NowTimeQual, /* time qual */
+ 1, /* number scan keys */
+ &key); /* scan keys */
+
+ oidList = NIL;
+ nkeyList = NIL;
+ keyList = NIL;
+ fiList = NIL;
+ predList = NIL;
+
+ while (tuple = heap_getnext(indexSd, /* scan desc */
+ false, /* scan backward flag */
+ NULL), /* return: buffer */
+ HeapTupleIsValid(tuple))
+ {
+
+ /* ----------------
+ * For each index relation we find, extract the information
+ * we need and store it in a list..
+ *
+ * first get the oid of the index relation from the tuple
+ * ----------------
+ */
+ indexStruct = (IndexTupleForm) GETSTRUCT(tuple);
+ indexOid = indexStruct->indexrelid;
+
+ /* ----------------
+ * allocate space for functional index information.
+ * ----------------
+ */
+ fInfoP = (FuncIndexInfoPtr) palloc(sizeof(*fInfoP));
+
+ /* ----------------
+ * next get the index key information from the tuple
+ * ----------------
+ */
+ ExecGetIndexKeyInfo(indexStruct,
+ &numKeyAtts,
+ &indexKeyAtts,
+ fInfoP);
+
+ /* ----------------
+ * next get the index predicate from the tuple
+ * ----------------
+ */
+ if (VARSIZE(&indexStruct->indpred) != 0)
+ {
+ predString = fmgr(F_TEXTOUT, &indexStruct->indpred);
+ predicate = (PredInfo *) stringToNode(predString);
+ pfree(predString);
+ }
+ else
+ {
+ predicate = NULL;
+ }
+
+ /* ----------------
+ * save the index information into lists
+ * ----------------
+ */
+ oidList = lconsi(indexOid, oidList);
+ nkeyList = lconsi(numKeyAtts, nkeyList);
+ keyList = lcons(indexKeyAtts, keyList);
+ fiList = lcons(fInfoP, fiList);
+ predList = lcons(predicate, predList);
}
-
+
/* ----------------
- * store the relation descriptor array and number of
- * descs into the result relation info.
+ * we have the info we need so close the pg_index relation..
* ----------------
*/
- resultRelationInfo->ri_NumIndices = i;
- resultRelationInfo->ri_IndexRelationDescs = relationDescs;
-
+ heap_endscan(indexSd);
+ heap_close(indexRd);
+
/* ----------------
- * store the index key information collected in our
- * lists into the index info array
+ * Now that we've collected the index information into three
+ * lists, we open the index relations and store the descriptors
+ * and the key information into arrays.
* ----------------
*/
- i = 0;
- foreach (numkeys, nkeyList) {
- numKeyAtts = lfirsti(numkeys);
- indexInfoArray[i++]->ii_NumKeyAttributes = numKeyAtts;
- }
-
- i = 0;
- foreach (indexkeys, keyList) {
- indexKeyAtts = (AttrNumber*) lfirst(indexkeys);
- indexInfoArray[i++]->ii_KeyAttributeNumbers = indexKeyAtts;
- }
-
- i = 0;
- foreach (indexfuncs, fiList) {
- FuncIndexInfoPtr fiP = (FuncIndexInfoPtr)lfirst(indexfuncs);
- indexInfoArray[i++]->ii_FuncIndexInfo = fiP;
- }
-
- i = 0;
- foreach (indexpreds, predList) {
- indexInfoArray[i++]->ii_Predicate = lfirst(indexpreds);
+ len = length(oidList);
+ if (len > 0)
+ {
+ /* ----------------
+ * allocate space for relation descs
+ * ----------------
+ */
+ CXT1_printf("ExecOpenIndices: context is %d\n", CurrentMemoryContext);
+ relationDescs = (RelationPtr)
+ palloc(len * sizeof(Relation));
+
+ /* ----------------
+ * initialize index info array
+ * ----------------
+ */
+ CXT1_printf("ExecOpenIndices: context is %d\n", CurrentMemoryContext);
+ indexInfoArray = (IndexInfo **)
+ palloc(len * sizeof(IndexInfo *));
+
+ for (i = 0; i < len; i++)
+ {
+ IndexInfo *ii = makeNode(IndexInfo);
+
+ ii->ii_NumKeyAttributes = 0;
+ ii->ii_KeyAttributeNumbers = (AttrNumber *) NULL;
+ ii->ii_FuncIndexInfo = (FuncIndexInfoPtr) NULL;
+ ii->ii_Predicate = NULL;
+ indexInfoArray[i] = ii;
+ }
+
+ /* ----------------
+ * attempt to open each of the indices. If we succeed,
+ * then store the index relation descriptor into the
+ * relation descriptor array.
+ * ----------------
+ */
+ i = 0;
+ foreach(indexoid, oidList)
+ {
+ Relation indexDesc;
+
+ indexOid = lfirsti(indexoid);
+ indexDesc = index_open(indexOid);
+ if (indexDesc != NULL)
+ relationDescs[i++] = indexDesc;
+ }
+
+ /* ----------------
+ * store the relation descriptor array and number of
+ * descs into the result relation info.
+ * ----------------
+ */
+ resultRelationInfo->ri_NumIndices = i;
+ resultRelationInfo->ri_IndexRelationDescs = relationDescs;
+
+ /* ----------------
+ * store the index key information collected in our
+ * lists into the index info array
+ * ----------------
+ */
+ i = 0;
+ foreach(numkeys, nkeyList)
+ {
+ numKeyAtts = lfirsti(numkeys);
+ indexInfoArray[i++]->ii_NumKeyAttributes = numKeyAtts;
+ }
+
+ i = 0;
+ foreach(indexkeys, keyList)
+ {
+ indexKeyAtts = (AttrNumber *) lfirst(indexkeys);
+ indexInfoArray[i++]->ii_KeyAttributeNumbers = indexKeyAtts;
+ }
+
+ i = 0;
+ foreach(indexfuncs, fiList)
+ {
+ FuncIndexInfoPtr fiP = (FuncIndexInfoPtr) lfirst(indexfuncs);
+
+ indexInfoArray[i++]->ii_FuncIndexInfo = fiP;
+ }
+
+ i = 0;
+ foreach(indexpreds, predList)
+ {
+ indexInfoArray[i++]->ii_Predicate = lfirst(indexpreds);
+ }
+ /* ----------------
+ * store the index info array into relation info
+ * ----------------
+ */
+ resultRelationInfo->ri_IndexRelationInfo = indexInfoArray;
}
+
/* ----------------
- * store the index info array into relation info
+ * All done, resultRelationInfo now contains complete information
+ * on the indices associated with the result relation.
* ----------------
*/
- resultRelationInfo->ri_IndexRelationInfo = indexInfoArray;
- }
-
- /* ----------------
- * All done, resultRelationInfo now contains complete information
- * on the indices associated with the result relation.
- * ----------------
- */
-
- /* should free oidList, nkeyList and keyList here */
- /* OK - let's do it -jolly */
- freeList(oidList);
- freeList(nkeyList);
- freeList(keyList);
- freeList(fiList);
- freeList(predList);
+
+ /* should free oidList, nkeyList and keyList here */
+ /* OK - let's do it -jolly */
+ freeList(oidList);
+ freeList(nkeyList);
+ freeList(keyList);
+ freeList(fiList);
+ freeList(predList);
}
/* ----------------------------------------------------------------
- * ExecCloseIndices
+ * ExecCloseIndices
*
- * Close the index relations stored in resultRelationInfo
+ * Close the index relations stored in resultRelationInfo
* ----------------------------------------------------------------
*/
void
-ExecCloseIndices(RelationInfo *resultRelationInfo)
+ExecCloseIndices(RelationInfo * resultRelationInfo)
{
- int i;
- int numIndices;
- RelationPtr relationDescs;
-
- numIndices = resultRelationInfo->ri_NumIndices;
- relationDescs = resultRelationInfo->ri_IndexRelationDescs;
-
- for (i=0; i<numIndices; i++)
- if (relationDescs[i] != NULL)
- index_close(relationDescs[i]);
- /*
- * XXX should free indexInfo array here too.
- */
+ int i;
+ int numIndices;
+ RelationPtr relationDescs;
+
+ numIndices = resultRelationInfo->ri_NumIndices;
+ relationDescs = resultRelationInfo->ri_IndexRelationDescs;
+
+ for (i = 0; i < numIndices; i++)
+ if (relationDescs[i] != NULL)
+ index_close(relationDescs[i]);
+
+ /*
+ * XXX should free indexInfo array here too.
+ */
}
/* ----------------------------------------------------------------
- * ExecFormIndexTuple
+ * ExecFormIndexTuple
*
- * Most of this code is cannabilized from DefaultBuild().
- * As said in the comments for ExecOpenIndices, most of
- * this functionality should be rearranged into a proper
- * set of routines..
+ * Most of this code is cannabilized from DefaultBuild().
+ * As said in the comments for ExecOpenIndices, most of
+ * this functionality should be rearranged into a proper
+ * set of routines..
* ----------------------------------------------------------------
*/
#ifdef NOT_USED
IndexTuple
ExecFormIndexTuple(HeapTuple heapTuple,
- Relation heapRelation,
- Relation indexRelation,
- IndexInfo *indexInfo)
+ Relation heapRelation,
+ Relation indexRelation,
+ IndexInfo * indexInfo)
{
- IndexTuple indexTuple;
- TupleDesc heapDescriptor;
- TupleDesc indexDescriptor;
- Datum *datum;
- char *nulls;
-
- int numberOfAttributes;
- AttrNumber *keyAttributeNumbers;
- FuncIndexInfoPtr fInfoP;
-
- /* ----------------
- * get information from index info structure
- * ----------------
- */
- numberOfAttributes = indexInfo->ii_NumKeyAttributes;
- keyAttributeNumbers = indexInfo->ii_KeyAttributeNumbers;
- fInfoP = indexInfo->ii_FuncIndexInfo;
-
- /* ----------------
- * datum and null are arrays in which we collect the index attributes
- * when forming a new index tuple.
- * ----------------
- */
- CXT1_printf("ExecFormIndexTuple: context is %d\n", CurrentMemoryContext);
- datum = (Datum *) palloc(numberOfAttributes * sizeof *datum);
- nulls = (char *) palloc(numberOfAttributes * sizeof *nulls);
-
- /* ----------------
- * get the tuple descriptors from the relations so we know
- * how to form the index tuples..
- * ----------------
- */
- heapDescriptor = RelationGetTupleDescriptor(heapRelation);
- indexDescriptor = RelationGetTupleDescriptor(indexRelation);
-
- /* ----------------
- * FormIndexDatum fills in its datum and null parameters
- * with attribute information taken from the given heap tuple.
- * ----------------
- */
- FormIndexDatum(numberOfAttributes, /* num attributes */
- keyAttributeNumbers, /* array of att nums to extract */
- heapTuple, /* tuple from base relation */
- heapDescriptor, /* heap tuple's descriptor */
- InvalidBuffer, /* buffer associated with heap tuple */
- datum, /* return: array of attributes */
- nulls, /* return: array of char's */
- fInfoP); /* functional index information */
-
- indexTuple = index_formtuple(indexDescriptor,
- datum,
- nulls);
-
- /* ----------------
- * free temporary arrays
- *
- * XXX should store these in the IndexInfo instead of allocating
- * and freeing on every insertion, but efficency here is not
- * that important and FormIndexTuple is wasteful anyways..
- * -cim 9/27/89
- * ----------------
- */
- pfree(nulls);
- pfree(datum);
-
- return indexTuple;
+ IndexTuple indexTuple;
+ TupleDesc heapDescriptor;
+ TupleDesc indexDescriptor;
+ Datum *datum;
+ char *nulls;
+
+ int numberOfAttributes;
+ AttrNumber *keyAttributeNumbers;
+ FuncIndexInfoPtr fInfoP;
+
+ /* ----------------
+ * get information from index info structure
+ * ----------------
+ */
+ numberOfAttributes = indexInfo->ii_NumKeyAttributes;
+ keyAttributeNumbers = indexInfo->ii_KeyAttributeNumbers;
+ fInfoP = indexInfo->ii_FuncIndexInfo;
+
+ /* ----------------
+ * datum and null are arrays in which we collect the index attributes
+ * when forming a new index tuple.
+ * ----------------
+ */
+ CXT1_printf("ExecFormIndexTuple: context is %d\n", CurrentMemoryContext);
+ datum = (Datum *) palloc(numberOfAttributes * sizeof *datum);
+ nulls = (char *) palloc(numberOfAttributes * sizeof *nulls);
+
+ /* ----------------
+ * get the tuple descriptors from the relations so we know
+ * how to form the index tuples..
+ * ----------------
+ */
+ heapDescriptor = RelationGetTupleDescriptor(heapRelation);
+ indexDescriptor = RelationGetTupleDescriptor(indexRelation);
+
+ /* ----------------
+ * FormIndexDatum fills in its datum and null parameters
+ * with attribute information taken from the given heap tuple.
+ * ----------------
+ */
+ FormIndexDatum(numberOfAttributes, /* num attributes */
+ keyAttributeNumbers, /* array of att nums to extract */
+ heapTuple, /* tuple from base relation */
+ heapDescriptor, /* heap tuple's descriptor */
+ InvalidBuffer, /* buffer associated with heap
+ * tuple */
+ datum, /* return: array of attributes */
+ nulls, /* return: array of char's */
+ fInfoP); /* functional index information */
+
+ indexTuple = index_formtuple(indexDescriptor,
+ datum,
+ nulls);
+
+ /* ----------------
+ * free temporary arrays
+ *
+ * XXX should store these in the IndexInfo instead of allocating
+ * and freeing on every insertion, but efficency here is not
+ * that important and FormIndexTuple is wasteful anyways..
+ * -cim 9/27/89
+ * ----------------
+ */
+ pfree(nulls);
+ pfree(datum);
+
+ return indexTuple;
}
+
#endif
/* ----------------------------------------------------------------
- * ExecInsertIndexTuples
+ * ExecInsertIndexTuples
*
- * This routine takes care of inserting index tuples
- * into all the relations indexing the result relation
- * when a heap tuple is inserted into the result relation.
- * Much of this code should be moved into the genam
- * stuff as it only exists here because the genam stuff
- * doesn't provide the functionality needed by the
- * executor.. -cim 9/27/89
+ * This routine takes care of inserting index tuples
+ * into all the relations indexing the result relation
+ * when a heap tuple is inserted into the result relation.
+ * Much of this code should be moved into the genam
+ * stuff as it only exists here because the genam stuff
+ * doesn't provide the functionality needed by the
+ * executor.. -cim 9/27/89
* ----------------------------------------------------------------
*/
void
-ExecInsertIndexTuples(TupleTableSlot *slot,
- ItemPointer tupleid,
- EState *estate,
- bool is_update)
+ExecInsertIndexTuples(TupleTableSlot * slot,
+ ItemPointer tupleid,
+ EState * estate,
+ bool is_update)
{
- HeapTuple heapTuple;
- RelationInfo *resultRelationInfo;
- int i;
- int numIndices;
- RelationPtr relationDescs;
- Relation heapRelation;
- IndexInfo **indexInfoArray;
- IndexInfo *indexInfo;
- Node *predicate;
- bool satisfied;
- ExprContext *econtext;
- InsertIndexResult result;
- int numberOfAttributes;
- AttrNumber *keyAttributeNumbers;
- FuncIndexInfoPtr fInfoP;
- TupleDesc heapDescriptor;
- Datum *datum;
- char *nulls;
-
- heapTuple = slot->val;
-
- /* ----------------
- * get information from the result relation info structure.
- * ----------------
- */
- resultRelationInfo = estate->es_result_relation_info;
- numIndices = resultRelationInfo->ri_NumIndices;
- relationDescs = resultRelationInfo->ri_IndexRelationDescs;
- indexInfoArray = resultRelationInfo->ri_IndexRelationInfo;
- heapRelation = resultRelationInfo->ri_RelationDesc;
-
- /* ----------------
- * for each index, form and insert the index tuple
- * ----------------
- */
- econtext = NULL;
- for (i=0; i<numIndices; i++) {
- if (relationDescs[i] == NULL) continue;
-
- indexInfo = indexInfoArray[i];
- predicate = indexInfo->ii_Predicate;
- if (predicate != NULL) {
- if (econtext == NULL) {
- econtext = makeNode(ExprContext);
- }
- econtext->ecxt_scantuple = slot;
-
- /* Skip this index-update if the predicate isn't satisfied */
- satisfied = ExecQual((List*)predicate, econtext);
- if (satisfied == false)
- continue;
- }
+ HeapTuple heapTuple;
+ RelationInfo *resultRelationInfo;
+ int i;
+ int numIndices;
+ RelationPtr relationDescs;
+ Relation heapRelation;
+ IndexInfo **indexInfoArray;
+ IndexInfo *indexInfo;
+ Node *predicate;
+ bool satisfied;
+ ExprContext *econtext;
+ InsertIndexResult result;
+ int numberOfAttributes;
+ AttrNumber *keyAttributeNumbers;
+ FuncIndexInfoPtr fInfoP;
+ TupleDesc heapDescriptor;
+ Datum *datum;
+ char *nulls;
+
+ heapTuple = slot->val;
/* ----------------
- * get information from index info structure
+ * get information from the result relation info structure.
* ----------------
*/
- numberOfAttributes = indexInfo->ii_NumKeyAttributes;
- keyAttributeNumbers = indexInfo->ii_KeyAttributeNumbers;
- fInfoP = indexInfo->ii_FuncIndexInfo;
- datum = (Datum *) palloc(numberOfAttributes * sizeof *datum);
- nulls = (char *) palloc(numberOfAttributes * sizeof *nulls);
- heapDescriptor = (TupleDesc)RelationGetTupleDescriptor(heapRelation);
-
- FormIndexDatum(numberOfAttributes, /* num attributes */
- keyAttributeNumbers, /* array of att nums to extract */
- heapTuple, /* tuple from base relation */
- heapDescriptor, /* heap tuple's descriptor */
- InvalidBuffer, /* buffer associated with heap tuple */
- datum, /* return: array of attributes */
- nulls, /* return: array of char's */
- fInfoP); /* functional index information */
-
-
- result = index_insert(relationDescs[i], /* index relation */
- datum, /* array of heaptuple Datums */
- nulls, /* info on nulls */
- &(heapTuple->t_ctid), /* oid of heap tuple */
- heapRelation);
-
- /* ----------------
- * keep track of index inserts for debugging
- * ----------------
- */
- IncrIndexInserted();
-
+ resultRelationInfo = estate->es_result_relation_info;
+ numIndices = resultRelationInfo->ri_NumIndices;
+ relationDescs = resultRelationInfo->ri_IndexRelationDescs;
+ indexInfoArray = resultRelationInfo->ri_IndexRelationInfo;
+ heapRelation = resultRelationInfo->ri_RelationDesc;
+
/* ----------------
- * free index tuple after insertion
+ * for each index, form and insert the index tuple
* ----------------
*/
- if (result) pfree(result);
- }
- if (econtext != NULL) pfree(econtext);
+ econtext = NULL;
+ for (i = 0; i < numIndices; i++)
+ {
+ if (relationDescs[i] == NULL)
+ continue;
+
+ indexInfo = indexInfoArray[i];
+ predicate = indexInfo->ii_Predicate;
+ if (predicate != NULL)
+ {
+ if (econtext == NULL)
+ {
+ econtext = makeNode(ExprContext);
+ }
+ econtext->ecxt_scantuple = slot;
+
+ /* Skip this index-update if the predicate isn't satisfied */
+ satisfied = ExecQual((List *) predicate, econtext);
+ if (satisfied == false)
+ continue;
+ }
+
+ /* ----------------
+ * get information from index info structure
+ * ----------------
+ */
+ numberOfAttributes = indexInfo->ii_NumKeyAttributes;
+ keyAttributeNumbers = indexInfo->ii_KeyAttributeNumbers;
+ fInfoP = indexInfo->ii_FuncIndexInfo;
+ datum = (Datum *) palloc(numberOfAttributes * sizeof *datum);
+ nulls = (char *) palloc(numberOfAttributes * sizeof *nulls);
+ heapDescriptor = (TupleDesc) RelationGetTupleDescriptor(heapRelation);
+
+ FormIndexDatum(numberOfAttributes, /* num attributes */
+ keyAttributeNumbers, /* array of att nums to
+ * extract */
+ heapTuple, /* tuple from base relation */
+ heapDescriptor, /* heap tuple's descriptor */
+ InvalidBuffer, /* buffer associated with heap
+ * tuple */
+ datum, /* return: array of attributes */
+ nulls, /* return: array of char's */
+ fInfoP); /* functional index information */
+
+
+ result = index_insert(relationDescs[i], /* index relation */
+ datum, /* array of heaptuple Datums */
+ nulls, /* info on nulls */
+ &(heapTuple->t_ctid), /* oid of heap tuple */
+ heapRelation);
+
+ /* ----------------
+ * keep track of index inserts for debugging
+ * ----------------
+ */
+ IncrIndexInserted();
+
+ /* ----------------
+ * free index tuple after insertion
+ * ----------------
+ */
+ if (result)
+ pfree(result);
+ }
+ if (econtext != NULL)
+ pfree(econtext);
}
/* ----------------------------------------------------------------
* setVarAttrLenForCreateTable -
- * called when we do a SELECT * INTO TABLE tab
- * needed for attributes that have a defined length, like bpchar and
- * varchar
+ * called when we do a SELECT * INTO TABLE tab
+ * needed for attributes that have a defined length, like bpchar and
+ * varchar
* ----------------------------------------------------------------
*/
void
-setVarAttrLenForCreateTable(TupleDesc tupType, List *targetList,
- List *rangeTable)
+setVarAttrLenForCreateTable(TupleDesc tupType, List * targetList,
+ List * rangeTable)
{
- List *tl;
- TargetEntry *tle;
- Node *expr;
- int varno;
-
- tl = targetList;
-
- for (varno = 0; varno < tupType->natts; varno++) {
- tle = lfirst(tl);
-
- if (tupType->attrs[varno]->atttypid == BPCHAROID ||
- tupType->attrs[varno]->atttypid == VARCHAROID) {
- expr = tle->expr;
- if (expr && IsA(expr,Var)) {
- Var *var;
- RangeTblEntry *rtentry;
- Relation rd;
-
- var = (Var *)expr;
- rtentry = rt_fetch(var->varnoold, rangeTable);
- rd = heap_open(rtentry->relid);
- /* set length to that defined in relation */
- tupType->attrs[varno]->attlen =
- (*rd->rd_att->attrs[var->varoattno-1]).attlen;
- heap_close(rd);
- }
- else
- elog(WARN, "setVarAttrLenForCreateTable: can't get length for variable-length field");
- }
- tl = lnext(tl);
- }
+ List *tl;
+ TargetEntry *tle;
+ Node *expr;
+ int varno;
+
+ tl = targetList;
+
+ for (varno = 0; varno < tupType->natts; varno++)
+ {
+ tle = lfirst(tl);
+
+ if (tupType->attrs[varno]->atttypid == BPCHAROID ||
+ tupType->attrs[varno]->atttypid == VARCHAROID)
+ {
+ expr = tle->expr;
+ if (expr && IsA(expr, Var))
+ {
+ Var *var;
+ RangeTblEntry *rtentry;
+ Relation rd;
+
+ var = (Var *) expr;
+ rtentry = rt_fetch(var->varnoold, rangeTable);
+ rd = heap_open(rtentry->relid);
+ /* set length to that defined in relation */
+ tupType->attrs[varno]->attlen =
+ (*rd->rd_att->attrs[var->varoattno - 1]).attlen;
+ heap_close(rd);
+ }
+ else
+ elog(WARN, "setVarAttrLenForCreateTable: can't get length for variable-length field");
+ }
+ tl = lnext(tl);
+ }
}
-#ifdef NOT_USED /* look at execMain.c */
+#ifdef NOT_USED /* look at execMain.c */
/* ----------------------------------------------------------------
* resetVarAttrLenForCreateTable -
- * called when we do a SELECT * INTO TABLE tab
- * needed for attributes that have a defined length, like bpchar and
- * varchar
- * resets length to -1 for those types
+ * called when we do a SELECT * INTO TABLE tab
+ * needed for attributes that have a defined length, like bpchar and
+ * varchar
+ * resets length to -1 for those types
* ----------------------------------------------------------------
*/
void
resetVarAttrLenForCreateTable(TupleDesc tupType)
{
- int varno;
-
- for (varno = 0; varno < tupType->natts; varno++) {
- if (tupType->attrs[varno]->atttypid == BPCHAROID ||
- tupType->attrs[varno]->atttypid == VARCHAROID)
- /* set length to original -1 */
- tupType->attrs[varno]->attlen = -1;
- }
+ int varno;
+
+ for (varno = 0; varno < tupType->natts; varno++)
+ {
+ if (tupType->attrs[varno]->atttypid == BPCHAROID ||
+ tupType->attrs[varno]->atttypid == VARCHAROID)
+ /* set length to original -1 */
+ tupType->attrs[varno]->attlen = -1;
+ }
}
+
#endif
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 79f8bede085..96b9b19dcb6 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* functions.c--
- * Routines to handle functions called from the executor
- * Putting this stuff in fmgr makes the postmaster a mess....
+ * Routines to handle functions called from the executor
+ * Putting this stuff in fmgr makes the postmaster a mess....
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.7 1997/08/29 09:02:50 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.8 1997/09/07 04:41:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -41,401 +41,438 @@
#undef new
-typedef enum {F_EXEC_START, F_EXEC_RUN, F_EXEC_DONE} ExecStatus;
+typedef enum
+{
+ F_EXEC_START, F_EXEC_RUN, F_EXEC_DONE
+} ExecStatus;
-typedef struct local_es {
- QueryDesc *qd;
- EState *estate;
- struct local_es *next;
- ExecStatus status;
-} execution_state;
+typedef struct local_es
+{
+ QueryDesc *qd;
+ EState *estate;
+ struct local_es *next;
+ ExecStatus status;
+} execution_state;
#define LAST_POSTQUEL_COMMAND(es) ((es)->next == (execution_state *)NULL)
/* non-export function prototypes */
-static TupleDesc postquel_start(execution_state *es);
-static execution_state *init_execution_state(FunctionCachePtr fcache,
- char *args[]);
-static TupleTableSlot *postquel_getnext(execution_state *es);
-static void postquel_end(execution_state *es);
-static void postquel_sub_params(execution_state *es, int nargs,
- char *args[], bool *nullV);
-static Datum postquel_execute(execution_state *es, FunctionCachePtr fcache,
- List *fTlist, char **args, bool *isNull);
-
+static TupleDesc postquel_start(execution_state * es);
+static execution_state *
+init_execution_state(FunctionCachePtr fcache,
+ char *args[]);
+static TupleTableSlot *postquel_getnext(execution_state * es);
+static void postquel_end(execution_state * es);
+static void
+postquel_sub_params(execution_state * es, int nargs,
+ char *args[], bool * nullV);
+static Datum
+postquel_execute(execution_state * es, FunctionCachePtr fcache,
+ List * fTlist, char **args, bool * isNull);
+
Datum
ProjectAttribute(TupleDesc TD,
- TargetEntry *tlist,
- HeapTuple tup,
- bool *isnullP)
+ TargetEntry * tlist,
+ HeapTuple tup,
+ bool * isnullP)
{
- Datum val,valueP;
- Var *attrVar = (Var *)tlist->expr;
- AttrNumber attrno = attrVar->varattno;
-
-
- val = PointerGetDatum(heap_getattr(tup,
- InvalidBuffer,
- attrno,
- TD,
- isnullP));
- if (*isnullP)
- return (Datum) NULL;
-
- valueP = datumCopy(val,
- TD->attrs[attrno-1]->atttypid,
- TD->attrs[attrno-1]->attbyval,
- (Size) TD->attrs[attrno-1]->attlen);
- return valueP;
+ Datum val,
+ valueP;
+ Var *attrVar = (Var *) tlist->expr;
+ AttrNumber attrno = attrVar->varattno;
+
+
+ val = PointerGetDatum(heap_getattr(tup,
+ InvalidBuffer,
+ attrno,
+ TD,
+ isnullP));
+ if (*isnullP)
+ return (Datum) NULL;
+
+ valueP = datumCopy(val,
+ TD->attrs[attrno - 1]->atttypid,
+ TD->attrs[attrno - 1]->attbyval,
+ (Size) TD->attrs[attrno - 1]->attlen);
+ return valueP;
}
static execution_state *
init_execution_state(FunctionCachePtr fcache,
- char *args[])
+ char *args[])
{
- execution_state *newes;
- execution_state *nextes;
- execution_state *preves;
- QueryTreeList *queryTree_list;
- int i;
- List *planTree_list;
- int nargs;
-
- nargs = fcache->nargs;
-
- newes = (execution_state *) palloc(sizeof(execution_state));
- nextes = newes;
- preves = (execution_state *)NULL;
-
-
- planTree_list = (List *)
- pg_plan(fcache->src, fcache->argOidVect, nargs, &queryTree_list, None);
-
- for (i=0; i < queryTree_list->len; i++) {
- EState *estate;
- Query *queryTree = (Query*) (queryTree_list->qtrees[i]);
- Plan *planTree = lfirst(planTree_list);
-
- if (!nextes)
- nextes = (execution_state *) palloc(sizeof(execution_state));
- if (preves)
- preves->next = nextes;
-
- nextes->next = NULL;
- nextes->status = F_EXEC_START;
- nextes->qd = CreateQueryDesc(queryTree,
- planTree,
- None);
- estate = CreateExecutorState();
-
- if (nargs > 0) {
- int i;
- ParamListInfo paramLI;
-
- paramLI =
- (ParamListInfo)palloc((nargs+1)*sizeof(ParamListInfoData));
-
- memset(paramLI, 0, nargs*sizeof(ParamListInfoData));
-
- estate->es_param_list_info = paramLI;
-
- for (i=0; i<nargs; paramLI++, i++) {
- paramLI->kind = PARAM_NUM;
- paramLI->id = i+1;
- paramLI->isnull = false;
- paramLI->value = (Datum) NULL;
- }
- paramLI->kind = PARAM_INVALID;
+ execution_state *newes;
+ execution_state *nextes;
+ execution_state *preves;
+ QueryTreeList *queryTree_list;
+ int i;
+ List *planTree_list;
+ int nargs;
+
+ nargs = fcache->nargs;
+
+ newes = (execution_state *) palloc(sizeof(execution_state));
+ nextes = newes;
+ preves = (execution_state *) NULL;
+
+
+ planTree_list = (List *)
+ pg_plan(fcache->src, fcache->argOidVect, nargs, &queryTree_list, None);
+
+ for (i = 0; i < queryTree_list->len; i++)
+ {
+ EState *estate;
+ Query *queryTree = (Query *) (queryTree_list->qtrees[i]);
+ Plan *planTree = lfirst(planTree_list);
+
+ if (!nextes)
+ nextes = (execution_state *) palloc(sizeof(execution_state));
+ if (preves)
+ preves->next = nextes;
+
+ nextes->next = NULL;
+ nextes->status = F_EXEC_START;
+ nextes->qd = CreateQueryDesc(queryTree,
+ planTree,
+ None);
+ estate = CreateExecutorState();
+
+ if (nargs > 0)
+ {
+ int i;
+ ParamListInfo paramLI;
+
+ paramLI =
+ (ParamListInfo) palloc((nargs + 1) * sizeof(ParamListInfoData));
+
+ memset(paramLI, 0, nargs * sizeof(ParamListInfoData));
+
+ estate->es_param_list_info = paramLI;
+
+ for (i = 0; i < nargs; paramLI++, i++)
+ {
+ paramLI->kind = PARAM_NUM;
+ paramLI->id = i + 1;
+ paramLI->isnull = false;
+ paramLI->value = (Datum) NULL;
+ }
+ paramLI->kind = PARAM_INVALID;
+ }
+ else
+ estate->es_param_list_info = (ParamListInfo) NULL;
+ nextes->estate = estate;
+ preves = nextes;
+ nextes = (execution_state *) NULL;
+
+ planTree_list = lnext(planTree_list);
}
- else
- estate->es_param_list_info = (ParamListInfo)NULL;
- nextes->estate = estate;
- preves = nextes;
- nextes = (execution_state *)NULL;
-
- planTree_list = lnext(planTree_list);
- }
-
- return newes;
+
+ return newes;
}
-static TupleDesc
-postquel_start(execution_state *es)
+static TupleDesc
+postquel_start(execution_state * es)
{
#ifdef FUNC_UTIL_PATCH
- /*
- * Do nothing for utility commands. (create, destroy...) DZ - 30-8-1996
- */
- if (es->qd->operation == CMD_UTILITY) {
- return (TupleDesc) NULL;
- }
+
+ /*
+ * Do nothing for utility commands. (create, destroy...) DZ -
+ * 30-8-1996
+ */
+ if (es->qd->operation == CMD_UTILITY)
+ {
+ return (TupleDesc) NULL;
+ }
#endif
- return ExecutorStart(es->qd, es->estate);
+ return ExecutorStart(es->qd, es->estate);
}
static TupleTableSlot *
-postquel_getnext(execution_state *es)
+postquel_getnext(execution_state * es)
{
- int feature;
-
+ int feature;
+
#ifdef FUNC_UTIL_PATCH
- if (es->qd->operation == CMD_UTILITY) {
- /*
- * Process an utility command. (create, destroy...) DZ - 30-8-1996
- */
- ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest);
- if (!LAST_POSTQUEL_COMMAND(es)) CommandCounterIncrement();
- return (TupleTableSlot*) NULL;
- }
+ if (es->qd->operation == CMD_UTILITY)
+ {
+
+ /*
+ * Process an utility command. (create, destroy...) DZ -
+ * 30-8-1996
+ */
+ ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest);
+ if (!LAST_POSTQUEL_COMMAND(es))
+ CommandCounterIncrement();
+ return (TupleTableSlot *) NULL;
+ }
#endif
- feature = (LAST_POSTQUEL_COMMAND(es)) ? EXEC_RETONE : EXEC_RUN;
-
- return ExecutorRun(es->qd, es->estate, feature, 0);
+ feature = (LAST_POSTQUEL_COMMAND(es)) ? EXEC_RETONE : EXEC_RUN;
+
+ return ExecutorRun(es->qd, es->estate, feature, 0);
}
static void
-postquel_end(execution_state *es)
+postquel_end(execution_state * es)
{
#ifdef FUNC_UTIL_PATCH
- /*
- * Do nothing for utility commands. (create, destroy...) DZ - 30-8-1996
- */
- if (es->qd->operation == CMD_UTILITY) {
- return;
- }
+
+ /*
+ * Do nothing for utility commands. (create, destroy...) DZ -
+ * 30-8-1996
+ */
+ if (es->qd->operation == CMD_UTILITY)
+ {
+ return;
+ }
#endif
- ExecutorEnd(es->qd, es->estate);
+ ExecutorEnd(es->qd, es->estate);
}
static void
-postquel_sub_params(execution_state *es,
- int nargs,
- char *args[],
- bool *nullV)
+postquel_sub_params(execution_state * es,
+ int nargs,
+ char *args[],
+ bool * nullV)
{
- ParamListInfo paramLI;
- EState *estate;
-
- estate = es->estate;
- paramLI = estate->es_param_list_info;
-
- while (paramLI->kind != PARAM_INVALID) {
- if (paramLI->kind == PARAM_NUM) {
- Assert(paramLI->id <= nargs);
- paramLI->value = (Datum)args[(paramLI->id - 1)];
- paramLI->isnull = nullV[(paramLI->id - 1)];
+ ParamListInfo paramLI;
+ EState *estate;
+
+ estate = es->estate;
+ paramLI = estate->es_param_list_info;
+
+ while (paramLI->kind != PARAM_INVALID)
+ {
+ if (paramLI->kind == PARAM_NUM)
+ {
+ Assert(paramLI->id <= nargs);
+ paramLI->value = (Datum) args[(paramLI->id - 1)];
+ paramLI->isnull = nullV[(paramLI->id - 1)];
+ }
+ paramLI++;
}
- paramLI++;
- }
}
static TupleTableSlot *
copy_function_result(FunctionCachePtr fcache,
- TupleTableSlot *resultSlot)
+ TupleTableSlot * resultSlot)
{
- TupleTableSlot *funcSlot;
- TupleDesc resultTd;
- HeapTuple newTuple;
- HeapTuple oldTuple;
-
- Assert(! TupIsNull(resultSlot));
- oldTuple = resultSlot->val;
-
- funcSlot = (TupleTableSlot*)fcache->funcSlot;
-
- if (funcSlot == (TupleTableSlot*)NULL)
- return resultSlot;
-
- resultTd = resultSlot->ttc_tupleDescriptor;
- /*
- * When the funcSlot is NULL we have to initialize the funcSlot's
- * tuple descriptor.
- */
- if (TupIsNull(funcSlot)) {
- int i= 0;
- TupleDesc funcTd = funcSlot->ttc_tupleDescriptor;
-
- while (i < oldTuple->t_natts) {
- funcTd->attrs[i] =
- (AttributeTupleForm)palloc(ATTRIBUTE_TUPLE_SIZE);
- memmove(funcTd->attrs[i],
- resultTd->attrs[i],
- ATTRIBUTE_TUPLE_SIZE);
- i++;
+ TupleTableSlot *funcSlot;
+ TupleDesc resultTd;
+ HeapTuple newTuple;
+ HeapTuple oldTuple;
+
+ Assert(!TupIsNull(resultSlot));
+ oldTuple = resultSlot->val;
+
+ funcSlot = (TupleTableSlot *) fcache->funcSlot;
+
+ if (funcSlot == (TupleTableSlot *) NULL)
+ return resultSlot;
+
+ resultTd = resultSlot->ttc_tupleDescriptor;
+
+ /*
+ * When the funcSlot is NULL we have to initialize the funcSlot's
+ * tuple descriptor.
+ */
+ if (TupIsNull(funcSlot))
+ {
+ int i = 0;
+ TupleDesc funcTd = funcSlot->ttc_tupleDescriptor;
+
+ while (i < oldTuple->t_natts)
+ {
+ funcTd->attrs[i] =
+ (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+ memmove(funcTd->attrs[i],
+ resultTd->attrs[i],
+ ATTRIBUTE_TUPLE_SIZE);
+ i++;
+ }
}
- }
-
- newTuple = heap_copytuple(oldTuple);
-
- return ExecStoreTuple(newTuple,funcSlot,InvalidBuffer,true);
+
+ newTuple = heap_copytuple(oldTuple);
+
+ return ExecStoreTuple(newTuple, funcSlot, InvalidBuffer, true);
}
-static Datum
-postquel_execute(execution_state *es,
- FunctionCachePtr fcache,
- List *fTlist,
- char **args,
- bool *isNull)
+static Datum
+postquel_execute(execution_state * es,
+ FunctionCachePtr fcache,
+ List * fTlist,
+ char **args,
+ bool * isNull)
{
- TupleTableSlot *slot;
- Datum value;
+ TupleTableSlot *slot;
+ Datum value;
#ifdef INDEXSCAN_PATCH
- /*
- * It's more right place to do it (before postquel_start->ExecutorStart).
- * Now ExecutorStart->ExecInitIndexScan->ExecEvalParam works ok.
- * (But note: I HOPE we can do it here). - vadim 01/22/97
- */
- if (fcache->nargs > 0)
- postquel_sub_params(es, fcache->nargs, args, fcache->nullVect);
+
+ /*
+ * It's more right place to do it (before
+ * postquel_start->ExecutorStart). Now
+ * ExecutorStart->ExecInitIndexScan->ExecEvalParam works ok. (But
+ * note: I HOPE we can do it here). - vadim 01/22/97
+ */
+ if (fcache->nargs > 0)
+ postquel_sub_params(es, fcache->nargs, args, fcache->nullVect);
#endif
-
- if (es->status == F_EXEC_START)
+
+ if (es->status == F_EXEC_START)
{
- postquel_start(es);
- es->status = F_EXEC_RUN;
+ postquel_start(es);
+ es->status = F_EXEC_RUN;
}
#ifndef INDEXSCAN_PATCH
- if (fcache->nargs > 0)
- postquel_sub_params(es, fcache->nargs, args, fcache->nullVect);
+ if (fcache->nargs > 0)
+ postquel_sub_params(es, fcache->nargs, args, fcache->nullVect);
#endif
-
- slot = postquel_getnext(es);
-
- if (TupIsNull(slot)) {
- postquel_end(es);
- es->status = F_EXEC_DONE;
- *isNull = true;
- /*
- * If this isn't the last command for the function
- * we have to increment the command
- * counter so that subsequent commands can see changes made
- * by previous ones.
- */
- if (!LAST_POSTQUEL_COMMAND(es)) CommandCounterIncrement();
- return (Datum)NULL;
- }
-
- if (LAST_POSTQUEL_COMMAND(es)) {
- TupleTableSlot *resSlot;
-
- /*
- * Copy the result. copy_function_result is smart enough
- * to do nothing when no action is called for. This helps
- * reduce the logic and code redundancy here.
- */
- resSlot = copy_function_result(fcache, slot);
- if (fTlist != NIL) {
- HeapTuple tup;
- TargetEntry *tle = lfirst(fTlist);
-
- tup = resSlot->val;
- value = ProjectAttribute(resSlot->ttc_tupleDescriptor,
- tle,
- tup,
- isNull);
- }else {
- value = (Datum)resSlot;
- *isNull = false;
+
+ slot = postquel_getnext(es);
+
+ if (TupIsNull(slot))
+ {
+ postquel_end(es);
+ es->status = F_EXEC_DONE;
+ *isNull = true;
+
+ /*
+ * If this isn't the last command for the function we have to
+ * increment the command counter so that subsequent commands can
+ * see changes made by previous ones.
+ */
+ if (!LAST_POSTQUEL_COMMAND(es))
+ CommandCounterIncrement();
+ return (Datum) NULL;
}
-
+
+ if (LAST_POSTQUEL_COMMAND(es))
+ {
+ TupleTableSlot *resSlot;
+
+ /*
+ * Copy the result. copy_function_result is smart enough to do
+ * nothing when no action is called for. This helps reduce the
+ * logic and code redundancy here.
+ */
+ resSlot = copy_function_result(fcache, slot);
+ if (fTlist != NIL)
+ {
+ HeapTuple tup;
+ TargetEntry *tle = lfirst(fTlist);
+
+ tup = resSlot->val;
+ value = ProjectAttribute(resSlot->ttc_tupleDescriptor,
+ tle,
+ tup,
+ isNull);
+ }
+ else
+ {
+ value = (Datum) resSlot;
+ *isNull = false;
+ }
+
+ /*
+ * If this is a single valued function we have to end the function
+ * execution now.
+ */
+ if (fcache->oneResult)
+ {
+ postquel_end(es);
+ es->status = F_EXEC_DONE;
+ }
+
+ return value;
+ }
+
/*
- * If this is a single valued function we have to end the
- * function execution now.
+ * If this isn't the last command for the function, we don't return
+ * any results, but we have to increment the command counter so that
+ * subsequent commands can see changes made by previous ones.
*/
- if (fcache->oneResult) {
- postquel_end(es);
- es->status = F_EXEC_DONE;
- }
-
- return value;
- }
- /*
- * If this isn't the last command for the function, we don't
- * return any results, but we have to increment the command
- * counter so that subsequent commands can see changes made
- * by previous ones.
- */
- CommandCounterIncrement();
- return (Datum)NULL;
+ CommandCounterIncrement();
+ return (Datum) NULL;
}
Datum
-postquel_function(Func *funcNode, char **args, bool *isNull, bool *isDone)
+postquel_function(Func * funcNode, char **args, bool * isNull, bool * isDone)
{
- execution_state *es;
- Datum result = 0;
- FunctionCachePtr fcache = funcNode->func_fcache;
- CommandId savedId;
-
- /*
- * Before we start do anything we must save CurrentScanCommandId
- * to restore it before return to upper Executor. Also, we have to
- * set CurrentScanCommandId equal to CurrentCommandId.
- * - vadim 08/29/97
- */
- savedId = GetScanCommandId ();
- SetScanCommandId (GetCurrentCommandId ());
-
- es = (execution_state *) fcache->func_state;
- if (es == NULL)
+ execution_state *es;
+ Datum result = 0;
+ FunctionCachePtr fcache = funcNode->func_fcache;
+ CommandId savedId;
+
+ /*
+ * Before we start do anything we must save CurrentScanCommandId to
+ * restore it before return to upper Executor. Also, we have to set
+ * CurrentScanCommandId equal to CurrentCommandId. - vadim 08/29/97
+ */
+ savedId = GetScanCommandId();
+ SetScanCommandId(GetCurrentCommandId());
+
+ es = (execution_state *) fcache->func_state;
+ if (es == NULL)
{
- es = init_execution_state(fcache, args);
- fcache->func_state = (char *) es;
+ es = init_execution_state(fcache, args);
+ fcache->func_state = (char *) es;
}
-
- while (es && es->status == F_EXEC_DONE)
- es = es->next;
-
- Assert(es);
- /*
- * Execute each command in the function one after another until we're
- * executing the final command and get a result or we run out of
- * commands.
- */
- while (es != (execution_state *)NULL)
+
+ while (es && es->status == F_EXEC_DONE)
+ es = es->next;
+
+ Assert(es);
+
+ /*
+ * Execute each command in the function one after another until we're
+ * executing the final command and get a result or we run out of
+ * commands.
+ */
+ while (es != (execution_state *) NULL)
{
- result = postquel_execute(es,
- fcache,
- funcNode->func_tlist,
- args,
- isNull);
- if (es->status != F_EXEC_DONE)
- break;
- es = es->next;
+ result = postquel_execute(es,
+ fcache,
+ funcNode->func_tlist,
+ args,
+ isNull);
+ if (es->status != F_EXEC_DONE)
+ break;
+ es = es->next;
}
-
- /*
- * If we've gone through every command in this function, we are done.
- */
- if (es == (execution_state *)NULL)
- {
+
/*
- * Reset the execution states to start over again
+ * If we've gone through every command in this function, we are done.
*/
- es = (execution_state *)fcache->func_state;
- while (es)
+ if (es == (execution_state *) NULL)
{
- es->status = F_EXEC_START;
- es = es->next;
+
+ /*
+ * Reset the execution states to start over again
+ */
+ es = (execution_state *) fcache->func_state;
+ while (es)
+ {
+ es->status = F_EXEC_START;
+ es = es->next;
+ }
+
+ /*
+ * Let caller know we're finished.
+ */
+ *isDone = true;
+ SetScanCommandId(savedId);
+ return (fcache->oneResult) ? result : (Datum) NULL;
}
+
/*
- * Let caller know we're finished.
+ * If we got a result from a command within the function it has to be
+ * the final command. All others shouldn't be returing anything.
*/
- *isDone = true;
- SetScanCommandId (savedId);
- return (fcache->oneResult) ? result : (Datum)NULL;
- }
- /*
- * If we got a result from a command within the function it has
- * to be the final command. All others shouldn't be returing
- * anything.
- */
- Assert ( LAST_POSTQUEL_COMMAND(es) );
- *isDone = false;
-
- SetScanCommandId (savedId);
- return result;
+ Assert(LAST_POSTQUEL_COMMAND(es));
+ *isDone = false;
+
+ SetScanCommandId(savedId);
+ return result;
}
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index c6e5b269cde..ee03f6854d9 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* nodeAgg.c--
- * Routines to handle aggregate nodes.
+ * Routines to handle aggregate nodes.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* NOTE
- * The implementation of Agg node has been reworked to handle legal
- * SQL aggregates. (Do not expect POSTQUEL semantics.) -- ay 2/95
+ * The implementation of Agg node has been reworked to handle legal
+ * SQL aggregates. (Do not expect POSTQUEL semantics.) -- ay 2/95
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/executor/nodeAgg.c,v 1.13 1995/08/01 20:19:07 jolly Exp
+ * /usr/local/devel/pglite/cvs/src/backend/executor/nodeAgg.c,v 1.13 1995/08/01 20:19:07 jolly Exp
*
*-------------------------------------------------------------------------
*/
@@ -32,570 +32,625 @@
/*
* AggFuncInfo -
- * keeps the transition functions information around
+ * keeps the transition functions information around
*/
-typedef struct AggFuncInfo {
- Oid xfn1_oid;
- Oid xfn2_oid;
- Oid finalfn_oid;
- func_ptr xfn1;
- func_ptr xfn2;
- func_ptr finalfn;
- int xfn1_nargs;
- int xfn2_nargs;
- int finalfn_nargs;
-} AggFuncInfo;
+typedef struct AggFuncInfo
+{
+ Oid xfn1_oid;
+ Oid xfn2_oid;
+ Oid finalfn_oid;
+ func_ptr xfn1;
+ func_ptr xfn2;
+ func_ptr finalfn;
+ int xfn1_nargs;
+ int xfn2_nargs;
+ int finalfn_nargs;
+} AggFuncInfo;
-static Datum aggGetAttr(TupleTableSlot *tuple, Aggreg *agg, bool *isNull);
+static Datum aggGetAttr(TupleTableSlot * tuple, Aggreg * agg, bool * isNull);
/* ---------------------------------------
*
* ExecAgg -
*
- * ExecAgg receives tuples from its outer subplan and aggregates over
- * the appropriate attribute for each (unique) aggregate in the target
- * list. (The number of tuples to aggregate over depends on whether a
- * GROUP BY clause is present. It might be the number of tuples in a
- * group or all the tuples that satisfy the qualifications.) The value of
- * each aggregate is stored in the expression context for ExecProject to
- * evaluate the result tuple.
- *
- * ExecAgg evaluates each aggregate in the following steps: (initcond1,
- * initcond2 are the initial values and sfunc1, sfunc2, and finalfunc are
- * the transition functions.)
+ * ExecAgg receives tuples from its outer subplan and aggregates over
+ * the appropriate attribute for each (unique) aggregate in the target
+ * list. (The number of tuples to aggregate over depends on whether a
+ * GROUP BY clause is present. It might be the number of tuples in a
+ * group or all the tuples that satisfy the qualifications.) The value of
+ * each aggregate is stored in the expression context for ExecProject to
+ * evaluate the result tuple.
+ *
+ * ExecAgg evaluates each aggregate in the following steps: (initcond1,
+ * initcond2 are the initial values and sfunc1, sfunc2, and finalfunc are
+ * the transition functions.)
*
- * value1[i] = initcond1
- * value2[i] = initcond2
- * forall tuples do
- * value1[i] = sfunc1(aggregate_attribute, value1[i])
- * value2[i] = sfunc2(value2[i])
- * value1[i] = finalfunc(value1[i], value2[i])
+ * value1[i] = initcond1
+ * value2[i] = initcond2
+ * forall tuples do
+ * value1[i] = sfunc1(aggregate_attribute, value1[i])
+ * value2[i] = sfunc2(value2[i])
+ * value1[i] = finalfunc(value1[i], value2[i])
*
- * If the outer subplan is a Group node, ExecAgg returns as many tuples
- * as there are groups.
+ * If the outer subplan is a Group node, ExecAgg returns as many tuples
+ * as there are groups.
*
- * XXX handling of NULL doesn't work
+ * XXX handling of NULL doesn't work
*
- * OLD COMMENTS
+ * OLD COMMENTS
*
- * XXX Aggregates should probably have another option: what to do
- * with transfn2 if we hit a null value. "count" (transfn1 = null,
- * transfn2 = increment) will want to have transfn2 called; "avg"
- * (transfn1 = add, transfn2 = increment) will not. -pma 1/3/93
+ * XXX Aggregates should probably have another option: what to do
+ * with transfn2 if we hit a null value. "count" (transfn1 = null,
+ * transfn2 = increment) will want to have transfn2 called; "avg"
+ * (transfn1 = add, transfn2 = increment) will not. -pma 1/3/93
*
* ------------------------------------------
*/
TupleTableSlot *
-ExecAgg(Agg *node)
+ExecAgg(Agg * node)
{
- AggState *aggstate;
- EState *estate;
- Aggreg **aggregates;
- Plan *outerPlan;
- int i, nagg;
- Datum *value1, *value2;
- int *noInitValue;
- AggFuncInfo *aggFuncInfo;
- long nTuplesAgged = 0;
- ExprContext *econtext;
- ProjectionInfo *projInfo;
- TupleTableSlot *resultSlot;
- HeapTuple oneTuple;
- char* nulls;
- bool isDone;
- bool isNull = FALSE, isNull1 = FALSE, isNull2 = FALSE;
-
- /* ---------------------
- * get state info from node
- * ---------------------
- */
- aggstate = node->aggstate;
- if (aggstate->agg_done)
- return NULL;
-
- estate = node->plan.state;
- econtext = aggstate->csstate.cstate.cs_ExprContext;
- aggregates = node->aggs;
- nagg = node->numAgg;
-
- value1 = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_values;
- nulls = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_nulls;
-
- value2 = (Datum *)palloc(sizeof(Datum) * nagg);
- memset(value2, 0, sizeof(Datum) * nagg);
-
- aggFuncInfo = (AggFuncInfo *)palloc(sizeof(AggFuncInfo) * nagg);
- memset(aggFuncInfo, 0, sizeof(AggFuncInfo) * nagg);
-
- noInitValue = (int *)palloc(sizeof(int) * nagg);
- memset(noInitValue, 0, sizeof(noInitValue) * nagg);
-
- outerPlan = outerPlan(node);
- oneTuple = NULL;
-
- projInfo = aggstate->csstate.cstate.cs_ProjInfo;
-
- for(i = 0; i < nagg; i++) {
- Aggreg *agg;
- char *aggname;
- HeapTuple aggTuple;
- Form_pg_aggregate aggp;
- Oid xfn1_oid, xfn2_oid, finalfn_oid;
- func_ptr xfn1_ptr, xfn2_ptr, finalfn_ptr;
- int xfn1_nargs, xfn2_nargs, finalfn_nargs;
-
- agg = aggregates[i];
+ AggState *aggstate;
+ EState *estate;
+ Aggreg **aggregates;
+ Plan *outerPlan;
+ int i,
+ nagg;
+ Datum *value1,
+ *value2;
+ int *noInitValue;
+ AggFuncInfo *aggFuncInfo;
+ long nTuplesAgged = 0;
+ ExprContext *econtext;
+ ProjectionInfo *projInfo;
+ TupleTableSlot *resultSlot;
+ HeapTuple oneTuple;
+ char *nulls;
+ bool isDone;
+ bool isNull = FALSE,
+ isNull1 = FALSE,
+ isNull2 = FALSE;
/* ---------------------
- * find transfer functions of all the aggregates and initialize
- * their initial values
+ * get state info from node
* ---------------------
*/
- aggname = agg->aggname;
- aggTuple = SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(aggname),
- ObjectIdGetDatum(agg->basetype),
- 0,0);
- if (!HeapTupleIsValid(aggTuple))
- elog(WARN, "ExecAgg: cache lookup failed for aggregate \"%s\"(%s)",
- aggname,
- tname(get_id_type(agg->basetype)));
- aggp = (Form_pg_aggregate) GETSTRUCT(aggTuple);
-
- xfn1_oid = aggp->aggtransfn1;
- xfn2_oid = aggp->aggtransfn2;
- finalfn_oid = aggp->aggfinalfn;
-
- if (OidIsValid(finalfn_oid)) {
- fmgr_info(finalfn_oid, &finalfn_ptr, &finalfn_nargs);
- aggFuncInfo[i].finalfn_oid = finalfn_oid;
- aggFuncInfo[i].finalfn = finalfn_ptr;
- aggFuncInfo[i].finalfn_nargs = finalfn_nargs;
- }
+ aggstate = node->aggstate;
+ if (aggstate->agg_done)
+ return NULL;
+
+ estate = node->plan.state;
+ econtext = aggstate->csstate.cstate.cs_ExprContext;
+ aggregates = node->aggs;
+ nagg = node->numAgg;
+
+ value1 = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_values;
+ nulls = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_nulls;
+
+ value2 = (Datum *) palloc(sizeof(Datum) * nagg);
+ memset(value2, 0, sizeof(Datum) * nagg);
+
+ aggFuncInfo = (AggFuncInfo *) palloc(sizeof(AggFuncInfo) * nagg);
+ memset(aggFuncInfo, 0, sizeof(AggFuncInfo) * nagg);
+
+ noInitValue = (int *) palloc(sizeof(int) * nagg);
+ memset(noInitValue, 0, sizeof(noInitValue) * nagg);
+
+ outerPlan = outerPlan(node);
+ oneTuple = NULL;
+
+ projInfo = aggstate->csstate.cstate.cs_ProjInfo;
+
+ for (i = 0; i < nagg; i++)
+ {
+ Aggreg *agg;
+ char *aggname;
+ HeapTuple aggTuple;
+ Form_pg_aggregate aggp;
+ Oid xfn1_oid,
+ xfn2_oid,
+ finalfn_oid;
+ func_ptr xfn1_ptr,
+ xfn2_ptr,
+ finalfn_ptr;
+ int xfn1_nargs,
+ xfn2_nargs,
+ finalfn_nargs;
+
+ agg = aggregates[i];
+
+ /* ---------------------
+ * find transfer functions of all the aggregates and initialize
+ * their initial values
+ * ---------------------
+ */
+ aggname = agg->aggname;
+ aggTuple = SearchSysCacheTuple(AGGNAME,
+ PointerGetDatum(aggname),
+ ObjectIdGetDatum(agg->basetype),
+ 0, 0);
+ if (!HeapTupleIsValid(aggTuple))
+ elog(WARN, "ExecAgg: cache lookup failed for aggregate \"%s\"(%s)",
+ aggname,
+ tname(get_id_type(agg->basetype)));
+ aggp = (Form_pg_aggregate) GETSTRUCT(aggTuple);
+
+ xfn1_oid = aggp->aggtransfn1;
+ xfn2_oid = aggp->aggtransfn2;
+ finalfn_oid = aggp->aggfinalfn;
+
+ if (OidIsValid(finalfn_oid))
+ {
+ fmgr_info(finalfn_oid, &finalfn_ptr, &finalfn_nargs);
+ aggFuncInfo[i].finalfn_oid = finalfn_oid;
+ aggFuncInfo[i].finalfn = finalfn_ptr;
+ aggFuncInfo[i].finalfn_nargs = finalfn_nargs;
+ }
- if (OidIsValid(xfn2_oid)) {
- fmgr_info(xfn2_oid, &xfn2_ptr, &xfn2_nargs);
- aggFuncInfo[i].xfn2_oid = xfn2_oid;
- aggFuncInfo[i].xfn2 = xfn2_ptr;
- aggFuncInfo[i].xfn2_nargs = xfn2_nargs;
- value2[i] = (Datum)AggNameGetInitVal((char*)aggname,
- aggp->aggbasetype,
- 2,
- &isNull2);
- /* ------------------------------------------
- * If there is a second transition function, its initial
- * value must exist -- as it does not depend on data values,
- * we have no other way of determining an initial value.
- * ------------------------------------------
- */
- if (isNull2)
- elog(WARN, "ExecAgg: agginitval2 is null");
- }
+ if (OidIsValid(xfn2_oid))
+ {
+ fmgr_info(xfn2_oid, &xfn2_ptr, &xfn2_nargs);
+ aggFuncInfo[i].xfn2_oid = xfn2_oid;
+ aggFuncInfo[i].xfn2 = xfn2_ptr;
+ aggFuncInfo[i].xfn2_nargs = xfn2_nargs;
+ value2[i] = (Datum) AggNameGetInitVal((char *) aggname,
+ aggp->aggbasetype,
+ 2,
+ &isNull2);
+ /* ------------------------------------------
+ * If there is a second transition function, its initial
+ * value must exist -- as it does not depend on data values,
+ * we have no other way of determining an initial value.
+ * ------------------------------------------
+ */
+ if (isNull2)
+ elog(WARN, "ExecAgg: agginitval2 is null");
+ }
- if (OidIsValid(xfn1_oid)) {
- fmgr_info(xfn1_oid, &xfn1_ptr, &xfn1_nargs);
- aggFuncInfo[i].xfn1_oid = xfn1_oid;
- aggFuncInfo[i].xfn1 = xfn1_ptr;
- aggFuncInfo[i].xfn1_nargs = xfn1_nargs;
- value1[i] = (Datum)AggNameGetInitVal((char*)aggname,
- aggp->aggbasetype,
- 1,
- &isNull1);
-
- /* ------------------------------------------
- * If the initial value for the first transition function
- * doesn't exist in the pg_aggregate table then we let
- * the first value returned from the outer procNode become
- * the initial value. (This is useful for aggregates like
- * max{} and min{}.)
- * ------------------------------------------
- */
- if (isNull1) {
- noInitValue[i] = 1;
- nulls[i] = 1;
- }
- }
- }
-
- /* ----------------
- * for each tuple from the the outer plan, apply all the aggregates
- * ----------------
- */
- for (;;) {
- HeapTuple outerTuple = NULL;
- TupleTableSlot *outerslot;
-
- isNull = isNull1 = isNull2 = 0;
- outerslot = ExecProcNode(outerPlan, (Plan*)node);
- if (outerslot) outerTuple = outerslot->val;
- if (!HeapTupleIsValid(outerTuple)) {
- /* when the outerplan doesn't return a single tuple,
- create a dummy heaptuple anyway
- because we still need to return a valid aggregate value.
- The value returned will be the initial values of the
- transition functions */
- if (nTuplesAgged == 0) {
- TupleDesc tupType;
- Datum *tupValue;
- char* null_array;
-
- tupType = aggstate->csstate.css_ScanTupleSlot->ttc_tupleDescriptor;
- tupValue = projInfo->pi_tupValue;
-
- /* initially, set all the values to NULL */
- null_array = malloc(tupType->natts);
- for (i=0;i<tupType->natts;i++)
- null_array[i] = 'n';
- oneTuple = heap_formtuple(tupType, tupValue, null_array);
- free(null_array);
- }
- break;
+ if (OidIsValid(xfn1_oid))
+ {
+ fmgr_info(xfn1_oid, &xfn1_ptr, &xfn1_nargs);
+ aggFuncInfo[i].xfn1_oid = xfn1_oid;
+ aggFuncInfo[i].xfn1 = xfn1_ptr;
+ aggFuncInfo[i].xfn1_nargs = xfn1_nargs;
+ value1[i] = (Datum) AggNameGetInitVal((char *) aggname,
+ aggp->aggbasetype,
+ 1,
+ &isNull1);
+
+ /* ------------------------------------------
+ * If the initial value for the first transition function
+ * doesn't exist in the pg_aggregate table then we let
+ * the first value returned from the outer procNode become
+ * the initial value. (This is useful for aggregates like
+ * max{} and min{}.)
+ * ------------------------------------------
+ */
+ if (isNull1)
+ {
+ noInitValue[i] = 1;
+ nulls[i] = 1;
+ }
+ }
}
- for(i = 0; i < nagg; i++) {
- AttrNumber attnum;
- int2 attlen;
- Datum newVal = (Datum) NULL;
- AggFuncInfo *aggfns = &aggFuncInfo[i];
- Datum args[2];
- Node *tagnode = NULL;
-
- switch(nodeTag(aggregates[i]->target))
- {
- case T_Var:
- tagnode = NULL;
- newVal = aggGetAttr(outerslot,
- aggregates[i],
- &isNull);
- break;
- case T_Expr:
- tagnode = ((Expr*)aggregates[i]->target)->oper;
- econtext->ecxt_scantuple = outerslot;
- newVal = ExecEvalExpr (aggregates[i]->target, econtext,
- &isNull, NULL);
+ /* ----------------
+ * for each tuple from the the outer plan, apply all the aggregates
+ * ----------------
+ */
+ for (;;)
+ {
+ HeapTuple outerTuple = NULL;
+ TupleTableSlot *outerslot;
+
+ isNull = isNull1 = isNull2 = 0;
+ outerslot = ExecProcNode(outerPlan, (Plan *) node);
+ if (outerslot)
+ outerTuple = outerslot->val;
+ if (!HeapTupleIsValid(outerTuple))
+ {
+
+ /*
+ * when the outerplan doesn't return a single tuple, create a
+ * dummy heaptuple anyway because we still need to return a
+ * valid aggregate value. The value returned will be the
+ * initial values of the transition functions
+ */
+ if (nTuplesAgged == 0)
+ {
+ TupleDesc tupType;
+ Datum *tupValue;
+ char *null_array;
+
+ tupType = aggstate->csstate.css_ScanTupleSlot->ttc_tupleDescriptor;
+ tupValue = projInfo->pi_tupValue;
+
+ /* initially, set all the values to NULL */
+ null_array = malloc(tupType->natts);
+ for (i = 0; i < tupType->natts; i++)
+ null_array[i] = 'n';
+ oneTuple = heap_formtuple(tupType, tupValue, null_array);
+ free(null_array);
+ }
break;
- default:
- elog(WARN, "ExecAgg: Bad Agg->Target for Agg %d", i);
- }
-
- if (isNull)
- continue; /* ignore this tuple for this agg */
-
- if (aggfns->xfn1) {
- if (noInitValue[i]) {
- int byVal;
-
- /*
- * value1 and value2 has not been initialized. This
- * is the first non-NULL value. We use it as the
- * initial value.
- */
- /* but we can't just use it straight, we have
- to make a copy of it since the tuple from which
- it came will be freed on the next iteration
- of the scan */
- if ( tagnode != NULL )
- {
- FunctionCachePtr fcache_ptr;
-
- if ( nodeTag(tagnode) == T_Func )
- fcache_ptr = ((Func*)tagnode)->func_fcache;
- else
- fcache_ptr = ((Oper*)tagnode)->op_fcache;
- attlen = fcache_ptr->typlen;
- byVal = fcache_ptr->typbyval;
- }
- else
- {
- attnum = ((Var*)aggregates[i]->target)->varattno;
- attlen = outerslot->ttc_tupleDescriptor->attrs[attnum-1]->attlen;
- byVal = outerslot->ttc_tupleDescriptor->attrs[attnum-1]->attbyval;
- }
- if (attlen == -1) {
- /* variable length */
- attlen = VARSIZE((struct varlena*) newVal);
- }
- value1[i] = (Datum)palloc(attlen);
- if ( byVal )
- value1[i] = newVal;
- else
- memmove((char*)(value1[i]), (char*)newVal, attlen);
- /* value1[i] = newVal; */
- noInitValue[i] = 0;
- nulls[i] = 0;
- } else {
- /*
- * apply the transition functions.
- */
- args[0] = value1[i];
- args[1] = newVal;
- value1[i] =
- (Datum)fmgr_c(aggfns->xfn1, aggfns->xfn1_oid,
- aggfns->xfn1_nargs, (FmgrValues *)args,
- &isNull1);
- Assert(!isNull1);
}
- }
-
- if (aggfns->xfn2) {
- Datum xfn2_val = value2[i];
-
- value2[i] =
- (Datum)fmgr_c(aggfns->xfn2, aggfns->xfn2_oid,
- aggfns->xfn2_nargs,
- (FmgrValues *)&xfn2_val, &isNull2);
- Assert(!isNull2);
- }
+
+ for (i = 0; i < nagg; i++)
+ {
+ AttrNumber attnum;
+ int2 attlen;
+ Datum newVal = (Datum) NULL;
+ AggFuncInfo *aggfns = &aggFuncInfo[i];
+ Datum args[2];
+ Node *tagnode = NULL;
+
+ switch (nodeTag(aggregates[i]->target))
+ {
+ case T_Var:
+ tagnode = NULL;
+ newVal = aggGetAttr(outerslot,
+ aggregates[i],
+ &isNull);
+ break;
+ case T_Expr:
+ tagnode = ((Expr *) aggregates[i]->target)->oper;
+ econtext->ecxt_scantuple = outerslot;
+ newVal = ExecEvalExpr(aggregates[i]->target, econtext,
+ &isNull, NULL);
+ break;
+ default:
+ elog(WARN, "ExecAgg: Bad Agg->Target for Agg %d", i);
+ }
+
+ if (isNull)
+ continue; /* ignore this tuple for this agg */
+
+ if (aggfns->xfn1)
+ {
+ if (noInitValue[i])
+ {
+ int byVal;
+
+ /*
+ * value1 and value2 has not been initialized. This is
+ * the first non-NULL value. We use it as the initial
+ * value.
+ */
+
+ /*
+ * but we can't just use it straight, we have to make
+ * a copy of it since the tuple from which it came
+ * will be freed on the next iteration of the scan
+ */
+ if (tagnode != NULL)
+ {
+ FunctionCachePtr fcache_ptr;
+
+ if (nodeTag(tagnode) == T_Func)
+ fcache_ptr = ((Func *) tagnode)->func_fcache;
+ else
+ fcache_ptr = ((Oper *) tagnode)->op_fcache;
+ attlen = fcache_ptr->typlen;
+ byVal = fcache_ptr->typbyval;
+ }
+ else
+ {
+ attnum = ((Var *) aggregates[i]->target)->varattno;
+ attlen = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attlen;
+ byVal = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attbyval;
+ }
+ if (attlen == -1)
+ {
+ /* variable length */
+ attlen = VARSIZE((struct varlena *) newVal);
+ }
+ value1[i] = (Datum) palloc(attlen);
+ if (byVal)
+ value1[i] = newVal;
+ else
+ memmove((char *) (value1[i]), (char *) newVal, attlen);
+ /* value1[i] = newVal; */
+ noInitValue[i] = 0;
+ nulls[i] = 0;
+ }
+ else
+ {
+
+ /*
+ * apply the transition functions.
+ */
+ args[0] = value1[i];
+ args[1] = newVal;
+ value1[i] =
+ (Datum) fmgr_c(aggfns->xfn1, aggfns->xfn1_oid,
+ aggfns->xfn1_nargs, (FmgrValues *) args,
+ &isNull1);
+ Assert(!isNull1);
+ }
+ }
+
+ if (aggfns->xfn2)
+ {
+ Datum xfn2_val = value2[i];
+
+ value2[i] =
+ (Datum) fmgr_c(aggfns->xfn2, aggfns->xfn2_oid,
+ aggfns->xfn2_nargs,
+ (FmgrValues *) & xfn2_val, &isNull2);
+ Assert(!isNull2);
+ }
+ }
+
+ /*
+ * keep this for the projection (we only need one of these - all
+ * the tuples we aggregate over share the same group column)
+ */
+ if (!oneTuple)
+ {
+ oneTuple = heap_copytuple(outerslot->val);
+ }
+
+ nTuplesAgged++;
+ }
+
+ /* --------------
+ * finalize the aggregate (if necessary), and get the resultant value
+ * --------------
+ */
+ for (i = 0; i < nagg; i++)
+ {
+ char *args[2];
+ AggFuncInfo *aggfns = &aggFuncInfo[i];
+
+ if (noInitValue[i])
+ {
+
+ /*
+ * No values found for this agg; return current state. This
+ * seems to fix behavior for avg() aggregate. -tgl 12/96
+ */
+ }
+ else if (aggfns->finalfn && nTuplesAgged > 0)
+ {
+ if (aggfns->finalfn_nargs > 1)
+ {
+ args[0] = (char *) value1[i];
+ args[1] = (char *) value2[i];
+ }
+ else if (aggfns->xfn1)
+ {
+ args[0] = (char *) value1[i];
+ }
+ else if (aggfns->xfn2)
+ {
+ args[0] = (char *) value2[i];
+ }
+ else
+ elog(WARN, "ExecAgg: no valid transition functions??");
+ value1[i] =
+ (Datum) fmgr_c(aggfns->finalfn, aggfns->finalfn_oid,
+ aggfns->finalfn_nargs, (FmgrValues *) args,
+ &(nulls[i]));
+ }
+ else if (aggfns->xfn1)
+ {
+
+ /*
+ * value in the right place, ignore. (If you remove this case,
+ * fix the else part. -ay 2/95)
+ */
+ }
+ else if (aggfns->xfn2)
+ {
+ value1[i] = value2[i];
+ }
+ else
+ elog(WARN, "ExecAgg: no valid transition functions??");
}
/*
- * keep this for the projection (we only need one of these -
- * all the tuples we aggregate over share the same group column)
+ * whether the aggregation is done depends on whether we are doing
+ * aggregation over groups or the entire table
*/
- if (!oneTuple) {
- oneTuple = heap_copytuple(outerslot->val);
+ if (nodeTag(outerPlan) == T_Group)
+ {
+ /* aggregation over groups */
+ aggstate->agg_done = ((Group *) outerPlan)->grpstate->grp_done;
+ }
+ else
+ {
+ aggstate->agg_done = TRUE;
}
- nTuplesAgged++;
- }
-
- /* --------------
- * finalize the aggregate (if necessary), and get the resultant value
- * --------------
- */
- for(i = 0; i < nagg; i++) {
- char *args[2];
- AggFuncInfo *aggfns = &aggFuncInfo[i];
-
- if (noInitValue[i]) {
- /*
- * No values found for this agg; return current state.
- * This seems to fix behavior for avg() aggregate. -tgl 12/96
- */
- } else if (aggfns->finalfn && nTuplesAgged > 0) {
- if (aggfns->finalfn_nargs > 1) {
- args[0] = (char*)value1[i];
- args[1] = (char*)value2[i];
- } else if (aggfns->xfn1) {
- args[0] = (char*)value1[i];
- } else if (aggfns->xfn2) {
- args[0] = (char*)value2[i];
- } else
- elog(WARN, "ExecAgg: no valid transition functions??");
- value1[i] =
- (Datum)fmgr_c(aggfns->finalfn, aggfns->finalfn_oid,
- aggfns->finalfn_nargs, (FmgrValues *) args,
- &(nulls[i]));
- } else if (aggfns->xfn1) {
- /*
- * value in the right place, ignore. (If you remove this
- * case, fix the else part. -ay 2/95)
- */
- } else if (aggfns->xfn2) {
- value1[i] = value2[i];
- } else
- elog(WARN, "ExecAgg: no valid transition functions??");
- }
-
- /*
- * whether the aggregation is done depends on whether we are doing
- * aggregation over groups or the entire table
- */
- if (nodeTag(outerPlan)==T_Group) {
- /* aggregation over groups */
- aggstate->agg_done = ((Group*)outerPlan)->grpstate->grp_done;
- } else {
- aggstate->agg_done = TRUE;
- }
-
- /* ----------------
- * form a projection tuple, store it in the result tuple
- * slot and return it.
- * ----------------
- */
- ExecStoreTuple(oneTuple,
- aggstate->csstate.css_ScanTupleSlot,
- InvalidBuffer,
- false);
- econtext->ecxt_scantuple = aggstate->csstate.css_ScanTupleSlot;
- resultSlot = ExecProject(projInfo, &isDone);
-
- if (oneTuple)
- pfree(oneTuple);
-
- return resultSlot;
+ /* ----------------
+ * form a projection tuple, store it in the result tuple
+ * slot and return it.
+ * ----------------
+ */
+ ExecStoreTuple(oneTuple,
+ aggstate->csstate.css_ScanTupleSlot,
+ InvalidBuffer,
+ false);
+ econtext->ecxt_scantuple = aggstate->csstate.css_ScanTupleSlot;
+ resultSlot = ExecProject(projInfo, &isDone);
+
+ if (oneTuple)
+ pfree(oneTuple);
+
+ return resultSlot;
}
/* -----------------
* ExecInitAgg
*
- * Creates the run-time information for the agg node produced by the
- * planner and initializes its outer subtree
+ * Creates the run-time information for the agg node produced by the
+ * planner and initializes its outer subtree
* -----------------
*/
bool
-ExecInitAgg(Agg *node, EState *estate, Plan *parent)
+ExecInitAgg(Agg * node, EState * estate, Plan * parent)
{
- AggState *aggstate;
- Plan *outerPlan;
- ExprContext *econtext;
-
- /*
- * assign the node's execution state
- */
- node->plan.state = estate;
-
- /*
- * create state structure
- */
- aggstate = makeNode(AggState);
- node->aggstate = aggstate;
- aggstate->agg_done = FALSE;
-
- /*
- * assign node's base id and create expression context
- */
- ExecAssignNodeBaseInfo(estate, &aggstate->csstate.cstate,
- (Plan*) parent);
- ExecAssignExprContext(estate, &aggstate->csstate.cstate);
-
+ AggState *aggstate;
+ Plan *outerPlan;
+ ExprContext *econtext;
+
+ /*
+ * assign the node's execution state
+ */
+ node->plan.state = estate;
+
+ /*
+ * create state structure
+ */
+ aggstate = makeNode(AggState);
+ node->aggstate = aggstate;
+ aggstate->agg_done = FALSE;
+
+ /*
+ * assign node's base id and create expression context
+ */
+ ExecAssignNodeBaseInfo(estate, &aggstate->csstate.cstate,
+ (Plan *) parent);
+ ExecAssignExprContext(estate, &aggstate->csstate.cstate);
+
#define AGG_NSLOTS 2
- /*
- * tuple table initialization
- */
- ExecInitScanTupleSlot(estate, &aggstate->csstate);
- ExecInitResultTupleSlot(estate, &aggstate->csstate.cstate);
-
- econtext = aggstate->csstate.cstate.cs_ExprContext;
- econtext->ecxt_values =
- (Datum *)palloc(sizeof(Datum) * node->numAgg);
- memset(econtext->ecxt_values, 0, sizeof(Datum) * node->numAgg);
- econtext->ecxt_nulls = (char *)palloc(node->numAgg);
- memset(econtext->ecxt_nulls, 0, node->numAgg);
-
- /*
- * initializes child nodes
- */
- outerPlan = outerPlan(node);
- ExecInitNode(outerPlan, estate, (Plan *)node);
-
- /* ----------------
- * initialize tuple type.
- * ----------------
- */
- ExecAssignScanTypeFromOuterPlan((Plan *) node, &aggstate->csstate);
-
- /*
- * Initialize tuple type for both result and scan.
- * This node does no projection
- */
- ExecAssignResultTypeFromTL((Plan*) node, &aggstate->csstate.cstate);
- ExecAssignProjectionInfo((Plan*)node, &aggstate->csstate.cstate);
-
- return TRUE;
+
+ /*
+ * tuple table initialization
+ */
+ ExecInitScanTupleSlot(estate, &aggstate->csstate);
+ ExecInitResultTupleSlot(estate, &aggstate->csstate.cstate);
+
+ econtext = aggstate->csstate.cstate.cs_ExprContext;
+ econtext->ecxt_values =
+ (Datum *) palloc(sizeof(Datum) * node->numAgg);
+ memset(econtext->ecxt_values, 0, sizeof(Datum) * node->numAgg);
+ econtext->ecxt_nulls = (char *) palloc(node->numAgg);
+ memset(econtext->ecxt_nulls, 0, node->numAgg);
+
+ /*
+ * initializes child nodes
+ */
+ outerPlan = outerPlan(node);
+ ExecInitNode(outerPlan, estate, (Plan *) node);
+
+ /* ----------------
+ * initialize tuple type.
+ * ----------------
+ */
+ ExecAssignScanTypeFromOuterPlan((Plan *) node, &aggstate->csstate);
+
+ /*
+ * Initialize tuple type for both result and scan. This node does no
+ * projection
+ */
+ ExecAssignResultTypeFromTL((Plan *) node, &aggstate->csstate.cstate);
+ ExecAssignProjectionInfo((Plan *) node, &aggstate->csstate.cstate);
+
+ return TRUE;
}
int
-ExecCountSlotsAgg(Agg *node)
+ExecCountSlotsAgg(Agg * node)
{
- return ExecCountSlotsNode(outerPlan(node)) +
+ return ExecCountSlotsNode(outerPlan(node)) +
ExecCountSlotsNode(innerPlan(node)) +
- AGG_NSLOTS;
+ AGG_NSLOTS;
}
/* ------------------------
- * ExecEndAgg(node)
+ * ExecEndAgg(node)
*
* -----------------------
*/
void
-ExecEndAgg(Agg *node)
+ExecEndAgg(Agg * node)
{
- AggState *aggstate;
- Plan *outerPlan;
+ AggState *aggstate;
+ Plan *outerPlan;
- aggstate = node->aggstate;
+ aggstate = node->aggstate;
- ExecFreeProjectionInfo(&aggstate->csstate.cstate);
+ ExecFreeProjectionInfo(&aggstate->csstate.cstate);
- outerPlan = outerPlan(node);
- ExecEndNode(outerPlan, (Plan*)node);
-
- /* clean up tuple table */
- ExecClearTuple(aggstate->csstate.css_ScanTupleSlot);
+ outerPlan = outerPlan(node);
+ ExecEndNode(outerPlan, (Plan *) node);
+
+ /* clean up tuple table */
+ ExecClearTuple(aggstate->csstate.css_ScanTupleSlot);
}
/*****************************************************************************
- * Support Routines
+ * Support Routines
*****************************************************************************/
/*
* aggGetAttr -
- * get the attribute (specified in the Var node in agg) to aggregate
- * over from the tuple
+ * get the attribute (specified in the Var node in agg) to aggregate
+ * over from the tuple
*/
-static Datum
-aggGetAttr(TupleTableSlot *slot,
- Aggreg *agg,
- bool *isNull)
+static Datum
+aggGetAttr(TupleTableSlot * slot,
+ Aggreg * agg,
+ bool * isNull)
{
- Datum result;
- AttrNumber attnum;
- HeapTuple heapTuple;
- TupleDesc tuple_type;
- Buffer buffer;
-
- /* ----------------
- * extract tuple information from the slot
- * ----------------
- */
- heapTuple = slot->val;
- tuple_type = slot->ttc_tupleDescriptor;
- buffer = slot->ttc_buffer;
-
- attnum = ((Var*)agg->target)->varattno;
-
- /*
- * If the attribute number is invalid, then we are supposed to
- * return the entire tuple, we give back a whole slot so that
- * callers know what the tuple looks like.
- */
- if (attnum == InvalidAttrNumber) {
- TupleTableSlot *tempSlot;
- TupleDesc td;
- HeapTuple tup;
-
- tempSlot = makeNode(TupleTableSlot);
- tempSlot->ttc_shouldFree = false;
- tempSlot->ttc_descIsNew = true;
- tempSlot->ttc_tupleDescriptor = (TupleDesc)NULL,
- tempSlot->ttc_buffer = InvalidBuffer;
- tempSlot->ttc_whichplan = -1;
-
- tup = heap_copytuple(slot->val);
- td = CreateTupleDescCopy(slot->ttc_tupleDescriptor);
-
- ExecSetSlotDescriptor(tempSlot, td);
-
- ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
- return (Datum) tempSlot;
- }
-
- result = (Datum)
- heap_getattr(heapTuple, /* tuple containing attribute */
- buffer, /* buffer associated with tuple */
- attnum, /* attribute number of desired attribute */
- tuple_type, /* tuple descriptor of tuple */
- isNull); /* return: is attribute null? */
-
- /* ----------------
- * return null if att is null
- * ----------------
- */
- if (*isNull)
- return (Datum) NULL;
-
- return result;
+ Datum result;
+ AttrNumber attnum;
+ HeapTuple heapTuple;
+ TupleDesc tuple_type;
+ Buffer buffer;
+
+ /* ----------------
+ * extract tuple information from the slot
+ * ----------------
+ */
+ heapTuple = slot->val;
+ tuple_type = slot->ttc_tupleDescriptor;
+ buffer = slot->ttc_buffer;
+
+ attnum = ((Var *) agg->target)->varattno;
+
+ /*
+ * If the attribute number is invalid, then we are supposed to return
+ * the entire tuple, we give back a whole slot so that callers know
+ * what the tuple looks like.
+ */
+ if (attnum == InvalidAttrNumber)
+ {
+ TupleTableSlot *tempSlot;
+ TupleDesc td;
+ HeapTuple tup;
+
+ tempSlot = makeNode(TupleTableSlot);
+ tempSlot->ttc_shouldFree = false;
+ tempSlot->ttc_descIsNew = true;
+ tempSlot->ttc_tupleDescriptor = (TupleDesc) NULL,
+ tempSlot->ttc_buffer = InvalidBuffer;
+ tempSlot->ttc_whichplan = -1;
+
+ tup = heap_copytuple(slot->val);
+ td = CreateTupleDescCopy(slot->ttc_tupleDescriptor);
+
+ ExecSetSlotDescriptor(tempSlot, td);
+
+ ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
+ return (Datum) tempSlot;
+ }
+
+ result = (Datum)
+ heap_getattr(heapTuple, /* tuple containing attribute */
+ buffer, /* buffer associated with tuple */
+ attnum, /* attribute number of desired attribute */
+ tuple_type,/* tuple descriptor of tuple */
+ isNull); /* return: is attribute null? */
+
+ /* ----------------
+ * return null if att is null
+ * ----------------
+ */
+ if (*isNull)
+ return (Datum) NULL;
+
+ return result;
}
diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c
index 7abc6d91744..043ad5d9743 100644
--- a/src/backend/executor/nodeAppend.c
+++ b/src/backend/executor/nodeAppend.c
@@ -1,56 +1,56 @@
/*-------------------------------------------------------------------------
*
* nodeAppend.c--
- * routines to handle append nodes.
+ * routines to handle append nodes.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.5 1997/08/19 21:31:07 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.6 1997/09/07 04:41:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* INTERFACE ROUTINES
- * ExecInitAppend - initialize the append node
- * ExecProcAppend - retrieve the next tuple from the node
- * ExecEndAppend - shut down the append node
+ * ExecInitAppend - initialize the append node
+ * ExecProcAppend - retrieve the next tuple from the node
+ * ExecEndAppend - shut down the append node
*
- * NOTES
- * Each append node contains a list of one or more subplans which
- * must be iteratively processed (forwards or backwards).
- * Tuples are retrieved by executing the 'whichplan'th subplan
- * until the subplan stops returning tuples, at which point that
- * plan is shut down and the next started up.
+ * NOTES
+ * Each append node contains a list of one or more subplans which
+ * must be iteratively processed (forwards or backwards).
+ * Tuples are retrieved by executing the 'whichplan'th subplan
+ * until the subplan stops returning tuples, at which point that
+ * plan is shut down and the next started up.
*
- * Append nodes don't make use of their left and right
- * subtrees, rather they maintain a list of subplans so
- * a typical append node looks like this in the plan tree:
+ * Append nodes don't make use of their left and right
+ * subtrees, rather they maintain a list of subplans so
+ * a typical append node looks like this in the plan tree:
*
- * ...
- * /
- * Append -------+------+------+--- nil
- * / \ | | |
- * nil nil ... ... ...
- * subplans
+ * ...
+ * /
+ * Append -------+------+------+--- nil
+ * / \ | | |
+ * nil nil ... ... ...
+ * subplans
*
- * Append nodes are currently used to support inheritance
- * queries, where several relations need to be scanned.
- * For example, in our standard person/student/employee/student-emp
- * example, where student and employee inherit from person
- * and student-emp inherits from student and employee, the
- * query:
+ * Append nodes are currently used to support inheritance
+ * queries, where several relations need to be scanned.
+ * For example, in our standard person/student/employee/student-emp
+ * example, where student and employee inherit from person
+ * and student-emp inherits from student and employee, the
+ * query:
*
- * retrieve (e.name) from e in person*
+ * retrieve (e.name) from e in person*
*
- * generates the plan:
+ * generates the plan:
*
- * |
- * Append -------+-------+--------+--------+
- * / \ | | | |
- * nil nil Scan Scan Scan Scan
- * | | | |
- * person employee student student-emp
+ * |
+ * Append -------+-------+--------+--------+
+ * / \ | | | |
+ * nil nil Scan Scan Scan Scan
+ * | | | |
+ * person employee student student-emp
*/
#include "postgres.h"
@@ -62,429 +62,451 @@
#include "executor/nodeIndexscan.h"
#include "utils/palloc.h"
#include "utils/mcxt.h"
-#include "parser/parsetree.h" /* for rt_store() macro */
+#include "parser/parsetree.h" /* for rt_store() macro */
-static bool exec_append_initialize_next(Append *node);
+static bool exec_append_initialize_next(Append * node);
/* ----------------------------------------------------------------
- * exec-append-initialize-next
- *
- * Sets up the append node state (i.e. the append state node)
- * for the "next" scan.
- *
- * Returns t iff there is a "next" scan to process.
+ * exec-append-initialize-next
+ *
+ * Sets up the append node state (i.e. the append state node)
+ * for the "next" scan.
+ *
+ * Returns t iff there is a "next" scan to process.
* ----------------------------------------------------------------
*/
-static bool
-exec_append_initialize_next(Append *node)
+static bool
+exec_append_initialize_next(Append * node)
{
- EState *estate;
- AppendState *unionstate;
- TupleTableSlot *result_slot;
- List *rangeTable;
-
- int whichplan;
- int nplans;
- List *rtentries;
- ResTarget *rtentry;
-
- Index unionrelid;
-
- /* ----------------
- * get information from the append node
- * ----------------
- */
- estate = node->plan.state;
- unionstate = node->unionstate;
- result_slot = unionstate->cstate.cs_ResultTupleSlot;
- rangeTable = estate->es_range_table;
-
- whichplan = unionstate->as_whichplan;
- nplans = unionstate->as_nplans;
- rtentries = node->unionrtentries;
-
- if (whichplan < 0) {
- /* ----------------
- * if scanning in reverse, we start at
- * the last scan in the list and then
- * proceed back to the first.. in any case
- * we inform ExecProcAppend that we are
- * at the end of the line by returning FALSE
- * ----------------
- */
- unionstate->as_whichplan = 0;
- return FALSE;
-
- } else if (whichplan >= nplans) {
- /* ----------------
- * as above, end the scan if we go beyond
- * the last scan in our list..
- * ----------------
- */
- unionstate->as_whichplan = nplans - 1;
- return FALSE;
-
- } else {
- /* ----------------
- * initialize the scan
- * (and update the range table appropriately)
- * (doesn't this leave the range table hosed for anybody upstream
- * of the Append node??? - jolly )
- * ----------------
- */
- if (node->unionrelid > 0) {
- rtentry = nth(whichplan, rtentries);
- if (rtentry == NULL)
- elog(DEBUG, "exec_append_initialize_next: rtentry is nil");
-
- unionrelid = node->unionrelid;
-
- rt_store(unionrelid, rangeTable, rtentry);
-
- if (unionstate->as_junkFilter_list) {
- estate->es_junkFilter =
- (JunkFilter*)nth(whichplan,
- unionstate->as_junkFilter_list);
- }
- if (unionstate->as_result_relation_info_list) {
- estate->es_result_relation_info =
- (RelationInfo*) nth(whichplan,
- unionstate->as_result_relation_info_list);
- }
- result_slot->ttc_whichplan = whichplan;
+ EState *estate;
+ AppendState *unionstate;
+ TupleTableSlot *result_slot;
+ List *rangeTable;
+
+ int whichplan;
+ int nplans;
+ List *rtentries;
+ ResTarget *rtentry;
+
+ Index unionrelid;
+
+ /* ----------------
+ * get information from the append node
+ * ----------------
+ */
+ estate = node->plan.state;
+ unionstate = node->unionstate;
+ result_slot = unionstate->cstate.cs_ResultTupleSlot;
+ rangeTable = estate->es_range_table;
+
+ whichplan = unionstate->as_whichplan;
+ nplans = unionstate->as_nplans;
+ rtentries = node->unionrtentries;
+
+ if (whichplan < 0)
+ {
+ /* ----------------
+ * if scanning in reverse, we start at
+ * the last scan in the list and then
+ * proceed back to the first.. in any case
+ * we inform ExecProcAppend that we are
+ * at the end of the line by returning FALSE
+ * ----------------
+ */
+ unionstate->as_whichplan = 0;
+ return FALSE;
+
+ }
+ else if (whichplan >= nplans)
+ {
+ /* ----------------
+ * as above, end the scan if we go beyond
+ * the last scan in our list..
+ * ----------------
+ */
+ unionstate->as_whichplan = nplans - 1;
+ return FALSE;
+
+ }
+ else
+ {
+ /* ----------------
+ * initialize the scan
+ * (and update the range table appropriately)
+ * (doesn't this leave the range table hosed for anybody upstream
+ * of the Append node??? - jolly )
+ * ----------------
+ */
+ if (node->unionrelid > 0)
+ {
+ rtentry = nth(whichplan, rtentries);
+ if (rtentry == NULL)
+ elog(DEBUG, "exec_append_initialize_next: rtentry is nil");
+
+ unionrelid = node->unionrelid;
+
+ rt_store(unionrelid, rangeTable, rtentry);
+
+ if (unionstate->as_junkFilter_list)
+ {
+ estate->es_junkFilter =
+ (JunkFilter *) nth(whichplan,
+ unionstate->as_junkFilter_list);
+ }
+ if (unionstate->as_result_relation_info_list)
+ {
+ estate->es_result_relation_info =
+ (RelationInfo *) nth(whichplan,
+ unionstate->as_result_relation_info_list);
+ }
+ result_slot->ttc_whichplan = whichplan;
+ }
+
+ return TRUE;
}
-
- return TRUE;
- }
}
/* ----------------------------------------------------------------
- * ExecInitAppend
- *
- * Begins all of the subscans of the append node, storing the
- * scan structures in the 'initialized' vector of the append-state
- * structure.
+ * ExecInitAppend
+ *
+ * Begins all of the subscans of the append node, storing the
+ * scan structures in the 'initialized' vector of the append-state
+ * structure.
*
- * (This is potentially wasteful, since the entire result of the
- * append node may not be scanned, but this way all of the
- * structures get allocated in the executor's top level memory
- * block instead of that of the call to ExecProcAppend.)
- *
- * Returns the scan result of the first scan.
+ * (This is potentially wasteful, since the entire result of the
+ * append node may not be scanned, but this way all of the
+ * structures get allocated in the executor's top level memory
+ * block instead of that of the call to ExecProcAppend.)
+ *
+ * Returns the scan result of the first scan.
* ----------------------------------------------------------------
*/
bool
-ExecInitAppend(Append *node, EState *estate, Plan *parent)
+ExecInitAppend(Append * node, EState * estate, Plan * parent)
{
- AppendState *unionstate;
- int nplans;
- List *resultList = NULL;
- List *rtentries;
- List *unionplans;
- bool *initialized;
- int i;
- Plan *initNode;
- List *junkList;
- RelationInfo *es_rri = estate->es_result_relation_info;
-
- /* ----------------
- * assign execution state to node and get information
- * for append state
- * ----------------
- */
- node->plan.state = estate;
-
- unionplans = node->unionplans;
- nplans = length(unionplans);
- rtentries = node->unionrtentries;
-
- CXT1_printf("ExecInitAppend: context is %d\n", CurrentMemoryContext);
- initialized = (bool *)palloc(nplans * sizeof(bool));
-
- /* ----------------
- * create new AppendState for our append node
- * ----------------
- */
- unionstate = makeNode(AppendState);
- unionstate->as_whichplan = 0;
- unionstate->as_nplans = nplans;
- unionstate->as_initialized = initialized;
- unionstate->as_rtentries = rtentries;
-
- node->unionstate = unionstate;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks
- *
- * Append plans don't have expression contexts because they
- * never call ExecQual or ExecTargetList.
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &unionstate->cstate, parent);
-
+ AppendState *unionstate;
+ int nplans;
+ List *resultList = NULL;
+ List *rtentries;
+ List *unionplans;
+ bool *initialized;
+ int i;
+ Plan *initNode;
+ List *junkList;
+ RelationInfo *es_rri = estate->es_result_relation_info;
+
+ /* ----------------
+ * assign execution state to node and get information
+ * for append state
+ * ----------------
+ */
+ node->plan.state = estate;
+
+ unionplans = node->unionplans;
+ nplans = length(unionplans);
+ rtentries = node->unionrtentries;
+
+ CXT1_printf("ExecInitAppend: context is %d\n", CurrentMemoryContext);
+ initialized = (bool *) palloc(nplans * sizeof(bool));
+
+ /* ----------------
+ * create new AppendState for our append node
+ * ----------------
+ */
+ unionstate = makeNode(AppendState);
+ unionstate->as_whichplan = 0;
+ unionstate->as_nplans = nplans;
+ unionstate->as_initialized = initialized;
+ unionstate->as_rtentries = rtentries;
+
+ node->unionstate = unionstate;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks
+ *
+ * Append plans don't have expression contexts because they
+ * never call ExecQual or ExecTargetList.
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &unionstate->cstate, parent);
+
#define APPEND_NSLOTS 1
- /* ----------------
- * append nodes still have Result slots, which hold pointers
- * to tuples, so we have to initialize them..
- * ----------------
- */
- ExecInitResultTupleSlot(estate, &unionstate->cstate);
-
- /*
- * If the inherits rtentry is the result relation, we have to make
- * a result relation info list for all inheritors so we can update
- * their indices and put the result tuples in the right place etc.
- *
- * e.g. replace p (age = p.age + 1) from p in person*
- */
- if ((es_rri != (RelationInfo*)NULL) &&
- (node->unionrelid == es_rri->ri_RangeTableIndex))
+ /* ----------------
+ * append nodes still have Result slots, which hold pointers
+ * to tuples, so we have to initialize them..
+ * ----------------
+ */
+ ExecInitResultTupleSlot(estate, &unionstate->cstate);
+
+ /*
+ * If the inherits rtentry is the result relation, we have to make a
+ * result relation info list for all inheritors so we can update their
+ * indices and put the result tuples in the right place etc.
+ *
+ * e.g. replace p (age = p.age + 1) from p in person*
+ */
+ if ((es_rri != (RelationInfo *) NULL) &&
+ (node->unionrelid == es_rri->ri_RangeTableIndex))
{
- RelationInfo *rri;
- List *rtentryP;
-
- foreach(rtentryP,rtentries)
+ RelationInfo *rri;
+ List *rtentryP;
+
+ foreach(rtentryP, rtentries)
{
- Oid reloid;
- RangeTblEntry *rtentry = lfirst(rtentryP);
-
- reloid = rtentry->relid;
- rri = makeNode(RelationInfo);
- rri->ri_RangeTableIndex = es_rri->ri_RangeTableIndex;
- rri->ri_RelationDesc = heap_open(reloid);
- rri->ri_NumIndices = 0;
- rri->ri_IndexRelationDescs = NULL; /* index descs */
- rri->ri_IndexRelationInfo = NULL; /* index key info */
-
- resultList = lcons(rri,resultList);
- ExecOpenIndices(reloid, rri);
+ Oid reloid;
+ RangeTblEntry *rtentry = lfirst(rtentryP);
+
+ reloid = rtentry->relid;
+ rri = makeNode(RelationInfo);
+ rri->ri_RangeTableIndex = es_rri->ri_RangeTableIndex;
+ rri->ri_RelationDesc = heap_open(reloid);
+ rri->ri_NumIndices = 0;
+ rri->ri_IndexRelationDescs = NULL; /* index descs */
+ rri->ri_IndexRelationInfo = NULL; /* index key info */
+
+ resultList = lcons(rri, resultList);
+ ExecOpenIndices(reloid, rri);
}
- unionstate->as_result_relation_info_list = resultList;
+ unionstate->as_result_relation_info_list = resultList;
}
- /* ----------------
- * call ExecInitNode on each of the plans in our list
- * and save the results into the array "initialized"
- * ----------------
- */
- junkList = NIL;
-
- for(i = 0; i < nplans ; i++ ) {
- JunkFilter *j;
- List *targetList;
- /* ----------------
- * NOTE: we first modify range table in
- * exec_append_initialize_next() and
- * then initialize the subnode,
- * since it may use the range table.
- * ----------------
- */
- unionstate->as_whichplan = i;
- exec_append_initialize_next(node);
-
- initNode = (Plan *) nth(i, unionplans);
- initialized[i] = ExecInitNode(initNode, estate, (Plan*) node);
-
- /* ---------------
- * Each targetlist in the subplan may need its own junk filter
- *
- * This is true only when the reln being replaced/deleted is
- * the one that we're looking at the subclasses of
- * ---------------
+ /* ----------------
+ * call ExecInitNode on each of the plans in our list
+ * and save the results into the array "initialized"
+ * ----------------
*/
- if ((es_rri != (RelationInfo*)NULL) &&
- (node->unionrelid == es_rri->ri_RangeTableIndex)) {
-
- targetList = initNode->targetlist;
- j = (JunkFilter *) ExecInitJunkFilter(targetList);
- junkList = lappend(junkList, j);
+ junkList = NIL;
+
+ for (i = 0; i < nplans; i++)
+ {
+ JunkFilter *j;
+ List *targetList;
+
+ /* ----------------
+ * NOTE: we first modify range table in
+ * exec_append_initialize_next() and
+ * then initialize the subnode,
+ * since it may use the range table.
+ * ----------------
+ */
+ unionstate->as_whichplan = i;
+ exec_append_initialize_next(node);
+
+ initNode = (Plan *) nth(i, unionplans);
+ initialized[i] = ExecInitNode(initNode, estate, (Plan *) node);
+
+ /* ---------------
+ * Each targetlist in the subplan may need its own junk filter
+ *
+ * This is true only when the reln being replaced/deleted is
+ * the one that we're looking at the subclasses of
+ * ---------------
+ */
+ if ((es_rri != (RelationInfo *) NULL) &&
+ (node->unionrelid == es_rri->ri_RangeTableIndex))
+ {
+
+ targetList = initNode->targetlist;
+ j = (JunkFilter *) ExecInitJunkFilter(targetList);
+ junkList = lappend(junkList, j);
+ }
+
}
-
- }
- unionstate->as_junkFilter_list = junkList;
- if (junkList != NIL)
- estate->es_junkFilter = (JunkFilter *)lfirst(junkList);
-
- /* ----------------
- * initialize the return type from the appropriate subplan.
- * ----------------
- */
- initNode = (Plan *) nth(0, unionplans);
- ExecAssignResultType(&unionstate->cstate,
-/* ExecGetExecTupDesc(initNode), */
- ExecGetTupType(initNode));
- unionstate->cstate.cs_ProjInfo = NULL;
-
- /* ----------------
- * return the result from the first subplan's initialization
- * ----------------
- */
- unionstate->as_whichplan = 0;
- exec_append_initialize_next(node);
+ unionstate->as_junkFilter_list = junkList;
+ if (junkList != NIL)
+ estate->es_junkFilter = (JunkFilter *) lfirst(junkList);
+
+ /* ----------------
+ * initialize the return type from the appropriate subplan.
+ * ----------------
+ */
+ initNode = (Plan *) nth(0, unionplans);
+ ExecAssignResultType(&unionstate->cstate,
+/* ExecGetExecTupDesc(initNode), */
+ ExecGetTupType(initNode));
+ unionstate->cstate.cs_ProjInfo = NULL;
+
+ /* ----------------
+ * return the result from the first subplan's initialization
+ * ----------------
+ */
+ unionstate->as_whichplan = 0;
+ exec_append_initialize_next(node);
#if 0
- result = (List *) initialized[0];
-#endif
- return TRUE;
+ result = (List *) initialized[0];
+#endif
+ return TRUE;
}
int
-ExecCountSlotsAppend(Append *node)
+ExecCountSlotsAppend(Append * node)
{
- List *plan;
- List *unionplans = node->unionplans;
- int nSlots = 0;
-
- foreach (plan,unionplans) {
- nSlots += ExecCountSlotsNode((Plan *)lfirst(plan));
- }
- return nSlots + APPEND_NSLOTS;
+ List *plan;
+ List *unionplans = node->unionplans;
+ int nSlots = 0;
+
+ foreach(plan, unionplans)
+ {
+ nSlots += ExecCountSlotsNode((Plan *) lfirst(plan));
+ }
+ return nSlots + APPEND_NSLOTS;
}
/* ----------------------------------------------------------------
- * ExecProcAppend
- *
- * Handles the iteration over the multiple scans.
- *
- * NOTE: Can't call this ExecAppend, that name is used in execMain.l
+ * ExecProcAppend
+ *
+ * Handles the iteration over the multiple scans.
+ *
+ * NOTE: Can't call this ExecAppend, that name is used in execMain.l
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecProcAppend(Append *node)
+ExecProcAppend(Append * node)
{
- EState *estate;
- AppendState *unionstate;
-
- int whichplan;
- List *unionplans;
- Plan *subnode;
- TupleTableSlot *result;
- TupleTableSlot *result_slot;
- ScanDirection direction;
-
- /* ----------------
- * get information from the node
- * ----------------
- */
- unionstate = node->unionstate;
- estate = node->plan.state;
- direction = estate->es_direction;
-
- unionplans = node->unionplans;
- whichplan = unionstate->as_whichplan;
- result_slot = unionstate->cstate.cs_ResultTupleSlot;
-
- /* ----------------
- * figure out which subplan we are currently processing
- * ----------------
- */
- subnode = (Plan *) nth(whichplan, unionplans);
-
- if (subnode == NULL)
- elog(DEBUG, "ExecProcAppend: subnode is NULL");
-
- /* ----------------
- * get a tuple from the subplan
- * ----------------
- */
- result = ExecProcNode(subnode, (Plan*)node);
-
- if (! TupIsNull(result)) {
- /* ----------------
- * if the subplan gave us something then place a copy of
- * whatever we get into our result slot and return it, else..
- * ----------------
- */
- return ExecStoreTuple(result->val,
- result_slot, result->ttc_buffer, false);
-
- } else {
- /* ----------------
- * .. go on to the "next" subplan in the appropriate
- * direction and try processing again (recursively)
- * ----------------
- */
- whichplan = unionstate->as_whichplan;
-
- if (ScanDirectionIsForward(direction))
- {
- unionstate->as_whichplan = whichplan + 1;
- }
- else
- {
- unionstate->as_whichplan = whichplan - 1;
- }
-
+ EState *estate;
+ AppendState *unionstate;
+
+ int whichplan;
+ List *unionplans;
+ Plan *subnode;
+ TupleTableSlot *result;
+ TupleTableSlot *result_slot;
+ ScanDirection direction;
+
/* ----------------
- * return something from next node or an empty slot
- * all of our subplans have been exhausted.
+ * get information from the node
* ----------------
*/
- if (exec_append_initialize_next(node)) {
- ExecSetSlotDescriptorIsNew(result_slot, true);
- return
- ExecProcAppend(node);
- } else
- return ExecClearTuple(result_slot);
- }
+ unionstate = node->unionstate;
+ estate = node->plan.state;
+ direction = estate->es_direction;
+
+ unionplans = node->unionplans;
+ whichplan = unionstate->as_whichplan;
+ result_slot = unionstate->cstate.cs_ResultTupleSlot;
+
+ /* ----------------
+ * figure out which subplan we are currently processing
+ * ----------------
+ */
+ subnode = (Plan *) nth(whichplan, unionplans);
+
+ if (subnode == NULL)
+ elog(DEBUG, "ExecProcAppend: subnode is NULL");
+
+ /* ----------------
+ * get a tuple from the subplan
+ * ----------------
+ */
+ result = ExecProcNode(subnode, (Plan *) node);
+
+ if (!TupIsNull(result))
+ {
+ /* ----------------
+ * if the subplan gave us something then place a copy of
+ * whatever we get into our result slot and return it, else..
+ * ----------------
+ */
+ return ExecStoreTuple(result->val,
+ result_slot, result->ttc_buffer, false);
+
+ }
+ else
+ {
+ /* ----------------
+ * .. go on to the "next" subplan in the appropriate
+ * direction and try processing again (recursively)
+ * ----------------
+ */
+ whichplan = unionstate->as_whichplan;
+
+ if (ScanDirectionIsForward(direction))
+ {
+ unionstate->as_whichplan = whichplan + 1;
+ }
+ else
+ {
+ unionstate->as_whichplan = whichplan - 1;
+ }
+
+ /* ----------------
+ * return something from next node or an empty slot
+ * all of our subplans have been exhausted.
+ * ----------------
+ */
+ if (exec_append_initialize_next(node))
+ {
+ ExecSetSlotDescriptorIsNew(result_slot, true);
+ return
+ ExecProcAppend(node);
+ }
+ else
+ return ExecClearTuple(result_slot);
+ }
}
/* ----------------------------------------------------------------
- * ExecEndAppend
- *
- * Shuts down the subscans of the append node.
- *
- * Returns nothing of interest.
+ * ExecEndAppend
+ *
+ * Shuts down the subscans of the append node.
+ *
+ * Returns nothing of interest.
* ----------------------------------------------------------------
*/
void
-ExecEndAppend(Append *node)
+ExecEndAppend(Append * node)
{
- AppendState *unionstate;
- int nplans;
- List *unionplans;
- bool *initialized;
- int i;
- List *resultRelationInfoList;
- RelationInfo *resultRelationInfo;
-
- /* ----------------
- * get information from the node
- * ----------------
- */
- unionstate = node->unionstate;
- unionplans = node->unionplans;
- nplans = unionstate->as_nplans;
- initialized = unionstate->as_initialized;
-
- /* ----------------
- * shut down each of the subscans
- * ----------------
- */
- for(i = 0; i < nplans; i++) {
- if (initialized[i]==TRUE) {
- ExecEndNode( (Plan *) nth(i, unionplans), (Plan*)node );
- }
- }
-
- /* ----------------
- * close out the different result relations
- * ----------------
- */
- resultRelationInfoList = unionstate->as_result_relation_info_list;
- while (resultRelationInfoList != NIL) {
- Relation resultRelationDesc;
-
- resultRelationInfo = (RelationInfo*) lfirst(resultRelationInfoList);
- resultRelationDesc = resultRelationInfo->ri_RelationDesc;
- heap_close(resultRelationDesc);
- pfree(resultRelationInfo);
- resultRelationInfoList = lnext(resultRelationInfoList);
- }
- if (unionstate->as_result_relation_info_list)
- pfree(unionstate->as_result_relation_info_list);
-
- /* XXX should free unionstate->as_rtentries and unionstate->as_junkfilter_list here */
-}
+ AppendState *unionstate;
+ int nplans;
+ List *unionplans;
+ bool *initialized;
+ int i;
+ List *resultRelationInfoList;
+ RelationInfo *resultRelationInfo;
+
+ /* ----------------
+ * get information from the node
+ * ----------------
+ */
+ unionstate = node->unionstate;
+ unionplans = node->unionplans;
+ nplans = unionstate->as_nplans;
+ initialized = unionstate->as_initialized;
+
+ /* ----------------
+ * shut down each of the subscans
+ * ----------------
+ */
+ for (i = 0; i < nplans; i++)
+ {
+ if (initialized[i] == TRUE)
+ {
+ ExecEndNode((Plan *) nth(i, unionplans), (Plan *) node);
+ }
+ }
+
+ /* ----------------
+ * close out the different result relations
+ * ----------------
+ */
+ resultRelationInfoList = unionstate->as_result_relation_info_list;
+ while (resultRelationInfoList != NIL)
+ {
+ Relation resultRelationDesc;
+ resultRelationInfo = (RelationInfo *) lfirst(resultRelationInfoList);
+ resultRelationDesc = resultRelationInfo->ri_RelationDesc;
+ heap_close(resultRelationDesc);
+ pfree(resultRelationInfo);
+ resultRelationInfoList = lnext(resultRelationInfoList);
+ }
+ if (unionstate->as_result_relation_info_list)
+ pfree(unionstate->as_result_relation_info_list);
+
+ /*
+ * XXX should free unionstate->as_rtentries and
+ * unionstate->as_junkfilter_list here
+ */
+}
diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c
index 0637a8dd282..1a96a1ee911 100644
--- a/src/backend/executor/nodeGroup.c
+++ b/src/backend/executor/nodeGroup.c
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* nodeGroup.c--
- * Routines to handle group nodes (used for queries with GROUP BY clause).
+ * Routines to handle group nodes (used for queries with GROUP BY clause).
*
* Copyright (c) 1994, Regents of the University of California
*
*
* DESCRIPTION
- * The Group node is designed for handling queries with a GROUP BY clause.
- * It's outer plan must be a sort node. It assumes that the tuples it gets
- * back from the outer plan is sorted in the order specified by the group
- * columns. (ie. tuples from the same group are consecutive)
+ * The Group node is designed for handling queries with a GROUP BY clause.
+ * It's outer plan must be a sort node. It assumes that the tuples it gets
+ * back from the outer plan is sorted in the order specified by the group
+ * columns. (ie. tuples from the same group are consecutive)
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.5 1997/01/10 20:17:35 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.6 1997/09/07 04:41:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,329 +28,348 @@
#include "executor/executor.h"
#include "executor/nodeGroup.h"
-static TupleTableSlot *ExecGroupEveryTuple(Group *node);
-static TupleTableSlot *ExecGroupOneTuple(Group *node);
-static bool sameGroup(TupleTableSlot *oldslot, TupleTableSlot *newslot,
- int numCols, AttrNumber *grpColIdx, TupleDesc tupdesc);
+static TupleTableSlot *ExecGroupEveryTuple(Group * node);
+static TupleTableSlot *ExecGroupOneTuple(Group * node);
+static bool
+sameGroup(TupleTableSlot * oldslot, TupleTableSlot * newslot,
+ int numCols, AttrNumber * grpColIdx, TupleDesc tupdesc);
/* ---------------------------------------
- * ExecGroup -
+ * ExecGroup -
*
- * There are two modes in which tuples are returned by ExecGroup. If
- * tuplePerGroup is TRUE, every tuple from the same group will be
- * returned, followed by a NULL at the end of each group. This is
- * useful for Agg node which needs to aggregate over tuples of the same
- * group. (eg. SELECT salary, count{*} FROM emp GROUP BY salary)
+ * There are two modes in which tuples are returned by ExecGroup. If
+ * tuplePerGroup is TRUE, every tuple from the same group will be
+ * returned, followed by a NULL at the end of each group. This is
+ * useful for Agg node which needs to aggregate over tuples of the same
+ * group. (eg. SELECT salary, count{*} FROM emp GROUP BY salary)
*
- * If tuplePerGroup is FALSE, only one tuple per group is returned. The
- * tuple returned contains only the group columns. NULL is returned only
- * at the end when no more groups is present. This is useful when
- * the query does not involve aggregates. (eg. SELECT salary FROM emp
- * GROUP BY salary)
+ * If tuplePerGroup is FALSE, only one tuple per group is returned. The
+ * tuple returned contains only the group columns. NULL is returned only
+ * at the end when no more groups is present. This is useful when
+ * the query does not involve aggregates. (eg. SELECT salary FROM emp
+ * GROUP BY salary)
* ------------------------------------------
*/
TupleTableSlot *
-ExecGroup(Group *node)
+ExecGroup(Group * node)
{
- if (node->tuplePerGroup)
- return ExecGroupEveryTuple(node);
- else
- return ExecGroupOneTuple(node);
+ if (node->tuplePerGroup)
+ return ExecGroupEveryTuple(node);
+ else
+ return ExecGroupOneTuple(node);
}
/*
* ExecGroupEveryTuple -
- * return every tuple with a NULL between each group
+ * return every tuple with a NULL between each group
*/
static TupleTableSlot *
-ExecGroupEveryTuple(Group *node)
+ExecGroupEveryTuple(Group * node)
{
- GroupState *grpstate;
- EState *estate;
- ExprContext *econtext;
+ GroupState *grpstate;
+ EState *estate;
+ ExprContext *econtext;
- HeapTuple outerTuple = NULL;
- TupleTableSlot *outerslot, *lastslot;
- ProjectionInfo *projInfo;
- TupleTableSlot *resultSlot;
+ HeapTuple outerTuple = NULL;
+ TupleTableSlot *outerslot,
+ *lastslot;
+ ProjectionInfo *projInfo;
+ TupleTableSlot *resultSlot;
- bool isDone;
+ bool isDone;
- /* ---------------------
- * get state info from node
- * ---------------------
- */
- grpstate = node->grpstate;
- if (grpstate->grp_done)
- return NULL;
+ /* ---------------------
+ * get state info from node
+ * ---------------------
+ */
+ grpstate = node->grpstate;
+ if (grpstate->grp_done)
+ return NULL;
- estate = node->plan.state;
+ estate = node->plan.state;
- econtext = grpstate->csstate.cstate.cs_ExprContext;
+ econtext = grpstate->csstate.cstate.cs_ExprContext;
- if (grpstate->grp_useLastTuple) {
- /*
- * we haven't returned last tuple yet because it is not of the
- * same group
- */
- grpstate->grp_useLastTuple = FALSE;
+ if (grpstate->grp_useLastTuple)
+ {
+
+ /*
+ * we haven't returned last tuple yet because it is not of the
+ * same group
+ */
+ grpstate->grp_useLastTuple = FALSE;
- ExecStoreTuple(grpstate->grp_lastSlot->val,
- grpstate->csstate.css_ScanTupleSlot,
- grpstate->grp_lastSlot->ttc_buffer,
- false);
- } else {
- outerslot = ExecProcNode(outerPlan(node), (Plan*)node);
- if (outerslot)
- outerTuple = outerslot->val;
- if (!HeapTupleIsValid(outerTuple)) {
- grpstate->grp_done = TRUE;
- return NULL;
+ ExecStoreTuple(grpstate->grp_lastSlot->val,
+ grpstate->csstate.css_ScanTupleSlot,
+ grpstate->grp_lastSlot->ttc_buffer,
+ false);
+ }
+ else
+ {
+ outerslot = ExecProcNode(outerPlan(node), (Plan *) node);
+ if (outerslot)
+ outerTuple = outerslot->val;
+ if (!HeapTupleIsValid(outerTuple))
+ {
+ grpstate->grp_done = TRUE;
+ return NULL;
+ }
+
+ /* ----------------
+ * Compare with last tuple and see if this tuple is of
+ * the same group.
+ * ----------------
+ */
+ lastslot = grpstate->csstate.css_ScanTupleSlot;
+
+ if (lastslot->val != NULL &&
+ (!sameGroup(lastslot, outerslot,
+ node->numCols, node->grpColIdx,
+ ExecGetScanType(&grpstate->csstate))))
+ {
+/* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
+
+ grpstate->grp_useLastTuple = TRUE;
+
+ /* save it for next time */
+ grpstate->grp_lastSlot = outerslot;
+
+ /*
+ * signifies the end of the group
+ */
+ return NULL;
+ }
+
+ ExecStoreTuple(outerTuple,
+ grpstate->csstate.css_ScanTupleSlot,
+ outerslot->ttc_buffer,
+ false);
}
/* ----------------
- * Compare with last tuple and see if this tuple is of
- * the same group.
+ * form a projection tuple, store it in the result tuple
+ * slot and return it.
* ----------------
*/
- lastslot = grpstate->csstate.css_ScanTupleSlot;
-
- if (lastslot->val != NULL &&
- (!sameGroup(lastslot, outerslot,
- node->numCols, node->grpColIdx,
- ExecGetScanType(&grpstate->csstate)))) {
-/* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
-
- grpstate->grp_useLastTuple = TRUE;
+ projInfo = grpstate->csstate.cstate.cs_ProjInfo;
- /* save it for next time */
- grpstate->grp_lastSlot = outerslot;
+ econtext->ecxt_scantuple = grpstate->csstate.css_ScanTupleSlot;
+ resultSlot = ExecProject(projInfo, &isDone);
- /*
- * signifies the end of the group
- */
- return NULL;
- }
-
- ExecStoreTuple(outerTuple,
- grpstate->csstate.css_ScanTupleSlot,
- outerslot->ttc_buffer,
- false);
- }
-
- /* ----------------
- * form a projection tuple, store it in the result tuple
- * slot and return it.
- * ----------------
- */
- projInfo = grpstate->csstate.cstate.cs_ProjInfo;
-
- econtext->ecxt_scantuple = grpstate->csstate.css_ScanTupleSlot;
- resultSlot = ExecProject(projInfo, &isDone);
-
- return resultSlot;
+ return resultSlot;
}
/*
* ExecGroupOneTuple -
- * returns one tuple per group, a NULL at the end when there are no more
- * tuples.
+ * returns one tuple per group, a NULL at the end when there are no more
+ * tuples.
*/
static TupleTableSlot *
-ExecGroupOneTuple(Group *node)
+ExecGroupOneTuple(Group * node)
{
- GroupState *grpstate;
- EState *estate;
- ExprContext *econtext;
+ GroupState *grpstate;
+ EState *estate;
+ ExprContext *econtext;
- HeapTuple outerTuple = NULL;
- TupleTableSlot *outerslot, *lastslot;
- ProjectionInfo *projInfo;
- TupleTableSlot *resultSlot;
+ HeapTuple outerTuple = NULL;
+ TupleTableSlot *outerslot,
+ *lastslot;
+ ProjectionInfo *projInfo;
+ TupleTableSlot *resultSlot;
- bool isDone;
+ bool isDone;
- /* ---------------------
- * get state info from node
- * ---------------------
- */
- grpstate = node->grpstate;
- if (grpstate->grp_done)
- return NULL;
+ /* ---------------------
+ * get state info from node
+ * ---------------------
+ */
+ grpstate = node->grpstate;
+ if (grpstate->grp_done)
+ return NULL;
- estate = node->plan.state;
+ estate = node->plan.state;
- econtext = node->grpstate->csstate.cstate.cs_ExprContext;
+ econtext = node->grpstate->csstate.cstate.cs_ExprContext;
- if (grpstate->grp_useLastTuple) {
- grpstate->grp_useLastTuple = FALSE;
- ExecStoreTuple(grpstate->grp_lastSlot->val,
- grpstate->csstate.css_ScanTupleSlot,
- grpstate->grp_lastSlot->ttc_buffer,
- false);
- } else {
- outerslot = ExecProcNode(outerPlan(node), (Plan*)node);
- if (outerslot) outerTuple = outerslot->val;
- if (!HeapTupleIsValid(outerTuple)) {
- grpstate->grp_done = TRUE;
- return NULL;
+ if (grpstate->grp_useLastTuple)
+ {
+ grpstate->grp_useLastTuple = FALSE;
+ ExecStoreTuple(grpstate->grp_lastSlot->val,
+ grpstate->csstate.css_ScanTupleSlot,
+ grpstate->grp_lastSlot->ttc_buffer,
+ false);
}
- ExecStoreTuple(outerTuple,
- grpstate->csstate.css_ScanTupleSlot,
- outerslot->ttc_buffer,
- false);
- }
- lastslot = grpstate->csstate.css_ScanTupleSlot;
-
- /*
- * find all tuples that belong to a group
- */
- for(;;) {
- outerslot = ExecProcNode(outerPlan(node), (Plan*)node);
- outerTuple = (outerslot) ? outerslot->val : NULL;
- if (!HeapTupleIsValid(outerTuple)) {
- /*
- * we have at least one tuple (lastslot) if we reach here
- */
- grpstate->grp_done = TRUE;
-
- /* return lastslot */
- break;
+ else
+ {
+ outerslot = ExecProcNode(outerPlan(node), (Plan *) node);
+ if (outerslot)
+ outerTuple = outerslot->val;
+ if (!HeapTupleIsValid(outerTuple))
+ {
+ grpstate->grp_done = TRUE;
+ return NULL;
+ }
+ ExecStoreTuple(outerTuple,
+ grpstate->csstate.css_ScanTupleSlot,
+ outerslot->ttc_buffer,
+ false);
}
+ lastslot = grpstate->csstate.css_ScanTupleSlot;
- /* ----------------
- * Compare with last tuple and see if this tuple is of
- * the same group.
- * ----------------
+ /*
+ * find all tuples that belong to a group
*/
- if ((!sameGroup(lastslot, outerslot,
- node->numCols, node->grpColIdx,
- ExecGetScanType(&grpstate->csstate)))) {
-/* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
+ for (;;)
+ {
+ outerslot = ExecProcNode(outerPlan(node), (Plan *) node);
+ outerTuple = (outerslot) ? outerslot->val : NULL;
+ if (!HeapTupleIsValid(outerTuple))
+ {
+
+ /*
+ * we have at least one tuple (lastslot) if we reach here
+ */
+ grpstate->grp_done = TRUE;
+
+ /* return lastslot */
+ break;
+ }
+
+ /* ----------------
+ * Compare with last tuple and see if this tuple is of
+ * the same group.
+ * ----------------
+ */
+ if ((!sameGroup(lastslot, outerslot,
+ node->numCols, node->grpColIdx,
+ ExecGetScanType(&grpstate->csstate))))
+ {
+/* ExecGetResultType(&grpstate->csstate.cstate)))) {*/
+
+ grpstate->grp_useLastTuple = TRUE;
+
+ /* save it for next time */
+ grpstate->grp_lastSlot = outerslot;
+
+ /* return lastslot */
+ break;
+ }
+
+ ExecStoreTuple(outerTuple,
+ grpstate->csstate.css_ScanTupleSlot,
+ outerslot->ttc_buffer,
+ false);
+
+ lastslot = grpstate->csstate.css_ScanTupleSlot;
+ }
- grpstate->grp_useLastTuple = TRUE;
+ ExecStoreTuple(lastslot->val,
+ grpstate->csstate.css_ScanTupleSlot,
+ lastslot->ttc_buffer,
+ false);
- /* save it for next time */
- grpstate->grp_lastSlot = outerslot;
+ /* ----------------
+ * form a projection tuple, store it in the result tuple
+ * slot and return it.
+ * ----------------
+ */
+ projInfo = grpstate->csstate.cstate.cs_ProjInfo;
- /* return lastslot */
- break;
- }
-
- ExecStoreTuple(outerTuple,
- grpstate->csstate.css_ScanTupleSlot,
- outerslot->ttc_buffer,
- false);
+ econtext->ecxt_scantuple = lastslot;
+ resultSlot = ExecProject(projInfo, &isDone);
- lastslot = grpstate->csstate.css_ScanTupleSlot;
- }
-
- ExecStoreTuple(lastslot->val,
- grpstate->csstate.css_ScanTupleSlot,
- lastslot->ttc_buffer,
- false);
-
- /* ----------------
- * form a projection tuple, store it in the result tuple
- * slot and return it.
- * ----------------
- */
- projInfo = grpstate->csstate.cstate.cs_ProjInfo;
-
- econtext->ecxt_scantuple = lastslot;
- resultSlot = ExecProject(projInfo, &isDone);
-
- return resultSlot;
+ return resultSlot;
}
/* -----------------
- * ExecInitGroup
+ * ExecInitGroup
*
- * Creates the run-time information for the group node produced by the
- * planner and initializes its outer subtree
+ * Creates the run-time information for the group node produced by the
+ * planner and initializes its outer subtree
* -----------------
*/
bool
-ExecInitGroup(Group *node, EState *estate, Plan *parent)
+ExecInitGroup(Group * node, EState * estate, Plan * parent)
{
- GroupState *grpstate;
- Plan *outerPlan;
-
- /*
- * assign the node's execution state
- */
- node->plan.state = estate;
-
- /*
- * create state structure
- */
- grpstate = makeNode(GroupState);
- node->grpstate = grpstate;
- grpstate->grp_useLastTuple = FALSE;
- grpstate->grp_done = FALSE;
-
- /*
- * assign node's base id and create expression context
- */
- ExecAssignNodeBaseInfo(estate, &grpstate->csstate.cstate,
- (Plan*) parent);
- ExecAssignExprContext(estate, &grpstate->csstate.cstate);
-
+ GroupState *grpstate;
+ Plan *outerPlan;
+
+ /*
+ * assign the node's execution state
+ */
+ node->plan.state = estate;
+
+ /*
+ * create state structure
+ */
+ grpstate = makeNode(GroupState);
+ node->grpstate = grpstate;
+ grpstate->grp_useLastTuple = FALSE;
+ grpstate->grp_done = FALSE;
+
+ /*
+ * assign node's base id and create expression context
+ */
+ ExecAssignNodeBaseInfo(estate, &grpstate->csstate.cstate,
+ (Plan *) parent);
+ ExecAssignExprContext(estate, &grpstate->csstate.cstate);
+
#define GROUP_NSLOTS 2
- /*
- * tuple table initialization
- */
- ExecInitScanTupleSlot(estate, &grpstate->csstate);
- ExecInitResultTupleSlot(estate, &grpstate->csstate.cstate);
-
- /*
- * initializes child nodes
- */
- outerPlan = outerPlan(node);
- ExecInitNode(outerPlan, estate, (Plan *)node);
-
- /* ----------------
- * initialize tuple type.
- * ----------------
- */
- ExecAssignScanTypeFromOuterPlan((Plan *) node, &grpstate->csstate);
-
- /*
- * Initialize tuple type for both result and scan.
- * This node does no projection
- */
- ExecAssignResultTypeFromTL((Plan*) node, &grpstate->csstate.cstate);
- ExecAssignProjectionInfo((Plan*)node, &grpstate->csstate.cstate);
-
- return TRUE;
+
+ /*
+ * tuple table initialization
+ */
+ ExecInitScanTupleSlot(estate, &grpstate->csstate);
+ ExecInitResultTupleSlot(estate, &grpstate->csstate.cstate);
+
+ /*
+ * initializes child nodes
+ */
+ outerPlan = outerPlan(node);
+ ExecInitNode(outerPlan, estate, (Plan *) node);
+
+ /* ----------------
+ * initialize tuple type.
+ * ----------------
+ */
+ ExecAssignScanTypeFromOuterPlan((Plan *) node, &grpstate->csstate);
+
+ /*
+ * Initialize tuple type for both result and scan. This node does no
+ * projection
+ */
+ ExecAssignResultTypeFromTL((Plan *) node, &grpstate->csstate.cstate);
+ ExecAssignProjectionInfo((Plan *) node, &grpstate->csstate.cstate);
+
+ return TRUE;
}
int
-ExecCountSlotsGroup(Group *node)
+ExecCountSlotsGroup(Group * node)
{
- return ExecCountSlotsNode(outerPlan(node)) + GROUP_NSLOTS;
+ return ExecCountSlotsNode(outerPlan(node)) + GROUP_NSLOTS;
}
/* ------------------------
- * ExecEndGroup(node)
+ * ExecEndGroup(node)
*
* -----------------------
*/
void
-ExecEndGroup(Group *node)
+ExecEndGroup(Group * node)
{
- GroupState *grpstate;
- Plan *outerPlan;
+ GroupState *grpstate;
+ Plan *outerPlan;
+
+ grpstate = node->grpstate;
- grpstate = node->grpstate;
+ ExecFreeProjectionInfo(&grpstate->csstate.cstate);
- ExecFreeProjectionInfo(&grpstate->csstate.cstate);
+ outerPlan = outerPlan(node);
+ ExecEndNode(outerPlan, (Plan *) node);
- outerPlan = outerPlan(node);
- ExecEndNode(outerPlan, (Plan*)node);
-
- /* clean up tuple table */
- ExecClearTuple(grpstate->csstate.css_ScanTupleSlot);
+ /* clean up tuple table */
+ ExecClearTuple(grpstate->csstate.css_ScanTupleSlot);
}
/*****************************************************************************
@@ -360,54 +379,63 @@ ExecEndGroup(Group *node)
/*
* code swiped from nodeUnique.c
*/
-static bool
-sameGroup(TupleTableSlot *oldslot,
- TupleTableSlot *newslot,
- int numCols,
- AttrNumber *grpColIdx,
- TupleDesc tupdesc)
+static bool
+sameGroup(TupleTableSlot * oldslot,
+ TupleTableSlot * newslot,
+ int numCols,
+ AttrNumber * grpColIdx,
+ TupleDesc tupdesc)
{
- bool isNull1,isNull2;
- char *attr1, *attr2;
- char *val1, *val2;
- int i;
- AttrNumber att;
- Oid typoutput;
-
- for(i = 0; i < numCols; i++) {
- att = grpColIdx[i];
- typoutput = typtoout((Oid)tupdesc->attrs[att-1]->atttypid);
-
- attr1 = heap_getattr(oldslot->val,
- InvalidBuffer,
- att,
- tupdesc,
- &isNull1);
-
- attr2 = heap_getattr(newslot->val,
- InvalidBuffer,
- att,
- tupdesc,
- &isNull2);
-
- if (isNull1 == isNull2) {
- if (isNull1) /* both are null, they are equal */
- continue;
-
- val1 = fmgr(typoutput, attr1,
- gettypelem(tupdesc->attrs[att-1]->atttypid));
- val2 = fmgr(typoutput, attr2,
- gettypelem(tupdesc->attrs[att-1]->atttypid));
-
- /* now, val1 and val2 are ascii representations so we can
- use strcmp for comparison */
- if (strcmp(val1,val2) != 0)
- return FALSE;
- } else {
- /* one is null and the other isn't, they aren't equal */
- return FALSE;
+ bool isNull1,
+ isNull2;
+ char *attr1,
+ *attr2;
+ char *val1,
+ *val2;
+ int i;
+ AttrNumber att;
+ Oid typoutput;
+
+ for (i = 0; i < numCols; i++)
+ {
+ att = grpColIdx[i];
+ typoutput = typtoout((Oid) tupdesc->attrs[att - 1]->atttypid);
+
+ attr1 = heap_getattr(oldslot->val,
+ InvalidBuffer,
+ att,
+ tupdesc,
+ &isNull1);
+
+ attr2 = heap_getattr(newslot->val,
+ InvalidBuffer,
+ att,
+ tupdesc,
+ &isNull2);
+
+ if (isNull1 == isNull2)
+ {
+ if (isNull1) /* both are null, they are equal */
+ continue;
+
+ val1 = fmgr(typoutput, attr1,
+ gettypelem(tupdesc->attrs[att - 1]->atttypid));
+ val2 = fmgr(typoutput, attr2,
+ gettypelem(tupdesc->attrs[att - 1]->atttypid));
+
+ /*
+ * now, val1 and val2 are ascii representations so we can use
+ * strcmp for comparison
+ */
+ if (strcmp(val1, val2) != 0)
+ return FALSE;
+ }
+ else
+ {
+ /* one is null and the other isn't, they aren't equal */
+ return FALSE;
+ }
}
- }
- return TRUE;
+ return TRUE;
}
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 10bfe9842cf..b25939fa832 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -1,26 +1,26 @@
/*-------------------------------------------------------------------------
*
* nodeHash.c--
- * Routines to hash relations for hashjoin
+ * Routines to hash relations for hashjoin
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.10 1997/08/19 21:31:08 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.11 1997/09/07 04:41:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * ExecHash - generate an in-memory hash table of the relation
- * ExecInitHash - initialize node and subnodes..
- * ExecEndHash - shutdown node and subnodes
+ * ExecHash - generate an in-memory hash table of the relation
+ * ExecInitHash - initialize node and subnodes..
+ * ExecEndHash - shutdown node and subnodes
*
*/
#include <sys/types.h>
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <math.h>
#include <string.h>
#include <sys/file.h>
@@ -32,9 +32,9 @@
#include "postgres.h"
-#include "storage/fd.h" /* for SEEK_ */
+#include "storage/fd.h" /* for SEEK_ */
#include "storage/ipc.h"
-#include "storage/bufmgr.h" /* for BLCKSZ */
+#include "storage/bufmgr.h" /* for BLCKSZ */
#include "executor/executor.h"
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
@@ -42,827 +42,855 @@
#include "utils/palloc.h"
#include "utils/hsearch.h"
-extern int NBuffers;
-static int HashTBSize;
+extern int NBuffers;
+static int HashTBSize;
-static void mk_hj_temp(char *tempname);
-static int hashFunc(char *key, int len);
-static int ExecHashPartition(Hash *node);
+static void mk_hj_temp(char *tempname);
+static int hashFunc(char *key, int len);
+static int ExecHashPartition(Hash * node);
static RelativeAddr hashTableAlloc(int size, HashJoinTable hashtable);
-static void ExecHashOverflowInsert(HashJoinTable hashtable,
- HashBucket bucket,
- HeapTuple heapTuple);
+static void
+ExecHashOverflowInsert(HashJoinTable hashtable,
+ HashBucket bucket,
+ HeapTuple heapTuple);
/* ----------------------------------------------------------------
- * ExecHash
+ * ExecHash
*
- * build hash table for hashjoin, all do partitioning if more
- * than one batches are required.
+ * build hash table for hashjoin, all do partitioning if more
+ * than one batches are required.
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecHash(Hash *node)
+ExecHash(Hash * node)
{
- EState *estate;
- HashState *hashstate;
- Plan *outerNode;
- Var *hashkey;
- HashJoinTable hashtable;
- TupleTableSlot *slot;
- ExprContext *econtext;
-
- int nbatch;
- File *batches = NULL;
- RelativeAddr *batchPos;
- int *batchSizes;
- int i;
- RelativeAddr *innerbatchNames;
-
- /* ----------------
- * get state info from node
- * ----------------
- */
-
- hashstate = node->hashstate;
- estate = node->plan.state;
- outerNode = outerPlan(node);
-
- hashtable = node->hashtable;
- if (hashtable == NULL)
- elog(WARN, "ExecHash: hash table is NULL.");
-
- nbatch = hashtable->nbatch;
-
- if (nbatch > 0) { /* if needs hash partition */
- innerbatchNames = (RelativeAddr *) ABSADDR(hashtable->innerbatchNames);
-
- /* --------------
- * allocate space for the file descriptors of batch files
- * then open the batch files in the current processes.
- * --------------
- */
- batches = (File*)palloc(nbatch * sizeof(File));
- for (i=0; i<nbatch; i++) {
- batches[i] = FileNameOpenFile(ABSADDR(innerbatchNames[i]),
- O_CREAT | O_RDWR, 0600);
+ EState *estate;
+ HashState *hashstate;
+ Plan *outerNode;
+ Var *hashkey;
+ HashJoinTable hashtable;
+ TupleTableSlot *slot;
+ ExprContext *econtext;
+
+ int nbatch;
+ File *batches = NULL;
+ RelativeAddr *batchPos;
+ int *batchSizes;
+ int i;
+ RelativeAddr *innerbatchNames;
+
+ /* ----------------
+ * get state info from node
+ * ----------------
+ */
+
+ hashstate = node->hashstate;
+ estate = node->plan.state;
+ outerNode = outerPlan(node);
+
+ hashtable = node->hashtable;
+ if (hashtable == NULL)
+ elog(WARN, "ExecHash: hash table is NULL.");
+
+ nbatch = hashtable->nbatch;
+
+ if (nbatch > 0)
+ { /* if needs hash partition */
+ innerbatchNames = (RelativeAddr *) ABSADDR(hashtable->innerbatchNames);
+
+ /* --------------
+ * allocate space for the file descriptors of batch files
+ * then open the batch files in the current processes.
+ * --------------
+ */
+ batches = (File *) palloc(nbatch * sizeof(File));
+ for (i = 0; i < nbatch; i++)
+ {
+ batches[i] = FileNameOpenFile(ABSADDR(innerbatchNames[i]),
+ O_CREAT | O_RDWR, 0600);
+ }
+ hashstate->hashBatches = batches;
+ batchPos = (RelativeAddr *) ABSADDR(hashtable->innerbatchPos);
+ batchSizes = (int *) ABSADDR(hashtable->innerbatchSizes);
+ }
+
+ /* ----------------
+ * set expression context
+ * ----------------
+ */
+ hashkey = node->hashkey;
+ econtext = hashstate->cstate.cs_ExprContext;
+
+ /* ----------------
+ * get tuple and insert into the hash table
+ * ----------------
+ */
+ for (;;)
+ {
+ slot = ExecProcNode(outerNode, (Plan *) node);
+ if (TupIsNull(slot))
+ break;
+
+ econtext->ecxt_innertuple = slot;
+ ExecHashTableInsert(hashtable, econtext, hashkey,
+ hashstate->hashBatches);
+
+ ExecClearTuple(slot);
+ }
+
+ /*
+ * end of build phase, flush all the last pages of the batches.
+ */
+ for (i = 0; i < nbatch; i++)
+ {
+ if (FileSeek(batches[i], 0L, SEEK_END) < 0)
+ perror("FileSeek");
+ if (FileWrite(batches[i], ABSADDR(hashtable->batch) + i * BLCKSZ, BLCKSZ) < 0)
+ perror("FileWrite");
+ NDirectFileWrite++;
}
- hashstate->hashBatches = batches;
- batchPos = (RelativeAddr*) ABSADDR(hashtable->innerbatchPos);
- batchSizes = (int*) ABSADDR(hashtable->innerbatchSizes);
- }
-
- /* ----------------
- * set expression context
- * ----------------
- */
- hashkey = node->hashkey;
- econtext = hashstate->cstate.cs_ExprContext;
-
- /* ----------------
- * get tuple and insert into the hash table
- * ----------------
- */
- for (;;) {
- slot = ExecProcNode(outerNode, (Plan*)node);
- if (TupIsNull(slot))
- break;
-
- econtext->ecxt_innertuple = slot;
- ExecHashTableInsert(hashtable, econtext, hashkey,
- hashstate->hashBatches);
-
- ExecClearTuple(slot);
- }
-
- /*
- * end of build phase, flush all the last pages of the batches.
- */
- for (i=0; i<nbatch; i++) {
- if (FileSeek(batches[i], 0L, SEEK_END) < 0)
- perror("FileSeek");
- if (FileWrite(batches[i],ABSADDR(hashtable->batch)+i*BLCKSZ,BLCKSZ) < 0)
- perror("FileWrite");
- NDirectFileWrite++;
- }
-
- /* ---------------------
- * Return the slot so that we have the tuple descriptor
- * when we need to save/restore them. -Jeff 11 July 1991
- * ---------------------
- */
- return slot;
+
+ /* ---------------------
+ * Return the slot so that we have the tuple descriptor
+ * when we need to save/restore them. -Jeff 11 July 1991
+ * ---------------------
+ */
+ return slot;
}
/* ----------------------------------------------------------------
- * ExecInitHash
+ * ExecInitHash
*
- * Init routine for Hash node
+ * Init routine for Hash node
* ----------------------------------------------------------------
*/
bool
-ExecInitHash(Hash *node, EState *estate, Plan *parent)
+ExecInitHash(Hash * node, EState * estate, Plan * parent)
{
- HashState *hashstate;
- Plan *outerPlan;
-
- SO1_printf("ExecInitHash: %s\n",
- "initializing hash node");
-
- /* ----------------
- * assign the node's execution state
- * ----------------
- */
- node->plan.state = estate;
-
- /* ----------------
- * create state structure
- * ----------------
- */
- hashstate = makeNode(HashState);
- node->hashstate = hashstate;
- hashstate->hashBatches = NULL;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks and
- * + create expression context for node
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &hashstate->cstate, parent);
- ExecAssignExprContext(estate, &hashstate->cstate);
-
+ HashState *hashstate;
+ Plan *outerPlan;
+
+ SO1_printf("ExecInitHash: %s\n",
+ "initializing hash node");
+
+ /* ----------------
+ * assign the node's execution state
+ * ----------------
+ */
+ node->plan.state = estate;
+
+ /* ----------------
+ * create state structure
+ * ----------------
+ */
+ hashstate = makeNode(HashState);
+ node->hashstate = hashstate;
+ hashstate->hashBatches = NULL;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks and
+ * + create expression context for node
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &hashstate->cstate, parent);
+ ExecAssignExprContext(estate, &hashstate->cstate);
+
#define HASH_NSLOTS 1
- /* ----------------
- * initialize our result slot
- * ----------------
- */
- ExecInitResultTupleSlot(estate, &hashstate->cstate);
-
- /* ----------------
- * initializes child nodes
- * ----------------
- */
- outerPlan = outerPlan(node);
- ExecInitNode(outerPlan, estate, (Plan *)node);
-
- /* ----------------
- * initialize tuple type. no need to initialize projection
- * info because this node doesn't do projections
- * ----------------
- */
- ExecAssignResultTypeFromOuterPlan((Plan *) node, &hashstate->cstate);
- hashstate->cstate.cs_ProjInfo = NULL;
-
- return TRUE;
+ /* ----------------
+ * initialize our result slot
+ * ----------------
+ */
+ ExecInitResultTupleSlot(estate, &hashstate->cstate);
+
+ /* ----------------
+ * initializes child nodes
+ * ----------------
+ */
+ outerPlan = outerPlan(node);
+ ExecInitNode(outerPlan, estate, (Plan *) node);
+
+ /* ----------------
+ * initialize tuple type. no need to initialize projection
+ * info because this node doesn't do projections
+ * ----------------
+ */
+ ExecAssignResultTypeFromOuterPlan((Plan *) node, &hashstate->cstate);
+ hashstate->cstate.cs_ProjInfo = NULL;
+
+ return TRUE;
}
int
-ExecCountSlotsHash(Hash *node)
+ExecCountSlotsHash(Hash * node)
{
- return ExecCountSlotsNode(outerPlan(node)) +
+ return ExecCountSlotsNode(outerPlan(node)) +
ExecCountSlotsNode(innerPlan(node)) +
- HASH_NSLOTS;
+ HASH_NSLOTS;
}
/* ---------------------------------------------------------------
- * ExecEndHash
+ * ExecEndHash
*
- * clean up routine for Hash node
+ * clean up routine for Hash node
* ----------------------------------------------------------------
*/
void
-ExecEndHash(Hash *node)
+ExecEndHash(Hash * node)
{
- HashState *hashstate;
- Plan *outerPlan;
- File *batches;
-
- /* ----------------
- * get info from the hash state
- * ----------------
- */
- hashstate = node->hashstate;
- batches = hashstate->hashBatches;
- if (batches != NULL)
- pfree(batches);
-
- /* ----------------
- * free projection info. no need to free result type info
- * because that came from the outer plan...
- * ----------------
- */
- ExecFreeProjectionInfo(&hashstate->cstate);
-
- /* ----------------
- * shut down the subplan
- * ----------------
- */
- outerPlan = outerPlan(node);
- ExecEndNode(outerPlan, (Plan*)node);
-}
-
-static RelativeAddr
+ HashState *hashstate;
+ Plan *outerPlan;
+ File *batches;
+
+ /* ----------------
+ * get info from the hash state
+ * ----------------
+ */
+ hashstate = node->hashstate;
+ batches = hashstate->hashBatches;
+ if (batches != NULL)
+ pfree(batches);
+
+ /* ----------------
+ * free projection info. no need to free result type info
+ * because that came from the outer plan...
+ * ----------------
+ */
+ ExecFreeProjectionInfo(&hashstate->cstate);
+
+ /* ----------------
+ * shut down the subplan
+ * ----------------
+ */
+ outerPlan = outerPlan(node);
+ ExecEndNode(outerPlan, (Plan *) node);
+}
+
+static RelativeAddr
hashTableAlloc(int size, HashJoinTable hashtable)
{
- RelativeAddr p;
- p = hashtable->top;
- hashtable->top += size;
- return p;
+ RelativeAddr p;
+
+ p = hashtable->top;
+ hashtable->top += size;
+ return p;
}
/* ----------------------------------------------------------------
- * ExecHashTableCreate
+ * ExecHashTableCreate
*
- * create a hashtable in shared memory for hashjoin.
+ * create a hashtable in shared memory for hashjoin.
* ----------------------------------------------------------------
*/
-#define NTUP_PER_BUCKET 10
-#define FUDGE_FAC 1.5
+#define NTUP_PER_BUCKET 10
+#define FUDGE_FAC 1.5
HashJoinTable
-ExecHashTableCreate(Hash *node)
+ExecHashTableCreate(Hash * node)
{
- Plan *outerNode;
- int nbatch;
- int ntuples;
- int tupsize;
- IpcMemoryId shmid;
- HashJoinTable hashtable;
- HashBucket bucket;
- int nbuckets;
- int totalbuckets;
- int bucketsize;
- int i;
- RelativeAddr *outerbatchNames;
- RelativeAddr *outerbatchPos;
- RelativeAddr *innerbatchNames;
- RelativeAddr *innerbatchPos;
- int *innerbatchSizes;
- RelativeAddr tempname;
-
- nbatch = -1;
- HashTBSize = NBuffers/2;
- while (nbatch < 0) {
+ Plan *outerNode;
+ int nbatch;
+ int ntuples;
+ int tupsize;
+ IpcMemoryId shmid;
+ HashJoinTable hashtable;
+ HashBucket bucket;
+ int nbuckets;
+ int totalbuckets;
+ int bucketsize;
+ int i;
+ RelativeAddr *outerbatchNames;
+ RelativeAddr *outerbatchPos;
+ RelativeAddr *innerbatchNames;
+ RelativeAddr *innerbatchPos;
+ int *innerbatchSizes;
+ RelativeAddr tempname;
+
+ nbatch = -1;
+ HashTBSize = NBuffers / 2;
+ while (nbatch < 0)
+ {
+
+ /*
+ * determine number of batches for the hashjoin
+ */
+ HashTBSize *= 2;
+ nbatch = ExecHashPartition(node);
+ }
+ /* ----------------
+ * get information about the size of the relation
+ * ----------------
+ */
+ outerNode = outerPlan(node);
+ ntuples = outerNode->plan_size;
+ if (ntuples <= 0)
+ ntuples = 1000; /* XXX just a hack */
+ tupsize = outerNode->plan_width + sizeof(HeapTupleData);
+
+ /*
+ * totalbuckets is the total number of hash buckets needed for the
+ * entire relation
+ */
+ totalbuckets = ceil((double) ntuples / NTUP_PER_BUCKET);
+ bucketsize = LONGALIGN(NTUP_PER_BUCKET * tupsize + sizeof(*bucket));
+
/*
- * determine number of batches for the hashjoin
- */
- HashTBSize *= 2;
- nbatch = ExecHashPartition(node);
- }
- /* ----------------
- * get information about the size of the relation
- * ----------------
- */
- outerNode = outerPlan(node);
- ntuples = outerNode->plan_size;
- if (ntuples <= 0)
- ntuples = 1000; /* XXX just a hack */
- tupsize = outerNode->plan_width + sizeof(HeapTupleData);
-
- /*
- * totalbuckets is the total number of hash buckets needed for
- * the entire relation
- */
- totalbuckets = ceil((double)ntuples/NTUP_PER_BUCKET);
- bucketsize = LONGALIGN (NTUP_PER_BUCKET * tupsize + sizeof(*bucket));
-
- /*
- * nbuckets is the number of hash buckets for the first pass
- * of hybrid hashjoin
- */
- nbuckets = (HashTBSize - nbatch) * BLCKSZ / (bucketsize * FUDGE_FAC);
- if (totalbuckets < nbuckets)
- totalbuckets = nbuckets;
- if (nbatch == 0)
- nbuckets = totalbuckets;
+ * nbuckets is the number of hash buckets for the first pass of hybrid
+ * hashjoin
+ */
+ nbuckets = (HashTBSize - nbatch) * BLCKSZ / (bucketsize * FUDGE_FAC);
+ if (totalbuckets < nbuckets)
+ totalbuckets = nbuckets;
+ if (nbatch == 0)
+ nbuckets = totalbuckets;
#ifdef HJDEBUG
- printf("nbatch = %d, totalbuckets = %d, nbuckets = %d\n", nbatch, totalbuckets, nbuckets);
+ printf("nbatch = %d, totalbuckets = %d, nbuckets = %d\n", nbatch, totalbuckets, nbuckets);
#endif
-
- /* ----------------
- * in non-parallel machines, we don't need to put the hash table
- * in the shared memory. We just palloc it.
- * ----------------
- */
- hashtable = (HashJoinTable)palloc((HashTBSize+1)*BLCKSZ);
- shmid = 0;
-
- if (hashtable == NULL) {
- elog(WARN, "not enough memory for hashjoin.");
- }
- /* ----------------
- * initialize the hash table header
- * ----------------
- */
- hashtable->nbuckets = nbuckets;
- hashtable->totalbuckets = totalbuckets;
- hashtable->bucketsize = bucketsize;
- hashtable->shmid = shmid;
- hashtable->top = sizeof(HashTableData);
- hashtable->bottom = HashTBSize * BLCKSZ;
- /*
- * hashtable->readbuf has to be long aligned!!!
- */
- hashtable->readbuf = hashtable->bottom;
- hashtable->nbatch = nbatch;
- hashtable->curbatch = 0;
- hashtable->pcount = hashtable->nprocess = 0;
- if (nbatch > 0) {
- /* ---------------
- * allocate and initialize the outer batches
- * ---------------
- */
- outerbatchNames = (RelativeAddr*)ABSADDR(
- hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
- outerbatchPos = (RelativeAddr*)ABSADDR(
- hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
- for (i=0; i<nbatch; i++) {
- tempname = hashTableAlloc(12, hashtable);
- mk_hj_temp(ABSADDR(tempname));
- outerbatchNames[i] = tempname;
- outerbatchPos[i] = -1;
+
+ /* ----------------
+ * in non-parallel machines, we don't need to put the hash table
+ * in the shared memory. We just palloc it.
+ * ----------------
+ */
+ hashtable = (HashJoinTable) palloc((HashTBSize + 1) * BLCKSZ);
+ shmid = 0;
+
+ if (hashtable == NULL)
+ {
+ elog(WARN, "not enough memory for hashjoin.");
+ }
+ /* ----------------
+ * initialize the hash table header
+ * ----------------
+ */
+ hashtable->nbuckets = nbuckets;
+ hashtable->totalbuckets = totalbuckets;
+ hashtable->bucketsize = bucketsize;
+ hashtable->shmid = shmid;
+ hashtable->top = sizeof(HashTableData);
+ hashtable->bottom = HashTBSize * BLCKSZ;
+
+ /*
+ * hashtable->readbuf has to be long aligned!!!
+ */
+ hashtable->readbuf = hashtable->bottom;
+ hashtable->nbatch = nbatch;
+ hashtable->curbatch = 0;
+ hashtable->pcount = hashtable->nprocess = 0;
+ if (nbatch > 0)
+ {
+ /* ---------------
+ * allocate and initialize the outer batches
+ * ---------------
+ */
+ outerbatchNames = (RelativeAddr *) ABSADDR(
+ hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
+ outerbatchPos = (RelativeAddr *) ABSADDR(
+ hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
+ for (i = 0; i < nbatch; i++)
+ {
+ tempname = hashTableAlloc(12, hashtable);
+ mk_hj_temp(ABSADDR(tempname));
+ outerbatchNames[i] = tempname;
+ outerbatchPos[i] = -1;
+ }
+ hashtable->outerbatchNames = RELADDR(outerbatchNames);
+ hashtable->outerbatchPos = RELADDR(outerbatchPos);
+ /* ---------------
+ * allocate and initialize the inner batches
+ * ---------------
+ */
+ innerbatchNames = (RelativeAddr *) ABSADDR(
+ hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
+ innerbatchPos = (RelativeAddr *) ABSADDR(
+ hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
+ innerbatchSizes = (int *) ABSADDR(
+ hashTableAlloc(nbatch * sizeof(int), hashtable));
+ for (i = 0; i < nbatch; i++)
+ {
+ tempname = hashTableAlloc(12, hashtable);
+ mk_hj_temp(ABSADDR(tempname));
+ innerbatchNames[i] = tempname;
+ innerbatchPos[i] = -1;
+ innerbatchSizes[i] = 0;
+ }
+ hashtable->innerbatchNames = RELADDR(innerbatchNames);
+ hashtable->innerbatchPos = RELADDR(innerbatchPos);
+ hashtable->innerbatchSizes = RELADDR(innerbatchSizes);
}
- hashtable->outerbatchNames = RELADDR(outerbatchNames);
- hashtable->outerbatchPos = RELADDR(outerbatchPos);
- /* ---------------
- * allocate and initialize the inner batches
- * ---------------
- */
- innerbatchNames = (RelativeAddr*)ABSADDR(
- hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
- innerbatchPos = (RelativeAddr*)ABSADDR(
- hashTableAlloc(nbatch * sizeof(RelativeAddr), hashtable));
- innerbatchSizes = (int*)ABSADDR(
- hashTableAlloc(nbatch * sizeof(int), hashtable));
- for (i=0; i<nbatch; i++) {
- tempname = hashTableAlloc(12, hashtable);
- mk_hj_temp(ABSADDR(tempname));
- innerbatchNames[i] = tempname;
- innerbatchPos[i] = -1;
- innerbatchSizes[i] = 0;
+ else
+ {
+ hashtable->outerbatchNames = (RelativeAddr) NULL;
+ hashtable->outerbatchPos = (RelativeAddr) NULL;
+ hashtable->innerbatchNames = (RelativeAddr) NULL;
+ hashtable->innerbatchPos = (RelativeAddr) NULL;
+ hashtable->innerbatchSizes = (RelativeAddr) NULL;
}
- hashtable->innerbatchNames = RELADDR(innerbatchNames);
- hashtable->innerbatchPos = RELADDR(innerbatchPos);
- hashtable->innerbatchSizes = RELADDR(innerbatchSizes);
- }
- else {
- hashtable->outerbatchNames = (RelativeAddr)NULL;
- hashtable->outerbatchPos = (RelativeAddr)NULL;
- hashtable->innerbatchNames = (RelativeAddr)NULL;
- hashtable->innerbatchPos = (RelativeAddr)NULL;
- hashtable->innerbatchSizes = (RelativeAddr)NULL;
- }
-
- hashtable->batch = (RelativeAddr)LONGALIGN(hashtable->top +
- bucketsize * nbuckets);
- hashtable->overflownext=hashtable->batch + nbatch * BLCKSZ;
- /* ----------------
- * initialize each hash bucket
- * ----------------
- */
- bucket = (HashBucket)ABSADDR(hashtable->top);
- for (i=0; i<nbuckets; i++) {
- bucket->top = RELADDR((char*)bucket + sizeof(*bucket));
- bucket->bottom = bucket->top;
- bucket->firstotuple = bucket->lastotuple = -1;
- bucket = (HashBucket)LONGALIGN(((char*)bucket + bucketsize));
- }
- return(hashtable);
+
+ hashtable->batch = (RelativeAddr) LONGALIGN(hashtable->top +
+ bucketsize * nbuckets);
+ hashtable->overflownext = hashtable->batch + nbatch * BLCKSZ;
+ /* ----------------
+ * initialize each hash bucket
+ * ----------------
+ */
+ bucket = (HashBucket) ABSADDR(hashtable->top);
+ for (i = 0; i < nbuckets; i++)
+ {
+ bucket->top = RELADDR((char *) bucket + sizeof(*bucket));
+ bucket->bottom = bucket->top;
+ bucket->firstotuple = bucket->lastotuple = -1;
+ bucket = (HashBucket) LONGALIGN(((char *) bucket + bucketsize));
+ }
+ return (hashtable);
}
/* ----------------------------------------------------------------
- * ExecHashTableInsert
+ * ExecHashTableInsert
*
- * insert a tuple into the hash table depending on the hash value
- * it may just go to a tmp file for other batches
+ * insert a tuple into the hash table depending on the hash value
+ * it may just go to a tmp file for other batches
* ----------------------------------------------------------------
*/
void
ExecHashTableInsert(HashJoinTable hashtable,
- ExprContext *econtext,
- Var *hashkey,
- File *batches)
+ ExprContext * econtext,
+ Var * hashkey,
+ File * batches)
{
- TupleTableSlot *slot;
- HeapTuple heapTuple;
- HashBucket bucket;
- int bucketno;
- int nbatch;
- int batchno;
- char *buffer;
- RelativeAddr *batchPos;
- int *batchSizes;
- char *pos;
-
- nbatch = hashtable->nbatch;
- batchPos = (RelativeAddr*)ABSADDR(hashtable->innerbatchPos);
- batchSizes = (int*)ABSADDR(hashtable->innerbatchSizes);
-
- slot = econtext->ecxt_innertuple;
- heapTuple = slot->val;
-
+ TupleTableSlot *slot;
+ HeapTuple heapTuple;
+ HashBucket bucket;
+ int bucketno;
+ int nbatch;
+ int batchno;
+ char *buffer;
+ RelativeAddr *batchPos;
+ int *batchSizes;
+ char *pos;
+
+ nbatch = hashtable->nbatch;
+ batchPos = (RelativeAddr *) ABSADDR(hashtable->innerbatchPos);
+ batchSizes = (int *) ABSADDR(hashtable->innerbatchSizes);
+
+ slot = econtext->ecxt_innertuple;
+ heapTuple = slot->val;
+
#ifdef HJDEBUG
- printf("Inserting ");
+ printf("Inserting ");
#endif
-
- bucketno = ExecHashGetBucket(hashtable, econtext, hashkey);
-
- /* ----------------
- * decide whether to put the tuple in the hash table or a tmp file
- * ----------------
- */
- if (bucketno < hashtable->nbuckets) {
- /* ---------------
- * put the tuple in hash table
- * ---------------
- */
- bucket = (HashBucket)
- (ABSADDR(hashtable->top) + bucketno * hashtable->bucketsize);
- if ((char*)LONGALIGN(ABSADDR(bucket->bottom))
- -(char*)bucket+heapTuple->t_len > hashtable->bucketsize)
- ExecHashOverflowInsert(hashtable, bucket, heapTuple);
- else {
- memmove((char*)LONGALIGN(ABSADDR(bucket->bottom)),
- heapTuple,
- heapTuple->t_len);
- bucket->bottom =
- ((RelativeAddr)LONGALIGN(bucket->bottom) + heapTuple->t_len);
+
+ bucketno = ExecHashGetBucket(hashtable, econtext, hashkey);
+
+ /* ----------------
+ * decide whether to put the tuple in the hash table or a tmp file
+ * ----------------
+ */
+ if (bucketno < hashtable->nbuckets)
+ {
+ /* ---------------
+ * put the tuple in hash table
+ * ---------------
+ */
+ bucket = (HashBucket)
+ (ABSADDR(hashtable->top) + bucketno * hashtable->bucketsize);
+ if ((char *) LONGALIGN(ABSADDR(bucket->bottom))
+ - (char *) bucket + heapTuple->t_len > hashtable->bucketsize)
+ ExecHashOverflowInsert(hashtable, bucket, heapTuple);
+ else
+ {
+ memmove((char *) LONGALIGN(ABSADDR(bucket->bottom)),
+ heapTuple,
+ heapTuple->t_len);
+ bucket->bottom =
+ ((RelativeAddr) LONGALIGN(bucket->bottom) + heapTuple->t_len);
+ }
+ }
+ else
+ {
+ /* -----------------
+ * put the tuple into a tmp file for other batches
+ * -----------------
+ */
+ batchno = (float) (bucketno - hashtable->nbuckets) /
+ (float) (hashtable->totalbuckets - hashtable->nbuckets)
+ * nbatch;
+ buffer = ABSADDR(hashtable->batch) + batchno * BLCKSZ;
+ batchSizes[batchno]++;
+ pos = (char *)
+ ExecHashJoinSaveTuple(heapTuple,
+ buffer,
+ batches[batchno],
+ (char *) ABSADDR(batchPos[batchno]));
+ batchPos[batchno] = RELADDR(pos);
}
- }
- else {
- /* -----------------
- * put the tuple into a tmp file for other batches
- * -----------------
- */
- batchno = (float)(bucketno - hashtable->nbuckets)/
- (float)(hashtable->totalbuckets - hashtable->nbuckets)
- * nbatch;
- buffer = ABSADDR(hashtable->batch) + batchno * BLCKSZ;
- batchSizes[batchno]++;
- pos= (char *)
- ExecHashJoinSaveTuple(heapTuple,
- buffer,
- batches[batchno],
- (char*)ABSADDR(batchPos[batchno]));
- batchPos[batchno] = RELADDR(pos);
- }
}
/* ----------------------------------------------------------------
- * ExecHashTableDestroy
+ * ExecHashTableDestroy
*
- * destroy a hash table
+ * destroy a hash table
* ----------------------------------------------------------------
*/
void
ExecHashTableDestroy(HashJoinTable hashtable)
{
- pfree(hashtable);
+ pfree(hashtable);
}
/* ----------------------------------------------------------------
- * ExecHashGetBucket
+ * ExecHashGetBucket
*
- * Get the hash value for a tuple
+ * Get the hash value for a tuple
* ----------------------------------------------------------------
*/
int
ExecHashGetBucket(HashJoinTable hashtable,
- ExprContext *econtext,
- Var *hashkey)
+ ExprContext * econtext,
+ Var * hashkey)
{
- int bucketno;
- Datum keyval;
- bool isNull;
-
-
- /* ----------------
- * Get the join attribute value of the tuple
- * ----------------
- * ...It's quick hack - use ExecEvalExpr instead of ExecEvalVar:
- * hashkey may be T_ArrayRef, not just T_Var. - vadim 04/22/97
- */
- keyval = ExecEvalExpr((Node*)hashkey, econtext, &isNull, NULL);
-
- /*
- * keyval could be null, so we better point it to something
- * valid before trying to run hashFunc on it. --djm 8/17/96
- */
- if(isNull) {
- execConstByVal = 0;
- execConstLen = 0;
- keyval = (Datum)"";
- }
-
- /* ------------------
- * compute the hash function
- * ------------------
- */
- if (execConstByVal)
- bucketno =
- hashFunc((char *) &keyval, execConstLen) % hashtable->totalbuckets;
- else
- bucketno =
- hashFunc((char *) keyval, execConstLen) % hashtable->totalbuckets;
+ int bucketno;
+ Datum keyval;
+ bool isNull;
+
+
+ /* ----------------
+ * Get the join attribute value of the tuple
+ * ----------------
+ * ...It's quick hack - use ExecEvalExpr instead of ExecEvalVar:
+ * hashkey may be T_ArrayRef, not just T_Var. - vadim 04/22/97
+ */
+ keyval = ExecEvalExpr((Node *) hashkey, econtext, &isNull, NULL);
+
+ /*
+ * keyval could be null, so we better point it to something valid
+ * before trying to run hashFunc on it. --djm 8/17/96
+ */
+ if (isNull)
+ {
+ execConstByVal = 0;
+ execConstLen = 0;
+ keyval = (Datum) "";
+ }
+
+ /* ------------------
+ * compute the hash function
+ * ------------------
+ */
+ if (execConstByVal)
+ bucketno =
+ hashFunc((char *) &keyval, execConstLen) % hashtable->totalbuckets;
+ else
+ bucketno =
+ hashFunc((char *) keyval, execConstLen) % hashtable->totalbuckets;
#ifdef HJDEBUG
- if (bucketno >= hashtable->nbuckets)
- printf("hash(%d) = %d SAVED\n", keyval, bucketno);
- else
- printf("hash(%d) = %d\n", keyval, bucketno);
+ if (bucketno >= hashtable->nbuckets)
+ printf("hash(%d) = %d SAVED\n", keyval, bucketno);
+ else
+ printf("hash(%d) = %d\n", keyval, bucketno);
#endif
-
- return(bucketno);
+
+ return (bucketno);
}
/* ----------------------------------------------------------------
- * ExecHashOverflowInsert
+ * ExecHashOverflowInsert
*
- * insert into the overflow area of a hash bucket
+ * insert into the overflow area of a hash bucket
* ----------------------------------------------------------------
*/
static void
ExecHashOverflowInsert(HashJoinTable hashtable,
- HashBucket bucket,
- HeapTuple heapTuple)
+ HashBucket bucket,
+ HeapTuple heapTuple)
{
- OverflowTuple otuple;
- RelativeAddr newend;
- OverflowTuple firstotuple;
- OverflowTuple lastotuple;
-
- firstotuple = (OverflowTuple)ABSADDR(bucket->firstotuple);
- lastotuple = (OverflowTuple)ABSADDR(bucket->lastotuple);
- /* ----------------
- * see if we run out of overflow space
- * ----------------
- */
- newend = (RelativeAddr)LONGALIGN(hashtable->overflownext + sizeof(*otuple)
- + heapTuple->t_len);
- if (newend > hashtable->bottom) {
-#if 0
- elog(DEBUG, "hash table out of memory. expanding.");
- /* ------------------
- * XXX this is a temporary hack
- * eventually, recursive hash partitioning will be
- * implemented
- * ------------------
+ OverflowTuple otuple;
+ RelativeAddr newend;
+ OverflowTuple firstotuple;
+ OverflowTuple lastotuple;
+
+ firstotuple = (OverflowTuple) ABSADDR(bucket->firstotuple);
+ lastotuple = (OverflowTuple) ABSADDR(bucket->lastotuple);
+ /* ----------------
+ * see if we run out of overflow space
+ * ----------------
*/
- hashtable->readbuf = hashtable->bottom = 2 * hashtable->bottom;
- hashtable =
- (HashJoinTable)repalloc(hashtable, hashtable->bottom+BLCKSZ);
- if (hashtable == NULL) {
- perror("repalloc");
- elog(WARN, "can't expand hashtable.");
- }
+ newend = (RelativeAddr) LONGALIGN(hashtable->overflownext + sizeof(*otuple)
+ + heapTuple->t_len);
+ if (newend > hashtable->bottom)
+ {
+#if 0
+ elog(DEBUG, "hash table out of memory. expanding.");
+ /* ------------------
+ * XXX this is a temporary hack
+ * eventually, recursive hash partitioning will be
+ * implemented
+ * ------------------
+ */
+ hashtable->readbuf = hashtable->bottom = 2 * hashtable->bottom;
+ hashtable =
+ (HashJoinTable) repalloc(hashtable, hashtable->bottom + BLCKSZ);
+ if (hashtable == NULL)
+ {
+ perror("repalloc");
+ elog(WARN, "can't expand hashtable.");
+ }
#else
- /* ------------------
- * XXX the temporary hack above doesn't work because things
- * above us don't know that we've moved the hash table!
- * - Chris Dunlop, <chris@onthe.net.au>
- * ------------------
- */
- elog(WARN, "hash table out of memory. Use -B parameter to increase buffers.");
+ /* ------------------
+ * XXX the temporary hack above doesn't work because things
+ * above us don't know that we've moved the hash table!
+ * - Chris Dunlop, <chris@onthe.net.au>
+ * ------------------
+ */
+ elog(WARN, "hash table out of memory. Use -B parameter to increase buffers.");
#endif
- }
-
- /* ----------------
- * establish the overflow chain
- * ----------------
- */
- otuple = (OverflowTuple)ABSADDR(hashtable->overflownext);
- hashtable->overflownext = newend;
- if (firstotuple == NULL)
- bucket->firstotuple = bucket->lastotuple = RELADDR(otuple);
- else {
- lastotuple->next = RELADDR(otuple);
- bucket->lastotuple = RELADDR(otuple);
- }
-
- /* ----------------
- * copy the tuple into the overflow area
- * ----------------
- */
- otuple->next = -1;
- otuple->tuple = RELADDR(LONGALIGN(((char*)otuple + sizeof(*otuple))));
- memmove(ABSADDR(otuple->tuple),
- heapTuple,
- heapTuple->t_len);
+ }
+
+ /* ----------------
+ * establish the overflow chain
+ * ----------------
+ */
+ otuple = (OverflowTuple) ABSADDR(hashtable->overflownext);
+ hashtable->overflownext = newend;
+ if (firstotuple == NULL)
+ bucket->firstotuple = bucket->lastotuple = RELADDR(otuple);
+ else
+ {
+ lastotuple->next = RELADDR(otuple);
+ bucket->lastotuple = RELADDR(otuple);
+ }
+
+ /* ----------------
+ * copy the tuple into the overflow area
+ * ----------------
+ */
+ otuple->next = -1;
+ otuple->tuple = RELADDR(LONGALIGN(((char *) otuple + sizeof(*otuple))));
+ memmove(ABSADDR(otuple->tuple),
+ heapTuple,
+ heapTuple->t_len);
}
/* ----------------------------------------------------------------
- * ExecScanHashBucket
+ * ExecScanHashBucket
*
- * scan a hash bucket of matches
+ * scan a hash bucket of matches
* ----------------------------------------------------------------
*/
HeapTuple
-ExecScanHashBucket(HashJoinState *hjstate,
- HashBucket bucket,
- HeapTuple curtuple,
- List *hjclauses,
- ExprContext *econtext)
+ExecScanHashBucket(HashJoinState * hjstate,
+ HashBucket bucket,
+ HeapTuple curtuple,
+ List * hjclauses,
+ ExprContext * econtext)
{
- HeapTuple heapTuple;
- bool qualResult;
- OverflowTuple otuple = NULL;
- OverflowTuple curotuple;
- TupleTableSlot *inntuple;
- OverflowTuple firstotuple;
- OverflowTuple lastotuple;
- HashJoinTable hashtable;
-
- hashtable = hjstate->hj_HashTable;
- firstotuple = (OverflowTuple)ABSADDR(bucket->firstotuple);
- lastotuple = (OverflowTuple)ABSADDR(bucket->lastotuple);
-
- /* ----------------
- * search the hash bucket
- * ----------------
- */
- if (curtuple == NULL || curtuple < (HeapTuple)ABSADDR(bucket->bottom)) {
- if (curtuple == NULL)
- heapTuple = (HeapTuple)
- LONGALIGN(ABSADDR(bucket->top));
- else
- heapTuple = (HeapTuple)
- LONGALIGN(((char*)curtuple+curtuple->t_len));
-
- while (heapTuple < (HeapTuple)ABSADDR(bucket->bottom)) {
-
- inntuple = ExecStoreTuple(heapTuple, /* tuple to store */
- hjstate->hj_HashTupleSlot, /* slot */
- InvalidBuffer,/* tuple has no buffer */
- false); /* do not pfree this tuple */
-
- econtext->ecxt_innertuple = inntuple;
- qualResult = ExecQual((List*)hjclauses, econtext);
-
- if (qualResult)
- return heapTuple;
-
- heapTuple = (HeapTuple)
- LONGALIGN(((char*)heapTuple+heapTuple->t_len));
+ HeapTuple heapTuple;
+ bool qualResult;
+ OverflowTuple otuple = NULL;
+ OverflowTuple curotuple;
+ TupleTableSlot *inntuple;
+ OverflowTuple firstotuple;
+ OverflowTuple lastotuple;
+ HashJoinTable hashtable;
+
+ hashtable = hjstate->hj_HashTable;
+ firstotuple = (OverflowTuple) ABSADDR(bucket->firstotuple);
+ lastotuple = (OverflowTuple) ABSADDR(bucket->lastotuple);
+
+ /* ----------------
+ * search the hash bucket
+ * ----------------
+ */
+ if (curtuple == NULL || curtuple < (HeapTuple) ABSADDR(bucket->bottom))
+ {
+ if (curtuple == NULL)
+ heapTuple = (HeapTuple)
+ LONGALIGN(ABSADDR(bucket->top));
+ else
+ heapTuple = (HeapTuple)
+ LONGALIGN(((char *) curtuple + curtuple->t_len));
+
+ while (heapTuple < (HeapTuple) ABSADDR(bucket->bottom))
+ {
+
+ inntuple = ExecStoreTuple(heapTuple, /* tuple to store */
+ hjstate->hj_HashTupleSlot, /* slot */
+ InvalidBuffer, /* tuple has no buffer */
+ false); /* do not pfree this tuple */
+
+ econtext->ecxt_innertuple = inntuple;
+ qualResult = ExecQual((List *) hjclauses, econtext);
+
+ if (qualResult)
+ return heapTuple;
+
+ heapTuple = (HeapTuple)
+ LONGALIGN(((char *) heapTuple + heapTuple->t_len));
+ }
+
+ if (firstotuple == NULL)
+ return NULL;
+ otuple = firstotuple;
}
-
- if (firstotuple == NULL)
- return NULL;
- otuple = firstotuple;
- }
-
- /* ----------------
- * search the overflow area of the hash bucket
- * ----------------
- */
- if (otuple == NULL) {
- curotuple = hjstate->hj_CurOTuple;
- otuple = (OverflowTuple)ABSADDR(curotuple->next);
- }
-
- while (otuple != NULL) {
- heapTuple = (HeapTuple)ABSADDR(otuple->tuple);
-
- inntuple = ExecStoreTuple(heapTuple, /* tuple to store */
- hjstate->hj_HashTupleSlot, /* slot */
- InvalidBuffer, /* SP?? this tuple has no buffer */
- false); /* do not pfree this tuple */
-
- econtext->ecxt_innertuple = inntuple;
- qualResult = ExecQual((List*)hjclauses, econtext);
-
- if (qualResult) {
- hjstate->hj_CurOTuple = otuple;
- return heapTuple;
+
+ /* ----------------
+ * search the overflow area of the hash bucket
+ * ----------------
+ */
+ if (otuple == NULL)
+ {
+ curotuple = hjstate->hj_CurOTuple;
+ otuple = (OverflowTuple) ABSADDR(curotuple->next);
+ }
+
+ while (otuple != NULL)
+ {
+ heapTuple = (HeapTuple) ABSADDR(otuple->tuple);
+
+ inntuple = ExecStoreTuple(heapTuple, /* tuple to store */
+ hjstate->hj_HashTupleSlot, /* slot */
+ InvalidBuffer, /* SP?? this tuple has
+ * no buffer */
+ false); /* do not pfree this tuple */
+
+ econtext->ecxt_innertuple = inntuple;
+ qualResult = ExecQual((List *) hjclauses, econtext);
+
+ if (qualResult)
+ {
+ hjstate->hj_CurOTuple = otuple;
+ return heapTuple;
+ }
+
+ otuple = (OverflowTuple) ABSADDR(otuple->next);
}
-
- otuple = (OverflowTuple)ABSADDR(otuple->next);
- }
-
- /* ----------------
- * no match
- * ----------------
- */
- return NULL;
+
+ /* ----------------
+ * no match
+ * ----------------
+ */
+ return NULL;
}
/* ----------------------------------------------------------------
- * hashFunc
+ * hashFunc
*
- * the hash function, copied from Margo
+ * the hash function, copied from Margo
* ----------------------------------------------------------------
*/
static int
hashFunc(char *key, int len)
{
- register unsigned int h;
- register int l;
- register unsigned char *k;
-
- /*
- * If this is a variable length type, then 'k' points
- * to a "struct varlena" and len == -1.
- * NOTE:
- * VARSIZE returns the "real" data length plus the sizeof the
- * "vl_len" attribute of varlena (the length information).
- * 'k' points to the beginning of the varlena struct, so
- * we have to use "VARDATA" to find the beginning of the "real"
- * data.
- */
- if (len == -1) {
- l = VARSIZE(key) - VARHDRSZ;
- k = (unsigned char*) VARDATA(key);
- } else {
- l = len;
- k = (unsigned char *) key;
- }
-
- h = 0;
-
- /*
- * Convert string to integer
- */
- while (l--) h = h * PRIME1 ^ (*k++);
- h %= PRIME2;
-
- return (h);
+ register unsigned int h;
+ register int l;
+ register unsigned char *k;
+
+ /*
+ * If this is a variable length type, then 'k' points to a "struct
+ * varlena" and len == -1. NOTE: VARSIZE returns the "real" data
+ * length plus the sizeof the "vl_len" attribute of varlena (the
+ * length information). 'k' points to the beginning of the varlena
+ * struct, so we have to use "VARDATA" to find the beginning of the
+ * "real" data.
+ */
+ if (len == -1)
+ {
+ l = VARSIZE(key) - VARHDRSZ;
+ k = (unsigned char *) VARDATA(key);
+ }
+ else
+ {
+ l = len;
+ k = (unsigned char *) key;
+ }
+
+ h = 0;
+
+ /*
+ * Convert string to integer
+ */
+ while (l--)
+ h = h * PRIME1 ^ (*k++);
+ h %= PRIME2;
+
+ return (h);
}
/* ----------------------------------------------------------------
- * ExecHashPartition
+ * ExecHashPartition
*
- * determine the number of batches needed for a hashjoin
+ * determine the number of batches needed for a hashjoin
* ----------------------------------------------------------------
*/
static int
-ExecHashPartition(Hash *node)
+ExecHashPartition(Hash * node)
{
- Plan *outerNode;
- int b;
- int pages;
- int ntuples;
- int tupsize;
-
- /*
- * get size information for plan node
- */
- outerNode = outerPlan(node);
- ntuples = outerNode->plan_size;
- if (ntuples == 0) ntuples = 1000;
- tupsize = outerNode->plan_width + sizeof(HeapTupleData);
- pages = ceil((double)ntuples * tupsize * FUDGE_FAC / BLCKSZ);
-
- /*
- * if amount of buffer space below hashjoin threshold,
- * return negative
- */
- if (ceil(sqrt((double)pages)) > HashTBSize)
- return -1;
- if (pages <= HashTBSize)
- b = 0; /* fit in memory, no partitioning */
- else
- b = ceil((double)(pages - HashTBSize)/(double)(HashTBSize - 1));
-
- return b;
+ Plan *outerNode;
+ int b;
+ int pages;
+ int ntuples;
+ int tupsize;
+
+ /*
+ * get size information for plan node
+ */
+ outerNode = outerPlan(node);
+ ntuples = outerNode->plan_size;
+ if (ntuples == 0)
+ ntuples = 1000;
+ tupsize = outerNode->plan_width + sizeof(HeapTupleData);
+ pages = ceil((double) ntuples * tupsize * FUDGE_FAC / BLCKSZ);
+
+ /*
+ * if amount of buffer space below hashjoin threshold, return negative
+ */
+ if (ceil(sqrt((double) pages)) > HashTBSize)
+ return -1;
+ if (pages <= HashTBSize)
+ b = 0; /* fit in memory, no partitioning */
+ else
+ b = ceil((double) (pages - HashTBSize) / (double) (HashTBSize - 1));
+
+ return b;
}
/* ----------------------------------------------------------------
- * ExecHashTableReset
+ * ExecHashTableReset
*
- * reset hash table header for new batch
+ * reset hash table header for new batch
* ----------------------------------------------------------------
*/
void
ExecHashTableReset(HashJoinTable hashtable, int ntuples)
{
- int i;
- HashBucket bucket;
-
- hashtable->nbuckets = hashtable->totalbuckets
- = ceil((double)ntuples/NTUP_PER_BUCKET);
-
- hashtable->overflownext = hashtable->top + hashtable->bucketsize *
- hashtable->nbuckets;
-
- bucket = (HashBucket)ABSADDR(hashtable->top);
- for (i=0; i<hashtable->nbuckets; i++) {
- bucket->top = RELADDR((char*)bucket + sizeof(*bucket));
- bucket->bottom = bucket->top;
- bucket->firstotuple = bucket->lastotuple = -1;
- bucket = (HashBucket)((char*)bucket + hashtable->bucketsize);
- }
- hashtable->pcount = hashtable->nprocess;
+ int i;
+ HashBucket bucket;
+
+ hashtable->nbuckets = hashtable->totalbuckets
+ = ceil((double) ntuples / NTUP_PER_BUCKET);
+
+ hashtable->overflownext = hashtable->top + hashtable->bucketsize *
+ hashtable->nbuckets;
+
+ bucket = (HashBucket) ABSADDR(hashtable->top);
+ for (i = 0; i < hashtable->nbuckets; i++)
+ {
+ bucket->top = RELADDR((char *) bucket + sizeof(*bucket));
+ bucket->bottom = bucket->top;
+ bucket->firstotuple = bucket->lastotuple = -1;
+ bucket = (HashBucket) ((char *) bucket + hashtable->bucketsize);
+ }
+ hashtable->pcount = hashtable->nprocess;
}
-static int hjtmpcnt = 0;
+static int hjtmpcnt = 0;
static void
mk_hj_temp(char *tempname)
{
- sprintf(tempname, "HJ%d.%d", (int)getpid(), hjtmpcnt);
- hjtmpcnt = (hjtmpcnt + 1) % 1000;
+ sprintf(tempname, "HJ%d.%d", (int) getpid(), hjtmpcnt);
+ hjtmpcnt = (hjtmpcnt + 1) % 1000;
}
-
-
-
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index c9f24efe193..3548e38cc86 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* nodeHashjoin.c--
- * Routines to handle hash join nodes
+ * Routines to handle hash join nodes
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.5 1997/08/19 21:31:09 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.6 1997/09/07 04:41:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,8 +20,8 @@
#include "postgres.h"
-#include "storage/bufmgr.h" /* for BLCKSZ */
-#include "storage/fd.h" /* for SEEK_ */
+#include "storage/bufmgr.h" /* for BLCKSZ */
+#include "storage/fd.h" /* for SEEK_ */
#include "executor/executor.h"
#include "executor/execdebug.h"
#include "executor/nodeHash.h"
@@ -33,775 +33,818 @@
#include "utils/palloc.h"
static TupleTableSlot *
-ExecHashJoinOuterGetTuple(Plan *node, Plan* parent, HashJoinState *hjstate);
+ ExecHashJoinOuterGetTuple(Plan * node, Plan * parent, HashJoinState * hjstate);
static TupleTableSlot *
-ExecHashJoinGetSavedTuple(HashJoinState *hjstate, char *buffer,
- File file, TupleTableSlot *tupleSlot, int *block, char **position);
+ExecHashJoinGetSavedTuple(HashJoinState * hjstate, char *buffer,
+ File file, TupleTableSlot * tupleSlot, int *block, char **position);
-static int ExecHashJoinGetBatch(int bucketno, HashJoinTable hashtable,
- int nbatch);
+static int
+ExecHashJoinGetBatch(int bucketno, HashJoinTable hashtable,
+ int nbatch);
-static int ExecHashJoinNewBatch(HashJoinState *hjstate);
+static int ExecHashJoinNewBatch(HashJoinState * hjstate);
/* ----------------------------------------------------------------
- * ExecHashJoin
+ * ExecHashJoin
*
- * This function implements the Hybrid Hashjoin algorithm.
- * recursive partitioning remains to be added.
- * Note: the relation we build hash table on is the inner
- * the other one is outer.
+ * This function implements the Hybrid Hashjoin algorithm.
+ * recursive partitioning remains to be added.
+ * Note: the relation we build hash table on is the inner
+ * the other one is outer.
* ----------------------------------------------------------------
*/
-TupleTableSlot * /* return: a tuple or NULL */
-ExecHashJoin(HashJoin *node)
+TupleTableSlot * /* return: a tuple or NULL */
+ExecHashJoin(HashJoin * node)
{
- HashJoinState *hjstate;
- EState *estate;
- Plan *outerNode;
- Hash *hashNode;
- List *hjclauses;
- Expr *clause;
- List *qual;
- ScanDirection dir;
- TupleTableSlot *inntuple;
- Var *outerVar;
- ExprContext *econtext;
-
- HashJoinTable hashtable;
- int bucketno;
- HashBucket bucket;
- HeapTuple curtuple;
-
- bool qualResult;
-
- TupleTableSlot *outerTupleSlot;
- TupleTableSlot *innerTupleSlot;
- int nbatch;
- int curbatch;
- File *outerbatches;
- RelativeAddr *outerbatchNames;
- RelativeAddr *outerbatchPos;
- Var *innerhashkey;
- int batch;
- int batchno;
- char *buffer;
- int i;
- bool hashPhaseDone;
- char *pos;
-
- /* ----------------
- * get information from HashJoin node
- * ----------------
- */
- hjstate = node->hashjoinstate;
- hjclauses = node->hashclauses;
- clause = lfirst(hjclauses);
- estate = node->join.state;
- qual = node->join.qual;
- hashNode = (Hash *)innerPlan(node);
- outerNode = outerPlan(node);
- hashPhaseDone = node->hashdone;
-
- dir = estate->es_direction;
-
- /* -----------------
- * get information from HashJoin state
- * -----------------
- */
- hashtable = hjstate->hj_HashTable;
- bucket = hjstate->hj_CurBucket;
- curtuple = hjstate->hj_CurTuple;
-
- /* --------------------
- * initialize expression context
- * --------------------
- */
- econtext = hjstate->jstate.cs_ExprContext;
-
- if (hjstate->jstate.cs_TupFromTlist) {
- TupleTableSlot *result;
- bool isDone;
-
- result = ExecProject(hjstate->jstate.cs_ProjInfo, &isDone);
- if (!isDone)
- return result;
- }
- /* ----------------
- * if this is the first call, build the hash table for inner relation
- * ----------------
- */
- if (!hashPhaseDone) { /* if the hash phase not completed */
- hashtable = node->hashjointable;
- if (hashtable == NULL) { /* if the hash table has not been created */
- /* ----------------
- * create the hash table
- * ----------------
- */
- hashtable = ExecHashTableCreate(hashNode);
- hjstate->hj_HashTable = hashtable;
- innerhashkey = hashNode->hashkey;
- hjstate->hj_InnerHashKey = innerhashkey;
-
- /* ----------------
- * execute the Hash node, to build the hash table
- * ----------------
- */
- hashNode->hashtable = hashtable;
- innerTupleSlot = ExecProcNode((Plan *)hashNode, (Plan*) node);
- }
- bucket = NULL;
- curtuple = NULL;
- curbatch = 0;
- node->hashdone = true;
- }
- nbatch = hashtable->nbatch;
- outerbatches = hjstate->hj_OuterBatches;
- if (nbatch > 0 && outerbatches == NULL) { /* if needs hash partition */
+ HashJoinState *hjstate;
+ EState *estate;
+ Plan *outerNode;
+ Hash *hashNode;
+ List *hjclauses;
+ Expr *clause;
+ List *qual;
+ ScanDirection dir;
+ TupleTableSlot *inntuple;
+ Var *outerVar;
+ ExprContext *econtext;
+
+ HashJoinTable hashtable;
+ int bucketno;
+ HashBucket bucket;
+ HeapTuple curtuple;
+
+ bool qualResult;
+
+ TupleTableSlot *outerTupleSlot;
+ TupleTableSlot *innerTupleSlot;
+ int nbatch;
+ int curbatch;
+ File *outerbatches;
+ RelativeAddr *outerbatchNames;
+ RelativeAddr *outerbatchPos;
+ Var *innerhashkey;
+ int batch;
+ int batchno;
+ char *buffer;
+ int i;
+ bool hashPhaseDone;
+ char *pos;
+
+ /* ----------------
+ * get information from HashJoin node
+ * ----------------
+ */
+ hjstate = node->hashjoinstate;
+ hjclauses = node->hashclauses;
+ clause = lfirst(hjclauses);
+ estate = node->join.state;
+ qual = node->join.qual;
+ hashNode = (Hash *) innerPlan(node);
+ outerNode = outerPlan(node);
+ hashPhaseDone = node->hashdone;
+
+ dir = estate->es_direction;
+
/* -----------------
- * allocate space for file descriptors of outer batch files
- * then open the batch files in the current process
+ * get information from HashJoin state
* -----------------
*/
- innerhashkey = hashNode->hashkey;
- hjstate->hj_InnerHashKey = innerhashkey;
- outerbatchNames = (RelativeAddr*)
- ABSADDR(hashtable->outerbatchNames);
- outerbatches = (File*)
- palloc(nbatch * sizeof(File));
- for (i=0; i<nbatch; i++) {
- outerbatches[i] = FileNameOpenFile(
- ABSADDR(outerbatchNames[i]),
- O_CREAT | O_RDWR, 0600);
- }
- hjstate->hj_OuterBatches = outerbatches;
+ hashtable = hjstate->hj_HashTable;
+ bucket = hjstate->hj_CurBucket;
+ curtuple = hjstate->hj_CurTuple;
- /* ------------------
- * get the inner batch file descriptors from the
- * hash node
- * ------------------
- */
- hjstate->hj_InnerBatches =
- hashNode->hashstate->hashBatches;
- }
- outerbatchPos = (RelativeAddr*)ABSADDR(hashtable->outerbatchPos);
- curbatch = hashtable->curbatch;
- outerbatchNames = (RelativeAddr*)ABSADDR(hashtable->outerbatchNames);
-
- /* ----------------
- * Now get an outer tuple and probe into the hash table for matches
- * ----------------
- */
- outerTupleSlot = hjstate->jstate.cs_OuterTupleSlot;
- outerVar = get_leftop(clause);
-
- bucketno = -1; /* if bucketno remains -1, means use old outer tuple */
- if (TupIsNull(outerTupleSlot)) {
- /*
- * if the current outer tuple is nil, get a new one
+ /* --------------------
+ * initialize expression context
+ * --------------------
*/
- outerTupleSlot = (TupleTableSlot*)
- ExecHashJoinOuterGetTuple(outerNode, (Plan*)node, hjstate);
-
- while (curbatch <= nbatch && TupIsNull(outerTupleSlot)) {
- /*
- * if the current batch runs out, switch to new batch
- */
- curbatch = ExecHashJoinNewBatch(hjstate);
- if (curbatch > nbatch) {
- /*
- * when the last batch runs out, clean up
- */
- ExecHashTableDestroy(hashtable);
- hjstate->hj_HashTable = NULL;
- return NULL;
- }
- else
- outerTupleSlot = (TupleTableSlot*)
- ExecHashJoinOuterGetTuple(outerNode, (Plan*)node, hjstate);
+ econtext = hjstate->jstate.cs_ExprContext;
+
+ if (hjstate->jstate.cs_TupFromTlist)
+ {
+ TupleTableSlot *result;
+ bool isDone;
+
+ result = ExecProject(hjstate->jstate.cs_ProjInfo, &isDone);
+ if (!isDone)
+ return result;
}
- /*
- * now we get an outer tuple, find the corresponding bucket for
- * this tuple from the hash table
- */
- econtext->ecxt_outertuple = outerTupleSlot;
-
-#ifdef HJDEBUG
- printf("Probing ");
-#endif
- bucketno = ExecHashGetBucket(hashtable, econtext, outerVar);
- bucket=(HashBucket)(ABSADDR(hashtable->top)
- + bucketno * hashtable->bucketsize);
- }
-
- for (;;) {
/* ----------------
- * Now we've got an outer tuple and the corresponding hash bucket,
- * but this tuple may not belong to the current batch.
+ * if this is the first call, build the hash table for inner relation
* ----------------
*/
- if (curbatch == 0 && bucketno != -1) /* if this is the first pass */
- batch = ExecHashJoinGetBatch(bucketno, hashtable, nbatch);
- else
- batch = 0;
- if (batch > 0) {
- /*
- * if the current outer tuple does not belong to
- * the current batch, save to the tmp file for
- * the corresponding batch.
- */
- buffer = ABSADDR(hashtable->batch) + (batch - 1) * BLCKSZ;
- batchno = batch - 1;
- pos = ExecHashJoinSaveTuple(outerTupleSlot->val,
- buffer,
- outerbatches[batchno],
- ABSADDR(outerbatchPos[batchno]));
-
- outerbatchPos[batchno] = RELADDR(pos);
+ if (!hashPhaseDone)
+ { /* if the hash phase not completed */
+ hashtable = node->hashjointable;
+ if (hashtable == NULL)
+ { /* if the hash table has not been created */
+ /* ----------------
+ * create the hash table
+ * ----------------
+ */
+ hashtable = ExecHashTableCreate(hashNode);
+ hjstate->hj_HashTable = hashtable;
+ innerhashkey = hashNode->hashkey;
+ hjstate->hj_InnerHashKey = innerhashkey;
+
+ /* ----------------
+ * execute the Hash node, to build the hash table
+ * ----------------
+ */
+ hashNode->hashtable = hashtable;
+ innerTupleSlot = ExecProcNode((Plan *) hashNode, (Plan *) node);
+ }
+ bucket = NULL;
+ curtuple = NULL;
+ curbatch = 0;
+ node->hashdone = true;
}
- else if (bucket != NULL) {
- do {
- /*
- * scan the hash bucket for matches
+ nbatch = hashtable->nbatch;
+ outerbatches = hjstate->hj_OuterBatches;
+ if (nbatch > 0 && outerbatches == NULL)
+ { /* if needs hash partition */
+ /* -----------------
+ * allocate space for file descriptors of outer batch files
+ * then open the batch files in the current process
+ * -----------------
*/
- curtuple = ExecScanHashBucket(hjstate,
- bucket,
- curtuple,
- hjclauses,
- econtext);
-
- if (curtuple != NULL) {
- /*
- * we've got a match, but still need to test qpqual
- */
- inntuple = ExecStoreTuple(curtuple,
- hjstate->hj_HashTupleSlot,
- InvalidBuffer,
- false); /* don't pfree this tuple */
-
- econtext->ecxt_innertuple = inntuple;
-
- /* ----------------
- * test to see if we pass the qualification
- * ----------------
- */
- qualResult = ExecQual((List*)qual, econtext);
-
- /* ----------------
- * if we pass the qual, then save state for next call and
- * have ExecProject form the projection, store it
- * in the tuple table, and return the slot.
- * ----------------
- */
- if (qualResult) {
- ProjectionInfo *projInfo;
- TupleTableSlot *result;
- bool isDone;
-
- hjstate->hj_CurBucket = bucket;
- hjstate->hj_CurTuple = curtuple;
- hashtable->curbatch = curbatch;
- hjstate->jstate.cs_OuterTupleSlot = outerTupleSlot;
-
- projInfo = hjstate->jstate.cs_ProjInfo;
- result = ExecProject(projInfo, &isDone);
- hjstate->jstate.cs_TupFromTlist = !isDone;
- return result;
- }
+ innerhashkey = hashNode->hashkey;
+ hjstate->hj_InnerHashKey = innerhashkey;
+ outerbatchNames = (RelativeAddr *)
+ ABSADDR(hashtable->outerbatchNames);
+ outerbatches = (File *)
+ palloc(nbatch * sizeof(File));
+ for (i = 0; i < nbatch; i++)
+ {
+ outerbatches[i] = FileNameOpenFile(
+ ABSADDR(outerbatchNames[i]),
+ O_CREAT | O_RDWR, 0600);
}
- }
- while (curtuple != NULL);
+ hjstate->hj_OuterBatches = outerbatches;
+
+ /* ------------------
+ * get the inner batch file descriptors from the
+ * hash node
+ * ------------------
+ */
+ hjstate->hj_InnerBatches =
+ hashNode->hashstate->hashBatches;
}
-
+ outerbatchPos = (RelativeAddr *) ABSADDR(hashtable->outerbatchPos);
+ curbatch = hashtable->curbatch;
+ outerbatchNames = (RelativeAddr *) ABSADDR(hashtable->outerbatchNames);
+
/* ----------------
- * Now the current outer tuple has run out of matches,
- * so we free it and get a new outer tuple.
+ * Now get an outer tuple and probe into the hash table for matches
* ----------------
*/
- outerTupleSlot = (TupleTableSlot*)
- ExecHashJoinOuterGetTuple(outerNode, (Plan*) node, hjstate);
-
- while (curbatch <= nbatch && TupIsNull(outerTupleSlot)) {
- /*
- * if the current batch runs out, switch to new batch
- */
- curbatch = ExecHashJoinNewBatch(hjstate);
- if (curbatch > nbatch) {
+ outerTupleSlot = hjstate->jstate.cs_OuterTupleSlot;
+ outerVar = get_leftop(clause);
+
+ bucketno = -1; /* if bucketno remains -1, means use old
+ * outer tuple */
+ if (TupIsNull(outerTupleSlot))
+ {
+
/*
- * when the last batch runs out, clean up
+ * if the current outer tuple is nil, get a new one
*/
- ExecHashTableDestroy(hashtable);
- hjstate->hj_HashTable = NULL;
- return NULL;
- }
- else
- outerTupleSlot = (TupleTableSlot*)
- ExecHashJoinOuterGetTuple(outerNode, (Plan*)node, hjstate);
+ outerTupleSlot = (TupleTableSlot *)
+ ExecHashJoinOuterGetTuple(outerNode, (Plan *) node, hjstate);
+
+ while (curbatch <= nbatch && TupIsNull(outerTupleSlot))
+ {
+
+ /*
+ * if the current batch runs out, switch to new batch
+ */
+ curbatch = ExecHashJoinNewBatch(hjstate);
+ if (curbatch > nbatch)
+ {
+
+ /*
+ * when the last batch runs out, clean up
+ */
+ ExecHashTableDestroy(hashtable);
+ hjstate->hj_HashTable = NULL;
+ return NULL;
+ }
+ else
+ outerTupleSlot = (TupleTableSlot *)
+ ExecHashJoinOuterGetTuple(outerNode, (Plan *) node, hjstate);
+ }
+
+ /*
+ * now we get an outer tuple, find the corresponding bucket for
+ * this tuple from the hash table
+ */
+ econtext->ecxt_outertuple = outerTupleSlot;
+
+#ifdef HJDEBUG
+ printf("Probing ");
+#endif
+ bucketno = ExecHashGetBucket(hashtable, econtext, outerVar);
+ bucket = (HashBucket) (ABSADDR(hashtable->top)
+ + bucketno * hashtable->bucketsize);
}
-
- /* ----------------
- * Now get the corresponding hash bucket for the new
- * outer tuple.
- * ----------------
- */
- econtext->ecxt_outertuple = outerTupleSlot;
+
+ for (;;)
+ {
+ /* ----------------
+ * Now we've got an outer tuple and the corresponding hash bucket,
+ * but this tuple may not belong to the current batch.
+ * ----------------
+ */
+ if (curbatch == 0 && bucketno != -1) /* if this is the first
+ * pass */
+ batch = ExecHashJoinGetBatch(bucketno, hashtable, nbatch);
+ else
+ batch = 0;
+ if (batch > 0)
+ {
+
+ /*
+ * if the current outer tuple does not belong to the current
+ * batch, save to the tmp file for the corresponding batch.
+ */
+ buffer = ABSADDR(hashtable->batch) + (batch - 1) * BLCKSZ;
+ batchno = batch - 1;
+ pos = ExecHashJoinSaveTuple(outerTupleSlot->val,
+ buffer,
+ outerbatches[batchno],
+ ABSADDR(outerbatchPos[batchno]));
+
+ outerbatchPos[batchno] = RELADDR(pos);
+ }
+ else if (bucket != NULL)
+ {
+ do
+ {
+
+ /*
+ * scan the hash bucket for matches
+ */
+ curtuple = ExecScanHashBucket(hjstate,
+ bucket,
+ curtuple,
+ hjclauses,
+ econtext);
+
+ if (curtuple != NULL)
+ {
+
+ /*
+ * we've got a match, but still need to test qpqual
+ */
+ inntuple = ExecStoreTuple(curtuple,
+ hjstate->hj_HashTupleSlot,
+ InvalidBuffer,
+ false); /* don't pfree this
+ * tuple */
+
+ econtext->ecxt_innertuple = inntuple;
+
+ /* ----------------
+ * test to see if we pass the qualification
+ * ----------------
+ */
+ qualResult = ExecQual((List *) qual, econtext);
+
+ /* ----------------
+ * if we pass the qual, then save state for next call and
+ * have ExecProject form the projection, store it
+ * in the tuple table, and return the slot.
+ * ----------------
+ */
+ if (qualResult)
+ {
+ ProjectionInfo *projInfo;
+ TupleTableSlot *result;
+ bool isDone;
+
+ hjstate->hj_CurBucket = bucket;
+ hjstate->hj_CurTuple = curtuple;
+ hashtable->curbatch = curbatch;
+ hjstate->jstate.cs_OuterTupleSlot = outerTupleSlot;
+
+ projInfo = hjstate->jstate.cs_ProjInfo;
+ result = ExecProject(projInfo, &isDone);
+ hjstate->jstate.cs_TupFromTlist = !isDone;
+ return result;
+ }
+ }
+ }
+ while (curtuple != NULL);
+ }
+
+ /* ----------------
+ * Now the current outer tuple has run out of matches,
+ * so we free it and get a new outer tuple.
+ * ----------------
+ */
+ outerTupleSlot = (TupleTableSlot *)
+ ExecHashJoinOuterGetTuple(outerNode, (Plan *) node, hjstate);
+
+ while (curbatch <= nbatch && TupIsNull(outerTupleSlot))
+ {
+
+ /*
+ * if the current batch runs out, switch to new batch
+ */
+ curbatch = ExecHashJoinNewBatch(hjstate);
+ if (curbatch > nbatch)
+ {
+
+ /*
+ * when the last batch runs out, clean up
+ */
+ ExecHashTableDestroy(hashtable);
+ hjstate->hj_HashTable = NULL;
+ return NULL;
+ }
+ else
+ outerTupleSlot = (TupleTableSlot *)
+ ExecHashJoinOuterGetTuple(outerNode, (Plan *) node, hjstate);
+ }
+
+ /* ----------------
+ * Now get the corresponding hash bucket for the new
+ * outer tuple.
+ * ----------------
+ */
+ econtext->ecxt_outertuple = outerTupleSlot;
#ifdef HJDEBUG
- printf("Probing ");
+ printf("Probing ");
#endif
- bucketno = ExecHashGetBucket(hashtable, econtext, outerVar);
- bucket=(HashBucket)(ABSADDR(hashtable->top)
- + bucketno * hashtable->bucketsize);
- curtuple = NULL;
- }
+ bucketno = ExecHashGetBucket(hashtable, econtext, outerVar);
+ bucket = (HashBucket) (ABSADDR(hashtable->top)
+ + bucketno * hashtable->bucketsize);
+ curtuple = NULL;
+ }
}
/* ----------------------------------------------------------------
- * ExecInitHashJoin
+ * ExecInitHashJoin
*
- * Init routine for HashJoin node.
+ * Init routine for HashJoin node.
* ----------------------------------------------------------------
*/
-bool /* return: initialization status */
-ExecInitHashJoin(HashJoin *node, EState *estate, Plan *parent)
+bool /* return: initialization status */
+ExecInitHashJoin(HashJoin * node, EState * estate, Plan * parent)
{
- HashJoinState *hjstate;
- Plan *outerNode;
- Hash *hashNode;
-
- /* ----------------
- * assign the node's execution state
- * ----------------
- */
- node->join.state = estate;
-
- /* ----------------
- * create state structure
- * ----------------
- */
- hjstate = makeNode(HashJoinState);
-
- node->hashjoinstate = hjstate;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks and
- * + create expression context for node
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &hjstate->jstate, parent);
- ExecAssignExprContext(estate, &hjstate->jstate);
-
+ HashJoinState *hjstate;
+ Plan *outerNode;
+ Hash *hashNode;
+
+ /* ----------------
+ * assign the node's execution state
+ * ----------------
+ */
+ node->join.state = estate;
+
+ /* ----------------
+ * create state structure
+ * ----------------
+ */
+ hjstate = makeNode(HashJoinState);
+
+ node->hashjoinstate = hjstate;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks and
+ * + create expression context for node
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &hjstate->jstate, parent);
+ ExecAssignExprContext(estate, &hjstate->jstate);
+
#define HASHJOIN_NSLOTS 2
- /* ----------------
- * tuple table initialization
- * ----------------
- */
- ExecInitResultTupleSlot(estate, &hjstate->jstate);
- ExecInitOuterTupleSlot(estate, hjstate);
-
- /* ----------------
- * initializes child nodes
- * ----------------
- */
- outerNode = outerPlan((Plan *)node);
- hashNode = (Hash*)innerPlan((Plan *)node);
-
- ExecInitNode(outerNode, estate, (Plan *) node);
- ExecInitNode((Plan*)hashNode, estate, (Plan *) node);
-
- /* ----------------
- * now for some voodoo. our temporary tuple slot
- * is actually the result tuple slot of the Hash node
- * (which is our inner plan). we do this because Hash
- * nodes don't return tuples via ExecProcNode() -- instead
- * the hash join node uses ExecScanHashBucket() to get
- * at the contents of the hash table. -cim 6/9/91
- * ----------------
- */
- {
- HashState *hashstate = hashNode->hashstate;
- TupleTableSlot *slot =
- hashstate->cstate.cs_ResultTupleSlot;
- hjstate->hj_HashTupleSlot = slot;
- }
- hjstate->hj_OuterTupleSlot->ttc_tupleDescriptor =
- ExecGetTupType(outerNode);
-
+ /* ----------------
+ * tuple table initialization
+ * ----------------
+ */
+ ExecInitResultTupleSlot(estate, &hjstate->jstate);
+ ExecInitOuterTupleSlot(estate, hjstate);
+
+ /* ----------------
+ * initializes child nodes
+ * ----------------
+ */
+ outerNode = outerPlan((Plan *) node);
+ hashNode = (Hash *) innerPlan((Plan *) node);
+
+ ExecInitNode(outerNode, estate, (Plan *) node);
+ ExecInitNode((Plan *) hashNode, estate, (Plan *) node);
+
+ /* ----------------
+ * now for some voodoo. our temporary tuple slot
+ * is actually the result tuple slot of the Hash node
+ * (which is our inner plan). we do this because Hash
+ * nodes don't return tuples via ExecProcNode() -- instead
+ * the hash join node uses ExecScanHashBucket() to get
+ * at the contents of the hash table. -cim 6/9/91
+ * ----------------
+ */
+ {
+ HashState *hashstate = hashNode->hashstate;
+ TupleTableSlot *slot =
+ hashstate->cstate.cs_ResultTupleSlot;
+
+ hjstate->hj_HashTupleSlot = slot;
+ }
+ hjstate->hj_OuterTupleSlot->ttc_tupleDescriptor =
+ ExecGetTupType(outerNode);
+
/*
- hjstate->hj_OuterTupleSlot->ttc_execTupDescriptor =
- ExecGetExecTupDesc(outerNode);
+ hjstate->hj_OuterTupleSlot->ttc_execTupDescriptor =
+ ExecGetExecTupDesc(outerNode);
*/
-
- /* ----------------
- * initialize tuple type and projection info
- * ----------------
- */
- ExecAssignResultTypeFromTL((Plan*) node, &hjstate->jstate);
- ExecAssignProjectionInfo((Plan*) node, &hjstate->jstate);
-
- /* ----------------
- * XXX comment me
- * ----------------
- */
-
- node->hashdone = false;
-
- hjstate->hj_HashTable = (HashJoinTable)NULL;
- hjstate->hj_HashTableShmId = (IpcMemoryId)0;
- hjstate->hj_CurBucket = (HashBucket )NULL;
- hjstate->hj_CurTuple = (HeapTuple )NULL;
- hjstate->hj_CurOTuple = (OverflowTuple )NULL;
- hjstate->hj_InnerHashKey = (Var*)NULL;
- hjstate->hj_OuterBatches = (File*)NULL;
- hjstate->hj_InnerBatches = (File*)NULL;
- hjstate->hj_OuterReadPos = (char*)NULL;
- hjstate->hj_OuterReadBlk = (int)0;
-
- hjstate->jstate.cs_OuterTupleSlot = (TupleTableSlot*) NULL;
- hjstate->jstate.cs_TupFromTlist = (bool) false;
-
- return TRUE;
+
+ /* ----------------
+ * initialize tuple type and projection info
+ * ----------------
+ */
+ ExecAssignResultTypeFromTL((Plan *) node, &hjstate->jstate);
+ ExecAssignProjectionInfo((Plan *) node, &hjstate->jstate);
+
+ /* ----------------
+ * XXX comment me
+ * ----------------
+ */
+
+ node->hashdone = false;
+
+ hjstate->hj_HashTable = (HashJoinTable) NULL;
+ hjstate->hj_HashTableShmId = (IpcMemoryId) 0;
+ hjstate->hj_CurBucket = (HashBucket) NULL;
+ hjstate->hj_CurTuple = (HeapTuple) NULL;
+ hjstate->hj_CurOTuple = (OverflowTuple) NULL;
+ hjstate->hj_InnerHashKey = (Var *) NULL;
+ hjstate->hj_OuterBatches = (File *) NULL;
+ hjstate->hj_InnerBatches = (File *) NULL;
+ hjstate->hj_OuterReadPos = (char *) NULL;
+ hjstate->hj_OuterReadBlk = (int) 0;
+
+ hjstate->jstate.cs_OuterTupleSlot = (TupleTableSlot *) NULL;
+ hjstate->jstate.cs_TupFromTlist = (bool) false;
+
+ return TRUE;
}
int
-ExecCountSlotsHashJoin(HashJoin *node)
+ExecCountSlotsHashJoin(HashJoin * node)
{
- return ExecCountSlotsNode(outerPlan(node)) +
+ return ExecCountSlotsNode(outerPlan(node)) +
ExecCountSlotsNode(innerPlan(node)) +
- HASHJOIN_NSLOTS;
+ HASHJOIN_NSLOTS;
}
/* ----------------------------------------------------------------
- * ExecEndHashJoin
+ * ExecEndHashJoin
*
- * clean up routine for HashJoin node
+ * clean up routine for HashJoin node
* ----------------------------------------------------------------
*/
void
-ExecEndHashJoin(HashJoin *node)
+ExecEndHashJoin(HashJoin * node)
{
- HashJoinState *hjstate;
-
- /* ----------------
- * get info from the HashJoin state
- * ----------------
- */
- hjstate = node->hashjoinstate;
-
- /* ----------------
- * free hash table in case we end plan before all tuples are retrieved
- * ---------------
- */
- if (hjstate->hj_HashTable) {
- ExecHashTableDestroy(hjstate->hj_HashTable);
- hjstate->hj_HashTable = NULL;
- }
-
- /* ----------------
- * Free the projection info and the scan attribute info
- *
- * Note: we don't ExecFreeResultType(hjstate)
- * because the rule manager depends on the tupType
- * returned by ExecMain(). So for now, this
- * is freed at end-transaction time. -cim 6/2/91
- * ----------------
- */
- ExecFreeProjectionInfo(&hjstate->jstate);
-
- /* ----------------
- * clean up subtrees
- * ----------------
- */
- ExecEndNode(outerPlan((Plan *) node), (Plan*)node);
- ExecEndNode(innerPlan((Plan *) node), (Plan*)node);
-
- /* ----------------
- * clean out the tuple table
- * ----------------
- */
- ExecClearTuple(hjstate->jstate.cs_ResultTupleSlot);
- ExecClearTuple(hjstate->hj_OuterTupleSlot);
- ExecClearTuple(hjstate->hj_HashTupleSlot);
-
+ HashJoinState *hjstate;
+
+ /* ----------------
+ * get info from the HashJoin state
+ * ----------------
+ */
+ hjstate = node->hashjoinstate;
+
+ /* ----------------
+ * free hash table in case we end plan before all tuples are retrieved
+ * ---------------
+ */
+ if (hjstate->hj_HashTable)
+ {
+ ExecHashTableDestroy(hjstate->hj_HashTable);
+ hjstate->hj_HashTable = NULL;
+ }
+
+ /* ----------------
+ * Free the projection info and the scan attribute info
+ *
+ * Note: we don't ExecFreeResultType(hjstate)
+ * because the rule manager depends on the tupType
+ * returned by ExecMain(). So for now, this
+ * is freed at end-transaction time. -cim 6/2/91
+ * ----------------
+ */
+ ExecFreeProjectionInfo(&hjstate->jstate);
+
+ /* ----------------
+ * clean up subtrees
+ * ----------------
+ */
+ ExecEndNode(outerPlan((Plan *) node), (Plan *) node);
+ ExecEndNode(innerPlan((Plan *) node), (Plan *) node);
+
+ /* ----------------
+ * clean out the tuple table
+ * ----------------
+ */
+ ExecClearTuple(hjstate->jstate.cs_ResultTupleSlot);
+ ExecClearTuple(hjstate->hj_OuterTupleSlot);
+ ExecClearTuple(hjstate->hj_HashTupleSlot);
+
}
/* ----------------------------------------------------------------
- * ExecHashJoinOuterGetTuple
+ * ExecHashJoinOuterGetTuple
*
- * get the next outer tuple for hashjoin: either by
- * executing a plan node as in the first pass, or from
- * the tmp files for the hashjoin batches.
+ * get the next outer tuple for hashjoin: either by
+ * executing a plan node as in the first pass, or from
+ * the tmp files for the hashjoin batches.
* ----------------------------------------------------------------
*/
static TupleTableSlot *
-ExecHashJoinOuterGetTuple(Plan *node, Plan* parent, HashJoinState *hjstate)
+ExecHashJoinOuterGetTuple(Plan * node, Plan * parent, HashJoinState * hjstate)
{
- TupleTableSlot *slot;
- HashJoinTable hashtable;
- int curbatch;
- File *outerbatches;
- char *outerreadPos;
- int batchno;
- char *outerreadBuf;
- int outerreadBlk;
-
- hashtable = hjstate->hj_HashTable;
- curbatch = hashtable->curbatch;
-
- if (curbatch == 0) { /* if it is the first pass */
- slot = ExecProcNode(node, parent);
+ TupleTableSlot *slot;
+ HashJoinTable hashtable;
+ int curbatch;
+ File *outerbatches;
+ char *outerreadPos;
+ int batchno;
+ char *outerreadBuf;
+ int outerreadBlk;
+
+ hashtable = hjstate->hj_HashTable;
+ curbatch = hashtable->curbatch;
+
+ if (curbatch == 0)
+ { /* if it is the first pass */
+ slot = ExecProcNode(node, parent);
+ return slot;
+ }
+
+ /*
+ * otherwise, read from the tmp files
+ */
+ outerbatches = hjstate->hj_OuterBatches;
+ outerreadPos = hjstate->hj_OuterReadPos;
+ outerreadBlk = hjstate->hj_OuterReadBlk;
+ outerreadBuf = ABSADDR(hashtable->readbuf);
+ batchno = curbatch - 1;
+
+ slot = ExecHashJoinGetSavedTuple(hjstate,
+ outerreadBuf,
+ outerbatches[batchno],
+ hjstate->hj_OuterTupleSlot,
+ &outerreadBlk,
+ &outerreadPos);
+
+ hjstate->hj_OuterReadPos = outerreadPos;
+ hjstate->hj_OuterReadBlk = outerreadBlk;
+
return slot;
- }
-
- /*
- * otherwise, read from the tmp files
- */
- outerbatches = hjstate->hj_OuterBatches;
- outerreadPos = hjstate->hj_OuterReadPos;
- outerreadBlk = hjstate->hj_OuterReadBlk;
- outerreadBuf = ABSADDR(hashtable->readbuf);
- batchno = curbatch - 1;
-
- slot = ExecHashJoinGetSavedTuple(hjstate,
- outerreadBuf,
- outerbatches[batchno],
- hjstate->hj_OuterTupleSlot,
- &outerreadBlk,
- &outerreadPos);
-
- hjstate->hj_OuterReadPos = outerreadPos;
- hjstate->hj_OuterReadBlk = outerreadBlk;
-
- return slot;
}
/* ----------------------------------------------------------------
- * ExecHashJoinGetSavedTuple
+ * ExecHashJoinGetSavedTuple
*
- * read the next tuple from a tmp file using a certain buffer
+ * read the next tuple from a tmp file using a certain buffer
* ----------------------------------------------------------------
*/
static TupleTableSlot *
-ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
- char *buffer,
- File file,
- TupleTableSlot *tupleSlot,
- int *block, /* return parameter */
- char **position) /* return parameter */
+ExecHashJoinGetSavedTuple(HashJoinState * hjstate,
+ char *buffer,
+ File file,
+ TupleTableSlot * tupleSlot,
+ int *block, /* return parameter */
+ char **position) /* return parameter */
{
- char *bufstart;
- char *bufend;
- int cc;
- HeapTuple heapTuple;
- HashJoinTable hashtable;
-
- hashtable = hjstate->hj_HashTable;
- bufend = buffer + *(long*)buffer;
- bufstart = (char*)(buffer + sizeof(long));
- if ((*position == NULL) || (*position >= bufend)) {
- if (*position == NULL)
- (*block) = 0;
- else
- (*block)++;
- FileSeek(file, *block * BLCKSZ, SEEK_SET);
- cc = FileRead(file, buffer, BLCKSZ);
- NDirectFileRead++;
- if (cc < 0)
- perror("FileRead");
- if (cc == 0) /* end of file */
- return NULL;
- else
- (*position) = bufstart;
- }
- heapTuple = (HeapTuple) (*position);
- (*position) = (char*)LONGALIGN(*position + heapTuple->t_len);
-
- return ExecStoreTuple(heapTuple,tupleSlot,InvalidBuffer,false);
+ char *bufstart;
+ char *bufend;
+ int cc;
+ HeapTuple heapTuple;
+ HashJoinTable hashtable;
+
+ hashtable = hjstate->hj_HashTable;
+ bufend = buffer + *(long *) buffer;
+ bufstart = (char *) (buffer + sizeof(long));
+ if ((*position == NULL) || (*position >= bufend))
+ {
+ if (*position == NULL)
+ (*block) = 0;
+ else
+ (*block)++;
+ FileSeek(file, *block * BLCKSZ, SEEK_SET);
+ cc = FileRead(file, buffer, BLCKSZ);
+ NDirectFileRead++;
+ if (cc < 0)
+ perror("FileRead");
+ if (cc == 0) /* end of file */
+ return NULL;
+ else
+ (*position) = bufstart;
+ }
+ heapTuple = (HeapTuple) (*position);
+ (*position) = (char *) LONGALIGN(*position + heapTuple->t_len);
+
+ return ExecStoreTuple(heapTuple, tupleSlot, InvalidBuffer, false);
}
/* ----------------------------------------------------------------
- * ExecHashJoinNewBatch
+ * ExecHashJoinNewBatch
*
- * switch to a new hashjoin batch
+ * switch to a new hashjoin batch
* ----------------------------------------------------------------
*/
static int
-ExecHashJoinNewBatch(HashJoinState *hjstate)
+ExecHashJoinNewBatch(HashJoinState * hjstate)
{
- File *innerBatches;
- File *outerBatches;
- int *innerBatchSizes;
- Var *innerhashkey;
- HashJoinTable hashtable;
- int nbatch;
- char *readPos;
- int readBlk;
- char *readBuf;
- TupleTableSlot *slot;
- ExprContext *econtext;
- int i;
- int cc;
- int newbatch;
-
- hashtable = hjstate->hj_HashTable;
- outerBatches = hjstate->hj_OuterBatches;
- innerBatches = hjstate->hj_InnerBatches;
- nbatch = hashtable->nbatch;
- newbatch = hashtable->curbatch + 1;
-
- /* ------------------
- * this is the last process, so it will do the cleanup and
- * batch-switching.
- * ------------------
- */
- if (newbatch == 1) {
- /*
- * if it is end of the first pass, flush all the last pages for
- * the batches.
- */
- outerBatches = hjstate->hj_OuterBatches;
- for (i=0; i<nbatch; i++) {
- cc = FileSeek(outerBatches[i], 0L, SEEK_END);
- if (cc < 0)
- perror("FileSeek");
- cc = FileWrite(outerBatches[i],
- ABSADDR(hashtable->batch) + i * BLCKSZ, BLCKSZ);
- NDirectFileWrite++;
- if (cc < 0)
- perror("FileWrite");
- }
+ File *innerBatches;
+ File *outerBatches;
+ int *innerBatchSizes;
+ Var *innerhashkey;
+ HashJoinTable hashtable;
+ int nbatch;
+ char *readPos;
+ int readBlk;
+ char *readBuf;
+ TupleTableSlot *slot;
+ ExprContext *econtext;
+ int i;
+ int cc;
+ int newbatch;
+
+ hashtable = hjstate->hj_HashTable;
+ outerBatches = hjstate->hj_OuterBatches;
+ innerBatches = hjstate->hj_InnerBatches;
+ nbatch = hashtable->nbatch;
+ newbatch = hashtable->curbatch + 1;
+
+ /* ------------------
+ * this is the last process, so it will do the cleanup and
+ * batch-switching.
+ * ------------------
+ */
+ if (newbatch == 1)
+ {
+
+ /*
+ * if it is end of the first pass, flush all the last pages for
+ * the batches.
+ */
+ outerBatches = hjstate->hj_OuterBatches;
+ for (i = 0; i < nbatch; i++)
+ {
+ cc = FileSeek(outerBatches[i], 0L, SEEK_END);
+ if (cc < 0)
+ perror("FileSeek");
+ cc = FileWrite(outerBatches[i],
+ ABSADDR(hashtable->batch) + i * BLCKSZ, BLCKSZ);
+ NDirectFileWrite++;
+ if (cc < 0)
+ perror("FileWrite");
+ }
}
- if (newbatch > 1) {
+ if (newbatch > 1)
+ {
+
+ /*
+ * remove the previous outer batch
+ */
+ FileUnlink(outerBatches[newbatch - 2]);
+ }
+
/*
- * remove the previous outer batch
+ * rebuild the hash table for the new inner batch
+ */
+ innerBatchSizes = (int *) ABSADDR(hashtable->innerbatchSizes);
+ /* --------------
+ * skip over empty inner batches
+ * --------------
*/
- FileUnlink(outerBatches[newbatch - 2]);
- }
- /*
- * rebuild the hash table for the new inner batch
- */
- innerBatchSizes = (int*)ABSADDR(hashtable->innerbatchSizes);
- /* --------------
- * skip over empty inner batches
- * --------------
- */
- while (newbatch <= nbatch && innerBatchSizes[newbatch - 1] == 0) {
- FileUnlink(outerBatches[newbatch-1]);
- FileUnlink(innerBatches[newbatch-1]);
- newbatch++;
+ while (newbatch <= nbatch && innerBatchSizes[newbatch - 1] == 0)
+ {
+ FileUnlink(outerBatches[newbatch - 1]);
+ FileUnlink(innerBatches[newbatch - 1]);
+ newbatch++;
}
- if (newbatch > nbatch) {
+ if (newbatch > nbatch)
+ {
+ hashtable->pcount = hashtable->nprocess;
+
+ return newbatch;
+ }
+ ExecHashTableReset(hashtable, innerBatchSizes[newbatch - 1]);
+
+
+ econtext = hjstate->jstate.cs_ExprContext;
+ innerhashkey = hjstate->hj_InnerHashKey;
+ readPos = NULL;
+ readBlk = 0;
+ readBuf = ABSADDR(hashtable->readbuf);
+
+ while ((slot = ExecHashJoinGetSavedTuple(hjstate,
+ readBuf,
+ innerBatches[newbatch - 1],
+ hjstate->hj_HashTupleSlot,
+ &readBlk,
+ &readPos))
+ && !TupIsNull(slot))
+ {
+ econtext->ecxt_innertuple = slot;
+ ExecHashTableInsert(hashtable, econtext, innerhashkey, NULL);
+ /* possible bug - glass */
+ }
+
+
+ /* -----------------
+ * only the last process comes to this branch
+ * now all the processes have finished the build phase
+ * ----------------
+ */
+
+ /*
+ * after we build the hash table, the inner batch is no longer needed
+ */
+ FileUnlink(innerBatches[newbatch - 1]);
+ hjstate->hj_OuterReadPos = NULL;
hashtable->pcount = hashtable->nprocess;
+ hashtable->curbatch = newbatch;
return newbatch;
- }
- ExecHashTableReset(hashtable, innerBatchSizes[newbatch - 1]);
-
-
- econtext = hjstate->jstate.cs_ExprContext;
- innerhashkey = hjstate->hj_InnerHashKey;
- readPos = NULL;
- readBlk = 0;
- readBuf = ABSADDR(hashtable->readbuf);
-
- while ((slot = ExecHashJoinGetSavedTuple(hjstate,
- readBuf,
- innerBatches[newbatch-1],
- hjstate->hj_HashTupleSlot,
- &readBlk,
- &readPos))
- && ! TupIsNull(slot)) {
- econtext->ecxt_innertuple = slot;
- ExecHashTableInsert(hashtable, econtext, innerhashkey,NULL);
- /* possible bug - glass */
- }
-
-
- /* -----------------
- * only the last process comes to this branch
- * now all the processes have finished the build phase
- * ----------------
- */
-
- /*
- * after we build the hash table, the inner batch is no longer needed
- */
- FileUnlink(innerBatches[newbatch - 1]);
- hjstate->hj_OuterReadPos = NULL;
- hashtable->pcount = hashtable->nprocess;
-
- hashtable->curbatch = newbatch;
- return newbatch;
}
/* ----------------------------------------------------------------
- * ExecHashJoinGetBatch
+ * ExecHashJoinGetBatch
*
- * determine the batch number for a bucketno
- * +----------------+-------+-------+ ... +-------+
- * 0 nbuckets totalbuckets
- * batch 0 1 2 ...
+ * determine the batch number for a bucketno
+ * +----------------+-------+-------+ ... +-------+
+ * 0 nbuckets totalbuckets
+ * batch 0 1 2 ...
* ----------------------------------------------------------------
*/
static int
ExecHashJoinGetBatch(int bucketno, HashJoinTable hashtable, int nbatch)
{
- int b;
- if (bucketno < hashtable->nbuckets || nbatch == 0)
- return 0;
-
- b = (float)(bucketno - hashtable->nbuckets) /
- (float)(hashtable->totalbuckets - hashtable->nbuckets) *
- nbatch;
- return b+1;
+ int b;
+
+ if (bucketno < hashtable->nbuckets || nbatch == 0)
+ return 0;
+
+ b = (float) (bucketno - hashtable->nbuckets) /
+ (float) (hashtable->totalbuckets - hashtable->nbuckets) *
+ nbatch;
+ return b + 1;
}
/* ----------------------------------------------------------------
- * ExecHashJoinSaveTuple
+ * ExecHashJoinSaveTuple
*
- * save a tuple to a tmp file using a buffer.
- * the first few bytes in a page is an offset to the end
- * of the page.
+ * save a tuple to a tmp file using a buffer.
+ * the first few bytes in a page is an offset to the end
+ * of the page.
* ----------------------------------------------------------------
*/
-char *
+char *
ExecHashJoinSaveTuple(HeapTuple heapTuple,
- char *buffer,
- File file,
- char *position)
+ char *buffer,
+ File file,
+ char *position)
{
- long *pageend;
- char *pagestart;
- char *pagebound;
- int cc;
-
- pageend = (long*)buffer;
- pagestart = (char*)(buffer + sizeof(long));
- pagebound = buffer + BLCKSZ;
- if (position == NULL)
- position = pagestart;
-
- if (position + heapTuple->t_len >= pagebound) {
- cc = FileSeek(file, 0L, SEEK_END);
- if (cc < 0)
- perror("FileSeek");
- cc = FileWrite(file, buffer, BLCKSZ);
- NDirectFileWrite++;
- if (cc < 0)
- perror("FileWrite");
- position = pagestart;
- *pageend = 0;
- }
- memmove(position, heapTuple, heapTuple->t_len);
- position = (char*)LONGALIGN(position + heapTuple->t_len);
- *pageend = position - buffer;
-
- return position;
+ long *pageend;
+ char *pagestart;
+ char *pagebound;
+ int cc;
+
+ pageend = (long *) buffer;
+ pagestart = (char *) (buffer + sizeof(long));
+ pagebound = buffer + BLCKSZ;
+ if (position == NULL)
+ position = pagestart;
+
+ if (position + heapTuple->t_len >= pagebound)
+ {
+ cc = FileSeek(file, 0L, SEEK_END);
+ if (cc < 0)
+ perror("FileSeek");
+ cc = FileWrite(file, buffer, BLCKSZ);
+ NDirectFileWrite++;
+ if (cc < 0)
+ perror("FileWrite");
+ position = pagestart;
+ *pageend = 0;
+ }
+ memmove(position, heapTuple, heapTuple->t_len);
+ position = (char *) LONGALIGN(position + heapTuple->t_len);
+ *pageend = position - buffer;
+
+ return position;
}
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index bc0c4c3d288..c89a4fcb081 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -1,31 +1,31 @@
/*-------------------------------------------------------------------------
*
* nodeIndexscan.c--
- * Routines to support indexes and indexed scans of relations
+ * Routines to support indexes and indexed scans of relations
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.7 1997/03/12 20:58:26 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.8 1997/09/07 04:41:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * ExecInsertIndexTuples inserts tuples into indices on result relation
+ * ExecInsertIndexTuples inserts tuples into indices on result relation
*
- * ExecIndexScan scans a relation using indices
- * ExecIndexNext using index to retrieve next tuple
- * ExecInitIndexScan creates and initializes state info.
- * ExecIndexReScan rescans the indexed relation.
- * ExecEndIndexScan releases all storage.
- * ExecIndexMarkPos marks scan position.
- * ExecIndexRestrPos restores scan position.
+ * ExecIndexScan scans a relation using indices
+ * ExecIndexNext using index to retrieve next tuple
+ * ExecInitIndexScan creates and initializes state info.
+ * ExecIndexReScan rescans the indexed relation.
+ * ExecEndIndexScan releases all storage.
+ * ExecIndexMarkPos marks scan position.
+ * ExecIndexRestrPos restores scan position.
*
- * NOTES
- * the code supporting ExecInsertIndexTuples should be
- * collected and merged with the genam stuff.
+ * NOTES
+ * the code supporting ExecInsertIndexTuples should be
+ * collected and merged with the genam stuff.
*
*/
#include "postgres.h"
@@ -48,894 +48,939 @@
#include "nodes/nodeFuncs.h"
/* ----------------
- * Misc stuff to move to executor.h soon -cim 6/5/90
+ * Misc stuff to move to executor.h soon -cim 6/5/90
* ----------------
*/
-#define NO_OP 0
-#define LEFT_OP 1
-#define RIGHT_OP 2
+#define NO_OP 0
+#define LEFT_OP 1
+#define RIGHT_OP 2
-static TupleTableSlot *IndexNext(IndexScan *node);
+static TupleTableSlot *IndexNext(IndexScan * node);
/* ----------------------------------------------------------------
- * IndexNext
+ * IndexNext
*
- * Retrieve a tuple from the IndexScan node's currentRelation
- * using the indices in the IndexScanState information.
+ * Retrieve a tuple from the IndexScan node's currentRelation
+ * using the indices in the IndexScanState information.
*
- * note: the old code mentions 'Primary indices'. to my knowledge
- * we only support a single secondary index. -cim 9/11/89
+ * note: the old code mentions 'Primary indices'. to my knowledge
+ * we only support a single secondary index. -cim 9/11/89
*
* old comments:
- * retrieve a tuple from relation using the indices given.
- * The indices are used in the order they appear in 'indices'.
- * The indices may be primary or secondary indices:
- * * primary index -- scan the relation 'relID' using keys supplied.
- * * secondary index -- scan the index relation to get the 'tid' for
- * a tuple in the relation 'relID'.
- * If the current index(pointed by 'indexPtr') fails to return a
- * tuple, the next index in the indices is used.
- *
- * bug fix so that it should retrieve on a null scan key.
+ * retrieve a tuple from relation using the indices given.
+ * The indices are used in the order they appear in 'indices'.
+ * The indices may be primary or secondary indices:
+ * * primary index -- scan the relation 'relID' using keys supplied.
+ * * secondary index -- scan the index relation to get the 'tid' for
+ * a tuple in the relation 'relID'.
+ * If the current index(pointed by 'indexPtr') fails to return a
+ * tuple, the next index in the indices is used.
+ *
+ * bug fix so that it should retrieve on a null scan key.
* ----------------------------------------------------------------
*/
static TupleTableSlot *
-IndexNext(IndexScan *node)
+IndexNext(IndexScan * node)
{
- EState *estate;
- CommonScanState *scanstate;
- IndexScanState *indexstate;
- ScanDirection direction;
- int indexPtr;
- IndexScanDescPtr scanDescs;
- IndexScanDesc scandesc;
- Relation heapRelation;
- RetrieveIndexResult result;
- ItemPointer iptr;
- HeapTuple tuple;
- TupleTableSlot *slot;
- Buffer buffer = InvalidBuffer;
-
- /* ----------------
- * extract necessary information from index scan node
- * ----------------
- */
- estate = node->scan.plan.state;
- direction = estate->es_direction;
- scanstate = node->scan.scanstate;
- indexstate = node->indxstate;
- indexPtr = indexstate->iss_IndexPtr;
- scanDescs = indexstate->iss_ScanDescs;
- scandesc = scanDescs[ indexPtr ];
- heapRelation = scanstate->css_currentRelation;
-
- slot = scanstate->css_ScanTupleSlot;
-
- /* ----------------
- * ok, now that we have what we need, fetch an index tuple.
- * ----------------
- */
-
- for(;;) {
- result = index_getnext(scandesc, direction);
+ EState *estate;
+ CommonScanState *scanstate;
+ IndexScanState *indexstate;
+ ScanDirection direction;
+ int indexPtr;
+ IndexScanDescPtr scanDescs;
+ IndexScanDesc scandesc;
+ Relation heapRelation;
+ RetrieveIndexResult result;
+ ItemPointer iptr;
+ HeapTuple tuple;
+ TupleTableSlot *slot;
+ Buffer buffer = InvalidBuffer;
+
/* ----------------
- * if scanning this index succeeded then return the
- * appropriate heap tuple.. else return NULL.
+ * extract necessary information from index scan node
* ----------------
*/
- if (result) {
- iptr = &result->heap_iptr;
- tuple = heap_fetch(heapRelation,
- NowTimeQual,
- iptr,
- &buffer);
- /* be tidy */
- pfree(result);
-
- if (tuple == NULL) {
+ estate = node->scan.plan.state;
+ direction = estate->es_direction;
+ scanstate = node->scan.scanstate;
+ indexstate = node->indxstate;
+ indexPtr = indexstate->iss_IndexPtr;
+ scanDescs = indexstate->iss_ScanDescs;
+ scandesc = scanDescs[indexPtr];
+ heapRelation = scanstate->css_currentRelation;
+
+ slot = scanstate->css_ScanTupleSlot;
+
+ /* ----------------
+ * ok, now that we have what we need, fetch an index tuple.
+ * ----------------
+ */
+
+ for (;;)
+ {
+ result = index_getnext(scandesc, direction);
+ /* ----------------
+ * if scanning this index succeeded then return the
+ * appropriate heap tuple.. else return NULL.
+ * ----------------
+ */
+ if (result)
+ {
+ iptr = &result->heap_iptr;
+ tuple = heap_fetch(heapRelation,
+ NowTimeQual,
+ iptr,
+ &buffer);
+ /* be tidy */
+ pfree(result);
+
+ if (tuple == NULL)
+ {
+ /* ----------------
+ * we found a deleted tuple, so keep on scanning..
+ * ----------------
+ */
+ if (BufferIsValid(buffer))
+ ReleaseBuffer(buffer);
+ continue;
+ }
+
+ /* ----------------
+ * 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
+ * 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 */
+
+ return slot;
+ }
+
/* ----------------
- * we found a deleted tuple, so keep on scanning..
+ * if we get here it means the index scan failed so we
+ * are at the end of the scan..
* ----------------
*/
- if (BufferIsValid(buffer))
- ReleaseBuffer(buffer);
- continue;
- }
-
- /* ----------------
- * 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
- * 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 */
-
- return slot;
+ return ExecClearTuple(slot);
}
-
- /* ----------------
- * if we get here it means the index scan failed so we
- * are at the end of the scan..
- * ----------------
- */
- return ExecClearTuple(slot);
- }
}
/* ----------------------------------------------------------------
- * ExecIndexScan(node)
+ * ExecIndexScan(node)
*
* old comments:
- * Scans the relation using primary or secondary indices and returns
- * the next qualifying tuple in the direction specified.
- * It calls ExecScan() and passes it the access methods which returns
- * the next tuple using the indices.
- *
- * Conditions:
- * -- the "cursor" maintained by the AMI is positioned at the tuple
- * returned previously.
- *
- * Initial States:
- * -- the relation indicated is opened for scanning so that the
- * "cursor" is positioned before the first qualifying tuple.
- * -- all index realtions are opened for scanning.
- * -- indexPtr points to the first index.
- * -- state variable ruleFlag = nil.
+ * Scans the relation using primary or secondary indices and returns
+ * the next qualifying tuple in the direction specified.
+ * It calls ExecScan() and passes it the access methods which returns
+ * the next tuple using the indices.
+ *
+ * Conditions:
+ * -- the "cursor" maintained by the AMI is positioned at the tuple
+ * returned previously.
+ *
+ * Initial States:
+ * -- the relation indicated is opened for scanning so that the
+ * "cursor" is positioned before the first qualifying tuple.
+ * -- all index realtions are opened for scanning.
+ * -- indexPtr points to the first index.
+ * -- state variable ruleFlag = nil.
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecIndexScan(IndexScan *node)
+ExecIndexScan(IndexScan * node)
{
- TupleTableSlot *returnTuple;
+ TupleTableSlot *returnTuple;
- /* ----------------
- * use IndexNext as access method
- * ----------------
- */
- returnTuple = ExecScan(&node->scan, IndexNext);
- return returnTuple;
-}
+ /* ----------------
+ * use IndexNext as access method
+ * ----------------
+ */
+ returnTuple = ExecScan(&node->scan, IndexNext);
+ return returnTuple;
+}
/* ----------------------------------------------------------------
- * ExecIndexReScan(node)
+ * ExecIndexReScan(node)
*
- * Recalculates the value of the scan keys whose value depends on
- * information known at runtime and rescans the indexed relation.
- * Updating the scan key was formerly done separately in
- * ExecUpdateIndexScanKeys. Integrating it into ReScan
- * makes rescans of indices and
- * relations/general streams more uniform.
+ * Recalculates the value of the scan keys whose value depends on
+ * information known at runtime and rescans the indexed relation.
+ * Updating the scan key was formerly done separately in
+ * ExecUpdateIndexScanKeys. Integrating it into ReScan
+ * makes rescans of indices and
+ * relations/general streams more uniform.
*
* ----------------------------------------------------------------
*/
void
-ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan* parent)
+ExecIndexReScan(IndexScan * node, ExprContext * exprCtxt, Plan * parent)
{
- EState *estate;
- IndexScanState *indexstate;
- ScanDirection direction;
- IndexScanDescPtr scanDescs;
- ScanKey *scanKeys;
- IndexScanDesc sdesc;
- ScanKey skey;
- int numIndices;
- int i;
-
- Pointer *runtimeKeyInfo;
- int indexPtr;
- int *numScanKeys;
- List *indxqual;
- List *qual;
- int n_keys;
- ScanKey scan_keys;
- int *run_keys;
- int j;
- Expr *clause;
- Node *scanexpr;
- Datum scanvalue;
- bool isNull;
- bool isDone;
-
- indexstate = node->indxstate;
- estate = node->scan.plan.state;
- direction = estate->es_direction;
- indexstate = node->indxstate;
- numIndices = indexstate->iss_NumIndices;
- scanDescs = indexstate->iss_ScanDescs;
- scanKeys = indexstate->iss_ScanKeys;
-
- runtimeKeyInfo = (Pointer *) indexstate->iss_RuntimeKeyInfo;
-
- if (runtimeKeyInfo != NULL) {
- /*
- * get the index qualifications and
- * recalculate the appropriate values
- */
- indexPtr = indexstate->iss_IndexPtr;
- indxqual = node->indxqual;
- qual = nth(indexPtr, indxqual);
- numScanKeys = indexstate->iss_NumScanKeys;
- n_keys = numScanKeys[indexPtr];
- run_keys = (int *) runtimeKeyInfo[indexPtr];
- scan_keys = (ScanKey) scanKeys[indexPtr];
-
- for (j=0; j < n_keys; j++) {
- /*
- * If we have a run-time key, then extract the run-time
- * expression and evaluate it with respect to the current
- * outer tuple. We then stick the result into the scan
- * key.
- */
- if (run_keys[j] != NO_OP) {
- clause = nth(j, qual);
- 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, exprCtxt, &isNull, &isDone);
- scan_keys[j].sk_argument = scanvalue;
- if (isNull) {
- scan_keys[j].sk_flags |= SK_ISNULL;
- } else {
- scan_keys[j].sk_flags &= ~SK_ISNULL;
+ EState *estate;
+ IndexScanState *indexstate;
+ ScanDirection direction;
+ IndexScanDescPtr scanDescs;
+ ScanKey *scanKeys;
+ IndexScanDesc sdesc;
+ ScanKey skey;
+ int numIndices;
+ int i;
+
+ Pointer *runtimeKeyInfo;
+ int indexPtr;
+ int *numScanKeys;
+ List *indxqual;
+ List *qual;
+ int n_keys;
+ ScanKey scan_keys;
+ int *run_keys;
+ int j;
+ Expr *clause;
+ Node *scanexpr;
+ Datum scanvalue;
+ bool isNull;
+ bool isDone;
+
+ indexstate = node->indxstate;
+ estate = node->scan.plan.state;
+ direction = estate->es_direction;
+ indexstate = node->indxstate;
+ numIndices = indexstate->iss_NumIndices;
+ scanDescs = indexstate->iss_ScanDescs;
+ scanKeys = indexstate->iss_ScanKeys;
+
+ runtimeKeyInfo = (Pointer *) indexstate->iss_RuntimeKeyInfo;
+
+ if (runtimeKeyInfo != NULL)
+ {
+
+ /*
+ * get the index qualifications and recalculate the appropriate
+ * values
+ */
+ indexPtr = indexstate->iss_IndexPtr;
+ indxqual = node->indxqual;
+ qual = nth(indexPtr, indxqual);
+ numScanKeys = indexstate->iss_NumScanKeys;
+ n_keys = numScanKeys[indexPtr];
+ run_keys = (int *) runtimeKeyInfo[indexPtr];
+ scan_keys = (ScanKey) scanKeys[indexPtr];
+
+ for (j = 0; j < n_keys; j++)
+ {
+
+ /*
+ * If we have a run-time key, then extract the run-time
+ * expression and evaluate it with respect to the current
+ * outer tuple. We then stick the result into the scan key.
+ */
+ if (run_keys[j] != NO_OP)
+ {
+ clause = nth(j, qual);
+ 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, exprCtxt, &isNull, &isDone);
+ scan_keys[j].sk_argument = scanvalue;
+ if (isNull)
+ {
+ scan_keys[j].sk_flags |= SK_ISNULL;
+ }
+ else
+ {
+ scan_keys[j].sk_flags &= ~SK_ISNULL;
+ }
+ }
}
- }
}
- }
-
- /*
- * rescans all indices
- *
- * note: AMrescan assumes only one scan key. This may have
- * to change if we ever decide to support multiple keys.
- */
- for (i = 0; i < numIndices; i++) {
- sdesc = scanDescs[ i ];
- skey = scanKeys[ i ];
- index_rescan(sdesc, direction, skey);
- }
-
- /* ----------------
- * perhaps return something meaningful
- * ----------------
- */
- return;
+
+ /*
+ * rescans all indices
+ *
+ * note: AMrescan assumes only one scan key. This may have to change if
+ * we ever decide to support multiple keys.
+ */
+ for (i = 0; i < numIndices; i++)
+ {
+ sdesc = scanDescs[i];
+ skey = scanKeys[i];
+ index_rescan(sdesc, direction, skey);
+ }
+
+ /* ----------------
+ * perhaps return something meaningful
+ * ----------------
+ */
+ return;
}
/* ----------------------------------------------------------------
- * ExecEndIndexScan
+ * ExecEndIndexScan
*
* old comments
- * Releases any storage allocated through C routines.
- * Returns nothing.
+ * Releases any storage allocated through C routines.
+ * Returns nothing.
* ----------------------------------------------------------------
*/
void
-ExecEndIndexScan(IndexScan *node)
+ExecEndIndexScan(IndexScan * node)
{
- CommonScanState *scanstate;
- IndexScanState *indexstate;
- ScanKey *scanKeys;
- int numIndices;
- int i;
-
- scanstate = node->scan.scanstate;
- indexstate = node->indxstate;
-
- /* ----------------
- * extract information from the node
- * ----------------
- */
- numIndices = indexstate->iss_NumIndices;
- scanKeys = indexstate->iss_ScanKeys;
-
- /* ----------------
- * Free the projection info and the scan attribute info
- *
- * Note: we don't ExecFreeResultType(scanstate)
- * because the rule manager depends on the tupType
- * returned by ExecMain(). So for now, this
- * is freed at end-transaction time. -cim 6/2/91
- * ----------------
- */
- ExecFreeProjectionInfo(&scanstate->cstate);
-
- /* ----------------
- * close the heap and index relations
- * ----------------
- */
- ExecCloseR((Plan *) node);
-
- /* ----------------
- * free the scan keys used in scanning the indices
- * ----------------
- */
- for (i=0; i<numIndices; i++) {
- if (scanKeys[i]!=NULL)
- pfree(scanKeys[i]);
-
- }
-
- /* ----------------
- * clear out tuple table slots
- * ----------------
- */
- ExecClearTuple(scanstate->cstate.cs_ResultTupleSlot);
- ExecClearTuple(scanstate->css_ScanTupleSlot);
-/* ExecClearTuple(scanstate->css_RawTupleSlot); */
+ CommonScanState *scanstate;
+ IndexScanState *indexstate;
+ ScanKey *scanKeys;
+ int numIndices;
+ int i;
+
+ scanstate = node->scan.scanstate;
+ indexstate = node->indxstate;
+
+ /* ----------------
+ * extract information from the node
+ * ----------------
+ */
+ numIndices = indexstate->iss_NumIndices;
+ scanKeys = indexstate->iss_ScanKeys;
+
+ /* ----------------
+ * Free the projection info and the scan attribute info
+ *
+ * Note: we don't ExecFreeResultType(scanstate)
+ * because the rule manager depends on the tupType
+ * returned by ExecMain(). So for now, this
+ * is freed at end-transaction time. -cim 6/2/91
+ * ----------------
+ */
+ ExecFreeProjectionInfo(&scanstate->cstate);
+
+ /* ----------------
+ * close the heap and index relations
+ * ----------------
+ */
+ ExecCloseR((Plan *) node);
+
+ /* ----------------
+ * free the scan keys used in scanning the indices
+ * ----------------
+ */
+ for (i = 0; i < numIndices; i++)
+ {
+ if (scanKeys[i] != NULL)
+ pfree(scanKeys[i]);
+
+ }
+
+ /* ----------------
+ * clear out tuple table slots
+ * ----------------
+ */
+ ExecClearTuple(scanstate->cstate.cs_ResultTupleSlot);
+ ExecClearTuple(scanstate->css_ScanTupleSlot);
+/* ExecClearTuple(scanstate->css_RawTupleSlot); */
}
/* ----------------------------------------------------------------
- * ExecIndexMarkPos
+ * ExecIndexMarkPos
*
* old comments
- * Marks scan position by marking the current index.
- * Returns nothing.
+ * Marks scan position by marking the current index.
+ * Returns nothing.
* ----------------------------------------------------------------
*/
void
-ExecIndexMarkPos(IndexScan *node)
+ExecIndexMarkPos(IndexScan * node)
{
- IndexScanState *indexstate;
- IndexScanDescPtr indexScanDescs;
- IndexScanDesc scanDesc;
- int indexPtr;
-
- indexstate = node->indxstate;
- indexPtr = indexstate->iss_IndexPtr;
- indexScanDescs = indexstate->iss_ScanDescs;
- scanDesc = indexScanDescs[ indexPtr ];
-
- /* ----------------
- * XXX access methods don't return marked positions so
- * ----------------
- */
- IndexScanMarkPosition( scanDesc );
- return;
+ IndexScanState *indexstate;
+ IndexScanDescPtr indexScanDescs;
+ IndexScanDesc scanDesc;
+ int indexPtr;
+
+ indexstate = node->indxstate;
+ indexPtr = indexstate->iss_IndexPtr;
+ indexScanDescs = indexstate->iss_ScanDescs;
+ scanDesc = indexScanDescs[indexPtr];
+
+ /* ----------------
+ * XXX access methods don't return marked positions so
+ * ----------------
+ */
+ IndexScanMarkPosition(scanDesc);
+ return;
}
/* ----------------------------------------------------------------
- * ExecIndexRestrPos
+ * ExecIndexRestrPos
*
* old comments
- * Restores scan position by restoring the current index.
- * Returns nothing.
- *
- * XXX Assumes previously marked scan position belongs to current index
+ * Restores scan position by restoring the current index.
+ * Returns nothing.
+ *
+ * XXX Assumes previously marked scan position belongs to current index
* ----------------------------------------------------------------
*/
void
-ExecIndexRestrPos(IndexScan *node)
+ExecIndexRestrPos(IndexScan * node)
{
- IndexScanState *indexstate;
- IndexScanDescPtr indexScanDescs;
- IndexScanDesc scanDesc;
- int indexPtr;
+ IndexScanState *indexstate;
+ IndexScanDescPtr indexScanDescs;
+ IndexScanDesc scanDesc;
+ int indexPtr;
- indexstate = node->indxstate;
- indexPtr = indexstate->iss_IndexPtr;
- indexScanDescs = indexstate->iss_ScanDescs;
- scanDesc = indexScanDescs[ indexPtr ];
+ indexstate = node->indxstate;
+ indexPtr = indexstate->iss_IndexPtr;
+ indexScanDescs = indexstate->iss_ScanDescs;
+ scanDesc = indexScanDescs[indexPtr];
- IndexScanRestorePosition( scanDesc );
+ IndexScanRestorePosition(scanDesc);
}
/* ----------------------------------------------------------------
- * ExecInitIndexScan
+ * ExecInitIndexScan
+ *
+ * Initializes the index scan's state information, creates
+ * scan keys, and opens the base and index relations.
*
- * Initializes the index scan's state information, creates
- * scan keys, and opens the base and index relations.
+ * Note: index scans have 2 sets of state information because
+ * we have to keep track of the base relation and the
+ * index relations.
*
- * Note: index scans have 2 sets of state information because
- * we have to keep track of the base relation and the
- * index relations.
- *
* old comments
- * Creates the run-time state information for the node and
- * sets the relation id to contain relevant decriptors.
- *
- * Parameters:
- * node: IndexNode node produced by the planner.
- * estate: the execution state initialized in InitPlan.
+ * Creates the run-time state information for the node and
+ * sets the relation id to contain relevant decriptors.
+ *
+ * Parameters:
+ * node: IndexNode node produced by the planner.
+ * estate: the execution state initialized in InitPlan.
* ----------------------------------------------------------------
*/
bool
-ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
+ExecInitIndexScan(IndexScan * node, EState * estate, Plan * parent)
{
- IndexScanState *indexstate;
- CommonScanState *scanstate;
- List *indxqual;
- List *indxid;
- int i;
- int numIndices;
- int indexPtr;
- ScanKey *scanKeys;
- int *numScanKeys;
- RelationPtr relationDescs;
- IndexScanDescPtr scanDescs;
- Pointer *runtimeKeyInfo;
- bool have_runtime_keys;
- List *rangeTable;
- RangeTblEntry *rtentry;
- Index relid;
- Oid reloid;
- TimeQual timeQual;
-
- Relation currentRelation;
- HeapScanDesc currentScanDesc;
- ScanDirection direction;
- int baseid;
-
- /* ----------------
- * assign execution state to node
- * ----------------
- */
- node->scan.plan.state = estate;
-
- /* --------------------------------
- * Part 1) initialize scan state
- *
- * create new CommonScanState for node
- * --------------------------------
- */
- scanstate = makeNode(CommonScanState);
+ IndexScanState *indexstate;
+ CommonScanState *scanstate;
+ List *indxqual;
+ List *indxid;
+ int i;
+ int numIndices;
+ int indexPtr;
+ ScanKey *scanKeys;
+ int *numScanKeys;
+ RelationPtr relationDescs;
+ IndexScanDescPtr scanDescs;
+ Pointer *runtimeKeyInfo;
+ bool have_runtime_keys;
+ List *rangeTable;
+ RangeTblEntry *rtentry;
+ Index relid;
+ Oid reloid;
+ TimeQual timeQual;
+
+ Relation currentRelation;
+ HeapScanDesc currentScanDesc;
+ ScanDirection direction;
+ int baseid;
+
+ /* ----------------
+ * assign execution state to node
+ * ----------------
+ */
+ node->scan.plan.state = estate;
+
+ /* --------------------------------
+ * Part 1) initialize scan state
+ *
+ * create new CommonScanState for node
+ * --------------------------------
+ */
+ scanstate = makeNode(CommonScanState);
/*
- scanstate->ss_ProcOuterFlag = false;
- scanstate->ss_OldRelId = 0;
+ scanstate->ss_ProcOuterFlag = false;
+ scanstate->ss_OldRelId = 0;
*/
- node->scan.scanstate = scanstate;
+ node->scan.scanstate = scanstate;
- /* ----------------
- * assign node's base_id .. we don't use AssignNodeBaseid() because
- * the increment is done later on after we assign the index scan's
- * scanstate. see below.
- * ----------------
- */
- baseid = estate->es_BaseId;
-/* scanstate->csstate.cstate.bnode.base_id = baseid; */
- scanstate->cstate.cs_base_id = baseid;
+ /* ----------------
+ * assign node's base_id .. we don't use AssignNodeBaseid() because
+ * the increment is done later on after we assign the index scan's
+ * scanstate. see below.
+ * ----------------
+ */
+ baseid = estate->es_BaseId;
+/* scanstate->csstate.cstate.bnode.base_id = baseid; */
+ scanstate->cstate.cs_base_id = baseid;
- /* ----------------
- * create expression context for node
- * ----------------
- */
- ExecAssignExprContext(estate, &scanstate->cstate);
+ /* ----------------
+ * create expression context for node
+ * ----------------
+ */
+ ExecAssignExprContext(estate, &scanstate->cstate);
#define INDEXSCAN_NSLOTS 3
- /* ----------------
- * tuple table initialization
- * ----------------
- */
- ExecInitResultTupleSlot(estate, &scanstate->cstate);
- ExecInitScanTupleSlot(estate, scanstate);
-/* ExecInitRawTupleSlot(estate, scanstate); */
-
- /* ----------------
- * initialize projection info. result type comes from scan desc
- * below..
- * ----------------
- */
- ExecAssignProjectionInfo((Plan *) node, &scanstate->cstate);
-
- /* --------------------------------
- * Part 2) initialize index scan state
- *
- * create new IndexScanState for node
- * --------------------------------
- */
- indexstate = makeNode(IndexScanState);
- indexstate->iss_NumIndices = 0;
- indexstate->iss_IndexPtr = 0;
- indexstate->iss_ScanKeys = NULL;
- indexstate->iss_NumScanKeys = NULL;
- indexstate->iss_RuntimeKeyInfo = NULL;
- indexstate->iss_RelationDescs = NULL;
- indexstate->iss_ScanDescs = NULL;
-
- node->indxstate = indexstate;
-
- /* ----------------
- * assign base id to index scan state also
- * ----------------
- */
- indexstate->cstate.cs_base_id = baseid;
- baseid++;
- estate->es_BaseId = baseid;
-
- /* ----------------
- * get the index node information
- * ----------------
- */
- indxid = node->indxid;
- indxqual = node->indxqual;
- numIndices = length(indxid);
- indexPtr = 0;
-
- CXT1_printf("ExecInitIndexScan: context is %d\n", CurrentMemoryContext);
-
- /* ----------------
- * scanKeys is used to keep track of the ScanKey's. This is needed
- * because a single scan may use several indices and each index has
- * its own ScanKey.
- * ----------------
- */
- numScanKeys = (int *) palloc(numIndices * sizeof(int));
- scanKeys = (ScanKey *) palloc(numIndices * sizeof(ScanKey));
- relationDescs = (RelationPtr) palloc(numIndices * sizeof(Relation));
- scanDescs = (IndexScanDescPtr) palloc(numIndices * sizeof(IndexScanDesc));
-
- /* ----------------
- * initialize runtime key info.
- * ----------------
- */
- have_runtime_keys = false;
- runtimeKeyInfo = (Pointer *)
- palloc(numIndices * sizeof(Pointer));
-
- /* ----------------
- * build the index scan keys from the index qualification
- * ----------------
- */
- for (i=0; i < numIndices; i++) {
- int j;
- List *qual;
- int n_keys;
- ScanKey scan_keys;
- int *run_keys;
-
- qual = nth(i, indxqual);
- n_keys = length(qual);
- scan_keys = (n_keys <= 0) ? NULL :
- (ScanKey)palloc(n_keys * sizeof(ScanKeyData));
- run_keys = (n_keys <= 0) ? NULL :
- (int *)palloc(n_keys * sizeof(int));
-
- CXT1_printf("ExecInitIndexScan: context is %d\n",
- CurrentMemoryContext);
-
/* ----------------
- * for each opclause in the given qual,
- * convert each qual's opclause into a single scan key
+ * tuple table initialization
* ----------------
*/
- for (j=0; j < n_keys; j++) {
- Expr *clause; /* one part of index qual */
- Oper *op; /* operator used in scan.. */
- Node *leftop; /* expr on lhs of operator */
- Node *rightop; /* expr on rhs ... */
- bits16 flags = 0;
-
- int scanvar; /* which var identifies varattno */
- AttrNumber varattno = 0; /* att number used in scan */
- Oid opid; /* operator id used in scan */
- Datum scanvalue = 0; /* value used in scan (if const) */
-
- /* ----------------
- * extract clause information from the qualification
- * ----------------
- */
- clause = nth(j, qual);
-
- op = (Oper*)clause->oper;
- if (!IsA(op,Oper))
- elog(WARN, "ExecInitIndexScan: op not an Oper!");
-
- opid = op->opid;
-
- /* ----------------
- * Here we figure out the contents of the index qual.
- * The usual case is (op var const) or (op const var)
- * which means we form a scan key for the attribute
- * listed in the var node and use the value of the const.
- *
- * If we don't have a const node, then it means that
- * one of the var nodes refers to the "scan" tuple and
- * is used to determine which attribute to scan, and the
- * other expression is used to calculate the value used in
- * scanning the index.
- *
- * This means our index scan's scan key is a function of
- * information obtained during the execution of the plan
- * in which case we need to recalculate the index scan key
- * at run time.
- *
- * Hence, we set have_runtime_keys to true and then set
- * the appropriate flag in run_keys to LEFT_OP or RIGHT_OP.
- * The corresponding scan keys are recomputed at run time.
- * ----------------
- */
-
- scanvar = NO_OP;
-
- /* ----------------
- * determine information in leftop
- * ----------------
- */
- leftop = (Node*) get_leftop(clause);
-
- if (IsA(leftop,Var) && var_is_rel((Var*)leftop)) {
- /* ----------------
- * if the leftop is a "rel-var", then it means
- * that it is a var node which tells us which
- * attribute to use for our scan key.
- * ----------------
- */
- varattno = ((Var*) leftop)->varattno;
- scanvar = LEFT_OP;
- } else if (IsA(leftop,Const)) {
+ ExecInitResultTupleSlot(estate, &scanstate->cstate);
+ ExecInitScanTupleSlot(estate, scanstate);
+/* ExecInitRawTupleSlot(estate, scanstate); */
+
+ /* ----------------
+ * initialize projection info. result type comes from scan desc
+ * below..
+ * ----------------
+ */
+ ExecAssignProjectionInfo((Plan *) node, &scanstate->cstate);
+
+ /* --------------------------------
+ * Part 2) initialize index scan state
+ *
+ * create new IndexScanState for node
+ * --------------------------------
+ */
+ indexstate = makeNode(IndexScanState);
+ indexstate->iss_NumIndices = 0;
+ indexstate->iss_IndexPtr = 0;
+ indexstate->iss_ScanKeys = NULL;
+ indexstate->iss_NumScanKeys = NULL;
+ indexstate->iss_RuntimeKeyInfo = NULL;
+ indexstate->iss_RelationDescs = NULL;
+ indexstate->iss_ScanDescs = NULL;
+
+ node->indxstate = indexstate;
+
+ /* ----------------
+ * assign base id to index scan state also
+ * ----------------
+ */
+ indexstate->cstate.cs_base_id = baseid;
+ baseid++;
+ estate->es_BaseId = baseid;
+
+ /* ----------------
+ * get the index node information
+ * ----------------
+ */
+ indxid = node->indxid;
+ indxqual = node->indxqual;
+ numIndices = length(indxid);
+ indexPtr = 0;
+
+ CXT1_printf("ExecInitIndexScan: context is %d\n", CurrentMemoryContext);
+
+ /* ----------------
+ * scanKeys is used to keep track of the ScanKey's. This is needed
+ * because a single scan may use several indices and each index has
+ * its own ScanKey.
+ * ----------------
+ */
+ numScanKeys = (int *) palloc(numIndices * sizeof(int));
+ scanKeys = (ScanKey *) palloc(numIndices * sizeof(ScanKey));
+ relationDescs = (RelationPtr) palloc(numIndices * sizeof(Relation));
+ scanDescs = (IndexScanDescPtr) palloc(numIndices * sizeof(IndexScanDesc));
+
+ /* ----------------
+ * initialize runtime key info.
+ * ----------------
+ */
+ have_runtime_keys = false;
+ runtimeKeyInfo = (Pointer *)
+ palloc(numIndices * sizeof(Pointer));
+
+ /* ----------------
+ * build the index scan keys from the index qualification
+ * ----------------
+ */
+ for (i = 0; i < numIndices; i++)
+ {
+ int j;
+ List *qual;
+ int n_keys;
+ ScanKey scan_keys;
+ int *run_keys;
+
+ qual = nth(i, indxqual);
+ n_keys = length(qual);
+ scan_keys = (n_keys <= 0) ? NULL :
+ (ScanKey) palloc(n_keys * sizeof(ScanKeyData));
+ run_keys = (n_keys <= 0) ? NULL :
+ (int *) palloc(n_keys * sizeof(int));
+
+ CXT1_printf("ExecInitIndexScan: context is %d\n",
+ CurrentMemoryContext);
+
/* ----------------
- * if the leftop is a const node then it means
- * it identifies the value to place in our scan key.
+ * for each opclause in the given qual,
+ * convert each qual's opclause into a single scan key
* ----------------
*/
- run_keys[ j ] = NO_OP;
- scanvalue = ((Const*) leftop)->constvalue;
+ for (j = 0; j < n_keys; j++)
+ {
+ Expr *clause; /* one part of index qual */
+ Oper *op; /* operator used in scan.. */
+ Node *leftop; /* expr on lhs of operator */
+ Node *rightop; /* expr on rhs ... */
+ bits16 flags = 0;
+
+ int scanvar; /* which var identifies varattno */
+ AttrNumber varattno = 0; /* att number used in scan */
+ Oid opid; /* operator id used in scan */
+ Datum scanvalue = 0; /* value used in scan (if
+ * const) */
+
+ /* ----------------
+ * extract clause information from the qualification
+ * ----------------
+ */
+ clause = nth(j, qual);
+
+ op = (Oper *) clause->oper;
+ if (!IsA(op, Oper))
+ elog(WARN, "ExecInitIndexScan: op not an Oper!");
+
+ opid = op->opid;
+
+ /* ----------------
+ * Here we figure out the contents of the index qual.
+ * The usual case is (op var const) or (op const var)
+ * which means we form a scan key for the attribute
+ * listed in the var node and use the value of the const.
+ *
+ * If we don't have a const node, then it means that
+ * one of the var nodes refers to the "scan" tuple and
+ * is used to determine which attribute to scan, and the
+ * other expression is used to calculate the value used in
+ * scanning the index.
+ *
+ * This means our index scan's scan key is a function of
+ * information obtained during the execution of the plan
+ * in which case we need to recalculate the index scan key
+ * at run time.
+ *
+ * Hence, we set have_runtime_keys to true and then set
+ * the appropriate flag in run_keys to LEFT_OP or RIGHT_OP.
+ * The corresponding scan keys are recomputed at run time.
+ * ----------------
+ */
+
+ scanvar = NO_OP;
+
+ /* ----------------
+ * determine information in leftop
+ * ----------------
+ */
+ leftop = (Node *) get_leftop(clause);
+
+ if (IsA(leftop, Var) && var_is_rel((Var *) leftop))
+ {
+ /* ----------------
+ * if the leftop is a "rel-var", then it means
+ * that it is a var node which tells us which
+ * attribute to use for our scan key.
+ * ----------------
+ */
+ varattno = ((Var *) leftop)->varattno;
+ scanvar = LEFT_OP;
+ }
+ else if (IsA(leftop, Const))
+ {
+ /* ----------------
+ * if the leftop is a const node then it means
+ * it identifies the value to place in our scan key.
+ * ----------------
+ */
+ run_keys[j] = NO_OP;
+ scanvalue = ((Const *) leftop)->constvalue;
#ifdef INDEXSCAN_PATCH
- } else if (IsA(leftop,Param)) {
- bool isnull;
- /* ----------------
- * if the leftop is a Param node then it means
- * it identifies the value to place in our scan key.
- * ----------------
- */
- run_keys[ j ] = NO_OP;
- scanvalue = ExecEvalParam((Param*) leftop,
- scanstate->cstate.cs_ExprContext,
- &isnull);
- if ( isnull )
- flags |= SK_ISNULL;
+ }
+ else if (IsA(leftop, Param))
+ {
+ bool isnull;
+
+ /* ----------------
+ * if the leftop is a Param node then it means
+ * it identifies the value to place in our scan key.
+ * ----------------
+ */
+ run_keys[j] = NO_OP;
+ scanvalue = ExecEvalParam((Param *) leftop,
+ scanstate->cstate.cs_ExprContext,
+ &isnull);
+ if (isnull)
+ flags |= SK_ISNULL;
#endif
- } else if (leftop != NULL &&
- is_funcclause(leftop) &&
- var_is_rel(lfirst(((Expr*)leftop)->args))) {
- /* ----------------
- * if the leftop is a func node then it means
- * it identifies the value to place in our scan key.
- * Since functional indices have only one attribute
- * the attno must always be set to 1.
- * ----------------
- */
- varattno = 1;
- scanvar = LEFT_OP;
-
- } else {
- /* ----------------
- * otherwise, the leftop contains information usable
- * at runtime to figure out the value to place in our
- * scan key.
- * ----------------
- */
- have_runtime_keys = true;
- run_keys[ j ] = LEFT_OP;
- scanvalue = Int32GetDatum((int32) true);
- }
-
- /* ----------------
- * now determine information in rightop
- * ----------------
- */
- rightop = (Node*) get_rightop(clause);
-
- if (IsA(rightop,Var) && var_is_rel((Var*)rightop)) {
- /* ----------------
- * here we make sure only one op identifies the
- * scan-attribute...
- * ----------------
- */
- if (scanvar == LEFT_OP)
- elog(WARN, "ExecInitIndexScan: %s",
- "both left and right op's are rel-vars");
-
- /* ----------------
- * if the rightop is a "rel-var", then it means
- * that it is a var node which tells us which
- * attribute to use for our scan key.
- * ----------------
- */
- varattno = ((Var*) rightop)->varattno;
- scanvar = RIGHT_OP;
-
- } else if (IsA(rightop,Const)) {
- /* ----------------
- * if the leftop is a const node then it means
- * it identifies the value to place in our scan key.
- * ----------------
- */
- run_keys[ j ] = NO_OP;
- scanvalue = ((Const*) rightop)->constvalue;
+ }
+ else if (leftop != NULL &&
+ is_funcclause(leftop) &&
+ var_is_rel(lfirst(((Expr *) leftop)->args)))
+ {
+ /* ----------------
+ * if the leftop is a func node then it means
+ * it identifies the value to place in our scan key.
+ * Since functional indices have only one attribute
+ * the attno must always be set to 1.
+ * ----------------
+ */
+ varattno = 1;
+ scanvar = LEFT_OP;
+
+ }
+ else
+ {
+ /* ----------------
+ * otherwise, the leftop contains information usable
+ * at runtime to figure out the value to place in our
+ * scan key.
+ * ----------------
+ */
+ have_runtime_keys = true;
+ run_keys[j] = LEFT_OP;
+ scanvalue = Int32GetDatum((int32) true);
+ }
+
+ /* ----------------
+ * now determine information in rightop
+ * ----------------
+ */
+ rightop = (Node *) get_rightop(clause);
+
+ if (IsA(rightop, Var) && var_is_rel((Var *) rightop))
+ {
+ /* ----------------
+ * here we make sure only one op identifies the
+ * scan-attribute...
+ * ----------------
+ */
+ if (scanvar == LEFT_OP)
+ elog(WARN, "ExecInitIndexScan: %s",
+ "both left and right op's are rel-vars");
+
+ /* ----------------
+ * if the rightop is a "rel-var", then it means
+ * that it is a var node which tells us which
+ * attribute to use for our scan key.
+ * ----------------
+ */
+ varattno = ((Var *) rightop)->varattno;
+ scanvar = RIGHT_OP;
+
+ }
+ else if (IsA(rightop, Const))
+ {
+ /* ----------------
+ * if the leftop is a const node then it means
+ * it identifies the value to place in our scan key.
+ * ----------------
+ */
+ run_keys[j] = NO_OP;
+ scanvalue = ((Const *) rightop)->constvalue;
#ifdef INDEXSCAN_PATCH
- } else if (IsA(rightop,Param)) {
- bool isnull;
- /* ----------------
- * if the rightop is a Param node then it means
- * it identifies the value to place in our scan key.
- * ----------------
- */
- run_keys[ j ] = NO_OP;
- scanvalue = ExecEvalParam((Param*) rightop,
- scanstate->cstate.cs_ExprContext,
- &isnull);
- if ( isnull )
- flags |= SK_ISNULL;
+ }
+ else if (IsA(rightop, Param))
+ {
+ bool isnull;
+
+ /* ----------------
+ * if the rightop is a Param node then it means
+ * it identifies the value to place in our scan key.
+ * ----------------
+ */
+ run_keys[j] = NO_OP;
+ scanvalue = ExecEvalParam((Param *) rightop,
+ scanstate->cstate.cs_ExprContext,
+ &isnull);
+ if (isnull)
+ flags |= SK_ISNULL;
#endif
- } else if (rightop!=NULL &&
- is_funcclause(rightop) &&
- var_is_rel(lfirst(((Expr*)rightop)->args))) {
- /* ----------------
- * if the rightop is a func node then it means
- * it identifies the value to place in our scan key.
- * Since functional indices have only one attribute
- * the attno must always be set to 1.
- * ----------------
- */
- if (scanvar == LEFT_OP)
- elog(WARN, "ExecInitIndexScan: %s",
- "both left and right ops are rel-vars");
-
- varattno = 1;
- scanvar = RIGHT_OP;
-
- } else {
+ }
+ else if (rightop != NULL &&
+ is_funcclause(rightop) &&
+ var_is_rel(lfirst(((Expr *) rightop)->args)))
+ {
+ /* ----------------
+ * if the rightop is a func node then it means
+ * it identifies the value to place in our scan key.
+ * Since functional indices have only one attribute
+ * the attno must always be set to 1.
+ * ----------------
+ */
+ if (scanvar == LEFT_OP)
+ elog(WARN, "ExecInitIndexScan: %s",
+ "both left and right ops are rel-vars");
+
+ varattno = 1;
+ scanvar = RIGHT_OP;
+
+ }
+ else
+ {
+ /* ----------------
+ * otherwise, the leftop contains information usable
+ * at runtime to figure out the value to place in our
+ * scan key.
+ * ----------------
+ */
+ have_runtime_keys = true;
+ run_keys[j] = RIGHT_OP;
+ scanvalue = Int32GetDatum((int32) true);
+ }
+
+ /* ----------------
+ * now check that at least one op tells us the scan
+ * attribute...
+ * ----------------
+ */
+ if (scanvar == NO_OP)
+ elog(WARN, "ExecInitIndexScan: %s",
+ "neither leftop nor rightop refer to scan relation");
+
+ /* ----------------
+ * initialize the scan key's fields appropriately
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&scan_keys[j],
+ flags,
+ varattno, /* attribute number to
+ * scan */
+ (RegProcedure) opid, /* reg proc to use */
+ (Datum) scanvalue); /* constant */
+ }
+
/* ----------------
- * otherwise, the leftop contains information usable
- * at runtime to figure out the value to place in our
- * scan key.
+ * store the key information into our array.
* ----------------
*/
- have_runtime_keys = true;
- run_keys[ j ] = RIGHT_OP;
- scanvalue = Int32GetDatum((int32) true);
- }
-
- /* ----------------
- * now check that at least one op tells us the scan
- * attribute...
- * ----------------
- */
- if (scanvar == NO_OP)
- elog(WARN, "ExecInitIndexScan: %s",
- "neither leftop nor rightop refer to scan relation");
-
- /* ----------------
- * initialize the scan key's fields appropriately
- * ----------------
- */
- ScanKeyEntryInitialize(&scan_keys[j],
- flags,
- varattno, /* attribute number to scan */
- (RegProcedure) opid, /* reg proc to use */
- (Datum) scanvalue); /* constant */
+ numScanKeys[i] = n_keys;
+ scanKeys[i] = scan_keys;
+ runtimeKeyInfo[i] = (Pointer) run_keys;
}
-
+
+ indexstate->iss_NumIndices = numIndices;
+ indexstate->iss_IndexPtr = indexPtr;
+ indexstate->iss_ScanKeys = scanKeys;
+ indexstate->iss_NumScanKeys = numScanKeys;
+
/* ----------------
- * store the key information into our array.
+ * If all of our keys have the form (op var const) , then we have no
+ * runtime keys so we store NULL in the runtime key info.
+ * Otherwise runtime key info contains an array of pointers
+ * (one for each index) to arrays of flags (one for each key)
+ * which indicate that the qual needs to be evaluated at runtime.
+ * -cim 10/24/89
* ----------------
*/
- numScanKeys[ i ] = n_keys;
- scanKeys[ i ] = scan_keys;
- runtimeKeyInfo[ i ] = (Pointer) run_keys;
- }
-
- indexstate->iss_NumIndices = numIndices;
- indexstate->iss_IndexPtr = indexPtr;
- indexstate->iss_ScanKeys = scanKeys;
- indexstate->iss_NumScanKeys = numScanKeys;
-
- /* ----------------
- * If all of our keys have the form (op var const) , then we have no
- * runtime keys so we store NULL in the runtime key info.
- * Otherwise runtime key info contains an array of pointers
- * (one for each index) to arrays of flags (one for each key)
- * which indicate that the qual needs to be evaluated at runtime.
- * -cim 10/24/89
- * ----------------
- */
- if (have_runtime_keys)
+ if (have_runtime_keys)
{
- indexstate->iss_RuntimeKeyInfo = (Pointer) runtimeKeyInfo;
+ indexstate->iss_RuntimeKeyInfo = (Pointer) runtimeKeyInfo;
}
- else {
- indexstate->iss_RuntimeKeyInfo = NULL;
- for (i=0; i < numIndices; i++) {
- List *qual;
- int n_keys;
- qual = nth(i, indxqual);
- n_keys = length(qual);
- if (n_keys > 0)
- pfree(runtimeKeyInfo[i]);
+ else
+ {
+ indexstate->iss_RuntimeKeyInfo = NULL;
+ for (i = 0; i < numIndices; i++)
+ {
+ List *qual;
+ int n_keys;
+
+ qual = nth(i, indxqual);
+ n_keys = length(qual);
+ if (n_keys > 0)
+ pfree(runtimeKeyInfo[i]);
+ }
+ pfree(runtimeKeyInfo);
}
- pfree(runtimeKeyInfo);
- }
-
- /* ----------------
- * get the range table and direction information
- * from the execution state (these are needed to
- * open the relations).
- * ----------------
- */
- rangeTable = estate->es_range_table;
- direction = estate->es_direction;
-
- /* ----------------
- * open the base relation
- * ----------------
- */
- relid = node->scan.scanrelid;
- rtentry = rt_fetch(relid, rangeTable);
- reloid = rtentry->relid;
- timeQual = rtentry->timeQual;
-
- ExecOpenScanR(reloid, /* relation */
- 0, /* nkeys */
- (ScanKey) NULL, /* scan key */
- 0, /* is index */
- direction, /* scan direction */
- timeQual, /* time qual */
- &currentRelation, /* return: rel desc */
- (Pointer *) &currentScanDesc); /* return: scan desc */
-
- scanstate->css_currentRelation = currentRelation;
- scanstate->css_currentScanDesc = currentScanDesc;
-
-
- /* ----------------
- * get the scan type from the relation descriptor.
- * ----------------
- */
- ExecAssignScanType(scanstate, RelationGetTupleDescriptor(currentRelation));
- ExecAssignResultTypeFromTL((Plan *) node, &scanstate->cstate);
-
- /* ----------------
- * index scans don't have subtrees..
- * ----------------
- */
-/* scanstate->ss_ProcOuterFlag = false; */
-
- /* ----------------
- * open the index relations and initialize
- * relation and scan descriptors.
- * ----------------
- */
- for (i=0; i < numIndices; i++) {
- Oid indexOid;
-
- indexOid = (Oid)nthi(i, indxid);
-
- if (indexOid != 0) {
- ExecOpenScanR(indexOid, /* relation */
- numScanKeys[ i ], /* nkeys */
- scanKeys[ i ], /* scan key */
- true, /* is index */
- direction, /* scan direction */
- timeQual, /* time qual */
- &(relationDescs[ i ]), /* return: rel desc */
- (Pointer *) &(scanDescs[ i ]));
- /* return: scan desc */
+
+ /* ----------------
+ * get the range table and direction information
+ * from the execution state (these are needed to
+ * open the relations).
+ * ----------------
+ */
+ rangeTable = estate->es_range_table;
+ direction = estate->es_direction;
+
+ /* ----------------
+ * open the base relation
+ * ----------------
+ */
+ relid = node->scan.scanrelid;
+ rtentry = rt_fetch(relid, rangeTable);
+ reloid = rtentry->relid;
+ timeQual = rtentry->timeQual;
+
+ ExecOpenScanR(reloid, /* relation */
+ 0, /* nkeys */
+ (ScanKey) NULL, /* scan key */
+ 0, /* is index */
+ direction, /* scan direction */
+ timeQual, /* time qual */
+ &currentRelation, /* return: rel desc */
+ (Pointer *) & currentScanDesc); /* return: scan desc */
+
+ scanstate->css_currentRelation = currentRelation;
+ scanstate->css_currentScanDesc = currentScanDesc;
+
+
+ /* ----------------
+ * get the scan type from the relation descriptor.
+ * ----------------
+ */
+ ExecAssignScanType(scanstate, RelationGetTupleDescriptor(currentRelation));
+ ExecAssignResultTypeFromTL((Plan *) node, &scanstate->cstate);
+
+ /* ----------------
+ * index scans don't have subtrees..
+ * ----------------
+ */
+/* scanstate->ss_ProcOuterFlag = false; */
+
+ /* ----------------
+ * open the index relations and initialize
+ * relation and scan descriptors.
+ * ----------------
+ */
+ for (i = 0; i < numIndices; i++)
+ {
+ Oid indexOid;
+
+ indexOid = (Oid) nthi(i, indxid);
+
+ if (indexOid != 0)
+ {
+ ExecOpenScanR(indexOid, /* relation */
+ numScanKeys[i], /* nkeys */
+ scanKeys[i], /* scan key */
+ true, /* is index */
+ direction, /* scan direction */
+ timeQual, /* time qual */
+ &(relationDescs[i]), /* return: rel desc */
+ (Pointer *) & (scanDescs[i]));
+ /* return: scan desc */
+ }
}
- }
- indexstate->iss_RelationDescs = relationDescs;
- indexstate->iss_ScanDescs = scanDescs;
+ indexstate->iss_RelationDescs = relationDescs;
+ indexstate->iss_ScanDescs = scanDescs;
- indexstate->cstate.cs_TupFromTlist = false;
+ indexstate->cstate.cs_TupFromTlist = false;
- /* ----------------
- * all done.
- * ----------------
- */
- return TRUE;
+ /* ----------------
+ * all done.
+ * ----------------
+ */
+ return TRUE;
}
int
-ExecCountSlotsIndexScan(IndexScan *node)
+ExecCountSlotsIndexScan(IndexScan * node)
{
- return ExecCountSlotsNode(outerPlan((Plan *)node)) +
- ExecCountSlotsNode(innerPlan((Plan *)node)) +
- INDEXSCAN_NSLOTS;
+ return ExecCountSlotsNode(outerPlan((Plan *) node)) +
+ ExecCountSlotsNode(innerPlan((Plan *) node)) +
+ INDEXSCAN_NSLOTS;
}
diff --git a/src/backend/executor/nodeMaterial.c b/src/backend/executor/nodeMaterial.c
index daf324bb77a..49ba73d3bf0 100644
--- a/src/backend/executor/nodeMaterial.c
+++ b/src/backend/executor/nodeMaterial.c
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nodeMaterial.c--
- * Routines to handle materialization nodes.
+ * Routines to handle materialization nodes.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.6 1997/08/20 14:53:24 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.7 1997/09/07 04:41:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * ExecMaterial - generate a temporary relation
- * ExecInitMaterial - initialize node and subnodes..
- * ExecEndMaterial - shutdown node and subnodes
+ * ExecMaterial - generate a temporary relation
+ * ExecInitMaterial - initialize node and subnodes..
+ * ExecEndMaterial - shutdown node and subnodes
*
*/
#include "postgres.h"
@@ -29,368 +29,373 @@
#include "access/heapam.h"
/* ----------------------------------------------------------------
- * ExecMaterial
+ * ExecMaterial
*
- * The first time this is called, ExecMaterial retrieves tuples
- * this node's outer subplan and inserts them into a temporary
- * relation. After this is done, a flag is set indicating that
- * the subplan has been materialized. Once the relation is
- * materialized, the first tuple is then returned. Successive
- * calls to ExecMaterial return successive tuples from the temp
- * relation.
+ * The first time this is called, ExecMaterial retrieves tuples
+ * this node's outer subplan and inserts them into a temporary
+ * relation. After this is done, a flag is set indicating that
+ * the subplan has been materialized. Once the relation is
+ * materialized, the first tuple is then returned. Successive
+ * calls to ExecMaterial return successive tuples from the temp
+ * relation.
*
- * Initial State:
+ * Initial State:
*
- * ExecMaterial assumes the temporary relation has been
- * created and openend by ExecInitMaterial during the prior
- * InitPlan() phase.
+ * ExecMaterial assumes the temporary relation has been
+ * created and openend by ExecInitMaterial during the prior
+ * InitPlan() phase.
*
* ----------------------------------------------------------------
*/
-TupleTableSlot * /* result tuple from subplan */
-ExecMaterial(Material *node)
+TupleTableSlot * /* result tuple from subplan */
+ExecMaterial(Material * node)
{
- EState *estate;
- MaterialState *matstate;
- Plan *outerNode;
- ScanDirection dir;
- Relation tempRelation;
- Relation currentRelation;
- HeapScanDesc currentScanDesc;
- HeapTuple heapTuple;
- TupleTableSlot *slot;
- Buffer buffer;
-
- /* ----------------
- * get state info from node
- * ----------------
- */
- matstate = node->matstate;
- estate = node->plan.state;
- dir = estate->es_direction;
-
- /* ----------------
- * the first time we call this, we retrieve all tuples
- * from the subplan into a temporary relation and then
- * we sort the relation. Subsequent calls return tuples
- * from the temporary relation.
- * ----------------
- */
-
- if (matstate->mat_Flag == false) {
+ EState *estate;
+ MaterialState *matstate;
+ Plan *outerNode;
+ ScanDirection dir;
+ Relation tempRelation;
+ Relation currentRelation;
+ HeapScanDesc currentScanDesc;
+ HeapTuple heapTuple;
+ TupleTableSlot *slot;
+ Buffer buffer;
+
/* ----------------
- * set all relations to be scanned in the forward direction
- * while creating the temporary relation.
+ * get state info from node
* ----------------
*/
- estate->es_direction = ForwardScanDirection;
-
+ matstate = node->matstate;
+ estate = node->plan.state;
+ dir = estate->es_direction;
+
/* ----------------
- * if we couldn't create the temp or current relations then
- * we print a warning and return NULL.
+ * the first time we call this, we retrieve all tuples
+ * from the subplan into a temporary relation and then
+ * we sort the relation. Subsequent calls return tuples
+ * from the temporary relation.
* ----------------
*/
- tempRelation = matstate->mat_TempRelation;
- if (tempRelation == NULL) {
- elog(DEBUG, "ExecMaterial: temp relation is NULL! aborting...");
- return NULL;
- }
-
- currentRelation = matstate->csstate.css_currentRelation;
- if (currentRelation == NULL) {
- elog(DEBUG, "ExecMaterial: current relation is NULL! aborting...");
- return NULL;
+
+ if (matstate->mat_Flag == false)
+ {
+ /* ----------------
+ * set all relations to be scanned in the forward direction
+ * while creating the temporary relation.
+ * ----------------
+ */
+ estate->es_direction = ForwardScanDirection;
+
+ /* ----------------
+ * if we couldn't create the temp or current relations then
+ * we print a warning and return NULL.
+ * ----------------
+ */
+ tempRelation = matstate->mat_TempRelation;
+ if (tempRelation == NULL)
+ {
+ elog(DEBUG, "ExecMaterial: temp relation is NULL! aborting...");
+ return NULL;
+ }
+
+ currentRelation = matstate->csstate.css_currentRelation;
+ if (currentRelation == NULL)
+ {
+ elog(DEBUG, "ExecMaterial: current relation is NULL! aborting...");
+ return NULL;
+ }
+
+ /* ----------------
+ * retrieve tuples from the subplan and
+ * insert them in the temporary relation
+ * ----------------
+ */
+ outerNode = outerPlan((Plan *) node);
+ for (;;)
+ {
+ slot = ExecProcNode(outerNode, (Plan *) node);
+
+ heapTuple = slot->val;
+ if (heapTuple == NULL)
+ break;
+
+ heap_insert(tempRelation, /* relation desc */
+ heapTuple); /* heap tuple to insert */
+
+ ExecClearTuple(slot);
+ }
+ currentRelation = tempRelation;
+
+ /* ----------------
+ * restore to user specified direction
+ * ----------------
+ */
+ estate->es_direction = dir;
+
+ /* ----------------
+ * now initialize the scan descriptor to scan the
+ * sorted relation and update the sortstate information
+ * ----------------
+ */
+ currentScanDesc = heap_beginscan(currentRelation, /* relation */
+ ScanDirectionIsBackward(dir),
+ /* bkwd flag */
+ NowTimeQual, /* time qual */
+ 0, /* num scan keys */
+ NULL); /* scan keys */
+ matstate->csstate.css_currentRelation = currentRelation;
+ matstate->csstate.css_currentScanDesc = currentScanDesc;
+
+ ExecAssignScanType(&matstate->csstate,
+ RelationGetTupleDescriptor(currentRelation));
+
+ /* ----------------
+ * finally set the sorted flag to true
+ * ----------------
+ */
+ matstate->mat_Flag = true;
}
-
+
/* ----------------
- * retrieve tuples from the subplan and
- * insert them in the temporary relation
+ * at this point we know we have a sorted relation so
+ * we preform a simple scan on it with amgetnext()..
* ----------------
*/
- outerNode = outerPlan((Plan *) node);
- for (;;) {
- slot = ExecProcNode(outerNode, (Plan*) node);
-
- heapTuple = slot->val;
- if (heapTuple == NULL)
- break;
-
- heap_insert(tempRelation, /* relation desc */
- heapTuple); /* heap tuple to insert */
-
- ExecClearTuple( slot);
- }
- currentRelation = tempRelation;
-
+ currentScanDesc = matstate->csstate.css_currentScanDesc;
+
+ heapTuple = heap_getnext(currentScanDesc, /* scan desc */
+ ScanDirectionIsBackward(dir),
+ /* bkwd flag */
+ &buffer); /* return: buffer */
+
/* ----------------
- * restore to user specified direction
+ * put the tuple into the scan tuple slot and return the slot.
+ * Note: since the tuple is really a pointer to a page, we don't want
+ * to call pfree() on it..
* ----------------
*/
- estate->es_direction = dir;
-
+ slot = (TupleTableSlot *) matstate->csstate.css_ScanTupleSlot;
+
+ return ExecStoreTuple(heapTuple, /* tuple to store */
+ slot, /* slot to store in */
+ buffer, /* buffer for this tuple */
+ false); /* don't pfree this pointer */
+
+}
+
+/* ----------------------------------------------------------------
+ * ExecInitMaterial
+ * ----------------------------------------------------------------
+ */
+bool /* initialization status */
+ExecInitMaterial(Material * node, EState * estate, Plan * parent)
+{
+ MaterialState *matstate;
+ Plan *outerPlan;
+ TupleDesc tupType;
+ Relation tempDesc;
+
+ /* int len; */
+
/* ----------------
- * now initialize the scan descriptor to scan the
- * sorted relation and update the sortstate information
+ * assign the node's execution state
* ----------------
*/
- currentScanDesc = heap_beginscan(currentRelation, /* relation */
- ScanDirectionIsBackward(dir),
- /* bkwd flag */
- NowTimeQual, /* time qual */
- 0, /* num scan keys */
- NULL); /* scan keys */
- matstate->csstate.css_currentRelation = currentRelation;
- matstate->csstate.css_currentScanDesc = currentScanDesc;
-
- ExecAssignScanType(&matstate->csstate,
- RelationGetTupleDescriptor(currentRelation));
-
+ node->plan.state = estate;
+
/* ----------------
- * finally set the sorted flag to true
+ * create state structure
* ----------------
*/
- matstate->mat_Flag = true;
- }
-
- /* ----------------
- * at this point we know we have a sorted relation so
- * we preform a simple scan on it with amgetnext()..
- * ----------------
- */
- currentScanDesc = matstate->csstate.css_currentScanDesc;
-
- heapTuple = heap_getnext(currentScanDesc, /* scan desc */
- ScanDirectionIsBackward(dir),
- /* bkwd flag */
- &buffer); /* return: buffer */
-
- /* ----------------
- * put the tuple into the scan tuple slot and return the slot.
- * Note: since the tuple is really a pointer to a page, we don't want
- * to call pfree() on it..
- * ----------------
- */
- slot = (TupleTableSlot *)matstate->csstate.css_ScanTupleSlot;
-
- return ExecStoreTuple(heapTuple, /* tuple to store */
- slot, /* slot to store in */
- buffer, /* buffer for this tuple */
- false); /* don't pfree this pointer */
-
-}
+ matstate = makeNode(MaterialState);
+ matstate->mat_Flag = false;
+ matstate->mat_TempRelation = NULL;
+ node->matstate = matstate;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks and
+ * + assign result tuple slot
+ *
+ * Materialization nodes don't need ExprContexts because
+ * they never call ExecQual or ExecTargetList.
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &matstate->csstate.cstate, parent);
-/* ----------------------------------------------------------------
- * ExecInitMaterial
- * ----------------------------------------------------------------
- */
-bool /* initialization status */
-ExecInitMaterial(Material *node, EState *estate, Plan *parent)
-{
- MaterialState *matstate;
- Plan *outerPlan;
- TupleDesc tupType;
- Relation tempDesc;
- /* int len; */
-
- /* ----------------
- * assign the node's execution state
- * ----------------
- */
- node->plan.state = estate;
-
- /* ----------------
- * create state structure
- * ----------------
- */
- matstate = makeNode(MaterialState);
- matstate->mat_Flag = false;
- matstate->mat_TempRelation = NULL;
- node->matstate = matstate;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks and
- * + assign result tuple slot
- *
- * Materialization nodes don't need ExprContexts because
- * they never call ExecQual or ExecTargetList.
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &matstate->csstate.cstate, parent);
-
#define MATERIAL_NSLOTS 1
- /* ----------------
- * tuple table initialization
- * ----------------
- */
- ExecInitScanTupleSlot(estate, &matstate->csstate);
-
- /* ----------------
- * initializes child nodes
- * ----------------
- */
- outerPlan = outerPlan((Plan *) node);
- ExecInitNode(outerPlan, estate, (Plan *) node);
-
- /* ----------------
- * initialize matstate information
- * ----------------
- */
- matstate->mat_Flag = false;
-
- /* ----------------
- * initialize tuple type. no need to initialize projection
- * info because this node doesn't do projections.
- * ----------------
- */
- ExecAssignScanTypeFromOuterPlan((Plan *) node, &matstate->csstate);
- matstate->csstate.cstate.cs_ProjInfo = NULL;
-
- /* ----------------
- * get type information needed for ExecCreatR
- * ----------------
- */
- tupType = ExecGetScanType(&matstate->csstate);
-
- /* ----------------
- * ExecCreatR wants it's second argument to be an object id of
- * a relation in the range table or a _TEMP_RELATION_ID
- * indicating that the relation is not in the range table.
- *
- * In the second case ExecCreatR creates a temp relation.
- * (currently this is the only case we support -cim 10/16/89)
- * ----------------
- */
- /* ----------------
- * create the temporary relation
- * ----------------
- */
-/* len = ExecTargetListLength(node->plan.targetlist); */
- tempDesc = ExecCreatR(tupType, _TEMP_RELATION_ID_);
-
- /* ----------------
- * save the relation descriptor in the sortstate
- * ----------------
- */
- matstate->mat_TempRelation = tempDesc;
- matstate->csstate.css_currentRelation = tempDesc;
-
- /* ----------------
- * return relation oid of temporary relation in a list
- * (someday -- for now we return LispTrue... cim 10/12/89)
- * ----------------
- */
- return TRUE;
+ /* ----------------
+ * tuple table initialization
+ * ----------------
+ */
+ ExecInitScanTupleSlot(estate, &matstate->csstate);
+
+ /* ----------------
+ * initializes child nodes
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+ ExecInitNode(outerPlan, estate, (Plan *) node);
+
+ /* ----------------
+ * initialize matstate information
+ * ----------------
+ */
+ matstate->mat_Flag = false;
+
+ /* ----------------
+ * initialize tuple type. no need to initialize projection
+ * info because this node doesn't do projections.
+ * ----------------
+ */
+ ExecAssignScanTypeFromOuterPlan((Plan *) node, &matstate->csstate);
+ matstate->csstate.cstate.cs_ProjInfo = NULL;
+
+ /* ----------------
+ * get type information needed for ExecCreatR
+ * ----------------
+ */
+ tupType = ExecGetScanType(&matstate->csstate);
+
+ /* ----------------
+ * ExecCreatR wants it's second argument to be an object id of
+ * a relation in the range table or a _TEMP_RELATION_ID
+ * indicating that the relation is not in the range table.
+ *
+ * In the second case ExecCreatR creates a temp relation.
+ * (currently this is the only case we support -cim 10/16/89)
+ * ----------------
+ */
+ /* ----------------
+ * create the temporary relation
+ * ----------------
+ */
+/* len = ExecTargetListLength(node->plan.targetlist); */
+ tempDesc = ExecCreatR(tupType, _TEMP_RELATION_ID_);
+
+ /* ----------------
+ * save the relation descriptor in the sortstate
+ * ----------------
+ */
+ matstate->mat_TempRelation = tempDesc;
+ matstate->csstate.css_currentRelation = tempDesc;
+
+ /* ----------------
+ * return relation oid of temporary relation in a list
+ * (someday -- for now we return LispTrue... cim 10/12/89)
+ * ----------------
+ */
+ return TRUE;
}
int
-ExecCountSlotsMaterial(Material *node)
+ExecCountSlotsMaterial(Material * node)
{
- return ExecCountSlotsNode(outerPlan((Plan *)node)) +
- ExecCountSlotsNode(innerPlan((Plan *)node)) +
- MATERIAL_NSLOTS;
+ return ExecCountSlotsNode(outerPlan((Plan *) node)) +
+ ExecCountSlotsNode(innerPlan((Plan *) node)) +
+ MATERIAL_NSLOTS;
}
/* ----------------------------------------------------------------
- * ExecEndMaterial
+ * ExecEndMaterial
*
* old comments
- * destroys the temporary relation.
+ * destroys the temporary relation.
* ----------------------------------------------------------------
*/
void
-ExecEndMaterial(Material *node)
+ExecEndMaterial(Material * node)
{
- MaterialState *matstate;
- Relation tempRelation;
- Plan *outerPlan;
-
- /* ----------------
- * get info from the material state
- * ----------------
- */
- matstate = node->matstate;
- tempRelation = matstate->mat_TempRelation;
-
- heap_destroyr(tempRelation);
-
- /* ----------------
- * close the temp relation and shut down the scan.
- * ----------------
- */
- ExecCloseR((Plan *) node);
-
- /* ----------------
- * shut down the subplan
- * ----------------
- */
- outerPlan = outerPlan((Plan *) node);
- ExecEndNode(outerPlan, (Plan*) node);
-
- /* ----------------
- * clean out the tuple table
- * ----------------
- */
- ExecClearTuple(matstate->csstate.css_ScanTupleSlot);
-}
-
-#ifdef NOT_USED /* not used */
+ MaterialState *matstate;
+ Relation tempRelation;
+ Plan *outerPlan;
+
+ /* ----------------
+ * get info from the material state
+ * ----------------
+ */
+ matstate = node->matstate;
+ tempRelation = matstate->mat_TempRelation;
+
+ heap_destroyr(tempRelation);
+
+ /* ----------------
+ * close the temp relation and shut down the scan.
+ * ----------------
+ */
+ ExecCloseR((Plan *) node);
+
+ /* ----------------
+ * shut down the subplan
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+ ExecEndNode(outerPlan, (Plan *) node);
+
+ /* ----------------
+ * clean out the tuple table
+ * ----------------
+ */
+ ExecClearTuple(matstate->csstate.css_ScanTupleSlot);
+}
+
+#ifdef NOT_USED /* not used */
/* ----------------------------------------------------------------
- * ExecMaterialMarkPos
+ * ExecMaterialMarkPos
* ----------------------------------------------------------------
*/
-List /* nothing of interest */
+List /* nothing of interest */
ExecMaterialMarkPos(Material node)
{
- MaterialState matstate;
- HeapScanDesc sdesc;
-
- /* ----------------
- * if we haven't materialized yet, just return NIL.
- * ----------------
- */
- matstate = get_matstate(node);
- if (get_mat_Flag(matstate) == false)
+ MaterialState matstate;
+ HeapScanDesc sdesc;
+
+ /* ----------------
+ * if we haven't materialized yet, just return NIL.
+ * ----------------
+ */
+ matstate = get_matstate(node);
+ if (get_mat_Flag(matstate) == false)
+ return NIL;
+
+ /* ----------------
+ * XXX access methods don't return positions yet so
+ * for now we return NIL. It's possible that
+ * they will never return positions for all I know -cim 10/16/89
+ * ----------------
+ */
+ sdesc = get_css_currentScanDesc((CommonScanState) matstate);
+ heap_markpos(sdesc);
+
return NIL;
-
- /* ----------------
- * XXX access methods don't return positions yet so
- * for now we return NIL. It's possible that
- * they will never return positions for all I know -cim 10/16/89
- * ----------------
- */
- sdesc = get_css_currentScanDesc((CommonScanState)matstate);
- heap_markpos(sdesc);
-
- return NIL;
}
/* ----------------------------------------------------------------
- * ExecMaterialRestrPos
+ * ExecMaterialRestrPos
* ----------------------------------------------------------------
*/
void
ExecMaterialRestrPos(Material node)
{
- MaterialState matstate;
- HeapScanDesc sdesc;
-
- /* ----------------
- * if we haven't materialized yet, just return.
- * ----------------
- */
- matstate = get_matstate(node);
- if (get_mat_Flag(matstate) == false)
- return;
-
- /* ----------------
- * restore the scan to the previously marked position
- * ----------------
- */
- sdesc = get_css_currentScanDesc((CommonScanState)matstate);
- heap_restrpos(sdesc);
+ MaterialState matstate;
+ HeapScanDesc sdesc;
+
+ /* ----------------
+ * if we haven't materialized yet, just return.
+ * ----------------
+ */
+ matstate = get_matstate(node);
+ if (get_mat_Flag(matstate) == false)
+ return;
+
+ /* ----------------
+ * restore the scan to the previously marked position
+ * ----------------
+ */
+ sdesc = get_css_currentScanDesc((CommonScanState) matstate);
+ heap_restrpos(sdesc);
}
-#endif
+#endif
diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c
index 9151479d306..348d3fa1e00 100644
--- a/src/backend/executor/nodeMergejoin.c
+++ b/src/backend/executor/nodeMergejoin.c
@@ -1,78 +1,78 @@
/*-------------------------------------------------------------------------
*
* nodeMergejoin.c--
- * routines supporting merge joins
+ * routines supporting merge joins
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.8 1997/08/19 21:31:10 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.9 1997/09/07 04:41:37 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * ExecMergeJoin mergejoin outer and inner relations.
- * ExecInitMergeJoin creates and initializes run time states
- * ExecEndMergeJoin cleand up the node.
+ * ExecMergeJoin mergejoin outer and inner relations.
+ * ExecInitMergeJoin creates and initializes run time states
+ * ExecEndMergeJoin cleand up the node.
*
* NOTES
- * Essential operation of the merge join algorithm is as follows:
- * (** indicates the tuples satisify the merge clause).
+ * Essential operation of the merge join algorithm is as follows:
+ * (** indicates the tuples satisify the merge clause).
*
- * Join { -
- * get initial outer and inner tuples INITIALIZE
- * Skip Inner SKIPINNER
- * mark inner position JOINMARK
- * do forever { -
- * while (outer ** inner) { JOINTEST
- * join tuples JOINTUPLES
- * advance inner position NEXTINNER
- * } -
- * advance outer position NEXTOUTER
- * if (outer ** mark) { TESTOUTER
- * restore inner position to mark TESTOUTER
- * continue -
- * } else { -
- * Skip Outer SKIPOUTER
- * mark inner position JOINMARK
- * } -
- * } -
- * } -
+ * Join { -
+ * get initial outer and inner tuples INITIALIZE
+ * Skip Inner SKIPINNER
+ * mark inner position JOINMARK
+ * do forever { -
+ * while (outer ** inner) { JOINTEST
+ * join tuples JOINTUPLES
+ * advance inner position NEXTINNER
+ * } -
+ * advance outer position NEXTOUTER
+ * if (outer ** mark) { TESTOUTER
+ * restore inner position to mark TESTOUTER
+ * continue -
+ * } else { -
+ * Skip Outer SKIPOUTER
+ * mark inner position JOINMARK
+ * } -
+ * } -
+ * } -
*
- * Skip Outer { SKIPOUTER
- * if (inner ** outer) Join Tuples JOINTUPLES
- * while (outer < inner) SKIPOUTER
- * advance outer SKIPOUTER
- * if (outer > inner) SKIPOUTER
- * Skip Inner SKIPINNER
- * } -
+ * Skip Outer { SKIPOUTER
+ * if (inner ** outer) Join Tuples JOINTUPLES
+ * while (outer < inner) SKIPOUTER
+ * advance outer SKIPOUTER
+ * if (outer > inner) SKIPOUTER
+ * Skip Inner SKIPINNER
+ * } -
*
- * Skip Inner { SKIPINNER
- * if (inner ** outer) Join Tuples JOINTUPLES
- * while (outer > inner) SKIPINNER
- * advance inner SKIPINNER
- * if (outer < inner) SKIPINNER
- * Skip Outer SKIPOUTER
- * } -
+ * Skip Inner { SKIPINNER
+ * if (inner ** outer) Join Tuples JOINTUPLES
+ * while (outer > inner) SKIPINNER
+ * advance inner SKIPINNER
+ * if (outer < inner) SKIPINNER
+ * Skip Outer SKIPOUTER
+ * } -
*
- * Currently, the merge join operation is coded in the fashion
- * of a state machine. At each state, we do something and then
- * proceed to another state. This state is stored in the node's
- * execution state information and is preserved across calls to
- * ExecMergeJoin. -cim 10/31/89
+ * Currently, the merge join operation is coded in the fashion
+ * of a state machine. At each state, we do something and then
+ * proceed to another state. This state is stored in the node's
+ * execution state information and is preserved across calls to
+ * ExecMergeJoin. -cim 10/31/89
*
- * Warning: This code is known to fail for inequality operations
- * and is being redesigned. Specifically, = and > work
- * but the logic is not correct for <. Since mergejoins
- * are no better then nestloops for inequalitys, the planner
- * should not plan them anyways. Alternatively, the
- * planner could just exchange the inner/outer relations
- * if it ever sees a <... -cim 7/1/90
+ * Warning: This code is known to fail for inequality operations
+ * and is being redesigned. Specifically, = and > work
+ * but the logic is not correct for <. Since mergejoins
+ * are no better then nestloops for inequalitys, the planner
+ * should not plan them anyways. Alternatively, the
+ * planner could just exchange the inner/outer relations
+ * if it ever sees a <... -cim 7/1/90
*
- * Update: The executor tuple table has long since alleviated the
- * problem described above -cim 4/23/91
+ * Update: The executor tuple table has long since alleviated the
+ * problem described above -cim 4/23/91
*
*/
#include "postgres.h"
@@ -84,1134 +84,1151 @@
#include "utils/lsyscache.h"
#include "utils/psort.h"
-static bool MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext);
+static bool MergeCompare(List * eqQual, List * compareQual, ExprContext * econtext);
/* ----------------------------------------------------------------
- * MarkInnerTuple and RestoreInnerTuple macros
+ * MarkInnerTuple and RestoreInnerTuple macros
*
- * when we "mark" a tuple, we place a pointer to it
- * in the marked tuple slot. now there are two pointers
- * to this tuple and we don't want it to be freed until
- * next time we mark a tuple, so we move the policy to
- * the marked tuple slot and set the inner tuple slot policy
- * to false.
+ * when we "mark" a tuple, we place a pointer to it
+ * in the marked tuple slot. now there are two pointers
+ * to this tuple and we don't want it to be freed until
+ * next time we mark a tuple, so we move the policy to
+ * the marked tuple slot and set the inner tuple slot policy
+ * to false.
*
- * But, when we restore the inner tuple, the marked tuple
- * retains the policy. Basically once a tuple is marked, it
- * should only be freed when we mark another tuple. -cim 9/27/90
+ * But, when we restore the inner tuple, the marked tuple
+ * retains the policy. Basically once a tuple is marked, it
+ * should only be freed when we mark another tuple. -cim 9/27/90
*
- * Note: now that we store buffers in the tuple table,
- * we have to also increment buffer reference counts
- * correctly whenever we propagate an additional pointer
- * to a buffer item. Later, when ExecStoreTuple() is
- * called again on this slot, the refcnt is decremented
- * when the old tuple is replaced.
+ * Note: now that we store buffers in the tuple table,
+ * we have to also increment buffer reference counts
+ * correctly whenever we propagate an additional pointer
+ * to a buffer item. Later, when ExecStoreTuple() is
+ * called again on this slot, the refcnt is decremented
+ * when the old tuple is replaced.
* ----------------------------------------------------------------
*/
#define MarkInnerTuple(innerTupleSlot, mergestate) \
{ \
- bool shouldFree; \
- shouldFree = ExecSetSlotPolicy(innerTupleSlot, false); \
- ExecStoreTuple(innerTupleSlot->val, \
- mergestate->mj_MarkedTupleSlot, \
- innerTupleSlot->ttc_buffer, \
- shouldFree); \
- ExecIncrSlotBufferRefcnt(innerTupleSlot); \
+ bool shouldFree; \
+ shouldFree = ExecSetSlotPolicy(innerTupleSlot, false); \
+ ExecStoreTuple(innerTupleSlot->val, \
+ mergestate->mj_MarkedTupleSlot, \
+ innerTupleSlot->ttc_buffer, \
+ shouldFree); \
+ ExecIncrSlotBufferRefcnt(innerTupleSlot); \
}
#define RestoreInnerTuple(innerTupleSlot, markedTupleSlot) \
- ExecStoreTuple(markedTupleSlot->val, \
- innerTupleSlot, \
- markedTupleSlot->ttc_buffer, \
- false); \
- ExecIncrSlotBufferRefcnt(innerTupleSlot)
+ ExecStoreTuple(markedTupleSlot->val, \
+ innerTupleSlot, \
+ markedTupleSlot->ttc_buffer, \
+ false); \
+ ExecIncrSlotBufferRefcnt(innerTupleSlot)
/* ----------------------------------------------------------------
- * MJFormOSortopI
+ * MJFormOSortopI
*
- * This takes the mergeclause which is a qualification of the
- * form ((= expr expr) (= expr expr) ...) and forms a new
- * qualification like ((> expr expr) (> expr expr) ...) which
- * is used by ExecMergeJoin() in order to determine if we should
- * skip tuples.
+ * This takes the mergeclause which is a qualification of the
+ * form ((= expr expr) (= expr expr) ...) and forms a new
+ * qualification like ((> expr expr) (> expr expr) ...) which
+ * is used by ExecMergeJoin() in order to determine if we should
+ * skip tuples.
*
* old comments
- * The 'qual' must be of the form:
- * {(= outerkey1 innerkey1)(= outerkey2 innerkey2) ...}
- * The "sortOp outerkey innerkey" is formed by substituting the "="
- * by "sortOp".
+ * The 'qual' must be of the form:
+ * {(= outerkey1 innerkey1)(= outerkey2 innerkey2) ...}
+ * The "sortOp outerkey innerkey" is formed by substituting the "="
+ * by "sortOp".
* ----------------------------------------------------------------
*/
-static List *
-MJFormOSortopI(List *qualList, Oid sortOp)
+static List *
+MJFormOSortopI(List * qualList, Oid sortOp)
{
- List *qualCopy;
- List *qualcdr;
- Expr *qual;
- Oper *op;
-
- /* ----------------
- * qualList is a list: ((op .. ..) ...)
- * first we make a copy of it. copyObject() makes a deep copy
- * so let's use it instead of the old fashoned lispCopy()...
- * ----------------
- */
- qualCopy = (List*) copyObject((Node*) qualList);
-
- foreach (qualcdr, qualCopy) {
- /* ----------------
- * first get the current (op .. ..) list
- * ----------------
- */
- qual = lfirst(qualcdr);
-
+ List *qualCopy;
+ List *qualcdr;
+ Expr *qual;
+ Oper *op;
+
/* ----------------
- * now get at the op
+ * qualList is a list: ((op .. ..) ...)
+ * first we make a copy of it. copyObject() makes a deep copy
+ * so let's use it instead of the old fashoned lispCopy()...
* ----------------
*/
- op = (Oper*)qual->oper;
- if (!IsA(op,Oper)) {
- elog(DEBUG, "MJFormOSortopI: op not an Oper!");
- return NIL;
+ qualCopy = (List *) copyObject((Node *) qualList);
+
+ foreach(qualcdr, qualCopy)
+ {
+ /* ----------------
+ * first get the current (op .. ..) list
+ * ----------------
+ */
+ qual = lfirst(qualcdr);
+
+ /* ----------------
+ * now get at the op
+ * ----------------
+ */
+ op = (Oper *) qual->oper;
+ if (!IsA(op, Oper))
+ {
+ elog(DEBUG, "MJFormOSortopI: op not an Oper!");
+ return NIL;
+ }
+
+ /* ----------------
+ * change it's opid and since Op nodes now carry around a
+ * cached pointer to the associated op function, we have
+ * to make sure we invalidate this. Otherwise you get bizarre
+ * behavior when someone runs a mergejoin with _exec_repeat_ > 1
+ * -cim 4/23/91
+ * ----------------
+ */
+ op->opid = sortOp;
+ op->op_fcache = NULL;
}
-
- /* ----------------
- * change it's opid and since Op nodes now carry around a
- * cached pointer to the associated op function, we have
- * to make sure we invalidate this. Otherwise you get bizarre
- * behavior when someone runs a mergejoin with _exec_repeat_ > 1
- * -cim 4/23/91
- * ----------------
- */
- op->opid = sortOp;
- op->op_fcache = NULL;
- }
-
- return qualCopy;
+
+ return qualCopy;
}
-
+
/* ----------------------------------------------------------------
- * MJFormISortopO
+ * MJFormISortopO
*
- * This does the same thing as MJFormOSortopI() except that
- * it also reverses the expressions in the qualifications.
- * For example: ((= expr1 expr2)) produces ((> expr2 expr1))
+ * This does the same thing as MJFormOSortopI() except that
+ * it also reverses the expressions in the qualifications.
+ * For example: ((= expr1 expr2)) produces ((> expr2 expr1))
*
* old comments
- * The 'qual' must be of the form:
- * {(= outerkey1 innerkey1) (= outerkey2 innerkey2) ...}
- * The 'sortOp innerkey1 outerkey" is formed by substituting the "="
- * by "sortOp" and reversing the positions of the keys.
- * ----------------------------------------------------------------
+ * The 'qual' must be of the form:
+ * {(= outerkey1 innerkey1) (= outerkey2 innerkey2) ...}
+ * The 'sortOp innerkey1 outerkey" is formed by substituting the "="
+ * by "sortOp" and reversing the positions of the keys.
+ * ----------------------------------------------------------------
*/
-static List *
-MJFormISortopO(List *qualList, Oid sortOp)
+static List *
+MJFormISortopO(List * qualList, Oid sortOp)
{
- List *ISortopO;
- List *qualcdr;
-
- /* ----------------
- * first generate OSortopI, a list of the form
- * ((op outer inner) (op outer inner) ... )
- * ----------------
- */
- ISortopO = MJFormOSortopI(qualList, sortOp);
-
- /* ----------------
- * now swap the cadr and caddr of each qual to form ISortopO,
- * ((op inner outer) (op inner outer) ... )
- * ----------------
- */
- foreach (qualcdr, ISortopO) {
- Expr *qual;
- List *inner;
- List *outer;
- qual = lfirst(qualcdr);
-
- inner = lfirst(qual->args);
- outer = lfirst(lnext(qual->args));
- lfirst(qual->args) = outer;
- lfirst(lnext(qual->args)) = inner;
- }
-
- return ISortopO;
+ List *ISortopO;
+ List *qualcdr;
+
+ /* ----------------
+ * first generate OSortopI, a list of the form
+ * ((op outer inner) (op outer inner) ... )
+ * ----------------
+ */
+ ISortopO = MJFormOSortopI(qualList, sortOp);
+
+ /* ----------------
+ * now swap the cadr and caddr of each qual to form ISortopO,
+ * ((op inner outer) (op inner outer) ... )
+ * ----------------
+ */
+ foreach(qualcdr, ISortopO)
+ {
+ Expr *qual;
+ List *inner;
+ List *outer;
+
+ qual = lfirst(qualcdr);
+
+ inner = lfirst(qual->args);
+ outer = lfirst(lnext(qual->args));
+ lfirst(qual->args) = outer;
+ lfirst(lnext(qual->args)) = inner;
+ }
+
+ return ISortopO;
}
-
+
/* ----------------------------------------------------------------
- * MergeCompare
- *
- * Compare the keys according to 'compareQual' which is of the
- * form: {(key1a > key2a)(key1b > key2b) ...}.
+ * MergeCompare
*
- * (actually, it could also be the form (key1a < key2a)..)
- *
- * This is different from calling ExecQual because ExecQual returns
- * true only if ALL the comparisions clauses are satisfied.
- * However, there is an order of significance among the keys with
- * the first keys being most significant. Therefore, the clauses
- * are evaluated in order and the 'compareQual' is satisfied
- * if (key1i > key2i) is true and (key1j = key2j) for 0 < j < i.
+ * Compare the keys according to 'compareQual' which is of the
+ * form: {(key1a > key2a)(key1b > key2b) ...}.
+ *
+ * (actually, it could also be the form (key1a < key2a)..)
+ *
+ * This is different from calling ExecQual because ExecQual returns
+ * true only if ALL the comparisions clauses are satisfied.
+ * However, there is an order of significance among the keys with
+ * the first keys being most significant. Therefore, the clauses
+ * are evaluated in order and the 'compareQual' is satisfied
+ * if (key1i > key2i) is true and (key1j = key2j) for 0 < j < i.
* ----------------------------------------------------------------
*/
-static bool
-MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
+static bool
+MergeCompare(List * eqQual, List * compareQual, ExprContext * econtext)
{
- List *clause;
- List *eqclause;
- Datum const_value;
- bool isNull;
- bool isDone;
-
- /* ----------------
- * if we have no compare qualification, return nil
- * ----------------
- */
- if (compareQual == NIL)
- return false;
-
- /* ----------------
- * for each pair of clauses, test them until
- * our compare conditions are satisified
- * ----------------
- */
- eqclause = eqQual;
- foreach (clause, compareQual) {
+ List *clause;
+ List *eqclause;
+ Datum const_value;
+ bool isNull;
+ bool isDone;
+
/* ----------------
- * first test if our compare clause is satisified.
- * if so then return true. ignore isDone, don't iterate in
- * quals.
+ * if we have no compare qualification, return nil
* ----------------
*/
- const_value = (Datum)
- ExecEvalExpr((Node*) lfirst(clause), econtext, &isNull, &isDone);
-
- if (DatumGetInt32(const_value) != 0)
- return true;
-
+ if (compareQual == NIL)
+ return false;
+
/* ----------------
- * ok, the compare clause failed so we test if the keys
- * are equal... if key1 != key2, we return false.
- * otherwise key1 = key2 so we move on to the next pair of keys.
- *
- * ignore isDone, don't iterate in quals.
+ * for each pair of clauses, test them until
+ * our compare conditions are satisified
* ----------------
*/
- const_value = ExecEvalExpr((Node*) lfirst(eqclause),
- econtext,
- &isNull,
- &isDone);
-
- if (DatumGetInt32(const_value) == 0)
- return false;
- eqclause = lnext(eqclause);
- }
-
- /* ----------------
- * if we get here then it means none of our key greater-than
- * conditions were satisified so we return false.
- * ----------------
- */
- return false;
+ eqclause = eqQual;
+ foreach(clause, compareQual)
+ {
+ /* ----------------
+ * first test if our compare clause is satisified.
+ * if so then return true. ignore isDone, don't iterate in
+ * quals.
+ * ----------------
+ */
+ const_value = (Datum)
+ ExecEvalExpr((Node *) lfirst(clause), econtext, &isNull, &isDone);
+
+ if (DatumGetInt32(const_value) != 0)
+ return true;
+
+ /* ----------------
+ * ok, the compare clause failed so we test if the keys
+ * are equal... if key1 != key2, we return false.
+ * otherwise key1 = key2 so we move on to the next pair of keys.
+ *
+ * ignore isDone, don't iterate in quals.
+ * ----------------
+ */
+ const_value = ExecEvalExpr((Node *) lfirst(eqclause),
+ econtext,
+ &isNull,
+ &isDone);
+
+ if (DatumGetInt32(const_value) == 0)
+ return false;
+ eqclause = lnext(eqclause);
+ }
+
+ /* ----------------
+ * if we get here then it means none of our key greater-than
+ * conditions were satisified so we return false.
+ * ----------------
+ */
+ return false;
}
-
+
/* ----------------------------------------------------------------
- * ExecMergeTupleDump
+ * ExecMergeTupleDump
*
- * This function is called through the MJ_dump() macro
- * when EXEC_MERGEJOINDEBUG is defined
+ * This function is called through the MJ_dump() macro
+ * when EXEC_MERGEJOINDEBUG is defined
* ----------------------------------------------------------------
*/
#ifdef EXEC_MERGEJOINDEBUG
void
-ExecMergeTupleDumpInner(ExprContext *econtext)
+ExecMergeTupleDumpInner(ExprContext * econtext)
{
- TupleTableSlot *innerSlot;
-
- printf("==== inner tuple ====\n");
- innerSlot = econtext->ecxt_innertuple;
- if (TupIsNull(innerSlot))
- printf("(nil)\n");
- else
- debugtup(innerSlot->val,
- innerSlot->ttc_tupleDescriptor);
+ TupleTableSlot *innerSlot;
+
+ printf("==== inner tuple ====\n");
+ innerSlot = econtext->ecxt_innertuple;
+ if (TupIsNull(innerSlot))
+ printf("(nil)\n");
+ else
+ debugtup(innerSlot->val,
+ innerSlot->ttc_tupleDescriptor);
}
void
-ExecMergeTupleDumpOuter(ExprContext *econtext)
+ExecMergeTupleDumpOuter(ExprContext * econtext)
{
- TupleTableSlot *outerSlot;
-
- printf("==== outer tuple ====\n");
- outerSlot = econtext->ecxt_outertuple;
- if (TupIsNull(outerSlot))
- printf("(nil)\n");
- else
- debugtup(outerSlot->val,
- outerSlot->ttc_tupleDescriptor);
+ TupleTableSlot *outerSlot;
+
+ printf("==== outer tuple ====\n");
+ outerSlot = econtext->ecxt_outertuple;
+ if (TupIsNull(outerSlot))
+ printf("(nil)\n");
+ else
+ debugtup(outerSlot->val,
+ outerSlot->ttc_tupleDescriptor);
}
void
-ExecMergeTupleDumpMarked(ExprContext *econtext,
- MergeJoinState *mergestate)
+ExecMergeTupleDumpMarked(ExprContext * econtext,
+ MergeJoinState * mergestate)
{
- TupleTableSlot *markedSlot;
+ TupleTableSlot *markedSlot;
- printf("==== marked tuple ====\n");
- markedSlot = mergestate->mj_MarkedTupleSlot;
+ printf("==== marked tuple ====\n");
+ markedSlot = mergestate->mj_MarkedTupleSlot;
- if (TupIsNull(markedSlot))
- printf("(nil)\n");
- else
- debugtup(markedSlot->val,
- markedSlot->ttc_tupleDescriptor);
+ if (TupIsNull(markedSlot))
+ printf("(nil)\n");
+ else
+ debugtup(markedSlot->val,
+ markedSlot->ttc_tupleDescriptor);
}
void
-ExecMergeTupleDump(ExprContext *econtext, MergeJoinState *mergestate)
+ExecMergeTupleDump(ExprContext * econtext, MergeJoinState * mergestate)
{
- printf("******** ExecMergeTupleDump ********\n");
-
- ExecMergeTupleDumpInner(econtext);
- ExecMergeTupleDumpOuter(econtext);
- ExecMergeTupleDumpMarked(econtext, mergestate);
-
- printf("******** \n");
+ printf("******** ExecMergeTupleDump ********\n");
+
+ ExecMergeTupleDumpInner(econtext);
+ ExecMergeTupleDumpOuter(econtext);
+ ExecMergeTupleDumpMarked(econtext, mergestate);
+
+ printf("******** \n");
}
+
#endif
-
+
static void
-CleanUpSort(Plan *plan) {
-
- if (plan == NULL)
- return;
-
- if (plan->type == T_Sort) {
- Sort *sort = (Sort *)plan;
- psort_end(sort);
- }
+CleanUpSort(Plan * plan)
+{
+
+ if (plan == NULL)
+ return;
+
+ if (plan->type == T_Sort)
+ {
+ Sort *sort = (Sort *) plan;
+
+ psort_end(sort);
+ }
}
/* ----------------------------------------------------------------
- * ExecMergeJoin
+ * ExecMergeJoin
*
* old comments
- * Details of the merge-join routines:
- *
- * (1) ">" and "<" operators
- *
- * Merge-join is done by joining the inner and outer tuples satisfying
- * the join clauses of the form ((= outerKey innerKey) ...).
- * The join clauses is provided by the query planner and may contain
- * more than one (= outerKey innerKey) clauses (for composite key).
- *
- * However, the query executor needs to know whether an outer
- * tuple is "greater/smaller" than an inner tuple so that it can
- * "synchronize" the two relations. For e.g., consider the following
- * relations:
- *
- * outer: (0 ^1 1 2 5 5 5 6 6 7) current tuple: 1
- * inner: (1 ^3 5 5 5 5 6) current tuple: 3
- *
- * To continue the merge-join, the executor needs to scan both inner
- * and outer relations till the matching tuples 5. It needs to know
- * that currently inner tuple 3 is "greater" than outer tuple 1 and
- * therefore it should scan the outer relation first to find a
- * matching tuple and so on.
- *
- * Therefore, when initializing the merge-join node, the executor
- * creates the "greater/smaller" clause by substituting the "="
- * operator in the join clauses with the sort operator used to
- * sort the outer and inner relation forming (outerKey sortOp innerKey).
- * The sort operator is "<" if the relations are in ascending order
- * otherwise, it is ">" if the relations are in descending order.
- * The opposite "smaller/greater" clause is formed by reversing the
- * outer and inner keys forming (innerKey sortOp outerKey).
- *
- * (2) repositioning inner "cursor"
- *
- * Consider the above relations and suppose that the executor has
- * just joined the first outer "5" with the last inner "5". The
- * next step is of course to join the second outer "5" with all
- * the inner "5's". This requires repositioning the inner "cursor"
- * to point at the first inner "5". This is done by "marking" the
- * first inner 5 and restore the "cursor" to it before joining
- * with the second outer 5. The access method interface provides
- * routines to mark and restore to a tuple.
+ * Details of the merge-join routines:
+ *
+ * (1) ">" and "<" operators
+ *
+ * Merge-join is done by joining the inner and outer tuples satisfying
+ * the join clauses of the form ((= outerKey innerKey) ...).
+ * The join clauses is provided by the query planner and may contain
+ * more than one (= outerKey innerKey) clauses (for composite key).
+ *
+ * However, the query executor needs to know whether an outer
+ * tuple is "greater/smaller" than an inner tuple so that it can
+ * "synchronize" the two relations. For e.g., consider the following
+ * relations:
+ *
+ * outer: (0 ^1 1 2 5 5 5 6 6 7) current tuple: 1
+ * inner: (1 ^3 5 5 5 5 6) current tuple: 3
+ *
+ * To continue the merge-join, the executor needs to scan both inner
+ * and outer relations till the matching tuples 5. It needs to know
+ * that currently inner tuple 3 is "greater" than outer tuple 1 and
+ * therefore it should scan the outer relation first to find a
+ * matching tuple and so on.
+ *
+ * Therefore, when initializing the merge-join node, the executor
+ * creates the "greater/smaller" clause by substituting the "="
+ * operator in the join clauses with the sort operator used to
+ * sort the outer and inner relation forming (outerKey sortOp innerKey).
+ * The sort operator is "<" if the relations are in ascending order
+ * otherwise, it is ">" if the relations are in descending order.
+ * The opposite "smaller/greater" clause is formed by reversing the
+ * outer and inner keys forming (innerKey sortOp outerKey).
+ *
+ * (2) repositioning inner "cursor"
+ *
+ * Consider the above relations and suppose that the executor has
+ * just joined the first outer "5" with the last inner "5". The
+ * next step is of course to join the second outer "5" with all
+ * the inner "5's". This requires repositioning the inner "cursor"
+ * to point at the first inner "5". This is done by "marking" the
+ * first inner 5 and restore the "cursor" to it before joining
+ * with the second outer 5. The access method interface provides
+ * routines to mark and restore to a tuple.
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecMergeJoin(MergeJoin *node)
+ExecMergeJoin(MergeJoin * node)
{
- EState *estate;
- MergeJoinState *mergestate;
- ScanDirection direction;
- List *innerSkipQual;
- List *outerSkipQual;
- List *mergeclauses;
- List *qual;
- bool qualResult;
- bool compareResult;
-
- Plan *innerPlan;
- TupleTableSlot *innerTupleSlot;
-
- Plan *outerPlan;
- TupleTableSlot *outerTupleSlot;
-
- TupleTableSlot *markedTupleSlot;
-
- ExprContext *econtext;
-
- /* ----------------
- * get information from node
- * ----------------
- */
- mergestate = node->mergestate;
- estate = node->join.state;
- direction = estate->es_direction;
- innerPlan = innerPlan((Plan *)node);
- outerPlan = outerPlan((Plan *)node);
- econtext = mergestate->jstate.cs_ExprContext;
- mergeclauses = node->mergeclauses;
- qual = node->join.qual;
-
- if (ScanDirectionIsForward(direction)) {
- outerSkipQual = mergestate->mj_OSortopI;
- innerSkipQual = mergestate->mj_ISortopO;
- } else {
- outerSkipQual = mergestate->mj_ISortopO;
- innerSkipQual = mergestate->mj_OSortopI;
- }
-
- /* ----------------
- * ok, everything is setup.. let's go to work
- * ----------------
- */
- if (mergestate->jstate.cs_TupFromTlist) {
- TupleTableSlot *result;
- ProjectionInfo *projInfo;
- bool isDone;
-
- projInfo = mergestate->jstate.cs_ProjInfo;
- result = ExecProject(projInfo, &isDone);
- if (!isDone)
- return result;
- }
- for (;;) {
+ EState *estate;
+ MergeJoinState *mergestate;
+ ScanDirection direction;
+ List *innerSkipQual;
+ List *outerSkipQual;
+ List *mergeclauses;
+ List *qual;
+ bool qualResult;
+ bool compareResult;
+
+ Plan *innerPlan;
+ TupleTableSlot *innerTupleSlot;
+
+ Plan *outerPlan;
+ TupleTableSlot *outerTupleSlot;
+
+ TupleTableSlot *markedTupleSlot;
+
+ ExprContext *econtext;
+
/* ----------------
- * get the current state of the join and do things accordingly.
- * Note: The join states are highlighted with 32-* comments for
- * improved readability.
+ * get information from node
* ----------------
*/
- MJ_dump(econtext, mergestate);
-
- switch (mergestate->mj_JoinState) {
- /* ********************************
- * EXEC_MJ_INITIALIZE means that this is the first time
- * ExecMergeJoin() has been called and so we have to
- * initialize the inner, outer and marked tuples as well
- * as various stuff in the expression context.
- * ********************************
- */
- case EXEC_MJ_INITIALIZE:
- MJ_printf("ExecMergeJoin: EXEC_MJ_INITIALIZE\n");
- /* ----------------
- * Note: at this point, if either of our inner or outer
- * tuples are nil, then the join ends immediately because
- * we know one of the subplans is empty.
- * ----------------
- */
- innerTupleSlot = ExecProcNode(innerPlan, (Plan*)node);
- if (TupIsNull(innerTupleSlot)) {
- MJ_printf("ExecMergeJoin: **** inner tuple is nil ****\n");
- return NULL;
- }
-
- outerTupleSlot = ExecProcNode(outerPlan, (Plan*)node);
- if (TupIsNull(outerTupleSlot)) {
- MJ_printf("ExecMergeJoin: **** outer tuple is nil ****\n");
- return NULL;
- }
-
- /* ----------------
- * store the inner and outer tuple in the merge state
- * ----------------
- */
- econtext->ecxt_innertuple = innerTupleSlot;
- econtext->ecxt_outertuple = outerTupleSlot;
-
- /* ----------------
- * set the marked tuple to nil
- * and initialize its tuple descriptor atttributes.
- * -jeff 10 july 1991
- * ----------------
- */
- ExecClearTuple(mergestate->mj_MarkedTupleSlot);
- mergestate->mj_MarkedTupleSlot->ttc_tupleDescriptor =
- innerTupleSlot->ttc_tupleDescriptor;
-/*
- mergestate->mj_MarkedTupleSlot->ttc_execTupDescriptor =
- innerTupleSlot->ttc_execTupDescriptor;
-*/
- /* ----------------
- * initialize merge join state to skip inner tuples.
- * ----------------
- */
- mergestate->mj_JoinState = EXEC_MJ_SKIPINNER;
- break;
-
- /* ********************************
- * EXEC_MJ_JOINMARK means we have just found a new
- * outer tuple and a possible matching inner tuple.
- * This is the case after the INITIALIZE, SKIPOUTER
- * or SKIPINNER states.
- * ********************************
- */
- case EXEC_MJ_JOINMARK:
- MJ_printf("ExecMergeJoin: EXEC_MJ_JOINMARK\n");
- ExecMarkPos(innerPlan);
-
- innerTupleSlot = econtext->ecxt_innertuple;
- MarkInnerTuple(innerTupleSlot, mergestate);
-
- mergestate->mj_JoinState = EXEC_MJ_JOINTEST;
- break;
-
- /* ********************************
- * EXEC_MJ_JOINTEST means we have two tuples which
- * might satisify the merge clause, so we test them.
- *
- * If they do satisify, then we join them and move
- * on to the next inner tuple (EXEC_MJ_JOINTUPLES).
- *
- * If they do not satisify then advance to next outer tuple.
- * ********************************
- */
- case EXEC_MJ_JOINTEST:
- MJ_printf("ExecMergeJoin: EXEC_MJ_JOINTEST\n");
-
- qualResult = ExecQual((List*)mergeclauses, econtext);
- MJ_DEBUG_QUAL(mergeclauses, qualResult);
-
- if (qualResult)
- {
- mergestate->mj_JoinState = EXEC_MJ_JOINTUPLES;
- }
- else
- {
- mergestate->mj_JoinState = EXEC_MJ_NEXTOUTER;
- }
- break;
-
- /* ********************************
- * EXEC_MJ_JOINTUPLES means we have two tuples which
- * satisified the merge clause so we join them and then
- * proceed to get the next inner tuple (EXEC_NEXT_INNER).
- * ********************************
+ mergestate = node->mergestate;
+ estate = node->join.state;
+ direction = estate->es_direction;
+ innerPlan = innerPlan((Plan *) node);
+ outerPlan = outerPlan((Plan *) node);
+ econtext = mergestate->jstate.cs_ExprContext;
+ mergeclauses = node->mergeclauses;
+ qual = node->join.qual;
+
+ if (ScanDirectionIsForward(direction))
+ {
+ outerSkipQual = mergestate->mj_OSortopI;
+ innerSkipQual = mergestate->mj_ISortopO;
+ }
+ else
+ {
+ outerSkipQual = mergestate->mj_ISortopO;
+ innerSkipQual = mergestate->mj_OSortopI;
+ }
+
+ /* ----------------
+ * ok, everything is setup.. let's go to work
+ * ----------------
*/
- case EXEC_MJ_JOINTUPLES:
- MJ_printf("ExecMergeJoin: EXEC_MJ_JOINTUPLES\n");
- mergestate->mj_JoinState = EXEC_MJ_NEXTINNER;
-
- qualResult = ExecQual((List*)qual, econtext);
- MJ_DEBUG_QUAL(qual, qualResult);
-
- if (qualResult) {
- /* ----------------
- * qualification succeeded. now form the desired
- * projection tuple and return the slot containing it.
- * ----------------
- */
- ProjectionInfo *projInfo;
+ if (mergestate->jstate.cs_TupFromTlist)
+ {
TupleTableSlot *result;
- bool isDone;
-
- MJ_printf("ExecMergeJoin: **** returning tuple ****\n");
-
+ ProjectionInfo *projInfo;
+ bool isDone;
+
projInfo = mergestate->jstate.cs_ProjInfo;
-
result = ExecProject(projInfo, &isDone);
- mergestate->jstate.cs_TupFromTlist = !isDone;
- return result;
- }
- break;
-
- /* ********************************
- * EXEC_MJ_NEXTINNER means advance the inner scan
- * to the next tuple. If the tuple is not nil, we then
- * proceed to test it against the join qualification.
- * ********************************
- */
- case EXEC_MJ_NEXTINNER:
- MJ_printf("ExecMergeJoin: EXEC_MJ_NEXTINNER\n");
-
- /* ----------------
- * now we get the next inner tuple, if any
- * ----------------
- */
- innerTupleSlot = ExecProcNode(innerPlan, (Plan*)node);
- MJ_DEBUG_PROC_NODE(innerTupleSlot);
- econtext->ecxt_innertuple = innerTupleSlot;
-
- if (TupIsNull(innerTupleSlot))
- {
- mergestate->mj_JoinState = EXEC_MJ_NEXTOUTER;
- }
- else
- {
- mergestate->mj_JoinState = EXEC_MJ_JOINTEST;
- }
- break;
-
- /* ********************************
- * EXEC_MJ_NEXTOUTER means
- *
- * outer inner
- * outer tuple - 5 5 - marked tuple
- * 5 5
- * 6 6 - inner tuple
- * 7 7
- *
- * we know we just bumped into
- * the first inner tuple > current outer tuple
- * so get a new outer tuple and then proceed to test
- * it against the marked tuple (EXEC_MJ_TESTOUTER)
- * ********************************
- */
- case EXEC_MJ_NEXTOUTER:
- MJ_printf("ExecMergeJoin: EXEC_MJ_NEXTOUTER\n");
-
- outerTupleSlot = ExecProcNode(outerPlan, (Plan*)node);
- MJ_DEBUG_PROC_NODE(outerTupleSlot);
- econtext->ecxt_outertuple = outerTupleSlot;
-
- /* ----------------
- * if the outer tuple is null then we know
- * we are done with the join
- * ----------------
- */
- if (TupIsNull(outerTupleSlot)) {
- MJ_printf("ExecMergeJoin: **** outer tuple is nil ****\n");
- CleanUpSort(node->join.lefttree->lefttree);
- CleanUpSort(node->join.righttree->lefttree);
- return NULL;
- }
-
- mergestate->mj_JoinState = EXEC_MJ_TESTOUTER;
- break;
-
- /* ********************************
- * EXEC_MJ_TESTOUTER
- * If the new outer tuple and the marked tuple satisify
- * the merge clause then we know we have duplicates in
- * the outer scan so we have to restore the inner scan
- * to the marked tuple and proceed to join the new outer
- * tuples with the inner tuples (EXEC_MJ_JOINTEST)
- *
- * This is the case when
- *
- * outer inner
- * 4 5 - marked tuple
- * outer tuple - 5 5
- * new outer tuple - 5 5
- * 6 8 - inner tuple
- * 7 12
- *
- * new outer tuple = marked tuple
- *
- * If the outer tuple fails the test, then we know we have
- * to proceed to skip outer tuples until outer >= inner
- * (EXEC_MJ_SKIPOUTER).
- *
- * This is the case when
- *
- * outer inner
- * 5 5 - marked tuple
- * outer tuple - 5 5
- * new outer tuple - 6 8 - inner tuple
- * 7 12
- *
- * new outer tuple > marked tuple
- *
- * ********************************
- */
- case EXEC_MJ_TESTOUTER:
- MJ_printf("ExecMergeJoin: EXEC_MJ_TESTOUTER\n");
-
- /* ----------------
- * here we compare the outer tuple with the marked inner tuple
- * by using the marked tuple in place of the inner tuple.
- * ----------------
- */
- innerTupleSlot = econtext->ecxt_innertuple;
- markedTupleSlot = mergestate->mj_MarkedTupleSlot;
- econtext->ecxt_innertuple = markedTupleSlot;
-
- qualResult = ExecQual((List*)mergeclauses, econtext);
- MJ_DEBUG_QUAL(mergeclauses, qualResult);
-
- if (qualResult) {
- /* ----------------
- * the merge clause matched so now we juggle the slots
- * back the way they were and proceed to JOINTEST.
- * ----------------
- */
- econtext->ecxt_innertuple = innerTupleSlot;
-
- RestoreInnerTuple(innerTupleSlot, markedTupleSlot);
-
- ExecRestrPos(innerPlan);
- mergestate->mj_JoinState = EXEC_MJ_JOINTEST;
-
- } else {
- /* ----------------
- * if the inner tuple was nil and the new outer
- * tuple didn't match the marked outer tuple then
- * we may have the case:
- *
- * outer inner
- * 4 4 - marked tuple
- * new outer - 5 4
- * 6 nil - inner tuple
- * 7
- *
- * which means that all subsequent outer tuples will be
- * larger than our inner tuples.
- * ----------------
- */
- if (TupIsNull(innerTupleSlot)) {
- MJ_printf("ExecMergeJoin: **** wierd case 1 ****\n");
- return NULL;
- }
-
- /* ----------------
- * restore the inner tuple and continue on to
- * skip outer tuples.
- * ----------------
- */
- econtext->ecxt_innertuple = innerTupleSlot;
- mergestate->mj_JoinState = EXEC_MJ_SKIPOUTER;
- }
- break;
-
- /* ********************************
- * EXEC_MJ_SKIPOUTER means skip over tuples in the outer plan
- * until we find an outer tuple > current inner tuple.
- *
- * For example:
- *
- * outer inner
- * 5 5
- * 5 5
- * outer tuple - 6 8 - inner tuple
- * 7 12
- * 8 14
- *
- * we have to advance the outer scan
- * until we find the outer 8.
- *
- * ********************************
- */
- case EXEC_MJ_SKIPOUTER:
- MJ_printf("ExecMergeJoin: EXEC_MJ_SKIPOUTER\n");
- /* ----------------
- * before we advance, make sure the current tuples
- * do not satisify the mergeclauses. If they do, then
- * we update the marked tuple and go join them.
- * ----------------
- */
- qualResult = ExecQual((List*)mergeclauses, econtext);
- MJ_DEBUG_QUAL(mergeclauses, qualResult);
-
- if (qualResult) {
- ExecMarkPos(innerPlan);
- innerTupleSlot = econtext->ecxt_innertuple;
-
- MarkInnerTuple(innerTupleSlot, mergestate);
-
- mergestate->mj_JoinState = EXEC_MJ_JOINTUPLES;
- break;
- }
-
- /* ----------------
- * ok, now test the skip qualification
- * ----------------
- */
- compareResult = MergeCompare(mergeclauses,
- outerSkipQual,
- econtext);
-
- MJ_DEBUG_MERGE_COMPARE(outerSkipQual, compareResult);
-
- /* ----------------
- * compareResult is true as long as we should
- * continue skipping tuples.
- * ----------------
- */
- if (compareResult) {
-
- outerTupleSlot = ExecProcNode(outerPlan, (Plan*)node);
- MJ_DEBUG_PROC_NODE(outerTupleSlot);
- econtext->ecxt_outertuple = outerTupleSlot;
-
- /* ----------------
- * if the outer tuple is null then we know
- * we are done with the join
- * ----------------
- */
- if (TupIsNull(outerTupleSlot)) {
- MJ_printf("ExecMergeJoin: **** outerTuple is nil ****\n");
- return NULL;
- }
- /* ----------------
- * otherwise test the new tuple against the skip qual.
- * (we remain in the EXEC_MJ_SKIPOUTER state)
- * ----------------
- */
- break;
- }
-
- /* ----------------
- * now check the inner skip qual to see if we
- * should now skip inner tuples... if we fail the
- * inner skip qual, then we know we have a new pair
- * of matching tuples.
- * ----------------
- */
- compareResult = MergeCompare(mergeclauses,
- innerSkipQual,
- econtext);
-
- MJ_DEBUG_MERGE_COMPARE(innerSkipQual, compareResult);
-
- if (compareResult)
- {
- mergestate->mj_JoinState = EXEC_MJ_SKIPINNER;
- }
- else
- {
- mergestate->mj_JoinState = EXEC_MJ_JOINMARK;
- }
- break;
-
- /* ********************************
- * EXEC_MJ_SKIPINNER means skip over tuples in the inner plan
- * until we find an inner tuple > current outer tuple.
- *
- * For example:
- *
- * outer inner
- * 5 5
- * 5 5
- * outer tuple - 12 8 - inner tuple
- * 14 10
- * 17 12
- *
- * we have to advance the inner scan
- * until we find the inner 12.
- *
- * ********************************
- */
- case EXEC_MJ_SKIPINNER:
- MJ_printf("ExecMergeJoin: EXEC_MJ_SKIPINNER\n");
- /* ----------------
- * before we advance, make sure the current tuples
- * do not satisify the mergeclauses. If they do, then
- * we update the marked tuple and go join them.
- * ----------------
- */
- qualResult = ExecQual((List*)mergeclauses, econtext);
- MJ_DEBUG_QUAL(mergeclauses, qualResult);
-
- if (qualResult) {
- ExecMarkPos(innerPlan);
- innerTupleSlot = econtext->ecxt_innertuple;
-
- MarkInnerTuple(innerTupleSlot, mergestate);
-
- mergestate->mj_JoinState = EXEC_MJ_JOINTUPLES;
- break;
- }
-
- /* ----------------
- * ok, now test the skip qualification
- * ----------------
- */
- compareResult = MergeCompare(mergeclauses,
- innerSkipQual,
- econtext);
-
- MJ_DEBUG_MERGE_COMPARE(innerSkipQual, compareResult);
-
- /* ----------------
- * compareResult is true as long as we should
- * continue skipping tuples.
- * ----------------
- */
- if (compareResult) {
- /* ----------------
- * now try and get a new inner tuple
- * ----------------
- */
- innerTupleSlot = ExecProcNode(innerPlan, (Plan*)node);
- MJ_DEBUG_PROC_NODE(innerTupleSlot);
- econtext->ecxt_innertuple = innerTupleSlot;
-
+ if (!isDone)
+ return result;
+ }
+ for (;;)
+ {
/* ----------------
- * if the inner tuple is null then we know
- * we have to restore the inner scan
- * and advance to the next outer tuple
+ * get the current state of the join and do things accordingly.
+ * Note: The join states are highlighted with 32-* comments for
+ * improved readability.
* ----------------
*/
- if (TupIsNull(innerTupleSlot)) {
- /* ----------------
- * this is an interesting case.. all our
- * inner tuples are smaller then our outer
- * tuples so we never found an inner tuple
- * to mark.
- *
- * outer inner
- * outer tuple - 5 4
- * 5 4
- * 6 nil - inner tuple
- * 7
- *
- * This means the join should end.
- * ----------------
- */
- MJ_printf("ExecMergeJoin: **** wierd case 2 ****\n");
- return NULL;
+ MJ_dump(econtext, mergestate);
+
+ switch (mergestate->mj_JoinState)
+ {
+
+ /*
+ * ******************************** EXEC_MJ_INITIALIZE means
+ * that this is the first time ExecMergeJoin() has been called
+ * and so we have to initialize the inner, outer and marked
+ * tuples as well as various stuff in the expression context. ********************************
+ *
+ */
+ case EXEC_MJ_INITIALIZE:
+ MJ_printf("ExecMergeJoin: EXEC_MJ_INITIALIZE\n");
+ /* ----------------
+ * Note: at this point, if either of our inner or outer
+ * tuples are nil, then the join ends immediately because
+ * we know one of the subplans is empty.
+ * ----------------
+ */
+ innerTupleSlot = ExecProcNode(innerPlan, (Plan *) node);
+ if (TupIsNull(innerTupleSlot))
+ {
+ MJ_printf("ExecMergeJoin: **** inner tuple is nil ****\n");
+ return NULL;
+ }
+
+ outerTupleSlot = ExecProcNode(outerPlan, (Plan *) node);
+ if (TupIsNull(outerTupleSlot))
+ {
+ MJ_printf("ExecMergeJoin: **** outer tuple is nil ****\n");
+ return NULL;
+ }
+
+ /* ----------------
+ * store the inner and outer tuple in the merge state
+ * ----------------
+ */
+ econtext->ecxt_innertuple = innerTupleSlot;
+ econtext->ecxt_outertuple = outerTupleSlot;
+
+ /* ----------------
+ * set the marked tuple to nil
+ * and initialize its tuple descriptor atttributes.
+ * -jeff 10 july 1991
+ * ----------------
+ */
+ ExecClearTuple(mergestate->mj_MarkedTupleSlot);
+ mergestate->mj_MarkedTupleSlot->ttc_tupleDescriptor =
+ innerTupleSlot->ttc_tupleDescriptor;
+/*
+ mergestate->mj_MarkedTupleSlot->ttc_execTupDescriptor =
+ innerTupleSlot->ttc_execTupDescriptor;
+*/
+ /* ----------------
+ * initialize merge join state to skip inner tuples.
+ * ----------------
+ */
+ mergestate->mj_JoinState = EXEC_MJ_SKIPINNER;
+ break;
+
+ /*
+ * ******************************** EXEC_MJ_JOINMARK means we
+ * have just found a new outer tuple and a possible matching
+ * inner tuple. This is the case after the INITIALIZE,
+ * SKIPOUTER or SKIPINNER states. ********************************
+ *
+ */
+ case EXEC_MJ_JOINMARK:
+ MJ_printf("ExecMergeJoin: EXEC_MJ_JOINMARK\n");
+ ExecMarkPos(innerPlan);
+
+ innerTupleSlot = econtext->ecxt_innertuple;
+ MarkInnerTuple(innerTupleSlot, mergestate);
+
+ mergestate->mj_JoinState = EXEC_MJ_JOINTEST;
+ break;
+
+ /*
+ * ******************************** EXEC_MJ_JOINTEST means we
+ * have two tuples which might satisify the merge clause, so
+ * we test them.
+ *
+ * If they do satisify, then we join them and move on to the next
+ * inner tuple (EXEC_MJ_JOINTUPLES).
+ *
+ * If they do not satisify then advance to next outer tuple. ********************************
+ *
+ */
+ case EXEC_MJ_JOINTEST:
+ MJ_printf("ExecMergeJoin: EXEC_MJ_JOINTEST\n");
+
+ qualResult = ExecQual((List *) mergeclauses, econtext);
+ MJ_DEBUG_QUAL(mergeclauses, qualResult);
+
+ if (qualResult)
+ {
+ mergestate->mj_JoinState = EXEC_MJ_JOINTUPLES;
+ }
+ else
+ {
+ mergestate->mj_JoinState = EXEC_MJ_NEXTOUTER;
+ }
+ break;
+
+ /*
+ * ******************************** EXEC_MJ_JOINTUPLES means
+ * we have two tuples which satisified the merge clause so we
+ * join them and then proceed to get the next inner tuple
+ * (EXEC_NEXT_INNER). ********************************
+ *
+ */
+ case EXEC_MJ_JOINTUPLES:
+ MJ_printf("ExecMergeJoin: EXEC_MJ_JOINTUPLES\n");
+ mergestate->mj_JoinState = EXEC_MJ_NEXTINNER;
+
+ qualResult = ExecQual((List *) qual, econtext);
+ MJ_DEBUG_QUAL(qual, qualResult);
+
+ if (qualResult)
+ {
+ /* ----------------
+ * qualification succeeded. now form the desired
+ * projection tuple and return the slot containing it.
+ * ----------------
+ */
+ ProjectionInfo *projInfo;
+ TupleTableSlot *result;
+ bool isDone;
+
+ MJ_printf("ExecMergeJoin: **** returning tuple ****\n");
+
+ projInfo = mergestate->jstate.cs_ProjInfo;
+
+ result = ExecProject(projInfo, &isDone);
+ mergestate->jstate.cs_TupFromTlist = !isDone;
+ return result;
+ }
+ break;
+
+ /*
+ * ******************************** EXEC_MJ_NEXTINNER means
+ * advance the inner scan to the next tuple. If the tuple is
+ * not nil, we then proceed to test it against the join
+ * qualification. ********************************
+ *
+ */
+ case EXEC_MJ_NEXTINNER:
+ MJ_printf("ExecMergeJoin: EXEC_MJ_NEXTINNER\n");
+
+ /* ----------------
+ * now we get the next inner tuple, if any
+ * ----------------
+ */
+ innerTupleSlot = ExecProcNode(innerPlan, (Plan *) node);
+ MJ_DEBUG_PROC_NODE(innerTupleSlot);
+ econtext->ecxt_innertuple = innerTupleSlot;
+
+ if (TupIsNull(innerTupleSlot))
+ {
+ mergestate->mj_JoinState = EXEC_MJ_NEXTOUTER;
+ }
+ else
+ {
+ mergestate->mj_JoinState = EXEC_MJ_JOINTEST;
+ }
+ break;
+
+ /*
+ * ******************************** EXEC_MJ_NEXTOUTER means
+ *
+ * outer inner outer tuple - 5 5 - marked tuple 5 5 6
+ * 6 - inner tuple 7 7
+ *
+ * we know we just bumped into the first inner tuple > current
+ * outer tuple so get a new outer tuple and then proceed to
+ * test it against the marked tuple (EXEC_MJ_TESTOUTER) ********************************
+ *
+ */
+ case EXEC_MJ_NEXTOUTER:
+ MJ_printf("ExecMergeJoin: EXEC_MJ_NEXTOUTER\n");
+
+ outerTupleSlot = ExecProcNode(outerPlan, (Plan *) node);
+ MJ_DEBUG_PROC_NODE(outerTupleSlot);
+ econtext->ecxt_outertuple = outerTupleSlot;
+
+ /* ----------------
+ * if the outer tuple is null then we know
+ * we are done with the join
+ * ----------------
+ */
+ if (TupIsNull(outerTupleSlot))
+ {
+ MJ_printf("ExecMergeJoin: **** outer tuple is nil ****\n");
+ CleanUpSort(node->join.lefttree->lefttree);
+ CleanUpSort(node->join.righttree->lefttree);
+ return NULL;
+ }
+
+ mergestate->mj_JoinState = EXEC_MJ_TESTOUTER;
+ break;
+
+ /*
+ * ******************************** EXEC_MJ_TESTOUTER If the
+ * new outer tuple and the marked tuple satisify the merge
+ * clause then we know we have duplicates in the outer scan so
+ * we have to restore the inner scan to the marked tuple and
+ * proceed to join the new outer tuples with the inner tuples
+ * (EXEC_MJ_JOINTEST)
+ *
+ * This is the case when
+ *
+ * outer inner 4 5 - marked tuple outer tuple - 5 5 new
+ * outer tuple - 5 5 6 8 - inner tuple 7 12
+ *
+ * new outer tuple = marked tuple
+ *
+ * If the outer tuple fails the test, then we know we have to
+ * proceed to skip outer tuples until outer >= inner
+ * (EXEC_MJ_SKIPOUTER).
+ *
+ * This is the case when
+ *
+ * outer inner 5 5 - marked tuple outer tuple - 5 5 new
+ * outer tuple - 6 8 - inner tuple 7 12
+ *
+ * new outer tuple > marked tuple
+ *
+ ********************************
+ *
+ */
+ case EXEC_MJ_TESTOUTER:
+ MJ_printf("ExecMergeJoin: EXEC_MJ_TESTOUTER\n");
+
+ /* ----------------
+ * here we compare the outer tuple with the marked inner tuple
+ * by using the marked tuple in place of the inner tuple.
+ * ----------------
+ */
+ innerTupleSlot = econtext->ecxt_innertuple;
+ markedTupleSlot = mergestate->mj_MarkedTupleSlot;
+ econtext->ecxt_innertuple = markedTupleSlot;
+
+ qualResult = ExecQual((List *) mergeclauses, econtext);
+ MJ_DEBUG_QUAL(mergeclauses, qualResult);
+
+ if (qualResult)
+ {
+ /* ----------------
+ * the merge clause matched so now we juggle the slots
+ * back the way they were and proceed to JOINTEST.
+ * ----------------
+ */
+ econtext->ecxt_innertuple = innerTupleSlot;
+
+ RestoreInnerTuple(innerTupleSlot, markedTupleSlot);
+
+ ExecRestrPos(innerPlan);
+ mergestate->mj_JoinState = EXEC_MJ_JOINTEST;
+
+ }
+ else
+ {
+ /* ----------------
+ * if the inner tuple was nil and the new outer
+ * tuple didn't match the marked outer tuple then
+ * we may have the case:
+ *
+ * outer inner
+ * 4 4 - marked tuple
+ * new outer - 5 4
+ * 6 nil - inner tuple
+ * 7
+ *
+ * which means that all subsequent outer tuples will be
+ * larger than our inner tuples.
+ * ----------------
+ */
+ if (TupIsNull(innerTupleSlot))
+ {
+ MJ_printf("ExecMergeJoin: **** wierd case 1 ****\n");
+ return NULL;
+ }
+
+ /* ----------------
+ * restore the inner tuple and continue on to
+ * skip outer tuples.
+ * ----------------
+ */
+ econtext->ecxt_innertuple = innerTupleSlot;
+ mergestate->mj_JoinState = EXEC_MJ_SKIPOUTER;
+ }
+ break;
+
+ /*
+ * ******************************** EXEC_MJ_SKIPOUTER means
+ * skip over tuples in the outer plan until we find an outer
+ * tuple > current inner tuple.
+ *
+ * For example:
+ *
+ * outer inner 5 5 5 5 outer tuple - 6 8 - inner
+ * tuple 7 12 8 14
+ *
+ * we have to advance the outer scan until we find the outer 8.
+ *
+ ********************************
+ *
+ */
+ case EXEC_MJ_SKIPOUTER:
+ MJ_printf("ExecMergeJoin: EXEC_MJ_SKIPOUTER\n");
+ /* ----------------
+ * before we advance, make sure the current tuples
+ * do not satisify the mergeclauses. If they do, then
+ * we update the marked tuple and go join them.
+ * ----------------
+ */
+ qualResult = ExecQual((List *) mergeclauses, econtext);
+ MJ_DEBUG_QUAL(mergeclauses, qualResult);
+
+ if (qualResult)
+ {
+ ExecMarkPos(innerPlan);
+ innerTupleSlot = econtext->ecxt_innertuple;
+
+ MarkInnerTuple(innerTupleSlot, mergestate);
+
+ mergestate->mj_JoinState = EXEC_MJ_JOINTUPLES;
+ break;
+ }
+
+ /* ----------------
+ * ok, now test the skip qualification
+ * ----------------
+ */
+ compareResult = MergeCompare(mergeclauses,
+ outerSkipQual,
+ econtext);
+
+ MJ_DEBUG_MERGE_COMPARE(outerSkipQual, compareResult);
+
+ /* ----------------
+ * compareResult is true as long as we should
+ * continue skipping tuples.
+ * ----------------
+ */
+ if (compareResult)
+ {
+
+ outerTupleSlot = ExecProcNode(outerPlan, (Plan *) node);
+ MJ_DEBUG_PROC_NODE(outerTupleSlot);
+ econtext->ecxt_outertuple = outerTupleSlot;
+
+ /* ----------------
+ * if the outer tuple is null then we know
+ * we are done with the join
+ * ----------------
+ */
+ if (TupIsNull(outerTupleSlot))
+ {
+ MJ_printf("ExecMergeJoin: **** outerTuple is nil ****\n");
+ return NULL;
+ }
+ /* ----------------
+ * otherwise test the new tuple against the skip qual.
+ * (we remain in the EXEC_MJ_SKIPOUTER state)
+ * ----------------
+ */
+ break;
+ }
+
+ /* ----------------
+ * now check the inner skip qual to see if we
+ * should now skip inner tuples... if we fail the
+ * inner skip qual, then we know we have a new pair
+ * of matching tuples.
+ * ----------------
+ */
+ compareResult = MergeCompare(mergeclauses,
+ innerSkipQual,
+ econtext);
+
+ MJ_DEBUG_MERGE_COMPARE(innerSkipQual, compareResult);
+
+ if (compareResult)
+ {
+ mergestate->mj_JoinState = EXEC_MJ_SKIPINNER;
+ }
+ else
+ {
+ mergestate->mj_JoinState = EXEC_MJ_JOINMARK;
+ }
+ break;
+
+ /*
+ * ******************************** EXEC_MJ_SKIPINNER means
+ * skip over tuples in the inner plan until we find an inner
+ * tuple > current outer tuple.
+ *
+ * For example:
+ *
+ * outer inner 5 5 5 5 outer tuple - 12 8 - inner
+ * tuple 14 10 17 12
+ *
+ * we have to advance the inner scan until we find the inner 12.
+ *
+ ********************************
+ *
+ */
+ case EXEC_MJ_SKIPINNER:
+ MJ_printf("ExecMergeJoin: EXEC_MJ_SKIPINNER\n");
+ /* ----------------
+ * before we advance, make sure the current tuples
+ * do not satisify the mergeclauses. If they do, then
+ * we update the marked tuple and go join them.
+ * ----------------
+ */
+ qualResult = ExecQual((List *) mergeclauses, econtext);
+ MJ_DEBUG_QUAL(mergeclauses, qualResult);
+
+ if (qualResult)
+ {
+ ExecMarkPos(innerPlan);
+ innerTupleSlot = econtext->ecxt_innertuple;
+
+ MarkInnerTuple(innerTupleSlot, mergestate);
+
+ mergestate->mj_JoinState = EXEC_MJ_JOINTUPLES;
+ break;
+ }
+
+ /* ----------------
+ * ok, now test the skip qualification
+ * ----------------
+ */
+ compareResult = MergeCompare(mergeclauses,
+ innerSkipQual,
+ econtext);
+
+ MJ_DEBUG_MERGE_COMPARE(innerSkipQual, compareResult);
+
+ /* ----------------
+ * compareResult is true as long as we should
+ * continue skipping tuples.
+ * ----------------
+ */
+ if (compareResult)
+ {
+ /* ----------------
+ * now try and get a new inner tuple
+ * ----------------
+ */
+ innerTupleSlot = ExecProcNode(innerPlan, (Plan *) node);
+ MJ_DEBUG_PROC_NODE(innerTupleSlot);
+ econtext->ecxt_innertuple = innerTupleSlot;
+
+ /* ----------------
+ * if the inner tuple is null then we know
+ * we have to restore the inner scan
+ * and advance to the next outer tuple
+ * ----------------
+ */
+ if (TupIsNull(innerTupleSlot))
+ {
+ /* ----------------
+ * this is an interesting case.. all our
+ * inner tuples are smaller then our outer
+ * tuples so we never found an inner tuple
+ * to mark.
+ *
+ * outer inner
+ * outer tuple - 5 4
+ * 5 4
+ * 6 nil - inner tuple
+ * 7
+ *
+ * This means the join should end.
+ * ----------------
+ */
+ MJ_printf("ExecMergeJoin: **** wierd case 2 ****\n");
+ return NULL;
+ }
+
+ /* ----------------
+ * otherwise test the new tuple against the skip qual.
+ * (we remain in the EXEC_MJ_SKIPINNER state)
+ * ----------------
+ */
+ break;
+ }
+
+ /* ----------------
+ * compare finally failed and we have stopped skipping
+ * inner tuples so now check the outer skip qual
+ * to see if we should now skip outer tuples...
+ * ----------------
+ */
+ compareResult = MergeCompare(mergeclauses,
+ outerSkipQual,
+ econtext);
+
+ MJ_DEBUG_MERGE_COMPARE(outerSkipQual, compareResult);
+
+ if (compareResult)
+ {
+ mergestate->mj_JoinState = EXEC_MJ_SKIPOUTER;
+ }
+ else
+ {
+ mergestate->mj_JoinState = EXEC_MJ_JOINMARK;
+ }
+
+ break;
+
+ /*
+ * ******************************** if we get here it means
+ * our code is fucked up and so we just end the join
+ * prematurely. ********************************
+ *
+ */
+ default:
+ elog(NOTICE, "ExecMergeJoin: invalid join state. aborting");
+ return NULL;
}
-
- /* ----------------
- * otherwise test the new tuple against the skip qual.
- * (we remain in the EXEC_MJ_SKIPINNER state)
- * ----------------
- */
- break;
- }
-
- /* ----------------
- * compare finally failed and we have stopped skipping
- * inner tuples so now check the outer skip qual
- * to see if we should now skip outer tuples...
- * ----------------
- */
- compareResult = MergeCompare(mergeclauses,
- outerSkipQual,
- econtext);
-
- MJ_DEBUG_MERGE_COMPARE(outerSkipQual, compareResult);
-
- if (compareResult)
- {
- mergestate->mj_JoinState = EXEC_MJ_SKIPOUTER;
- }
- else
- {
- mergestate->mj_JoinState = EXEC_MJ_JOINMARK;
- }
-
- break;
-
- /* ********************************
- * if we get here it means our code is fucked up and
- * so we just end the join prematurely.
- * ********************************
- */
- default:
- elog(NOTICE, "ExecMergeJoin: invalid join state. aborting");
- return NULL;
}
- }
}
-
+
/* ----------------------------------------------------------------
- * ExecInitMergeJoin
+ * ExecInitMergeJoin
*
* old comments
- * Creates the run-time state information for the node and
- * sets the relation id to contain relevant decriptors.
+ * Creates the run-time state information for the node and
+ * sets the relation id to contain relevant decriptors.
* ----------------------------------------------------------------
*/
bool
-ExecInitMergeJoin(MergeJoin *node, EState *estate, Plan *parent)
+ExecInitMergeJoin(MergeJoin * node, EState * estate, Plan * parent)
{
- MergeJoinState *mergestate;
- List *joinclauses;
- RegProcedure rightsortop;
- RegProcedure leftsortop;
- RegProcedure sortop;
-
- List *OSortopI;
- List *ISortopO;
-
- MJ1_printf("ExecInitMergeJoin: %s\n",
- "initializing node");
-
- /* ----------------
- * assign the node's execution state and
- * get the range table and direction from it
- * ----------------
- */
- node->join.state = estate;
-
- /* ----------------
- * create new merge state for node
- * ----------------
- */
- mergestate = makeNode(MergeJoinState);
- mergestate->mj_OSortopI = NIL;
- mergestate->mj_ISortopO = NIL;
- mergestate->mj_JoinState = 0;
- mergestate->mj_MarkedTupleSlot = NULL;
- node->mergestate = mergestate;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks and
- * + create expression context for node
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &mergestate->jstate, parent);
- ExecAssignExprContext(estate, &mergestate->jstate);
+ MergeJoinState *mergestate;
+ List *joinclauses;
+ RegProcedure rightsortop;
+ RegProcedure leftsortop;
+ RegProcedure sortop;
+
+ List *OSortopI;
+ List *ISortopO;
+
+ MJ1_printf("ExecInitMergeJoin: %s\n",
+ "initializing node");
+
+ /* ----------------
+ * assign the node's execution state and
+ * get the range table and direction from it
+ * ----------------
+ */
+ node->join.state = estate;
+
+ /* ----------------
+ * create new merge state for node
+ * ----------------
+ */
+ mergestate = makeNode(MergeJoinState);
+ mergestate->mj_OSortopI = NIL;
+ mergestate->mj_ISortopO = NIL;
+ mergestate->mj_JoinState = 0;
+ mergestate->mj_MarkedTupleSlot = NULL;
+ node->mergestate = mergestate;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks and
+ * + create expression context for node
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &mergestate->jstate, parent);
+ ExecAssignExprContext(estate, &mergestate->jstate);
#define MERGEJOIN_NSLOTS 2
- /* ----------------
- * tuple table initialization
- * ----------------
- */
- ExecInitResultTupleSlot(estate, &mergestate->jstate);
- ExecInitMarkedTupleSlot(estate, mergestate);
-
- /* ----------------
- * get merge sort operators.
- *
- * XXX for now we assume all quals in the joinclauses were
- * sorted with the same operator in both the inner and
- * outer relations. -cim 11/2/89
- * ----------------
- */
- joinclauses = node->mergeclauses;
-
- rightsortop = get_opcode(node->mergerightorder[0]);
- leftsortop = get_opcode(node->mergeleftorder[0]);
-
- if (leftsortop != rightsortop)
- elog(NOTICE, "ExecInitMergeJoin: %s",
- "left and right sortop's are unequal!");
-
- sortop = rightsortop;
-
- /* ----------------
- * form merge skip qualifications
- *
- * XXX MJform routines need to be extended
- * to take a list of sortops.. -cim 11/2/89
- * ----------------
- */
- OSortopI = MJFormOSortopI(joinclauses, sortop);
- ISortopO = MJFormISortopO(joinclauses, sortop);
- mergestate->mj_OSortopI = OSortopI;
- mergestate->mj_ISortopO = ISortopO;
-
- MJ_printf("\nExecInitMergeJoin: OSortopI is ");
- MJ_nodeDisplay(OSortopI);
- MJ_printf("\nExecInitMergeJoin: ISortopO is ");
- MJ_nodeDisplay(ISortopO);
- MJ_printf("\n");
-
- /* ----------------
- * initialize join state
- * ----------------
- */
- mergestate->mj_JoinState = EXEC_MJ_INITIALIZE;
-
- /* ----------------
- * initialize subplans
- * ----------------
- */
- ExecInitNode(outerPlan((Plan *) node), estate, (Plan *) node);
- ExecInitNode(innerPlan((Plan *) node), estate, (Plan *) node);
-
- /* ----------------
- * initialize tuple type and projection info
- * ----------------
- */
- ExecAssignResultTypeFromTL((Plan *) node, &mergestate->jstate);
- ExecAssignProjectionInfo((Plan *) node, &mergestate->jstate);
-
- mergestate->jstate.cs_TupFromTlist = false;
- /* ----------------
- * initialization successful
- * ----------------
- */
- MJ1_printf("ExecInitMergeJoin: %s\n",
- "node initialized");
-
- return TRUE;
+ /* ----------------
+ * tuple table initialization
+ * ----------------
+ */
+ ExecInitResultTupleSlot(estate, &mergestate->jstate);
+ ExecInitMarkedTupleSlot(estate, mergestate);
+
+ /* ----------------
+ * get merge sort operators.
+ *
+ * XXX for now we assume all quals in the joinclauses were
+ * sorted with the same operator in both the inner and
+ * outer relations. -cim 11/2/89
+ * ----------------
+ */
+ joinclauses = node->mergeclauses;
+
+ rightsortop = get_opcode(node->mergerightorder[0]);
+ leftsortop = get_opcode(node->mergeleftorder[0]);
+
+ if (leftsortop != rightsortop)
+ elog(NOTICE, "ExecInitMergeJoin: %s",
+ "left and right sortop's are unequal!");
+
+ sortop = rightsortop;
+
+ /* ----------------
+ * form merge skip qualifications
+ *
+ * XXX MJform routines need to be extended
+ * to take a list of sortops.. -cim 11/2/89
+ * ----------------
+ */
+ OSortopI = MJFormOSortopI(joinclauses, sortop);
+ ISortopO = MJFormISortopO(joinclauses, sortop);
+ mergestate->mj_OSortopI = OSortopI;
+ mergestate->mj_ISortopO = ISortopO;
+
+ MJ_printf("\nExecInitMergeJoin: OSortopI is ");
+ MJ_nodeDisplay(OSortopI);
+ MJ_printf("\nExecInitMergeJoin: ISortopO is ");
+ MJ_nodeDisplay(ISortopO);
+ MJ_printf("\n");
+
+ /* ----------------
+ * initialize join state
+ * ----------------
+ */
+ mergestate->mj_JoinState = EXEC_MJ_INITIALIZE;
+
+ /* ----------------
+ * initialize subplans
+ * ----------------
+ */
+ ExecInitNode(outerPlan((Plan *) node), estate, (Plan *) node);
+ ExecInitNode(innerPlan((Plan *) node), estate, (Plan *) node);
+
+ /* ----------------
+ * initialize tuple type and projection info
+ * ----------------
+ */
+ ExecAssignResultTypeFromTL((Plan *) node, &mergestate->jstate);
+ ExecAssignProjectionInfo((Plan *) node, &mergestate->jstate);
+
+ mergestate->jstate.cs_TupFromTlist = false;
+ /* ----------------
+ * initialization successful
+ * ----------------
+ */
+ MJ1_printf("ExecInitMergeJoin: %s\n",
+ "node initialized");
+
+ return TRUE;
}
-
+
int
-ExecCountSlotsMergeJoin(MergeJoin *node)
+ExecCountSlotsMergeJoin(MergeJoin * node)
{
- return ExecCountSlotsNode(outerPlan((Plan *)node)) +
- ExecCountSlotsNode(innerPlan((Plan *)node)) +
- MERGEJOIN_NSLOTS;
+ return ExecCountSlotsNode(outerPlan((Plan *) node)) +
+ ExecCountSlotsNode(innerPlan((Plan *) node)) +
+ MERGEJOIN_NSLOTS;
}
-
+
/* ----------------------------------------------------------------
- * ExecEndMergeJoin
+ * ExecEndMergeJoin
*
* old comments
- * frees storage allocated through C routines.
+ * frees storage allocated through C routines.
* ----------------------------------------------------------------
*/
void
-ExecEndMergeJoin(MergeJoin *node)
+ExecEndMergeJoin(MergeJoin * node)
{
- MergeJoinState *mergestate;
-
- MJ1_printf("ExecEndMergeJoin: %s\n",
- "ending node processing");
-
- /* ----------------
- * get state information from the node
- * ----------------
- */
- mergestate = node->mergestate;
-
- /* ----------------
- * Free the projection info and the scan attribute info
- *
- * Note: we don't ExecFreeResultType(mergestate)
- * because the rule manager depends on the tupType
- * returned by ExecMain(). So for now, this
- * is freed at end-transaction time. -cim 6/2/91
- * ----------------
- */
- ExecFreeProjectionInfo(&mergestate->jstate);
-
- /* ----------------
- * shut down the subplans
- * ----------------
- */
- ExecEndNode((Plan*) innerPlan((Plan *) node), (Plan*)node);
- ExecEndNode((Plan*) outerPlan((Plan *) node), (Plan*)node);
-
- /* ----------------
- * clean out the tuple table so that we don't try and
- * pfree the marked tuples.. see HACK ALERT at the top of
- * this file.
- * ----------------
- */
- ExecClearTuple(mergestate->jstate.cs_ResultTupleSlot);
- ExecClearTuple(mergestate->mj_MarkedTupleSlot);
-
- MJ1_printf("ExecEndMergeJoin: %s\n",
- "node processing ended");
+ MergeJoinState *mergestate;
+
+ MJ1_printf("ExecEndMergeJoin: %s\n",
+ "ending node processing");
+
+ /* ----------------
+ * get state information from the node
+ * ----------------
+ */
+ mergestate = node->mergestate;
+
+ /* ----------------
+ * Free the projection info and the scan attribute info
+ *
+ * Note: we don't ExecFreeResultType(mergestate)
+ * because the rule manager depends on the tupType
+ * returned by ExecMain(). So for now, this
+ * is freed at end-transaction time. -cim 6/2/91
+ * ----------------
+ */
+ ExecFreeProjectionInfo(&mergestate->jstate);
+
+ /* ----------------
+ * shut down the subplans
+ * ----------------
+ */
+ ExecEndNode((Plan *) innerPlan((Plan *) node), (Plan *) node);
+ ExecEndNode((Plan *) outerPlan((Plan *) node), (Plan *) node);
+
+ /* ----------------
+ * clean out the tuple table so that we don't try and
+ * pfree the marked tuples.. see HACK ALERT at the top of
+ * this file.
+ * ----------------
+ */
+ ExecClearTuple(mergestate->jstate.cs_ResultTupleSlot);
+ ExecClearTuple(mergestate->mj_MarkedTupleSlot);
+
+ MJ1_printf("ExecEndMergeJoin: %s\n",
+ "node processing ended");
}
-
diff --git a/src/backend/executor/nodeNestloop.c b/src/backend/executor/nodeNestloop.c
index d83d306bba9..e7cba2e756e 100644
--- a/src/backend/executor/nodeNestloop.c
+++ b/src/backend/executor/nodeNestloop.c
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nodeNestloop.c--
- * routines to support nest-loop joins
+ * routines to support nest-loop joins
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeNestloop.c,v 1.3 1996/11/08 05:56:15 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeNestloop.c,v 1.4 1997/09/07 04:41:41 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * INTERFACE ROUTINES
- * ExecNestLoop - process a nestloop join of two plans
- * ExecInitNestLoop - initialize the join
- * ExecEndNestLoop - shut down the join
+ * INTERFACE ROUTINES
+ * ExecNestLoop - process a nestloop join of two plans
+ * ExecInitNestLoop - initialize the join
+ * ExecEndNestLoop - shut down the join
*/
#include "postgres.h"
@@ -25,349 +25,363 @@
#include "executor/nodeIndexscan.h"
/* ----------------------------------------------------------------
- * ExecNestLoop(node)
+ * ExecNestLoop(node)
*
* old comments
- * Returns the tuple joined from inner and outer tuples which
- * satisfies the qualification clause.
+ * Returns the tuple joined from inner and outer tuples which
+ * satisfies the qualification clause.
*
- * It scans the inner relation to join with current outer tuple.
+ * It scans the inner relation to join with current outer tuple.
*
- * If none is found, next tuple form the outer relation is retrieved
- * and the inner relation is scanned from the beginning again to join
- * with the outer tuple.
+ * If none is found, next tuple form the outer relation is retrieved
+ * and the inner relation is scanned from the beginning again to join
+ * with the outer tuple.
*
- * Nil is returned if all the remaining outer tuples are tried and
- * all fail to join with the inner tuples.
+ * Nil is returned if all the remaining outer tuples are tried and
+ * all fail to join with the inner tuples.
*
- * Nil is also returned if there is no tuple from inner realtion.
- *
- * Conditions:
- * -- outerTuple contains current tuple from outer relation and
- * the right son(inner realtion) maintains "cursor" at the tuple
- * returned previously.
- * This is achieved by maintaining a scan position on the outer
- * relation.
- *
- * Initial States:
- * -- the outer child and the inner child
- * are prepared to return the first tuple.
+ * Nil is also returned if there is no tuple from inner realtion.
+ *
+ * Conditions:
+ * -- outerTuple contains current tuple from outer relation and
+ * the right son(inner realtion) maintains "cursor" at the tuple
+ * returned previously.
+ * This is achieved by maintaining a scan position on the outer
+ * relation.
+ *
+ * Initial States:
+ * -- the outer child and the inner child
+ * are prepared to return the first tuple.
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecNestLoop(NestLoop *node, Plan* parent)
+ExecNestLoop(NestLoop * node, Plan * parent)
{
- NestLoopState *nlstate;
- Plan *innerPlan;
- Plan *outerPlan;
- bool needNewOuterTuple;
-
- TupleTableSlot *outerTupleSlot;
- TupleTableSlot *innerTupleSlot;
-
- List *qual;
- bool qualResult;
- ExprContext *econtext;
-
- /* ----------------
- * get information from the node
- * ----------------
- */
- ENL1_printf("getting info from node");
-
- nlstate = node->nlstate;
- qual = node->join.qual;
- outerPlan = outerPlan(&node->join);
- innerPlan = innerPlan(&node->join);
-
- /* ----------------
- * initialize expression context
- * ----------------
- */
- econtext = nlstate->jstate.cs_ExprContext;
-
- /* ---------------- * get the current outer tuple
- * ----------------
- */
- outerTupleSlot = nlstate->jstate.cs_OuterTupleSlot;
- econtext->ecxt_outertuple = outerTupleSlot;
-
- /* ----------------
- * Ok, everything is setup for the join so now loop until
- * we return a qualifying join tuple..
- * ----------------
- */
-
- if (nlstate->jstate.cs_TupFromTlist) {
- TupleTableSlot *result;
- bool isDone;
-
- result = ExecProject(nlstate->jstate.cs_ProjInfo, &isDone);
- if (!isDone)
- return result;
- }
-
- ENL1_printf("entering main loop");
- for(;;) {
+ NestLoopState *nlstate;
+ Plan *innerPlan;
+ Plan *outerPlan;
+ bool needNewOuterTuple;
+
+ TupleTableSlot *outerTupleSlot;
+ TupleTableSlot *innerTupleSlot;
+
+ List *qual;
+ bool qualResult;
+ ExprContext *econtext;
+
/* ----------------
- * The essential idea now is to get the next inner tuple
- * and join it with the current outer tuple.
+ * get information from the node
* ----------------
*/
- needNewOuterTuple = false;
-
+ ENL1_printf("getting info from node");
+
+ nlstate = node->nlstate;
+ qual = node->join.qual;
+ outerPlan = outerPlan(&node->join);
+ innerPlan = innerPlan(&node->join);
+
/* ----------------
- * If outer tuple is not null then that means
- * we are in the middle of a scan and we should
- * restore our previously saved scan position.
+ * initialize expression context
* ----------------
*/
- if (! TupIsNull(outerTupleSlot)) {
- ENL1_printf("have outer tuple, restoring outer plan");
- ExecRestrPos(outerPlan);
- } else {
- ENL1_printf("outer tuple is nil, need new outer tuple");
- needNewOuterTuple = true;
- }
-
- /* ----------------
- * if we have an outerTuple, try to get the next inner tuple.
+ econtext = nlstate->jstate.cs_ExprContext;
+
+ /* ---------------- * get the current outer tuple
* ----------------
*/
- if (!needNewOuterTuple) {
- ENL1_printf("getting new inner tuple");
-
- innerTupleSlot = ExecProcNode(innerPlan, (Plan*)node);
- econtext->ecxt_innertuple = innerTupleSlot;
-
- if (TupIsNull(innerTupleSlot)) {
- ENL1_printf("no inner tuple, need new outer tuple");
- needNewOuterTuple = true;
- }
- }
-
+ outerTupleSlot = nlstate->jstate.cs_OuterTupleSlot;
+ econtext->ecxt_outertuple = outerTupleSlot;
+
/* ----------------
- * loop until we have a new outer tuple and a new
- * inner tuple.
+ * Ok, everything is setup for the join so now loop until
+ * we return a qualifying join tuple..
* ----------------
*/
- while (needNewOuterTuple) {
- /* ----------------
- * now try to get the next outer tuple
- * ----------------
- */
- ENL1_printf("getting new outer tuple");
- outerTupleSlot = ExecProcNode(outerPlan, (Plan*)node);
- econtext->ecxt_outertuple = outerTupleSlot;
-
- /* ----------------
- * if there are no more outer tuples, then the join
- * is complete..
- * ----------------
- */
- if (TupIsNull(outerTupleSlot)) {
- ENL1_printf("no outer tuple, ending join");
- return NULL;
- }
-
- /* ----------------
- * we have a new outer tuple so we mark our position
- * in the outer scan and save the outer tuple in the
- * NestLoop state
- * ----------------
- */
- ENL1_printf("saving new outer tuple information");
- ExecMarkPos(outerPlan);
- nlstate->jstate.cs_OuterTupleSlot = outerTupleSlot;
-
- /* ----------------
- * now rescan the inner plan and get a new inner tuple
- * ----------------
- */
-
- ENL1_printf("rescanning inner plan");
- /*
- * The scan key of the inner plan might depend on the current
- * outer tuple (e.g. in index scans), that's why we pass our
- * expr context.
- */
- ExecReScan(innerPlan, econtext, parent);
-
- ENL1_printf("getting new inner tuple");
-
- innerTupleSlot = ExecProcNode(innerPlan, (Plan*)node);
- econtext->ecxt_innertuple = innerTupleSlot;
-
- if (TupIsNull(innerTupleSlot)) {
- ENL1_printf("couldn't get inner tuple - need new outer tuple");
- } else {
- ENL1_printf("got inner and outer tuples");
+
+ if (nlstate->jstate.cs_TupFromTlist)
+ {
+ TupleTableSlot *result;
+ bool isDone;
+
+ result = ExecProject(nlstate->jstate.cs_ProjInfo, &isDone);
+ if (!isDone)
+ return result;
+ }
+
+ ENL1_printf("entering main loop");
+ for (;;)
+ {
+ /* ----------------
+ * The essential idea now is to get the next inner tuple
+ * and join it with the current outer tuple.
+ * ----------------
+ */
needNewOuterTuple = false;
- }
- } /* while (needNewOuterTuple) */
-
+
+ /* ----------------
+ * If outer tuple is not null then that means
+ * we are in the middle of a scan and we should
+ * restore our previously saved scan position.
+ * ----------------
+ */
+ if (!TupIsNull(outerTupleSlot))
+ {
+ ENL1_printf("have outer tuple, restoring outer plan");
+ ExecRestrPos(outerPlan);
+ }
+ else
+ {
+ ENL1_printf("outer tuple is nil, need new outer tuple");
+ needNewOuterTuple = true;
+ }
+
+ /* ----------------
+ * if we have an outerTuple, try to get the next inner tuple.
+ * ----------------
+ */
+ if (!needNewOuterTuple)
+ {
+ ENL1_printf("getting new inner tuple");
+
+ innerTupleSlot = ExecProcNode(innerPlan, (Plan *) node);
+ econtext->ecxt_innertuple = innerTupleSlot;
+
+ if (TupIsNull(innerTupleSlot))
+ {
+ ENL1_printf("no inner tuple, need new outer tuple");
+ needNewOuterTuple = true;
+ }
+ }
+
+ /* ----------------
+ * loop until we have a new outer tuple and a new
+ * inner tuple.
+ * ----------------
+ */
+ while (needNewOuterTuple)
+ {
+ /* ----------------
+ * now try to get the next outer tuple
+ * ----------------
+ */
+ ENL1_printf("getting new outer tuple");
+ outerTupleSlot = ExecProcNode(outerPlan, (Plan *) node);
+ econtext->ecxt_outertuple = outerTupleSlot;
+
+ /* ----------------
+ * if there are no more outer tuples, then the join
+ * is complete..
+ * ----------------
+ */
+ if (TupIsNull(outerTupleSlot))
+ {
+ ENL1_printf("no outer tuple, ending join");
+ return NULL;
+ }
+
+ /* ----------------
+ * we have a new outer tuple so we mark our position
+ * in the outer scan and save the outer tuple in the
+ * NestLoop state
+ * ----------------
+ */
+ ENL1_printf("saving new outer tuple information");
+ ExecMarkPos(outerPlan);
+ nlstate->jstate.cs_OuterTupleSlot = outerTupleSlot;
+
+ /* ----------------
+ * now rescan the inner plan and get a new inner tuple
+ * ----------------
+ */
+
+ ENL1_printf("rescanning inner plan");
+
+ /*
+ * The scan key of the inner plan might depend on the current
+ * outer tuple (e.g. in index scans), that's why we pass our
+ * expr context.
+ */
+ ExecReScan(innerPlan, econtext, parent);
+
+ ENL1_printf("getting new inner tuple");
+
+ innerTupleSlot = ExecProcNode(innerPlan, (Plan *) node);
+ econtext->ecxt_innertuple = innerTupleSlot;
+
+ if (TupIsNull(innerTupleSlot))
+ {
+ ENL1_printf("couldn't get inner tuple - need new outer tuple");
+ }
+ else
+ {
+ ENL1_printf("got inner and outer tuples");
+ needNewOuterTuple = false;
+ }
+ } /* while (needNewOuterTuple) */
+
+ /* ----------------
+ * at this point we have a new pair of inner and outer
+ * tuples so we test the inner and outer tuples to see
+ * if they satisify the node's qualification.
+ * ----------------
+ */
+ ENL1_printf("testing qualification");
+ qualResult = ExecQual((List *) qual, econtext);
+
+ if (qualResult)
+ {
+ /* ----------------
+ * qualification was satisified so we project and
+ * return the slot containing the result tuple
+ * using ExecProject().
+ * ----------------
+ */
+ ProjectionInfo *projInfo;
+ TupleTableSlot *result;
+ bool isDone;
+
+ ENL1_printf("qualification succeeded, projecting tuple");
+
+ projInfo = nlstate->jstate.cs_ProjInfo;
+ result = ExecProject(projInfo, &isDone);
+ nlstate->jstate.cs_TupFromTlist = !isDone;
+ return result;
+ }
+
+ /* ----------------
+ * qualification failed so we have to try again..
+ * ----------------
+ */
+ ENL1_printf("qualification failed, looping");
+ }
+}
+
+/* ----------------------------------------------------------------
+ * ExecInitNestLoop
+ *
+ * Creates the run-time state information for the nestloop node
+ * produced by the planner and initailizes inner and outer relations
+ * (child nodes).
+ * ----------------------------------------------------------------
+ */
+bool
+ExecInitNestLoop(NestLoop * node, EState * estate, Plan * parent)
+{
+ NestLoopState *nlstate;
+
+ NL1_printf("ExecInitNestLoop: %s\n",
+ "initializing node");
+
/* ----------------
- * at this point we have a new pair of inner and outer
- * tuples so we test the inner and outer tuples to see
- * if they satisify the node's qualification.
+ * assign execution state to node
* ----------------
*/
- ENL1_printf("testing qualification");
- qualResult = ExecQual((List*)qual, econtext);
-
- if (qualResult) {
- /* ----------------
- * qualification was satisified so we project and
- * return the slot containing the result tuple
- * using ExecProject().
- * ----------------
- */
- ProjectionInfo *projInfo;
- TupleTableSlot *result;
- bool isDone;
-
- ENL1_printf("qualification succeeded, projecting tuple");
-
- projInfo = nlstate->jstate.cs_ProjInfo;
- result = ExecProject(projInfo, &isDone);
- nlstate->jstate.cs_TupFromTlist = !isDone;
- return result;
- }
-
+ node->join.state = estate;
+
/* ----------------
- * qualification failed so we have to try again..
+ * create new nest loop state
* ----------------
*/
- ENL1_printf("qualification failed, looping");
- }
-}
+ nlstate = makeNode(NestLoopState);
+ nlstate->nl_PortalFlag = false;
+ node->nlstate = nlstate;
-/* ----------------------------------------------------------------
- * ExecInitNestLoop
- *
- * Creates the run-time state information for the nestloop node
- * produced by the planner and initailizes inner and outer relations
- * (child nodes).
- * ----------------------------------------------------------------
- */
-bool
-ExecInitNestLoop(NestLoop *node, EState *estate, Plan *parent)
-{
- NestLoopState *nlstate;
-
- NL1_printf("ExecInitNestLoop: %s\n",
- "initializing node");
-
- /* ----------------
- * assign execution state to node
- * ----------------
- */
- node->join.state = estate;
-
- /* ----------------
- * create new nest loop state
- * ----------------
- */
- nlstate = makeNode(NestLoopState);
- nlstate->nl_PortalFlag = false;
- node->nlstate = nlstate;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks and
- * + create expression context for node
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &nlstate->jstate, parent);
- ExecAssignExprContext(estate, &nlstate->jstate);
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks and
+ * + create expression context for node
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &nlstate->jstate, parent);
+ ExecAssignExprContext(estate, &nlstate->jstate);
#define NESTLOOP_NSLOTS 1
- /* ----------------
- * tuple table initialization
- * ----------------
- */
- ExecInitResultTupleSlot(estate, &nlstate->jstate);
-
- /* ----------------
- * now initialize children
- * ----------------
- */
- ExecInitNode(outerPlan((Plan*)node), estate, (Plan*)node);
- ExecInitNode(innerPlan((Plan*)node), estate, (Plan*)node);
-
- /* ----------------
- * initialize tuple type and projection info
- * ----------------
- */
- ExecAssignResultTypeFromTL((Plan *) node, &nlstate->jstate);
- ExecAssignProjectionInfo((Plan *) node, &nlstate->jstate);
-
- /* ----------------
- * finally, wipe the current outer tuple clean.
- * ----------------
- */
- nlstate->jstate.cs_OuterTupleSlot = NULL;
- nlstate->jstate.cs_TupFromTlist = false;
-
- NL1_printf("ExecInitNestLoop: %s\n",
- "node initialized");
- return TRUE;
+ /* ----------------
+ * tuple table initialization
+ * ----------------
+ */
+ ExecInitResultTupleSlot(estate, &nlstate->jstate);
+
+ /* ----------------
+ * now initialize children
+ * ----------------
+ */
+ ExecInitNode(outerPlan((Plan *) node), estate, (Plan *) node);
+ ExecInitNode(innerPlan((Plan *) node), estate, (Plan *) node);
+
+ /* ----------------
+ * initialize tuple type and projection info
+ * ----------------
+ */
+ ExecAssignResultTypeFromTL((Plan *) node, &nlstate->jstate);
+ ExecAssignProjectionInfo((Plan *) node, &nlstate->jstate);
+
+ /* ----------------
+ * finally, wipe the current outer tuple clean.
+ * ----------------
+ */
+ nlstate->jstate.cs_OuterTupleSlot = NULL;
+ nlstate->jstate.cs_TupFromTlist = false;
+
+ NL1_printf("ExecInitNestLoop: %s\n",
+ "node initialized");
+ return TRUE;
}
int
-ExecCountSlotsNestLoop(NestLoop *node)
+ExecCountSlotsNestLoop(NestLoop * node)
{
- return ExecCountSlotsNode(outerPlan(node)) +
- ExecCountSlotsNode(innerPlan(node)) +
- NESTLOOP_NSLOTS;
+ return ExecCountSlotsNode(outerPlan(node)) +
+ ExecCountSlotsNode(innerPlan(node)) +
+ NESTLOOP_NSLOTS;
}
/* ----------------------------------------------------------------
- * ExecEndNestLoop
- *
- * closes down scans and frees allocated storage
+ * ExecEndNestLoop
+ *
+ * closes down scans and frees allocated storage
* ----------------------------------------------------------------
*/
void
-ExecEndNestLoop(NestLoop *node)
+ExecEndNestLoop(NestLoop * node)
{
- NestLoopState *nlstate;
-
- NL1_printf("ExecEndNestLoop: %s\n",
- "ending node processing");
-
- /* ----------------
- * get info from the node
- * ----------------
- */
- nlstate = node->nlstate;
-
- /* ----------------
- * Free the projection info
- *
- * Note: we don't ExecFreeResultType(nlstate)
- * because the rule manager depends on the tupType
- * returned by ExecMain(). So for now, this
- * is freed at end-transaction time. -cim 6/2/91
- * ----------------
- */
- ExecFreeProjectionInfo(&nlstate->jstate);
-
- /* ----------------
- * close down subplans
- * ----------------
- */
- ExecEndNode(outerPlan((Plan *) node), (Plan*)node);
- ExecEndNode(innerPlan((Plan *) node), (Plan*)node);
-
- /* ----------------
- * clean out the tuple table
- * ----------------
- */
- ExecClearTuple(nlstate->jstate.cs_ResultTupleSlot);
-
- NL1_printf("ExecEndNestLoop: %s\n",
- "node processing ended");
+ NestLoopState *nlstate;
+
+ NL1_printf("ExecEndNestLoop: %s\n",
+ "ending node processing");
+
+ /* ----------------
+ * get info from the node
+ * ----------------
+ */
+ nlstate = node->nlstate;
+
+ /* ----------------
+ * Free the projection info
+ *
+ * Note: we don't ExecFreeResultType(nlstate)
+ * because the rule manager depends on the tupType
+ * returned by ExecMain(). So for now, this
+ * is freed at end-transaction time. -cim 6/2/91
+ * ----------------
+ */
+ ExecFreeProjectionInfo(&nlstate->jstate);
+
+ /* ----------------
+ * close down subplans
+ * ----------------
+ */
+ ExecEndNode(outerPlan((Plan *) node), (Plan *) node);
+ ExecEndNode(innerPlan((Plan *) node), (Plan *) node);
+
+ /* ----------------
+ * clean out the tuple table
+ * ----------------
+ */
+ ExecClearTuple(nlstate->jstate.cs_ResultTupleSlot);
+
+ NL1_printf("ExecEndNestLoop: %s\n",
+ "node processing ended");
}
diff --git a/src/backend/executor/nodeResult.c b/src/backend/executor/nodeResult.c
index f4553dcc7b7..743bd73f2b3 100644
--- a/src/backend/executor/nodeResult.c
+++ b/src/backend/executor/nodeResult.c
@@ -1,33 +1,33 @@
/*-------------------------------------------------------------------------
*
* nodeResult.c--
- * support for constant nodes needing special code.
+ * support for constant nodes needing special code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
- * DESCRIPTION
+ * DESCRIPTION
*
- * Example: in constant queries where no relations are scanned,
- * the planner generates result nodes. Examples of such queries are:
+ * Example: in constant queries where no relations are scanned,
+ * the planner generates result nodes. Examples of such queries are:
*
- * retrieve (x = 1)
- * and
- * append emp (name = "mike", salary = 15000)
+ * retrieve (x = 1)
+ * and
+ * append emp (name = "mike", salary = 15000)
*
- * Result nodes are also used to optimise queries
- * with tautological qualifications like:
+ * Result nodes are also used to optimise queries
+ * with tautological qualifications like:
*
- * retrieve (emp.all) where 2 > 1
+ * retrieve (emp.all) where 2 > 1
*
- * In this case, the plan generated is
+ * In this case, the plan generated is
*
- * Result (with 2 > 1 qual)
- * /
- * SeqScan (emp.all)
+ * Result (with 2 > 1 qual)
+ * /
+ * SeqScan (emp.all)
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.2 1996/10/31 10:12:18 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.3 1997/09/07 04:41:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,253 +38,259 @@
#include "executor/nodeResult.h"
/* ----------------------------------------------------------------
- * ExecResult(node)
+ * ExecResult(node)
*
- * returns the tuples from the outer plan which satisify the
- * qualification clause. Since result nodes with right
- * subtrees are never planned, we ignore the right subtree
- * entirely (for now).. -cim 10/7/89
+ * returns the tuples from the outer plan which satisify the
+ * qualification clause. Since result nodes with right
+ * subtrees are never planned, we ignore the right subtree
+ * entirely (for now).. -cim 10/7/89
*
- * The qualification containing only constant clauses are
- * checked first before any processing is done. It always returns
- * 'nil' if the constant qualification is not satisfied.
+ * The qualification containing only constant clauses are
+ * checked first before any processing is done. It always returns
+ * 'nil' if the constant qualification is not satisfied.
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecResult(Result *node)
+ExecResult(Result * node)
{
- ResultState *resstate;
- TupleTableSlot *outerTupleSlot;
- TupleTableSlot *resultSlot;
- Plan *outerPlan;
- ExprContext *econtext;
- Node *qual;
- bool qualResult;
- bool isDone;
- ProjectionInfo *projInfo;
-
- /* ----------------
- * initialize the result node's state
- * ----------------
- */
- resstate = node->resstate;
-
- /* ----------------
- * get the expression context
- * ----------------
- */
- econtext = resstate->cstate.cs_ExprContext;
-
- /* ----------------
- * check tautological qualifications like (2 > 1)
- * ----------------
- */
- qual = node->resconstantqual;
- if (qual != NULL) {
- qualResult = ExecQual((List*)qual, econtext);
- /* ----------------
- * if we failed the constant qual, then there
- * is no need to continue processing because regardless of
- * what happens, the constant qual will be false..
- * ----------------
- */
- if (qualResult == false)
- return NULL;
-
- /* ----------------
- * our constant qualification succeeded so now we
- * throw away the qual because we know it will always
- * succeed.
- * ----------------
- */
- node->resconstantqual = NULL;
- }
-
- if (resstate->cstate.cs_TupFromTlist) {
+ ResultState *resstate;
+ TupleTableSlot *outerTupleSlot;
+ TupleTableSlot *resultSlot;
+ Plan *outerPlan;
+ ExprContext *econtext;
+ Node *qual;
+ bool qualResult;
+ bool isDone;
ProjectionInfo *projInfo;
-
- projInfo = resstate->cstate.cs_ProjInfo;
- resultSlot = ExecProject(projInfo, &isDone);
- if (!isDone)
- return resultSlot;
- }
-
- /* ----------------
- * retrieve a tuple that satisfy the qual from the outer plan until
- * there are no more.
- *
- * if rs_done is 1 then it means that we were asked to return
- * a constant tuple and we alread did the last time ExecResult()
- * was called, so now we are through.
- * ----------------
- */
- outerPlan = outerPlan(node);
-
- while (!resstate->rs_done) {
/* ----------------
- * get next outer tuple if necessary.
+ * initialize the result node's state
* ----------------
*/
- if (outerPlan != NULL) {
- outerTupleSlot = ExecProcNode(outerPlan, (Plan*)node);
-
- if (TupIsNull(outerTupleSlot))
- return NULL;
-
- resstate->cstate.cs_OuterTupleSlot = outerTupleSlot;
- } else {
-
- /* ----------------
- * if we don't have an outer plan, then it's probably
- * the case that we are doing a retrieve or an append
- * with a constant target list, so we should only return
- * the constant tuple once or never if we fail the qual.
- * ----------------
- */
- resstate->rs_done = 1;
- }
-
+ resstate = node->resstate;
+
/* ----------------
- * get the information to place into the expr context
+ * get the expression context
* ----------------
*/
- resstate = node->resstate;
-
- outerTupleSlot = resstate->cstate.cs_OuterTupleSlot;
-
+ econtext = resstate->cstate.cs_ExprContext;
+
/* ----------------
- * fill in the information in the expression context
- * XXX gross hack. use outer tuple as scan tuple
+ * check tautological qualifications like (2 > 1)
* ----------------
*/
- econtext->ecxt_outertuple = outerTupleSlot;
- econtext->ecxt_scantuple = outerTupleSlot;
-
+ qual = node->resconstantqual;
+ if (qual != NULL)
+ {
+ qualResult = ExecQual((List *) qual, econtext);
+ /* ----------------
+ * if we failed the constant qual, then there
+ * is no need to continue processing because regardless of
+ * what happens, the constant qual will be false..
+ * ----------------
+ */
+ if (qualResult == false)
+ return NULL;
+
+ /* ----------------
+ * our constant qualification succeeded so now we
+ * throw away the qual because we know it will always
+ * succeed.
+ * ----------------
+ */
+ node->resconstantqual = NULL;
+ }
+
+ if (resstate->cstate.cs_TupFromTlist)
+ {
+ ProjectionInfo *projInfo;
+
+ projInfo = resstate->cstate.cs_ProjInfo;
+ resultSlot = ExecProject(projInfo, &isDone);
+ if (!isDone)
+ return resultSlot;
+ }
+
/* ----------------
- * form the result tuple and pass it back using ExecProject()
+ * retrieve a tuple that satisfy the qual from the outer plan until
+ * there are no more.
+ *
+ * if rs_done is 1 then it means that we were asked to return
+ * a constant tuple and we alread did the last time ExecResult()
+ * was called, so now we are through.
* ----------------
*/
- projInfo = resstate->cstate.cs_ProjInfo;
- resultSlot = ExecProject(projInfo, &isDone);
- resstate->cstate.cs_TupFromTlist = !isDone;
- return resultSlot;
- }
+ outerPlan = outerPlan(node);
+
+ while (!resstate->rs_done)
+ {
+
+ /* ----------------
+ * get next outer tuple if necessary.
+ * ----------------
+ */
+ if (outerPlan != NULL)
+ {
+ outerTupleSlot = ExecProcNode(outerPlan, (Plan *) node);
+
+ if (TupIsNull(outerTupleSlot))
+ return NULL;
- return NULL;
+ resstate->cstate.cs_OuterTupleSlot = outerTupleSlot;
+ }
+ else
+ {
+
+ /* ----------------
+ * if we don't have an outer plan, then it's probably
+ * the case that we are doing a retrieve or an append
+ * with a constant target list, so we should only return
+ * the constant tuple once or never if we fail the qual.
+ * ----------------
+ */
+ resstate->rs_done = 1;
+ }
+
+ /* ----------------
+ * get the information to place into the expr context
+ * ----------------
+ */
+ resstate = node->resstate;
+
+ outerTupleSlot = resstate->cstate.cs_OuterTupleSlot;
+
+ /* ----------------
+ * fill in the information in the expression context
+ * XXX gross hack. use outer tuple as scan tuple
+ * ----------------
+ */
+ econtext->ecxt_outertuple = outerTupleSlot;
+ econtext->ecxt_scantuple = outerTupleSlot;
+
+ /* ----------------
+ * form the result tuple and pass it back using ExecProject()
+ * ----------------
+ */
+ projInfo = resstate->cstate.cs_ProjInfo;
+ resultSlot = ExecProject(projInfo, &isDone);
+ resstate->cstate.cs_TupFromTlist = !isDone;
+ return resultSlot;
+ }
+
+ return NULL;
}
/* ----------------------------------------------------------------
- * ExecInitResult
- *
- * Creates the run-time state information for the result node
- * produced by the planner and initailizes outer relations
- * (child nodes).
+ * ExecInitResult
+ *
+ * Creates the run-time state information for the result node
+ * produced by the planner and initailizes outer relations
+ * (child nodes).
* ----------------------------------------------------------------
*/
bool
-ExecInitResult(Result *node, EState *estate, Plan *parent)
+ExecInitResult(Result * node, EState * estate, Plan * parent)
{
- ResultState *resstate;
-
- /* ----------------
- * assign execution state to node
- * ----------------
- */
- node->plan.state = estate;
-
- /* ----------------
- * create new ResultState for node
- * ----------------
- */
- resstate = makeNode(ResultState);
- resstate->rs_done = 0;
- node->resstate = resstate;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks and
- * + create expression context for node
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &resstate->cstate, parent);
- ExecAssignExprContext(estate, &resstate->cstate);
-
+ ResultState *resstate;
+
+ /* ----------------
+ * assign execution state to node
+ * ----------------
+ */
+ node->plan.state = estate;
+
+ /* ----------------
+ * create new ResultState for node
+ * ----------------
+ */
+ resstate = makeNode(ResultState);
+ resstate->rs_done = 0;
+ node->resstate = resstate;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks and
+ * + create expression context for node
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &resstate->cstate, parent);
+ ExecAssignExprContext(estate, &resstate->cstate);
+
#define RESULT_NSLOTS 1
- /* ----------------
- * tuple table initialization
- * ----------------
- */
- ExecInitResultTupleSlot(estate, &resstate->cstate);
-
- /* ----------------
- * then initialize children
- * ----------------
- */
- ExecInitNode(outerPlan(node), estate, (Plan*)node);
-
- /*
- * we don't use inner plan
- */
- Assert(innerPlan(node)==NULL);
-
- /* ----------------
- * initialize tuple type and projection info
- * ----------------
- */
- ExecAssignResultTypeFromTL((Plan*)node, &resstate->cstate);
- ExecAssignProjectionInfo((Plan*)node, &resstate->cstate);
-
- /* ----------------
- * set "are we done yet" to false
- * ----------------
- */
- resstate->rs_done = 0;
-
- return TRUE;
+ /* ----------------
+ * tuple table initialization
+ * ----------------
+ */
+ ExecInitResultTupleSlot(estate, &resstate->cstate);
+
+ /* ----------------
+ * then initialize children
+ * ----------------
+ */
+ ExecInitNode(outerPlan(node), estate, (Plan *) node);
+
+ /*
+ * we don't use inner plan
+ */
+ Assert(innerPlan(node) == NULL);
+
+ /* ----------------
+ * initialize tuple type and projection info
+ * ----------------
+ */
+ ExecAssignResultTypeFromTL((Plan *) node, &resstate->cstate);
+ ExecAssignProjectionInfo((Plan *) node, &resstate->cstate);
+
+ /* ----------------
+ * set "are we done yet" to false
+ * ----------------
+ */
+ resstate->rs_done = 0;
+
+ return TRUE;
}
int
-ExecCountSlotsResult(Result *node)
+ExecCountSlotsResult(Result * node)
{
- return ExecCountSlotsNode(outerPlan(node)) + RESULT_NSLOTS;
+ return ExecCountSlotsNode(outerPlan(node)) + RESULT_NSLOTS;
}
/* ----------------------------------------------------------------
- * ExecEndResult
- *
- * fees up storage allocated through C routines
+ * ExecEndResult
+ *
+ * fees up storage allocated through C routines
* ----------------------------------------------------------------
*/
void
-ExecEndResult(Result *node)
+ExecEndResult(Result * node)
{
- ResultState *resstate;
-
- resstate = node->resstate;
-
- /* ----------------
- * Free the projection info
- *
- * Note: we don't ExecFreeResultType(resstate)
- * because the rule manager depends on the tupType
- * returned by ExecMain(). So for now, this
- * is freed at end-transaction time. -cim 6/2/91
- * ----------------
- */
- ExecFreeProjectionInfo(&resstate->cstate);
-
- /* ----------------
- * shut down subplans
- * ----------------
- */
- ExecEndNode(outerPlan(node), (Plan*)node);
-
- /* ----------------
- * clean out the tuple table
- * ----------------
- */
- ExecClearTuple(resstate->cstate.cs_ResultTupleSlot);
+ ResultState *resstate;
+
+ resstate = node->resstate;
+
+ /* ----------------
+ * Free the projection info
+ *
+ * Note: we don't ExecFreeResultType(resstate)
+ * because the rule manager depends on the tupType
+ * returned by ExecMain(). So for now, this
+ * is freed at end-transaction time. -cim 6/2/91
+ * ----------------
+ */
+ ExecFreeProjectionInfo(&resstate->cstate);
+
+ /* ----------------
+ * shut down subplans
+ * ----------------
+ */
+ ExecEndNode(outerPlan(node), (Plan *) node);
+
+ /* ----------------
+ * clean out the tuple table
+ * ----------------
+ */
+ ExecClearTuple(resstate->cstate.cs_ResultTupleSlot);
}
diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c
index b94bb58d260..d3451f8026f 100644
--- a/src/backend/executor/nodeSeqscan.c
+++ b/src/backend/executor/nodeSeqscan.c
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* nodeSeqscan.c--
- * Support routines for sequential scans of relations.
+ * Support routines for sequential scans of relations.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.4 1997/08/19 21:31:12 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.5 1997/09/07 04:41:44 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * ExecSeqScan sequentially scans a relation.
- * ExecSeqNext retrieve next tuple in sequential order.
- * ExecInitSeqScan creates and initializes a seqscan node.
- * ExecEndSeqScan releases any storage allocated.
- * ExecSeqReScan rescans the relation
- * ExecMarkPos marks scan position
- * ExecRestrPos restores scan position
+ * ExecSeqScan sequentially scans a relation.
+ * ExecSeqNext retrieve next tuple in sequential order.
+ * ExecInitSeqScan creates and initializes a seqscan node.
+ * ExecEndSeqScan releases any storage allocated.
+ * ExecSeqReScan rescans the relation
+ * ExecMarkPos marks scan position
+ * ExecRestrPos restores scan position
*
*/
#include "postgres.h"
@@ -30,429 +30,443 @@
#include "access/heapam.h"
#include "parser/parsetree.h"
-static Oid InitScanRelation(SeqScan *node, EState *estate,
- CommonScanState *scanstate, Plan *outerPlan);
+static Oid
+InitScanRelation(SeqScan * node, EState * estate,
+ CommonScanState * scanstate, Plan * outerPlan);
-static TupleTableSlot *SeqNext(SeqScan *node);
+static TupleTableSlot *SeqNext(SeqScan * node);
/* ----------------------------------------------------------------
- * Scan Support
+ * Scan Support
* ----------------------------------------------------------------
*/
/* ----------------------------------------------------------------
- * SeqNext
+ * SeqNext
*
- * This is a workhorse for ExecSeqScan
+ * This is a workhorse for ExecSeqScan
* ----------------------------------------------------------------
*/
static TupleTableSlot *
-SeqNext(SeqScan *node)
+SeqNext(SeqScan * node)
{
- HeapTuple tuple;
- HeapScanDesc scandesc;
- CommonScanState *scanstate;
- EState *estate;
- ScanDirection direction;
- TupleTableSlot *slot;
- Buffer buffer;
-
- /* ----------------
- * get information from the estate and scan state
- * ----------------
- */
- estate = node->plan.state;
- scanstate = node->scanstate;
- scandesc = scanstate->css_currentScanDesc;
- direction = estate->es_direction;
-
- /* ----------------
- * get the next tuple from the access methods
- * ----------------
- */
- tuple = heap_getnext(scandesc, /* scan desc */
- ScanDirectionIsBackward(direction), /*backward flag*/
- &buffer); /* return: buffer */
-
- /* ----------------
- * save the tuple and the buffer returned to us by the access methods
- * in our scan tuple slot and return the slot. Note: we pass 'false'
- * because tuples returned by heap_getnext() are pointers onto
- * disk pages and were not created with palloc() and so should not
- * be pfree()'d.
- * ----------------
- */
- slot = scanstate->css_ScanTupleSlot;
-
- slot = ExecStoreTuple(tuple, /* tuple to store */
- slot, /* slot to store in */
- buffer, /* buffer associated with this tuple */
- false); /* don't pfree this pointer */
-
- /* ----------------
- * XXX -- mao says: The sequential scan for heap relations will
- * automatically unpin the buffer this tuple is on when we cross
- * a page boundary. The clearslot code also does this. We bump
- * the pin count on the page here, since we actually have two
- * pointers to it -- one in the scan desc and one in the tuple
- * table slot. --mar 20 91
- * ----------------
- */
- ExecIncrSlotBufferRefcnt(slot);
-
- return slot;
+ HeapTuple tuple;
+ HeapScanDesc scandesc;
+ CommonScanState *scanstate;
+ EState *estate;
+ ScanDirection direction;
+ TupleTableSlot *slot;
+ Buffer buffer;
+
+ /* ----------------
+ * get information from the estate and scan state
+ * ----------------
+ */
+ estate = node->plan.state;
+ scanstate = node->scanstate;
+ scandesc = scanstate->css_currentScanDesc;
+ direction = estate->es_direction;
+
+ /* ----------------
+ * get the next tuple from the access methods
+ * ----------------
+ */
+ tuple = heap_getnext(scandesc, /* scan desc */
+ ScanDirectionIsBackward(direction), /* backward flag */
+ &buffer); /* return: buffer */
+
+ /* ----------------
+ * save the tuple and the buffer returned to us by the access methods
+ * in our scan tuple slot and return the slot. Note: we pass 'false'
+ * because tuples returned by heap_getnext() are pointers onto
+ * disk pages and were not created with palloc() and so should not
+ * be pfree()'d.
+ * ----------------
+ */
+ slot = scanstate->css_ScanTupleSlot;
+
+ slot = ExecStoreTuple(tuple,/* tuple to store */
+ slot, /* slot to store in */
+ buffer, /* buffer associated with this
+ * tuple */
+ false); /* don't pfree this pointer */
+
+ /* ----------------
+ * XXX -- mao says: The sequential scan for heap relations will
+ * automatically unpin the buffer this tuple is on when we cross
+ * a page boundary. The clearslot code also does this. We bump
+ * the pin count on the page here, since we actually have two
+ * pointers to it -- one in the scan desc and one in the tuple
+ * table slot. --mar 20 91
+ * ----------------
+ */
+ ExecIncrSlotBufferRefcnt(slot);
+
+ return slot;
}
/* ----------------------------------------------------------------
- * ExecSeqScan(node)
+ * ExecSeqScan(node)
+ *
+ * Scans the relation sequentially and returns the next qualifying
+ * tuple.
+ * It calls the ExecScan() routine and passes it the access method
+ * which retrieve tuples sequentially.
*
- * Scans the relation sequentially and returns the next qualifying
- * tuple.
- * It calls the ExecScan() routine and passes it the access method
- * which retrieve tuples sequentially.
- *
*/
TupleTableSlot *
-ExecSeqScan(SeqScan *node)
+ExecSeqScan(SeqScan * node)
{
- TupleTableSlot *slot;
- Plan *outerPlan;
-
-S_printf("ExecSeqScan: scanning node: "); S_nodeDisplay(node);
-
- /* ----------------
- * if there is an outer subplan, get a tuple from it
- * else, scan the relation
- * ----------------
- */
- outerPlan = outerPlan((Plan *) node);
- if (outerPlan) {
- slot = ExecProcNode(outerPlan, (Plan*) node);
- } else {
- slot = ExecScan(node, SeqNext);
- }
-
-S1_printf("ExecSeqScan: returned tuple slot: %d\n", slot);
-
- return slot;
+ TupleTableSlot *slot;
+ Plan *outerPlan;
+
+ S_printf("ExecSeqScan: scanning node: ");
+ S_nodeDisplay(node);
+
+ /* ----------------
+ * if there is an outer subplan, get a tuple from it
+ * else, scan the relation
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+ if (outerPlan)
+ {
+ slot = ExecProcNode(outerPlan, (Plan *) node);
+ }
+ else
+ {
+ slot = ExecScan(node, SeqNext);
+ }
+
+ S1_printf("ExecSeqScan: returned tuple slot: %d\n", slot);
+
+ return slot;
}
/* ----------------------------------------------------------------
- * InitScanRelation
+ * InitScanRelation
*
- * This does the initialization for scan relations and
- * subplans of scans.
+ * This does the initialization for scan relations and
+ * subplans of scans.
* ----------------------------------------------------------------
*/
-static Oid
-InitScanRelation(SeqScan *node, EState *estate,
- CommonScanState *scanstate, Plan *outerPlan)
+static Oid
+InitScanRelation(SeqScan * node, EState * estate,
+ CommonScanState * scanstate, Plan * outerPlan)
{
- Index relid;
- List *rangeTable;
- RangeTblEntry *rtentry;
- Oid reloid;
- TimeQual timeQual;
- ScanDirection direction;
- Relation currentRelation;
- HeapScanDesc currentScanDesc;
- RelationInfo *resultRelationInfo;
-
- if (outerPlan == NULL) {
- /* ----------------
- * if the outer node is nil then we are doing a simple
- * sequential scan of a relation...
- *
- * get the relation object id from the relid'th entry
- * in the range table, open that relation and initialize
- * the scan state...
- * ----------------
- */
- relid = node->scanrelid;
- rangeTable = estate->es_range_table;
- rtentry = rt_fetch(relid, rangeTable);
- reloid = rtentry->relid;
- timeQual = rtentry->timeQual;
- direction = estate->es_direction;
- resultRelationInfo = estate->es_result_relation_info;
-
- ExecOpenScanR(reloid, /* relation */
- 0, /* nkeys */
- NULL, /* scan key */
- 0, /* is index */
- direction, /* scan direction */
- timeQual, /* time qual */
- &currentRelation, /* return: rel desc */
- (Pointer *) &currentScanDesc); /* return: scan desc */
-
- scanstate->css_currentRelation = currentRelation;
- scanstate->css_currentScanDesc = currentScanDesc;
-
- ExecAssignScanType(scanstate,
- RelationGetTupleDescriptor(currentRelation));
- } else {
+ Index relid;
+ List *rangeTable;
+ RangeTblEntry *rtentry;
+ Oid reloid;
+ TimeQual timeQual;
+ ScanDirection direction;
+ Relation currentRelation;
+ HeapScanDesc currentScanDesc;
+ RelationInfo *resultRelationInfo;
+
+ if (outerPlan == NULL)
+ {
+ /* ----------------
+ * if the outer node is nil then we are doing a simple
+ * sequential scan of a relation...
+ *
+ * get the relation object id from the relid'th entry
+ * in the range table, open that relation and initialize
+ * the scan state...
+ * ----------------
+ */
+ relid = node->scanrelid;
+ rangeTable = estate->es_range_table;
+ rtentry = rt_fetch(relid, rangeTable);
+ reloid = rtentry->relid;
+ timeQual = rtentry->timeQual;
+ direction = estate->es_direction;
+ resultRelationInfo = estate->es_result_relation_info;
+
+ ExecOpenScanR(reloid, /* relation */
+ 0, /* nkeys */
+ NULL, /* scan key */
+ 0, /* is index */
+ direction,/* scan direction */
+ timeQual, /* time qual */
+ &currentRelation, /* return: rel desc */
+ (Pointer *) & currentScanDesc); /* return: scan desc */
+
+ scanstate->css_currentRelation = currentRelation;
+ scanstate->css_currentScanDesc = currentScanDesc;
+
+ ExecAssignScanType(scanstate,
+ RelationGetTupleDescriptor(currentRelation));
+ }
+ else
+ {
+ /* ----------------
+ * otherwise we are scanning tuples from the
+ * outer subplan so we initialize the outer plan
+ * and nullify
+ * ----------------
+ */
+ ExecInitNode(outerPlan, estate, (Plan *) node);
+
+ node->scanrelid = 0;
+ scanstate->css_currentRelation = NULL;
+ scanstate->css_currentScanDesc = NULL;
+ ExecAssignScanType(scanstate, NULL);
+ reloid = InvalidOid;
+ }
+
/* ----------------
- * otherwise we are scanning tuples from the
- * outer subplan so we initialize the outer plan
- * and nullify
+ * return the relation
* ----------------
*/
- ExecInitNode(outerPlan, estate, (Plan*)node);
-
- node->scanrelid = 0;
- scanstate->css_currentRelation = NULL;
- scanstate->css_currentScanDesc = NULL;
- ExecAssignScanType(scanstate, NULL);
- reloid = InvalidOid;
- }
-
- /* ----------------
- * return the relation
- * ----------------
- */
- return reloid;
+ return reloid;
}
/* ----------------------------------------------------------------
- * ExecInitSeqScan
+ * ExecInitSeqScan
*
* old comments
- * Creates the run-time state information for the seqscan node
- * and sets the relation id to contain relevant descriptors.
- *
- * If there is a outer subtree (sort), the outer subtree
- * is initialized and the relation id is set to the descriptors
- * returned by the subtree.
+ * Creates the run-time state information for the seqscan node
+ * and sets the relation id to contain relevant descriptors.
+ *
+ * If there is a outer subtree (sort), the outer subtree
+ * is initialized and the relation id is set to the descriptors
+ * returned by the subtree.
* ----------------------------------------------------------------
*/
bool
-ExecInitSeqScan(SeqScan *node, EState *estate, Plan *parent)
+ExecInitSeqScan(SeqScan * node, EState * estate, Plan * parent)
{
- CommonScanState *scanstate;
- Plan *outerPlan;
- Oid reloid;
- HeapScanDesc scandesc;
-
- /* ----------------
- * assign the node's execution state
- * ----------------
- */
- node->plan.state = estate;
-
- /* ----------------
- * create new CommonScanState for node
- * ----------------
- */
- scanstate = makeNode(CommonScanState);
- node->scanstate = scanstate;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + create expression context for node
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &scanstate->cstate, parent);
- ExecAssignExprContext(estate, &scanstate->cstate);
+ CommonScanState *scanstate;
+ Plan *outerPlan;
+ Oid reloid;
+ HeapScanDesc scandesc;
+
+ /* ----------------
+ * assign the node's execution state
+ * ----------------
+ */
+ node->plan.state = estate;
+
+ /* ----------------
+ * create new CommonScanState for node
+ * ----------------
+ */
+ scanstate = makeNode(CommonScanState);
+ node->scanstate = scanstate;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + create expression context for node
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &scanstate->cstate, parent);
+ ExecAssignExprContext(estate, &scanstate->cstate);
#define SEQSCAN_NSLOTS 3
- /* ----------------
- * tuple table initialization
- * ----------------
- */
- ExecInitResultTupleSlot(estate, &scanstate->cstate);
- ExecInitScanTupleSlot(estate, scanstate);
-
- /* ----------------
- * initialize scan relation or outer subplan
- * ----------------
- */
- outerPlan = outerPlan((Plan *)node);
-
- reloid = InitScanRelation(node, estate, scanstate, outerPlan);
-
- scandesc = scanstate->css_currentScanDesc;
- scanstate->cstate.cs_TupFromTlist = false;
-
- /* ----------------
- * initialize tuple type
- * ----------------
- */
- ExecAssignResultTypeFromTL((Plan*)node, &scanstate->cstate);
- ExecAssignProjectionInfo((Plan*)node, &scanstate->cstate);
-
- return TRUE;
+ /* ----------------
+ * tuple table initialization
+ * ----------------
+ */
+ ExecInitResultTupleSlot(estate, &scanstate->cstate);
+ ExecInitScanTupleSlot(estate, scanstate);
+
+ /* ----------------
+ * initialize scan relation or outer subplan
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+
+ reloid = InitScanRelation(node, estate, scanstate, outerPlan);
+
+ scandesc = scanstate->css_currentScanDesc;
+ scanstate->cstate.cs_TupFromTlist = false;
+
+ /* ----------------
+ * initialize tuple type
+ * ----------------
+ */
+ ExecAssignResultTypeFromTL((Plan *) node, &scanstate->cstate);
+ ExecAssignProjectionInfo((Plan *) node, &scanstate->cstate);
+
+ return TRUE;
}
int
-ExecCountSlotsSeqScan(SeqScan *node)
+ExecCountSlotsSeqScan(SeqScan * node)
{
- return ExecCountSlotsNode(outerPlan(node)) +
+ return ExecCountSlotsNode(outerPlan(node)) +
ExecCountSlotsNode(innerPlan(node)) +
- SEQSCAN_NSLOTS;
+ SEQSCAN_NSLOTS;
}
/* ----------------------------------------------------------------
- * ExecEndSeqScan
- *
- * frees any storage allocated through C routines.
- *| ...and also closes relations and/or shuts down outer subplan
- *| -cim 8/14/89
+ * ExecEndSeqScan
+ *
+ * frees any storage allocated through C routines.
+ *| ...and also closes relations and/or shuts down outer subplan
+ *| -cim 8/14/89
* ----------------------------------------------------------------
*/
void
-ExecEndSeqScan(SeqScan *node)
+ExecEndSeqScan(SeqScan * node)
{
- CommonScanState *scanstate;
- Plan *outerPlan;
-
- /* ----------------
- * get information from node
- * ----------------
- */
- scanstate = node->scanstate;
-
- /* ----------------
- * Free the projection info and the scan attribute info
- *
- * Note: we don't ExecFreeResultType(scanstate)
- * because the rule manager depends on the tupType
- * returned by ExecMain(). So for now, this
- * is freed at end-transaction time. -cim 6/2/91
- * ----------------
- */
- ExecFreeProjectionInfo(&scanstate->cstate);
-
- /* ----------------
- * close scan relation
- * ----------------
- */
- ExecCloseR((Plan*) node);
-
- /* ----------------
- * clean up outer subtree (does nothing if there is no outerPlan)
- * ----------------
- */
- outerPlan = outerPlan((Plan *)node);
- ExecEndNode(outerPlan, (Plan*)node);
-
- /* ----------------
- * clean out the tuple table
- * ----------------
- */
- ExecClearTuple(scanstate->cstate.cs_ResultTupleSlot);
- ExecClearTuple(scanstate->css_ScanTupleSlot);
+ CommonScanState *scanstate;
+ Plan *outerPlan;
+
+ /* ----------------
+ * get information from node
+ * ----------------
+ */
+ scanstate = node->scanstate;
+
+ /* ----------------
+ * Free the projection info and the scan attribute info
+ *
+ * Note: we don't ExecFreeResultType(scanstate)
+ * because the rule manager depends on the tupType
+ * returned by ExecMain(). So for now, this
+ * is freed at end-transaction time. -cim 6/2/91
+ * ----------------
+ */
+ ExecFreeProjectionInfo(&scanstate->cstate);
+
+ /* ----------------
+ * close scan relation
+ * ----------------
+ */
+ ExecCloseR((Plan *) node);
+
+ /* ----------------
+ * clean up outer subtree (does nothing if there is no outerPlan)
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+ ExecEndNode(outerPlan, (Plan *) node);
+
+ /* ----------------
+ * clean out the tuple table
+ * ----------------
+ */
+ ExecClearTuple(scanstate->cstate.cs_ResultTupleSlot);
+ ExecClearTuple(scanstate->css_ScanTupleSlot);
}
/* ----------------------------------------------------------------
- * Join Support
+ * Join Support
* ----------------------------------------------------------------
*/
/* ----------------------------------------------------------------
- * ExecSeqReScan
- *
- * Rescans the relation.
+ * ExecSeqReScan
+ *
+ * Rescans the relation.
* ----------------------------------------------------------------
*/
void
-ExecSeqReScan(SeqScan *node, ExprContext *exprCtxt, Plan* parent)
+ExecSeqReScan(SeqScan * node, ExprContext * exprCtxt, Plan * parent)
{
- CommonScanState *scanstate;
- EState *estate;
- Plan *outerPlan;
- Relation rdesc;
- HeapScanDesc sdesc;
- ScanDirection direction;
-
- scanstate = node->scanstate;
- estate = node->plan.state;
-
- outerPlan = outerPlan((Plan*)node);
- if (outerPlan) {
- /* we are scanning a subplan */
- outerPlan = outerPlan((Plan *)node);
- ExecReScan(outerPlan, exprCtxt, parent);
- } else {
- /* otherwise, we are scanning a relation */
- rdesc = scanstate->css_currentRelation;
- sdesc = scanstate->css_currentScanDesc;
- direction = estate->es_direction;
- sdesc = ExecReScanR(rdesc, sdesc, direction, 0, NULL);
- scanstate->css_currentScanDesc = sdesc;
- }
+ CommonScanState *scanstate;
+ EState *estate;
+ Plan *outerPlan;
+ Relation rdesc;
+ HeapScanDesc sdesc;
+ ScanDirection direction;
+
+ scanstate = node->scanstate;
+ estate = node->plan.state;
+
+ outerPlan = outerPlan((Plan *) node);
+ if (outerPlan)
+ {
+ /* we are scanning a subplan */
+ outerPlan = outerPlan((Plan *) node);
+ ExecReScan(outerPlan, exprCtxt, parent);
+ }
+ else
+ {
+ /* otherwise, we are scanning a relation */
+ rdesc = scanstate->css_currentRelation;
+ sdesc = scanstate->css_currentScanDesc;
+ direction = estate->es_direction;
+ sdesc = ExecReScanR(rdesc, sdesc, direction, 0, NULL);
+ scanstate->css_currentScanDesc = sdesc;
+ }
}
/* ----------------------------------------------------------------
- * ExecSeqMarkPos(node)
- *
- * Marks scan position.
+ * ExecSeqMarkPos(node)
+ *
+ * Marks scan position.
* ----------------------------------------------------------------
*/
void
-ExecSeqMarkPos(SeqScan *node)
+ExecSeqMarkPos(SeqScan * node)
{
- CommonScanState *scanstate;
- Plan *outerPlan;
- HeapScanDesc sdesc;
-
- scanstate = node->scanstate;
-
- /* ----------------
- * if we are scanning a subplan then propagate
- * the ExecMarkPos() request to the subplan
- * ----------------
- */
- outerPlan = outerPlan((Plan*)node);
- if (outerPlan) {
- ExecMarkPos(outerPlan);
+ CommonScanState *scanstate;
+ Plan *outerPlan;
+ HeapScanDesc sdesc;
+
+ scanstate = node->scanstate;
+
+ /* ----------------
+ * if we are scanning a subplan then propagate
+ * the ExecMarkPos() request to the subplan
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+ if (outerPlan)
+ {
+ ExecMarkPos(outerPlan);
+ return;
+ }
+
+ /* ----------------
+ * otherwise we are scanning a relation so mark the
+ * position using the access methods..
+ *
+ * ----------------
+ */
+ sdesc = scanstate->css_currentScanDesc;
+ heap_markpos(sdesc);
+
return;
- }
-
- /* ----------------
- * otherwise we are scanning a relation so mark the
- * position using the access methods..
- *
- * ----------------
- */
- sdesc = scanstate->css_currentScanDesc;
- heap_markpos(sdesc);
-
- return;
}
/* ----------------------------------------------------------------
- * ExecSeqRestrPos
- *
- * Restores scan position.
+ * ExecSeqRestrPos
+ *
+ * Restores scan position.
* ----------------------------------------------------------------
*/
void
-ExecSeqRestrPos(SeqScan *node)
+ExecSeqRestrPos(SeqScan * node)
{
- CommonScanState *scanstate;
- Plan *outerPlan;
- HeapScanDesc sdesc;
-
- scanstate = node->scanstate;
-
- /* ----------------
- * if we are scanning a subplan then propagate
- * the ExecRestrPos() request to the subplan
- * ----------------
- */
- outerPlan = outerPlan((Plan*)node);
- if (outerPlan) {
- ExecRestrPos(outerPlan);
- return;
- }
-
- /* ----------------
- * otherwise we are scanning a relation so restore the
- * position using the access methods..
- * ----------------
- */
- sdesc = scanstate->css_currentScanDesc;
- heap_restrpos(sdesc);
+ CommonScanState *scanstate;
+ Plan *outerPlan;
+ HeapScanDesc sdesc;
+
+ scanstate = node->scanstate;
+
+ /* ----------------
+ * if we are scanning a subplan then propagate
+ * the ExecRestrPos() request to the subplan
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+ if (outerPlan)
+ {
+ ExecRestrPos(outerPlan);
+ return;
+ }
+
+ /* ----------------
+ * otherwise we are scanning a relation so restore the
+ * position using the access methods..
+ * ----------------
+ */
+ sdesc = scanstate->css_currentScanDesc;
+ heap_restrpos(sdesc);
}
diff --git a/src/backend/executor/nodeSort.c b/src/backend/executor/nodeSort.c
index 0955108b2fb..eb2e2e7b180 100644
--- a/src/backend/executor/nodeSort.c
+++ b/src/backend/executor/nodeSort.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* nodeSort.c--
- * Routines to handle sorting of relations.
+ * Routines to handle sorting of relations.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.6 1997/08/21 02:28:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.7 1997/09/07 04:41:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,383 +25,389 @@
#include "optimizer/internal.h" /* for _TEMP_RELATION_ID_ */
/* ----------------------------------------------------------------
- * FormSortKeys(node)
- *
- * Forms the structure containing information used to sort the relation.
- *
- * Returns an array of ScanKeyData.
+ * FormSortKeys(node)
+ *
+ * Forms the structure containing information used to sort the relation.
+ *
+ * Returns an array of ScanKeyData.
* ----------------------------------------------------------------
*/
-static ScanKey
-FormSortKeys(Sort *sortnode)
+static ScanKey
+FormSortKeys(Sort * sortnode)
{
- ScanKey sortkeys;
- List *targetList;
- List *tl;
- int keycount;
- Resdom *resdom;
- AttrNumber resno;
- Index reskey;
- Oid reskeyop;
-
- /* ----------------
- * get information from the node
- * ----------------
- */
- targetList = sortnode->plan.targetlist;
- keycount = sortnode->keycount;
-
- /* ----------------
- * first allocate space for scan keys
- * ----------------
- */
- if (keycount <= 0)
- elog(WARN, "FormSortKeys: keycount <= 0");
- sortkeys = (ScanKey) palloc(keycount * sizeof(ScanKeyData));
-
- /* ----------------
- * form each scan key from the resdom info in the target list
- * ----------------
- */
- foreach(tl, targetList) {
- TargetEntry *target = (TargetEntry *)lfirst(tl);
- resdom = target->resdom;
- resno = resdom->resno;
- reskey = resdom->reskey;
- reskeyop = resdom->reskeyop;
-
- if (reskey > 0) {
- ScanKeyEntryInitialize(&sortkeys[reskey-1],
- 0,
- resno,
- (RegProcedure) DatumGetInt32(reskeyop),
- (Datum) 0);
+ ScanKey sortkeys;
+ List *targetList;
+ List *tl;
+ int keycount;
+ Resdom *resdom;
+ AttrNumber resno;
+ Index reskey;
+ Oid reskeyop;
+
+ /* ----------------
+ * get information from the node
+ * ----------------
+ */
+ targetList = sortnode->plan.targetlist;
+ keycount = sortnode->keycount;
+
+ /* ----------------
+ * first allocate space for scan keys
+ * ----------------
+ */
+ if (keycount <= 0)
+ elog(WARN, "FormSortKeys: keycount <= 0");
+ sortkeys = (ScanKey) palloc(keycount * sizeof(ScanKeyData));
+
+ /* ----------------
+ * form each scan key from the resdom info in the target list
+ * ----------------
+ */
+ foreach(tl, targetList)
+ {
+ TargetEntry *target = (TargetEntry *) lfirst(tl);
+
+ resdom = target->resdom;
+ resno = resdom->resno;
+ reskey = resdom->reskey;
+ reskeyop = resdom->reskeyop;
+
+ if (reskey > 0)
+ {
+ ScanKeyEntryInitialize(&sortkeys[reskey - 1],
+ 0,
+ resno,
+ (RegProcedure) DatumGetInt32(reskeyop),
+ (Datum) 0);
+ }
}
- }
-
- return sortkeys;
+
+ return sortkeys;
}
/* ----------------------------------------------------------------
- * ExecSort
+ * ExecSort
*
* old comments
- * Sorts tuples from the outer subtree of the node in psort,
- * which saves the results in a temporary file or memory. After the
- * initial call, returns a tuple from the file with each call.
- * Assumes that heap access method is used.
- *
- * Conditions:
- * -- none.
- *
- * Initial States:
- * -- the outer child is prepared to return the first tuple.
+ * Sorts tuples from the outer subtree of the node in psort,
+ * which saves the results in a temporary file or memory. After the
+ * initial call, returns a tuple from the file with each call.
+ * Assumes that heap access method is used.
+ *
+ * Conditions:
+ * -- none.
+ *
+ * Initial States:
+ * -- the outer child is prepared to return the first tuple.
* ----------------------------------------------------------------
*/
TupleTableSlot *
-ExecSort(Sort *node)
+ExecSort(Sort * node)
{
- EState *estate;
- SortState *sortstate;
- Plan *outerNode;
- ScanDirection dir;
- int keycount;
- ScanKey sortkeys;
- HeapTuple heapTuple;
- TupleTableSlot *slot;
-
- /* ----------------
- * get state info from node
- * ----------------
- */
- SO1_printf("ExecSort: %s\n",
- "entering routine");
-
- sortstate = node->sortstate;
- estate = node->plan.state;
- dir = estate->es_direction;
-
- /* ----------------
- * the first time we call this, psort sorts this into a file.
- * Subsequent calls return tuples from psort.
- * ----------------
- */
-
- if (sortstate->sort_Flag == false) {
- SO1_printf("ExecSort: %s\n",
- "sortstate == false -> sorting subplan");
+ EState *estate;
+ SortState *sortstate;
+ Plan *outerNode;
+ ScanDirection dir;
+ int keycount;
+ ScanKey sortkeys;
+ HeapTuple heapTuple;
+ TupleTableSlot *slot;
+
/* ----------------
- * set all relations to be scanned in the forward direction
- * while creating the temporary relation.
+ * get state info from node
* ----------------
*/
- estate->es_direction = ForwardScanDirection;
+ SO1_printf("ExecSort: %s\n",
+ "entering routine");
+
+ sortstate = node->sortstate;
+ estate = node->plan.state;
+ dir = estate->es_direction;
/* ----------------
- * prepare information for psort_begin()
+ * the first time we call this, psort sorts this into a file.
+ * Subsequent calls return tuples from psort.
* ----------------
*/
- outerNode = outerPlan((Plan *) node);
- keycount = node->keycount;
- sortkeys = (ScanKey)sortstate->sort_Keys;
- SO1_printf("ExecSort: %s\n",
- "calling psort_begin");
-
- if (!psort_begin(node, /* this node */
- keycount, /* number keys */
- sortkeys)) /* keys */
+ if (sortstate->sort_Flag == false)
{
- /* Psort says, there are no tuples to be sorted */
- return NULL;
- }
-
- /* ----------------
- * restore to user specified direction
- * ----------------
- */
- estate->es_direction = dir;
-
- /* ----------------
- * make sure the tuple descriptor is up to date
- * ----------------
- */
- slot = (TupleTableSlot*)sortstate->csstate.cstate.cs_ResultTupleSlot;
- /* *** get_cs_ResultTupleSlot((CommonState) sortstate); */
+ SO1_printf("ExecSort: %s\n",
+ "sortstate == false -> sorting subplan");
+ /* ----------------
+ * set all relations to be scanned in the forward direction
+ * while creating the temporary relation.
+ * ----------------
+ */
+ estate->es_direction = ForwardScanDirection;
+
+ /* ----------------
+ * prepare information for psort_begin()
+ * ----------------
+ */
+ outerNode = outerPlan((Plan *) node);
+
+ keycount = node->keycount;
+ sortkeys = (ScanKey) sortstate->sort_Keys;
+ SO1_printf("ExecSort: %s\n",
+ "calling psort_begin");
+
+ if (!psort_begin(node, /* this node */
+ keycount, /* number keys */
+ sortkeys)) /* keys */
+ {
+ /* Psort says, there are no tuples to be sorted */
+ return NULL;
+ }
+
+ /* ----------------
+ * restore to user specified direction
+ * ----------------
+ */
+ estate->es_direction = dir;
- slot->ttc_tupleDescriptor = ExecGetTupType(outerNode);
+ /* ----------------
+ * make sure the tuple descriptor is up to date
+ * ----------------
+ */
+ slot = (TupleTableSlot *) sortstate->csstate.cstate.cs_ResultTupleSlot;
+ /* *** get_cs_ResultTupleSlot((CommonState) sortstate); */
+
+ slot->ttc_tupleDescriptor = ExecGetTupType(outerNode);
#if 0
- slot->ttc_execTupDescriptor = ExecGetExecTupDesc(outerNode);
+ slot->ttc_execTupDescriptor = ExecGetExecTupDesc(outerNode);
#endif
+ /* ----------------
+ * finally set the sorted flag to true
+ * ----------------
+ */
+ sortstate->sort_Flag = true;
+ SO1_printf(stderr, "ExecSort: sorting done.\n");
+ }
+ else
+ {
+ slot = (TupleTableSlot *) sortstate->csstate.cstate.cs_ResultTupleSlot;
+ /* *** get_cs_ResultTupleSlot((CommonState) sortstate); */
+/* slot = sortstate->csstate.css_ScanTupleSlot; orig */
+ }
+
+ SO1_printf("ExecSort: %s\n",
+ "retrieving tuple from sorted relation");
+
/* ----------------
- * finally set the sorted flag to true
+ * at this point we grab a tuple from psort
* ----------------
*/
- sortstate->sort_Flag = true;
- SO1_printf(stderr, "ExecSort: sorting done.\n");
- }
- else {
- slot = (TupleTableSlot*)sortstate->csstate.cstate.cs_ResultTupleSlot;
- /* *** get_cs_ResultTupleSlot((CommonState) sortstate); */
-/* slot = sortstate->csstate.css_ScanTupleSlot; orig */
- }
-
- SO1_printf("ExecSort: %s\n",
- "retrieving tuple from sorted relation");
-
- /* ----------------
- * at this point we grab a tuple from psort
- * ----------------
- */
- heapTuple = psort_grabtuple(node);
-
- if (heapTuple == NULL) {
-/* psort_end(node); */
- return (ExecClearTuple(slot));
- }
-
- ExecStoreTuple(heapTuple, /* tuple to store */
- slot, /* slot to store in */
- InvalidBuffer, /* no buffer */
- true); /* free the palloc'd tuple */
-/* printf("ExecSort: (%x)",node);print_slot(slot);printf("\n");*/
- return slot;
+ heapTuple = psort_grabtuple(node);
+
+ if (heapTuple == NULL)
+ {
+/* psort_end(node); */
+ return (ExecClearTuple(slot));
+ }
+
+ ExecStoreTuple(heapTuple, /* tuple to store */
+ slot, /* slot to store in */
+ InvalidBuffer, /* no buffer */
+ true); /* free the palloc'd tuple */
+/* printf("ExecSort: (%x)",node);print_slot(slot);printf("\n");*/
+ return slot;
#if 0
- return ExecStoreTuple(heapTuple, /* tuple to store */
- slot, /* slot to store in */
- InvalidBuffer, /* no buffer */
- true); /* free the palloc'd tuple */
+ return ExecStoreTuple(heapTuple, /* tuple to store */
+ slot, /* slot to store in */
+ InvalidBuffer, /* no buffer */
+ true);/* free the palloc'd tuple */
#endif
}
/* ----------------------------------------------------------------
- * ExecInitSort
+ * ExecInitSort
*
* old comments
- * Creates the run-time state information for the sort node
- * produced by the planner and initailizes its outer subtree.
+ * Creates the run-time state information for the sort node
+ * produced by the planner and initailizes its outer subtree.
* ----------------------------------------------------------------
*/
bool
-ExecInitSort(Sort *node, EState *estate, Plan *parent)
+ExecInitSort(Sort * node, EState * estate, Plan * parent)
{
- SortState *sortstate;
- Plan *outerPlan;
- ScanKey sortkeys;
-
- SO1_printf("ExecInitSort: %s\n",
- "initializing sort node");
-
- /* ----------------
- * assign the node's execution state
- * ----------------
- */
- node->plan.state = estate;
-
- /* ----------------
- * create state structure
- * ----------------
- */
- sortstate = makeNode(SortState);
- sortstate->sort_Flag = 0;
- sortstate->sort_Keys = NULL;
- node->cleaned = FALSE;
-
- node->sortstate = sortstate;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks
- *
- * Sort nodes don't initialize their ExprContexts because
- * they never call ExecQual or ExecTargetList.
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &sortstate->csstate.cstate, parent);
-
+ SortState *sortstate;
+ Plan *outerPlan;
+ ScanKey sortkeys;
+
+ SO1_printf("ExecInitSort: %s\n",
+ "initializing sort node");
+
+ /* ----------------
+ * assign the node's execution state
+ * ----------------
+ */
+ node->plan.state = estate;
+
+ /* ----------------
+ * create state structure
+ * ----------------
+ */
+ sortstate = makeNode(SortState);
+ sortstate->sort_Flag = 0;
+ sortstate->sort_Keys = NULL;
+ node->cleaned = FALSE;
+
+ node->sortstate = sortstate;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks
+ *
+ * Sort nodes don't initialize their ExprContexts because
+ * they never call ExecQual or ExecTargetList.
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &sortstate->csstate.cstate, parent);
+
#define SORT_NSLOTS 1
- /* ----------------
- * tuple table initialization
- *
- * sort nodes only return scan tuples from their sorted
- * relation.
- * ----------------
- */
- ExecInitResultTupleSlot(estate, &sortstate->csstate.cstate);
- ExecInitScanTupleSlot(estate, &sortstate->csstate);
-
- /* ----------------
- * initializes child nodes
- * ----------------
- */
- outerPlan = outerPlan((Plan *) node);
- ExecInitNode(outerPlan, estate, (Plan *) node);
-
- /* ----------------
- * initialize sortstate information
- * ----------------
- */
- sortkeys = FormSortKeys(node);
- sortstate->sort_Keys = sortkeys;
- sortstate->sort_Flag = false;
-
- /* ----------------
- * initialize tuple type. no need to initialize projection
- * info because this node doesn't do projections.
- * ----------------
- */
- ExecAssignResultTypeFromOuterPlan((Plan *)node, &sortstate->csstate.cstate);
- ExecAssignScanTypeFromOuterPlan((Plan *) node, &sortstate->csstate);
- sortstate->csstate.cstate.cs_ProjInfo = NULL;
-
- SO1_printf("ExecInitSort: %s\n",
- "sort node initialized");
-
- /* ----------------
- * return relation oid of temporary sort relation in a list
- * (someday -- for now we return LispTrue... cim 10/12/89)
- * ----------------
- */
- return TRUE;
+ /* ----------------
+ * tuple table initialization
+ *
+ * sort nodes only return scan tuples from their sorted
+ * relation.
+ * ----------------
+ */
+ ExecInitResultTupleSlot(estate, &sortstate->csstate.cstate);
+ ExecInitScanTupleSlot(estate, &sortstate->csstate);
+
+ /* ----------------
+ * initializes child nodes
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+ ExecInitNode(outerPlan, estate, (Plan *) node);
+
+ /* ----------------
+ * initialize sortstate information
+ * ----------------
+ */
+ sortkeys = FormSortKeys(node);
+ sortstate->sort_Keys = sortkeys;
+ sortstate->sort_Flag = false;
+
+ /* ----------------
+ * initialize tuple type. no need to initialize projection
+ * info because this node doesn't do projections.
+ * ----------------
+ */
+ ExecAssignResultTypeFromOuterPlan((Plan *) node, &sortstate->csstate.cstate);
+ ExecAssignScanTypeFromOuterPlan((Plan *) node, &sortstate->csstate);
+ sortstate->csstate.cstate.cs_ProjInfo = NULL;
+
+ SO1_printf("ExecInitSort: %s\n",
+ "sort node initialized");
+
+ /* ----------------
+ * return relation oid of temporary sort relation in a list
+ * (someday -- for now we return LispTrue... cim 10/12/89)
+ * ----------------
+ */
+ return TRUE;
}
int
-ExecCountSlotsSort(Sort *node)
+ExecCountSlotsSort(Sort * node)
{
- return ExecCountSlotsNode(outerPlan((Plan *)node)) +
- ExecCountSlotsNode(innerPlan((Plan *)node)) +
- SORT_NSLOTS;
+ return ExecCountSlotsNode(outerPlan((Plan *) node)) +
+ ExecCountSlotsNode(innerPlan((Plan *) node)) +
+ SORT_NSLOTS;
}
/* ----------------------------------------------------------------
- * ExecEndSort(node)
+ * ExecEndSort(node)
*
* old comments
* ----------------------------------------------------------------
*/
void
-ExecEndSort(Sort *node)
+ExecEndSort(Sort * node)
{
- SortState *sortstate;
- Plan *outerPlan;
-
- /* ----------------
- * get info from the sort state
- * ----------------
- */
- SO1_printf("ExecEndSort: %s\n",
- "shutting down sort node");
-
- sortstate = node->sortstate;
-
- /* ----------------
- * shut down the subplan
- * ----------------
- */
- outerPlan = outerPlan((Plan *) node);
- ExecEndNode(outerPlan, (Plan*)node);
-
- /* ----------------
- * clean out the tuple table
- * ----------------
- */
- ExecClearTuple(sortstate->csstate.css_ScanTupleSlot);
-
- /* Clean up after psort */
- psort_end(node);
-
- SO1_printf("ExecEndSort: %s\n",
- "sort node shutdown");
-}
+ SortState *sortstate;
+ Plan *outerPlan;
+
+ /* ----------------
+ * get info from the sort state
+ * ----------------
+ */
+ SO1_printf("ExecEndSort: %s\n",
+ "shutting down sort node");
+
+ sortstate = node->sortstate;
+
+ /* ----------------
+ * shut down the subplan
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+ ExecEndNode(outerPlan, (Plan *) node);
+
+ /* ----------------
+ * clean out the tuple table
+ * ----------------
+ */
+ ExecClearTuple(sortstate->csstate.css_ScanTupleSlot);
+
+ /* Clean up after psort */
+ psort_end(node);
+
+ SO1_printf("ExecEndSort: %s\n",
+ "sort node shutdown");
+}
/* ----------------------------------------------------------------
- * ExecSortMarkPos
+ * ExecSortMarkPos
*
- * Calls psort to save the current position in the sorted file.
+ * Calls psort to save the current position in the sorted file.
* ----------------------------------------------------------------
*/
void
-ExecSortMarkPos(Sort *node)
+ExecSortMarkPos(Sort * node)
{
- SortState *sortstate;
-
- /* ----------------
- * if we haven't sorted yet, just return
- * ----------------
- */
- sortstate = node->sortstate;
- if (sortstate->sort_Flag == false)
- return;
-
- psort_markpos(node);
-
- return;
+ SortState *sortstate;
+
+ /* ----------------
+ * if we haven't sorted yet, just return
+ * ----------------
+ */
+ sortstate = node->sortstate;
+ if (sortstate->sort_Flag == false)
+ return;
+
+ psort_markpos(node);
+
+ return;
}
/* ----------------------------------------------------------------
- * ExecSortRestrPos
+ * ExecSortRestrPos
*
- * Calls psort to restore the last saved sort file position.
+ * Calls psort to restore the last saved sort file position.
* ----------------------------------------------------------------
*/
void
-ExecSortRestrPos(Sort *node)
+ExecSortRestrPos(Sort * node)
{
- SortState *sortstate;
-
- /* ----------------
- * if we haven't sorted yet, just return.
- * ----------------
- */
- sortstate = node->sortstate;
- if (sortstate->sort_Flag == false)
- return;
-
- /* ----------------
- * restore the scan to the previously marked position
- * ----------------
- */
- psort_restorepos(node);
+ SortState *sortstate;
+
+ /* ----------------
+ * if we haven't sorted yet, just return.
+ * ----------------
+ */
+ sortstate = node->sortstate;
+ if (sortstate->sort_Flag == false)
+ return;
+
+ /* ----------------
+ * restore the scan to the previously marked position
+ * ----------------
+ */
+ psort_restorepos(node);
}
diff --git a/src/backend/executor/nodeTee.c b/src/backend/executor/nodeTee.c
index 6ddbecc3a49..8a1e233125a 100644
--- a/src/backend/executor/nodeTee.c
+++ b/src/backend/executor/nodeTee.c
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nodeTee.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
- * DESCRIPTION
- * This code provides support for a tee node, which allows multiple
- * parent in a megaplan.
- *
- * INTERFACE ROUTINES
- * ExecTee
- * ExecInitTee
- * ExecEndTee
+ * DESCRIPTION
+ * This code provides support for a tee node, which allows multiple
+ * parent in a megaplan.
+ *
+ * INTERFACE ROUTINES
+ * ExecTee
+ * ExecInitTee
+ * ExecEndTee
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/Attic/nodeTee.c,v 1.6 1997/07/28 00:54:11 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/Attic/nodeTee.c,v 1.7 1997/09/07 04:41:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,9 +25,9 @@
#include "postgres.h"
#include "utils/palloc.h"
-#include "utils/relcache.h"
+#include "utils/relcache.h"
#include "utils/mcxt.h"
-#include "storage/bufmgr.h" /* for IncrBufferRefCount */
+#include "storage/bufmgr.h" /* for IncrBufferRefCount */
#include "storage/smgr.h"
#include "optimizer/internal.h"
#include "executor/executor.h"
@@ -38,475 +38,520 @@
#include "access/heapam.h"
/* ------------------------------------------------------------------
- * ExecInitTee
+ * ExecInitTee
*
- * Create tee state
+ * Create tee state
*
* ------------------------------------------------------------------
*/
bool
-ExecInitTee(Tee* node, EState *currentEstate, Plan * parent)
+ExecInitTee(Tee * node, EState * currentEstate, Plan * parent)
{
- TeeState *teeState;
- Plan *outerPlan;
- int len;
- Relation bufferRel;
- TupleDesc tupType;
- EState *estate;
-
- /* it is possible that the Tee has already been initialized
- since it can be reached by multiple parents.
- If it is already initialized, simply return and do
- not initialize the children nodes again
- */
- if (node->plan.state)
- return TRUE;
-
- /* ----------------
- * assign the node's execution state
- * ----------------
- */
- /* make a new executor state, because we have a different
- es_range_table */
-
-/* node->plan.state = estate;*/
-
- estate = CreateExecutorState();
- estate->es_direction = currentEstate->es_direction;
- estate->es_BaseId = currentEstate->es_BaseId;
- estate->es_BaseId = currentEstate->es_BaseId;
- estate->es_tupleTable = currentEstate->es_tupleTable;
- estate->es_refcount = currentEstate->es_refcount;
- estate->es_junkFilter = currentEstate->es_junkFilter;
-
- /* use the range table for Tee subplan since the range tables
- for the two parents may be different */
- if (node->rtentries)
- estate->es_range_table = node->rtentries;
- else
- estate->es_range_table = currentEstate->es_range_table;
-
- node->plan.state = estate;
-
-
- /* ----------------
- * create teeState structure
- * ----------------
- */
- teeState = makeNode(TeeState);
- teeState->tee_leftPlace = 0;
- teeState->tee_rightPlace = 0;
- teeState->tee_lastPlace = 0;
- teeState->tee_bufferRel = NULL;
- teeState->tee_leftScanDesc = NULL;
- teeState->tee_rightScanDesc = NULL;
-
-
- node->teestate = teeState;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks and
- * + create expression context for node
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &(teeState->cstate), parent);
- ExecAssignExprContext(estate, &(teeState->cstate));
+ TeeState *teeState;
+ Plan *outerPlan;
+ int len;
+ Relation bufferRel;
+ TupleDesc tupType;
+ EState *estate;
+
+ /*
+ * it is possible that the Tee has already been initialized since it
+ * can be reached by multiple parents. If it is already initialized,
+ * simply return and do not initialize the children nodes again
+ */
+ if (node->plan.state)
+ return TRUE;
+
+ /* ----------------
+ * assign the node's execution state
+ * ----------------
+ */
+
+ /*
+ * make a new executor state, because we have a different
+ * es_range_table
+ */
+
+/* node->plan.state = estate;*/
+
+ estate = CreateExecutorState();
+ estate->es_direction = currentEstate->es_direction;
+ estate->es_BaseId = currentEstate->es_BaseId;
+ estate->es_BaseId = currentEstate->es_BaseId;
+ estate->es_tupleTable = currentEstate->es_tupleTable;
+ estate->es_refcount = currentEstate->es_refcount;
+ estate->es_junkFilter = currentEstate->es_junkFilter;
+
+ /*
+ * use the range table for Tee subplan since the range tables for the
+ * two parents may be different
+ */
+ if (node->rtentries)
+ estate->es_range_table = node->rtentries;
+ else
+ estate->es_range_table = currentEstate->es_range_table;
+
+ node->plan.state = estate;
+
+
+ /* ----------------
+ * create teeState structure
+ * ----------------
+ */
+ teeState = makeNode(TeeState);
+ teeState->tee_leftPlace = 0;
+ teeState->tee_rightPlace = 0;
+ teeState->tee_lastPlace = 0;
+ teeState->tee_bufferRel = NULL;
+ teeState->tee_leftScanDesc = NULL;
+ teeState->tee_rightScanDesc = NULL;
+
+
+ node->teestate = teeState;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks and
+ * + create expression context for node
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &(teeState->cstate), parent);
+ ExecAssignExprContext(estate, &(teeState->cstate));
#define TEE_NSLOTS 2
- /* ----------------
- * initialize tuple slots
- * ----------------
- */
- ExecInitResultTupleSlot(estate, &(teeState->cstate));
-
- /* initialize child nodes */
- outerPlan = outerPlan((Plan*) node);
- ExecInitNode(outerPlan, estate, (Plan*) node);
-
- /* ----------------
- * the tuple type info is from the outer plan of this node
- * the result type is also the same as the outerplan
- */
- ExecAssignResultTypeFromOuterPlan((Plan*) node, &(teeState->cstate));
- ExecAssignProjectionInfo((Plan*)node, &teeState->cstate);
-
- /* ---------------------------------------
- initialize temporary relation to buffer tuples
- */
- tupType = ExecGetResultType(&(teeState->cstate));
- len = ExecTargetListLength(((Plan*)node)->targetlist);
-
-/* bufferRel = ExecCreatR(len, tupType, _TEMP_RELATION_ID_); */
-
- /* create a catalogued relation even though this is a temporary relation */
- /* cleanup of catalogued relations is easier to do */
-
- if (node->teeTableName[0] != '\0') {
- Relation r;
-
- teeState->tee_bufferRelname = pstrdup(node->teeTableName);
-
- /* we are given an tee table name,
- if a relation by that name exists, then we open it,
- else we create it and then open it */
- r = RelationNameGetRelation(teeState->tee_bufferRelname);
-
- if (RelationIsValid(r))
- bufferRel = heap_openr(teeState->tee_bufferRelname);
+ /* ----------------
+ * initialize tuple slots
+ * ----------------
+ */
+ ExecInitResultTupleSlot(estate, &(teeState->cstate));
+
+ /* initialize child nodes */
+ outerPlan = outerPlan((Plan *) node);
+ ExecInitNode(outerPlan, estate, (Plan *) node);
+
+ /* ----------------
+ * the tuple type info is from the outer plan of this node
+ * the result type is also the same as the outerplan
+ */
+ ExecAssignResultTypeFromOuterPlan((Plan *) node, &(teeState->cstate));
+ ExecAssignProjectionInfo((Plan *) node, &teeState->cstate);
+
+ /* ---------------------------------------
+ initialize temporary relation to buffer tuples
+ */
+ tupType = ExecGetResultType(&(teeState->cstate));
+ len = ExecTargetListLength(((Plan *) node)->targetlist);
+
+/* bufferRel = ExecCreatR(len, tupType, _TEMP_RELATION_ID_); */
+
+ /*
+ * create a catalogued relation even though this is a temporary
+ * relation
+ */
+ /* cleanup of catalogued relations is easier to do */
+
+ if (node->teeTableName[0] != '\0')
+ {
+ Relation r;
+
+ teeState->tee_bufferRelname = pstrdup(node->teeTableName);
+
+ /*
+ * we are given an tee table name, if a relation by that name
+ * exists, then we open it, else we create it and then open it
+ */
+ r = RelationNameGetRelation(teeState->tee_bufferRelname);
+
+ if (RelationIsValid(r))
+ bufferRel = heap_openr(teeState->tee_bufferRelname);
+ else
+ bufferRel = heap_open(heap_create(teeState->tee_bufferRelname,
+ /*FIX */ NULL,
+ 'n',
+ DEFAULT_SMGR,
+ tupType));
+ }
else
- bufferRel = heap_open(heap_create(teeState->tee_bufferRelname,
-/*FIX */ NULL,
- 'n',
- DEFAULT_SMGR,
- tupType));
- }
- else {
- sprintf(teeState->tee_bufferRelname,
- "ttemp_%d", /* 'ttemp' for 'tee' temporary*/
- newoid());
-/* bufferRel = ExecCreatR(len, tupType, _TEMP_RELATION_ID); */
- bufferRel = heap_open(heap_create(teeState->tee_bufferRelname,
- NULL, /*XXX */
- 'n',
- DEFAULT_SMGR,
- tupType));
- }
-
- teeState->tee_bufferRel = bufferRel;
-
- /*initialize a memory context for allocating thing like scan descriptors */
- /* we do this so that on cleanup of the tee, we can free things.
- if we didn't have our own memory context, we would be in the memory
- context of the portal that we happen to be using at the moment */
-
- teeState->tee_mcxt = (MemoryContext)CreateGlobalMemory(teeState->tee_bufferRelname);
-
- /* don't initialize the scan descriptors here
- because it's not good to initialize scan descriptors on empty
- rels. Wait until the scan descriptors are needed
- before initializing them. */
-
- teeState->tee_leftScanDesc = NULL;
- teeState->tee_rightScanDesc = NULL;
-
- return TRUE;
+ {
+ sprintf(teeState->tee_bufferRelname,
+ "ttemp_%d", /* 'ttemp' for 'tee' temporary */
+ newoid());
+/* bufferRel = ExecCreatR(len, tupType, _TEMP_RELATION_ID); */
+ bufferRel = heap_open(heap_create(teeState->tee_bufferRelname,
+ NULL, /* XXX */
+ 'n',
+ DEFAULT_SMGR,
+ tupType));
+ }
+
+ teeState->tee_bufferRel = bufferRel;
+
+ /*
+ * initialize a memory context for allocating thing like scan
+ * descriptors
+ */
+
+ /*
+ * we do this so that on cleanup of the tee, we can free things. if we
+ * didn't have our own memory context, we would be in the memory
+ * context of the portal that we happen to be using at the moment
+ */
+
+ teeState->tee_mcxt = (MemoryContext) CreateGlobalMemory(teeState->tee_bufferRelname);
+
+ /*
+ * don't initialize the scan descriptors here because it's not good to
+ * initialize scan descriptors on empty rels. Wait until the scan
+ * descriptors are needed before initializing them.
+ */
+
+ teeState->tee_leftScanDesc = NULL;
+ teeState->tee_rightScanDesc = NULL;
+
+ return TRUE;
}
-int
-ExecCountSlotsTee(Tee *node)
+int
+ExecCountSlotsTee(Tee * node)
{
- /* Tee nodes can't have innerPlans */
- return ExecCountSlotsNode(outerPlan(node)) + TEE_NSLOTS;
+ /* Tee nodes can't have innerPlans */
+ return ExecCountSlotsNode(outerPlan(node)) + TEE_NSLOTS;
}
/* ----------------------------------------------------------------
initTeeScanDescs
- initializes the left and right scandescs on the temporary
- relation of a Tee node
+ initializes the left and right scandescs on the temporary
+ relation of a Tee node
- must open two separate scan descriptors,
- because the left and right scans may be at different points
+ must open two separate scan descriptors,
+ because the left and right scans may be at different points
* ----------------------------------------------------------------
*/
-static void
-initTeeScanDescs(Tee* node)
+static void
+initTeeScanDescs(Tee * node)
{
- TeeState *teeState;
- Relation bufferRel;
- ScanDirection dir;
- MemoryContext orig;
-
- teeState = node->teestate;
- if (teeState->tee_leftScanDesc && teeState->tee_rightScanDesc)
- return;
-
- orig = CurrentMemoryContext;
- MemoryContextSwitchTo(teeState->tee_mcxt);
-
- bufferRel = teeState->tee_bufferRel;
- dir = ((Plan*)node)->state->es_direction; /* backwards not handled yet XXX */
-
- if (teeState->tee_leftScanDesc == NULL)
- {
- teeState->tee_leftScanDesc = heap_beginscan(bufferRel,
- ScanDirectionIsBackward(dir),
- NowTimeQual, /* time qual */
- 0, /* num scan keys */
- NULL /* scan keys */
- );
- }
- if (teeState->tee_rightScanDesc == NULL)
- {
- teeState->tee_rightScanDesc = heap_beginscan(bufferRel,
- ScanDirectionIsBackward(dir),
- NowTimeQual, /* time qual */
- 0, /* num scan keys */
- NULL /* scan keys */
- );
- }
-
- MemoryContextSwitchTo(orig);
+ TeeState *teeState;
+ Relation bufferRel;
+ ScanDirection dir;
+ MemoryContext orig;
+
+ teeState = node->teestate;
+ if (teeState->tee_leftScanDesc && teeState->tee_rightScanDesc)
+ return;
+
+ orig = CurrentMemoryContext;
+ MemoryContextSwitchTo(teeState->tee_mcxt);
+
+ bufferRel = teeState->tee_bufferRel;
+ dir = ((Plan *) node)->state->es_direction; /* backwards not handled
+ * yet XXX */
+
+ if (teeState->tee_leftScanDesc == NULL)
+ {
+ teeState->tee_leftScanDesc = heap_beginscan(bufferRel,
+ ScanDirectionIsBackward(dir),
+ NowTimeQual, /* time qual */
+ 0, /* num scan keys */
+ NULL /* scan keys */
+ );
+ }
+ if (teeState->tee_rightScanDesc == NULL)
+ {
+ teeState->tee_rightScanDesc = heap_beginscan(bufferRel,
+ ScanDirectionIsBackward(dir),
+ NowTimeQual, /* time qual */
+ 0, /* num scan keys */
+ NULL /* scan keys */
+ );
+ }
+
+ MemoryContextSwitchTo(orig);
}
/* ----------------------------------------------------------------
- * ExecTee(node)
+ * ExecTee(node)
+ *
*
+ * A Tee serves to connect a subplan to multiple parents.
+ * the subplan is always the outplan of the Tee node.
*
- * A Tee serves to connect a subplan to multiple parents.
- * the subplan is always the outplan of the Tee node.
- *
- * The Tee gets requests from either leftParent or rightParent,
- * fetches the result tuple from the child, and then
- * stored the result into a temporary relation (serving as a queue).
- * leftPlace and rightPlace keep track of where the left and rightParents
- * are.
- * If a parent requests a tuple and that parent is not at the end
- * of the temporary relation, then the request is satisfied from
- * the queue instead of by executing the child plan
+ * The Tee gets requests from either leftParent or rightParent,
+ * fetches the result tuple from the child, and then
+ * stored the result into a temporary relation (serving as a queue).
+ * leftPlace and rightPlace keep track of where the left and rightParents
+ * are.
+ * If a parent requests a tuple and that parent is not at the end
+ * of the temporary relation, then the request is satisfied from
+ * the queue instead of by executing the child plan
*
* ----------------------------------------------------------------
*/
-TupleTableSlot*
-ExecTee(Tee *node, Plan *parent)
+TupleTableSlot *
+ExecTee(Tee * node, Plan * parent)
{
- EState *estate;
- TeeState *teeState;
- int leftPlace, rightPlace, lastPlace;
- int branch;
- TupleTableSlot* result;
- TupleTableSlot* slot;
- Plan *childNode;
- ScanDirection dir;
- HeapTuple heapTuple;
- Relation bufferRel;
- HeapScanDesc scanDesc;
- Buffer buffer;
-
- estate = ((Plan*)node)->state;
- teeState = node->teestate;
- leftPlace = teeState->tee_leftPlace;
- rightPlace = teeState->tee_rightPlace;
- lastPlace = teeState->tee_lastPlace;
- bufferRel = teeState->tee_bufferRel;
-
- childNode = outerPlan(node);
-
- dir = estate->es_direction;
-
- /* XXX doesn't handle backwards direction yet */
-
- if (parent == node->leftParent) {
- branch = leftPlace;
- }
- else
- if ( (parent == node->rightParent) || (parent == (Plan*) node))
- /* the tee node could be the root node of the plan,
- in which case, we treat it like a right-parent pull*/
+ EState *estate;
+ TeeState *teeState;
+ int leftPlace,
+ rightPlace,
+ lastPlace;
+ int branch;
+ TupleTableSlot *result;
+ TupleTableSlot *slot;
+ Plan *childNode;
+ ScanDirection dir;
+ HeapTuple heapTuple;
+ Relation bufferRel;
+ HeapScanDesc scanDesc;
+ Buffer buffer;
+
+ estate = ((Plan *) node)->state;
+ teeState = node->teestate;
+ leftPlace = teeState->tee_leftPlace;
+ rightPlace = teeState->tee_rightPlace;
+ lastPlace = teeState->tee_lastPlace;
+ bufferRel = teeState->tee_bufferRel;
+
+ childNode = outerPlan(node);
+
+ dir = estate->es_direction;
+
+ /* XXX doesn't handle backwards direction yet */
+
+ if (parent == node->leftParent)
+ {
+ branch = leftPlace;
+ }
+ else if ((parent == node->rightParent) || (parent == (Plan *) node))
+
+ /*
+ * the tee node could be the root node of the plan, in which case,
+ * we treat it like a right-parent pull
+ */
+ {
+ branch = rightPlace;
+ }
+ else
+ {
+ elog(WARN, "A Tee node can only be executed from its left or right parent\n");
+ return NULL;
+ }
+
+ if (branch == lastPlace)
+ { /* we're at the end of the queue already,
+ * - get a new tuple from the child plan,
+ * - store it in the queue, - increment
+ * lastPlace, - increment leftPlace or
+ * rightPlace as appropriate, - and return
+ * result */
+ slot = ExecProcNode(childNode, (Plan *) node);
+ if (!TupIsNull(slot))
+ {
+ heapTuple = slot->val;
+
+ /* insert into temporary relation */
+ heap_insert(bufferRel, heapTuple);
+
+ /*
+ * once there is data in the temporary relation, ensure that
+ * the left and right scandescs are initialized
+ */
+ initTeeScanDescs(node);
+
+ scanDesc = (parent == node->leftParent) ?
+ teeState->tee_leftScanDesc : teeState->tee_rightScanDesc;
+
+ {
+
+ /*
+ * move the scandesc forward so we don't re-read this
+ * tuple later
+ */
+ HeapTuple throwAway;
+
+ /* Buffer buffer; */
+ throwAway = heap_getnext(scanDesc,
+ ScanDirectionIsBackward(dir),
+ /* &buffer */
+ (Buffer *) NULL);
+ }
+
+ /*
+ * set the shouldFree field of the child's slot so that when
+ * the child's slot is free'd, this tuple isn't free'd also
+ */
+
+ /*
+ * does this mean this tuple has to be garbage collected
+ * later??
+ */
+ slot->ttc_shouldFree = false;
+
+ teeState->tee_lastPlace = lastPlace + 1;
+ }
+ result = slot;
+ }
+ else
+ { /* the desired data already exists in the
+ * temporary relation */
+ scanDesc = (parent == node->leftParent) ?
+ teeState->tee_leftScanDesc : teeState->tee_rightScanDesc;
+
+ heapTuple = heap_getnext(scanDesc,
+ ScanDirectionIsBackward(dir),
+ &buffer);
+
+ /*
+ * Increase the pin count on the buffer page, because the tuple
+ * stored in the slot also points to it (as well as the scan
+ * descriptor). If we don't, ExecStoreTuple will decrease the pin
+ * count on the next iteration.
+ */
+
+ if (buffer != InvalidBuffer)
+ IncrBufferRefCount(buffer);
+
+ slot = teeState->cstate.cs_ResultTupleSlot;
+ slot->ttc_tupleDescriptor = RelationGetTupleDescriptor(bufferRel);
+
+ result = ExecStoreTuple(heapTuple, /* tuple to store */
+ slot, /* slot to store in */
+ buffer, /* this tuple's buffer */
+ false); /* don't free stuff from
+ * heap_getnext */
+
+ }
+
+ if (parent == node->leftParent)
{
- branch = rightPlace;
- }
- else
- {
- elog(WARN,"A Tee node can only be executed from its left or right parent\n");
- return NULL;
- }
-
- if (branch == lastPlace)
- { /* we're at the end of the queue already,
- - get a new tuple from the child plan,
- - store it in the queue,
- - increment lastPlace,
- - increment leftPlace or rightPlace as appropriate,
- - and return result
- */
- slot = ExecProcNode(childNode, (Plan*)node);
- if (!TupIsNull(slot))
- {
- heapTuple = slot->val;
-
- /* insert into temporary relation */
- heap_insert(bufferRel, heapTuple);
-
- /* once there is data in the temporary relation,
- ensure that the left and right scandescs are initialized */
- initTeeScanDescs(node);
-
- scanDesc = (parent == node->leftParent) ?
- teeState->tee_leftScanDesc : teeState->tee_rightScanDesc;
-
- {
- /* move the scandesc forward so we don't re-read this tuple later */
- HeapTuple throwAway;
- /* Buffer buffer;*/
- throwAway = heap_getnext(scanDesc,
- ScanDirectionIsBackward(dir),
- /* &buffer */
- (Buffer*)NULL);
- }
-
- /* set the shouldFree field of the child's slot so that
- when the child's slot is free'd, this tuple isn't free'd also */
- /* does this mean this tuple has to be garbage collected later??*/
- slot->ttc_shouldFree = false;
-
- teeState->tee_lastPlace = lastPlace + 1;
- }
- result = slot;
- }
- else
- {/* the desired data already exists in the temporary relation */
- scanDesc = (parent == node->leftParent) ?
- teeState->tee_leftScanDesc : teeState->tee_rightScanDesc;
-
- heapTuple = heap_getnext(scanDesc,
- ScanDirectionIsBackward(dir),
- &buffer);
-
- /* Increase the pin count on the buffer page, because the
- tuple stored in the slot also points to it (as well as
- the scan descriptor). If we don't, ExecStoreTuple will
- decrease the pin count on the next iteration. */
-
- if (buffer != InvalidBuffer)
- IncrBufferRefCount(buffer);
-
- slot = teeState->cstate.cs_ResultTupleSlot;
- slot->ttc_tupleDescriptor = RelationGetTupleDescriptor(bufferRel);
-
- result = ExecStoreTuple(heapTuple,/* tuple to store */
- slot, /* slot to store in */
- buffer,/* this tuple's buffer */
- false); /* don't free stuff from heap_getnext */
-
- }
-
- if (parent == node->leftParent)
- {
- teeState->tee_leftPlace = leftPlace+1;
- }
- else
- {
- teeState->tee_rightPlace = rightPlace+1;
- }
-
- return result;
+ teeState->tee_leftPlace = leftPlace + 1;
+ }
+ else
+ {
+ teeState->tee_rightPlace = rightPlace + 1;
+ }
+
+ return result;
}
/* ----------------------------------------------------------------
- * ExecTeeReScan(node)
- *
- * Rescans the relation.
+ * ExecTeeReScan(node)
+ *
+ * Rescans the relation.
* ----------------------------------------------------------------
*/
void
-ExecTeeReScan(Tee *node, ExprContext *exprCtxt, Plan *parent)
+ExecTeeReScan(Tee * node, ExprContext * exprCtxt, Plan * parent)
{
- EState *estate;
- TeeState *teeState;
- ScanDirection dir;
+ EState *estate;
+ TeeState *teeState;
+ ScanDirection dir;
- estate = ((Plan*)node)->state;
- teeState = node->teestate;
+ estate = ((Plan *) node)->state;
+ teeState = node->teestate;
- dir = estate->es_direction;
-
- /* XXX doesn't handle backwards direction yet */
+ dir = estate->es_direction;
- if (parent == node->leftParent) {
- if (teeState->tee_leftScanDesc)
+ /* XXX doesn't handle backwards direction yet */
+
+ if (parent == node->leftParent)
+ {
+ if (teeState->tee_leftScanDesc)
+ {
+ heap_rescan(teeState->tee_leftScanDesc,
+ ScanDirectionIsBackward(dir),
+ NULL);
+ teeState->tee_leftPlace = 0;
+ }
+ }
+ else
{
- heap_rescan(teeState->tee_leftScanDesc,
- ScanDirectionIsBackward(dir),
- NULL);
- teeState->tee_leftPlace = 0;
+ if (teeState->tee_rightScanDesc)
+ {
+ heap_rescan(teeState->tee_leftScanDesc,
+ ScanDirectionIsBackward(dir),
+ NULL);
+ teeState->tee_rightPlace = 0;
+ }
}
- }
- else
- {
- if (teeState->tee_rightScanDesc)
- {
- heap_rescan(teeState->tee_leftScanDesc,
- ScanDirectionIsBackward(dir),
- NULL);
- teeState->tee_rightPlace = 0;
- }
- }
}
/* ---------------------------------------------------------------------
- * ExecEndTee
+ * ExecEndTee
*
- * End the Tee node, and free up any storage
+ * End the Tee node, and free up any storage
* since a Tee node can be downstream of multiple parent nodes,
* only free when both parents are done
* --------------------------------------------------------------------
*/
-void
-ExecEndTee(Tee* node, Plan* parent)
+void
+ExecEndTee(Tee * node, Plan * parent)
{
- EState *estate;
- TeeState *teeState;
- int leftPlace, rightPlace, lastPlace;
- Relation bufferRel;
- MemoryContext orig;
-
- estate = ((Plan*)node)->state;
- teeState = node->teestate;
- leftPlace = teeState->tee_leftPlace;
- rightPlace = teeState->tee_rightPlace;
- lastPlace = teeState->tee_lastPlace;
-
- if (!node->leftParent || parent == node->leftParent)
- leftPlace = -1;
-
- if (!node->rightParent || parent == node->rightParent)
- rightPlace = -1;
-
- if (parent == (Plan*)node)
- rightPlace = leftPlace = -1;
-
- teeState->tee_leftPlace = leftPlace;
- teeState->tee_rightPlace = rightPlace;
- if ( (leftPlace == -1) && (rightPlace == -1) )
- {
- /* remove the temporary relations */
- /* and close the scan descriptors */
-
- bufferRel = teeState->tee_bufferRel;
- if (bufferRel) {
- heap_destroyr(bufferRel);
- teeState->tee_bufferRel = NULL;
- if (teeState->tee_mcxt) {
- orig = CurrentMemoryContext;
- MemoryContextSwitchTo(teeState->tee_mcxt);
- }
- else
- orig = 0;
-
- if (teeState->tee_leftScanDesc)
- {
- heap_endscan(teeState->tee_leftScanDesc);
- teeState->tee_leftScanDesc = NULL;
- }
- if (teeState->tee_rightScanDesc)
- {
- heap_endscan(teeState->tee_rightScanDesc);
- teeState->tee_rightScanDesc = NULL;
- }
-
- if (teeState->tee_mcxt) {
- MemoryContextSwitchTo(orig);
- teeState->tee_mcxt = NULL;
- }
+ EState *estate;
+ TeeState *teeState;
+ int leftPlace,
+ rightPlace,
+ lastPlace;
+ Relation bufferRel;
+ MemoryContext orig;
+
+ estate = ((Plan *) node)->state;
+ teeState = node->teestate;
+ leftPlace = teeState->tee_leftPlace;
+ rightPlace = teeState->tee_rightPlace;
+ lastPlace = teeState->tee_lastPlace;
+
+ if (!node->leftParent || parent == node->leftParent)
+ leftPlace = -1;
+
+ if (!node->rightParent || parent == node->rightParent)
+ rightPlace = -1;
+
+ if (parent == (Plan *) node)
+ rightPlace = leftPlace = -1;
+
+ teeState->tee_leftPlace = leftPlace;
+ teeState->tee_rightPlace = rightPlace;
+ if ((leftPlace == -1) && (rightPlace == -1))
+ {
+ /* remove the temporary relations */
+ /* and close the scan descriptors */
+
+ bufferRel = teeState->tee_bufferRel;
+ if (bufferRel)
+ {
+ heap_destroyr(bufferRel);
+ teeState->tee_bufferRel = NULL;
+ if (teeState->tee_mcxt)
+ {
+ orig = CurrentMemoryContext;
+ MemoryContextSwitchTo(teeState->tee_mcxt);
+ }
+ else
+ orig = 0;
+
+ if (teeState->tee_leftScanDesc)
+ {
+ heap_endscan(teeState->tee_leftScanDesc);
+ teeState->tee_leftScanDesc = NULL;
+ }
+ if (teeState->tee_rightScanDesc)
+ {
+ heap_endscan(teeState->tee_rightScanDesc);
+ teeState->tee_rightScanDesc = NULL;
+ }
+
+ if (teeState->tee_mcxt)
+ {
+ MemoryContextSwitchTo(orig);
+ teeState->tee_mcxt = NULL;
+ }
+ }
}
- }
-
-}
+}
diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c
index 65c3bea76e0..75e40ccad96 100644
--- a/src/backend/executor/nodeUnique.c
+++ b/src/backend/executor/nodeUnique.c
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* nodeUnique.c--
- * Routines to handle unique'ing of queries where appropriate
+ * Routines to handle unique'ing of queries where appropriate
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.7 1997/08/26 23:31:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.8 1997/09/07 04:41:50 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * ExecUnique - generate a unique'd temporary relation
- * ExecInitUnique - initialize node and subnodes..
- * ExecEndUnique - shutdown node and subnodes
+ * ExecUnique - generate a unique'd temporary relation
+ * ExecInitUnique - initialize node and subnodes..
+ * ExecEndUnique - shutdown node and subnodes
*
* NOTES
- * Assumes tuples returned from subplan arrive in
- * sorted order.
+ * Assumes tuples returned from subplan arrive in
+ * sorted order.
*
*/
#include <string.h>
@@ -31,296 +31,318 @@
#include "executor/nodeUnique.h"
#include "optimizer/clauses.h"
#include "access/heapam.h"
-#include "access/printtup.h" /* for typtoout() */
-#include "utils/builtins.h" /* for namecpy()*/
+#include "access/printtup.h" /* for typtoout() */
+#include "utils/builtins.h" /* for namecpy() */
/* ----------------------------------------------------------------
- * ExecIdenticalTuples
+ * ExecIdenticalTuples
*
- * This is a hack function used by ExecUnique to see if
- * two tuples are identical. This should be provided
- * by the heap tuple code but isn't. The real problem
- * is that we assume we can byte compare tuples to determine
- * if they are "equal". In fact, if we have user defined
- * types there may be problems because it's possible that
- * an ADT may have multiple representations with the
- * same ADT value. -cim
+ * This is a hack function used by ExecUnique to see if
+ * two tuples are identical. This should be provided
+ * by the heap tuple code but isn't. The real problem
+ * is that we assume we can byte compare tuples to determine
+ * if they are "equal". In fact, if we have user defined
+ * types there may be problems because it's possible that
+ * an ADT may have multiple representations with the
+ * same ADT value. -cim
* ----------------------------------------------------------------
*/
-static bool /* true if tuples are identical, false otherwise */
-ExecIdenticalTuples(TupleTableSlot *t1, TupleTableSlot *t2)
+static bool /* true if tuples are identical, false
+ * otherwise */
+ExecIdenticalTuples(TupleTableSlot * t1, TupleTableSlot * t2)
{
- HeapTuple h1;
- HeapTuple h2;
- char *d1;
- char *d2;
- int len;
-
- h1 = t1->val;
- h2 = t2->val;
-
- /* ----------------
- * if tuples aren't the same length then they are
- * obviously different (one may have null attributes).
- * ----------------
- */
- if (h1->t_len != h2->t_len)
- return false;
-
- /* ----------------
- * if the tuples have different header offsets then
- * they are different. This will prevent us from returning
- * true when comparing tuples of one attribute where one of
- * two we're looking at is null (t_len - t_hoff == 0).
- * THE t_len FIELDS CAN BE THE SAME IN THIS CASE!!
- * ----------------
- */
- if (h1->t_hoff != h2->t_hoff)
- return false;
-
- /* ----------------
- * ok, now get the pointers to the data and the
- * size of the attribute portion of the tuple.
- * ----------------
- */
- d1 = (char *) GETSTRUCT(h1);
- d2 = (char *) GETSTRUCT(h2);
- len = (int) h1->t_len - (int) h1->t_hoff;
-
- /* ----------------
- * byte compare the data areas and return the result.
- * ----------------
- */
- if (memcmp(d1, d2, len) != 0)
- return false;
-
- return true;
+ HeapTuple h1;
+ HeapTuple h2;
+ char *d1;
+ char *d2;
+ int len;
+
+ h1 = t1->val;
+ h2 = t2->val;
+
+ /* ----------------
+ * if tuples aren't the same length then they are
+ * obviously different (one may have null attributes).
+ * ----------------
+ */
+ if (h1->t_len != h2->t_len)
+ return false;
+
+ /* ----------------
+ * if the tuples have different header offsets then
+ * they are different. This will prevent us from returning
+ * true when comparing tuples of one attribute where one of
+ * two we're looking at is null (t_len - t_hoff == 0).
+ * THE t_len FIELDS CAN BE THE SAME IN THIS CASE!!
+ * ----------------
+ */
+ if (h1->t_hoff != h2->t_hoff)
+ return false;
+
+ /* ----------------
+ * ok, now get the pointers to the data and the
+ * size of the attribute portion of the tuple.
+ * ----------------
+ */
+ d1 = (char *) GETSTRUCT(h1);
+ d2 = (char *) GETSTRUCT(h2);
+ len = (int) h1->t_len - (int) h1->t_hoff;
+
+ /* ----------------
+ * byte compare the data areas and return the result.
+ * ----------------
+ */
+ if (memcmp(d1, d2, len) != 0)
+ return false;
+
+ return true;
}
/* ----------------------------------------------------------------
- * ExecUnique
+ * ExecUnique
*
- * This is a very simple node which filters out duplicate
- * tuples from a stream of sorted tuples from a subplan.
+ * This is a very simple node which filters out duplicate
+ * tuples from a stream of sorted tuples from a subplan.
*
- * XXX see comments below regarding freeing tuples.
+ * XXX see comments below regarding freeing tuples.
* ----------------------------------------------------------------
*/
-TupleTableSlot * /* return: a tuple or NULL */
-ExecUnique(Unique *node)
+TupleTableSlot * /* return: a tuple or NULL */
+ExecUnique(Unique * node)
{
- UniqueState *uniquestate;
- TupleTableSlot *resultTupleSlot;
- TupleTableSlot *slot;
- Plan *outerPlan;
- char *uniqueAttr;
- AttrNumber uniqueAttrNum;
- TupleDesc tupDesc;
- Oid typoutput;
-
- /* ----------------
- * get information from the node
- * ----------------
- */
- uniquestate = node->uniquestate;
- outerPlan = outerPlan((Plan *) node);
- resultTupleSlot = uniquestate->cs_ResultTupleSlot;
- uniqueAttr = node->uniqueAttr;
- uniqueAttrNum = node->uniqueAttrNum;
-
- if (uniqueAttr) {
- tupDesc = ExecGetResultType(uniquestate);
- typoutput = typtoout((Oid)tupDesc->attrs[uniqueAttrNum-1]->atttypid);
- }
- else { /* keep compiler quiet */
- tupDesc = NULL;
- typoutput = 0;
- }
-
- /* ----------------
- * now loop, returning only non-duplicate tuples.
- * We assume that the tuples arrive in sorted order
- * so we can detect duplicates easily.
- * ----------------
- */
- for (;;) {
+ UniqueState *uniquestate;
+ TupleTableSlot *resultTupleSlot;
+ TupleTableSlot *slot;
+ Plan *outerPlan;
+ char *uniqueAttr;
+ AttrNumber uniqueAttrNum;
+ TupleDesc tupDesc;
+ Oid typoutput;
+
/* ----------------
- * fetch a tuple from the outer subplan
+ * get information from the node
* ----------------
*/
- slot = ExecProcNode(outerPlan, (Plan*)node);
- if (TupIsNull(slot))
- return NULL;
-
+ uniquestate = node->uniquestate;
+ outerPlan = outerPlan((Plan *) node);
+ resultTupleSlot = uniquestate->cs_ResultTupleSlot;
+ uniqueAttr = node->uniqueAttr;
+ uniqueAttrNum = node->uniqueAttrNum;
+
+ if (uniqueAttr)
+ {
+ tupDesc = ExecGetResultType(uniquestate);
+ typoutput = typtoout((Oid) tupDesc->attrs[uniqueAttrNum - 1]->atttypid);
+ }
+ else
+ { /* keep compiler quiet */
+ tupDesc = NULL;
+ typoutput = 0;
+ }
+
/* ----------------
- * we use the result tuple slot to hold our saved tuples.
- * if we haven't a saved tuple to compare our new tuple with,
- * then we exit the loop. This new tuple as the saved tuple
- * the next time we get here.
+ * now loop, returning only non-duplicate tuples.
+ * We assume that the tuples arrive in sorted order
+ * so we can detect duplicates easily.
* ----------------
*/
- if (TupIsNull(resultTupleSlot))
- break;
-
+ for (;;)
+ {
+ /* ----------------
+ * fetch a tuple from the outer subplan
+ * ----------------
+ */
+ slot = ExecProcNode(outerPlan, (Plan *) node);
+ if (TupIsNull(slot))
+ return NULL;
+
+ /* ----------------
+ * we use the result tuple slot to hold our saved tuples.
+ * if we haven't a saved tuple to compare our new tuple with,
+ * then we exit the loop. This new tuple as the saved tuple
+ * the next time we get here.
+ * ----------------
+ */
+ if (TupIsNull(resultTupleSlot))
+ break;
+
+ /* ----------------
+ * now test if the new tuple and the previous
+ * tuple match. If so then we loop back and fetch
+ * another new tuple from the subplan.
+ * ----------------
+ */
+
+ if (uniqueAttr)
+ {
+
+ /*
+ * to check equality, we check to see if the typoutput of the
+ * attributes are equal
+ */
+ bool isNull1,
+ isNull2;
+ char *attr1,
+ *attr2;
+ char *val1,
+ *val2;
+
+ attr1 = heap_getattr(slot->val, InvalidBuffer,
+ uniqueAttrNum, tupDesc, &isNull1);
+ attr2 = heap_getattr(resultTupleSlot->val, InvalidBuffer,
+ uniqueAttrNum, tupDesc, &isNull2);
+
+ if (isNull1 == isNull2)
+ {
+ if (isNull1) /* both are null, they are equal */
+ continue;
+ val1 = fmgr(typoutput, attr1, gettypelem(tupDesc->attrs[uniqueAttrNum - 1]->atttypid));
+ val2 = fmgr(typoutput, attr2, gettypelem(tupDesc->attrs[uniqueAttrNum - 1]->atttypid));
+
+ /*
+ * now, val1 and val2 are ascii representations so we can
+ * use strcmp for comparison
+ */
+ if (strcmp(val1, val2) == 0) /* they are equal */
+ continue;
+ else
+ break;
+ }
+ else
+/* one is null and the other isn't, they aren't equal */
+ break;
+
+ }
+ else
+ {
+ if (!ExecIdenticalTuples(slot, resultTupleSlot))
+ break;
+ }
+
+ }
+
/* ----------------
- * now test if the new tuple and the previous
- * tuple match. If so then we loop back and fetch
- * another new tuple from the subplan.
+ * we have a new tuple different from the previous saved tuple
+ * so we save it in the saved tuple slot. We copy the tuple
+ * so we don't increment the buffer ref count.
* ----------------
*/
+ ExecStoreTuple(heap_copytuple(slot->val),
+ resultTupleSlot,
+ InvalidBuffer,
+ true);
- if (uniqueAttr) {
- /* to check equality, we check to see if the typoutput
- of the attributes are equal */
- bool isNull1,isNull2;
- char *attr1, *attr2;
- char *val1, *val2;
-
- attr1 = heap_getattr(slot->val, InvalidBuffer,
- uniqueAttrNum, tupDesc,&isNull1);
- attr2 = heap_getattr(resultTupleSlot->val, InvalidBuffer,
- uniqueAttrNum, tupDesc,&isNull2);
-
- if (isNull1 == isNull2) {
- if (isNull1) /* both are null, they are equal */
- continue;
- val1 = fmgr(typoutput, attr1, gettypelem(tupDesc->attrs[uniqueAttrNum-1]->atttypid));
- val2 = fmgr(typoutput, attr2, gettypelem(tupDesc->attrs[uniqueAttrNum-1]->atttypid));
- /* now, val1 and val2 are ascii representations so we can
- use strcmp for comparison */
- if (strcmp(val1,val2) == 0) /* they are equal */
- continue;
- else
- break;
- }
- else /* one is null and the other isn't, they aren't equal */
- break;
-
- }
- else {
- if (! ExecIdenticalTuples(slot, resultTupleSlot))
- break;
- }
-
- }
-
- /* ----------------
- * we have a new tuple different from the previous saved tuple
- * so we save it in the saved tuple slot. We copy the tuple
- * so we don't increment the buffer ref count.
- * ----------------
- */
- ExecStoreTuple(heap_copytuple(slot->val),
- resultTupleSlot,
- InvalidBuffer,
- true);
-
- return resultTupleSlot;
+ return resultTupleSlot;
}
/* ----------------------------------------------------------------
- * ExecInitUnique
+ * ExecInitUnique
*
- * This initializes the unique node state structures and
- * the node's subplan.
+ * This initializes the unique node state structures and
+ * the node's subplan.
* ----------------------------------------------------------------
*/
-bool /* return: initialization status */
-ExecInitUnique(Unique *node, EState *estate, Plan *parent)
+bool /* return: initialization status */
+ExecInitUnique(Unique * node, EState * estate, Plan * parent)
{
- UniqueState *uniquestate;
- Plan *outerPlan;
- char *uniqueAttr;
-
- /* ----------------
- * assign execution state to node
- * ----------------
- */
- node->plan.state = estate;
-
- /* ----------------
- * create new UniqueState for node
- * ----------------
- */
- uniquestate = makeNode(UniqueState);
- node->uniquestate = uniquestate;
- uniqueAttr = node->uniqueAttr;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks and
- *
- * Unique nodes have no ExprContext initialization because
- * they never call ExecQual or ExecTargetList.
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, uniquestate, parent);
-
+ UniqueState *uniquestate;
+ Plan *outerPlan;
+ char *uniqueAttr;
+
+ /* ----------------
+ * assign execution state to node
+ * ----------------
+ */
+ node->plan.state = estate;
+
+ /* ----------------
+ * create new UniqueState for node
+ * ----------------
+ */
+ uniquestate = makeNode(UniqueState);
+ node->uniquestate = uniquestate;
+ uniqueAttr = node->uniqueAttr;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks and
+ *
+ * Unique nodes have no ExprContext initialization because
+ * they never call ExecQual or ExecTargetList.
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, uniquestate, parent);
+
#define UNIQUE_NSLOTS 1
- /* ------------
- * Tuple table initialization
- * ------------
- */
- ExecInitResultTupleSlot(estate, uniquestate);
-
- /* ----------------
- * then initialize outer plan
- * ----------------
- */
- outerPlan = outerPlan((Plan *) node);
- ExecInitNode(outerPlan, estate, (Plan *) node);
-
- /* ----------------
- * unique nodes do no projections, so initialize
- * projection info for this node appropriately
- * ----------------
- */
- ExecAssignResultTypeFromOuterPlan((Plan *)node,uniquestate);
- uniquestate->cs_ProjInfo = NULL;
-
- if (uniqueAttr) {
- TupleDesc tupDesc;
- int i = 0;
-
- tupDesc = ExecGetResultType(uniquestate);
- /* the parser should have ensured that uniqueAttr is a legal attribute name*/
- while ( strcmp((tupDesc->attrs[i]->attname).data, uniqueAttr) != 0)
- i++;
- node->uniqueAttrNum = i+1; /* attribute numbers start from 1 */
- }
- else
- node->uniqueAttrNum = InvalidAttrNumber;
-
- /* ----------------
- * all done.
- * ----------------
- */
- return TRUE;
+ /* ------------
+ * Tuple table initialization
+ * ------------
+ */
+ ExecInitResultTupleSlot(estate, uniquestate);
+
+ /* ----------------
+ * then initialize outer plan
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+ ExecInitNode(outerPlan, estate, (Plan *) node);
+
+ /* ----------------
+ * unique nodes do no projections, so initialize
+ * projection info for this node appropriately
+ * ----------------
+ */
+ ExecAssignResultTypeFromOuterPlan((Plan *) node, uniquestate);
+ uniquestate->cs_ProjInfo = NULL;
+
+ if (uniqueAttr)
+ {
+ TupleDesc tupDesc;
+ int i = 0;
+
+ tupDesc = ExecGetResultType(uniquestate);
+
+ /*
+ * the parser should have ensured that uniqueAttr is a legal
+ * attribute name
+ */
+ while (strcmp((tupDesc->attrs[i]->attname).data, uniqueAttr) != 0)
+ i++;
+ node->uniqueAttrNum = i + 1; /* attribute numbers start from 1 */
+ }
+ else
+ node->uniqueAttrNum = InvalidAttrNumber;
+
+ /* ----------------
+ * all done.
+ * ----------------
+ */
+ return TRUE;
}
int
-ExecCountSlotsUnique(Unique *node)
+ExecCountSlotsUnique(Unique * node)
{
- return ExecCountSlotsNode(outerPlan(node)) +
+ return ExecCountSlotsNode(outerPlan(node)) +
ExecCountSlotsNode(innerPlan(node)) +
- UNIQUE_NSLOTS;
+ UNIQUE_NSLOTS;
}
/* ----------------------------------------------------------------
- * ExecEndUnique
+ * ExecEndUnique
*
- * This shuts down the subplan and frees resources allocated
- * to this node.
+ * This shuts down the subplan and frees resources allocated
+ * to this node.
* ----------------------------------------------------------------
*/
void
-ExecEndUnique(Unique *node)
+ExecEndUnique(Unique * node)
{
- UniqueState *uniquestate;
-
- uniquestate = node->uniquestate;
- ExecEndNode(outerPlan((Plan *) node), (Plan*)node);
- ExecClearTuple(uniquestate->cs_ResultTupleSlot);
-}
+ UniqueState *uniquestate;
+
+ uniquestate = node->uniquestate;
+ ExecEndNode(outerPlan((Plan *) node), (Plan *) node);
+ ExecClearTuple(uniquestate->cs_ResultTupleSlot);
+}
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 74ace81171a..1d05a752d24 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* spi.c--
- * Server Programming Interface
+ * Server Programming Interface
*
*-------------------------------------------------------------------------
*/
@@ -9,440 +9,447 @@
#include "access/printtup.h"
#include "fmgr.h"
-typedef struct {
- QueryTreeList *qtlist; /* malloced */
- uint32 processed; /* by Executor */
- SPITupleTable *tuptable;
- Portal portal; /* portal per procedure */
- MemoryContext savedcxt;
- CommandId savedId;
-} _SPI_connection;
-
-static Portal _SPI_portal = (Portal) NULL;
+typedef struct
+{
+ QueryTreeList *qtlist; /* malloced */
+ uint32 processed; /* by Executor */
+ SPITupleTable *tuptable;
+ Portal portal; /* portal per procedure */
+ MemoryContext savedcxt;
+ CommandId savedId;
+} _SPI_connection;
+
+static Portal _SPI_portal = (Portal) NULL;
static _SPI_connection *_SPI_stack = NULL;
static _SPI_connection *_SPI_current = NULL;
-static int _SPI_connected = -1;
-static int _SPI_curid = -1;
+static int _SPI_connected = -1;
+static int _SPI_curid = -1;
+
+uint32 SPI_processed = 0;
+SPITupleTable *SPI_tuptable;
+int SPI_result;
-uint32 SPI_processed = 0;
-SPITupleTable *SPI_tuptable;
-int SPI_result;
+void spi_printtup(HeapTuple tuple, TupleDesc tupdesc);
-void spi_printtup (HeapTuple tuple, TupleDesc tupdesc);
+typedef struct
+{
+ QueryTreeList *qtlist;
+ List *ptlist;
+ int nargs;
+ Oid *argtypes;
+} _SPI_plan;
-typedef struct {
- QueryTreeList *qtlist;
- List *ptlist;
- int nargs;
- Oid *argtypes;
-} _SPI_plan;
+static int _SPI_execute(char *src, int tcount, _SPI_plan * plan);
+static int _SPI_pquery(QueryDesc * queryDesc, EState * state, int tcount);
-static int _SPI_execute (char *src, int tcount, _SPI_plan *plan);
-static int _SPI_pquery (QueryDesc *queryDesc, EState *state, int tcount);
#if 0
-static void _SPI_fetch (FetchStmt *stmt);
+static void _SPI_fetch(FetchStmt * stmt);
+
#endif
-static int _SPI_execute_plan (_SPI_plan *plan,
- char **Values, char *Nulls, int tcount);
+static int
+_SPI_execute_plan(_SPI_plan * plan,
+ char **Values, char *Nulls, int tcount);
-static _SPI_plan *_SPI_copy_plan (_SPI_plan *plan, bool local);
+static _SPI_plan *_SPI_copy_plan(_SPI_plan * plan, bool local);
-static int _SPI_begin_call (bool execmem);
-static int _SPI_end_call (bool procmem);
-static MemoryContext _SPI_execmem (void);
-static MemoryContext _SPI_procmem (void);
-static bool _SPI_checktuples (bool isRetrieveIntoRelation);
+static int _SPI_begin_call(bool execmem);
+static int _SPI_end_call(bool procmem);
+static MemoryContext _SPI_execmem(void);
+static MemoryContext _SPI_procmem(void);
+static bool _SPI_checktuples(bool isRetrieveIntoRelation);
#ifdef SPI_EXECUTOR_STATS
-extern int ShowExecutorStats;
-extern void ResetUsage (void);
-extern void ShowUsage (void);
+extern int ShowExecutorStats;
+extern void ResetUsage(void);
+extern void ShowUsage(void);
+
#endif
int
-SPI_connect ()
+SPI_connect()
{
- char pname[64];
- PortalVariableMemory pvmem;
-
- /*
- * It's possible on startup and after commit/abort.
- * In future we'll catch commit/abort in some way...
- */
- strcpy (pname, "<SPI manager>");
- _SPI_portal = GetPortalByName (pname);
- if ( !PortalIsValid (_SPI_portal) )
- {
- if ( _SPI_stack != NULL ) /* there was abort */
- free (_SPI_stack);
- _SPI_current = _SPI_stack = NULL;
- _SPI_connected = _SPI_curid = -1;
- SPI_processed = 0;
- SPI_tuptable = NULL;
- _SPI_portal = CreatePortal (pname);
- if ( !PortalIsValid (_SPI_portal) )
- elog (FATAL, "SPI_connect: global initialization failed");
- }
-
- /*
- * When procedure called by Executor _SPI_curid expected to be
- * equal to _SPI_connected
- */
- if ( _SPI_curid != _SPI_connected )
- return (SPI_ERROR_CONNECT);
-
- if ( _SPI_stack == NULL )
- {
- if ( _SPI_connected != -1 )
- elog (FATAL, "SPI_connect: no connection(s) expected");
- _SPI_stack = (_SPI_connection *) malloc (sizeof (_SPI_connection));
- }
- else
- {
- if ( _SPI_connected <= -1 )
- elog (FATAL, "SPI_connect: some connection(s) expected");
- _SPI_stack = (_SPI_connection *) realloc (_SPI_stack,
- (_SPI_connected + 1) * sizeof (_SPI_connection));
- }
- /*
- * We' returning to procedure where _SPI_curid == _SPI_connected - 1
- */
- _SPI_connected++;
-
- _SPI_current = &(_SPI_stack[_SPI_connected]);
- _SPI_current->qtlist = NULL;
- _SPI_current->processed = 0;
- _SPI_current->tuptable = NULL;
-
- /* Create Portal for this procedure ... */
- sprintf (pname, "<SPI %d>", _SPI_connected);
- _SPI_current->portal = CreatePortal (pname);
- if ( !PortalIsValid (_SPI_current->portal) )
- elog (FATAL, "SPI_connect: initialization failed");
-
- /* ... and switch to Portal' Variable memory - procedure' context */
- pvmem = PortalGetVariableMemory (_SPI_current->portal);
- _SPI_current->savedcxt = MemoryContextSwitchTo ((MemoryContext)pvmem);
-
- _SPI_current->savedId = GetScanCommandId ();
- SetScanCommandId (GetCurrentCommandId ());
-
- return (SPI_OK_CONNECT);
-
+ char pname[64];
+ PortalVariableMemory pvmem;
+
+ /*
+ * It's possible on startup and after commit/abort. In future we'll
+ * catch commit/abort in some way...
+ */
+ strcpy(pname, "<SPI manager>");
+ _SPI_portal = GetPortalByName(pname);
+ if (!PortalIsValid(_SPI_portal))
+ {
+ if (_SPI_stack != NULL) /* there was abort */
+ free(_SPI_stack);
+ _SPI_current = _SPI_stack = NULL;
+ _SPI_connected = _SPI_curid = -1;
+ SPI_processed = 0;
+ SPI_tuptable = NULL;
+ _SPI_portal = CreatePortal(pname);
+ if (!PortalIsValid(_SPI_portal))
+ elog(FATAL, "SPI_connect: global initialization failed");
+ }
+
+ /*
+ * When procedure called by Executor _SPI_curid expected to be equal
+ * to _SPI_connected
+ */
+ if (_SPI_curid != _SPI_connected)
+ return (SPI_ERROR_CONNECT);
+
+ if (_SPI_stack == NULL)
+ {
+ if (_SPI_connected != -1)
+ elog(FATAL, "SPI_connect: no connection(s) expected");
+ _SPI_stack = (_SPI_connection *) malloc(sizeof(_SPI_connection));
+ }
+ else
+ {
+ if (_SPI_connected <= -1)
+ elog(FATAL, "SPI_connect: some connection(s) expected");
+ _SPI_stack = (_SPI_connection *) realloc(_SPI_stack,
+ (_SPI_connected + 1) * sizeof(_SPI_connection));
+ }
+
+ /*
+ * We' returning to procedure where _SPI_curid == _SPI_connected - 1
+ */
+ _SPI_connected++;
+
+ _SPI_current = &(_SPI_stack[_SPI_connected]);
+ _SPI_current->qtlist = NULL;
+ _SPI_current->processed = 0;
+ _SPI_current->tuptable = NULL;
+
+ /* Create Portal for this procedure ... */
+ sprintf(pname, "<SPI %d>", _SPI_connected);
+ _SPI_current->portal = CreatePortal(pname);
+ if (!PortalIsValid(_SPI_current->portal))
+ elog(FATAL, "SPI_connect: initialization failed");
+
+ /* ... and switch to Portal' Variable memory - procedure' context */
+ pvmem = PortalGetVariableMemory(_SPI_current->portal);
+ _SPI_current->savedcxt = MemoryContextSwitchTo((MemoryContext) pvmem);
+
+ _SPI_current->savedId = GetScanCommandId();
+ SetScanCommandId(GetCurrentCommandId());
+
+ return (SPI_OK_CONNECT);
+
}
int
-SPI_finish ()
+SPI_finish()
{
- int res;
-
- res = _SPI_begin_call (false); /* live in procedure memory */
- if ( res < 0 )
- return (res);
-
- /* Restore memory context as it was before procedure call */
- MemoryContextSwitchTo (_SPI_current->savedcxt);
- PortalDestroy (&(_SPI_current->portal));
-
- SetScanCommandId (_SPI_current->savedId);
-
- /*
- * After _SPI_begin_call _SPI_connected == _SPI_curid.
- * Now we are closing connection to SPI and returning to upper
- * Executor and so _SPI_connected must be equal to _SPI_curid.
- */
- _SPI_connected--;
- _SPI_curid--;
- if ( _SPI_connected == -1 )
- {
- free (_SPI_stack);
- _SPI_stack = NULL;
- }
- else
- {
- _SPI_stack = (_SPI_connection *) realloc (_SPI_stack,
- (_SPI_connected + 1) * sizeof (_SPI_connection));
- _SPI_current = &(_SPI_stack[_SPI_connected]);
- }
-
- return (SPI_OK_FINISH);
-
+ int res;
+
+ res = _SPI_begin_call(false); /* live in procedure memory */
+ if (res < 0)
+ return (res);
+
+ /* Restore memory context as it was before procedure call */
+ MemoryContextSwitchTo(_SPI_current->savedcxt);
+ PortalDestroy(&(_SPI_current->portal));
+
+ SetScanCommandId(_SPI_current->savedId);
+
+ /*
+ * After _SPI_begin_call _SPI_connected == _SPI_curid. Now we are
+ * closing connection to SPI and returning to upper Executor and so
+ * _SPI_connected must be equal to _SPI_curid.
+ */
+ _SPI_connected--;
+ _SPI_curid--;
+ if (_SPI_connected == -1)
+ {
+ free(_SPI_stack);
+ _SPI_stack = NULL;
+ }
+ else
+ {
+ _SPI_stack = (_SPI_connection *) realloc(_SPI_stack,
+ (_SPI_connected + 1) * sizeof(_SPI_connection));
+ _SPI_current = &(_SPI_stack[_SPI_connected]);
+ }
+
+ return (SPI_OK_FINISH);
+
}
int
-SPI_exec (char *src, int tcount)
+SPI_exec(char *src, int tcount)
{
- int res;
-
- if ( src == NULL || tcount < 0 )
- return (SPI_ERROR_ARGUMENT);
-
- res = _SPI_begin_call (true);
- if ( res < 0 )
- return (res);
-
- res = _SPI_execute (src, tcount, NULL);
-
- _SPI_end_call (true);
- return (res);
+ int res;
+
+ if (src == NULL || tcount < 0)
+ return (SPI_ERROR_ARGUMENT);
+
+ res = _SPI_begin_call(true);
+ if (res < 0)
+ return (res);
+
+ res = _SPI_execute(src, tcount, NULL);
+
+ _SPI_end_call(true);
+ return (res);
}
-int
-SPI_execp (void *plan, char **Values, char *Nulls, int tcount)
+int
+SPI_execp(void *plan, char **Values, char *Nulls, int tcount)
{
- int res;
-
- if ( plan == NULL || tcount < 0 )
- return (SPI_ERROR_ARGUMENT);
-
- if ( ((_SPI_plan *)plan)->nargs > 0 &&
- ( Values == NULL || Nulls == NULL ) )
- return (SPI_ERROR_PARAM);
-
- res = _SPI_begin_call (true);
- if ( res < 0 )
- return (res);
-
- res = _SPI_execute_plan ((_SPI_plan *)plan, Values, Nulls, tcount);
-
- _SPI_end_call (true);
- return (res);
+ int res;
+
+ if (plan == NULL || tcount < 0)
+ return (SPI_ERROR_ARGUMENT);
+
+ if (((_SPI_plan *) plan)->nargs > 0 &&
+ (Values == NULL || Nulls == NULL))
+ return (SPI_ERROR_PARAM);
+
+ res = _SPI_begin_call(true);
+ if (res < 0)
+ return (res);
+
+ res = _SPI_execute_plan((_SPI_plan *) plan, Values, Nulls, tcount);
+
+ _SPI_end_call(true);
+ return (res);
}
-void *
-SPI_prepare (char *src, int nargs, Oid *argtypes)
+void *
+SPI_prepare(char *src, int nargs, Oid * argtypes)
{
- _SPI_plan *plan;
-
- if ( nargs < 0 || ( nargs > 0 && argtypes == NULL ) )
- {
- SPI_result = SPI_ERROR_ARGUMENT;
- return (NULL);
- }
-
- SPI_result = _SPI_begin_call (true);
- if ( SPI_result < 0 )
- return (NULL);
-
- plan = (_SPI_plan *) palloc (sizeof (_SPI_plan)); /* Executor context */
- plan->argtypes = argtypes;
- plan->nargs = nargs;
-
- SPI_result = _SPI_execute (src, 0, plan);
-
- if ( SPI_result >= 0 ) /* copy plan to local space */
- plan = _SPI_copy_plan (plan, true);
- else
- plan = NULL;
-
- _SPI_end_call (true);
-
- return ((void *)plan);
-
+ _SPI_plan *plan;
+
+ if (nargs < 0 || (nargs > 0 && argtypes == NULL))
+ {
+ SPI_result = SPI_ERROR_ARGUMENT;
+ return (NULL);
+ }
+
+ SPI_result = _SPI_begin_call(true);
+ if (SPI_result < 0)
+ return (NULL);
+
+ plan = (_SPI_plan *) palloc(sizeof(_SPI_plan)); /* Executor context */
+ plan->argtypes = argtypes;
+ plan->nargs = nargs;
+
+ SPI_result = _SPI_execute(src, 0, plan);
+
+ if (SPI_result >= 0) /* copy plan to local space */
+ plan = _SPI_copy_plan(plan, true);
+ else
+ plan = NULL;
+
+ _SPI_end_call(true);
+
+ return ((void *) plan);
+
}
-void *
-SPI_saveplan (void *plan)
+void *
+SPI_saveplan(void *plan)
{
- _SPI_plan *newplan;
-
- if ( plan == NULL )
- {
- SPI_result = SPI_ERROR_ARGUMENT;
- return (NULL);
- }
-
- SPI_result = _SPI_begin_call (false); /* don't change context */
- if ( SPI_result < 0 )
- return (NULL);
-
- newplan = _SPI_copy_plan ((_SPI_plan *)plan, false);
-
- _SPI_curid--;
- SPI_result = 0;
-
- return ((void *)newplan);
-
+ _SPI_plan *newplan;
+
+ if (plan == NULL)
+ {
+ SPI_result = SPI_ERROR_ARGUMENT;
+ return (NULL);
+ }
+
+ SPI_result = _SPI_begin_call(false); /* don't change context */
+ if (SPI_result < 0)
+ return (NULL);
+
+ newplan = _SPI_copy_plan((_SPI_plan *) plan, false);
+
+ _SPI_curid--;
+ SPI_result = 0;
+
+ return ((void *) newplan);
+
}
int
-SPI_fnumber (TupleDesc tupdesc, char *fname)
+SPI_fnumber(TupleDesc tupdesc, char *fname)
{
- int res;
-
- if ( _SPI_curid + 1 != _SPI_connected )
- return (SPI_ERROR_UNCONNECTED);
-
- for (res = 0; res < tupdesc->natts; res++)
- {
- if ( strcmp (tupdesc->attrs[res]->attname.data, fname) == 0 )
- return (res + 1);
- }
-
- return (SPI_ERROR_NOATTRIBUTE);
+ int res;
+
+ if (_SPI_curid + 1 != _SPI_connected)
+ return (SPI_ERROR_UNCONNECTED);
+
+ for (res = 0; res < tupdesc->natts; res++)
+ {
+ if (strcmp(tupdesc->attrs[res]->attname.data, fname) == 0)
+ return (res + 1);
+ }
+
+ return (SPI_ERROR_NOATTRIBUTE);
}
-char *
-SPI_getvalue (HeapTuple tuple, TupleDesc tupdesc, int fnumber)
+char *
+SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
{
- char *val;
- bool isnull;
- Oid foutoid;
-
- SPI_result = 0;
- if ( _SPI_curid + 1 != _SPI_connected )
- {
- SPI_result = SPI_ERROR_UNCONNECTED;
- return (NULL);
- }
-
- if ( tuple->t_natts < fnumber || fnumber <= 0 )
- return (NULL);
-
- val = heap_getattr (tuple, InvalidBuffer, fnumber, tupdesc, &isnull);
- if ( isnull )
- return (NULL);
- foutoid = typtoout ((Oid) tupdesc->attrs[fnumber - 1]->atttypid);
- if ( !OidIsValid (foutoid) )
- {
- SPI_result = SPI_ERROR_NOOUTFUNC;
- return (NULL);
- }
-
- return (fmgr (foutoid, val, gettypelem (tupdesc->attrs[fnumber - 1]->atttypid)));
+ char *val;
+ bool isnull;
+ Oid foutoid;
+
+ SPI_result = 0;
+ if (_SPI_curid + 1 != _SPI_connected)
+ {
+ SPI_result = SPI_ERROR_UNCONNECTED;
+ return (NULL);
+ }
+
+ if (tuple->t_natts < fnumber || fnumber <= 0)
+ return (NULL);
+
+ val = heap_getattr(tuple, InvalidBuffer, fnumber, tupdesc, &isnull);
+ if (isnull)
+ return (NULL);
+ foutoid = typtoout((Oid) tupdesc->attrs[fnumber - 1]->atttypid);
+ if (!OidIsValid(foutoid))
+ {
+ SPI_result = SPI_ERROR_NOOUTFUNC;
+ return (NULL);
+ }
+
+ return (fmgr(foutoid, val, gettypelem(tupdesc->attrs[fnumber - 1]->atttypid)));
}
-char *
-SPI_getbinval (HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
+char *
+SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull)
{
- char *val;
-
- *isnull = true;
- SPI_result = 0;
- if ( _SPI_curid + 1 != _SPI_connected )
- {
- SPI_result = SPI_ERROR_UNCONNECTED;
- return (NULL);
- }
-
- if ( tuple->t_natts < fnumber || fnumber <= 0 )
- return (NULL);
-
- val = heap_getattr (tuple, InvalidBuffer, fnumber, tupdesc, isnull);
-
- return (val);
+ char *val;
+
+ *isnull = true;
+ SPI_result = 0;
+ if (_SPI_curid + 1 != _SPI_connected)
+ {
+ SPI_result = SPI_ERROR_UNCONNECTED;
+ return (NULL);
+ }
+
+ if (tuple->t_natts < fnumber || fnumber <= 0)
+ return (NULL);
+
+ val = heap_getattr(tuple, InvalidBuffer, fnumber, tupdesc, isnull);
+
+ return (val);
}
-char *
-SPI_gettype (TupleDesc tupdesc, int fnumber)
+char *
+SPI_gettype(TupleDesc tupdesc, int fnumber)
{
- HeapTuple typeTuple;
-
- SPI_result = 0;
- if ( _SPI_curid + 1 != _SPI_connected )
- {
- SPI_result = SPI_ERROR_UNCONNECTED;
- return (NULL);
- }
-
- if ( tupdesc->natts < fnumber || fnumber <= 0 )
- {
- SPI_result = SPI_ERROR_NOATTRIBUTE;
- return (NULL);
- }
-
- typeTuple = SearchSysCacheTuple (TYPOID,
- ObjectIdGetDatum (tupdesc->attrs[fnumber - 1]->atttypid),
- 0, 0, 0);
-
- if ( !HeapTupleIsValid (typeTuple) )
- {
- SPI_result = SPI_ERROR_TYPUNKNOWN;
- return (NULL);
- }
-
- return (pstrdup (((TypeTupleForm) GETSTRUCT (typeTuple))->typname.data));
+ HeapTuple typeTuple;
+
+ SPI_result = 0;
+ if (_SPI_curid + 1 != _SPI_connected)
+ {
+ SPI_result = SPI_ERROR_UNCONNECTED;
+ return (NULL);
+ }
+
+ if (tupdesc->natts < fnumber || fnumber <= 0)
+ {
+ SPI_result = SPI_ERROR_NOATTRIBUTE;
+ return (NULL);
+ }
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(tupdesc->attrs[fnumber - 1]->atttypid),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(typeTuple))
+ {
+ SPI_result = SPI_ERROR_TYPUNKNOWN;
+ return (NULL);
+ }
+
+ return (pstrdup(((TypeTupleForm) GETSTRUCT(typeTuple))->typname.data));
}
Oid
-SPI_gettypeid (TupleDesc tupdesc, int fnumber)
+SPI_gettypeid(TupleDesc tupdesc, int fnumber)
{
-
- SPI_result = 0;
- if ( _SPI_curid + 1 != _SPI_connected )
- {
- SPI_result = SPI_ERROR_UNCONNECTED;
- return (InvalidOid);
- }
-
- if ( tupdesc->natts < fnumber || fnumber <= 0 )
- {
- SPI_result = SPI_ERROR_NOATTRIBUTE;
- return (InvalidOid);
- }
-
- return (tupdesc->attrs[fnumber - 1]->atttypid);
+
+ SPI_result = 0;
+ if (_SPI_curid + 1 != _SPI_connected)
+ {
+ SPI_result = SPI_ERROR_UNCONNECTED;
+ return (InvalidOid);
+ }
+
+ if (tupdesc->natts < fnumber || fnumber <= 0)
+ {
+ SPI_result = SPI_ERROR_NOATTRIBUTE;
+ return (InvalidOid);
+ }
+
+ return (tupdesc->attrs[fnumber - 1]->atttypid);
}
-char *
-SPI_getrelname (Relation rel)
+char *
+SPI_getrelname(Relation rel)
{
-
- SPI_result = 0;
- if ( _SPI_curid + 1 != _SPI_connected )
- {
- SPI_result = SPI_ERROR_UNCONNECTED;
- return (NULL);
- }
-
- return (pstrdup (rel->rd_rel->relname.data));
+
+ SPI_result = 0;
+ if (_SPI_curid + 1 != _SPI_connected)
+ {
+ SPI_result = SPI_ERROR_UNCONNECTED;
+ return (NULL);
+ }
+
+ return (pstrdup(rel->rd_rel->relname.data));
}
/*
* spi_printtup --
- * store tuple retrieved by Executor into SPITupleTable
- * of current SPI procedure
+ * store tuple retrieved by Executor into SPITupleTable
+ * of current SPI procedure
*
*/
void
-spi_printtup (HeapTuple tuple, TupleDesc tupdesc)
+spi_printtup(HeapTuple tuple, TupleDesc tupdesc)
{
- SPITupleTable *tuptable;
- MemoryContext oldcxt;
-
- /*
- * When called by Executor _SPI_curid expected to be
- * equal to _SPI_connected
- */
- if ( _SPI_curid != _SPI_connected || _SPI_connected < 0 )
- elog (FATAL, "SPI: improper call to spi_printtup");
- if ( _SPI_current != &(_SPI_stack[_SPI_curid]) )
- elog (FATAL, "SPI: stack corrupted in spi_printtup");
-
- oldcxt = _SPI_procmem (); /* switch to procedure memory context */
-
- tuptable = _SPI_current->tuptable;
- if ( tuptable == NULL )
- {
- _SPI_current->tuptable = tuptable = (SPITupleTable *)
- palloc (sizeof (SPITupleTable));
- tuptable->alloced = tuptable->free = 128;
- tuptable->vals = (HeapTuple *) palloc (tuptable->alloced * sizeof (HeapTuple));
- tuptable->tupdesc = CreateTupleDescCopy (tupdesc);
- }
- else if ( tuptable->free == 0 )
- {
- tuptable->free = 256;
- tuptable->alloced += tuptable->free;
- tuptable->vals = (HeapTuple *) repalloc (tuptable->vals,
- tuptable->alloced * sizeof (HeapTuple));
- }
-
- tuptable->vals[tuptable->alloced - tuptable->free] = heap_copytuple (tuple);
- (tuptable->free)--;
-
- MemoryContextSwitchTo (oldcxt);
- return;
+ SPITupleTable *tuptable;
+ MemoryContext oldcxt;
+
+ /*
+ * When called by Executor _SPI_curid expected to be equal to
+ * _SPI_connected
+ */
+ if (_SPI_curid != _SPI_connected || _SPI_connected < 0)
+ elog(FATAL, "SPI: improper call to spi_printtup");
+ if (_SPI_current != &(_SPI_stack[_SPI_curid]))
+ elog(FATAL, "SPI: stack corrupted in spi_printtup");
+
+ oldcxt = _SPI_procmem(); /* switch to procedure memory context */
+
+ tuptable = _SPI_current->tuptable;
+ if (tuptable == NULL)
+ {
+ _SPI_current->tuptable = tuptable = (SPITupleTable *)
+ palloc(sizeof(SPITupleTable));
+ tuptable->alloced = tuptable->free = 128;
+ tuptable->vals = (HeapTuple *) palloc(tuptable->alloced * sizeof(HeapTuple));
+ tuptable->tupdesc = CreateTupleDescCopy(tupdesc);
+ }
+ else if (tuptable->free == 0)
+ {
+ tuptable->free = 256;
+ tuptable->alloced += tuptable->free;
+ tuptable->vals = (HeapTuple *) repalloc(tuptable->vals,
+ tuptable->alloced * sizeof(HeapTuple));
+ }
+
+ tuptable->vals[tuptable->alloced - tuptable->free] = heap_copytuple(tuple);
+ (tuptable->free)--;
+
+ MemoryContextSwitchTo(oldcxt);
+ return;
}
/*
@@ -450,330 +457,334 @@ spi_printtup (HeapTuple tuple, TupleDesc tupdesc)
*/
static int
-_SPI_execute (char *src, int tcount, _SPI_plan *plan)
+_SPI_execute(char *src, int tcount, _SPI_plan * plan)
{
- QueryTreeList *queryTree_list;
- List *planTree_list;
- List *ptlist;
- QueryDesc *qdesc;
- Query *queryTree;
- Plan *planTree;
- EState *state;
- int qlen;
- int nargs = 0;
- Oid *argtypes = NULL;
- int res;
- int i;
-
- /* Increment CommandCounter to see changes made by now */
- CommandCounterIncrement ();
-
- SPI_processed = 0;
- SPI_tuptable = NULL;
- _SPI_current->tuptable = NULL;
- _SPI_current->qtlist = NULL;
-
- if ( plan )
- {
- nargs = plan->nargs;
- argtypes = plan->argtypes;
- }
- ptlist = planTree_list = (List *)
- pg_plan (src, argtypes, nargs, &queryTree_list, None);
-
- _SPI_current->qtlist = queryTree_list;
-
- qlen = queryTree_list->len;
- for (i=0; ;i++)
- {
- queryTree = (Query*) (queryTree_list->qtrees[i]);
- planTree = lfirst(planTree_list);
-
- planTree_list = lnext (planTree_list);
-
- if ( queryTree->commandType == CMD_UTILITY )
- {
- if ( nodeTag (queryTree->utilityStmt ) == T_CopyStmt )
- {
- CopyStmt *stmt = (CopyStmt *)(queryTree->utilityStmt);
-
- if ( stmt->filename == NULL )
- return (SPI_ERROR_COPY);
- }
- else if ( nodeTag (queryTree->utilityStmt ) == T_ClosePortalStmt ||
- nodeTag (queryTree->utilityStmt ) == T_FetchStmt )
- return (SPI_ERROR_CURSOR);
- else if ( nodeTag (queryTree->utilityStmt ) == T_TransactionStmt )
- return (SPI_ERROR_TRANSACTION);
- res = SPI_OK_UTILITY;
- if ( plan == NULL )
- {
- ProcessUtility (queryTree->utilityStmt, None);
- if ( i < qlen - 1 )
- CommandCounterIncrement ();
- else
- return (res);
- }
- else if ( i >= qlen - 1 )
- break;
- }
- else if ( plan == NULL )
- {
- qdesc = CreateQueryDesc (queryTree, planTree,
- ( i < qlen - 1 ) ? None : SPI);
- state = CreateExecutorState();
- res = _SPI_pquery (qdesc, state, ( i < qlen - 1 ) ? 0 : tcount);
- if ( res < 0 || i >= qlen - 1 )
- return (res);
- CommandCounterIncrement ();
+ QueryTreeList *queryTree_list;
+ List *planTree_list;
+ List *ptlist;
+ QueryDesc *qdesc;
+ Query *queryTree;
+ Plan *planTree;
+ EState *state;
+ int qlen;
+ int nargs = 0;
+ Oid *argtypes = NULL;
+ int res;
+ int i;
+
+ /* Increment CommandCounter to see changes made by now */
+ CommandCounterIncrement();
+
+ SPI_processed = 0;
+ SPI_tuptable = NULL;
+ _SPI_current->tuptable = NULL;
+ _SPI_current->qtlist = NULL;
+
+ if (plan)
+ {
+ nargs = plan->nargs;
+ argtypes = plan->argtypes;
}
- else
+ ptlist = planTree_list = (List *)
+ pg_plan(src, argtypes, nargs, &queryTree_list, None);
+
+ _SPI_current->qtlist = queryTree_list;
+
+ qlen = queryTree_list->len;
+ for (i = 0;; i++)
{
- qdesc = CreateQueryDesc (queryTree, planTree,
- ( i < qlen - 1 ) ? None : SPI);
- res = _SPI_pquery (qdesc, NULL, ( i < qlen - 1 ) ? 0 : tcount);
- if ( res < 0 )
- return (res);
- if ( i >= qlen - 1 )
- break;
- }
- }
-
- plan->qtlist = queryTree_list;
- plan->ptlist = ptlist;
-
- return (res);
-
+ queryTree = (Query *) (queryTree_list->qtrees[i]);
+ planTree = lfirst(planTree_list);
+
+ planTree_list = lnext(planTree_list);
+
+ if (queryTree->commandType == CMD_UTILITY)
+ {
+ if (nodeTag(queryTree->utilityStmt) == T_CopyStmt)
+ {
+ CopyStmt *stmt = (CopyStmt *) (queryTree->utilityStmt);
+
+ if (stmt->filename == NULL)
+ return (SPI_ERROR_COPY);
+ }
+ else if (nodeTag(queryTree->utilityStmt) == T_ClosePortalStmt ||
+ nodeTag(queryTree->utilityStmt) == T_FetchStmt)
+ return (SPI_ERROR_CURSOR);
+ else if (nodeTag(queryTree->utilityStmt) == T_TransactionStmt)
+ return (SPI_ERROR_TRANSACTION);
+ res = SPI_OK_UTILITY;
+ if (plan == NULL)
+ {
+ ProcessUtility(queryTree->utilityStmt, None);
+ if (i < qlen - 1)
+ CommandCounterIncrement();
+ else
+ return (res);
+ }
+ else if (i >= qlen - 1)
+ break;
+ }
+ else if (plan == NULL)
+ {
+ qdesc = CreateQueryDesc(queryTree, planTree,
+ (i < qlen - 1) ? None : SPI);
+ state = CreateExecutorState();
+ res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount);
+ if (res < 0 || i >= qlen - 1)
+ return (res);
+ CommandCounterIncrement();
+ }
+ else
+ {
+ qdesc = CreateQueryDesc(queryTree, planTree,
+ (i < qlen - 1) ? None : SPI);
+ res = _SPI_pquery(qdesc, NULL, (i < qlen - 1) ? 0 : tcount);
+ if (res < 0)
+ return (res);
+ if (i >= qlen - 1)
+ break;
+ }
+ }
+
+ plan->qtlist = queryTree_list;
+ plan->ptlist = ptlist;
+
+ return (res);
+
}
static int
-_SPI_execute_plan (_SPI_plan *plan, char **Values, char *Nulls, int tcount)
+_SPI_execute_plan(_SPI_plan * plan, char **Values, char *Nulls, int tcount)
{
- QueryTreeList *queryTree_list = plan->qtlist;
- List *planTree_list = plan->ptlist;
- QueryDesc *qdesc;
- Query *queryTree;
- Plan *planTree;
- EState *state;
- int nargs = plan->nargs;
- int qlen = queryTree_list->len;
- int res;
- int i, k;
-
- /* Increment CommandCounter to see changes made by now */
- CommandCounterIncrement ();
-
- SPI_processed = 0;
- SPI_tuptable = NULL;
- _SPI_current->tuptable = NULL;
- _SPI_current->qtlist = NULL;
-
- for (i=0; ;i++)
- {
- queryTree = (Query*) (queryTree_list->qtrees[i]);
- planTree = lfirst(planTree_list);
-
- planTree_list = lnext (planTree_list);
-
- if ( queryTree->commandType == CMD_UTILITY )
- {
- ProcessUtility (queryTree->utilityStmt, None);
- if ( i < qlen - 1 )
- CommandCounterIncrement ();
- else
- return (SPI_OK_UTILITY);
- }
- else
+ QueryTreeList *queryTree_list = plan->qtlist;
+ List *planTree_list = plan->ptlist;
+ QueryDesc *qdesc;
+ Query *queryTree;
+ Plan *planTree;
+ EState *state;
+ int nargs = plan->nargs;
+ int qlen = queryTree_list->len;
+ int res;
+ int i,
+ k;
+
+ /* Increment CommandCounter to see changes made by now */
+ CommandCounterIncrement();
+
+ SPI_processed = 0;
+ SPI_tuptable = NULL;
+ _SPI_current->tuptable = NULL;
+ _SPI_current->qtlist = NULL;
+
+ for (i = 0;; i++)
{
- qdesc = CreateQueryDesc (queryTree, planTree,
- ( i < qlen - 1 ) ? None : SPI);
- state = CreateExecutorState();
- if ( nargs > 0 )
- {
- ParamListInfo paramLI = (ParamListInfo) palloc ((nargs + 1) *
- sizeof (ParamListInfoData));
- state->es_param_list_info = paramLI;
- for (k = 0; k < plan->nargs; paramLI++, k++)
- {
- paramLI->kind = PARAM_NUM;
- paramLI->id = k+1;
- paramLI->isnull = (Nulls[k] != 0);
- paramLI->value = (Datum) Values[k];
- }
- paramLI->kind = PARAM_INVALID;
- }
- else
- state->es_param_list_info = NULL;
- res = _SPI_pquery (qdesc, state, ( i < qlen - 1 ) ? 0 : tcount);
- if ( res < 0 || i >= qlen - 1 )
- return (res);
- CommandCounterIncrement ();
- }
- }
-
- return (res);
-
+ queryTree = (Query *) (queryTree_list->qtrees[i]);
+ planTree = lfirst(planTree_list);
+
+ planTree_list = lnext(planTree_list);
+
+ if (queryTree->commandType == CMD_UTILITY)
+ {
+ ProcessUtility(queryTree->utilityStmt, None);
+ if (i < qlen - 1)
+ CommandCounterIncrement();
+ else
+ return (SPI_OK_UTILITY);
+ }
+ else
+ {
+ qdesc = CreateQueryDesc(queryTree, planTree,
+ (i < qlen - 1) ? None : SPI);
+ state = CreateExecutorState();
+ if (nargs > 0)
+ {
+ ParamListInfo paramLI = (ParamListInfo) palloc((nargs + 1) *
+ sizeof(ParamListInfoData));
+
+ state->es_param_list_info = paramLI;
+ for (k = 0; k < plan->nargs; paramLI++, k++)
+ {
+ paramLI->kind = PARAM_NUM;
+ paramLI->id = k + 1;
+ paramLI->isnull = (Nulls[k] != 0);
+ paramLI->value = (Datum) Values[k];
+ }
+ paramLI->kind = PARAM_INVALID;
+ }
+ else
+ state->es_param_list_info = NULL;
+ res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount);
+ if (res < 0 || i >= qlen - 1)
+ return (res);
+ CommandCounterIncrement();
+ }
+ }
+
+ return (res);
+
}
static int
-_SPI_pquery (QueryDesc *queryDesc, EState *state, int tcount)
+_SPI_pquery(QueryDesc * queryDesc, EState * state, int tcount)
{
- Query *parseTree;
- Plan *plan;
- int operation;
- TupleDesc tupdesc;
- bool isRetrieveIntoPortal = false;
- bool isRetrieveIntoRelation = false;
- char* intoName = NULL;
- int res;
-
- parseTree = queryDesc->parsetree;
- plan = queryDesc->plantree;
- operation = queryDesc->operation;
-
- switch (operation)
- {
- case CMD_SELECT:
- res = SPI_OK_SELECT;
- if (parseTree->isPortal)
- {
- isRetrieveIntoPortal = true;
- intoName = parseTree->into;
- parseTree->isBinary = false; /* */
-
- return (SPI_ERROR_CURSOR);
-
- }
- else if (parseTree->into != NULL) /* select into table */
- {
- res = SPI_OK_SELINTO;
- isRetrieveIntoRelation = true;
- }
- break;
- case CMD_INSERT:
- res = SPI_OK_INSERT;
- break;
- case CMD_DELETE:
- res = SPI_OK_DELETE;
- break;
- case CMD_UPDATE:
- res = SPI_OK_UPDATE;
- break;
- default:
- return (SPI_ERROR_OPUNKNOWN);
- }
-
- if ( state == NULL ) /* plan preparation */
- return (res);
+ Query *parseTree;
+ Plan *plan;
+ int operation;
+ TupleDesc tupdesc;
+ bool isRetrieveIntoPortal = false;
+ bool isRetrieveIntoRelation = false;
+ char *intoName = NULL;
+ int res;
+
+ parseTree = queryDesc->parsetree;
+ plan = queryDesc->plantree;
+ operation = queryDesc->operation;
+
+ switch (operation)
+ {
+ case CMD_SELECT:
+ res = SPI_OK_SELECT;
+ if (parseTree->isPortal)
+ {
+ isRetrieveIntoPortal = true;
+ intoName = parseTree->into;
+ parseTree->isBinary = false; /* */
+
+ return (SPI_ERROR_CURSOR);
+
+ }
+ else if (parseTree->into != NULL) /* select into table */
+ {
+ res = SPI_OK_SELINTO;
+ isRetrieveIntoRelation = true;
+ }
+ break;
+ case CMD_INSERT:
+ res = SPI_OK_INSERT;
+ break;
+ case CMD_DELETE:
+ res = SPI_OK_DELETE;
+ break;
+ case CMD_UPDATE:
+ res = SPI_OK_UPDATE;
+ break;
+ default:
+ return (SPI_ERROR_OPUNKNOWN);
+ }
+
+ if (state == NULL) /* plan preparation */
+ return (res);
#ifdef SPI_EXECUTOR_STATS
- if ( ShowExecutorStats )
- ResetUsage ();
+ if (ShowExecutorStats)
+ ResetUsage();
#endif
- tupdesc = ExecutorStart (queryDesc, state);
-
- /* Don't work currently */
- if (isRetrieveIntoPortal)
- {
- ProcessPortal(intoName,
- parseTree,
- plan,
- state,
- tupdesc,
- None);
- return (SPI_OK_CURSOR);
- }
-
- ExecutorRun (queryDesc, state, EXEC_RUN, tcount);
-
- _SPI_current->processed = state->es_processed;
- if ( operation == CMD_SELECT && queryDesc->dest == SPI )
- {
- if ( _SPI_checktuples (isRetrieveIntoRelation) )
- elog (FATAL, "SPI_select: # of processed tuples check failed");
- }
-
- ExecutorEnd (queryDesc, state);
-
+ tupdesc = ExecutorStart(queryDesc, state);
+
+ /* Don't work currently */
+ if (isRetrieveIntoPortal)
+ {
+ ProcessPortal(intoName,
+ parseTree,
+ plan,
+ state,
+ tupdesc,
+ None);
+ return (SPI_OK_CURSOR);
+ }
+
+ ExecutorRun(queryDesc, state, EXEC_RUN, tcount);
+
+ _SPI_current->processed = state->es_processed;
+ if (operation == CMD_SELECT && queryDesc->dest == SPI)
+ {
+ if (_SPI_checktuples(isRetrieveIntoRelation))
+ elog(FATAL, "SPI_select: # of processed tuples check failed");
+ }
+
+ ExecutorEnd(queryDesc, state);
+
#ifdef SPI_EXECUTOR_STATS
- if ( ShowExecutorStats )
- {
- fprintf (stderr, "! Executor Stats:\n");
- ShowUsage ();
- }
+ if (ShowExecutorStats)
+ {
+ fprintf(stderr, "! Executor Stats:\n");
+ ShowUsage();
+ }
#endif
-
- if ( queryDesc->dest == SPI )
- {
- SPI_processed = _SPI_current->processed;
- SPI_tuptable = _SPI_current->tuptable;
- }
-
- return (res);
+
+ if (queryDesc->dest == SPI)
+ {
+ SPI_processed = _SPI_current->processed;
+ SPI_tuptable = _SPI_current->tuptable;
+ }
+
+ return (res);
}
#if 0
static void
-_SPI_fetch (FetchStmt *stmt)
+_SPI_fetch(FetchStmt * stmt)
{
- char *name = stmt->portalname;
- int feature = ( stmt->direction == FORWARD ) ? EXEC_FOR : EXEC_BACK;
- int count = stmt->howMany;
- Portal portal;
- QueryDesc *queryDesc;
- EState *state;
- MemoryContext context;
-
- if ( name == NULL)
- elog (FATAL, "SPI_fetch from blank portal unsupported");
-
- portal = GetPortalByName (name);
- if ( !PortalIsValid (portal) )
- elog (FATAL, "SPI_fetch: portal \"%s\" not found", name);
-
- context = MemoryContextSwitchTo((MemoryContext)PortalGetHeapMemory(portal));
-
- queryDesc = PortalGetQueryDesc(portal);
- state = PortalGetState(portal);
-
- ExecutorRun(queryDesc, state, feature, count);
-
- MemoryContextSwitchTo (context); /* switch to the normal Executor context */
-
- _SPI_current->processed = state->es_processed;
- if ( _SPI_checktuples (false) )
- elog (FATAL, "SPI_fetch: # of processed tuples check failed");
-
- SPI_processed = _SPI_current->processed;
- SPI_tuptable = _SPI_current->tuptable;
-
+ char *name = stmt->portalname;
+ int feature = (stmt->direction == FORWARD) ? EXEC_FOR : EXEC_BACK;
+ int count = stmt->howMany;
+ Portal portal;
+ QueryDesc *queryDesc;
+ EState *state;
+ MemoryContext context;
+
+ if (name == NULL)
+ elog(FATAL, "SPI_fetch from blank portal unsupported");
+
+ portal = GetPortalByName(name);
+ if (!PortalIsValid(portal))
+ elog(FATAL, "SPI_fetch: portal \"%s\" not found", name);
+
+ context = MemoryContextSwitchTo((MemoryContext) PortalGetHeapMemory(portal));
+
+ queryDesc = PortalGetQueryDesc(portal);
+ state = PortalGetState(portal);
+
+ ExecutorRun(queryDesc, state, feature, count);
+
+ MemoryContextSwitchTo(context); /* switch to the normal Executor
+ * context */
+
+ _SPI_current->processed = state->es_processed;
+ if (_SPI_checktuples(false))
+ elog(FATAL, "SPI_fetch: # of processed tuples check failed");
+
+ SPI_processed = _SPI_current->processed;
+ SPI_tuptable = _SPI_current->tuptable;
+
}
+
#endif
-static MemoryContext
-_SPI_execmem ()
+static MemoryContext
+_SPI_execmem()
{
- MemoryContext oldcxt;
- PortalHeapMemory phmem;
-
- phmem = PortalGetHeapMemory (_SPI_current->portal);
- oldcxt = MemoryContextSwitchTo ((MemoryContext)phmem);
-
- return (oldcxt);
-
+ MemoryContext oldcxt;
+ PortalHeapMemory phmem;
+
+ phmem = PortalGetHeapMemory(_SPI_current->portal);
+ oldcxt = MemoryContextSwitchTo((MemoryContext) phmem);
+
+ return (oldcxt);
+
}
-static MemoryContext
-_SPI_procmem ()
+static MemoryContext
+_SPI_procmem()
{
- MemoryContext oldcxt;
- PortalVariableMemory pvmem;
-
- pvmem = PortalGetVariableMemory (_SPI_current->portal);
- oldcxt = MemoryContextSwitchTo ((MemoryContext)pvmem);
-
- return (oldcxt);
-
+ MemoryContext oldcxt;
+ PortalVariableMemory pvmem;
+
+ pvmem = PortalGetVariableMemory(_SPI_current->portal);
+ oldcxt = MemoryContextSwitchTo((MemoryContext) pvmem);
+
+ return (oldcxt);
+
}
/*
@@ -781,108 +792,110 @@ _SPI_procmem ()
*
*/
static int
-_SPI_begin_call (bool execmem)
+_SPI_begin_call(bool execmem)
{
- if ( _SPI_curid + 1 != _SPI_connected )
- return (SPI_ERROR_UNCONNECTED);
- _SPI_curid++;
- if ( _SPI_current != &(_SPI_stack[_SPI_curid]) )
- elog (FATAL, "SPI: stack corrupted");
-
- if ( execmem ) /* switch to the Executor memory context */
- {
- _SPI_execmem ();
- StartPortalAllocMode (DefaultAllocMode, 0);
- }
-
- return (0);
+ if (_SPI_curid + 1 != _SPI_connected)
+ return (SPI_ERROR_UNCONNECTED);
+ _SPI_curid++;
+ if (_SPI_current != &(_SPI_stack[_SPI_curid]))
+ elog(FATAL, "SPI: stack corrupted");
+
+ if (execmem) /* switch to the Executor memory context */
+ {
+ _SPI_execmem();
+ StartPortalAllocMode(DefaultAllocMode, 0);
+ }
+
+ return (0);
}
static int
-_SPI_end_call (bool procmem)
+_SPI_end_call(bool procmem)
{
- /*
- * We' returning to procedure where _SPI_curid == _SPI_connected - 1
- */
- _SPI_curid--;
-
- if ( _SPI_current->qtlist) /* free _SPI_plan allocations */
- {
- free (_SPI_current->qtlist->qtrees);
- free (_SPI_current->qtlist);
- _SPI_current->qtlist = NULL;
- }
-
- if ( procmem ) /* switch to the procedure memory context */
- { /* but free Executor memory before */
- EndPortalAllocMode ();
- _SPI_procmem ();
- }
-
- return (0);
+
+ /*
+ * We' returning to procedure where _SPI_curid == _SPI_connected - 1
+ */
+ _SPI_curid--;
+
+ if (_SPI_current->qtlist) /* free _SPI_plan allocations */
+ {
+ free(_SPI_current->qtlist->qtrees);
+ free(_SPI_current->qtlist);
+ _SPI_current->qtlist = NULL;
+ }
+
+ if (procmem) /* switch to the procedure memory context */
+ { /* but free Executor memory before */
+ EndPortalAllocMode();
+ _SPI_procmem();
+ }
+
+ return (0);
}
-static bool
-_SPI_checktuples (bool isRetrieveIntoRelation)
+static bool
+_SPI_checktuples(bool isRetrieveIntoRelation)
{
- uint32 processed = _SPI_current->processed;
- SPITupleTable *tuptable = _SPI_current->tuptable;
- bool failed = false;
-
- if ( processed == 0 )
- {
- if ( tuptable != NULL )
- failed = true;
- }
- else /* some tuples were processed */
- {
- if ( tuptable == NULL ) /* spi_printtup was not called */
- {
- if ( !isRetrieveIntoRelation )
- failed = true;
- }
- else if ( isRetrieveIntoRelation )
- failed = true;
- else if ( processed != ( tuptable->alloced - tuptable->free ) )
- failed = true;
- }
-
- return (failed);
+ uint32 processed = _SPI_current->processed;
+ SPITupleTable *tuptable = _SPI_current->tuptable;
+ bool failed = false;
+
+ if (processed == 0)
+ {
+ if (tuptable != NULL)
+ failed = true;
+ }
+ else
+/* some tuples were processed */
+ {
+ if (tuptable == NULL) /* spi_printtup was not called */
+ {
+ if (!isRetrieveIntoRelation)
+ failed = true;
+ }
+ else if (isRetrieveIntoRelation)
+ failed = true;
+ else if (processed != (tuptable->alloced - tuptable->free))
+ failed = true;
+ }
+
+ return (failed);
}
-
+
static _SPI_plan *
-_SPI_copy_plan (_SPI_plan *plan, bool local)
+_SPI_copy_plan(_SPI_plan * plan, bool local)
{
- _SPI_plan *newplan;
- MemoryContext oldcxt;
- int i;
-
- if ( local )
- oldcxt = MemoryContextSwitchTo ((MemoryContext)
- PortalGetVariableMemory (_SPI_current->portal));
- else
- oldcxt = MemoryContextSwitchTo (TopMemoryContext);
-
- newplan = (_SPI_plan *) palloc (sizeof (_SPI_plan));
- newplan->qtlist = (QueryTreeList*) palloc (sizeof (QueryTreeList));
- newplan->qtlist->len = plan->qtlist->len;
- newplan->qtlist->qtrees = (Query**) palloc (plan->qtlist->len *
- sizeof (Query*));
- for (i = 0; i < plan->qtlist->len; i++)
- newplan->qtlist->qtrees[i] = (Query *)
- copyObject (plan->qtlist->qtrees[i]);
-
- newplan->ptlist = (List *) copyObject (plan->ptlist);
- newplan->nargs = plan->nargs;
- if ( plan->nargs > 0 )
- {
- newplan->argtypes = (Oid *) palloc (plan->nargs * sizeof (Oid));
- memcpy (newplan->argtypes, plan->argtypes, plan->nargs * sizeof (Oid));
- }
- else
- newplan->argtypes = NULL;
-
- MemoryContextSwitchTo (oldcxt);
-
- return (newplan);
+ _SPI_plan *newplan;
+ MemoryContext oldcxt;
+ int i;
+
+ if (local)
+ oldcxt = MemoryContextSwitchTo((MemoryContext)
+ PortalGetVariableMemory(_SPI_current->portal));
+ else
+ oldcxt = MemoryContextSwitchTo(TopMemoryContext);
+
+ newplan = (_SPI_plan *) palloc(sizeof(_SPI_plan));
+ newplan->qtlist = (QueryTreeList *) palloc(sizeof(QueryTreeList));
+ newplan->qtlist->len = plan->qtlist->len;
+ newplan->qtlist->qtrees = (Query **) palloc(plan->qtlist->len *
+ sizeof(Query *));
+ for (i = 0; i < plan->qtlist->len; i++)
+ newplan->qtlist->qtrees[i] = (Query *)
+ copyObject(plan->qtlist->qtrees[i]);
+
+ newplan->ptlist = (List *) copyObject(plan->ptlist);
+ newplan->nargs = plan->nargs;
+ if (plan->nargs > 0)
+ {
+ newplan->argtypes = (Oid *) palloc(plan->nargs * sizeof(Oid));
+ memcpy(newplan->argtypes, plan->argtypes, plan->nargs * sizeof(Oid));
+ }
+ else
+ newplan->argtypes = NULL;
+
+ MemoryContextSwitchTo(oldcxt);
+
+ return (newplan);
}
diff --git a/src/backend/lib/bit.c b/src/backend/lib/bit.c
index 680f349a520..439566c0b75 100644
--- a/src/backend/lib/bit.c
+++ b/src/backend/lib/bit.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* bit.c--
- * Standard bit array code.
+ * Standard bit array code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/lib/Attic/bit.c,v 1.4 1996/11/06 08:27:09 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/lib/Attic/bit.c,v 1.5 1997/09/07 04:41:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,27 +22,26 @@
void
BitArraySetBit(BitArray bitArray, BitIndex bitIndex)
-{
- bitArray[bitIndex/BitsPerByte]
+{
+ bitArray[bitIndex / BitsPerByte]
|= (1 << (BitsPerByte - (bitIndex % BitsPerByte) - 1));
- return;
+ return;
}
void
BitArrayClearBit(BitArray bitArray, BitIndex bitIndex)
{
- bitArray[bitIndex/BitsPerByte]
+ bitArray[bitIndex / BitsPerByte]
&= ~(1 << (BitsPerByte - (bitIndex % BitsPerByte) - 1));
- return;
+ return;
}
bool
BitArrayBitIsSet(BitArray bitArray, BitIndex bitIndex)
-{
- return( (bool) (((bitArray[bitIndex / BitsPerByte] &
- (1 << (BitsPerByte - (bitIndex % BitsPerByte)
- - 1)
- )
- ) != 0 ) ? 1 : 0) );
+{
+ return ((bool) (((bitArray[bitIndex / BitsPerByte] &
+ (1 << (BitsPerByte - (bitIndex % BitsPerByte)
+ - 1)
+ )
+ ) != 0) ? 1 : 0));
}
-
diff --git a/src/backend/lib/dllist.c b/src/backend/lib/dllist.c
index b8dd14a231b..70feee02bb9 100644
--- a/src/backend/lib/dllist.c
+++ b/src/backend/lib/dllist.c
@@ -1,15 +1,15 @@
/*-------------------------------------------------------------------------
*
* dllist.c--
- * this is a simple doubly linked list implementation
- * replaces the old simplelists stuff
- * the elements of the lists are void*
+ * this is a simple doubly linked list implementation
+ * replaces the old simplelists stuff
+ * the elements of the lists are void*
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.5 1997/08/19 21:31:16 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.6 1997/09/07 04:41:56 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,191 +18,197 @@
#include <lib/dllist.h>
-Dllist*
+Dllist *
DLNewList(void)
{
- Dllist* l;
+ Dllist *l;
- l = malloc(sizeof(Dllist));
- l->dll_head = 0;
- l->dll_tail = 0;
+ l = malloc(sizeof(Dllist));
+ l->dll_head = 0;
+ l->dll_tail = 0;
- return l;
+ return l;
}
- /* free up a list and all the nodes in it*/
+ /* free up a list and all the nodes in it */
void
-DLFreeList(Dllist* l)
+DLFreeList(Dllist * l)
{
- Dlelem* curr;
+ Dlelem *curr;
- while ( (curr = DLRemHead(l)) != 0)
- free(curr);
+ while ((curr = DLRemHead(l)) != 0)
+ free(curr);
- free(l);
+ free(l);
}
-Dlelem*
-DLNewElem(void* val)
+Dlelem *
+DLNewElem(void *val)
{
- Dlelem* e;
- e = malloc(sizeof(Dlelem));
- e->dle_next = 0;
- e->dle_prev = 0;
- e->dle_val = val;
- e->dle_list = 0;
- return e;
+ Dlelem *e;
+
+ e = malloc(sizeof(Dlelem));
+ e->dle_next = 0;
+ e->dle_prev = 0;
+ e->dle_val = val;
+ e->dle_list = 0;
+ return e;
}
void
-DLFreeElem(Dlelem* e)
+DLFreeElem(Dlelem * e)
{
- free(e);
+ free(e);
}
-Dlelem*
-DLGetHead(Dllist* l)
+Dlelem *
+DLGetHead(Dllist * l)
{
- return (l ? l->dll_head : 0);
+ return (l ? l->dll_head : 0);
}
/* get the value stored in the first element */
#ifdef NOT_USED
-void*
-DLGetHeadVal(Dllist* l)
+void *
+DLGetHeadVal(Dllist * l)
{
- Dlelem* e = DLGetHead(l);
-
- return (e ? e->dle_val : 0);
+ Dlelem *e = DLGetHead(l);
+
+ return (e ? e->dle_val : 0);
}
+
#endif
-Dlelem*
-DLGetTail(Dllist* l)
+Dlelem *
+DLGetTail(Dllist * l)
{
- return (l ? l->dll_tail : 0);
+ return (l ? l->dll_tail : 0);
}
/* get the value stored in the first element */
#ifdef NOT_USED
-void*
-DLGetTailVal(Dllist* l)
+void *
+DLGetTailVal(Dllist * l)
{
- Dlelem* e = DLGetTail(l);
-
- return (e ? e->dle_val : 0);
+ Dlelem *e = DLGetTail(l);
+
+ return (e ? e->dle_val : 0);
}
+
#endif
-Dlelem*
-DLGetPred(Dlelem* e) /* get predecessor */
+Dlelem *
+DLGetPred(Dlelem * e) /* get predecessor */
{
- return (e ? e->dle_prev : 0);
+ return (e ? e->dle_prev : 0);
}
-Dlelem*
-DLGetSucc(Dlelem* e) /* get successor */
+Dlelem *
+DLGetSucc(Dlelem * e) /* get successor */
{
- return (e ? e->dle_next : 0);
+ return (e ? e->dle_next : 0);
}
void
-DLRemove(Dlelem* e)
+DLRemove(Dlelem * e)
{
- Dllist* l;
+ Dllist *l;
- if (e->dle_prev)
- e->dle_prev->dle_next = e->dle_next;
- if (e->dle_next)
- e->dle_next->dle_prev = e->dle_prev;
+ if (e->dle_prev)
+ e->dle_prev->dle_next = e->dle_next;
+ if (e->dle_next)
+ e->dle_next->dle_prev = e->dle_prev;
- /* check to see if we're removing the head or tail */
- l = e->dle_list;
- if (e == l->dll_head)
- DLRemHead(l);
- if (e == l->dll_tail)
- DLRemTail(l);
+ /* check to see if we're removing the head or tail */
+ l = e->dle_list;
+ if (e == l->dll_head)
+ DLRemHead(l);
+ if (e == l->dll_tail)
+ DLRemTail(l);
}
-void
-DLAddHead(Dllist* l, Dlelem* e)
+void
+DLAddHead(Dllist * l, Dlelem * e)
{
- e->dle_list = l;
-
- if (l->dll_head) {
- l->dll_head->dle_prev = e;
- e->dle_next = l->dll_head;
- }
- e->dle_prev = 0;
- l->dll_head = e;
-
- if (l->dll_tail == 0) /* if this is first element added */
- l->dll_tail = l->dll_head;
+ e->dle_list = l;
+
+ if (l->dll_head)
+ {
+ l->dll_head->dle_prev = e;
+ e->dle_next = l->dll_head;
+ }
+ e->dle_prev = 0;
+ l->dll_head = e;
+
+ if (l->dll_tail == 0) /* if this is first element added */
+ l->dll_tail = l->dll_head;
}
void
-DLAddTail(Dllist* l, Dlelem* e)
+DLAddTail(Dllist * l, Dlelem * e)
{
- e->dle_list = l;
-
- if (l->dll_tail) {
- l->dll_tail->dle_next = e;
- e->dle_prev = l->dll_tail;
- }
- e->dle_next = 0;
- l->dll_tail = e;
-
- if (l->dll_head == 0) /* if this is first element added */
- l->dll_head = l->dll_tail;
+ e->dle_list = l;
+
+ if (l->dll_tail)
+ {
+ l->dll_tail->dle_next = e;
+ e->dle_prev = l->dll_tail;
+ }
+ e->dle_next = 0;
+ l->dll_tail = e;
+
+ if (l->dll_head == 0) /* if this is first element added */
+ l->dll_head = l->dll_tail;
}
-Dlelem*
-DLRemHead(Dllist* l)
+Dlelem *
+DLRemHead(Dllist * l)
{
- /* remove and return the head */
- Dlelem* result;
+ /* remove and return the head */
+ Dlelem *result;
- if (l->dll_head == 0)
- return 0;
+ if (l->dll_head == 0)
+ return 0;
- result = l->dll_head;
- if (l->dll_head->dle_next) {
- l->dll_head->dle_next->dle_prev = 0;
- }
+ result = l->dll_head;
+ if (l->dll_head->dle_next)
+ {
+ l->dll_head->dle_next->dle_prev = 0;
+ }
- l->dll_head = l->dll_head->dle_next;
+ l->dll_head = l->dll_head->dle_next;
- result->dle_next = 0;
- result->dle_list = 0;
-
- if (result == l->dll_tail) /* if the head is also the tail */
- l->dll_tail = 0;
+ result->dle_next = 0;
+ result->dle_list = 0;
- return result;
+ if (result == l->dll_tail) /* if the head is also the tail */
+ l->dll_tail = 0;
+
+ return result;
}
-Dlelem*
-DLRemTail(Dllist* l)
+Dlelem *
+DLRemTail(Dllist * l)
{
- /* remove and return the tail */
- Dlelem* result;
+ /* remove and return the tail */
+ Dlelem *result;
- if (l->dll_tail == 0 )
- return 0;
+ if (l->dll_tail == 0)
+ return 0;
- result = l->dll_tail;
- if (l->dll_tail->dle_prev) {
- l->dll_tail->dle_prev->dle_next = 0;
- }
- l->dll_tail = l->dll_tail->dle_prev;
+ result = l->dll_tail;
+ if (l->dll_tail->dle_prev)
+ {
+ l->dll_tail->dle_prev->dle_next = 0;
+ }
+ l->dll_tail = l->dll_tail->dle_prev;
- result->dle_prev = 0;
- result->dle_list = 0;
+ result->dle_prev = 0;
+ result->dle_list = 0;
- if (result == l->dll_head) /* if the tail is also the head */
- l->dll_head = 0;
+ if (result == l->dll_head) /* if the tail is also the head */
+ l->dll_head = 0;
- return result;
+ return result;
}
-
diff --git a/src/backend/lib/fstack.c b/src/backend/lib/fstack.c
index 68f1505b167..f97d467fe92 100644
--- a/src/backend/lib/fstack.c
+++ b/src/backend/lib/fstack.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* fstack.c--
- * Fixed format stack definitions.
+ * Fixed format stack definitions.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/lib/Attic/fstack.c,v 1.4 1997/06/06 22:02:37 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/lib/Attic/fstack.c,v 1.5 1997/09/07 04:42:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,25 +21,25 @@
/*
* FixedItemIsValid --
- * True iff item is valid.
+ * True iff item is valid.
*/
#define FixedItemIsValid(item) PointerIsValid(item)
/*
* FixedStackGetItemBase --
- * Returns base of enclosing structure.
+ * Returns base of enclosing structure.
*/
#define FixedStackGetItemBase(stack, item) \
- ((Pointer)((char *)(item) - (stack)->offset))
+ ((Pointer)((char *)(item) - (stack)->offset))
/*
* FixedStackGetItem --
- * Returns item of given pointer to enclosing structure.
+ * Returns item of given pointer to enclosing structure.
*/
#define FixedStackGetItem(stack, pointer) \
- ((FixedItem)((char *)(pointer) + (stack)->offset))
+ ((FixedItem)((char *)(pointer) + (stack)->offset))
-#define FixedStackIsValid(stack) ((bool)PointerIsValid(stack))
+#define FixedStackIsValid(stack) ((bool)PointerIsValid(stack))
/*
* External functions
@@ -48,99 +48,105 @@
void
FixedStackInit(FixedStack stack, Offset offset)
{
- AssertArg(PointerIsValid(stack));
-
- stack->top = NULL;
- stack->offset = offset;
+ AssertArg(PointerIsValid(stack));
+
+ stack->top = NULL;
+ stack->offset = offset;
}
Pointer
FixedStackPop(FixedStack stack)
{
- Pointer pointer;
-
- AssertArg(FixedStackIsValid(stack));
-
- if (!PointerIsValid(stack->top)) {
- return (NULL);
- }
-
- pointer = FixedStackGetItemBase(stack, stack->top);
- stack->top = stack->top->next;
-
- return (pointer);
+ Pointer pointer;
+
+ AssertArg(FixedStackIsValid(stack));
+
+ if (!PointerIsValid(stack->top))
+ {
+ return (NULL);
+ }
+
+ pointer = FixedStackGetItemBase(stack, stack->top);
+ stack->top = stack->top->next;
+
+ return (pointer);
}
void
FixedStackPush(FixedStack stack, Pointer pointer)
{
- FixedItem item = FixedStackGetItem(stack, pointer);
-
- AssertArg(FixedStackIsValid(stack));
- AssertArg(PointerIsValid(pointer));
-
- item->next = stack->top;
- stack->top = item;
+ FixedItem item = FixedStackGetItem(stack, pointer);
+
+ AssertArg(FixedStackIsValid(stack));
+ AssertArg(PointerIsValid(pointer));
+
+ item->next = stack->top;
+ stack->top = item;
}
-#ifndef NO_ASSERT_CHECKING
+#ifndef NO_ASSERT_CHECKING
/*
* FixedStackContains --
- * True iff ordered stack contains given element.
+ * True iff ordered stack contains given element.
*
* Note:
- * This is inefficient. It is intended for debugging use only.
+ * This is inefficient. It is intended for debugging use only.
*
* Exceptions:
- * BadArg if stack is invalid.
- * BadArg if pointer is invalid.
+ * BadArg if stack is invalid.
+ * BadArg if pointer is invalid.
*/
-static bool
+static bool
FixedStackContains(FixedStack stack, Pointer pointer)
{
- FixedItem next;
- FixedItem item;
-
- AssertArg(FixedStackIsValid(stack));
- AssertArg(PointerIsValid(pointer));
-
- item = FixedStackGetItem(stack, pointer);
-
- for (next = stack->top; FixedItemIsValid(next); next = next->next) {
- if (next == item) {
- return (true);
+ FixedItem next;
+ FixedItem item;
+
+ AssertArg(FixedStackIsValid(stack));
+ AssertArg(PointerIsValid(pointer));
+
+ item = FixedStackGetItem(stack, pointer);
+
+ for (next = stack->top; FixedItemIsValid(next); next = next->next)
+ {
+ if (next == item)
+ {
+ return (true);
+ }
}
- }
- return (false);
+ return (false);
}
+
#endif
Pointer
FixedStackGetTop(FixedStack stack)
{
- AssertArg(FixedStackIsValid(stack));
-
- if (!PointerIsValid(stack->top)) {
- return (NULL);
- }
-
- return (FixedStackGetItemBase(stack, stack->top));
+ AssertArg(FixedStackIsValid(stack));
+
+ if (!PointerIsValid(stack->top))
+ {
+ return (NULL);
+ }
+
+ return (FixedStackGetItemBase(stack, stack->top));
}
Pointer
FixedStackGetNext(FixedStack stack, Pointer pointer)
{
- FixedItem item;
-
- /* AssertArg(FixedStackIsValid(stack)); */
- /* AssertArg(PointerIsValid(pointer)); */
- AssertArg(FixedStackContains(stack, pointer));
-
- item = FixedStackGetItem(stack, pointer)->next;
-
- if (!PointerIsValid(item)) {
- return (NULL);
- }
-
- return(FixedStackGetItemBase(stack, item));
+ FixedItem item;
+
+ /* AssertArg(FixedStackIsValid(stack)); */
+ /* AssertArg(PointerIsValid(pointer)); */
+ AssertArg(FixedStackContains(stack, pointer));
+
+ item = FixedStackGetItem(stack, pointer)->next;
+
+ if (!PointerIsValid(item))
+ {
+ return (NULL);
+ }
+
+ return (FixedStackGetItemBase(stack, item));
}
diff --git a/src/backend/lib/hasht.c b/src/backend/lib/hasht.c
index baceabfcf7a..4e12dcf30eb 100644
--- a/src/backend/lib/hasht.c
+++ b/src/backend/lib/hasht.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* hasht.c--
- * hash table related functions that are not directly supported
- * by the hashing packages under utils/hash.
+ * hash table related functions that are not directly supported
+ * by the hashing packages under utils/hash.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/lib/Attic/hasht.c,v 1.4 1997/08/12 22:52:42 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/lib/Attic/hasht.c,v 1.5 1997/09/07 04:42:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,29 +19,31 @@
#include <lib/hasht.h>
/* -----------------------------------
- * HashTableWalk
+ * HashTableWalk
*
- * call function on every element in hashtable
- * one extra argument, arg may be supplied
+ * call function on every element in hashtable
+ * one extra argument, arg may be supplied
* -----------------------------------
*/
void
-HashTableWalk(HTAB *hashtable, HashtFunc function, int arg)
+HashTableWalk(HTAB * hashtable, HashtFunc function, int arg)
{
- long *hashent;
- long *data;
- int keysize;
-
- keysize = hashtable->hctl->keysize;
- hash_seq((HTAB *)NULL);
- while ((hashent = hash_seq(hashtable)) != (long *) TRUE) {
- if (hashent == NULL)
- elog(FATAL, "error in HashTableWalk.");
- /*
- * XXX the corresponding hash table insertion does NOT
- * LONGALIGN -- make sure the keysize is ok
- */
- data = (long *) LONGALIGN((char*) hashent + keysize);
- (*function)(data, arg);
- }
+ long *hashent;
+ long *data;
+ int keysize;
+
+ keysize = hashtable->hctl->keysize;
+ hash_seq((HTAB *) NULL);
+ while ((hashent = hash_seq(hashtable)) != (long *) TRUE)
+ {
+ if (hashent == NULL)
+ elog(FATAL, "error in HashTableWalk.");
+
+ /*
+ * XXX the corresponding hash table insertion does NOT LONGALIGN
+ * -- make sure the keysize is ok
+ */
+ data = (long *) LONGALIGN((char *) hashent + keysize);
+ (*function) (data, arg);
+ }
}
diff --git a/src/backend/lib/lispsort.c b/src/backend/lib/lispsort.c
index 11acc5683b2..bf346ecc1a6 100644
--- a/src/backend/lib/lispsort.c
+++ b/src/backend/lib/lispsort.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/lib/Attic/lispsort.c,v 1.4 1997/08/19 21:31:18 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/lib/Attic/lispsort.c,v 1.5 1997/09/07 04:42:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,38 +24,41 @@
#ifdef NOT_USED
/*
-** lisp_qsort: Takes a lisp list as input, copies it into an array of lisp
-** nodes which it sorts via qsort() with the comparison function
-** as passed into lisp_qsort(), and returns a new list with
-** the nodes sorted. The old list is *not* freed or modified (?)
+** lisp_qsort: Takes a lisp list as input, copies it into an array of lisp
+** nodes which it sorts via qsort() with the comparison function
+** as passed into lisp_qsort(), and returns a new list with
+** the nodes sorted. The old list is *not* freed or modified (?)
*/
-List *lisp_qsort(List *the_list, /* the list to be sorted */
- int (*compare)()) /* function to compare two nodes */
+List *
+lisp_qsort(List * the_list, /* the list to be sorted */
+ int (*compare) ()) /* function to compare two nodes */
{
- int i;
- size_t num;
- List **nodearray;
- List *tmp, *output;
-
- /* find size of list */
- num = length(the_list);
- if (num < 2)
- return(copyObject(the_list));
-
- /* copy elements of the list into an array */
- nodearray = (List **) palloc(num * sizeof(List *));
-
- for (tmp = the_list, i = 0; tmp != NIL; tmp = lnext(tmp), i++)
- nodearray[i] = copyObject(lfirst(tmp));
-
- /* sort the array */
- pg_qsort(nodearray, num, sizeof(List *), compare);
-
- /* lcons together the array elements */
- output = NIL;
- for (i = num - 1; i >= 0; i--)
- output = lcons(nodearray[i], output);
-
- return(output);
+ int i;
+ size_t num;
+ List **nodearray;
+ List *tmp,
+ *output;
+
+ /* find size of list */
+ num = length(the_list);
+ if (num < 2)
+ return (copyObject(the_list));
+
+ /* copy elements of the list into an array */
+ nodearray = (List **) palloc(num * sizeof(List *));
+
+ for (tmp = the_list, i = 0; tmp != NIL; tmp = lnext(tmp), i++)
+ nodearray[i] = copyObject(lfirst(tmp));
+
+ /* sort the array */
+ pg_qsort(nodearray, num, sizeof(List *), compare);
+
+ /* lcons together the array elements */
+ output = NIL;
+ for (i = num - 1; i >= 0; i--)
+ output = lcons(nodearray[i], output);
+
+ return (output);
}
+
#endif
diff --git a/src/backend/lib/qsort.c b/src/backend/lib/qsort.c
index e0f3cbbb2c2..ff2bbfa16d9 100644
--- a/src/backend/lib/qsort.c
+++ b/src/backend/lib/qsort.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* qsort.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/lib/Attic/qsort.c,v 1.2 1996/11/06 08:27:15 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/lib/Attic/qsort.c,v 1.3 1997/09/07 04:42:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,22 +19,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -45,8 +45,9 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)qsort.c 5.9 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
+static char sccsid[] = "@(#)qsort.c 5.9 (Berkeley) 2/23/91";
+
+#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -58,21 +59,22 @@ static char sccsid[] = "@(#)qsort.c 5.9 (Berkeley) 2/23/91";
* MTHRESH is the smallest partition for which we compare for a median
* value instead of using the middle value.
*/
-#define MTHRESH 6
+#define MTHRESH 6
/*
* THRESH is the minimum number of entries in a partition for continued
* partitioning.
*/
-#define THRESH 4
+#define THRESH 4
-static void insertion_sort(char* bot, int nmemb, int size, int (*compar)());
-static void quick_sort(char* bot, int nmemb, int size, int (*compar)());
+static void insertion_sort(char *bot, int nmemb, int size, int (*compar) ());
+static void quick_sort(char *bot, int nmemb, int size, int (*compar) ());
-void pg_qsort(void *bot,
- size_t nmemb,
- size_t size,
- int (*compar)(void *, void *))
+void
+pg_qsort(void *bot,
+ size_t nmemb,
+ size_t size,
+ int (*compar) (void *, void *))
{
if (nmemb <= 1)
@@ -85,19 +87,19 @@ void pg_qsort(void *bot,
}
/*
- * Swap two areas of size number of bytes. Although qsort(3) permits random
+ * Swap two areas of size number of bytes. Although qsort(3) permits random
* blocks of memory to be sorted, sorting pointers is almost certainly the
* common case (and, were it not, could easily be made so). Regardless, it
* isn't worth optimizing; the SWAP's get sped up by the cache, and pointer
* arithmetic gets lost in the time required for comparison function calls.
*/
-#define SWAP(a, b) { \
- cnt = size; \
- do { \
- ch = *a; \
- *a++ = *b; \
- *b++ = ch; \
- } while (--cnt); \
+#define SWAP(a, b) { \
+ cnt = size; \
+ do { \
+ ch = *a; \
+ *a++ = *b; \
+ *b++ = ch; \
+ } while (--cnt); \
}
/*
@@ -114,24 +116,28 @@ void pg_qsort(void *bot,
* Knuth, page 122, equation 26), since the quicksort algorithm does less
* comparisons than the insertion sort.
*/
-#define SORT(bot, n) { \
- if (n > 1) \
- if (n == 2) { \
- t1 = bot + size; \
- if (compar(t1, bot) < 0) \
- SWAP(t1, bot); \
- } else \
- insertion_sort(bot, n, size, compar); \
+#define SORT(bot, n) { \
+ if (n > 1) \
+ if (n == 2) { \
+ t1 = bot + size; \
+ if (compar(t1, bot) < 0) \
+ SWAP(t1, bot); \
+ } else \
+ insertion_sort(bot, n, size, compar); \
}
static void
-quick_sort(char* bot, int nmemb, int size, int (*compar)())
+quick_sort(char *bot, int nmemb, int size, int (*compar) ())
{
- register int cnt;
+ register int cnt;
register u_char ch;
- register char *top, *mid, *t1, *t2;
- register int n1, n2;
- char *bsv;
+ register char *top,
+ *mid,
+ *t1,
+ *t2;
+ register int n1,
+ n2;
+ char *bsv;
/* bot and nmemb must already be set. */
partition:
@@ -145,7 +151,8 @@ partition:
* Vol. 3, page 123, Eq. 28). This test order gets the equalities
* right.
*/
- if (nmemb >= MTHRESH) {
+ if (nmemb >= MTHRESH)
+ {
n1 = compar(bot, mid);
n2 = compar(mid, top);
if (n1 < 0 && n2 > 0)
@@ -156,28 +163,33 @@ partition:
t1 = mid;
/* if mid element not selected, swap selection there */
- if (t1 != mid) {
+ if (t1 != mid)
+ {
SWAP(t1, mid);
mid -= size;
}
}
/* Standard quicksort, Knuth, Vol. 3, page 116, Algorithm Q. */
-#define didswap n1
-#define newbot t1
-#define replace t2
+#define didswap n1
+#define newbot t1
+#define replace t2
didswap = 0;
- for (bsv = bot;;) {
+ for (bsv = bot;;)
+ {
for (; bot < mid && compar(bot, mid) <= 0; bot += size);
- while (top > mid) {
- if (compar(mid, top) <= 0) {
+ while (top > mid)
+ {
+ if (compar(mid, top) <= 0)
+ {
top -= size;
continue;
}
- newbot = bot + size; /* value of bot after swap */
+ newbot = bot + size;/* value of bot after swap */
if (bot == mid) /* top <-> mid, mid == top */
replace = mid = top;
- else { /* bot <-> top */
+ else
+ { /* bot <-> top */
replace = top;
top -= size;
}
@@ -191,7 +203,7 @@ partition:
newbot = mid = bot; /* value of bot after swap */
top -= size;
-swap: SWAP(bot, replace);
+swap: SWAP(bot, replace);
bot = newbot;
didswap = 1;
}
@@ -200,14 +212,15 @@ swap: SWAP(bot, replace);
* Quicksort behaves badly in the presence of data which is already
* sorted (see Knuth, Vol. 3, page 119) going from O N lg N to O N^2.
* To avoid this worst case behavior, if a re-partitioning occurs
- * without swapping any elements, it is not further partitioned and
- * is insert sorted. This wins big with almost sorted data sets and
- * only loses if the data set is very strangely partitioned. A fix
- * for those data sets would be to return prematurely if the insertion
+ * without swapping any elements, it is not further partitioned and is
+ * insert sorted. This wins big with almost sorted data sets and only
+ * loses if the data set is very strangely partitioned. A fix for
+ * those data sets would be to return prematurely if the insertion
* sort routine is forced to make an excessive number of swaps, and
* continue the partitioning.
*/
- if (!didswap) {
+ if (!didswap)
+ {
insertion_sort(bsv, nmemb, size, compar);
return;
}
@@ -216,34 +229,41 @@ swap: SWAP(bot, replace);
* Re-partition or sort as necessary. Note that the mid element
* itself is correctly positioned and can be ignored.
*/
-#define nlower n1
-#define nupper n2
+#define nlower n1
+#define nupper n2
bot = bsv;
- nlower = (mid - bot) / size; /* size of lower partition */
+ nlower = (mid - bot) / size;/* size of lower partition */
mid += size;
- nupper = nmemb - nlower - 1; /* size of upper partition */
+ nupper = nmemb - nlower - 1;/* size of upper partition */
/*
* If must call recursively, do it on the smaller partition; this
* bounds the stack to lg N entries.
*/
- if (nlower > nupper) {
+ if (nlower > nupper)
+ {
if (nupper >= THRESH)
quick_sort(mid, nupper, size, compar);
- else {
+ else
+ {
SORT(mid, nupper);
- if (nlower < THRESH) {
+ if (nlower < THRESH)
+ {
SORT(bot, nlower);
return;
}
}
nmemb = nlower;
- } else {
+ }
+ else
+ {
if (nlower >= THRESH)
quick_sort(bot, nlower, size, compar);
- else {
+ else
+ {
SORT(bot, nlower);
- if (nupper < THRESH) {
+ if (nupper < THRESH)
+ {
SORT(mid, nupper);
return;
}
@@ -255,30 +275,38 @@ swap: SWAP(bot, replace);
}
static void
-insertion_sort(char* bot, int nmemb, int size, int (*compar)())
+insertion_sort(char *bot, int nmemb, int size, int (*compar) ())
{
- register int cnt;
+ register int cnt;
register u_char ch;
- register char *s1, *s2, *t1, *t2, *top;
+ register char *s1,
+ *s2,
+ *t1,
+ *t2,
+ *top;
/*
- * A simple insertion sort (see Knuth, Vol. 3, page 81, Algorithm
- * S). Insertion sort has the same worst case as most simple sorts
- * (O N^2). It gets used here because it is (O N) in the case of
- * sorted data.
+ * A simple insertion sort (see Knuth, Vol. 3, page 81, Algorithm S).
+ * Insertion sort has the same worst case as most simple sorts (O
+ * N^2). It gets used here because it is (O N) in the case of sorted
+ * data.
*/
top = bot + nmemb * size;
- for (t1 = bot + size; t1 < top;) {
+ for (t1 = bot + size; t1 < top;)
+ {
for (t2 = t1; (t2 -= size) >= bot && compar(t1, t2) < 0;);
- if (t1 != (t2 += size)) {
+ if (t1 != (t2 += size))
+ {
/* Bubble bytes up through each element. */
- for (cnt = size; cnt--; ++t1) {
+ for (cnt = size; cnt--; ++t1)
+ {
ch = *t1;
for (s1 = s2 = t1; (s2 -= size) >= t2; s1 = s2)
*s1 = *s2;
*s1 = ch;
}
- } else
+ }
+ else
t1 += size;
}
}
diff --git a/src/backend/lib/stringinfo.c b/src/backend/lib/stringinfo.c
index 18cfc89f982..34108c04c72 100644
--- a/src/backend/lib/stringinfo.c
+++ b/src/backend/lib/stringinfo.c
@@ -1,15 +1,15 @@
/*-------------------------------------------------------------------------
*
* stringinfo.c--
- * These are routines that can be used to write informations to a string,
- * without having to worry about string lengths, space allocation etc.
- * Ideally the interface should look like the file i/o interface,
+ * These are routines that can be used to write informations to a string,
+ * without having to worry about string lengths, space allocation etc.
+ * Ideally the interface should look like the file i/o interface,
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/lib/stringinfo.c,v 1.3 1997/08/12 20:15:15 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/lib/stringinfo.c,v 1.4 1997/09/07 04:42:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,30 +30,33 @@
StringInfo
makeStringInfo()
{
- StringInfo res;
- long size;
-
- res = (StringInfo) palloc(sizeof(StringInfoData));
- if (res == NULL) {
- elog(WARN, "makeStringInfo: Out of memory!");
- }
-
- size = 100;
- res->data = palloc(size);
- if (res->data == NULL) {
- elog(WARN,
- "makeStringInfo: Out of memory! (%ld bytes requested)", size);
- }
- res->maxlen = size;
- res->len = 0;
- /*
- * NOTE: we must initialize `res->data' to the empty string because
- * we use 'strcat' in 'appendStringInfo', which of course it always
- * expects a null terminated string.
- */
- res->data[0] = '\0';
-
- return(res);
+ StringInfo res;
+ long size;
+
+ res = (StringInfo) palloc(sizeof(StringInfoData));
+ if (res == NULL)
+ {
+ elog(WARN, "makeStringInfo: Out of memory!");
+ }
+
+ size = 100;
+ res->data = palloc(size);
+ if (res->data == NULL)
+ {
+ elog(WARN,
+ "makeStringInfo: Out of memory! (%ld bytes requested)", size);
+ }
+ res->maxlen = size;
+ res->len = 0;
+
+ /*
+ * NOTE: we must initialize `res->data' to the empty string because we
+ * use 'strcat' in 'appendStringInfo', which of course it always
+ * expects a null terminated string.
+ */
+ res->data[0] = '\0';
+
+ return (res);
}
/*---------------------------------------------------------------------
@@ -69,48 +72,53 @@ makeStringInfo()
void
appendStringInfo(StringInfo str, char *buffer)
{
- int buflen, newlen;
- char *s;
-
- Assert((str!=NULL));
-
- /*
- * do we have enough space to append the new string?
- * (don't forget to count the null string terminating char!)
- * If no, then reallocate some more.
- */
- buflen = strlen(buffer);
- if (buflen + str->len >= str->maxlen-1) {
+ int buflen,
+ newlen;
+ char *s;
+
+ Assert((str != NULL));
+
/*
- * how much more space to allocate ?
- * Let's say double the current space...
- * However we must check if this is enough!
+ * do we have enough space to append the new string? (don't forget to
+ * count the null string terminating char!) If no, then reallocate
+ * some more.
*/
- newlen = 2 * str->len;
- while (buflen + str->len >= newlen-1) {
- newlen = 2 * newlen;
+ buflen = strlen(buffer);
+ if (buflen + str->len >= str->maxlen - 1)
+ {
+
+ /*
+ * how much more space to allocate ? Let's say double the current
+ * space... However we must check if this is enough!
+ */
+ newlen = 2 * str->len;
+ while (buflen + str->len >= newlen - 1)
+ {
+ newlen = 2 * newlen;
+ }
+
+ /*
+ * allocate enough space.
+ */
+ s = palloc(newlen);
+ if (s == NULL)
+ {
+ elog(WARN,
+ "appendStringInfo: Out of memory (%d bytes requested)",
+ newlen);
+ }
+ memmove(s, str->data, str->len + 1);
+ pfree(str->data);
+ str->maxlen = newlen;
+ str->data = s;
}
+
/*
- * allocate enough space.
+ * OK, we have enough space now, append 'buffer' at the end of the
+ * string & update the string length. NOTE: this is a text string
+ * (i.e. printable characters) so 'strcat' will do the job (no need to
+ * use 'bcopy' et all...)
*/
- s = palloc(newlen);
- if (s==NULL) {
- elog(WARN,
- "appendStringInfo: Out of memory (%d bytes requested)",
- newlen);
- }
- memmove(s, str->data, str->len+1);
- pfree(str->data);
- str->maxlen = newlen;
- str->data = s;
- }
-
- /*
- * OK, we have enough space now, append 'buffer' at the
- * end of the string & update the string length.
- * NOTE: this is a text string (i.e. printable characters)
- * so 'strcat' will do the job (no need to use 'bcopy' et all...)
- */
- strcat(str->data, buffer);
- str->len += buflen;
+ strcat(str->data, buffer);
+ str->len += buflen;
}
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index abf59e25b17..ff6711d3b5c 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -1,65 +1,65 @@
/*-------------------------------------------------------------------------
*
* auth.c--
- * Routines to handle network authentication
+ * Routines to handle network authentication
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.14 1997/08/19 21:31:23 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.15 1997/09/07 04:42:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
*
- * backend (postmaster) routines:
- * be_recvauth receive authentication information
- * be_setauthsvc do/do not permit an authentication service
- * be_getauthsvc is an authentication service permitted?
+ * backend (postmaster) routines:
+ * be_recvauth receive authentication information
+ * be_setauthsvc do/do not permit an authentication service
+ * be_getauthsvc is an authentication service permitted?
*
- * NOTES
- * To add a new authentication system:
- * 0. If you can't do your authentication over an existing socket,
- * you lose -- get ready to hack around this framework instead of
- * using it. Otherwise, you can assume you have an initialized
- * and empty connection to work with. (Please don't leave leftover
- * gunk in the connection after the authentication transactions, or
- * the POSTGRES routines that follow will be very unhappy.)
- * 1. Write a set of routines that:
- * let a client figure out what user/principal name to use
- * send authentication information (client side)
- * receive authentication information (server side)
- * You can include both routines in this file, using #ifdef FRONTEND
- * to separate them.
- * 2. Edit libpq/pqcomm.h and assign a MsgType for your protocol.
- * 3. Edit the static "struct authsvc" array and the generic
- * {be,fe}_{get,set}auth{name,svc} routines in this file to reflect
- * the new service. You may have to change the arguments of these
- * routines; they basically just reflect what Kerberos v4 needs.
- * 4. Hack on src/{,bin}/Makefile.global and src/{backend,libpq}/Makefile
- * to add library and CFLAGS hooks -- basically, grep the Makefile
- * hierarchy for KRBVERS to see where you need to add things.
+ * NOTES
+ * To add a new authentication system:
+ * 0. If you can't do your authentication over an existing socket,
+ * you lose -- get ready to hack around this framework instead of
+ * using it. Otherwise, you can assume you have an initialized
+ * and empty connection to work with. (Please don't leave leftover
+ * gunk in the connection after the authentication transactions, or
+ * the POSTGRES routines that follow will be very unhappy.)
+ * 1. Write a set of routines that:
+ * let a client figure out what user/principal name to use
+ * send authentication information (client side)
+ * receive authentication information (server side)
+ * You can include both routines in this file, using #ifdef FRONTEND
+ * to separate them.
+ * 2. Edit libpq/pqcomm.h and assign a MsgType for your protocol.
+ * 3. Edit the static "struct authsvc" array and the generic
+ * {be,fe}_{get,set}auth{name,svc} routines in this file to reflect
+ * the new service. You may have to change the arguments of these
+ * routines; they basically just reflect what Kerberos v4 needs.
+ * 4. Hack on src/{,bin}/Makefile.global and src/{backend,libpq}/Makefile
+ * to add library and CFLAGS hooks -- basically, grep the Makefile
+ * hierarchy for KRBVERS to see where you need to add things.
*
- * Send mail to post_hackers@postgres.Berkeley.EDU if you have to make
- * any changes to arguments, etc. Context diffs would be nice, too.
+ * Send mail to post_hackers@postgres.Berkeley.EDU if you have to make
+ * any changes to arguments, etc. Context diffs would be nice, too.
*
- * Someday, this cruft will go away and magically be replaced by a
- * nice interface based on the GSS API or something. For now, though,
- * there's no (stable) UNIX security API to work with...
+ * Someday, this cruft will go away and magically be replaced by a
+ * nice interface based on the GSS API or something. For now, though,
+ * there's no (stable) UNIX security API to work with...
*
*/
#include <stdio.h>
#include <string.h>
-#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
+#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
#ifndef MAXHOSTNAMELEN
-#include <netdb.h> /* for MAXHOSTNAMELEN on some */
+#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#endif
#include <pwd.h>
-#include <ctype.h> /* isspace() declaration */
+#include <ctype.h> /* isspace() declaration */
-#include <sys/types.h> /* needed by in.h on Ultrix */
+#include <sys/types.h> /* needed by in.h on Ultrix */
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -72,19 +72,19 @@
#include <libpq/hba.h>
#include <libpq/password.h>
-static int be_getauthsvc(MsgType msgtype);
+static int be_getauthsvc(MsgType msgtype);
/*----------------------------------------------------------------
* common definitions for generic fe/be routines
*----------------------------------------------------------------
*/
-struct authsvc {
- char name[16]; /* service nickname (for command line) */
- MsgType msgtype; /* startup packet header type */
- int allowed; /* initially allowed (before command line
- * option parsing)?
- */
+struct authsvc
+{
+ char name[16]; /* service nickname (for command line) */
+ MsgType msgtype; /* startup packet header type */
+ int allowed; /* initially allowed (before command line
+ * option parsing)? */
};
/*
@@ -99,9 +99,11 @@ struct authsvc {
*/
#if defined(HBA)
-static int useHostBasedAuth = 1;
+static int useHostBasedAuth = 1;
+
#else
-static int useHostBasedAuth = 0;
+static int useHostBasedAuth = 0;
+
#endif
#if defined(KRB4) || defined(KRB5) || defined(HBA)
@@ -111,19 +113,19 @@ static int useHostBasedAuth = 0;
#endif
static struct authsvc authsvcs[] = {
- { "unauth", STARTUP_UNAUTH_MSG, UNAUTH_ALLOWED },
- { "hba", STARTUP_HBA_MSG, 1 },
- { "krb4", STARTUP_KRB4_MSG, 1 },
- { "krb5", STARTUP_KRB5_MSG, 1 },
-#if defined(KRB5)
- { "kerberos", STARTUP_KRB5_MSG, 1 },
+ {"unauth", STARTUP_UNAUTH_MSG, UNAUTH_ALLOWED},
+ {"hba", STARTUP_HBA_MSG, 1},
+ {"krb4", STARTUP_KRB4_MSG, 1},
+ {"krb5", STARTUP_KRB5_MSG, 1},
+#if defined(KRB5)
+ {"kerberos", STARTUP_KRB5_MSG, 1},
#else
- { "kerberos", STARTUP_KRB4_MSG, 1 },
+ {"kerberos", STARTUP_KRB4_MSG, 1},
#endif
- { "password", STARTUP_PASSWORD_MSG, 1 }
+ {"password", STARTUP_PASSWORD_MSG, 1}
};
-static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
+static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
#ifdef KRB4
/* This has to be ifdef'd out because krb.h does exist. This needs
@@ -138,11 +140,11 @@ static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
#ifdef FRONTEND
/* moves to src/libpq/fe-auth.c */
-#else /* !FRONTEND */
+#else /* !FRONTEND */
/*
* pg_krb4_recvauth -- server routine to receive authentication information
- * from the client
+ * from the client
*
* Nothing unusual here, except that we compare the username obtained from
* the client's setup packet to the authenticated name. (We have to retain
@@ -151,77 +153,82 @@ static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
*/
static int
pg_krb4_recvauth(int sock,
- struct sockaddr_in *laddr,
- struct sockaddr_in *raddr,
- char *username)
+ struct sockaddr_in * laddr,
+ struct sockaddr_in * raddr,
+ char *username)
{
- long krbopts = 0; /* one-way authentication */
- KTEXT_ST clttkt;
- char instance[INST_SZ];
- AUTH_DAT auth_data;
- Key_schedule key_sched;
- char version[KRB_SENDAUTH_VLEN];
- int status;
-
- strcpy(instance, "*"); /* don't care, but arg gets expanded anyway */
- status = krb_recvauth(krbopts,
- sock,
- &clttkt,
- PG_KRB_SRVNAM,
- instance,
- raddr,
- laddr,
- &auth_data,
- PG_KRB_SRVTAB,
- key_sched,
- version);
- if (status != KSUCCESS) {
- sprintf(PQerrormsg,
- "pg_krb4_recvauth: kerberos error: %s\n",
- krb_err_txt[status]);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- if (strncmp(version, PG_KRB4_VERSION, KRB_SENDAUTH_VLEN)) {
- sprintf(PQerrormsg,
- "pg_krb4_recvauth: protocol version != \"%s\"\n",
- PG_KRB4_VERSION);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- if (username && *username &&
- strncmp(username, auth_data.pname, NAMEDATALEN)) {
- sprintf(PQerrormsg,
- "pg_krb4_recvauth: name \"%s\" != \"%s\"\n",
- username,
- auth_data.pname);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- return(STATUS_OK);
+ long krbopts = 0;/* one-way authentication */
+ KTEXT_ST clttkt;
+ char instance[INST_SZ];
+ AUTH_DAT auth_data;
+ Key_schedule key_sched;
+ char version[KRB_SENDAUTH_VLEN];
+ int status;
+
+ strcpy(instance, "*"); /* don't care, but arg gets expanded
+ * anyway */
+ status = krb_recvauth(krbopts,
+ sock,
+ &clttkt,
+ PG_KRB_SRVNAM,
+ instance,
+ raddr,
+ laddr,
+ &auth_data,
+ PG_KRB_SRVTAB,
+ key_sched,
+ version);
+ if (status != KSUCCESS)
+ {
+ sprintf(PQerrormsg,
+ "pg_krb4_recvauth: kerberos error: %s\n",
+ krb_err_txt[status]);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ if (strncmp(version, PG_KRB4_VERSION, KRB_SENDAUTH_VLEN))
+ {
+ sprintf(PQerrormsg,
+ "pg_krb4_recvauth: protocol version != \"%s\"\n",
+ PG_KRB4_VERSION);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ if (username && *username &&
+ strncmp(username, auth_data.pname, NAMEDATALEN))
+ {
+ sprintf(PQerrormsg,
+ "pg_krb4_recvauth: name \"%s\" != \"%s\"\n",
+ username,
+ auth_data.pname);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ return (STATUS_OK);
}
-#endif /* !FRONTEND */
+#endif /* !FRONTEND */
#else
static int
pg_krb4_recvauth(int sock,
- struct sockaddr_in *laddr,
- struct sockaddr_in *raddr,
- char *username)
+ struct sockaddr_in * laddr,
+ struct sockaddr_in * raddr,
+ char *username)
{
- sprintf(PQerrormsg,
- "pg_krb4_recvauth: Kerberos not implemented on this "
- "server.\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
+ sprintf(PQerrormsg,
+ "pg_krb4_recvauth: Kerberos not implemented on this "
+ "server.\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
-return(STATUS_ERROR);
+ return (STATUS_ERROR);
}
-#endif /* KRB4 */
+
+#endif /* KRB4 */
#ifdef KRB5
@@ -237,37 +244,37 @@ return(STATUS_ERROR);
/*
* pg_an_to_ln -- return the local name corresponding to an authentication
- * name
+ * name
*
* XXX Assumes that the first aname component is the user name. This is NOT
- * necessarily so, since an aname can actually be something out of your
- * worst X.400 nightmare, like
- * ORGANIZATION=U. C. Berkeley/NAME=Paul M. Aoki@CS.BERKELEY.EDU
- * Note that the MIT an_to_ln code does the same thing if you don't
- * provide an aname mapping database...it may be a better idea to use
- * krb5_an_to_ln, except that it punts if multiple components are found,
- * and we can't afford to punt.
+ * necessarily so, since an aname can actually be something out of your
+ * worst X.400 nightmare, like
+ * ORGANIZATION=U. C. Berkeley/NAME=Paul M. Aoki@CS.BERKELEY.EDU
+ * Note that the MIT an_to_ln code does the same thing if you don't
+ * provide an aname mapping database...it may be a better idea to use
+ * krb5_an_to_ln, except that it punts if multiple components are found,
+ * and we can't afford to punt.
*/
-static char *
+static char *
pg_an_to_ln(char *aname)
{
- char *p;
-
- if ((p = strchr(aname, '/')) || (p = strchr(aname, '@')))
- *p = '\0';
- return(aname);
+ char *p;
+
+ if ((p = strchr(aname, '/')) || (p = strchr(aname, '@')))
+ *p = '\0';
+ return (aname);
}
#ifdef FRONTEND
/* moves to src/libpq/fe-auth.c */
-#else /* !FRONTEND */
+#else /* !FRONTEND */
/*
* pg_krb5_recvauth -- server routine to receive authentication information
- * from the client
+ * from the client
*
* We still need to compare the username obtained from the client's setup
- * packet to the authenticated name, as described in pg_krb4_recvauth. This
+ * packet to the authenticated name, as described in pg_krb4_recvauth. This
* is a bit more problematic in v5, as described above in pg_an_to_ln.
*
* In addition, as described above in pg_krb5_sendauth, we still need to
@@ -286,315 +293,348 @@ pg_an_to_ln(char *aname)
*/
static int
pg_krb5_recvauth(int sock,
- struct sockaddr_in *laddr,
- struct sockaddr_in *raddr,
- char *username)
+ struct sockaddr_in * laddr,
+ struct sockaddr_in * raddr,
+ char *username)
{
- char servbuf[MAXHOSTNAMELEN + 1 +
- sizeof(PG_KRB_SRVNAM)];
- char *hostp, *kusername = (char *) NULL;
- krb5_error_code code;
- krb5_principal client, server;
- krb5_address sender_addr;
- krb5_rdreq_key_proc keyproc = (krb5_rdreq_key_proc) NULL;
- krb5_pointer keyprocarg = (krb5_pointer) NULL;
-
- /*
- * Set up server side -- since we have no ticket file to make this
- * easy, we construct our own name and parse it. See note on
- * canonicalization above.
- */
- strcpy(servbuf, PG_KRB_SRVNAM);
- *(hostp = servbuf + (sizeof(PG_KRB_SRVNAM) - 1)) = '/';
- if (gethostname(++hostp, MAXHOSTNAMELEN) < 0)
- strcpy(hostp, "localhost");
- if (hostp = strchr(hostp, '.'))
- *hostp = '\0';
- if (code = krb5_parse_name(servbuf, &server)) {
- sprintf(PQerrormsg,
- "pg_krb5_recvauth: Kerberos error %d in krb5_parse_name\n",
- code);
- com_err("pg_krb5_recvauth", code, "in krb5_parse_name");
- return(STATUS_ERROR);
- }
-
- /*
- * krb5_sendauth needs this to verify the address in the client
- * authenticator.
- */
- sender_addr.addrtype = raddr->sin_family;
- sender_addr.length = sizeof(raddr->sin_addr);
- sender_addr.contents = (krb5_octet *) &(raddr->sin_addr);
-
- if (strcmp(PG_KRB_SRVTAB, "")) {
- keyproc = krb5_kt_read_service_key;
- keyprocarg = PG_KRB_SRVTAB;
- }
-
- if (code = krb5_recvauth((krb5_pointer) &sock,
- PG_KRB5_VERSION,
- server,
- &sender_addr,
- (krb5_pointer) NULL,
- keyproc,
- keyprocarg,
- (char *) NULL,
- (krb5_int32 *) NULL,
- &client,
- (krb5_ticket **) NULL,
- (krb5_authenticator **) NULL)) {
- sprintf(PQerrormsg,
- "pg_krb5_recvauth: Kerberos error %d in krb5_recvauth\n",
- code);
- com_err("pg_krb5_recvauth", code, "in krb5_recvauth");
+ char servbuf[MAXHOSTNAMELEN + 1 +
+ sizeof(PG_KRB_SRVNAM)];
+ char *hostp,
+ *kusername = (char *) NULL;
+ krb5_error_code code;
+ krb5_principal client,
+ server;
+ krb5_address sender_addr;
+ krb5_rdreq_key_proc keyproc = (krb5_rdreq_key_proc) NULL;
+ krb5_pointer keyprocarg = (krb5_pointer) NULL;
+
+ /*
+ * Set up server side -- since we have no ticket file to make this
+ * easy, we construct our own name and parse it. See note on
+ * canonicalization above.
+ */
+ strcpy(servbuf, PG_KRB_SRVNAM);
+ *(hostp = servbuf + (sizeof(PG_KRB_SRVNAM) - 1)) = '/';
+ if (gethostname(++hostp, MAXHOSTNAMELEN) < 0)
+ strcpy(hostp, "localhost");
+ if (hostp = strchr(hostp, '.'))
+ *hostp = '\0';
+ if (code = krb5_parse_name(servbuf, &server))
+ {
+ sprintf(PQerrormsg,
+ "pg_krb5_recvauth: Kerberos error %d in krb5_parse_name\n",
+ code);
+ com_err("pg_krb5_recvauth", code, "in krb5_parse_name");
+ return (STATUS_ERROR);
+ }
+
+ /*
+ * krb5_sendauth needs this to verify the address in the client
+ * authenticator.
+ */
+ sender_addr.addrtype = raddr->sin_family;
+ sender_addr.length = sizeof(raddr->sin_addr);
+ sender_addr.contents = (krb5_octet *) & (raddr->sin_addr);
+
+ if (strcmp(PG_KRB_SRVTAB, ""))
+ {
+ keyproc = krb5_kt_read_service_key;
+ keyprocarg = PG_KRB_SRVTAB;
+ }
+
+ if (code = krb5_recvauth((krb5_pointer) & sock,
+ PG_KRB5_VERSION,
+ server,
+ &sender_addr,
+ (krb5_pointer) NULL,
+ keyproc,
+ keyprocarg,
+ (char *) NULL,
+ (krb5_int32 *) NULL,
+ &client,
+ (krb5_ticket **) NULL,
+ (krb5_authenticator **) NULL))
+ {
+ sprintf(PQerrormsg,
+ "pg_krb5_recvauth: Kerberos error %d in krb5_recvauth\n",
+ code);
+ com_err("pg_krb5_recvauth", code, "in krb5_recvauth");
+ krb5_free_principal(server);
+ return (STATUS_ERROR);
+ }
krb5_free_principal(server);
- return(STATUS_ERROR);
- }
- krb5_free_principal(server);
-
- /*
- * The "client" structure comes out of the ticket and is therefore
- * authenticated. Use it to check the username obtained from the
- * postmaster startup packet.
- */
- if ((code = krb5_unparse_name(client, &kusername))) {
- sprintf(PQerrormsg,
- "pg_krb5_recvauth: Kerberos error %d in krb5_unparse_name\n",
- code);
- com_err("pg_krb5_recvauth", code, "in krb5_unparse_name");
+
+ /*
+ * The "client" structure comes out of the ticket and is therefore
+ * authenticated. Use it to check the username obtained from the
+ * postmaster startup packet.
+ */
+ if ((code = krb5_unparse_name(client, &kusername)))
+ {
+ sprintf(PQerrormsg,
+ "pg_krb5_recvauth: Kerberos error %d in krb5_unparse_name\n",
+ code);
+ com_err("pg_krb5_recvauth", code, "in krb5_unparse_name");
+ krb5_free_principal(client);
+ return (STATUS_ERROR);
+ }
krb5_free_principal(client);
- return(STATUS_ERROR);
- }
- krb5_free_principal(client);
- if (!kusername) {
- sprintf(PQerrormsg,
- "pg_krb5_recvauth: could not decode username\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- kusername = pg_an_to_ln(kusername);
- if (username && strncmp(username, kusername, NAMEDATALEN)) {
- sprintf(PQerrormsg,
- "pg_krb5_recvauth: name \"%s\" != \"%s\"\n",
- username, kusername);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
+ if (!kusername)
+ {
+ sprintf(PQerrormsg,
+ "pg_krb5_recvauth: could not decode username\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ kusername = pg_an_to_ln(kusername);
+ if (username && strncmp(username, kusername, NAMEDATALEN))
+ {
+ sprintf(PQerrormsg,
+ "pg_krb5_recvauth: name \"%s\" != \"%s\"\n",
+ username, kusername);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ free(kusername);
+ return (STATUS_ERROR);
+ }
free(kusername);
- return(STATUS_ERROR);
- }
- free(kusername);
- return(STATUS_OK);
+ return (STATUS_OK);
}
-#endif /* !FRONTEND */
+#endif /* !FRONTEND */
#else
static int
pg_krb5_recvauth(int sock,
- struct sockaddr_in *laddr,
- struct sockaddr_in *raddr,
- char *username)
+ struct sockaddr_in * laddr,
+ struct sockaddr_in * raddr,
+ char *username)
{
- sprintf(PQerrormsg,
- "pg_krb5_recvauth: Kerberos not implemented on this "
- "server.\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
+ sprintf(PQerrormsg,
+ "pg_krb5_recvauth: Kerberos not implemented on this "
+ "server.\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
-return(STATUS_ERROR);
+ return (STATUS_ERROR);
}
-#endif /* KRB5 */
+
+#endif /* KRB5 */
static int
-pg_password_recvauth(Port *port, char *database, char *DataDir)
+pg_password_recvauth(Port * port, char *database, char *DataDir)
{
- PacketBuf buf;
- char *user, *password;
-
- if(PacketReceive(port, &buf, BLOCKING) != STATUS_OK) {
- sprintf(PQerrormsg,
- "pg_password_recvauth: failed to receive authentication packet.\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return STATUS_ERROR;
- }
+ PacketBuf buf;
+ char *user,
+ *password;
+
+ if (PacketReceive(port, &buf, BLOCKING) != STATUS_OK)
+ {
+ sprintf(PQerrormsg,
+ "pg_password_recvauth: failed to receive authentication packet.\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return STATUS_ERROR;
+ }
- user = buf.data;
- password = buf.data + strlen(user) + 1;
+ user = buf.data;
+ password = buf.data + strlen(user) + 1;
- return verify_password(user, password, port, database, DataDir);
+ return verify_password(user, password, port, database, DataDir);
}
/*
* be_recvauth -- server demux routine for incoming authentication information
*/
int
-be_recvauth(MsgType msgtype_arg, Port *port, char *username, StartupInfo* sp)
+be_recvauth(MsgType msgtype_arg, Port * port, char *username, StartupInfo * sp)
{
- MsgType msgtype;
-
- /* A message type of STARTUP_MSG (which once upon a time was the only
- startup message type) means user wants us to choose. "unauth" is
- what used to be the only choice, but installation may choose "hba"
- instead.
- */
- if (msgtype_arg == STARTUP_MSG) {
- if(useHostBasedAuth)
- msgtype = STARTUP_HBA_MSG;
- else
- msgtype = STARTUP_UNAUTH_MSG;
- } else
- msgtype = msgtype_arg;
-
-
- if (!username) {
- sprintf(PQerrormsg,
- "be_recvauth: no user name passed\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- if (!port) {
- sprintf(PQerrormsg,
- "be_recvauth: no port structure passed\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
-
- switch (msgtype) {
- case STARTUP_KRB4_MSG:
- if (!be_getauthsvc(msgtype)) {
- sprintf(PQerrormsg,
- "be_recvauth: krb4 authentication disallowed\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- if (pg_krb4_recvauth(port->sock, &port->laddr, &port->raddr,
- username) != STATUS_OK) {
- sprintf(PQerrormsg,
- "be_recvauth: krb4 authentication failed\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- break;
- case STARTUP_KRB5_MSG:
- if (!be_getauthsvc(msgtype)) {
- sprintf(PQerrormsg,
- "be_recvauth: krb5 authentication disallowed\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- if (pg_krb5_recvauth(port->sock, &port->laddr, &port->raddr,
- username) != STATUS_OK) {
- sprintf(PQerrormsg,
- "be_recvauth: krb5 authentication failed\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- break;
- case STARTUP_UNAUTH_MSG:
- if (!be_getauthsvc(msgtype)) {
- sprintf(PQerrormsg,
- "be_recvauth: "
- "unauthenticated connections disallowed\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- break;
- case STARTUP_HBA_MSG:
- if (hba_recvauth(port, sp->database, sp->user, DataDir) != STATUS_OK) {
- sprintf(PQerrormsg,
- "be_recvauth: host-based authentication failed\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- break;
- case STARTUP_PASSWORD_MSG:
- if(!be_getauthsvc(msgtype)) {
- sprintf(PQerrormsg,
- "be_recvauth: "
- "plaintext password authentication disallowed\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
+ MsgType msgtype;
+
+ /*
+ * A message type of STARTUP_MSG (which once upon a time was the only
+ * startup message type) means user wants us to choose. "unauth" is
+ * what used to be the only choice, but installation may choose "hba"
+ * instead.
+ */
+ if (msgtype_arg == STARTUP_MSG)
+ {
+ if (useHostBasedAuth)
+ msgtype = STARTUP_HBA_MSG;
+ else
+ msgtype = STARTUP_UNAUTH_MSG;
+ }
+ else
+ msgtype = msgtype_arg;
+
+
+ if (!username)
+ {
+ sprintf(PQerrormsg,
+ "be_recvauth: no user name passed\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ if (!port)
+ {
+ sprintf(PQerrormsg,
+ "be_recvauth: no port structure passed\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
}
- if(pg_password_recvauth(port, sp->database, DataDir) != STATUS_OK) {
- /* pg_password_recvauth or lower-level routines have already set */
- /* the error message */
- return(STATUS_ERROR);
+
+ switch (msgtype)
+ {
+ case STARTUP_KRB4_MSG:
+ if (!be_getauthsvc(msgtype))
+ {
+ sprintf(PQerrormsg,
+ "be_recvauth: krb4 authentication disallowed\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ if (pg_krb4_recvauth(port->sock, &port->laddr, &port->raddr,
+ username) != STATUS_OK)
+ {
+ sprintf(PQerrormsg,
+ "be_recvauth: krb4 authentication failed\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ break;
+ case STARTUP_KRB5_MSG:
+ if (!be_getauthsvc(msgtype))
+ {
+ sprintf(PQerrormsg,
+ "be_recvauth: krb5 authentication disallowed\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ if (pg_krb5_recvauth(port->sock, &port->laddr, &port->raddr,
+ username) != STATUS_OK)
+ {
+ sprintf(PQerrormsg,
+ "be_recvauth: krb5 authentication failed\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ break;
+ case STARTUP_UNAUTH_MSG:
+ if (!be_getauthsvc(msgtype))
+ {
+ sprintf(PQerrormsg,
+ "be_recvauth: "
+ "unauthenticated connections disallowed\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ break;
+ case STARTUP_HBA_MSG:
+ if (hba_recvauth(port, sp->database, sp->user, DataDir) != STATUS_OK)
+ {
+ sprintf(PQerrormsg,
+ "be_recvauth: host-based authentication failed\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ break;
+ case STARTUP_PASSWORD_MSG:
+ if (!be_getauthsvc(msgtype))
+ {
+ sprintf(PQerrormsg,
+ "be_recvauth: "
+ "plaintext password authentication disallowed\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ if (pg_password_recvauth(port, sp->database, DataDir) != STATUS_OK)
+ {
+
+ /*
+ * pg_password_recvauth or lower-level routines have already
+ * set
+ */
+ /* the error message */
+ return (STATUS_ERROR);
+ }
+ break;
+ default:
+ sprintf(PQerrormsg,
+ "be_recvauth: unrecognized message type: %d\n",
+ msgtype);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
}
- break;
- default:
- sprintf(PQerrormsg,
- "be_recvauth: unrecognized message type: %d\n",
- msgtype);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- return(STATUS_OK);
+ return (STATUS_OK);
}
/*
* be_setauthsvc -- enable/disable the authentication services currently
- * selected for use by the backend
+ * selected for use by the backend
* be_getauthsvc -- returns whether a particular authentication system
- * (indicated by its message type) is permitted by the
- * current selections
+ * (indicated by its message type) is permitted by the
+ * current selections
*
* be_setauthsvc encodes the command-line syntax that
- * -a "<service-name>"
+ * -a "<service-name>"
* enables a service, whereas
- * -a "no<service-name>"
+ * -a "no<service-name>"
* disables it.
*/
void
be_setauthsvc(char *name)
{
- int i, j;
- int turnon = 1;
-
- if (!name)
- return;
- if (!strncmp("no", name, 2)) {
- turnon = 0;
- name += 2;
- }
- if (name[0] == '\0')
- return;
- for (i = 0; i < n_authsvcs; ++i)
- if (!strcmp(name, authsvcs[i].name)) {
- for (j = 0; j < n_authsvcs; ++j)
- if (authsvcs[j].msgtype == authsvcs[i].msgtype)
- authsvcs[j].allowed = turnon;
- break;
+ int i,
+ j;
+ int turnon = 1;
+
+ if (!name)
+ return;
+ if (!strncmp("no", name, 2))
+ {
+ turnon = 0;
+ name += 2;
}
- if (i == n_authsvcs) {
- sprintf(PQerrormsg,
- "be_setauthsvc: invalid name %s, ignoring...\n",
- name);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- }
- return;
+ if (name[0] == '\0')
+ return;
+ for (i = 0; i < n_authsvcs; ++i)
+ if (!strcmp(name, authsvcs[i].name))
+ {
+ for (j = 0; j < n_authsvcs; ++j)
+ if (authsvcs[j].msgtype == authsvcs[i].msgtype)
+ authsvcs[j].allowed = turnon;
+ break;
+ }
+ if (i == n_authsvcs)
+ {
+ sprintf(PQerrormsg,
+ "be_setauthsvc: invalid name %s, ignoring...\n",
+ name);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ }
+ return;
}
static int
be_getauthsvc(MsgType msgtype)
{
- int i;
-
- for (i = 0; i < n_authsvcs; ++i)
- if (msgtype == authsvcs[i].msgtype)
- return(authsvcs[i].allowed);
- return(0);
+ int i;
+
+ for (i = 0; i < n_authsvcs; ++i)
+ if (msgtype == authsvcs[i].msgtype)
+ return (authsvcs[i].allowed);
+ return (0);
}
diff --git a/src/backend/libpq/be-dumpdata.c b/src/backend/libpq/be-dumpdata.c
index b47e79fa65c..db0a99141d6 100644
--- a/src/backend/libpq/be-dumpdata.c
+++ b/src/backend/libpq/be-dumpdata.c
@@ -1,32 +1,32 @@
/*-------------------------------------------------------------------------
*
* be-dumpdata.c--
- * support for collection of returned tuples from an internal
- * PQ call into a backend buffer.
+ * support for collection of returned tuples from an internal
+ * PQ call into a backend buffer.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-dumpdata.c,v 1.5 1997/08/18 20:52:31 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-dumpdata.c,v 1.6 1997/09/07 04:42:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * be_portalinit - initialize backend portal administration
- * be_portalpush - add a portal to the top of the portal stack
- * be_portalpop - remove portal on the top of the stack & return it
- * be_currentportal - return the top portal on the portal stack
- * be_newportal - return a new portal.
- * be_portalinit - initialize backend portal expected to hold results.
- * be_printtup - add a tuple to a backend portal
+ * be_portalinit - initialize backend portal administration
+ * be_portalpush - add a portal to the top of the portal stack
+ * be_portalpop - remove portal on the top of the stack & return it
+ * be_currentportal - return the top portal on the portal stack
+ * be_newportal - return a new portal.
+ * be_portalinit - initialize backend portal expected to hold results.
+ * be_printtup - add a tuple to a backend portal
*
* NOTES
- * Since backend user-defined operators can call queries
- * which in turn call user-defined operators can call queries...
- * we have to keep track of portals on a stack. BeginCommand()
- * puts portals on the stack and the PQ functions remove them.
+ * Since backend user-defined operators can call queries
+ * which in turn call user-defined operators can call queries...
+ * we have to keep track of portals on a stack. BeginCommand()
+ * puts portals on the stack and the PQ functions remove them.
*
*/
#include <string.h>
@@ -48,274 +48,288 @@
#include <access/printtup.h>
/* ----------------
- * backend portal stack for recursive PQexec calls
+ * backend portal stack for recursive PQexec calls
* ----------------
*/
-static Dllist *be_portalstack;
+static Dllist *be_portalstack;
/* ----------------
- * be_portalinit - initialize backend portal administration
+ * be_portalinit - initialize backend portal administration
*
- * This is called once from InitPostgres() to initialize
- * the portal stack.
+ * This is called once from InitPostgres() to initialize
+ * the portal stack.
* ----------------
*/
void
be_portalinit(void)
{
- be_portalstack = DLNewList();
+ be_portalstack = DLNewList();
}
/* ----------------
- * be_portalpush - add a portal to the top of the portal stack
+ * be_portalpush - add a portal to the top of the portal stack
*
- * used by BeginCommand()
+ * used by BeginCommand()
* ----------------
*/
void
-be_portalpush(PortalEntry *entry)
+be_portalpush(PortalEntry * entry)
{
- DLAddTail(be_portalstack, DLNewElem(entry));
+ DLAddTail(be_portalstack, DLNewElem(entry));
}
/* ----------------
- * be_portalpop - remove the portal on the top of the stack & return it
+ * be_portalpop - remove the portal on the top of the stack & return it
*
- * used by PQexec()
+ * used by PQexec()
* ----------------
*/
-PortalEntry *
+PortalEntry *
be_portalpop(void)
{
- PortalEntry *p;
- Dlelem* elt;
- elt = DLRemTail(be_portalstack);
+ PortalEntry *p;
+ Dlelem *elt;
+
+ elt = DLRemTail(be_portalstack);
+
+ p = (elt ? (PortalEntry *) DLE_VAL(elt) : NULL);
+ DLFreeElem(elt);
+ return p;
- p = (elt ? (PortalEntry*)DLE_VAL(elt) : NULL);
- DLFreeElem(elt);
- return p;
-
}
/* ----------------
- * be_currentportal - return the top portal on the portal stack
+ * be_currentportal - return the top portal on the portal stack
*
- * used by be_printtup()
+ * used by be_printtup()
* ----------------
*/
-PortalEntry *
+PortalEntry *
be_currentportal(void)
{
- Dlelem* elt;
- elt = DLGetTail(be_portalstack);
- return (elt ? (PortalEntry*)DLE_VAL(elt) : NULL);
+ Dlelem *elt;
+
+ elt = DLGetTail(be_portalstack);
+ return (elt ? (PortalEntry *) DLE_VAL(elt) : NULL);
}
/* ----------------
- * be_newportal - return a new portal.
+ * be_newportal - return a new portal.
*
- * If the user-defined function does not specify a portal name,
- * we generate a unique one. Names are generated from a combination
- * of a postgres oid and an integer counter which is incremented
- * every time we ask for a local portal.
+ * If the user-defined function does not specify a portal name,
+ * we generate a unique one. Names are generated from a combination
+ * of a postgres oid and an integer counter which is incremented
+ * every time we ask for a local portal.
*
- * used by BeginCommand()
+ * used by BeginCommand()
* ----------------
*/
-static Oid be_portaloid;
+static Oid be_portaloid;
static u_int be_portalcnt = 0;
-PortalEntry *
-be_newportal(void)
+PortalEntry *
+be_newportal(void)
{
- PortalEntry *entry;
- char buf[PortalNameLength];
-
- /* ----------------
- * generate a new name
- * ----------------
- */
- if (be_portalcnt == 0)
- be_portaloid = newoid();
- be_portalcnt++;
- sprintf(buf, "be_%d_%d", be_portaloid, be_portalcnt);
-
- /* ----------------
- * initialize the new portal entry and keep track
- * of the current memory context for be_printtup().
- * This is important - otherwise whatever we allocate
- * will go away and the contents of the portal after
- * PQexec() returns will be meaningless.
- * ----------------
- */
- entry = pbuf_setup(buf);
- entry->portalcxt = (Pointer) CurrentMemoryContext;
-
- return entry;
+ PortalEntry *entry;
+ char buf[PortalNameLength];
+
+ /* ----------------
+ * generate a new name
+ * ----------------
+ */
+ if (be_portalcnt == 0)
+ be_portaloid = newoid();
+ be_portalcnt++;
+ sprintf(buf, "be_%d_%d", be_portaloid, be_portalcnt);
+
+ /* ----------------
+ * initialize the new portal entry and keep track
+ * of the current memory context for be_printtup().
+ * This is important - otherwise whatever we allocate
+ * will go away and the contents of the portal after
+ * PQexec() returns will be meaningless.
+ * ----------------
+ */
+ entry = pbuf_setup(buf);
+ entry->portalcxt = (Pointer) CurrentMemoryContext;
+
+ return entry;
}
/* ----------------
- * be_typeinit - initialize backend portal expected to hold
- * query results.
+ * be_typeinit - initialize backend portal expected to hold
+ * query results.
*
- * used by BeginCommand()
+ * used by BeginCommand()
* ----------------
*/
void
-be_typeinit(PortalEntry *entry,
- TupleDesc tupDesc,
- int natts)
+be_typeinit(PortalEntry * entry,
+ TupleDesc tupDesc,
+ int natts)
{
- PortalBuffer *portal;
- GroupBuffer *group;
- int i;
- AttributeTupleForm *attrs = tupDesc->attrs;
-
- /* ----------------
- * add a new portal group to the portal
- * ----------------
- */
- portal = entry->portal;
- portal->no_groups++;
- portal->groups = group = pbuf_addGroup(portal);
- group->no_fields = natts;
-
- /* ----------------
- * initialize portal group type info
- * ----------------
- */
- if (natts > 0) {
- group->types = pbuf_addTypes(natts);
- for (i = 0; i < natts; ++i) {
- strncpy(group->types[i].name, attrs[i]->attname.data, NAMEDATALEN);
- group->types[i].adtid = attrs[i]->atttypid;
- group->types[i].adtsize = attrs[i]->attlen;
+ PortalBuffer *portal;
+ GroupBuffer *group;
+ int i;
+ AttributeTupleForm *attrs = tupDesc->attrs;
+
+ /* ----------------
+ * add a new portal group to the portal
+ * ----------------
+ */
+ portal = entry->portal;
+ portal->no_groups++;
+ portal->groups = group = pbuf_addGroup(portal);
+ group->no_fields = natts;
+
+ /* ----------------
+ * initialize portal group type info
+ * ----------------
+ */
+ if (natts > 0)
+ {
+ group->types = pbuf_addTypes(natts);
+ for (i = 0; i < natts; ++i)
+ {
+ strncpy(group->types[i].name, attrs[i]->attname.data, NAMEDATALEN);
+ group->types[i].adtid = attrs[i]->atttypid;
+ group->types[i].adtsize = attrs[i]->attlen;
+ }
}
- }
}
/* ----------------
- * be_printtup - add a tuple to a backend portal
+ * be_printtup - add a tuple to a backend portal
*
- * used indirectly by ExecRetrieve()
+ * used indirectly by ExecRetrieve()
*
- * This code is pretty much copied from printtup(), dump_type()
- * and dump_data(). -cim 2/12/91
+ * This code is pretty much copied from printtup(), dump_type()
+ * and dump_data(). -cim 2/12/91
* ----------------
*/
void
be_printtup(HeapTuple tuple, TupleDesc typeinfo)
{
- int i;
- char *attr;
- bool isnull;
- Oid typoutput;
-
- PortalEntry *entry = NULL;
- PortalBuffer *portal = NULL;
- GroupBuffer *group = NULL ;
- TupleBlock *tuples = NULL;
- char **values;
- int *lengths;
-
- MemoryContext savecxt;
-
- /* ----------------
- * get the current portal and group
- * ----------------
- */
- entry = be_currentportal();
- portal = entry->portal;
- group = portal->groups;
-
- /* ----------------
- * switch to the portal's memory context so that
- * the tuples we allocate are returned to the user.
- * ----------------
- */
- savecxt = MemoryContextSwitchTo((MemoryContext)entry->portalcxt);
-
- /* ----------------
- * If no tuple block yet, allocate one.
- * If the current block is full, allocate another one.
- * ----------------
- */
- if (group->tuples == NULL) {
- tuples = group->tuples = pbuf_addTuples();
- tuples->tuple_index = 0;
- } else {
- tuples = group->tuples;
- /* walk to the end of the linked list of TupleBlocks */
- while (tuples->next)
- tuples = tuples->next;
- /* now, tuples is the last TupleBlock, check to see if it is full.
- If so, allocate a new TupleBlock and add it to the end of
- the chain */
-
- if (tuples->tuple_index == TupleBlockSize) {
- tuples->next = pbuf_addTuples();
- tuples = tuples->next;
- tuples->tuple_index = 0;
+ int i;
+ char *attr;
+ bool isnull;
+ Oid typoutput;
+
+ PortalEntry *entry = NULL;
+ PortalBuffer *portal = NULL;
+ GroupBuffer *group = NULL;
+ TupleBlock *tuples = NULL;
+ char **values;
+ int *lengths;
+
+ MemoryContext savecxt;
+
+ /* ----------------
+ * get the current portal and group
+ * ----------------
+ */
+ entry = be_currentportal();
+ portal = entry->portal;
+ group = portal->groups;
+
+ /* ----------------
+ * switch to the portal's memory context so that
+ * the tuples we allocate are returned to the user.
+ * ----------------
+ */
+ savecxt = MemoryContextSwitchTo((MemoryContext) entry->portalcxt);
+
+ /* ----------------
+ * If no tuple block yet, allocate one.
+ * If the current block is full, allocate another one.
+ * ----------------
+ */
+ if (group->tuples == NULL)
+ {
+ tuples = group->tuples = pbuf_addTuples();
+ tuples->tuple_index = 0;
}
- }
-
- /* ----------------
- * Allocate space for a tuple.
- * ----------------
- */
- tuples->values[tuples->tuple_index] = pbuf_addTuple(tuple->t_natts);
- tuples->lengths[tuples->tuple_index] = pbuf_addTupleValueLengths(tuple->t_natts);
- /* ----------------
- * copy printable representations of the tuple's attributes
- * to the portal.
- *
- * This seems silly, because the user's function which is calling
- * PQexec() or PQfn() will probably just convert this back into the
- * internal form anyways, but the point here is to provide a uniform
- * libpq interface and this is how the fe libpq interface currently
- * works. Pretty soon we'll have to add code to let the fe or be
- * select the desired data representation and then deal with that.
- * This should not be too hard, as there already exist typrecieve()
- * and typsend() procedures for user-defined types (see pg_type.h)
- * -cim 2/11/91
- * ----------------
- */
-
- values = tuples->values[tuples->tuple_index];
- lengths = tuples->lengths[tuples->tuple_index];
-
- for (i = 0; i < tuple->t_natts; i++) {
- attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
- typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
-
- lengths[i] = typeinfo->attrs[i]->attlen;
-
- if (lengths[i] == -1) /* variable length attribute */
- if (!isnull)
- lengths[i] = VARSIZE(attr)-VARHDRSZ;
- else
- lengths[i] = 0;
-
- if (!isnull && OidIsValid(typoutput)) {
- values[i] = fmgr(typoutput, attr, gettypelem(typeinfo->attrs[i]->atttypid));
- } else
- values[i] = NULL;
-
- }
-
- /* ----------------
- * increment tuple group counters
- * ----------------
- */
- portal->no_tuples++;
- group->no_tuples++;
- tuples->tuple_index++;
-
- /* ----------------
- * return to the original memory context
- * ----------------
- */
- MemoryContextSwitchTo(savecxt);
+ else
+ {
+ tuples = group->tuples;
+ /* walk to the end of the linked list of TupleBlocks */
+ while (tuples->next)
+ tuples = tuples->next;
+
+ /*
+ * now, tuples is the last TupleBlock, check to see if it is full.
+ * If so, allocate a new TupleBlock and add it to the end of the
+ * chain
+ */
+
+ if (tuples->tuple_index == TupleBlockSize)
+ {
+ tuples->next = pbuf_addTuples();
+ tuples = tuples->next;
+ tuples->tuple_index = 0;
+ }
+ }
+
+ /* ----------------
+ * Allocate space for a tuple.
+ * ----------------
+ */
+ tuples->values[tuples->tuple_index] = pbuf_addTuple(tuple->t_natts);
+ tuples->lengths[tuples->tuple_index] = pbuf_addTupleValueLengths(tuple->t_natts);
+ /* ----------------
+ * copy printable representations of the tuple's attributes
+ * to the portal.
+ *
+ * This seems silly, because the user's function which is calling
+ * PQexec() or PQfn() will probably just convert this back into the
+ * internal form anyways, but the point here is to provide a uniform
+ * libpq interface and this is how the fe libpq interface currently
+ * works. Pretty soon we'll have to add code to let the fe or be
+ * select the desired data representation and then deal with that.
+ * This should not be too hard, as there already exist typrecieve()
+ * and typsend() procedures for user-defined types (see pg_type.h)
+ * -cim 2/11/91
+ * ----------------
+ */
+
+ values = tuples->values[tuples->tuple_index];
+ lengths = tuples->lengths[tuples->tuple_index];
+
+ for (i = 0; i < tuple->t_natts; i++)
+ {
+ attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
+ typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
+
+ lengths[i] = typeinfo->attrs[i]->attlen;
+
+ if (lengths[i] == -1) /* variable length attribute */
+ if (!isnull)
+ lengths[i] = VARSIZE(attr) - VARHDRSZ;
+ else
+ lengths[i] = 0;
+
+ if (!isnull && OidIsValid(typoutput))
+ {
+ values[i] = fmgr(typoutput, attr, gettypelem(typeinfo->attrs[i]->atttypid));
+ }
+ else
+ values[i] = NULL;
+
+ }
+
+ /* ----------------
+ * increment tuple group counters
+ * ----------------
+ */
+ portal->no_tuples++;
+ group->no_tuples++;
+ tuples->tuple_index++;
+
+ /* ----------------
+ * return to the original memory context
+ * ----------------
+ */
+ MemoryContextSwitchTo(savecxt);
}
diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c
index 58a827838db..e3a464b087f 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -1,24 +1,24 @@
/*-------------------------------------------------------------------------
*
* be-fsstubs.c--
- * support for filesystem operations on large objects
+ * support for filesystem operations on large objects
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.12 1997/08/12 22:52:48 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.13 1997/09/07 04:42:15 momjian Exp $
*
* NOTES
- * This should be moved to a more appropriate place. It is here
- * for lack of a better place.
+ * This should be moved to a more appropriate place. It is here
+ * for lack of a better place.
*
- * Builtin functions for open/close/read/write operations on large objects.
+ * Builtin functions for open/close/read/write operations on large objects.
*
- * These functions operate in the current portal variable context, which
- * means the large object descriptors hang around between transactions and
- * are not deallocated until explicitly closed, or until the portal is
- * closed.
+ * These functions operate in the current portal variable context, which
+ * means the large object descriptors hang around between transactions and
+ * are not deallocated until explicitly closed, or until the portal is
+ * closed.
*-------------------------------------------------------------------------
*/
@@ -37,340 +37,364 @@
#include <utils/memutils.h>
#include <lib/fstack.h>
#include <utils/mcxt.h>
-#include <storage/fd.h> /* for O_ */
+#include <storage/fd.h> /* for O_ */
#include <storage/large_object.h>
#include <libpq/be-fsstubs.h>
/*#define FSDB 1*/
#define MAX_LOBJ_FDS 256
-static LargeObjectDesc *cookies[MAX_LOBJ_FDS];
+static LargeObjectDesc *cookies[MAX_LOBJ_FDS];
static GlobalMemory fscxt = NULL;
-static int newLOfd(LargeObjectDesc *lobjCookie);
-static void deleteLOfd(int fd);
+static int newLOfd(LargeObjectDesc * lobjCookie);
+static void deleteLOfd(int fd);
/*****************************************************************************
- * File Interfaces for Large Objects
+ * File Interfaces for Large Objects
*****************************************************************************/
int
lo_open(Oid lobjId, int mode)
{
- LargeObjectDesc *lobjDesc;
- int fd;
- MemoryContext currentContext;
-
+ LargeObjectDesc *lobjDesc;
+ int fd;
+ MemoryContext currentContext;
+
#if FSDB
- elog(NOTICE,"LOopen(%d,%d)",lobjId,mode);
+ elog(NOTICE, "LOopen(%d,%d)", lobjId, mode);
#endif
- if (fscxt == NULL) {
- fscxt = CreateGlobalMemory("Filesystem");
- }
- currentContext = MemoryContextSwitchTo((MemoryContext)fscxt);
+ if (fscxt == NULL)
+ {
+ fscxt = CreateGlobalMemory("Filesystem");
+ }
+ currentContext = MemoryContextSwitchTo((MemoryContext) fscxt);
- lobjDesc = inv_open(lobjId, mode);
-
- if (lobjDesc == NULL) { /* lookup failed */
- MemoryContextSwitchTo(currentContext);
-#if FSDB
- elog(NOTICE,"cannot open large object %d", lobjId);
+ lobjDesc = inv_open(lobjId, mode);
+
+ if (lobjDesc == NULL)
+ { /* lookup failed */
+ MemoryContextSwitchTo(currentContext);
+#if FSDB
+ elog(NOTICE, "cannot open large object %d", lobjId);
#endif
- return -1;
- }
-
- fd = newLOfd(lobjDesc);
+ return -1;
+ }
+
+ fd = newLOfd(lobjDesc);
- /* switch context back to orig. */
- MemoryContextSwitchTo(currentContext);
+ /* switch context back to orig. */
+ MemoryContextSwitchTo(currentContext);
- return fd;
+ return fd;
}
int
lo_close(int fd)
{
- MemoryContext currentContext;
-
- if (fd >= MAX_LOBJ_FDS) {
- elog(WARN,"lo_close: large obj descriptor (%d) out of range", fd);
- return -2;
- }
- if (cookies[fd] == NULL) {
- elog(WARN,"lo_close: invalid large obj descriptor (%d)", fd);
- return -3;
- }
+ MemoryContext currentContext;
+
+ if (fd >= MAX_LOBJ_FDS)
+ {
+ elog(WARN, "lo_close: large obj descriptor (%d) out of range", fd);
+ return -2;
+ }
+ if (cookies[fd] == NULL)
+ {
+ elog(WARN, "lo_close: invalid large obj descriptor (%d)", fd);
+ return -3;
+ }
#if FSDB
- elog(NOTICE,"LOclose(%d)",fd);
+ elog(NOTICE, "LOclose(%d)", fd);
#endif
- Assert(fscxt != NULL);
- currentContext = MemoryContextSwitchTo((MemoryContext)fscxt);
+ Assert(fscxt != NULL);
+ currentContext = MemoryContextSwitchTo((MemoryContext) fscxt);
- inv_close(cookies[fd]);
+ inv_close(cookies[fd]);
- MemoryContextSwitchTo(currentContext);
+ MemoryContextSwitchTo(currentContext);
- deleteLOfd(fd);
- return 0;
+ deleteLOfd(fd);
+ return 0;
}
/*
- * We assume the large object supports byte oriented reads and seeks so
- * that our work is easier.
+ * We assume the large object supports byte oriented reads and seeks so
+ * that our work is easier.
*/
int
lo_read(int fd, char *buf, int len)
{
- Assert(cookies[fd]!=NULL);
- return inv_read(cookies[fd], buf, len);
+ Assert(cookies[fd] != NULL);
+ return inv_read(cookies[fd], buf, len);
}
int
lo_write(int fd, char *buf, int len)
{
- Assert(cookies[fd]!=NULL);
- return inv_write(cookies[fd], buf, len);
+ Assert(cookies[fd] != NULL);
+ return inv_write(cookies[fd], buf, len);
}
int
lo_lseek(int fd, int offset, int whence)
{
- MemoryContext currentContext;
- int ret;
+ MemoryContext currentContext;
+ int ret;
- if (fd >= MAX_LOBJ_FDS) {
- elog(WARN,"lo_seek: large obj descriptor (%d) out of range", fd);
- return -2;
- }
+ if (fd >= MAX_LOBJ_FDS)
+ {
+ elog(WARN, "lo_seek: large obj descriptor (%d) out of range", fd);
+ return -2;
+ }
- currentContext = MemoryContextSwitchTo((MemoryContext)fscxt);
+ currentContext = MemoryContextSwitchTo((MemoryContext) fscxt);
- ret = inv_seek(cookies[fd], offset, whence);
+ ret = inv_seek(cookies[fd], offset, whence);
- MemoryContextSwitchTo(currentContext);
+ MemoryContextSwitchTo(currentContext);
- return ret;
+ return ret;
}
Oid
lo_creat(int mode)
{
- LargeObjectDesc *lobjDesc;
- MemoryContext currentContext;
- Oid lobjId;
-
- if (fscxt == NULL) {
- fscxt = CreateGlobalMemory("Filesystem");
- }
-
- currentContext = MemoryContextSwitchTo((MemoryContext)fscxt);
-
- lobjDesc = inv_create(mode);
-
- if (lobjDesc == NULL) {
+ LargeObjectDesc *lobjDesc;
+ MemoryContext currentContext;
+ Oid lobjId;
+
+ if (fscxt == NULL)
+ {
+ fscxt = CreateGlobalMemory("Filesystem");
+ }
+
+ currentContext = MemoryContextSwitchTo((MemoryContext) fscxt);
+
+ lobjDesc = inv_create(mode);
+
+ if (lobjDesc == NULL)
+ {
+ MemoryContextSwitchTo(currentContext);
+ return InvalidOid;
+ }
+
+ lobjId = lobjDesc->heap_r->rd_id;
+
+ inv_close(lobjDesc);
+
+ /* switch context back to original memory context */
MemoryContextSwitchTo(currentContext);
- return InvalidOid;
- }
-
- lobjId = lobjDesc->heap_r->rd_id;
-
- inv_close(lobjDesc);
-
- /* switch context back to original memory context */
- MemoryContextSwitchTo(currentContext);
-
- return lobjId;
+
+ return lobjId;
}
int
lo_tell(int fd)
{
- if (fd >= MAX_LOBJ_FDS) {
- elog(WARN,"lo_tell: large object descriptor (%d) out of range",fd);
- return -2;
- }
- if (cookies[fd] == NULL) {
- elog(WARN,"lo_tell: invalid large object descriptor (%d)",fd);
- return -3;
- }
- return inv_tell(cookies[fd]);
+ if (fd >= MAX_LOBJ_FDS)
+ {
+ elog(WARN, "lo_tell: large object descriptor (%d) out of range", fd);
+ return -2;
+ }
+ if (cookies[fd] == NULL)
+ {
+ elog(WARN, "lo_tell: invalid large object descriptor (%d)", fd);
+ return -3;
+ }
+ return inv_tell(cookies[fd]);
}
int
lo_unlink(Oid lobjId)
{
- return (inv_destroy(lobjId));
+ return (inv_destroy(lobjId));
}
/*****************************************************************************
- * Read/Write using varlena
+ * Read/Write using varlena
*****************************************************************************/
struct varlena *
loread(int fd, int len)
{
- struct varlena *retval;
- int totalread = 0;
-
- retval = (struct varlena *)palloc(sizeof(int32) + len);
- totalread = lo_read(fd, VARDATA(retval), len);
- VARSIZE(retval) = totalread + sizeof(int32);
-
- return retval;
+ struct varlena *retval;
+ int totalread = 0;
+
+ retval = (struct varlena *) palloc(sizeof(int32) + len);
+ totalread = lo_read(fd, VARDATA(retval), len);
+ VARSIZE(retval) = totalread + sizeof(int32);
+
+ return retval;
}
-int lowrite(int fd, struct varlena *wbuf)
+int
+lowrite(int fd, struct varlena * wbuf)
{
- int totalwritten;
- int bytestowrite;
-
- bytestowrite = VARSIZE(wbuf) - sizeof(int32);
- totalwritten = lo_write(fd, VARDATA(wbuf), bytestowrite);
- return totalwritten;
+ int totalwritten;
+ int bytestowrite;
+
+ bytestowrite = VARSIZE(wbuf) - sizeof(int32);
+ totalwritten = lo_write(fd, VARDATA(wbuf), bytestowrite);
+ return totalwritten;
}
/*****************************************************************************
- * Import/Export of Large Object
+ * Import/Export of Large Object
*****************************************************************************/
/*
* lo_import -
- * imports a file as an (inversion) large object.
+ * imports a file as an (inversion) large object.
*/
Oid
-lo_import(text *filename)
+lo_import(text * filename)
{
- int fd;
- int nbytes, tmp;
-#define BUFSIZE 1024
- char buf[BUFSIZE];
- char fnamebuf[8192];
- LargeObjectDesc *lobj;
- Oid lobjOid;
-
- /*
- * open the file to be read in
- */
- strNcpy(fnamebuf, VARDATA(filename), VARSIZE(filename) - VARHDRSZ);
- fd = open(fnamebuf, O_RDONLY, 0666);
- if (fd < 0) { /* error */
- elog(WARN, "be_lo_import: can't open unix file\"%s\"\n",
- fnamebuf);
- }
-
- /*
- * create an inversion "object"
- */
- lobj = inv_create(INV_READ|INV_WRITE);
- if (lobj == NULL) {
- elog(WARN, "lo_import: can't create inv object for \"%s\"",
- fnamebuf);
- }
-
- /*
- * the oid for the large object is just the oid of the relation
- * XInv??? which contains the data.
- */
- lobjOid = lobj->heap_r->rd_id;
-
- /*
- * read in from the Unix file and write to the inversion file
- */
- while ((nbytes = read(fd, buf, BUFSIZE)) > 0) {
- tmp = inv_write(lobj, buf, nbytes);
- if (tmp < nbytes) {
- elog(WARN, "lo_import: error while reading \"%s\"",
- fnamebuf);
+ int fd;
+ int nbytes,
+ tmp;
+
+#define BUFSIZE 1024
+ char buf[BUFSIZE];
+ char fnamebuf[8192];
+ LargeObjectDesc *lobj;
+ Oid lobjOid;
+
+ /*
+ * open the file to be read in
+ */
+ strNcpy(fnamebuf, VARDATA(filename), VARSIZE(filename) - VARHDRSZ);
+ fd = open(fnamebuf, O_RDONLY, 0666);
+ if (fd < 0)
+ { /* error */
+ elog(WARN, "be_lo_import: can't open unix file\"%s\"\n",
+ fnamebuf);
}
- }
- close(fd);
- inv_close(lobj);
+ /*
+ * create an inversion "object"
+ */
+ lobj = inv_create(INV_READ | INV_WRITE);
+ if (lobj == NULL)
+ {
+ elog(WARN, "lo_import: can't create inv object for \"%s\"",
+ fnamebuf);
+ }
- return lobjOid;
+ /*
+ * the oid for the large object is just the oid of the relation
+ * XInv??? which contains the data.
+ */
+ lobjOid = lobj->heap_r->rd_id;
+
+ /*
+ * read in from the Unix file and write to the inversion file
+ */
+ while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
+ {
+ tmp = inv_write(lobj, buf, nbytes);
+ if (tmp < nbytes)
+ {
+ elog(WARN, "lo_import: error while reading \"%s\"",
+ fnamebuf);
+ }
+ }
+
+ close(fd);
+ inv_close(lobj);
+
+ return lobjOid;
}
/*
* lo_export -
- * exports an (inversion) large object.
+ * exports an (inversion) large object.
*/
int4
-lo_export(Oid lobjId, text *filename)
+lo_export(Oid lobjId, text * filename)
{
- int fd;
- int nbytes, tmp;
-#define BUFSIZE 1024
- char buf[BUFSIZE];
- char fnamebuf[8192];
- LargeObjectDesc *lobj;
- mode_t oumask;
-
- /*
- * create an inversion "object"
- */
- lobj = inv_open(lobjId, INV_READ);
- if (lobj == NULL) {
- elog(WARN, "lo_export: can't open inv object %d",
- lobjId);
- }
-
- /*
- * open the file to be written to
- */
- oumask = umask((mode_t) 0);
- strNcpy(fnamebuf, VARDATA(filename), VARSIZE(filename) - VARHDRSZ);
- fd = open(fnamebuf, O_CREAT|O_WRONLY, 0666);
- umask(oumask);
- if (fd < 0) { /* error */
- elog(WARN, "lo_export: can't open unix file\"%s\"",
- fnamebuf);
- }
-
- /*
- * read in from the Unix file and write to the inversion file
- */
- while ((nbytes = inv_read(lobj, buf, BUFSIZE)) > 0) {
- tmp = write(fd, buf, nbytes);
- if (tmp < nbytes) {
- elog(WARN, "lo_export: error while writing \"%s\"",
- fnamebuf);
+ int fd;
+ int nbytes,
+ tmp;
+
+#define BUFSIZE 1024
+ char buf[BUFSIZE];
+ char fnamebuf[8192];
+ LargeObjectDesc *lobj;
+ mode_t oumask;
+
+ /*
+ * create an inversion "object"
+ */
+ lobj = inv_open(lobjId, INV_READ);
+ if (lobj == NULL)
+ {
+ elog(WARN, "lo_export: can't open inv object %d",
+ lobjId);
+ }
+
+ /*
+ * open the file to be written to
+ */
+ oumask = umask((mode_t) 0);
+ strNcpy(fnamebuf, VARDATA(filename), VARSIZE(filename) - VARHDRSZ);
+ fd = open(fnamebuf, O_CREAT | O_WRONLY, 0666);
+ umask(oumask);
+ if (fd < 0)
+ { /* error */
+ elog(WARN, "lo_export: can't open unix file\"%s\"",
+ fnamebuf);
}
- }
- inv_close(lobj);
- close(fd);
+ /*
+ * read in from the Unix file and write to the inversion file
+ */
+ while ((nbytes = inv_read(lobj, buf, BUFSIZE)) > 0)
+ {
+ tmp = write(fd, buf, nbytes);
+ if (tmp < nbytes)
+ {
+ elog(WARN, "lo_export: error while writing \"%s\"",
+ fnamebuf);
+ }
+ }
+
+ inv_close(lobj);
+ close(fd);
- return 1;
+ return 1;
}
/*****************************************************************************
- * Support routines for this file
+ * Support routines for this file
*****************************************************************************/
static int
-newLOfd(LargeObjectDesc *lobjCookie)
+newLOfd(LargeObjectDesc * lobjCookie)
{
- int i;
-
- for (i = 0; i < MAX_LOBJ_FDS; i++) {
-
- if (cookies[i] == NULL) {
- cookies[i] = lobjCookie;
- return i;
+ int i;
+
+ for (i = 0; i < MAX_LOBJ_FDS; i++)
+ {
+
+ if (cookies[i] == NULL)
+ {
+ cookies[i] = lobjCookie;
+ return i;
+ }
}
- }
- return -1;
+ return -1;
}
-static void
+static void
deleteLOfd(int fd)
{
- cookies[fd] = NULL;
+ cookies[fd] = NULL;
}
diff --git a/src/backend/libpq/be-pqexec.c b/src/backend/libpq/be-pqexec.c
index caa710129a9..06185e4534f 100644
--- a/src/backend/libpq/be-pqexec.c
+++ b/src/backend/libpq/be-pqexec.c
@@ -1,24 +1,24 @@
/*-------------------------------------------------------------------------
*
* be-pqexec.c--
- * support for executing POSTGRES commands and functions from a
- * user-defined function in a backend.
+ * support for executing POSTGRES commands and functions from a
+ * user-defined function in a backend.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-pqexec.c,v 1.4 1997/08/19 21:31:31 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-pqexec.c,v 1.5 1997/09/07 04:42:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * PQfn - call a POSTGRES function
- * PQexec - execute a POSTGRES query
- *
+ * PQfn - call a POSTGRES function
+ * PQexec - execute a POSTGRES query
+ *
* NOTES
- * These routines are compiled into the postgres backend.
+ * These routines are compiled into the postgres backend.
*/
#include <postgres.h>
@@ -32,356 +32,395 @@
#include <utils/exc.h>
#include <utils/builtins.h>
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static char *strmake(char *str, int len);
+static char *strmake(char *str, int len);
/* ----------------------------------------------------------------
- * PQ interface routines
+ * PQ interface routines
* ----------------------------------------------------------------
*/
/* ----------------
- * PQfn - Send a function call to the POSTGRES backend.
+ * PQfn - Send a function call to the POSTGRES backend.
*
- * fnid : function id
- * result_buf : pointer to result buffer (&int if integer)
- * result_len : length of return value.
- * result_is_int : If the result is an integer, this must be non-zero
- * args : pointer to a NULL terminated arg array.
- * (length, if integer, and result-pointer)
- * nargs : # of arguments in args array.
+ * fnid : function id
+ * result_buf : pointer to result buffer (&int if integer)
+ * result_len : length of return value.
+ * result_is_int : If the result is an integer, this must be non-zero
+ * args : pointer to a NULL terminated arg array.
+ * (length, if integer, and result-pointer)
+ * nargs : # of arguments in args array.
*
- * This code scavanged from HandleFunctionRequest() in tcop/fastpath.h
+ * This code scavanged from HandleFunctionRequest() in tcop/fastpath.h
* ----------------
*/
-char *
+char *
PQfn(int fnid,
- int *result_buf, /* can't use void, dec compiler barfs */
- int result_len,
- int result_is_int,
- PQArgBlock *args,
- int nargs)
+ int *result_buf, /* can't use void, dec compiler barfs */
+ int result_len,
+ int result_is_int,
+ PQArgBlock * args,
+ int nargs)
{
- char *retval; /* XXX - should be datum, maybe ? */
- char *arg[8];
- int i;
-
- /* ----------------
- * fill args[] array
- * ----------------
- */
- for (i = 0; i < nargs; i++) {
- if (args[i].len == VAR_LENGTH_ARG) {
- arg[i] = (char*) args[i].u.ptr;
- } else if (args[i].len > 4) {
- elog(WARN,"arg_length of argument %d too long",i);
- } else {
- arg[i] = (char*)args[i].u.integer;
+ char *retval; /* XXX - should be datum, maybe ? */
+ char *arg[8];
+ int i;
+
+ /* ----------------
+ * fill args[] array
+ * ----------------
+ */
+ for (i = 0; i < nargs; i++)
+ {
+ if (args[i].len == VAR_LENGTH_ARG)
+ {
+ arg[i] = (char *) args[i].u.ptr;
+ }
+ else if (args[i].len > 4)
+ {
+ elog(WARN, "arg_length of argument %d too long", i);
+ }
+ else
+ {
+ arg[i] = (char *) args[i].u.integer;
+ }
}
- }
-
- /* ----------------
- * call the postgres function manager
- * ----------------
- */
- retval = (char *)
- fmgr(fnid, arg[0], arg[1], arg[2], arg[3],
- arg[4], arg[5], arg[6], arg[7]);
-
- /* ----------------
- * put the result in the buffer the user specified and
- * return the proper code.
- * ----------------
- */
- if (retval == (char *) NULL) /* void retval */
- return "0";
-
- if (result_is_int) {
- *result_buf = (int) retval;
- } else {
- memmove(result_buf, retval, result_len);
- }
- return "G";
+
+ /* ----------------
+ * call the postgres function manager
+ * ----------------
+ */
+ retval = (char *)
+ fmgr(fnid, arg[0], arg[1], arg[2], arg[3],
+ arg[4], arg[5], arg[6], arg[7]);
+
+ /* ----------------
+ * put the result in the buffer the user specified and
+ * return the proper code.
+ * ----------------
+ */
+ if (retval == (char *) NULL)/* void retval */
+ return "0";
+
+ if (result_is_int)
+ {
+ *result_buf = (int) retval;
+ }
+ else
+ {
+ memmove(result_buf, retval, result_len);
+ }
+ return "G";
}
/* ----------------
- * PQexec - Send a query to the POSTGRES backend
+ * PQexec - Send a query to the POSTGRES backend
*
- * The return value is a string.
- * If 0 or more tuples fetched from the backend, return "P portal-name".
- * If a query is does not return tuples, return "C query-command".
- * If there is an error: return "E error-message".
+ * The return value is a string.
+ * If 0 or more tuples fetched from the backend, return "P portal-name".
+ * If a query is does not return tuples, return "C query-command".
+ * If there is an error: return "E error-message".
*
- * Note: if we get a serious error or an elog(WARN), then PQexec never
- * returns because the system longjmp's back to the main loop.
+ * Note: if we get a serious error or an elog(WARN), then PQexec never
+ * returns because the system longjmp's back to the main loop.
* ----------------
*/
-char *
+char *
PQexec(char *query)
{
- PortalEntry *entry = NULL;
- char *result = NULL;
-
- /* ----------------
- * create a new portal and put it on top of the portal stack.
- * ----------------
- */
- entry = (PortalEntry *) be_newportal();
- be_portalpush(entry);
-
- /* ----------------
- * pg_eval_dest will put the query results in a portal which will
- * end up on the top of the portal stack.
- * ----------------
- */
- pg_eval_dest(query, (char **) NULL, (Oid *) NULL, 0, Local);
-
- /* ----------------
- * pop the portal off the portal stack and return the
- * result. Note if result is null, we return C.
- * ----------------
- */
- entry = (PortalEntry *) be_portalpop();
- result = entry->result;
- if (result == NULL) {
- char *PQE = "Cnull PQexec result";
- result = pstrdup(PQE);
- }
-
- if (result[0] != 'P')
+ PortalEntry *entry = NULL;
+ char *result = NULL;
+
+ /* ----------------
+ * create a new portal and put it on top of the portal stack.
+ * ----------------
+ */
+ entry = (PortalEntry *) be_newportal();
+ be_portalpush(entry);
+
+ /* ----------------
+ * pg_eval_dest will put the query results in a portal which will
+ * end up on the top of the portal stack.
+ * ----------------
+ */
+ pg_eval_dest(query, (char **) NULL, (Oid *) NULL, 0, Local);
+
+ /* ----------------
+ * pop the portal off the portal stack and return the
+ * result. Note if result is null, we return C.
+ * ----------------
+ */
+ entry = (PortalEntry *) be_portalpop();
+ result = entry->result;
+ if (result == NULL)
{
- /* some successful command was executed,
- but it's not one where we return the portal name so
- here we should be sure to clear out the portal
- (since the caller has no handle on it)
- */
- pbuf_close(entry->name);
-
+ char *PQE = "Cnull PQexec result";
+
+ result = pstrdup(PQE);
}
- return result;
+
+ if (result[0] != 'P')
+ {
+
+ /*
+ * some successful command was executed, but it's not one where we
+ * return the portal name so here we should be sure to clear out
+ * the portal (since the caller has no handle on it)
+ */
+ pbuf_close(entry->name);
+
+ }
+ return result;
}
/* ----------------------------------------------------------------
- * pqtest support
+ * pqtest support
* ----------------------------------------------------------------
*/
/* ----------------
- * pqtest_PQexec takes a text query and returns the number of
- * tuples it returns. Note: there is no need to PQclear()
- * here - the memory will go away at end transaction.
+ * pqtest_PQexec takes a text query and returns the number of
+ * tuples it returns. Note: there is no need to PQclear()
+ * here - the memory will go away at end transaction.
* ----------------
*/
int
pqtest_PQexec(char *q)
{
- PortalBuffer *a;
- char *res;
- int t;
-
- /* ----------------
- * execute the postgres query
- * ----------------
- */
- res = PQexec(q);
-
- /* ----------------
- * return number of tuples in portal or 0 if command returns no tuples.
- * ----------------
- */
- t = 0;
- switch(res[0]) {
- case 'P':
- a = PQparray(&res[1]);
- if (a == NULL)
- elog(WARN, "pqtest_PQexec: PQparray could not find portal %s",
- res);
-
- t = PQntuples(a);
- break;
- case 'C':
- break;
- default:
- elog(NOTICE, "pqtest_PQexec: PQexec(%s) returns %s", q, res);
- break;
- }
-
- return t;
+ PortalBuffer *a;
+ char *res;
+ int t;
+
+ /* ----------------
+ * execute the postgres query
+ * ----------------
+ */
+ res = PQexec(q);
+
+ /* ----------------
+ * return number of tuples in portal or 0 if command returns no tuples.
+ * ----------------
+ */
+ t = 0;
+ switch (res[0])
+ {
+ case 'P':
+ a = PQparray(&res[1]);
+ if (a == NULL)
+ elog(WARN, "pqtest_PQexec: PQparray could not find portal %s",
+ res);
+
+ t = PQntuples(a);
+ break;
+ case 'C':
+ break;
+ default:
+ elog(NOTICE, "pqtest_PQexec: PQexec(%s) returns %s", q, res);
+ break;
+ }
+
+ return t;
}
/* ----------------
- * utilities for pqtest_PQfn()
+ * utilities for pqtest_PQfn()
* ----------------
*/
-static char *
+static char *
strmake(char *str, int len)
{
- char *newstr;
- if (str == NULL) return NULL;
- if (len <= 0) len = strlen(str);
-
- newstr = (char *) palloc((unsigned) len+1);
- strNcpy(newstr, str, len);
- newstr[len] = (char) 0;
- return newstr;
+ char *newstr;
+
+ if (str == NULL)
+ return NULL;
+ if (len <= 0)
+ len = strlen(str);
+
+ newstr = (char *) palloc((unsigned) len + 1);
+ strNcpy(newstr, str, len);
+ newstr[len] = (char) 0;
+ return newstr;
}
#define SKIP 0
#define SCAN 1
-static char spacestr[] = " ";
+static char spacestr[] = " ";
static int
strparse(char *s, char **fields, int *offsets, int maxfields)
{
- int len = strlen(s);
- char *cp = s, *end = cp + len, *ep;
- int parsed = 0;
- int mode = SKIP, i = 0;
-
- if (*(end - 1) == '\n') end--;
-
- for (i=0; i<maxfields; i++)
- fields[i] = spacestr;
-
- i = 0;
- while (!parsed) {
- if (mode == SKIP) {
-
- while ((cp < end) &&
- (*cp == ' ' || *cp == '\t'))
- cp++;
- if (cp < end) mode = SCAN;
- else parsed = 1;
-
- } else {
-
- ep = cp;
- while ((ep < end) && (*ep != ' ' && *ep != '\t'))
- ep++;
-
- if (ep < end) mode = SKIP;
- else parsed = 1;
-
- fields[i] = strmake(cp, ep - cp);
- if (offsets != NULL)
- offsets[i] = cp - s;
-
- i++;
- cp = ep;
- if (i > maxfields)
- parsed = 1;
-
+ int len = strlen(s);
+ char *cp = s,
+ *end = cp + len,
+ *ep;
+ int parsed = 0;
+ int mode = SKIP,
+ i = 0;
+
+ if (*(end - 1) == '\n')
+ end--;
+
+ for (i = 0; i < maxfields; i++)
+ fields[i] = spacestr;
+
+ i = 0;
+ while (!parsed)
+ {
+ if (mode == SKIP)
+ {
+
+ while ((cp < end) &&
+ (*cp == ' ' || *cp == '\t'))
+ cp++;
+ if (cp < end)
+ mode = SCAN;
+ else
+ parsed = 1;
+
+ }
+ else
+ {
+
+ ep = cp;
+ while ((ep < end) && (*ep != ' ' && *ep != '\t'))
+ ep++;
+
+ if (ep < end)
+ mode = SKIP;
+ else
+ parsed = 1;
+
+ fields[i] = strmake(cp, ep - cp);
+ if (offsets != NULL)
+ offsets[i] = cp - s;
+
+ i++;
+ cp = ep;
+ if (i > maxfields)
+ parsed = 1;
+
+ }
}
- }
- return i;
+ return i;
}
/* ----------------
- * pqtest_PQfn converts it's string into a PQArgBlock and
- * calls the specified function, which is assumed to return
- * an integer value.
+ * pqtest_PQfn converts it's string into a PQArgBlock and
+ * calls the specified function, which is assumed to return
+ * an integer value.
* ----------------
*/
int
pqtest_PQfn(char *q)
{
- int k, j, i, v, f, offsets;
- char *fields[8];
- PQArgBlock pqargs[7];
- int res;
- char *pqres;
-
- /* ----------------
- * parse q into fields
- * ----------------
- */
- i = strparse(q, fields, &offsets, 8);
- printf("pqtest_PQfn: strparse returns %d fields\n", i); /* debug */
- if (i == 0)
- return -1;
-
- /* ----------------
- * get the function id
- * ----------------
- */
- f = atoi(fields[0]);
- printf("pqtest_PQfn: func is %d\n", f); /* debug */
- if (f == 0)
- return -1;
-
- /* ----------------
- * build a PQArgBlock
- * ----------------
- */
- for (j=1; j<i && j<8; j++) {
- k = j-1;
- v = atoi(fields[j]);
- if (v != 0 || (v == 0 && fields[j][0] == '0')) {
- pqargs[k].len = 4;
- pqargs[k].u.integer = v;
- printf("pqtest_PQfn: arg %d is int %d\n", k, v); /* debug */
- } else {
- pqargs[k].len = VAR_LENGTH_ARG;
- pqargs[k].u.ptr = (int *) textin(fields[j]);
- printf("pqtest_PQfn: arg %d is text %s\n", k, fields[j]); /*debug*/
+ int k,
+ j,
+ i,
+ v,
+ f,
+ offsets;
+ char *fields[8];
+ PQArgBlock pqargs[7];
+ int res;
+ char *pqres;
+
+ /* ----------------
+ * parse q into fields
+ * ----------------
+ */
+ i = strparse(q, fields, &offsets, 8);
+ printf("pqtest_PQfn: strparse returns %d fields\n", i); /* debug */
+ if (i == 0)
+ return -1;
+
+ /* ----------------
+ * get the function id
+ * ----------------
+ */
+ f = atoi(fields[0]);
+ printf("pqtest_PQfn: func is %d\n", f); /* debug */
+ if (f == 0)
+ return -1;
+
+ /* ----------------
+ * build a PQArgBlock
+ * ----------------
+ */
+ for (j = 1; j < i && j < 8; j++)
+ {
+ k = j - 1;
+ v = atoi(fields[j]);
+ if (v != 0 || (v == 0 && fields[j][0] == '0'))
+ {
+ pqargs[k].len = 4;
+ pqargs[k].u.integer = v;
+ printf("pqtest_PQfn: arg %d is int %d\n", k, v); /* debug */
+ }
+ else
+ {
+ pqargs[k].len = VAR_LENGTH_ARG;
+ pqargs[k].u.ptr = (int *) textin(fields[j]);
+ printf("pqtest_PQfn: arg %d is text %s\n", k, fields[j]); /* debug */
+ }
+ }
+
+ /* ----------------
+ * call PQfn
+ * ----------------
+ */
+ pqres = PQfn(f, &res, 4, 1, pqargs, i - 1);
+ printf("pqtest_PQfn: pqres is %s\n", pqres); /* debug */
+
+ /* ----------------
+ * free memory used
+ * ----------------
+ */
+ for (j = 0; j < i; j++)
+ {
+ pfree(fields[j]);
+ if (pqargs[j].len == VAR_LENGTH_ARG)
+ pfree(pqargs[j].u.ptr);
}
- }
-
- /* ----------------
- * call PQfn
- * ----------------
- */
- pqres = PQfn(f, &res, 4, 1, pqargs, i-1);
- printf("pqtest_PQfn: pqres is %s\n", pqres); /* debug */
-
- /* ----------------
- * free memory used
- * ----------------
- */
- for (j=0; j<i; j++) {
- pfree(fields[j]);
- if (pqargs[j].len == VAR_LENGTH_ARG)
- pfree(pqargs[j].u.ptr);
- }
-
- /* ----------------
- * return result
- * ----------------
- */
- printf("pqtest_PQfn: res is %d\n", res); /* debugg */
- return res;
+
+ /* ----------------
+ * return result
+ * ----------------
+ */
+ printf("pqtest_PQfn: res is %d\n", res); /* debugg */
+ return res;
}
/* ----------------
- * pqtest looks at the first character of it's test argument
- * and decides which of pqtest_PQexec or pqtest_PQfn to call.
+ * pqtest looks at the first character of it's test argument
+ * and decides which of pqtest_PQexec or pqtest_PQfn to call.
* ----------------
*/
int32
-pqtest(struct varlena *vlena)
+pqtest(struct varlena * vlena)
{
- char *q;
-
- /* ----------------
- * get the query
- * ----------------
- */
- q = textout(vlena);
- if (q == NULL)
- return -1;
-
- switch(q[0]) {
- case '%':
- return pqtest_PQfn(&q[1]);
- break;
- default:
- return pqtest_PQexec(q);
- break;
- }
- return(0);
+ char *q;
+
+ /* ----------------
+ * get the query
+ * ----------------
+ */
+ q = textout(vlena);
+ if (q == NULL)
+ return -1;
+
+ switch (q[0])
+ {
+ case '%':
+ return pqtest_PQfn(&q[1]);
+ break;
+ default:
+ return pqtest_PQexec(q);
+ break;
+ }
+ return (0);
}
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 0cc2bbf6ac9..014eca14fa3 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* hba.c--
- * Routines to handle host based authentication (that's the scheme
- * wherein you authenticate a user by seeing what IP address the system
- * says he comes from and possibly using ident).
+ * Routines to handle host based authentication (that's the scheme
+ * wherein you authenticate a user by seeing what IP address the system
+ * says he comes from and possibly using ident).
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.19 1997/08/27 03:48:31 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.20 1997/09/07 04:42:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,263 +27,356 @@
#include <libpq/libpq.h>
#include <libpq/pqcomm.h>
#include <libpq/hba.h>
-#include <port/inet_aton.h> /* For inet_aton() */
+#include <port/inet_aton.h> /* For inet_aton() */
#include <storage/fd.h>
/* Some standard C libraries, including GNU, have an isblank() function.
Others, including Solaris, do not. So we have our own.
*/
-static bool
-isblank(const char c) {
- return(c == ' ' || c == 9 /* tab */);
+static bool
+isblank(const char c)
+{
+ return (c == ' ' || c == 9 /* tab */ );
}
-static void
-next_token(FILE *fp, char *buf, const int bufsz) {
+static void
+next_token(FILE * fp, char *buf, const int bufsz)
+{
/*--------------------------------------------------------------------------
Grab one token out of fp. Tokens are strings of non-blank
characters bounded by blank characters, beginning of line, and end
- of line. Blank means space or tab. Return the token as *buf.
+ of line. Blank means space or tab. Return the token as *buf.
Leave file positioned to character immediately after the token or
EOF, whichever comes first. If no more tokens on line, return null
string as *buf and position file to beginning of next line or EOF,
- whichever comes first.
+ whichever comes first.
--------------------------------------------------------------------------*/
- int c;
- char *eb = buf+(bufsz-1);
-
- /* Move over inital token-delimiting blanks */
- while (isblank(c = getc(fp))) ;
-
- if (c != '\n') {
- /* build a token in buf of next characters up to EOF, eol, or blank. */
- while (c != EOF && c != '\n' && !isblank(c)) {
- if (buf < eb) *buf++ = c;
- c = getc(fp);
- /* Put back the char right after the token (putting back EOF is ok) */
- }
- ungetc(c, fp);
- }
- *buf = '\0';
+ int c;
+ char *eb = buf + (bufsz - 1);
+
+ /* Move over inital token-delimiting blanks */
+ while (isblank(c = getc(fp)));
+
+ if (c != '\n')
+ {
+
+ /*
+ * build a token in buf of next characters up to EOF, eol, or
+ * blank.
+ */
+ while (c != EOF && c != '\n' && !isblank(c))
+ {
+ if (buf < eb)
+ *buf++ = c;
+ c = getc(fp);
+
+ /*
+ * Put back the char right after the token (putting back EOF
+ * is ok)
+ */
+ }
+ ungetc(c, fp);
+ }
+ *buf = '\0';
}
static void
-read_through_eol(FILE *file) {
- int c;
- do
- c = getc(file);
- while (c != '\n' && c != EOF);
+read_through_eol(FILE * file)
+{
+ int c;
+
+ do
+ c = getc(file);
+ while (c != '\n' && c != EOF);
}
static void
-read_hba_entry2(FILE *file, enum Userauth *userauth_p, char usermap_name[],
- bool *error_p, bool *matches_p, bool find_password_entries) {
+read_hba_entry2(FILE * file, enum Userauth * userauth_p, char usermap_name[],
+ bool * error_p, bool * matches_p, bool find_password_entries)
+{
/*--------------------------------------------------------------------------
Read from file FILE the rest of a host record, after the mask field,
and return the interpretation of it as *userauth_p, usermap_name, and
*error_p.
---------------------------------------------------------------------------*/
- char buf[MAX_TOKEN];
-
- bool userauth_valid;
-
- /* Get authentication type token. */
- next_token(file, buf, sizeof(buf));
- userauth_valid = false;
- if (buf[0] == '\0') {
- *error_p = true;
- } else {
- userauth_valid = true;
- if(strcmp(buf, "trust") == 0) {
- *userauth_p = Trust;
- } else if(strcmp(buf, "ident") == 0) {
- *userauth_p = Ident;
- } else if(strcmp(buf, "password") == 0) {
- *userauth_p = Password;
- } else {
- userauth_valid = false;
- }
-
- if((find_password_entries && strcmp(buf, "password") == 0) ||
- (!find_password_entries && strcmp(buf, "password") != 0)) {
- *matches_p = true;
- } else {
- *matches_p = false;
- }
- }
-
- if(!userauth_valid || !*matches_p || *error_p) {
- if (!userauth_valid) {
- *error_p = true;
- }
- read_through_eol(file);
- } else {
- /* Get the map name token, if any */
- next_token(file, buf, sizeof(buf));
- if (buf[0] == '\0') {
- *error_p = false;
- usermap_name[0] = '\0';
- } else {
- strncpy(usermap_name, buf, USERMAP_NAME_SIZE);
- next_token(file, buf, sizeof(buf));
- if (buf[0] != '\0') {
- *error_p = true;
- read_through_eol(file);
- } else *error_p = false;
- }
- }
+ char buf[MAX_TOKEN];
+
+ bool userauth_valid;
+
+ /* Get authentication type token. */
+ next_token(file, buf, sizeof(buf));
+ userauth_valid = false;
+ if (buf[0] == '\0')
+ {
+ *error_p = true;
+ }
+ else
+ {
+ userauth_valid = true;
+ if (strcmp(buf, "trust") == 0)
+ {
+ *userauth_p = Trust;
+ }
+ else if (strcmp(buf, "ident") == 0)
+ {
+ *userauth_p = Ident;
+ }
+ else if (strcmp(buf, "password") == 0)
+ {
+ *userauth_p = Password;
+ }
+ else
+ {
+ userauth_valid = false;
+ }
+
+ if ((find_password_entries && strcmp(buf, "password") == 0) ||
+ (!find_password_entries && strcmp(buf, "password") != 0))
+ {
+ *matches_p = true;
+ }
+ else
+ {
+ *matches_p = false;
+ }
+ }
+
+ if (!userauth_valid || !*matches_p || *error_p)
+ {
+ if (!userauth_valid)
+ {
+ *error_p = true;
+ }
+ read_through_eol(file);
+ }
+ else
+ {
+ /* Get the map name token, if any */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] == '\0')
+ {
+ *error_p = false;
+ usermap_name[0] = '\0';
+ }
+ else
+ {
+ strncpy(usermap_name, buf, USERMAP_NAME_SIZE);
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ *error_p = true;
+ read_through_eol(file);
+ }
+ else
+ *error_p = false;
+ }
+ }
}
static void
-process_hba_record(FILE *file,
- const struct in_addr ip_addr, const char database[],
- bool *matches_p, bool *error_p,
- enum Userauth *userauth_p, char usermap_name[],
- bool find_password_entries) {
+process_hba_record(FILE * file,
+ const struct in_addr ip_addr, const char database[],
+ bool * matches_p, bool * error_p,
+ enum Userauth * userauth_p, char usermap_name[],
+ bool find_password_entries)
+{
/*---------------------------------------------------------------------------
Process the non-comment record in the config file that is next on the file.
See if it applies to a connection to a host with IP address "ip_addr"
to a database named "database[]". If so, return *matches_p true
and *userauth_p and usermap_name[] as the values from the entry.
If not, return matches_p false. If the record has a syntax error,
- return *error_p true, after issuing a message to stderr. If no error,
+ return *error_p true, after issuing a message to stderr. If no error,
leave *error_p as it was.
---------------------------------------------------------------------------*/
- char buf[MAX_TOKEN]; /* A token from the record */
-
- /* Read the record type field */
- next_token(file, buf, sizeof(buf));
- if (buf[0] == '\0') *matches_p = false;
- else {
- /* if this isn't a "host" record, it can't match. */
- if (strcmp(buf, "host") != 0) {
- *matches_p = false;
- read_through_eol(file);
- } else {
- /* It's a "host" record. Read the database name field. */
- next_token(file, buf, sizeof(buf));
- if (buf[0] == '\0') *matches_p = false;
- else {
- /* If this record isn't for our database, ignore it. */
- if (strcmp(buf, database) != 0 && strcmp(buf, "all") != 0) {
- *matches_p = false;
- read_through_eol(file);
- } else {
- /* Read the IP address field */
- next_token(file, buf, sizeof(buf));
- if (buf[0] == '\0') *matches_p = false;
- else {
- int valid; /* Field is valid dotted decimal */
- /* Remember the IP address field and go get mask field */
- struct in_addr file_ip_addr; /* IP address field value */
-
- valid = inet_aton(buf, &file_ip_addr);
- if (!valid) {
- *matches_p = false;
- read_through_eol(file);
- } else {
- /* Read the mask field */
- next_token(file, buf, sizeof(buf));
- if (buf[0] == '\0') *matches_p = false;
- else {
- struct in_addr mask;
- /* Got mask. Now see if this record is for our host. */
- valid = inet_aton(buf, &mask);
- if (!valid) {
- *matches_p = false;
- read_through_eol(file);
- } else {
- if (((file_ip_addr.s_addr ^ ip_addr.s_addr) & mask.s_addr)
- != 0x0000) {
- *matches_p = false;
- read_through_eol(file);
- } else {
- /* This is the record we're looking for. Read
- the rest of the info from it.
- */
- read_hba_entry2(file, userauth_p, usermap_name,
- error_p, matches_p, find_password_entries);
- if (*error_p) {
- sprintf(PQerrormsg,
- "process_hba_record: invalid syntax in "
- "hba config file "
- "for host record for IP address %s\n",
- inet_ntoa(file_ip_addr));
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
+ char buf[MAX_TOKEN]; /* A token from the record */
+
+ /* Read the record type field */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] == '\0')
+ *matches_p = false;
+ else
+ {
+ /* if this isn't a "host" record, it can't match. */
+ if (strcmp(buf, "host") != 0)
+ {
+ *matches_p = false;
+ read_through_eol(file);
+ }
+ else
+ {
+ /* It's a "host" record. Read the database name field. */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] == '\0')
+ *matches_p = false;
+ else
+ {
+ /* If this record isn't for our database, ignore it. */
+ if (strcmp(buf, database) != 0 && strcmp(buf, "all") != 0)
+ {
+ *matches_p = false;
+ read_through_eol(file);
+ }
+ else
+ {
+ /* Read the IP address field */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] == '\0')
+ *matches_p = false;
+ else
+ {
+ int valid; /* Field is valid dotted
+ * decimal */
+
+ /*
+ * Remember the IP address field and go get mask
+ * field
+ */
+ struct in_addr file_ip_addr; /* IP address field
+ * value */
+
+ valid = inet_aton(buf, &file_ip_addr);
+ if (!valid)
+ {
+ *matches_p = false;
+ read_through_eol(file);
+ }
+ else
+ {
+ /* Read the mask field */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] == '\0')
+ *matches_p = false;
+ else
+ {
+ struct in_addr mask;
+
+ /*
+ * Got mask. Now see if this record is
+ * for our host.
+ */
+ valid = inet_aton(buf, &mask);
+ if (!valid)
+ {
+ *matches_p = false;
+ read_through_eol(file);
+ }
+ else
+ {
+ if (((file_ip_addr.s_addr ^ ip_addr.s_addr) & mask.s_addr)
+ != 0x0000)
+ {
+ *matches_p = false;
+ read_through_eol(file);
+ }
+ else
+ {
+
+ /*
+ * This is the record we're
+ * looking for. Read the rest of
+ * the info from it.
+ */
+ read_hba_entry2(file, userauth_p, usermap_name,
+ error_p, matches_p, find_password_entries);
+ if (*error_p)
+ {
+ sprintf(PQerrormsg,
+ "process_hba_record: invalid syntax in "
+ "hba config file "
+ "for host record for IP address %s\n",
+ inet_ntoa(file_ip_addr));
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
static void
-process_open_config_file(FILE *file,
- const struct in_addr ip_addr, const char database[],
- bool *host_ok_p, enum Userauth *userauth_p,
- char usermap_name[], bool find_password_entries) {
+process_open_config_file(FILE * file,
+ const struct in_addr ip_addr, const char database[],
+ bool * host_ok_p, enum Userauth * userauth_p,
+ char usermap_name[], bool find_password_entries)
+{
/*---------------------------------------------------------------------------
This function does the same thing as find_hba_entry, only with
the config file already open on stream descriptor "file".
----------------------------------------------------------------------------*/
- bool found_entry;
- /* We've processed a record that applies to our connection */
- bool error;
- /* Said record has invalid syntax. */
- bool eof; /* We've reached the end of the file we're reading */
-
- found_entry = false; /* initial value */
- error = false; /* initial value */
- eof = false; /* initial value */
- while (!eof && !found_entry && !error) {
- /* Process a line from the config file */
-
- int c; /* a character read from the file */
-
- c = getc(file); ungetc(c, file);
- if (c == EOF) eof = true;
- else {
- if (c == '#') read_through_eol(file);
- else {
- process_hba_record(file, ip_addr, database,
- &found_entry, &error, userauth_p, usermap_name,
- find_password_entries);
- }
- }
- }
- if (found_entry) {
- if (error) *host_ok_p = false;
- else *host_ok_p = true;
- } else *host_ok_p = false;
-}
+ bool found_entry;
+
+ /* We've processed a record that applies to our connection */
+ bool error;
+
+ /* Said record has invalid syntax. */
+ bool eof; /* We've reached the end of the file we're
+ * reading */
+
+ found_entry = false; /* initial value */
+ error = false; /* initial value */
+ eof = false; /* initial value */
+ while (!eof && !found_entry && !error)
+ {
+ /* Process a line from the config file */
+
+ int c; /* a character read from the file */
+
+ c = getc(file);
+ ungetc(c, file);
+ if (c == EOF)
+ eof = true;
+ else
+ {
+ if (c == '#')
+ read_through_eol(file);
+ else
+ {
+ process_hba_record(file, ip_addr, database,
+ &found_entry, &error, userauth_p, usermap_name,
+ find_password_entries);
+ }
+ }
+ }
+ if (found_entry)
+ {
+ if (error)
+ *host_ok_p = false;
+ else
+ *host_ok_p = true;
+ }
+ else
+ *host_ok_p = false;
+}
void
-find_hba_entry(const char DataDir[], const struct in_addr ip_addr,
- const char database[],
- bool *host_ok_p, enum Userauth *userauth_p,
- char usermap_name[], bool find_password_entries) {
+find_hba_entry(const char DataDir[], const struct in_addr ip_addr,
+ const char database[],
+ bool * host_ok_p, enum Userauth * userauth_p,
+ char usermap_name[], bool find_password_entries)
+{
/*--------------------------------------------------------------------------
Read the config file and find an entry that allows connection from
- host "ip_addr" to database "database". If not found, return
- *host_ok_p == false. If found, return *userauth_p and *usermap_name
+ host "ip_addr" to database "database". If not found, return
+ *host_ok_p == false. If found, return *userauth_p and *usermap_name
representing the contents of that entry.
When a record has invalid syntax, we either ignore it or reject the
@@ -298,133 +391,167 @@ find_hba_entry(const char DataDir[], const struct in_addr ip_addr,
follow directions and just installed his old hba file in the new database
system.
----------------------------------------------------------------------------*/
- int fd;
-
- FILE *file; /* The config file we have to read */
-
- char *old_conf_file;
- /* The name of old config file that better not exist. */
-
- /* Fail if config file by old name exists. */
-
-
- /* put together the full pathname to the old config file */
- old_conf_file = (char *) malloc((strlen(DataDir) +
- strlen(OLD_CONF_FILE)+2)*sizeof(char));
- sprintf(old_conf_file, "%s/%s", DataDir, OLD_CONF_FILE);
-
- if ((fd = open(old_conf_file,O_RDONLY,0)) != -1) {
- /* Old config file exists. Tell this guy he needs to upgrade. */
- close(fd);
- sprintf(PQerrormsg,
- "A file exists by the name used for host-based authentication "
- "in prior releases of Postgres (%s). The name and format of "
- "the configuration file have changed, so this file should be "
- "converted.\n",
- old_conf_file);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- } else {
- char *conf_file; /* The name of the config file we have to read */
-
- /* put together the full pathname to the config file */
- conf_file = (char *) malloc((strlen(DataDir) +
- strlen(CONF_FILE)+2)*sizeof(char));
- sprintf(conf_file, "%s/%s", DataDir, CONF_FILE);
-
- file = AllocateFile(conf_file, "r");
- if (file == NULL) {
- /* The open of the config file failed. */
-
- *host_ok_p = false;
-
- sprintf(PQerrormsg,
- "find_hba_entry: Host-based authentication config file "
- "does not exist or permissions are not setup correctly! "
- "Unable to open file \"%s\".\n",
- conf_file);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- } else {
- process_open_config_file(file, ip_addr, database, host_ok_p, userauth_p,
- usermap_name, find_password_entries);
- FreeFile(file);
- }
- free(conf_file);
- }
- free(old_conf_file);
- return;
+---------------------------------------------------------------------------*/
+ int fd;
+
+ FILE *file; /* The config file we have to read */
+
+ char *old_conf_file;
+
+ /* The name of old config file that better not exist. */
+
+ /* Fail if config file by old name exists. */
+
+
+ /* put together the full pathname to the old config file */
+ old_conf_file = (char *) malloc((strlen(DataDir) +
+ strlen(OLD_CONF_FILE) + 2) * sizeof(char));
+ sprintf(old_conf_file, "%s/%s", DataDir, OLD_CONF_FILE);
+
+ if ((fd = open(old_conf_file, O_RDONLY, 0)) != -1)
+ {
+ /* Old config file exists. Tell this guy he needs to upgrade. */
+ close(fd);
+ sprintf(PQerrormsg,
+ "A file exists by the name used for host-based authentication "
+ "in prior releases of Postgres (%s). The name and format of "
+ "the configuration file have changed, so this file should be "
+ "converted.\n",
+ old_conf_file);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ }
+ else
+ {
+ char *conf_file; /* The name of the config file we
+ * have to read */
+
+ /* put together the full pathname to the config file */
+ conf_file = (char *) malloc((strlen(DataDir) +
+ strlen(CONF_FILE) + 2) * sizeof(char));
+ sprintf(conf_file, "%s/%s", DataDir, CONF_FILE);
+
+ file = AllocateFile(conf_file, "r");
+ if (file == NULL)
+ {
+ /* The open of the config file failed. */
+
+ *host_ok_p = false;
+
+ sprintf(PQerrormsg,
+ "find_hba_entry: Host-based authentication config file "
+ "does not exist or permissions are not setup correctly! "
+ "Unable to open file \"%s\".\n",
+ conf_file);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ }
+ else
+ {
+ process_open_config_file(file, ip_addr, database, host_ok_p, userauth_p,
+ usermap_name, find_password_entries);
+ FreeFile(file);
+ }
+ free(conf_file);
+ }
+ free(old_conf_file);
+ return;
}
static void
-interpret_ident_response(char ident_response[],
- bool *error_p, char ident_username[]) {
+interpret_ident_response(char ident_response[],
+ bool * error_p, char ident_username[])
+{
/*----------------------------------------------------------------------------
Parse the string "ident_response[]" as a response from a query to an Ident
- server. If it's a normal response indicating a username, return
+ server. If it's a normal response indicating a username, return
*error_p == false and the username as ident_username[]. If it's anything
else, return *error_p == true and ident_username[] undefined.
----------------------------------------------------------------------------*/
- char *cursor; /* Cursor into ident_response[] */
-
- cursor = &ident_response[0];
-
- /* Ident's response, in the telnet tradition, should end in crlf (\r\n). */
- if (strlen(ident_response) < 2) *error_p = true;
- else if (ident_response[strlen(ident_response)-2] != '\r') *error_p = true;
- else {
- while (*cursor != ':' && *cursor != '\r') cursor++; /* skip port field */
-
- if (*cursor != ':') *error_p = true;
- else {
- /* We're positioned to colon before response type field */
- char response_type[80];
- int i; /* Index into response_type[] */
- cursor++; /* Go over colon */
- while (isblank(*cursor)) cursor++; /* skip blanks */
- i = 0;
- while (*cursor != ':' && *cursor != '\r' && !isblank(*cursor)
- && i < sizeof(response_type)-1)
- response_type[i++] = *cursor++;
- response_type[i] = '\0';
- while (isblank(*cursor)) cursor++; /* skip blanks */
- if (strcmp(response_type, "USERID") != 0)
- *error_p = true;
- else {
- /* It's a USERID response. Good. "cursor" should be pointing to
- the colon that precedes the operating system type.
- */
- if (*cursor != ':') *error_p = true;
- else {
- cursor++; /* Go over colon */
- /* Skip over operating system field. */
- while (*cursor != ':' && *cursor != '\r') cursor++;
- if (*cursor != ':') *error_p = true;
- else {
- int i; /* Index into ident_username[] */
- cursor ++; /* Go over colon */
- while (isblank(*cursor)) cursor++; /* skip blanks */
- /* Rest of line is username. Copy it over. */
- i = 0;
- while (*cursor != '\r' && i < IDENT_USERNAME_MAX)
- ident_username[i++] = *cursor++;
- ident_username[i] = '\0';
- *error_p = false;
- }
- }
- }
- }
- }
+ char *cursor; /* Cursor into ident_response[] */
+
+ cursor = &ident_response[0];
+
+ /*
+ * Ident's response, in the telnet tradition, should end in crlf
+ * (\r\n).
+ */
+ if (strlen(ident_response) < 2)
+ *error_p = true;
+ else if (ident_response[strlen(ident_response) - 2] != '\r')
+ *error_p = true;
+ else
+ {
+ while (*cursor != ':' && *cursor != '\r')
+ cursor++; /* skip port field */
+
+ if (*cursor != ':')
+ *error_p = true;
+ else
+ {
+ /* We're positioned to colon before response type field */
+ char response_type[80];
+ int i; /* Index into response_type[] */
+
+ cursor++; /* Go over colon */
+ while (isblank(*cursor))
+ cursor++; /* skip blanks */
+ i = 0;
+ while (*cursor != ':' && *cursor != '\r' && !isblank(*cursor)
+ && i < sizeof(response_type) - 1)
+ response_type[i++] = *cursor++;
+ response_type[i] = '\0';
+ while (isblank(*cursor))
+ cursor++; /* skip blanks */
+ if (strcmp(response_type, "USERID") != 0)
+ *error_p = true;
+ else
+ {
+
+ /*
+ * It's a USERID response. Good. "cursor" should be
+ * pointing to the colon that precedes the operating
+ * system type.
+ */
+ if (*cursor != ':')
+ *error_p = true;
+ else
+ {
+ cursor++; /* Go over colon */
+ /* Skip over operating system field. */
+ while (*cursor != ':' && *cursor != '\r')
+ cursor++;
+ if (*cursor != ':')
+ *error_p = true;
+ else
+ {
+ int i; /* Index into
+ * ident_username[] */
+
+ cursor++; /* Go over colon */
+ while (isblank(*cursor))
+ cursor++; /* skip blanks */
+ /* Rest of line is username. Copy it over. */
+ i = 0;
+ while (*cursor != '\r' && i < IDENT_USERNAME_MAX)
+ ident_username[i++] = *cursor++;
+ ident_username[i] = '\0';
+ *error_p = false;
+ }
+ }
+ }
+ }
+ }
}
static void
ident(const struct in_addr remote_ip_addr, const struct in_addr local_ip_addr,
- const ushort remote_port, const ushort local_port,
- bool *ident_failed, char ident_username[]) {
+ const ushort remote_port, const ushort local_port,
+ bool * ident_failed, char ident_username[])
+{
/*--------------------------------------------------------------------------
Talk to the ident server on host "remote_ip_addr" and find out who
owns the tcp connection from his port "remote_port" to port
@@ -437,169 +564,204 @@ ident(const struct in_addr remote_ip_addr, const struct in_addr local_ip_addr,
*ident_failed == true (and ident_username[] undefined).
----------------------------------------------------------------------------*/
- int sock_fd;
- /* File descriptor for socket on which we talk to Ident */
-
- int rc; /* Return code from a locally called function */
-
- sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
- if (sock_fd == -1) {
- sprintf(PQerrormsg,
- "Failed to create socket on which to talk to Ident server. "
- "socket() returned errno = %s (%d)\n",
- strerror(errno), errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- } else {
- struct sockaddr_in ident_server;
- /* Socket address of Ident server on the system from which client
- is attempting to connect to us.
- */
- ident_server.sin_family = AF_INET;
- ident_server.sin_port = htons(IDENT_PORT);
- ident_server.sin_addr = remote_ip_addr;
- rc = connect(sock_fd,
- (struct sockaddr *) &ident_server, sizeof(ident_server));
- if (rc != 0) {
- sprintf(PQerrormsg,
- "Unable to connect to Ident server on the host which is "
- "trying to connect to Postgres "
- "(IP address %s, Port %d). "
- "errno = %s (%d)\n",
- inet_ntoa(remote_ip_addr), IDENT_PORT, strerror(errno), errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- *ident_failed = true;
- } else {
- char ident_query[80];
- /* The query we send to the Ident server */
- sprintf(ident_query, "%d,%d\n",
- ntohs(remote_port), ntohs(local_port));
- rc = send(sock_fd, ident_query, strlen(ident_query), 0);
- if (rc < 0) {
- sprintf(PQerrormsg,
- "Unable to send query to Ident server on the host which is "
- "trying to connect to Postgres (Host %s, Port %d),"
- "even though we successfully connected to it. "
- "errno = %s (%d)\n",
- inet_ntoa(remote_ip_addr), IDENT_PORT, strerror(errno), errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- *ident_failed = true;
- } else {
- char ident_response[80+IDENT_USERNAME_MAX];
- rc = recv(sock_fd, ident_response, sizeof(ident_response)-1, 0);
- if (rc < 0) {
- sprintf(PQerrormsg,
- "Unable to receive response from Ident server "
- "on the host which is "
- "trying to connect to Postgres (Host %s, Port %d),"
- "even though we successfully sent our query to it. "
- "errno = %s (%d)\n",
- inet_ntoa(remote_ip_addr), IDENT_PORT,
- strerror(errno), errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- *ident_failed = true;
- } else {
- bool error; /* response from Ident is garbage. */
- ident_response[rc] = '\0';
- interpret_ident_response(ident_response, &error, ident_username);
- *ident_failed = error;
- }
- }
- close(sock_fd);
- }
- }
+ int sock_fd;
+
+ /* File descriptor for socket on which we talk to Ident */
+
+ int rc; /* Return code from a locally called
+ * function */
+
+ sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+ if (sock_fd == -1)
+ {
+ sprintf(PQerrormsg,
+ "Failed to create socket on which to talk to Ident server. "
+ "socket() returned errno = %s (%d)\n",
+ strerror(errno), errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ }
+ else
+ {
+ struct sockaddr_in ident_server;
+
+ /*
+ * Socket address of Ident server on the system from which client
+ * is attempting to connect to us.
+ */
+ ident_server.sin_family = AF_INET;
+ ident_server.sin_port = htons(IDENT_PORT);
+ ident_server.sin_addr = remote_ip_addr;
+ rc = connect(sock_fd,
+ (struct sockaddr *) & ident_server, sizeof(ident_server));
+ if (rc != 0)
+ {
+ sprintf(PQerrormsg,
+ "Unable to connect to Ident server on the host which is "
+ "trying to connect to Postgres "
+ "(IP address %s, Port %d). "
+ "errno = %s (%d)\n",
+ inet_ntoa(remote_ip_addr), IDENT_PORT, strerror(errno), errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ *ident_failed = true;
+ }
+ else
+ {
+ char ident_query[80];
+
+ /* The query we send to the Ident server */
+ sprintf(ident_query, "%d,%d\n",
+ ntohs(remote_port), ntohs(local_port));
+ rc = send(sock_fd, ident_query, strlen(ident_query), 0);
+ if (rc < 0)
+ {
+ sprintf(PQerrormsg,
+ "Unable to send query to Ident server on the host which is "
+ "trying to connect to Postgres (Host %s, Port %d),"
+ "even though we successfully connected to it. "
+ "errno = %s (%d)\n",
+ inet_ntoa(remote_ip_addr), IDENT_PORT, strerror(errno), errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ *ident_failed = true;
+ }
+ else
+ {
+ char ident_response[80 + IDENT_USERNAME_MAX];
+
+ rc = recv(sock_fd, ident_response, sizeof(ident_response) - 1, 0);
+ if (rc < 0)
+ {
+ sprintf(PQerrormsg,
+ "Unable to receive response from Ident server "
+ "on the host which is "
+ "trying to connect to Postgres (Host %s, Port %d),"
+ "even though we successfully sent our query to it. "
+ "errno = %s (%d)\n",
+ inet_ntoa(remote_ip_addr), IDENT_PORT,
+ strerror(errno), errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ *ident_failed = true;
+ }
+ else
+ {
+ bool error; /* response from Ident is
+ * garbage. */
+
+ ident_response[rc] = '\0';
+ interpret_ident_response(ident_response, &error, ident_username);
+ *ident_failed = error;
+ }
+ }
+ close(sock_fd);
+ }
+ }
}
static void
-parse_map_record(FILE *file,
- char file_map[], char file_pguser[], char file_iuser[]) {
+parse_map_record(FILE * file,
+ char file_map[], char file_pguser[], char file_iuser[])
+{
/*---------------------------------------------------------------------------
Take the noncomment line which is next on file "file" and interpret
it as a line in a usermap file. Specifically, return the first
- 3 tokens as file_map, file_iuser, and file_pguser, respectively. If
+ 3 tokens as file_map, file_iuser, and file_pguser, respectively. If
there are fewer than 3 tokens, return null strings for the missing
ones.
---------------------------------------------------------------------------*/
- char buf[MAX_TOKEN];
- /* A token read from the file */
-
- /* Set defaults in case fields not in file */
- file_map[0] = '\0';
- file_pguser[0] = '\0';
- file_iuser[0] = '\0';
-
- next_token(file, buf, sizeof(buf));
- if (buf != '\0') {
- strcpy(file_map, buf);
- next_token(file, buf, sizeof(buf));
- if (buf != '\0') {
- strcpy(file_iuser, buf);
- next_token(file, buf, sizeof(buf));
- if (buf != '\0') {
- strcpy(file_pguser, buf);
- read_through_eol(file);
- }
- }
- }
+ char buf[MAX_TOKEN];
+
+ /* A token read from the file */
+
+ /* Set defaults in case fields not in file */
+ file_map[0] = '\0';
+ file_pguser[0] = '\0';
+ file_iuser[0] = '\0';
+
+ next_token(file, buf, sizeof(buf));
+ if (buf != '\0')
+ {
+ strcpy(file_map, buf);
+ next_token(file, buf, sizeof(buf));
+ if (buf != '\0')
+ {
+ strcpy(file_iuser, buf);
+ next_token(file, buf, sizeof(buf));
+ if (buf != '\0')
+ {
+ strcpy(file_pguser, buf);
+ read_through_eol(file);
+ }
+ }
+ }
}
static void
-verify_against_open_usermap(FILE *file,
- const char pguser[],
- const char ident_username[],
- const char usermap_name[],
- bool *checks_out_p) {
+verify_against_open_usermap(FILE * file,
+ const char pguser[],
+ const char ident_username[],
+ const char usermap_name[],
+ bool * checks_out_p)
+{
/*--------------------------------------------------------------------------
This function does the same thing as verify_against_usermap,
only with the config file already open on stream descriptor "file".
---------------------------------------------------------------------------*/
- bool match; /* We found a matching entry in the map file */
- bool eof; /* We've reached the end of the file we're reading */
-
- match = false; /* initial value */
- eof = false; /* initial value */
- while (!eof && !match) {
- /* Process a line from the map file */
-
- int c; /* a character read from the file */
-
- c = getc(file); ungetc(c, file);
- if (c == EOF) eof = true;
- else {
- if (c == '#') read_through_eol(file);
- else {
- /* The following are fields read from a record of the file */
- char file_map[MAX_TOKEN+1];
- char file_pguser[MAX_TOKEN+1];
- char file_iuser[MAX_TOKEN+1];
-
- parse_map_record(file, file_map, file_pguser, file_iuser);
- if (strcmp(file_map, usermap_name) == 0 &&
- strcmp(file_pguser, pguser) == 0 &&
- strcmp(file_iuser, ident_username) == 0)
- match = true;
- }
- }
- }
- *checks_out_p = match;
+ bool match; /* We found a matching entry in the map
+ * file */
+ bool eof; /* We've reached the end of the file we're
+ * reading */
+
+ match = false; /* initial value */
+ eof = false; /* initial value */
+ while (!eof && !match)
+ {
+ /* Process a line from the map file */
+
+ int c; /* a character read from the file */
+
+ c = getc(file);
+ ungetc(c, file);
+ if (c == EOF)
+ eof = true;
+ else
+ {
+ if (c == '#')
+ read_through_eol(file);
+ else
+ {
+ /* The following are fields read from a record of the file */
+ char file_map[MAX_TOKEN + 1];
+ char file_pguser[MAX_TOKEN + 1];
+ char file_iuser[MAX_TOKEN + 1];
+
+ parse_map_record(file, file_map, file_pguser, file_iuser);
+ if (strcmp(file_map, usermap_name) == 0 &&
+ strcmp(file_pguser, pguser) == 0 &&
+ strcmp(file_iuser, ident_username) == 0)
+ match = true;
+ }
+ }
+ }
+ *checks_out_p = match;
}
static void
verify_against_usermap(const char DataDir[],
- const char pguser[],
- const char ident_username[],
- const char usermap_name[],
- bool *checks_out_p) {
+ const char pguser[],
+ const char ident_username[],
+ const char usermap_name[],
+ bool * checks_out_p)
+{
/*--------------------------------------------------------------------------
See if the user with ident username "ident_username" is allowed to act
as Postgres user "pguser" according to usermap "usermap_name". Look
@@ -610,151 +772,194 @@ verify_against_usermap(const char DataDir[],
"ident_username" in order to be authorized.
Iff authorized, return *checks_out_p == true.
-
+
--------------------------------------------------------------------------*/
- if (usermap_name[0] == '\0') {
- *checks_out_p = false;
- sprintf(PQerrormsg,
- "verify_against_usermap: hba configuration file does not "
- "have the usermap field filled in in the entry that pertains "
- "to this connection. That field is essential for Ident-based "
- "authentication.\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- } else if (strcmp(usermap_name, "sameuser") == 0) {
- if (strcmp(ident_username, pguser) == 0) *checks_out_p = true;
- else *checks_out_p = false;
- } else {
- FILE *file; /* The map file we have to read */
-
- char *map_file; /* The name of the map file we have to read */
-
- /* put together the full pathname to the map file */
- map_file = (char *) malloc((strlen(DataDir) +
- strlen(MAP_FILE)+2)*sizeof(char));
- sprintf(map_file, "%s/%s", DataDir, MAP_FILE);
-
- file = AllocateFile(map_file, "r");
- if (file == NULL) {
- /* The open of the map file failed. */
-
- *checks_out_p = false;
-
- sprintf(PQerrormsg,
- "verify_against_usermap: usermap file for Ident-based "
- "authentication "
- "does not exist or permissions are not setup correctly! "
- "Unable to open file \"%s\".\n",
- map_file);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- } else {
- verify_against_open_usermap(file,
- pguser, ident_username, usermap_name,
- checks_out_p);
- FreeFile(file);
- }
- free(map_file);
-
-
- }
+ if (usermap_name[0] == '\0')
+ {
+ *checks_out_p = false;
+ sprintf(PQerrormsg,
+ "verify_against_usermap: hba configuration file does not "
+ "have the usermap field filled in in the entry that pertains "
+ "to this connection. That field is essential for Ident-based "
+ "authentication.\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ }
+ else if (strcmp(usermap_name, "sameuser") == 0)
+ {
+ if (strcmp(ident_username, pguser) == 0)
+ *checks_out_p = true;
+ else
+ *checks_out_p = false;
+ }
+ else
+ {
+ FILE *file; /* The map file we have to read */
+
+ char *map_file; /* The name of the map file we
+ * have to read */
+
+ /* put together the full pathname to the map file */
+ map_file = (char *) malloc((strlen(DataDir) +
+ strlen(MAP_FILE) + 2) * sizeof(char));
+ sprintf(map_file, "%s/%s", DataDir, MAP_FILE);
+
+ file = AllocateFile(map_file, "r");
+ if (file == NULL)
+ {
+ /* The open of the map file failed. */
+
+ *checks_out_p = false;
+
+ sprintf(PQerrormsg,
+ "verify_against_usermap: usermap file for Ident-based "
+ "authentication "
+ "does not exist or permissions are not setup correctly! "
+ "Unable to open file \"%s\".\n",
+ map_file);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ }
+ else
+ {
+ verify_against_open_usermap(file,
+ pguser, ident_username, usermap_name,
+ checks_out_p);
+ FreeFile(file);
+ }
+ free(map_file);
+
+
+ }
}
static void
-authident(const char DataDir[],
- const Port port, const char postgres_username[],
- const char usermap_name[],
- bool *authentic_p) {
+authident(const char DataDir[],
+ const Port port, const char postgres_username[],
+ const char usermap_name[],
+ bool * authentic_p)
+{
/*---------------------------------------------------------------------------
- Talk to the ident server on the remote host and find out who owns the
+ Talk to the ident server on the remote host and find out who owns the
connection described by "port". Then look in the usermap file under
- the usermap usermap_name[] and see if that user is equivalent to
+ the usermap usermap_name[] and see if that user is equivalent to
Postgres user user[].
Return *authentic_p true iff yes.
---------------------------------------------------------------------------*/
- bool ident_failed;
- /* We were unable to get ident to give us a username */
- char ident_username[IDENT_USERNAME_MAX+1];
- /* The username returned by ident */
-
- ident(port.raddr.sin_addr, port.laddr.sin_addr,
- port.raddr.sin_port, port.laddr.sin_port,
- &ident_failed, ident_username);
-
- if (ident_failed) *authentic_p = false;
- else {
- bool checks_out;
- verify_against_usermap(DataDir,
- postgres_username, ident_username, usermap_name,
- &checks_out);
- if (checks_out) *authentic_p = true;
- else *authentic_p = false;
- }
+ bool ident_failed;
+
+ /* We were unable to get ident to give us a username */
+ char ident_username[IDENT_USERNAME_MAX + 1];
+
+ /* The username returned by ident */
+
+ ident(port.raddr.sin_addr, port.laddr.sin_addr,
+ port.raddr.sin_port, port.laddr.sin_port,
+ &ident_failed, ident_username);
+
+ if (ident_failed)
+ *authentic_p = false;
+ else
+ {
+ bool checks_out;
+
+ verify_against_usermap(DataDir,
+ postgres_username, ident_username, usermap_name,
+ &checks_out);
+ if (checks_out)
+ *authentic_p = true;
+ else
+ *authentic_p = false;
+ }
}
extern int
-hba_recvauth(const Port *port, const char database[], const char user[],
- const char DataDir[]) {
+hba_recvauth(const Port * port, const char database[], const char user[],
+ const char DataDir[])
+{
/*---------------------------------------------------------------------------
Determine if the TCP connection described by "port" is with someone
allowed to act as user "user" and access database "database". Return
STATUS_OK if yes; STATUS_ERROR if not.
-----------------------------------------------------------------------------*/
- bool host_ok;
- /* There's an entry for this database and remote host in the pg_hba file */
- char usermap_name[USERMAP_NAME_SIZE+1];
- /* The name of the map pg_hba specifies for this connection (or special
- value "SAMEUSER")
- */
- enum Userauth userauth;
- /* The type of user authentication pg_hba specifies for this connection */
- int retvalue;
- /* Our eventual return value */
-
-
- find_hba_entry(DataDir, port->raddr.sin_addr, database,
- &host_ok, &userauth, usermap_name,
- false /* don't find password entries of type 'password' */);
-
- if (!host_ok) retvalue = STATUS_ERROR;
- else {
- switch (userauth) {
- case Trust:
- retvalue = STATUS_OK;
- break;
- case Ident: {
- /* Here's where we need to call up ident and authenticate the user */
-
- bool authentic; /* He is who he says he is. */
-
- authident(DataDir, *port, user, usermap_name, &authentic);
-
- if (authentic) retvalue = STATUS_OK;
- else retvalue = STATUS_ERROR;
- }
- break;
- default:
- retvalue = STATUS_ERROR;
- Assert(false);
- }
- }
- return(retvalue);
+----------------------------------------------------------------------------*/
+ bool host_ok;
+
+ /*
+ * There's an entry for this database and remote host in the pg_hba
+ * file
+ */
+ char usermap_name[USERMAP_NAME_SIZE + 1];
+
+ /*
+ * The name of the map pg_hba specifies for this connection (or
+ * special value "SAMEUSER")
+ */
+ enum Userauth userauth;
+
+ /*
+ * The type of user authentication pg_hba specifies for this
+ * connection
+ */
+ int retvalue;
+
+ /* Our eventual return value */
+
+
+ find_hba_entry(DataDir, port->raddr.sin_addr, database,
+ &host_ok, &userauth, usermap_name,
+ false /* don't find password entries of type
+ 'password' */ );
+
+ if (!host_ok)
+ retvalue = STATUS_ERROR;
+ else
+ {
+ switch (userauth)
+ {
+ case Trust:
+ retvalue = STATUS_OK;
+ break;
+ case Ident:
+ {
+
+ /*
+ * Here's where we need to call up ident and authenticate
+ * the user
+ */
+
+ bool authentic; /* He is who he says he
+ * is. */
+
+ authident(DataDir, *port, user, usermap_name, &authentic);
+
+ if (authentic)
+ retvalue = STATUS_OK;
+ else
+ retvalue = STATUS_ERROR;
+ }
+ break;
+ default:
+ retvalue = STATUS_ERROR;
+ Assert(false);
+ }
+ }
+ return (retvalue);
}
/*----------------------------------------------------------------
* This version of hba was written by Bryan Henderson
- * in September 1996 for Release 6.0. It changed the format of the
+ * in September 1996 for Release 6.0. It changed the format of the
* hba file and added ident function.
*
* Here are some notes about the original host based authentication
- * the preceded this one.
+ * the preceded this one.
*
* based on the securelib package originally written by William
* LeFebvre, EECS Department, Northwestern University
@@ -765,4 +970,3 @@ hba_recvauth(const Port *port, const char database[], const char user[],
* (pnfisher@unity.ncsu.edu)
*
-----------------------------------------------------------------*/
-
diff --git a/src/backend/libpq/password.c b/src/backend/libpq/password.c
index 346d59e8bf6..1efc2e668a3 100644
--- a/src/backend/libpq/password.c
+++ b/src/backend/libpq/password.c
@@ -6,106 +6,116 @@
#include <string.h>
#include <unistd.h>
#ifdef HAVE_CRYPT_H
-# include <crypt.h>
+#include <crypt.h>
#endif
int
-verify_password(char *user, char *password, Port *port,
- char *database, char *DataDir)
+verify_password(char *user, char *password, Port * port,
+ char *database, char *DataDir)
{
- bool host_ok;
- enum Userauth userauth;
- char pw_file_name[PWFILE_NAME_SIZE+1];
-
- char *pw_file_fullname;
- FILE *pw_file;
-
- char pw_file_line[255];
- char *p, *test_user, *test_pw;
- char salt[3];
-
- find_hba_entry(DataDir, port->raddr.sin_addr, database,
- &host_ok, &userauth, pw_file_name, true);
+ bool host_ok;
+ enum Userauth userauth;
+ char pw_file_name[PWFILE_NAME_SIZE + 1];
+
+ char *pw_file_fullname;
+ FILE *pw_file;
+
+ char pw_file_line[255];
+ char *p,
+ *test_user,
+ *test_pw;
+ char salt[3];
+
+ find_hba_entry(DataDir, port->raddr.sin_addr, database,
+ &host_ok, &userauth, pw_file_name, true);
+
+ if (!host_ok)
+ {
+ sprintf(PQerrormsg,
+ "verify_password: couldn't find entry for connecting host\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return STATUS_ERROR;
+ }
- if(!host_ok) {
- sprintf(PQerrormsg,
- "verify_password: couldn't find entry for connecting host\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return STATUS_ERROR;
- }
+ if (userauth != Password)
+ {
+ sprintf(PQerrormsg,
+ "verify_password: couldn't find entry of type 'password' "
+ "for this host\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return STATUS_ERROR;
+ }
- if(userauth != Password) {
- sprintf(PQerrormsg,
- "verify_password: couldn't find entry of type 'password' "
- "for this host\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return STATUS_ERROR;
- }
+ if (!pw_file_name || pw_file_name[0] == '\0')
+ {
+ sprintf(PQerrormsg,
+ "verify_password: no password file specified\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return STATUS_ERROR;
+ }
- if(!pw_file_name || pw_file_name[0] == '\0') {
- sprintf(PQerrormsg,
- "verify_password: no password file specified\n");
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return STATUS_ERROR;
- }
+ pw_file_fullname = (char *) malloc(strlen(DataDir) + strlen(pw_file_name) + 2);
+ strcpy(pw_file_fullname, DataDir);
+ strcat(pw_file_fullname, "/");
+ strcat(pw_file_fullname, pw_file_name);
+
+ pw_file = AllocateFile(pw_file_fullname, "r");
+ if (!pw_file)
+ {
+ sprintf(PQerrormsg,
+ "verify_password: couldn't open password file '%s'\n",
+ pw_file_fullname);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return STATUS_ERROR;
+ }
- pw_file_fullname = (char *)malloc(strlen(DataDir) + strlen(pw_file_name) + 2);
- strcpy(pw_file_fullname, DataDir);
- strcat(pw_file_fullname, "/");
- strcat(pw_file_fullname, pw_file_name);
+ while (!feof(pw_file))
+ {
+ fgets(pw_file_line, 255, pw_file);
+ p = pw_file_line;
+
+ test_user = strtok(p, ":");
+ test_pw = strtok(NULL, ":");
+ if (!test_user || !test_pw ||
+ test_user[0] == '\0' || test_pw[0] == '\0')
+ {
+ continue;
+ }
+
+ /* kill the newline */
+ if (test_pw[strlen(test_pw) - 1] == '\n')
+ test_pw[strlen(test_pw) - 1] = '\0';
+
+ strNcpy(salt, test_pw, 2);
+
+ if (strcmp(user, test_user) == 0)
+ {
+ /* we're outta here one way or the other. */
+ FreeFile(pw_file);
+
+ if (strcmp(crypt(password, salt), test_pw) == 0)
+ {
+ /* it matched. */
+ return STATUS_OK;
+ }
+
+ sprintf(PQerrormsg,
+ "verify_password: password mismatch for '%s'.\n",
+ user);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return STATUS_ERROR;
+ }
+ }
- pw_file = AllocateFile(pw_file_fullname, "r");
- if(!pw_file) {
sprintf(PQerrormsg,
- "verify_password: couldn't open password file '%s'\n",
- pw_file_fullname);
+ "verify_password: user '%s' not found in password file.\n",
+ user);
fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
+ pqdebug("%s", PQerrormsg);
return STATUS_ERROR;
- }
-
- while(!feof(pw_file)) {
- fgets(pw_file_line, 255, pw_file);
- p = pw_file_line;
-
- test_user = strtok(p, ":");
- test_pw = strtok(NULL, ":");
- if(!test_user || !test_pw ||
- test_user[0] == '\0' || test_pw[0] == '\0') {
- continue;
- }
-
- /* kill the newline */
- if (test_pw[strlen(test_pw)-1] == '\n')
- test_pw[strlen(test_pw)-1] = '\0';
-
- strNcpy(salt, test_pw, 2);
-
- if(strcmp(user, test_user) == 0) {
- /* we're outta here one way or the other. */
- FreeFile(pw_file);
-
- if(strcmp(crypt(password, salt), test_pw) == 0) {
- /* it matched. */
- return STATUS_OK;
- }
-
- sprintf(PQerrormsg,
- "verify_password: password mismatch for '%s'.\n",
- user);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return STATUS_ERROR;
- }
- }
-
- sprintf(PQerrormsg,
- "verify_password: user '%s' not found in password file.\n",
- user);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return STATUS_ERROR;
}
diff --git a/src/backend/libpq/portal.c b/src/backend/libpq/portal.c
index 301773be9f5..c3c8fe55e38 100644
--- a/src/backend/libpq/portal.c
+++ b/src/backend/libpq/portal.c
@@ -1,642 +1,655 @@
/*-------------------------------------------------------------------------
*
* portal.c--
- * generalized portal support routines
+ * generalized portal support routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portal.c,v 1.6 1997/08/12 22:52:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portal.c,v 1.7 1997/09/07 04:42:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * INTERFACE ROUTINES
- * PQnportals - Return the number of open portals.
- * PQpnames - Return all the portal names
- * PQparray - Return the portal buffer given a portal name
- * PQrulep - Return 1 if an asynchronous portal
- * PQntuples - Return the number of tuples in a portal buffer
- * PQninstances - same as PQntuples using object terminology
- * PQngroups - Return the number of tuple groups in a portal buffer
- * PQntuplesGroup - Return the number of tuples in a tuple group
- * PQninstancesGroup - same as PQntuplesGroup using object terminology
- * PQnfieldsGroup - Return the number of fields in a tuple group
- * PQfnumberGroup - Return field number given (group index, field name)
- * PQftypeGroup - Return field type given (group index, field index)
- * PQfsizeGroup - Return field size given (group index, field index)
- * PQfnameGroup - Return field name given (group index, field index)
- * PQgroup - Return the tuple group that a particular tuple is in
- * PQgetgroup - Return the index of the group that a tuple is in
- * PQnfields - Return the number of fields in a tuple
- * PQfnumber - Return the field index of a field name in a tuple
- * PQfname - Return the name of a field
- * PQftype - Return the type of a field
- * PQfsize - Return the size of a field
- * PQftype - Return the type of a field
- * PQsametype - Return 1 if the two tuples have the same type
- * PQgetvalue - Return an attribute (field) value
- * PQgetlength - Return an attribute (field) length
- * PQclear - free storage claimed by named portal
- * PQnotifies - Return a list of relations on which notification
- * has occurred.
- * PQremoveNotify - Remove this notification from the list.
+ * INTERFACE ROUTINES
+ * PQnportals - Return the number of open portals.
+ * PQpnames - Return all the portal names
+ * PQparray - Return the portal buffer given a portal name
+ * PQrulep - Return 1 if an asynchronous portal
+ * PQntuples - Return the number of tuples in a portal buffer
+ * PQninstances - same as PQntuples using object terminology
+ * PQngroups - Return the number of tuple groups in a portal buffer
+ * PQntuplesGroup - Return the number of tuples in a tuple group
+ * PQninstancesGroup - same as PQntuplesGroup using object terminology
+ * PQnfieldsGroup - Return the number of fields in a tuple group
+ * PQfnumberGroup - Return field number given (group index, field name)
+ * PQftypeGroup - Return field type given (group index, field index)
+ * PQfsizeGroup - Return field size given (group index, field index)
+ * PQfnameGroup - Return field name given (group index, field index)
+ * PQgroup - Return the tuple group that a particular tuple is in
+ * PQgetgroup - Return the index of the group that a tuple is in
+ * PQnfields - Return the number of fields in a tuple
+ * PQfnumber - Return the field index of a field name in a tuple
+ * PQfname - Return the name of a field
+ * PQftype - Return the type of a field
+ * PQfsize - Return the size of a field
+ * PQftype - Return the type of a field
+ * PQsametype - Return 1 if the two tuples have the same type
+ * PQgetvalue - Return an attribute (field) value
+ * PQgetlength - Return an attribute (field) length
+ * PQclear - free storage claimed by named portal
+ * PQnotifies - Return a list of relations on which notification
+ * has occurred.
+ * PQremoveNotify - Remove this notification from the list.
*
- * NOTES
- * These functions may be used by both frontend routines which
- * communicate with a backend or by user-defined functions which
- * are compiled or dynamically loaded into a backend.
+ * NOTES
+ * These functions may be used by both frontend routines which
+ * communicate with a backend or by user-defined functions which
+ * are compiled or dynamically loaded into a backend.
*
- * the portals[] array should be organized as a hash table for
- * quick portal-by-name lookup.
+ * the portals[] array should be organized as a hash table for
+ * quick portal-by-name lookup.
*
- * Do not confuse "PortalEntry" (or "PortalBuffer") with "Portal"
- * see utils/mmgr/portalmem.c for why. -cim 2/22/91
+ * Do not confuse "PortalEntry" (or "PortalBuffer") with "Portal"
+ * see utils/mmgr/portalmem.c for why. -cim 2/22/91
*
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include <postgres.h>
#include <lib/dllist.h>
-#include <libpq/libpq.h> /* where the declarations go */
+#include <libpq/libpq.h> /* where the declarations go */
#include <utils/exc.h>
/* ----------------------------------------------------------------
- * Helper routines for PQ portal interface routines below
+ * Helper routines for PQ portal interface routines below
* ----------------------------------------------------------------
*/
static int
in_range(char *msg, int value, int min, int max)
{
- if (value < min || value >= max) {
- sprintf(PQerrormsg, "FATAL: %s, %d is not in range [%d,%d)\n",
- msg, value, min, max);
- pqdebug("%s", PQerrormsg);
- fputs(PQerrormsg, stderr);
- return(0);
- }
- return(1);
+ if (value < min || value >= max)
+ {
+ sprintf(PQerrormsg, "FATAL: %s, %d is not in range [%d,%d)\n",
+ msg, value, min, max);
+ pqdebug("%s", PQerrormsg);
+ fputs(PQerrormsg, stderr);
+ return (0);
+ }
+ return (1);
}
static int
valid_pointer(char *msg, void *ptr)
{
- if (!ptr) {
- sprintf(PQerrormsg, "FATAL: %s\n", msg);
- pqdebug("%s", PQerrormsg);
- fputs(PQerrormsg, stderr);
- return(0);
- }
- return(1);
+ if (!ptr)
+ {
+ sprintf(PQerrormsg, "FATAL: %s\n", msg);
+ pqdebug("%s", PQerrormsg);
+ fputs(PQerrormsg, stderr);
+ return (0);
+ }
+ return (1);
}
/* ----------------------------------------------------------------
- * PQ portal interface routines
+ * PQ portal interface routines
* ----------------------------------------------------------------
*/
/* --------------------------------
- * PQnportals - Return the number of open portals.
- * If rule_p, only return asynchronous portals.
+ * PQnportals - Return the number of open portals.
+ * If rule_p, only return asynchronous portals.
* --------------------------------
*/
int
PQnportals(int rule_p)
{
- int i, n = 0;
-
- for (i = 0; i < portals_array_size; ++i) {
- if (portals[i] && portals[i]->portal) {
- if (!rule_p || portals[i]->portal->rule_p) {
- ++n;
- }
+ int i,
+ n = 0;
+
+ for (i = 0; i < portals_array_size; ++i)
+ {
+ if (portals[i] && portals[i]->portal)
+ {
+ if (!rule_p || portals[i]->portal->rule_p)
+ {
+ ++n;
+ }
+ }
}
- }
- return(n);
+ return (n);
}
/* --------------------------------
- * PQpnames - Return all the portal names
- * If rule_p, only return asynchronous portals.
+ * PQpnames - Return all the portal names
+ * If rule_p, only return asynchronous portals.
*
- * the caller must have allocated sufficient memory for char** pnames
- * (an array of PQnportals strings of length PortalNameLength).
+ * the caller must have allocated sufficient memory for char** pnames
+ * (an array of PQnportals strings of length PortalNameLength).
*
- * notice that this assumes that the user is calling PQnportals and
- * PQpnames with the same rule_p argument, and with no intervening
- * portal closures. if not, you can get in heap big trouble..
+ * notice that this assumes that the user is calling PQnportals and
+ * PQpnames with the same rule_p argument, and with no intervening
+ * portal closures. if not, you can get in heap big trouble..
* --------------------------------
*/
void
PQpnames(char **pnames, int rule_p)
{
- int i, cur_pname = 0;
-
- if (!valid_pointer("PQpnames: invalid name buffer", pnames))
- return;
-
- for (i = 0; i < portals_array_size; ++i) {
- if (portals[i] && portals[i]->portal) {
- if (!rule_p || portals[i]->portal->rule_p) {
- strncpy(pnames[cur_pname], portals[i]->name, PortalNameLength);
- ++cur_pname;
- }
+ int i,
+ cur_pname = 0;
+
+ if (!valid_pointer("PQpnames: invalid name buffer", pnames))
+ return;
+
+ for (i = 0; i < portals_array_size; ++i)
+ {
+ if (portals[i] && portals[i]->portal)
+ {
+ if (!rule_p || portals[i]->portal->rule_p)
+ {
+ strncpy(pnames[cur_pname], portals[i]->name, PortalNameLength);
+ ++cur_pname;
+ }
+ }
}
- }
}
/* --------------------------------
- * PQparray - Return the portal buffer given a portal name
+ * PQparray - Return the portal buffer given a portal name
* --------------------------------
*/
-PortalBuffer *
+PortalBuffer *
PQparray(char *pname)
{
- int i;
-
- if (!valid_pointer("PQparray: invalid name buffer", pname))
- return NULL;
-
- if ((i = pbuf_getIndex(pname)) < 0)
- return((PortalBuffer *) NULL);
- return(portals[i]->portal);
+ int i;
+
+ if (!valid_pointer("PQparray: invalid name buffer", pname))
+ return NULL;
+
+ if ((i = pbuf_getIndex(pname)) < 0)
+ return ((PortalBuffer *) NULL);
+ return (portals[i]->portal);
}
/* --------------------------------
- * PQrulep - Return 1 if an asynchronous portal
+ * PQrulep - Return 1 if an asynchronous portal
* --------------------------------
*/
int
-PQrulep(PortalBuffer *portal)
+PQrulep(PortalBuffer * portal)
{
- if (!valid_pointer("PQrulep: invalid portal pointer", portal))
- return(-1);
-
- return(portal->rule_p);
+ if (!valid_pointer("PQrulep: invalid portal pointer", portal))
+ return (-1);
+
+ return (portal->rule_p);
}
/* --------------------------------
- * PQntuples - Return the number of tuples in a portal buffer
+ * PQntuples - Return the number of tuples in a portal buffer
* --------------------------------
*/
int
-PQntuples(PortalBuffer *portal)
+PQntuples(PortalBuffer * portal)
{
- if (!valid_pointer("PQntuples: invalid portal pointer", portal))
- return(-1);
-
- return(portal->no_tuples);
+ if (!valid_pointer("PQntuples: invalid portal pointer", portal))
+ return (-1);
+
+ return (portal->no_tuples);
}
int
-PQninstances(PortalBuffer *portal)
+PQninstances(PortalBuffer * portal)
{
- return(PQntuples(portal));
+ return (PQntuples(portal));
}
/* --------------------------------
- * PQngroups - Return the number of tuple groups in a portal buffer
+ * PQngroups - Return the number of tuple groups in a portal buffer
* --------------------------------
*/
int
-PQngroups(PortalBuffer *portal)
+PQngroups(PortalBuffer * portal)
{
- if (!valid_pointer("PQngroups: invalid portal pointer", portal))
- return(-1);
-
- return(portal->no_groups);
+ if (!valid_pointer("PQngroups: invalid portal pointer", portal))
+ return (-1);
+
+ return (portal->no_groups);
}
/* --------------------------------
- * PQntuplesGroup - Return the number of tuples in a tuple group
+ * PQntuplesGroup - Return the number of tuples in a tuple group
* --------------------------------
*/
int
-PQntuplesGroup(PortalBuffer *portal, int group_index)
+PQntuplesGroup(PortalBuffer * portal, int group_index)
{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQntuplesGroup: invalid portal pointer", portal) ||
- !in_range("PQntuplesGroup: group index",
- group_index, 0, portal->no_groups))
- return(-1);
+ GroupBuffer *gbp;
- gbp = pbuf_findGroup(portal, group_index);
- if (gbp)
- return(gbp->no_tuples);
- return(-1);
+ if (!valid_pointer("PQntuplesGroup: invalid portal pointer", portal) ||
+ !in_range("PQntuplesGroup: group index",
+ group_index, 0, portal->no_groups))
+ return (-1);
+
+ gbp = pbuf_findGroup(portal, group_index);
+ if (gbp)
+ return (gbp->no_tuples);
+ return (-1);
}
int
-PQninstancesGroup(PortalBuffer *portal, int group_index)
+PQninstancesGroup(PortalBuffer * portal, int group_index)
{
- return(PQntuplesGroup(portal, group_index));
+ return (PQntuplesGroup(portal, group_index));
}
/* --------------------------------
- * PQnfieldsGroup - Return the number of fields in a tuple group
+ * PQnfieldsGroup - Return the number of fields in a tuple group
* --------------------------------
*/
int
-PQnfieldsGroup(PortalBuffer *portal, int group_index)
+PQnfieldsGroup(PortalBuffer * portal, int group_index)
{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQnfieldsGroup: invalid portal pointer", portal) ||
- !in_range("PQnfieldsGroup: group index",
- group_index, 0, portal->no_groups))
- return(-1);
- gbp = pbuf_findGroup(portal, group_index);
- if (gbp)
- return(gbp->no_fields);
- return(-1);
+ GroupBuffer *gbp;
+
+ if (!valid_pointer("PQnfieldsGroup: invalid portal pointer", portal) ||
+ !in_range("PQnfieldsGroup: group index",
+ group_index, 0, portal->no_groups))
+ return (-1);
+ gbp = pbuf_findGroup(portal, group_index);
+ if (gbp)
+ return (gbp->no_fields);
+ return (-1);
}
/* --------------------------------
- * PQfnumberGroup - Return the field number (index) given
- * the group index and the field name
+ * PQfnumberGroup - Return the field number (index) given
+ * the group index and the field name
* --------------------------------
*/
int
-PQfnumberGroup(PortalBuffer *portal, int group_index, char *field_name)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfnumberGroup: invalid portal pointer", portal) ||
- !valid_pointer("PQfnumberGroup: invalid field name pointer",
- field_name) ||
- !in_range("PQfnumberGroup: group index",
- group_index, 0, portal->no_groups))
- return(-1);
- gbp = pbuf_findGroup(portal, group_index);
- if (gbp)
- return(pbuf_findFnumber(gbp, field_name));
- return(-1);
+PQfnumberGroup(PortalBuffer * portal, int group_index, char *field_name)
+{
+ GroupBuffer *gbp;
+
+ if (!valid_pointer("PQfnumberGroup: invalid portal pointer", portal) ||
+ !valid_pointer("PQfnumberGroup: invalid field name pointer",
+ field_name) ||
+ !in_range("PQfnumberGroup: group index",
+ group_index, 0, portal->no_groups))
+ return (-1);
+ gbp = pbuf_findGroup(portal, group_index);
+ if (gbp)
+ return (pbuf_findFnumber(gbp, field_name));
+ return (-1);
}
/* --------------------------------
- * PQfnameGroup - Return the field (attribute) name given
- * the group index and field index.
+ * PQfnameGroup - Return the field (attribute) name given
+ * the group index and field index.
* --------------------------------
*/
-char *
-PQfnameGroup(PortalBuffer *portal, int group_index, int field_number)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfnameGroup: invalid portal pointer", portal) ||
- !in_range("PQfnameGroup: group index",
- group_index, 0, portal->no_groups))
- return((char *) NULL);
-
- if ((gbp = pbuf_findGroup(portal, group_index)) &&
- in_range("PQfnameGroup: field number",
- field_number, 0, gbp->no_fields))
- return(pbuf_findFname(gbp, field_number));
- return((char *) NULL);
+char *
+PQfnameGroup(PortalBuffer * portal, int group_index, int field_number)
+{
+ GroupBuffer *gbp;
+
+ if (!valid_pointer("PQfnameGroup: invalid portal pointer", portal) ||
+ !in_range("PQfnameGroup: group index",
+ group_index, 0, portal->no_groups))
+ return ((char *) NULL);
+
+ if ((gbp = pbuf_findGroup(portal, group_index)) &&
+ in_range("PQfnameGroup: field number",
+ field_number, 0, gbp->no_fields))
+ return (pbuf_findFname(gbp, field_number));
+ return ((char *) NULL);
}
/* --------------------------------
- * PQftypeGroup - Return the type of a field given
- * the group index and field index
+ * PQftypeGroup - Return the type of a field given
+ * the group index and field index
* --------------------------------
*/
int
-PQftypeGroup(PortalBuffer *portal, int group_index, int field_number)
+PQftypeGroup(PortalBuffer * portal, int group_index, int field_number)
{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQftypeGroup: invalid portal pointer", portal) ||
- !in_range("PQftypeGroup: group index",
- group_index, 0, portal->no_groups))
- return(-1);
-
- if ((gbp = pbuf_findGroup(portal, group_index)) &&
- in_range("PQftypeGroup: field number", field_number, 0, gbp->no_fields))
- return(gbp->types[field_number].adtid);
- return(-1);
+ GroupBuffer *gbp;
+
+ if (!valid_pointer("PQftypeGroup: invalid portal pointer", portal) ||
+ !in_range("PQftypeGroup: group index",
+ group_index, 0, portal->no_groups))
+ return (-1);
+
+ if ((gbp = pbuf_findGroup(portal, group_index)) &&
+ in_range("PQftypeGroup: field number", field_number, 0, gbp->no_fields))
+ return (gbp->types[field_number].adtid);
+ return (-1);
}
/* --------------------------------
- * PQfsizeGroup - Return the size of a field given
- * the group index and field index
+ * PQfsizeGroup - Return the size of a field given
+ * the group index and field index
* --------------------------------
*/
int
-PQfsizeGroup(PortalBuffer *portal, int group_index, int field_number)
+PQfsizeGroup(PortalBuffer * portal, int group_index, int field_number)
{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfsizeGroup: invalid portal pointer", portal) ||
- !in_range("PQfsizeGroup: tuple index",
- group_index, 0, portal->no_groups))
- return(-1);
-
- if ((gbp = pbuf_findGroup(portal, group_index)) &&
- in_range("PQfsizeGroup: field number", field_number, 0, gbp->no_fields))
- return(gbp->types[field_number].adtsize);
- return(-1);
+ GroupBuffer *gbp;
+
+ if (!valid_pointer("PQfsizeGroup: invalid portal pointer", portal) ||
+ !in_range("PQfsizeGroup: tuple index",
+ group_index, 0, portal->no_groups))
+ return (-1);
+
+ if ((gbp = pbuf_findGroup(portal, group_index)) &&
+ in_range("PQfsizeGroup: field number", field_number, 0, gbp->no_fields))
+ return (gbp->types[field_number].adtsize);
+ return (-1);
}
/* --------------------------------
- * PQgroup - Return the tuple group that a particular tuple is in
+ * PQgroup - Return the tuple group that a particular tuple is in
* --------------------------------
*/
-GroupBuffer *
-PQgroup(PortalBuffer *portal, int tuple_index)
-{
- GroupBuffer *gbp;
- int tuple_count = 0;
-
- if (!valid_pointer("PQgroup: invalid portal pointer", portal) ||
- !in_range("PQgroup: tuple index",
- tuple_index, 0, portal->no_tuples))
- return((GroupBuffer *) NULL);
-
- for (gbp = portal->groups;
- gbp && tuple_index >= (tuple_count += gbp->no_tuples);
- gbp = gbp->next)
- ;
- if (!in_range("PQgroup: tuple not found: tuple index",
- tuple_index, 0, tuple_count))
- return((GroupBuffer *) NULL);
- return(gbp);
+GroupBuffer *
+PQgroup(PortalBuffer * portal, int tuple_index)
+{
+ GroupBuffer *gbp;
+ int tuple_count = 0;
+
+ if (!valid_pointer("PQgroup: invalid portal pointer", portal) ||
+ !in_range("PQgroup: tuple index",
+ tuple_index, 0, portal->no_tuples))
+ return ((GroupBuffer *) NULL);
+
+ for (gbp = portal->groups;
+ gbp && tuple_index >= (tuple_count += gbp->no_tuples);
+ gbp = gbp->next)
+ ;
+ if (!in_range("PQgroup: tuple not found: tuple index",
+ tuple_index, 0, tuple_count))
+ return ((GroupBuffer *) NULL);
+ return (gbp);
}
/* --------------------------------
- * PQgetgroup - Return the index of the group that a
- * particular tuple is in
+ * PQgetgroup - Return the index of the group that a
+ * particular tuple is in
* --------------------------------
*/
int
-PQgetgroup(PortalBuffer *portal, int tuple_index)
-{
- GroupBuffer *gbp;
- int tuple_count = 0, group_count = 0;
-
- if (!valid_pointer("PQgetgroup: invalid portal pointer", portal) ||
- !in_range("PQgetgroup: tuple index",
- tuple_index, 0, portal->no_tuples))
- return(-1);
-
- for (gbp = portal->groups;
- gbp && tuple_index >= (tuple_count += gbp->no_tuples);
- gbp = gbp->next)
- ++group_count;
- if (!gbp || !in_range("PQgetgroup: tuple not found: tuple index",
- tuple_index, 0, tuple_count))
- return(-1);
- return(group_count);
+PQgetgroup(PortalBuffer * portal, int tuple_index)
+{
+ GroupBuffer *gbp;
+ int tuple_count = 0,
+ group_count = 0;
+
+ if (!valid_pointer("PQgetgroup: invalid portal pointer", portal) ||
+ !in_range("PQgetgroup: tuple index",
+ tuple_index, 0, portal->no_tuples))
+ return (-1);
+
+ for (gbp = portal->groups;
+ gbp && tuple_index >= (tuple_count += gbp->no_tuples);
+ gbp = gbp->next)
+ ++group_count;
+ if (!gbp || !in_range("PQgetgroup: tuple not found: tuple index",
+ tuple_index, 0, tuple_count))
+ return (-1);
+ return (group_count);
}
/* --------------------------------
- * PQnfields - Return the number of fields in a tuple
+ * PQnfields - Return the number of fields in a tuple
* --------------------------------
*/
int
-PQnfields(PortalBuffer *portal, int tuple_index)
+PQnfields(PortalBuffer * portal, int tuple_index)
{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQnfields: invalid portal pointer", portal) ||
- !in_range("PQnfields: tuple index",
- tuple_index, 0, portal->no_tuples))
- return(-1);
- gbp = PQgroup(portal, tuple_index);
- if (gbp)
- return(gbp->no_fields);
- return(-1);
+ GroupBuffer *gbp;
+
+ if (!valid_pointer("PQnfields: invalid portal pointer", portal) ||
+ !in_range("PQnfields: tuple index",
+ tuple_index, 0, portal->no_tuples))
+ return (-1);
+ gbp = PQgroup(portal, tuple_index);
+ if (gbp)
+ return (gbp->no_fields);
+ return (-1);
}
/* --------------------------------
- * PQfnumber - Return the field index of a given
- * field name within a tuple.
+ * PQfnumber - Return the field index of a given
+ * field name within a tuple.
* --------------------------------
*/
int
-PQfnumber(PortalBuffer *portal, int tuple_index, char *field_name)
+PQfnumber(PortalBuffer * portal, int tuple_index, char *field_name)
{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfnumber: invalid portal pointer", portal) ||
+ GroupBuffer *gbp;
+
+ if (!valid_pointer("PQfnumber: invalid portal pointer", portal) ||
!valid_pointer("PQfnumber: invalid field name pointer", field_name) ||
- !in_range("PQfnumber: tuple index",
- tuple_index, 0, portal->no_tuples))
- return(-1);
- gbp = PQgroup(portal, tuple_index);
- if (gbp)
- return(pbuf_findFnumber(gbp, field_name));
- return(-1);
+ !in_range("PQfnumber: tuple index",
+ tuple_index, 0, portal->no_tuples))
+ return (-1);
+ gbp = PQgroup(portal, tuple_index);
+ if (gbp)
+ return (pbuf_findFnumber(gbp, field_name));
+ return (-1);
}
/* --------------------------------
- * PQfname - Return the name of a field
+ * PQfname - Return the name of a field
* --------------------------------
*/
-char *
-PQfname(PortalBuffer *portal, int tuple_index, int field_number)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfname: invalid portal pointer", portal) ||
- !in_range("PQfname: tuple index",
- tuple_index, 0, portal->no_tuples))
- return((char *) NULL);
-
- if ((gbp = PQgroup(portal, tuple_index)) &&
- in_range("PQfname: field number",
- field_number, 0, gbp->no_fields))
- return(pbuf_findFname(gbp, field_number));
- return((char *) NULL);
+char *
+PQfname(PortalBuffer * portal, int tuple_index, int field_number)
+{
+ GroupBuffer *gbp;
+
+ if (!valid_pointer("PQfname: invalid portal pointer", portal) ||
+ !in_range("PQfname: tuple index",
+ tuple_index, 0, portal->no_tuples))
+ return ((char *) NULL);
+
+ if ((gbp = PQgroup(portal, tuple_index)) &&
+ in_range("PQfname: field number",
+ field_number, 0, gbp->no_fields))
+ return (pbuf_findFname(gbp, field_number));
+ return ((char *) NULL);
}
/* --------------------------------
- * PQftype - Return the type of a field
+ * PQftype - Return the type of a field
* --------------------------------
*/
int
-PQftype(PortalBuffer *portal, int tuple_index, int field_number)
+PQftype(PortalBuffer * portal, int tuple_index, int field_number)
{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQftype: invalid portal pointer", portal) ||
- !in_range("PQfname: tuple index",
- tuple_index, 0, portal->no_tuples))
- return(-1);
-
- if ((gbp = PQgroup(portal, tuple_index)) &&
- in_range("PQftype: field number", field_number, 0, gbp->no_fields))
- return(gbp->types[field_number].adtid);
- return(-1);
+ GroupBuffer *gbp;
+
+ if (!valid_pointer("PQftype: invalid portal pointer", portal) ||
+ !in_range("PQfname: tuple index",
+ tuple_index, 0, portal->no_tuples))
+ return (-1);
+
+ if ((gbp = PQgroup(portal, tuple_index)) &&
+ in_range("PQftype: field number", field_number, 0, gbp->no_fields))
+ return (gbp->types[field_number].adtid);
+ return (-1);
}
/* --------------------------------
- * PQfsize - Return the size of a field
+ * PQfsize - Return the size of a field
* --------------------------------
*/
int
-PQfsize(PortalBuffer *portal, int tuple_index, int field_number)
+PQfsize(PortalBuffer * portal, int tuple_index, int field_number)
{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfsize: invalid portal pointer", portal) ||
- !in_range("PQfsize: tuple index",
- tuple_index, 0, portal->no_tuples))
- return(-1);
-
- if ((gbp = PQgroup(portal, tuple_index)) &&
- in_range("PQfsize: field number", field_number, 0, gbp->no_fields))
- return(gbp->types[field_number].adtsize);
- return(-1);
+ GroupBuffer *gbp;
+
+ if (!valid_pointer("PQfsize: invalid portal pointer", portal) ||
+ !in_range("PQfsize: tuple index",
+ tuple_index, 0, portal->no_tuples))
+ return (-1);
+
+ if ((gbp = PQgroup(portal, tuple_index)) &&
+ in_range("PQfsize: field number", field_number, 0, gbp->no_fields))
+ return (gbp->types[field_number].adtsize);
+ return (-1);
}
-
+
/* --------------------------------
- * PQsametype - Return 1 if the two tuples have the same type
- * (in the same group)
+ * PQsametype - Return 1 if the two tuples have the same type
+ * (in the same group)
* --------------------------------
*/
int
-PQsametype(PortalBuffer *portal, int tuple_index1, int tuple_index2)
-{
- GroupBuffer *gbp1, *gbp2;
-
- if (!valid_pointer("PQsametype: invalid portal pointer", portal) ||
- !in_range("PQsametype: tuple index 1",
- tuple_index1, 0, portal->no_tuples) ||
- !in_range("PQsametype: tuple index 2",
- tuple_index2, 0, portal->no_tuples))
- return(-1);
-
- gbp1 = PQgroup(portal, tuple_index1);
- gbp2 = PQgroup(portal, tuple_index2);
- if (gbp1 && gbp2)
- return(gbp1 == gbp2);
- return(-1);
+PQsametype(PortalBuffer * portal, int tuple_index1, int tuple_index2)
+{
+ GroupBuffer *gbp1,
+ *gbp2;
+
+ if (!valid_pointer("PQsametype: invalid portal pointer", portal) ||
+ !in_range("PQsametype: tuple index 1",
+ tuple_index1, 0, portal->no_tuples) ||
+ !in_range("PQsametype: tuple index 2",
+ tuple_index2, 0, portal->no_tuples))
+ return (-1);
+
+ gbp1 = PQgroup(portal, tuple_index1);
+ gbp2 = PQgroup(portal, tuple_index2);
+ if (gbp1 && gbp2)
+ return (gbp1 == gbp2);
+ return (-1);
}
static TupleBlock *
-PQGetTupleBlock(PortalBuffer *portal,
- int tuple_index,
- int *tuple_offset)
-{
- GroupBuffer *gbp;
- TupleBlock *tbp;
- int tuple_count = 0;
-
- if (!valid_pointer("PQGetTupleBlock: invalid portal pointer", portal) ||
- !valid_pointer("PQGetTupleBlock: invalid offset pointer",
- tuple_offset) ||
- !in_range("PQGetTupleBlock: tuple index",
- tuple_index, 0, portal->no_tuples))
- return((TupleBlock *) NULL);
-
- for (gbp = portal->groups;
- gbp && tuple_index >= (tuple_count += gbp->no_tuples);
- gbp = gbp->next)
- ;
- if (!gbp ||
- !in_range("PQGetTupleBlock: tuple not found: tuple index",
- tuple_index, 0, tuple_count))
- return((TupleBlock *) NULL);
- tuple_count -= gbp->no_tuples;
- for (tbp = gbp->tuples;
- tbp && tuple_index >= (tuple_count += TupleBlockSize);
- tbp = tbp->next)
- ;
- if (!tbp ||
- !in_range("PQGetTupleBlock: tuple not found: tuple index",
- tuple_index, 0, tuple_count))
- return((TupleBlock *) NULL);
- tuple_count -= TupleBlockSize;
-
- *tuple_offset = tuple_index - tuple_count;
- return(tbp);
+PQGetTupleBlock(PortalBuffer * portal,
+ int tuple_index,
+ int *tuple_offset)
+{
+ GroupBuffer *gbp;
+ TupleBlock *tbp;
+ int tuple_count = 0;
+
+ if (!valid_pointer("PQGetTupleBlock: invalid portal pointer", portal) ||
+ !valid_pointer("PQGetTupleBlock: invalid offset pointer",
+ tuple_offset) ||
+ !in_range("PQGetTupleBlock: tuple index",
+ tuple_index, 0, portal->no_tuples))
+ return ((TupleBlock *) NULL);
+
+ for (gbp = portal->groups;
+ gbp && tuple_index >= (tuple_count += gbp->no_tuples);
+ gbp = gbp->next)
+ ;
+ if (!gbp ||
+ !in_range("PQGetTupleBlock: tuple not found: tuple index",
+ tuple_index, 0, tuple_count))
+ return ((TupleBlock *) NULL);
+ tuple_count -= gbp->no_tuples;
+ for (tbp = gbp->tuples;
+ tbp && tuple_index >= (tuple_count += TupleBlockSize);
+ tbp = tbp->next)
+ ;
+ if (!tbp ||
+ !in_range("PQGetTupleBlock: tuple not found: tuple index",
+ tuple_index, 0, tuple_count))
+ return ((TupleBlock *) NULL);
+ tuple_count -= TupleBlockSize;
+
+ *tuple_offset = tuple_index - tuple_count;
+ return (tbp);
}
/* --------------------------------
- * PQgetvalue - Return an attribute (field) value
+ * PQgetvalue - Return an attribute (field) value
* --------------------------------
*/
-char *
-PQgetvalue(PortalBuffer *portal,
- int tuple_index,
- int field_number)
+char *
+PQgetvalue(PortalBuffer * portal,
+ int tuple_index,
+ int field_number)
{
- TupleBlock *tbp;
- int tuple_offset;
+ TupleBlock *tbp;
+ int tuple_offset;
- tbp = PQGetTupleBlock(portal, tuple_index, &tuple_offset);
- if (tbp)
- return(tbp->values[tuple_offset][field_number]);
- return((char *) NULL);
+ tbp = PQGetTupleBlock(portal, tuple_index, &tuple_offset);
+ if (tbp)
+ return (tbp->values[tuple_offset][field_number]);
+ return ((char *) NULL);
}
/* --------------------------------
- * PQgetAttr - Return an attribute (field) value
- * this differs from PQgetvalue in that the value returned is
- * a copy. The CALLER is responsible for free'ing the data returned.
+ * PQgetAttr - Return an attribute (field) value
+ * this differs from PQgetvalue in that the value returned is
+ * a copy. The CALLER is responsible for free'ing the data returned.
* --------------------------------
*/
-char *
-PQgetAttr(PortalBuffer *portal,
- int tuple_index,
- int field_number)
-{
- TupleBlock *tbp;
- int tuple_offset;
- int len;
- char* result = NULL;
-
- tbp = PQGetTupleBlock(portal, tuple_index, &tuple_offset);
- if (tbp) {
- len = tbp->lengths[tuple_offset][field_number];
- result = malloc(len + 1);
- memcpy(result,
- tbp->values[tuple_offset][field_number],
- len);
- result[len] = '\0';
- }
- return result;
+char *
+PQgetAttr(PortalBuffer * portal,
+ int tuple_index,
+ int field_number)
+{
+ TupleBlock *tbp;
+ int tuple_offset;
+ int len;
+ char *result = NULL;
+
+ tbp = PQGetTupleBlock(portal, tuple_index, &tuple_offset);
+ if (tbp)
+ {
+ len = tbp->lengths[tuple_offset][field_number];
+ result = malloc(len + 1);
+ memcpy(result,
+ tbp->values[tuple_offset][field_number],
+ len);
+ result[len] = '\0';
+ }
+ return result;
}
/* --------------------------------
- * PQgetlength - Return an attribute (field) length
+ * PQgetlength - Return an attribute (field) length
* --------------------------------
*/
int
-PQgetlength(PortalBuffer *portal,
- int tuple_index,
- int field_number)
+PQgetlength(PortalBuffer * portal,
+ int tuple_index,
+ int field_number)
{
- TupleBlock *tbp;
- int tuple_offset;
+ TupleBlock *tbp;
+ int tuple_offset;
- tbp = PQGetTupleBlock(portal, tuple_index, &tuple_offset);
- if (tbp)
- return(tbp->lengths[tuple_offset][field_number]);
- return(-1);
+ tbp = PQGetTupleBlock(portal, tuple_index, &tuple_offset);
+ if (tbp)
+ return (tbp->lengths[tuple_offset][field_number]);
+ return (-1);
}
/* ----------------
- * PQclear - free storage claimed by named portal
+ * PQclear - free storage claimed by named portal
* ----------------
*/
void
PQclear(char *pname)
-{
- if (!valid_pointer("PQclear: invalid portal name pointer", pname))
- return;
- pbuf_close(pname);
+{
+ if (!valid_pointer("PQclear: invalid portal name pointer", pname))
+ return;
+ pbuf_close(pname);
}
/*
@@ -644,74 +657,81 @@ PQclear(char *pname)
* This is going away with pending rewrite of comm. code...
*/
/* static SLList pqNotifyList;*/
-static Dllist *pqNotifyList = NULL;
+static Dllist *pqNotifyList = NULL;
/* remove invalid notifies before returning */
void
PQcleanNotify()
{
- Dlelem *e, *next;
- PQNotifyList *p;
-
- e = DLGetHead(pqNotifyList);
-
- while (e) {
- next = DLGetSucc(e);
- p = (PQNotifyList*)DLE_VAL(e);
- if (p->valid == 0) {
- DLRemove(e);
- DLFreeElem(e);
- pfree(p);
- }
- e = next;
- }
+ Dlelem *e,
+ *next;
+ PQNotifyList *p;
+
+ e = DLGetHead(pqNotifyList);
+
+ while (e)
+ {
+ next = DLGetSucc(e);
+ p = (PQNotifyList *) DLE_VAL(e);
+ if (p->valid == 0)
+ {
+ DLRemove(e);
+ DLFreeElem(e);
+ pfree(p);
+ }
+ e = next;
+ }
}
void
PQnotifies_init()
{
- Dlelem *e;
- PQNotifyList *p;
-
- if (pqNotifyList == NULL) {
- pqNotifyList = DLNewList();
- }
- else {
- /* clean all notifies */
- for (e = DLGetHead(pqNotifyList); e != NULL; e = DLGetSucc(e)) {
- p = (PQNotifyList*)DLE_VAL(e);
- p->valid = 0;
+ Dlelem *e;
+ PQNotifyList *p;
+
+ if (pqNotifyList == NULL)
+ {
+ pqNotifyList = DLNewList();
+ }
+ else
+ {
+ /* clean all notifies */
+ for (e = DLGetHead(pqNotifyList); e != NULL; e = DLGetSucc(e))
+ {
+ p = (PQNotifyList *) DLE_VAL(e);
+ p->valid = 0;
+ }
+ PQcleanNotify();
}
- PQcleanNotify();
- }
}
-PQNotifyList *
+PQNotifyList *
PQnotifies()
{
- Dlelem *e;
- PQcleanNotify();
- e = DLGetHead(pqNotifyList);
- return (e ? (PQNotifyList*)DLE_VAL(e) : NULL);
+ Dlelem *e;
+
+ PQcleanNotify();
+ e = DLGetHead(pqNotifyList);
+ return (e ? (PQNotifyList *) DLE_VAL(e) : NULL);
}
void
-PQremoveNotify(PQNotifyList *nPtr)
+PQremoveNotify(PQNotifyList * nPtr)
{
- nPtr->valid = 0; /* remove later */
+ nPtr->valid = 0; /* remove later */
}
void
PQappendNotify(char *relname, int pid)
{
- PQNotifyList *p;
-
- if (pqNotifyList == NULL)
- pqNotifyList = DLNewList();
-
- p = (PQNotifyList*)pbuf_alloc(sizeof(PQNotifyList));
- strNcpy(p->relname, relname, NAMEDATALEN-1);
- p->be_pid = pid;
- p->valid = 1;
- DLAddTail(pqNotifyList, DLNewElem(p));
+ PQNotifyList *p;
+
+ if (pqNotifyList == NULL)
+ pqNotifyList = DLNewList();
+
+ p = (PQNotifyList *) pbuf_alloc(sizeof(PQNotifyList));
+ strNcpy(p->relname, relname, NAMEDATALEN - 1);
+ p->be_pid = pid;
+ p->valid = 1;
+ DLAddTail(pqNotifyList, DLNewElem(p));
}
diff --git a/src/backend/libpq/portalbuf.c b/src/backend/libpq/portalbuf.c
index b7a527dcfaf..ed2d5bbe615 100644
--- a/src/backend/libpq/portalbuf.c
+++ b/src/backend/libpq/portalbuf.c
@@ -1,50 +1,50 @@
/*-------------------------------------------------------------------------
*
* portalbuf.c--
- * portal buffer support routines for src/libpq/portal.c
+ * portal buffer support routines for src/libpq/portal.c
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portalbuf.c,v 1.4 1997/08/12 20:15:23 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portalbuf.c,v 1.5 1997/09/07 04:42:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * pbuf_alloc - allocate memory for libpq routines
- * pbuf_free - free memory for libpq routines
- * pbuf_addPortal - Allocate a new portal buffer
- * pbuf_addGroup - Add a new tuple group to the portal
- * pbuf_addTypes - Allocate n type blocks
- * pbuf_addTuples - Allocate a tuple block
- * pbuf_addTuple - Allocate a tuple of n fields (attributes)
- * pbuf_addValues - Allocate n bytes for a value
- * pbuf_addEntry - Allocate a portal entry
- * pbuf_freeEntry - Free a portal entry in the portal table
- * pbuf_freeTypes - Free up the space used by a portal
- * pbuf_freeTuples - free space used by tuple block
- * pbuf_freeGroup - free space used by group, types and tuples
- * pbuf_freePortal - free space used by portal and portal's group
- * pbuf_getIndex - Return the index of the portal entry
- * pbuf_setup - Set up a portal for dumping data
- * pbuf_close - Close a portal, remove it from the portal table
- * pbuf_findGroup - Return group given the group_index
- * pbuf_findFnumber - Return field index of a given field within a group
- * pbuf_findFname - Find the field name given the field index
- * pbuf_checkFnumber - signal an error if field number is out of bounds
+ * pbuf_alloc - allocate memory for libpq routines
+ * pbuf_free - free memory for libpq routines
+ * pbuf_addPortal - Allocate a new portal buffer
+ * pbuf_addGroup - Add a new tuple group to the portal
+ * pbuf_addTypes - Allocate n type blocks
+ * pbuf_addTuples - Allocate a tuple block
+ * pbuf_addTuple - Allocate a tuple of n fields (attributes)
+ * pbuf_addValues - Allocate n bytes for a value
+ * pbuf_addEntry - Allocate a portal entry
+ * pbuf_freeEntry - Free a portal entry in the portal table
+ * pbuf_freeTypes - Free up the space used by a portal
+ * pbuf_freeTuples - free space used by tuple block
+ * pbuf_freeGroup - free space used by group, types and tuples
+ * pbuf_freePortal - free space used by portal and portal's group
+ * pbuf_getIndex - Return the index of the portal entry
+ * pbuf_setup - Set up a portal for dumping data
+ * pbuf_close - Close a portal, remove it from the portal table
+ * pbuf_findGroup - Return group given the group_index
+ * pbuf_findFnumber - Return field index of a given field within a group
+ * pbuf_findFname - Find the field name given the field index
+ * pbuf_checkFnumber - signal an error if field number is out of bounds
*
* NOTES
- * These functions may be used by both frontend routines which
- * communicate with a backend or by user-defined functions which
- * are compiled or dynamically loaded into a backend.
+ * These functions may be used by both frontend routines which
+ * communicate with a backend or by user-defined functions which
+ * are compiled or dynamically loaded into a backend.
*
- * the portals[] array should be organized as a hash table for
- * quick portal-by-name lookup.
+ * the portals[] array should be organized as a hash table for
+ * quick portal-by-name lookup.
*
- * Do not confuse "PortalEntry" (or "PortalBuffer") with "Portal"
- * see utils/mmgr/portalmem.c for why. -cim 2/22/91
+ * Do not confuse "PortalEntry" (or "PortalBuffer") with "Portal"
+ * see utils/mmgr/portalmem.c for why. -cim 2/22/91
*
*/
#include <string.h>
@@ -55,407 +55,417 @@
#include <libpq/libpq.h> /* where the declarations go */
#include <utils/exc.h>
-PortalEntry** portals = (PortalEntry**) NULL;
-size_t portals_array_size = 0;
+PortalEntry **portals = (PortalEntry **) NULL;
+size_t portals_array_size = 0;
/* portals array memory is malloc'd instead of using MemoryContexts */
/* since it will be used by both front and backend programs*/
-/* GlobalMemory portals_mmcxt = (GlobalMemory) NULL; */
+/* GlobalMemory portals_mmcxt = (GlobalMemory) NULL; */
-/* -------------------------------
+/* -------------------------------
* portals_realloc --
- * grow the size of the portals array by size
+ * grow the size of the portals array by size
*
- * also ensures that elements are initially NULL
+ * also ensures that elements are initially NULL
*/
static void
portals_realloc(size_t size)
{
- size_t oldsize;
- int i;
- PortalEntry** newp;
-
- oldsize = portals_array_size;
-
- portals_array_size += size;
- if (portals)
- newp= (PortalEntry**)realloc(portals,
- portals_array_size*sizeof(PortalEntry*));
- else
- newp= (PortalEntry**)malloc(portals_array_size*sizeof(PortalEntry*));
-
- if (newp)
- portals = newp;
- else
- libpq_raise(&PortalError,
- form("Cannot alloc more memory in portals_realloc"));
-
- for (i=oldsize;i<portals_array_size;i++)
- portals[i]=(PortalEntry*)NULL;
-
+ size_t oldsize;
+ int i;
+ PortalEntry **newp;
+
+ oldsize = portals_array_size;
+
+ portals_array_size += size;
+ if (portals)
+ newp = (PortalEntry **) realloc(portals,
+ portals_array_size * sizeof(PortalEntry *));
+ else
+ newp = (PortalEntry **) malloc(portals_array_size * sizeof(PortalEntry *));
+
+ if (newp)
+ portals = newp;
+ else
+ libpq_raise(&PortalError,
+ form("Cannot alloc more memory in portals_realloc"));
+
+ for (i = oldsize; i < portals_array_size; i++)
+ portals[i] = (PortalEntry *) NULL;
+
}
/* --------------------------------
- * pbuf_alloc - allocate memory for portal buffers
+ * pbuf_alloc - allocate memory for portal buffers
*
- * remember: palloc() in the backend uses the postgres MemoryContext
- * library and palloc() in the frontend (fe-pqstubs.c) calls malloc().
+ * remember: palloc() in the backend uses the postgres MemoryContext
+ * library and palloc() in the frontend (fe-pqstubs.c) calls malloc().
* --------------------------------
*/
caddr_t
pbuf_alloc(size_t size)
{
- caddr_t addr;
-
- if (size <= 0)
- libpq_raise(&MemoryError, form("Invalid argument to pbuf_alloc()."));
-
- addr = (caddr_t) palloc(size);
- if (addr == (caddr_t) NULL)
- libpq_raise(&MemoryError, form("Cannot Allocate space."));
-
- return (addr);
+ caddr_t addr;
+
+ if (size <= 0)
+ libpq_raise(&MemoryError, form("Invalid argument to pbuf_alloc()."));
+
+ addr = (caddr_t) palloc(size);
+ if (addr == (caddr_t) NULL)
+ libpq_raise(&MemoryError, form("Cannot Allocate space."));
+
+ return (addr);
}
/* --------------------------------
- * pbuf_free - free memory for portal buffers
+ * pbuf_free - free memory for portal buffers
*
- * remember: pfree() in the backend uses the postgres MemoryContext
- * library and pfree() in the frontend (fe-pqstubs.c) calls free().
+ * remember: pfree() in the backend uses the postgres MemoryContext
+ * library and pfree() in the frontend (fe-pqstubs.c) calls free().
* --------------------------------
*/
void
pbuf_free(caddr_t pointer)
{
- if (pointer)
- pfree(pointer);
- else
- libpq_raise(&MemoryError, form("Tried to free NULL memory pointer"));
-
+ if (pointer)
+ pfree(pointer);
+ else
+ libpq_raise(&MemoryError, form("Tried to free NULL memory pointer"));
+
}
/* --------------------------------
- * pbuf_addPortal - Allocate a new portal buffer
+ * pbuf_addPortal - Allocate a new portal buffer
* --------------------------------
*/
-PortalBuffer *
+PortalBuffer *
pbuf_addPortal()
{
- PortalBuffer *portal;
-
- portal = (PortalBuffer *)
- pbuf_alloc(sizeof (PortalBuffer));
-
- portal->rule_p = 0;
- portal->no_tuples = 0;
- portal->no_groups = 0;
- portal->groups = NULL;
-
- return (portal);
+ PortalBuffer *portal;
+
+ portal = (PortalBuffer *)
+ pbuf_alloc(sizeof(PortalBuffer));
+
+ portal->rule_p = 0;
+ portal->no_tuples = 0;
+ portal->no_groups = 0;
+ portal->groups = NULL;
+
+ return (portal);
}
/* --------------------------------
- * pbuf_addGroup - Add a new tuple group to the portal
+ * pbuf_addGroup - Add a new tuple group to the portal
* --------------------------------
*/
-GroupBuffer *
-pbuf_addGroup(PortalBuffer *portal)
+GroupBuffer *
+pbuf_addGroup(PortalBuffer * portal)
{
- GroupBuffer *group, *group1;
-
- group = (GroupBuffer *)
- pbuf_alloc(sizeof (GroupBuffer));
-
- /* Initialize the new group buffer. */
- group->no_tuples = 0;
- group->no_fields = 0;
- group->types = NULL;
- group->tuples = NULL;
- group->next = NULL;
-
- if ((group1 = portal->groups) == NULL)
- portal->groups = group;
- else {
- while (group1->next != NULL)
- group1 = group1->next;
- group1->next = group;
- }
-
- return (group);
+ GroupBuffer *group,
+ *group1;
+
+ group = (GroupBuffer *)
+ pbuf_alloc(sizeof(GroupBuffer));
+
+ /* Initialize the new group buffer. */
+ group->no_tuples = 0;
+ group->no_fields = 0;
+ group->types = NULL;
+ group->tuples = NULL;
+ group->next = NULL;
+
+ if ((group1 = portal->groups) == NULL)
+ portal->groups = group;
+ else
+ {
+ while (group1->next != NULL)
+ group1 = group1->next;
+ group1->next = group;
+ }
+
+ return (group);
}
/* --------------------------------
- * pbuf_addTypes - Allocate n type blocks
+ * pbuf_addTypes - Allocate n type blocks
* --------------------------------
*/
-TypeBlock *
+TypeBlock *
pbuf_addTypes(int n)
{
- TypeBlock *types;
-
- types = (TypeBlock *)
- pbuf_alloc(n * sizeof (TypeBlock));
-
- return (types);
+ TypeBlock *types;
+
+ types = (TypeBlock *)
+ pbuf_alloc(n * sizeof(TypeBlock));
+
+ return (types);
}
/* --------------------------------
- * pbuf_addTuples - Allocate a tuple block
+ * pbuf_addTuples - Allocate a tuple block
* --------------------------------
*/
-TupleBlock *
+TupleBlock *
pbuf_addTuples()
{
- TupleBlock *tuples;
-
- tuples = (TupleBlock *)
- pbuf_alloc(sizeof (TupleBlock));
-
- tuples->next = NULL;
- tuples->tuple_index = 0;
-
- return (tuples);
+ TupleBlock *tuples;
+
+ tuples = (TupleBlock *)
+ pbuf_alloc(sizeof(TupleBlock));
+
+ tuples->next = NULL;
+ tuples->tuple_index = 0;
+
+ return (tuples);
}
/* --------------------------------
- * pbuf_addTuple - Allocate a tuple of n fields (attributes)
+ * pbuf_addTuple - Allocate a tuple of n fields (attributes)
* --------------------------------
*/
-char **
+char **
pbuf_addTuple(int n)
{
- return (char **)
- pbuf_alloc(n * sizeof (char *));
+ return (char **)
+ pbuf_alloc(n * sizeof(char *));
}
/* --------------------------------
- * pbuf_addTupleValueLengths - Allocate a tuple of n lengths (attributes)
+ * pbuf_addTupleValueLengths - Allocate a tuple of n lengths (attributes)
* --------------------------------
*/
-int *
+int *
pbuf_addTupleValueLengths(int n)
{
- return (int *)
+ return (int *)
pbuf_alloc(n * sizeof(int));
}
/* --------------------------------
- * pbuf_addValues - Allocate n bytes for a value
+ * pbuf_addValues - Allocate n bytes for a value
* --------------------------------
*/
-char *
+char *
pbuf_addValues(int n)
{
- return
+ return
pbuf_alloc(n);
}
/* --------------------------------
- * pbuf_addEntry - Allocate a portal entry
+ * pbuf_addEntry - Allocate a portal entry
* --------------------------------
*/
-PortalEntry *pbuf_addEntry()
+PortalEntry *
+pbuf_addEntry()
{
- return (PortalEntry *)
- pbuf_alloc (sizeof (PortalEntry));
+ return (PortalEntry *)
+ pbuf_alloc(sizeof(PortalEntry));
}
/* --------------------------------
- * pbuf_freeEntry - Free a portal entry in the portal table
- * the portal is freed separately.
+ * pbuf_freeEntry - Free a portal entry in the portal table
+ * the portal is freed separately.
* --------------------------------
*/
void
pbuf_freeEntry(int i)
{
- if (portals)
+ if (portals)
{
- pbuf_free ((caddr_t)portals[i]);
- portals[i] = NULL;
+ pbuf_free((caddr_t) portals[i]);
+ portals[i] = NULL;
}
}
/* --------------------------------
- * pbuf_freeTypes - Free up the space used by a portal
+ * pbuf_freeTypes - Free up the space used by a portal
* --------------------------------
*/
void
-pbuf_freeTypes(TypeBlock *types)
+pbuf_freeTypes(TypeBlock * types)
{
- pbuf_free((caddr_t)types);
+ pbuf_free((caddr_t) types);
}
/* --------------------------------
- * pbuf_freeTuples - free space used by tuple block
+ * pbuf_freeTuples - free space used by tuple block
* --------------------------------
*/
void
-pbuf_freeTuples(TupleBlock *tuples,
- int no_tuples,
- int no_fields)
+pbuf_freeTuples(TupleBlock * tuples,
+ int no_tuples,
+ int no_fields)
{
- int i, j;
-
- if (no_tuples > TupleBlockSize) {
- pbuf_freeTuples (tuples->next, no_tuples - TupleBlockSize, no_fields);
- no_tuples = TupleBlockSize;
- }
-
- /* For each tuple, free all its attribute values. */
- for (i = 0; i < no_tuples; i++) {
- for (j = 0; j < no_fields; j++)
- if (tuples->values[i][j] != NULL)
- pbuf_free((caddr_t)tuples->values[i][j]);
- if (tuples->lengths[i])
- pbuf_free((caddr_t)tuples->lengths[i]);
- if (tuples->values[i])
- pbuf_free((caddr_t)tuples->values[i]);
- }
-
- pbuf_free((caddr_t)tuples);
+ int i,
+ j;
+
+ if (no_tuples > TupleBlockSize)
+ {
+ pbuf_freeTuples(tuples->next, no_tuples - TupleBlockSize, no_fields);
+ no_tuples = TupleBlockSize;
+ }
+
+ /* For each tuple, free all its attribute values. */
+ for (i = 0; i < no_tuples; i++)
+ {
+ for (j = 0; j < no_fields; j++)
+ if (tuples->values[i][j] != NULL)
+ pbuf_free((caddr_t) tuples->values[i][j]);
+ if (tuples->lengths[i])
+ pbuf_free((caddr_t) tuples->lengths[i]);
+ if (tuples->values[i])
+ pbuf_free((caddr_t) tuples->values[i]);
+ }
+
+ pbuf_free((caddr_t) tuples);
}
/* --------------------------------
- * pbuf_freeGroup - free space used by group, types and tuples
+ * pbuf_freeGroup - free space used by group, types and tuples
* --------------------------------
*/
void
-pbuf_freeGroup(GroupBuffer *group)
+pbuf_freeGroup(GroupBuffer * group)
{
- if (group->next != NULL)
- pbuf_freeGroup(group->next);
-
- if (group->types != NULL)
- pbuf_freeTypes(group->types);
-
- if (group->tuples != NULL)
- pbuf_freeTuples(group->tuples, group->no_tuples,group->no_fields);
-
- pbuf_free((caddr_t)group);
+ if (group->next != NULL)
+ pbuf_freeGroup(group->next);
+
+ if (group->types != NULL)
+ pbuf_freeTypes(group->types);
+
+ if (group->tuples != NULL)
+ pbuf_freeTuples(group->tuples, group->no_tuples, group->no_fields);
+
+ pbuf_free((caddr_t) group);
}
/* --------------------------------
- * pbuf_freePortal - free space used by portal and portal's group
+ * pbuf_freePortal - free space used by portal and portal's group
* --------------------------------
*/
void
-pbuf_freePortal(PortalBuffer *portal)
+pbuf_freePortal(PortalBuffer * portal)
{
- if (portal->groups != NULL)
- pbuf_freeGroup(portal->groups);
-
- pbuf_free((caddr_t)portal);
+ if (portal->groups != NULL)
+ pbuf_freeGroup(portal->groups);
+
+ pbuf_free((caddr_t) portal);
}
/* --------------------------------
- * pbuf_getIndex - Return the index of the portal entry
- * note: portals[] maps portal names to portal buffers.
+ * pbuf_getIndex - Return the index of the portal entry
+ * note: portals[] maps portal names to portal buffers.
* --------------------------------
*/
int
pbuf_getIndex(char *pname)
{
- int i;
-
- if (portals) {
- for (i = 0; i < portals_array_size; i++)
- if (portals[i] != NULL &&
- strncmp(portals[i]->name, pname, PortalNameLength) == 0)
- return i;
- }
-
- return (-1);
+ int i;
+
+ if (portals)
+ {
+ for (i = 0; i < portals_array_size; i++)
+ if (portals[i] != NULL &&
+ strncmp(portals[i]->name, pname, PortalNameLength) == 0)
+ return i;
+ }
+
+ return (-1);
}
/* --------------------------------
- * pbuf_setportalname - assign a user given name to a portal
+ * pbuf_setportalname - assign a user given name to a portal
* --------------------------------
*/
void
-pbuf_setportalinfo(PortalEntry *entry, char *pname)
+pbuf_setportalinfo(PortalEntry * entry, char *pname)
{
- if (entry)
- strNcpy(entry->name, pname, PortalNameLength-1);
+ if (entry)
+ strNcpy(entry->name, pname, PortalNameLength - 1);
}
/* --------------------------------
- * pbuf_setup - Set up a portal for dumping data
+ * pbuf_setup - Set up a portal for dumping data
* --------------------------------
*/
-PortalEntry *
+PortalEntry *
pbuf_setup(char *pname)
{
- int i;
-
- if (!portals) /* the portals array has not been allocated yet */
+ int i;
+
+ if (!portals) /* the portals array has not been
+ * allocated yet */
{
- /* allocate portals[] array here */
- portals_realloc(PORTALS_INITIAL_SIZE);
+ /* allocate portals[] array here */
+ portals_realloc(PORTALS_INITIAL_SIZE);
}
-
- /* If a portal with the same name already exists, close it. */
- /* else look for an empty entry in the portal table. */
- if ((i = pbuf_getIndex(pname)) != -1)
- pbuf_freePortal(portals[i]->portal);
- else {
- for (i = 0; i < portals_array_size; i++)
- if (portals[i] == NULL)
- break;
-
- /* If the portal table is full, enlarge it */
- if (i >= portals_array_size)
- portals_realloc(PORTALS_GROW_BY);
-
- portals[i] = pbuf_addEntry();
- strncpy(portals[i]->name, pname, PortalNameLength);
- }
- portals[i]->portal = pbuf_addPortal();
- portals[i]->portalcxt = NULL;
- portals[i]->result = NULL;
-
- return portals[i];
+
+ /* If a portal with the same name already exists, close it. */
+ /* else look for an empty entry in the portal table. */
+ if ((i = pbuf_getIndex(pname)) != -1)
+ pbuf_freePortal(portals[i]->portal);
+ else
+ {
+ for (i = 0; i < portals_array_size; i++)
+ if (portals[i] == NULL)
+ break;
+
+ /* If the portal table is full, enlarge it */
+ if (i >= portals_array_size)
+ portals_realloc(PORTALS_GROW_BY);
+
+ portals[i] = pbuf_addEntry();
+ strncpy(portals[i]->name, pname, PortalNameLength);
+ }
+ portals[i]->portal = pbuf_addPortal();
+ portals[i]->portalcxt = NULL;
+ portals[i]->result = NULL;
+
+ return portals[i];
}
/* --------------------------------
- * pbuf_close - Close a portal, remove it from the portal table
- * and free up the space
+ * pbuf_close - Close a portal, remove it from the portal table
+ * and free up the space
* --------------------------------
*/
void
pbuf_close(char *pname)
{
- int i;
-
- if ((i = pbuf_getIndex(pname)) == -1)
- libpq_raise(&PortalError, form("Portal %s does not exist.", pname));
-
- pbuf_freePortal(portals[i]->portal);
- pbuf_freeEntry(i);
+ int i;
+
+ if ((i = pbuf_getIndex(pname)) == -1)
+ libpq_raise(&PortalError, form("Portal %s does not exist.", pname));
+
+ pbuf_freePortal(portals[i]->portal);
+ pbuf_freeEntry(i);
}
/* --------------------------------
- * pbuf_findGroup - Return the group given the group_index
+ * pbuf_findGroup - Return the group given the group_index
* --------------------------------
*/
-GroupBuffer *
-pbuf_findGroup(PortalBuffer *portal,
- int group_index)
+GroupBuffer *
+pbuf_findGroup(PortalBuffer * portal,
+ int group_index)
{
- GroupBuffer *group;
-
- group = portal->groups;
- while (group_index > 0 && group != NULL) {
- group = group->next;
- group_index--;
- }
-
- if (group == NULL)
- libpq_raise(&PortalError,
- form("Group index %d out of bound.", group_index));
-
- return (group);
+ GroupBuffer *group;
+
+ group = portal->groups;
+ while (group_index > 0 && group != NULL)
+ {
+ group = group->next;
+ group_index--;
+ }
+
+ if (group == NULL)
+ libpq_raise(&PortalError,
+ form("Group index %d out of bound.", group_index));
+
+ return (group);
}
/* --------------------------------
@@ -463,49 +473,48 @@ pbuf_findGroup(PortalBuffer *portal,
* --------------------------------
*/
int
-pbuf_findFnumber(GroupBuffer *group,
- char *field_name)
-{
- TypeBlock *types;
- int i;
-
- types = group->types;
-
- for (i = 0; i < group->no_fields; i++)
- if (strncmp(types[i].name, field_name, NAMEDATALEN) == 0)
- return (i);
-
- libpq_raise(&PortalError,
- form("Field-name %s does not exist.", field_name));
-
- /* not reached, here to make compiler happy */
- return 0;
+pbuf_findFnumber(GroupBuffer * group,
+ char *field_name)
+{
+ TypeBlock *types;
+ int i;
+
+ types = group->types;
+
+ for (i = 0; i < group->no_fields; i++)
+ if (strncmp(types[i].name, field_name, NAMEDATALEN) == 0)
+ return (i);
+
+ libpq_raise(&PortalError,
+ form("Field-name %s does not exist.", field_name));
+
+ /* not reached, here to make compiler happy */
+ return 0;
}
/* --------------------------------
- * pbuf_checkFnumber - signal an error if field number is out of bounds
+ * pbuf_checkFnumber - signal an error if field number is out of bounds
* --------------------------------
*/
void
-pbuf_checkFnumber(GroupBuffer *group,
- int field_number)
+pbuf_checkFnumber(GroupBuffer * group,
+ int field_number)
{
- if (field_number < 0 || field_number >= group->no_fields)
- libpq_raise(&PortalError,
- form("Field number %d out of bound.", field_number));
+ if (field_number < 0 || field_number >= group->no_fields)
+ libpq_raise(&PortalError,
+ form("Field number %d out of bound.", field_number));
}
/* --------------------------------
- * pbuf_findFname - Find the field name given the field index
+ * pbuf_findFname - Find the field name given the field index
* --------------------------------
*/
-char *
-pbuf_findFname(GroupBuffer *group,
- int field_number)
+char *
+pbuf_findFname(GroupBuffer * group,
+ int field_number)
{
- pbuf_checkFnumber(group, field_number);
- return
- (group->types[field_number]).name;
+ pbuf_checkFnumber(group, field_number);
+ return
+ (group->types[field_number]).name;
}
-
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index cfa0aebc521..6a7df5771ac 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1,37 +1,37 @@
/*-------------------------------------------------------------------------
*
* pqcomm.c--
- * Communication functions between the Frontend and the Backend
+ * Communication functions between the Frontend and the Backend
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.19 1997/08/12 22:52:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.20 1997/09/07 04:42:25 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * pq_gettty - return the name of the tty in the given buffer
- * pq_getport - return the PGPORT setting
- * pq_close - close input / output connections
- * pq_flush - flush pending output
- * pq_getstr - get a null terminated string from connection
- * pq_getnchar - get n characters from connection
- * pq_getint - get an integer from connection
- * pq_putstr - send a null terminated string to connection
- * pq_putnchar - send n characters to connection
- * pq_putint - send an integer to connection
- * pq_getinaddr - initialize address from host and port number
- * pq_getinserv - initialize address from host and service name
- * pq_connect - create remote input / output connection
- * pq_accept - accept remote input / output connection
- * pq_async_notify - receive notification from backend.
+ * pq_gettty - return the name of the tty in the given buffer
+ * pq_getport - return the PGPORT setting
+ * pq_close - close input / output connections
+ * pq_flush - flush pending output
+ * pq_getstr - get a null terminated string from connection
+ * pq_getnchar - get n characters from connection
+ * pq_getint - get an integer from connection
+ * pq_putstr - send a null terminated string to connection
+ * pq_putnchar - send n characters to connection
+ * pq_putint - send an integer to connection
+ * pq_getinaddr - initialize address from host and port number
+ * pq_getinserv - initialize address from host and service name
+ * pq_connect - create remote input / output connection
+ * pq_accept - accept remote input / output connection
+ * pq_async_notify - receive notification from backend.
*
* NOTES
- * These functions are used by both frontend applications and
- * the postgres backend.
+ * These functions are used by both frontend applications and
+ * the postgres backend.
*
*/
#include <stdio.h>
@@ -39,7 +39,7 @@
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
-#include <unistd.h> /* for ttyname() */
+#include <unistd.h> /* for ttyname() */
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
@@ -49,208 +49,217 @@
#if defined(linux)
#ifndef SOMAXCONN
-#define SOMAXCONN 5 /* from Linux listen(2) man page */
-#endif /* SOMAXCONN */
-#endif /* linux */
+#define SOMAXCONN 5 /* from Linux listen(2) man page */
+#endif /* SOMAXCONN */
+#endif /* linux */
#include <postgres.h>
#include <libpq/pqsignal.h>
#include <libpq/auth.h>
-#include <libpq/libpq.h> /* where the declarations go */
+#include <libpq/libpq.h> /* where the declarations go */
/* ----------------
- * declarations
+ * declarations
* ----------------
*/
-FILE *Pfout, *Pfin;
-FILE *Pfdebug; /* debugging libpq */
-int PQAsyncNotifyWaiting; /* for async. notification */
+FILE *Pfout,
+ *Pfin;
+FILE *Pfdebug; /* debugging libpq */
+int PQAsyncNotifyWaiting; /* for async. notification */
/* --------------------------------
- * pq_init - open portal file descriptors
+ * pq_init - open portal file descriptors
* --------------------------------
*/
void
pq_init(int fd)
{
- Pfin = fdopen(fd, "r");
- Pfout = fdopen(dup(fd), "w");
- if (!Pfin || !Pfout)
- elog(FATAL, "pq_init: Couldn't initialize socket connection");
- PQnotifies_init();
- if (getenv("LIBPQ_DEBUG")) {
- Pfdebug = stderr;
- }else {
- Pfdebug = NULL;
- }
+ Pfin = fdopen(fd, "r");
+ Pfout = fdopen(dup(fd), "w");
+ if (!Pfin || !Pfout)
+ elog(FATAL, "pq_init: Couldn't initialize socket connection");
+ PQnotifies_init();
+ if (getenv("LIBPQ_DEBUG"))
+ {
+ Pfdebug = stderr;
+ }
+ else
+ {
+ Pfdebug = NULL;
+ }
}
/* -------------------------
- * pq_getc(File* fin)
- *
- * get a character from the input file,
+ * pq_getc(File* fin)
+ *
+ * get a character from the input file,
*
- * if Pfdebug is set, also echo the character fetched into Pfdebug
+ * if Pfdebug is set, also echo the character fetched into Pfdebug
*
- * used for debugging libpq
+ * used for debugging libpq
*/
static int
-pq_getc(FILE* fin)
+pq_getc(FILE * fin)
{
- int c;
+ int c;
- c = getc(fin);
- if (Pfdebug && c != EOF)
- putc(c,Pfdebug);
- return c;
+ c = getc(fin);
+ if (Pfdebug && c != EOF)
+ putc(c, Pfdebug);
+ return c;
}
/* --------------------------------
- * pq_gettty - return the name of the tty in the given buffer
+ * pq_gettty - return the name of the tty in the given buffer
* --------------------------------
*/
void
pq_gettty(char *tp)
-{
- strncpy(tp, ttyname(0), 19);
+{
+ strncpy(tp, ttyname(0), 19);
}
/* --------------------------------
- * pq_getport - return the PGPORT setting
+ * pq_getport - return the PGPORT setting
* --------------------------------
*/
int
pq_getport()
{
- char *envport = getenv("PGPORT");
-
- if (envport)
- return(atoi(envport));
- return(atoi(DEF_PGPORT));
+ char *envport = getenv("PGPORT");
+
+ if (envport)
+ return (atoi(envport));
+ return (atoi(DEF_PGPORT));
}
/* --------------------------------
- * pq_close - close input / output connections
+ * pq_close - close input / output connections
* --------------------------------
*/
void
pq_close()
{
- if (Pfin) {
- fclose(Pfin);
- Pfin = NULL;
- }
- if (Pfout) {
- fclose(Pfout);
- Pfout = NULL;
- }
- PQAsyncNotifyWaiting = 0;
- PQnotifies_init();
- pq_unregoob();
+ if (Pfin)
+ {
+ fclose(Pfin);
+ Pfin = NULL;
+ }
+ if (Pfout)
+ {
+ fclose(Pfout);
+ Pfout = NULL;
+ }
+ PQAsyncNotifyWaiting = 0;
+ PQnotifies_init();
+ pq_unregoob();
}
/* --------------------------------
- * pq_flush - flush pending output
+ * pq_flush - flush pending output
* --------------------------------
*/
void
pq_flush()
{
- if (Pfout)
- fflush(Pfout);
+ if (Pfout)
+ fflush(Pfout);
}
/* --------------------------------
- * pq_getstr - get a null terminated string from connection
+ * pq_getstr - get a null terminated string from connection
* --------------------------------
*/
int
pq_getstr(char *s, int maxlen)
{
- int c = '\0';
-
- if (Pfin == (FILE *) NULL) {
-/* elog(DEBUG, "Input descriptor is null"); */
- return(EOF);
- }
-
- while (maxlen-- && (c = pq_getc(Pfin)) != EOF && c)
- *s++ = c;
- *s = '\0';
-
- /* -----------------
- * If EOF reached let caller know.
- * (This will only happen if we hit EOF before the string
- * delimiter is reached.)
- * -----------------
- */
- if (c == EOF)
- return(EOF);
- return(!EOF);
+ int c = '\0';
+
+ if (Pfin == (FILE *) NULL)
+ {
+/* elog(DEBUG, "Input descriptor is null"); */
+ return (EOF);
+ }
+
+ while (maxlen-- && (c = pq_getc(Pfin)) != EOF && c)
+ *s++ = c;
+ *s = '\0';
+
+ /* -----------------
+ * If EOF reached let caller know.
+ * (This will only happen if we hit EOF before the string
+ * delimiter is reached.)
+ * -----------------
+ */
+ if (c == EOF)
+ return (EOF);
+ return (!EOF);
}
/*
* USER FUNCTION - gets a newline-terminated string from the backend.
- *
+ *
* Chiefly here so that applications can use "COPY <rel> to stdout"
- * and read the output string. Returns a null-terminated string in s.
+ * and read the output string. Returns a null-terminated string in s.
*
* PQgetline reads up to maxlen-1 characters (like fgets(3)) but strips
* the terminating \n (like gets(3)).
*
* RETURNS:
- * EOF if it is detected or invalid arguments are given
- * 0 if EOL is reached (i.e., \n has been read)
- * (this is required for backward-compatibility -- this
- * routine used to always return EOF or 0, assuming that
- * the line ended within maxlen bytes.)
- * 1 in other cases
+ * EOF if it is detected or invalid arguments are given
+ * 0 if EOL is reached (i.e., \n has been read)
+ * (this is required for backward-compatibility -- this
+ * routine used to always return EOF or 0, assuming that
+ * the line ended within maxlen bytes.)
+ * 1 in other cases
*/
-int PQgetline(char *s, int maxlen)
+int
+PQgetline(char *s, int maxlen)
+{
+ if (!Pfin || !s || maxlen <= 1)
+ return (EOF);
+
+ if (fgets(s, maxlen - 1, Pfin) == NULL)
{
- if (!Pfin || !s || maxlen <= 1)
- return(EOF);
-
- if(fgets(s, maxlen - 1, Pfin) == NULL)
- {
- return feof(Pfin) ? EOF : 1;
- }
- else
- {
- for( ; *s; s++)
- {
- if(*s == '\n')
- {
- *s = '\0';
- break;
- }
- }
- }
-
- return 0;
- }
+ return feof(Pfin) ? EOF : 1;
+ }
+ else
+ {
+ for (; *s; s++)
+ {
+ if (*s == '\n')
+ {
+ *s = '\0';
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
/*
* USER FUNCTION - sends a string to the backend.
- *
+ *
* Chiefly here so that applications can use "COPY <rel> from stdin".
*
* RETURNS:
- * 0 in all cases.
+ * 0 in all cases.
*/
int
PQputline(char *s)
{
- if (Pfout) {
- fputs(s, Pfout);
- fflush(Pfout);
- }
- return(0);
+ if (Pfout)
+ {
+ fputs(s, Pfout);
+ fflush(Pfout);
+ }
+ return (0);
}
/* --------------------------------
- * pq_getnchar - get n characters from connection
+ * pq_getnchar - get n characters from connection
* --------------------------------
*/
int
@@ -259,228 +268,239 @@ pq_getnchar(char *s, int off, int maxlen)
return pqGetNBytes(s + off, maxlen, Pfin);
#if 0
- int c = '\0';
-
- if (Pfin == (FILE *) NULL) {
-/* elog(DEBUG, "Input descriptor is null"); */
- return(EOF);
- }
-
- s += off;
- while (maxlen-- && (c = pq_getc(Pfin)) != EOF)
- *s++ = c;
-
- /* -----------------
- * If EOF reached let caller know
- * -----------------
- */
- if (c == EOF)
- return(EOF);
- return(!EOF);
+ int c = '\0';
+
+ if (Pfin == (FILE *) NULL)
+ {
+/* elog(DEBUG, "Input descriptor is null"); */
+ return (EOF);
+ }
+
+ s += off;
+ while (maxlen-- && (c = pq_getc(Pfin)) != EOF)
+ *s++ = c;
+
+ /* -----------------
+ * If EOF reached let caller know
+ * -----------------
+ */
+ if (c == EOF)
+ return (EOF);
+ return (!EOF);
#endif
}
/* --------------------------------
- * pq_getint - get an integer from connection
- * we receive an integer a byte at a type and reconstruct it so that
- * machines with different ENDIAN representations can talk to each
- * other
+ * pq_getint - get an integer from connection
+ * we receive an integer a byte at a type and reconstruct it so that
+ * machines with different ENDIAN representations can talk to each
+ * other
* --------------------------------
*/
int
pq_getint(int b)
{
- int n, status = 1;
-
- if(!Pfin)
- return EOF;
- /* mjl: Seems inconsisten w/ return value of pq_putint (void). Also,
- EOF is a valid return value for an int! XXX */
-
- switch(b)
- {
- case 1:
- status = ((n = fgetc(Pfin)) == EOF);
- break;
- case 2:
- status = pqGetShort(&n, Pfin);
- break;
- case 4:
- status = pqGetLong(&n, Pfin);
- break;
- default:
- fprintf(stderr, "** Unsupported size %d\n", b);
- }
-
- if(status)
- {
- sprintf(PQerrormsg,
- "FATAL: pq_getint failed: errno=%d\n", errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- n = 0;
- }
-
- return n;
+ int n,
+ status = 1;
+
+ if (!Pfin)
+ return EOF;
+
+ /*
+ * mjl: Seems inconsisten w/ return value of pq_putint (void). Also,
+ * EOF is a valid return value for an int! XXX
+ */
+
+ switch (b)
+ {
+ case 1:
+ status = ((n = fgetc(Pfin)) == EOF);
+ break;
+ case 2:
+ status = pqGetShort(&n, Pfin);
+ break;
+ case 4:
+ status = pqGetLong(&n, Pfin);
+ break;
+ default:
+ fprintf(stderr, "** Unsupported size %d\n", b);
+ }
+
+ if (status)
+ {
+ sprintf(PQerrormsg,
+ "FATAL: pq_getint failed: errno=%d\n", errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ n = 0;
+ }
+
+ return n;
}
/* --------------------------------
- * pq_putstr - send a null terminated string to connection
+ * pq_putstr - send a null terminated string to connection
* --------------------------------
*/
void
pq_putstr(char *s)
{
- if(pqPutString(s, Pfout))
- {
- sprintf(PQerrormsg,
- "FATAL: pq_putstr: fputs() failed: errno=%d\n", errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
+ if (pqPutString(s, Pfout))
+ {
+ sprintf(PQerrormsg,
+ "FATAL: pq_putstr: fputs() failed: errno=%d\n", errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
}
}
/* --------------------------------
- * pq_putnchar - send n characters to connection
+ * pq_putnchar - send n characters to connection
* --------------------------------
*/
void
pq_putnchar(char *s, int n)
+{
+ if (pqPutNBytes(s, n, Pfout))
{
- if(pqPutNBytes(s, n, Pfout))
- {
sprintf(PQerrormsg,
- "FATAL: pq_putnchar: fputc() failed: errno=%d\n",
- errno);
+ "FATAL: pq_putnchar: fputc() failed: errno=%d\n",
+ errno);
fputs(PQerrormsg, stderr);
pqdebug("%s", PQerrormsg);
- }
}
+}
/* --------------------------------
- * pq_putint - send an integer to connection
- * we chop an integer into bytes and send individual bytes
- * machines with different ENDIAN representations can still talk to each
- * other
+ * pq_putint - send an integer to connection
+ * we chop an integer into bytes and send individual bytes
+ * machines with different ENDIAN representations can still talk to each
+ * other
* --------------------------------
*/
void
pq_putint(int i, int b)
{
- int status;
-
- if(!Pfout) return;
-
- status = 1;
- switch(b)
- {
- case 1:
- status = (fputc(i, Pfout) == EOF);
- break;
- case 2:
- status = pqPutShort(i, Pfout);
- break;
- case 4:
- status = pqPutLong(i, Pfout);
- break;
- default:
- fprintf(stderr, "** Unsupported size %d\n", b);
- }
-
- if(status)
- {
+ int status;
+
+ if (!Pfout)
+ return;
+
+ status = 1;
+ switch (b)
+ {
+ case 1:
+ status = (fputc(i, Pfout) == EOF);
+ break;
+ case 2:
+ status = pqPutShort(i, Pfout);
+ break;
+ case 4:
+ status = pqPutLong(i, Pfout);
+ break;
+ default:
+ fprintf(stderr, "** Unsupported size %d\n", b);
+ }
+
+ if (status)
+ {
sprintf(PQerrormsg,
- "FATAL: pq_putint failed: errno=%d\n", errno);
+ "FATAL: pq_putint failed: errno=%d\n", errno);
fputs(PQerrormsg, stderr);
pqdebug("%s", PQerrormsg);
- }
+ }
}
/* ---
- * pq_sendoob - send a string over the out-of-band channel
- * pq_recvoob - receive a string over the oob channel
- * NB: Fortunately, the out-of-band channel doesn't conflict with
- * buffered I/O because it is separate from regular com. channel.
+ * pq_sendoob - send a string over the out-of-band channel
+ * pq_recvoob - receive a string over the oob channel
+ * NB: Fortunately, the out-of-band channel doesn't conflict with
+ * buffered I/O because it is separate from regular com. channel.
* ---
*/
int
pq_sendoob(char *msg, int len)
{
- int fd = fileno(Pfout);
-
- return(send(fd,msg,len,MSG_OOB));
+ int fd = fileno(Pfout);
+
+ return (send(fd, msg, len, MSG_OOB));
}
int
pq_recvoob(char *msgPtr, int *lenPtr)
{
- int fd = fileno(Pfout);
- int len = 0;
-
- len = recv(fd,msgPtr+len,*lenPtr,MSG_OOB);
- *lenPtr = len;
- return(len);
+ int fd = fileno(Pfout);
+ int len = 0;
+
+ len = recv(fd, msgPtr + len, *lenPtr, MSG_OOB);
+ *lenPtr = len;
+ return (len);
}
/* --------------------------------
- * pq_getinaddr - initialize address from host and port number
+ * pq_getinaddr - initialize address from host and port number
* --------------------------------
*/
int
-pq_getinaddr(struct sockaddr_in *sin,
- char *host,
- int port)
+pq_getinaddr(struct sockaddr_in * sin,
+ char *host,
+ int port)
{
- struct hostent *hs;
-
- memset((char *) sin, 0, sizeof(*sin));
-
- if (host) {
- if (*host >= '0' && *host <= '9')
- sin->sin_addr.s_addr = inet_addr(host);
- else {
- if (!(hs = gethostbyname(host))) {
- perror(host);
- return(1);
- }
- if (hs->h_addrtype != AF_INET) {
- sprintf(PQerrormsg,
- "FATAL: pq_getinaddr: %s not on Internet\n",
- host);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(1);
- }
- memmove((char *) &sin->sin_addr,
- hs->h_addr,
- hs->h_length);
+ struct hostent *hs;
+
+ memset((char *) sin, 0, sizeof(*sin));
+
+ if (host)
+ {
+ if (*host >= '0' && *host <= '9')
+ sin->sin_addr.s_addr = inet_addr(host);
+ else
+ {
+ if (!(hs = gethostbyname(host)))
+ {
+ perror(host);
+ return (1);
+ }
+ if (hs->h_addrtype != AF_INET)
+ {
+ sprintf(PQerrormsg,
+ "FATAL: pq_getinaddr: %s not on Internet\n",
+ host);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (1);
+ }
+ memmove((char *) &sin->sin_addr,
+ hs->h_addr,
+ hs->h_length);
+ }
}
- }
- sin->sin_family = AF_INET;
- sin->sin_port = htons(port);
- return(0);
+ sin->sin_family = AF_INET;
+ sin->sin_port = htons(port);
+ return (0);
}
/* --------------------------------
- * pq_getinserv - initialize address from host and servive name
+ * pq_getinserv - initialize address from host and servive name
* --------------------------------
*/
int
-pq_getinserv(struct sockaddr_in *sin, char *host, char *serv)
+pq_getinserv(struct sockaddr_in * sin, char *host, char *serv)
{
- struct servent *ss;
-
- if (*serv >= '0' && *serv <= '9')
- return(pq_getinaddr(sin, host, atoi(serv)));
- if (!(ss = getservbyname(serv, NULL))) {
- sprintf(PQerrormsg,
- "FATAL: pq_getinserv: unknown service: %s\n",
- serv);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(1);
- }
- return(pq_getinaddr(sin, host, ntohs(ss->s_port)));
+ struct servent *ss;
+
+ if (*serv >= '0' && *serv <= '9')
+ return (pq_getinaddr(sin, host, atoi(serv)));
+ if (!(ss = getservbyname(serv, NULL)))
+ {
+ sprintf(PQerrormsg,
+ "FATAL: pq_getinserv: unknown service: %s\n",
+ serv);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (1);
+ }
+ return (pq_getinaddr(sin, host, ntohs(ss->s_port)));
}
/*
@@ -488,279 +508,297 @@ pq_getinserv(struct sockaddr_in *sin, char *host, char *serv)
* This is used for receiving async. notification from the backend.
*/
void
-pq_regoob(void (*fptr)())
+pq_regoob(void (*fptr) ())
{
- int fd = fileno(Pfout);
+ int fd = fileno(Pfout);
+
#if defined(hpux)
- ioctl(fd, FIOSSAIOOWN, getpid());
+ ioctl(fd, FIOSSAIOOWN, getpid());
#elif defined(sco)
- ioctl(fd, SIOCSPGRP, getpid());
+ ioctl(fd, SIOCSPGRP, getpid());
#else
- fcntl(fd, F_SETOWN, getpid());
-#endif /* hpux */
- pqsignal(SIGURG,fptr);
+ fcntl(fd, F_SETOWN, getpid());
+#endif /* hpux */
+ pqsignal(SIGURG, fptr);
}
void
pq_unregoob()
{
- pqsignal(SIGURG,SIG_DFL);
+ pqsignal(SIGURG, SIG_DFL);
}
void
pq_async_notify()
{
- char msg[20];
- /* int len = sizeof(msg);*/
- int len = 20;
-
- if (pq_recvoob(msg,&len) >= 0) {
- /* debugging */
- printf("received notification: %s\n",msg);
- PQAsyncNotifyWaiting = 1;
- /* PQappendNotify(msg+1);*/
- } else {
- extern int errno;
- printf("SIGURG but no data: len = %d, err=%d\n",len,errno);
- }
+ char msg[20];
+
+ /* int len = sizeof(msg); */
+ int len = 20;
+
+ if (pq_recvoob(msg, &len) >= 0)
+ {
+ /* debugging */
+ printf("received notification: %s\n", msg);
+ PQAsyncNotifyWaiting = 1;
+ /* PQappendNotify(msg+1); */
+ }
+ else
+ {
+ extern int errno;
+
+ printf("SIGURG but no data: len = %d, err=%d\n", len, errno);
+ }
}
/*
* Streams -- wrapper around Unix socket system calls
*
*
- * Stream functions are used for vanilla TCP connection protocol.
+ * Stream functions are used for vanilla TCP connection protocol.
*/
/*
* StreamServerPort -- open a sock stream "listening" port.
*
* This initializes the Postmaster's connection
- * accepting port.
+ * accepting port.
*
* ASSUME: that this doesn't need to be non-blocking because
- * the Postmaster uses select() to tell when the socket
- * is ready.
+ * the Postmaster uses select() to tell when the socket
+ * is ready.
*
* RETURNS: STATUS_OK or STATUS_ERROR
*/
int
StreamServerPort(char *hostName, short portName, int *fdP)
{
- struct sockaddr_in sin;
- int fd;
- int one = 1;
-
-
- if (! hostName)
- hostName = "localhost";
-
- memset((char *)&sin, 0, sizeof sin);
-
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- sprintf(PQerrormsg,
- "FATAL: StreamServerPort: socket() failed: errno=%d\n",
- errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
-
- if((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one,
- sizeof(one))) == -1) {
- sprintf(PQerrormsg,
- "FATAL: StreamServerPort: setsockopt (SO_REUSEADDR) failed: errno=%d\n",
- errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
-
- sin.sin_family = AF_INET;
- sin.sin_port = htons(portName);
-
- if (bind(fd, (struct sockaddr *)&sin, sizeof sin) < 0) {
- sprintf(PQerrormsg,
- "FATAL: StreamServerPort: bind() failed: errno=%d\n",
- errno);
- pqdebug("%s", PQerrormsg);
- strcat(PQerrormsg, "\tIs another postmaster already running on that port?\n");
- strcat(PQerrormsg, "\tIf not, wait a few seconds and retry.\n");
- fputs(PQerrormsg, stderr);
- return(STATUS_ERROR);
- }
-
- listen(fd, SOMAXCONN);
-
- /* MS: I took this code from Dillon's version. It makes the
- * listening port non-blocking. That is not necessary (and
- * may tickle kernel bugs).
-
- fcntl(fd, F_SETFD, 1);
- fcntl(fd, F_SETFL, FNDELAY);
- */
-
- *fdP = fd;
- return(STATUS_OK);
+ struct sockaddr_in sin;
+ int fd;
+ int one = 1;
+
+
+ if (!hostName)
+ hostName = "localhost";
+
+ memset((char *) &sin, 0, sizeof sin);
+
+ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ sprintf(PQerrormsg,
+ "FATAL: StreamServerPort: socket() failed: errno=%d\n",
+ errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+
+ if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
+ sizeof(one))) == -1)
+ {
+ sprintf(PQerrormsg,
+ "FATAL: StreamServerPort: setsockopt (SO_REUSEADDR) failed: errno=%d\n",
+ errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(portName);
+
+ if (bind(fd, (struct sockaddr *) & sin, sizeof sin) < 0)
+ {
+ sprintf(PQerrormsg,
+ "FATAL: StreamServerPort: bind() failed: errno=%d\n",
+ errno);
+ pqdebug("%s", PQerrormsg);
+ strcat(PQerrormsg, "\tIs another postmaster already running on that port?\n");
+ strcat(PQerrormsg, "\tIf not, wait a few seconds and retry.\n");
+ fputs(PQerrormsg, stderr);
+ return (STATUS_ERROR);
+ }
+
+ listen(fd, SOMAXCONN);
+
+ /*
+ * MS: I took this code from Dillon's version. It makes the listening
+ * port non-blocking. That is not necessary (and may tickle kernel
+ * bugs).
+ *
+ * fcntl(fd, F_SETFD, 1); fcntl(fd, F_SETFL, FNDELAY);
+ */
+
+ *fdP = fd;
+ return (STATUS_OK);
}
/*
* StreamConnection -- create a new connection with client using
- * server port.
+ * server port.
*
* This one should be non-blocking.
- *
+ *
* RETURNS: STATUS_OK or STATUS_ERROR
*/
int
-StreamConnection(int server_fd, Port *port)
+StreamConnection(int server_fd, Port * port)
{
- int addrlen;
-
- /* accept connection (and fill in the client (remote) address) */
- addrlen = sizeof(struct sockaddr_in);
- if ((port->sock = accept(server_fd,
- (struct sockaddr *) &port->raddr,
- &addrlen)) < 0) {
- elog(WARN, "postmaster: StreamConnection: accept: %m");
- return(STATUS_ERROR);
- }
-
- /* fill in the server (local) address */
- addrlen = sizeof(struct sockaddr_in);
- if (getsockname(port->sock, (struct sockaddr *) &port->laddr,
- &addrlen) < 0) {
- elog(WARN, "postmaster: StreamConnection: getsockname: %m");
- return(STATUS_ERROR);
- }
- {
- struct protoent *pe;
- int on=1;
-
- pe = getprotobyname ("TCP");
- if ( pe == NULL )
- {
- elog(WARN, "postmaster: getprotobyname failed");
- return(STATUS_ERROR);
+ int addrlen;
+
+ /* accept connection (and fill in the client (remote) address) */
+ addrlen = sizeof(struct sockaddr_in);
+ if ((port->sock = accept(server_fd,
+ (struct sockaddr *) & port->raddr,
+ &addrlen)) < 0)
+ {
+ elog(WARN, "postmaster: StreamConnection: accept: %m");
+ return (STATUS_ERROR);
+ }
+
+ /* fill in the server (local) address */
+ addrlen = sizeof(struct sockaddr_in);
+ if (getsockname(port->sock, (struct sockaddr *) & port->laddr,
+ &addrlen) < 0)
+ {
+ elog(WARN, "postmaster: StreamConnection: getsockname: %m");
+ return (STATUS_ERROR);
}
- if ( setsockopt (port->sock, pe->p_proto, TCP_NODELAY,
- &on, sizeof (on)) < 0 )
- {
- elog(WARN, "postmaster: setsockopt failed");
- return(STATUS_ERROR);
+ {
+ struct protoent *pe;
+ int on = 1;
+
+ pe = getprotobyname("TCP");
+ if (pe == NULL)
+ {
+ elog(WARN, "postmaster: getprotobyname failed");
+ return (STATUS_ERROR);
+ }
+ if (setsockopt(port->sock, pe->p_proto, TCP_NODELAY,
+ &on, sizeof(on)) < 0)
+ {
+ elog(WARN, "postmaster: setsockopt failed");
+ return (STATUS_ERROR);
+ }
}
- }
-
- port->mask = 1 << port->sock;
-
- /* reset to non-blocking */
- fcntl(port->sock, F_SETFL, 1);
-
- return(STATUS_OK);
+
+ port->mask = 1 << port->sock;
+
+ /* reset to non-blocking */
+ fcntl(port->sock, F_SETFL, 1);
+
+ return (STATUS_OK);
}
-/*
+/*
* StreamClose -- close a client/backend connection
*/
void
StreamClose(int sock)
{
- close(sock);
+ close(sock);
}
/* ---------------------------
- * StreamOpen -- From client, initiate a connection with the
- * server (Postmaster).
+ * StreamOpen -- From client, initiate a connection with the
+ * server (Postmaster).
*
* RETURNS: STATUS_OK or STATUS_ERROR
*
* NOTE: connection is NOT established just because this
- * routine exits. Local state is ok, but we haven't
- * spoken to the postmaster yet.
+ * routine exits. Local state is ok, but we haven't
+ * spoken to the postmaster yet.
* ---------------------------
*/
int
-StreamOpen(char *hostName, short portName, Port *port)
+StreamOpen(char *hostName, short portName, Port * port)
{
- struct hostent *hp;
- int laddrlen = sizeof(struct sockaddr_in);
- extern int errno;
-
- if (!hostName)
- hostName = "localhost";
-
- /* set up the server (remote) address */
- if (!(hp = gethostbyname(hostName)) || hp->h_addrtype != AF_INET) {
- sprintf(PQerrormsg,
- "FATAL: StreamOpen: unknown hostname: %s\n",
- hostName);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- memset((char *) &port->raddr, 0, sizeof(port->raddr));
- memmove((char *) &(port->raddr.sin_addr),
- (char *) hp->h_addr,
- hp->h_length);
- port->raddr.sin_family = AF_INET;
- port->raddr.sin_port = htons(portName);
-
- /* connect to the server */
- if ((port->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- sprintf(PQerrormsg,
- "FATAL: StreamOpen: socket() failed: errno=%d\n",
- errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
- if (connect(port->sock, (struct sockaddr *)&port->raddr,
- sizeof(port->raddr)) < 0) {
- sprintf(PQerrormsg,
- "FATAL: StreamOpen: connect() failed: errno=%d\n",
- errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
-
- /* fill in the client address */
- if (getsockname(port->sock, (struct sockaddr *) &port->laddr,
- &laddrlen) < 0) {
- sprintf(PQerrormsg,
- "FATAL: StreamOpen: getsockname() failed: errno=%d\n",
- errno);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- return(STATUS_ERROR);
- }
-
- return(STATUS_OK);
+ struct hostent *hp;
+ int laddrlen = sizeof(struct sockaddr_in);
+ extern int errno;
+
+ if (!hostName)
+ hostName = "localhost";
+
+ /* set up the server (remote) address */
+ if (!(hp = gethostbyname(hostName)) || hp->h_addrtype != AF_INET)
+ {
+ sprintf(PQerrormsg,
+ "FATAL: StreamOpen: unknown hostname: %s\n",
+ hostName);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ memset((char *) &port->raddr, 0, sizeof(port->raddr));
+ memmove((char *) &(port->raddr.sin_addr),
+ (char *) hp->h_addr,
+ hp->h_length);
+ port->raddr.sin_family = AF_INET;
+ port->raddr.sin_port = htons(portName);
+
+ /* connect to the server */
+ if ((port->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ sprintf(PQerrormsg,
+ "FATAL: StreamOpen: socket() failed: errno=%d\n",
+ errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+ if (connect(port->sock, (struct sockaddr *) & port->raddr,
+ sizeof(port->raddr)) < 0)
+ {
+ sprintf(PQerrormsg,
+ "FATAL: StreamOpen: connect() failed: errno=%d\n",
+ errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+
+ /* fill in the client address */
+ if (getsockname(port->sock, (struct sockaddr *) & port->laddr,
+ &laddrlen) < 0)
+ {
+ sprintf(PQerrormsg,
+ "FATAL: StreamOpen: getsockname() failed: errno=%d\n",
+ errno);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return (STATUS_ERROR);
+ }
+
+ return (STATUS_OK);
}
-static char *authentication_type_name[] = {
- 0, 0, 0, 0, 0, 0, 0,
- "the default authentication type",
- 0, 0,
- "Kerberos v4",
- "Kerberos v5",
- "host-based authentication",
- "unauthenication",
- "plaintext password authentication"
+static char *authentication_type_name[] = {
+ 0, 0, 0, 0, 0, 0, 0,
+ "the default authentication type",
+ 0, 0,
+ "Kerberos v4",
+ "Kerberos v5",
+ "host-based authentication",
+ "unauthenication",
+ "plaintext password authentication"
};
-char *name_of_authentication_type(int type)
+char *
+name_of_authentication_type(int type)
{
- char *result = 0;
+ char *result = 0;
- if(type >= 1 && type <= LAST_AUTHENTICATION_TYPE) {
- result = authentication_type_name[type];
- }
+ if (type >= 1 && type <= LAST_AUTHENTICATION_TYPE)
+ {
+ result = authentication_type_name[type];
+ }
- if(result == 0) {
- result = "<unknown authentication type>";
- }
+ if (result == 0)
+ {
+ result = "<unknown authentication type>";
+ }
- return result;
+ return result;
}
diff --git a/src/backend/libpq/pqcomprim.c b/src/backend/libpq/pqcomprim.c
index 3501b63c7b6..8675205d784 100644
--- a/src/backend/libpq/pqcomprim.c
+++ b/src/backend/libpq/pqcomprim.c
@@ -4,171 +4,185 @@
#include "postgres.h"
#include "libpq/pqcomm.h"
-#ifdef HAVE_ENDIAN_H
-# include <endian.h>
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
#endif
/* --------------------------------------------------------------------- */
/* These definitions for ntoh/hton are the other way around from the
- * default system definitions, so we roll our own here.
+ * default system definitions, so we roll our own here.
*/
-#ifndef BYTE_ORDER
+#ifndef BYTE_ORDER
#error BYTE_ORDER must be defined as LITTLE_ENDIAN, BIG_ENDIAN or PDP_ENDIAN
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
-# define ntoh_s(n) n
-# define ntoh_l(n) n
-# define hton_s(n) n
-# define hton_l(n) n
-#else /* BYTE_ORDER != LITTLE_ENDIAN */
-# if BYTE_ORDER == BIG_ENDIAN
-# define ntoh_s(n) (u_short)(((u_char *)&n)[1] << 8 \
- | ((u_char *)&n)[0])
-# define ntoh_l(n) (u_long) (((u_char *)&n)[3] << 24 \
- | ((u_char *)&n)[2] << 16 \
- | ((u_char *)&n)[1] << 8 \
- | ((u_char *)&n)[0])
-# define hton_s(n) (ntoh_s(n))
-# define hton_l(n) (ntoh_l(n))
-# else /* BYTE_ORDER != BIG_ENDIAN */
-# if BYTE_ORDER == PDP_ENDIAN
-# error PDP_ENDIAN macros not written yet
-# else /* BYTE_ORDER != anything known */
-# error BYTE_ORDER not defined as anything understood
-# endif /* BYTE_ORDER == PDP_ENDIAN */
-# endif /* BYTE_ORDER == BIG_ENDIAN */
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+#define ntoh_s(n) n
+#define ntoh_l(n) n
+#define hton_s(n) n
+#define hton_l(n) n
+#else /* BYTE_ORDER != LITTLE_ENDIAN */
+#if BYTE_ORDER == BIG_ENDIAN
+#define ntoh_s(n) (u_short)(((u_char *)&n)[1] << 8 \
+ | ((u_char *)&n)[0])
+#define ntoh_l(n) (u_long) (((u_char *)&n)[3] << 24 \
+ | ((u_char *)&n)[2] << 16 \
+ | ((u_char *)&n)[1] << 8 \
+ | ((u_char *)&n)[0])
+#define hton_s(n) (ntoh_s(n))
+#define hton_l(n) (ntoh_l(n))
+#else
+/* BYTE_ORDER != BIG_ENDIAN */
+#if BYTE_ORDER == PDP_ENDIAN
+#error PDP_ENDIAN macros not written yet
+#else
+/* BYTE_ORDER != anything known */
+#error BYTE_ORDER not defined as anything understood
+#endif /* BYTE_ORDER == PDP_ENDIAN */
+#endif /* BYTE_ORDER == BIG_ENDIAN */
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
/* --------------------------------------------------------------------- */
-int pqPutShort(int integer, FILE *f)
- {
- int retval = 0;
- u_short n,s;
-
- s = integer;
- n = hton_s(s);
- if(fwrite(&n, sizeof(u_short), 1, f) != 1)
- retval = EOF;
-
- return retval;
- }
+int
+pqPutShort(int integer, FILE * f)
+{
+ int retval = 0;
+ u_short n,
+ s;
+
+ s = integer;
+ n = hton_s(s);
+ if (fwrite(&n, sizeof(u_short), 1, f) != 1)
+ retval = EOF;
+
+ return retval;
+}
/* --------------------------------------------------------------------- */
-int pqPutLong(int integer, FILE *f)
- {
- int retval = 0;
- u_long n;
-
- n = hton_l(integer);
- if(fwrite(&n, sizeof(u_long), 1, f) != 1)
- retval = EOF;
-
- return retval;
- }
-
+int
+pqPutLong(int integer, FILE * f)
+{
+ int retval = 0;
+ u_long n;
+
+ n = hton_l(integer);
+ if (fwrite(&n, sizeof(u_long), 1, f) != 1)
+ retval = EOF;
+
+ return retval;
+}
+
/* --------------------------------------------------------------------- */
-int pqGetShort(int *result, FILE *f)
- {
- int retval = 0;
- u_short n;
-
- if(fread(&n, sizeof(u_short), 1, f) != 1)
- retval = EOF;
-
- *result = ntoh_s(n);
- return retval;
- }
+int
+pqGetShort(int *result, FILE * f)
+{
+ int retval = 0;
+ u_short n;
+
+ if (fread(&n, sizeof(u_short), 1, f) != 1)
+ retval = EOF;
+
+ *result = ntoh_s(n);
+ return retval;
+}
/* --------------------------------------------------------------------- */
-int pqGetLong(int *result, FILE *f)
- {
- int retval = 0;
- u_long n;
-
- if(fread(&n, sizeof(u_long), 1, f) != 1)
- retval = EOF;
-
- *result = ntoh_l(n);
- return retval;
- }
+int
+pqGetLong(int *result, FILE * f)
+{
+ int retval = 0;
+ u_long n;
+
+ if (fread(&n, sizeof(u_long), 1, f) != 1)
+ retval = EOF;
+
+ *result = ntoh_l(n);
+ return retval;
+}
/* --------------------------------------------------------------------- */
/* pqGetNBytes: Read a chunk of exactly len bytes in buffer s.
- Return 0 if ok.
+ Return 0 if ok.
*/
-int pqGetNBytes(char *s, size_t len, FILE *f)
- {
- int cnt;
+int
+pqGetNBytes(char *s, size_t len, FILE * f)
+{
+ int cnt;
if (f == NULL)
return EOF;
-
+
cnt = fread(s, 1, len, f);
s[cnt] = '\0';
- /* mjl: actually needs up to len+1 bytes, is this okay? XXX */
+ /* mjl: actually needs up to len+1 bytes, is this okay? XXX */
return (cnt == len) ? 0 : EOF;
- }
+}
/* --------------------------------------------------------------------- */
-int pqPutNBytes(const char *s, size_t len, FILE *f)
- {
+int
+pqPutNBytes(const char *s, size_t len, FILE * f)
+{
if (f == NULL)
return 0;
- if(fwrite(s, 1, len, f) != len)
- return EOF;
+ if (fwrite(s, 1, len, f) != len)
+ return EOF;
return 0;
- }
-
+}
+
/* --------------------------------------------------------------------- */
-int pqGetString(char *s, size_t len, FILE *f)
- {
- int c;
+int
+pqGetString(char *s, size_t len, FILE * f)
+{
+ int c;
if (f == NULL)
- return EOF;
-
+ return EOF;
+
while (len-- && (c = getc(f)) != EOF && c)
*s++ = c;
*s = '\0';
- /* mjl: actually needs up to len+1 bytes, is this okay? XXX */
+ /* mjl: actually needs up to len+1 bytes, is this okay? XXX */
return 0;
- }
+}
/* --------------------------------------------------------------------- */
-int pqPutString(const char *s, FILE *f)
- {
+int
+pqPutString(const char *s, FILE * f)
+{
if (f == NULL)
return 0;
-
+
if (fputs(s, f) == EOF)
return EOF;
- fputc('\0', f); /* important to send an ending \0 since backend expects it */
+ fputc('\0', f); /* important to send an ending \0 since
+ * backend expects it */
fflush(f);
return 0;
- }
+}
/* --------------------------------------------------------------------- */
-int pqGetByte(FILE *f)
- {
+int
+pqGetByte(FILE * f)
+{
return getc(f);
- }
-
+}
+
/* --------------------------------------------------------------------- */
-int pqPutByte(int c, FILE *f)
- {
- if(!f) return 0;
-
+int
+pqPutByte(int c, FILE * f)
+{
+ if (!f)
+ return 0;
+
return (putc(c, f) == c) ? 0 : EOF;
- }
-
-/* --------------------------------------------------------------------- */
+}
+/* --------------------------------------------------------------------- */
diff --git a/src/backend/libpq/pqpacket.c b/src/backend/libpq/pqpacket.c
index 6f67ddc5f5b..9f56556537f 100644
--- a/src/backend/libpq/pqpacket.c
+++ b/src/backend/libpq/pqpacket.c
@@ -1,39 +1,39 @@
/*-------------------------------------------------------------------------
*
* pqpacket.c--
- * routines for reading and writing data packets sent/received by
- * POSTGRES clients and servers
+ * routines for reading and writing data packets sent/received by
+ * POSTGRES clients and servers
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.5 1997/08/12 22:53:00 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.6 1997/09/07 04:42:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* NOTES
- * This is the module that understands the lowest-level part
- * of the communication protocol. All of the trickiness in
- * this module is for making sure that non-blocking I/O in
- * the Postmaster works correctly. Check the notes in PacketRecv
- * on non-blocking I/O.
+ * This is the module that understands the lowest-level part
+ * of the communication protocol. All of the trickiness in
+ * this module is for making sure that non-blocking I/O in
+ * the Postmaster works correctly. Check the notes in PacketRecv
+ * on non-blocking I/O.
*
* Data Structures:
- * Port has two important functions. (1) It records the
- * sock/addr used in communication. (2) It holds partially
- * read in messages. This is especially important when
- * we haven't seen enough to construct a complete packet
- * header.
+ * Port has two important functions. (1) It records the
+ * sock/addr used in communication. (2) It holds partially
+ * read in messages. This is especially important when
+ * we haven't seen enough to construct a complete packet
+ * header.
*
* PacketBuf -- None of the clients of this module should know
- * what goes into a packet hdr (although they know how big
- * it is). This routine is in charge of host to net order
- * conversion for headers. Data conversion is someone elses
- * responsibility.
+ * what goes into a packet hdr (although they know how big
+ * it is). This routine is in charge of host to net order
+ * conversion for headers. Data conversion is someone elses
+ * responsibility.
*
* IMPORTANT: these routines are called by backends, clients, and
- * the Postmaster.
+ * the Postmaster.
*
*/
#include <stdio.h>
@@ -57,134 +57,156 @@
*
*/
int
-PacketReceive(Port *port, /* receive port */
- PacketBuf *buf, /* MAX_PACKET_SIZE-worth of buffer space */
- bool nonBlocking) /* NON_BLOCKING or BLOCKING i/o */
+PacketReceive(Port * port, /* receive port */
+ PacketBuf * buf, /* MAX_PACKET_SIZE-worth of buffer space */
+ bool nonBlocking) /* NON_BLOCKING or BLOCKING i/o */
{
- PacketLen max_size = sizeof(PacketBuf);
- PacketLen cc; /* character count -- bytes recvd */
- PacketLen packetLen; /* remaining packet chars to read */
- Addr tmp; /* curr recv buf pointer */
- int addrLen = sizeof(struct sockaddr_in);
- int hdrLen;
- int flag;
- int decr;
-
- hdrLen = sizeof(buf->len);
-
- if (nonBlocking == NON_BLOCKING) {
- flag = MSG_PEEK;
- decr = 0;
- } else {
- flag = 0;
- decr = hdrLen;
- }
- /*
- * Assume port->nBytes is zero unless we were interrupted during
- * non-blocking I/O. This first recvfrom() is to get the hdr
- * information so we know how many bytes to read. Life would
- * be very complicated if we read too much data (buffering).
- */
- tmp = ((Addr)buf) + port->nBytes;
-
- if (port->nBytes >= hdrLen) {
- packetLen = ntohl(buf->len) - port->nBytes;
- }
- else {
- /* peeking into the incoming message */
- cc = recvfrom(port->sock, (char *)&(buf->len), hdrLen, flag,
- (struct sockaddr*) &(port->raddr), &addrLen);
- if (cc < hdrLen) {
- /* if cc is negative, the system call failed */
- if (cc < 0) {
- return(STATUS_ERROR);
- }
- /*
- * cc == 0 means the connection was broken at the
- * other end.
- */
- else if (! cc) {
- return(STATUS_INVALID);
-
- } else {
- /*
- * Worst case. We didn't even read in enough data to
- * get the header length.
- * since we are using a data stream,
- * this happens only if the client is mallicious.
- *
- * Don't save the number of bytes we've read so far.
- * Since we only peeked at the incoming message, the
- * kernel is going to keep it for us.
- */
- return(STATUS_NOT_DONE);
- }
- } else {
- /*
- * This is an attempt to shield the Postmaster
- * from mallicious attacks by placing tighter
- * restrictions on the reported packet length.
- *
- * Check for negative packet length
- */
- if ((buf->len) <= 0) {
- return(STATUS_INVALID);
- }
- /*
- * Check for oversize packet
- */
- if ((ntohl(buf->len)) > max_size) {
- return(STATUS_INVALID);
- }
- /*
- * great. got the header. now get the true length (including
- * header size).
- */
- packetLen = ntohl(buf->len);
- /*
- * if someone is sending us junk, close the connection
- */
- if (packetLen > max_size) {
- port->nBytes = packetLen;
- return(STATUS_BAD_PACKET);
- }
- packetLen -= decr;
- tmp += decr - port->nBytes;
+ PacketLen max_size = sizeof(PacketBuf);
+ PacketLen cc; /* character count -- bytes recvd */
+ PacketLen packetLen; /* remaining packet chars to read */
+ Addr tmp; /* curr recv buf pointer */
+ int addrLen = sizeof(struct sockaddr_in);
+ int hdrLen;
+ int flag;
+ int decr;
+
+ hdrLen = sizeof(buf->len);
+
+ if (nonBlocking == NON_BLOCKING)
+ {
+ flag = MSG_PEEK;
+ decr = 0;
+ }
+ else
+ {
+ flag = 0;
+ decr = hdrLen;
+ }
+
+ /*
+ * Assume port->nBytes is zero unless we were interrupted during
+ * non-blocking I/O. This first recvfrom() is to get the hdr
+ * information so we know how many bytes to read. Life would be very
+ * complicated if we read too much data (buffering).
+ */
+ tmp = ((Addr) buf) + port->nBytes;
+
+ if (port->nBytes >= hdrLen)
+ {
+ packetLen = ntohl(buf->len) - port->nBytes;
+ }
+ else
+ {
+ /* peeking into the incoming message */
+ cc = recvfrom(port->sock, (char *) &(buf->len), hdrLen, flag,
+ (struct sockaddr *) & (port->raddr), &addrLen);
+ if (cc < hdrLen)
+ {
+ /* if cc is negative, the system call failed */
+ if (cc < 0)
+ {
+ return (STATUS_ERROR);
+ }
+
+ /*
+ * cc == 0 means the connection was broken at the other end.
+ */
+ else if (!cc)
+ {
+ return (STATUS_INVALID);
+
+ }
+ else
+ {
+
+ /*
+ * Worst case. We didn't even read in enough data to get
+ * the header length. since we are using a data stream,
+ * this happens only if the client is mallicious.
+ *
+ * Don't save the number of bytes we've read so far. Since we
+ * only peeked at the incoming message, the kernel is
+ * going to keep it for us.
+ */
+ return (STATUS_NOT_DONE);
+ }
+ }
+ else
+ {
+
+ /*
+ * This is an attempt to shield the Postmaster from mallicious
+ * attacks by placing tighter restrictions on the reported
+ * packet length.
+ *
+ * Check for negative packet length
+ */
+ if ((buf->len) <= 0)
+ {
+ return (STATUS_INVALID);
+ }
+
+ /*
+ * Check for oversize packet
+ */
+ if ((ntohl(buf->len)) > max_size)
+ {
+ return (STATUS_INVALID);
+ }
+
+ /*
+ * great. got the header. now get the true length (including
+ * header size).
+ */
+ packetLen = ntohl(buf->len);
+
+ /*
+ * if someone is sending us junk, close the connection
+ */
+ if (packetLen > max_size)
+ {
+ port->nBytes = packetLen;
+ return (STATUS_BAD_PACKET);
+ }
+ packetLen -= decr;
+ tmp += decr - port->nBytes;
+ }
}
- }
-
- /*
- * Now that we know how big it is, read the packet. We read
- * the entire packet, since the last call was just a peek.
- */
- while (packetLen) {
- cc = recvfrom(port->sock, tmp, packetLen, 0,
- (struct sockaddr*) &(port->raddr), &addrLen);
- if (cc < 0)
- return(STATUS_ERROR);
- /*
- * cc == 0 means the connection was broken at the
- * other end.
+
+ /*
+ * Now that we know how big it is, read the packet. We read the
+ * entire packet, since the last call was just a peek.
*/
- else if (! cc)
- return(STATUS_INVALID);
-
+ while (packetLen)
+ {
+ cc = recvfrom(port->sock, tmp, packetLen, 0,
+ (struct sockaddr *) & (port->raddr), &addrLen);
+ if (cc < 0)
+ return (STATUS_ERROR);
+
+ /*
+ * cc == 0 means the connection was broken at the other end.
+ */
+ else if (!cc)
+ return (STATUS_INVALID);
+
/*
fprintf(stderr,"expected packet of %d bytes, got %d bytes\n",
- packetLen, cc);
+ packetLen, cc);
*/
- tmp += cc;
- packetLen -= cc;
-
- /* if non-blocking, we're done. */
- if (nonBlocking && packetLen) {
- port->nBytes += cc;
- return(STATUS_NOT_DONE);
+ tmp += cc;
+ packetLen -= cc;
+
+ /* if non-blocking, we're done. */
+ if (nonBlocking && packetLen)
+ {
+ port->nBytes += cc;
+ return (STATUS_NOT_DONE);
+ }
}
- }
-
- port->nBytes = 0;
- return(STATUS_OK);
+
+ port->nBytes = 0;
+ return (STATUS_OK);
}
/*
@@ -192,46 +214,47 @@ PacketReceive(Port *port, /* receive port */
*
* RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
* SIDE_EFFECTS: may block.
- * NOTES: Non-blocking writes would significantly complicate
- * buffer management. For now, we're not going to do it.
+ * NOTES: Non-blocking writes would significantly complicate
+ * buffer management. For now, we're not going to do it.
*
*/
int
-PacketSend(Port *port,
- PacketBuf *buf,
- PacketLen len,
- bool nonBlocking)
+PacketSend(Port * port,
+ PacketBuf * buf,
+ PacketLen len,
+ bool nonBlocking)
{
- PacketLen totalLen;
- int addrLen = sizeof(struct sockaddr_in);
-
- Assert(!nonBlocking);
- Assert(buf);
-
- totalLen = len;
-
- len = sendto(port->sock, (Addr) buf, totalLen, /* flags */ 0,
- (struct sockaddr *)&(port->raddr), addrLen);
-
- if (len < totalLen) {
- sprintf(PQerrormsg,
- "FATAL: PacketSend: couldn't send complete packet: errno=%d\n",
- errno);
- fputs(PQerrormsg, stderr);
- return(STATUS_ERROR);
- }
-
- return(STATUS_OK);
+ PacketLen totalLen;
+ int addrLen = sizeof(struct sockaddr_in);
+
+ Assert(!nonBlocking);
+ Assert(buf);
+
+ totalLen = len;
+
+ len = sendto(port->sock, (Addr) buf, totalLen, /* flags */ 0,
+ (struct sockaddr *) & (port->raddr), addrLen);
+
+ if (len < totalLen)
+ {
+ sprintf(PQerrormsg,
+ "FATAL: PacketSend: couldn't send complete packet: errno=%d\n",
+ errno);
+ fputs(PQerrormsg, stderr);
+ return (STATUS_ERROR);
+ }
+
+ return (STATUS_OK);
}
/*
* StartupInfo2PacketBuf -
- * convert the fields of the StartupInfo to a PacketBuf
+ * convert the fields of the StartupInfo to a PacketBuf
*
*/
/* moved to src/libpq/fe-connect.c */
/*
-PacketBuf*
+PacketBuf*
StartupInfo2PacketBuf(StartupInfo* s)
{
PacketBuf* res;
@@ -259,10 +282,10 @@ StartupInfo2PacketBuf(StartupInfo* s)
/*
* PacketBuf2StartupInfo -
- * convert the fields of the StartupInfo to a PacketBuf
+ * convert the fields of the StartupInfo to a PacketBuf
*
*/
-/* moved to postmaster.c
+/* moved to postmaster.c
StartupInfo*
PacketBuf2StartupInfo(PacketBuf* p)
{
diff --git a/src/backend/libpq/pqsignal.c b/src/backend/libpq/pqsignal.c
index 0c91f50df03..727a2a7207d 100644
--- a/src/backend/libpq/pqsignal.c
+++ b/src/backend/libpq/pqsignal.c
@@ -1,41 +1,41 @@
/*-------------------------------------------------------------------------
*
* pqsignal.c--
- * reliable BSD-style signal(2) routine stolen from RWW who stole it
- * from Stevens...
+ * reliable BSD-style signal(2) routine stolen from RWW who stole it
+ * from Stevens...
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/pqsignal.c,v 1.5 1996/12/26 22:07:08 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/pqsignal.c,v 1.6 1997/09/07 04:42:29 momjian Exp $
*
* NOTES
- * This shouldn't be in libpq, but the monitor and some other
- * things need it...
+ * This shouldn't be in libpq, but the monitor and some other
+ * things need it...
*
- * A NOTE ABOUT SIGNAL HANDLING ACROSS THE VARIOUS PLATFORMS.
+ * A NOTE ABOUT SIGNAL HANDLING ACROSS THE VARIOUS PLATFORMS.
*
- * config.h defines the macro USE_POSIX_SIGNALS for some platforms and
- * not for others. This file and pqsignal.h use that macro to decide
- * how to handle signalling.
+ * config.h defines the macro USE_POSIX_SIGNALS for some platforms and
+ * not for others. This file and pqsignal.h use that macro to decide
+ * how to handle signalling.
*
- * signal(2) handling - this is here because it affects some of
- * the frontend commands as well as the backend server.
- *
- * Ultrix and SunOS provide BSD signal(2) semantics by default.
- *
- * SVID2 and POSIX signal(2) semantics differ from BSD signal(2)
- * semantics. We can use the POSIX sigaction(2) on systems that
- * allow us to request restartable signals (SA_RESTART).
- *
- * Some systems don't allow restartable signals at all unless we
- * link to a special BSD library.
- *
- * We devoutly hope that there aren't any systems that provide
- * neither POSIX signals nor BSD signals. The alternative
- * is to do signal-handler reinstallation, which doesn't work well
- * at all.
+ * signal(2) handling - this is here because it affects some of
+ * the frontend commands as well as the backend server.
+ *
+ * Ultrix and SunOS provide BSD signal(2) semantics by default.
+ *
+ * SVID2 and POSIX signal(2) semantics differ from BSD signal(2)
+ * semantics. We can use the POSIX sigaction(2) on systems that
+ * allow us to request restartable signals (SA_RESTART).
+ *
+ * Some systems don't allow restartable signals at all unless we
+ * link to a special BSD library.
+ *
+ * We devoutly hope that there aren't any systems that provide
+ * neither POSIX signals nor BSD signals. The alternative
+ * is to do signal-handler reinstallation, which doesn't work well
+ * at all.
* ------------------------------------------------------------------------*/
#include <postgres.h>
@@ -47,18 +47,20 @@ pqsigfunc
pqsignal(int signo, pqsigfunc func)
{
#if !defined(USE_POSIX_SIGNALS)
- return signal(signo, func);
+ return signal(signo, func);
#else
- struct sigaction act, oact;
-
- act.sa_handler = func;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- if (signo != SIGALRM) {
- act.sa_flags |= SA_RESTART;
- }
- if (sigaction(signo, &act, &oact) < 0)
- return(SIG_ERR);
- return(oact.sa_handler);
-#endif /* !USE_POSIX_SIGNALS */
+ struct sigaction act,
+ oact;
+
+ act.sa_handler = func;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ if (signo != SIGALRM)
+ {
+ act.sa_flags |= SA_RESTART;
+ }
+ if (sigaction(signo, &act, &oact) < 0)
+ return (SIG_ERR);
+ return (oact.sa_handler);
+#endif /* !USE_POSIX_SIGNALS */
}
diff --git a/src/backend/libpq/util.c b/src/backend/libpq/util.c
index e8ca2e4ccc5..f4efec13f3a 100644
--- a/src/backend/libpq/util.c
+++ b/src/backend/libpq/util.c
@@ -1,100 +1,100 @@
/*-------------------------------------------------------------------------
*
* util.c--
- * general routines for libpq backend
+ * general routines for libpq backend
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/util.c,v 1.3 1996/11/06 08:48:33 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/util.c,v 1.4 1997/09/07 04:42:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * UTILITY ROUTINES
- * pqdebug - send a string to the debugging output port
- * pqdebug2 - send two strings to stdout
- * PQtrace - turn on pqdebug() tracing
- * PQuntrace - turn off pqdebug() tracing
+ * UTILITY ROUTINES
+ * pqdebug - send a string to the debugging output port
+ * pqdebug2 - send two strings to stdout
+ * PQtrace - turn on pqdebug() tracing
+ * PQuntrace - turn off pqdebug() tracing
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include <postgres.h>
#include <lib/dllist.h>
-#include <libpq/libpq.h> /* where the declarations go */
+#include <libpq/libpq.h> /* where the declarations go */
#include <utils/exc.h>
/* ----------------
- * exceptions
+ * exceptions
* ----------------
*/
-Exception MemoryError = {"Memory Allocation Error"};
-Exception PortalError = {"Invalid arguments to portal functions"};
-Exception PostquelError = {"Sql Error"};
-Exception ProtocolError = {"Protocol Error"};
-char PQerrormsg[ERROR_MSG_LENGTH];
+Exception MemoryError = {"Memory Allocation Error"};
+Exception PortalError = {"Invalid arguments to portal functions"};
+Exception PostquelError = {"Sql Error"};
+Exception ProtocolError = {"Protocol Error"};
+char PQerrormsg[ERROR_MSG_LENGTH];
-int PQtracep = 0; /* 1 to print out debugging messages */
-FILE *debug_port = (FILE *) NULL;
+int PQtracep = 0; /* 1 to print out debugging messages */
+FILE *debug_port = (FILE *) NULL;
/* ----------------------------------------------------------------
- * PQ utility routines
+ * PQ utility routines
* ----------------------------------------------------------------
*/
void
pqdebug(char *target, char *msg)
{
- if (!target)
- return;
-
- if (PQtracep) {
- /*
- * if nothing else was suggested default to stdout
- */
- if (!debug_port)
- debug_port = stdout;
- fprintf(debug_port, target, msg);
- fprintf(debug_port, "\n");
- }
+ if (!target)
+ return;
+
+ if (PQtracep)
+ {
+
+ /*
+ * if nothing else was suggested default to stdout
+ */
+ if (!debug_port)
+ debug_port = stdout;
+ fprintf(debug_port, target, msg);
+ fprintf(debug_port, "\n");
+ }
}
void
pqdebug2(char *target, char *msg1, char *msg2)
{
- if (!target)
- return;
-
- if (PQtracep) {
- /*
- * if nothing else was suggested default to stdout
- */
- if (!debug_port)
- debug_port = stdout;
- fprintf(debug_port, target, msg1, msg2);
- fprintf(debug_port, "\n");
- }
+ if (!target)
+ return;
+
+ if (PQtracep)
+ {
+
+ /*
+ * if nothing else was suggested default to stdout
+ */
+ if (!debug_port)
+ debug_port = stdout;
+ fprintf(debug_port, target, msg1, msg2);
+ fprintf(debug_port, "\n");
+ }
}
/* --------------------------------
- * PQtrace() / PQuntrace()
+ * PQtrace() / PQuntrace()
* --------------------------------
*/
void
PQtrace()
{
- PQtracep = 1;
+ PQtracep = 1;
}
void
PQuntrace()
{
- PQtracep = 0;
+ PQtracep = 0;
}
-
-
-
-
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index c3bb0793394..b70be2a08c4 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* main.c--
- * Stub main() routine for the postgres backend.
+ * Stub main() routine for the postgres backend.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/main/main.c,v 1.7 1997/04/24 20:30:09 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/main/main.c,v 1.8 1997/09/07 04:42:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,11 +16,11 @@
#include <unistd.h>
#include "postgres.h"
-#ifdef USE_LOCALE
-# include <locale.h>
+#ifdef USE_LOCALE
+#include <locale.h>
#endif
#include "miscadmin.h"
-#include "bootstrap/bootstrap.h" /* for BootstrapMain() */
+#include "bootstrap/bootstrap.h"/* for BootstrapMain() */
#include "tcop/tcopprot.h" /* for PostgresMain() */
#include "port-protos.h" /* for init_address_fixup() */
@@ -34,36 +34,45 @@ echo \"postmaster -B 256 >/var/log/pglog 2>&1 &\" | su - postgres\n\n"
int
main(int argc, char *argv[])
{
- int len;
+ int len;
+
#ifdef USE_LOCALE
- setlocale(LC_CTYPE,""); /* take locale information from an environment */
- setlocale(LC_COLLATE,"");
- setlocale(LC_MONETARY,"");
+ setlocale(LC_CTYPE, ""); /* take locale information from an
+ * environment */
+ setlocale(LC_COLLATE, "");
+ setlocale(LC_MONETARY, "");
#endif
#if defined(NOFIXADE) || defined(NOPRINTADE)
- /*
- * Must be first so that the bootstrap code calls it, too.
- * (Only needed on some RISC architectures.)
- */
- init_address_fixup();
-#endif /* NOFIXADE || NOPRINTADE */
-
- /* use one executable for both postgres and postmaster,
- invoke one or the other depending on the name of the executable */
- len = strlen(argv[0]);
- if (!geteuid()) {
- fprintf(stderr, "%s", NOROOTEXEC);
- exit(1);
- }
+ /*
+ * Must be first so that the bootstrap code calls it, too. (Only
+ * needed on some RISC architectures.)
+ */
+ init_address_fixup();
+#endif /* NOFIXADE || NOPRINTADE */
+
+ /*
+ * use one executable for both postgres and postmaster, invoke one or
+ * the other depending on the name of the executable
+ */
+ len = strlen(argv[0]);
+
+ if (!geteuid())
+ {
+ fprintf(stderr, "%s", NOROOTEXEC);
+ exit(1);
+ }
- if(len >= 10 && ! strcmp(argv[0] + len - 10, "postmaster"))
- exit(PostmasterMain(argc, argv));
+ if (len >= 10 && !strcmp(argv[0] + len - 10, "postmaster"))
+ exit(PostmasterMain(argc, argv));
- /* if the first argument is "-boot", then invoke the backend in
- bootstrap mode */
- if (argc > 1 && strcmp(argv[1], "-boot") == 0)
- exit(BootstrapMain(argc-1, argv+1)); /* remove the -boot arg from the command line */
- else
- exit(PostgresMain(argc, argv));
+ /*
+ * if the first argument is "-boot", then invoke the backend in
+ * bootstrap mode
+ */
+ if (argc > 1 && strcmp(argv[1], "-boot") == 0)
+ exit(BootstrapMain(argc - 1, argv + 1)); /* remove the -boot arg
+ * from the command line */
+ else
+ exit(PostgresMain(argc, argv));
}
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index e763b9cd7ce..caf9e176ef3 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* copyfuncs.c--
- * Copy functions for Postgres tree nodes.
+ * Copy functions for Postgres tree nodes.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.6 1997/09/04 13:24:01 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.7 1997/09/07 04:42:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,7 +25,7 @@
#include "parser/parse_query.h"
#include "utils/syscache.h"
-#include "utils/builtins.h" /* for namecpy */
+#include "utils/builtins.h" /* for namecpy */
#include "utils/elog.h"
#include "utils/palloc.h"
#include "catalog/pg_type.h"
@@ -33,1716 +33,1774 @@
/*
* listCopy--
- * this copy function only copies the "lcons-cells" of the list but not
- * its contents. (good for list of pointers as well as list of integers).
+ * this copy function only copies the "lcons-cells" of the list but not
+ * its contents. (good for list of pointers as well as list of integers).
*/
-List *
-listCopy(List *list)
+List *
+listCopy(List * list)
{
- List *newlist=NIL;
- List *l, *nl=NIL;
-
- foreach(l, list) {
- if (newlist==NIL) {
- newlist = nl = lcons(lfirst(l),NIL);
- }else {
- lnext(nl) = lcons(lfirst(l),NIL);
- nl = lnext(nl);
+ List *newlist = NIL;
+ List *l,
+ *nl = NIL;
+
+ foreach(l, list)
+ {
+ if (newlist == NIL)
+ {
+ newlist = nl = lcons(lfirst(l), NIL);
+ }
+ else
+ {
+ lnext(nl) = lcons(lfirst(l), NIL);
+ nl = lnext(nl);
+ }
}
- }
- return newlist;
+ return newlist;
}
-
+
/*
* Node_Copy--
- * a macro to simplify calling of copyObject on the specified field
+ * a macro to simplify calling of copyObject on the specified field
*/
#define Node_Copy(from, newnode, field) \
- newnode->field = copyObject(from->field)
+ newnode->field = copyObject(from->field)
/* ****************************************************************
- * plannodes.h copy functions
+ * plannodes.h copy functions
* ****************************************************************
*/
/* ----------------
- * CopyPlanFields
+ * CopyPlanFields
*
- * This function copies the fields of the Plan node. It is used by
- * all the copy functions for classes which inherit from Plan.
+ * This function copies the fields of the Plan node. It is used by
+ * all the copy functions for classes which inherit from Plan.
* ----------------
*/
static void
-CopyPlanFields(Plan *from, Plan *newnode)
+CopyPlanFields(Plan * from, Plan * newnode)
{
- newnode->cost = from->cost;
- newnode->plan_size = from->plan_size;
- newnode->plan_width = from->plan_width;
- newnode->state = from->state;
- newnode->targetlist = copyObject(from->targetlist);
- newnode->qual = copyObject(from->qual);
- newnode->lefttree = copyObject(from->lefttree);
- newnode->righttree = copyObject(from->righttree);
+ newnode->cost = from->cost;
+ newnode->plan_size = from->plan_size;
+ newnode->plan_width = from->plan_width;
+ newnode->state = from->state;
+ newnode->targetlist = copyObject(from->targetlist);
+ newnode->qual = copyObject(from->qual);
+ newnode->lefttree = copyObject(from->lefttree);
+ newnode->righttree = copyObject(from->righttree);
}
/* ----------------
- * _copyPlan
+ * _copyPlan
* ----------------
*/
-static Plan *
-_copyPlan(Plan *from)
+static Plan *
+_copyPlan(Plan * from)
{
- Plan *newnode = makeNode(Plan);
-
- /* ----------------
- * copy the node superclass fields
- * ----------------
- */
- CopyPlanFields(from, newnode);
-
- return newnode;
+ Plan *newnode = makeNode(Plan);
+
+ /* ----------------
+ * copy the node superclass fields
+ * ----------------
+ */
+ CopyPlanFields(from, newnode);
+
+ return newnode;
}
/* ----------------
- * _copyExistential
+ * _copyExistential
* ----------------
*/
static Existential *
-_copyExistential(Existential *from)
+_copyExistential(Existential * from)
{
- Existential *newnode = makeNode(Existential);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields(from, newnode);
-
- return newnode;
+ Existential *newnode = makeNode(Existential);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields(from, newnode);
+
+ return newnode;
}
/* ----------------
- * _copyResult
+ * _copyResult
* ----------------
*/
-static Result *
-_copyResult(Result *from)
+static Result *
+_copyResult(Result * from)
{
- Result *newnode = makeNode(Result);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, resconstantqual);
- Node_Copy(from, newnode, resstate);
-
- return newnode;
+ Result *newnode = makeNode(Result);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, resconstantqual);
+ Node_Copy(from, newnode, resstate);
+
+ return newnode;
}
/* ----------------
- * _copyAppend
+ * _copyAppend
* ----------------
*/
-static Append *
-_copyAppend(Append *from)
+static Append *
+_copyAppend(Append * from)
{
- Append *newnode = makeNode(Append);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, unionplans);
- newnode->unionrelid = from->unionrelid;
- Node_Copy(from, newnode, unionrtentries);
- Node_Copy(from, newnode, unionstate);
-
- return newnode;
+ Append *newnode = makeNode(Append);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, unionplans);
+ newnode->unionrelid = from->unionrelid;
+ Node_Copy(from, newnode, unionrtentries);
+ Node_Copy(from, newnode, unionstate);
+
+ return newnode;
}
/* ----------------
- * CopyScanFields
+ * CopyScanFields
*
- * This function copies the fields of the Scan node. It is used by
- * all the copy functions for classes which inherit from Scan.
+ * This function copies the fields of the Scan node. It is used by
+ * all the copy functions for classes which inherit from Scan.
* ----------------
*/
static void
-CopyScanFields(Scan *from, Scan *newnode)
+CopyScanFields(Scan * from, Scan * newnode)
{
- newnode->scanrelid = from->scanrelid;
- Node_Copy(from, newnode, scanstate);
- return;
+ newnode->scanrelid = from->scanrelid;
+ Node_Copy(from, newnode, scanstate);
+ return;
}
/* ----------------
- * _copyScan
+ * _copyScan
* ----------------
*/
-static Scan *
-_copyScan(Scan *from)
+static Scan *
+_copyScan(Scan * from)
{
- Scan *newnode = makeNode(Scan);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyScanFields(from, newnode);
-
- return newnode;
+ Scan *newnode = makeNode(Scan);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyScanFields(from, newnode);
+
+ return newnode;
}
/* ----------------
- * _copySeqScan
+ * _copySeqScan
* ----------------
*/
static SeqScan *
-_copySeqScan(SeqScan *from)
+_copySeqScan(SeqScan * from)
{
- SeqScan *newnode = makeNode(SeqScan);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyScanFields((Scan*)from, (Scan*)newnode);
-
- return newnode;
+ SeqScan *newnode = makeNode(SeqScan);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyScanFields((Scan *) from, (Scan *) newnode);
+
+ return newnode;
}
/* ----------------
- * _copyIndexScan
+ * _copyIndexScan
* ----------------
*/
static IndexScan *
-_copyIndexScan(IndexScan *from)
+_copyIndexScan(IndexScan * from)
{
- IndexScan *newnode = makeNode(IndexScan);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyScanFields((Scan*)from, (Scan*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->indxid = listCopy(from->indxid);
- Node_Copy(from, newnode, indxqual);
- Node_Copy(from, newnode, indxstate);
-
- return newnode;
+ IndexScan *newnode = makeNode(IndexScan);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyScanFields((Scan *) from, (Scan *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->indxid = listCopy(from->indxid);
+ Node_Copy(from, newnode, indxqual);
+ Node_Copy(from, newnode, indxstate);
+
+ return newnode;
}
/* ----------------
- * CopyJoinFields
+ * CopyJoinFields
*
- * This function copies the fields of the Join node. It is used by
- * all the copy functions for classes which inherit from Join.
+ * This function copies the fields of the Join node. It is used by
+ * all the copy functions for classes which inherit from Join.
* ----------------
*/
static void
-CopyJoinFields(Join *from, Join *newnode)
+CopyJoinFields(Join * from, Join * newnode)
{
- /* nothing extra */
- return;
+ /* nothing extra */
+ return;
}
/* ----------------
- * _copyJoin
+ * _copyJoin
* ----------------
*/
-static Join *
-_copyJoin(Join *from)
+static Join *
+_copyJoin(Join * from)
{
- Join *newnode = makeNode(Join);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyJoinFields(from, newnode);
-
- return newnode;
+ Join *newnode = makeNode(Join);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyJoinFields(from, newnode);
+
+ return newnode;
}
/* ----------------
- * _copyNestLoop
+ * _copyNestLoop
* ----------------
*/
static NestLoop *
-_copyNestLoop(NestLoop *from)
+_copyNestLoop(NestLoop * from)
{
- NestLoop *newnode = makeNode(NestLoop);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyJoinFields((Join*)from, (Join*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, nlstate);
-
- return newnode;
+ NestLoop *newnode = makeNode(NestLoop);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyJoinFields((Join *) from, (Join *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, nlstate);
+
+ return newnode;
}
/* ----------------
- * _copyMergeJoin
+ * _copyMergeJoin
* ----------------
*/
static MergeJoin *
-_copyMergeJoin(MergeJoin *from)
+_copyMergeJoin(MergeJoin * from)
{
- MergeJoin *newnode = makeNode(MergeJoin);
- List *newlist;
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyJoinFields((Join*)from, (Join*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, mergeclauses);
-
- newnode->mergesortop = from->mergesortop;
- newlist = NIL;
-
- newnode->mergerightorder = (Oid *)palloc(sizeof(Oid)*2);
- newnode->mergerightorder[0] = from->mergerightorder[0];
- newnode->mergerightorder[1] = 0;
-
- newnode->mergeleftorder = (Oid *)palloc(sizeof(Oid)*2);
- newnode->mergeleftorder[0] = from->mergeleftorder[0];
- newnode->mergeleftorder[1] = 0;
-
- Node_Copy(from, newnode, mergestate);
-
- return newnode;
+ MergeJoin *newnode = makeNode(MergeJoin);
+ List *newlist;
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyJoinFields((Join *) from, (Join *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, mergeclauses);
+
+ newnode->mergesortop = from->mergesortop;
+ newlist = NIL;
+
+ newnode->mergerightorder = (Oid *) palloc(sizeof(Oid) * 2);
+ newnode->mergerightorder[0] = from->mergerightorder[0];
+ newnode->mergerightorder[1] = 0;
+
+ newnode->mergeleftorder = (Oid *) palloc(sizeof(Oid) * 2);
+ newnode->mergeleftorder[0] = from->mergeleftorder[0];
+ newnode->mergeleftorder[1] = 0;
+
+ Node_Copy(from, newnode, mergestate);
+
+ return newnode;
}
/* ----------------
- * _copyHashJoin
+ * _copyHashJoin
* ----------------
*/
static HashJoin *
-_copyHashJoin(HashJoin *from)
+_copyHashJoin(HashJoin * from)
{
- HashJoin *newnode = makeNode(HashJoin);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyJoinFields((Join*)from, (Join*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, hashclauses);
-
- newnode->hashjoinop = from->hashjoinop;
-
- Node_Copy(from, newnode, hashjoinstate);
-
- newnode->hashjointable = from->hashjointable;
- newnode->hashjointablekey = from->hashjointablekey;
- newnode->hashjointablesize = from->hashjointablesize;
- newnode->hashdone = from->hashdone;
-
- return newnode;
+ HashJoin *newnode = makeNode(HashJoin);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyJoinFields((Join *) from, (Join *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, hashclauses);
+
+ newnode->hashjoinop = from->hashjoinop;
+
+ Node_Copy(from, newnode, hashjoinstate);
+
+ newnode->hashjointable = from->hashjointable;
+ newnode->hashjointablekey = from->hashjointablekey;
+ newnode->hashjointablesize = from->hashjointablesize;
+ newnode->hashdone = from->hashdone;
+
+ return newnode;
}
/* ----------------
- * CopyTempFields
+ * CopyTempFields
*
- * This function copies the fields of the Temp node. It is used by
- * all the copy functions for classes which inherit from Temp.
+ * This function copies the fields of the Temp node. It is used by
+ * all the copy functions for classes which inherit from Temp.
* ----------------
*/
static void
-CopyTempFields(Temp *from, Temp *newnode)
+CopyTempFields(Temp * from, Temp * newnode)
{
- newnode->tempid = from->tempid;
- newnode->keycount = from->keycount;
- return;
+ newnode->tempid = from->tempid;
+ newnode->keycount = from->keycount;
+ return;
}
/* ----------------
- * _copyTemp
+ * _copyTemp
* ----------------
*/
-static Temp *
-_copyTemp(Temp *from)
+static Temp *
+_copyTemp(Temp * from)
{
- Temp *newnode = makeNode(Temp);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyTempFields(from, newnode);
-
- return newnode;
+ Temp *newnode = makeNode(Temp);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyTempFields(from, newnode);
+
+ return newnode;
}
/* ----------------
- * _copyMaterial
+ * _copyMaterial
* ----------------
*/
static Material *
-_copyMaterial(Material *from)
+_copyMaterial(Material * from)
{
- Material *newnode = makeNode(Material);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyTempFields((Temp*)from, (Temp*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, matstate);
-
- return newnode;
+ Material *newnode = makeNode(Material);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyTempFields((Temp *) from, (Temp *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, matstate);
+
+ return newnode;
}
/* ----------------
- * _copySort
+ * _copySort
* ----------------
*/
-static Sort *
-_copySort(Sort *from)
+static Sort *
+_copySort(Sort * from)
{
- Sort *newnode = makeNode(Sort);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyTempFields((Temp*)from, (Temp*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, sortstate);
-
- return newnode;
+ Sort *newnode = makeNode(Sort);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyTempFields((Temp *) from, (Temp *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, sortstate);
+
+ return newnode;
}
/* ---------------
- * _copyAgg
+ * _copyAgg
* --------------
*/
-static Agg *
-_copyAgg(Agg *from)
+static Agg *
+_copyAgg(Agg * from)
{
- Agg *newnode = makeNode(Agg);
- int i;
-
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyTempFields((Temp*)from, (Temp*)newnode);
-
- newnode->numAgg = from->numAgg;
- newnode->aggs = malloc(sizeof(Aggreg *));
- for(i=0; i < from->numAgg; i++) {
- newnode->aggs[i] = copyObject(from->aggs[i]);
- }
-
- Node_Copy(from, newnode, aggstate);
-
- return newnode;
+ Agg *newnode = makeNode(Agg);
+ int i;
+
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyTempFields((Temp *) from, (Temp *) newnode);
+
+ newnode->numAgg = from->numAgg;
+ newnode->aggs = malloc(sizeof(Aggreg *));
+ for (i = 0; i < from->numAgg; i++)
+ {
+ newnode->aggs[i] = copyObject(from->aggs[i]);
+ }
+
+ Node_Copy(from, newnode, aggstate);
+
+ return newnode;
}
/* ----------------
- * _copyUnique
+ * _copyUnique
* ----------------
*/
-static Unique *
-_copyUnique(Unique *from)
+static Unique *
+_copyUnique(Unique * from)
{
- Unique *newnode = makeNode(Unique);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
- CopyTempFields((Temp*)from, (Temp*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, uniquestate);
-
- return newnode;
+ Unique *newnode = makeNode(Unique);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyTempFields((Temp *) from, (Temp *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, uniquestate);
+
+ return newnode;
}
/* ----------------
- * _copyHash
+ * _copyHash
* ----------------
*/
-static Hash *
-_copyHash(Hash *from)
+static Hash *
+_copyHash(Hash * from)
{
- Hash *newnode = makeNode(Hash);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyPlanFields((Plan*)from, (Plan*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, hashkey);
- Node_Copy(from, newnode, hashstate);
-
- newnode->hashtable = from->hashtable;
- newnode->hashtablekey = from->hashtablekey;
- newnode->hashtablesize = from->hashtablesize;
-
- return newnode;
+ Hash *newnode = makeNode(Hash);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, hashkey);
+ Node_Copy(from, newnode, hashstate);
+
+ newnode->hashtable = from->hashtable;
+ newnode->hashtablekey = from->hashtablekey;
+ newnode->hashtablesize = from->hashtablesize;
+
+ return newnode;
}
/* ****************************************************************
- * primnodes.h copy functions
+ * primnodes.h copy functions
* ****************************************************************
*/
/* ----------------
- * _copyResdom
+ * _copyResdom
* ----------------
*/
-static Resdom *
-_copyResdom(Resdom *from)
+static Resdom *
+_copyResdom(Resdom * from)
{
- Resdom *newnode = makeNode(Resdom);
-
- newnode->resno = from->resno;
- newnode->restype = from->restype;
- newnode->reslen = from->reslen;
-
- if (from->resname != NULL) {
- newnode->resname = palloc(strlen(from->resname)+1);
- strcpy(newnode->resname, from->resname);
- } else
- newnode->resname = (char*) NULL;
-
- newnode->reskey = from->reskey;
- newnode->reskeyop = from->reskeyop;
- newnode->resjunk = from->resjunk;
-
- return newnode;
+ Resdom *newnode = makeNode(Resdom);
+
+ newnode->resno = from->resno;
+ newnode->restype = from->restype;
+ newnode->reslen = from->reslen;
+
+ if (from->resname != NULL)
+ {
+ newnode->resname = palloc(strlen(from->resname) + 1);
+ strcpy(newnode->resname, from->resname);
+ }
+ else
+ newnode->resname = (char *) NULL;
+
+ newnode->reskey = from->reskey;
+ newnode->reskeyop = from->reskeyop;
+ newnode->resjunk = from->resjunk;
+
+ return newnode;
}
-static Fjoin *
-_copyFjoin(Fjoin *from)
+static Fjoin *
+_copyFjoin(Fjoin * from)
{
- Fjoin *newnode = makeNode(Fjoin);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
-
- newnode->fj_initialized = from->fj_initialized;
- newnode->fj_nNodes = from->fj_nNodes;
-
- Node_Copy(from, newnode, fj_innerNode);
-
- newnode->fj_results = (DatumPtr)
- palloc((from->fj_nNodes)*sizeof(Datum));
-
- newnode->fj_alwaysDone = (BoolPtr)
- palloc((from->fj_nNodes)*sizeof(bool));
-
- memmove(from->fj_results,
- newnode->fj_results,
- (from->fj_nNodes)*sizeof(Datum));
-
- memmove(from->fj_alwaysDone,
- newnode->fj_alwaysDone,
- (from->fj_nNodes)*sizeof(bool));
-
-
- return newnode;
+ Fjoin *newnode = makeNode(Fjoin);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+
+ newnode->fj_initialized = from->fj_initialized;
+ newnode->fj_nNodes = from->fj_nNodes;
+
+ Node_Copy(from, newnode, fj_innerNode);
+
+ newnode->fj_results = (DatumPtr)
+ palloc((from->fj_nNodes) * sizeof(Datum));
+
+ newnode->fj_alwaysDone = (BoolPtr)
+ palloc((from->fj_nNodes) * sizeof(bool));
+
+ memmove(from->fj_results,
+ newnode->fj_results,
+ (from->fj_nNodes) * sizeof(Datum));
+
+ memmove(from->fj_alwaysDone,
+ newnode->fj_alwaysDone,
+ (from->fj_nNodes) * sizeof(bool));
+
+
+ return newnode;
}
/* ----------------
- * _copyExpr
+ * _copyExpr
* ----------------
*/
-static Expr *
-_copyExpr(Expr *from)
+static Expr *
+_copyExpr(Expr * from)
{
- Expr *newnode = makeNode(Expr);
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- newnode->typeOid = from->typeOid;
- newnode->opType = from->opType;
-
- Node_Copy(from, newnode, oper);
- Node_Copy(from, newnode, args);
-
- return newnode;
+ Expr *newnode = makeNode(Expr);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ newnode->typeOid = from->typeOid;
+ newnode->opType = from->opType;
+
+ Node_Copy(from, newnode, oper);
+ Node_Copy(from, newnode, args);
+
+ return newnode;
}
/* ----------------
- * _copyVar
+ * _copyVar
* ----------------
*/
-static Var *
-_copyVar(Var *from)
+static Var *
+_copyVar(Var * from)
{
- Var *newnode = makeNode(Var);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->varno = from->varno;
- newnode->varattno = from->varattno;
- newnode->vartype = from->vartype;
-
- newnode->varnoold = from->varnoold;
- newnode->varoattno = from->varoattno;
-
- return newnode;
+ Var *newnode = makeNode(Var);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->varno = from->varno;
+ newnode->varattno = from->varattno;
+ newnode->vartype = from->vartype;
+
+ newnode->varnoold = from->varnoold;
+ newnode->varoattno = from->varoattno;
+
+ return newnode;
}
/* ----------------
- * _copyOper
+ * _copyOper
* ----------------
*/
-static Oper *
-_copyOper(Oper *from)
+static Oper *
+_copyOper(Oper * from)
{
- Oper *newnode = makeNode(Oper);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->opno = from->opno;
- newnode->opid = from->opid;
- newnode->opresulttype = from->opresulttype;
- newnode->opsize = from->opsize;
-
- /*
- * NOTE: shall we copy the cache structure or just the pointer ?
- * Alternatively we can set 'op_fcache' to NULL, in which
- * case the executor will initialize it when it needs it...
- */
- newnode->op_fcache = from->op_fcache;
-
- return newnode;
+ Oper *newnode = makeNode(Oper);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->opno = from->opno;
+ newnode->opid = from->opid;
+ newnode->opresulttype = from->opresulttype;
+ newnode->opsize = from->opsize;
+
+ /*
+ * NOTE: shall we copy the cache structure or just the pointer ?
+ * Alternatively we can set 'op_fcache' to NULL, in which case the
+ * executor will initialize it when it needs it...
+ */
+ newnode->op_fcache = from->op_fcache;
+
+ return newnode;
}
/* ----------------
- * _copyConst
+ * _copyConst
* ----------------
*/
-static Const *
-_copyConst(Const *from)
+static Const *
+_copyConst(Const * from)
{
- static Oid cached_type;
- static bool cached_typbyval;
-
- Const *newnode = makeNode(Const);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->consttype = from->consttype;
- newnode->constlen = from->constlen;
-
- /* ----------------
- * XXX super cheesy hack until parser/planner
- * puts in the right values here.
- * ----------------
- */
- if (cached_type != from->consttype) {
- HeapTuple typeTuple;
- TypeTupleForm typeStruct;
-
- /* ----------------
- * get the type tuple corresponding to the paramList->type,
- * If this fails, returnValue has been pre-initialized
- * to "null" so we just return it.
- * ----------------
- */
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(from->consttype),
- 0,0,0);
-
+ static Oid cached_type;
+ static bool cached_typbyval;
+
+ Const *newnode = makeNode(Const);
+
/* ----------------
- * get the type length and by-value from the type tuple and
- * save the information in our one element cache.
+ * copy remainder of node
* ----------------
*/
- Assert(PointerIsValid(typeTuple));
-
- typeStruct = (TypeTupleForm) GETSTRUCT(typeTuple);
- cached_typbyval = (typeStruct)->typbyval ? true : false ;
- cached_type = from->consttype;
- }
-
- from->constbyval = cached_typbyval;
-
- if (!from->constisnull) {
+ newnode->consttype = from->consttype;
+ newnode->constlen = from->constlen;
+
/* ----------------
- * copying the Datum in a const node is a bit trickier
- * because it might be a pointer and it might also be of
- * variable length...
+ * XXX super cheesy hack until parser/planner
+ * puts in the right values here.
* ----------------
*/
- if (from->constbyval == true) {
- /* ----------------
- * passed by value so just copy the datum.
- * ----------------
- */
- newnode->constvalue = from->constvalue;
- } else {
- /* ----------------
- * not passed by value. datum contains a pointer.
- * ----------------
- */
- if (from->constlen != -1) {
+ if (cached_type != from->consttype)
+ {
+ HeapTuple typeTuple;
+ TypeTupleForm typeStruct;
+
+ /* ----------------
+ * get the type tuple corresponding to the paramList->type,
+ * If this fails, returnValue has been pre-initialized
+ * to "null" so we just return it.
+ * ----------------
+ */
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(from->consttype),
+ 0, 0, 0);
+
/* ----------------
- * fixed length structure
+ * get the type length and by-value from the type tuple and
+ * save the information in our one element cache.
* ----------------
*/
- newnode->constvalue = PointerGetDatum(palloc(from->constlen));
- memmove((char*)newnode->constvalue,
- (char*)from->constvalue, from->constlen);
- } else {
+ Assert(PointerIsValid(typeTuple));
+
+ typeStruct = (TypeTupleForm) GETSTRUCT(typeTuple);
+ cached_typbyval = (typeStruct)->typbyval ? true : false;
+ cached_type = from->consttype;
+ }
+
+ from->constbyval = cached_typbyval;
+
+ if (!from->constisnull)
+ {
/* ----------------
- * variable length structure. here the length is stored
- * in the first int pointed to by the constval.
+ * copying the Datum in a const node is a bit trickier
+ * because it might be a pointer and it might also be of
+ * variable length...
* ----------------
*/
- int length;
- length = *((int *) from->constvalue);
- newnode->constvalue = PointerGetDatum(palloc(length));
- memmove((char*)newnode->constvalue,
- (char*)from->constvalue, length);
- }
+ if (from->constbyval == true)
+ {
+ /* ----------------
+ * passed by value so just copy the datum.
+ * ----------------
+ */
+ newnode->constvalue = from->constvalue;
+ }
+ else
+ {
+ /* ----------------
+ * not passed by value. datum contains a pointer.
+ * ----------------
+ */
+ if (from->constlen != -1)
+ {
+ /* ----------------
+ * fixed length structure
+ * ----------------
+ */
+ newnode->constvalue = PointerGetDatum(palloc(from->constlen));
+ memmove((char *) newnode->constvalue,
+ (char *) from->constvalue, from->constlen);
+ }
+ else
+ {
+ /* ----------------
+ * variable length structure. here the length is stored
+ * in the first int pointed to by the constval.
+ * ----------------
+ */
+ int length;
+
+ length = *((int *) from->constvalue);
+ newnode->constvalue = PointerGetDatum(palloc(length));
+ memmove((char *) newnode->constvalue,
+ (char *) from->constvalue, length);
+ }
+ }
+ }
+ else
+ {
+ newnode->constvalue = from->constvalue;
}
- }
- else {
- newnode->constvalue = from->constvalue;
- }
- newnode->constisnull = from->constisnull;
- newnode->constbyval = from->constbyval;
-
- return newnode;
+ newnode->constisnull = from->constisnull;
+ newnode->constbyval = from->constbyval;
+
+ return newnode;
}
/* ----------------
- * _copyParam
+ * _copyParam
* ----------------
*/
-static Param *
-_copyParam(Param *from)
+static Param *
+_copyParam(Param * from)
{
- Param *newnode = makeNode(Param);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->paramkind = from->paramkind;
- newnode->paramid = from->paramid;
-
- if (from->paramname != NULL) {
- newnode->paramname = pstrdup(from->paramname);
- } else
- newnode->paramname = (char*)NULL;
-
- newnode->paramtype = from->paramtype;
- Node_Copy(from, newnode, param_tlist);
-
- return newnode;
+ Param *newnode = makeNode(Param);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->paramkind = from->paramkind;
+ newnode->paramid = from->paramid;
+
+ if (from->paramname != NULL)
+ {
+ newnode->paramname = pstrdup(from->paramname);
+ }
+ else
+ newnode->paramname = (char *) NULL;
+
+ newnode->paramtype = from->paramtype;
+ Node_Copy(from, newnode, param_tlist);
+
+ return newnode;
}
/* ----------------
- * _copyFunc
+ * _copyFunc
* ----------------
*/
-static Func *
-_copyFunc(Func *from)
+static Func *
+_copyFunc(Func * from)
{
- Func *newnode = makeNode(Func);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->funcid = from->funcid;
- newnode->functype = from->functype;
- newnode->funcisindex = from->funcisindex;
- newnode->funcsize = from->funcsize;
- newnode->func_fcache = from->func_fcache;
- Node_Copy(from, newnode, func_tlist);
- Node_Copy(from, newnode, func_planlist);
-
- return newnode;
+ Func *newnode = makeNode(Func);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->funcid = from->funcid;
+ newnode->functype = from->functype;
+ newnode->funcisindex = from->funcisindex;
+ newnode->funcsize = from->funcsize;
+ newnode->func_fcache = from->func_fcache;
+ Node_Copy(from, newnode, func_tlist);
+ Node_Copy(from, newnode, func_planlist);
+
+ return newnode;
}
/* ----------------
- * _copyAggreg
+ * _copyAggreg
* ----------------
*/
-static Aggreg *
-_copyAggreg(Aggreg *from)
+static Aggreg *
+_copyAggreg(Aggreg * from)
{
- Aggreg *newnode = makeNode(Aggreg);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->aggname = pstrdup(from->aggname);
- newnode->basetype = from->basetype;
- newnode->aggtype = from->aggtype;
-
- Node_Copy(from, newnode, target);
-
- newnode->aggno = from->aggno;
-
- return newnode;
+ Aggreg *newnode = makeNode(Aggreg);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->aggname = pstrdup(from->aggname);
+ newnode->basetype = from->basetype;
+ newnode->aggtype = from->aggtype;
+
+ Node_Copy(from, newnode, target);
+
+ newnode->aggno = from->aggno;
+
+ return newnode;
}
-static Array *
-_copyArray(Array *from)
+static Array *
+_copyArray(Array * from)
{
- Array *newnode = makeNode(Array);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->arrayelemtype = from->arrayelemtype;
- newnode->arrayelemlength = from->arrayelemlength;
- newnode->arrayelembyval = from->arrayelembyval;
- newnode->arrayndim = from->arrayndim;
- newnode->arraylow = from->arraylow;
- newnode->arrayhigh = from->arrayhigh;
- newnode->arraylen = from->arraylen;
-
- return newnode;
+ Array *newnode = makeNode(Array);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->arrayelemtype = from->arrayelemtype;
+ newnode->arrayelemlength = from->arrayelemlength;
+ newnode->arrayelembyval = from->arrayelembyval;
+ newnode->arrayndim = from->arrayndim;
+ newnode->arraylow = from->arraylow;
+ newnode->arrayhigh = from->arrayhigh;
+ newnode->arraylen = from->arraylen;
+
+ return newnode;
}
static ArrayRef *
-_copyArrayRef(ArrayRef *from)
+_copyArrayRef(ArrayRef * from)
{
- ArrayRef *newnode = makeNode(ArrayRef);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->refelemtype = from->refelemtype;
- newnode->refattrlength = from->refattrlength;
- newnode->refelemlength = from->refelemlength;
- newnode->refelembyval = from->refelembyval;
-
- Node_Copy(from,newnode,refupperindexpr);
- Node_Copy(from,newnode,reflowerindexpr);
- Node_Copy(from,newnode,refexpr);
- Node_Copy(from,newnode,refassgnexpr);
-
- return newnode;
+ ArrayRef *newnode = makeNode(ArrayRef);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->refelemtype = from->refelemtype;
+ newnode->refattrlength = from->refattrlength;
+ newnode->refelemlength = from->refelemlength;
+ newnode->refelembyval = from->refelembyval;
+
+ Node_Copy(from, newnode, refupperindexpr);
+ Node_Copy(from, newnode, reflowerindexpr);
+ Node_Copy(from, newnode, refexpr);
+ Node_Copy(from, newnode, refassgnexpr);
+
+ return newnode;
}
/* ****************************************************************
- * relation.h copy functions
+ * relation.h copy functions
* ****************************************************************
*/
/* ----------------
- * _copyRel
+ * _copyRel
* ----------------
*/
/*
- ** when you change this, also make sure to fix up xfunc_copyRel in
+ ** when you change this, also make sure to fix up xfunc_copyRel in
** planner/path/xfunc.c accordingly!!!
- ** -- JMH, 8/2/93
+ ** -- JMH, 8/2/93
*/
-static Rel *
-_copyRel(Rel *from)
+static Rel *
+_copyRel(Rel * from)
{
- Rel *newnode = makeNode(Rel);
- int i, len;
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->relids = listCopy(from->relids);
-
- newnode->indexed = from->indexed;
- newnode->pages = from->pages;
- newnode->tuples = from->tuples;
- newnode->size = from->size;
- newnode->width = from->width;
- newnode->indproc = from->indproc;
-
- Node_Copy(from, newnode, targetlist);
- Node_Copy(from, newnode, pathlist);
- Node_Copy(from, newnode, unorderedpath);
- Node_Copy(from, newnode, cheapestpath);
- newnode->pruneable = from->pruneable;
- newnode->relam = from->relam;
-
- if (from->classlist) {
- for(len=0; from->classlist[len]!=0; len++)
- ;
- newnode->classlist = (Oid *)palloc(sizeof(Oid) * (len+1));
- for(i=0; i < len; i++) {
- newnode->classlist[i] = from->classlist[i];
+ Rel *newnode = makeNode(Rel);
+ int i,
+ len;
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->relids = listCopy(from->relids);
+
+ newnode->indexed = from->indexed;
+ newnode->pages = from->pages;
+ newnode->tuples = from->tuples;
+ newnode->size = from->size;
+ newnode->width = from->width;
+ newnode->indproc = from->indproc;
+
+ Node_Copy(from, newnode, targetlist);
+ Node_Copy(from, newnode, pathlist);
+ Node_Copy(from, newnode, unorderedpath);
+ Node_Copy(from, newnode, cheapestpath);
+ newnode->pruneable = from->pruneable;
+ newnode->relam = from->relam;
+
+ if (from->classlist)
+ {
+ for (len = 0; from->classlist[len] != 0; len++)
+ ;
+ newnode->classlist = (Oid *) palloc(sizeof(Oid) * (len + 1));
+ for (i = 0; i < len; i++)
+ {
+ newnode->classlist[i] = from->classlist[i];
+ }
+ newnode->classlist[len] = 0;
}
- newnode->classlist[len] = 0;
- }
-
- if (from->indexkeys) {
- for(len=0; from->indexkeys[len]!=0; len++)
- ;
- newnode->indexkeys = (int *)palloc(sizeof(int) * (len+1));
- for(i=0; i < len; i++) {
- newnode->indexkeys[i] = from->indexkeys[i];
+
+ if (from->indexkeys)
+ {
+ for (len = 0; from->indexkeys[len] != 0; len++)
+ ;
+ newnode->indexkeys = (int *) palloc(sizeof(int) * (len + 1));
+ for (i = 0; i < len; i++)
+ {
+ newnode->indexkeys[i] = from->indexkeys[i];
+ }
+ newnode->indexkeys[len] = 0;
}
- newnode->indexkeys[len] = 0;
- }
-
- if (from->ordering) {
- for(len=0; from->ordering[len]!=0; len++)
- ;
- newnode->ordering = (Oid *)palloc(sizeof(Oid) * (len+1));
- for(i=0; i < len; i++) {
- newnode->ordering[i] = from->ordering[i];
+
+ if (from->ordering)
+ {
+ for (len = 0; from->ordering[len] != 0; len++)
+ ;
+ newnode->ordering = (Oid *) palloc(sizeof(Oid) * (len + 1));
+ for (i = 0; i < len; i++)
+ {
+ newnode->ordering[i] = from->ordering[i];
+ }
+ newnode->ordering[len] = 0;
}
- newnode->ordering[len] = 0;
- }
-
- Node_Copy(from, newnode, clauseinfo);
- Node_Copy(from, newnode, joininfo);
- Node_Copy(from, newnode, innerjoin);
- Node_Copy(from, newnode, superrels);
-
- return newnode;
+
+ Node_Copy(from, newnode, clauseinfo);
+ Node_Copy(from, newnode, joininfo);
+ Node_Copy(from, newnode, innerjoin);
+ Node_Copy(from, newnode, superrels);
+
+ return newnode;
}
/* ----------------
- * CopyPathFields
+ * CopyPathFields
*
- * This function copies the fields of the Path node. It is used by
- * all the copy functions for classes which inherit from Path.
+ * This function copies the fields of the Path node. It is used by
+ * all the copy functions for classes which inherit from Path.
* ----------------
*/
static void
-CopyPathFields(Path *from, Path *newnode)
+CopyPathFields(Path * from, Path * newnode)
{
- newnode->pathtype = from->pathtype;
- /* 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:
- Node_Copy(from, newnode, parent);
- */
- newnode->parent = from->parent;
-
- newnode->path_cost = from->path_cost;
-
- newnode->p_ordering.ordtype = from->p_ordering.ordtype;
- if (from->p_ordering.ordtype == SORTOP_ORDER) {
- int len, i;
- Oid *ordering = from->p_ordering.ord.sortop;
-
- if (ordering) {
- for(len=0; ordering[len]!=0; len++)
- ;
- newnode->p_ordering.ord.sortop =
- (Oid *)palloc(sizeof(Oid) * (len+1));
- for(i=0; i < len; i++) {
- newnode->p_ordering.ord.sortop[i] = ordering[i];
- }
- newnode->p_ordering.ord.sortop[len] = 0;
- } else {
- newnode->p_ordering.ord.sortop = NULL;
+ newnode->pathtype = from->pathtype;
+
+ /*
+ * 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:
+ * Node_Copy(from, newnode, parent);
+ */
+ newnode->parent = from->parent;
+
+ newnode->path_cost = from->path_cost;
+
+ newnode->p_ordering.ordtype = from->p_ordering.ordtype;
+ if (from->p_ordering.ordtype == SORTOP_ORDER)
+ {
+ int len,
+ i;
+ Oid *ordering = from->p_ordering.ord.sortop;
+
+ if (ordering)
+ {
+ for (len = 0; ordering[len] != 0; len++)
+ ;
+ newnode->p_ordering.ord.sortop =
+ (Oid *) palloc(sizeof(Oid) * (len + 1));
+ for (i = 0; i < len; i++)
+ {
+ newnode->p_ordering.ord.sortop[i] = ordering[i];
+ }
+ newnode->p_ordering.ord.sortop[len] = 0;
+ }
+ else
+ {
+ newnode->p_ordering.ord.sortop = NULL;
+ }
+ }
+ else
+ {
+ Node_Copy(from, newnode, p_ordering.ord.merge);
}
- } else {
- Node_Copy(from, newnode, p_ordering.ord.merge);
- }
-
- Node_Copy(from, newnode, keys);
-
- newnode->outerjoincost = from->outerjoincost;
-
- newnode->joinid = listCopy(from->joinid);
- Node_Copy(from, newnode, locclauseinfo);
+
+ Node_Copy(from, newnode, keys);
+
+ newnode->outerjoincost = from->outerjoincost;
+
+ newnode->joinid = listCopy(from->joinid);
+ Node_Copy(from, newnode, locclauseinfo);
}
/* ----------------
- * _copyPath
+ * _copyPath
* ----------------
*/
-static Path *
-_copyPath(Path *from)
+static Path *
+_copyPath(Path * from)
{
- Path *newnode = makeNode(Path);
-
- CopyPathFields(from, newnode);
-
- return newnode;
+ Path *newnode = makeNode(Path);
+
+ CopyPathFields(from, newnode);
+
+ return newnode;
}
/* ----------------
- * _copyIndexPath
+ * _copyIndexPath
* ----------------
*/
static IndexPath *
-_copyIndexPath(IndexPath *from)
+_copyIndexPath(IndexPath * from)
{
- IndexPath *newnode = makeNode(IndexPath);
-
- /* ----------------
- * copy the node superclass fields
- * ----------------
- */
- CopyPathFields((Path*)from, (Path*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->indexid = listCopy(from->indexid);
- Node_Copy(from, newnode, indexqual);
-
- if (from->indexkeys)
- {
- int i, len;
-
- for(len=0; from->indexkeys[len]!=0; len++)
- ;
- newnode->indexkeys = (int *)palloc(sizeof(int) * (len+1));
- for(i=0; i < len; i++) {
- newnode->indexkeys[i] = from->indexkeys[i];
+ IndexPath *newnode = makeNode(IndexPath);
+
+ /* ----------------
+ * copy the node superclass fields
+ * ----------------
+ */
+ CopyPathFields((Path *) from, (Path *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->indexid = listCopy(from->indexid);
+ Node_Copy(from, newnode, indexqual);
+
+ if (from->indexkeys)
+ {
+ int i,
+ len;
+
+ for (len = 0; from->indexkeys[len] != 0; len++)
+ ;
+ newnode->indexkeys = (int *) palloc(sizeof(int) * (len + 1));
+ for (i = 0; i < len; i++)
+ {
+ newnode->indexkeys[i] = from->indexkeys[i];
+ }
+ newnode->indexkeys[len] = 0;
}
- newnode->indexkeys[len] = 0;
- }
-
- return newnode;
+
+ return newnode;
}
/* ----------------
- * CopyJoinPathFields
+ * CopyJoinPathFields
*
- * This function copies the fields of the JoinPath node. It is used by
- * all the copy functions for classes which inherit from JoinPath.
+ * This function copies the fields of the JoinPath node. It is used by
+ * all the copy functions for classes which inherit from JoinPath.
* ----------------
*/
static void
-CopyJoinPathFields(JoinPath *from, JoinPath *newnode)
+CopyJoinPathFields(JoinPath * from, JoinPath * newnode)
{
- Node_Copy(from, newnode, pathclauseinfo);
- Node_Copy(from, newnode, outerjoinpath);
- Node_Copy(from, newnode, innerjoinpath);
+ Node_Copy(from, newnode, pathclauseinfo);
+ Node_Copy(from, newnode, outerjoinpath);
+ Node_Copy(from, newnode, innerjoinpath);
}
/* ----------------
- * _copyJoinPath
+ * _copyJoinPath
* ----------------
*/
static JoinPath *
-_copyJoinPath(JoinPath *from)
+_copyJoinPath(JoinPath * from)
{
- JoinPath *newnode = makeNode(JoinPath);
-
- /* ----------------
- * copy the node superclass fields
- * ----------------
- */
- CopyPathFields((Path*)from, (Path*)newnode);
- CopyJoinPathFields(from, newnode);
-
- return newnode;
+ JoinPath *newnode = makeNode(JoinPath);
+
+ /* ----------------
+ * copy the node superclass fields
+ * ----------------
+ */
+ CopyPathFields((Path *) from, (Path *) newnode);
+ CopyJoinPathFields(from, newnode);
+
+ return newnode;
}
/* ----------------
- * _copyMergePath
+ * _copyMergePath
* ----------------
*/
static MergePath *
-_copyMergePath(MergePath *from)
+_copyMergePath(MergePath * from)
{
- MergePath *newnode = makeNode(MergePath);
-
- /* ----------------
- * copy the node superclass fields
- * ----------------
- */
- CopyPathFields((Path*)from, (Path*)newnode);
- CopyJoinPathFields((JoinPath*)from, (JoinPath*)newnode);
-
- /* ----------------
- * copy the remainder of the node
- * ----------------
- */
- Node_Copy(from, newnode, path_mergeclauses);
- Node_Copy(from, newnode, outersortkeys);
- Node_Copy(from, newnode, innersortkeys);
-
- return newnode;
+ MergePath *newnode = makeNode(MergePath);
+
+ /* ----------------
+ * copy the node superclass fields
+ * ----------------
+ */
+ CopyPathFields((Path *) from, (Path *) newnode);
+ CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
+
+ /* ----------------
+ * copy the remainder of the node
+ * ----------------
+ */
+ Node_Copy(from, newnode, path_mergeclauses);
+ Node_Copy(from, newnode, outersortkeys);
+ Node_Copy(from, newnode, innersortkeys);
+
+ return newnode;
}
/* ----------------
- * _copyHashPath
+ * _copyHashPath
* ----------------
*/
static HashPath *
-_copyHashPath(HashPath *from)
+_copyHashPath(HashPath * from)
{
- HashPath *newnode = makeNode(HashPath);
-
- /* ----------------
- * copy the node superclass fields
- * ----------------
- */
- CopyPathFields((Path*)from, (Path*)newnode);
- CopyJoinPathFields((JoinPath*)from, (JoinPath*)newnode);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, path_hashclauses);
- Node_Copy(from, newnode, outerhashkeys);
- Node_Copy(from, newnode, innerhashkeys);
-
- return newnode;
+ HashPath *newnode = makeNode(HashPath);
+
+ /* ----------------
+ * copy the node superclass fields
+ * ----------------
+ */
+ CopyPathFields((Path *) from, (Path *) newnode);
+ CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, path_hashclauses);
+ Node_Copy(from, newnode, outerhashkeys);
+ Node_Copy(from, newnode, innerhashkeys);
+
+ return newnode;
}
/* ----------------
- * _copyOrderKey
+ * _copyOrderKey
* ----------------
*/
static OrderKey *
-_copyOrderKey(OrderKey *from)
+_copyOrderKey(OrderKey * from)
{
- OrderKey *newnode = makeNode(OrderKey);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->attribute_number = from->attribute_number;
- newnode->array_index = from->array_index;
-
- return newnode;
+ OrderKey *newnode = makeNode(OrderKey);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->attribute_number = from->attribute_number;
+ newnode->array_index = from->array_index;
+
+ return newnode;
}
/* ----------------
- * _copyJoinKey
+ * _copyJoinKey
* ----------------
*/
static JoinKey *
-_copyJoinKey(JoinKey *from)
+_copyJoinKey(JoinKey * from)
{
- JoinKey *newnode = makeNode(JoinKey);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, outer);
- Node_Copy(from, newnode, inner);
-
- return newnode;
+ JoinKey *newnode = makeNode(JoinKey);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, outer);
+ Node_Copy(from, newnode, inner);
+
+ return newnode;
}
/* ----------------
- * _copyMergeOrder
+ * _copyMergeOrder
* ----------------
*/
static MergeOrder *
-_copyMergeOrder(MergeOrder *from)
+_copyMergeOrder(MergeOrder * from)
{
- MergeOrder *newnode = makeNode(MergeOrder);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->join_operator = from->join_operator;
- newnode->left_operator = from->left_operator;
- newnode->right_operator = from->right_operator;
- newnode->left_type = from->left_type;
- newnode->right_type = from->right_type;
-
- return newnode;
+ MergeOrder *newnode = makeNode(MergeOrder);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->join_operator = from->join_operator;
+ newnode->left_operator = from->left_operator;
+ newnode->right_operator = from->right_operator;
+ newnode->left_type = from->left_type;
+ newnode->right_type = from->right_type;
+
+ return newnode;
}
/* ----------------
- * _copyCInfo
+ * _copyCInfo
* ----------------
*/
-static CInfo *
-_copyCInfo(CInfo *from)
+static CInfo *
+_copyCInfo(CInfo * from)
{
- CInfo *newnode = makeNode(CInfo);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, clause);
-
- newnode->selectivity = from->selectivity;
- newnode->notclause = from->notclause;
-
- Node_Copy(from, newnode, indexids);
- Node_Copy(from, newnode, mergesortorder);
- newnode->hashjoinoperator = from->hashjoinoperator;
- newnode->cinfojoinid = listCopy(from->cinfojoinid);
-
- return newnode;
+ CInfo *newnode = makeNode(CInfo);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, clause);
+
+ newnode->selectivity = from->selectivity;
+ newnode->notclause = from->notclause;
+
+ Node_Copy(from, newnode, indexids);
+ Node_Copy(from, newnode, mergesortorder);
+ newnode->hashjoinoperator = from->hashjoinoperator;
+ newnode->cinfojoinid = listCopy(from->cinfojoinid);
+
+ return newnode;
}
/* ----------------
- * CopyJoinMethodFields
+ * CopyJoinMethodFields
*
- * This function copies the fields of the JoinMethod node. It is used by
- * all the copy functions for classes which inherit from JoinMethod.
+ * This function copies the fields of the JoinMethod node. It is used by
+ * all the copy functions for classes which inherit from JoinMethod.
* ----------------
*/
static void
-CopyJoinMethodFields(JoinMethod *from, JoinMethod *newnode)
+CopyJoinMethodFields(JoinMethod * from, JoinMethod * newnode)
{
- Node_Copy(from, newnode, jmkeys);
- Node_Copy(from, newnode, clauses);
- return;
+ Node_Copy(from, newnode, jmkeys);
+ Node_Copy(from, newnode, clauses);
+ return;
}
/* ----------------
- * _copyJoinMethod
+ * _copyJoinMethod
* ----------------
*/
static JoinMethod *
-_copyJoinMethod(JoinMethod *from)
+_copyJoinMethod(JoinMethod * from)
{
- JoinMethod *newnode = makeNode(JoinMethod);
-
- CopyJoinMethodFields(from, newnode);
-
- return newnode;
+ JoinMethod *newnode = makeNode(JoinMethod);
+
+ CopyJoinMethodFields(from, newnode);
+
+ return newnode;
}
/* ----------------
- * _copyHInfo
+ * _copyHInfo
* ----------------
*/
-static HInfo *
-_copyHInfo(HInfo *from)
+static HInfo *
+_copyHInfo(HInfo * from)
{
- HInfo *newnode = makeNode(HInfo);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->hashop = from->hashop;
-
- return newnode;
+ HInfo *newnode = makeNode(HInfo);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->hashop = from->hashop;
+
+ return newnode;
}
/* ----------------
- * _copyMInfo
+ * _copyMInfo
* ----------------
*/
-static MInfo *
-_copyMInfo(MInfo *from)
+static MInfo *
+_copyMInfo(MInfo * from)
{
- MInfo *newnode = makeNode(MInfo);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, m_ordering);
-
- return newnode;
+ MInfo *newnode = makeNode(MInfo);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, m_ordering);
+
+ return newnode;
}
/* ----------------
- * _copyJInfo
+ * _copyJInfo
* ----------------
*/
-static JInfo *
-_copyJInfo(JInfo *from)
+static JInfo *
+_copyJInfo(JInfo * from)
{
- JInfo *newnode = makeNode(JInfo);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- newnode->otherrels = listCopy(from->otherrels);
- Node_Copy(from, newnode, jinfoclauseinfo);
-
- newnode->mergesortable = from->mergesortable;
- newnode->hashjoinable = from->hashjoinable;
- newnode->inactive = from->inactive;
-
- return newnode;
+ JInfo *newnode = makeNode(JInfo);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ newnode->otherrels = listCopy(from->otherrels);
+ Node_Copy(from, newnode, jinfoclauseinfo);
+
+ newnode->mergesortable = from->mergesortable;
+ newnode->hashjoinable = from->hashjoinable;
+ newnode->inactive = from->inactive;
+
+ return newnode;
}
-static Iter *
-_copyIter(Iter *from)
+static Iter *
+_copyIter(Iter * from)
{
- Iter *newnode = makeNode(Iter);
+ Iter *newnode = makeNode(Iter);
+
+ Node_Copy(from, newnode, iterexpr);
+ newnode->itertype = from->itertype;
- Node_Copy(from, newnode, iterexpr);
- newnode->itertype = from->itertype;
-
- return newnode;
+ return newnode;
}
-static Stream *
-_copyStream(Stream *from)
+static Stream *
+_copyStream(Stream * from)
{
- Stream *newnode = makeNode(Stream);
-
- newnode->pathptr = from->pathptr;
- newnode->cinfo = from->cinfo;
- newnode->clausetype = from->clausetype;
- newnode->groupup = from->groupup;
- newnode->groupcost = from->groupcost;
- newnode->groupsel = from->groupsel;
- newnode->upstream = (StreamPtr)NULL; /* only copy nodes downwards! */
- Node_Copy(from, newnode, downstream);
- if (newnode->downstream)
- ((Stream*)newnode->downstream)->upstream = (Stream*)newnode;
-
- return newnode;
+ Stream *newnode = makeNode(Stream);
+
+ newnode->pathptr = from->pathptr;
+ newnode->cinfo = from->cinfo;
+ newnode->clausetype = from->clausetype;
+ newnode->groupup = from->groupup;
+ newnode->groupcost = from->groupcost;
+ newnode->groupsel = from->groupsel;
+ newnode->upstream = (StreamPtr) NULL; /* only copy nodes
+ * downwards! */
+ Node_Copy(from, newnode, downstream);
+ if (newnode->downstream)
+ ((Stream *) newnode->downstream)->upstream = (Stream *) newnode;
+
+ return newnode;
}
/* ****************
- * parsenodes.h routines have no copy functions
+ * parsenodes.h routines have no copy functions
* ****************
*/
static TargetEntry *
-_copyTargetEntry(TargetEntry *from)
+_copyTargetEntry(TargetEntry * from)
{
- TargetEntry *newnode = makeNode(TargetEntry);
+ TargetEntry *newnode = makeNode(TargetEntry);
- Node_Copy(from, newnode, resdom);
- Node_Copy(from, newnode, fjoin);
- Node_Copy(from, newnode, expr);
- return newnode;
+ Node_Copy(from, newnode, resdom);
+ Node_Copy(from, newnode, fjoin);
+ Node_Copy(from, newnode, expr);
+ return newnode;
}
static RangeTblEntry *
-_copyRangeTblEntry(RangeTblEntry *from)
+_copyRangeTblEntry(RangeTblEntry * from)
{
- RangeTblEntry *newnode = makeNode(RangeTblEntry);
-
- memcpy (newnode, from, sizeof (RangeTblEntry));
- if ( from->relname )
- newnode->relname = pstrdup (from->relname);
- if ( from->refname )
- newnode->refname = pstrdup (from->refname);
- if ( from->timeRange )
- {
- newnode->timeRange = makeNode (TimeRange);
- if ( from->timeRange->startDate )
- newnode->timeRange->startDate = pstrdup (from->timeRange->startDate);
- else
- newnode->timeRange->startDate = NULL;
- if ( from->timeRange->endDate )
- newnode->timeRange->endDate = pstrdup (from->timeRange->endDate);
- else
- newnode->timeRange->endDate = NULL;
- newnode->timeQual = makeTimeRange (newnode->timeRange->startDate,
- newnode->timeRange->endDate,
- ((newnode->timeRange->endDate == NULL) ? 0 : 1));
- }
-
- return newnode;
+ RangeTblEntry *newnode = makeNode(RangeTblEntry);
+
+ memcpy(newnode, from, sizeof(RangeTblEntry));
+ if (from->relname)
+ newnode->relname = pstrdup(from->relname);
+ if (from->refname)
+ newnode->refname = pstrdup(from->refname);
+ if (from->timeRange)
+ {
+ newnode->timeRange = makeNode(TimeRange);
+ if (from->timeRange->startDate)
+ newnode->timeRange->startDate = pstrdup(from->timeRange->startDate);
+ else
+ newnode->timeRange->startDate = NULL;
+ if (from->timeRange->endDate)
+ newnode->timeRange->endDate = pstrdup(from->timeRange->endDate);
+ else
+ newnode->timeRange->endDate = NULL;
+ newnode->timeQual = makeTimeRange(newnode->timeRange->startDate,
+ newnode->timeRange->endDate,
+ ((newnode->timeRange->endDate == NULL) ? 0 : 1));
+ }
+
+ return newnode;
}
static SortClause *
-_copySortClause(SortClause *from)
+_copySortClause(SortClause * from)
{
- SortClause *newnode = makeNode(SortClause);
+ SortClause *newnode = makeNode(SortClause);
+
+ Node_Copy(from, newnode, resdom);
+ newnode->opoid = from->opoid;
- Node_Copy(from, newnode, resdom);
- newnode->opoid = from->opoid;
-
- return newnode;
+ return newnode;
}
static A_Const *
-_copyAConst(A_Const *from)
+_copyAConst(A_Const * from)
{
- A_Const *newnode = makeNode(A_Const);
+ A_Const *newnode = makeNode(A_Const);
- newnode->val = *((Value *)(copyObject(&(from->val))));
- Node_Copy(from, newnode, typename);
+ newnode->val = *((Value *) (copyObject(&(from->val))));
+ Node_Copy(from, newnode, typename);
- return newnode;
+ return newnode;
}
static TypeName *
-_copyTypeName(TypeName *from)
+_copyTypeName(TypeName * from)
{
- TypeName *newnode = makeNode(TypeName);
-
- if(from->name) {
- newnode->name = pstrdup(from->name);
- } else {
- from->name = (char *)0;
- }
- newnode->setof = from->setof;
- Node_Copy(from, newnode, arrayBounds);
- newnode->typlen = from->typlen;
-
- return newnode;
+ TypeName *newnode = makeNode(TypeName);
+
+ if (from->name)
+ {
+ newnode->name = pstrdup(from->name);
+ }
+ else
+ {
+ from->name = (char *) 0;
+ }
+ newnode->setof = from->setof;
+ Node_Copy(from, newnode, arrayBounds);
+ newnode->typlen = from->typlen;
+
+ return newnode;
}
-static Query *
-_copyQuery(Query *from)
+static Query *
+_copyQuery(Query * from)
{
- Query *newnode = makeNode(Query);
-
- newnode->commandType = from->commandType;
- newnode->resultRelation = from->resultRelation;
- /* probably should dup this string instead of just pointing */
- /* to the old one --djm */
- if(from->into) {
- newnode->into = pstrdup(from->into);
- } else {
- newnode->into = (char *)0;
- }
- newnode->isPortal = from->isPortal;
- Node_Copy(from, newnode, rtable);
- if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt) {
- NotifyStmt *from_notify = (NotifyStmt*)from->utilityStmt;
- NotifyStmt *n = makeNode(NotifyStmt);
- int length = strlen(from_notify->relname);
-
- n->relname = palloc(length + 1);
- strcpy(n->relname,from_notify->relname);
- newnode->utilityStmt = (Node*)n;
- }
- if (from->uniqueFlag) {
- newnode->uniqueFlag = (char*)palloc(strlen(from->uniqueFlag)+1);
- strcpy(newnode->uniqueFlag, from->uniqueFlag);
- }
- else
- newnode->uniqueFlag = NULL;
- Node_Copy(from, newnode, sortClause);
- Node_Copy(from, newnode, targetList);
- Node_Copy(from, newnode, qual);
-
- return newnode;
+ Query *newnode = makeNode(Query);
+
+ newnode->commandType = from->commandType;
+ newnode->resultRelation = from->resultRelation;
+ /* probably should dup this string instead of just pointing */
+ /* to the old one --djm */
+ if (from->into)
+ {
+ newnode->into = pstrdup(from->into);
+ }
+ else
+ {
+ newnode->into = (char *) 0;
+ }
+ newnode->isPortal = from->isPortal;
+ Node_Copy(from, newnode, rtable);
+ if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt)
+ {
+ NotifyStmt *from_notify = (NotifyStmt *) from->utilityStmt;
+ NotifyStmt *n = makeNode(NotifyStmt);
+ int length = strlen(from_notify->relname);
+
+ n->relname = palloc(length + 1);
+ strcpy(n->relname, from_notify->relname);
+ newnode->utilityStmt = (Node *) n;
+ }
+ if (from->uniqueFlag)
+ {
+ newnode->uniqueFlag = (char *) palloc(strlen(from->uniqueFlag) + 1);
+ strcpy(newnode->uniqueFlag, from->uniqueFlag);
+ }
+ else
+ newnode->uniqueFlag = NULL;
+ Node_Copy(from, newnode, sortClause);
+ Node_Copy(from, newnode, targetList);
+ Node_Copy(from, newnode, qual);
+
+ return newnode;
}
/* ****************
- * mnodes.h routines have no copy functions
+ * mnodes.h routines have no copy functions
* ****************
*/
/* ****************************************************************
- * pg_list.h copy functions
+ * pg_list.h copy functions
* ****************************************************************
*/
-static Value *
-_copyValue(Value *from)
+static Value *
+_copyValue(Value * from)
{
- Value *newnode = makeNode(Value);
-
- newnode->type = from->type;
- switch(from->type) {
- case T_String:
- newnode->val.str = pstrdup(from->val.str);
- break;
- case T_Integer:
- newnode->val.ival = from->val.ival;
- break;
- case T_Float:
- newnode->val.dval = from->val.dval;
- break;
- default:
- break;
- }
- return newnode;
+ Value *newnode = makeNode(Value);
+
+ newnode->type = from->type;
+ switch (from->type)
+ {
+ case T_String:
+ newnode->val.str = pstrdup(from->val.str);
+ break;
+ case T_Integer:
+ newnode->val.ival = from->val.ival;
+ break;
+ case T_Float:
+ newnode->val.dval = from->val.dval;
+ break;
+ default:
+ break;
+ }
+ return newnode;
}
/* ----------------
- * copyObject returns a copy of the node or list. If it is a list, it
- * recursively copies its items.
+ * copyObject returns a copy of the node or list. If it is a list, it
+ * recursively copies its items.
* ----------------
*/
-void *
+void *
copyObject(void *from)
{
- void *retval;
-
- if (from==NULL)
- return NULL;
- switch(nodeTag(from)) {
- /*
- * PLAN NODES
- */
- case T_Plan:
- retval = _copyPlan(from);
- break;
- case T_Existential:
- retval = _copyExistential(from);
- break;
- case T_Result:
- retval = _copyResult(from);
- break;
- case T_Append:
- retval = _copyAppend(from);
- break;
- case T_Scan:
- retval = _copyScan(from);
- break;
- case T_SeqScan:
- retval = _copySeqScan(from);
- break;
- case T_IndexScan:
- retval = _copyIndexScan(from);
- break;
- case T_Join:
- retval = _copyJoin(from);
- break;
- case T_NestLoop:
- retval = _copyNestLoop(from);
- break;
- case T_MergeJoin:
- retval = _copyMergeJoin(from);
- break;
- case T_HashJoin:
- retval = _copyHashJoin(from);
- break;
- case T_Temp:
- retval = _copyTemp(from);
- break;
- case T_Material:
- retval = _copyMaterial(from);
- break;
- case T_Sort:
- retval = _copySort(from);
- break;
- case T_Agg:
- retval = _copyAgg(from);
- break;
- case T_Unique:
- retval = _copyUnique(from);
- break;
- case T_Hash:
- retval = _copyHash(from);
- break;
-
- /*
- * PRIMITIVE NODES
- */
- case T_Resdom:
- retval = _copyResdom(from);
- break;
- case T_Fjoin:
- retval = _copyFjoin(from);
- break;
- case T_Expr:
- retval = _copyExpr(from);
- break;
- case T_Var:
- retval = _copyVar(from);
- break;
- case T_Oper:
- retval = _copyOper(from);
- break;
- case T_Const:
- retval = _copyConst(from);
- break;
- case T_Param:
- retval = _copyParam(from);
- break;
- case T_Func:
- retval = _copyFunc(from);
- break;
- case T_Array:
- retval = _copyArray(from);
- break;
- case T_ArrayRef:
- retval = _copyArrayRef(from);
- break;
- case T_Aggreg:
- retval = _copyAggreg(from);
- break;
- /*
- * RELATION NODES
- */
- case T_Rel:
- retval = _copyRel(from);
- break;
- case T_Path:
- retval = _copyPath(from);
- break;
- case T_IndexPath:
- retval = _copyIndexPath(from);
- break;
- case T_JoinPath:
- retval = _copyJoinPath(from);
- break;
- case T_MergePath:
- retval = _copyMergePath(from);
- break;
- case T_HashPath:
- retval = _copyHashPath(from);
- break;
- case T_OrderKey:
- retval = _copyOrderKey(from);
- break;
- case T_JoinKey:
- retval = _copyJoinKey(from);
- break;
- case T_MergeOrder:
- retval = _copyMergeOrder(from);
- break;
- case T_CInfo:
- retval = _copyCInfo(from);
- break;
- case T_JoinMethod:
- retval = _copyJoinMethod(from);
- break;
- case T_HInfo:
- retval = _copyHInfo(from);
- break;
- case T_MInfo:
- retval = _copyMInfo(from);
- break;
- case T_JInfo:
- retval = _copyJInfo(from);
- break;
- case T_Iter:
- retval = _copyIter(from);
- break;
- case T_Stream:
- retval = _copyStream(from);
- break;
+ void *retval;
- /*
- * PARSE NODES
- */
- case T_Query:
- retval = _copyQuery(from);
- break;
- case T_TargetEntry:
- retval = _copyTargetEntry(from);
- break;
- case T_RangeTblEntry:
- retval = _copyRangeTblEntry(from);
- break;
- case T_SortClause:
- retval = _copySortClause(from);
- break;
- case T_A_Const:
- retval = _copyAConst(from);
- break;
- case T_TypeName:
- retval = _copyTypeName(from);
- break;
-
- /*
- * VALUE NODES
- */
- case T_Integer: case T_String: case T_Float:
- retval = _copyValue(from);
- break;
- case T_List:
+ if (from == NULL)
+ return NULL;
+ switch (nodeTag(from))
{
- List *list=from, *l;
- List *newlist = NIL, *nl=NIL;
- foreach(l, list) {
- if (newlist==NIL) {
- newlist = nl = lcons(copyObject(lfirst(l)),NIL);
- }else {
- lnext(nl) = lcons(copyObject(lfirst(l)),NIL);
- nl = lnext(nl);
+
+ /*
+ * PLAN NODES
+ */
+ case T_Plan:
+ retval = _copyPlan(from);
+ break;
+ case T_Existential:
+ retval = _copyExistential(from);
+ break;
+ case T_Result:
+ retval = _copyResult(from);
+ break;
+ case T_Append:
+ retval = _copyAppend(from);
+ break;
+ case T_Scan:
+ retval = _copyScan(from);
+ break;
+ case T_SeqScan:
+ retval = _copySeqScan(from);
+ break;
+ case T_IndexScan:
+ retval = _copyIndexScan(from);
+ break;
+ case T_Join:
+ retval = _copyJoin(from);
+ break;
+ case T_NestLoop:
+ retval = _copyNestLoop(from);
+ break;
+ case T_MergeJoin:
+ retval = _copyMergeJoin(from);
+ break;
+ case T_HashJoin:
+ retval = _copyHashJoin(from);
+ break;
+ case T_Temp:
+ retval = _copyTemp(from);
+ break;
+ case T_Material:
+ retval = _copyMaterial(from);
+ break;
+ case T_Sort:
+ retval = _copySort(from);
+ break;
+ case T_Agg:
+ retval = _copyAgg(from);
+ break;
+ case T_Unique:
+ retval = _copyUnique(from);
+ break;
+ case T_Hash:
+ retval = _copyHash(from);
+ break;
+
+ /*
+ * PRIMITIVE NODES
+ */
+ case T_Resdom:
+ retval = _copyResdom(from);
+ break;
+ case T_Fjoin:
+ retval = _copyFjoin(from);
+ break;
+ case T_Expr:
+ retval = _copyExpr(from);
+ break;
+ case T_Var:
+ retval = _copyVar(from);
+ break;
+ case T_Oper:
+ retval = _copyOper(from);
+ break;
+ case T_Const:
+ retval = _copyConst(from);
+ break;
+ case T_Param:
+ retval = _copyParam(from);
+ break;
+ case T_Func:
+ retval = _copyFunc(from);
+ break;
+ case T_Array:
+ retval = _copyArray(from);
+ break;
+ case T_ArrayRef:
+ retval = _copyArrayRef(from);
+ break;
+ case T_Aggreg:
+ retval = _copyAggreg(from);
+ break;
+
+ /*
+ * RELATION NODES
+ */
+ case T_Rel:
+ retval = _copyRel(from);
+ break;
+ case T_Path:
+ retval = _copyPath(from);
+ break;
+ case T_IndexPath:
+ retval = _copyIndexPath(from);
+ break;
+ case T_JoinPath:
+ retval = _copyJoinPath(from);
+ break;
+ case T_MergePath:
+ retval = _copyMergePath(from);
+ break;
+ case T_HashPath:
+ retval = _copyHashPath(from);
+ break;
+ case T_OrderKey:
+ retval = _copyOrderKey(from);
+ break;
+ case T_JoinKey:
+ retval = _copyJoinKey(from);
+ break;
+ case T_MergeOrder:
+ retval = _copyMergeOrder(from);
+ break;
+ case T_CInfo:
+ retval = _copyCInfo(from);
+ break;
+ case T_JoinMethod:
+ retval = _copyJoinMethod(from);
+ break;
+ case T_HInfo:
+ retval = _copyHInfo(from);
+ break;
+ case T_MInfo:
+ retval = _copyMInfo(from);
+ break;
+ case T_JInfo:
+ retval = _copyJInfo(from);
+ break;
+ case T_Iter:
+ retval = _copyIter(from);
+ break;
+ case T_Stream:
+ retval = _copyStream(from);
+ break;
+
+ /*
+ * PARSE NODES
+ */
+ case T_Query:
+ retval = _copyQuery(from);
+ break;
+ case T_TargetEntry:
+ retval = _copyTargetEntry(from);
+ break;
+ case T_RangeTblEntry:
+ retval = _copyRangeTblEntry(from);
+ break;
+ case T_SortClause:
+ retval = _copySortClause(from);
+ break;
+ case T_A_Const:
+ retval = _copyAConst(from);
+ break;
+ case T_TypeName:
+ retval = _copyTypeName(from);
+ break;
+
+ /*
+ * VALUE NODES
+ */
+ case T_Integer:
+ case T_String:
+ case T_Float:
+ retval = _copyValue(from);
+ break;
+ case T_List:
+ {
+ List *list = from,
+ *l;
+ List *newlist = NIL,
+ *nl = NIL;
+
+ foreach(l, list)
+ {
+ if (newlist == NIL)
+ {
+ newlist = nl = lcons(copyObject(lfirst(l)), NIL);
+ }
+ else
+ {
+ lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
+ nl = lnext(nl);
+ }
+ }
+ retval = newlist;
}
- }
- retval = newlist;
+ break;
+ default:
+ elog(NOTICE, "copyObject: don't know how to copy %d", nodeTag(from));
+ retval = from;
+ break;
}
- break;
- default:
- elog(NOTICE, "copyObject: don't know how to copy %d", nodeTag(from));
- retval = from;
- break;
- }
- return retval;
+ return retval;
}
-
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 4a8a072d33f..792c8783f99 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* equalfuncs.c--
- * equal functions to compare the nodes
+ * equal functions to compare the nodes
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.6 1997/08/19 21:31:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.7 1997/09/07 04:42:44 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,700 +26,717 @@
#include "utils/elog.h"
#include "storage/itemptr.h"
-static bool equali(List *a, List *b);
+static bool equali(List * a, List * b);
/*
- * Stuff from primnodes.h
+ * Stuff from primnodes.h
*/
/*
- * Resdom is a subclass of Node.
+ * Resdom is a subclass of Node.
*/
-static bool
-_equalResdom(Resdom *a, Resdom *b)
+static bool
+_equalResdom(Resdom * a, Resdom * b)
{
- if (a->resno != b->resno)
- return (false);
- if (a->restype != b->restype)
- return (false);
- if (a->reslen != b->reslen)
- return (false);
- if (strcmp(a->resname, b->resname) != 0)
- return (false);
- if (a->reskey != b->reskey)
- return (false);
- if (a->reskeyop != b->reskeyop)
- return (false);
-
- return (true);
+ if (a->resno != b->resno)
+ return (false);
+ if (a->restype != b->restype)
+ return (false);
+ if (a->reslen != b->reslen)
+ return (false);
+ if (strcmp(a->resname, b->resname) != 0)
+ return (false);
+ if (a->reskey != b->reskey)
+ return (false);
+ if (a->reskeyop != b->reskeyop)
+ return (false);
+
+ return (true);
}
-static bool
-_equalFjoin(Fjoin *a, Fjoin *b)
+static bool
+_equalFjoin(Fjoin * a, Fjoin * b)
{
- int nNodes;
-
- if (a->fj_initialized != b->fj_initialized)
- return (false);
- if (a->fj_nNodes != b->fj_nNodes)
- return (false);
- if (!equal(a->fj_innerNode, b->fj_innerNode))
- return (false);
-
- nNodes = a->fj_nNodes;
- if (memcmp(a->fj_results, b->fj_results, nNodes*sizeof(Datum)) != 0)
- return (false);
- if (memcmp(a->fj_alwaysDone, b->fj_alwaysDone, nNodes*sizeof(bool)) != 0)
- return (false);
-
- return(true);
+ int nNodes;
+
+ if (a->fj_initialized != b->fj_initialized)
+ return (false);
+ if (a->fj_nNodes != b->fj_nNodes)
+ return (false);
+ if (!equal(a->fj_innerNode, b->fj_innerNode))
+ return (false);
+
+ nNodes = a->fj_nNodes;
+ if (memcmp(a->fj_results, b->fj_results, nNodes * sizeof(Datum)) != 0)
+ return (false);
+ if (memcmp(a->fj_alwaysDone, b->fj_alwaysDone, nNodes * sizeof(bool)) != 0)
+ return (false);
+
+ return (true);
}
/*
- * Expr is a subclass of Node.
+ * Expr is a subclass of Node.
*/
-static bool
-_equalExpr(Expr *a, Expr *b)
+static bool
+_equalExpr(Expr * a, Expr * b)
{
- if (a->opType != b->opType)
- return (false);
- if (!equal(a->oper, b->oper))
- return (false);
- if (!equal(a->args, b->args))
- return (false);
-
- return (true);
+ if (a->opType != b->opType)
+ return (false);
+ if (!equal(a->oper, b->oper))
+ return (false);
+ if (!equal(a->args, b->args))
+ return (false);
+
+ return (true);
}
-static bool
-_equalIter(Iter *a, Iter *b)
+static bool
+_equalIter(Iter * a, Iter * b)
{
- return (equal(a->iterexpr, b->iterexpr));
+ return (equal(a->iterexpr, b->iterexpr));
}
-static bool
-_equalStream(Stream *a, Stream *b)
+static bool
+_equalStream(Stream * a, Stream * b)
{
- if (a->clausetype != b->clausetype)
- return(false);
- if (a->groupup != b->groupup)
- return(false);
- if (a->groupcost != b->groupcost)
- return(false);
- if (a->groupsel != b->groupsel)
- return(false);
- if (!equal(a->pathptr, b->pathptr))
- return(false);
- if (!equal(a->cinfo, b->cinfo))
- return(false);
- if (!equal(a->upstream, b->upstream))
- return(false);
- return(equal(a->downstream, b->downstream));
+ if (a->clausetype != b->clausetype)
+ return (false);
+ if (a->groupup != b->groupup)
+ return (false);
+ if (a->groupcost != b->groupcost)
+ return (false);
+ if (a->groupsel != b->groupsel)
+ return (false);
+ if (!equal(a->pathptr, b->pathptr))
+ return (false);
+ if (!equal(a->cinfo, b->cinfo))
+ return (false);
+ if (!equal(a->upstream, b->upstream))
+ return (false);
+ return (equal(a->downstream, b->downstream));
}
/*
- * Var is a subclass of Expr.
+ * Var is a subclass of Expr.
*/
-static bool
-_equalVar(Var *a, Var *b)
+static bool
+_equalVar(Var * a, Var * b)
{
- if (a->varno != b->varno)
- return (false);
- if (a->varattno != b->varattno)
- return (false);
- if (a->vartype != b->vartype)
- return (false);
- if (a->varnoold != b->varnoold)
- return (false);
- if (a->varoattno != b->varoattno)
- return (false);
-
- return (true);
+ if (a->varno != b->varno)
+ return (false);
+ if (a->varattno != b->varattno)
+ return (false);
+ if (a->vartype != b->vartype)
+ return (false);
+ if (a->varnoold != b->varnoold)
+ return (false);
+ if (a->varoattno != b->varoattno)
+ return (false);
+
+ return (true);
}
-static bool
-_equalArray(Array *a, Array *b)
+static bool
+_equalArray(Array * a, Array * b)
{
- if (a->arrayelemtype != b->arrayelemtype)
- return (false);
- if (a->arrayndim != b->arrayndim)
- return (false);
- if (a->arraylow.indx[0] != b->arraylow.indx[0])
- return (false);
- if (a->arrayhigh.indx[0] != b->arrayhigh.indx[0])
- return (false);
- if (a->arraylen != b->arraylen)
- return (false);
- return(TRUE);
+ if (a->arrayelemtype != b->arrayelemtype)
+ return (false);
+ if (a->arrayndim != b->arrayndim)
+ return (false);
+ if (a->arraylow.indx[0] != b->arraylow.indx[0])
+ return (false);
+ if (a->arrayhigh.indx[0] != b->arrayhigh.indx[0])
+ return (false);
+ if (a->arraylen != b->arraylen)
+ return (false);
+ return (TRUE);
}
-static bool
-_equalArrayRef(ArrayRef *a, ArrayRef *b)
+static bool
+_equalArrayRef(ArrayRef * a, ArrayRef * b)
{
- if (a->refelemtype != b->refelemtype)
- return (false);
- if (a->refattrlength != b->refattrlength)
- return (false);
- if (a->refelemlength != b->refelemlength)
- return (false);
- if (a->refelembyval != b->refelembyval)
- return (false);
- if (!equal(a->refupperindexpr, b->refupperindexpr))
- return (false);
- if (!equal(a->reflowerindexpr, b->reflowerindexpr))
- return (false);
- if (!equal(a->refexpr, b->refexpr))
- return (false);
- return (equal(a->refassgnexpr, b->refassgnexpr));
+ if (a->refelemtype != b->refelemtype)
+ return (false);
+ if (a->refattrlength != b->refattrlength)
+ return (false);
+ if (a->refelemlength != b->refelemlength)
+ return (false);
+ if (a->refelembyval != b->refelembyval)
+ return (false);
+ if (!equal(a->refupperindexpr, b->refupperindexpr))
+ return (false);
+ if (!equal(a->reflowerindexpr, b->reflowerindexpr))
+ return (false);
+ if (!equal(a->refexpr, b->refexpr))
+ return (false);
+ return (equal(a->refassgnexpr, b->refassgnexpr));
}
/*
- * Oper is a subclass of Expr.
+ * Oper is a subclass of Expr.
*/
-static bool
-_equalOper(Oper *a, Oper *b)
+static bool
+_equalOper(Oper * a, Oper * b)
{
- if (a->opno != b->opno)
- return (false);
- if (a->opresulttype != b->opresulttype)
- return (false);
-
- return (true);
+ if (a->opno != b->opno)
+ return (false);
+ if (a->opresulttype != b->opresulttype)
+ return (false);
+
+ return (true);
}
/*
- * Const is a subclass of Expr.
+ * Const is a subclass of Expr.
*/
-static bool
-_equalConst(Const *a, Const *b)
+static bool
+_equalConst(Const * a, Const * b)
{
- /*
- ** this function used to do a pointer compare on a and b. That's
- ** ridiculous. -- JMH, 7/11/92
- */
- if (a->consttype != b->consttype)
- return(false);
- if (a->constlen != b->constlen)
- return(false);
- if (a->constisnull != b->constisnull)
- return(false);
- if (a->constbyval != b->constbyval)
- return(false);
- return(datumIsEqual(a->constvalue, b->constvalue,
- a->consttype, a->constbyval, a->constlen));
+
+ /*
+ * * this function used to do a pointer compare on a and b. That's *
+ * ridiculous. -- JMH, 7/11/92
+ */
+ if (a->consttype != b->consttype)
+ return (false);
+ if (a->constlen != b->constlen)
+ return (false);
+ if (a->constisnull != b->constisnull)
+ return (false);
+ if (a->constbyval != b->constbyval)
+ return (false);
+ return (datumIsEqual(a->constvalue, b->constvalue,
+ a->consttype, a->constbyval, a->constlen));
}
/*
- * Param is a subclass of Expr.
+ * Param is a subclass of Expr.
*/
-static bool
-_equalParam(Param *a, Param *b)
+static bool
+_equalParam(Param * a, Param * b)
{
- if (a->paramkind != b->paramkind)
- return (false);
- if (a->paramtype != b->paramtype)
- return (false);
- if (!equal(a->param_tlist, b->param_tlist))
- return (false);
-
- switch (a->paramkind) {
- case PARAM_NAMED:
- case PARAM_NEW:
- case PARAM_OLD:
- if (strcmp(a->paramname, b->paramname) != 0)
- return (false);
- break;
- case PARAM_NUM:
- if (a->paramid != b->paramid)
- return (false);
- break;
- case PARAM_INVALID:
- /*
- * XXX: Hmmm... What are we supposed to return
- * in this case ??
- */
- return(true);
- break;
- default:
- elog(WARN, "_equalParam: Invalid paramkind value: %d",
- a->paramkind);
- }
-
- return (true);
+ if (a->paramkind != b->paramkind)
+ return (false);
+ if (a->paramtype != b->paramtype)
+ return (false);
+ if (!equal(a->param_tlist, b->param_tlist))
+ return (false);
+
+ switch (a->paramkind)
+ {
+ case PARAM_NAMED:
+ case PARAM_NEW:
+ case PARAM_OLD:
+ if (strcmp(a->paramname, b->paramname) != 0)
+ return (false);
+ break;
+ case PARAM_NUM:
+ if (a->paramid != b->paramid)
+ return (false);
+ break;
+ case PARAM_INVALID:
+
+ /*
+ * XXX: Hmmm... What are we supposed to return in this case ??
+ */
+ return (true);
+ break;
+ default:
+ elog(WARN, "_equalParam: Invalid paramkind value: %d",
+ a->paramkind);
+ }
+
+ return (true);
}
/*
- * Func is a subclass of Expr.
+ * Func is a subclass of Expr.
*/
-static bool
-_equalFunc(Func *a, Func *b)
+static bool
+_equalFunc(Func * a, Func * b)
{
- if (a->funcid != b->funcid)
- return (false);
- if (a->functype != b->functype)
- return (false);
- if (a->funcisindex != b->funcisindex)
- return (false);
- if (a->funcsize != b->funcsize)
- return (false);
- if (!equal(a->func_tlist, b->func_tlist))
- return (false);
- if (!equal(a->func_planlist, b->func_planlist))
- return (false);
-
- return (true);
+ if (a->funcid != b->funcid)
+ return (false);
+ if (a->functype != b->functype)
+ return (false);
+ if (a->funcisindex != b->funcisindex)
+ return (false);
+ if (a->funcsize != b->funcsize)
+ return (false);
+ if (!equal(a->func_tlist, b->func_tlist))
+ return (false);
+ if (!equal(a->func_planlist, b->func_planlist))
+ return (false);
+
+ return (true);
}
/*
* CInfo is a subclass of Node.
*/
-static bool
-_equalCInfo(CInfo *a, CInfo *b)
+static bool
+_equalCInfo(CInfo * a, CInfo * b)
{
- Assert(IsA(a,CInfo));
- Assert(IsA(b,CInfo));
-
- if (!equal(a->clause, b->clause))
- return(false);
- if (a->selectivity != b->selectivity)
- return(false);
- if (a->notclause != b->notclause)
- return(false);
+ Assert(IsA(a, CInfo));
+ Assert(IsA(b, CInfo));
+
+ if (!equal(a->clause, b->clause))
+ return (false);
+ if (a->selectivity != b->selectivity)
+ return (false);
+ if (a->notclause != b->notclause)
+ return (false);
#ifdef EqualMergeOrderExists
- if (!EqualMergeOrder(a->mergesortorder,b->mergesortorder))
- return(false);
+ if (!EqualMergeOrder(a->mergesortorder, b->mergesortorder))
+ return (false);
#endif
- if(a->hashjoinoperator != b->hashjoinoperator)
- return(false);
- return(equal((a->indexids),
- (b->indexids)));
+ if (a->hashjoinoperator != b->hashjoinoperator)
+ return (false);
+ return (equal((a->indexids),
+ (b->indexids)));
}
-static bool
-_equalJoinMethod(JoinMethod *a, JoinMethod *b)
+static bool
+_equalJoinMethod(JoinMethod * a, JoinMethod * b)
{
- Assert(IsA(a,JoinMethod));
- Assert(IsA(b,JoinMethod));
-
- if (!equal((a->jmkeys),
- (b->jmkeys)))
- return(false);
- if (!equal((a->clauses),
- (b->clauses)))
- return(false);
- return(true);
+ Assert(IsA(a, JoinMethod));
+ Assert(IsA(b, JoinMethod));
+
+ if (!equal((a->jmkeys),
+ (b->jmkeys)))
+ return (false);
+ if (!equal((a->clauses),
+ (b->clauses)))
+ return (false);
+ return (true);
}
-static bool
-_equalPath(Path *a, Path *b)
+static bool
+_equalPath(Path * a, Path * b)
{
- if (a->pathtype != b->pathtype)
- return(false);
- if (a->parent != b->parent)
- return(false);
- /*
- if (a->path_cost != b->path_cost)
- return(false);
- */
- if (a->p_ordering.ordtype == SORTOP_ORDER) {
- int i = 0;
- if (a->p_ordering.ord.sortop==NULL ||
- b->p_ordering.ord.sortop==NULL) {
-
- if (a->p_ordering.ord.sortop != b->p_ordering.ord.sortop)
- return false;
- } else {
- while(a->p_ordering.ord.sortop[i]!=0 &&
- b->p_ordering.ord.sortop[i]!=0) {
- if (a->p_ordering.ord.sortop[i] != b->p_ordering.ord.sortop[i])
- return false;
- i++;
- }
- if (a->p_ordering.ord.sortop[i]!=0 ||
- b->p_ordering.ord.sortop[i]!=0)
- return false;
+ if (a->pathtype != b->pathtype)
+ return (false);
+ if (a->parent != b->parent)
+ return (false);
+
+ /*
+ * if (a->path_cost != b->path_cost) return(false);
+ */
+ if (a->p_ordering.ordtype == SORTOP_ORDER)
+ {
+ int i = 0;
+
+ if (a->p_ordering.ord.sortop == NULL ||
+ b->p_ordering.ord.sortop == NULL)
+ {
+
+ if (a->p_ordering.ord.sortop != b->p_ordering.ord.sortop)
+ return false;
+ }
+ else
+ {
+ while (a->p_ordering.ord.sortop[i] != 0 &&
+ b->p_ordering.ord.sortop[i] != 0)
+ {
+ if (a->p_ordering.ord.sortop[i] != b->p_ordering.ord.sortop[i])
+ return false;
+ i++;
+ }
+ if (a->p_ordering.ord.sortop[i] != 0 ||
+ b->p_ordering.ord.sortop[i] != 0)
+ return false;
+ }
+ }
+ else
+ {
+ if (!equal((a->p_ordering.ord.merge),
+ (b->p_ordering.ord.merge)))
+ return (false);
}
- } else {
- if (!equal((a->p_ordering.ord.merge),
- (b->p_ordering.ord.merge)))
- return(false);
- }
- if (!equal((a->keys),
- (b->keys)))
- return(false);
- /*
- if (a->outerjoincost != b->outerjoincost)
- return(false);
- */
- if (!equali((a->joinid),
- (b->joinid)))
- return(false);
- return(true);
+ if (!equal((a->keys),
+ (b->keys)))
+ return (false);
+
+ /*
+ * if (a->outerjoincost != b->outerjoincost) return(false);
+ */
+ if (!equali((a->joinid),
+ (b->joinid)))
+ return (false);
+ return (true);
}
-static bool
-_equalIndexPath(IndexPath *a, IndexPath *b)
+static bool
+_equalIndexPath(IndexPath * a, IndexPath * b)
{
- if (!_equalPath((Path*)a,(Path*)b))
- return(false);
- if (!equali((a->indexid), (b->indexid)))
- return(false);
- if (!equal((a->indexqual), (b->indexqual)))
- return(false);
- return(true);
+ if (!_equalPath((Path *) a, (Path *) b))
+ return (false);
+ if (!equali((a->indexid), (b->indexid)))
+ return (false);
+ if (!equal((a->indexqual), (b->indexqual)))
+ return (false);
+ return (true);
}
-static bool
-_equalJoinPath(JoinPath *a,JoinPath *b)
+static bool
+_equalJoinPath(JoinPath * a, JoinPath * b)
{
- Assert(IsA_JoinPath(a));
- Assert(IsA_JoinPath(b));
-
- if (!_equalPath((Path*)a,(Path*)b))
- return(false);
- if (!equal((a->pathclauseinfo), (b->pathclauseinfo)))
- return(false);
- if (!equal((a->outerjoinpath), (b->outerjoinpath)))
- return(false);
- if (!equal((a->innerjoinpath), (b->innerjoinpath)))
- return(false);
- return(true);
+ Assert(IsA_JoinPath(a));
+ Assert(IsA_JoinPath(b));
+
+ if (!_equalPath((Path *) a, (Path *) b))
+ return (false);
+ if (!equal((a->pathclauseinfo), (b->pathclauseinfo)))
+ return (false);
+ if (!equal((a->outerjoinpath), (b->outerjoinpath)))
+ return (false);
+ if (!equal((a->innerjoinpath), (b->innerjoinpath)))
+ return (false);
+ return (true);
}
-static bool
-_equalMergePath(MergePath *a, MergePath *b)
+static bool
+_equalMergePath(MergePath * a, MergePath * b)
{
- Assert(IsA(a,MergePath));
- Assert(IsA(b,MergePath));
-
- if (!_equalJoinPath((JoinPath*)a,(JoinPath*)b))
- return(false);
- if (!equal((a->path_mergeclauses), (b->path_mergeclauses)))
- return(false);
- if (!equal((a->outersortkeys), (b->outersortkeys)))
- return(false);
- if (!equal((a->innersortkeys), (b->innersortkeys)))
- return(false);
- return(true);
+ Assert(IsA(a, MergePath));
+ Assert(IsA(b, MergePath));
+
+ if (!_equalJoinPath((JoinPath *) a, (JoinPath *) b))
+ return (false);
+ if (!equal((a->path_mergeclauses), (b->path_mergeclauses)))
+ return (false);
+ if (!equal((a->outersortkeys), (b->outersortkeys)))
+ return (false);
+ if (!equal((a->innersortkeys), (b->innersortkeys)))
+ return (false);
+ return (true);
}
-static bool
-_equalHashPath(HashPath *a, HashPath *b)
+static bool
+_equalHashPath(HashPath * a, HashPath * b)
{
- Assert(IsA(a,HashPath));
- Assert(IsA(b,HashPath));
-
- if (!_equalJoinPath((JoinPath*)a,(JoinPath*)b))
- return(false);
- if (!equal((a->path_hashclauses), (b->path_hashclauses)))
- return(false);
- if (!equal((a->outerhashkeys), (b->outerhashkeys)))
- return(false);
- if (!equal((a->innerhashkeys), (b->innerhashkeys)))
- return(false);
- return(true);
+ Assert(IsA(a, HashPath));
+ Assert(IsA(b, HashPath));
+
+ if (!_equalJoinPath((JoinPath *) a, (JoinPath *) b))
+ return (false);
+ if (!equal((a->path_hashclauses), (b->path_hashclauses)))
+ return (false);
+ if (!equal((a->outerhashkeys), (b->outerhashkeys)))
+ return (false);
+ if (!equal((a->innerhashkeys), (b->innerhashkeys)))
+ return (false);
+ return (true);
}
-static bool
-_equalJoinKey(JoinKey *a, JoinKey *b)
+static bool
+_equalJoinKey(JoinKey * a, JoinKey * b)
{
- Assert(IsA(a,JoinKey));
- Assert(IsA(b,JoinKey));
-
- if (!equal((a->outer),(b->outer)))
- return(false);
- if (!equal((a->inner),(b->inner)))
- return(false);
- return(true);
+ Assert(IsA(a, JoinKey));
+ Assert(IsA(b, JoinKey));
+
+ if (!equal((a->outer), (b->outer)))
+ return (false);
+ if (!equal((a->inner), (b->inner)))
+ return (false);
+ return (true);
}
-static bool
-_equalMergeOrder(MergeOrder *a, MergeOrder *b)
+static bool
+_equalMergeOrder(MergeOrder * a, MergeOrder * b)
{
- if (a == (MergeOrder*)NULL && b == (MergeOrder*)NULL)
- return(true);
- Assert(IsA(a,MergeOrder));
- Assert(IsA(b,MergeOrder));
-
- if (a->join_operator != b->join_operator)
- return(false);
- if (a->left_operator != b->left_operator)
- return(false);
- if (a->right_operator != b->right_operator)
- return(false);
- if (a->left_type != b->left_type)
- return(false);
- if (a->right_type != b->right_type)
- return(false);
- return(true);
+ if (a == (MergeOrder *) NULL && b == (MergeOrder *) NULL)
+ return (true);
+ Assert(IsA(a, MergeOrder));
+ Assert(IsA(b, MergeOrder));
+
+ if (a->join_operator != b->join_operator)
+ return (false);
+ if (a->left_operator != b->left_operator)
+ return (false);
+ if (a->right_operator != b->right_operator)
+ return (false);
+ if (a->left_type != b->left_type)
+ return (false);
+ if (a->right_type != b->right_type)
+ return (false);
+ return (true);
}
-static bool
-_equalHInfo(HInfo *a, HInfo *b)
+static bool
+_equalHInfo(HInfo * a, HInfo * b)
{
- Assert(IsA(a,HInfo));
- Assert(IsA(b,HInfo));
-
- if (a->hashop != b->hashop)
- return(false);
- return(true);
+ Assert(IsA(a, HInfo));
+ Assert(IsA(b, HInfo));
+
+ if (a->hashop != b->hashop)
+ return (false);
+ return (true);
}
-/* XXX This equality function is a quick hack, should be
- * fixed to compare all fields.
+/* XXX This equality function is a quick hack, should be
+ * fixed to compare all fields.
*/
-static bool
-_equalIndexScan(IndexScan *a, IndexScan *b)
+static bool
+_equalIndexScan(IndexScan * a, IndexScan * b)
{
- Assert(IsA(a,IndexScan));
- Assert(IsA(b,IndexScan));
-
- /*
- if(a->scan.plan.cost != b->scan.plan.cost)
- return(false);
- */
-
- if (!equal((a->indxqual),(b->indxqual)))
- return(false);
-
- if (a->scan.scanrelid != b->scan.scanrelid)
- return(false);
-
- if (!equali((a->indxid),(b->indxid)))
- return(false);
- return(true);
+ Assert(IsA(a, IndexScan));
+ Assert(IsA(b, IndexScan));
+
+ /*
+ * if(a->scan.plan.cost != b->scan.plan.cost) return(false);
+ */
+
+ if (!equal((a->indxqual), (b->indxqual)))
+ return (false);
+
+ if (a->scan.scanrelid != b->scan.scanrelid)
+ return (false);
+
+ if (!equali((a->indxid), (b->indxid)))
+ return (false);
+ return (true);
}
-static bool
-_equalJInfo(JInfo *a, JInfo *b)
+static bool
+_equalJInfo(JInfo * a, JInfo * b)
{
- Assert(IsA(a,JInfo));
- Assert(IsA(b,JInfo));
- if (!equal((a->otherrels),(b->otherrels)))
- return(false);
- if (!equal((a->jinfoclauseinfo),(b->jinfoclauseinfo)))
- return(false);
- if (a->mergesortable != b->mergesortable)
- return(false);
- if (a->hashjoinable != b->hashjoinable)
- return(false);
- return(true);
+ Assert(IsA(a, JInfo));
+ Assert(IsA(b, JInfo));
+ if (!equal((a->otherrels), (b->otherrels)))
+ return (false);
+ if (!equal((a->jinfoclauseinfo), (b->jinfoclauseinfo)))
+ return (false);
+ if (a->mergesortable != b->mergesortable)
+ return (false);
+ if (a->hashjoinable != b->hashjoinable)
+ return (false);
+ return (true);
}
/*
- * Stuff from execnodes.h
+ * Stuff from execnodes.h
*/
/*
- * EState is a subclass of Node.
+ * EState is a subclass of Node.
*/
-static bool
-_equalEState(EState *a, EState *b)
+static bool
+_equalEState(EState * a, EState * b)
{
- if (a->es_direction != b->es_direction)
- return (false);
-
- if (!equal(a->es_range_table, b->es_range_table))
- return (false);
-
- if (a->es_result_relation_info != b->es_result_relation_info)
- return (false);
-
- return (true);
+ if (a->es_direction != b->es_direction)
+ return (false);
+
+ if (!equal(a->es_range_table, b->es_range_table))
+ return (false);
+
+ if (a->es_result_relation_info != b->es_result_relation_info)
+ return (false);
+
+ return (true);
}
-static bool
-_equalTargetEntry(TargetEntry *a, TargetEntry *b)
+static bool
+_equalTargetEntry(TargetEntry * a, TargetEntry * b)
{
- if (!equal(a->resdom,b->resdom))
- return(false);
- if (!equal(a->fjoin,b->fjoin))
- return(false);
- if (!equal(a->expr,b->expr))
- return(false);
-
- return(true);
+ if (!equal(a->resdom, b->resdom))
+ return (false);
+ if (!equal(a->fjoin, b->fjoin))
+ return (false);
+ if (!equal(a->expr, b->expr))
+ return (false);
+
+ return (true);
}
/*
- * equal -- are two lists equal?
+ * equal -- are two lists equal?
*
- * This is a comparison by value. It would be simpler to write it
- * to be recursive, but it should run faster if we iterate.
+ * This is a comparison by value. It would be simpler to write it
+ * to be recursive, but it should run faster if we iterate.
*/
-static bool
-_equalValue(Value *a, Value *b)
+static bool
+_equalValue(Value * a, Value * b)
{
- if (a->type != b->type)
- return (false);
-
- switch(a->type) {
- case T_String:
- return strcmp(a->val.str, b->val.str);
- case T_Integer:
- return (a->val.ival==b->val.ival);
- case T_Float:
- return (a->val.dval==b->val.dval);
- default:
- break;
- }
-
- return (true);
+ if (a->type != b->type)
+ return (false);
+
+ switch (a->type)
+ {
+ case T_String:
+ return strcmp(a->val.str, b->val.str);
+ case T_Integer:
+ return (a->val.ival == b->val.ival);
+ case T_Float:
+ return (a->val.dval == b->val.dval);
+ default:
+ break;
+ }
+
+ return (true);
}
/*
* equal--
- * returns whether two nodes are equal
+ * returns whether two nodes are equal
*/
bool
equal(void *a, void *b)
{
- bool retval=false;
-
- if (a == b)
- return(true);
- /*
- * note that a!=b, so only one of them can be NULL
- */
- if (a==NULL || b==NULL)
- return (false);
- /*
- * are they the same type of nodes?
- */
- if (nodeTag(a)!=nodeTag(b))
- return (false);
-
- switch(nodeTag(a)) {
- case T_Resdom:
- retval = _equalResdom(a, b);
- break;
- case T_Fjoin:
- retval = _equalFjoin(a, b);
- break;
- case T_Expr:
- retval = _equalExpr(a, b);
- break;
- case T_TargetEntry:
- retval = _equalTargetEntry(a,b);
- break;
- case T_Iter:
- retval = _equalIter(a, b);
- break;
- case T_Stream:
- retval = _equalStream(a, b);
- break;
- case T_Var:
- retval = _equalVar(a, b);
- break;
- case T_Array:
- retval = _equalArray(a, b);
- break;
- case T_ArrayRef:
- retval = _equalArrayRef(a, b);
- break;
- case T_Oper:
- retval = _equalOper(a, b);
- break;
- case T_Const:
- retval = _equalConst(a, b);
- break;
- case T_Param:
- retval = _equalParam(a, b);
- break;
- case T_Func:
- retval = _equalFunc(a, b);
- break;
- case T_CInfo:
- retval = _equalCInfo(a, b);
- break;
- case T_JoinMethod:
- retval = _equalJoinMethod(a, b);
- break;
- case T_Path:
- retval = _equalPath(a, b);
- break;
- case T_IndexPath:
- retval = _equalIndexPath(a, b);
- break;
- case T_JoinPath:
- retval = _equalJoinPath(a, b);
- break;
- case T_MergePath:
- retval = _equalMergePath(a, b);
- break;
- case T_HashPath:
- retval = _equalHashPath(a, b);
- break;
- case T_JoinKey:
- retval = _equalJoinKey(a, b);
- break;
- case T_MergeOrder:
- retval = _equalMergeOrder(a, b);
- break;
- case T_HInfo:
- retval = _equalHInfo(a, b);
- break;
- case T_IndexScan:
- retval = _equalIndexScan(a, b);
- break;
- case T_JInfo:
- retval = _equalJInfo(a, b);
- break;
- case T_EState:
- retval = _equalEState(a, b);
- break;
- case T_Integer: case T_String: case T_Float:
- retval = _equalValue(a, b);
- break;
- case T_List:
- {
- List *la = (List*)a;
- List *lb = (List*)b;
- List *l;
+ bool retval = false;
- if (a==NULL && b==NULL)
+ if (a == b)
return (true);
- if (length(a)!=length(b))
+
+ /*
+ * note that a!=b, so only one of them can be NULL
+ */
+ if (a == NULL || b == NULL)
return (false);
- foreach(l, la) {
- if (!equal(lfirst(l), lfirst(lb)))
- return (false);
- lb = lnext(lb);
- }
- retval = true;
+
+ /*
+ * are they the same type of nodes?
+ */
+ if (nodeTag(a) != nodeTag(b))
+ return (false);
+
+ switch (nodeTag(a))
+ {
+ case T_Resdom:
+ retval = _equalResdom(a, b);
+ break;
+ case T_Fjoin:
+ retval = _equalFjoin(a, b);
+ break;
+ case T_Expr:
+ retval = _equalExpr(a, b);
+ break;
+ case T_TargetEntry:
+ retval = _equalTargetEntry(a, b);
+ break;
+ case T_Iter:
+ retval = _equalIter(a, b);
+ break;
+ case T_Stream:
+ retval = _equalStream(a, b);
+ break;
+ case T_Var:
+ retval = _equalVar(a, b);
+ break;
+ case T_Array:
+ retval = _equalArray(a, b);
+ break;
+ case T_ArrayRef:
+ retval = _equalArrayRef(a, b);
+ break;
+ case T_Oper:
+ retval = _equalOper(a, b);
+ break;
+ case T_Const:
+ retval = _equalConst(a, b);
+ break;
+ case T_Param:
+ retval = _equalParam(a, b);
+ break;
+ case T_Func:
+ retval = _equalFunc(a, b);
+ break;
+ case T_CInfo:
+ retval = _equalCInfo(a, b);
+ break;
+ case T_JoinMethod:
+ retval = _equalJoinMethod(a, b);
+ break;
+ case T_Path:
+ retval = _equalPath(a, b);
+ break;
+ case T_IndexPath:
+ retval = _equalIndexPath(a, b);
+ break;
+ case T_JoinPath:
+ retval = _equalJoinPath(a, b);
+ break;
+ case T_MergePath:
+ retval = _equalMergePath(a, b);
+ break;
+ case T_HashPath:
+ retval = _equalHashPath(a, b);
+ break;
+ case T_JoinKey:
+ retval = _equalJoinKey(a, b);
+ break;
+ case T_MergeOrder:
+ retval = _equalMergeOrder(a, b);
+ break;
+ case T_HInfo:
+ retval = _equalHInfo(a, b);
+ break;
+ case T_IndexScan:
+ retval = _equalIndexScan(a, b);
+ break;
+ case T_JInfo:
+ retval = _equalJInfo(a, b);
+ break;
+ case T_EState:
+ retval = _equalEState(a, b);
+ break;
+ case T_Integer:
+ case T_String:
+ case T_Float:
+ retval = _equalValue(a, b);
+ break;
+ case T_List:
+ {
+ List *la = (List *) a;
+ List *lb = (List *) b;
+ List *l;
+
+ if (a == NULL && b == NULL)
+ return (true);
+ if (length(a) != length(b))
+ return (false);
+ foreach(l, la)
+ {
+ if (!equal(lfirst(l), lfirst(lb)))
+ return (false);
+ lb = lnext(lb);
+ }
+ retval = true;
+ }
+ break;
+ default:
+ elog(NOTICE, "equal: don't know whether nodes of type %d are equal",
+ nodeTag(a));
+ break;
}
- break;
- default:
- elog(NOTICE, "equal: don't know whether nodes of type %d are equal",
- nodeTag(a));
- break;
- }
-
- return retval;
+
+ return retval;
}
/*
* equali--
- * compares two lists of integers
+ * compares two lists of integers
*
* XXX temp hack. needs something like T_IntList
*/
-static bool
-equali(List *a, List *b)
-{
- List *la = (List*)a;
- List *lb = (List*)b;
- List *l;
-
- if (a==NULL && b==NULL)
- return (true);
- if (length(a)!=length(b))
- return (false);
- foreach(l, la) {
- if (lfirsti(l) != lfirsti(lb))
- return (false);
- lb = lnext(lb);
- }
- return true;
+static bool
+equali(List * a, List * b)
+{
+ List *la = (List *) a;
+ List *lb = (List *) b;
+ List *l;
+
+ if (a == NULL && b == NULL)
+ return (true);
+ if (length(a) != length(b))
+ return (false);
+ foreach(l, la)
+ {
+ if (lfirsti(l) != lfirsti(lb))
+ return (false);
+ lb = lnext(lb);
+ }
+ return true;
}
diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c
index 6dc010eff65..334030822f7 100644
--- a/src/backend/nodes/list.c
+++ b/src/backend/nodes/list.c
@@ -1,23 +1,23 @@
/*-------------------------------------------------------------------------
*
* list.c--
- * various list handling routines
+ * various list handling routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.4 1997/08/19 21:31:39 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.5 1997/09/07 04:42:46 momjian Exp $
*
* NOTES
- * XXX a few of the following functions are duplicated to handle
- * List of pointers and List of integers separately. Some day,
- * someone should unify them. - ay 11/2/94
- * This file needs cleanup.
+ * XXX a few of the following functions are duplicated to handle
+ * List of pointers and List of integers separately. Some day,
+ * someone should unify them. - ay 11/2/94
+ * This file needs cleanup.
*
* HISTORY
- * AUTHOR DATE MAJOR EVENT
- * Andrew Yu Oct, 1994 file creation
+ * AUTHOR DATE MAJOR EVENT
+ * Andrew Yu Oct, 1994 file creation
*
*-------------------------------------------------------------------------
*/
@@ -25,442 +25,483 @@
#include "postgres.h"
#include "nodes/pg_list.h"
#include "nodes/parsenodes.h"
-#include "utils/builtins.h" /* for namecpy */
+#include "utils/builtins.h" /* for namecpy */
#include "utils/elog.h"
#include "utils/palloc.h"
-List *
-makeList(void *elem, ...)
+List *
+makeList(void *elem,...)
{
- va_list args;
- List *retval = NIL;
- List *temp = NIL;
- List *tempcons = NIL;
-
- va_start(args, elem);
-
- temp = elem;
- while (temp != (void *) -1) {
- temp = lcons(temp, NIL);
- if (tempcons == NIL)
- retval = temp;
- else
- lnext(tempcons) = temp;
- tempcons = temp;
-
- temp = va_arg(args, void *);
- }
+ va_list args;
+ List *retval = NIL;
+ List *temp = NIL;
+ List *tempcons = NIL;
+
+ va_start(args, elem);
+
+ temp = elem;
+ while (temp != (void *) -1)
+ {
+ temp = lcons(temp, NIL);
+ if (tempcons == NIL)
+ retval = temp;
+ else
+ lnext(tempcons) = temp;
+ tempcons = temp;
+
+ temp = va_arg(args, void *);
+ }
- va_end(args);
+ va_end(args);
- return (retval);
+ return (retval);
}
-List *
-lcons(void *obj, List *list)
+List *
+lcons(void *obj, List * list)
{
- List *l = makeNode(List);
- lfirst(l) = obj;
- lnext(l) = list;
- return l;
+ List *l = makeNode(List);
+
+ lfirst(l) = obj;
+ lnext(l) = list;
+ return l;
}
-List *
-lconsi(int datum, List *list)
+List *
+lconsi(int datum, List * list)
{
- List *l = makeNode(List);
- lfirsti(l) = datum;
- lnext(l) = list;
- return l;
+ List *l = makeNode(List);
+
+ lfirsti(l) = datum;
+ lnext(l) = list;
+ return l;
}
-List *
-lappend(List *list, void *obj)
+List *
+lappend(List * list, void *obj)
{
- return nconc(list, lcons(obj, NIL));
+ return nconc(list, lcons(obj, NIL));
}
-List *
-lappendi(List *list, int datum)
+List *
+lappendi(List * list, int datum)
{
- return nconc(list, lconsi(datum, NIL));
+ return nconc(list, lconsi(datum, NIL));
}
-Value *
+Value *
makeInteger(long i)
{
- Value *v = makeNode(Value);
- v->type = T_Integer;
- v->val.ival = i;
- return v;
+ Value *v = makeNode(Value);
+
+ v->type = T_Integer;
+ v->val.ival = i;
+ return v;
}
-Value *
+Value *
makeFloat(double d)
{
- Value *v = makeNode(Value);
- v->type = T_Float;
- v->val.dval = d;
- return v;
+ Value *v = makeNode(Value);
+
+ v->type = T_Float;
+ v->val.dval = d;
+ return v;
}
-Value *
+Value *
makeString(char *str)
{
- Value *v = makeNode(Value);
- v->type = T_String;
- v->val.str = str;
- return v;
+ Value *v = makeNode(Value);
+
+ v->type = T_String;
+ v->val.str = str;
+ return v;
}
/* n starts with 0 */
-void *
-nth(int n, List *l)
+void *
+nth(int n, List * l)
{
- /* XXX assume list is long enough */
- while(n > 0) {
- l = lnext(l);
- n--;
- }
- return lfirst(l);
+ /* XXX assume list is long enough */
+ while (n > 0)
+ {
+ l = lnext(l);
+ n--;
+ }
+ return lfirst(l);
}
int
-nthi(int n, List *l)
+nthi(int n, List * l)
{
- /* XXX assume list is long enough */
- while(n > 0) {
- l = lnext(l);
- n--;
- }
- return lfirsti(l);
+ /* XXX assume list is long enough */
+ while (n > 0)
+ {
+ l = lnext(l);
+ n--;
+ }
+ return lfirsti(l);
}
/* this is here solely for rt_store. Get rid of me some day! */
void
-set_nth(List *l, int n, void *elem)
+set_nth(List * l, int n, void *elem)
{
- /* XXX assume list is long enough */
- while(n > 0) {
- l = lnext(l);
- n--;
- }
- lfirst(l) = elem;
- return;
+ /* XXX assume list is long enough */
+ while (n > 0)
+ {
+ l = lnext(l);
+ n--;
+ }
+ lfirst(l) = elem;
+ return;
}
int
-length(List *l)
+length(List * l)
{
- int i=0;
- while(l!=NIL) {
- l = lnext(l);
- i++;
- }
- return i;
+ int i = 0;
+
+ while (l != NIL)
+ {
+ l = lnext(l);
+ i++;
+ }
+ return i;
}
void
-freeList(List *list)
+freeList(List * list)
{
- while(list!=NIL) {
- List *l = list;
- list = lnext(list);
- pfree(l);
- }
+ while (list != NIL)
+ {
+ List *l = list;
+
+ list = lnext(list);
+ pfree(l);
+ }
}
/*
* below are for backwards compatibility
*/
-List *
-append(List *l1, List *l2)
+List *
+append(List * l1, List * l2)
{
- List *newlist, *newlist2, *p;
+ List *newlist,
+ *newlist2,
+ *p;
- if (l1==NIL)
- return copyObject(l2);
+ if (l1 == NIL)
+ return copyObject(l2);
- newlist = copyObject(l1);
- newlist2 = copyObject(l2);
+ newlist = copyObject(l1);
+ newlist2 = copyObject(l2);
- for (p=newlist; lnext(p)!=NIL; p=lnext(p))
- ;
- lnext(p) = newlist2;
- return newlist;
+ for (p = newlist; lnext(p) != NIL; p = lnext(p))
+ ;
+ lnext(p) = newlist2;
+ return newlist;
}
/*
* below are for backwards compatibility
*/
-List *
-intAppend(List *l1, List *l2)
+List *
+intAppend(List * l1, List * l2)
{
- List *newlist, *newlist2, *p;
+ List *newlist,
+ *newlist2,
+ *p;
- if (l1==NIL)
- return listCopy(l2);
+ if (l1 == NIL)
+ return listCopy(l2);
- newlist = listCopy(l1);
- newlist2 = listCopy(l2);
+ newlist = listCopy(l1);
+ newlist2 = listCopy(l2);
- for (p=newlist; lnext(p)!=NIL; p=lnext(p))
- ;
- lnext(p) = newlist2;
- return newlist;
+ for (p = newlist; lnext(p) != NIL; p = lnext(p))
+ ;
+ lnext(p) = newlist2;
+ return newlist;
}
-List *
-nconc(List *l1, List *l2)
+List *
+nconc(List * l1, List * l2)
{
- List *temp;
-
- if (l1 == NIL)
- return l2;
- if (l2 == NIL)
- return l1;
- if (l1 == l2)
- elog(WARN, "tryout to nconc a list to itself");
-
- for (temp = l1; lnext(temp)!=NULL; temp = lnext(temp))
- ;
-
- lnext(temp) = l2;
- return(l1); /* list1 is now list1[]list2 */
+ List *temp;
+
+ if (l1 == NIL)
+ return l2;
+ if (l2 == NIL)
+ return l1;
+ if (l1 == l2)
+ elog(WARN, "tryout to nconc a list to itself");
+
+ for (temp = l1; lnext(temp) != NULL; temp = lnext(temp))
+ ;
+
+ lnext(temp) = l2;
+ return (l1); /* list1 is now list1[]list2 */
}
-List *
-nreverse(List *list)
+List *
+nreverse(List * list)
{
- List *rlist = NIL;
- List *p = NIL;
-
- if(list==NULL)
- return(NIL);
-
- if (length(list) == 1)
- return(list);
-
- for (p = list; p!=NULL; p = lnext(p)) {
- rlist = lcons(lfirst(p),rlist);
- }
-
- lfirst(list) = lfirst(rlist);
- lnext(list) = lnext(rlist);
- return(list);
+ List *rlist = NIL;
+ List *p = NIL;
+
+ if (list == NULL)
+ return (NIL);
+
+ if (length(list) == 1)
+ return (list);
+
+ for (p = list; p != NULL; p = lnext(p))
+ {
+ rlist = lcons(lfirst(p), rlist);
+ }
+
+ lfirst(list) = lfirst(rlist);
+ lnext(list) = lnext(rlist);
+ return (list);
}
-/*
- * same
- *
- * Returns t if two lists contain the same elements.
- * now defined in lispdep.c
+/*
+ * same
+ *
+ * Returns t if two lists contain the same elements.
+ * now defined in lispdep.c
*
* XXX only good for IntList -ay
*/
bool
-same(List *foo, List *bar)
+same(List * foo, List * bar)
{
- List *temp = NIL;
-
- if (foo == NULL)
- return (bar==NULL);
- if (bar == NULL)
- return (foo==NULL);
- if (length(foo) == length(bar)) {
- foreach (temp,foo) {
- if (!intMember(lfirsti(temp),bar))
- return(false);
+ List *temp = NIL;
+
+ if (foo == NULL)
+ return (bar == NULL);
+ if (bar == NULL)
+ return (foo == NULL);
+ if (length(foo) == length(bar))
+ {
+ foreach(temp, foo)
+ {
+ if (!intMember(lfirsti(temp), bar))
+ return (false);
+ }
+ return (true);
}
- return(true);
- }
- return(false);
-
-}
-
-List *
-LispUnion(List *foo, List *bar)
+ return (false);
+
+}
+
+List *
+LispUnion(List * foo, List * bar)
{
- List *retval = NIL;
- List *i = NIL;
- List *j = NIL;
-
- if (foo==NIL)
- return(bar); /* XXX - should be copy of bar */
-
- if (bar==NIL)
- return(foo); /* XXX - should be copy of foo */
-
- foreach (i,foo) {
- foreach (j,bar) {
- if (! equal(lfirst(i), lfirst(j))) {
- retval = lappend(retval,lfirst(i));
- break;
- }
+ List *retval = NIL;
+ List *i = NIL;
+ List *j = NIL;
+
+ if (foo == NIL)
+ return (bar); /* XXX - should be copy of bar */
+
+ if (bar == NIL)
+ return (foo); /* XXX - should be copy of foo */
+
+ foreach(i, foo)
+ {
+ foreach(j, bar)
+ {
+ if (!equal(lfirst(i), lfirst(j)))
+ {
+ retval = lappend(retval, lfirst(i));
+ break;
+ }
+ }
}
- }
- foreach(i,bar) {
- retval = lappend(retval,lfirst(i));
- }
-
- return(retval);
+ foreach(i, bar)
+ {
+ retval = lappend(retval, lfirst(i));
+ }
+
+ return (retval);
}
-List *
-LispUnioni(List *foo, List *bar)
+List *
+LispUnioni(List * foo, List * bar)
{
- List *retval = NIL;
- List *i = NIL;
- List *j = NIL;
-
- if (foo==NIL)
- return(bar); /* XXX - should be copy of bar */
-
- if (bar==NIL)
- return(foo); /* XXX - should be copy of foo */
-
- foreach (i,foo) {
- foreach (j,bar) {
- if (lfirsti(i) != lfirsti(j)) {
- retval = lappendi(retval,lfirsti(i));
- break;
- }
+ List *retval = NIL;
+ List *i = NIL;
+ List *j = NIL;
+
+ if (foo == NIL)
+ return (bar); /* XXX - should be copy of bar */
+
+ if (bar == NIL)
+ return (foo); /* XXX - should be copy of foo */
+
+ foreach(i, foo)
+ {
+ foreach(j, bar)
+ {
+ if (lfirsti(i) != lfirsti(j))
+ {
+ retval = lappendi(retval, lfirsti(i));
+ break;
+ }
+ }
+ }
+ foreach(i, bar)
+ {
+ retval = lappendi(retval, lfirsti(i));
}
- }
- foreach(i,bar) {
- retval = lappendi(retval, lfirsti(i));
- }
-
- return(retval);
+
+ return (retval);
}
/*
* member()
* - nondestructive, returns t iff foo is a member of the list
- * bar
+ * bar
*/
bool
-member(void *foo, List *bar)
+member(void *foo, List * bar)
{
- List *i;
- foreach (i,bar)
- if (equal((Node*)(lfirst(i)),(Node*)foo))
- return(true);
- return(false);
+ List *i;
+
+ foreach(i, bar)
+ if (equal((Node *) (lfirst(i)), (Node *) foo))
+ return (true);
+ return (false);
}
bool
-intMember(int foo, List *bar)
+intMember(int foo, List * bar)
{
- List *i;
- foreach (i,bar)
- if (foo == lfirsti(i))
- return(true);
- return(false);
+ List *i;
+
+ foreach(i, bar)
+ if (foo == lfirsti(i))
+ return (true);
+ return (false);
}
/*
* lremove -
- * only does pointer comparisons. Removes 'elem' from the the linked list.
+ * only does pointer comparisons. Removes 'elem' from the the linked list.
*/
-List *
-lremove(void *elem, List *list)
+List *
+lremove(void *elem, List * list)
{
- List *l;
- List *prev = NIL;
- List *result = list;
-
- foreach(l, list) {
- if (elem == lfirst(l))
- break;
- prev = l;
- }
- if (l!=NULL) {
- if (prev == NIL) {
- result = lnext(list);
- } else {
- lnext(prev) = lnext(l);
+ List *l;
+ List *prev = NIL;
+ List *result = list;
+
+ foreach(l, list)
+ {
+ if (elem == lfirst(l))
+ break;
+ prev = l;
+ }
+ if (l != NULL)
+ {
+ if (prev == NIL)
+ {
+ result = lnext(list);
+ }
+ else
+ {
+ lnext(prev) = lnext(l);
+ }
}
- }
- return result;
+ return result;
}
-
-List *
-LispRemove(void *elem, List *list)
+
+List *
+LispRemove(void *elem, List * list)
{
- List *temp = NIL;
- List *prev = NIL;
-
- if (equal(elem, lfirst(list)))
- return lnext(list);
-
- temp = lnext(list);
- prev = list;
- while(temp!=NIL) {
- if (equal(elem, lfirst(temp))) {
- lnext(prev) = lnext(temp);
- break;
+ List *temp = NIL;
+ List *prev = NIL;
+
+ if (equal(elem, lfirst(list)))
+ return lnext(list);
+
+ temp = lnext(list);
+ prev = list;
+ while (temp != NIL)
+ {
+ if (equal(elem, lfirst(temp)))
+ {
+ lnext(prev) = lnext(temp);
+ break;
+ }
+ temp = lnext(temp);
+ prev = lnext(prev);
}
- temp = lnext(temp);
- prev = lnext(prev);
- }
- return(list);
+ return (list);
}
#ifdef NOT_USED
-List *
-intLispRemove(int elem, List *list)
+List *
+intLispRemove(int elem, List * list)
{
- List *temp = NIL;
- List *prev = NIL;
-
- if (elem == lfirsti(list))
- return lnext(list);
-
- temp = lnext(list);
- prev = list;
- while(temp!=NIL) {
- if (elem == lfirsti(temp)) {
- lnext(prev) = lnext(temp);
- break;
+ List *temp = NIL;
+ List *prev = NIL;
+
+ if (elem == lfirsti(list))
+ return lnext(list);
+
+ temp = lnext(list);
+ prev = list;
+ while (temp != NIL)
+ {
+ if (elem == lfirsti(temp))
+ {
+ lnext(prev) = lnext(temp);
+ break;
+ }
+ temp = lnext(temp);
+ prev = lnext(prev);
}
- temp = lnext(temp);
- prev = lnext(prev);
- }
- return(list);
+ return (list);
}
+
#endif
-List *
-set_difference(List *list1, List *list2)
+List *
+set_difference(List * list1, List * list2)
{
- List *temp1 = NIL;
- List *result = NIL;
-
- if (list2==NIL)
- return(list1);
-
- foreach (temp1, list1) {
- if (!member(lfirst(temp1), list2))
- result = lappend(result, lfirst(temp1));
- }
- return(result);
+ List *temp1 = NIL;
+ List *result = NIL;
+
+ if (list2 == NIL)
+ return (list1);
+
+ foreach(temp1, list1)
+ {
+ if (!member(lfirst(temp1), list2))
+ result = lappend(result, lfirst(temp1));
+ }
+ return (result);
}
-List *
-set_differencei(List *list1, List *list2)
+List *
+set_differencei(List * list1, List * list2)
{
- List *temp1 = NIL;
- List *result = NIL;
-
- if (list2==NIL)
- return(list1);
-
- foreach (temp1, list1) {
- if (!intMember(lfirsti(temp1), list2))
- result = lappendi(result, lfirsti(temp1));
- }
- return(result);
-}
+ List *temp1 = NIL;
+ List *result = NIL;
+
+ if (list2 == NIL)
+ return (list1);
+ foreach(temp1, list1)
+ {
+ if (!intMember(lfirsti(temp1), list2))
+ result = lappendi(result, lfirsti(temp1));
+ }
+ return (result);
+}
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 18894e8a41c..7c5a9efc1fb 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -1,22 +1,22 @@
/*
* makefuncs.c--
- * creator functions for primitive nodes. The functions here are for
- * the most frequently created nodes.
+ * creator functions for primitive nodes. The functions here are for
+ * the most frequently created nodes.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.2 1997/01/22 01:42:26 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.3 1997/09/07 04:42:48 momjian Exp $
*
* NOTES
- * Creator functions in POSTGRES 4.2 are generated automatically. Most of
- * them are rarely used. Now we don't generate them any more. If you want
- * one, you have to write it yourself.
+ * Creator functions in POSTGRES 4.2 are generated automatically. Most of
+ * them are rarely used. Now we don't generate them any more. If you want
+ * one, you have to write it yourself.
*
* HISTORY
- * AUTHOR DATE MAJOR EVENT
- * Andrew Yu Oct 20, 1994 file creation
+ * AUTHOR DATE MAJOR EVENT
+ * Andrew Yu Oct 20, 1994 file creation
*/
#include "postgres.h"
#include "nodes/pg_list.h"
@@ -25,95 +25,94 @@
/*
* makeOper -
- * creates an Oper node
+ * creates an Oper node
*/
-Oper *
+Oper *
makeOper(Oid opno,
- Oid opid,
- Oid opresulttype,
- int opsize,
- FunctionCachePtr op_fcache)
+ Oid opid,
+ Oid opresulttype,
+ int opsize,
+ FunctionCachePtr op_fcache)
{
- Oper *oper = makeNode(Oper);
+ Oper *oper = makeNode(Oper);
- oper->opno = opno;
- oper->opid = opid;
- oper->opresulttype = opresulttype;
- oper->opsize = opsize;
- oper->op_fcache = op_fcache;
- return oper;
+ oper->opno = opno;
+ oper->opid = opid;
+ oper->opresulttype = opresulttype;
+ oper->opsize = opsize;
+ oper->op_fcache = op_fcache;
+ return oper;
}
/*
* makeVar -
- * creates a Var node
+ * creates a Var node
*
*/
-Var *
-makeVar(Index varno,
- AttrNumber varattno,
- Oid vartype,
- Index varnoold,
- AttrNumber varoattno)
+Var *
+makeVar(Index varno,
+ AttrNumber varattno,
+ Oid vartype,
+ Index varnoold,
+ AttrNumber varoattno)
{
- Var *var = makeNode(Var);
+ Var *var = makeNode(Var);
- var->varno = varno;
- var->varattno = varattno;
- var->vartype = vartype;
- var->varnoold = varnoold;
- var->varoattno = varoattno;
+ var->varno = varno;
+ var->varattno = varattno;
+ var->vartype = vartype;
+ var->varnoold = varnoold;
+ var->varoattno = varoattno;
- return var;
+ return var;
}
/*
* makeResdom -
- * creates a Resdom (Result Domain) node
+ * creates a Resdom (Result Domain) node
*/
-Resdom *
+Resdom *
makeResdom(AttrNumber resno,
- Oid restype,
- int reslen,
- char *resname,
- Index reskey,
- Oid reskeyop,
- int resjunk)
+ Oid restype,
+ int reslen,
+ char *resname,
+ Index reskey,
+ Oid reskeyop,
+ int resjunk)
{
- Resdom *resdom = makeNode(Resdom);
+ Resdom *resdom = makeNode(Resdom);
- resdom->resno = resno;
- resdom->restype = restype;
- resdom->reslen = reslen;
- resdom->resname = resname;
- resdom->reskey = reskey;
- resdom->reskeyop = reskeyop;
- resdom->resjunk = resjunk;
- return resdom;
+ resdom->resno = resno;
+ resdom->restype = restype;
+ resdom->reslen = reslen;
+ resdom->resname = resname;
+ resdom->reskey = reskey;
+ resdom->reskeyop = reskeyop;
+ resdom->resjunk = resjunk;
+ return resdom;
}
/*
* makeConst -
- * creates a Const node
+ * creates a Const node
*/
-Const *
+Const *
makeConst(Oid consttype,
- Size constlen,
- Datum constvalue,
- bool constisnull,
- bool constbyval,
- bool constisset,
- bool constiscast)
+ Size constlen,
+ Datum constvalue,
+ bool constisnull,
+ bool constbyval,
+ bool constisset,
+ bool constiscast)
{
- Const *cnst = makeNode(Const);
+ Const *cnst = makeNode(Const);
- cnst->consttype = consttype;
- cnst->constlen = constlen;
- cnst->constvalue = constvalue;
- cnst->constisnull = constisnull;
- cnst->constbyval = constbyval;
- cnst->constisset = constisset;
- cnst->constiscast = constiscast;
- return cnst;
+ cnst->consttype = consttype;
+ cnst->constlen = constlen;
+ cnst->constvalue = constvalue;
+ cnst->constisnull = constisnull;
+ cnst->constbyval = constbyval;
+ cnst->constisset = constisset;
+ cnst->constiscast = constiscast;
+ return cnst;
}
-
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index e1e6bc6f140..081760eaca2 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* nodeFuncs.c--
- * All node routines more complicated than simple access/modification
+ * All node routines more complicated than simple access/modification
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/nodeFuncs.c,v 1.3 1997/08/19 21:31:41 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/nodeFuncs.c,v 1.4 1997/09/07 04:42:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <sys/types.h>
+#include <sys/types.h>
#include "postgres.h"
@@ -23,99 +23,96 @@
#include "nodes/nodeFuncs.h"
#include "utils/lsyscache.h"
-static bool var_is_inner(Var *var);
+static bool var_is_inner(Var * var);
-/*
+/*
* single_node -
- * Returns t if node corresponds to a single-noded expression
+ * Returns t if node corresponds to a single-noded expression
*/
bool
-single_node(Node *node)
+single_node(Node * node)
{
- if(IsA(node,Ident) || IsA(node,Const) || IsA(node,Var) || IsA(node,Param))
- return(true);
- else
- return(false);
+ if (IsA(node, Ident) || IsA(node, Const) || IsA(node, Var) || IsA(node, Param))
+ return (true);
+ else
+ return (false);
}
/*****************************************************************************
- * VAR nodes
+ * VAR nodes
*****************************************************************************/
-/*
- * var_is_outer
- * var_is_inner
- * var_is_mat
- * var_is_rel
- *
- * Returns t iff the var node corresponds to (respectively):
- * the outer relation in a join
- * the inner relation of a join
- * a materialized relation
- * a base relation (i.e., not an attribute reference, a variable from
- * some lower join level, or a sort result)
- * var node is an array reference
- *
+/*
+ * var_is_outer
+ * var_is_inner
+ * var_is_mat
+ * var_is_rel
+ *
+ * Returns t iff the var node corresponds to (respectively):
+ * the outer relation in a join
+ * the inner relation of a join
+ * a materialized relation
+ * a base relation (i.e., not an attribute reference, a variable from
+ * some lower join level, or a sort result)
+ * var node is an array reference
+ *
*/
bool
-var_is_outer (Var *var)
+var_is_outer(Var * var)
{
- return((bool)(var->varno == OUTER));
+ return ((bool) (var->varno == OUTER));
}
-static bool
-var_is_inner (Var *var)
+static bool
+var_is_inner(Var * var)
{
- return ( (bool) (var->varno == INNER));
+ return ((bool) (var->varno == INNER));
}
bool
-var_is_rel (Var *var)
+var_is_rel(Var * var)
{
- return (bool)
- ! (var_is_inner (var) || var_is_outer (var));
+ return (bool)
+ ! (var_is_inner(var) || var_is_outer(var));
}
/*****************************************************************************
- * OPER nodes
+ * OPER nodes
*****************************************************************************/
-/*
+/*
* replace_opid -
- *
- * Given a oper node, resets the opfid field with the
- * procedure OID (regproc id).
- *
- * Returns the modified oper node.
- *
+ *
+ * Given a oper node, resets the opfid field with the
+ * procedure OID (regproc id).
+ *
+ * Returns the modified oper node.
+ *
*/
-Oper *
-replace_opid (Oper *oper)
+Oper *
+replace_opid(Oper * oper)
{
- oper->opid = get_opcode(oper->opno);
- oper->op_fcache = NULL;
- return(oper);
+ oper->opid = get_opcode(oper->opno);
+ oper->op_fcache = NULL;
+ return (oper);
}
/*****************************************************************************
- * constant (CONST, PARAM) nodes
+ * constant (CONST, PARAM) nodes
*****************************************************************************/
-/*
+/*
* non_null -
- * Returns t if the node is a non-null constant, e.g., if the node has a
- * valid `constvalue' field.
- *
+ * Returns t if the node is a non-null constant, e.g., if the node has a
+ * valid `constvalue' field.
+ *
*/
bool
-non_null (Expr *c)
+non_null(Expr * c)
{
-
- if ( IsA(c,Const) && ! ((Const*)c)->constisnull )
- return(true);
- else
- return(false);
-}
-
-
+ if (IsA(c, Const) && !((Const *) c)->constisnull)
+ return (true);
+ else
+ return (false);
+}
diff --git a/src/backend/nodes/nodes.c b/src/backend/nodes/nodes.c
index 82845cca15c..2af057e5a4c 100644
--- a/src/backend/nodes/nodes.c
+++ b/src/backend/nodes/nodes.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* nodes.c--
- * support code for nodes (now that we get rid of the home-brew
- * inheritance system, our support code for nodes get much simpler)
+ * support code for nodes (now that we get rid of the home-brew
+ * inheritance system, our support code for nodes get much simpler)
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/nodes.c,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/nodes.c,v 1.2 1997/09/07 04:42:52 momjian Exp $
*
* HISTORY
- * Andrew Yu Oct 20, 1994 file creation
+ * Andrew Yu Oct 20, 1994 file creation
*
*-------------------------------------------------------------------------
*/
@@ -19,27 +19,27 @@
#include "postgres.h"
#include "utils/palloc.h"
#include "utils/elog.h"
-#include "nodes/nodes.h" /* where func declarations of this file goes */
+#include "nodes/nodes.h" /* where func declarations of this file
+ * goes */
/*
* newNode -
- * create a new node of the specified size and tag the node with the
- * specified tag.
+ * create a new node of the specified size and tag the node with the
+ * specified tag.
*
* !WARNING!: Avoid using newNode directly. You should be using the
- * macro makeNode. eg. to create a Resdom node, use makeNode(Resdom)
+ * macro makeNode. eg. to create a Resdom node, use makeNode(Resdom)
*
*/
-Node *
+Node *
newNode(Size size, NodeTag tag)
{
- Node *newNode;
-
- Assert(size >= 4); /* need the tag, at least */
-
- newNode = (Node *)palloc(size);
- memset((char *)newNode, 0, size);
- newNode->type = tag;
- return(newNode);
-}
+ Node *newNode;
+
+ Assert(size >= 4); /* need the tag, at least */
+ newNode = (Node *) palloc(size);
+ memset((char *) newNode, 0, size);
+ newNode->type = tag;
+ return (newNode);
+}
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index a41848c6188..a1574c8734f 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1,24 +1,24 @@
/*-------------------------------------------------------------------------
*
* outfuncs.c--
- * routines to convert a node to ascii representation
+ * routines to convert a node to ascii representation
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.6 1997/08/18 20:52:43 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.7 1997/09/07 04:42:53 momjian Exp $
*
* NOTES
- * Every (plan) node in POSTGRES has an associated "out" routine which
- * knows how to create its ascii representation. These functions are
- * useful for debugging as well as for storing plans in the system
- * catalogs (eg. indexes). This is also the plan string sent out in
- * Mariposa.
+ * Every (plan) node in POSTGRES has an associated "out" routine which
+ * knows how to create its ascii representation. These functions are
+ * useful for debugging as well as for storing plans in the system
+ * catalogs (eg. indexes). This is also the plan string sent out in
+ * Mariposa.
*
- * These functions update the in/out argument of type StringInfo
- * passed to them. This argument contains the string holding the ASCII
- * representation plus some other information (string length, etc.)
+ * These functions update the in/out argument of type StringInfo
+ * passed to them. This argument contains the string holding the ASCII
+ * representation plus some other information (string length, etc.)
*
*-------------------------------------------------------------------------
*/
@@ -45,1305 +45,1322 @@
#include "catalog/pg_type.h"
#include "lib/stringinfo.h"
-static void _outDatum(StringInfo str, Datum value, Oid type);
-static void _outNode(StringInfo str, void *obj);
+static void _outDatum(StringInfo str, Datum value, Oid type);
+static void _outNode(StringInfo str, void *obj);
/*
* _outIntList -
- * converts a List of integers
+ * converts a List of integers
*/
static void
-_outIntList(StringInfo str, List *list)
+_outIntList(StringInfo str, List * list)
{
- List *l;
- char buf[500];
+ List *l;
+ char buf[500];
- appendStringInfo(str, "(");
- foreach(l, list) {
- sprintf(buf, "%d ", (int)lfirst(l));
- appendStringInfo(str, buf);
- }
- appendStringInfo(str, ")");
+ appendStringInfo(str, "(");
+ foreach(l, list)
+ {
+ sprintf(buf, "%d ", (int) lfirst(l));
+ appendStringInfo(str, buf);
+ }
+ appendStringInfo(str, ")");
}
static void
-_outQuery(StringInfo str, Query *node)
+_outQuery(StringInfo str, Query * node)
{
- char buf[500];
-
- sprintf(buf, "QUERY");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :command %d", node->commandType);
- appendStringInfo(str,buf);
- if (node->utilityStmt &&
- nodeTag(node->utilityStmt) == T_NotifyStmt)
- sprintf(buf," :utility %s",
- ((NotifyStmt*)(node->utilityStmt))->relname);
- else /* use "" to designate */
- sprintf(buf," :utility \"\"");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :resrel %d", node->resultRelation);
- appendStringInfo(str,buf);
- sprintf(buf, " :rtable ");
- appendStringInfo(str,buf);
- _outNode(str, node->rtable);
- if (node->uniqueFlag)
- sprintf(buf, " :unique %s", node->uniqueFlag);
- else /* use "" to designate non-unique */
- sprintf(buf, " :unique \"\"");
- appendStringInfo(str,buf);
- sprintf(buf, " :targetlist ");
- appendStringInfo(str,buf);
- _outNode(str, node->targetList);
- sprintf(buf, " :qual ");
- appendStringInfo(str,buf);
- _outNode(str, node->qual);
-
+ char buf[500];
+
+ sprintf(buf, "QUERY");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :command %d", node->commandType);
+ appendStringInfo(str, buf);
+ if (node->utilityStmt &&
+ nodeTag(node->utilityStmt) == T_NotifyStmt)
+ sprintf(buf, " :utility %s",
+ ((NotifyStmt *) (node->utilityStmt))->relname);
+ else
+/* use "" to designate */
+ sprintf(buf, " :utility \"\"");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :resrel %d", node->resultRelation);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :rtable ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->rtable);
+ if (node->uniqueFlag)
+ sprintf(buf, " :unique %s", node->uniqueFlag);
+ else
+/* use "" to designate non-unique */
+ sprintf(buf, " :unique \"\"");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :targetlist ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->targetList);
+ sprintf(buf, " :qual ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->qual);
+
}
/*
* print the basic stuff of all nodes that inherit from Plan
*/
static void
-_outPlanInfo(StringInfo str, Plan *node)
+_outPlanInfo(StringInfo str, Plan * node)
{
- char buf[500];
-
- sprintf(buf, " :cost %g", node->cost );
- appendStringInfo(str,buf);
- sprintf(buf, " :size %d", node->plan_size);
- appendStringInfo(str,buf);
- sprintf(buf, " :width %d", node->plan_width);
- appendStringInfo(str,buf);
- sprintf(buf, " :state %s", (node->state == (EState*) NULL ?
- "nil" : "non-NIL"));
- appendStringInfo(str,buf);
- sprintf(buf, " :qptargetlist ");
- appendStringInfo(str,buf);
- _outNode(str, node->targetlist);
- sprintf(buf, " :qpqual ");
- appendStringInfo(str,buf);
- _outNode(str, node->qual);
- sprintf(buf, " :lefttree ");
- appendStringInfo(str,buf);
- _outNode(str, node->lefttree);
- sprintf(buf, " :righttree ");
- appendStringInfo(str,buf);
- _outNode(str, node->righttree);
-
+ char buf[500];
+
+ sprintf(buf, " :cost %g", node->cost);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :size %d", node->plan_size);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :width %d", node->plan_width);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :state %s", (node->state == (EState *) NULL ?
+ "nil" : "non-NIL"));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :qptargetlist ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->targetlist);
+ sprintf(buf, " :qpqual ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->qual);
+ sprintf(buf, " :lefttree ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->lefttree);
+ sprintf(buf, " :righttree ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->righttree);
+
}
/*
- * Stuff from plannodes.h
+ * Stuff from plannodes.h
*/
static void
-_outPlan(StringInfo str, Plan *node)
+_outPlan(StringInfo str, Plan * node)
{
- char buf[500];
-
- sprintf(buf, "PLAN");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
+ char buf[500];
+
+ sprintf(buf, "PLAN");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
}
static void
-_outResult(StringInfo str, Result *node)
+_outResult(StringInfo str, Result * node)
{
- char buf[500];
-
- sprintf(buf, "RESULT");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :resconstantqual ");
- appendStringInfo(str,buf);
- _outNode(str, node->resconstantqual);
-
+ char buf[500];
+
+ sprintf(buf, "RESULT");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :resconstantqual ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->resconstantqual);
+
}
/*
- * Existential is a subclass of Plan.
+ * Existential is a subclass of Plan.
*/
static void
-_outExistential(StringInfo str, Existential *node)
+_outExistential(StringInfo str, Existential * node)
{
- char buf[500];
-
- sprintf(buf, "EXISTENTIAL");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
-
+ char buf[500];
+
+ sprintf(buf, "EXISTENTIAL");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+
}
/*
- * Append is a subclass of Plan.
+ * Append is a subclass of Plan.
*/
static void
-_outAppend(StringInfo str, Append *node)
+_outAppend(StringInfo str, Append * node)
{
- char buf[500];
-
- sprintf(buf, "APPEND");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :unionplans ");
- appendStringInfo(str,buf);
- _outNode(str, node->unionplans);
-
- sprintf(buf, " :unionrelid %d", node->unionrelid);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :unionrtentries ");
- appendStringInfo(str,buf);
- _outNode(str, node->unionrtentries);
-
+ char buf[500];
+
+ sprintf(buf, "APPEND");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :unionplans ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->unionplans);
+
+ sprintf(buf, " :unionrelid %d", node->unionrelid);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :unionrtentries ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->unionrtentries);
+
}
/*
- * Join is a subclass of Plan
+ * Join is a subclass of Plan
*/
static void
-_outJoin(StringInfo str, Join *node)
+_outJoin(StringInfo str, Join * node)
{
- char buf[500];
-
- sprintf(buf, "JOIN");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
+ char buf[500];
+
+ sprintf(buf, "JOIN");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
}
/*
- * NestLoop is a subclass of Join
+ * NestLoop is a subclass of Join
*/
static void
-_outNestLoop(StringInfo str, NestLoop *node)
+_outNestLoop(StringInfo str, NestLoop * node)
{
- char buf[500];
-
- sprintf(buf, "NESTLOOP");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
+ char buf[500];
+
+ sprintf(buf, "NESTLOOP");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
}
/*
- * MergeJoin is a subclass of Join
+ * MergeJoin is a subclass of Join
*/
static void
-_outMergeJoin(StringInfo str, MergeJoin *node)
+_outMergeJoin(StringInfo str, MergeJoin * node)
{
- char buf[500];
-
- sprintf(buf, "MERGEJOIN");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :mergeclauses ");
- appendStringInfo(str,buf);
- _outNode(str, node->mergeclauses);
-
- sprintf(buf, " :mergesortop %u", node->mergesortop);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :mergerightorder %u", node->mergerightorder[0]);
- appendStringInfo(str, buf);
-
- sprintf(buf, " :mergeleftorder %u", node->mergeleftorder[0]);
- appendStringInfo(str, buf);
+ char buf[500];
+
+ sprintf(buf, "MERGEJOIN");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :mergeclauses ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->mergeclauses);
+
+ sprintf(buf, " :mergesortop %u", node->mergesortop);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :mergerightorder %u", node->mergerightorder[0]);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :mergeleftorder %u", node->mergeleftorder[0]);
+ appendStringInfo(str, buf);
}
/*
- * HashJoin is a subclass of Join.
+ * HashJoin is a subclass of Join.
*/
static void
-_outHashJoin(StringInfo str, HashJoin *node)
+_outHashJoin(StringInfo str, HashJoin * node)
{
- char buf[500];
-
- sprintf(buf, "HASHJOIN");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :hashclauses ");
- appendStringInfo(str,buf);
- _outNode(str, node->hashclauses);
-
- sprintf(buf, " :hashjoinop %u",node->hashjoinop);
- appendStringInfo(str,buf);
- sprintf(buf, " :hashjointable 0x%x", (int) node->hashjointable);
- appendStringInfo(str,buf);
- sprintf(buf, " :hashjointablekey %d", node->hashjointablekey);
- appendStringInfo(str,buf);
- sprintf(buf, " :hashjointablesize %d", node->hashjointablesize);
- appendStringInfo(str,buf);
- sprintf(buf, " :hashdone %d", node->hashdone);
- appendStringInfo(str,buf);
+ char buf[500];
+
+ sprintf(buf, "HASHJOIN");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :hashclauses ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->hashclauses);
+
+ sprintf(buf, " :hashjoinop %u", node->hashjoinop);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :hashjointable 0x%x", (int) node->hashjointable);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :hashjointablekey %d", node->hashjointablekey);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :hashjointablesize %d", node->hashjointablesize);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :hashdone %d", node->hashdone);
+ appendStringInfo(str, buf);
}
/*
- * Scan is a subclass of Node
+ * Scan is a subclass of Node
*/
static void
-_outScan(StringInfo str, Scan *node)
+_outScan(StringInfo str, Scan * node)
{
- char buf[500];
-
- sprintf(buf, "SCAN");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :scanrelid %d", node->scanrelid);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "SCAN");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :scanrelid %d", node->scanrelid);
+ appendStringInfo(str, buf);
+
}
/*
- * SeqScan is a subclass of Scan
+ * SeqScan is a subclass of Scan
*/
static void
-_outSeqScan(StringInfo str, SeqScan *node)
+_outSeqScan(StringInfo str, SeqScan * node)
{
- char buf[500];
-
- sprintf(buf, "SEQSCAN");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :scanrelid %d", node->scanrelid);
- appendStringInfo(str,buf);
-
-
+ char buf[500];
+
+ sprintf(buf, "SEQSCAN");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :scanrelid %d", node->scanrelid);
+ appendStringInfo(str, buf);
+
+
}
/*
- * IndexScan is a subclass of Scan
+ * IndexScan is a subclass of Scan
*/
static void
-_outIndexScan(StringInfo str, IndexScan *node)
+_outIndexScan(StringInfo str, IndexScan * node)
{
- char buf[500];
-
- sprintf(buf, "INDEXSCAN");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :scanrelid %d", node->scan.scanrelid);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :indxid ");
- appendStringInfo(str,buf);
- _outIntList(str, node->indxid);
-
- sprintf(buf, " :indxqual ");
- appendStringInfo(str,buf);
- _outNode(str, node->indxqual);
-
+ char buf[500];
+
+ sprintf(buf, "INDEXSCAN");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :scanrelid %d", node->scan.scanrelid);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :indxid ");
+ appendStringInfo(str, buf);
+ _outIntList(str, node->indxid);
+
+ sprintf(buf, " :indxqual ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->indxqual);
+
}
/*
- * Temp is a subclass of Plan
+ * Temp is a subclass of Plan
*/
static void
-_outTemp(StringInfo str, Temp *node)
+_outTemp(StringInfo str, Temp * node)
{
- char buf[500];
-
- sprintf(buf, "TEMP");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :tempid %u", node->tempid);
- appendStringInfo(str,buf);
- sprintf(buf, " :keycount %d", node->keycount);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "TEMP");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :tempid %u", node->tempid);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :keycount %d", node->keycount);
+ appendStringInfo(str, buf);
+
}
/*
- * Sort is a subclass of Temp
+ * Sort is a subclass of Temp
*/
static void
-_outSort(StringInfo str, Sort *node)
+_outSort(StringInfo str, Sort * node)
{
- char buf[500];
-
- sprintf(buf, "SORT");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :tempid %u", node->tempid);
- appendStringInfo(str,buf);
- sprintf(buf, " :keycount %d", node->keycount);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "SORT");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :tempid %u", node->tempid);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :keycount %d", node->keycount);
+ appendStringInfo(str, buf);
+
}
static void
-_outAgg(StringInfo str, Agg *node)
+_outAgg(StringInfo str, Agg * node)
{
- char buf[500];
- sprintf(buf, "AGG");
- appendStringInfo(str,buf);
- _outPlanInfo(str,(Plan*)node);
-
- /* the actual Agg fields */
- sprintf(buf, " :numagg %d ", node->numAgg);
- appendStringInfo(str, buf);
+ char buf[500];
+
+ sprintf(buf, "AGG");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ /* the actual Agg fields */
+ sprintf(buf, " :numagg %d ", node->numAgg);
+ appendStringInfo(str, buf);
}
static void
-_outGroup(StringInfo str, Group *node)
+_outGroup(StringInfo str, Group * node)
{
- char buf[500];
- sprintf(buf, "GRP");
- appendStringInfo(str,buf);
- _outPlanInfo(str,(Plan*)node);
-
- /* the actual Group fields */
- sprintf(buf, " :numCols %d ", node->numCols);
- appendStringInfo(str, buf);
- sprintf(buf, " :tuplePerGroup %s", node->tuplePerGroup ? "true" : "nil");
- appendStringInfo(str, buf);
+ char buf[500];
+
+ sprintf(buf, "GRP");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ /* the actual Group fields */
+ sprintf(buf, " :numCols %d ", node->numCols);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :tuplePerGroup %s", node->tuplePerGroup ? "true" : "nil");
+ appendStringInfo(str, buf);
}
-
-
+
+
/*
- * For some reason, unique is a subclass of Temp.
+ * For some reason, unique is a subclass of Temp.
*/
static void
-_outUnique(StringInfo str, Unique *node)
+_outUnique(StringInfo str, Unique * node)
{
- char buf[500];
-
- sprintf(buf, "UNIQUE");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :tempid %u", node->tempid);
- appendStringInfo(str,buf);
- sprintf(buf, " :keycount %d", node->keycount);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "UNIQUE");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :tempid %u", node->tempid);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :keycount %d", node->keycount);
+ appendStringInfo(str, buf);
+
}
/*
- * Hash is a subclass of Temp
+ * Hash is a subclass of Temp
*/
static void
-_outHash(StringInfo str, Hash *node)
+_outHash(StringInfo str, Hash * node)
{
- char buf[500];
-
- sprintf(buf, "HASH");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :hashkey ");
- appendStringInfo(str,buf);
- _outNode(str, node->hashkey);
-
- sprintf(buf, " :hashtable 0x%x", (int) (node->hashtable));
- appendStringInfo(str,buf);
- sprintf(buf, " :hashtablekey %d", node->hashtablekey);
- appendStringInfo(str,buf);
- sprintf(buf, " :hashtablesize %d", node->hashtablesize);
- appendStringInfo(str,buf);
+ char buf[500];
+
+ sprintf(buf, "HASH");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :hashkey ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->hashkey);
+
+ sprintf(buf, " :hashtable 0x%x", (int) (node->hashtable));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :hashtablekey %d", node->hashtablekey);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :hashtablesize %d", node->hashtablesize);
+ appendStringInfo(str, buf);
}
static void
-_outTee(StringInfo str, Tee *node)
+_outTee(StringInfo str, Tee * node)
{
- char buf[500];
-
- sprintf(buf, "TEE");
- appendStringInfo(str,buf);
- _outPlanInfo(str, (Plan*) node);
-
- sprintf(buf, " :leftParent %X", (int) (node->leftParent));
- appendStringInfo(str,buf);
- sprintf(buf, " :rightParent %X", (int) (node->rightParent));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :rtentries ");
- appendStringInfo(str,buf);
- _outNode(str, node->rtentries);
+ char buf[500];
+
+ sprintf(buf, "TEE");
+ appendStringInfo(str, buf);
+ _outPlanInfo(str, (Plan *) node);
+
+ sprintf(buf, " :leftParent %X", (int) (node->leftParent));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :rightParent %X", (int) (node->rightParent));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :rtentries ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->rtentries);
}
/*****************************************************************************
*
- * Stuff from primnodes.h.
+ * Stuff from primnodes.h.
*
*****************************************************************************/
/*
- * Resdom is a subclass of Node
+ * Resdom is a subclass of Node
*/
static void
-_outResdom(StringInfo str, Resdom *node)
+_outResdom(StringInfo str, Resdom * node)
{
- char buf[500];
-
- sprintf(buf, "RESDOM");
- appendStringInfo(str,buf);
- sprintf(buf, " :resno %hd", node->resno);
- appendStringInfo(str,buf);
- sprintf(buf, " :restype %u", node->restype);
- appendStringInfo(str,buf);
- sprintf(buf, " :reslen %d", node->reslen);
- appendStringInfo(str,buf);
- sprintf(buf, " :resname \"%s\"",
- ((node->resname) ? ((char *) node->resname) : "null"));
- appendStringInfo(str,buf);
- sprintf(buf, " :reskey %d", node->reskey);
- appendStringInfo(str,buf);
- sprintf(buf, " :reskeyop %u", node->reskeyop);
- appendStringInfo(str,buf);
- sprintf(buf, " :resjunk %d", node->resjunk);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "RESDOM");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :resno %hd", node->resno);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :restype %u", node->restype);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :reslen %d", node->reslen);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :resname \"%s\"",
+ ((node->resname) ? ((char *) node->resname) : "null"));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :reskey %d", node->reskey);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :reskeyop %u", node->reskeyop);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :resjunk %d", node->resjunk);
+ appendStringInfo(str, buf);
+
}
static void
-_outFjoin(StringInfo str, Fjoin *node)
+_outFjoin(StringInfo str, Fjoin * node)
{
- char buf[500];
- int i;
-
- sprintf(buf, "FJOIN");
- appendStringInfo(str,buf);
- sprintf(buf, " :initialized %s", node->fj_initialized ? "true":"nil");
- appendStringInfo(str,buf);
- sprintf(buf, " :nNodes %d", node->fj_nNodes);
- appendStringInfo(str,buf);
-
- appendStringInfo(str," :innerNode ");
- appendStringInfo(str,buf);
- _outNode(str, node->fj_innerNode);
-
- sprintf(buf, " :results @ 0x%x ", (int)(node->fj_results));
- appendStringInfo(str, buf);
-
- appendStringInfo( str, " :alwaysdone ");
- for (i = 0; i<node->fj_nNodes; i++)
+ char buf[500];
+ int i;
+
+ sprintf(buf, "FJOIN");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :initialized %s", node->fj_initialized ? "true" : "nil");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :nNodes %d", node->fj_nNodes);
+ appendStringInfo(str, buf);
+
+ appendStringInfo(str, " :innerNode ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->fj_innerNode);
+
+ sprintf(buf, " :results @ 0x%x ", (int) (node->fj_results));
+ appendStringInfo(str, buf);
+
+ appendStringInfo(str, " :alwaysdone ");
+ for (i = 0; i < node->fj_nNodes; i++)
{
- sprintf(buf, " %s ", ((node->fj_alwaysDone[i]) ? "true" : "nil"));
- appendStringInfo(str, buf);
+ sprintf(buf, " %s ", ((node->fj_alwaysDone[i]) ? "true" : "nil"));
+ appendStringInfo(str, buf);
}
}
/*
- * Expr is a subclass of Node
+ * Expr is a subclass of Node
*/
static void
-_outExpr(StringInfo str, Expr *node)
+_outExpr(StringInfo str, Expr * node)
{
- char buf[500];
- char *opstr = NULL;
-
- sprintf(buf, "EXPR");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :typeOid %u", node->typeOid);
- appendStringInfo(str,buf);
- switch(node->opType) {
- case OP_EXPR:
- opstr = "op";
- break;
- case FUNC_EXPR:
- opstr = "func";
- break;
- case OR_EXPR:
- opstr = "or";
- break;
- case AND_EXPR:
- opstr = "and";
- break;
- case NOT_EXPR:
- opstr = "not";
- break;
- }
- sprintf(buf, " :opType %s", opstr);
- appendStringInfo(str,buf);
- sprintf(buf, " :oper ");
- appendStringInfo(str,buf);
- _outNode(str, node->oper);
- sprintf(buf, " :args ");
- appendStringInfo(str,buf);
- _outNode(str, node->args);
+ char buf[500];
+ char *opstr = NULL;
+
+ sprintf(buf, "EXPR");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :typeOid %u", node->typeOid);
+ appendStringInfo(str, buf);
+ switch (node->opType)
+ {
+ case OP_EXPR:
+ opstr = "op";
+ break;
+ case FUNC_EXPR:
+ opstr = "func";
+ break;
+ case OR_EXPR:
+ opstr = "or";
+ break;
+ case AND_EXPR:
+ opstr = "and";
+ break;
+ case NOT_EXPR:
+ opstr = "not";
+ break;
+ }
+ sprintf(buf, " :opType %s", opstr);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :oper ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->oper);
+ sprintf(buf, " :args ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->args);
}
/*
- * Var is a subclass of Expr
+ * Var is a subclass of Expr
*/
static void
-_outVar(StringInfo str, Var *node)
+_outVar(StringInfo str, Var * node)
{
- char buf[500];
-
- sprintf(buf, "VAR");
- appendStringInfo(str,buf);
- sprintf(buf, " :varno %d", node->varno);
- appendStringInfo(str,buf);
- sprintf(buf, " :varattno %hd", node->varattno);
- appendStringInfo(str,buf);
- sprintf(buf, " :vartype %u", node->vartype);
- appendStringInfo(str,buf);
- sprintf(buf, " :varnoold %d", node->varnoold);
- appendStringInfo(str,buf);
- sprintf(buf, " :varoattno %d", node->varoattno);
- appendStringInfo(str,buf);
+ char buf[500];
+
+ sprintf(buf, "VAR");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :varno %d", node->varno);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :varattno %hd", node->varattno);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :vartype %u", node->vartype);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :varnoold %d", node->varnoold);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :varoattno %d", node->varoattno);
+ appendStringInfo(str, buf);
}
/*
- * Const is a subclass of Expr
+ * Const is a subclass of Expr
*/
static void
-_outConst(StringInfo str, Const *node)
+_outConst(StringInfo str, Const * node)
{
- char buf[500];
-
- sprintf(buf, "CONST");
- appendStringInfo(str,buf);
- sprintf(buf, " :consttype %u", node->consttype);
- appendStringInfo(str,buf);
- sprintf(buf, " :constlen %hd", node->constlen);
- appendStringInfo(str,buf);
- sprintf(buf, " :constisnull %s", (node->constisnull ? "true" : "nil"));
- appendStringInfo(str,buf);
- sprintf(buf, " :constvalue ");
- appendStringInfo(str,buf);
- if (node->constisnull) {
- sprintf(buf, "NIL ");
- appendStringInfo(str,buf);
- } else {
- _outDatum(str, node->constvalue, node->consttype);
- }
- sprintf(buf, " :constbyval %s", (node->constbyval ? "true" : "nil"));
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "CONST");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :consttype %u", node->consttype);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :constlen %hd", node->constlen);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :constisnull %s", (node->constisnull ? "true" : "nil"));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :constvalue ");
+ appendStringInfo(str, buf);
+ if (node->constisnull)
+ {
+ sprintf(buf, "NIL ");
+ appendStringInfo(str, buf);
+ }
+ else
+ {
+ _outDatum(str, node->constvalue, node->consttype);
+ }
+ sprintf(buf, " :constbyval %s", (node->constbyval ? "true" : "nil"));
+ appendStringInfo(str, buf);
+
}
/*
- * Aggreg
+ * Aggreg
*/
static void
-_outAggreg(StringInfo str, Aggreg *node)
+_outAggreg(StringInfo str, Aggreg * node)
{
- char buf[500];
-
- sprintf(buf, "AGGREG");
- appendStringInfo(str,buf);
- sprintf(buf, " :aggname \"%s\"", (char*)node->aggname);
- appendStringInfo(str,buf);
- sprintf(buf, " :basetype %u", node->basetype);
- appendStringInfo(str,buf);
- sprintf(buf, " :aggtype %u", node->aggtype);
- appendStringInfo(str,buf);
- sprintf(buf, " :aggno %d", node->aggno);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :target ");
- appendStringInfo(str,buf);
- _outNode(str, node->target);
+ char buf[500];
+
+ sprintf(buf, "AGGREG");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :aggname \"%s\"", (char *) node->aggname);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :basetype %u", node->basetype);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :aggtype %u", node->aggtype);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :aggno %d", node->aggno);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :target ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->target);
}
/*
- * Array is a subclass of Expr
+ * Array is a subclass of Expr
*/
static void
-_outArray(StringInfo str, Array *node)
+_outArray(StringInfo str, Array * node)
{
- char buf[500];
- int i;
- sprintf(buf, "ARRAY");
- appendStringInfo(str, buf);
- sprintf(buf, " :arrayelemtype %u", node->arrayelemtype);
- appendStringInfo(str, buf);
- sprintf(buf, " :arrayelemlength %d", node->arrayelemlength);
- appendStringInfo(str, buf);
- sprintf(buf, " :arrayelembyval %c", (node->arrayelembyval) ? 't' : 'f');
- appendStringInfo(str, buf);
- sprintf(buf, " :arrayndim %d", node->arrayndim);
- appendStringInfo(str, buf);
- sprintf(buf, " :arraylow ");
- appendStringInfo(str, buf);
- for (i = 0; i < node->arrayndim; i++){
- sprintf(buf, " %d", node->arraylow.indx[i]);
- appendStringInfo(str, buf);
- }
- sprintf(buf, " :arrayhigh ");
- appendStringInfo(str, buf);
- for (i = 0; i < node->arrayndim; i++){
- sprintf(buf, " %d", node->arrayhigh.indx[i]);
- appendStringInfo(str, buf);
- }
- sprintf(buf, " :arraylen %d", node->arraylen);
- appendStringInfo(str, buf);
+ char buf[500];
+ int i;
+
+ sprintf(buf, "ARRAY");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :arrayelemtype %u", node->arrayelemtype);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :arrayelemlength %d", node->arrayelemlength);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :arrayelembyval %c", (node->arrayelembyval) ? 't' : 'f');
+ appendStringInfo(str, buf);
+ sprintf(buf, " :arrayndim %d", node->arrayndim);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :arraylow ");
+ appendStringInfo(str, buf);
+ for (i = 0; i < node->arrayndim; i++)
+ {
+ sprintf(buf, " %d", node->arraylow.indx[i]);
+ appendStringInfo(str, buf);
+ }
+ sprintf(buf, " :arrayhigh ");
+ appendStringInfo(str, buf);
+ for (i = 0; i < node->arrayndim; i++)
+ {
+ sprintf(buf, " %d", node->arrayhigh.indx[i]);
+ appendStringInfo(str, buf);
+ }
+ sprintf(buf, " :arraylen %d", node->arraylen);
+ appendStringInfo(str, buf);
}
/*
- * ArrayRef is a subclass of Expr
+ * ArrayRef is a subclass of Expr
*/
static void
-_outArrayRef(StringInfo str, ArrayRef *node)
+_outArrayRef(StringInfo str, ArrayRef * node)
{
- char buf[500];
-
- sprintf(buf, "ARRAYREF");
- appendStringInfo(str, buf);
- sprintf(buf, " :refelemtype %u", node->refelemtype);
- appendStringInfo(str, buf);
- sprintf(buf, " :refattrlength %d", node->refattrlength);
- appendStringInfo(str, buf);
- sprintf(buf, " :refelemlength %d", node->refelemlength);
- appendStringInfo(str, buf);
- sprintf(buf, " :refelembyval %c", (node->refelembyval) ? 't' : 'f');
- appendStringInfo(str, buf);
-
- sprintf(buf, " :refupperindex ");
- appendStringInfo(str, buf);
- _outNode(str, node->refupperindexpr);
-
- sprintf(buf, " :reflowerindex ");
- appendStringInfo(str, buf);
- _outNode(str, node->reflowerindexpr);
-
- sprintf(buf, " :refexpr ");
- appendStringInfo(str, buf);
- _outNode(str, node->refexpr);
-
- sprintf(buf, " :refassgnexpr ");
- appendStringInfo(str, buf);
- _outNode(str, node->refassgnexpr);
+ char buf[500];
+
+ sprintf(buf, "ARRAYREF");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :refelemtype %u", node->refelemtype);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :refattrlength %d", node->refattrlength);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :refelemlength %d", node->refelemlength);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :refelembyval %c", (node->refelembyval) ? 't' : 'f');
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :refupperindex ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->refupperindexpr);
+
+ sprintf(buf, " :reflowerindex ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->reflowerindexpr);
+
+ sprintf(buf, " :refexpr ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->refexpr);
+
+ sprintf(buf, " :refassgnexpr ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->refassgnexpr);
}
/*
- * Func is a subclass of Expr
+ * Func is a subclass of Expr
*/
static void
-_outFunc(StringInfo str, Func *node)
+_outFunc(StringInfo str, Func * node)
{
- char buf[500];
-
- sprintf(buf, "FUNC");
- appendStringInfo(str,buf);
- sprintf(buf, " :funcid %u", node->funcid);
- appendStringInfo(str,buf);
- sprintf(buf, " :functype %u", node->functype);
- appendStringInfo(str,buf);
- sprintf(buf, " :funcisindex %s",
- (node->funcisindex ? "true" : "nil"));
- appendStringInfo(str,buf);
- sprintf(buf, " :funcsize %d", node->funcsize);
- appendStringInfo(str, buf);
- sprintf(buf, " :func_fcache @ 0x%x", (int)(node->func_fcache));
- appendStringInfo(str, buf);
-
- appendStringInfo(str, " :func_tlist ");
- _outNode(str, node->func_tlist);
-
- appendStringInfo(str, " :func_planlist ");
- _outNode(str, node->func_planlist);
+ char buf[500];
+
+ sprintf(buf, "FUNC");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :funcid %u", node->funcid);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :functype %u", node->functype);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :funcisindex %s",
+ (node->funcisindex ? "true" : "nil"));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :funcsize %d", node->funcsize);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :func_fcache @ 0x%x", (int) (node->func_fcache));
+ appendStringInfo(str, buf);
+
+ appendStringInfo(str, " :func_tlist ");
+ _outNode(str, node->func_tlist);
+
+ appendStringInfo(str, " :func_planlist ");
+ _outNode(str, node->func_planlist);
}
/*
- * Oper is a subclass of Expr
+ * Oper is a subclass of Expr
*/
static void
-_outOper(StringInfo str, Oper *node)
+_outOper(StringInfo str, Oper * node)
{
- char buf[500];
-
- sprintf(buf, "OPER");
- appendStringInfo(str,buf);
- sprintf(buf, " :opno %u", node->opno);
- appendStringInfo(str,buf);
- sprintf(buf, " :opid %u", node->opid);
- appendStringInfo(str,buf);
- sprintf(buf, " :opresulttype %u", node->opresulttype);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "OPER");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :opno %u", node->opno);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :opid %u", node->opid);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :opresulttype %u", node->opresulttype);
+ appendStringInfo(str, buf);
+
}
/*
- * Param is a subclass of Expr
+ * Param is a subclass of Expr
*/
static void
-_outParam(StringInfo str, Param *node)
+_outParam(StringInfo str, Param * node)
{
- char buf[500];
-
- sprintf(buf, "PARAM");
- appendStringInfo(str,buf);
- sprintf(buf, " :paramkind %d", node->paramkind);
- appendStringInfo(str,buf);
- sprintf(buf, " :paramid %hd", node->paramid);
- appendStringInfo(str,buf);
- sprintf(buf, " :paramname \"%s\"", node->paramname);
- appendStringInfo(str,buf);
- sprintf(buf, " :paramtype %u", node->paramtype);
- appendStringInfo(str,buf);
-
- appendStringInfo(str, " :param_tlist ");
- _outNode(str, node->param_tlist);
+ char buf[500];
+
+ sprintf(buf, "PARAM");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :paramkind %d", node->paramkind);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :paramid %hd", node->paramid);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :paramname \"%s\"", node->paramname);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :paramtype %u", node->paramtype);
+ appendStringInfo(str, buf);
+
+ appendStringInfo(str, " :param_tlist ");
+ _outNode(str, node->param_tlist);
}
/*
- * Stuff from execnodes.h
+ * Stuff from execnodes.h
*/
/*
- * EState is a subclass of Node.
+ * EState is a subclass of Node.
*/
static void
-_outEState(StringInfo str, EState *node)
+_outEState(StringInfo str, EState * node)
{
- char buf[500];
-
- sprintf(buf, "ESTATE");
- appendStringInfo(str,buf);
- sprintf(buf, " :direction %d", node->es_direction);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :range_table ");
- appendStringInfo(str,buf);
- _outNode(str, node->es_range_table);
-
- sprintf(buf, " :result_relation_info @ 0x%x",
- (int) (node->es_result_relation_info));
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "ESTATE");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :direction %d", node->es_direction);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :range_table ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->es_range_table);
+
+ sprintf(buf, " :result_relation_info @ 0x%x",
+ (int) (node->es_result_relation_info));
+ appendStringInfo(str, buf);
+
}
/*
- * Stuff from relation.h
+ * Stuff from relation.h
*/
static void
-_outRel(StringInfo str, Rel *node)
+_outRel(StringInfo str, Rel * node)
{
- char buf[500];
-
- sprintf(buf, "REL");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :relids ");
- appendStringInfo(str,buf);
- _outIntList(str, node->relids);
-
- sprintf(buf, " :indexed %s", (node->indexed ? "true" : "nil"));
- appendStringInfo(str,buf);
- sprintf(buf, " :pages %u", node->pages);
- appendStringInfo(str,buf);
- sprintf(buf, " :tuples %u", node->tuples);
- appendStringInfo(str,buf);
- sprintf(buf, " :size %u", node->size);
- appendStringInfo(str,buf);
- sprintf(buf, " :width %u", node->width);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :targetlist ");
- appendStringInfo(str,buf);
- _outNode(str, node->targetlist);
-
- sprintf(buf, " :pathlist ");
- appendStringInfo(str,buf);
- _outNode(str, node->pathlist);
-
- /*
- * Not sure if these are nodes or not. They're declared as
- * struct Path *. Since i don't know, i'll just print the
- * addresses for now. This can be changed later, if necessary.
- */
-
- sprintf(buf, " :unorderedpath @ 0x%x", (int)(node->unorderedpath));
- appendStringInfo(str,buf);
- sprintf(buf, " :cheapestpath @ 0x%x", (int)(node->cheapestpath));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :pruneable %s", (node->pruneable ? "true" : "nil"));
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "REL");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :relids ");
+ appendStringInfo(str, buf);
+ _outIntList(str, node->relids);
+
+ sprintf(buf, " :indexed %s", (node->indexed ? "true" : "nil"));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :pages %u", node->pages);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :tuples %u", node->tuples);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :size %u", node->size);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :width %u", node->width);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :targetlist ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->targetlist);
+
+ sprintf(buf, " :pathlist ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->pathlist);
+
+ /*
+ * Not sure if these are nodes or not. They're declared as struct
+ * Path *. Since i don't know, i'll just print the addresses for now.
+ * This can be changed later, if necessary.
+ */
+
+ sprintf(buf, " :unorderedpath @ 0x%x", (int) (node->unorderedpath));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :cheapestpath @ 0x%x", (int) (node->cheapestpath));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :pruneable %s", (node->pruneable ? "true" : "nil"));
+ appendStringInfo(str, buf);
+
#if 0
- sprintf(buf, " :classlist ");
- appendStringInfo(str,buf);
- _outNode(str, node->classlist);
-
- sprintf(buf, " :indexkeys ");
- appendStringInfo(str,buf);
- _outNode(str, node->indexkeys);
-
- sprintf(buf, " :ordering ");
- appendStringInfo(str,buf);
- _outNode(str, node->ordering);
-#endif
-
- sprintf(buf, " :clauseinfo ");
- appendStringInfo(str,buf);
- _outNode(str, node->clauseinfo);
-
- sprintf(buf, " :joininfo ");
- appendStringInfo(str,buf);
- _outNode(str, node->joininfo);
-
- sprintf(buf, " :innerjoin ");
- appendStringInfo(str,buf);
- _outNode(str, node->innerjoin);
-
+ sprintf(buf, " :classlist ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->classlist);
+
+ sprintf(buf, " :indexkeys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->indexkeys);
+
+ sprintf(buf, " :ordering ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->ordering);
+#endif
+
+ sprintf(buf, " :clauseinfo ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->clauseinfo);
+
+ sprintf(buf, " :joininfo ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->joininfo);
+
+ sprintf(buf, " :innerjoin ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->innerjoin);
+
}
/*
- * TargetEntry is a subclass of Node.
+ * TargetEntry is a subclass of Node.
*/
static void
-_outTargetEntry(StringInfo str, TargetEntry *node)
+_outTargetEntry(StringInfo str, TargetEntry * node)
{
- char buf[500];
-
- sprintf(buf, "TLE");
- appendStringInfo(str,buf);
- sprintf(buf, " :resdom ");
- appendStringInfo(str,buf);
- _outNode(str, node->resdom);
-
- sprintf(buf, " :expr ");
- appendStringInfo(str,buf);
- if (node->expr) {
- _outNode(str, node->expr);
- }else {
- appendStringInfo(str, "nil");
- }
-}
+ char buf[500];
+
+ sprintf(buf, "TLE");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :resdom ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->resdom);
+
+ sprintf(buf, " :expr ");
+ appendStringInfo(str, buf);
+ if (node->expr)
+ {
+ _outNode(str, node->expr);
+ }
+ else
+ {
+ appendStringInfo(str, "nil");
+ }
+}
static void
-_outRangeTblEntry(StringInfo str, RangeTblEntry *node)
+_outRangeTblEntry(StringInfo str, RangeTblEntry * node)
{
- char buf[500];
-
- sprintf(buf, "RTE");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :relname \"%s\"",
- ((node->relname) ? ((char *) node->relname) : "null"));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :inh %d ", node->inh);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :refname \"%s\"",
- ((node->refname) ? ((char *) node->refname) : "null"));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :relid %u ", node->relid);
- appendStringInfo(str,buf);
-}
+ char buf[500];
+
+ sprintf(buf, "RTE");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :relname \"%s\"",
+ ((node->relname) ? ((char *) node->relname) : "null"));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :inh %d ", node->inh);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :refname \"%s\"",
+ ((node->refname) ? ((char *) node->refname) : "null"));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :relid %u ", node->relid);
+ appendStringInfo(str, buf);
+}
/*
- * Path is a subclass of Node.
+ * Path is a subclass of Node.
*/
static void
-_outPath(StringInfo str, Path *node)
+_outPath(StringInfo str, Path * node)
{
- char buf[500];
-
- sprintf(buf, "PATH");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :pathtype %d", node->pathtype);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :cost %f", node->path_cost);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :keys ");
- appendStringInfo(str,buf);
- _outNode(str, node->keys);
-
+ char buf[500];
+
+ sprintf(buf, "PATH");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :pathtype %d", node->pathtype);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :cost %f", node->path_cost);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :keys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->keys);
+
}
/*
- * IndexPath is a subclass of Path.
+ * IndexPath is a subclass of Path.
*/
static void
-_outIndexPath(StringInfo str, IndexPath *node)
+_outIndexPath(StringInfo str, IndexPath * node)
{
- char buf[500];
-
- sprintf(buf, "INDEXPATH");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :pathtype %d", node->path.pathtype);
- appendStringInfo(str,buf);
-
- /* sprintf(buf, " :parent ");
- appendStringInfo(str,buf);
- _outNode(str, node->parent); */
-
- sprintf(buf, " :cost %f", node->path.path_cost);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "INDEXPATH");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :pathtype %d", node->path.pathtype);
+ appendStringInfo(str, buf);
+
+ /*
+ * sprintf(buf, " :parent "); appendStringInfo(str,buf); _outNode(str,
+ * node->parent);
+ */
+
+ sprintf(buf, " :cost %f", node->path.path_cost);
+ appendStringInfo(str, buf);
+
#if 0
- sprintf(buf, " :p_ordering ");
- appendStringInfo(str,buf);
- _outNode(str, node->path.p_ordering);
-#endif
- sprintf(buf, " :keys ");
- appendStringInfo(str,buf);
- _outNode(str, node->path.keys);
-
- sprintf(buf, " :indexid ");
- appendStringInfo(str,buf);
- _outIntList(str, node->indexid);
-
- sprintf(buf, " :indexqual ");
- appendStringInfo(str,buf);
- _outNode(str, node->indexqual);
-
+ sprintf(buf, " :p_ordering ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->path.p_ordering);
+#endif
+ sprintf(buf, " :keys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->path.keys);
+
+ sprintf(buf, " :indexid ");
+ appendStringInfo(str, buf);
+ _outIntList(str, node->indexid);
+
+ sprintf(buf, " :indexqual ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->indexqual);
+
}
/*
- * JoinPath is a subclass of Path
+ * JoinPath is a subclass of Path
*/
static void
-_outJoinPath(StringInfo str, JoinPath *node)
+_outJoinPath(StringInfo str, JoinPath * node)
{
- char buf[500];
-
- sprintf(buf, "JOINPATH");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :pathtype %d", node->path.pathtype);
- appendStringInfo(str,buf);
-
- /* sprintf(buf, " :parent ");
- appendStringInfo(str,buf);
- _outNode(str, node->parent); */
-
- sprintf(buf, " :cost %f", node->path.path_cost);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "JOINPATH");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :pathtype %d", node->path.pathtype);
+ appendStringInfo(str, buf);
+
+ /*
+ * sprintf(buf, " :parent "); appendStringInfo(str,buf); _outNode(str,
+ * node->parent);
+ */
+
+ sprintf(buf, " :cost %f", node->path.path_cost);
+ appendStringInfo(str, buf);
+
#if 0
- sprintf(buf, " :p_ordering ");
- appendStringInfo(str,buf);
- _outNode(str, node->path.p_ordering);
-#endif
- sprintf(buf, " :keys ");
- appendStringInfo(str,buf);
- _outNode(str, node->path.keys);
-
- sprintf(buf, " :pathclauseinfo ");
- appendStringInfo(str,buf);
- _outNode(str, node->pathclauseinfo);
-
- /*
- * Not sure if these are nodes; they're declared as "struct path *".
- * For now, i'll just print the addresses.
- */
-
- sprintf(buf, " :outerjoinpath @ 0x%x", (int)(node->outerjoinpath));
- appendStringInfo(str,buf);
- sprintf(buf, " :innerjoinpath @ 0x%x", (int)(node->innerjoinpath));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :outerjoincost %f", node->path.outerjoincost);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :joinid ");
- appendStringInfo(str,buf);
- _outIntList(str, node->path.joinid);
-
+ sprintf(buf, " :p_ordering ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->path.p_ordering);
+#endif
+ sprintf(buf, " :keys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->path.keys);
+
+ sprintf(buf, " :pathclauseinfo ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->pathclauseinfo);
+
+ /*
+ * Not sure if these are nodes; they're declared as "struct path *".
+ * For now, i'll just print the addresses.
+ */
+
+ sprintf(buf, " :outerjoinpath @ 0x%x", (int) (node->outerjoinpath));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :innerjoinpath @ 0x%x", (int) (node->innerjoinpath));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :outerjoincost %f", node->path.outerjoincost);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :joinid ");
+ appendStringInfo(str, buf);
+ _outIntList(str, node->path.joinid);
+
}
/*
- * MergePath is a subclass of JoinPath.
+ * MergePath is a subclass of JoinPath.
*/
static void
-_outMergePath(StringInfo str, MergePath *node)
+_outMergePath(StringInfo str, MergePath * node)
{
- char buf[500];
-
- sprintf(buf, "MERGEPATH");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :pathtype %d", node->jpath.path.pathtype);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :cost %f", node->jpath.path.path_cost);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :keys ");
- appendStringInfo(str,buf);
- _outNode(str, node->jpath.path.keys);
-
- sprintf(buf, " :pathclauseinfo ");
- appendStringInfo(str,buf);
- _outNode(str, node->jpath.pathclauseinfo);
-
- /*
- * Not sure if these are nodes; they're declared as "struct path *".
- * For now, i'll just print the addresses.
- */
-
- sprintf(buf, " :outerjoinpath @ 0x%x", (int)(node->jpath.outerjoinpath));
- appendStringInfo(str,buf);
- sprintf(buf, " :innerjoinpath @ 0x%x", (int)(node->jpath.innerjoinpath));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :outerjoincost %f", node->jpath.path.outerjoincost);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :joinid ");
- appendStringInfo(str,buf);
- _outIntList(str, node->jpath.path.joinid);
-
- sprintf(buf, " :path_mergeclauses ");
- appendStringInfo(str,buf);
- _outNode(str, node->path_mergeclauses);
-
- sprintf(buf, " :outersortkeys ");
- appendStringInfo(str,buf);
- _outNode(str, node->outersortkeys);
-
- sprintf(buf, " :innersortkeys ");
- appendStringInfo(str,buf);
- _outNode(str, node->innersortkeys);
-
+ char buf[500];
+
+ sprintf(buf, "MERGEPATH");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :pathtype %d", node->jpath.path.pathtype);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :cost %f", node->jpath.path.path_cost);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :keys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->jpath.path.keys);
+
+ sprintf(buf, " :pathclauseinfo ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->jpath.pathclauseinfo);
+
+ /*
+ * Not sure if these are nodes; they're declared as "struct path *".
+ * For now, i'll just print the addresses.
+ */
+
+ sprintf(buf, " :outerjoinpath @ 0x%x", (int) (node->jpath.outerjoinpath));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :innerjoinpath @ 0x%x", (int) (node->jpath.innerjoinpath));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :outerjoincost %f", node->jpath.path.outerjoincost);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :joinid ");
+ appendStringInfo(str, buf);
+ _outIntList(str, node->jpath.path.joinid);
+
+ sprintf(buf, " :path_mergeclauses ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->path_mergeclauses);
+
+ sprintf(buf, " :outersortkeys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->outersortkeys);
+
+ sprintf(buf, " :innersortkeys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->innersortkeys);
+
}
/*
- * HashPath is a subclass of JoinPath.
+ * HashPath is a subclass of JoinPath.
*/
static void
-_outHashPath(StringInfo str, HashPath *node)
+_outHashPath(StringInfo str, HashPath * node)
{
- char buf[500];
-
- sprintf(buf, "HASHPATH");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :pathtype %d", node->jpath.path.pathtype);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :cost %f", node->jpath.path.path_cost);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :keys ");
- appendStringInfo(str,buf);
- _outNode(str, node->jpath.path.keys);
-
- sprintf(buf, " :pathclauseinfo ");
- appendStringInfo(str,buf);
- _outNode(str, node->jpath.pathclauseinfo);
-
- /*
- * Not sure if these are nodes; they're declared as "struct path *".
- * For now, i'll just print the addresses.
- */
-
- sprintf(buf, " :outerjoinpath @ 0x%x", (int) (node->jpath.outerjoinpath));
- appendStringInfo(str,buf);
- sprintf(buf, " :innerjoinpath @ 0x%x", (int) (node->jpath.innerjoinpath));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :outerjoincost %f", node->jpath.path.outerjoincost);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :joinid ");
- appendStringInfo(str,buf);
- _outIntList(str, node->jpath.path.joinid);
-
- sprintf(buf, " :path_hashclauses ");
- appendStringInfo(str,buf);
- _outNode(str, node->path_hashclauses);
-
- sprintf(buf, " :outerhashkeys ");
- appendStringInfo(str,buf);
- _outNode(str, node->outerhashkeys);
-
- sprintf(buf, " :innerhashkeys ");
- appendStringInfo(str,buf);
- _outNode(str, node->innerhashkeys);
-
+ char buf[500];
+
+ sprintf(buf, "HASHPATH");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :pathtype %d", node->jpath.path.pathtype);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :cost %f", node->jpath.path.path_cost);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :keys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->jpath.path.keys);
+
+ sprintf(buf, " :pathclauseinfo ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->jpath.pathclauseinfo);
+
+ /*
+ * Not sure if these are nodes; they're declared as "struct path *".
+ * For now, i'll just print the addresses.
+ */
+
+ sprintf(buf, " :outerjoinpath @ 0x%x", (int) (node->jpath.outerjoinpath));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :innerjoinpath @ 0x%x", (int) (node->jpath.innerjoinpath));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :outerjoincost %f", node->jpath.path.outerjoincost);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :joinid ");
+ appendStringInfo(str, buf);
+ _outIntList(str, node->jpath.path.joinid);
+
+ sprintf(buf, " :path_hashclauses ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->path_hashclauses);
+
+ sprintf(buf, " :outerhashkeys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->outerhashkeys);
+
+ sprintf(buf, " :innerhashkeys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->innerhashkeys);
+
}
/*
- * OrderKey is a subclass of Node.
+ * OrderKey is a subclass of Node.
*/
static void
-_outOrderKey(StringInfo str, OrderKey *node)
+_outOrderKey(StringInfo str, OrderKey * node)
{
- char buf[500];
-
- sprintf(buf, "ORDERKEY");
- appendStringInfo(str,buf);
- sprintf(buf, " :attribute_number %d", node->attribute_number);
- appendStringInfo(str,buf);
- sprintf(buf, " :array_index %d", node->array_index);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "ORDERKEY");
+ appendStringInfo(str, buf);
+ sprintf(buf, " :attribute_number %d", node->attribute_number);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :array_index %d", node->array_index);
+ appendStringInfo(str, buf);
+
}
/*
- * JoinKey is a subclass of Node.
+ * JoinKey is a subclass of Node.
*/
static void
-_outJoinKey(StringInfo str, JoinKey *node)
+_outJoinKey(StringInfo str, JoinKey * node)
{
- char buf[500];
-
- sprintf(buf, "JOINKEY");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :outer ");
- appendStringInfo(str,buf);
- _outNode(str, node->outer);
-
- sprintf(buf, " :inner ");
- appendStringInfo(str,buf);
- _outNode(str, node->inner);
-
+ char buf[500];
+
+ sprintf(buf, "JOINKEY");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :outer ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->outer);
+
+ sprintf(buf, " :inner ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->inner);
+
}
/*
- * MergeOrder is a subclass of Node.
+ * MergeOrder is a subclass of Node.
*/
static void
-_outMergeOrder(StringInfo str, MergeOrder *node)
+_outMergeOrder(StringInfo str, MergeOrder * node)
{
- char buf[500];
-
- sprintf(buf, "MERGEORDER");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :join_operator %d", node->join_operator);
- appendStringInfo(str,buf);
- sprintf(buf, " :left_operator %d", node->left_operator);
- appendStringInfo(str,buf);
- sprintf(buf, " :right_operator %d", node->right_operator);
- appendStringInfo(str,buf);
- sprintf(buf, " :left_type %d", node->left_type);
- appendStringInfo(str,buf);
- sprintf(buf, " :right_type %d", node->right_type);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "MERGEORDER");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :join_operator %d", node->join_operator);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :left_operator %d", node->left_operator);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :right_operator %d", node->right_operator);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :left_type %d", node->left_type);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :right_type %d", node->right_type);
+ appendStringInfo(str, buf);
+
}
/*
- * CInfo is a subclass of Node.
+ * CInfo is a subclass of Node.
*/
static void
-_outCInfo(StringInfo str, CInfo *node)
+_outCInfo(StringInfo str, CInfo * node)
{
- char buf[500];
-
- sprintf(buf, "CINFO");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :clause ");
- appendStringInfo(str,buf);
- _outNode(str, node->clause);
-
- sprintf(buf, " :selectivity %f", node->selectivity);
- appendStringInfo(str,buf);
- sprintf(buf, " :notclause %s", (node->notclause ? "true" : "nil"));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :indexids ");
- appendStringInfo(str,buf);
- _outNode(str, node->indexids);
-
- sprintf(buf, " :mergesortorder ");
- appendStringInfo(str,buf);
- _outNode(str, node->mergesortorder);
-
- sprintf(buf, " :hashjoinoperator %u", node->hashjoinoperator);
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "CINFO");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :clause ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->clause);
+
+ sprintf(buf, " :selectivity %f", node->selectivity);
+ appendStringInfo(str, buf);
+ sprintf(buf, " :notclause %s", (node->notclause ? "true" : "nil"));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :indexids ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->indexids);
+
+ sprintf(buf, " :mergesortorder ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->mergesortorder);
+
+ sprintf(buf, " :hashjoinoperator %u", node->hashjoinoperator);
+ appendStringInfo(str, buf);
+
}
/*
- * JoinMethod is a subclass of Node.
+ * JoinMethod is a subclass of Node.
*/
static void
-_outJoinMethod(StringInfo str, JoinMethod *node)
+_outJoinMethod(StringInfo str, JoinMethod * node)
{
- char buf[500];
-
- sprintf(buf, "JOINMETHOD");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :jmkeys ");
- appendStringInfo(str,buf);
- _outNode(str, node->jmkeys);
-
- sprintf(buf, " :clauses ");
- appendStringInfo(str,buf);
- _outNode(str, node->clauses);
-
-
+ char buf[500];
+
+ sprintf(buf, "JOINMETHOD");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :jmkeys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->jmkeys);
+
+ sprintf(buf, " :clauses ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->clauses);
+
+
}
/*
* HInfo is a subclass of JoinMethod.
*/
static void
-_outHInfo(StringInfo str, HInfo *node)
+_outHInfo(StringInfo str, HInfo * node)
{
- char buf[500];
-
- sprintf(buf, "HASHINFO");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :hashop ");
- appendStringInfo(str,buf);
- sprintf(buf, "%u",node->hashop);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :jmkeys ");
- appendStringInfo(str,buf);
- _outNode(str, node->jmethod.jmkeys);
-
- sprintf(buf, " :clauses ");
- appendStringInfo(str,buf);
- _outNode(str, node->jmethod.clauses);
-
+ char buf[500];
+
+ sprintf(buf, "HASHINFO");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :hashop ");
+ appendStringInfo(str, buf);
+ sprintf(buf, "%u", node->hashop);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :jmkeys ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->jmethod.jmkeys);
+
+ sprintf(buf, " :clauses ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->jmethod.clauses);
+
}
/*
- * JInfo is a subclass of Node.
+ * JInfo is a subclass of Node.
*/
static void
-_outJInfo(StringInfo str, JInfo *node)
+_outJInfo(StringInfo str, JInfo * node)
{
- char buf[500];
-
- sprintf(buf, "JINFO");
- appendStringInfo(str,buf);
-
- sprintf(buf, " :otherrels ");
- appendStringInfo(str,buf);
- _outIntList(str, node->otherrels);
-
- sprintf(buf, " :jinfoclauseinfo ");
- appendStringInfo(str,buf);
- _outNode(str, node->jinfoclauseinfo);
-
- sprintf(buf, " :mergesortable %s",
- (node->mergesortable ? "true" : "nil"));
- appendStringInfo(str,buf);
- sprintf(buf, " :hashjoinable %s",
- (node->hashjoinable ? "true" : "nil"));
- appendStringInfo(str,buf);
-
+ char buf[500];
+
+ sprintf(buf, "JINFO");
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :otherrels ");
+ appendStringInfo(str, buf);
+ _outIntList(str, node->otherrels);
+
+ sprintf(buf, " :jinfoclauseinfo ");
+ appendStringInfo(str, buf);
+ _outNode(str, node->jinfoclauseinfo);
+
+ sprintf(buf, " :mergesortable %s",
+ (node->mergesortable ? "true" : "nil"));
+ appendStringInfo(str, buf);
+ sprintf(buf, " :hashjoinable %s",
+ (node->hashjoinable ? "true" : "nil"));
+ appendStringInfo(str, buf);
+
}
/*
@@ -1352,319 +1369,340 @@ _outJInfo(StringInfo str, JInfo *node)
static void
_outDatum(StringInfo str, Datum value, Oid type)
{
- char buf[500];
- Size length, typeLength;
- bool byValue;
- int i;
- char *s;
-
- /*
- * find some information about the type and the "real" length
- * of the datum.
- */
- byValue = get_typbyval(type);
- typeLength = get_typlen(type);
- length = datumGetSize(value, type, byValue, typeLength);
-
- if (byValue) {
- s = (char *) (&value);
- sprintf(buf, " %d [ ", length);
- appendStringInfo(str,buf);
- for (i=0; i<sizeof(Datum); i++) {
- sprintf(buf, "%d ", (int) (s[i]) );
- appendStringInfo(str,buf);
+ char buf[500];
+ Size length,
+ typeLength;
+ bool byValue;
+ int i;
+ char *s;
+
+ /*
+ * find some information about the type and the "real" length of the
+ * datum.
+ */
+ byValue = get_typbyval(type);
+ typeLength = get_typlen(type);
+ length = datumGetSize(value, type, byValue, typeLength);
+
+ if (byValue)
+ {
+ s = (char *) (&value);
+ sprintf(buf, " %d [ ", length);
+ appendStringInfo(str, buf);
+ for (i = 0; i < sizeof(Datum); i++)
+ {
+ sprintf(buf, "%d ", (int) (s[i]));
+ appendStringInfo(str, buf);
+ }
+ sprintf(buf, "] ");
+ appendStringInfo(str, buf);
}
- sprintf(buf, "] ");
- appendStringInfo(str,buf);
- } else { /* !byValue */
- s = (char *) DatumGetPointer(value);
- if (!PointerIsValid(s)) {
- sprintf(buf, " 0 [ ] ");
- appendStringInfo(str,buf);
- } else {
- /*
- * length is unsigned - very bad to do < comparison to -1 without
- * casting it to int first!! -mer 8 Jan 1991
- */
- if (((int)length) <= -1) {
- length = VARSIZE(s);
- }
- sprintf(buf, " %d [ ", length);
- appendStringInfo(str,buf);
- for (i=0; i<length; i++) {
- sprintf(buf, "%d ", (int) (s[i]) );
- appendStringInfo(str,buf);
- }
- sprintf(buf, "] ");
- appendStringInfo(str,buf);
+ else
+ { /* !byValue */
+ s = (char *) DatumGetPointer(value);
+ if (!PointerIsValid(s))
+ {
+ sprintf(buf, " 0 [ ] ");
+ appendStringInfo(str, buf);
+ }
+ else
+ {
+
+ /*
+ * length is unsigned - very bad to do < comparison to -1
+ * without casting it to int first!! -mer 8 Jan 1991
+ */
+ if (((int) length) <= -1)
+ {
+ length = VARSIZE(s);
+ }
+ sprintf(buf, " %d [ ", length);
+ appendStringInfo(str, buf);
+ for (i = 0; i < length; i++)
+ {
+ sprintf(buf, "%d ", (int) (s[i]));
+ appendStringInfo(str, buf);
+ }
+ sprintf(buf, "] ");
+ appendStringInfo(str, buf);
+ }
}
- }
-
+
}
static void
-_outIter(StringInfo str, Iter *node)
+_outIter(StringInfo str, Iter * node)
{
- appendStringInfo(str,"ITER");
-
- appendStringInfo(str," :iterexpr ");
- _outNode(str, node->iterexpr);
+ appendStringInfo(str, "ITER");
+
+ appendStringInfo(str, " :iterexpr ");
+ _outNode(str, node->iterexpr);
}
static void
-_outStream(StringInfo str, Stream *node)
+_outStream(StringInfo str, Stream * node)
{
- char buf[500];
-
- appendStringInfo(str,"STREAM");
-
- sprintf(buf, " :pathptr @ 0x%x", (int)(node->pathptr));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :cinfo @ 0x%x", (int)(node->cinfo));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :clausetype %d", (int)(node->clausetype));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :upstream @ 0x%x", (int)(node->upstream));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :downstream @ 0x%x", (int)(node->downstream));
- appendStringInfo(str,buf);
-
- sprintf(buf, " :groupup %d", node->groupup);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :groupcost %f", node->groupcost);
- appendStringInfo(str,buf);
-
- sprintf(buf, " :groupsel %f", node->groupsel);
- appendStringInfo(str,buf);
-}
+ char buf[500];
+
+ appendStringInfo(str, "STREAM");
+
+ sprintf(buf, " :pathptr @ 0x%x", (int) (node->pathptr));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :cinfo @ 0x%x", (int) (node->cinfo));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :clausetype %d", (int) (node->clausetype));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :upstream @ 0x%x", (int) (node->upstream));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :downstream @ 0x%x", (int) (node->downstream));
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :groupup %d", node->groupup);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :groupcost %f", node->groupcost);
+ appendStringInfo(str, buf);
+
+ sprintf(buf, " :groupsel %f", node->groupsel);
+ appendStringInfo(str, buf);
+}
static void
-_outValue(StringInfo str, Value *value)
+_outValue(StringInfo str, Value * value)
{
- char buf[500];
-
- switch(value->type) {
- case T_String:
- sprintf(buf, "\"%s\"", value->val.str);
- appendStringInfo(str, buf);
- break;
- case T_Integer:
- sprintf(buf, "%ld", value->val.ival);
- appendStringInfo(str, buf);
- break;
- case T_Float:
- sprintf(buf, "%f", value->val.dval);
- appendStringInfo(str, buf);
- break;
- default:
- break;
- }
- return;
+ char buf[500];
+
+ switch (value->type)
+ {
+ case T_String:
+ sprintf(buf, "\"%s\"", value->val.str);
+ appendStringInfo(str, buf);
+ break;
+ case T_Integer:
+ sprintf(buf, "%ld", value->val.ival);
+ appendStringInfo(str, buf);
+ break;
+ case T_Float:
+ sprintf(buf, "%f", value->val.dval);
+ appendStringInfo(str, buf);
+ break;
+ default:
+ break;
+ }
+ return;
}
/*
* _outNode -
- * converts a Node into ascii string and append it to 'str'
+ * converts a Node into ascii string and append it to 'str'
*/
static void
_outNode(StringInfo str, void *obj)
{
- if (obj==NULL) {
- appendStringInfo(str, "nil");
- return;
- }
+ if (obj == NULL)
+ {
+ appendStringInfo(str, "nil");
+ return;
+ }
- if (nodeTag(obj)==T_List) {
- List *l;
- appendStringInfo(str, "(");
- foreach(l, (List*)obj) {
- _outNode(str, lfirst(l));
- if (lnext(l))
- appendStringInfo(str, " ");
+ if (nodeTag(obj) == T_List)
+ {
+ List *l;
+
+ appendStringInfo(str, "(");
+ foreach(l, (List *) obj)
+ {
+ _outNode(str, lfirst(l));
+ if (lnext(l))
+ appendStringInfo(str, " ");
+ }
+ appendStringInfo(str, ")");
}
- appendStringInfo(str, ")");
- }else {
- appendStringInfo(str, "{");
- switch(nodeTag(obj)) {
- case T_Query:
- _outQuery(str, obj);
- break;
- case T_Plan:
- _outPlan(str, obj);
- break;
- case T_Result:
- _outResult(str, obj);
- break;
- case T_Existential:
- _outExistential(str, obj);
- break;
- case T_Append:
- _outAppend(str, obj);
- break;
- case T_Join:
- _outJoin(str, obj);
- break;
- case T_NestLoop:
- _outNestLoop(str, obj);
- break;
- case T_MergeJoin:
- _outMergeJoin(str, obj);
- break;
- case T_HashJoin:
- _outHashJoin(str, obj);
- break;
- case T_Scan:
- _outScan(str, obj);
- break;
- case T_SeqScan:
- _outSeqScan(str, obj);
- break;
- case T_IndexScan:
- _outIndexScan(str, obj);
- break;
- case T_Temp:
- _outTemp(str, obj);
- break;
- case T_Sort:
- _outSort(str, obj);
- break;
- case T_Agg:
- _outAgg(str, obj);
- break;
- case T_Group:
- _outGroup(str, obj);
- break;
- case T_Unique:
- _outUnique(str, obj);
- break;
- case T_Hash:
- _outHash(str, obj);
- break;
- case T_Tee:
- _outTee(str, obj);
- break;
- case T_Resdom:
- _outResdom(str, obj);
- break;
- case T_Fjoin:
- _outFjoin(str, obj);
- break;
- case T_Expr:
- _outExpr(str, obj);
- break;
- case T_Var:
- _outVar(str, obj);
- break;
- case T_Const:
- _outConst(str, obj);
- break;
- case T_Aggreg:
- _outAggreg(str, obj);
- break;
- case T_Array:
- _outArray(str, obj);
- break;
- case T_ArrayRef:
- _outArrayRef(str, obj);
- break;
- case T_Func:
- _outFunc(str, obj);
- break;
- case T_Oper:
- _outOper(str, obj);
- break;
- case T_Param:
- _outParam(str, obj);
- break;
- case T_EState:
- _outEState(str, obj);
- break;
- case T_Rel:
- _outRel(str, obj);
- break;
- case T_TargetEntry:
- _outTargetEntry(str, obj);
- break;
- case T_RangeTblEntry:
- _outRangeTblEntry(str, obj);
- break;
- case T_Path:
- _outPath(str, obj);
- break;
- case T_IndexPath:
- _outIndexPath (str, obj);
- break;
- case T_JoinPath:
- _outJoinPath(str, obj);
- break;
- case T_MergePath:
- _outMergePath(str, obj);
- break;
- case T_HashPath:
- _outHashPath(str, obj);
- break;
- case T_OrderKey:
- _outOrderKey(str, obj);
- break;
- case T_JoinKey:
- _outJoinKey(str, obj);
- break;
- case T_MergeOrder:
- _outMergeOrder(str, obj);
- break;
- case T_CInfo:
- _outCInfo(str, obj);
- break;
- case T_JoinMethod:
- _outJoinMethod(str, obj);
- break;
- case T_HInfo:
- _outHInfo(str, obj);
- break;
- case T_JInfo:
- _outJInfo(str, obj);
- break;
- case T_Iter:
- _outIter(str, obj);
- break;
- case T_Stream:
- _outStream(str, obj);
- break;
- case T_Integer: case T_String: case T_Float:
- _outValue(str, obj);
- break;
- default:
- elog(NOTICE, "_outNode: don't know how to print type %d",
- nodeTag(obj));
- break;
+ else
+ {
+ appendStringInfo(str, "{");
+ switch (nodeTag(obj))
+ {
+ case T_Query:
+ _outQuery(str, obj);
+ break;
+ case T_Plan:
+ _outPlan(str, obj);
+ break;
+ case T_Result:
+ _outResult(str, obj);
+ break;
+ case T_Existential:
+ _outExistential(str, obj);
+ break;
+ case T_Append:
+ _outAppend(str, obj);
+ break;
+ case T_Join:
+ _outJoin(str, obj);
+ break;
+ case T_NestLoop:
+ _outNestLoop(str, obj);
+ break;
+ case T_MergeJoin:
+ _outMergeJoin(str, obj);
+ break;
+ case T_HashJoin:
+ _outHashJoin(str, obj);
+ break;
+ case T_Scan:
+ _outScan(str, obj);
+ break;
+ case T_SeqScan:
+ _outSeqScan(str, obj);
+ break;
+ case T_IndexScan:
+ _outIndexScan(str, obj);
+ break;
+ case T_Temp:
+ _outTemp(str, obj);
+ break;
+ case T_Sort:
+ _outSort(str, obj);
+ break;
+ case T_Agg:
+ _outAgg(str, obj);
+ break;
+ case T_Group:
+ _outGroup(str, obj);
+ break;
+ case T_Unique:
+ _outUnique(str, obj);
+ break;
+ case T_Hash:
+ _outHash(str, obj);
+ break;
+ case T_Tee:
+ _outTee(str, obj);
+ break;
+ case T_Resdom:
+ _outResdom(str, obj);
+ break;
+ case T_Fjoin:
+ _outFjoin(str, obj);
+ break;
+ case T_Expr:
+ _outExpr(str, obj);
+ break;
+ case T_Var:
+ _outVar(str, obj);
+ break;
+ case T_Const:
+ _outConst(str, obj);
+ break;
+ case T_Aggreg:
+ _outAggreg(str, obj);
+ break;
+ case T_Array:
+ _outArray(str, obj);
+ break;
+ case T_ArrayRef:
+ _outArrayRef(str, obj);
+ break;
+ case T_Func:
+ _outFunc(str, obj);
+ break;
+ case T_Oper:
+ _outOper(str, obj);
+ break;
+ case T_Param:
+ _outParam(str, obj);
+ break;
+ case T_EState:
+ _outEState(str, obj);
+ break;
+ case T_Rel:
+ _outRel(str, obj);
+ break;
+ case T_TargetEntry:
+ _outTargetEntry(str, obj);
+ break;
+ case T_RangeTblEntry:
+ _outRangeTblEntry(str, obj);
+ break;
+ case T_Path:
+ _outPath(str, obj);
+ break;
+ case T_IndexPath:
+ _outIndexPath(str, obj);
+ break;
+ case T_JoinPath:
+ _outJoinPath(str, obj);
+ break;
+ case T_MergePath:
+ _outMergePath(str, obj);
+ break;
+ case T_HashPath:
+ _outHashPath(str, obj);
+ break;
+ case T_OrderKey:
+ _outOrderKey(str, obj);
+ break;
+ case T_JoinKey:
+ _outJoinKey(str, obj);
+ break;
+ case T_MergeOrder:
+ _outMergeOrder(str, obj);
+ break;
+ case T_CInfo:
+ _outCInfo(str, obj);
+ break;
+ case T_JoinMethod:
+ _outJoinMethod(str, obj);
+ break;
+ case T_HInfo:
+ _outHInfo(str, obj);
+ break;
+ case T_JInfo:
+ _outJInfo(str, obj);
+ break;
+ case T_Iter:
+ _outIter(str, obj);
+ break;
+ case T_Stream:
+ _outStream(str, obj);
+ break;
+ case T_Integer:
+ case T_String:
+ case T_Float:
+ _outValue(str, obj);
+ break;
+ default:
+ elog(NOTICE, "_outNode: don't know how to print type %d",
+ nodeTag(obj));
+ break;
+ }
+ appendStringInfo(str, "}");
}
- appendStringInfo(str, "}");
- }
- return;
+ return;
}
/*
* nodeToString -
- * returns the ascii representation of the Node
+ * returns the ascii representation of the Node
*/
-char *
+char *
nodeToString(void *obj)
{
- StringInfo str;
- char *s;
-
- if (obj==NULL)
- return "";
- Assert(obj!=NULL);
- str = makeStringInfo();
- _outNode(str, obj);
- s = str->data;
- pfree(str);
-
- return s;
+ StringInfo str;
+ char *s;
+
+ if (obj == NULL)
+ return "";
+ Assert(obj != NULL);
+ str = makeStringInfo();
+ _outNode(str, obj);
+ s = str->data;
+ pfree(str);
+
+ return s;
}
diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c
index 0f92c189e51..9fb61ed3ea7 100644
--- a/src/backend/nodes/print.c
+++ b/src/backend/nodes/print.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* print.c--
- * various print routines (used mostly for debugging)
+ * various print routines (used mostly for debugging)
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.6 1997/08/19 21:31:43 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.7 1997/09/07 04:42:55 momjian Exp $
*
* HISTORY
- * AUTHOR DATE MAJOR EVENT
- * Andrew Yu Oct 26, 1994 file creation
+ * AUTHOR DATE MAJOR EVENT
+ * Andrew Yu Oct 26, 1994 file creation
*
*-------------------------------------------------------------------------
*/
@@ -33,21 +33,21 @@
#include "nodes/plannodes.h"
#include "optimizer/clauses.h"
-static char *plannode_type (Plan* p);
+static char *plannode_type(Plan * p);
/*
* print--
- * print contents of Node to stdout
+ * print contents of Node to stdout
*/
void
print(void *obj)
{
- char *s;
+ char *s;
- s = nodeToString(obj);
- printf("%s\n", s);
- fflush(stdout);
- return;
+ s = nodeToString(obj);
+ printf("%s\n", s);
+ fflush(stdout);
+ return;
}
/*
@@ -56,327 +56,365 @@ print(void *obj)
void
pprint(void *obj)
{
- char *s;
- int i;
- char line[80];
- int indentLev;
- int j;
-
- s = nodeToString(obj);
-
- indentLev = 0;
- i = 0;
- for(;;) {
- for(j=0; j<indentLev*3; j++) {
- line[j] = ' ';
- }
- for( ; j<75 && s[i]!='\0'; i++, j++) {
- line[j] = s[i];
- switch (line[j]) {
- case '}':
- if (j != indentLev*3) {
- line[j] = '\0';
- printf("%s\n",line);
- line[indentLev*3] = '\0';
- printf("%s}\n",line);
- }else {
- line[j] = '\0';
- printf("%s}\n",line);
- }
- indentLev--;
- j = indentLev*3-1; /* print the line before : and resets */
- break;
- case ')':
- line[j+1] = '\0';
- printf("%s\n", line);
- j = indentLev*3-1;
- break;
- case '{':
- indentLev++;
- /* !!! FALLS THROUGH */
- case ':':
- if (j != 0) {
- line[j] = '\0';
- printf("%s\n",line);
- /* print the line before : and resets */
- for(j=0; j<indentLev*3; j++) {
+ char *s;
+ int i;
+ char line[80];
+ int indentLev;
+ int j;
+
+ s = nodeToString(obj);
+
+ indentLev = 0;
+ i = 0;
+ for (;;)
+ {
+ for (j = 0; j < indentLev * 3; j++)
+ {
line[j] = ' ';
- }
}
- line[j] = s[i];
- break;
- }
+ for (; j < 75 && s[i] != '\0'; i++, j++)
+ {
+ line[j] = s[i];
+ switch (line[j])
+ {
+ case '}':
+ if (j != indentLev * 3)
+ {
+ line[j] = '\0';
+ printf("%s\n", line);
+ line[indentLev * 3] = '\0';
+ printf("%s}\n", line);
+ }
+ else
+ {
+ line[j] = '\0';
+ printf("%s}\n", line);
+ }
+ indentLev--;
+ j = indentLev * 3 - 1; /* print the line before : and
+ * resets */
+ break;
+ case ')':
+ line[j + 1] = '\0';
+ printf("%s\n", line);
+ j = indentLev * 3 - 1;
+ break;
+ case '{':
+ indentLev++;
+ /* !!! FALLS THROUGH */
+ case ':':
+ if (j != 0)
+ {
+ line[j] = '\0';
+ printf("%s\n", line);
+ /* print the line before : and resets */
+ for (j = 0; j < indentLev * 3; j++)
+ {
+ line[j] = ' ';
+ }
+ }
+ line[j] = s[i];
+ break;
+ }
+ }
+ line[j] = '\0';
+ if (s[i] == '\0')
+ break;
+ printf("%s\n", line);
}
- line[j] = '\0';
- if (s[i]=='\0')
- break;
- printf("%s\n", line);
- }
- if (j!=0) {
- printf("%s\n", line);
- }
- fflush(stdout);
- return;
+ if (j != 0)
+ {
+ printf("%s\n", line);
+ }
+ fflush(stdout);
+ return;
}
/*
* print_rt--
- * print contents of range table
+ * print contents of range table
*/
void
-print_rt(List *rtable)
+print_rt(List * rtable)
{
- List *l;
- int i=1;
-
- printf("resno\trelname(refname)\trelid\tinFromCl\n");
- printf("-----\t----------------\t-----\t--------\n");
- foreach(l, rtable) {
- RangeTblEntry *rte = lfirst(l);
- printf("%d\t%s(%s)\t%d\t%d\t%s\n",
- i,rte->relname,rte->refname,rte->relid,
- rte->inFromCl,
- (rte->inh?"inh":""));
- i++;
- }
+ List *l;
+ int i = 1;
+
+ printf("resno\trelname(refname)\trelid\tinFromCl\n");
+ printf("-----\t----------------\t-----\t--------\n");
+ foreach(l, rtable)
+ {
+ RangeTblEntry *rte = lfirst(l);
+
+ printf("%d\t%s(%s)\t%d\t%d\t%s\n",
+ i, rte->relname, rte->refname, rte->relid,
+ rte->inFromCl,
+ (rte->inh ? "inh" : ""));
+ i++;
+ }
}
/*
* print_expr--
- * print an expression
+ * print an expression
*/
void
-print_expr(Node *expr, List *rtable)
+print_expr(Node * expr, List * rtable)
{
- if (expr==NULL) {
- printf("nil");
- return;
- }
-
- if (IsA(expr,Var)) {
- Var *var = (Var*)expr;
- RangeTblEntry *rt;
- char *relname, *attname;
-
- switch (var->varno) {
- case INNER:
- relname = "INNER";
- attname = "?";
- break;
- case OUTER:
- relname = "OUTER";
- attname = "?";
- break;
- default:
- {
- Relation r;
- rt = rt_fetch(var->varno, rtable);
- relname = rt->relname;
- r = heap_openr(relname);
- if (rt->refname)
- relname = rt->refname; /* table renamed */
- attname = getAttrName(r, var->varattno);
- heap_close(r);
- }
- break;
+ if (expr == NULL)
+ {
+ printf("nil");
+ return;
}
- printf("%s.%s",relname,attname);
- } else if (IsA(expr,Expr)) {
- Expr *e = (Expr*)expr;
- if (is_opclause(expr)) {
- char *opname;
-
- print_expr((Node*)get_leftop(e), rtable);
- opname = get_opname(((Oper*)e->oper)->opno);
- printf(" %s ", opname);
- print_expr((Node*)get_rightop(e), rtable);
- } else {
- printf("an expr");
+
+ if (IsA(expr, Var))
+ {
+ Var *var = (Var *) expr;
+ RangeTblEntry *rt;
+ char *relname,
+ *attname;
+
+ switch (var->varno)
+ {
+ case INNER:
+ relname = "INNER";
+ attname = "?";
+ break;
+ case OUTER:
+ relname = "OUTER";
+ attname = "?";
+ break;
+ default:
+ {
+ Relation r;
+
+ rt = rt_fetch(var->varno, rtable);
+ relname = rt->relname;
+ r = heap_openr(relname);
+ if (rt->refname)
+ relname = rt->refname; /* table renamed */
+ attname = getAttrName(r, var->varattno);
+ heap_close(r);
+ }
+ break;
+ }
+ printf("%s.%s", relname, attname);
+ }
+ else if (IsA(expr, Expr))
+ {
+ Expr *e = (Expr *) expr;
+
+ if (is_opclause(expr))
+ {
+ char *opname;
+
+ print_expr((Node *) get_leftop(e), rtable);
+ opname = get_opname(((Oper *) e->oper)->opno);
+ printf(" %s ", opname);
+ print_expr((Node *) get_rightop(e), rtable);
+ }
+ else
+ {
+ printf("an expr");
+ }
+ }
+ else
+ {
+ printf("not an expr");
}
- } else {
- printf("not an expr");
- }
}
/*
* print_keys -
- * temporary here. where is keys list of list??
+ * temporary here. where is keys list of list??
*/
void
-print_keys(List *keys, List *rtable)
+print_keys(List * keys, List * rtable)
{
- List *k;
-
- printf("(");
- foreach(k, keys) {
- Node *var = lfirst((List*)lfirst(k));
- print_expr(var, rtable);
- if (lnext(k)) printf(", ");
- }
- printf(")\n");
+ List *k;
+
+ printf("(");
+ foreach(k, keys)
+ {
+ Node *var = lfirst((List *) lfirst(k));
+
+ print_expr(var, rtable);
+ if (lnext(k))
+ printf(", ");
+ }
+ printf(")\n");
}
/*
* print_tl --
- * print targetlist in a more legible way.
+ * print targetlist in a more legible way.
*/
-void
-print_tl(List *tlist, List *rtable)
+void
+print_tl(List * tlist, List * rtable)
{
- List *tl;
+ List *tl;
- printf("(\n");
- foreach(tl, tlist) {
- TargetEntry *tle = lfirst(tl);
+ printf("(\n");
+ foreach(tl, tlist)
+ {
+ TargetEntry *tle = lfirst(tl);
- printf("\t%d %s\t", tle->resdom->resno, tle->resdom->resname);
- if (tle->resdom->reskey!=0) {
- printf("(%d):\t", tle->resdom->reskey);
- } else {
- printf(" :\t");
+ printf("\t%d %s\t", tle->resdom->resno, tle->resdom->resname);
+ if (tle->resdom->reskey != 0)
+ {
+ printf("(%d):\t", tle->resdom->reskey);
+ }
+ else
+ {
+ printf(" :\t");
+ }
+ print_expr(tle->expr, rtable);
+ printf("\n");
}
- print_expr(tle->expr, rtable);
- printf("\n");
- }
- printf(")\n");
+ printf(")\n");
}
/*
* print_slot--
- * print out the tuple with the given TupleTableSlot
+ * print out the tuple with the given TupleTableSlot
*/
void
-print_slot(TupleTableSlot *slot)
+print_slot(TupleTableSlot * slot)
{
- if (!slot->val) {
- printf("tuple is null.\n");
- return;
- }
- if (!slot->ttc_tupleDescriptor) {
- printf("no tuple descriptor.\n");
- return;
- }
-
- debugtup(slot->val, slot->ttc_tupleDescriptor);
+ if (!slot->val)
+ {
+ printf("tuple is null.\n");
+ return;
+ }
+ if (!slot->ttc_tupleDescriptor)
+ {
+ printf("no tuple descriptor.\n");
+ return;
+ }
+
+ debugtup(slot->val, slot->ttc_tupleDescriptor);
}
-static char *
-plannode_type (Plan* p)
+static char *
+plannode_type(Plan * p)
{
- switch(nodeTag(p)) {
- case T_Plan:
- return "PLAN";
- break;
- case T_Existential:
- return "EXISTENTIAL";
- break;
- case T_Result:
- return "RESULT";
- break;
- case T_Append:
- return "APPEND";
- break;
- case T_Scan:
- return "SCAN";
- break;
- case T_SeqScan:
- return "SEQSCAN";
- break;
- case T_IndexScan:
- return "INDEXSCAN";
- break;
- case T_Join:
- return "JOIN";
- break;
- case T_NestLoop:
- return "NESTLOOP";
- break;
- case T_MergeJoin:
- return "MERGEJOIN";
- break;
- case T_HashJoin:
- return "HASHJOIN";
- break;
- case T_Temp:
- return "TEMP";
- break;
- case T_Material:
- return "MATERIAL";
- break;
- case T_Sort:
- return "SORT";
- break;
- case T_Agg:
- return "AGG";
- break;
- case T_Unique:
- return "UNIQUE";
- break;
- case T_Hash:
- return "HASH";
- break;
- case T_Tee:
- return "TEE";
- break;
- case T_Choose:
- return "CHOOSE";
- break;
- case T_Group:
- return "GROUP";
- break;
- default:
- return "UNKNOWN";
- break;
- }
+ switch (nodeTag(p))
+ {
+ case T_Plan:
+ return "PLAN";
+ break;
+ case T_Existential:
+ return "EXISTENTIAL";
+ break;
+ case T_Result:
+ return "RESULT";
+ break;
+ case T_Append:
+ return "APPEND";
+ break;
+ case T_Scan:
+ return "SCAN";
+ break;
+ case T_SeqScan:
+ return "SEQSCAN";
+ break;
+ case T_IndexScan:
+ return "INDEXSCAN";
+ break;
+ case T_Join:
+ return "JOIN";
+ break;
+ case T_NestLoop:
+ return "NESTLOOP";
+ break;
+ case T_MergeJoin:
+ return "MERGEJOIN";
+ break;
+ case T_HashJoin:
+ return "HASHJOIN";
+ break;
+ case T_Temp:
+ return "TEMP";
+ break;
+ case T_Material:
+ return "MATERIAL";
+ break;
+ case T_Sort:
+ return "SORT";
+ break;
+ case T_Agg:
+ return "AGG";
+ break;
+ case T_Unique:
+ return "UNIQUE";
+ break;
+ case T_Hash:
+ return "HASH";
+ break;
+ case T_Tee:
+ return "TEE";
+ break;
+ case T_Choose:
+ return "CHOOSE";
+ break;
+ case T_Group:
+ return "GROUP";
+ break;
+ default:
+ return "UNKNOWN";
+ break;
+ }
}
+
/*
prints the ascii description of the plan nodes
does this recursively by doing a depth-first traversal of the
plan tree. for SeqScan and IndexScan, the name of the table is also
- printed out
+ printed out
*/
void
-print_plan_recursive (Plan* p, Query *parsetree, int indentLevel, char* label)
+print_plan_recursive(Plan * p, Query * parsetree, int indentLevel, char *label)
{
- int i;
- char extraInfo[100];
+ int i;
+ char extraInfo[100];
- if (!p)
- return;
- for (i=0;i<indentLevel;i++)
- printf(" ");
- printf("%s%s :c=%.4f :s=%d :w=%d ",label, plannode_type(p),
- p->cost, p->plan_size, p->plan_width);
- if (IsA(p,Scan) || IsA(p,SeqScan)) {
- RangeTblEntry *rte;
- rte = rt_fetch(((Scan*)p)->scanrelid, parsetree->rtable);
- strNcpy(extraInfo, rte->relname, NAMEDATALEN-1);
- } else
- if (IsA(p,IndexScan)) {
- strNcpy(extraInfo,
- ((RangeTblEntry*)(nth(((IndexScan*)p)->scan.scanrelid - 1,
- parsetree->rtable)))->relname,
- NAMEDATALEN-1);
- } else
- extraInfo[0] = '\0';
- if (extraInfo[0] != '\0')
- printf(" ( %s )\n", extraInfo);
- else
- printf("\n");
- print_plan_recursive(p->lefttree, parsetree, indentLevel + 3, "l: ");
- print_plan_recursive(p->righttree, parsetree, indentLevel + 3, "r: ");
+ if (!p)
+ return;
+ for (i = 0; i < indentLevel; i++)
+ printf(" ");
+ printf("%s%s :c=%.4f :s=%d :w=%d ", label, plannode_type(p),
+ p->cost, p->plan_size, p->plan_width);
+ if (IsA(p, Scan) || IsA(p, SeqScan))
+ {
+ RangeTblEntry *rte;
+
+ rte = rt_fetch(((Scan *) p)->scanrelid, parsetree->rtable);
+ strNcpy(extraInfo, rte->relname, NAMEDATALEN - 1);
+ }
+ else if (IsA(p, IndexScan))
+ {
+ strNcpy(extraInfo,
+ ((RangeTblEntry *) (nth(((IndexScan *) p)->scan.scanrelid - 1,
+ parsetree->rtable)))->relname,
+ NAMEDATALEN - 1);
+ }
+ else
+ extraInfo[0] = '\0';
+ if (extraInfo[0] != '\0')
+ printf(" ( %s )\n", extraInfo);
+ else
+ printf("\n");
+ print_plan_recursive(p->lefttree, parsetree, indentLevel + 3, "l: ");
+ print_plan_recursive(p->righttree, parsetree, indentLevel + 3, "r: ");
}
-/* print_plan
+/* print_plan
prints just the plan node types */
void
-print_plan (Plan* p, Query* parsetree)
+print_plan(Plan * p, Query * parsetree)
{
- print_plan_recursive(p, parsetree, 0, "");
+ print_plan_recursive(p, parsetree, 0, "");
}
-
-
-
diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c
index 7e89f9d74d3..f0baa4f14d7 100644
--- a/src/backend/nodes/read.c
+++ b/src/backend/nodes/read.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* read.c--
- * routines to convert a string (legal ascii representation of node) back
- * to nodes
+ * routines to convert a string (legal ascii representation of node) back
+ * to nodes
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.3 1997/08/12 22:53:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.4 1997/09/07 04:42:56 momjian Exp $
*
* HISTORY
- * AUTHOR DATE MAJOR EVENT
- * Andrew Yu Nov 2, 1994 file creation
+ * AUTHOR DATE MAJOR EVENT
+ * Andrew Yu Nov 2, 1994 file creation
*
*-------------------------------------------------------------------------
*/
@@ -26,17 +26,17 @@
/*
* stringToNode -
- * returns a Node with a given legal ascii representation
+ * returns a Node with a given legal ascii representation
*/
-void *
+void *
stringToNode(char *str)
{
- void *retval;
+ void *retval;
- lsptok(str, NULL); /* set the string used in lsptok */
- retval = nodeRead(true); /* start reading */
+ lsptok(str, NULL); /* set the string used in lsptok */
+ retval = nodeRead(true); /* start reading */
- return retval;
+ return retval;
}
/*****************************************************************************
@@ -46,115 +46,126 @@ stringToNode(char *str)
*****************************************************************************/
#define RIGHT_PAREN (1000000 + 1)
-#define LEFT_PAREN (1000000 + 2)
-#define PLAN_SYM (1000000 + 3)
-#define AT_SYMBOL (1000000 + 4)
-#define ATOM_TOKEN (1000000 + 5)
+#define LEFT_PAREN (1000000 + 2)
+#define PLAN_SYM (1000000 + 3)
+#define AT_SYMBOL (1000000 + 4)
+#define ATOM_TOKEN (1000000 + 5)
/*
* nodeTokenType -
- * returns the type of the node token contained in token.
- * It returns one of the following valid NodeTags:
- * T_Integer, T_Float, T_String
- * and some of its own:
- * RIGHT_PAREN, LEFT_PAREN, PLAN_SYM, AT_SYMBOL, ATOM_TOKEN
+ * returns the type of the node token contained in token.
+ * It returns one of the following valid NodeTags:
+ * T_Integer, T_Float, T_String
+ * and some of its own:
+ * RIGHT_PAREN, LEFT_PAREN, PLAN_SYM, AT_SYMBOL, ATOM_TOKEN
*
- * Assumption: the ascii representation is legal
+ * Assumption: the ascii representation is legal
*/
-static NodeTag
+static NodeTag
nodeTokenType(char *token, int length)
{
- NodeTag retval = 0;
-
- /*
- * Check if the token is a number (decimal or integer,
- * positive or negative
- */
- if (isdigit(*token) ||
- (length>=2 && *token=='-' && isdigit(*(token+1)) ))
+ NodeTag retval = 0;
+
+ /*
+ * Check if the token is a number (decimal or integer, positive or
+ * negative
+ */
+ if (isdigit(*token) ||
+ (length >= 2 && *token == '-' && isdigit(*(token + 1))))
{
- /*
- * skip the optional '-' (i.e. negative number)
- */
- if (*token == '-') {
- token++;
- }
-
- /*
- * See if there is a decimal point
- */
-
- for (; length && *token != '.'; token++, length--);
-
- /*
- * if there isn't, token's an int, otherwise it's a float.
- */
-
- retval = (*token != '.') ? T_Integer : T_Float;
+
+ /*
+ * skip the optional '-' (i.e. negative number)
+ */
+ if (*token == '-')
+ {
+ token++;
+ }
+
+ /*
+ * See if there is a decimal point
+ */
+
+ for (; length && *token != '.'; token++, length--);
+
+ /*
+ * if there isn't, token's an int, otherwise it's a float.
+ */
+
+ retval = (*token != '.') ? T_Integer : T_Float;
}
- else if (isalpha(*token))
- retval = ATOM_TOKEN;
- else if (*token == '(')
- retval = LEFT_PAREN;
- else if (*token == ')')
- retval = RIGHT_PAREN;
- else if (*token == '@')
- retval = AT_SYMBOL;
- else if (*token == '\"')
- retval = T_String;
- else if (*token == '{')
- retval = PLAN_SYM;
- return(retval);
+ else if (isalpha(*token))
+ retval = ATOM_TOKEN;
+ else if (*token == '(')
+ retval = LEFT_PAREN;
+ else if (*token == ')')
+ retval = RIGHT_PAREN;
+ else if (*token == '@')
+ retval = AT_SYMBOL;
+ else if (*token == '\"')
+ retval = T_String;
+ else if (*token == '{')
+ retval = PLAN_SYM;
+ return (retval);
}
/*
* Works kinda like strtok, except it doesn't put nulls into string.
- *
+ *
* Returns the length in length instead. The string can be set without
* returning a token by calling lsptok with length == NULL.
*
*/
-char *
+char *
lsptok(char *string, int *length)
{
- static char *local_str;
- char *ret_string;
-
- if (string != NULL) {
- local_str = string;
- if (length == NULL) {
- return(NULL);
+ static char *local_str;
+ char *ret_string;
+
+ if (string != NULL)
+ {
+ local_str = string;
+ if (length == NULL)
+ {
+ return (NULL);
+ }
+ }
+
+ for (; *local_str == ' '
+ || *local_str == '\n'
+ || *local_str == '\t'; local_str++);
+
+ /*
+ * Now pointing at next token.
+ */
+ ret_string = local_str;
+ if (*local_str == '\0')
+ return (NULL);
+ *length = 1;
+
+ if (*local_str == '\"')
+ {
+ for (local_str++; *local_str != '\"'; (*length)++, local_str++);
+ (*length)++;
+ local_str++;
+ }
+ else if (*local_str == ')' || *local_str == '(' ||
+ *local_str == '}' || *local_str == '{')
+ {
+ local_str++;
+ }
+ else
+ {
+ for (; *local_str != ' '
+ && *local_str != '\n'
+ && *local_str != '\t'
+ && *local_str != '{'
+ && *local_str != '}'
+ && *local_str != '('
+ && *local_str != ')'; local_str++, (*length)++);
+ (*length)--;
}
- }
-
- for (; *local_str == ' '
- || *local_str == '\n'
- || *local_str == '\t'; local_str++);
-
- /*
- * Now pointing at next token.
- */
- ret_string = local_str;
- if (*local_str == '\0') return(NULL);
- *length = 1;
-
- if (*local_str == '\"') {
- for (local_str++; *local_str != '\"'; (*length)++, local_str++);
- (*length)++; local_str++;
- }else if (*local_str == ')' || *local_str == '(' ||
- *local_str == '}' || *local_str == '{') {
- local_str++;
- }else {
- for (; *local_str != ' '
- && *local_str != '\n'
- && *local_str != '\t'
- && *local_str != '{'
- && *local_str != '}'
- && *local_str != '('
- && *local_str != ')'; local_str++, (*length)++);
- (*length)--;
- }
- return(ret_string);
+ return (ret_string);
}
/*
@@ -163,108 +174,128 @@ lsptok(char *string, int *length)
* Secrets: He assumes that lsptok already has the string (see below).
* Any callers should set read_car_only to true.
*/
-void *
+void *
nodeRead(bool read_car_only)
{
- char *token;
- NodeTag type;
- Node *this_value = NULL, *return_value = NULL;
- int tok_len;
- char tmp;
- bool make_dotted_pair_cell = false;
-
- token = lsptok(NULL, &tok_len);
-
- if (token == NULL) return(NULL);
-
- type = nodeTokenType(token, tok_len);
-
- switch(type) {
- case PLAN_SYM:
- this_value = parsePlanString();
+ char *token;
+ NodeTag type;
+ Node *this_value = NULL,
+ *return_value = NULL;
+ int tok_len;
+ char tmp;
+ bool make_dotted_pair_cell = false;
+
token = lsptok(NULL, &tok_len);
- if (token[0] != '}') return(NULL);
- if (!read_car_only)
- make_dotted_pair_cell = true;
- else
- make_dotted_pair_cell = false;
- break;
- case LEFT_PAREN:
- if (!read_car_only) {
- List *l = makeNode(List);
+ if (token == NULL)
+ return (NULL);
- lfirst(l) = nodeRead(false);
- lnext(l) = nodeRead(false);
- this_value = (Node*)l;
- }else {
- this_value = nodeRead(false);
- }
- break;
- case RIGHT_PAREN:
- this_value = NULL;
- break;
- case AT_SYMBOL:
- break;
- case ATOM_TOKEN:
- if (!strncmp(token, "nil", 3)) {
- this_value = NULL;
- /*
- * It might be "nil" but it is an atom!
- */
- if (read_car_only) {
- make_dotted_pair_cell = false;
- } else {
+ type = nodeTokenType(token, tok_len);
+
+ switch (type)
+ {
+ case PLAN_SYM:
+ this_value = parsePlanString();
+ token = lsptok(NULL, &tok_len);
+ if (token[0] != '}')
+ return (NULL);
+
+ if (!read_car_only)
+ make_dotted_pair_cell = true;
+ else
+ make_dotted_pair_cell = false;
+ break;
+ case LEFT_PAREN:
+ if (!read_car_only)
+ {
+ List *l = makeNode(List);
+
+ lfirst(l) = nodeRead(false);
+ lnext(l) = nodeRead(false);
+ this_value = (Node *) l;
+ }
+ else
+ {
+ this_value = nodeRead(false);
+ }
+ break;
+ case RIGHT_PAREN:
+ this_value = NULL;
+ break;
+ case AT_SYMBOL:
+ break;
+ case ATOM_TOKEN:
+ if (!strncmp(token, "nil", 3))
+ {
+ this_value = NULL;
+
+ /*
+ * It might be "nil" but it is an atom!
+ */
+ if (read_car_only)
+ {
+ make_dotted_pair_cell = false;
+ }
+ else
+ {
+ make_dotted_pair_cell = true;
+ }
+ }
+ else
+ {
+ tmp = token[tok_len];
+ token[tok_len] = '\0';
+ this_value = (Node *) pstrdup(token); /* !attention! not a
+ * Node. use with
+ * caution */
+ token[tok_len] = tmp;
+ make_dotted_pair_cell = true;
+ }
+ break;
+ case T_Float:
+ tmp = token[tok_len];
+ token[tok_len] = '\0';
+ this_value = (Node *) makeFloat(atof(token));
+ token[tok_len] = tmp;
+ make_dotted_pair_cell = true;
+ break;
+ case T_Integer:
+ tmp = token[tok_len];
+ token[tok_len] = '\0';
+ this_value = (Node *) makeInteger(atoi(token));
+ token[tok_len] = tmp;
make_dotted_pair_cell = true;
- }
- }else {
- tmp = token[tok_len];
- token[tok_len] = '\0';
- this_value = (Node*)pstrdup(token); /* !attention! not a Node.
- use with caution */
- token[tok_len] = tmp;
- make_dotted_pair_cell = true;
+ break;
+ case T_String:
+ tmp = token[tok_len - 1];
+ token[tok_len - 1] = '\0';
+ token++;
+ this_value = (Node *) makeString(token); /* !! not strdup'd */
+ token[tok_len - 2] = tmp;
+ make_dotted_pair_cell = true;
+ break;
+ default:
+ elog(WARN, "nodeRead: Bad type %d", type);
+ break;
}
- break;
- case T_Float:
- tmp = token[tok_len];
- token[tok_len] = '\0';
- this_value = (Node*)makeFloat(atof(token));
- token[tok_len] = tmp;
- make_dotted_pair_cell = true;
- break;
- case T_Integer:
- tmp = token[tok_len];
- token[tok_len] = '\0';
- this_value = (Node*)makeInteger(atoi(token));
- token[tok_len] = tmp;
- make_dotted_pair_cell = true;
- break;
- case T_String:
- tmp = token[tok_len - 1];
- token[tok_len - 1] = '\0';
- token++;
- this_value = (Node*)makeString(token); /* !! not strdup'd */
- token[tok_len - 2] = tmp;
- make_dotted_pair_cell = true;
- break;
- default:
- elog(WARN, "nodeRead: Bad type %d", type);
- break;
- }
- if (make_dotted_pair_cell) {
- List *l = makeNode(List);
+ if (make_dotted_pair_cell)
+ {
+ List *l = makeNode(List);
- lfirst(l) = this_value;
- if (!read_car_only) {
- lnext(l) = nodeRead(false);
- }else {
- lnext(l) = NULL;
+ lfirst(l) = this_value;
+ if (!read_car_only)
+ {
+ lnext(l) = nodeRead(false);
+ }
+ else
+ {
+ lnext(l) = NULL;
+ }
+ return_value = (Node *) l;
}
- return_value = (Node*)l;
- }else {
- return_value = this_value;
- }
- return(return_value);
+ else
+ {
+ return_value = this_value;
+ }
+ return (return_value);
}
-
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 736873bcba2..f42d5d536ee 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* readfuncs.c--
- * Reader functions for Postgres tree nodes.
+ * Reader functions for Postgres tree nodes.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.6 1997/08/12 20:15:28 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.7 1997/09/07 04:42:57 momjian Exp $
*
* NOTES
- * Most of the read functions for plan nodes are tested. (In fact, they
- * pass the regression test as of 11/8/94.) The rest (for path selection)
- * are probably never used. No effort has been made to get them to work.
- * The simplest way to test these functions is by doing the following in
- * ProcessQuery (before executing the plan):
- * plan = stringToNode(nodeToString(plan));
- * Then, run the regression test. Let's just say you'll notice if either
- * of the above function are not properly done.
- * - ay 11/94
- *
+ * Most of the read functions for plan nodes are tested. (In fact, they
+ * pass the regression test as of 11/8/94.) The rest (for path selection)
+ * are probably never used. No effort has been made to get them to work.
+ * The simplest way to test these functions is by doing the following in
+ * ProcessQuery (before executing the plan):
+ * plan = stringToNode(nodeToString(plan));
+ * Then, run the regression test. Let's just say you'll notice if either
+ * of the above function are not properly done.
+ * - ay 11/94
+ *
*-------------------------------------------------------------------------
*/
#include <stdio.h>
@@ -47,697 +47,720 @@
#include "nodes/readfuncs.h"
/* ----------------
- * node creator declarations
+ * node creator declarations
* ----------------
*/
-static Datum readDatum(Oid type);
+static Datum readDatum(Oid type);
-static List *toIntList(List *list)
+static List *
+toIntList(List * list)
{
- List *l;
- foreach(l, list) {
- /* ugly manipulation, should probably free the Value node too */
- lfirst(l) = (void*)intVal(lfirst(l));
- }
- return list;
+ List *l;
+
+ foreach(l, list)
+ {
+ /* ugly manipulation, should probably free the Value node too */
+ lfirst(l) = (void *) intVal(lfirst(l));
+ }
+ return list;
}
/* ----------------
- * _readQuery
+ * _readQuery
* ----------------
*/
-static Query *
+static Query *
_readQuery()
{
- Query *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Query);
-
- token = lsptok(NULL, &length); /* skip the :command */
- token = lsptok(NULL, &length); /* get the commandType */
- local_node->commandType = atoi(token);
-
- token = lsptok(NULL, &length); /* skip the :utility */
- token = lsptok(NULL, &length); /* get the notify name if any*/
- if (token[0] == '"' && token[1] == '"')
- local_node->utilityStmt = NULL;
- else {
- NotifyStmt *n = makeNode(NotifyStmt);
- n->relname = palloc(length + 1);
- strNcpy(n->relname,token,length);
- local_node->utilityStmt = (Node*)n;
- }
-
- token = lsptok(NULL, &length); /* skip the :resrel */
- token = lsptok(NULL, &length); /* get the resultRelation */
- local_node->resultRelation = atoi(token);
-
- token = lsptok(NULL, &length); /* skip :rtable */
- local_node->rtable = nodeRead(true);
-
- token = lsptok(NULL, &length); /* skip the :unique */
- token = lsptok(NULL, &length); /* get the uniqueFlag */
-/* local_node->uniqueFlag = (bool)atoi(token); */
- if (token[0]=='"' && token[1] == '"') /* non-unique */
- local_node->uniqueFlag = NULL;
- else {
- local_node->uniqueFlag = palloc(length + 1);
- strNcpy(local_node->uniqueFlag,token,length);
- }
-
- token = lsptok(NULL, &length); /* skip :targetlist */
- local_node->targetList = nodeRead(true);
-
- token = lsptok(NULL, &length); /* skip :qual */
- local_node->qual = nodeRead(true);
-
- return (local_node);
+ Query *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Query);
+
+ token = lsptok(NULL, &length); /* skip the :command */
+ token = lsptok(NULL, &length); /* get the commandType */
+ local_node->commandType = atoi(token);
+
+ token = lsptok(NULL, &length); /* skip the :utility */
+ token = lsptok(NULL, &length); /* get the notify name if any */
+ if (token[0] == '"' && token[1] == '"')
+ local_node->utilityStmt = NULL;
+ else
+ {
+ NotifyStmt *n = makeNode(NotifyStmt);
+
+ n->relname = palloc(length + 1);
+ strNcpy(n->relname, token, length);
+ local_node->utilityStmt = (Node *) n;
+ }
+
+ token = lsptok(NULL, &length); /* skip the :resrel */
+ token = lsptok(NULL, &length); /* get the resultRelation */
+ local_node->resultRelation = atoi(token);
+
+ token = lsptok(NULL, &length); /* skip :rtable */
+ local_node->rtable = nodeRead(true);
+
+ token = lsptok(NULL, &length); /* skip the :unique */
+ token = lsptok(NULL, &length); /* get the uniqueFlag */
+/* local_node->uniqueFlag = (bool)atoi(token); */
+ if (token[0] == '"' && token[1] == '"') /* non-unique */
+ local_node->uniqueFlag = NULL;
+ else
+ {
+ local_node->uniqueFlag = palloc(length + 1);
+ strNcpy(local_node->uniqueFlag, token, length);
+ }
+
+ token = lsptok(NULL, &length); /* skip :targetlist */
+ local_node->targetList = nodeRead(true);
+
+ token = lsptok(NULL, &length); /* skip :qual */
+ local_node->qual = nodeRead(true);
+
+ return (local_node);
}
/* ----------------
- * _getPlan
+ * _getPlan
* ----------------
*/
static void
-_getPlan(Plan *node)
+_getPlan(Plan * node)
{
- char *token;
- int length;
-
- token = lsptok(NULL, &length); /* first token is :cost */
- token = lsptok(NULL, &length); /* next is the actual cost */
- node->cost = (Cost) atof(token);
-
- token = lsptok(NULL, &length); /* skip the :size */
- token = lsptok(NULL, &length); /* get the plan_size */
- node->plan_size = atoi(token);
-
- token = lsptok(NULL, &length); /* skip the :width */
- token = lsptok(NULL, &length); /* get the plan_width */
- node->plan_width = atoi(token);
-
- token = lsptok(NULL, &length); /* eat the :state stuff */
- token = lsptok(NULL, &length); /* now get the state */
-
- if (!strncmp(token, "nil", 3)) {
- node->state = (EState*) NULL;
- }else { /* Disgusting hack until I figure out what to do here */
- node->state = (EState*) ! NULL;
- }
-
- token = lsptok(NULL, &length); /* eat :qptargetlist */
- node->targetlist = nodeRead(true);
-
- token = lsptok(NULL, &length); /* eat :qpqual */
- node->qual = nodeRead(true);
-
- token = lsptok(NULL, &length); /* eat :lefttree */
- node->lefttree = (Plan*) nodeRead(true);
-
- token = lsptok(NULL, &length); /* eat :righttree */
- node->righttree = (Plan*) nodeRead(true);
-
- return;
+ char *token;
+ int length;
+
+ token = lsptok(NULL, &length); /* first token is :cost */
+ token = lsptok(NULL, &length); /* next is the actual cost */
+ node->cost = (Cost) atof(token);
+
+ token = lsptok(NULL, &length); /* skip the :size */
+ token = lsptok(NULL, &length); /* get the plan_size */
+ node->plan_size = atoi(token);
+
+ token = lsptok(NULL, &length); /* skip the :width */
+ token = lsptok(NULL, &length); /* get the plan_width */
+ node->plan_width = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat the :state stuff */
+ token = lsptok(NULL, &length); /* now get the state */
+
+ if (!strncmp(token, "nil", 3))
+ {
+ node->state = (EState *) NULL;
+ }
+ else
+ { /* Disgusting hack until I figure out what
+ * to do here */
+ node->state = (EState *) ! NULL;
+ }
+
+ token = lsptok(NULL, &length); /* eat :qptargetlist */
+ node->targetlist = nodeRead(true);
+
+ token = lsptok(NULL, &length); /* eat :qpqual */
+ node->qual = nodeRead(true);
+
+ token = lsptok(NULL, &length); /* eat :lefttree */
+ node->lefttree = (Plan *) nodeRead(true);
+
+ token = lsptok(NULL, &length); /* eat :righttree */
+ node->righttree = (Plan *) nodeRead(true);
+
+ return;
}
/*
- * Stuff from plannodes.h
+ * Stuff from plannodes.h
*/
/* ----------------
- * _readPlan
+ * _readPlan
* ----------------
*/
-static Plan *
+static Plan *
_readPlan()
{
- Plan *local_node;
-
- local_node = makeNode(Plan);
-
- _getPlan(local_node);
-
- return (local_node);
+ Plan *local_node;
+
+ local_node = makeNode(Plan);
+
+ _getPlan(local_node);
+
+ return (local_node);
}
/* ----------------
- * _readResult
+ * _readResult
*
- * Does some obscene, possibly unportable, magic with
- * sizes of things.
+ * Does some obscene, possibly unportable, magic with
+ * sizes of things.
* ----------------
*/
-static Result *
+static Result *
_readResult()
{
- Result *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Result);
-
- _getPlan((Plan*)local_node);
-
- token = lsptok(NULL, &length); /* eat :resconstantqual */
- local_node->resconstantqual = nodeRead(true); /* now read it */
-
- return( local_node );
+ Result *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Result);
+
+ _getPlan((Plan *) local_node);
+
+ token = lsptok(NULL, &length); /* eat :resconstantqual */
+ local_node->resconstantqual = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readExistential
+ * _readExistential
*
- * Existential nodes are only used by the planner.
+ * Existential nodes are only used by the planner.
* ----------------
*/
static Existential *
_readExistential()
{
- Existential *local_node;
-
- local_node = makeNode(Existential);
-
- _getPlan((Plan*)local_node);
-
- return( local_node );
+ Existential *local_node;
+
+ local_node = makeNode(Existential);
+
+ _getPlan((Plan *) local_node);
+
+ return (local_node);
}
/* ----------------
- * _readAppend
+ * _readAppend
*
- * Append is a subclass of Plan.
+ * Append is a subclass of Plan.
* ----------------
*/
-static Append *
+static Append *
_readAppend()
{
- Append *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Append);
-
- _getPlan((Plan*)local_node);
-
- token = lsptok(NULL, &length); /* eat :unionplans */
- local_node->unionplans = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* eat :unionrelid */
- token = lsptok(NULL, &length); /* get unionrelid */
- local_node->unionrelid = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :unionrtentries */
- local_node->unionrtentries = nodeRead(true); /* now read it */
-
- return(local_node);
+ Append *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Append);
+
+ _getPlan((Plan *) local_node);
+
+ token = lsptok(NULL, &length); /* eat :unionplans */
+ local_node->unionplans = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* eat :unionrelid */
+ token = lsptok(NULL, &length); /* get unionrelid */
+ local_node->unionrelid = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :unionrtentries */
+ local_node->unionrtentries = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _getJoin
+ * _getJoin
*
* In case Join is not the same structure as Plan someday.
* ----------------
*/
static void
-_getJoin(Join *node)
+_getJoin(Join * node)
{
- _getPlan((Plan*)node);
+ _getPlan((Plan *) node);
}
/* ----------------
- * _readJoin
+ * _readJoin
*
- * Join is a subclass of Plan
+ * Join is a subclass of Plan
* ----------------
*/
-static Join *
+static Join *
_readJoin()
{
- Join *local_node;
-
- local_node = makeNode(Join);
-
- _getJoin(local_node);
-
- return( local_node );
+ Join *local_node;
+
+ local_node = makeNode(Join);
+
+ _getJoin(local_node);
+
+ return (local_node);
}
/* ----------------
- * _readNestLoop
- *
- * NestLoop is a subclass of Join
+ * _readNestLoop
+ *
+ * NestLoop is a subclass of Join
* ----------------
*/
static NestLoop *
_readNestLoop()
{
- NestLoop *local_node;
-
- local_node = makeNode(NestLoop);
-
- _getJoin((Join*)local_node);
-
- return( local_node );
+ NestLoop *local_node;
+
+ local_node = makeNode(NestLoop);
+
+ _getJoin((Join *) local_node);
+
+ return (local_node);
}
/* ----------------
- * _readMergeJoin
- *
- * MergeJoin is a subclass of Join
+ * _readMergeJoin
+ *
+ * MergeJoin is a subclass of Join
* ----------------
*/
static MergeJoin *
_readMergeJoin()
{
- MergeJoin *local_node;
- char *token;
- int length;
-
- local_node = makeNode(MergeJoin);
-
- _getJoin((Join*)local_node);
- token = lsptok(NULL, &length); /* eat :mergeclauses */
- local_node->mergeclauses = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* eat :mergesortop */
- token = lsptok(NULL, &length); /* get mergesortop */
- local_node->mergesortop = atol(token);
-
- return( local_node );
+ MergeJoin *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(MergeJoin);
+
+ _getJoin((Join *) local_node);
+ token = lsptok(NULL, &length); /* eat :mergeclauses */
+ local_node->mergeclauses = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* eat :mergesortop */
+ token = lsptok(NULL, &length); /* get mergesortop */
+ local_node->mergesortop = atol(token);
+
+ return (local_node);
}
/* ----------------
- * _readHashJoin
- *
- * HashJoin is a subclass of Join.
+ * _readHashJoin
+ *
+ * HashJoin is a subclass of Join.
* ----------------
*/
static HashJoin *
_readHashJoin()
{
- HashJoin *local_node;
- char *token;
- int length;
-
- local_node = makeNode(HashJoin);
-
- _getJoin((Join*)local_node);
-
- token = lsptok(NULL, &length); /* eat :hashclauses */
- local_node->hashclauses = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* eat :hashjoinop */
- token = lsptok(NULL, &length); /* get hashjoinop */
- local_node->hashjoinop = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :hashjointable */
- token = lsptok(NULL, &length); /* eat hashjointable */
- local_node->hashjointable = NULL;
-
- token = lsptok(NULL, &length); /* eat :hashjointablekey */
- token = lsptok(NULL, &length); /* eat hashjointablekey */
- local_node->hashjointablekey = 0;
-
- token = lsptok(NULL, &length); /* eat :hashjointablesize */
- token = lsptok(NULL, &length); /* eat hashjointablesize */
- local_node->hashjointablesize = 0;
-
- token = lsptok(NULL, &length); /* eat :hashdone */
- token = lsptok(NULL, &length); /* eat hashdone */
- local_node->hashdone = false;
-
- return( local_node );
+ HashJoin *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(HashJoin);
+
+ _getJoin((Join *) local_node);
+
+ token = lsptok(NULL, &length); /* eat :hashclauses */
+ local_node->hashclauses = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* eat :hashjoinop */
+ token = lsptok(NULL, &length); /* get hashjoinop */
+ local_node->hashjoinop = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :hashjointable */
+ token = lsptok(NULL, &length); /* eat hashjointable */
+ local_node->hashjointable = NULL;
+
+ token = lsptok(NULL, &length); /* eat :hashjointablekey */
+ token = lsptok(NULL, &length); /* eat hashjointablekey */
+ local_node->hashjointablekey = 0;
+
+ token = lsptok(NULL, &length); /* eat :hashjointablesize */
+ token = lsptok(NULL, &length); /* eat hashjointablesize */
+ local_node->hashjointablesize = 0;
+
+ token = lsptok(NULL, &length); /* eat :hashdone */
+ token = lsptok(NULL, &length); /* eat hashdone */
+ local_node->hashdone = false;
+
+ return (local_node);
}
/* ----------------
- * _getScan
+ * _getScan
*
- * Scan is a subclass of Node
- * (Actually, according to the plannodes.h include file, it is a
- * subclass of Plan. This is why _getPlan is used here.)
+ * Scan is a subclass of Node
+ * (Actually, according to the plannodes.h include file, it is a
+ * subclass of Plan. This is why _getPlan is used here.)
*
- * Scan gets its own get function since stuff inherits it.
+ * Scan gets its own get function since stuff inherits it.
* ----------------
*/
-static void
-_getScan(Scan *node)
+static void
+_getScan(Scan * node)
{
- char *token;
- int length;
-
- _getPlan((Plan*)node);
-
- token = lsptok(NULL, &length); /* eat :scanrelid */
- token = lsptok(NULL, &length); /* get scanrelid */
- node->scanrelid = atoi(token);
+ char *token;
+ int length;
+
+ _getPlan((Plan *) node);
+
+ token = lsptok(NULL, &length); /* eat :scanrelid */
+ token = lsptok(NULL, &length); /* get scanrelid */
+ node->scanrelid = atoi(token);
}
/* ----------------
- * _readScan
- *
+ * _readScan
+ *
* Scan is a subclass of Plan (Not Node, see above).
* ----------------
*/
-static Scan *
+static Scan *
_readScan()
{
- Scan *local_node;
-
- local_node = makeNode(Scan);
-
- _getScan(local_node);
-
- return(local_node);
+ Scan *local_node;
+
+ local_node = makeNode(Scan);
+
+ _getScan(local_node);
+
+ return (local_node);
}
/* ----------------
- * _readSeqScan
- *
- * SeqScan is a subclass of Scan
+ * _readSeqScan
+ *
+ * SeqScan is a subclass of Scan
* ----------------
*/
static SeqScan *
_readSeqScan()
{
- SeqScan *local_node;
-
- local_node = makeNode(SeqScan);
-
- _getScan((Scan*)local_node);
-
- return(local_node);
+ SeqScan *local_node;
+
+ local_node = makeNode(SeqScan);
+
+ _getScan((Scan *) local_node);
+
+ return (local_node);
}
/* ----------------
- * _readIndexScan
- *
- * IndexScan is a subclass of Scan
+ * _readIndexScan
+ *
+ * IndexScan is a subclass of Scan
* ----------------
*/
static IndexScan *
_readIndexScan()
{
- IndexScan *local_node;
- char *token;
- int length;
-
- local_node = makeNode(IndexScan);
-
- _getScan((Scan*)local_node);
-
- token = lsptok(NULL, &length); /* eat :indxid */
- local_node->indxid =
- toIntList(nodeRead(true)); /* now read it */
-
- token = lsptok(NULL, &length); /* eat :indxqual */
- local_node->indxqual = nodeRead(true); /* now read it */
-
- return(local_node);
+ IndexScan *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(IndexScan);
+
+ _getScan((Scan *) local_node);
+
+ token = lsptok(NULL, &length); /* eat :indxid */
+ local_node->indxid =
+ toIntList(nodeRead(true)); /* now read it */
+
+ token = lsptok(NULL, &length); /* eat :indxqual */
+ local_node->indxqual = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readTemp
- *
- * Temp is a subclass of Plan
+ * _readTemp
+ *
+ * Temp is a subclass of Plan
* ----------------
*/
-static Temp *
+static Temp *
_readTemp()
{
- Temp *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Temp);
-
- _getPlan((Plan*)local_node);
-
- token = lsptok(NULL, &length); /* eat :tempid */
- token = lsptok(NULL, &length); /* get tempid */
- local_node->tempid = atol(token);
-
- token = lsptok(NULL, &length); /* eat :keycount */
- token = lsptok(NULL, &length); /* get keycount */
- local_node->keycount = atoi(token);
-
- return(local_node);
+ Temp *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Temp);
+
+ _getPlan((Plan *) local_node);
+
+ token = lsptok(NULL, &length); /* eat :tempid */
+ token = lsptok(NULL, &length); /* get tempid */
+ local_node->tempid = atol(token);
+
+ token = lsptok(NULL, &length); /* eat :keycount */
+ token = lsptok(NULL, &length); /* get keycount */
+ local_node->keycount = atoi(token);
+
+ return (local_node);
}
/* ----------------
- * _readSort
- *
- * Sort is a subclass of Temp
+ * _readSort
+ *
+ * Sort is a subclass of Temp
* ----------------
*/
-static Sort *
+static Sort *
_readSort()
{
- Sort *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Sort);
-
- _getPlan((Plan*)local_node);
-
- token = lsptok(NULL, &length); /* eat :tempid */
- token = lsptok(NULL, &length); /* get tempid */
- local_node->tempid = atol(token);
-
- token = lsptok(NULL, &length); /* eat :keycount */
- token = lsptok(NULL, &length); /* get keycount */
- local_node->keycount = atoi(token);
-
- return(local_node);
+ Sort *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Sort);
+
+ _getPlan((Plan *) local_node);
+
+ token = lsptok(NULL, &length); /* eat :tempid */
+ token = lsptok(NULL, &length); /* get tempid */
+ local_node->tempid = atol(token);
+
+ token = lsptok(NULL, &length); /* eat :keycount */
+ token = lsptok(NULL, &length); /* get keycount */
+ local_node->keycount = atoi(token);
+
+ return (local_node);
}
-static Agg *
+static Agg *
_readAgg()
{
- Agg *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Agg);
- _getPlan((Plan*)local_node);
-
- token = lsptok(NULL, &length); /* eat :numagg */
- token = lsptok(NULL, &length); /* get numagg */
- local_node->numAgg = atoi(token);
-
- return(local_node);
+ Agg *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Agg);
+ _getPlan((Plan *) local_node);
+
+ token = lsptok(NULL, &length); /* eat :numagg */
+ token = lsptok(NULL, &length); /* get numagg */
+ local_node->numAgg = atoi(token);
+
+ return (local_node);
}
/* ----------------
- * _readUnique
+ * _readUnique
*
* For some reason, unique is a subclass of Temp.
*/
-static Unique *
+static Unique *
_readUnique()
{
- Unique *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Unique);
-
- _getPlan((Plan*)local_node);
-
- token = lsptok(NULL, &length); /* eat :tempid */
- token = lsptok(NULL, &length); /* get :tempid */
- local_node->tempid = atol(token);
-
- token = lsptok(NULL, &length); /* eat :keycount */
- token = lsptok(NULL, &length); /* get :keycount */
- local_node->keycount = atoi(token);
-
- return(local_node);
+ Unique *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Unique);
+
+ _getPlan((Plan *) local_node);
+
+ token = lsptok(NULL, &length); /* eat :tempid */
+ token = lsptok(NULL, &length); /* get :tempid */
+ local_node->tempid = atol(token);
+
+ token = lsptok(NULL, &length); /* eat :keycount */
+ token = lsptok(NULL, &length); /* get :keycount */
+ local_node->keycount = atoi(token);
+
+ return (local_node);
}
/* ----------------
- * _readHash
- *
- * Hash is a subclass of Temp
+ * _readHash
+ *
+ * Hash is a subclass of Temp
* ----------------
*/
-static Hash *
+static Hash *
_readHash()
{
- Hash *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Hash);
-
- _getPlan((Plan*)local_node);
-
- token = lsptok(NULL, &length); /* eat :hashkey */
- local_node->hashkey = (Var*) nodeRead(true);
-
- token = lsptok(NULL, &length); /* eat :hashtable */
- token = lsptok(NULL, &length); /* eat hashtable address*/
- local_node->hashtable = NULL;
-
- token = lsptok(NULL, &length); /* eat :hashtablekey*/
- token = lsptok(NULL, &length); /* get hashtablekey */
- local_node->hashtablekey = 0;
-
- token = lsptok(NULL, &length); /* eat :hashtablesize*/
- token = lsptok(NULL, &length); /* get hashtablesize */
- local_node->hashtablesize = 0;
-
- return(local_node);
+ Hash *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Hash);
+
+ _getPlan((Plan *) local_node);
+
+ token = lsptok(NULL, &length); /* eat :hashkey */
+ local_node->hashkey = (Var *) nodeRead(true);
+
+ token = lsptok(NULL, &length); /* eat :hashtable */
+ token = lsptok(NULL, &length); /* eat hashtable address */
+ local_node->hashtable = NULL;
+
+ token = lsptok(NULL, &length); /* eat :hashtablekey */
+ token = lsptok(NULL, &length); /* get hashtablekey */
+ local_node->hashtablekey = 0;
+
+ token = lsptok(NULL, &length); /* eat :hashtablesize */
+ token = lsptok(NULL, &length); /* get hashtablesize */
+ local_node->hashtablesize = 0;
+
+ return (local_node);
}
/*
- * Stuff from primnodes.h.
+ * Stuff from primnodes.h.
*/
/* ----------------
- * _readResdom
- *
- * Resdom is a subclass of Node
+ * _readResdom
+ *
+ * Resdom is a subclass of Node
* ----------------
*/
-static Resdom *
+static Resdom *
_readResdom()
{
- Resdom *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Resdom);
-
- token = lsptok(NULL, &length); /* eat :resno */
- token = lsptok(NULL, &length); /* get resno */
- local_node->resno = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :restype */
- token = lsptok(NULL, &length); /* get restype */
- local_node->restype = atol(token);
-
- token = lsptok(NULL, &length); /* eat :reslen */
- token = lsptok(NULL, &length); /* get reslen */
- local_node->reslen = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :resname */
- token = lsptok(NULL, &length); /* get the name */
-
- if (!strncmp(token, "\"null\"", 5)) {
- local_node->resname = NULL;
- }else {
- /*
- * Peel off ""'s, then make a true copy.
- */
-
- token++;
- token[length - 2] = '\0';
-
- local_node->resname = palloc(length);
- strcpy(local_node->resname, token);
- token[length - 2] = '\"';
- }
-
- token = lsptok(NULL, &length); /* eat :reskey */
- token = lsptok(NULL, &length); /* get reskey */
- local_node->reskey = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :reskeyop */
- token = lsptok(NULL, &length); /* get reskeyop */
- local_node->reskeyop = (Oid) atol(token);
-
- token = lsptok(NULL, &length); /* eat :resjunk */
- token = lsptok(NULL, &length); /* get resjunk */
- local_node->resjunk = atoi(token);
-
- return(local_node);
+ Resdom *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Resdom);
+
+ token = lsptok(NULL, &length); /* eat :resno */
+ token = lsptok(NULL, &length); /* get resno */
+ local_node->resno = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :restype */
+ token = lsptok(NULL, &length); /* get restype */
+ local_node->restype = atol(token);
+
+ token = lsptok(NULL, &length); /* eat :reslen */
+ token = lsptok(NULL, &length); /* get reslen */
+ local_node->reslen = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :resname */
+ token = lsptok(NULL, &length); /* get the name */
+
+ if (!strncmp(token, "\"null\"", 5))
+ {
+ local_node->resname = NULL;
+ }
+ else
+ {
+
+ /*
+ * Peel off ""'s, then make a true copy.
+ */
+
+ token++;
+ token[length - 2] = '\0';
+
+ local_node->resname = palloc(length);
+ strcpy(local_node->resname, token);
+ token[length - 2] = '\"';
+ }
+
+ token = lsptok(NULL, &length); /* eat :reskey */
+ token = lsptok(NULL, &length); /* get reskey */
+ local_node->reskey = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :reskeyop */
+ token = lsptok(NULL, &length); /* get reskeyop */
+ local_node->reskeyop = (Oid) atol(token);
+
+ token = lsptok(NULL, &length); /* eat :resjunk */
+ token = lsptok(NULL, &length); /* get resjunk */
+ local_node->resjunk = atoi(token);
+
+ return (local_node);
}
/* ----------------
- * _readExpr
- *
- * Expr is a subclass of Node
+ * _readExpr
+ *
+ * Expr is a subclass of Node
* ----------------
*/
-static Expr *
+static Expr *
_readExpr()
{
- Expr *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Expr);
-
- token = lsptok(NULL, &length); /* eat :typeOid */
- token = lsptok(NULL, &length); /* get typeOid */
- local_node->typeOid = (Oid)atol(token);
-
- token = lsptok(NULL, &length); /* eat :opType */
- token = lsptok(NULL, &length); /* get opType */
- if (!strncmp(token, "op", 2)) {
- local_node->opType = OP_EXPR;
- } else if (!strncmp(token, "func", 4)) {
- local_node->opType = FUNC_EXPR;
- } else if (!strncmp(token, "or", 2)) {
- local_node->opType = OR_EXPR;
- } else if (!strncmp(token, "and", 3)) {
- local_node->opType = AND_EXPR;
- } else if (!strncmp(token, "not", 3)) {
- local_node->opType = NOT_EXPR;
- }
-
- token = lsptok(NULL, &length); /* eat :oper */
- local_node->oper = nodeRead(true);
-
- token = lsptok(NULL, &length); /* eat :args */
- local_node->args = nodeRead(true); /* now read it */
-
- return(local_node);
+ Expr *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Expr);
+
+ token = lsptok(NULL, &length); /* eat :typeOid */
+ token = lsptok(NULL, &length); /* get typeOid */
+ local_node->typeOid = (Oid) atol(token);
+
+ token = lsptok(NULL, &length); /* eat :opType */
+ token = lsptok(NULL, &length); /* get opType */
+ if (!strncmp(token, "op", 2))
+ {
+ local_node->opType = OP_EXPR;
+ }
+ else if (!strncmp(token, "func", 4))
+ {
+ local_node->opType = FUNC_EXPR;
+ }
+ else if (!strncmp(token, "or", 2))
+ {
+ local_node->opType = OR_EXPR;
+ }
+ else if (!strncmp(token, "and", 3))
+ {
+ local_node->opType = AND_EXPR;
+ }
+ else if (!strncmp(token, "not", 3))
+ {
+ local_node->opType = NOT_EXPR;
+ }
+
+ token = lsptok(NULL, &length); /* eat :oper */
+ local_node->oper = nodeRead(true);
+
+ token = lsptok(NULL, &length); /* eat :args */
+ local_node->args = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readVar
- *
- * Var is a subclass of Expr
+ * _readVar
+ *
+ * Var is a subclass of Expr
* ----------------
*/
-static Var *
+static Var *
_readVar()
{
- Var *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Var);
-
- token = lsptok(NULL, &length); /* eat :varno */
- token = lsptok(NULL, &length); /* get varno */
- local_node->varno = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :varattno */
- token = lsptok(NULL, &length); /* get varattno */
- local_node->varattno = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :vartype */
- token = lsptok(NULL, &length); /* get vartype */
- local_node->vartype = (Oid) atol(token);
-
- token = lsptok(NULL, &length); /* eat :varnoold */
- token = lsptok(NULL, &length); /* get varnoold */
- local_node->varnoold = (Oid) atol(token);
-
- token = lsptok(NULL, &length); /* eat :varoattno */
- token = lsptok(NULL, &length); /* eat :varoattno */
- local_node->varoattno = (int) atol(token);
-
- return(local_node);
+ Var *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Var);
+
+ token = lsptok(NULL, &length); /* eat :varno */
+ token = lsptok(NULL, &length); /* get varno */
+ local_node->varno = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :varattno */
+ token = lsptok(NULL, &length); /* get varattno */
+ local_node->varattno = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :vartype */
+ token = lsptok(NULL, &length); /* get vartype */
+ local_node->vartype = (Oid) atol(token);
+
+ token = lsptok(NULL, &length); /* eat :varnoold */
+ token = lsptok(NULL, &length); /* get varnoold */
+ local_node->varnoold = (Oid) atol(token);
+
+ token = lsptok(NULL, &length); /* eat :varoattno */
+ token = lsptok(NULL, &length); /* eat :varoattno */
+ local_node->varoattno = (int) atol(token);
+
+ return (local_node);
}
/* ----------------
@@ -746,40 +769,40 @@ _readVar()
* Array is a subclass of Expr
* ----------------
*/
-static Array *
+static Array *
_readArray()
{
- Array *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Array);
-
- token = lsptok(NULL, &length); /* eat :arrayelemtype */
- token = lsptok(NULL, &length); /* get arrayelemtype */
- local_node->arrayelemtype = (Oid) atoi(token);
-
- token = lsptok(NULL, &length); /* eat :arrayelemlength */
- token = lsptok(NULL, &length); /* get arrayelemlength */
- local_node->arrayelemlength = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :arrayelembyval */
- token = lsptok(NULL, &length); /* get arrayelembyval */
- local_node->arrayelembyval = (token[0] == 't') ? true : false;
-
- token = lsptok(NULL, &length); /* eat :arraylow */
- token = lsptok(NULL, &length); /* get arraylow */
- local_node->arraylow.indx[0] = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :arrayhigh */
- token = lsptok(NULL, &length); /* get arrayhigh */
- local_node->arrayhigh.indx[0] = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :arraylen */
- token = lsptok(NULL, &length); /* get arraylen */
- local_node->arraylen = atoi(token);
-
- return(local_node);
+ Array *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Array);
+
+ token = lsptok(NULL, &length); /* eat :arrayelemtype */
+ token = lsptok(NULL, &length); /* get arrayelemtype */
+ local_node->arrayelemtype = (Oid) atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :arrayelemlength */
+ token = lsptok(NULL, &length); /* get arrayelemlength */
+ local_node->arrayelemlength = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :arrayelembyval */
+ token = lsptok(NULL, &length); /* get arrayelembyval */
+ local_node->arrayelembyval = (token[0] == 't') ? true : false;
+
+ token = lsptok(NULL, &length); /* eat :arraylow */
+ token = lsptok(NULL, &length); /* get arraylow */
+ local_node->arraylow.indx[0] = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :arrayhigh */
+ token = lsptok(NULL, &length); /* get arrayhigh */
+ local_node->arrayhigh.indx[0] = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :arraylen */
+ token = lsptok(NULL, &length); /* get arraylen */
+ local_node->arraylen = atoi(token);
+
+ return (local_node);
}
/* ----------------
@@ -791,1031 +814,1052 @@ _readArray()
static ArrayRef *
_readArrayRef()
{
- ArrayRef *local_node;
- char *token;
- int length;
-
- local_node = makeNode(ArrayRef);
-
- token = lsptok(NULL, &length); /* eat :refelemtype */
- token = lsptok(NULL, &length); /* get refelemtype */
- local_node->refelemtype = (Oid) atoi(token);
-
- token = lsptok(NULL, &length); /* eat :refattrlength */
- token = lsptok(NULL, &length); /* get refattrlength */
- local_node->refattrlength = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :refelemlength */
- token = lsptok(NULL, &length); /* get refelemlength */
- local_node->refelemlength = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :refelembyval */
- token = lsptok(NULL, &length); /* get refelembyval */
- local_node->refelembyval = (token[0] == 't') ? true : false;
-
- token = lsptok(NULL, &length); /* eat :refupperindex */
- local_node->refupperindexpr = nodeRead(true);
-
- token = lsptok(NULL, &length); /* eat :reflowerindex */
- local_node->reflowerindexpr = nodeRead(true);
-
- token = lsptok(NULL, &length); /* eat :refexpr */
- local_node->refexpr = nodeRead(true);
-
- token = lsptok(NULL, &length); /* eat :refassgnexpr */
- local_node->refassgnexpr = nodeRead(true);
-
- return(local_node);
+ ArrayRef *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(ArrayRef);
+
+ token = lsptok(NULL, &length); /* eat :refelemtype */
+ token = lsptok(NULL, &length); /* get refelemtype */
+ local_node->refelemtype = (Oid) atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :refattrlength */
+ token = lsptok(NULL, &length); /* get refattrlength */
+ local_node->refattrlength = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :refelemlength */
+ token = lsptok(NULL, &length); /* get refelemlength */
+ local_node->refelemlength = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :refelembyval */
+ token = lsptok(NULL, &length); /* get refelembyval */
+ local_node->refelembyval = (token[0] == 't') ? true : false;
+
+ token = lsptok(NULL, &length); /* eat :refupperindex */
+ local_node->refupperindexpr = nodeRead(true);
+
+ token = lsptok(NULL, &length); /* eat :reflowerindex */
+ local_node->reflowerindexpr = nodeRead(true);
+
+ token = lsptok(NULL, &length); /* eat :refexpr */
+ local_node->refexpr = nodeRead(true);
+
+ token = lsptok(NULL, &length); /* eat :refassgnexpr */
+ local_node->refassgnexpr = nodeRead(true);
+
+ return (local_node);
}
/* ----------------
- * _readConst
- *
- * Const is a subclass of Expr
+ * _readConst
+ *
+ * Const is a subclass of Expr
* ----------------
*/
-static Const *
+static Const *
_readConst()
{
- Const *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Const);
-
- token = lsptok(NULL, &length); /* get :consttype */
- token = lsptok(NULL, &length); /* now read it */
- local_node->consttype = atol(token);
-
-
- token = lsptok(NULL, &length); /* get :constlen */
- token = lsptok(NULL, &length); /* now read it */
- local_node->constlen = atoi(token);
-
- token = lsptok(NULL, &length); /* get :constisnull */
- token = lsptok(NULL, &length); /* now read it */
-
- if (!strncmp(token, "true", 4)) {
- local_node->constisnull = true;
- }else {
- local_node->constisnull = false;
- }
-
-
- token = lsptok(NULL, &length); /* get :constvalue */
-
- if (local_node->constisnull) {
- token = lsptok(NULL, &length); /* skip "NIL" */
- }else {
- /*
- * read the value
- */
- local_node->constvalue = readDatum(local_node->consttype);
- }
-
- token = lsptok(NULL, &length); /* get :constbyval */
- token = lsptok(NULL, &length); /* now read it */
-
- if (!strncmp(token, "true", 4)) {
- local_node->constbyval = true;
- }else {
- local_node->constbyval = false;
- }
-
- return(local_node);
+ Const *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Const);
+
+ token = lsptok(NULL, &length); /* get :consttype */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->consttype = atol(token);
+
+
+ token = lsptok(NULL, &length); /* get :constlen */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->constlen = atoi(token);
+
+ token = lsptok(NULL, &length); /* get :constisnull */
+ token = lsptok(NULL, &length); /* now read it */
+
+ if (!strncmp(token, "true", 4))
+ {
+ local_node->constisnull = true;
+ }
+ else
+ {
+ local_node->constisnull = false;
+ }
+
+
+ token = lsptok(NULL, &length); /* get :constvalue */
+
+ if (local_node->constisnull)
+ {
+ token = lsptok(NULL, &length); /* skip "NIL" */
+ }
+ else
+ {
+
+ /*
+ * read the value
+ */
+ local_node->constvalue = readDatum(local_node->consttype);
+ }
+
+ token = lsptok(NULL, &length); /* get :constbyval */
+ token = lsptok(NULL, &length); /* now read it */
+
+ if (!strncmp(token, "true", 4))
+ {
+ local_node->constbyval = true;
+ }
+ else
+ {
+ local_node->constbyval = false;
+ }
+
+ return (local_node);
}
/* ----------------
- * _readFunc
- *
- * Func is a subclass of Expr
+ * _readFunc
+ *
+ * Func is a subclass of Expr
* ----------------
*/
-static Func *
+static Func *
_readFunc()
{
- Func *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Func);
-
- token = lsptok(NULL, &length); /* get :funcid */
- token = lsptok(NULL, &length); /* now read it */
- local_node->funcid = atol(token);
-
- token = lsptok(NULL, &length); /* get :functype */
- token = lsptok(NULL, &length); /* now read it */
- local_node->functype = atol(token);
-
- token = lsptok(NULL, &length); /* get :funcisindex */
- token = lsptok(NULL, &length); /* now read it */
-
- if (!strncmp(token, "true", 4)) {
- local_node->funcisindex = true;
- }else {
- local_node->funcisindex = false;
- }
-
- token = lsptok(NULL, &length); /* get :funcsize */
- token = lsptok(NULL, &length); /* now read it */
- local_node->funcsize = atol(token);
-
- token = lsptok(NULL, &length); /* get :func_fcache */
- token = lsptok(NULL, &length); /* get @ */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->func_fcache = (FunctionCache *) NULL;
-
- token = lsptok(NULL, &length); /* get :func_tlist */
- local_node->func_tlist = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :func_planlist */
- local_node->func_planlist = nodeRead(true); /* now read it */
-
- return(local_node);
+ Func *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Func);
+
+ token = lsptok(NULL, &length); /* get :funcid */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->funcid = atol(token);
+
+ token = lsptok(NULL, &length); /* get :functype */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->functype = atol(token);
+
+ token = lsptok(NULL, &length); /* get :funcisindex */
+ token = lsptok(NULL, &length); /* now read it */
+
+ if (!strncmp(token, "true", 4))
+ {
+ local_node->funcisindex = true;
+ }
+ else
+ {
+ local_node->funcisindex = false;
+ }
+
+ token = lsptok(NULL, &length); /* get :funcsize */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->funcsize = atol(token);
+
+ token = lsptok(NULL, &length); /* get :func_fcache */
+ token = lsptok(NULL, &length); /* get @ */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->func_fcache = (FunctionCache *) NULL;
+
+ token = lsptok(NULL, &length); /* get :func_tlist */
+ local_node->func_tlist = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :func_planlist */
+ local_node->func_planlist = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readOper
- *
- * Oper is a subclass of Expr
+ * _readOper
+ *
+ * Oper is a subclass of Expr
* ----------------
*/
-static Oper *
+static Oper *
_readOper()
{
- Oper *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Oper);
-
- token = lsptok(NULL, &length); /* get :opno */
- token = lsptok(NULL, &length); /* now read it */
- local_node->opno = atol(token);
-
- token = lsptok(NULL, &length); /* get :opid */
- token = lsptok(NULL, &length); /* now read it */
- local_node->opid = atol(token);
-
- token = lsptok(NULL, &length); /* get :opresulttype */
- token = lsptok(NULL, &length); /* now read it */
- local_node->opresulttype = atol(token);
-
- /*
- * NOTE: Alternatively we can call 'replace_opid'
- * which initializes both 'opid' and 'op_fcache'.
- */
- local_node->op_fcache = (FunctionCache *) NULL;
-
- return(local_node);
+ Oper *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Oper);
+
+ token = lsptok(NULL, &length); /* get :opno */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->opno = atol(token);
+
+ token = lsptok(NULL, &length); /* get :opid */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->opid = atol(token);
+
+ token = lsptok(NULL, &length); /* get :opresulttype */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->opresulttype = atol(token);
+
+ /*
+ * NOTE: Alternatively we can call 'replace_opid' which initializes
+ * both 'opid' and 'op_fcache'.
+ */
+ local_node->op_fcache = (FunctionCache *) NULL;
+
+ return (local_node);
}
/* ----------------
- * _readParam
- *
- * Param is a subclass of Expr
+ * _readParam
+ *
+ * Param is a subclass of Expr
* ----------------
*/
-static Param *
+static Param *
_readParam()
{
- Param *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Param);
-
- token = lsptok(NULL, &length); /* get :paramkind */
- token = lsptok(NULL, &length); /* now read it */
- local_node->paramkind = atoi(token);
-
- token = lsptok(NULL, &length); /* get :paramid */
- token = lsptok(NULL, &length); /* now read it */
- local_node->paramid = atol(token);
-
- token = lsptok(NULL, &length); /* get :paramname */
- token = lsptok(NULL, &length); /* now read it */
- token++; /* skip the first `"' */
- token[length - 2] = '\0'; /* this is the 2nd `"' */
-
- local_node->paramname = pstrdup(token);
- token[length - 2] = '\"'; /* restore the 2nd `"' */
-
- token = lsptok(NULL, &length); /* get :paramtype */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->paramtype = atol(token);
- token = lsptok(NULL, &length); /* get :param_tlist */
- local_node->param_tlist = nodeRead(true); /* now read it */
-
- return(local_node);
+ Param *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Param);
+
+ token = lsptok(NULL, &length); /* get :paramkind */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->paramkind = atoi(token);
+
+ token = lsptok(NULL, &length); /* get :paramid */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->paramid = atol(token);
+
+ token = lsptok(NULL, &length); /* get :paramname */
+ token = lsptok(NULL, &length); /* now read it */
+ token++; /* skip the first `"' */
+ token[length - 2] = '\0'; /* this is the 2nd `"' */
+
+ local_node->paramname = pstrdup(token);
+ token[length - 2] = '\"'; /* restore the 2nd `"' */
+
+ token = lsptok(NULL, &length); /* get :paramtype */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->paramtype = atol(token);
+ token = lsptok(NULL, &length); /* get :param_tlist */
+ local_node->param_tlist = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readAggreg
- *
- * Aggreg is a subclass of Node
+ * _readAggreg
+ *
+ * Aggreg is a subclass of Node
* ----------------
*/
-static Aggreg *
+static Aggreg *
_readAggreg()
{
- Aggreg *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Aggreg);
-
- token = lsptok(NULL, &length); /* eat :aggname */
- token = lsptok(NULL, &length); /* get aggname */
- local_node->aggname = (char*) palloc (length + 1);
- strNcpy (local_node->aggname, token, length);
-
- token = lsptok(NULL, &length); /* eat :basetype */
- token = lsptok(NULL, &length); /* get basetype */
- local_node->basetype = (Oid)atol(token);
-
- token = lsptok(NULL, &length); /* eat :aggtype */
- token = lsptok(NULL, &length); /* get aggtype */
- local_node->aggtype = (Oid)atol(token);
-
- token = lsptok(NULL, &length); /* eat :aggno */
- token = lsptok(NULL, &length); /* get aggno */
- local_node->aggno = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :target */
- local_node->target = nodeRead(true); /* now read it */
-
- return(local_node);
+ Aggreg *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Aggreg);
+
+ token = lsptok(NULL, &length); /* eat :aggname */
+ token = lsptok(NULL, &length); /* get aggname */
+ local_node->aggname = (char *) palloc(length + 1);
+ strNcpy(local_node->aggname, token, length);
+
+ token = lsptok(NULL, &length); /* eat :basetype */
+ token = lsptok(NULL, &length); /* get basetype */
+ local_node->basetype = (Oid) atol(token);
+
+ token = lsptok(NULL, &length); /* eat :aggtype */
+ token = lsptok(NULL, &length); /* get aggtype */
+ local_node->aggtype = (Oid) atol(token);
+
+ token = lsptok(NULL, &length); /* eat :aggno */
+ token = lsptok(NULL, &length); /* get aggno */
+ local_node->aggno = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :target */
+ local_node->target = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/*
- * Stuff from execnodes.h
+ * Stuff from execnodes.h
*/
/* ----------------
- * _readEState
- *
- * EState is a subclass of Node.
+ * _readEState
+ *
+ * EState is a subclass of Node.
* ----------------
*/
-static EState *
+static EState *
_readEState()
{
- EState *local_node;
- char *token;
- int length;
-
- local_node = makeNode(EState);
-
- token = lsptok(NULL, &length); /* get :direction */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->es_direction = atoi(token);
-
- token = lsptok(NULL, &length); /* get :range_table */
-
- local_node->es_range_table = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :result_relation_info */
- token = lsptok(NULL, &length); /* get @ */
- token = lsptok(NULL, &length); /* now read it */
-
- sscanf(token, "%x",(unsigned int *)&local_node->es_result_relation_info);
-
- return(local_node);
+ EState *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(EState);
+
+ token = lsptok(NULL, &length); /* get :direction */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->es_direction = atoi(token);
+
+ token = lsptok(NULL, &length); /* get :range_table */
+
+ local_node->es_range_table = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :result_relation_info */
+ token = lsptok(NULL, &length); /* get @ */
+ token = lsptok(NULL, &length); /* now read it */
+
+ sscanf(token, "%x", (unsigned int *) &local_node->es_result_relation_info);
+
+ return (local_node);
}
/*
- * Stuff from relation.h
+ * Stuff from relation.h
*/
/* ----------------
- * _readRel
+ * _readRel
* ----------------
*/
-static Rel *
+static Rel *
_readRel()
{
- Rel *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Rel);
-
- token = lsptok(NULL, &length); /* get :relids */
- local_node->relids =
- toIntList(nodeRead(true)); /* now read it */
-
- token = lsptok(NULL, &length); /* get :indexed */
- token = lsptok(NULL, &length); /* now read it */
-
- if (!strncmp(token, "true", 4))
- {
- local_node->indexed = true;
- }
- else
- {
- local_node->indexed = false;
- }
-
- token = lsptok(NULL, &length); /* get :pages */
- token = lsptok(NULL, &length); /* now read it */
- local_node->pages = (unsigned int) atoi(token);
-
- token = lsptok(NULL, &length); /* get :tuples */
- token = lsptok(NULL, &length); /* now read it */
- local_node->tuples = (unsigned int) atoi(token);
-
- token = lsptok(NULL, &length); /* get :size */
- token = lsptok(NULL, &length); /* now read it */
- local_node->size = (unsigned int) atoi(token);
-
- token = lsptok(NULL, &length); /* get :width */
- token = lsptok(NULL, &length); /* now read it */
- local_node->width = (unsigned int) atoi(token);
-
- token = lsptok(NULL, &length); /* get :targetlist */
- local_node->targetlist = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :pathlist */
- local_node->pathlist = nodeRead(true); /* now read it */
-
- /*
- * Not sure if these are nodes or not. They're declared as
- * struct Path *. Since i don't know, i'll just print the
- * addresses for now. This can be changed later, if necessary.
- */
-
- token = lsptok(NULL, &length); /* get :unorderpath */
- token = lsptok(NULL, &length); /* get @ */
- token = lsptok(NULL, &length); /* now read it */
-
- sscanf(token, "%x", (unsigned int *)&local_node->unorderedpath);
-
- token = lsptok(NULL, &length); /* get :cheapestpath */
- token = lsptok(NULL, &length); /* get @ */
- token = lsptok(NULL, &length); /* now read it */
-
- sscanf(token, "%x", (unsigned int *)&local_node->cheapestpath);
-
-
- token = lsptok(NULL, &length); /* get :clauseinfo */
- local_node->clauseinfo = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :joininfo */
- local_node->joininfo = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :innerjoin */
- local_node->innerjoin = nodeRead(true); /* now read it */
-
- return(local_node);
+ Rel *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Rel);
+
+ token = lsptok(NULL, &length); /* get :relids */
+ local_node->relids =
+ toIntList(nodeRead(true)); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :indexed */
+ token = lsptok(NULL, &length); /* now read it */
+
+ if (!strncmp(token, "true", 4))
+ {
+ local_node->indexed = true;
+ }
+ else
+ {
+ local_node->indexed = false;
+ }
+
+ token = lsptok(NULL, &length); /* get :pages */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->pages = (unsigned int) atoi(token);
+
+ token = lsptok(NULL, &length); /* get :tuples */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->tuples = (unsigned int) atoi(token);
+
+ token = lsptok(NULL, &length); /* get :size */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->size = (unsigned int) atoi(token);
+
+ token = lsptok(NULL, &length); /* get :width */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->width = (unsigned int) atoi(token);
+
+ token = lsptok(NULL, &length); /* get :targetlist */
+ local_node->targetlist = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :pathlist */
+ local_node->pathlist = nodeRead(true); /* now read it */
+
+ /*
+ * Not sure if these are nodes or not. They're declared as struct
+ * Path *. Since i don't know, i'll just print the addresses for now.
+ * This can be changed later, if necessary.
+ */
+
+ token = lsptok(NULL, &length); /* get :unorderpath */
+ token = lsptok(NULL, &length); /* get @ */
+ token = lsptok(NULL, &length); /* now read it */
+
+ sscanf(token, "%x", (unsigned int *) &local_node->unorderedpath);
+
+ token = lsptok(NULL, &length); /* get :cheapestpath */
+ token = lsptok(NULL, &length); /* get @ */
+ token = lsptok(NULL, &length); /* now read it */
+
+ sscanf(token, "%x", (unsigned int *) &local_node->cheapestpath);
+
+
+ token = lsptok(NULL, &length); /* get :clauseinfo */
+ local_node->clauseinfo = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :joininfo */
+ local_node->joininfo = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :innerjoin */
+ local_node->innerjoin = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readTargetEntry
+ * _readTargetEntry
* ----------------
*/
static TargetEntry *
_readTargetEntry()
{
- TargetEntry *local_node;
- char *token;
- int length;
+ TargetEntry *local_node;
+ char *token;
+ int length;
- local_node = makeNode(TargetEntry);
+ local_node = makeNode(TargetEntry);
- token = lsptok(NULL, &length); /* get :resdom */
- local_node->resdom = nodeRead(true); /* now read it */
+ token = lsptok(NULL, &length); /* get :resdom */
+ local_node->resdom = nodeRead(true); /* now read it */
- token = lsptok(NULL, &length); /* get :expr */
- local_node->expr = nodeRead(true); /* now read it */
+ token = lsptok(NULL, &length); /* get :expr */
+ local_node->expr = nodeRead(true); /* now read it */
- return (local_node);
+ return (local_node);
}
/* ----------------
- * _readTargetEntry
+ * _readTargetEntry
* ----------------
*/
static RangeTblEntry *
_readRangeTblEntry()
{
- RangeTblEntry *local_node;
- char *token;
- int length;
+ RangeTblEntry *local_node;
+ char *token;
+ int length;
- local_node = makeNode(RangeTblEntry);
+ local_node = makeNode(RangeTblEntry);
- token = lsptok(NULL, &length); /* eat :relname */
- token = lsptok(NULL, &length); /* get :relname */
- if (!strncmp(token, "\"null\"", 5)) {
- local_node->relname = NULL;
- }else {
- /*
- * Peel off ""'s, then make a true copy.
- */
-
- token++;
- token[length - 2] = '\0';
-
- local_node->relname = (char *) palloc(NAMEDATALEN);
- strcpy(local_node->relname, token);
- token[length - 2] = '\"';
- }
-
- token = lsptok(NULL, &length); /* eat :inh */
- token = lsptok(NULL, &length); /* get :inh */
- local_node->inh = atoi(token);
-
- token = lsptok(NULL, &length); /* eat :refname */
- token = lsptok(NULL, &length); /* get :refname */
- if (!strncmp(token, "\"null\"", 5)) {
- local_node->refname = NULL;
- }else {
- /*
- * Peel off ""'s, then make a true copy.
- */
-
- token++;
- token[length - 2] = '\0';
-
- local_node->refname = (char*)pstrdup(token);
- token[length - 2] = '\"';
- }
-
- token = lsptok(NULL, &length); /* eat :relid */
- token = lsptok(NULL, &length); /* get :relid */
- local_node->relid = atoi(token);
-
- return (local_node);
+ token = lsptok(NULL, &length); /* eat :relname */
+ token = lsptok(NULL, &length); /* get :relname */
+ if (!strncmp(token, "\"null\"", 5))
+ {
+ local_node->relname = NULL;
+ }
+ else
+ {
+
+ /*
+ * Peel off ""'s, then make a true copy.
+ */
+
+ token++;
+ token[length - 2] = '\0';
+
+ local_node->relname = (char *) palloc(NAMEDATALEN);
+ strcpy(local_node->relname, token);
+ token[length - 2] = '\"';
+ }
+
+ token = lsptok(NULL, &length); /* eat :inh */
+ token = lsptok(NULL, &length); /* get :inh */
+ local_node->inh = atoi(token);
+
+ token = lsptok(NULL, &length); /* eat :refname */
+ token = lsptok(NULL, &length); /* get :refname */
+ if (!strncmp(token, "\"null\"", 5))
+ {
+ local_node->refname = NULL;
+ }
+ else
+ {
+
+ /*
+ * Peel off ""'s, then make a true copy.
+ */
+
+ token++;
+ token[length - 2] = '\0';
+
+ local_node->refname = (char *) pstrdup(token);
+ token[length - 2] = '\"';
+ }
+
+ token = lsptok(NULL, &length); /* eat :relid */
+ token = lsptok(NULL, &length); /* get :relid */
+ local_node->relid = atoi(token);
+
+ return (local_node);
}
/* ----------------
- * _readPath
- *
- * Path is a subclass of Node.
+ * _readPath
+ *
+ * Path is a subclass of Node.
* ----------------
*/
-static Path *
+static Path *
_readPath()
{
- Path *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Path);
-
- token = lsptok(NULL, &length); /* get :pathtype */
- token = lsptok(NULL, &length); /* now read it */
- local_node->pathtype = atol(token);
-
- token = lsptok(NULL, &length); /* get :cost */
- token = lsptok(NULL, &length); /* now read it */
- local_node->path_cost = (Cost) atof(token);
-
+ Path *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Path);
+
+ token = lsptok(NULL, &length); /* get :pathtype */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->pathtype = atol(token);
+
+ token = lsptok(NULL, &length); /* get :cost */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->path_cost = (Cost) atof(token);
+
#if 0
- token = lsptok(NULL, &length); /* get :p_ordering */
- local_node->p_ordering =
- nodeRead(true); /* now read it */
+ token = lsptok(NULL, &length); /* get :p_ordering */
+ local_node->p_ordering =
+ nodeRead(true); /* now read it */
#endif
-
- token = lsptok(NULL, &length); /* get :keys */
- local_node->keys = nodeRead(true); /* now read it */
-
- return(local_node);
+
+ token = lsptok(NULL, &length); /* get :keys */
+ local_node->keys = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readIndexPath
- *
- * IndexPath is a subclass of Path.
+ * _readIndexPath
+ *
+ * IndexPath is a subclass of Path.
* ----------------
*/
static IndexPath *
_readIndexPath()
{
- IndexPath *local_node;
- char *token;
- int length;
-
- local_node = makeNode(IndexPath);
-
- token = lsptok(NULL, &length); /* get :pathtype */
- token = lsptok(NULL, &length); /* now read it */
- local_node->path.pathtype = atol(token);
-
- token = lsptok(NULL, &length); /* get :cost */
- token = lsptok(NULL, &length); /* now read it */
- local_node->path.path_cost = (Cost) atof(token);
-
+ IndexPath *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(IndexPath);
+
+ token = lsptok(NULL, &length); /* get :pathtype */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->path.pathtype = atol(token);
+
+ token = lsptok(NULL, &length); /* get :cost */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->path.path_cost = (Cost) atof(token);
+
#if 0
- token = lsptok(NULL, &length); /* get :p_ordering */
- local_node->path.p_ordering = nodeRead(true); /* now read it */
+ token = lsptok(NULL, &length); /* get :p_ordering */
+ local_node->path.p_ordering = nodeRead(true); /* now read it */
#endif
-
- token = lsptok(NULL, &length); /* get :keys */
- local_node->path.keys = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :indexid */
- local_node->indexid =
- toIntList(nodeRead(true));
-
- token = lsptok(NULL, &length); /* get :indexqual */
- local_node->indexqual = nodeRead(true); /* now read it */
-
- return(local_node);
+
+ token = lsptok(NULL, &length); /* get :keys */
+ local_node->path.keys = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :indexid */
+ local_node->indexid =
+ toIntList(nodeRead(true));
+
+ token = lsptok(NULL, &length); /* get :indexqual */
+ local_node->indexqual = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readJoinPath
- *
- * JoinPath is a subclass of Path
+ * _readJoinPath
+ *
+ * JoinPath is a subclass of Path
* ----------------
*/
static JoinPath *
_readJoinPath()
{
- JoinPath *local_node;
- char *token;
- int length;
-
-
- local_node = makeNode(JoinPath);
-
- token = lsptok(NULL, &length); /* get :pathtype */
- token = lsptok(NULL, &length); /* now read it */
- local_node->path.pathtype = atol(token);
-
- token = lsptok(NULL, &length); /* get :cost */
- token = lsptok(NULL, &length); /* now read it */
- local_node->path.path_cost = (Cost) atof(token);
-
+ JoinPath *local_node;
+ char *token;
+ int length;
+
+
+ local_node = makeNode(JoinPath);
+
+ token = lsptok(NULL, &length); /* get :pathtype */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->path.pathtype = atol(token);
+
+ token = lsptok(NULL, &length); /* get :cost */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->path.path_cost = (Cost) atof(token);
+
#if 0
- token = lsptok(NULL, &length); /* get :p_ordering */
- local_node->path.p_ordering = nodeRead(true); /* now read it */
+ token = lsptok(NULL, &length); /* get :p_ordering */
+ local_node->path.p_ordering = nodeRead(true); /* now read it */
#endif
-
- token = lsptok(NULL, &length); /* get :keys */
- local_node->path.keys = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :pathclauseinfo */
- local_node->pathclauseinfo = nodeRead(true); /* now read it */
-
- /*
- * Not sure if these are nodes; they're declared as "struct path *".
- * For now, i'll just print the addresses.
- *
- * GJK: Since I am parsing this stuff, I'll just ignore the addresses,
- * and initialize these pointers to NULL.
- */
-
- token = lsptok(NULL, &length); /* get :outerjoinpath */
- token = lsptok(NULL, &length); /* get @ */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->outerjoinpath = NULL;
-
- token = lsptok(NULL, &length); /* get :innerjoinpath */
- token = lsptok(NULL, &length); /* get @ */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->innerjoinpath = NULL;
-
- token = lsptok(NULL, &length); /* get :outerjoincost */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->path.outerjoincost = (Cost) atof(token);
-
- token = lsptok(NULL, &length); /* get :joinid */
- local_node->path.joinid =
- toIntList(nodeRead(true)); /* now read it */
-
- return(local_node);
+
+ token = lsptok(NULL, &length); /* get :keys */
+ local_node->path.keys = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :pathclauseinfo */
+ local_node->pathclauseinfo = nodeRead(true); /* now read it */
+
+ /*
+ * Not sure if these are nodes; they're declared as "struct path *".
+ * For now, i'll just print the addresses.
+ *
+ * GJK: Since I am parsing this stuff, I'll just ignore the addresses,
+ * and initialize these pointers to NULL.
+ */
+
+ token = lsptok(NULL, &length); /* get :outerjoinpath */
+ token = lsptok(NULL, &length); /* get @ */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->outerjoinpath = NULL;
+
+ token = lsptok(NULL, &length); /* get :innerjoinpath */
+ token = lsptok(NULL, &length); /* get @ */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->innerjoinpath = NULL;
+
+ token = lsptok(NULL, &length); /* get :outerjoincost */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->path.outerjoincost = (Cost) atof(token);
+
+ token = lsptok(NULL, &length); /* get :joinid */
+ local_node->path.joinid =
+ toIntList(nodeRead(true)); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readMergePath
- *
- * MergePath is a subclass of JoinPath.
+ * _readMergePath
+ *
+ * MergePath is a subclass of JoinPath.
* ----------------
*/
static MergePath *
_readMergePath()
{
- MergePath *local_node;
- char *token;
- int length;
-
- local_node = makeNode(MergePath);
-
- token = lsptok(NULL, &length); /* get :pathtype */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->jpath.path.pathtype = atol(token);
-
- token = lsptok(NULL, &length); /* get :cost */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->jpath.path.path_cost = (Cost) atof(token);
-
+ MergePath *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(MergePath);
+
+ token = lsptok(NULL, &length); /* get :pathtype */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->jpath.path.pathtype = atol(token);
+
+ token = lsptok(NULL, &length); /* get :cost */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->jpath.path.path_cost = (Cost) atof(token);
+
#if 0
- token = lsptok(NULL, &length); /* get :p_ordering */
- local_node->jpath.path.p_ordering = nodeRead(true); /* now read it */
+ token = lsptok(NULL, &length); /* get :p_ordering */
+ local_node->jpath.path.p_ordering = nodeRead(true); /* now read it */
#endif
-
- token = lsptok(NULL, &length); /* get :keys */
- local_node->jpath.path.keys = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :pathclauseinfo */
- local_node->jpath.pathclauseinfo = nodeRead(true); /* now read it */
-
- /*
- * Not sure if these are nodes; they're declared as "struct path *".
- * For now, i'll just print the addresses.
- *
- * GJK: Since I am parsing this stuff, I'll just ignore the addresses,
- * and initialize these pointers to NULL.
- */
-
- token = lsptok(NULL, &length); /* get :outerjoinpath */
- token = lsptok(NULL, &length); /* get @ */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->jpath.outerjoinpath = NULL;
-
- token = lsptok(NULL, &length); /* get :innerjoinpath */
- token = lsptok(NULL, &length); /* get @ */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->jpath.innerjoinpath = NULL;
-
- token = lsptok(NULL, &length); /* get :outerjoincost */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->jpath.path.outerjoincost = (Cost) atof(token);
-
- token = lsptok(NULL, &length); /* get :joinid */
- local_node->jpath.path.joinid =
- toIntList(nodeRead(true)); /* now read it */
-
- token = lsptok(NULL, &length); /* get :path_mergeclauses */
- local_node->path_mergeclauses = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :outersortkeys */
- local_node->outersortkeys = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :innersortkeys */
- local_node->innersortkeys = nodeRead(true); /* now read it */
-
- return(local_node);
+
+ token = lsptok(NULL, &length); /* get :keys */
+ local_node->jpath.path.keys = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :pathclauseinfo */
+ local_node->jpath.pathclauseinfo = nodeRead(true); /* now read it */
+
+ /*
+ * Not sure if these are nodes; they're declared as "struct path *".
+ * For now, i'll just print the addresses.
+ *
+ * GJK: Since I am parsing this stuff, I'll just ignore the addresses,
+ * and initialize these pointers to NULL.
+ */
+
+ token = lsptok(NULL, &length); /* get :outerjoinpath */
+ token = lsptok(NULL, &length); /* get @ */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->jpath.outerjoinpath = NULL;
+
+ token = lsptok(NULL, &length); /* get :innerjoinpath */
+ token = lsptok(NULL, &length); /* get @ */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->jpath.innerjoinpath = NULL;
+
+ token = lsptok(NULL, &length); /* get :outerjoincost */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->jpath.path.outerjoincost = (Cost) atof(token);
+
+ token = lsptok(NULL, &length); /* get :joinid */
+ local_node->jpath.path.joinid =
+ toIntList(nodeRead(true)); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :path_mergeclauses */
+ local_node->path_mergeclauses = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :outersortkeys */
+ local_node->outersortkeys = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :innersortkeys */
+ local_node->innersortkeys = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readHashPath
- *
- * HashPath is a subclass of JoinPath.
+ * _readHashPath
+ *
+ * HashPath is a subclass of JoinPath.
* ----------------
*/
static HashPath *
_readHashPath()
{
- HashPath *local_node;
- char *token;
- int length;
-
- local_node = makeNode(HashPath);
-
- token = lsptok(NULL, &length); /* get :pathtype */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->jpath.path.pathtype = atol(token);
-
- token = lsptok(NULL, &length); /* get :cost */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->jpath.path.path_cost = (Cost) atof(token);
-
+ HashPath *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(HashPath);
+
+ token = lsptok(NULL, &length); /* get :pathtype */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->jpath.path.pathtype = atol(token);
+
+ token = lsptok(NULL, &length); /* get :cost */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->jpath.path.path_cost = (Cost) atof(token);
+
#if 0
- token = lsptok(NULL, &length); /* get :p_ordering */
- local_node->jpath.path.p_ordering = nodeRead(true); /* now read it */
+ token = lsptok(NULL, &length); /* get :p_ordering */
+ local_node->jpath.path.p_ordering = nodeRead(true); /* now read it */
#endif
-
- token = lsptok(NULL, &length); /* get :keys */
- local_node->jpath.path.keys = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :pathclauseinfo */
- local_node->jpath.pathclauseinfo = nodeRead(true); /* now read it */
-
- /*
- * Not sure if these are nodes; they're declared as "struct path *".
- * For now, i'll just print the addresses.
- *
- * GJK: Since I am parsing this stuff, I'll just ignore the addresses,
- * and initialize these pointers to NULL.
- */
-
- token = lsptok(NULL, &length); /* get :outerjoinpath */
- token = lsptok(NULL, &length); /* get @ */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->jpath.outerjoinpath = NULL;
-
- token = lsptok(NULL, &length); /* get :innerjoinpath */
- token = lsptok(NULL, &length); /* get @ */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->jpath.innerjoinpath = NULL;
-
- token = lsptok(NULL, &length); /* get :outerjoincost */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->jpath.path.outerjoincost = (Cost) atof(token);
-
- token = lsptok(NULL, &length); /* get :joinid */
- local_node->jpath.path.joinid =
- toIntList(nodeRead(true)); /* now read it */
-
- token = lsptok(NULL, &length); /* get :path_hashclauses */
- local_node->path_hashclauses = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :outerhashkeys */
- local_node->outerhashkeys = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :innerhashkeys */
- local_node->innerhashkeys = nodeRead(true); /* now read it */
-
- return(local_node);
+
+ token = lsptok(NULL, &length); /* get :keys */
+ local_node->jpath.path.keys = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :pathclauseinfo */
+ local_node->jpath.pathclauseinfo = nodeRead(true); /* now read it */
+
+ /*
+ * Not sure if these are nodes; they're declared as "struct path *".
+ * For now, i'll just print the addresses.
+ *
+ * GJK: Since I am parsing this stuff, I'll just ignore the addresses,
+ * and initialize these pointers to NULL.
+ */
+
+ token = lsptok(NULL, &length); /* get :outerjoinpath */
+ token = lsptok(NULL, &length); /* get @ */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->jpath.outerjoinpath = NULL;
+
+ token = lsptok(NULL, &length); /* get :innerjoinpath */
+ token = lsptok(NULL, &length); /* get @ */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->jpath.innerjoinpath = NULL;
+
+ token = lsptok(NULL, &length); /* get :outerjoincost */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->jpath.path.outerjoincost = (Cost) atof(token);
+
+ token = lsptok(NULL, &length); /* get :joinid */
+ local_node->jpath.path.joinid =
+ toIntList(nodeRead(true)); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :path_hashclauses */
+ local_node->path_hashclauses = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :outerhashkeys */
+ local_node->outerhashkeys = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :innerhashkeys */
+ local_node->innerhashkeys = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readOrderKey
- *
- * OrderKey is a subclass of Node.
+ * _readOrderKey
+ *
+ * OrderKey is a subclass of Node.
* ----------------
*/
static OrderKey *
_readOrderKey()
{
- OrderKey *local_node;
- char *token;
- int length;
-
- local_node = makeNode(OrderKey);
-
- token = lsptok(NULL, &length); /* get :attribute_number */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->attribute_number = atoi(token);
-
- token = lsptok(NULL, &length); /* get :array_index */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->array_index = atoi(token);
-
- return(local_node);
+ OrderKey *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(OrderKey);
+
+ token = lsptok(NULL, &length); /* get :attribute_number */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->attribute_number = atoi(token);
+
+ token = lsptok(NULL, &length); /* get :array_index */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->array_index = atoi(token);
+
+ return (local_node);
}
/* ----------------
- * _readJoinKey
- *
- * JoinKey is a subclass of Node.
+ * _readJoinKey
+ *
+ * JoinKey is a subclass of Node.
* ----------------
*/
static JoinKey *
_readJoinKey()
{
- JoinKey *local_node;
- char *token;
- int length;
-
- local_node = makeNode(JoinKey);
-
- token = lsptok(NULL, &length); /* get :outer */
- local_node->outer = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :inner */
- local_node->inner = nodeRead(true); /* now read it */
-
- return(local_node);
+ JoinKey *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(JoinKey);
+
+ token = lsptok(NULL, &length); /* get :outer */
+ local_node->outer = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :inner */
+ local_node->inner = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readMergeOrder
- *
- * MergeOrder is a subclass of Node.
+ * _readMergeOrder
+ *
+ * MergeOrder is a subclass of Node.
* ----------------
*/
static MergeOrder *
_readMergeOrder()
{
- MergeOrder *local_node;
- char *token;
- int length;
-
- local_node = makeNode(MergeOrder);
- token = lsptok(NULL, &length); /* get :join_operator */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->join_operator = atol(token);
-
- token = lsptok(NULL, &length); /* get :left_operator */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->left_operator = atol(token);
-
- token = lsptok(NULL, &length); /* get :right_operator */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->right_operator = atol(token);
-
- token = lsptok(NULL, &length); /* get :left_type */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->left_type = atol(token);
-
- token = lsptok(NULL, &length); /* get :right_type */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->right_type = atol(token);
-
- return(local_node);
+ MergeOrder *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(MergeOrder);
+ token = lsptok(NULL, &length); /* get :join_operator */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->join_operator = atol(token);
+
+ token = lsptok(NULL, &length); /* get :left_operator */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->left_operator = atol(token);
+
+ token = lsptok(NULL, &length); /* get :right_operator */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->right_operator = atol(token);
+
+ token = lsptok(NULL, &length); /* get :left_type */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->left_type = atol(token);
+
+ token = lsptok(NULL, &length); /* get :right_type */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->right_type = atol(token);
+
+ return (local_node);
}
/* ----------------
- * _readCInfo
- *
- * CInfo is a subclass of Node.
+ * _readCInfo
+ *
+ * CInfo is a subclass of Node.
* ----------------
*/
-static CInfo *
+static CInfo *
_readCInfo()
{
- CInfo *local_node;
- char *token;
- int length;
-
- local_node = makeNode(CInfo);
-
- token = lsptok(NULL, &length); /* get :clause */
- local_node->clause = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :selectivity */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->selectivity = atof(token);
-
- token = lsptok(NULL, &length); /* get :notclause */
- token = lsptok(NULL, &length); /* now read it */
-
- if (!strncmp(token, "true", 4))
- {
- local_node->notclause = true;
- }
- else
- {
- local_node->notclause = false;
- }
-
- token = lsptok(NULL, &length); /* get :indexids */
- local_node->indexids = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :mergesortorder */
- local_node->mergesortorder = (MergeOrder*) nodeRead(true);
-
- token = lsptok(NULL, &length); /* get :hashjoinoperator */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->hashjoinoperator = atol(token);
-
- return(local_node);
+ CInfo *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(CInfo);
+
+ token = lsptok(NULL, &length); /* get :clause */
+ local_node->clause = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :selectivity */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->selectivity = atof(token);
+
+ token = lsptok(NULL, &length); /* get :notclause */
+ token = lsptok(NULL, &length); /* now read it */
+
+ if (!strncmp(token, "true", 4))
+ {
+ local_node->notclause = true;
+ }
+ else
+ {
+ local_node->notclause = false;
+ }
+
+ token = lsptok(NULL, &length); /* get :indexids */
+ local_node->indexids = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :mergesortorder */
+ local_node->mergesortorder = (MergeOrder *) nodeRead(true);
+
+ token = lsptok(NULL, &length); /* get :hashjoinoperator */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->hashjoinoperator = atol(token);
+
+ return (local_node);
}
/* ----------------
- * _readJoinMethod
- *
- * JoinMethod is a subclass of Node.
+ * _readJoinMethod
+ *
+ * JoinMethod is a subclass of Node.
* ----------------
*/
static JoinMethod *
_readJoinMethod()
{
- JoinMethod *local_node;
- char *token;
- int length;
-
- local_node = makeNode(JoinMethod);
-
- token = lsptok(NULL, &length); /* get :jmkeys */
- local_node->jmkeys = nodeRead(true);/* now read it */
-
- token = lsptok(NULL, &length); /* get :clauses */
- local_node->clauses = nodeRead(true); /* now read it */
-
- return(local_node);
+ JoinMethod *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(JoinMethod);
+
+ token = lsptok(NULL, &length); /* get :jmkeys */
+ local_node->jmkeys = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :clauses */
+ local_node->clauses = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readHInfo
- *
+ * _readHInfo
+ *
* HInfo is a subclass of JoinMethod.
* ----------------
*/
-static HInfo *
+static HInfo *
_readHInfo()
{
- HInfo *local_node;
- char *token;
- int length;
-
- local_node = makeNode(HInfo);
-
- token = lsptok(NULL, &length); /* get :hashop */
- token = lsptok(NULL, &length); /* now read it */
-
- local_node->hashop = atoi(token);
-
- token = lsptok(NULL, &length); /* get :jmkeys */
- local_node->jmethod.jmkeys = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :clauses */
- local_node->jmethod.clauses = nodeRead(true); /* now read it */
-
- return(local_node);
+ HInfo *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(HInfo);
+
+ token = lsptok(NULL, &length); /* get :hashop */
+ token = lsptok(NULL, &length); /* now read it */
+
+ local_node->hashop = atoi(token);
+
+ token = lsptok(NULL, &length); /* get :jmkeys */
+ local_node->jmethod.jmkeys = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :clauses */
+ local_node->jmethod.clauses = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * _readJInfo()
- *
- * JInfo is a subclass of Node.
+ * _readJInfo()
+ *
+ * JInfo is a subclass of Node.
* ----------------
*/
-static JInfo *
+static JInfo *
_readJInfo()
{
- JInfo *local_node;
- char *token;
- int length;
-
- local_node = makeNode(JInfo);
-
- token = lsptok(NULL, &length); /* get :otherrels */
- local_node->otherrels =
- toIntList(nodeRead(true)); /* now read it */
-
- token = lsptok(NULL, &length); /* get :jinfoclauseinfo */
- local_node->jinfoclauseinfo = nodeRead(true); /* now read it */
-
- token = lsptok(NULL, &length); /* get :mergesortable */
-
- if (!strncmp(token, "true", 4))
- {
- local_node->mergesortable = true;
- }
- else
- {
- local_node->mergesortable = false;
- }
-
- token = lsptok(NULL, &length); /* get :hashjoinable */
-
- if (!strncmp(token, "true", 4))
- {
- local_node->hashjoinable = true;
- }
- else
- {
- local_node->hashjoinable = false;
- }
-
- return(local_node);
+ JInfo *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(JInfo);
+
+ token = lsptok(NULL, &length); /* get :otherrels */
+ local_node->otherrels =
+ toIntList(nodeRead(true)); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :jinfoclauseinfo */
+ local_node->jinfoclauseinfo = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* get :mergesortable */
+
+ if (!strncmp(token, "true", 4))
+ {
+ local_node->mergesortable = true;
+ }
+ else
+ {
+ local_node->mergesortable = false;
+ }
+
+ token = lsptok(NULL, &length); /* get :hashjoinable */
+
+ if (!strncmp(token, "true", 4))
+ {
+ local_node->hashjoinable = true;
+ }
+ else
+ {
+ local_node->hashjoinable = false;
+ }
+
+ return (local_node);
}
/* ----------------
- * _readIter()
+ * _readIter()
*
* ----------------
*/
-static Iter *
+static Iter *
_readIter()
{
- Iter *local_node;
- char *token;
- int length;
-
- local_node = makeNode(Iter);
-
- token = lsptok(NULL, &length); /* eat :iterexpr */
- local_node->iterexpr = nodeRead(true); /* now read it */
-
- return(local_node);
+ Iter *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(Iter);
+
+ token = lsptok(NULL, &length); /* eat :iterexpr */
+ local_node->iterexpr = nodeRead(true); /* now read it */
+
+ return (local_node);
}
/* ----------------
- * parsePlanString
+ * parsePlanString
*
* Given a character string containing a plan, parsePlanString sets up the
* plan structure representing that plan.
@@ -1823,164 +1867,263 @@ _readIter()
* The string passed to parsePlanString must be null-terminated.
* ----------------
*/
-Node *
+Node *
parsePlanString(void)
{
- char *token;
- int length;
- void *return_value = NULL;
-
- token = lsptok(NULL, &length);
-
- if (!strncmp(token, "PLAN", 4)) {
- return_value = _readPlan();
- }else if (!strncmp(token, "RESULT", 6)) {
- return_value = _readResult();
- }else if (!strncmp(token, "EXISTENTIAL", 11)) {
- return_value = _readExistential();
- }else if (!strncmp(token, "APPEND", 6)) {
- return_value = _readAppend();
- }else if (!strncmp(token, "JOIN", 4)) {
- return_value = _readJoin();
- }else if (!strncmp(token, "NESTLOOP", 8)) {
- return_value = _readNestLoop();
- }else if (!strncmp(token, "MERGEJOIN", 9)) {
- return_value = _readMergeJoin();
- }else if (!strncmp(token, "HASHJOIN", 8)) {
- return_value = _readHashJoin();
- }else if (!strncmp(token, "SCAN", 4)) {
- return_value = _readScan();
- }else if (!strncmp(token, "SEQSCAN", 7)) {
- return_value = _readSeqScan();
- }else if (!strncmp(token, "INDEXSCAN", 9)) {
- return_value = _readIndexScan();
- }else if (!strncmp(token, "TEMP", 4)) {
- return_value = _readTemp();
- }else if (!strncmp(token, "SORT", 4)) {
- return_value = _readSort();
- }else if (!strncmp(token, "AGGREG", 6)) {
- return_value = _readAggreg();
- }else if (!strncmp(token, "AGG", 3)) {
- return_value = _readAgg();
- }else if (!strncmp(token, "UNIQUE", 4)) {
- return_value = _readUnique();
- }else if (!strncmp(token, "HASH", 4)) {
- return_value = _readHash();
- }else if (!strncmp(token, "RESDOM", 6)) {
- return_value = _readResdom();
- }else if (!strncmp(token, "EXPR", 4)) {
- return_value = _readExpr();
- }else if (!strncmp(token, "ARRAYREF", 7)) {
- /* make sure this strncmp is done before that of ARRAY */
- return_value = _readArrayRef();
- }else if (!strncmp(token, "ARRAY", 5)) {
- return_value = _readArray();
- }else if (!strncmp(token, "VAR", 3)) {
- return_value = _readVar();
- }else if (!strncmp(token, "CONST", 5)) {
- return_value = _readConst();
- }else if (!strncmp(token, "FUNC", 4)) {
- return_value = _readFunc();
- }else if (!strncmp(token, "OPER", 4)) {
- return_value = _readOper();
- }else if (!strncmp(token, "PARAM", 5)) {
- return_value = _readParam();
- }else if (!strncmp(token, "ESTATE", 6)) {
- return_value = _readEState();
- }else if (!strncmp(token, "REL", 3)) {
- return_value = _readRel();
- }else if (!strncmp(token, "TLE", 3)) {
- return_value = _readTargetEntry();
- }else if (!strncmp(token, "RTE", 3)) {
- return_value = _readRangeTblEntry();
- }else if (!strncmp(token, "PATH", 4)) {
- return_value = _readPath();
- }else if (!strncmp(token, "INDEXPATH", 9)) {
- return_value = _readIndexPath();
- }else if (!strncmp(token, "JOINPATH", 8)) {
- return_value = _readJoinPath();
- }else if (!strncmp(token, "MERGEPATH", 9)) {
- return_value = _readMergePath();
- }else if (!strncmp(token, "HASHPATH", 8)) {
- return_value = _readHashPath();
- }else if (!strncmp(token, "ORDERKEY", 8)) {
- return_value = _readOrderKey();
- }else if (!strncmp(token, "JOINKEY", 7)) {
- return_value = _readJoinKey();
- }else if (!strncmp(token, "MERGEORDER", 10)) {
- return_value = _readMergeOrder();
- }else if (!strncmp(token, "CINFO", 5)) {
- return_value = _readCInfo();
- }else if (!strncmp(token, "JOINMETHOD", 10)) {
- return_value = _readJoinMethod();
- }else if (!strncmp(token, "JINFO", 5)) {
- return_value = _readJInfo();
- }else if (!strncmp(token, "HINFO", 5)) {
- return_value = _readHInfo();
- }else if (!strncmp(token, "ITER", 4)) {
- return_value = _readIter();
- }else if (!strncmp(token, "QUERY", 5)) {
- return_value = _readQuery();
- }else {
- elog(WARN, "badly formatted planstring \"%.10s\"...\n", token);
- }
-
- return ((Node*)return_value);
+ char *token;
+ int length;
+ void *return_value = NULL;
+
+ token = lsptok(NULL, &length);
+
+ if (!strncmp(token, "PLAN", 4))
+ {
+ return_value = _readPlan();
+ }
+ else if (!strncmp(token, "RESULT", 6))
+ {
+ return_value = _readResult();
+ }
+ else if (!strncmp(token, "EXISTENTIAL", 11))
+ {
+ return_value = _readExistential();
+ }
+ else if (!strncmp(token, "APPEND", 6))
+ {
+ return_value = _readAppend();
+ }
+ else if (!strncmp(token, "JOIN", 4))
+ {
+ return_value = _readJoin();
+ }
+ else if (!strncmp(token, "NESTLOOP", 8))
+ {
+ return_value = _readNestLoop();
+ }
+ else if (!strncmp(token, "MERGEJOIN", 9))
+ {
+ return_value = _readMergeJoin();
+ }
+ else if (!strncmp(token, "HASHJOIN", 8))
+ {
+ return_value = _readHashJoin();
+ }
+ else if (!strncmp(token, "SCAN", 4))
+ {
+ return_value = _readScan();
+ }
+ else if (!strncmp(token, "SEQSCAN", 7))
+ {
+ return_value = _readSeqScan();
+ }
+ else if (!strncmp(token, "INDEXSCAN", 9))
+ {
+ return_value = _readIndexScan();
+ }
+ else if (!strncmp(token, "TEMP", 4))
+ {
+ return_value = _readTemp();
+ }
+ else if (!strncmp(token, "SORT", 4))
+ {
+ return_value = _readSort();
+ }
+ else if (!strncmp(token, "AGGREG", 6))
+ {
+ return_value = _readAggreg();
+ }
+ else if (!strncmp(token, "AGG", 3))
+ {
+ return_value = _readAgg();
+ }
+ else if (!strncmp(token, "UNIQUE", 4))
+ {
+ return_value = _readUnique();
+ }
+ else if (!strncmp(token, "HASH", 4))
+ {
+ return_value = _readHash();
+ }
+ else if (!strncmp(token, "RESDOM", 6))
+ {
+ return_value = _readResdom();
+ }
+ else if (!strncmp(token, "EXPR", 4))
+ {
+ return_value = _readExpr();
+ }
+ else if (!strncmp(token, "ARRAYREF", 7))
+ {
+ /* make sure this strncmp is done before that of ARRAY */
+ return_value = _readArrayRef();
+ }
+ else if (!strncmp(token, "ARRAY", 5))
+ {
+ return_value = _readArray();
+ }
+ else if (!strncmp(token, "VAR", 3))
+ {
+ return_value = _readVar();
+ }
+ else if (!strncmp(token, "CONST", 5))
+ {
+ return_value = _readConst();
+ }
+ else if (!strncmp(token, "FUNC", 4))
+ {
+ return_value = _readFunc();
+ }
+ else if (!strncmp(token, "OPER", 4))
+ {
+ return_value = _readOper();
+ }
+ else if (!strncmp(token, "PARAM", 5))
+ {
+ return_value = _readParam();
+ }
+ else if (!strncmp(token, "ESTATE", 6))
+ {
+ return_value = _readEState();
+ }
+ else if (!strncmp(token, "REL", 3))
+ {
+ return_value = _readRel();
+ }
+ else if (!strncmp(token, "TLE", 3))
+ {
+ return_value = _readTargetEntry();
+ }
+ else if (!strncmp(token, "RTE", 3))
+ {
+ return_value = _readRangeTblEntry();
+ }
+ else if (!strncmp(token, "PATH", 4))
+ {
+ return_value = _readPath();
+ }
+ else if (!strncmp(token, "INDEXPATH", 9))
+ {
+ return_value = _readIndexPath();
+ }
+ else if (!strncmp(token, "JOINPATH", 8))
+ {
+ return_value = _readJoinPath();
+ }
+ else if (!strncmp(token, "MERGEPATH", 9))
+ {
+ return_value = _readMergePath();
+ }
+ else if (!strncmp(token, "HASHPATH", 8))
+ {
+ return_value = _readHashPath();
+ }
+ else if (!strncmp(token, "ORDERKEY", 8))
+ {
+ return_value = _readOrderKey();
+ }
+ else if (!strncmp(token, "JOINKEY", 7))
+ {
+ return_value = _readJoinKey();
+ }
+ else if (!strncmp(token, "MERGEORDER", 10))
+ {
+ return_value = _readMergeOrder();
+ }
+ else if (!strncmp(token, "CINFO", 5))
+ {
+ return_value = _readCInfo();
+ }
+ else if (!strncmp(token, "JOINMETHOD", 10))
+ {
+ return_value = _readJoinMethod();
+ }
+ else if (!strncmp(token, "JINFO", 5))
+ {
+ return_value = _readJInfo();
+ }
+ else if (!strncmp(token, "HINFO", 5))
+ {
+ return_value = _readHInfo();
+ }
+ else if (!strncmp(token, "ITER", 4))
+ {
+ return_value = _readIter();
+ }
+ else if (!strncmp(token, "QUERY", 5))
+ {
+ return_value = _readQuery();
+ }
+ else
+ {
+ elog(WARN, "badly formatted planstring \"%.10s\"...\n", token);
+ }
+
+ return ((Node *) return_value);
}
+
/*------------------------------------------------------------*/
/* ----------------
- * readDatum
+ * readDatum
*
* given a string representation of the value of the given type,
* create the appropriate Datum
* ----------------
*/
-static Datum
+static Datum
readDatum(Oid type)
{
- int length;
- int tokenLength;
- char *token;
- bool byValue;
- Datum res;
- char *s;
- int i;
-
- byValue = get_typbyval(type);
-
- /*
- * read the actual length of the value
- */
- token = lsptok(NULL, &tokenLength);
- length = atoi(token);
- token = lsptok(NULL, &tokenLength); /* skip the '[' */
-
- if (byValue) {
- if (length > sizeof(Datum)) {
- elog(WARN, "readValue: byval & length = %d", length);
- }
- s = (char *) (&res);
- for (i=0; i<sizeof(Datum); i++) {
- token = lsptok(NULL, &tokenLength);
- s[i] = (char) atoi(token);
- }
- } else if (length <= 0) {
- s = NULL;
- } else if (length >= 1) {
- s = (char*)palloc(length);
- Assert( s!=NULL );
- for (i=0; i<length; i++) {
- token = lsptok(NULL, &tokenLength);
- s[i] = (char) atoi(token);
- }
- res = PointerGetDatum(s);
- }
-
- token = lsptok(NULL, &tokenLength); /* skip the ']' */
- if (token[0] != ']') {
- elog(WARN, "readValue: ']' expected, length =%d", length);
- }
-
- return(res);
+ int length;
+ int tokenLength;
+ char *token;
+ bool byValue;
+ Datum res;
+ char *s;
+ int i;
+
+ byValue = get_typbyval(type);
+
+ /*
+ * read the actual length of the value
+ */
+ token = lsptok(NULL, &tokenLength);
+ length = atoi(token);
+ token = lsptok(NULL, &tokenLength); /* skip the '[' */
+
+ if (byValue)
+ {
+ if (length > sizeof(Datum))
+ {
+ elog(WARN, "readValue: byval & length = %d", length);
+ }
+ s = (char *) (&res);
+ for (i = 0; i < sizeof(Datum); i++)
+ {
+ token = lsptok(NULL, &tokenLength);
+ s[i] = (char) atoi(token);
+ }
+ }
+ else if (length <= 0)
+ {
+ s = NULL;
+ }
+ else if (length >= 1)
+ {
+ s = (char *) palloc(length);
+ Assert(s != NULL);
+ for (i = 0; i < length; i++)
+ {
+ token = lsptok(NULL, &tokenLength);
+ s[i] = (char) atoi(token);
+ }
+ res = PointerGetDatum(s);
+ }
+
+ token = lsptok(NULL, &tokenLength); /* skip the ']' */
+ if (token[0] != ']')
+ {
+ elog(WARN, "readValue: ']' expected, length =%d", length);
+ }
+
+ return (res);
}
diff --git a/src/backend/optimizer/geqo/geqo_copy.c b/src/backend/optimizer/geqo/geqo_copy.c
index 3356f8d5475..4c35f99f9f5 100644
--- a/src/backend/optimizer/geqo/geqo_copy.c
+++ b/src/backend/optimizer/geqo/geqo_copy.c
@@ -4,32 +4,32 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_copy.c,v 1.1 1997/02/19 12:56:40 scrappy Exp $
+ * $Id: geqo_copy.c,v 1.2 1997/09/07 04:43:01 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* this is adopted from D. Whitley's Genitor algorithm */
/*************************************************************/
-/* */
-/* Copyright (c) 1990 */
-/* Darrell L. Whitley */
-/* Computer Science Department */
-/* Colorado State University */
-/* */
-/* Permission is hereby granted to copy all or any part of */
-/* this program for free distribution. The author's name */
-/* and this copyright notice must be included in any copy. */
-/* */
+/* */
+/* Copyright (c) 1990 */
+/* Darrell L. Whitley */
+/* Computer Science Department */
+/* Colorado State University */
+/* */
+/* Permission is hereby granted to copy all or any part of */
+/* this program for free distribution. The author's name */
+/* and this copyright notice must be included in any copy. */
+/* */
/*************************************************************/
#include "postgres.h"
@@ -52,16 +52,16 @@
/* geqo_copy--
*
- * copies one gene to another
+ * copies one gene to another
*
*/
void
-geqo_copy (Chromosome *chromo1, Chromosome *chromo2, int string_length)
+geqo_copy(Chromosome * chromo1, Chromosome * chromo2, int string_length)
{
- int i;
+ int i;
- for (i=0; i<string_length; i++)
- chromo1->string[i] = chromo2->string[i];
+ for (i = 0; i < string_length; i++)
+ chromo1->string[i] = chromo2->string[i];
- chromo1->worth = chromo2->worth;
+ chromo1->worth = chromo2->worth;
}
diff --git a/src/backend/optimizer/geqo/geqo_cx.c b/src/backend/optimizer/geqo/geqo_cx.c
index a3aa6fce4f4..dfde1bdc530 100644
--- a/src/backend/optimizer/geqo/geqo_cx.c
+++ b/src/backend/optimizer/geqo/geqo_cx.c
@@ -2,35 +2,35 @@
*
* geqo_cx.c--
*
-* cycle crossover [CX] routines;
-* CX operator according to Oliver et al
-* (Proc 2nd Int'l Conf on GA's)
+* cycle crossover [CX] routines;
+* CX operator according to Oliver et al
+* (Proc 2nd Int'l Conf on GA's)
*
-* $Id: geqo_cx.c,v 1.1 1997/02/19 12:56:48 scrappy Exp $
+* $Id: geqo_cx.c,v 1.2 1997/09/07 04:43:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* the cx algorithm is adopted from Genitor : */
/*************************************************************/
-/* */
-/* Copyright (c) 1990 */
-/* Darrell L. Whitley */
-/* Computer Science Department */
-/* Colorado State University */
-/* */
-/* Permission is hereby granted to copy all or any part of */
-/* this program for free distribution. The author's name */
-/* and this copyright notice must be included in any copy. */
-/* */
+/* */
+/* Copyright (c) 1990 */
+/* Darrell L. Whitley */
+/* Computer Science Department */
+/* Colorado State University */
+/* */
+/* Permission is hereby granted to copy all or any part of */
+/* this program for free distribution. The author's name */
+/* and this copyright notice must be included in any copy. */
+/* */
/*************************************************************/
@@ -57,73 +57,81 @@
/* cx--
*
- * cycle crossover
+ * cycle crossover
*/
int
-cx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
+cx(Gene * tour1, Gene * tour2, Gene * offspring, int num_gene, City * city_table)
{
- int i, start_pos, curr_pos;
- int count = 0;
- int num_diffs = 0;
+ int i,
+ start_pos,
+ curr_pos;
+ int count = 0;
+ int num_diffs = 0;
- /* initialize city table */
- for (i=1; i<=num_gene; i++) {
- city_table[i].used = 0;
- city_table[tour2[i-1]].tour2_position = i-1;
- city_table[tour1[i-1]].tour1_position = i-1;
- }
+ /* initialize city table */
+ for (i = 1; i <= num_gene; i++)
+ {
+ city_table[i].used = 0;
+ city_table[tour2[i - 1]].tour2_position = i - 1;
+ city_table[tour1[i - 1]].tour1_position = i - 1;
+ }
- /* choose random cycle starting position */
- start_pos = geqo_randint(num_gene - 1, 0);
+ /* choose random cycle starting position */
+ start_pos = geqo_randint(num_gene - 1, 0);
- /* child inherits first city */
- offspring[start_pos] = tour1[start_pos];
+ /* child inherits first city */
+ offspring[start_pos] = tour1[start_pos];
- /* begin cycle with tour1 */
- curr_pos = start_pos;
- city_table[(int) tour1[start_pos]].used = 1;
+ /* begin cycle with tour1 */
+ curr_pos = start_pos;
+ city_table[(int) tour1[start_pos]].used = 1;
- count++;
+ count++;
- /* cx main part */
+ /* cx main part */
/* STEP 1 */
- while (tour2[curr_pos] != tour1[start_pos]) {
- city_table[(int) tour2[curr_pos]].used = 1;
- curr_pos = city_table[(int) tour2[curr_pos]].tour1_position;
- offspring[curr_pos] = tour1[curr_pos];
- count++;
- }
+ while (tour2[curr_pos] != tour1[start_pos])
+ {
+ city_table[(int) tour2[curr_pos]].used = 1;
+ curr_pos = city_table[(int) tour2[curr_pos]].tour1_position;
+ offspring[curr_pos] = tour1[curr_pos];
+ count++;
+ }
/* STEP 2 */
- /* failed to create a complete tour */
- if (count < num_gene) {
- for (i=1; i<=num_gene; i++) {
- if (!city_table[i].used) {
- offspring[city_table[i].tour2_position] =
- tour2[(int) city_table[i].tour2_position];
- count++;
- }
- }
- }
+ /* failed to create a complete tour */
+ if (count < num_gene)
+ {
+ for (i = 1; i <= num_gene; i++)
+ {
+ if (!city_table[i].used)
+ {
+ offspring[city_table[i].tour2_position] =
+ tour2[(int) city_table[i].tour2_position];
+ count++;
+ }
+ }
+ }
/* STEP 3 */
- /* still failed to create a complete tour */
- if (count < num_gene) {
+ /* still failed to create a complete tour */
+ if (count < num_gene)
+ {
- /* count the number of differences between mom and offspring */
- for (i=0; i<num_gene; i++)
- if (tour1[i] != offspring[i]) num_diffs++;
+ /* count the number of differences between mom and offspring */
+ for (i = 0; i < num_gene; i++)
+ if (tour1[i] != offspring[i])
+ num_diffs++;
- }
-
- return(num_diffs);
- }
+ }
+ return (num_diffs);
+}
diff --git a/src/backend/optimizer/geqo/geqo_erx.c b/src/backend/optimizer/geqo/geqo_erx.c
index 8c3c63d755c..9d0f93efe8c 100644
--- a/src/backend/optimizer/geqo/geqo_erx.c
+++ b/src/backend/optimizer/geqo/geqo_erx.c
@@ -1,33 +1,33 @@
/*------------------------------------------------------------------------
*
* geqo_erx.c--
-* edge recombination crossover [ER]
+* edge recombination crossover [ER]
*
-* $Id: geqo_erx.c,v 1.2 1997/06/06 00:37:23 scrappy Exp $
+* $Id: geqo_erx.c,v 1.3 1997/09/07 04:43:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* the edge recombination algorithm is adopted from Genitor : */
/*************************************************************/
-/* */
-/* Copyright (c) 1990 */
-/* Darrell L. Whitley */
-/* Computer Science Department */
-/* Colorado State University */
-/* */
-/* Permission is hereby granted to copy all or any part of */
-/* this program for free distribution. The author's name */
-/* and this copyright notice must be included in any copy. */
-/* */
+/* */
+/* Copyright (c) 1990 */
+/* Darrell L. Whitley */
+/* Computer Science Department */
+/* Colorado State University */
+/* */
+/* Permission is hereby granted to copy all or any part of */
+/* this program for free distribution. The author's name */
+/* and this copyright notice must be included in any copy. */
+/* */
/*************************************************************/
@@ -52,384 +52,441 @@
#include "optimizer/geqo_random.h"
-static int gimme_edge (Gene gene1, Gene gene2, Edge *edge_table);
-static void remove_gene(Gene gene, Edge edge, Edge *edge_table);
-static Gene gimme_gene(Edge edge, Edge *edge_table);
+static int gimme_edge(Gene gene1, Gene gene2, Edge * edge_table);
+static void remove_gene(Gene gene, Edge edge, Edge * edge_table);
+static Gene gimme_gene(Edge edge, Edge * edge_table);
-static Gene edge_failure(Gene *gene, int index, Edge *edge_table, int num_gene);
+static Gene edge_failure(Gene * gene, int index, Edge * edge_table, int num_gene);
/* alloc_edge_table--
*
- * allocate memory for edge table
+ * allocate memory for edge table
*
*/
-Edge *
+Edge *
alloc_edge_table(int num_gene)
{
- Edge *edge_table;
+ Edge *edge_table;
- /* palloc one extra location so that nodes numbered
- 1..n can be indexed directly; 0 will not be used */
+ /*
+ * palloc one extra location so that nodes numbered 1..n can be
+ * indexed directly; 0 will not be used
+ */
- edge_table = (Edge *) palloc ((num_gene+1)*sizeof(Edge));
+ edge_table = (Edge *) palloc((num_gene + 1) * sizeof(Edge));
- return (edge_table);
- }
+ return (edge_table);
+}
/* free_edge_table--
*
- * deallocate memory of edge table
+ * deallocate memory of edge table
*
*/
- void
- free_edge_table(Edge *edge_table)
- {
- pfree(edge_table);
- }
+void
+free_edge_table(Edge * edge_table)
+{
+ pfree(edge_table);
+}
/* gimme_edge_table--
*
- * fills a data structure which represents the set of explicit
- * edges between points in the (2) input genes
+ * fills a data structure which represents the set of explicit
+ * edges between points in the (2) input genes
+ *
+ * assumes circular tours and bidirectional edges
*
- * assumes circular tours and bidirectional edges
- *
- * gimme_edge() will set "shared" edges to negative values
+ * gimme_edge() will set "shared" edges to negative values
*
- * returns average number edges/city in range 2.0 - 4.0
- * where 2.0=homogeneous; 4.0=diverse
+ * returns average number edges/city in range 2.0 - 4.0
+ * where 2.0=homogeneous; 4.0=diverse
*
*/
float
-gimme_edge_table (Gene *tour1, Gene *tour2, int num_gene, Edge *edge_table)
+gimme_edge_table(Gene * tour1, Gene * tour2, int num_gene, Edge * edge_table)
{
- int i, index1, index2;
- int edge_total; /* total number of unique edges in two genes */
-
- /* at first clear the edge table's old data */
- for (i = 1; i <= num_gene; i++) {
- edge_table[i].total_edges = 0;
- edge_table[i].unused_edges = 0;
+ int i,
+ index1,
+ index2;
+ int edge_total; /* total number of unique edges in two
+ * genes */
+
+ /* at first clear the edge table's old data */
+ for (i = 1; i <= num_gene; i++)
+ {
+ edge_table[i].total_edges = 0;
+ edge_table[i].unused_edges = 0;
}
- /* fill edge table with new data */
+ /* fill edge table with new data */
- edge_total = 0;
+ edge_total = 0;
- for (index1 = 0; index1 < num_gene; index1++) {
+ for (index1 = 0; index1 < num_gene; index1++)
+ {
- /* presume the tour is circular, i.e. 1->2, 2->3, 3->1
- this operaton maps n back to 1 */
+ /*
+ * presume the tour is circular, i.e. 1->2, 2->3, 3->1 this
+ * operaton maps n back to 1
+ */
- index2 = (index1 + 1) % num_gene;
+ index2 = (index1 + 1) % num_gene;
- /* edges are bidirectional, i.e. 1->2 is same as 2->1
- call gimme_edge twice per edge */
+ /*
+ * edges are bidirectional, i.e. 1->2 is same as 2->1 call
+ * gimme_edge twice per edge
+ */
- edge_total += gimme_edge(tour1[index1], tour1[index2], edge_table);
- gimme_edge(tour1[index2], tour1[index1], edge_table);
+ edge_total += gimme_edge(tour1[index1], tour1[index2], edge_table);
+ gimme_edge(tour1[index2], tour1[index1], edge_table);
- edge_total += gimme_edge(tour2[index1], tour2[index2], edge_table);
- gimme_edge(tour2[index2], tour2[index1], edge_table);
- }
+ edge_total += gimme_edge(tour2[index1], tour2[index2], edge_table);
+ gimme_edge(tour2[index2], tour2[index1], edge_table);
+ }
- /* return average number of edges per index */
- return (((float) (edge_total * 2)/ (float) num_gene));
+ /* return average number of edges per index */
+ return (((float) (edge_total * 2) / (float) num_gene));
}
/* gimme_edge--
*
- * registers edge from city1 to city2 in input edge table
+ * registers edge from city1 to city2 in input edge table
*
- * no assumptions about directionality are made;
- * therefor it is up to the calling routine to
- * call gimme_edge twice to make a bi-directional edge
- * between city1 and city2;
- * uni-directional edges are possible as well (just call gimme_edge
- * once with the direction from city1 to city2)
+ * no assumptions about directionality are made;
+ * therefor it is up to the calling routine to
+ * call gimme_edge twice to make a bi-directional edge
+ * between city1 and city2;
+ * uni-directional edges are possible as well (just call gimme_edge
+ * once with the direction from city1 to city2)
*
- * returns 1 if edge was not already registered and was just added;
- * 0 if edge was already registered and edge_table is unchanged
+ * returns 1 if edge was not already registered and was just added;
+ * 0 if edge was already registered and edge_table is unchanged
*/
static int
-gimme_edge (Gene gene1, Gene gene2, Edge *edge_table)
+gimme_edge(Gene gene1, Gene gene2, Edge * edge_table)
{
- int i;
- int edges;
- int city1 = (int) gene1;
- int city2 = (int) gene2;
+ int i;
+ int edges;
+ int city1 = (int) gene1;
+ int city2 = (int) gene2;
- /* check whether edge city1->city2 already exists */
- edges = edge_table[city1].total_edges;
+ /* check whether edge city1->city2 already exists */
+ edges = edge_table[city1].total_edges;
- for (i=0; i<edges; i++) {
- if ((Gene) Abs(edge_table[city1].edge_list[i]) == city2) {
+ for (i = 0; i < edges; i++)
+ {
+ if ((Gene) Abs(edge_table[city1].edge_list[i]) == city2)
+ {
- /* mark shared edges as negative */
- edge_table[city1].edge_list[i] = 0-city2;
+ /* mark shared edges as negative */
+ edge_table[city1].edge_list[i] = 0 - city2;
- return (0);
- }
- }
+ return (0);
+ }
+ }
- /* add city1->city2; */
- edge_table[city1].edge_list[edges] = city2;
+ /* add city1->city2; */
+ edge_table[city1].edge_list[edges] = city2;
- /* increment the number of edges from city1 */
- edge_table[city1].total_edges++;
- edge_table[city1].unused_edges++;
+ /* increment the number of edges from city1 */
+ edge_table[city1].total_edges++;
+ edge_table[city1].unused_edges++;
- return (1);
+ return (1);
}
/* gimme_tour--
*
- * creates a new tour using edges from the edge table.
- * priority is given to "shared" edges (i.e. edges which
- * all parent genes possess and are marked as negative
- * in the edge table.)
+ * creates a new tour using edges from the edge table.
+ * priority is given to "shared" edges (i.e. edges which
+ * all parent genes possess and are marked as negative
+ * in the edge table.)
*
*/
int
-gimme_tour (Edge *edge_table, Gene *new_gene, int num_gene)
+gimme_tour(Edge * edge_table, Gene * new_gene, int num_gene)
{
- int i;
- int edge_failures=0;
+ int i;
+ int edge_failures = 0;
- new_gene[0] = (Gene) geqo_randint(num_gene, 1); /* choose int between 1 and num_gene */
+ new_gene[0] = (Gene) geqo_randint(num_gene, 1); /* choose int between 1
+ * and num_gene */
- for (i=1; i<num_gene; i++) {
-
- /* as each point is entered into the tour,
- remove it from the edge table */
+ for (i = 1; i < num_gene; i++)
+ {
- remove_gene(new_gene[i-1], edge_table[(int) new_gene[i-1]], edge_table);
-
- /* find destination for the newly entered point */
+ /*
+ * as each point is entered into the tour, remove it from the edge
+ * table
+ */
- if (edge_table[new_gene[i-1]].unused_edges > 0) {
- new_gene[i] = gimme_gene(edge_table[(int) new_gene[i-1]], edge_table);
- }
+ remove_gene(new_gene[i - 1], edge_table[(int) new_gene[i - 1]], edge_table);
- else { /* cope with fault */
- edge_failures++;
+ /* find destination for the newly entered point */
- new_gene[i] = edge_failure(new_gene, i-1, edge_table, num_gene);
- }
+ if (edge_table[new_gene[i - 1]].unused_edges > 0)
+ {
+ new_gene[i] = gimme_gene(edge_table[(int) new_gene[i - 1]], edge_table);
+ }
- /* mark this node as incorporated */
- edge_table[(int) new_gene[i-1]].unused_edges = -1;
+ else
+ { /* cope with fault */
+ edge_failures++;
- } /* for (i=1; i<num_gene; i++) */
+ new_gene[i] = edge_failure(new_gene, i - 1, edge_table, num_gene);
+ }
-return(edge_failures);
+ /* mark this node as incorporated */
+ edge_table[(int) new_gene[i - 1]].unused_edges = -1;
+
+ } /* for (i=1; i<num_gene; i++) */
+
+ return (edge_failures);
}
/* remove_gene--
*
- * removes input gene from edge_table.
- * input edge is used
- * to identify deletion locations within edge table.
+ * removes input gene from edge_table.
+ * input edge is used
+ * to identify deletion locations within edge table.
*
*/
static void
-remove_gene (Gene gene, Edge edge, Edge *edge_table)
+remove_gene(Gene gene, Edge edge, Edge * edge_table)
{
- int i,j;
- int possess_edge;
- int genes_remaining;
+ int i,
+ j;
+ int possess_edge;
+ int genes_remaining;
- /* do for every gene known to have an edge to input gene
- (i.e. in edge_list for input edge) */
+ /*
+ * do for every gene known to have an edge to input gene (i.e. in
+ * edge_list for input edge)
+ */
- for (i=0; i<edge.unused_edges; i++) {
- possess_edge = (int) Abs(edge.edge_list[i]);
- genes_remaining = edge_table[possess_edge].unused_edges;
+ for (i = 0; i < edge.unused_edges; i++)
+ {
+ possess_edge = (int) Abs(edge.edge_list[i]);
+ genes_remaining = edge_table[possess_edge].unused_edges;
- /* find the input gene in all edge_lists and delete it */
- for (j=0; j<genes_remaining; j++) {
+ /* find the input gene in all edge_lists and delete it */
+ for (j = 0; j < genes_remaining; j++)
+ {
- if ( (Gene) Abs(edge_table[possess_edge].edge_list[j]) == gene) {
+ if ((Gene) Abs(edge_table[possess_edge].edge_list[j]) == gene)
+ {
- edge_table[possess_edge].unused_edges--;
+ edge_table[possess_edge].unused_edges--;
- edge_table[possess_edge].edge_list[j] =
- edge_table[possess_edge].edge_list[genes_remaining-1];
+ edge_table[possess_edge].edge_list[j] =
+ edge_table[possess_edge].edge_list[genes_remaining - 1];
- break;
- }
+ break;
+ }
}
- }
+ }
}
/* gimme_gene--
*
- * priority is given to "shared" edges
- * (i.e. edges which both genes possess)
+ * priority is given to "shared" edges
+ * (i.e. edges which both genes possess)
*
*/
-static Gene
-gimme_gene (Edge edge, Edge *edge_table)
+static Gene
+gimme_gene(Edge edge, Edge * edge_table)
{
- int i;
- Gene friend;
- int minimum_edges;
- int minimum_count = -1;
- int rand_decision;
-
- /* no point has edges to more than 4 other points
- thus, this contrived minimum will be replaced */
-
- minimum_edges = 5;
-
- /* consider candidate destination points in edge list */
-
- for (i=0; i<edge.unused_edges; i++) {
- friend = (Gene) edge.edge_list[i];
-
- /* give priority to shared edges that are negative;
- so return 'em */
-
- /* negative values are caught here
- so we need not worry about converting to absolute values */
- if (friend < 0) return ( (Gene) Abs(friend));
-
-
- /* give priority to candidates with fewest remaining unused edges;
- find out what the minimum number of unused edges is (minimum_edges);
- if there is more than one cadidate with the minimum number
- of unused edges keep count of this number (minimum_count); */
-
- /* The test for minimum_count can probably be removed at some
- point but comments should probably indicate exactly why it
- is guaranteed that the test will always succeed the first
- time around. If it can fail then the code is in error */
-
-
- if (edge_table[(int) friend].unused_edges < minimum_edges) {
- minimum_edges = edge_table[(int) friend].unused_edges;
- minimum_count = 1;
+ int i;
+ Gene friend;
+ int minimum_edges;
+ int minimum_count = -1;
+ int rand_decision;
+
+ /*
+ * no point has edges to more than 4 other points thus, this contrived
+ * minimum will be replaced
+ */
+
+ minimum_edges = 5;
+
+ /* consider candidate destination points in edge list */
+
+ for (i = 0; i < edge.unused_edges; i++)
+ {
+ friend = (Gene) edge.edge_list[i];
+
+ /*
+ * give priority to shared edges that are negative; so return 'em
+ */
+
+ /*
+ * negative values are caught here so we need not worry about
+ * converting to absolute values
+ */
+ if (friend < 0)
+ return ((Gene) Abs(friend));
+
+
+ /*
+ * give priority to candidates with fewest remaining unused edges;
+ * find out what the minimum number of unused edges is
+ * (minimum_edges); if there is more than one cadidate with the
+ * minimum number of unused edges keep count of this number
+ * (minimum_count);
+ */
+
+ /*
+ * The test for minimum_count can probably be removed at some
+ * point but comments should probably indicate exactly why it is
+ * guaranteed that the test will always succeed the first time
+ * around. If it can fail then the code is in error
+ */
+
+
+ if (edge_table[(int) friend].unused_edges < minimum_edges)
+ {
+ minimum_edges = edge_table[(int) friend].unused_edges;
+ minimum_count = 1;
}
- else
- if (minimum_count == -1)
- elog(WARN, "gimme_gene: Internal error - minimum_count not set");
- else
- if (edge_table[(int) friend].unused_edges == minimum_edges)
- minimum_count++;
+ else if (minimum_count == -1)
+ elog(WARN, "gimme_gene: Internal error - minimum_count not set");
+ else if (edge_table[(int) friend].unused_edges == minimum_edges)
+ minimum_count++;
+
+ } /* for (i=0; i<edge.unused_edges; i++) */
- } /* for (i=0; i<edge.unused_edges; i++) */
-
- /* random decision of the possible candidates to use */
- rand_decision = (int) geqo_randint(minimum_count-1, 0);
+ /* random decision of the possible candidates to use */
+ rand_decision = (int) geqo_randint(minimum_count - 1, 0);
-
- for (i=0; i<edge.unused_edges; i++) {
- friend = (Gene) edge.edge_list[i];
- /* return the chosen candidate point */
- if (edge_table[(int) friend].unused_edges == minimum_edges) {
- minimum_count--;
+ for (i = 0; i < edge.unused_edges; i++)
+ {
+ friend = (Gene) edge.edge_list[i];
- if ( minimum_count == rand_decision ) return (friend);
+ /* return the chosen candidate point */
+ if (edge_table[(int) friend].unused_edges == minimum_edges)
+ {
+ minimum_count--;
+
+ if (minimum_count == rand_decision)
+ return (friend);
}
}
- /* ... should never be reached */
- elog(WARN,"gimme_gene: neither shared nor minimum number nor random edge found");
- return 0; /* to keep the compiler quiet */
+ /* ... should never be reached */
+ elog(WARN, "gimme_gene: neither shared nor minimum number nor random edge found");
+ return 0; /* to keep the compiler quiet */
}
/* edge_failure--
*
- * routine for handling edge failure
+ * routine for handling edge failure
*
*/
-static Gene
-edge_failure (Gene *gene, int index, Edge *edge_table, int num_gene)
+static Gene
+edge_failure(Gene * gene, int index, Edge * edge_table, int num_gene)
{
- int i;
- Gene fail_gene = gene[index];
- int remaining_edges = 0;
- int four_count = 0;
- int rand_decision;
-
-
- /* how many edges remain?
- how many gene with four total (initial) edges remain? */
-
- for (i=1; i<=num_gene; i++) {
- if ( (edge_table[i].unused_edges != -1) && (i != (int) fail_gene) ) {
- remaining_edges++;
-
- if (edge_table[i].total_edges == 4) four_count++;
- }
- }
+ int i;
+ Gene fail_gene = gene[index];
+ int remaining_edges = 0;
+ int four_count = 0;
+ int rand_decision;
+
+
+ /*
+ * how many edges remain? how many gene with four total (initial)
+ * edges remain?
+ */
+
+ for (i = 1; i <= num_gene; i++)
+ {
+ if ((edge_table[i].unused_edges != -1) && (i != (int) fail_gene))
+ {
+ remaining_edges++;
+
+ if (edge_table[i].total_edges == 4)
+ four_count++;
+ }
+ }
- /* random decision of the gene
- with remaining edges and whose total_edges == 4 */
+ /*
+ * random decision of the gene with remaining edges and whose
+ * total_edges == 4
+ */
- if (four_count != 0 ) {
+ if (four_count != 0)
+ {
- rand_decision = (int) geqo_randint(four_count-1, 0);
+ rand_decision = (int) geqo_randint(four_count - 1, 0);
- for (i=1; i<=num_gene; i++) {
+ for (i = 1; i <= num_gene; i++)
+ {
- if ((Gene) i != fail_gene &&
+ if ((Gene) i != fail_gene &&
edge_table[i].unused_edges != -1 &&
- edge_table[i].total_edges==4) {
+ edge_table[i].total_edges == 4)
+ {
four_count--;
- if (rand_decision == four_count) return ((Gene) i);
- }
+ if (rand_decision == four_count)
+ return ((Gene) i);
}
+ }
- elog(DEBUG,"edge_failure(1): no edge found via random decision and total_edges == 4");
+ elog(DEBUG, "edge_failure(1): no edge found via random decision and total_edges == 4");
}
- else /* random decision of the gene with remaining edges */
+ else
+/* random decision of the gene with remaining edges */
- if (remaining_edges != 0) {
+ if (remaining_edges != 0)
+ {
- rand_decision = (int) geqo_randint(remaining_edges-1, 0);
+ rand_decision = (int) geqo_randint(remaining_edges - 1, 0);
- for (i=1; i<=num_gene; i++) {
+ for (i = 1; i <= num_gene; i++)
+ {
- if ((Gene) i != fail_gene &&
- edge_table[i].unused_edges != -1) {
+ if ((Gene) i != fail_gene &&
+ edge_table[i].unused_edges != -1)
+ {
remaining_edges--;
- if (rand_decision == remaining_edges) return (i);
- }
+ if (rand_decision == remaining_edges)
+ return (i);
}
-
- elog(DEBUG,"edge_failure(2): no edge found via random decision and remainig edges");
}
- /* edge table seems to be empty; this happens sometimes on
- the last point due to the fact that the first point is
- removed from the table even though only one of its edges
- has been determined */
+ elog(DEBUG, "edge_failure(2): no edge found via random decision and remainig edges");
+ }
- else { /* occurs only at the last point in the tour;
- simply look for the point which is not yet used */
+ /*
+ * edge table seems to be empty; this happens sometimes on the last
+ * point due to the fact that the first point is removed from the
+ * table even though only one of its edges has been determined
+ */
- for (i=1; i<=num_gene; i++)
- if (edge_table[i].unused_edges >= 0)
- return ((Gene) i);
-
- elog(DEBUG,"edge_failure(3): no edge found via looking for the last ununsed point");
+ else
+ { /* occurs only at the last point in the
+ * tour; simply look for the point which
+ * is not yet used */
+
+ for (i = 1; i <= num_gene; i++)
+ if (edge_table[i].unused_edges >= 0)
+ return ((Gene) i);
+
+ elog(DEBUG, "edge_failure(3): no edge found via looking for the last ununsed point");
}
/* ... should never be reached */
- elog(WARN,"edge_failure: no edge detected");
- return 0; /* to keep the compiler quiet */
+ elog(WARN, "edge_failure: no edge detected");
+ return 0; /* to keep the compiler quiet */
}
-
diff --git a/src/backend/optimizer/geqo/geqo_eval.c b/src/backend/optimizer/geqo/geqo_eval.c
index 7ec449f2e94..ba34d8f3e02 100644
--- a/src/backend/optimizer/geqo/geqo_eval.c
+++ b/src/backend/optimizer/geqo/geqo_eval.c
@@ -1,20 +1,20 @@
/*------------------------------------------------------------------------
*
* geqo_eval.c--
- * Routines to evaluate query trees
+ * Routines to evaluate query trees
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_eval.c,v 1.12 1997/08/12 22:53:07 momjian Exp $
+ * $Id: geqo_eval.c,v 1.13 1997/09/07 04:43:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
@@ -22,13 +22,13 @@
#include <math.h>
#ifdef HAVE_LIMITS_H
-# include <limits.h>
-# ifndef MAXINT
-# define MAXINT INT_MAX
-# endif
+#include <limits.h>
+#ifndef MAXINT
+#define MAXINT INT_MAX
+#endif
#else
-# include <values.h>
-#endif
+#include <values.h>
+#endif
#include "nodes/pg_list.h"
#include "nodes/relation.h"
@@ -50,548 +50,598 @@
#include "optimizer/geqo_paths.h"
-static List *gimme_clause_joins(Query *root, Rel *outer_rel, Rel *inner_rel);
-static Rel *gimme_clauseless_join(Rel *outer_rel, Rel *inner_rel);
-static Rel *init_join_rel(Rel *outer_rel, Rel *inner_rel, JInfo *joininfo);
-static List *new_join_tlist(List *tlist, List *other_relids, int first_resdomno);
-static List *new_joininfo_list(List *joininfo_list, List *join_relids);
-static void geqo_joinrel_size(Rel *joinrel, Rel *outer_rel, Rel *inner_rel);
-static Rel *geqo_nth(int stop, List *rels);
+static List *gimme_clause_joins(Query * root, Rel * outer_rel, Rel * inner_rel);
+static Rel *gimme_clauseless_join(Rel * outer_rel, Rel * inner_rel);
+static Rel *init_join_rel(Rel * outer_rel, Rel * inner_rel, JInfo * joininfo);
+static List *new_join_tlist(List * tlist, List * other_relids, int first_resdomno);
+static List *new_joininfo_list(List * joininfo_list, List * join_relids);
+static void geqo_joinrel_size(Rel * joinrel, Rel * outer_rel, Rel * inner_rel);
+static Rel *geqo_nth(int stop, List * rels);
-/*
+/*
* geqo_eval--
- *
+ *
* Returns cost of a query tree as an individual of the population.
*/
Cost
-geqo_eval (Query *root, Gene *tour, int num_gene)
+geqo_eval(Query * root, Gene * tour, int num_gene)
{
- Rel *joinrel;
- Cost fitness;
- List *temp;
+ Rel *joinrel;
+ Cost fitness;
+ List *temp;
/* remember root->join_relation_list_ ... */
/* because root->join_relation_list_ will be changed during the following */
- temp = listCopy(root->join_relation_list_);
+ temp = listCopy(root->join_relation_list_);
/* joinrel is readily processed query tree -- left-sided ! */
- joinrel = gimme_tree(root, tour, 0, num_gene, NULL);
+ joinrel = gimme_tree(root, tour, 0, num_gene, NULL);
/* compute fitness */
- fitness = (Cost) joinrel->cheapestpath->path_cost;
+ fitness = (Cost) joinrel->cheapestpath->path_cost;
- root->join_relation_list_ = listCopy(temp);
+ root->join_relation_list_ = listCopy(temp);
- pfree(joinrel);
- freeList(temp);
+ pfree(joinrel);
+ freeList(temp);
- return(fitness);
+ return (fitness);
}
-/*
+/*
* gimme-tree --
- * this program presumes that only LEFT-SIDED TREES are considered!
- *
+ * this program presumes that only LEFT-SIDED TREES are considered!
+ *
* 'outer_rel' is the preceeding join
- *
+ *
* Returns a new join relation incorporating all joins in a left-sided tree.
*/
-Rel *
-gimme_tree (Query *root, Gene *tour, int rel_count, int num_gene, Rel *outer_rel)
+Rel *
+gimme_tree(Query * root, Gene * tour, int rel_count, int num_gene, Rel * outer_rel)
{
- Rel *inner_rel; /* current relation */
- int base_rel_index;
+ Rel *inner_rel; /* current relation */
+ int base_rel_index;
- List *new_rels = NIL;
- Rel *new_rel = NULL;
+ List *new_rels = NIL;
+ Rel *new_rel = NULL;
- if (rel_count < num_gene ) { /* tree not yet finished */
+ if (rel_count < num_gene)
+ { /* tree not yet finished */
- /* tour[0] = 3; tour[1] = 1; tour[2] = 2 */
- base_rel_index = (int) tour[rel_count];
+ /* tour[0] = 3; tour[1] = 1; tour[2] = 2 */
+ base_rel_index = (int) tour[rel_count];
- inner_rel = (Rel *) geqo_nth(base_rel_index,root->base_relation_list_);
+ inner_rel = (Rel *) geqo_nth(base_rel_index, root->base_relation_list_);
- if (rel_count == 0) { /* processing first join with base_rel_index = (int) tour[0] */
- rel_count++;
- return gimme_tree(root, tour, rel_count, num_gene, inner_rel);
+ if (rel_count == 0)
+ { /* processing first join with
+ * base_rel_index = (int) tour[0] */
+ rel_count++;
+ return gimme_tree(root, tour, rel_count, num_gene, inner_rel);
}
- else { /* tree main part */
-
- if(!(new_rels = gimme_clause_joins(root, outer_rel,inner_rel))) {
- if (BushyPlanFlag) {
- new_rels = lcons(gimme_clauseless_join(outer_rel,outer_rel),NIL); /* ??? MAU */
+ else
+ { /* tree main part */
+
+ if (!(new_rels = gimme_clause_joins(root, outer_rel, inner_rel)))
+ {
+ if (BushyPlanFlag)
+ {
+ new_rels = lcons(gimme_clauseless_join(outer_rel, outer_rel), NIL); /* ??? MAU */
}
- else {
- new_rels = lcons(gimme_clauseless_join(outer_rel,inner_rel),NIL);
+ else
+ {
+ new_rels = lcons(gimme_clauseless_join(outer_rel, inner_rel), NIL);
}
}
- /* process new_rel->pathlist */
- find_all_join_paths(root, new_rels);
+ /* process new_rel->pathlist */
+ find_all_join_paths(root, new_rels);
- /* prune new_rels */
- /* MAU: is this necessary? */
- /* what's the matter if more than one new rel is left till now? */
- /* joinrels in newrels with different ordering of relids are not possible */
- if (length(new_rels) > 1) new_rels = geqo_prune_rels(new_rels);
+ /* prune new_rels */
+ /* MAU: is this necessary? */
- if (length(new_rels) > 1) { /* should never be reached ... */
- elog(DEBUG,"gimme_tree: still %d relations left", length(new_rels));
+ /*
+ * what's the matter if more than one new rel is left till
+ * now?
+ */
+
+ /*
+ * joinrels in newrels with different ordering of relids are
+ * not possible
+ */
+ if (length(new_rels) > 1)
+ new_rels = geqo_prune_rels(new_rels);
+
+ if (length(new_rels) > 1)
+ { /* should never be reached ... */
+ elog(DEBUG, "gimme_tree: still %d relations left", length(new_rels));
}
- /* get essential new relation */
- new_rel = (Rel *) lfirst(new_rels);
- rel_count++;
+ /* get essential new relation */
+ new_rel = (Rel *) lfirst(new_rels);
+ rel_count++;
- /* process new_rel->cheapestpath, new_rel->unorderedpath */
- geqo_rel_paths(new_rel);
+ /* process new_rel->cheapestpath, new_rel->unorderedpath */
+ geqo_rel_paths(new_rel);
- /* processing of other new_rel attributes */
- if ( new_rel->size <= 0 )
- new_rel->size = compute_rel_size(new_rel);
- new_rel->width = compute_rel_width(new_rel);
+ /* processing of other new_rel attributes */
+ if (new_rel->size <= 0)
+ new_rel->size = compute_rel_size(new_rel);
+ new_rel->width = compute_rel_width(new_rel);
- root->join_relation_list_ = lcons(new_rel, NIL);
+ root->join_relation_list_ = lcons(new_rel, NIL);
- return gimme_tree(root, tour, rel_count, num_gene, new_rel);
+ return gimme_tree(root, tour, rel_count, num_gene, new_rel);
}
}
- return (outer_rel); /* tree finished ... */
+ return (outer_rel); /* tree finished ... */
}
-/*
+/*
* gimme-clause-joins--
*
* 'outer-rel' is the relation entry for the outer relation
* 'inner-rel' is the relation entry for the inner relation
- *
+ *
* Returns a list of new join relations.
*/
-static List *
-gimme_clause_joins(Query *root, Rel *outer_rel, Rel *inner_rel)
+static List *
+gimme_clause_joins(Query * root, Rel * outer_rel, Rel * inner_rel)
{
- List *join_list = NIL;
- List *i = NIL;
- List *joininfo_list = (List *) outer_rel->joininfo;
-
- foreach (i, joininfo_list) {
- JInfo *joininfo = (JInfo*)lfirst(i);
- Rel *rel = NULL;
-
- if(!joininfo->inactive) {
- List *other_rels = (List *)joininfo->otherrels;
-
- if(other_rels != NIL) {
- if( (length(other_rels) == 1) ) {
-
- if( same(other_rels, inner_rel->relids) ) { /* look if inner_rel is it...*/
- rel = init_join_rel(outer_rel, inner_rel, joininfo);
+ List *join_list = NIL;
+ List *i = NIL;
+ List *joininfo_list = (List *) outer_rel->joininfo;
+
+ foreach(i, joininfo_list)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(i);
+ Rel *rel = NULL;
+
+ if (!joininfo->inactive)
+ {
+ List *other_rels = (List *) joininfo->otherrels;
+
+ if (other_rels != NIL)
+ {
+ if ((length(other_rels) == 1))
+ {
+
+ if (same(other_rels, inner_rel->relids))
+ { /* look if inner_rel is it... */
+ rel = init_join_rel(outer_rel, inner_rel, joininfo);
}
}
- else if (BushyPlanFlag) { /* ?!? MAU */
- rel = init_join_rel(outer_rel, get_join_rel(root, other_rels), joininfo);
- }
- else {
- rel = NULL;
- }
+ else if (BushyPlanFlag)
+ { /* ?!? MAU */
+ rel = init_join_rel(outer_rel, get_join_rel(root, other_rels), joininfo);
+ }
+ else
+ {
+ rel = NULL;
+ }
- if (rel != NULL)
- join_list = lappend(join_list, rel);
+ if (rel != NULL)
+ join_list = lappend(join_list, rel);
}
}
}
- return(join_list);
+ return (join_list);
}
-/*
+/*
* gimme-clauseless-join--
- * Given an outer relation 'outer-rel' and an inner relation
- * 'inner-rel', create a join relation between 'outer-rel' and 'inner-rel'
- *
+ * Given an outer relation 'outer-rel' and an inner relation
+ * 'inner-rel', create a join relation between 'outer-rel' and 'inner-rel'
+ *
* Returns a new join relation.
*/
-static Rel *
-gimme_clauseless_join(Rel *outer_rel, Rel *inner_rel)
+static Rel *
+gimme_clauseless_join(Rel * outer_rel, Rel * inner_rel)
{
- return(init_join_rel(outer_rel, inner_rel, (JInfo*)NULL));
+ return (init_join_rel(outer_rel, inner_rel, (JInfo *) NULL));
}
-/*
+/*
* init-join-rel--
- * Creates and initializes a new join relation.
- *
+ * Creates and initializes a new join relation.
+ *
* 'outer-rel' and 'inner-rel' are relation nodes for the relations to be
- * joined
+ * joined
* 'joininfo' is the joininfo node(join clause) containing both
- * 'outer-rel' and 'inner-rel', if any exists
- *
+ * 'outer-rel' and 'inner-rel', if any exists
+ *
* Returns the new join relation node.
*/
-static Rel *
-init_join_rel(Rel *outer_rel, Rel *inner_rel, JInfo *joininfo)
+static Rel *
+init_join_rel(Rel * outer_rel, Rel * inner_rel, JInfo * joininfo)
{
- Rel *joinrel = makeNode(Rel);
- List *joinrel_joininfo_list = NIL;
- List *new_outer_tlist;
- List *new_inner_tlist;
-
- /*
- * Create a new tlist by removing irrelevant elements from both
- * tlists of the outer and inner join relations and then merging
- * the results together.
- */
- new_outer_tlist =
- new_join_tlist(outer_rel->targetlist, /* XXX 1-based attnos */
- inner_rel->relids, 1);
- new_inner_tlist =
- new_join_tlist(inner_rel->targetlist, /* XXX 1-based attnos */
- outer_rel->relids,
- length(new_outer_tlist) + 1);
-
- joinrel->relids = NIL;
- joinrel->indexed = false;
- joinrel->pages = 0;
- joinrel->tuples = 0;
- joinrel->width = 0;
-/* joinrel->targetlist = NIL;*/
- joinrel->pathlist = NIL;
- joinrel->unorderedpath = (Path *)NULL;
- joinrel->cheapestpath = (Path *)NULL;
- joinrel->pruneable = true;
- joinrel->classlist = NULL;
- joinrel->relam = InvalidOid;
- joinrel->ordering = NULL;
- joinrel->clauseinfo = NIL;
- joinrel->joininfo = NULL;
- joinrel->innerjoin = NIL;
- joinrel->superrels = NIL;
-
- joinrel->relids = lcons(outer_rel->relids, lcons(inner_rel->relids, NIL));
-
- new_outer_tlist = nconc(new_outer_tlist,new_inner_tlist);
- joinrel->targetlist = new_outer_tlist;
-
- if (joininfo) {
- joinrel->clauseinfo = joininfo->jinfoclauseinfo;
- if (BushyPlanFlag) joininfo->inactive = true;
- }
-
- joinrel_joininfo_list =
- new_joininfo_list(append(outer_rel->joininfo, inner_rel->joininfo),
- intAppend(outer_rel->relids, inner_rel->relids));
-
- joinrel->joininfo = joinrel_joininfo_list;
-
- geqo_joinrel_size(joinrel, outer_rel, inner_rel);
-
- return(joinrel);
+ Rel *joinrel = makeNode(Rel);
+ List *joinrel_joininfo_list = NIL;
+ List *new_outer_tlist;
+ List *new_inner_tlist;
+
+ /*
+ * Create a new tlist by removing irrelevant elements from both tlists
+ * of the outer and inner join relations and then merging the results
+ * together.
+ */
+ new_outer_tlist =
+ new_join_tlist(outer_rel->targetlist, /* XXX 1-based attnos */
+ inner_rel->relids, 1);
+ new_inner_tlist =
+ new_join_tlist(inner_rel->targetlist, /* XXX 1-based attnos */
+ outer_rel->relids,
+ length(new_outer_tlist) + 1);
+
+ joinrel->relids = NIL;
+ joinrel->indexed = false;
+ joinrel->pages = 0;
+ joinrel->tuples = 0;
+ joinrel->width = 0;
+/* joinrel->targetlist = NIL;*/
+ joinrel->pathlist = NIL;
+ joinrel->unorderedpath = (Path *) NULL;
+ joinrel->cheapestpath = (Path *) NULL;
+ joinrel->pruneable = true;
+ joinrel->classlist = NULL;
+ joinrel->relam = InvalidOid;
+ joinrel->ordering = NULL;
+ joinrel->clauseinfo = NIL;
+ joinrel->joininfo = NULL;
+ joinrel->innerjoin = NIL;
+ joinrel->superrels = NIL;
+
+ joinrel->relids = lcons(outer_rel->relids, lcons(inner_rel->relids, NIL));
+
+ new_outer_tlist = nconc(new_outer_tlist, new_inner_tlist);
+ joinrel->targetlist = new_outer_tlist;
+
+ if (joininfo)
+ {
+ joinrel->clauseinfo = joininfo->jinfoclauseinfo;
+ if (BushyPlanFlag)
+ joininfo->inactive = true;
+ }
+
+ joinrel_joininfo_list =
+ new_joininfo_list(append(outer_rel->joininfo, inner_rel->joininfo),
+ intAppend(outer_rel->relids, inner_rel->relids));
+
+ joinrel->joininfo = joinrel_joininfo_list;
+
+ geqo_joinrel_size(joinrel, outer_rel, inner_rel);
+
+ return (joinrel);
}
-/*
+/*
* new-join-tlist--
- * Builds a join relations's target list by keeping those elements that
- * will be in the final target list and any other elements that are still
- * needed for future joins. For a target list entry to still be needed
- * for future joins, its 'joinlist' field must not be empty after removal
- * of all relids in 'other-relids'.
- *
+ * Builds a join relations's target list by keeping those elements that
+ * will be in the final target list and any other elements that are still
+ * needed for future joins. For a target list entry to still be needed
+ * for future joins, its 'joinlist' field must not be empty after removal
+ * of all relids in 'other-relids'.
+ *
* 'tlist' is the target list of one of the join relations
* 'other-relids' is a list of relids contained within the other
- * join relation
+ * join relation
* 'first-resdomno' is the resdom number to use for the first created
- * target list entry
- *
+ * target list entry
+ *
* Returns the new target list.
*/
-static List *
-new_join_tlist(List *tlist,
- List *other_relids,
- int first_resdomno)
+static List *
+new_join_tlist(List * tlist,
+ List * other_relids,
+ int first_resdomno)
{
- int resdomno = first_resdomno - 1;
- TargetEntry *xtl = NULL;
- List *temp_node = NIL;
- List *t_list = NIL;
- List *i = NIL;
- List *join_list = NIL;
- bool in_final_tlist =false;
-
-
- foreach(i,tlist) {
- xtl= lfirst(i);
- in_final_tlist = (join_list==NIL);
- if( in_final_tlist) {
- resdomno += 1;
- temp_node =
- lcons(create_tl_element(get_expr(xtl),
- resdomno),
- NIL);
- t_list = nconc(t_list,temp_node);
- }
- }
-
- return(t_list);
+ int resdomno = first_resdomno - 1;
+ TargetEntry *xtl = NULL;
+ List *temp_node = NIL;
+ List *t_list = NIL;
+ List *i = NIL;
+ List *join_list = NIL;
+ bool in_final_tlist = false;
+
+
+ foreach(i, tlist)
+ {
+ xtl = lfirst(i);
+ in_final_tlist = (join_list == NIL);
+ if (in_final_tlist)
+ {
+ resdomno += 1;
+ temp_node =
+ lcons(create_tl_element(get_expr(xtl),
+ resdomno),
+ NIL);
+ t_list = nconc(t_list, temp_node);
+ }
+ }
+
+ return (t_list);
}
-/*
+/*
* new-joininfo-list--
- * Builds a join relation's joininfo list by checking for join clauses
- * which still need to used in future joins involving this relation. A
- * join clause is still needed if there are still relations in the clause
- * not contained in the list of relations comprising this join relation.
- * New joininfo nodes are only created and added to
- * 'current-joininfo-list' if a node for a particular join hasn't already
- * been created.
+ * Builds a join relation's joininfo list by checking for join clauses
+ * which still need to used in future joins involving this relation. A
+ * join clause is still needed if there are still relations in the clause
+ * not contained in the list of relations comprising this join relation.
+ * New joininfo nodes are only created and added to
+ * 'current-joininfo-list' if a node for a particular join hasn't already
+ * been created.
*
- * 'current-joininfo-list' contains a list of those joininfo nodes that
- * have already been built
+ * 'current-joininfo-list' contains a list of those joininfo nodes that
+ * have already been built
* 'joininfo-list' is the list of join clauses involving this relation
- * 'join-relids' is a list of relids corresponding to the relations
- * currently being joined
- *
+ * 'join-relids' is a list of relids corresponding to the relations
+ * currently being joined
+ *
* Returns a list of joininfo nodes, new and old.
*/
-static List *
-new_joininfo_list(List *joininfo_list, List *join_relids)
+static List *
+new_joininfo_list(List * joininfo_list, List * join_relids)
{
- List *current_joininfo_list = NIL;
- List *new_otherrels = NIL;
- JInfo *other_joininfo = (JInfo*)NULL;
- List *xjoininfo = NIL;
-
- foreach (xjoininfo, joininfo_list) {
- List *or;
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
-
- new_otherrels = joininfo->otherrels;
- foreach (or, new_otherrels)
- {
- if ( intMember (lfirsti(or), join_relids) )
- new_otherrels = lremove ((void*)lfirst(or), new_otherrels);
- }
- joininfo->otherrels = new_otherrels;
- if ( new_otherrels != NIL )
+ List *current_joininfo_list = NIL;
+ List *new_otherrels = NIL;
+ JInfo *other_joininfo = (JInfo *) NULL;
+ List *xjoininfo = NIL;
+
+ foreach(xjoininfo, joininfo_list)
{
- other_joininfo = joininfo_member(new_otherrels,
- current_joininfo_list);
- if(other_joininfo) {
- other_joininfo->jinfoclauseinfo =
- (List*)LispUnion(joininfo->jinfoclauseinfo,
- other_joininfo->jinfoclauseinfo);
- }else {
- other_joininfo = makeNode(JInfo);
-
- other_joininfo->otherrels =
- joininfo->otherrels;
- other_joininfo->jinfoclauseinfo =
- joininfo->jinfoclauseinfo;
- other_joininfo->mergesortable =
- joininfo->mergesortable;
- other_joininfo->hashjoinable =
- joininfo->hashjoinable;
- other_joininfo->inactive = false;
-
- current_joininfo_list = lcons(other_joininfo,
- current_joininfo_list);
- }
+ List *or;
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+
+ new_otherrels = joininfo->otherrels;
+ foreach(or, new_otherrels)
+ {
+ if (intMember(lfirsti(or), join_relids))
+ new_otherrels = lremove((void *) lfirst(or), new_otherrels);
+ }
+ joininfo->otherrels = new_otherrels;
+ if (new_otherrels != NIL)
+ {
+ other_joininfo = joininfo_member(new_otherrels,
+ current_joininfo_list);
+ if (other_joininfo)
+ {
+ other_joininfo->jinfoclauseinfo =
+ (List *) LispUnion(joininfo->jinfoclauseinfo,
+ other_joininfo->jinfoclauseinfo);
+ }
+ else
+ {
+ other_joininfo = makeNode(JInfo);
+
+ other_joininfo->otherrels =
+ joininfo->otherrels;
+ other_joininfo->jinfoclauseinfo =
+ joininfo->jinfoclauseinfo;
+ other_joininfo->mergesortable =
+ joininfo->mergesortable;
+ other_joininfo->hashjoinable =
+ joininfo->hashjoinable;
+ other_joininfo->inactive = false;
+
+ current_joininfo_list = lcons(other_joininfo,
+ current_joininfo_list);
+ }
+ }
}
- }
- return(current_joininfo_list);
+ return (current_joininfo_list);
}
#ifdef NOTUSED
/*
* add-new-joininfos--
- * For each new join relation, create new joininfos that
- * use the join relation as inner relation, and add
- * the new joininfos to those rel nodes that still
- * have joins with the join relation.
+ * For each new join relation, create new joininfos that
+ * use the join relation as inner relation, and add
+ * the new joininfos to those rel nodes that still
+ * have joins with the join relation.
*
* 'joinrels' is a list of join relations.
*
* Modifies the joininfo field of appropriate rel nodes.
*/
static void
-geqo_add_new_joininfos(Query *root, List *joinrels, List *outerrels)
+geqo_add_new_joininfos(Query * root, List * joinrels, List * outerrels)
{
- List *xjoinrel = NIL;
- List *xrelid = NIL;
- List *xrel = NIL;
- List *xjoininfo = NIL;
-
- Rel *rel;
- List *relids;
-
- List *super_rels;
- List *xsuper_rel = NIL;
- JInfo *new_joininfo;
-
- foreach(xjoinrel, joinrels) {
- Rel *joinrel = (Rel *)lfirst(xjoinrel);
- foreach(xrelid, joinrel->relids) {
- /* length(joinrel->relids) should always be greater that 1, because of *JOIN* */
- /* ! BUG BUG !
- Relid relid = (Relid)lfirst(xrelid);
- Rel *rel = get_join_rel(root, relid);
- */
-
- /*
- if ( (root->join_relation_list_) != NIL ) {
- rel = get_join_rel(root, xrelid);
- }
- else {
- rel = get_base_rel(root, lfirsti(xrelid));
- }
- */
-
- /* NOTE: STILL BUGGY FOR CLAUSE-JOINS: */
- /*
- relids = lconsi(lfirsti(xrelid), NIL);
- rel = rel_member(relids, outerrels);
- */
+ List *xjoinrel = NIL;
+ List *xrelid = NIL;
+ List *xrel = NIL;
+ List *xjoininfo = NIL;
+
+ Rel *rel;
+ List *relids;
+
+ List *super_rels;
+ List *xsuper_rel = NIL;
+ JInfo *new_joininfo;
+
+ foreach(xjoinrel, joinrels)
+ {
+ Rel *joinrel = (Rel *) lfirst(xjoinrel);
+
+ foreach(xrelid, joinrel->relids)
+ {
+
+ /*
+ * length(joinrel->relids) should always be greater that 1,
+ * because of *JOIN*
+ */
+
+ /*
+ * ! BUG BUG ! Relid relid = (Relid)lfirst(xrelid); Rel *rel =
+ * get_join_rel(root, relid);
+ */
- relids = lconsi(lfirsti(xrelid), NIL);
- rel = rel_member(relids, root->base_relation_list_);
+ /*
+ * if ( (root->join_relation_list_) != NIL ) { rel =
+ * get_join_rel(root, xrelid); } else { rel =
+ * get_base_rel(root, lfirsti(xrelid)); }
+ */
- add_superrels(rel,joinrel);
+ /* NOTE: STILL BUGGY FOR CLAUSE-JOINS: */
+
+ /*
+ * relids = lconsi(lfirsti(xrelid), NIL); rel =
+ * rel_member(relids, outerrels);
+ */
+
+ relids = lconsi(lfirsti(xrelid), NIL);
+ rel = rel_member(relids, root->base_relation_list_);
+
+ add_superrels(rel, joinrel);
+ }
}
- }
- foreach(xjoinrel, joinrels) {
- Rel *joinrel = (Rel *)lfirst(xjoinrel);
-
- foreach(xjoininfo, joinrel->joininfo) {
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
- List *other_rels = joininfo->otherrels;
- List *clause_info = joininfo->jinfoclauseinfo;
- bool mergesortable = joininfo->mergesortable;
- bool hashjoinable = joininfo->hashjoinable;
-
- foreach(xrelid, other_rels) {
- /* ! BUG BUG !
- Relid relid = (Relid)lfirst(xrelid);
- Rel *rel = get_join_rel(root, relid);
- */
-
- /*
- if ( (root->join_relation_list_) != NIL ) {
- rel = get_join_rel(root, xrelid);
- }
- else {
- rel = get_base_rel(root, lfirsti(xrelid));
- }
- */
-
- /* NOTE: STILL BUGGY FOR CLAUSE-JOINS: */
- /*
- relids = lconsi(lfirsti(xrelid), NIL);
- rel = rel_member(relids, outerrels);
- */
-
- relids = lconsi(lfirsti(xrelid), NIL);
- rel = rel_member(relids, root->base_relation_list_);
-
- super_rels = rel->superrels;
- new_joininfo = makeNode(JInfo);
-
- new_joininfo->otherrels = joinrel->relids;
- new_joininfo->jinfoclauseinfo = clause_info;
- new_joininfo->mergesortable = mergesortable;
- new_joininfo->hashjoinable = hashjoinable;
- new_joininfo->inactive = false;
- rel->joininfo =
- lappend(rel->joininfo, new_joininfo);
-
- foreach(xsuper_rel, super_rels) {
- Rel *super_rel = (Rel *)lfirst(xsuper_rel);
-
- if( nonoverlap_rels(super_rel,joinrel) ) {
- List *new_relids = super_rel->relids;
- JInfo *other_joininfo =
- joininfo_member(new_relids,
- joinrel->joininfo);
-
- if (other_joininfo) {
- other_joininfo->jinfoclauseinfo =
- (List*)LispUnion(clause_info,
- other_joininfo->jinfoclauseinfo);
- } else {
- JInfo *new_joininfo = makeNode(JInfo);
-
- new_joininfo->otherrels = new_relids;
- new_joininfo->jinfoclauseinfo = clause_info;
- new_joininfo->mergesortable = mergesortable;
- new_joininfo->hashjoinable = hashjoinable;
- new_joininfo->inactive = false;
- joinrel->joininfo =
- lappend(joinrel->joininfo,
- new_joininfo);
+ foreach(xjoinrel, joinrels)
+ {
+ Rel *joinrel = (Rel *) lfirst(xjoinrel);
+
+ foreach(xjoininfo, joinrel->joininfo)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+ List *other_rels = joininfo->otherrels;
+ List *clause_info = joininfo->jinfoclauseinfo;
+ bool mergesortable = joininfo->mergesortable;
+ bool hashjoinable = joininfo->hashjoinable;
+
+ foreach(xrelid, other_rels)
+ {
+
+ /*
+ * ! BUG BUG ! Relid relid = (Relid)lfirst(xrelid); Rel
+ * *rel = get_join_rel(root, relid);
+ */
+
+ /*
+ * if ( (root->join_relation_list_) != NIL ) { rel =
+ * get_join_rel(root, xrelid); } else { rel =
+ * get_base_rel(root, lfirsti(xrelid)); }
+ */
+
+ /* NOTE: STILL BUGGY FOR CLAUSE-JOINS: */
+
+ /*
+ * relids = lconsi(lfirsti(xrelid), NIL); rel =
+ * rel_member(relids, outerrels);
+ */
+
+ relids = lconsi(lfirsti(xrelid), NIL);
+ rel = rel_member(relids, root->base_relation_list_);
+
+ super_rels = rel->superrels;
+ new_joininfo = makeNode(JInfo);
+
+ new_joininfo->otherrels = joinrel->relids;
+ new_joininfo->jinfoclauseinfo = clause_info;
+ new_joininfo->mergesortable = mergesortable;
+ new_joininfo->hashjoinable = hashjoinable;
+ new_joininfo->inactive = false;
+ rel->joininfo =
+ lappend(rel->joininfo, new_joininfo);
+
+ foreach(xsuper_rel, super_rels)
+ {
+ Rel *super_rel = (Rel *) lfirst(xsuper_rel);
+
+ if (nonoverlap_rels(super_rel, joinrel))
+ {
+ List *new_relids = super_rel->relids;
+ JInfo *other_joininfo =
+ joininfo_member(new_relids,
+ joinrel->joininfo);
+
+ if (other_joininfo)
+ {
+ other_joininfo->jinfoclauseinfo =
+ (List *) LispUnion(clause_info,
+ other_joininfo->jinfoclauseinfo);
+ }
+ else
+ {
+ JInfo *new_joininfo = makeNode(JInfo);
+
+ new_joininfo->otherrels = new_relids;
+ new_joininfo->jinfoclauseinfo = clause_info;
+ new_joininfo->mergesortable = mergesortable;
+ new_joininfo->hashjoinable = hashjoinable;
+ new_joininfo->inactive = false;
+ joinrel->joininfo =
+ lappend(joinrel->joininfo,
+ new_joininfo);
+ }
+ }
+ }
}
- }
}
- }
}
- }
- foreach(xrel, outerrels) {
- rel = (Rel *)lfirst(xrel);
- rel->superrels = NIL;
- }
+ foreach(xrel, outerrels)
+ {
+ rel = (Rel *) lfirst(xrel);
+ rel->superrels = NIL;
+ }
}
/*
* final-join-rels--
- * Find the join relation that includes all the original
- * relations, i.e. the final join result.
+ * Find the join relation that includes all the original
+ * relations, i.e. the final join result.
*
* 'join-rel-list' is a list of join relations.
*
* Returns the list of final join relations.
*/
-static List *
-geqo_final_join_rels(List *join_rel_list)
+static List *
+geqo_final_join_rels(List * join_rel_list)
{
- List *xrel = NIL;
- List *temp = NIL;
- List *t_list = NIL;
-
- /*
- * find the relations that has no further joins,
- * i.e., its joininfos all have otherrels nil.
- */
- foreach(xrel,join_rel_list) {
- Rel *rel = (Rel *)lfirst(xrel);
- List *xjoininfo = NIL;
- bool final = true;
-
- foreach (xjoininfo, rel->joininfo) {
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
-
- if (joininfo->otherrels != NIL) {
- final = false;
- break;
- }
- }
- if (final) {
- temp = lcons(rel, NIL);
- t_list = nconc(t_list, temp);
+ List *xrel = NIL;
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ /*
+ * find the relations that has no further joins, i.e., its joininfos
+ * all have otherrels nil.
+ */
+ foreach(xrel, join_rel_list)
+ {
+ Rel *rel = (Rel *) lfirst(xrel);
+ List *xjoininfo = NIL;
+ bool final = true;
+
+ foreach(xjoininfo, rel->joininfo)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+
+ if (joininfo->otherrels != NIL)
+ {
+ final = false;
+ break;
+ }
+ }
+ if (final)
+ {
+ temp = lcons(rel, NIL);
+ t_list = nconc(t_list, temp);
+ }
}
- }
- return(t_list);
+ return (t_list);
}
/*
* add_superrels--
- * add rel to the temporary property list superrels.
+ * add rel to the temporary property list superrels.
*
* 'rel' a rel node
* 'super-rel' rel node of a join relation that includes rel
@@ -599,65 +649,72 @@ geqo_final_join_rels(List *join_rel_list)
* Modifies the superrels field of rel
*/
static void
-add_superrels(Rel *rel, Rel *super_rel)
+add_superrels(Rel * rel, Rel * super_rel)
{
- rel->superrels = lappend(rel->superrels, super_rel);
+ rel->superrels = lappend(rel->superrels, super_rel);
}
/*
* nonoverlap-rels--
- * test if two join relations overlap, i.e., includes the same
- * relation.
+ * test if two join relations overlap, i.e., includes the same
+ * relation.
*
* 'rel1' and 'rel2' are two join relations
*
* Returns non-nil if rel1 and rel2 do not overlap.
*/
-static bool
-nonoverlap_rels(Rel *rel1, Rel *rel2)
+static bool
+nonoverlap_rels(Rel * rel1, Rel * rel2)
{
- return(nonoverlap_sets(rel1->relids, rel2->relids));
+ return (nonoverlap_sets(rel1->relids, rel2->relids));
}
-static bool
-nonoverlap_sets(List *s1, List *s2)
+static bool
+nonoverlap_sets(List * s1, List * s2)
{
- List *x = NIL;
-
- foreach(x,s1) {
- int e = lfirsti(x);
- if(intMember(e,s2))
- return(false);
- }
- return(true);
+ List *x = NIL;
+
+ foreach(x, s1)
+ {
+ int e = lfirsti(x);
+
+ if (intMember(e, s2))
+ return (false);
+ }
+ return (true);
}
-#endif /* NOTUSED */
+
+#endif /* NOTUSED */
/*
* geqo_joinrel_size--
- * compute estimate for join relation tuples, even for
- * long join queries; so get logarithm of size when MAXINT overflow;
+ * compute estimate for join relation tuples, even for
+ * long join queries; so get logarithm of size when MAXINT overflow;
*/
static void
-geqo_joinrel_size(Rel *joinrel, Rel *outer_rel, Rel *inner_rel)
+geqo_joinrel_size(Rel * joinrel, Rel * outer_rel, Rel * inner_rel)
{
- Cost temp;
- int ntuples;
-
+ Cost temp;
+ int ntuples;
+
temp = (Cost) inner_rel->tuples * (Cost) outer_rel->tuples; /* cartesian product */
- if (joinrel->clauseinfo) {
+ if (joinrel->clauseinfo)
+ {
temp = temp * product_selec(joinrel->clauseinfo);
- }
-
- if (temp >= (MAXINT -1)) {
- ntuples = ceil( geqo_log((double)temp, (double) GEQO_LOG_BASE) );
- }
- else {
- ntuples = ceil((double)temp);
- }
+ }
- if (ntuples < 1) ntuples = 1; /* make the best case 1 instead of 0 */
+ if (temp >= (MAXINT - 1))
+ {
+ ntuples = ceil(geqo_log((double) temp, (double) GEQO_LOG_BASE));
+ }
+ else
+ {
+ ntuples = ceil((double) temp);
+ }
+
+ if (ntuples < 1)
+ ntuples = 1; /* make the best case 1 instead of 0 */
joinrel->tuples = ntuples;
}
@@ -665,19 +722,21 @@ geqo_joinrel_size(Rel *joinrel, Rel *outer_rel, Rel *inner_rel)
double
geqo_log(double x, double b)
{
- return(log(x)/log(b));
+ return (log(x) / log(b));
}
-static Rel *
-geqo_nth(int stop, List *rels)
+static Rel *
+geqo_nth(int stop, List * rels)
{
- List *r;
- int i=1;
+ List *r;
+ int i = 1;
- foreach(r, rels) {
- if (i == stop) return lfirst(r);
+ foreach(r, rels)
+ {
+ if (i == stop)
+ return lfirst(r);
i++;
- }
- elog(WARN,"geqo_nth: Internal error - ran off end of list");
- return NULL; /* to keep compiler happy */
+ }
+ elog(WARN, "geqo_nth: Internal error - ran off end of list");
+ return NULL; /* to keep compiler happy */
}
diff --git a/src/backend/optimizer/geqo/geqo_main.c b/src/backend/optimizer/geqo/geqo_main.c
index 4b450002885..eab939c03e6 100644
--- a/src/backend/optimizer/geqo/geqo_main.c
+++ b/src/backend/optimizer/geqo/geqo_main.c
@@ -1,21 +1,21 @@
/*------------------------------------------------------------------------
*
* geqo_main.c--
- * solution of the query optimization problem
- * by means of a Genetic Algorithm (GA)
+ * solution of the query optimization problem
+ * by means of a Genetic Algorithm (GA)
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_main.c,v 1.3 1997/03/14 16:02:51 scrappy Exp $
+ * $Id: geqo_main.c,v 1.4 1997/09/07 04:43:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
@@ -48,228 +48,241 @@
/* define edge recombination crossover [ERX] per default */
#if !defined(ERX) && \
- !defined(PMX) && \
- !defined(CX) && \
- !defined(PX) && \
- !defined(OX1) && \
- !defined(OX2)
+ !defined(PMX) && \
+ !defined(CX) && \
+ !defined(PX) && \
+ !defined(OX1) && \
+ !defined(OX2)
#define ERX
#endif
/*
* geqo--
- * solution of the query optimization problem
- * similar to a constrained Traveling Salesman Problem (TSP)
+ * solution of the query optimization problem
+ * similar to a constrained Traveling Salesman Problem (TSP)
*/
-Rel *
-geqo(Query *root)
+Rel *
+geqo(Query * root)
{
- int generation;
- Chromosome *momma;
- Chromosome *daddy;
- Chromosome *kid;
+ int generation;
+ Chromosome *momma;
+ Chromosome *daddy;
+ Chromosome *kid;
#if defined(ERX)
- Edge *edge_table; /* list of edges */
- int edge_failures=0;
- float difference;
-#endif
+ Edge *edge_table; /* list of edges */
+ int edge_failures = 0;
+ float difference;
+
+#endif
#if defined(CX) || defined(PX) || defined(OX1) || defined(OX2)
- City *city_table; /* list of cities */
+ City *city_table; /* list of cities */
+
#endif
#if defined(CX)
- int cycle_diffs=0;
- int mutations=0;
+ int cycle_diffs = 0;
+ int mutations = 0;
+
#endif
- int number_of_rels;
+ int number_of_rels;
- Pool *pool;
- int pool_size, number_generations, status_interval;
+ Pool *pool;
+ int pool_size,
+ number_generations,
+ status_interval;
- Gene *best_tour;
- Rel *best_rel;
-/* Plan *best_plan; */
+ Gene *best_tour;
+ Rel *best_rel;
+
+/* Plan *best_plan; */
/* set tour size */
- number_of_rels = length(root->base_relation_list_);
+ number_of_rels = length(root->base_relation_list_);
/* set GA parameters */
- geqo_params(number_of_rels) ; /* out of "$PGDATA/pg_geqo" file */
- pool_size = PoolSize;
- number_generations = Generations;
- status_interval = 10;
+ geqo_params(number_of_rels);/* out of "$PGDATA/pg_geqo" file */
+ pool_size = PoolSize;
+ number_generations = Generations;
+ status_interval = 10;
/* seed random number generator */
- srandom(RandomSeed);
+ srandom(RandomSeed);
/* allocate genetic pool memory */
- pool = alloc_pool(pool_size, number_of_rels);
+ pool = alloc_pool(pool_size, number_of_rels);
/* random initialization of the pool */
- random_init_pool (root, pool, 0, pool->size);
+ random_init_pool(root, pool, 0, pool->size);
/* sort the pool according to cheapest path as fitness */
- sort_pool (pool); /* we have to do it only one time, since all kids replace the worst individuals in future (-> geqo_pool.c:spread_chromo ) */
+ sort_pool(pool); /* we have to do it only one time, since
+ * all kids replace the worst individuals
+ * in future (-> geqo_pool.c:spread_chromo
+ * ) */
/* allocate chromosome momma and daddy memory */
- momma = alloc_chromo(pool->string_length);
- daddy = alloc_chromo(pool->string_length);
+ momma = alloc_chromo(pool->string_length);
+ daddy = alloc_chromo(pool->string_length);
#if defined (ERX)
- elog(DEBUG,"geqo_main: using edge recombination crossover [ERX]");
+ elog(DEBUG, "geqo_main: using edge recombination crossover [ERX]");
/* allocate edge table memory */
- edge_table = alloc_edge_table(pool->string_length);
+ edge_table = alloc_edge_table(pool->string_length);
#elif defined(PMX)
- elog(DEBUG,"geqo_main: using partially matched crossover [PMX]");
+ elog(DEBUG, "geqo_main: using partially matched crossover [PMX]");
/* allocate chromosome kid memory */
- kid = alloc_chromo(pool->string_length);
+ kid = alloc_chromo(pool->string_length);
#elif defined(CX)
- elog(DEBUG,"geqo_main: using cycle crossover [CX]");
+ elog(DEBUG, "geqo_main: using cycle crossover [CX]");
/* allocate city table memory */
- kid = alloc_chromo(pool->string_length);
- city_table = alloc_city_table(pool->string_length);
+ kid = alloc_chromo(pool->string_length);
+ city_table = alloc_city_table(pool->string_length);
#elif defined(PX)
- elog(DEBUG,"geqo_main: using position crossover [PX]");
+ elog(DEBUG, "geqo_main: using position crossover [PX]");
/* allocate city table memory */
- kid = alloc_chromo(pool->string_length);
- city_table = alloc_city_table(pool->string_length);
+ kid = alloc_chromo(pool->string_length);
+ city_table = alloc_city_table(pool->string_length);
#elif defined(OX1)
- elog(DEBUG,"geqo_main: using order crossover [OX1]");
+ elog(DEBUG, "geqo_main: using order crossover [OX1]");
/* allocate city table memory */
- kid = alloc_chromo(pool->string_length);
- city_table = alloc_city_table(pool->string_length);
+ kid = alloc_chromo(pool->string_length);
+ city_table = alloc_city_table(pool->string_length);
#elif defined(OX2)
- elog(DEBUG,"geqo_main: using order crossover [OX2]");
+ elog(DEBUG, "geqo_main: using order crossover [OX2]");
/* allocate city table memory */
- kid = alloc_chromo(pool->string_length);
- city_table = alloc_city_table(pool->string_length);
+ kid = alloc_chromo(pool->string_length);
+ city_table = alloc_city_table(pool->string_length);
#endif
/* my pain main part: */
/* iterative optimization */
- for (generation = 0; generation < number_generations; generation++) {
+ for (generation = 0; generation < number_generations; generation++)
+ {
- /* SELECTION */
- geqo_selection(momma, daddy, pool, SelectionBias); /* using linear bias function */
+ /* SELECTION */
+ geqo_selection(momma, daddy, pool, SelectionBias); /* using linear bias
+ * function */
#if defined (ERX)
- /* EDGE RECOMBINATION CROSSOVER */
- difference = gimme_edge_table(momma->string, daddy->string, pool->string_length, edge_table);
+ /* EDGE RECOMBINATION CROSSOVER */
+ difference = gimme_edge_table(momma->string, daddy->string, pool->string_length, edge_table);
- /* let the kid grow in momma's womb (storage) for nine months ;-) */
- /* sleep(23328000) -- har har har */
- kid = momma;
+ /* let the kid grow in momma's womb (storage) for nine months ;-) */
+ /* sleep(23328000) -- har har har */
+ kid = momma;
- /* are there any edge failures ? */
- edge_failures += gimme_tour(edge_table, kid->string, pool->string_length);
+ /* are there any edge failures ? */
+ edge_failures += gimme_tour(edge_table, kid->string, pool->string_length);
#elif defined(PMX)
- /* PARTIALLY MATCHED CROSSOVER */
- pmx(momma->string, daddy->string, kid->string, pool->string_length);
+ /* PARTIALLY MATCHED CROSSOVER */
+ pmx(momma->string, daddy->string, kid->string, pool->string_length);
#elif defined(CX)
- /* CYCLE CROSSOVER */
- cycle_diffs =
- cx(momma->string, daddy->string, kid->string, pool->string_length, city_table);
- /* mutate the child */
- if (cycle_diffs == 0) {
- mutations++;
- geqo_mutation (kid->string, pool->string_length);
- }
+ /* CYCLE CROSSOVER */
+ cycle_diffs =
+ cx(momma->string, daddy->string, kid->string, pool->string_length, city_table);
+ /* mutate the child */
+ if (cycle_diffs == 0)
+ {
+ mutations++;
+ geqo_mutation(kid->string, pool->string_length);
+ }
#elif defined(PX)
- /* POSITION CROSSOVER */
- px(momma->string, daddy->string, kid->string, pool->string_length, city_table);
+ /* POSITION CROSSOVER */
+ px(momma->string, daddy->string, kid->string, pool->string_length, city_table);
#elif defined(OX1)
- /* ORDER CROSSOVER */
- ox1(momma->string, daddy->string, kid->string, pool->string_length, city_table);
+ /* ORDER CROSSOVER */
+ ox1(momma->string, daddy->string, kid->string, pool->string_length, city_table);
#elif defined(OX2)
- /* ORDER CROSSOVER */
- ox2(momma->string, daddy->string, kid->string, pool->string_length, city_table);
+ /* ORDER CROSSOVER */
+ ox2(momma->string, daddy->string, kid->string, pool->string_length, city_table);
#endif
- /* EVALUATE FITNESS */
- kid->worth = geqo_eval (root, kid->string, pool->string_length);
+ /* EVALUATE FITNESS */
+ kid->worth = geqo_eval(root, kid->string, pool->string_length);
- /* push the kid into the wilderness of life according to its worth */
- spread_chromo (kid, pool);
+ /* push the kid into the wilderness of life according to its worth */
+ spread_chromo(kid, pool);
#ifdef GEQO_DEBUG
- if (status_interval && !(generation % status_interval))
- print_gen (stdout, pool, generation);
+ if (status_interval && !(generation % status_interval))
+ print_gen(stdout, pool, generation);
#endif
- } /* end of iterative optimization */
+ } /* end of iterative optimization */
#if defined(ERX) && defined(GEQO_DEBUG)
-if (edge_failures != 0)
- fprintf (stdout, "\nFailures: %d Avg: %d\n", edge_failures, (int) generation/edge_failures);
+ if (edge_failures != 0)
+ fprintf(stdout, "\nFailures: %d Avg: %d\n", edge_failures, (int) generation / edge_failures);
-else fprintf (stdout, "No edge failures detected.\n");
+ else
+ fprintf(stdout, "No edge failures detected.\n");
#endif
#if defined(CX) && defined(GEQO_DEBUG)
-if (mutations != 0)
- fprintf (stdout, "\nMutations: %d Generations: %d\n", mutations, generation);
+ if (mutations != 0)
+ fprintf(stdout, "\nMutations: %d Generations: %d\n", mutations, generation);
-else fprintf (stdout, "No mutations processed.\n");
+ else
+ fprintf(stdout, "No mutations processed.\n");
#endif
-
+
#ifdef GEQO_DEBUG
-fprintf (stdout, "\n");
-print_pool (stdout, pool, 0, pool_size-1);
+ fprintf(stdout, "\n");
+ print_pool(stdout, pool, 0, pool_size - 1);
#endif
/* got the cheapest query tree processed by geqo;
first element of the population indicates the best query tree */
-best_tour = (Gene *) pool->data[0].string;
+ best_tour = (Gene *) pool->data[0].string;
/* root->join_relation_list_ will be modified during this ! */
-best_rel = (Rel *) gimme_tree(root, best_tour, 0, pool->string_length, NULL);
+ best_rel = (Rel *) gimme_tree(root, best_tour, 0, pool->string_length, NULL);
/* DBG: show the query plan
print_plan(best_plan, root);
DBG */
/* ... free memory stuff */
-free_chromo(momma);
-free_chromo(daddy);
+ free_chromo(momma);
+ free_chromo(daddy);
#if defined (ERX)
-free_edge_table(edge_table);
+ free_edge_table(edge_table);
#elif defined(PMX)
-free_chromo(kid);
+ free_chromo(kid);
#elif defined(CX)
-free_chromo(kid);
-free_city_table(city_table);
+ free_chromo(kid);
+ free_city_table(city_table);
#elif defined(PX)
-free_chromo(kid);
-free_city_table(city_table);
+ free_chromo(kid);
+ free_city_table(city_table);
#elif defined(OX1)
-free_chromo(kid);
-free_city_table(city_table);
+ free_chromo(kid);
+ free_city_table(city_table);
#elif defined(OX2)
-free_chromo(kid);
-free_city_table(city_table);
+ free_chromo(kid);
+ free_city_table(city_table);
#endif
-free_pool(pool);
+ free_pool(pool);
-return(best_rel);
+ return (best_rel);
}
-
diff --git a/src/backend/optimizer/geqo/geqo_misc.c b/src/backend/optimizer/geqo/geqo_misc.c
index 48ae78bdcda..67e810d87ca 100644
--- a/src/backend/optimizer/geqo/geqo_misc.c
+++ b/src/backend/optimizer/geqo/geqo_misc.c
@@ -1,20 +1,20 @@
/*------------------------------------------------------------------------
*
* geqo_misc.c--
- * misc. printout and debug stuff
+ * misc. printout and debug stuff
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_misc.c,v 1.2 1997/02/19 14:52:01 scrappy Exp $
+ * $Id: geqo_misc.c,v 1.3 1997/09/07 04:43:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
@@ -41,91 +41,97 @@
#include "optimizer/geqo_recombination.h"
#include "optimizer/geqo_misc.h"
-static float avg_pool (Pool *pool);
+static float avg_pool(Pool * pool);
/* avg_pool--
*
*/
static float
-avg_pool (Pool *pool)
+avg_pool(Pool * pool)
{
- int i;
- double cumulative = 0.0;
-
- if (pool->size==0)
- elog(WARN,"avg_pool: pool_size of zero");
-
- for (i=0; i<pool->size; i++)
- cumulative = cumulative + pool->data[i].worth;
-
- return ((float) cumulative/pool->size);
+ int i;
+ double cumulative = 0.0;
+
+ if (pool->size == 0)
+ elog(WARN, "avg_pool: pool_size of zero");
+
+ for (i = 0; i < pool->size; i++)
+ cumulative = cumulative + pool->data[i].worth;
+
+ return ((float) cumulative / pool->size);
}
/* print_pool--
*/
void
-print_pool (FILE *fp, Pool *pool, int start, int stop)
+print_pool(FILE * fp, Pool * pool, int start, int stop)
{
- int i, j;
+ int i,
+ j;
- /* be extra careful that start and stop are valid inputs */
+ /* be extra careful that start and stop are valid inputs */
- if (start < 0) start = 0;
- if (stop > pool->size) stop = pool->size;
+ if (start < 0)
+ start = 0;
+ if (stop > pool->size)
+ stop = pool->size;
- if (start+stop > pool->size) {
- start = 0;
- stop = pool->size;
+ if (start + stop > pool->size)
+ {
+ start = 0;
+ stop = pool->size;
}
- for (i=start; i<stop; i++) {
- fprintf (fp, "%d)\t", i);
- for (j=0; j<pool->string_length; j++)
- fprintf (fp, "%d ", pool->data[i].string[j]);
- fprintf (fp, "%f\n", pool->data[i].worth);
+ for (i = start; i < stop; i++)
+ {
+ fprintf(fp, "%d)\t", i);
+ for (j = 0; j < pool->string_length; j++)
+ fprintf(fp, "%d ", pool->data[i].string[j]);
+ fprintf(fp, "%f\n", pool->data[i].worth);
}
}
/* print_gen--
*
- * printout for chromosome: best, worst, mean, average
+ * printout for chromosome: best, worst, mean, average
*
*/
void
-print_gen(FILE *fp, Pool *pool, int generation)
+print_gen(FILE * fp, Pool * pool, int generation)
{
- int lowest;
-
- /* Get index to lowest ranking gene in poplulation. */
- /* Use 2nd to last since last is buffer. */
- lowest = pool->size > 1 ? pool->size-2 : 0;
-
- fprintf (fp,
- "%5d | Bst: %f Wst: %f Mean: %f Avg: %f\n",
- generation,
- pool->data[0].worth,
- pool->data[lowest].worth,
- pool->data[pool->size/2].worth,
- avg_pool(pool));
+ int lowest;
+
+ /* Get index to lowest ranking gene in poplulation. */
+ /* Use 2nd to last since last is buffer. */
+ lowest = pool->size > 1 ? pool->size - 2 : 0;
+
+ fprintf(fp,
+ "%5d | Bst: %f Wst: %f Mean: %f Avg: %f\n",
+ generation,
+ pool->data[0].worth,
+ pool->data[lowest].worth,
+ pool->data[pool->size / 2].worth,
+ avg_pool(pool));
}
void
-print_edge_table (FILE *fp, Edge *edge_table, int num_gene)
+print_edge_table(FILE * fp, Edge * edge_table, int num_gene)
{
- int i,j;
-
- fprintf (fp, "\nEDGE TABLE\n");
-
- for (i=1; i<=num_gene; i++)
- {
- fprintf (fp, "%d :", i);
- for (j=0; j<edge_table[i].unused_edges; j++)
- fprintf (fp, " %d", edge_table[i].edge_list[j]);
- fprintf (fp, "\n");
- }
-
- fprintf (fp, "\n");
+ int i,
+ j;
+
+ fprintf(fp, "\nEDGE TABLE\n");
+
+ for (i = 1; i <= num_gene; i++)
+ {
+ fprintf(fp, "%d :", i);
+ for (j = 0; j < edge_table[i].unused_edges; j++)
+ fprintf(fp, " %d", edge_table[i].edge_list[j]);
+ fprintf(fp, "\n");
+ }
+
+ fprintf(fp, "\n");
}
/*************************************************************
@@ -133,116 +139,147 @@ print_edge_table (FILE *fp, Edge *edge_table, int num_gene)
*************************************************************/
void
-geqo_print_joinclauses(Query *root, List *clauses)
+geqo_print_joinclauses(Query * root, List * clauses)
{
- List *l;
- extern void print_expr(Node *expr, List *rtable); /* in print.c */
+ List *l;
+ extern void print_expr(Node * expr, List * rtable); /* in print.c */
- foreach(l, clauses) {
- CInfo *c = lfirst(l);
+ foreach(l, clauses)
+ {
+ CInfo *c = lfirst(l);
- print_expr((Node*)c->clause, root->rtable);
- if (lnext(l)) printf(" ");
- }
+ print_expr((Node *) c->clause, root->rtable);
+ if (lnext(l))
+ printf(" ");
+ }
}
void
-geqo_print_path(Query *root, Path *path, int indent)
+geqo_print_path(Query * root, Path * path, int indent)
{
- char *ptype = NULL;
- JoinPath *jp;
- bool join = false;
- int i;
-
- for(i=0; i < indent; i++)
- printf("\t");
-
- switch(nodeTag(path)) {
- case T_Path:
- ptype = "SeqScan"; join=false; break;
- case T_IndexPath:
- ptype = "IdxScan"; join=false; break;
- case T_JoinPath:
- ptype = "Nestloop"; join=true; break;
- case T_MergePath:
- ptype = "MergeJoin"; join=true; break;
- case T_HashPath:
- ptype = "HashJoin"; join=true; break;
- default:
- break;
- }
- if (join) {
- int size = path->parent->size;
- jp = (JoinPath*)path;
- printf("%s size=%d cost=%f\n", ptype, size, path->path_cost);
- switch(nodeTag(path)) {
+ char *ptype = NULL;
+ JoinPath *jp;
+ bool join = false;
+ int i;
+
+ for (i = 0; i < indent; i++)
+ printf("\t");
+
+ switch (nodeTag(path))
+ {
+ case T_Path:
+ ptype = "SeqScan";
+ join = false;
+ break;
+ case T_IndexPath:
+ ptype = "IdxScan";
+ join = false;
+ break;
+ case T_JoinPath:
+ ptype = "Nestloop";
+ join = true;
+ break;
case T_MergePath:
+ ptype = "MergeJoin";
+ join = true;
+ break;
case T_HashPath:
- for(i=0; i < indent+1; i++)
- printf("\t");
- printf(" clauses=(");
- geqo_print_joinclauses(root,
- ((JoinPath*)path)->pathclauseinfo);
- printf(")\n");
-
- if (nodeTag(path)==T_MergePath) {
- MergePath *mp = (MergePath*)path;
- if (mp->outersortkeys || mp->innersortkeys) {
- for(i=0; i < indent+1; i++)
- printf("\t");
- printf(" sortouter=%d sortinner=%d\n",
- ((mp->outersortkeys)?1:0),
- ((mp->innersortkeys)?1:0));
- }
- }
- break;
+ ptype = "HashJoin";
+ join = true;
+ break;
default:
- break;
+ break;
}
- geqo_print_path(root, jp->outerjoinpath, indent+1);
- geqo_print_path(root, jp->innerjoinpath, indent+1);
- } else {
- int size = path->parent->size;
- int relid = lfirsti(path->parent->relids);
- printf("%s(%d) size=%d cost=%f",
- ptype, relid, size, path->path_cost);
-
- if (nodeTag(path)==T_IndexPath) {
- List *k, *l;
-
- printf(" keys=");
- foreach (k, path->keys) {
- printf("(");
- foreach (l, lfirst(k)) {
- Var *var = lfirst(l);
- printf("%d.%d", var->varnoold, var->varoattno);
- if (lnext(l)) printf(", ");
+ if (join)
+ {
+ int size = path->parent->size;
+
+ jp = (JoinPath *) path;
+ printf("%s size=%d cost=%f\n", ptype, size, path->path_cost);
+ switch (nodeTag(path))
+ {
+ case T_MergePath:
+ case T_HashPath:
+ for (i = 0; i < indent + 1; i++)
+ printf("\t");
+ printf(" clauses=(");
+ geqo_print_joinclauses(root,
+ ((JoinPath *) path)->pathclauseinfo);
+ printf(")\n");
+
+ if (nodeTag(path) == T_MergePath)
+ {
+ MergePath *mp = (MergePath *) path;
+
+ if (mp->outersortkeys || mp->innersortkeys)
+ {
+ for (i = 0; i < indent + 1; i++)
+ printf("\t");
+ printf(" sortouter=%d sortinner=%d\n",
+ ((mp->outersortkeys) ? 1 : 0),
+ ((mp->innersortkeys) ? 1 : 0));
+ }
+ }
+ break;
+ default:
+ break;
}
- printf(")");
- if (lnext(k)) printf(", ");
- }
+ geqo_print_path(root, jp->outerjoinpath, indent + 1);
+ geqo_print_path(root, jp->innerjoinpath, indent + 1);
+ }
+ else
+ {
+ int size = path->parent->size;
+ int relid = lfirsti(path->parent->relids);
+
+ printf("%s(%d) size=%d cost=%f",
+ ptype, relid, size, path->path_cost);
+
+ if (nodeTag(path) == T_IndexPath)
+ {
+ List *k,
+ *l;
+
+ printf(" keys=");
+ foreach(k, path->keys)
+ {
+ printf("(");
+ foreach(l, lfirst(k))
+ {
+ Var *var = lfirst(l);
+
+ printf("%d.%d", var->varnoold, var->varoattno);
+ if (lnext(l))
+ printf(", ");
+ }
+ printf(")");
+ if (lnext(k))
+ printf(", ");
+ }
+ }
+ printf("\n");
}
- printf("\n");
- }
}
-void
-geqo_print_rel(Query *root, Rel *rel)
+void
+geqo_print_rel(Query * root, Rel * rel)
{
- List *l;
-
- printf("______________________________\n");
- printf("(");
- foreach(l, rel->relids) {
- printf("%d ", lfirsti(l));
- }
- printf("): size=%d width=%d\n", rel->size, rel->width);
-
- printf("\tpath list:\n");
- foreach (l, rel->pathlist) {
- geqo_print_path(root, lfirst(l), 1);
- }
-
- printf("\tcheapest path:\n");
- geqo_print_path(root, rel->cheapestpath, 1);
+ List *l;
+
+ printf("______________________________\n");
+ printf("(");
+ foreach(l, rel->relids)
+ {
+ printf("%d ", lfirsti(l));
+ }
+ printf("): size=%d width=%d\n", rel->size, rel->width);
+
+ printf("\tpath list:\n");
+ foreach(l, rel->pathlist)
+ {
+ geqo_print_path(root, lfirst(l), 1);
+ }
+
+ printf("\tcheapest path:\n");
+ geqo_print_path(root, rel->cheapestpath, 1);
}
diff --git a/src/backend/optimizer/geqo/geqo_mutation.c b/src/backend/optimizer/geqo/geqo_mutation.c
index 9d544564210..a5a43e6e2b9 100644
--- a/src/backend/optimizer/geqo/geqo_mutation.c
+++ b/src/backend/optimizer/geqo/geqo_mutation.c
@@ -2,33 +2,33 @@
*
* geqo_mutation.c--
*
-* TSP mutation routines
+* TSP mutation routines
*
-* $Id: geqo_mutation.c,v 1.1 1997/02/19 12:57:13 scrappy Exp $
+* $Id: geqo_mutation.c,v 1.2 1997/09/07 04:43:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* this is adopted from Genitor : */
/*************************************************************/
-/* */
-/* Copyright (c) 1990 */
-/* Darrell L. Whitley */
-/* Computer Science Department */
-/* Colorado State University */
-/* */
-/* Permission is hereby granted to copy all or any part of */
-/* this program for free distribution. The author's name */
-/* and this copyright notice must be included in any copy. */
-/* */
+/* */
+/* Copyright (c) 1990 */
+/* Darrell L. Whitley */
+/* Computer Science Department */
+/* Colorado State University */
+/* */
+/* Permission is hereby granted to copy all or any part of */
+/* this program for free distribution. The author's name */
+/* and this copyright notice must be included in any copy. */
+/* */
/*************************************************************/
#include "postgres.h"
@@ -50,27 +50,28 @@
#include "optimizer/geqo_random.h"
#include "optimizer/geqo_mutation.h"
- void
- geqo_mutation (Gene *tour, int num_gene)
- {
- int swap1;
- int swap2;
- int num_swaps = geqo_randint (num_gene/3, 0);
- Gene temp;
+void
+geqo_mutation(Gene * tour, int num_gene)
+{
+ int swap1;
+ int swap2;
+ int num_swaps = geqo_randint(num_gene / 3, 0);
+ Gene temp;
- while (num_swaps > 0) {
- swap1 = geqo_randint (num_gene-1, 0);
- swap2 = geqo_randint (num_gene-1, 0);
+ while (num_swaps > 0)
+ {
+ swap1 = geqo_randint(num_gene - 1, 0);
+ swap2 = geqo_randint(num_gene - 1, 0);
- while (swap1 == swap2)
- swap2 = geqo_randint (num_gene-1, 0);
+ while (swap1 == swap2)
+ swap2 = geqo_randint(num_gene - 1, 0);
- temp = tour[swap1];
- tour[swap1] = tour[swap2];
- tour[swap2] = temp;
+ temp = tour[swap1];
+ tour[swap1] = tour[swap2];
+ tour[swap2] = temp;
- num_swaps -= 1;
- }
+ num_swaps -= 1;
+ }
}
diff --git a/src/backend/optimizer/geqo/geqo_ox1.c b/src/backend/optimizer/geqo/geqo_ox1.c
index 329554f9aae..b88b8950673 100644
--- a/src/backend/optimizer/geqo/geqo_ox1.c
+++ b/src/backend/optimizer/geqo/geqo_ox1.c
@@ -2,35 +2,35 @@
*
* geqo_ox1.c--
*
-* order crossover [OX] routines;
-* OX1 operator according to Davis
-* (Proc Int'l Joint Conf on AI)
+* order crossover [OX] routines;
+* OX1 operator according to Davis
+* (Proc Int'l Joint Conf on AI)
*
-* $Id: geqo_ox1.c,v 1.1 1997/03/14 16:02:58 scrappy Exp $
+* $Id: geqo_ox1.c,v 1.2 1997/09/07 04:43:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* the ox algorithm is adopted from Genitor : */
/*************************************************************/
-/* */
-/* Copyright (c) 1990 */
-/* Darrell L. Whitley */
-/* Computer Science Department */
-/* Colorado State University */
-/* */
-/* Permission is hereby granted to copy all or any part of */
-/* this program for free distribution. The author's name */
-/* and this copyright notice must be included in any copy. */
-/* */
+/* */
+/* Copyright (c) 1990 */
+/* Darrell L. Whitley */
+/* Computer Science Department */
+/* Colorado State University */
+/* */
+/* Permission is hereby granted to copy all or any part of */
+/* this program for free distribution. The author's name */
+/* and this copyright notice must be included in any copy. */
+/* */
/*************************************************************/
#include "postgres.h"
@@ -56,48 +56,52 @@
/* ox1--
*
- * position crossover
+ * position crossover
*/
void
-ox1(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
+ox1(Gene * tour1, Gene * tour2, Gene * offspring, int num_gene, City * city_table)
{
- int left, right, k, p, temp;
-
- /* initialize city table */
- for (k = 1; k <= num_gene; k++)
- city_table[k].used = 0;
-
- /* select portion to copy from tour1 */
- left = geqo_randint (num_gene - 1, 0);
- right = geqo_randint (num_gene - 1, 0);
-
- if (left > right)
- {
- temp = left;
- left = right;
- right = temp;
- }
-
- /* copy portion from tour1 to offspring */
- for (k = left; k <= right; k++)
- {
- offspring[k] = tour1[k];
- city_table[(int) tour1[k]].used = 1;
- }
-
- k = (right + 1) % num_gene; /* index into offspring */
- p = k; /* index into tour2 */
-
- /* copy stuff from tour2 to offspring */
- while (k != left)
- {
- if (!city_table[(int) tour2[p]].used)
- {
- offspring[k] = tour2[p];
- k = (k + 1) % num_gene;
- city_table[(int) tour2[p]].used = 1;
- }
- p = (p + 1) % num_gene; /* increment tour2-index */
- }
-
- }
+ int left,
+ right,
+ k,
+ p,
+ temp;
+
+ /* initialize city table */
+ for (k = 1; k <= num_gene; k++)
+ city_table[k].used = 0;
+
+ /* select portion to copy from tour1 */
+ left = geqo_randint(num_gene - 1, 0);
+ right = geqo_randint(num_gene - 1, 0);
+
+ if (left > right)
+ {
+ temp = left;
+ left = right;
+ right = temp;
+ }
+
+ /* copy portion from tour1 to offspring */
+ for (k = left; k <= right; k++)
+ {
+ offspring[k] = tour1[k];
+ city_table[(int) tour1[k]].used = 1;
+ }
+
+ k = (right + 1) % num_gene; /* index into offspring */
+ p = k; /* index into tour2 */
+
+ /* copy stuff from tour2 to offspring */
+ while (k != left)
+ {
+ if (!city_table[(int) tour2[p]].used)
+ {
+ offspring[k] = tour2[p];
+ k = (k + 1) % num_gene;
+ city_table[(int) tour2[p]].used = 1;
+ }
+ p = (p + 1) % num_gene; /* increment tour2-index */
+ }
+
+}
diff --git a/src/backend/optimizer/geqo/geqo_ox2.c b/src/backend/optimizer/geqo/geqo_ox2.c
index 2afcece01ff..ef09925b4fa 100644
--- a/src/backend/optimizer/geqo/geqo_ox2.c
+++ b/src/backend/optimizer/geqo/geqo_ox2.c
@@ -2,35 +2,35 @@
*
* geqo_ox2.c--
*
-* order crossover [OX] routines;
-* OX2 operator according to Syswerda
-* (The Genetic Algorithms Handbook, ed L Davis)
+* order crossover [OX] routines;
+* OX2 operator according to Syswerda
+* (The Genetic Algorithms Handbook, ed L Davis)
*
-* $Id: geqo_ox2.c,v 1.1 1997/03/14 16:03:02 scrappy Exp $
+* $Id: geqo_ox2.c,v 1.2 1997/09/07 04:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* the ox algorithm is adopted from Genitor : */
/*************************************************************/
-/* */
-/* Copyright (c) 1990 */
-/* Darrell L. Whitley */
-/* Computer Science Department */
-/* Colorado State University */
-/* */
-/* Permission is hereby granted to copy all or any part of */
-/* this program for free distribution. The author's name */
-/* and this copyright notice must be included in any copy. */
-/* */
+/* */
+/* Copyright (c) 1990 */
+/* Darrell L. Whitley */
+/* Computer Science Department */
+/* Colorado State University */
+/* */
+/* Permission is hereby granted to copy all or any part of */
+/* this program for free distribution. The author's name */
+/* and this copyright notice must be included in any copy. */
+/* */
/*************************************************************/
#include "postgres.h"
@@ -56,58 +56,70 @@
/* ox2--
*
- * position crossover
+ * position crossover
*/
void
-ox2(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
+ox2(Gene * tour1, Gene * tour2, Gene * offspring, int num_gene, City * city_table)
{
- int k, j, count, pos, select, num_positions;
-
- /* initialize city table */
- for (k = 1; k <= num_gene; k++) {
- city_table[k].used = 0;
- city_table[k-1].select_list = -1;
- }
-
- /* determine the number of positions to be inherited from tour1 */
- num_positions = geqo_randint (2*num_gene/3, num_gene/3);
-
- /* make a list of selected cities */
- for (k=0; k<num_positions; k++) {
- pos = geqo_randint (num_gene - 1, 0);
- city_table[pos].select_list = (int) tour1[pos];
- city_table[(int) tour1[pos]].used = 1; /* mark used */
- }
-
-
- count = 0;
- k = 0;
-
- /* consolidate the select list to adjacent positions */
- while (count < num_positions) {
- if (city_table[k].select_list == -1) {
- j = k + 1;
- while ((city_table[j].select_list == -1) && (j < num_gene))
- j++;
-
- city_table[k].select_list = city_table[j].select_list;
- city_table[j].select_list = -1;
- count ++;
- }
- else
- count ++;
- k++;
- }
-
- select = 0;
-
- for (k=0; k<num_gene; k++) {
- if (city_table[(int) tour2[k]].used) {
- offspring[k] = (Gene) city_table[select].select_list;
- select ++; /* next city in the select list */
- }
- else /* city isn't used yet, so inherit from tour2 */
- offspring[k] = tour2[k];
- }
+ int k,
+ j,
+ count,
+ pos,
+ select,
+ num_positions;
+
+ /* initialize city table */
+ for (k = 1; k <= num_gene; k++)
+ {
+ city_table[k].used = 0;
+ city_table[k - 1].select_list = -1;
+ }
+
+ /* determine the number of positions to be inherited from tour1 */
+ num_positions = geqo_randint(2 * num_gene / 3, num_gene / 3);
+
+ /* make a list of selected cities */
+ for (k = 0; k < num_positions; k++)
+ {
+ pos = geqo_randint(num_gene - 1, 0);
+ city_table[pos].select_list = (int) tour1[pos];
+ city_table[(int) tour1[pos]].used = 1; /* mark used */
+ }
+
+
+ count = 0;
+ k = 0;
+
+ /* consolidate the select list to adjacent positions */
+ while (count < num_positions)
+ {
+ if (city_table[k].select_list == -1)
+ {
+ j = k + 1;
+ while ((city_table[j].select_list == -1) && (j < num_gene))
+ j++;
+
+ city_table[k].select_list = city_table[j].select_list;
+ city_table[j].select_list = -1;
+ count++;
+ }
+ else
+ count++;
+ k++;
+ }
+
+ select = 0;
+
+ for (k = 0; k < num_gene; k++)
+ {
+ if (city_table[(int) tour2[k]].used)
+ {
+ offspring[k] = (Gene) city_table[select].select_list;
+ select++; /* next city in the select list */
+ }
+ else
+/* city isn't used yet, so inherit from tour2 */
+ offspring[k] = tour2[k];
+ }
}
diff --git a/src/backend/optimizer/geqo/geqo_params.c b/src/backend/optimizer/geqo/geqo_params.c
index 52c57c45378..45f7dfd5ddc 100644
--- a/src/backend/optimizer/geqo/geqo_params.c
+++ b/src/backend/optimizer/geqo/geqo_params.c
@@ -1,20 +1,20 @@
/*------------------------------------------------------------------------
*
* geqo_params.c--
-* routines for determining necessary genetic optimization parameters
+* routines for determining necessary genetic optimization parameters
*
* Copyright (c) 1994, Regents of the University of California
*
-* $Id: geqo_params.c,v 1.5 1997/08/18 02:14:41 momjian Exp $
+* $Id: geqo_params.c,v 1.6 1997/09/07 04:43:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
@@ -45,48 +45,48 @@
#include "storage/fd.h"
-#define POOL_TAG "Pool_Size"
-#define TRIAL_TAG "Generations"
-#define RAND_TAG "Random_Seed"
-#define BIAS_TAG "Selection_Bias"
+#define POOL_TAG "Pool_Size"
+#define TRIAL_TAG "Generations"
+#define RAND_TAG "Random_Seed"
+#define BIAS_TAG "Selection_Bias"
-#define EFFORT_TAG "Effort" /* optimization effort and */
-#define LOW "low" /* corresponding tags */
-#define MEDIUM "medium"
-#define HIGH "high"
+#define EFFORT_TAG "Effort"/* optimization effort and */
+#define LOW "low" /* corresponding tags */
+#define MEDIUM "medium"
+#define HIGH "high"
-#define MAX_TOKEN 80 /* Maximum size of one token in the *
- * configuration file */
+#define MAX_TOKEN 80 /* Maximum size of one token in the *
+ * configuration file */
-static int gimme_pool_size(int string_length);
-static int gimme_number_generations(int pool_size, int effort);
-static int next_token(FILE *, char *, int);
+static int gimme_pool_size(int string_length);
+static int gimme_number_generations(int pool_size, int effort);
+static int next_token(FILE *, char *, int);
/*
* geqo_param--
- * get ga parameters out of "$PGDATA/pg_geqo" file.
+ * get ga parameters out of "$PGDATA/pg_geqo" file.
*/
void
geqo_params(int string_length)
{
- int i;
+ int i;
- char buf[MAX_TOKEN];
- FILE *file;
+ char buf[MAX_TOKEN];
+ FILE *file;
- char *conf_file;
+ char *conf_file;
/* these static variables are used to signal that a value has been set */
- int pool_size = 0;
- int number_trials = 0;
- int random_seed = 0;
- int selection_bias = 0;
- int effort = 0;
+ int pool_size = 0;
+ int number_trials = 0;
+ int random_seed = 0;
+ int selection_bias = 0;
+ int effort = 0;
/* put together the full pathname to the config file */
conf_file =
- (char *) palloc((strlen(DataDir)+strlen(GEQO_FILE)+2)*sizeof(char));
+ (char *) palloc((strlen(DataDir) + strlen(GEQO_FILE) + 2) * sizeof(char));
sprintf(conf_file, "%s/%s", DataDir, GEQO_FILE);
@@ -94,99 +94,109 @@ geqo_params(int string_length)
file = AllocateFile(conf_file, "r");
if (file)
{
+
/*
* empty and comment line stuff
*/
while ((i = next_token(file, buf, sizeof(buf))) != EOF)
{
- /* If only token on the line, ignore */
- if (i == '\n') continue;
-
- /* Comment -- read until end of line then next line */
- if (buf[0] == '#')
- {
- while (next_token(file, buf, sizeof(buf)) == 0) ;
- continue;
- }
+ /* If only token on the line, ignore */
+ if (i == '\n')
+ continue;
+
+ /* Comment -- read until end of line then next line */
+ if (buf[0] == '#')
+ {
+ while (next_token(file, buf, sizeof(buf)) == 0);
+ continue;
+ }
/*
* get ga parameters by parsing
*/
-
+
/*------------------------------------------------- pool size */
- if ( strcmp(buf, POOL_TAG) == 0 )
+ if (strcmp(buf, POOL_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf)); /* get next token */
-
- if (i != EOF) /* only ignore if we got no text at all */
+
+ if (i != EOF) /* only ignore if we got no text at all */
{
- if (sscanf (buf, "%d", &PoolSize) == 1) pool_size = 1;
+ if (sscanf(buf, "%d", &PoolSize) == 1)
+ pool_size = 1;
}
-
+
}
-
+
/*------------------------------------------------- number of trials */
- else if ( strcmp(buf, TRIAL_TAG) == 0 )
+ else if (strcmp(buf, TRIAL_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
-
+
if (i != EOF)
{
- if (sscanf (buf, "%d", &Generations) == 1) number_trials = 1;
+ if (sscanf(buf, "%d", &Generations) == 1)
+ number_trials = 1;
}
-
+
}
-
+
/*------------------------------------------------- optimization effort */
- else if ( strcmp(buf, EFFORT_TAG) == 0 )
+ else if (strcmp(buf, EFFORT_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
-
+
if (i != EOF)
{
- if (strcmp (buf, LOW) == 0) effort = LOW_EFFORT;
- else if (strcmp (buf, MEDIUM) == 0) effort = MEDIUM_EFFORT;
- else if (strcmp (buf, HIGH) == 0) effort = HIGH_EFFORT;
+ if (strcmp(buf, LOW) == 0)
+ effort = LOW_EFFORT;
+ else if (strcmp(buf, MEDIUM) == 0)
+ effort = MEDIUM_EFFORT;
+ else if (strcmp(buf, HIGH) == 0)
+ effort = HIGH_EFFORT;
}
-
+
}
-
+
/*------------------------------------------- random seed */
- else if ( strcmp(buf, RAND_TAG) == 0 )
- {
+ else if (strcmp(buf, RAND_TAG) == 0)
+ {
i = next_token(file, buf, sizeof(buf));
-
+
if (i != EOF)
{
- if (sscanf (buf, "%ld", &RandomSeed) == 1) random_seed = 1;
+ if (sscanf(buf, "%ld", &RandomSeed) == 1)
+ random_seed = 1;
}
-
+
}
-
+
/*------------------------------------------- selection bias */
- else if ( strcmp(buf, BIAS_TAG) == 0 )
+ else if (strcmp(buf, BIAS_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
-
+
if (i != EOF)
{
- if (sscanf (buf, "%lf", &SelectionBias) == 1) selection_bias = 1;
+ if (sscanf(buf, "%lf", &SelectionBias) == 1)
+ selection_bias = 1;
}
-
+
}
-
+
/* unrecognized tags */
else
{
if (i != EOF)
{
}
-
- elog(DEBUG,"geqo_params: unknown parameter type \"%s\"\nin file \'%s\'", buf, conf_file);
+
+ elog(DEBUG, "geqo_params: unknown parameter type \"%s\"\nin file \'%s\'", buf, conf_file);
/* if not at end-of-line, keep reading til we are */
- while (i == 0) i = next_token(file, buf, sizeof(buf));
- }
+ while (i == 0)
+ i = next_token(file, buf, sizeof(buf));
+ }
}
FreeFile(file);
@@ -194,9 +204,9 @@ geqo_params(int string_length)
pfree(conf_file);
}
- else
+ else
{
- elog(DEBUG,"geqo_params: ga parameter file\n\'%s\'\ndoes not exist or permissions are not setup correctly", conf_file);
+ elog(DEBUG, "geqo_params: ga parameter file\n\'%s\'\ndoes not exist or permissions are not setup correctly", conf_file);
}
/*
@@ -204,49 +214,49 @@ geqo_params(int string_length)
*/
/**************** PoolSize: essential ****************/
- if ( !(pool_size) )
+ if (!(pool_size))
{
PoolSize = gimme_pool_size(string_length);
- elog(DEBUG,"geqo_params: no pool size specified;\nusing computed value of %d", PoolSize);
+ elog(DEBUG, "geqo_params: no pool size specified;\nusing computed value of %d", PoolSize);
}
-
-
+
+
/**************** Effort: essential ****************/
- if ( !(effort) )
+ if (!(effort))
{
if (PoolSize == MAX_POOL)
effort = HIGH_EFFORT;
else
effort = MEDIUM_EFFORT;
-
- elog(DEBUG,"geqo_params: no optimization effort specified;\nusing value of %d", effort);
+
+ elog(DEBUG, "geqo_params: no optimization effort specified;\nusing value of %d", effort);
}
/**************** Generations: essential ****************/
- if ( !(number_trials) )
+ if (!(number_trials))
{
Generations = gimme_number_generations(PoolSize, effort);
-
- elog(DEBUG,"geqo_params: no number of trials specified;\nusing computed value of %d", Generations);
+
+ elog(DEBUG, "geqo_params: no number of trials specified;\nusing computed value of %d", Generations);
}
/* RandomSeed: */
- if ( !(random_seed) )
+ if (!(random_seed))
{
RandomSeed = (long) time(NULL);
- elog(DEBUG,"geqo_params: no random seed specified;\nusing computed value of %ld", RandomSeed);
+ elog(DEBUG, "geqo_params: no random seed specified;\nusing computed value of %ld", RandomSeed);
}
/* SelectionBias: */
- if ( !(selection_bias) )
+ if (!(selection_bias))
{
SelectionBias = SELECTION_BIAS;
- elog(DEBUG,"geqo_params: no selection bias specified;\nusing default value of %f", SelectionBias);
+ elog(DEBUG, "geqo_params: no selection bias specified;\nusing default value of %f", SelectionBias);
}
}
@@ -255,73 +265,79 @@ geqo_params(int string_length)
/*
* Grab one token out of fp. Defined as the next string of non-whitespace
* in the file. After we get the token, continue reading until EOF, end of
- * line or the next token. If it's the last token on the line, return '\n'
+ * line or the next token. If it's the last token on the line, return '\n'
* for the value. If we get EOF before reading a token, return EOF. In all
* other cases return 0.
*/
-static int
-next_token(FILE *fp, char *buf, int bufsz)
+static int
+next_token(FILE * fp, char *buf, int bufsz)
{
- int c;
- char *eb = buf+(bufsz-1);
+ int c;
+ char *eb = buf + (bufsz - 1);
- /* Discard inital whitespace */
- while (isspace(c = getc(fp))) ;
+ /* Discard inital whitespace */
+ while (isspace(c = getc(fp)));
- /* EOF seen before any token so return EOF */
- if (c == EOF) return -1;
+ /* EOF seen before any token so return EOF */
+ if (c == EOF)
+ return -1;
- /* Form a token in buf */
- do {
- if (buf < eb) *buf++ = c;
- c = getc(fp);
- } while (!isspace(c) && c != EOF);
- *buf = '\0';
+ /* Form a token in buf */
+ do
+ {
+ if (buf < eb)
+ *buf++ = c;
+ c = getc(fp);
+ } while (!isspace(c) && c != EOF);
+ *buf = '\0';
- /* Discard trailing tabs and spaces */
- while (c == ' ' || c == '\t') c = getc(fp);
+ /* Discard trailing tabs and spaces */
+ while (c == ' ' || c == '\t')
+ c = getc(fp);
- /* Put back the char that was non-whitespace (putting back EOF is ok) */
- ungetc(c, fp);
+ /* Put back the char that was non-whitespace (putting back EOF is ok) */
+ ungetc(c, fp);
- /* If we ended with a newline, return that, otherwise return 0 */
- return (c == '\n' ? '\n' : 0);
+ /* If we ended with a newline, return that, otherwise return 0 */
+ return (c == '\n' ? '\n' : 0);
}
/* gimme_pool_size--
- * compute good estimation for pool size
- * according to number of involved rels in a query
+ * compute good estimation for pool size
+ * according to number of involved rels in a query
*/
-static int
+static int
gimme_pool_size(int string_length)
{
- double exponent;
- double size;
+ double exponent;
+ double size;
exponent = (double) string_length + 1.0;
- size = pow (2.0, exponent);
+ size = pow(2.0, exponent);
- if (size < MIN_POOL) {
+ if (size < MIN_POOL)
+ {
return (MIN_POOL);
- }
- else if (size > MAX_POOL) {
+ }
+ else if (size > MAX_POOL)
+ {
return (MAX_POOL);
- }
- else
- return ( (int) ceil(size) );
+ }
+ else
+ return ((int) ceil(size));
}
/* gimme_number_generations--
- * compute good estimation for number of generations size
- * for convergence
+ * compute good estimation for number of generations size
+ * for convergence
*/
-static int
+static int
gimme_number_generations(int pool_size, int effort)
{
- int number_gens;
+ int number_gens;
- number_gens = (int) ceil ( geqo_log((double) pool_size, 2.0) );
+ number_gens = (int) ceil(geqo_log((double) pool_size, 2.0));
return (effort * number_gens);
}
diff --git a/src/backend/optimizer/geqo/geqo_paths.c b/src/backend/optimizer/geqo/geqo_paths.c
index a22be406f5a..d98855d2887 100644
--- a/src/backend/optimizer/geqo/geqo_paths.c
+++ b/src/backend/optimizer/geqo/geqo_paths.c
@@ -1,11 +1,11 @@
/*-------------------------------------------------------------------------
*
* geqo_paths.c--
- * Routines to process redundant paths and relations
+ * Routines to process redundant paths and relations
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_paths.c,v 1.4 1997/06/11 02:44:12 vadim Exp $
+ * $Id: geqo_paths.c,v 1.5 1997/09/07 04:43:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,120 +28,128 @@
#include "optimizer/geqo_paths.h"
-static List *geqo_prune_rel(Rel *rel, List *other_rels);
-static Path *set_paths(Rel *rel, Path *unorderedpath);
+static List *geqo_prune_rel(Rel * rel, List * other_rels);
+static Path *set_paths(Rel * rel, Path * unorderedpath);
-/*
+/*
* geqo-prune-rels--
- * Removes any redundant relation entries from a list of rel nodes
- * 'rel-list'.
- *
- * Returns the resulting list.
- *
+ * Removes any redundant relation entries from a list of rel nodes
+ * 'rel-list'.
+ *
+ * Returns the resulting list.
+ *
*/
-List *geqo_prune_rels(List *rel_list)
+List *
+geqo_prune_rels(List * rel_list)
{
- List *temp_list = NIL;
-
- if (rel_list != NIL) {
- temp_list = lcons(lfirst(rel_list),
- geqo_prune_rels(geqo_prune_rel((Rel*)lfirst(rel_list),
- lnext(rel_list))));
- }
- return(temp_list);
+ List *temp_list = NIL;
+
+ if (rel_list != NIL)
+ {
+ temp_list = lcons(lfirst(rel_list),
+ geqo_prune_rels(geqo_prune_rel((Rel *) lfirst(rel_list),
+ lnext(rel_list))));
+ }
+ return (temp_list);
}
-/*
+/*
* geqo-prune-rel--
- * Prunes those relations from 'other-rels' that are redundant with
- * 'rel'. A relation is redundant if it is built up of the same
- * relations as 'rel'. Paths for the redundant relation are merged into
- * the pathlist of 'rel'.
- *
+ * Prunes those relations from 'other-rels' that are redundant with
+ * 'rel'. A relation is redundant if it is built up of the same
+ * relations as 'rel'. Paths for the redundant relation are merged into
+ * the pathlist of 'rel'.
+ *
* Returns a list of non-redundant relations, and sets the pathlist field
* of 'rel' appropriately.
- *
+ *
*/
-static List *
-geqo_prune_rel(Rel *rel, List *other_rels)
+static List *
+geqo_prune_rel(Rel * rel, List * other_rels)
{
- List *i = NIL;
- List *t_list = NIL;
- List *temp_node = NIL;
- Rel *other_rel = (Rel *)NULL;
-
- foreach(i, other_rels) {
- other_rel = (Rel*)lfirst(i);
- if(same(rel->relids, other_rel->relids)) {
- rel->pathlist = add_pathlist(rel,
- rel->pathlist,
- other_rel->pathlist);
- t_list = nconc(t_list, NIL); /* XXX is this right ? */
- } else {
- temp_node = lcons(other_rel, NIL);
- t_list = nconc(t_list,temp_node);
- }
- }
- return(t_list);
+ List *i = NIL;
+ List *t_list = NIL;
+ List *temp_node = NIL;
+ Rel *other_rel = (Rel *) NULL;
+
+ foreach(i, other_rels)
+ {
+ other_rel = (Rel *) lfirst(i);
+ if (same(rel->relids, other_rel->relids))
+ {
+ rel->pathlist = add_pathlist(rel,
+ rel->pathlist,
+ other_rel->pathlist);
+ t_list = nconc(t_list, NIL); /* XXX is this right ? */
+ }
+ else
+ {
+ temp_node = lcons(other_rel, NIL);
+ t_list = nconc(t_list, temp_node);
+ }
+ }
+ return (t_list);
}
-/*
+/*
* geqo-rel-paths--
- * For a relation 'rel' (which corresponds to a join
- * relation), set pointers to the unordered path and cheapest paths
- * (if the unordered path isn't the cheapest, it is pruned), and
- * reset the relation's size field to reflect the join.
- *
+ * For a relation 'rel' (which corresponds to a join
+ * relation), set pointers to the unordered path and cheapest paths
+ * (if the unordered path isn't the cheapest, it is pruned), and
+ * reset the relation's size field to reflect the join.
+ *
* Returns nothing of interest.
- *
+ *
*/
void
-geqo_rel_paths(Rel *rel)
+geqo_rel_paths(Rel * rel)
{
- List *y = NIL;
- Path *path = (Path*)NULL;
- JoinPath *cheapest = (JoinPath*)NULL;
-
- rel->size = 0;
- foreach(y, rel->pathlist)
- {
- path = (Path*)lfirst(y);
-
- if(!path->p_ordering.ord.sortop)
+ List *y = NIL;
+ Path *path = (Path *) NULL;
+ JoinPath *cheapest = (JoinPath *) NULL;
+
+ rel->size = 0;
+ foreach(y, rel->pathlist)
+ {
+ path = (Path *) lfirst(y);
+
+ if (!path->p_ordering.ord.sortop)
break;
- }
+ }
- cheapest = (JoinPath*)set_paths(rel, path);
- if ( IsA_JoinPath (cheapest) )
- rel->size = compute_joinrel_size(cheapest);
+ cheapest = (JoinPath *) set_paths(rel, path);
+ if (IsA_JoinPath(cheapest))
+ rel->size = compute_joinrel_size(cheapest);
}
-/*
+/*
* set-path--
- * Compares the unordered path for a relation with the cheapest path. If
- * the unordered path is not cheapest, it is pruned.
- *
- * Resets the pointers in 'rel' for unordered and cheapest paths.
- *
+ * Compares the unordered path for a relation with the cheapest path. If
+ * the unordered path is not cheapest, it is pruned.
+ *
+ * Resets the pointers in 'rel' for unordered and cheapest paths.
+ *
* Returns the cheapest path.
- *
+ *
*/
-static Path *
-set_paths(Rel *rel, Path *unorderedpath)
+static Path *
+set_paths(Rel * rel, Path * unorderedpath)
{
- Path *cheapest = set_cheapest(rel, rel->pathlist);
-
- /* don't prune if not pruneable -- JMH, 11/23/92 */
- if(unorderedpath != cheapest
- && rel->pruneable) {
-
- rel->unorderedpath = (Path *)NULL;
- rel->pathlist = lremove(unorderedpath, rel->pathlist);
- } else {
- rel->unorderedpath = (Path *)unorderedpath;
- }
-
- return(cheapest);
+ Path *cheapest = set_cheapest(rel, rel->pathlist);
+
+ /* don't prune if not pruneable -- JMH, 11/23/92 */
+ if (unorderedpath != cheapest
+ && rel->pruneable)
+ {
+
+ rel->unorderedpath = (Path *) NULL;
+ rel->pathlist = lremove(unorderedpath, rel->pathlist);
+ }
+ else
+ {
+ rel->unorderedpath = (Path *) unorderedpath;
+ }
+
+ return (cheapest);
}
-
diff --git a/src/backend/optimizer/geqo/geqo_pmx.c b/src/backend/optimizer/geqo/geqo_pmx.c
index c6e699cfa9f..c9187fec54b 100644
--- a/src/backend/optimizer/geqo/geqo_pmx.c
+++ b/src/backend/optimizer/geqo/geqo_pmx.c
@@ -2,35 +2,35 @@
*
* geqo_pmx.c--
*
-* partially matched crossover [PMX] routines;
-* PMX operator according to Goldberg & Lingle
-* (Proc Int'l Conf on GA's)
+* partially matched crossover [PMX] routines;
+* PMX operator according to Goldberg & Lingle
+* (Proc Int'l Conf on GA's)
*
-* $Id: geqo_pmx.c,v 1.1 1997/02/19 12:57:28 scrappy Exp $
+* $Id: geqo_pmx.c,v 1.2 1997/09/07 04:43:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* the pmx algorithm is adopted from Genitor : */
/*************************************************************/
-/* */
-/* Copyright (c) 1990 */
-/* Darrell L. Whitley */
-/* Computer Science Department */
-/* Colorado State University */
-/* */
-/* Permission is hereby granted to copy all or any part of */
-/* this program for free distribution. The author's name */
-/* and this copyright notice must be included in any copy. */
-/* */
+/* */
+/* Copyright (c) 1990 */
+/* Darrell L. Whitley */
+/* Computer Science Department */
+/* Colorado State University */
+/* */
+/* Permission is hereby granted to copy all or any part of */
+/* this program for free distribution. The author's name */
+/* and this copyright notice must be included in any copy. */
+/* */
/*************************************************************/
#include "postgres.h"
@@ -56,155 +56,182 @@
/* pmx--
*
- * partially matched crossover
+ * partially matched crossover
*/
void
-pmx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene)
+pmx(Gene * tour1, Gene * tour2, Gene * offspring, int num_gene)
{
- int *failed = (int *) palloc ((num_gene+1)*sizeof(int));
- int *from = (int *) palloc ((num_gene+1)*sizeof(int));
- int *indx = (int *) palloc ((num_gene+1)*sizeof(int));
- int *check_list = (int *) palloc ((num_gene+1)*sizeof(int));
+ int *failed = (int *) palloc((num_gene + 1) * sizeof(int));
+ int *from = (int *) palloc((num_gene + 1) * sizeof(int));
+ int *indx = (int *) palloc((num_gene + 1) * sizeof(int));
+ int *check_list = (int *) palloc((num_gene + 1) * sizeof(int));
+
+ int left,
+ right,
+ temp,
+ i,
+ j,
+ k;
+ int mx_fail,
+ found,
+ mx_hold;
- int left, right, temp, i, j, k;
- int mx_fail, found, mx_hold;
-
/* no mutation so start up the pmx replacement algorithm */
/* initialize failed[], from[], check_list[] */
- for (k = 0; k < num_gene; k++) {
- failed[k] = -1;
- from[k] = -1;
- check_list[k+1] = 0;
- }
-
+ for (k = 0; k < num_gene; k++)
+ {
+ failed[k] = -1;
+ from[k] = -1;
+ check_list[k + 1] = 0;
+ }
+
/* locate crossover points */
- left = geqo_randint(num_gene-1, 0);
- right = geqo_randint(num_gene-1, 0);
+ left = geqo_randint(num_gene - 1, 0);
+ right = geqo_randint(num_gene - 1, 0);
- if (left > right) {
- temp = left;
- left = right;
- right = temp;
- }
+ if (left > right)
+ {
+ temp = left;
+ left = right;
+ right = temp;
+ }
/* copy tour2 into offspring */
- for (k = 0; k < num_gene; k++) {
- offspring[k] = tour2[k];
- from[k] = DAD;
- check_list[tour2[k]]++;
- }
-
+ for (k = 0; k < num_gene; k++)
+ {
+ offspring[k] = tour2[k];
+ from[k] = DAD;
+ check_list[tour2[k]]++;
+ }
+
/* copy tour1 into offspring */
- for (k = left; k <= right; k++) {
- check_list[offspring[k]]--;
- offspring[k] = tour1[k];
- from[k] = MOM;
- check_list[tour1[k]]++;
- }
+ for (k = left; k <= right; k++)
+ {
+ check_list[offspring[k]]--;
+ offspring[k] = tour1[k];
+ from[k] = MOM;
+ check_list[tour1[k]]++;
+ }
/* pmx main part */
- mx_fail = 0;
+ mx_fail = 0;
/* STEP 1 */
- for (k = left; k <= right; k++) { /* for all elements in the tour1-2 */
-
- if (tour1[k] == tour2[k]) found = 1; /* find match in tour2 */
+ for (k = left; k <= right; k++)
+ { /* for all elements in the tour1-2 */
- else {
- found = 0; /* substitute elements */
+ if (tour1[k] == tour2[k])
+ found = 1; /* find match in tour2 */
- j = 0;
- while ( !(found) && (j < num_gene) ) {
- if ( (offspring[j] == tour1[k]) && (from[j] == DAD) ) {
+ else
+ {
+ found = 0; /* substitute elements */
- check_list[offspring[j]]--;
- offspring[j] = tour2[k];
- found = 1;
- check_list[tour2[k]]++;
- }
+ j = 0;
+ while (!(found) && (j < num_gene))
+ {
+ if ((offspring[j] == tour1[k]) && (from[j] == DAD))
+ {
- j++;
- }
+ check_list[offspring[j]]--;
+ offspring[j] = tour2[k];
+ found = 1;
+ check_list[tour2[k]]++;
+ }
- }
+ j++;
+ }
- if ( !(found) ) { /* failed to replace gene */
- failed[mx_fail] = (int) tour1[k];
- indx[mx_fail] = k;
- mx_fail++;
- }
-
- } /* ... for */
-
-
-/* STEP 2 */
+ }
- /* see if any genes could not be replaced */
- if (mx_fail > 0) {
- mx_hold = mx_fail;
+ if (!(found))
+ { /* failed to replace gene */
+ failed[mx_fail] = (int) tour1[k];
+ indx[mx_fail] = k;
+ mx_fail++;
+ }
- for (k = 0; k < mx_hold; k++) {
- found = 0;
+ } /* ... for */
- j = 0;
- while ( !(found) && (j < num_gene) ) {
- if ( (failed[k] == (int) offspring[j]) && (from[j] == DAD) ) {
- check_list[offspring[j]]--;
- offspring[j] = tour2[indx[k]];
- check_list[tour2[indx[k]]]++;
-
- found = 1;
- failed[k] = -1;
- mx_fail--;
- }
+/* STEP 2 */
- j++;
- }
+ /* see if any genes could not be replaced */
+ if (mx_fail > 0)
+ {
+ mx_hold = mx_fail;
- } /* ... for */
+ for (k = 0; k < mx_hold; k++)
+ {
+ found = 0;
- } /* ... if */
-
+ j = 0;
+ while (!(found) && (j < num_gene))
+ {
-/* STEP 3 */
+ if ((failed[k] == (int) offspring[j]) && (from[j] == DAD))
+ {
+ check_list[offspring[j]]--;
+ offspring[j] = tour2[indx[k]];
+ check_list[tour2[indx[k]]]++;
- for (k = 1; k <= num_gene; k++) {
+ found = 1;
+ failed[k] = -1;
+ mx_fail--;
+ }
- if (check_list[k] > 1) {
- i = 0;
+ j++;
+ }
- while (i < num_gene) {
- if ( (offspring[i] == (Gene) k) && (from[i] == DAD) ) {
- j = 1;
+ } /* ... for */
- while (j <= num_gene) {
- if (check_list[j] == 0) {
- offspring[i] = (Gene) j;
- check_list[k]--;
- check_list[j]++;
- i = num_gene + 1;
- j = i;
- }
+ } /* ... if */
- j++;
- }
- } /* ... if */
-
- i++;
- } /* end while */
+/* STEP 3 */
- }
- } /* ... for */
-
- pfree(failed);
- pfree(from);
- pfree(indx);
- pfree(check_list);
+ for (k = 1; k <= num_gene; k++)
+ {
+
+ if (check_list[k] > 1)
+ {
+ i = 0;
+
+ while (i < num_gene)
+ {
+ if ((offspring[i] == (Gene) k) && (from[i] == DAD))
+ {
+ j = 1;
+
+ while (j <= num_gene)
+ {
+ if (check_list[j] == 0)
+ {
+ offspring[i] = (Gene) j;
+ check_list[k]--;
+ check_list[j]++;
+ i = num_gene + 1;
+ j = i;
+ }
+
+ j++;
+ }
+
+ } /* ... if */
+
+ i++;
+ } /* end while */
+
+ }
+ } /* ... for */
+
+ pfree(failed);
+ pfree(from);
+ pfree(indx);
+ pfree(check_list);
}
diff --git a/src/backend/optimizer/geqo/geqo_pool.c b/src/backend/optimizer/geqo/geqo_pool.c
index 98a1a6e2a06..89c945d4ef4 100644
--- a/src/backend/optimizer/geqo/geqo_pool.c
+++ b/src/backend/optimizer/geqo/geqo_pool.c
@@ -1,20 +1,20 @@
/*------------------------------------------------------------------------
*
* geqo_pool.c--
- * Genetic Algorithm (GA) pool stuff
+ * Genetic Algorithm (GA) pool stuff
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_pool.c,v 1.1 1997/02/19 12:57:31 scrappy Exp $
+ * $Id: geqo_pool.c,v 1.2 1997/09/07 04:43:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
@@ -44,205 +44,220 @@
#include "optimizer/geqo_recombination.h"
-static int compare(void *arg1, void *arg2);
+static int compare(void *arg1, void *arg2);
/*
* alloc-pool--
- * allocates memory for GA pool
+ * allocates memory for GA pool
*/
-Pool *
+Pool *
alloc_pool(int pool_size, int string_length)
{
- Pool *new_pool;
- Chromosome *chromo;
- int i;
-
- /* pool */
- new_pool = (Pool *) palloc (sizeof(Pool));
- new_pool->size = (int) pool_size;
- new_pool->string_length = (int) string_length;
-
- /* all chromosome */
- new_pool->data = (Chromosome *) palloc (pool_size * sizeof(Chromosome));
-
- /* all gene */
- chromo = (Chromosome *) new_pool->data; /* vector of all chromos */
- for (i=0; i<pool_size; i++) {
- chromo[i].string = palloc((string_length+1)*sizeof(Gene));
+ Pool *new_pool;
+ Chromosome *chromo;
+ int i;
+
+ /* pool */
+ new_pool = (Pool *) palloc(sizeof(Pool));
+ new_pool->size = (int) pool_size;
+ new_pool->string_length = (int) string_length;
+
+ /* all chromosome */
+ new_pool->data = (Chromosome *) palloc(pool_size * sizeof(Chromosome));
+
+ /* all gene */
+ chromo = (Chromosome *) new_pool->data; /* vector of all chromos */
+ for (i = 0; i < pool_size; i++)
+ {
+ chromo[i].string = palloc((string_length + 1) * sizeof(Gene));
}
- return (new_pool);
+ return (new_pool);
}
/*
* free-pool--
- * deallocates memory for GA pool
+ * deallocates memory for GA pool
*/
void
-free_pool (Pool *pool)
+free_pool(Pool * pool)
{
- Chromosome *chromo;
- int i;
+ Chromosome *chromo;
+ int i;
- /* all gene */
- chromo = (Chromosome *) pool->data; /* vector of all chromos */
- for (i=0; i<pool->size; i++) pfree(chromo[i].string);
+ /* all gene */
+ chromo = (Chromosome *) pool->data; /* vector of all chromos */
+ for (i = 0; i < pool->size; i++)
+ pfree(chromo[i].string);
- /* all chromosome */
- pfree (pool->data);
+ /* all chromosome */
+ pfree(pool->data);
- /* pool */
- pfree (pool);
+ /* pool */
+ pfree(pool);
}
/*
* random-init-pool--
- * initialize genetic pool
+ * initialize genetic pool
*/
void
-random_init_pool (Query *root, Pool *pool, int strt, int stp)
+random_init_pool(Query * root, Pool * pool, int strt, int stp)
{
- Chromosome *chromo = (Chromosome *) pool->data;
- int i;
+ Chromosome *chromo = (Chromosome *) pool->data;
+ int i;
- for (i=strt; i<stp; i++) {
- init_tour(chromo[i].string, pool->string_length); /* from "geqo_recombination.c" */
+ for (i = strt; i < stp; i++)
+ {
+ init_tour(chromo[i].string, pool->string_length); /* from
+ * "geqo_recombination.c"
+ * */
- pool->data[i].worth =
- geqo_eval(root, chromo[i].string, pool->string_length); /* "from geqo_eval.c" */
+ pool->data[i].worth =
+ geqo_eval(root, chromo[i].string, pool->string_length); /* "from geqo_eval.c" */
}
}
/*
* sort-pool--
- * sorts input pool according to worth, from smallest to largest
+ * sorts input pool according to worth, from smallest to largest
*
- * maybe you have to change compare() for different ordering ...
+ * maybe you have to change compare() for different ordering ...
*/
void
-sort_pool(Pool *pool)
-{
- pg_qsort(pool->data, pool->size, sizeof(Chromosome), compare);
+sort_pool(Pool * pool)
+{
+ pg_qsort(pool->data, pool->size, sizeof(Chromosome), compare);
}
/*
* compare--
- * static input function for pg_sort
+ * static input function for pg_sort
*
- * return values for sort from smallest to largest are prooved!
- * don't change them!
+ * return values for sort from smallest to largest are prooved!
+ * don't change them!
*/
static int
compare(void *arg1, void *arg2)
{
- Chromosome chromo1 = *(Chromosome *) arg1;
- Chromosome chromo2 = *(Chromosome *) arg2;
-
- if (chromo1.worth == chromo2.worth)
- return(0);
- else if (chromo1.worth > chromo2.worth)
- return(1);
- else
- return(-1);
+ Chromosome chromo1 = *(Chromosome *) arg1;
+ Chromosome chromo2 = *(Chromosome *) arg2;
+
+ if (chromo1.worth == chromo2.worth)
+ return (0);
+ else if (chromo1.worth > chromo2.worth)
+ return (1);
+ else
+ return (-1);
}
/* alloc_chromo--
- * allocates a chromosome and string space
+ * allocates a chromosome and string space
*/
-Chromosome *
-alloc_chromo (int string_length)
+Chromosome *
+alloc_chromo(int string_length)
{
- Chromosome *chromo;
+ Chromosome *chromo;
+
+ chromo = (Chromosome *) palloc(sizeof(Chromosome));
+ chromo->string = (Gene *) palloc((string_length + 1) * sizeof(Gene));
- chromo = (Chromosome *) palloc (sizeof(Chromosome));
- chromo->string = (Gene *) palloc ((string_length+1)*sizeof(Gene));
-
- return (chromo);
+ return (chromo);
}
/* free_chromo--
- * deallocates a chromosome and string space
+ * deallocates a chromosome and string space
*/
void
-free_chromo (Chromosome *chromo)
+free_chromo(Chromosome * chromo)
{
- pfree(chromo->string);
- pfree(chromo);
+ pfree(chromo->string);
+ pfree(chromo);
}
/* spread_chromo--
- * inserts a new chromosome into the pool, displacing worst gene in pool
- * assumes best->worst = smallest->largest
+ * inserts a new chromosome into the pool, displacing worst gene in pool
+ * assumes best->worst = smallest->largest
*/
void
-spread_chromo (Chromosome *chromo, Pool *pool)
+spread_chromo(Chromosome * chromo, Pool * pool)
{
- int top, mid, bot;
- int i, index;
- Chromosome swap_chromo, tmp_chromo;
-
- /* new chromo is so bad we can't use it */
- if (chromo->worth > pool->data[pool->size-1].worth) return;
-
- /* do a binary search to find the index of the new chromo */
-
- top = 0;
- mid = pool->size/2;
- bot = pool->size-1;
- index = -1;
-
- while (index == -1) {
- /* these 4 cases find a new location */
-
- if (chromo->worth <= pool->data[top].worth)
- index = top;
- else
- if (chromo->worth == pool->data[mid].worth)
- index = mid;
- else
- if (chromo->worth == pool->data[bot].worth)
- index = bot;
- else
- if (bot-top <=1)
- index = bot;
-
-
- /* these 2 cases move the search indices since
- a new location has not yet been found. */
-
- else
- if (chromo->worth < pool->data[mid].worth) {
- bot = mid;
- mid = top + ( (bot-top)/2 );
- }
- else { /* (chromo->worth > pool->data[mid].worth) */
- top = mid;
- mid = top + ( (bot-top)/2 );
- }
- } /* ... while */
-
- /* now we have index for chromo */
-
- /* move every gene from index on down
- one position to make room for chromo */
-
- /* copy new gene into pool storage;
- always replace worst gene in pool */
-
- geqo_copy (&pool->data[pool->size-1], chromo, pool->string_length);
-
- swap_chromo.string = pool->data[pool->size-1].string;
- swap_chromo.worth = pool->data[pool->size-1].worth;
-
- for (i=index; i<pool->size; i++) {
- tmp_chromo.string = pool->data[i].string;
- tmp_chromo.worth = pool->data[i].worth;
-
- pool->data[i].string = swap_chromo.string;
- pool->data[i].worth = swap_chromo.worth;
-
- swap_chromo.string = tmp_chromo.string;
- swap_chromo.worth = tmp_chromo.worth;
- }
+ int top,
+ mid,
+ bot;
+ int i,
+ index;
+ Chromosome swap_chromo,
+ tmp_chromo;
+
+ /* new chromo is so bad we can't use it */
+ if (chromo->worth > pool->data[pool->size - 1].worth)
+ return;
+
+ /* do a binary search to find the index of the new chromo */
+
+ top = 0;
+ mid = pool->size / 2;
+ bot = pool->size - 1;
+ index = -1;
+
+ while (index == -1)
+ {
+ /* these 4 cases find a new location */
+
+ if (chromo->worth <= pool->data[top].worth)
+ index = top;
+ else if (chromo->worth == pool->data[mid].worth)
+ index = mid;
+ else if (chromo->worth == pool->data[bot].worth)
+ index = bot;
+ else if (bot - top <= 1)
+ index = bot;
+
+
+ /*
+ * these 2 cases move the search indices since a new location has
+ * not yet been found.
+ */
+
+ else if (chromo->worth < pool->data[mid].worth)
+ {
+ bot = mid;
+ mid = top + ((bot - top) / 2);
+ }
+ else
+ { /* (chromo->worth > pool->data[mid].worth) */
+ top = mid;
+ mid = top + ((bot - top) / 2);
+ }
+ } /* ... while */
+
+ /* now we have index for chromo */
+
+ /*
+ * move every gene from index on down one position to make room for
+ * chromo
+ */
+
+ /*
+ * copy new gene into pool storage; always replace worst gene in pool
+ */
+
+ geqo_copy(&pool->data[pool->size - 1], chromo, pool->string_length);
+
+ swap_chromo.string = pool->data[pool->size - 1].string;
+ swap_chromo.worth = pool->data[pool->size - 1].worth;
+
+ for (i = index; i < pool->size; i++)
+ {
+ tmp_chromo.string = pool->data[i].string;
+ tmp_chromo.worth = pool->data[i].worth;
+
+ pool->data[i].string = swap_chromo.string;
+ pool->data[i].worth = swap_chromo.worth;
+
+ swap_chromo.string = tmp_chromo.string;
+ swap_chromo.worth = tmp_chromo.worth;
+ }
}
diff --git a/src/backend/optimizer/geqo/geqo_px.c b/src/backend/optimizer/geqo/geqo_px.c
index f060561b516..71aa2415b55 100644
--- a/src/backend/optimizer/geqo/geqo_px.c
+++ b/src/backend/optimizer/geqo/geqo_px.c
@@ -2,35 +2,35 @@
*
* geqo_px.c--
*
-* position crossover [PX] routines;
-* PX operator according to Syswerda
-* (The Genetic Algorithms Handbook, L Davis, ed)
+* position crossover [PX] routines;
+* PX operator according to Syswerda
+* (The Genetic Algorithms Handbook, L Davis, ed)
*
-* $Id: geqo_px.c,v 1.1 1997/02/19 12:57:37 scrappy Exp $
+* $Id: geqo_px.c,v 1.2 1997/09/07 04:43:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* the px algorithm is adopted from Genitor : */
/*************************************************************/
-/* */
-/* Copyright (c) 1990 */
-/* Darrell L. Whitley */
-/* Computer Science Department */
-/* Colorado State University */
-/* */
-/* Permission is hereby granted to copy all or any part of */
-/* this program for free distribution. The author's name */
-/* and this copyright notice must be included in any copy. */
-/* */
+/* */
+/* Copyright (c) 1990 */
+/* Darrell L. Whitley */
+/* Computer Science Department */
+/* Colorado State University */
+/* */
+/* Permission is hereby granted to copy all or any part of */
+/* this program for free distribution. The author's name */
+/* and this copyright notice must be included in any copy. */
+/* */
/*************************************************************/
#include "postgres.h"
@@ -56,61 +56,70 @@
/* px--
*
- * position crossover
+ * position crossover
*/
void
-px(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
+px(Gene * tour1, Gene * tour2, Gene * offspring, int num_gene, City * city_table)
{
- int num_positions;
- int i, pos, tour2_index, offspring_index;
+ int num_positions;
+ int i,
+ pos,
+ tour2_index,
+ offspring_index;
- /* initialize city table */
- for (i=1; i<=num_gene; i++) {
- city_table[i].used = 0;
- }
+ /* initialize city table */
+ for (i = 1; i <= num_gene; i++)
+ {
+ city_table[i].used = 0;
+ }
- /* choose random positions that will be inherited directly from parent */
- num_positions = geqo_randint (2*num_gene/3, num_gene/3);
+ /* choose random positions that will be inherited directly from parent */
+ num_positions = geqo_randint(2 * num_gene / 3, num_gene / 3);
- /* choose random position */
- for (i=0; i<num_positions; i++) {
- pos = geqo_randint (num_gene - 1, 0);
+ /* choose random position */
+ for (i = 0; i < num_positions; i++)
+ {
+ pos = geqo_randint(num_gene - 1, 0);
- offspring[pos] = tour1[pos]; /* transfer cities to child */
- city_table[(int) tour1[pos]].used = 1; /* mark city used */
- }
+ offspring[pos] = tour1[pos]; /* transfer cities to child */
+ city_table[(int) tour1[pos]].used = 1; /* mark city used */
+ }
- tour2_index = 0;
- offspring_index = 0;
+ tour2_index = 0;
+ offspring_index = 0;
- /* px main part */
+ /* px main part */
- while (offspring_index < num_gene) {
+ while (offspring_index < num_gene)
+ {
- /* next position in offspring filled */
- if (!city_table[(int) tour1[offspring_index]].used) {
+ /* next position in offspring filled */
+ if (!city_table[(int) tour1[offspring_index]].used)
+ {
- /* next city in tour1 not used */
- if (!city_table[(int) tour2[tour2_index]].used) {
+ /* next city in tour1 not used */
+ if (!city_table[(int) tour2[tour2_index]].used)
+ {
- /* inherit from tour1 */
- offspring[offspring_index] = tour2[tour2_index];
+ /* inherit from tour1 */
+ offspring[offspring_index] = tour2[tour2_index];
- tour2_index++;
- offspring_index++;
- }
- else { /* next city in tour2 has been used */
- tour2_index++;
- }
+ tour2_index++;
+ offspring_index++;
+ }
+ else
+ { /* next city in tour2 has been used */
+ tour2_index++;
+ }
- }
- else { /* next position in offspring is filled */
- offspring_index++;
- }
+ }
+ else
+ { /* next position in offspring is filled */
+ offspring_index++;
+ }
- }
-
- }
+ }
+}
diff --git a/src/backend/optimizer/geqo/geqo_recombination.c b/src/backend/optimizer/geqo/geqo_recombination.c
index df175dcb866..53803079819 100644
--- a/src/backend/optimizer/geqo/geqo_recombination.c
+++ b/src/backend/optimizer/geqo/geqo_recombination.c
@@ -1,18 +1,18 @@
/*------------------------------------------------------------------------
*
* geqo_recombination.c--
-* misc recombination procedures
+* misc recombination procedures
*
-* $Id: geqo_recombination.c,v 1.1 1997/02/19 12:57:42 scrappy Exp $
+* $Id: geqo_recombination.c,v 1.2 1997/09/07 04:43:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
@@ -42,65 +42,70 @@
/*
* init_tour--
*
- * Randomly generates a legal "traveling salesman" tour
- * (i.e. where each point is visited only once.)
- * Essentially, this routine fills an array with all possible
- * points on the tour and randomly chooses the 'next' city from
- * this array. When a city is chosen, the array is shortened
- * and the procedure repeated.
+ * Randomly generates a legal "traveling salesman" tour
+ * (i.e. where each point is visited only once.)
+ * Essentially, this routine fills an array with all possible
+ * points on the tour and randomly chooses the 'next' city from
+ * this array. When a city is chosen, the array is shortened
+ * and the procedure repeated.
*
*/
void
-init_tour(Gene *tour, int num_gene)
+init_tour(Gene * tour, int num_gene)
{
-Gene *tmp;
-int remainder;
-int next, i;
+ Gene *tmp;
+ int remainder;
+ int next,
+ i;
-tmp = (Gene *) palloc (num_gene*sizeof(Gene));
-
-for(i = 0; i < num_gene; i++) {
- tmp[i] = (Gene) i+1; /* builds tours "1 - 2 - 3" etc. */
- }
+ tmp = (Gene *) palloc(num_gene * sizeof(Gene));
-remainder = num_gene - 1;
+ for (i = 0; i < num_gene; i++)
+ {
+ tmp[i] = (Gene) i + 1; /* builds tours "1 - 2 - 3" etc. */
+ }
-for(i = 0; i < num_gene; i++) {
- next = (int) geqo_randint(remainder, 0); /* choose city between 0 and remainder */
- tour[i] = tmp[next];
- tmp[next] = tmp[remainder];
- remainder--;
- }
+ remainder = num_gene - 1;
-pfree(tmp);
-}
+ for (i = 0; i < num_gene; i++)
+ {
+ next = (int) geqo_randint(remainder, 0); /* choose city between 0
+ * and remainder */
+ tour[i] = tmp[next];
+ tmp[next] = tmp[remainder];
+ remainder--;
+ }
+
+ pfree(tmp);
+}
/* alloc_city_table--
*
- * allocate memory for city table
+ * allocate memory for city table
*
*/
-City *
+City *
alloc_city_table(int num_gene)
{
- City *city_table;
+ City *city_table;
- /* palloc one extra location so that nodes numbered
- 1..n can be indexed directly; 0 will not be used */
+ /*
+ * palloc one extra location so that nodes numbered 1..n can be
+ * indexed directly; 0 will not be used
+ */
- city_table = (City *) palloc ((num_gene+1)*sizeof(City));
+ city_table = (City *) palloc((num_gene + 1) * sizeof(City));
- return (city_table);
- }
+ return (city_table);
+}
/* free_city_table--
*
- * deallocate memory of city table
+ * deallocate memory of city table
*
*/
- void
- free_city_table(City *city_table)
- {
- pfree(city_table);
- }
-
+void
+free_city_table(City * city_table)
+{
+ pfree(city_table);
+}
diff --git a/src/backend/optimizer/geqo/geqo_selection.c b/src/backend/optimizer/geqo/geqo_selection.c
index 0c6502003bd..820de485fe4 100644
--- a/src/backend/optimizer/geqo/geqo_selection.c
+++ b/src/backend/optimizer/geqo/geqo_selection.c
@@ -1,36 +1,36 @@
/*-------------------------------------------------------------------------
*
* geqo_selection.c--
- * linear selection scheme for the genetic query optimizer
+ * linear selection scheme for the genetic query optimizer
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_selection.c,v 1.1 1997/02/19 12:57:46 scrappy Exp $
+ * $Id: geqo_selection.c,v 1.2 1997/09/07 04:43:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* this is adopted from D. Whitley's Genitor algorithm */
/*************************************************************/
-/* */
-/* Copyright (c) 1990 */
-/* Darrell L. Whitley */
-/* Computer Science Department */
-/* Colorado State University */
-/* */
-/* Permission is hereby granted to copy all or any part of */
-/* this program for free distribution. The author's name */
-/* and this copyright notice must be included in any copy. */
-/* */
+/* */
+/* Copyright (c) 1990 */
+/* Darrell L. Whitley */
+/* Computer Science Department */
+/* Colorado State University */
+/* */
+/* Permission is hereby granted to copy all or any part of */
+/* this program for free distribution. The author's name */
+/* and this copyright notice must be included in any copy. */
+/* */
/*************************************************************/
#include <math.h>
@@ -55,49 +55,51 @@
#include "optimizer/geqo_copy.h"
#include "optimizer/geqo_random.h"
-static int linear(int max, double bias);
+static int linear(int max, double bias);
/* geqo_selection--
*
- * according to bias described by input parameters,
- * second genes are selected from the pool
+ * according to bias described by input parameters,
+ * second genes are selected from the pool
*/
void
-geqo_selection (Chromosome *momma, Chromosome *daddy, Pool *pool, double bias)
+geqo_selection(Chromosome * momma, Chromosome * daddy, Pool * pool, double bias)
{
- int first, second;
-
- first = (int) linear(pool->size, bias);
- second = (int) linear(pool->size, bias);
-
- if (pool->size > 1) {
- while(first==second)
- second = (int) linear(pool->size, bias);
- }
-
- geqo_copy (momma, &pool->data[first], pool->string_length);
- geqo_copy (daddy, &pool->data[second], pool->string_length);
+ int first,
+ second;
+
+ first = (int) linear(pool->size, bias);
+ second = (int) linear(pool->size, bias);
+
+ if (pool->size > 1)
+ {
+ while (first == second)
+ second = (int) linear(pool->size, bias);
+ }
+
+ geqo_copy(momma, &pool->data[first], pool->string_length);
+ geqo_copy(daddy, &pool->data[second], pool->string_length);
}
/* linear--
- * generates random integer between 0 and input max number
- * using input linear bias
+ * generates random integer between 0 and input max number
+ * using input linear bias
*
- * probability distribution function is: f(x) = bias - 2(bias - 1)x
- * bias = (prob of first rule) / (prob of middle rule)
+ * probability distribution function is: f(x) = bias - 2(bias - 1)x
+ * bias = (prob of first rule) / (prob of middle rule)
*
*/
static int
-linear(int pool_size, double bias) /* bias is y-intercept of linear distribution */
+linear(int pool_size, double bias) /* bias is y-intercept of linear
+ * distribution */
{
- double index; /* index between 0 and pop_size */
- double max = (double) pool_size;
+ double index; /* index between 0 and pop_size */
+ double max = (double) pool_size;
- index =
- max*( bias - sqrt ( (bias*bias) - 4.0*(bias-1.0)*geqo_rand() ) )
- / 2.0 / (bias-1.0);
+ index =
+ max * (bias - sqrt((bias * bias) - 4.0 * (bias - 1.0) * geqo_rand()))
+ / 2.0 / (bias - 1.0);
- return((int) index);
+ return ((int) index);
}
-
diff --git a/src/backend/optimizer/geqo/minspantree.c b/src/backend/optimizer/geqo/minspantree.c
index 4e4c2ad11b4..1fcc2569478 100644
--- a/src/backend/optimizer/geqo/minspantree.c
+++ b/src/backend/optimizer/geqo/minspantree.c
@@ -1,13 +1,13 @@
/*------------------------------------------------------------------------
*
* minspantree.c--
-* routine to sort a join graph which is including cycles
+* routine to sort a join graph which is including cycles
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
-* $Header: /cvsroot/pgsql/src/backend/optimizer/geqo/Attic/minspantree.c,v 1.1 1997/02/19 12:57:50 scrappy Exp $
+* $Header: /cvsroot/pgsql/src/backend/optimizer/geqo/Attic/minspantree.c,v 1.2 1997/09/07 04:43:25 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,166 +33,181 @@
/*
* minspantree--
- * The function minspantree computes the minimum spanning tree
- * for a given number of nodes and a given distance function.
- * For each pair of nodes found to be connected, a given
- * function is called. Nodes are denoted by the integer numbers
- * 1 .. number_of_joins, where number_of_joins is the number of nodes.
+ * The function minspantree computes the minimum spanning tree
+ * for a given number of nodes and a given distance function.
+ * For each pair of nodes found to be connected, a given
+ * function is called. Nodes are denoted by the integer numbers
+ * 1 .. number_of_joins, where number_of_joins is the number of nodes.
*/
void
-minspantree(Query *root, List *join_rels, Rel *garel)
+minspantree(Query * root, List * join_rels, Rel * garel)
{
- int number_of_rels = length(root->base_relation_list_);
- int number_of_joins = length(join_rels);
- int *connectto;
- /* connectto[i] = 0, if node i is already connected */
- /* to the tree, otherwise connectto[i] is the node */
- /* nearest to i, which is already connected. */
-
- Cost *disttoconnect; /* disttoconnect[i]: distance between i and connectto[i] */
-
- Cost dist, /* temporary */
- mindist; /* minimal distance between connected and unconnected node */
-
- Cost mstlength = 0.0; /* the total length of the minimum spanning tree */
-
- int count;
- int n, /* newly attached node */
- nextn, /* next node to be attached */
- tempn;
-
- int i, id1, id2;
- List *r = NIL;
- Rel *joinrel = NULL;
- Rel **tmprel_array;
-
-
- /* allocate memory for matrix tmprel_array[x][y] */
- tmprel_array = (Rel **) palloc((number_of_rels+1)*sizeof(Rel *));
- for (i=0; i<=number_of_rels; i++)
- (tmprel_array[i] = (Rel *) palloc ((number_of_rels+1)*sizeof(Rel)));
-
- /* read relations of join-relations into tmprel_array */
-
- foreach(r, join_rels) {
- joinrel = (Rel *)lfirst(r);
- id1 = (int)lfirst(joinrel->relids);
- id2 = (int)lsecond(joinrel->relids);
-
- if (id1 > id2) {
- tmprel_array[id2][id1] = *(Rel *)joinrel;
- }
- else {
- tmprel_array[id1][id2] = *(Rel *)joinrel; /* ever reached? */
- }
- }
-
- /* Trivial special cases handled first */
- /* garel is global in "tsp.h" */
-
- if (number_of_joins <= 2)
- {
- i=1;
- foreach(r, join_rels) {
- garel[i] = *(Rel *)lfirst(r);
- i++;
- }
- }
-
-
- else if (number_of_joins == 3)
- {
- Rel *rel12 = (Rel *) &tmprel_array[1][2];
- Rel *rel13 = (Rel *) &tmprel_array[1][3];
- Rel *rel23 = (Rel *) &tmprel_array[2][3];
- if (rel12->cheapestpath->path_cost > rel13->cheapestpath->path_cost)
- {
- garel[1] = tmprel_array[1][3];
- if (rel12->cheapestpath->path_cost > rel23->cheapestpath->path_cost)
+ int number_of_rels = length(root->base_relation_list_);
+ int number_of_joins = length(join_rels);
+ int *connectto;
+
+ /* connectto[i] = 0, if node i is already connected */
+ /* to the tree, otherwise connectto[i] is the node */
+ /* nearest to i, which is already connected. */
+
+ Cost *disttoconnect; /* disttoconnect[i]: distance
+ * between i and connectto[i] */
+
+ Cost dist, /* temporary */
+ mindist; /* minimal distance between connected and
+ * unconnected node */
+
+ Cost mstlength = 0.0; /* the total length of the minimum
+ * spanning tree */
+
+ int count;
+ int n, /* newly attached node */
+ nextn, /* next node to be attached */
+ tempn;
+
+ int i,
+ id1,
+ id2;
+ List *r = NIL;
+ Rel *joinrel = NULL;
+ Rel **tmprel_array;
+
+
+ /* allocate memory for matrix tmprel_array[x][y] */
+ tmprel_array = (Rel **) palloc((number_of_rels + 1) * sizeof(Rel *));
+ for (i = 0; i <= number_of_rels; i++)
+ (tmprel_array[i] = (Rel *) palloc((number_of_rels + 1) * sizeof(Rel)));
+
+ /* read relations of join-relations into tmprel_array */
+
+ foreach(r, join_rels)
{
- garel[2] = tmprel_array[2][3];
+ joinrel = (Rel *) lfirst(r);
+ id1 = (int) lfirst(joinrel->relids);
+ id2 = (int) lsecond(joinrel->relids);
+
+ if (id1 > id2)
+ {
+ tmprel_array[id2][id1] = *(Rel *) joinrel;
+ }
+ else
+ {
+ tmprel_array[id1][id2] = *(Rel *) joinrel; /* ever reached? */
+ }
}
- else
+
+ /* Trivial special cases handled first */
+ /* garel is global in "tsp.h" */
+
+ if (number_of_joins <= 2)
{
- garel[2] = tmprel_array[1][2];
+ i = 1;
+ foreach(r, join_rels)
+ {
+ garel[i] = *(Rel *) lfirst(r);
+ i++;
+ }
}
- }
- else
- {
- garel[1] = tmprel_array[1][2];
- if (rel13->cheapestpath->path_cost > rel23->cheapestpath->path_cost)
+
+
+ else if (number_of_joins == 3)
{
- garel[2] = tmprel_array[2][3];
+ Rel *rel12 = (Rel *) & tmprel_array[1][2];
+ Rel *rel13 = (Rel *) & tmprel_array[1][3];
+ Rel *rel23 = (Rel *) & tmprel_array[2][3];
+
+ if (rel12->cheapestpath->path_cost > rel13->cheapestpath->path_cost)
+ {
+ garel[1] = tmprel_array[1][3];
+ if (rel12->cheapestpath->path_cost > rel23->cheapestpath->path_cost)
+ {
+ garel[2] = tmprel_array[2][3];
+ }
+ else
+ {
+ garel[2] = tmprel_array[1][2];
+ }
+ }
+ else
+ {
+ garel[1] = tmprel_array[1][2];
+ if (rel13->cheapestpath->path_cost > rel23->cheapestpath->path_cost)
+ {
+ garel[2] = tmprel_array[2][3];
+ }
+ else
+ {
+ garel[2] = tmprel_array[1][3];
+ }
+ }
}
+
+
+ /* now the general case */
else
{
- garel[2] = tmprel_array[1][3];
- }
- }
- }
-
-
- /* now the general case */
- else
- {
- connectto = (int *) palloc((number_of_rels+1)*sizeof(int));
- disttoconnect = (Cost *) palloc((number_of_rels+1)*sizeof(Cost));
-
- nextn = 2;
- for (tempn = 2; tempn <= number_of_rels; tempn++ )
- {
- connectto[tempn] = 1;
- disttoconnect[tempn] = (Cost) MAXFLOAT;
- }
-
- joinrel = NULL;
- n = 1;
- i = 1;
- for (count = 2; count <= number_of_rels; count++ )
- {
- connectto[n] = 0;
- mindist = (Cost) MAXFLOAT;
- for (tempn = 2; tempn <= number_of_rels; tempn++ )
- {
- if (connectto[tempn] != 0)
- {
- if (n > tempn) {
- joinrel = (Rel *) &tmprel_array[tempn][n];
- }
- else {
- joinrel = (Rel *) &tmprel_array[n][tempn];
- }
- dist = joinrel->cheapestpath->path_cost;
-
- if (dist < disttoconnect[tempn])
- {
- disttoconnect[tempn] = dist;
- connectto[tempn] = n;
- }
- if (disttoconnect[tempn] < mindist)
- {
- mindist = disttoconnect[tempn];
- nextn = tempn;
+ connectto = (int *) palloc((number_of_rels + 1) * sizeof(int));
+ disttoconnect = (Cost *) palloc((number_of_rels + 1) * sizeof(Cost));
+
+ nextn = 2;
+ for (tempn = 2; tempn <= number_of_rels; tempn++)
+ {
+ connectto[tempn] = 1;
+ disttoconnect[tempn] = (Cost) MAXFLOAT;
+ }
+
+ joinrel = NULL;
+ n = 1;
+ i = 1;
+ for (count = 2; count <= number_of_rels; count++)
+ {
+ connectto[n] = 0;
+ mindist = (Cost) MAXFLOAT;
+ for (tempn = 2; tempn <= number_of_rels; tempn++)
+ {
+ if (connectto[tempn] != 0)
+ {
+ if (n > tempn)
+ {
+ joinrel = (Rel *) & tmprel_array[tempn][n];
+ }
+ else
+ {
+ joinrel = (Rel *) & tmprel_array[n][tempn];
+ }
+ dist = joinrel->cheapestpath->path_cost;
+
+ if (dist < disttoconnect[tempn])
+ {
+ disttoconnect[tempn] = dist;
+ connectto[tempn] = n;
+ }
+ if (disttoconnect[tempn] < mindist)
+ {
+ mindist = disttoconnect[tempn];
+ nextn = tempn;
+ }
+ }
+ }
+ n = nextn;
+ if (n > connectto[n])
+ {
+ garel[i] = tmprel_array[connectto[n]][n];
+ }
+ else
+ {
+ garel[i] = tmprel_array[n][connectto[n]];
+ }
+ i++;
+ }
+
+ pfree(connectto);
+ pfree(disttoconnect);
+
}
- }
- }
- n = nextn;
- if (n > connectto[n]) {
- garel[i] = tmprel_array[connectto[n]][n];
- }
- else {
- garel[i] = tmprel_array[n][connectto[n]];
- }
- i++;
- }
-
- pfree(connectto);
- pfree(disttoconnect);
-
- }
-
- for (i=0; i<=number_of_rels; i++) pfree(tmprel_array[i]);
- pfree(tmprel_array);
-}
+ for (i = 0; i <= number_of_rels; i++)
+ pfree(tmprel_array[i]);
+ pfree(tmprel_array);
+}
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index d27b31cfbd7..7c4576d6f02 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* allpaths.c--
- * Routines to find possible search paths for processing a query
+ * Routines to find possible search paths for processing a query
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.10 1997/06/10 07:55:45 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.11 1997/09/07 04:43:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,226 +34,245 @@
#include "optimizer/geqo.h"
#ifdef GEQO
-bool _use_geqo_ = true;
+bool _use_geqo_ = true;
+
#else
-bool _use_geqo_ = false;
+bool _use_geqo_ = false;
+
#endif
-int32 _use_geqo_rels_ = GEQO_RELS;
+int32 _use_geqo_rels_ = GEQO_RELS;
-static void find_rel_paths(Query *root, List *rels);
-static List *find_join_paths(Query *root, List *outer_rels, int levels_left);
+static void find_rel_paths(Query * root, List * rels);
+static List *find_join_paths(Query * root, List * outer_rels, int levels_left);
-/*
+/*
* find-paths--
- * Finds all possible access paths for executing a query, returning the
- * top level list of relation entries.
- *
+ * Finds all possible access paths for executing a query, returning the
+ * top level list of relation entries.
+ *
* 'rels' is the list of single relation entries appearing in the query
*/
-List *
-find_paths(Query *root, List *rels)
+List *
+find_paths(Query * root, List * rels)
{
- int levels_left;
-
- /*
- * Set the number of join (not nesting) levels yet to be processed.
- */
- levels_left = length(rels);
-
- if (levels_left <= 0)
- return NIL;
-
- /*
- * Find the base relation paths.
- */
- find_rel_paths(root, rels);
-
- if (levels_left <= 1) {
+ int levels_left;
+
/*
- * Unsorted single relation, no more processing is required.
+ * Set the number of join (not nesting) levels yet to be processed.
*/
- return (rels);
- }else {
- /*
- * this means that joins or sorts are required.
- * set selectivities of clauses that have not been set
- * by an index.
+ levels_left = length(rels);
+
+ if (levels_left <= 0)
+ return NIL;
+
+ /*
+ * Find the base relation paths.
*/
- set_rest_relselec(root, rels);
+ find_rel_paths(root, rels);
+
+ if (levels_left <= 1)
+ {
- return(find_join_paths(root, rels, levels_left-1));
- }
+ /*
+ * Unsorted single relation, no more processing is required.
+ */
+ return (rels);
+ }
+ else
+ {
+
+ /*
+ * this means that joins or sorts are required. set selectivities
+ * of clauses that have not been set by an index.
+ */
+ set_rest_relselec(root, rels);
+
+ return (find_join_paths(root, rels, levels_left - 1));
+ }
}
-/*
+/*
* find-rel-paths--
- * Finds all paths available for scanning each relation entry in
- * 'rels'. Sequential scan and any available indices are considered
- * if possible(indices are not considered for lower nesting levels).
- * All unique paths are attached to the relation's 'pathlist' field.
- *
- * MODIFIES: rels
+ * Finds all paths available for scanning each relation entry in
+ * 'rels'. Sequential scan and any available indices are considered
+ * if possible(indices are not considered for lower nesting levels).
+ * All unique paths are attached to the relation's 'pathlist' field.
+ *
+ * MODIFIES: rels
*/
static void
-find_rel_paths(Query *root, List *rels)
+find_rel_paths(Query * root, List * rels)
{
- List *temp;
- Rel *rel;
- List *lastpath;
-
- foreach(temp, rels) {
- List *sequential_scan_list;
- List *rel_index_scan_list;
- List *or_index_scan_list;
-
- rel = (Rel *)lfirst(temp);
- sequential_scan_list = lcons(create_seqscan_path(rel),
- NIL);
-
- rel_index_scan_list =
- find_index_paths(root,
- rel,
- find_relation_indices(root,rel),
- rel->clauseinfo,
- rel->joininfo);
-
- or_index_scan_list =
- create_or_index_paths(root, rel, rel->clauseinfo);
-
- rel->pathlist = add_pathlist(rel,
- sequential_scan_list,
- append(rel_index_scan_list,
- or_index_scan_list));
-
- /* The unordered path is always the last in the list.
- * If it is not the cheapest path, prune it.
- */
- lastpath = rel->pathlist;
- while(lnext(lastpath)!=NIL)
- lastpath=lnext(lastpath);
- prune_rel_path(rel, (Path*)lfirst(lastpath));
- /*
- * if there is a qualification of sequential scan the selec.
- * value is not set -- so set it explicitly -- Sunita
- */
- set_rest_selec(root, rel->clauseinfo);
- rel->size = compute_rel_size(rel);
- rel->width = compute_rel_width(rel);
- }
- return;
+ List *temp;
+ Rel *rel;
+ List *lastpath;
+
+ foreach(temp, rels)
+ {
+ List *sequential_scan_list;
+ List *rel_index_scan_list;
+ List *or_index_scan_list;
+
+ rel = (Rel *) lfirst(temp);
+ sequential_scan_list = lcons(create_seqscan_path(rel),
+ NIL);
+
+ rel_index_scan_list =
+ find_index_paths(root,
+ rel,
+ find_relation_indices(root, rel),
+ rel->clauseinfo,
+ rel->joininfo);
+
+ or_index_scan_list =
+ create_or_index_paths(root, rel, rel->clauseinfo);
+
+ rel->pathlist = add_pathlist(rel,
+ sequential_scan_list,
+ append(rel_index_scan_list,
+ or_index_scan_list));
+
+ /*
+ * The unordered path is always the last in the list. If it is not
+ * the cheapest path, prune it.
+ */
+ lastpath = rel->pathlist;
+ while (lnext(lastpath) != NIL)
+ lastpath = lnext(lastpath);
+ prune_rel_path(rel, (Path *) lfirst(lastpath));
+
+ /*
+ * if there is a qualification of sequential scan the selec. value
+ * is not set -- so set it explicitly -- Sunita
+ */
+ set_rest_selec(root, rel->clauseinfo);
+ rel->size = compute_rel_size(rel);
+ rel->width = compute_rel_width(rel);
+ }
+ return;
}
-/*
+/*
* find-join-paths--
- * Find all possible joinpaths for a query by successively finding ways
- * to join single relations into join relations.
+ * Find all possible joinpaths for a query by successively finding ways
+ * to join single relations into join relations.
*
- * if BushyPlanFlag is set, bushy tree plans will be generated:
- * Find all possible joinpaths(bushy trees) for a query by systematically
- * finding ways to join relations(both original and derived) together.
- *
- * 'outer-rels' is the current list of relations for which join paths
- * are to be found, i.e., he current list of relations that
- * have already been derived.
+ * if BushyPlanFlag is set, bushy tree plans will be generated:
+ * Find all possible joinpaths(bushy trees) for a query by systematically
+ * finding ways to join relations(both original and derived) together.
+ *
+ * 'outer-rels' is the current list of relations for which join paths
+ * are to be found, i.e., he current list of relations that
+ * have already been derived.
* 'levels-left' is the current join level being processed, where '1' is
- * the "last" level
- *
+ * the "last" level
+ *
* Returns the final level of join relations, i.e., the relation that is
* the result of joining all the original relations togehter.
*/
-static List *
-find_join_paths(Query *root, List *outer_rels, int levels_left)
+static List *
+find_join_paths(Query * root, List * outer_rels, int levels_left)
{
- List *x;
- List *new_rels;
- Rel *rel;
-
- /*******************************************
- * genetic query optimizer entry point *
- * <utesch@aut.tu-freiberg.de> *
- *******************************************/
-
- if ( (_use_geqo_) && length(root->base_relation_list_) >= _use_geqo_rels_ )
- return lcons(geqo(root), NIL); /* returns *one* Rel, so lcons it */
-
- /*******************************************
- * rest will be deprecated in case of GEQO *
- *******************************************/
-
- /*
- * Determine all possible pairs of relations to be joined at this level.
- * Determine paths for joining these relation pairs and modify 'new-rels'
- * accordingly, then eliminate redundant join relations.
- */
- new_rels = find_join_rels(root, outer_rels);
-
- find_all_join_paths(root, new_rels);
-
- new_rels = prune_joinrels(new_rels);
-
-#if 0
- /*
- ** for each expensive predicate in each path in each distinct rel,
- ** consider doing pullup -- JMH
- */
- if (XfuncMode != XFUNC_NOPULL && XfuncMode != XFUNC_OFF)
- foreach(x, new_rels)
- xfunc_trypullup((Rel*)lfirst(x));
-#endif
+ List *x;
+ List *new_rels;
+ Rel *rel;
- prune_rel_paths(new_rels);
+ /*******************************************
+ * genetic query optimizer entry point *
+ * <utesch@aut.tu-freiberg.de> *
+ *******************************************/
+
+ if ((_use_geqo_) && length(root->base_relation_list_) >= _use_geqo_rels_)
+ return lcons(geqo(root), NIL); /* returns *one* Rel, so lcons it */
+
+ /*******************************************
+ * rest will be deprecated in case of GEQO *
+ *******************************************/
- if(BushyPlanFlag) {
/*
- * In case of bushy trees
- * if there is still a join between a join relation and another
- * relation, add a new joininfo that involves the join relation
- * to the joininfo list of the other relation
+ * Determine all possible pairs of relations to be joined at this
+ * level. Determine paths for joining these relation pairs and modify
+ * 'new-rels' accordingly, then eliminate redundant join relations.
*/
- add_new_joininfos(root, new_rels,outer_rels);
- }
+ new_rels = find_join_rels(root, outer_rels);
+
+ find_all_join_paths(root, new_rels);
+
+ new_rels = prune_joinrels(new_rels);
- foreach(x, new_rels) {
- rel = (Rel*)lfirst(x);
- if ( rel->size <= 0 )
- rel->size = compute_rel_size(rel);
- rel->width = compute_rel_width(rel);
+#if 0
+
+ /*
+ * * for each expensive predicate in each path in each distinct rel, *
+ * consider doing pullup -- JMH
+ */
+ if (XfuncMode != XFUNC_NOPULL && XfuncMode != XFUNC_OFF)
+ foreach(x, new_rels)
+ xfunc_trypullup((Rel *) lfirst(x));
+#endif
+
+ prune_rel_paths(new_rels);
+
+ if (BushyPlanFlag)
+ {
+
+ /*
+ * In case of bushy trees if there is still a join between a join
+ * relation and another relation, add a new joininfo that involves
+ * the join relation to the joininfo list of the other relation
+ */
+ add_new_joininfos(root, new_rels, outer_rels);
+ }
+
+ foreach(x, new_rels)
+ {
+ rel = (Rel *) lfirst(x);
+ if (rel->size <= 0)
+ rel->size = compute_rel_size(rel);
+ rel->width = compute_rel_width(rel);
/*#define OPTIMIZER_DEBUG*/
#ifdef OPTIMIZER_DEBUG
- printf("levels left: %d\n", levels_left);
- debug_print_rel(root, rel);
-#endif
- }
-
- if(BushyPlanFlag) {
- /*
- * prune rels that have been completely incorporated into
- * new join rels
- */
- outer_rels = prune_oldrels(outer_rels);
- /*
- * merge join rels if then contain the same list of base rels
- */
- outer_rels = merge_joinrels(new_rels,outer_rels);
- root->join_relation_list_ = outer_rels;
- }
- else {
- root->join_relation_list_ = new_rels;
- }
-
- if(levels_left == 1) {
- if(BushyPlanFlag)
- return(final_join_rels(outer_rels));
+ printf("levels left: %d\n", levels_left);
+ debug_print_rel(root, rel);
+#endif
+ }
+
+ if (BushyPlanFlag)
+ {
+
+ /*
+ * prune rels that have been completely incorporated into new join
+ * rels
+ */
+ outer_rels = prune_oldrels(outer_rels);
+
+ /*
+ * merge join rels if then contain the same list of base rels
+ */
+ outer_rels = merge_joinrels(new_rels, outer_rels);
+ root->join_relation_list_ = outer_rels;
+ }
else
- return(new_rels);
- } else {
- if(BushyPlanFlag)
- return(find_join_paths(root, outer_rels, levels_left - 1));
+ {
+ root->join_relation_list_ = new_rels;
+ }
+
+ if (levels_left == 1)
+ {
+ if (BushyPlanFlag)
+ return (final_join_rels(outer_rels));
+ else
+ return (new_rels);
+ }
else
- return(find_join_paths(root, new_rels, levels_left - 1));
- }
+ {
+ if (BushyPlanFlag)
+ return (find_join_paths(root, outer_rels, levels_left - 1));
+ else
+ return (find_join_paths(root, new_rels, levels_left - 1));
+ }
}
/*****************************************************************************
@@ -262,115 +281,147 @@ find_join_paths(Query *root, List *outer_rels, int levels_left)
#ifdef OPTIMIZER_DEBUG
static void
-print_joinclauses(Query *root, List *clauses)
+print_joinclauses(Query * root, List * clauses)
{
- List *l;
- extern void print_expr(Node *expr, List *rtable); /* in print.c */
+ List *l;
+ extern void print_expr(Node * expr, List * rtable); /* in print.c */
- foreach(l, clauses) {
- CInfo *c = lfirst(l);
+ foreach(l, clauses)
+ {
+ CInfo *c = lfirst(l);
- print_expr((Node*)c->clause, root->rtable);
- if (lnext(l)) printf(" ");
- }
+ print_expr((Node *) c->clause, root->rtable);
+ if (lnext(l))
+ printf(" ");
+ }
}
static void
-print_path(Query *root, Path *path, int indent)
+print_path(Query * root, Path * path, int indent)
{
- char *ptype = NULL;
- JoinPath *jp;
- bool join = false;
- int i;
-
- for(i=0; i < indent; i++)
- printf("\t");
-
- switch(nodeTag(path)) {
- case T_Path:
- ptype = "SeqScan"; join=false; break;
- case T_IndexPath:
- ptype = "IdxScan"; join=false; break;
- case T_JoinPath:
- ptype = "Nestloop"; join=true; break;
- case T_MergePath:
- ptype = "MergeJoin"; join=true; break;
- case T_HashPath:
- ptype = "HashJoin"; join=true; break;
- default:
- break;
- }
- if (join) {
- int size = path->parent->size;
- jp = (JoinPath*)path;
- printf("%s size=%d cost=%f\n", ptype, size, path->path_cost);
- switch(nodeTag(path)) {
+ char *ptype = NULL;
+ JoinPath *jp;
+ bool join = false;
+ int i;
+
+ for (i = 0; i < indent; i++)
+ printf("\t");
+
+ switch (nodeTag(path))
+ {
+ case T_Path:
+ ptype = "SeqScan";
+ join = false;
+ break;
+ case T_IndexPath:
+ ptype = "IdxScan";
+ join = false;
+ break;
+ case T_JoinPath:
+ ptype = "Nestloop";
+ join = true;
+ break;
case T_MergePath:
+ ptype = "MergeJoin";
+ join = true;
+ break;
case T_HashPath:
- for(i=0; i < indent+1; i++)
- printf("\t");
- printf(" clauses=(");
- print_joinclauses(root,
- ((JoinPath*)path)->pathclauseinfo);
- printf(")\n");
-
- if (nodeTag(path)==T_MergePath) {
- MergePath *mp = (MergePath*)path;
- if (mp->outersortkeys || mp->innersortkeys) {
- for(i=0; i < indent+1; i++)
- printf("\t");
- printf(" sortouter=%d sortinner=%d\n",
- ((mp->outersortkeys)?1:0),
- ((mp->innersortkeys)?1:0));
- }
- }
- break;
+ ptype = "HashJoin";
+ join = true;
+ break;
default:
- break;
+ break;
}
- print_path(root, jp->outerjoinpath, indent+1);
- print_path(root, jp->innerjoinpath, indent+1);
- } else {
- int size = path->parent->size;
- int relid = lfirsti(path->parent->relids);
- printf("%s(%d) size=%d cost=%f",
- ptype, relid, size, path->path_cost);
-
- if (nodeTag(path)==T_IndexPath) {
- List *k, *l;
-
- printf(" keys=");
- foreach (k, path->keys) {
- printf("(");
- foreach (l, lfirst(k)) {
- Var *var = lfirst(l);
- printf("%d.%d", var->varnoold, var->varoattno);
- if (lnext(l)) printf(", ");
+ if (join)
+ {
+ int size = path->parent->size;
+
+ jp = (JoinPath *) path;
+ printf("%s size=%d cost=%f\n", ptype, size, path->path_cost);
+ switch (nodeTag(path))
+ {
+ case T_MergePath:
+ case T_HashPath:
+ for (i = 0; i < indent + 1; i++)
+ printf("\t");
+ printf(" clauses=(");
+ print_joinclauses(root,
+ ((JoinPath *) path)->pathclauseinfo);
+ printf(")\n");
+
+ if (nodeTag(path) == T_MergePath)
+ {
+ MergePath *mp = (MergePath *) path;
+
+ if (mp->outersortkeys || mp->innersortkeys)
+ {
+ for (i = 0; i < indent + 1; i++)
+ printf("\t");
+ printf(" sortouter=%d sortinner=%d\n",
+ ((mp->outersortkeys) ? 1 : 0),
+ ((mp->innersortkeys) ? 1 : 0));
+ }
+ }
+ break;
+ default:
+ break;
}
- printf(")");
- if (lnext(k)) printf(", ");
- }
+ print_path(root, jp->outerjoinpath, indent + 1);
+ print_path(root, jp->innerjoinpath, indent + 1);
+ }
+ else
+ {
+ int size = path->parent->size;
+ int relid = lfirsti(path->parent->relids);
+
+ printf("%s(%d) size=%d cost=%f",
+ ptype, relid, size, path->path_cost);
+
+ if (nodeTag(path) == T_IndexPath)
+ {
+ List *k,
+ *l;
+
+ printf(" keys=");
+ foreach(k, path->keys)
+ {
+ printf("(");
+ foreach(l, lfirst(k))
+ {
+ Var *var = lfirst(l);
+
+ printf("%d.%d", var->varnoold, var->varoattno);
+ if (lnext(l))
+ printf(", ");
+ }
+ printf(")");
+ if (lnext(k))
+ printf(", ");
+ }
+ }
+ printf("\n");
}
- printf("\n");
- }
}
-static void
-debug_print_rel(Query *root, Rel *rel)
+static void
+debug_print_rel(Query * root, Rel * rel)
{
- List *l;
-
- printf("(");
- foreach(l, rel->relids) {
- printf("%d ", lfirsti(l));
- }
- printf("): size=%d width=%d\n", rel->size, rel->width);
-
- printf("\tpath list:\n");
- foreach (l, rel->pathlist) {
- print_path(root, lfirst(l), 1);
- }
- printf("\tcheapest path:\n");
- print_path(root, rel->cheapestpath, 1);
+ List *l;
+
+ printf("(");
+ foreach(l, rel->relids)
+ {
+ printf("%d ", lfirsti(l));
+ }
+ printf("): size=%d width=%d\n", rel->size, rel->width);
+
+ printf("\tpath list:\n");
+ foreach(l, rel->pathlist)
+ {
+ print_path(root, lfirst(l), 1);
+ }
+ printf("\tcheapest path:\n");
+ print_path(root, rel->cheapestpath, 1);
}
-#endif /* OPTIMIZER_DEBUG */
+
+#endif /* OPTIMIZER_DEBUG */
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index 634e1130794..0ce580754e3 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* clausesel.c--
- * Routines to compute and set clause selectivities
+ * Routines to compute and set clause selectivities
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.1.1.1 1996/07/09 06:21:35 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.2 1997/09/07 04:43:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,7 +23,7 @@
#include "optimizer/cost.h"
#include "optimizer/plancat.h"
-#include "parser/parsetree.h" /* for getrelid() */
+#include "parser/parsetree.h" /* for getrelid() */
#include "catalog/pg_proc.h"
#include "catalog/pg_operator.h"
@@ -31,301 +31,353 @@
#include "utils/elog.h"
#include "utils/lsyscache.h"
-static Cost compute_selec(Query *root, List *clauses, List *or_selectivities);
+static Cost compute_selec(Query * root, List * clauses, List * or_selectivities);
/****************************************************************************
- * ROUTINES TO SET CLAUSE SELECTIVITIES
+ * ROUTINES TO SET CLAUSE SELECTIVITIES
****************************************************************************/
-/*
+/*
* set_clause_selectivities -
- * Sets the selectivity field for each of clause in 'clauseinfo-list'
- * to 'new-selectivity'. If the selectivity has already been set, reset
- * it only if the new one is better.
- *
+ * Sets the selectivity field for each of clause in 'clauseinfo-list'
+ * to 'new-selectivity'. If the selectivity has already been set, reset
+ * it only if the new one is better.
+ *
* Returns nothing of interest.
*
*/
void
-set_clause_selectivities(List *clauseinfo_list, Cost new_selectivity)
+set_clause_selectivities(List * clauseinfo_list, Cost new_selectivity)
{
- List *temp;
- CInfo *clausenode;
- Cost cost_clause;
-
- foreach (temp,clauseinfo_list) {
- clausenode = (CInfo*)lfirst(temp);
- cost_clause = clausenode->selectivity;
- if ( FLOAT_IS_ZERO(cost_clause) || new_selectivity < cost_clause) {
- clausenode->selectivity = new_selectivity;
+ List *temp;
+ CInfo *clausenode;
+ Cost cost_clause;
+
+ foreach(temp, clauseinfo_list)
+ {
+ clausenode = (CInfo *) lfirst(temp);
+ cost_clause = clausenode->selectivity;
+ if (FLOAT_IS_ZERO(cost_clause) || new_selectivity < cost_clause)
+ {
+ clausenode->selectivity = new_selectivity;
+ }
}
- }
}
-/*
+/*
* product_selec -
- * Multiplies the selectivities of each clause in 'clauseinfo-list'.
- *
+ * Multiplies the selectivities of each clause in 'clauseinfo-list'.
+ *
* Returns a flonum corresponding to the selectivity of 'clauseinfo-list'.
*/
Cost
-product_selec(List *clauseinfo_list)
+product_selec(List * clauseinfo_list)
{
- Cost result = 1.0;
- if (clauseinfo_list!=NIL) {
- List *xclausenode = NIL;
- Cost temp;
-
- foreach(xclausenode,clauseinfo_list) {
- temp = ((CInfo *)lfirst(xclausenode))->selectivity;
- result = result * temp;
+ Cost result = 1.0;
+
+ if (clauseinfo_list != NIL)
+ {
+ List *xclausenode = NIL;
+ Cost temp;
+
+ foreach(xclausenode, clauseinfo_list)
+ {
+ temp = ((CInfo *) lfirst(xclausenode))->selectivity;
+ result = result * temp;
+ }
}
- }
- return(result);
+ return (result);
}
-/*
+/*
* set_rest_relselec -
- * Scans through clauses on each relation and assigns a selectivity to
- * those clauses that haven't been assigned a selectivity by an index.
- *
+ * Scans through clauses on each relation and assigns a selectivity to
+ * those clauses that haven't been assigned a selectivity by an index.
+ *
* Returns nothing of interest.
* MODIFIES: selectivities of the various rel's clauseinfo
- * slots.
+ * slots.
*/
void
-set_rest_relselec(Query *root, List *rel_list)
+set_rest_relselec(Query * root, List * rel_list)
{
- Rel *rel;
- List *x;
+ Rel *rel;
+ List *x;
- foreach (x,rel_list) {
- rel = (Rel*)lfirst(x);
- set_rest_selec(root, rel->clauseinfo);
- }
+ foreach(x, rel_list)
+ {
+ rel = (Rel *) lfirst(x);
+ set_rest_selec(root, rel->clauseinfo);
+ }
}
-/*
+/*
* set_rest_selec -
- * Sets the selectivity fields for those clauses within a single
- * relation's 'clauseinfo-list' that haven't already been set.
- *
+ * Sets the selectivity fields for those clauses within a single
+ * relation's 'clauseinfo-list' that haven't already been set.
+ *
* Returns nothing of interest.
- *
+ *
*/
void
-set_rest_selec(Query *root, List *clauseinfo_list)
+set_rest_selec(Query * root, List * clauseinfo_list)
{
- List *temp = NIL;
- CInfo *clausenode = (CInfo*)NULL;
- Cost cost_clause;
-
- foreach (temp,clauseinfo_list) {
- clausenode = (CInfo*)lfirst(temp);
- cost_clause = clausenode->selectivity;
+ List *temp = NIL;
+ CInfo *clausenode = (CInfo *) NULL;
+ Cost cost_clause;
- /*
- * Check to see if the selectivity of this clause or any 'or'
- * subclauses (if any) haven't been set yet.
- */
- if (valid_or_clause(clausenode) || FLOAT_IS_ZERO(cost_clause)) {
- clausenode->selectivity =
- compute_clause_selec(root,
- (Node*)clausenode->clause,
- lcons(makeFloat(cost_clause), NIL));
+ foreach(temp, clauseinfo_list)
+ {
+ clausenode = (CInfo *) lfirst(temp);
+ cost_clause = clausenode->selectivity;
+
+ /*
+ * Check to see if the selectivity of this clause or any 'or'
+ * subclauses (if any) haven't been set yet.
+ */
+ if (valid_or_clause(clausenode) || FLOAT_IS_ZERO(cost_clause))
+ {
+ clausenode->selectivity =
+ compute_clause_selec(root,
+ (Node *) clausenode->clause,
+ lcons(makeFloat(cost_clause), NIL));
+ }
}
- }
}
/****************************************************************************
- * ROUTINES TO COMPUTE SELECTIVITIES
+ * ROUTINES TO COMPUTE SELECTIVITIES
****************************************************************************/
-/*
+/*
* compute_clause_selec -
- * Given a clause, this routine will compute the selectivity of the
- * clause by calling 'compute_selec' with the appropriate parameters
- * and possibly use that return value to compute the real selectivity
- * of a clause.
- *
+ * Given a clause, this routine will compute the selectivity of the
+ * clause by calling 'compute_selec' with the appropriate parameters
+ * and possibly use that return value to compute the real selectivity
+ * of a clause.
+ *
* 'or-selectivities' are selectivities that have already been assigned
- * to subclauses of an 'or' clause.
- *
+ * to subclauses of an 'or' clause.
+ *
* Returns a flonum corresponding to the clause selectivity.
- *
+ *
*/
Cost
-compute_clause_selec(Query *root, Node *clause, List *or_selectivities)
+compute_clause_selec(Query * root, Node * clause, List * or_selectivities)
{
- if (!is_opclause (clause)) {
- /* if it's not an operator clause, then it is a boolean clause -jolly*/
- /*
- * Boolean variables get a selectivity of 1/2.
- */
- return(0.1);
- } else if (not_clause (clause)) {
- /*
- * 'not' gets "1.0 - selectivity-of-inner-clause".
- */
- return (1.000000 - compute_selec(root,
- lcons(get_notclausearg((Expr*)clause),
- NIL),
- or_selectivities));
- } else if (or_clause(clause)) {
- /*
- * Both 'or' and 'and' clauses are evaluated as described in
- * (compute_selec).
- */
- return (compute_selec(root,
- ((Expr*)clause)->args, or_selectivities));
- } else {
- return(compute_selec(root,
- lcons(clause,NIL),or_selectivities));
- }
+ if (!is_opclause(clause))
+ {
+
+ /*
+ * if it's not an operator clause, then it is a boolean clause
+ * -jolly
+ */
+
+ /*
+ * Boolean variables get a selectivity of 1/2.
+ */
+ return (0.1);
+ }
+ else if (not_clause(clause))
+ {
+
+ /*
+ * 'not' gets "1.0 - selectivity-of-inner-clause".
+ */
+ return (1.000000 - compute_selec(root,
+ lcons(get_notclausearg((Expr *) clause),
+ NIL),
+ or_selectivities));
+ }
+ else if (or_clause(clause))
+ {
+
+ /*
+ * Both 'or' and 'and' clauses are evaluated as described in
+ * (compute_selec).
+ */
+ return (compute_selec(root,
+ ((Expr *) clause)->args, or_selectivities));
+ }
+ else
+ {
+ return (compute_selec(root,
+ lcons(clause, NIL), or_selectivities));
+ }
}
-/*
- * compute_selec -
- * Computes the selectivity of a clause.
- *
- * If there is more than one clause in the argument 'clauses', then the
- * desired selectivity is that of an 'or' clause. Selectivities for an
- * 'or' clause such as (OR a b) are computed by finding the selectivity
- * of a (s1) and b (s2) and computing s1+s2 - s1*s2.
- *
- * In addition, if the clause is an 'or' clause, individual selectivities
- * may have already been assigned by indices to subclauses. These values
- * are contained in the list 'or-selectivities'.
- *
+/*
+ * compute_selec -
+ * Computes the selectivity of a clause.
+ *
+ * If there is more than one clause in the argument 'clauses', then the
+ * desired selectivity is that of an 'or' clause. Selectivities for an
+ * 'or' clause such as (OR a b) are computed by finding the selectivity
+ * of a (s1) and b (s2) and computing s1+s2 - s1*s2.
+ *
+ * In addition, if the clause is an 'or' clause, individual selectivities
+ * may have already been assigned by indices to subclauses. These values
+ * are contained in the list 'or-selectivities'.
+ *
* Returns the clause selectivity as a flonum.
- *
+ *
*/
-static Cost
-compute_selec(Query *root, List *clauses, List *or_selectivities)
+static Cost
+compute_selec(Query * root, List * clauses, List * or_selectivities)
{
- Cost s1 = 0;
- List *clause = lfirst(clauses);
-
- if (clauses==NULL) {
- s1 = 1.0;
- } else if (IsA(clause,Param)) {
- /* XXX How're we handling this before?? -ay */
- s1 = 1.0;
- } else if (IsA(clause,Const)) {
- s1 = ((bool) ((Const*) clause)->constvalue) ? 1.0 : 0.0;
- } else if (IsA(clause,Var)) {
- Oid relid = getrelid(((Var*)clause)->varno,
- root->rtable);
+ Cost s1 = 0;
+ List *clause = lfirst(clauses);
- /*
- * we have a bool Var. This is exactly equivalent to the clause:
- * reln.attribute = 't'
- * so we compute the selectivity as if that is what we have. The
- * magic #define constants are a hack. I didn't want to have to
- * do system cache look ups to find out all of that info.
- */
+ if (clauses == NULL)
+ {
+ s1 = 1.0;
+ }
+ else if (IsA(clause, Param))
+ {
+ /* XXX How're we handling this before?? -ay */
+ s1 = 1.0;
+ }
+ else if (IsA(clause, Const))
+ {
+ s1 = ((bool) ((Const *) clause)->constvalue) ? 1.0 : 0.0;
+ }
+ else if (IsA(clause, Var))
+ {
+ Oid relid = getrelid(((Var *) clause)->varno,
+ root->rtable);
- s1 = restriction_selectivity(EqualSelectivityProcedure,
- BooleanEqualOperator,
- relid,
- ((Var*)clause)->varoattno,
- "t",
- _SELEC_CONSTANT_RIGHT_);
- } else if (or_selectivities) {
- /* If s1 has already been assigned by an index, use that value. */
- List *this_sel = lfirst(or_selectivities);
-
- s1 = floatVal(this_sel);
- } else if (is_funcclause((Node*)clause)) {
- /* this isn't an Oper, it's a Func!! */
- /*
- ** 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 SELECTIVITIES THEMSELVES.
- ** -- JMH 7/9/92
- */
- s1 = 0.1;
- } else if (NumRelids((Node*) clause) == 1) {
- /* ...otherwise, calculate s1 from 'clauses'.
- * The clause is not a join clause, since there is
- * only one relid in the clause. The clause
- * selectivity will be based on the operator
- * selectivity and operand values.
- */
- Oid opno = ((Oper*)((Expr*)clause)->oper)->opno;
- RegProcedure oprrest = get_oprrest(opno);
- Oid relid;
- int relidx;
- AttrNumber attno;
- Datum constval;
- int flag;
-
- get_relattval((Node*)clause, &relidx, &attno, &constval, &flag);
- relid = getrelid(relidx, root->rtable);
-
- /* if the oprrest procedure is missing for whatever reason,
- use a selectivity of 0.5*/
- if (!oprrest)
- s1 = (Cost) (0.5);
+ /*
+ * we have a bool Var. This is exactly equivalent to the clause:
+ * reln.attribute = 't' so we compute the selectivity as if that
+ * is what we have. The magic #define constants are a hack. I
+ * didn't want to have to do system cache look ups to find out all
+ * of that info.
+ */
+
+ s1 = restriction_selectivity(EqualSelectivityProcedure,
+ BooleanEqualOperator,
+ relid,
+ ((Var *) clause)->varoattno,
+ "t",
+ _SELEC_CONSTANT_RIGHT_);
+ }
+ else if (or_selectivities)
+ {
+ /* If s1 has already been assigned by an index, use that value. */
+ List *this_sel = lfirst(or_selectivities);
+
+ s1 = floatVal(this_sel);
+ }
+ else if (is_funcclause((Node *) clause))
+ {
+ /* this isn't an Oper, it's a Func!! */
+
+ /*
+ * * 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 SELECTIVITIES THEMSELVES. * -- JMH 7/9/92
+ */
+ s1 = 0.1;
+ }
+ else if (NumRelids((Node *) clause) == 1)
+ {
+
+ /*
+ * ...otherwise, calculate s1 from 'clauses'. The clause is not a
+ * join clause, since there is only one relid in the clause. The
+ * clause selectivity will be based on the operator selectivity
+ * and operand values.
+ */
+ Oid opno = ((Oper *) ((Expr *) clause)->oper)->opno;
+ RegProcedure oprrest = get_oprrest(opno);
+ Oid relid;
+ int relidx;
+ AttrNumber attno;
+ Datum constval;
+ int flag;
+
+ get_relattval((Node *) clause, &relidx, &attno, &constval, &flag);
+ relid = getrelid(relidx, root->rtable);
+
+ /*
+ * if the oprrest procedure is missing for whatever reason, use a
+ * selectivity of 0.5
+ */
+ if (!oprrest)
+ s1 = (Cost) (0.5);
+ else if (attno == InvalidAttrNumber)
+ {
+
+ /*
+ * attno can be Invalid if the clause had a function in it,
+ * i.e. WHERE myFunc(f) = 10
+ */
+ /* this should be FIXED somehow to use function selectivity */
+ s1 = (Cost) (0.5);
+ }
+ else
+ s1 = (Cost) restriction_selectivity(oprrest,
+ opno,
+ relid,
+ attno,
+ (char *) constval,
+ flag);
+
+ }
else
- if (attno == InvalidAttrNumber) {
- /* attno can be Invalid if the clause had a function in it,
- i.e. WHERE myFunc(f) = 10 */
- /* this should be FIXED somehow to use function selectivity */
- s1 = (Cost) (0.5);
- } else
- s1 = (Cost) restriction_selectivity(oprrest,
- opno,
- relid,
- attno,
- (char *)constval,
- flag);
-
- } else {
- /* The clause must be a join clause. The clause
- * selectivity will be based on the relations to be
- * scanned and the attributes they are to be joined
- * on.
+ {
+
+ /*
+ * The clause must be a join clause. The clause selectivity will
+ * be based on the relations to be scanned and the attributes they
+ * are to be joined on.
+ */
+ Oid opno = ((Oper *) ((Expr *) clause)->oper)->opno;
+ RegProcedure oprjoin = get_oprjoin(opno);
+ int relid1,
+ relid2;
+ AttrNumber attno1,
+ attno2;
+
+ get_rels_atts((Node *) clause, &relid1, &attno1, &relid2, &attno2);
+ relid1 = getrelid(relid1, root->rtable);
+ relid2 = getrelid(relid2, root->rtable);
+
+ /*
+ * if the oprjoin procedure is missing for whatever reason, use a
+ * selectivity of 0.5
+ */
+ if (!oprjoin)
+ s1 = (Cost) (0.5);
+ else
+ s1 = (Cost) join_selectivity(oprjoin,
+ opno,
+ relid1,
+ attno1,
+ relid2,
+ attno2);
+ }
+
+ /*
+ * A null clause list eliminates no tuples, so return a selectivity of
+ * 1.0. If there is only one clause, the selectivity is not that of
+ * an 'or' clause, but rather that of the single clause.
*/
- Oid opno = ((Oper*)((Expr*)clause)->oper)->opno;
- RegProcedure oprjoin = get_oprjoin (opno);
- int relid1, relid2;
- AttrNumber attno1, attno2;
-
- get_rels_atts((Node*)clause, &relid1, &attno1, &relid2, &attno2);
- relid1 = getrelid(relid1, root->rtable);
- relid2 = getrelid(relid2, root->rtable);
-
- /* if the oprjoin procedure is missing for whatever reason,
- use a selectivity of 0.5*/
- if (!oprjoin)
- s1 = (Cost) (0.5);
- else
- s1 = (Cost) join_selectivity(oprjoin,
- opno,
- relid1,
- attno1,
- relid2,
- attno2);
- }
-
- /* A null clause list eliminates no tuples, so return a selectivity
- * of 1.0. If there is only one clause, the selectivity is not
- * that of an 'or' clause, but rather that of the single clause.
- */
-
- if (length (clauses) < 2) {
- return(s1);
- } else {
- /* Compute selectivity of the 'or'ed subclauses. */
- /* Added check for taking lnext(NIL). -- JMH 3/9/92 */
- Cost s2;
-
- if (or_selectivities != NIL)
- s2 = compute_selec(root, lnext(clauses), lnext(or_selectivities));
+
+ if (length(clauses) < 2)
+ {
+ return (s1);
+ }
else
- s2 = compute_selec(root, lnext(clauses), NIL);
- return(s1 + s2 - s1 * s2);
- }
-}
+ {
+ /* Compute selectivity of the 'or'ed subclauses. */
+ /* Added check for taking lnext(NIL). -- JMH 3/9/92 */
+ Cost s2;
+ if (or_selectivities != NIL)
+ s2 = compute_selec(root, lnext(clauses), lnext(or_selectivities));
+ else
+ s2 = compute_selec(root, lnext(clauses), NIL);
+ return (s1 + s2 - s1 * s2);
+ }
+}
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 35453fb3870..2873e62c48c 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* costsize.c--
- * Routines to compute (and set) relation sizes and path costs
+ * Routines to compute (and set) relation sizes and path costs
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.16 1997/08/19 21:31:48 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.17 1997/09/07 04:43:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,15 +17,15 @@
#include <math.h>
#ifdef HAVE_LIMITS_H
-# include <limits.h>
-# ifndef MAXINT
-# define MAXINT INT_MAX
-# endif
+#include <limits.h>
+#ifndef MAXINT
+#define MAXINT INT_MAX
+#endif
#else
-# ifdef HAVE_VALUES_H
-# include <values.h>
-# endif
-#endif
+#ifdef HAVE_VALUES_H
+#include <values.h>
+#endif
+#endif
#include <utils/lsyscache.h>
#include "nodes/relation.h"
@@ -35,77 +35,81 @@
#include "optimizer/keys.h"
#include "optimizer/tlist.h"
-#include "storage/bufmgr.h" /* for BLCKSZ */
+#include "storage/bufmgr.h" /* for BLCKSZ */
-extern int NBuffers;
+extern int NBuffers;
-static int compute_attribute_width(TargetEntry *tlistentry);
-static double base_log(double x, double b);
-static int compute_targetlist_width(List *targetlist);
+static int compute_attribute_width(TargetEntry * tlistentry);
+static double base_log(double x, double b);
+static int compute_targetlist_width(List * targetlist);
-int _disable_cost_ = 30000000;
-
-bool _enable_seqscan_ = true;
-bool _enable_indexscan_ = true;
-bool _enable_sort_ = true;
-bool _enable_hash_ = true;
-bool _enable_nestloop_ = true;
-bool _enable_mergesort_ = true;
-bool _enable_hashjoin_ = true;
+int _disable_cost_ = 30000000;
-Cost _cpu_page_wight_ = _CPU_PAGE_WEIGHT_;
-Cost _cpu_index_page_wight_ = _CPU_INDEX_PAGE_WEIGHT_;
+bool _enable_seqscan_ = true;
+bool _enable_indexscan_ = true;
+bool _enable_sort_ = true;
+bool _enable_hash_ = true;
+bool _enable_nestloop_ = true;
+bool _enable_mergesort_ = true;
+bool _enable_hashjoin_ = true;
-/*
+Cost _cpu_page_wight_ = _CPU_PAGE_WEIGHT_;
+Cost _cpu_index_page_wight_ = _CPU_INDEX_PAGE_WEIGHT_;
+
+/*
* cost_seqscan--
- * Determines and returns the cost of scanning a relation sequentially.
- * If the relation is a temporary to be materialized from a query
- * embedded within a data field (determined by 'relid' containing an
- * attribute reference), then a predetermined constant is returned (we
- * have NO IDEA how big the result of a POSTQUEL procedure is going to
- * be).
- *
- * disk = p
- * cpu = *CPU-PAGE-WEIGHT* * t
- *
+ * Determines and returns the cost of scanning a relation sequentially.
+ * If the relation is a temporary to be materialized from a query
+ * embedded within a data field (determined by 'relid' containing an
+ * attribute reference), then a predetermined constant is returned (we
+ * have NO IDEA how big the result of a POSTQUEL procedure is going to
+ * be).
+ *
+ * disk = p
+ * cpu = *CPU-PAGE-WEIGHT* * t
+ *
* 'relid' is the relid of the relation to be scanned
* 'relpages' is the number of pages in the relation to be scanned
- * (as determined from the system catalogs)
+ * (as determined from the system catalogs)
* 'reltuples' is the number of tuples in the relation to be scanned
- *
+ *
* Returns a flonum.
- *
+ *
*/
Cost
cost_seqscan(int relid, int relpages, int reltuples)
{
- Cost temp = 0;
+ Cost temp = 0;
- if ( !_enable_seqscan_ )
- temp += _disable_cost_;
+ if (!_enable_seqscan_)
+ temp += _disable_cost_;
- if (relid < 0) {
- /*
- * cost of sequentially scanning a materialized temporary relation
- */
- temp += _TEMP_SCAN_COST_;
- } else {
- temp += relpages;
- temp += _cpu_page_wight_ * reltuples;
- }
- Assert(temp >= 0);
- return(temp);
+ if (relid < 0)
+ {
+
+ /*
+ * cost of sequentially scanning a materialized temporary relation
+ */
+ temp += _TEMP_SCAN_COST_;
+ }
+ else
+ {
+ temp += relpages;
+ temp += _cpu_page_wight_ * reltuples;
+ }
+ Assert(temp >= 0);
+ return (temp);
}
-/*
+/*
* cost_index--
- * Determines and returns the cost of scanning a relation using an index.
- *
- * disk = expected-index-pages + expected-data-pages
- * cpu = *CPU-PAGE-WEIGHT* *
- * (expected-index-tuples + expected-data-tuples)
- *
+ * Determines and returns the cost of scanning a relation using an index.
+ *
+ * disk = expected-index-pages + expected-data-pages
+ * cpu = *CPU-PAGE-WEIGHT* *
+ * (expected-index-tuples + expected-data-tuples)
+ *
* 'indexid' is the index OID
* 'expected-indexpages' is the number of index pages examined in the scan
* 'selec' is the selectivity of the index
@@ -113,100 +117,102 @@ cost_seqscan(int relid, int relpages, int reltuples)
* 'reltuples' is the number of tuples in the main relation
* 'indexpages' is the number of pages in the index relation
* 'indextuples' is the number of tuples in the index relation
- *
+ *
* Returns a flonum.
- *
+ *
*/
Cost
cost_index(Oid indexid,
- int expected_indexpages,
- Cost selec,
- int relpages,
- int reltuples,
- int indexpages,
- int indextuples,
- bool is_injoin)
+ int expected_indexpages,
+ Cost selec,
+ int relpages,
+ int reltuples,
+ int indexpages,
+ int indextuples,
+ bool is_injoin)
{
- Cost temp;
- double temp2;
+ Cost temp;
+ double temp2;
+
+ temp = (Cost) 0;
- temp = (Cost) 0;
+ if (!_enable_indexscan_ && !is_injoin)
+ temp += _disable_cost_;
- if (!_enable_indexscan_ && !is_injoin)
- temp += _disable_cost_;
+ /* expected index relation pages */
+ temp += expected_indexpages;
- /* expected index relation pages */
- temp += expected_indexpages;
+ /* expected base relation pages */
+ temp2 = (reltuples == 0) ? (double) 0 : (double) relpages / reltuples;
+ temp2 = temp2 * (double) selec *indextuples;
- /* expected base relation pages */
- temp2 = ( reltuples == 0 ) ? (double)0 : (double)relpages/reltuples;
- temp2 = temp2 * (double)selec * indextuples;
- temp += Min (relpages, (int)ceil (temp2));
+ temp += Min(relpages, (int) ceil(temp2));
- /* per index tuples */
- temp = temp + (_cpu_index_page_wight_ * selec * indextuples);
+ /* per index tuples */
+ temp = temp + (_cpu_index_page_wight_ * selec * indextuples);
- /* per heap tuples */
- temp = temp + (_cpu_page_wight_ * selec * reltuples);
+ /* per heap tuples */
+ temp = temp + (_cpu_page_wight_ * selec * reltuples);
- Assert(temp >= 0);
- return(temp);
+ Assert(temp >= 0);
+ return (temp);
}
-/*
+/*
* cost_sort--
- * Determines and returns the cost of sorting a relation by considering
- * 1. the cost of doing an external sort: XXX this is probably too low
- * disk = (p lg p)
- * cpu = *CPU-PAGE-WEIGHT* * (t lg t)
- * 2. the cost of reading the sort result into memory (another seqscan)
- * unless 'noread' is set
- *
+ * Determines and returns the cost of sorting a relation by considering
+ * 1. the cost of doing an external sort: XXX this is probably too low
+ * disk = (p lg p)
+ * cpu = *CPU-PAGE-WEIGHT* * (t lg t)
+ * 2. the cost of reading the sort result into memory (another seqscan)
+ * unless 'noread' is set
+ *
* 'keys' is a list of sort keys
* 'tuples' is the number of tuples in the relation
* 'width' is the average tuple width in bytes
* 'noread' is a flag indicating that the sort result can remain on disk
- * (i.e., the sort result is the result relation)
- *
+ * (i.e., the sort result is the result relation)
+ *
* Returns a flonum.
- *
+ *
*/
Cost
-cost_sort(List *keys, int tuples, int width, bool noread)
+cost_sort(List * keys, int tuples, int width, bool noread)
{
- Cost temp = 0;
- int npages = page_size (tuples,width);
- Cost pages = (Cost)npages;
- Cost numTuples = tuples;
-
- if ( !_enable_sort_ )
- temp += _disable_cost_ ;
- if (tuples == 0 || keys==NULL)
+ Cost temp = 0;
+ int npages = page_size(tuples, width);
+ Cost pages = (Cost) npages;
+ Cost numTuples = tuples;
+
+ if (!_enable_sort_)
+ temp += _disable_cost_;
+ if (tuples == 0 || keys == NULL)
{
- Assert(temp >= 0);
- return(temp);
+ Assert(temp >= 0);
+ return (temp);
}
- temp += pages * base_log((double)pages, (double)2.0);
+ temp += pages * base_log((double) pages, (double) 2.0);
- /*
- * could be base_log(pages, NBuffers), but we are only doing 2-way merges
- */
- temp += _cpu_page_wight_ *
- numTuples * base_log((double)pages,(double)2.0);
+ /*
+ * could be base_log(pages, NBuffers), but we are only doing 2-way
+ * merges
+ */
+ temp += _cpu_page_wight_ *
+ numTuples * base_log((double) pages, (double) 2.0);
- if( !noread )
- temp = temp + cost_seqscan(_TEMP_RELATION_ID_, npages, tuples);
- Assert(temp >= 0);
+ if (!noread)
+ temp = temp + cost_seqscan(_TEMP_RELATION_ID_, npages, tuples);
+ Assert(temp >= 0);
- return(temp);
+ return (temp);
}
-/*
+/*
* cost_result--
- * Determines and returns the cost of writing a relation of 'tuples'
- * tuples of 'width' bytes out to a result relation.
- *
+ * Determines and returns the cost of writing a relation of 'tuples'
+ * tuples of 'width' bytes out to a result relation.
+ *
* Returns a flonum.
*
*/
@@ -214,257 +220,273 @@ cost_sort(List *keys, int tuples, int width, bool noread)
Cost
cost_result(int tuples, int width)
{
- Cost temp =0;
- temp = temp + page_size(tuples,width);
- temp = temp + _cpu_page_wight_ * tuples;
- Assert(temp >= 0);
- return(temp);
+ Cost temp = 0;
+
+ temp = temp + page_size(tuples, width);
+ temp = temp + _cpu_page_wight_ * tuples;
+ Assert(temp >= 0);
+ return (temp);
}
+
#endif
-/*
+/*
* cost_nestloop--
- * Determines and returns the cost of joining two relations using the
- * nested loop algorithm.
- *
+ * Determines and returns the cost of joining two relations using the
+ * nested loop algorithm.
+ *
* 'outercost' is the (disk+cpu) cost of scanning the outer relation
* 'innercost' is the (disk+cpu) cost of scanning the inner relation
* 'outertuples' is the number of tuples in the outer relation
- *
+ *
* Returns a flonum.
*
*/
Cost
cost_nestloop(Cost outercost,
- Cost innercost,
- int outertuples,
- int innertuples,
- int outerpages,
- bool is_indexjoin)
+ Cost innercost,
+ int outertuples,
+ int innertuples,
+ int outerpages,
+ bool is_indexjoin)
{
- Cost temp =0;
+ Cost temp = 0;
- if ( !_enable_nestloop_ )
- temp += _disable_cost_;
- temp += outercost;
- temp += outertuples * innercost;
- Assert(temp >= 0);
+ if (!_enable_nestloop_)
+ temp += _disable_cost_;
+ temp += outercost;
+ temp += outertuples * innercost;
+ Assert(temp >= 0);
- return(temp);
+ return (temp);
}
-/*
+/*
* cost_mergesort--
- * 'outercost' and 'innercost' are the (disk+cpu) costs of scanning the
- * outer and inner relations
- * 'outersortkeys' and 'innersortkeys' are lists of the keys to be used
- * to sort the outer and inner relations
- * 'outertuples' and 'innertuples' are the number of tuples in the outer
- * and inner relations
- * 'outerwidth' and 'innerwidth' are the (typical) widths (in bytes)
- * of the tuples of the outer and inner relations
- *
+ * 'outercost' and 'innercost' are the (disk+cpu) costs of scanning the
+ * outer and inner relations
+ * 'outersortkeys' and 'innersortkeys' are lists of the keys to be used
+ * to sort the outer and inner relations
+ * 'outertuples' and 'innertuples' are the number of tuples in the outer
+ * and inner relations
+ * 'outerwidth' and 'innerwidth' are the (typical) widths (in bytes)
+ * of the tuples of the outer and inner relations
+ *
* Returns a flonum.
- *
+ *
*/
Cost
cost_mergesort(Cost outercost,
- Cost innercost,
- List *outersortkeys,
- List *innersortkeys,
- int outersize,
- int innersize,
- int outerwidth,
- int innerwidth)
+ Cost innercost,
+ List * outersortkeys,
+ List * innersortkeys,
+ int outersize,
+ int innersize,
+ int outerwidth,
+ int innerwidth)
{
- Cost temp = 0;
-
- if ( !_enable_mergesort_ )
- temp += _disable_cost_;
-
- temp += outercost;
- temp += innercost;
- temp += cost_sort(outersortkeys,outersize,outerwidth,false);
- temp += cost_sort(innersortkeys,innersize,innerwidth,false);
- temp += _cpu_page_wight_ * (outersize + innersize);
- Assert(temp >= 0);
-
- return(temp);
+ Cost temp = 0;
+
+ if (!_enable_mergesort_)
+ temp += _disable_cost_;
+
+ temp += outercost;
+ temp += innercost;
+ temp += cost_sort(outersortkeys, outersize, outerwidth, false);
+ temp += cost_sort(innersortkeys, innersize, innerwidth, false);
+ temp += _cpu_page_wight_ * (outersize + innersize);
+ Assert(temp >= 0);
+
+ return (temp);
}
-/*
- * cost_hashjoin-- XXX HASH
- * 'outercost' and 'innercost' are the (disk+cpu) costs of scanning the
- * outer and inner relations
- * 'outerkeys' and 'innerkeys' are lists of the keys to be used
- * to hash the outer and inner relations
- * 'outersize' and 'innersize' are the number of tuples in the outer
- * and inner relations
- * 'outerwidth' and 'innerwidth' are the (typical) widths (in bytes)
- * of the tuples of the outer and inner relations
- *
+/*
+ * cost_hashjoin-- XXX HASH
+ * 'outercost' and 'innercost' are the (disk+cpu) costs of scanning the
+ * outer and inner relations
+ * 'outerkeys' and 'innerkeys' are lists of the keys to be used
+ * to hash the outer and inner relations
+ * 'outersize' and 'innersize' are the number of tuples in the outer
+ * and inner relations
+ * 'outerwidth' and 'innerwidth' are the (typical) widths (in bytes)
+ * of the tuples of the outer and inner relations
+ *
* Returns a flonum.
*/
Cost
cost_hashjoin(Cost outercost,
- Cost innercost,
- List *outerkeys,
- List *innerkeys,
- int outersize,
- int innersize,
- int outerwidth,
- int innerwidth)
+ Cost innercost,
+ List * outerkeys,
+ List * innerkeys,
+ int outersize,
+ int innersize,
+ int outerwidth,
+ int innerwidth)
{
- Cost temp = 0;
- int outerpages = page_size (outersize,outerwidth);
- int innerpages = page_size (innersize,innerwidth);
- int nrun = ceil((double)outerpages/(double)NBuffers);
-
- if (outerpages < innerpages)
- return _disable_cost_;
- if ( !_enable_hashjoin_ )
- temp += _disable_cost_;
- /*
- temp += outercost + (nrun + 1) * innercost;
- *
- * the innercost shouldn't be used it. Instead the
- * cost of hashing the innerpath should be used
- *
- * ASSUME innercost is 1 for now -- a horrible hack
- * - jolly
- temp += outercost + (nrun + 1);
- *
- * But we must add innercost to result. - vadim 04/24/97
- */
- temp += outercost + innercost + (nrun + 1);
-
- temp += _cpu_page_wight_ * (outersize + nrun * innersize);
- Assert(temp >= 0);
-
- return(temp);
+ Cost temp = 0;
+ int outerpages = page_size(outersize, outerwidth);
+ int innerpages = page_size(innersize, innerwidth);
+ int nrun = ceil((double) outerpages / (double) NBuffers);
+
+ if (outerpages < innerpages)
+ return _disable_cost_;
+ if (!_enable_hashjoin_)
+ temp += _disable_cost_;
+
+ /*
+ * temp += outercost + (nrun + 1) * innercost;
+ *
+ * the innercost shouldn't be used it. Instead the cost of hashing the
+ * innerpath should be used
+ *
+ * ASSUME innercost is 1 for now -- a horrible hack - jolly temp +=
+ * outercost + (nrun + 1);
+ *
+ * But we must add innercost to result. - vadim 04/24/97
+ */
+ temp += outercost + innercost + (nrun + 1);
+
+ temp += _cpu_page_wight_ * (outersize + nrun * innersize);
+ Assert(temp >= 0);
+
+ return (temp);
}
-/*
+/*
* compute-rel-size--
- * Computes the size of each relation in 'rel-list' (after applying
- * restrictions), by multiplying the selectivity of each restriction
- * by the original size of the relation.
- *
- * Sets the 'size' field for each relation entry with this computed size.
- *
+ * Computes the size of each relation in 'rel-list' (after applying
+ * restrictions), by multiplying the selectivity of each restriction
+ * by the original size of the relation.
+ *
+ * Sets the 'size' field for each relation entry with this computed size.
+ *
* Returns the size.
*/
-int compute_rel_size(Rel *rel)
+int
+compute_rel_size(Rel * rel)
{
- Cost temp;
- int temp1;
-
- temp = rel->tuples * product_selec(rel->clauseinfo);
- Assert(temp >= 0);
- if (temp >= (MAXINT - 1)) {
- temp1 = MAXINT;
- } else {
- temp1 = ceil((double) temp);
- }
- Assert(temp1 >= 0);
- Assert(temp1 <= MAXINT);
- return(temp1);
+ Cost temp;
+ int temp1;
+
+ temp = rel->tuples * product_selec(rel->clauseinfo);
+ Assert(temp >= 0);
+ if (temp >= (MAXINT - 1))
+ {
+ temp1 = MAXINT;
+ }
+ else
+ {
+ temp1 = ceil((double) temp);
+ }
+ Assert(temp1 >= 0);
+ Assert(temp1 <= MAXINT);
+ return (temp1);
}
-/*
+/*
* compute-rel-width--
- * Computes the width in bytes of a tuple from 'rel'.
- *
+ * Computes the width in bytes of a tuple from 'rel'.
+ *
* Returns the width of the tuple as a fixnum.
*/
int
-compute_rel_width(Rel *rel)
+compute_rel_width(Rel * rel)
{
- return (compute_targetlist_width(get_actual_tlist(rel->targetlist)));
+ return (compute_targetlist_width(get_actual_tlist(rel->targetlist)));
}
-/*
+/*
* compute-targetlist-width--
- * Computes the width in bytes of a tuple made from 'targetlist'.
- *
+ * Computes the width in bytes of a tuple made from 'targetlist'.
+ *
* Returns the width of the tuple as a fixnum.
*/
static int
-compute_targetlist_width(List *targetlist)
+compute_targetlist_width(List * targetlist)
{
- List *temp_tl;
- int tuple_width = 0;
-
- foreach (temp_tl, targetlist) {
- tuple_width = tuple_width +
- compute_attribute_width(lfirst(temp_tl));
- }
- return(tuple_width);
+ List *temp_tl;
+ int tuple_width = 0;
+
+ foreach(temp_tl, targetlist)
+ {
+ tuple_width = tuple_width +
+ compute_attribute_width(lfirst(temp_tl));
+ }
+ return (tuple_width);
}
-/*
+/*
* compute-attribute-width--
- * Given a target list entry, find the size in bytes of the attribute.
- *
- * If a field is variable-length, it is assumed to be at least the size
- * of a TID field.
- *
+ * Given a target list entry, find the size in bytes of the attribute.
+ *
+ * If a field is variable-length, it is assumed to be at least the size
+ * of a TID field.
+ *
* Returns the width of the attribute as a fixnum.
*/
static int
-compute_attribute_width(TargetEntry *tlistentry)
+compute_attribute_width(TargetEntry * tlistentry)
{
- int width = get_typlen(tlistentry->resdom->restype);
- if (width < 0)
- return(_DEFAULT_ATTRIBUTE_WIDTH_);
- else
- return(width);
+ int width = get_typlen(tlistentry->resdom->restype);
+
+ if (width < 0)
+ return (_DEFAULT_ATTRIBUTE_WIDTH_);
+ else
+ return (width);
}
-/*
+/*
* compute-joinrel-size--
- * Computes the size of the join relation 'joinrel'.
- *
+ * Computes the size of the join relation 'joinrel'.
+ *
* Returns a fixnum.
*/
int
-compute_joinrel_size(JoinPath *joinpath)
+compute_joinrel_size(JoinPath * joinpath)
{
- Cost temp = 1.0;
- int temp1 = 0;
-
- temp *= ((Path*)joinpath->outerjoinpath)->parent->size;
- temp *= ((Path*)joinpath->innerjoinpath)->parent->size;
-
- temp = temp * product_selec(joinpath->pathclauseinfo);
- if (temp >= (MAXINT -1)) {
- temp1 = MAXINT;
- } else {
- /* should be ceil here, we don't want joinrel size's of one, do we? */
- temp1 = ceil((double)temp);
- }
- Assert(temp1 >= 0);
-
- return(temp1);
+ Cost temp = 1.0;
+ int temp1 = 0;
+
+ temp *= ((Path *) joinpath->outerjoinpath)->parent->size;
+ temp *= ((Path *) joinpath->innerjoinpath)->parent->size;
+
+ temp = temp * product_selec(joinpath->pathclauseinfo);
+ if (temp >= (MAXINT - 1))
+ {
+ temp1 = MAXINT;
+ }
+ else
+ {
+
+ /*
+ * should be ceil here, we don't want joinrel size's of one, do
+ * we?
+ */
+ temp1 = ceil((double) temp);
+ }
+ Assert(temp1 >= 0);
+
+ return (temp1);
}
-/*
+/*
* page-size--
- * Returns an estimate of the number of pages covered by a given
- * number of tuples of a given width (size in bytes).
+ * Returns an estimate of the number of pages covered by a given
+ * number of tuples of a given width (size in bytes).
*/
-int page_size(int tuples, int width)
+int
+page_size(int tuples, int width)
{
- int temp =0;
+ int temp = 0;
- temp = ceil((double)(tuples * (width + sizeof(HeapTupleData)))
- / BLCKSZ);
- Assert(temp >= 0);
- return(temp);
+ temp = ceil((double) (tuples * (width + sizeof(HeapTupleData)))
+ / BLCKSZ);
+ Assert(temp >= 0);
+ return (temp);
}
static double
base_log(double x, double b)
{
- return(log(x)/log(b));
+ return (log(x) / log(b));
}
diff --git a/src/backend/optimizer/path/hashutils.c b/src/backend/optimizer/path/hashutils.c
index cdbd9b6d901..5ec592ad1f9 100644
--- a/src/backend/optimizer/path/hashutils.c
+++ b/src/backend/optimizer/path/hashutils.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* hashutils.c--
- * Utilities for finding applicable merge clauses and pathkeys
+ * Utilities for finding applicable merge clauses and pathkeys
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/hashutils.c,v 1.1.1.1 1996/07/09 06:21:35 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/hashutils.c,v 1.2 1997/09/07 04:43:34 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,101 +20,109 @@
#include "optimizer/clauses.h"
-static HInfo *match_hashop_hashinfo(Oid hashop, List *hashinfo_list);
+static HInfo *match_hashop_hashinfo(Oid hashop, List * hashinfo_list);
-/*
+/*
* group-clauses-by-hashop--
- * If a join clause node in 'clauseinfo-list' is hashjoinable, store
- * it within a hashinfo node containing other clause nodes with the same
- * hash operator.
- *
+ * If a join clause node in 'clauseinfo-list' is hashjoinable, store
+ * it within a hashinfo node containing other clause nodes with the same
+ * hash operator.
+ *
* 'clauseinfo-list' is the list of clauseinfo nodes
* 'inner-relid' is the relid of the inner join relation
- *
+ *
* Returns the new list of hashinfo nodes.
- *
+ *
*/
-List *
-group_clauses_by_hashop(List *clauseinfo_list,
- int inner_relid)
+List *
+group_clauses_by_hashop(List * clauseinfo_list,
+ int inner_relid)
{
- List *hashinfo_list = NIL;
- CInfo *clauseinfo = (CInfo*)NULL;
- List *i = NIL;
- Oid hashjoinop = 0;
-
- foreach (i,clauseinfo_list) {
- clauseinfo = (CInfo*)lfirst(i);
- hashjoinop = clauseinfo->hashjoinoperator;
-
- /*
- * Create a new hashinfo node and add it to 'hashinfo-list' if one
- * does not yet exist for this hash operator.
- */
- if (hashjoinop ) {
- HInfo *xhashinfo = (HInfo*)NULL;
- Expr *clause = clauseinfo->clause;
- Var *leftop = get_leftop(clause);
- Var *rightop = get_rightop(clause);
- JoinKey *keys = (JoinKey*)NULL;
-
- xhashinfo =
- match_hashop_hashinfo(hashjoinop,hashinfo_list);
-
- if (inner_relid == leftop->varno){
- keys = makeNode(JoinKey);
- keys->outer = rightop;
- keys->inner = leftop;
- } else {
- keys = makeNode(JoinKey);
- keys->outer = leftop;
- keys->inner = rightop;
- }
-
- if (xhashinfo==NULL) {
- xhashinfo = makeNode(HInfo);
- xhashinfo->hashop = hashjoinop;
-
- xhashinfo->jmethod.jmkeys = NIL;
- xhashinfo->jmethod.clauses = NIL;
-
- /* XXX was push */
- hashinfo_list = lappend(hashinfo_list,xhashinfo);
- hashinfo_list = nreverse(hashinfo_list);
- }
-
- xhashinfo->jmethod.clauses =
- lcons(clause, xhashinfo->jmethod.clauses);
-
- xhashinfo->jmethod.jmkeys =
- lcons(keys, xhashinfo->jmethod.jmkeys);
+ List *hashinfo_list = NIL;
+ CInfo *clauseinfo = (CInfo *) NULL;
+ List *i = NIL;
+ Oid hashjoinop = 0;
+
+ foreach(i, clauseinfo_list)
+ {
+ clauseinfo = (CInfo *) lfirst(i);
+ hashjoinop = clauseinfo->hashjoinoperator;
+
+ /*
+ * Create a new hashinfo node and add it to 'hashinfo-list' if one
+ * does not yet exist for this hash operator.
+ */
+ if (hashjoinop)
+ {
+ HInfo *xhashinfo = (HInfo *) NULL;
+ Expr *clause = clauseinfo->clause;
+ Var *leftop = get_leftop(clause);
+ Var *rightop = get_rightop(clause);
+ JoinKey *keys = (JoinKey *) NULL;
+
+ xhashinfo =
+ match_hashop_hashinfo(hashjoinop, hashinfo_list);
+
+ if (inner_relid == leftop->varno)
+ {
+ keys = makeNode(JoinKey);
+ keys->outer = rightop;
+ keys->inner = leftop;
+ }
+ else
+ {
+ keys = makeNode(JoinKey);
+ keys->outer = leftop;
+ keys->inner = rightop;
+ }
+
+ if (xhashinfo == NULL)
+ {
+ xhashinfo = makeNode(HInfo);
+ xhashinfo->hashop = hashjoinop;
+
+ xhashinfo->jmethod.jmkeys = NIL;
+ xhashinfo->jmethod.clauses = NIL;
+
+ /* XXX was push */
+ hashinfo_list = lappend(hashinfo_list, xhashinfo);
+ hashinfo_list = nreverse(hashinfo_list);
+ }
+
+ xhashinfo->jmethod.clauses =
+ lcons(clause, xhashinfo->jmethod.clauses);
+
+ xhashinfo->jmethod.jmkeys =
+ lcons(keys, xhashinfo->jmethod.jmkeys);
+ }
}
- }
- return(hashinfo_list);
+ return (hashinfo_list);
}
-/*
+/*
* match-hashop-hashinfo--
- * Searches the list 'hashinfo-list' for a hashinfo node whose hash op
- * field equals 'hashop'.
- *
+ * Searches the list 'hashinfo-list' for a hashinfo node whose hash op
+ * field equals 'hashop'.
+ *
* Returns the node if it exists.
- *
+ *
*/
-static HInfo *
-match_hashop_hashinfo(Oid hashop, List *hashinfo_list)
+static HInfo *
+match_hashop_hashinfo(Oid hashop, List * hashinfo_list)
{
- Oid key = 0;
- HInfo *xhashinfo = (HInfo*)NULL;
- List *i = NIL;
-
- foreach( i, hashinfo_list) {
- xhashinfo = (HInfo*)lfirst(i);
- key = xhashinfo->hashop;
- if (hashop == key) { /* found */
- return(xhashinfo); /* should be a hashinfo node ! */
+ Oid key = 0;
+ HInfo *xhashinfo = (HInfo *) NULL;
+ List *i = NIL;
+
+ foreach(i, hashinfo_list)
+ {
+ xhashinfo = (HInfo *) lfirst(i);
+ key = xhashinfo->hashop;
+ if (hashop == key)
+ { /* found */
+ return (xhashinfo); /* should be a hashinfo node ! */
+ }
}
- }
- return((HInfo*)NIL);
+ return ((HInfo *) NIL);
}
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index f5b70e43a0f..bd9bc15ace0 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* indxpath.c--
- * Routines to determine which indices are usable for scanning a
- * given relation
+ * Routines to determine which indices are usable for scanning a
+ * given relation
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.8 1997/08/12 22:53:12 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.9 1997/09/07 04:43:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -43,308 +43,321 @@
#include "catalog/pg_proc.h"
#include "executor/executor.h"
-#include "parser/parsetree.h" /* for getrelid() */
-
-
-static void match_index_orclauses(Rel *rel, Rel *index, int indexkey,
- int xclass, List *clauseinfo_list);
-static bool match_index_to_operand(int indexkey, Expr *operand,
- Rel *rel, Rel *index);
-static List *match_index_orclause(Rel *rel, Rel *index, int indexkey,
- int xclass, List *or_clauses, List *other_matching_indices);
-static List *group_clauses_by_indexkey(Rel *rel, Rel *index,
- int *indexkeys, Oid *classes, List *clauseinfo_list);
-static List *group_clauses_by_ikey_for_joins(Rel *rel, Rel *index,
- int *indexkeys, Oid *classes, List *join_cinfo_list, List *restr_cinfo_list);
-static CInfo *match_clause_to_indexkey(Rel *rel, Rel *index, int indexkey,
- int xclass, CInfo *clauseInfo, bool join);
-static bool pred_test(List *predicate_list, List *clauseinfo_list,
- List *joininfo_list);
-static bool one_pred_test(Expr *predicate, List *clauseinfo_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 List *indexable_joinclauses (Rel *rel, Rel *index,
- List *joininfo_list, List *clauseinfo_list);
-static List *index_innerjoin(Query *root, Rel *rel,
- List *clausegroup_list, Rel *index);
-static List *create_index_paths(Query *root, Rel *rel, Rel *index,
- List *clausegroup_list, bool join);
-static List *add_index_paths(List *indexpaths, List *new_indexpaths);
-static bool function_index_operand(Expr *funcOpnd, Rel *rel, Rel *index);
-static bool SingleAttributeIndex(Rel *index);
+#include "parser/parsetree.h" /* for getrelid() */
+
+
+static void
+match_index_orclauses(Rel * rel, Rel * index, int indexkey,
+ int xclass, List * clauseinfo_list);
+static bool
+match_index_to_operand(int indexkey, Expr * operand,
+ Rel * rel, Rel * index);
+static List *
+match_index_orclause(Rel * rel, Rel * index, int indexkey,
+ int xclass, List * or_clauses, List * other_matching_indices);
+static List *
+group_clauses_by_indexkey(Rel * rel, Rel * index,
+ int *indexkeys, Oid * classes, List * clauseinfo_list);
+static List *
+group_clauses_by_ikey_for_joins(Rel * rel, Rel * index,
+ int *indexkeys, Oid * classes, List * join_cinfo_list, List * restr_cinfo_list);
+static CInfo *
+match_clause_to_indexkey(Rel * rel, Rel * index, int indexkey,
+ int xclass, CInfo * clauseInfo, bool join);
+static bool
+pred_test(List * predicate_list, List * clauseinfo_list,
+ List * joininfo_list);
+static bool one_pred_test(Expr * predicate, List * clauseinfo_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 List *
+indexable_joinclauses(Rel * rel, Rel * index,
+ List * joininfo_list, List * clauseinfo_list);
+static List *
+index_innerjoin(Query * root, Rel * rel,
+ List * clausegroup_list, Rel * index);
+static List *
+create_index_paths(Query * root, Rel * rel, Rel * index,
+ List * clausegroup_list, bool join);
+static List *add_index_paths(List * indexpaths, List * new_indexpaths);
+static bool function_index_operand(Expr * funcOpnd, Rel * rel, Rel * index);
+static bool SingleAttributeIndex(Rel * index);
/* If Spyros can use a constant PRS2_BOOL_TYPEID, I can use this */
#define BOOL_TYPEID ((Oid) 16)
-/*
+/*
* find-index-paths--
- * Finds all possible index paths by determining which indices in the
- * list 'indices' are usable.
- *
- * To be usable, an index must match against either a set of
- * restriction clauses or join clauses.
- *
- * Note that the current implementation requires that there exist
- * matching clauses for every key in the index (i.e., no partial
- * matches are allowed).
- *
- * If an index can't be used with restriction clauses, but its keys
- * match those of the result sort order (according to information stored
- * within 'sortkeys'), then the index is also considered.
+ * Finds all possible index paths by determining which indices in the
+ * list 'indices' are usable.
+ *
+ * To be usable, an index must match against either a set of
+ * restriction clauses or join clauses.
+ *
+ * Note that the current implementation requires that there exist
+ * matching clauses for every key in the index (i.e., no partial
+ * matches are allowed).
+ *
+ * If an index can't be used with restriction clauses, but its keys
+ * match those of the result sort order (according to information stored
+ * within 'sortkeys'), then the index is also considered.
*
* 'rel' is the relation entry to which these index paths correspond
* 'indices' is a list of possible index paths
* 'clauseinfo-list' is a list of restriction clauseinfo nodes for 'rel'
* 'joininfo-list' is a list of joininfo nodes for 'rel'
* 'sortkeys' is a node describing the result sort order (from
- * (find_sortkeys))
- *
+ * (find_sortkeys))
+ *
* Returns a list of index nodes.
- *
+ *
*/
-List *
-find_index_paths (Query *root,
- Rel *rel,
- List *indices,
- List *clauseinfo_list,
- List *joininfo_list)
+List *
+find_index_paths(Query * root,
+ Rel * rel,
+ List * indices,
+ List * clauseinfo_list,
+ List * joininfo_list)
{
- List *scanclausegroups = NIL;
- List *scanpaths = NIL;
- Rel *index = (Rel *)NULL;
- List *joinclausegroups = NIL;
- List *joinpaths = NIL;
- List *retval = NIL;
-
- if(indices == NIL)
- return(NULL);
-
- index = (Rel*)lfirst (indices);
-
- retval = find_index_paths(root,
- rel,
- lnext (indices),
- clauseinfo_list,
- joininfo_list);
-
- /* If this is a partial index, return if it fails the predicate test */
- if (index->indpred != NIL)
- if (!pred_test(index->indpred, clauseinfo_list, joininfo_list))
- return retval;
-
- /* 1. If this index has only one key, try matching it against
- * subclauses of an 'or' clause. The fields of the clauseinfo
- * nodes are marked with lists of the matching indices no path
- * are actually created.
- *
- * XXX NOTE: Currently btrees dos not support indices with
- * > 1 key, so the following test will always be true for
- * now but we have decided not to support index-scans
- * on disjunction . -- lp
- */
- if (SingleAttributeIndex(index))
- {
- match_index_orclauses (rel,
- index,
- index->indexkeys[0],
- index->classlist[0],
- clauseinfo_list);
- }
+ List *scanclausegroups = NIL;
+ List *scanpaths = NIL;
+ Rel *index = (Rel *) NULL;
+ List *joinclausegroups = NIL;
+ List *joinpaths = NIL;
+ List *retval = NIL;
+
+ if (indices == NIL)
+ return (NULL);
+
+ index = (Rel *) lfirst(indices);
+
+ retval = find_index_paths(root,
+ rel,
+ lnext(indices),
+ clauseinfo_list,
+ joininfo_list);
- /*
- * 2. If the keys of this index match any of the available
- * restriction clauses, then create pathnodes corresponding
- * to each group of usable clauses.
- */
- scanclausegroups = group_clauses_by_indexkey(rel,
- index,
- index->indexkeys,
- index->classlist,
- clauseinfo_list);
-
- scanpaths = NIL;
- if (scanclausegroups != NIL)
- scanpaths = create_index_paths (root,
- rel,
- index,
- scanclausegroups,
- false);
-
- /*
- * 3. If this index can be used with any join clause, then
- * create pathnodes for each group of usable clauses. An
- * index can be used with a join clause if its ordering is
- * useful for a mergejoin, or if the index can possibly be
- * used for scanning the inner relation of a nestloop join.
- */
- joinclausegroups = indexable_joinclauses(rel,index,joininfo_list, clauseinfo_list);
- joinpaths = NIL;
-
- if (joinclausegroups != NIL)
+ /* If this is a partial index, return if it fails the predicate test */
+ if (index->indpred != NIL)
+ if (!pred_test(index->indpred, clauseinfo_list, joininfo_list))
+ return retval;
+
+ /*
+ * 1. If this index has only one key, try matching it against
+ * subclauses of an 'or' clause. The fields of the clauseinfo nodes
+ * are marked with lists of the matching indices no path are actually
+ * created.
+ *
+ * XXX NOTE: Currently btrees dos not support indices with > 1 key, so
+ * the following test will always be true for now but we have decided
+ * not to support index-scans on disjunction . -- lp
+ */
+ if (SingleAttributeIndex(index))
{
- List *new_join_paths = create_index_paths(root, rel,
+ match_index_orclauses(rel,
index,
- joinclausegroups,
- true);
- List *innerjoin_paths = index_innerjoin(root, rel,joinclausegroups,index);
+ index->indexkeys[0],
+ index->classlist[0],
+ clauseinfo_list);
+ }
+
+ /*
+ * 2. If the keys of this index match any of the available restriction
+ * clauses, then create pathnodes corresponding to each group of
+ * usable clauses.
+ */
+ scanclausegroups = group_clauses_by_indexkey(rel,
+ index,
+ index->indexkeys,
+ index->classlist,
+ clauseinfo_list);
+
+ scanpaths = NIL;
+ if (scanclausegroups != NIL)
+ scanpaths = create_index_paths(root,
+ rel,
+ index,
+ scanclausegroups,
+ false);
+
+ /*
+ * 3. If this index can be used with any join clause, then create
+ * pathnodes for each group of usable clauses. An index can be used
+ * with a join clause if its ordering is useful for a mergejoin, or if
+ * the index can possibly be used for scanning the inner relation of a
+ * nestloop join.
+ */
+ joinclausegroups = indexable_joinclauses(rel, index, joininfo_list, clauseinfo_list);
+ joinpaths = NIL;
- rel->innerjoin = nconc (rel->innerjoin, innerjoin_paths);
- joinpaths = new_join_paths;
+ if (joinclausegroups != NIL)
+ {
+ List *new_join_paths = create_index_paths(root, rel,
+ index,
+ joinclausegroups,
+ true);
+ List *innerjoin_paths = index_innerjoin(root, rel, joinclausegroups, index);
+
+ rel->innerjoin = nconc(rel->innerjoin, innerjoin_paths);
+ joinpaths = new_join_paths;
}
-
- /*
- * Some sanity checks to make sure that
- * the indexpath is valid.
- */
- if (joinpaths!=NULL)
- retval = add_index_paths(joinpaths,retval);
- if (scanpaths!=NULL)
- retval = add_index_paths(scanpaths,retval);
-
- return retval;
+
+ /*
+ * Some sanity checks to make sure that the indexpath is valid.
+ */
+ if (joinpaths != NULL)
+ retval = add_index_paths(joinpaths, retval);
+ if (scanpaths != NULL)
+ retval = add_index_paths(scanpaths, retval);
+
+ return retval;
}
/****************************************************************************
- * ---- ROUTINES TO MATCH 'OR' CLAUSES ----
+ * ---- ROUTINES TO MATCH 'OR' CLAUSES ----
****************************************************************************/
-/*
+/*
* match-index-orclauses--
- * Attempt to match an index against subclauses within 'or' clauses.
- * If the index does match, then the clause is marked with information
- * about the index.
- *
- * Essentially, this adds 'index' to the list of indices in the
- * ClauseInfo field of each of the clauses which it matches.
- *
+ * Attempt to match an index against subclauses within 'or' clauses.
+ * If the index does match, then the clause is marked with information
+ * about the index.
+ *
+ * Essentially, this adds 'index' to the list of indices in the
+ * ClauseInfo field of each of the clauses which it matches.
+ *
* 'rel' is the node of the relation on which the index is defined.
* 'index' is the index node.
* 'indexkey' is the (single) key of the index
* 'class' is the class of the operator corresponding to 'indexkey'.
* 'clauseinfo-list' is the list of available restriction clauses.
- *
+ *
* Returns nothing.
- *
+ *
*/
static void
-match_index_orclauses(Rel *rel,
- Rel *index,
- int indexkey,
- int xclass,
- List *clauseinfo_list)
+match_index_orclauses(Rel * rel,
+ Rel * index,
+ int indexkey,
+ int xclass,
+ List * clauseinfo_list)
{
- CInfo *clauseinfo = (CInfo*)NULL;
- List *i = NIL;
-
- foreach (i, clauseinfo_list) {
- clauseinfo = (CInfo*)lfirst(i);
- if (valid_or_clause(clauseinfo)) {
-
- /* Mark the 'or' clause with a list of indices which
- * match each of its subclauses. The list is
- * generated by adding 'index' to the existing
- * list where appropriate.
- */
- clauseinfo->indexids =
- match_index_orclause (rel,index,indexkey,
- xclass,
- clauseinfo->clause->args,
- clauseinfo->indexids);
+ CInfo *clauseinfo = (CInfo *) NULL;
+ List *i = NIL;
+
+ foreach(i, clauseinfo_list)
+ {
+ clauseinfo = (CInfo *) lfirst(i);
+ if (valid_or_clause(clauseinfo))
+ {
+
+ /*
+ * Mark the 'or' clause with a list of indices which match
+ * each of its subclauses. The list is generated by adding
+ * 'index' to the existing list where appropriate.
+ */
+ clauseinfo->indexids =
+ match_index_orclause(rel, index, indexkey,
+ xclass,
+ clauseinfo->clause->args,
+ clauseinfo->indexids);
+ }
}
- }
}
/*
* match_index_operand--
- * Generalize test for a match between an existing index's key
- * and the operand on the rhs of a restriction clause. Now check
- * for functional indices as well.
+ * Generalize test for a match between an existing index's key
+ * and the operand on the rhs of a restriction clause. Now check
+ * for functional indices as well.
*/
-static bool
+static bool
match_index_to_operand(int indexkey,
- Expr *operand,
- Rel *rel,
- Rel *index)
+ Expr * operand,
+ Rel * rel,
+ Rel * index)
{
- /*
- * Normal index.
- */
- if (index->indproc == InvalidOid)
- return match_indexkey_operand(indexkey, (Var*)operand, rel);
-
- /*
- * functional index check
- */
- return (function_index_operand(operand, rel, index));
+
+ /*
+ * Normal index.
+ */
+ if (index->indproc == InvalidOid)
+ return match_indexkey_operand(indexkey, (Var *) operand, rel);
+
+ /*
+ * functional index check
+ */
+ return (function_index_operand(operand, rel, index));
}
-/*
+/*
* match-index-orclause--
- * Attempts to match an index against the subclauses of an 'or' clause.
- *
- * A match means that:
- * (1) the operator within the subclause can be used with one
- * of the index's operator classes, and
- * (2) there is a usable key that matches the variable within a
- * sargable clause.
- *
+ * Attempts to match an index against the subclauses of an 'or' clause.
+ *
+ * A match means that:
+ * (1) the operator within the subclause can be used with one
+ * of the index's operator classes, and
+ * (2) there is a usable key that matches the variable within a
+ * sargable clause.
+ *
* 'or-clauses' are the remaining subclauses within the 'or' clause
* 'other-matching-indices' is the list of information on other indices
- * that have already been matched to subclauses within this
- * particular 'or' clause (i.e., a list previously generated by
- * this routine)
- *
+ * that have already been matched to subclauses within this
+ * particular 'or' clause (i.e., a list previously generated by
+ * this routine)
+ *
* 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
* 'or-clauses', d,e,f match the second subclause, no indices
* match the third, g,h match the fourth, etc.
*/
-static List *
-match_index_orclause(Rel *rel,
- Rel *index,
- int indexkey,
- int xclass,
- List *or_clauses,
- List *other_matching_indices)
+static List *
+match_index_orclause(Rel * rel,
+ Rel * index,
+ int indexkey,
+ int xclass,
+ List * or_clauses,
+ List * other_matching_indices)
{
- Node *clause = NULL;
- List *matched_indices = other_matching_indices;
- List *index_list = NIL;
- List *clist;
- List *ind;
-
- if (!matched_indices)
- matched_indices = lcons(NIL, NIL);
-
- for (clist = or_clauses, ind = matched_indices;
- clist;
- clist = lnext(clist), ind = lnext(ind))
+ Node *clause = NULL;
+ List *matched_indices = other_matching_indices;
+ List *index_list = NIL;
+ List *clist;
+ List *ind;
+
+ if (!matched_indices)
+ matched_indices = lcons(NIL, NIL);
+
+ for (clist = or_clauses, ind = matched_indices;
+ clist;
+ clist = lnext(clist), ind = lnext(ind))
{
- clause = lfirst(clist);
- if (is_opclause (clause) &&
- op_class(((Oper*)((Expr*)clause)->oper)->opno,
- xclass, index->relam) &&
- match_index_to_operand(indexkey,
- (Expr*)get_leftop((Expr*)clause),
- rel,
- index) &&
- IsA(get_rightop((Expr*)clause),Const)) {
-
- matched_indices = lcons(index, matched_indices);
- index_list = lappend(index_list,
- matched_indices);
- }
+ clause = lfirst(clist);
+ if (is_opclause(clause) &&
+ op_class(((Oper *) ((Expr *) clause)->oper)->opno,
+ xclass, index->relam) &&
+ match_index_to_operand(indexkey,
+ (Expr *) get_leftop((Expr *) clause),
+ rel,
+ index) &&
+ IsA(get_rightop((Expr *) clause), Const))
+ {
+
+ matched_indices = lcons(index, matched_indices);
+ index_list = lappend(index_list,
+ matched_indices);
+ }
}
- return(index_list);
-
+ return (index_list);
+
}
/****************************************************************************
- * ---- ROUTINES TO CHECK RESTRICTIONS ----
+ * ---- ROUTINES TO CHECK RESTRICTIONS ----
****************************************************************************/
@@ -358,176 +371,177 @@ match_index_orclause(Rel *rel,
* keys list represent the arguments to the function. -mer 3 Oct. 1991
*/
#define DoneMatchingIndexKeys(indexkeys, index) \
- (indexkeys[0] == 0 || \
- (index->indproc != InvalidOid))
+ (indexkeys[0] == 0 || \
+ (index->indproc != InvalidOid))
-/*
+/*
* group-clauses-by-indexkey--
- * Determines whether there are clauses which will match each and every
- * one of the remaining keys of an index.
- *
+ * Determines whether there are clauses which will match each and every
+ * one of the remaining keys of an index.
+ *
* 'rel' is the node of the relation corresponding to the index.
* 'indexkeys' are the remaining index keys to be matched.
* 'classes' are the classes of the index operators on those keys.
* 'clauses' is either:
- * (1) the list of available restriction clauses on a single
- * relation, or
- * (2) a list of join clauses between 'rel' and a fixed set of
- * relations,
- * depending on the value of 'join'.
+ * (1) the list of available restriction clauses on a single
+ * relation, or
+ * (2) a list of join clauses between 'rel' and a fixed set of
+ * relations,
+ * depending on the value of 'join'.
+ *
+ * NOTE: it works now for restriction clauses only. - vadim 03/18/97
*
- * NOTE: it works now for restriction clauses only. - vadim 03/18/97
- *
* Returns all possible groups of clauses that will match (given that
* one or more clauses can match any of the remaining keys).
- * E.g., if you have clauses A, B, and C, ((A B) (A C)) might be
+ * E.g., if you have clauses A, B, and C, ((A B) (A C)) might be
* returned for an index with 2 keys.
- *
+ *
*/
-static List *
-group_clauses_by_indexkey(Rel *rel,
- Rel *index,
- int *indexkeys,
- Oid *classes,
- List *clauseinfo_list)
+static List *
+group_clauses_by_indexkey(Rel * rel,
+ Rel * index,
+ int *indexkeys,
+ Oid * classes,
+ List * clauseinfo_list)
{
- List *curCinfo = NIL;
- CInfo *matched_clause = (CInfo*)NULL;
- List *clausegroup = NIL;
- int curIndxKey;
- Oid curClass;
+ List *curCinfo = NIL;
+ CInfo *matched_clause = (CInfo *) NULL;
+ List *clausegroup = NIL;
+ int curIndxKey;
+ Oid curClass;
- if (clauseinfo_list == NIL)
- return NIL;
+ if (clauseinfo_list == NIL)
+ return NIL;
- while ( !DoneMatchingIndexKeys(indexkeys, index) )
- {
- List *tempgroup = NIL;
-
- curIndxKey = indexkeys[0];
- curClass = classes[0];
-
- foreach (curCinfo,clauseinfo_list)
- {
- CInfo *temp = (CInfo*)lfirst(curCinfo);
-
- matched_clause = match_clause_to_indexkey (rel,
- index,
- curIndxKey,
- curClass,
- temp,
- false);
- if (!matched_clause)
- continue;
-
- tempgroup = lappend(tempgroup, matched_clause);
- }
- if ( tempgroup == NIL )
- break;
+ while (!DoneMatchingIndexKeys(indexkeys, index))
+ {
+ List *tempgroup = NIL;
+
+ curIndxKey = indexkeys[0];
+ curClass = classes[0];
+
+ foreach(curCinfo, clauseinfo_list)
+ {
+ CInfo *temp = (CInfo *) lfirst(curCinfo);
+
+ matched_clause = match_clause_to_indexkey(rel,
+ index,
+ curIndxKey,
+ curClass,
+ temp,
+ false);
+ if (!matched_clause)
+ continue;
- clausegroup = nconc (clausegroup, tempgroup);
-
- indexkeys++;
- classes++;
-
- }
+ tempgroup = lappend(tempgroup, matched_clause);
+ }
+ if (tempgroup == NIL)
+ break;
- /* clausegroup holds all matched clauses ordered by indexkeys */
+ clausegroup = nconc(clausegroup, tempgroup);
+
+ indexkeys++;
+ classes++;
+
+ }
- if (clausegroup != NIL)
- return(lcons(clausegroup, NIL));
- return NIL;
+ /* clausegroup holds all matched clauses ordered by indexkeys */
+
+ if (clausegroup != NIL)
+ return (lcons(clausegroup, NIL));
+ return NIL;
}
-/*
+/*
* group-clauses-by-ikey-for-joins--
- * special edition of group-clauses-by-indexkey - will
- * match join & restriction clauses. See comment in indexable_joinclauses.
- * - vadim 03/18/97
- *
+ * special edition of group-clauses-by-indexkey - will
+ * match join & restriction clauses. See comment in indexable_joinclauses.
+ * - vadim 03/18/97
+ *
*/
-static List *
-group_clauses_by_ikey_for_joins(Rel *rel,
- Rel *index,
- int *indexkeys,
- Oid *classes,
- List *join_cinfo_list,
- List *restr_cinfo_list)
+static List *
+group_clauses_by_ikey_for_joins(Rel * rel,
+ Rel * index,
+ int *indexkeys,
+ Oid * classes,
+ List * join_cinfo_list,
+ List * restr_cinfo_list)
{
- List *curCinfo = NIL;
- CInfo *matched_clause = (CInfo*)NULL;
- List *clausegroup = NIL;
- int curIndxKey;
- Oid curClass;
- bool jfound = false;
-
- if (join_cinfo_list == NIL)
- return NIL;
+ List *curCinfo = NIL;
+ CInfo *matched_clause = (CInfo *) NULL;
+ List *clausegroup = NIL;
+ int curIndxKey;
+ Oid curClass;
+ bool jfound = false;
+
+ if (join_cinfo_list == NIL)
+ return NIL;
+
+ while (!DoneMatchingIndexKeys(indexkeys, index))
+ {
+ List *tempgroup = NIL;
+
+ curIndxKey = indexkeys[0];
+ curClass = classes[0];
+
+ foreach(curCinfo, join_cinfo_list)
+ {
+ CInfo *temp = (CInfo *) lfirst(curCinfo);
+
+ matched_clause = match_clause_to_indexkey(rel,
+ index,
+ curIndxKey,
+ curClass,
+ temp,
+ true);
+ if (!matched_clause)
+ continue;
+
+ tempgroup = lappend(tempgroup, matched_clause);
+ jfound = true;
+ }
+ foreach(curCinfo, restr_cinfo_list)
+ {
+ CInfo *temp = (CInfo *) lfirst(curCinfo);
+
+ matched_clause = match_clause_to_indexkey(rel,
+ index,
+ curIndxKey,
+ curClass,
+ temp,
+ false);
+ if (!matched_clause)
+ continue;
+
+ tempgroup = lappend(tempgroup, matched_clause);
+ }
+ if (tempgroup == NIL)
+ break;
+
+ clausegroup = nconc(clausegroup, tempgroup);
+
+ indexkeys++;
+ classes++;
- while ( !DoneMatchingIndexKeys(indexkeys, index) )
- {
- List *tempgroup = NIL;
-
- curIndxKey = indexkeys[0];
- curClass = classes[0];
-
- foreach (curCinfo,join_cinfo_list)
- {
- CInfo *temp = (CInfo*)lfirst(curCinfo);
-
- matched_clause = match_clause_to_indexkey (rel,
- index,
- curIndxKey,
- curClass,
- temp,
- true);
- if (!matched_clause)
- continue;
-
- tempgroup = lappend(tempgroup, matched_clause);
- jfound = true;
}
- foreach (curCinfo,restr_cinfo_list)
- {
- CInfo *temp = (CInfo*)lfirst(curCinfo);
-
- matched_clause = match_clause_to_indexkey (rel,
- index,
- curIndxKey,
- curClass,
- temp,
- false);
- if (!matched_clause)
- continue;
-
- tempgroup = lappend(tempgroup, matched_clause);
+
+ /* clausegroup holds all matched clauses ordered by indexkeys */
+
+ if (clausegroup != NIL)
+ {
+
+ /*
+ * if no one join clause was matched then there ain't clauses for
+ * joins at all.
+ */
+ if (!jfound)
+ {
+ freeList(clausegroup);
+ return NIL;
+ }
+ return (lcons(clausegroup, NIL));
}
- if ( tempgroup == NIL )
- break;
-
- clausegroup = nconc (clausegroup, tempgroup);
-
- indexkeys++;
- classes++;
-
- }
-
- /* clausegroup holds all matched clauses ordered by indexkeys */
-
- if (clausegroup != NIL)
- {
- /*
- * if no one join clause was matched then there ain't clauses
- * for joins at all.
- */
- if ( !jfound )
- {
- freeList (clausegroup);
- return NIL;
- }
- return(lcons(clausegroup, NIL));
- }
- return NIL;
+ return NIL;
}
/*
@@ -537,798 +551,867 @@ group_clauses_by_ikey_for_joins(Rel *rel,
* Now we can match with functional indices.
*/
#define IndexScanableOperand(opnd, indkeys, rel, index) \
- ((index->indproc == InvalidOid) ? \
- match_indexkey_operand(indkeys, opnd, rel) : \
- function_index_operand((Expr*)opnd,rel,index))
+ ((index->indproc == InvalidOid) ? \
+ match_indexkey_operand(indkeys, opnd, rel) : \
+ function_index_operand((Expr*)opnd,rel,index))
/*
* There was
- * equal_indexkey_var(indkeys,opnd) : \
+ * equal_indexkey_var(indkeys,opnd) : \
* above, and now
- * match_indexkey_operand(indkeys, opnd, rel) : \
+ * match_indexkey_operand(indkeys, opnd, rel) : \
* - vadim 01/22/97
*/
-/*
+/*
* match_clause_to-indexkey--
- * Finds the first of a relation's available restriction clauses that
- * matches a key of an index.
- *
- * To match, the clause must:
- * (1) be in the form (op var const) if the clause is a single-
- * relation clause, and
- * (2) contain an operator which is in the same class as the index
- * operator for this key.
- *
- * If the clause being matched is a join clause, then 'join' is t.
- *
- * Returns a single clauseinfo node corresponding to the matching
+ * Finds the first of a relation's available restriction clauses that
+ * matches a key of an index.
+ *
+ * To match, the clause must:
+ * (1) be in the form (op var const) if the clause is a single-
+ * relation clause, and
+ * (2) contain an operator which is in the same class as the index
+ * operator for this key.
+ *
+ * If the clause being matched is a join clause, then 'join' is t.
+ *
+ * Returns a single clauseinfo node corresponding to the matching
* clause.
*
* NOTE: returns nil if clause is an or_clause.
- *
+ *
*/
-static CInfo *
-match_clause_to_indexkey(Rel *rel,
- Rel *index,
- int indexkey,
- int xclass,
- CInfo *clauseInfo,
- bool join)
+static CInfo *
+match_clause_to_indexkey(Rel * rel,
+ Rel * index,
+ int indexkey,
+ int xclass,
+ CInfo * clauseInfo,
+ bool join)
{
- Expr *clause = clauseInfo->clause;
- Var *leftop, *rightop;
- Oid join_op = InvalidOid;
- Oid restrict_op = InvalidOid;
- bool isIndexable = false;
-
- if (or_clause((Node*)clause) ||
- not_clause((Node*)clause) || single_node((Node*)clause))
- return ((CInfo*)NULL);
-
- leftop = get_leftop(clause);
- rightop = get_rightop(clause);
- /*
- * If this is not a join clause, check for clauses of the form:
- * (operator var/func constant) and (operator constant var/func)
- */
- if (!join)
- {
+ Expr *clause = clauseInfo->clause;
+ Var *leftop,
+ *rightop;
+ Oid join_op = InvalidOid;
+ Oid restrict_op = InvalidOid;
+ bool isIndexable = false;
+
+ if (or_clause((Node *) clause) ||
+ not_clause((Node *) clause) || single_node((Node *) clause))
+ return ((CInfo *) NULL);
+
+ leftop = get_leftop(clause);
+ rightop = get_rightop(clause);
+
/*
- * Check for standard s-argable clause
+ * If this is not a join clause, check for clauses of the form:
+ * (operator var/func constant) and (operator constant var/func)
*/
-#ifdef INDEXSCAN_PATCH
- /* Handle also function parameters. DZ - 27-8-1996 */
- if ((rightop && IsA(rightop,Const)) ||
- (rightop && IsA(rightop,Param)))
-#else
- if (rightop && IsA(rightop,Const))
-#endif
+ if (!join)
{
- restrict_op = ((Oper*)((Expr*)clause)->oper)->opno;
- isIndexable =
- ( op_class(restrict_op, xclass, index->relam) &&
- IndexScanableOperand(leftop,
- indexkey,
- rel,
- index) );
- }
- /*
- * Must try to commute the clause to standard s-arg format.
- */
+ /*
+ * Check for standard s-argable clause
+ */
#ifdef INDEXSCAN_PATCH
- /* ...And here... - vadim 01/22/97 */
- else if ((leftop && IsA(leftop,Const)) ||
- (leftop && IsA(leftop,Param)))
+ /* Handle also function parameters. DZ - 27-8-1996 */
+ if ((rightop && IsA(rightop, Const)) ||
+ (rightop && IsA(rightop, Param)))
#else
- else if (leftop && IsA(leftop,Const))
+ if (rightop && IsA(rightop, Const))
#endif
- {
- restrict_op =
- get_commutator(((Oper*)((Expr*)clause)->oper)->opno);
-
- if ( (restrict_op != InvalidOid) &&
- op_class(restrict_op, xclass, index->relam) &&
- IndexScanableOperand(rightop,
- indexkey,rel,index) )
- {
- isIndexable = true;
+ {
+ restrict_op = ((Oper *) ((Expr *) clause)->oper)->opno;
+ isIndexable =
+ (op_class(restrict_op, xclass, index->relam) &&
+ IndexScanableOperand(leftop,
+ indexkey,
+ rel,
+ index));
+ }
+
/*
- * In place list modification.
- * (op const var/func) -> (op var/func const)
+ * Must try to commute the clause to standard s-arg format.
*/
- CommuteClause((Node*)clause);
- }
- }
- }
- /*
- * Check for an indexable scan on one of the join relations.
- * clause is of the form (operator var/func var/func)
- */
- else
- {
- if (rightop
- && match_index_to_operand(indexkey,(Expr*)rightop,rel,index))
- {
-
- join_op = get_commutator(((Oper*)((Expr*)clause)->oper)->opno);
-
- } else if (leftop
- && match_index_to_operand(indexkey,
- (Expr*)leftop,rel,index))
- {
- join_op = ((Oper*)((Expr*)clause)->oper)->opno;
+#ifdef INDEXSCAN_PATCH
+ /* ...And here... - vadim 01/22/97 */
+ else if ((leftop && IsA(leftop, Const)) ||
+ (leftop && IsA(leftop, Param)))
+#else
+ else if (leftop && IsA(leftop, Const))
+#endif
+ {
+ restrict_op =
+ get_commutator(((Oper *) ((Expr *) clause)->oper)->opno);
+
+ if ((restrict_op != InvalidOid) &&
+ op_class(restrict_op, xclass, index->relam) &&
+ IndexScanableOperand(rightop,
+ indexkey, rel, index))
+ {
+ isIndexable = true;
+
+ /*
+ * In place list modification. (op const var/func) -> (op
+ * var/func const)
+ */
+ CommuteClause((Node *) clause);
+ }
+ }
}
- if ( join_op && op_class(join_op,xclass,index->relam) &&
- join_clause_p((Node*)clause))
+ /*
+ * Check for an indexable scan on one of the join relations. clause is
+ * of the form (operator var/func var/func)
+ */
+ else
{
- isIndexable = true;
-
- /*
- * If we're using the operand's commutator we must
- * commute the clause.
- */
- if (join_op != ((Oper*)((Expr*)clause)->oper)->opno)
- CommuteClause((Node*)clause);
+ if (rightop
+ && match_index_to_operand(indexkey, (Expr *) rightop, rel, index))
+ {
+
+ join_op = get_commutator(((Oper *) ((Expr *) clause)->oper)->opno);
+
+ }
+ else if (leftop
+ && match_index_to_operand(indexkey,
+ (Expr *) leftop, rel, index))
+ {
+ join_op = ((Oper *) ((Expr *) clause)->oper)->opno;
+ }
+
+ if (join_op && op_class(join_op, xclass, index->relam) &&
+ join_clause_p((Node *) clause))
+ {
+ isIndexable = true;
+
+ /*
+ * If we're using the operand's commutator we must commute the
+ * clause.
+ */
+ if (join_op != ((Oper *) ((Expr *) clause)->oper)->opno)
+ CommuteClause((Node *) clause);
+ }
}
- }
- if (isIndexable)
- return(clauseInfo);
+ if (isIndexable)
+ return (clauseInfo);
- return(NULL);
+ return (NULL);
}
/****************************************************************************
- * ---- ROUTINES TO DO PARTIAL INDEX PREDICATE TESTS ----
+ * ---- ROUTINES TO DO PARTIAL INDEX PREDICATE TESTS ----
****************************************************************************/
-/*
+/*
* pred_test--
- * Does the "predicate inclusion test" for partial indexes.
+ * Does the "predicate inclusion test" for partial indexes.
*
- * Recursively checks whether the clauses in clauseinfo_list imply
- * that the given predicate is true.
+ * Recursively checks whether the clauses in clauseinfo_list imply
+ * that the given predicate is true.
*
- * This routine (together with the routines it calls) iterates over
- * ANDs in the predicate first, then reduces the qualification
- * clauses down to their constituent terms, and iterates over ORs
- * in the predicate last. This order is important to make the test
- * succeed whenever possible (assuming the predicate has been
- * successfully cnfify()-ed). --Nels, Jan '93
+ * This routine (together with the routines it calls) iterates over
+ * ANDs in the predicate first, then reduces the qualification
+ * clauses down to their constituent terms, and iterates over ORs
+ * in the predicate last. This order is important to make the test
+ * succeed whenever possible (assuming the predicate has been
+ * successfully cnfify()-ed). --Nels, Jan '93
*/
-static bool
-pred_test(List *predicate_list, List *clauseinfo_list, List *joininfo_list)
+static bool
+pred_test(List * predicate_list, List * clauseinfo_list, List * joininfo_list)
{
- List *pred, *items, *item;
-
- /*
- * Note: if Postgres tried to optimize queries by forming equivalence
- * classes over equi-joined attributes (i.e., if it recognized that a
- * qualification such as "where a.b=c.d and a.b=5" could make use of
- * an index on c.d), then we could use that equivalence class info
- * here with joininfo_list to do more complete tests for the usability
- * of a partial index. For now, the test only uses restriction
- * clauses (those in clauseinfo_list). --Nels, Dec '92
- */
-
- if (predicate_list == NULL)
- return true; /* no predicate: the index is usable */
- if (clauseinfo_list == NULL)
- return false; /* no restriction clauses: the test must fail */
-
- foreach (pred, predicate_list) {
- /* if any clause is not implied, the whole predicate is not implied */
- if (and_clause(lfirst(pred))) {
- items = ((Expr*)lfirst(pred))->args;
- foreach (item, items) {
- if (!one_pred_test(lfirst(item), clauseinfo_list))
- return false;
- }
+ List *pred,
+ *items,
+ *item;
+
+ /*
+ * Note: if Postgres tried to optimize queries by forming equivalence
+ * classes over equi-joined attributes (i.e., if it recognized that a
+ * qualification such as "where a.b=c.d and a.b=5" could make use of
+ * an index on c.d), then we could use that equivalence class info
+ * here with joininfo_list to do more complete tests for the usability
+ * of a partial index. For now, the test only uses restriction
+ * clauses (those in clauseinfo_list). --Nels, Dec '92
+ */
+
+ if (predicate_list == NULL)
+ return true; /* no predicate: the index is usable */
+ if (clauseinfo_list == NULL)
+ return false; /* no restriction clauses: the test must
+ * fail */
+
+ foreach(pred, predicate_list)
+ {
+
+ /*
+ * if any clause is not implied, the whole predicate is not
+ * implied
+ */
+ if (and_clause(lfirst(pred)))
+ {
+ items = ((Expr *) lfirst(pred))->args;
+ foreach(item, items)
+ {
+ if (!one_pred_test(lfirst(item), clauseinfo_list))
+ return false;
+ }
+ }
+ else if (!one_pred_test(lfirst(pred), clauseinfo_list))
+ return false;
}
- else if (!one_pred_test(lfirst(pred), clauseinfo_list))
- return false;
- }
- return true;
+ return true;
}
-/*
+/*
* one_pred_test--
- * Does the "predicate inclusion test" for one conjunct of a predicate
- * expression.
+ * Does the "predicate inclusion test" for one conjunct of a predicate
+ * expression.
*/
-static bool
-one_pred_test(Expr *predicate, List *clauseinfo_list)
+static bool
+one_pred_test(Expr * predicate, List * clauseinfo_list)
{
- CInfo *clauseinfo;
- List *item;
-
- Assert(predicate != NULL);
- foreach (item, clauseinfo_list) {
- clauseinfo = (CInfo *)lfirst(item);
- /* if any clause implies the predicate, return true */
- if (one_pred_clause_expr_test(predicate, (Node*)clauseinfo->clause))
- return true;
- }
- return false;
+ CInfo *clauseinfo;
+ List *item;
+
+ Assert(predicate != NULL);
+ foreach(item, clauseinfo_list)
+ {
+ clauseinfo = (CInfo *) lfirst(item);
+ /* if any clause implies the predicate, return true */
+ if (one_pred_clause_expr_test(predicate, (Node *) clauseinfo->clause))
+ return true;
+ }
+ return false;
}
-/*
+/*
* one_pred_clause_expr_test--
- * Does the "predicate inclusion test" for a general restriction-clause
- * expression.
+ * Does the "predicate inclusion test" for a general restriction-clause
+ * expression.
*/
-static bool
-one_pred_clause_expr_test(Expr *predicate, Node *clause)
+static bool
+one_pred_clause_expr_test(Expr * predicate, Node * clause)
{
- List *items, *item;
-
- if (is_opclause(clause))
- return one_pred_clause_test(predicate, clause);
- else if (or_clause(clause)) {
- items = ((Expr*)clause)->args;
- foreach (item, items) {
- /* if any OR item doesn't imply the predicate, clause doesn't */
- if (!one_pred_clause_expr_test(predicate, lfirst(item)))
+ List *items,
+ *item;
+
+ if (is_opclause(clause))
+ return one_pred_clause_test(predicate, clause);
+ else if (or_clause(clause))
+ {
+ items = ((Expr *) clause)->args;
+ foreach(item, items)
+ {
+ /* if any OR item doesn't imply the predicate, clause doesn't */
+ if (!one_pred_clause_expr_test(predicate, lfirst(item)))
+ return false;
+ }
+ return true;
+ }
+ else if (and_clause(clause))
+ {
+ items = ((Expr *) clause)->args;
+ foreach(item, items)
+ {
+
+ /*
+ * if any AND item implies the predicate, the whole clause
+ * does
+ */
+ if (one_pred_clause_expr_test(predicate, lfirst(item)))
+ return true;
+ }
return false;
}
- return true;
- }else if (and_clause(clause)) {
- items = ((Expr*)clause)->args;
- foreach (item, items) {
- /* if any AND item implies the predicate, the whole clause does */
- if (one_pred_clause_expr_test(predicate, lfirst(item)))
- return true;
+ else
+ {
+ /* unknown clause type never implies the predicate */
+ return false;
}
- return false;
- }else {
- /* unknown clause type never implies the predicate */
- return false;
- }
}
-/*
+/*
* one_pred_clause_test--
- * Does the "predicate inclusion test" for one conjunct of a predicate
- * expression for a simple restriction clause.
+ * Does the "predicate inclusion test" for one conjunct of a predicate
+ * expression for a simple restriction clause.
*/
-static bool
-one_pred_clause_test(Expr *predicate, Node *clause)
+static bool
+one_pred_clause_test(Expr * predicate, Node * clause)
{
- List *items, *item;
-
- if (is_opclause((Node*)predicate))
- return clause_pred_clause_test(predicate, clause);
- else if (or_clause((Node*)predicate)) {
- items = predicate->args;
- foreach (item, items) {
- /* if any item is implied, the whole predicate is implied */
- if (one_pred_clause_test(lfirst(item), clause))
+ List *items,
+ *item;
+
+ if (is_opclause((Node *) predicate))
+ return clause_pred_clause_test(predicate, clause);
+ else if (or_clause((Node *) predicate))
+ {
+ items = predicate->args;
+ foreach(item, items)
+ {
+ /* if any item is implied, the whole predicate is implied */
+ if (one_pred_clause_test(lfirst(item), clause))
+ return true;
+ }
+ return false;
+ }
+ else if (and_clause((Node *) predicate))
+ {
+ items = predicate->args;
+ foreach(item, items)
+ {
+
+ /*
+ * if any item is not implied, the whole predicate is not
+ * implied
+ */
+ if (!one_pred_clause_test(lfirst(item), clause))
+ return false;
+ }
return true;
}
- return false;
- }else if (and_clause((Node*)predicate)) {
- items = predicate->args;
- foreach (item, items) {
- /*
- * if any item is not implied, the whole predicate is not
- * implied
- */
- if (!one_pred_clause_test(lfirst(item), clause))
+ else
+ {
+ elog(DEBUG, "Unsupported predicate type, index will not be used");
return false;
}
- return true;
- }
- else {
- elog(DEBUG, "Unsupported predicate type, index will not be used");
- return false;
- }
}
/*
* Define an "operator implication table" for btree operators ("strategies").
- * The "strategy numbers" are: (1) < (2) <= (3) = (4) >= (5) >
+ * The "strategy numbers" are: (1) < (2) <= (3) = (4) >= (5) >
*
* The interpretation of:
*
- * test_op = BT_implic_table[given_op-1][target_op-1]
+ * test_op = BT_implic_table[given_op-1][target_op-1]
*
* where test_op, given_op and target_op are strategy numbers (from 1 to 5)
* of btree operators, is as follows:
*
- * If you know, for some ATTR, that "ATTR given_op CONST1" is true, and you
- * want to determine whether "ATTR target_op CONST2" must also be true, then
- * you can use "CONST1 test_op CONST2" as a test. If this test returns true,
- * then the target expression must be true; if the test returns false, then
- * the target expression may be false.
+ * If you know, for some ATTR, that "ATTR given_op CONST1" is true, and you
+ * want to determine whether "ATTR target_op CONST2" must also be true, then
+ * you can use "CONST1 test_op CONST2" as a test. If this test returns true,
+ * then the target expression must be true; if the test returns false, then
+ * the target expression may be false.
*
* An entry where test_op==0 means the implication cannot be determined, i.e.,
* this test should always be considered false.
*/
-StrategyNumber BT_implic_table[BTMaxStrategyNumber][BTMaxStrategyNumber] = {
- {2, 2, 0, 0, 0},
- {1, 2, 0, 0, 0},
- {1, 2, 3, 4, 5},
- {0, 0, 0, 4, 5},
- {0, 0, 0, 4, 4}
+StrategyNumber BT_implic_table[BTMaxStrategyNumber][BTMaxStrategyNumber] = {
+ {2, 2, 0, 0, 0},
+ {1, 2, 0, 0, 0},
+ {1, 2, 3, 4, 5},
+ {0, 0, 0, 4, 5},
+ {0, 0, 0, 4, 4}
};
-/*
+/*
* clause_pred_clause_test--
- * Use operator class info to check whether clause implies predicate.
- *
- * Does the "predicate inclusion test" for a "simple clause" predicate
- * for a single "simple clause" restriction. Currently, this only handles
- * (binary boolean) operators that are in some btree operator class.
- * Eventually, rtree operators could also be handled by defining an
- * appropriate "RT_implic_table" array.
+ * Use operator class info to check whether clause implies predicate.
+ *
+ * Does the "predicate inclusion test" for a "simple clause" predicate
+ * for a single "simple clause" restriction. Currently, this only handles
+ * (binary boolean) operators that are in some btree operator class.
+ * Eventually, rtree operators could also be handled by defining an
+ * appropriate "RT_implic_table" array.
*/
-static bool
-clause_pred_clause_test(Expr *predicate, Node *clause)
+static bool
+clause_pred_clause_test(Expr * predicate, Node * clause)
{
- Var *pred_var, *clause_var;
- Const *pred_const, *clause_const;
- Oid pred_op, clause_op, test_op;
- Oid opclass_id;
- StrategyNumber pred_strategy, clause_strategy, test_strategy;
- Oper *test_oper;
- Expr *test_expr;
- bool test_result, isNull;
- Relation relation;
- HeapScanDesc scan;
- HeapTuple tuple;
- ScanKeyData entry[3];
- Form_pg_amop form;
-
- pred_var = (Var*)get_leftop(predicate);
- pred_const = (Const*)get_rightop(predicate);
- clause_var = (Var*)get_leftop((Expr*)clause);
- clause_const = (Const*)get_rightop((Expr*)clause);
-
- /* Check the basic form; for now, only allow the simplest case */
- if (!is_opclause(clause) ||
- !IsA(clause_var,Var) ||
- !IsA(clause_const,Const) ||
- !IsA(predicate->oper,Oper) ||
- !IsA(pred_var,Var) ||
- !IsA(pred_const,Const)) {
- return false;
- }
+ Var *pred_var,
+ *clause_var;
+ Const *pred_const,
+ *clause_const;
+ Oid pred_op,
+ clause_op,
+ test_op;
+ Oid opclass_id;
+ StrategyNumber pred_strategy,
+ clause_strategy,
+ test_strategy;
+ Oper *test_oper;
+ Expr *test_expr;
+ bool test_result,
+ isNull;
+ Relation relation;
+ HeapScanDesc scan;
+ HeapTuple tuple;
+ ScanKeyData entry[3];
+ Form_pg_amop form;
+
+ pred_var = (Var *) get_leftop(predicate);
+ pred_const = (Const *) get_rightop(predicate);
+ clause_var = (Var *) get_leftop((Expr *) clause);
+ clause_const = (Const *) get_rightop((Expr *) clause);
+
+ /* Check the basic form; for now, only allow the simplest case */
+ if (!is_opclause(clause) ||
+ !IsA(clause_var, Var) ||
+ !IsA(clause_const, Const) ||
+ !IsA(predicate->oper, Oper) ||
+ !IsA(pred_var, Var) ||
+ !IsA(pred_const, Const))
+ {
+ return false;
+ }
- /*
- * The implication can't be determined unless the predicate and the clause
- * refer to the same attribute.
- */
- if (clause_var->varattno != pred_var->varattno)
- return false;
+ /*
+ * The implication can't be determined unless the predicate and the
+ * clause refer to the same attribute.
+ */
+ if (clause_var->varattno != pred_var->varattno)
+ return false;
- /* Get the operators for the two clauses we're comparing */
- pred_op = ((Oper*)((Expr*)predicate)->oper)->opno;
- clause_op = ((Oper*)((Expr*)clause)->oper)->opno;
-
-
- /*
- * 1. Find a "btree" strategy number for the pred_op
- */
- /* XXX - hardcoded amopid value 403 to find "btree" operator classes */
- ScanKeyEntryInitialize(&entry[0], 0,
- Anum_pg_amop_amopid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(403));
-
- ScanKeyEntryInitialize(&entry[1], 0,
- Anum_pg_amop_amopopr,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(pred_op));
-
- relation = heap_openr(AccessMethodOperatorRelationName);
-
- /*
- * The following assumes that any given operator will only be in a single
- * btree operator class. This is true at least for all the pre-defined
- * operator classes. If it isn't true, then whichever operator class
- * happens to be returned first for the given operator will be used to
- * find the associated strategy numbers for the test. --Nels, Jan '93
- */
- scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
- tuple = heap_getnext(scan, false, (Buffer *)NULL);
- if (! HeapTupleIsValid(tuple)) {
- elog(DEBUG, "clause_pred_clause_test: unknown pred_op");
- return false;
- }
- form = (Form_pg_amop) GETSTRUCT(tuple);
+ /* Get the operators for the two clauses we're comparing */
+ pred_op = ((Oper *) ((Expr *) predicate)->oper)->opno;
+ clause_op = ((Oper *) ((Expr *) clause)->oper)->opno;
- /* Get the predicate operator's strategy number (1 to 5) */
- pred_strategy = (StrategyNumber)form->amopstrategy;
- /* Remember which operator class this strategy number came from */
- opclass_id = form->amopclaid;
+ /*
+ * 1. Find a "btree" strategy number for the pred_op
+ */
+ /* XXX - hardcoded amopid value 403 to find "btree" operator classes */
+ ScanKeyEntryInitialize(&entry[0], 0,
+ Anum_pg_amop_amopid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(403));
- heap_endscan(scan);
+ ScanKeyEntryInitialize(&entry[1], 0,
+ Anum_pg_amop_amopopr,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(pred_op));
+ relation = heap_openr(AccessMethodOperatorRelationName);
- /*
- * 2. From the same opclass, find a strategy num for the clause_op
- */
- ScanKeyEntryInitialize(&entry[1], 0,
- Anum_pg_amop_amopclaid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(opclass_id));
+ /*
+ * The following assumes that any given operator will only be in a
+ * single btree operator class. This is true at least for all the
+ * pre-defined operator classes. If it isn't true, then whichever
+ * operator class happens to be returned first for the given operator
+ * will be used to find the associated strategy numbers for the test.
+ * --Nels, Jan '93
+ */
+ scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
+ tuple = heap_getnext(scan, false, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(DEBUG, "clause_pred_clause_test: unknown pred_op");
+ return false;
+ }
+ form = (Form_pg_amop) GETSTRUCT(tuple);
- ScanKeyEntryInitialize(&entry[2], 0,
- Anum_pg_amop_amopopr,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(clause_op));
+ /* Get the predicate operator's strategy number (1 to 5) */
+ pred_strategy = (StrategyNumber) form->amopstrategy;
- scan = heap_beginscan(relation, false, NowTimeQual, 3, entry);
- tuple = heap_getnext(scan, false, (Buffer *)NULL);
- if (! HeapTupleIsValid(tuple)) {
- elog(DEBUG, "clause_pred_clause_test: unknown clause_op");
- return false;
- }
- form = (Form_pg_amop) GETSTRUCT(tuple);
+ /* Remember which operator class this strategy number came from */
+ opclass_id = form->amopclaid;
- /* Get the restriction clause operator's strategy number (1 to 5) */
- clause_strategy = (StrategyNumber)form->amopstrategy;
- heap_endscan(scan);
+ heap_endscan(scan);
- /*
- * 3. Look up the "test" strategy number in the implication table
- */
+ /*
+ * 2. From the same opclass, find a strategy num for the clause_op
+ */
+ ScanKeyEntryInitialize(&entry[1], 0,
+ Anum_pg_amop_amopclaid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(opclass_id));
+
+ ScanKeyEntryInitialize(&entry[2], 0,
+ Anum_pg_amop_amopopr,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(clause_op));
+
+ scan = heap_beginscan(relation, false, NowTimeQual, 3, entry);
+ tuple = heap_getnext(scan, false, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(DEBUG, "clause_pred_clause_test: unknown clause_op");
+ return false;
+ }
+ form = (Form_pg_amop) GETSTRUCT(tuple);
- test_strategy = BT_implic_table[clause_strategy-1][pred_strategy-1];
- if (test_strategy == 0)
- return false; /* the implication cannot be determined */
+ /* Get the restriction clause operator's strategy number (1 to 5) */
+ clause_strategy = (StrategyNumber) form->amopstrategy;
+ heap_endscan(scan);
- /*
- * 4. From the same opclass, find the operator for the test strategy
- */
+ /*
+ * 3. Look up the "test" strategy number in the implication table
+ */
- ScanKeyEntryInitialize(&entry[2], 0,
- Anum_pg_amop_amopstrategy,
- Integer16EqualRegProcedure,
- Int16GetDatum(test_strategy));
+ test_strategy = BT_implic_table[clause_strategy - 1][pred_strategy - 1];
+ if (test_strategy == 0)
+ return false; /* the implication cannot be determined */
- scan = heap_beginscan(relation, false, NowTimeQual, 3, entry);
- tuple = heap_getnext(scan, false, (Buffer *)NULL);
- if (! HeapTupleIsValid(tuple)) {
- elog(DEBUG, "clause_pred_clause_test: unknown test_op");
- return false;
- }
- form = (Form_pg_amop) GETSTRUCT(tuple);
- /* Get the test operator */
- test_op = form->amopopr;
- heap_endscan(scan);
+ /*
+ * 4. From the same opclass, find the operator for the test strategy
+ */
+ ScanKeyEntryInitialize(&entry[2], 0,
+ Anum_pg_amop_amopstrategy,
+ Integer16EqualRegProcedure,
+ Int16GetDatum(test_strategy));
- /*
- * 5. Evaluate the test
- */
- test_oper = makeOper(test_op, /* opno */
- InvalidOid, /* opid */
- BOOL_TYPEID, /* opresulttype */
- 0, /* opsize */
- NULL); /* op_fcache */
- replace_opid(test_oper);
+ scan = heap_beginscan(relation, false, NowTimeQual, 3, entry);
+ tuple = heap_getnext(scan, false, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(DEBUG, "clause_pred_clause_test: unknown test_op");
+ return false;
+ }
+ form = (Form_pg_amop) GETSTRUCT(tuple);
+
+ /* Get the test operator */
+ test_op = form->amopopr;
+ heap_endscan(scan);
- test_expr = make_opclause(test_oper,
- copyObject(clause_const),
- copyObject(pred_const));
+
+ /*
+ * 5. Evaluate the test
+ */
+ test_oper = makeOper(test_op, /* opno */
+ InvalidOid, /* opid */
+ BOOL_TYPEID, /* opresulttype */
+ 0, /* opsize */
+ NULL); /* op_fcache */
+ replace_opid(test_oper);
+
+ test_expr = make_opclause(test_oper,
+ copyObject(clause_const),
+ copyObject(pred_const));
#ifndef OMIT_PARTIAL_INDEX
- test_result = ExecEvalExpr((Node*)test_expr, NULL, &isNull, NULL);
-#endif /* OMIT_PARTIAL_INDEX */
- if (isNull) {
- elog(DEBUG, "clause_pred_clause_test: null test result");
- return false;
- }
- return test_result;
+ test_result = ExecEvalExpr((Node *) test_expr, NULL, &isNull, NULL);
+#endif /* OMIT_PARTIAL_INDEX */
+ if (isNull)
+ {
+ elog(DEBUG, "clause_pred_clause_test: null test result");
+ return false;
+ }
+ return test_result;
}
/****************************************************************************
- * ---- ROUTINES TO CHECK JOIN CLAUSES ----
+ * ---- ROUTINES TO CHECK JOIN CLAUSES ----
****************************************************************************/
-/*
+/*
* indexable-joinclauses--
- * Finds all groups of join clauses from among 'joininfo-list' that can
- * be used in conjunction with 'index'.
- *
- * The first clause in the group is marked as having the other relation
- * in the join clause as its outer join relation.
- *
+ * Finds all groups of join clauses from among 'joininfo-list' that can
+ * be used in conjunction with 'index'.
+ *
+ * The first clause in the group is marked as having the other relation
+ * in the join clause as its outer join relation.
+ *
* Returns a list of these clause groups.
*
- * Added: clauseinfo_list - list of restriction CInfos. It's to
- * support multi-column indices in joins and for cases
- * when a key is in both join & restriction clauses. - vadim 03/18/97
- *
+ * Added: clauseinfo_list - list of restriction CInfos. It's to
+ * support multi-column indices in joins and for cases
+ * when a key is in both join & restriction clauses. - vadim 03/18/97
+ *
*/
-static List *
-indexable_joinclauses(Rel *rel, Rel *index,
- List *joininfo_list, List *clauseinfo_list)
+static List *
+indexable_joinclauses(Rel * rel, Rel * index,
+ List * joininfo_list, List * clauseinfo_list)
{
- JInfo *joininfo = (JInfo*)NULL;
- List *cg_list = NIL;
- List *i = NIL;
- List *clausegroups = NIL;
-
- foreach(i,joininfo_list) {
- joininfo = (JInfo*)lfirst(i);
-
- if ( joininfo->jinfoclauseinfo == NIL )
- continue;
- clausegroups =
- group_clauses_by_ikey_for_joins (rel,
- index,
- index->indexkeys,
- index->classlist,
- joininfo->jinfoclauseinfo,
- clauseinfo_list);
-
- if (clausegroups != NIL) {
- List *clauses = lfirst(clausegroups);
-
- ((CInfo*)lfirst(clauses))->cinfojoinid =
- joininfo->otherrels;
+ JInfo *joininfo = (JInfo *) NULL;
+ List *cg_list = NIL;
+ List *i = NIL;
+ List *clausegroups = NIL;
+
+ foreach(i, joininfo_list)
+ {
+ joininfo = (JInfo *) lfirst(i);
+
+ if (joininfo->jinfoclauseinfo == NIL)
+ continue;
+ clausegroups =
+ group_clauses_by_ikey_for_joins(rel,
+ index,
+ index->indexkeys,
+ index->classlist,
+ joininfo->jinfoclauseinfo,
+ clauseinfo_list);
+
+ if (clausegroups != NIL)
+ {
+ List *clauses = lfirst(clausegroups);
+
+ ((CInfo *) lfirst(clauses))->cinfojoinid =
+ joininfo->otherrels;
+ }
+ cg_list = nconc(cg_list, clausegroups);
}
- cg_list = nconc(cg_list,clausegroups);
- }
- return(cg_list);
+ return (cg_list);
}
/****************************************************************************
- * ---- PATH CREATION UTILITIES ----
+ * ---- PATH CREATION UTILITIES ----
****************************************************************************/
/*
* extract_restrict_clauses -
- * the list of clause info contains join clauses and restriction clauses.
- * This routine returns the restriction clauses only.
+ * the list of clause info contains join clauses and restriction clauses.
+ * This routine returns the restriction clauses only.
*/
#ifdef NOT_USED
-static List *
-extract_restrict_clauses(List *clausegroup)
+static List *
+extract_restrict_clauses(List * clausegroup)
{
- List *restrict_cls = NIL;
- List *l;
-
- foreach (l, clausegroup) {
- CInfo *cinfo = lfirst(l);
-
- if (!join_clause_p((Node*)cinfo->clause)) {
- restrict_cls = lappend(restrict_cls, cinfo);
+ List *restrict_cls = NIL;
+ List *l;
+
+ foreach(l, clausegroup)
+ {
+ CInfo *cinfo = lfirst(l);
+
+ if (!join_clause_p((Node *) cinfo->clause))
+ {
+ restrict_cls = lappend(restrict_cls, cinfo);
+ }
}
- }
- return restrict_cls;
+ return restrict_cls;
}
+
#endif
-/*
+/*
* index-innerjoin--
- * Creates index path nodes corresponding to paths to be used as inner
- * relations in nestloop joins.
+ * Creates index path nodes corresponding to paths to be used as inner
+ * relations in nestloop joins.
*
* 'clausegroup-list' is a list of list of clauseinfo nodes which can use
* 'index' on their inner relation.
- *
+ *
* Returns a list of index pathnodes.
- *
+ *
*/
-static List *
-index_innerjoin(Query *root, Rel *rel, List *clausegroup_list, Rel *index)
+static List *
+index_innerjoin(Query * root, Rel * rel, List * clausegroup_list, Rel * index)
{
- List *clausegroup = NIL;
- List *cg_list = NIL;
- List *i = NIL;
- IndexPath *pathnode = (IndexPath*)NULL;
- Cost temp_selec;
- float temp_pages;
-
- foreach(i,clausegroup_list) {
- List *attnos, *values, *flags;
-
- clausegroup = lfirst(i);
- pathnode = makeNode(IndexPath);
-
- get_joinvars(lfirsti(rel->relids),clausegroup,
- &attnos, &values, &flags);
- index_selectivity(lfirsti(index->relids),
- index->classlist,
- get_opnos(clausegroup),
- getrelid(lfirsti(rel->relids),
- root->rtable),
- attnos,
- values,
- flags,
- length(clausegroup),
- &temp_pages,
- &temp_selec);
- pathnode->path.pathtype = T_IndexScan;
- pathnode->path.parent = rel;
- pathnode->indexid = index->relids;
- pathnode->indexkeys = index->indexkeys;
- pathnode->indexqual = clausegroup;
-
- pathnode->path.joinid = ((CInfo*)lfirst(clausegroup))->cinfojoinid;
-
- pathnode->path.path_cost =
- cost_index((Oid)lfirsti(index->relids),
- (int)temp_pages,
- temp_selec,
- rel->pages,
- rel->tuples,
- index->pages,
- index->tuples,
- true);
-
- /* copy clauseinfo list into path for expensive function processing
- -- JMH, 7/7/92 */
- pathnode->path.locclauseinfo =
- set_difference(copyObject((Node*)rel->clauseinfo),
- clausegroup);
-
-#if 0 /* fix xfunc */
- /* add in cost for expensive functions! -- JMH, 7/7/92 */
- if (XfuncMode != XFUNC_OFF) {
- ((Path*)pathnode)->path_cost +=
- xfunc_get_path_cost((Path*)pathnode);
- }
+ List *clausegroup = NIL;
+ List *cg_list = NIL;
+ List *i = NIL;
+ IndexPath *pathnode = (IndexPath *) NULL;
+ Cost temp_selec;
+ float temp_pages;
+
+ foreach(i, clausegroup_list)
+ {
+ List *attnos,
+ *values,
+ *flags;
+
+ clausegroup = lfirst(i);
+ pathnode = makeNode(IndexPath);
+
+ get_joinvars(lfirsti(rel->relids), clausegroup,
+ &attnos, &values, &flags);
+ index_selectivity(lfirsti(index->relids),
+ index->classlist,
+ get_opnos(clausegroup),
+ getrelid(lfirsti(rel->relids),
+ root->rtable),
+ attnos,
+ values,
+ flags,
+ length(clausegroup),
+ &temp_pages,
+ &temp_selec);
+ pathnode->path.pathtype = T_IndexScan;
+ pathnode->path.parent = rel;
+ pathnode->indexid = index->relids;
+ pathnode->indexkeys = index->indexkeys;
+ pathnode->indexqual = clausegroup;
+
+ pathnode->path.joinid = ((CInfo *) lfirst(clausegroup))->cinfojoinid;
+
+ pathnode->path.path_cost =
+ cost_index((Oid) lfirsti(index->relids),
+ (int) temp_pages,
+ temp_selec,
+ rel->pages,
+ rel->tuples,
+ index->pages,
+ index->tuples,
+ true);
+
+ /*
+ * copy clauseinfo list into path for expensive function
+ * processing -- JMH, 7/7/92
+ */
+ pathnode->path.locclauseinfo =
+ set_difference(copyObject((Node *) rel->clauseinfo),
+ clausegroup);
+
+#if 0 /* fix xfunc */
+ /* add in cost for expensive functions! -- JMH, 7/7/92 */
+ if (XfuncMode != XFUNC_OFF)
+ {
+ ((Path *) pathnode)->path_cost +=
+ xfunc_get_path_cost((Path *) pathnode);
+ }
#endif
- cg_list = lappend(cg_list,pathnode);
- }
- return(cg_list);
+ cg_list = lappend(cg_list, pathnode);
+ }
+ return (cg_list);
}
-/*
+/*
* create-index-paths--
- * Creates a list of index path nodes for each group of clauses
- * (restriction or join) that can be used in conjunction with an index.
- *
+ * Creates a list of index path nodes for each group of clauses
+ * (restriction or join) that can be used in conjunction with an index.
+ *
* 'rel' is the relation for which 'index' is defined
- * 'clausegroup-list' is the list of clause groups (lists of clauseinfo
- * nodes) grouped by mergesortorder
+ * 'clausegroup-list' is the list of clause groups (lists of clauseinfo
+ * nodes) grouped by mergesortorder
* 'join' is a flag indicating whether or not the clauses are join
- * clauses
- *
+ * clauses
+ *
* Returns a list of new index path nodes.
- *
+ *
*/
-static List *
-create_index_paths(Query *root,
- Rel *rel,
- Rel *index,
- List *clausegroup_list,
- bool join)
+static List *
+create_index_paths(Query * root,
+ Rel * rel,
+ Rel * index,
+ List * clausegroup_list,
+ bool join)
{
- List *clausegroup = NIL;
- List *ip_list = NIL;
- List *i = NIL;
- List *j = NIL;
- IndexPath *temp_path;
-
- foreach(i, clausegroup_list) {
- CInfo *clauseinfo;
- List *temp_node = NIL;
- bool temp = true;
-
- clausegroup = lfirst(i);
-
- foreach (j,clausegroup) {
- clauseinfo = (CInfo*)lfirst(j);
- if (!(join_clause_p((Node*)clauseinfo->clause) &&
- equal_path_merge_ordering(index->ordering,
- clauseinfo->mergesortorder))) {
- temp = false;
- }
- }
+ List *clausegroup = NIL;
+ List *ip_list = NIL;
+ List *i = NIL;
+ List *j = NIL;
+ IndexPath *temp_path;
- if (!join || temp) { /* restriction, ordering scan */
- temp_path = create_index_path (root, rel,index,clausegroup,join);
- temp_node =
- lcons(temp_path, NIL);
- ip_list = nconc(ip_list,temp_node);
- }
- }
- return(ip_list);
+ foreach(i, clausegroup_list)
+ {
+ CInfo *clauseinfo;
+ List *temp_node = NIL;
+ bool temp = true;
+
+ clausegroup = lfirst(i);
+
+ foreach(j, clausegroup)
+ {
+ clauseinfo = (CInfo *) lfirst(j);
+ if (!(join_clause_p((Node *) clauseinfo->clause) &&
+ equal_path_merge_ordering(index->ordering,
+ clauseinfo->mergesortorder)))
+ {
+ temp = false;
+ }
+ }
+
+ if (!join || temp)
+ { /* restriction, ordering scan */
+ temp_path = create_index_path(root, rel, index, clausegroup, join);
+ temp_node =
+ lcons(temp_path, NIL);
+ ip_list = nconc(ip_list, temp_node);
+ }
+ }
+ return (ip_list);
}
-static List *
-add_index_paths(List *indexpaths, List *new_indexpaths)
+static List *
+add_index_paths(List * indexpaths, List * new_indexpaths)
{
- return append(indexpaths, new_indexpaths);
+ return append(indexpaths, new_indexpaths);
}
-static bool
-function_index_operand(Expr *funcOpnd, Rel *rel, Rel *index)
+static bool
+function_index_operand(Expr * funcOpnd, Rel * rel, Rel * index)
{
- Oid heapRelid = (Oid)lfirsti(rel->relids);
- Func *function;
- List *funcargs;
- int *indexKeys = index->indexkeys;
- List *arg;
- int i;
-
- /*
- * sanity check, make sure we know what we're dealing with here.
- */
- if (funcOpnd==NULL ||
- nodeTag(funcOpnd)!=T_Expr || funcOpnd->opType!=FUNC_EXPR ||
- funcOpnd->oper==NULL || indexKeys==NULL)
- return false;
+ Oid heapRelid = (Oid) lfirsti(rel->relids);
+ Func *function;
+ List *funcargs;
+ int *indexKeys = index->indexkeys;
+ List *arg;
+ int i;
- function = (Func*)funcOpnd->oper;
- funcargs = funcOpnd->args;
+ /*
+ * sanity check, make sure we know what we're dealing with here.
+ */
+ if (funcOpnd == NULL ||
+ nodeTag(funcOpnd) != T_Expr || funcOpnd->opType != FUNC_EXPR ||
+ funcOpnd->oper == NULL || indexKeys == NULL)
+ return false;
- if (function->funcid != index->indproc)
- return false;
+ function = (Func *) funcOpnd->oper;
+ funcargs = funcOpnd->args;
+
+ if (function->funcid != index->indproc)
+ return false;
+
+ /*
+ * Check that the arguments correspond to the same arguments used to
+ * create the functional index. To do this we must check that 1.
+ * refer to the right relatiion. 2. the args have the right attr.
+ * numbers in the right order.
+ *
+ *
+ * Check all args refer to the correct relation (i.e. the one with the
+ * functional index defined on it (rel). To do this we can simply
+ * compare range table entry numbers, they must be the same.
+ */
+ foreach(arg, funcargs)
+ {
+ if (heapRelid != ((Var *) lfirst(arg))->varno)
+ return false;
+ }
+
+ /*
+ * check attr numbers and order.
+ */
+ i = 0;
+ foreach(arg, funcargs)
+ {
+
+ if (indexKeys[i] == 0)
+ return (false);
- /*
- * Check that the arguments correspond to the same arguments used
- * to create the functional index. To do this we must check that
- * 1. refer to the right relatiion.
- * 2. the args have the right attr. numbers in the right order.
- *
- *
- * Check all args refer to the correct relation (i.e. the one with
- * the functional index defined on it (rel). To do this we can
- * simply compare range table entry numbers, they must be the same.
- */
- foreach (arg, funcargs) {
- if (heapRelid != ((Var*)lfirst(arg))->varno)
- return false;
- }
-
- /*
- * check attr numbers and order.
- */
- i = 0;
- foreach (arg, funcargs) {
-
- if (indexKeys[i]==0)
- return (false);
-
- if (((Var*)lfirst(arg))->varattno != indexKeys[i])
- return (false);
-
- i++;
- }
-
- return true;
+ if (((Var *) lfirst(arg))->varattno != indexKeys[i])
+ return (false);
+
+ i++;
+ }
+
+ return true;
}
-static bool
-SingleAttributeIndex(Rel *index)
+static bool
+SingleAttributeIndex(Rel * index)
{
- /*
- * return false for now as I don't know if we support index scans
- * on disjunction and the code doesn't work
- */
- return (false);
+
+ /*
+ * return false for now as I don't know if we support index scans on
+ * disjunction and the code doesn't work
+ */
+ return (false);
#if 0
- /*
- * Non-functional indices.
- */
- if (index->indproc == InvalidOid)
- return (index->indexkeys[0] != 0 &&
- index->indexkeys[1] == 0);
-
- /*
- * We have a functional index which is a single attr index
- */
- return true;
+
+ /*
+ * Non-functional indices.
+ */
+ if (index->indproc == InvalidOid)
+ return (index->indexkeys[0] != 0 &&
+ index->indexkeys[1] == 0);
+
+ /*
+ * We have a functional index which is a single attr index
+ */
+ return true;
#endif
}
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 87365278ffa..c20558cf42b 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* joinpath.c--
- * Routines to find all possible paths for processing a set of joins
+ * Routines to find all possible paths for processing a set of joins
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.2 1996/10/31 10:59:00 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.3 1997/09/07 04:43:38 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,269 +26,286 @@
#include "optimizer/paths.h"
#include "optimizer/pathnode.h"
#include "optimizer/keys.h"
-#include "optimizer/cost.h" /* for _enable_{hashjoin, _enable_mergesort} */
-
-static Path *best_innerjoin(List *join_paths, List *outer_relid);
-static List *sort_inner_and_outer(Rel *joinrel, Rel *outerrel, Rel *innerrel,
- List *mergeinfo_list);
-static List *match_unsorted_outer(Rel *joinrel, Rel *outerrel, Rel *innerrel,
- List *outerpath_list, Path *cheapest_inner, Path *best_innerjoin,
- List *mergeinfo_list);
-static List *match_unsorted_inner(Rel *joinrel, Rel *outerrel, Rel *innerrel,
- List *innerpath_list, List *mergeinfo_list);
-static bool EnoughMemoryForHashjoin(Rel *hashrel);
-static List *hash_inner_and_outer(Rel *joinrel, Rel *outerrel, Rel *innerrel,
- List *hashinfo_list);
-
-/*
+#include "optimizer/cost.h" /* for _enable_{hashjoin,
+ * _enable_mergesort} */
+
+static Path *best_innerjoin(List * join_paths, List * outer_relid);
+static List *
+sort_inner_and_outer(Rel * joinrel, Rel * outerrel, Rel * innerrel,
+ List * mergeinfo_list);
+static List *
+match_unsorted_outer(Rel * joinrel, Rel * outerrel, Rel * innerrel,
+ List * outerpath_list, Path * cheapest_inner, Path * best_innerjoin,
+ List * mergeinfo_list);
+static List *
+match_unsorted_inner(Rel * joinrel, Rel * outerrel, Rel * innerrel,
+ List * innerpath_list, List * mergeinfo_list);
+static bool EnoughMemoryForHashjoin(Rel * hashrel);
+static List *
+hash_inner_and_outer(Rel * joinrel, Rel * outerrel, Rel * innerrel,
+ List * hashinfo_list);
+
+/*
* find-all-join-paths--
- * Creates all possible ways to process joins for each of the join
- * relations in the list 'joinrels.' Each unique path will be included
- * in the join relation's 'pathlist' field.
- *
- * In postgres, n-way joins are handled left-only(permuting clauseless
- * joins doesn't usually win much).
- *
- * if BushyPlanFlag is true, bushy tree plans will be generated
+ * Creates all possible ways to process joins for each of the join
+ * relations in the list 'joinrels.' Each unique path will be included
+ * in the join relation's 'pathlist' field.
+ *
+ * In postgres, n-way joins are handled left-only(permuting clauseless
+ * joins doesn't usually win much).
+ *
+ * if BushyPlanFlag is true, bushy tree plans will be generated
*
* 'joinrels' is the list of relation entries to be joined
- *
+ *
* Modifies the pathlist field of the appropriate rel node to contain
* the unique join paths.
* If bushy trees are considered, may modify the relid field of the
* join rel nodes to flatten the lists.
- *
- * Returns nothing of interest. (?)
+ *
+ * Returns nothing of interest. (?)
* It does a destructive modification.
*/
void
-find_all_join_paths(Query *root, List *joinrels)
+find_all_join_paths(Query * root, List * joinrels)
{
- List *mergeinfo_list = NIL;
- List *hashinfo_list = NIL;
- List *temp_list = NIL;
- List *path = NIL;
-
- while (joinrels != NIL) {
- Rel *joinrel = (Rel *)lfirst(joinrels);
- List *innerrelids;
- List *outerrelids;
- Rel *innerrel;
- Rel *outerrel;
- Path *bestinnerjoin;
- List *pathlist = NIL;
-
- innerrelids = lsecond(joinrel->relids);
- outerrelids = lfirst(joinrel->relids);
-
- /*
- * base relation id is an integer and join relation relid is a
- * list of integers.
- */
- innerrel = (length(innerrelids)==1)?
- get_base_rel(root, lfirsti(innerrelids)) : get_join_rel(root,innerrelids);
- outerrel = (length(outerrelids)==1)?
- get_base_rel(root, lfirsti(outerrelids)) : get_join_rel(root, outerrelids);
-
- bestinnerjoin = best_innerjoin(innerrel->innerjoin,
- outerrel->relids);
- if( _enable_mergesort_ ) {
- mergeinfo_list =
- group_clauses_by_order(joinrel->clauseinfo,
- lfirsti(innerrel->relids));
- }
-
- if( _enable_hashjoin_ ) {
- hashinfo_list =
- group_clauses_by_hashop(joinrel->clauseinfo,
- lfirsti(innerrel->relids));
- }
-
- /* need to flatten the relids list */
- joinrel->relids = intAppend(outerrelids, innerrelids);
-
- /*
- * 1. Consider mergesort paths where both relations must be
- * explicitly sorted.
- */
- pathlist = sort_inner_and_outer(joinrel,outerrel,
- innerrel,mergeinfo_list);
-
- /*
- * 2. Consider paths where the outer relation need not be explicitly
- * sorted. This may include either nestloops and mergesorts where
- * the outer path is already ordered.
- */
- pathlist =
- add_pathlist(joinrel, pathlist,
- match_unsorted_outer(joinrel,
- outerrel,
- innerrel,
- outerrel->pathlist,
- (Path*)innerrel->cheapestpath,
- bestinnerjoin,
- mergeinfo_list));
-
- /*
- * 3. Consider paths where the inner relation need not be explicitly
- * sorted. This may include nestloops and mergesorts the actual
- * nestloop nodes were constructed in (match-unsorted-outer).
- */
- pathlist =
- add_pathlist(joinrel,pathlist,
- match_unsorted_inner(joinrel,outerrel,
- innerrel,
- innerrel->pathlist,
- mergeinfo_list));
-
- /*
- * 4. Consider paths where both outer and inner relations must be
- * hashed before being joined.
- */
-
- pathlist =
- add_pathlist(joinrel, pathlist,
- hash_inner_and_outer(joinrel,outerrel,
- innerrel,hashinfo_list));
-
- joinrel->pathlist = pathlist;
-
- /*
- * 'OuterJoinCost is only valid when calling (match-unsorted-inner)
- * with the same arguments as the previous invokation of
- * (match-unsorted-outer), so clear the field before going on.
- */
- temp_list = innerrel->pathlist;
- foreach(path, temp_list) {
-
- /*
- * XXX
- *
- * This gross hack is to get around an apparent optimizer bug on
- * Sparc (or maybe it is a bug of ours?) that causes really wierd
- * behavior.
- */
- if (IsA_JoinPath(path)) {
- ((Path*)lfirst(path))->outerjoincost = (Cost) 0;
- }
-
- /* do it iff it is a join path, which is not always
- true, esp since the base level */
+ List *mergeinfo_list = NIL;
+ List *hashinfo_list = NIL;
+ List *temp_list = NIL;
+ List *path = NIL;
+
+ while (joinrels != NIL)
+ {
+ Rel *joinrel = (Rel *) lfirst(joinrels);
+ List *innerrelids;
+ List *outerrelids;
+ Rel *innerrel;
+ Rel *outerrel;
+ Path *bestinnerjoin;
+ List *pathlist = NIL;
+
+ innerrelids = lsecond(joinrel->relids);
+ outerrelids = lfirst(joinrel->relids);
+
+ /*
+ * base relation id is an integer and join relation relid is a
+ * list of integers.
+ */
+ innerrel = (length(innerrelids) == 1) ?
+ get_base_rel(root, lfirsti(innerrelids)) : get_join_rel(root, innerrelids);
+ outerrel = (length(outerrelids) == 1) ?
+ get_base_rel(root, lfirsti(outerrelids)) : get_join_rel(root, outerrelids);
+
+ bestinnerjoin = best_innerjoin(innerrel->innerjoin,
+ outerrel->relids);
+ if (_enable_mergesort_)
+ {
+ mergeinfo_list =
+ group_clauses_by_order(joinrel->clauseinfo,
+ lfirsti(innerrel->relids));
+ }
+
+ if (_enable_hashjoin_)
+ {
+ hashinfo_list =
+ group_clauses_by_hashop(joinrel->clauseinfo,
+ lfirsti(innerrel->relids));
+ }
+
+ /* need to flatten the relids list */
+ joinrel->relids = intAppend(outerrelids, innerrelids);
+
+ /*
+ * 1. Consider mergesort paths where both relations must be
+ * explicitly sorted.
+ */
+ pathlist = sort_inner_and_outer(joinrel, outerrel,
+ innerrel, mergeinfo_list);
+
+ /*
+ * 2. Consider paths where the outer relation need not be
+ * explicitly sorted. This may include either nestloops and
+ * mergesorts where the outer path is already ordered.
+ */
+ pathlist =
+ add_pathlist(joinrel, pathlist,
+ match_unsorted_outer(joinrel,
+ outerrel,
+ innerrel,
+ outerrel->pathlist,
+ (Path *) innerrel->cheapestpath,
+ bestinnerjoin,
+ mergeinfo_list));
+
+ /*
+ * 3. Consider paths where the inner relation need not be
+ * explicitly sorted. This may include nestloops and mergesorts
+ * the actual nestloop nodes were constructed in
+ * (match-unsorted-outer).
+ */
+ pathlist =
+ add_pathlist(joinrel, pathlist,
+ match_unsorted_inner(joinrel, outerrel,
+ innerrel,
+ innerrel->pathlist,
+ mergeinfo_list));
+
+ /*
+ * 4. Consider paths where both outer and inner relations must be
+ * hashed before being joined.
+ */
+
+ pathlist =
+ add_pathlist(joinrel, pathlist,
+ hash_inner_and_outer(joinrel, outerrel,
+ innerrel, hashinfo_list));
+
+ joinrel->pathlist = pathlist;
+
+ /*
+ * 'OuterJoinCost is only valid when calling
+ * (match-unsorted-inner) with the same arguments as the previous
+ * invokation of (match-unsorted-outer), so clear the field before
+ * going on.
+ */
+ temp_list = innerrel->pathlist;
+ foreach(path, temp_list)
+ {
+
+ /*
+ * XXX
+ *
+ * This gross hack is to get around an apparent optimizer bug on
+ * Sparc (or maybe it is a bug of ours?) that causes really
+ * wierd behavior.
+ */
+ if (IsA_JoinPath(path))
+ {
+ ((Path *) lfirst(path))->outerjoincost = (Cost) 0;
+ }
+
+ /*
+ * do it iff it is a join path, which is not always true, esp
+ * since the base level
+ */
+ }
+
+ joinrels = lnext(joinrels);
}
-
- joinrels = lnext(joinrels);
- }
}
-/*
+/*
* best-innerjoin--
- * Find the cheapest index path that has already been identified by
- * (indexable_joinclauses) as being a possible inner path for the given
- * outer relation in a nestloop join.
- *
+ * Find the cheapest index path that has already been identified by
+ * (indexable_joinclauses) as being a possible inner path for the given
+ * outer relation in a nestloop join.
+ *
* 'join-paths' is a list of join nodes
* 'outer-relid' is the relid of the outer join relation
- *
+ *
* Returns the pathnode of the selected path.
*/
-static Path *
-best_innerjoin(List *join_paths, List *outer_relids)
+static Path *
+best_innerjoin(List * join_paths, List * outer_relids)
{
- Path *cheapest = (Path*)NULL;
- List *join_path;
-
- foreach(join_path, join_paths) {
- Path *path = (Path *)lfirst(join_path);
+ Path *cheapest = (Path *) NULL;
+ List *join_path;
+
+ foreach(join_path, join_paths)
+ {
+ Path *path = (Path *) lfirst(join_path);
- if (intMember(lfirsti(path->joinid), outer_relids)
- && ((cheapest==NULL ||
- path_is_cheaper((Path*)lfirst(join_path),cheapest)))) {
+ if (intMember(lfirsti(path->joinid), outer_relids)
+ && ((cheapest == NULL ||
+ path_is_cheaper((Path *) lfirst(join_path), cheapest))))
+ {
- cheapest = (Path*)lfirst(join_path);
+ cheapest = (Path *) lfirst(join_path);
+ }
}
- }
- return(cheapest);
+ return (cheapest);
}
-/*
+/*
* sort-inner-and-outer--
- * Create mergesort join paths by explicitly sorting both the outer and
- * inner join relations on each available merge ordering.
- *
+ * Create mergesort join paths by explicitly sorting both the outer and
+ * inner join relations on each available merge ordering.
+ *
* 'joinrel' is the join relation
* 'outerrel' is the outer join relation
* 'innerrel' is the inner join relation
* 'mergeinfo-list' is a list of nodes containing info on(mergesortable)
- * clauses for joining the relations
- *
+ * clauses for joining the relations
+ *
* Returns a list of mergesort paths.
*/
-static List *
-sort_inner_and_outer(Rel *joinrel,
- Rel *outerrel,
- Rel *innerrel,
- List *mergeinfo_list)
+static List *
+sort_inner_and_outer(Rel * joinrel,
+ Rel * outerrel,
+ Rel * innerrel,
+ List * mergeinfo_list)
{
- List *ms_list = NIL;
- MInfo *xmergeinfo = (MInfo*)NULL;
- MergePath *temp_node = (MergePath*)NULL;
- List *i;
- List *outerkeys = NIL;
- List *innerkeys = NIL;
- List *merge_pathkeys = NIL;
-
- foreach(i, mergeinfo_list) {
- xmergeinfo = (MInfo *)lfirst(i);
-
- outerkeys =
- extract_path_keys(xmergeinfo->jmethod.jmkeys,
- outerrel->targetlist,
- OUTER);
-
- innerkeys =
- extract_path_keys(xmergeinfo->jmethod.jmkeys,
- innerrel->targetlist,
- INNER);
-
- merge_pathkeys =
- new_join_pathkeys(outerkeys, joinrel->targetlist,
- xmergeinfo->jmethod.clauses);
-
- temp_node =
- create_mergesort_path(joinrel,
- outerrel->size,
- innerrel->size,
- outerrel->width,
- innerrel->width,
- (Path*)outerrel->cheapestpath,
- (Path*)innerrel->cheapestpath,
- merge_pathkeys,
- xmergeinfo->m_ordering,
- xmergeinfo->jmethod.clauses,
- outerkeys,
- innerkeys);
-
- ms_list = lappend(ms_list, temp_node);
- }
- return(ms_list);
+ List *ms_list = NIL;
+ MInfo *xmergeinfo = (MInfo *) NULL;
+ MergePath *temp_node = (MergePath *) NULL;
+ List *i;
+ List *outerkeys = NIL;
+ List *innerkeys = NIL;
+ List *merge_pathkeys = NIL;
+
+ foreach(i, mergeinfo_list)
+ {
+ xmergeinfo = (MInfo *) lfirst(i);
+
+ outerkeys =
+ extract_path_keys(xmergeinfo->jmethod.jmkeys,
+ outerrel->targetlist,
+ OUTER);
+
+ innerkeys =
+ extract_path_keys(xmergeinfo->jmethod.jmkeys,
+ innerrel->targetlist,
+ INNER);
+
+ merge_pathkeys =
+ new_join_pathkeys(outerkeys, joinrel->targetlist,
+ xmergeinfo->jmethod.clauses);
+
+ temp_node =
+ create_mergesort_path(joinrel,
+ outerrel->size,
+ innerrel->size,
+ outerrel->width,
+ innerrel->width,
+ (Path *) outerrel->cheapestpath,
+ (Path *) innerrel->cheapestpath,
+ merge_pathkeys,
+ xmergeinfo->m_ordering,
+ xmergeinfo->jmethod.clauses,
+ outerkeys,
+ innerkeys);
+
+ ms_list = lappend(ms_list, temp_node);
+ }
+ return (ms_list);
}
-/*
+/*
* match-unsorted-outer--
- * Creates possible join paths for processing a single join relation
- * 'joinrel' by employing either iterative substitution or
- * mergesorting on each of its possible outer paths(assuming that the
- * outer relation need not be explicitly sorted).
- *
- * 1. The inner path is the cheapest available inner path.
- * 2. Mergesort wherever possible. Mergesorts are considered if there
- * are mergesortable join clauses between the outer and inner join
- * relations such that the outer path is keyed on the variables
- * appearing in the clauses. The corresponding inner merge path is
- * either a path whose keys match those of the outer path(if such a
- * path is available) or an explicit sort on the appropriate inner
- * join keys, whichever is cheaper.
- *
+ * Creates possible join paths for processing a single join relation
+ * 'joinrel' by employing either iterative substitution or
+ * mergesorting on each of its possible outer paths(assuming that the
+ * outer relation need not be explicitly sorted).
+ *
+ * 1. The inner path is the cheapest available inner path.
+ * 2. Mergesort wherever possible. Mergesorts are considered if there
+ * are mergesortable join clauses between the outer and inner join
+ * relations such that the outer path is keyed on the variables
+ * appearing in the clauses. The corresponding inner merge path is
+ * either a path whose keys match those of the outer path(if such a
+ * path is available) or an explicit sort on the appropriate inner
+ * join keys, whichever is cheaper.
+ *
* 'joinrel' is the join relation
* 'outerrel' is the outer join relation
* 'innerrel' is the inner join relation
@@ -296,331 +313,355 @@ sort_inner_and_outer(Rel *joinrel,
* 'cheapest-inner' is the cheapest inner path
* 'best-innerjoin' is the best inner index path(if any)
* 'mergeinfo-list' is a list of nodes containing info on mergesortable
- * clauses
- *
+ * clauses
+ *
* Returns a list of possible join path nodes.
*/
-static List *
-match_unsorted_outer(Rel *joinrel,
- Rel *outerrel,
- Rel *innerrel,
- List *outerpath_list,
- Path *cheapest_inner,
- Path *best_innerjoin,
- List *mergeinfo_list)
+static List *
+match_unsorted_outer(Rel * joinrel,
+ Rel * outerrel,
+ Rel * innerrel,
+ List * outerpath_list,
+ Path * cheapest_inner,
+ Path * best_innerjoin,
+ List * mergeinfo_list)
{
- Path *outerpath = (Path*)NULL;
- List *jp_list = NIL;
- List *temp_node = NIL;
- List *merge_pathkeys = NIL;
- Path *nestinnerpath =(Path*)NULL;
- List *paths = NIL;
- List *i = NIL;
- PathOrder *outerpath_ordering = NULL;
-
- foreach(i,outerpath_list) {
- List *clauses = NIL;
- List *matchedJoinKeys = NIL;
- List *matchedJoinClauses = NIL;
- MInfo *xmergeinfo = (MInfo*)NULL;
-
- outerpath = (Path*)lfirst(i);
-
- outerpath_ordering = &outerpath->p_ordering;
-
- if (outerpath_ordering) {
- xmergeinfo =
- match_order_mergeinfo(outerpath_ordering,
- mergeinfo_list);
- }
-
- if (xmergeinfo) {
- clauses = xmergeinfo->jmethod.clauses;
- }
-
- if (clauses) {
- List *keys = xmergeinfo->jmethod.jmkeys;
- List *clauses = xmergeinfo->jmethod.clauses;
-
- matchedJoinKeys =
- match_pathkeys_joinkeys(outerpath->keys,
- keys,
- clauses,
- OUTER,
- &matchedJoinClauses);
- merge_pathkeys =
- new_join_pathkeys(outerpath->keys,
- joinrel->targetlist, clauses);
- } else {
- merge_pathkeys = outerpath->keys;
- }
-
- if(best_innerjoin &&
- path_is_cheaper(best_innerjoin, cheapest_inner)) {
- nestinnerpath = best_innerjoin;
- } else {
- nestinnerpath = cheapest_inner;
- }
-
- paths = lcons(create_nestloop_path(joinrel,
- outerrel,
- outerpath,
- nestinnerpath,
- merge_pathkeys),
- NIL);
-
- if (clauses && matchedJoinKeys) {
- bool path_is_cheaper_than_sort;
- List *varkeys = NIL;
- Path *mergeinnerpath =
- match_paths_joinkeys(matchedJoinKeys,
- outerpath_ordering,
- innerrel->pathlist,
- INNER);
-
- path_is_cheaper_than_sort =
- (bool) (mergeinnerpath &&
- (mergeinnerpath->path_cost <
- (cheapest_inner->path_cost +
- cost_sort(matchedJoinKeys,
- innerrel->size,
- innerrel->width,
- false))));
- if(!path_is_cheaper_than_sort) {
- varkeys =
- extract_path_keys(matchedJoinKeys,
- innerrel->targetlist,
- INNER);
- }
-
-
- /*
- * Keep track of the cost of the outer path used with
- * this ordered inner path for later processing in
- * (match-unsorted-inner), since it isn't a sort and
- * thus wouldn't otherwise be considered.
- */
- if (path_is_cheaper_than_sort) {
- mergeinnerpath->outerjoincost = outerpath->path_cost;
- } else {
- mergeinnerpath = cheapest_inner;
- }
-
- temp_node =
- lcons(create_mergesort_path(joinrel,
- outerrel->size,
- innerrel->size,
- outerrel->width,
- innerrel->width,
- outerpath,
- mergeinnerpath,
- merge_pathkeys,
- xmergeinfo->m_ordering,
- matchedJoinClauses,
- NIL,
- varkeys),
- paths);
- } else {
- temp_node = paths;
- }
- jp_list = nconc(jp_list, temp_node);
- }
- return(jp_list);
+ Path *outerpath = (Path *) NULL;
+ List *jp_list = NIL;
+ List *temp_node = NIL;
+ List *merge_pathkeys = NIL;
+ Path *nestinnerpath = (Path *) NULL;
+ List *paths = NIL;
+ List *i = NIL;
+ PathOrder *outerpath_ordering = NULL;
+
+ foreach(i, outerpath_list)
+ {
+ List *clauses = NIL;
+ List *matchedJoinKeys = NIL;
+ List *matchedJoinClauses = NIL;
+ MInfo *xmergeinfo = (MInfo *) NULL;
+
+ outerpath = (Path *) lfirst(i);
+
+ outerpath_ordering = &outerpath->p_ordering;
+
+ if (outerpath_ordering)
+ {
+ xmergeinfo =
+ match_order_mergeinfo(outerpath_ordering,
+ mergeinfo_list);
+ }
+
+ if (xmergeinfo)
+ {
+ clauses = xmergeinfo->jmethod.clauses;
+ }
+
+ if (clauses)
+ {
+ List *keys = xmergeinfo->jmethod.jmkeys;
+ List *clauses = xmergeinfo->jmethod.clauses;
+
+ matchedJoinKeys =
+ match_pathkeys_joinkeys(outerpath->keys,
+ keys,
+ clauses,
+ OUTER,
+ &matchedJoinClauses);
+ merge_pathkeys =
+ new_join_pathkeys(outerpath->keys,
+ joinrel->targetlist, clauses);
+ }
+ else
+ {
+ merge_pathkeys = outerpath->keys;
+ }
+
+ if (best_innerjoin &&
+ path_is_cheaper(best_innerjoin, cheapest_inner))
+ {
+ nestinnerpath = best_innerjoin;
+ }
+ else
+ {
+ nestinnerpath = cheapest_inner;
+ }
+
+ paths = lcons(create_nestloop_path(joinrel,
+ outerrel,
+ outerpath,
+ nestinnerpath,
+ merge_pathkeys),
+ NIL);
+
+ if (clauses && matchedJoinKeys)
+ {
+ bool path_is_cheaper_than_sort;
+ List *varkeys = NIL;
+ Path *mergeinnerpath =
+ match_paths_joinkeys(matchedJoinKeys,
+ outerpath_ordering,
+ innerrel->pathlist,
+ INNER);
+
+ path_is_cheaper_than_sort =
+ (bool) (mergeinnerpath &&
+ (mergeinnerpath->path_cost <
+ (cheapest_inner->path_cost +
+ cost_sort(matchedJoinKeys,
+ innerrel->size,
+ innerrel->width,
+ false))));
+ if (!path_is_cheaper_than_sort)
+ {
+ varkeys =
+ extract_path_keys(matchedJoinKeys,
+ innerrel->targetlist,
+ INNER);
+ }
+
+
+ /*
+ * Keep track of the cost of the outer path used with this
+ * ordered inner path for later processing in
+ * (match-unsorted-inner), since it isn't a sort and thus
+ * wouldn't otherwise be considered.
+ */
+ if (path_is_cheaper_than_sort)
+ {
+ mergeinnerpath->outerjoincost = outerpath->path_cost;
+ }
+ else
+ {
+ mergeinnerpath = cheapest_inner;
+ }
+
+ temp_node =
+ lcons(create_mergesort_path(joinrel,
+ outerrel->size,
+ innerrel->size,
+ outerrel->width,
+ innerrel->width,
+ outerpath,
+ mergeinnerpath,
+ merge_pathkeys,
+ xmergeinfo->m_ordering,
+ matchedJoinClauses,
+ NIL,
+ varkeys),
+ paths);
+ }
+ else
+ {
+ temp_node = paths;
+ }
+ jp_list = nconc(jp_list, temp_node);
+ }
+ return (jp_list);
}
-/*
+/*
* match-unsorted-inner --
- * Find the cheapest ordered join path for a given(ordered, unsorted)
- * inner join path.
- *
- * Scans through each path available on an inner join relation and tries
- * matching its ordering keys against those of mergejoin clauses.
- * If 1. an appropriately-ordered inner path and matching mergeclause are
- * found, and
- * 2. sorting the cheapest outer path is cheaper than using an ordered
- * but unsorted outer path(as was considered in
- * (match-unsorted-outer)),
- * then this merge path is considered.
- *
+ * Find the cheapest ordered join path for a given(ordered, unsorted)
+ * inner join path.
+ *
+ * Scans through each path available on an inner join relation and tries
+ * matching its ordering keys against those of mergejoin clauses.
+ * If 1. an appropriately-ordered inner path and matching mergeclause are
+ * found, and
+ * 2. sorting the cheapest outer path is cheaper than using an ordered
+ * but unsorted outer path(as was considered in
+ * (match-unsorted-outer)),
+ * then this merge path is considered.
+ *
* 'joinrel' is the join result relation
* 'outerrel' is the outer join relation
* 'innerrel' is the inner join relation
* 'innerpath-list' is the list of possible inner join paths
* 'mergeinfo-list' is a list of nodes containing info on mergesortable
- * clauses
- *
+ * clauses
+ *
* Returns a list of possible merge paths.
*/
-static List *
-match_unsorted_inner(Rel *joinrel,
- Rel *outerrel,
- Rel *innerrel,
- List *innerpath_list,
- List *mergeinfo_list)
+static List *
+match_unsorted_inner(Rel * joinrel,
+ Rel * outerrel,
+ Rel * innerrel,
+ List * innerpath_list,
+ List * mergeinfo_list)
{
- Path *innerpath = (Path*)NULL;
- List *mp_list = NIL;
- List *temp_node = NIL;
- PathOrder *innerpath_ordering = NULL;
- Cost temp1 = 0.0;
- bool temp2 = false;
- List *i = NIL;
-
- foreach (i, innerpath_list) {
- MInfo *xmergeinfo = (MInfo*)NULL;
- List *clauses = NIL;
- List *matchedJoinKeys = NIL;
- List *matchedJoinClauses = NIL;
-
- innerpath = (Path*)lfirst(i);
-
- innerpath_ordering = &innerpath->p_ordering;
-
- if (innerpath_ordering) {
- xmergeinfo =
- match_order_mergeinfo(innerpath_ordering,
- mergeinfo_list);
- }
-
- if (xmergeinfo) {
- clauses = ((JoinMethod*)xmergeinfo)->clauses;
- }
-
- if (clauses) {
- List *keys = xmergeinfo->jmethod.jmkeys;
- List *cls = xmergeinfo->jmethod.clauses;
-
- matchedJoinKeys =
- match_pathkeys_joinkeys(innerpath->keys,
- keys,
- cls,
- INNER,
- &matchedJoinClauses);
- }
-
- /*
- * (match-unsorted-outer) if it is applicable.
- * 'OuterJoinCost was set above in
- */
- if (clauses && matchedJoinKeys) {
- temp1 = outerrel->cheapestpath->path_cost +
- cost_sort(matchedJoinKeys, outerrel->size, outerrel->width,
- false);
-
- temp2 = (bool) (FLOAT_IS_ZERO(innerpath->outerjoincost)
- || (innerpath->outerjoincost > temp1));
-
- if(temp2) {
- List *outerkeys =
- extract_path_keys(matchedJoinKeys,
- outerrel->targetlist,
- OUTER);
- List *merge_pathkeys =
- new_join_pathkeys(outerkeys,
- joinrel->targetlist,
- clauses);
-
- temp_node =
- lcons(create_mergesort_path(joinrel,
- outerrel->size,
- innerrel->size,
- outerrel->width,
- innerrel->width,
- (Path*)outerrel->cheapestpath,
- innerpath,
- merge_pathkeys,
- xmergeinfo->m_ordering,
- matchedJoinClauses,
- outerkeys,
- NIL),
- NIL);
-
- mp_list = nconc(mp_list,temp_node);
- }
+ Path *innerpath = (Path *) NULL;
+ List *mp_list = NIL;
+ List *temp_node = NIL;
+ PathOrder *innerpath_ordering = NULL;
+ Cost temp1 = 0.0;
+ bool temp2 = false;
+ List *i = NIL;
+
+ foreach(i, innerpath_list)
+ {
+ MInfo *xmergeinfo = (MInfo *) NULL;
+ List *clauses = NIL;
+ List *matchedJoinKeys = NIL;
+ List *matchedJoinClauses = NIL;
+
+ innerpath = (Path *) lfirst(i);
+
+ innerpath_ordering = &innerpath->p_ordering;
+
+ if (innerpath_ordering)
+ {
+ xmergeinfo =
+ match_order_mergeinfo(innerpath_ordering,
+ mergeinfo_list);
+ }
+
+ if (xmergeinfo)
+ {
+ clauses = ((JoinMethod *) xmergeinfo)->clauses;
+ }
+
+ if (clauses)
+ {
+ List *keys = xmergeinfo->jmethod.jmkeys;
+ List *cls = xmergeinfo->jmethod.clauses;
+
+ matchedJoinKeys =
+ match_pathkeys_joinkeys(innerpath->keys,
+ keys,
+ cls,
+ INNER,
+ &matchedJoinClauses);
+ }
+
+ /*
+ * (match-unsorted-outer) if it is applicable. 'OuterJoinCost was
+ * set above in
+ */
+ if (clauses && matchedJoinKeys)
+ {
+ temp1 = outerrel->cheapestpath->path_cost +
+ cost_sort(matchedJoinKeys, outerrel->size, outerrel->width,
+ false);
+
+ temp2 = (bool) (FLOAT_IS_ZERO(innerpath->outerjoincost)
+ || (innerpath->outerjoincost > temp1));
+
+ if (temp2)
+ {
+ List *outerkeys =
+ extract_path_keys(matchedJoinKeys,
+ outerrel->targetlist,
+ OUTER);
+ List *merge_pathkeys =
+ new_join_pathkeys(outerkeys,
+ joinrel->targetlist,
+ clauses);
+
+ temp_node =
+ lcons(create_mergesort_path(joinrel,
+ outerrel->size,
+ innerrel->size,
+ outerrel->width,
+ innerrel->width,
+ (Path *) outerrel->cheapestpath,
+ innerpath,
+ merge_pathkeys,
+ xmergeinfo->m_ordering,
+ matchedJoinClauses,
+ outerkeys,
+ NIL),
+ NIL);
+
+ mp_list = nconc(mp_list, temp_node);
+ }
+ }
}
- }
- return(mp_list);
-
+ return (mp_list);
+
}
-static bool
-EnoughMemoryForHashjoin(Rel *hashrel)
+static bool
+EnoughMemoryForHashjoin(Rel * hashrel)
{
- int ntuples;
- int tupsize;
- int pages;
-
- ntuples = hashrel->size;
- if (ntuples == 0) ntuples = 1000;
- tupsize = hashrel->width + sizeof(HeapTupleData);
- pages = page_size(ntuples, tupsize);
- /*
- * if amount of buffer space below hashjoin threshold,
- * return false
- */
- if (ceil(sqrt((double)pages)) > NBuffers)
- return false;
- return true;
+ int ntuples;
+ int tupsize;
+ int pages;
+
+ ntuples = hashrel->size;
+ if (ntuples == 0)
+ ntuples = 1000;
+ tupsize = hashrel->width + sizeof(HeapTupleData);
+ pages = page_size(ntuples, tupsize);
+
+ /*
+ * if amount of buffer space below hashjoin threshold, return false
+ */
+ if (ceil(sqrt((double) pages)) > NBuffers)
+ return false;
+ return true;
}
-/*
- * hash-inner-and-outer-- XXX HASH
- * Create hashjoin join paths by explicitly hashing both the outer and
- * inner join relations on each available hash op.
- *
+/*
+ * hash-inner-and-outer-- XXX HASH
+ * Create hashjoin join paths by explicitly hashing both the outer and
+ * inner join relations on each available hash op.
+ *
* 'joinrel' is the join relation
* 'outerrel' is the outer join relation
* 'innerrel' is the inner join relation
* 'hashinfo-list' is a list of nodes containing info on(hashjoinable)
- * clauses for joining the relations
- *
+ * clauses for joining the relations
+ *
* Returns a list of hashjoin paths.
*/
-static List *
-hash_inner_and_outer(Rel *joinrel,
- Rel *outerrel,
- Rel *innerrel,
- List *hashinfo_list)
+static List *
+hash_inner_and_outer(Rel * joinrel,
+ Rel * outerrel,
+ Rel * innerrel,
+ List * hashinfo_list)
{
- HInfo *xhashinfo = (HInfo*)NULL;
- List *hjoin_list = NIL;
- HashPath *temp_node = (HashPath*)NULL;
- List *i = NIL;
- List *outerkeys = NIL;
- List *innerkeys = NIL;
- List *hash_pathkeys = NIL;
-
- foreach (i, hashinfo_list) {
- xhashinfo = (HInfo*)lfirst(i);
- outerkeys =
- extract_path_keys(((JoinMethod*)xhashinfo)->jmkeys,
- outerrel->targetlist,
- OUTER);
- innerkeys =
- extract_path_keys(((JoinMethod*)xhashinfo)->jmkeys,
- innerrel->targetlist,
- INNER);
- hash_pathkeys =
- new_join_pathkeys(outerkeys,
- joinrel->targetlist,
- ((JoinMethod*)xhashinfo)->clauses);
-
- if (EnoughMemoryForHashjoin(innerrel)) {
- temp_node = create_hashjoin_path(joinrel,
- outerrel->size,
- innerrel->size,
- outerrel->width,
- innerrel->width,
- (Path*)outerrel->cheapestpath,
- (Path*)innerrel->cheapestpath,
- hash_pathkeys,
- xhashinfo->hashop,
- ((JoinMethod*)xhashinfo)->clauses,
- outerkeys,
- innerkeys);
- hjoin_list = lappend(hjoin_list, temp_node);
+ HInfo *xhashinfo = (HInfo *) NULL;
+ List *hjoin_list = NIL;
+ HashPath *temp_node = (HashPath *) NULL;
+ List *i = NIL;
+ List *outerkeys = NIL;
+ List *innerkeys = NIL;
+ List *hash_pathkeys = NIL;
+
+ foreach(i, hashinfo_list)
+ {
+ xhashinfo = (HInfo *) lfirst(i);
+ outerkeys =
+ extract_path_keys(((JoinMethod *) xhashinfo)->jmkeys,
+ outerrel->targetlist,
+ OUTER);
+ innerkeys =
+ extract_path_keys(((JoinMethod *) xhashinfo)->jmkeys,
+ innerrel->targetlist,
+ INNER);
+ hash_pathkeys =
+ new_join_pathkeys(outerkeys,
+ joinrel->targetlist,
+ ((JoinMethod *) xhashinfo)->clauses);
+
+ if (EnoughMemoryForHashjoin(innerrel))
+ {
+ temp_node = create_hashjoin_path(joinrel,
+ outerrel->size,
+ innerrel->size,
+ outerrel->width,
+ innerrel->width,
+ (Path *) outerrel->cheapestpath,
+ (Path *) innerrel->cheapestpath,
+ hash_pathkeys,
+ xhashinfo->hashop,
+ ((JoinMethod *) xhashinfo)->clauses,
+ outerkeys,
+ innerkeys);
+ hjoin_list = lappend(hjoin_list, temp_node);
+ }
}
- }
- return(hjoin_list);
+ return (hjoin_list);
}
-
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 00f8a04a050..98762f9800c 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* joinrels.c--
- * Routines to determine which relations should be joined
+ * Routines to determine which relations should be joined
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.4 1997/06/05 09:33:52 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.5 1997/09/07 04:43:40 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,467 +24,508 @@
#include "optimizer/pathnode.h"
#ifdef USE_RIGHT_SIDED_PLANS
-bool _use_right_sided_plans_ = true;
+bool _use_right_sided_plans_ = true;
+
#else
-bool _use_right_sided_plans_ = false;
+bool _use_right_sided_plans_ = false;
+
#endif
-static List *find_clause_joins(Query *root, Rel *outer_rel, List *joininfo_list);
-static List *find_clauseless_joins(Rel *outer_rel, List *inner_rels);
-static Rel *init_join_rel(Rel *outer_rel, Rel *inner_rel, JInfo *joininfo);
-static List *new_join_tlist(List *tlist, List *other_relids,
- int first_resdomno);
-static List *new_joininfo_list(List *joininfo_list, List *join_relids);
-static void add_superrels(Rel *rel, Rel *super_rel);
-static bool nonoverlap_rels(Rel *rel1, Rel *rel2);
-static bool nonoverlap_sets(List *s1, List *s2);
-static void set_joinrel_size(Rel *joinrel, Rel *outer_rel, Rel *inner_rel,
- JInfo *jinfo);
-
-/*
+static List *find_clause_joins(Query * root, Rel * outer_rel, List * joininfo_list);
+static List *find_clauseless_joins(Rel * outer_rel, List * inner_rels);
+static Rel *init_join_rel(Rel * outer_rel, Rel * inner_rel, JInfo * joininfo);
+static List *
+new_join_tlist(List * tlist, List * other_relids,
+ int first_resdomno);
+static List *new_joininfo_list(List * joininfo_list, List * join_relids);
+static void add_superrels(Rel * rel, Rel * super_rel);
+static bool nonoverlap_rels(Rel * rel1, Rel * rel2);
+static bool nonoverlap_sets(List * s1, List * s2);
+static void
+set_joinrel_size(Rel * joinrel, Rel * outer_rel, Rel * inner_rel,
+ JInfo * jinfo);
+
+/*
* find-join-rels--
- * Find all possible joins for each of the outer join relations in
- * 'outer-rels'. A rel node is created for each possible join relation,
- * and the resulting list of nodes is returned. If at all possible, only
- * those relations for which join clauses exist are considered. If none
- * of these exist for a given relation, all remaining possibilities are
- * considered.
- *
+ * Find all possible joins for each of the outer join relations in
+ * 'outer-rels'. A rel node is created for each possible join relation,
+ * and the resulting list of nodes is returned. If at all possible, only
+ * those relations for which join clauses exist are considered. If none
+ * of these exist for a given relation, all remaining possibilities are
+ * considered.
+ *
* 'outer-rels' is the list of rel nodes
- *
+ *
* Returns a list of rel nodes corresponding to the new join relations.
*/
-List *
-find_join_rels(Query *root, List *outer_rels)
+List *
+find_join_rels(Query * root, List * outer_rels)
{
- List *joins = NIL;
- List *join_list = NIL;
- List *r = NIL;
-
- foreach(r, outer_rels) {
- Rel *outer_rel = (Rel *)lfirst(r);
-
- if(!(joins = find_clause_joins(root, outer_rel,outer_rel->joininfo)))
- if (BushyPlanFlag)
- joins = find_clauseless_joins(outer_rel,outer_rels);
- else
- joins = find_clauseless_joins(outer_rel,root->base_relation_list_);
-
- join_list = nconc(join_list, joins);
- }
-
- return(join_list);
+ List *joins = NIL;
+ List *join_list = NIL;
+ List *r = NIL;
+
+ foreach(r, outer_rels)
+ {
+ Rel *outer_rel = (Rel *) lfirst(r);
+
+ if (!(joins = find_clause_joins(root, outer_rel, outer_rel->joininfo)))
+ if (BushyPlanFlag)
+ joins = find_clauseless_joins(outer_rel, outer_rels);
+ else
+ joins = find_clauseless_joins(outer_rel, root->base_relation_list_);
+
+ join_list = nconc(join_list, joins);
+ }
+
+ return (join_list);
}
-/*
+/*
* find-clause-joins--
- * Determines whether joins can be performed between an outer relation
- * 'outer-rel' and those relations within 'outer-rel's joininfo nodes
- * (i.e., relations that participate in join clauses that 'outer-rel'
- * participates in). This is possible if all but one of the relations
- * contained within the join clauses of the joininfo node are already
- * contained within 'outer-rel'.
+ * Determines whether joins can be performed between an outer relation
+ * 'outer-rel' and those relations within 'outer-rel's joininfo nodes
+ * (i.e., relations that participate in join clauses that 'outer-rel'
+ * participates in). This is possible if all but one of the relations
+ * contained within the join clauses of the joininfo node are already
+ * contained within 'outer-rel'.
*
* 'outer-rel' is the relation entry for the outer relation
- * 'joininfo-list' is a list of join clauses which 'outer-rel'
- * participates in
- *
+ * 'joininfo-list' is a list of join clauses which 'outer-rel'
+ * participates in
+ *
* Returns a list of new join relations.
*/
-static List *
-find_clause_joins(Query *root, Rel *outer_rel, List *joininfo_list)
+static List *
+find_clause_joins(Query * root, Rel * outer_rel, List * joininfo_list)
{
- List *join_list = NIL;
- List *i = NIL;
-
- foreach (i, joininfo_list) {
- JInfo *joininfo = (JInfo*)lfirst(i);
- Rel *rel;
-
- if(!joininfo->inactive) {
- List *other_rels = joininfo->otherrels;
-
- if(other_rels != NIL) {
- if(length(other_rels) == 1) {
- rel = init_join_rel(outer_rel,
- get_base_rel(root, lfirsti(other_rels)),
- joininfo);
- /* how about right-sided plan ? */
- if ( _use_right_sided_plans_ &&
- length (outer_rel->relids) > 1 )
- {
- if (rel != NULL)
- join_list = lappend(join_list, rel);
- rel = init_join_rel(get_base_rel(root, lfirsti(other_rels)),
- outer_rel,
- joininfo);
- }
- } else if (BushyPlanFlag) {
- rel = init_join_rel(outer_rel,
- get_join_rel(root, other_rels),
- joininfo);
- } else {
- rel = NULL;
- }
+ List *join_list = NIL;
+ List *i = NIL;
- if (rel != NULL)
- join_list = lappend(join_list, rel);
- }
+ foreach(i, joininfo_list)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(i);
+ Rel *rel;
+
+ if (!joininfo->inactive)
+ {
+ List *other_rels = joininfo->otherrels;
+
+ if (other_rels != NIL)
+ {
+ if (length(other_rels) == 1)
+ {
+ rel = init_join_rel(outer_rel,
+ get_base_rel(root, lfirsti(other_rels)),
+ joininfo);
+ /* how about right-sided plan ? */
+ if (_use_right_sided_plans_ &&
+ length(outer_rel->relids) > 1)
+ {
+ if (rel != NULL)
+ join_list = lappend(join_list, rel);
+ rel = init_join_rel(get_base_rel(root, lfirsti(other_rels)),
+ outer_rel,
+ joininfo);
+ }
+ }
+ else if (BushyPlanFlag)
+ {
+ rel = init_join_rel(outer_rel,
+ get_join_rel(root, other_rels),
+ joininfo);
+ }
+ else
+ {
+ rel = NULL;
+ }
+
+ if (rel != NULL)
+ join_list = lappend(join_list, rel);
+ }
+ }
}
- }
- return(join_list);
+ return (join_list);
}
-/*
+/*
* find-clauseless-joins--
- * Given an outer relation 'outer-rel' and a list of inner relations
- * 'inner-rels', create a join relation between 'outer-rel' and each
- * member of 'inner-rels' that isn't already included in 'outer-rel'.
- *
+ * Given an outer relation 'outer-rel' and a list of inner relations
+ * 'inner-rels', create a join relation between 'outer-rel' and each
+ * member of 'inner-rels' that isn't already included in 'outer-rel'.
+ *
* Returns a list of new join relations.
*/
-static List *
-find_clauseless_joins(Rel *outer_rel, List *inner_rels)
+static List *
+find_clauseless_joins(Rel * outer_rel, List * inner_rels)
{
- Rel *inner_rel;
- List *t_list = NIL;
- List *temp_node = NIL;
- List *i = NIL;
-
- foreach (i, inner_rels) {
- inner_rel = (Rel *)lfirst(i);
- if(nonoverlap_rels(inner_rel, outer_rel)) {
- temp_node = lcons(init_join_rel(outer_rel,
- inner_rel,
- (JInfo*)NULL),
- NIL);
- t_list = nconc(t_list,temp_node);
- }
- }
-
- return(t_list);
+ Rel *inner_rel;
+ List *t_list = NIL;
+ List *temp_node = NIL;
+ List *i = NIL;
+
+ foreach(i, inner_rels)
+ {
+ inner_rel = (Rel *) lfirst(i);
+ if (nonoverlap_rels(inner_rel, outer_rel))
+ {
+ temp_node = lcons(init_join_rel(outer_rel,
+ inner_rel,
+ (JInfo *) NULL),
+ NIL);
+ t_list = nconc(t_list, temp_node);
+ }
+ }
+
+ return (t_list);
}
-/*
+/*
* init-join-rel--
- * Creates and initializes a new join relation.
- *
+ * Creates and initializes a new join relation.
+ *
* 'outer-rel' and 'inner-rel' are relation nodes for the relations to be
- * joined
+ * joined
* 'joininfo' is the joininfo node(join clause) containing both
- * 'outer-rel' and 'inner-rel', if any exists
- *
+ * 'outer-rel' and 'inner-rel', if any exists
+ *
* Returns the new join relation node.
*/
-static Rel *
-init_join_rel(Rel *outer_rel, Rel *inner_rel, JInfo *joininfo)
+static Rel *
+init_join_rel(Rel * outer_rel, Rel * inner_rel, JInfo * joininfo)
{
- Rel *joinrel = makeNode(Rel);
- List *joinrel_joininfo_list = NIL;
- List *new_outer_tlist;
- List *new_inner_tlist;
-
- /*
- * Create a new tlist by removing irrelevant elements from both
- * tlists of the outer and inner join relations and then merging
- * the results together.
- */
- new_outer_tlist =
- new_join_tlist(outer_rel->targetlist, /* XXX 1-based attnos */
- inner_rel->relids, 1);
- new_inner_tlist =
- new_join_tlist(inner_rel->targetlist, /* XXX 1-based attnos */
- outer_rel->relids,
- length(new_outer_tlist) + 1);
-
- joinrel->relids = NIL;
- joinrel->indexed = false;
- joinrel->pages = 0;
- joinrel->tuples = 0;
- joinrel->width = 0;
-/* joinrel->targetlist = NIL;*/
- joinrel->pathlist = NIL;
- joinrel->unorderedpath = (Path *)NULL;
- joinrel->cheapestpath = (Path *)NULL;
- joinrel->pruneable = true;
- joinrel->classlist = NULL;
- joinrel->relam = InvalidOid;
- joinrel->ordering = NULL;
- joinrel->clauseinfo = NIL;
- joinrel->joininfo = NULL;
- joinrel->innerjoin = NIL;
- joinrel->superrels = NIL;
-
- joinrel->relids = lcons(outer_rel->relids, /* ??? aren't they lists? -ay */
- lcons(inner_rel->relids, NIL));
-
- new_outer_tlist = nconc(new_outer_tlist,new_inner_tlist);
- joinrel->targetlist = new_outer_tlist;
-
- if (joininfo) {
- joinrel->clauseinfo = joininfo->jinfoclauseinfo;
- if (BushyPlanFlag)
- joininfo->inactive = true;
- }
-
- joinrel_joininfo_list =
- new_joininfo_list(append(outer_rel->joininfo, inner_rel->joininfo),
- intAppend(outer_rel->relids, inner_rel->relids));
-
- joinrel->joininfo = joinrel_joininfo_list;
-
- set_joinrel_size(joinrel, outer_rel, inner_rel, joininfo);
-
- return(joinrel);
+ Rel *joinrel = makeNode(Rel);
+ List *joinrel_joininfo_list = NIL;
+ List *new_outer_tlist;
+ List *new_inner_tlist;
+
+ /*
+ * Create a new tlist by removing irrelevant elements from both tlists
+ * of the outer and inner join relations and then merging the results
+ * together.
+ */
+ new_outer_tlist =
+ new_join_tlist(outer_rel->targetlist, /* XXX 1-based attnos */
+ inner_rel->relids, 1);
+ new_inner_tlist =
+ new_join_tlist(inner_rel->targetlist, /* XXX 1-based attnos */
+ outer_rel->relids,
+ length(new_outer_tlist) + 1);
+
+ joinrel->relids = NIL;
+ joinrel->indexed = false;
+ joinrel->pages = 0;
+ joinrel->tuples = 0;
+ joinrel->width = 0;
+/* joinrel->targetlist = NIL;*/
+ joinrel->pathlist = NIL;
+ joinrel->unorderedpath = (Path *) NULL;
+ joinrel->cheapestpath = (Path *) NULL;
+ joinrel->pruneable = true;
+ joinrel->classlist = NULL;
+ joinrel->relam = InvalidOid;
+ joinrel->ordering = NULL;
+ joinrel->clauseinfo = NIL;
+ joinrel->joininfo = NULL;
+ joinrel->innerjoin = NIL;
+ joinrel->superrels = NIL;
+
+ joinrel->relids = lcons(outer_rel->relids, /* ??? aren't they lists?
+ * -ay */
+ lcons(inner_rel->relids, NIL));
+
+ new_outer_tlist = nconc(new_outer_tlist, new_inner_tlist);
+ joinrel->targetlist = new_outer_tlist;
+
+ if (joininfo)
+ {
+ joinrel->clauseinfo = joininfo->jinfoclauseinfo;
+ if (BushyPlanFlag)
+ joininfo->inactive = true;
+ }
+
+ joinrel_joininfo_list =
+ new_joininfo_list(append(outer_rel->joininfo, inner_rel->joininfo),
+ intAppend(outer_rel->relids, inner_rel->relids));
+
+ joinrel->joininfo = joinrel_joininfo_list;
+
+ set_joinrel_size(joinrel, outer_rel, inner_rel, joininfo);
+
+ return (joinrel);
}
-/*
+/*
* new-join-tlist--
- * Builds a join relations's target list by keeping those elements that
- * will be in the final target list and any other elements that are still
- * needed for future joins. For a target list entry to still be needed
- * for future joins, its 'joinlist' field must not be empty after removal
- * of all relids in 'other-relids'.
- *
+ * Builds a join relations's target list by keeping those elements that
+ * will be in the final target list and any other elements that are still
+ * needed for future joins. For a target list entry to still be needed
+ * for future joins, its 'joinlist' field must not be empty after removal
+ * of all relids in 'other-relids'.
+ *
* 'tlist' is the target list of one of the join relations
* 'other-relids' is a list of relids contained within the other
- * join relation
+ * join relation
* 'first-resdomno' is the resdom number to use for the first created
- * target list entry
- *
+ * target list entry
+ *
* Returns the new target list.
*/
-static List *
-new_join_tlist(List *tlist,
- List *other_relids,
- int first_resdomno)
+static List *
+new_join_tlist(List * tlist,
+ List * other_relids,
+ int first_resdomno)
{
- int resdomno = first_resdomno - 1;
- TargetEntry *xtl = NULL;
- List *temp_node = NIL;
- List *t_list = NIL;
- List *i = NIL;
- List *join_list = NIL;
- bool in_final_tlist =false;
-
-
- foreach(i,tlist) {
- xtl= lfirst(i);
- in_final_tlist = (join_list==NIL);
- if( in_final_tlist) {
- resdomno += 1;
- temp_node =
- lcons(create_tl_element(get_expr(xtl),
- resdomno),
- NIL);
- t_list = nconc(t_list,temp_node);
- }
- }
-
- return(t_list);
+ int resdomno = first_resdomno - 1;
+ TargetEntry *xtl = NULL;
+ List *temp_node = NIL;
+ List *t_list = NIL;
+ List *i = NIL;
+ List *join_list = NIL;
+ bool in_final_tlist = false;
+
+
+ foreach(i, tlist)
+ {
+ xtl = lfirst(i);
+ in_final_tlist = (join_list == NIL);
+ if (in_final_tlist)
+ {
+ resdomno += 1;
+ temp_node =
+ lcons(create_tl_element(get_expr(xtl),
+ resdomno),
+ NIL);
+ t_list = nconc(t_list, temp_node);
+ }
+ }
+
+ return (t_list);
}
-/*
+/*
* new-joininfo-list--
- * Builds a join relation's joininfo list by checking for join clauses
- * which still need to used in future joins involving this relation. A
- * join clause is still needed if there are still relations in the clause
- * not contained in the list of relations comprising this join relation.
- * New joininfo nodes are only created and added to
- * 'current-joininfo-list' if a node for a particular join hasn't already
- * been created.
+ * Builds a join relation's joininfo list by checking for join clauses
+ * which still need to used in future joins involving this relation. A
+ * join clause is still needed if there are still relations in the clause
+ * not contained in the list of relations comprising this join relation.
+ * New joininfo nodes are only created and added to
+ * 'current-joininfo-list' if a node for a particular join hasn't already
+ * been created.
*
- * 'current-joininfo-list' contains a list of those joininfo nodes that
- * have already been built
+ * 'current-joininfo-list' contains a list of those joininfo nodes that
+ * have already been built
* 'joininfo-list' is the list of join clauses involving this relation
- * 'join-relids' is a list of relids corresponding to the relations
- * currently being joined
- *
+ * 'join-relids' is a list of relids corresponding to the relations
+ * currently being joined
+ *
* Returns a list of joininfo nodes, new and old.
*/
-static List *
-new_joininfo_list(List *joininfo_list, List *join_relids)
+static List *
+new_joininfo_list(List * joininfo_list, List * join_relids)
{
- List *current_joininfo_list = NIL;
- List *new_otherrels = NIL;
- JInfo *other_joininfo = (JInfo*)NULL;
- List *xjoininfo = NIL;
-
- foreach (xjoininfo, joininfo_list) {
- List *or;
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
-
- new_otherrels = joininfo->otherrels;
- foreach (or, new_otherrels)
- {
- if ( intMember (lfirsti(or), join_relids) )
- new_otherrels = lremove ((void*)lfirst(or), new_otherrels);
- }
- joininfo->otherrels = new_otherrels;
- if ( new_otherrels != NIL )
+ List *current_joininfo_list = NIL;
+ List *new_otherrels = NIL;
+ JInfo *other_joininfo = (JInfo *) NULL;
+ List *xjoininfo = NIL;
+
+ foreach(xjoininfo, joininfo_list)
{
- other_joininfo = joininfo_member(new_otherrels,
- current_joininfo_list);
- if(other_joininfo) {
- other_joininfo->jinfoclauseinfo =
- (List*)LispUnion(joininfo->jinfoclauseinfo,
- other_joininfo->jinfoclauseinfo);
- }else {
- other_joininfo = makeNode(JInfo);
-
- other_joininfo->otherrels =
- joininfo->otherrels;
- other_joininfo->jinfoclauseinfo =
- joininfo->jinfoclauseinfo;
- other_joininfo->mergesortable =
- joininfo->mergesortable;
- other_joininfo->hashjoinable =
- joininfo->hashjoinable;
- other_joininfo->inactive = false;
-
- current_joininfo_list = lcons(other_joininfo,
- current_joininfo_list);
- }
+ List *or;
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+
+ new_otherrels = joininfo->otherrels;
+ foreach(or, new_otherrels)
+ {
+ if (intMember(lfirsti(or), join_relids))
+ new_otherrels = lremove((void *) lfirst(or), new_otherrels);
+ }
+ joininfo->otherrels = new_otherrels;
+ if (new_otherrels != NIL)
+ {
+ other_joininfo = joininfo_member(new_otherrels,
+ current_joininfo_list);
+ if (other_joininfo)
+ {
+ other_joininfo->jinfoclauseinfo =
+ (List *) LispUnion(joininfo->jinfoclauseinfo,
+ other_joininfo->jinfoclauseinfo);
+ }
+ else
+ {
+ other_joininfo = makeNode(JInfo);
+
+ other_joininfo->otherrels =
+ joininfo->otherrels;
+ other_joininfo->jinfoclauseinfo =
+ joininfo->jinfoclauseinfo;
+ other_joininfo->mergesortable =
+ joininfo->mergesortable;
+ other_joininfo->hashjoinable =
+ joininfo->hashjoinable;
+ other_joininfo->inactive = false;
+
+ current_joininfo_list = lcons(other_joininfo,
+ current_joininfo_list);
+ }
+ }
}
- }
- return(current_joininfo_list);
+ return (current_joininfo_list);
}
/*
* add-new-joininfos--
- * For each new join relation, create new joininfos that
- * use the join relation as inner relation, and add
- * the new joininfos to those rel nodes that still
- * have joins with the join relation.
+ * For each new join relation, create new joininfos that
+ * use the join relation as inner relation, and add
+ * the new joininfos to those rel nodes that still
+ * have joins with the join relation.
*
* 'joinrels' is a list of join relations.
*
* Modifies the joininfo field of appropriate rel nodes.
*/
void
-add_new_joininfos(Query *root, List *joinrels, List *outerrels)
+add_new_joininfos(Query * root, List * joinrels, List * outerrels)
{
- List *xjoinrel = NIL;
- List *xrelid = NIL;
- List *xrel = NIL;
- List *xjoininfo = NIL;
-
- foreach(xjoinrel, joinrels) {
- Rel *joinrel = (Rel *)lfirst(xjoinrel);
- foreach(xrelid, joinrel->relids) {
- Relid relid = (Relid)lfirst(xrelid);
- Rel *rel = get_join_rel(root, relid);
- add_superrels(rel,joinrel);
+ List *xjoinrel = NIL;
+ List *xrelid = NIL;
+ List *xrel = NIL;
+ List *xjoininfo = NIL;
+
+ foreach(xjoinrel, joinrels)
+ {
+ Rel *joinrel = (Rel *) lfirst(xjoinrel);
+
+ foreach(xrelid, joinrel->relids)
+ {
+ Relid relid = (Relid) lfirst(xrelid);
+ Rel *rel = get_join_rel(root, relid);
+
+ add_superrels(rel, joinrel);
+ }
}
- }
- foreach(xjoinrel, joinrels) {
- Rel *joinrel = (Rel *)lfirst(xjoinrel);
-
- foreach(xjoininfo, joinrel->joininfo) {
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
- List *other_rels = joininfo->otherrels;
- List *clause_info = joininfo->jinfoclauseinfo;
- bool mergesortable = joininfo->mergesortable;
- bool hashjoinable = joininfo->hashjoinable;
-
- foreach(xrelid, other_rels) {
- Relid relid = (Relid)lfirst(xrelid);
- Rel *rel = get_join_rel(root, relid);
- List *super_rels = rel->superrels;
- List *xsuper_rel = NIL;
- JInfo *new_joininfo = makeNode(JInfo);
-
- new_joininfo->otherrels = joinrel->relids;
- new_joininfo->jinfoclauseinfo = clause_info;
- new_joininfo->mergesortable = mergesortable;
- new_joininfo->hashjoinable = hashjoinable;
- new_joininfo->inactive = false;
- rel->joininfo =
- lappend(rel->joininfo, new_joininfo);
-
- foreach(xsuper_rel, super_rels) {
- Rel *super_rel = (Rel *)lfirst(xsuper_rel);
-
- if( nonoverlap_rels(super_rel,joinrel) ) {
- List *new_relids = super_rel->relids;
- JInfo *other_joininfo =
- joininfo_member(new_relids,
- joinrel->joininfo);
-
- if (other_joininfo) {
- other_joininfo->jinfoclauseinfo =
- (List*)LispUnion(clause_info,
- other_joininfo->jinfoclauseinfo);
- } else {
- JInfo *new_joininfo = makeNode(JInfo);
-
- new_joininfo->otherrels = new_relids;
- new_joininfo->jinfoclauseinfo = clause_info;
- new_joininfo->mergesortable = mergesortable;
- new_joininfo->hashjoinable = hashjoinable;
- new_joininfo->inactive = false;
- joinrel->joininfo =
- lappend(joinrel->joininfo,
- new_joininfo);
+ foreach(xjoinrel, joinrels)
+ {
+ Rel *joinrel = (Rel *) lfirst(xjoinrel);
+
+ foreach(xjoininfo, joinrel->joininfo)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+ List *other_rels = joininfo->otherrels;
+ List *clause_info = joininfo->jinfoclauseinfo;
+ bool mergesortable = joininfo->mergesortable;
+ bool hashjoinable = joininfo->hashjoinable;
+
+ foreach(xrelid, other_rels)
+ {
+ Relid relid = (Relid) lfirst(xrelid);
+ Rel *rel = get_join_rel(root, relid);
+ List *super_rels = rel->superrels;
+ List *xsuper_rel = NIL;
+ JInfo *new_joininfo = makeNode(JInfo);
+
+ new_joininfo->otherrels = joinrel->relids;
+ new_joininfo->jinfoclauseinfo = clause_info;
+ new_joininfo->mergesortable = mergesortable;
+ new_joininfo->hashjoinable = hashjoinable;
+ new_joininfo->inactive = false;
+ rel->joininfo =
+ lappend(rel->joininfo, new_joininfo);
+
+ foreach(xsuper_rel, super_rels)
+ {
+ Rel *super_rel = (Rel *) lfirst(xsuper_rel);
+
+ if (nonoverlap_rels(super_rel, joinrel))
+ {
+ List *new_relids = super_rel->relids;
+ JInfo *other_joininfo =
+ joininfo_member(new_relids,
+ joinrel->joininfo);
+
+ if (other_joininfo)
+ {
+ other_joininfo->jinfoclauseinfo =
+ (List *) LispUnion(clause_info,
+ other_joininfo->jinfoclauseinfo);
+ }
+ else
+ {
+ JInfo *new_joininfo = makeNode(JInfo);
+
+ new_joininfo->otherrels = new_relids;
+ new_joininfo->jinfoclauseinfo = clause_info;
+ new_joininfo->mergesortable = mergesortable;
+ new_joininfo->hashjoinable = hashjoinable;
+ new_joininfo->inactive = false;
+ joinrel->joininfo =
+ lappend(joinrel->joininfo,
+ new_joininfo);
+ }
+ }
+ }
}
- }
}
- }
}
- }
- foreach(xrel, outerrels) {
- Rel *rel = (Rel *)lfirst(xrel);
- rel->superrels = NIL;
- }
+ foreach(xrel, outerrels)
+ {
+ Rel *rel = (Rel *) lfirst(xrel);
+
+ rel->superrels = NIL;
+ }
}
/*
* final-join-rels--
- * Find the join relation that includes all the original
- * relations, i.e. the final join result.
+ * Find the join relation that includes all the original
+ * relations, i.e. the final join result.
*
* 'join-rel-list' is a list of join relations.
*
* Returns the list of final join relations.
*/
-List *
-final_join_rels(List *join_rel_list)
+List *
+final_join_rels(List * join_rel_list)
{
- List *xrel = NIL;
- List *temp = NIL;
- List *t_list = NIL;
-
- /*
- * find the relations that has no further joins,
- * i.e., its joininfos all have otherrels nil.
- */
- foreach(xrel,join_rel_list) {
- Rel *rel = (Rel *)lfirst(xrel);
- List *xjoininfo = NIL;
- bool final = true;
-
- foreach (xjoininfo, rel->joininfo) {
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
-
- if (joininfo->otherrels != NIL) {
- final = false;
- break;
- }
- }
- if (final) {
- temp = lcons(rel, NIL);
- t_list = nconc(t_list, temp);
+ List *xrel = NIL;
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ /*
+ * find the relations that has no further joins, i.e., its joininfos
+ * all have otherrels nil.
+ */
+ foreach(xrel, join_rel_list)
+ {
+ Rel *rel = (Rel *) lfirst(xrel);
+ List *xjoininfo = NIL;
+ bool final = true;
+
+ foreach(xjoininfo, rel->joininfo)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+
+ if (joininfo->otherrels != NIL)
+ {
+ final = false;
+ break;
+ }
+ }
+ if (final)
+ {
+ temp = lcons(rel, NIL);
+ t_list = nconc(t_list, temp);
+ }
}
- }
- return(t_list);
+ return (t_list);
}
/*
* add_superrels--
- * add rel to the temporary property list superrels.
+ * add rel to the temporary property list superrels.
*
* 'rel' a rel node
* 'super-rel' rel node of a join relation that includes rel
@@ -492,60 +533,69 @@ final_join_rels(List *join_rel_list)
* Modifies the superrels field of rel
*/
static void
-add_superrels(Rel *rel, Rel *super_rel)
+add_superrels(Rel * rel, Rel * super_rel)
{
- rel->superrels = lappend(rel->superrels, super_rel);
+ rel->superrels = lappend(rel->superrels, super_rel);
}
/*
* nonoverlap-rels--
- * test if two join relations overlap, i.e., includes the same
- * relation.
+ * test if two join relations overlap, i.e., includes the same
+ * relation.
*
* 'rel1' and 'rel2' are two join relations
*
* Returns non-nil if rel1 and rel2 do not overlap.
*/
-static bool
-nonoverlap_rels(Rel *rel1, Rel *rel2)
+static bool
+nonoverlap_rels(Rel * rel1, Rel * rel2)
{
- return(nonoverlap_sets(rel1->relids, rel2->relids));
+ return (nonoverlap_sets(rel1->relids, rel2->relids));
}
-static bool
-nonoverlap_sets(List *s1, List *s2)
+static bool
+nonoverlap_sets(List * s1, List * s2)
{
- List *x = NIL;
-
- foreach(x,s1) {
- int e = lfirsti(x);
- if(intMember(e,s2))
- return(false);
- }
- return(true);
+ List *x = NIL;
+
+ foreach(x, s1)
+ {
+ int e = lfirsti(x);
+
+ if (intMember(e, s2))
+ return (false);
+ }
+ return (true);
}
static void
-set_joinrel_size(Rel *joinrel, Rel *outer_rel, Rel *inner_rel, JInfo *jinfo)
+set_joinrel_size(Rel * joinrel, Rel * outer_rel, Rel * inner_rel, JInfo * jinfo)
{
- int ntuples;
- float selec;
-
- /* voodoo magic. but better than a size of 0. I have no idea why
- we didn't set the size before. -ay 2/95 */
- if (jinfo==NULL) {
- /* worst case: the cartesian product */
- ntuples = outer_rel->tuples * inner_rel->tuples;
- } else {
- selec = product_selec(jinfo->jinfoclauseinfo);
-/* ntuples = Min(outer_rel->tuples,inner_rel->tuples) * selec; */
- ntuples = outer_rel->tuples * inner_rel->tuples * selec;
- }
-
- /* I bet sizes less than 1 will screw up optimization so
- make the best case 1 instead of 0 - jolly*/
- if (ntuples < 1)
- ntuples = 1;
-
- joinrel->tuples = ntuples;
+ int ntuples;
+ float selec;
+
+ /*
+ * voodoo magic. but better than a size of 0. I have no idea why we
+ * didn't set the size before. -ay 2/95
+ */
+ if (jinfo == NULL)
+ {
+ /* worst case: the cartesian product */
+ ntuples = outer_rel->tuples * inner_rel->tuples;
+ }
+ else
+ {
+ selec = product_selec(jinfo->jinfoclauseinfo);
+/* ntuples = Min(outer_rel->tuples,inner_rel->tuples) * selec; */
+ ntuples = outer_rel->tuples * inner_rel->tuples * selec;
+ }
+
+ /*
+ * I bet sizes less than 1 will screw up optimization so make the best
+ * case 1 instead of 0 - jolly
+ */
+ if (ntuples < 1)
+ ntuples = 1;
+
+ joinrel->tuples = ntuples;
}
diff --git a/src/backend/optimizer/path/joinutils.c b/src/backend/optimizer/path/joinutils.c
index 1be5a57f2ec..c88d3cf19e8 100644
--- a/src/backend/optimizer/path/joinutils.c
+++ b/src/backend/optimizer/path/joinutils.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* joinutils.c--
- * Utilities for matching and building join and path keys
+ * Utilities for matching and building join and path keys
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/joinutils.c,v 1.1.1.1 1996/07/09 06:21:36 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/joinutils.c,v 1.2 1997/09/07 04:43:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,407 +26,440 @@
#include "optimizer/ordering.h"
-static int match_pathkey_joinkeys(List *pathkey, List *joinkeys,
- int which_subkey);
-static bool every_func(List *joinkeys, List *pathkey,
- int which_subkey);
-static List *new_join_pathkey(List *subkeys,
- List *considered_subkeys, List *join_rel_tlist,
- List *joinclauses);
-static List *new_matching_subkeys(Var *subkey, List *considered_subkeys,
- List *join_rel_tlist, List *joinclauses);
+static int
+match_pathkey_joinkeys(List * pathkey, List * joinkeys,
+ int which_subkey);
+static bool
+every_func(List * joinkeys, List * pathkey,
+ int which_subkey);
+static List *
+new_join_pathkey(List * subkeys,
+ List * considered_subkeys, List * join_rel_tlist,
+ List * joinclauses);
+static List *
+new_matching_subkeys(Var * subkey, List * considered_subkeys,
+ List * join_rel_tlist, List * joinclauses);
/****************************************************************************
- * KEY COMPARISONS
+ * KEY COMPARISONS
****************************************************************************/
-/*
+/*
* match-pathkeys-joinkeys--
- * Attempts to match the keys of a path against the keys of join clauses.
- * This is done by looking for a matching join key in 'joinkeys' for
- * every path key in the list 'pathkeys'. If there is a matching join key
- * (not necessarily unique) for every path key, then the list of
- * corresponding join keys and join clauses are returned in the order in
- * which the keys matched the path keys.
- *
+ * Attempts to match the keys of a path against the keys of join clauses.
+ * This is done by looking for a matching join key in 'joinkeys' for
+ * every path key in the list 'pathkeys'. If there is a matching join key
+ * (not necessarily unique) for every path key, then the list of
+ * corresponding join keys and join clauses are returned in the order in
+ * which the keys matched the path keys.
+ *
* 'pathkeys' is a list of path keys:
- * ( ( (var) (var) ... ) ( (var) ... ) )
+ * ( ( (var) (var) ... ) ( (var) ... ) )
* 'joinkeys' is a list of join keys:
- * ( (outer inner) (outer inner) ... )
+ * ( (outer inner) (outer inner) ... )
* 'joinclauses' is a list of clauses corresponding to the join keys in
- * 'joinkeys'
+ * 'joinkeys'
* 'which-subkey' is a flag that selects the desired subkey of a join key
- * in 'joinkeys'
- *
+ * in 'joinkeys'
+ *
* Returns the join keys and corresponding join clauses in a list if all
* of the path keys were matched:
- * (
- * ( (outerkey0 innerkey0) ... (outerkeyN innerkeyN) )
- * ( clause0 ... clauseN )
- * )
+ * (
+ * ( (outerkey0 innerkey0) ... (outerkeyN innerkeyN) )
+ * ( clause0 ... clauseN )
+ * )
* and nil otherwise.
- *
+ *
* Returns a list of matched join keys and a list of matched join clauses
* in matchedJoinClausesPtr. - ay 11/94
*/
-List *
-match_pathkeys_joinkeys(List *pathkeys,
- List *joinkeys,
- List *joinclauses,
- int which_subkey,
- List **matchedJoinClausesPtr)
+List *
+match_pathkeys_joinkeys(List * pathkeys,
+ List * joinkeys,
+ List * joinclauses,
+ int which_subkey,
+ List ** matchedJoinClausesPtr)
{
- List *matched_joinkeys = NIL;
- List *matched_joinclauses = NIL;
- List *pathkey = NIL;
- List *i = NIL;
- int matched_joinkey_index = -1;
-
- foreach(i, pathkeys) {
- pathkey = lfirst(i);
- matched_joinkey_index =
- match_pathkey_joinkeys(pathkey, joinkeys, which_subkey);
-
- if (matched_joinkey_index != -1 ) {
- List *xjoinkey = nth(matched_joinkey_index,joinkeys);
- List *joinclause = nth(matched_joinkey_index,joinclauses);
-
- /* XXX was "push" function */
- matched_joinkeys = lappend(matched_joinkeys,xjoinkey);
- matched_joinkeys = nreverse(matched_joinkeys);
-
- matched_joinclauses = lappend(matched_joinclauses,joinclause);
- matched_joinclauses = nreverse(matched_joinclauses);
- joinkeys = LispRemove(xjoinkey,joinkeys);
- } else {
- return(NIL);
- }
-
- }
- if(matched_joinkeys==NULL ||
- length(matched_joinkeys) != length(pathkeys)) {
- return NIL;
- }
-
- *matchedJoinClausesPtr = nreverse(matched_joinclauses);
- return (nreverse(matched_joinkeys));
+ List *matched_joinkeys = NIL;
+ List *matched_joinclauses = NIL;
+ List *pathkey = NIL;
+ List *i = NIL;
+ int matched_joinkey_index = -1;
+
+ foreach(i, pathkeys)
+ {
+ pathkey = lfirst(i);
+ matched_joinkey_index =
+ match_pathkey_joinkeys(pathkey, joinkeys, which_subkey);
+
+ if (matched_joinkey_index != -1)
+ {
+ List *xjoinkey = nth(matched_joinkey_index, joinkeys);
+ List *joinclause = nth(matched_joinkey_index, joinclauses);
+
+ /* XXX was "push" function */
+ matched_joinkeys = lappend(matched_joinkeys, xjoinkey);
+ matched_joinkeys = nreverse(matched_joinkeys);
+
+ matched_joinclauses = lappend(matched_joinclauses, joinclause);
+ matched_joinclauses = nreverse(matched_joinclauses);
+ joinkeys = LispRemove(xjoinkey, joinkeys);
+ }
+ else
+ {
+ return (NIL);
+ }
+
+ }
+ if (matched_joinkeys == NULL ||
+ length(matched_joinkeys) != length(pathkeys))
+ {
+ return NIL;
+ }
+
+ *matchedJoinClausesPtr = nreverse(matched_joinclauses);
+ return (nreverse(matched_joinkeys));
}
-/*
+/*
* match-pathkey-joinkeys--
- * Returns the 0-based index into 'joinkeys' of the first joinkey whose
- * outer or inner subkey matches any subkey of 'pathkey'.
+ * Returns the 0-based index into 'joinkeys' of the first joinkey whose
+ * outer or inner subkey matches any subkey of 'pathkey'.
*/
static int
-match_pathkey_joinkeys(List *pathkey,
- List *joinkeys,
- int which_subkey)
+match_pathkey_joinkeys(List * pathkey,
+ List * joinkeys,
+ int which_subkey)
{
- Var *path_subkey;
- int pos;
- List *i = NIL;
- List *x = NIL;
- JoinKey *jk;
-
- foreach(i, pathkey) {
- path_subkey = (Var *)lfirst(i);
- pos = 0;
- foreach(x, joinkeys) {
- jk = (JoinKey*)lfirst(x);
- if(var_equal(path_subkey,
- extract_subkey(jk, which_subkey)))
- return(pos);
- pos++;
+ Var *path_subkey;
+ int pos;
+ List *i = NIL;
+ List *x = NIL;
+ JoinKey *jk;
+
+ foreach(i, pathkey)
+ {
+ path_subkey = (Var *) lfirst(i);
+ pos = 0;
+ foreach(x, joinkeys)
+ {
+ jk = (JoinKey *) lfirst(x);
+ if (var_equal(path_subkey,
+ extract_subkey(jk, which_subkey)))
+ return (pos);
+ pos++;
+ }
}
- }
- return(-1); /* no index found */
+ return (-1); /* no index found */
}
-/*
+/*
* match-paths-joinkeys--
- * Attempts to find a path in 'paths' whose keys match a set of join
- * keys 'joinkeys'. To match,
- * 1. the path node ordering must equal 'ordering'.
- * 2. each subkey of a given path must match(i.e., be(var_equal) to) the
- * appropriate subkey of the corresponding join key in 'joinkeys',
- * i.e., the Nth path key must match its subkeys against the subkey of
- * the Nth join key in 'joinkeys'.
- *
- * 'joinkeys' is the list of key pairs to which the path keys must be
- * matched
+ * Attempts to find a path in 'paths' whose keys match a set of join
+ * keys 'joinkeys'. To match,
+ * 1. the path node ordering must equal 'ordering'.
+ * 2. each subkey of a given path must match(i.e., be(var_equal) to) the
+ * appropriate subkey of the corresponding join key in 'joinkeys',
+ * i.e., the Nth path key must match its subkeys against the subkey of
+ * the Nth join key in 'joinkeys'.
+ *
+ * 'joinkeys' is the list of key pairs to which the path keys must be
+ * matched
* 'ordering' is the ordering of the(outer) path to which 'joinkeys'
- * must correspond
+ * must correspond
* 'paths' is a list of(inner) paths which are to be matched against
- * each join key in 'joinkeys'
+ * each join key in 'joinkeys'
* 'which-subkey' is a flag that selects the desired subkey of a join key
- * in 'joinkeys'
- *
+ * in 'joinkeys'
+ *
* Returns the matching path node if one exists, nil otherwise.
*/
-static bool
-every_func(List *joinkeys, List *pathkey, int which_subkey)
+static bool
+every_func(List * joinkeys, List * pathkey, int which_subkey)
{
- JoinKey *xjoinkey;
- Var *temp;
- Var *tempkey = NULL;
- bool found = false;
- List *i = NIL;
- List *j = NIL;
-
- foreach(i,joinkeys) {
- xjoinkey = (JoinKey*)lfirst(i);
- found = false;
- foreach(j,pathkey) {
- temp = (Var*)lfirst((List*)lfirst(j));
- if(temp == NULL) continue;
- tempkey = extract_subkey(xjoinkey,which_subkey);
- if(var_equal(tempkey, temp)) {
- found = true;
- break;
- }
+ JoinKey *xjoinkey;
+ Var *temp;
+ Var *tempkey = NULL;
+ bool found = false;
+ List *i = NIL;
+ List *j = NIL;
+
+ foreach(i, joinkeys)
+ {
+ xjoinkey = (JoinKey *) lfirst(i);
+ found = false;
+ foreach(j, pathkey)
+ {
+ temp = (Var *) lfirst((List *) lfirst(j));
+ if (temp == NULL)
+ continue;
+ tempkey = extract_subkey(xjoinkey, which_subkey);
+ if (var_equal(tempkey, temp))
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found == false)
+ return (false);
}
- if(found == false)
- return(false);
- }
- return(found);
+ return (found);
}
/*
* match_paths_joinkeys -
- * find the cheapest path that matches the join keys
+ * find the cheapest path that matches the join keys
*/
-Path *
-match_paths_joinkeys(List *joinkeys,
- PathOrder *ordering,
- List *paths,
- int which_subkey)
+Path *
+match_paths_joinkeys(List * joinkeys,
+ PathOrder * ordering,
+ List * paths,
+ int which_subkey)
{
- Path *matched_path = NULL ;
- bool key_match = false;
- List *i = NIL;
-
- foreach(i,paths) {
- Path *path = (Path*)lfirst(i);
-
- key_match = every_func(joinkeys, path->keys, which_subkey);
-
- if (equal_path_path_ordering(ordering,
- &path->p_ordering) &&
- length(joinkeys) == length(path->keys) &&
- key_match) {
-
- if (matched_path) {
- if (path->path_cost < matched_path->path_cost)
- matched_path = path;
- } else {
- matched_path = path;
- }
+ Path *matched_path = NULL;
+ bool key_match = false;
+ List *i = NIL;
+
+ foreach(i, paths)
+ {
+ Path *path = (Path *) lfirst(i);
+
+ key_match = every_func(joinkeys, path->keys, which_subkey);
+
+ if (equal_path_path_ordering(ordering,
+ &path->p_ordering) &&
+ length(joinkeys) == length(path->keys) &&
+ key_match)
+ {
+
+ if (matched_path)
+ {
+ if (path->path_cost < matched_path->path_cost)
+ matched_path = path;
+ }
+ else
+ {
+ matched_path = path;
+ }
+ }
}
- }
- return matched_path;
+ return matched_path;
}
-/*
+/*
* extract-path-keys--
- * Builds a subkey list for a path by pulling one of the subkeys from
- * a list of join keys 'joinkeys' and then finding the var node in the
- * target list 'tlist' that corresponds to that subkey.
- *
+ * Builds a subkey list for a path by pulling one of the subkeys from
+ * a list of join keys 'joinkeys' and then finding the var node in the
+ * target list 'tlist' that corresponds to that subkey.
+ *
* 'joinkeys' is a list of join key pairs
* 'tlist' is a relation target list
* 'which-subkey' is a flag that selects the desired subkey of a join key
- * in 'joinkeys'
- *
+ * in 'joinkeys'
+ *
* Returns a list of pathkeys: ((tlvar1)(tlvar2)...(tlvarN)).
* [I've no idea why they have to be list of lists. Should be fixed. -ay 12/94]
*/
-List *
-extract_path_keys(List *joinkeys,
- List *tlist,
- int which_subkey)
+List *
+extract_path_keys(List * joinkeys,
+ List * tlist,
+ int which_subkey)
{
- List *pathkeys = NIL;
- List *jk;
-
- foreach(jk, joinkeys) {
- JoinKey *jkey = (JoinKey*)lfirst(jk);
- Var *var, *key;
- List *p;
-
- /*
- * find the right Var in the target list for this key
- */
- var = (Var*)extract_subkey(jkey, which_subkey);
- key = (Var*)matching_tlvar(var, tlist);
-
- /*
- * include it in the pathkeys list if we haven't already done so
- */
- foreach(p, pathkeys) {
- Var *pkey = lfirst((List*)lfirst(p)); /* XXX fix me */
- if (key == pkey)
- break;
- }
- if (p!=NIL)
- continue; /* key already in pathkeys */
+ List *pathkeys = NIL;
+ List *jk;
+
+ foreach(jk, joinkeys)
+ {
+ JoinKey *jkey = (JoinKey *) lfirst(jk);
+ Var *var,
+ *key;
+ List *p;
- pathkeys =
- lappend(pathkeys, lcons(key,NIL));
- }
- return(pathkeys);
+ /*
+ * find the right Var in the target list for this key
+ */
+ var = (Var *) extract_subkey(jkey, which_subkey);
+ key = (Var *) matching_tlvar(var, tlist);
+
+ /*
+ * include it in the pathkeys list if we haven't already done so
+ */
+ foreach(p, pathkeys)
+ {
+ Var *pkey = lfirst((List *) lfirst(p)); /* XXX fix me */
+
+ if (key == pkey)
+ break;
+ }
+ if (p != NIL)
+ continue; /* key already in pathkeys */
+
+ pathkeys =
+ lappend(pathkeys, lcons(key, NIL));
+ }
+ return (pathkeys);
}
/****************************************************************************
- * NEW PATHKEY FORMATION
+ * NEW PATHKEY FORMATION
****************************************************************************/
-/*
+/*
* new-join-pathkeys--
- * Find the path keys for a join relation by finding all vars in the list
- * of join clauses 'joinclauses' such that:
- * (1) the var corresponding to the outer join relation is a
- * key on the outer path
- * (2) the var appears in the target list of the join relation
- * In other words, add to each outer path key the inner path keys that
- * are required for qualification.
- *
+ * Find the path keys for a join relation by finding all vars in the list
+ * of join clauses 'joinclauses' such that:
+ * (1) the var corresponding to the outer join relation is a
+ * key on the outer path
+ * (2) the var appears in the target list of the join relation
+ * In other words, add to each outer path key the inner path keys that
+ * are required for qualification.
+ *
* 'outer-pathkeys' is the list of the outer path's path keys
* 'join-rel-tlist' is the target list of the join relation
* 'joinclauses' is the list of restricting join clauses
- *
- * Returns the list of new path keys.
- *
+ *
+ * Returns the list of new path keys.
+ *
*/
-List *
-new_join_pathkeys(List *outer_pathkeys,
- List *join_rel_tlist,
- List *joinclauses)
-{
- List *outer_pathkey = NIL;
- List *t_list = NIL;
- List *x;
- List *i = NIL;
-
- foreach(i, outer_pathkeys) {
- outer_pathkey = lfirst(i);
- x = new_join_pathkey(outer_pathkey, NIL,
- join_rel_tlist,joinclauses);
- if (x!=NIL) {
- t_list = lappend(t_list, x);
+List *
+new_join_pathkeys(List * outer_pathkeys,
+ List * join_rel_tlist,
+ List * joinclauses)
+{
+ List *outer_pathkey = NIL;
+ List *t_list = NIL;
+ List *x;
+ List *i = NIL;
+
+ foreach(i, outer_pathkeys)
+ {
+ outer_pathkey = lfirst(i);
+ x = new_join_pathkey(outer_pathkey, NIL,
+ join_rel_tlist, joinclauses);
+ if (x != NIL)
+ {
+ t_list = lappend(t_list, x);
+ }
}
- }
- return(t_list);
+ return (t_list);
}
-/*
+/*
* new-join-pathkey--
- * Finds new vars that become subkeys due to qualification clauses that
- * contain any previously considered subkeys. These new subkeys plus the
- * subkeys from 'subkeys' form a new pathkey for the join relation.
- *
- * Note that each returned subkey is the var node found in
- * 'join-rel-tlist' rather than the joinclause var node.
- *
+ * Finds new vars that become subkeys due to qualification clauses that
+ * contain any previously considered subkeys. These new subkeys plus the
+ * subkeys from 'subkeys' form a new pathkey for the join relation.
+ *
+ * Note that each returned subkey is the var node found in
+ * 'join-rel-tlist' rather than the joinclause var node.
+ *
* 'subkeys' is a list of subkeys for which matching subkeys are to be
- * found
+ * found
* 'considered-subkeys' is the current list of all subkeys corresponding
- * to a given pathkey
- *
+ * to a given pathkey
+ *
* Returns a new pathkey(list of subkeys).
- *
+ *
*/
-static List *
-new_join_pathkey(List *subkeys,
- List *considered_subkeys,
- List *join_rel_tlist,
- List *joinclauses)
+static List *
+new_join_pathkey(List * subkeys,
+ List * considered_subkeys,
+ List * join_rel_tlist,
+ List * joinclauses)
{
- List *t_list = NIL;
- Var *subkey;
- List *i = NIL;
- List *matched_subkeys = NIL;
- Expr *tlist_key = (Expr*)NULL;
- List *newly_considered_subkeys = NIL;
-
- foreach (i, subkeys) {
- subkey = (Var *)lfirst(i);
- if(subkey == NULL)
- break; /* XXX something is wrong */
- matched_subkeys =
- new_matching_subkeys(subkey,considered_subkeys,
- join_rel_tlist,joinclauses);
- tlist_key = matching_tlvar(subkey,join_rel_tlist);
- newly_considered_subkeys = NIL;
-
- if (tlist_key) {
- if(!member(tlist_key, matched_subkeys))
- newly_considered_subkeys = lcons(tlist_key,
- matched_subkeys);
- }
- else {
- newly_considered_subkeys = matched_subkeys;
- }
-
- considered_subkeys =
- append(considered_subkeys, newly_considered_subkeys);
-
- t_list = nconc(t_list,newly_considered_subkeys);
- }
- return(t_list);
+ List *t_list = NIL;
+ Var *subkey;
+ List *i = NIL;
+ List *matched_subkeys = NIL;
+ Expr *tlist_key = (Expr *) NULL;
+ List *newly_considered_subkeys = NIL;
+
+ foreach(i, subkeys)
+ {
+ subkey = (Var *) lfirst(i);
+ if (subkey == NULL)
+ break; /* XXX something is wrong */
+ matched_subkeys =
+ new_matching_subkeys(subkey, considered_subkeys,
+ join_rel_tlist, joinclauses);
+ tlist_key = matching_tlvar(subkey, join_rel_tlist);
+ newly_considered_subkeys = NIL;
+
+ if (tlist_key)
+ {
+ if (!member(tlist_key, matched_subkeys))
+ newly_considered_subkeys = lcons(tlist_key,
+ matched_subkeys);
+ }
+ else
+ {
+ newly_considered_subkeys = matched_subkeys;
+ }
+
+ considered_subkeys =
+ append(considered_subkeys, newly_considered_subkeys);
+
+ t_list = nconc(t_list, newly_considered_subkeys);
+ }
+ return (t_list);
}
-/*
+/*
* new-matching-subkeys--
- * Returns a list of new subkeys:
- * (1) which are not listed in 'considered-subkeys'
- * (2) for which the "other" variable in some clause in 'joinclauses' is
- * 'subkey'
- * (3) which are mentioned in 'join-rel-tlist'
- *
- * Note that each returned subkey is the var node found in
- * 'join-rel-tlist' rather than the joinclause var node.
- *
+ * Returns a list of new subkeys:
+ * (1) which are not listed in 'considered-subkeys'
+ * (2) for which the "other" variable in some clause in 'joinclauses' is
+ * 'subkey'
+ * (3) which are mentioned in 'join-rel-tlist'
+ *
+ * Note that each returned subkey is the var node found in
+ * 'join-rel-tlist' rather than the joinclause var node.
+ *
* 'subkey' is the var node for which we are trying to find matching
- * clauses
- *
+ * clauses
+ *
* Returns a list of new subkeys.
*
*/
-static List *
-new_matching_subkeys(Var *subkey,
- List *considered_subkeys,
- List *join_rel_tlist,
- List *joinclauses)
+static List *
+new_matching_subkeys(Var * subkey,
+ List * considered_subkeys,
+ List * join_rel_tlist,
+ List * joinclauses)
{
- Expr *joinclause = NULL;
- List *t_list = NIL;
- List *temp = NIL;
- List *i = NIL;
- Expr *tlist_other_var = (Expr *)NULL;
-
- foreach(i,joinclauses) {
- joinclause = lfirst(i);
- tlist_other_var =
- matching_tlvar(other_join_clause_var(subkey,joinclause),
- join_rel_tlist);
-
- if(tlist_other_var &&
- !(member(tlist_other_var,considered_subkeys))) {
-
- /* XXX was "push" function */
- considered_subkeys = lappend(considered_subkeys,
- tlist_other_var);
-
- /* considered_subkeys = nreverse(considered_subkeys);
- XXX -- I am not sure of this. */
-
- temp = lcons(tlist_other_var, NIL);
- t_list = nconc(t_list,temp);
- }
- }
- return(t_list);
+ Expr *joinclause = NULL;
+ List *t_list = NIL;
+ List *temp = NIL;
+ List *i = NIL;
+ Expr *tlist_other_var = (Expr *) NULL;
+
+ foreach(i, joinclauses)
+ {
+ joinclause = lfirst(i);
+ tlist_other_var =
+ matching_tlvar(other_join_clause_var(subkey, joinclause),
+ join_rel_tlist);
+
+ if (tlist_other_var &&
+ !(member(tlist_other_var, considered_subkeys)))
+ {
+
+ /* XXX was "push" function */
+ considered_subkeys = lappend(considered_subkeys,
+ tlist_other_var);
+
+ /*
+ * considered_subkeys = nreverse(considered_subkeys); XXX -- I
+ * am not sure of this.
+ */
+
+ temp = lcons(tlist_other_var, NIL);
+ t_list = nconc(t_list, temp);
+ }
+ }
+ return (t_list);
}
diff --git a/src/backend/optimizer/path/mergeutils.c b/src/backend/optimizer/path/mergeutils.c
index d5f0fdcb65b..93004a6741e 100644
--- a/src/backend/optimizer/path/mergeutils.c
+++ b/src/backend/optimizer/path/mergeutils.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* mergeutils.c--
- * Utilities for finding applicable merge clauses and pathkeys
+ * Utilities for finding applicable merge clauses and pathkeys
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.1.1.1 1996/07/09 06:21:36 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.2 1997/09/07 04:43:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,102 +21,110 @@
#include "optimizer/clauses.h"
#include "optimizer/ordering.h"
-/*
+/*
* group-clauses-by-order--
- * If a join clause node in 'clauseinfo-list' is mergesortable, store
- * it within a mergeinfo node containing other clause nodes with the same
- * mergesort ordering.
- *
+ * If a join clause node in 'clauseinfo-list' is mergesortable, store
+ * it within a mergeinfo node containing other clause nodes with the same
+ * mergesort ordering.
+ *
* 'clauseinfo-list' is the list of clauseinfo nodes
* 'inner-relid' is the relid of the inner join relation
- *
+ *
* Returns the new list of mergeinfo nodes.
- *
+ *
*/
-List *
-group_clauses_by_order(List *clauseinfo_list,
- int inner_relid)
+List *
+group_clauses_by_order(List * clauseinfo_list,
+ int inner_relid)
{
- List *mergeinfo_list = NIL;
- List *xclauseinfo = NIL;
-
- foreach (xclauseinfo, clauseinfo_list) {
- CInfo *clauseinfo = (CInfo *)lfirst(xclauseinfo);
- MergeOrder *merge_ordering = clauseinfo->mergesortorder;
-
- if (merge_ordering) {
- /*
- * Create a new mergeinfo node and add it to
- * 'mergeinfo-list' if one does not yet exist for this
- * merge ordering.
- */
- PathOrder p_ordering;
- MInfo *xmergeinfo;
- Expr *clause = clauseinfo->clause;
- Var *leftop = get_leftop (clause);
- Var *rightop = get_rightop (clause);
- JoinKey *keys;
-
- p_ordering.ordtype = MERGE_ORDER;
- p_ordering.ord.merge = merge_ordering;
- xmergeinfo =
- match_order_mergeinfo(&p_ordering, mergeinfo_list);
- if (inner_relid == leftop->varno) {
- keys = makeNode(JoinKey);
- keys->outer = rightop;
- keys->inner = leftop;
- } else {
- keys = makeNode(JoinKey);
- keys->outer = leftop;
- keys->inner = rightop;
- }
-
- if (xmergeinfo==NULL) {
- xmergeinfo = makeNode(MInfo);
-
- xmergeinfo->m_ordering = merge_ordering;
- mergeinfo_list = lcons(xmergeinfo,
- mergeinfo_list);
- }
-
- ((JoinMethod *)xmergeinfo)->clauses =
- lcons(clause,
- ((JoinMethod *)xmergeinfo)->clauses);
- ((JoinMethod *)xmergeinfo)->jmkeys =
- lcons(keys,
- ((JoinMethod *)xmergeinfo)->jmkeys);
+ List *mergeinfo_list = NIL;
+ List *xclauseinfo = NIL;
+
+ foreach(xclauseinfo, clauseinfo_list)
+ {
+ CInfo *clauseinfo = (CInfo *) lfirst(xclauseinfo);
+ MergeOrder *merge_ordering = clauseinfo->mergesortorder;
+
+ if (merge_ordering)
+ {
+
+ /*
+ * Create a new mergeinfo node and add it to 'mergeinfo-list'
+ * if one does not yet exist for this merge ordering.
+ */
+ PathOrder p_ordering;
+ MInfo *xmergeinfo;
+ Expr *clause = clauseinfo->clause;
+ Var *leftop = get_leftop(clause);
+ Var *rightop = get_rightop(clause);
+ JoinKey *keys;
+
+ p_ordering.ordtype = MERGE_ORDER;
+ p_ordering.ord.merge = merge_ordering;
+ xmergeinfo =
+ match_order_mergeinfo(&p_ordering, mergeinfo_list);
+ if (inner_relid == leftop->varno)
+ {
+ keys = makeNode(JoinKey);
+ keys->outer = rightop;
+ keys->inner = leftop;
+ }
+ else
+ {
+ keys = makeNode(JoinKey);
+ keys->outer = leftop;
+ keys->inner = rightop;
+ }
+
+ if (xmergeinfo == NULL)
+ {
+ xmergeinfo = makeNode(MInfo);
+
+ xmergeinfo->m_ordering = merge_ordering;
+ mergeinfo_list = lcons(xmergeinfo,
+ mergeinfo_list);
+ }
+
+ ((JoinMethod *) xmergeinfo)->clauses =
+ lcons(clause,
+ ((JoinMethod *) xmergeinfo)->clauses);
+ ((JoinMethod *) xmergeinfo)->jmkeys =
+ lcons(keys,
+ ((JoinMethod *) xmergeinfo)->jmkeys);
+ }
}
- }
- return(mergeinfo_list);
+ return (mergeinfo_list);
}
-/*
+/*
* match-order-mergeinfo--
- * Searches the list 'mergeinfo-list' for a mergeinfo node whose order
- * field equals 'ordering'.
- *
+ * Searches the list 'mergeinfo-list' for a mergeinfo node whose order
+ * field equals 'ordering'.
+ *
* Returns the node if it exists.
- *
+ *
*/
-MInfo *
-match_order_mergeinfo(PathOrder *ordering, List *mergeinfo_list)
+MInfo *
+match_order_mergeinfo(PathOrder * ordering, List * mergeinfo_list)
{
- MergeOrder *xmergeorder;
- List *xmergeinfo = NIL;
+ MergeOrder *xmergeorder;
+ List *xmergeinfo = NIL;
- foreach(xmergeinfo, mergeinfo_list) {
- MInfo *mergeinfo = (MInfo*)lfirst(xmergeinfo);
+ foreach(xmergeinfo, mergeinfo_list)
+ {
+ MInfo *mergeinfo = (MInfo *) lfirst(xmergeinfo);
- xmergeorder = mergeinfo->m_ordering;
+ xmergeorder = mergeinfo->m_ordering;
- if ((ordering->ordtype==MERGE_ORDER &&
- equal_merge_merge_ordering(ordering->ord.merge, xmergeorder)) ||
- (ordering->ordtype==SORTOP_ORDER &&
- equal_path_merge_ordering(ordering->ord.sortop, xmergeorder))) {
+ if ((ordering->ordtype == MERGE_ORDER &&
+ equal_merge_merge_ordering(ordering->ord.merge, xmergeorder)) ||
+ (ordering->ordtype == SORTOP_ORDER &&
+ equal_path_merge_ordering(ordering->ord.sortop, xmergeorder)))
+ {
- return (mergeinfo);
+ return (mergeinfo);
+ }
}
- }
- return((MInfo*) NIL);
+ return ((MInfo *) NIL);
}
diff --git a/src/backend/optimizer/path/orindxpath.c b/src/backend/optimizer/path/orindxpath.c
index e040675e6ec..96408b78905 100644
--- a/src/backend/optimizer/path/orindxpath.c
+++ b/src/backend/optimizer/path/orindxpath.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* orindxpath.c--
- * Routines to find index paths that match a set of 'or' clauses
+ * Routines to find index paths that match a set of 'or' clauses
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.1.1.1 1996/07/09 06:21:36 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.2 1997/09/07 04:43:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,241 +31,267 @@
#include "parser/parsetree.h"
-static void best_or_subclause_indices(Query *root, Rel *rel, List *subclauses,
- List *indices, List *examined_indexids, Cost subcost, List *selectivities,
- List **indexids, Cost *cost, List **selecs);
-static void best_or_subclause_index(Query *root, Rel *rel, Expr *subclause,
- List *indices, int *indexid, Cost *cost, Cost *selec);
+static void
+best_or_subclause_indices(Query * root, Rel * rel, List * subclauses,
+ List * indices, List * examined_indexids, Cost subcost, List * selectivities,
+ List ** indexids, Cost * cost, List ** selecs);
+static void
+best_or_subclause_index(Query * root, Rel * rel, Expr * subclause,
+ List * indices, int *indexid, Cost * cost, Cost * selec);
-/*
+/*
* create-or-index-paths--
- * Creates index paths for indices that match 'or' clauses.
- *
+ * Creates index paths for indices that match 'or' clauses.
+ *
* 'rel' is the relation entry for which the paths are to be defined on
* 'clauses' is the list of available restriction clause nodes
- *
+ *
* Returns a list of these index path nodes.
- *
+ *
*/
-List *
-create_or_index_paths(Query *root,
- Rel *rel, List *clauses)
+List *
+create_or_index_paths(Query * root,
+ Rel * rel, List * clauses)
{
- List *t_list = NIL;
-
- if (clauses != NIL) {
- CInfo *clausenode = (CInfo *) (lfirst (clauses));
-
- /* 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 'Index field was set in
- * (match_or) if no index matches a given subclause, one of the
- * lists of index nodes returned by (get_index) will be 'nil').
- */
- if (valid_or_clause(clausenode) &&
- clausenode->indexids) {
- List *temp = NIL;
- List *index_list = NIL;
- bool index_flag = true;
-
- index_list = clausenode->indexids;
- foreach(temp,index_list) {
- if (!temp)
- index_flag = false;
- }
- if (index_flag) { /* used to be a lisp every function */
- IndexPath *pathnode = makeNode(IndexPath);
- List *indexids;
- Cost cost;
- List *selecs;
+ List *t_list = NIL;
+
+ if (clauses != NIL)
+ {
+ CInfo *clausenode = (CInfo *) (lfirst(clauses));
+
+ /*
+ * 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 'Index field was set in
+ * (match_or) if no index matches a given subclause, one of the
+ * lists of index nodes returned by (get_index) will be 'nil').
+ */
+ if (valid_or_clause(clausenode) &&
+ clausenode->indexids)
+ {
+ List *temp = NIL;
+ List *index_list = NIL;
+ bool index_flag = true;
+
+ index_list = clausenode->indexids;
+ foreach(temp, index_list)
+ {
+ if (!temp)
+ index_flag = false;
+ }
+ if (index_flag)
+ { /* used to be a lisp every function */
+ IndexPath *pathnode = makeNode(IndexPath);
+ List *indexids;
+ Cost cost;
+ List *selecs;
- best_or_subclause_indices(root,
- rel,
- clausenode->clause->args,
- clausenode->indexids,
- NIL,
- (Cost)0,
- NIL,
- &indexids,
- &cost,
- &selecs);
-
- pathnode->path.pathtype = T_IndexScan;
- pathnode->path.parent = rel;
- pathnode->indexqual =
- lcons(clausenode,NIL);
- pathnode->indexid = indexids;
- pathnode->path.path_cost = cost;
-
- /* copy clauseinfo list into path for expensive
- function processing -- JMH, 7/7/92 */
- pathnode->path.locclauseinfo =
- set_difference(clauses,
- copyObject((Node*)
- rel->clauseinfo));
-
-#if 0 /* fix xfunc */
- /* add in cost for expensive functions! -- JMH, 7/7/92 */
- if (XfuncMode != XFUNC_OFF) {
- ((Path*)pathnode)->path_cost +=
- xfunc_get_path_cost((Path)pathnode);
+ best_or_subclause_indices(root,
+ rel,
+ clausenode->clause->args,
+ clausenode->indexids,
+ NIL,
+ (Cost) 0,
+ NIL,
+ &indexids,
+ &cost,
+ &selecs);
+
+ pathnode->path.pathtype = T_IndexScan;
+ pathnode->path.parent = rel;
+ pathnode->indexqual =
+ lcons(clausenode, NIL);
+ pathnode->indexid = indexids;
+ pathnode->path.path_cost = cost;
+
+ /*
+ * copy clauseinfo list into path for expensive function
+ * processing -- JMH, 7/7/92
+ */
+ pathnode->path.locclauseinfo =
+ set_difference(clauses,
+ copyObject((Node *)
+ rel->clauseinfo));
+
+#if 0 /* fix xfunc */
+ /* add in cost for expensive functions! -- JMH, 7/7/92 */
+ if (XfuncMode != XFUNC_OFF)
+ {
+ ((Path *) pathnode)->path_cost +=
+ xfunc_get_path_cost((Path) pathnode);
+ }
+#endif
+ clausenode->selectivity = (Cost) floatVal(selecs);
+ t_list =
+ lcons(pathnode,
+ create_or_index_paths(root, rel, lnext(clauses)));
+ }
+ else
+ {
+ t_list = create_or_index_paths(root, rel, lnext(clauses));
+ }
}
-#endif
- clausenode->selectivity = (Cost)floatVal(selecs);
- t_list =
- lcons(pathnode,
- create_or_index_paths(root, rel,lnext(clauses)));
- } else {
- t_list = create_or_index_paths(root, rel,lnext(clauses));
- }
}
- }
- return(t_list);
+ return (t_list);
}
-/*
+/*
* best-or-subclause-indices--
- * Determines the best index to be used in conjunction with each subclause
- * of an 'or' clause and the cost of scanning a relation using these
- * indices. The cost is the sum of the individual index costs.
- *
+ * Determines the best index to be used in conjunction with each subclause
+ * of an 'or' clause and the cost of scanning a relation using these
+ * indices. The cost is the sum of the individual index costs.
+ *
* 'rel' is the node of the relation on which the index is defined
* 'subclauses' are the subclauses of the 'or' clause
* 'indices' are those index nodes that matched subclauses of the 'or'
- * clause
- * 'examined-indexids' is a list of those index ids to be used with
- * subclauses that have already been examined
+ * clause
+ * 'examined-indexids' is a list of those index ids to be used with
+ * subclauses that have already been examined
* 'subcost' is the cost of using the indices in 'examined-indexids'
* 'selectivities' is a list of the selectivities of subclauses that
- * have already been examined
- *
+ * have already been examined
+ *
* Returns a list of the indexids, cost, and selectivities of each
* subclause, e.g., ((i1 i2 i3) cost (s1 s2 s3)), where 'i' is an OID,
* 'cost' is a flonum, and 's' is a flonum.
*/
static void
-best_or_subclause_indices(Query *root,
- Rel *rel,
- List *subclauses,
- List *indices,
- List *examined_indexids,
- Cost subcost,
- List *selectivities,
- List **indexids, /* return value */
- Cost *cost, /* return value */
- List **selecs) /* return value */
+best_or_subclause_indices(Query * root,
+ Rel * rel,
+ List * subclauses,
+ List * indices,
+ List * examined_indexids,
+ Cost subcost,
+ List * selectivities,
+ List ** indexids, /* return value */
+ Cost * cost, /* return value */
+ List ** selecs) /* return value */
{
- if (subclauses==NIL) {
- *indexids = nreverse(examined_indexids);
- *cost = subcost;
- *selecs = nreverse(selectivities);
- } else {
- int best_indexid;
- Cost best_cost;
- Cost best_selec;
-
- best_or_subclause_index(root, rel, lfirst(subclauses), lfirst(indices),
- &best_indexid, &best_cost, &best_selec);
-
- best_or_subclause_indices(root,
- rel,
- lnext(subclauses),
- lnext(indices),
- lconsi(best_indexid, examined_indexids),
- subcost + best_cost,
- lcons(makeFloat(best_selec), selectivities),
- indexids,
- cost,
- selecs);
- }
- return;
-}
+ if (subclauses == NIL)
+ {
+ *indexids = nreverse(examined_indexids);
+ *cost = subcost;
+ *selecs = nreverse(selectivities);
+ }
+ else
+ {
+ int best_indexid;
+ Cost best_cost;
+ Cost best_selec;
+
+ best_or_subclause_index(root, rel, lfirst(subclauses), lfirst(indices),
+ &best_indexid, &best_cost, &best_selec);
-/*
+ best_or_subclause_indices(root,
+ rel,
+ lnext(subclauses),
+ lnext(indices),
+ lconsi(best_indexid, examined_indexids),
+ subcost + best_cost,
+ lcons(makeFloat(best_selec), selectivities),
+ indexids,
+ cost,
+ selecs);
+ }
+ return;
+}
+
+/*
* best-or-subclause-index--
- * Determines which is the best index to be used with a subclause of
- * an 'or' clause by estimating the cost of using each index and selecting
- * the least expensive.
- *
+ * Determines which is the best index to be used with a subclause of
+ * an 'or' clause by estimating the cost of using each index and selecting
+ * the least expensive.
+ *
* 'rel' is the node of the relation on which the index is defined
* 'subclause' is the subclause
* 'indices' is a list of index nodes that match the subclause
- *
+ *
* Returns a list (index-id index-subcost index-selectivity)
* (a fixnum, a fixnum, and a flonum respectively).
- *
+ *
*/
static void
-best_or_subclause_index(Query *root,
- Rel *rel,
- Expr *subclause,
- List *indices,
- int *retIndexid, /* return value */
- Cost *retCost, /* return value */
- Cost *retSelec) /* return value */
+best_or_subclause_index(Query * root,
+ Rel * rel,
+ Expr * subclause,
+ List * indices,
+ int *retIndexid, /* return value */
+ Cost * retCost, /* return value */
+ Cost * retSelec) /* return value */
{
- if (indices != NIL) {
- Datum value;
- int flag = 0;
- Cost subcost;
- Rel *index = (Rel *)lfirst (indices);
- AttrNumber attno = (get_leftop (subclause))->varattno ;
- Oid opno = ((Oper*)subclause->oper)->opno;
- bool constant_on_right = non_null((Expr*)get_rightop(subclause));
- float npages, selec;
- int subclause_indexid;
- Cost subclause_cost;
- Cost subclause_selec;
-
- if(constant_on_right) {
- value = ((Const*)get_rightop (subclause))->constvalue;
- } else {
- value = NameGetDatum("");
- }
- if(constant_on_right) {
- flag = (_SELEC_IS_CONSTANT_ ||_SELEC_CONSTANT_RIGHT_);
- } else {
- flag = _SELEC_CONSTANT_RIGHT_;
- }
- index_selectivity(lfirsti(index->relids),
- index->classlist,
- lconsi(opno,NIL),
- getrelid(lfirsti(rel->relids),
- root->rtable),
- lconsi(attno,NIL),
- lconsi(value,NIL),
- lconsi(flag,NIL),
- 1,
- &npages,
- &selec);
-
- subcost = cost_index((Oid) lfirsti(index->relids),
- (int)npages,
- (Cost)selec,
- rel->pages,
- rel->tuples,
- index->pages,
- index->tuples,
- false);
- best_or_subclause_index(root,
- rel,
- subclause,
- lnext(indices),
- &subclause_indexid,
- &subclause_cost,
- &subclause_selec);
+ if (indices != NIL)
+ {
+ Datum value;
+ int flag = 0;
+ Cost subcost;
+ Rel *index = (Rel *) lfirst(indices);
+ AttrNumber attno = (get_leftop(subclause))->varattno;
+ Oid opno = ((Oper *) subclause->oper)->opno;
+ bool constant_on_right = non_null((Expr *) get_rightop(subclause));
+ float npages,
+ selec;
+ int subclause_indexid;
+ Cost subclause_cost;
+ Cost subclause_selec;
- if (subclause_indexid==0 || subcost < subclause_cost) {
- *retIndexid = lfirsti(index->relids);
- *retCost = subcost;
- *retSelec = selec;
- } else {
- *retIndexid = 0;
- *retCost = 0.0;
- *retSelec = 0.0;
- }
- }
- return;
+ if (constant_on_right)
+ {
+ value = ((Const *) get_rightop(subclause))->constvalue;
+ }
+ else
+ {
+ value = NameGetDatum("");
+ }
+ if (constant_on_right)
+ {
+ flag = (_SELEC_IS_CONSTANT_ || _SELEC_CONSTANT_RIGHT_);
+ }
+ else
+ {
+ flag = _SELEC_CONSTANT_RIGHT_;
+ }
+ index_selectivity(lfirsti(index->relids),
+ index->classlist,
+ lconsi(opno, NIL),
+ getrelid(lfirsti(rel->relids),
+ root->rtable),
+ lconsi(attno, NIL),
+ lconsi(value, NIL),
+ lconsi(flag, NIL),
+ 1,
+ &npages,
+ &selec);
+
+ subcost = cost_index((Oid) lfirsti(index->relids),
+ (int) npages,
+ (Cost) selec,
+ rel->pages,
+ rel->tuples,
+ index->pages,
+ index->tuples,
+ false);
+ best_or_subclause_index(root,
+ rel,
+ subclause,
+ lnext(indices),
+ &subclause_indexid,
+ &subclause_cost,
+ &subclause_selec);
+
+ if (subclause_indexid == 0 || subcost < subclause_cost)
+ {
+ *retIndexid = lfirsti(index->relids);
+ *retCost = subcost;
+ *retSelec = selec;
+ }
+ else
+ {
+ *retIndexid = 0;
+ *retCost = 0.0;
+ *retSelec = 0.0;
+ }
+ }
+ return;
}
diff --git a/src/backend/optimizer/path/predmig.c b/src/backend/optimizer/path/predmig.c
index 241ab4a12d7..c302af3b581 100644
--- a/src/backend/optimizer/path/predmig.c
+++ b/src/backend/optimizer/path/predmig.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* predmig.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/predmig.c,v 1.2 1996/10/23 07:14:41 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/predmig.c,v 1.3 1997/09/07 04:43:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,23 +16,23 @@
** Main Routines to handle Predicate Migration (i.e. correct optimization
** of queries with expensive functions.)
**
-** The reasoning behind some of these algorithms is rather detailed.
-** Have a look at Sequoia Tech Report 92/13 for more info. Also
+** The reasoning behind some of these algorithms is rather detailed.
+** Have a look at Sequoia Tech Report 92/13 for more info. Also
** see Monma and Sidney's paper "Sequencing with Series-Parallel
** Precedence Constraints", in "Mathematics of Operations Research",
** volume 4 (1979), pp. 215-224.
**
-** The main thing that this code does that wasn't handled in xfunc.c is
+** The main thing that this code does that wasn't handled in xfunc.c is
** it considers the possibility that two joins in a stream may not
** be ordered by ascending rank -- in such a scenario, it may be optimal
** to pullup more restrictions than we did via xfunc_try_pullup.
**
-** This code in some sense generalizes xfunc_try_pullup; if you
+** This code in some sense generalizes xfunc_try_pullup; if you
** run postgres -x noprune, you'll turn off xfunc_try_pullup, and this
** code will do everything that xfunc_try_pullup would have, and maybe
-** more. However, this results in no pruning, which may slow down the
+** more. However, this results in no pruning, which may slow down the
** optimizer and/or cause the system to run out of memory.
-** -- JMH, 11/13/92
+** -- JMH, 11/13/92
*/
#include "nodes/pg_list.h"
@@ -49,331 +49,350 @@
#include "optimizer/tlist.h"
#include "lib/qsort.h"
-#define is_clause(node) (get_cinfo(node)) /* a stream node represents a
- clause (not a join) iff it
- has a non-NULL cinfo field */
-
-static void xfunc_predmig(JoinPath pathnode, Stream streamroot,
- Stream laststream, bool *progressp);
-static bool xfunc_series_llel(Stream stream);
-static bool xfunc_llel_chains(Stream root, Stream bottom);
-static Stream xfunc_complete_stream(Stream stream);
-static bool xfunc_prdmig_pullup(Stream origstream, Stream pullme,
- JoinPath joinpath);
-static void xfunc_form_groups(Stream root, Stream bottom);
-static void xfunc_free_stream(Stream root);
-static Stream xfunc_add_clauses(Stream current);
-static void xfunc_setup_group(Stream node, Stream bottom);
-static Stream xfunc_streaminsert(CInfo clauseinfo, Stream current,
- int clausetype);
-static int xfunc_num_relids(Stream node);
+#define is_clause(node) (get_cinfo(node)) /* a stream node
+ * represents a clause
+ * (not a join) iff it has
+ * a non-NULL cinfo field */
+
+static void
+xfunc_predmig(JoinPath pathnode, Stream streamroot,
+ Stream laststream, bool * progressp);
+static bool xfunc_series_llel(Stream stream);
+static bool xfunc_llel_chains(Stream root, Stream bottom);
+static Stream xfunc_complete_stream(Stream stream);
+static bool
+xfunc_prdmig_pullup(Stream origstream, Stream pullme,
+ JoinPath joinpath);
+static void xfunc_form_groups(Stream root, Stream bottom);
+static void xfunc_free_stream(Stream root);
+static Stream xfunc_add_clauses(Stream current);
+static void xfunc_setup_group(Stream node, Stream bottom);
+static Stream
+xfunc_streaminsert(CInfo clauseinfo, Stream current,
+ int clausetype);
+static int xfunc_num_relids(Stream node);
static StreamPtr xfunc_get_downjoin(Stream node);
static StreamPtr xfunc_get_upjoin(Stream node);
-static Stream xfunc_stream_qsort(Stream root, Stream bottom);
-static int xfunc_stream_compare(void *arg1, void *arg2);
-static bool xfunc_check_stream(Stream node);
-static bool xfunc_in_stream(Stream node, Stream stream);
+static Stream xfunc_stream_qsort(Stream root, Stream bottom);
+static int xfunc_stream_compare(void *arg1, void *arg2);
+static bool xfunc_check_stream(Stream node);
+static bool xfunc_in_stream(Stream node, Stream stream);
-/* ----------------- MAIN FUNCTIONS ------------------------ */
+/* ----------------- MAIN FUNCTIONS ------------------------ */
/*
** xfunc_do_predmig
-** wrapper for Predicate Migration. It calls xfunc_predmig until no
+** wrapper for Predicate Migration. It calls xfunc_predmig until no
** more progress is made.
-** return value says if any changes were ever made.
+** return value says if any changes were ever made.
*/
-bool xfunc_do_predmig(Path root)
+bool
+xfunc_do_predmig(Path root)
{
- bool progress, changed = false;
-
- if (is_join(root))
- do
- {
- progress = false;
- Assert(IsA(root,JoinPath));
- xfunc_predmig((JoinPath)root, (Stream)NULL, (Stream)NULL,
- &progress);
- if (changed && progress)
- elog(DEBUG, "Needed to do a second round of predmig!\n");
- if (progress) changed = true;
- } while (progress);
- return(changed);
+ bool progress,
+ changed = false;
+
+ if (is_join(root))
+ do
+ {
+ progress = false;
+ Assert(IsA(root, JoinPath));
+ xfunc_predmig((JoinPath) root, (Stream) NULL, (Stream) NULL,
+ &progress);
+ if (changed && progress)
+ elog(DEBUG, "Needed to do a second round of predmig!\n");
+ if (progress)
+ changed = true;
+ } while (progress);
+ return (changed);
}
/*
** xfunc_predmig
- ** The main routine for Predicate Migration. It traverses a join tree,
- ** and for each root-to-leaf path in the plan tree it constructs a
+ ** The main routine for Predicate Migration. It traverses a join tree,
+ ** and for each root-to-leaf path in the plan tree it constructs a
** "Stream", which it passes to xfunc_series_llel for optimization.
** Destructively modifies the join tree (via predicate pullup).
*/
static void
-xfunc_predmig(JoinPath pathnode, /* root of the join tree */
- Stream streamroot,
- Stream laststream, /* for recursive calls -- these are
- the root of the stream under
- construction, and the lowest node
- created so far */
- bool *progressp)
+xfunc_predmig(JoinPath pathnode,/* root of the join tree */
+ Stream streamroot,
+ Stream laststream,/* for recursive calls -- these are the
+ * root of the stream under construction,
+ * and the lowest node created so far */
+ bool * progressp)
{
- Stream newstream;
-
- /*
- ** traverse the join tree dfs-style, constructing a stream as you go.
- ** When you hit a scan node, pass the stream off to xfunc_series_llel.
- */
-
- /* sanity check */
- if ((!streamroot && laststream) ||
- (streamroot && !laststream))
- elog(WARN, "called xfunc_predmig with bad inputs");
- if (streamroot) Assert(xfunc_check_stream(streamroot));
-
- /* add path node to stream */
- newstream = RMakeStream();
- if (!streamroot)
- streamroot = newstream;
- set_upstream(newstream, (StreamPtr)laststream);
- if (laststream)
- set_downstream(laststream, (StreamPtr)newstream);
- set_downstream(newstream, (StreamPtr)NULL);
- set_pathptr(newstream, (pathPtr)pathnode);
- set_cinfo(newstream, (CInfo)NULL);
- set_clausetype(newstream, XFUNC_UNKNOWN);
-
- /* base case: we're at a leaf, call xfunc_series_llel */
- if (!is_join(pathnode))
+ Stream newstream;
+
+ /*
+ * * traverse the join tree dfs-style, constructing a stream as you
+ * go. * When you hit a scan node, pass the stream off to
+ * xfunc_series_llel.
+ */
+
+ /* sanity check */
+ if ((!streamroot && laststream) ||
+ (streamroot && !laststream))
+ elog(WARN, "called xfunc_predmig with bad inputs");
+ if (streamroot)
+ Assert(xfunc_check_stream(streamroot));
+
+ /* add path node to stream */
+ newstream = RMakeStream();
+ if (!streamroot)
+ streamroot = newstream;
+ set_upstream(newstream, (StreamPtr) laststream);
+ if (laststream)
+ set_downstream(laststream, (StreamPtr) newstream);
+ set_downstream(newstream, (StreamPtr) NULL);
+ set_pathptr(newstream, (pathPtr) pathnode);
+ set_cinfo(newstream, (CInfo) NULL);
+ set_clausetype(newstream, XFUNC_UNKNOWN);
+
+ /* base case: we're at a leaf, call xfunc_series_llel */
+ if (!is_join(pathnode))
{
- /* form a fleshed-out copy of the stream */
- Stream fullstream = xfunc_complete_stream(streamroot);
-
- /* sort it via series-llel */
- if (xfunc_series_llel(fullstream))
- *progressp = true;
-
- /* free up the copy */
- xfunc_free_stream(fullstream);
+ /* form a fleshed-out copy of the stream */
+ Stream fullstream = xfunc_complete_stream(streamroot);
+
+ /* sort it via series-llel */
+ if (xfunc_series_llel(fullstream))
+ *progressp = true;
+
+ /* free up the copy */
+ xfunc_free_stream(fullstream);
}
- else
+ else
{
- /* visit left child */
- xfunc_predmig((JoinPath)get_outerjoinpath(pathnode),
- streamroot, newstream, progressp);
-
- /* visit right child */
- xfunc_predmig((JoinPath)get_innerjoinpath(pathnode),
- streamroot, newstream, progressp);
+ /* visit left child */
+ xfunc_predmig((JoinPath) get_outerjoinpath(pathnode),
+ streamroot, newstream, progressp);
+
+ /* visit right child */
+ xfunc_predmig((JoinPath) get_innerjoinpath(pathnode),
+ streamroot, newstream, progressp);
}
-
- /* remove this node */
- if (get_upstream(newstream))
- set_downstream((Stream)get_upstream(newstream), (StreamPtr)NULL);
- pfree(newstream);
+
+ /* remove this node */
+ if (get_upstream(newstream))
+ set_downstream((Stream) get_upstream(newstream), (StreamPtr) NULL);
+ pfree(newstream);
}
/*
** xfunc_series_llel
** A flavor of Monma and Sidney's Series-Parallel algorithm.
- ** Traverse stream downwards. When you find a node with restrictions on it,
+ ** Traverse stream downwards. When you find a node with restrictions on it,
** call xfunc_llel_chains on the substream from root to that node.
*/
-static bool xfunc_series_llel(Stream stream)
+static bool
+xfunc_series_llel(Stream stream)
{
- Stream temp, next;
- bool progress = false;
-
- for (temp = stream; temp != (Stream)NULL; temp = next)
+ Stream temp,
+ next;
+ bool progress = false;
+
+ for (temp = stream; temp != (Stream) NULL; temp = next)
{
- next = (Stream)xfunc_get_downjoin(temp);
- /*
- ** if there are restrictions/secondary join clauses above this
- ** node, call xfunc_llel_chains
- */
- if (get_upstream(temp) && is_clause((Stream)get_upstream(temp)))
- if (xfunc_llel_chains(stream, temp))
- progress = true;
+ next = (Stream) xfunc_get_downjoin(temp);
+
+ /*
+ * * if there are restrictions/secondary join clauses above this *
+ * node, call xfunc_llel_chains
+ */
+ if (get_upstream(temp) && is_clause((Stream) get_upstream(temp)))
+ if (xfunc_llel_chains(stream, temp))
+ progress = true;
}
- return(progress);
+ return (progress);
}
/*
** xfunc_llel_chains
** A flavor of Monma and Sidney's Parallel Chains algorithm.
** Given a stream which has been well-ordered except for its lowermost
- ** restrictions/2-ary joins, pull up the restrictions/2-arys as appropriate.
+ ** restrictions/2-ary joins, pull up the restrictions/2-arys as appropriate.
** What that means here is to form groups in the chain above the lowest
- ** join node above bottom inclusive, and then take all the restrictions
+ ** join node above bottom inclusive, and then take all the restrictions
** following bottom, and try to pull them up as far as possible.
*/
-static bool xfunc_llel_chains(Stream root, Stream bottom)
+static bool
+xfunc_llel_chains(Stream root, Stream bottom)
{
- bool progress = false;
- Stream origstream;
- Stream tmpstream, pathstream;
- Stream rootcopy = root;
-
- Assert(xfunc_check_stream(root));
-
- /* xfunc_prdmig_pullup will need an unmodified copy of the stream */
- origstream = (Stream)copyObject((Node)root);
-
- /* form groups among ill-ordered nodes */
- xfunc_form_groups(root, bottom);
-
- /* sort chain by rank */
- Assert(xfunc_in_stream(bottom, root));
- rootcopy = xfunc_stream_qsort(root, bottom);
-
- /*
- ** traverse sorted stream -- if any restriction has moved above a join,
- ** we must pull it up in the plan. That is, make plan tree
- ** reflect order of sorted stream.
- */
- for (tmpstream = rootcopy,
- pathstream = (Stream)xfunc_get_downjoin(rootcopy);
- tmpstream != (Stream)NULL && pathstream != (Stream)NULL;
- tmpstream = (Stream)get_downstream(tmpstream))
+ bool progress = false;
+ Stream origstream;
+ Stream tmpstream,
+ pathstream;
+ Stream rootcopy = root;
+
+ Assert(xfunc_check_stream(root));
+
+ /* xfunc_prdmig_pullup will need an unmodified copy of the stream */
+ origstream = (Stream) copyObject((Node) root);
+
+ /* form groups among ill-ordered nodes */
+ xfunc_form_groups(root, bottom);
+
+ /* sort chain by rank */
+ Assert(xfunc_in_stream(bottom, root));
+ rootcopy = xfunc_stream_qsort(root, bottom);
+
+ /*
+ * * traverse sorted stream -- if any restriction has moved above a
+ * join, * we must pull it up in the plan. That is, make plan tree *
+ * reflect order of sorted stream.
+ */
+ for (tmpstream = rootcopy,
+ pathstream = (Stream) xfunc_get_downjoin(rootcopy);
+ tmpstream != (Stream) NULL && pathstream != (Stream) NULL;
+ tmpstream = (Stream) get_downstream(tmpstream))
{
- if (is_clause(tmpstream)
- && get_pathptr(pathstream) != get_pathptr(tmpstream))
+ if (is_clause(tmpstream)
+ && get_pathptr(pathstream) != get_pathptr(tmpstream))
{
- /*
- ** If restriction moved above a Join after sort, we pull it
- ** up in the join plan.
- ** If restriction moved down, we ignore it.
- ** This is because Joey's Sequoia paper proves that
- ** restrictions should never move down. If this
- ** one were moved down, it would violate "semantic correctness",
- ** i.e. it would be lower than the attributes it references.
- */
- Assert(xfunc_num_relids(pathstream)>xfunc_num_relids(tmpstream));
- progress =
- xfunc_prdmig_pullup(origstream, tmpstream,
- (JoinPath)get_pathptr(pathstream));
+
+ /*
+ * * If restriction moved above a Join after sort, we pull it *
+ * up in the join plan. * If restriction moved down, we
+ * ignore it. * This is because Joey's Sequoia paper proves
+ * that * restrictions should never move down. If this * one
+ * were moved down, it would violate "semantic correctness", *
+ * i.e. it would be lower than the attributes it references.
+ */
+ Assert(xfunc_num_relids(pathstream) > xfunc_num_relids(tmpstream));
+ progress =
+ xfunc_prdmig_pullup(origstream, tmpstream,
+ (JoinPath) get_pathptr(pathstream));
}
- if (get_downstream(tmpstream))
- pathstream =
- (Stream)xfunc_get_downjoin((Stream)get_downstream(tmpstream));
+ if (get_downstream(tmpstream))
+ pathstream =
+ (Stream) xfunc_get_downjoin((Stream) get_downstream(tmpstream));
}
-
- /* free up origstream */
- xfunc_free_stream(origstream);
- return(progress);
+
+ /* free up origstream */
+ xfunc_free_stream(origstream);
+ return (progress);
}
/*
** xfunc_complete_stream --
** Given a stream composed of join nodes only, make a copy containing the
- ** join nodes along with the associated restriction nodes.
+ ** join nodes along with the associated restriction nodes.
*/
-static Stream xfunc_complete_stream(Stream stream)
+static Stream
+xfunc_complete_stream(Stream stream)
{
- Stream tmpstream, copystream, curstream = (Stream)NULL;
-
- copystream = (Stream)copyObject((Node)stream);
- Assert(xfunc_check_stream(copystream));
-
- curstream = copystream;
- Assert(!is_clause(curstream));
-
- /* curstream = (Stream)xfunc_get_downjoin(curstream); */
-
- while(curstream != (Stream)NULL)
+ Stream tmpstream,
+ copystream,
+ curstream = (Stream) NULL;
+
+ copystream = (Stream) copyObject((Node) stream);
+ Assert(xfunc_check_stream(copystream));
+
+ curstream = copystream;
+ Assert(!is_clause(curstream));
+
+ /* curstream = (Stream)xfunc_get_downjoin(curstream); */
+
+ while (curstream != (Stream) NULL)
{
- xfunc_add_clauses(curstream);
- curstream = (Stream)xfunc_get_downjoin(curstream);
+ xfunc_add_clauses(curstream);
+ curstream = (Stream) xfunc_get_downjoin(curstream);
}
-
- /* find top of stream and return it */
- for (tmpstream = copystream; get_upstream(tmpstream) != (StreamPtr)NULL;
- tmpstream = (Stream)get_upstream(tmpstream))
- /* no body in for loop */;
-
- return(tmpstream);
+
+ /* find top of stream and return it */
+ for (tmpstream = copystream; get_upstream(tmpstream) != (StreamPtr) NULL;
+ tmpstream = (Stream) get_upstream(tmpstream))
+ /* no body in for loop */ ;
+
+ return (tmpstream);
}
/*
** xfunc_prdmig_pullup
** pullup a clause in a path above joinpath. Since the JoinPath tree
- ** doesn't have upward pointers, it's difficult to deal with. Thus we
+ ** doesn't have upward pointers, it's difficult to deal with. Thus we
** require the original stream, which maintains pointers to all the path
- ** nodes. We use the original stream to find out what joins are
+ ** nodes. We use the original stream to find out what joins are
** above the clause.
*/
-static bool
+static bool
xfunc_prdmig_pullup(Stream origstream, Stream pullme, JoinPath joinpath)
{
- CInfo clauseinfo = get_cinfo(pullme);
- bool progress = false;
- Stream upjoin, orignode, temp;
- int whichchild;
-
- /* find node in origstream that contains clause */
- for (orignode = origstream;
- orignode != (Stream) NULL
- && get_cinfo(orignode) != clauseinfo;
- orignode = (Stream)get_downstream(orignode))
- /* empty body in for loop */ ;
- if (!orignode)
- elog(WARN, "Didn't find matching node in original stream");
-
-
- /* pull up this node as far as it should go */
- for (upjoin = (Stream)xfunc_get_upjoin(orignode);
- upjoin != (Stream)NULL
- && (JoinPath)get_pathptr((Stream)xfunc_get_downjoin(upjoin))
- != joinpath;
- upjoin = (Stream)xfunc_get_upjoin(upjoin))
+ CInfo clauseinfo = get_cinfo(pullme);
+ bool progress = false;
+ Stream upjoin,
+ orignode,
+ temp;
+ int whichchild;
+
+ /* find node in origstream that contains clause */
+ for (orignode = origstream;
+ orignode != (Stream) NULL
+ && get_cinfo(orignode) != clauseinfo;
+ orignode = (Stream) get_downstream(orignode))
+ /* empty body in for loop */ ;
+ if (!orignode)
+ elog(WARN, "Didn't find matching node in original stream");
+
+
+ /* pull up this node as far as it should go */
+ for (upjoin = (Stream) xfunc_get_upjoin(orignode);
+ upjoin != (Stream) NULL
+ && (JoinPath) get_pathptr((Stream) xfunc_get_downjoin(upjoin))
+ != joinpath;
+ upjoin = (Stream) xfunc_get_upjoin(upjoin))
{
-#ifdef DEBUG
- elog(DEBUG, "pulling up in xfunc_predmig_pullup!");
+#ifdef DEBUG
+ elog(DEBUG, "pulling up in xfunc_predmig_pullup!");
#endif
- /* move clause up in path */
- if (get_pathptr((Stream)get_downstream(upjoin))
- == (pathPtr)get_outerjoinpath((JoinPath)get_pathptr(upjoin)))
- whichchild = OUTER;
- else whichchild = INNER;
- clauseinfo = xfunc_pullup((Path)get_pathptr((Stream)get_downstream(upjoin)),
- (JoinPath)get_pathptr(upjoin),
- clauseinfo,
- whichchild,
- get_clausetype(orignode));
- set_pathptr(pullme, get_pathptr(upjoin));
- /* pullme has been moved into locclauseinfo */
- set_clausetype(pullme, XFUNC_LOCPRD);
-
- /*
- ** xfunc_pullup makes new path nodes for children of
- ** get_pathptr(current). We must modify the stream nodes to point
- ** to these path nodes
- */
- if (whichchild == OUTER)
+ /* move clause up in path */
+ if (get_pathptr((Stream) get_downstream(upjoin))
+ == (pathPtr) get_outerjoinpath((JoinPath) get_pathptr(upjoin)))
+ whichchild = OUTER;
+ else
+ whichchild = INNER;
+ clauseinfo = xfunc_pullup((Path) get_pathptr((Stream) get_downstream(upjoin)),
+ (JoinPath) get_pathptr(upjoin),
+ clauseinfo,
+ whichchild,
+ get_clausetype(orignode));
+ set_pathptr(pullme, get_pathptr(upjoin));
+ /* pullme has been moved into locclauseinfo */
+ set_clausetype(pullme, XFUNC_LOCPRD);
+
+ /*
+ * * xfunc_pullup makes new path nodes for children of *
+ * get_pathptr(current). We must modify the stream nodes to point *
+ * to these path nodes
+ */
+ if (whichchild == OUTER)
{
- for(temp = (Stream)get_downstream(upjoin); is_clause(temp);
- temp = (Stream)get_downstream(temp))
+ for (temp = (Stream) get_downstream(upjoin); is_clause(temp);
+ temp = (Stream) get_downstream(temp))
+ set_pathptr
+ (temp, (pathPtr)
+ get_outerjoinpath((JoinPath) get_pathptr(upjoin)));
set_pathptr
- (temp, (pathPtr)
- get_outerjoinpath((JoinPath)get_pathptr(upjoin)));
- set_pathptr
- (temp,
- (pathPtr)get_outerjoinpath((JoinPath)get_pathptr(upjoin)));
+ (temp,
+ (pathPtr) get_outerjoinpath((JoinPath) get_pathptr(upjoin)));
}
- else
+ else
{
- for(temp = (Stream)get_downstream(upjoin); is_clause(temp);
- temp = (Stream)get_downstream(temp))
+ for (temp = (Stream) get_downstream(upjoin); is_clause(temp);
+ temp = (Stream) get_downstream(temp))
+ set_pathptr
+ (temp, (pathPtr)
+ get_innerjoinpath((JoinPath) get_pathptr(upjoin)));
set_pathptr
- (temp, (pathPtr)
- get_innerjoinpath((JoinPath)get_pathptr(upjoin)));
- set_pathptr
- (temp, (pathPtr)
- get_innerjoinpath((JoinPath)get_pathptr(upjoin)));
+ (temp, (pathPtr)
+ get_innerjoinpath((JoinPath) get_pathptr(upjoin)));
}
- progress = true;
+ progress = true;
}
- if (!progress)
- elog(DEBUG, "didn't succeed in pulling up in xfunc_prdmig_pullup");
- return(progress);
+ if (!progress)
+ elog(DEBUG, "didn't succeed in pulling up in xfunc_prdmig_pullup");
+ return (progress);
}
/*
@@ -386,143 +405,151 @@ xfunc_prdmig_pullup(Stream origstream, Stream pullme, JoinPath joinpath)
** equal to the cost of the first plus the selectivity of the first times the
** cost of the second. We define each node to be in a group by itself,
** and then repeatedly find adjacent groups which are ordered by descending
- ** rank, and make larger groups. You know that two adjacent nodes are in a
- ** group together if the lower has groupup set to true. They will both have
+ ** rank, and make larger groups. You know that two adjacent nodes are in a
+ ** group together if the lower has groupup set to true. They will both have
** the same groupcost and groupsel (since they're in the same group!)
*/
-static void xfunc_form_groups(Query* queryInfo, Stream root, Stream bottom)
+static void
+xfunc_form_groups(Query * queryInfo, Stream root, Stream bottom)
{
- Stream temp, parent;
- int lowest = xfunc_num_relids((Stream)xfunc_get_upjoin(bottom));
- bool progress;
- LispValue primjoin;
- int whichchild;
-
- if (!lowest) return; /* no joins in stream, so no groups */
-
- /* initialize groups to be single nodes */
- for (temp = root;
- temp != (Stream)NULL && temp != bottom;
- temp = (Stream)get_downstream(temp))
+ Stream temp,
+ parent;
+ int lowest = xfunc_num_relids((Stream) xfunc_get_upjoin(bottom));
+ bool progress;
+ LispValue primjoin;
+ int whichchild;
+
+ if (!lowest)
+ return; /* no joins in stream, so no groups */
+
+ /* initialize groups to be single nodes */
+ for (temp = root;
+ temp != (Stream) NULL && temp != bottom;
+ temp = (Stream) get_downstream(temp))
{
- /* if a Join node */
- if (!is_clause(temp))
+ /* if a Join node */
+ if (!is_clause(temp))
{
- if (get_pathptr((Stream)get_downstream(temp))
- == (pathPtr)get_outerjoinpath((JoinPath)get_pathptr(temp)))
- whichchild = OUTER;
- else whichchild = INNER;
- set_groupcost(temp,
- xfunc_join_expense((JoinPath)get_pathptr(temp),
- whichchild));
- if (primjoin = xfunc_primary_join((JoinPath)get_pathptr(temp)))
+ if (get_pathptr((Stream) get_downstream(temp))
+ == (pathPtr) get_outerjoinpath((JoinPath) get_pathptr(temp)))
+ whichchild = OUTER;
+ else
+ whichchild = INNER;
+ set_groupcost(temp,
+ xfunc_join_expense((JoinPath) get_pathptr(temp),
+ whichchild));
+ if (primjoin = xfunc_primary_join((JoinPath) get_pathptr(temp)))
{
- set_groupsel(temp,
- compute_clause_selec(queryInfo,
- primjoin, NIL));
+ set_groupsel(temp,
+ compute_clause_selec(queryInfo,
+ primjoin, NIL));
}
- else
+ else
{
- set_groupsel(temp,1.0);
+ set_groupsel(temp, 1.0);
}
}
- else /* a restriction, or 2-ary join pred */
+ else
+/* a restriction, or 2-ary join pred */
{
- set_groupcost(temp,
- xfunc_expense(queryInfo,
- get_clause(get_cinfo(temp))));
- set_groupsel(temp,
- compute_clause_selec(queryInfo,
- get_clause(get_cinfo(temp)),
- NIL));
+ set_groupcost(temp,
+ xfunc_expense(queryInfo,
+ get_clause(get_cinfo(temp))));
+ set_groupsel(temp,
+ compute_clause_selec(queryInfo,
+ get_clause(get_cinfo(temp)),
+ NIL));
}
- set_groupup(temp,false);
+ set_groupup(temp, false);
}
-
- /* make passes upwards, forming groups */
- do
+
+ /* make passes upwards, forming groups */
+ do
{
- progress = false;
- for (temp = (Stream)get_upstream(bottom);
- temp != (Stream)NULL;
- temp = (Stream)get_upstream(temp))
+ progress = false;
+ for (temp = (Stream) get_upstream(bottom);
+ temp != (Stream) NULL;
+ temp = (Stream) get_upstream(temp))
{
- /* check for grouping with node upstream */
- if (!get_groupup(temp) && /* not already grouped */
- (parent = (Stream)get_upstream(temp)) != (Stream)NULL &&
+ /* check for grouping with node upstream */
+ if (!get_groupup(temp) && /* not already grouped */
+ (parent = (Stream) get_upstream(temp)) != (Stream) NULL &&
/* temp is a join or temp is the top of a group */
- (is_join((Path)get_pathptr(temp)) ||
- get_downstream(temp) &&
- get_groupup((Stream)get_downstream(temp))) &&
- get_grouprank(parent) < get_grouprank(temp))
+ (is_join((Path) get_pathptr(temp)) ||
+ get_downstream(temp) &&
+ get_groupup((Stream) get_downstream(temp))) &&
+ get_grouprank(parent) < get_grouprank(temp))
{
- progress = true; /* we formed a new group */
- set_groupup(temp,true);
- set_groupcost(temp,
- get_groupcost(temp) +
- get_groupsel(temp) * get_groupcost(parent));
- set_groupsel(temp,get_groupsel(temp) * get_groupsel(parent));
-
- /* fix costs and sels of all members of group */
- xfunc_setup_group(temp, bottom);
+ progress = true;/* we formed a new group */
+ set_groupup(temp, true);
+ set_groupcost(temp,
+ get_groupcost(temp) +
+ get_groupsel(temp) * get_groupcost(parent));
+ set_groupsel(temp, get_groupsel(temp) * get_groupsel(parent));
+
+ /* fix costs and sels of all members of group */
+ xfunc_setup_group(temp, bottom);
}
}
- } while(progress);
+ } while (progress);
}
-/* ------------------- UTILITY FUNCTIONS ------------------------- */
+/* ------------------- UTILITY FUNCTIONS ------------------------- */
/*
** xfunc_free_stream --
** walk down a stream and pfree it
*/
-static void xfunc_free_stream(Stream root)
+static void
+xfunc_free_stream(Stream root)
{
- Stream cur, next;
-
- Assert(xfunc_check_stream(root));
-
- if (root != (Stream)NULL)
- for (cur = root; cur != (Stream)NULL; cur = next)
- {
- next = (Stream)get_downstream(cur);
- pfree(cur);
- }
+ Stream cur,
+ next;
+
+ Assert(xfunc_check_stream(root));
+
+ if (root != (Stream) NULL)
+ for (cur = root; cur != (Stream) NULL; cur = next)
+ {
+ next = (Stream) get_downstream(cur);
+ pfree(cur);
+ }
}
/*
** xfunc_add<_clauses
- ** find any clauses above current, and insert them into stream as
+ ** find any clauses above current, and insert them into stream as
** appropriate. Return uppermost clause inserted, or current if none.
*/
-static Stream xfunc_add_clauses(Stream current)
+static Stream
+xfunc_add_clauses(Stream current)
{
- Stream topnode = current;
- LispValue temp;
- LispValue primjoin;
-
- /* first add in the local clauses */
- foreach(temp, get_locclauseinfo((Path)get_pathptr(current)))
+ Stream topnode = current;
+ LispValue temp;
+ LispValue primjoin;
+
+ /* first add in the local clauses */
+ foreach(temp, get_locclauseinfo((Path) get_pathptr(current)))
{
- topnode =
- xfunc_streaminsert((CInfo)lfirst(temp), topnode,
- XFUNC_LOCPRD);
+ topnode =
+ xfunc_streaminsert((CInfo) lfirst(temp), topnode,
+ XFUNC_LOCPRD);
}
-
- /* and add in the join clauses */
- if (IsA(get_pathptr(current),JoinPath))
+
+ /* and add in the join clauses */
+ if (IsA(get_pathptr(current), JoinPath))
{
- primjoin = xfunc_primary_join((JoinPath)get_pathptr(current));
- foreach(temp, get_pathclauseinfo((JoinPath)get_pathptr(current)))
+ primjoin = xfunc_primary_join((JoinPath) get_pathptr(current));
+ foreach(temp, get_pathclauseinfo((JoinPath) get_pathptr(current)))
{
- if (!equal(get_clause((CInfo)lfirst(temp)), primjoin))
- topnode =
- xfunc_streaminsert((CInfo)lfirst(temp), topnode,
- XFUNC_JOINPRD);
+ if (!equal(get_clause((CInfo) lfirst(temp)), primjoin))
+ topnode =
+ xfunc_streaminsert((CInfo) lfirst(temp), topnode,
+ XFUNC_JOINPRD);
}
}
- return(topnode);
+ return (topnode);
}
@@ -531,33 +558,36 @@ static Stream xfunc_add_clauses(Stream current)
** find all elements of stream that are grouped with node and are above
** bottom, and set their groupcost and groupsel to be the same as node's.
*/
-static void xfunc_setup_group(Stream node, Stream bottom)
+static void
+xfunc_setup_group(Stream node, Stream bottom)
{
- Stream temp;
-
- if (node != bottom)
- /* traverse downwards */
- for (temp = (Stream)get_downstream(node);
- temp != (Stream)NULL && temp != bottom;
- temp = (Stream)get_downstream(temp))
- {
- if (!get_groupup(temp)) break;
- else
- {
- set_groupcost(temp, get_groupcost(node));
- set_groupsel(temp, get_groupsel(node));
- }
- }
-
- /* traverse upwards */
- for (temp = (Stream)get_upstream(node); temp != (Stream)NULL;
- temp = (Stream)get_upstream(temp))
+ Stream temp;
+
+ if (node != bottom)
+ /* traverse downwards */
+ for (temp = (Stream) get_downstream(node);
+ temp != (Stream) NULL && temp != bottom;
+ temp = (Stream) get_downstream(temp))
+ {
+ if (!get_groupup(temp))
+ break;
+ else
+ {
+ set_groupcost(temp, get_groupcost(node));
+ set_groupsel(temp, get_groupsel(node));
+ }
+ }
+
+ /* traverse upwards */
+ for (temp = (Stream) get_upstream(node); temp != (Stream) NULL;
+ temp = (Stream) get_upstream(temp))
{
- if (!get_groupup((Stream)get_downstream(temp))) break;
- else
+ if (!get_groupup((Stream) get_downstream(temp)))
+ break;
+ else
{
- set_groupcost(temp, get_groupcost(node));
- set_groupsel(temp, get_groupsel(node));
+ set_groupcost(temp, get_groupcost(node));
+ set_groupsel(temp, get_groupsel(node));
}
}
}
@@ -568,70 +598,75 @@ static void xfunc_setup_group(Stream node, Stream bottom)
** Make a new Stream node to hold clause, and insert it above current.
** Return new node.
*/
-static Stream
+static Stream
xfunc_streaminsert(CInfo clauseinfo,
- Stream current,
- int clausetype) /* XFUNC_LOCPRD or XFUNC_JOINPRD */
+ Stream current,
+ int clausetype) /* XFUNC_LOCPRD or XFUNC_JOINPRD */
{
- Stream newstream = RMakeStream();
- set_upstream(newstream, get_upstream(current));
- if (get_upstream(current))
- set_downstream((Stream)(get_upstream(current)), (StreamPtr)newstream);
- set_upstream(current, (StreamPtr)newstream);
- set_downstream(newstream, (StreamPtr)current);
- set_pathptr(newstream, get_pathptr(current));
- set_cinfo(newstream, clauseinfo);
- set_clausetype(newstream, clausetype);
- return(newstream);
+ Stream newstream = RMakeStream();
+
+ set_upstream(newstream, get_upstream(current));
+ if (get_upstream(current))
+ set_downstream((Stream) (get_upstream(current)), (StreamPtr) newstream);
+ set_upstream(current, (StreamPtr) newstream);
+ set_downstream(newstream, (StreamPtr) current);
+ set_pathptr(newstream, get_pathptr(current));
+ set_cinfo(newstream, clauseinfo);
+ set_clausetype(newstream, clausetype);
+ return (newstream);
}
/*
** Given a Stream node, find the number of relids referenced in the pathnode
** associated with the stream node. The number of relids gives a unique
- ** ordering on the joins in a stream, which we use to compare the height of
+ ** ordering on the joins in a stream, which we use to compare the height of
** join nodes.
*/
-static int xfunc_num_relids(Stream node)
+static int
+xfunc_num_relids(Stream node)
{
- if (!node || !IsA(get_pathptr(node),JoinPath))
- return(0);
- else return(length
- (get_relids(get_parent((JoinPath)get_pathptr(node)))));
+ if (!node || !IsA(get_pathptr(node), JoinPath))
+ return (0);
+ else
+ return (length
+ (get_relids(get_parent((JoinPath) get_pathptr(node)))));
}
-/*
+/*
** xfunc_get_downjoin --
** Given a stream node, find the next lowest node which points to a
** join predicate or a scan node.
*/
-static StreamPtr xfunc_get_downjoin(Stream node)
+static StreamPtr
+xfunc_get_downjoin(Stream node)
{
- Stream temp;
-
- if (!is_clause(node)) /* if this is a join */
- node = (Stream)get_downstream(node);
- for (temp = node; temp && is_clause(temp);
- temp = (Stream)get_downstream(temp))
- /* empty body in for loop */ ;
-
- return((StreamPtr)temp);
+ Stream temp;
+
+ if (!is_clause(node)) /* if this is a join */
+ node = (Stream) get_downstream(node);
+ for (temp = node; temp && is_clause(temp);
+ temp = (Stream) get_downstream(temp))
+ /* empty body in for loop */ ;
+
+ return ((StreamPtr) temp);
}
/*
** xfunc_get_upjoin --
** same as above, but upwards.
*/
-static StreamPtr xfunc_get_upjoin(Stream node)
+static StreamPtr
+xfunc_get_upjoin(Stream node)
{
- Stream temp;
-
- if (!is_clause(node)) /* if this is a join */
- node = (Stream)get_upstream(node);
- for (temp = node; temp && is_clause(temp);
- temp = (Stream)get_upstream(temp))
- /* empty body in for loop */ ;
-
- return((StreamPtr)temp);
+ Stream temp;
+
+ if (!is_clause(node)) /* if this is a join */
+ node = (Stream) get_upstream(node);
+ for (temp = node; temp && is_clause(temp);
+ temp = (Stream) get_upstream(temp))
+ /* empty body in for loop */ ;
+
+ return ((StreamPtr) temp);
}
/*
@@ -639,43 +674,46 @@ static StreamPtr xfunc_get_upjoin(Stream node)
** Given a stream, sort by group rank the elements in the stream from the
** node "bottom" up. DESTRUCTIVELY MODIFIES STREAM! Returns new root.
*/
-static Stream xfunc_stream_qsort(Stream root, Stream bottom)
+static Stream
+xfunc_stream_qsort(Stream root, Stream bottom)
{
- int i;
- size_t num;
- Stream *nodearray, output;
- Stream tmp;
-
- /* find size of list */
- for (num = 0, tmp = root; tmp != bottom;
- tmp = (Stream)get_downstream(tmp))
- num ++;
- if (num <= 1) return (root);
-
- /* copy elements of the list into an array */
- nodearray = (Stream *) palloc(num * sizeof(Stream));
-
- for (tmp = root, i = 0; tmp != bottom;
- tmp = (Stream)get_downstream(tmp), i++)
- nodearray[i] = tmp;
-
- /* sort the array */
- pg_qsort(nodearray, num, sizeof(LispValue), xfunc_stream_compare);
-
- /* paste together the array elements */
- output = nodearray[num - 1];
- set_upstream(output, (StreamPtr)NULL);
- for (i = num - 2; i >= 0; i--)
+ int i;
+ size_t num;
+ Stream *nodearray,
+ output;
+ Stream tmp;
+
+ /* find size of list */
+ for (num = 0, tmp = root; tmp != bottom;
+ tmp = (Stream) get_downstream(tmp))
+ num++;
+ if (num <= 1)
+ return (root);
+
+ /* copy elements of the list into an array */
+ nodearray = (Stream *) palloc(num * sizeof(Stream));
+
+ for (tmp = root, i = 0; tmp != bottom;
+ tmp = (Stream) get_downstream(tmp), i++)
+ nodearray[i] = tmp;
+
+ /* sort the array */
+ pg_qsort(nodearray, num, sizeof(LispValue), xfunc_stream_compare);
+
+ /* paste together the array elements */
+ output = nodearray[num - 1];
+ set_upstream(output, (StreamPtr) NULL);
+ for (i = num - 2; i >= 0; i--)
{
- set_downstream(nodearray[i+1], (StreamPtr)nodearray[i]);
- set_upstream(nodearray[i], (StreamPtr)nodearray[i+1]);
+ set_downstream(nodearray[i + 1], (StreamPtr) nodearray[i]);
+ set_upstream(nodearray[i], (StreamPtr) nodearray[i + 1]);
}
- set_downstream(nodearray[0], (StreamPtr)bottom);
- if (bottom)
- set_upstream(bottom, (StreamPtr)nodearray[0]);
-
- Assert(xfunc_check_stream(output));
- return(output);
+ set_downstream(nodearray[0], (StreamPtr) bottom);
+ if (bottom)
+ set_upstream(bottom, (StreamPtr) nodearray[0]);
+
+ Assert(xfunc_check_stream(output));
+ return (output);
}
/*
@@ -684,90 +722,102 @@ static Stream xfunc_stream_qsort(Stream root, Stream bottom)
** Compare nodes by group rank. If group ranks are equal, ensure that
** join nodes appear in same order as in plan tree.
*/
-static int xfunc_stream_compare(void *arg1, void *arg2)
+static int
+xfunc_stream_compare(void *arg1, void *arg2)
{
- Stream stream1 = *(Stream *) arg1;
- Stream stream2 = *(Stream *) arg2;
- Cost rank1, rank2;
-
- rank1 = get_grouprank(stream1);
- rank2 = get_grouprank(stream2);
-
- if (rank1 > rank2) return(1);
- else if (rank1 < rank2) return(-1);
- else
+ Stream stream1 = *(Stream *) arg1;
+ Stream stream2 = *(Stream *) arg2;
+ Cost rank1,
+ rank2;
+
+ rank1 = get_grouprank(stream1);
+ rank2 = get_grouprank(stream2);
+
+ if (rank1 > rank2)
+ return (1);
+ else if (rank1 < rank2)
+ return (-1);
+ else
{
- if (is_clause(stream1) && is_clause(stream2))
- return(0); /* doesn't matter what order if both are restrictions */
- else if (!is_clause(stream1) && !is_clause(stream2))
+ if (is_clause(stream1) && is_clause(stream2))
+ return (0); /* doesn't matter what order if both are
+ * restrictions */
+ else if (!is_clause(stream1) && !is_clause(stream2))
{
- if (xfunc_num_relids(stream1) < xfunc_num_relids(stream2))
- return(-1);
- else return(1);
+ if (xfunc_num_relids(stream1) < xfunc_num_relids(stream2))
+ return (-1);
+ else
+ return (1);
}
- else if (is_clause(stream1) && !is_clause(stream2))
+ else if (is_clause(stream1) && !is_clause(stream2))
{
- if (xfunc_num_relids(stream1) == xfunc_num_relids(stream2))
- /* stream1 is a restriction over stream2 */
- return(1);
- else return(-1);
+ if (xfunc_num_relids(stream1) == xfunc_num_relids(stream2))
+ /* stream1 is a restriction over stream2 */
+ return (1);
+ else
+ return (-1);
}
- else if (!is_clause(stream1) && is_clause(stream2))
+ else if (!is_clause(stream1) && is_clause(stream2))
{
- /* stream2 is a restriction over stream1: never push down */
- return(-1);
+ /* stream2 is a restriction over stream1: never push down */
+ return (-1);
}
}
}
-/* ------------------ DEBUGGING ROUTINES ---------------------------- */
+/* ------------------ DEBUGGING ROUTINES ---------------------------- */
/*
** Make sure all pointers in stream make sense. Make sure no joins are
** out of order.
*/
-static bool xfunc_check_stream(Stream node)
+static bool
+xfunc_check_stream(Stream node)
{
- Stream temp;
- int numrelids, tmp;
-
- /* set numrelids higher than max */
- if (!is_clause(node))
- numrelids = xfunc_num_relids(node) + 1;
- else if (xfunc_get_downjoin(node))
- numrelids = xfunc_num_relids((Stream)xfunc_get_downjoin(node)) + 1;
- else numrelids = 1;
-
- for (temp = node; get_downstream(temp); temp = (Stream)get_downstream(temp))
+ Stream temp;
+ int numrelids,
+ tmp;
+
+ /* set numrelids higher than max */
+ if (!is_clause(node))
+ numrelids = xfunc_num_relids(node) + 1;
+ else if (xfunc_get_downjoin(node))
+ numrelids = xfunc_num_relids((Stream) xfunc_get_downjoin(node)) + 1;
+ else
+ numrelids = 1;
+
+ for (temp = node; get_downstream(temp); temp = (Stream) get_downstream(temp))
{
- if ((Stream)get_upstream((Stream)get_downstream(temp)) != temp)
+ if ((Stream) get_upstream((Stream) get_downstream(temp)) != temp)
{
- elog(WARN, "bad pointers in stream");
- return(false);
+ elog(WARN, "bad pointers in stream");
+ return (false);
}
- if (!is_clause(temp))
+ if (!is_clause(temp))
{
- if ((tmp = xfunc_num_relids(temp)) >= numrelids)
+ if ((tmp = xfunc_num_relids(temp)) >= numrelids)
{
- elog(WARN, "Joins got reordered!");
- return(false);
+ elog(WARN, "Joins got reordered!");
+ return (false);
}
- numrelids = tmp;
+ numrelids = tmp;
}
}
-
- return(true);
+
+ return (true);
}
/*
** xfunc_in_stream
** check if node is in stream
*/
-static bool xfunc_in_stream(Stream node, Stream stream)
+static bool
+xfunc_in_stream(Stream node, Stream stream)
{
- Stream temp;
-
- for (temp = stream; temp; temp = (Stream)get_downstream(temp))
- if (temp == node) return(1);
- return(0);
+ Stream temp;
+
+ for (temp = stream; temp; temp = (Stream) get_downstream(temp))
+ if (temp == node)
+ return (1);
+ return (0);
}
diff --git a/src/backend/optimizer/path/prune.c b/src/backend/optimizer/path/prune.c
index 0b154e108fa..4f3ae2d15de 100644
--- a/src/backend/optimizer/path/prune.c
+++ b/src/backend/optimizer/path/prune.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* prune.c--
- * Routines to prune redundant paths and relations
+ * Routines to prune redundant paths and relations
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.3 1997/06/10 07:55:47 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.4 1997/09/07 04:43:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,181 +24,199 @@
#include "utils/elog.h"
-static List *prune_joinrel(Rel *rel, List *other_rels);
+static List *prune_joinrel(Rel * rel, List * other_rels);
-/*
+/*
* prune-joinrels--
- * Removes any redundant relation entries from a list of rel nodes
- * 'rel-list'.
- *
- * Returns the resulting list.
- *
+ * Removes any redundant relation entries from a list of rel nodes
+ * 'rel-list'.
+ *
+ * Returns the resulting list.
+ *
*/
-List *prune_joinrels(List *rel_list)
+List *
+prune_joinrels(List * rel_list)
{
- List *temp_list = NIL;
-
- if (rel_list != NIL) {
- temp_list = lcons(lfirst(rel_list),
- prune_joinrels(prune_joinrel((Rel*)lfirst(rel_list),
- lnext(rel_list))));
- }
- return(temp_list);
+ List *temp_list = NIL;
+
+ if (rel_list != NIL)
+ {
+ temp_list = lcons(lfirst(rel_list),
+ prune_joinrels(prune_joinrel((Rel *) lfirst(rel_list),
+ lnext(rel_list))));
+ }
+ return (temp_list);
}
-/*
+/*
* prune-joinrel--
- * Prunes those relations from 'other-rels' that are redundant with
- * 'rel'. A relation is redundant if it is built up of the same
- * relations as 'rel'. Paths for the redundant relation are merged into
- * the pathlist of 'rel'.
- *
+ * Prunes those relations from 'other-rels' that are redundant with
+ * 'rel'. A relation is redundant if it is built up of the same
+ * relations as 'rel'. Paths for the redundant relation are merged into
+ * the pathlist of 'rel'.
+ *
* Returns a list of non-redundant relations, and sets the pathlist field
* of 'rel' appropriately.
- *
+ *
*/
-static List *
-prune_joinrel(Rel *rel, List *other_rels)
+static List *
+prune_joinrel(Rel * rel, List * other_rels)
{
- List *i = NIL;
- List *t_list = NIL;
- List *temp_node = NIL;
- Rel *other_rel = (Rel *)NULL;
-
- foreach(i, other_rels) {
- other_rel = (Rel*)lfirst(i);
- if(same(rel->relids, other_rel->relids)) {
- rel->pathlist = add_pathlist(rel,
- rel->pathlist,
- other_rel->pathlist);
- t_list = nconc(t_list, NIL); /* XXX is this right ? */
- } else {
- temp_node = lcons(other_rel, NIL);
- t_list = nconc(t_list,temp_node);
- }
- }
- return(t_list);
+ List *i = NIL;
+ List *t_list = NIL;
+ List *temp_node = NIL;
+ Rel *other_rel = (Rel *) NULL;
+
+ foreach(i, other_rels)
+ {
+ other_rel = (Rel *) lfirst(i);
+ if (same(rel->relids, other_rel->relids))
+ {
+ rel->pathlist = add_pathlist(rel,
+ rel->pathlist,
+ other_rel->pathlist);
+ t_list = nconc(t_list, NIL); /* XXX is this right ? */
+ }
+ else
+ {
+ temp_node = lcons(other_rel, NIL);
+ t_list = nconc(t_list, temp_node);
+ }
+ }
+ return (t_list);
}
-/*
+/*
* prune-rel-paths--
- * For each relation entry in 'rel-list' (which corresponds to a join
- * relation), set pointers to the unordered path and cheapest paths
- * (if the unordered path isn't the cheapest, it is pruned), and
- * reset the relation's size field to reflect the join.
- *
+ * For each relation entry in 'rel-list' (which corresponds to a join
+ * relation), set pointers to the unordered path and cheapest paths
+ * (if the unordered path isn't the cheapest, it is pruned), and
+ * reset the relation's size field to reflect the join.
+ *
* Returns nothing of interest.
- *
+ *
*/
void
-prune_rel_paths(List *rel_list)
+prune_rel_paths(List * rel_list)
{
- List *x = NIL;
- List *y = NIL;
- Path *path = NULL;
- Rel *rel = (Rel*)NULL;
- JoinPath *cheapest = (JoinPath*)NULL;
-
- foreach(x, rel_list) {
- rel = (Rel*)lfirst(x);
- rel->size = 0;
- foreach(y, rel->pathlist) {
- path = (Path*)lfirst(y);
-
- if(!path->p_ordering.ord.sortop) {
- break;
- }
+ List *x = NIL;
+ List *y = NIL;
+ Path *path = NULL;
+ Rel *rel = (Rel *) NULL;
+ JoinPath *cheapest = (JoinPath *) NULL;
+
+ foreach(x, rel_list)
+ {
+ rel = (Rel *) lfirst(x);
+ rel->size = 0;
+ foreach(y, rel->pathlist)
+ {
+ path = (Path *) lfirst(y);
+
+ if (!path->p_ordering.ord.sortop)
+ {
+ break;
+ }
+ }
+ cheapest = (JoinPath *) prune_rel_path(rel, path);
+ if (IsA_JoinPath(cheapest))
+ {
+ rel->size = compute_joinrel_size(cheapest);
+ }
+ else
+ elog(WARN, "non JoinPath called");
}
- cheapest = (JoinPath*)prune_rel_path(rel, path);
- if (IsA_JoinPath(cheapest))
- {
- rel->size = compute_joinrel_size(cheapest);
- }
- else
- elog(WARN, "non JoinPath called");
- }
}
-/*
+/*
* prune-rel-path--
- * Compares the unordered path for a relation with the cheapest path. If
- * the unordered path is not cheapest, it is pruned.
- *
- * Resets the pointers in 'rel' for unordered and cheapest paths.
- *
+ * Compares the unordered path for a relation with the cheapest path. If
+ * the unordered path is not cheapest, it is pruned.
+ *
+ * Resets the pointers in 'rel' for unordered and cheapest paths.
+ *
* Returns the cheapest path.
- *
+ *
*/
-Path *
-prune_rel_path(Rel *rel, Path *unorderedpath)
+Path *
+prune_rel_path(Rel * rel, Path * unorderedpath)
{
- Path *cheapest = set_cheapest(rel, rel->pathlist);
-
- /* don't prune if not pruneable -- JMH, 11/23/92 */
- if(unorderedpath != cheapest
- && rel->pruneable) {
-
- rel->unorderedpath = (Path *)NULL;
- rel->pathlist = lremove(unorderedpath, rel->pathlist);
- } else {
- rel->unorderedpath = (Path *)unorderedpath;
- }
-
- return(cheapest);
+ Path *cheapest = set_cheapest(rel, rel->pathlist);
+
+ /* don't prune if not pruneable -- JMH, 11/23/92 */
+ if (unorderedpath != cheapest
+ && rel->pruneable)
+ {
+
+ rel->unorderedpath = (Path *) NULL;
+ rel->pathlist = lremove(unorderedpath, rel->pathlist);
+ }
+ else
+ {
+ rel->unorderedpath = (Path *) unorderedpath;
+ }
+
+ return (cheapest);
}
/*
* merge-joinrels--
- * Given two lists of rel nodes that are already
- * pruned, merge them into one pruned rel node list
+ * Given two lists of rel nodes that are already
+ * pruned, merge them into one pruned rel node list
*
* 'rel-list1' and
* 'rel-list2' are the rel node lists
*
* Returns one pruned rel node list
*/
-List *
-merge_joinrels(List *rel_list1, List *rel_list2)
+List *
+merge_joinrels(List * rel_list1, List * rel_list2)
{
- List *xrel = NIL;
-
- foreach(xrel,rel_list1) {
- Rel *rel = (Rel*)lfirst(xrel);
- rel_list2 = prune_joinrel(rel,rel_list2);
- }
- return(append(rel_list1, rel_list2));
+ List *xrel = NIL;
+
+ foreach(xrel, rel_list1)
+ {
+ Rel *rel = (Rel *) lfirst(xrel);
+
+ rel_list2 = prune_joinrel(rel, rel_list2);
+ }
+ return (append(rel_list1, rel_list2));
}
/*
* prune_oldrels--
- * If all the joininfo's in a rel node are inactive,
- * that means that this node has been joined into
- * other nodes in all possible ways, therefore
- * this node can be discarded. If not, it will cause
- * extra complexity of the optimizer.
+ * If all the joininfo's in a rel node are inactive,
+ * that means that this node has been joined into
+ * other nodes in all possible ways, therefore
+ * this node can be discarded. If not, it will cause
+ * extra complexity of the optimizer.
*
* old_rels is a list of rel nodes
- *
+ *
* Returns a new list of rel nodes
*/
-List *prune_oldrels(List *old_rels)
+List *
+prune_oldrels(List * old_rels)
{
- Rel *rel;
- List *joininfo_list, *xjoininfo;
-
- if(old_rels == NIL)
- return(NIL);
-
- rel = (Rel*)lfirst(old_rels);
- joininfo_list = rel->joininfo;
- if(joininfo_list == NIL)
- return (lcons(rel, prune_oldrels(lnext(old_rels))));
-
- foreach(xjoininfo, joininfo_list) {
- JInfo *joininfo = (JInfo*)lfirst(xjoininfo);
- if(!joininfo->inactive)
- return (lcons(rel, prune_oldrels(lnext(old_rels))));
- }
- return(prune_oldrels(lnext(old_rels)));
+ Rel *rel;
+ List *joininfo_list,
+ *xjoininfo;
+
+ if (old_rels == NIL)
+ return (NIL);
+
+ rel = (Rel *) lfirst(old_rels);
+ joininfo_list = rel->joininfo;
+ if (joininfo_list == NIL)
+ return (lcons(rel, prune_oldrels(lnext(old_rels))));
+
+ foreach(xjoininfo, joininfo_list)
+ {
+ JInfo *joininfo = (JInfo *) lfirst(xjoininfo);
+
+ if (!joininfo->inactive)
+ return (lcons(rel, prune_oldrels(lnext(old_rels))));
+ }
+ return (prune_oldrels(lnext(old_rels)));
}
diff --git a/src/backend/optimizer/path/xfunc.c b/src/backend/optimizer/path/xfunc.c
index 3e3ee650f94..36135d4a823 100644
--- a/src/backend/optimizer/path/xfunc.c
+++ b/src/backend/optimizer/path/xfunc.c
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* xfunc.c--
- * Utility routines to handle expensive function optimization.
- * Includes xfunc_trypullup(), which attempts early pullup of predicates
- * to allow for maximal pruning.
- *
+ * Utility routines to handle expensive function optimization.
+ * Includes xfunc_trypullup(), which attempts early pullup of predicates
+ * to allow for maximal pruning.
+ *
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/xfunc.c,v 1.3 1997/02/14 04:15:39 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/xfunc.c,v 1.4 1997/09/07 04:43:50 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <math.h> /* for MAXFLOAT on most systems */
+#include <math.h> /* for MAXFLOAT on most systems */
-#include <values.h> /* for MAXFLOAT on SunOS */
+#include <values.h> /* for MAXFLOAT on SunOS */
#include <string.h>
#include "postgres.h"
@@ -40,82 +40,96 @@
#include "lib/lispsort.h"
#include "access/heapam.h"
#include "tcop/dest.h"
-#include "storage/buf_internals.h" /* for NBuffers */
-#include "optimizer/tlist.h" /* for get_expr */
+#include "storage/buf_internals.h" /* for NBuffers */
+#include "optimizer/tlist.h" /* for get_expr */
#define ever ; 1 ;
/* local funcs */
-static int xfunc_card_unreferenced(Query *queryInfo,
- Expr *clause, Relid referenced); */
+static int
+xfunc_card_unreferenced(Query * queryInfo,
+ Expr * clause, Relid referenced);
+
+*/
/*
** xfunc_trypullup --
-** Preliminary pullup of predicates, to allow for maximal pruning.
+** Preliminary pullup of predicates, to allow for maximal pruning.
** Given a relation, check each of its paths and see if you can
** pullup clauses from its inner and outer.
*/
-void xfunc_trypullup(Rel rel)
+void
+xfunc_trypullup(Rel rel)
{
- LispValue y; /* list ptr */
- CInfo maxcinfo; /* The CInfo to pull up, as calculated by
- xfunc_shouldpull() */
- JoinPath curpath; /* current path in list */
- int progress; /* has progress been made this time through? */
- int clausetype;
-
- do {
- progress = false; /* no progress yet in this iteration */
- foreach(y, get_pathlist(rel)) {
- curpath = (JoinPath)lfirst(y);
-
- /*
- ** for each operand, attempt to pullup predicates until first
- ** failure.
- */
- for(ever) {
- /* No, the following should NOT be '==' !! */
- if (clausetype =
- xfunc_shouldpull((Path)get_innerjoinpath(curpath),
- curpath, INNER, &maxcinfo)) {
-
- xfunc_pullup((Path)get_innerjoinpath(curpath),
- curpath, maxcinfo, INNER, clausetype);
- progress = true;
- }else
- break;
- }
- for(ever) {
-
- /* No, the following should NOT be '==' !! */
- if (clausetype =
- xfunc_shouldpull((Path)get_outerjoinpath(curpath),
- curpath, OUTER, &maxcinfo)) {
-
- xfunc_pullup((Path)get_outerjoinpath(curpath),
- curpath, maxcinfo, OUTER, clausetype);
- progress = true;
- }else
- break;
- }
-
- /*
- ** make sure the unpruneable flag bubbles up, i.e.
- ** if anywhere below us in the path pruneable is false,
- ** then pruneable should be false here
- */
- if (get_pruneable(get_parent(curpath)) &&
- (!get_pruneable(get_parent
- ((Path)get_innerjoinpath(curpath))) ||
- !get_pruneable(get_parent((Path)
- get_outerjoinpath(curpath))))) {
-
- set_pruneable(get_parent(curpath),false);
- progress = true;
- }
- }
- } while(progress);
+ LispValue y; /* list ptr */
+ CInfo maxcinfo; /* The CInfo to pull up, as calculated by
+ * xfunc_shouldpull() */
+ JoinPath curpath; /* current path in list */
+ int progress; /* has progress been made this time
+ * through? */
+ int clausetype;
+
+ do
+ {
+ progress = false; /* no progress yet in this iteration */
+ foreach(y, get_pathlist(rel))
+ {
+ curpath = (JoinPath) lfirst(y);
+
+ /*
+ * * for each operand, attempt to pullup predicates until
+ * first * failure.
+ */
+ for (ever)
+ {
+ /* No, the following should NOT be '==' !! */
+ if (clausetype =
+ xfunc_shouldpull((Path) get_innerjoinpath(curpath),
+ curpath, INNER, &maxcinfo))
+ {
+
+ xfunc_pullup((Path) get_innerjoinpath(curpath),
+ curpath, maxcinfo, INNER, clausetype);
+ progress = true;
+ }
+ else
+ break;
+ }
+ for (ever)
+ {
+
+ /* No, the following should NOT be '==' !! */
+ if (clausetype =
+ xfunc_shouldpull((Path) get_outerjoinpath(curpath),
+ curpath, OUTER, &maxcinfo))
+ {
+
+ xfunc_pullup((Path) get_outerjoinpath(curpath),
+ curpath, maxcinfo, OUTER, clausetype);
+ progress = true;
+ }
+ else
+ break;
+ }
+
+ /*
+ * * make sure the unpruneable flag bubbles up, i.e. * if
+ * anywhere below us in the path pruneable is false, * then
+ * pruneable should be false here
+ */
+ if (get_pruneable(get_parent(curpath)) &&
+ (!get_pruneable(get_parent
+ ((Path) get_innerjoinpath(curpath))) ||
+ !get_pruneable(get_parent((Path)
+ get_outerjoinpath(curpath)))))
+ {
+
+ set_pruneable(get_parent(curpath), false);
+ progress = true;
+ }
+ }
+ } while (progress);
}
/*
@@ -128,108 +142,123 @@ void xfunc_trypullup(Rel rel)
** we'd better set the unpruneable flag. -- JMH, 11/11/92
**
** Returns: 0 if nothing left to pullup
- ** XFUNC_LOCPRD if a local predicate is to be pulled up
- ** XFUNC_JOINPRD if a secondary join predicate is to be pulled up
+ ** XFUNC_LOCPRD if a local predicate is to be pulled up
+ ** XFUNC_JOINPRD if a secondary join predicate is to be pulled up
*/
-int xfunc_shouldpull(Query* queryInfo,
- Path childpath,
- JoinPath parentpath,
- int whichchild,
- CInfo *maxcinfopt) /* Out: pointer to clause to pullup */
+int
+xfunc_shouldpull(Query * queryInfo,
+ Path childpath,
+ JoinPath parentpath,
+ int whichchild,
+ CInfo * maxcinfopt) /* Out: pointer to clause to
+ * pullup */
{
- LispValue clauselist, tmplist; /* lists of clauses */
- CInfo maxcinfo; /* clause to pullup */
- LispValue primjoinclause /* primary join clause */
+ LispValue clauselist,
+ tmplist; /* lists of clauses */
+ CInfo maxcinfo; /* clause to pullup */
+ LispValue primjoinclause /* primary join clause */
= xfunc_primary_join(parentpath);
- Cost tmprank, maxrank = (-1 * MAXFLOAT); /* ranks of clauses */
- Cost joinselec = 0; /* selectivity of the join predicate */
- Cost joincost = 0; /* join cost + primjoinclause cost */
- int retval = XFUNC_LOCPRD;
-
- clauselist = get_locclauseinfo(childpath);
-
- if (clauselist != LispNil) {
- /* find local predicate with maximum rank */
- for (tmplist = clauselist,
- maxcinfo = (CInfo) lfirst(tmplist),
- maxrank = xfunc_rank(get_clause(maxcinfo));
- tmplist != LispNil;
- tmplist = lnext(tmplist)) {
-
- if ((tmprank = xfunc_rank(get_clause((CInfo)lfirst(tmplist))))
- > maxrank) {
- maxcinfo = (CInfo) lfirst(tmplist);
- maxrank = tmprank;
- }
+ Cost tmprank,
+ maxrank = (-1 * MAXFLOAT); /* ranks of clauses */
+ Cost joinselec = 0; /* selectivity of the join
+ * predicate */
+ Cost joincost = 0; /* join cost + primjoinclause cost */
+ int retval = XFUNC_LOCPRD;
+
+ clauselist = get_locclauseinfo(childpath);
+
+ if (clauselist != LispNil)
+ {
+ /* find local predicate with maximum rank */
+ for (tmplist = clauselist,
+ maxcinfo = (CInfo) lfirst(tmplist),
+ maxrank = xfunc_rank(get_clause(maxcinfo));
+ tmplist != LispNil;
+ tmplist = lnext(tmplist))
+ {
+
+ if ((tmprank = xfunc_rank(get_clause((CInfo) lfirst(tmplist))))
+ > maxrank)
+ {
+ maxcinfo = (CInfo) lfirst(tmplist);
+ maxrank = tmprank;
+ }
+ }
}
- }
-
- /*
- ** If child is a join path, and there are multiple join clauses,
- ** see if any join clause has even higher rank than the highest
- ** local predicate
- */
- if (is_join(childpath) && xfunc_num_join_clauses((JoinPath)childpath) > 1)
- for (tmplist = get_pathclauseinfo((JoinPath)childpath);
- tmplist != LispNil;
- tmplist = lnext(tmplist)) {
-
- if (tmplist != LispNil &&
- (tmprank = xfunc_rank(get_clause((CInfo) lfirst(tmplist))))
- > maxrank) {
- maxcinfo = (CInfo) lfirst(tmplist);
- maxrank = tmprank;
- retval = XFUNC_JOINPRD;
- }
- }
- if (maxrank == (-1 * MAXFLOAT)) /* no expensive clauses */
- return(0);
-
- /*
- ** Pullup over join if clause is higher rank than join, or if
- ** join is nested loop and current path is inner child (note that
- ** restrictions on the inner of a nested loop don't buy you anything --
- ** you still have to scan the entire inner relation each time).
- ** Note that the cost of a secondary join clause is only what's
- ** calculated by xfunc_expense(), since the actual joining
- ** (i.e. the usual path_cost) is paid for by the primary join clause.
- */
- if (primjoinclause != LispNil) {
- joinselec = compute_clause_selec(queryInfo, primjoinclause, LispNil);
- joincost = xfunc_join_expense(parentpath, whichchild);
-
- if (XfuncMode == XFUNC_PULLALL ||
- (XfuncMode != XFUNC_WAIT &&
- ((joincost != 0 &&
- (maxrank = xfunc_rank(get_clause(maxcinfo))) >
- ((joinselec - 1.0) / joincost))
- || (joincost == 0 && joinselec < 1)
- || (!is_join(childpath)
- && (whichchild == INNER)
- && IsA(parentpath,JoinPath)
- && !IsA(parentpath,HashPath)
- && !IsA(parentpath,MergePath))))) {
-
- *maxcinfopt = maxcinfo;
- return(retval);
-
- }else if (maxrank != -(MAXFLOAT)) {
- /*
- ** we've left an expensive restriction below a join. Since
- ** we may pullup this restriction in predmig.c, we'd best
- ** set the Rel of this join to be unpruneable
- */
- set_pruneable(get_parent(parentpath), false);
- /* and fall through */
+
+ /*
+ * * If child is a join path, and there are multiple join clauses, *
+ * see if any join clause has even higher rank than the highest *
+ * local predicate
+ */
+ if (is_join(childpath) && xfunc_num_join_clauses((JoinPath) childpath) > 1)
+ for (tmplist = get_pathclauseinfo((JoinPath) childpath);
+ tmplist != LispNil;
+ tmplist = lnext(tmplist))
+ {
+
+ if (tmplist != LispNil &&
+ (tmprank = xfunc_rank(get_clause((CInfo) lfirst(tmplist))))
+ > maxrank)
+ {
+ maxcinfo = (CInfo) lfirst(tmplist);
+ maxrank = tmprank;
+ retval = XFUNC_JOINPRD;
+ }
+ }
+ if (maxrank == (-1 * MAXFLOAT)) /* no expensive clauses */
+ return (0);
+
+ /*
+ * * Pullup over join if clause is higher rank than join, or if * join
+ * is nested loop and current path is inner child (note that *
+ * restrictions on the inner of a nested loop don't buy you anything
+ * -- * you still have to scan the entire inner relation each time). *
+ * Note that the cost of a secondary join clause is only what's *
+ * calculated by xfunc_expense(), since the actual joining * (i.e. the
+ * usual path_cost) is paid for by the primary join clause.
+ */
+ if (primjoinclause != LispNil)
+ {
+ joinselec = compute_clause_selec(queryInfo, primjoinclause, LispNil);
+ joincost = xfunc_join_expense(parentpath, whichchild);
+
+ if (XfuncMode == XFUNC_PULLALL ||
+ (XfuncMode != XFUNC_WAIT &&
+ ((joincost != 0 &&
+ (maxrank = xfunc_rank(get_clause(maxcinfo))) >
+ ((joinselec - 1.0) / joincost))
+ || (joincost == 0 && joinselec < 1)
+ || (!is_join(childpath)
+ && (whichchild == INNER)
+ && IsA(parentpath, JoinPath)
+ && !IsA(parentpath, HashPath)
+ && !IsA(parentpath, MergePath)))))
+ {
+
+ *maxcinfopt = maxcinfo;
+ return (retval);
+
+ }
+ else if (maxrank != -(MAXFLOAT))
+ {
+
+ /*
+ * * we've left an expensive restriction below a join. Since *
+ * we may pullup this restriction in predmig.c, we'd best *
+ * set the Rel of this join to be unpruneable
+ */
+ set_pruneable(get_parent(parentpath), false);
+ /* and fall through */
+ }
}
- }
- return(0);
+ return (0);
}
/*
** xfunc_pullup --
- ** move clause from child pathnode to parent pathnode. This operation
+ ** move clause from child pathnode to parent pathnode. This operation
** makes the child pathnode produce a larger relation than it used to.
** This means that we must construct a new Rel just for the childpath,
** although this Rel will not be added to the list of Rels to be joined up
@@ -238,101 +267,111 @@ int xfunc_shouldpull(Query* queryInfo,
**
** Now returns a pointer to the new pulled-up CInfo. -- JMH, 11/18/92
*/
-CInfo xfunc_pullup(Query* queryInfo,
- Path childpath,
- JoinPath parentpath,
- CInfo cinfo, /* clause to pull up */
- int whichchild,/* whether child is INNER or OUTER of join */
- int clausetype)/* whether clause to pull is join or local */
+CInfo
+xfunc_pullup(Query * queryInfo,
+ Path childpath,
+ JoinPath parentpath,
+ CInfo cinfo, /* clause to pull up */
+ int whichchild, /* whether child is INNER or OUTER of join */
+ int clausetype) /* whether clause to pull is join or local */
{
- Path newkid;
- Rel newrel;
- Cost pulled_selec;
- Cost cost;
- CInfo newinfo;
-
- /* remove clause from childpath */
- newkid = (Path)copyObject((Node)childpath);
- if (clausetype == XFUNC_LOCPRD) {
- set_locclauseinfo(newkid,
- xfunc_LispRemove((LispValue)cinfo,
- (List)get_locclauseinfo(newkid)));
- }else {
- set_pathclauseinfo
- ((JoinPath)newkid,
- xfunc_LispRemove((LispValue)cinfo,
- (List)get_pathclauseinfo((JoinPath)newkid)));
- }
-
- /*
- ** give the new child path its own Rel node that reflects the
- ** lack of the pulled-up predicate
- */
- pulled_selec = compute_clause_selec(queryInfo,
- get_clause(cinfo), LispNil);
- xfunc_copyrel(get_parent(newkid), &newrel);
- set_parent(newkid, newrel);
- set_pathlist(newrel, lcons(newkid, NIL));
- set_unorderedpath(newrel, (PathPtr)newkid);
- set_cheapestpath(newrel, (PathPtr)newkid);
- set_size(newrel,
- (Count)((Cost)get_size(get_parent(childpath)) / pulled_selec));
-
- /*
- ** fix up path cost of newkid. To do this we subtract away all the
- ** xfunc_costs of childpath, then recompute the xfunc_costs of newkid
- */
- cost = get_path_cost(newkid) - xfunc_get_path_cost(childpath);
- Assert(cost >= 0);
- set_path_cost(newkid, cost);
- cost = get_path_cost(newkid) + xfunc_get_path_cost(newkid);
- set_path_cost(newkid, cost);
-
- /*
- ** We copy the cinfo, since it may appear in other plans, and we're going
- ** to munge it. -- JMH, 7/22/92
- */
- newinfo = (CInfo)copyObject((Node)cinfo);
-
- /*
- ** Fix all vars in the clause
- ** to point to the right varno and varattno in parentpath
- */
- xfunc_fixvars(get_clause(newinfo), newrel, whichchild);
-
- /* add clause to parentpath, and fix up its cost. */
- set_locclauseinfo(parentpath,
- lispCons((LispValue)newinfo,
- (LispValue)get_locclauseinfo(parentpath)));
- /* put new childpath into the path tree */
- if (whichchild == INNER) {
- set_innerjoinpath(parentpath, (pathPtr)newkid);
- }else {
- set_outerjoinpath(parentpath, (pathPtr)newkid);
- }
-
- /*
- ** recompute parentpath cost from scratch -- the cost
- ** of the join method has changed
- */
- cost = xfunc_total_path_cost(parentpath);
- set_path_cost(parentpath, cost);
-
- return(newinfo);
+ Path newkid;
+ Rel newrel;
+ Cost pulled_selec;
+ Cost cost;
+ CInfo newinfo;
+
+ /* remove clause from childpath */
+ newkid = (Path) copyObject((Node) childpath);
+ if (clausetype == XFUNC_LOCPRD)
+ {
+ set_locclauseinfo(newkid,
+ xfunc_LispRemove((LispValue) cinfo,
+ (List) get_locclauseinfo(newkid)));
+ }
+ else
+ {
+ set_pathclauseinfo
+ ((JoinPath) newkid,
+ xfunc_LispRemove((LispValue) cinfo,
+ (List) get_pathclauseinfo((JoinPath) newkid)));
+ }
+
+ /*
+ * * give the new child path its own Rel node that reflects the * lack
+ * of the pulled-up predicate
+ */
+ pulled_selec = compute_clause_selec(queryInfo,
+ get_clause(cinfo), LispNil);
+ xfunc_copyrel(get_parent(newkid), &newrel);
+ set_parent(newkid, newrel);
+ set_pathlist(newrel, lcons(newkid, NIL));
+ set_unorderedpath(newrel, (PathPtr) newkid);
+ set_cheapestpath(newrel, (PathPtr) newkid);
+ set_size(newrel,
+ (Count) ((Cost) get_size(get_parent(childpath)) / pulled_selec));
+
+ /*
+ * * fix up path cost of newkid. To do this we subtract away all the *
+ * xfunc_costs of childpath, then recompute the xfunc_costs of newkid
+ */
+ cost = get_path_cost(newkid) - xfunc_get_path_cost(childpath);
+ Assert(cost >= 0);
+ set_path_cost(newkid, cost);
+ cost = get_path_cost(newkid) + xfunc_get_path_cost(newkid);
+ set_path_cost(newkid, cost);
+
+ /*
+ * * We copy the cinfo, since it may appear in other plans, and we're
+ * going * to munge it. -- JMH, 7/22/92
+ */
+ newinfo = (CInfo) copyObject((Node) cinfo);
+
+ /*
+ * * Fix all vars in the clause * to point to the right varno and
+ * varattno in parentpath
+ */
+ xfunc_fixvars(get_clause(newinfo), newrel, whichchild);
+
+ /* add clause to parentpath, and fix up its cost. */
+ set_locclauseinfo(parentpath,
+ lispCons((LispValue) newinfo,
+ (LispValue) get_locclauseinfo(parentpath)));
+ /* put new childpath into the path tree */
+ if (whichchild == INNER)
+ {
+ set_innerjoinpath(parentpath, (pathPtr) newkid);
+ }
+ else
+ {
+ set_outerjoinpath(parentpath, (pathPtr) newkid);
+ }
+
+ /*
+ * * recompute parentpath cost from scratch -- the cost * of the join
+ * method has changed
+ */
+ cost = xfunc_total_path_cost(parentpath);
+ set_path_cost(parentpath, cost);
+
+ return (newinfo);
}
/*
- ** calculate (selectivity-1)/cost.
+ ** calculate (selectivity-1)/cost.
*/
-Cost xfunc_rank(Query *queryInfo,LispValue clause)
+Cost
+xfunc_rank(Query * queryInfo, LispValue clause)
{
- Cost selec = compute_clause_selec(queryInfo, clause, LispNil);
- Cost cost = xfunc_expense(queryInfo,clause);
-
- if (cost == 0)
- if (selec > 1) return(MAXFLOAT);
- else return(-(MAXFLOAT));
- return((selec - 1)/cost);
+ Cost selec = compute_clause_selec(queryInfo, clause, LispNil);
+ Cost cost = xfunc_expense(queryInfo, clause);
+
+ if (cost == 0)
+ if (selec > 1)
+ return (MAXFLOAT);
+ else
+ return (-(MAXFLOAT));
+ return ((selec - 1) / cost);
}
/*
@@ -340,91 +379,99 @@ Cost xfunc_rank(Query *queryInfo,LispValue clause)
** by the cardinalities of all the base relations of the query that are *not*
** referenced in the clause.
*/
-Cost xfunc_expense(Query* queryInfo, clause)
- LispValue clause;
+Cost
+xfunc_expense(Query * queryInfo, clause)
+LispValue clause;
{
- Cost cost = xfunc_local_expense(clause);
-
- if (cost)
+ Cost cost = xfunc_local_expense(clause);
+
+ if (cost)
{
- Count card = xfunc_card_unreferenced(queryInfo, clause, LispNil);
- if (card)
- cost /= card;
+ Count card = xfunc_card_unreferenced(queryInfo, clause, LispNil);
+
+ if (card)
+ cost /= card;
}
-
- return(cost);
+
+ return (cost);
}
/*
** xfunc_join_expense --
** Find global expense of a join clause
*/
-Cost xfunc_join_expense(Query *queryInfo, JoinPath path, int whichchild)
+Cost
+xfunc_join_expense(Query * queryInfo, JoinPath path, int whichchild)
{
- LispValue primjoinclause = xfunc_primary_join(path);
-
- /*
- ** the second argument to xfunc_card_unreferenced reflects all the
- ** relations involved in the join clause, i.e. all the relids in the Rel
- ** of the join clause
- */
- Count card = 0;
- Cost cost = xfunc_expense_per_tuple(path, whichchild);
-
- card = xfunc_card_unreferenced(queryInfo,
- primjoinclause,
- get_relids(get_parent(path)));
- if (primjoinclause)
- cost += xfunc_local_expense(primjoinclause);
-
- if (card) cost /= card;
-
- return(cost);
+ LispValue primjoinclause = xfunc_primary_join(path);
+
+ /*
+ * * the second argument to xfunc_card_unreferenced reflects all the *
+ * relations involved in the join clause, i.e. all the relids in the
+ * Rel * of the join clause
+ */
+ Count card = 0;
+ Cost cost = xfunc_expense_per_tuple(path, whichchild);
+
+ card = xfunc_card_unreferenced(queryInfo,
+ primjoinclause,
+ get_relids(get_parent(path)));
+ if (primjoinclause)
+ cost += xfunc_local_expense(primjoinclause);
+
+ if (card)
+ cost /= card;
+
+ return (cost);
}
/*
** Recursively find the per-tuple expense of a clause. See
** xfunc_func_expense for more discussion.
*/
-Cost xfunc_local_expense(LispValue clause)
+Cost
+xfunc_local_expense(LispValue clause)
{
- Cost cost = 0; /* running expense */
- LispValue tmpclause;
-
- /* First handle the base case */
- if (IsA(clause,Const) || IsA(clause,Var) || IsA(clause,Param))
- return(0);
- /* now other stuff */
- else if (IsA(clause,Iter))
- /* Too low. Should multiply by the expected number of iterations. */
- return(xfunc_local_expense(get_iterexpr((Iter)clause)));
- else if (IsA(clause,ArrayRef))
- return(xfunc_local_expense(get_refexpr((ArrayRef)clause)));
- else if (fast_is_clause(clause))
- return(xfunc_func_expense((LispValue)get_op(clause),
- (LispValue)get_opargs(clause)));
- else if (fast_is_funcclause(clause))
- return(xfunc_func_expense((LispValue)get_function(clause),
- (LispValue)get_funcargs(clause)));
- else if (fast_not_clause(clause))
- return(xfunc_local_expense(lsecond(clause)));
- else if (fast_or_clause(clause)) {
- /* find cost of evaluating each disjunct */
- for (tmpclause = lnext(clause); tmpclause != LispNil;
- tmpclause = lnext(tmpclause))
- cost += xfunc_local_expense(lfirst(tmpclause));
- return(cost);
- }else {
- elog(WARN, "Clause node of undetermined type");
- return(-1);
- }
+ Cost cost = 0; /* running expense */
+ LispValue tmpclause;
+
+ /* First handle the base case */
+ if (IsA(clause, Const) || IsA(clause, Var) || IsA(clause, Param))
+ return (0);
+ /* now other stuff */
+ else if (IsA(clause, Iter))
+ /* Too low. Should multiply by the expected number of iterations. */
+ return (xfunc_local_expense(get_iterexpr((Iter) clause)));
+ else if (IsA(clause, ArrayRef))
+ return (xfunc_local_expense(get_refexpr((ArrayRef) clause)));
+ else if (fast_is_clause(clause))
+ return (xfunc_func_expense((LispValue) get_op(clause),
+ (LispValue) get_opargs(clause)));
+ else if (fast_is_funcclause(clause))
+ return (xfunc_func_expense((LispValue) get_function(clause),
+ (LispValue) get_funcargs(clause)));
+ else if (fast_not_clause(clause))
+ return (xfunc_local_expense(lsecond(clause)));
+ else if (fast_or_clause(clause))
+ {
+ /* find cost of evaluating each disjunct */
+ for (tmpclause = lnext(clause); tmpclause != LispNil;
+ tmpclause = lnext(tmpclause))
+ cost += xfunc_local_expense(lfirst(tmpclause));
+ return (cost);
+ }
+ else
+ {
+ elog(WARN, "Clause node of undetermined type");
+ return (-1);
+ }
}
/*
** xfunc_func_expense --
** given a Func or Oper and its args, find its expense.
** Note: in Stonebraker's SIGMOD '91 paper, he uses a more complicated metric
- ** than the one here. We can ignore the expected number of tuples for
+ ** than the one here. We can ignore the expected number of tuples for
** our calculations; we just need the per-tuple expense. But he also
** proposes components to take into account the costs of accessing disk and
** archive. We didn't adopt that scheme here; eventually the vacuum
@@ -434,268 +481,323 @@ Cost xfunc_local_expense(LispValue clause)
** accessing secondary or tertiary storage, since we don't have sufficient
** stats to do it right.
*/
-Cost xfunc_func_expense(LispValue node, LispValue args)
+Cost
+xfunc_func_expense(LispValue node, LispValue args)
{
- HeapTuple tupl; /* the pg_proc tuple for each function */
- Form_pg_proc proc; /* a data structure to hold the pg_proc tuple */
- int width = 0; /* byte width of the field referenced by each clause */
- RegProcedure funcid; /* ID of function associate with node */
- Cost cost = 0; /* running expense */
- LispValue tmpclause;
- LispValue operand; /* one operand of an operator */
-
- if (IsA(node,Oper)) {
- /* don't trust the opid in the Oper node. Use the opno. */
- if (!(funcid = get_opcode(get_opno((Oper)node))))
- elog(WARN, "Oper's function is undefined");
- }else {
- funcid = get_funcid((Func)node);
- }
-
- /* look up tuple in cache */
- tupl = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(funcid),0,0,0);
- if (!HeapTupleIsValid(tupl))
- elog(WARN, "Cache lookup failed for procedure %d", funcid);
- proc = (Form_pg_proc) GETSTRUCT(tupl);
-
- /*
- ** if it's a Postquel function, its cost is stored in the
- ** associated plan.
- */
- if (proc->prolang == SQLlanguageId) {
- LispValue tmpplan;
- List planlist;
-
- if (IsA(node,Oper) || get_func_planlist((Func)node) == LispNil) {
- Oid *argOidVect; /* vector of argtypes */
- char *pq_src; /* text of PQ function */
- int nargs; /* num args to PQ function */
- QueryTreeList *queryTree_list; /* dummy variable */
-
- /*
- ** plan the function, storing it in the Func node for later
- ** use by the executor.
- */
- pq_src = (char *) textout(&(proc->prosrc));
- nargs = proc->pronargs;
- if (nargs > 0)
- argOidVect = proc->proargtypes;
- planlist = (List)pg_plan(pq_src, argOidVect, nargs,
- &parseTree_list, None);
- if (IsA(node,Func))
- set_func_planlist((Func)node, planlist);
-
- }else {/* plan has been cached inside the Func node already */
- planlist = get_func_planlist((Func)node);
+ HeapTuple tupl; /* the pg_proc tuple for each function */
+ Form_pg_proc proc; /* a data structure to hold the pg_proc
+ * tuple */
+ int width = 0; /* byte width of the field referenced by
+ * each clause */
+ RegProcedure funcid; /* ID of function associate with node */
+ Cost cost = 0; /* running expense */
+ LispValue tmpclause;
+ LispValue operand; /* one operand of an operator */
+
+ if (IsA(node, Oper))
+ {
+ /* don't trust the opid in the Oper node. Use the opno. */
+ if (!(funcid = get_opcode(get_opno((Oper) node))))
+ elog(WARN, "Oper's function is undefined");
}
-
- /*
- ** Return the sum of the costs of the plans (the PQ function
- ** may have many queries in its body).
- */
- foreach(tmpplan, planlist)
- cost += get_cost((Plan)lfirst(tmpplan));
- return(cost);
- }else { /* it's a C function */
+ else
+ {
+ funcid = get_funcid((Func) node);
+ }
+
+ /* look up tuple in cache */
+ tupl = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(funcid), 0, 0, 0);
+ if (!HeapTupleIsValid(tupl))
+ elog(WARN, "Cache lookup failed for procedure %d", funcid);
+ proc = (Form_pg_proc) GETSTRUCT(tupl);
+
/*
- ** find the cost of evaluating the function's arguments
- ** and the width of the operands
+ * * if it's a Postquel function, its cost is stored in the *
+ * associated plan.
*/
- for (tmpclause = args; tmpclause != LispNil;
- tmpclause = lnext(tmpclause)) {
-
- if ((operand = lfirst(tmpclause)) != LispNil) {
- cost += xfunc_local_expense(operand);
- width += xfunc_width(operand);
- }
+ if (proc->prolang == SQLlanguageId)
+ {
+ LispValue tmpplan;
+ List planlist;
+
+ if (IsA(node, Oper) || get_func_planlist((Func) node) == LispNil)
+ {
+ Oid *argOidVect; /* vector of argtypes */
+ char *pq_src; /* text of PQ function */
+ int nargs; /* num args to PQ function */
+ QueryTreeList *queryTree_list; /* dummy variable */
+
+ /*
+ * * plan the function, storing it in the Func node for later *
+ * use by the executor.
+ */
+ pq_src = (char *) textout(&(proc->prosrc));
+ nargs = proc->pronargs;
+ if (nargs > 0)
+ argOidVect = proc->proargtypes;
+ planlist = (List) pg_plan(pq_src, argOidVect, nargs,
+ &parseTree_list, None);
+ if (IsA(node, Func))
+ set_func_planlist((Func) node, planlist);
+
+ }
+ else
+ { /* plan has been cached inside the Func
+ * node already */
+ planlist = get_func_planlist((Func) node);
+ }
+
+ /*
+ * * Return the sum of the costs of the plans (the PQ function *
+ * may have many queries in its body).
+ */
+ foreach(tmpplan, planlist)
+ cost += get_cost((Plan) lfirst(tmpplan));
+ return (cost);
+ }
+ else
+ { /* it's a C function */
+
+ /*
+ * * find the cost of evaluating the function's arguments * and
+ * the width of the operands
+ */
+ for (tmpclause = args; tmpclause != LispNil;
+ tmpclause = lnext(tmpclause))
+ {
+
+ if ((operand = lfirst(tmpclause)) != LispNil)
+ {
+ cost += xfunc_local_expense(operand);
+ width += xfunc_width(operand);
+ }
+ }
+
+ /*
+ * * when stats become available, add in cost of accessing
+ * secondary * and tertiary storage here.
+ */
+ return (cost +
+ (Cost) proc->propercall_cpu +
+ (Cost) proc->properbyte_cpu * (Cost) proc->probyte_pct / 100.00 *
+ (Cost) width
+
+ /*
+ * Pct_of_obj_in_mem DISK_COST * proc->probyte_pct/100.00 * width
+ * Pct_of_obj_on_disk + ARCH_COST * proc->probyte_pct/100.00 *
+ * width Pct_of_obj_on_arch
+ */
+ );
}
-
- /*
- ** when stats become available, add in cost of accessing secondary
- ** and tertiary storage here.
- */
- return(cost +
- (Cost)proc->propercall_cpu +
- (Cost)proc->properbyte_cpu * (Cost)proc->probyte_pct/100.00 *
- (Cost)width
- /*
- * Pct_of_obj_in_mem
- DISK_COST * proc->probyte_pct/100.00 * width
- * Pct_of_obj_on_disk +
- ARCH_COST * proc->probyte_pct/100.00 * width
- * Pct_of_obj_on_arch
- */
- );
- }
}
-/*
+/*
** xfunc_width --
** recursively find the width of a expression
*/
-int xfunc_width(LispValue clause)
+int
+xfunc_width(LispValue clause)
{
- Relation rd; /* Relation Descriptor */
- HeapTuple tupl; /* structure to hold a cached tuple */
- TypeTupleForm type; /* structure to hold a type tuple */
- int retval = 0;
-
- if (IsA(clause,Const)) {
- /* base case: width is the width of this constant */
- retval = get_constlen((Const) clause);
- goto exit;
- }else if (IsA(clause,ArrayRef)) {
- /* base case: width is width of the refelem within the array */
- retval = get_refelemlength((ArrayRef)clause);
- goto exit;
- }else if (IsA(clause,Var)) {
- /* base case: width is width of this attribute */
- tupl = SearchSysCacheTuple(TYPOID,
- PointerGetDatum(get_vartype((Var)clause)),
- 0,0,0);
- if (!HeapTupleIsValid(tupl))
- elog(WARN, "Cache lookup failed for type %d",
- get_vartype((Var)clause));
- type = (TypeTupleForm) GETSTRUCT(tupl);
- if (get_varattno((Var)clause) == 0) {
- /* clause is a tuple. Get its width */
- rd = heap_open(type->typrelid);
- retval = xfunc_tuple_width(rd);
- heap_close(rd);
- }else {
- /* attribute is a base type */
- retval = type->typlen;
+ Relation rd; /* Relation Descriptor */
+ HeapTuple tupl; /* structure to hold a cached tuple */
+ TypeTupleForm type; /* structure to hold a type tuple */
+ int retval = 0;
+
+ if (IsA(clause, Const))
+ {
+ /* base case: width is the width of this constant */
+ retval = get_constlen((Const) clause);
+ goto exit;
}
- goto exit;
- }else if (IsA(clause,Param)) {
- if (typeid_get_relid(get_paramtype((Param)clause))) {
- /* Param node returns a tuple. Find its width */
- rd = heap_open(typeid_get_relid(get_paramtype((Param)clause)));
- retval = xfunc_tuple_width(rd);
- heap_close(rd);
- }else if (get_param_tlist((Param)clause) != LispNil) {
- /* Param node projects a complex type */
- Assert(length(get_param_tlist((Param)clause)) == 1); /* sanity */
- retval =
- xfunc_width((LispValue)
- get_expr(lfirst(get_param_tlist((Param)clause))));
- }else {
- /* Param node returns a base type */
- retval = tlen(get_id_type(get_paramtype((Param)clause)));
+ else if (IsA(clause, ArrayRef))
+ {
+ /* base case: width is width of the refelem within the array */
+ retval = get_refelemlength((ArrayRef) clause);
+ goto exit;
}
- goto exit;
- }else if (IsA(clause,Iter)) {
- /*
- ** An Iter returns a setof things, so return the width of a single
- ** thing.
- ** Note: THIS MAY NOT WORK RIGHT WHEN AGGS GET FIXED,
- ** SINCE AGG FUNCTIONS CHEW ON THE WHOLE SETOF THINGS!!!!
- ** This whole Iter business is bogus, anyway.
- */
- retval = xfunc_width(get_iterexpr((Iter)clause));
- goto exit;
- }else if (fast_is_clause(clause)) {
- /*
- ** get function associated with this Oper, and treat this as
- ** a Func
- */
- tupl = SearchSysCacheTuple(OPROID,
- ObjectIdGetDatum(get_opno((Oper)get_op(clause))),
- 0,0,0);
- if (!HeapTupleIsValid(tupl))
- elog(WARN, "Cache lookup failed for procedure %d",
- get_opno((Oper)get_op(clause)));
- return(xfunc_func_width
- ((RegProcedure)(((OperatorTupleForm)(GETSTRUCT(tupl)))->oprcode),
- (LispValue)get_opargs(clause)));
- }else if (fast_is_funcclause(clause)) {
- Func func = (Func)get_function(clause);
- if (get_func_tlist(func) != LispNil) {
- /* this function has a projection on it. Get the length
- of the projected attribute */
- Assert(length(get_func_tlist(func)) == 1); /* sanity */
- retval =
- xfunc_width((LispValue)
- get_expr(lfirst(get_func_tlist(func))));
- goto exit;
- }else {
- return(xfunc_func_width((RegProcedure)get_funcid(func),
- (LispValue)get_funcargs(clause)));
+ else if (IsA(clause, Var))
+ {
+ /* base case: width is width of this attribute */
+ tupl = SearchSysCacheTuple(TYPOID,
+ PointerGetDatum(get_vartype((Var) clause)),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tupl))
+ elog(WARN, "Cache lookup failed for type %d",
+ get_vartype((Var) clause));
+ type = (TypeTupleForm) GETSTRUCT(tupl);
+ if (get_varattno((Var) clause) == 0)
+ {
+ /* clause is a tuple. Get its width */
+ rd = heap_open(type->typrelid);
+ retval = xfunc_tuple_width(rd);
+ heap_close(rd);
+ }
+ else
+ {
+ /* attribute is a base type */
+ retval = type->typlen;
+ }
+ goto exit;
+ }
+ else if (IsA(clause, Param))
+ {
+ if (typeid_get_relid(get_paramtype((Param) clause)))
+ {
+ /* Param node returns a tuple. Find its width */
+ rd = heap_open(typeid_get_relid(get_paramtype((Param) clause)));
+ retval = xfunc_tuple_width(rd);
+ heap_close(rd);
+ }
+ else if (get_param_tlist((Param) clause) != LispNil)
+ {
+ /* Param node projects a complex type */
+ Assert(length(get_param_tlist((Param) clause)) == 1); /* sanity */
+ retval =
+ xfunc_width((LispValue)
+ get_expr(lfirst(get_param_tlist((Param) clause))));
+ }
+ else
+ {
+ /* Param node returns a base type */
+ retval = tlen(get_id_type(get_paramtype((Param) clause)));
+ }
+ goto exit;
+ }
+ else if (IsA(clause, Iter))
+ {
+
+ /*
+ * * An Iter returns a setof things, so return the width of a
+ * single * thing. * Note: THIS MAY NOT WORK RIGHT WHEN AGGS GET
+ * FIXED, * SINCE AGG FUNCTIONS CHEW ON THE WHOLE SETOF THINGS!!!! *
+ * This whole Iter business is bogus, anyway.
+ */
+ retval = xfunc_width(get_iterexpr((Iter) clause));
+ goto exit;
+ }
+ else if (fast_is_clause(clause))
+ {
+
+ /*
+ * * get function associated with this Oper, and treat this as * a
+ * Func
+ */
+ tupl = SearchSysCacheTuple(OPROID,
+ ObjectIdGetDatum(get_opno((Oper) get_op(clause))),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tupl))
+ elog(WARN, "Cache lookup failed for procedure %d",
+ get_opno((Oper) get_op(clause)));
+ return (xfunc_func_width
+ ((RegProcedure) (((OperatorTupleForm) (GETSTRUCT(tupl)))->oprcode),
+ (LispValue) get_opargs(clause)));
+ }
+ else if (fast_is_funcclause(clause))
+ {
+ Func func = (Func) get_function(clause);
+
+ if (get_func_tlist(func) != LispNil)
+ {
+
+ /*
+ * this function has a projection on it. Get the length of
+ * the projected attribute
+ */
+ Assert(length(get_func_tlist(func)) == 1); /* sanity */
+ retval =
+ xfunc_width((LispValue)
+ get_expr(lfirst(get_func_tlist(func))));
+ goto exit;
+ }
+ else
+ {
+ return (xfunc_func_width((RegProcedure) get_funcid(func),
+ (LispValue) get_funcargs(clause)));
+ }
+ }
+ else
+ {
+ elog(WARN, "Clause node of undetermined type");
+ return (-1);
}
- }else {
- elog(WARN, "Clause node of undetermined type");
- return(-1);
- }
-
- exit:
- if (retval == -1)
- retval = VARLEN_DEFAULT;
- return(retval);
+
+exit:
+ if (retval == -1)
+ retval = VARLEN_DEFAULT;
+ return (retval);
}
/*
** xfunc_card_unreferenced:
- ** find all relations not referenced in clause, and multiply their
- ** cardinalities. Ignore relation of cardinality 0.
+ ** find all relations not referenced in clause, and multiply their
+ ** cardinalities. Ignore relation of cardinality 0.
** User may pass in referenced list, if they know it (useful
** for joins).
*/
-static Count
-xfunc_card_unreferenced(Query *queryInfo,
- LispValue clause, Relid referenced)
+static Count
+xfunc_card_unreferenced(Query * queryInfo,
+ LispValue clause, Relid referenced)
{
- Relid unreferenced, allrelids = LispNil;
- LispValue temp;
-
- /* find all relids of base relations referenced in query */
- foreach (temp,queryInfo->base_relation_list_)
+ Relid unreferenced,
+ allrelids = LispNil;
+ LispValue temp;
+
+ /* find all relids of base relations referenced in query */
+ foreach(temp, queryInfo->base_relation_list_)
{
- Assert(lnext(get_relids((Rel)lfirst(temp))) == LispNil);
- allrelids = lappend(allrelids,
- lfirst(get_relids((Rel)lfirst(temp))));
+ Assert(lnext(get_relids((Rel) lfirst(temp))) == LispNil);
+ allrelids = lappend(allrelids,
+ lfirst(get_relids((Rel) lfirst(temp))));
}
-
- /* find all relids referenced in query but not in clause */
- if (!referenced)
- referenced = xfunc_find_references(clause);
- unreferenced = set_difference(allrelids, referenced);
-
- return(xfunc_card_product(unreferenced));
+
+ /* find all relids referenced in query but not in clause */
+ if (!referenced)
+ referenced = xfunc_find_references(clause);
+ unreferenced = set_difference(allrelids, referenced);
+
+ return (xfunc_card_product(unreferenced));
}
/*
- ** xfunc_card_product
+ ** xfunc_card_product
** multiple together cardinalities of a list relations.
*/
-Count xfunc_card_product(Query *queryInfo, Relid relids)
+Count
+xfunc_card_product(Query * queryInfo, Relid relids)
{
- LispValue cinfonode;
- LispValue temp;
- Rel currel;
- Cost tuples;
- Count retval = 0;
-
- foreach(temp,relids) {
- currel = get_rel(lfirst(temp));
- tuples = get_tuples(currel);
-
- if (tuples) { /* not of cardinality 0 */
- /* factor in the selectivity of all zero-cost clauses */
- foreach (cinfonode, get_clauseinfo(currel)) {
- if (!xfunc_expense(queryInfo,get_clause((CInfo)lfirst(cinfonode))))
- tuples *=
- compute_clause_selec(queryInfo,
- get_clause((CInfo)lfirst(cinfonode)),
- LispNil);
- }
-
- if (retval == 0) retval = tuples;
- else retval *= tuples;
+ LispValue cinfonode;
+ LispValue temp;
+ Rel currel;
+ Cost tuples;
+ Count retval = 0;
+
+ foreach(temp, relids)
+ {
+ currel = get_rel(lfirst(temp));
+ tuples = get_tuples(currel);
+
+ if (tuples)
+ { /* not of cardinality 0 */
+ /* factor in the selectivity of all zero-cost clauses */
+ foreach(cinfonode, get_clauseinfo(currel))
+ {
+ if (!xfunc_expense(queryInfo, get_clause((CInfo) lfirst(cinfonode))))
+ tuples *=
+ compute_clause_selec(queryInfo,
+ get_clause((CInfo) lfirst(cinfonode)),
+ LispNil);
+ }
+
+ if (retval == 0)
+ retval = tuples;
+ else
+ retval *= tuples;
+ }
}
- }
- if (retval == 0) retval = 1; /* saves caller from dividing by zero */
- return(retval);
+ if (retval == 0)
+ retval = 1; /* saves caller from dividing by zero */
+ return (retval);
}
@@ -703,48 +805,60 @@ Count xfunc_card_product(Query *queryInfo, Relid relids)
** xfunc_find_references:
** Traverse a clause and find all relids referenced in the clause.
*/
-List xfunc_find_references(LispValue clause)
+List
+xfunc_find_references(LispValue clause)
{
- List retval = (List)LispNil;
- LispValue tmpclause;
-
- /* Base cases */
- if (IsA(clause,Var))
- return(lispCons(lfirst(get_varid((Var)clause)), LispNil));
- else if (IsA(clause,Const) || IsA(clause,Param))
- return((List)LispNil);
-
- /* recursion */
- else if (IsA(clause,Iter))
- /* Too low. Should multiply by the expected number of iterations. maybe */
- return(xfunc_find_references(get_iterexpr((Iter)clause)));
- else if (IsA(clause,ArrayRef))
- return(xfunc_find_references(get_refexpr((ArrayRef)clause)));
- else if (fast_is_clause(clause)) {
- /* string together result of all operands of Oper */
- for (tmpclause = (LispValue)get_opargs(clause); tmpclause != LispNil;
- tmpclause = lnext(tmpclause))
- retval = nconc(retval, xfunc_find_references(lfirst(tmpclause)));
- return(retval);
- }else if (fast_is_funcclause(clause)) {
- /* string together result of all args of Func */
- for (tmpclause = (LispValue)get_funcargs(clause);
- tmpclause != LispNil;
- tmpclause = lnext(tmpclause))
- retval = nconc(retval, xfunc_find_references(lfirst(tmpclause)));
- return(retval);
- }else if (fast_not_clause(clause))
- return(xfunc_find_references(lsecond(clause)));
- else if (fast_or_clause(clause)) {
- /* string together result of all operands of OR */
- for (tmpclause = lnext(clause); tmpclause != LispNil;
- tmpclause = lnext(tmpclause))
- retval = nconc(retval, xfunc_find_references(lfirst(tmpclause)));
- return(retval);
- }else {
- elog(WARN, "Clause node of undetermined type");
- return((List)LispNil);
- }
+ List retval = (List) LispNil;
+ LispValue tmpclause;
+
+ /* Base cases */
+ if (IsA(clause, Var))
+ return (lispCons(lfirst(get_varid((Var) clause)), LispNil));
+ else if (IsA(clause, Const) || IsA(clause, Param))
+ return ((List) LispNil);
+
+ /* recursion */
+ else if (IsA(clause, Iter))
+
+ /*
+ * Too low. Should multiply by the expected number of iterations.
+ * maybe
+ */
+ return (xfunc_find_references(get_iterexpr((Iter) clause)));
+ else if (IsA(clause, ArrayRef))
+ return (xfunc_find_references(get_refexpr((ArrayRef) clause)));
+ else if (fast_is_clause(clause))
+ {
+ /* string together result of all operands of Oper */
+ for (tmpclause = (LispValue) get_opargs(clause); tmpclause != LispNil;
+ tmpclause = lnext(tmpclause))
+ retval = nconc(retval, xfunc_find_references(lfirst(tmpclause)));
+ return (retval);
+ }
+ else if (fast_is_funcclause(clause))
+ {
+ /* string together result of all args of Func */
+ for (tmpclause = (LispValue) get_funcargs(clause);
+ tmpclause != LispNil;
+ tmpclause = lnext(tmpclause))
+ retval = nconc(retval, xfunc_find_references(lfirst(tmpclause)));
+ return (retval);
+ }
+ else if (fast_not_clause(clause))
+ return (xfunc_find_references(lsecond(clause)));
+ else if (fast_or_clause(clause))
+ {
+ /* string together result of all operands of OR */
+ for (tmpclause = lnext(clause); tmpclause != LispNil;
+ tmpclause = lnext(tmpclause))
+ retval = nconc(retval, xfunc_find_references(lfirst(tmpclause)));
+ return (retval);
+ }
+ else
+ {
+ elog(WARN, "Clause node of undetermined type");
+ return ((List) LispNil);
+ }
}
/*
@@ -753,212 +867,219 @@ List xfunc_find_references(LispValue clause)
** min rank Hash or Merge clause, while for Nested Loop it's the
** min rank pathclause
*/
-LispValue xfunc_primary_join(JoinPath pathnode)
+LispValue
+xfunc_primary_join(JoinPath pathnode)
{
- LispValue joinclauselist = get_pathclauseinfo(pathnode);
- CInfo mincinfo;
- LispValue tmplist;
- LispValue minclause = LispNil;
- Cost minrank, tmprank;
-
- if (IsA(pathnode,MergePath))
+ LispValue joinclauselist = get_pathclauseinfo(pathnode);
+ CInfo mincinfo;
+ LispValue tmplist;
+ LispValue minclause = LispNil;
+ Cost minrank,
+ tmprank;
+
+ if (IsA(pathnode, MergePath))
{
- for(tmplist = get_path_mergeclauses((MergePath)pathnode),
- minclause = lfirst(tmplist),
- minrank = xfunc_rank(minclause);
- tmplist != LispNil;
- tmplist = lnext(tmplist))
- if ((tmprank = xfunc_rank(lfirst(tmplist)))
- < minrank)
- {
- minrank = tmprank;
- minclause = lfirst(tmplist);
- }
- return(minclause);
+ for (tmplist = get_path_mergeclauses((MergePath) pathnode),
+ minclause = lfirst(tmplist),
+ minrank = xfunc_rank(minclause);
+ tmplist != LispNil;
+ tmplist = lnext(tmplist))
+ if ((tmprank = xfunc_rank(lfirst(tmplist)))
+ < minrank)
+ {
+ minrank = tmprank;
+ minclause = lfirst(tmplist);
+ }
+ return (minclause);
}
- else if (IsA(pathnode,HashPath))
+ else if (IsA(pathnode, HashPath))
{
- for(tmplist = get_path_hashclauses((HashPath)pathnode),
- minclause = lfirst(tmplist),
- minrank = xfunc_rank(minclause);
- tmplist != LispNil;
- tmplist = lnext(tmplist))
- if ((tmprank = xfunc_rank(lfirst(tmplist)))
- < minrank)
- {
- minrank = tmprank;
- minclause = lfirst(tmplist);
- }
- return(minclause);
+ for (tmplist = get_path_hashclauses((HashPath) pathnode),
+ minclause = lfirst(tmplist),
+ minrank = xfunc_rank(minclause);
+ tmplist != LispNil;
+ tmplist = lnext(tmplist))
+ if ((tmprank = xfunc_rank(lfirst(tmplist)))
+ < minrank)
+ {
+ minrank = tmprank;
+ minclause = lfirst(tmplist);
+ }
+ return (minclause);
}
-
- /* if we drop through, it's nested loop join */
- if (joinclauselist == LispNil)
- return(LispNil);
-
- for(tmplist = joinclauselist, mincinfo = (CInfo) lfirst(joinclauselist),
- minrank = xfunc_rank(get_clause((CInfo) lfirst(tmplist)));
- tmplist != LispNil;
- tmplist = lnext(tmplist))
- if ((tmprank = xfunc_rank(get_clause((CInfo) lfirst(tmplist))))
- < minrank)
- {
- minrank = tmprank;
- mincinfo = (CInfo) lfirst(tmplist);
- }
- return((LispValue)get_clause(mincinfo));
+
+ /* if we drop through, it's nested loop join */
+ if (joinclauselist == LispNil)
+ return (LispNil);
+
+ for (tmplist = joinclauselist, mincinfo = (CInfo) lfirst(joinclauselist),
+ minrank = xfunc_rank(get_clause((CInfo) lfirst(tmplist)));
+ tmplist != LispNil;
+ tmplist = lnext(tmplist))
+ if ((tmprank = xfunc_rank(get_clause((CInfo) lfirst(tmplist))))
+ < minrank)
+ {
+ minrank = tmprank;
+ mincinfo = (CInfo) lfirst(tmplist);
+ }
+ return ((LispValue) get_clause(mincinfo));
}
/*
** xfunc_get_path_cost
** get the expensive function costs of the path
*/
-Cost xfunc_get_path_cost(Query *queryInfo, Path pathnode)
+Cost
+xfunc_get_path_cost(Query * queryInfo, Path pathnode)
{
- Cost cost = 0;
- LispValue tmplist;
- Cost selec = 1.0;
-
- /*
- ** first add in the expensive local function costs.
- ** We ensure that the clauses are sorted by rank, so that we
- ** know (via selectivities) the number of tuples that will be checked
- ** by each function. If we're not doing any optimization of expensive
- ** functions, we don't sort.
- */
- if (XfuncMode != XFUNC_OFF)
- set_locclauseinfo(pathnode, lisp_qsort(get_locclauseinfo(pathnode),
- xfunc_cinfo_compare));
- for(tmplist = get_locclauseinfo(pathnode), selec = 1.0;
- tmplist != LispNil;
- tmplist = lnext(tmplist))
+ Cost cost = 0;
+ LispValue tmplist;
+ Cost selec = 1.0;
+
+ /*
+ * * first add in the expensive local function costs. * We ensure that
+ * the clauses are sorted by rank, so that we * know (via
+ * selectivities) the number of tuples that will be checked * by each
+ * function. If we're not doing any optimization of expensive *
+ * functions, we don't sort.
+ */
+ if (XfuncMode != XFUNC_OFF)
+ set_locclauseinfo(pathnode, lisp_qsort(get_locclauseinfo(pathnode),
+ xfunc_cinfo_compare));
+ for (tmplist = get_locclauseinfo(pathnode), selec = 1.0;
+ tmplist != LispNil;
+ tmplist = lnext(tmplist))
{
- cost += (Cost)(xfunc_local_expense(get_clause((CInfo)lfirst(tmplist)))
- * (Cost)get_tuples(get_parent(pathnode)) * selec);
- selec *= compute_clause_selec(queryInfo,
- get_clause((CInfo)lfirst(tmplist)),
- LispNil);
+ cost += (Cost) (xfunc_local_expense(get_clause((CInfo) lfirst(tmplist)))
+ * (Cost) get_tuples(get_parent(pathnode)) * selec);
+ selec *= compute_clause_selec(queryInfo,
+ get_clause((CInfo) lfirst(tmplist)),
+ LispNil);
}
-
- /*
- ** Now add in any node-specific expensive function costs.
- ** Again, we must ensure that the clauses are sorted by rank.
- */
- if (IsA(pathnode,JoinPath))
+
+ /*
+ * * Now add in any node-specific expensive function costs. * Again,
+ * we must ensure that the clauses are sorted by rank.
+ */
+ if (IsA(pathnode, JoinPath))
{
- if (XfuncMode != XFUNC_OFF)
- set_pathclauseinfo((JoinPath)pathnode, lisp_qsort
- (get_pathclauseinfo((JoinPath)pathnode),
- xfunc_cinfo_compare));
- for(tmplist = get_pathclauseinfo((JoinPath)pathnode), selec = 1.0;
- tmplist != LispNil;
- tmplist = lnext(tmplist))
+ if (XfuncMode != XFUNC_OFF)
+ set_pathclauseinfo((JoinPath) pathnode, lisp_qsort
+ (get_pathclauseinfo((JoinPath) pathnode),
+ xfunc_cinfo_compare));
+ for (tmplist = get_pathclauseinfo((JoinPath) pathnode), selec = 1.0;
+ tmplist != LispNil;
+ tmplist = lnext(tmplist))
{
- cost += (Cost)(xfunc_local_expense(get_clause((CInfo)lfirst(tmplist)))
- * (Cost)get_tuples(get_parent(pathnode)) * selec);
- selec *= compute_clause_selec(queryInfo,
- get_clause((CInfo)lfirst(tmplist)),
- LispNil);
+ cost += (Cost) (xfunc_local_expense(get_clause((CInfo) lfirst(tmplist)))
+ * (Cost) get_tuples(get_parent(pathnode)) * selec);
+ selec *= compute_clause_selec(queryInfo,
+ get_clause((CInfo) lfirst(tmplist)),
+ LispNil);
}
}
- if (IsA(pathnode,HashPath))
+ if (IsA(pathnode, HashPath))
{
- if (XfuncMode != XFUNC_OFF)
- set_path_hashclauses
- ((HashPath)pathnode,
- lisp_qsort(get_path_hashclauses((HashPath)pathnode),
- xfunc_clause_compare));
- for(tmplist = get_path_hashclauses((HashPath)pathnode), selec = 1.0;
- tmplist != LispNil;
- tmplist = lnext(tmplist))
+ if (XfuncMode != XFUNC_OFF)
+ set_path_hashclauses
+ ((HashPath) pathnode,
+ lisp_qsort(get_path_hashclauses((HashPath) pathnode),
+ xfunc_clause_compare));
+ for (tmplist = get_path_hashclauses((HashPath) pathnode), selec = 1.0;
+ tmplist != LispNil;
+ tmplist = lnext(tmplist))
{
- cost += (Cost)(xfunc_local_expense(lfirst(tmplist))
- * (Cost)get_tuples(get_parent(pathnode)) * selec);
- selec *= compute_clause_selec(queryInfo,
- lfirst(tmplist), LispNil);
+ cost += (Cost) (xfunc_local_expense(lfirst(tmplist))
+ * (Cost) get_tuples(get_parent(pathnode)) * selec);
+ selec *= compute_clause_selec(queryInfo,
+ lfirst(tmplist), LispNil);
}
}
- if (IsA(pathnode,MergePath))
+ if (IsA(pathnode, MergePath))
{
- if (XfuncMode != XFUNC_OFF)
- set_path_mergeclauses
- ((MergePath)pathnode,
- lisp_qsort(get_path_mergeclauses((MergePath)pathnode),
- xfunc_clause_compare));
- for(tmplist = get_path_mergeclauses((MergePath)pathnode), selec = 1.0;
- tmplist != LispNil;
- tmplist = lnext(tmplist))
+ if (XfuncMode != XFUNC_OFF)
+ set_path_mergeclauses
+ ((MergePath) pathnode,
+ lisp_qsort(get_path_mergeclauses((MergePath) pathnode),
+ xfunc_clause_compare));
+ for (tmplist = get_path_mergeclauses((MergePath) pathnode), selec = 1.0;
+ tmplist != LispNil;
+ tmplist = lnext(tmplist))
{
- cost += (Cost)(xfunc_local_expense(lfirst(tmplist))
- * (Cost)get_tuples(get_parent(pathnode)) * selec);
- selec *= compute_clause_selec(queryInfo,
- lfirst(tmplist), LispNil);
+ cost += (Cost) (xfunc_local_expense(lfirst(tmplist))
+ * (Cost) get_tuples(get_parent(pathnode)) * selec);
+ selec *= compute_clause_selec(queryInfo,
+ lfirst(tmplist), LispNil);
}
}
- Assert(cost >= 0);
- return(cost);
+ Assert(cost >= 0);
+ return (cost);
}
/*
- ** Recalculate the cost of a path node. This includes the basic cost of the
+ ** Recalculate the cost of a path node. This includes the basic cost of the
** node, as well as the cost of its expensive functions.
** We need to do this to the parent after pulling a clause from a child into a
** parent. Thus we should only be calling this function on JoinPaths.
*/
-Cost xfunc_total_path_cost(JoinPath pathnode)
+Cost
+xfunc_total_path_cost(JoinPath pathnode)
{
- Cost cost = xfunc_get_path_cost((Path)pathnode);
-
- Assert(IsA(pathnode,JoinPath));
- if (IsA(pathnode,MergePath))
+ Cost cost = xfunc_get_path_cost((Path) pathnode);
+
+ Assert(IsA(pathnode, JoinPath));
+ if (IsA(pathnode, MergePath))
{
- MergePath mrgnode = (MergePath)pathnode;
- cost += cost_mergesort(get_path_cost((Path)get_outerjoinpath(mrgnode)),
- get_path_cost((Path)get_innerjoinpath(mrgnode)),
- get_outersortkeys(mrgnode),
- get_innersortkeys(mrgnode),
- get_tuples(get_parent((Path)get_outerjoinpath
- (mrgnode))),
- get_tuples(get_parent((Path)get_innerjoinpath
- (mrgnode))),
- get_width(get_parent((Path)get_outerjoinpath
- (mrgnode))),
- get_width(get_parent((Path)get_innerjoinpath
- (mrgnode))));
- Assert(cost >= 0);
- return(cost);
+ MergePath mrgnode = (MergePath) pathnode;
+
+ cost += cost_mergesort(get_path_cost((Path) get_outerjoinpath(mrgnode)),
+ get_path_cost((Path) get_innerjoinpath(mrgnode)),
+ get_outersortkeys(mrgnode),
+ get_innersortkeys(mrgnode),
+ get_tuples(get_parent((Path) get_outerjoinpath
+ (mrgnode))),
+ get_tuples(get_parent((Path) get_innerjoinpath
+ (mrgnode))),
+ get_width(get_parent((Path) get_outerjoinpath
+ (mrgnode))),
+ get_width(get_parent((Path) get_innerjoinpath
+ (mrgnode))));
+ Assert(cost >= 0);
+ return (cost);
}
- else if (IsA(pathnode,HashPath))
+ else if (IsA(pathnode, HashPath))
{
- HashPath hashnode = (HashPath)pathnode;
- cost += cost_hashjoin(get_path_cost((Path)get_outerjoinpath(hashnode)),
- get_path_cost((Path)get_innerjoinpath(hashnode)),
- get_outerhashkeys(hashnode),
- get_innerhashkeys(hashnode),
- get_tuples(get_parent((Path)get_outerjoinpath
- (hashnode))),
- get_tuples(get_parent((Path)get_innerjoinpath
- (hashnode))),
- get_width(get_parent((Path)get_outerjoinpath
- (hashnode))),
- get_width(get_parent((Path)get_innerjoinpath
- (hashnode))));
- Assert (cost >= 0);
- return(cost);
+ HashPath hashnode = (HashPath) pathnode;
+
+ cost += cost_hashjoin(get_path_cost((Path) get_outerjoinpath(hashnode)),
+ get_path_cost((Path) get_innerjoinpath(hashnode)),
+ get_outerhashkeys(hashnode),
+ get_innerhashkeys(hashnode),
+ get_tuples(get_parent((Path) get_outerjoinpath
+ (hashnode))),
+ get_tuples(get_parent((Path) get_innerjoinpath
+ (hashnode))),
+ get_width(get_parent((Path) get_outerjoinpath
+ (hashnode))),
+ get_width(get_parent((Path) get_innerjoinpath
+ (hashnode))));
+ Assert(cost >= 0);
+ return (cost);
}
- else /* Nested Loop Join */
+ else
+/* Nested Loop Join */
{
- cost += cost_nestloop(get_path_cost((Path)get_outerjoinpath(pathnode)),
- get_path_cost((Path)get_innerjoinpath(pathnode)),
- get_tuples(get_parent((Path)get_outerjoinpath
- (pathnode))),
- get_tuples(get_parent((Path)get_innerjoinpath
- (pathnode))),
- get_pages(get_parent((Path)get_outerjoinpath
- (pathnode))),
- IsA(get_innerjoinpath(pathnode),IndexPath));
- Assert(cost >= 0);
- return(cost);
+ cost += cost_nestloop(get_path_cost((Path) get_outerjoinpath(pathnode)),
+ get_path_cost((Path) get_innerjoinpath(pathnode)),
+ get_tuples(get_parent((Path) get_outerjoinpath
+ (pathnode))),
+ get_tuples(get_parent((Path) get_innerjoinpath
+ (pathnode))),
+ get_pages(get_parent((Path) get_outerjoinpath
+ (pathnode))),
+ IsA(get_innerjoinpath(pathnode), IndexPath));
+ Assert(cost >= 0);
+ return (cost);
}
}
@@ -967,7 +1088,7 @@ Cost xfunc_total_path_cost(JoinPath pathnode)
** xfunc_expense_per_tuple --
** return the expense of the join *per-tuple* of the input relation.
** The cost model here is that a join costs
- ** k*card(outer)*card(inner) + l*card(outer) + m*card(inner) + n
+ ** k*card(outer)*card(inner) + l*card(outer) + m*card(inner) + n
**
** We treat the l and m terms by considering them to be like restrictions
** constrained to be right under the join. Thus the cost per inner and
@@ -975,138 +1096,146 @@ Cost xfunc_total_path_cost(JoinPath pathnode)
**
** The cost per tuple of outer is k + l/referenced(inner). Cost per tuple
** of inner is k + m/referenced(outer).
- ** The constants k, l, m and n depend on the join method. Measures here are
+ ** The constants k, l, m and n depend on the join method. Measures here are
** based on the costs in costsize.c, with fudging for HashJoin and Sorts to
** make it fit our model (the 'q' in HashJoin results in a
** card(outer)/card(inner) term, and sorting results in a log term.
-
+
*/
-Cost xfunc_expense_per_tuple(JoinPath joinnode, int whichchild)
+Cost
+xfunc_expense_per_tuple(JoinPath joinnode, int whichchild)
{
- Rel outerrel = get_parent((Path)get_outerjoinpath(joinnode));
- Rel innerrel = get_parent((Path)get_innerjoinpath(joinnode));
- Count outerwidth = get_width(outerrel);
- Count outers_per_page = ceil(BLCKSZ/(outerwidth + sizeof(HeapTupleData)));
-
- if (IsA(joinnode,HashPath))
+ Rel outerrel = get_parent((Path) get_outerjoinpath(joinnode));
+ Rel innerrel = get_parent((Path) get_innerjoinpath(joinnode));
+ Count outerwidth = get_width(outerrel);
+ Count outers_per_page = ceil(BLCKSZ / (outerwidth + sizeof(HeapTupleData)));
+
+ if (IsA(joinnode, HashPath))
{
- if (whichchild == INNER)
- return((1 + _CPU_PAGE_WEIGHT_)*outers_per_page/NBuffers);
- else
- return(((1 + _CPU_PAGE_WEIGHT_)*outers_per_page/NBuffers)
- + _CPU_PAGE_WEIGHT_
- / xfunc_card_product(get_relids(innerrel)));
+ if (whichchild == INNER)
+ return ((1 + _CPU_PAGE_WEIGHT_) * outers_per_page / NBuffers);
+ else
+ return (((1 + _CPU_PAGE_WEIGHT_) * outers_per_page / NBuffers)
+ + _CPU_PAGE_WEIGHT_
+ / xfunc_card_product(get_relids(innerrel)));
}
- else if (IsA(joinnode,MergePath))
+ else if (IsA(joinnode, MergePath))
{
- /* assumes sort exists, and costs one (I/O + CPU) per tuple */
- if (whichchild == INNER)
- return((2*_CPU_PAGE_WEIGHT_ + 1)
- / xfunc_card_product(get_relids(outerrel)));
- else
- return((2*_CPU_PAGE_WEIGHT_ + 1)
- / xfunc_card_product(get_relids(innerrel)));
+ /* assumes sort exists, and costs one (I/O + CPU) per tuple */
+ if (whichchild == INNER)
+ return ((2 * _CPU_PAGE_WEIGHT_ + 1)
+ / xfunc_card_product(get_relids(outerrel)));
+ else
+ return ((2 * _CPU_PAGE_WEIGHT_ + 1)
+ / xfunc_card_product(get_relids(innerrel)));
}
- else /* nestloop */
+ else
+/* nestloop */
{
- Assert(IsA(joinnode,JoinPath));
- return(_CPU_PAGE_WEIGHT_);
+ Assert(IsA(joinnode, JoinPath));
+ return (_CPU_PAGE_WEIGHT_);
}
}
/*
** xfunc_fixvars --
- ** After pulling up a clause, we must walk its expression tree, fixing Var
+ ** After pulling up a clause, we must walk its expression tree, fixing Var
** nodes to point to the correct varno (either INNER or OUTER, depending
- ** on which child the clause was pulled from), and the right varattno in the
+ ** on which child the clause was pulled from), and the right varattno in the
** target list of the child's former relation. If the target list of the
** child Rel does not contain the attribute we need, we add it.
*/
-void xfunc_fixvars(LispValue clause, /* clause being pulled up */
- Rel rel, /* rel it's being pulled from */
- int varno) /* whether rel is INNER or OUTER of join */
+void
+xfunc_fixvars(LispValue clause, /* clause being pulled up */
+ Rel rel, /* rel it's being pulled from */
+ int varno) /* whether rel is INNER or OUTER of join */
{
- LispValue tmpclause; /* temporary variable */
- TargetEntry *tle; /* tlist member corresponding to var */
-
-
- if (IsA(clause,Const) || IsA(clause,Param)) return;
- else if (IsA(clause,Var))
+ LispValue tmpclause; /* temporary variable */
+ TargetEntry *tle; /* tlist member corresponding to var */
+
+
+ if (IsA(clause, Const) || IsA(clause, Param))
+ return;
+ else if (IsA(clause, Var))
{
- /* here's the meat */
- tle = tlistentry_member((Var)clause, get_targetlist(rel));
- if (tle == LispNil)
+ /* here's the meat */
+ tle = tlistentry_member((Var) clause, get_targetlist(rel));
+ if (tle == LispNil)
{
- /*
- ** The attribute we need is not in the target list,
- ** so we have to add it.
- **
- */
- add_tl_element(rel, (Var)clause);
- tle = tlistentry_member((Var)clause, get_targetlist(rel));
+
+ /*
+ * * The attribute we need is not in the target list, * so we
+ * have to add it. *
+ *
+ */
+ add_tl_element(rel, (Var) clause);
+ tle = tlistentry_member((Var) clause, get_targetlist(rel));
}
- set_varno(((Var)clause), varno);
- set_varattno(((Var)clause), get_resno(get_resdom(get_entry(tle))));
+ set_varno(((Var) clause), varno);
+ set_varattno(((Var) clause), get_resno(get_resdom(get_entry(tle))));
}
- else if (IsA(clause,Iter))
- xfunc_fixvars(get_iterexpr((Iter)clause), rel, varno);
- else if (fast_is_clause(clause))
+ else if (IsA(clause, Iter))
+ xfunc_fixvars(get_iterexpr((Iter) clause), rel, varno);
+ else if (fast_is_clause(clause))
{
- xfunc_fixvars(lfirst(lnext(clause)), rel, varno);
- xfunc_fixvars(lfirst(lnext(lnext(clause))), rel, varno);
+ xfunc_fixvars(lfirst(lnext(clause)), rel, varno);
+ xfunc_fixvars(lfirst(lnext(lnext(clause))), rel, varno);
}
- else if (fast_is_funcclause(clause))
- for (tmpclause = lnext(clause); tmpclause != LispNil;
- tmpclause = lnext(tmpclause))
- xfunc_fixvars(lfirst(tmpclause), rel, varno);
- else if (fast_not_clause(clause))
- xfunc_fixvars(lsecond(clause), rel, varno);
- else if (fast_or_clause(clause))
- for (tmpclause = lnext(clause); tmpclause != LispNil;
- tmpclause = lnext(tmpclause))
- xfunc_fixvars(lfirst(tmpclause), rel, varno);
- else
+ else if (fast_is_funcclause(clause))
+ for (tmpclause = lnext(clause); tmpclause != LispNil;
+ tmpclause = lnext(tmpclause))
+ xfunc_fixvars(lfirst(tmpclause), rel, varno);
+ else if (fast_not_clause(clause))
+ xfunc_fixvars(lsecond(clause), rel, varno);
+ else if (fast_or_clause(clause))
+ for (tmpclause = lnext(clause); tmpclause != LispNil;
+ tmpclause = lnext(tmpclause))
+ xfunc_fixvars(lfirst(tmpclause), rel, varno);
+ else
{
- elog(WARN, "Clause node of undetermined type");
+ elog(WARN, "Clause node of undetermined type");
}
}
/*
** Comparison function for lisp_qsort() on a list of CInfo's.
- ** arg1 and arg2 should really be of type (CInfo *).
+ ** arg1 and arg2 should really be of type (CInfo *).
*/
-int xfunc_cinfo_compare(void *arg1, void *arg2)
+int
+xfunc_cinfo_compare(void *arg1, void *arg2)
{
- CInfo info1 = *(CInfo *) arg1;
- CInfo info2 = *(CInfo *) arg2;
-
- LispValue clause1 = (LispValue) get_clause(info1),
- clause2 = (LispValue) get_clause(info2);
-
- return(xfunc_clause_compare((void *) &clause1, (void *) &clause2));
+ CInfo info1 = *(CInfo *) arg1;
+ CInfo info2 = *(CInfo *) arg2;
+
+ LispValue clause1 = (LispValue) get_clause(info1),
+ clause2 = (LispValue) get_clause(info2);
+
+ return (xfunc_clause_compare((void *) &clause1, (void *) &clause2));
}
/*
- ** xfunc_clause_compare: comparison function for lisp_qsort() that compares two
+ ** xfunc_clause_compare: comparison function for lisp_qsort() that compares two
** clauses based on expense/(1 - selectivity)
** arg1 and arg2 are really pointers to clauses.
*/
-int xfunc_clause_compare(void *arg1, void *arg2)
+int
+xfunc_clause_compare(void *arg1, void *arg2)
{
- LispValue clause1 = *(LispValue *) arg1;
- LispValue clause2 = *(LispValue *) arg2;
- Cost rank1, /* total xfunc rank of clause1 */
- rank2; /* total xfunc rank of clause2 */
-
- rank1 = xfunc_rank(clause1);
- rank2 = xfunc_rank(clause2);
-
- if ( rank1 < rank2)
- return(-1);
- else if (rank1 == rank2)
- return(0);
- else return(1);
+ LispValue clause1 = *(LispValue *) arg1;
+ LispValue clause2 = *(LispValue *) arg2;
+ Cost rank1, /* total xfunc rank of clause1 */
+ rank2; /* total xfunc rank of clause2 */
+
+ rank1 = xfunc_rank(clause1);
+ rank2 = xfunc_rank(clause2);
+
+ if (rank1 < rank2)
+ return (-1);
+ else if (rank1 == rank2)
+ return (0);
+ else
+ return (1);
}
/*
@@ -1115,58 +1244,62 @@ int xfunc_clause_compare(void *arg1, void *arg2)
** (this assumes the predicates have been converted to Conjunctive NF)
** Modifies the clause list!
*/
-void xfunc_disjunct_sort(LispValue clause_list)
+void
+xfunc_disjunct_sort(LispValue clause_list)
{
- LispValue temp;
-
- foreach(temp, clause_list)
- if(or_clause(lfirst(temp)))
- lnext(lfirst(temp)) =
- lisp_qsort(lnext(lfirst(temp)), xfunc_disjunct_compare);
+ LispValue temp;
+
+ foreach(temp, clause_list)
+ if (or_clause(lfirst(temp)))
+ lnext(lfirst(temp)) =
+ lisp_qsort(lnext(lfirst(temp)), xfunc_disjunct_compare);
}
/*
- ** xfunc_disjunct_compare: comparison function for qsort() that compares two
+ ** xfunc_disjunct_compare: comparison function for qsort() that compares two
** disjuncts based on cost/selec.
** arg1 and arg2 are really pointers to disjuncts
*/
-int xfunc_disjunct_compare(Query* queryInfo, void *arg1, void *arg2)
+int
+xfunc_disjunct_compare(Query * queryInfo, void *arg1, void *arg2)
{
- LispValue disjunct1 = *(LispValue *) arg1;
- LispValue disjunct2 = *(LispValue *) arg2;
- Cost cost1, /* total cost of disjunct1 */
- cost2, /* total cost of disjunct2 */
- selec1,
- selec2;
- Cost rank1, rank2;
-
- cost1 = xfunc_expense(queryInfo, disjunct1);
- cost2 = xfunc_expense(queryInfo, disjunct2);
- selec1 = compute_clause_selec(queryInfo,
- disjunct1, LispNil);
- selec2 = compute_clause_selec(queryInfo,
- disjunct2, LispNil);
-
- if (selec1 == 0)
- rank1 = MAXFLOAT;
- else if (cost1 == 0)
- rank1 = 0;
- else
- rank1 = cost1/selec1;
-
- if (selec2 == 0)
- rank2 = MAXFLOAT;
- else if (cost2 == 0)
- rank2 = 0;
- else
- rank2 = cost2/selec2;
-
- if ( rank1 < rank2)
- return(-1);
- else if (rank1 == rank2)
- return(0);
- else return(1);
+ LispValue disjunct1 = *(LispValue *) arg1;
+ LispValue disjunct2 = *(LispValue *) arg2;
+ Cost cost1, /* total cost of disjunct1 */
+ cost2, /* total cost of disjunct2 */
+ selec1,
+ selec2;
+ Cost rank1,
+ rank2;
+
+ cost1 = xfunc_expense(queryInfo, disjunct1);
+ cost2 = xfunc_expense(queryInfo, disjunct2);
+ selec1 = compute_clause_selec(queryInfo,
+ disjunct1, LispNil);
+ selec2 = compute_clause_selec(queryInfo,
+ disjunct2, LispNil);
+
+ if (selec1 == 0)
+ rank1 = MAXFLOAT;
+ else if (cost1 == 0)
+ rank1 = 0;
+ else
+ rank1 = cost1 / selec1;
+
+ if (selec2 == 0)
+ rank2 = MAXFLOAT;
+ else if (cost2 == 0)
+ rank2 = 0;
+ else
+ rank2 = cost2 / selec2;
+
+ if (rank1 < rank2)
+ return (-1);
+ else if (rank1 == rank2)
+ return (0);
+ else
+ return (1);
}
/* ------------------------ UTILITY FUNCTIONS ------------------------------- */
@@ -1174,182 +1307,197 @@ int xfunc_disjunct_compare(Query* queryInfo, void *arg1, void *arg2)
** xfunc_func_width --
** Given a function OID and operands, find the width of the return value.
*/
-int xfunc_func_width(RegProcedure funcid, LispValue args)
+int
+xfunc_func_width(RegProcedure funcid, LispValue args)
{
- Relation rd; /* Relation Descriptor */
- HeapTuple tupl; /* structure to hold a cached tuple */
- Form_pg_proc proc; /* structure to hold the pg_proc tuple */
- TypeTupleForm type; /* structure to hold the pg_type tuple */
- LispValue tmpclause;
- int retval;
-
- /* lookup function and find its return type */
- Assert(RegProcedureIsValid(funcid));
- tupl = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(funcid), 0,0,0);
- if (!HeapTupleIsValid(tupl))
- elog(WARN, "Cache lookup failed for procedure %d", funcid);
- proc = (Form_pg_proc) GETSTRUCT(tupl);
-
- /* if function returns a tuple, get the width of that */
- if (typeid_get_relid(proc->prorettype))
+ Relation rd; /* Relation Descriptor */
+ HeapTuple tupl; /* structure to hold a cached tuple */
+ Form_pg_proc proc; /* structure to hold the pg_proc tuple */
+ TypeTupleForm type; /* structure to hold the pg_type tuple */
+ LispValue tmpclause;
+ int retval;
+
+ /* lookup function and find its return type */
+ Assert(RegProcedureIsValid(funcid));
+ tupl = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(funcid), 0, 0, 0);
+ if (!HeapTupleIsValid(tupl))
+ elog(WARN, "Cache lookup failed for procedure %d", funcid);
+ proc = (Form_pg_proc) GETSTRUCT(tupl);
+
+ /* if function returns a tuple, get the width of that */
+ if (typeid_get_relid(proc->prorettype))
{
- rd = heap_open(typeid_get_relid(proc->prorettype));
- retval = xfunc_tuple_width(rd);
- heap_close(rd);
- goto exit;
+ rd = heap_open(typeid_get_relid(proc->prorettype));
+ retval = xfunc_tuple_width(rd);
+ heap_close(rd);
+ goto exit;
}
- else /* function returns a base type */
+ else
+/* function returns a base type */
{
- tupl = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(proc->prorettype),
- 0,0,0);
- if (!HeapTupleIsValid(tupl))
- elog(WARN, "Cache lookup failed for type %d", proc->prorettype);
- type = (TypeTupleForm) GETSTRUCT(tupl);
- /* if the type length is known, return that */
- if (type->typlen != -1)
+ tupl = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(proc->prorettype),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tupl))
+ elog(WARN, "Cache lookup failed for type %d", proc->prorettype);
+ type = (TypeTupleForm) GETSTRUCT(tupl);
+ /* if the type length is known, return that */
+ if (type->typlen != -1)
{
- retval = type->typlen;
- goto exit;
+ retval = type->typlen;
+ goto exit;
}
- else /* estimate the return size */
+ else
+/* estimate the return size */
{
- /* find width of the function's arguments */
- for (tmpclause = args; tmpclause != LispNil;
- tmpclause = lnext(tmpclause))
- retval += xfunc_width(lfirst(tmpclause));
- /* multiply by outin_ratio */
- retval = (int)(proc->prooutin_ratio/100.0 * retval);
- goto exit;
+ /* find width of the function's arguments */
+ for (tmpclause = args; tmpclause != LispNil;
+ tmpclause = lnext(tmpclause))
+ retval += xfunc_width(lfirst(tmpclause));
+ /* multiply by outin_ratio */
+ retval = (int) (proc->prooutin_ratio / 100.0 * retval);
+ goto exit;
}
}
- exit:
- return(retval);
+exit:
+ return (retval);
}
/*
** xfunc_tuple_width --
- ** Return the sum of the lengths of all the attributes of a given relation
+ ** Return the sum of the lengths of all the attributes of a given relation
*/
-int xfunc_tuple_width(Relation rd)
+int
+xfunc_tuple_width(Relation rd)
{
- int i;
- int retval = 0;
- TupleDesc tdesc = RelationGetTupleDescriptor(rd);
-
- for (i = 0; i < tdesc->natts; i++)
+ int i;
+ int retval = 0;
+ TupleDesc tdesc = RelationGetTupleDescriptor(rd);
+
+ for (i = 0; i < tdesc->natts; i++)
{
- if (tdesc->attrs[i]->attlen != -1)
- retval += tdesc->attrs[i]->attlen;
- else retval += VARLEN_DEFAULT;
+ if (tdesc->attrs[i]->attlen != -1)
+ retval += tdesc->attrs[i]->attlen;
+ else
+ retval += VARLEN_DEFAULT;
}
-
- return(retval);
+
+ return (retval);
}
/*
** xfunc_num_join_clauses --
** Find the number of join clauses associated with this join path
*/
-int xfunc_num_join_clauses(JoinPath path)
+int
+xfunc_num_join_clauses(JoinPath path)
{
- int num = length(get_pathclauseinfo(path));
- if (IsA(path,MergePath))
- return(num + length(get_path_mergeclauses((MergePath)path)));
- else if (IsA(path,HashPath))
- return(num + length(get_path_hashclauses((HashPath)path)));
- else return(num);
+ int num = length(get_pathclauseinfo(path));
+
+ if (IsA(path, MergePath))
+ return (num + length(get_path_mergeclauses((MergePath) path)));
+ else if (IsA(path, HashPath))
+ return (num + length(get_path_hashclauses((HashPath) path)));
+ else
+ return (num);
}
/*
** xfunc_LispRemove --
** Just like LispRemove, but it whines if the item to be removed ain't there
*/
-LispValue xfunc_LispRemove(LispValue foo, List bar)
+LispValue
+xfunc_LispRemove(LispValue foo, List bar)
{
- LispValue temp = LispNil;
- LispValue result = LispNil;
- int sanity = false;
-
- for (temp = bar; !null(temp); temp = lnext(temp))
- if (! equal((Node)(foo),(Node)(lfirst(temp))) )
- {
- result = lappend(result,lfirst(temp));
- }
- else sanity = true; /* found a matching item to remove! */
-
- if (!sanity)
- elog(WARN, "xfunc_LispRemove: didn't find a match!");
-
- return(result);
+ LispValue temp = LispNil;
+ LispValue result = LispNil;
+ int sanity = false;
+
+ for (temp = bar; !null(temp); temp = lnext(temp))
+ if (!equal((Node) (foo), (Node) (lfirst(temp))))
+ {
+ result = lappend(result, lfirst(temp));
+ }
+ else
+ sanity = true; /* found a matching item to remove! */
+
+ if (!sanity)
+ elog(WARN, "xfunc_LispRemove: didn't find a match!");
+
+ return (result);
}
#define Node_Copy(a, b, c, d) \
- if (NodeCopy((Node)((a)->d), (Node*)&((b)->d), c) != true) { \
- return false; \
- }
+ if (NodeCopy((Node)((a)->d), (Node*)&((b)->d), c) != true) { \
+ return false; \
+ }
/*
** xfunc_copyrel --
** Just like _copyRel, but doesn't copy the paths
*/
-bool xfunc_copyrel(Rel from, Rel *to)
+bool
+xfunc_copyrel(Rel from, Rel * to)
{
- Rel newnode;
- Pointer (*alloc)() = palloc;
-
- /* COPY_CHECKARGS() */
- if (to == NULL)
- {
- return false;
- }
-
- /* COPY_CHECKNULL() */
- if (from == NULL)
+ Rel newnode;
+
+ Pointer(*alloc) () = palloc;
+
+ /* COPY_CHECKARGS() */
+ if (to == NULL)
+ {
+ return false;
+ }
+
+ /* COPY_CHECKNULL() */
+ if (from == NULL)
{
- (*to) = NULL;
- return true;
- }
-
- /* COPY_NEW(c) */
- newnode = (Rel)(*alloc)(classSize(Rel));
- if (newnode == NULL)
- {
- return false;
- }
-
- /* ----------------
- * copy node superclass fields
- * ----------------
- */
- CopyNodeFields((Node)from, (Node)newnode, alloc);
-
- /* ----------------
- * copy remainder of node
- * ----------------
- */
- Node_Copy(from, newnode, alloc, relids);
-
- newnode->indexed = from->indexed;
- newnode->pages = from->pages;
- newnode->tuples = from->tuples;
- newnode->size = from->size;
- newnode->width = from->width;
-
- Node_Copy(from, newnode, alloc, targetlist);
- /* No!!!! Node_Copy(from, newnode, alloc, pathlist);
- Node_Copy(from, newnode, alloc, unorderedpath);
- Node_Copy(from, newnode, alloc, cheapestpath); */
-#if 0 /* can't use Node_copy now. 2/95 -ay */
- Node_Copy(from, newnode, alloc, classlist);
- Node_Copy(from, newnode, alloc, indexkeys);
- Node_Copy(from, newnode, alloc, ordering);
+ (*to) = NULL;
+ return true;
+ }
+
+ /* COPY_NEW(c) */
+ newnode = (Rel) (*alloc) (classSize(Rel));
+ if (newnode == NULL)
+ {
+ return false;
+ }
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyNodeFields((Node) from, (Node) newnode, alloc);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, alloc, relids);
+
+ newnode->indexed = from->indexed;
+ newnode->pages = from->pages;
+ newnode->tuples = from->tuples;
+ newnode->size = from->size;
+ newnode->width = from->width;
+
+ Node_Copy(from, newnode, alloc, targetlist);
+
+ /*
+ * No!!!! Node_Copy(from, newnode, alloc, pathlist);
+ * Node_Copy(from, newnode, alloc, unorderedpath); Node_Copy(from,
+ * newnode, alloc, cheapestpath);
+ */
+#if 0 /* can't use Node_copy now. 2/95 -ay */
+ Node_Copy(from, newnode, alloc, classlist);
+ Node_Copy(from, newnode, alloc, indexkeys);
+ Node_Copy(from, newnode, alloc, ordering);
#endif
- Node_Copy(from, newnode, alloc, clauseinfo);
- Node_Copy(from, newnode, alloc, joininfo);
- Node_Copy(from, newnode, alloc, innerjoin);
- Node_Copy(from, newnode, alloc, superrels);
-
- (*to) = newnode;
- return true;
+ Node_Copy(from, newnode, alloc, clauseinfo);
+ Node_Copy(from, newnode, alloc, joininfo);
+ Node_Copy(from, newnode, alloc, innerjoin);
+ Node_Copy(from, newnode, alloc, superrels);
+
+ (*to) = newnode;
+ return true;
}
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 7637d15f200..bdceec18be3 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* createplan.c--
- * Routines to create the desired plan for processing a query
+ * Routines to create the desired plan for processing a query
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.11 1997/04/24 15:59:58 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.12 1997/09/07 04:43:57 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -41,766 +41,836 @@
#include "optimizer/internal.h"
-#define TEMP_SORT 1
+#define TEMP_SORT 1
#define TEMP_MATERIAL 2
-static List *switch_outer(List *clauses);
-static Scan *create_scan_node(Path *best_path, List *tlist);
-static Join *create_join_node(JoinPath *best_path, List *tlist);
-static SeqScan *create_seqscan_node(Path *best_path, List *tlist,
- List *scan_clauses);
-static IndexScan *create_indexscan_node(IndexPath *best_path, List *tlist,
- List *scan_clauses);
-static NestLoop *create_nestloop_node(JoinPath *best_path, List *tlist,
- List *clauses, Plan *outer_node, List *outer_tlist,
- Plan *inner_node, List *inner_tlist);
-static MergeJoin *create_mergejoin_node(MergePath *best_path, List *tlist,
- List *clauses, Plan *outer_node, List *outer_tlist,
- Plan *inner_node, List *inner_tlist);
-static HashJoin *create_hashjoin_node(HashPath *best_path, List *tlist,
- List *clauses, Plan *outer_node, List *outer_tlist,
- Plan *inner_node, List *inner_tlist);
-static Node *fix_indxqual_references(Node *clause, Path *index_path);
-static Temp *make_temp(List *tlist, List *keys, Oid *operators,
- Plan *plan_node, int temptype);
-static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
- List *indxid, List *indxqual);
-static NestLoop *make_nestloop(List *qptlist, List *qpqual, Plan *lefttree,
- Plan *righttree);
-static HashJoin *make_hashjoin(List *tlist, List *qpqual,
- List *hashclauses, Plan *lefttree, Plan *righttree);
-static Hash *make_hash(List *tlist, Var *hashkey, Plan *lefttree);
-static MergeJoin *make_mergesort(List * tlist, List *qpqual,
- List *mergeclauses, Oid opcode, Oid *rightorder,
- Oid *leftorder, Plan *righttree, Plan *lefttree);
-static Material *make_material(List *tlist, Oid tempid, Plan *lefttree,
- int keycount);
-
-/*
+static List *switch_outer(List * clauses);
+static Scan *create_scan_node(Path * best_path, List * tlist);
+static Join *create_join_node(JoinPath * best_path, List * tlist);
+static SeqScan *
+create_seqscan_node(Path * best_path, List * tlist,
+ List * scan_clauses);
+static IndexScan *
+create_indexscan_node(IndexPath * best_path, List * tlist,
+ List * scan_clauses);
+static NestLoop *
+create_nestloop_node(JoinPath * best_path, List * tlist,
+ List * clauses, Plan * outer_node, List * outer_tlist,
+ Plan * inner_node, List * inner_tlist);
+static MergeJoin *
+create_mergejoin_node(MergePath * best_path, List * tlist,
+ List * clauses, Plan * outer_node, List * outer_tlist,
+ Plan * inner_node, List * inner_tlist);
+static HashJoin *
+create_hashjoin_node(HashPath * best_path, List * tlist,
+ List * clauses, Plan * outer_node, List * outer_tlist,
+ Plan * inner_node, List * inner_tlist);
+static Node *fix_indxqual_references(Node * clause, Path * index_path);
+static Temp *
+make_temp(List * tlist, List * keys, Oid * operators,
+ Plan * plan_node, int temptype);
+static IndexScan *
+make_indexscan(List * qptlist, List * qpqual, Index scanrelid,
+ List * indxid, List * indxqual);
+static NestLoop *
+make_nestloop(List * qptlist, List * qpqual, Plan * lefttree,
+ Plan * righttree);
+static HashJoin *
+make_hashjoin(List * tlist, List * qpqual,
+ List * hashclauses, Plan * lefttree, Plan * righttree);
+static Hash *make_hash(List * tlist, Var * hashkey, Plan * lefttree);
+static MergeJoin *
+make_mergesort(List * tlist, List * qpqual,
+ List * mergeclauses, Oid opcode, Oid * rightorder,
+ Oid * leftorder, Plan * righttree, Plan * lefttree);
+static Material *
+make_material(List * tlist, Oid tempid, Plan * lefttree,
+ int keycount);
+
+/*
* create_plan--
- * Creates the access plan for a query by tracing backwards through the
- * desired chain of pathnodes, starting at the node 'best-path'. For
- * every pathnode found:
- * (1) Create a corresponding plan node containing appropriate id,
- * target list, and qualification information.
- * (2) Modify ALL clauses so that attributes are referenced using
- * relative values.
- * (3) Target lists are not modified, but will be in another routine.
- *
- * best-path is the best access path
+ * Creates the access plan for a query by tracing backwards through the
+ * desired chain of pathnodes, starting at the node 'best-path'. For
+ * every pathnode found:
+ * (1) Create a corresponding plan node containing appropriate id,
+ * target list, and qualification information.
+ * (2) Modify ALL clauses so that attributes are referenced using
+ * relative values.
+ * (3) Target lists are not modified, but will be in another routine.
+ *
+ * best-path is the best access path
*
- * Returns the optimal(?) access plan.
+ * Returns the optimal(?) access plan.
*/
-Plan *
-create_plan(Path *best_path)
+Plan *
+create_plan(Path * best_path)
{
- List *tlist;
- Plan *plan_node = (Plan*)NULL;
- Rel *parent_rel;
- int size;
- int width;
- int pages;
- int tuples;
-
- parent_rel = best_path->parent;
- tlist = get_actual_tlist(parent_rel->targetlist);
- size = parent_rel->size;
- width = parent_rel->width;
- pages = parent_rel->pages;
- tuples = parent_rel->tuples;
-
- switch(best_path->pathtype) {
- case T_IndexScan :
- case T_SeqScan :
- plan_node = (Plan*)create_scan_node(best_path, tlist);
- break;
- case T_HashJoin :
- case T_MergeJoin :
- case T_NestLoop:
- plan_node = (Plan*)create_join_node((JoinPath*)best_path, tlist);
- break;
- default:
- /* do nothing */
- break;
- }
-
- plan_node->plan_size = size;
- plan_node->plan_width = width;
- if (pages == 0) pages = 1;
- plan_node->plan_tupperpage = tuples/pages;
-
-#if 0 /* fix xfunc */
- /* sort clauses by cost/(1-selectivity) -- JMH 2/26/92 */
- if (XfuncMode != XFUNC_OFF)
+ List *tlist;
+ Plan *plan_node = (Plan *) NULL;
+ Rel *parent_rel;
+ int size;
+ int width;
+ int pages;
+ int tuples;
+
+ parent_rel = best_path->parent;
+ tlist = get_actual_tlist(parent_rel->targetlist);
+ size = parent_rel->size;
+ width = parent_rel->width;
+ pages = parent_rel->pages;
+ tuples = parent_rel->tuples;
+
+ switch (best_path->pathtype)
{
- set_qpqual((Plan) plan_node,
- lisp_qsort( get_qpqual((Plan) plan_node),
- xfunc_clause_compare));
- if (XfuncMode != XFUNC_NOR)
- /* sort the disjuncts within each clause by cost -- JMH 3/4/92 */
- xfunc_disjunct_sort(plan_node->qpqual);
+ case T_IndexScan:
+ case T_SeqScan:
+ plan_node = (Plan *) create_scan_node(best_path, tlist);
+ break;
+ case T_HashJoin:
+ case T_MergeJoin:
+ case T_NestLoop:
+ plan_node = (Plan *) create_join_node((JoinPath *) best_path, tlist);
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+
+ plan_node->plan_size = size;
+ plan_node->plan_width = width;
+ if (pages == 0)
+ pages = 1;
+ plan_node->plan_tupperpage = tuples / pages;
+
+#if 0 /* fix xfunc */
+ /* sort clauses by cost/(1-selectivity) -- JMH 2/26/92 */
+ if (XfuncMode != XFUNC_OFF)
+ {
+ set_qpqual((Plan) plan_node,
+ lisp_qsort(get_qpqual((Plan) plan_node),
+ xfunc_clause_compare));
+ if (XfuncMode != XFUNC_NOR)
+ /* sort the disjuncts within each clause by cost -- JMH 3/4/92 */
+ xfunc_disjunct_sort(plan_node->qpqual);
}
#endif
-
- return(plan_node);
+
+ return (plan_node);
}
-/*
+/*
* create_scan_node--
- * Create a scan path for the parent relation of 'best-path'.
- *
- * tlist is the targetlist for the base relation scanned by 'best-path'
- *
- * Returns the scan node.
+ * Create a scan path for the parent relation of 'best-path'.
+ *
+ * tlist is the targetlist for the base relation scanned by 'best-path'
+ *
+ * Returns the scan node.
*/
-static Scan *
-create_scan_node(Path *best_path, List *tlist)
+static Scan *
+create_scan_node(Path * best_path, List * tlist)
{
- Scan *node = NULL ;
- List *scan_clauses;
-
- /*
- * Extract the relevant clauses from the parent relation and replace the
- * operator OIDs with the corresponding regproc ids.
- *
- * now that local predicate clauses are copied into paths in
- * find_rel_paths() and then (possibly) pulled up in xfunc_trypullup(),
- * we get the relevant clauses from the path itself, not its parent
- * relation. --- JMH, 6/15/92
- */
- scan_clauses = fix_opids(get_actual_clauses(best_path->locclauseinfo));
-
- switch(best_path->pathtype) {
- case T_SeqScan :
- node = (Scan*)create_seqscan_node(best_path, tlist, scan_clauses);
- break;
-
- case T_IndexScan:
- node = (Scan*)create_indexscan_node((IndexPath*)best_path,
- tlist,
- scan_clauses);
- break;
-
- default :
- elog(WARN, "create_scan_node: unknown node type",
- best_path->pathtype);
- break;
- }
-
- return node;
+ Scan *node = NULL;
+ List *scan_clauses;
+
+ /*
+ * Extract the relevant clauses from the parent relation and replace
+ * the operator OIDs with the corresponding regproc ids.
+ *
+ * now that local predicate clauses are copied into paths in
+ * find_rel_paths() and then (possibly) pulled up in
+ * xfunc_trypullup(), we get the relevant clauses from the path
+ * itself, not its parent relation. --- JMH, 6/15/92
+ */
+ scan_clauses = fix_opids(get_actual_clauses(best_path->locclauseinfo));
+
+ switch (best_path->pathtype)
+ {
+ case T_SeqScan:
+ node = (Scan *) create_seqscan_node(best_path, tlist, scan_clauses);
+ break;
+
+ case T_IndexScan:
+ node = (Scan *) create_indexscan_node((IndexPath *) best_path,
+ tlist,
+ scan_clauses);
+ break;
+
+ default:
+ elog(WARN, "create_scan_node: unknown node type",
+ best_path->pathtype);
+ break;
+ }
+
+ return node;
}
-/*
+/*
* create_join_node --
- * Create a join path for 'best-path' and(recursively) paths for its
- * inner and outer paths.
- *
- * 'tlist' is the targetlist for the join relation corresponding to
- * 'best-path'
- *
- * Returns the join node.
+ * Create a join path for 'best-path' and(recursively) paths for its
+ * inner and outer paths.
+ *
+ * 'tlist' is the targetlist for the join relation corresponding to
+ * 'best-path'
+ *
+ * Returns the join node.
*/
-static Join *
-create_join_node(JoinPath *best_path, List *tlist)
+static Join *
+create_join_node(JoinPath * best_path, List * tlist)
{
- Plan *outer_node;
- List *outer_tlist;
- Plan *inner_node;
- List *inner_tlist;
- List *clauses;
- Join *retval = NULL;
-
- outer_node = create_plan((Path*)best_path->outerjoinpath);
- outer_tlist = outer_node->targetlist;
-
- inner_node = create_plan((Path*)best_path->innerjoinpath);
- inner_tlist = inner_node->targetlist;
-
- clauses = get_actual_clauses(best_path->pathclauseinfo);
-
- switch(best_path->path.pathtype) {
- case T_MergeJoin:
- retval = (Join*)create_mergejoin_node((MergePath*)best_path,
- tlist,
- clauses,
- outer_node,
- outer_tlist,
- inner_node,
- inner_tlist);
- break;
- case T_HashJoin:
- retval = (Join*)create_hashjoin_node((HashPath*)best_path,
- tlist,
- clauses,
- outer_node,
- outer_tlist,
- inner_node,
- inner_tlist);
- break;
- case T_NestLoop:
- retval = (Join*)create_nestloop_node((JoinPath*)best_path,
- tlist,
- clauses,
- outer_node,
- outer_tlist,
- inner_node,
- inner_tlist);
- break;
- default:
- /* do nothing */
- elog(WARN, "create_join_node: unknown node type",
- best_path->path.pathtype);
- }
+ Plan *outer_node;
+ List *outer_tlist;
+ Plan *inner_node;
+ List *inner_tlist;
+ List *clauses;
+ Join *retval = NULL;
+
+ outer_node = create_plan((Path *) best_path->outerjoinpath);
+ outer_tlist = outer_node->targetlist;
+
+ inner_node = create_plan((Path *) best_path->innerjoinpath);
+ inner_tlist = inner_node->targetlist;
+
+ clauses = get_actual_clauses(best_path->pathclauseinfo);
+
+ switch (best_path->path.pathtype)
+ {
+ case T_MergeJoin:
+ retval = (Join *) create_mergejoin_node((MergePath *) best_path,
+ tlist,
+ clauses,
+ outer_node,
+ outer_tlist,
+ inner_node,
+ inner_tlist);
+ break;
+ case T_HashJoin:
+ retval = (Join *) create_hashjoin_node((HashPath *) best_path,
+ tlist,
+ clauses,
+ outer_node,
+ outer_tlist,
+ inner_node,
+ inner_tlist);
+ break;
+ case T_NestLoop:
+ retval = (Join *) create_nestloop_node((JoinPath *) best_path,
+ tlist,
+ clauses,
+ outer_node,
+ outer_tlist,
+ inner_node,
+ inner_tlist);
+ break;
+ default:
+ /* do nothing */
+ elog(WARN, "create_join_node: unknown node type",
+ best_path->path.pathtype);
+ }
#if 0
- /*
- ** Expensive function pullups may have pulled local predicates
- ** into this path node. Put them in the qpqual of the plan node.
- ** -- JMH, 6/15/92
- */
- if (get_locclauseinfo(best_path) != NIL)
- set_qpqual((Plan)retval,
- nconc(get_qpqual((Plan) retval),
- fix_opids(get_actual_clauses
- (get_locclauseinfo(best_path)))));
+
+ /*
+ * * Expensive function pullups may have pulled local predicates *
+ * into this path node. Put them in the qpqual of the plan node. *
+ * -- JMH, 6/15/92
+ */
+ if (get_locclauseinfo(best_path) != NIL)
+ set_qpqual((Plan) retval,
+ nconc(get_qpqual((Plan) retval),
+ fix_opids(get_actual_clauses
+ (get_locclauseinfo(best_path)))));
#endif
- return(retval);
+ return (retval);
}
/*****************************************************************************
*
- * BASE-RELATION SCAN METHODS
+ * BASE-RELATION SCAN METHODS
*
*****************************************************************************/
-
-/*
+
+/*
* create_seqscan_node--
- * Returns a seqscan node for the base relation scanned by 'best-path'
- * with restriction clauses 'scan-clauses' and targetlist 'tlist'.
+ * Returns a seqscan node for the base relation scanned by 'best-path'
+ * with restriction clauses 'scan-clauses' and targetlist 'tlist'.
*/
static SeqScan *
-create_seqscan_node(Path *best_path, List *tlist, List *scan_clauses)
+create_seqscan_node(Path * best_path, List * tlist, List * scan_clauses)
{
- SeqScan *scan_node = (SeqScan*)NULL;
- Index scan_relid = -1;
- List *temp;
-
- temp = best_path->parent->relids;
- if(temp == NULL)
- elog(WARN,"scanrelid is empty");
- else
- scan_relid = (Index)lfirsti(temp); /* ??? who takes care of lnext? - ay */
- scan_node = make_seqscan(tlist,
- scan_clauses,
- scan_relid,
- (Plan*)NULL);
-
- scan_node->plan.cost = best_path->path_cost;
-
- return(scan_node);
+ SeqScan *scan_node = (SeqScan *) NULL;
+ Index scan_relid = -1;
+ List *temp;
+
+ temp = best_path->parent->relids;
+ if (temp == NULL)
+ elog(WARN, "scanrelid is empty");
+ else
+ scan_relid = (Index) lfirsti(temp); /* ??? who takes care of
+ * lnext? - ay */
+ scan_node = make_seqscan(tlist,
+ scan_clauses,
+ scan_relid,
+ (Plan *) NULL);
+
+ scan_node->plan.cost = best_path->path_cost;
+
+ return (scan_node);
}
-/*
+/*
* create_indexscan_node--
- * Returns a indexscan node for the base relation scanned by 'best-path'
- * with restriction clauses 'scan-clauses' and targetlist 'tlist'.
+ * Returns a indexscan node for the base relation scanned by 'best-path'
+ * with restriction clauses 'scan-clauses' and targetlist 'tlist'.
*/
static IndexScan *
-create_indexscan_node(IndexPath *best_path,
- List *tlist,
- List *scan_clauses)
+create_indexscan_node(IndexPath * best_path,
+ List * tlist,
+ List * scan_clauses)
{
- /*
- * Extract the(first if conjunct, only if disjunct) clause from the
- * clauseinfo list.
- */
- Expr *index_clause = (Expr*)NULL;
- List *indxqual = NIL;
- List *qpqual = NIL;
- List *fixed_indxqual = NIL;
- List *ixid;
- IndexScan *scan_node = (IndexScan*)NULL;
- bool lossy = FALSE;
- HeapTuple indexTuple;
- IndexTupleForm index;
-
- /*
- * If an 'or' clause is to be used with this index, the indxqual
- * field will contain a list of the 'or' clause arguments, e.g., the
- * clause(OR a b c) will generate: ((a) (b) (c)). Otherwise, the
- * indxqual will simply contain one conjunctive qualification: ((a)).
- */
- if (best_path->indexqual != NULL)
- /* added call to fix_opids, JMH 6/23/92 */
- index_clause = (Expr*)
- lfirst(fix_opids(get_actual_clauses(best_path->indexqual)));
-
- if (or_clause((Node*)index_clause)) {
- List *temp = NIL;
-
- foreach(temp, index_clause->args)
- indxqual = lappend(indxqual, lcons(lfirst(temp), NIL));
- } else {
- indxqual = lcons(get_actual_clauses(best_path->indexqual),
- NIL);
- }
-
- /* check and see if any indices are lossy */
- foreach (ixid, best_path->indexid) {
- indexTuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(lfirsti(ixid)),
- 0,0,0);
- if (!HeapTupleIsValid(indexTuple))
- elog(WARN, "create_plan: index %d not found",
- lfirsti(ixid));
- index = (IndexTupleForm)GETSTRUCT(indexTuple);
- if (index->indislossy)
- lossy = TRUE;
- }
-
-
- /*
- * The qpqual field contains all restrictions not automatically handled
- * by the index. Note that for non-lossy indices, the predicates
- * in the indxqual are handled by the index, while for lossy indices
- * the indxqual predicates need to be double-checked after the
- * index fetches the best-guess tuples.
- */
- if(or_clause((Node*)index_clause)) {
- qpqual = set_difference(scan_clauses,
- lcons(index_clause,NIL));
-
- if (lossy)
- qpqual = nconc(qpqual,
- lcons((List *)copyObject(index_clause),NIL));
- }
- else {
- qpqual = set_difference(scan_clauses, lfirst(indxqual));
- if (lossy)
- qpqual = nconc(qpqual,
- (List *)copyObject(lfirst(indxqual)));
- }
-
- fixed_indxqual =
- (List*)fix_indxqual_references((Node*)indxqual,(Path*)best_path);
-
- scan_node =
- make_indexscan(tlist,
- qpqual,
- lfirsti(best_path->path.parent->relids),
- best_path->indexid,
- fixed_indxqual);
-
- scan_node->scan.plan.cost = best_path->path.path_cost;
-
- return(scan_node);
+
+ /*
+ * Extract the(first if conjunct, only if disjunct) clause from the
+ * clauseinfo list.
+ */
+ Expr *index_clause = (Expr *) NULL;
+ List *indxqual = NIL;
+ List *qpqual = NIL;
+ List *fixed_indxqual = NIL;
+ List *ixid;
+ IndexScan *scan_node = (IndexScan *) NULL;
+ bool lossy = FALSE;
+ HeapTuple indexTuple;
+ IndexTupleForm index;
+
+ /*
+ * If an 'or' clause is to be used with this index, the indxqual field
+ * will contain a list of the 'or' clause arguments, e.g., the
+ * clause(OR a b c) will generate: ((a) (b) (c)). Otherwise, the
+ * indxqual will simply contain one conjunctive qualification: ((a)).
+ */
+ if (best_path->indexqual != NULL)
+ /* added call to fix_opids, JMH 6/23/92 */
+ index_clause = (Expr *)
+ lfirst(fix_opids(get_actual_clauses(best_path->indexqual)));
+
+ if (or_clause((Node *) index_clause))
+ {
+ List *temp = NIL;
+
+ foreach(temp, index_clause->args)
+ indxqual = lappend(indxqual, lcons(lfirst(temp), NIL));
+ }
+ else
+ {
+ indxqual = lcons(get_actual_clauses(best_path->indexqual),
+ NIL);
+ }
+
+ /* check and see if any indices are lossy */
+ foreach(ixid, best_path->indexid)
+ {
+ indexTuple = SearchSysCacheTuple(INDEXRELID,
+ ObjectIdGetDatum(lfirsti(ixid)),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(indexTuple))
+ elog(WARN, "create_plan: index %d not found",
+ lfirsti(ixid));
+ index = (IndexTupleForm) GETSTRUCT(indexTuple);
+ if (index->indislossy)
+ lossy = TRUE;
+ }
+
+
+ /*
+ * The qpqual field contains all restrictions not automatically
+ * handled by the index. Note that for non-lossy indices, the
+ * predicates in the indxqual are handled by the index, while for
+ * lossy indices the indxqual predicates need to be double-checked
+ * after the index fetches the best-guess tuples.
+ */
+ if (or_clause((Node *) index_clause))
+ {
+ qpqual = set_difference(scan_clauses,
+ lcons(index_clause, NIL));
+
+ if (lossy)
+ qpqual = nconc(qpqual,
+ lcons((List *) copyObject(index_clause), NIL));
+ }
+ else
+ {
+ qpqual = set_difference(scan_clauses, lfirst(indxqual));
+ if (lossy)
+ qpqual = nconc(qpqual,
+ (List *) copyObject(lfirst(indxqual)));
+ }
+
+ fixed_indxqual =
+ (List *) fix_indxqual_references((Node *) indxqual, (Path *) best_path);
+
+ scan_node =
+ make_indexscan(tlist,
+ qpqual,
+ lfirsti(best_path->path.parent->relids),
+ best_path->indexid,
+ fixed_indxqual);
+
+ scan_node->scan.plan.cost = best_path->path.path_cost;
+
+ return (scan_node);
}
/*****************************************************************************
*
- * JOIN METHODS
+ * JOIN METHODS
*
*****************************************************************************/
static NestLoop *
-create_nestloop_node(JoinPath *best_path,
- List *tlist,
- List *clauses,
- Plan *outer_node,
- List *outer_tlist,
- Plan *inner_node,
- List *inner_tlist)
+create_nestloop_node(JoinPath * best_path,
+ List * tlist,
+ List * clauses,
+ Plan * outer_node,
+ List * outer_tlist,
+ Plan * inner_node,
+ List * inner_tlist)
{
- NestLoop *join_node = (NestLoop*)NULL;
+ NestLoop *join_node = (NestLoop *) NULL;
- if (IsA(inner_node,IndexScan)) {
- /* An index is being used to reduce the number of tuples scanned in
- * the inner relation. There will never be more than one index used
- * in the inner scan path, so we need only consider the first set of
- * qualifications in indxqual.
- *
- * But there may be more than one clauses in this "first set"
- * in the case of multi-column indices. - vadim 03/18/97
- */
+ if (IsA(inner_node, IndexScan))
+ {
- List *inner_indxqual = lfirst(((IndexScan*)inner_node)->indxqual);
- List *inner_qual;
- bool found = false;
+ /*
+ * An index is being used to reduce the number of tuples scanned
+ * in the inner relation. There will never be more than one index
+ * used in the inner scan path, so we need only consider the first
+ * set of qualifications in indxqual.
+ *
+ * But there may be more than one clauses in this "first set" in the
+ * case of multi-column indices. - vadim 03/18/97
+ */
+
+ List *inner_indxqual = lfirst(((IndexScan *) inner_node)->indxqual);
+ List *inner_qual;
+ bool found = false;
+
+ foreach(inner_qual, inner_indxqual)
+ {
+ if (!qual_clause_p((Node *) lfirst(inner_qual)))
+ {
+ found = true;
+ break;
+ }
+ }
- foreach (inner_qual, inner_indxqual)
- {
- if ( !qual_clause_p ((Node*)lfirst(inner_qual)) )
- {
- found = true;
- break;
- }
+ /*
+ * If we have in fact found a join index qualification, remove
+ * these index clauses from the nestloop's join clauses and reset
+ * the inner(index) scan's qualification so that the var nodes
+ * refer to the proper outer join relation attributes.
+ *
+ * XXX Re-moving index clauses doesn't work properly: 1.
+ * fix_indxqual_references may change varattno-s in
+ * inner_indxqual; 2. clauses may be commuted I havn't time to fix
+ * it at the moment. - vadim 04/24/97
+ */
+ if (found)
+ {
+ List *new_inner_qual = NIL;
+
+ clauses = set_difference(clauses, inner_indxqual); /* XXX */
+ new_inner_qual =
+ index_outerjoin_references(inner_indxqual,
+ outer_node->targetlist,
+ ((Scan *) inner_node)->scanrelid);
+ ((IndexScan *) inner_node)->indxqual =
+ lcons(new_inner_qual, NIL);
+ }
}
-
- /* If we have in fact found a join index qualification, remove these
- * index clauses from the nestloop's join clauses and reset the
- * inner(index) scan's qualification so that the var nodes refer to
- * the proper outer join relation attributes.
- *
- * XXX Re-moving index clauses doesn't work properly:
- * 1. fix_indxqual_references may change varattno-s in
- * inner_indxqual;
- * 2. clauses may be commuted
- * I havn't time to fix it at the moment. - vadim 04/24/97
- */
- if ( found )
+ else if (IsA_Join(inner_node))
{
- List *new_inner_qual = NIL;
-
- clauses = set_difference(clauses,inner_indxqual); /* XXX */
- new_inner_qual =
- index_outerjoin_references(inner_indxqual,
- outer_node->targetlist,
- ((Scan*)inner_node)->scanrelid);
- ((IndexScan*)inner_node)->indxqual =
- lcons(new_inner_qual,NIL);
+ inner_node = (Plan *) make_temp(inner_tlist,
+ NIL,
+ NULL,
+ inner_node,
+ TEMP_MATERIAL);
}
- }else if (IsA_Join(inner_node)) {
- inner_node = (Plan*)make_temp(inner_tlist,
- NIL,
- NULL,
- inner_node,
- TEMP_MATERIAL);
- }
-
- join_node = make_nestloop(tlist,
- join_references(clauses,
- outer_tlist,
- inner_tlist),
- outer_node,
- inner_node);
-
- join_node->join.cost = best_path->path.path_cost;
-
- return(join_node);
+
+ join_node = make_nestloop(tlist,
+ join_references(clauses,
+ outer_tlist,
+ inner_tlist),
+ outer_node,
+ inner_node);
+
+ join_node->join.cost = best_path->path.path_cost;
+
+ return (join_node);
}
static MergeJoin *
-create_mergejoin_node(MergePath *best_path,
- List *tlist,
- List *clauses,
- Plan *outer_node,
- List *outer_tlist,
- Plan *inner_node,
- List *inner_tlist)
+create_mergejoin_node(MergePath * best_path,
+ List * tlist,
+ List * clauses,
+ Plan * outer_node,
+ List * outer_tlist,
+ Plan * inner_node,
+ List * inner_tlist)
{
- List *qpqual, *mergeclauses;
- RegProcedure opcode;
- Oid *outer_order, *inner_order;
- MergeJoin *join_node;
-
-
- /* Separate the mergeclauses from the other join qualification
- * clauses and set those clauses to contain references to lower
- * attributes.
- */
- qpqual = join_references(set_difference(clauses,
- best_path->path_mergeclauses),
- outer_tlist,
- inner_tlist);
-
- /* Now set the references in the mergeclauses and rearrange them so
- * that the outer variable is always on the left.
- */
- mergeclauses = switch_outer(join_references(best_path->path_mergeclauses,
- outer_tlist,
- inner_tlist));
-
- opcode =
- get_opcode((best_path->jpath.path.p_ordering.ord.merge)->join_operator);
-
- outer_order = (Oid *)palloc(sizeof(Oid)*2);
- outer_order[0] =
- (best_path->jpath.path.p_ordering.ord.merge)->left_operator;
- outer_order[1] = 0;
-
- inner_order = (Oid *)palloc(sizeof(Oid)*2);
- inner_order[0] =
- (best_path->jpath.path.p_ordering.ord.merge)->right_operator;
- inner_order[1] = 0;
-
- /* Create explicit sort paths for the outer and inner join paths if
- * necessary. The sort cost was already accounted for in the path.
- */
- if (best_path->outersortkeys) {
- Temp *sorted_outer_node = make_temp(outer_tlist,
- best_path->outersortkeys,
- outer_order,
- outer_node,
- TEMP_SORT);
- sorted_outer_node->plan.cost = outer_node->cost;
- outer_node = (Plan*)sorted_outer_node;
- }
-
- if (best_path->innersortkeys) {
- Temp *sorted_inner_node = make_temp(inner_tlist,
- best_path->innersortkeys,
- inner_order,
- inner_node,
- TEMP_SORT);
- sorted_inner_node->plan.cost = outer_node->cost;
- inner_node = (Plan*)sorted_inner_node;
- }
-
- join_node = make_mergesort(tlist,
- qpqual,
- mergeclauses,
- opcode,
- inner_order,
- outer_order,
- inner_node,
- outer_node);
-
- join_node->join.cost = best_path->jpath.path.path_cost;
-
- return(join_node);
+ List *qpqual,
+ *mergeclauses;
+ RegProcedure opcode;
+ Oid *outer_order,
+ *inner_order;
+ MergeJoin *join_node;
+
+
+ /*
+ * Separate the mergeclauses from the other join qualification clauses
+ * and set those clauses to contain references to lower attributes.
+ */
+ qpqual = join_references(set_difference(clauses,
+ best_path->path_mergeclauses),
+ outer_tlist,
+ inner_tlist);
+
+ /*
+ * Now set the references in the mergeclauses and rearrange them so
+ * that the outer variable is always on the left.
+ */
+ mergeclauses = switch_outer(join_references(best_path->path_mergeclauses,
+ outer_tlist,
+ inner_tlist));
+
+ opcode =
+ get_opcode((best_path->jpath.path.p_ordering.ord.merge)->join_operator);
+
+ outer_order = (Oid *) palloc(sizeof(Oid) * 2);
+ outer_order[0] =
+ (best_path->jpath.path.p_ordering.ord.merge)->left_operator;
+ outer_order[1] = 0;
+
+ inner_order = (Oid *) palloc(sizeof(Oid) * 2);
+ inner_order[0] =
+ (best_path->jpath.path.p_ordering.ord.merge)->right_operator;
+ inner_order[1] = 0;
+
+ /*
+ * Create explicit sort paths for the outer and inner join paths if
+ * necessary. The sort cost was already accounted for in the path.
+ */
+ if (best_path->outersortkeys)
+ {
+ Temp *sorted_outer_node = make_temp(outer_tlist,
+ best_path->outersortkeys,
+ outer_order,
+ outer_node,
+ TEMP_SORT);
+
+ sorted_outer_node->plan.cost = outer_node->cost;
+ outer_node = (Plan *) sorted_outer_node;
+ }
+
+ if (best_path->innersortkeys)
+ {
+ Temp *sorted_inner_node = make_temp(inner_tlist,
+ best_path->innersortkeys,
+ inner_order,
+ inner_node,
+ TEMP_SORT);
+
+ sorted_inner_node->plan.cost = outer_node->cost;
+ inner_node = (Plan *) sorted_inner_node;
+ }
+
+ join_node = make_mergesort(tlist,
+ qpqual,
+ mergeclauses,
+ opcode,
+ inner_order,
+ outer_order,
+ inner_node,
+ outer_node);
+
+ join_node->join.cost = best_path->jpath.path.path_cost;
+
+ return (join_node);
}
-/*
- * create_hashjoin_node-- XXX HASH
- *
- * Returns a new hashjoin node.
- *
- * XXX hash join ops are totally bogus -- how the hell do we choose
- * these?? at runtime? what about a hash index?
+/*
+ * create_hashjoin_node-- XXX HASH
+ *
+ * Returns a new hashjoin node.
+ *
+ * XXX hash join ops are totally bogus -- how the hell do we choose
+ * these?? at runtime? what about a hash index?
*/
static HashJoin *
-create_hashjoin_node(HashPath *best_path,
- List *tlist,
- List *clauses,
- Plan *outer_node,
- List *outer_tlist,
- Plan *inner_node,
- List *inner_tlist)
+create_hashjoin_node(HashPath * best_path,
+ List * tlist,
+ List * clauses,
+ Plan * outer_node,
+ List * outer_tlist,
+ Plan * inner_node,
+ List * inner_tlist)
{
- List *qpqual;
- List *hashclauses;
- HashJoin *join_node;
- Hash *hash_node;
- Var *innerhashkey;
-
- /* Separate the hashclauses from the other join qualification clauses
- * and set those clauses to contain references to lower attributes.
- */
- qpqual =
- join_references(set_difference(clauses,
- best_path->path_hashclauses),
- outer_tlist,
- inner_tlist);
-
- /* Now set the references in the hashclauses and rearrange them so
- * that the outer variable is always on the left.
- */
- hashclauses =
- switch_outer(join_references(best_path->path_hashclauses,
- outer_tlist,
- inner_tlist));
-
- innerhashkey = get_rightop(lfirst(hashclauses));
-
- hash_node = make_hash(inner_tlist, innerhashkey, inner_node);
- join_node = make_hashjoin(tlist,
- qpqual,
- hashclauses,
- outer_node,
- (Plan*)hash_node);
- join_node->join.cost = best_path->jpath.path.path_cost;
-
- return(join_node);
+ List *qpqual;
+ List *hashclauses;
+ HashJoin *join_node;
+ Hash *hash_node;
+ Var *innerhashkey;
+
+ /*
+ * Separate the hashclauses from the other join qualification clauses
+ * and set those clauses to contain references to lower attributes.
+ */
+ qpqual =
+ join_references(set_difference(clauses,
+ best_path->path_hashclauses),
+ outer_tlist,
+ inner_tlist);
+
+ /*
+ * Now set the references in the hashclauses and rearrange them so
+ * that the outer variable is always on the left.
+ */
+ hashclauses =
+ switch_outer(join_references(best_path->path_hashclauses,
+ outer_tlist,
+ inner_tlist));
+
+ innerhashkey = get_rightop(lfirst(hashclauses));
+
+ hash_node = make_hash(inner_tlist, innerhashkey, inner_node);
+ join_node = make_hashjoin(tlist,
+ qpqual,
+ hashclauses,
+ outer_node,
+ (Plan *) hash_node);
+ join_node->join.cost = best_path->jpath.path.path_cost;
+
+ return (join_node);
}
/*****************************************************************************
*
- * SUPPORTING ROUTINES
+ * SUPPORTING ROUTINES
*
*****************************************************************************/
-static Node *
-fix_indxqual_references(Node *clause, Path *index_path)
+static Node *
+fix_indxqual_references(Node * clause, Path * index_path)
{
- Node *newclause;
-
- if (IsA(clause,Var)) {
- if (lfirsti(index_path->parent->relids) == ((Var*)clause)->varno) {
- int pos = 0;
- int varatt = ((Var*)clause)->varattno;
- int *indexkeys = ((IndexPath*)index_path)->indexkeys;
-
- if (indexkeys) {
- while (indexkeys[pos] != 0) {
- if(varatt == indexkeys[pos]) {
- break;
- }
- pos++;
+ Node *newclause;
+
+ if (IsA(clause, Var))
+ {
+ if (lfirsti(index_path->parent->relids) == ((Var *) clause)->varno)
+ {
+ int pos = 0;
+ int varatt = ((Var *) clause)->varattno;
+ int *indexkeys = ((IndexPath *) index_path)->indexkeys;
+
+ if (indexkeys)
+ {
+ while (indexkeys[pos] != 0)
+ {
+ if (varatt == indexkeys[pos])
+ {
+ break;
+ }
+ pos++;
+ }
+ }
+ newclause = copyObject((Node *) clause);
+ ((Var *) newclause)->varattno = pos + 1;
+ return (newclause);
+ }
+ else
+ {
+ return (clause);
}
- }
- newclause = copyObject((Node*)clause);
- ((Var*)newclause)->varattno = pos + 1;
- return (newclause);
- } else {
- return (clause);
}
- } else if(IsA(clause,Const)) {
- return(clause);
+ else if (IsA(clause, Const))
+ {
+ return (clause);
#ifdef INDEXSCAN_PATCH
- } else if(IsA(clause,Param)) {
- /* Function parameter used as index scan arg. DZ - 27-8-1996 */
- return(clause);
+ }
+ else if (IsA(clause, Param))
+ {
+ /* Function parameter used as index scan arg. DZ - 27-8-1996 */
+ return (clause);
#endif
- } else if(is_opclause(clause) &&
- is_funcclause((Node*)get_leftop((Expr*)clause)) &&
- ((Func*)((Expr*)get_leftop((Expr*)clause))->oper)->funcisindex){
- Var *newvar =
- makeVar((Index)lfirsti(index_path->parent->relids),
- 1, /* func indices have one key */
- ((Func*)((Expr*)clause)->oper)->functype,
- (Index)lfirsti(index_path->parent->relids),
- 0);
-
- return
- ((Node*)make_opclause((Oper*)((Expr*)clause)->oper,
- newvar,
- get_rightop((Expr*)clause)));
-
- } else if (IsA(clause,Expr)) {
- Expr *expr = (Expr*)clause;
- List *new_subclauses = NIL;
- Node *subclause = NULL;
- List *i = NIL;
-
- foreach(i, expr->args) {
- subclause = lfirst(i);
- if(subclause)
- new_subclauses =
- lappend(new_subclauses,
- fix_indxqual_references(subclause,
- index_path));
+ }
+ else if (is_opclause(clause) &&
+ is_funcclause((Node *) get_leftop((Expr *) clause)) &&
+ ((Func *) ((Expr *) get_leftop((Expr *) clause))->oper)->funcisindex)
+ {
+ Var *newvar =
+ makeVar((Index) lfirsti(index_path->parent->relids),
+ 1, /* func indices have one key */
+ ((Func *) ((Expr *) clause)->oper)->functype,
+ (Index) lfirsti(index_path->parent->relids),
+ 0);
+
+ return
+ ((Node *) make_opclause((Oper *) ((Expr *) clause)->oper,
+ newvar,
+ get_rightop((Expr *) clause)));
}
-
- /* XXX new_subclauses should be a list of the form:
- * ( (var var) (var const) ...) ?
- */
- if(new_subclauses) {
- return (Node*)
- make_clause(expr->opType, expr->oper, new_subclauses);
- } else {
- return(clause);
- }
- } else {
- List *oldclauses = (List*)clause;
- List *new_subclauses = NIL;
- Node *subclause = NULL;
- List *i = NIL;
-
- foreach(i, oldclauses) {
- subclause = lfirst(i);
- if(subclause)
- new_subclauses =
- lappend(new_subclauses,
- fix_indxqual_references(subclause,
- index_path));
+ else if (IsA(clause, Expr))
+ {
+ Expr *expr = (Expr *) clause;
+ List *new_subclauses = NIL;
+ Node *subclause = NULL;
+ List *i = NIL;
+
+ foreach(i, expr->args)
+ {
+ subclause = lfirst(i);
+ if (subclause)
+ new_subclauses =
+ lappend(new_subclauses,
+ fix_indxqual_references(subclause,
+ index_path));
+
+ }
+
+ /*
+ * XXX new_subclauses should be a list of the form: ( (var var)
+ * (var const) ...) ?
+ */
+ if (new_subclauses)
+ {
+ return (Node *)
+ make_clause(expr->opType, expr->oper, new_subclauses);
+ }
+ else
+ {
+ return (clause);
+ }
+ }
+ else
+ {
+ List *oldclauses = (List *) clause;
+ List *new_subclauses = NIL;
+ Node *subclause = NULL;
+ List *i = NIL;
+
+ foreach(i, oldclauses)
+ {
+ subclause = lfirst(i);
+ if (subclause)
+ new_subclauses =
+ lappend(new_subclauses,
+ fix_indxqual_references(subclause,
+ index_path));
+
+ }
+ /*
+ * XXX new_subclauses should be a list of the form: ( (var var)
+ * (var const) ...) ?
+ */
+ if (new_subclauses)
+ {
+ return (Node *) new_subclauses;
+ }
+ else
+ {
+ return (clause);
+ }
}
-
- /* XXX new_subclauses should be a list of the form:
- * ( (var var) (var const) ...) ?
- */
- if(new_subclauses) {
- return (Node*)new_subclauses;
- } else {
- return (clause);
- }
- }
}
-/*
+/*
* switch_outer--
- * Given a list of merge clauses, rearranges the elements within the
- * clauses so the outer join variable is on the left and the inner is on
- * the right.
- *
- * Returns the rearranged list ?
- *
- * XXX Shouldn't the operator be commuted?!
+ * Given a list of merge clauses, rearranges the elements within the
+ * clauses so the outer join variable is on the left and the inner is on
+ * the right.
+ *
+ * Returns the rearranged list ?
+ *
+ * XXX Shouldn't the operator be commuted?!
*/
-static List *
-switch_outer(List *clauses)
+static List *
+switch_outer(List * clauses)
{
- List *t_list = NIL;
- Expr *temp = NULL;
- List *i = NIL;
- Expr *clause;
- Node *op;
-
- foreach(i,clauses) {
- clause = lfirst(i);
- op = (Node*)get_rightop(clause);
- if ( IsA (op, ArrayRef) )
- op = ((ArrayRef*)op)->refexpr;
- Assert ( IsA (op, Var) );
- if ( var_is_outer ((Var*)op) )
+ List *t_list = NIL;
+ Expr *temp = NULL;
+ List *i = NIL;
+ Expr *clause;
+ Node *op;
+
+ foreach(i, clauses)
{
- temp = make_clause(clause->opType, clause->oper,
- lcons(get_rightop(clause),
- lcons(get_leftop(clause),
- NIL)));
- t_list = lappend(t_list,temp);
- }
- else
- t_list = lappend(t_list,clause);
- }
- return(t_list);
+ clause = lfirst(i);
+ op = (Node *) get_rightop(clause);
+ if (IsA(op, ArrayRef))
+ op = ((ArrayRef *) op)->refexpr;
+ Assert(IsA(op, Var));
+ if (var_is_outer((Var *) op))
+ {
+ temp = make_clause(clause->opType, clause->oper,
+ lcons(get_rightop(clause),
+ lcons(get_leftop(clause),
+ NIL)));
+ t_list = lappend(t_list, temp);
+ }
+ else
+ t_list = lappend(t_list, clause);
+ }
+ return (t_list);
}
-/*
+/*
* set-temp-tlist-operators--
- * Sets the key and keyop fields of resdom nodes in a target list.
- *
- * 'tlist' is the target list
- * 'pathkeys' is a list of N keys in the form((key1) (key2)...(keyn)),
- * corresponding to vars in the target list that are to
- * be sorted or hashed
- * 'operators' is the corresponding list of N sort or hash operators
- * 'keyno' is the first key number
- * XXX - keyno ? doesn't exist - jeff
- *
- * Returns the modified target list.
+ * Sets the key and keyop fields of resdom nodes in a target list.
+ *
+ * 'tlist' is the target list
+ * 'pathkeys' is a list of N keys in the form((key1) (key2)...(keyn)),
+ * corresponding to vars in the target list that are to
+ * be sorted or hashed
+ * 'operators' is the corresponding list of N sort or hash operators
+ * 'keyno' is the first key number
+ * XXX - keyno ? doesn't exist - jeff
+ *
+ * Returns the modified target list.
*/
-static List *
-set_temp_tlist_operators(List *tlist, List *pathkeys, Oid *operators)
+static List *
+set_temp_tlist_operators(List * tlist, List * pathkeys, Oid * operators)
{
- Node *keys = NULL;
- int keyno = 1;
- Resdom *resdom = (Resdom*)NULL ;
- List *i = NIL;
-
- foreach(i, pathkeys) {
- keys = lfirst((List*)lfirst(i));
- resdom = tlist_member((Var*)keys, tlist);
- if (resdom) {
-
- /* Order the resdom keys and replace the operator OID for each
- * key with the regproc OID.
- *
- * XXX Note that the optimizer only generates merge joins
- * with 1 operator (see create_mergejoin_node) - ay 2/95
- */
- resdom->reskey = keyno;
- resdom->reskeyop = get_opcode(operators[0]);
+ Node *keys = NULL;
+ int keyno = 1;
+ Resdom *resdom = (Resdom *) NULL;
+ List *i = NIL;
+
+ foreach(i, pathkeys)
+ {
+ keys = lfirst((List *) lfirst(i));
+ resdom = tlist_member((Var *) keys, tlist);
+ if (resdom)
+ {
+
+ /*
+ * Order the resdom keys and replace the operator OID for each
+ * key with the regproc OID.
+ *
+ * XXX Note that the optimizer only generates merge joins with 1
+ * operator (see create_mergejoin_node) - ay 2/95
+ */
+ resdom->reskey = keyno;
+ resdom->reskeyop = get_opcode(operators[0]);
+ }
+ keyno += 1;
}
- keyno += 1;
- }
- return(tlist);
+ return (tlist);
}
/*****************************************************************************
@@ -808,355 +878,362 @@ set_temp_tlist_operators(List *tlist, List *pathkeys, Oid *operators)
*
*****************************************************************************/
-/*
+/*
* make_temp--
- * Create plan nodes to sort or materialize relations into temporaries. The
- * result returned for a sort will look like (SEQSCAN(SORT(plan-node)))
- * or (SEQSCAN(MATERIAL(plan-node)))
- *
- * 'tlist' is the target list of the scan to be sorted or hashed
- * 'keys' is the list of keys which the sort or hash will be done on
- * 'operators' is the operators with which the sort or hash is to be done
- * (a list of operator OIDs)
- * 'plan-node' is the node which yields tuples for the sort
- * 'temptype' indicates which operation(sort or hash) to perform
+ * Create plan nodes to sort or materialize relations into temporaries. The
+ * result returned for a sort will look like (SEQSCAN(SORT(plan-node)))
+ * or (SEQSCAN(MATERIAL(plan-node)))
+ *
+ * 'tlist' is the target list of the scan to be sorted or hashed
+ * 'keys' is the list of keys which the sort or hash will be done on
+ * 'operators' is the operators with which the sort or hash is to be done
+ * (a list of operator OIDs)
+ * 'plan-node' is the node which yields tuples for the sort
+ * 'temptype' indicates which operation(sort or hash) to perform
*/
-static Temp *
-make_temp(List *tlist,
- List *keys,
- Oid *operators,
- Plan *plan_node,
- int temptype)
+static Temp *
+make_temp(List * tlist,
+ List * keys,
+ Oid * operators,
+ Plan * plan_node,
+ int temptype)
{
- List *temp_tlist;
- Temp *retval = NULL;
-
- /* Create a new target list for the temporary, with keys set. */
- temp_tlist = set_temp_tlist_operators(new_unsorted_tlist(tlist),
- keys,
- operators);
- switch(temptype) {
- case TEMP_SORT :
- retval = (Temp*)make_seqscan(tlist,
- NIL,
- _TEMP_RELATION_ID_,
- (Plan*)make_sort(temp_tlist,
- _TEMP_RELATION_ID_,
- plan_node,
- length(keys)));
- break;
-
- case TEMP_MATERIAL :
- retval = (Temp*)make_seqscan(tlist,
- NIL,
- _TEMP_RELATION_ID_,
- (Plan*)make_material(temp_tlist,
- _TEMP_RELATION_ID_,
- plan_node,
- length(keys)));
- break;
-
- default:
- elog(WARN,"make_temp: unknown temp type %d", temptype);
-
- }
- return(retval);
+ List *temp_tlist;
+ Temp *retval = NULL;
+
+ /* Create a new target list for the temporary, with keys set. */
+ temp_tlist = set_temp_tlist_operators(new_unsorted_tlist(tlist),
+ keys,
+ operators);
+ switch (temptype)
+ {
+ case TEMP_SORT:
+ retval = (Temp *) make_seqscan(tlist,
+ NIL,
+ _TEMP_RELATION_ID_,
+ (Plan *) make_sort(temp_tlist,
+ _TEMP_RELATION_ID_,
+ plan_node,
+ length(keys)));
+ break;
+
+ case TEMP_MATERIAL:
+ retval = (Temp *) make_seqscan(tlist,
+ NIL,
+ _TEMP_RELATION_ID_,
+ (Plan *) make_material(temp_tlist,
+ _TEMP_RELATION_ID_,
+ plan_node,
+ length(keys)));
+ break;
+
+ default:
+ elog(WARN, "make_temp: unknown temp type %d", temptype);
+
+ }
+ return (retval);
}
-SeqScan *
-make_seqscan(List *qptlist,
- List *qpqual,
- Index scanrelid,
- Plan *lefttree)
+SeqScan *
+make_seqscan(List * qptlist,
+ List * qpqual,
+ Index scanrelid,
+ Plan * lefttree)
{
- SeqScan *node = makeNode(SeqScan);
- Plan *plan = &node->plan;
-
- plan->cost = 0.0;
- plan->state = (EState *)NULL;
- plan->targetlist = qptlist;
- plan->qual = qpqual;
- plan->lefttree = lefttree;
- plan->righttree = NULL;
- node->scanrelid = scanrelid;
- node->scanstate = (CommonScanState *)NULL;
-
- return(node);
+ SeqScan *node = makeNode(SeqScan);
+ Plan *plan = &node->plan;
+
+ plan->cost = 0.0;
+ plan->state = (EState *) NULL;
+ plan->targetlist = qptlist;
+ plan->qual = qpqual;
+ plan->lefttree = lefttree;
+ plan->righttree = NULL;
+ node->scanrelid = scanrelid;
+ node->scanstate = (CommonScanState *) NULL;
+
+ return (node);
}
static IndexScan *
-make_indexscan(List *qptlist,
- List *qpqual,
- Index scanrelid,
- List *indxid,
- List *indxqual)
+make_indexscan(List * qptlist,
+ List * qpqual,
+ Index scanrelid,
+ List * indxid,
+ List * indxqual)
{
- IndexScan *node = makeNode(IndexScan);
- Plan *plan = &node->scan.plan;
-
- plan->cost = 0.0;
- plan->state = (EState *)NULL;
- plan->targetlist = qptlist;
- plan->qual = qpqual;
- plan->lefttree = NULL;
- plan->righttree = NULL;
- node->scan.scanrelid = scanrelid;
- node->indxid = indxid;
- node->indxqual = indxqual;
- node->scan.scanstate = (CommonScanState *)NULL;
-
- return(node);
+ IndexScan *node = makeNode(IndexScan);
+ Plan *plan = &node->scan.plan;
+
+ plan->cost = 0.0;
+ plan->state = (EState *) NULL;
+ plan->targetlist = qptlist;
+ plan->qual = qpqual;
+ plan->lefttree = NULL;
+ plan->righttree = NULL;
+ node->scan.scanrelid = scanrelid;
+ node->indxid = indxid;
+ node->indxqual = indxqual;
+ node->scan.scanstate = (CommonScanState *) NULL;
+
+ return (node);
}
static NestLoop *
-make_nestloop(List *qptlist,
- List *qpqual,
- Plan *lefttree,
- Plan *righttree)
+make_nestloop(List * qptlist,
+ List * qpqual,
+ Plan * lefttree,
+ Plan * righttree)
{
- NestLoop *node = makeNode(NestLoop);
- Plan *plan = &node->join;
-
- plan->cost = 0.0;
- plan->state = (EState *)NULL;
- plan->targetlist = qptlist;
- plan->qual = qpqual;
- plan->lefttree = lefttree;
- plan->righttree = righttree;
- node->nlstate = (NestLoopState*)NULL;
-
- return(node);
+ NestLoop *node = makeNode(NestLoop);
+ Plan *plan = &node->join;
+
+ plan->cost = 0.0;
+ plan->state = (EState *) NULL;
+ plan->targetlist = qptlist;
+ plan->qual = qpqual;
+ plan->lefttree = lefttree;
+ plan->righttree = righttree;
+ node->nlstate = (NestLoopState *) NULL;
+
+ return (node);
}
static HashJoin *
-make_hashjoin(List *tlist,
- List *qpqual,
- List *hashclauses,
- Plan *lefttree,
- Plan *righttree)
+make_hashjoin(List * tlist,
+ List * qpqual,
+ List * hashclauses,
+ Plan * lefttree,
+ Plan * righttree)
{
- HashJoin *node = makeNode(HashJoin);
- Plan *plan = &node->join;
-
- plan->cost = 0.0;
- plan->state = (EState *)NULL;
- plan->targetlist = tlist;
- plan->qual = qpqual;
- plan->lefttree = lefttree;
- plan->righttree = righttree;
- node->hashclauses = hashclauses;
- node->hashjointable = NULL;
- node->hashjointablekey = 0;
- node->hashjointablesize = 0;
- node->hashdone = false;
-
- return(node);
+ HashJoin *node = makeNode(HashJoin);
+ Plan *plan = &node->join;
+
+ plan->cost = 0.0;
+ plan->state = (EState *) NULL;
+ plan->targetlist = tlist;
+ plan->qual = qpqual;
+ plan->lefttree = lefttree;
+ plan->righttree = righttree;
+ node->hashclauses = hashclauses;
+ node->hashjointable = NULL;
+ node->hashjointablekey = 0;
+ node->hashjointablesize = 0;
+ node->hashdone = false;
+
+ return (node);
}
-static Hash *
-make_hash(List *tlist, Var *hashkey, Plan *lefttree)
+static Hash *
+make_hash(List * tlist, Var * hashkey, Plan * lefttree)
{
- Hash *node = makeNode(Hash);
- Plan *plan = &node->plan;
-
- plan->cost = 0.0;
- plan->state = (EState *)NULL;
- plan->targetlist = tlist;
- plan->qual = NULL;
- plan->lefttree = lefttree;
- plan->righttree = NULL;
- node->hashkey = hashkey;
- node->hashtable = NULL;
- node->hashtablekey = 0;
- node->hashtablesize = 0;
-
- return(node);
+ Hash *node = makeNode(Hash);
+ Plan *plan = &node->plan;
+
+ plan->cost = 0.0;
+ plan->state = (EState *) NULL;
+ plan->targetlist = tlist;
+ plan->qual = NULL;
+ plan->lefttree = lefttree;
+ plan->righttree = NULL;
+ node->hashkey = hashkey;
+ node->hashtable = NULL;
+ node->hashtablekey = 0;
+ node->hashtablesize = 0;
+
+ return (node);
}
static MergeJoin *
-make_mergesort(List *tlist,
- List *qpqual,
- List *mergeclauses,
- Oid opcode,
- Oid *rightorder,
- Oid *leftorder,
- Plan *righttree,
- Plan *lefttree)
+make_mergesort(List * tlist,
+ List * qpqual,
+ List * mergeclauses,
+ Oid opcode,
+ Oid * rightorder,
+ Oid * leftorder,
+ Plan * righttree,
+ Plan * lefttree)
{
- MergeJoin *node = makeNode(MergeJoin);
- Plan *plan = &node->join;
-
- plan->cost = 0.0;
- plan->state = (EState *)NULL;
- plan->targetlist = tlist;
- plan->qual = qpqual;
- plan->lefttree = lefttree;
- plan->righttree = righttree;
- node->mergeclauses = mergeclauses;
- node->mergesortop = opcode;
- node->mergerightorder = rightorder;
- node->mergeleftorder = leftorder;
-
- return(node);
+ MergeJoin *node = makeNode(MergeJoin);
+ Plan *plan = &node->join;
+
+ plan->cost = 0.0;
+ plan->state = (EState *) NULL;
+ plan->targetlist = tlist;
+ plan->qual = qpqual;
+ plan->lefttree = lefttree;
+ plan->righttree = righttree;
+ node->mergeclauses = mergeclauses;
+ node->mergesortop = opcode;
+ node->mergerightorder = rightorder;
+ node->mergeleftorder = leftorder;
+
+ return (node);
}
-Sort *
-make_sort(List *tlist, Oid tempid, Plan *lefttree, int keycount)
+Sort *
+make_sort(List * tlist, Oid tempid, Plan * lefttree, int keycount)
{
- Sort *node = makeNode(Sort);
- Plan *plan = &node->plan;
-
- plan->cost = 0.0;
- plan->state = (EState *)NULL;
- plan->targetlist = tlist;
- plan->qual = NIL;
- plan->lefttree = lefttree;
- plan->righttree = NULL;
- node->tempid = tempid;
- node->keycount = keycount;
-
- return(node);
+ Sort *node = makeNode(Sort);
+ Plan *plan = &node->plan;
+
+ plan->cost = 0.0;
+ plan->state = (EState *) NULL;
+ plan->targetlist = tlist;
+ plan->qual = NIL;
+ plan->lefttree = lefttree;
+ plan->righttree = NULL;
+ node->tempid = tempid;
+ node->keycount = keycount;
+
+ return (node);
}
static Material *
-make_material(List *tlist,
- Oid tempid,
- Plan *lefttree,
- int keycount)
+make_material(List * tlist,
+ Oid tempid,
+ Plan * lefttree,
+ int keycount)
{
- Material *node = makeNode(Material);
- Plan *plan = &node->plan;
-
- plan->cost = 0.0;
- plan->state = (EState *)NULL;
- plan->targetlist = tlist;
- plan->qual = NIL;
- plan->lefttree = lefttree;
- plan->righttree = NULL;
- node->tempid = tempid;
- node->keycount = keycount;
-
- return(node);
+ Material *node = makeNode(Material);
+ Plan *plan = &node->plan;
+
+ plan->cost = 0.0;
+ plan->state = (EState *) NULL;
+ plan->targetlist = tlist;
+ plan->qual = NIL;
+ plan->lefttree = lefttree;
+ plan->righttree = NULL;
+ node->tempid = tempid;
+ node->keycount = keycount;
+
+ return (node);
}
-Agg *
-make_agg(List *tlist, int nagg, Aggreg **aggs)
+Agg *
+make_agg(List * tlist, int nagg, Aggreg ** aggs)
{
- Agg *node = makeNode(Agg);
-
- node->plan.cost = 0.0;
- node->plan.state = (EState*)NULL;
- node->plan.qual = NULL;
- node->plan.targetlist = tlist;
- node->plan.lefttree = (Plan*)NULL;
- node->plan.righttree = (Plan*)NULL;
- node->numAgg = nagg;
- node->aggs = aggs;
-
- return(node);
+ Agg *node = makeNode(Agg);
+
+ node->plan.cost = 0.0;
+ node->plan.state = (EState *) NULL;
+ node->plan.qual = NULL;
+ node->plan.targetlist = tlist;
+ node->plan.lefttree = (Plan *) NULL;
+ node->plan.righttree = (Plan *) NULL;
+ node->numAgg = nagg;
+ node->aggs = aggs;
+
+ return (node);
}
-Group *
-make_group(List *tlist,
- bool tuplePerGroup,
- int ngrp,
- AttrNumber *grpColIdx,
- Sort *lefttree)
+Group *
+make_group(List * tlist,
+ bool tuplePerGroup,
+ int ngrp,
+ AttrNumber * grpColIdx,
+ Sort * lefttree)
{
- Group *node = makeNode(Group);
-
- node->plan.cost = 0.0;
- node->plan.state = (EState*)NULL;
- node->plan.qual = NULL;
- node->plan.targetlist = tlist;
- node->plan.lefttree = (Plan*)lefttree;
- node->plan.righttree = (Plan*)NULL;
- node->tuplePerGroup = tuplePerGroup;
- node->numCols = ngrp;
- node->grpColIdx = grpColIdx;
-
- return(node);
+ Group *node = makeNode(Group);
+
+ node->plan.cost = 0.0;
+ node->plan.state = (EState *) NULL;
+ node->plan.qual = NULL;
+ node->plan.targetlist = tlist;
+ node->plan.lefttree = (Plan *) lefttree;
+ node->plan.righttree = (Plan *) NULL;
+ node->tuplePerGroup = tuplePerGroup;
+ node->numCols = ngrp;
+ node->grpColIdx = grpColIdx;
+
+ return (node);
}
/*
- * A unique node always has a SORT node in the lefttree.
+ * A unique node always has a SORT node in the lefttree.
*
- * the uniqueAttr argument must be a null-terminated string,
- * either the name of the attribute to select unique on
+ * the uniqueAttr argument must be a null-terminated string,
+ * either the name of the attribute to select unique on
* or "*"
*/
-Unique *
-make_unique(List *tlist, Plan *lefttree, char* uniqueAttr)
+Unique *
+make_unique(List * tlist, Plan * lefttree, char *uniqueAttr)
{
- Unique *node = makeNode(Unique);
- Plan *plan = &node->plan;
-
- plan->cost = 0.0;
- plan->state = (EState *)NULL;
- plan->targetlist = tlist;
- plan->qual = NIL;
- plan->lefttree = lefttree;
- plan->righttree = NULL;
- node->tempid = _TEMP_RELATION_ID_;
- node->keycount = 0;
- if (strcmp(uniqueAttr,"*") == 0)
- node->uniqueAttr = NULL;
- else
- {
- node->uniqueAttr=pstrdup(uniqueAttr);
- }
- return(node);
+ Unique *node = makeNode(Unique);
+ Plan *plan = &node->plan;
+
+ plan->cost = 0.0;
+ plan->state = (EState *) NULL;
+ plan->targetlist = tlist;
+ plan->qual = NIL;
+ plan->lefttree = lefttree;
+ plan->righttree = NULL;
+ node->tempid = _TEMP_RELATION_ID_;
+ node->keycount = 0;
+ if (strcmp(uniqueAttr, "*") == 0)
+ node->uniqueAttr = NULL;
+ else
+ {
+ node->uniqueAttr = pstrdup(uniqueAttr);
+ }
+ return (node);
}
-List *generate_fjoin(List *tlist)
+List *
+generate_fjoin(List * tlist)
{
#if 0
- List tlistP;
- List newTlist = NIL;
- List fjoinList = NIL;
- int nIters = 0;
-
- /*
- * Break the target list into elements with Iter nodes,
- * and those without them.
- */
- foreach(tlistP, tlist) {
- List tlistElem;
-
- tlistElem = lfirst(tlistP);
- if (IsA(lsecond(tlistElem),Iter)) {
- nIters++;
- fjoinList = lappend(fjoinList, tlistElem);
- } else {
- newTlist = lappend(newTlist, tlistElem);
+ List tlistP;
+ List newTlist = NIL;
+ List fjoinList = NIL;
+ int nIters = 0;
+
+ /*
+ * Break the target list into elements with Iter nodes, and those
+ * without them.
+ */
+ foreach(tlistP, tlist)
+ {
+ List tlistElem;
+
+ tlistElem = lfirst(tlistP);
+ if (IsA(lsecond(tlistElem), Iter))
+ {
+ nIters++;
+ fjoinList = lappend(fjoinList, tlistElem);
+ }
+ else
+ {
+ newTlist = lappend(newTlist, tlistElem);
+ }
+ }
+
+ /*
+ * if we have an Iter node then we need to flatten.
+ */
+ if (nIters > 0)
+ {
+ List *inner;
+ List *tempList;
+ Fjoin *fjoinNode;
+ DatumPtr results = (DatumPtr) palloc(nIters * sizeof(Datum));
+ BoolPtr alwaysDone = (BoolPtr) palloc(nIters * sizeof(bool));
+
+ inner = lfirst(fjoinList);
+ fjoinList = lnext(fjoinList);
+ fjoinNode = (Fjoin) MakeFjoin(false,
+ nIters,
+ inner,
+ results,
+ alwaysDone);
+ tempList = lcons(fjoinNode, NIL);
+ tempList = nconc(tempList, fjoinList);
+ newTlist = lappend(newTlist, tempList);
}
- }
-
- /*
- * if we have an Iter node then we need to flatten.
- */
- if (nIters > 0) {
- List *inner;
- List *tempList;
- Fjoin *fjoinNode;
- DatumPtr results = (DatumPtr)palloc(nIters*sizeof(Datum));
- BoolPtr alwaysDone = (BoolPtr)palloc(nIters*sizeof(bool));
-
- inner = lfirst(fjoinList);
- fjoinList = lnext(fjoinList);
- fjoinNode = (Fjoin)MakeFjoin(false,
- nIters,
- inner,
- results,
- alwaysDone);
- tempList = lcons(fjoinNode, NIL);
- tempList = nconc(tempList, fjoinList);
- newTlist = lappend(newTlist, tempList);
- }
- return newTlist;
+ return newTlist;
#endif
- return tlist; /* do nothing for now - ay 10/94 */
+ return tlist; /* do nothing for now - ay 10/94 */
}
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 35b3969b702..62ff23f207e 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* initsplan.c--
- * Target list, qualification, joininfo initialization routines
+ * Target list, qualification, joininfo initialization routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.5 1997/04/24 16:04:23 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.6 1997/09/07 04:44:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,370 +33,397 @@
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
-extern int Quiet;
+extern int Quiet;
-static void add_clause_to_rels(Query *root, List *clause);
-static void add_join_clause_info_to_rels(Query *root, CInfo *clauseinfo,
- List *join_relids);
-static void add_vars_to_rels(Query *root, List *vars, List *join_relids);
+static void add_clause_to_rels(Query * root, List * clause);
+static void
+add_join_clause_info_to_rels(Query * root, CInfo * clauseinfo,
+ List * join_relids);
+static void add_vars_to_rels(Query * root, List * vars, List * join_relids);
-static MergeOrder *mergesortop(Expr *clause);
-static Oid hashjoinop(Expr *clause);
+static MergeOrder *mergesortop(Expr * clause);
+static Oid hashjoinop(Expr * clause);
/*****************************************************************************
*
- * TARGET LISTS
+ * TARGET LISTS
*
*****************************************************************************/
-/*
+/*
* initialize_rel_nodes--
- * Creates rel nodes for every relation mentioned in the target list
- * 'tlist' (if a node hasn't already been created) and adds them to
- * *query-relation-list*. Creates targetlist entries for each member of
- * 'tlist' and adds them to the tlist field of the appropriate rel node.
- *
- * Returns nothing.
+ * Creates rel nodes for every relation mentioned in the target list
+ * 'tlist' (if a node hasn't already been created) and adds them to
+ * *query-relation-list*. Creates targetlist entries for each member of
+ * 'tlist' and adds them to the tlist field of the appropriate rel node.
+ *
+ * Returns nothing.
*/
void
-initialize_base_rels_list(Query *root, List *tlist)
+initialize_base_rels_list(Query * root, List * tlist)
{
- List *tlist_vars = NIL;
- List *l = NIL;
- List *tvar = NIL;
-
- foreach (l, tlist) {
- TargetEntry *entry = (TargetEntry *) lfirst(l);
-
- tlist_vars = append(tlist_vars, pull_var_clause(entry->expr));
- }
-
- /* now, the target list only contains Var nodes */
- foreach (tvar, tlist_vars) {
- Var *var;
- Index varno;
- Rel *result;
-
- var = (Var*)lfirst(tvar);
- varno = var->varno;
- result = get_base_rel(root, varno);
-
- add_tl_element(result, var);
- }
+ List *tlist_vars = NIL;
+ List *l = NIL;
+ List *tvar = NIL;
+
+ foreach(l, tlist)
+ {
+ TargetEntry *entry = (TargetEntry *) lfirst(l);
+
+ tlist_vars = append(tlist_vars, pull_var_clause(entry->expr));
+ }
+
+ /* now, the target list only contains Var nodes */
+ foreach(tvar, tlist_vars)
+ {
+ Var *var;
+ Index varno;
+ Rel *result;
+
+ var = (Var *) lfirst(tvar);
+ varno = var->varno;
+ result = get_base_rel(root, varno);
+
+ add_tl_element(result, var);
+ }
}
/*
* add_missing_variables_to_base_rels -
- * If we have range variable(s) in the FROM clause that does not appear
- * in the target list nor qualifications, we add it to the base relation
- * list. 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.
+ * If we have range variable(s) in the FROM clause that does not appear
+ * in the target list nor qualifications, we add it to the base relation
+ * list. 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.
*/
void
-add_missing_vars_to_base_rels(Query *root, List *tlist)
+add_missing_vars_to_base_rels(Query * root, List * tlist)
{
- List *l;
- int varno;
-
- varno = 1;
- foreach (l, root->rtable) {
- RangeTblEntry *rte = (RangeTblEntry *)lfirst(l);
- List *relids;
- Rel *result;
- Var *var;
-
- relids = lconsi(varno, NIL);
- if (rte->inFromCl &&
- !rel_member(relids, root->base_relation_list_)) {
-
- var = makeVar(varno, -2 , 26, varno, -2);
- /* add it to base_relation_list_ */
- result = get_base_rel(root, varno);
- add_tl_element(result, var);
+ List *l;
+ int varno;
+
+ varno = 1;
+ foreach(l, root->rtable)
+ {
+ RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
+ List *relids;
+ Rel *result;
+ Var *var;
+
+ relids = lconsi(varno, NIL);
+ if (rte->inFromCl &&
+ !rel_member(relids, root->base_relation_list_))
+ {
+
+ var = makeVar(varno, -2, 26, varno, -2);
+ /* add it to base_relation_list_ */
+ result = get_base_rel(root, varno);
+ add_tl_element(result, var);
+ }
+ pfree(relids);
+ varno++;
}
- pfree(relids);
- varno++;
- }
- return;
+ return;
}
/*****************************************************************************
*
- * QUALIFICATIONS
+ * QUALIFICATIONS
*
*****************************************************************************/
-/*
+/*
* initialize-qualification--
- * Initializes ClauseInfo and JoinInfo fields of relation entries for all
- * relations appearing within clauses. Creates new relation entries if
- * necessary, adding them to *query-relation-list*.
- *
- * Returns nothing of interest.
+ * Initializes ClauseInfo and JoinInfo fields of relation entries for all
+ * relations appearing within clauses. Creates new relation entries if
+ * necessary, adding them to *query-relation-list*.
+ *
+ * Returns nothing of interest.
*/
void
-initialize_base_rels_jinfo(Query *root, List *clauses)
+initialize_base_rels_jinfo(Query * root, List * clauses)
{
- List *clause;
+ List *clause;
- foreach (clause, clauses) {
- add_clause_to_rels(root, lfirst(clause));
- }
- return;
+ foreach(clause, clauses)
+ {
+ add_clause_to_rels(root, lfirst(clause));
+ }
+ return;
}
-/*
+/*
* add-clause-to-rels--
- * Add clause information to either the 'ClauseInfo' or 'JoinInfo' field
- * of a relation entry(depending on whether or not the clause is a join)
- * by creating a new ClauseInfo node and setting appropriate fields
- * within the nodes.
- *
- * Returns nothing of interest.
+ * Add clause information to either the 'ClauseInfo' or 'JoinInfo' field
+ * of a relation entry(depending on whether or not the clause is a join)
+ * by creating a new ClauseInfo node and setting appropriate fields
+ * within the nodes.
+ *
+ * Returns nothing of interest.
*/
static void
-add_clause_to_rels(Query *root, List *clause)
+add_clause_to_rels(Query * root, List * clause)
{
- List *relids;
- List *vars;
- CInfo *clauseinfo = makeNode(CInfo);
+ List *relids;
+ List *vars;
+ CInfo *clauseinfo = makeNode(CInfo);
- /*
- * Retrieve all relids and vars contained within the clause.
- */
- clause_relids_vars((Node*)clause, &relids, &vars);
+ /*
+ * Retrieve all relids and vars contained within the clause.
+ */
+ clause_relids_vars((Node *) clause, &relids, &vars);
- clauseinfo->clause = (Expr*)clause;
- clauseinfo->notclause = contains_not((Node*)clause);
- clauseinfo->selectivity = 0;
- clauseinfo->indexids = NIL;
- clauseinfo->mergesortorder = (MergeOrder*)NULL;
- clauseinfo->hashjoinoperator = (Oid)0;
-
+ clauseinfo->clause = (Expr *) clause;
+ clauseinfo->notclause = contains_not((Node *) clause);
+ clauseinfo->selectivity = 0;
+ clauseinfo->indexids = NIL;
+ clauseinfo->mergesortorder = (MergeOrder *) NULL;
+ clauseinfo->hashjoinoperator = (Oid) 0;
- if(length(relids) == 1) {
- Rel *rel = get_base_rel(root, lfirsti(relids));
-
- /*
- * There is only one relation participating in 'clause',
- * so 'clause' must be a restriction clause.
- */
- /* the selectivity of the clause must be computed
- regardless of whether it's a restriction or a join clause */
- if (is_funcclause((Node*)clause))
- {
+ if (length(relids) == 1)
+ {
+ Rel *rel = get_base_rel(root, lfirsti(relids));
+
/*
- * XXX If we have a func clause set selectivity to 1/3,
- * really need a true selectivity function.
+ * There is only one relation participating in 'clause', so
+ * 'clause' must be a restriction clause.
*/
- clauseinfo->selectivity = (Cost)0.3333333;
- }
- else
- {
- clauseinfo->selectivity =
- compute_clause_selec(root, (Node*)clause,
- NIL);
- }
- rel->clauseinfo = lcons(clauseinfo,
- rel->clauseinfo);
- } else {
- /*
- * 'clause' is a join clause, since there is more than one
- * atom in the relid list.
- */
-
- if (is_funcclause((Node*)clause))
- {
+
/*
- * XXX If we have a func clause set selectivity to 1/3,
- * really need a true selectivity function.
+ * the selectivity of the clause must be computed regardless of
+ * whether it's a restriction or a join clause
*/
- clauseinfo->selectivity = (Cost)0.3333333;
- }
+ if (is_funcclause((Node *) clause))
+ {
+
+ /*
+ * XXX If we have a func clause set selectivity to 1/3, really
+ * need a true selectivity function.
+ */
+ clauseinfo->selectivity = (Cost) 0.3333333;
+ }
+ else
+ {
+ clauseinfo->selectivity =
+ compute_clause_selec(root, (Node *) clause,
+ NIL);
+ }
+ rel->clauseinfo = lcons(clauseinfo,
+ rel->clauseinfo);
+ }
else
- {
- clauseinfo->selectivity =
- compute_clause_selec(root, (Node*)clause,
- NIL);
- }
- add_join_clause_info_to_rels(root, clauseinfo, relids);
- add_vars_to_rels(root,vars, relids);
- }
+ {
+
+ /*
+ * 'clause' is a join clause, since there is more than one atom in
+ * the relid list.
+ */
+
+ if (is_funcclause((Node *) clause))
+ {
+
+ /*
+ * XXX If we have a func clause set selectivity to 1/3, really
+ * need a true selectivity function.
+ */
+ clauseinfo->selectivity = (Cost) 0.3333333;
+ }
+ else
+ {
+ clauseinfo->selectivity =
+ compute_clause_selec(root, (Node *) clause,
+ NIL);
+ }
+ add_join_clause_info_to_rels(root, clauseinfo, relids);
+ add_vars_to_rels(root, vars, relids);
+ }
}
-/*
+/*
* add-join-clause-info-to-rels--
- * For every relation participating in a join clause, add 'clauseinfo' to
- * the appropriate joininfo node(creating a new one and adding it to the
- * appropriate rel node if necessary).
- *
+ * For every relation participating in a join clause, add 'clauseinfo' to
+ * the appropriate joininfo node(creating a new one and adding it to the
+ * appropriate rel node if necessary).
+ *
* 'clauseinfo' describes the join clause
* 'join-relids' is the list of relations participating in the join clause
- *
+ *
* Returns nothing.
- *
+ *
*/
static void
-add_join_clause_info_to_rels(Query *root, CInfo *clauseinfo, List *join_relids)
+add_join_clause_info_to_rels(Query * root, CInfo * clauseinfo, List * join_relids)
{
- List *join_relid;
-
- foreach (join_relid, join_relids) {
- JInfo *joininfo;
- List *other_rels = NIL;
- List *rel;
-
- foreach (rel, join_relids)
- {
- if ( lfirsti(rel) != lfirsti(join_relid) )
- other_rels = lappendi (other_rels, lfirsti(rel));
- }
-
- joininfo =
- find_joininfo_node(get_base_rel(root, lfirsti(join_relid)),
- other_rels);
- joininfo->jinfoclauseinfo =
- lcons(copyObject((void*)clauseinfo), joininfo->jinfoclauseinfo);
-
- }
+ List *join_relid;
+
+ foreach(join_relid, join_relids)
+ {
+ JInfo *joininfo;
+ List *other_rels = NIL;
+ List *rel;
+
+ foreach(rel, join_relids)
+ {
+ if (lfirsti(rel) != lfirsti(join_relid))
+ other_rels = lappendi(other_rels, lfirsti(rel));
+ }
+
+ joininfo =
+ find_joininfo_node(get_base_rel(root, lfirsti(join_relid)),
+ other_rels);
+ joininfo->jinfoclauseinfo =
+ lcons(copyObject((void *) clauseinfo), joininfo->jinfoclauseinfo);
+
+ }
}
-/*
+/*
* add-vars-to-rels--
- * For each variable appearing in a clause,
- * (1) If a targetlist entry for the variable is not already present in
- * the appropriate relation's target list, add one.
- * (2) If a targetlist entry is already present, but the var is part of a
- * join clause, add the relids of the join relations to the JoinList
- * entry of the targetlist entry.
- *
- * 'vars' is the list of var nodes
- * 'join-relids' is the list of relids appearing in the join clause
- * (if this is a join clause)
- *
- * Returns nothing.
+ * For each variable appearing in a clause,
+ * (1) If a targetlist entry for the variable is not already present in
+ * the appropriate relation's target list, add one.
+ * (2) If a targetlist entry is already present, but the var is part of a
+ * join clause, add the relids of the join relations to the JoinList
+ * entry of the targetlist entry.
+ *
+ * 'vars' is the list of var nodes
+ * 'join-relids' is the list of relids appearing in the join clause
+ * (if this is a join clause)
+ *
+ * Returns nothing.
*/
static void
-add_vars_to_rels(Query *root, List *vars, List *join_relids)
+add_vars_to_rels(Query * root, List * vars, List * join_relids)
{
- Var *var;
- List *temp = NIL;
- Rel *rel = (Rel*)NULL;
- TargetEntry *tlistentry;
-
- foreach (temp, vars) {
- var = (Var*)lfirst(temp);
- rel = get_base_rel(root, var->varno);
- tlistentry = tlistentry_member(var, rel->targetlist);
- if(tlistentry==NULL)
- /* add a new entry */
- add_tl_element(rel, var);
- }
+ Var *var;
+ List *temp = NIL;
+ Rel *rel = (Rel *) NULL;
+ TargetEntry *tlistentry;
+
+ foreach(temp, vars)
+ {
+ var = (Var *) lfirst(temp);
+ rel = get_base_rel(root, var->varno);
+ tlistentry = tlistentry_member(var, rel->targetlist);
+ if (tlistentry == NULL)
+ /* add a new entry */
+ add_tl_element(rel, var);
+ }
}
/*****************************************************************************
*
- * JOININFO
+ * JOININFO
*
*****************************************************************************/
-/*
+/*
* initialize-join-clause-info--
- * Set the MergeSortable or HashJoinable field for every joininfo node
- * (within a rel node) and the MergeSortOrder or HashJoinOp field for
- * each clauseinfo node(within a joininfo node) for all relations in a
- * query.
- *
- * Returns nothing.
+ * Set the MergeSortable or HashJoinable field for every joininfo node
+ * (within a rel node) and the MergeSortOrder or HashJoinOp field for
+ * each clauseinfo node(within a joininfo node) for all relations in a
+ * query.
+ *
+ * Returns nothing.
*/
void
-initialize_join_clause_info(List *rel_list)
+initialize_join_clause_info(List * rel_list)
{
- List *x, *y, *z;
- Rel *rel;
- JInfo *joininfo;
- CInfo *clauseinfo;
- Expr *clause;
-
- foreach (x, rel_list) {
- rel = (Rel*)lfirst(x);
- foreach (y, rel->joininfo) {
- joininfo = (JInfo*)lfirst(y);
- foreach (z, joininfo->jinfoclauseinfo) {
- clauseinfo = (CInfo*)lfirst(z);
- clause = clauseinfo->clause;
- if(join_clause_p((Node*)clause)) {
- MergeOrder *sortop = (MergeOrder*)NULL;
- Oid hashop = (Oid)NULL;
-
- if (_enable_mergesort_)
- sortop = mergesortop(clause);
- if (_enable_hashjoin_)
- hashop = hashjoinop(clause);
-
- if (sortop) {
- clauseinfo->mergesortorder = sortop;
- joininfo->mergesortable = true;
- }
- if (hashop) {
- clauseinfo->hashjoinoperator = hashop;
- joininfo->hashjoinable = true;
- }
+ List *x,
+ *y,
+ *z;
+ Rel *rel;
+ JInfo *joininfo;
+ CInfo *clauseinfo;
+ Expr *clause;
+
+ foreach(x, rel_list)
+ {
+ rel = (Rel *) lfirst(x);
+ foreach(y, rel->joininfo)
+ {
+ joininfo = (JInfo *) lfirst(y);
+ foreach(z, joininfo->jinfoclauseinfo)
+ {
+ clauseinfo = (CInfo *) lfirst(z);
+ clause = clauseinfo->clause;
+ if (join_clause_p((Node *) clause))
+ {
+ MergeOrder *sortop = (MergeOrder *) NULL;
+ Oid hashop = (Oid) NULL;
+
+ if (_enable_mergesort_)
+ sortop = mergesortop(clause);
+ if (_enable_hashjoin_)
+ hashop = hashjoinop(clause);
+
+ if (sortop)
+ {
+ clauseinfo->mergesortorder = sortop;
+ joininfo->mergesortable = true;
+ }
+ if (hashop)
+ {
+ clauseinfo->hashjoinoperator = hashop;
+ joininfo->hashjoinable = true;
+ }
+ }
+ }
}
- }
}
- }
}
-/*
+/*
* mergesortop--
- * Returns the mergesort operator of an operator iff 'clause' is
- * mergesortable, i.e., both operands are single vars and the operator is
- * a mergesortable operator.
+ * Returns the mergesort operator of an operator iff 'clause' is
+ * mergesortable, i.e., both operands are single vars and the operator is
+ * a mergesortable operator.
*/
static MergeOrder *
-mergesortop(Expr *clause)
+mergesortop(Expr * clause)
{
- Oid leftOp, rightOp;
- bool sortable;
-
- sortable = op_mergesortable(((Oper*)clause->oper)->opno,
- (get_leftop(clause))->vartype,
- (get_rightop(clause))->vartype,
- &leftOp,
- &rightOp);
-
- if (sortable) {
- MergeOrder *morder = makeNode(MergeOrder);
-
- morder->join_operator = ((Oper*)clause->oper)->opno;
- morder->left_operator = leftOp;
- morder->right_operator = rightOp;
- morder->left_type = (get_leftop(clause))->vartype;
- morder->right_type = (get_rightop(clause))->vartype;
- return (morder);
- } else
- return(NULL);
+ Oid leftOp,
+ rightOp;
+ bool sortable;
+
+ sortable = op_mergesortable(((Oper *) clause->oper)->opno,
+ (get_leftop(clause))->vartype,
+ (get_rightop(clause))->vartype,
+ &leftOp,
+ &rightOp);
+
+ if (sortable)
+ {
+ MergeOrder *morder = makeNode(MergeOrder);
+
+ morder->join_operator = ((Oper *) clause->oper)->opno;
+ morder->left_operator = leftOp;
+ morder->right_operator = rightOp;
+ morder->left_type = (get_leftop(clause))->vartype;
+ morder->right_type = (get_rightop(clause))->vartype;
+ return (morder);
+ }
+ else
+ return (NULL);
}
-/*
+/*
* hashjoinop--
- * Returns the hashjoin operator of an operator iff 'clause' is
- * hashjoinable, i.e., both operands are single vars and the operator is
- * a hashjoinable operator.
+ * Returns the hashjoin operator of an operator iff 'clause' is
+ * hashjoinable, i.e., both operands are single vars and the operator is
+ * a hashjoinable operator.
*/
-static Oid
-hashjoinop(Expr *clause)
+static Oid
+hashjoinop(Expr * clause)
{
- return(op_hashjoinable(((Oper*)clause->oper)->opno,
- (get_leftop(clause))->vartype,
- (get_rightop(clause))->vartype));
+ return (op_hashjoinable(((Oper *) clause->oper)->opno,
+ (get_leftop(clause))->vartype,
+ (get_rightop(clause))->vartype));
}
diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c
index 7f70d76ac6c..630ed12d2a1 100644
--- a/src/backend/optimizer/plan/planmain.c
+++ b/src/backend/optimizer/plan/planmain.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* planmain.c--
- * Routines to plan a single query
+ * Routines to plan a single query
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.4 1997/04/29 04:32:50 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.5 1997/09/07 04:44:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,506 +38,536 @@
#include "utils/mcxt.h"
#include "utils/lsyscache.h"
-static Plan *subplanner(Query *root, List *flat_tlist, List *qual);
-static Result *make_result(List *tlist, Node *resconstantqual, Plan *subplan);
+static Plan *subplanner(Query * root, List * flat_tlist, List * qual);
+static Result *make_result(List * tlist, Node * resconstantqual, Plan * subplan);
-static Plan *make_groupPlan(List **tlist, bool tuplePerGroup,
- List *groupClause, Plan *subplan);
+static Plan *
+make_groupPlan(List ** tlist, bool tuplePerGroup,
+ List * groupClause, Plan * subplan);
-/*
+/*
* query_planner--
- * Routine to create a query plan. It does so by first creating a
- * subplan for the topmost level of attributes in the query. Then,
- * it modifies all target list and qualifications to consider the next
- * level of nesting and creates a plan for this modified query by
- * recursively calling itself. The two pieces are then merged together
- * by creating a result node that indicates which attributes should
- * be placed where and any relation level qualifications to be
- * satisfied.
- *
- * command-type is the query command, e.g., retrieve, delete, etc.
- * tlist is the target list of the query
- * qual is the qualification of the query
- *
- * Returns a query plan.
+ * Routine to create a query plan. It does so by first creating a
+ * subplan for the topmost level of attributes in the query. Then,
+ * it modifies all target list and qualifications to consider the next
+ * level of nesting and creates a plan for this modified query by
+ * recursively calling itself. The two pieces are then merged together
+ * by creating a result node that indicates which attributes should
+ * be placed where and any relation level qualifications to be
+ * satisfied.
+ *
+ * command-type is the query command, e.g., retrieve, delete, etc.
+ * tlist is the target list of the query
+ * qual is the qualification of the query
+ *
+ * Returns a query plan.
*/
-Plan *
-query_planner(Query *root,
- int command_type,
- List *tlist,
- List *qual)
+Plan *
+query_planner(Query * root,
+ int command_type,
+ List * tlist,
+ List * qual)
{
- List *constant_qual = NIL;
- List *flattened_tlist = NIL;
- List *level_tlist = NIL;
- Plan *subplan = (Plan*)NULL;
- Agg *aggplan = NULL;
-
- /*
- * A command without a target list or qualification is an error,
- * except for "delete foo".
- */
- if (tlist==NIL && qual==NULL) {
- if (command_type == CMD_DELETE ||
- /* Total hack here. I don't know how to handle
- statements like notify in action bodies.
- Notify doesn't return anything but
- scans a system table. */
- command_type == CMD_NOTIFY) {
- return ((Plan*)make_seqscan(NIL,
- NIL,
- root->resultRelation,
- (Plan*)NULL));
- } else
- return((Plan*)NULL);
- }
-
- /*
- * Pull out any non-variable qualifications so these can be put in
- * the topmost result node. The opids for the remaining
- * qualifications will be changed to regprocs later.
- */
- qual = pull_constant_clauses(qual, &constant_qual);
- fix_opids(constant_qual);
-
- /*
- * Create a target list that consists solely of (resdom var) target
- * list entries, i.e., contains no arbitrary expressions.
- */
- flattened_tlist = flatten_tlist(tlist);
- if (flattened_tlist) {
- level_tlist = flattened_tlist;
- } else {
- /* from old code. the logic is beyond me. - ay 2/95 */
- level_tlist = tlist;
- }
-
- /*
- * A query may have a non-variable target list and a non-variable
- * qualification only under certain conditions:
- * - the query creates all-new tuples, or
- * - the query is a replace (a scan must still be done in this case).
- */
- if (flattened_tlist==NULL && qual==NULL) {
-
- switch (command_type) {
- case CMD_SELECT:
- case CMD_INSERT:
- return ((Plan*)make_result(tlist,
- (Node*)constant_qual,
- (Plan*)NULL));
- break;
-
- case CMD_DELETE:
- case CMD_UPDATE:
- {
- SeqScan *scan = make_seqscan(tlist,
- (List *)NULL,
- root->resultRelation,
- (Plan*)NULL);
- if (constant_qual!=NULL) {
- return ((Plan*)make_result(tlist,
- (Node*)constant_qual,
- (Plan*)scan));
- } else {
- return ((Plan*)scan);
- }
- }
- break;
-
- default:
- return ((Plan*)NULL);
+ List *constant_qual = NIL;
+ List *flattened_tlist = NIL;
+ List *level_tlist = NIL;
+ Plan *subplan = (Plan *) NULL;
+ Agg *aggplan = NULL;
+
+ /*
+ * A command without a target list or qualification is an error,
+ * except for "delete foo".
+ */
+ if (tlist == NIL && qual == NULL)
+ {
+ if (command_type == CMD_DELETE ||
+
+ /*
+ * Total hack here. I don't know how to handle statements like
+ * notify in action bodies. Notify doesn't return anything but
+ * scans a system table.
+ */
+ command_type == CMD_NOTIFY)
+ {
+ return ((Plan *) make_seqscan(NIL,
+ NIL,
+ root->resultRelation,
+ (Plan *) NULL));
+ }
+ else
+ return ((Plan *) NULL);
+ }
+
+ /*
+ * Pull out any non-variable qualifications so these can be put in the
+ * topmost result node. The opids for the remaining qualifications
+ * will be changed to regprocs later.
+ */
+ qual = pull_constant_clauses(qual, &constant_qual);
+ fix_opids(constant_qual);
+
+ /*
+ * Create a target list that consists solely of (resdom var) target
+ * list entries, i.e., contains no arbitrary expressions.
+ */
+ flattened_tlist = flatten_tlist(tlist);
+ if (flattened_tlist)
+ {
+ level_tlist = flattened_tlist;
+ }
+ else
+ {
+ /* from old code. the logic is beyond me. - ay 2/95 */
+ level_tlist = tlist;
}
- }
-
- /*
- * Find the subplan (access path) and destructively modify the
- * target list of the newly created subplan to contain the appropriate
- * join references.
- */
- subplan = subplanner(root, level_tlist, qual);
-
- set_tlist_references(subplan);
-
- /*
- * If we have a GROUP BY clause, insert a group node (with the appropriate
- * sort node.)
- */
- if (root->groupClause != NULL) {
- bool tuplePerGroup;
/*
- * decide whether how many tuples per group the Group node needs
- * to return. (Needs only one tuple per group if no aggregate is
- * present. Otherwise, need every tuple from the group to do the
- * aggregation.)
+ * A query may have a non-variable target list and a non-variable
+ * qualification only under certain conditions: - the query creates
+ * all-new tuples, or - the query is a replace (a scan must still be
+ * done in this case).
*/
- tuplePerGroup = ( root->qry_aggs ) ? TRUE : FALSE;
-
- subplan =
- make_groupPlan(&tlist, tuplePerGroup, root->groupClause, subplan);
-
- }
-
- /*
- * If aggregate is present, insert the agg node
- */
- if ( root->qry_aggs )
- {
- aggplan = make_agg(tlist, root->qry_numAgg, root->qry_aggs);
- aggplan->plan.lefttree = subplan;
+ if (flattened_tlist == NULL && qual == NULL)
+ {
+
+ switch (command_type)
+ {
+ case CMD_SELECT:
+ case CMD_INSERT:
+ return ((Plan *) make_result(tlist,
+ (Node *) constant_qual,
+ (Plan *) NULL));
+ break;
+
+ case CMD_DELETE:
+ case CMD_UPDATE:
+ {
+ SeqScan *scan = make_seqscan(tlist,
+ (List *) NULL,
+ root->resultRelation,
+ (Plan *) NULL);
+
+ if (constant_qual != NULL)
+ {
+ return ((Plan *) make_result(tlist,
+ (Node *) constant_qual,
+ (Plan *) scan));
+ }
+ else
+ {
+ return ((Plan *) scan);
+ }
+ }
+ break;
+
+ default:
+ return ((Plan *) NULL);
+ }
+ }
+
/*
- * set the varno/attno entries to the appropriate references to
- * the result tuple of the subplans. (We need to set those in the
- * array of aggreg's in the Agg node also. Even though they're
- * pointers, after a few dozen's of copying, they're not the same as
- * those in the target list.)
+ * Find the subplan (access path) and destructively modify the target
+ * list of the newly created subplan to contain the appropriate join
+ * references.
*/
- set_agg_tlist_references (aggplan);
- set_agg_agglist_references (aggplan);
-
- subplan = (Plan*)aggplan;
-
- tlist = aggplan->plan.targetlist;
- }
-
- /*
- * Build a result node linking the plan if we have constant quals
- */
- if (constant_qual) {
- Plan *plan;
-
- plan = (Plan*)make_result(tlist,
- (Node*)constant_qual,
- subplan);
+ subplan = subplanner(root, level_tlist, qual);
+
+ set_tlist_references(subplan);
+
/*
- * Change all varno's of the Result's node target list.
+ * If we have a GROUP BY clause, insert a group node (with the
+ * appropriate sort node.)
*/
- set_result_tlist_references((Result*)plan);
-
- return (plan);
- }
-
- /*
- * fix up the flattened target list of the plan root node so that
- * expressions are evaluated. this forces expression evaluations
- * that may involve expensive function calls to be delayed to
- * the very last stage of query execution. this could be bad.
- * but it is joey's responsibility to optimally push these
- * expressions down the plan tree. -- Wei
- *
- * But now nothing to do if there are GroupBy and/or Aggregates:
- * 1. make_groupPlan fixes tlist; 2. flatten_tlist_vars does nothing
- * with aggregates fixing only other entries (i.e. - GroupBy-ed and
- * so fixed by make_groupPlan). - vadim 04/05/97
- */
- if ( root->groupClause == NULL && aggplan == NULL )
- {
- subplan->targetlist = flatten_tlist_vars(tlist,
- subplan->targetlist);
- }
-
- /*
- * Destructively modify the query plan's targetlist to add fjoin
- * lists to flatten functions that return sets of base types
- */
- subplan->targetlist = generate_fjoin(subplan->targetlist);
-
- return (subplan);
+ if (root->groupClause != NULL)
+ {
+ bool tuplePerGroup;
+
+ /*
+ * decide whether how many tuples per group the Group node needs
+ * to return. (Needs only one tuple per group if no aggregate is
+ * present. Otherwise, need every tuple from the group to do the
+ * aggregation.)
+ */
+ tuplePerGroup = (root->qry_aggs) ? TRUE : FALSE;
+
+ subplan =
+ make_groupPlan(&tlist, tuplePerGroup, root->groupClause, subplan);
+
+ }
+
+ /*
+ * If aggregate is present, insert the agg node
+ */
+ if (root->qry_aggs)
+ {
+ aggplan = make_agg(tlist, root->qry_numAgg, root->qry_aggs);
+ aggplan->plan.lefttree = subplan;
+
+ /*
+ * set the varno/attno entries to the appropriate references to
+ * the result tuple of the subplans. (We need to set those in the
+ * array of aggreg's in the Agg node also. Even though they're
+ * pointers, after a few dozen's of copying, they're not the same
+ * as those in the target list.)
+ */
+ set_agg_tlist_references(aggplan);
+ set_agg_agglist_references(aggplan);
+
+ subplan = (Plan *) aggplan;
+
+ tlist = aggplan->plan.targetlist;
+ }
+
+ /*
+ * Build a result node linking the plan if we have constant quals
+ */
+ if (constant_qual)
+ {
+ Plan *plan;
+
+ plan = (Plan *) make_result(tlist,
+ (Node *) constant_qual,
+ subplan);
+
+ /*
+ * Change all varno's of the Result's node target list.
+ */
+ set_result_tlist_references((Result *) plan);
+
+ return (plan);
+ }
+
+ /*
+ * fix up the flattened target list of the plan root node so that
+ * expressions are evaluated. this forces expression evaluations that
+ * may involve expensive function calls to be delayed to the very last
+ * stage of query execution. this could be bad. but it is joey's
+ * responsibility to optimally push these expressions down the plan
+ * tree. -- Wei
+ *
+ * But now nothing to do if there are GroupBy and/or Aggregates: 1.
+ * make_groupPlan fixes tlist; 2. flatten_tlist_vars does nothing with
+ * aggregates fixing only other entries (i.e. - GroupBy-ed and so
+ * fixed by make_groupPlan). - vadim 04/05/97
+ */
+ if (root->groupClause == NULL && aggplan == NULL)
+ {
+ subplan->targetlist = flatten_tlist_vars(tlist,
+ subplan->targetlist);
+ }
+
+ /*
+ * Destructively modify the query plan's targetlist to add fjoin lists
+ * to flatten functions that return sets of base types
+ */
+ subplan->targetlist = generate_fjoin(subplan->targetlist);
+
+ return (subplan);
}
-/*
+/*
* subplanner
- *
- * Subplanner creates an entire plan consisting of joins and scans
- * for processing a single level of attributes.
- *
- * flat-tlist is the flattened target list
- * qual is the qualification to be satisfied
- *
- * Returns a subplan.
- *
+ *
+ * Subplanner creates an entire plan consisting of joins and scans
+ * for processing a single level of attributes.
+ *
+ * flat-tlist is the flattened target list
+ * qual is the qualification to be satisfied
+ *
+ * Returns a subplan.
+ *
*/
-static Plan *
-subplanner(Query *root,
- List *flat_tlist,
- List *qual)
+static Plan *
+subplanner(Query * root,
+ List * flat_tlist,
+ List * qual)
{
- Rel *final_relation;
- List *final_relation_list;
-
- /* Initialize the targetlist and qualification, adding entries to
- * *query-relation-list* as relation references are found (e.g., in the
- * qualification, the targetlist, etc.)
- */
- root->base_relation_list_ = NIL;
- root->join_relation_list_ = NIL;
- initialize_base_rels_list(root, flat_tlist);
- initialize_base_rels_jinfo(root, qual);
- add_missing_vars_to_base_rels(root, flat_tlist);
-
- /* Find all possible scan and join paths.
- * Mark all the clauses and relations that can be processed using special
- * join methods, then do the exhaustive path search.
- */
- initialize_join_clause_info(root->base_relation_list_);
- final_relation_list = find_paths(root,
- root->base_relation_list_);
-
- if (final_relation_list)
- final_relation = (Rel*)lfirst (final_relation_list);
- else
- final_relation = (Rel*)NIL;
-
-#if 0 /* fix xfunc */
- /*
- * Perform Predicate Migration on each path, to optimize and correctly
- * assess the cost of each before choosing the cheapest one.
- * -- JMH, 11/16/92
- *
- * Needn't do so if the top rel is pruneable: that means there's no
- * expensive functions left to pull up. -- JMH, 11/22/92
- */
- if (XfuncMode != XFUNC_OFF && XfuncMode != XFUNC_NOPM &&
- XfuncMode != XFUNC_NOPULL && !final_relation->pruneable)
+ Rel *final_relation;
+ List *final_relation_list;
+
+ /*
+ * Initialize the targetlist and qualification, adding entries to
+ * *query-relation-list* as relation references are found (e.g., in
+ * the qualification, the targetlist, etc.)
+ */
+ root->base_relation_list_ = NIL;
+ root->join_relation_list_ = NIL;
+ initialize_base_rels_list(root, flat_tlist);
+ initialize_base_rels_jinfo(root, qual);
+ add_missing_vars_to_base_rels(root, flat_tlist);
+
+ /*
+ * Find all possible scan and join paths. Mark all the clauses and
+ * relations that can be processed using special join methods, then do
+ * the exhaustive path search.
+ */
+ initialize_join_clause_info(root->base_relation_list_);
+ final_relation_list = find_paths(root,
+ root->base_relation_list_);
+
+ if (final_relation_list)
+ final_relation = (Rel *) lfirst(final_relation_list);
+ else
+ final_relation = (Rel *) NIL;
+
+#if 0 /* fix xfunc */
+
+ /*
+ * Perform Predicate Migration on each path, to optimize and correctly
+ * assess the cost of each before choosing the cheapest one. -- JMH,
+ * 11/16/92
+ *
+ * Needn't do so if the top rel is pruneable: that means there's no
+ * expensive functions left to pull up. -- JMH, 11/22/92
+ */
+ if (XfuncMode != XFUNC_OFF && XfuncMode != XFUNC_NOPM &&
+ XfuncMode != XFUNC_NOPULL && !final_relation->pruneable)
{
- List *pathnode;
- foreach(pathnode, final_relation->pathlist)
+ List *pathnode;
+
+ foreach(pathnode, final_relation->pathlist)
{
- if (xfunc_do_predmig((Path*)lfirst(pathnode)))
- set_cheapest(final_relation, final_relation->pathlist);
+ if (xfunc_do_predmig((Path *) lfirst(pathnode)))
+ set_cheapest(final_relation, final_relation->pathlist);
}
}
#endif
-
- /*
- * Determine the cheapest path and create a subplan corresponding to it.
- */
- if (final_relation) {
- return (create_plan ((Path*)final_relation->cheapestpath));
- }else {
- elog(NOTICE, "final relation is nil");
- return(create_plan ((Path*)NULL));
- }
-
+
+ /*
+ * Determine the cheapest path and create a subplan corresponding to
+ * it.
+ */
+ if (final_relation)
+ {
+ return (create_plan((Path *) final_relation->cheapestpath));
+ }
+ else
+ {
+ elog(NOTICE, "final relation is nil");
+ return (create_plan((Path *) NULL));
+ }
+
}
/*****************************************************************************
*
*****************************************************************************/
-static Result *
-make_result(List *tlist,
- Node *resconstantqual,
- Plan *subplan)
+static Result *
+make_result(List * tlist,
+ Node * resconstantqual,
+ Plan * subplan)
{
- Result *node = makeNode(Result);
- Plan *plan = &node->plan;
-
- tlist = generate_fjoin(tlist);
- plan->cost = 0.0;
- plan->state = (EState *)NULL;
- plan->targetlist = tlist;
- plan->lefttree = subplan;
- plan->righttree = NULL;
- node->resconstantqual = resconstantqual;
- node->resstate = NULL;
-
- return(node);
-}
+ Result *node = makeNode(Result);
+ Plan *plan = &node->plan;
+
+ tlist = generate_fjoin(tlist);
+ plan->cost = 0.0;
+ plan->state = (EState *) NULL;
+ plan->targetlist = tlist;
+ plan->lefttree = subplan;
+ plan->righttree = NULL;
+ node->resconstantqual = resconstantqual;
+ node->resstate = NULL;
+
+ return (node);
+}
/*****************************************************************************
*
*****************************************************************************/
-static Plan *
-make_groupPlan(List **tlist,
- bool tuplePerGroup,
- List *groupClause,
- Plan *subplan)
+static Plan *
+make_groupPlan(List ** tlist,
+ bool tuplePerGroup,
+ List * groupClause,
+ Plan * subplan)
{
- List *sort_tlist;
- List *sl, *gl;
- List *glc = listCopy (groupClause);
- List *otles = NIL; /* list of removed non-GroupBy entries */
- List *otlvars = NIL; /* list of var in them */
- int otlvcnt;
- Sort *sortplan;
- Group *grpplan;
- int numCols;
- AttrNumber *grpColIdx;
- int keyno = 1;
- int last_resno = 1;
-
- numCols = length(groupClause);
- grpColIdx = (AttrNumber *)palloc(sizeof(AttrNumber)*numCols);
-
- sort_tlist = new_unsorted_tlist(*tlist); /* it's copy */
-
- /*
- * Make template TL for subplan, Sort & Group:
- * 1. If there are aggregates (tuplePerGroup is true) then take
- * away non-GroupBy entries and re-set resno-s accordantly.
- * 2. Make grpColIdx
- *
- * Note: we assume that TLEs in *tlist are ordered in accordance
- * with their resdom->resno.
- */
- foreach (sl, sort_tlist)
- {
- Resdom *resdom = NULL;
- TargetEntry *te = (TargetEntry *) lfirst (sl);
-
- foreach (gl, glc)
- {
- GroupClause *grpcl = (GroupClause*)lfirst(gl);
-
- if ( grpcl->entry->resdom->resno == te->resdom->resno )
- {
-
- resdom = te->resdom;
- resdom->reskey = keyno;
- resdom->reskeyop = get_opcode (grpcl->grpOpoid);
- resdom->resno = last_resno; /* re-set */
- grpColIdx[keyno-1] = last_resno++;
- keyno++;
- glc = lremove (lfirst (gl), glc); /* TLE found for it */
- break;
- }
- }
- /*
- * Non-GroupBy entry: remove it from Group/Sort TL if there are
- * aggregates in query - it will be evaluated by Aggregate plan
+ List *sort_tlist;
+ List *sl,
+ *gl;
+ List *glc = listCopy(groupClause);
+ List *otles = NIL;/* list of removed non-GroupBy entries */
+ List *otlvars = NIL; /* list of var in them */
+ int otlvcnt;
+ Sort *sortplan;
+ Group *grpplan;
+ int numCols;
+ AttrNumber *grpColIdx;
+ int keyno = 1;
+ int last_resno = 1;
+
+ numCols = length(groupClause);
+ grpColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
+
+ sort_tlist = new_unsorted_tlist(*tlist); /* it's copy */
+
+ /*
+ * Make template TL for subplan, Sort & Group: 1. If there are
+ * aggregates (tuplePerGroup is true) then take away non-GroupBy
+ * entries and re-set resno-s accordantly. 2. Make grpColIdx
+ *
+ * Note: we assume that TLEs in *tlist are ordered in accordance with
+ * their resdom->resno.
*/
- if ( resdom == NULL )
+ foreach(sl, sort_tlist)
{
- if ( tuplePerGroup )
- {
- otlvars = nconc (otlvars, pull_var_clause (te->expr));
- otles = lcons (te, otles);
- sort_tlist = lremove (te, sort_tlist);
- }
- else
- te->resdom->resno = last_resno++;
+ Resdom *resdom = NULL;
+ TargetEntry *te = (TargetEntry *) lfirst(sl);
+
+ foreach(gl, glc)
+ {
+ GroupClause *grpcl = (GroupClause *) lfirst(gl);
+
+ if (grpcl->entry->resdom->resno == te->resdom->resno)
+ {
+
+ resdom = te->resdom;
+ resdom->reskey = keyno;
+ resdom->reskeyop = get_opcode(grpcl->grpOpoid);
+ resdom->resno = last_resno; /* re-set */
+ grpColIdx[keyno - 1] = last_resno++;
+ keyno++;
+ glc = lremove(lfirst(gl), glc); /* TLE found for it */
+ break;
+ }
+ }
+
+ /*
+ * Non-GroupBy entry: remove it from Group/Sort TL if there are
+ * aggregates in query - it will be evaluated by Aggregate plan
+ */
+ if (resdom == NULL)
+ {
+ if (tuplePerGroup)
+ {
+ otlvars = nconc(otlvars, pull_var_clause(te->expr));
+ otles = lcons(te, otles);
+ sort_tlist = lremove(te, sort_tlist);
+ }
+ else
+ te->resdom->resno = last_resno++;
+ }
}
- }
-
- if ( length (glc) != 0 )
- {
- elog(WARN, "group attribute disappeared from target list");
- }
-
- /*
- * If non-GroupBy entries were removed from TL - we are to add Vars for
- * them to the end of TL if there are no such Vars in TL already.
- */
-
- otlvcnt = length (otlvars);
- foreach (gl, otlvars)
- {
- Var *v = (Var*)lfirst (gl);
-
- if ( tlist_member (v, sort_tlist) == NULL )
+
+ if (length(glc) != 0)
{
- sort_tlist = lappend (sort_tlist,
- create_tl_element (v, last_resno));
- last_resno++;
+ elog(WARN, "group attribute disappeared from target list");
}
- else /* already in TL */
- otlvcnt--;
- }
- /* Now otlvcnt is number of Vars added in TL for non-GroupBy entries */
-
- /* Make TL for subplan: substitute Vars from subplan TL into new TL */
- sl = flatten_tlist_vars (sort_tlist, subplan->targetlist);
-
- subplan->targetlist = new_unsorted_tlist (sl); /* there */
-
- /*
- * Make Sort/Group TL :
- * 1. make Var nodes (with varno = 1 and varnoold = -1) for all
- * functions, 'couse they will be evaluated by subplan;
- * 2. for real Vars: set varno = 1 and varattno to its resno in subplan
- */
- foreach (sl, sort_tlist)
- {
- TargetEntry *te = (TargetEntry *) lfirst (sl);
- Resdom *resdom = te->resdom;
- Node *expr = te->expr;
-
- if ( IsA (expr, Var) )
- {
-#if 0 /* subplanVar->resdom->resno expected to be = te->resdom->resno */
- TargetEntry *subplanVar;
-
- subplanVar = match_varid ((Var*)expr, subplan->targetlist);
- ((Var*)expr)->varattno = subplanVar->resdom->resno;
+
+ /*
+ * If non-GroupBy entries were removed from TL - we are to add Vars
+ * for them to the end of TL if there are no such Vars in TL already.
+ */
+
+ otlvcnt = length(otlvars);
+ foreach(gl, otlvars)
+ {
+ Var *v = (Var *) lfirst(gl);
+
+ if (tlist_member(v, sort_tlist) == NULL)
+ {
+ sort_tlist = lappend(sort_tlist,
+ create_tl_element(v, last_resno));
+ last_resno++;
+ }
+ else
+/* already in TL */
+ otlvcnt--;
+ }
+ /* Now otlvcnt is number of Vars added in TL for non-GroupBy entries */
+
+ /* Make TL for subplan: substitute Vars from subplan TL into new TL */
+ sl = flatten_tlist_vars(sort_tlist, subplan->targetlist);
+
+ subplan->targetlist = new_unsorted_tlist(sl); /* there */
+
+ /*
+ * Make Sort/Group TL : 1. make Var nodes (with varno = 1 and varnoold
+ * = -1) for all functions, 'couse they will be evaluated by subplan;
+ * 2. for real Vars: set varno = 1 and varattno to its resno in
+ * subplan
+ */
+ foreach(sl, sort_tlist)
+ {
+ TargetEntry *te = (TargetEntry *) lfirst(sl);
+ Resdom *resdom = te->resdom;
+ Node *expr = te->expr;
+
+ if (IsA(expr, Var))
+ {
+#if 0 /* subplanVar->resdom->resno expected to
+ * be = te->resdom->resno */
+ TargetEntry *subplanVar;
+
+ subplanVar = match_varid((Var *) expr, subplan->targetlist);
+ ((Var *) expr)->varattno = subplanVar->resdom->resno;
#endif
- ((Var*)expr)->varattno = te->resdom->resno;
- ((Var*)expr)->varno = 1;
- }
- else
- te->expr = (Node*) makeVar (1, resdom->resno,
- resdom->restype,
- -1, resdom->resno);
- }
-
- sortplan = make_sort(sort_tlist,
- _TEMP_RELATION_ID_,
- subplan,
- numCols);
- sortplan->plan.cost = subplan->cost; /* XXX assume no cost */
-
- /*
- * make the Group node
- */
- sort_tlist = copyObject (sort_tlist);
- grpplan = make_group(sort_tlist, tuplePerGroup, numCols,
- grpColIdx, sortplan);
-
- /*
- * Make TL for parent: "restore" non-GroupBy entries (if they
- * were removed) and set resno-s of others accordantly.
- */
- sl = sort_tlist;
- sort_tlist = NIL; /* to be new parent TL */
- foreach (gl, *tlist)
- {
- List *temp = NIL;
- TargetEntry *te = (TargetEntry *) lfirst (gl);
-
- foreach (temp, otles) /* Is it removed non-GroupBy entry ? */
- {
- TargetEntry *ote = (TargetEntry *) lfirst (temp);
-
- if ( ote->resdom->resno == te->resdom->resno )
- {
- otles = lremove (ote, otles);
- break;
- }
- }
- if ( temp == NIL ) /* It's "our" TLE - we're to return */
- { /* it from Sort/Group plans */
- TargetEntry *my = (TargetEntry *) lfirst (sl); /* get it */
-
- sl = sl->next; /* prepare for the next "our" */
- my = copyObject (my);
- my->resdom->resno = te->resdom->resno; /* order of parent TL */
- sort_tlist = lappend (sort_tlist, my);
- continue;
+ ((Var *) expr)->varattno = te->resdom->resno;
+ ((Var *) expr)->varno = 1;
+ }
+ else
+ te->expr = (Node *) makeVar(1, resdom->resno,
+ resdom->restype,
+ -1, resdom->resno);
}
- /* else - it's TLE of an non-GroupBy entry */
- sort_tlist = lappend (sort_tlist, copyObject(te));
- }
- /*
- * Pure non-GroupBy entries Vars were at the end of Group' TL.
- * They shouldn't appear in parent TL, all others shouldn't
- * disappear.
- */
- Assert ( otlvcnt == length (sl) );
- Assert ( length (otles) == 0 );
-
- *tlist = sort_tlist;
-
- return (Plan*)grpplan;
+
+ sortplan = make_sort(sort_tlist,
+ _TEMP_RELATION_ID_,
+ subplan,
+ numCols);
+ sortplan->plan.cost = subplan->cost; /* XXX assume no cost */
+
+ /*
+ * make the Group node
+ */
+ sort_tlist = copyObject(sort_tlist);
+ grpplan = make_group(sort_tlist, tuplePerGroup, numCols,
+ grpColIdx, sortplan);
+
+ /*
+ * Make TL for parent: "restore" non-GroupBy entries (if they were
+ * removed) and set resno-s of others accordantly.
+ */
+ sl = sort_tlist;
+ sort_tlist = NIL; /* to be new parent TL */
+ foreach(gl, *tlist)
+ {
+ List *temp = NIL;
+ TargetEntry *te = (TargetEntry *) lfirst(gl);
+
+ foreach(temp, otles) /* Is it removed non-GroupBy entry ? */
+ {
+ TargetEntry *ote = (TargetEntry *) lfirst(temp);
+
+ if (ote->resdom->resno == te->resdom->resno)
+ {
+ otles = lremove(ote, otles);
+ break;
+ }
+ }
+ if (temp == NIL) /* It's "our" TLE - we're to return */
+ { /* it from Sort/Group plans */
+ TargetEntry *my = (TargetEntry *) lfirst(sl); /* get it */
+
+ sl = sl->next; /* prepare for the next "our" */
+ my = copyObject(my);
+ my->resdom->resno = te->resdom->resno; /* order of parent TL */
+ sort_tlist = lappend(sort_tlist, my);
+ continue;
+ }
+ /* else - it's TLE of an non-GroupBy entry */
+ sort_tlist = lappend(sort_tlist, copyObject(te));
+ }
+
+ /*
+ * Pure non-GroupBy entries Vars were at the end of Group' TL. They
+ * shouldn't appear in parent TL, all others shouldn't disappear.
+ */
+ Assert(otlvcnt == length(sl));
+ Assert(length(otles) == 0);
+
+ *tlist = sort_tlist;
+
+ return (Plan *) grpplan;
}
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 5a6b78384b6..43441a3b7ff 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* planner.c--
- * The query optimizer external interface.
+ * The query optimizer external interface.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.6 1997/09/05 20:20:48 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.7 1997/09/07 04:44:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,7 +28,7 @@
#include "optimizer/internal.h"
#include "optimizer/planner.h"
-#include "optimizer/plancat.h"
+#include "optimizer/plancat.h"
#include "optimizer/prep.h"
#include "optimizer/planmain.h"
#include "optimizer/paths.h"
@@ -47,215 +47,225 @@
#include "executor/executor.h"
-static Plan *make_sortplan(List *tlist, List *sortcls, Plan *plannode);
-static Plan *init_query_planner(Query *parse);
-static Existential *make_existential(Plan *left, Plan *right);
+static Plan *make_sortplan(List * tlist, List * sortcls, Plan * plannode);
+static Plan *init_query_planner(Query * parse);
+static Existential *make_existential(Plan * left, Plan * right);
/*****************************************************************************
*
- * Query optimizer entry point
- *
+ * Query optimizer entry point
+ *
*****************************************************************************/
-/*
+/*
* planner--
- * Main query optimizer routine.
- *
- * Invokes the planner on union queries if there are any left,
- * recursing if necessary to get them all, then processes normal plans.
- *
+ * Main query optimizer routine.
+ *
+ * Invokes the planner on union queries if there are any left,
+ * recursing if necessary to get them all, then processes normal plans.
+ *
* Returns a query plan.
- *
+ *
*/
-Plan*
-planner(Query *parse)
+Plan *
+planner(Query * parse)
{
- List *tlist = parse->targetList;
- List *rangetable = parse->rtable;
- char* uniqueflag = parse->uniqueFlag;
- List *sortclause = parse->sortClause;
- Plan *special_plans = (Plan*)NULL;
-
- Plan *result_plan = (Plan*) NULL;
-
- int rt_index;
-
- /*
- * plan inheritance
- */
- rt_index = first_matching_rt_entry(rangetable, INHERITS_FLAG);
- if (rt_index != -1) {
- special_plans = (Plan *)plan_union_queries((Index)rt_index,
- parse,
- INHERITS_FLAG);
- }
-
- /*
- * plan archive queries
- */
- rt_index = first_matching_rt_entry(rangetable, ARCHIVE_FLAG);
- if (rt_index != -1) {
- special_plans = (Plan *)plan_union_queries((Index)rt_index,
- parse,
- ARCHIVE_FLAG);
- }
-
- if (special_plans)
- result_plan = special_plans;
- else
- result_plan = init_query_planner(parse); /* regular plans */
-
- /*
- * For now, before we hand back the plan, check to see if there
- * is a user-specified sort that needs to be done. Eventually, this
- * will be moved into the guts of the planner s.t. user specified
- * sorts will be considered as part of the planning process.
- * Since we can only make use of user-specified sorts in
- * special cases, we can do the optimization step later.
- */
-
- if (uniqueflag) {
- Plan *sortplan = make_sortplan(tlist, sortclause, result_plan);
-
- return((Plan*)make_unique(tlist,sortplan,uniqueflag));
- } else {
- if (sortclause)
- return(make_sortplan(tlist,sortclause,result_plan));
- else
- return((Plan*)result_plan);
- }
+ List *tlist = parse->targetList;
+ List *rangetable = parse->rtable;
+ char *uniqueflag = parse->uniqueFlag;
+ List *sortclause = parse->sortClause;
+ Plan *special_plans = (Plan *) NULL;
+
+ Plan *result_plan = (Plan *) NULL;
+
+ int rt_index;
+
+ /*
+ * plan inheritance
+ */
+ rt_index = first_matching_rt_entry(rangetable, INHERITS_FLAG);
+ if (rt_index != -1)
+ {
+ special_plans = (Plan *) plan_union_queries((Index) rt_index,
+ parse,
+ INHERITS_FLAG);
+ }
+
+ /*
+ * plan archive queries
+ */
+ rt_index = first_matching_rt_entry(rangetable, ARCHIVE_FLAG);
+ if (rt_index != -1)
+ {
+ special_plans = (Plan *) plan_union_queries((Index) rt_index,
+ parse,
+ ARCHIVE_FLAG);
+ }
+
+ if (special_plans)
+ result_plan = special_plans;
+ else
+ result_plan = init_query_planner(parse); /* regular plans */
+
+ /*
+ * For now, before we hand back the plan, check to see if there is a
+ * user-specified sort that needs to be done. Eventually, this will
+ * be moved into the guts of the planner s.t. user specified sorts
+ * will be considered as part of the planning process. Since we can
+ * only make use of user-specified sorts in special cases, we can do
+ * the optimization step later.
+ */
+
+ if (uniqueflag)
+ {
+ Plan *sortplan = make_sortplan(tlist, sortclause, result_plan);
+
+ return ((Plan *) make_unique(tlist, sortplan, uniqueflag));
+ }
+ else
+ {
+ if (sortclause)
+ return (make_sortplan(tlist, sortclause, result_plan));
+ else
+ return ((Plan *) result_plan);
+ }
}
/*
* make_sortplan--
- * Returns a sortplan which is basically a SORT node attached to the
- * top of the plan returned from the planner. It also adds the
- * cost of sorting into the plan.
- *
+ * Returns a sortplan which is basically a SORT node attached to the
+ * top of the plan returned from the planner. It also adds the
+ * cost of sorting into the plan.
+ *
* sortkeys: ( resdom1 resdom2 resdom3 ...)
* sortops: (sortop1 sortop2 sortop3 ...)
*/
-static Plan *
-make_sortplan(List *tlist, List *sortcls, Plan *plannode)
+static Plan *
+make_sortplan(List * tlist, List * sortcls, Plan * plannode)
{
- Plan *sortplan = (Plan*)NULL;
- List *temp_tlist = NIL;
- List *i = NIL;
- Resdom *resnode = (Resdom*)NULL;
- Resdom *resdom = (Resdom*)NULL;
- int keyno =1;
-
- /* First make a copy of the tlist so that we don't corrupt the
- * the original .
- */
-
- temp_tlist = new_unsorted_tlist(tlist);
-
- foreach (i, sortcls) {
- SortClause *sortcl = (SortClause*)lfirst(i);
-
- resnode = sortcl->resdom;
- resdom = tlist_resdom(temp_tlist, resnode);
-
- /* Order the resdom keys and replace the operator OID for each
- * key with the regproc OID.
+ Plan *sortplan = (Plan *) NULL;
+ List *temp_tlist = NIL;
+ List *i = NIL;
+ Resdom *resnode = (Resdom *) NULL;
+ Resdom *resdom = (Resdom *) NULL;
+ int keyno = 1;
+
+ /*
+ * First make a copy of the tlist so that we don't corrupt the the
+ * original .
+ */
+
+ temp_tlist = new_unsorted_tlist(tlist);
+
+ foreach(i, sortcls)
+ {
+ SortClause *sortcl = (SortClause *) lfirst(i);
+
+ resnode = sortcl->resdom;
+ resdom = tlist_resdom(temp_tlist, resnode);
+
+ /*
+ * Order the resdom keys and replace the operator OID for each key
+ * with the regproc OID.
+ */
+ resdom->reskey = keyno;
+ resdom->reskeyop = get_opcode(sortcl->opoid);
+ keyno += 1;
+ }
+
+ sortplan = (Plan *) make_sort(temp_tlist,
+ _TEMP_RELATION_ID_,
+ (Plan *) plannode,
+ length(sortcls));
+
+ /*
+ * XXX Assuming that an internal sort has no. cost. This is wrong, but
+ * given that at this point, we don't know the no. of tuples returned,
+ * etc, we can't do better than to add a constant cost. This will be
+ * fixed once we move the sort further into the planner, but for now
+ * ... functionality....
*/
- resdom->reskey = keyno;
- resdom->reskeyop = get_opcode(sortcl->opoid);
- keyno += 1;
- }
-
- sortplan = (Plan*)make_sort(temp_tlist,
- _TEMP_RELATION_ID_,
- (Plan*)plannode,
- length(sortcls));
-
- /*
- * XXX Assuming that an internal sort has no. cost.
- * This is wrong, but given that at this point, we don't
- * know the no. of tuples returned, etc, we can't do
- * better than to add a constant cost.
- * This will be fixed once we move the sort further into the planner,
- * but for now ... functionality....
- */
-
- sortplan->cost = plannode->cost;
-
- return(sortplan);
+
+ sortplan->cost = plannode->cost;
+
+ return (sortplan);
}
-/*
+/*
* init-query-planner--
- * Deals with all non-union preprocessing, including existential
- * qualifications and CNFifying the qualifications.
- *
+ * Deals with all non-union preprocessing, including existential
+ * qualifications and CNFifying the qualifications.
+ *
* Returns a query plan.
* MODIFIES: tlist,qual
- *
+ *
*/
-static Plan *
-init_query_planner(Query *root)
+static Plan *
+init_query_planner(Query * root)
{
- List *primary_qual;
- List *existential_qual;
- Existential *exist_plan;
- List *tlist = root->targetList;
-
- tlist = preprocess_targetlist(tlist,
- root->commandType,
- root->resultRelation,
- root->rtable);
-
- primary_qual =
- preprocess_qualification((Expr*)root->qual,
- tlist,
- &existential_qual);
-
- if(existential_qual==NULL) {
- return(query_planner(root,
- root->commandType,
- tlist,
- primary_qual));
- } else {
- int temp = root->commandType;
- Plan *existential_plan;
-
- root->commandType = CMD_SELECT;
- existential_plan = query_planner(root,
- temp,
- NIL,
- existential_qual);
-
- exist_plan = make_existential(existential_plan,
- query_planner(root,
- root->commandType,
- tlist,
- primary_qual));
- return((Plan*)exist_plan);
- }
+ List *primary_qual;
+ List *existential_qual;
+ Existential *exist_plan;
+ List *tlist = root->targetList;
+
+ tlist = preprocess_targetlist(tlist,
+ root->commandType,
+ root->resultRelation,
+ root->rtable);
+
+ primary_qual =
+ preprocess_qualification((Expr *) root->qual,
+ tlist,
+ &existential_qual);
+
+ if (existential_qual == NULL)
+ {
+ return (query_planner(root,
+ root->commandType,
+ tlist,
+ primary_qual));
+ }
+ else
+ {
+ int temp = root->commandType;
+ Plan *existential_plan;
+
+ root->commandType = CMD_SELECT;
+ existential_plan = query_planner(root,
+ temp,
+ NIL,
+ existential_qual);
+
+ exist_plan = make_existential(existential_plan,
+ query_planner(root,
+ root->commandType,
+ tlist,
+ primary_qual));
+ return ((Plan *) exist_plan);
+ }
}
-/*
+/*
* make_existential--
- * Instantiates an existential plan node and fills in
- * the left and right subtree slots.
+ * Instantiates an existential plan node and fills in
+ * the left and right subtree slots.
*/
static Existential *
-make_existential(Plan *left, Plan *right)
+make_existential(Plan * left, Plan * right)
{
- Existential *node = makeNode(Existential);
+ Existential *node = makeNode(Existential);
- node->lefttree = left;
- node->righttree = left;
- return(node);
+ node->lefttree = left;
+ node->righttree = left;
+ return (node);
}
/*
* pg_checkretval() -- check return value of a list of sql parse
- * trees.
+ * trees.
*
* The return value of a sql function is the value returned by
* the final query in the function. We do some ad-hoc define-time
@@ -263,145 +273,152 @@ make_existential(Plan *left, Plan *right)
* type he claims.
*/
void
-pg_checkretval(Oid rettype, QueryTreeList *queryTreeList)
+pg_checkretval(Oid rettype, QueryTreeList * queryTreeList)
{
- Query *parse;
- List *tlist;
- List *rt;
- int cmd;
- Type typ;
- Resdom *resnode;
- Relation reln;
- Oid relid;
- Oid tletype;
- int relnatts;
- int i;
-
- /* find the final query */
- parse = queryTreeList->qtrees[queryTreeList->len - 1];
-
- /*
- * test 1: if the last query is a utility invocation, then there
- * had better not be a return value declared.
- */
- if (parse->commandType == CMD_UTILITY) {
+ Query *parse;
+ List *tlist;
+ List *rt;
+ int cmd;
+ Type typ;
+ Resdom *resnode;
+ Relation reln;
+ Oid relid;
+ Oid tletype;
+ int relnatts;
+ int i;
+
+ /* find the final query */
+ parse = queryTreeList->qtrees[queryTreeList->len - 1];
+
+ /*
+ * test 1: if the last query is a utility invocation, then there had
+ * better not be a return value declared.
+ */
+ if (parse->commandType == CMD_UTILITY)
+ {
+ if (rettype == InvalidOid)
+ return;
+ else
+ elog(WARN, "return type mismatch in function decl: final query is a catalog utility");
+ }
+
+ /* okay, it's an ordinary query */
+ tlist = parse->targetList;
+ rt = parse->rtable;
+ cmd = parse->commandType;
+
+ /*
+ * test 2: if the function is declared to return no value, then the
+ * final query had better not be a retrieve.
+ */
if (rettype == InvalidOid)
- return;
- else
- elog(WARN, "return type mismatch in function decl: final query is a catalog utility");
- }
-
- /* okay, it's an ordinary query */
- tlist = parse->targetList;
- rt = parse->rtable;
- cmd = parse->commandType;
-
- /*
- * test 2: if the function is declared to return no value, then the
- * final query had better not be a retrieve.
- */
- if (rettype == InvalidOid) {
- if (cmd == CMD_SELECT)
- elog(WARN,
- "function declared with no return type, but final query is a retrieve");
- else
- return;
- }
-
- /* by here, the function is declared to return some type */
- if ((typ = (Type)get_id_type(rettype)) == NULL)
- elog(WARN, "can't find return type %d for function\n", rettype);
-
- /*
- * test 3: if the function is declared to return a value, then the
- * final query had better be a retrieve.
- */
- if (cmd != CMD_SELECT)
- elog(WARN, "function declared to return type %s, but final query is not a retrieve", tname(typ));
-
- /*
- * test 4: for base type returns, the target list should have exactly
- * one entry, and its type should agree with what the user declared.
- */
-
- if (get_typrelid(typ) == InvalidOid) {
- if (exec_tlist_length(tlist) > 1)
- elog(WARN, "function declared to return %s returns multiple values in final retrieve", tname(typ));
-
- resnode = (Resdom*) ((TargetEntry*)lfirst(tlist))->resdom;
- if (resnode->restype != rettype)
- elog(WARN, "return type mismatch in function: declared to return %s, returns %s", tname(typ), tname(get_id_type(resnode->restype)));
-
- /* by here, base return types match */
- return;
- }
-
- /*
- * If the target list is of length 1, and the type of the varnode
- * in the target list is the same as the declared return type, this
- * is okay. This can happen, for example, where the body of the
- * function is 'retrieve (x = func2())', where func2 has the same
- * return type as the function that's calling it.
- */
- if (exec_tlist_length(tlist) == 1) {
- resnode = (Resdom*) ((TargetEntry*)lfirst(tlist))->resdom;
- if (resnode->restype == rettype)
- return;
- }
-
- /*
- * By here, the procedure returns a (set of) tuples. This part of
- * the typechecking is a hack. We look up the relation that is
- * the declared return type, and be sure that attributes 1 .. n
- * in the target list match the declared types.
- */
- reln = heap_open(get_typrelid(typ));
-
- if (!RelationIsValid(reln))
- elog(WARN, "cannot open relation relid %d", get_typrelid(typ));
-
- relid = reln->rd_id;
- relnatts = reln->rd_rel->relnatts;
-
- if (exec_tlist_length(tlist) != relnatts)
- elog(WARN, "function declared to return type %s does not retrieve (%s.*)", tname(typ), tname(typ));
-
- /* expect attributes 1 .. n in order */
- for (i = 1; i <= relnatts; i++) {
- TargetEntry *tle = lfirst(tlist);
- Node *thenode = tle->expr;
-
- tlist = lnext(tlist);
- tletype = exprType(thenode);
-
-#if 0 /* fix me */
- /* this is tedious */
- if (IsA(thenode,Var))
- tletype = (Oid) ((Var*)thenode)->vartype;
- else if (IsA(thenode,Const))
- tletype = (Oid) ((Const*)thenode)->consttype;
- else if (IsA(thenode,Param))
- tletype = (Oid) ((Param*)thenode)->paramtype;
- else if (IsA(thenode,Expr))
- tletype = Expr;
- else if (IsA(thenode,LispList)) {
- thenode = lfirst(thenode);
- if (IsA(thenode,Oper))
- tletype = (Oid) get_opresulttype((Oper*)thenode);
- else if (IsA(thenode,Func))
- tletype = (Oid) get_functype((Func*)thenode);
- else
- elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ));
- } else
- elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ));
+ {
+ if (cmd == CMD_SELECT)
+ elog(WARN,
+ "function declared with no return type, but final query is a retrieve");
+ else
+ return;
+ }
+
+ /* by here, the function is declared to return some type */
+ if ((typ = (Type) get_id_type(rettype)) == NULL)
+ elog(WARN, "can't find return type %d for function\n", rettype);
+
+ /*
+ * test 3: if the function is declared to return a value, then the
+ * final query had better be a retrieve.
+ */
+ if (cmd != CMD_SELECT)
+ elog(WARN, "function declared to return type %s, but final query is not a retrieve", tname(typ));
+
+ /*
+ * test 4: for base type returns, the target list should have exactly
+ * one entry, and its type should agree with what the user declared.
+ */
+
+ if (get_typrelid(typ) == InvalidOid)
+ {
+ if (exec_tlist_length(tlist) > 1)
+ elog(WARN, "function declared to return %s returns multiple values in final retrieve", tname(typ));
+
+ resnode = (Resdom *) ((TargetEntry *) lfirst(tlist))->resdom;
+ if (resnode->restype != rettype)
+ elog(WARN, "return type mismatch in function: declared to return %s, returns %s", tname(typ), tname(get_id_type(resnode->restype)));
+
+ /* by here, base return types match */
+ return;
+ }
+
+ /*
+ * If the target list is of length 1, and the type of the varnode in
+ * the target list is the same as the declared return type, this is
+ * okay. This can happen, for example, where the body of the function
+ * is 'retrieve (x = func2())', where func2 has the same return type
+ * as the function that's calling it.
+ */
+ if (exec_tlist_length(tlist) == 1)
+ {
+ resnode = (Resdom *) ((TargetEntry *) lfirst(tlist))->resdom;
+ if (resnode->restype == rettype)
+ return;
+ }
+
+ /*
+ * By here, the procedure returns a (set of) tuples. This part of the
+ * typechecking is a hack. We look up the relation that is the
+ * declared return type, and be sure that attributes 1 .. n in the
+ * target list match the declared types.
+ */
+ reln = heap_open(get_typrelid(typ));
+
+ if (!RelationIsValid(reln))
+ elog(WARN, "cannot open relation relid %d", get_typrelid(typ));
+
+ relid = reln->rd_id;
+ relnatts = reln->rd_rel->relnatts;
+
+ if (exec_tlist_length(tlist) != relnatts)
+ elog(WARN, "function declared to return type %s does not retrieve (%s.*)", tname(typ), tname(typ));
+
+ /* expect attributes 1 .. n in order */
+ for (i = 1; i <= relnatts; i++)
+ {
+ TargetEntry *tle = lfirst(tlist);
+ Node *thenode = tle->expr;
+
+ tlist = lnext(tlist);
+ tletype = exprType(thenode);
+
+#if 0 /* fix me */
+ /* this is tedious */
+ if (IsA(thenode, Var))
+ tletype = (Oid) ((Var *) thenode)->vartype;
+ else if (IsA(thenode, Const))
+ tletype = (Oid) ((Const *) thenode)->consttype;
+ else if (IsA(thenode, Param))
+ tletype = (Oid) ((Param *) thenode)->paramtype;
+ else if (IsA(thenode, Expr))
+ tletype = Expr;
+ else if (IsA(thenode, LispList))
+ {
+ thenode = lfirst(thenode);
+ if (IsA(thenode, Oper))
+ tletype = (Oid) get_opresulttype((Oper *) thenode);
+ else if (IsA(thenode, Func))
+ tletype = (Oid) get_functype((Func *) thenode);
+ else
+ elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ));
+ }
+ else
+ elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ));
#endif
- /* reach right in there, why don't you? */
- if (tletype != reln->rd_att->attrs[i-1]->atttypid)
- elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ));
- }
+ /* reach right in there, why don't you? */
+ if (tletype != reln->rd_att->attrs[i - 1]->atttypid)
+ elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ));
+ }
- heap_close(reln);
+ heap_close(reln);
- /* success */
- return;
+ /* success */
+ return;
}
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 4527837e9d4..19cee246a58 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* setrefs.c--
- * Routines to change varno/attno entries to contain references
+ * Routines to change varno/attno entries to contain references
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.4 1997/06/12 17:26:15 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.5 1997/09/07 04:44:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,419 +33,468 @@
#include "optimizer/var.h"
#include "optimizer/tlist.h"
-static void set_join_tlist_references(Join *join);
-static void set_tempscan_tlist_references(SeqScan *tempscan);
-static void set_temp_tlist_references(Temp *temp);
-static List *replace_clause_joinvar_refs(Expr *clause,
- List *outer_tlist, List *inner_tlist);
-static List *replace_subclause_joinvar_refs(List *clauses,
- List *outer_tlist, List *inner_tlist);
-static Var *replace_joinvar_refs(Var *var, List *outer_tlist, List *inner_tlist);
-static List *tlist_temp_references(Oid tempid, List *tlist);
-static void replace_result_clause(List *clause, List *subplanTargetList);
-static bool OperandIsInner(Node *opnd, int inner_relid);
-static void replace_agg_clause(Node *expr, List *targetlist);
+static void set_join_tlist_references(Join * join);
+static void set_tempscan_tlist_references(SeqScan * tempscan);
+static void set_temp_tlist_references(Temp * temp);
+static List *
+replace_clause_joinvar_refs(Expr * clause,
+ List * outer_tlist, List * inner_tlist);
+static List *
+replace_subclause_joinvar_refs(List * clauses,
+ List * outer_tlist, List * inner_tlist);
+static Var *replace_joinvar_refs(Var * var, List * outer_tlist, List * inner_tlist);
+static List *tlist_temp_references(Oid tempid, List * tlist);
+static void replace_result_clause(List * clause, List * subplanTargetList);
+static bool OperandIsInner(Node * opnd, int inner_relid);
+static void replace_agg_clause(Node * expr, List * targetlist);
/*****************************************************************************
- *
- * SUBPLAN REFERENCES
- *
+ *
+ * SUBPLAN REFERENCES
+ *
*****************************************************************************/
-/*
+/*
* set-tlist-references--
- * Modifies the target list of nodes in a plan to reference target lists
- * at lower levels.
- *
+ * Modifies the target list of nodes in a plan to reference target lists
+ * at lower levels.
+ *
* 'plan' is the plan whose target list and children's target lists will
- * be modified
- *
+ * be modified
+ *
* Returns nothing of interest, but modifies internal fields of nodes.
- *
+ *
*/
void
-set_tlist_references(Plan *plan)
+set_tlist_references(Plan * plan)
{
- if(plan==NULL)
- return;
-
- if (IsA_Join(plan)) {
- set_join_tlist_references((Join*)plan);
- } else if (IsA(plan,SeqScan) && plan->lefttree &&
- IsA_Temp(plan->lefttree)) {
- set_tempscan_tlist_references((SeqScan*)plan);
- } else if (IsA(plan,Sort)) {
- set_temp_tlist_references ((Temp*)plan);
- } else if (IsA(plan,Result)) {
- set_result_tlist_references((Result*)plan);
- } else if (IsA(plan,Hash)) {
- set_tlist_references(plan->lefttree);
- } else if (IsA(plan,Choose)) {
- List *x;
- foreach (x, ((Choose*)plan)->chooseplanlist) {
- set_tlist_references((Plan*)lfirst(x));
- }
- }
+ if (plan == NULL)
+ return;
+
+ if (IsA_Join(plan))
+ {
+ set_join_tlist_references((Join *) plan);
+ }
+ else if (IsA(plan, SeqScan) && plan->lefttree &&
+ IsA_Temp(plan->lefttree))
+ {
+ set_tempscan_tlist_references((SeqScan *) plan);
+ }
+ else if (IsA(plan, Sort))
+ {
+ set_temp_tlist_references((Temp *) plan);
+ }
+ else if (IsA(plan, Result))
+ {
+ set_result_tlist_references((Result *) plan);
+ }
+ else if (IsA(plan, Hash))
+ {
+ set_tlist_references(plan->lefttree);
+ }
+ else if (IsA(plan, Choose))
+ {
+ List *x;
+
+ foreach(x, ((Choose *) plan)->chooseplanlist)
+ {
+ set_tlist_references((Plan *) lfirst(x));
+ }
+ }
}
-/*
+/*
* set-join-tlist-references--
- * Modifies the target list of a join node by setting the varnos and
- * varattnos to reference the target list of the outer and inner join
- * relations.
- *
- * Creates a target list for a join node to contain references by setting
- * varno values to OUTER or INNER and setting attno values to the
- * result domain number of either the corresponding outer or inner join
- * tuple.
- *
+ * Modifies the target list of a join node by setting the varnos and
+ * varattnos to reference the target list of the outer and inner join
+ * relations.
+ *
+ * Creates a target list for a join node to contain references by setting
+ * varno values to OUTER or INNER and setting attno values to the
+ * result domain number of either the corresponding outer or inner join
+ * tuple.
+ *
* 'join' is a join plan node
- *
+ *
* Returns nothing of interest, but modifies internal fields of nodes.
- *
+ *
*/
static void
-set_join_tlist_references(Join *join)
+set_join_tlist_references(Join * join)
{
- Plan *outer = ((Plan*)join)->lefttree;
- Plan *inner = ((Plan*)join)->righttree;
- List *new_join_targetlist = NIL;
- TargetEntry *temp = (TargetEntry *)NULL;
- List *entry = NIL;
- List *inner_tlist = NULL;
- List *outer_tlist = NULL;
- TargetEntry *xtl = (TargetEntry *)NULL;
- List *qptlist = ((Plan*)join)->targetlist;
-
- foreach(entry, qptlist) {
- List *joinvar;
-
- xtl = (TargetEntry *)lfirst(entry);
- inner_tlist = ((inner==NULL) ? NIL : inner->targetlist);
- outer_tlist = ((outer==NULL) ? NIL : outer->targetlist);
- joinvar = replace_clause_joinvar_refs((Expr*)get_expr(xtl),
- outer_tlist,
- inner_tlist);
-
- temp = MakeTLE(xtl->resdom, (Node*)joinvar);
- new_join_targetlist = lappend(new_join_targetlist,temp);
- }
-
- ((Plan*)join)->targetlist = new_join_targetlist;
- if (outer!=NULL)
- set_tlist_references(outer);
- if (inner!=NULL)
- set_tlist_references(inner);
+ Plan *outer = ((Plan *) join)->lefttree;
+ Plan *inner = ((Plan *) join)->righttree;
+ List *new_join_targetlist = NIL;
+ TargetEntry *temp = (TargetEntry *) NULL;
+ List *entry = NIL;
+ List *inner_tlist = NULL;
+ List *outer_tlist = NULL;
+ TargetEntry *xtl = (TargetEntry *) NULL;
+ List *qptlist = ((Plan *) join)->targetlist;
+
+ foreach(entry, qptlist)
+ {
+ List *joinvar;
+
+ xtl = (TargetEntry *) lfirst(entry);
+ inner_tlist = ((inner == NULL) ? NIL : inner->targetlist);
+ outer_tlist = ((outer == NULL) ? NIL : outer->targetlist);
+ joinvar = replace_clause_joinvar_refs((Expr *) get_expr(xtl),
+ outer_tlist,
+ inner_tlist);
+
+ temp = MakeTLE(xtl->resdom, (Node *) joinvar);
+ new_join_targetlist = lappend(new_join_targetlist, temp);
+ }
+
+ ((Plan *) join)->targetlist = new_join_targetlist;
+ if (outer != NULL)
+ set_tlist_references(outer);
+ if (inner != NULL)
+ set_tlist_references(inner);
}
-/*
+/*
* set-tempscan-tlist-references--
- * Modifies the target list of a node that scans a temp relation (i.e., a
- * sort or hash node) so that the varnos refer to the child temporary.
- *
+ * Modifies the target list of a node that scans a temp relation (i.e., a
+ * sort or hash node) so that the varnos refer to the child temporary.
+ *
* 'tempscan' is a seqscan node
- *
+ *
* Returns nothing of interest, but modifies internal fields of nodes.
- *
+ *
*/
static void
-set_tempscan_tlist_references(SeqScan *tempscan)
+set_tempscan_tlist_references(SeqScan * tempscan)
{
- Temp *temp = (Temp*)((Plan*)tempscan)->lefttree;
+ Temp *temp = (Temp *) ((Plan *) tempscan)->lefttree;
- ((Plan*)tempscan)->targetlist =
- tlist_temp_references(temp->tempid,
- ((Plan*)tempscan)->targetlist);
- set_temp_tlist_references(temp);
+ ((Plan *) tempscan)->targetlist =
+ tlist_temp_references(temp->tempid,
+ ((Plan *) tempscan)->targetlist);
+ set_temp_tlist_references(temp);
}
-/*
+/*
* set-temp-tlist-references--
- * The temp's vars are made consistent with (actually, identical to) the
- * modified version of the target list of the node from which temp node
- * receives its tuples.
- *
+ * The temp's vars are made consistent with (actually, identical to) the
+ * modified version of the target list of the node from which temp node
+ * receives its tuples.
+ *
* 'temp' is a temp (e.g., sort, hash) plan node
- *
+ *
* Returns nothing of interest, but modifies internal fields of nodes.
- *
+ *
*/
static void
-set_temp_tlist_references(Temp *temp)
+set_temp_tlist_references(Temp * temp)
{
- Plan *source = ((Plan*)temp)->lefttree;
-
- if (source!=NULL) {
- set_tlist_references(source);
- ((Plan*)temp)->targetlist =
- copy_vars(((Plan*)temp)->targetlist ,
- (source)->targetlist);
- } else {
- elog(WARN, "calling set_temp_tlist_references with empty lefttree");
- }
+ Plan *source = ((Plan *) temp)->lefttree;
+
+ if (source != NULL)
+ {
+ set_tlist_references(source);
+ ((Plan *) temp)->targetlist =
+ copy_vars(((Plan *) temp)->targetlist,
+ (source)->targetlist);
+ }
+ else
+ {
+ elog(WARN, "calling set_temp_tlist_references with empty lefttree");
+ }
}
-/*
+/*
* join-references--
- * Creates a new set of join clauses by replacing the varno/varattno
- * values of variables in the clauses to reference target list values
- * from the outer and inner join relation target lists.
- *
+ * Creates a new set of join clauses by replacing the varno/varattno
+ * values of variables in the clauses to reference target list values
+ * from the outer and inner join relation target lists.
+ *
* 'clauses' is the list of join clauses
* 'outer-tlist' is the target list of the outer join relation
* 'inner-tlist' is the target list of the inner join relation
- *
+ *
* Returns the new join clauses.
- *
+ *
*/
-List *
-join_references(List *clauses,
- List *outer_tlist,
- List *inner_tlist)
+List *
+join_references(List * clauses,
+ List * outer_tlist,
+ List * inner_tlist)
{
- return (replace_subclause_joinvar_refs(clauses,
- outer_tlist,
- inner_tlist));
+ return (replace_subclause_joinvar_refs(clauses,
+ outer_tlist,
+ inner_tlist));
}
-/*
+/*
* index-outerjoin-references--
- * Given a list of join clauses, replace the operand corresponding to the
- * outer relation in the join with references to the corresponding target
- * list element in 'outer-tlist' (the outer is rather obscurely
- * identified as the side that doesn't contain a var whose varno equals
- * 'inner-relid').
- *
- * As a side effect, the operator is replaced by the regproc id.
- *
+ * Given a list of join clauses, replace the operand corresponding to the
+ * outer relation in the join with references to the corresponding target
+ * list element in 'outer-tlist' (the outer is rather obscurely
+ * identified as the side that doesn't contain a var whose varno equals
+ * 'inner-relid').
+ *
+ * As a side effect, the operator is replaced by the regproc id.
+ *
* 'inner-indxqual' is the list of join clauses (so-called because they
* are used as qualifications for the inner (inbex) scan of a nestloop)
- *
+ *
* Returns the new list of clauses.
- *
+ *
*/
-List *
-index_outerjoin_references(List *inner_indxqual,
- List *outer_tlist,
- Index inner_relid)
+List *
+index_outerjoin_references(List * inner_indxqual,
+ List * outer_tlist,
+ Index inner_relid)
{
- List *t_list = NIL;
- Expr *temp = NULL;
- List *t_clause = NIL;
- Expr *clause = NULL;
+ List *t_list = NIL;
+ Expr *temp = NULL;
+ List *t_clause = NIL;
+ Expr *clause = NULL;
- foreach (t_clause,inner_indxqual) {
- clause = lfirst(t_clause);
- /*
- * if inner scan on the right.
- */
- if (OperandIsInner((Node*)get_rightop(clause), inner_relid)) {
- Var *joinvar = (Var*)
- replace_clause_joinvar_refs((Expr*)get_leftop(clause),
- outer_tlist,
- NIL);
- temp = make_opclause(replace_opid((Oper*)((Expr*)clause)->oper),
- joinvar,
- get_rightop(clause));
- t_list = lappend(t_list,temp);
- } else {
- /* inner scan on left */
- Var *joinvar = (Var*)
- replace_clause_joinvar_refs((Expr*)get_rightop(clause),
- outer_tlist,
- NIL);
- temp = make_opclause(replace_opid((Oper*)((Expr*)clause)->oper),
- get_leftop(clause),
- joinvar);
- t_list = lappend(t_list,temp);
- }
-
- }
- return(t_list);
+ foreach(t_clause, inner_indxqual)
+ {
+ clause = lfirst(t_clause);
+
+ /*
+ * if inner scan on the right.
+ */
+ if (OperandIsInner((Node *) get_rightop(clause), inner_relid))
+ {
+ Var *joinvar = (Var *)
+ replace_clause_joinvar_refs((Expr *) get_leftop(clause),
+ outer_tlist,
+ NIL);
+
+ temp = make_opclause(replace_opid((Oper *) ((Expr *) clause)->oper),
+ joinvar,
+ get_rightop(clause));
+ t_list = lappend(t_list, temp);
+ }
+ else
+ {
+ /* inner scan on left */
+ Var *joinvar = (Var *)
+ replace_clause_joinvar_refs((Expr *) get_rightop(clause),
+ outer_tlist,
+ NIL);
+
+ temp = make_opclause(replace_opid((Oper *) ((Expr *) clause)->oper),
+ get_leftop(clause),
+ joinvar);
+ t_list = lappend(t_list, temp);
+ }
+
+ }
+ return (t_list);
}
-/*
+/*
* replace-clause-joinvar-refs
* replace-subclause-joinvar-refs
* replace-joinvar-refs
- *
- * Replaces all variables within a join clause with a new var node
- * whose varno/varattno fields contain a reference to a target list
- * element from either the outer or inner join relation.
- *
+ *
+ * Replaces all variables within a join clause with a new var node
+ * whose varno/varattno fields contain a reference to a target list
+ * element from either the outer or inner join relation.
+ *
* 'clause' is the join clause
* 'outer-tlist' is the target list of the outer join relation
* 'inner-tlist' is the target list of the inner join relation
- *
+ *
* Returns the new join clause.
- *
+ *
*/
-static List *
-replace_clause_joinvar_refs(Expr *clause,
- List *outer_tlist,
- List *inner_tlist)
+static List *
+replace_clause_joinvar_refs(Expr * clause,
+ List * outer_tlist,
+ List * inner_tlist)
{
- List *temp = NULL;
+ List *temp = NULL;
- if(IsA (clause,Var)) {
- temp = (List*)replace_joinvar_refs((Var*)clause,
- outer_tlist,inner_tlist);
- if(temp)
- return(temp);
- else
- if (clause != NULL)
- return((List*)clause);
- else
- return(NIL);
- } else if (single_node((Node*)clause)) {
- return ((List*)clause);
- } else if (or_clause((Node*)clause)) {
- List *orclause =
- replace_subclause_joinvar_refs(((Expr*)clause)->args,
- outer_tlist,
- inner_tlist);
- return ((List*)make_orclause(orclause));
- } else if (IsA(clause,ArrayRef)) {
- ArrayRef *aref = (ArrayRef *)clause;
-
- temp = replace_subclause_joinvar_refs(aref->refupperindexpr,
- outer_tlist,
- inner_tlist);
- aref->refupperindexpr = (List*)temp;
- temp = replace_subclause_joinvar_refs(aref->reflowerindexpr,
- outer_tlist,
- inner_tlist);
- aref->reflowerindexpr = (List*)temp;
- temp = replace_clause_joinvar_refs((Expr*)aref->refexpr,
- outer_tlist,
- inner_tlist);
- aref->refexpr = (Node*)temp;
+ if (IsA(clause, Var))
+ {
+ temp = (List *) replace_joinvar_refs((Var *) clause,
+ outer_tlist, inner_tlist);
+ if (temp)
+ return (temp);
+ else if (clause != NULL)
+ return ((List *) clause);
+ else
+ return (NIL);
+ }
+ else if (single_node((Node *) clause))
+ {
+ return ((List *) clause);
+ }
+ else if (or_clause((Node *) clause))
+ {
+ List *orclause =
+ replace_subclause_joinvar_refs(((Expr *) clause)->args,
+ outer_tlist,
+ inner_tlist);
- /*
- * no need to set refassgnexpr. we only set that in the
- * target list on replaces, and this is an array reference
- * in the qualification. if we got this far, it's 0x0 in
- * the ArrayRef structure 'clause'.
- */
+ return ((List *) make_orclause(orclause));
+ }
+ else if (IsA(clause, ArrayRef))
+ {
+ ArrayRef *aref = (ArrayRef *) clause;
+
+ temp = replace_subclause_joinvar_refs(aref->refupperindexpr,
+ outer_tlist,
+ inner_tlist);
+ aref->refupperindexpr = (List *) temp;
+ temp = replace_subclause_joinvar_refs(aref->reflowerindexpr,
+ outer_tlist,
+ inner_tlist);
+ aref->reflowerindexpr = (List *) temp;
+ temp = replace_clause_joinvar_refs((Expr *) aref->refexpr,
+ outer_tlist,
+ inner_tlist);
+ aref->refexpr = (Node *) temp;
+
+ /*
+ * no need to set refassgnexpr. we only set that in the target
+ * list on replaces, and this is an array reference in the
+ * qualification. if we got this far, it's 0x0 in the ArrayRef
+ * structure 'clause'.
+ */
+
+ return ((List *) clause);
+ }
+ else if (is_funcclause((Node *) clause))
+ {
+ List *funcclause =
+ replace_subclause_joinvar_refs(((Expr *) clause)->args,
+ outer_tlist,
+ inner_tlist);
+
+ return ((List *) make_funcclause((Func *) ((Expr *) clause)->oper,
+ funcclause));
+ }
+ else if (not_clause((Node *) clause))
+ {
+ List *notclause =
+ replace_clause_joinvar_refs(get_notclausearg(clause),
+ outer_tlist,
+ inner_tlist);
- return((List*)clause);
- } else if (is_funcclause((Node*)clause)) {
- List *funcclause =
- replace_subclause_joinvar_refs(((Expr*)clause)->args,
- outer_tlist,
- inner_tlist);
- return ((List*)make_funcclause((Func*)((Expr*)clause)->oper,
- funcclause));
- } else if (not_clause((Node*)clause)) {
- List *notclause =
- replace_clause_joinvar_refs(get_notclausearg(clause),
- outer_tlist,
- inner_tlist);
- return ((List*)make_notclause((Expr*)notclause));
- } else if (is_opclause((Node*)clause)) {
- Var *leftvar =
- (Var*)replace_clause_joinvar_refs((Expr*)get_leftop(clause),
- outer_tlist,
- inner_tlist);
- Var *rightvar =
- (Var*)replace_clause_joinvar_refs((Expr*)get_rightop(clause),
- outer_tlist,
- inner_tlist);
- return ((List*)make_opclause(replace_opid((Oper*)((Expr*)clause)->oper),
- leftvar,
- rightvar));
- }
- /* shouldn't reach here */
- return NULL;
+ return ((List *) make_notclause((Expr *) notclause));
+ }
+ else if (is_opclause((Node *) clause))
+ {
+ Var *leftvar =
+ (Var *) replace_clause_joinvar_refs((Expr *) get_leftop(clause),
+ outer_tlist,
+ inner_tlist);
+ Var *rightvar =
+ (Var *) replace_clause_joinvar_refs((Expr *) get_rightop(clause),
+ outer_tlist,
+ inner_tlist);
+
+ return ((List *) make_opclause(replace_opid((Oper *) ((Expr *) clause)->oper),
+ leftvar,
+ rightvar));
+ }
+ /* shouldn't reach here */
+ return NULL;
}
-static List *
-replace_subclause_joinvar_refs(List *clauses,
- List *outer_tlist,
- List *inner_tlist)
+static List *
+replace_subclause_joinvar_refs(List * clauses,
+ List * outer_tlist,
+ List * inner_tlist)
{
- List *t_list = NIL;
- List *temp = NIL;
- List *clause = NIL;
-
- foreach (clause,clauses) {
- temp = replace_clause_joinvar_refs(lfirst(clause),
- outer_tlist,
- inner_tlist);
- t_list = lappend(t_list,temp);
- }
- return(t_list);
+ List *t_list = NIL;
+ List *temp = NIL;
+ List *clause = NIL;
+
+ foreach(clause, clauses)
+ {
+ temp = replace_clause_joinvar_refs(lfirst(clause),
+ outer_tlist,
+ inner_tlist);
+ t_list = lappend(t_list, temp);
+ }
+ return (t_list);
}
-static Var *
-replace_joinvar_refs(Var *var, List *outer_tlist, List *inner_tlist)
+static Var *
+replace_joinvar_refs(Var * var, List * outer_tlist, List * inner_tlist)
{
- Resdom *outer_resdom =(Resdom*)NULL;
-
- outer_resdom= tlist_member(var,outer_tlist);
-
- if (outer_resdom!=NULL && IsA (outer_resdom,Resdom) ) {
- return (makeVar (OUTER,
- outer_resdom->resno,
- var->vartype,
- var->varnoold,
- var->varoattno));
- } else {
- Resdom *inner_resdom;
- inner_resdom = tlist_member(var,inner_tlist);
- if ( inner_resdom!=NULL && IsA (inner_resdom,Resdom) ) {
- return (makeVar (INNER,
- inner_resdom->resno,
- var->vartype,
- var->varnoold,
- var->varoattno));
- }
- }
- return (Var*)NULL;
+ Resdom *outer_resdom = (Resdom *) NULL;
+
+ outer_resdom = tlist_member(var, outer_tlist);
+
+ if (outer_resdom != NULL && IsA(outer_resdom, Resdom))
+ {
+ return (makeVar(OUTER,
+ outer_resdom->resno,
+ var->vartype,
+ var->varnoold,
+ var->varoattno));
+ }
+ else
+ {
+ Resdom *inner_resdom;
+
+ inner_resdom = tlist_member(var, inner_tlist);
+ if (inner_resdom != NULL && IsA(inner_resdom, Resdom))
+ {
+ return (makeVar(INNER,
+ inner_resdom->resno,
+ var->vartype,
+ var->varnoold,
+ var->varoattno));
+ }
+ }
+ return (Var *) NULL;
}
-/*
+/*
* tlist-temp-references--
- * Creates a new target list for a node that scans a temp relation,
- * setting the varnos to the id of the temp relation and setting varids
- * if necessary (varids are only needed if this is a targetlist internal
- * to the tree, in which case the targetlist entry always contains a var
- * node, so we can just copy it from the temp).
- *
+ * Creates a new target list for a node that scans a temp relation,
+ * setting the varnos to the id of the temp relation and setting varids
+ * if necessary (varids are only needed if this is a targetlist internal
+ * to the tree, in which case the targetlist entry always contains a var
+ * node, so we can just copy it from the temp).
+ *
* 'tempid' is the id of the temp relation
* 'tlist' is the target list to be modified
- *
+ *
* Returns new target list
- *
+ *
*/
-static List *
-tlist_temp_references(Oid tempid,
- List *tlist)
+static List *
+tlist_temp_references(Oid tempid,
+ List * tlist)
{
- List *t_list = NIL;
- TargetEntry *temp = (TargetEntry *)NULL;
- TargetEntry *xtl = NULL;
- List *entry;
-
- foreach (entry, tlist) {
- AttrNumber oattno;
-
- xtl = lfirst(entry);
- if (IsA(get_expr(xtl), Var))
- oattno = ((Var*)xtl->expr)->varoattno;
- else
- oattno = 0;
-
- temp = MakeTLE(xtl->resdom,
- (Node*)makeVar(tempid,
- xtl->resdom->resno,
- xtl->resdom->restype,
- tempid,
- oattno));
-
- t_list = lappend(t_list,temp);
- }
- return(t_list);
+ List *t_list = NIL;
+ TargetEntry *temp = (TargetEntry *) NULL;
+ TargetEntry *xtl = NULL;
+ List *entry;
+
+ foreach(entry, tlist)
+ {
+ AttrNumber oattno;
+
+ xtl = lfirst(entry);
+ if (IsA(get_expr(xtl), Var))
+ oattno = ((Var *) xtl->expr)->varoattno;
+ else
+ oattno = 0;
+
+ temp = MakeTLE(xtl->resdom,
+ (Node *) makeVar(tempid,
+ xtl->resdom->resno,
+ xtl->resdom->restype,
+ tempid,
+ oattno));
+
+ t_list = lappend(t_list, temp);
+ }
+ return (t_list);
}
/*---------------------------------------------------------
@@ -456,45 +505,49 @@ tlist_temp_references(Oid tempid,
* addresses the tuples returned by its left tree subplan.
*
* NOTE:
- * 1) we ignore the right tree! (in the current implementation
- * it is always nil
- * 2) this routine will probably *NOT* work with nested dot
- * fields....
+ * 1) we ignore the right tree! (in the current implementation
+ * it is always nil
+ * 2) this routine will probably *NOT* work with nested dot
+ * fields....
*/
void
-set_result_tlist_references(Result *resultNode)
+set_result_tlist_references(Result * resultNode)
{
- Plan *subplan;
- List *resultTargetList;
- List *subplanTargetList;
- List *t;
- TargetEntry *entry;
- Expr *expr;
-
- resultTargetList= ((Plan*)resultNode)->targetlist;
-
- /*
- * NOTE: we only consider the left tree subplan.
- * This is usually a seq scan.
- */
- subplan = ((Plan*)resultNode)->lefttree;
- if (subplan != NULL) {
- subplanTargetList = subplan->targetlist;
- } else {
- subplanTargetList = NIL;
- }
-
- /*
- * now for traverse all the entris of the target list.
- * These should be of the form (Resdom_Node Expression).
- * For every expression clause, call "replace_result_clause()"
- * to appropriatelly change all the Var nodes.
- */
- foreach (t, resultTargetList) {
- entry = (TargetEntry *)lfirst(t);
- expr = (Expr*) get_expr(entry);
- replace_result_clause((List*)expr, subplanTargetList);
- }
+ Plan *subplan;
+ List *resultTargetList;
+ List *subplanTargetList;
+ List *t;
+ TargetEntry *entry;
+ Expr *expr;
+
+ resultTargetList = ((Plan *) resultNode)->targetlist;
+
+ /*
+ * NOTE: we only consider the left tree subplan. This is usually a seq
+ * scan.
+ */
+ subplan = ((Plan *) resultNode)->lefttree;
+ if (subplan != NULL)
+ {
+ subplanTargetList = subplan->targetlist;
+ }
+ else
+ {
+ subplanTargetList = NIL;
+ }
+
+ /*
+ * now for traverse all the entris of the target list. These should be
+ * of the form (Resdom_Node Expression). For every expression clause,
+ * call "replace_result_clause()" to appropriatelly change all the Var
+ * nodes.
+ */
+ foreach(t, resultTargetList)
+ {
+ entry = (TargetEntry *) lfirst(t);
+ expr = (Expr *) get_expr(entry);
+ replace_result_clause((List *) expr, subplanTargetList);
+ }
}
/*---------------------------------------------------------
@@ -504,100 +557,121 @@ set_result_tlist_references(Result *resultNode)
* This routine is called from set_result_tlist_references().
* and modifies the expressions of the target list of a Result
* node so that all Var nodes reference the target list of its subplan.
- *
+ *
*/
static void
-replace_result_clause(List *clause,
- List *subplanTargetList) /* target list of the
- subplan */
+replace_result_clause(List * clause,
+ List * subplanTargetList) /* target list of the
+ * subplan */
{
- List *t;
- List *subClause;
- TargetEntry *subplanVar;
+ List *t;
+ List *subClause;
+ TargetEntry *subplanVar;
- if (IsA(clause,Var)) {
- /*
- * Ha! A Var node!
- */
- subplanVar = match_varid((Var*)clause, subplanTargetList);
- /*
- * Change the varno & varattno fields of the
- * var node.
- *
- */
- ((Var*)clause)->varno = (Index)OUTER;
- ((Var*)clause)->varattno = subplanVar->resdom->resno;
- } else if (is_funcclause((Node*)clause)) {
- /*
- * This is a function. Recursively call this routine
- * for its arguments...
- */
- subClause = ((Expr*)clause)->args;
- foreach (t, subClause) {
- replace_result_clause(lfirst(t),subplanTargetList);
- }
- } else if (IsA(clause,ArrayRef)) {
- ArrayRef *aref = (ArrayRef *)clause;
- /*
- * This is an arrayref. Recursively call this routine
- * for its expression and its index expression...
- */
- subClause = aref->refupperindexpr;
- foreach (t, subClause) {
- replace_result_clause(lfirst(t),subplanTargetList);
- }
- subClause = aref->reflowerindexpr;
- foreach (t, subClause) {
- replace_result_clause(lfirst(t),subplanTargetList);
- }
- replace_result_clause((List*)aref->refexpr,
- subplanTargetList);
- replace_result_clause((List*)aref->refassgnexpr,
- subplanTargetList);
- } else if (is_opclause((Node*)clause)) {
- /*
- * This is an operator. Recursively call this routine
- * for both its left and right operands
- */
- subClause = (List*)get_leftop((Expr*)clause);
- replace_result_clause(subClause,subplanTargetList);
- subClause = (List*)get_rightop((Expr*)clause);
- replace_result_clause(subClause,subplanTargetList);
- } else if (IsA(clause,Param) || IsA(clause,Const)) {
- /* do nothing! */
- } else {
- /*
- * Ooops! we can not handle that!
- */
- elog(WARN,"replace_result_clause: Can not handle this tlist!\n");
- }
+ if (IsA(clause, Var))
+ {
+
+ /*
+ * Ha! A Var node!
+ */
+ subplanVar = match_varid((Var *) clause, subplanTargetList);
+
+ /*
+ * Change the varno & varattno fields of the var node.
+ *
+ */
+ ((Var *) clause)->varno = (Index) OUTER;
+ ((Var *) clause)->varattno = subplanVar->resdom->resno;
+ }
+ else if (is_funcclause((Node *) clause))
+ {
+
+ /*
+ * This is a function. Recursively call this routine for its
+ * arguments...
+ */
+ subClause = ((Expr *) clause)->args;
+ foreach(t, subClause)
+ {
+ replace_result_clause(lfirst(t), subplanTargetList);
+ }
+ }
+ else if (IsA(clause, ArrayRef))
+ {
+ ArrayRef *aref = (ArrayRef *) clause;
+
+ /*
+ * This is an arrayref. Recursively call this routine for its
+ * expression and its index expression...
+ */
+ subClause = aref->refupperindexpr;
+ foreach(t, subClause)
+ {
+ replace_result_clause(lfirst(t), subplanTargetList);
+ }
+ subClause = aref->reflowerindexpr;
+ foreach(t, subClause)
+ {
+ replace_result_clause(lfirst(t), subplanTargetList);
+ }
+ replace_result_clause((List *) aref->refexpr,
+ subplanTargetList);
+ replace_result_clause((List *) aref->refassgnexpr,
+ subplanTargetList);
+ }
+ else if (is_opclause((Node *) clause))
+ {
+
+ /*
+ * This is an operator. Recursively call this routine for both its
+ * left and right operands
+ */
+ subClause = (List *) get_leftop((Expr *) clause);
+ replace_result_clause(subClause, subplanTargetList);
+ subClause = (List *) get_rightop((Expr *) clause);
+ replace_result_clause(subClause, subplanTargetList);
+ }
+ else if (IsA(clause, Param) || IsA(clause, Const))
+ {
+ /* do nothing! */
+ }
+ else
+ {
+
+ /*
+ * Ooops! we can not handle that!
+ */
+ elog(WARN, "replace_result_clause: Can not handle this tlist!\n");
+ }
}
static
-bool OperandIsInner(Node *opnd, int inner_relid)
+bool
+OperandIsInner(Node * opnd, int inner_relid)
{
- /*
- * Can be the inner scan if its a varnode or a function and the
- * inner_relid is equal to the varnode's var number or in the
- * case of a function the first argument's var number (all args
- * in a functional index are from the same relation).
- */
- if ( IsA (opnd,Var) &&
- (inner_relid == ((Var*)opnd)->varno) )
+
+ /*
+ * Can be the inner scan if its a varnode or a function and the
+ * inner_relid is equal to the varnode's var number or in the case of
+ * a function the first argument's var number (all args in a
+ * functional index are from the same relation).
+ */
+ if (IsA(opnd, Var) &&
+ (inner_relid == ((Var *) opnd)->varno))
{
- return true;
+ return true;
}
- if (is_funcclause(opnd))
+ if (is_funcclause(opnd))
{
- List *firstArg = lfirst(((Expr*)opnd)->args);
+ List *firstArg = lfirst(((Expr *) opnd)->args);
- if ( IsA (firstArg,Var) &&
- (inner_relid == ((Var*)firstArg)->varno) )
+ if (IsA(firstArg, Var) &&
+ (inner_relid == ((Var *) firstArg)->varno))
{
- return true;
+ return true;
}
}
- return false;
+ return false;
}
/*****************************************************************************
@@ -607,105 +681,125 @@ bool OperandIsInner(Node *opnd, int inner_relid)
/*---------------------------------------------------------
*
* set_agg_tlist_references -
- * changes the target list of an Agg node so that it points to
- * the tuples returned by its left tree subplan.
+ * changes the target list of an Agg node so that it points to
+ * the tuples returned by its left tree subplan.
*
*/
void
-set_agg_tlist_references(Agg *aggNode)
+set_agg_tlist_references(Agg * aggNode)
{
- List *aggTargetList;
- List *subplanTargetList;
- List *tl;
+ List *aggTargetList;
+ List *subplanTargetList;
+ List *tl;
- aggTargetList = aggNode->plan.targetlist;
- subplanTargetList = aggNode->plan.lefttree->targetlist;
+ aggTargetList = aggNode->plan.targetlist;
+ subplanTargetList = aggNode->plan.lefttree->targetlist;
- foreach (tl, aggTargetList) {
- TargetEntry *tle = lfirst(tl);
+ foreach(tl, aggTargetList)
+ {
+ TargetEntry *tle = lfirst(tl);
- replace_agg_clause(tle->expr, subplanTargetList);
- }
+ replace_agg_clause(tle->expr, subplanTargetList);
+ }
}
void
-set_agg_agglist_references(Agg *aggNode)
+set_agg_agglist_references(Agg * aggNode)
{
- List *subplanTargetList;
- Aggreg **aggs;
- int i;
+ List *subplanTargetList;
+ Aggreg **aggs;
+ int i;
- aggs = aggNode->aggs;
- subplanTargetList = aggNode->plan.lefttree->targetlist;
+ aggs = aggNode->aggs;
+ subplanTargetList = aggNode->plan.lefttree->targetlist;
- for (i = 0; i < aggNode->numAgg; i++) {
- replace_agg_clause(aggs[i]->target, subplanTargetList);
- }
+ for (i = 0; i < aggNode->numAgg; i++)
+ {
+ replace_agg_clause(aggs[i]->target, subplanTargetList);
+ }
}
static void
-replace_agg_clause(Node *clause, List *subplanTargetList)
+replace_agg_clause(Node * clause, List * subplanTargetList)
{
- List *t;
- TargetEntry *subplanVar;
+ List *t;
+ TargetEntry *subplanVar;
- if (IsA(clause,Var)) {
- /*
- * Ha! A Var node!
- */
- subplanVar = match_varid((Var*)clause, subplanTargetList);
- /*
- * Change the varno & varattno fields of the
- * var node.
- *
- */
- ((Var*)clause)->varattno = subplanVar->resdom->resno;
- } else if (is_funcclause(clause)) {
- /*
- * This is a function. Recursively call this routine
- * for its arguments...
- */
- foreach (t, ((Expr*)clause)->args) {
- replace_agg_clause(lfirst(t), subplanTargetList);
- }
- } else if (IsA(clause,Aggreg)) {
- replace_agg_clause(((Aggreg*)clause)->target, subplanTargetList);
- } else if (IsA(clause,ArrayRef)) {
- ArrayRef *aref = (ArrayRef *)clause;
+ if (IsA(clause, Var))
+ {
- /*
- * This is an arrayref. Recursively call this routine
- * for its expression and its index expression...
- */
- foreach (t, aref->refupperindexpr) {
- replace_agg_clause(lfirst(t),subplanTargetList);
+ /*
+ * Ha! A Var node!
+ */
+ subplanVar = match_varid((Var *) clause, subplanTargetList);
+
+ /*
+ * Change the varno & varattno fields of the var node.
+ *
+ */
+ ((Var *) clause)->varattno = subplanVar->resdom->resno;
+ }
+ else if (is_funcclause(clause))
+ {
+
+ /*
+ * This is a function. Recursively call this routine for its
+ * arguments...
+ */
+ foreach(t, ((Expr *) clause)->args)
+ {
+ replace_agg_clause(lfirst(t), subplanTargetList);
+ }
}
- foreach (t, aref->reflowerindexpr) {
- replace_agg_clause(lfirst(t),subplanTargetList);
+ else if (IsA(clause, Aggreg))
+ {
+ replace_agg_clause(((Aggreg *) clause)->target, subplanTargetList);
}
- replace_agg_clause(aref->refexpr, subplanTargetList);
- replace_agg_clause(aref->refassgnexpr, subplanTargetList);
- } else if (is_opclause(clause)) {
- /*
- * This is an operator. Recursively call this routine
- * for both its left and right operands
- */
- Node *left = (Node*)get_leftop((Expr*)clause);
- Node *right = (Node*)get_rightop((Expr*)clause);
-
- if ( left != (Node*) NULL )
- replace_agg_clause(left, subplanTargetList);
- if ( right != (Node*) NULL )
- replace_agg_clause(right, subplanTargetList);
- } else if (IsA(clause,Param) || IsA(clause,Const)) {
- /* do nothing! */
- } else {
- /*
- * Ooops! we can not handle that!
- */
- elog(WARN,"replace_agg_clause: Can not handle this tlist!\n");
- }
+ else if (IsA(clause, ArrayRef))
+ {
+ ArrayRef *aref = (ArrayRef *) clause;
-}
+ /*
+ * This is an arrayref. Recursively call this routine for its
+ * expression and its index expression...
+ */
+ foreach(t, aref->refupperindexpr)
+ {
+ replace_agg_clause(lfirst(t), subplanTargetList);
+ }
+ foreach(t, aref->reflowerindexpr)
+ {
+ replace_agg_clause(lfirst(t), subplanTargetList);
+ }
+ replace_agg_clause(aref->refexpr, subplanTargetList);
+ replace_agg_clause(aref->refassgnexpr, subplanTargetList);
+ }
+ else if (is_opclause(clause))
+ {
+
+ /*
+ * This is an operator. Recursively call this routine for both its
+ * left and right operands
+ */
+ Node *left = (Node *) get_leftop((Expr *) clause);
+ Node *right = (Node *) get_rightop((Expr *) clause);
+
+ if (left != (Node *) NULL)
+ replace_agg_clause(left, subplanTargetList);
+ if (right != (Node *) NULL)
+ replace_agg_clause(right, subplanTargetList);
+ }
+ else if (IsA(clause, Param) || IsA(clause, Const))
+ {
+ /* do nothing! */
+ }
+ else
+ {
+ /*
+ * Ooops! we can not handle that!
+ */
+ elog(WARN, "replace_agg_clause: Can not handle this tlist!\n");
+ }
+}
diff --git a/src/backend/optimizer/prep/archive.c b/src/backend/optimizer/prep/archive.c
index 0303eca70f1..bbc797234ac 100644
--- a/src/backend/optimizer/prep/archive.c
+++ b/src/backend/optimizer/prep/archive.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* archive.c--
- * Support for planning scans on archived relations
+ * Support for planning scans on archived relations
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/Attic/archive.c,v 1.1.1.1 1996/07/09 06:21:38 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/Attic/archive.c,v 1.2 1997/09/07 04:44:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
-#include <sys/types.h> /* for u_int in relcache.h */
+#include <stdio.h> /* for sprintf() */
+#include <sys/types.h> /* for u_int in relcache.h */
#include "postgres.h"
#include "utils/rel.h"
@@ -26,41 +26,44 @@
#include "commands/creatinh.h"
void
-plan_archive(List *rt)
+plan_archive(List * rt)
{
- List *rtitem;
- RangeTblEntry *rte;
- TimeRange *trange;
- Relation r;
- Oid reloid;
+ List *rtitem;
+ RangeTblEntry *rte;
+ TimeRange *trange;
+ Relation r;
+ Oid reloid;
- foreach(rtitem, rt) {
- rte = lfirst(rtitem);
- trange = rte->timeRange;
- if (trange) {
- reloid = rte->relid;
- r = RelationIdGetRelation(reloid);
- if (r->rd_rel->relarch != 'n') {
- rte->archive = true;
- }
+ foreach(rtitem, rt)
+ {
+ rte = lfirst(rtitem);
+ trange = rte->timeRange;
+ if (trange)
+ {
+ reloid = rte->relid;
+ r = RelationIdGetRelation(reloid);
+ if (r->rd_rel->relarch != 'n')
+ {
+ rte->archive = true;
+ }
+ }
}
- }
}
/*
- * find_archive_rels -- Given a particular relid, find the archive
- * relation's relid.
+ * find_archive_rels -- Given a particular relid, find the archive
+ * relation's relid.
*/
-List *
+List *
find_archive_rels(Oid relid)
{
- Relation arel;
- char *arelName;
+ Relation arel;
+ char *arelName;
- arelName = MakeArchiveName(relid);
- arel = RelationNameGetRelation(arelName);
- pfree(arelName);
+ arelName = MakeArchiveName(relid);
+ arel = RelationNameGetRelation(arelName);
+ pfree(arelName);
- return lconsi(arel->rd_id, lconsi(relid, NIL));
+ return lconsi(arel->rd_id, lconsi(relid, NIL));
}
diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c
index 148f9638089..eac1eafa44f 100644
--- a/src/backend/optimizer/prep/prepqual.c
+++ b/src/backend/optimizer/prep/prepqual.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* prepqual.c--
- * Routines for preprocessing the parse tree qualification
+ * Routines for preprocessing the parse tree qualification
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.3 1997/08/20 14:53:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.4 1997/09/07 04:44:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,531 +24,608 @@
#include "utils/lsyscache.h"
-static Expr *pull_args(Expr *qual);
-static List *pull_ors(List *orlist);
-static List *pull_ands(List *andlist);
-static Expr *find_nots(Expr *qual);
-static Expr *push_nots(Expr *qual);
-static Expr *normalize(Expr *qual);
-static List *or_normalize(List *orlist);
-static List *distribute_args(List *item, List *args);
-static List *qualcleanup(Expr *qual);
-static List *remove_ands(Expr *qual);
-static List *remove_duplicates(List *list);
-
-/*
+static Expr *pull_args(Expr * qual);
+static List *pull_ors(List * orlist);
+static List *pull_ands(List * andlist);
+static Expr *find_nots(Expr * qual);
+static Expr *push_nots(Expr * qual);
+static Expr *normalize(Expr * qual);
+static List *or_normalize(List * orlist);
+static List *distribute_args(List * item, List * args);
+static List *qualcleanup(Expr * qual);
+static List *remove_ands(Expr * qual);
+static List *remove_duplicates(List * list);
+
+/*
* preprocess-qualification--
- * Driver routine for modifying the parse tree qualification.
- *
+ * Driver routine for modifying the parse tree qualification.
+ *
* Returns the new base qualification and the existential qualification
* in existentialQualPtr.
- *
- * XXX right now, update_clauses() does nothing so
- * preprocess-qualification simply converts the qual in conjunctive
- * normal form (see cnfify() below )
+ *
+ * XXX right now, update_clauses() does nothing so
+ * preprocess-qualification simply converts the qual in conjunctive
+ * normal form (see cnfify() below )
*/
-List *
-preprocess_qualification(Expr *qual, List *tlist, List **existentialQualPtr)
+List *
+preprocess_qualification(Expr * qual, List * tlist, List ** existentialQualPtr)
{
- List *cnf_qual = cnfify(qual, true);
+ List *cnf_qual = cnfify(qual, true);
+
/*
- List *existential_qual =
- update_clauses(intCons(_query_result_relation_,
- update_relations(tlist)),
- cnf_qual,
- _query_command_type_);
- if (existential_qual) {
- *existentialQualPtr = existential_qual;
- return set_difference(cnf_qual, existential_qual);
- } else {
+ List *existential_qual =
+ update_clauses(intCons(_query_result_relation_,
+ update_relations(tlist)),
+ cnf_qual,
+ _query_command_type_);
+ if (existential_qual) {
+ *existentialQualPtr = existential_qual;
+ return set_difference(cnf_qual, existential_qual);
+ } else {
+ *existentialQualPtr = NIL;
+ return cnf_qual;
+ }
+*/
+ /* update_clauses() is not working right now */
*existentialQualPtr = NIL;
return cnf_qual;
- }
-*/
- /* update_clauses() is not working right now */
- *existentialQualPtr = NIL;
- return cnf_qual;
}
/*****************************************************************************
*
- * CNF CONVERSION ROUTINES
- *
- * NOTES:
- * The basic algorithms for normalizing the qualification are taken
- * from ingres/source/qrymod/norml.c
- *
- * Remember that the initial qualification may consist of ARBITRARY
- * combinations of clauses. In addition, before this routine is called,
- * the qualification will contain explicit "AND"s.
- *
+ * CNF CONVERSION ROUTINES
+ *
+ * NOTES:
+ * The basic algorithms for normalizing the qualification are taken
+ * from ingres/source/qrymod/norml.c
+ *
+ * Remember that the initial qualification may consist of ARBITRARY
+ * combinations of clauses. In addition, before this routine is called,
+ * the qualification will contain explicit "AND"s.
+ *
*****************************************************************************/
-/*
+/*
* cnfify--
- * Convert a qualification to conjunctive normal form by applying
- * successive normalizations.
- *
+ * Convert a qualification to conjunctive normal form by applying
+ * successive normalizations.
+ *
* Returns the modified qualification with an extra level of nesting.
*
* If 'removeAndFlag' is true then it removes the explicit ANDs.
*
* NOTE: this routine is called by the planner (removeAndFlag = true)
- * and from the rule manager (removeAndFlag = false).
+ * and from the rule manager (removeAndFlag = false).
*
*/
-List *
-cnfify(Expr *qual, bool removeAndFlag)
+List *
+cnfify(Expr * qual, bool removeAndFlag)
{
- Expr *newqual = NULL;
-
- if (qual != NULL) {
- newqual = find_nots(pull_args(qual));
- newqual = normalize(pull_args(newqual));
- newqual = (Expr*)qualcleanup(pull_args(newqual));
- newqual = pull_args(newqual);;
-
- if (removeAndFlag) {
- if(and_clause((Node*)newqual))
- newqual=(Expr*)remove_ands(newqual);
- else
- newqual=(Expr*)remove_ands(make_andclause(lcons(newqual,NIL)));
- }
- }
- else if (qual!=NULL)
- newqual = (Expr*)lcons(qual, NIL);
-
- return (List*)(newqual);
+ Expr *newqual = NULL;
+
+ if (qual != NULL)
+ {
+ newqual = find_nots(pull_args(qual));
+ newqual = normalize(pull_args(newqual));
+ newqual = (Expr *) qualcleanup(pull_args(newqual));
+ newqual = pull_args(newqual);;
+
+ if (removeAndFlag)
+ {
+ if (and_clause((Node *) newqual))
+ newqual = (Expr *) remove_ands(newqual);
+ else
+ newqual = (Expr *) remove_ands(make_andclause(lcons(newqual, NIL)));
+ }
+ }
+ else if (qual != NULL)
+ newqual = (Expr *) lcons(qual, NIL);
+
+ return (List *) (newqual);
}
-/*
+/*
* pull-args--
- * Given a qualification, eliminate nested 'and' and 'or' clauses.
- *
+ * Given a qualification, eliminate nested 'and' and 'or' clauses.
+ *
* Returns the modified qualification.
- *
+ *
*/
-static Expr *
-pull_args(Expr *qual)
+static Expr *
+pull_args(Expr * qual)
{
- if (qual==NULL)
- return (NULL);
-
- if (is_opclause((Node*)qual)) {
- return(make_clause(qual->opType, qual->oper,
- lcons(pull_args((Expr*)get_leftop(qual)),
- lcons(pull_args((Expr*)get_rightop(qual)),
- NIL))));
- } else if (and_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach (temp, qual->args)
- t_list = lappend (t_list, pull_args(lfirst(temp)));
- return (make_andclause (pull_ands (t_list)));
- }else if (or_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach (temp, qual->args)
- t_list = lappend (t_list, pull_args(lfirst(temp)));
- return (make_orclause (pull_ors (t_list)));
- } else if (not_clause((Node*)qual)) {
- return (make_notclause (pull_args (get_notclausearg (qual))));
- } else {
- return (qual);
- }
+ if (qual == NULL)
+ return (NULL);
+
+ if (is_opclause((Node *) qual))
+ {
+ return (make_clause(qual->opType, qual->oper,
+ lcons(pull_args((Expr *) get_leftop(qual)),
+ lcons(pull_args((Expr *) get_rightop(qual)),
+ NIL))));
+ }
+ else if (and_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, pull_args(lfirst(temp)));
+ return (make_andclause(pull_ands(t_list)));
+ }
+ else if (or_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, pull_args(lfirst(temp)));
+ return (make_orclause(pull_ors(t_list)));
+ }
+ else if (not_clause((Node *) qual))
+ {
+ return (make_notclause(pull_args(get_notclausearg(qual))));
+ }
+ else
+ {
+ return (qual);
+ }
}
-/*
+/*
* pull-ors--
- * Pull the arguments of an 'or' clause nested within another 'or'
- * clause up into the argument list of the parent.
- *
+ * Pull the arguments of an 'or' clause nested within another 'or'
+ * clause up into the argument list of the parent.
+ *
* Returns the modified list.
*/
-static List *
-pull_ors(List *orlist)
+static List *
+pull_ors(List * orlist)
{
- if (orlist==NIL)
- return (NIL);
+ if (orlist == NIL)
+ return (NIL);
- if (or_clause(lfirst(orlist))) {
- List *args = ((Expr*)lfirst(orlist))->args;
- return (pull_ors(nconc(copyObject((Node*)args),
- copyObject((Node*)lnext(orlist)))));
- } else {
- return (lcons(lfirst(orlist), pull_ors(lnext(orlist))));
- }
+ if (or_clause(lfirst(orlist)))
+ {
+ List *args = ((Expr *) lfirst(orlist))->args;
+
+ return (pull_ors(nconc(copyObject((Node *) args),
+ copyObject((Node *) lnext(orlist)))));
+ }
+ else
+ {
+ return (lcons(lfirst(orlist), pull_ors(lnext(orlist))));
+ }
}
-/*
+/*
* pull-ands--
- * Pull the arguments of an 'and' clause nested within another 'and'
- * clause up into the argument list of the parent.
- *
+ * Pull the arguments of an 'and' clause nested within another 'and'
+ * clause up into the argument list of the parent.
+ *
* Returns the modified list.
*/
-static List *
-pull_ands(List *andlist)
+static List *
+pull_ands(List * andlist)
{
- if (andlist==NIL)
- return (NIL);
+ if (andlist == NIL)
+ return (NIL);
+
+ if (and_clause(lfirst(andlist)))
+ {
+ List *args = ((Expr *) lfirst(andlist))->args;
- if (and_clause (lfirst(andlist))) {
- List *args = ((Expr*)lfirst(andlist))->args;
- return (pull_ands(nconc(copyObject((Node*)args),
- copyObject((Node*)lnext(andlist)))));
- } else {
- return (lcons(lfirst(andlist), pull_ands(lnext(andlist))));
- }
+ return (pull_ands(nconc(copyObject((Node *) args),
+ copyObject((Node *) lnext(andlist)))));
+ }
+ else
+ {
+ return (lcons(lfirst(andlist), pull_ands(lnext(andlist))));
+ }
}
-/*
+/*
* find-nots--
- * Traverse the qualification, looking for 'not's to take care of.
- * For 'not' clauses, remove the 'not' and push it down to the clauses'
- * descendants.
- * For all other clause types, simply recurse.
- *
+ * Traverse the qualification, looking for 'not's to take care of.
+ * For 'not' clauses, remove the 'not' and push it down to the clauses'
+ * descendants.
+ * For all other clause types, simply recurse.
+ *
* Returns the modified qualification.
- *
+ *
*/
-static Expr *
-find_nots(Expr *qual)
+static Expr *
+find_nots(Expr * qual)
{
- if (qual==NULL)
- return (NULL);
-
- if (is_opclause((Node*)qual)) {
- return (make_clause(qual->opType, qual->oper,
- lcons(find_nots((Expr*)get_leftop(qual)),
- lcons(find_nots((Expr*)get_rightop(qual)),
- NIL))));
- } else if (and_clause ((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach (temp, qual->args) {
- t_list = lappend(t_list,find_nots(lfirst(temp)));
- }
-
- return (make_andclause(t_list));
- } else if (or_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach (temp, qual->args) {
- t_list = lappend(t_list,find_nots(lfirst(temp)));
- }
- return (make_orclause (t_list));
- } else if (not_clause((Node*)qual))
- return (push_nots(get_notclausearg (qual)));
- else
- return (qual);
+ if (qual == NULL)
+ return (NULL);
+
+ if (is_opclause((Node *) qual))
+ {
+ return (make_clause(qual->opType, qual->oper,
+ lcons(find_nots((Expr *) get_leftop(qual)),
+ lcons(find_nots((Expr *) get_rightop(qual)),
+ NIL))));
+ }
+ else if (and_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ {
+ t_list = lappend(t_list, find_nots(lfirst(temp)));
+ }
+
+ return (make_andclause(t_list));
+ }
+ else if (or_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ {
+ t_list = lappend(t_list, find_nots(lfirst(temp)));
+ }
+ return (make_orclause(t_list));
+ }
+ else if (not_clause((Node *) qual))
+ return (push_nots(get_notclausearg(qual)));
+ else
+ return (qual);
}
-/*
+/*
* push-nots--
- * Negate the descendants of a 'not' clause.
- *
+ * Negate the descendants of a 'not' clause.
+ *
* Returns the modified qualification.
- *
+ *
*/
-static Expr *
-push_nots(Expr *qual)
+static Expr *
+push_nots(Expr * qual)
{
- if (qual==NULL)
- return (NULL);
-
- /*
- * Negate an operator clause if possible:
- * ("NOT" (< A B)) => (> A B)
- * Otherwise, retain the clause as it is (the 'not' can't be pushed
- * down any farther).
- */
- if (is_opclause((Node*)qual)) {
- Oper *oper = (Oper*)((Expr*)qual)->oper;
- Oid negator = get_negator(oper->opno);
-
- if(negator) {
- Oper *op = (Oper*) makeOper(negator,
- InvalidOid,
- oper->opresulttype,
- 0, NULL);
- op->op_fcache = (FunctionCache *) NULL;
- return
- (make_opclause(op, get_leftop(qual), get_rightop(qual)));
- } else {
- return (make_notclause(qual));
- }
- } else if (and_clause((Node*)qual)) {
- /* Apply DeMorgan's Laws:
- * ("NOT" ("AND" A B)) => ("OR" ("NOT" A) ("NOT" B))
- * ("NOT" ("OR" A B)) => ("AND" ("NOT" A) ("NOT" B))
- * i.e., continue negating down through the clause's descendants.
- */
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach(temp, qual->args) {
- t_list = lappend(t_list,push_nots(lfirst(temp)));
- }
- return (make_orclause (t_list));
- } else if (or_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach(temp, qual->args) {
- t_list = lappend(t_list,push_nots(lfirst(temp)));
- }
- return (make_andclause (t_list));
- } else if (not_clause((Node*)qual))
- /* Another 'not' cancels this 'not', so eliminate the 'not' and
- * stop negating this branch.
- */
- return (find_nots (get_notclausearg (qual)));
- else
- /* We don't know how to negate anything else, place a 'not' at this
- * level.
+ if (qual == NULL)
+ return (NULL);
+
+ /*
+ * Negate an operator clause if possible: ("NOT" (< A B)) => (> A B)
+ * Otherwise, retain the clause as it is (the 'not' can't be pushed
+ * down any farther).
*/
- return (make_notclause (qual));
+ if (is_opclause((Node *) qual))
+ {
+ Oper *oper = (Oper *) ((Expr *) qual)->oper;
+ Oid negator = get_negator(oper->opno);
+
+ if (negator)
+ {
+ Oper *op = (Oper *) makeOper(negator,
+ InvalidOid,
+ oper->opresulttype,
+ 0, NULL);
+
+ op->op_fcache = (FunctionCache *) NULL;
+ return
+ (make_opclause(op, get_leftop(qual), get_rightop(qual)));
+ }
+ else
+ {
+ return (make_notclause(qual));
+ }
+ }
+ else if (and_clause((Node *) qual))
+ {
+
+ /*
+ * Apply DeMorgan's Laws: ("NOT" ("AND" A B)) => ("OR" ("NOT" A)
+ * ("NOT" B)) ("NOT" ("OR" A B)) => ("AND" ("NOT" A) ("NOT" B))
+ * i.e., continue negating down through the clause's descendants.
+ */
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ {
+ t_list = lappend(t_list, push_nots(lfirst(temp)));
+ }
+ return (make_orclause(t_list));
+ }
+ else if (or_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ {
+ t_list = lappend(t_list, push_nots(lfirst(temp)));
+ }
+ return (make_andclause(t_list));
+ }
+ else if (not_clause((Node *) qual))
+
+ /*
+ * Another 'not' cancels this 'not', so eliminate the 'not' and
+ * stop negating this branch.
+ */
+ return (find_nots(get_notclausearg(qual)));
+ else
+
+ /*
+ * We don't know how to negate anything else, place a 'not' at
+ * this level.
+ */
+ return (make_notclause(qual));
}
-/*
+/*
* normalize--
- * Given a qualification tree with the 'not's pushed down, convert it
- * to a tree in CNF by repeatedly applying the rule:
- * ("OR" A ("AND" B C)) => ("AND" ("OR" A B) ("OR" A C))
- * bottom-up.
- * Note that 'or' clauses will always be turned into 'and' clauses.
- *
+ * Given a qualification tree with the 'not's pushed down, convert it
+ * to a tree in CNF by repeatedly applying the rule:
+ * ("OR" A ("AND" B C)) => ("AND" ("OR" A B) ("OR" A C))
+ * bottom-up.
+ * Note that 'or' clauses will always be turned into 'and' clauses.
+ *
* Returns the modified qualification.
- *
+ *
*/
-static Expr *
-normalize(Expr *qual)
+static Expr *
+normalize(Expr * qual)
{
- if (qual==NULL)
- return (NULL);
-
- if (is_opclause((Node*)qual)) {
- Expr *expr = (Expr*)qual;
- return (make_clause(expr->opType, expr->oper,
- lcons(normalize((Expr*)get_leftop(qual)),
- lcons(normalize((Expr*)get_rightop(qual)),
- NIL))));
- } else if (and_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
-
- foreach (temp, qual->args) {
- t_list = lappend(t_list,normalize(lfirst(temp)));
- }
- return (make_andclause (t_list));
- } else if (or_clause((Node*)qual)) {
- /* XXX - let form, maybe incorrect */
- List *orlist = NIL;
- List *temp = NIL;
- bool has_andclause = FALSE;
-
- foreach(temp, qual->args) {
- orlist = lappend(orlist,normalize(lfirst(temp)));
- }
- foreach (temp, orlist) {
- if (and_clause (lfirst(temp))) {
- has_andclause = TRUE;
- break;
- }
- }
- if (has_andclause == TRUE)
- return (make_andclause(or_normalize(orlist)));
- else
- return (make_orclause(orlist));
-
- } else if (not_clause((Node*)qual))
- return (make_notclause (normalize (get_notclausearg (qual))));
- else
- return (qual);
+ if (qual == NULL)
+ return (NULL);
+
+ if (is_opclause((Node *) qual))
+ {
+ Expr *expr = (Expr *) qual;
+
+ return (make_clause(expr->opType, expr->oper,
+ lcons(normalize((Expr *) get_leftop(qual)),
+ lcons(normalize((Expr *) get_rightop(qual)),
+ NIL))));
+ }
+ else if (and_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ foreach(temp, qual->args)
+ {
+ t_list = lappend(t_list, normalize(lfirst(temp)));
+ }
+ return (make_andclause(t_list));
+ }
+ else if (or_clause((Node *) qual))
+ {
+ /* XXX - let form, maybe incorrect */
+ List *orlist = NIL;
+ List *temp = NIL;
+ bool has_andclause = FALSE;
+
+ foreach(temp, qual->args)
+ {
+ orlist = lappend(orlist, normalize(lfirst(temp)));
+ }
+ foreach(temp, orlist)
+ {
+ if (and_clause(lfirst(temp)))
+ {
+ has_andclause = TRUE;
+ break;
+ }
+ }
+ if (has_andclause == TRUE)
+ return (make_andclause(or_normalize(orlist)));
+ else
+ return (make_orclause(orlist));
+
+ }
+ else if (not_clause((Node *) qual))
+ return (make_notclause(normalize(get_notclausearg(qual))));
+ else
+ return (qual);
}
-/*
+/*
* or-normalize--
- * Given a list of exprs which are 'or'ed together, distribute any
- * 'and' clauses.
- *
+ * Given a list of exprs which are 'or'ed together, distribute any
+ * 'and' clauses.
+ *
* Returns the modified list.
- *
+ *
*/
-static List *
-or_normalize(List *orlist)
+static List *
+or_normalize(List * orlist)
{
- List *distributable = NIL;
- List *new_orlist = NIL;
- List *temp = NIL;
-
- if (orlist==NIL)
- return NIL;
-
- foreach(temp, orlist) {
- if (and_clause(lfirst(temp)))
- distributable = lfirst(temp);
- }
- if (distributable)
- new_orlist = LispRemove(distributable,orlist);
-
- if(new_orlist) {
- return
- (or_normalize(lcons(distribute_args(lfirst(new_orlist),
- ((Expr*)distributable)->args),
- lnext(new_orlist))));
- }else {
- return (orlist);
- }
+ List *distributable = NIL;
+ List *new_orlist = NIL;
+ List *temp = NIL;
+
+ if (orlist == NIL)
+ return NIL;
+
+ foreach(temp, orlist)
+ {
+ if (and_clause(lfirst(temp)))
+ distributable = lfirst(temp);
+ }
+ if (distributable)
+ new_orlist = LispRemove(distributable, orlist);
+
+ if (new_orlist)
+ {
+ return
+ (or_normalize(lcons(distribute_args(lfirst(new_orlist),
+ ((Expr *) distributable)->args),
+ lnext(new_orlist))));
+ }
+ else
+ {
+ return (orlist);
+ }
}
-/*
+/*
* distribute-args--
- * Create new 'or' clauses by or'ing 'item' with each element of 'args'.
- * E.g.: (distribute-args A ("AND" B C)) => ("AND" ("OR" A B) ("OR" A C))
- *
+ * Create new 'or' clauses by or'ing 'item' with each element of 'args'.
+ * E.g.: (distribute-args A ("AND" B C)) => ("AND" ("OR" A B) ("OR" A C))
+ *
* Returns an 'and' clause.
- *
+ *
*/
-static List *
-distribute_args(List *item, List *args)
+static List *
+distribute_args(List * item, List * args)
{
- List *or_list = NIL;
- List *n_list = NIL;
- List *temp = NIL;
- List *t_list = NIL;
-
- if (args==NULL)
- return (item);
-
- foreach (temp,args) {
- n_list = or_normalize(pull_ors(lcons(item,
- lcons(lfirst(temp),NIL))));
- or_list = (List*)make_orclause(n_list);
- t_list = lappend(t_list,or_list);
- }
- return ((List*)make_andclause(t_list));
+ List *or_list = NIL;
+ List *n_list = NIL;
+ List *temp = NIL;
+ List *t_list = NIL;
+
+ if (args == NULL)
+ return (item);
+
+ foreach(temp, args)
+ {
+ n_list = or_normalize(pull_ors(lcons(item,
+ lcons(lfirst(temp), NIL))));
+ or_list = (List *) make_orclause(n_list);
+ t_list = lappend(t_list, or_list);
+ }
+ return ((List *) make_andclause(t_list));
}
-/*
+/*
* qualcleanup--
- * Fix up a qualification by removing duplicate entries (left over from
- * normalization), and by removing 'and' and 'or' clauses which have only
- * one valid expr (e.g., ("AND" A) => A).
- *
+ * Fix up a qualification by removing duplicate entries (left over from
+ * normalization), and by removing 'and' and 'or' clauses which have only
+ * one valid expr (e.g., ("AND" A) => A).
+ *
* Returns the modified qualfication.
- *
+ *
*/
-static List *
-qualcleanup(Expr *qual)
+static List *
+qualcleanup(Expr * qual)
{
- if (qual==NULL)
- return (NIL);
-
- if (is_opclause((Node*)qual)) {
- return ((List*)make_clause(qual->opType, qual->oper,
- lcons(qualcleanup((Expr*)get_leftop(qual)),
- lcons(qualcleanup((Expr*)get_rightop(qual)),
- NIL))));
- } else if (and_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
- List *new_and_args = NIL;
-
- foreach(temp, qual->args)
- t_list = lappend(t_list,qualcleanup(lfirst(temp)));
-
- new_and_args = remove_duplicates(t_list);
-
- if(length (new_and_args) > 1)
- return ((List*)make_andclause(new_and_args));
- else
- return (lfirst(new_and_args));
- }
- else if (or_clause((Node*)qual)) {
- List *temp = NIL;
- List *t_list = NIL;
- List *new_or_args = NIL;
-
- foreach (temp, qual->args)
- t_list = lappend(t_list,qualcleanup(lfirst(temp)));
-
- new_or_args = remove_duplicates(t_list);
-
-
- if(length (new_or_args) > 1)
- return ((List*)make_orclause (new_or_args));
- else
- return (lfirst (new_or_args));
- } else if (not_clause((Node*)qual))
- return ((List*)make_notclause((Expr*)qualcleanup((Expr*)get_notclausearg(qual))));
-
- else
- return ((List*)qual);
+ if (qual == NULL)
+ return (NIL);
+
+ if (is_opclause((Node *) qual))
+ {
+ return ((List *) make_clause(qual->opType, qual->oper,
+ lcons(qualcleanup((Expr *) get_leftop(qual)),
+ lcons(qualcleanup((Expr *) get_rightop(qual)),
+ NIL))));
+ }
+ else if (and_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+ List *new_and_args = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, qualcleanup(lfirst(temp)));
+
+ new_and_args = remove_duplicates(t_list);
+
+ if (length(new_and_args) > 1)
+ return ((List *) make_andclause(new_and_args));
+ else
+ return (lfirst(new_and_args));
+ }
+ else if (or_clause((Node *) qual))
+ {
+ List *temp = NIL;
+ List *t_list = NIL;
+ List *new_or_args = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, qualcleanup(lfirst(temp)));
+
+ new_or_args = remove_duplicates(t_list);
+
+
+ if (length(new_or_args) > 1)
+ return ((List *) make_orclause(new_or_args));
+ else
+ return (lfirst(new_or_args));
+ }
+ else if (not_clause((Node *) qual))
+ return ((List *) make_notclause((Expr *) qualcleanup((Expr *) get_notclausearg(qual))));
+
+ else
+ return ((List *) qual);
}
-/*
+/*
* remove-ands--
- * Remove the explicit "AND"s from the qualification:
- * ("AND" A B) => (A B)
- *
+ * Remove the explicit "AND"s from the qualification:
+ * ("AND" A B) => (A B)
+ *
* RETURNS : qual
* MODIFIES: qual
*/
-static List *
-remove_ands(Expr *qual)
+static List *
+remove_ands(Expr * qual)
{
- List *t_list = NIL;
-
- if (qual==NULL)
- return (NIL);
- if (is_opclause((Node*)qual)) {
- return ((List*)make_clause(qual->opType, qual->oper,
- lcons(remove_ands((Expr*)get_leftop(qual)),
- lcons(remove_ands((Expr*)get_rightop(qual)),
- NIL))));
- } else if (and_clause((Node*)qual)) {
- List *temp = NIL;
- foreach (temp, qual->args)
- t_list = lappend(t_list,remove_ands(lfirst(temp)));
- return(t_list);
- } else if (or_clause((Node*)qual)) {
- List *temp = NIL;
- foreach (temp, qual->args)
- t_list = lappend(t_list,remove_ands(lfirst(temp)));
- return ((List*)make_orclause((List*)t_list));
- } else if (not_clause((Node*)qual)) {
- return ((List*)make_notclause((Expr*)remove_ands((Expr*)get_notclausearg (qual))));
- } else {
- return ((List*)qual);
- }
+ List *t_list = NIL;
+
+ if (qual == NULL)
+ return (NIL);
+ if (is_opclause((Node *) qual))
+ {
+ return ((List *) make_clause(qual->opType, qual->oper,
+ lcons(remove_ands((Expr *) get_leftop(qual)),
+ lcons(remove_ands((Expr *) get_rightop(qual)),
+ NIL))));
+ }
+ else if (and_clause((Node *) qual))
+ {
+ List *temp = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, remove_ands(lfirst(temp)));
+ return (t_list);
+ }
+ else if (or_clause((Node *) qual))
+ {
+ List *temp = NIL;
+
+ foreach(temp, qual->args)
+ t_list = lappend(t_list, remove_ands(lfirst(temp)));
+ return ((List *) make_orclause((List *) t_list));
+ }
+ else if (not_clause((Node *) qual))
+ {
+ return ((List *) make_notclause((Expr *) remove_ands((Expr *) get_notclausearg(qual))));
+ }
+ else
+ {
+ return ((List *) qual);
+ }
}
/*****************************************************************************
*
- * EXISTENTIAL QUALIFICATIONS
+ * EXISTENTIAL QUALIFICATIONS
*
*****************************************************************************/
-/*
+/*
* update-relations--
- * Returns the range table indices (i.e., varnos) for all relations which
- * are referenced in the target list.
- *
+ * Returns the range table indices (i.e., varnos) for all relations which
+ * are referenced in the target list.
+ *
*/
-#ifdef NOT_USED
-static List *
-update_relations(List *tlist)
+#ifdef NOT_USED
+static List *
+update_relations(List * tlist)
{
- return(NIL);
+ return (NIL);
}
+
#endif
/*****************************************************************************
@@ -557,28 +634,31 @@ update_relations(List *tlist)
*
*****************************************************************************/
-static List *
-remove_duplicates(List *list)
+static List *
+remove_duplicates(List * list)
{
- List *i;
- List *j;
- List *result = NIL;
- bool there_exists_duplicate = false;
-
- if (length(list) == 1)
- return(list);
-
- foreach (i, list) {
- if (i != NIL) {
- foreach (j, lnext(i)) {
- if (equal(lfirst(i), lfirst(j)))
- there_exists_duplicate = true;
- }
- if (!there_exists_duplicate)
- result = lappend(result, lfirst(i));
-
- there_exists_duplicate = false;
- }
- }
- return(result);
+ List *i;
+ List *j;
+ List *result = NIL;
+ bool there_exists_duplicate = false;
+
+ if (length(list) == 1)
+ return (list);
+
+ foreach(i, list)
+ {
+ if (i != NIL)
+ {
+ foreach(j, lnext(i))
+ {
+ if (equal(lfirst(i), lfirst(j)))
+ there_exists_duplicate = true;
+ }
+ if (!there_exists_duplicate)
+ result = lappend(result, lfirst(i));
+
+ there_exists_duplicate = false;
+ }
+ }
+ return (result);
}
diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index d57755ac064..8b94fb4cbba 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* preptlist.c--
- * Routines to preprocess the parse tree target list
+ * Routines to preprocess the parse tree target list
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.2 1997/01/22 01:42:38 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.3 1997/09/07 04:44:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,7 +25,7 @@
#include "utils/lsyscache.h"
#include "utils/palloc.h"
-#include "parser/parsetree.h" /* for getrelid() */
+#include "parser/parsetree.h" /* for getrelid() */
#include "parser/catalog_utils.h"
#include "optimizer/internal.h"
@@ -33,291 +33,315 @@
#include "optimizer/clauses.h"
#include "optimizer/tlist.h"
-static List *expand_targetlist(List *tlist, Oid relid, int command_type,
- Index result_relation);
-static List *replace_matching_resname(List *new_tlist,
- List *old_tlist);
-static List *new_relation_targetlist(Oid relid, Index rt_index,
- NodeTag node_type);
-
+static List *
+expand_targetlist(List * tlist, Oid relid, int command_type,
+ Index result_relation);
+static List *
+replace_matching_resname(List * new_tlist,
+ List * old_tlist);
+static List *
+new_relation_targetlist(Oid relid, Index rt_index,
+ NodeTag node_type);
-/*
+
+/*
* preprocess-targetlist--
- * Driver for preprocessing the parse tree targetlist.
- *
- * 1. Deal with appends and replaces by filling missing attributes
- * in the target list.
- * 2. Reset operator OIDs to the appropriate regproc ids.
- *
- * Returns the new targetlist.
+ * Driver for preprocessing the parse tree targetlist.
+ *
+ * 1. Deal with appends and replaces by filling missing attributes
+ * in the target list.
+ * 2. Reset operator OIDs to the appropriate regproc ids.
+ *
+ * Returns the new targetlist.
*/
-List *
-preprocess_targetlist(List *tlist,
- int command_type,
- Index result_relation,
- List *range_table)
+List *
+preprocess_targetlist(List * tlist,
+ int command_type,
+ Index result_relation,
+ List * range_table)
{
- List *expanded_tlist = NIL;
- Oid relid = InvalidOid;
- List *t_list = NIL;
- List *temp = NIL;
-
- if (result_relation>=1 && command_type != CMD_SELECT) {
- relid = getrelid(result_relation, range_table);
- }
-
- /*
- * for heap_formtuple to work, the targetlist must match the exact
- * order of the attributes. We also need to fill in the missing
- * attributes here. -ay 10/94
- */
- expanded_tlist =
- expand_targetlist(tlist, relid, command_type, result_relation);
-
- /* XXX should the fix-opids be this early?? */
- /* was mapCAR */
- foreach (temp,expanded_tlist) {
- TargetEntry *tle = lfirst(temp);
- if (tle->expr)
- fix_opid(tle->expr);
- }
- t_list = copyObject(expanded_tlist);
-
- /* ------------------
- * for "replace" or "delete" queries, add ctid of the result
- * relation into the target list so that the ctid can get
- * propogate through the execution and in the end ExecReplace()
- * will find the right tuple to replace or delete. This
- * extra field will be removed in ExecReplace().
- * For convinient, we append this extra field to the end of
- * the target list.
- * ------------------
- */
- if (command_type == CMD_UPDATE || command_type == CMD_DELETE) {
- TargetEntry *ctid;
- Resdom *resdom;
- Var *var;
-
- resdom = makeResdom(length(t_list) + 1,
- 27,
- 6,
- "ctid",
- 0,
- 0,
- 1);
-
- var = makeVar(result_relation, -1, 27, result_relation, -1);
-
- ctid = makeNode(TargetEntry);
- ctid->resdom = resdom;
- ctid->expr = (Node *)var;
- t_list = lappend(t_list, ctid);
- }
-
- return(t_list);
+ List *expanded_tlist = NIL;
+ Oid relid = InvalidOid;
+ List *t_list = NIL;
+ List *temp = NIL;
+
+ if (result_relation >= 1 && command_type != CMD_SELECT)
+ {
+ relid = getrelid(result_relation, range_table);
+ }
+
+ /*
+ * for heap_formtuple to work, the targetlist must match the exact
+ * order of the attributes. We also need to fill in the missing
+ * attributes here. -ay 10/94
+ */
+ expanded_tlist =
+ expand_targetlist(tlist, relid, command_type, result_relation);
+
+ /* XXX should the fix-opids be this early?? */
+ /* was mapCAR */
+ foreach(temp, expanded_tlist)
+ {
+ TargetEntry *tle = lfirst(temp);
+
+ if (tle->expr)
+ fix_opid(tle->expr);
+ }
+ t_list = copyObject(expanded_tlist);
+
+ /* ------------------
+ * for "replace" or "delete" queries, add ctid of the result
+ * relation into the target list so that the ctid can get
+ * propogate through the execution and in the end ExecReplace()
+ * will find the right tuple to replace or delete. This
+ * extra field will be removed in ExecReplace().
+ * For convinient, we append this extra field to the end of
+ * the target list.
+ * ------------------
+ */
+ if (command_type == CMD_UPDATE || command_type == CMD_DELETE)
+ {
+ TargetEntry *ctid;
+ Resdom *resdom;
+ Var *var;
+
+ resdom = makeResdom(length(t_list) + 1,
+ 27,
+ 6,
+ "ctid",
+ 0,
+ 0,
+ 1);
+
+ var = makeVar(result_relation, -1, 27, result_relation, -1);
+
+ ctid = makeNode(TargetEntry);
+ ctid->resdom = resdom;
+ ctid->expr = (Node *) var;
+ t_list = lappend(t_list, ctid);
+ }
+
+ return (t_list);
}
/*****************************************************************************
*
- * TARGETLIST EXPANSION
+ * TARGETLIST EXPANSION
*
*****************************************************************************/
-/*
+/*
* expand-targetlist--
- * Given a target list as generated by the parser and a result relation,
- * add targetlist entries for the attributes which have not been used.
- *
- * XXX This code is only supposed to work with unnested relations.
- *
- * 'tlist' is the original target list
- * 'relid' is the relid of the result relation
- * 'command' is the update command
- *
+ * Given a target list as generated by the parser and a result relation,
+ * add targetlist entries for the attributes which have not been used.
+ *
+ * XXX This code is only supposed to work with unnested relations.
+ *
+ * 'tlist' is the original target list
+ * 'relid' is the relid of the result relation
+ * 'command' is the update command
+ *
* Returns the expanded target list, sorted in resno order.
*/
-static List *
-expand_targetlist(List *tlist,
- Oid relid,
- int command_type,
- Index result_relation)
+static List *
+expand_targetlist(List * tlist,
+ Oid relid,
+ int command_type,
+ Index result_relation)
{
- NodeTag node_type = T_Invalid;
-
- switch (command_type) {
- case CMD_INSERT:
- node_type = (NodeTag)T_Const;
- break;
- case CMD_UPDATE:
- node_type = (NodeTag)T_Var;
- break;
- }
-
- if(node_type != T_Invalid) {
- List *ntlist = new_relation_targetlist(relid,
- result_relation,
- node_type);
-
- return (replace_matching_resname(ntlist, tlist));
- } else {
- return (tlist);
- }
-
+ NodeTag node_type = T_Invalid;
+
+ switch (command_type)
+ {
+ case CMD_INSERT:
+ node_type = (NodeTag) T_Const;
+ break;
+ case CMD_UPDATE:
+ node_type = (NodeTag) T_Var;
+ break;
+ }
+
+ if (node_type != T_Invalid)
+ {
+ List *ntlist = new_relation_targetlist(relid,
+ result_relation,
+ node_type);
+
+ return (replace_matching_resname(ntlist, tlist));
+ }
+ else
+ {
+ return (tlist);
+ }
+
}
-static List *
-replace_matching_resname(List *new_tlist, List *old_tlist)
+static List *
+replace_matching_resname(List * new_tlist, List * old_tlist)
{
- List *temp, *i;
- List *t_list = NIL;
-
- foreach (i,new_tlist) {
- TargetEntry *new_tle = (TargetEntry *)lfirst(i);
- TargetEntry *matching_old_tl = NULL;
-
- foreach (temp, old_tlist) {
- TargetEntry *old_tle = (TargetEntry *)lfirst(temp);
-
- old_tle = lfirst(temp);
- if (!strcmp(old_tle->resdom->resname,
- new_tle->resdom->resname)) {
- matching_old_tl = old_tle;
- break;
- }
+ List *temp,
+ *i;
+ List *t_list = NIL;
+
+ foreach(i, new_tlist)
+ {
+ TargetEntry *new_tle = (TargetEntry *) lfirst(i);
+ TargetEntry *matching_old_tl = NULL;
+
+ foreach(temp, old_tlist)
+ {
+ TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
+
+ old_tle = lfirst(temp);
+ if (!strcmp(old_tle->resdom->resname,
+ new_tle->resdom->resname))
+ {
+ matching_old_tl = old_tle;
+ break;
+ }
+ }
+
+ if (matching_old_tl)
+ {
+ matching_old_tl->resdom->resno =
+ new_tle->resdom->resno;
+ t_list = lappend(t_list, matching_old_tl);
+ }
+ else
+ {
+ t_list = lappend(t_list, new_tle);
+ }
}
-
- if(matching_old_tl) {
- matching_old_tl->resdom->resno =
- new_tle->resdom->resno;
- t_list = lappend(t_list, matching_old_tl);
- }
- else {
- t_list = lappend(t_list, new_tle);
- }
- }
-
- /*
- * It is possible that 'old_tlist' has some negative
- * attributes (i.e. negative resnos). This only happens
- * if this is a replace/append command and we explicitly
- * specify a system attribute. Of course this is not a very good
- * idea if this is a user query, but on the other hand the rule
- * manager uses this mechanism to replace rule locks.
- *
- * So, copy all these entries to the end of the target list
- * and set their 'resjunk' value to 1 to show that these are
- * special attributes and have to be treated specially by the
- * executor!
- */
- foreach (temp, old_tlist) {
- TargetEntry *old_tle, *new_tl;
- Resdom *newresno;
-
- old_tle = lfirst(temp);
- if (old_tle->resdom->resno < 0) {
- newresno = (Resdom*) copyObject((Node*)old_tle->resdom);
- newresno->resno = length(t_list) +1;
- newresno->resjunk = 1;
- new_tl = MakeTLE(newresno, old_tle->expr);
- t_list = lappend(t_list, new_tl);
+
+ /*
+ * It is possible that 'old_tlist' has some negative attributes (i.e.
+ * negative resnos). This only happens if this is a replace/append
+ * command and we explicitly specify a system attribute. Of course
+ * this is not a very good idea if this is a user query, but on the
+ * other hand the rule manager uses this mechanism to replace rule
+ * locks.
+ *
+ * So, copy all these entries to the end of the target list and set their
+ * 'resjunk' value to 1 to show that these are special attributes and
+ * have to be treated specially by the executor!
+ */
+ foreach(temp, old_tlist)
+ {
+ TargetEntry *old_tle,
+ *new_tl;
+ Resdom *newresno;
+
+ old_tle = lfirst(temp);
+ if (old_tle->resdom->resno < 0)
+ {
+ newresno = (Resdom *) copyObject((Node *) old_tle->resdom);
+ newresno->resno = length(t_list) + 1;
+ newresno->resjunk = 1;
+ new_tl = MakeTLE(newresno, old_tle->expr);
+ t_list = lappend(t_list, new_tl);
+ }
}
- }
- return (t_list);
+ return (t_list);
}
-/*
+/*
* new-relation-targetlist--
- * Generate a targetlist for the relation with relation OID 'relid'
- * and rangetable index 'rt-index'.
- *
- * Returns the new targetlist.
+ * Generate a targetlist for the relation with relation OID 'relid'
+ * and rangetable index 'rt-index'.
+ *
+ * Returns the new targetlist.
*/
-static List *
+static List *
new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type)
{
- AttrNumber attno;
- List *t_list = NIL;
- char *attname;
- Oid atttype = 0;
- int16 typlen = 0;
- bool attisset = false;
-/* Oid type_id; */
-/* type_id = RelationIdGetTypeId(relid); */
-
- for(attno=1; attno <= get_relnatts(relid); attno++) {
- attname = get_attname(/*type_id,*/ relid, attno);
- atttype = get_atttype(/*type_id,*/ relid, attno);
- /*
- * Since this is an append or replace, the size of any set
- * attribute is the size of the OID used to represent it.
- */
- attisset = get_attisset(/* type_id,*/ relid, attname);
- if (attisset) {
- typlen = tlen(type("oid"));
- } else {
- typlen = get_typlen(atttype);
- }
-
- switch (node_type) {
- case T_Const:
- {
- struct varlena *typedefault = get_typdefault(atttype);
- int temp = 0;
- Const *temp2 = (Const*)NULL;
- TargetEntry *temp3 = (TargetEntry *)NULL;
-
- if (typedefault==NULL)
- temp = 0;
- else
- temp = typlen;
-
- temp2 = makeConst (atttype,
- temp,
- (Datum)typedefault,
- (typedefault == (struct varlena *)NULL),
- /* XXX this is bullshit */
- false,
- false, /* not a set */
- false);
-
- temp3 = MakeTLE (makeResdom(attno,
- atttype,
- typlen,
- attname,
- 0,
- (Oid)0,
- 0),
- (Node*)temp2);
- t_list = lappend(t_list,temp3);
- break;
- }
- case T_Var:
- {
- Var *temp_var = (Var*)NULL;
- TargetEntry *temp_list = NULL;
-
- temp_var =
- makeVar(rt_index, attno, atttype, rt_index, attno);
-
- temp_list = MakeTLE(makeResdom(attno,
- atttype,
- typlen,
- attname,
- 0,
- (Oid)0,
- 0),
- (Node*)temp_var);
- t_list = lappend(t_list,temp_list);
- break;
- }
- default: /* do nothing */
- break;
- }
- }
+ AttrNumber attno;
+ List *t_list = NIL;
+ char *attname;
+ Oid atttype = 0;
+ int16 typlen = 0;
+ bool attisset = false;
- return(t_list);
-}
+/* Oid type_id; */
+/* type_id = RelationIdGetTypeId(relid); */
+
+ for (attno = 1; attno <= get_relnatts(relid); attno++)
+ {
+ attname = get_attname( /* type_id, */ relid, attno);
+ atttype = get_atttype( /* type_id, */ relid, attno);
+
+ /*
+ * Since this is an append or replace, the size of any set
+ * attribute is the size of the OID used to represent it.
+ */
+ attisset = get_attisset( /* type_id, */ relid, attname);
+ if (attisset)
+ {
+ typlen = tlen(type("oid"));
+ }
+ else
+ {
+ typlen = get_typlen(atttype);
+ }
+ switch (node_type)
+ {
+ case T_Const:
+ {
+ struct varlena *typedefault = get_typdefault(atttype);
+ int temp = 0;
+ Const *temp2 = (Const *) NULL;
+ TargetEntry *temp3 = (TargetEntry *) NULL;
+ if (typedefault == NULL)
+ temp = 0;
+ else
+ temp = typlen;
+
+ temp2 = makeConst(atttype,
+ temp,
+ (Datum) typedefault,
+ (typedefault == (struct varlena *) NULL),
+ /* XXX this is bullshit */
+ false,
+ false, /* not a set */
+ false);
+
+ temp3 = MakeTLE(makeResdom(attno,
+ atttype,
+ typlen,
+ attname,
+ 0,
+ (Oid) 0,
+ 0),
+ (Node *) temp2);
+ t_list = lappend(t_list, temp3);
+ break;
+ }
+ case T_Var:
+ {
+ Var *temp_var = (Var *) NULL;
+ TargetEntry *temp_list = NULL;
+
+ temp_var =
+ makeVar(rt_index, attno, atttype, rt_index, attno);
+
+ temp_list = MakeTLE(makeResdom(attno,
+ atttype,
+ typlen,
+ attname,
+ 0,
+ (Oid) 0,
+ 0),
+ (Node *) temp_var);
+ t_list = lappend(t_list, temp_list);
+ break;
+ }
+ default: /* do nothing */
+ break;
+ }
+ }
+
+ return (t_list);
+}
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 3142f37c07a..9bf282f8cc3 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* prepunion.c--
- * Routines to plan archive, inheritance, union, and version queries
+ * Routines to plan archive, inheritance, union, and version queries
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.3 1997/01/10 20:18:12 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.4 1997/09/07 04:44:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,370 +34,396 @@
#include "optimizer/planner.h"
#include "optimizer/prep.h"
-static List *plan_union_query(List *relids, Index rt_index,
- RangeTblEntry *rt_entry, Query *parse, UnionFlag flag,
- List **union_rtentriesPtr);
-static RangeTblEntry *new_rangetable_entry(Oid new_relid,
- RangeTblEntry *old_entry);
-static Query *subst_rangetable(Query *root, Index index,
- RangeTblEntry *new_entry);
-static void fix_parsetree_attnums(Index rt_index, Oid old_relid,
- Oid new_relid, Query *parsetree);
-static Append *make_append(List *unionplans, Index rt_index,
- List *union_rt_entries, List *tlist);
+static List *
+plan_union_query(List * relids, Index rt_index,
+ RangeTblEntry * rt_entry, Query * parse, UnionFlag flag,
+ List ** union_rtentriesPtr);
+static RangeTblEntry *
+new_rangetable_entry(Oid new_relid,
+ RangeTblEntry * old_entry);
+static Query *
+subst_rangetable(Query * root, Index index,
+ RangeTblEntry * new_entry);
+static void
+fix_parsetree_attnums(Index rt_index, Oid old_relid,
+ Oid new_relid, Query * parsetree);
+static Append *
+make_append(List * unionplans, Index rt_index,
+ List * union_rt_entries, List * tlist);
-/*
+/*
* find-all-inheritors -
- * Returns a list of relids corresponding to relations that inherit
- * attributes from any relations listed in either of the argument relid
- * lists.
+ * Returns a list of relids corresponding to relations that inherit
+ * attributes from any relations listed in either of the argument relid
+ * lists.
*/
-List *
-find_all_inheritors(List *unexamined_relids,
- List *examined_relids)
+List *
+find_all_inheritors(List * unexamined_relids,
+ List * examined_relids)
{
- List *new_inheritors = NIL;
- List *new_examined_relids = NIL;
- List *new_unexamined_relids = NIL;
-
- /* Find all relations which inherit from members of
- * 'unexamined-relids' and store them in 'new-inheritors'.
- */
- List *rels = NIL;
- List *newrels = NIL;
-
- foreach(rels,unexamined_relids) {
- newrels = (List*)LispUnioni(find_inheritance_children(lfirsti(rels)),
- newrels);
- }
- new_inheritors = newrels;
-
- new_examined_relids = (List*)LispUnioni(examined_relids,unexamined_relids);
- new_unexamined_relids = set_differencei(new_inheritors,
- new_examined_relids);
-
- if (new_unexamined_relids==NULL) {
- return(new_examined_relids);
- } else {
- return (find_all_inheritors (new_unexamined_relids,
- new_examined_relids));
- }
+ List *new_inheritors = NIL;
+ List *new_examined_relids = NIL;
+ List *new_unexamined_relids = NIL;
+
+ /*
+ * Find all relations which inherit from members of
+ * 'unexamined-relids' and store them in 'new-inheritors'.
+ */
+ List *rels = NIL;
+ List *newrels = NIL;
+
+ foreach(rels, unexamined_relids)
+ {
+ newrels = (List *) LispUnioni(find_inheritance_children(lfirsti(rels)),
+ newrels);
+ }
+ new_inheritors = newrels;
+
+ new_examined_relids = (List *) LispUnioni(examined_relids, unexamined_relids);
+ new_unexamined_relids = set_differencei(new_inheritors,
+ new_examined_relids);
+
+ if (new_unexamined_relids == NULL)
+ {
+ return (new_examined_relids);
+ }
+ else
+ {
+ return (find_all_inheritors(new_unexamined_relids,
+ new_examined_relids));
+ }
}
-/*
+/*
* first-matching-rt-entry -
- * Given a rangetable, find the first rangetable entry that represents
- * the appropriate special case.
- *
- * Returns a rangetable index., Returns -1 if no matches
+ * Given a rangetable, find the first rangetable entry that represents
+ * the appropriate special case.
+ *
+ * Returns a rangetable index., Returns -1 if no matches
*/
int
-first_matching_rt_entry (List *rangetable, UnionFlag flag)
+first_matching_rt_entry(List * rangetable, UnionFlag flag)
{
- int count = 0;
- List *temp = NIL;
+ int count = 0;
+ List *temp = NIL;
- foreach(temp, rangetable) {
- RangeTblEntry *rt_entry = lfirst(temp);
-
- switch(flag) {
- case INHERITS_FLAG:
- if (rt_entry->inh)
- return count+1;
- break;
- case ARCHIVE_FLAG:
- if (rt_entry->archive)
- return count+1;
- break;
- default:
- break;
+ foreach(temp, rangetable)
+ {
+ RangeTblEntry *rt_entry = lfirst(temp);
+
+ switch (flag)
+ {
+ case INHERITS_FLAG:
+ if (rt_entry->inh)
+ return count + 1;
+ break;
+ case ARCHIVE_FLAG:
+ if (rt_entry->archive)
+ return count + 1;
+ break;
+ default:
+ break;
+ }
+ count++;
}
- count++;
- }
-
- return(-1);
+
+ return (-1);
}
-/*
+/*
* plan-union-queries--
- *
- * Plans the queries for a given parent relation.
- *
+ *
+ * Plans the queries for a given parent relation.
+ *
* Returns a list containing a list of plans and a list of rangetable
* entries to be inserted into an APPEND node.
* XXX - what exactly does this mean, look for make_append
*/
-Append *
+Append *
plan_union_queries(Index rt_index,
- Query *parse,
- UnionFlag flag)
+ Query * parse,
+ UnionFlag flag)
{
- List *rangetable = parse->rtable;
- RangeTblEntry *rt_entry = rt_fetch(rt_index,rangetable);
- List *union_relids = NIL;
- List *union_plans = NIL;
- List *union_rt_entries = NIL;
-
- switch (flag) {
- case INHERITS_FLAG:
- union_relids =
- find_all_inheritors(lconsi(rt_entry->relid,
- NIL),
- NIL);
- break;
-
-#if 0
- case UNION_FLAG:
+ List *rangetable = parse->rtable;
+ RangeTblEntry *rt_entry = rt_fetch(rt_index, rangetable);
+ List *union_relids = NIL;
+ List *union_plans = NIL;
+ List *union_rt_entries = NIL;
+
+ switch (flag)
{
- Index rt_index = 0;
- union_plans = handleunion(root,rangetable,tlist,qual);
- return (make_append (union_plans,
- rt_index, rangetable,
- ((Plan*)lfirst(union_plans))->targetlist ));
- }
- break;
+ case INHERITS_FLAG:
+ union_relids =
+ find_all_inheritors(lconsi(rt_entry->relid,
+ NIL),
+ NIL);
+ break;
+
+#if 0
+ case UNION_FLAG:
+ {
+ Index rt_index = 0;
+
+ union_plans = handleunion(root, rangetable, tlist, qual);
+ return (make_append(union_plans,
+ rt_index, rangetable,
+ ((Plan *) lfirst(union_plans))->targetlist));
+ }
+ break;
#endif
-
- case VERSION_FLAG:
- union_relids = VersionGetParents(rt_entry->relid);
- break;
-
- case ARCHIVE_FLAG:
- union_relids = find_archive_rels(rt_entry->relid);
- break;
-
- default:
- /* do nothing */
- break;
- }
-
- /*
- * Remove the flag for this relation, since we're about to handle it
- * (do it before recursing!).
- * XXX destructive parse tree change
- */
- switch(flag) {
- case INHERITS_FLAG:
- rt_fetch(rt_index,rangetable)->inh = false;
- break;
- case ARCHIVE_FLAG:
- rt_fetch(rt_index,rangetable)->archive = false;
- break;
- default:
- break;
- }
-
- /* XXX - can't find any reason to sort union-relids
- * as paul did, so we're leaving it out for now
- * (maybe forever) - jeff & lp
- *
- * [maybe so. btw, jeff & lp did the lisp conversion, according to Paul.
- * -- ay 10/94.]
- */
- union_plans = plan_union_query(union_relids, rt_index, rt_entry,
- parse, flag, &union_rt_entries);
-
- return (make_append(union_plans,
- rt_index,
- union_rt_entries,
- ((Plan*)lfirst(union_plans))->targetlist));
+
+ case VERSION_FLAG:
+ union_relids = VersionGetParents(rt_entry->relid);
+ break;
+
+ case ARCHIVE_FLAG:
+ union_relids = find_archive_rels(rt_entry->relid);
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ /*
+ * Remove the flag for this relation, since we're about to handle it
+ * (do it before recursing!). XXX destructive parse tree change
+ */
+ switch (flag)
+ {
+ case INHERITS_FLAG:
+ rt_fetch(rt_index, rangetable)->inh = false;
+ break;
+ case ARCHIVE_FLAG:
+ rt_fetch(rt_index, rangetable)->archive = false;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * XXX - can't find any reason to sort union-relids as paul did, so
+ * we're leaving it out for now (maybe forever) - jeff & lp
+ *
+ * [maybe so. btw, jeff & lp did the lisp conversion, according to Paul.
+ * -- ay 10/94.]
+ */
+ union_plans = plan_union_query(union_relids, rt_index, rt_entry,
+ parse, flag, &union_rt_entries);
+
+ return (make_append(union_plans,
+ rt_index,
+ union_rt_entries,
+ ((Plan *) lfirst(union_plans))->targetlist));
}
-/*
+/*
* plan-union-query--
- * Returns a list of plans for 'relids' and a list of range table entries
- * in union_rtentries.
+ * Returns a list of plans for 'relids' and a list of range table entries
+ * in union_rtentries.
*/
-static List *
-plan_union_query(List *relids,
- Index rt_index,
- RangeTblEntry *rt_entry,
- Query *root,
- UnionFlag flag,
- List **union_rtentriesPtr)
+static List *
+plan_union_query(List * relids,
+ Index rt_index,
+ RangeTblEntry * rt_entry,
+ Query * root,
+ UnionFlag flag,
+ List ** union_rtentriesPtr)
{
- List *i;
- List *union_plans = NIL;
- List *union_rtentries = NIL;
-
- foreach (i, relids) {
- int relid = lfirsti(i);
- RangeTblEntry *new_rt_entry = new_rangetable_entry(relid,
- rt_entry);
- Query *new_root = subst_rangetable(root,
- rt_index,
- new_rt_entry);
-
- /* reset the uniqueflag and sortclause in parse tree root, so that
- * sorting will only be done once after append
- */
-/* new_root->uniqueFlag = false; */
- new_root->uniqueFlag = NULL;
- new_root->sortClause = NULL;
- if (flag == ARCHIVE_FLAG) {
- /*
- * the entire union query uses the same (most recent) schema.
- * to do otherwise would require either ragged tuples or careful
- * archiving and interpretation of pg_attribute...
- */
- } else {
- fix_parsetree_attnums(rt_index,
- rt_entry->relid,
- relid,
- new_root);
- }
+ List *i;
+ List *union_plans = NIL;
+ List *union_rtentries = NIL;
- union_plans = lappend(union_plans, planner(new_root));
- union_rtentries = lappend(union_rtentries, new_rt_entry);
- }
+ foreach(i, relids)
+ {
+ int relid = lfirsti(i);
+ RangeTblEntry *new_rt_entry = new_rangetable_entry(relid,
+ rt_entry);
+ Query *new_root = subst_rangetable(root,
+ rt_index,
+ new_rt_entry);
+
+ /*
+ * reset the uniqueflag and sortclause in parse tree root, so that
+ * sorting will only be done once after append
+ */
+/* new_root->uniqueFlag = false; */
+ new_root->uniqueFlag = NULL;
+ new_root->sortClause = NULL;
+ if (flag == ARCHIVE_FLAG)
+ {
+
+ /*
+ * the entire union query uses the same (most recent) schema.
+ * to do otherwise would require either ragged tuples or
+ * careful archiving and interpretation of pg_attribute...
+ */
+ }
+ else
+ {
+ fix_parsetree_attnums(rt_index,
+ rt_entry->relid,
+ relid,
+ new_root);
+ }
+
+ union_plans = lappend(union_plans, planner(new_root));
+ union_rtentries = lappend(union_rtentries, new_rt_entry);
+ }
- *union_rtentriesPtr = union_rtentries;
- return(union_plans);
+ *union_rtentriesPtr = union_rtentries;
+ return (union_plans);
}
-/*
+/*
* new-rangetable-entry -
- * Replaces the name and relid of 'old-entry' with the values for
- * 'new-relid'.
- *
- * Returns a copy of 'old-entry' with the parameters substituted.
+ * Replaces the name and relid of 'old-entry' with the values for
+ * 'new-relid'.
+ *
+ * Returns a copy of 'old-entry' with the parameters substituted.
*/
static RangeTblEntry *
-new_rangetable_entry(Oid new_relid, RangeTblEntry *old_entry)
+new_rangetable_entry(Oid new_relid, RangeTblEntry * old_entry)
{
- RangeTblEntry *new_entry = copyObject(old_entry);
+ RangeTblEntry *new_entry = copyObject(old_entry);
- /* ??? someone tell me what the following is doing! - ay 11/94 */
- if (!strcmp(new_entry->refname, "*CURRENT*") ||
- !strcmp(new_entry->refname, "*NEW*"))
- new_entry->refname = get_rel_name(new_relid);
- else
- new_entry->relname = get_rel_name(new_relid);
+ /* ??? someone tell me what the following is doing! - ay 11/94 */
+ if (!strcmp(new_entry->refname, "*CURRENT*") ||
+ !strcmp(new_entry->refname, "*NEW*"))
+ new_entry->refname = get_rel_name(new_relid);
+ else
+ new_entry->relname = get_rel_name(new_relid);
- new_entry->relid = new_relid;
- return(new_entry);
+ new_entry->relid = new_relid;
+ return (new_entry);
}
-/*
+/*
* subst-rangetable--
- * Replaces the 'index'th rangetable entry in 'root' with 'new-entry'.
- *
+ * Replaces the 'index'th rangetable entry in 'root' with 'new-entry'.
+ *
* Returns a new copy of 'root'.
*/
-static Query *
-subst_rangetable(Query *root, Index index, RangeTblEntry *new_entry)
+static Query *
+subst_rangetable(Query * root, Index index, RangeTblEntry * new_entry)
{
- Query *new_root = copyObject(root);
- List *temp = NIL;
- int i = 0;
+ Query *new_root = copyObject(root);
+ List *temp = NIL;
+ int i = 0;
- for(temp = new_root->rtable,i =1; i < index; temp =lnext(temp),i++)
- ;
- lfirst(temp) = new_entry;
+ for (temp = new_root->rtable, i = 1; i < index; temp = lnext(temp), i++)
+ ;
+ lfirst(temp) = new_entry;
- return (new_root);
+ return (new_root);
}
static void
fix_parsetree_attnums_nodes(Index rt_index,
- Oid old_relid,
- Oid new_relid,
- Node *node)
+ Oid old_relid,
+ Oid new_relid,
+ Node * node)
{
- if (node==NULL)
- return;
-
- switch(nodeTag(node)) {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
-
- fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
- tle->expr);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr *)node;
- fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
- (Node*)expr->args);
- }
- break;
- case T_Var:
- {
- Var *var = (Var *)node;
- Oid old_typeid, new_typeid;
-
-/* old_typeid = RelationIdGetTypeId(old_relid);*/
-/* new_typeid = RelationIdGetTypeId(new_relid);*/
- old_typeid = old_relid;
- new_typeid = new_relid;
-
- if (var->varno == rt_index && var->varattno != 0) {
- var->varattno =
- get_attnum(new_typeid,
- get_attname(old_typeid, var->varattno));
- }
- }
- break;
- case T_List:
+ if (node == NULL)
+ return;
+
+ switch (nodeTag(node))
{
- List *l;
- foreach(l, (List*)node) {
- fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
- (Node*)lfirst(l));
- }
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
+ tle->expr);
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
+ (Node *) expr->args);
+ }
+ break;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+ Oid old_typeid,
+ new_typeid;
+
+/* old_typeid = RelationIdGetTypeId(old_relid);*/
+/* new_typeid = RelationIdGetTypeId(new_relid);*/
+ old_typeid = old_relid;
+ new_typeid = new_relid;
+
+ if (var->varno == rt_index && var->varattno != 0)
+ {
+ var->varattno =
+ get_attnum(new_typeid,
+ get_attname(old_typeid, var->varattno));
+ }
+ }
+ break;
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
+ (Node *) lfirst(l));
+ }
+ }
+ break;
+ default:
+ break;
}
- break;
- default:
- break;
- }
}
-
-/*
+
+/*
* fix-parsetree-attnums--
- * Replaces attribute numbers from the relation represented by
- * 'old-relid' in 'parsetree' with the attribute numbers from
- * 'new-relid'.
- *
+ * Replaces attribute numbers from the relation represented by
+ * 'old-relid' in 'parsetree' with the attribute numbers from
+ * 'new-relid'.
+ *
* Returns the destructively-modified parsetree.
- *
+ *
*/
static void
fix_parsetree_attnums(Index rt_index,
- Oid old_relid,
- Oid new_relid,
- Query *parsetree)
+ Oid old_relid,
+ Oid new_relid,
+ Query * parsetree)
{
- if (old_relid == new_relid)
- return;
+ if (old_relid == new_relid)
+ return;
- fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
- (Node*)parsetree->targetList);
- fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
- parsetree->qual);
+ fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
+ (Node *) parsetree->targetList);
+ fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
+ parsetree->qual);
}
-static Append *
-make_append(List *unionplans,
- Index rt_index,
- List *union_rt_entries,
- List *tlist)
+static Append *
+make_append(List * unionplans,
+ Index rt_index,
+ List * union_rt_entries,
+ List * tlist)
{
- Append *node = makeNode(Append);
-
- node->unionplans = unionplans;
- node->unionrelid = rt_index;
- node->unionrtentries = union_rt_entries;
- node->plan.cost = 0.0;
- node->plan.state = (EState*)NULL;
- node->plan.targetlist = tlist;
- node->plan.qual = NIL;
- node->plan.lefttree = (Plan*)NULL;
- node->plan.righttree = (Plan*)NULL;
-
- return(node);
+ Append *node = makeNode(Append);
+
+ node->unionplans = unionplans;
+ node->unionrelid = rt_index;
+ node->unionrtentries = union_rt_entries;
+ node->plan.cost = 0.0;
+ node->plan.state = (EState *) NULL;
+ node->plan.targetlist = tlist;
+ node->plan.qual = NIL;
+ node->plan.lefttree = (Plan *) NULL;
+ node->plan.righttree = (Plan *) NULL;
+
+ return (node);
}
diff --git a/src/backend/optimizer/util/clauseinfo.c b/src/backend/optimizer/util/clauseinfo.c
index 2d648eb3605..e5fd2b7e5bb 100644
--- a/src/backend/optimizer/util/clauseinfo.c
+++ b/src/backend/optimizer/util/clauseinfo.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* clauseinfo.c--
- * ClauseInfo node manipulation routines.
+ * ClauseInfo node manipulation routines.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/clauseinfo.c,v 1.3 1996/07/31 18:47:06 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/clauseinfo.c,v 1.4 1997/09/07 04:44:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,167 +20,172 @@
#include "optimizer/clauses.h"
#include "optimizer/clauseinfo.h"
-/*
+/*
* valid-or-clause--
- *
+ *
* Returns t iff the clauseinfo node contains a 'normal' 'or' clause.
- *
+ *
*/
bool
-valid_or_clause(CInfo *clauseinfo)
+valid_or_clause(CInfo * clauseinfo)
{
- if (clauseinfo != NULL &&
- !single_node((Node*)clauseinfo->clause) &&
- !clauseinfo->notclause &&
- or_clause((Node*)clauseinfo->clause))
- return(true);
- else
- return(false);
+ if (clauseinfo != NULL &&
+ !single_node((Node *) clauseinfo->clause) &&
+ !clauseinfo->notclause &&
+ or_clause((Node *) clauseinfo->clause))
+ return (true);
+ else
+ return (false);
}
-/*
+/*
* get-actual-clauses--
- *
+ *
* Returns a list containing the clauses from 'clauseinfo-list'.
- *
+ *
*/
-List *
-get_actual_clauses(List *clauseinfo_list)
+List *
+get_actual_clauses(List * clauseinfo_list)
{
- List *temp = NIL;
- List *result = NIL;
- CInfo *clause = (CInfo *)NULL;
-
- foreach(temp,clauseinfo_list) {
- clause = (CInfo *)lfirst(temp);
- result = lappend(result,clause->clause);
- }
- return(result);
+ List *temp = NIL;
+ List *result = NIL;
+ CInfo *clause = (CInfo *) NULL;
+
+ foreach(temp, clauseinfo_list)
+ {
+ clause = (CInfo *) lfirst(temp);
+ result = lappend(result, clause->clause);
+ }
+ return (result);
}
-/*
+/*
* XXX NOTE:
- * The following routines must return their contents in the same order
- * (e.g., the first clause's info should be first, and so on) or else
- * get_index_sel() won't work.
- *
+ * The following routines must return their contents in the same order
+ * (e.g., the first clause's info should be first, and so on) or else
+ * get_index_sel() won't work.
+ *
*/
-/*
+/*
* get_relattvals--
- * For each member of a list of clauseinfo nodes to be used with an
- * index, create a vectori-long specifying:
- * the attnos,
- * the values of the clause constants, and
- * flags indicating the type and location of the constant within
- * each clause.
- * Each clause is of the form (op var some_type_of_constant), thus the
- * flag indicating whether the constant is on the left or right should
- * always be *SELEC-CONSTANT-RIGHT*.
- *
+ * For each member of a list of clauseinfo nodes to be used with an
+ * index, create a vectori-long specifying:
+ * the attnos,
+ * the values of the clause constants, and
+ * flags indicating the type and location of the constant within
+ * each clause.
+ * Each clause is of the form (op var some_type_of_constant), thus the
+ * flag indicating whether the constant is on the left or right should
+ * always be *SELEC-CONSTANT-RIGHT*.
+ *
* 'clauseinfo-list' is a list of clauseinfo nodes
- *
+ *
* Returns a list of vectori-longs.
- *
+ *
*/
void
-get_relattvals(List *clauseinfo_list,
- List **attnos,
- List **values,
- List **flags)
+get_relattvals(List * clauseinfo_list,
+ List ** attnos,
+ List ** values,
+ List ** flags)
{
- List *result1 = NIL;
- List *result2 = NIL;
- List *result3 = NIL;
- CInfo *temp = (CInfo *)NULL;
- List *i = NIL;
-
- foreach (i,clauseinfo_list) {
- int dummy;
- AttrNumber attno;
- Datum constval;
- int flag;
-
- temp = (CInfo *)lfirst(i);
- get_relattval((Node*)temp->clause, &dummy, &attno, &constval, &flag);
- result1 = lappendi(result1, (int)attno);
- result2 = lappendi(result2, constval);
- result3 = lappendi(result3, flag);
- }
+ List *result1 = NIL;
+ List *result2 = NIL;
+ List *result3 = NIL;
+ CInfo *temp = (CInfo *) NULL;
+ List *i = NIL;
+
+ foreach(i, clauseinfo_list)
+ {
+ int dummy;
+ AttrNumber attno;
+ Datum constval;
+ int flag;
+
+ temp = (CInfo *) lfirst(i);
+ get_relattval((Node *) temp->clause, &dummy, &attno, &constval, &flag);
+ result1 = lappendi(result1, (int) attno);
+ result2 = lappendi(result2, constval);
+ result3 = lappendi(result3, flag);
+ }
- *attnos = result1;
- *values = result2;
- *flags = result3;
- return;
+ *attnos = result1;
+ *values = result2;
+ *flags = result3;
+ return;
}
-/*
+/*
* get_joinvars --
- * Given a list of join clauseinfo nodes to be used with the index
- * of an inner join relation, return three lists consisting of:
- * the attributes corresponding to the inner join relation
- * the value of the inner var clause (always "")
- * whether the attribute appears on the left or right side of
- * the operator.
- *
+ * Given a list of join clauseinfo nodes to be used with the index
+ * of an inner join relation, return three lists consisting of:
+ * the attributes corresponding to the inner join relation
+ * the value of the inner var clause (always "")
+ * whether the attribute appears on the left or right side of
+ * the operator.
+ *
* 'relid' is the inner join relation
* 'clauseinfo-list' is a list of qualification clauses to be used with
- * 'rel'
- *
+ * 'rel'
+ *
*/
void
get_joinvars(Oid relid,
- List *clauseinfo_list,
- List **attnos,
- List **values,
- List **flags)
+ List * clauseinfo_list,
+ List ** attnos,
+ List ** values,
+ List ** flags)
{
- List *result1 = NIL;
- List *result2 = NIL;
- List *result3 = NIL;
- List *temp;
-
- foreach(temp, clauseinfo_list) {
- CInfo *clauseinfo = lfirst(temp);
- Expr *clause = clauseinfo->clause;
-
- if( IsA (get_leftop(clause),Var) &&
- (relid == (get_leftop(clause))->varno)) {
- result1 = lappendi(result1, (int4)(get_leftop(clause))->varattno);
- result2 = lappend(result2, "");
- result3 = lappendi(result3, _SELEC_CONSTANT_RIGHT_);
- } else {
- result1 = lappendi(result1, (int4)(get_rightop(clause))->varattno);
- result2 = lappend(result2, "");
- result3 = lappendi(result3, _SELEC_CONSTANT_LEFT_);
+ List *result1 = NIL;
+ List *result2 = NIL;
+ List *result3 = NIL;
+ List *temp;
+
+ foreach(temp, clauseinfo_list)
+ {
+ CInfo *clauseinfo = lfirst(temp);
+ Expr *clause = clauseinfo->clause;
+
+ if (IsA(get_leftop(clause), Var) &&
+ (relid == (get_leftop(clause))->varno))
+ {
+ result1 = lappendi(result1, (int4) (get_leftop(clause))->varattno);
+ result2 = lappend(result2, "");
+ result3 = lappendi(result3, _SELEC_CONSTANT_RIGHT_);
+ }
+ else
+ {
+ result1 = lappendi(result1, (int4) (get_rightop(clause))->varattno);
+ result2 = lappend(result2, "");
+ result3 = lappendi(result3, _SELEC_CONSTANT_LEFT_);
+ }
}
- }
- *attnos = result1;
- *values = result2;
- *flags = result3;
- return;
+ *attnos = result1;
+ *values = result2;
+ *flags = result3;
+ return;
}
-/*
+/*
* get_opnos--
- * Create and return a list containing the clause operators of each member
- * of a list of clauseinfo nodes to be used with an index.
- *
+ * Create and return a list containing the clause operators of each member
+ * of a list of clauseinfo nodes to be used with an index.
+ *
*/
-List *
-get_opnos(List *clauseinfo_list)
+List *
+get_opnos(List * clauseinfo_list)
{
- CInfo *temp = (CInfo *)NULL;
- List *result = NIL;
- List *i = NIL;
-
- foreach(i,clauseinfo_list) {
- temp = (CInfo *)lfirst(i);
- result =
- lappendi(result,
- (((Oper*)temp->clause->oper)->opno));
- }
- return(result);
+ CInfo *temp = (CInfo *) NULL;
+ List *result = NIL;
+ List *i = NIL;
+
+ foreach(i, clauseinfo_list)
+ {
+ temp = (CInfo *) lfirst(i);
+ result =
+ lappendi(result,
+ (((Oper *) temp->clause->oper)->opno));
+ }
+ return (result);
}
-
-
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 153c11f9f42..03e0856ef09 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* clauses.c--
- * routines to manipulate qualification clauses
+ * routines to manipulate qualification clauses
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.7 1997/08/19 21:31:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.8 1997/09/07 04:44:20 momjian Exp $
*
* HISTORY
- * AUTHOR DATE MAJOR EVENT
- * Andrew Yu Nov 3, 1994 clause.c and clauses.c combined
+ * AUTHOR DATE MAJOR EVENT
+ * Andrew Yu Nov 3, 1994 clause.c and clauses.c combined
*
*-------------------------------------------------------------------------
*/
@@ -34,533 +34,556 @@
#include "optimizer/internal.h"
#include "optimizer/var.h"
-static bool agg_clause(Node *clause);
+static bool agg_clause(Node * clause);
-Expr *
-make_clause(int type, Node *oper, List *args)
+Expr *
+make_clause(int type, Node * oper, List * args)
{
- if (type == AND_EXPR || type == OR_EXPR || type == NOT_EXPR ||
- type == OP_EXPR || type == FUNC_EXPR) {
- Expr *expr = makeNode(Expr);
-
- /*
- * assume type checking already done and we don't need the type of
- * the expr any more.
- */
- expr->typeOid = InvalidOid;
- expr->opType = type;
- expr->oper = oper; /* ignored for AND, OR, NOT */
- expr->args = args;
- return expr;
- }else {
- /* will this ever happen? translated from lispy C code - ay 10/94 */
- return((Expr*)args);
- }
+ if (type == AND_EXPR || type == OR_EXPR || type == NOT_EXPR ||
+ type == OP_EXPR || type == FUNC_EXPR)
+ {
+ Expr *expr = makeNode(Expr);
+
+ /*
+ * assume type checking already done and we don't need the type of
+ * the expr any more.
+ */
+ expr->typeOid = InvalidOid;
+ expr->opType = type;
+ expr->oper = oper; /* ignored for AND, OR, NOT */
+ expr->args = args;
+ return expr;
+ }
+ else
+ {
+ /* will this ever happen? translated from lispy C code - ay 10/94 */
+ return ((Expr *) args);
+ }
}
/*****************************************************************************
- * OPERATOR clause functions
+ * OPERATOR clause functions
*****************************************************************************/
-/*
+/*
* is_opclause--
- *
+ *
* Returns t iff the clause is an operator clause:
- * (op expr expr) or (op expr).
+ * (op expr expr) or (op expr).
*
* [historical note: is_clause has the exact functionality and is used
- * throughout the code. They're renamed to is_opclause for clarity.
- * - ay 10/94.]
+ * throughout the code. They're renamed to is_opclause for clarity.
+ * - ay 10/94.]
*/
bool
-is_opclause(Node *clause)
+is_opclause(Node * clause)
{
- return
- (clause!=NULL &&
- nodeTag(clause)==T_Expr && ((Expr*)clause)->opType==OP_EXPR);
+ return
+ (clause != NULL &&
+ nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == OP_EXPR);
}
-/*
+/*
* make_opclause--
- * Creates a clause given its operator left operand and right
- * operand (if it is non-null).
- *
+ * Creates a clause given its operator left operand and right
+ * operand (if it is non-null).
+ *
*/
-Expr *
-make_opclause(Oper *op, Var *leftop, Var *rightop)
+Expr *
+make_opclause(Oper * op, Var * leftop, Var * rightop)
{
- Expr *expr = makeNode(Expr);
+ Expr *expr = makeNode(Expr);
- expr->typeOid = InvalidOid; /* assume type checking done */
- expr->opType = OP_EXPR;
- expr->oper = (Node*)op;
- expr->args = makeList(leftop, rightop, -1);
- return expr;
+ expr->typeOid = InvalidOid; /* assume type checking done */
+ expr->opType = OP_EXPR;
+ expr->oper = (Node *) op;
+ expr->args = makeList(leftop, rightop, -1);
+ return expr;
}
-/*
+/*
* get_leftop--
- *
+ *
* Returns the left operand of a clause of the form (op expr expr)
- * or (op expr)
- * NB: it is assumed (for now) that all expr must be Var nodes
+ * or (op expr)
+ * NB: it is assumed (for now) that all expr must be Var nodes
*/
-Var *
-get_leftop(Expr *clause)
+Var *
+get_leftop(Expr * clause)
{
- if (clause->args!=NULL)
- return(lfirst(clause->args));
- else
- return NULL;
+ if (clause->args != NULL)
+ return (lfirst(clause->args));
+ else
+ return NULL;
}
-/*
+/*
* get_rightop
- *
+ *
* Returns the right operand in a clause of the form (op expr expr).
- *
+ *
*/
-Var *
-get_rightop(Expr *clause)
+Var *
+get_rightop(Expr * clause)
{
- if (clause->args!=NULL && lnext(clause->args)!=NULL)
- return (lfirst(lnext(clause->args)));
- else
- return NULL;
+ if (clause->args != NULL && lnext(clause->args) != NULL)
+ return (lfirst(lnext(clause->args)));
+ else
+ return NULL;
}
/*****************************************************************************
- * AGG clause functions
+ * AGG clause functions
*****************************************************************************/
-static bool
-agg_clause(Node *clause)
+static bool
+agg_clause(Node * clause)
{
- return
- (clause!=NULL && nodeTag(clause)==T_Aggreg);
+ return
+ (clause != NULL && nodeTag(clause) == T_Aggreg);
}
/*****************************************************************************
- * FUNC clause functions
+ * FUNC clause functions
*****************************************************************************/
-/*
+/*
* is_funcclause--
- *
+ *
* Returns t iff the clause is a function clause: (func { expr }).
- *
+ *
*/
bool
-is_funcclause(Node *clause)
+is_funcclause(Node * clause)
{
- return
- (clause!=NULL &&
- nodeTag(clause)==T_Expr && ((Expr*)clause)->opType==FUNC_EXPR);
+ return
+ (clause != NULL &&
+ nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == FUNC_EXPR);
}
-/*
+/*
* make_funcclause--
- *
+ *
* Creates a function clause given the FUNC node and the functional
* arguments.
- *
+ *
*/
-Expr *
-make_funcclause(Func *func, List *funcargs)
+Expr *
+make_funcclause(Func * func, List * funcargs)
{
- Expr *expr = makeNode(Expr);
+ Expr *expr = makeNode(Expr);
- expr->typeOid = InvalidOid; /* assume type checking done */
- expr->opType = FUNC_EXPR;
- expr->oper = (Node*)func;
- expr->args = funcargs;
- return expr;
+ expr->typeOid = InvalidOid; /* assume type checking done */
+ expr->opType = FUNC_EXPR;
+ expr->oper = (Node *) func;
+ expr->args = funcargs;
+ return expr;
}
/*****************************************************************************
- * OR clause functions
+ * OR clause functions
*****************************************************************************/
-/*
+/*
* or_clause--
- *
+ *
* Returns t iff the clause is an 'or' clause: (OR { expr }).
- *
+ *
*/
bool
-or_clause(Node *clause)
+or_clause(Node * clause)
{
- return
- (clause!=NULL &&
- nodeTag(clause)==T_Expr && ((Expr*)clause)->opType==OR_EXPR);
+ return
+ (clause != NULL &&
+ nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == OR_EXPR);
}
-/*
+/*
* make_orclause--
- *
+ *
* Creates an 'or' clause given a list of its subclauses.
- *
+ *
*/
-Expr *
-make_orclause(List *orclauses)
+Expr *
+make_orclause(List * orclauses)
{
- Expr *expr = makeNode(Expr);
+ Expr *expr = makeNode(Expr);
- expr->typeOid = InvalidOid; /* assume type checking done */
- expr->opType = OR_EXPR;
- expr->oper = NULL;
- expr->args = orclauses;
- return expr;
+ expr->typeOid = InvalidOid; /* assume type checking done */
+ expr->opType = OR_EXPR;
+ expr->oper = NULL;
+ expr->args = orclauses;
+ return expr;
}
/*****************************************************************************
- * NOT clause functions
+ * NOT clause functions
*****************************************************************************/
-/*
+/*
* not_clause--
- *
+ *
* Returns t iff this is a 'not' clause: (NOT expr).
- *
+ *
*/
bool
-not_clause(Node *clause)
+not_clause(Node * clause)
{
- return
- (clause!=NULL &&
- nodeTag(clause)==T_Expr && ((Expr*)clause)->opType == NOT_EXPR);
+ return
+ (clause != NULL &&
+ nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == NOT_EXPR);
}
-/*
+/*
* make_notclause--
- *
+ *
* Create a 'not' clause given the expression to be negated.
- *
+ *
*/
-Expr *
-make_notclause(Expr *notclause)
+Expr *
+make_notclause(Expr * notclause)
{
- Expr *expr = makeNode(Expr);
+ Expr *expr = makeNode(Expr);
- expr->typeOid = InvalidOid; /* assume type checking done */
- expr->opType = NOT_EXPR;
- expr->oper = NULL;
- expr->args = lcons(notclause, NIL);
- return expr;
+ expr->typeOid = InvalidOid; /* assume type checking done */
+ expr->opType = NOT_EXPR;
+ expr->oper = NULL;
+ expr->args = lcons(notclause, NIL);
+ return expr;
}
-/*
+/*
* get_notclausearg--
- *
+ *
* Retrieve the clause within a 'not' clause
- *
+ *
*/
-Expr *
-get_notclausearg(Expr *notclause)
+Expr *
+get_notclausearg(Expr * notclause)
{
- return(lfirst(notclause->args));
+ return (lfirst(notclause->args));
}
/*****************************************************************************
- * AND clause functions
+ * AND clause functions
*****************************************************************************/
-/*
+/*
* and_clause--
- *
+ *
* Returns t iff its argument is an 'and' clause: (AND { expr }).
- *
+ *
*/
bool
-and_clause(Node *clause)
+and_clause(Node * clause)
{
- return
- (clause!=NULL &&
- nodeTag(clause)==T_Expr && ((Expr*)clause)->opType == AND_EXPR);
+ return
+ (clause != NULL &&
+ nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == AND_EXPR);
}
-/*
+
+/*
* make_andclause--
- *
+ *
* Create an 'and' clause given its arguments in a list.
- *
+ *
*/
-Expr *
-make_andclause(List *andclauses)
+Expr *
+make_andclause(List * andclauses)
{
- Expr *expr = makeNode(Expr);
+ Expr *expr = makeNode(Expr);
- expr->typeOid = InvalidOid; /* assume type checking done */
- expr->opType = AND_EXPR;
- expr->oper = NULL;
- expr->args = andclauses;
- return expr;
+ expr->typeOid = InvalidOid; /* assume type checking done */
+ expr->opType = AND_EXPR;
+ expr->oper = NULL;
+ expr->args = andclauses;
+ return expr;
}
/*****************************************************************************
- * *
- * *
- * *
+ * *
+ * *
+ * *
*****************************************************************************/
-/*
+/*
* pull-constant-clauses--
- * Scans through a list of qualifications and find those that
- * contain no variables.
- *
+ * Scans through a list of qualifications and find those that
+ * contain no variables.
+ *
* Returns a list of the constant clauses in constantQual and the remaining
* quals as the return value.
- *
+ *
*/
-List *
-pull_constant_clauses(List *quals, List **constantQual)
+List *
+pull_constant_clauses(List * quals, List ** constantQual)
{
- List *q;
- List *constqual=NIL;
- List *restqual=NIL;
-
- foreach(q, quals) {
- if (!contain_var_clause(lfirst(q))) {
- constqual = lcons(lfirst(q), constqual);
- }else {
- restqual = lcons(lfirst(q), restqual);
+ List *q;
+ List *constqual = NIL;
+ List *restqual = NIL;
+
+ foreach(q, quals)
+ {
+ if (!contain_var_clause(lfirst(q)))
+ {
+ constqual = lcons(lfirst(q), constqual);
+ }
+ else
+ {
+ restqual = lcons(lfirst(q), restqual);
+ }
}
- }
- freeList(quals);
- *constantQual = constqual;
- return restqual;
+ freeList(quals);
+ *constantQual = constqual;
+ return restqual;
}
-/*
+/*
* clause-relids-vars--
- * Retrieves relids and vars appearing within a clause.
- * Returns ((relid1 relid2 ... relidn) (var1 var2 ... varm)) where
- * vars appear in the clause this is done by recursively searching
- * through the left and right operands of a clause.
- *
+ * Retrieves relids and vars appearing within a clause.
+ * Returns ((relid1 relid2 ... relidn) (var1 var2 ... varm)) where
+ * vars appear in the clause this is done by recursively searching
+ * through the left and right operands of a clause.
+ *
* Returns the list of relids and vars.
- *
+ *
* XXX take the nreverse's out later
- *
+ *
*/
void
-clause_relids_vars(Node *clause, List **relids, List **vars)
+clause_relids_vars(Node * clause, List ** relids, List ** vars)
{
- List *clvars = pull_var_clause(clause);
- List *var_list = NIL;
- List *varno_list = NIL;
- List *i = NIL;
+ List *clvars = pull_var_clause(clause);
+ List *var_list = NIL;
+ List *varno_list = NIL;
+ List *i = NIL;
- foreach (i, clvars) {
- Var *var = (Var *)lfirst(i);
- List *vi;
-
- if (!intMember(var->varno, varno_list)) {
- varno_list = lappendi(varno_list, var->varno);
- }
- foreach (vi, var_list)
+ foreach(i, clvars)
{
- Var *in_list = (Var *)lfirst(vi);
-
- if ( in_list->varno == var->varno &&
- in_list->varattno == var->varattno )
- break;
+ Var *var = (Var *) lfirst(i);
+ List *vi;
+
+ if (!intMember(var->varno, varno_list))
+ {
+ varno_list = lappendi(varno_list, var->varno);
+ }
+ foreach(vi, var_list)
+ {
+ Var *in_list = (Var *) lfirst(vi);
+
+ if (in_list->varno == var->varno &&
+ in_list->varattno == var->varattno)
+ break;
+ }
+ if (vi == NIL)
+ var_list = lappend(var_list, var);
}
- if ( vi == NIL )
- var_list = lappend(var_list, var);
- }
- *relids = varno_list;
- *vars = var_list;
- return;
+ *relids = varno_list;
+ *vars = var_list;
+ return;
}
-/*
+/*
* NumRelids--
- * (formerly clause-relids)
- *
+ * (formerly clause-relids)
+ *
* Returns the number of different relations referenced in 'clause'.
*/
int
-NumRelids(Node *clause)
+NumRelids(Node * clause)
{
- List *vars = pull_var_clause(clause);
- List *i = NIL;
- List *var_list = NIL;
+ List *vars = pull_var_clause(clause);
+ List *i = NIL;
+ List *var_list = NIL;
- foreach (i, vars) {
- Var *var = (Var *)lfirst(i);
+ foreach(i, vars)
+ {
+ Var *var = (Var *) lfirst(i);
- if (!intMember(var->varno, var_list)) {
- var_list = lconsi(var->varno, var_list);
+ if (!intMember(var->varno, var_list))
+ {
+ var_list = lconsi(var->varno, var_list);
+ }
}
- }
- return(length(var_list));
+ return (length(var_list));
}
-/*
+/*
* contains-not--
*
* Returns t iff the clause is a 'not' clause or if any of the
* subclauses within an 'or' clause contain 'not's.
- *
+ *
*/
bool
-contains_not(Node *clause)
+contains_not(Node * clause)
{
- if (single_node(clause))
- return (false);
-
- if (not_clause(clause))
- return (true);
+ if (single_node(clause))
+ return (false);
- if (or_clause(clause)) {
- List *a;
- foreach(a, ((Expr*)clause)->args) {
- if (contains_not(lfirst(a)))
+ if (not_clause(clause))
return (true);
+
+ if (or_clause(clause))
+ {
+ List *a;
+
+ foreach(a, ((Expr *) clause)->args)
+ {
+ if (contains_not(lfirst(a)))
+ return (true);
+ }
}
- }
-
- return(false);
+
+ return (false);
}
-/*
+/*
* join-clause-p--
- *
+ *
* Returns t iff 'clause' is a valid join clause.
- *
+ *
*/
bool
-join_clause_p(Node *clause)
+join_clause_p(Node * clause)
{
- Node *leftop, *rightop;
+ Node *leftop,
+ *rightop;
- if (!is_opclause(clause))
- return false;
+ if (!is_opclause(clause))
+ return false;
- leftop = (Node*)get_leftop((Expr*)clause);
- rightop = (Node*)get_rightop((Expr*)clause);
+ leftop = (Node *) get_leftop((Expr *) clause);
+ rightop = (Node *) get_rightop((Expr *) clause);
- /*
- * One side of the clause (i.e. left or right operands)
- * must either be a var node ...
- */
- if (IsA(leftop,Var) || IsA(rightop,Var))
- return true;
+ /*
+ * One side of the clause (i.e. left or right operands) must either be
+ * a var node ...
+ */
+ if (IsA(leftop, Var) || IsA(rightop, Var))
+ return true;
- /*
- * ... or a func node.
- */
- if (is_funcclause(leftop) || is_funcclause(rightop))
- return(true);
+ /*
+ * ... or a func node.
+ */
+ if (is_funcclause(leftop) || is_funcclause(rightop))
+ return (true);
- return(false);
+ return (false);
}
-/*
+/*
* qual-clause-p--
- *
+ *
* Returns t iff 'clause' is a valid qualification clause.
- *
+ *
*/
bool
-qual_clause_p(Node *clause)
+qual_clause_p(Node * clause)
{
- if (!is_opclause(clause))
- return false;
+ if (!is_opclause(clause))
+ return false;
- if (IsA (get_leftop((Expr*)clause),Var) &&
- IsA (get_rightop((Expr*)clause),Const))
+ if (IsA(get_leftop((Expr *) clause), Var) &&
+ IsA(get_rightop((Expr *) clause), Const))
{
- return(true);
+ return (true);
}
- else if (IsA (get_rightop((Expr*)clause),Var) &&
- IsA (get_leftop((Expr*)clause),Const))
+ else if (IsA(get_rightop((Expr *) clause), Var) &&
+ IsA(get_leftop((Expr *) clause), Const))
{
- return(true);
+ return (true);
}
- return(false);
+ return (false);
}
-/*
+/*
* fix-opid--
- * Calculate the opfid from the opno...
- *
+ * Calculate the opfid from the opno...
+ *
* Returns nothing.
- *
+ *
*/
void
-fix_opid(Node *clause)
+fix_opid(Node * clause)
{
- if (clause==NULL || single_node(clause)) {
- ;
- }
- else if (or_clause (clause)) {
- fix_opids(((Expr*)clause)->args);
- }
- else if (is_funcclause (clause)) {
- fix_opids(((Expr*)clause)->args);
- }
- else if (IsA(clause,ArrayRef)) {
- ArrayRef *aref = (ArrayRef *)clause;
-
- fix_opids(aref->refupperindexpr);
- fix_opids(aref->reflowerindexpr);
- fix_opid(aref->refexpr);
- fix_opid(aref->refassgnexpr);
- }
- else if (not_clause(clause)) {
- fix_opid((Node*)get_notclausearg((Expr*)clause));
- }
- else if (is_opclause (clause)) {
- replace_opid((Oper*)((Expr*)clause)->oper);
- fix_opid((Node*)get_leftop((Expr*)clause));
- fix_opid((Node*)get_rightop((Expr*)clause));
- }
- else if (agg_clause (clause)) {
- fix_opid (((Aggreg*)clause)->target);
- }
+ if (clause == NULL || single_node(clause))
+ {
+ ;
+ }
+ else if (or_clause(clause))
+ {
+ fix_opids(((Expr *) clause)->args);
+ }
+ else if (is_funcclause(clause))
+ {
+ fix_opids(((Expr *) clause)->args);
+ }
+ else if (IsA(clause, ArrayRef))
+ {
+ ArrayRef *aref = (ArrayRef *) clause;
+
+ fix_opids(aref->refupperindexpr);
+ fix_opids(aref->reflowerindexpr);
+ fix_opid(aref->refexpr);
+ fix_opid(aref->refassgnexpr);
+ }
+ else if (not_clause(clause))
+ {
+ fix_opid((Node *) get_notclausearg((Expr *) clause));
+ }
+ else if (is_opclause(clause))
+ {
+ replace_opid((Oper *) ((Expr *) clause)->oper);
+ fix_opid((Node *) get_leftop((Expr *) clause));
+ fix_opid((Node *) get_rightop((Expr *) clause));
+ }
+ else if (agg_clause(clause))
+ {
+ fix_opid(((Aggreg *) clause)->target);
+ }
}
-/*
+/*
* fix-opids--
- * Calculate the opfid from the opno for all the clauses...
- *
+ * Calculate the opfid from the opno for all the clauses...
+ *
* Returns its argument.
- *
+ *
*/
-List *
-fix_opids(List *clauses)
+List *
+fix_opids(List * clauses)
{
- List *clause;
+ List *clause;
- foreach(clause, clauses)
- fix_opid(lfirst(clause));
+ foreach(clause, clauses)
+ fix_opid(lfirst(clause));
- return(clauses);
+ return (clauses);
}
-/*
+/*
* get_relattval--
- * For a non-join clause, returns a list consisting of the
- * relid,
- * attno,
- * value of the CONST node (if any), and a
- * flag indicating whether the value appears on the left or right
- * of the operator and whether the value varied.
+ * For a non-join clause, returns a list consisting of the
+ * relid,
+ * attno,
+ * value of the CONST node (if any), and a
+ * flag indicating whether the value appears on the left or right
+ * of the operator and whether the value varied.
*
* OLD OBSOLETE COMMENT FOLLOWS:
- * If 'clause' is not of the format (op var node) or (op node var),
- * or if the var refers to a nested attribute, then -1's are returned for
- * everything but the value a blank string "" (pointer to \0) is
- * returned for the value if it is unknown or null.
+ * If 'clause' is not of the format (op var node) or (op node var),
+ * or if the var refers to a nested attribute, then -1's are returned for
+ * everything but the value a blank string "" (pointer to \0) is
+ * returned for the value if it is unknown or null.
* END OF OLD OBSOLETE COMMENT.
* NEW COMMENT:
* when defining rules one of the attibutes of the operator can
@@ -569,198 +592,223 @@ fix_opids(List *clauses)
* this routine used to return "" as value, which made 'compute_selec'
* to bomb (because it was expecting a lisp integer and got back a lisp
* string). Now the code returns a plain old good "lispInteger(0)".
- *
+ *
*/
void
-get_relattval(Node *clause,
- int *relid,
- AttrNumber *attno,
- Datum *constval,
- int *flag)
+get_relattval(Node * clause,
+ int *relid,
+ AttrNumber * attno,
+ Datum * constval,
+ int *flag)
{
- Var *left = get_leftop((Expr*)clause);
- Var *right = get_rightop((Expr*)clause);
-
- if(is_opclause(clause) && IsA(left,Var) &&
- IsA(right,Const)) {
-
- if(right!=NULL) {
-
- *relid = left->varno;
- *attno = left->varattno;
- *constval = ((Const *)right)->constvalue;
- *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_);
-
- } else {
-
- *relid = left->varno;
- *attno = left->varattno;
- *constval = 0;
- *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_NOT_CONSTANT_);
-
- }
+ Var *left = get_leftop((Expr *) clause);
+ Var *right = get_rightop((Expr *) clause);
+
+ if (is_opclause(clause) && IsA(left, Var) &&
+ IsA(right, Const))
+ {
+
+ if (right != NULL)
+ {
+
+ *relid = left->varno;
+ *attno = left->varattno;
+ *constval = ((Const *) right)->constvalue;
+ *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_);
+
+ }
+ else
+ {
+
+ *relid = left->varno;
+ *attno = left->varattno;
+ *constval = 0;
+ *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_NOT_CONSTANT_);
+
+ }
#ifdef INDEXSCAN_PATCH
- } else if (is_opclause(clause) && IsA(left,Var) && IsA(right,Param)) {
- /* Function parameter used as index scan arg. DZ - 27-8-1996 */
- *relid = left->varno;
- *attno = left->varattno;
- *constval = 0;
- *flag = (_SELEC_NOT_CONSTANT_);
+ }
+ else if (is_opclause(clause) && IsA(left, Var) && IsA(right, Param))
+ {
+ /* Function parameter used as index scan arg. DZ - 27-8-1996 */
+ *relid = left->varno;
+ *attno = left->varattno;
+ *constval = 0;
+ *flag = (_SELEC_NOT_CONSTANT_);
#endif
- }else if (is_opclause(clause) &&
- is_funcclause((Node*)left) &&
- IsA(right,Const)) {
- List *args = ((Expr*)left)->args;
+ }
+ else if (is_opclause(clause) &&
+ is_funcclause((Node *) left) &&
+ IsA(right, Const))
+ {
+ List *args = ((Expr *) left)->args;
+
+
+ *relid = ((Var *) lfirst(args))->varno;
+ *attno = InvalidAttrNumber;
+ *constval = ((Const *) right)->constvalue;
+ *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_);
+
+ /*
+ * XXX both of these func clause handling if's seem wrong to me.
+ * they assume that the first argument is the Var. It could not
+ * handle (for example) f(1, emp.name). I think I may have been
+ * assuming no constants in functional index scans when I
+ * implemented this originally (still currently true). -mer 10 Aug
+ * 1992
+ */
+ }
+ else if (is_opclause(clause) &&
+ is_funcclause((Node *) right) &&
+ IsA(left, Const))
+ {
+ List *args = ((Expr *) right)->args;
+ *relid = ((Var *) lfirst(args))->varno;
+ *attno = InvalidAttrNumber;
+ *constval = ((Const *) left)->constvalue;
+ *flag = (_SELEC_IS_CONSTANT_);
- *relid = ((Var*)lfirst(args))->varno;
- *attno = InvalidAttrNumber;
- *constval = ((Const*)right)->constvalue;
- *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_);
-
- /*
- * XXX both of these func clause handling if's seem wrong to me.
- * they assume that the first argument is the Var. It could
- * not handle (for example) f(1, emp.name). I think I may have
- * been assuming no constants in functional index scans when I
- * implemented this originally (still currently true).
- * -mer 10 Aug 1992
- */
- } else if (is_opclause(clause) &&
- is_funcclause((Node*)right) &&
- IsA(left,Const)) {
- List *args = ((Expr*)right)->args;
-
- *relid = ((Var*)lfirst(args))->varno;
- *attno = InvalidAttrNumber;
- *constval = ((Const*)left)->constvalue;
- *flag = ( _SELEC_IS_CONSTANT_);
-
- } else if (is_opclause (clause) && IsA (right,Var) &&
- IsA (left,Const)) {
- if (left!=NULL) {
-
- *relid = right->varno;
- *attno = right->varattno;
- *constval = ((Const*)left)->constvalue;
- *flag = (_SELEC_IS_CONSTANT_);
- } else {
-
- *relid = right->varno;
- *attno = right->varattno;
- *constval = 0;
- *flag = (_SELEC_NOT_CONSTANT_);
- }
+ }
+ else if (is_opclause(clause) && IsA(right, Var) &&
+ IsA(left, Const))
+ {
+ if (left != NULL)
+ {
+
+ *relid = right->varno;
+ *attno = right->varattno;
+ *constval = ((Const *) left)->constvalue;
+ *flag = (_SELEC_IS_CONSTANT_);
+ }
+ else
+ {
+
+ *relid = right->varno;
+ *attno = right->varattno;
+ *constval = 0;
+ *flag = (_SELEC_NOT_CONSTANT_);
+ }
#ifdef INDEXSCAN_PATCH
- } else if (is_opclause(clause) && IsA(right,Var) && IsA(left,Param)) {
- /* ...And here... - vadim 01/22/97 */
- *relid = right->varno;
- *attno = right->varattno;
- *constval = 0;
- *flag = (_SELEC_NOT_CONSTANT_);
+ }
+ else if (is_opclause(clause) && IsA(right, Var) && IsA(left, Param))
+ {
+ /* ...And here... - vadim 01/22/97 */
+ *relid = right->varno;
+ *attno = right->varattno;
+ *constval = 0;
+ *flag = (_SELEC_NOT_CONSTANT_);
#endif
- } else {
- /* One or more of the operands are expressions
- * (e.g., oper clauses)
- */
- *relid = _SELEC_VALUE_UNKNOWN_;
- *attno = _SELEC_VALUE_UNKNOWN_;
- *constval = 0;
- *flag = (_SELEC_NOT_CONSTANT_);
- }
+ }
+ else
+ {
+
+ /*
+ * One or more of the operands are expressions (e.g., oper
+ * clauses)
+ */
+ *relid = _SELEC_VALUE_UNKNOWN_;
+ *attno = _SELEC_VALUE_UNKNOWN_;
+ *constval = 0;
+ *flag = (_SELEC_NOT_CONSTANT_);
+ }
}
-/*
+/*
* get_relsatts--
- *
- * Returns a list
- * ( relid1 attno1 relid2 attno2 )
- * for a joinclause.
- *
+ *
+ * Returns a list
+ * ( relid1 attno1 relid2 attno2 )
+ * for a joinclause.
+ *
* If the clause is not of the form (op var var) or if any of the vars
* refer to nested attributes, then -1's are returned.
- *
+ *
*/
void
-get_rels_atts(Node *clause,
- int *relid1,
- AttrNumber *attno1,
- int *relid2,
- AttrNumber *attno2)
+get_rels_atts(Node * clause,
+ int *relid1,
+ AttrNumber * attno1,
+ int *relid2,
+ AttrNumber * attno2)
{
- Var *left = get_leftop((Expr*)clause);
- Var *right = get_rightop((Expr*)clause);
- bool var_left = (IsA(left,Var));
- bool var_right = (IsA(right,Var));
- bool varexpr_left = (bool)((IsA(left,Func) || IsA (left,Oper)) &&
- contain_var_clause((Node*)left));
- bool varexpr_right = (bool)(( IsA(right,Func) || IsA (right,Oper)) &&
- contain_var_clause((Node*)right));
-
- if (is_opclause(clause)) {
- if(var_left && var_right) {
-
- *relid1 = left->varno;
- *attno1 = left->varoattno;
- *relid2 = right->varno;
- *attno2 = right->varoattno;
- return;
- } else if (var_left && varexpr_right ) {
-
- *relid1 = left->varno;
- *attno1 = left->varoattno;
- *relid2 = _SELEC_VALUE_UNKNOWN_;
- *attno2 = _SELEC_VALUE_UNKNOWN_;
- return;
- } else if (varexpr_left && var_right) {
-
- *relid1 = _SELEC_VALUE_UNKNOWN_;
- *attno1 = _SELEC_VALUE_UNKNOWN_;
- *relid2 = right->varno;
- *attno2 = right->varoattno;
- return;
+ Var *left = get_leftop((Expr *) clause);
+ Var *right = get_rightop((Expr *) clause);
+ bool var_left = (IsA(left, Var));
+ bool var_right = (IsA(right, Var));
+ bool varexpr_left = (bool) ((IsA(left, Func) || IsA(left, Oper)) &&
+ contain_var_clause((Node *) left));
+ bool varexpr_right = (bool) ((IsA(right, Func) || IsA(right, Oper)) &&
+ contain_var_clause((Node *) right));
+
+ if (is_opclause(clause))
+ {
+ if (var_left && var_right)
+ {
+
+ *relid1 = left->varno;
+ *attno1 = left->varoattno;
+ *relid2 = right->varno;
+ *attno2 = right->varoattno;
+ return;
+ }
+ else if (var_left && varexpr_right)
+ {
+
+ *relid1 = left->varno;
+ *attno1 = left->varoattno;
+ *relid2 = _SELEC_VALUE_UNKNOWN_;
+ *attno2 = _SELEC_VALUE_UNKNOWN_;
+ return;
+ }
+ else if (varexpr_left && var_right)
+ {
+
+ *relid1 = _SELEC_VALUE_UNKNOWN_;
+ *attno1 = _SELEC_VALUE_UNKNOWN_;
+ *relid2 = right->varno;
+ *attno2 = right->varoattno;
+ return;
+ }
}
- }
- *relid1 = _SELEC_VALUE_UNKNOWN_;
- *attno1 = _SELEC_VALUE_UNKNOWN_;
- *relid2 = _SELEC_VALUE_UNKNOWN_;
- *attno2 = _SELEC_VALUE_UNKNOWN_;
- return;
+ *relid1 = _SELEC_VALUE_UNKNOWN_;
+ *attno1 = _SELEC_VALUE_UNKNOWN_;
+ *relid2 = _SELEC_VALUE_UNKNOWN_;
+ *attno2 = _SELEC_VALUE_UNKNOWN_;
+ return;
}
void
-CommuteClause(Node *clause)
+CommuteClause(Node * clause)
{
- Node *temp;
- Oper *commu;
- OperatorTupleForm commuTup;
- HeapTuple heapTup;
+ Node *temp;
+ Oper *commu;
+ OperatorTupleForm commuTup;
+ HeapTuple heapTup;
- if (!is_opclause(clause))
- return;
+ if (!is_opclause(clause))
+ return;
- heapTup = (HeapTuple)
- get_operator_tuple(get_commutator(((Oper*)((Expr*)clause)->oper)->opno));
+ heapTup = (HeapTuple)
+ get_operator_tuple(get_commutator(((Oper *) ((Expr *) clause)->oper)->opno));
- if (heapTup == (HeapTuple)NULL)
- return;
+ if (heapTup == (HeapTuple) NULL)
+ return;
- commuTup = (OperatorTupleForm)GETSTRUCT(heapTup);
-
- commu = makeOper(heapTup->t_oid,
- InvalidOid,
- commuTup->oprresult,
- ((Oper*)((Expr*)clause)->oper)->opsize,
- NULL);
-
- /*
- * reform the clause -> (operator func/var constant)
- */
- ((Expr*)clause)->oper = (Node*)commu;
- temp = lfirst(((Expr*)clause)->args);
- lfirst(((Expr*)clause)->args) = lsecond(((Expr*)clause)->args);
- lsecond(((Expr*)clause)->args) = temp;
-}
+ commuTup = (OperatorTupleForm) GETSTRUCT(heapTup);
+ commu = makeOper(heapTup->t_oid,
+ InvalidOid,
+ commuTup->oprresult,
+ ((Oper *) ((Expr *) clause)->oper)->opsize,
+ NULL);
+ /*
+ * reform the clause -> (operator func/var constant)
+ */
+ ((Expr *) clause)->oper = (Node *) commu;
+ temp = lfirst(((Expr *) clause)->args);
+ lfirst(((Expr *) clause)->args) = lsecond(((Expr *) clause)->args);
+ lsecond(((Expr *) clause)->args) = temp;
+}
diff --git a/src/backend/optimizer/util/indexnode.c b/src/backend/optimizer/util/indexnode.c
index 8e9237e6845..e6a1902f8b9 100644
--- a/src/backend/optimizer/util/indexnode.c
+++ b/src/backend/optimizer/util/indexnode.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* indexnode.c--
- * Routines to find all indices on a relation
+ * Routines to find all indices on a relation
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/indexnode.c,v 1.2 1996/10/31 10:59:37 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/indexnode.c,v 1.3 1997/09/07 04:44:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,74 +21,77 @@
#include "optimizer/internal.h"
#include "optimizer/plancat.h"
-#include "optimizer/pathnode.h" /* where the decls go */
+#include "optimizer/pathnode.h" /* where the decls go */
-static List *find_secondary_index(Query *root, Oid relid);
+static List *find_secondary_index(Query * root, Oid relid);
-/*
+/*
* find-relation-indices--
- * Returns a list of index nodes containing appropriate information for
- * each (secondary) index defined on a relation.
- *
+ * Returns a list of index nodes containing appropriate information for
+ * each (secondary) index defined on a relation.
+ *
*/
-List *
-find_relation_indices(Query *root, Rel *rel)
+List *
+find_relation_indices(Query * root, Rel * rel)
{
- if (rel->indexed) {
- return (find_secondary_index(root, lfirsti(rel->relids)));
- } else {
- return (NIL);
- }
+ if (rel->indexed)
+ {
+ return (find_secondary_index(root, lfirsti(rel->relids)));
+ }
+ else
+ {
+ return (NIL);
+ }
}
-/*
+/*
* find-secondary-index--
- * Creates a list of index path nodes containing information for each
- * secondary index defined on a relation by searching through the index
- * catalog.
- *
+ * Creates a list of index path nodes containing information for each
+ * secondary index defined on a relation by searching through the index
+ * catalog.
+ *
* 'relid' is the OID of the relation for which indices are being located
- *
+ *
* Returns a list of new index nodes.
- *
+ *
*/
-static List *
-find_secondary_index(Query *root, Oid relid)
+static List *
+find_secondary_index(Query * root, Oid relid)
{
- IdxInfoRetval indexinfo;
- List *indexes = NIL;
- bool first = TRUE;
+ IdxInfoRetval indexinfo;
+ List *indexes = NIL;
+ bool first = TRUE;
- while (index_info(root, first, relid,&indexinfo)) {
- Rel *indexnode = makeNode(Rel);
+ while (index_info(root, first, relid, &indexinfo))
+ {
+ Rel *indexnode = makeNode(Rel);
- indexnode->relids = lconsi(indexinfo.relid,NIL);
- indexnode->relam = indexinfo.relam;
- indexnode->pages = indexinfo.pages;
- indexnode->tuples = indexinfo.tuples;
- indexnode->indexkeys = indexinfo.indexkeys;
- indexnode->ordering = indexinfo.orderOprs;
- indexnode->classlist = indexinfo.classlist;
- indexnode->indproc= indexinfo.indproc;
- indexnode->indpred = (List*)indexinfo.indpred;
-
- indexnode->indexed= false; /* not indexed itself */
- indexnode->size = 0;
- indexnode->width= 0;
- indexnode->targetlist= NIL;
- indexnode->pathlist= NIL;
- indexnode->unorderedpath= NULL;
- indexnode->cheapestpath= NULL;
- indexnode->pruneable= true;
- indexnode->clauseinfo= NIL;
- indexnode->joininfo= NIL;
- indexnode->innerjoin= NIL;
+ indexnode->relids = lconsi(indexinfo.relid, NIL);
+ indexnode->relam = indexinfo.relam;
+ indexnode->pages = indexinfo.pages;
+ indexnode->tuples = indexinfo.tuples;
+ indexnode->indexkeys = indexinfo.indexkeys;
+ indexnode->ordering = indexinfo.orderOprs;
+ indexnode->classlist = indexinfo.classlist;
+ indexnode->indproc = indexinfo.indproc;
+ indexnode->indpred = (List *) indexinfo.indpred;
- indexes = lcons(indexnode, indexes);
- first = FALSE;
- }
+ indexnode->indexed = false; /* not indexed itself */
+ indexnode->size = 0;
+ indexnode->width = 0;
+ indexnode->targetlist = NIL;
+ indexnode->pathlist = NIL;
+ indexnode->unorderedpath = NULL;
+ indexnode->cheapestpath = NULL;
+ indexnode->pruneable = true;
+ indexnode->clauseinfo = NIL;
+ indexnode->joininfo = NIL;
+ indexnode->innerjoin = NIL;
- return indexes;
-}
+ indexes = lcons(indexnode, indexes);
+ first = FALSE;
+ }
+ return indexes;
+}
diff --git a/src/backend/optimizer/util/internal.c b/src/backend/optimizer/util/internal.c
index 8b2dfd43bcb..d1af2062fce 100644
--- a/src/backend/optimizer/util/internal.c
+++ b/src/backend/optimizer/util/internal.c
@@ -1,24 +1,24 @@
/*-------------------------------------------------------------------------
*
* internal.c--
- * Definitions required throughout the query optimizer.
+ * Definitions required throughout the query optimizer.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/internal.c,v 1.3 1997/08/20 14:53:37 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/internal.c,v 1.4 1997/09/07 04:44:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-/*
- * ---------- SHARED MACROS
- *
- * Macros common to modules for creating, accessing, and modifying
- * query tree and query plan components.
- * Shared with the executor.
- *
+/*
+ * ---------- SHARED MACROS
+ *
+ * Macros common to modules for creating, accessing, and modifying
+ * query tree and query plan components.
+ * Shared with the executor.
+ *
*/
#include <sys/types.h>
@@ -31,32 +31,30 @@
#include "nodes/primnodes.h"
#include "utils/palloc.h"
-#ifdef NOT_USED
+#ifdef NOT_USED
/*****************************************************************************
*
*****************************************************************************/
/* the following should probably be moved elsewhere -ay */
-TargetEntry *
-MakeTLE(Resdom *resdom, Node *expr)
+TargetEntry *
+MakeTLE(Resdom * resdom, Node * expr)
{
- TargetEntry *rt = makeNode(TargetEntry);
- rt->resdom = resdom;
- rt->expr = expr;
- return rt;
+ TargetEntry *rt = makeNode(TargetEntry);
+
+ rt->resdom = resdom;
+ rt->expr = expr;
+ return rt;
}
-Var *
-get_expr(TargetEntry *tle)
+Var *
+get_expr(TargetEntry * tle)
{
- Assert(tle!=NULL);
- Assert(tle->expr!=NULL);
+ Assert(tle != NULL);
+ Assert(tle->expr != NULL);
- return ((Var *)tle->expr);
+ return ((Var *) tle->expr);
}
-#endif /* 0 */
-
-
-
+#endif /* 0 */
diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c
index a4fd6913752..cf206d80094 100644
--- a/src/backend/optimizer/util/joininfo.c
+++ b/src/backend/optimizer/util/joininfo.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* joininfo.c--
- * JoinInfo node manipulation routines
+ * JoinInfo node manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/joininfo.c,v 1.2 1996/11/10 03:01:00 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/joininfo.c,v 1.3 1997/09/07 04:44:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,88 +21,96 @@
#include "optimizer/clauses.h"
-/*
+/*
* joininfo-member--
- * Determines whether a node has already been created for a join
- * between a set of join relations and the relation described by
- * 'joininfo-list'.
- *
+ * Determines whether a node has already been created for a join
+ * between a set of join relations and the relation described by
+ * 'joininfo-list'.
+ *
* 'join-relids' is a list of relids corresponding to the join relation
- * 'joininfo-list' is the list of joininfo nodes against which this is
- * checked
- *
+ * 'joininfo-list' is the list of joininfo nodes against which this is
+ * checked
+ *
* Returns the corresponding node in 'joininfo-list' if such a node
* exists.
- *
+ *
*/
-JInfo *
-joininfo_member(List *join_relids, List *joininfo_list)
+JInfo *
+joininfo_member(List * join_relids, List * joininfo_list)
{
- List *i = NIL;
- List *other_rels = NIL;
+ List *i = NIL;
+ List *other_rels = NIL;
- foreach(i,joininfo_list) {
- other_rels = lfirst(i);
- if(same(join_relids, ((JInfo*)other_rels)->otherrels))
- return((JInfo*)other_rels);
- }
- return((JInfo*)NULL);
+ foreach(i, joininfo_list)
+ {
+ other_rels = lfirst(i);
+ if (same(join_relids, ((JInfo *) other_rels)->otherrels))
+ return ((JInfo *) other_rels);
+ }
+ return ((JInfo *) NULL);
}
-/*
+/*
* find-joininfo-node--
- * Find the joininfo node within a relation entry corresponding
- * to a join between 'this_rel' and the relations in 'join-relids'. A
- * new node is created and added to the relation entry's joininfo
- * field if the desired one can't be found.
- *
+ * Find the joininfo node within a relation entry corresponding
+ * to a join between 'this_rel' and the relations in 'join-relids'. A
+ * new node is created and added to the relation entry's joininfo
+ * field if the desired one can't be found.
+ *
* Returns a joininfo node.
- *
+ *
*/
-JInfo *
-find_joininfo_node(Rel *this_rel, List *join_relids)
+JInfo *
+find_joininfo_node(Rel * this_rel, List * join_relids)
{
- JInfo *joininfo = joininfo_member(join_relids,
- this_rel->joininfo);
- if( joininfo == NULL ) {
- joininfo = makeNode(JInfo);
- joininfo->otherrels = join_relids;
- joininfo->jinfoclauseinfo = NIL;
- joininfo->mergesortable = false;
- joininfo->hashjoinable = false;
- joininfo->inactive = false;
- this_rel->joininfo = lcons(joininfo, this_rel->joininfo);
- }
- return(joininfo);
+ JInfo *joininfo = joininfo_member(join_relids,
+ this_rel->joininfo);
+
+ if (joininfo == NULL)
+ {
+ joininfo = makeNode(JInfo);
+ joininfo->otherrels = join_relids;
+ joininfo->jinfoclauseinfo = NIL;
+ joininfo->mergesortable = false;
+ joininfo->hashjoinable = false;
+ joininfo->inactive = false;
+ this_rel->joininfo = lcons(joininfo, this_rel->joininfo);
+ }
+ return (joininfo);
}
-/*
+/*
* other-join-clause-var--
- * Determines whether a var node is contained within a joinclause
- * of the form(op var var).
- *
+ * Determines whether a var node is contained within a joinclause
+ * of the form(op var var).
+ *
* Returns the other var node in the joinclause if it is, nil if not.
- *
+ *
*/
-Var *
-other_join_clause_var(Var *var, Expr *clause)
+Var *
+other_join_clause_var(Var * var, Expr * clause)
{
- Var *retval;
- Var *l, *r;
+ Var *retval;
+ Var *l,
+ *r;
- retval = (Var*) NULL;
+ retval = (Var *) NULL;
- if( var != NULL && join_clause_p((Node*)clause)) {
- l = (Var *) get_leftop(clause);
- r = (Var *) get_rightop(clause);
+ if (var != NULL && join_clause_p((Node *) clause))
+ {
+ l = (Var *) get_leftop(clause);
+ r = (Var *) get_rightop(clause);
- if(var_equal(var, l)) {
- retval = r;
- } else if(var_equal(var, r)) {
- retval = l;
- }
- }
+ if (var_equal(var, l))
+ {
+ retval = r;
+ }
+ else if (var_equal(var, r))
+ {
+ retval = l;
+ }
+ }
- return(retval);
+ return (retval);
}
diff --git a/src/backend/optimizer/util/keys.c b/src/backend/optimizer/util/keys.c
index 4296deb7e98..0c3a3569eb5 100644
--- a/src/backend/optimizer/util/keys.c
+++ b/src/backend/optimizer/util/keys.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* keys.c--
- * Key manipulation routines
+ * Key manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.2 1997/08/19 21:32:03 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.3 1997/09/07 04:44:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,173 +22,180 @@
#include "optimizer/tlist.h"
-static Expr *matching2_tlvar(int var, List *tlist, bool (*test)());
-static bool equal_indexkey_var(int index_key, Var *var);
+static Expr *matching2_tlvar(int var, List * tlist, bool(*test) ());
+static bool equal_indexkey_var(int index_key, Var * var);
-/*
+/*
* 1. index key
- * one of:
- * attnum
- * (attnum arrayindex)
+ * one of:
+ * attnum
+ * (attnum arrayindex)
* 2. path key
- * (subkey1 ... subkeyN)
- * where subkeyI is a var node
- * note that the 'Keys field is a list of these
+ * (subkey1 ... subkeyN)
+ * where subkeyI is a var node
+ * note that the 'Keys field is a list of these
* 3. join key
- * (outer-subkey inner-subkey)
- * where each subkey is a var node
+ * (outer-subkey inner-subkey)
+ * where each subkey is a var node
* 4. sort key
- * one of:
- * SortKey node
- * number
- * nil
- * (may also refer to the 'SortKey field of a SortKey node,
- * which looks exactly like an index key)
- *
+ * one of:
+ * SortKey node
+ * number
+ * nil
+ * (may also refer to the 'SortKey field of a SortKey node,
+ * which looks exactly like an index key)
+ *
*/
-/*
+/*
* match-indexkey-operand--
- * Returns t iff an index key 'index-key' matches the given clause
- * operand.
- *
+ * Returns t iff an index key 'index-key' matches the given clause
+ * operand.
+ *
*/
bool
-match_indexkey_operand(int indexkey, Var *operand, Rel *rel)
+match_indexkey_operand(int indexkey, Var * operand, Rel * rel)
{
- if (IsA (operand,Var) &&
- (lfirsti(rel->relids) == operand->varno) &&
- equal_indexkey_var(indexkey,operand))
- return(true);
- else
- return(false);
+ if (IsA(operand, Var) &&
+ (lfirsti(rel->relids) == operand->varno) &&
+ equal_indexkey_var(indexkey, operand))
+ return (true);
+ else
+ return (false);
}
-/*
+/*
* equal_indexkey_var--
- * Returns t iff an index key 'index-key' matches the corresponding
- * fields of var node 'var'.
- *
+ * Returns t iff an index key 'index-key' matches the corresponding
+ * fields of var node 'var'.
+ *
*/
-static bool
-equal_indexkey_var(int index_key, Var *var)
+static bool
+equal_indexkey_var(int index_key, Var * var)
{
- if (index_key == var->varattno)
- return(true);
- else
- return(false);
+ if (index_key == var->varattno)
+ return (true);
+ else
+ return (false);
}
-/*
+/*
* extract-subkey--
- * Returns the subkey in a join key corresponding to the outer or inner
- * lelation.
- *
+ * Returns the subkey in a join key corresponding to the outer or inner
+ * lelation.
+ *
*/
-Var *
-extract_subkey(JoinKey *jk, int which_subkey)
+Var *
+extract_subkey(JoinKey * jk, int which_subkey)
{
- Var *retval;
-
- switch (which_subkey) {
- case OUTER:
- retval = jk->outer;
- break;
- case INNER:
- retval = jk->inner;
- break;
- default: /* do nothing */
- elog(DEBUG,"extract_subkey with neither INNER or OUTER");
- retval = NULL;
- }
- return(retval);
+ Var *retval;
+
+ switch (which_subkey)
+ {
+ case OUTER:
+ retval = jk->outer;
+ break;
+ case INNER:
+ retval = jk->inner;
+ break;
+ default: /* do nothing */
+ elog(DEBUG, "extract_subkey with neither INNER or OUTER");
+ retval = NULL;
+ }
+ return (retval);
}
-/*
+/*
* samekeys--
- * Returns t iff two sets of path keys are equivalent. They are
- * equivalent if the first subkey (var node) within each sublist of
- * list 'keys1' is contained within the corresponding sublist of 'keys2'.
- *
- * XXX It isn't necessary to check that each sublist exactly contain
- * the same elements because if the routine that built these
- * sublists together is correct, having one element in common
- * implies having all elements in common.
- *
+ * Returns t iff two sets of path keys are equivalent. They are
+ * equivalent if the first subkey (var node) within each sublist of
+ * list 'keys1' is contained within the corresponding sublist of 'keys2'.
+ *
+ * XXX It isn't necessary to check that each sublist exactly contain
+ * the same elements because if the routine that built these
+ * sublists together is correct, having one element in common
+ * implies having all elements in common.
+ *
*/
bool
-samekeys(List *keys1, List *keys2)
+samekeys(List * keys1, List * keys2)
{
- bool allmember = true;
- List *key1, *key2;
-
- for(key1=keys1,key2=keys2 ; key1 != NIL && key2 !=NIL ;
- key1=lnext(key1), key2=lnext(key2))
- if (!member(lfirst(key1), lfirst(key2)))
- allmember = false;
-
- if ( (length (keys2) >= length (keys1)) && allmember)
- return(true);
- else
- return(false);
+ bool allmember = true;
+ List *key1,
+ *key2;
+
+ for (key1 = keys1, key2 = keys2; key1 != NIL && key2 != NIL;
+ key1 = lnext(key1), key2 = lnext(key2))
+ if (!member(lfirst(key1), lfirst(key2)))
+ allmember = false;
+
+ if ((length(keys2) >= length(keys1)) && allmember)
+ return (true);
+ else
+ return (false);
}
-/*
+/*
* collect-index-pathkeys--
- * Creates a list of subkeys by retrieving var nodes corresponding to
- * each index key in 'index-keys' from the relation's target list
- * 'tlist'. If the key is not in the target list, the key is irrelevant
- * and is thrown away. The returned subkey list is of the form:
- * ((var1) (var2) ... (varn))
- *
+ * Creates a list of subkeys by retrieving var nodes corresponding to
+ * each index key in 'index-keys' from the relation's target list
+ * 'tlist'. If the key is not in the target list, the key is irrelevant
+ * and is thrown away. The returned subkey list is of the form:
+ * ((var1) (var2) ... (varn))
+ *
* 'index-keys' is a list of index keys
* 'tlist' is a relation target list
- *
+ *
* Returns the list of cons'd subkeys.
- *
+ *
*/
/* This function is identical to matching_tlvar and tlistentry_member.
* They should be merged.
*/
-static Expr *
-matching2_tlvar(int var, List *tlist, bool (*test)())
+static Expr *
+matching2_tlvar(int var, List * tlist, bool(*test) ())
{
- TargetEntry *tlentry = NULL;
-
- if (var) {
- List *temp;
- foreach (temp,tlist) {
- if ((*test)(var, get_expr(lfirst(temp)))) {
- tlentry = lfirst(temp);
- break;
- }
+ TargetEntry *tlentry = NULL;
+
+ if (var)
+ {
+ List *temp;
+
+ foreach(temp, tlist)
+ {
+ if ((*test) (var, get_expr(lfirst(temp))))
+ {
+ tlentry = lfirst(temp);
+ break;
+ }
+ }
}
- }
- if (tlentry)
- return((Expr*)get_expr(tlentry));
- else
- return((Expr*)NULL);
+ if (tlentry)
+ return ((Expr *) get_expr(tlentry));
+ else
+ return ((Expr *) NULL);
}
-List *
-collect_index_pathkeys(int *index_keys, List *tlist)
+List *
+collect_index_pathkeys(int *index_keys, List * tlist)
{
- List *retval = NIL;
-
- Assert (index_keys != NULL);
-
- while(index_keys[0] != 0) {
- Expr *mvar;
- mvar = matching2_tlvar(index_keys[0],
- tlist,
- equal_indexkey_var);
- if (mvar)
- retval = nconc(retval,lcons(lcons(mvar,NIL),
- NIL));
- index_keys++;
- }
- return(retval);
-}
+ List *retval = NIL;
+
+ Assert(index_keys != NULL);
+
+ while (index_keys[0] != 0)
+ {
+ Expr *mvar;
+ mvar = matching2_tlvar(index_keys[0],
+ tlist,
+ equal_indexkey_var);
+ if (mvar)
+ retval = nconc(retval, lcons(lcons(mvar, NIL),
+ NIL));
+ index_keys++;
+ }
+ return (retval);
+}
diff --git a/src/backend/optimizer/util/ordering.c b/src/backend/optimizer/util/ordering.c
index 40699e81e0b..504d48bdce5 100644
--- a/src/backend/optimizer/util/ordering.c
+++ b/src/backend/optimizer/util/ordering.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* ordering.c--
- * Routines to manipulate and compare merge and path orderings
+ * Routines to manipulate and compare merge and path orderings
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/ordering.c,v 1.3 1997/08/19 21:32:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/ordering.c,v 1.4 1997/09/07 04:44:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,81 +18,88 @@
#include "optimizer/internal.h"
#include "optimizer/ordering.h"
-static bool equal_sortops_order(Oid *ordering1, Oid *ordering2);
+static bool equal_sortops_order(Oid * ordering1, Oid * ordering2);
-/*
+/*
* equal-path-path-ordering--
- * Returns t iff two path orderings are equal.
- *
+ * Returns t iff two path orderings are equal.
+ *
*/
bool
-equal_path_path_ordering(PathOrder *path_ordering1,
- PathOrder *path_ordering2)
+equal_path_path_ordering(PathOrder * path_ordering1,
+ PathOrder * path_ordering2)
{
- if (path_ordering1 == path_ordering2)
- return true;
-
- if (!path_ordering1 || !path_ordering2)
- return false;
-
- if (path_ordering1->ordtype == MERGE_ORDER &&
- path_ordering2->ordtype == MERGE_ORDER) {
-
- return equal(path_ordering1->ord.merge, path_ordering2->ord.merge);
-
- } else if (path_ordering1->ordtype == SORTOP_ORDER &&
- path_ordering2->ordtype == SORTOP_ORDER) {
-
- return
- (equal_sortops_order(path_ordering1->ord.sortop,
- path_ordering2->ord.sortop));
- } else if (path_ordering1->ordtype == MERGE_ORDER &&
- path_ordering2->ordtype == SORTOP_ORDER) {
-
- return (path_ordering2->ord.sortop &&
- (path_ordering1->ord.merge->left_operator ==
- path_ordering2->ord.sortop[0]));
- } else {
-
- return (path_ordering1->ord.sortop &&
- (path_ordering1->ord.sortop[0] ==
- path_ordering2->ord.merge->left_operator));
- }
+ if (path_ordering1 == path_ordering2)
+ return true;
+
+ if (!path_ordering1 || !path_ordering2)
+ return false;
+
+ if (path_ordering1->ordtype == MERGE_ORDER &&
+ path_ordering2->ordtype == MERGE_ORDER)
+ {
+
+ return equal(path_ordering1->ord.merge, path_ordering2->ord.merge);
+
+ }
+ else if (path_ordering1->ordtype == SORTOP_ORDER &&
+ path_ordering2->ordtype == SORTOP_ORDER)
+ {
+
+ return
+ (equal_sortops_order(path_ordering1->ord.sortop,
+ path_ordering2->ord.sortop));
+ }
+ else if (path_ordering1->ordtype == MERGE_ORDER &&
+ path_ordering2->ordtype == SORTOP_ORDER)
+ {
+
+ return (path_ordering2->ord.sortop &&
+ (path_ordering1->ord.merge->left_operator ==
+ path_ordering2->ord.sortop[0]));
+ }
+ else
+ {
+
+ return (path_ordering1->ord.sortop &&
+ (path_ordering1->ord.sortop[0] ==
+ path_ordering2->ord.merge->left_operator));
+ }
}
-/*
+/*
* equal-path-merge-ordering--
- * Returns t iff a path ordering is usable for ordering a merge join.
+ * Returns t iff a path ordering is usable for ordering a merge join.
*
* XXX Presently, this means that the first sortop of the path matches
- * either of the merge sortops. Is there a "right" and "wrong"
- * sortop to match?
- *
+ * either of the merge sortops. Is there a "right" and "wrong"
+ * sortop to match?
+ *
*/
bool
-equal_path_merge_ordering(Oid *path_ordering,
- MergeOrder *merge_ordering)
+equal_path_merge_ordering(Oid * path_ordering,
+ MergeOrder * merge_ordering)
{
- if (path_ordering == NULL || merge_ordering == NULL)
- return(false);
-
- if (path_ordering[0] == merge_ordering->left_operator ||
- path_ordering[0] == merge_ordering->right_operator)
- return(true);
- else
- return(false);
+ if (path_ordering == NULL || merge_ordering == NULL)
+ return (false);
+
+ if (path_ordering[0] == merge_ordering->left_operator ||
+ path_ordering[0] == merge_ordering->right_operator)
+ return (true);
+ else
+ return (false);
}
-/*
+/*
* equal-merge-merge-ordering--
- * Returns t iff two merge orderings are equal.
- *
+ * Returns t iff two merge orderings are equal.
+ *
*/
bool
-equal_merge_merge_ordering(MergeOrder *merge_ordering1,
- MergeOrder *merge_ordering2)
+equal_merge_merge_ordering(MergeOrder * merge_ordering1,
+ MergeOrder * merge_ordering2)
{
- return (equal(merge_ordering1, merge_ordering2));
+ return (equal(merge_ordering1, merge_ordering2));
}
/*****************************************************************************
@@ -101,21 +108,22 @@ equal_merge_merge_ordering(MergeOrder *merge_ordering1,
/*
* equal_sort_ops_order -
- * Returns true iff the sort operators are in the same order.
+ * Returns true iff the sort operators are in the same order.
*/
-static bool
-equal_sortops_order(Oid *ordering1, Oid *ordering2)
+static bool
+equal_sortops_order(Oid * ordering1, Oid * ordering2)
{
- int i = 0;
-
- if (ordering1 == NULL || ordering2 == NULL)
- return (ordering1==ordering2);
-
- while (ordering1[i]!=0 && ordering2[i]!=0) {
- if (ordering1[i] != ordering2[i])
- break;
- i++;
- }
-
- return (ordering1[i]==0 && ordering2[i]==0);
+ int i = 0;
+
+ if (ordering1 == NULL || ordering2 == NULL)
+ return (ordering1 == ordering2);
+
+ while (ordering1[i] != 0 && ordering2[i] != 0)
+ {
+ if (ordering1[i] != ordering2[i])
+ break;
+ i++;
+ }
+
+ return (ordering1[i] == 0 && ordering2[i] == 0);
}
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index d79788b0e6e..6b37d2f36d4 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* pathnode.c--
- * Routines to manipulate pathlists and create path nodes
+ * Routines to manipulate pathlists and create path nodes
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.3 1997/09/05 18:10:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.4 1997/09/07 04:44:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,418 +27,459 @@
#include "optimizer/xfunc.h"
#include "optimizer/ordering.h"
-#include "parser/parsetree.h" /* for getrelid() */
+#include "parser/parsetree.h" /* for getrelid() */
-static Path *better_path(Path *new_path, List *unique_paths, bool *noOther);
+static Path *better_path(Path * new_path, List * unique_paths, bool * noOther);
/*****************************************************************************
- * MISC. PATH UTILITIES
+ * MISC. PATH UTILITIES
*****************************************************************************/
-/*
+/*
* path-is-cheaper--
- * Returns t iff 'path1' is cheaper than 'path2'.
- *
+ * Returns t iff 'path1' is cheaper than 'path2'.
+ *
*/
bool
-path_is_cheaper(Path *path1, Path *path2)
+path_is_cheaper(Path * path1, Path * path2)
{
- Cost cost1 = path1->path_cost;
- Cost cost2 = path2->path_cost;
+ Cost cost1 = path1->path_cost;
+ Cost cost2 = path2->path_cost;
- return((bool)(cost1 < cost2));
+ return ((bool) (cost1 < cost2));
}
-/*
+/*
* set_cheapest--
- * Finds the minimum cost path from among a relation's paths.
- *
+ * Finds the minimum cost path from among a relation's paths.
+ *
* 'parent-rel' is the parent relation
* 'pathlist' is a list of path nodes corresponding to 'parent-rel'
- *
- * Returns and sets the relation entry field with the pathnode that
+ *
+ * Returns and sets the relation entry field with the pathnode that
* is minimum.
- *
+ *
*/
-Path *
-set_cheapest(Rel *parent_rel, List *pathlist)
+Path *
+set_cheapest(Rel * parent_rel, List * pathlist)
{
- List *p;
- Path *cheapest_so_far;
+ List *p;
+ Path *cheapest_so_far;
- Assert(pathlist!=NIL);
- Assert(IsA(parent_rel,Rel));
+ Assert(pathlist != NIL);
+ Assert(IsA(parent_rel, Rel));
- cheapest_so_far = (Path*)lfirst(pathlist);
+ cheapest_so_far = (Path *) lfirst(pathlist);
- foreach (p, lnext(pathlist)) {
- Path *path = (Path*)lfirst(p);
+ foreach(p, lnext(pathlist))
+ {
+ Path *path = (Path *) lfirst(p);
- if (path_is_cheaper(path, cheapest_so_far)) {
- cheapest_so_far = path;
+ if (path_is_cheaper(path, cheapest_so_far))
+ {
+ cheapest_so_far = path;
+ }
}
- }
- parent_rel->cheapestpath = cheapest_so_far;
+ parent_rel->cheapestpath = cheapest_so_far;
- return(cheapest_so_far);
+ return (cheapest_so_far);
}
-/*
+/*
* add_pathlist--
- * For each path in the list 'new-paths', add to the list 'unique-paths'
- * only those paths that are unique (i.e., unique ordering and ordering
- * keys). Should a conflict arise, the more expensive path is thrown out,
- * thereby pruning the plan space. But we don't prune if xfunc
- * told us not to.
- *
+ * For each path in the list 'new-paths', add to the list 'unique-paths'
+ * only those paths that are unique (i.e., unique ordering and ordering
+ * keys). Should a conflict arise, the more expensive path is thrown out,
+ * thereby pruning the plan space. But we don't prune if xfunc
+ * told us not to.
+ *
* 'parent-rel' is the relation entry to which these paths correspond.
- *
+ *
* Returns the list of unique pathnodes.
- *
+ *
*/
-List *
-add_pathlist(Rel *parent_rel, List *unique_paths, List *new_paths)
+List *
+add_pathlist(Rel * parent_rel, List * unique_paths, List * new_paths)
{
- List *x;
- Path *new_path;
- Path *old_path;
- bool noOther;
-
- foreach (x, new_paths) {
- new_path = (Path*)lfirst(x);
- if (member(new_path, unique_paths))
- continue;
- old_path = better_path(new_path,unique_paths,&noOther);
-
- if (noOther) {
- /* Is a brand new path. */
- new_path->parent = parent_rel;
- unique_paths = lcons(new_path, unique_paths);
- } else if (old_path==NULL) {
- ; /* do nothing if path is not cheaper */
- } else if (old_path != NULL) { /* (IsA(old_path,Path)) { */
- new_path->parent = parent_rel;
- if (!parent_rel->pruneable) {
- unique_paths = lcons(new_path, unique_paths);
- }else
- unique_paths = lcons(new_path,
- LispRemove(old_path,unique_paths));
+ List *x;
+ Path *new_path;
+ Path *old_path;
+ bool noOther;
+
+ foreach(x, new_paths)
+ {
+ new_path = (Path *) lfirst(x);
+ if (member(new_path, unique_paths))
+ continue;
+ old_path = better_path(new_path, unique_paths, &noOther);
+
+ if (noOther)
+ {
+ /* Is a brand new path. */
+ new_path->parent = parent_rel;
+ unique_paths = lcons(new_path, unique_paths);
+ }
+ else if (old_path == NULL)
+ {
+ ; /* do nothing if path is not cheaper */
+ }
+ else if (old_path != NULL)
+ { /* (IsA(old_path,Path)) { */
+ new_path->parent = parent_rel;
+ if (!parent_rel->pruneable)
+ {
+ unique_paths = lcons(new_path, unique_paths);
+ }
+ else
+ unique_paths = lcons(new_path,
+ LispRemove(old_path, unique_paths));
+ }
}
- }
- return(unique_paths);
+ return (unique_paths);
}
-/*
+/*
* better_path--
- * Determines whether 'new-path' has the same ordering and keys as some
- * path in the list 'unique-paths'. If there is a redundant path,
- * eliminate the more expensive path.
- *
+ * Determines whether 'new-path' has the same ordering and keys as some
+ * path in the list 'unique-paths'. If there is a redundant path,
+ * eliminate the more expensive path.
+ *
* Returns:
- * The old path - if 'new-path' matches some path in 'unique-paths' and is
- * cheaper
- * nil - if 'new-path' matches but isn't cheaper
- * t - if there is no path in the list with the same ordering and keys
- *
+ * The old path - if 'new-path' matches some path in 'unique-paths' and is
+ * cheaper
+ * nil - if 'new-path' matches but isn't cheaper
+ * t - if there is no path in the list with the same ordering and keys
+ *
*/
-static Path *
-better_path(Path *new_path, List *unique_paths, bool *noOther)
+static Path *
+better_path(Path * new_path, List * unique_paths, bool * noOther)
{
- Path *old_path = (Path*)NULL;
- Path *path = (Path*)NULL;
- List *temp = NIL;
- Path *retval = NULL;
-
- /* XXX - added the following two lines which weren't int
- * the lisp planner, but otherwise, doesn't seem to work
- * for the case where new_path is 'nil
- */
- foreach (temp,unique_paths) {
- path = (Path*) lfirst(temp);
-
- if ((equal_path_path_ordering(&new_path->p_ordering,
- &path->p_ordering) &&
- samekeys(new_path->keys, path->keys))) {
- old_path = path;
- break;
+ Path *old_path = (Path *) NULL;
+ Path *path = (Path *) NULL;
+ List *temp = NIL;
+ Path *retval = NULL;
+
+ /*
+ * XXX - added the following two lines which weren't int the lisp
+ * planner, but otherwise, doesn't seem to work for the case where
+ * new_path is 'nil
+ */
+ foreach(temp, unique_paths)
+ {
+ path = (Path *) lfirst(temp);
+
+ if ((equal_path_path_ordering(&new_path->p_ordering,
+ &path->p_ordering) &&
+ samekeys(new_path->keys, path->keys)))
+ {
+ old_path = path;
+ break;
+ }
}
- }
-
- if (old_path==NULL) {
- *noOther = true;
- } else {
- *noOther = false;
- if (path_is_cheaper(new_path,old_path)) {
- retval = old_path;
+
+ if (old_path == NULL)
+ {
+ *noOther = true;
+ }
+ else
+ {
+ *noOther = false;
+ if (path_is_cheaper(new_path, old_path))
+ {
+ retval = old_path;
+ }
}
- }
-
- return(retval);
+
+ return (retval);
}
/*****************************************************************************
- * PATH NODE CREATION ROUTINES
+ * PATH NODE CREATION ROUTINES
*****************************************************************************/
-/*
+/*
* create_seqscan_path--
- * Creates a path corresponding to a sequential scan, returning the
- * pathnode.
- *
+ * Creates a path corresponding to a sequential scan, returning the
+ * pathnode.
+ *
*/
-Path *
-create_seqscan_path(Rel *rel)
+Path *
+create_seqscan_path(Rel * rel)
{
- int relid=0;
-
- Path *pathnode = makeNode(Path);
-
- pathnode->pathtype = T_SeqScan;
- pathnode->parent = rel;
- pathnode->path_cost = 0.0;
- pathnode->p_ordering.ordtype = SORTOP_ORDER;
- pathnode->p_ordering.ord.sortop = NULL;
- pathnode->keys = NIL;
- /* copy clauseinfo list into path for expensive function processing
- * -- JMH, 7/7/92
- */
- pathnode->locclauseinfo=
- (List*)copyObject((Node*)rel->clauseinfo);
-
- if (rel->relids !=NULL)
- relid = lfirsti(rel->relids);
-
- pathnode->path_cost = cost_seqscan (relid,
- rel->pages, rel->tuples);
- /* add in expensive functions cost! -- JMH, 7/7/92 */
+ int relid = 0;
+
+ Path *pathnode = makeNode(Path);
+
+ pathnode->pathtype = T_SeqScan;
+ pathnode->parent = rel;
+ pathnode->path_cost = 0.0;
+ pathnode->p_ordering.ordtype = SORTOP_ORDER;
+ pathnode->p_ordering.ord.sortop = NULL;
+ pathnode->keys = NIL;
+
+ /*
+ * copy clauseinfo list into path for expensive function processing --
+ * JMH, 7/7/92
+ */
+ pathnode->locclauseinfo =
+ (List *) copyObject((Node *) rel->clauseinfo);
+
+ if (rel->relids != NULL)
+ relid = lfirsti(rel->relids);
+
+ pathnode->path_cost = cost_seqscan(relid,
+ rel->pages, rel->tuples);
+ /* add in expensive functions cost! -- JMH, 7/7/92 */
#if 0
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost +=
- xfunc_get_path_cost(pathnode);
- }
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost +=
+ xfunc_get_path_cost(pathnode);
+ }
#endif
- return (pathnode);
+ return (pathnode);
}
-/*
+/*
* create_index_path--
- * Creates a single path node for an index scan.
- *
+ * Creates a single path node for an index scan.
+ *
* 'rel' is the parent rel
* 'index' is the pathnode for the index on 'rel'
* 'restriction-clauses' is a list of restriction clause nodes.
* 'is-join-scan' is a flag indicating whether or not the index is being
- * considered because of its sort order.
- *
+ * considered because of its sort order.
+ *
* Returns the new path node.
- *
+ *
*/
-IndexPath *
-create_index_path(Query *root,
- Rel *rel,
- Rel *index,
- List *restriction_clauses,
- bool is_join_scan)
+IndexPath *
+create_index_path(Query * root,
+ Rel * rel,
+ Rel * index,
+ List * restriction_clauses,
+ bool is_join_scan)
{
- IndexPath *pathnode = makeNode(IndexPath);
-
- pathnode->path.pathtype = T_IndexScan;
- pathnode->path.parent = rel;
- pathnode->path.p_ordering.ordtype = SORTOP_ORDER;
- pathnode->path.p_ordering.ord.sortop = index->ordering;
-
- pathnode->indexid = index->relids;
- pathnode->indexkeys = index->indexkeys;
- pathnode->indexqual = NIL;
-
- /* copy clauseinfo list into path for expensive function processing
- * -- JMH, 7/7/92
- */
- pathnode->path.locclauseinfo =
- set_difference((List*) copyObject((Node*)rel->clauseinfo),
- (List*) restriction_clauses);
-
- /*
- * The index must have an ordering for the path to have (ordering) keys,
- * and vice versa.
- */
- if (pathnode->path.p_ordering.ord.sortop) {
- pathnode->path.keys = collect_index_pathkeys(index->indexkeys,
- rel->targetlist);
+ IndexPath *pathnode = makeNode(IndexPath);
+
+ pathnode->path.pathtype = T_IndexScan;
+ pathnode->path.parent = rel;
+ pathnode->path.p_ordering.ordtype = SORTOP_ORDER;
+ pathnode->path.p_ordering.ord.sortop = index->ordering;
+
+ pathnode->indexid = index->relids;
+ pathnode->indexkeys = index->indexkeys;
+ pathnode->indexqual = NIL;
+
/*
- * Check that the keys haven't 'disappeared', since they may
- * no longer be in the target list (i.e., index keys that are not
- * relevant to the scan are not applied to the scan path node,
- * so if no index keys were found, we can't order the path).
+ * copy clauseinfo list into path for expensive function processing --
+ * JMH, 7/7/92
*/
- if (pathnode->path.keys==NULL) {
- pathnode->path.p_ordering.ord.sortop = NULL;
- }
- } else {
- pathnode->path.keys = NULL;
- }
+ pathnode->path.locclauseinfo =
+ set_difference((List *) copyObject((Node *) rel->clauseinfo),
+ (List *) restriction_clauses);
- if (is_join_scan || restriction_clauses==NULL) {
/*
- * Indices used for joins or sorting result nodes don't
- * restrict the result at all, they simply order it,
- * so compute the scan cost
- * accordingly -- use a selectivity of 1.0.
+ * The index must have an ordering for the path to have (ordering)
+ * keys, and vice versa.
*/
-/* is the statement above really true? what about IndexScan as the
+ if (pathnode->path.p_ordering.ord.sortop)
+ {
+ pathnode->path.keys = collect_index_pathkeys(index->indexkeys,
+ rel->targetlist);
+
+ /*
+ * Check that the keys haven't 'disappeared', since they may no
+ * longer be in the target list (i.e., index keys that are not
+ * relevant to the scan are not applied to the scan path node, so
+ * if no index keys were found, we can't order the path).
+ */
+ if (pathnode->path.keys == NULL)
+ {
+ pathnode->path.p_ordering.ord.sortop = NULL;
+ }
+ }
+ else
+ {
+ pathnode->path.keys = NULL;
+ }
+
+ if (is_join_scan || restriction_clauses == NULL)
+ {
+
+ /*
+ * Indices used for joins or sorting result nodes don't restrict
+ * the result at all, they simply order it, so compute the scan
+ * cost accordingly -- use a selectivity of 1.0.
+ */
+/* is the statement above really true? what about IndexScan as the
inner of a join? */
- pathnode->path.path_cost =
- cost_index (lfirsti(index->relids),
- index->pages,
- 1.0,
- rel->pages,
- rel->tuples,
- index->pages,
- index->tuples,
- false);
- /* add in expensive functions cost! -- JMH, 7/7/92 */
+ pathnode->path.path_cost =
+ cost_index(lfirsti(index->relids),
+ index->pages,
+ 1.0,
+ rel->pages,
+ rel->tuples,
+ index->pages,
+ index->tuples,
+ false);
+ /* add in expensive functions cost! -- JMH, 7/7/92 */
#if 0
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost =
- (pathnode->path_cost +
- xfunc_get_path_cost((Path*)pathnode));
- }
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost =
+ (pathnode->path_cost +
+ xfunc_get_path_cost((Path *) pathnode));
+ }
#endif
- } else {
- /*
- * Compute scan cost for the case when 'index' is used with a
- * restriction clause.
- */
- List *attnos;
- List *values;
- List *flags;
- float npages;
- float selec;
- Cost clausesel;
-
- get_relattvals(restriction_clauses,
- &attnos,
- &values,
- &flags);
- index_selectivity(lfirsti(index->relids),
- index->classlist,
- get_opnos(restriction_clauses),
- getrelid(lfirsti(rel->relids),
- root->rtable),
- attnos,
- values,
- flags,
- length(restriction_clauses),
- &npages,
- &selec);
- /* each clause gets an equal selectivity */
- clausesel =
- pow(selec,
- 1.0 / (double) length(restriction_clauses));
-
- pathnode->indexqual = restriction_clauses;
- pathnode->path.path_cost =
- cost_index (lfirsti(index->relids),
- (int)npages,
- selec,
- rel->pages,
- rel->tuples,
- index->pages,
- index->tuples,
- false);
+ }
+ else
+ {
+
+ /*
+ * Compute scan cost for the case when 'index' is used with a
+ * restriction clause.
+ */
+ List *attnos;
+ List *values;
+ List *flags;
+ float npages;
+ float selec;
+ Cost clausesel;
+
+ get_relattvals(restriction_clauses,
+ &attnos,
+ &values,
+ &flags);
+ index_selectivity(lfirsti(index->relids),
+ index->classlist,
+ get_opnos(restriction_clauses),
+ getrelid(lfirsti(rel->relids),
+ root->rtable),
+ attnos,
+ values,
+ flags,
+ length(restriction_clauses),
+ &npages,
+ &selec);
+ /* each clause gets an equal selectivity */
+ clausesel =
+ pow(selec,
+ 1.0 / (double) length(restriction_clauses));
+
+ pathnode->indexqual = restriction_clauses;
+ pathnode->path.path_cost =
+ cost_index(lfirsti(index->relids),
+ (int) npages,
+ selec,
+ rel->pages,
+ rel->tuples,
+ index->pages,
+ index->tuples,
+ false);
#if 0
- /* add in expensive functions cost! -- JMH, 7/7/92 */
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost +=
- xfunc_get_path_cost((Path*)pathnode);
- }
+ /* add in expensive functions cost! -- JMH, 7/7/92 */
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost +=
+ xfunc_get_path_cost((Path *) pathnode);
+ }
#endif
- /* Set selectivities of clauses used with index to the selectivity
- * of this index, subdividing the selectivity equally over each of
- * the clauses.
- */
- /* XXX Can this divide the selectivities in a better way? */
- set_clause_selectivities(restriction_clauses, clausesel);
- }
- return(pathnode);
+ /*
+ * Set selectivities of clauses used with index to the selectivity
+ * of this index, subdividing the selectivity equally over each of
+ * the clauses.
+ */
+
+ /* XXX Can this divide the selectivities in a better way? */
+ set_clause_selectivities(restriction_clauses, clausesel);
+ }
+ return (pathnode);
}
-/*
+/*
* create_nestloop_path--
- * Creates a pathnode corresponding to a nestloop join between two
- * relations.
- *
+ * Creates a pathnode corresponding to a nestloop join between two
+ * relations.
+ *
* 'joinrel' is the join relation.
* 'outer_rel' is the outer join relation
* 'outer_path' is the outer join path.
* 'inner_path' is the inner join path.
* 'keys' are the keys of the path
- *
+ *
* Returns the resulting path node.
- *
+ *
*/
-JoinPath *
-create_nestloop_path(Rel *joinrel,
- Rel *outer_rel,
- Path *outer_path,
- Path *inner_path,
- List *keys)
+JoinPath *
+create_nestloop_path(Rel * joinrel,
+ Rel * outer_rel,
+ Path * outer_path,
+ Path * inner_path,
+ List * keys)
{
- JoinPath *pathnode = makeNode(JoinPath);
-
- pathnode->path.pathtype = T_NestLoop;
- pathnode->path.parent = joinrel;
- pathnode->outerjoinpath = outer_path;
- pathnode->innerjoinpath = inner_path;
- pathnode->pathclauseinfo = joinrel->clauseinfo;
- pathnode->path.keys = keys;
- pathnode->path.joinid = NIL;
- pathnode->path.outerjoincost = (Cost)0.0;
- pathnode->path.locclauseinfo = NIL;
-
- if (keys) {
- pathnode->path.p_ordering.ordtype =
- outer_path->p_ordering.ordtype;
- if (outer_path->p_ordering.ordtype == SORTOP_ORDER) {
- pathnode->path.p_ordering.ord.sortop =
- outer_path->p_ordering.ord.sortop;
- } else {
- pathnode->path.p_ordering.ord.merge =
- outer_path->p_ordering.ord.merge;
+ JoinPath *pathnode = makeNode(JoinPath);
+
+ pathnode->path.pathtype = T_NestLoop;
+ pathnode->path.parent = joinrel;
+ pathnode->outerjoinpath = outer_path;
+ pathnode->innerjoinpath = inner_path;
+ pathnode->pathclauseinfo = joinrel->clauseinfo;
+ pathnode->path.keys = keys;
+ pathnode->path.joinid = NIL;
+ pathnode->path.outerjoincost = (Cost) 0.0;
+ pathnode->path.locclauseinfo = NIL;
+
+ if (keys)
+ {
+ pathnode->path.p_ordering.ordtype =
+ outer_path->p_ordering.ordtype;
+ if (outer_path->p_ordering.ordtype == SORTOP_ORDER)
+ {
+ pathnode->path.p_ordering.ord.sortop =
+ outer_path->p_ordering.ord.sortop;
+ }
+ else
+ {
+ pathnode->path.p_ordering.ord.merge =
+ outer_path->p_ordering.ord.merge;
+ }
}
- } else {
- pathnode->path.p_ordering.ordtype = SORTOP_ORDER;
- pathnode->path.p_ordering.ord.sortop = NULL;
- }
-
- pathnode->path.path_cost =
- cost_nestloop(outer_path->path_cost,
- inner_path->path_cost,
- outer_rel->size,
- inner_path->parent->size,
- page_size(outer_rel->size,
- outer_rel->width),
- IsA(inner_path,IndexPath));
- /* add in expensive function costs -- JMH 7/7/92 */
+ else
+ {
+ pathnode->path.p_ordering.ordtype = SORTOP_ORDER;
+ pathnode->path.p_ordering.ord.sortop = NULL;
+ }
+
+ pathnode->path.path_cost =
+ cost_nestloop(outer_path->path_cost,
+ inner_path->path_cost,
+ outer_rel->size,
+ inner_path->parent->size,
+ page_size(outer_rel->size,
+ outer_rel->width),
+ IsA(inner_path, IndexPath));
+ /* add in expensive function costs -- JMH 7/7/92 */
#if 0
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost += xfunc_get_path_cost((Path*)pathnode);
- }
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost += xfunc_get_path_cost((Path *) pathnode);
+ }
#endif
- return(pathnode);
+ return (pathnode);
}
-/*
+/*
* create_mergesort_path--
- * Creates a pathnode corresponding to a mergesort join between
- * two relations
- *
+ * Creates a pathnode corresponding to a mergesort join between
+ * two relations
+ *
* 'joinrel' is the join relation
* 'outersize' is the number of tuples in the outer relation
* 'innersize' is the number of tuples in the inner relation
@@ -451,59 +492,60 @@ create_nestloop_path(Rel *joinrel,
* 'mergeclauses' are the applicable join/restriction clauses
* 'outersortkeys' are the sort varkeys for the outer relation
* 'innersortkeys' are the sort varkeys for the inner relation
- *
+ *
*/
-MergePath *
-create_mergesort_path(Rel *joinrel,
- int outersize,
- int innersize,
- int outerwidth,
- int innerwidth,
- Path *outer_path,
- Path *inner_path,
- List *keys,
- MergeOrder *order,
- List *mergeclauses,
- List *outersortkeys,
- List *innersortkeys)
+MergePath *
+create_mergesort_path(Rel * joinrel,
+ int outersize,
+ int innersize,
+ int outerwidth,
+ int innerwidth,
+ Path * outer_path,
+ Path * inner_path,
+ List * keys,
+ MergeOrder * order,
+ List * mergeclauses,
+ List * outersortkeys,
+ List * innersortkeys)
{
- MergePath *pathnode = makeNode(MergePath);
-
- pathnode->jpath.path.pathtype = T_MergeJoin;
- pathnode->jpath.path.parent = joinrel;
- pathnode->jpath.outerjoinpath = outer_path;
- pathnode->jpath.innerjoinpath = inner_path;
- pathnode->jpath.pathclauseinfo = joinrel->clauseinfo;
- pathnode->jpath.path.keys = keys;
- pathnode->jpath.path.p_ordering.ordtype = MERGE_ORDER;
- pathnode->jpath.path.p_ordering.ord.merge = order;
- pathnode->path_mergeclauses = mergeclauses;
- pathnode->jpath.path.locclauseinfo = NIL;
- pathnode->outersortkeys = outersortkeys;
- pathnode->innersortkeys = innersortkeys;
- pathnode->jpath.path.path_cost =
- cost_mergesort(outer_path->path_cost,
- inner_path->path_cost,
- outersortkeys,
- innersortkeys,
- outersize,
- innersize,
- outerwidth,
- innerwidth);
- /* add in expensive function costs -- JMH 7/7/92 */
+ MergePath *pathnode = makeNode(MergePath);
+
+ pathnode->jpath.path.pathtype = T_MergeJoin;
+ pathnode->jpath.path.parent = joinrel;
+ pathnode->jpath.outerjoinpath = outer_path;
+ pathnode->jpath.innerjoinpath = inner_path;
+ pathnode->jpath.pathclauseinfo = joinrel->clauseinfo;
+ pathnode->jpath.path.keys = keys;
+ pathnode->jpath.path.p_ordering.ordtype = MERGE_ORDER;
+ pathnode->jpath.path.p_ordering.ord.merge = order;
+ pathnode->path_mergeclauses = mergeclauses;
+ pathnode->jpath.path.locclauseinfo = NIL;
+ pathnode->outersortkeys = outersortkeys;
+ pathnode->innersortkeys = innersortkeys;
+ pathnode->jpath.path.path_cost =
+ cost_mergesort(outer_path->path_cost,
+ inner_path->path_cost,
+ outersortkeys,
+ innersortkeys,
+ outersize,
+ innersize,
+ outerwidth,
+ innerwidth);
+ /* add in expensive function costs -- JMH 7/7/92 */
#if 0
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost +=
- xfunc_get_path_cost((Path*)pathnode);
- }
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost +=
+ xfunc_get_path_cost((Path *) pathnode);
+ }
#endif
- return(pathnode);
+ return (pathnode);
}
-/*
- * create_hashjoin_path-- XXX HASH
- * Creates a pathnode corresponding to a hash join between two relations.
- *
+/*
+ * create_hashjoin_path-- XXX HASH
+ * Creates a pathnode corresponding to a hash join between two relations.
+ *
* 'joinrel' is the join relation
* 'outersize' is the number of tuples in the outer relation
* 'innersize' is the number of tuples in the inner relation
@@ -516,52 +558,53 @@ create_mergesort_path(Rel *joinrel,
* 'hashclauses' are the applicable join/restriction clauses
* 'outerkeys' are the sort varkeys for the outer relation
* 'innerkeys' are the sort varkeys for the inner relation
- *
+ *
*/
-HashPath *
-create_hashjoin_path(Rel *joinrel,
- int outersize,
- int innersize,
- int outerwidth,
- int innerwidth,
- Path *outer_path,
- Path *inner_path,
- List *keys,
- Oid operator,
- List *hashclauses,
- List *outerkeys,
- List *innerkeys)
+HashPath *
+create_hashjoin_path(Rel * joinrel,
+ int outersize,
+ int innersize,
+ int outerwidth,
+ int innerwidth,
+ Path * outer_path,
+ Path * inner_path,
+ List * keys,
+ Oid operator,
+ List * hashclauses,
+ List * outerkeys,
+ List * innerkeys)
{
- HashPath *pathnode = makeNode(HashPath);
-
- pathnode->jpath.path.pathtype = T_HashJoin;
- pathnode->jpath.path.parent = joinrel;
- pathnode->jpath.outerjoinpath = outer_path;
- pathnode->jpath.innerjoinpath = inner_path;
- pathnode->jpath.pathclauseinfo = joinrel->clauseinfo;
- pathnode->jpath.path.locclauseinfo = NIL;
- pathnode->jpath.path.keys = keys;
- pathnode->jpath.path.p_ordering.ordtype = SORTOP_ORDER;
- pathnode->jpath.path.p_ordering.ord.sortop = NULL;
- pathnode->jpath.path.outerjoincost = (Cost)0.0;
- pathnode->jpath.path.joinid = (Relid)NULL;
- /* pathnode->hashjoinoperator = operator; */
- pathnode->path_hashclauses = hashclauses;
- pathnode->outerhashkeys = outerkeys;
- pathnode->innerhashkeys = innerkeys;
- pathnode->jpath.path.path_cost =
- cost_hashjoin(outer_path->path_cost,
- inner_path->path_cost,
- outerkeys,
- innerkeys,
- outersize,innersize,
- outerwidth,innerwidth);
- /* add in expensive function costs -- JMH 7/7/92 */
+ HashPath *pathnode = makeNode(HashPath);
+
+ pathnode->jpath.path.pathtype = T_HashJoin;
+ pathnode->jpath.path.parent = joinrel;
+ pathnode->jpath.outerjoinpath = outer_path;
+ pathnode->jpath.innerjoinpath = inner_path;
+ pathnode->jpath.pathclauseinfo = joinrel->clauseinfo;
+ pathnode->jpath.path.locclauseinfo = NIL;
+ pathnode->jpath.path.keys = keys;
+ pathnode->jpath.path.p_ordering.ordtype = SORTOP_ORDER;
+ pathnode->jpath.path.p_ordering.ord.sortop = NULL;
+ pathnode->jpath.path.outerjoincost = (Cost) 0.0;
+ pathnode->jpath.path.joinid = (Relid) NULL;
+ /* pathnode->hashjoinoperator = operator; */
+ pathnode->path_hashclauses = hashclauses;
+ pathnode->outerhashkeys = outerkeys;
+ pathnode->innerhashkeys = innerkeys;
+ pathnode->jpath.path.path_cost =
+ cost_hashjoin(outer_path->path_cost,
+ inner_path->path_cost,
+ outerkeys,
+ innerkeys,
+ outersize, innersize,
+ outerwidth, innerwidth);
+ /* add in expensive function costs -- JMH 7/7/92 */
#if 0
- if (XfuncMode != XFUNC_OFF) {
- pathnode->path_cost +=
- xfunc_get_path_cost((Path*)pathnode);
- }
+ if (XfuncMode != XFUNC_OFF)
+ {
+ pathnode->path_cost +=
+ xfunc_get_path_cost((Path *) pathnode);
+ }
#endif
- return(pathnode);
+ return (pathnode);
}
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index abe764aa4e0..0e88a72c4eb 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* plancat.c--
- * routines for accessing the system catalogs
+ * routines for accessing the system catalogs
*
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.6 1997/04/24 16:07:14 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.7 1997/09/07 04:44:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,7 +26,7 @@
#include "catalog/pg_inherits.h"
#include "catalog/pg_version.h"
-#include "parser/parsetree.h" /* for getrelid() */
+#include "parser/parsetree.h" /* for getrelid() */
#include "fmgr.h"
#include "optimizer/internal.h"
@@ -34,193 +34,203 @@
#include "utils/syscache.h"
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static void IndexSelectivity(Oid indexrelid, Oid indrelid, int32 nIndexKeys,
- Oid AccessMethodOperatorClasses[], Oid operatorObjectIds[],
+static void
+IndexSelectivity(Oid indexrelid, Oid indrelid, int32 nIndexKeys,
+ Oid AccessMethodOperatorClasses[], Oid operatorObjectIds[],
int32 varAttributeNumbers[], char *constValues[], int32 constFlags[],
- float *idxPages, float *idxSelec);
+ float *idxPages, float *idxSelec);
/*
* relation-info -
- * Retrieves catalog information for a given relation. Given the oid of
- * the relation, return the following information:
- * whether the relation has secondary indices
- * number of pages
- * number of tuples
+ * Retrieves catalog information for a given relation. Given the oid of
+ * the relation, return the following information:
+ * whether the relation has secondary indices
+ * number of pages
+ * number of tuples
*/
void
-relation_info(Query *root, Index relid,
- bool *hasindex, int *pages, int *tuples)
+relation_info(Query * root, Index relid,
+ bool * hasindex, int *pages, int *tuples)
{
- HeapTuple relationTuple;
- Form_pg_class relation;
- Oid relationObjectId;
-
- relationObjectId = getrelid(relid, root->rtable);
- relationTuple = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relationObjectId),
- 0,0,0);
- if (HeapTupleIsValid(relationTuple)) {
- relation = (Form_pg_class)GETSTRUCT(relationTuple);
-
- *hasindex = (relation->relhasindex) ? TRUE : FALSE;
- *pages = relation->relpages;
- *tuples = relation->reltuples;
- } else {
- elog(WARN, "RelationCatalogInformation: Relation %d not found",
- relationObjectId);
- }
-
- return;
+ HeapTuple relationTuple;
+ Form_pg_class relation;
+ Oid relationObjectId;
+
+ relationObjectId = getrelid(relid, root->rtable);
+ relationTuple = SearchSysCacheTuple(RELOID,
+ ObjectIdGetDatum(relationObjectId),
+ 0, 0, 0);
+ if (HeapTupleIsValid(relationTuple))
+ {
+ relation = (Form_pg_class) GETSTRUCT(relationTuple);
+
+ *hasindex = (relation->relhasindex) ? TRUE : FALSE;
+ *pages = relation->relpages;
+ *tuples = relation->reltuples;
+ }
+ else
+ {
+ elog(WARN, "RelationCatalogInformation: Relation %d not found",
+ relationObjectId);
+ }
+
+ return;
}
-/*
+/*
* index-info--
- * Retrieves catalog information on an index on a given relation.
- *
- * The index relation is opened on the first invocation. The current
- * retrieves the next index relation within the catalog that has not
- * already been retrieved by a previous call. The index catalog
- * is closed when no more indices for 'relid' can be found.
- *
- * 'first' is 1 if this is the first call
- *
+ * Retrieves catalog information on an index on a given relation.
+ *
+ * The index relation is opened on the first invocation. The current
+ * retrieves the next index relation within the catalog that has not
+ * already been retrieved by a previous call. The index catalog
+ * is closed when no more indices for 'relid' can be found.
+ *
+ * 'first' is 1 if this is the first call
+ *
* Returns true if successful and false otherwise. Index info is returned
* via the transient data structure 'info'.
- *
+ *
*/
bool
-index_info(Query *root, bool first, int relid, IdxInfoRetval *info)
+index_info(Query * root, bool first, int relid, IdxInfoRetval * info)
{
- register i;
- HeapTuple indexTuple, amopTuple;
- IndexTupleForm index;
- Relation indexRelation;
- uint16 amstrategy;
- Oid relam;
- Oid indrelid;
-
- static Relation relation = (Relation) NULL;
- static HeapScanDesc scan = (HeapScanDesc) NULL;
- static ScanKeyData indexKey;
-
-
- /* find the oid of the indexed relation */
- indrelid = getrelid(relid, root->rtable);
-
- memset(info, 0, sizeof(IdxInfoRetval));
-
- /*
- * the maximum number of elements in each of the following arrays is
- * 8. We allocate one more for a terminating 0 to indicate the end
- * of the array.
- */
- info->indexkeys = (int *)palloc(sizeof(int)*9);
- memset(info->indexkeys, 0, sizeof(int)*9);
- info->orderOprs = (Oid *)palloc(sizeof(Oid)*9);
- memset(info->orderOprs, 0, sizeof(Oid)*9);
- info->classlist = (Oid *)palloc(sizeof(Oid)*9);
- memset(info->classlist, 0, sizeof(Oid)*9);
-
- /* Find an index on the given relation */
- if (first) {
- if (RelationIsValid(relation))
- heap_close(relation);
- if (HeapScanIsValid(scan))
- heap_endscan(scan);
-
- ScanKeyEntryInitialize(&indexKey, 0,
- Anum_pg_index_indrelid,
- F_OIDEQ,
- ObjectIdGetDatum(indrelid));
-
- relation = heap_openr(IndexRelationName);
- scan = heap_beginscan(relation, 0, NowTimeQual,
- 1, &indexKey);
- }
- if (!HeapScanIsValid(scan))
- elog(WARN, "index_info: scan not started");
- indexTuple = heap_getnext(scan, 0, (Buffer *) NULL);
- if (!HeapTupleIsValid(indexTuple)) {
- heap_endscan(scan);
- heap_close(relation);
- scan = (HeapScanDesc) NULL;
- relation = (Relation) NULL;
- return(0);
- }
-
- /* Extract info from the index tuple */
- index = (IndexTupleForm)GETSTRUCT(indexTuple);
- info->relid = index->indexrelid; /* index relation */
- for (i = 0; i < 8; i++)
- info->indexkeys[i] = index->indkey[i];
- for (i = 0; i < 8; i++)
- info->classlist[i] = index->indclass[i];
-
- info->indproc = index->indproc; /* functional index ?? */
-
- /* partial index ?? */
- if (VARSIZE(&index->indpred) != 0) {
+ register i;
+ HeapTuple indexTuple,
+ amopTuple;
+ IndexTupleForm index;
+ Relation indexRelation;
+ uint16 amstrategy;
+ Oid relam;
+ Oid indrelid;
+
+ static Relation relation = (Relation) NULL;
+ static HeapScanDesc scan = (HeapScanDesc) NULL;
+ static ScanKeyData indexKey;
+
+
+ /* find the oid of the indexed relation */
+ indrelid = getrelid(relid, root->rtable);
+
+ memset(info, 0, sizeof(IdxInfoRetval));
+
/*
- * The memory allocated here for the predicate (in lispReadString)
- * only needs to stay around until it's used in find_index_paths,
- * which is all within a command, so the automatic pfree at end
- * of transaction should be ok.
+ * the maximum number of elements in each of the following arrays is
+ * 8. We allocate one more for a terminating 0 to indicate the end of
+ * the array.
*/
- char *predString;
+ info->indexkeys = (int *) palloc(sizeof(int) * 9);
+ memset(info->indexkeys, 0, sizeof(int) * 9);
+ info->orderOprs = (Oid *) palloc(sizeof(Oid) * 9);
+ memset(info->orderOprs, 0, sizeof(Oid) * 9);
+ info->classlist = (Oid *) palloc(sizeof(Oid) * 9);
+ memset(info->classlist, 0, sizeof(Oid) * 9);
+
+ /* Find an index on the given relation */
+ if (first)
+ {
+ if (RelationIsValid(relation))
+ heap_close(relation);
+ if (HeapScanIsValid(scan))
+ heap_endscan(scan);
+
+ ScanKeyEntryInitialize(&indexKey, 0,
+ Anum_pg_index_indrelid,
+ F_OIDEQ,
+ ObjectIdGetDatum(indrelid));
+
+ relation = heap_openr(IndexRelationName);
+ scan = heap_beginscan(relation, 0, NowTimeQual,
+ 1, &indexKey);
+ }
+ if (!HeapScanIsValid(scan))
+ elog(WARN, "index_info: scan not started");
+ indexTuple = heap_getnext(scan, 0, (Buffer *) NULL);
+ if (!HeapTupleIsValid(indexTuple))
+ {
+ heap_endscan(scan);
+ heap_close(relation);
+ scan = (HeapScanDesc) NULL;
+ relation = (Relation) NULL;
+ return (0);
+ }
+
+ /* Extract info from the index tuple */
+ index = (IndexTupleForm) GETSTRUCT(indexTuple);
+ info->relid = index->indexrelid; /* index relation */
+ for (i = 0; i < 8; i++)
+ info->indexkeys[i] = index->indkey[i];
+ for (i = 0; i < 8; i++)
+ info->classlist[i] = index->indclass[i];
- predString = fmgr(F_TEXTOUT, &index->indpred);
- info->indpred = (Node*)stringToNode(predString);
- pfree(predString);
- }
+ info->indproc = index->indproc; /* functional index ?? */
- /* Extract info from the relation descriptor for the index */
- indexRelation = index_open(index->indexrelid);
+ /* partial index ?? */
+ if (VARSIZE(&index->indpred) != 0)
+ {
+
+ /*
+ * The memory allocated here for the predicate (in lispReadString)
+ * only needs to stay around until it's used in find_index_paths,
+ * which is all within a command, so the automatic pfree at end of
+ * transaction should be ok.
+ */
+ char *predString;
+
+ predString = fmgr(F_TEXTOUT, &index->indpred);
+ info->indpred = (Node *) stringToNode(predString);
+ pfree(predString);
+ }
+
+ /* Extract info from the relation descriptor for the index */
+ indexRelation = index_open(index->indexrelid);
#ifdef notdef
- /* XXX should iterate through strategies -- but how? use #1 for now */
- amstrategy = indexRelation->rd_am->amstrategies;
-#endif /* notdef */
- amstrategy = 1;
- relam = indexRelation->rd_rel->relam;
- info->relam = relam;
- info->pages = indexRelation->rd_rel->relpages;
- info->tuples = indexRelation->rd_rel->reltuples;
- heap_close(indexRelation);
-
- /*
- * Find the index ordering keys
- *
- * Must use indclass to know when to stop looking since with
- * functional indices there could be several keys (args) for
- * one opclass. -mer 27 Sept 1991
- */
- for (i = 0; i < 8 && index->indclass[i]; ++i) {
- amopTuple = SearchSysCacheTuple(AMOPSTRATEGY,
- ObjectIdGetDatum(relam),
- ObjectIdGetDatum(index->indclass[i]),
- UInt16GetDatum(amstrategy),
- 0);
- if (!HeapTupleIsValid(amopTuple))
- elog(WARN, "index_info: no amop %d %d %d",
- relam, index->indclass[i], amstrategy);
- info->orderOprs[i] =
- ((Form_pg_amop)GETSTRUCT(amopTuple))->amopopr;
- }
- return(TRUE);
+ /* XXX should iterate through strategies -- but how? use #1 for now */
+ amstrategy = indexRelation->rd_am->amstrategies;
+#endif /* notdef */
+ amstrategy = 1;
+ relam = indexRelation->rd_rel->relam;
+ info->relam = relam;
+ info->pages = indexRelation->rd_rel->relpages;
+ info->tuples = indexRelation->rd_rel->reltuples;
+ heap_close(indexRelation);
+
+ /*
+ * Find the index ordering keys
+ *
+ * Must use indclass to know when to stop looking since with functional
+ * indices there could be several keys (args) for one opclass. -mer 27
+ * Sept 1991
+ */
+ for (i = 0; i < 8 && index->indclass[i]; ++i)
+ {
+ amopTuple = SearchSysCacheTuple(AMOPSTRATEGY,
+ ObjectIdGetDatum(relam),
+ ObjectIdGetDatum(index->indclass[i]),
+ UInt16GetDatum(amstrategy),
+ 0);
+ if (!HeapTupleIsValid(amopTuple))
+ elog(WARN, "index_info: no amop %d %d %d",
+ relam, index->indclass[i], amstrategy);
+ info->orderOprs[i] =
+ ((Form_pg_amop) GETSTRUCT(amopTuple))->amopopr;
+ }
+ return (TRUE);
}
-/*
+/*
* index-selectivity--
- *
- * Call util/plancat.c:IndexSelectivity with the indicated arguments.
- *
+ *
+ * Call util/plancat.c:IndexSelectivity with the indicated arguments.
+ *
* 'indid' is the index OID
* 'classes' is a list of index key classes
* 'opnos' is a list of index key operator OIDs
@@ -229,153 +239,162 @@ index_info(Query *root, bool first, int relid, IdxInfoRetval *info)
* 'values' is a list of the values of the clause's constants
* 'flags' is a list of fixnums which describe the constants
* 'nkeys' is the number of index keys
- *
+ *
* Returns two floats: index pages and index selectivity in 'idxPages' and
- * 'idxSelec'.
- *
+ * 'idxSelec'.
+ *
*/
void
index_selectivity(Oid indid,
- Oid *classes,
- List *opnos,
- Oid relid,
- List *attnos,
- List *values,
- List *flags,
- int32 nkeys,
- float *idxPages,
- float *idxSelec)
+ Oid * classes,
+ List * opnos,
+ Oid relid,
+ List * attnos,
+ List * values,
+ List * flags,
+ int32 nkeys,
+ float *idxPages,
+ float *idxSelec)
{
- Oid *opno_array;
- int *attno_array, *flag_array;
- char **value_array;
- int i = 0;
- List *xopno, *xattno, *value, *flag;
+ Oid *opno_array;
+ int *attno_array,
+ *flag_array;
+ char **value_array;
+ int i = 0;
+ List *xopno,
+ *xattno,
+ *value,
+ *flag;
+
+ if (length(opnos) != nkeys || length(attnos) != nkeys ||
+ length(values) != nkeys || length(flags) != nkeys)
+ {
+
+ *idxPages = 0.0;
+ *idxSelec = 1.0;
+ return;
+ }
- if (length(opnos)!=nkeys || length(attnos)!=nkeys ||
- length(values)!=nkeys || length(flags)!=nkeys) {
+ opno_array = (Oid *) palloc(nkeys * sizeof(Oid));
+ attno_array = (int *) palloc(nkeys * sizeof(int32));
+ value_array = (char **) palloc(nkeys * sizeof(char *));
+ flag_array = (int *) palloc(nkeys * sizeof(int32));
- *idxPages = 0.0;
- *idxSelec = 1.0;
+ i = 0;
+ foreach(xopno, opnos)
+ {
+ opno_array[i++] = lfirsti(xopno);
+ }
+
+ i = 0;
+ foreach(xattno, attnos)
+ {
+ attno_array[i++] = lfirsti(xattno);
+ }
+
+ i = 0;
+ foreach(value, values)
+ {
+ value_array[i++] = (char *) lfirst(value);
+ }
+
+ i = 0;
+ foreach(flag, flags)
+ {
+ flag_array[i++] = lfirsti(flag);
+ }
+
+ IndexSelectivity(indid,
+ relid,
+ nkeys,
+ classes, /* not used */
+ opno_array,
+ attno_array,
+ value_array,
+ flag_array,
+ idxPages,
+ idxSelec);
return;
- }
-
- opno_array = (Oid *)palloc(nkeys*sizeof(Oid));
- attno_array = (int *)palloc(nkeys*sizeof(int32));
- value_array = (char **)palloc(nkeys*sizeof(char *));
- flag_array = (int *)palloc(nkeys*sizeof(int32));
-
- i = 0;
- foreach(xopno, opnos) {
- opno_array[i++] = lfirsti(xopno);
- }
-
- i = 0;
- foreach(xattno,attnos) {
- attno_array[i++] = lfirsti(xattno);
- }
-
- i = 0;
- foreach(value, values) {
- value_array[i++] = (char *)lfirst(value);
- }
-
- i = 0;
- foreach(flag,flags) {
- flag_array[i++] = lfirsti(flag);
- }
-
- IndexSelectivity(indid,
- relid,
- nkeys,
- classes, /* not used */
- opno_array,
- attno_array,
- value_array,
- flag_array,
- idxPages,
- idxSelec);
- return;
}
/*
* restriction_selectivity in lisp system.--
*
- * NOTE: The routine is now merged with RestrictionClauseSelectivity
- * as defined in plancat.c
+ * NOTE: The routine is now merged with RestrictionClauseSelectivity
+ * as defined in plancat.c
*
* Returns the selectivity of a specified operator.
* This code executes registered procedures stored in the
* operator relation, by calling the function manager.
*
* XXX The assumption in the selectivity procedures is that if the
- * relation OIDs or attribute numbers are -1, then the clause
- * isn't of the form (op var const).
+ * relation OIDs or attribute numbers are -1, then the clause
+ * isn't of the form (op var const).
*/
Cost
restriction_selectivity(Oid functionObjectId,
- Oid operatorObjectId,
- Oid relationObjectId,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag)
+ Oid operatorObjectId,
+ Oid relationObjectId,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag)
{
- float64 result;
-
- result = (float64) fmgr(functionObjectId,
- (char *) operatorObjectId,
- (char *) relationObjectId,
- (char *) (int)attributeNumber,
- (char *) constValue,
- (char *) constFlag,
- NULL);
- if (!PointerIsValid(result))
- elog(WARN, "RestrictionClauseSelectivity: bad pointer");
-
- if (*result < 0.0 || *result > 1.0)
- elog(WARN, "RestrictionClauseSelectivity: bad value %lf",
- *result);
-
- return ((Cost)*result);
+ float64 result;
+
+ result = (float64) fmgr(functionObjectId,
+ (char *) operatorObjectId,
+ (char *) relationObjectId,
+ (char *) (int) attributeNumber,
+ (char *) constValue,
+ (char *) constFlag,
+ NULL);
+ if (!PointerIsValid(result))
+ elog(WARN, "RestrictionClauseSelectivity: bad pointer");
+
+ if (*result < 0.0 || *result > 1.0)
+ elog(WARN, "RestrictionClauseSelectivity: bad value %lf",
+ *result);
+
+ return ((Cost) * result);
}
/*
* join_selectivity--
- * Similarly, this routine is merged with JoinClauseSelectivity in
- * plancat.c
+ * Similarly, this routine is merged with JoinClauseSelectivity in
+ * plancat.c
*
- * Returns the selectivity of an operator, given the join clause
- * information.
+ * Returns the selectivity of an operator, given the join clause
+ * information.
*
* XXX The assumption in the selectivity procedures is that if the
- * relation OIDs or attribute numbers are -1, then the clause
- * isn't of the form (op var var).
+ * relation OIDs or attribute numbers are -1, then the clause
+ * isn't of the form (op var var).
*/
Cost
-join_selectivity (Oid functionObjectId,
- Oid operatorObjectId,
- Oid relationObjectId1,
- AttrNumber attributeNumber1,
- Oid relationObjectId2,
- AttrNumber attributeNumber2)
+join_selectivity(Oid functionObjectId,
+ Oid operatorObjectId,
+ Oid relationObjectId1,
+ AttrNumber attributeNumber1,
+ Oid relationObjectId2,
+ AttrNumber attributeNumber2)
{
- float64 result;
-
- result = (float64) fmgr(functionObjectId,
- (char *) operatorObjectId,
- (char *) relationObjectId1,
- (char *) (int)attributeNumber1,
- (char *) relationObjectId2,
- (char *) (int)attributeNumber2,
- NULL);
- if (!PointerIsValid(result))
- elog(WARN, "JoinClauseSelectivity: bad pointer");
-
- if (*result < 0.0 || *result > 1.0)
- elog(WARN, "JoinClauseSelectivity: bad value %lf",
- *result);
-
- return((Cost)*result);
+ float64 result;
+
+ result = (float64) fmgr(functionObjectId,
+ (char *) operatorObjectId,
+ (char *) relationObjectId1,
+ (char *) (int) attributeNumber1,
+ (char *) relationObjectId2,
+ (char *) (int) attributeNumber2,
+ NULL);
+ if (!PointerIsValid(result))
+ elog(WARN, "JoinClauseSelectivity: bad pointer");
+
+ if (*result < 0.0 || *result > 1.0)
+ elog(WARN, "JoinClauseSelectivity: bad value %lf",
+ *result);
+
+ return ((Cost) * result);
}
/*
@@ -384,33 +403,34 @@ join_selectivity (Oid functionObjectId,
* Returns a LISP list containing the OIDs of all relations which
* inherits from the relation with OID 'inhparent'.
*/
-List *
+List *
find_inheritance_children(Oid inhparent)
{
- static ScanKeyData key[1] = {
- { 0, Anum_pg_inherits_inhparent, F_OIDEQ }
- };
-
- HeapTuple inheritsTuple;
- Relation relation;
- HeapScanDesc scan;
- List *list = NIL;
- Oid inhrelid;
-
- fmgr_info(F_OIDEQ, &key[0].sk_func, &key[0].sk_nargs);
-
- key[0].sk_argument = ObjectIdGetDatum((Oid)inhparent);
- relation = heap_openr(InheritsRelationName);
- scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
- while (HeapTupleIsValid(inheritsTuple =
- heap_getnext(scan, 0,
- (Buffer *) NULL))) {
- inhrelid = ((InheritsTupleForm)GETSTRUCT(inheritsTuple))->inhrel;
- list = lappendi(list, inhrelid);
- }
- heap_endscan(scan);
- heap_close(relation);
- return(list);
+ static ScanKeyData key[1] = {
+ {0, Anum_pg_inherits_inhparent, F_OIDEQ}
+ };
+
+ HeapTuple inheritsTuple;
+ Relation relation;
+ HeapScanDesc scan;
+ List *list = NIL;
+ Oid inhrelid;
+
+ fmgr_info(F_OIDEQ, &key[0].sk_func, &key[0].sk_nargs);
+
+ key[0].sk_argument = ObjectIdGetDatum((Oid) inhparent);
+ relation = heap_openr(InheritsRelationName);
+ scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
+ while (HeapTupleIsValid(inheritsTuple =
+ heap_getnext(scan, 0,
+ (Buffer *) NULL)))
+ {
+ inhrelid = ((InheritsTupleForm) GETSTRUCT(inheritsTuple))->inhrel;
+ list = lappendi(list, inhrelid);
+ }
+ heap_endscan(scan);
+ heap_close(relation);
+ return (list);
}
/*
@@ -419,39 +439,40 @@ find_inheritance_children(Oid inhparent)
* Returns a LISP list containing the OIDs of all relations which are
* base relations of the relation with OID 'verrelid'.
*/
-List *
+List *
VersionGetParents(Oid verrelid)
{
- static ScanKeyData key[1] = {
- { 0, Anum_pg_version_verrelid, F_OIDEQ }
- };
-
- HeapTuple versionTuple;
- Relation relation;
- HeapScanDesc scan;
- Oid verbaseid;
- List *list= NIL;
-
- fmgr_info(F_OIDEQ, &key[0].sk_func, &key[0].sk_nargs);
- relation = heap_openr(VersionRelationName);
- key[0].sk_argument = ObjectIdGetDatum(verrelid);
- scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
- for (;;) {
- versionTuple = heap_getnext(scan, 0,
- (Buffer *) NULL);
- if (!HeapTupleIsValid(versionTuple))
- break;
- verbaseid = ((VersionTupleForm)
- GETSTRUCT(versionTuple))->verbaseid;
-
- list = lconsi(verbaseid, list);
-
- key[0].sk_argument = ObjectIdGetDatum(verbaseid);
- heap_rescan(scan, 0, key);
- }
- heap_endscan(scan);
- heap_close(relation);
- return(list);
+ static ScanKeyData key[1] = {
+ {0, Anum_pg_version_verrelid, F_OIDEQ}
+ };
+
+ HeapTuple versionTuple;
+ Relation relation;
+ HeapScanDesc scan;
+ Oid verbaseid;
+ List *list = NIL;
+
+ fmgr_info(F_OIDEQ, &key[0].sk_func, &key[0].sk_nargs);
+ relation = heap_openr(VersionRelationName);
+ key[0].sk_argument = ObjectIdGetDatum(verrelid);
+ scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
+ for (;;)
+ {
+ versionTuple = heap_getnext(scan, 0,
+ (Buffer *) NULL);
+ if (!HeapTupleIsValid(versionTuple))
+ break;
+ verbaseid = ((VersionTupleForm)
+ GETSTRUCT(versionTuple))->verbaseid;
+
+ list = lconsi(verbaseid, list);
+
+ key[0].sk_argument = ObjectIdGetDatum(verbaseid);
+ heap_rescan(scan, 0, key);
+ }
+ heap_endscan(scan);
+ heap_close(relation);
+ return (list);
}
/*****************************************************************************
@@ -461,14 +482,14 @@ VersionGetParents(Oid verrelid)
/*
* IdexSelectivity--
*
- * Retrieves the 'amopnpages' and 'amopselect' parameters for each
- * AM operator when a given index (specified by 'indexrelid') is used.
- * These two parameters are returned by copying them to into an array of
- * floats.
+ * Retrieves the 'amopnpages' and 'amopselect' parameters for each
+ * AM operator when a given index (specified by 'indexrelid') is used.
+ * These two parameters are returned by copying them to into an array of
+ * floats.
*
- * Assumption: the attribute numbers and operator ObjectIds are in order
- * WRT to each other (otherwise, you have no way of knowing which
- * AM operator class or attribute number corresponds to which operator.
+ * Assumption: the attribute numbers and operator ObjectIds are in order
+ * WRT to each other (otherwise, you have no way of knowing which
+ * AM operator class or attribute number corresponds to which operator.
*
* 'varAttributeNumbers' contains attribute numbers for variables
* 'constValues' contains the constant values
@@ -481,144 +502,154 @@ VersionGetParents(Oid verrelid)
*/
static void
IndexSelectivity(Oid indexrelid,
- Oid indrelid,
- int32 nIndexKeys,
- Oid AccessMethodOperatorClasses[], /* XXX not used? */
- Oid operatorObjectIds[],
- int32 varAttributeNumbers[],
- char *constValues[],
- int32 constFlags[],
- float *idxPages,
- float *idxSelec)
+ Oid indrelid,
+ int32 nIndexKeys,
+ Oid AccessMethodOperatorClasses[], /* XXX not used? */
+ Oid operatorObjectIds[],
+ int32 varAttributeNumbers[],
+ char *constValues[],
+ int32 constFlags[],
+ float *idxPages,
+ float *idxSelec)
{
- register i, n;
- HeapTuple indexTuple, amopTuple, indRel;
- IndexTupleForm index;
- Form_pg_amop amop;
- Oid indclass;
- float64data npages, select;
- float64 amopnpages, amopselect;
- Oid relam;
- bool nphack = false;
- float64data fattr_select = 1.0;
-
- indRel = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(indexrelid),
- 0,0,0);
- if (!HeapTupleIsValid(indRel))
- elog(WARN, "IndexSelectivity: index %d not found",
- indexrelid);
- relam = ((Form_pg_class)GETSTRUCT(indRel))->relam;
-
- indexTuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexrelid),
- 0,0,0);
- if (!HeapTupleIsValid(indexTuple))
- elog(WARN, "IndexSelectivity: index %d not found",
- indexrelid);
- index = (IndexTupleForm)GETSTRUCT(indexTuple);
-
- /*
- * Hack for non-functional btree npages estimation:
- * npages = index_pages * selectivity_of_1st_attr_clause(s)
- * - vadim 04/24/97
- */
- if ( relam == BTREE_AM_OID &&
- varAttributeNumbers[0] != InvalidAttrNumber )
- nphack = true;
-
- npages = 0.0;
- select = 1.0;
- for (n = 0; n < nIndexKeys; ++n) {
- /*
- * Find the AM class for this key.
- *
- * If the first attribute number is invalid then we have a
- * functional index, and AM class is the first one defined
- * since functional indices have exactly one key.
+ register i,
+ n;
+ HeapTuple indexTuple,
+ amopTuple,
+ indRel;
+ IndexTupleForm index;
+ Form_pg_amop amop;
+ Oid indclass;
+ float64data npages,
+ select;
+ float64 amopnpages,
+ amopselect;
+ Oid relam;
+ bool nphack = false;
+ float64data fattr_select = 1.0;
+
+ indRel = SearchSysCacheTuple(RELOID,
+ ObjectIdGetDatum(indexrelid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(indRel))
+ elog(WARN, "IndexSelectivity: index %d not found",
+ indexrelid);
+ relam = ((Form_pg_class) GETSTRUCT(indRel))->relam;
+
+ indexTuple = SearchSysCacheTuple(INDEXRELID,
+ ObjectIdGetDatum(indexrelid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(indexTuple))
+ elog(WARN, "IndexSelectivity: index %d not found",
+ indexrelid);
+ index = (IndexTupleForm) GETSTRUCT(indexTuple);
+
+ /*
+ * Hack for non-functional btree npages estimation: npages =
+ * index_pages * selectivity_of_1st_attr_clause(s) - vadim 04/24/97
*/
- indclass = (varAttributeNumbers[0] == InvalidAttrNumber) ?
- index->indclass[0] : InvalidOid;
- i = 0;
- while ((i < nIndexKeys) && (indclass == InvalidOid)) {
- if (varAttributeNumbers[n] == index->indkey[i]) {
- indclass = index->indclass[i];
- break;
- }
- i++;
- }
- if (!OidIsValid(indclass)) {
- /*
- * Presumably this means that we are using a functional
- * index clause and so had no variable to match to
- * the index key ... if not we are in trouble.
- */
- elog(NOTICE, "IndexSelectivity: no key %d in index %d",
- varAttributeNumbers[n], indexrelid);
- continue;
- }
+ if (relam == BTREE_AM_OID &&
+ varAttributeNumbers[0] != InvalidAttrNumber)
+ nphack = true;
- amopTuple = SearchSysCacheTuple(AMOPOPID,
- ObjectIdGetDatum(indclass),
- ObjectIdGetDatum(operatorObjectIds[n]),
- ObjectIdGetDatum(relam),
- 0);
- if (!HeapTupleIsValid(amopTuple))
- elog(WARN, "IndexSelectivity: no amop %d %d",
- indclass, operatorObjectIds[n]);
- amop = (Form_pg_amop)GETSTRUCT(amopTuple);
-
- if ( !nphack )
+ npages = 0.0;
+ select = 1.0;
+ for (n = 0; n < nIndexKeys; ++n)
{
- amopnpages = (float64) fmgr(amop->amopnpages,
- (char *) operatorObjectIds[n],
- (char *) indrelid,
- (char *) varAttributeNumbers[n],
- (char *) constValues[n],
- (char *) constFlags[n],
- (char *) nIndexKeys,
- (char *) indexrelid);
-#if 0
-/*
+
+ /*
+ * Find the AM class for this key.
+ *
+ * If the first attribute number is invalid then we have a functional
+ * index, and AM class is the first one defined since functional
+ * indices have exactly one key.
+ */
+ indclass = (varAttributeNumbers[0] == InvalidAttrNumber) ?
+ index->indclass[0] : InvalidOid;
+ i = 0;
+ while ((i < nIndexKeys) && (indclass == InvalidOid))
+ {
+ if (varAttributeNumbers[n] == index->indkey[i])
+ {
+ indclass = index->indclass[i];
+ break;
+ }
+ i++;
+ }
+ if (!OidIsValid(indclass))
+ {
+
+ /*
+ * Presumably this means that we are using a functional index
+ * clause and so had no variable to match to the index key ...
+ * if not we are in trouble.
+ */
+ elog(NOTICE, "IndexSelectivity: no key %d in index %d",
+ varAttributeNumbers[n], indexrelid);
+ continue;
+ }
+
+ amopTuple = SearchSysCacheTuple(AMOPOPID,
+ ObjectIdGetDatum(indclass),
+ ObjectIdGetDatum(operatorObjectIds[n]),
+ ObjectIdGetDatum(relam),
+ 0);
+ if (!HeapTupleIsValid(amopTuple))
+ elog(WARN, "IndexSelectivity: no amop %d %d",
+ indclass, operatorObjectIds[n]);
+ amop = (Form_pg_amop) GETSTRUCT(amopTuple);
+
+ if (!nphack)
+ {
+ amopnpages = (float64) fmgr(amop->amopnpages,
+ (char *) operatorObjectIds[n],
+ (char *) indrelid,
+ (char *) varAttributeNumbers[n],
+ (char *) constValues[n],
+ (char *) constFlags[n],
+ (char *) nIndexKeys,
+ (char *) indexrelid);
+#if 0
+/*
* So cool guys! Npages for x > 10 and x < 20 is twice as
* npages for x > 10! - vadim 04/09/97
*/
- npages += PointerIsValid(amopnpages) ? *amopnpages : 0.0;
- if ((i = npages) < npages) /* ceil(npages)? */
- npages += 1.0;
+ npages += PointerIsValid(amopnpages) ? *amopnpages : 0.0;
+ if ((i = npages) < npages) /* ceil(npages)? */
+ npages += 1.0;
#endif
- npages += PointerIsValid(amopnpages) ? *amopnpages : 0.0;
+ npages += PointerIsValid(amopnpages) ? *amopnpages : 0.0;
+ }
+
+ amopselect = (float64) fmgr(amop->amopselect,
+ (char *) operatorObjectIds[n],
+ (char *) indrelid,
+ (char *) varAttributeNumbers[n],
+ (char *) constValues[n],
+ (char *) constFlags[n],
+ (char *) nIndexKeys,
+ (char *) indexrelid);
+
+ if (nphack && varAttributeNumbers[n] == index->indkey[0])
+ fattr_select *= PointerIsValid(amopselect) ? *amopselect : 1.0;
+
+ select *= PointerIsValid(amopselect) ? *amopselect : 1.0;
}
-
- amopselect = (float64) fmgr(amop->amopselect,
- (char *) operatorObjectIds[n],
- (char *) indrelid,
- (char *) varAttributeNumbers[n],
- (char *) constValues[n],
- (char *) constFlags[n],
- (char *) nIndexKeys,
- (char *) indexrelid);
-
- if ( nphack && varAttributeNumbers[n] == index->indkey[0] )
- fattr_select *= PointerIsValid(amopselect) ? *amopselect : 1.0;
-
- select *= PointerIsValid(amopselect) ? *amopselect : 1.0;
- }
- /*
- * Estimation of npages below is hack of course, but it's
- * better than it was before. - vadim 04/09/97
- */
- if ( nphack )
- {
- npages = fattr_select * ((Form_pg_class)GETSTRUCT(indRel))->relpages;
- *idxPages = ceil ((double)npages);
- }
- else
- {
- if ( nIndexKeys > 1 )
- npages = npages / (1.0 + nIndexKeys);
- *idxPages = ceil ((double)(npages/nIndexKeys));
- }
- *idxSelec = select;
-}
+ /*
+ * Estimation of npages below is hack of course, but it's better than
+ * it was before. - vadim 04/09/97
+ */
+ if (nphack)
+ {
+ npages = fattr_select * ((Form_pg_class) GETSTRUCT(indRel))->relpages;
+ *idxPages = ceil((double) npages);
+ }
+ else
+ {
+ if (nIndexKeys > 1)
+ npages = npages / (1.0 + nIndexKeys);
+ *idxPages = ceil((double) (npages / nIndexKeys));
+ }
+ *idxSelec = select;
+}
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 351fb182107..229dff98092 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* relnode.c--
- * Relation manipulation routines
+ * Relation manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.1.1.1 1996/07/09 06:21:39 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.2 1997/09/07 04:44:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,108 +16,118 @@
#include "nodes/relation.h"
#include "optimizer/internal.h"
-#include "optimizer/pathnode.h" /* where the decls go */
+#include "optimizer/pathnode.h" /* where the decls go */
#include "optimizer/plancat.h"
-/*
+/*
* get_base_rel--
- * Returns relation entry corresponding to 'relid', creating a new one if
- * necessary. This is for base relations.
- *
+ * Returns relation entry corresponding to 'relid', creating a new one if
+ * necessary. This is for base relations.
+ *
*/
-Rel *get_base_rel(Query* root, int relid)
+Rel *
+get_base_rel(Query * root, int relid)
{
- List *relids;
- Rel *rel;
+ List *relids;
+ Rel *rel;
+
+ relids = lconsi(relid, NIL);
+ rel = rel_member(relids, root->base_relation_list_);
+ if (rel == NULL)
+ {
+ rel = makeNode(Rel);
+ rel->relids = relids;
+ rel->indexed = false;
+ rel->pages = 0;
+ rel->tuples = 0;
+ rel->width = 0;
+ rel->targetlist = NIL;
+ rel->pathlist = NIL;
+ rel->unorderedpath = (Path *) NULL;
+ rel->cheapestpath = (Path *) NULL;
+ rel->pruneable = true;
+ rel->classlist = NULL;
+ rel->ordering = NULL;
+ rel->relam = InvalidOid;
+ rel->clauseinfo = NIL;
+ rel->joininfo = NIL;
+ rel->innerjoin = NIL;
+ rel->superrels = NIL;
+
+ root->base_relation_list_ = lcons(rel,
+ root->base_relation_list_);
+
+ /*
+ * ??? the old lispy C code (get_rel) do a listp(relid) here but
+ * that can never happen since we already established relid is not
+ * a list. -ay 10/94
+ */
+ if (relid < 0)
+ {
+
+ /*
+ * If the relation is a materialized relation, assume
+ * constants for sizes.
+ */
+ rel->pages = _TEMP_RELATION_PAGES_;
+ rel->tuples = _TEMP_RELATION_TUPLES_;
+
+ }
+ else
+ {
+ bool hasindex;
+ int pages,
+ tuples;
- relids = lconsi(relid, NIL);
- rel = rel_member(relids, root->base_relation_list_);
- if (rel==NULL) {
- rel = makeNode(Rel);
- rel->relids = relids;
- rel->indexed = false;
- rel->pages = 0;
- rel->tuples = 0;
- rel->width = 0;
- rel->targetlist = NIL;
- rel->pathlist = NIL;
- rel->unorderedpath = (Path *)NULL;
- rel->cheapestpath = (Path *)NULL;
- rel->pruneable = true;
- rel->classlist = NULL;
- rel->ordering = NULL;
- rel->relam = InvalidOid;
- rel->clauseinfo = NIL;
- rel->joininfo = NIL;
- rel->innerjoin = NIL;
- rel->superrels = NIL;
-
- root->base_relation_list_ = lcons(rel,
- root->base_relation_list_);
-
- /*
- * ??? the old lispy C code (get_rel) do a listp(relid) here but
- * that can never happen since we already established relid is not
- * a list. -ay 10/94
- */
- if(relid < 0) {
- /*
- * If the relation is a materialized relation, assume
- * constants for sizes.
- */
- rel->pages = _TEMP_RELATION_PAGES_;
- rel->tuples = _TEMP_RELATION_TUPLES_;
-
- } else {
- bool hasindex;
- int pages, tuples;
-
- /*
- * Otherwise, retrieve relation characteristics from the
- * system catalogs.
- */
- relation_info(root, relid, &hasindex, &pages, &tuples);
- rel->indexed = hasindex;
- rel->pages = pages;
- rel->tuples = tuples;
- }
- }
- return rel;
+ /*
+ * Otherwise, retrieve relation characteristics from the
+ * system catalogs.
+ */
+ relation_info(root, relid, &hasindex, &pages, &tuples);
+ rel->indexed = hasindex;
+ rel->pages = pages;
+ rel->tuples = tuples;
+ }
+ }
+ return rel;
}
-/*
+/*
* get_join_rel--
- * Returns relation entry corresponding to 'relid' (a list of relids),
- * creating a new one if necessary. This is for join relations.
- *
+ * Returns relation entry corresponding to 'relid' (a list of relids),
+ * creating a new one if necessary. This is for join relations.
+ *
*/
-Rel *get_join_rel(Query *root, List *relid)
+Rel *
+get_join_rel(Query * root, List * relid)
{
- return rel_member(relid, root->join_relation_list_);
+ return rel_member(relid, root->join_relation_list_);
}
-/*
+/*
* rel-member--
- * Determines whether a relation of id 'relid' is contained within a list
- * 'rels'.
- *
+ * Determines whether a relation of id 'relid' is contained within a list
+ * 'rels'.
+ *
* Returns the corresponding entry in 'rels' if it is there.
- *
+ *
*/
-Rel *
-rel_member(List *relid, List *rels)
+Rel *
+rel_member(List * relid, List * rels)
{
- List *temp = NIL;
- List *temprelid = NIL;
-
- if (relid!=NIL && rels!=NIL) {
- foreach(temp,rels) {
- temprelid = ((Rel*)lfirst(temp))->relids;
- if(same(temprelid, relid))
- return((Rel*)(lfirst(temp)));
+ List *temp = NIL;
+ List *temprelid = NIL;
+
+ if (relid != NIL && rels != NIL)
+ {
+ foreach(temp, rels)
+ {
+ temprelid = ((Rel *) lfirst(temp))->relids;
+ if (same(temprelid, relid))
+ return ((Rel *) (lfirst(temp)));
+ }
}
- }
- return(NULL);
+ return (NULL);
}
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index c0f11ff3293..7e8563d31ab 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* tlist.c--
- * Target list manipulation routines
+ * Target list manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.4 1997/08/20 14:53:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.5 1997/09/07 04:44:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,498 +28,538 @@
#include "nodes/makefuncs.h"
#include "parser/catalog_utils.h"
-static Node *flatten_tlistentry(Node *tlistentry, List *flat_tlist);
+static Node *flatten_tlistentry(Node * tlistentry, List * flat_tlist);
/*****************************************************************************
- * ---------- RELATION node target list routines ----------
+ * ---------- RELATION node target list routines ----------
*****************************************************************************/
-/*
+/*
* tlistentry-member--
- *
+ *
* RETURNS: the leftmost member of sequence "targetlist" that satisfies
- * the predicate "var_equal"
+ * the predicate "var_equal"
* MODIFIES: nothing
* REQUIRES: test = function which can operate on a lispval union
- * var = valid var-node
- * targetlist = valid sequence
+ * var = valid var-node
+ * targetlist = valid sequence
*/
-TargetEntry *
-tlistentry_member(Var *var, List *targetlist)
+TargetEntry *
+tlistentry_member(Var * var, List * targetlist)
{
- if (var) {
- List *temp = NIL;
-
- foreach (temp,targetlist) {
- if (var_equal(var,
- get_expr(lfirst(temp))))
- return((TargetEntry*)lfirst(temp));
+ if (var)
+ {
+ List *temp = NIL;
+
+ foreach(temp, targetlist)
+ {
+ if (var_equal(var,
+ get_expr(lfirst(temp))))
+ return ((TargetEntry *) lfirst(temp));
+ }
}
- }
- return (NULL);
+ return (NULL);
}
-/*
+/*
* matching_tlvar--
- *
+ *
* RETURNS: var node in a target list which is var_equal to 'var',
- * if one exists.
+ * if one exists.
* REQUIRES: "test" operates on lispval unions,
- *
+ *
*/
-Expr *
-matching_tlvar(Var *var, List *targetlist)
+Expr *
+matching_tlvar(Var * var, List * targetlist)
{
- TargetEntry *tlentry;
+ TargetEntry *tlentry;
- tlentry = tlistentry_member(var,targetlist);
- if (tlentry)
- return((Expr*)get_expr (tlentry) );
+ tlentry = tlistentry_member(var, targetlist);
+ if (tlentry)
+ return ((Expr *) get_expr(tlentry));
- return((Expr*) NULL);
+ return ((Expr *) NULL);
}
-/*
+/*
* add_tl_element--
- * Creates a targetlist entry corresponding to the supplied var node
+ * Creates a targetlist entry corresponding to the supplied var node
*
* 'var' and adds the new targetlist entry to the targetlist field of
- * 'rel'
- *
+ * 'rel'
+ *
* RETURNS: nothing
* MODIFIES: vartype and varid fields of leftmost varnode that matches
- * argument "var" (sometimes).
+ * argument "var" (sometimes).
* CREATES: new var-node iff no matching var-node exists in targetlist
*/
void
-add_tl_element(Rel *rel, Var *var)
+add_tl_element(Rel * rel, Var * var)
{
- Expr *oldvar = (Expr *)NULL;
-
- oldvar = matching_tlvar(var, rel->targetlist);
-
- /*
- * If 'var' is not already in 'rel's target list, add a new node.
- */
- if (oldvar==NULL) {
- List *tlist = rel->targetlist;
- Var *newvar = makeVar(var->varno,
- var->varattno,
- var->vartype,
- var->varno,
- var->varoattno);
-
- rel->targetlist =
- lappend (tlist,
- create_tl_element(newvar,
- length(tlist) + 1));
-
- }
+ Expr *oldvar = (Expr *) NULL;
+
+ oldvar = matching_tlvar(var, rel->targetlist);
+
+ /*
+ * If 'var' is not already in 'rel's target list, add a new node.
+ */
+ if (oldvar == NULL)
+ {
+ List *tlist = rel->targetlist;
+ Var *newvar = makeVar(var->varno,
+ var->varattno,
+ var->vartype,
+ var->varno,
+ var->varoattno);
+
+ rel->targetlist =
+ lappend(tlist,
+ create_tl_element(newvar,
+ length(tlist) + 1));
+
+ }
}
-/*
+/*
* create_tl_element--
- * Creates a target list entry node and its associated (resdom var) pair
- * with its resdom number equal to 'resdomno' and the joinlist field set
- * to 'joinlist'.
- *
+ * Creates a target list entry node and its associated (resdom var) pair
+ * with its resdom number equal to 'resdomno' and the joinlist field set
+ * to 'joinlist'.
+ *
* RETURNS: newly created tlist-entry
* CREATES: new targetlist entry (always).
*/
-TargetEntry*
-create_tl_element(Var *var, int resdomno)
+TargetEntry *
+create_tl_element(Var * var, int resdomno)
{
- TargetEntry *tlelement= makeNode(TargetEntry);
-
- tlelement->resdom =
- makeResdom(resdomno,
- var->vartype,
- get_typlen(var->vartype),
- NULL,
- (Index)0,
- (Oid)0,
- 0);
- tlelement->expr = (Node*)var;
-
- return(tlelement);
+ TargetEntry *tlelement = makeNode(TargetEntry);
+
+ tlelement->resdom =
+ makeResdom(resdomno,
+ var->vartype,
+ get_typlen(var->vartype),
+ NULL,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+ tlelement->expr = (Node *) var;
+
+ return (tlelement);
}
-/*
+/*
* get-actual-tlist--
- * Returns the targetlist elements from a relation tlist.
- *
+ * Returns the targetlist elements from a relation tlist.
+ *
*/
-List *
-get_actual_tlist(List *tlist)
+List *
+get_actual_tlist(List * tlist)
{
- /*
- * this function is not making sense. - ay 10/94
- */
-#if 0
- List *element = NIL;
- List *result = NIL;
-
- if (tlist==NULL) {
- elog(DEBUG,"calling get_actual_tlist with empty tlist");
- return(NIL);
- }
- /* XXX - it is unclear to me what exactly get_entry
- should be doing, as it is unclear to me the exact
- relationship between "TL" "TLE" and joinlists */
-
- foreach(element,tlist)
- result = lappend(result, lfirst((List*)lfirst(element)));
-
- return(result);
+
+ /*
+ * this function is not making sense. - ay 10/94
+ */
+#if 0
+ List *element = NIL;
+ List *result = NIL;
+
+ if (tlist == NULL)
+ {
+ elog(DEBUG, "calling get_actual_tlist with empty tlist");
+ return (NIL);
+ }
+
+ /*
+ * XXX - it is unclear to me what exactly get_entry should be doing,
+ * as it is unclear to me the exact relationship between "TL" "TLE"
+ * and joinlists
+ */
+
+ foreach(element, tlist)
+ result = lappend(result, lfirst((List *) lfirst(element)));
+
+ return (result);
#endif
- return tlist;
+ return tlist;
}
/*****************************************************************************
- * ---------- GENERAL target list routines ----------
+ * ---------- GENERAL target list routines ----------
*****************************************************************************/
-/*
+/*
* tlist-member--
- * Determines whether a var node is already contained within a
- * target list.
- *
+ * Determines whether a var node is already contained within a
+ * target list.
+ *
* 'var' is the var node
* 'tlist' is the target list
* 'dots' is t if we must match dotfields to determine uniqueness
- *
+ *
* Returns the resdom entry of the matching var node.
- *
+ *
*/
-Resdom *
-tlist_member(Var *var, List *tlist)
+Resdom *
+tlist_member(Var * var, List * tlist)
{
- List *i = NIL;
- TargetEntry *temp_tle = (TargetEntry *)NULL;
- TargetEntry *tl_elt = (TargetEntry *)NULL;
-
- if (var) {
- foreach (i,tlist) {
- temp_tle = (TargetEntry *)lfirst(i);
- if (var_equal(var, get_expr(temp_tle))) {
- tl_elt = temp_tle;
- break;
- }
+ List *i = NIL;
+ TargetEntry *temp_tle = (TargetEntry *) NULL;
+ TargetEntry *tl_elt = (TargetEntry *) NULL;
+
+ if (var)
+ {
+ foreach(i, tlist)
+ {
+ temp_tle = (TargetEntry *) lfirst(i);
+ if (var_equal(var, get_expr(temp_tle)))
+ {
+ tl_elt = temp_tle;
+ break;
+ }
+ }
+
+ if (tl_elt != NULL)
+ return (tl_elt->resdom);
+ else
+ return ((Resdom *) NULL);
}
-
- if (tl_elt != NULL)
- return(tl_elt->resdom);
- else
- return((Resdom*)NULL);
- }
- return ((Resdom*)NULL);
+ return ((Resdom *) NULL);
}
/*
- * Routine to get the resdom out of a targetlist.
+ * Routine to get the resdom out of a targetlist.
*/
-Resdom *
-tlist_resdom(List *tlist, Resdom *resnode)
+Resdom *
+tlist_resdom(List * tlist, Resdom * resnode)
{
- Resdom *resdom = (Resdom*)NULL;
- List *i = NIL;
- TargetEntry *temp_tle = (TargetEntry *)NULL;
-
- foreach(i,tlist) {
- temp_tle = (TargetEntry *)lfirst(i);
- resdom = temp_tle->resdom;
- /* Since resnos are supposed to be unique */
- if (resnode->resno == resdom->resno)
- return(resdom);
- }
- return((Resdom*)NULL);
+ Resdom *resdom = (Resdom *) NULL;
+ List *i = NIL;
+ TargetEntry *temp_tle = (TargetEntry *) NULL;
+
+ foreach(i, tlist)
+ {
+ temp_tle = (TargetEntry *) lfirst(i);
+ resdom = temp_tle->resdom;
+ /* Since resnos are supposed to be unique */
+ if (resnode->resno == resdom->resno)
+ return (resdom);
+ }
+ return ((Resdom *) NULL);
}
-/*
+/*
* match_varid--
- * Searches a target list for an entry with some desired varid.
- *
+ * Searches a target list for an entry with some desired varid.
+ *
* 'varid' is the desired id
* 'tlist' is the target list that is searched
- *
+ *
* Returns the target list entry (resdom var) of the matching var.
*
* Now checks to make sure array references (in addition to range
* table indices) are identical - retrieve (a.b[1],a.b[2]) should
* not be turned into retrieve (a.b[1],a.b[1]).
- *
+ *
* [what used to be varid is now broken up into two fields varnoold and
- * varoattno. Also, nested attnos are long gone. - ay 2/95]
+ * varoattno. Also, nested attnos are long gone. - ay 2/95]
*/
-TargetEntry *
-match_varid(Var *test_var, List *tlist)
+TargetEntry *
+match_varid(Var * test_var, List * tlist)
{
- List *tl;
- Oid type_var;
+ List *tl;
+ Oid type_var;
- type_var = (Oid) test_var->vartype;
+ type_var = (Oid) test_var->vartype;
- foreach (tl, tlist) {
- TargetEntry *entry;
- Var *tlvar;
+ foreach(tl, tlist)
+ {
+ TargetEntry *entry;
+ Var *tlvar;
- entry = lfirst(tl);
- tlvar = get_expr(entry);
-
- if ( !IsA (tlvar, Var) )
- continue;
+ entry = lfirst(tl);
+ tlvar = get_expr(entry);
- /*
- * we test the original varno (instead of varno which might
- * be changed to INNER/OUTER.
- */
- if (tlvar->varnoold == test_var->varnoold &&
- tlvar->varoattno == test_var->varoattno) {
+ if (!IsA(tlvar, Var))
+ continue;
+
+ /*
+ * we test the original varno (instead of varno which might be
+ * changed to INNER/OUTER.
+ */
+ if (tlvar->varnoold == test_var->varnoold &&
+ tlvar->varoattno == test_var->varoattno)
+ {
- if (tlvar->vartype == type_var)
- return(entry);
+ if (tlvar->vartype == type_var)
+ return (entry);
+ }
}
- }
- return (NULL);
+ return (NULL);
}
-/*
+/*
* new-unsorted-tlist--
- * Creates a copy of a target list by creating new resdom nodes
- * without sort information.
- *
+ * Creates a copy of a target list by creating new resdom nodes
+ * without sort information.
+ *
* 'targetlist' is the target list to be copied.
- *
+ *
* Returns the resulting target list.
- *
+ *
*/
-List *
-new_unsorted_tlist(List *targetlist)
+List *
+new_unsorted_tlist(List * targetlist)
{
- List *new_targetlist = (List*)copyObject ((Node*)targetlist);
- List *x = NIL;
-
- foreach (x, new_targetlist) {
- TargetEntry *tle = (TargetEntry *)lfirst(x);
- tle->resdom->reskey = 0;
- tle->resdom->reskeyop = (Oid)0;
- }
- return(new_targetlist);
+ List *new_targetlist = (List *) copyObject((Node *) targetlist);
+ List *x = NIL;
+
+ foreach(x, new_targetlist)
+ {
+ TargetEntry *tle = (TargetEntry *) lfirst(x);
+
+ tle->resdom->reskey = 0;
+ tle->resdom->reskeyop = (Oid) 0;
+ }
+ return (new_targetlist);
}
-/*
+/*
* copy-vars--
- * Replaces the var nodes in the first target list with those from
- * the second target list. The two target lists are assumed to be
- * identical except their actual resdoms and vars are different.
- *
+ * Replaces the var nodes in the first target list with those from
+ * the second target list. The two target lists are assumed to be
+ * identical except their actual resdoms and vars are different.
+ *
* 'target' is the target list to be replaced
* 'source' is the target list to be copied
- *
+ *
* Returns a new target list.
- *
+ *
*/
-List *
-copy_vars(List *target, List *source)
+List *
+copy_vars(List * target, List * source)
{
- List *result = NIL;
- List *src = NIL;
- List *dest = NIL;
-
- for ( src = source, dest = target; src != NIL &&
- dest != NIL; src = lnext(src), dest = lnext(dest)) {
- TargetEntry *temp = MakeTLE(((TargetEntry *)lfirst(dest))->resdom,
- (Node*)get_expr(lfirst(src)));
- result = lappend(result,temp);
- }
- return(result);
+ List *result = NIL;
+ List *src = NIL;
+ List *dest = NIL;
+
+ for (src = source, dest = target; src != NIL &&
+ dest != NIL; src = lnext(src), dest = lnext(dest))
+ {
+ TargetEntry *temp = MakeTLE(((TargetEntry *) lfirst(dest))->resdom,
+ (Node *) get_expr(lfirst(src)));
+
+ result = lappend(result, temp);
+ }
+ return (result);
}
-/*
+/*
* flatten-tlist--
- * Create a target list that only contains unique variables.
+ * Create a target list that only contains unique variables.
*
*
* 'tlist' is the current target list
- *
+ *
* Returns the "flattened" new target list.
- *
+ *
*/
-List *
-flatten_tlist(List *tlist)
+List *
+flatten_tlist(List * tlist)
{
- int last_resdomno = 1;
- List *new_tlist = NIL;
- List *tlist_vars = NIL;
- List *temp;
-
- foreach (temp, tlist) {
- TargetEntry *temp_entry = NULL;
- List *vars;
-
- temp_entry = lfirst(temp);
- vars = pull_var_clause((Node*)get_expr(temp_entry));
- if(vars != NULL) {
- tlist_vars = nconc(tlist_vars, vars);
+ int last_resdomno = 1;
+ List *new_tlist = NIL;
+ List *tlist_vars = NIL;
+ List *temp;
+
+ foreach(temp, tlist)
+ {
+ TargetEntry *temp_entry = NULL;
+ List *vars;
+
+ temp_entry = lfirst(temp);
+ vars = pull_var_clause((Node *) get_expr(temp_entry));
+ if (vars != NULL)
+ {
+ tlist_vars = nconc(tlist_vars, vars);
+ }
}
- }
-
- foreach (temp, tlist_vars) {
- Var *var = lfirst(temp);
- if (!(tlist_member(var, new_tlist))) {
- Resdom *r;
-
- r = makeResdom(last_resdomno,
- var->vartype,
- get_typlen(var->vartype),
- NULL,
- (Index)0,
- (Oid)0,
- 0);
- last_resdomno++;
- new_tlist = lappend(new_tlist, MakeTLE (r, (Node*)var));
+
+ foreach(temp, tlist_vars)
+ {
+ Var *var = lfirst(temp);
+
+ if (!(tlist_member(var, new_tlist)))
+ {
+ Resdom *r;
+
+ r = makeResdom(last_resdomno,
+ var->vartype,
+ get_typlen(var->vartype),
+ NULL,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+ last_resdomno++;
+ new_tlist = lappend(new_tlist, MakeTLE(r, (Node *) var));
+ }
}
- }
- return new_tlist;
+ return new_tlist;
}
-/*
+/*
* flatten-tlist-vars--
- * Redoes the target list of a query with no nested attributes by
- * replacing vars within computational expressions with vars from
- * the 'flattened' target list of the query.
- *
+ * Redoes the target list of a query with no nested attributes by
+ * replacing vars within computational expressions with vars from
+ * the 'flattened' target list of the query.
+ *
* 'full-tlist' is the actual target list
* 'flat-tlist' is the flattened (var-only) target list
- *
+ *
* Returns the modified actual target list.
- *
+ *
*/
-List *
-flatten_tlist_vars(List *full_tlist, List *flat_tlist)
+List *
+flatten_tlist_vars(List * full_tlist, List * flat_tlist)
{
- List *x = NIL;
- List *result = NIL;
-
- foreach(x,full_tlist) {
- TargetEntry *tle= lfirst(x);
- result =
- lappend(result,
- MakeTLE(tle->resdom,
- flatten_tlistentry((Node*)get_expr(tle),
- flat_tlist)));
- }
-
- return(result);
+ List *x = NIL;
+ List *result = NIL;
+
+ foreach(x, full_tlist)
+ {
+ TargetEntry *tle = lfirst(x);
+
+ result =
+ lappend(result,
+ MakeTLE(tle->resdom,
+ flatten_tlistentry((Node *) get_expr(tle),
+ flat_tlist)));
+ }
+
+ return (result);
}
-/*
+/*
* flatten-tlistentry--
- * Replaces vars within a target list entry with vars from a flattened
- * target list.
- *
+ * Replaces vars within a target list entry with vars from a flattened
+ * target list.
+ *
* 'tlistentry' is the target list entry to be modified
* 'flat-tlist' is the flattened target list
- *
+ *
* Returns the (modified) target_list entry from the target list.
- *
+ *
*/
-static Node *
-flatten_tlistentry(Node *tlistentry, List *flat_tlist)
+static Node *
+flatten_tlistentry(Node * tlistentry, List * flat_tlist)
{
- if (tlistentry==NULL) {
-
- return NULL;
-
- } else if (IsA (tlistentry,Var)) {
-
- return
- ((Node *)get_expr(match_varid((Var*)tlistentry,
- flat_tlist)));
- } else if (IsA (tlistentry,Iter)) {
-
- ((Iter*)tlistentry)->iterexpr =
- flatten_tlistentry((Node*)((Iter*)tlistentry)->iterexpr,
- flat_tlist);
- return tlistentry;
-
- } else if (single_node(tlistentry)) {
-
- return tlistentry;
-
- } else if (is_funcclause (tlistentry)) {
- Expr *expr = (Expr*)tlistentry;
- List *temp_result = NIL;
- List *elt = NIL;
-
- foreach(elt, expr->args)
- temp_result = lappend(temp_result,
- flatten_tlistentry(lfirst(elt),flat_tlist));
-
- return
- ((Node *)make_funcclause((Func*)expr->oper, temp_result));
-
- } else if (IsA(tlistentry,Aggreg)) {
-
- return tlistentry;
-
- } else if (IsA(tlistentry,ArrayRef)) {
- ArrayRef *aref = (ArrayRef *)tlistentry;
- List *temp = NIL;
- List *elt = NIL;
-
- foreach(elt, aref->refupperindexpr)
- temp = lappend(temp, flatten_tlistentry(lfirst(elt), flat_tlist));
- aref->refupperindexpr = temp;
-
- temp = NIL;
- foreach(elt, aref->reflowerindexpr)
- temp = lappend(temp, flatten_tlistentry(lfirst(elt), flat_tlist));
- aref->reflowerindexpr = temp;
-
- aref->refexpr =
- flatten_tlistentry(aref->refexpr, flat_tlist);
-
- aref->refassgnexpr =
- flatten_tlistentry(aref->refassgnexpr, flat_tlist);
-
- return tlistentry;
- } else {
- Expr *expr = (Expr*)tlistentry;
- Var *left =
- (Var*)flatten_tlistentry((Node*)get_leftop(expr),
- flat_tlist);
- Var *right =
- (Var*)flatten_tlistentry((Node*)get_rightop(expr),
- flat_tlist);
-
- return((Node *)
- make_opclause((Oper*)expr->oper, left, right));
- }
+ if (tlistentry == NULL)
+ {
+
+ return NULL;
+
+ }
+ else if (IsA(tlistentry, Var))
+ {
+
+ return
+ ((Node *) get_expr(match_varid((Var *) tlistentry,
+ flat_tlist)));
+ }
+ else if (IsA(tlistentry, Iter))
+ {
+
+ ((Iter *) tlistentry)->iterexpr =
+ flatten_tlistentry((Node *) ((Iter *) tlistentry)->iterexpr,
+ flat_tlist);
+ return tlistentry;
+
+ }
+ else if (single_node(tlistentry))
+ {
+
+ return tlistentry;
+
+ }
+ else if (is_funcclause(tlistentry))
+ {
+ Expr *expr = (Expr *) tlistentry;
+ List *temp_result = NIL;
+ List *elt = NIL;
+
+ foreach(elt, expr->args)
+ temp_result = lappend(temp_result,
+ flatten_tlistentry(lfirst(elt), flat_tlist));
+
+ return
+ ((Node *) make_funcclause((Func *) expr->oper, temp_result));
+
+ }
+ else if (IsA(tlistentry, Aggreg))
+ {
+
+ return tlistentry;
+
+ }
+ else if (IsA(tlistentry, ArrayRef))
+ {
+ ArrayRef *aref = (ArrayRef *) tlistentry;
+ List *temp = NIL;
+ List *elt = NIL;
+
+ foreach(elt, aref->refupperindexpr)
+ temp = lappend(temp, flatten_tlistentry(lfirst(elt), flat_tlist));
+ aref->refupperindexpr = temp;
+
+ temp = NIL;
+ foreach(elt, aref->reflowerindexpr)
+ temp = lappend(temp, flatten_tlistentry(lfirst(elt), flat_tlist));
+ aref->reflowerindexpr = temp;
+
+ aref->refexpr =
+ flatten_tlistentry(aref->refexpr, flat_tlist);
+
+ aref->refassgnexpr =
+ flatten_tlistentry(aref->refassgnexpr, flat_tlist);
+
+ return tlistentry;
+ }
+ else
+ {
+ Expr *expr = (Expr *) tlistentry;
+ Var *left =
+ (Var *) flatten_tlistentry((Node *) get_leftop(expr),
+ flat_tlist);
+ Var *right =
+ (Var *) flatten_tlistentry((Node *) get_rightop(expr),
+ flat_tlist);
+
+ return ((Node *)
+ make_opclause((Oper *) expr->oper, left, right));
+ }
}
-TargetEntry *
-MakeTLE(Resdom *resdom, Node *expr)
+TargetEntry *
+MakeTLE(Resdom * resdom, Node * expr)
{
- TargetEntry *rt = makeNode(TargetEntry);
+ TargetEntry *rt = makeNode(TargetEntry);
- rt->resdom = resdom;
- rt->expr = expr;
- return rt;
+ rt->resdom = resdom;
+ rt->expr = expr;
+ return rt;
}
-Var *
-get_expr(TargetEntry *tle)
+Var *
+get_expr(TargetEntry * tle)
{
- Assert(tle!=NULL);
- Assert(tle->expr!=NULL);
+ Assert(tle != NULL);
+ Assert(tle->expr != NULL);
- return ((Var *)tle->expr);
+ return ((Var *) tle->expr);
}
@@ -529,54 +569,56 @@ get_expr(TargetEntry *tle)
/*
* AddGroupAttrToTlist -
- * append the group attribute to the target list if it's not already
- * in there.
+ * append the group attribute to the target list if it's not already
+ * in there.
*/
#ifdef NOT_USED
void
-AddGroupAttrToTlist(List *tlist, List *grpCl)
+AddGroupAttrToTlist(List * tlist, List * grpCl)
{
- List *gl;
- int last_resdomno = length(tlist) + 1;
-
- foreach (gl, grpCl) {
- GroupClause *gc = (GroupClause*)lfirst(gl);
- Var *var = gc->grpAttr;
-
- if (!(tlist_member(var, tlist))) {
- Resdom *r;
-
- r = makeResdom(last_resdomno,
- var->vartype,
- get_typlen(var->vartype),
- NULL,
- (Index)0,
- (Oid)0,
- 0);
- last_resdomno++;
- tlist = lappend(tlist, MakeTLE(r, (Node*)var));
+ List *gl;
+ int last_resdomno = length(tlist) + 1;
+
+ foreach(gl, grpCl)
+ {
+ GroupClause *gc = (GroupClause *) lfirst(gl);
+ Var *var = gc->grpAttr;
+
+ if (!(tlist_member(var, tlist)))
+ {
+ Resdom *r;
+
+ r = makeResdom(last_resdomno,
+ var->vartype,
+ get_typlen(var->vartype),
+ NULL,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+ last_resdomno++;
+ tlist = lappend(tlist, MakeTLE(r, (Node *) var));
+ }
}
- }
}
+
#endif
-/* was ExecTargetListLength() in execQual.c,
+/* was ExecTargetListLength() in execQual.c,
moved here to reduce dependencies on the executor module */
int
-exec_tlist_length(List *targetlist)
+exec_tlist_length(List * targetlist)
{
- int len;
- List *tl;
- TargetEntry *curTle;
-
- len = 0;
- foreach (tl, targetlist) {
- curTle = lfirst(tl);
-
- if (curTle->resdom != NULL)
- len++;
- }
- return len;
-}
+ int len;
+ List *tl;
+ TargetEntry *curTle;
+ len = 0;
+ foreach(tl, targetlist)
+ {
+ curTle = lfirst(tl);
+ if (curTle->resdom != NULL)
+ len++;
+ }
+ return len;
+}
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index 3eb0787e3ef..40abf5f80cb 100644
--- a/src/backend/optimizer/util/var.c
+++ b/src/backend/optimizer/util/var.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* var.c--
- * Var node manipulation routines
+ * Var node manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.3 1996/11/06 09:29:26 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.4 1997/09/07 04:44:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,169 +27,193 @@
#include "parser/parsetree.h"
/*
- * find_varnos
+ * find_varnos
*
- * Descends down part of a parsetree (qual or tlist),
+ * Descends down part of a parsetree (qual or tlist),
*
- * XXX assumes varno's are always integers, which shouldn't be true...
- * (though it currently is, see primnodes.h)
+ * XXX assumes varno's are always integers, which shouldn't be true...
+ * (though it currently is, see primnodes.h)
*/
-List *
-pull_varnos(Node *me)
+List *
+pull_varnos(Node * me)
{
- List *i, *result = NIL;
-
- if (me == NULL)
- return (NIL);
-
- switch (nodeTag(me)) {
- case T_List:
- foreach (i, (List*)me) {
- result = nconc(result, pull_varnos(lfirst(i)));
+ List *i,
+ *result = NIL;
+
+ if (me == NULL)
+ return (NIL);
+
+ switch (nodeTag(me))
+ {
+ case T_List:
+ foreach(i, (List *) me)
+ {
+ result = nconc(result, pull_varnos(lfirst(i)));
+ }
+ break;
+ case T_ArrayRef:
+ foreach(i, ((ArrayRef *) me)->refupperindexpr)
+ result = nconc(result, pull_varnos(lfirst(i)));
+ foreach(i, ((ArrayRef *) me)->reflowerindexpr)
+ result = nconc(result, pull_varnos(lfirst(i)));
+ result = nconc(result, pull_varnos(((ArrayRef *) me)->refassgnexpr));
+ break;
+ case T_Var:
+ result = lconsi(((Var *) me)->varno, NIL);
+ break;
+ default:
+ break;
}
- break;
- case T_ArrayRef:
- foreach (i, ((ArrayRef*) me)->refupperindexpr)
- result = nconc(result, pull_varnos(lfirst(i)));
- foreach (i, ((ArrayRef*) me)->reflowerindexpr)
- result = nconc(result, pull_varnos(lfirst(i)));
- result = nconc(result, pull_varnos(((ArrayRef*) me)->refassgnexpr));
- break;
- case T_Var:
- result = lconsi(((Var*) me)->varno, NIL);
- break;
- default:
- break;
- }
- return(result);
+ return (result);
}
-/*
+/*
* contain_var_clause--
- * Recursively find var nodes from a clause by pulling vars from the
- * left and right operands of the clause.
- *
- * Returns true if any varnode found.
+ * Recursively find var nodes from a clause by pulling vars from the
+ * left and right operands of the clause.
+ *
+ * Returns true if any varnode found.
*/
-bool contain_var_clause(Node *clause)
+bool
+contain_var_clause(Node * clause)
{
- if (clause==NULL)
- return FALSE;
- else if (IsA(clause,Var))
- return TRUE;
- else if (IsA(clause,Iter))
- return contain_var_clause(((Iter*)clause)->iterexpr);
- else if (single_node(clause))
- return FALSE;
- else if (or_clause(clause)) {
- List *temp;
-
- foreach (temp, ((Expr*)clause)->args) {
- if (contain_var_clause(lfirst(temp)))
- return TRUE;
- }
- return FALSE;
- } else if (is_funcclause (clause)) {
- List *temp;
-
- foreach(temp, ((Expr *)clause)->args) {
- if (contain_var_clause(lfirst(temp)))
+ if (clause == NULL)
+ return FALSE;
+ else if (IsA(clause, Var))
return TRUE;
+ else if (IsA(clause, Iter))
+ return contain_var_clause(((Iter *) clause)->iterexpr);
+ else if (single_node(clause))
+ return FALSE;
+ else if (or_clause(clause))
+ {
+ List *temp;
+
+ foreach(temp, ((Expr *) clause)->args)
+ {
+ if (contain_var_clause(lfirst(temp)))
+ return TRUE;
+ }
+ return FALSE;
}
- return FALSE;
- } else if (IsA(clause,ArrayRef)) {
- List *temp;
-
- foreach(temp, ((ArrayRef*)clause)->refupperindexpr) {
- if (contain_var_clause(lfirst(temp)))
- return TRUE;
+ else if (is_funcclause(clause))
+ {
+ List *temp;
+
+ foreach(temp, ((Expr *) clause)->args)
+ {
+ if (contain_var_clause(lfirst(temp)))
+ return TRUE;
+ }
+ return FALSE;
}
- foreach(temp, ((ArrayRef*)clause)->reflowerindexpr) {
- if (contain_var_clause(lfirst(temp)))
- return TRUE;
+ else if (IsA(clause, ArrayRef))
+ {
+ List *temp;
+
+ foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
+ {
+ if (contain_var_clause(lfirst(temp)))
+ return TRUE;
+ }
+ foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
+ {
+ if (contain_var_clause(lfirst(temp)))
+ return TRUE;
+ }
+ if (contain_var_clause(((ArrayRef *) clause)->refexpr))
+ return TRUE;
+ if (contain_var_clause(((ArrayRef *) clause)->refassgnexpr))
+ return TRUE;
+ return FALSE;
}
- if (contain_var_clause(((ArrayRef*)clause)->refexpr))
- return TRUE;
- if (contain_var_clause(((ArrayRef*)clause)->refassgnexpr))
- return TRUE;
- return FALSE;
- } else if (not_clause(clause))
- return contain_var_clause((Node*)get_notclausearg((Expr*)clause));
- else if (is_opclause(clause))
- return (contain_var_clause((Node*)get_leftop((Expr*)clause)) ||
- contain_var_clause((Node*)get_rightop((Expr*)clause)));
+ else if (not_clause(clause))
+ return contain_var_clause((Node *) get_notclausearg((Expr *) clause));
+ else if (is_opclause(clause))
+ return (contain_var_clause((Node *) get_leftop((Expr *) clause)) ||
+ contain_var_clause((Node *) get_rightop((Expr *) clause)));
- return FALSE;
+ return FALSE;
}
-/*
+/*
* pull_var_clause--
- * Recursively pulls all var nodes from a clause by pulling vars from the
- * left and right operands of the clause.
- *
- * Returns list of varnodes found.
+ * Recursively pulls all var nodes from a clause by pulling vars from the
+ * left and right operands of the clause.
+ *
+ * Returns list of varnodes found.
*/
-List *
-pull_var_clause(Node *clause)
+List *
+pull_var_clause(Node * clause)
{
- List *retval = NIL;
-
- if (clause==NULL)
- return(NIL);
- else if (IsA(clause,Var))
- retval = lcons(clause,NIL);
- else if (IsA(clause,Iter))
- retval = pull_var_clause(((Iter*)clause)->iterexpr);
- else if (single_node(clause))
- retval = NIL;
- else if (or_clause(clause)) {
- List *temp;
-
- foreach (temp, ((Expr*)clause)->args)
- retval = nconc(retval, pull_var_clause(lfirst(temp)));
- } else if (is_funcclause (clause)) {
- List *temp;
-
- foreach(temp, ((Expr *)clause)->args)
- retval = nconc (retval,pull_var_clause(lfirst(temp)));
- } else if (IsA(clause,Aggreg)) {
- retval = pull_var_clause(((Aggreg*)clause)->target);
- } else if (IsA(clause,ArrayRef)) {
- List *temp;
-
- foreach(temp, ((ArrayRef*)clause)->refupperindexpr)
- retval = nconc (retval,pull_var_clause(lfirst(temp)));
- foreach(temp, ((ArrayRef*)clause)->reflowerindexpr)
- retval = nconc (retval,pull_var_clause(lfirst(temp)));
- retval = nconc(retval,
- pull_var_clause(((ArrayRef*)clause)->refexpr));
- retval = nconc(retval,
- pull_var_clause(((ArrayRef*)clause)->refassgnexpr));
- } else if (not_clause(clause))
- retval = pull_var_clause((Node*)get_notclausearg((Expr*)clause));
- else if (is_opclause(clause))
- retval = nconc(pull_var_clause((Node*)get_leftop((Expr*)clause)),
- pull_var_clause((Node*)get_rightop((Expr*)clause)));
- else
- retval = NIL;
-
- return (retval);
+ List *retval = NIL;
+
+ if (clause == NULL)
+ return (NIL);
+ else if (IsA(clause, Var))
+ retval = lcons(clause, NIL);
+ else if (IsA(clause, Iter))
+ retval = pull_var_clause(((Iter *) clause)->iterexpr);
+ else if (single_node(clause))
+ retval = NIL;
+ else if (or_clause(clause))
+ {
+ List *temp;
+
+ foreach(temp, ((Expr *) clause)->args)
+ retval = nconc(retval, pull_var_clause(lfirst(temp)));
+ }
+ else if (is_funcclause(clause))
+ {
+ List *temp;
+
+ foreach(temp, ((Expr *) clause)->args)
+ retval = nconc(retval, pull_var_clause(lfirst(temp)));
+ }
+ else if (IsA(clause, Aggreg))
+ {
+ retval = pull_var_clause(((Aggreg *) clause)->target);
+ }
+ else if (IsA(clause, ArrayRef))
+ {
+ List *temp;
+
+ foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
+ retval = nconc(retval, pull_var_clause(lfirst(temp)));
+ foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
+ retval = nconc(retval, pull_var_clause(lfirst(temp)));
+ retval = nconc(retval,
+ pull_var_clause(((ArrayRef *) clause)->refexpr));
+ retval = nconc(retval,
+ pull_var_clause(((ArrayRef *) clause)->refassgnexpr));
+ }
+ else if (not_clause(clause))
+ retval = pull_var_clause((Node *) get_notclausearg((Expr *) clause));
+ else if (is_opclause(clause))
+ retval = nconc(pull_var_clause((Node *) get_leftop((Expr *) clause)),
+ pull_var_clause((Node *) get_rightop((Expr *) clause)));
+ else
+ retval = NIL;
+
+ return (retval);
}
-/*
- * var_equal
- *
- * Returns t iff two var nodes correspond to the same attribute.
+/*
+ * var_equal
+ *
+ * Returns t iff two var nodes correspond to the same attribute.
*/
bool
-var_equal(Var *var1, Var *var2)
+var_equal(Var * var1, Var * var2)
{
- if (IsA (var1,Var) && IsA (var2,Var) &&
- (((Var*)var1)->varno == ((Var*)var2)->varno) &&
- (((Var*)var1)->vartype == ((Var*)var2)->vartype) &&
- (((Var*)var1)->varattno == ((Var*)var2)->varattno)) {
-
- return(true);
- } else
- return(false);
+ if (IsA(var1, Var) && IsA(var2, Var) &&
+ (((Var *) var1)->varno == ((Var *) var2)->varno) &&
+ (((Var *) var1)->vartype == ((Var *) var2)->vartype) &&
+ (((Var *) var1)->varattno == ((Var *) var2)->varattno))
+ {
+
+ return (true);
+ }
+ else
+ return (false);
}
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index a78d2c5c70e..8f63522812e 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* analyze.c--
- * transform the parse tree into a query tree
+ * transform the parse tree into a query tree
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.38 1997/09/05 19:32:31 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.39 1997/09/07 04:44:38 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,11 +20,11 @@
#include "nodes/primnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/relation.h"
-#include "parse.h" /* for AND, OR, etc. */
+#include "parse.h" /* for AND, OR, etc. */
#include "catalog/pg_type.h" /* for INT4OID, etc. */
#include "catalog/pg_proc.h"
#include "utils/elog.h"
-#include "utils/builtins.h" /* namecmp(), textout() */
+#include "utils/builtins.h" /* namecmp(), textout() */
#include "utils/lsyscache.h"
#include "utils/palloc.h"
#include "utils/mcxt.h"
@@ -41,502 +41,519 @@
#include "miscadmin.h"
-#include "port-protos.h" /* strdup() */
+#include "port-protos.h" /* strdup() */
/* convert the parse tree into a query tree */
-static Query *transformStmt(ParseState *pstate, Node *stmt);
-
-static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
-static Query *transformInsertStmt(ParseState *pstate, AppendStmt *stmt);
-static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
-static Query *transformExtendStmt(ParseState *pstate, ExtendStmt *stmt);
-static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
-static Query *transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt);
-static Query *transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt);
-static Query *transformCursorStmt(ParseState *pstate, CursorStmt *stmt);
-static Node *handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno);
-
-#define EXPR_COLUMN_FIRST 1
+static Query *transformStmt(ParseState * pstate, Node * stmt);
+
+static Query *transformDeleteStmt(ParseState * pstate, DeleteStmt * stmt);
+static Query *transformInsertStmt(ParseState * pstate, AppendStmt * stmt);
+static Query *transformIndexStmt(ParseState * pstate, IndexStmt * stmt);
+static Query *transformExtendStmt(ParseState * pstate, ExtendStmt * stmt);
+static Query *transformRuleStmt(ParseState * query, RuleStmt * stmt);
+static Query *transformSelectStmt(ParseState * pstate, RetrieveStmt * stmt);
+static Query *transformUpdateStmt(ParseState * pstate, ReplaceStmt * stmt);
+static Query *transformCursorStmt(ParseState * pstate, CursorStmt * stmt);
+static Node *handleNestedDots(ParseState * pstate, Attr * attr, int *curr_resno);
+
+#define EXPR_COLUMN_FIRST 1
#define EXPR_RELATION_FIRST 2
-static Node *transformExpr(ParseState *pstate, Node *expr, int precedence);
-static Node *transformIdent(ParseState *pstate, Node *expr, int precedence);
-
-static void makeRangeTable(ParseState *pstate, char *relname, List *frmList);
-static List *expandAllTables(ParseState *pstate);
-static char *figureColname(Node *expr, Node *resval);
-static List *makeTargetNames(ParseState *pstate, List *cols);
-static List *transformTargetList(ParseState *pstate, List *targetlist);
-static TargetEntry *make_targetlist_expr(ParseState *pstate,
- char *colname, Node *expr,
- List *arrayRef);
-static bool inWhereClause = false;
-static Node *transformWhereClause(ParseState *pstate, Node *a_expr);
-static List *transformGroupClause(ParseState *pstate, List *grouplist,
- List *targetlist);
-static List *transformSortClause(ParseState *pstate,
- List *orderlist, List *targetlist,
- char* uniqueFlag);
-
-static void parseFromClause(ParseState *pstate, List *frmList);
-static Node *ParseFunc(ParseState *pstate, char *funcname,
- List *fargs, int *curr_resno);
-static List *setup_tlist(char *attname, Oid relid);
-static List *setup_base_tlist(Oid typeid);
-static void make_arguments(int nargs, List *fargs, Oid *input_typeids,
- Oid *function_typeids);
-static void AddAggToParseState(ParseState *pstate, Aggreg *aggreg);
-static void finalizeAggregates(ParseState *pstate, Query *qry);
-static void parseCheckAggregates(ParseState *pstate, Query *qry);
-static ParseState* makeParseState(void);
+static Node *transformExpr(ParseState * pstate, Node * expr, int precedence);
+static Node *transformIdent(ParseState * pstate, Node * expr, int precedence);
+
+static void makeRangeTable(ParseState * pstate, char *relname, List * frmList);
+static List *expandAllTables(ParseState * pstate);
+static char *figureColname(Node * expr, Node * resval);
+static List *makeTargetNames(ParseState * pstate, List * cols);
+static List *transformTargetList(ParseState * pstate, List * targetlist);
+static TargetEntry *
+make_targetlist_expr(ParseState * pstate,
+ char *colname, Node * expr,
+ List * arrayRef);
+static bool inWhereClause = false;
+static Node *transformWhereClause(ParseState * pstate, Node * a_expr);
+static List *
+transformGroupClause(ParseState * pstate, List * grouplist,
+ List * targetlist);
+static List *
+transformSortClause(ParseState * pstate,
+ List * orderlist, List * targetlist,
+ char *uniqueFlag);
+
+static void parseFromClause(ParseState * pstate, List * frmList);
+static Node *
+ParseFunc(ParseState * pstate, char *funcname,
+ List * fargs, int *curr_resno);
+static List *setup_tlist(char *attname, Oid relid);
+static List *setup_base_tlist(Oid typeid);
+static void
+make_arguments(int nargs, List * fargs, Oid * input_typeids,
+ Oid * function_typeids);
+static void AddAggToParseState(ParseState * pstate, Aggreg * aggreg);
+static void finalizeAggregates(ParseState * pstate, Query * qry);
+static void parseCheckAggregates(ParseState * pstate, Query * qry);
+static ParseState *makeParseState(void);
/*****************************************************************************
*
*****************************************************************************/
/*
- * makeParseState() --
- * allocate and initialize a new ParseState.
- * the CALLERS is responsible for freeing the ParseState* returned
+ * makeParseState() --
+ * allocate and initialize a new ParseState.
+ * the CALLERS is responsible for freeing the ParseState* returned
*
*/
-static ParseState*
+static ParseState *
makeParseState(void)
{
- ParseState *pstate;
-
- pstate = malloc(sizeof(ParseState));
- pstate->p_last_resno = 1;
- pstate->p_rtable = NIL;
- pstate->p_numAgg = 0;
- pstate->p_aggs = NIL;
- pstate->p_is_insert = false;
- pstate->p_insert_columns = NIL;
- pstate->p_is_update = false;
- pstate->p_is_rule = false;
- pstate->p_target_relation = NULL;
- pstate->p_target_rangetblentry = NULL;
-
- return (pstate);
+ ParseState *pstate;
+
+ pstate = malloc(sizeof(ParseState));
+ pstate->p_last_resno = 1;
+ pstate->p_rtable = NIL;
+ pstate->p_numAgg = 0;
+ pstate->p_aggs = NIL;
+ pstate->p_is_insert = false;
+ pstate->p_insert_columns = NIL;
+ pstate->p_is_update = false;
+ pstate->p_is_rule = false;
+ pstate->p_target_relation = NULL;
+ pstate->p_target_rangetblentry = NULL;
+
+ return (pstate);
}
/*
* parse_analyze -
- * analyze a list of parse trees and transform them if necessary.
+ * analyze a list of parse trees and transform them if necessary.
*
* Returns a list of transformed parse trees. Optimizable statements are
* all transformed to Query while the rest stays the same.
*
* CALLER is responsible for freeing the QueryTreeList* returned
*/
-QueryTreeList *
-parse_analyze(List *pl)
+QueryTreeList *
+parse_analyze(List * pl)
{
- QueryTreeList *result;
- ParseState *pstate;
- int i = 0;
-
- result = malloc(sizeof(QueryTreeList));
- result->len = length(pl);
- result->qtrees = (Query**)malloc(result->len * sizeof(Query*));
-
- inWhereClause = false; /* to avoid nextval(sequence) in WHERE */
-
- while(pl!=NIL) {
- pstate = makeParseState();
- result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
- pl = lnext(pl);
- if (pstate->p_target_relation != NULL)
- heap_close(pstate->p_target_relation);
- free(pstate);
- }
-
- return result;
+ QueryTreeList *result;
+ ParseState *pstate;
+ int i = 0;
+
+ result = malloc(sizeof(QueryTreeList));
+ result->len = length(pl);
+ result->qtrees = (Query **) malloc(result->len * sizeof(Query *));
+
+ inWhereClause = false; /* to avoid nextval(sequence) in WHERE */
+
+ while (pl != NIL)
+ {
+ pstate = makeParseState();
+ result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
+ pl = lnext(pl);
+ if (pstate->p_target_relation != NULL)
+ heap_close(pstate->p_target_relation);
+ free(pstate);
+ }
+
+ return result;
}
/*
* transformStmt -
- * transform a Parse tree. If it is an optimizable statement, turn it
- * into a Query tree.
+ * transform a Parse tree. If it is an optimizable statement, turn it
+ * into a Query tree.
*/
-static Query *
-transformStmt(ParseState* pstate, Node *parseTree)
+static Query *
+transformStmt(ParseState * pstate, Node * parseTree)
{
- Query* result = NULL;
-
- switch(nodeTag(parseTree)) {
- /*------------------------
- * Non-optimizable statements
- *------------------------
- */
- case T_IndexStmt:
- result = transformIndexStmt(pstate, (IndexStmt *)parseTree);
- break;
-
- case T_ExtendStmt:
- result = transformExtendStmt(pstate, (ExtendStmt *)parseTree);
- break;
-
- case T_RuleStmt:
- result = transformRuleStmt(pstate, (RuleStmt *)parseTree);
- break;
-
- case T_ViewStmt:
- {
- ViewStmt *n = (ViewStmt *)parseTree;
- n->query = (Query *)transformStmt(pstate, (Node*)n->query);
- result = makeNode(Query);
- result->commandType = CMD_UTILITY;
- result->utilityStmt = (Node*)n;
- }
- break;
-
- case T_VacuumStmt:
- {
- MemoryContext oldcontext;
- /* make sure that this Query is allocated in TopMemory context
- because vacuum spans transactions and we don't want to lose
- the vacuum Query due to end-of-transaction free'ing*/
- oldcontext = MemoryContextSwitchTo(TopMemoryContext);
- result = makeNode(Query);
- result->commandType = CMD_UTILITY;
- result->utilityStmt = (Node*)parseTree;
- MemoryContextSwitchTo(oldcontext);
- break;
-
- }
- case T_ExplainStmt:
- {
- ExplainStmt *n = (ExplainStmt *)parseTree;
- result = makeNode(Query);
- result->commandType = CMD_UTILITY;
- n->query = transformStmt(pstate, (Node*)n->query);
- result->utilityStmt = (Node*)parseTree;
- }
- break;
-
- /*------------------------
- * Optimizable statements
- *------------------------
- */
- case T_AppendStmt:
- result = transformInsertStmt(pstate, (AppendStmt *)parseTree);
- break;
-
- case T_DeleteStmt:
- result = transformDeleteStmt(pstate, (DeleteStmt *)parseTree);
- break;
-
- case T_ReplaceStmt:
- result = transformUpdateStmt(pstate, (ReplaceStmt *)parseTree);
- break;
-
- case T_CursorStmt:
- result = transformCursorStmt(pstate, (CursorStmt *)parseTree);
- break;
-
- case T_RetrieveStmt:
- result = transformSelectStmt(pstate, (RetrieveStmt *)parseTree);
- break;
-
- default:
- /*
- * other statments don't require any transformation-- just
- * return the original parsetree
- */
- result = makeNode(Query);
- result->commandType = CMD_UTILITY;
- result->utilityStmt = (Node*)parseTree;
- break;
- }
- return result;
+ Query *result = NULL;
+
+ switch (nodeTag(parseTree))
+ {
+ /*------------------------
+ * Non-optimizable statements
+ *------------------------
+ */
+ case T_IndexStmt:
+ result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
+ break;
+
+ case T_ExtendStmt:
+ result = transformExtendStmt(pstate, (ExtendStmt *) parseTree);
+ break;
+
+ case T_RuleStmt:
+ result = transformRuleStmt(pstate, (RuleStmt *) parseTree);
+ break;
+
+ case T_ViewStmt:
+ {
+ ViewStmt *n = (ViewStmt *) parseTree;
+
+ n->query = (Query *) transformStmt(pstate, (Node *) n->query);
+ result = makeNode(Query);
+ result->commandType = CMD_UTILITY;
+ result->utilityStmt = (Node *) n;
+ }
+ break;
+
+ case T_VacuumStmt:
+ {
+ MemoryContext oldcontext;
+
+ /*
+ * make sure that this Query is allocated in TopMemory context
+ * because vacuum spans transactions and we don't want to lose
+ * the vacuum Query due to end-of-transaction free'ing
+ */
+ oldcontext = MemoryContextSwitchTo(TopMemoryContext);
+ result = makeNode(Query);
+ result->commandType = CMD_UTILITY;
+ result->utilityStmt = (Node *) parseTree;
+ MemoryContextSwitchTo(oldcontext);
+ break;
+
+ }
+ case T_ExplainStmt:
+ {
+ ExplainStmt *n = (ExplainStmt *) parseTree;
+
+ result = makeNode(Query);
+ result->commandType = CMD_UTILITY;
+ n->query = transformStmt(pstate, (Node *) n->query);
+ result->utilityStmt = (Node *) parseTree;
+ }
+ break;
+
+ /*------------------------
+ * Optimizable statements
+ *------------------------
+ */
+ case T_AppendStmt:
+ result = transformInsertStmt(pstate, (AppendStmt *) parseTree);
+ break;
+
+ case T_DeleteStmt:
+ result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
+ break;
+
+ case T_ReplaceStmt:
+ result = transformUpdateStmt(pstate, (ReplaceStmt *) parseTree);
+ break;
+
+ case T_CursorStmt:
+ result = transformCursorStmt(pstate, (CursorStmt *) parseTree);
+ break;
+
+ case T_RetrieveStmt:
+ result = transformSelectStmt(pstate, (RetrieveStmt *) parseTree);
+ break;
+
+ default:
+
+ /*
+ * other statments don't require any transformation-- just return
+ * the original parsetree
+ */
+ result = makeNode(Query);
+ result->commandType = CMD_UTILITY;
+ result->utilityStmt = (Node *) parseTree;
+ break;
+ }
+ return result;
}
/*
* transformDeleteStmt -
- * transforms a Delete Statement
+ * transforms a Delete Statement
*/
-static Query *
-transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
+static Query *
+transformDeleteStmt(ParseState * pstate, DeleteStmt * stmt)
{
- Query *qry = makeNode(Query);
+ Query *qry = makeNode(Query);
- qry->commandType = CMD_DELETE;
+ qry->commandType = CMD_DELETE;
- /* set up a range table */
- makeRangeTable(pstate, stmt->relname, NULL);
-
- qry->uniqueFlag = NULL;
+ /* set up a range table */
+ makeRangeTable(pstate, stmt->relname, NULL);
- /* fix where clause */
- qry->qual = transformWhereClause(pstate, stmt->whereClause);
+ qry->uniqueFlag = NULL;
- qry->rtable = pstate->p_rtable;
- qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
+ /* fix where clause */
+ qry->qual = transformWhereClause(pstate, stmt->whereClause);
- /* make sure we don't have aggregates in the where clause */
- if (pstate->p_numAgg > 0)
- parseCheckAggregates(pstate, qry);
+ qry->rtable = pstate->p_rtable;
+ qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
+
+ /* make sure we don't have aggregates in the where clause */
+ if (pstate->p_numAgg > 0)
+ parseCheckAggregates(pstate, qry);
- return (Query *)qry;
+ return (Query *) qry;
}
/*
* transformInsertStmt -
- * transform an Insert Statement
+ * transform an Insert Statement
*/
-static Query *
-transformInsertStmt(ParseState *pstate, AppendStmt *stmt)
+static Query *
+transformInsertStmt(ParseState * pstate, AppendStmt * stmt)
{
- Query *qry = makeNode(Query); /* make a new query tree */
+ Query *qry = makeNode(Query); /* make a new query tree */
- qry->commandType = CMD_INSERT;
- pstate->p_is_insert = true;
+ qry->commandType = CMD_INSERT;
+ pstate->p_is_insert = true;
- /* set up a range table */
- makeRangeTable(pstate, stmt->relname, stmt->fromClause);
+ /* set up a range table */
+ makeRangeTable(pstate, stmt->relname, stmt->fromClause);
- qry->uniqueFlag = NULL;
+ qry->uniqueFlag = NULL;
- /* fix the target list */
- pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
+ /* fix the target list */
+ pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
- qry->targetList = transformTargetList(pstate, stmt->targetList);
+ qry->targetList = transformTargetList(pstate, stmt->targetList);
- /* fix where clause */
- qry->qual = transformWhereClause(pstate, stmt->whereClause);
+ /* fix where clause */
+ qry->qual = transformWhereClause(pstate, stmt->whereClause);
- /* now the range table will not change */
- qry->rtable = pstate->p_rtable;
- qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
+ /* now the range table will not change */
+ qry->rtable = pstate->p_rtable;
+ qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
- if (pstate->p_numAgg > 0)
- finalizeAggregates(pstate, qry);
+ if (pstate->p_numAgg > 0)
+ finalizeAggregates(pstate, qry);
- return (Query *)qry;
+ return (Query *) qry;
}
/*
* transformIndexStmt -
- * transforms the qualification of the index statement
+ * transforms the qualification of the index statement
*/
-static Query *
-transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
+static Query *
+transformIndexStmt(ParseState * pstate, IndexStmt * stmt)
{
- Query* q;
+ Query *q;
- q = makeNode(Query);
- q->commandType = CMD_UTILITY;
-
- /* take care of the where clause */
- stmt->whereClause = transformWhereClause(pstate,stmt->whereClause);
- stmt->rangetable = pstate->p_rtable;
+ q = makeNode(Query);
+ q->commandType = CMD_UTILITY;
- q->utilityStmt = (Node*)stmt;
+ /* take care of the where clause */
+ stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
+ stmt->rangetable = pstate->p_rtable;
- return q;
+ q->utilityStmt = (Node *) stmt;
+
+ return q;
}
/*
* transformExtendStmt -
- * transform the qualifications of the Extend Index Statement
+ * transform the qualifications of the Extend Index Statement
*
*/
-static Query *
-transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
+static Query *
+transformExtendStmt(ParseState * pstate, ExtendStmt * stmt)
{
- Query *q;
+ Query *q;
- q = makeNode(Query);
- q->commandType = CMD_UTILITY;
+ q = makeNode(Query);
+ q->commandType = CMD_UTILITY;
- /* take care of the where clause */
- stmt->whereClause = transformWhereClause(pstate,stmt->whereClause);
- stmt->rangetable = pstate->p_rtable;
+ /* take care of the where clause */
+ stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
+ stmt->rangetable = pstate->p_rtable;
- q->utilityStmt = (Node*)stmt;
- return q;
+ q->utilityStmt = (Node *) stmt;
+ return q;
}
/*
* transformRuleStmt -
- * transform a Create Rule Statement. The actions is a list of parse
- * trees which is transformed into a list of query trees.
+ * transform a Create Rule Statement. The actions is a list of parse
+ * trees which is transformed into a list of query trees.
*/
-static Query *
-transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
+static Query *
+transformRuleStmt(ParseState * pstate, RuleStmt * stmt)
{
- Query *q;
- List *actions;
-
- q = makeNode(Query);
- q->commandType = CMD_UTILITY;
-
- actions = stmt->actions;
- /*
- * transform each statment, like parse_analyze()
- */
- while (actions != NIL) {
+ Query *q;
+ List *actions;
+
+ q = makeNode(Query);
+ q->commandType = CMD_UTILITY;
+
+ actions = stmt->actions;
+
/*
- * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
- * equal to 2.
+ * transform each statment, like parse_analyze()
*/
- addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
- FALSE, FALSE, NULL);
- addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
- FALSE, FALSE, NULL);
+ while (actions != NIL)
+ {
- pstate->p_last_resno = 1;
- pstate->p_is_rule = true; /* for expand all */
- pstate->p_numAgg = 0;
- pstate->p_aggs = NULL;
-
- lfirst(actions) = transformStmt(pstate, lfirst(actions));
- actions = lnext(actions);
- }
+ /*
+ * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
+ * equal to 2.
+ */
+ addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
+ FALSE, FALSE, NULL);
+ addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
+ FALSE, FALSE, NULL);
+
+ pstate->p_last_resno = 1;
+ pstate->p_is_rule = true; /* for expand all */
+ pstate->p_numAgg = 0;
+ pstate->p_aggs = NULL;
+
+ lfirst(actions) = transformStmt(pstate, lfirst(actions));
+ actions = lnext(actions);
+ }
- /* take care of the where clause */
- stmt->whereClause = transformWhereClause(pstate,stmt->whereClause);
+ /* take care of the where clause */
+ stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
- q->utilityStmt = (Node*)stmt;
- return q;
+ q->utilityStmt = (Node *) stmt;
+ return q;
}
/*
* transformSelectStmt -
- * transforms a Select Statement
+ * transforms a Select Statement
*
*/
-static Query *
-transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt)
+static Query *
+transformSelectStmt(ParseState * pstate, RetrieveStmt * stmt)
{
- Query *qry = makeNode(Query);
+ Query *qry = makeNode(Query);
+
+ qry->commandType = CMD_SELECT;
- qry->commandType = CMD_SELECT;
+ /* set up a range table */
+ makeRangeTable(pstate, NULL, stmt->fromClause);
- /* set up a range table */
- makeRangeTable(pstate, NULL, stmt->fromClause);
+ qry->uniqueFlag = stmt->unique;
- qry->uniqueFlag = stmt->unique;
+ qry->into = stmt->into;
+ qry->isPortal = FALSE;
- qry->into = stmt->into;
- qry->isPortal = FALSE;
+ /* fix the target list */
+ qry->targetList = transformTargetList(pstate, stmt->targetList);
- /* fix the target list */
- qry->targetList = transformTargetList(pstate, stmt->targetList);
+ /* fix where clause */
+ qry->qual = transformWhereClause(pstate, stmt->whereClause);
- /* fix where clause */
- qry->qual = transformWhereClause(pstate,stmt->whereClause);
+ /* check subselect clause */
+ if (stmt->selectClause)
+ elog(NOTICE, "UNION not yet supported; using first SELECT only", NULL);
- /* check subselect clause */
- if (stmt->selectClause)
- elog(NOTICE,"UNION not yet supported; using first SELECT only",NULL);
+ /* check subselect clause */
+ if (stmt->havingClause)
+ elog(NOTICE, "HAVING not yet supported; ignore clause", NULL);
- /* check subselect clause */
- if (stmt->havingClause)
- elog(NOTICE,"HAVING not yet supported; ignore clause",NULL);
+ /* fix order clause */
+ qry->sortClause = transformSortClause(pstate,
+ stmt->sortClause,
+ qry->targetList,
+ qry->uniqueFlag);
- /* fix order clause */
- qry->sortClause = transformSortClause(pstate,
- stmt->sortClause,
- qry->targetList,
- qry->uniqueFlag);
+ /* fix group by clause */
+ qry->groupClause = transformGroupClause(pstate,
+ stmt->groupClause,
+ qry->targetList);
+ qry->rtable = pstate->p_rtable;
- /* fix group by clause */
- qry->groupClause = transformGroupClause(pstate,
- stmt->groupClause,
- qry->targetList);
- qry->rtable = pstate->p_rtable;
+ if (pstate->p_numAgg > 0)
+ finalizeAggregates(pstate, qry);
- if (pstate->p_numAgg > 0)
- finalizeAggregates(pstate, qry);
-
- return (Query *)qry;
+ return (Query *) qry;
}
/*
* transformUpdateStmt -
- * transforms an update statement
+ * transforms an update statement
*
*/
-static Query *
-transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt)
+static Query *
+transformUpdateStmt(ParseState * pstate, ReplaceStmt * stmt)
{
- Query *qry = makeNode(Query);
+ Query *qry = makeNode(Query);
+
+ qry->commandType = CMD_UPDATE;
+ pstate->p_is_update = true;
- qry->commandType = CMD_UPDATE;
- pstate->p_is_update = true;
- /*
- * the FROM clause is non-standard SQL syntax. We used to be able to
- * do this with REPLACE in POSTQUEL so we keep the feature.
- */
- makeRangeTable(pstate, stmt->relname, stmt->fromClause);
+ /*
+ * the FROM clause is non-standard SQL syntax. We used to be able to
+ * do this with REPLACE in POSTQUEL so we keep the feature.
+ */
+ makeRangeTable(pstate, stmt->relname, stmt->fromClause);
- /* fix the target list */
- qry->targetList = transformTargetList(pstate, stmt->targetList);
+ /* fix the target list */
+ qry->targetList = transformTargetList(pstate, stmt->targetList);
- /* fix where clause */
- qry->qual = transformWhereClause(pstate,stmt->whereClause);
+ /* fix where clause */
+ qry->qual = transformWhereClause(pstate, stmt->whereClause);
- qry->rtable = pstate->p_rtable;
- qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
+ qry->rtable = pstate->p_rtable;
+ qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
- /* make sure we don't have aggregates in the where clause */
- if (pstate->p_numAgg > 0)
- parseCheckAggregates(pstate, qry);
+ /* make sure we don't have aggregates in the where clause */
+ if (pstate->p_numAgg > 0)
+ parseCheckAggregates(pstate, qry);
- return (Query *)qry;
+ return (Query *) qry;
}
/*
* transformCursorStmt -
- * transform a Create Cursor Statement
+ * transform a Create Cursor Statement
*
*/
-static Query *
-transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
+static Query *
+transformCursorStmt(ParseState * pstate, CursorStmt * stmt)
{
- Query *qry = makeNode(Query);
+ Query *qry = makeNode(Query);
- /*
- * in the old days, a cursor statement is a 'retrieve into portal';
- * If you change the following, make sure you also go through the code
- * in various places that tests the kind of operation.
- */
- qry->commandType = CMD_SELECT;
+ /*
+ * in the old days, a cursor statement is a 'retrieve into portal'; If
+ * you change the following, make sure you also go through the code in
+ * various places that tests the kind of operation.
+ */
+ qry->commandType = CMD_SELECT;
- /* set up a range table */
- makeRangeTable(pstate, NULL, stmt->fromClause);
+ /* set up a range table */
+ makeRangeTable(pstate, NULL, stmt->fromClause);
- qry->uniqueFlag = stmt->unique;
+ qry->uniqueFlag = stmt->unique;
- qry->into = stmt->portalname;
- qry->isPortal = TRUE;
- qry->isBinary = stmt->binary; /* internal portal */
+ qry->into = stmt->portalname;
+ qry->isPortal = TRUE;
+ qry->isBinary = stmt->binary; /* internal portal */
- /* fix the target list */
- qry->targetList = transformTargetList(pstate, stmt->targetList);
+ /* fix the target list */
+ qry->targetList = transformTargetList(pstate, stmt->targetList);
- /* fix where clause */
- qry->qual = transformWhereClause(pstate,stmt->whereClause);
+ /* fix where clause */
+ qry->qual = transformWhereClause(pstate, stmt->whereClause);
- /* fix order clause */
- qry->sortClause = transformSortClause(pstate,
- stmt->sortClause,
- qry->targetList,
- qry->uniqueFlag);
- /* fix group by clause */
- qry->groupClause = transformGroupClause(pstate,
- stmt->groupClause,
- qry->targetList);
+ /* fix order clause */
+ qry->sortClause = transformSortClause(pstate,
+ stmt->sortClause,
+ qry->targetList,
+ qry->uniqueFlag);
+ /* fix group by clause */
+ qry->groupClause = transformGroupClause(pstate,
+ stmt->groupClause,
+ qry->targetList);
- qry->rtable = pstate->p_rtable;
+ qry->rtable = pstate->p_rtable;
- if (pstate->p_numAgg > 0)
- finalizeAggregates(pstate, qry);
+ if (pstate->p_numAgg > 0)
+ finalizeAggregates(pstate, qry);
- return (Query *)qry;
+ return (Query *) qry;
}
/*****************************************************************************
@@ -547,236 +564,278 @@ transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
/*
* transformExpr -
- * analyze and transform expressions. Type checking and type casting is
- * done here. The optimizer and the executor cannot handle the original
- * (raw) expressions collected by the parse tree. Hence the transformation
- * here.
+ * analyze and transform expressions. Type checking and type casting is
+ * done here. The optimizer and the executor cannot handle the original
+ * (raw) expressions collected by the parse tree. Hence the transformation
+ * here.
*/
-static Node *
-transformExpr(ParseState *pstate, Node *expr, int precedence)
+static Node *
+transformExpr(ParseState * pstate, Node * expr, int precedence)
{
- Node *result = NULL;
+ Node *result = NULL;
- if (expr==NULL)
- return NULL;
-
- switch(nodeTag(expr)) {
- case T_Attr: {
- Attr *att = (Attr *)expr;
- Node *temp;
-
- /* what if att.attrs == "*"?? */
- temp = handleNestedDots(pstate, att, &pstate->p_last_resno);
- if (att->indirection != NIL) {
- List *idx = att->indirection;
- while(idx!=NIL) {
- A_Indices *ai = (A_Indices *)lfirst(idx);
- Node *lexpr=NULL, *uexpr;
- uexpr = transformExpr(pstate, ai->uidx, precedence); /* must exists */
- if (exprType(uexpr) != INT4OID)
- elog(WARN, "array index expressions must be int4's");
- if (ai->lidx != NULL) {
- lexpr = transformExpr(pstate, ai->lidx, precedence);
- if (exprType(lexpr) != INT4OID)
- elog(WARN, "array index expressions must be int4's");
- }
+ if (expr == NULL)
+ return NULL;
+
+ switch (nodeTag(expr))
+ {
+ case T_Attr:
+ {
+ Attr *att = (Attr *) expr;
+ Node *temp;
+
+ /* what if att.attrs == "*"?? */
+ temp = handleNestedDots(pstate, att, &pstate->p_last_resno);
+ if (att->indirection != NIL)
+ {
+ List *idx = att->indirection;
+
+ while (idx != NIL)
+ {
+ A_Indices *ai = (A_Indices *) lfirst(idx);
+ Node *lexpr = NULL,
+ *uexpr;
+
+ uexpr = transformExpr(pstate, ai->uidx, precedence); /* must exists */
+ if (exprType(uexpr) != INT4OID)
+ elog(WARN, "array index expressions must be int4's");
+ if (ai->lidx != NULL)
+ {
+ lexpr = transformExpr(pstate, ai->lidx, precedence);
+ if (exprType(lexpr) != INT4OID)
+ elog(WARN, "array index expressions must be int4's");
+ }
#if 0
- pfree(ai->uidx);
- if (ai->lidx!=NULL) pfree(ai->lidx);
+ pfree(ai->uidx);
+ if (ai->lidx != NULL)
+ pfree(ai->lidx);
#endif
- ai->lidx = lexpr;
- ai->uidx = uexpr;
- /* note we reuse the list of indices, make sure we don't free
- them! Otherwise, make a new list here */
- idx = lnext(idx);
- }
- result = (Node*)make_array_ref(temp, att->indirection);
- }else {
- result = temp;
- }
- break;
- }
- case T_A_Const: {
- A_Const *con= (A_Const *)expr;
- Value *val = &con->val;
- if (con->typename != NULL) {
- result = parser_typecast(val, con->typename, -1);
- }else {
- result = (Node *)make_const(val);
- }
- break;
- }
- case T_ParamNo: {
- ParamNo *pno = (ParamNo *)expr;
- Oid toid;
- int paramno;
- Param *param;
-
- paramno = pno->number;
- toid = param_type(paramno);
- if (!OidIsValid(toid)) {
- elog(WARN, "Parameter '$%d' is out of range",
- paramno);
- }
- param = makeNode(Param);
- param->paramkind = PARAM_NUM;
- param->paramid = (AttrNumber) paramno;
- param->paramname = "<unnamed>";
- param->paramtype = (Oid)toid;
- param->param_tlist = (List*) NULL;
-
- result = (Node *)param;
- break;
- }
- case T_A_Expr: {
- A_Expr *a = (A_Expr *)expr;
-
- switch(a->oper) {
- case OP:
- {
- Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
- Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
- result = (Node *)make_op(a->opname, lexpr, rexpr);
- }
- break;
- case ISNULL:
- {
- Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
- result = ParseFunc(pstate,
- "nullvalue", lcons(lexpr, NIL),
- &pstate->p_last_resno);
- }
- break;
- case NOTNULL:
- {
- Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
- result = ParseFunc(pstate,
- "nonnullvalue", lcons(lexpr, NIL),
- &pstate->p_last_resno);
- }
- break;
- case AND:
- {
- Expr *expr = makeNode(Expr);
- Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
- Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
- if (exprType(lexpr) != BOOLOID)
- elog(WARN,
- "left-hand side of AND is type '%s', not bool",
- tname(get_id_type(exprType(lexpr))));
- if (exprType(rexpr) != BOOLOID)
- elog(WARN,
- "right-hand side of AND is type '%s', not bool",
- tname(get_id_type(exprType(rexpr))));
- expr->typeOid = BOOLOID;
- expr->opType = AND_EXPR;
- expr->args = makeList(lexpr, rexpr, -1);
- result = (Node *)expr;
- }
- break;
- case OR:
- {
- Expr *expr = makeNode(Expr);
- Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
- Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
- if (exprType(lexpr) != BOOLOID)
- elog(WARN,
- "left-hand side of OR is type '%s', not bool",
- tname(get_id_type(exprType(lexpr))));
- if (exprType(rexpr) != BOOLOID)
- elog(WARN,
- "right-hand side of OR is type '%s', not bool",
- tname(get_id_type(exprType(rexpr))));
- expr->typeOid = BOOLOID;
- expr->opType = OR_EXPR;
- expr->args = makeList(lexpr, rexpr, -1);
- result = (Node *)expr;
- }
- break;
- case NOT:
- {
- Expr *expr = makeNode(Expr);
- Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
- if (exprType(rexpr) != BOOLOID)
- elog(WARN,
- "argument to NOT is type '%s', not bool",
- tname(get_id_type(exprType(rexpr))));
- expr->typeOid = BOOLOID;
- expr->opType = NOT_EXPR;
- expr->args = makeList(rexpr, -1);
- result = (Node *)expr;
- }
- break;
+ ai->lidx = lexpr;
+ ai->uidx = uexpr;
+
+ /*
+ * note we reuse the list of indices, make sure we
+ * don't free them! Otherwise, make a new list here
+ */
+ idx = lnext(idx);
+ }
+ result = (Node *) make_array_ref(temp, att->indirection);
+ }
+ else
+ {
+ result = temp;
+ }
+ break;
+ }
+ case T_A_Const:
+ {
+ A_Const *con = (A_Const *) expr;
+ Value *val = &con->val;
+
+ if (con->typename != NULL)
+ {
+ result = parser_typecast(val, con->typename, -1);
+ }
+ else
+ {
+ result = (Node *) make_const(val);
+ }
+ break;
+ }
+ case T_ParamNo:
+ {
+ ParamNo *pno = (ParamNo *) expr;
+ Oid toid;
+ int paramno;
+ Param *param;
+
+ paramno = pno->number;
+ toid = param_type(paramno);
+ if (!OidIsValid(toid))
+ {
+ elog(WARN, "Parameter '$%d' is out of range",
+ paramno);
+ }
+ param = makeNode(Param);
+ param->paramkind = PARAM_NUM;
+ param->paramid = (AttrNumber) paramno;
+ param->paramname = "<unnamed>";
+ param->paramtype = (Oid) toid;
+ param->param_tlist = (List *) NULL;
+
+ result = (Node *) param;
+ break;
+ }
+ case T_A_Expr:
+ {
+ A_Expr *a = (A_Expr *) expr;
+
+ switch (a->oper)
+ {
+ case OP:
+ {
+ Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
+ Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
+
+ result = (Node *) make_op(a->opname, lexpr, rexpr);
+ }
+ break;
+ case ISNULL:
+ {
+ Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
+
+ result = ParseFunc(pstate,
+ "nullvalue", lcons(lexpr, NIL),
+ &pstate->p_last_resno);
+ }
+ break;
+ case NOTNULL:
+ {
+ Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
+
+ result = ParseFunc(pstate,
+ "nonnullvalue", lcons(lexpr, NIL),
+ &pstate->p_last_resno);
+ }
+ break;
+ case AND:
+ {
+ Expr *expr = makeNode(Expr);
+ Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
+ Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
+
+ if (exprType(lexpr) != BOOLOID)
+ elog(WARN,
+ "left-hand side of AND is type '%s', not bool",
+ tname(get_id_type(exprType(lexpr))));
+ if (exprType(rexpr) != BOOLOID)
+ elog(WARN,
+ "right-hand side of AND is type '%s', not bool",
+ tname(get_id_type(exprType(rexpr))));
+ expr->typeOid = BOOLOID;
+ expr->opType = AND_EXPR;
+ expr->args = makeList(lexpr, rexpr, -1);
+ result = (Node *) expr;
+ }
+ break;
+ case OR:
+ {
+ Expr *expr = makeNode(Expr);
+ Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
+ Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
+
+ if (exprType(lexpr) != BOOLOID)
+ elog(WARN,
+ "left-hand side of OR is type '%s', not bool",
+ tname(get_id_type(exprType(lexpr))));
+ if (exprType(rexpr) != BOOLOID)
+ elog(WARN,
+ "right-hand side of OR is type '%s', not bool",
+ tname(get_id_type(exprType(rexpr))));
+ expr->typeOid = BOOLOID;
+ expr->opType = OR_EXPR;
+ expr->args = makeList(lexpr, rexpr, -1);
+ result = (Node *) expr;
+ }
+ break;
+ case NOT:
+ {
+ Expr *expr = makeNode(Expr);
+ Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
+
+ if (exprType(rexpr) != BOOLOID)
+ elog(WARN,
+ "argument to NOT is type '%s', not bool",
+ tname(get_id_type(exprType(rexpr))));
+ expr->typeOid = BOOLOID;
+ expr->opType = NOT_EXPR;
+ expr->args = makeList(rexpr, -1);
+ result = (Node *) expr;
+ }
+ break;
+ }
+ break;
+ }
+ case T_Ident:
+ {
+
+ /*
+ * look for a column name or a relation name (the default
+ * behavior)
+ */
+ result = transformIdent(pstate, expr, precedence);
+ break;
+ }
+ case T_FuncCall:
+ {
+ FuncCall *fn = (FuncCall *) expr;
+ List *args;
+
+ /* transform the list of arguments */
+ foreach(args, fn->args)
+ lfirst(args) = transformExpr(pstate, (Node *) lfirst(args), precedence);
+ result = ParseFunc(pstate,
+ fn->funcname, fn->args, &pstate->p_last_resno);
+ break;
+ }
+ default:
+ /* should not reach here */
+ elog(WARN, "transformExpr: does not know how to transform %d\n",
+ nodeTag(expr));
+ break;
}
- break;
- }
- case T_Ident: {
- /* look for a column name or a relation name (the default behavior) */
- result = transformIdent(pstate, expr, precedence);
- break;
- }
- case T_FuncCall: {
- FuncCall *fn = (FuncCall *)expr;
- List *args;
-
- /* transform the list of arguments */
- foreach(args, fn->args)
- lfirst(args) = transformExpr(pstate, (Node*)lfirst(args), precedence);
- result = ParseFunc(pstate,
- fn->funcname, fn->args, &pstate->p_last_resno);
- break;
- }
- default:
- /* should not reach here */
- elog(WARN, "transformExpr: does not know how to transform %d\n",
- nodeTag(expr));
- break;
- }
-
- return result;
+
+ return result;
}
-static Node *
-transformIdent(ParseState *pstate, Node *expr, int precedence)
+static Node *
+transformIdent(ParseState * pstate, Node * expr, int precedence)
{
- Ident *ident = (Ident*)expr;
- RangeTblEntry *rte;
- Node *column_result, *relation_result, *result;
-
- column_result = relation_result = result = 0;
- /* try to find the ident as a column */
- if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL) {
- Attr *att = makeNode(Attr);
-
- att->relname = rte->refname;
- att->attrs = lcons(makeString(ident->name), NIL);
- column_result =
- (Node*)handleNestedDots(pstate, att, &pstate->p_last_resno);
- }
-
- /* try to find the ident as a relation */
- if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL) {
- ident->isRel = TRUE;
- relation_result = (Node*)ident;
- }
-
- /* choose the right result based on the precedence */
- if(precedence == EXPR_COLUMN_FIRST) {
- if(column_result)
- result = column_result;
- else
- result = relation_result;
- } else {
- if(relation_result)
- result = relation_result;
+ Ident *ident = (Ident *) expr;
+ RangeTblEntry *rte;
+ Node *column_result,
+ *relation_result,
+ *result;
+
+ column_result = relation_result = result = 0;
+ /* try to find the ident as a column */
+ if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL)
+ {
+ Attr *att = makeNode(Attr);
+
+ att->relname = rte->refname;
+ att->attrs = lcons(makeString(ident->name), NIL);
+ column_result =
+ (Node *) handleNestedDots(pstate, att, &pstate->p_last_resno);
+ }
+
+ /* try to find the ident as a relation */
+ if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL)
+ {
+ ident->isRel = TRUE;
+ relation_result = (Node *) ident;
+ }
+
+ /* choose the right result based on the precedence */
+ if (precedence == EXPR_COLUMN_FIRST)
+ {
+ if (column_result)
+ result = column_result;
+ else
+ result = relation_result;
+ }
else
- result = column_result;
- }
+ {
+ if (relation_result)
+ result = relation_result;
+ else
+ result = column_result;
+ }
+
+ if (result == NULL)
+ elog(WARN, "attribute \"%s\" not found", ident->name);
- if(result == NULL)
- elog(WARN, "attribute \"%s\" not found", ident->name);
-
- return result;
+ return result;
}
/*****************************************************************************
@@ -787,201 +846,210 @@ transformIdent(ParseState *pstate, Node *expr, int precedence)
/*
* parseFromClause -
- * turns the table references specified in the from-clause into a
- * range table. The range table may grow as we transform the expressions
- * in the target list. (Note that this happens because in POSTQUEL, we
- * allow references to relations not specified in the from-clause. We
- * also allow that in our POST-SQL)
+ * turns the table references specified in the from-clause into a
+ * range table. The range table may grow as we transform the expressions
+ * in the target list. (Note that this happens because in POSTQUEL, we
+ * allow references to relations not specified in the from-clause. We
+ * also allow that in our POST-SQL)
*
*/
static void
-parseFromClause(ParseState *pstate, List *frmList)
+parseFromClause(ParseState * pstate, List * frmList)
{
- List *fl;
-
- foreach(fl, frmList)
- {
- RangeVar *r = lfirst(fl);
- RelExpr *baserel = r->relExpr;
- char *relname = baserel->relname;
- char *refname = r->name;
- RangeTblEntry *rte;
-
- if (refname==NULL)
- refname = relname;
+ List *fl;
- /*
- * marks this entry to indicate it comes from the FROM clause. In
- * SQL, the target list can only refer to range variables specified
- * in the from clause but we follow the more powerful POSTQUEL
- * semantics and automatically generate the range variable if not
- * specified. However there are times we need to know whether the
- * entries are legitimate.
- *
- * eg. select * from foo f where f.x = 1; will generate wrong answer
- * if we expand * to foo.x.
- */
- rte = addRangeTableEntry(pstate, relname, refname, baserel->inh, TRUE,
- baserel->timeRange);
- }
+ foreach(fl, frmList)
+ {
+ RangeVar *r = lfirst(fl);
+ RelExpr *baserel = r->relExpr;
+ char *relname = baserel->relname;
+ char *refname = r->name;
+ RangeTblEntry *rte;
+
+ if (refname == NULL)
+ refname = relname;
+
+ /*
+ * marks this entry to indicate it comes from the FROM clause. In
+ * SQL, the target list can only refer to range variables
+ * specified in the from clause but we follow the more powerful
+ * POSTQUEL semantics and automatically generate the range
+ * variable if not specified. However there are times we need to
+ * know whether the entries are legitimate.
+ *
+ * eg. select * from foo f where f.x = 1; will generate wrong answer
+ * if we expand * to foo.x.
+ */
+ rte = addRangeTableEntry(pstate, relname, refname, baserel->inh, TRUE,
+ baserel->timeRange);
+ }
}
/*
* makeRangeTable -
- * make a range table with the specified relation (optional) and the
- * from-clause.
+ * make a range table with the specified relation (optional) and the
+ * from-clause.
*/
static void
-makeRangeTable(ParseState *pstate, char *relname, List *frmList)
+makeRangeTable(ParseState * pstate, char *relname, List * frmList)
{
- RangeTblEntry *rte;
+ RangeTblEntry *rte;
- parseFromClause(pstate, frmList);
+ parseFromClause(pstate, frmList);
- if (relname == NULL)
- return;
-
- if (refnameRangeTablePosn(pstate->p_rtable, relname) < 1)
- rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE, NULL);
- else
- rte = refnameRangeTableEntry(pstate->p_rtable, relname);
-
- pstate->p_target_rangetblentry = rte;
- Assert(pstate->p_target_relation == NULL);
- pstate->p_target_relation = heap_open(rte->relid);
- Assert(pstate->p_target_relation != NULL);
+ if (relname == NULL)
+ return;
+
+ if (refnameRangeTablePosn(pstate->p_rtable, relname) < 1)
+ rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE, NULL);
+ else
+ rte = refnameRangeTableEntry(pstate->p_rtable, relname);
+
+ pstate->p_target_rangetblentry = rte;
+ Assert(pstate->p_target_relation == NULL);
+ pstate->p_target_relation = heap_open(rte->relid);
+ Assert(pstate->p_target_relation != NULL);
/* will close relation later */
}
/*
- * exprType -
- * returns the Oid of the type of the expression. (Used for typechecking.)
+ * exprType -
+ * returns the Oid of the type of the expression. (Used for typechecking.)
*/
Oid
-exprType(Node *expr)
+exprType(Node * expr)
{
- Oid type = (Oid)0;
-
- switch(nodeTag(expr)) {
- case T_Func:
- type = ((Func*)expr)->functype;
- break;
- case T_Iter:
- type = ((Iter*)expr)->itertype;
- break;
- case T_Var:
- type = ((Var*)expr)->vartype;
- break;
- case T_Expr:
- type = ((Expr*)expr)->typeOid;
- break;
- case T_Const:
- type = ((Const*)expr)->consttype;
- break;
- case T_ArrayRef:
- type = ((ArrayRef*)expr)->refelemtype;
- break;
- case T_Aggreg:
- type = ((Aggreg*)expr)->aggtype;
- break;
- case T_Param:
- type = ((Param*)expr)->paramtype;
- break;
- case T_Ident:
- /* is this right? */
- type = UNKNOWNOID;
- break;
- default:
- elog(WARN, "exprType: don't know how to get type for %d node",
- nodeTag(expr));
- break;
- }
- return type;
+ Oid type = (Oid) 0;
+
+ switch (nodeTag(expr))
+ {
+ case T_Func:
+ type = ((Func *) expr)->functype;
+ break;
+ case T_Iter:
+ type = ((Iter *) expr)->itertype;
+ break;
+ case T_Var:
+ type = ((Var *) expr)->vartype;
+ break;
+ case T_Expr:
+ type = ((Expr *) expr)->typeOid;
+ break;
+ case T_Const:
+ type = ((Const *) expr)->consttype;
+ break;
+ case T_ArrayRef:
+ type = ((ArrayRef *) expr)->refelemtype;
+ break;
+ case T_Aggreg:
+ type = ((Aggreg *) expr)->aggtype;
+ break;
+ case T_Param:
+ type = ((Param *) expr)->paramtype;
+ break;
+ case T_Ident:
+ /* is this right? */
+ type = UNKNOWNOID;
+ break;
+ default:
+ elog(WARN, "exprType: don't know how to get type for %d node",
+ nodeTag(expr));
+ break;
+ }
+ return type;
}
/*
* expandAllTables -
- * turns '*' (in the target list) into a list of attributes (of all
- * relations in the range table)
+ * turns '*' (in the target list) into a list of attributes (of all
+ * relations in the range table)
*/
-static List *
-expandAllTables(ParseState *pstate)
+static List *
+expandAllTables(ParseState * pstate)
{
- List *target= NIL;
- List *legit_rtable=NIL;
- List *rt, *rtable;
+ List *target = NIL;
+ List *legit_rtable = NIL;
+ List *rt,
+ *rtable;
- rtable = pstate->p_rtable;
- if (pstate->p_is_rule) {
- /*
- * skip first two entries, "*new*" and "*current*"
- */
- rtable = lnext(lnext(pstate->p_rtable));
- }
-
- /* this should not happen */
- if (rtable==NULL)
- elog(WARN, "cannot expand: null p_rtable");
-
- /*
- * go through the range table and make a list of range table entries
- * which we will expand.
- */
- foreach(rt, rtable) {
- RangeTblEntry *rte = lfirst(rt);
+ rtable = pstate->p_rtable;
+ if (pstate->p_is_rule)
+ {
+
+ /*
+ * skip first two entries, "*new*" and "*current*"
+ */
+ rtable = lnext(lnext(pstate->p_rtable));
+ }
+
+ /* this should not happen */
+ if (rtable == NULL)
+ elog(WARN, "cannot expand: null p_rtable");
/*
- * we only expand those specify in the from clause. (This will
- * also prevent us from using the wrong table in inserts: eg. tenk2
- * in "insert into tenk2 select * from tenk1;")
+ * go through the range table and make a list of range table entries
+ * which we will expand.
*/
- if (!rte->inFromCl)
- continue;
- legit_rtable = lappend(legit_rtable, rte);
- }
-
- foreach(rt, legit_rtable) {
- RangeTblEntry *rte = lfirst(rt);
- List *temp = target;
-
- if(temp == NIL )
- target = expandAll(pstate, rte->relname, rte->refname,
- &pstate->p_last_resno);
- else {
- while (temp != NIL && lnext(temp) != NIL)
- temp = lnext(temp);
- lnext(temp) = expandAll(pstate, rte->relname, rte->refname,
- &pstate->p_last_resno);
+ foreach(rt, rtable)
+ {
+ RangeTblEntry *rte = lfirst(rt);
+
+ /*
+ * we only expand those specify in the from clause. (This will
+ * also prevent us from using the wrong table in inserts: eg.
+ * tenk2 in "insert into tenk2 select * from tenk1;")
+ */
+ if (!rte->inFromCl)
+ continue;
+ legit_rtable = lappend(legit_rtable, rte);
+ }
+
+ foreach(rt, legit_rtable)
+ {
+ RangeTblEntry *rte = lfirst(rt);
+ List *temp = target;
+
+ if (temp == NIL)
+ target = expandAll(pstate, rte->relname, rte->refname,
+ &pstate->p_last_resno);
+ else
+ {
+ while (temp != NIL && lnext(temp) != NIL)
+ temp = lnext(temp);
+ lnext(temp) = expandAll(pstate, rte->relname, rte->refname,
+ &pstate->p_last_resno);
+ }
}
- }
- return target;
+ return target;
}
/*
* figureColname -
- * if the name of the resulting column is not specified in the target
- * list, we have to guess.
+ * if the name of the resulting column is not specified in the target
+ * list, we have to guess.
*
*/
-static char *
-figureColname(Node *expr, Node *resval)
+static char *
+figureColname(Node * expr, Node * resval)
{
- switch (nodeTag(expr)) {
- case T_Aggreg:
- return (char*) /* XXX */
- ((Aggreg *)expr)->aggname;
- case T_Expr:
- if (((Expr*)expr)->opType == FUNC_EXPR) {
- if (nodeTag(resval)==T_FuncCall)
- return ((FuncCall*)resval)->funcname;
+ switch (nodeTag(expr))
+ {
+ case T_Aggreg:
+ return (char *) /* XXX */
+ ((Aggreg *) expr)->aggname;
+ case T_Expr:
+ if (((Expr *) expr)->opType == FUNC_EXPR)
+ {
+ if (nodeTag(resval) == T_FuncCall)
+ return ((FuncCall *) resval)->funcname;
+ }
+ break;
+ default:
+ break;
}
- break;
- default:
- break;
- }
-
- return "?column?";
+
+ return "?column?";
}
/*****************************************************************************
@@ -992,452 +1060,531 @@ figureColname(Node *expr, Node *resval)
/*
* makeTargetNames -
- * generate a list of column names if not supplied or
- * test supplied column names to make sure they are in target table
- * (used exclusively for inserts)
+ * generate a list of column names if not supplied or
+ * test supplied column names to make sure they are in target table
+ * (used exclusively for inserts)
*/
-static List *
-makeTargetNames(ParseState *pstate, List *cols)
+static List *
+makeTargetNames(ParseState * pstate, List * cols)
{
- List *tl=NULL;
-
- /* Generate ResTarget if not supplied */
-
- if (cols == NIL) {
- int numcol;
- int i;
- AttributeTupleForm *attr = pstate->p_target_relation->rd_att->attrs;
-
- numcol = pstate->p_target_relation->rd_rel->relnatts;
- for(i=0; i < numcol; i++) {
- Ident *id = makeNode(Ident);
-
- id->name = palloc(NAMEDATALEN);
- strNcpy(id->name, attr[i]->attname.data, NAMEDATALEN-1);
- id->indirection = NIL;
- id->isRel = false;
- if (tl == NIL)
- cols = tl = lcons(id, NIL);
- else {
- lnext(tl) = lcons(id,NIL);
- tl = lnext(tl);
- }
+ List *tl = NULL;
+
+ /* Generate ResTarget if not supplied */
+
+ if (cols == NIL)
+ {
+ int numcol;
+ int i;
+ AttributeTupleForm *attr = pstate->p_target_relation->rd_att->attrs;
+
+ numcol = pstate->p_target_relation->rd_rel->relnatts;
+ for (i = 0; i < numcol; i++)
+ {
+ Ident *id = makeNode(Ident);
+
+ id->name = palloc(NAMEDATALEN);
+ strNcpy(id->name, attr[i]->attname.data, NAMEDATALEN - 1);
+ id->indirection = NIL;
+ id->isRel = false;
+ if (tl == NIL)
+ cols = tl = lcons(id, NIL);
+ else
+ {
+ lnext(tl) = lcons(id, NIL);
+ tl = lnext(tl);
+ }
+ }
}
- }
- else
- foreach(tl, cols)
- /* elog on failure */
- varattno(pstate->p_target_relation,((Ident *)lfirst(tl))->name);
+ else
+ foreach(tl, cols)
+ /* elog on failure */
+ varattno(pstate->p_target_relation, ((Ident *) lfirst(tl))->name);
- return cols;
+ return cols;
}
/*
* transformTargetList -
- * turns a list of ResTarget's into a list of TargetEntry's
+ * turns a list of ResTarget's into a list of TargetEntry's
*/
-static List *
-transformTargetList(ParseState *pstate, List *targetlist)
+static List *
+transformTargetList(ParseState * pstate, List * targetlist)
{
- List *p_target= NIL;
- List *tail_p_target = NIL;
-
- while(targetlist != NIL) {
- ResTarget *res= (ResTarget *)lfirst(targetlist);
- TargetEntry *tent = makeNode(TargetEntry);
-
- switch(nodeTag(res->val)) {
- case T_Ident: {
- Node *expr;
- Oid type_id;
- int type_len;
- char *identname;
- char *resname;
-
- identname = ((Ident*)res->val)->name;
- handleTargetColname(pstate, &res->name, NULL, identname );
-
- /* here we want to look for column names only, not relation */
- /* names (even though they can be stored in Ident nodes, */
- /* too) */
- expr = transformIdent(pstate, (Node*)res->val, EXPR_COLUMN_FIRST);
- type_id = exprType(expr);
- type_len = tlen(get_id_type(type_id));
- resname = (res->name) ? res->name : identname;
- tent->resdom = makeResdom((AttrNumber)pstate->p_last_resno++,
- (Oid)type_id,
- (Size)type_len,
- resname,
- (Index)0,
- (Oid)0,
- 0);
-
- tent->expr = expr;
- break;
- }
- case T_ParamNo:
- case T_FuncCall:
- case T_A_Const:
- case T_A_Expr: {
- Node *expr = transformExpr(pstate, (Node *)res->val, EXPR_COLUMN_FIRST);
-
- handleTargetColname(pstate, &res->name, NULL, NULL);
- /* note indirection has not been transformed */
- if (pstate->p_is_insert && res->indirection!=NIL) {
- /* this is an array assignment */
- char *val;
- char *str, *save_str;
- List *elt;
- int i = 0, ndims;
- int lindx[MAXDIM], uindx[MAXDIM];
- int resdomno;
- Relation rd;
- Value *constval;
-
- if (exprType(expr) != UNKNOWNOID ||
- !IsA(expr,Const))
- elog(WARN, "yyparse: string constant expected");
-
- val = (char *) textout((struct varlena *)
- ((Const *)expr)->constvalue);
- str = save_str = (char*)palloc(strlen(val) + MAXDIM * 25 + 2);
- foreach(elt, res->indirection) {
- A_Indices *aind = (A_Indices *)lfirst(elt);
- aind->uidx = transformExpr(pstate, aind->uidx, EXPR_COLUMN_FIRST);
- if (!IsA(aind->uidx,Const))
+ List *p_target = NIL;
+ List *tail_p_target = NIL;
+
+ while (targetlist != NIL)
+ {
+ ResTarget *res = (ResTarget *) lfirst(targetlist);
+ TargetEntry *tent = makeNode(TargetEntry);
+
+ switch (nodeTag(res->val))
+ {
+ case T_Ident:
+ {
+ Node *expr;
+ Oid type_id;
+ int type_len;
+ char *identname;
+ char *resname;
+
+ identname = ((Ident *) res->val)->name;
+ handleTargetColname(pstate, &res->name, NULL, identname);
+
+ /*
+ * here we want to look for column names only, not
+ * relation
+ */
+ /* names (even though they can be stored in Ident nodes, */
+ /* too) */
+ expr = transformIdent(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
+ type_id = exprType(expr);
+ type_len = tlen(get_id_type(type_id));
+ resname = (res->name) ? res->name : identname;
+ tent->resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
+ (Oid) type_id,
+ (Size) type_len,
+ resname,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+
+ tent->expr = expr;
+ break;
+ }
+ case T_ParamNo:
+ case T_FuncCall:
+ case T_A_Const:
+ case T_A_Expr:
+ {
+ Node *expr = transformExpr(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
+
+ handleTargetColname(pstate, &res->name, NULL, NULL);
+ /* note indirection has not been transformed */
+ if (pstate->p_is_insert && res->indirection != NIL)
+ {
+ /* this is an array assignment */
+ char *val;
+ char *str,
+ *save_str;
+ List *elt;
+ int i = 0,
+ ndims;
+ int lindx[MAXDIM],
+ uindx[MAXDIM];
+ int resdomno;
+ Relation rd;
+ Value *constval;
+
+ if (exprType(expr) != UNKNOWNOID ||
+ !IsA(expr, Const))
+ elog(WARN, "yyparse: string constant expected");
+
+ val = (char *) textout((struct varlena *)
+ ((Const *) expr)->constvalue);
+ str = save_str = (char *) palloc(strlen(val) + MAXDIM * 25 + 2);
+ foreach(elt, res->indirection)
+ {
+ A_Indices *aind = (A_Indices *) lfirst(elt);
+
+ aind->uidx = transformExpr(pstate, aind->uidx, EXPR_COLUMN_FIRST);
+ if (!IsA(aind->uidx, Const))
+ elog(WARN,
+ "Array Index for Append should be a constant");
+ uindx[i] = ((Const *) aind->uidx)->constvalue;
+ if (aind->lidx != NULL)
+ {
+ aind->lidx = transformExpr(pstate, aind->lidx, EXPR_COLUMN_FIRST);
+ if (!IsA(aind->lidx, Const))
+ elog(WARN,
+ "Array Index for Append should be a constant");
+ lindx[i] = ((Const *) aind->lidx)->constvalue;
+ }
+ else
+ {
+ lindx[i] = 1;
+ }
+ if (lindx[i] > uindx[i])
+ elog(WARN, "yyparse: lower index cannot be greater than upper index");
+ sprintf(str, "[%d:%d]", lindx[i], uindx[i]);
+ str += strlen(str);
+ i++;
+ }
+ sprintf(str, "=%s", val);
+ rd = pstate->p_target_relation;
+ Assert(rd != NULL);
+ resdomno = varattno(rd, res->name);
+ ndims = att_attnelems(rd, resdomno);
+ if (i != ndims)
+ elog(WARN, "yyparse: array dimensions do not match");
+ constval = makeNode(Value);
+ constval->type = T_String;
+ constval->val.str = save_str;
+ tent = make_targetlist_expr(pstate, res->name,
+ (Node *) make_const(constval),
+ NULL);
+ pfree(save_str);
+ }
+ else
+ {
+ char *colname = res->name;
+
+ /* this is not an array assignment */
+ if (colname == NULL)
+ {
+
+ /*
+ * if you're wondering why this is here, look at
+ * the yacc grammar for why a name can be missing.
+ * -ay
+ */
+ colname = figureColname(expr, res->val);
+ }
+ if (res->indirection)
+ {
+ List *ilist = res->indirection;
+
+ while (ilist != NIL)
+ {
+ A_Indices *ind = lfirst(ilist);
+
+ ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
+ ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
+ ilist = lnext(ilist);
+ }
+ }
+ res->name = colname;
+ tent = make_targetlist_expr(pstate, res->name, expr,
+ res->indirection);
+ }
+ break;
+ }
+ case T_Attr:
+ {
+ Oid type_id;
+ int type_len;
+ Attr *att = (Attr *) res->val;
+ Node *result;
+ char *attrname;
+ char *resname;
+ Resdom *resnode;
+ List *attrs = att->attrs;
+
+ /*
+ * Target item is a single '*', expand all tables (eg.
+ * SELECT * FROM emp)
+ */
+ if (att->relname != NULL && !strcmp(att->relname, "*"))
+ {
+ if (tail_p_target == NIL)
+ p_target = tail_p_target = expandAllTables(pstate);
+ else
+ lnext(tail_p_target) = expandAllTables(pstate);
+
+ while (lnext(tail_p_target) != NIL)
+ /* make sure we point to the last target entry */
+ tail_p_target = lnext(tail_p_target);
+
+ /*
+ * skip rest of while loop
+ */
+ targetlist = lnext(targetlist);
+ continue;
+ }
+
+ /*
+ * Target item is relation.*, expand the table (eg. SELECT
+ * emp.*, dname FROM emp, dept)
+ */
+ attrname = strVal(lfirst(att->attrs));
+ if (att->attrs != NIL && !strcmp(attrname, "*"))
+ {
+
+ /*
+ * tail_p_target is the target list we're building in
+ * the while loop. Make sure we fix it after appending
+ * more nodes.
+ */
+ if (tail_p_target == NIL)
+ p_target = tail_p_target = expandAll(pstate, att->relname,
+ att->relname, &pstate->p_last_resno);
+ else
+ lnext(tail_p_target) =
+ expandAll(pstate, att->relname, att->relname,
+ &pstate->p_last_resno);
+ while (lnext(tail_p_target) != NIL)
+ /* make sure we point to the last target entry */
+ tail_p_target = lnext(tail_p_target);
+
+ /*
+ * skip the rest of the while loop
+ */
+ targetlist = lnext(targetlist);
+ continue;
+ }
+
+
+ /*
+ * Target item is fully specified: ie. relation.attribute
+ */
+ result = handleNestedDots(pstate, att, &pstate->p_last_resno);
+ handleTargetColname(pstate, &res->name, att->relname, attrname);
+ if (att->indirection != NIL)
+ {
+ List *ilist = att->indirection;
+
+ while (ilist != NIL)
+ {
+ A_Indices *ind = lfirst(ilist);
+
+ ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
+ ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
+ ilist = lnext(ilist);
+ }
+ result = (Node *) make_array_ref(result, att->indirection);
+ }
+ type_id = exprType(result);
+ type_len = tlen(get_id_type(type_id));
+ /* move to last entry */
+ while (lnext(attrs) != NIL)
+ attrs = lnext(attrs);
+ resname = (res->name) ? res->name : strVal(lfirst(attrs));
+ resnode = makeResdom((AttrNumber) pstate->p_last_resno++,
+ (Oid) type_id,
+ (Size) type_len,
+ resname,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+ tent->resdom = resnode;
+ tent->expr = result;
+ break;
+ }
+ default:
+ /* internal error */
elog(WARN,
- "Array Index for Append should be a constant");
- uindx[i] = ((Const *)aind->uidx)->constvalue;
- if (aind->lidx!=NULL) {
- aind->lidx = transformExpr(pstate, aind->lidx, EXPR_COLUMN_FIRST);
- if (!IsA(aind->lidx,Const))
- elog(WARN,
- "Array Index for Append should be a constant");
- lindx[i] = ((Const*)aind->lidx)->constvalue;
- }else {
- lindx[i] = 1;
- }
- if (lindx[i] > uindx[i])
- elog(WARN, "yyparse: lower index cannot be greater than upper index");
- sprintf(str, "[%d:%d]", lindx[i], uindx[i]);
- str += strlen(str);
- i++;
- }
- sprintf(str, "=%s", val);
- rd = pstate->p_target_relation;
- Assert(rd != NULL);
- resdomno = varattno(rd, res->name);
- ndims = att_attnelems(rd, resdomno);
- if (i != ndims)
- elog(WARN, "yyparse: array dimensions do not match");
- constval = makeNode(Value);
- constval->type = T_String;
- constval->val.str = save_str;
- tent = make_targetlist_expr(pstate, res->name,
- (Node*)make_const(constval),
- NULL);
- pfree(save_str);
- } else {
- char *colname= res->name;
- /* this is not an array assignment */
- if (colname==NULL) {
- /* if you're wondering why this is here, look at
- * the yacc grammar for why a name can be missing. -ay
- */
- colname = figureColname(expr, res->val);
- }
- if (res->indirection) {
- List *ilist = res->indirection;
- while (ilist!=NIL) {
- A_Indices *ind = lfirst(ilist);
- ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
- ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
- ilist = lnext(ilist);
- }
+ "internal error: do not know how to transform targetlist");
+ break;
}
- res->name = colname;
- tent = make_targetlist_expr(pstate, res->name, expr,
- res->indirection);
- }
- break;
- }
- case T_Attr: {
- Oid type_id;
- int type_len;
- Attr *att = (Attr *)res->val;
- Node *result;
- char *attrname;
- char *resname;
- Resdom *resnode;
- List *attrs = att->attrs;
-
- /*
- * Target item is a single '*', expand all tables
- * (eg. SELECT * FROM emp)
- */
- if (att->relname!=NULL && !strcmp(att->relname, "*")) {
- if (tail_p_target == NIL)
- p_target = tail_p_target = expandAllTables(pstate);
- else
- lnext(tail_p_target) = expandAllTables(pstate);
- while(lnext(tail_p_target)!=NIL)
- /* make sure we point to the last target entry */
- tail_p_target = lnext(tail_p_target);
- /*
- * skip rest of while loop
- */
- targetlist = lnext(targetlist);
- continue;
- }
-
- /*
- * Target item is relation.*, expand the table
- * (eg. SELECT emp.*, dname FROM emp, dept)
- */
- attrname = strVal(lfirst(att->attrs));
- if (att->attrs!=NIL && !strcmp(attrname,"*")) {
- /* tail_p_target is the target list we're building in the while
- * loop. Make sure we fix it after appending more nodes.
- */
- if (tail_p_target == NIL)
- p_target = tail_p_target = expandAll(pstate, att->relname,
- att->relname, &pstate->p_last_resno);
+ if (p_target == NIL)
+ {
+ p_target = tail_p_target = lcons(tent, NIL);
+ }
else
- lnext(tail_p_target) =
- expandAll(pstate, att->relname, att->relname,
- &pstate->p_last_resno);
- while(lnext(tail_p_target)!=NIL)
- /* make sure we point to the last target entry */
- tail_p_target = lnext(tail_p_target);
- /*
- * skip the rest of the while loop
- */
- targetlist = lnext(targetlist);
- continue;
- }
-
-
- /*
- * Target item is fully specified: ie. relation.attribute
- */
- result = handleNestedDots(pstate, att, &pstate->p_last_resno);
- handleTargetColname(pstate, &res->name, att->relname, attrname);
- if (att->indirection != NIL) {
- List *ilist = att->indirection;
- while (ilist!=NIL) {
- A_Indices *ind = lfirst(ilist);
- ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
- ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
- ilist = lnext(ilist);
+ {
+ lnext(tail_p_target) = lcons(tent, NIL);
+ tail_p_target = lnext(tail_p_target);
}
- result = (Node*)make_array_ref(result, att->indirection);
- }
- type_id = exprType(result);
- type_len = tlen(get_id_type(type_id));
- /* move to last entry */
- while(lnext(attrs)!=NIL)
- attrs=lnext(attrs);
- resname = (res->name) ? res->name : strVal(lfirst(attrs));
- resnode = makeResdom((AttrNumber)pstate->p_last_resno++,
- (Oid)type_id,
- (Size)type_len,
- resname,
- (Index)0,
- (Oid)0,
- 0);
- tent->resdom = resnode;
- tent->expr = result;
- break;
- }
- default:
- /* internal error */
- elog(WARN,
- "internal error: do not know how to transform targetlist");
- break;
- }
-
- if (p_target == NIL) {
- p_target = tail_p_target = lcons(tent, NIL);
- }else {
- lnext(tail_p_target) = lcons(tent, NIL);
- tail_p_target = lnext(tail_p_target);
+ targetlist = lnext(targetlist);
}
- targetlist = lnext(targetlist);
- }
- return p_target;
+ return p_target;
}
/*
* make_targetlist_expr -
- * make a TargetEntry from an expression
+ * make a TargetEntry from an expression
*
* arrayRef is a list of transformed A_Indices
*/
static TargetEntry *
-make_targetlist_expr(ParseState *pstate,
- char *colname,
- Node *expr,
- List *arrayRef)
+make_targetlist_expr(ParseState * pstate,
+ char *colname,
+ Node * expr,
+ List * arrayRef)
{
- Oid type_id, attrtype;
- int type_len, attrlen;
- int resdomno;
- Relation rd;
- bool attrisset;
- TargetEntry *tent;
- Resdom *resnode;
-
- if (expr == NULL)
- elog(WARN, "make_targetlist_expr: invalid use of NULL expression");
-
- type_id = exprType(expr);
- if (type_id == InvalidOid) {
- type_len = 0;
- } else
- type_len = tlen(get_id_type(type_id));
-
- /* I have no idea what the following does! */
- /* It appears to process target columns that will be receiving results */
- if (pstate->p_is_insert||pstate->p_is_update) {
- /*
- * append or replace query --
- * append, replace work only on one relation,
- * so multiple occurence of same resdomno is bogus
- */
- rd = pstate->p_target_relation;
- Assert(rd != NULL);
- resdomno = varattno(rd,colname);
- attrisset = varisset(rd,colname);
- attrtype = att_typeid(rd,resdomno);
- if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
- attrtype = GetArrayElementType(attrtype);
- if (attrtype==BPCHAROID || attrtype==VARCHAROID) {
- attrlen = rd->rd_att->attrs[resdomno-1]->attlen;
- } else {
- attrlen = tlen(get_id_type(attrtype));
- }
+ Oid type_id,
+ attrtype;
+ int type_len,
+ attrlen;
+ int resdomno;
+ Relation rd;
+ bool attrisset;
+ TargetEntry *tent;
+ Resdom *resnode;
+
+ if (expr == NULL)
+ elog(WARN, "make_targetlist_expr: invalid use of NULL expression");
+
+ type_id = exprType(expr);
+ if (type_id == InvalidOid)
+ {
+ type_len = 0;
+ }
+ else
+ type_len = tlen(get_id_type(type_id));
+
+ /* I have no idea what the following does! */
+ /* It appears to process target columns that will be receiving results */
+ if (pstate->p_is_insert || pstate->p_is_update)
+ {
+
+ /*
+ * append or replace query -- append, replace work only on one
+ * relation, so multiple occurence of same resdomno is bogus
+ */
+ rd = pstate->p_target_relation;
+ Assert(rd != NULL);
+ resdomno = varattno(rd, colname);
+ attrisset = varisset(rd, colname);
+ attrtype = att_typeid(rd, resdomno);
+ if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
+ attrtype = GetArrayElementType(attrtype);
+ if (attrtype == BPCHAROID || attrtype == VARCHAROID)
+ {
+ attrlen = rd->rd_att->attrs[resdomno - 1]->attlen;
+ }
+ else
+ {
+ attrlen = tlen(get_id_type(attrtype));
+ }
#if 0
- if(Input_is_string && Typecast_ok){
- Datum val;
- if (type_id == typeid(type("unknown"))){
- val = (Datum)textout((struct varlena *)
- ((Const)lnext(expr))->constvalue);
- }else{
- val = ((Const)lnext(expr))->constvalue;
- }
- if (attrisset) {
- lnext(expr) = makeConst(attrtype,
- attrlen,
- val,
- false,
- true,
- true, /* is set */
- false);
- } else {
- lnext(expr) =
- makeConst(attrtype,
- attrlen,
- (Datum)fmgr(typeid_get_retinfunc(attrtype),
- val,get_typelem(attrtype),-1),
- false,
- true /* Maybe correct-- 80% chance */,
- false, /* is not a set */
- false);
- }
- } else if((Typecast_ok) && (attrtype != type_id)){
- lnext(expr) =
- parser_typecast2(expr, get_id_type(attrtype));
- } else
- if (attrtype != type_id) {
- if ((attrtype == INT2OID) && (type_id == INT4OID))
- lfirst(expr) = lispInteger (INT2OID); /* handle CASHOID too*/
- else if ((attrtype == FLOAT4OID) && (type_id == FLOAT8OID))
- lfirst(expr) = lispInteger (FLOAT4OID);
- else
- elog(WARN, "unequal type in tlist : %s \n", colname);
- }
-
- Input_is_string = false;
- Input_is_integer = false;
- Typecast_ok = true;
+ if (Input_is_string && Typecast_ok)
+ {
+ Datum val;
+
+ if (type_id == typeid(type("unknown")))
+ {
+ val = (Datum) textout((struct varlena *)
+ ((Const) lnext(expr))->constvalue);
+ }
+ else
+ {
+ val = ((Const) lnext(expr))->constvalue;
+ }
+ if (attrisset)
+ {
+ lnext(expr) = makeConst(attrtype,
+ attrlen,
+ val,
+ false,
+ true,
+ true, /* is set */
+ false);
+ }
+ else
+ {
+ lnext(expr) =
+ makeConst(attrtype,
+ attrlen,
+ (Datum) fmgr(typeid_get_retinfunc(attrtype),
+ val, get_typelem(attrtype), -1),
+ false,
+ true /* Maybe correct-- 80% chance */ ,
+ false, /* is not a set */
+ false);
+ }
+ }
+ else if ((Typecast_ok) && (attrtype != type_id))
+ {
+ lnext(expr) =
+ parser_typecast2(expr, get_id_type(attrtype));
+ }
+ else if (attrtype != type_id)
+ {
+ if ((attrtype == INT2OID) && (type_id == INT4OID))
+ lfirst(expr) = lispInteger(INT2OID); /* handle CASHOID too */
+ else if ((attrtype == FLOAT4OID) && (type_id == FLOAT8OID))
+ lfirst(expr) = lispInteger(FLOAT4OID);
+ else
+ elog(WARN, "unequal type in tlist : %s \n", colname);
+ }
+
+ Input_is_string = false;
+ Input_is_integer = false;
+ Typecast_ok = true;
#endif
- if (attrtype != type_id) {
- if (IsA(expr,Const)) {
- /* try to cast the constant */
- if (arrayRef && !(((A_Indices *)lfirst(arrayRef))->lidx)) {
- /* updating a single item */
- Oid typelem = get_typelem(attrtype);
- expr = (Node*)parser_typecast2(expr,
- type_id,
- get_id_type(typelem),
- attrlen);
- } else
- expr = (Node*)parser_typecast2(expr,
- type_id,
- get_id_type(attrtype),
- attrlen);
- } else {
- /* currently, we can't handle casting of expressions */
- elog(WARN, "parser: attribute '%s' is of type '%s' but expression is of type '%s'",
- colname,
- get_id_typname(attrtype),
- get_id_typname(type_id));
- }
- }
-
- if (arrayRef != NIL) {
- Expr *target_expr;
- Attr *att = makeNode(Attr);
- List *ar = arrayRef;
- List *upperIndexpr = NIL;
- List *lowerIndexpr = NIL;
-
- att->relname = pstrdup(RelationGetRelationName(rd)->data);
- att->attrs = lcons(makeString(colname), NIL);
- target_expr = (Expr*)handleNestedDots(pstate, att,
- &pstate->p_last_resno);
- while(ar!=NIL) {
- A_Indices *ind = lfirst(ar);
- if (lowerIndexpr || (!upperIndexpr && ind->lidx)) {
- /* XXX assume all lowerIndexpr is non-null in
- * this case
- */
- lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
- }
- upperIndexpr = lappend(upperIndexpr, ind->uidx);
- ar = lnext(ar);
- }
-
- expr = (Node*)make_array_set(target_expr,
- upperIndexpr,
- lowerIndexpr,
- (Expr*)expr);
- attrtype = att_typeid(rd,resdomno);
- attrlen = tlen(get_id_type(attrtype));
- }
- } else {
- resdomno = pstate->p_last_resno++;
- attrtype = type_id;
- attrlen = type_len;
- }
- tent = makeNode(TargetEntry);
-
- resnode = makeResdom((AttrNumber)resdomno,
- (Oid) attrtype,
- (Size) attrlen,
- colname,
- (Index)0,
- (Oid)0,
- 0);
-
- tent->resdom = resnode;
- tent->expr = expr;
-
- return tent;
+ if (attrtype != type_id)
+ {
+ if (IsA(expr, Const))
+ {
+ /* try to cast the constant */
+ if (arrayRef && !(((A_Indices *) lfirst(arrayRef))->lidx))
+ {
+ /* updating a single item */
+ Oid typelem = get_typelem(attrtype);
+
+ expr = (Node *) parser_typecast2(expr,
+ type_id,
+ get_id_type(typelem),
+ attrlen);
+ }
+ else
+ expr = (Node *) parser_typecast2(expr,
+ type_id,
+ get_id_type(attrtype),
+ attrlen);
+ }
+ else
+ {
+ /* currently, we can't handle casting of expressions */
+ elog(WARN, "parser: attribute '%s' is of type '%s' but expression is of type '%s'",
+ colname,
+ get_id_typname(attrtype),
+ get_id_typname(type_id));
+ }
+ }
+
+ if (arrayRef != NIL)
+ {
+ Expr *target_expr;
+ Attr *att = makeNode(Attr);
+ List *ar = arrayRef;
+ List *upperIndexpr = NIL;
+ List *lowerIndexpr = NIL;
+
+ att->relname = pstrdup(RelationGetRelationName(rd)->data);
+ att->attrs = lcons(makeString(colname), NIL);
+ target_expr = (Expr *) handleNestedDots(pstate, att,
+ &pstate->p_last_resno);
+ while (ar != NIL)
+ {
+ A_Indices *ind = lfirst(ar);
+
+ if (lowerIndexpr || (!upperIndexpr && ind->lidx))
+ {
+
+ /*
+ * XXX assume all lowerIndexpr is non-null in this
+ * case
+ */
+ lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
+ }
+ upperIndexpr = lappend(upperIndexpr, ind->uidx);
+ ar = lnext(ar);
+ }
+
+ expr = (Node *) make_array_set(target_expr,
+ upperIndexpr,
+ lowerIndexpr,
+ (Expr *) expr);
+ attrtype = att_typeid(rd, resdomno);
+ attrlen = tlen(get_id_type(attrtype));
+ }
+ }
+ else
+ {
+ resdomno = pstate->p_last_resno++;
+ attrtype = type_id;
+ attrlen = type_len;
+ }
+ tent = makeNode(TargetEntry);
+
+ resnode = makeResdom((AttrNumber) resdomno,
+ (Oid) attrtype,
+ (Size) attrlen,
+ colname,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+
+ tent->resdom = resnode;
+ tent->expr = expr;
+
+ return tent;
}
@@ -1449,26 +1596,27 @@ make_targetlist_expr(ParseState *pstate,
/*
* transformWhereClause -
- * transforms the qualification and make sure it is of type Boolean
+ * transforms the qualification and make sure it is of type Boolean
*
*/
-static Node *
-transformWhereClause(ParseState *pstate, Node *a_expr)
+static Node *
+transformWhereClause(ParseState * pstate, Node * a_expr)
{
- Node *qual;
-
- if (a_expr == NULL)
- return (Node *)NULL; /* no qualifiers */
-
- inWhereClause = true;
- qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST);
- inWhereClause = false;
- if (exprType(qual) != BOOLOID) {
- elog(WARN,
- "where clause must return type bool, not %s",
- tname(get_id_type(exprType(qual))));
- }
- return qual;
+ Node *qual;
+
+ if (a_expr == NULL)
+ return (Node *) NULL; /* no qualifiers */
+
+ inWhereClause = true;
+ qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST);
+ inWhereClause = false;
+ if (exprType(qual) != BOOLOID)
+ {
+ elog(WARN,
+ "where clause must return type bool, not %s",
+ tname(get_id_type(exprType(qual))));
+ }
+ return qual;
}
/*****************************************************************************
@@ -1478,203 +1626,237 @@ transformWhereClause(ParseState *pstate, Node *a_expr)
*****************************************************************************/
/*
- * find_targetlist_entry -
- * returns the Resdom in the target list matching the specified varname
- * and range
+ * find_targetlist_entry -
+ * returns the Resdom in the target list matching the specified varname
+ * and range
*
*/
static TargetEntry *
-find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
+find_targetlist_entry(ParseState * pstate, SortGroupBy * sortgroupby, List * tlist)
{
- List *i;
- int real_rtable_pos = 0, target_pos = 0;
- TargetEntry *target_result = NULL;
-
- if(sortgroupby->range)
- real_rtable_pos = refnameRangeTablePosn(pstate->p_rtable,
- sortgroupby->range);
-
- foreach(i, tlist) {
- TargetEntry *target = (TargetEntry *)lfirst(i);
- Resdom *resnode = target->resdom;
- Var *var = (Var *)target->expr;
- char *resname = resnode->resname;
- int test_rtable_pos = var->varno;
+ List *i;
+ int real_rtable_pos = 0,
+ target_pos = 0;
+ TargetEntry *target_result = NULL;
+
+ if (sortgroupby->range)
+ real_rtable_pos = refnameRangeTablePosn(pstate->p_rtable,
+ sortgroupby->range);
+
+ foreach(i, tlist)
+ {
+ TargetEntry *target = (TargetEntry *) lfirst(i);
+ Resdom *resnode = target->resdom;
+ Var *var = (Var *) target->expr;
+ char *resname = resnode->resname;
+ int test_rtable_pos = var->varno;
#ifdef PARSEDEBUG
-printf("find_targetlist_entry- target name is %s, position %d, resno %d\n",
- (sortgroupby->name? sortgroupby->name: "(null)"), target_pos+1, sortgroupby->resno);
+ printf("find_targetlist_entry- target name is %s, position %d, resno %d\n",
+ (sortgroupby->name ? sortgroupby->name : "(null)"), target_pos + 1, sortgroupby->resno);
#endif
- if (!sortgroupby->name) {
- if (sortgroupby->resno == ++target_pos) {
- target_result = target;
- break;
- }
- }
- else {
- if (!strcmp(resname, sortgroupby->name)) {
- if(sortgroupby->range) {
- if(real_rtable_pos == test_rtable_pos) {
- if (target_result != NULL)
- elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
- else target_result = target;
- }
- }
- else {
- if (target_result != NULL)
- elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
- else target_result = target;
- }
- }
+ if (!sortgroupby->name)
+ {
+ if (sortgroupby->resno == ++target_pos)
+ {
+ target_result = target;
+ break;
+ }
+ }
+ else
+ {
+ if (!strcmp(resname, sortgroupby->name))
+ {
+ if (sortgroupby->range)
+ {
+ if (real_rtable_pos == test_rtable_pos)
+ {
+ if (target_result != NULL)
+ elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
+ else
+ target_result = target;
+ }
+ }
+ else
+ {
+ if (target_result != NULL)
+ elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
+ else
+ target_result = target;
+ }
+ }
+ }
}
- }
- return target_result;
+ return target_result;
}
-static Oid
+static Oid
any_ordering_op(int restype)
{
- Operator order_op;
- Oid order_opid;
-
- order_op = oper("<",restype,restype,false);
- order_opid = oprid(order_op);
-
- return order_opid;
+ Operator order_op;
+ Oid order_opid;
+
+ order_op = oper("<", restype, restype, false);
+ order_opid = oprid(order_op);
+
+ return order_opid;
}
/*
* transformGroupClause -
- * transform a Group By clause
+ * transform a Group By clause
*
*/
-static List *
-transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
+static List *
+transformGroupClause(ParseState * pstate, List * grouplist, List * targetlist)
{
- List *glist = NIL, *gl = NIL;
-
- while (grouplist != NIL) {
- GroupClause *grpcl = makeNode(GroupClause);
- TargetEntry *restarget;
- Resdom *resdom;
-
- restarget = find_targetlist_entry(pstate, lfirst(grouplist), targetlist);
-
- if (restarget == NULL)
- elog(WARN,"The field being grouped by must appear in the target list");
-
- grpcl->entry = restarget;
- resdom = restarget->resdom;
- grpcl->grpOpoid = oprid(oper("<",
- resdom->restype,
- resdom->restype,false));
- if (glist == NIL)
- gl = glist = lcons(grpcl, NIL);
- else {
- lnext(gl) = lcons(grpcl, NIL);
- gl = lnext(gl);
+ List *glist = NIL,
+ *gl = NIL;
+
+ while (grouplist != NIL)
+ {
+ GroupClause *grpcl = makeNode(GroupClause);
+ TargetEntry *restarget;
+ Resdom *resdom;
+
+ restarget = find_targetlist_entry(pstate, lfirst(grouplist), targetlist);
+
+ if (restarget == NULL)
+ elog(WARN, "The field being grouped by must appear in the target list");
+
+ grpcl->entry = restarget;
+ resdom = restarget->resdom;
+ grpcl->grpOpoid = oprid(oper("<",
+ resdom->restype,
+ resdom->restype, false));
+ if (glist == NIL)
+ gl = glist = lcons(grpcl, NIL);
+ else
+ {
+ lnext(gl) = lcons(grpcl, NIL);
+ gl = lnext(gl);
+ }
+ grouplist = lnext(grouplist);
}
- grouplist = lnext(grouplist);
- }
- return glist;
+ return glist;
}
/*
* transformSortClause -
- * transform an Order By clause
+ * transform an Order By clause
*
*/
-static List *
-transformSortClause(ParseState *pstate,
- List *orderlist, List *targetlist,
- char* uniqueFlag)
+static List *
+transformSortClause(ParseState * pstate,
+ List * orderlist, List * targetlist,
+ char *uniqueFlag)
{
- List *sortlist = NIL;
- List *s = NIL, *i;
-
- while(orderlist != NIL) {
- SortGroupBy *sortby = lfirst(orderlist);
- SortClause *sortcl = makeNode(SortClause);
- TargetEntry *restarget;
- Resdom *resdom;
-
- restarget = find_targetlist_entry(pstate, sortby, targetlist);
- if (restarget == NULL)
- elog(WARN,"The field being ordered by must appear in the target list");
-
- sortcl->resdom = resdom = restarget->resdom;
- sortcl->opoid = oprid(oper(sortby->useOp,
- resdom->restype,
- resdom->restype,false));
- if (sortlist == NIL) {
- s = sortlist = lcons(sortcl, NIL);
- }else {
- lnext(s) = lcons(sortcl, NIL);
- s = lnext(s);
+ List *sortlist = NIL;
+ List *s = NIL,
+ *i;
+
+ while (orderlist != NIL)
+ {
+ SortGroupBy *sortby = lfirst(orderlist);
+ SortClause *sortcl = makeNode(SortClause);
+ TargetEntry *restarget;
+ Resdom *resdom;
+
+ restarget = find_targetlist_entry(pstate, sortby, targetlist);
+ if (restarget == NULL)
+ elog(WARN, "The field being ordered by must appear in the target list");
+
+ sortcl->resdom = resdom = restarget->resdom;
+ sortcl->opoid = oprid(oper(sortby->useOp,
+ resdom->restype,
+ resdom->restype, false));
+ if (sortlist == NIL)
+ {
+ s = sortlist = lcons(sortcl, NIL);
+ }
+ else
+ {
+ lnext(s) = lcons(sortcl, NIL);
+ s = lnext(s);
+ }
+ orderlist = lnext(orderlist);
}
- orderlist = lnext(orderlist);
- }
-
- if (uniqueFlag) {
- if (uniqueFlag[0] == '*') {
- /* concatenate all elements from target list
- that are not already in the sortby list */
- foreach (i,targetlist) {
- TargetEntry *tlelt = (TargetEntry *)lfirst(i);
-
- s = sortlist;
- while(s != NIL) {
- SortClause *sortcl = lfirst(s);
- if (sortcl->resdom==tlelt->resdom)
- break;
- s = lnext(s);
- }
- if (s == NIL) {
- /* not a member of the sortclauses yet */
- SortClause *sortcl = makeNode(SortClause);
-
- sortcl->resdom = tlelt->resdom;
- sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
-
- sortlist = lappend(sortlist, sortcl);
- }
- }
- }
- else {
- TargetEntry *tlelt = NULL;
- char* uniqueAttrName = uniqueFlag;
-
- /* only create sort clause with the specified unique attribute */
- foreach (i, targetlist) {
- tlelt = (TargetEntry*)lfirst(i);
- if (strcmp(tlelt->resdom->resname, uniqueAttrName) == 0)
- break;
- }
- if (i == NIL) {
- elog(WARN, "The field specified in the UNIQUE ON clause is not in the targetlist");
- }
- s = sortlist;
- foreach (s, sortlist) {
- SortClause *sortcl = lfirst(s);
- if (sortcl->resdom == tlelt->resdom)
- break;
- }
- if (s == NIL) {
- /* not a member of the sortclauses yet */
- SortClause *sortcl = makeNode(SortClause);
-
- sortcl->resdom = tlelt->resdom;
- sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
-
- sortlist = lappend(sortlist, sortcl);
- }
+
+ if (uniqueFlag)
+ {
+ if (uniqueFlag[0] == '*')
+ {
+
+ /*
+ * concatenate all elements from target list that are not
+ * already in the sortby list
+ */
+ foreach(i, targetlist)
+ {
+ TargetEntry *tlelt = (TargetEntry *) lfirst(i);
+
+ s = sortlist;
+ while (s != NIL)
+ {
+ SortClause *sortcl = lfirst(s);
+
+ if (sortcl->resdom == tlelt->resdom)
+ break;
+ s = lnext(s);
+ }
+ if (s == NIL)
+ {
+ /* not a member of the sortclauses yet */
+ SortClause *sortcl = makeNode(SortClause);
+
+ sortcl->resdom = tlelt->resdom;
+ sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
+
+ sortlist = lappend(sortlist, sortcl);
+ }
+ }
+ }
+ else
+ {
+ TargetEntry *tlelt = NULL;
+ char *uniqueAttrName = uniqueFlag;
+
+ /* only create sort clause with the specified unique attribute */
+ foreach(i, targetlist)
+ {
+ tlelt = (TargetEntry *) lfirst(i);
+ if (strcmp(tlelt->resdom->resname, uniqueAttrName) == 0)
+ break;
+ }
+ if (i == NIL)
+ {
+ elog(WARN, "The field specified in the UNIQUE ON clause is not in the targetlist");
+ }
+ s = sortlist;
+ foreach(s, sortlist)
+ {
+ SortClause *sortcl = lfirst(s);
+
+ if (sortcl->resdom == tlelt->resdom)
+ break;
+ }
+ if (s == NIL)
+ {
+ /* not a member of the sortclauses yet */
+ SortClause *sortcl = makeNode(SortClause);
+
+ sortcl->resdom = tlelt->resdom;
+ sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
+
+ sortlist = lappend(sortlist, sortcl);
+ }
+ }
+
}
- }
-
- return sortlist;
+ return sortlist;
}
/*
@@ -1682,578 +1864,645 @@ transformSortClause(ParseState *pstate,
** Given a nested dot expression (i.e. (relation func ... attr), build up
** a tree with of Iter and Func nodes.
*/
-static Node*
-handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno)
+static Node *
+handleNestedDots(ParseState * pstate, Attr * attr, int *curr_resno)
{
- List *mutator_iter;
- Node *retval = NULL;
-
- if (attr->paramNo != NULL) {
- Param *param = (Param *)transformExpr(pstate, (Node*)attr->paramNo, EXPR_RELATION_FIRST);
-
- retval =
- ParseFunc(pstate, strVal(lfirst(attr->attrs)),
- lcons(param, NIL),
- curr_resno);
- } else {
- Ident *ident = makeNode(Ident);
-
- ident->name = attr->relname;
- ident->isRel = TRUE;
- retval =
- ParseFunc(pstate, strVal(lfirst(attr->attrs)),
- lcons(ident, NIL),
- curr_resno);
- }
-
- foreach (mutator_iter, lnext(attr->attrs)) {
- retval = ParseFunc(pstate,strVal(lfirst(mutator_iter)),
- lcons(retval, NIL),
- curr_resno);
- }
-
- return(retval);
+ List *mutator_iter;
+ Node *retval = NULL;
+
+ if (attr->paramNo != NULL)
+ {
+ Param *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST);
+
+ retval =
+ ParseFunc(pstate, strVal(lfirst(attr->attrs)),
+ lcons(param, NIL),
+ curr_resno);
+ }
+ else
+ {
+ Ident *ident = makeNode(Ident);
+
+ ident->name = attr->relname;
+ ident->isRel = TRUE;
+ retval =
+ ParseFunc(pstate, strVal(lfirst(attr->attrs)),
+ lcons(ident, NIL),
+ curr_resno);
+ }
+
+ foreach(mutator_iter, lnext(attr->attrs))
+ {
+ retval = ParseFunc(pstate, strVal(lfirst(mutator_iter)),
+ lcons(retval, NIL),
+ curr_resno);
+ }
+
+ return (retval);
}
/*
** make_arguments --
- ** Given the number and types of arguments to a function, and the
+ ** Given the number and types of arguments to a function, and the
** actual arguments and argument types, do the necessary typecasting.
*/
static void
make_arguments(int nargs,
- List *fargs,
- Oid *input_typeids,
- Oid *function_typeids)
+ List * fargs,
+ Oid * input_typeids,
+ Oid * function_typeids)
{
- /*
- * there are two ways an input typeid can differ from a function typeid :
- * either the input type inherits the function type, so no typecasting is
- * necessary, or the input type can be typecast into the function type.
- * right now, we only typecast unknowns, and that is all we check for.
- */
-
- List *current_fargs;
- int i;
-
- for (i=0, current_fargs = fargs;
- i<nargs;
- i++, current_fargs = lnext(current_fargs)) {
-
- if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid) {
- lfirst(current_fargs) =
- parser_typecast2(lfirst(current_fargs),
- input_typeids[i],
- get_id_type(function_typeids[i]),
- -1);
+
+ /*
+ * there are two ways an input typeid can differ from a function
+ * typeid : either the input type inherits the function type, so no
+ * typecasting is necessary, or the input type can be typecast into
+ * the function type. right now, we only typecast unknowns, and that
+ * is all we check for.
+ */
+
+ List *current_fargs;
+ int i;
+
+ for (i = 0, current_fargs = fargs;
+ i < nargs;
+ i++, current_fargs = lnext(current_fargs))
+ {
+
+ if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid)
+ {
+ lfirst(current_fargs) =
+ parser_typecast2(lfirst(current_fargs),
+ input_typeids[i],
+ get_id_type(function_typeids[i]),
+ -1);
+ }
}
- }
}
/*
** setup_tlist --
- ** Build a tlist that says which attribute to project to.
- ** This routine is called by ParseFunc() to set up a target list
- ** on a tuple parameter or return value. Due to a bug in 4.0,
- ** it's not possible to refer to system attributes in this case.
+ ** Build a tlist that says which attribute to project to.
+ ** This routine is called by ParseFunc() to set up a target list
+ ** on a tuple parameter or return value. Due to a bug in 4.0,
+ ** it's not possible to refer to system attributes in this case.
*/
-static List *
+static List *
setup_tlist(char *attname, Oid relid)
{
- TargetEntry *tle;
- Resdom *resnode;
- Var *varnode;
- Oid typeid;
- int attno;
-
- attno = get_attnum(relid, attname);
- if (attno < 0)
- elog(WARN, "cannot reference attribute %s of tuple params/return values for functions", attname);
-
- typeid = find_atttype(relid, attname);
- resnode = makeResdom(1,
- typeid,
- tlen(get_id_type(typeid)),
- get_attname(relid, attno),
- 0,
- (Oid)0,
- 0);
- varnode = makeVar(-1, attno, typeid, -1, attno);
-
- tle = makeNode(TargetEntry);
- tle->resdom = resnode;
- tle->expr = (Node*)varnode;
- return (lcons(tle, NIL));
+ TargetEntry *tle;
+ Resdom *resnode;
+ Var *varnode;
+ Oid typeid;
+ int attno;
+
+ attno = get_attnum(relid, attname);
+ if (attno < 0)
+ elog(WARN, "cannot reference attribute %s of tuple params/return values for functions", attname);
+
+ typeid = find_atttype(relid, attname);
+ resnode = makeResdom(1,
+ typeid,
+ tlen(get_id_type(typeid)),
+ get_attname(relid, attno),
+ 0,
+ (Oid) 0,
+ 0);
+ varnode = makeVar(-1, attno, typeid, -1, attno);
+
+ tle = makeNode(TargetEntry);
+ tle->resdom = resnode;
+ tle->expr = (Node *) varnode;
+ return (lcons(tle, NIL));
}
/*
** setup_base_tlist --
- ** Build a tlist that extracts a base type from the tuple
- ** returned by the executor.
+ ** Build a tlist that extracts a base type from the tuple
+ ** returned by the executor.
*/
-static List *
+static List *
setup_base_tlist(Oid typeid)
{
- TargetEntry *tle;
- Resdom *resnode;
- Var *varnode;
-
- resnode = makeResdom(1,
- typeid,
- tlen(get_id_type(typeid)),
- "<noname>",
- 0,
- (Oid)0,
- 0);
- varnode = makeVar(-1, 1, typeid, -1, 1);
- tle = makeNode(TargetEntry);
- tle->resdom = resnode;
- tle->expr = (Node*)varnode;
-
- return (lcons(tle, NIL));
+ TargetEntry *tle;
+ Resdom *resnode;
+ Var *varnode;
+
+ resnode = makeResdom(1,
+ typeid,
+ tlen(get_id_type(typeid)),
+ "<noname>",
+ 0,
+ (Oid) 0,
+ 0);
+ varnode = makeVar(-1, 1, typeid, -1, 1);
+ tle = makeNode(TargetEntry);
+ tle->resdom = resnode;
+ tle->expr = (Node *) varnode;
+
+ return (lcons(tle, NIL));
}
/*
* ParseComplexProjection -
- * handles function calls with a single argument that is of complex type.
- * This routine returns NULL if it can't handle the projection (eg. sets).
+ * handles function calls with a single argument that is of complex type.
+ * This routine returns NULL if it can't handle the projection (eg. sets).
*/
-static Node *
-ParseComplexProjection(ParseState *pstate,
- char *funcname,
- Node *first_arg,
- bool *attisset)
+static Node *
+ParseComplexProjection(ParseState * pstate,
+ char *funcname,
+ Node * first_arg,
+ bool * attisset)
{
- Oid argtype;
- Oid argrelid;
- Name relname;
- Relation rd;
- Oid relid;
- int attnum;
-
- switch (nodeTag(first_arg)) {
- case T_Iter:
+ Oid argtype;
+ Oid argrelid;
+ Name relname;
+ Relation rd;
+ Oid relid;
+ int attnum;
+
+ switch (nodeTag(first_arg))
{
- Func *func;
- Iter *iter;
-
- iter = (Iter*)first_arg;
- func = (Func *)((Expr*)iter->iterexpr)->oper;
- argtype = funcid_get_rettype(func->funcid);
- argrelid = typeid_get_relid(argtype);
- if (argrelid &&
- ((attnum = get_attnum(argrelid, funcname))
- != InvalidAttrNumber)) {
-
- /* the argument is a function returning a tuple, so funcname
- may be a projection */
-
- /* add a tlist to the func node and return the Iter */
- rd = heap_openr(tname(get_id_type(argtype)));
- if (RelationIsValid(rd)) {
- relid = RelationGetRelationId(rd);
- relname = RelationGetRelationName(rd);
- heap_close(rd);
+ case T_Iter:
+ {
+ Func *func;
+ Iter *iter;
+
+ iter = (Iter *) first_arg;
+ func = (Func *) ((Expr *) iter->iterexpr)->oper;
+ argtype = funcid_get_rettype(func->funcid);
+ argrelid = typeid_get_relid(argtype);
+ if (argrelid &&
+ ((attnum = get_attnum(argrelid, funcname))
+ != InvalidAttrNumber))
+ {
+
+ /*
+ * the argument is a function returning a tuple, so
+ * funcname may be a projection
+ */
+
+ /* add a tlist to the func node and return the Iter */
+ rd = heap_openr(tname(get_id_type(argtype)));
+ if (RelationIsValid(rd))
+ {
+ relid = RelationGetRelationId(rd);
+ relname = RelationGetRelationName(rd);
+ heap_close(rd);
+ }
+ if (RelationIsValid(rd))
+ {
+ func->func_tlist =
+ setup_tlist(funcname, argrelid);
+ iter->itertype = att_typeid(rd, attnum);
+ return ((Node *) iter);
+ }
+ else
+ {
+ elog(WARN,
+ "Function %s has bad returntype %d",
+ funcname, argtype);
+ }
+ }
+ else
+ {
+ /* drop through */
+ ;
+ }
+ break;
}
- if (RelationIsValid(rd)) {
- func->func_tlist =
- setup_tlist(funcname, argrelid);
- iter->itertype = att_typeid(rd,attnum);
- return ((Node*)iter);
- }else {
- elog(WARN,
- "Function %s has bad returntype %d",
- funcname, argtype);
+ case T_Var:
+ {
+
+ /*
+ * The argument is a set, so this is either a projection or a
+ * function call on this set.
+ */
+ *attisset = true;
+ break;
}
- }else {
- /* drop through */
- ;
- }
- break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) first_arg;
+ Func *funcnode;
+
+ if (expr->opType != FUNC_EXPR)
+ break;
+
+ funcnode = (Func *) expr->oper;
+ argtype = funcid_get_rettype(funcnode->funcid);
+ argrelid = typeid_get_relid(argtype);
+
+ /*
+ * the argument is a function returning a tuple, so funcname
+ * may be a projection
+ */
+ if (argrelid &&
+ (attnum = get_attnum(argrelid, funcname))
+ != InvalidAttrNumber)
+ {
+
+ /* add a tlist to the func node */
+ rd = heap_openr(tname(get_id_type(argtype)));
+ if (RelationIsValid(rd))
+ {
+ relid = RelationGetRelationId(rd);
+ relname = RelationGetRelationName(rd);
+ heap_close(rd);
+ }
+ if (RelationIsValid(rd))
+ {
+ Expr *newexpr;
+
+ funcnode->func_tlist =
+ setup_tlist(funcname, argrelid);
+ funcnode->functype = att_typeid(rd, attnum);
+
+ newexpr = makeNode(Expr);
+ newexpr->typeOid = funcnode->functype;
+ newexpr->opType = FUNC_EXPR;
+ newexpr->oper = (Node *) funcnode;
+ newexpr->args = lcons(first_arg, NIL);
+
+ return ((Node *) newexpr);
+ }
+
+ }
+
+ elog(WARN, "Function %s has bad returntype %d",
+ funcname, argtype);
+ break;
+ }
+ case T_Param:
+ {
+ Param *param = (Param *) first_arg;
+
+ /*
+ * If the Param is a complex type, this could be a projection
+ */
+ rd = heap_openr(tname(get_id_type(param->paramtype)));
+ if (RelationIsValid(rd))
+ {
+ relid = RelationGetRelationId(rd);
+ relname = RelationGetRelationName(rd);
+ heap_close(rd);
+ }
+ if (RelationIsValid(rd) &&
+ (attnum = get_attnum(relid, funcname))
+ != InvalidAttrNumber)
+ {
+
+ param->paramtype = att_typeid(rd, attnum);
+ param->param_tlist = setup_tlist(funcname, relid);
+ return ((Node *) param);
+ }
+ break;
+ }
+ default:
+ break;
}
- case T_Var:
+
+ return NULL;
+}
+
+static Node *
+ParseFunc(ParseState * pstate, char *funcname, List * fargs, int *curr_resno)
+{
+ Oid rettype = (Oid) 0;
+ Oid argrelid = (Oid) 0;
+ Oid funcid = (Oid) 0;
+ List *i = NIL;
+ Node *first_arg = NULL;
+ char *relname = NULL;
+ char *refname = NULL;
+ Relation rd;
+ Oid relid;
+ int nargs;
+ Func *funcnode;
+ Oid oid_array[8];
+ Oid *true_oid_array;
+ Node *retval;
+ bool retset;
+ bool exists;
+ bool attisset = false;
+ Oid toid = (Oid) 0;
+ Expr *expr;
+
+ if (fargs)
{
- /*
- * The argument is a set, so this is either a projection
- * or a function call on this set.
- */
- *attisset = true;
- break;
+ first_arg = lfirst(fargs);
+ if (first_arg == NULL)
+ elog(WARN, "function %s does not allow NULL input", funcname);
}
- case T_Expr:
+
+ /*
+ * * check for projection methods: if function takes one argument, and *
+ * that argument is a relation, param, or PQ function returning a
+ * complex * type, then the function could be a projection.
+ */
+ if (length(fargs) == 1)
{
- Expr *expr = (Expr*)first_arg;
- Func *funcnode;
- if (expr->opType != FUNC_EXPR)
- break;
+ if (nodeTag(first_arg) == T_Ident && ((Ident *) first_arg)->isRel)
+ {
+ RangeTblEntry *rte;
+ Ident *ident = (Ident *) first_arg;
+
+ /*
+ * first arg is a relation. This could be a projection.
+ */
+ refname = ident->name;
+
+ rte = refnameRangeTableEntry(pstate->p_rtable, refname);
+ if (rte == NULL)
+ rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE, NULL);
+
+ relname = rte->relname;
+ relid = rte->relid;
+
+ /*
+ * If the attr isn't a set, just make a var for it. If it is
+ * a set, treat it like a function and drop through.
+ */
+ if (get_attnum(relid, funcname) != InvalidAttrNumber)
+ {
+ Oid dummyTypeId;
+
+ return
+ ((Node *) make_var(pstate,
+ refname,
+ funcname,
+ &dummyTypeId));
+ }
+ else
+ {
+ /* drop through - attr is a set */
+ ;
+ }
+ }
+ else if (ISCOMPLEX(exprType(first_arg)))
+ {
+
+ /*
+ * Attempt to handle projection of a complex argument. If
+ * ParseComplexProjection can't handle the projection, we have
+ * to keep going.
+ */
+ retval = ParseComplexProjection(pstate,
+ funcname,
+ first_arg,
+ &attisset);
+ if (attisset)
+ {
+ toid = exprType(first_arg);
+ rd = heap_openr(tname(get_id_type(toid)));
+ if (RelationIsValid(rd))
+ {
+ relname = RelationGetRelationName(rd)->data;
+ heap_close(rd);
+ }
+ else
+ elog(WARN,
+ "Type %s is not a relation type",
+ tname(get_id_type(toid)));
+ argrelid = typeid_get_relid(toid);
+
+ /*
+ * A projection contains either an attribute name or the
+ * "*".
+ */
+ if ((get_attnum(argrelid, funcname) == InvalidAttrNumber)
+ && strcmp(funcname, "*"))
+ {
+ elog(WARN, "Functions on sets are not yet supported");
+ }
+ }
+
+ if (retval)
+ return retval;
+ }
+ else
+ {
+
+ /*
+ * Parsing aggregates.
+ */
+ Oid basetype;
+
+ /*
+ * the aggregate count is a special case, ignore its base
+ * type. Treat it as zero
+ */
+ if (strcmp(funcname, "count") == 0)
+ basetype = 0;
+ else
+ basetype = exprType(lfirst(fargs));
+ if (SearchSysCacheTuple(AGGNAME,
+ PointerGetDatum(funcname),
+ ObjectIdGetDatum(basetype),
+ 0, 0))
+ {
+ Aggreg *aggreg = ParseAgg(funcname, basetype, lfirst(fargs));
+
+ AddAggToParseState(pstate, aggreg);
+ return (Node *) aggreg;
+ }
+ }
+ }
- funcnode= (Func *) expr->oper;
- argtype = funcid_get_rettype(funcnode->funcid);
- argrelid = typeid_get_relid(argtype);
- /*
- * the argument is a function returning a tuple, so funcname
- * may be a projection
- */
- if (argrelid &&
- (attnum = get_attnum(argrelid, funcname))
- != InvalidAttrNumber) {
-
- /* add a tlist to the func node */
- rd = heap_openr(tname(get_id_type(argtype)));
- if (RelationIsValid(rd)) {
- relid = RelationGetRelationId(rd);
- relname = RelationGetRelationName(rd);
- heap_close(rd);
+
+ /*
+ * * If we dropped through to here it's really a function (or a set,
+ * which * is implemented as a function.) * extract arg type info and
+ * transform relation name arguments into * varnodes of the
+ * appropriate form.
+ */
+ memset(&oid_array[0], 0, 8 * sizeof(Oid));
+
+ nargs = 0;
+ foreach(i, fargs)
+ {
+ int vnum;
+ RangeTblEntry *rte;
+ Node *pair = lfirst(i);
+
+ if (nodeTag(pair) == T_Ident && ((Ident *) pair)->isRel)
+ {
+
+ /*
+ * a relation
+ */
+ refname = ((Ident *) pair)->name;
+
+ rte = refnameRangeTableEntry(pstate->p_rtable, refname);
+ if (rte == NULL)
+ rte = addRangeTableEntry(pstate, refname, refname,
+ FALSE, FALSE, NULL);
+ relname = rte->relname;
+
+ vnum = refnameRangeTablePosn(pstate->p_rtable, rte->refname);
+
+ /*
+ * for func(relname), the param to the function is the tuple
+ * under consideration. we build a special VarNode to reflect
+ * this -- it has varno set to the correct range table entry,
+ * but has varattno == 0 to signal that the whole tuple is the
+ * argument.
+ */
+ toid = typeid(type(relname));
+ /* replace it in the arg list */
+ lfirst(fargs) =
+ makeVar(vnum, 0, toid, vnum, 0);
}
- if (RelationIsValid(rd)) {
- Expr *newexpr;
-
- funcnode->func_tlist =
- setup_tlist(funcname, argrelid);
- funcnode->functype = att_typeid(rd,attnum);
-
- newexpr = makeNode(Expr);
- newexpr->typeOid = funcnode->functype;
- newexpr->opType = FUNC_EXPR;
- newexpr->oper = (Node *)funcnode;
- newexpr->args = lcons(first_arg, NIL);
-
- return ((Node*)newexpr);
+ else if (!attisset)
+ { /* set functions don't have parameters */
+
+ /*
+ * any functiona args which are typed "unknown", but aren't
+ * constants, we don't know what to do with, because we can't
+ * cast them - jolly
+ */
+ if (exprType(pair) == UNKNOWNOID &&
+ !IsA(pair, Const))
+ {
+ elog(WARN, "ParseFunc: no function named %s that takes in an unknown type as argument #%d", funcname, nargs);
+ }
+ else
+ toid = exprType(pair);
}
-
- }
- elog(WARN, "Function %s has bad returntype %d",
- funcname, argtype);
- break;
+ oid_array[nargs++] = toid;
+ }
+
+ /*
+ * func_get_detail looks up the function in the catalogs, does
+ * disambiguation for polymorphic functions, handles inheritance, and
+ * returns the funcid and type and set or singleton status of the
+ * function's return value. it also returns the true argument types
+ * to the function. if func_get_detail returns true, the function
+ * exists. otherwise, there was an error.
+ */
+ if (attisset)
+ { /* we know all of these fields already */
+
+ /*
+ * We create a funcnode with a placeholder function SetEval.
+ * SetEval() never actually gets executed. When the function
+ * evaluation routines see it, they use the funcid projected out
+ * from the relation as the actual function to call. Example:
+ * retrieve (emp.mgr.name) The plan for this will scan the emp
+ * relation, projecting out the mgr attribute, which is a funcid.
+ * This function is then called (instead of SetEval) and "name" is
+ * projected from its result.
+ */
+ funcid = SetEvalRegProcedure;
+ rettype = toid;
+ retset = true;
+ true_oid_array = oid_array;
+ exists = true;
}
- case T_Param:
+ else
{
- Param *param = (Param*)first_arg;
- /*
- * If the Param is a complex type, this could be a projection
- */
- rd = heap_openr(tname(get_id_type(param->paramtype)));
- if (RelationIsValid(rd)) {
- relid = RelationGetRelationId(rd);
- relname = RelationGetRelationName(rd);
- heap_close(rd);
- }
- if (RelationIsValid(rd) &&
- (attnum = get_attnum(relid, funcname))
- != InvalidAttrNumber) {
-
- param->paramtype = att_typeid(rd, attnum);
- param->param_tlist = setup_tlist(funcname, relid);
- return ((Node*)param);
- }
- break;
+ exists = func_get_detail(funcname, nargs, oid_array, &funcid,
+ &rettype, &retset, &true_oid_array);
}
- default:
- break;
- }
- return NULL;
-}
-
-static Node *
-ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
-{
- Oid rettype = (Oid)0;
- Oid argrelid = (Oid)0;
- Oid funcid = (Oid)0;
- List *i = NIL;
- Node *first_arg= NULL;
- char *relname = NULL;
- char *refname = NULL;
- Relation rd;
- Oid relid;
- int nargs;
- Func *funcnode;
- Oid oid_array[8];
- Oid *true_oid_array;
- Node *retval;
- bool retset;
- bool exists;
- bool attisset = false;
- Oid toid = (Oid)0;
- Expr *expr;
-
- if (fargs) {
- first_arg = lfirst(fargs);
- if (first_arg == NULL)
- elog (WARN,"function %s does not allow NULL input",funcname);
- }
-
- /*
- ** check for projection methods: if function takes one argument, and
- ** that argument is a relation, param, or PQ function returning a complex
- ** type, then the function could be a projection.
- */
- if (length(fargs) == 1) {
-
- if (nodeTag(first_arg)==T_Ident && ((Ident*)first_arg)->isRel) {
- RangeTblEntry *rte;
- Ident *ident = (Ident*)first_arg;
-
- /*
- * first arg is a relation. This could be a projection.
- */
- refname = ident->name;
-
- rte = refnameRangeTableEntry(pstate->p_rtable, refname);
- if (rte == NULL)
- rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE,NULL);
-
- relname = rte->relname;
- relid = rte->relid;
-
- /* If the attr isn't a set, just make a var for it. If
- * it is a set, treat it like a function and drop through.
- */
- if (get_attnum(relid, funcname) != InvalidAttrNumber) {
- Oid dummyTypeId;
-
- return
- ((Node*)make_var(pstate,
- refname,
- funcname,
- &dummyTypeId));
- } else {
- /* drop through - attr is a set */
- ;
- }
- } else if (ISCOMPLEX(exprType(first_arg))) {
- /*
- * Attempt to handle projection of a complex argument. If
- * ParseComplexProjection can't handle the projection, we
- * have to keep going.
- */
- retval = ParseComplexProjection(pstate,
- funcname,
- first_arg,
- &attisset);
- if (attisset) {
- toid = exprType(first_arg);
- rd = heap_openr(tname(get_id_type(toid)));
- if (RelationIsValid(rd)) {
- relname = RelationGetRelationName(rd)->data;
- heap_close(rd);
- } else
- elog(WARN,
- "Type %s is not a relation type",
- tname(get_id_type(toid)));
- argrelid = typeid_get_relid(toid);
- /* A projection contains either an attribute name or the
- * "*".
- */
- if ((get_attnum(argrelid, funcname) == InvalidAttrNumber)
- && strcmp(funcname, "*")) {
- elog(WARN, "Functions on sets are not yet supported");
+ if (!exists)
+ elog(WARN, "no such attribute or function %s", funcname);
+
+ /* got it */
+ funcnode = makeNode(Func);
+ funcnode->funcid = funcid;
+ funcnode->functype = rettype;
+ funcnode->funcisindex = false;
+ funcnode->funcsize = 0;
+ funcnode->func_fcache = NULL;
+ funcnode->func_tlist = NIL;
+ funcnode->func_planlist = NIL;
+
+ /* perform the necessary typecasting */
+ make_arguments(nargs, fargs, oid_array, true_oid_array);
+
+ /*
+ * for functions returning base types, we want to project out the
+ * return value. set up a target list to do that. the executor will
+ * ignore these for c functions, and do the right thing for postquel
+ * functions.
+ */
+
+ if (typeid_get_relid(rettype) == InvalidOid)
+ funcnode->func_tlist = setup_base_tlist(rettype);
+
+ /*
+ * For sets, we want to make a targetlist to project out this
+ * attribute of the set tuples.
+ */
+ if (attisset)
+ {
+ if (!strcmp(funcname, "*"))
+ {
+ funcnode->func_tlist =
+ expandAll(pstate, relname, refname, curr_resno);
+ }
+ else
+ {
+ funcnode->func_tlist = setup_tlist(funcname, argrelid);
+ rettype = find_atttype(argrelid, funcname);
}
- }
-
- if (retval)
- return retval;
- } else {
- /*
- * Parsing aggregates.
- */
- Oid basetype;
- /* the aggregate count is a special case,
- ignore its base type. Treat it as zero */
- if (strcmp(funcname, "count") == 0)
- basetype = 0;
- else
- basetype = exprType(lfirst(fargs));
- if (SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(funcname),
- ObjectIdGetDatum(basetype),
- 0, 0)) {
- Aggreg *aggreg = ParseAgg(funcname, basetype, lfirst(fargs));
-
- AddAggToParseState(pstate, aggreg);
- return (Node*)aggreg;
- }
}
- }
-
-
- /*
- ** If we dropped through to here it's really a function (or a set, which
- ** is implemented as a function.)
- ** extract arg type info and transform relation name arguments into
- ** varnodes of the appropriate form.
- */
- memset(&oid_array[0], 0, 8 * sizeof(Oid));
-
- nargs=0;
- foreach ( i , fargs ) {
- int vnum;
- RangeTblEntry *rte;
- Node *pair = lfirst(i);
-
- if (nodeTag(pair)==T_Ident && ((Ident*)pair)->isRel) {
- /*
- * a relation
- */
- refname = ((Ident*)pair)->name;
-
- rte = refnameRangeTableEntry(pstate->p_rtable, refname);
- if (rte == NULL)
- rte = addRangeTableEntry(pstate, refname, refname,
- FALSE, FALSE, NULL);
- relname = rte->relname;
-
- vnum = refnameRangeTablePosn (pstate->p_rtable, rte->refname);
-
- /*
- * for func(relname), the param to the function
- * is the tuple under consideration. we build a special
- * VarNode to reflect this -- it has varno set to the
- * correct range table entry, but has varattno == 0 to
- * signal that the whole tuple is the argument.
- */
- toid = typeid(type(relname));
- /* replace it in the arg list */
- lfirst(fargs) =
- makeVar(vnum, 0, toid, vnum, 0);
- }else if (!attisset) { /* set functions don't have parameters */
-
- /* any functiona args which are typed "unknown", but aren't
- constants, we don't know what to do with, because we
- can't cast them - jolly*/
- if (exprType(pair) == UNKNOWNOID &&
- !IsA(pair, Const))
- {
- elog(WARN, "ParseFunc: no function named %s that takes in an unknown type as argument #%d", funcname, nargs);
- }
- else
- toid = exprType(pair);
+
+ /*
+ * Sequence handling.
+ */
+ if (funcid == SeqNextValueRegProcedure ||
+ funcid == SeqCurrValueRegProcedure)
+ {
+ Const *seq;
+ char *seqrel;
+ int32 aclcheck_result = -1;
+
+ Assert(length(fargs) == 1);
+ seq = (Const *) lfirst(fargs);
+ if (!IsA((Node *) seq, Const))
+ elog(WARN, "%s: only constant sequence names are acceptable", funcname);
+ seqrel = textout((struct varlena *) (seq->constvalue));
+
+ if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
+ ((funcid == SeqNextValueRegProcedure) ? ACL_WR : ACL_RD)))
+ != ACLCHECK_OK)
+ elog(WARN, "%s.%s: %s",
+ seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
+
+ pfree(seqrel);
+
+ if (funcid == SeqNextValueRegProcedure && inWhereClause)
+ elog(WARN, "nextval of a sequence in WHERE disallowed");
}
-
- oid_array[nargs++] = toid;
- }
-
- /*
- * func_get_detail looks up the function in the catalogs, does
- * disambiguation for polymorphic functions, handles inheritance,
- * and returns the funcid and type and set or singleton status of
- * the function's return value. it also returns the true argument
- * types to the function. if func_get_detail returns true,
- * the function exists. otherwise, there was an error.
- */
- if (attisset) { /* we know all of these fields already */
- /* We create a funcnode with a placeholder function SetEval.
- * SetEval() never actually gets executed. When the function
- * evaluation routines see it, they use the funcid projected
- * out from the relation as the actual function to call.
- * Example: retrieve (emp.mgr.name)
- * The plan for this will scan the emp relation, projecting
- * out the mgr attribute, which is a funcid. This function
- * is then called (instead of SetEval) and "name" is projected
- * from its result.
+
+ expr = makeNode(Expr);
+ expr->typeOid = rettype;
+ expr->opType = FUNC_EXPR;
+ expr->oper = (Node *) funcnode;
+ expr->args = fargs;
+ retval = (Node *) expr;
+
+ /*
+ * if the function returns a set of values, then we need to iterate
+ * over all the returned values in the executor, so we stick an iter
+ * node here. if it returns a singleton, then we don't need the iter
+ * node.
*/
- funcid = SetEvalRegProcedure;
- rettype = toid;
- retset = true;
- true_oid_array = oid_array;
- exists = true;
- } else {
- exists = func_get_detail(funcname, nargs, oid_array, &funcid,
- &rettype, &retset, &true_oid_array);
- }
-
- if (!exists)
- elog(WARN, "no such attribute or function %s", funcname);
-
- /* got it */
- funcnode = makeNode(Func);
- funcnode->funcid = funcid;
- funcnode->functype = rettype;
- funcnode->funcisindex = false;
- funcnode->funcsize = 0;
- funcnode->func_fcache = NULL;
- funcnode->func_tlist = NIL;
- funcnode->func_planlist = NIL;
-
- /* perform the necessary typecasting */
- make_arguments(nargs, fargs, oid_array, true_oid_array);
-
- /*
- * for functions returning base types, we want to project out the
- * return value. set up a target list to do that. the executor
- * will ignore these for c functions, and do the right thing for
- * postquel functions.
- */
-
- if (typeid_get_relid(rettype) == InvalidOid)
- funcnode->func_tlist = setup_base_tlist(rettype);
-
- /* For sets, we want to make a targetlist to project out this
- * attribute of the set tuples.
- */
- if (attisset) {
- if (!strcmp(funcname, "*")) {
- funcnode->func_tlist =
- expandAll(pstate, relname, refname, curr_resno);
- } else {
- funcnode->func_tlist = setup_tlist(funcname,argrelid);
- rettype = find_atttype(argrelid, funcname);
+
+ if (retset)
+ {
+ Iter *iter = makeNode(Iter);
+
+ iter->itertype = rettype;
+ iter->iterexpr = retval;
+ retval = (Node *) iter;
}
- }
-
- /*
- * Sequence handling.
- */
- if ( funcid == SeqNextValueRegProcedure ||
- funcid == SeqCurrValueRegProcedure )
- {
- Const *seq;
- char *seqrel;
- int32 aclcheck_result = -1;
-
- Assert ( length(fargs) == 1 );
- seq = (Const*)lfirst(fargs);
- if ( ! IsA ((Node*)seq, Const) )
- elog (WARN, "%s: only constant sequence names are acceptable", funcname);
- seqrel = textout ((struct varlena *) (seq->constvalue));
-
- if ( ( aclcheck_result = pg_aclcheck (seqrel, GetPgUserName(),
- ((funcid == SeqNextValueRegProcedure) ? ACL_WR : ACL_RD)) )
- != ACLCHECK_OK )
- elog (WARN, "%s.%s: %s",
- seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
-
- pfree (seqrel);
-
- if ( funcid == SeqNextValueRegProcedure && inWhereClause )
- elog (WARN, "nextval of a sequence in WHERE disallowed");
- }
-
- expr = makeNode(Expr);
- expr->typeOid = rettype;
- expr->opType = FUNC_EXPR;
- expr->oper = (Node *)funcnode;
- expr->args = fargs;
- retval = (Node*)expr;
-
- /*
- * if the function returns a set of values, then we need to iterate
- * over all the returned values in the executor, so we stick an
- * iter node here. if it returns a singleton, then we don't need
- * the iter node.
- */
-
- if (retset) {
- Iter *iter = makeNode(Iter);
- iter->itertype = rettype;
- iter->iterexpr = retval;
- retval = (Node*)iter;
- }
-
- return(retval);
+
+ return (retval);
}
/*****************************************************************************
@@ -2262,232 +2511,243 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
/*
* AddAggToParseState -
- * add the aggregate to the list of unique aggregates in pstate.
+ * add the aggregate to the list of unique aggregates in pstate.
*
* SIDE EFFECT: aggno in target list entry will be modified
*/
static void
-AddAggToParseState(ParseState *pstate, Aggreg *aggreg)
+AddAggToParseState(ParseState * pstate, Aggreg * aggreg)
{
- List *ag;
- int i;
-
- /*
- * see if we have the aggregate already (we only need to record
- * the aggregate once)
- */
- i = 0;
- foreach(ag, pstate->p_aggs) {
- Aggreg *a = lfirst(ag);
-
- if (!strcmp(a->aggname, aggreg->aggname) &&
- equal(a->target, aggreg->target)) {
-
- /* fill in the aggno and we're done */
- aggreg->aggno = i;
- return;
+ List *ag;
+ int i;
+
+ /*
+ * see if we have the aggregate already (we only need to record the
+ * aggregate once)
+ */
+ i = 0;
+ foreach(ag, pstate->p_aggs)
+ {
+ Aggreg *a = lfirst(ag);
+
+ if (!strcmp(a->aggname, aggreg->aggname) &&
+ equal(a->target, aggreg->target))
+ {
+
+ /* fill in the aggno and we're done */
+ aggreg->aggno = i;
+ return;
+ }
+ i++;
}
- i++;
- }
-
- /* not found, new aggregate */
- aggreg->aggno = i;
- pstate->p_numAgg++;
- pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
- return;
+
+ /* not found, new aggregate */
+ aggreg->aggno = i;
+ pstate->p_numAgg++;
+ pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
+ return;
}
/*
* finalizeAggregates -
- * fill in qry_aggs from pstate. Also checks to make sure that aggregates
- * are used in the proper place.
+ * fill in qry_aggs from pstate. Also checks to make sure that aggregates
+ * are used in the proper place.
*/
static void
-finalizeAggregates(ParseState *pstate, Query *qry)
-{
- List *l;
- int i;
-
- parseCheckAggregates(pstate, qry);
-
- qry->qry_numAgg = pstate->p_numAgg;
- qry->qry_aggs =
- (Aggreg **)palloc(sizeof(Aggreg *) * qry->qry_numAgg);
- i = 0;
- foreach(l, pstate->p_aggs)
- qry->qry_aggs[i++] = (Aggreg*)lfirst(l);
+finalizeAggregates(ParseState * pstate, Query * qry)
+{
+ List *l;
+ int i;
+
+ parseCheckAggregates(pstate, qry);
+
+ qry->qry_numAgg = pstate->p_numAgg;
+ qry->qry_aggs =
+ (Aggreg **) palloc(sizeof(Aggreg *) * qry->qry_numAgg);
+ i = 0;
+ foreach(l, pstate->p_aggs)
+ qry->qry_aggs[i++] = (Aggreg *) lfirst(l);
}
-/*
+/*
* contain_agg_clause--
- * Recursively find aggreg nodes from a clause.
- *
- * Returns true if any aggregate found.
+ * Recursively find aggreg nodes from a clause.
+ *
+ * Returns true if any aggregate found.
*/
-static bool
-contain_agg_clause(Node *clause)
+static bool
+contain_agg_clause(Node * clause)
{
- if (clause==NULL)
- return FALSE;
- else if (IsA(clause,Aggreg))
- return TRUE;
- else if (IsA(clause,Iter))
- return contain_agg_clause(((Iter*)clause)->iterexpr);
- else if (single_node(clause))
- return FALSE;
- else if (or_clause(clause)) {
- List *temp;
-
- foreach (temp, ((Expr*)clause)->args)
- if (contain_agg_clause(lfirst(temp)))
+ if (clause == NULL)
+ return FALSE;
+ else if (IsA(clause, Aggreg))
return TRUE;
- return FALSE;
- } else if (is_funcclause (clause)) {
- List *temp;
+ else if (IsA(clause, Iter))
+ return contain_agg_clause(((Iter *) clause)->iterexpr);
+ else if (single_node(clause))
+ return FALSE;
+ else if (or_clause(clause))
+ {
+ List *temp;
- foreach(temp, ((Expr *)clause)->args)
- if (contain_agg_clause(lfirst(temp)))
- return TRUE;
- return FALSE;
- } else if (IsA(clause,ArrayRef)) {
- List *temp;
+ foreach(temp, ((Expr *) clause)->args)
+ if (contain_agg_clause(lfirst(temp)))
+ return TRUE;
+ return FALSE;
+ }
+ else if (is_funcclause(clause))
+ {
+ List *temp;
- foreach(temp, ((ArrayRef*)clause)->refupperindexpr)
- if (contain_agg_clause(lfirst(temp)))
- return TRUE;
- foreach(temp, ((ArrayRef*)clause)->reflowerindexpr)
- if (contain_agg_clause(lfirst(temp)))
- return TRUE;
- if (contain_agg_clause(((ArrayRef*)clause)->refexpr))
- return TRUE;
- if (contain_agg_clause(((ArrayRef*)clause)->refassgnexpr))
- return TRUE;
- return FALSE;
- } else if (not_clause(clause))
- return contain_agg_clause((Node*)get_notclausearg((Expr*)clause));
- else if (is_opclause(clause))
- return (contain_agg_clause((Node*)get_leftop((Expr*)clause)) ||
- contain_agg_clause((Node*)get_rightop((Expr*)clause)));
+ foreach(temp, ((Expr *) clause)->args)
+ if (contain_agg_clause(lfirst(temp)))
+ return TRUE;
+ return FALSE;
+ }
+ else if (IsA(clause, ArrayRef))
+ {
+ List *temp;
+
+ foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
+ if (contain_agg_clause(lfirst(temp)))
+ return TRUE;
+ foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
+ if (contain_agg_clause(lfirst(temp)))
+ return TRUE;
+ if (contain_agg_clause(((ArrayRef *) clause)->refexpr))
+ return TRUE;
+ if (contain_agg_clause(((ArrayRef *) clause)->refassgnexpr))
+ return TRUE;
+ return FALSE;
+ }
+ else if (not_clause(clause))
+ return contain_agg_clause((Node *) get_notclausearg((Expr *) clause));
+ else if (is_opclause(clause))
+ return (contain_agg_clause((Node *) get_leftop((Expr *) clause)) ||
+ contain_agg_clause((Node *) get_rightop((Expr *) clause)));
- return FALSE;
+ return FALSE;
}
/*
* exprIsAggOrGroupCol -
- * returns true if the expression does not contain non-group columns.
+ * returns true if the expression does not contain non-group columns.
*/
-static bool
-exprIsAggOrGroupCol(Node *expr, List *groupClause)
+static bool
+exprIsAggOrGroupCol(Node * expr, List * groupClause)
{
- List *gl;
-
- if ( expr == NULL || IsA (expr, Const) ||
- IsA (expr, Param) || IsA (expr, Aggreg) )
- return TRUE;
-
- foreach (gl, groupClause)
- {
- GroupClause *grpcl = lfirst(gl);
-
- if ( equal (expr, grpcl->entry->expr) )
+ List *gl;
+
+ if (expr == NULL || IsA(expr, Const) ||
+ IsA(expr, Param) || IsA(expr, Aggreg))
return TRUE;
- }
- if ( IsA (expr, Expr) )
- {
- List *temp;
+ foreach(gl, groupClause)
+ {
+ GroupClause *grpcl = lfirst(gl);
- foreach (temp, ((Expr*)expr)->args)
- if (!exprIsAggOrGroupCol(lfirst(temp),groupClause))
- return FALSE;
- return TRUE;
- }
+ if (equal(expr, grpcl->entry->expr))
+ return TRUE;
+ }
+
+ if (IsA(expr, Expr))
+ {
+ List *temp;
+
+ foreach(temp, ((Expr *) expr)->args)
+ if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
+ return FALSE;
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
/*
* tleIsAggOrGroupCol -
- * returns true if the TargetEntry is Agg or GroupCol.
+ * returns true if the TargetEntry is Agg or GroupCol.
*/
-static bool
-tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
+static bool
+tleIsAggOrGroupCol(TargetEntry * tle, List * groupClause)
{
- Node *expr = tle->expr;
- List *gl;
-
- if ( expr == NULL || IsA (expr, Const) || IsA (expr, Param) )
- return TRUE;
-
- foreach (gl, groupClause)
- {
- GroupClause *grpcl = lfirst(gl);
-
- if ( tle->resdom->resno == grpcl->entry->resdom->resno )
- {
- if ( contain_agg_clause ((Node*) expr) )
- elog (WARN, "parser: aggregates not allowed in GROUP BY clause");
- return TRUE;
+ Node *expr = tle->expr;
+ List *gl;
+
+ if (expr == NULL || IsA(expr, Const) || IsA(expr, Param))
+ return TRUE;
+
+ foreach(gl, groupClause)
+ {
+ GroupClause *grpcl = lfirst(gl);
+
+ if (tle->resdom->resno == grpcl->entry->resdom->resno)
+ {
+ if (contain_agg_clause((Node *) expr))
+ elog(WARN, "parser: aggregates not allowed in GROUP BY clause");
+ return TRUE;
+ }
}
- }
- if ( IsA (expr, Aggreg) )
- return TRUE;
+ if (IsA(expr, Aggreg))
+ return TRUE;
- if ( IsA (expr, Expr) )
- {
- List *temp;
+ if (IsA(expr, Expr))
+ {
+ List *temp;
- foreach (temp, ((Expr*)expr)->args)
- if (!exprIsAggOrGroupCol(lfirst(temp),groupClause))
- return FALSE;
- return TRUE;
- }
+ foreach(temp, ((Expr *) expr)->args)
+ if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
+ return FALSE;
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
/*
* parseCheckAggregates -
- * this should really be done earlier but the current grammar
- * cannot differentiate functions from aggregates. So we have do check
- * here when the target list and the qualifications are finalized.
+ * this should really be done earlier but the current grammar
+ * cannot differentiate functions from aggregates. So we have do check
+ * here when the target list and the qualifications are finalized.
*/
static void
-parseCheckAggregates(ParseState *pstate, Query *qry)
+parseCheckAggregates(ParseState * pstate, Query * qry)
{
- List *tl;
- Assert(pstate->p_numAgg > 0);
-
- /*
- * aggregates never appear in WHERE clauses. (we have to check where
- * clause first because if there is an aggregate, the check for
- * non-group column in target list may fail.)
- */
- if (contain_agg_clause(qry->qual))
- elog(WARN, "parser: aggregates not allowed in WHERE clause");
-
- /*
- * the target list can only contain aggregates, group columns and
- * functions thereof.
- */
- foreach (tl, qry->targetList) {
- TargetEntry *tle = lfirst(tl);
- if (!tleIsAggOrGroupCol(tle, qry->groupClause))
- elog(WARN,
- "parser: illegal use of aggregates or non-group column in target list");
- }
-
- /*
- * the expression specified in the HAVING clause has the same restriction
- * as those in the target list.
- */
+ List *tl;
+
+ Assert(pstate->p_numAgg > 0);
+
+ /*
+ * aggregates never appear in WHERE clauses. (we have to check where
+ * clause first because if there is an aggregate, the check for
+ * non-group column in target list may fail.)
+ */
+ if (contain_agg_clause(qry->qual))
+ elog(WARN, "parser: aggregates not allowed in WHERE clause");
+
+ /*
+ * the target list can only contain aggregates, group columns and
+ * functions thereof.
+ */
+ foreach(tl, qry->targetList)
+ {
+ TargetEntry *tle = lfirst(tl);
+
+ if (!tleIsAggOrGroupCol(tle, qry->groupClause))
+ elog(WARN,
+ "parser: illegal use of aggregates or non-group column in target list");
+ }
+
+ /*
+ * the expression specified in the HAVING clause has the same
+ * restriction as those in the target list.
+ */
/*
- * Need to change here when we get HAVING works. Currently
- * qry->havingQual is NULL. - vadim 04/05/97
- if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause))
- elog(WARN,
- "parser: illegal use of aggregates or non-group column in HAVING clause");
- */
- return;
+ * Need to change here when we get HAVING works. Currently
+ * qry->havingQual is NULL. - vadim 04/05/97
+ if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause))
+ elog(WARN,
+ "parser: illegal use of aggregates or non-group column in HAVING clause");
+ */
+ return;
}
diff --git a/src/backend/parser/catalog_utils.c b/src/backend/parser/catalog_utils.c
index 043c2865060..41e6fffac9b 100644
--- a/src/backend/parser/catalog_utils.c
+++ b/src/backend/parser/catalog_utils.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/catalog_utils.c,v 1.22 1997/08/22 00:02:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/catalog_utils.c,v 1.23 1997/09/07 04:44:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -48,83 +48,110 @@
#include "utils/lsyscache.h"
#include "storage/lmgr.h"
-#include "port-protos.h" /* strdup() */
-
-struct {
- char *field;
- int code;
-} special_attr[] = {
- { "ctid", SelfItemPointerAttributeNumber },
- { "oid", ObjectIdAttributeNumber },
- { "xmin", MinTransactionIdAttributeNumber },
- { "cmin", MinCommandIdAttributeNumber },
- { "xmax", MaxTransactionIdAttributeNumber },
- { "cmax", MaxCommandIdAttributeNumber },
- { "chain", ChainItemPointerAttributeNumber },
- { "anchor", AnchorItemPointerAttributeNumber },
- { "tmin", MinAbsoluteTimeAttributeNumber },
- { "tmax", MaxAbsoluteTimeAttributeNumber },
- { "vtype", VersionTypeAttributeNumber }
+#include "port-protos.h" /* strdup() */
+
+struct
+{
+ char *field;
+ int code;
+} special_attr[] =
+
+{
+ {
+ "ctid", SelfItemPointerAttributeNumber
+ },
+ {
+ "oid", ObjectIdAttributeNumber
+ },
+ {
+ "xmin", MinTransactionIdAttributeNumber
+ },
+ {
+ "cmin", MinCommandIdAttributeNumber
+ },
+ {
+ "xmax", MaxTransactionIdAttributeNumber
+ },
+ {
+ "cmax", MaxCommandIdAttributeNumber
+ },
+ {
+ "chain", ChainItemPointerAttributeNumber
+ },
+ {
+ "anchor", AnchorItemPointerAttributeNumber
+ },
+ {
+ "tmin", MinAbsoluteTimeAttributeNumber
+ },
+ {
+ "tmax", MaxAbsoluteTimeAttributeNumber
+ },
+ {
+ "vtype", VersionTypeAttributeNumber
+ }
};
#define SPECIALS (sizeof(special_attr)/sizeof(*special_attr))
-
-static char *attnum_type[SPECIALS] = {
- "tid",
- "oid",
- "xid",
- "cid",
- "xid",
- "cid",
- "tid",
- "tid",
- "abstime",
- "abstime",
- "char"
- };
-
-#define MAXFARGS 8 /* max # args to a c or postquel function */
+
+static char *attnum_type[SPECIALS] = {
+ "tid",
+ "oid",
+ "xid",
+ "cid",
+ "xid",
+ "cid",
+ "tid",
+ "tid",
+ "abstime",
+ "abstime",
+ "char"
+};
+
+#define MAXFARGS 8 /* max # args to a c or postquel function */
/*
- * This structure is used to explore the inheritance hierarchy above
- * nodes in the type tree in order to disambiguate among polymorphic
- * functions.
+ * This structure is used to explore the inheritance hierarchy above
+ * nodes in the type tree in order to disambiguate among polymorphic
+ * functions.
*/
-typedef struct _InhPaths {
- int nsupers; /* number of superclasses */
- Oid self; /* this class */
- Oid *supervec; /* vector of superclasses */
-} InhPaths;
+typedef struct _InhPaths
+{
+ int nsupers; /* number of superclasses */
+ Oid self; /* this class */
+ Oid *supervec; /* vector of superclasses */
+} InhPaths;
/*
- * This structure holds a list of possible functions or operators that
- * agree with the known name and argument types of the function/operator.
+ * This structure holds a list of possible functions or operators that
+ * agree with the known name and argument types of the function/operator.
*/
-typedef struct _CandidateList {
- Oid *args;
- struct _CandidateList *next;
-} *CandidateList;
-
-static Oid **argtype_inherit(int nargs, Oid *oid_array);
-static Oid **genxprod(InhPaths *arginh, int nargs);
-static int findsupers(Oid relid, Oid **supervec);
-static bool check_typeid(Oid id);
-static char *instr1(TypeTupleForm tp, char *string, int typlen);
-static void op_error(char *op, Oid arg1, Oid arg2);
+typedef struct _CandidateList
+{
+ Oid *args;
+ struct _CandidateList *next;
+} *CandidateList;
+
+static Oid **argtype_inherit(int nargs, Oid * oid_array);
+static Oid **genxprod(InhPaths * arginh, int nargs);
+static int findsupers(Oid relid, Oid ** supervec);
+static bool check_typeid(Oid id);
+static char *instr1(TypeTupleForm tp, char *string, int typlen);
+static void op_error(char *op, Oid arg1, Oid arg2);
/* check to see if a type id is valid,
- * returns true if it is. By using this call before calling
+ * returns true if it is. By using this call before calling
* get_id_type or get_id_typname, more meaningful error messages
* can be produced because the caller typically has more context of
- * what's going on - jolly
+ * what's going on - jolly
*/
-static bool
+static bool
check_typeid(Oid id)
{
- return (SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(id),
- 0,0,0) != NULL);
+ return (SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(id),
+ 0, 0, 0) != NULL);
}
@@ -132,46 +159,50 @@ check_typeid(Oid id)
Type
get_id_type(Oid id)
{
- HeapTuple tup;
-
- if (!(tup = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(id),
- 0,0,0))) {
- elog ( WARN, "type id lookup of %ud failed", id);
- return(NULL);
- }
- return((Type) tup);
+ HeapTuple tup;
+
+ if (!(tup = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(id),
+ 0, 0, 0)))
+ {
+ elog(WARN, "type id lookup of %ud failed", id);
+ return (NULL);
+ }
+ return ((Type) tup);
}
/* return a type name, given a typeid */
-char*
+char *
get_id_typname(Oid id)
{
- HeapTuple tup;
- TypeTupleForm typetuple;
-
- if (!(tup = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(id),
- 0,0,0))) {
- elog ( WARN, "type id lookup of %ud failed", id);
- return(NULL);
- }
- typetuple = (TypeTupleForm)GETSTRUCT(tup);
- return (typetuple->typname).data;
+ HeapTuple tup;
+ TypeTupleForm typetuple;
+
+ if (!(tup = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(id),
+ 0, 0, 0)))
+ {
+ elog(WARN, "type id lookup of %ud failed", id);
+ return (NULL);
+ }
+ typetuple = (TypeTupleForm) GETSTRUCT(tup);
+ return (typetuple->typname).data;
}
/* return a Type structure, given type name */
Type
type(char *s)
{
- HeapTuple tup;
-
- if (s == NULL) {
- elog ( WARN , "type(): Null type" );
- }
-
- if (!(tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(s), 0,0,0))) {
- elog (WARN , "type name lookup of %s failed", s);
- }
- return((Type) tup);
+ HeapTuple tup;
+
+ if (s == NULL)
+ {
+ elog(WARN, "type(): Null type");
+ }
+
+ if (!(tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(s), 0, 0, 0)))
+ {
+ elog(WARN, "type name lookup of %s failed", s);
+ }
+ return ((Type) tup);
}
/* given attribute id, return type of that attribute */
@@ -179,297 +210,327 @@ type(char *s)
Oid
att_typeid(Relation rd, int attid)
{
-
- if (attid < 0) {
- return(typeid(type(attnum_type[-attid-1])));
- }
- /* -1 because varattno (where attid comes from) returns one
- more than index */
- return(rd->rd_att->attrs[attid-1]->atttypid);
+
+ if (attid < 0)
+ {
+ return (typeid(type(attnum_type[-attid - 1])));
+ }
+
+ /*
+ * -1 because varattno (where attid comes from) returns one more than
+ * index
+ */
+ return (rd->rd_att->attrs[attid - 1]->atttypid);
}
int
att_attnelems(Relation rd, int attid)
{
- return(rd->rd_att->attrs[attid-1]->attnelems);
+ return (rd->rd_att->attrs[attid - 1]->attnelems);
}
/* given type, return the type OID */
Oid
typeid(Type tp)
{
- if (tp == NULL) {
- elog ( WARN , "typeid() called with NULL type struct");
- }
- return(tp->t_oid);
+ if (tp == NULL)
+ {
+ elog(WARN, "typeid() called with NULL type struct");
+ }
+ return (tp->t_oid);
}
/* given type (as type struct), return the length of type */
int16
tlen(Type t)
{
- TypeTupleForm typ;
-
- typ = (TypeTupleForm)GETSTRUCT(t);
- return(typ->typlen);
+ TypeTupleForm typ;
+
+ typ = (TypeTupleForm) GETSTRUCT(t);
+ return (typ->typlen);
}
/* given type (as type struct), return the value of its 'byval' attribute.*/
bool
tbyval(Type t)
{
- TypeTupleForm typ;
-
- typ = (TypeTupleForm)GETSTRUCT(t);
- return(typ->typbyval);
+ TypeTupleForm typ;
+
+ typ = (TypeTupleForm) GETSTRUCT(t);
+ return (typ->typbyval);
}
/* given type (as type struct), return the name of type */
-char*
+char *
tname(Type t)
{
- TypeTupleForm typ;
-
- typ = (TypeTupleForm)GETSTRUCT(t);
- return (typ->typname).data;
+ TypeTupleForm typ;
+
+ typ = (TypeTupleForm) GETSTRUCT(t);
+ return (typ->typname).data;
}
/* given type (as type struct), return wether type is passed by value */
int
tbyvalue(Type t)
{
- TypeTupleForm typ;
-
- typ = (TypeTupleForm) GETSTRUCT(t);
- return(typ->typbyval);
+ TypeTupleForm typ;
+
+ typ = (TypeTupleForm) GETSTRUCT(t);
+ return (typ->typbyval);
}
/* given a type, return its typetype ('c' for 'c'atalog types) */
static char
typetypetype(Type t)
{
- TypeTupleForm typ;
-
- typ = (TypeTupleForm) GETSTRUCT(t);
- return(typ->typtype);
+ TypeTupleForm typ;
+
+ typ = (TypeTupleForm) GETSTRUCT(t);
+ return (typ->typtype);
}
/* given operator, return the operator OID */
Oid
oprid(Operator op)
{
- return(op->t_oid);
+ return (op->t_oid);
}
/*
- * given opname, leftTypeId and rightTypeId,
- * find all possible (arg1, arg2) pairs for which an operator named
- * opname exists, such that leftTypeId can be coerced to arg1 and
- * rightTypeId can be coerced to arg2
+ * given opname, leftTypeId and rightTypeId,
+ * find all possible (arg1, arg2) pairs for which an operator named
+ * opname exists, such that leftTypeId can be coerced to arg1 and
+ * rightTypeId can be coerced to arg2
*/
static int
binary_oper_get_candidates(char *opname,
- Oid leftTypeId,
- Oid rightTypeId,
- CandidateList *candidates)
+ Oid leftTypeId,
+ Oid rightTypeId,
+ CandidateList * candidates)
{
- CandidateList current_candidate;
- Relation pg_operator_desc;
- HeapScanDesc pg_operator_scan;
- HeapTuple tup;
- OperatorTupleForm oper;
- Buffer buffer;
- int nkeys;
- int ncandidates = 0;
- ScanKeyData opKey[3];
-
- *candidates = NULL;
-
- ScanKeyEntryInitialize(&opKey[0], 0,
- Anum_pg_operator_oprname,
- NameEqualRegProcedure,
- NameGetDatum(opname));
-
- ScanKeyEntryInitialize(&opKey[1], 0,
- Anum_pg_operator_oprkind,
- CharacterEqualRegProcedure,
- CharGetDatum('b'));
-
-
- if (leftTypeId == UNKNOWNOID) {
- if (rightTypeId == UNKNOWNOID) {
- nkeys = 2;
- } else {
- nkeys = 3;
-
- ScanKeyEntryInitialize(&opKey[2], 0,
- Anum_pg_operator_oprright,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(rightTypeId));
- }
- } else if (rightTypeId == UNKNOWNOID) {
- nkeys = 3;
-
- ScanKeyEntryInitialize(&opKey[2], 0,
- Anum_pg_operator_oprleft,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(leftTypeId));
- } else {
- /* currently only "unknown" can be coerced */
- return 0;
- }
-
- pg_operator_desc = heap_openr(OperatorRelationName);
- pg_operator_scan = heap_beginscan(pg_operator_desc,
- 0,
- SelfTimeQual,
- nkeys,
- opKey);
-
- do {
- tup = heap_getnext(pg_operator_scan, 0, &buffer);
- if (HeapTupleIsValid(tup)) {
- current_candidate = (CandidateList)palloc(sizeof(struct _CandidateList));
- current_candidate->args = (Oid *)palloc(2 * sizeof(Oid));
-
- oper = (OperatorTupleForm)GETSTRUCT(tup);
- current_candidate->args[0] = oper->oprleft;
- current_candidate->args[1] = oper->oprright;
- current_candidate->next = *candidates;
- *candidates = current_candidate;
- ncandidates++;
- ReleaseBuffer(buffer);
+ CandidateList current_candidate;
+ Relation pg_operator_desc;
+ HeapScanDesc pg_operator_scan;
+ HeapTuple tup;
+ OperatorTupleForm oper;
+ Buffer buffer;
+ int nkeys;
+ int ncandidates = 0;
+ ScanKeyData opKey[3];
+
+ *candidates = NULL;
+
+ ScanKeyEntryInitialize(&opKey[0], 0,
+ Anum_pg_operator_oprname,
+ NameEqualRegProcedure,
+ NameGetDatum(opname));
+
+ ScanKeyEntryInitialize(&opKey[1], 0,
+ Anum_pg_operator_oprkind,
+ CharacterEqualRegProcedure,
+ CharGetDatum('b'));
+
+
+ if (leftTypeId == UNKNOWNOID)
+ {
+ if (rightTypeId == UNKNOWNOID)
+ {
+ nkeys = 2;
+ }
+ else
+ {
+ nkeys = 3;
+
+ ScanKeyEntryInitialize(&opKey[2], 0,
+ Anum_pg_operator_oprright,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(rightTypeId));
+ }
+ }
+ else if (rightTypeId == UNKNOWNOID)
+ {
+ nkeys = 3;
+
+ ScanKeyEntryInitialize(&opKey[2], 0,
+ Anum_pg_operator_oprleft,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(leftTypeId));
}
- } while(HeapTupleIsValid(tup));
-
- heap_endscan(pg_operator_scan);
- heap_close(pg_operator_desc);
-
- return ncandidates;
+ else
+ {
+ /* currently only "unknown" can be coerced */
+ return 0;
+ }
+
+ pg_operator_desc = heap_openr(OperatorRelationName);
+ pg_operator_scan = heap_beginscan(pg_operator_desc,
+ 0,
+ SelfTimeQual,
+ nkeys,
+ opKey);
+
+ do
+ {
+ tup = heap_getnext(pg_operator_scan, 0, &buffer);
+ if (HeapTupleIsValid(tup))
+ {
+ current_candidate = (CandidateList) palloc(sizeof(struct _CandidateList));
+ current_candidate->args = (Oid *) palloc(2 * sizeof(Oid));
+
+ oper = (OperatorTupleForm) GETSTRUCT(tup);
+ current_candidate->args[0] = oper->oprleft;
+ current_candidate->args[1] = oper->oprright;
+ current_candidate->next = *candidates;
+ *candidates = current_candidate;
+ ncandidates++;
+ ReleaseBuffer(buffer);
+ }
+ } while (HeapTupleIsValid(tup));
+
+ heap_endscan(pg_operator_scan);
+ heap_close(pg_operator_desc);
+
+ return ncandidates;
}
/*
* equivalentOpersAfterPromotion -
- * checks if a list of candidate operators obtained from
- * binary_oper_get_candidates() contain equivalent operators. If
- * this routine is called, we have more than 1 candidate and need to
- * decided whether to pick one of them. This routine returns true if
- * the all the candidates operate on the same data types after
- * promotion (int2, int4, float4 -> float8).
+ * checks if a list of candidate operators obtained from
+ * binary_oper_get_candidates() contain equivalent operators. If
+ * this routine is called, we have more than 1 candidate and need to
+ * decided whether to pick one of them. This routine returns true if
+ * the all the candidates operate on the same data types after
+ * promotion (int2, int4, float4 -> float8).
*/
-static bool
+static bool
equivalentOpersAfterPromotion(CandidateList candidates)
{
- CandidateList result;
- CandidateList promotedCandidates = NULL;
- Oid leftarg, rightarg;
-
- for (result = candidates; result != NULL; result = result->next) {
- CandidateList c;
- c = (CandidateList)palloc(sizeof(*c));
- c->args = (Oid *)palloc(2 * sizeof(Oid));
- switch (result->args[0]) {
- case FLOAT4OID:
- case INT4OID:
- case INT2OID:
- case CASHOID:
- c->args[0] = FLOAT8OID;
- break;
- default:
- c->args[0] = result->args[0];
- break;
+ CandidateList result;
+ CandidateList promotedCandidates = NULL;
+ Oid leftarg,
+ rightarg;
+
+ for (result = candidates; result != NULL; result = result->next)
+ {
+ CandidateList c;
+
+ c = (CandidateList) palloc(sizeof(*c));
+ c->args = (Oid *) palloc(2 * sizeof(Oid));
+ switch (result->args[0])
+ {
+ case FLOAT4OID:
+ case INT4OID:
+ case INT2OID:
+ case CASHOID:
+ c->args[0] = FLOAT8OID;
+ break;
+ default:
+ c->args[0] = result->args[0];
+ break;
+ }
+ switch (result->args[1])
+ {
+ case FLOAT4OID:
+ case INT4OID:
+ case INT2OID:
+ case CASHOID:
+ c->args[1] = FLOAT8OID;
+ break;
+ default:
+ c->args[1] = result->args[1];
+ break;
+ }
+ c->next = promotedCandidates;
+ promotedCandidates = c;
}
- switch (result->args[1]) {
- case FLOAT4OID:
- case INT4OID:
- case INT2OID:
- case CASHOID:
- c->args[1] = FLOAT8OID;
- break;
- default:
- c->args[1] = result->args[1];
- break;
+
+ /*
+ * if we get called, we have more than 1 candidates so we can do the
+ * following safely
+ */
+ leftarg = promotedCandidates->args[0];
+ rightarg = promotedCandidates->args[1];
+
+ for (result = promotedCandidates->next; result != NULL; result = result->next)
+ {
+ if (result->args[0] != leftarg || result->args[1] != rightarg)
+
+ /*
+ * this list contains operators that operate on different data
+ * types even after promotion. Hence we can't decide on which
+ * one to pick. The user must do explicit type casting.
+ */
+ return FALSE;
}
- c->next = promotedCandidates;
- promotedCandidates = c;
- }
-
- /* if we get called, we have more than 1 candidates so we can do the
- following safely */
- leftarg = promotedCandidates->args[0];
- rightarg = promotedCandidates->args[1];
-
- for (result=promotedCandidates->next; result!=NULL; result=result->next) {
- if (result->args[0]!=leftarg || result->args[1]!=rightarg)
- /*
- * this list contains operators that operate on different
- * data types even after promotion. Hence we can't decide on
- * which one to pick. The user must do explicit type casting.
- */
- return FALSE;
- }
-
- /* all the candidates are equivalent in the following sense: they operate
- on equivalent data types and picking any one of them is as good. */
- return TRUE;
+
+ /*
+ * all the candidates are equivalent in the following sense: they
+ * operate on equivalent data types and picking any one of them is as
+ * good.
+ */
+ return TRUE;
}
-
+
/*
- * given a choice of argument type pairs for a binary operator,
- * try to choose a default pair
+ * given a choice of argument type pairs for a binary operator,
+ * try to choose a default pair
*/
-static CandidateList
+static CandidateList
binary_oper_select_candidate(Oid arg1,
- Oid arg2,
- CandidateList candidates)
+ Oid arg2,
+ CandidateList candidates)
{
- CandidateList result;
-
- /*
- * if both are "unknown", there is no way to select a candidate
- *
- * current wisdom holds that the default operator should be one
- * in which both operands have the same type (there will only
- * be one such operator)
- *
- * 7.27.93 - I have decided not to do this; it's too hard to
- * justify, and it's easy enough to typecast explicitly -avi
- * [the rest of this routine were commented out since then -ay]
- */
-
- if (arg1 == UNKNOWNOID && arg2 == UNKNOWNOID)
- return (NULL);
+ CandidateList result;
+
+ /*
+ * if both are "unknown", there is no way to select a candidate
+ *
+ * current wisdom holds that the default operator should be one in which
+ * both operands have the same type (there will only be one such
+ * operator)
+ *
+ * 7.27.93 - I have decided not to do this; it's too hard to justify, and
+ * it's easy enough to typecast explicitly -avi [the rest of this
+ * routine were commented out since then -ay]
+ */
+
+ if (arg1 == UNKNOWNOID && arg2 == UNKNOWNOID)
+ return (NULL);
+
+ /*
+ * 6/23/95 - I don't complete agree with avi. In particular, casting
+ * floats is a pain for users. Whatever the rationale behind not doing
+ * this is, I need the following special case to work.
+ *
+ * In the WHERE clause of a query, if a float is specified without
+ * quotes, we treat it as float8. I added the float48* operators so
+ * that we can operate on float4 and float8. But now we have more than
+ * one matching operator if the right arg is unknown (eg. float
+ * specified with quotes). This break some stuff in the regression
+ * test where there are floats in quotes not properly casted. Below is
+ * the solution. In addition to requiring the operator operates on the
+ * same type for both operands [as in the code Avi originally
+ * commented out], we also require that the operators be equivalent in
+ * some sense. (see equivalentOpersAfterPromotion for details.) - ay
+ * 6/95
+ */
+ if (!equivalentOpersAfterPromotion(candidates))
+ return NULL;
+
+ /*
+ * if we get here, any one will do but we're more picky and require
+ * both operands be the same.
+ */
+ for (result = candidates; result != NULL; result = result->next)
+ {
+ if (result->args[0] == result->args[1])
+ return result;
+ }
- /*
- * 6/23/95 - I don't complete agree with avi. In particular, casting
- * floats is a pain for users. Whatever the rationale behind not doing
- * this is, I need the following special case to work.
- *
- * In the WHERE clause of a query, if a float is specified without
- * quotes, we treat it as float8. I added the float48* operators so
- * that we can operate on float4 and float8. But now we have more
- * than one matching operator if the right arg is unknown (eg. float
- * specified with quotes). This break some stuff in the regression
- * test where there are floats in quotes not properly casted. Below
- * is the solution. In addition to requiring the operator operates
- * on the same type for both operands [as in the code Avi originally
- * commented out], we also require that the operators be equivalent
- * in some sense. (see equivalentOpersAfterPromotion for details.)
- * - ay 6/95
- */
- if (!equivalentOpersAfterPromotion(candidates))
- return NULL;
-
- /* if we get here, any one will do but we're more picky and require
- both operands be the same. */
- for (result = candidates; result != NULL; result = result->next) {
- if (result->args[0] == result->args[1])
- return result;
- }
-
- return (NULL);
+ return (NULL);
}
/* Given operator, types of arg1, and arg2, return oper struct */
@@ -477,135 +538,158 @@ binary_oper_select_candidate(Oid arg1,
Operator
oper(char *op, Oid arg1, Oid arg2, bool noWarnings)
{
- HeapTuple tup;
- CandidateList candidates;
- int ncandidates;
-
- if (!arg2) arg2=arg1;
- if (!arg1) arg1=arg2;
-
- if (!(tup = SearchSysCacheTuple(OPRNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(arg1),
- ObjectIdGetDatum(arg2),
- Int8GetDatum('b')))) {
- ncandidates = binary_oper_get_candidates(op, arg1, arg2, &candidates);
- if (ncandidates == 0) {
- /*
- * no operators of the desired types found
- */
- if (!noWarnings)
- op_error(op, arg1, arg2);
- return(NULL);
- } else if (ncandidates == 1) {
- /*
- * exactly one operator of the desired types found
- */
- tup = SearchSysCacheTuple(OPRNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(candidates->args[0]),
- ObjectIdGetDatum(candidates->args[1]),
- Int8GetDatum('b'));
- Assert(HeapTupleIsValid(tup));
- } else {
- /*
- * multiple operators of the desired types found
- */
- candidates = binary_oper_select_candidate(arg1, arg2, candidates);
- if (candidates != NULL) {
- /* we chose one of them */
- tup = SearchSysCacheTuple(OPRNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(candidates->args[0]),
- ObjectIdGetDatum(candidates->args[1]),
- Int8GetDatum('b'));
- Assert(HeapTupleIsValid(tup));
- } else {
- Type tp1, tp2;
-
- /* we chose none of them */
- tp1 = get_id_type(arg1);
- tp2 = get_id_type(arg2);
- if (!noWarnings) {
- elog(NOTICE, "there is more than one operator %s for types", op);
- elog(NOTICE, "%s and %s. You will have to retype this query",
- tname(tp1), tname(tp2));
- elog(WARN, "using an explicit cast");
+ HeapTuple tup;
+ CandidateList candidates;
+ int ncandidates;
+
+ if (!arg2)
+ arg2 = arg1;
+ if (!arg1)
+ arg1 = arg2;
+
+ if (!(tup = SearchSysCacheTuple(OPRNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(arg1),
+ ObjectIdGetDatum(arg2),
+ Int8GetDatum('b'))))
+ {
+ ncandidates = binary_oper_get_candidates(op, arg1, arg2, &candidates);
+ if (ncandidates == 0)
+ {
+
+ /*
+ * no operators of the desired types found
+ */
+ if (!noWarnings)
+ op_error(op, arg1, arg2);
+ return (NULL);
+ }
+ else if (ncandidates == 1)
+ {
+
+ /*
+ * exactly one operator of the desired types found
+ */
+ tup = SearchSysCacheTuple(OPRNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(candidates->args[0]),
+ ObjectIdGetDatum(candidates->args[1]),
+ Int8GetDatum('b'));
+ Assert(HeapTupleIsValid(tup));
+ }
+ else
+ {
+
+ /*
+ * multiple operators of the desired types found
+ */
+ candidates = binary_oper_select_candidate(arg1, arg2, candidates);
+ if (candidates != NULL)
+ {
+ /* we chose one of them */
+ tup = SearchSysCacheTuple(OPRNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(candidates->args[0]),
+ ObjectIdGetDatum(candidates->args[1]),
+ Int8GetDatum('b'));
+ Assert(HeapTupleIsValid(tup));
+ }
+ else
+ {
+ Type tp1,
+ tp2;
+
+ /* we chose none of them */
+ tp1 = get_id_type(arg1);
+ tp2 = get_id_type(arg2);
+ if (!noWarnings)
+ {
+ elog(NOTICE, "there is more than one operator %s for types", op);
+ elog(NOTICE, "%s and %s. You will have to retype this query",
+ tname(tp1), tname(tp2));
+ elog(WARN, "using an explicit cast");
+ }
+ return (NULL);
+ }
}
- return(NULL);
- }
}
- }
- return((Operator) tup);
+ return ((Operator) tup);
}
/*
- * given opname and typeId, find all possible types for which
- * a right/left unary operator named opname exists,
- * such that typeId can be coerced to it
+ * given opname and typeId, find all possible types for which
+ * a right/left unary operator named opname exists,
+ * such that typeId can be coerced to it
*/
static int
unary_oper_get_candidates(char *op,
- Oid typeId,
- CandidateList *candidates,
- char rightleft)
+ Oid typeId,
+ CandidateList * candidates,
+ char rightleft)
{
- CandidateList current_candidate;
- Relation pg_operator_desc;
- HeapScanDesc pg_operator_scan;
- HeapTuple tup;
- OperatorTupleForm oper;
- Buffer buffer;
- int ncandidates = 0;
-
- static ScanKeyData opKey[2] = {
- { 0, Anum_pg_operator_oprname, NameEqualRegProcedure },
- { 0, Anum_pg_operator_oprkind, CharacterEqualRegProcedure } };
-
- *candidates = NULL;
-
- fmgr_info(NameEqualRegProcedure, (func_ptr *) &opKey[0].sk_func,
- &opKey[0].sk_nargs);
- opKey[0].sk_argument = NameGetDatum(op);
- fmgr_info(CharacterEqualRegProcedure, (func_ptr *) &opKey[1].sk_func,
- &opKey[1].sk_nargs);
- opKey[1].sk_argument = CharGetDatum(rightleft);
-
- /* currently, only "unknown" can be coerced */
- /* but we should allow types that are internally the same to be "coerced" */
- if (typeId != UNKNOWNOID) {
- return 0;
- }
-
- pg_operator_desc = heap_openr(OperatorRelationName);
- pg_operator_scan = heap_beginscan(pg_operator_desc,
- 0,
- SelfTimeQual,
- 2,
- opKey);
-
- do {
- tup = heap_getnext(pg_operator_scan, 0, &buffer);
- if (HeapTupleIsValid(tup)) {
- current_candidate = (CandidateList)palloc(sizeof(struct _CandidateList));
- current_candidate->args = (Oid *)palloc(sizeof(Oid));
-
- oper = (OperatorTupleForm)GETSTRUCT(tup);
- if (rightleft == 'r')
- current_candidate->args[0] = oper->oprleft;
- else
- current_candidate->args[0] = oper->oprright;
- current_candidate->next = *candidates;
- *candidates = current_candidate;
- ncandidates++;
- ReleaseBuffer(buffer);
+ CandidateList current_candidate;
+ Relation pg_operator_desc;
+ HeapScanDesc pg_operator_scan;
+ HeapTuple tup;
+ OperatorTupleForm oper;
+ Buffer buffer;
+ int ncandidates = 0;
+
+ static ScanKeyData opKey[2] = {
+ {0, Anum_pg_operator_oprname, NameEqualRegProcedure},
+ {0, Anum_pg_operator_oprkind, CharacterEqualRegProcedure}};
+
+ *candidates = NULL;
+
+ fmgr_info(NameEqualRegProcedure, (func_ptr *) & opKey[0].sk_func,
+ &opKey[0].sk_nargs);
+ opKey[0].sk_argument = NameGetDatum(op);
+ fmgr_info(CharacterEqualRegProcedure, (func_ptr *) & opKey[1].sk_func,
+ &opKey[1].sk_nargs);
+ opKey[1].sk_argument = CharGetDatum(rightleft);
+
+ /* currently, only "unknown" can be coerced */
+
+ /*
+ * but we should allow types that are internally the same to be
+ * "coerced"
+ */
+ if (typeId != UNKNOWNOID)
+ {
+ return 0;
}
- } while(HeapTupleIsValid(tup));
-
- heap_endscan(pg_operator_scan);
- heap_close(pg_operator_desc);
-
- return ncandidates;
+
+ pg_operator_desc = heap_openr(OperatorRelationName);
+ pg_operator_scan = heap_beginscan(pg_operator_desc,
+ 0,
+ SelfTimeQual,
+ 2,
+ opKey);
+
+ do
+ {
+ tup = heap_getnext(pg_operator_scan, 0, &buffer);
+ if (HeapTupleIsValid(tup))
+ {
+ current_candidate = (CandidateList) palloc(sizeof(struct _CandidateList));
+ current_candidate->args = (Oid *) palloc(sizeof(Oid));
+
+ oper = (OperatorTupleForm) GETSTRUCT(tup);
+ if (rightleft == 'r')
+ current_candidate->args[0] = oper->oprleft;
+ else
+ current_candidate->args[0] = oper->oprright;
+ current_candidate->next = *candidates;
+ *candidates = current_candidate;
+ ncandidates++;
+ ReleaseBuffer(buffer);
+ }
+ } while (HeapTupleIsValid(tup));
+
+ heap_endscan(pg_operator_scan);
+ heap_close(pg_operator_desc);
+
+ return ncandidates;
}
/* Given unary right-side operator (operator on right), return oper struct */
@@ -613,42 +697,44 @@ unary_oper_get_candidates(char *op,
Operator
right_oper(char *op, Oid arg)
{
- HeapTuple tup;
- CandidateList candidates;
- int ncandidates;
-
- /*
- if (!OpCache) {
- init_op_cache();
- }
- */
- if (!(tup = SearchSysCacheTuple(OPRNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(arg),
- ObjectIdGetDatum(InvalidOid),
- Int8GetDatum('r')))) {
- ncandidates = unary_oper_get_candidates(op, arg, &candidates, 'r');
- if (ncandidates == 0) {
- elog ( WARN ,
- "Can't find right op: %s for type %d", op, arg );
- return(NULL);
- }
- else if (ncandidates == 1) {
- tup = SearchSysCacheTuple(OPRNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(candidates->args[0]),
- ObjectIdGetDatum(InvalidOid),
- Int8GetDatum('r'));
- Assert(HeapTupleIsValid(tup));
- }
- else {
- elog(NOTICE, "there is more than one right operator %s", op);
- elog(NOTICE, "you will have to retype this query");
- elog(WARN, "using an explicit cast");
- return(NULL);
+ HeapTuple tup;
+ CandidateList candidates;
+ int ncandidates;
+
+ /*
+ * if (!OpCache) { init_op_cache(); }
+ */
+ if (!(tup = SearchSysCacheTuple(OPRNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(arg),
+ ObjectIdGetDatum(InvalidOid),
+ Int8GetDatum('r'))))
+ {
+ ncandidates = unary_oper_get_candidates(op, arg, &candidates, 'r');
+ if (ncandidates == 0)
+ {
+ elog(WARN,
+ "Can't find right op: %s for type %d", op, arg);
+ return (NULL);
+ }
+ else if (ncandidates == 1)
+ {
+ tup = SearchSysCacheTuple(OPRNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(candidates->args[0]),
+ ObjectIdGetDatum(InvalidOid),
+ Int8GetDatum('r'));
+ Assert(HeapTupleIsValid(tup));
+ }
+ else
+ {
+ elog(NOTICE, "there is more than one right operator %s", op);
+ elog(NOTICE, "you will have to retype this query");
+ elog(WARN, "using an explicit cast");
+ return (NULL);
+ }
}
- }
- return((Operator) tup);
+ return ((Operator) tup);
}
/* Given unary left-side operator (operator on left), return oper struct */
@@ -656,42 +742,44 @@ right_oper(char *op, Oid arg)
Operator
left_oper(char *op, Oid arg)
{
- HeapTuple tup;
- CandidateList candidates;
- int ncandidates;
-
- /*
- if (!OpCache) {
- init_op_cache();
- }
- */
- if (!(tup = SearchSysCacheTuple(OPRNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(InvalidOid),
- ObjectIdGetDatum(arg),
- Int8GetDatum('l')))) {
- ncandidates = unary_oper_get_candidates(op, arg, &candidates, 'l');
- if (ncandidates == 0) {
- elog ( WARN ,
- "Can't find left op: %s for type %d", op, arg );
- return(NULL);
- }
- else if (ncandidates == 1) {
- tup = SearchSysCacheTuple(OPRNAME,
- PointerGetDatum(op),
- ObjectIdGetDatum(InvalidOid),
- ObjectIdGetDatum(candidates->args[0]),
- Int8GetDatum('l'));
- Assert(HeapTupleIsValid(tup));
- }
- else {
- elog(NOTICE, "there is more than one left operator %s", op);
- elog(NOTICE, "you will have to retype this query");
- elog(WARN, "using an explicit cast");
- return(NULL);
+ HeapTuple tup;
+ CandidateList candidates;
+ int ncandidates;
+
+ /*
+ * if (!OpCache) { init_op_cache(); }
+ */
+ if (!(tup = SearchSysCacheTuple(OPRNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(InvalidOid),
+ ObjectIdGetDatum(arg),
+ Int8GetDatum('l'))))
+ {
+ ncandidates = unary_oper_get_candidates(op, arg, &candidates, 'l');
+ if (ncandidates == 0)
+ {
+ elog(WARN,
+ "Can't find left op: %s for type %d", op, arg);
+ return (NULL);
+ }
+ else if (ncandidates == 1)
+ {
+ tup = SearchSysCacheTuple(OPRNAME,
+ PointerGetDatum(op),
+ ObjectIdGetDatum(InvalidOid),
+ ObjectIdGetDatum(candidates->args[0]),
+ Int8GetDatum('l'));
+ Assert(HeapTupleIsValid(tup));
+ }
+ else
+ {
+ elog(NOTICE, "there is more than one left operator %s", op);
+ elog(NOTICE, "you will have to retype this query");
+ elog(WARN, "using an explicit cast");
+ return (NULL);
+ }
}
- }
- return((Operator) tup);
+ return ((Operator) tup);
}
/* given range variable, return id of variable */
@@ -699,22 +787,26 @@ left_oper(char *op, Oid arg)
int
varattno(Relation rd, char *a)
{
- int i;
-
- for (i = 0; i < rd->rd_rel->relnatts; i++) {
- if (!namestrcmp(&(rd->rd_att->attrs[i]->attname), a)) {
- return(i+1);
+ int i;
+
+ for (i = 0; i < rd->rd_rel->relnatts; i++)
+ {
+ if (!namestrcmp(&(rd->rd_att->attrs[i]->attname), a))
+ {
+ return (i + 1);
+ }
}
- }
- for (i = 0; i < SPECIALS; i++) {
- if (!strcmp(special_attr[i].field, a)) {
- return(special_attr[i].code);
+ for (i = 0; i < SPECIALS; i++)
+ {
+ if (!strcmp(special_attr[i].field, a))
+ {
+ return (special_attr[i].code);
+ }
}
- }
-
- elog(WARN,"Relation %s does not have attribute %s\n",
- RelationGetRelationName(rd), a );
- return(-1);
+
+ elog(WARN, "Relation %s does not have attribute %s\n",
+ RelationGetRelationName(rd), a);
+ return (-1);
}
/* Given range variable, return whether attribute of this name
@@ -725,104 +817,118 @@ varattno(Relation rd, char *a)
bool
varisset(Relation rd, char *name)
{
- int i;
-
- /* First check if this is a system attribute */
- for (i = 0; i < SPECIALS; i++) {
- if (! strcmp(special_attr[i].field, name)) {
- return(false); /* no sys attr is a set */
+ int i;
+
+ /* First check if this is a system attribute */
+ for (i = 0; i < SPECIALS; i++)
+ {
+ if (!strcmp(special_attr[i].field, name))
+ {
+ return (false); /* no sys attr is a set */
+ }
}
- }
- return (get_attisset(rd->rd_id, name));
+ return (get_attisset(rd->rd_id, name));
}
/* given range variable, return id of variable */
int
nf_varattno(Relation rd, char *a)
{
- int i;
-
- for (i = 0; i < rd->rd_rel->relnatts; i++) {
- if (!namestrcmp(&(rd->rd_att->attrs[i]->attname), a)) {
- return(i+1);
+ int i;
+
+ for (i = 0; i < rd->rd_rel->relnatts; i++)
+ {
+ if (!namestrcmp(&(rd->rd_att->attrs[i]->attname), a))
+ {
+ return (i + 1);
+ }
}
- }
- for (i = 0; i < SPECIALS; i++) {
- if (!strcmp(special_attr[i].field, a)) {
- return(special_attr[i].code);
+ for (i = 0; i < SPECIALS; i++)
+ {
+ if (!strcmp(special_attr[i].field, a))
+ {
+ return (special_attr[i].code);
+ }
}
- }
- return InvalidAttrNumber;
+ return InvalidAttrNumber;
}
/*-------------
* given an attribute number and a relation, return its relation name
*/
-char*
+char *
getAttrName(Relation rd, int attrno)
{
- char *name;
- int i;
-
- if (attrno<0) {
- for (i = 0; i < SPECIALS; i++) {
- if (special_attr[i].code == attrno) {
- name = special_attr[i].field;
- return(name);
- }
+ char *name;
+ int i;
+
+ if (attrno < 0)
+ {
+ for (i = 0; i < SPECIALS; i++)
+ {
+ if (special_attr[i].code == attrno)
+ {
+ name = special_attr[i].field;
+ return (name);
+ }
+ }
+ elog(WARN, "Illegal attr no %d for relation %s\n",
+ attrno, RelationGetRelationName(rd));
+ }
+ else if (attrno >= 1 && attrno <= RelationGetNumberOfAttributes(rd))
+ {
+ name = (rd->rd_att->attrs[attrno - 1]->attname).data;
+ return (name);
+ }
+ else
+ {
+ elog(WARN, "Illegal attr no %d for relation %s\n",
+ attrno, RelationGetRelationName(rd));
}
- elog(WARN, "Illegal attr no %d for relation %s\n",
- attrno, RelationGetRelationName(rd));
- } else if (attrno >=1 && attrno<= RelationGetNumberOfAttributes(rd)) {
- name = (rd->rd_att->attrs[attrno-1]->attname).data;
- return(name);
- } else {
- elog(WARN, "Illegal attr no %d for relation %s\n",
- attrno, RelationGetRelationName(rd));
- }
-
- /*
- * Shouldn't get here, but we want lint to be happy...
- */
-
- return(NULL);
+
+ /*
+ * Shouldn't get here, but we want lint to be happy...
+ */
+
+ return (NULL);
}
/* Given a typename and value, returns the ascii form of the value */
#ifdef NOT_USED
-char *
-outstr(char *typename, /* Name of type of value */
- char *value) /* Could be of any type */
+char *
+outstr(char *typename, /* Name of type of value */
+ char *value) /* Could be of any type */
{
- TypeTupleForm tp;
- Oid op;
-
- tp = (TypeTupleForm ) GETSTRUCT(type(typename));
- op = tp->typoutput;
- return((char *) fmgr(op, value));
+ TypeTupleForm tp;
+ Oid op;
+
+ tp = (TypeTupleForm) GETSTRUCT(type(typename));
+ op = tp->typoutput;
+ return ((char *) fmgr(op, value));
}
+
#endif
/* Given a Type and a string, return the internal form of that string */
-char *
+char *
instr2(Type tp, char *string, int typlen)
{
- return(instr1((TypeTupleForm ) GETSTRUCT(tp), string, typlen));
+ return (instr1((TypeTupleForm) GETSTRUCT(tp), string, typlen));
}
/* Given a type structure and a string, returns the internal form of
that string */
-static char *
+static char *
instr1(TypeTupleForm tp, char *string, int typlen)
{
- Oid op;
- Oid typelem;
-
- op = tp->typinput;
- typelem = tp->typelem; /* XXX - used for array_in */
- /* typlen is for bpcharin() and varcharin() */
- return((char *) fmgr(op, string, typelem, typlen));
+ Oid op;
+ Oid typelem;
+
+ op = tp->typinput;
+ typelem = tp->typelem; /* XXX - used for array_in */
+ /* typlen is for bpcharin() and varcharin() */
+ return ((char *) fmgr(op, string, typelem, typlen));
}
/* Given the attribute type of an array return the arrtribute type of
@@ -831,151 +937,160 @@ instr1(TypeTupleForm tp, char *string, int typlen)
Oid
GetArrayElementType(Oid typearray)
{
- HeapTuple type_tuple;
- TypeTupleForm type_struct_array;
-
- type_tuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(typearray),
- 0,0,0);
-
- if (!HeapTupleIsValid(type_tuple))
- elog(WARN, "GetArrayElementType: Cache lookup failed for type %d\n",
- typearray);
-
- /* get the array type struct from the type tuple */
- type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
-
- if (type_struct_array->typelem == InvalidOid) {
- elog(WARN, "GetArrayElementType: type %s is not an array",
- (Name)&(type_struct_array->typname.data[0]));
- }
-
- return(type_struct_array->typelem);
+ HeapTuple type_tuple;
+ TypeTupleForm type_struct_array;
+
+ type_tuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(typearray),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(type_tuple))
+ elog(WARN, "GetArrayElementType: Cache lookup failed for type %d\n",
+ typearray);
+
+ /* get the array type struct from the type tuple */
+ type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
+
+ if (type_struct_array->typelem == InvalidOid)
+ {
+ elog(WARN, "GetArrayElementType: type %s is not an array",
+ (Name) & (type_struct_array->typname.data[0]));
+ }
+
+ return (type_struct_array->typelem);
}
Oid
funcid_get_rettype(Oid funcid)
{
- HeapTuple func_tuple = NULL;
- Oid funcrettype = (Oid)0;
-
- func_tuple = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(funcid),
- 0,0,0);
-
- if ( !HeapTupleIsValid ( func_tuple ))
- elog (WARN, "function %d does not exist", funcid);
-
- funcrettype = (Oid)
- ((Form_pg_proc)GETSTRUCT(func_tuple))->prorettype ;
-
- return (funcrettype);
+ HeapTuple func_tuple = NULL;
+ Oid funcrettype = (Oid) 0;
+
+ func_tuple = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(funcid),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(func_tuple))
+ elog(WARN, "function %d does not exist", funcid);
+
+ funcrettype = (Oid)
+ ((Form_pg_proc) GETSTRUCT(func_tuple))->prorettype;
+
+ return (funcrettype);
}
/*
* get a list of all argument type vectors for which a function named
* funcname taking nargs arguments exists
*/
-static CandidateList
+static CandidateList
func_get_candidates(char *funcname, int nargs)
{
- Relation heapRelation;
- Relation idesc;
- ScanKeyData skey;
- HeapTuple tuple;
- IndexScanDesc sd;
- RetrieveIndexResult indexRes;
- Buffer buffer;
- Form_pg_proc pgProcP;
- bool bufferUsed = FALSE;
- CandidateList candidates = NULL;
- CandidateList current_candidate;
- int i;
-
- heapRelation = heap_openr(ProcedureRelationName);
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)NameEqualRegProcedure,
- (Datum)funcname);
-
- idesc = index_openr(ProcedureNameIndex);
-
- sd = index_beginscan(idesc, false, 1, &skey);
-
- do {
- tuple = (HeapTuple)NULL;
- if (bufferUsed) {
- ReleaseBuffer(buffer);
- bufferUsed = FALSE;
- }
-
- indexRes = index_getnext(sd, ForwardScanDirection);
- if (indexRes) {
- ItemPointer iptr;
-
- iptr = &indexRes->heap_iptr;
- tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
- pfree(indexRes);
- if (HeapTupleIsValid(tuple)) {
- pgProcP = (Form_pg_proc)GETSTRUCT(tuple);
- bufferUsed = TRUE;
- if (pgProcP->pronargs == nargs) {
- current_candidate = (CandidateList)
- palloc(sizeof(struct _CandidateList));
- current_candidate->args = (Oid *)
- palloc(8 * sizeof(Oid));
- memset(current_candidate->args, 0, 8 * sizeof(Oid));
- for (i=0; i<nargs; i++) {
- current_candidate->args[i] =
- pgProcP->proargtypes[i];
- }
-
- current_candidate->next = candidates;
- candidates = current_candidate;
+ Relation heapRelation;
+ Relation idesc;
+ ScanKeyData skey;
+ HeapTuple tuple;
+ IndexScanDesc sd;
+ RetrieveIndexResult indexRes;
+ Buffer buffer;
+ Form_pg_proc pgProcP;
+ bool bufferUsed = FALSE;
+ CandidateList candidates = NULL;
+ CandidateList current_candidate;
+ int i;
+
+ heapRelation = heap_openr(ProcedureRelationName);
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) NameEqualRegProcedure,
+ (Datum) funcname);
+
+ idesc = index_openr(ProcedureNameIndex);
+
+ sd = index_beginscan(idesc, false, 1, &skey);
+
+ do
+ {
+ tuple = (HeapTuple) NULL;
+ if (bufferUsed)
+ {
+ ReleaseBuffer(buffer);
+ bufferUsed = FALSE;
}
- }
- }
- } while (indexRes);
-
- index_endscan(sd);
- index_close(idesc);
- heap_close(heapRelation);
-
- return candidates;
+
+ indexRes = index_getnext(sd, ForwardScanDirection);
+ if (indexRes)
+ {
+ ItemPointer iptr;
+
+ iptr = &indexRes->heap_iptr;
+ tuple = heap_fetch(heapRelation, NowTimeQual, iptr, &buffer);
+ pfree(indexRes);
+ if (HeapTupleIsValid(tuple))
+ {
+ pgProcP = (Form_pg_proc) GETSTRUCT(tuple);
+ bufferUsed = TRUE;
+ if (pgProcP->pronargs == nargs)
+ {
+ current_candidate = (CandidateList)
+ palloc(sizeof(struct _CandidateList));
+ current_candidate->args = (Oid *)
+ palloc(8 * sizeof(Oid));
+ memset(current_candidate->args, 0, 8 * sizeof(Oid));
+ for (i = 0; i < nargs; i++)
+ {
+ current_candidate->args[i] =
+ pgProcP->proargtypes[i];
+ }
+
+ current_candidate->next = candidates;
+ candidates = current_candidate;
+ }
+ }
+ }
+ } while (indexRes);
+
+ index_endscan(sd);
+ index_close(idesc);
+ heap_close(heapRelation);
+
+ return candidates;
}
/*
* can input_typeids be coerced to func_typeids?
*/
-static bool
-can_coerce(int nargs, Oid *input_typeids, Oid *func_typeids)
+static bool
+can_coerce(int nargs, Oid * input_typeids, Oid * func_typeids)
{
- int i;
- Type tp;
-
- /*
- * right now, we only coerce "unknown", and we cannot coerce it to a
- * relation type
- */
- for (i=0; i<nargs; i++) {
- if (input_typeids[i] != func_typeids[i]) {
- if ((input_typeids[i] == BPCHAROID && func_typeids[i] == TEXTOID) ||
- (input_typeids[i] == BPCHAROID && func_typeids[i] == VARCHAROID) ||
- (input_typeids[i] == VARCHAROID && func_typeids[i] == TEXTOID) ||
- (input_typeids[i] == VARCHAROID && func_typeids[i] == BPCHAROID) ||
- (input_typeids[i] == CASHOID && func_typeids[i] == INT4OID) ||
- (input_typeids[i] == INT4OID && func_typeids[i] == CASHOID))
- ; /* these are OK */
- else if (input_typeids[i] != UNKNOWNOID || func_typeids[i] == 0)
- return false;
-
- tp = get_id_type(input_typeids[i]);
- if (typetypetype(tp) == 'c' )
- return false;
+ int i;
+ Type tp;
+
+ /*
+ * right now, we only coerce "unknown", and we cannot coerce it to a
+ * relation type
+ */
+ for (i = 0; i < nargs; i++)
+ {
+ if (input_typeids[i] != func_typeids[i])
+ {
+ if ((input_typeids[i] == BPCHAROID && func_typeids[i] == TEXTOID) ||
+ (input_typeids[i] == BPCHAROID && func_typeids[i] == VARCHAROID) ||
+ (input_typeids[i] == VARCHAROID && func_typeids[i] == TEXTOID) ||
+ (input_typeids[i] == VARCHAROID && func_typeids[i] == BPCHAROID) ||
+ (input_typeids[i] == CASHOID && func_typeids[i] == INT4OID) ||
+ (input_typeids[i] == INT4OID && func_typeids[i] == CASHOID))
+ ; /* these are OK */
+ else if (input_typeids[i] != UNKNOWNOID || func_typeids[i] == 0)
+ return false;
+
+ tp = get_id_type(input_typeids[i]);
+ if (typetypetype(tp) == 'c')
+ return false;
+ }
}
- }
-
- return true;
+
+ return true;
}
/*
@@ -986,32 +1101,34 @@ can_coerce(int nargs, Oid *input_typeids, Oid *func_typeids)
*/
static int
match_argtypes(int nargs,
- Oid *input_typeids,
- CandidateList function_typeids,
- CandidateList *candidates) /* return value */
+ Oid * input_typeids,
+ CandidateList function_typeids,
+ CandidateList * candidates) /* return value */
{
- CandidateList current_candidate;
- CandidateList matching_candidate;
- Oid *current_typeids;
- int ncandidates = 0;
-
- *candidates = NULL;
-
- for (current_candidate = function_typeids;
- current_candidate != NULL;
- current_candidate = current_candidate->next) {
- current_typeids = current_candidate->args;
- if (can_coerce(nargs, input_typeids, current_typeids)) {
- matching_candidate = (CandidateList)
- palloc(sizeof(struct _CandidateList));
- matching_candidate->args = current_typeids;
- matching_candidate->next = *candidates;
- *candidates = matching_candidate;
- ncandidates++;
+ CandidateList current_candidate;
+ CandidateList matching_candidate;
+ Oid *current_typeids;
+ int ncandidates = 0;
+
+ *candidates = NULL;
+
+ for (current_candidate = function_typeids;
+ current_candidate != NULL;
+ current_candidate = current_candidate->next)
+ {
+ current_typeids = current_candidate->args;
+ if (can_coerce(nargs, input_typeids, current_typeids))
+ {
+ matching_candidate = (CandidateList)
+ palloc(sizeof(struct _CandidateList));
+ matching_candidate->args = current_typeids;
+ matching_candidate->next = *candidates;
+ *candidates = matching_candidate;
+ ncandidates++;
+ }
}
- }
-
- return ncandidates;
+
+ return ncandidates;
}
/*
@@ -1020,442 +1137,483 @@ match_argtypes(int nargs,
* returns the selected argtype array if the conflict can be resolved,
* otherwise returns NULL
*/
-static Oid *
+static Oid *
func_select_candidate(int nargs,
- Oid *input_typeids,
- CandidateList candidates)
+ Oid * input_typeids,
+ CandidateList candidates)
{
- /* XXX no conflict resolution implemeneted yet */
- return (NULL);
+ /* XXX no conflict resolution implemeneted yet */
+ return (NULL);
}
bool
func_get_detail(char *funcname,
- int nargs,
- Oid *oid_array,
- Oid *funcid, /* return value */
- Oid *rettype, /* return value */
- bool *retset, /* return value */
- Oid **true_typeids) /* return value */
+ int nargs,
+ Oid * oid_array,
+ Oid * funcid, /* return value */
+ Oid * rettype, /* return value */
+ bool * retset, /* return value */
+ Oid ** true_typeids) /* return value */
{
- Oid **input_typeid_vector;
- Oid *current_input_typeids;
- CandidateList function_typeids;
- CandidateList current_function_typeids;
- HeapTuple ftup;
- Form_pg_proc pform;
-
- /*
- * attempt to find named function in the system catalogs
- * with arguments exactly as specified - so that the normal
- * case is just as quick as before
- */
- ftup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(funcname),
- Int32GetDatum(nargs),
- PointerGetDatum(oid_array),
- 0);
- *true_typeids = oid_array;
-
- /*
- * If an exact match isn't found :
- * 1) get a vector of all possible input arg type arrays constructed
- * from the superclasses of the original input arg types
- * 2) get a list of all possible argument type arrays to the
- * function with given name and number of arguments
- * 3) for each input arg type array from vector #1 :
- * a) find how many of the function arg type arrays from list #2
- * it can be coerced to
- * b) - if the answer is one, we have our function
- * - if the answer is more than one, attempt to resolve the
- * conflict
- * - if the answer is zero, try the next array from vector #1
- */
- if (!HeapTupleIsValid(ftup)) {
- function_typeids = func_get_candidates(funcname, nargs);
-
- if (function_typeids != NULL) {
- int ncandidates = 0;
-
- input_typeid_vector = argtype_inherit(nargs, oid_array);
- current_input_typeids = oid_array;
-
- do {
- ncandidates = match_argtypes(nargs, current_input_typeids,
- function_typeids,
- &current_function_typeids);
- if (ncandidates == 1) {
- *true_typeids = current_function_typeids->args;
- ftup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(funcname),
- Int32GetDatum(nargs),
- PointerGetDatum(*true_typeids),
- 0);
- Assert(HeapTupleIsValid(ftup));
+ Oid **input_typeid_vector;
+ Oid *current_input_typeids;
+ CandidateList function_typeids;
+ CandidateList current_function_typeids;
+ HeapTuple ftup;
+ Form_pg_proc pform;
+
+ /*
+ * attempt to find named function in the system catalogs with
+ * arguments exactly as specified - so that the normal case is just as
+ * quick as before
+ */
+ ftup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(funcname),
+ Int32GetDatum(nargs),
+ PointerGetDatum(oid_array),
+ 0);
+ *true_typeids = oid_array;
+
+ /*
+ * If an exact match isn't found : 1) get a vector of all possible
+ * input arg type arrays constructed from the superclasses of the
+ * original input arg types 2) get a list of all possible argument
+ * type arrays to the function with given name and number of arguments
+ * 3) for each input arg type array from vector #1 : a) find how many
+ * of the function arg type arrays from list #2 it can be coerced to
+ * b) - if the answer is one, we have our function - if the answer is
+ * more than one, attempt to resolve the conflict - if the answer is
+ * zero, try the next array from vector #1
+ */
+ if (!HeapTupleIsValid(ftup))
+ {
+ function_typeids = func_get_candidates(funcname, nargs);
+
+ if (function_typeids != NULL)
+ {
+ int ncandidates = 0;
+
+ input_typeid_vector = argtype_inherit(nargs, oid_array);
+ current_input_typeids = oid_array;
+
+ do
+ {
+ ncandidates = match_argtypes(nargs, current_input_typeids,
+ function_typeids,
+ &current_function_typeids);
+ if (ncandidates == 1)
+ {
+ *true_typeids = current_function_typeids->args;
+ ftup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(funcname),
+ Int32GetDatum(nargs),
+ PointerGetDatum(*true_typeids),
+ 0);
+ Assert(HeapTupleIsValid(ftup));
+ }
+ else if (ncandidates > 1)
+ {
+ *true_typeids =
+ func_select_candidate(nargs,
+ current_input_typeids,
+ current_function_typeids);
+ if (*true_typeids == NULL)
+ {
+ elog(NOTICE, "there is more than one function named \"%s\"",
+ funcname);
+ elog(NOTICE, "that satisfies the given argument types. you will have to");
+ elog(NOTICE, "retype your query using explicit typecasts.");
+ func_error("func_get_detail", funcname, nargs, oid_array);
+ }
+ else
+ {
+ ftup = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(funcname),
+ Int32GetDatum(nargs),
+ PointerGetDatum(*true_typeids),
+ 0);
+ Assert(HeapTupleIsValid(ftup));
+ }
+ }
+ current_input_typeids = *input_typeid_vector++;
+ }
+ while (current_input_typeids !=
+ InvalidOid && ncandidates == 0);
}
- else if (ncandidates > 1) {
- *true_typeids =
- func_select_candidate(nargs,
- current_input_typeids,
- current_function_typeids);
- if (*true_typeids == NULL) {
- elog(NOTICE, "there is more than one function named \"%s\"",
- funcname);
- elog(NOTICE, "that satisfies the given argument types. you will have to");
- elog(NOTICE, "retype your query using explicit typecasts.");
- func_error("func_get_detail", funcname, nargs, oid_array);
- }
- else {
- ftup = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(funcname),
- Int32GetDatum(nargs),
- PointerGetDatum(*true_typeids),
- 0);
- Assert(HeapTupleIsValid(ftup));
- }
+ }
+
+ if (!HeapTupleIsValid(ftup))
+ {
+ Type tp;
+
+ if (nargs == 1)
+ {
+ tp = get_id_type(oid_array[0]);
+ if (typetypetype(tp) == 'c')
+ elog(WARN, "no such attribute or function \"%s\"",
+ funcname);
}
- current_input_typeids = *input_typeid_vector++;
- }
- while (current_input_typeids !=
- InvalidOid && ncandidates == 0);
+ func_error("func_get_detail", funcname, nargs, oid_array);
}
- }
-
- if (!HeapTupleIsValid(ftup)) {
- Type tp;
-
- if (nargs == 1) {
- tp = get_id_type(oid_array[0]);
- if (typetypetype(tp) == 'c')
- elog(WARN, "no such attribute or function \"%s\"",
- funcname);
+ else
+ {
+ pform = (Form_pg_proc) GETSTRUCT(ftup);
+ *funcid = ftup->t_oid;
+ *rettype = pform->prorettype;
+ *retset = pform->proretset;
+
+ return (true);
}
- func_error("func_get_detail", funcname, nargs, oid_array);
- } else {
- pform = (Form_pg_proc) GETSTRUCT(ftup);
- *funcid = ftup->t_oid;
- *rettype = pform->prorettype;
- *retset = pform->proretset;
-
- return (true);
- }
/* shouldn't reach here */
- return (false);
+ return (false);
}
/*
- * argtype_inherit() -- Construct an argtype vector reflecting the
- * inheritance properties of the supplied argv.
+ * argtype_inherit() -- Construct an argtype vector reflecting the
+ * inheritance properties of the supplied argv.
*
- * This function is used to disambiguate among functions with the
- * same name but different signatures. It takes an array of eight
- * type ids. For each type id in the array that's a complex type
- * (a class), it walks up the inheritance tree, finding all
- * superclasses of that type. A vector of new Oid type arrays
- * is returned to the caller, reflecting the structure of the
- * inheritance tree above the supplied arguments.
+ * This function is used to disambiguate among functions with the
+ * same name but different signatures. It takes an array of eight
+ * type ids. For each type id in the array that's a complex type
+ * (a class), it walks up the inheritance tree, finding all
+ * superclasses of that type. A vector of new Oid type arrays
+ * is returned to the caller, reflecting the structure of the
+ * inheritance tree above the supplied arguments.
*
- * The order of this vector is as follows: all superclasses of the
- * rightmost complex class are explored first. The exploration
- * continues from right to left. This policy means that we favor
- * keeping the leftmost argument type as low in the inheritance tree
- * as possible. This is intentional; it is exactly what we need to
- * do for method dispatch. The last type array we return is all
- * zeroes. This will match any functions for which return types are
- * not defined. There are lots of these (mostly builtins) in the
- * catalogs.
+ * The order of this vector is as follows: all superclasses of the
+ * rightmost complex class are explored first. The exploration
+ * continues from right to left. This policy means that we favor
+ * keeping the leftmost argument type as low in the inheritance tree
+ * as possible. This is intentional; it is exactly what we need to
+ * do for method dispatch. The last type array we return is all
+ * zeroes. This will match any functions for which return types are
+ * not defined. There are lots of these (mostly builtins) in the
+ * catalogs.
*/
-static Oid **
-argtype_inherit(int nargs, Oid *oid_array)
+static Oid **
+argtype_inherit(int nargs, Oid * oid_array)
{
- Oid relid;
- int i;
- InhPaths arginh[MAXFARGS];
-
- for (i = 0; i < MAXFARGS; i++) {
- if (i < nargs) {
- arginh[i].self = oid_array[i];
- if ((relid = typeid_get_relid(oid_array[i])) != InvalidOid) {
- arginh[i].nsupers = findsupers(relid, &(arginh[i].supervec));
- } else {
- arginh[i].nsupers = 0;
- arginh[i].supervec = (Oid *) NULL;
- }
- } else {
- arginh[i].self = InvalidOid;
- arginh[i].nsupers = 0;
- arginh[i].supervec = (Oid *) NULL;
+ Oid relid;
+ int i;
+ InhPaths arginh[MAXFARGS];
+
+ for (i = 0; i < MAXFARGS; i++)
+ {
+ if (i < nargs)
+ {
+ arginh[i].self = oid_array[i];
+ if ((relid = typeid_get_relid(oid_array[i])) != InvalidOid)
+ {
+ arginh[i].nsupers = findsupers(relid, &(arginh[i].supervec));
+ }
+ else
+ {
+ arginh[i].nsupers = 0;
+ arginh[i].supervec = (Oid *) NULL;
+ }
+ }
+ else
+ {
+ arginh[i].self = InvalidOid;
+ arginh[i].nsupers = 0;
+ arginh[i].supervec = (Oid *) NULL;
+ }
}
- }
-
- /* return an ordered cross-product of the classes involved */
- return (genxprod(arginh, nargs));
+
+ /* return an ordered cross-product of the classes involved */
+ return (genxprod(arginh, nargs));
}
-typedef struct _SuperQE {
- Oid sqe_relid;
-} SuperQE;
+typedef struct _SuperQE
+{
+ Oid sqe_relid;
+} SuperQE;
static int
-findsupers(Oid relid, Oid **supervec)
+findsupers(Oid relid, Oid ** supervec)
{
- Oid *relidvec;
- Relation inhrel;
- HeapScanDesc inhscan;
- ScanKeyData skey;
- HeapTuple inhtup;
- TupleDesc inhtupdesc;
- int nvisited;
- SuperQE *qentry, *vnode;
- Dllist *visited, *queue;
- Dlelem *qe, *elt;
-
- Relation rd;
- Buffer buf;
- Datum d;
- bool newrelid;
- char isNull;
-
- nvisited = 0;
- queue = DLNewList();
- visited = DLNewList();
-
-
- inhrel = heap_openr(InheritsRelationName);
- RelationSetLockForRead(inhrel);
- inhtupdesc = RelationGetTupleDescriptor(inhrel);
-
- /*
- * Use queue to do a breadth-first traversal of the inheritance
- * graph from the relid supplied up to the root.
- */
- do {
- ScanKeyEntryInitialize(&skey, 0x0, Anum_pg_inherits_inhrel,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relid));
-
- inhscan = heap_beginscan(inhrel, 0, NowTimeQual, 1, &skey);
-
- while (HeapTupleIsValid(inhtup = heap_getnext(inhscan, 0, &buf))) {
- qentry = (SuperQE *) palloc(sizeof(SuperQE));
-
- d = (Datum) fastgetattr(inhtup, Anum_pg_inherits_inhparent,
- inhtupdesc, &isNull);
- qentry->sqe_relid = DatumGetObjectId(d);
-
- /* put this one on the queue */
- DLAddTail(queue, DLNewElem(qentry));
-
- ReleaseBuffer(buf);
+ Oid *relidvec;
+ Relation inhrel;
+ HeapScanDesc inhscan;
+ ScanKeyData skey;
+ HeapTuple inhtup;
+ TupleDesc inhtupdesc;
+ int nvisited;
+ SuperQE *qentry,
+ *vnode;
+ Dllist *visited,
+ *queue;
+ Dlelem *qe,
+ *elt;
+
+ Relation rd;
+ Buffer buf;
+ Datum d;
+ bool newrelid;
+ char isNull;
+
+ nvisited = 0;
+ queue = DLNewList();
+ visited = DLNewList();
+
+
+ inhrel = heap_openr(InheritsRelationName);
+ RelationSetLockForRead(inhrel);
+ inhtupdesc = RelationGetTupleDescriptor(inhrel);
+
+ /*
+ * Use queue to do a breadth-first traversal of the inheritance graph
+ * from the relid supplied up to the root.
+ */
+ do
+ {
+ ScanKeyEntryInitialize(&skey, 0x0, Anum_pg_inherits_inhrel,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relid));
+
+ inhscan = heap_beginscan(inhrel, 0, NowTimeQual, 1, &skey);
+
+ while (HeapTupleIsValid(inhtup = heap_getnext(inhscan, 0, &buf)))
+ {
+ qentry = (SuperQE *) palloc(sizeof(SuperQE));
+
+ d = (Datum) fastgetattr(inhtup, Anum_pg_inherits_inhparent,
+ inhtupdesc, &isNull);
+ qentry->sqe_relid = DatumGetObjectId(d);
+
+ /* put this one on the queue */
+ DLAddTail(queue, DLNewElem(qentry));
+
+ ReleaseBuffer(buf);
+ }
+
+ heap_endscan(inhscan);
+
+ /* pull next unvisited relid off the queue */
+ do
+ {
+ qe = DLRemHead(queue);
+ qentry = qe ? (SuperQE *) DLE_VAL(qe) : NULL;
+
+ if (qentry == (SuperQE *) NULL)
+ break;
+
+ relid = qentry->sqe_relid;
+ newrelid = true;
+
+ for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt))
+ {
+ vnode = (SuperQE *) DLE_VAL(elt);
+ if (vnode && (qentry->sqe_relid == vnode->sqe_relid))
+ {
+ newrelid = false;
+ break;
+ }
+ }
+ } while (!newrelid);
+
+ if (qentry != (SuperQE *) NULL)
+ {
+
+ /* save the type id, rather than the relation id */
+ if ((rd = heap_open(qentry->sqe_relid)) == (Relation) NULL)
+ elog(WARN, "relid %d does not exist", qentry->sqe_relid);
+ qentry->sqe_relid = typeid(type(RelationGetRelationName(rd)->data));
+ heap_close(rd);
+
+ DLAddTail(visited, qe);
+
+ nvisited++;
+ }
+ } while (qentry != (SuperQE *) NULL);
+
+ RelationUnsetLockForRead(inhrel);
+ heap_close(inhrel);
+
+ if (nvisited > 0)
+ {
+ relidvec = (Oid *) palloc(nvisited * sizeof(Oid));
+ *supervec = relidvec;
+
+ for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt))
+ {
+ vnode = (SuperQE *) DLE_VAL(elt);
+ *relidvec++ = vnode->sqe_relid;
+ }
+
}
-
- heap_endscan(inhscan);
-
- /* pull next unvisited relid off the queue */
- do {
- qe = DLRemHead(queue);
- qentry = qe ? (SuperQE*)DLE_VAL(qe) : NULL;
-
- if (qentry == (SuperQE *) NULL)
- break;
-
- relid = qentry->sqe_relid;
- newrelid = true;
-
- for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt)) {
- vnode = (SuperQE*)DLE_VAL(elt);
- if (vnode && (qentry->sqe_relid == vnode->sqe_relid)) {
- newrelid = false;
- break;
- }
- }
- } while (!newrelid);
-
- if (qentry != (SuperQE *) NULL) {
-
- /* save the type id, rather than the relation id */
- if ((rd = heap_open(qentry->sqe_relid)) == (Relation) NULL)
- elog(WARN, "relid %d does not exist", qentry->sqe_relid);
- qentry->sqe_relid = typeid(type(RelationGetRelationName(rd)->data));
- heap_close(rd);
-
- DLAddTail(visited, qe);
-
- nvisited++;
+ else
+ {
+ *supervec = (Oid *) NULL;
}
- } while (qentry != (SuperQE *) NULL);
-
- RelationUnsetLockForRead(inhrel);
- heap_close(inhrel);
-
- if (nvisited > 0) {
- relidvec = (Oid *) palloc(nvisited * sizeof(Oid));
- *supervec = relidvec;
-
- for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt)) {
- vnode = (SuperQE*)DLE_VAL(elt);
- *relidvec++ = vnode->sqe_relid;
- }
-
- } else {
- *supervec = (Oid *) NULL;
- }
-
- return (nvisited);
+
+ return (nvisited);
}
-static Oid **
-genxprod(InhPaths *arginh, int nargs)
+static Oid **
+genxprod(InhPaths * arginh, int nargs)
{
- int nanswers;
- Oid **result, **iter;
- Oid *oneres;
- int i, j;
- int cur[MAXFARGS];
-
- nanswers = 1;
- for (i = 0; i < nargs; i++) {
- nanswers *= (arginh[i].nsupers + 2);
- cur[i] = 0;
- }
-
- iter = result = (Oid **) palloc(sizeof(Oid *) * nanswers);
-
- /* compute the cross product from right to left */
- for (;;) {
- oneres = (Oid *) palloc(MAXFARGS * sizeof(Oid));
- memset(oneres, 0, MAXFARGS * sizeof(Oid));
-
- for (i = nargs - 1; i >= 0 && cur[i] > arginh[i].nsupers; i--)
- continue;
-
- /* if we're done, terminate with NULL pointer */
- if (i < 0) {
- *iter = NULL;
- return (result);
+ int nanswers;
+ Oid **result,
+ **iter;
+ Oid *oneres;
+ int i,
+ j;
+ int cur[MAXFARGS];
+
+ nanswers = 1;
+ for (i = 0; i < nargs; i++)
+ {
+ nanswers *= (arginh[i].nsupers + 2);
+ cur[i] = 0;
}
-
- /* no, increment this column and zero the ones after it */
- cur[i] = cur[i] + 1;
- for (j = nargs - 1; j > i; j--)
- cur[j] = 0;
-
- for (i = 0; i < nargs; i++) {
- if (cur[i] == 0)
- oneres[i] = arginh[i].self;
- else if (cur[i] > arginh[i].nsupers)
- oneres[i] = 0; /* wild card */
- else
- oneres[i] = arginh[i].supervec[cur[i] - 1];
+
+ iter = result = (Oid **) palloc(sizeof(Oid *) * nanswers);
+
+ /* compute the cross product from right to left */
+ for (;;)
+ {
+ oneres = (Oid *) palloc(MAXFARGS * sizeof(Oid));
+ memset(oneres, 0, MAXFARGS * sizeof(Oid));
+
+ for (i = nargs - 1; i >= 0 && cur[i] > arginh[i].nsupers; i--)
+ continue;
+
+ /* if we're done, terminate with NULL pointer */
+ if (i < 0)
+ {
+ *iter = NULL;
+ return (result);
+ }
+
+ /* no, increment this column and zero the ones after it */
+ cur[i] = cur[i] + 1;
+ for (j = nargs - 1; j > i; j--)
+ cur[j] = 0;
+
+ for (i = 0; i < nargs; i++)
+ {
+ if (cur[i] == 0)
+ oneres[i] = arginh[i].self;
+ else if (cur[i] > arginh[i].nsupers)
+ oneres[i] = 0; /* wild card */
+ else
+ oneres[i] = arginh[i].supervec[cur[i] - 1];
+ }
+
+ *iter++ = oneres;
}
-
- *iter++ = oneres;
- }
}
/* Given a type id, returns the in-conversion function of the type */
Oid
typeid_get_retinfunc(Oid type_id)
{
- HeapTuple typeTuple;
- TypeTupleForm type;
- Oid infunc;
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type_id),
- 0,0,0);
- if ( !HeapTupleIsValid ( typeTuple ))
- elog(WARN,
- "typeid_get_retinfunc: Invalid type - oid = %u",
- type_id);
-
- type = (TypeTupleForm) GETSTRUCT(typeTuple);
- infunc = type->typinput;
- return(infunc);
+ HeapTuple typeTuple;
+ TypeTupleForm type;
+ Oid infunc;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type_id),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(typeTuple))
+ elog(WARN,
+ "typeid_get_retinfunc: Invalid type - oid = %u",
+ type_id);
+
+ type = (TypeTupleForm) GETSTRUCT(typeTuple);
+ infunc = type->typinput;
+ return (infunc);
}
/* Given a type id, returns the out-conversion function of the type */
Oid
typeid_get_retoutfunc(Oid type_id)
{
- HeapTuple typeTuple;
- TypeTupleForm type;
- Oid outfunc;
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type_id),
- 0,0,0);
- if ( !HeapTupleIsValid ( typeTuple ))
- elog(WARN,
- "typeid_get_retoutfunc: Invalid type - oid = %u",
- type_id);
-
- type = (TypeTupleForm) GETSTRUCT(typeTuple);
- outfunc = type->typoutput;
- return(outfunc);
+ HeapTuple typeTuple;
+ TypeTupleForm type;
+ Oid outfunc;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type_id),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(typeTuple))
+ elog(WARN,
+ "typeid_get_retoutfunc: Invalid type - oid = %u",
+ type_id);
+
+ type = (TypeTupleForm) GETSTRUCT(typeTuple);
+ outfunc = type->typoutput;
+ return (outfunc);
}
Oid
typeid_get_relid(Oid type_id)
{
- HeapTuple typeTuple;
- TypeTupleForm type;
- Oid infunc;
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type_id),
- 0,0,0);
- if ( !HeapTupleIsValid ( typeTuple ))
- elog(WARN, "typeid_get_relid: Invalid type - oid = %u ", type_id);
-
- type = (TypeTupleForm) GETSTRUCT(typeTuple);
- infunc = type->typrelid;
- return(infunc);
+ HeapTuple typeTuple;
+ TypeTupleForm type;
+ Oid infunc;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type_id),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(typeTuple))
+ elog(WARN, "typeid_get_relid: Invalid type - oid = %u ", type_id);
+
+ type = (TypeTupleForm) GETSTRUCT(typeTuple);
+ infunc = type->typrelid;
+ return (infunc);
}
Oid
get_typrelid(Type typ)
{
- TypeTupleForm typtup;
-
- typtup = (TypeTupleForm) GETSTRUCT(typ);
-
- return (typtup->typrelid);
+ TypeTupleForm typtup;
+
+ typtup = (TypeTupleForm) GETSTRUCT(typ);
+
+ return (typtup->typrelid);
}
Oid
get_typelem(Oid type_id)
{
- HeapTuple typeTuple;
- TypeTupleForm type;
-
- if (!(typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type_id),
- 0,0,0))) {
- elog (WARN , "type id lookup of %u failed", type_id);
- }
- type = (TypeTupleForm) GETSTRUCT(typeTuple);
-
- return (type->typelem);
+ HeapTuple typeTuple;
+ TypeTupleForm type;
+
+ if (!(typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type_id),
+ 0, 0, 0)))
+ {
+ elog(WARN, "type id lookup of %u failed", type_id);
+ }
+ type = (TypeTupleForm) GETSTRUCT(typeTuple);
+
+ return (type->typelem);
}
#ifdef NOT_USED
char
FindDelimiter(char *typename)
{
- char delim;
- HeapTuple typeTuple;
- TypeTupleForm type;
-
-
- if (!(typeTuple = SearchSysCacheTuple(TYPNAME,
- PointerGetDatum(typename),
- 0,0,0))) {
- elog (WARN , "type name lookup of %s failed", typename);
- }
- type = (TypeTupleForm) GETSTRUCT(typeTuple);
-
- delim = type->typdelim;
- return (delim);
+ char delim;
+ HeapTuple typeTuple;
+ TypeTupleForm type;
+
+
+ if (!(typeTuple = SearchSysCacheTuple(TYPNAME,
+ PointerGetDatum(typename),
+ 0, 0, 0)))
+ {
+ elog(WARN, "type name lookup of %s failed", typename);
+ }
+ type = (TypeTupleForm) GETSTRUCT(typeTuple);
+
+ delim = type->typdelim;
+ return (delim);
}
+
#endif
/*
@@ -1465,26 +1623,33 @@ FindDelimiter(char *typename)
static void
op_error(char *op, Oid arg1, Oid arg2)
{
- Type tp1 = NULL, tp2 = NULL;
-
- if (check_typeid(arg1)) {
- tp1 = get_id_type(arg1);
- } else {
- elog(WARN, "left hand side of operator %s has an unknown type, probably a bad attribute name", op);
- }
-
- if (check_typeid(arg2)) {
- tp2 = get_id_type(arg2);
- } else {
- elog(WARN, "right hand side of operator %s has an unknown type, probably a bad attribute name", op);
- }
-
- elog(NOTICE, "there is no operator %s for types %s and %s",
- op, tname(tp1),tname(tp2));
- elog(NOTICE, "You will either have to retype this query using an");
- elog(NOTICE, "explicit cast, or you will have to define the operator");
- elog(WARN, "%s for %s and %s using CREATE OPERATOR",
- op, tname(tp1),tname(tp2));
+ Type tp1 = NULL,
+ tp2 = NULL;
+
+ if (check_typeid(arg1))
+ {
+ tp1 = get_id_type(arg1);
+ }
+ else
+ {
+ elog(WARN, "left hand side of operator %s has an unknown type, probably a bad attribute name", op);
+ }
+
+ if (check_typeid(arg2))
+ {
+ tp2 = get_id_type(arg2);
+ }
+ else
+ {
+ elog(WARN, "right hand side of operator %s has an unknown type, probably a bad attribute name", op);
+ }
+
+ elog(NOTICE, "there is no operator %s for types %s and %s",
+ op, tname(tp1), tname(tp2));
+ elog(NOTICE, "You will either have to retype this query using an");
+ elog(NOTICE, "explicit cast, or you will have to define the operator");
+ elog(WARN, "%s for %s and %s using CREATE OPERATOR",
+ op, tname(tp1), tname(tp2));
}
/*
@@ -1492,27 +1657,32 @@ op_error(char *op, Oid arg1, Oid arg2)
* argument types
*/
void
-func_error(char *caller, char *funcname, int nargs, Oid *argtypes)
+func_error(char *caller, char *funcname, int nargs, Oid * argtypes)
{
- char p[(NAMEDATALEN+2)*MAXFMGRARGS], *ptr;
- int i;
-
- ptr = p;
- *ptr = '\0';
- for (i=0; i<nargs; i++) {
- if (i) {
- *ptr++ = ',';
- *ptr++ = ' ';
+ char p[(NAMEDATALEN + 2) * MAXFMGRARGS],
+ *ptr;
+ int i;
+
+ ptr = p;
+ *ptr = '\0';
+ for (i = 0; i < nargs; i++)
+ {
+ if (i)
+ {
+ *ptr++ = ',';
+ *ptr++ = ' ';
+ }
+ if (argtypes[i] != 0)
+ {
+ strcpy(ptr, tname(get_id_type(argtypes[i])));
+ *(ptr + NAMEDATALEN) = '\0';
+ }
+ else
+ strcpy(ptr, "opaque");
+ ptr += strlen(ptr);
}
- if (argtypes[i] != 0) {
- strcpy(ptr, tname(get_id_type(argtypes[i])));
- *(ptr + NAMEDATALEN) = '\0';
- } else
- strcpy(ptr, "opaque");
- ptr += strlen(ptr);
- }
-
- elog(WARN, "%s: function %s(%s) does not exist", caller, funcname, p);
+
+ elog(WARN, "%s: function %s(%s) does not exist", caller, funcname, p);
}
/*
@@ -1522,12 +1692,19 @@ func_error(char *caller, char *funcname, int nargs, Oid *argtypes)
void
agg_error(char *caller, char *aggname, Oid basetypeID)
{
- /* basetypeID that is Invalid (zero) means aggregate over all types. (count) */
-
- if (basetypeID == InvalidOid) {
- elog(WARN, "%s: aggregate '%s' for all types does not exist", caller, aggname);
- } else {
- elog(WARN, "%s: aggregate '%s' for '%s' does not exist", caller, aggname,
- tname(get_id_type(basetypeID)));
- }
+
+ /*
+ * basetypeID that is Invalid (zero) means aggregate over all types.
+ * (count)
+ */
+
+ if (basetypeID == InvalidOid)
+ {
+ elog(WARN, "%s: aggregate '%s' for all types does not exist", caller, aggname);
+ }
+ else
+ {
+ elog(WARN, "%s: aggregate '%s' for '%s' does not exist", caller, aggname,
+ tname(get_id_type(basetypeID)));
+ }
}
diff --git a/src/backend/parser/dbcommands.c b/src/backend/parser/dbcommands.c
index f975937b5ad..158e033b6e7 100644
--- a/src/backend/parser/dbcommands.c
+++ b/src/backend/parser/dbcommands.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* dbcommands.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/dbcommands.c,v 1.6 1997/08/19 21:32:14 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/dbcommands.c,v 1.7 1997/09/07 04:44:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,7 +16,7 @@
#include <signal.h>
#include "postgres.h"
-#include "miscadmin.h" /* for DataDir */
+#include "miscadmin.h" /* for DataDir */
#include "access/heapam.h"
#include "access/htup.h"
#include "access/relscan.h"
@@ -35,228 +35,253 @@
/* non-export function prototypes */
-static void check_permissions(char *command, char *dbname,
- Oid *dbIdP, Oid *userIdP);
+static void
+check_permissions(char *command, char *dbname,
+ Oid * dbIdP, Oid * userIdP);
static HeapTuple get_pg_dbtup(char *command, char *dbname, Relation dbrel);
-static void stop_vacuum(char *dbname);
+static void stop_vacuum(char *dbname);
void
createdb(char *dbname)
{
- Oid db_id, user_id;
- char buf[512];
-
- /*
- * If this call returns, the database does not exist and we're allowed
- * to create databases.
- */
- check_permissions("createdb", dbname, &db_id, &user_id);
-
- /* close virtual file descriptors so we can do system() calls */
- closeAllVfds();
-
- sprintf(buf, "mkdir %s%cbase%c%s", DataDir, SEP_CHAR, SEP_CHAR, dbname);
- system(buf);
- sprintf(buf, "%s %s%cbase%ctemplate1%c* %s%cbase%c%s",
- COPY_CMD, DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR, DataDir,
- SEP_CHAR, SEP_CHAR, dbname);
- system(buf);
-
-/* sprintf(buf, "insert into pg_database (datname, datdba, datpath) \
+ Oid db_id,
+ user_id;
+ char buf[512];
+
+ /*
+ * If this call returns, the database does not exist and we're allowed
+ * to create databases.
+ */
+ check_permissions("createdb", dbname, &db_id, &user_id);
+
+ /* close virtual file descriptors so we can do system() calls */
+ closeAllVfds();
+
+ sprintf(buf, "mkdir %s%cbase%c%s", DataDir, SEP_CHAR, SEP_CHAR, dbname);
+ system(buf);
+ sprintf(buf, "%s %s%cbase%ctemplate1%c* %s%cbase%c%s",
+ COPY_CMD, DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR, DataDir,
+ SEP_CHAR, SEP_CHAR, dbname);
+ system(buf);
+
+/* sprintf(buf, "insert into pg_database (datname, datdba, datpath) \
values (\'%s\'::char16, \'%d\'::oid, \'%s\'::text);",
- dbname, user_id, dbname);
+ dbname, user_id, dbname);
*/
- sprintf(buf, "insert into pg_database (datname, datdba, datpath) \
+ sprintf(buf, "insert into pg_database (datname, datdba, datpath) \
values (\'%s\', \'%d\', \'%s\');",
- dbname, user_id, dbname);
+ dbname, user_id, dbname);
- pg_eval(buf, (char **) NULL, (Oid *) NULL, 0);
+ pg_eval(buf, (char **) NULL, (Oid *) NULL, 0);
}
void
destroydb(char *dbname)
{
- Oid user_id, db_id;
- char buf[512];
-
- /*
- * If this call returns, the database exists and we're allowed to
- * remove it.
- */
- check_permissions("destroydb", dbname, &db_id, &user_id);
-
- if (!OidIsValid(db_id)) {
- elog(FATAL, "impossible: pg_database instance with invalid OID.");
- }
-
- /* stop the vacuum daemon */
- stop_vacuum(dbname);
-
- /* remove the pg_database tuple FIRST,
- this may fail due to permissions problems*/
- sprintf(buf, "delete from pg_database where pg_database.oid = \'%d\'::oid",
- db_id);
- pg_eval(buf, (char **) NULL, (Oid *) NULL, 0);
-
- /* remove the data directory. If the DELETE above failed, this will
- not be reached */
- sprintf(buf, "rm -r %s/base/%s", DataDir, dbname);
- system(buf);
-
- /* drop pages for this database that are in the shared buffer cache */
- DropBuffers(db_id);
+ Oid user_id,
+ db_id;
+ char buf[512];
+
+ /*
+ * If this call returns, the database exists and we're allowed to
+ * remove it.
+ */
+ check_permissions("destroydb", dbname, &db_id, &user_id);
+
+ if (!OidIsValid(db_id))
+ {
+ elog(FATAL, "impossible: pg_database instance with invalid OID.");
+ }
+
+ /* stop the vacuum daemon */
+ stop_vacuum(dbname);
+
+ /*
+ * remove the pg_database tuple FIRST, this may fail due to
+ * permissions problems
+ */
+ sprintf(buf, "delete from pg_database where pg_database.oid = \'%d\'::oid",
+ db_id);
+ pg_eval(buf, (char **) NULL, (Oid *) NULL, 0);
+
+ /*
+ * remove the data directory. If the DELETE above failed, this will
+ * not be reached
+ */
+ sprintf(buf, "rm -r %s/base/%s", DataDir, dbname);
+ system(buf);
+
+ /* drop pages for this database that are in the shared buffer cache */
+ DropBuffers(db_id);
}
-static HeapTuple
+static HeapTuple
get_pg_dbtup(char *command, char *dbname, Relation dbrel)
{
- HeapTuple dbtup;
- HeapTuple tup;
- Buffer buf;
- HeapScanDesc scan;
- ScanKeyData scanKey;
-
- ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname,
- NameEqualRegProcedure, NameGetDatum(dbname));
-
- scan = heap_beginscan(dbrel, 0, NowTimeQual, 1, &scanKey);
- if (!HeapScanIsValid(scan))
- elog(WARN, "%s: cannot begin scan of pg_database.", command);
-
- /*
- * since we want to return the tuple out of this proc, and we're
- * going to close the relation, copy the tuple and return the copy.
- */
- tup = heap_getnext(scan, 0, &buf);
-
- if (HeapTupleIsValid(tup)) {
- dbtup = heap_copytuple(tup);
- ReleaseBuffer(buf);
- } else
- dbtup = tup;
-
- heap_endscan(scan);
- return (dbtup);
+ HeapTuple dbtup;
+ HeapTuple tup;
+ Buffer buf;
+ HeapScanDesc scan;
+ ScanKeyData scanKey;
+
+ ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname,
+ NameEqualRegProcedure, NameGetDatum(dbname));
+
+ scan = heap_beginscan(dbrel, 0, NowTimeQual, 1, &scanKey);
+ if (!HeapScanIsValid(scan))
+ elog(WARN, "%s: cannot begin scan of pg_database.", command);
+
+ /*
+ * since we want to return the tuple out of this proc, and we're going
+ * to close the relation, copy the tuple and return the copy.
+ */
+ tup = heap_getnext(scan, 0, &buf);
+
+ if (HeapTupleIsValid(tup))
+ {
+ dbtup = heap_copytuple(tup);
+ ReleaseBuffer(buf);
+ }
+ else
+ dbtup = tup;
+
+ heap_endscan(scan);
+ return (dbtup);
}
/*
- * check_permissions() -- verify that the user is permitted to do this.
+ * check_permissions() -- verify that the user is permitted to do this.
*
- * If the user is not allowed to carry out this operation, this routine
- * elog(WARN, ...)s, which will abort the xact. As a side effect, the
- * user's pg_user tuple OID is returned in userIdP and the target database's
- * OID is returned in dbIdP.
+ * If the user is not allowed to carry out this operation, this routine
+ * elog(WARN, ...)s, which will abort the xact. As a side effect, the
+ * user's pg_user tuple OID is returned in userIdP and the target database's
+ * OID is returned in dbIdP.
*/
static void
check_permissions(char *command,
- char *dbname,
- Oid *dbIdP,
- Oid *userIdP)
+ char *dbname,
+ Oid * dbIdP,
+ Oid * userIdP)
{
- Relation dbrel;
- HeapTuple dbtup, utup;
- Oid dbowner = (Oid)0;
- char use_createdb;
- bool dbfound;
- bool use_super;
- char *userName;
-
- userName = GetPgUserName();
- utup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName),
- 0,0,0);
- *userIdP = ((Form_pg_user)GETSTRUCT(utup))->usesysid;
- use_super = ((Form_pg_user)GETSTRUCT(utup))->usesuper;
- use_createdb = ((Form_pg_user)GETSTRUCT(utup))->usecreatedb;
-
- /* Check to make sure user has permission to use createdb */
- if (!use_createdb) {
- elog(WARN, "user \"%s\" is not allowed to create/destroy databases",
- userName);
- }
-
- /* Make sure we are not mucking with the template database */
- if (!strcmp(dbname, "template1")) {
- elog(WARN, "%s cannot be executed on the template database.", command);
- }
-
- /* Check to make sure database is not the currently open database */
- if (!strcmp(dbname, GetDatabaseName())) {
- elog(WARN, "%s cannot be executed on an open database", command);
- }
-
- /* Check to make sure database is owned by this user */
-
- /*
- * need the reldesc to get the database owner out of dbtup
- * and to set a write lock on it.
- */
- dbrel = heap_openr(DatabaseRelationName);
-
- if (!RelationIsValid(dbrel))
- elog(FATAL, "%s: cannot open relation \"%-.*s\"",
- command, DatabaseRelationName);
-
- /*
- * Acquire a write lock on pg_database from the beginning to avoid
- * upgrading a read lock to a write lock. Upgrading causes long delays
- * when multiple 'createdb's or 'destroydb's are run simult. -mer 7/3/91
- */
- RelationSetLockForWrite(dbrel);
- dbtup = get_pg_dbtup(command, dbname, dbrel);
- dbfound = HeapTupleIsValid(dbtup);
-
- if (dbfound) {
- dbowner = (Oid) heap_getattr(dbtup, InvalidBuffer,
- Anum_pg_database_datdba,
- RelationGetTupleDescriptor(dbrel),
- (char *) NULL);
- *dbIdP = dbtup->t_oid;
- } else {
- *dbIdP = InvalidOid;
- }
-
- heap_close(dbrel);
-
- /*
- * Now be sure that the user is allowed to do this.
- */
-
- if (dbfound && !strcmp(command, "createdb")) {
-
- elog(WARN, "createdb: database %s already exists.", dbname);
-
- } else if (!dbfound && !strcmp(command, "destroydb")) {
-
- elog(WARN, "destroydb: database %s does not exist.", dbname);
-
- } else if (dbfound && !strcmp(command, "destroydb")
- && dbowner != *userIdP && use_super == false) {
-
- elog(WARN, "%s: database %s is not owned by you.", command, dbname);
-
- }
+ Relation dbrel;
+ HeapTuple dbtup,
+ utup;
+ Oid dbowner = (Oid) 0;
+ char use_createdb;
+ bool dbfound;
+ bool use_super;
+ char *userName;
+
+ userName = GetPgUserName();
+ utup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName),
+ 0, 0, 0);
+ *userIdP = ((Form_pg_user) GETSTRUCT(utup))->usesysid;
+ use_super = ((Form_pg_user) GETSTRUCT(utup))->usesuper;
+ use_createdb = ((Form_pg_user) GETSTRUCT(utup))->usecreatedb;
+
+ /* Check to make sure user has permission to use createdb */
+ if (!use_createdb)
+ {
+ elog(WARN, "user \"%s\" is not allowed to create/destroy databases",
+ userName);
+ }
+
+ /* Make sure we are not mucking with the template database */
+ if (!strcmp(dbname, "template1"))
+ {
+ elog(WARN, "%s cannot be executed on the template database.", command);
+ }
+
+ /* Check to make sure database is not the currently open database */
+ if (!strcmp(dbname, GetDatabaseName()))
+ {
+ elog(WARN, "%s cannot be executed on an open database", command);
+ }
+
+ /* Check to make sure database is owned by this user */
+
+ /*
+ * need the reldesc to get the database owner out of dbtup and to set
+ * a write lock on it.
+ */
+ dbrel = heap_openr(DatabaseRelationName);
+
+ if (!RelationIsValid(dbrel))
+ elog(FATAL, "%s: cannot open relation \"%-.*s\"",
+ command, DatabaseRelationName);
+
+ /*
+ * Acquire a write lock on pg_database from the beginning to avoid
+ * upgrading a read lock to a write lock. Upgrading causes long
+ * delays when multiple 'createdb's or 'destroydb's are run simult.
+ * -mer 7/3/91
+ */
+ RelationSetLockForWrite(dbrel);
+ dbtup = get_pg_dbtup(command, dbname, dbrel);
+ dbfound = HeapTupleIsValid(dbtup);
+
+ if (dbfound)
+ {
+ dbowner = (Oid) heap_getattr(dbtup, InvalidBuffer,
+ Anum_pg_database_datdba,
+ RelationGetTupleDescriptor(dbrel),
+ (char *) NULL);
+ *dbIdP = dbtup->t_oid;
+ }
+ else
+ {
+ *dbIdP = InvalidOid;
+ }
+
+ heap_close(dbrel);
+
+ /*
+ * Now be sure that the user is allowed to do this.
+ */
+
+ if (dbfound && !strcmp(command, "createdb"))
+ {
+
+ elog(WARN, "createdb: database %s already exists.", dbname);
+
+ }
+ else if (!dbfound && !strcmp(command, "destroydb"))
+ {
+
+ elog(WARN, "destroydb: database %s does not exist.", dbname);
+
+ }
+ else if (dbfound && !strcmp(command, "destroydb")
+ && dbowner != *userIdP && use_super == false)
+ {
+
+ elog(WARN, "%s: database %s is not owned by you.", command, dbname);
+
+ }
}
/*
- * stop_vacuum() -- stop the vacuum daemon on the database, if one is
- * running.
+ * stop_vacuum() -- stop the vacuum daemon on the database, if one is
+ * running.
*/
static void
stop_vacuum(char *dbname)
{
- char filename[256];
- FILE *fp;
- int pid;
-
- sprintf(filename, "%s%cbase%c%s%c%s.vacuum", DataDir, SEP_CHAR, SEP_CHAR,
- dbname, SEP_CHAR, dbname);
- if ((fp = AllocateFile(filename, "r")) != NULL) {
- fscanf(fp, "%d", &pid);
- FreeFile(fp);
- if (kill(pid, SIGKILLDAEMON1) < 0) {
- elog(WARN, "can't kill vacuum daemon (pid %d) on %s",
- pid, dbname);
+ char filename[256];
+ FILE *fp;
+ int pid;
+
+ sprintf(filename, "%s%cbase%c%s%c%s.vacuum", DataDir, SEP_CHAR, SEP_CHAR,
+ dbname, SEP_CHAR, dbname);
+ if ((fp = AllocateFile(filename, "r")) != NULL)
+ {
+ fscanf(fp, "%d", &pid);
+ FreeFile(fp);
+ if (kill(pid, SIGKILLDAEMON1) < 0)
+ {
+ elog(WARN, "can't kill vacuum daemon (pid %d) on %s",
+ pid, dbname);
+ }
}
- }
}
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index 9aa6da82ca6..b9f1a273398 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* keywords.c--
- * lexical token lookup for reserved words in postgres SQL
+ * lexical token lookup for reserved words in postgres SQL
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.14 1997/09/04 13:24:26 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.15 1997/09/07 04:44:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,202 +20,204 @@
#include "parse.h"
#include "utils/elog.h"
#include "parser/keywords.h"
-#include "parser/dbcommands.h" /* createdb, destroydb stop_vacuum */
+#include "parser/dbcommands.h" /* createdb, destroydb stop_vacuum */
/*
* List of (keyword-name, keyword-token-value) pairs.
*
* !!WARNING!!: This list must be sorted, because binary
- * search is used to locate entries.
+ * search is used to locate entries.
*/
static ScanKeyword ScanKeywords[] = {
- /* name value */
- { "abort", ABORT_TRANS },
- { "acl", ACL },
- { "add", ADD },
- { "after", AFTER },
- { "aggregate", AGGREGATE },
- { "all", ALL },
- { "alter", ALTER },
- { "analyze", ANALYZE },
- { "and", AND },
- { "append", APPEND },
- { "archIve", ARCHIVE }, /* XXX crooked: I < _ */
- { "arch_store", ARCH_STORE },
- { "archive", ARCHIVE }, /* XXX crooked: i > _ */
- { "as", AS },
- { "asc", ASC },
- { "backward", BACKWARD },
- { "before", BEFORE },
- { "begin", BEGIN_TRANS },
- { "between", BETWEEN },
- { "binary", BINARY },
- { "both", BOTH },
- { "by", BY },
- { "cast", CAST },
- { "change", CHANGE },
- { "check", CHECK },
- { "close", CLOSE },
- { "cluster", CLUSTER },
- { "column", COLUMN },
- { "commit", COMMIT },
- { "constraint", CONSTRAINT },
- { "copy", COPY },
- { "create", CREATE },
- { "cross", CROSS },
- { "current", CURRENT },
- { "cursor", CURSOR },
- { "database", DATABASE },
- { "day", DAYINTERVAL },
- { "declare", DECLARE },
- { "default", DEFAULT },
- { "delete", DELETE },
- { "delimiters", DELIMITERS },
- { "desc", DESC },
- { "distinct", DISTINCT },
- { "do", DO },
- { "drop", DROP },
- { "end", END_TRANS },
- { "execute", EXECUTE },
- { "exists", EXISTS },
- { "explain", EXPLAIN },
- { "extend", EXTEND },
- { "extract", EXTRACT },
- { "fetch", FETCH },
- { "for", FOR },
- { "forward", FORWARD },
- { "from", FROM },
- { "full", FULL },
- { "function", FUNCTION },
- { "grant", GRANT },
- { "group", GROUP },
- { "having", HAVING },
- { "heavy", HEAVY },
- { "hour", HOURINTERVAL },
- { "in", IN },
- { "index", INDEX },
- { "inherits", INHERITS },
- { "inner", INNERJOIN },
- { "insert", INSERT },
- { "instead", INSTEAD },
- { "interval", INTERVAL },
- { "into", INTO },
- { "is", IS },
- { "isnull", ISNULL },
- { "join", JOIN },
- { "language", LANGUAGE },
- { "leading", LEADING },
- { "left", LEFT },
- { "light", LIGHT },
- { "like", LIKE },
- { "listen", LISTEN },
- { "load", LOAD },
- { "local", LOCAL },
- { "merge", MERGE },
- { "minute", MINUTEINTERVAL },
- { "month", MONTHINTERVAL },
- { "move", MOVE },
- { "natural", NATURAL },
- { "new", NEW },
- { "none", NONE },
- { "not", NOT },
- { "nothing", NOTHING },
- { "notify", NOTIFY },
- { "notnull", NOTNULL },
- { "null", PNULL },
- { "oids", OIDS },
- { "on", ON },
- { "operator", OPERATOR },
- { "option", OPTION },
- { "or", OR },
- { "order", ORDER },
- { "outer", OUTERJOIN },
- { "position", POSITION },
- { "privileges", PRIVILEGES },
- { "procedure", PROCEDURE },
- { "public", PUBLIC },
- { "purge", PURGE },
- { "recipe", RECIPE },
- { "rename", RENAME },
- { "replace", REPLACE },
- { "reset", RESET },
- { "retrieve", RETRIEVE },
- { "returns", RETURNS },
- { "revoke", REVOKE },
- { "right", RIGHT },
- { "rollback", ROLLBACK },
- { "rule", RULE },
- { "second", SECONDINTERVAL },
- { "select", SELECT },
- { "sequence", SEQUENCE },
- { "set", SET },
- { "setof", SETOF },
- { "show", SHOW },
- { "stdin", STDIN },
- { "stdout", STDOUT },
- { "store", STORE },
- { "substring", SUBSTRING },
- { "table", TABLE },
- { "time", TIME },
- { "to", TO },
- { "transaction", TRANSACTION },
- { "trailing", TRAILING },
- { "trigger", TRIGGER },
- { "trim", TRIM },
- { "type", P_TYPE },
- { "union", UNION },
- { "unique", UNIQUE },
- { "update", UPDATE },
- { "using", USING },
- { "vacuum", VACUUM },
- { "values", VALUES },
- { "verbose", VERBOSE },
- { "version", VERSION },
- { "view", VIEW },
- { "where", WHERE },
- { "with", WITH },
- { "work", WORK },
- { "year", YEARINTERVAL },
- { "zone", ZONE },
+ /* name value */
+ {"abort", ABORT_TRANS},
+ {"acl", ACL},
+ {"add", ADD},
+ {"after", AFTER},
+ {"aggregate", AGGREGATE},
+ {"all", ALL},
+ {"alter", ALTER},
+ {"analyze", ANALYZE},
+ {"and", AND},
+ {"append", APPEND},
+ {"archIve", ARCHIVE}, /* XXX crooked: I < _ */
+ {"arch_store", ARCH_STORE},
+ {"archive", ARCHIVE}, /* XXX crooked: i > _ */
+ {"as", AS},
+ {"asc", ASC},
+ {"backward", BACKWARD},
+ {"before", BEFORE},
+ {"begin", BEGIN_TRANS},
+ {"between", BETWEEN},
+ {"binary", BINARY},
+ {"both", BOTH},
+ {"by", BY},
+ {"cast", CAST},
+ {"change", CHANGE},
+ {"check", CHECK},
+ {"close", CLOSE},
+ {"cluster", CLUSTER},
+ {"column", COLUMN},
+ {"commit", COMMIT},
+ {"constraint", CONSTRAINT},
+ {"copy", COPY},
+ {"create", CREATE},
+ {"cross", CROSS},
+ {"current", CURRENT},
+ {"cursor", CURSOR},
+ {"database", DATABASE},
+ {"day", DAYINTERVAL},
+ {"declare", DECLARE},
+ {"default", DEFAULT},
+ {"delete", DELETE},
+ {"delimiters", DELIMITERS},
+ {"desc", DESC},
+ {"distinct", DISTINCT},
+ {"do", DO},
+ {"drop", DROP},
+ {"end", END_TRANS},
+ {"execute", EXECUTE},
+ {"exists", EXISTS},
+ {"explain", EXPLAIN},
+ {"extend", EXTEND},
+ {"extract", EXTRACT},
+ {"fetch", FETCH},
+ {"for", FOR},
+ {"forward", FORWARD},
+ {"from", FROM},
+ {"full", FULL},
+ {"function", FUNCTION},
+ {"grant", GRANT},
+ {"group", GROUP},
+ {"having", HAVING},
+ {"heavy", HEAVY},
+ {"hour", HOURINTERVAL},
+ {"in", IN},
+ {"index", INDEX},
+ {"inherits", INHERITS},
+ {"inner", INNERJOIN},
+ {"insert", INSERT},
+ {"instead", INSTEAD},
+ {"interval", INTERVAL},
+ {"into", INTO},
+ {"is", IS},
+ {"isnull", ISNULL},
+ {"join", JOIN},
+ {"language", LANGUAGE},
+ {"leading", LEADING},
+ {"left", LEFT},
+ {"light", LIGHT},
+ {"like", LIKE},
+ {"listen", LISTEN},
+ {"load", LOAD},
+ {"local", LOCAL},
+ {"merge", MERGE},
+ {"minute", MINUTEINTERVAL},
+ {"month", MONTHINTERVAL},
+ {"move", MOVE},
+ {"natural", NATURAL},
+ {"new", NEW},
+ {"none", NONE},
+ {"not", NOT},
+ {"nothing", NOTHING},
+ {"notify", NOTIFY},
+ {"notnull", NOTNULL},
+ {"null", PNULL},
+ {"oids", OIDS},
+ {"on", ON},
+ {"operator", OPERATOR},
+ {"option", OPTION},
+ {"or", OR},
+ {"order", ORDER},
+ {"outer", OUTERJOIN},
+ {"position", POSITION},
+ {"privileges", PRIVILEGES},
+ {"procedure", PROCEDURE},
+ {"public", PUBLIC},
+ {"purge", PURGE},
+ {"recipe", RECIPE},
+ {"rename", RENAME},
+ {"replace", REPLACE},
+ {"reset", RESET},
+ {"retrieve", RETRIEVE},
+ {"returns", RETURNS},
+ {"revoke", REVOKE},
+ {"right", RIGHT},
+ {"rollback", ROLLBACK},
+ {"rule", RULE},
+ {"second", SECONDINTERVAL},
+ {"select", SELECT},
+ {"sequence", SEQUENCE},
+ {"set", SET},
+ {"setof", SETOF},
+ {"show", SHOW},
+ {"stdin", STDIN},
+ {"stdout", STDOUT},
+ {"store", STORE},
+ {"substring", SUBSTRING},
+ {"table", TABLE},
+ {"time", TIME},
+ {"to", TO},
+ {"transaction", TRANSACTION},
+ {"trailing", TRAILING},
+ {"trigger", TRIGGER},
+ {"trim", TRIM},
+ {"type", P_TYPE},
+ {"union", UNION},
+ {"unique", UNIQUE},
+ {"update", UPDATE},
+ {"using", USING},
+ {"vacuum", VACUUM},
+ {"values", VALUES},
+ {"verbose", VERBOSE},
+ {"version", VERSION},
+ {"view", VIEW},
+ {"where", WHERE},
+ {"with", WITH},
+ {"work", WORK},
+ {"year", YEARINTERVAL},
+ {"zone", ZONE},
};
-ScanKeyword *
+ScanKeyword *
ScanKeywordLookup(char *text)
{
- ScanKeyword *low = &ScanKeywords[0];
- ScanKeyword *high = endof(ScanKeywords) - 1;
- ScanKeyword *middle;
- int difference;
-
- while (low <= high) {
- middle = low + (high - low) / 2;
- difference = strcmp(middle->name, text);
- if (difference == 0)
- return (middle);
- else if (difference < 0)
- low = middle + 1;
- else
- high = middle - 1;
- }
-
- return (NULL);
+ ScanKeyword *low = &ScanKeywords[0];
+ ScanKeyword *high = endof(ScanKeywords) - 1;
+ ScanKeyword *middle;
+ int difference;
+
+ while (low <= high)
+ {
+ middle = low + (high - low) / 2;
+ difference = strcmp(middle->name, text);
+ if (difference == 0)
+ return (middle);
+ else if (difference < 0)
+ low = middle + 1;
+ else
+ high = middle - 1;
+ }
+
+ return (NULL);
}
#ifdef NOT_USED
-char*
+char *
AtomValueGetString(int atomval)
{
- ScanKeyword *low = &ScanKeywords[0];
- ScanKeyword *high = endof(ScanKeywords) - 1;
- int keyword_list_length = (high-low);
- int i;
-
- for (i=0; i < keyword_list_length ; i++ )
- if (ScanKeywords[i].value == atomval )
- return(ScanKeywords[i].name);
-
- elog(WARN,"AtomGetString called with bogus atom # : %d", atomval );
- return(NULL);
+ ScanKeyword *low = &ScanKeywords[0];
+ ScanKeyword *high = endof(ScanKeywords) - 1;
+ int keyword_list_length = (high - low);
+ int i;
+
+ for (i = 0; i < keyword_list_length; i++)
+ if (ScanKeywords[i].value == atomval)
+ return (ScanKeywords[i].name);
+
+ elog(WARN, "AtomGetString called with bogus atom # : %d", atomval);
+ return (NULL);
}
+
#endif
diff --git a/src/backend/parser/parse_query.c b/src/backend/parser/parse_query.c
index b19b291769f..5d144660a48 100644
--- a/src/backend/parser/parse_query.c
+++ b/src/backend/parser/parse_query.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* parse_query.c--
- * take an "optimizable" stmt and make the query tree that
- * the planner requires.
+ * take an "optimizable" stmt and make the query tree that
+ * the planner requires.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/parse_query.c,v 1.18 1997/08/22 00:02:07 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/parse_query.c,v 1.19 1997/09/07 04:44:48 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,8 +23,8 @@
#include "utils/builtins.h"
#include "utils/elog.h"
#include "utils/palloc.h"
-#include "utils/acl.h" /* for ACL_NO_PRIV_WARNING */
-#include "utils/rel.h" /* Relation stuff */
+#include "utils/acl.h" /* for ACL_NO_PRIV_WARNING */
+#include "utils/rel.h" /* Relation stuff */
#include "utils/syscache.h"
#include "catalog/pg_type.h"
@@ -38,680 +38,744 @@
#include "nodes/parsenodes.h"
#include "nodes/makefuncs.h"
-static void checkTargetTypes(ParseState *pstate, char *target_colname,
- char *refname, char *colname);
+static void
+checkTargetTypes(ParseState * pstate, char *target_colname,
+ char *refname, char *colname);
-Oid *param_type_info;
-int pfunc_num_args;
+Oid *param_type_info;
+int pfunc_num_args;
/* given refname, return a pointer to the range table entry */
-RangeTblEntry *
-refnameRangeTableEntry(List *rtable, char *refname)
+RangeTblEntry *
+refnameRangeTableEntry(List * rtable, char *refname)
{
- List *temp;
-
- foreach(temp, rtable) {
- RangeTblEntry *rte = lfirst(temp);
-
- if (!strcmp(rte->refname, refname))
- return rte;
- }
- return NULL;
+ List *temp;
+
+ foreach(temp, rtable)
+ {
+ RangeTblEntry *rte = lfirst(temp);
+
+ if (!strcmp(rte->refname, refname))
+ return rte;
+ }
+ return NULL;
}
/* given refname, return id of variable; position starts with 1 */
int
-refnameRangeTablePosn(List *rtable, char *refname)
+refnameRangeTablePosn(List * rtable, char *refname)
{
- int index;
- List *temp;
-
- index = 1;
- foreach(temp, rtable) {
- RangeTblEntry *rte = lfirst(temp);
-
- if (!strcmp(rte->refname, refname))
- return index;
- index++;
- }
- return(0);
+ int index;
+ List *temp;
+
+ index = 1;
+ foreach(temp, rtable)
+ {
+ RangeTblEntry *rte = lfirst(temp);
+
+ if (!strcmp(rte->refname, refname))
+ return index;
+ index++;
+ }
+ return (0);
}
/*
* returns range entry if found, else NULL
*/
-RangeTblEntry *
-colnameRangeTableEntry(ParseState *pstate, char *colname)
+RangeTblEntry *
+colnameRangeTableEntry(ParseState * pstate, char *colname)
{
- List *et;
- List *rtable;
- RangeTblEntry *rte_result;
+ List *et;
+ List *rtable;
+ RangeTblEntry *rte_result;
- if (pstate->p_is_rule)
- rtable = lnext(lnext(pstate->p_rtable));
- else
- rtable = pstate->p_rtable;
+ if (pstate->p_is_rule)
+ rtable = lnext(lnext(pstate->p_rtable));
+ else
+ rtable = pstate->p_rtable;
- rte_result = NULL;
- foreach(et, rtable) {
- RangeTblEntry *rte = lfirst(et);
+ rte_result = NULL;
+ foreach(et, rtable)
+ {
+ RangeTblEntry *rte = lfirst(et);
/* only entries on outer(non-function?) scope */
- if (!rte->inFromCl && rte != pstate->p_target_rangetblentry)
- continue;
-
- if (get_attnum(rte->relid, colname) != InvalidAttrNumber) {
- if (rte_result != NULL) {
- if (!pstate->p_is_insert ||
- rte != pstate->p_target_rangetblentry)
- elog(WARN, "Column %s is ambiguous", colname);
- }
- else rte_result = rte;
+ if (!rte->inFromCl && rte != pstate->p_target_rangetblentry)
+ continue;
+
+ if (get_attnum(rte->relid, colname) != InvalidAttrNumber)
+ {
+ if (rte_result != NULL)
+ {
+ if (!pstate->p_is_insert ||
+ rte != pstate->p_target_rangetblentry)
+ elog(WARN, "Column %s is ambiguous", colname);
+ }
+ else
+ rte_result = rte;
+ }
}
- }
- return rte_result;
+ return rte_result;
}
/*
* put new entry in pstate p_rtable structure, or return pointer
* if pstate null
*/
-RangeTblEntry *
-addRangeTableEntry(ParseState *pstate,
- char *relname,
- char *refname,
- bool inh, bool inFromCl,
- TimeRange *timeRange)
+RangeTblEntry *
+addRangeTableEntry(ParseState * pstate,
+ char *relname,
+ char *refname,
+ bool inh, bool inFromCl,
+ TimeRange * timeRange)
{
- Relation relation;
- RangeTblEntry *rte = makeNode(RangeTblEntry);
-
- if (pstate != NULL &&
- refnameRangeTableEntry(pstate->p_rtable, refname) != NULL)
- elog(WARN,"Table name %s specified more than once",refname);
-
- rte->relname = pstrdup(relname);
- rte->refname = pstrdup(refname);
-
- relation = heap_openr(relname);
- if (relation == NULL) {
- elog(WARN,"%s: %s",
- relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]);
- }
-
- /*
- * Flags - zero or more from archive,inheritance,union,version
- * or recursive (transitive closure)
- * [we don't support them all -- ay 9/94 ]
- */
- rte->inh = inh;
-
- rte->timeRange = timeRange;
-
- /* RelOID */
- rte->relid = RelationGetRelationId(relation);
-
- rte->archive = false;
-
- rte->inFromCl = inFromCl;
-
- /*
- * close the relation we're done with it for now.
- */
- if (pstate != NULL)
- pstate->p_rtable = lappend(pstate->p_rtable, rte);
-
- heap_close(relation);
-
- return rte;
+ Relation relation;
+ RangeTblEntry *rte = makeNode(RangeTblEntry);
+
+ if (pstate != NULL &&
+ refnameRangeTableEntry(pstate->p_rtable, refname) != NULL)
+ elog(WARN, "Table name %s specified more than once", refname);
+
+ rte->relname = pstrdup(relname);
+ rte->refname = pstrdup(refname);
+
+ relation = heap_openr(relname);
+ if (relation == NULL)
+ {
+ elog(WARN, "%s: %s",
+ relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]);
+ }
+
+ /*
+ * Flags - zero or more from archive,inheritance,union,version or
+ * recursive (transitive closure) [we don't support them all -- ay
+ * 9/94 ]
+ */
+ rte->inh = inh;
+
+ rte->timeRange = timeRange;
+
+ /* RelOID */
+ rte->relid = RelationGetRelationId(relation);
+
+ rte->archive = false;
+
+ rte->inFromCl = inFromCl;
+
+ /*
+ * close the relation we're done with it for now.
+ */
+ if (pstate != NULL)
+ pstate->p_rtable = lappend(pstate->p_rtable, rte);
+
+ heap_close(relation);
+
+ return rte;
}
/*
* expandAll -
- * makes a list of attributes
- * assumes reldesc caching works
+ * makes a list of attributes
+ * assumes reldesc caching works
*/
-List *
-expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno)
+List *
+expandAll(ParseState * pstate, char *relname, char *refname, int *this_resno)
{
- Relation rdesc;
- List *te_tail = NIL, *te_head = NIL;
- Var *varnode;
- int varattno, maxattrs;
- Oid type_id;
- int type_len;
- RangeTblEntry *rte;
-
- rte = refnameRangeTableEntry(pstate->p_rtable, refname);
- if (rte == NULL)
- rte = addRangeTableEntry(pstate, relname, refname, FALSE, FALSE, NULL);
-
- rdesc = heap_open(rte->relid);
-
- if (rdesc == NULL ) {
- elog(WARN,"Unable to expand all -- heap_open failed on %s",
- rte->refname);
- return NIL;
- }
- maxattrs = RelationGetNumberOfAttributes(rdesc);
-
- for ( varattno = 0; varattno <= maxattrs-1 ; varattno++ ) {
- char *attrname;
- char *resname = NULL;
- TargetEntry *te = makeNode(TargetEntry);
-
- attrname = pstrdup ((rdesc->rd_att->attrs[varattno]->attname).data);
- varnode = (Var*)make_var(pstate, refname, attrname, &type_id);
- type_len = (int)tlen(get_id_type(type_id));
-
- handleTargetColname(pstate, &resname, refname, attrname);
- if (resname != NULL)
- attrname = resname;
-
- /* Even if the elements making up a set are complex, the
- * set itself is not. */
-
- te->resdom = makeResdom((AttrNumber) (*this_resno)++,
- type_id,
- (Size)type_len,
- attrname,
- (Index)0,
- (Oid)0,
- 0);
- te->expr = (Node *)varnode;
- if (te_head == NIL)
- te_head = te_tail = lcons(te, NIL);
- else te_tail = lappend(te_tail, te);
- }
-
- heap_close(rdesc);
- return(te_head);
+ Relation rdesc;
+ List *te_tail = NIL,
+ *te_head = NIL;
+ Var *varnode;
+ int varattno,
+ maxattrs;
+ Oid type_id;
+ int type_len;
+ RangeTblEntry *rte;
+
+ rte = refnameRangeTableEntry(pstate->p_rtable, refname);
+ if (rte == NULL)
+ rte = addRangeTableEntry(pstate, relname, refname, FALSE, FALSE, NULL);
+
+ rdesc = heap_open(rte->relid);
+
+ if (rdesc == NULL)
+ {
+ elog(WARN, "Unable to expand all -- heap_open failed on %s",
+ rte->refname);
+ return NIL;
+ }
+ maxattrs = RelationGetNumberOfAttributes(rdesc);
+
+ for (varattno = 0; varattno <= maxattrs - 1; varattno++)
+ {
+ char *attrname;
+ char *resname = NULL;
+ TargetEntry *te = makeNode(TargetEntry);
+
+ attrname = pstrdup((rdesc->rd_att->attrs[varattno]->attname).data);
+ varnode = (Var *) make_var(pstate, refname, attrname, &type_id);
+ type_len = (int) tlen(get_id_type(type_id));
+
+ handleTargetColname(pstate, &resname, refname, attrname);
+ if (resname != NULL)
+ attrname = resname;
+
+ /*
+ * Even if the elements making up a set are complex, the set
+ * itself is not.
+ */
+
+ te->resdom = makeResdom((AttrNumber) (*this_resno)++,
+ type_id,
+ (Size) type_len,
+ attrname,
+ (Index) 0,
+ (Oid) 0,
+ 0);
+ te->expr = (Node *) varnode;
+ if (te_head == NIL)
+ te_head = te_tail = lcons(te, NIL);
+ else
+ te_tail = lappend(te_tail, te);
+ }
+
+ heap_close(rdesc);
+ return (te_head);
}
TimeQual
makeTimeRange(char *datestring1,
- char *datestring2,
- int timecode) /* 0 = snapshot , 1 = timerange */
+ char *datestring2,
+ int timecode) /* 0 = snapshot , 1 = timerange */
{
- TimeQual qual = NULL;
- AbsoluteTime t1,t2;
-
- switch (timecode) {
- case 0:
- if (datestring1 == NULL) {
- elog(WARN, "MakeTimeRange: bad snapshot arg");
- }
- t1 = nabstimein(datestring1);
- if (!AbsoluteTimeIsValid(t1)) {
- elog(WARN, "bad snapshot time: \"%s\"",
- datestring1);
- }
- qual = TimeFormSnapshotTimeQual(t1);
- break;
- case 1:
- if (datestring1 == NULL) {
- t1 = NOSTART_ABSTIME;
- } else {
- t1 = nabstimein(datestring1);
- if (!AbsoluteTimeIsValid(t1)) {
- elog(WARN,
- "bad range start time: \"%s\"",
- datestring1);
- }
- }
- if (datestring2 == NULL) {
- t2 = NOEND_ABSTIME;
- } else {
- t2 = nabstimein(datestring2);
- if (!AbsoluteTimeIsValid(t2)) {
- elog(WARN,
- "bad range end time: \"%s\"",
- datestring2);
- }
+ TimeQual qual = NULL;
+ AbsoluteTime t1,
+ t2;
+
+ switch (timecode)
+ {
+ case 0:
+ if (datestring1 == NULL)
+ {
+ elog(WARN, "MakeTimeRange: bad snapshot arg");
+ }
+ t1 = nabstimein(datestring1);
+ if (!AbsoluteTimeIsValid(t1))
+ {
+ elog(WARN, "bad snapshot time: \"%s\"",
+ datestring1);
+ }
+ qual = TimeFormSnapshotTimeQual(t1);
+ break;
+ case 1:
+ if (datestring1 == NULL)
+ {
+ t1 = NOSTART_ABSTIME;
+ }
+ else
+ {
+ t1 = nabstimein(datestring1);
+ if (!AbsoluteTimeIsValid(t1))
+ {
+ elog(WARN,
+ "bad range start time: \"%s\"",
+ datestring1);
+ }
+ }
+ if (datestring2 == NULL)
+ {
+ t2 = NOEND_ABSTIME;
+ }
+ else
+ {
+ t2 = nabstimein(datestring2);
+ if (!AbsoluteTimeIsValid(t2))
+ {
+ elog(WARN,
+ "bad range end time: \"%s\"",
+ datestring2);
+ }
+ }
+ qual = TimeFormRangedTimeQual(t1, t2);
+ break;
+ default:
+ elog(WARN, "MakeTimeRange: internal parser error");
}
- qual = TimeFormRangedTimeQual(t1,t2);
- break;
- default:
- elog(WARN, "MakeTimeRange: internal parser error");
- }
- return qual;
+ return qual;
}
static void
-disallow_setop(char *op, Type optype, Node *operand)
+disallow_setop(char *op, Type optype, Node * operand)
{
- if (operand==NULL)
- return;
-
- if (nodeTag(operand) == T_Iter) {
- elog(NOTICE, "An operand to the '%s' operator returns a set of %s,",
- op, tname(optype));
- elog(WARN, "but '%s' takes single values, not sets.",
- op);
- }
+ if (operand == NULL)
+ return;
+
+ if (nodeTag(operand) == T_Iter)
+ {
+ elog(NOTICE, "An operand to the '%s' operator returns a set of %s,",
+ op, tname(optype));
+ elog(WARN, "but '%s' takes single values, not sets.",
+ op);
+ }
}
-static Node *
+static Node *
make_operand(char *opname,
- Node *tree,
- Oid orig_typeId,
- Oid true_typeId)
+ Node * tree,
+ Oid orig_typeId,
+ Oid true_typeId)
{
- Node *result;
- Type true_type;
- Datum val;
- Oid infunc;
-
- if (tree != NULL) {
- result = tree;
- true_type = get_id_type(true_typeId);
- disallow_setop(opname, true_type, result);
- if (true_typeId != orig_typeId) { /* must coerce */
- Const *con= (Const *)result;
-
- Assert(nodeTag(result)==T_Const);
- val = (Datum)textout((struct varlena *)
- con->constvalue);
- infunc = typeid_get_retinfunc(true_typeId);
- con = makeNode(Const);
- con->consttype = true_typeId;
- con->constlen = tlen(true_type);
- con->constvalue = (Datum)fmgr(infunc,
- val,
- get_typelem(true_typeId),
- -1 /* for varchar() type */);
- con->constisnull = false;
- con->constbyval = true;
- con->constisset = false;
- result = (Node *)con;
+ Node *result;
+ Type true_type;
+ Datum val;
+ Oid infunc;
+
+ if (tree != NULL)
+ {
+ result = tree;
+ true_type = get_id_type(true_typeId);
+ disallow_setop(opname, true_type, result);
+ if (true_typeId != orig_typeId)
+ { /* must coerce */
+ Const *con = (Const *) result;
+
+ Assert(nodeTag(result) == T_Const);
+ val = (Datum) textout((struct varlena *)
+ con->constvalue);
+ infunc = typeid_get_retinfunc(true_typeId);
+ con = makeNode(Const);
+ con->consttype = true_typeId;
+ con->constlen = tlen(true_type);
+ con->constvalue = (Datum) fmgr(infunc,
+ val,
+ get_typelem(true_typeId),
+ -1 /* for varchar() type */ );
+ con->constisnull = false;
+ con->constbyval = true;
+ con->constisset = false;
+ result = (Node *) con;
+ }
+ }
+ else
+ {
+ Const *con = makeNode(Const);
+
+ con->consttype = true_typeId;
+ con->constlen = 0;
+ con->constvalue = (Datum) (struct varlena *) NULL;
+ con->constisnull = true;
+ con->constbyval = true;
+ con->constisset = false;
+ result = (Node *) con;
}
- }else {
- Const *con= makeNode(Const);
-
- con->consttype = true_typeId;
- con->constlen = 0;
- con->constvalue = (Datum)(struct varlena *)NULL;
- con->constisnull = true;
- con->constbyval = true;
- con->constisset = false;
- result = (Node *)con;
- }
-
- return result;
+
+ return result;
}
-Expr *
-make_op(char *opname, Node *ltree, Node *rtree)
+Expr *
+make_op(char *opname, Node * ltree, Node * rtree)
{
- Oid ltypeId, rtypeId;
- Operator temp;
- OperatorTupleForm opform;
- Oper *newop;
- Node *left, *right;
- Expr *result;
-
- if (rtree == NULL) {
-
- /* right operator */
- ltypeId = (ltree==NULL) ? UNKNOWNOID : exprType(ltree);
- temp = right_oper(opname, ltypeId);
- opform = (OperatorTupleForm) GETSTRUCT(temp);
- left = make_operand(opname, ltree, ltypeId, opform->oprleft);
- right = NULL;
-
- }else if (ltree == NULL) {
-
- /* left operator */
- rtypeId = (rtree==NULL) ? UNKNOWNOID : exprType(rtree);
- temp = left_oper(opname, rtypeId);
- opform = (OperatorTupleForm) GETSTRUCT(temp);
- right = make_operand(opname, rtree, rtypeId, opform->oprright);
- left = NULL;
-
- }else {
- char *outstr;
- Oid infunc, outfunc;
- Type newtype;
+ Oid ltypeId,
+ rtypeId;
+ Operator temp;
+ OperatorTupleForm opform;
+ Oper *newop;
+ Node *left,
+ *right;
+ Expr *result;
+
+ if (rtree == NULL)
+ {
+
+ /* right operator */
+ ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
+ temp = right_oper(opname, ltypeId);
+ opform = (OperatorTupleForm) GETSTRUCT(temp);
+ left = make_operand(opname, ltree, ltypeId, opform->oprleft);
+ right = NULL;
+
+ }
+ else if (ltree == NULL)
+ {
+
+ /* left operator */
+ rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
+ temp = left_oper(opname, rtypeId);
+ opform = (OperatorTupleForm) GETSTRUCT(temp);
+ right = make_operand(opname, rtree, rtypeId, opform->oprright);
+ left = NULL;
+
+ }
+ else
+ {
+ char *outstr;
+ Oid infunc,
+ outfunc;
+ Type newtype;
#define CONVERTABLE_TYPE(t) ( (t) == INT2OID || \
- (t) == INT4OID || \
- (t) == OIDOID || \
- (t) == FLOAT4OID || \
- (t) == FLOAT8OID || \
- (t) == CASHOID)
-
- /* binary operator */
- ltypeId = (ltree==NULL) ? UNKNOWNOID : exprType(ltree);
- rtypeId = (rtree==NULL) ? UNKNOWNOID : exprType(rtree);
-
- /* convert constant when using a const of a numeric type
- and a non-const of another numeric type */
- if (CONVERTABLE_TYPE(ltypeId) && nodeTag(ltree) != T_Const &&
- CONVERTABLE_TYPE(rtypeId) && nodeTag(rtree) == T_Const &&
- !((Const *)rtree)->constiscast) {
- outfunc = typeid_get_retoutfunc(rtypeId);
- infunc = typeid_get_retinfunc(ltypeId);
- outstr = (char *)fmgr(outfunc, ((Const *)rtree)->constvalue);
- ((Const *)rtree)->constvalue = (Datum)fmgr(infunc, outstr);
- pfree(outstr);
- ((Const *)rtree)->consttype = rtypeId = ltypeId;
- newtype = get_id_type(rtypeId);
- ((Const *)rtree)->constlen = tlen(newtype);
- ((Const *)rtree)->constbyval = tbyval(newtype);
+ (t) == INT4OID || \
+ (t) == OIDOID || \
+ (t) == FLOAT4OID || \
+ (t) == FLOAT8OID || \
+ (t) == CASHOID)
+
+ /* binary operator */
+ ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
+ rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
+
+ /*
+ * convert constant when using a const of a numeric type and a
+ * non-const of another numeric type
+ */
+ if (CONVERTABLE_TYPE(ltypeId) && nodeTag(ltree) != T_Const &&
+ CONVERTABLE_TYPE(rtypeId) && nodeTag(rtree) == T_Const &&
+ !((Const *) rtree)->constiscast)
+ {
+ outfunc = typeid_get_retoutfunc(rtypeId);
+ infunc = typeid_get_retinfunc(ltypeId);
+ outstr = (char *) fmgr(outfunc, ((Const *) rtree)->constvalue);
+ ((Const *) rtree)->constvalue = (Datum) fmgr(infunc, outstr);
+ pfree(outstr);
+ ((Const *) rtree)->consttype = rtypeId = ltypeId;
+ newtype = get_id_type(rtypeId);
+ ((Const *) rtree)->constlen = tlen(newtype);
+ ((Const *) rtree)->constbyval = tbyval(newtype);
+ }
+
+ if (CONVERTABLE_TYPE(rtypeId) && nodeTag(rtree) != T_Const &&
+ CONVERTABLE_TYPE(ltypeId) && nodeTag(ltree) == T_Const &&
+ !((Const *) ltree)->constiscast)
+ {
+ outfunc = typeid_get_retoutfunc(ltypeId);
+ infunc = typeid_get_retinfunc(rtypeId);
+ outstr = (char *) fmgr(outfunc, ((Const *) ltree)->constvalue);
+ ((Const *) ltree)->constvalue = (Datum) fmgr(infunc, outstr);
+ pfree(outstr);
+ ((Const *) ltree)->consttype = ltypeId = rtypeId;
+ newtype = get_id_type(ltypeId);
+ ((Const *) ltree)->constlen = tlen(newtype);
+ ((Const *) ltree)->constbyval = tbyval(newtype);
+ }
+
+ temp = oper(opname, ltypeId, rtypeId, false);
+ opform = (OperatorTupleForm) GETSTRUCT(temp);
+ left = make_operand(opname, ltree, ltypeId, opform->oprleft);
+ right = make_operand(opname, rtree, rtypeId, opform->oprright);
}
- if (CONVERTABLE_TYPE(rtypeId) && nodeTag(rtree) != T_Const &&
- CONVERTABLE_TYPE(ltypeId) && nodeTag(ltree) == T_Const &&
- !((Const *)ltree)->constiscast) {
- outfunc = typeid_get_retoutfunc(ltypeId);
- infunc = typeid_get_retinfunc(rtypeId);
- outstr = (char *)fmgr(outfunc, ((Const *)ltree)->constvalue);
- ((Const *)ltree)->constvalue = (Datum)fmgr(infunc, outstr);
- pfree(outstr);
- ((Const *)ltree)->consttype = ltypeId = rtypeId;
- newtype = get_id_type(ltypeId);
- ((Const *)ltree)->constlen = tlen(newtype);
- ((Const *)ltree)->constbyval = tbyval(newtype);
+ newop = makeOper(oprid(temp), /* opno */
+ InvalidOid,/* opid */
+ opform->oprresult, /* operator result type */
+ 0,
+ NULL);
+
+ result = makeNode(Expr);
+ result->typeOid = opform->oprresult;
+ result->opType = OP_EXPR;
+ result->oper = (Node *) newop;
+
+ if (!left)
+ {
+ result->args = lcons(right, NIL);
+ }
+ else if (!right)
+ {
+ result->args = lcons(left, NIL);
+ }
+ else
+ {
+ result->args = lcons(left, lcons(right, NIL));
}
- temp = oper(opname, ltypeId, rtypeId, false);
- opform = (OperatorTupleForm) GETSTRUCT(temp);
- left = make_operand(opname, ltree, ltypeId, opform->oprleft);
- right = make_operand(opname, rtree, rtypeId, opform->oprright);
- }
-
- newop = makeOper(oprid(temp), /* opno */
- InvalidOid, /* opid */
- opform->oprresult, /* operator result type */
- 0,
- NULL);
-
- result = makeNode(Expr);
- result->typeOid = opform->oprresult;
- result->opType = OP_EXPR;
- result->oper = (Node *)newop;
-
- if (!left) {
- result->args = lcons(right, NIL);
- } else if (!right) {
- result->args = lcons(left, NIL);
- } else {
- result->args = lcons(left, lcons(right, NIL));
- }
-
- return result;
+ return result;
}
Oid
find_atttype(Oid relid, char *attrname)
{
- int attid;
- Oid vartype;
- Relation rd;
-
- rd = heap_open(relid);
- if (!RelationIsValid(rd)) {
- rd = heap_openr(tname(get_id_type(relid)));
+ int attid;
+ Oid vartype;
+ Relation rd;
+
+ rd = heap_open(relid);
if (!RelationIsValid(rd))
- elog(WARN, "cannot compute type of att %s for relid %d",
- attrname, relid);
- }
-
- attid = nf_varattno(rd, attrname);
-
- if (attid == InvalidAttrNumber)
- elog(WARN, "Invalid attribute %s\n", attrname);
-
- vartype = att_typeid(rd , attid);
-
- /*
- * close relation we're done with it now
- */
- heap_close(rd);
-
- return (vartype);
+ {
+ rd = heap_openr(tname(get_id_type(relid)));
+ if (!RelationIsValid(rd))
+ elog(WARN, "cannot compute type of att %s for relid %d",
+ attrname, relid);
+ }
+
+ attid = nf_varattno(rd, attrname);
+
+ if (attid == InvalidAttrNumber)
+ elog(WARN, "Invalid attribute %s\n", attrname);
+
+ vartype = att_typeid(rd, attid);
+
+ /*
+ * close relation we're done with it now
+ */
+ heap_close(rd);
+
+ return (vartype);
}
-Var *
-make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id)
+Var *
+make_var(ParseState * pstate, char *refname, char *attrname, Oid * type_id)
{
- Var *varnode;
- int vnum, attid;
- Oid vartypeid;
- Relation rd;
- RangeTblEntry *rte;
+ Var *varnode;
+ int vnum,
+ attid;
+ Oid vartypeid;
+ Relation rd;
+ RangeTblEntry *rte;
- rte = refnameRangeTableEntry(pstate->p_rtable, refname);
- if (rte == NULL)
- rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE, NULL);
+ rte = refnameRangeTableEntry(pstate->p_rtable, refname);
+ if (rte == NULL)
+ rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE, NULL);
- vnum = refnameRangeTablePosn(pstate->p_rtable, refname);
+ vnum = refnameRangeTablePosn(pstate->p_rtable, refname);
- rd = heap_open(rte->relid);
+ rd = heap_open(rte->relid);
- attid = nf_varattno(rd, attrname);
- if (attid == InvalidAttrNumber)
- elog(WARN, "Invalid attribute %s\n", attrname);
- vartypeid = att_typeid(rd, attid);
+ attid = nf_varattno(rd, attrname);
+ if (attid == InvalidAttrNumber)
+ elog(WARN, "Invalid attribute %s\n", attrname);
+ vartypeid = att_typeid(rd, attid);
- varnode = makeVar(vnum, attid, vartypeid, vnum, attid);
+ varnode = makeVar(vnum, attid, vartypeid, vnum, attid);
- heap_close(rd);
+ heap_close(rd);
- *type_id = vartypeid;
- return varnode;
+ *type_id = vartypeid;
+ return varnode;
}
/*
- * make_array_ref() -- Make an array reference node.
+ * make_array_ref() -- Make an array reference node.
*
- * Array references can hang off of arbitrary nested dot (or
- * function invocation) expressions. This routine takes a
- * tree generated by ParseFunc() and an array index and
- * generates a new array reference tree. We do some simple
- * typechecking to be sure the dereference is valid in the
- * type system, but we don't do any bounds checking here.
+ * Array references can hang off of arbitrary nested dot (or
+ * function invocation) expressions. This routine takes a
+ * tree generated by ParseFunc() and an array index and
+ * generates a new array reference tree. We do some simple
+ * typechecking to be sure the dereference is valid in the
+ * type system, but we don't do any bounds checking here.
*
- * indirection is a list of A_Indices
+ * indirection is a list of A_Indices
*/
-ArrayRef *
-make_array_ref(Node *expr,
- List *indirection)
+ArrayRef *
+make_array_ref(Node * expr,
+ List * indirection)
{
- Oid typearray;
- HeapTuple type_tuple;
- TypeTupleForm type_struct_array, type_struct_element;
- ArrayRef *aref;
- Oid reftype;
- List *upperIndexpr=NIL;
- List *lowerIndexpr=NIL;
-
- typearray = exprType(expr);
-
- type_tuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(typearray),
- 0,0,0);
-
- if (!HeapTupleIsValid(type_tuple))
- elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
- typearray);
-
- /* get the array type struct from the type tuple */
- type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
-
- if (type_struct_array->typelem == InvalidOid) {
- elog(WARN, "make_array_ref: type %s is not an array",
- (Name)&(type_struct_array->typname.data[0]));
- }
-
- /* get the type tuple for the element type */
- type_tuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type_struct_array->typelem),
- 0,0,0);
- if (!HeapTupleIsValid(type_tuple))
- elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
- typearray);
-
- type_struct_element = (TypeTupleForm) GETSTRUCT(type_tuple);
-
- while(indirection!=NIL) {
- A_Indices *ind = lfirst(indirection);
- if (ind->lidx) {
- /* XXX assumes all lower indices non null in this case
- */
- lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
+ Oid typearray;
+ HeapTuple type_tuple;
+ TypeTupleForm type_struct_array,
+ type_struct_element;
+ ArrayRef *aref;
+ Oid reftype;
+ List *upperIndexpr = NIL;
+ List *lowerIndexpr = NIL;
+
+ typearray = exprType(expr);
+
+ type_tuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(typearray),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(type_tuple))
+ elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
+ typearray);
+
+ /* get the array type struct from the type tuple */
+ type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
+
+ if (type_struct_array->typelem == InvalidOid)
+ {
+ elog(WARN, "make_array_ref: type %s is not an array",
+ (Name) & (type_struct_array->typname.data[0]));
+ }
+
+ /* get the type tuple for the element type */
+ type_tuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type_struct_array->typelem),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(type_tuple))
+ elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
+ typearray);
+
+ type_struct_element = (TypeTupleForm) GETSTRUCT(type_tuple);
+
+ while (indirection != NIL)
+ {
+ A_Indices *ind = lfirst(indirection);
+
+ if (ind->lidx)
+ {
+
+ /*
+ * XXX assumes all lower indices non null in this case
+ */
+ lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
+ }
+ upperIndexpr = lappend(upperIndexpr, ind->uidx);
+ indirection = lnext(indirection);
}
- upperIndexpr = lappend(upperIndexpr, ind->uidx);
- indirection = lnext(indirection);
- }
- aref = makeNode(ArrayRef);
- aref->refattrlength = type_struct_array->typlen;
- aref->refelemlength = type_struct_element->typlen;
- aref->refelemtype = type_struct_array->typelem;
- aref->refelembyval = type_struct_element->typbyval;
- aref->refupperindexpr = upperIndexpr;
- aref->reflowerindexpr = lowerIndexpr;
- aref->refexpr = expr;
- aref->refassgnexpr = NULL;
-
- if (lowerIndexpr == NIL) /* accessing a single array element */
- reftype = aref->refelemtype;
- else /* request to clip a part of the array, the result is another array */
- reftype = typearray;
-
- /* we change it to reflect the true type; since the original refelemtype
- * doesn't seem to get used anywhere. - ay 10/94
- */
- aref->refelemtype = reftype;
-
- return aref;
+ aref = makeNode(ArrayRef);
+ aref->refattrlength = type_struct_array->typlen;
+ aref->refelemlength = type_struct_element->typlen;
+ aref->refelemtype = type_struct_array->typelem;
+ aref->refelembyval = type_struct_element->typbyval;
+ aref->refupperindexpr = upperIndexpr;
+ aref->reflowerindexpr = lowerIndexpr;
+ aref->refexpr = expr;
+ aref->refassgnexpr = NULL;
+
+ if (lowerIndexpr == NIL) /* accessing a single array element */
+ reftype = aref->refelemtype;
+ else
+/* request to clip a part of the array, the result is another array */
+ reftype = typearray;
+
+ /*
+ * we change it to reflect the true type; since the original
+ * refelemtype doesn't seem to get used anywhere. - ay 10/94
+ */
+ aref->refelemtype = reftype;
+
+ return aref;
}
-ArrayRef *
-make_array_set(Expr *target_expr,
- List *upperIndexpr,
- List *lowerIndexpr,
- Expr *expr)
+ArrayRef *
+make_array_set(Expr * target_expr,
+ List * upperIndexpr,
+ List * lowerIndexpr,
+ Expr * expr)
{
- Oid typearray;
- HeapTuple type_tuple;
- TypeTupleForm type_struct_array;
- TypeTupleForm type_struct_element;
- ArrayRef *aref;
- Oid reftype;
-
- typearray = exprType((Node*)target_expr);
-
- type_tuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(typearray),
- 0,0,0);
-
- if (!HeapTupleIsValid(type_tuple))
- elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
- typearray);
-
- /* get the array type struct from the type tuple */
- type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
-
- if (type_struct_array->typelem == InvalidOid) {
- elog(WARN, "make_array_ref: type %s is not an array",
- (Name)&(type_struct_array->typname.data[0]));
- }
- /* get the type tuple for the element type */
- type_tuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(type_struct_array->typelem),
- 0,0,0);
-
- if (!HeapTupleIsValid(type_tuple))
- elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
- typearray);
-
- type_struct_element = (TypeTupleForm) GETSTRUCT(type_tuple);
-
- aref = makeNode(ArrayRef);
- aref->refattrlength = type_struct_array->typlen;
- aref->refelemlength = type_struct_element->typlen;
- aref->refelemtype = type_struct_array->typelem;
- aref->refelembyval = type_struct_element->typbyval;
- aref->refupperindexpr = upperIndexpr;
- aref->reflowerindexpr = lowerIndexpr;
- aref->refexpr = (Node*)target_expr;
- aref->refassgnexpr = (Node*)expr;
-
- if (lowerIndexpr == NIL) /* accessing a single array element */
- reftype = aref->refelemtype;
- else /* request to set a part of the array, by another array */
- reftype = typearray;
-
- aref->refelemtype = reftype;
-
- return aref;
+ Oid typearray;
+ HeapTuple type_tuple;
+ TypeTupleForm type_struct_array;
+ TypeTupleForm type_struct_element;
+ ArrayRef *aref;
+ Oid reftype;
+
+ typearray = exprType((Node *) target_expr);
+
+ type_tuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(typearray),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(type_tuple))
+ elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
+ typearray);
+
+ /* get the array type struct from the type tuple */
+ type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
+
+ if (type_struct_array->typelem == InvalidOid)
+ {
+ elog(WARN, "make_array_ref: type %s is not an array",
+ (Name) & (type_struct_array->typname.data[0]));
+ }
+ /* get the type tuple for the element type */
+ type_tuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(type_struct_array->typelem),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(type_tuple))
+ elog(WARN, "make_array_ref: Cache lookup failed for type %d\n",
+ typearray);
+
+ type_struct_element = (TypeTupleForm) GETSTRUCT(type_tuple);
+
+ aref = makeNode(ArrayRef);
+ aref->refattrlength = type_struct_array->typlen;
+ aref->refelemlength = type_struct_element->typlen;
+ aref->refelemtype = type_struct_array->typelem;
+ aref->refelembyval = type_struct_element->typbyval;
+ aref->refupperindexpr = upperIndexpr;
+ aref->reflowerindexpr = lowerIndexpr;
+ aref->refexpr = (Node *) target_expr;
+ aref->refassgnexpr = (Node *) expr;
+
+ if (lowerIndexpr == NIL) /* accessing a single array element */
+ reftype = aref->refelemtype;
+ else
+/* request to set a part of the array, by another array */
+ reftype = typearray;
+
+ aref->refelemtype = reftype;
+
+ return aref;
}
/*
- *
+ *
* make_const -
- *
+ *
* - takes a lispvalue, (as returned to the yacc routine by the lexer)
- * extracts the type, and makes the appropriate type constant
- * by invoking the (c-callable) lisp routine c-make-const
- * via the lisp_call() mechanism
+ * extracts the type, and makes the appropriate type constant
+ * by invoking the (c-callable) lisp routine c-make-const
+ * via the lisp_call() mechanism
*
* eventually, produces a "const" lisp-struct as per nodedefs.cl
- */
-Const *
-make_const(Value *value)
+ */
+Const *
+make_const(Value * value)
{
- Type tp;
- Datum val;
- Const *con;
-
- switch(nodeTag(value)) {
- case T_Integer:
- tp = type("int4");
- val = Int32GetDatum(intVal(value));
- break;
-
- case T_Float:
- {
- float64 dummy;
- tp = type("float8");
-
- dummy = (float64)palloc(sizeof(float64data));
- *dummy = floatVal(value);
-
- val = Float64GetDatum(dummy);
- }
- break;
-
- case T_String:
- tp = type("unknown"); /* unknown for now, will be type coerced */
- val = PointerGetDatum(textin(strVal(value)));
- break;
-
- case T_Null:
- default:
- {
- if (nodeTag(value)!=T_Null)
- elog(NOTICE,"unknown type : %d\n", nodeTag(value));
+ Type tp;
+ Datum val;
+ Const *con;
- /* null const */
- con = makeConst(0, 0, (Datum)NULL, true, false, false, false);
- return con;
+ switch (nodeTag(value))
+ {
+ case T_Integer:
+ tp = type("int4");
+ val = Int32GetDatum(intVal(value));
+ break;
+
+ case T_Float:
+ {
+ float64 dummy;
+
+ tp = type("float8");
+
+ dummy = (float64) palloc(sizeof(float64data));
+ *dummy = floatVal(value);
+
+ val = Float64GetDatum(dummy);
+ }
+ break;
+
+ case T_String:
+ tp = type("unknown"); /* unknown for now, will be type coerced */
+ val = PointerGetDatum(textin(strVal(value)));
+ break;
+
+ case T_Null:
+ default:
+ {
+ if (nodeTag(value) != T_Null)
+ elog(NOTICE, "unknown type : %d\n", nodeTag(value));
+
+ /* null const */
+ con = makeConst(0, 0, (Datum) NULL, true, false, false, false);
+ return con;
+ }
}
- }
- con = makeConst(typeid(tp),
- tlen(tp),
- val,
- false,
- tbyval(tp),
- false, /* not a set */
- false);
+ con = makeConst(typeid(tp),
+ tlen(tp),
+ val,
+ false,
+ tbyval(tp),
+ false, /* not a set */
+ false);
- return (con);
+ return (con);
}
/*
@@ -721,87 +785,93 @@ make_const(Value *value)
* used in postquel functions
*/
void
-param_type_init(Oid* typev, int nargs)
+param_type_init(Oid * typev, int nargs)
{
- pfunc_num_args = nargs;
- param_type_info = typev;
+ pfunc_num_args = nargs;
+ param_type_info = typev;
}
Oid
param_type(int t)
{
- if ((t >pfunc_num_args) ||(t ==0)) return InvalidOid;
- return param_type_info[t-1];
+ if ((t > pfunc_num_args) || (t == 0))
+ return InvalidOid;
+ return param_type_info[t - 1];
}
/*
* handleTargetColname -
- * use column names from insert
+ * use column names from insert
*/
void
-handleTargetColname(ParseState *pstate, char **resname,
+handleTargetColname(ParseState * pstate, char **resname,
char *refname, char *colname)
{
- if (pstate->p_is_insert) {
- if (pstate->p_insert_columns != NIL ) {
- Ident *id = lfirst(pstate->p_insert_columns);
- *resname = id->name;
- pstate->p_insert_columns = lnext(pstate->p_insert_columns);
- }
- else
- elog(WARN, "insert: more expressions than target columns");
- }
- if (pstate->p_is_insert||pstate->p_is_update)
- checkTargetTypes(pstate, *resname, refname, colname);
+ if (pstate->p_is_insert)
+ {
+ if (pstate->p_insert_columns != NIL)
+ {
+ Ident *id = lfirst(pstate->p_insert_columns);
+
+ *resname = id->name;
+ pstate->p_insert_columns = lnext(pstate->p_insert_columns);
+ }
+ else
+ elog(WARN, "insert: more expressions than target columns");
+ }
+ if (pstate->p_is_insert || pstate->p_is_update)
+ checkTargetTypes(pstate, *resname, refname, colname);
}
/*
* checkTargetTypes -
- * checks value and target column types
+ * checks value and target column types
*/
static void
-checkTargetTypes(ParseState *pstate, char *target_colname,
- char *refname, char *colname)
+checkTargetTypes(ParseState * pstate, char *target_colname,
+ char *refname, char *colname)
{
- Oid attrtype_id, attrtype_target;
- int resdomno_id, resdomno_target;
- Relation rd;
- RangeTblEntry *rte;
-
- if (target_colname == NULL || colname == NULL)
- return;
-
- if (refname != NULL)
- rte = refnameRangeTableEntry(pstate->p_rtable, refname);
- else {
- rte = colnameRangeTableEntry(pstate, colname);
- if ( rte == (RangeTblEntry *) NULL )
- elog (WARN, "attribute %s not found", colname);
- refname = rte->refname;
- }
+ Oid attrtype_id,
+ attrtype_target;
+ int resdomno_id,
+ resdomno_target;
+ Relation rd;
+ RangeTblEntry *rte;
+
+ if (target_colname == NULL || colname == NULL)
+ return;
+
+ if (refname != NULL)
+ rte = refnameRangeTableEntry(pstate->p_rtable, refname);
+ else
+ {
+ rte = colnameRangeTableEntry(pstate, colname);
+ if (rte == (RangeTblEntry *) NULL)
+ elog(WARN, "attribute %s not found", colname);
+ refname = rte->refname;
+ }
/*
- if (pstate->p_is_insert && rte == pstate->p_target_rangetblentry)
- elog(WARN, "%s not available in this context", colname);
+ if (pstate->p_is_insert && rte == pstate->p_target_rangetblentry)
+ elog(WARN, "%s not available in this context", colname);
*/
- rd = heap_open(rte->relid);
+ rd = heap_open(rte->relid);
- resdomno_id = varattno(rd,colname);
- attrtype_id = att_typeid(rd,resdomno_id);
+ resdomno_id = varattno(rd, colname);
+ attrtype_id = att_typeid(rd, resdomno_id);
- resdomno_target = varattno(pstate->p_target_relation,target_colname);
- attrtype_target = att_typeid(pstate->p_target_relation, resdomno_target);
+ resdomno_target = varattno(pstate->p_target_relation, target_colname);
+ attrtype_target = att_typeid(pstate->p_target_relation, resdomno_target);
- if (attrtype_id != attrtype_target)
- elog(WARN, "Type of %s does not match target column %s",
- colname, target_colname);
+ if (attrtype_id != attrtype_target)
+ elog(WARN, "Type of %s does not match target column %s",
+ colname, target_colname);
- if ((attrtype_id == BPCHAROID || attrtype_id == VARCHAROID) &&
- rd->rd_att->attrs[resdomno_id-1]->attlen !=
- pstate->p_target_relation->rd_att->attrs[resdomno_target-1]->attlen)
- elog(WARN, "Length of %s does not match length of target column %s",
- colname, target_colname);
+ if ((attrtype_id == BPCHAROID || attrtype_id == VARCHAROID) &&
+ rd->rd_att->attrs[resdomno_id - 1]->attlen !=
+ pstate->p_target_relation->rd_att->attrs[resdomno_target - 1]->attlen)
+ elog(WARN, "Length of %s does not match length of target column %s",
+ colname, target_colname);
- heap_close(rd);
+ heap_close(rd);
}
-
diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c
index ab4276055cd..99c6ce2bfdb 100644
--- a/src/backend/parser/parser.c
+++ b/src/backend/parser/parser.c
@@ -6,14 +6,14 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.22 1997/08/22 07:12:45 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.23 1997/09/07 04:44:50 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <string.h>
#include <stdio.h>
#include <pwd.h>
-#include <sys/param.h> /* for MAXPATHLEN */
+#include <sys/param.h> /* for MAXPATHLEN */
#include "postgres.h"
#include "parser/catalog_utils.h"
@@ -34,456 +34,510 @@
#include "catalog/pg_aggregate.h"
#include "catalog/pg_type.h"
#include "access/heapam.h"
-#include "optimizer/clauses.h"
+#include "optimizer/clauses.h"
-void init_io(); /* from scan.l */
-void parser_init(Oid *typev, int nargs); /* from gram.y */
-int yyparse(); /* from gram.c */
+void init_io(); /* from scan.l */
+void parser_init(Oid * typev, int nargs); /* from gram.y */
+int yyparse(); /* from gram.c */
-char *parseString; /* the char* which holds the string to be parsed */
-char *parseCh; /* a pointer used during parsing to walk down ParseString*/
+char *parseString; /* the char* which holds the string to be
+ * parsed */
+char *parseCh; /* a pointer used during parsing to walk
+ * down ParseString */
-List *parsetree = NIL;
+List *parsetree = NIL;
#ifdef SETS_FIXED
-static void fixupsets();
-static void define_sets();
+static void fixupsets();
+static void define_sets();
+
#endif
/*
* parser-- returns a list of parse trees
- *
- * CALLER is responsible for free'ing the list returned
+ *
+ * CALLER is responsible for free'ing the list returned
*/
-QueryTreeList *
-parser(char *str, Oid *typev, int nargs)
+QueryTreeList *
+parser(char *str, Oid * typev, int nargs)
{
- QueryTreeList* queryList;
- int yyresult;
+ QueryTreeList *queryList;
+ int yyresult;
#if defined(FLEX_SCANNER)
- extern void DeleteBuffer(void);
-#endif /* FLEX_SCANNER */
-
- init_io();
-
- /* Set things up to read from the string, if there is one */
- parseString = (char *) palloc(strlen(str) + 1);
- memmove(parseString,str,strlen(str)+1);
-
- parser_init(typev, nargs);
- yyresult = yyparse();
+ extern void DeleteBuffer(void);
+
+#endif /* FLEX_SCANNER */
+
+ init_io();
+
+ /* Set things up to read from the string, if there is one */
+ parseString = (char *) palloc(strlen(str) + 1);
+ memmove(parseString, str, strlen(str) + 1);
+
+ parser_init(typev, nargs);
+ yyresult = yyparse();
#if defined(FLEX_SCANNER)
- DeleteBuffer();
-#endif /* FLEX_SCANNER */
-
- clearerr(stdin);
-
- if (yyresult) { /* error */
- return((QueryTreeList*)NULL);
- }
-
- queryList = parse_analyze(parsetree);
-
+ DeleteBuffer();
+#endif /* FLEX_SCANNER */
+
+ clearerr(stdin);
+
+ if (yyresult)
+ { /* error */
+ return ((QueryTreeList *) NULL);
+ }
+
+ queryList = parse_analyze(parsetree);
+
#ifdef SETS_FIXED
- /* Fixing up sets calls the parser, so it reassigns the global
- * variable parsetree. So save the real parsetree.
- */
- savetree = parsetree;
- foreach (parse, savetree) { /* savetree is really a list of parses */
- /* find set definitions embedded in query */
- fixupsets((Query *)lfirst(parse));
+ /*
+ * Fixing up sets calls the parser, so it reassigns the global
+ * variable parsetree. So save the real parsetree.
+ */
+ savetree = parsetree;
+ foreach(parse, savetree)
+ { /* savetree is really a list of parses */
+
+ /* find set definitions embedded in query */
+ fixupsets((Query *) lfirst(parse));
- }
- return savetree;
-#endif
+ }
+ return savetree;
+#endif
- return queryList;
+ return queryList;
}
#ifdef SETS_FIXED
static void
-fixupsets(Query *parse)
+fixupsets(Query * parse)
{
- if (parse == NULL)
- return;
- if (parse->commandType==CMD_UTILITY) /* utility */
- return;
- if (parse->commandType!=CMD_INSERT)
- return;
- define_sets(parse);
+ if (parse == NULL)
+ return;
+ if (parse->commandType == CMD_UTILITY) /* utility */
+ return;
+ if (parse->commandType != CMD_INSERT)
+ return;
+ define_sets(parse);
}
/* Recursively find all of the Consts in the parsetree. Some of
* these may represent a set. The value of the Const will be the
- * query (a string) which defines the set. Call SetDefine to define
+ * query (a string) which defines the set. Call SetDefine to define
* the set, and store the OID of the new set in the Const instead.
*/
static void
-define_sets(Node *clause)
+define_sets(Node * clause)
{
- Oid setoid;
- Type t = type("oid");
- Oid typeoid = typeid(t);
- Size oidsize = tlen(t);
- bool oidbyval = tbyval(t);
-
- if (clause==NULL) {
- return;
- } else if (IsA(clause,LispList)) {
- define_sets(lfirst(clause));
- define_sets(lnext(clause));
- } else if (IsA(clause,Const)) {
- if (get_constisnull((Const)clause) ||
- !get_constisset((Const)clause)) {
- return;
+ Oid setoid;
+ Type t = type("oid");
+ Oid typeoid = typeid(t);
+ Size oidsize = tlen(t);
+ bool oidbyval = tbyval(t);
+
+ if (clause == NULL)
+ {
+ return;
+ }
+ else if (IsA(clause, LispList))
+ {
+ define_sets(lfirst(clause));
+ define_sets(lnext(clause));
+ }
+ else if (IsA(clause, Const))
+ {
+ if (get_constisnull((Const) clause) ||
+ !get_constisset((Const) clause))
+ {
+ return;
+ }
+ setoid = SetDefine(((Const *) clause)->constvalue,
+ get_id_typname(((Const *) clause)->consttype));
+ set_constvalue((Const) clause, setoid);
+ set_consttype((Const) clause, typeoid);
+ set_constlen((Const) clause, oidsize);
+ set_constbyval((Const) clause, oidbyval);
+ }
+ else if (IsA(clause, Iter))
+ {
+ define_sets(((Iter *) clause)->iterexpr);
+ }
+ else if (single_node(clause))
+ {
+ return;
+ }
+ else if (or_clause(clause))
+ {
+ List *temp;
+
+ /* mapcan */
+ foreach(temp, ((Expr *) clause)->args)
+ {
+ define_sets(lfirst(temp));
+ }
}
- setoid = SetDefine(((Const*)clause)->constvalue,
- get_id_typname(((Const*)clause)->consttype));
- set_constvalue((Const)clause, setoid);
- set_consttype((Const)clause,typeoid);
- set_constlen((Const)clause,oidsize);
- set_constbyval((Const)clause,oidbyval);
- } else if ( IsA(clause,Iter) ) {
- define_sets(((Iter*)clause)->iterexpr);
- } else if (single_node (clause)) {
- return;
- } else if (or_clause(clause)) {
- List *temp;
- /* mapcan */
- foreach (temp, ((Expr*)clause)->args) {
- define_sets(lfirst(temp));
+ else if (is_funcclause(clause))
+ {
+ List *temp;
+
+ /* mapcan */
+ foreach(temp, ((Expr *) clause)->args)
+ {
+ define_sets(lfirst(temp));
+ }
}
- } else if (is_funcclause (clause)) {
- List *temp;
- /* mapcan */
- foreach(temp, ((Expr*)clause)->args) {
- define_sets(lfirst(temp));
+ else if (IsA(clause, ArrayRef))
+ {
+ define_sets(((ArrayRef *) clause)->refassgnexpr);
+ }
+ else if (not_clause(clause))
+ {
+ define_sets(get_notclausearg(clause));
+ }
+ else if (is_opclause(clause))
+ {
+ define_sets(get_leftop(clause));
+ define_sets(get_rightop(clause));
}
- } else if (IsA(clause,ArrayRef)) {
- define_sets(((ArrayRef*)clause)->refassgnexpr);
- } else if (not_clause (clause)) {
- define_sets (get_notclausearg (clause));
- } else if (is_opclause (clause)) {
- define_sets(get_leftop (clause));
- define_sets(get_rightop (clause));
- }
}
+
#endif
/* not used
-#define PSIZE(PTR) (*((int32 *)(PTR) - 1))
+#define PSIZE(PTR) (*((int32 *)(PTR) - 1))
*/
-Node *
-parser_typecast(Value *expr, TypeName *typename, int typlen)
+Node *
+parser_typecast(Value * expr, TypeName * typename, int typlen)
{
- /* check for passing non-ints */
- Const *adt;
- Datum lcp;
- Type tp;
- char type_string[16];
- int32 len;
- char *cp = NULL;
- char *const_string = NULL;
- bool string_palloced = false;
-
- switch(nodeTag(expr)) {
- case T_String:
- const_string = DatumGetPointer(expr->val.str);
- break;
- case T_Integer:
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string, "%d", expr->val.ival);
- break;
- default:
- elog(WARN,
- "parser_typecast: cannot cast this expression to type \"%s\"",
- typename->name);
- }
-
- if (typename->arrayBounds != NIL) {
- sprintf(type_string,"_%s", typename->name);
- tp = (Type) type(type_string);
- } else {
- tp = (Type) type(typename->name);
- }
-
- len = tlen(tp);
-
-#if 0 /* fix me */
- switch ( CInteger(lfirst(expr)) ) {
- case INT4OID: /* int4 */
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%d", ((Const*)lnext(expr))->constvalue);
- break;
-
- case NAMEOID: /* char16 */
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%s", ((Const*)lnext(expr))->constvalue);
- break;
-
- case CHAROID: /* char */
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%c", ((Const)lnext(expr))->constvalue);
- break;
-
- case FLOAT8OID:/* float8 */
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%f", ((Const)lnext(expr))->constvalue);
- break;
-
- case CASHOID: /* money */
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%d",
- (int) ((Const*)expr)->constvalue);
- break;
-
- case TEXTOID: /* text */
- const_string = DatumGetPointer(((Const)lnext(expr))->constvalue);
- const_string = (char *) textout((struct varlena *)const_string);
- break;
-
- case UNKNOWNOID: /* unknown */
- const_string = DatumGetPointer(((Const)lnext(expr))->constvalue);
- const_string = (char *) textout((struct varlena *)const_string);
- break;
-
- default:
- elog(WARN,"unknown type %d", CInteger(lfirst(expr)));
- }
+ /* check for passing non-ints */
+ Const *adt;
+ Datum lcp;
+ Type tp;
+ char type_string[16];
+ int32 len;
+ char *cp = NULL;
+ char *const_string = NULL;
+ bool string_palloced = false;
+
+ switch (nodeTag(expr))
+ {
+ case T_String:
+ const_string = DatumGetPointer(expr->val.str);
+ break;
+ case T_Integer:
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%d", expr->val.ival);
+ break;
+ default:
+ elog(WARN,
+ "parser_typecast: cannot cast this expression to type \"%s\"",
+ typename->name);
+ }
+
+ if (typename->arrayBounds != NIL)
+ {
+ sprintf(type_string, "_%s", typename->name);
+ tp = (Type) type(type_string);
+ }
+ else
+ {
+ tp = (Type) type(typename->name);
+ }
+
+ len = tlen(tp);
+
+#if 0 /* fix me */
+ switch (CInteger(lfirst(expr)))
+ {
+ case INT4OID: /* int4 */
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%d", ((Const *) lnext(expr))->constvalue);
+ break;
+
+ case NAMEOID: /* char16 */
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%s", ((Const *) lnext(expr))->constvalue);
+ break;
+
+ case CHAROID: /* char */
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%c", ((Const) lnext(expr))->constvalue);
+ break;
+
+ case FLOAT8OID: /* float8 */
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%f", ((Const) lnext(expr))->constvalue);
+ break;
+
+ case CASHOID: /* money */
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%d",
+ (int) ((Const *) expr)->constvalue);
+ break;
+
+ case TEXTOID: /* text */
+ const_string = DatumGetPointer(((Const) lnext(expr))->constvalue);
+ const_string = (char *) textout((struct varlena *) const_string);
+ break;
+
+ case UNKNOWNOID: /* unknown */
+ const_string = DatumGetPointer(((Const) lnext(expr))->constvalue);
+ const_string = (char *) textout((struct varlena *) const_string);
+ break;
+
+ default:
+ elog(WARN, "unknown type %d", CInteger(lfirst(expr)));
+ }
#endif
- cp = instr2 (tp, const_string, typlen);
-
- if (!tbyvalue(tp)) {
+ cp = instr2(tp, const_string, typlen);
+
+ if (!tbyvalue(tp))
+ {
/*
- if (len >= 0 && len != PSIZE(cp)) {
- char *pp;
- pp = (char *) palloc(len);
- memmove(pp, cp, len);
- cp = pp;
- }
+ if (len >= 0 && len != PSIZE(cp)) {
+ char *pp;
+ pp = (char *) palloc(len);
+ memmove(pp, cp, len);
+ cp = pp;
+ }
*/
- lcp = PointerGetDatum(cp);
- } else {
- switch(len) {
- case 1:
- lcp = Int8GetDatum(cp);
- break;
- case 2:
- lcp = Int16GetDatum(cp);
- break;
- case 4:
- lcp = Int32GetDatum(cp);
- break;
- default:
- lcp = PointerGetDatum(cp);
- break;
+ lcp = PointerGetDatum(cp);
+ }
+ else
+ {
+ switch (len)
+ {
+ case 1:
+ lcp = Int8GetDatum(cp);
+ break;
+ case 2:
+ lcp = Int16GetDatum(cp);
+ break;
+ case 4:
+ lcp = Int32GetDatum(cp);
+ break;
+ default:
+ lcp = PointerGetDatum(cp);
+ break;
+ }
}
- }
-
- adt = makeConst(typeid(tp),
- len,
- (Datum)lcp ,
- false,
- tbyvalue(tp),
- false, /* not a set */
- true /* is cast */);
-
- if (string_palloced)
- pfree(const_string);
-
- return (Node*)adt;
+
+ adt = makeConst(typeid(tp),
+ len,
+ (Datum) lcp,
+ false,
+ tbyvalue(tp),
+ false, /* not a set */
+ true /* is cast */ );
+
+ if (string_palloced)
+ pfree(const_string);
+
+ return (Node *) adt;
}
-Node *
-parser_typecast2(Node *expr, Oid exprType, Type tp, int typlen)
+Node *
+parser_typecast2(Node * expr, Oid exprType, Type tp, int typlen)
{
- /* check for passing non-ints */
- Const *adt;
- Datum lcp;
- int32 len = tlen(tp);
- char *cp = NULL;
-
- char *const_string = NULL;
- bool string_palloced = false;
-
- Assert(IsA(expr,Const));
-
- switch (exprType) {
- case 0: /* NULL */
- break;
- case INT4OID: /* int4 */
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%d",
- (int) ((Const*)expr)->constvalue);
- break;
- case NAMEOID: /* char16 */
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%s",
- (char*) ((Const*)expr)->constvalue);
- break;
- case CHAROID: /* char */
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%c",
- (char) ((Const*)expr)->constvalue);
- break;
- case FLOAT4OID: /* float4 */
+ /* check for passing non-ints */
+ Const *adt;
+ Datum lcp;
+ int32 len = tlen(tp);
+ char *cp = NULL;
+
+ char *const_string = NULL;
+ bool string_palloced = false;
+
+ Assert(IsA(expr, Const));
+
+ switch (exprType)
{
- float32 floatVal =
- DatumGetFloat32(((Const*)expr)->constvalue);
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%f", *floatVal);
- break;
+ case 0: /* NULL */
+ break;
+ case INT4OID: /* int4 */
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%d",
+ (int) ((Const *) expr)->constvalue);
+ break;
+ case NAMEOID: /* char16 */
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%s",
+ (char *) ((Const *) expr)->constvalue);
+ break;
+ case CHAROID: /* char */
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%c",
+ (char) ((Const *) expr)->constvalue);
+ break;
+ case FLOAT4OID: /* float4 */
+ {
+ float32 floatVal =
+ DatumGetFloat32(((Const *) expr)->constvalue);
+
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%f", *floatVal);
+ break;
+ }
+ case FLOAT8OID: /* float8 */
+ {
+ float64 floatVal =
+ DatumGetFloat64(((Const *) expr)->constvalue);
+
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%f", *floatVal);
+ break;
+ }
+ case CASHOID: /* money */
+ const_string = (char *) palloc(256);
+ string_palloced = true;
+ sprintf(const_string, "%d",
+ (long) ((Const *) expr)->constvalue);
+ break;
+ case TEXTOID: /* text */
+ const_string =
+ DatumGetPointer(((Const *) expr)->constvalue);
+ const_string = (char *) textout((struct varlena *) const_string);
+ break;
+ case UNKNOWNOID: /* unknown */
+ const_string =
+ DatumGetPointer(((Const *) expr)->constvalue);
+ const_string = (char *) textout((struct varlena *) const_string);
+ break;
+ default:
+ elog(WARN, "unknown type %u ", exprType);
}
- case FLOAT8OID:/* float8 */
+
+ if (!exprType)
{
- float64 floatVal =
- DatumGetFloat64(((Const*)expr)->constvalue);
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%f", *floatVal);
- break;
+ adt = makeConst(typeid(tp),
+ (Size) 0,
+ (Datum) NULL,
+ true, /* isnull */
+ false, /* was omitted */
+ false, /* not a set */
+ true /* is cast */ );
+ return ((Node *) adt);
}
- case CASHOID: /* money */
- const_string = (char *) palloc(256);
- string_palloced = true;
- sprintf(const_string,"%d",
- (long) ((Const*)expr)->constvalue);
- break;
- case TEXTOID: /* text */
- const_string =
- DatumGetPointer(((Const*)expr)->constvalue );
- const_string = (char *) textout((struct varlena *)const_string);
- break;
- case UNKNOWNOID: /* unknown */
- const_string =
- DatumGetPointer(((Const*)expr)->constvalue );
- const_string = (char *) textout((struct varlena *)const_string);
- break;
- default:
- elog(WARN,"unknown type %u ",exprType);
- }
-
- if (!exprType) {
- adt = makeConst(typeid(tp),
- (Size) 0,
- (Datum) NULL,
- true, /* isnull */
- false, /* was omitted */
- false, /* not a set */
- true /* is cast */);
- return ((Node*) adt);
- }
-
- cp = instr2 (tp, const_string, typlen);
-
-
- if (!tbyvalue(tp)) {
+
+ cp = instr2(tp, const_string, typlen);
+
+
+ if (!tbyvalue(tp))
+ {
/*
- if (len >= 0 && len != PSIZE(cp)) {
- char *pp;
- pp = (char *) palloc(len);
- memmove(pp, cp, len);
- cp = pp;
- }
+ if (len >= 0 && len != PSIZE(cp)) {
+ char *pp;
+ pp = (char *) palloc(len);
+ memmove(pp, cp, len);
+ cp = pp;
+ }
*/
- lcp = PointerGetDatum(cp);
- } else {
- switch(len) {
- case 1:
- lcp = Int8GetDatum(cp);
- break;
- case 2:
- lcp = Int16GetDatum(cp);
- break;
- case 4:
- lcp = Int32GetDatum(cp);
- break;
- default:
- lcp = PointerGetDatum(cp);
- break;
+ lcp = PointerGetDatum(cp);
+ }
+ else
+ {
+ switch (len)
+ {
+ case 1:
+ lcp = Int8GetDatum(cp);
+ break;
+ case 2:
+ lcp = Int16GetDatum(cp);
+ break;
+ case 4:
+ lcp = Int32GetDatum(cp);
+ break;
+ default:
+ lcp = PointerGetDatum(cp);
+ break;
+ }
}
- }
-
- adt = makeConst(typeid(tp),
- (Size)len,
- (Datum)lcp,
- false,
- false, /*was omitted*/
- false, /* not a set */
- true /* is cast */);
- /*
- printf("adt %s : %u %d %d\n",CString(expr),typeid(tp) ,
- len,cp);
- */
- if (string_palloced) pfree(const_string);
-
- return ((Node*) adt);
+
+ adt = makeConst(typeid(tp),
+ (Size) len,
+ (Datum) lcp,
+ false,
+ false, /* was omitted */
+ false, /* not a set */
+ true /* is cast */ );
+
+ /*
+ * printf("adt %s : %u %d %d\n",CString(expr),typeid(tp) , len,cp);
+ */
+ if (string_palloced)
+ pfree(const_string);
+
+ return ((Node *) adt);
}
-Aggreg *
-ParseAgg(char *aggname, Oid basetype, Node *target)
+Aggreg *
+ParseAgg(char *aggname, Oid basetype, Node * target)
{
- Oid fintype;
- Oid vartype;
- Oid xfn1;
- Form_pg_aggregate aggform;
- Aggreg *aggreg;
- HeapTuple theAggTuple;
-
- theAggTuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggname),
- ObjectIdGetDatum(basetype),
- 0, 0);
- if (!HeapTupleIsValid(theAggTuple)) {
- elog(WARN, "aggregate %s does not exist", aggname);
- }
-
- aggform = (Form_pg_aggregate) GETSTRUCT(theAggTuple);
- fintype = aggform->aggfinaltype;
- xfn1 = aggform->aggtransfn1;
-
- if (nodeTag(target) != T_Var && nodeTag(target) != T_Expr)
- elog(WARN, "parser: aggregate can only be applied on an attribute or expression");
-
- /* only aggregates with transfn1 need a base type */
- if (OidIsValid(xfn1)) {
- basetype = aggform->aggbasetype;
- if (nodeTag(target) == T_Var)
- vartype = ((Var*)target)->vartype;
- else
- vartype = ((Expr*)target)->typeOid;
-
- if (basetype != vartype) {
- Type tp1, tp2;
-
- tp1 = get_id_type(basetype);
- tp2 = get_id_type(vartype);
- elog(NOTICE, "Aggregate type mismatch:");
- elog(WARN, "%s works on %s, not %s", aggname,
- tname(tp1), tname(tp2));
- }
- }
-
- aggreg = makeNode(Aggreg);
- aggreg->aggname = pstrdup(aggname);
- aggreg->basetype = aggform->aggbasetype;
- aggreg->aggtype = fintype;
-
- aggreg->target = target;
-
- return aggreg;
-}
+ Oid fintype;
+ Oid vartype;
+ Oid xfn1;
+ Form_pg_aggregate aggform;
+ Aggreg *aggreg;
+ HeapTuple theAggTuple;
+ theAggTuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggname),
+ ObjectIdGetDatum(basetype),
+ 0, 0);
+ if (!HeapTupleIsValid(theAggTuple))
+ {
+ elog(WARN, "aggregate %s does not exist", aggname);
+ }
+
+ aggform = (Form_pg_aggregate) GETSTRUCT(theAggTuple);
+ fintype = aggform->aggfinaltype;
+ xfn1 = aggform->aggtransfn1;
+
+ if (nodeTag(target) != T_Var && nodeTag(target) != T_Expr)
+ elog(WARN, "parser: aggregate can only be applied on an attribute or expression");
+
+ /* only aggregates with transfn1 need a base type */
+ if (OidIsValid(xfn1))
+ {
+ basetype = aggform->aggbasetype;
+ if (nodeTag(target) == T_Var)
+ vartype = ((Var *) target)->vartype;
+ else
+ vartype = ((Expr *) target)->typeOid;
+
+ if (basetype != vartype)
+ {
+ Type tp1,
+ tp2;
+
+ tp1 = get_id_type(basetype);
+ tp2 = get_id_type(vartype);
+ elog(NOTICE, "Aggregate type mismatch:");
+ elog(WARN, "%s works on %s, not %s", aggname,
+ tname(tp1), tname(tp2));
+ }
+ }
+
+ aggreg = makeNode(Aggreg);
+ aggreg->aggname = pstrdup(aggname);
+ aggreg->basetype = aggform->aggbasetype;
+ aggreg->aggtype = fintype;
+
+ aggreg->target = target;
+
+ return aggreg;
+}
diff --git a/src/backend/parser/scansup.c b/src/backend/parser/scansup.c
index 98bf6dba93b..0b944528980 100644
--- a/src/backend/parser/scansup.c
+++ b/src/backend/parser/scansup.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* scansup.c--
- * support routines for the lex/flex scanner, used by both the normal
+ * support routines for the lex/flex scanner, used by both the normal
* backend as well as the bootstrap backend
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/scansup.c,v 1.5 1996/11/15 18:38:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/scansup.c,v 1.6 1997/09/07 04:44:51 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,12 +24,12 @@
#include "parser/scansup.h"
/* ----------------
- * scanstr
- *
+ * scanstr
+ *
* if the string passed in has escaped codes, map the escape codes to actual
* chars
*
- * also, remove leading and ending quotes '"' if any
+ * also, remove leading and ending quotes '"' if any
*
* the string passed in must be non-null
*
@@ -38,88 +38,95 @@
* ----------------
*/
-char*
+char *
scanstr(char *s)
{
- static char newStr[MAX_PARSE_BUFFER];
- int len, i, j;
-
- if (s == NULL || s[0] == '\0')
- return s;
+ static char newStr[MAX_PARSE_BUFFER];
+ int len,
+ i,
+ j;
- len = strlen(s);
+ if (s == NULL || s[0] == '\0')
+ return s;
- for (i = 0, j = 0; i < len ; i++) {
- if (s[i] == '\'') {
- i = i + 1;
- if (s[i] == '\'')
- newStr[j] = '\'';
- }
- else {
- if (s[i] == '\\') {
- i = i + 1;
- switch (s[i]) {
- case '\\':
- newStr[j] = '\\';
- break;
- case 'b':
- newStr[j] = '\b';
- break;
- case 'f':
- newStr[j] = '\f';
- break;
- case 'n':
- newStr[j] = '\n';
- break;
- case 'r':
- newStr[j] = '\r';
- break;
- case 't':
- newStr[j] = '\t';
- break;
- case '"':
- newStr[j] = '"';
- break;
- case '\'':
- newStr[j] = '\'';
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- {
- char octal[4];
- int k;
- long octVal;
+ len = strlen(s);
+
+ for (i = 0, j = 0; i < len; i++)
+ {
+ if (s[i] == '\'')
+ {
+ i = i + 1;
+ if (s[i] == '\'')
+ newStr[j] = '\'';
+ }
+ else
+ {
+ if (s[i] == '\\')
+ {
+ i = i + 1;
+ switch (s[i])
+ {
+ case '\\':
+ newStr[j] = '\\';
+ break;
+ case 'b':
+ newStr[j] = '\b';
+ break;
+ case 'f':
+ newStr[j] = '\f';
+ break;
+ case 'n':
+ newStr[j] = '\n';
+ break;
+ case 'r':
+ newStr[j] = '\r';
+ break;
+ case 't':
+ newStr[j] = '\t';
+ break;
+ case '"':
+ newStr[j] = '"';
+ break;
+ case '\'':
+ newStr[j] = '\'';
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ {
+ char octal[4];
+ int k;
+ long octVal;
- for (k=0;
- s[i+k] >= '0' && s[i+k] <= '7' && k < 3;
- k++)
- octal[k] = s[i+k];
- i += k-1;
- octal[3] = '\0';
-
- octVal = strtol(octal,0,8);
-/* elog (NOTICE, "octal = %s octVal = %d, %od", octal, octVal, octVal);*/
- if (octVal <= 0377) {
- newStr[j] = ((char)octVal);
- break;
- }
- }
- default:
- newStr[j] = s[i];
- } /* switch */
- } /* s[i] == '\\' */
- else
- newStr[j] = s[i];
+ for (k = 0;
+ s[i + k] >= '0' && s[i + k] <= '7' && k < 3;
+ k++)
+ octal[k] = s[i + k];
+ i += k - 1;
+ octal[3] = '\0';
+
+ octVal = strtol(octal, 0, 8);
+/* elog (NOTICE, "octal = %s octVal = %d, %od", octal, octVal, octVal);*/
+ if (octVal <= 0377)
+ {
+ newStr[j] = ((char) octVal);
+ break;
+ }
+ }
+ default:
+ newStr[j] = s[i];
+ } /* switch */
+ } /* s[i] == '\\' */
+ else
+ newStr[j] = s[i];
+ }
+ j++;
}
- j++;
- }
- newStr[j] = '\0';
- return newStr;
+ newStr[j] = '\0';
+ return newStr;
}
-
diff --git a/src/backend/parser/sysfunc.c b/src/backend/parser/sysfunc.c
index fac1b60fd5a..02d6d6b21a7 100644
--- a/src/backend/parser/sysfunc.c
+++ b/src/backend/parser/sysfunc.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
- *
+ *
* sysfunc.c--
- * process system functions and return a string result
- *
+ * process system functions and return a string result
+ *
* Notes:
* 1) I return a string result because most of the functions cannot return any
- * normal type anyway (e.g. SYS_DATE, SYS_TIME, etc...), and the few that
- * might (SYS_UID or whatever) can just return it as a string - no problem.
- * This keeps the function flexible enough to be of good use.
- *
+ * normal type anyway (e.g. SYS_DATE, SYS_TIME, etc...), and the few that
+ * might (SYS_UID or whatever) can just return it as a string - no problem.
+ * This keeps the function flexible enough to be of good use.
+ *
* Written by Chad Robinson, chadr@brttech.com
* Last modified: 04/27/1996
* -------------------------------------------------------------------------
@@ -27,39 +27,42 @@
* Can't get much more obvious than this. Might need to replace localtime()
* on older systems...
*/
-static char *Sysfunc_system_date(void)
+static char *
+Sysfunc_system_date(void)
{
- time_t cur_time_secs;
- struct tm *cur_time_expanded;
- static char buf[12]; /* Just for safety, y'understand... */
-
+ time_t cur_time_secs;
+ struct tm *cur_time_expanded;
+ static char buf[12]; /* Just for safety, y'understand... */
+
time(&cur_time_secs);
cur_time_expanded = localtime(&cur_time_secs);
if (EuroDates == 1)
sprintf(buf, "%2.2d-%2.2d-%4.4d", cur_time_expanded->tm_mday,
- cur_time_expanded->tm_mon+1, cur_time_expanded->tm_year+1900);
+ cur_time_expanded->tm_mon + 1, cur_time_expanded->tm_year + 1900);
else
- sprintf(buf, "%2.2d-%2.2d-%4.4d", cur_time_expanded->tm_mon+1,
- cur_time_expanded->tm_mday, cur_time_expanded->tm_year+1900);
+ sprintf(buf, "%2.2d-%2.2d-%4.4d", cur_time_expanded->tm_mon + 1,
+ cur_time_expanded->tm_mday, cur_time_expanded->tm_year + 1900);
return &buf[0];
}
-static char *Sysfunc_system_time(void)
+static char *
+Sysfunc_system_time(void)
{
- time_t cur_time_secs;
- struct tm *cur_time_expanded;
- static char buf[10]; /* Just for safety, y'understand... */
-
+ time_t cur_time_secs;
+ struct tm *cur_time_expanded;
+ static char buf[10]; /* Just for safety, y'understand... */
+
time(&cur_time_secs);
cur_time_expanded = localtime(&cur_time_secs);
sprintf(buf, "%2.2d:%2.2d:%2.2d", cur_time_expanded->tm_hour,
- cur_time_expanded->tm_min, cur_time_expanded->tm_sec);
+ cur_time_expanded->tm_min, cur_time_expanded->tm_sec);
return &buf[0];
}
-char *SystemFunctionHandler(char *funct)
+char *
+SystemFunctionHandler(char *funct)
{
if (!strcmp(funct, "SYS_DATE"))
return Sysfunc_system_date();
@@ -73,9 +76,11 @@ char *SystemFunctionHandler(char *funct)
* Chad's rule of coding #4 - never delete a test function, even a stupid
* one - you always need it 10 minutes after you delete it.
*/
-void main(void)
+void
+main(void)
{
printf("Current system date: %s\n", SystemFunctionHandler("SYS_DATE"));
return;
}
+
#endif
diff --git a/src/backend/port/BSD44_derived/dl.c b/src/backend/port/BSD44_derived/dl.c
index 0a6525c8ac8..091507204b4 100644
--- a/src/backend/port/BSD44_derived/dl.c
+++ b/src/backend/port/BSD44_derived/dl.c
@@ -6,22 +6,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -32,8 +32,9 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)dl.c 5.4 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
+static char sccsid[] = "@(#)dl.c 5.4 (Berkeley) 2/23/91";
+
+#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <nlist.h>
@@ -45,52 +46,55 @@ static char sccsid[] = "@(#)dl.c 5.4 (Berkeley) 2/23/91";
#include "port-protos.h"
-static char error_message[BUFSIZ];
+static char error_message[BUFSIZ];
-char *
+char *
BSD44_derived_dlerror(void)
{
- static char ret[BUFSIZ];
+ static char ret[BUFSIZ];
strcpy(ret, error_message);
error_message[0] = 0;
- return((ret[0] == 0) ? (char *) NULL : ret);
+ return ((ret[0] == 0) ? (char *) NULL : ret);
}
-void *
+void *
BSD44_derived_dlopen(const char *file, int num)
{
#ifdef __mips__
- sprintf(error_message, "dlopen (%s) not supported", file);
+ sprintf(error_message, "dlopen (%s) not supported", file);
return NULL;
#else
- void *vp;
+ void *vp;
- if ((vp = dlopen((char *) file, num)) == (void *) NULL) {
+ if ((vp = dlopen((char *) file, num)) == (void *) NULL)
+ {
sprintf(error_message, "dlopen (%s) failed", file);
}
- return(vp);
+ return (vp);
#endif
}
-void *
+void *
BSD44_derived_dlsym(void *handle, const char *name)
{
#ifdef __mips__
sprintf(error_message, "dlsym (%s) failed", name);
return NULL;
#else
- void *vp;
- char buf[BUFSIZ];
+ void *vp;
+ char buf[BUFSIZ];
- if (*name != '_') {
+ if (*name != '_')
+ {
sprintf(buf, "_%s", name);
name = buf;
}
- if ((vp = dlsym(handle, (char *) name)) == (void *) NULL) {
+ if ((vp = dlsym(handle, (char *) name)) == (void *) NULL)
+ {
sprintf(error_message, "dlsym (%s) failed", name);
}
- return(vp);
+ return (vp);
#endif
}
diff --git a/src/backend/port/BSD44_derived/port-protos.h b/src/backend/port/BSD44_derived/port-protos.h
index e1f52bbdd63..2452355d29d 100644
--- a/src/backend/port/BSD44_derived/port-protos.h
+++ b/src/backend/port/BSD44_derived/port-protos.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for NetBSD 1.0
+ * port-specific prototypes for NetBSD 1.0
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.6 1997/03/19 03:56:50 scrappy Exp $
+ * $Id: port-protos.h,v 1.7 1997/09/07 04:45:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,14 +19,14 @@
#include "postgres.h"
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
/* dynloader.c */
/*
* Dynamic Loader on NetBSD 1.0.
*
- * this dynamic loader uses the system dynamic loading interface for shared
+ * this dynamic loader uses the system dynamic loading interface for shared
* libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared
* library as the file to be dynamically loaded.
*
@@ -35,14 +35,14 @@
* begin with an underscore is fairly tricky, and some versions of
* NetBSD (like 1.0, and 1.0A pre June 1995) have no dlerror.)
*/
-# define pg_dlopen(f) BSD44_derived_dlopen(f, 1)
-# define pg_dlsym BSD44_derived_dlsym
-# define pg_dlclose BSD44_derived_dlclose
-# define pg_dlerror BSD44_derived_dlerror
+#define pg_dlopen(f) BSD44_derived_dlopen(f, 1)
+#define pg_dlsym BSD44_derived_dlsym
+#define pg_dlclose BSD44_derived_dlclose
+#define pg_dlerror BSD44_derived_dlerror
-char * BSD44_derived_dlerror(void);
-void * BSD44_derived_dlopen(const char *filename, int num);
-void * BSD44_derived_dlsym(void *handle, const char *name);
-void BSD44_derived_dlclose(void *handle);
+char *BSD44_derived_dlerror(void);
+void *BSD44_derived_dlopen(const char *filename, int num);
+void *BSD44_derived_dlsym(void *handle, const char *name);
+void BSD44_derived_dlclose(void *handle);
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/aix/dlfcn.c b/src/backend/port/aix/dlfcn.c
index 4e95271e098..58a3dea3c12 100644
--- a/src/backend/port/aix/dlfcn.c
+++ b/src/backend/port/aix/dlfcn.c
@@ -22,33 +22,36 @@
* address.
*/
-typedef struct {
- char *name; /* the symbols's name */
- void *addr; /* its relocated virtual address */
-} Export, *ExportPtr;
+typedef struct
+{
+ char *name; /* the symbols's name */
+ void *addr; /* its relocated virtual address */
+} Export, *ExportPtr;
/*
* xlC uses the following structure to list its constructors and
* destructors. This is gleaned from the output of munch.
*/
-typedef struct {
- void (*init)(void); /* call static constructors */
- void (*term)(void); /* call static destructors */
-} Cdtor, *CdtorPtr;
+typedef struct
+{
+ void (*init) (void); /* call static constructors */
+ void (*term) (void); /* call static destructors */
+} Cdtor, *CdtorPtr;
/*
* The void * handle returned from dlopen is actually a ModulePtr.
*/
-typedef struct Module {
- struct Module *next;
- char *name; /* module name for refcounting */
- int refCnt; /* the number of references */
- void *entry; /* entry point from load */
- struct dl_info *info; /* optional init/terminate functions */
- CdtorPtr cdtors; /* optional C++ constructors */
- int nExports; /* the number of exports found */
- ExportPtr exports; /* the array of exports */
-} Module, *ModulePtr;
+typedef struct Module
+{
+ struct Module *next;
+ char *name; /* module name for refcounting */
+ int refCnt; /* the number of references */
+ void *entry; /* entry point from load */
+ struct dl_info *info; /* optional init/terminate functions */
+ CdtorPtr cdtors; /* optional C++ constructors */
+ int nExports; /* the number of exports found */
+ ExportPtr exports; /* the array of exports */
+} Module, *ModulePtr;
/*
* We keep a list of all loaded modules to be able to call the fini
@@ -60,98 +63,116 @@ static ModulePtr modList;
* The last error from one of the dl* routines is kept in static
* variables here. Each error is returned only once to the caller.
*/
-static char errbuf[BUFSIZ];
-static int errvalid;
+static char errbuf[BUFSIZ];
+static int errvalid;
-extern char *strdup(const char *);
-static void caterr(char *);
-static int readExports(ModulePtr);
-static void terminate(void);
-static void *findMain(void);
+extern char *strdup(const char *);
+static void caterr(char *);
+static int readExports(ModulePtr);
+static void terminate(void);
+static void *findMain(void);
-void *dlopen(const char *path, int mode)
+void *
+dlopen(const char *path, int mode)
{
register ModulePtr mp;
- static void *mainModule;
+ static void *mainModule;
/*
- * Upon the first call register a terminate handler that will
- * close all libraries. Also get a reference to the main module
- * for use with loadbind.
+ * Upon the first call register a terminate handler that will close
+ * all libraries. Also get a reference to the main module for use with
+ * loadbind.
*/
- if (!mainModule) {
+ if (!mainModule)
+ {
if ((mainModule = findMain()) == NULL)
return NULL;
atexit(terminate);
}
+
/*
* Scan the list of modules if we have the module already loaded.
*/
for (mp = modList; mp; mp = mp->next)
- if (strcmp(mp->name, path) == 0) {
+ if (strcmp(mp->name, path) == 0)
+ {
mp->refCnt++;
return mp;
}
- if ((mp = (ModulePtr)calloc(1, sizeof(*mp))) == NULL) {
+ if ((mp = (ModulePtr) calloc(1, sizeof(*mp))) == NULL)
+ {
errvalid++;
strcpy(errbuf, "calloc: ");
strcat(errbuf, strerror(errno));
return NULL;
}
- if ((mp->name = strdup(path)) == NULL) {
+ if ((mp->name = strdup(path)) == NULL)
+ {
errvalid++;
strcpy(errbuf, "strdup: ");
strcat(errbuf, strerror(errno));
free(mp);
return NULL;
}
+
/*
- * load should be declared load(const char *...). Thus we
- * cast the path to a normal char *. Ugly.
+ * load should be declared load(const char *...). Thus we cast the
+ * path to a normal char *. Ugly.
*/
- if ((mp->entry = (void *)load((char *)path, L_NOAUTODEFER, NULL)) == NULL) {
+ if ((mp->entry = (void *) load((char *) path, L_NOAUTODEFER, NULL)) == NULL)
+ {
free(mp->name);
free(mp);
errvalid++;
strcpy(errbuf, "dlopen: ");
strcat(errbuf, path);
strcat(errbuf, ": ");
+
/*
- * If AIX says the file is not executable, the error
- * can be further described by querying the loader about
- * the last error.
+ * If AIX says the file is not executable, the error can be
+ * further described by querying the loader about the last error.
*/
- if (errno == ENOEXEC) {
- char *tmp[BUFSIZ/sizeof(char *)];
+ if (errno == ENOEXEC)
+ {
+ char *tmp[BUFSIZ / sizeof(char *)];
+
if (loadquery(L_GETMESSAGES, tmp, sizeof(tmp)) == -1)
strcpy(errbuf, strerror(errno));
- else {
- char **p;
+ else
+ {
+ char **p;
+
for (p = tmp; *p; p++)
caterr(*p);
}
- } else
+ }
+ else
strcat(errbuf, strerror(errno));
return NULL;
}
mp->refCnt = 1;
mp->next = modList;
modList = mp;
- if (loadbind(0, mainModule, mp->entry) == -1) {
+ if (loadbind(0, mainModule, mp->entry) == -1)
+ {
dlclose(mp);
errvalid++;
strcpy(errbuf, "loadbind: ");
strcat(errbuf, strerror(errno));
return NULL;
}
+
/*
- * If the user wants global binding, loadbind against all other
- * loaded modules.
+ * If the user wants global binding, loadbind against all other loaded
+ * modules.
*/
- if (mode & RTLD_GLOBAL) {
+ if (mode & RTLD_GLOBAL)
+ {
register ModulePtr mp1;
+
for (mp1 = mp->next; mp1; mp1 = mp1->next)
- if (loadbind(0, mp1->entry, mp->entry) == -1) {
+ if (loadbind(0, mp1->entry, mp->entry) == -1)
+ {
dlclose(mp);
errvalid++;
strcpy(errbuf, "loadbind: ");
@@ -159,28 +180,36 @@ void *dlopen(const char *path, int mode)
return NULL;
}
}
- if (readExports(mp) == -1) {
+ if (readExports(mp) == -1)
+ {
dlclose(mp);
return NULL;
}
+
/*
* If there is a dl_info structure, call the init function.
*/
- if (mp->info = (struct dl_info *)dlsym(mp, "dl_info")) {
+ if (mp->info = (struct dl_info *) dlsym(mp, "dl_info"))
+ {
if (mp->info->init)
- (*mp->info->init)();
- } else
+ (*mp->info->init) ();
+ }
+ else
errvalid = 0;
+
/*
- * If the shared object was compiled using xlC we will need
- * to call static constructors (and later on dlclose destructors).
+ * If the shared object was compiled using xlC we will need to call
+ * static constructors (and later on dlclose destructors).
*/
- if (mp->cdtors = (CdtorPtr)dlsym(mp, "__cdtors")) {
- while (mp->cdtors->init) {
- (*mp->cdtors->init)();
+ if (mp->cdtors = (CdtorPtr) dlsym(mp, "__cdtors"))
+ {
+ while (mp->cdtors->init)
+ {
+ (*mp->cdtors->init) ();
mp->cdtors++;
}
- } else
+ }
+ else
errvalid = 0;
return mp;
}
@@ -189,13 +218,15 @@ void *dlopen(const char *path, int mode)
* Attempt to decipher an AIX loader error message and append it
* to our static error message buffer.
*/
-static void caterr(char *s)
+static void
+caterr(char *s)
{
- register char *p = s;
+ register char *p = s;
while (*p >= '0' && *p <= '9')
p++;
- switch(atoi(s)) {
+ switch (atoi(s))
+ {
case L_ERROR_TOOMANY:
strcat(errbuf, "to many errors");
break;
@@ -224,15 +255,16 @@ static void caterr(char *s)
}
}
-void *dlsym(void *handle, const char *symbol)
+void *
+dlsym(void *handle, const char *symbol)
{
- register ModulePtr mp = (ModulePtr)handle;
+ register ModulePtr mp = (ModulePtr) handle;
register ExportPtr ep;
- register int i;
+ register int i;
/*
- * Could speed up the search, but I assume that one assigns
- * the result to function pointers anyways.
+ * Could speed up the search, but I assume that one assigns the result
+ * to function pointers anyways.
*/
for (ep = mp->exports, i = mp->nExports; i; i--, ep++)
if (strcmp(ep->name, symbol) == 0)
@@ -243,38 +275,45 @@ void *dlsym(void *handle, const char *symbol)
return NULL;
}
-char *dlerror(void)
+char *
+dlerror(void)
{
- if (errvalid) {
+ if (errvalid)
+ {
errvalid = 0;
return errbuf;
}
return NULL;
}
-int dlclose(void *handle)
+int
+dlclose(void *handle)
{
- register ModulePtr mp = (ModulePtr)handle;
- int result;
+ register ModulePtr mp = (ModulePtr) handle;
+ int result;
register ModulePtr mp1;
if (--mp->refCnt > 0)
return 0;
if (mp->info && mp->info->fini)
- (*mp->info->fini)();
+ (*mp->info->fini) ();
if (mp->cdtors)
- while (mp->cdtors->term) {
- (*mp->cdtors->term)();
+ while (mp->cdtors->term)
+ {
+ (*mp->cdtors->term) ();
mp->cdtors++;
}
result = unload(mp->entry);
- if (result == -1) {
+ if (result == -1)
+ {
errvalid++;
strcpy(errbuf, strerror(errno));
}
- if (mp->exports) {
+ if (mp->exports)
+ {
register ExportPtr ep;
- register int i;
+ register int i;
+
for (ep = mp->exports, i = mp->nExports; i; i--, ep++)
if (ep->name)
free(ep->name);
@@ -282,9 +321,11 @@ int dlclose(void *handle)
}
if (mp == modList)
modList = mp->next;
- else {
+ else
+ {
for (mp1 = modList; mp1; mp1 = mp1->next)
- if (mp1->next == mp) {
+ if (mp1->next == mp)
+ {
mp1->next = mp->next;
break;
}
@@ -294,7 +335,8 @@ int dlclose(void *handle)
return result;
}
-static void terminate(void)
+static void
+terminate(void)
{
while (modList)
dlclose(modList);
@@ -303,180 +345,208 @@ static void terminate(void)
/*
* Build the export table from the XCOFF .loader section.
*/
-static int readExports(ModulePtr mp)
+static int
+readExports(ModulePtr mp)
{
- LDFILE *ldp = NULL;
- SCNHDR sh, shdata;
- LDHDR *lhp;
- char *ldbuf;
- LDSYM *ls;
- int i;
- ExportPtr ep;
-
- if ((ldp = ldopen(mp->name, ldp)) == NULL) {
+ LDFILE *ldp = NULL;
+ SCNHDR sh,
+ shdata;
+ LDHDR *lhp;
+ char *ldbuf;
+ LDSYM *ls;
+ int i;
+ ExportPtr ep;
+
+ if ((ldp = ldopen(mp->name, ldp)) == NULL)
+ {
struct ld_info *lp;
- char *buf;
- int size = 4*1024;
- if (errno != ENOENT) {
+ char *buf;
+ int size = 4 * 1024;
+
+ if (errno != ENOENT)
+ {
errvalid++;
strcpy(errbuf, "readExports: ");
strcat(errbuf, strerror(errno));
return -1;
}
+
/*
- * The module might be loaded due to the LIBPATH
- * environment variable. Search for the loaded
- * module using L_GETINFO.
+ * The module might be loaded due to the LIBPATH environment
+ * variable. Search for the loaded module using L_GETINFO.
*/
- if ((buf = malloc(size)) == NULL) {
+ if ((buf = malloc(size)) == NULL)
+ {
errvalid++;
strcpy(errbuf, "readExports: ");
strcat(errbuf, strerror(errno));
return -1;
}
- while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
+ while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM)
+ {
free(buf);
- size += 4*1024;
- if ((buf = malloc(size)) == NULL) {
+ size += 4 * 1024;
+ if ((buf = malloc(size)) == NULL)
+ {
errvalid++;
strcpy(errbuf, "readExports: ");
strcat(errbuf, strerror(errno));
return -1;
}
}
- if (i == -1) {
+ if (i == -1)
+ {
errvalid++;
strcpy(errbuf, "readExports: ");
strcat(errbuf, strerror(errno));
free(buf);
return -1;
}
+
/*
- * Traverse the list of loaded modules. The entry point
- * returned by load() does actually point to the data
- * segment origin.
+ * Traverse the list of loaded modules. The entry point returned
+ * by load() does actually point to the data segment origin.
*/
- lp = (struct ld_info *)buf;
- while (lp) {
- if (lp->ldinfo_dataorg == mp->entry) {
+ lp = (struct ld_info *) buf;
+ while (lp)
+ {
+ if (lp->ldinfo_dataorg == mp->entry)
+ {
ldp = ldopen(lp->ldinfo_filename, ldp);
break;
}
if (lp->ldinfo_next == 0)
lp = NULL;
else
- lp = (struct ld_info *)((char *)lp + lp->ldinfo_next);
+ lp = (struct ld_info *) ((char *) lp + lp->ldinfo_next);
}
free(buf);
- if (!ldp) {
+ if (!ldp)
+ {
errvalid++;
strcpy(errbuf, "readExports: ");
strcat(errbuf, strerror(errno));
return -1;
}
}
- if (TYPE(ldp) != U802TOCMAGIC) {
+ if (TYPE(ldp) != U802TOCMAGIC)
+ {
errvalid++;
strcpy(errbuf, "readExports: bad magic");
- while(ldclose(ldp) == FAILURE)
+ while (ldclose(ldp) == FAILURE)
;
return -1;
}
+
/*
- * Get the padding for the data section. This is needed for
- * AIX 4.1 compilers. This is used when building the final
- * function pointer to the exported symbol.
+ * Get the padding for the data section. This is needed for AIX 4.1
+ * compilers. This is used when building the final function pointer to
+ * the exported symbol.
*/
- if (ldnshread(ldp, _DATA, &shdata) != SUCCESS) {
+ if (ldnshread(ldp, _DATA, &shdata) != SUCCESS)
+ {
errvalid++;
strcpy(errbuf, "readExports: cannot read data section header");
- while(ldclose(ldp) == FAILURE)
+ while (ldclose(ldp) == FAILURE)
;
return -1;
}
- if (ldnshread(ldp, _LOADER, &sh) != SUCCESS) {
+ if (ldnshread(ldp, _LOADER, &sh) != SUCCESS)
+ {
errvalid++;
strcpy(errbuf, "readExports: cannot read loader section header");
- while(ldclose(ldp) == FAILURE)
+ while (ldclose(ldp) == FAILURE)
;
return -1;
}
+
/*
* We read the complete loader section in one chunk, this makes
* finding long symbol names residing in the string table easier.
*/
- if ((ldbuf = (char *)malloc(sh.s_size)) == NULL) {
+ if ((ldbuf = (char *) malloc(sh.s_size)) == NULL)
+ {
errvalid++;
strcpy(errbuf, "readExports: ");
strcat(errbuf, strerror(errno));
- while(ldclose(ldp) == FAILURE)
+ while (ldclose(ldp) == FAILURE)
;
return -1;
}
- if (FSEEK(ldp, sh.s_scnptr, BEGINNING) != OKFSEEK) {
+ if (FSEEK(ldp, sh.s_scnptr, BEGINNING) != OKFSEEK)
+ {
errvalid++;
strcpy(errbuf, "readExports: cannot seek to loader section");
free(ldbuf);
- while(ldclose(ldp) == FAILURE)
+ while (ldclose(ldp) == FAILURE)
;
return -1;
}
- if (FREAD(ldbuf, sh.s_size, 1, ldp) != 1) {
+ if (FREAD(ldbuf, sh.s_size, 1, ldp) != 1)
+ {
errvalid++;
strcpy(errbuf, "readExports: cannot read loader section");
free(ldbuf);
- while(ldclose(ldp) == FAILURE)
+ while (ldclose(ldp) == FAILURE)
;
return -1;
}
- lhp = (LDHDR *)ldbuf;
- ls = (LDSYM *)(ldbuf+LDHDRSZ);
+ lhp = (LDHDR *) ldbuf;
+ ls = (LDSYM *) (ldbuf + LDHDRSZ);
+
/*
* Count the number of exports to include in our export table.
*/
- for (i = lhp->l_nsyms; i; i--, ls++) {
+ for (i = lhp->l_nsyms; i; i--, ls++)
+ {
if (!LDR_EXPORT(*ls))
continue;
mp->nExports++;
}
- if ((mp->exports = (ExportPtr)calloc(mp->nExports, sizeof(*mp->exports))) == NULL) {
+ if ((mp->exports = (ExportPtr) calloc(mp->nExports, sizeof(*mp->exports))) == NULL)
+ {
errvalid++;
strcpy(errbuf, "readExports: ");
strcat(errbuf, strerror(errno));
free(ldbuf);
- while(ldclose(ldp) == FAILURE)
+ while (ldclose(ldp) == FAILURE)
;
return -1;
}
+
/*
- * Fill in the export table. All entries are relative to
- * the entry point we got from load.
+ * Fill in the export table. All entries are relative to the entry
+ * point we got from load.
*/
ep = mp->exports;
- ls = (LDSYM *)(ldbuf+LDHDRSZ);
- for (i = lhp->l_nsyms; i; i--, ls++) {
- char *symname;
- char tmpsym[SYMNMLEN+1];
+ ls = (LDSYM *) (ldbuf + LDHDRSZ);
+ for (i = lhp->l_nsyms; i; i--, ls++)
+ {
+ char *symname;
+ char tmpsym[SYMNMLEN + 1];
+
if (!LDR_EXPORT(*ls))
continue;
if (ls->l_zeroes == 0)
- symname = ls->l_offset+lhp->l_stoff+ldbuf;
- else {
+ symname = ls->l_offset + lhp->l_stoff + ldbuf;
+ else
+ {
+
/*
- * The l_name member is not zero terminated, we
- * must copy the first SYMNMLEN chars and make
- * sure we have a zero byte at the end.
+ * The l_name member is not zero terminated, we must copy the
+ * first SYMNMLEN chars and make sure we have a zero byte at
+ * the end.
*/
strNcpy(tmpsym, ls->l_name, SYMNMLEN);
symname = tmpsym;
}
ep->name = strdup(symname);
- ep->addr = (void *)((unsigned long)mp->entry +
- ls->l_value - shdata.s_vaddr);
+ ep->addr = (void *) ((unsigned long) mp->entry +
+ ls->l_value - shdata.s_vaddr);
ep++;
}
free(ldbuf);
- while(ldclose(ldp) == FAILURE)
+ while (ldclose(ldp) == FAILURE)
;
return 0;
}
@@ -485,43 +555,48 @@ static int readExports(ModulePtr mp)
* Find the main modules entry point. This is used as export pointer
* for loadbind() to be able to resolve references to the main part.
*/
-static void * findMain(void)
+static void *
+findMain(void)
{
struct ld_info *lp;
- char *buf;
- int size = 4*1024;
- int i;
- void *ret;
+ char *buf;
+ int size = 4 * 1024;
+ int i;
+ void *ret;
- if ((buf = malloc(size)) == NULL) {
+ if ((buf = malloc(size)) == NULL)
+ {
errvalid++;
strcpy(errbuf, "findMain: ");
strcat(errbuf, strerror(errno));
return NULL;
}
- while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
+ while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM)
+ {
free(buf);
- size += 4*1024;
- if ((buf = malloc(size)) == NULL) {
+ size += 4 * 1024;
+ if ((buf = malloc(size)) == NULL)
+ {
errvalid++;
strcpy(errbuf, "findMain: ");
strcat(errbuf, strerror(errno));
return NULL;
}
}
- if (i == -1) {
+ if (i == -1)
+ {
errvalid++;
strcpy(errbuf, "findMain: ");
strcat(errbuf, strerror(errno));
free(buf);
return NULL;
}
+
/*
- * The first entry is the main module. The entry point
- * returned by load() does actually point to the data
- * segment origin.
+ * The first entry is the main module. The entry point returned by
+ * load() does actually point to the data segment origin.
*/
- lp = (struct ld_info *)buf;
+ lp = (struct ld_info *) buf;
ret = lp->ldinfo_dataorg;
free(buf);
return ret;
diff --git a/src/backend/port/aix/dlfcn.h b/src/backend/port/aix/dlfcn.h
index 5671e9caa3a..1e874d96559 100644
--- a/src/backend/port/aix/dlfcn.h
+++ b/src/backend/port/aix/dlfcn.h
@@ -8,39 +8,42 @@
#define __dlfcn_h__
#ifdef __cplusplus
-extern "C" {
+extern "C"
+{
#endif
/*
* Mode flags for the dlopen routine.
*/
-#define RTLD_LAZY 1 /* lazy function call binding */
-#define RTLD_NOW 2 /* immediate function call binding */
-#define RTLD_GLOBAL 0x100 /* allow symbols to be global */
+#define RTLD_LAZY 1 /* lazy function call binding */
+#define RTLD_NOW 2 /* immediate function call binding */
+#define RTLD_GLOBAL 0x100 /* allow symbols to be global */
/*
* To be able to intialize, a library may provide a dl_info structure
* that contains functions to be called to initialize and terminate.
*/
-struct dl_info {
- void (*init)(void);
- void (*fini)(void);
-};
+ struct dl_info
+ {
+ void (*init) (void);
+ void (*fini) (void);
+ };
#if __STDC__ || defined(_IBMR2)
-void *dlopen(const char *path, int mode);
-void *dlsym(void *handle, const char *symbol);
-char *dlerror(void);
-int dlclose(void *handle);
+ void *dlopen(const char *path, int mode);
+ void *dlsym(void *handle, const char *symbol);
+ char *dlerror(void);
+ int dlclose(void *handle);
#else
-void *dlopen();
-void *dlsym();
-char *dlerror();
-int dlclose();
+ void *dlopen();
+ void *dlsym();
+ char *dlerror();
+ int dlclose();
#endif
#ifdef __cplusplus
}
+
#endif
-#endif /* __dlfcn_h__ */
+#endif /* __dlfcn_h__ */
diff --git a/src/backend/port/aix/port-protos.h b/src/backend/port/aix/port-protos.h
index 986e5bd7d48..6429dc26c04 100644
--- a/src/backend/port/aix/port-protos.h
+++ b/src/backend/port/aix/port-protos.h
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for AIX
+ * port-specific prototypes for AIX
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.1.1.1 1996/07/09 06:21:41 scrappy Exp $
+ * $Id: port-protos.h,v 1.2 1997/09/07 04:45:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PORT_PROTOS_H
#define PORT_PROTOS_H
-#include "dlfcn.h" /* this is from jum's libdl package */
+#include "dlfcn.h" /* this is from jum's libdl package */
/* dynloader.c */
@@ -22,4 +22,4 @@
#define pg_dlclose(h) dlclose(h)
#define pg_dlerror() dlerror()
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/alpha/port-protos.h b/src/backend/port/alpha/port-protos.h
index 3bd8d454a5e..3b5cb47adea 100644
--- a/src/backend/port/alpha/port-protos.h
+++ b/src/backend/port/alpha/port-protos.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * prototypes for OSF/1-specific routines
+ * prototypes for OSF/1-specific routines
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.1.1.1 1996/07/09 06:21:42 scrappy Exp $
+ * $Id: port-protos.h,v 1.2 1997/09/07 04:45:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,18 +22,18 @@
/*
* Dynamic Loader on Alpha OSF/1.x
*
- * this dynamic loader uses the system dynamic loading interface for shared
+ * this dynamic loader uses the system dynamic loading interface for shared
* libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared
* library as the file to be dynamically loaded.
*
*/
#define pg_dlopen(f) dlopen(f, RTLD_LAZY)
-#define pg_dlsym(h, f) ((func_ptr)dlsym(h, f))
-#define pg_dlclose(h) dlclose(h)
+#define pg_dlsym(h, f) ((func_ptr)dlsym(h, f))
+#define pg_dlclose(h) dlclose(h)
#define pg_dlerror() dlerror()
/* port.c */
-extern void init_address_fixup(void);
+extern void init_address_fixup(void);
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/alpha/port.c b/src/backend/port/alpha/port.c
index d7c17b0a5ba..80b03088a43 100644
--- a/src/backend/port/alpha/port.c
+++ b/src/backend/port/alpha/port.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * OSF/1-specific routines
+ * OSF/1-specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/alpha/Attic/port.c,v 1.1.1.1 1996/07/09 06:21:42 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/alpha/Attic/port.c,v 1.2 1997/09/07 04:45:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,14 +21,17 @@ void
init_address_fixup()
{
#ifdef NOFIXADE
- int buffer[] = { SSIN_UACPROC, UAC_SIGBUS };
-#endif /* NOFIXADE */
+ int buffer[] = {SSIN_UACPROC, UAC_SIGBUS};
+
+#endif /* NOFIXADE */
#ifdef NOPRINTADE
- int buffer[] = { SSIN_UACPROC, UAC_NOPRINT };
-#endif /* NOPRINTADE */
+ int buffer[] = {SSIN_UACPROC, UAC_NOPRINT};
+
+#endif /* NOPRINTADE */
- if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
- (unsigned long) NULL) < 0) {
- elog(NOTICE, "setsysinfo failed: %d\n", errno);
- }
+ if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
+ (unsigned long) NULL) < 0)
+ {
+ elog(NOTICE, "setsysinfo failed: %d\n", errno);
+ }
}
diff --git a/src/backend/port/bsdi/dynloader.c b/src/backend/port/bsdi/dynloader.c
index f9b2180f03a..cfaeec0c200 100644
--- a/src/backend/port/bsdi/dynloader.c
+++ b/src/backend/port/bsdi/dynloader.c
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* dynloader.c--
- * Dynamic Loader for Postgres for Linux, generated from those for
- * Ultrix.
+ * Dynamic Loader for Postgres for Linux, generated from those for
+ * Ultrix.
*
- * You need to install the dld library on your Linux system!
+ * You need to install the dld library on your Linux system!
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/port/linux/dynloader.c,v 1.1.1.1 1994/11/07 05:19:37 andrew Exp
+ * /usr/local/devel/pglite/cvs/src/backend/port/linux/dynloader.c,v 1.1.1.1 1994/11/07 05:19:37 andrew Exp
*
*-------------------------------------------------------------------------
*/
@@ -22,74 +22,85 @@
#include "utils/elog.h"
#include "fmgr.h"
-extern char pg_pathname[];
+extern char pg_pathname[];
-void *
+void *
pg_dlopen(char *filename)
{
- static int dl_initialized= 0;
+ static int dl_initialized = 0;
- /*
- * initializes the dynamic loader with the executable's pathname.
- * (only needs to do this the first time pg_dlopen is called.)
- */
- if (!dl_initialized) {
- if (dld_init (dld_find_executable (pg_pathname))) {
- return NULL;
- }
/*
- * if there are undefined symbols, we want dl to search from the
- * following libraries also.
+ * initializes the dynamic loader with the executable's pathname.
+ * (only needs to do this the first time pg_dlopen is called.)
*/
- dl_initialized= 1;
- }
-
- /*
- * link the file, then check for undefined symbols!
- */
- if (dld_link(filename)) {
- return NULL;
- }
+ if (!dl_initialized)
+ {
+ if (dld_init(dld_find_executable(pg_pathname)))
+ {
+ return NULL;
+ }
- /*
- * If undefined symbols: try to link with the C and math libraries!
- * This could be smarter, if the dynamic linker was able to handle
- * shared libs!
- */
- if(dld_undefined_sym_count > 0) {
- if (dld_link("/usr/lib/libc.a")) {
- elog(NOTICE, "dld: Cannot link C library!");
- return NULL;
+ /*
+ * if there are undefined symbols, we want dl to search from the
+ * following libraries also.
+ */
+ dl_initialized = 1;
}
- if(dld_undefined_sym_count > 0) {
- if (dld_link("/usr/lib/libm.a")) {
- elog(NOTICE, "dld: Cannot link math library!");
+
+ /*
+ * link the file, then check for undefined symbols!
+ */
+ if (dld_link(filename))
+ {
return NULL;
- }
- if(dld_undefined_sym_count > 0) {
- int count = dld_undefined_sym_count;
- char **list= dld_list_undefined_sym();
+ }
- /* list the undefined symbols, if any */
- elog(NOTICE, "dld: Undefined:");
- do {
- elog(NOTICE, " %s", *list);
- list++;
- count--;
- } while(count > 0);
+ /*
+ * If undefined symbols: try to link with the C and math libraries!
+ * This could be smarter, if the dynamic linker was able to handle
+ * shared libs!
+ */
+ if (dld_undefined_sym_count > 0)
+ {
+ if (dld_link("/usr/lib/libc.a"))
+ {
+ elog(NOTICE, "dld: Cannot link C library!");
+ return NULL;
+ }
+ if (dld_undefined_sym_count > 0)
+ {
+ if (dld_link("/usr/lib/libm.a"))
+ {
+ elog(NOTICE, "dld: Cannot link math library!");
+ return NULL;
+ }
+ if (dld_undefined_sym_count > 0)
+ {
+ int count = dld_undefined_sym_count;
+ char **list = dld_list_undefined_sym();
- dld_unlink_by_file(filename, 1);
- return NULL;
- }
+ /* list the undefined symbols, if any */
+ elog(NOTICE, "dld: Undefined:");
+ do
+ {
+ elog(NOTICE, " %s", *list);
+ list++;
+ count--;
+ } while (count > 0);
+
+ dld_unlink_by_file(filename, 1);
+ return NULL;
+ }
+ }
}
- }
- return (void *) strdup(filename);
+ return (void *) strdup(filename);
}
-char *
+char *
pg_dlerror()
{
- return dld_strerror(dld_errno);
+ return dld_strerror(dld_errno);
}
+
#endif
diff --git a/src/backend/port/bsdi/port-protos.h b/src/backend/port/bsdi/port-protos.h
index 9d21bb15115..acd0e85a49b 100644
--- a/src/backend/port/bsdi/port-protos.h
+++ b/src/backend/port/bsdi/port-protos.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for SunOS 4
+ * port-specific prototypes for SunOS 4
*
*
* Copyright (c) 1994, Regents of the University of California
@@ -17,26 +17,26 @@
* Externals in libc that need prototypes (or at least declarations)
*/
-extern char *ecvt(double, int, int*, int*);
-extern char *fcvt(double, int, int*, int*);
+extern char *ecvt(double, int, int *, int *);
+extern char *fcvt(double, int, int *, int *);
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
/* dynloader.c */
#ifndef PRE_BSDI_2_1
-# include <dlfcn.h>
-# define pg_dlopen(f) dlopen(f, 1)
-# define pg_dlsym dlsym
-# define pg_dlclose dlclose
-# define pg_dlerror dlerror
+#include <dlfcn.h>
+#define pg_dlopen(f) dlopen(f, 1)
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
#else
-# define pg_dlsym(handle, funcname) ((func_ptr) dld_get_func((funcname)))
-# define pg_dlclose(handle) ({ dld_unlink_by_file(handle, 1); free(handle); })
+#define pg_dlsym(handle, funcname) ((func_ptr) dld_get_func((funcname)))
+#define pg_dlclose(handle) ({ dld_unlink_by_file(handle, 1); free(handle); })
#endif
/* port.c */
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/dgux/dynloader.c b/src/backend/port/dgux/dynloader.c
index 7ec648fb44b..0f7d38bc092 100644
--- a/src/backend/port/dgux/dynloader.c
+++ b/src/backend/port/dgux/dynloader.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* dynloader.c--
- * Dynamic Loader for Postgres for DG/UX, generated from those for
- * Linux.
+ * Dynamic Loader for Postgres for DG/UX, generated from those for
+ * Linux.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/dgux/Attic/dynloader.c,v 1.1 1996/07/25 20:43:58 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/dgux/Attic/dynloader.c,v 1.2 1997/09/07 04:45:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,73 +19,83 @@
#include "utils/elog.h"
#include "fmgr.h"
-extern char pg_pathname[];
+extern char pg_pathname[];
-void *
+void *
pg_dlopen(char *filename)
{
- static int dl_initialized= 0;
+ static int dl_initialized = 0;
- /*
- * initializes the dynamic loader with the executable's pathname.
- * (only needs to do this the first time pg_dlopen is called.)
- */
- if (!dl_initialized) {
- if (dld_init (dld_find_executable (pg_pathname))) {
- return NULL;
- }
/*
- * if there are undefined symbols, we want dl to search from the
- * following libraries also.
+ * initializes the dynamic loader with the executable's pathname.
+ * (only needs to do this the first time pg_dlopen is called.)
*/
- dl_initialized= 1;
- }
-
- /*
- * link the file, then check for undefined symbols!
- */
- if (dld_link(filename)) {
- return NULL;
- }
+ if (!dl_initialized)
+ {
+ if (dld_init(dld_find_executable(pg_pathname)))
+ {
+ return NULL;
+ }
- /*
- * If undefined symbols: try to link with the C and math libraries!
- * This could be smarter, if the dynamic linker was able to handle
- * shared libs!
- */
- if(dld_undefined_sym_count > 0) {
- if (dld_link("/usr/lib/libc.a")) {
- elog(NOTICE, "dld: Cannot link C library!");
- return NULL;
+ /*
+ * if there are undefined symbols, we want dl to search from the
+ * following libraries also.
+ */
+ dl_initialized = 1;
}
- if(dld_undefined_sym_count > 0) {
- if (dld_link("/usr/lib/libm.a")) {
- elog(NOTICE, "dld: Cannot link math library!");
+
+ /*
+ * link the file, then check for undefined symbols!
+ */
+ if (dld_link(filename))
+ {
return NULL;
- }
- if(dld_undefined_sym_count > 0) {
- int count = dld_undefined_sym_count;
- char **list= dld_list_undefined_sym();
+ }
- /* list the undefined symbols, if any */
- elog(NOTICE, "dld: Undefined:");
- do {
- elog(NOTICE, " %s", *list);
- list++;
- count--;
- } while(count > 0);
+ /*
+ * If undefined symbols: try to link with the C and math libraries!
+ * This could be smarter, if the dynamic linker was able to handle
+ * shared libs!
+ */
+ if (dld_undefined_sym_count > 0)
+ {
+ if (dld_link("/usr/lib/libc.a"))
+ {
+ elog(NOTICE, "dld: Cannot link C library!");
+ return NULL;
+ }
+ if (dld_undefined_sym_count > 0)
+ {
+ if (dld_link("/usr/lib/libm.a"))
+ {
+ elog(NOTICE, "dld: Cannot link math library!");
+ return NULL;
+ }
+ if (dld_undefined_sym_count > 0)
+ {
+ int count = dld_undefined_sym_count;
+ char **list = dld_list_undefined_sym();
- dld_unlink_by_file(filename, 1);
- return NULL;
- }
+ /* list the undefined symbols, if any */
+ elog(NOTICE, "dld: Undefined:");
+ do
+ {
+ elog(NOTICE, " %s", *list);
+ list++;
+ count--;
+ } while (count > 0);
+
+ dld_unlink_by_file(filename, 1);
+ return NULL;
+ }
+ }
}
- }
- return (void *) strdup(filename);
+ return (void *) strdup(filename);
}
-char *
+char *
pg_dlerror()
{
- return dld_strerror(dld_errno);
+ return dld_strerror(dld_errno);
}
diff --git a/src/backend/port/dgux/port-protos.h b/src/backend/port/dgux/port-protos.h
index 13862f9a007..9ca45ba234a 100644
--- a/src/backend/port/dgux/port-protos.h
+++ b/src/backend/port/dgux/port-protos.h
@@ -1,30 +1,30 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for SunOS 4
+ * port-specific prototypes for SunOS 4
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.1 1996/07/25 20:44:00 scrappy Exp $
+ * $Id: port-protos.h,v 1.2 1997/09/07 04:45:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PORT_PROTOS_H
#define PORT_PROTOS_H
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
#include "dlfcn.h"
/* dynloader.c */
-/* #define pg_dlopen(f) dlopen(f, 1) */
-#define pg_dlopen(f) dlopen(f, 2)
-#define pg_dlsym dlsym
-#define pg_dlclose dlclose
-#define pg_dlerror dlerror
+/* #define pg_dlopen(f) dlopen(f, 1) */
+#define pg_dlopen(f) dlopen(f, 2)
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
/* port.c */
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/dgux/port.c b/src/backend/port/dgux/port.c
index 46fe71db568..1cc325c0db0 100644
--- a/src/backend/port/dgux/port.c
+++ b/src/backend/port/dgux/port.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * Linux-specific routines
+ * Linux-specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/dgux/Attic/port.c,v 1.1 1996/07/25 20:44:00 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/dgux/Attic/port.c,v 1.2 1997/09/07 04:45:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
diff --git a/src/backend/port/hpux/dynloader.c b/src/backend/port/hpux/dynloader.c
index deea2e1dc29..3c7a8acaa7a 100644
--- a/src/backend/port/hpux/dynloader.c
+++ b/src/backend/port/hpux/dynloader.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* dynloader.c--
- * dynamic loader for HP-UX using the shared library mechanism
+ * dynamic loader for HP-UX using the shared library mechanism
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/hpux/Attic/dynloader.c,v 1.1.1.1 1996/07/09 06:21:43 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/hpux/Attic/dynloader.c,v 1.2 1997/09/07 04:45:44 momjian Exp $
*
- * NOTES
- * all functions are defined here -- it's impossible to trace the
- * shl_* routines from the bundled HP-UX debugger.
+ * NOTES
+ * all functions are defined here -- it's impossible to trace the
+ * shl_* routines from the bundled HP-UX debugger.
*
*-------------------------------------------------------------------------
*/
@@ -24,34 +24,36 @@
#include "utils/dynamic_loader.h"
#include "port-protos.h"
-void *
+void *
pg_dlopen(char *filename)
{
- shl_t handle = shl_load(filename, BIND_DEFERRED, 0);
+ shl_t handle = shl_load(filename, BIND_DEFERRED, 0);
- return((void *) handle);
+ return ((void *) handle);
}
func_ptr
pg_dlsym(void *handle, char *funcname)
{
- func_ptr f;
+ func_ptr f;
- if (shl_findsym((shl_t *) &handle, funcname, TYPE_PROCEDURE, &f) == -1) {
- f = (func_ptr) NULL;
- }
- return(f);
+ if (shl_findsym((shl_t *) & handle, funcname, TYPE_PROCEDURE, &f) == -1)
+ {
+ f = (func_ptr) NULL;
+ }
+ return (f);
}
void
pg_dlclose(void *handle)
{
- shl_unload((shl_t) handle);
+ shl_unload((shl_t) handle);
}
-char *
+char *
pg_dlerror()
{
- static char errmsg[]= "shl_load failed";
- return errmsg;
+ static char errmsg[] = "shl_load failed";
+
+ return errmsg;
}
diff --git a/src/backend/port/hpux/fixade.h b/src/backend/port/hpux/fixade.h
index 62324eb05d7..094cd13ca83 100644
--- a/src/backend/port/hpux/fixade.h
+++ b/src/backend/port/hpux/fixade.h
@@ -1,63 +1,66 @@
/*-------------------------------------------------------------------------
*
* fixade.h--
- * compiler tricks to make things work while POSTGRES does non-native
- * dereferences on PA-RISC.
+ * compiler tricks to make things work while POSTGRES does non-native
+ * dereferences on PA-RISC.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: fixade.h,v 1.1.1.1 1996/07/09 06:21:43 scrappy Exp $
+ * $Id: fixade.h,v 1.2 1997/09/07 04:45:48 momjian Exp $
*
- * NOTES
- * This must be included in EVERY source file.
+ * NOTES
+ * This must be included in EVERY source file.
*
*-------------------------------------------------------------------------
*/
-#ifndef FIXADE_H
+#ifndef FIXADE_H
#define FIXADE_H
#if !defined(NOFIXADE)
#if defined(HP_S500_ALIGN)
/* ----------------
- * This cheesy hack turns ON unaligned-access fixup on H-P PA-RISC;
- * the resulting object files contain code that explicitly handles
- * realignment on reference, so it slows memory access down by a
- * considerable factor. It must be used in conjunction with the +u
- * flag to cc. The #pragma is included in c.h to be safe since EVERY
- * source file that performs unaligned access must contain the #pragma.
+ * This cheesy hack turns ON unaligned-access fixup on H-P PA-RISC;
+ * the resulting object files contain code that explicitly handles
+ * realignment on reference, so it slows memory access down by a
+ * considerable factor. It must be used in conjunction with the +u
+ * flag to cc. The #pragma is included in c.h to be safe since EVERY
+ * source file that performs unaligned access must contain the #pragma.
* ----------------
*/
#pragma HP_ALIGN HPUX_NATURAL_S500
#if defined(BROKEN_STRUCT_INIT)
/* ----------------
- * This is so bogus. The HP-UX 9.01 compiler has totally broken
- * struct initialization code. It actually length-checks ALL
- * array initializations within structs against the FIRST one that
- * it sees (when #pragma HP_ALIGN HPUX_NATURAL_S500 is defined)..
- * we have to throw in this unused structure before struct varlena
- * is defined.
+ * This is so bogus. The HP-UX 9.01 compiler has totally broken
+ * struct initialization code. It actually length-checks ALL
+ * array initializations within structs against the FIRST one that
+ * it sees (when #pragma HP_ALIGN HPUX_NATURAL_S500 is defined)..
+ * we have to throw in this unused structure before struct varlena
+ * is defined.
*
- * XXX guess you don't need the #pragma anymore after all :-)
- * since no one looks at this except me i think i'll just leave
- * this here for now..
+ * XXX guess you don't need the #pragma anymore after all :-)
+ * since no one looks at this except me i think i'll just leave
+ * this here for now..
* ----------------
*/
-struct HP_WAY_BOGUS {
- char hpwb_bogus[8192];
+struct HP_WAY_BOGUS
+{
+ char hpwb_bogus[8192];
};
-struct HP_TOO_BOGUS {
- int hptb_bogus[8192];
+struct HP_TOO_BOGUS
+{
+ int hptb_bogus[8192];
};
-#endif /* BROKEN_STRUCT_INIT */
-#endif /* HP_S500_ALIGN */
+
+#endif /* BROKEN_STRUCT_INIT */
+#endif /* HP_S500_ALIGN */
#if defined(WEAK_C_OPTIMIZER)
#pragma OPT_LEVEL 1
-#endif /* WEAK_C_OPTIMIZER */
+#endif /* WEAK_C_OPTIMIZER */
-#endif /* !NOFIXADE */
+#endif /* !NOFIXADE */
-#endif /* FIXADE_H */
+#endif /* FIXADE_H */
diff --git a/src/backend/port/hpux/port-protos.h b/src/backend/port/hpux/port-protos.h
index 33d2dd66def..76b336aae22 100644
--- a/src/backend/port/hpux/port-protos.h
+++ b/src/backend/port/hpux/port-protos.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for HP-UX
+ * port-specific prototypes for HP-UX
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.2 1997/07/27 18:51:57 momjian Exp $
+ * $Id: port-protos.h,v 1.3 1997/09/07 04:45:51 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,7 +14,7 @@
#define PORT_PROTOS_H
#include <sys/resource.h> /* for struct rusage */
-#include <dl.h> /* for shl_t */
+#include <dl.h> /* for shl_t */
#include "utils/dynamic_loader.h"
@@ -24,11 +24,11 @@
/* port.c */
-extern int init_address_fixup(void);
-extern double rint(double x);
-extern double cbrt(double x);
-extern long random(void);
-extern void srandom(unsigned seed);
-extern int getrusage(int who, struct rusage *ru);
+extern int init_address_fixup(void);
+extern double rint(double x);
+extern double cbrt(double x);
+extern long random(void);
+extern void srandom(unsigned seed);
+extern int getrusage(int who, struct rusage * ru);
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/hpux/port.c b/src/backend/port/hpux/port.c
index 205a3178267..8f37cd44484 100644
--- a/src/backend/port/hpux/port.c
+++ b/src/backend/port/hpux/port.c
@@ -1,47 +1,49 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * port-specific routines for HP-UX
+ * port-specific routines for HP-UX
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/hpux/Attic/port.c,v 1.2 1997/07/27 18:52:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/hpux/Attic/port.c,v 1.3 1997/09/07 04:45:52 momjian Exp $
*
* NOTES
- * For the most part, this file gets around some non-POSIX calls
- * in POSTGRES.
+ * For the most part, this file gets around some non-POSIX calls
+ * in POSTGRES.
*
*-------------------------------------------------------------------------
*/
-#include <unistd.h> /* for rand()/srand() prototypes */
-#include <math.h> /* for pow() prototype */
-#include <sys/syscall.h> /* for syscall #defines */
+#include <unistd.h> /* for rand()/srand() prototypes */
+#include <math.h> /* for pow() prototype */
+#include <sys/syscall.h> /* for syscall #defines */
#include "c.h"
void
init_address_fixup()
{
- /*
- * On PA-RISC, unaligned access fixup is handled by the compiler,
- * not by the kernel.
- */
+
+ /*
+ * On PA-RISC, unaligned access fixup is handled by the compiler, not
+ * by the kernel.
+ */
}
long
random()
{
- return(lrand48());
+ return (lrand48());
}
-void srandom(unsigned seed)
+void
+srandom(unsigned seed)
{
srand48((long int) seed);
}
-getrusage(int who, struct rusage *ru)
+getrusage(int who, struct rusage * ru)
{
- return(syscall(SYS_GETRUSAGE, who, ru));
+ return (syscall(SYS_GETRUSAGE, who, ru));
}
diff --git a/src/backend/port/hpux/rusagestub.h b/src/backend/port/hpux/rusagestub.h
index d2393eb792d..5eda998802e 100644
--- a/src/backend/port/hpux/rusagestub.h
+++ b/src/backend/port/hpux/rusagestub.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* rusagestub.h--
- * Stubs for getrusage(3).
+ * Stubs for getrusage(3).
*
*
* Copyright (c) 1994, Regents of the University of California
@@ -13,18 +13,19 @@
#ifndef RUSAGESTUB_H
#define RUSAGESTUB_H
-#include <sys/time.h> /* for struct timeval */
-#include <sys/times.h> /* for struct tms */
-#include <limits.h> /* for CLK_TCK */
+#include <sys/time.h> /* for struct timeval */
+#include <sys/times.h> /* for struct tms */
+#include <limits.h> /* for CLK_TCK */
-#define RUSAGE_SELF 0
-#define RUSAGE_CHILDREN -1
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN -1
-struct rusage {
- struct timeval ru_utime; /* user time used */
- struct timeval ru_stime; /* system time used */
+struct rusage
+{
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
};
-extern int getrusage(int who, struct rusage *rusage);
+extern int getrusage(int who, struct rusage * rusage);
-#endif /* RUSAGESTUB_H */
+#endif /* RUSAGESTUB_H */
diff --git a/src/backend/port/i386_solaris/port-protos.h b/src/backend/port/i386_solaris/port-protos.h
index 45e56ad1e75..6118a650460 100644
--- a/src/backend/port/i386_solaris/port-protos.h
+++ b/src/backend/port/i386_solaris/port-protos.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for SunOS 4
+ * port-specific prototypes for SunOS 4
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.1 1996/07/20 08:34:33 scrappy Exp $
+ * $Id: port-protos.h,v 1.2 1997/09/07 04:45:56 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,25 +14,25 @@
#define PORT_PROTOS_H
#include <dlfcn.h>
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
/* dynloader.c */
/*
* Dynamic Loader on SunOS 4.
*
- * this dynamic loader uses the system dynamic loading interface for shared
+ * this dynamic loader uses the system dynamic loading interface for shared
* libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared
* library as the file to be dynamically loaded.
*
*/
#define pg_dlopen(f) dlopen(f,1)
-#define pg_dlsym dlsym
-#define pg_dlclose dlclose
-#define pg_dlerror dlerror
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
/* port.c */
-extern long random(void);
-extern void srandom(int seed);
+extern long random(void);
+extern void srandom(int seed);
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/i386_solaris/port.c b/src/backend/port/i386_solaris/port.c
index c6fcdab98e7..119163a1869 100644
--- a/src/backend/port/i386_solaris/port.c
+++ b/src/backend/port/i386_solaris/port.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * SunOS5-specific routines
+ * SunOS5-specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/i386_solaris/Attic/port.c,v 1.1 1996/07/20 08:34:34 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/i386_solaris/Attic/port.c,v 1.2 1997/09/07 04:45:58 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <math.h> /* for pow() prototype */
+#include <math.h> /* for pow() prototype */
#include <errno.h>
#include "rusagestub.h"
@@ -19,48 +19,52 @@
long
random()
{
- return(lrand48());
+ return (lrand48());
}
void
srandom(int seed)
{
- srand48((long int) seed);
+ srand48((long int) seed);
}
int
-getrusage(int who, struct rusage *rusage)
+getrusage(int who, struct rusage * rusage)
{
- struct tms tms;
- register int tick_rate = CLK_TCK; /* ticks per second */
- clock_t u, s;
+ struct tms tms;
+ register int tick_rate = CLK_TCK; /* ticks per second */
+ clock_t u,
+ s;
- if (rusage == (struct rusage *) NULL) {
- errno = EFAULT;
- return(-1);
- }
- if (times(&tms) < 0) {
- /* errno set by times */
- return(-1);
- }
- switch (who) {
- case RUSAGE_SELF:
- u = tms.tms_utime;
- s = tms.tms_stime;
- break;
- case RUSAGE_CHILDREN:
- u = tms.tms_cutime;
- s = tms.tms_cstime;
- break;
- default:
- errno = EINVAL;
- return(-1);
- }
+ if (rusage == (struct rusage *) NULL)
+ {
+ errno = EFAULT;
+ return (-1);
+ }
+ if (times(&tms) < 0)
+ {
+ /* errno set by times */
+ return (-1);
+ }
+ switch (who)
+ {
+ case RUSAGE_SELF:
+ u = tms.tms_utime;
+ s = tms.tms_stime;
+ break;
+ case RUSAGE_CHILDREN:
+ u = tms.tms_cutime;
+ s = tms.tms_cstime;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
#define TICK_TO_SEC(T, RATE) ((T)/(RATE))
-#define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE)
- rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
- rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
- rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
- rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
- return(0);
+#define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE)
+ rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
+ rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
+ rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
+ rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
+ return (0);
}
diff --git a/src/backend/port/i386_solaris/rusagestub.h b/src/backend/port/i386_solaris/rusagestub.h
index 0ad45fafaad..c6e2ceae453 100644
--- a/src/backend/port/i386_solaris/rusagestub.h
+++ b/src/backend/port/i386_solaris/rusagestub.h
@@ -1,30 +1,31 @@
/*-------------------------------------------------------------------------
*
* rusagestub.h--
- * Stubs for getrusage(3).
+ * Stubs for getrusage(3).
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rusagestub.h,v 1.1 1996/07/20 08:34:34 scrappy Exp $
+ * $Id: rusagestub.h,v 1.2 1997/09/07 04:46:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef RUSAGESTUB_H
#define RUSAGESTUB_H
-#include <sys/time.h> /* for struct timeval */
-#include <sys/times.h> /* for struct tms */
-#include <limits.h> /* for CLK_TCK */
+#include <sys/time.h> /* for struct timeval */
+#include <sys/times.h> /* for struct tms */
+#include <limits.h> /* for CLK_TCK */
-#define RUSAGE_SELF 0
-#define RUSAGE_CHILDREN -1
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN -1
-struct rusage {
- struct timeval ru_utime; /* user time used */
- struct timeval ru_stime; /* system time used */
+struct rusage
+{
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
};
-extern int getrusage(int who, struct rusage *rusage);
+extern int getrusage(int who, struct rusage * rusage);
-#endif /* RUSAGESTUB_H */
+#endif /* RUSAGESTUB_H */
diff --git a/src/backend/port/inet_aton.c b/src/backend/port/inet_aton.c
index 37c11b621b7..122875eda3b 100644
--- a/src/backend/port/inet_aton.c
+++ b/src/backend/port/inet_aton.c
@@ -1,39 +1,39 @@
/*
*
- * This inet_aton() function was taken from the GNU C library and
- * incorporated into Postgres for those systems which do not have this
- * routine in their standard C libraries.
+ * This inet_aton() function was taken from the GNU C library and
+ * incorporated into Postgres for those systems which do not have this
+ * routine in their standard C libraries.
*
- * The function was been extracted whole from the file inet_aton.c in
- * Release 5.3.12 of the Linux C library, which is derived from the
- * GNU C library, by Bryan Henderson in October 1996. The copyright
- * notice from that file is below.
+ * The function was been extracted whole from the file inet_aton.c in
+ * Release 5.3.12 of the Linux C library, which is derived from the
+ * GNU C library, by Bryan Henderson in October 1996. The copyright
+ * notice from that file is below.
*/
/*
* Copyright (c) 1983, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -55,82 +55,92 @@
* cannot distinguish between failure and a local broadcast address.
*/
int
-inet_aton(const char *cp, struct in_addr *addr)
+inet_aton(const char *cp, struct in_addr * addr)
{
register u_long val;
- register int base, n;
- register char c;
- u_int parts[4];
+ register int base,
+ n;
+ register char c;
+ u_int parts[4];
register u_int *pp = parts;
- for (;;) {
+ for (;;)
+ {
+
/*
- * Collect number up to ``.''.
- * Values are specified as for C:
+ * Collect number up to ``.''. Values are specified as for C:
* 0x=hex, 0=octal, other=decimal.
*/
- val = 0; base = 10;
- if (*cp == '0') {
+ val = 0;
+ base = 10;
+ if (*cp == '0')
+ {
if (*++cp == 'x' || *cp == 'X')
base = 16, cp++;
else
base = 8;
}
- while ((c = *cp) != '\0') {
- if (isascii(c) && isdigit(c)) {
+ while ((c = *cp) != '\0')
+ {
+ if (isascii(c) && isdigit(c))
+ {
val = (val * base) + (c - '0');
cp++;
continue;
}
- if (base == 16 && isascii(c) && isxdigit(c)) {
- val = (val << 4) +
+ if (base == 16 && isascii(c) && isxdigit(c))
+ {
+ val = (val << 4) +
(c + 10 - (islower(c) ? 'a' : 'A'));
cp++;
continue;
}
break;
}
- if (*cp == '.') {
+ if (*cp == '.')
+ {
+
/*
- * Internet format:
- * a.b.c.d
- * a.b.c (with c treated as 16-bits)
- * a.b (with b treated as 24 bits)
+ * Internet format: a.b.c.d a.b.c (with c treated as
+ * 16-bits) a.b (with b treated as 24 bits)
*/
if (pp >= parts + 3 || val > 0xff)
return (0);
*pp++ = val, cp++;
- } else
+ }
+ else
break;
}
+
/*
* Check for trailing characters.
*/
if (*cp && (!isascii(*cp) || !isspace(*cp)))
return (0);
+
/*
- * Concoct the address according to
- * the number of parts specified.
+ * Concoct the address according to the number of parts specified.
*/
n = pp - parts + 1;
- switch (n) {
+ switch (n)
+ {
- case 1: /* a -- 32 bits */
+ case 1: /* a -- 32 bits */
break;
- case 2: /* a.b -- 8.24 bits */
+ case 2: /* a.b -- 8.24 bits */
if (val > 0xffffff)
return (0);
val |= parts[0] << 24;
break;
- case 3: /* a.b.c -- 8.8.16 bits */
+ case 3: /* a.b.c -- 8.8.16 bits */
if (val > 0xffff)
return (0);
val |= (parts[0] << 24) | (parts[1] << 16);
break;
- case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
if (val > 0xff)
return (0);
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
diff --git a/src/backend/port/inet_aton.h b/src/backend/port/inet_aton.h
index 6909bd2b12d..b1df9a8ff3d 100644
--- a/src/backend/port/inet_aton.h
+++ b/src/backend/port/inet_aton.h
@@ -1,2 +1,2 @@
int
-inet_aton(const char *cp, struct in_addr *addr);
+ inet_aton(const char *cp, struct in_addr * addr);
diff --git a/src/backend/port/irix5/port-protos.h b/src/backend/port/irix5/port-protos.h
index 3f580758416..be894ed5b12 100644
--- a/src/backend/port/irix5/port-protos.h
+++ b/src/backend/port/irix5/port-protos.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for Irix 5
+ * port-specific prototypes for Irix 5
*
*
* Copyright (c) 1994, Regents of the University of California
@@ -14,24 +14,24 @@
#define PORT_PROTOS_H
#include <dlfcn.h>
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
/* dynloader.c */
/*
* Dynamic Loader on SunOS 4.
*
- * this dynamic loader uses the system dynamic loading interface for shared
+ * this dynamic loader uses the system dynamic loading interface for shared
* libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared
* library as the file to be dynamically loaded.
*
*/
#define pg_dlopen(f) dlopen(f,1)
-#define pg_dlsym dlsym
-#define pg_dlclose dlclose
-#define pg_dlerror dlerror
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
/* port.c */
-extern long random(void);
+extern long random(void);
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/irix5/port.c b/src/backend/port/irix5/port.c
index 82303ed7fcb..6c60ade72f9 100644
--- a/src/backend/port/irix5/port.c
+++ b/src/backend/port/irix5/port.c
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * Irix5-specific routines
+ * Irix5-specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/port/sparc_solaris/port.c,v 1.2 1995/03/17 06:40:19 andrew Exp
+ * /usr/local/devel/pglite/cvs/src/backend/port/sparc_solaris/port.c,v 1.2 1995/03/17 06:40:19 andrew Exp
*
*-------------------------------------------------------------------------
*/
-#include <math.h> /* for pow() prototype */
+#include <math.h> /* for pow() prototype */
#include <errno.h>
diff --git a/src/backend/port/linux/dynloader.c b/src/backend/port/linux/dynloader.c
index a3b551b6f95..adb13b40194 100644
--- a/src/backend/port/linux/dynloader.c
+++ b/src/backend/port/linux/dynloader.c
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* dynloader.c--
- * Dynamic Loader for Postgres for Linux, generated from those for
- * Ultrix.
+ * Dynamic Loader for Postgres for Linux, generated from those for
+ * Ultrix.
*
- * You need to install the dld library on your Linux system!
+ * You need to install the dld library on your Linux system!
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/linux/Attic/dynloader.c,v 1.2 1997/02/06 08:39:40 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/linux/Attic/dynloader.c,v 1.3 1997/09/07 04:46:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,82 +23,92 @@
#include "utils/elog.h"
#include "fmgr.h"
-extern char pg_pathname[];
+extern char pg_pathname[];
-void *
+void *
pg_dlopen(char *filename)
{
#ifndef HAVE_DLD_H
- elog(WARN, "dynamic load not supported");
- return(NULL);
+ elog(WARN, "dynamic load not supported");
+ return (NULL);
#else
- static int dl_initialized= 0;
+ static int dl_initialized = 0;
- /*
- * initializes the dynamic loader with the executable's pathname.
- * (only needs to do this the first time pg_dlopen is called.)
- */
- if (!dl_initialized) {
- if (dld_init (dld_find_executable (pg_pathname))) {
- return NULL;
- }
/*
- * if there are undefined symbols, we want dl to search from the
- * following libraries also.
+ * initializes the dynamic loader with the executable's pathname.
+ * (only needs to do this the first time pg_dlopen is called.)
*/
- dl_initialized= 1;
- }
-
- /*
- * link the file, then check for undefined symbols!
- */
- if (dld_link(filename)) {
- return NULL;
- }
+ if (!dl_initialized)
+ {
+ if (dld_init(dld_find_executable(pg_pathname)))
+ {
+ return NULL;
+ }
- /*
- * If undefined symbols: try to link with the C and math libraries!
- * This could be smarter, if the dynamic linker was able to handle
- * shared libs!
- */
- if(dld_undefined_sym_count > 0) {
- if (dld_link("/usr/lib/libc.a")) {
- elog(NOTICE, "dld: Cannot link C library!");
- return NULL;
+ /*
+ * if there are undefined symbols, we want dl to search from the
+ * following libraries also.
+ */
+ dl_initialized = 1;
}
- if(dld_undefined_sym_count > 0) {
- if (dld_link("/usr/lib/libm.a")) {
- elog(NOTICE, "dld: Cannot link math library!");
+
+ /*
+ * link the file, then check for undefined symbols!
+ */
+ if (dld_link(filename))
+ {
return NULL;
- }
- if(dld_undefined_sym_count > 0) {
- int count = dld_undefined_sym_count;
- char **list= dld_list_undefined_sym();
+ }
- /* list the undefined symbols, if any */
- elog(NOTICE, "dld: Undefined:");
- do {
- elog(NOTICE, " %s", *list);
- list++;
- count--;
- } while(count > 0);
+ /*
+ * If undefined symbols: try to link with the C and math libraries!
+ * This could be smarter, if the dynamic linker was able to handle
+ * shared libs!
+ */
+ if (dld_undefined_sym_count > 0)
+ {
+ if (dld_link("/usr/lib/libc.a"))
+ {
+ elog(NOTICE, "dld: Cannot link C library!");
+ return NULL;
+ }
+ if (dld_undefined_sym_count > 0)
+ {
+ if (dld_link("/usr/lib/libm.a"))
+ {
+ elog(NOTICE, "dld: Cannot link math library!");
+ return NULL;
+ }
+ if (dld_undefined_sym_count > 0)
+ {
+ int count = dld_undefined_sym_count;
+ char **list = dld_list_undefined_sym();
- dld_unlink_by_file(filename, 1);
- return NULL;
- }
+ /* list the undefined symbols, if any */
+ elog(NOTICE, "dld: Undefined:");
+ do
+ {
+ elog(NOTICE, " %s", *list);
+ list++;
+ count--;
+ } while (count > 0);
+
+ dld_unlink_by_file(filename, 1);
+ return NULL;
+ }
+ }
}
- }
- return (void *) strdup(filename);
+ return (void *) strdup(filename);
#endif
}
-char *
+char *
pg_dlerror()
{
#ifndef HAVE_DLD_H
- return("dynaloader unspported");
+ return ("dynaloader unspported");
#else
- return dld_strerror(dld_errno);
+ return dld_strerror(dld_errno);
#endif
}
diff --git a/src/backend/port/linux/port-protos.h b/src/backend/port/linux/port-protos.h
index 76f02b48fe9..f5af9beecee 100644
--- a/src/backend/port/linux/port-protos.h
+++ b/src/backend/port/linux/port-protos.h
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for SunOS 4
+ * port-specific prototypes for SunOS 4
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.2 1997/02/06 08:39:53 scrappy Exp $
+ * $Id: port-protos.h,v 1.3 1997/09/07 04:46:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PORT_PROTOS_H
#define PORT_PROTOS_H
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
#ifdef LINUX_ELF
#include "dlfcn.h"
@@ -22,21 +22,21 @@
/* dynloader.c */
#ifndef LINUX_ELF
-# ifndef HAVE_DLD_H
-#define pg_dlsym(handle, funcname) (NULL)
-# define pg_dlclose(handle) ({})
-# else
-#define pg_dlsym(handle, funcname) ((func_ptr) dld_get_func((funcname)))
-# define pg_dlclose(handle) ({ dld_unlink_by_file(handle, 1); free(handle); })
-# endif
+#ifndef HAVE_DLD_H
+#define pg_dlsym(handle, funcname) (NULL)
+#define pg_dlclose(handle) ({})
#else
-/* #define pg_dlopen(f) dlopen(f, 1) */
-#define pg_dlopen(f) dlopen(f, 2)
-#define pg_dlsym dlsym
-#define pg_dlclose dlclose
-#define pg_dlerror dlerror
+#define pg_dlsym(handle, funcname) ((func_ptr) dld_get_func((funcname)))
+#define pg_dlclose(handle) ({ dld_unlink_by_file(handle, 1); free(handle); })
+#endif
+#else
+/* #define pg_dlopen(f) dlopen(f, 1) */
+#define pg_dlopen(f) dlopen(f, 2)
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
#endif
/* port.c */
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/linux/port.c b/src/backend/port/linux/port.c
index e4c5edfb9e5..942340f40fd 100644
--- a/src/backend/port/linux/port.c
+++ b/src/backend/port/linux/port.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * Linux-specific routines
+ * Linux-specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/linux/Attic/port.c,v 1.1.1.1 1996/07/09 06:21:44 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/linux/Attic/port.c,v 1.2 1997/09/07 04:46:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
diff --git a/src/backend/port/linuxalpha/machine.h b/src/backend/port/linuxalpha/machine.h
index 78d45d41ba9..eee148e390c 100644
--- a/src/backend/port/linuxalpha/machine.h
+++ b/src/backend/port/linuxalpha/machine.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* machine.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: machine.h,v 1.1 1997/03/14 06:01:21 scrappy Exp $
+ * $Id: machine.h,v 1.2 1997/09/07 04:46:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
diff --git a/src/backend/port/linuxalpha/port-protos.h b/src/backend/port/linuxalpha/port-protos.h
index 7bcbaf020d1..350c0c52809 100644
--- a/src/backend/port/linuxalpha/port-protos.h
+++ b/src/backend/port/linuxalpha/port-protos.h
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for SunOS 4
+ * port-specific prototypes for SunOS 4
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.1 1997/03/14 06:01:33 scrappy Exp $
+ * $Id: port-protos.h,v 1.2 1997/09/07 04:46:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PORT_PROTOS_H
#define PORT_PROTOS_H
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
#include "dlfcn.h"
-#define pg_dlopen(f) dlopen(f, 2)
-#define pg_dlsym dlsym
-#define pg_dlclose dlclose
-#define pg_dlerror dlerror
+#define pg_dlopen(f) dlopen(f, 2)
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/linuxalpha/port.c b/src/backend/port/linuxalpha/port.c
index a9886814449..8ddc6ddc1e3 100644
--- a/src/backend/port/linuxalpha/port.c
+++ b/src/backend/port/linuxalpha/port.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * Linux-specific routines
+ * Linux-specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/linuxalpha/Attic/port.c,v 1.1 1997/03/14 06:01:40 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/linuxalpha/Attic/port.c,v 1.2 1997/09/07 04:46:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
diff --git a/src/backend/port/nextstep/dynloader.c b/src/backend/port/nextstep/dynloader.c
index af183d436de..c37508f7f19 100644
--- a/src/backend/port/nextstep/dynloader.c
+++ b/src/backend/port/nextstep/dynloader.c
@@ -2,71 +2,80 @@
#include <streams/streams.h>
#include <stdlib.h>
-static char* lastError = NULL;
+static char *lastError = NULL;
-static NXStream* OpenError()
+static NXStream *
+OpenError()
{
- return NXOpenMemory(NULL, 0, NX_WRITEONLY);
+ return NXOpenMemory(NULL, 0, NX_WRITEONLY);
}
-static void CloseError(NXStream* s)
+static void
+CloseError(NXStream * s)
{
- if (s)
- NXCloseMemory (s, NX_FREEBUFFER);
+ if (s)
+ NXCloseMemory(s, NX_FREEBUFFER);
}
-static void TransferError(NXStream* s)
+static void
+TransferError(NXStream * s)
{
- char *buffer;
- int len, maxlen;
+ char *buffer;
+ int len,
+ maxlen;
- if (lastError)
- free (lastError);
- NXGetMemoryBuffer (s, &buffer, &len, &maxlen);
- lastError = malloc (len + 1);
- strcpy (lastError, buffer);
+ if (lastError)
+ free(lastError);
+ NXGetMemoryBuffer(s, &buffer, &len, &maxlen);
+ lastError = malloc(len + 1);
+ strcpy(lastError, buffer);
}
-void* next_dlopen(char* name)
+void *
+next_dlopen(char *name)
{
- int rld_success;
- NXStream* errorStream;
- char* result = NULL;
- char **p;
-
- errorStream = OpenError();
- p = calloc (2, sizeof(void*));
- p[0] = name;
- rld_success = rld_load(errorStream, NULL, p, NULL);
- free (p);
+ int rld_success;
+ NXStream *errorStream;
+ char *result = NULL;
+ char **p;
- if (!rld_success) {
- TransferError (errorStream);
- result = (char*)1;
- }
- CloseError (errorStream);
- return result;
+ errorStream = OpenError();
+ p = calloc(2, sizeof(void *));
+ p[0] = name;
+ rld_success = rld_load(errorStream, NULL, p, NULL);
+ free(p);
+
+ if (!rld_success)
+ {
+ TransferError(errorStream);
+ result = (char *) 1;
+ }
+ CloseError(errorStream);
+ return result;
}
-int next_dlclose(void* handle)
+int
+next_dlclose(void *handle)
{
- return 0;
+ return 0;
}
-void* next_dlsym (void *handle, char *symbol)
+void *
+next_dlsym(void *handle, char *symbol)
{
- NXStream* errorStream = OpenError();
- char symbuf[1024];
- unsigned long symref = 0;
+ NXStream *errorStream = OpenError();
+ char symbuf[1024];
+ unsigned long symref = 0;
- sprintf(symbuf, "_%s", symbol);
- if (!rld_lookup (errorStream, symbuf, &symref))
- TransferError(errorStream);
- CloseError(errorStream);
- return (void*) symref;
+ sprintf(symbuf, "_%s", symbol);
+ if (!rld_lookup(errorStream, symbuf, &symref))
+ TransferError(errorStream);
+ CloseError(errorStream);
+ return (void *) symref;
}
-char* next_dlerror(void)
+char *
+next_dlerror(void)
{
- return lastError;
+ return lastError;
}
diff --git a/src/backend/port/nextstep/port-protos.h b/src/backend/port/nextstep/port-protos.h
index 93fec7642f0..ce17beb69a6 100644
--- a/src/backend/port/nextstep/port-protos.h
+++ b/src/backend/port/nextstep/port-protos.h
@@ -1,27 +1,27 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for NeXT
+ * port-specific prototypes for NeXT
*
-
+
-------------------------------------------------------------------------
*/
#ifndef PORT_PROTOS_H
#define PORT_PROTOS_H
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
-void* next_dlopen(char* name);
-int next_dlclose(void* handle);
-void* next_dlsym (void *handle, char *symbol);
-char* next_dlerror(void);
+void *next_dlopen(char *name);
+int next_dlclose(void *handle);
+void *next_dlsym(void *handle, char *symbol);
+char *next_dlerror(void);
-#define pg_dlopen(f) next_dlopen
-#define pg_dlsym next_dlsym
-#define pg_dlclose next_dlclose
-#define pg_dlerror next_dlerror
+#define pg_dlopen(f) next_dlopen
+#define pg_dlsym next_dlsym
+#define pg_dlclose next_dlclose
+#define pg_dlerror next_dlerror
/* port.c */
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/nextstep/port.c b/src/backend/port/nextstep/port.c
index 3da87b32eb8..baf026d5d1d 100644
--- a/src/backend/port/nextstep/port.c
+++ b/src/backend/port/nextstep/port.c
@@ -1,58 +1,65 @@
#ifndef _POSIX_SOURCE
-# include <libc.h>
+#include <libc.h>
#else
-# include <unistd.h>
-# include <stdlib.h>
+#include <unistd.h>
+#include <stdlib.h>
#endif
#include <string.h>
#include <sys/signal.h>
-void putenv(char* name)
+void
+putenv(char *name)
{
- extern char** environ;
- static int was_mallocated = 0;
- int size;
-
- /* Compute the size of environ array including the final NULL */
- for (size = 1; environ[size++];)
- /* nothing */;
-
- if (!was_mallocated) {
- char** tmp = environ;
- int i;
-
- was_mallocated = 1;
- environ = malloc (size * sizeof(char*));
- for (i = 0; i < size; i++)
- environ[i] = tmp[i];
- }
-
- environ = realloc (environ, (size + 1) * sizeof (char*));
- environ[size - 1] = strcpy (malloc (strlen (name) + 1), name);
- environ[size] = NULL;
+ extern char **environ;
+ static int was_mallocated = 0;
+ int size;
+
+ /* Compute the size of environ array including the final NULL */
+ for (size = 1; environ[size++];)
+ /* nothing */ ;
+
+ if (!was_mallocated)
+ {
+ char **tmp = environ;
+ int i;
+
+ was_mallocated = 1;
+ environ = malloc(size * sizeof(char *));
+ for (i = 0; i < size; i++)
+ environ[i] = tmp[i];
+ }
+
+ environ = realloc(environ, (size + 1) * sizeof(char *));
+ environ[size - 1] = strcpy(malloc(strlen(name) + 1), name);
+ environ[size] = NULL;
}
-char* strdup (const char* string)
+char *
+strdup(const char *string)
{
- return strcpy (malloc (strlen (string) + 1), string);
+ return strcpy(malloc(strlen(string) + 1), string);
}
#ifndef _POSIX_SOURCE
-int sigaddset(int *set, int signo)
+int
+sigaddset(int *set, int signo)
{
- *set |= sigmask(signo);
- return *set;
+ *set |= sigmask(signo);
+ return *set;
}
-int sigemptyset(int *set)
+int
+sigemptyset(int *set)
{
- return (*set = 0);
+ return (*set = 0);
}
-char *getcwd(char *buf, size_t size)
+char *
+getcwd(char *buf, size_t size)
{
- return getwd (buf);
+ return getwd(buf);
}
+
#endif
diff --git a/src/backend/port/sco/port-protos.h b/src/backend/port/sco/port-protos.h
index 17e3b02a265..9526f7c747d 100644
--- a/src/backend/port/sco/port-protos.h
+++ b/src/backend/port/sco/port-protos.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for SCO 3.2v5.2
+ * port-specific prototypes for SCO 3.2v5.2
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.1 1997/07/28 01:33:55 momjian Exp $
+ * $Id: port-protos.h,v 1.2 1997/09/07 04:46:41 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,23 +14,23 @@
#define PORT_PROTOS_H
#include <dlfcn.h>
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
/* dynloader.c */
/*
* Dynamic Loader on SCO 3.2v5.0.2
*
- * this dynamic loader uses the system dynamic loading interface for shared
+ * this dynamic loader uses the system dynamic loading interface for shared
* libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared
* library as the file to be dynamically loaded.
*
*/
#define pg_dlopen(f) dlopen(f,1)
-#define pg_dlsym dlsym
-#define pg_dlclose dlclose
-#define pg_dlerror dlerror
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
/* port.c */
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/sco/port.c b/src/backend/port/sco/port.c
index 3f1b84d6189..d1c868e8426 100644
--- a/src/backend/port/sco/port.c
+++ b/src/backend/port/sco/port.c
@@ -1,57 +1,60 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * SCO 3.2v5.0.2 specific routines
+ * SCO 3.2v5.0.2 specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/port/svr4/port.c,v 1.2 1995/03/17 06:40:19 andrew Exp
+ * /usr/local/devel/pglite/cvs/src/backend/port/svr4/port.c,v 1.2 1995/03/17 06:40:19 andrew Exp
*
*-------------------------------------------------------------------------
*/
#include <unistd.h>
-#include <math.h> /* for pow() prototype */
+#include <math.h> /* for pow() prototype */
#include <errno.h>
#include "rusagestub.h"
int
-getrusage(int who, struct rusage *rusage)
+getrusage(int who, struct rusage * rusage)
{
- struct tms tms;
- register int tick_rate = CLK_TCK; /* ticks per second */
- clock_t u, s;
+ struct tms tms;
+ register int tick_rate = CLK_TCK; /* ticks per second */
+ clock_t u,
+ s;
- if (rusage == (struct rusage *) NULL) {
- errno = EFAULT;
- return(-1);
- }
- if (times(&tms) < 0) {
- /* errno set by times */
- return(-1);
- }
- switch (who) {
- case RUSAGE_SELF:
- u = tms.tms_utime;
- s = tms.tms_stime;
- break;
- case RUSAGE_CHILDREN:
- u = tms.tms_cutime;
- s = tms.tms_cstime;
- break;
- default:
- errno = EINVAL;
- return(-1);
- }
+ if (rusage == (struct rusage *) NULL)
+ {
+ errno = EFAULT;
+ return (-1);
+ }
+ if (times(&tms) < 0)
+ {
+ /* errno set by times */
+ return (-1);
+ }
+ switch (who)
+ {
+ case RUSAGE_SELF:
+ u = tms.tms_utime;
+ s = tms.tms_stime;
+ break;
+ case RUSAGE_CHILDREN:
+ u = tms.tms_cutime;
+ s = tms.tms_cstime;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
#define TICK_TO_SEC(T, RATE) ((T)/(RATE))
-#define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE)
- rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
- rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
- rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
- rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
- return(0);
+#define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE)
+ rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
+ rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
+ rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
+ rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
+ return (0);
}
-
diff --git a/src/backend/port/sco/rusagestub.h b/src/backend/port/sco/rusagestub.h
index d2393eb792d..5eda998802e 100644
--- a/src/backend/port/sco/rusagestub.h
+++ b/src/backend/port/sco/rusagestub.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* rusagestub.h--
- * Stubs for getrusage(3).
+ * Stubs for getrusage(3).
*
*
* Copyright (c) 1994, Regents of the University of California
@@ -13,18 +13,19 @@
#ifndef RUSAGESTUB_H
#define RUSAGESTUB_H
-#include <sys/time.h> /* for struct timeval */
-#include <sys/times.h> /* for struct tms */
-#include <limits.h> /* for CLK_TCK */
+#include <sys/time.h> /* for struct timeval */
+#include <sys/times.h> /* for struct tms */
+#include <limits.h> /* for CLK_TCK */
-#define RUSAGE_SELF 0
-#define RUSAGE_CHILDREN -1
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN -1
-struct rusage {
- struct timeval ru_utime; /* user time used */
- struct timeval ru_stime; /* system time used */
+struct rusage
+{
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
};
-extern int getrusage(int who, struct rusage *rusage);
+extern int getrusage(int who, struct rusage * rusage);
-#endif /* RUSAGESTUB_H */
+#endif /* RUSAGESTUB_H */
diff --git a/src/backend/port/sparc_solaris/port-protos.h b/src/backend/port/sparc_solaris/port-protos.h
index c2cbf5803b5..95239173462 100644
--- a/src/backend/port/sparc_solaris/port-protos.h
+++ b/src/backend/port/sparc_solaris/port-protos.h
@@ -1,52 +1,52 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for SunOS 4
+ * port-specific prototypes for SunOS 4
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.4 1997/04/15 18:18:33 scrappy Exp $
+ * $Id: port-protos.h,v 1.5 1997/09/07 04:46:50 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PORT_PROTOS_H
#define PORT_PROTOS_H
-#include <netinet/in.h> /* For struct in_addr */
+#include <netinet/in.h> /* For struct in_addr */
#include <arpa/inet.h>
#include <dlfcn.h>
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
/* dynloader.c */
/*
* Dynamic Loader on SunOS 4.
*
- * this dynamic loader uses the system dynamic loading interface for shared
+ * this dynamic loader uses the system dynamic loading interface for shared
* libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared
* library as the file to be dynamically loaded.
*
*/
#define pg_dlopen(f) dlopen(f,1)
-#define pg_dlsym dlsym
-#define pg_dlclose dlclose
-#define pg_dlerror dlerror
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
/* port.c */
-extern long random(void);
-extern void srandom(int seed);
+extern long random(void);
+extern void srandom(int seed);
/* inet_aton.c in backend/port directory */
-extern int inet_aton(const char *cp, struct in_addr *addr);
+extern int inet_aton(const char *cp, struct in_addr * addr);
/* In system library, but can't find prototype in system library .h files */
-extern int gethostname(char *name, int namelen);
+extern int gethostname(char *name, int namelen);
/* In system library, but can't find prototype in system library .h files */
#include <sys/resource.h>
-extern int getrusage(int who, struct rusage *rusage);
+extern int getrusage(int who, struct rusage * rusage);
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/sparc_solaris/port.c b/src/backend/port/sparc_solaris/port.c
index 8710ec95451..7f19a1ae237 100644
--- a/src/backend/port/sparc_solaris/port.c
+++ b/src/backend/port/sparc_solaris/port.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * SunOS5-specific routines
+ * SunOS5-specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/sparc_solaris/Attic/port.c,v 1.4 1997/04/15 18:18:45 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/sparc_solaris/Attic/port.c,v 1.5 1997/09/07 04:46:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <math.h> /* for pow() prototype */
+#include <math.h> /* for pow() prototype */
#include <stdlib.h>
#include <errno.h>
@@ -20,55 +20,60 @@
#include "port-protos.h"
#ifndef HAVE_GETRUSAGE
#include "rusagestub.h"
-#endif /* HAVE_GETRUSAGE */
+#endif /* HAVE_GETRUSAGE */
long
random()
{
- return(lrand48());
+ return (lrand48());
}
void
srandom(int seed)
{
- srand48((long int) seed);
+ srand48((long int) seed);
}
#ifndef HAVE_GETRUSAGE
int
-getrusage(int who, struct rusage *rusage)
+getrusage(int who, struct rusage * rusage)
{
- struct tms tms;
- register int tick_rate = CLK_TCK; /* ticks per second */
- clock_t u, s;
+ struct tms tms;
+ register int tick_rate = CLK_TCK; /* ticks per second */
+ clock_t u,
+ s;
- if (rusage == (struct rusage *) NULL) {
- errno = EFAULT;
- return(-1);
- }
- if (times(&tms) < 0) {
- /* errno set by times */
- return(-1);
- }
- switch (who) {
- case RUSAGE_SELF:
- u = tms.tms_utime;
- s = tms.tms_stime;
- break;
- case RUSAGE_CHILDREN:
- u = tms.tms_cutime;
- s = tms.tms_cstime;
- break;
- default:
- errno = EINVAL;
- return(-1);
- }
+ if (rusage == (struct rusage *) NULL)
+ {
+ errno = EFAULT;
+ return (-1);
+ }
+ if (times(&tms) < 0)
+ {
+ /* errno set by times */
+ return (-1);
+ }
+ switch (who)
+ {
+ case RUSAGE_SELF:
+ u = tms.tms_utime;
+ s = tms.tms_stime;
+ break;
+ case RUSAGE_CHILDREN:
+ u = tms.tms_cutime;
+ s = tms.tms_cstime;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
#define TICK_TO_SEC(T, RATE) ((T)/(RATE))
-#define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE)
- rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
- rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
- rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
- rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
- return(0);
+#define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE)
+ rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
+ rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
+ rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
+ rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
+ return (0);
}
-#endif /* HAVE_GETRUSAGE */
+
+#endif /* HAVE_GETRUSAGE */
diff --git a/src/backend/port/sparc_solaris/rusagestub.h b/src/backend/port/sparc_solaris/rusagestub.h
index 5e413bd0d9a..87957a45eac 100644
--- a/src/backend/port/sparc_solaris/rusagestub.h
+++ b/src/backend/port/sparc_solaris/rusagestub.h
@@ -1,30 +1,31 @@
/*-------------------------------------------------------------------------
*
* rusagestub.h--
- * Stubs for getrusage(3).
+ * Stubs for getrusage(3).
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rusagestub.h,v 1.1.1.1 1996/07/09 06:21:45 scrappy Exp $
+ * $Id: rusagestub.h,v 1.2 1997/09/07 04:46:56 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef RUSAGESTUB_H
#define RUSAGESTUB_H
-#include <sys/time.h> /* for struct timeval */
-#include <sys/times.h> /* for struct tms */
-#include <limits.h> /* for CLK_TCK */
+#include <sys/time.h> /* for struct timeval */
+#include <sys/times.h> /* for struct tms */
+#include <limits.h> /* for CLK_TCK */
-#define RUSAGE_SELF 0
-#define RUSAGE_CHILDREN -1
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN -1
-struct rusage {
- struct timeval ru_utime; /* user time used */
- struct timeval ru_stime; /* system time used */
+struct rusage
+{
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
};
-extern int getrusage(int who, struct rusage *rusage);
+extern int getrusage(int who, struct rusage * rusage);
-#endif /* RUSAGESTUB_H */
+#endif /* RUSAGESTUB_H */
diff --git a/src/backend/port/strerror.c b/src/backend/port/strerror.c
index 7ec842e366e..5bcd3cb4527 100644
--- a/src/backend/port/strerror.c
+++ b/src/backend/port/strerror.c
@@ -7,24 +7,23 @@
* modified for ANSI by D'Arcy J.M. Cain
*/
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
-extern const char * const sys_errlist[];
-extern int sys_nerr;
+extern const char *const sys_errlist[];
+extern int sys_nerr;
-const char *
+const char *
strerror(int errnum)
{
- static char buf[24];
+ static char buf[24];
- if (errnum < 0 || errnum > sys_nerr)
- {
- sprintf(buf, "unknown error %d", errnum);
- return(buf);
- }
+ if (errnum < 0 || errnum > sys_nerr)
+ {
+ sprintf(buf, "unknown error %d", errnum);
+ return (buf);
+ }
- return(sys_errlist[errnum]);
+ return (sys_errlist[errnum]);
}
-
diff --git a/src/backend/port/sunos4/float.h b/src/backend/port/sunos4/float.h
index eb9ec5c2a2e..e81d29557fe 100644
--- a/src/backend/port/sunos4/float.h
+++ b/src/backend/port/sunos4/float.h
@@ -1,30 +1,30 @@
/*-------------------------------------------------------------------------
*
* float.h--
- * definitions for ANSI floating point
+ * definitions for ANSI floating point
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: float.h,v 1.1 1997/07/28 00:08:35 momjian Exp $
+ * $Id: float.h,v 1.2 1997/09/07 04:46:58 momjian Exp $
*
* NOTES
- * These come straight out of ANSI X3.159-1989 (p.18) and
- * would be unnecessary if SunOS 4 were ANSI-compliant.
+ * These come straight out of ANSI X3.159-1989 (p.18) and
+ * would be unnecessary if SunOS 4 were ANSI-compliant.
*
- * This is only a partial listing because I'm lazy to type
- * the whole thing in.
+ * This is only a partial listing because I'm lazy to type
+ * the whole thing in.
*
*-------------------------------------------------------------------------
*/
#ifndef FLOAT_H
#define FLOAT_H
-#define FLT_DIG 6
-#define FLT_MIN ((float) 1.17549435e-38)
-#define FLT_MAX ((float) 3.40282347e+38)
-#define DBL_DIG 15
-#define DBL_MIN 2.2250738585072014e-308
-#define DBL_MAX 1.7976931348623157e+308
+#define FLT_DIG 6
+#define FLT_MIN ((float) 1.17549435e-38)
+#define FLT_MAX ((float) 3.40282347e+38)
+#define DBL_DIG 15
+#define DBL_MIN 2.2250738585072014e-308
+#define DBL_MAX 1.7976931348623157e+308
-#endif /* FLOAT_H */
+#endif /* FLOAT_H */
diff --git a/src/backend/port/sunos4/port-protos.h b/src/backend/port/sunos4/port-protos.h
index ce1de05aa02..33ec1e40e93 100644
--- a/src/backend/port/sunos4/port-protos.h
+++ b/src/backend/port/sunos4/port-protos.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for SunOS 4
+ * port-specific prototypes for SunOS 4
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.1 1997/07/28 00:08:39 momjian Exp $
+ * $Id: port-protos.h,v 1.2 1997/09/07 04:47:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,21 +14,21 @@
#define PORT_PROTOS_H
#include <dlfcn.h>
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
/* dynloader.c */
/*
* Dynamic Loader on SunOS 4.
*
- * this dynamic loader uses the system dynamic loading interface for shared
+ * this dynamic loader uses the system dynamic loading interface for shared
* libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared
* library as the file to be dynamically loaded.
*
*/
-#define pg_dlopen(f) dlopen(f, 1)
-#define pg_dlsym dlsym
-#define pg_dlclose dlclose
-#define pg_dlerror dlerror
+#define pg_dlopen(f) dlopen(f, 1)
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/sunos4/strtol.c b/src/backend/port/sunos4/strtol.c
index 5850848e66a..c788d94bd50 100644
--- a/src/backend/port/sunos4/strtol.c
+++ b/src/backend/port/sunos4/strtol.c
@@ -6,22 +6,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -32,8 +32,9 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strtol.c 5.4 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
+static char sccsid[] = "@(#)strtol.c 5.4 (Berkeley) 2/23/91";
+
+#endif /* LIBC_SCCS and not lint */
#include <limits.h>
#include <ctype.h>
@@ -50,31 +51,37 @@ static char sccsid[] = "@(#)strtol.c 5.4 (Berkeley) 2/23/91";
*/
long
strtol(nptr, endptr, base)
- const char *nptr;
- char **endptr;
- register int base;
+const char *nptr;
+char **endptr;
+register int base;
{
register const char *s = nptr;
register unsigned long acc;
- register int c;
+ register int c;
register unsigned long cutoff;
- register int neg = 0, any, cutlim;
+ register int neg = 0,
+ any,
+ cutlim;
/*
- * Skip white space and pick up leading +/- sign if any.
- * If base is 0, allow 0x for hex and 0 for octal, else
- * assume decimal; if base is already 16, allow 0x.
+ * Skip white space and pick up leading +/- sign if any. If base is 0,
+ * allow 0x for hex and 0 for octal, else assume decimal; if base is
+ * already 16, allow 0x.
*/
- do {
+ do
+ {
c = *s++;
} while (isspace(c));
- if (c == '-') {
+ if (c == '-')
+ {
neg = 1;
c = *s++;
- } else if (c == '+')
+ }
+ else if (c == '+')
c = *s++;
if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
+ c == '0' && (*s == 'x' || *s == 'X'))
+ {
c = s[1];
s += 2;
base = 16;
@@ -83,26 +90,26 @@ strtol(nptr, endptr, base)
base = c == '0' ? 8 : 10;
/*
- * Compute the cutoff value between legal numbers and illegal
- * numbers. That is the largest legal value, divided by the
- * base. An input number that is greater than this value, if
- * followed by a legal input character, is too big. One that
- * is equal to this value may be valid or not; the limit
- * between valid and invalid numbers is then based on the last
- * digit. For instance, if the range for longs is
- * [-2147483648..2147483647] and the input base is 10,
- * cutoff will be set to 214748364 and cutlim to either
- * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
- * a value > 214748364, or equal but the next digit is > 7 (or 8),
- * the number is too big, and we will return a range error.
+ * Compute the cutoff value between legal numbers and illegal numbers.
+ * That is the largest legal value, divided by the base. An input
+ * number that is greater than this value, if followed by a legal
+ * input character, is too big. One that is equal to this value may
+ * be valid or not; the limit between valid and invalid numbers is
+ * then based on the last digit. For instance, if the range for longs
+ * is [-2147483648..2147483647] and the input base is 10, cutoff will
+ * be set to 214748364 and cutlim to either 7 (neg==0) or 8 (neg==1),
+ * meaning that if we have accumulated a value > 214748364, or equal
+ * but the next digit is > 7 (or 8), the number is too big, and we
+ * will return a range error.
*
* Set any if any `digits' consumed; make it negative to indicate
* overflow.
*/
- cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
- cutlim = cutoff % (unsigned long)base;
- cutoff /= (unsigned long)base;
- for (acc = 0, any = 0;; c = *s++) {
+ cutoff = neg ? -(unsigned long) LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long) base;
+ cutoff /= (unsigned long) base;
+ for (acc = 0, any = 0;; c = *s++)
+ {
if (isdigit(c))
c -= '0';
else if (isalpha(c))
@@ -113,18 +120,21 @@ strtol(nptr, endptr, base)
break;
if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
any = -1;
- else {
+ else
+ {
any = 1;
acc *= base;
acc += c;
}
}
- if (any < 0) {
+ if (any < 0)
+ {
acc = neg ? LONG_MIN : LONG_MAX;
errno = ERANGE;
- } else if (neg)
+ }
+ else if (neg)
acc = -acc;
if (endptr != 0)
- *endptr = any ? s - 1 : (char *)nptr;
+ *endptr = any ? s - 1 : (char *) nptr;
return (acc);
}
diff --git a/src/backend/port/svr4/port-protos.h b/src/backend/port/svr4/port-protos.h
index 4b992570acd..1baff088769 100644
--- a/src/backend/port/svr4/port-protos.h
+++ b/src/backend/port/svr4/port-protos.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for Intel x86/Intel SVR4
+ * port-specific prototypes for Intel x86/Intel SVR4
*
*
* Copyright (c) 1994, Regents of the University of California
@@ -14,25 +14,25 @@
#define PORT_PROTOS_H
#include <dlfcn.h>
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
/* dynloader.c */
/*
* Dynamic Loader on Intel x86/Intel SVR4.
*
- * this dynamic loader uses the system dynamic loading interface for shared
+ * this dynamic loader uses the system dynamic loading interface for shared
* libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared
* library as the file to be dynamically loaded.
*
*/
#define pg_dlopen(f) dlopen(f,RTLD_LAZY)
-#define pg_dlsym dlsym
-#define pg_dlclose dlclose
-#define pg_dlerror dlerror
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
/* port.c */
-extern long random(void);
-extern void srandom(int seed);
+extern long random(void);
+extern void srandom(int seed);
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/svr4/port.c b/src/backend/port/svr4/port.c
index 137cebbcbe3..0b38e2c4acd 100644
--- a/src/backend/port/svr4/port.c
+++ b/src/backend/port/svr4/port.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * Intel x86/Intel SVR4-specific routines
+ * Intel x86/Intel SVR4-specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/port/svr4/port.c,v 1.2 1995/03/17 06:40:19 andrew Exp
+ * /usr/local/devel/pglite/cvs/src/backend/port/svr4/port.c,v 1.2 1995/03/17 06:40:19 andrew Exp
*
*-------------------------------------------------------------------------
*/
-#include <math.h> /* for pow() prototype */
+#include <math.h> /* for pow() prototype */
#include <errno.h>
#include "rusagestub.h"
@@ -19,50 +19,54 @@
long
random()
{
- return(lrand48());
+ return (lrand48());
}
void
srandom(int seed)
{
- srand48((long int) seed);
+ srand48((long int) seed);
}
int
-getrusage(int who, struct rusage *rusage)
+getrusage(int who, struct rusage * rusage)
{
- struct tms tms;
- register int tick_rate = CLK_TCK; /* ticks per second */
- clock_t u, s;
+ struct tms tms;
+ register int tick_rate = CLK_TCK; /* ticks per second */
+ clock_t u,
+ s;
- if (rusage == (struct rusage *) NULL) {
- errno = EFAULT;
- return(-1);
- }
- if (times(&tms) < 0) {
- /* errno set by times */
- return(-1);
- }
- switch (who) {
- case RUSAGE_SELF:
- u = tms.tms_utime;
- s = tms.tms_stime;
- break;
- case RUSAGE_CHILDREN:
- u = tms.tms_cutime;
- s = tms.tms_cstime;
- break;
- default:
- errno = EINVAL;
- return(-1);
- }
+ if (rusage == (struct rusage *) NULL)
+ {
+ errno = EFAULT;
+ return (-1);
+ }
+ if (times(&tms) < 0)
+ {
+ /* errno set by times */
+ return (-1);
+ }
+ switch (who)
+ {
+ case RUSAGE_SELF:
+ u = tms.tms_utime;
+ s = tms.tms_stime;
+ break;
+ case RUSAGE_CHILDREN:
+ u = tms.tms_cutime;
+ s = tms.tms_cstime;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
#define TICK_TO_SEC(T, RATE) ((T)/(RATE))
-#define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE)
- rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
- rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
- rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
- rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
- return(0);
+#define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE)
+ rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
+ rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
+ rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
+ rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
+ return (0);
}
/*
@@ -78,15 +82,16 @@ getrusage(int who, struct rusage *rusage)
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strcasecmp.c 5.5 (Berkeley) 11/24/87";
-#endif /* LIBC_SCCS and not lint */
+static char sccsid[] = "@(#)strcasecmp.c 5.5 (Berkeley) 11/24/87";
+
+#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
/*
* This array is designed for mapping upper and lower case letter
- * together for a case independent comparison. The mappings are
+ * together for a case independent comparison. The mappings are
p * based upon ascii character sequences.
*/
static unsigned char charmap[] = {
@@ -127,17 +132,20 @@ static unsigned char charmap[] = {
int
strcasecmp(char *s1, char *s2)
{
- register unsigned char u1, u2;
+ register unsigned char u1,
+ u2;
- for (;;) {
+ for (;;)
+ {
u1 = (unsigned char) *s1++;
u2 = (unsigned char) *s2++;
- if (charmap[u1] != charmap[u2]) {
+ if (charmap[u1] != charmap[u2])
+ {
return charmap[u1] - charmap[u2];
}
- if (u1 == '\0') {
+ if (u1 == '\0')
+ {
return 0;
}
- }
+ }
}
-
diff --git a/src/backend/port/svr4/rusagestub.h b/src/backend/port/svr4/rusagestub.h
index d2393eb792d..5eda998802e 100644
--- a/src/backend/port/svr4/rusagestub.h
+++ b/src/backend/port/svr4/rusagestub.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* rusagestub.h--
- * Stubs for getrusage(3).
+ * Stubs for getrusage(3).
*
*
* Copyright (c) 1994, Regents of the University of California
@@ -13,18 +13,19 @@
#ifndef RUSAGESTUB_H
#define RUSAGESTUB_H
-#include <sys/time.h> /* for struct timeval */
-#include <sys/times.h> /* for struct tms */
-#include <limits.h> /* for CLK_TCK */
+#include <sys/time.h> /* for struct timeval */
+#include <sys/times.h> /* for struct tms */
+#include <limits.h> /* for CLK_TCK */
-#define RUSAGE_SELF 0
-#define RUSAGE_CHILDREN -1
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN -1
-struct rusage {
- struct timeval ru_utime; /* user time used */
- struct timeval ru_stime; /* system time used */
+struct rusage
+{
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
};
-extern int getrusage(int who, struct rusage *rusage);
+extern int getrusage(int who, struct rusage * rusage);
-#endif /* RUSAGESTUB_H */
+#endif /* RUSAGESTUB_H */
diff --git a/src/backend/port/ultrix4/dl.h b/src/backend/port/ultrix4/dl.h
index 7855db38f30..56eab754bf4 100644
--- a/src/backend/port/ultrix4/dl.h
+++ b/src/backend/port/ultrix4/dl.h
@@ -1,40 +1,40 @@
/*-------------------------------------------------------------------------
*
* dl.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: dl.h,v 1.3 1996/11/26 03:18:46 bryanh Exp $
+ * $Id: dl.h,v 1.4 1997/09/07 04:47:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * Ultrix 4.x Dynamic Loader Library Version 1.0
+ * Ultrix 4.x Dynamic Loader Library Version 1.0
*
- * dl.h--
- * header file for the Dynamic Loader Library
+ * dl.h--
+ * header file for the Dynamic Loader Library
*
*
- * Copyright (c) 1993 Andrew K. Yu, University of California at Berkeley
- * All rights reserved.
+ * Copyright (c) 1993 Andrew K. Yu, University of California at Berkeley
+ * All rights reserved.
*
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for educational, research, and non-profit purposes and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation. Permission
- * to incorporate this software into commercial products can be obtained
- * from the author. The University of California and the author make
- * no representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for educational, research, and non-profit purposes and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation. Permission
+ * to incorporate this software into commercial products can be obtained
+ * from the author. The University of California and the author make
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
*
*/
#ifndef _DL_HEADER_
#define _DL_HEADER_
-#include <stdio.h> /* needed to declare FILE for ldfcn.h */
+#include <stdio.h> /* needed to declare FILE for ldfcn.h */
#include <filehdr.h>
#include <syms.h>
#include <ldfcn.h>
@@ -42,77 +42,82 @@
#include <scnhdr.h>
-typedef long CoreAddr;
+typedef long CoreAddr;
-typedef struct ScnInfo {
- CoreAddr addr; /* starting address of the section */
- SCNHDR hdr; /* section header */
- RELOC *relocEntries; /* relocation entries */
-} ScnInfo;
+typedef struct ScnInfo
+{
+ CoreAddr addr; /* starting address of the section */
+ SCNHDR hdr; /* section header */
+ RELOC *relocEntries; /* relocation entries */
+} ScnInfo;
-typedef enum {
- DL_NEEDRELOC, /* still need relocation */
- DL_RELOCATED, /* no relocation necessary */
- DL_INPROG /* relocation in progress */
-} dlRStatus;
+typedef enum
+{
+ DL_NEEDRELOC, /* still need relocation */
+ DL_RELOCATED, /* no relocation necessary */
+ DL_INPROG /* relocation in progress */
+} dlRStatus;
-typedef struct JmpTbl {
- char *block; /* the jump table memory block */
- struct JmpTbl *next; /* next block */
-} JmpTbl;
+typedef struct JmpTbl
+{
+ char *block; /* the jump table memory block */
+ struct JmpTbl *next; /* next block */
+} JmpTbl;
-typedef struct dlFile {
- char *filename; /* file name of the object file */
+typedef struct dlFile
+{
+ char *filename; /* file name of the object file */
- int textSize; /* used by mprotect */
- CoreAddr textAddress; /* start addr of text section */
- long textVaddr; /* vaddr of text section in obj file */
- CoreAddr rdataAddress; /* start addr of rdata section */
- long rdataVaddr; /* vaddr of text section in obj file */
- CoreAddr dataAddress; /* start addr of data section */
- long dataVaddr; /* vaddr of text section in obj file */
- CoreAddr bssAddress; /* start addr of bss section */
- long bssVaddr; /* vaddr of text section in obj file */
+ int textSize; /* used by mprotect */
+ CoreAddr textAddress;/* start addr of text section */
+ long textVaddr; /* vaddr of text section in obj file */
+ CoreAddr rdataAddress; /* start addr of rdata section */
+ long rdataVaddr; /* vaddr of text section in obj file */
+ CoreAddr dataAddress;/* start addr of data section */
+ long dataVaddr; /* vaddr of text section in obj file */
+ CoreAddr bssAddress; /* start addr of bss section */
+ long bssVaddr; /* vaddr of text section in obj file */
- int nsect; /* number of sections */
- ScnInfo *sect; /* details of each section (array) */
+ int nsect; /* number of sections */
+ ScnInfo *sect; /* details of each section (array) */
- int issExtMax; /* size of string space */
- char *extss; /* extern sym string space (in core) */
- int iextMax; /* maximum number of Symbols */
- pEXTR extsyms; /* extern syms */
+ int issExtMax; /* size of string space */
+ char *extss; /* extern sym string space (in core) */
+ int iextMax; /* maximum number of Symbols */
+ pEXTR extsyms; /* extern syms */
- dlRStatus relocStatus; /* what relocation needed? */
- int needReloc;
+ dlRStatus relocStatus;/* what relocation needed? */
+ int needReloc;
- JmpTbl *jmptable; /* the jump table for R_JMPADDR */
+ JmpTbl *jmptable; /* the jump table for R_JMPADDR */
- struct dlFile *next; /* next member of the archive */
-} dlFile;
+ struct dlFile *next; /* next member of the archive */
+} dlFile;
-typedef struct dlSymbol {
- char *name; /* name of the symbol */
- long addr; /* address of the symbol */
- dlFile *objFile; /* from which file */
-} dlSymbol;
+typedef struct dlSymbol
+{
+ char *name; /* name of the symbol */
+ long addr; /* address of the symbol */
+ dlFile *objFile; /* from which file */
+} dlSymbol;
/*
* prototypes for the dl* interface
*/
-extern void *dl_open(/* char *filename, int mode */);
-extern void *dl_sym(/* void *handle, char *name */);
-extern void dl_close(/* void *handle */);
-extern char *dl_error(/* void */);
+extern void *dl_open( /* char *filename, int mode */ );
+extern void *dl_sym( /* void *handle, char *name */ );
+extern void dl_close( /* void *handle */ );
+extern char *dl_error( /* void */ );
-#define DL_LAZY 0 /* lazy resolution */
-#define DL_NOW 1 /* immediate resolution */
+#define DL_LAZY 0 /* lazy resolution */
+#define DL_NOW 1 /* immediate resolution */
/*
* Miscellaneous utility routines:
*/
-extern char **dl_undefinedSymbols(/* int *count */);
-extern void dl_printAllSymbols(/* void *handle */);
-extern void dl_setLibraries(/* char *libs */);
+extern char **dl_undefinedSymbols( /* int *count */ );
+extern void dl_printAllSymbols( /* void *handle */ );
+extern void dl_setLibraries( /* char *libs */ );
-#endif /* _DL_HEADER_ */
+#endif /* _DL_HEADER_ */
diff --git a/src/backend/port/ultrix4/dynloader.c b/src/backend/port/ultrix4/dynloader.c
index 1acc54260a1..d896eebf901 100644
--- a/src/backend/port/ultrix4/dynloader.c
+++ b/src/backend/port/ultrix4/dynloader.c
@@ -1,15 +1,15 @@
/*-------------------------------------------------------------------------
*
* dynloader.c--
- * This dynamic loader uses Andrew Yu's libdl-1.0 package for Ultrix 4.x.
- * (Note that pg_dlsym and pg_dlclose are actually macros defined in
- * "port-protos.h".)
- *
+ * This dynamic loader uses Andrew Yu's libdl-1.0 package for Ultrix 4.x.
+ * (Note that pg_dlsym and pg_dlclose are actually macros defined in
+ * "port-protos.h".)
+ *
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/ultrix4/Attic/dynloader.c,v 1.3 1996/11/26 03:18:50 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/ultrix4/Attic/dynloader.c,v 1.4 1997/09/07 04:47:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,49 +22,54 @@
#include "port-protos.h"
#include "utils/elog.h"
-extern char pg_pathname[];
+extern char pg_pathname[];
-void *
+void *
pg_dlopen(char *filename)
{
- static int dl_initialized= 0;
- void *handle;
+ static int dl_initialized = 0;
+ void *handle;
- /*
- * initializes the dynamic loader with the executable's pathname.
- * (only needs to do this the first time pg_dlopen is called.)
- */
- if (!dl_initialized) {
- if (!dl_init(pg_pathname)) {
- return NULL;
- }
/*
- * if there are undefined symbols, we want dl to search from the
- * following libraries also.
+ * initializes the dynamic loader with the executable's pathname.
+ * (only needs to do this the first time pg_dlopen is called.)
*/
- dl_setLibraries("/usr/lib/libm_G0.a:/usr/lib/libc_G0.a");
- dl_initialized= 1;
- }
+ if (!dl_initialized)
+ {
+ if (!dl_init(pg_pathname))
+ {
+ return NULL;
+ }
- /*
- * open the file. We do the symbol resolution right away so that we
- * will know if there are undefined symbols. (This is in fact the
- * same semantics as "ld -A". ie. you cannot have undefined symbols.
- */
- if ((handle=dl_open(filename, DL_NOW))==NULL) {
- int count;
- char **list= dl_undefinedSymbols(&count);
+ /*
+ * if there are undefined symbols, we want dl to search from the
+ * following libraries also.
+ */
+ dl_setLibraries("/usr/lib/libm_G0.a:/usr/lib/libc_G0.a");
+ dl_initialized = 1;
+ }
- /* list the undefined symbols, if any */
- if(count) {
- elog(NOTICE, "dl: Undefined:");
- while(*list) {
- elog(NOTICE, " %s", *list);
- list++;
- }
+ /*
+ * open the file. We do the symbol resolution right away so that we
+ * will know if there are undefined symbols. (This is in fact the same
+ * semantics as "ld -A". ie. you cannot have undefined symbols.
+ */
+ if ((handle = dl_open(filename, DL_NOW)) == NULL)
+ {
+ int count;
+ char **list = dl_undefinedSymbols(&count);
+
+ /* list the undefined symbols, if any */
+ if (count)
+ {
+ elog(NOTICE, "dl: Undefined:");
+ while (*list)
+ {
+ elog(NOTICE, " %s", *list);
+ list++;
+ }
+ }
}
- }
- return (void *)handle;
+ return (void *) handle;
}
-
diff --git a/src/backend/port/ultrix4/port-protos.h b/src/backend/port/ultrix4/port-protos.h
index 4d4346f16b5..25f49db393d 100644
--- a/src/backend/port/ultrix4/port-protos.h
+++ b/src/backend/port/ultrix4/port-protos.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * prototypes for Ultrix-specific routines
+ * prototypes for Ultrix-specific routines
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: port-protos.h,v 1.5 1997/02/13 09:53:57 scrappy Exp $
+ * $Id: port-protos.h,v 1.6 1997/09/07 04:47:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,8 +17,8 @@
* Externals in libc that need prototypes (or at least declarations)
*/
-extern char *ecvt(double, int, int*, int*);
-extern char *fcvt(double, int, int*, int*);
+extern char *ecvt(double, int, int *, int *);
+extern char *fcvt(double, int, int *, int *);
/* dynloader.c */
/*
@@ -27,21 +27,21 @@ extern char *fcvt(double, int, int*, int*);
* This dynamic loader uses Andrew Yu's libdl-1.0 package for Ultrix 4.x.
* (Note that pg_dlsym and pg_dlclose are actually macros defined in
* "port-protos.h".)
- */
+ */
#define pg_dlsym(h, f) ((func_ptr)dl_sym(h, f))
#define pg_dlclose(h) dl_close(h)
-#define pg_dlerror() dl_error()
-extern int dl_init(char *);
+#define pg_dlerror() dl_error()
+extern int dl_init(char *);
/* port.c */
-extern int syscall();
+extern int syscall();
-extern void init_address_fixup(void);
+extern void init_address_fixup(void);
/* strdup.c: strdup() is not part of libc on Ultrix */
-extern char* strdup(char const*);
+extern char *strdup(char const *);
/* inet_aton() is not part of libc on Ultrix. The following is from
backend/port/inet_aton.h
@@ -49,6 +49,6 @@ extern char* strdup(char const*);
struct in_addr;
int
-inet_aton(const char *cp, struct in_addr *addr);
+ inet_aton(const char *cp, struct in_addr * addr);
-#endif /* PORT_PORTOS_H */
+#endif /* PORT_PORTOS_H */
diff --git a/src/backend/port/ultrix4/port.c b/src/backend/port/ultrix4/port.c
index 4e6e19bdd0d..b009073f788 100644
--- a/src/backend/port/ultrix4/port.c
+++ b/src/backend/port/ultrix4/port.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * Ultrix-specific routines
+ * Ultrix-specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/ultrix4/Attic/port.c,v 1.2 1997/02/13 09:53:59 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/ultrix4/Attic/port.c,v 1.3 1997/09/07 04:47:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,6 +21,6 @@ void
init_address_fixup()
{
#ifdef NOFIXADE
- syscall(SYS_sysmips, MIPS_FIXADE, 0, NULL, NULL, NULL);
-#endif /* NOFIXADE */
+ syscall(SYS_sysmips, MIPS_FIXADE, 0, NULL, NULL, NULL);
+#endif /* NOFIXADE */
}
diff --git a/src/backend/port/ultrix4/strdup.c b/src/backend/port/ultrix4/strdup.c
index 882f0047e63..a738e1611ef 100644
--- a/src/backend/port/ultrix4/strdup.c
+++ b/src/backend/port/ultrix4/strdup.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* strdup.c--
- * copies a null-terminated string.
+ * copies a null-terminated string.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/port/ultrix4/Attic/strdup.c,v 1.2 1996/11/26 03:19:04 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/backend/port/ultrix4/Attic/strdup.c,v 1.3 1997/09/07 04:47:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,11 +17,11 @@
#include "port-protos.h"
-char *
-strdup(char const *string)
+char *
+strdup(char const * string)
{
- char *nstr;
+ char *nstr;
- nstr = strcpy((char *)palloc(strlen(string)+1), string);
- return nstr;
+ nstr = strcpy((char *) palloc(strlen(string) + 1), string);
+ return nstr;
}
diff --git a/src/backend/port/univel/frontend-port-protos.h b/src/backend/port/univel/frontend-port-protos.h
index b76feb9d6ca..9ca0100cb90 100644
--- a/src/backend/port/univel/frontend-port-protos.h
+++ b/src/backend/port/univel/frontend-port-protos.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for Intel x86/Intel SVR4
+ * port-specific prototypes for Intel x86/Intel SVR4
*
*
* Copyright (c) 1994, Regents of the University of California
@@ -14,9 +14,9 @@
#define FPORT_PROTOS_H
/* port.c */
-extern long random(void);
-extern void srandom(int seed);
-extern int strcasecmp(char *s1,char *s2);
-extern int gethostname(char *name,int namelen);
+extern long random(void);
+extern void srandom(int seed);
+extern int strcasecmp(char *s1, char *s2);
+extern int gethostname(char *name, int namelen);
-#endif /* FPORT_PROTOS_H */
+#endif /* FPORT_PROTOS_H */
diff --git a/src/backend/port/univel/port-protos.h b/src/backend/port/univel/port-protos.h
index 8c5cfb0f019..c181edfc9ec 100644
--- a/src/backend/port/univel/port-protos.h
+++ b/src/backend/port/univel/port-protos.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* port-protos.h--
- * port-specific prototypes for Intel x86/Intel SVR4
+ * port-specific prototypes for Intel x86/Intel SVR4
*
*
* Copyright (c) 1994, Regents of the University of California
@@ -14,27 +14,27 @@
#define PORT_PROTOS_H
#include <dlfcn.h>
-#include "fmgr.h" /* for func_ptr */
+#include "fmgr.h" /* for func_ptr */
#include "utils/dynamic_loader.h"
/* dynloader.c */
/*
* Dynamic Loader on Intel x86/Intel SVR4.
*
- * this dynamic loader uses the system dynamic loading interface for shared
+ * this dynamic loader uses the system dynamic loading interface for shared
* libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared
* library as the file to be dynamically loaded.
*
*/
#define pg_dlopen(f) dlopen(f,RTLD_LAZY)
-#define pg_dlsym dlsym
-#define pg_dlclose dlclose
-#define pg_dlerror dlerror
+#define pg_dlsym dlsym
+#define pg_dlclose dlclose
+#define pg_dlerror dlerror
/* port.c */
-extern long random(void);
-extern void srandom(int seed);
-extern int strcasecmp(char *s1,char *s2);
-extern int gethostname(char *name,int namelen);
+extern long random(void);
+extern void srandom(int seed);
+extern int strcasecmp(char *s1, char *s2);
+extern int gethostname(char *name, int namelen);
-#endif /* PORT_PROTOS_H */
+#endif /* PORT_PROTOS_H */
diff --git a/src/backend/port/univel/port.c b/src/backend/port/univel/port.c
index 07daeba62c6..d4c7658859e 100644
--- a/src/backend/port/univel/port.c
+++ b/src/backend/port/univel/port.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* port.c--
- * Intel x86/Intel SVR4-specific routines
+ * Intel x86/Intel SVR4-specific routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/port/svr4/port.c,v 1.2 1995/03/17 06:40:19 andrew Exp
+ * /usr/local/devel/pglite/cvs/src/backend/port/svr4/port.c,v 1.2 1995/03/17 06:40:19 andrew Exp
*
*-------------------------------------------------------------------------
*/
-#include <math.h> /* for pow() prototype */
+#include <math.h> /* for pow() prototype */
#include <errno.h>
#include "rusagestub.h"
@@ -20,50 +20,54 @@
long
random()
{
- return(lrand48());
+ return (lrand48());
}
void
srandom(int seed)
{
- srand48((long int) seed);
+ srand48((long int) seed);
}
int
-getrusage(int who, struct rusage *rusage)
+getrusage(int who, struct rusage * rusage)
{
- struct tms tms;
- register int tick_rate = CLK_TCK; /* ticks per second */
- clock_t u, s;
-
- if (rusage == (struct rusage *) NULL) {
- errno = EFAULT;
- return(-1);
- }
- if (times(&tms) < 0) {
- /* errno set by times */
- return(-1);
- }
- switch (who) {
- case RUSAGE_SELF:
- u = tms.tms_utime;
- s = tms.tms_stime;
- break;
- case RUSAGE_CHILDREN:
- u = tms.tms_cutime;
- s = tms.tms_cstime;
- break;
- default:
- errno = EINVAL;
- return(-1);
- }
+ struct tms tms;
+ register int tick_rate = CLK_TCK; /* ticks per second */
+ clock_t u,
+ s;
+
+ if (rusage == (struct rusage *) NULL)
+ {
+ errno = EFAULT;
+ return (-1);
+ }
+ if (times(&tms) < 0)
+ {
+ /* errno set by times */
+ return (-1);
+ }
+ switch (who)
+ {
+ case RUSAGE_SELF:
+ u = tms.tms_utime;
+ s = tms.tms_stime;
+ break;
+ case RUSAGE_CHILDREN:
+ u = tms.tms_cutime;
+ s = tms.tms_cstime;
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
#define TICK_TO_SEC(T, RATE) ((T)/(RATE))
-#define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE)
- rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
- rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
- rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
- rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
- return(0);
+#define TICK_TO_USEC(T,RATE) (((T)%(RATE)*1000000)/RATE)
+ rusage->ru_utime.tv_sec = TICK_TO_SEC(u, tick_rate);
+ rusage->ru_utime.tv_usec = TICK_TO_USEC(u, tick_rate);
+ rusage->ru_stime.tv_sec = TICK_TO_SEC(s, tick_rate);
+ rusage->ru_stime.tv_usec = TICK_TO_USEC(u, tick_rate);
+ return (0);
}
/*
@@ -79,15 +83,16 @@ getrusage(int who, struct rusage *rusage)
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strcasecmp.c 5.5 (Berkeley) 11/24/87";
-#endif /* LIBC_SCCS and not lint */
+static char sccsid[] = "@(#)strcasecmp.c 5.5 (Berkeley) 11/24/87";
+
+#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
/*
* This array is designed for mapping upper and lower case letter
- * together for a case independent comparison. The mappings are
+ * together for a case independent comparison. The mappings are
p * based upon ascii character sequences.
*/
static unsigned char charmap[] = {
@@ -128,34 +133,38 @@ static unsigned char charmap[] = {
int
strcasecmp(char *s1, char *s2)
{
- register unsigned char u1, u2;
+ register unsigned char u1,
+ u2;
- for (;;) {
+ for (;;)
+ {
u1 = (unsigned char) *s1++;
u2 = (unsigned char) *s2++;
- if (charmap[u1] != charmap[u2]) {
+ if (charmap[u1] != charmap[u2])
+ {
return charmap[u1] - charmap[u2];
}
- if (u1 == '\0') {
+ if (u1 == '\0')
+ {
return 0;
}
- }
+ }
}
#include <sys/utsname.h>
-int gethostname(char *name, int namelen)
+int
+gethostname(char *name, int namelen)
{
static struct utsname mname;
- static int called=0;
+ static int called = 0;
- if(!called)
+ if (!called)
{
called++;
uname(&mname);
}
- strncpy(name,mname.nodename,(SYS_NMLN<namelen?SYS_NMLN:namelen));
+ strncpy(name, mname.nodename, (SYS_NMLN < namelen ? SYS_NMLN : namelen));
- return(0);
+ return (0);
}
-
diff --git a/src/backend/port/univel/rusagestub.h b/src/backend/port/univel/rusagestub.h
index d2393eb792d..5eda998802e 100644
--- a/src/backend/port/univel/rusagestub.h
+++ b/src/backend/port/univel/rusagestub.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* rusagestub.h--
- * Stubs for getrusage(3).
+ * Stubs for getrusage(3).
*
*
* Copyright (c) 1994, Regents of the University of California
@@ -13,18 +13,19 @@
#ifndef RUSAGESTUB_H
#define RUSAGESTUB_H
-#include <sys/time.h> /* for struct timeval */
-#include <sys/times.h> /* for struct tms */
-#include <limits.h> /* for CLK_TCK */
+#include <sys/time.h> /* for struct timeval */
+#include <sys/times.h> /* for struct tms */
+#include <limits.h> /* for CLK_TCK */
-#define RUSAGE_SELF 0
-#define RUSAGE_CHILDREN -1
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN -1
-struct rusage {
- struct timeval ru_utime; /* user time used */
- struct timeval ru_stime; /* system time used */
+struct rusage
+{
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
};
-extern int getrusage(int who, struct rusage *rusage);
+extern int getrusage(int who, struct rusage * rusage);
-#endif /* RUSAGESTUB_H */
+#endif /* RUSAGESTUB_H */
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 9c13eae1957..c9979b76969 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1,45 +1,45 @@
/*-------------------------------------------------------------------------
*
* postmaster.c--
- * This program acts as a clearing house for requests to the
- * POSTGRES system. Frontend programs send a startup message
- * to the Postmaster and the postmaster uses the info in the
- * message to setup a backend process.
+ * This program acts as a clearing house for requests to the
+ * POSTGRES system. Frontend programs send a startup message
+ * to the Postmaster and the postmaster uses the info in the
+ * message to setup a backend process.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.53 1997/08/25 04:15:31 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.54 1997/09/07 04:47:43 momjian Exp $
*
* NOTES
*
* Initialization:
- * The Postmaster sets up a few shared memory data structures
- * for the backends. It should at the very least initialize the
- * lock manager.
+ * The Postmaster sets up a few shared memory data structures
+ * for the backends. It should at the very least initialize the
+ * lock manager.
*
* Synchronization:
- * The Postmaster shares memory with the backends and will have to lock
- * the shared memory it accesses. The Postmaster should never block
- * on messages from clients.
- *
+ * The Postmaster shares memory with the backends and will have to lock
+ * the shared memory it accesses. The Postmaster should never block
+ * on messages from clients.
+ *
* Garbage Collection:
- * The Postmaster cleans up after backends if they have an emergency
- * exit and/or core dump.
+ * The Postmaster cleans up after backends if they have an emergency
+ * exit and/or core dump.
*
* Communication:
*
*-------------------------------------------------------------------------
*/
- /* moved here to prevent double define */
-#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
+ /* moved here to prevent double define */
+#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
#ifdef HAVE_NETDB_H
-# include <netdb.h> /* for MAXHOSTNAMELEN on some */
+#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#endif
#ifndef MAXHOSTNAMELEN
-# define MAXHOSTNAMELEN 256
+#define MAXHOSTNAMELEN 256
#endif
#include "postgres.h"
@@ -49,20 +49,20 @@
#include <stdlib.h>
#if !defined(NO_UNISTD_H)
-# include <unistd.h>
-#endif /* !NO_UNISTD_H */
+#include <unistd.h>
+#endif /* !NO_UNISTD_H */
#include <ctype.h>
-#include <sys/types.h> /* for fd_set stuff */
-#include <sys/stat.h> /* for umask */
+#include <sys/types.h> /* for fd_set stuff */
+#include <sys/stat.h> /* for umask */
#include <sys/time.h>
#include <sys/socket.h>
#ifdef HAVE_LIMITS_H
-# include <limits.h>
-# define MAXINT INT_MAX
+#include <limits.h>
+#define MAXINT INT_MAX
#else
-# include <values.h>
-#endif
+#include <values.h>
+#endif
#include <sys/wait.h>
#include <errno.h>
@@ -70,8 +70,8 @@
#include <stdio.h>
#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
+#include <sys/select.h>
+#endif
#include "storage/ipc.h"
#include "libpq/libpq.h"
@@ -85,137 +85,152 @@
#include "utils/mcxt.h"
#include "storage/proc.h"
#include "utils/elog.h"
-#include "port-protos.h" /* For gethostname() */
+#include "port-protos.h" /* For gethostname() */
#if defined(DBX_VERSION)
-# define FORK() (0)
+#define FORK() (0)
#else
-# ifndef HAVE_VFORK
-# define FORK() fork()
-# else
-# define FORK() vfork()
-# endif
+#ifndef HAVE_VFORK
+#define FORK() fork()
+#else
+#define FORK() vfork()
+#endif
#endif
#define LINGER_TIME 3
- /* Max time in seconds for socket to linger (close() to block) waiting
- for frontend to retrieve its message from us.
+
+ /*
+ * Max time in seconds for socket to linger (close() to block) waiting
+ * for frontend to retrieve its message from us.
*/
/*
* Info for garbage collection. Whenever a process dies, the Postmaster
- * cleans up after it. Currently, NO information is required for cleanup,
+ * cleans up after it. Currently, NO information is required for cleanup,
* but I left this structure around in case that changed.
*/
-typedef struct bkend {
- int pid; /* process id of backend */
-} Backend;
+typedef struct bkend
+{
+ int pid; /* process id of backend */
+} Backend;
/* list of active backends. For garbage collection only now. */
-static Dllist* BackendList;
+static Dllist *BackendList;
/* list of ports associated with still open, but incomplete connections */
-static Dllist* PortList;
+static Dllist *PortList;
-static short PostPortName = -1;
-static short ActiveBackends = FALSE;
-static int NextBackendId = MAXINT; /* XXX why? */
-static char *progname = (char *) NULL;
+static short PostPortName = -1;
+static short ActiveBackends = FALSE;
+static int NextBackendId = MAXINT; /* XXX why? */
+static char *progname = (char *) NULL;
/*
* Default Values
*/
-static char Execfile[MAXPATHLEN] = "";
+static char Execfile[MAXPATHLEN] = "";
-static int ServerSock = INVALID_SOCK; /* stream socket server */
+static int ServerSock = INVALID_SOCK; /* stream socket server */
/*
* Set by the -o option
*/
-static char ExtraOptions[ARGV_SIZE] = "";
+static char ExtraOptions[ARGV_SIZE] = "";
/*
* These globals control the behavior of the postmaster in case some
- * backend dumps core. Normally, it kills all peers of the dead backend
+ * backend dumps core. Normally, it kills all peers of the dead backend
* and reinitializes shared memory. By specifying -s or -n, we can have
* the postmaster stop (rather than kill) peers and not reinitialize
* shared data structures.
*/
-static int Reinit = 1;
-static int SendStop = 0;
+static int Reinit = 1;
+static int SendStop = 0;
-static int MultiplexedBackends = 0;
-static int MultiplexedBackendPort;
+static int MultiplexedBackends = 0;
+static int MultiplexedBackendPort;
-/*
+/*
* postmaster.c - function prototypes
*/
-static void pmdaemonize(void);
-static void ConnStartup(Port *port, int *status,
- char *errormsg, const int errormsg_len);
-static int ConnCreate(int serverFd, int *newFdP);
-static void reset_shared(short port);
-static void pmdie(SIGNAL_ARGS);
-static void reaper(SIGNAL_ARGS);
-static void dumpstatus(SIGNAL_ARGS);
-static void CleanupProc(int pid, int exitstatus);
-static int DoExec(StartupInfo *packet, int portFd);
-static void ExitPostmaster(int status);
-static void usage(const char *);
-static int ServerLoop(void);
-static int BackendStartup(StartupInfo *packet, Port *port, int *pidPtr);
-static void send_error_reply(Port *port, const char *errormsg);
-
-extern char *optarg;
-extern int optind, opterr;
+static void pmdaemonize(void);
+static void
+ConnStartup(Port * port, int *status,
+ char *errormsg, const int errormsg_len);
+static int ConnCreate(int serverFd, int *newFdP);
+static void reset_shared(short port);
+static void pmdie(SIGNAL_ARGS);
+static void reaper(SIGNAL_ARGS);
+static void dumpstatus(SIGNAL_ARGS);
+static void CleanupProc(int pid, int exitstatus);
+static int DoExec(StartupInfo * packet, int portFd);
+static void ExitPostmaster(int status);
+static void usage(const char *);
+static int ServerLoop(void);
+static int BackendStartup(StartupInfo * packet, Port * port, int *pidPtr);
+static void send_error_reply(Port * port, const char *errormsg);
+
+extern char *optarg;
+extern int optind,
+ opterr;
static void
-checkDataDir(const char *DataDir, bool *DataDirOK)
+checkDataDir(const char *DataDir, bool * DataDirOK)
{
- if (DataDir == NULL) {
- fprintf(stderr, "%s does not know where to find the database system "
- "data. You must specify the directory that contains the "
- "database system either by specifying the -D invocation "
- "option or by setting the PGDATA environment variable.\n\n",
- progname);
- *DataDirOK = false;
- } else {
- char path[MAXPATHLEN];
- FILE *fp;
-
- sprintf(path, "%s%cbase%ctemplate1%cpg_class",
- DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR);
- fp = fopen(path, "r");
- if (fp == NULL) {
- fprintf(stderr, "%s does not find the database system. "
- "Expected to find it "
- "in the PGDATA directory \"%s\", but unable to open file "
- "with pathname \"%s\".\n\n",
- progname, DataDir, path);
- *DataDirOK = false;
- } else {
- char *reason;
- /* reason ValidatePgVersion failed. NULL if didn't */
-
- fclose(fp);
-
- ValidatePgVersion(DataDir, &reason);
- if (reason) {
- fprintf(stderr,
- "Database system in directory %s "
- "is not compatible with this version of "
- "Postgres, or we are unable to read the "
- "PG_VERSION file. "
- "Explanation from ValidatePgVersion: %s\n\n",
- DataDir, reason);
- free(reason);
- *DataDirOK = false;
- } else *DataDirOK = true;
- }
- }
+ if (DataDir == NULL)
+ {
+ fprintf(stderr, "%s does not know where to find the database system "
+ "data. You must specify the directory that contains the "
+ "database system either by specifying the -D invocation "
+ "option or by setting the PGDATA environment variable.\n\n",
+ progname);
+ *DataDirOK = false;
+ }
+ else
+ {
+ char path[MAXPATHLEN];
+ FILE *fp;
+
+ sprintf(path, "%s%cbase%ctemplate1%cpg_class",
+ DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR);
+ fp = fopen(path, "r");
+ if (fp == NULL)
+ {
+ fprintf(stderr, "%s does not find the database system. "
+ "Expected to find it "
+ "in the PGDATA directory \"%s\", but unable to open file "
+ "with pathname \"%s\".\n\n",
+ progname, DataDir, path);
+ *DataDirOK = false;
+ }
+ else
+ {
+ char *reason;
+
+ /* reason ValidatePgVersion failed. NULL if didn't */
+
+ fclose(fp);
+
+ ValidatePgVersion(DataDir, &reason);
+ if (reason)
+ {
+ fprintf(stderr,
+ "Database system in directory %s "
+ "is not compatible with this version of "
+ "Postgres, or we are unable to read the "
+ "PG_VERSION file. "
+ "Explanation from ValidatePgVersion: %s\n\n",
+ DataDir, reason);
+ free(reason);
+ *DataDirOK = false;
+ }
+ else
+ *DataDirOK = true;
+ }
+ }
}
@@ -223,533 +238,596 @@ checkDataDir(const char *DataDir, bool *DataDirOK)
int
PostmasterMain(int argc, char *argv[])
{
- extern int NBuffers; /* from buffer/bufmgr.c */
- extern bool IsPostmaster; /* from smgr/mm.c */
- int opt;
- char *hostName;
- int status;
- int silentflag = 0;
- char hostbuf[MAXHOSTNAMELEN];
- bool DataDirOK; /* We have a usable PGDATA value */
-
- progname = argv[0];
-
- IsPostmaster = true;
-
- /* for security, no dir or file created can be group or other accessible */
- umask((mode_t) 0077);
-
- if (!(hostName = getenv("PGHOST"))) {
- if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
- strcpy(hostbuf, "localhost");
- hostName = hostbuf;
- }
-
- DataDir = getenv("PGDATA"); /* default value */
-
- opterr = 0;
- while ((opt = getopt(argc, argv, "a:B:b:D:dm:Mno:p:Ss")) != EOF) {
- switch (opt) {
- case 'a':
- /* Set the authentication system. */
- be_setauthsvc(optarg);
- break;
- case 'B':
- /*
- * The number of buffers to create. Setting this
- * option means we have to start each backend with
- * a -B # to make sure they know how many buffers
- * were allocated.
- */
- NBuffers = atol(optarg);
- strcat(ExtraOptions, " -B ");
- strcat(ExtraOptions, optarg);
- break;
- case 'b':
- /* Set the backend executable file to use. */
- if (!ValidateBackend(optarg))
- strcpy(Execfile, optarg);
- else {
- fprintf(stderr, "%s: invalid backend \"%s\"\n",
- progname, optarg);
- exit(2);
- }
- break;
- case 'D':
- /* Set PGDATA from the command line. */
- DataDir = optarg;
- break;
- case 'd':
- /*
- * Turn on debugging for the postmaster and the backend
- * servers descended from it.
- */
- if ((optind < argc) && *argv[optind] != '-') {
- DebugLvl = atoi(argv[optind]);
- optind++;
- }
- else
- DebugLvl = 1;
- break;
- case 'm':
- MultiplexedBackends = 1;
- MultiplexedBackendPort = atoi(optarg);
- break;
- case 'M':
- /* ignore this flag. This may be passed in because the
- program was run as 'postgres -M' instead of 'postmaster' */
- break;
- case 'n':
- /* Don't reinit shared mem after abnormal exit */
- Reinit = 0;
- break;
- case 'o':
- /*
- * Other options to pass to the backend on the
- * command line -- useful only for debugging.
- */
- strcat(ExtraOptions, " ");
- strcat(ExtraOptions, optarg);
- break;
- case 'p':
- /* Set PGPORT by hand. */
- PostPortName = (short) atoi(optarg);
- break;
- case 'S':
- /*
- * Start in 'S'ilent mode (disassociate from controlling tty).
- * You may also think of this as 'S'ysV mode since it's most
- * badly needed on SysV-derived systems like SVR4 and HP-UX.
- */
- silentflag = 1;
- break;
- case 's':
- /*
- * In the event that some backend dumps core,
- * send SIGSTOP, rather than SIGUSR1, to all
- * its peers. This lets the wily post_hacker
- * collect core dumps from everyone.
- */
- SendStop = 1;
- break;
- default:
- /* usage() never returns */
- usage(progname);
- break;
- }
- }
- if (PostPortName == -1)
- PostPortName = pq_getport();
-
- checkDataDir(DataDir, &DataDirOK); /* issues error messages */
- if (!DataDirOK) {
- fprintf(stderr, "No data directory -- can't proceed.\n");
- exit(2);
- }
-
- if (!Execfile[0] && FindBackend(Execfile, argv[0]) < 0) {
- fprintf(stderr, "%s: could not find backend to execute...\n",
- argv[0]);
- exit(1);
- }
-
-
- status = StreamServerPort(hostName, PostPortName, &ServerSock);
- if (status != STATUS_OK) {
- fprintf(stderr, "%s: cannot create stream port\n",
- progname);
- exit(1);
- }
-
- /* set up shared memory and semaphores */
- EnableMemoryContext(TRUE);
- reset_shared(PostPortName);
-
- /*
- * Initialize the list of active backends. This list is only
- * used for garbage collecting the backend processes.
- */
- BackendList = DLNewList();
- PortList = DLNewList();
-
- if (silentflag)
- pmdaemonize();
-
- pqsignal(SIGINT, pmdie);
- pqsignal(SIGCHLD, reaper);
- pqsignal(SIGTTIN, SIG_IGN);
- pqsignal(SIGTTOU, SIG_IGN);
- pqsignal(SIGHUP, pmdie);
- pqsignal(SIGTERM, pmdie);
- pqsignal(SIGCONT, dumpstatus);
- pqsignal(SIGPIPE, SIG_IGN);
-
- status = ServerLoop();
-
- ExitPostmaster(status != STATUS_OK);
- return 0; /* not reached */
+ extern int NBuffers; /* from buffer/bufmgr.c */
+ extern bool IsPostmaster; /* from smgr/mm.c */
+ int opt;
+ char *hostName;
+ int status;
+ int silentflag = 0;
+ char hostbuf[MAXHOSTNAMELEN];
+ bool DataDirOK; /* We have a usable PGDATA value */
+
+ progname = argv[0];
+
+ IsPostmaster = true;
+
+ /*
+ * for security, no dir or file created can be group or other
+ * accessible
+ */
+ umask((mode_t) 0077);
+
+ if (!(hostName = getenv("PGHOST")))
+ {
+ if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
+ strcpy(hostbuf, "localhost");
+ hostName = hostbuf;
+ }
+
+ DataDir = getenv("PGDATA"); /* default value */
+
+ opterr = 0;
+ while ((opt = getopt(argc, argv, "a:B:b:D:dm:Mno:p:Ss")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'a':
+ /* Set the authentication system. */
+ be_setauthsvc(optarg);
+ break;
+ case 'B':
+
+ /*
+ * The number of buffers to create. Setting this option means
+ * we have to start each backend with a -B # to make sure they
+ * know how many buffers were allocated.
+ */
+ NBuffers = atol(optarg);
+ strcat(ExtraOptions, " -B ");
+ strcat(ExtraOptions, optarg);
+ break;
+ case 'b':
+ /* Set the backend executable file to use. */
+ if (!ValidateBackend(optarg))
+ strcpy(Execfile, optarg);
+ else
+ {
+ fprintf(stderr, "%s: invalid backend \"%s\"\n",
+ progname, optarg);
+ exit(2);
+ }
+ break;
+ case 'D':
+ /* Set PGDATA from the command line. */
+ DataDir = optarg;
+ break;
+ case 'd':
+
+ /*
+ * Turn on debugging for the postmaster and the backend
+ * servers descended from it.
+ */
+ if ((optind < argc) && *argv[optind] != '-')
+ {
+ DebugLvl = atoi(argv[optind]);
+ optind++;
+ }
+ else
+ DebugLvl = 1;
+ break;
+ case 'm':
+ MultiplexedBackends = 1;
+ MultiplexedBackendPort = atoi(optarg);
+ break;
+ case 'M':
+
+ /*
+ * ignore this flag. This may be passed in because the
+ * program was run as 'postgres -M' instead of 'postmaster'
+ */
+ break;
+ case 'n':
+ /* Don't reinit shared mem after abnormal exit */
+ Reinit = 0;
+ break;
+ case 'o':
+
+ /*
+ * Other options to pass to the backend on the command line --
+ * useful only for debugging.
+ */
+ strcat(ExtraOptions, " ");
+ strcat(ExtraOptions, optarg);
+ break;
+ case 'p':
+ /* Set PGPORT by hand. */
+ PostPortName = (short) atoi(optarg);
+ break;
+ case 'S':
+
+ /*
+ * Start in 'S'ilent mode (disassociate from controlling tty).
+ * You may also think of this as 'S'ysV mode since it's most
+ * badly needed on SysV-derived systems like SVR4 and HP-UX.
+ */
+ silentflag = 1;
+ break;
+ case 's':
+
+ /*
+ * In the event that some backend dumps core, send SIGSTOP,
+ * rather than SIGUSR1, to all its peers. This lets the wily
+ * post_hacker collect core dumps from everyone.
+ */
+ SendStop = 1;
+ break;
+ default:
+ /* usage() never returns */
+ usage(progname);
+ break;
+ }
+ }
+ if (PostPortName == -1)
+ PostPortName = pq_getport();
+
+ checkDataDir(DataDir, &DataDirOK); /* issues error messages */
+ if (!DataDirOK)
+ {
+ fprintf(stderr, "No data directory -- can't proceed.\n");
+ exit(2);
+ }
+
+ if (!Execfile[0] && FindBackend(Execfile, argv[0]) < 0)
+ {
+ fprintf(stderr, "%s: could not find backend to execute...\n",
+ argv[0]);
+ exit(1);
+ }
+
+
+ status = StreamServerPort(hostName, PostPortName, &ServerSock);
+ if (status != STATUS_OK)
+ {
+ fprintf(stderr, "%s: cannot create stream port\n",
+ progname);
+ exit(1);
+ }
+
+ /* set up shared memory and semaphores */
+ EnableMemoryContext(TRUE);
+ reset_shared(PostPortName);
+
+ /*
+ * Initialize the list of active backends. This list is only used for
+ * garbage collecting the backend processes.
+ */
+ BackendList = DLNewList();
+ PortList = DLNewList();
+
+ if (silentflag)
+ pmdaemonize();
+
+ pqsignal(SIGINT, pmdie);
+ pqsignal(SIGCHLD, reaper);
+ pqsignal(SIGTTIN, SIG_IGN);
+ pqsignal(SIGTTOU, SIG_IGN);
+ pqsignal(SIGHUP, pmdie);
+ pqsignal(SIGTERM, pmdie);
+ pqsignal(SIGCONT, dumpstatus);
+ pqsignal(SIGPIPE, SIG_IGN);
+
+ status = ServerLoop();
+
+ ExitPostmaster(status != STATUS_OK);
+ return 0; /* not reached */
}
static void
pmdaemonize(void)
{
- int i;
-
- if (fork())
- exit(0);
+ int i;
+
+ if (fork())
+ exit(0);
/* GH: If there's no setsid(), we hopefully don't need silent mode.
* Until there's a better solution.
*/
#ifdef HAVE_SETSID
- if (setsid() < 0) {
- fprintf(stderr, "%s: ", progname);
- perror("cannot disassociate from controlling TTY");
- exit(1);
- }
+ if (setsid() < 0)
+ {
+ fprintf(stderr, "%s: ", progname);
+ perror("cannot disassociate from controlling TTY");
+ exit(1);
+ }
#endif
- i = open(NULL_DEV, O_RDWR);
- dup2(i, 0);
- dup2(i, 1);
- dup2(i, 2);
- close(i);
+ i = open(NULL_DEV, O_RDWR);
+ dup2(i, 0);
+ dup2(i, 1);
+ dup2(i, 2);
+ close(i);
}
static void
usage(const char *progname)
{
- fprintf(stderr, "usage: %s [options..]\n", progname);
- fprintf(stderr, "\t-a authsys\tdo/do not permit use of an authentication system\n");
- fprintf(stderr, "\t-B nbufs\tset number of shared buffers\n");
- fprintf(stderr, "\t-b backend\tuse a specific backend server executable\n");
- fprintf(stderr, "\t-d [1|2|3]\tset debugging level\n");
- fprintf(stderr, "\t-D datadir\tset data directory\n");
- fprintf(stderr, "\t-m \tstart up multiplexing backends\n");
- fprintf(stderr, "\t-n\t\tdon't reinitialize shared memory after abnormal exit\n");
- fprintf(stderr, "\t-o option\tpass 'option' to each backend servers\n");
- fprintf(stderr, "\t-p port\t\tspecify port for postmaster to listen on\n");
- fprintf(stderr, "\t-S\t\tsilent mode (disassociate from tty)\n");
- fprintf(stderr, "\t-s\t\tsend SIGSTOP to all backend servers if one dies\n");
- exit(1);
+ fprintf(stderr, "usage: %s [options..]\n", progname);
+ fprintf(stderr, "\t-a authsys\tdo/do not permit use of an authentication system\n");
+ fprintf(stderr, "\t-B nbufs\tset number of shared buffers\n");
+ fprintf(stderr, "\t-b backend\tuse a specific backend server executable\n");
+ fprintf(stderr, "\t-d [1|2|3]\tset debugging level\n");
+ fprintf(stderr, "\t-D datadir\tset data directory\n");
+ fprintf(stderr, "\t-m \tstart up multiplexing backends\n");
+ fprintf(stderr, "\t-n\t\tdon't reinitialize shared memory after abnormal exit\n");
+ fprintf(stderr, "\t-o option\tpass 'option' to each backend servers\n");
+ fprintf(stderr, "\t-p port\t\tspecify port for postmaster to listen on\n");
+ fprintf(stderr, "\t-S\t\tsilent mode (disassociate from tty)\n");
+ fprintf(stderr, "\t-s\t\tsend SIGSTOP to all backend servers if one dies\n");
+ exit(1);
}
static int
ServerLoop(void)
{
- int serverFd = ServerSock;
- fd_set rmask, basemask;
- int nSockets, nSelected, status, newFd;
- Dlelem *next, *curr;
- /* GH: For !HAVE_SIGPROCMASK (NEXTSTEP), TRH implemented
- * an alternative interface.
- */
+ int serverFd = ServerSock;
+ fd_set rmask,
+ basemask;
+ int nSockets,
+ nSelected,
+ status,
+ newFd;
+ Dlelem *next,
+ *curr;
+
+ /*
+ * GH: For !HAVE_SIGPROCMASK (NEXTSTEP), TRH implemented an
+ * alternative interface.
+ */
#ifdef HAVE_SIGPROCMASK
- sigset_t oldsigmask, newsigmask;
+ sigset_t oldsigmask,
+ newsigmask;
+
#else
- int orgsigmask = sigblock(0);
+ int orgsigmask = sigblock(0);
+
#endif
-
- nSockets = ServerSock + 1;
- FD_ZERO(&basemask);
- FD_SET(ServerSock, &basemask);
-
+
+ nSockets = ServerSock + 1;
+ FD_ZERO(&basemask);
+ FD_SET(ServerSock, &basemask);
+
#ifdef HAVE_SIGPROCMASK
- sigprocmask(0,0,&oldsigmask);
- sigemptyset(&newsigmask);
- sigaddset(&newsigmask,SIGCHLD);
+ sigprocmask(0, 0, &oldsigmask);
+ sigemptyset(&newsigmask);
+ sigaddset(&newsigmask, SIGCHLD);
#endif
- for (;;) {
+ for (;;)
+ {
#ifdef HAVE_SIGPROCMASK
- sigprocmask(SIG_SETMASK,&oldsigmask,0);
+ sigprocmask(SIG_SETMASK, &oldsigmask, 0);
#else
- sigsetmask(orgsigmask);
+ sigsetmask(orgsigmask);
#endif
- newFd = -1;
- memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set));
- if ((nSelected = select(nSockets, &rmask,
- (fd_set *) NULL,
- (fd_set *) NULL,
- (struct timeval *) NULL)) < 0) {
- if (errno == EINTR)
- continue;
- fprintf(stderr, "%s: ServerLoop: select failed\n",
- progname);
- return(STATUS_ERROR);
- }
- /* [TRH]
- * To avoid race conditions, block SIGCHLD signals while we are
- * handling the request. (both reaper() and ConnCreate()
- * manipulate the BackEnd list, and reaper() calls free() which is
- * usually non-reentrant.)
- */
+ newFd = -1;
+ memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set));
+ if ((nSelected = select(nSockets, &rmask,
+ (fd_set *) NULL,
+ (fd_set *) NULL,
+ (struct timeval *) NULL)) < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "%s: ServerLoop: select failed\n",
+ progname);
+ return (STATUS_ERROR);
+ }
+
+ /*
+ * [TRH] To avoid race conditions, block SIGCHLD signals while we
+ * are handling the request. (both reaper() and ConnCreate()
+ * manipulate the BackEnd list, and reaper() calls free() which is
+ * usually non-reentrant.)
+ */
#ifdef HAVE_SIGPROCMASK
- sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
+ sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
#else
- sigblock(sigmask(SIGCHLD)); /* XXX[TRH] portability */
+ sigblock(sigmask(SIGCHLD)); /* XXX[TRH] portability */
#endif
- if (DebugLvl > 1) {
- fprintf(stderr, "%s: ServerLoop: %d sockets pending\n",
- progname, nSelected);
- }
-
- /* new connection pending on our well-known port's socket */
- if (FD_ISSET(ServerSock, &rmask)) {
- /*
- * connect and make an addition to PortList. If
- * the connection dies and we notice it, just forget
- * about the whole thing.
- */
- if (ConnCreate(serverFd, &newFd) == STATUS_OK) {
- if (newFd >= nSockets)
- nSockets = newFd + 1;
- FD_SET(newFd, &rmask);
- FD_SET(newFd, &basemask);
- if (DebugLvl)
- fprintf(stderr, "%s: ServerLoop: connect on %d\n",
- progname, newFd);
- }
- --nSelected;
- FD_CLR(ServerSock, &rmask);
- }
-
- if (DebugLvl > 1) {
- fprintf(stderr, "%s: ServerLoop:\tnSelected=%d\n",
- progname, nSelected);
- curr = DLGetHead(PortList);
- while (curr) {
- Port *port = DLE_VAL(curr);
-
- fprintf(stderr, "%s: ServerLoop:\t\tport %d%s pending\n",
- progname, port->sock,
- FD_ISSET(port->sock, &rmask)
- ? "" :
- " not");
- curr = DLGetSucc(curr);
- }
- }
-
- curr = DLGetHead(PortList);
-
- while (curr) {
- Port *port = (Port*)DLE_VAL(curr);
- int lastbytes = port->nBytes;
-
- if (FD_ISSET(port->sock, &rmask) && port->sock != newFd) {
- if (DebugLvl > 1)
- fprintf(stderr, "%s: ServerLoop:\t\thandling %d\n",
- progname, port->sock);
- --nSelected;
-
- /*
- * Read the incoming packet into its packet buffer.
- * Read the connection id out of the packet so we
- * know who the packet is from.
- */
- status = PacketReceive(port, &port->buf, NON_BLOCKING);
- switch (status) {
- case STATUS_OK: {
- int CSstatus; /* Completion status of ConnStartup */
- char errormsg[200]; /* error msg from ConnStartup */
-
- ConnStartup(port, &CSstatus, errormsg, sizeof(errormsg));
-
- if (CSstatus == STATUS_ERROR)
- send_error_reply(port, errormsg);
- ActiveBackends = TRUE;
- }
- /*FALLTHROUGH*/
- case STATUS_INVALID:
- if (DebugLvl)
- fprintf(stderr, "%s: ServerLoop:\t\tdone with %d\n",
- progname, port->sock);
- break;
- case STATUS_BAD_PACKET:
- /*
- * This is a bogus client, kill the connection
- * and forget the whole thing.
- */
- if (DebugLvl)
- fprintf(stderr, "%s: ServerLoop:\t\tbad packet format (reported packet size of %d read on port %d\n", progname, port->nBytes, port->sock);
- break;
- case STATUS_NOT_DONE:
- if (DebugLvl)
- fprintf(stderr, "%s: ServerLoop:\t\tpartial packet (%d bytes actually read) on %d\n",
- progname, port->nBytes, port->sock);
- /*
- * If we've received at least a PacketHdr's worth of data
- * and we're still receiving data each time we read, we're
- * ok. If the client gives us less than a PacketHdr at
- * the beginning, just kill the connection and forget
- * about the whole thing.
- */
- if (lastbytes < port->nBytes) {
- if (DebugLvl)
- fprintf(stderr, "%s: ServerLoop:\t\tpartial packet on %d ok\n",
- progname, port->sock);
- curr = DLGetSucc(curr);
- continue;
- }
- break;
- case STATUS_ERROR: /* system call error - die */
- fprintf(stderr, "%s: ServerLoop:\t\terror receiving packet\n",
- progname);
- return(STATUS_ERROR);
- }
- FD_CLR(port->sock, &basemask);
- StreamClose(port->sock);
- next = DLGetSucc(curr);
- DLRemove(curr);
- free(port);
- DLFreeElem(curr);
- curr = next;
- continue;
- }
- curr = DLGetSucc(curr);
- }
- Assert(nSelected == 0);
- }
+ if (DebugLvl > 1)
+ {
+ fprintf(stderr, "%s: ServerLoop: %d sockets pending\n",
+ progname, nSelected);
+ }
+
+ /* new connection pending on our well-known port's socket */
+ if (FD_ISSET(ServerSock, &rmask))
+ {
+
+ /*
+ * connect and make an addition to PortList. If the
+ * connection dies and we notice it, just forget about the
+ * whole thing.
+ */
+ if (ConnCreate(serverFd, &newFd) == STATUS_OK)
+ {
+ if (newFd >= nSockets)
+ nSockets = newFd + 1;
+ FD_SET(newFd, &rmask);
+ FD_SET(newFd, &basemask);
+ if (DebugLvl)
+ fprintf(stderr, "%s: ServerLoop: connect on %d\n",
+ progname, newFd);
+ }
+ --nSelected;
+ FD_CLR(ServerSock, &rmask);
+ }
+
+ if (DebugLvl > 1)
+ {
+ fprintf(stderr, "%s: ServerLoop:\tnSelected=%d\n",
+ progname, nSelected);
+ curr = DLGetHead(PortList);
+ while (curr)
+ {
+ Port *port = DLE_VAL(curr);
+
+ fprintf(stderr, "%s: ServerLoop:\t\tport %d%s pending\n",
+ progname, port->sock,
+ FD_ISSET(port->sock, &rmask)
+ ? "" :
+ " not");
+ curr = DLGetSucc(curr);
+ }
+ }
+
+ curr = DLGetHead(PortList);
+
+ while (curr)
+ {
+ Port *port = (Port *) DLE_VAL(curr);
+ int lastbytes = port->nBytes;
+
+ if (FD_ISSET(port->sock, &rmask) && port->sock != newFd)
+ {
+ if (DebugLvl > 1)
+ fprintf(stderr, "%s: ServerLoop:\t\thandling %d\n",
+ progname, port->sock);
+ --nSelected;
+
+ /*
+ * Read the incoming packet into its packet buffer. Read
+ * the connection id out of the packet so we know who the
+ * packet is from.
+ */
+ status = PacketReceive(port, &port->buf, NON_BLOCKING);
+ switch (status)
+ {
+ case STATUS_OK:
+ {
+ int CSstatus; /* Completion status of
+ * ConnStartup */
+ char errormsg[200]; /* error msg from
+ * ConnStartup */
+
+ ConnStartup(port, &CSstatus, errormsg, sizeof(errormsg));
+
+ if (CSstatus == STATUS_ERROR)
+ send_error_reply(port, errormsg);
+ ActiveBackends = TRUE;
+ }
+ /* FALLTHROUGH */
+ case STATUS_INVALID:
+ if (DebugLvl)
+ fprintf(stderr, "%s: ServerLoop:\t\tdone with %d\n",
+ progname, port->sock);
+ break;
+ case STATUS_BAD_PACKET:
+
+ /*
+ * This is a bogus client, kill the connection and
+ * forget the whole thing.
+ */
+ if (DebugLvl)
+ fprintf(stderr, "%s: ServerLoop:\t\tbad packet format (reported packet size of %d read on port %d\n", progname, port->nBytes, port->sock);
+ break;
+ case STATUS_NOT_DONE:
+ if (DebugLvl)
+ fprintf(stderr, "%s: ServerLoop:\t\tpartial packet (%d bytes actually read) on %d\n",
+ progname, port->nBytes, port->sock);
+
+ /*
+ * If we've received at least a PacketHdr's worth of
+ * data and we're still receiving data each time we
+ * read, we're ok. If the client gives us less than a
+ * PacketHdr at the beginning, just kill the
+ * connection and forget about the whole thing.
+ */
+ if (lastbytes < port->nBytes)
+ {
+ if (DebugLvl)
+ fprintf(stderr, "%s: ServerLoop:\t\tpartial packet on %d ok\n",
+ progname, port->sock);
+ curr = DLGetSucc(curr);
+ continue;
+ }
+ break;
+ case STATUS_ERROR: /* system call error - die */
+ fprintf(stderr, "%s: ServerLoop:\t\terror receiving packet\n",
+ progname);
+ return (STATUS_ERROR);
+ }
+ FD_CLR(port->sock, &basemask);
+ StreamClose(port->sock);
+ next = DLGetSucc(curr);
+ DLRemove(curr);
+ free(port);
+ DLFreeElem(curr);
+ curr = next;
+ continue;
+ }
+ curr = DLGetSucc(curr);
+ }
+ Assert(nSelected == 0);
+ }
}
/*
- ConnStartup: get the startup packet from the front end (client),
- authenticate the user, and start up a backend.
+ ConnStartup: get the startup packet from the front end (client),
+ authenticate the user, and start up a backend.
- If all goes well, return *status == STATUS_OK.
- Otherwise, return *status == STATUS_ERROR and return a text string
- explaining why in the "errormsg_len" bytes at "errormsg",
+ If all goes well, return *status == STATUS_OK.
+ Otherwise, return *status == STATUS_ERROR and return a text string
+ explaining why in the "errormsg_len" bytes at "errormsg",
*/
static void
-ConnStartup(Port *port, int *status,
- char *errormsg, const int errormsg_len)
+ConnStartup(Port * port, int *status,
+ char *errormsg, const int errormsg_len)
{
- MsgType msgType;
- char namebuf[NAMEDATALEN];
- int pid;
- PacketBuf *p;
- StartupInfo sp;
- char *tmp;
-
- p = &port->buf;
-
- sp.database[0]='\0';
- sp.user[0]='\0';
- sp.options[0]='\0';
- sp.execFile[0]='\0';
- sp.tty[0]='\0';
-
- tmp= p->data;
- strncpy(sp.database,tmp,sizeof(sp.database));
- tmp += sizeof(sp.database);
- strncpy(sp.user,tmp, sizeof(sp.user));
- tmp += sizeof(sp.user);
- strncpy(sp.options,tmp, sizeof(sp.options));
- tmp += sizeof(sp.options);
- strncpy(sp.execFile,tmp, sizeof(sp.execFile));
- tmp += sizeof(sp.execFile);
- strncpy(sp.tty,tmp, sizeof(sp.tty));
-
- msgType = (MsgType) ntohl(port->buf.msgtype);
-
- strNcpy(namebuf, sp.user, NAMEDATALEN-1);
- if (!namebuf[0]) {
- strncpy(errormsg,
- "No Postgres username specified in startup packet.",
- errormsg_len);
- *status = STATUS_ERROR;
- } else {
- if (be_recvauth(msgType, port, namebuf, &sp) != STATUS_OK) {
- char buffer[200 + sizeof(namebuf)];
- sprintf(buffer,
- "Failed to authenticate client as Postgres user '%s' "
- "using %s: %s",
- namebuf, name_of_authentication_type(msgType), PQerrormsg);
- strncpy(errormsg, buffer, errormsg_len);
- *status = STATUS_ERROR;
- } else {
- if (BackendStartup(&sp, port, &pid) != STATUS_OK) {
- strncpy(errormsg, "Startup (fork) of backend failed.",
- errormsg_len);
- *status = STATUS_ERROR;
- } else {
- errormsg[0] = '\0'; /* just for robustness */
- *status = STATUS_OK;
- }
- }
- }
- if (*status == STATUS_ERROR)
- fprintf(stderr, "%s: ConnStartup: %s\n", progname, errormsg);
+ MsgType msgType;
+ char namebuf[NAMEDATALEN];
+ int pid;
+ PacketBuf *p;
+ StartupInfo sp;
+ char *tmp;
+
+ p = &port->buf;
+
+ sp.database[0] = '\0';
+ sp.user[0] = '\0';
+ sp.options[0] = '\0';
+ sp.execFile[0] = '\0';
+ sp.tty[0] = '\0';
+
+ tmp = p->data;
+ strncpy(sp.database, tmp, sizeof(sp.database));
+ tmp += sizeof(sp.database);
+ strncpy(sp.user, tmp, sizeof(sp.user));
+ tmp += sizeof(sp.user);
+ strncpy(sp.options, tmp, sizeof(sp.options));
+ tmp += sizeof(sp.options);
+ strncpy(sp.execFile, tmp, sizeof(sp.execFile));
+ tmp += sizeof(sp.execFile);
+ strncpy(sp.tty, tmp, sizeof(sp.tty));
+
+ msgType = (MsgType) ntohl(port->buf.msgtype);
+
+ strNcpy(namebuf, sp.user, NAMEDATALEN - 1);
+ if (!namebuf[0])
+ {
+ strncpy(errormsg,
+ "No Postgres username specified in startup packet.",
+ errormsg_len);
+ *status = STATUS_ERROR;
+ }
+ else
+ {
+ if (be_recvauth(msgType, port, namebuf, &sp) != STATUS_OK)
+ {
+ char buffer[200 + sizeof(namebuf)];
+
+ sprintf(buffer,
+ "Failed to authenticate client as Postgres user '%s' "
+ "using %s: %s",
+ namebuf, name_of_authentication_type(msgType), PQerrormsg);
+ strncpy(errormsg, buffer, errormsg_len);
+ *status = STATUS_ERROR;
+ }
+ else
+ {
+ if (BackendStartup(&sp, port, &pid) != STATUS_OK)
+ {
+ strncpy(errormsg, "Startup (fork) of backend failed.",
+ errormsg_len);
+ *status = STATUS_ERROR;
+ }
+ else
+ {
+ errormsg[0] = '\0'; /* just for robustness */
+ *status = STATUS_OK;
+ }
+ }
+ }
+ if (*status == STATUS_ERROR)
+ fprintf(stderr, "%s: ConnStartup: %s\n", progname, errormsg);
}
/*
- send_error_reply: send a reply to the front end telling it that
- the connection was a bust, and why.
-
- "port" tells to whom and how to send the reply. "errormsg" is
- the string of text telling what the problem was.
-
- It should be noted that we're executing a pretty messy protocol
- here. The postmaster does not reply when the connection is
- successful, but rather just hands the connection off to the
- backend and the backend waits for a query from the frontend.
- Thus, the frontend is not expecting any reply in regards to the
- connect request.
-
- But when the connection fails, we send this reply that starts
- with "E". The frontend only gets this reply when it sends its
- first query and waits for the reply. Nobody receives that query,
- but this reply is already in the pipe, so that's what the
- frontend sees.
-
- Note that the backend closes the socket immediately after sending
- the reply, so to give the frontend a fighting chance to see the
- error info, we set the socket to linger up to 3 seconds waiting
- for the frontend to retrieve the message. That's all the delay
- we can afford, since we have other clients to serve and the
- postmaster will be blocked the whole time. Also, if there is no
- message space in the socket for the reply (shouldn't be a
- problem) the postmaster will block until the frontend reads the
- reply.
+ send_error_reply: send a reply to the front end telling it that
+ the connection was a bust, and why.
+
+ "port" tells to whom and how to send the reply. "errormsg" is
+ the string of text telling what the problem was.
+
+ It should be noted that we're executing a pretty messy protocol
+ here. The postmaster does not reply when the connection is
+ successful, but rather just hands the connection off to the
+ backend and the backend waits for a query from the frontend.
+ Thus, the frontend is not expecting any reply in regards to the
+ connect request.
+
+ But when the connection fails, we send this reply that starts
+ with "E". The frontend only gets this reply when it sends its
+ first query and waits for the reply. Nobody receives that query,
+ but this reply is already in the pipe, so that's what the
+ frontend sees.
+
+ Note that the backend closes the socket immediately after sending
+ the reply, so to give the frontend a fighting chance to see the
+ error info, we set the socket to linger up to 3 seconds waiting
+ for the frontend to retrieve the message. That's all the delay
+ we can afford, since we have other clients to serve and the
+ postmaster will be blocked the whole time. Also, if there is no
+ message space in the socket for the reply (shouldn't be a
+ problem) the postmaster will block until the frontend reads the
+ reply.
*/
static void
-send_error_reply(Port *port, const char *errormsg)
+send_error_reply(Port * port, const char *errormsg)
{
- int rc; /* return code from sendto */
- char *reply;
- /* The literal reply string we put into the socket. This is a pointer
- to storage we malloc.
- */
- const struct linger linger_parm = {true, LINGER_TIME};
- /* A parameter for setsockopt() that tells it to have close() block for
- a while waiting for the frontend to read its outstanding messages.
- */
-
- reply = malloc(strlen(errormsg)+10);
-
- sprintf(reply, "E%s", errormsg);
-
- rc = send(port->sock, (Addr) reply, strlen(reply)+1, /* flags */ 0);
- if (rc < 0)
- fprintf(stderr,
- "%s: ServerLoop:\t\t"
- "Failed to send error reply to front end\n",
- progname);
- else if (rc < strlen(reply)+1)
- fprintf(stderr,
- "%s: ServerLoop:\t\t"
- "Only partial error reply sent to front end.\n",
- progname);
-
- free(reply);
- /* Now we have to make sure frontend has a chance to see what we
- just wrote.
- */
- rc = setsockopt(port->sock, SOL_SOCKET, SO_LINGER,
- &linger_parm, sizeof(linger_parm));
+ int rc; /* return code from sendto */
+ char *reply;
+
+ /*
+ * The literal reply string we put into the socket. This is a pointer
+ * to storage we malloc.
+ */
+ const struct linger linger_parm = {true, LINGER_TIME};
+
+ /*
+ * A parameter for setsockopt() that tells it to have close() block
+ * for a while waiting for the frontend to read its outstanding
+ * messages.
+ */
+
+ reply = malloc(strlen(errormsg) + 10);
+
+ sprintf(reply, "E%s", errormsg);
+
+ rc = send(port->sock, (Addr) reply, strlen(reply) + 1, /* flags */ 0);
+ if (rc < 0)
+ fprintf(stderr,
+ "%s: ServerLoop:\t\t"
+ "Failed to send error reply to front end\n",
+ progname);
+ else if (rc < strlen(reply) + 1)
+ fprintf(stderr,
+ "%s: ServerLoop:\t\t"
+ "Only partial error reply sent to front end.\n",
+ progname);
+
+ free(reply);
+
+ /*
+ * Now we have to make sure frontend has a chance to see what we just
+ * wrote.
+ */
+ rc = setsockopt(port->sock, SOL_SOCKET, SO_LINGER,
+ &linger_parm, sizeof(linger_parm));
}
@@ -759,26 +837,29 @@ send_error_reply(Port *port, const char *errormsg)
static int
ConnCreate(int serverFd, int *newFdP)
{
- int status;
- Port *port;
-
-
- if (!(port = (Port *) calloc(1, sizeof(Port)))) {
- fprintf(stderr, "%s: ConnCreate: malloc failed\n",
- progname);
- ExitPostmaster(1);
- }
-
- if ((status = StreamConnection(serverFd, port)) != STATUS_OK) {
- StreamClose(port->sock);
- free(port);
- }
- else {
- DLAddHead(PortList, DLNewElem(port));
- *newFdP = port->sock;
- }
-
- return (status);
+ int status;
+ Port *port;
+
+
+ if (!(port = (Port *) calloc(1, sizeof(Port))))
+ {
+ fprintf(stderr, "%s: ConnCreate: malloc failed\n",
+ progname);
+ ExitPostmaster(1);
+ }
+
+ if ((status = StreamConnection(serverFd, port)) != STATUS_OK)
+ {
+ StreamClose(port->sock);
+ free(port);
+ }
+ else
+ {
+ DLAddHead(PortList, DLNewElem(port));
+ *newFdP = port->sock;
+ }
+
+ return (status);
}
/*
@@ -787,11 +868,11 @@ ConnCreate(int serverFd, int *newFdP)
static void
reset_shared(short port)
{
- IPCKey key;
-
- key = SystemPortAddressCreateIPCKey((SystemPortAddress) port);
- CreateSharedMemoryAndSemaphores(key);
- ActiveBackends = FALSE;
+ IPCKey key;
+
+ key = SystemPortAddressCreateIPCKey((SystemPortAddress) port);
+ CreateSharedMemoryAndSemaphores(key);
+ ActiveBackends = FALSE;
}
/*
@@ -800,7 +881,7 @@ reset_shared(short port)
static void
pmdie(SIGNAL_ARGS)
{
- exitpg(0);
+ exitpg(0);
}
/*
@@ -811,25 +892,29 @@ reaper(SIGNAL_ARGS)
{
/* GH: replace waitpid for !HAVE_WAITPID. Does this work ? */
#ifdef HAVE_WAITPID
- int status; /* backend exit status */
+ int status; /* backend exit status */
+
#else
- union wait statusp; /* backend exit status */
+ union wait statusp; /* backend exit status */
+
#endif
- int pid; /* process id of dead backend */
-
- if (DebugLvl)
- fprintf(stderr, "%s: reaping dead processes...\n",
- progname);
+ int pid; /* process id of dead backend */
+
+ if (DebugLvl)
+ fprintf(stderr, "%s: reaping dead processes...\n",
+ progname);
#ifdef HAVE_WAITPID
- while((pid = waitpid(-1, &status, WNOHANG)) > 0) {
- CleanupProc(pid, status);
- pqsignal(SIGCHLD, reaper);
- }
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
+ {
+ CleanupProc(pid, status);
+ pqsignal(SIGCHLD, reaper);
+ }
#else
- while((pid = wait3(&statusp, WNOHANG, NULL)) > 0) {
- CleanupProc(pid, statusp.w_status);
- pqsignal(SIGCHLD, reaper);
- }
+ while ((pid = wait3(&statusp, WNOHANG, NULL)) > 0)
+ {
+ CleanupProc(pid, statusp.w_status);
+ pqsignal(SIGCHLD, reaper);
+ }
#endif
}
@@ -842,189 +927,204 @@ reaper(SIGNAL_ARGS)
*/
static void
CleanupProc(int pid,
- int exitstatus) /* child's exit status. */
+ int exitstatus) /* child's exit status. */
{
- Dlelem *prev, *curr;
- Backend *bp;
- int sig;
-
- if (DebugLvl) {
- fprintf(stderr, "%s: CleanupProc: pid %d exited with status %d\n",
- progname, pid, exitstatus);
- }
- /*
- * -------------------------
- * If a backend dies in an ugly way (i.e. exit status not 0) then
- * we must signal all other backends to quickdie. If exit status
- * is zero we assume everything is hunky dory and simply remove the
- * backend from the active backend list.
- * -------------------------
- */
- if (!exitstatus) {
- curr = DLGetHead(BackendList);
- while (curr) {
- bp = (Backend*)DLE_VAL(curr);
- if (bp->pid == pid) {
- DLRemove(curr);
- free(bp);
- DLFreeElem(curr);
- break;
- }
- curr = DLGetSucc(curr);
- }
-
- ProcRemove(pid);
-
- return;
- }
-
- curr = DLGetHead(BackendList);
- while (curr) {
- bp = (Backend*)DLE_VAL(curr);
-
- /*
- * -----------------
- * SIGUSR1 is the special signal that sez exit without exitpg
- * and let the user know what's going on. ProcSemaphoreKill()
- * cleans up the backends semaphore. If SendStop is set (-s on
- * command line), then we send a SIGSTOP so that we can
- * core dumps from all backends by hand.
- * -----------------
- */
- sig = (SendStop) ? SIGSTOP : SIGUSR1;
- if (bp->pid != pid) {
- if (DebugLvl)
- fprintf(stderr, "%s: CleanupProc: sending %s to process %d\n",
- progname,
- (sig == SIGUSR1)
- ? "SIGUSR1" : "SIGSTOP",
- bp->pid);
- kill(bp->pid, sig);
- }
- ProcRemove(bp->pid);
-
- prev = DLGetPred(curr);
- DLRemove(curr);
- free(bp);
- DLFreeElem(curr);
- if (!prev) { /* removed head */
- curr = DLGetHead(BackendList);
- continue;
- }
- curr = DLGetSucc(prev);
- }
- /*
- * -------------
- * Quasi_exit means run all of the on_exitpg routines but don't
- * acutally call exit(). The on_exit list of routines to do is
- * also truncated.
- *
- * Nothing up my sleeve here, ActiveBackends means that since the
- * last time we recreated shared memory and sems another frontend
- * has requested and received a connection and I have forked off
- * another backend. This prevents me from reinitializing shared
- * stuff more than once for the set of backends that caused the
- * failure and were killed off.
- * ----------------
- */
- if (ActiveBackends == TRUE && Reinit) {
- if (DebugLvl)
- fprintf(stderr, "%s: CleanupProc: reinitializing shared memory and semaphores\n",
- progname);
- quasi_exitpg();
- reset_shared(PostPortName);
- }
+ Dlelem *prev,
+ *curr;
+ Backend *bp;
+ int sig;
+
+ if (DebugLvl)
+ {
+ fprintf(stderr, "%s: CleanupProc: pid %d exited with status %d\n",
+ progname, pid, exitstatus);
+ }
+
+ /*
+ * ------------------------- If a backend dies in an ugly way (i.e.
+ * exit status not 0) then we must signal all other backends to
+ * quickdie. If exit status is zero we assume everything is hunky
+ * dory and simply remove the backend from the active backend list.
+ * -------------------------
+ */
+ if (!exitstatus)
+ {
+ curr = DLGetHead(BackendList);
+ while (curr)
+ {
+ bp = (Backend *) DLE_VAL(curr);
+ if (bp->pid == pid)
+ {
+ DLRemove(curr);
+ free(bp);
+ DLFreeElem(curr);
+ break;
+ }
+ curr = DLGetSucc(curr);
+ }
+
+ ProcRemove(pid);
+
+ return;
+ }
+
+ curr = DLGetHead(BackendList);
+ while (curr)
+ {
+ bp = (Backend *) DLE_VAL(curr);
+
+ /*
+ * ----------------- SIGUSR1 is the special signal that sez exit
+ * without exitpg and let the user know what's going on.
+ * ProcSemaphoreKill() cleans up the backends semaphore. If
+ * SendStop is set (-s on command line), then we send a SIGSTOP so
+ * that we can core dumps from all backends by hand.
+ * -----------------
+ */
+ sig = (SendStop) ? SIGSTOP : SIGUSR1;
+ if (bp->pid != pid)
+ {
+ if (DebugLvl)
+ fprintf(stderr, "%s: CleanupProc: sending %s to process %d\n",
+ progname,
+ (sig == SIGUSR1)
+ ? "SIGUSR1" : "SIGSTOP",
+ bp->pid);
+ kill(bp->pid, sig);
+ }
+ ProcRemove(bp->pid);
+
+ prev = DLGetPred(curr);
+ DLRemove(curr);
+ free(bp);
+ DLFreeElem(curr);
+ if (!prev)
+ { /* removed head */
+ curr = DLGetHead(BackendList);
+ continue;
+ }
+ curr = DLGetSucc(prev);
+ }
+
+ /*
+ * ------------- Quasi_exit means run all of the on_exitpg routines
+ * but don't acutally call exit(). The on_exit list of routines to do
+ * is also truncated.
+ *
+ * Nothing up my sleeve here, ActiveBackends means that since the last
+ * time we recreated shared memory and sems another frontend has
+ * requested and received a connection and I have forked off another
+ * backend. This prevents me from reinitializing shared stuff more
+ * than once for the set of backends that caused the failure and were
+ * killed off. ----------------
+ */
+ if (ActiveBackends == TRUE && Reinit)
+ {
+ if (DebugLvl)
+ fprintf(stderr, "%s: CleanupProc: reinitializing shared memory and semaphores\n",
+ progname);
+ quasi_exitpg();
+ reset_shared(PostPortName);
+ }
}
/*
* BackendStartup -- start backend process
*
* returns: STATUS_ERROR if the fork/exec failed, STATUS_OK
- * otherwise.
+ * otherwise.
*
*/
static int
-BackendStartup(StartupInfo *packet, /* client's startup packet */
- Port *port,
- int *pidPtr)
+BackendStartup(StartupInfo * packet, /* client's startup packet */
+ Port * port,
+ int *pidPtr)
{
- Backend* bn; /* for backend cleanup */
- int pid, i;
- static char envEntry[4][2 * ARGV_SIZE];
-
- for (i = 0; i < 4; ++i) {
- memset(envEntry[i], 0, 2*ARGV_SIZE);
- }
- /*
- * Set up the necessary environment variables for the backend
- * This should really be some sort of message....
- */
- sprintf(envEntry[0], "POSTPORT=%d", PostPortName);
- putenv(envEntry[0]);
- sprintf(envEntry[1], "POSTID=%d", NextBackendId);
- putenv(envEntry[1]);
- sprintf(envEntry[2], "PG_USER=%s", packet->user);
- putenv(envEntry[2]);
- if (!getenv("PGDATA")) {
- sprintf(envEntry[3], "PGDATA=%s", DataDir);
- putenv(envEntry[3]);
- }
- if (DebugLvl > 2) {
- char **p;
- extern char **environ;
-
- fprintf(stderr, "%s: BackendStartup: environ dump:\n",
- progname);
- fprintf(stderr, "-----------------------------------------\n");
- for (p = environ; *p; ++p)
- fprintf(stderr, "\t%s\n", *p);
- fprintf(stderr, "-----------------------------------------\n");
- }
-
- if ((pid = FORK()) == 0) { /* child */
- if (DoExec(packet, port->sock))
- fprintf(stderr, "%s child[%d]: BackendStartup: execv failed\n",
- progname, pid);
- /* use _exit to keep from double-flushing stdio */
- _exit(1);
- }
-
- /* in parent */
- if (pid < 0) {
- fprintf(stderr, "%s: BackendStartup: fork failed\n",
- progname);
- return(STATUS_ERROR);
- }
-
- if (DebugLvl)
- fprintf(stderr, "%s: BackendStartup: pid %d user %s db %s socket %d\n",
- progname, pid, packet->user,
- (packet->database[0] == '\0' ? packet->user : packet->database),
- port->sock);
-
- /* adjust backend counter */
- /* XXX Don't know why this is done, but for now backend needs it */
- NextBackendId -= 1;
-
- /*
- * Everything's been successful, it's safe to add this backend to our
- * list of backends.
- */
- if (!(bn = (Backend *) calloc(1, sizeof (Backend)))) {
- fprintf(stderr, "%s: BackendStartup: malloc failed\n",
- progname);
- ExitPostmaster(1);
- }
-
- bn->pid = pid;
- DLAddHead(BackendList,DLNewElem(bn));
-
- if (MultiplexedBackends)
- MultiplexedBackendPort++;
-
- *pidPtr = pid;
-
- return(STATUS_OK);
+ Backend *bn; /* for backend cleanup */
+ int pid,
+ i;
+ static char envEntry[4][2 * ARGV_SIZE];
+
+ for (i = 0; i < 4; ++i)
+ {
+ memset(envEntry[i], 0, 2 * ARGV_SIZE);
+ }
+
+ /*
+ * Set up the necessary environment variables for the backend This
+ * should really be some sort of message....
+ */
+ sprintf(envEntry[0], "POSTPORT=%d", PostPortName);
+ putenv(envEntry[0]);
+ sprintf(envEntry[1], "POSTID=%d", NextBackendId);
+ putenv(envEntry[1]);
+ sprintf(envEntry[2], "PG_USER=%s", packet->user);
+ putenv(envEntry[2]);
+ if (!getenv("PGDATA"))
+ {
+ sprintf(envEntry[3], "PGDATA=%s", DataDir);
+ putenv(envEntry[3]);
+ }
+ if (DebugLvl > 2)
+ {
+ char **p;
+ extern char **environ;
+
+ fprintf(stderr, "%s: BackendStartup: environ dump:\n",
+ progname);
+ fprintf(stderr, "-----------------------------------------\n");
+ for (p = environ; *p; ++p)
+ fprintf(stderr, "\t%s\n", *p);
+ fprintf(stderr, "-----------------------------------------\n");
+ }
+
+ if ((pid = FORK()) == 0)
+ { /* child */
+ if (DoExec(packet, port->sock))
+ fprintf(stderr, "%s child[%d]: BackendStartup: execv failed\n",
+ progname, pid);
+ /* use _exit to keep from double-flushing stdio */
+ _exit(1);
+ }
+
+ /* in parent */
+ if (pid < 0)
+ {
+ fprintf(stderr, "%s: BackendStartup: fork failed\n",
+ progname);
+ return (STATUS_ERROR);
+ }
+
+ if (DebugLvl)
+ fprintf(stderr, "%s: BackendStartup: pid %d user %s db %s socket %d\n",
+ progname, pid, packet->user,
+ (packet->database[0] == '\0' ? packet->user : packet->database),
+ port->sock);
+
+ /* adjust backend counter */
+ /* XXX Don't know why this is done, but for now backend needs it */
+ NextBackendId -= 1;
+
+ /*
+ * Everything's been successful, it's safe to add this backend to our
+ * list of backends.
+ */
+ if (!(bn = (Backend *) calloc(1, sizeof(Backend))))
+ {
+ fprintf(stderr, "%s: BackendStartup: malloc failed\n",
+ progname);
+ ExitPostmaster(1);
+ }
+
+ bn->pid = pid;
+ DLAddHead(BackendList, DLNewElem(bn));
+
+ if (MultiplexedBackends)
+ MultiplexedBackendPort++;
+
+ *pidPtr = pid;
+
+ return (STATUS_OK);
}
/*
@@ -1040,19 +1140,20 @@ BackendStartup(StartupInfo *packet, /* client's startup packet */
static void
split_opts(char **argv, int *argcp, char *s)
{
- int i = *argcp;
-
- while (s && *s) {
- while (isspace(*s))
- ++s;
- if (*s)
- argv[i++] = s;
- while (*s && !isspace(*s))
- ++s;
- if (isspace(*s))
- *s++ = '\0';
- }
- *argcp = i;
+ int i = *argcp;
+
+ while (s && *s)
+ {
+ while (isspace(*s))
+ ++s;
+ if (*s)
+ argv[i++] = s;
+ while (*s && !isspace(*s))
+ ++s;
+ if (isspace(*s))
+ *s++ = '\0';
+ }
+ *argcp = i;
}
/*
@@ -1063,88 +1164,93 @@ split_opts(char **argv, int *argcp, char *s)
* its thread back. (This is vfork() we're talking about. If we're using
* fork() because we don't have vfork(), then we don't really care.)
*
- * returns:
- * Shouldn't return at all.
- * If execv() fails, return status.
+ * returns:
+ * Shouldn't return at all.
+ * If execv() fails, return status.
*/
static int
-DoExec(StartupInfo *packet, int portFd)
+DoExec(StartupInfo * packet, int portFd)
{
- char execbuf[MAXPATHLEN];
- char portbuf[ARGV_SIZE];
- char mbbuf[ARGV_SIZE];
- char debugbuf[ARGV_SIZE];
- char ttybuf[ARGV_SIZE + 1];
- char argbuf[(2 * ARGV_SIZE) + 1];
- /*
- * each argument takes at least three chars, so we can't
- * have more than ARGV_SIZE arguments in (2 * ARGV_SIZE)
- * chars (i.e., packet->options plus ExtraOptions)...
- */
- char *av[ARGV_SIZE];
- char dbbuf[ARGV_SIZE + 1];
- int ac = 0;
- int i;
-
- strncpy(execbuf, Execfile, MAXPATHLEN-1);
- av[ac++] = execbuf;
-
- /* Tell the backend it is being called from the postmaster */
- av[ac++] = "-p";
-
- /*
- * Pass the requested debugging level along to the backend. We
- * decrement by one; level one debugging in the postmaster traces
- * postmaster connection activity, and levels two and higher
- * are passed along to the backend. This allows us to watch only
- * the postmaster or the postmaster and the backend.
- */
-
- if (DebugLvl > 1) {
- sprintf(debugbuf, "-d%d", DebugLvl);
- av[ac++] = debugbuf;
- }
- else
- av[ac++] = "-Q";
-
- /* Pass the requested debugging output file */
- if (packet->tty[0]) {
- strncpy(ttybuf, packet->tty, ARGV_SIZE);
- av[ac++] = "-o";
- av[ac++] = ttybuf;
- }
-
- /* tell the multiplexed backend to start on a certain port */
- if (MultiplexedBackends) {
- sprintf(mbbuf, "-m %d", MultiplexedBackendPort);
- av[ac++] = mbbuf;
- }
- /* Tell the backend the descriptor of the fe/be socket */
- sprintf(portbuf, "-P%d", portFd);
- av[ac++] = portbuf;
-
- strNcpy(argbuf, packet->options, ARGV_SIZE);
- strncat(argbuf, ExtraOptions, ARGV_SIZE);
- argbuf[(2 * ARGV_SIZE)] = '\0';
- split_opts(av, &ac, argbuf);
-
- if (packet->database[0])
- strNcpy(dbbuf, packet->database, ARGV_SIZE);
- else
- strNcpy(dbbuf, packet->user, NAMEDATALEN-1);
- av[ac++] = dbbuf;
-
- av[ac] = (char *) NULL;
-
- if (DebugLvl > 1) {
- fprintf(stderr, "%s child[%ld]: execv(",
- progname, (long)getpid());
- for (i = 0; i < ac; ++i)
- fprintf(stderr, "%s, ", av[i]);
- fprintf(stderr, ")\n");
- }
-
- return(execv(av[0], av));
+ char execbuf[MAXPATHLEN];
+ char portbuf[ARGV_SIZE];
+ char mbbuf[ARGV_SIZE];
+ char debugbuf[ARGV_SIZE];
+ char ttybuf[ARGV_SIZE + 1];
+ char argbuf[(2 * ARGV_SIZE) + 1];
+
+ /*
+ * each argument takes at least three chars, so we can't have more
+ * than ARGV_SIZE arguments in (2 * ARGV_SIZE) chars (i.e.,
+ * packet->options plus ExtraOptions)...
+ */
+ char *av[ARGV_SIZE];
+ char dbbuf[ARGV_SIZE + 1];
+ int ac = 0;
+ int i;
+
+ strncpy(execbuf, Execfile, MAXPATHLEN - 1);
+ av[ac++] = execbuf;
+
+ /* Tell the backend it is being called from the postmaster */
+ av[ac++] = "-p";
+
+ /*
+ * Pass the requested debugging level along to the backend. We
+ * decrement by one; level one debugging in the postmaster traces
+ * postmaster connection activity, and levels two and higher are
+ * passed along to the backend. This allows us to watch only the
+ * postmaster or the postmaster and the backend.
+ */
+
+ if (DebugLvl > 1)
+ {
+ sprintf(debugbuf, "-d%d", DebugLvl);
+ av[ac++] = debugbuf;
+ }
+ else
+ av[ac++] = "-Q";
+
+ /* Pass the requested debugging output file */
+ if (packet->tty[0])
+ {
+ strncpy(ttybuf, packet->tty, ARGV_SIZE);
+ av[ac++] = "-o";
+ av[ac++] = ttybuf;
+ }
+
+ /* tell the multiplexed backend to start on a certain port */
+ if (MultiplexedBackends)
+ {
+ sprintf(mbbuf, "-m %d", MultiplexedBackendPort);
+ av[ac++] = mbbuf;
+ }
+ /* Tell the backend the descriptor of the fe/be socket */
+ sprintf(portbuf, "-P%d", portFd);
+ av[ac++] = portbuf;
+
+ strNcpy(argbuf, packet->options, ARGV_SIZE);
+ strncat(argbuf, ExtraOptions, ARGV_SIZE);
+ argbuf[(2 * ARGV_SIZE)] = '\0';
+ split_opts(av, &ac, argbuf);
+
+ if (packet->database[0])
+ strNcpy(dbbuf, packet->database, ARGV_SIZE);
+ else
+ strNcpy(dbbuf, packet->user, NAMEDATALEN - 1);
+ av[ac++] = dbbuf;
+
+ av[ac] = (char *) NULL;
+
+ if (DebugLvl > 1)
+ {
+ fprintf(stderr, "%s child[%ld]: execv(",
+ progname, (long) getpid());
+ for (i = 0; i < ac; ++i)
+ fprintf(stderr, "%s, ", av[i]);
+ fprintf(stderr, ")\n");
+ }
+
+ return (execv(av[0], av));
}
/*
@@ -1153,34 +1259,31 @@ DoExec(StartupInfo *packet, int portFd)
static void
ExitPostmaster(int status)
{
- /* should cleanup shared memory and kill all backends */
-
- /*
- * Not sure of the semantics here. When the Postmaster dies,
- * should the backends all be killed? probably not.
- */
- if (ServerSock != INVALID_SOCK)
- close(ServerSock);
- exitpg(status);
+ /* should cleanup shared memory and kill all backends */
+
+ /*
+ * Not sure of the semantics here. When the Postmaster dies, should
+ * the backends all be killed? probably not.
+ */
+ if (ServerSock != INVALID_SOCK)
+ close(ServerSock);
+ exitpg(status);
}
static void
dumpstatus(SIGNAL_ARGS)
{
- Dlelem *curr = DLGetHead(PortList);
-
- while (curr) {
- Port *port = DLE_VAL(curr);
-
- fprintf(stderr, "%s: dumpstatus:\n", progname);
- fprintf(stderr, "\tsock %d: nBytes=%d, laddr=0x%lx, raddr=0x%lx\n",
- port->sock, port->nBytes,
- (long int) port->laddr.sin_addr.s_addr,
- (long int) port->raddr.sin_addr.s_addr);
- curr = DLGetSucc(curr);
- }
+ Dlelem *curr = DLGetHead(PortList);
+
+ while (curr)
+ {
+ Port *port = DLE_VAL(curr);
+
+ fprintf(stderr, "%s: dumpstatus:\n", progname);
+ fprintf(stderr, "\tsock %d: nBytes=%d, laddr=0x%lx, raddr=0x%lx\n",
+ port->sock, port->nBytes,
+ (long int) port->laddr.sin_addr.s_addr,
+ (long int) port->raddr.sin_addr.s_addr);
+ curr = DLGetSucc(curr);
+ }
}
-
-
-
-
diff --git a/src/backend/regex/engine.c b/src/backend/regex/engine.c
index 3c323586d6b..6e0e7012140 100644
--- a/src/backend/regex/engine.c
+++ b/src/backend/regex/engine.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)engine.c 8.5 (Berkeley) 3/20/94
+ * @(#)engine.c 8.5 (Berkeley) 3/20/94
*/
/*
@@ -45,150 +45,157 @@
*/
#ifdef SNAMES
-#define matcher smatcher
-#define fast sfast
-#define slow sslow
-#define dissect sdissect
-#define backref sbackref
-#define step sstep
-#define print sprint
-#define at sat
-#define match smat
+#define matcher smatcher
+#define fast sfast
+#define slow sslow
+#define dissect sdissect
+#define backref sbackref
+#define step sstep
+#define print sprint
+#define at sat
+#define match smat
#endif
#ifdef LNAMES
-#define matcher lmatcher
-#define fast lfast
-#define slow lslow
-#define dissect ldissect
-#define backref lbackref
-#define step lstep
-#define print lprint
-#define at lat
-#define match lmat
+#define matcher lmatcher
+#define fast lfast
+#define slow lslow
+#define dissect ldissect
+#define backref lbackref
+#define step lstep
+#define print lprint
+#define at lat
+#define match lmat
#endif
/* another structure passed up and down to avoid zillions of parameters */
-struct match {
+struct match
+{
struct re_guts *g;
- int eflags;
- regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
- char *offp; /* offsets work from here */
- char *beginp; /* start of string -- virtual NUL precedes */
- char *endp; /* end of string -- virtual NUL here */
- char *coldp; /* can be no match starting before here */
- char **lastpos; /* [nplus+1] */
- STATEVARS;
- states st; /* current states */
- states fresh; /* states for a fresh start */
- states tmp; /* temporary */
- states empty; /* empty set of states */
+ int eflags;
+ regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
+ char *offp; /* offsets work from here */
+ char *beginp; /* start of string -- virtual NUL precedes */
+ char *endp; /* end of string -- virtual NUL here */
+ char *coldp; /* can be no match starting before here */
+ char **lastpos; /* [nplus+1] */
+ STATEVARS;
+ states st; /* current states */
+ states fresh; /* states for a fresh start */
+ states tmp; /* temporary */
+ states empty; /* empty set of states */
};
/* ========= begin header generated by ./mkh ========= */
#ifdef __cplusplus
-extern "C" {
+extern "C"
+{
#endif
/* === engine.c === */
-static int
-matcher(struct re_guts *g, char *string, size_t nmatch,
- regmatch_t pmatch[], int eflags);
-static char *
-dissect(struct match *m, char *start, char *stop,
- sopno startst, sopno stopst);
-static char *
-backref(struct match *m, char *start, char *stop,
- sopno startst, sopno stopst, sopno lev);
-static char *
-fast(struct match *m, char *start, char *stop,
- sopno startst, sopno stopst);
-static char *
-slow(struct match *m, char *start, char *stop, sopno startst, sopno stopst);
-static states
-step(struct re_guts *g, sopno start,
- sopno stop, states bef, int ch, states aft);
-#define BOL (OUT+1)
-#define EOL (BOL+1)
-#define BOLEOL (BOL+2)
-#define NOTHING (BOL+3)
-#define BOW (BOL+4)
-#define EOW (BOL+5)
-#define CODEMAX (BOL+5) /* highest code used */
-#define NONCHAR(c) ((c) > CHAR_MAX)
-#define NNONCHAR (CODEMAX-CHAR_MAX)
+ static int
+ matcher(struct re_guts * g, char *string, size_t nmatch,
+ regmatch_t pmatch[], int eflags);
+ static char *
+ dissect(struct match * m, char *start, char *stop,
+ sopno startst, sopno stopst);
+ static char *
+ backref(struct match * m, char *start, char *stop,
+ sopno startst, sopno stopst, sopno lev);
+ static char *
+ fast(struct match * m, char *start, char *stop,
+ sopno startst, sopno stopst);
+ static char *
+ slow(struct match * m, char *start, char *stop, sopno startst, sopno stopst);
+ static states
+ step(struct re_guts * g, sopno start,
+ sopno stop, states bef, int ch, states aft);
+#define BOL (OUT+1)
+#define EOL (BOL+1)
+#define BOLEOL (BOL+2)
+#define NOTHING (BOL+3)
+#define BOW (BOL+4)
+#define EOW (BOL+5)
+#define CODEMAX (BOL+5) /* highest code used */
+#define NONCHAR(c) ((c) > CHAR_MAX)
+#define NNONCHAR (CODEMAX-CHAR_MAX)
#ifdef REDEBUG
-static void
-print(struct match *m, char *caption, states st, int ch, FILE *d);
+ static void
+ print(struct match * m, char *caption, states st, int ch, FILE * d);
#endif
#ifdef REDEBUG
-static void
-at(struct match *m, char *title, char *start, char *stop,
- sopno startst, sopno stopst);
+ static void
+ at(struct match * m, char *title, char *start, char *stop,
+ sopno startst, sopno stopst);
#endif
#ifdef REDEBUG
-static char *
-pchar(int ch);
+ static char *
+ pchar(int ch);
#endif
#ifdef __cplusplus
}
+
#endif
/* ========= end header generated by ./mkh ========= */
#ifdef REDEBUG
-#define SP(t, s, c) print(m, t, s, c, stdout)
-#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2)
-#define NOTE(str) { if (m->eflags&REG_TRACE) printf("=%s\n", (str)); }
+#define SP(t, s, c) print(m, t, s, c, stdout)
+#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2)
+#define NOTE(str) { if (m->eflags&REG_TRACE) printf("=%s\n", (str)); }
#else
-#define SP(t, s, c) /* nothing */
-#define AT(t, p1, p2, s1, s2) /* nothing */
-#define NOTE(s) /* nothing */
+#define SP(t, s, c) /* nothing */
+#define AT(t, p1, p2, s1, s2) /* nothing */
+#define NOTE(s) /* nothing */
#endif
/*
- matcher - the actual matching engine
== static int matcher(register struct re_guts *g, char *string, \
- == size_t nmatch, regmatch_t pmatch[], int eflags);
+ == size_t nmatch, regmatch_t pmatch[], int eflags);
*/
-static int /* 0 success, REG_NOMATCH failure */
+static int /* 0 success, REG_NOMATCH failure */
matcher(g, string, nmatch, pmatch, eflags)
register struct re_guts *g;
-char *string;
-size_t nmatch;
-regmatch_t pmatch[];
-int eflags;
+char *string;
+size_t nmatch;
+regmatch_t pmatch[];
+int eflags;
{
- register char *endp;
- register int i;
- struct match mv;
+ register char *endp;
+ register int i;
+ struct match mv;
register struct match *m = &mv;
- register char *dp;
- register const sopno gf = g->firststate+1; /* +1 for OEND */
+ register char *dp;
+ register const sopno gf = g->firststate + 1; /* +1 for OEND */
register const sopno gl = g->laststate;
- char *start;
- char *stop;
+ char *start;
+ char *stop;
/* simplify the situation where possible */
- if (g->cflags&REG_NOSUB)
+ if (g->cflags & REG_NOSUB)
nmatch = 0;
- if (eflags&REG_STARTEND) {
+ if (eflags & REG_STARTEND)
+ {
start = string + pmatch[0].rm_so;
stop = string + pmatch[0].rm_eo;
- } else {
+ }
+ else
+ {
start = string;
stop = start + strlen(start);
}
if (stop < start)
- return(REG_INVARG);
+ return (REG_INVARG);
/* prescreening; this does wonders for this rather slow code */
- if (g->must != NULL) {
+ if (g->must != NULL)
+ {
for (dp = start; dp < stop; dp++)
if (*dp == g->must[0] && stop - dp >= g->mlen &&
- memcmp(dp, g->must, (size_t)g->mlen) == 0)
+ memcmp(dp, g->must, (size_t) g->mlen) == 0)
break;
- if (dp == stop) /* we didn't find g->must */
- return(REG_NOMATCH);
+ if (dp == stop) /* we didn't find g->must */
+ return (REG_NOMATCH);
}
/* match struct setup */
@@ -207,18 +214,21 @@ int eflags;
CLEAR(m->empty);
/* this loop does only one repetition except for backrefs */
- for (;;) {
+ for (;;)
+ {
endp = fast(m, start, stop, gf, gl);
- if (endp == NULL) { /* a miss */
+ if (endp == NULL)
+ { /* a miss */
STATETEARDOWN(m);
- return(REG_NOMATCH);
+ return (REG_NOMATCH);
}
if (nmatch == 0 && !g->backrefs)
- break; /* no further info needed */
+ break; /* no further info needed */
/* where? */
assert(m->coldp != NULL);
- for (;;) {
+ for (;;)
+ {
NOTE("finding start");
endp = slow(m, m->coldp, stop, gf, gl);
if (endp != NULL)
@@ -227,32 +237,37 @@ int eflags;
m->coldp++;
}
if (nmatch == 1 && !g->backrefs)
- break; /* no further info needed */
+ break; /* no further info needed */
/* oh my, he wants the subexpressions... */
if (m->pmatch == NULL)
- m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) *
- sizeof(regmatch_t));
- if (m->pmatch == NULL) {
+ m->pmatch = (regmatch_t *) malloc((m->g->nsub + 1) *
+ sizeof(regmatch_t));
+ if (m->pmatch == NULL)
+ {
STATETEARDOWN(m);
- return(REG_ESPACE);
+ return (REG_ESPACE);
}
for (i = 1; i <= m->g->nsub; i++)
m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1;
- if (!g->backrefs && !(m->eflags&REG_BACKR)) {
+ if (!g->backrefs && !(m->eflags & REG_BACKR))
+ {
NOTE("dissecting");
dp = dissect(m, m->coldp, endp, gf, gl);
- } else {
+ }
+ else
+ {
+ if (g->nplus > 0 && m->lastpos == NULL)
+ m->lastpos = (char **) malloc((g->nplus + 1) *
+ sizeof(char *));
if (g->nplus > 0 && m->lastpos == NULL)
- m->lastpos = (char **)malloc((g->nplus+1) *
- sizeof(char *));
- if (g->nplus > 0 && m->lastpos == NULL) {
+ {
free(m->pmatch);
STATETEARDOWN(m);
- return(REG_ESPACE);
+ return (REG_ESPACE);
}
NOTE("backref dissect");
- dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
+ dp = backref(m, m->coldp, endp, gf, gl, (sopno) 0);
}
if (dp != NULL)
break;
@@ -260,25 +275,27 @@ int eflags;
/* uh-oh... we couldn't find a subexpression-level match */
assert(g->backrefs); /* must be back references doing it */
assert(g->nplus == 0 || m->lastpos != NULL);
- for (;;) {
+ for (;;)
+ {
if (dp != NULL || endp <= m->coldp)
- break; /* defeat */
+ break; /* defeat */
NOTE("backoff");
- endp = slow(m, m->coldp, endp-1, gf, gl);
+ endp = slow(m, m->coldp, endp - 1, gf, gl);
if (endp == NULL)
- break; /* defeat */
+ break; /* defeat */
/* try it on a shorter possibility */
#ifndef NDEBUG
- for (i = 1; i <= m->g->nsub; i++) {
+ for (i = 1; i <= m->g->nsub; i++)
+ {
assert(m->pmatch[i].rm_so == -1);
assert(m->pmatch[i].rm_eo == -1);
}
#endif
NOTE("backoff dissect");
- dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
+ dp = backref(m, m->coldp, endp, gf, gl, (sopno) 0);
}
assert(dp == NULL || dp == endp);
- if (dp != NULL) /* found a shorter one */
+ if (dp != NULL) /* found a shorter one */
break;
/* despite initial appearances, there is no match here */
@@ -288,62 +305,67 @@ int eflags;
}
/* fill in the details if requested */
- if (nmatch > 0) {
+ if (nmatch > 0)
+ {
pmatch[0].rm_so = m->coldp - m->offp;
pmatch[0].rm_eo = endp - m->offp;
}
- if (nmatch > 1) {
+ if (nmatch > 1)
+ {
assert(m->pmatch != NULL);
for (i = 1; i < nmatch; i++)
if (i <= m->g->nsub)
pmatch[i] = m->pmatch[i];
- else {
+ else
+ {
pmatch[i].rm_so = -1;
pmatch[i].rm_eo = -1;
}
}
if (m->pmatch != NULL)
- free((char *)m->pmatch);
+ free((char *) m->pmatch);
if (m->lastpos != NULL)
- free((char *)m->lastpos);
+ free((char *) m->lastpos);
STATETEARDOWN(m);
- return(0);
+ return (0);
}
/*
- dissect - figure out what matched what, no back references
== static char *dissect(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst);
+ == char *stop, sopno startst, sopno stopst);
*/
-static char * /* == stop (success) always */
+static char * /* == stop (success) always */
dissect(m, start, stop, startst, stopst)
register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
{
- register int i;
- register sopno ss; /* start sop of current subRE */
- register sopno es; /* end sop of current subRE */
- register char *sp; /* start of string matched by it */
- register char *stp; /* string matched by it cannot pass here */
- register char *rest; /* start of rest of string */
- register char *tail; /* string unmatched by rest of RE */
- register sopno ssub; /* start sop of subsubRE */
- register sopno esub; /* end sop of subsubRE */
- register char *ssp; /* start of string matched by subsubRE */
- register char *sep; /* end of string matched by subsubRE */
- register char *oldssp; /* previous ssp */
- register char *dp;
+ register int i;
+ register sopno ss; /* start sop of current subRE */
+ register sopno es; /* end sop of current subRE */
+ register char *sp; /* start of string matched by it */
+ register char *stp; /* string matched by it cannot pass here */
+ register char *rest; /* start of rest of string */
+ register char *tail; /* string unmatched by rest of RE */
+ register sopno ssub; /* start sop of subsubRE */
+ register sopno esub; /* end sop of subsubRE */
+ register char *ssp; /* start of string matched by subsubRE */
+ register char *sep; /* end of string matched by subsubRE */
+ register char *oldssp; /* previous ssp */
+ register char *dp;
AT("diss", start, stop, startst, stopst);
sp = start;
- for (ss = startst; ss < stopst; ss = es) {
+ for (ss = startst; ss < stopst; ss = es)
+ {
/* identify end of subRE */
es = ss;
- switch (OP(m->g->strip[es])) {
+ switch (OP(m->g->strip[es]))
+ {
case OPLUS_:
case OQUEST_:
es += OPND(m->g->strip[es]);
@@ -356,7 +378,8 @@ sopno stopst;
es++;
/* figure out what it matched */
- switch (OP(m->g->strip[ss])) {
+ switch (OP(m->g->strip[ss]))
+ {
case OEND:
assert(nope);
break;
@@ -376,10 +399,11 @@ sopno stopst;
case O_BACK:
assert(nope);
break;
- /* cases where length of match is hard to find */
+ /* cases where length of match is hard to find */
case OQUEST_:
stp = stop;
- for (;;) {
+ for (;;)
+ {
/* how long could this one be? */
rest = slow(m, sp, stp, ss, es);
assert(rest != NULL); /* it did match */
@@ -389,21 +413,25 @@ sopno stopst;
break; /* yes! */
/* no -- try a shorter match for this one */
stp = rest - 1;
- assert(stp >= sp); /* it did work */
+ assert(stp >= sp); /* it did work */
}
ssub = ss + 1;
esub = es - 1;
/* did innards match? */
- if (slow(m, sp, rest, ssub, esub) != NULL) {
+ if (slow(m, sp, rest, ssub, esub) != NULL)
+ {
dp = dissect(m, sp, rest, ssub, esub);
assert(dp == rest);
- } else /* no */
+ }
+ else
+/* no */
assert(sp == rest);
sp = rest;
break;
case OPLUS_:
stp = stop;
- for (;;) {
+ for (;;)
+ {
/* how long could this one be? */
rest = slow(m, sp, stp, ss, es);
assert(rest != NULL); /* it did match */
@@ -413,25 +441,27 @@ sopno stopst;
break; /* yes! */
/* no -- try a shorter match for this one */
stp = rest - 1;
- assert(stp >= sp); /* it did work */
+ assert(stp >= sp); /* it did work */
}
ssub = ss + 1;
esub = es - 1;
ssp = sp;
oldssp = ssp;
- for (;;) { /* find last match of innards */
+ for (;;)
+ { /* find last match of innards */
sep = slow(m, ssp, rest, ssub, esub);
if (sep == NULL || sep == ssp)
- break; /* failed or matched null */
+ break; /* failed or matched null */
oldssp = ssp; /* on to next try */
ssp = sep;
}
- if (sep == NULL) {
+ if (sep == NULL)
+ {
/* last successful match */
sep = ssp;
ssp = oldssp;
}
- assert(sep == rest); /* must exhaust substring */
+ assert(sep == rest);/* must exhaust substring */
assert(slow(m, ssp, sep, ssub, esub) == rest);
dp = dissect(m, ssp, sep, ssub, esub);
assert(dp == sep);
@@ -439,7 +469,8 @@ sopno stopst;
break;
case OCH_:
stp = stop;
- for (;;) {
+ for (;;)
+ {
/* how long could this one be? */
rest = slow(m, sp, stp, ss, es);
assert(rest != NULL); /* it did match */
@@ -449,14 +480,15 @@ sopno stopst;
break; /* yes! */
/* no -- try a shorter match for this one */
stp = rest - 1;
- assert(stp >= sp); /* it did work */
+ assert(stp >= sp); /* it did work */
}
ssub = ss + 1;
esub = ss + OPND(m->g->strip[ss]) - 1;
assert(OP(m->g->strip[esub]) == OOR1);
- for (;;) { /* find first matching branch */
+ for (;;)
+ { /* find first matching branch */
if (slow(m, sp, rest, ssub, esub) == rest)
- break; /* it matched all of it */
+ break; /* it matched all of it */
/* that one missed, try next one */
assert(OP(m->g->strip[esub]) == OOR1);
esub++;
@@ -489,42 +521,42 @@ sopno stopst;
assert(0 < i && i <= m->g->nsub);
m->pmatch[i].rm_eo = sp - m->offp;
break;
- default: /* uh oh */
+ default: /* uh oh */
assert(nope);
break;
}
}
assert(sp == stop);
- return(sp);
+ return (sp);
}
/*
- backref - figure out what matched what, figuring in back references
== static char *backref(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst, sopno lev);
+ == char *stop, sopno startst, sopno stopst, sopno lev);
*/
-static char * /* == stop (success) or NULL (failure) */
+static char * /* == stop (success) or NULL (failure) */
backref(m, start, stop, startst, stopst, lev)
register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
-sopno lev; /* PLUS nesting level */
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+sopno lev; /* PLUS nesting level */
{
- register int i;
- register sopno ss; /* start sop of current subRE */
- register char *sp; /* start of string matched by it */
- register sopno ssub; /* start sop of subsubRE */
- register sopno esub; /* end sop of subsubRE */
- register char *ssp; /* start of string matched by subsubRE */
- register char *dp;
+ register int i;
+ register sopno ss; /* start sop of current subRE */
+ register char *sp; /* start of string matched by it */
+ register sopno ssub; /* start sop of subsubRE */
+ register sopno esub; /* end sop of subsubRE */
+ register char *ssp; /* start of string matched by subsubRE */
+ register char *dp;
register size_t len;
- register int hard;
- register sop s;
+ register int hard;
+ register sop s;
register regoff_t offsave;
- register cset *cs;
+ register cset *cs;
AT("back", start, stop, startst, stopst);
sp = start;
@@ -532,135 +564,144 @@ sopno lev; /* PLUS nesting level */
/* get as far as we can with easy stuff */
hard = 0;
for (ss = startst; !hard && ss < stopst; ss++)
- switch (OP(s = m->g->strip[ss])) {
+ switch (OP(s = m->g->strip[ss]))
+ {
case OCHAR:
- if (sp == stop || *sp++ != (char)OPND(s))
- return(NULL);
+ if (sp == stop || *sp++ != (char) OPND(s))
+ return (NULL);
break;
case OANY:
if (sp == stop)
- return(NULL);
+ return (NULL);
sp++;
break;
case OANYOF:
cs = &m->g->sets[OPND(s)];
if (sp == stop || !CHIN(cs, *sp++))
- return(NULL);
+ return (NULL);
break;
case OBOL:
- if ( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
- (sp < m->endp && *(sp-1) == '\n' &&
- (m->g->cflags&REG_NEWLINE)) )
- { /* yes */ }
+ if ((sp == m->beginp && !(m->eflags & REG_NOTBOL)) ||
+ (sp < m->endp && *(sp - 1) == '\n' &&
+ (m->g->cflags & REG_NEWLINE)))
+ { /* yes */
+ }
else
- return(NULL);
+ return (NULL);
break;
case OEOL:
- if ( (sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
- (sp < m->endp && *sp == '\n' &&
- (m->g->cflags&REG_NEWLINE)) )
- { /* yes */ }
+ if ((sp == m->endp && !(m->eflags & REG_NOTEOL)) ||
+ (sp < m->endp && *sp == '\n' &&
+ (m->g->cflags & REG_NEWLINE)))
+ { /* yes */
+ }
else
- return(NULL);
+ return (NULL);
break;
case OBOW:
- if (( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
- (sp < m->endp && *(sp-1) == '\n' &&
- (m->g->cflags&REG_NEWLINE)) ||
- (sp > m->beginp &&
- !ISWORD(*(sp-1))) ) &&
- (sp < m->endp && ISWORD(*sp)) )
- { /* yes */ }
+ if (((sp == m->beginp && !(m->eflags & REG_NOTBOL)) ||
+ (sp < m->endp && *(sp - 1) == '\n' &&
+ (m->g->cflags & REG_NEWLINE)) ||
+ (sp > m->beginp &&
+ !ISWORD(*(sp - 1)))) &&
+ (sp < m->endp && ISWORD(*sp)))
+ { /* yes */
+ }
else
- return(NULL);
+ return (NULL);
break;
case OEOW:
- if (( (sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
- (sp < m->endp && *sp == '\n' &&
- (m->g->cflags&REG_NEWLINE)) ||
- (sp < m->endp && !ISWORD(*sp)) ) &&
- (sp > m->beginp && ISWORD(*(sp-1))) )
- { /* yes */ }
+ if (((sp == m->endp && !(m->eflags & REG_NOTEOL)) ||
+ (sp < m->endp && *sp == '\n' &&
+ (m->g->cflags & REG_NEWLINE)) ||
+ (sp < m->endp && !ISWORD(*sp))) &&
+ (sp > m->beginp && ISWORD(*(sp - 1))))
+ { /* yes */
+ }
else
- return(NULL);
+ return (NULL);
break;
case O_QUEST:
break;
- case OOR1: /* matches null but needs to skip */
+ case OOR1: /* matches null but needs to skip */
ss++;
s = m->g->strip[ss];
- do {
+ do
+ {
assert(OP(s) == OOR2);
ss += OPND(s);
} while (OP(s = m->g->strip[ss]) != O_CH);
/* note that the ss++ gets us past the O_CH */
break;
- default: /* have to make a choice */
+ default: /* have to make a choice */
hard = 1;
break;
}
- if (!hard) { /* that was it! */
+ if (!hard)
+ { /* that was it! */
if (sp != stop)
- return(NULL);
- return(sp);
+ return (NULL);
+ return (sp);
}
- ss--; /* adjust for the for's final increment */
+ ss--; /* adjust for the for's final increment */
/* the hard stuff */
AT("hard", sp, stop, ss, stopst);
s = m->g->strip[ss];
- switch (OP(s)) {
- case OBACK_: /* the vilest depths */
+ switch (OP(s))
+ {
+ case OBACK_: /* the vilest depths */
i = OPND(s);
assert(0 < i && i <= m->g->nsub);
if (m->pmatch[i].rm_eo == -1)
- return(NULL);
+ return (NULL);
assert(m->pmatch[i].rm_so != -1);
len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so;
assert(stop - m->beginp >= len);
if (sp > stop - len)
- return(NULL); /* not enough left to match */
+ return (NULL); /* not enough left to match */
ssp = m->offp + m->pmatch[i].rm_so;
if (memcmp(sp, ssp, len) != 0)
- return(NULL);
+ return (NULL);
while (m->g->strip[ss] != SOP(O_BACK, i))
ss++;
- return(backref(m, sp+len, stop, ss+1, stopst, lev));
+ return (backref(m, sp + len, stop, ss + 1, stopst, lev));
break;
- case OQUEST_: /* to null or not */
- dp = backref(m, sp, stop, ss+1, stopst, lev);
+ case OQUEST_: /* to null or not */
+ dp = backref(m, sp, stop, ss + 1, stopst, lev);
if (dp != NULL)
- return(dp); /* not */
- return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev));
+ return (dp); /* not */
+ return (backref(m, sp, stop, ss + OPND(s) + 1, stopst, lev));
break;
case OPLUS_:
assert(m->lastpos != NULL);
- assert(lev+1 <= m->g->nplus);
- m->lastpos[lev+1] = sp;
- return(backref(m, sp, stop, ss+1, stopst, lev+1));
+ assert(lev + 1 <= m->g->nplus);
+ m->lastpos[lev + 1] = sp;
+ return (backref(m, sp, stop, ss + 1, stopst, lev + 1));
break;
case O_PLUS:
- if (sp == m->lastpos[lev]) /* last pass matched null */
- return(backref(m, sp, stop, ss+1, stopst, lev-1));
+ if (sp == m->lastpos[lev]) /* last pass matched null */
+ return (backref(m, sp, stop, ss + 1, stopst, lev - 1));
/* try another pass */
m->lastpos[lev] = sp;
- dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev);
+ dp = backref(m, sp, stop, ss - OPND(s) + 1, stopst, lev);
if (dp == NULL)
- return(backref(m, sp, stop, ss+1, stopst, lev-1));
+ return (backref(m, sp, stop, ss + 1, stopst, lev - 1));
else
- return(dp);
+ return (dp);
break;
- case OCH_: /* find the right one, if any */
+ case OCH_: /* find the right one, if any */
ssub = ss + 1;
esub = ss + OPND(s) - 1;
assert(OP(m->g->strip[esub]) == OOR1);
- for (;;) { /* find first matching branch */
+ for (;;)
+ { /* find first matching branch */
dp = backref(m, sp, stop, ssub, esub, lev);
if (dp != NULL)
- return(dp);
+ return (dp);
/* that one missed, try next one */
if (OP(m->g->strip[esub]) == O_CH)
- return(NULL); /* there is none */
+ return (NULL); /* there is none */
esub++;
assert(OP(m->g->strip[esub]) == OOR2);
ssub = esub + 1;
@@ -671,29 +712,29 @@ sopno lev; /* PLUS nesting level */
assert(OP(m->g->strip[esub]) == O_CH);
}
break;
- case OLPAREN: /* must undo assignment if rest fails */
+ case OLPAREN: /* must undo assignment if rest fails */
i = OPND(s);
assert(0 < i && i <= m->g->nsub);
offsave = m->pmatch[i].rm_so;
m->pmatch[i].rm_so = sp - m->offp;
- dp = backref(m, sp, stop, ss+1, stopst, lev);
+ dp = backref(m, sp, stop, ss + 1, stopst, lev);
if (dp != NULL)
- return(dp);
+ return (dp);
m->pmatch[i].rm_so = offsave;
- return(NULL);
+ return (NULL);
break;
- case ORPAREN: /* must undo assignment if rest fails */
+ case ORPAREN: /* must undo assignment if rest fails */
i = OPND(s);
assert(0 < i && i <= m->g->nsub);
offsave = m->pmatch[i].rm_eo;
m->pmatch[i].rm_eo = sp - m->offp;
- dp = backref(m, sp, stop, ss+1, stopst, lev);
+ dp = backref(m, sp, stop, ss + 1, stopst, lev);
if (dp != NULL)
- return(dp);
+ return (dp);
m->pmatch[i].rm_eo = offsave;
- return(NULL);
+ return (NULL);
break;
- default: /* uh oh */
+ default: /* uh oh */
assert(nope);
break;
}
@@ -707,25 +748,26 @@ sopno lev; /* PLUS nesting level */
/*
- fast - step through the string at top speed
== static char *fast(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst);
+ == char *stop, sopno startst, sopno stopst);
*/
-static char * /* where tentative match ended, or NULL */
+static char * /* where tentative match ended, or NULL */
fast(m, start, stop, startst, stopst)
register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
{
register states st = m->st;
register states fresh = m->fresh;
register states tmp = m->tmp;
- register char *p = start;
- register int c = (start == m->beginp) ? OUT : *(start-1);
- register int lastc; /* previous c */
- register int flagch;
- register int i;
- register char *coldp; /* last p after which no match was underway */
+ register char *p = start;
+ register int c = (start == m->beginp) ? OUT : *(start - 1);
+ register int lastc; /* previous c */
+ register int flagch;
+ register int i;
+ register char *coldp; /* last p after which no match was
+ * underway */
CLEAR(st);
SET1(st, startst);
@@ -733,7 +775,8 @@ sopno stopst;
ASSIGN(fresh, st);
SP("start", st, *p);
coldp = NULL;
- for (;;) {
+ for (;;)
+ {
/* next character */
lastc = c;
c = (p == m->endp) ? OUT : *p;
@@ -743,39 +786,45 @@ sopno stopst;
/* is there an EOL and/or BOL between lastc and c? */
flagch = '\0';
i = 0;
- if ( (lastc == '\n' && m->g->cflags&REG_NEWLINE) ||
- (lastc == OUT && !(m->eflags&REG_NOTBOL)) ) {
+ if ((lastc == '\n' && m->g->cflags & REG_NEWLINE) ||
+ (lastc == OUT && !(m->eflags & REG_NOTBOL)))
+ {
flagch = BOL;
i = m->g->nbol;
}
- if ( (c == '\n' && m->g->cflags&REG_NEWLINE) ||
- (c == OUT && !(m->eflags&REG_NOTEOL)) ) {
+ if ((c == '\n' && m->g->cflags & REG_NEWLINE) ||
+ (c == OUT && !(m->eflags & REG_NOTEOL)))
+ {
flagch = (flagch == BOL) ? BOLEOL : EOL;
i += m->g->neol;
}
- if (i != 0) {
+ if (i != 0)
+ {
for (; i > 0; i--)
st = step(m->g, startst, stopst, st, flagch, st);
SP("boleol", st, c);
}
/* how about a word boundary? */
- if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
- (c != OUT && ISWORD(c)) ) {
+ if ((flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
+ (c != OUT && ISWORD(c)))
+ {
flagch = BOW;
}
- if ( (lastc != OUT && ISWORD(lastc)) &&
- (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
+ if ((lastc != OUT && ISWORD(lastc)) &&
+ (flagch == EOL || (c != OUT && !ISWORD(c))))
+ {
flagch = EOW;
}
- if (flagch == BOW || flagch == EOW) {
+ if (flagch == BOW || flagch == EOW)
+ {
st = step(m->g, startst, stopst, st, flagch, st);
SP("boweow", st, c);
}
/* are we done? */
if (ISSET(st, stopst) || p == stop)
- break; /* NOTE BREAK OUT */
+ break; /* NOTE BREAK OUT */
/* no, we must deal with this character */
ASSIGN(tmp, st);
@@ -790,33 +839,33 @@ sopno stopst;
assert(coldp != NULL);
m->coldp = coldp;
if (ISSET(st, stopst))
- return(p+1);
+ return (p + 1);
else
- return(NULL);
+ return (NULL);
}
/*
- slow - step through the string more deliberately
== static char *slow(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst);
+ == char *stop, sopno startst, sopno stopst);
*/
-static char * /* where it ended */
+static char * /* where it ended */
slow(m, start, stop, startst, stopst)
register struct match *m;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
{
register states st = m->st;
register states empty = m->empty;
register states tmp = m->tmp;
- register char *p = start;
- register int c = (start == m->beginp) ? OUT : *(start-1);
- register int lastc; /* previous c */
- register int flagch;
- register int i;
- register char *matchp; /* last p at which a match ended */
+ register char *p = start;
+ register int c = (start == m->beginp) ? OUT : *(start - 1);
+ register int lastc; /* previous c */
+ register int flagch;
+ register int i;
+ register char *matchp; /* last p at which a match ended */
AT("slow", start, stop, startst, stopst);
CLEAR(st);
@@ -824,7 +873,8 @@ sopno stopst;
SP("sstart", st, *p);
st = step(m->g, startst, stopst, st, NOTHING, st);
matchp = NULL;
- for (;;) {
+ for (;;)
+ {
/* next character */
lastc = c;
c = (p == m->endp) ? OUT : *p;
@@ -832,32 +882,38 @@ sopno stopst;
/* is there an EOL and/or BOL between lastc and c? */
flagch = '\0';
i = 0;
- if ( (lastc == '\n' && m->g->cflags&REG_NEWLINE) ||
- (lastc == OUT && !(m->eflags&REG_NOTBOL)) ) {
+ if ((lastc == '\n' && m->g->cflags & REG_NEWLINE) ||
+ (lastc == OUT && !(m->eflags & REG_NOTBOL)))
+ {
flagch = BOL;
i = m->g->nbol;
}
- if ( (c == '\n' && m->g->cflags&REG_NEWLINE) ||
- (c == OUT && !(m->eflags&REG_NOTEOL)) ) {
+ if ((c == '\n' && m->g->cflags & REG_NEWLINE) ||
+ (c == OUT && !(m->eflags & REG_NOTEOL)))
+ {
flagch = (flagch == BOL) ? BOLEOL : EOL;
i += m->g->neol;
}
- if (i != 0) {
+ if (i != 0)
+ {
for (; i > 0; i--)
st = step(m->g, startst, stopst, st, flagch, st);
SP("sboleol", st, c);
}
/* how about a word boundary? */
- if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
- (c != OUT && ISWORD(c)) ) {
+ if ((flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
+ (c != OUT && ISWORD(c)))
+ {
flagch = BOW;
}
- if ( (lastc != OUT && ISWORD(lastc)) &&
- (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
+ if ((lastc != OUT && ISWORD(lastc)) &&
+ (flagch == EOL || (c != OUT && !ISWORD(c))))
+ {
flagch = EOW;
}
- if (flagch == BOW || flagch == EOW) {
+ if (flagch == BOW || flagch == EOW)
+ {
st = step(m->g, startst, stopst, st, flagch, st);
SP("sboweow", st, c);
}
@@ -866,7 +922,7 @@ sopno stopst;
if (ISSET(st, stopst))
matchp = p;
if (EQ(st, empty) || p == stop)
- break; /* NOTE BREAK OUT */
+ break; /* NOTE BREAK OUT */
/* no, we must deal with this character */
ASSIGN(tmp, st);
@@ -878,50 +934,52 @@ sopno stopst;
p++;
}
- return(matchp);
+ return (matchp);
}
/*
- step - map set of states reachable before char to set reachable after
== static states step(register struct re_guts *g, sopno start, sopno stop, \
- == register states bef, int ch, register states aft);
- == #define BOL (OUT+1)
- == #define EOL (BOL+1)
- == #define BOLEOL (BOL+2)
- == #define NOTHING (BOL+3)
- == #define BOW (BOL+4)
- == #define EOW (BOL+5)
- == #define CODEMAX (BOL+5) // highest code used
- == #define NONCHAR(c) ((c) > CHAR_MAX)
- == #define NNONCHAR (CODEMAX-CHAR_MAX)
+ == register states bef, int ch, register states aft);
+ == #define BOL (OUT+1)
+ == #define EOL (BOL+1)
+ == #define BOLEOL (BOL+2)
+ == #define NOTHING (BOL+3)
+ == #define BOW (BOL+4)
+ == #define EOW (BOL+5)
+ == #define CODEMAX (BOL+5) // highest code used
+ == #define NONCHAR(c) ((c) > CHAR_MAX)
+ == #define NNONCHAR (CODEMAX-CHAR_MAX)
*/
-static states
+static states
step(g, start, stop, bef, ch, aft)
register struct re_guts *g;
-sopno start; /* start state within strip */
-sopno stop; /* state after stop state within strip */
-register states bef; /* states reachable before */
-int ch; /* character or NONCHAR code */
-register states aft; /* states already known reachable after */
+sopno start; /* start state within strip */
+sopno stop; /* state after stop state within strip */
+register states bef; /* states reachable before */
+int ch; /* character or NONCHAR code */
+register states aft; /* states already known reachable after */
{
- register cset *cs;
- register sop s;
- register sopno pc;
+ register cset *cs;
+ register sop s;
+ register sopno pc;
register onestate here; /* note, macros know this name */
- register sopno look;
- register int i;
+ register sopno look;
+ register int i;
- for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) {
+ for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here))
+ {
s = g->strip[pc];
- switch (OP(s)) {
+ switch (OP(s))
+ {
case OEND:
- assert(pc == stop-1);
+ assert(pc == stop - 1);
break;
case OCHAR:
/* only characters can match */
- assert(!NONCHAR(ch) || ch != (char)OPND(s));
- if (ch == (char)OPND(s))
+ assert(!NONCHAR(ch) || ch != (char) OPND(s));
+ if (ch == (char) OPND(s))
FWD(aft, bef, 1);
break;
case OBOL:
@@ -949,65 +1007,68 @@ register states aft; /* states already known reachable after */
if (!NONCHAR(ch) && CHIN(cs, ch))
FWD(aft, bef, 1);
break;
- case OBACK_: /* ignored here */
+ case OBACK_: /* ignored here */
case O_BACK:
FWD(aft, aft, 1);
break;
- case OPLUS_: /* forward, this is just an empty */
+ case OPLUS_: /* forward, this is just an empty */
FWD(aft, aft, 1);
break;
- case O_PLUS: /* both forward and back */
+ case O_PLUS: /* both forward and back */
FWD(aft, aft, 1);
i = ISSETBACK(aft, OPND(s));
BACK(aft, aft, OPND(s));
- if (!i && ISSETBACK(aft, OPND(s))) {
+ if (!i && ISSETBACK(aft, OPND(s)))
+ {
/* oho, must reconsider loop body */
pc -= OPND(s) + 1;
INIT(here, pc);
}
break;
- case OQUEST_: /* two branches, both forward */
+ case OQUEST_: /* two branches, both forward */
FWD(aft, aft, 1);
FWD(aft, aft, OPND(s));
break;
- case O_QUEST: /* just an empty */
+ case O_QUEST: /* just an empty */
FWD(aft, aft, 1);
break;
- case OLPAREN: /* not significant here */
+ case OLPAREN: /* not significant here */
case ORPAREN:
FWD(aft, aft, 1);
break;
- case OCH_: /* mark the first two branches */
+ case OCH_: /* mark the first two branches */
FWD(aft, aft, 1);
- assert(OP(g->strip[pc+OPND(s)]) == OOR2);
+ assert(OP(g->strip[pc + OPND(s)]) == OOR2);
FWD(aft, aft, OPND(s));
break;
- case OOR1: /* done a branch, find the O_CH */
- if (ISSTATEIN(aft, here)) {
+ case OOR1: /* done a branch, find the O_CH */
+ if (ISSTATEIN(aft, here))
+ {
for (look = 1;
- OP(s = g->strip[pc+look]) != O_CH;
- look += OPND(s))
+ OP(s = g->strip[pc + look]) != O_CH;
+ look += OPND(s))
assert(OP(s) == OOR2);
FWD(aft, aft, look);
}
break;
- case OOR2: /* propagate OCH_'s marking */
+ case OOR2: /* propagate OCH_'s marking */
FWD(aft, aft, 1);
- if (OP(g->strip[pc+OPND(s)]) != O_CH) {
- assert(OP(g->strip[pc+OPND(s)]) == OOR2);
+ if (OP(g->strip[pc + OPND(s)]) != O_CH)
+ {
+ assert(OP(g->strip[pc + OPND(s)]) == OOR2);
FWD(aft, aft, OPND(s));
}
break;
- case O_CH: /* just empty */
+ case O_CH: /* just empty */
FWD(aft, aft, 1);
break;
- default: /* ooooops... */
+ default: /* ooooops... */
assert(nope);
break;
}
}
- return(aft);
+ return (aft);
}
#ifdef REDEBUG
@@ -1015,84 +1076,86 @@ register states aft; /* states already known reachable after */
- print - print a set of states
== #ifdef REDEBUG
== static void print(struct match *m, char *caption, states st, \
- == int ch, FILE *d);
+ == int ch, FILE *d);
== #endif
*/
static void
print(m, caption, st, ch, d)
-struct match *m;
-char *caption;
-states st;
-int ch;
-FILE *d;
+struct match *m;
+char *caption;
+states st;
+int ch;
+FILE *d;
{
register struct re_guts *g = m->g;
- register int i;
- register int first = 1;
+ register int i;
+ register int first = 1;
- if (!(m->eflags&REG_TRACE))
+ if (!(m->eflags & REG_TRACE))
return;
fprintf(d, "%s", caption);
if (ch != '\0')
fprintf(d, " %s", pchar(ch));
for (i = 0; i < g->nstates; i++)
- if (ISSET(st, i)) {
+ if (ISSET(st, i))
+ {
fprintf(d, "%s%d", (first) ? "\t" : ", ", i);
first = 0;
}
fprintf(d, "\n");
}
-/*
+/*
- at - print current situation
== #ifdef REDEBUG
== static void at(struct match *m, char *title, char *start, char *stop, \
- == sopno startst, sopno stopst);
+ == sopno startst, sopno stopst);
== #endif
*/
static void
at(m, title, start, stop, startst, stopst)
-struct match *m;
-char *title;
-char *start;
-char *stop;
-sopno startst;
-sopno stopst;
+struct match *m;
+char *title;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
{
- if (!(m->eflags&REG_TRACE))
+ if (!(m->eflags & REG_TRACE))
return;
printf("%s %s-", title, pchar(*start));
printf("%s ", pchar(*stop));
- printf("%ld-%ld\n", (long)startst, (long)stopst);
+ printf("%ld-%ld\n", (long) startst, (long) stopst);
}
#ifndef PCHARDONE
-#define PCHARDONE /* never again */
+#define PCHARDONE /* never again */
/*
- pchar - make a character printable
== #ifdef REDEBUG
== static char *pchar(int ch);
== #endif
*
- * Is this identical to regchar() over in debug.c? Well, yes. But a
+ * Is this identical to regchar() over in debug.c? Well, yes. But a
* duplicate here avoids having a debugging-capable regexec.o tied to
- * a matching debug.o, and this is convenient. It all disappears in
+ * a matching debug.o, and this is convenient. It all disappears in
* the non-debug compilation anyway, so it doesn't matter much.
*/
-static char * /* -> representation */
+static char * /* -> representation */
pchar(ch)
-int ch;
+int ch;
{
- static char pbuf[10];
+ static char pbuf[10];
if (isprint(ch) || ch == ' ')
sprintf(pbuf, "%c", ch);
else
sprintf(pbuf, "\\%o", ch);
- return(pbuf);
+ return (pbuf);
}
+
#endif
#endif
diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c
index 364573e2b5b..dcb95173c06 100644
--- a/src/backend/regex/regcomp.c
+++ b/src/backend/regex/regcomp.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,12 +34,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)regcomp.c 8.5 (Berkeley) 3/20/94
+ * @(#)regcomp.c 8.5 (Berkeley) 3/20/94
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)regcomp.c 8.5 (Berkeley) 3/20/94";
-#endif /* LIBC_SCCS and not lint */
+static char sccsid[] = "@(#)regcomp.c 8.5 (Berkeley) 3/20/94";
+
+#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stdio.h>
@@ -49,7 +50,7 @@ static char sccsid[] = "@(#)regcomp.c 8.5 (Berkeley) 3/20/94";
#include <stdlib.h>
#include <assert.h>
-#include <regex/regex.h>
+#include <regex/regex.h>
#include <regex/utils.h>
#include <regex/regex2.h>
#include <regex/cclass.h>
@@ -59,167 +60,179 @@ static char sccsid[] = "@(#)regcomp.c 8.5 (Berkeley) 3/20/94";
* parse structure, passed up and down to avoid global variables and
* other clumsinesses
*/
-struct parse {
- char *next; /* next character in RE */
- char *end; /* end of string (-> NUL normally) */
- int error; /* has an error been seen? */
- sop *strip; /* malloced strip */
- sopno ssize; /* malloced strip size (allocated) */
- sopno slen; /* malloced strip length (used) */
- int ncsalloc; /* number of csets allocated */
+struct parse
+{
+ char *next; /* next character in RE */
+ char *end; /* end of string (-> NUL normally) */
+ int error; /* has an error been seen? */
+ sop *strip; /* malloced strip */
+ sopno ssize; /* malloced strip size (allocated) */
+ sopno slen; /* malloced strip length (used) */
+ int ncsalloc; /* number of csets allocated */
struct re_guts *g;
-# define NPAREN 10 /* we need to remember () 1-9 for back refs */
- sopno pbegin[NPAREN]; /* -> ( ([0] unused) */
- sopno pend[NPAREN]; /* -> ) ([0] unused) */
+#define NPAREN 10 /* we need to remember () 1-9 for back
+ * refs */
+ sopno pbegin[NPAREN]; /* -> ( ([0] unused) */
+ sopno pend[NPAREN]; /* -> ) ([0] unused) */
};
/* ========= begin header generated by ./mkh ========= */
#ifdef __cplusplus
-extern "C" {
+extern "C"
+{
#endif
/* === regcomp.c === */
-static void p_ere(struct parse *p, int stop);
-static void p_ere_exp(struct parse *p);
-static void p_str(struct parse *p);
-static void p_bre(struct parse *p, int end1, int end2);
-static int p_simp_re(struct parse *p, int starordinary);
-static int p_count(struct parse *p);
-static void p_bracket(struct parse *p);
-static void p_b_term(struct parse *p, cset *cs);
-static void p_b_cclass(struct parse *p, cset *cs);
-static void p_b_eclass(struct parse *p, cset *cs);
-static char p_b_symbol(struct parse *p);
-static char p_b_coll_elem(struct parse *p, int endc);
-static char othercase(int ch);
-static void bothcases(struct parse *p, int ch);
-static void ordinary(struct parse *p, int ch);
-static void nonnewline(struct parse *p);
-static void repeat(struct parse *p, sopno start, int from, int to);
-static int seterr(struct parse *p, int e);
-static cset *allocset(struct parse *p);
-static void freeset(struct parse *p, cset *cs);
-static int freezeset(struct parse *p, cset *cs);
-static int firstch(struct parse *p, cset *cs);
-static int nch(struct parse *p, cset *cs);
-static void mcadd(struct parse *p, cset *cs, char *cp);
-static void mcinvert(struct parse *p, cset *cs);
-static void mccase(struct parse *p, cset *cs);
-static int isinsets(struct re_guts *g, int c);
-static int samesets(struct re_guts *g, int c1, int c2);
-static void categorize(struct parse *p, struct re_guts *g);
-static sopno dupl(struct parse *p, sopno start, sopno finish);
-static void doemit(struct parse *p, sop op, size_t opnd);
-static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos);
-static void dofwd(struct parse *p, sopno pos, sop value);
-static void enlarge(struct parse *p, sopno size);
-static void stripsnug(struct parse *p, struct re_guts *g);
-static void findmust(struct parse *p, struct re_guts *g);
-static sopno pluscount(struct parse *p, struct re_guts *g);
+ static void p_ere(struct parse * p, int stop);
+ static void p_ere_exp(struct parse * p);
+ static void p_str(struct parse * p);
+ static void p_bre(struct parse * p, int end1, int end2);
+ static int p_simp_re(struct parse * p, int starordinary);
+ static int p_count(struct parse * p);
+ static void p_bracket(struct parse * p);
+ static void p_b_term(struct parse * p, cset * cs);
+ static void p_b_cclass(struct parse * p, cset * cs);
+ static void p_b_eclass(struct parse * p, cset * cs);
+ static char p_b_symbol(struct parse * p);
+ static char p_b_coll_elem(struct parse * p, int endc);
+ static char othercase(int ch);
+ static void bothcases(struct parse * p, int ch);
+ static void ordinary(struct parse * p, int ch);
+ static void nonnewline(struct parse * p);
+ static void repeat(struct parse * p, sopno start, int from, int to);
+ static int seterr(struct parse * p, int e);
+ static cset *allocset(struct parse * p);
+ static void freeset(struct parse * p, cset * cs);
+ static int freezeset(struct parse * p, cset * cs);
+ static int firstch(struct parse * p, cset * cs);
+ static int nch(struct parse * p, cset * cs);
+ static void mcadd(struct parse * p, cset * cs, char *cp);
+ static void mcinvert(struct parse * p, cset * cs);
+ static void mccase(struct parse * p, cset * cs);
+ static int isinsets(struct re_guts * g, int c);
+ static int samesets(struct re_guts * g, int c1, int c2);
+ static void categorize(struct parse * p, struct re_guts * g);
+ static sopno dupl(struct parse * p, sopno start, sopno finish);
+ static void doemit(struct parse * p, sop op, size_t opnd);
+ static void doinsert(struct parse * p, sop op, size_t opnd, sopno pos);
+ static void dofwd(struct parse * p, sopno pos, sop value);
+ static void enlarge(struct parse * p, sopno size);
+ static void stripsnug(struct parse * p, struct re_guts * g);
+ static void findmust(struct parse * p, struct re_guts * g);
+ static sopno pluscount(struct parse * p, struct re_guts * g);
#ifdef __cplusplus
}
+
#endif
/* ========= end header generated by ./mkh ========= */
-static char nuls[10]; /* place to point scanner in event of error */
+static char nuls[10]; /* place to point scanner in event of
+ * error */
/*
* macros for use with parse structure
- * BEWARE: these know that the parse structure is named `p' !!!
+ * BEWARE: these know that the parse structure is named `p' !!!
*/
-#define PEEK() (*p->next)
-#define PEEK2() (*(p->next+1))
-#define MORE() (p->next < p->end)
-#define MORE2() (p->next+1 < p->end)
-#define SEE(c) (MORE() && PEEK() == (c))
-#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b))
-#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0)
-#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
-#define NEXT() (p->next++)
-#define NEXT2() (p->next += 2)
-#define NEXTn(n) (p->next += (n))
-#define GETNEXT() (*p->next++)
-#define SETERROR(e) seterr(p, (e))
-#define REQUIRE(co, e) if (!(co)) SETERROR(e)
-#define MUSTSEE(c, e) REQUIRE(MORE() && PEEK() == (c), e)
-#define MUSTEAT(c, e) REQUIRE(MORE() && GETNEXT() == (c), e)
-#define MUSTNOTSEE(c, e) REQUIRE(!MORE() || PEEK() != (c), e)
-#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
-#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
-#define AHEAD(pos) dofwd(p, pos, HERE()-(pos))
-#define ASTERN(sop, pos) EMIT(sop, HERE()-pos)
-#define HERE() (p->slen)
-#define THERE() (p->slen - 1)
-#define THERETHERE() (p->slen - 2)
-#define DROP(n) (p->slen -= (n))
+#define PEEK() (*p->next)
+#define PEEK2() (*(p->next+1))
+#define MORE() (p->next < p->end)
+#define MORE2() (p->next+1 < p->end)
+#define SEE(c) (MORE() && PEEK() == (c))
+#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b))
+#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0)
+#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
+#define NEXT() (p->next++)
+#define NEXT2() (p->next += 2)
+#define NEXTn(n) (p->next += (n))
+#define GETNEXT() (*p->next++)
+#define SETERROR(e) seterr(p, (e))
+#define REQUIRE(co, e) if (!(co)) SETERROR(e)
+#define MUSTSEE(c, e) REQUIRE(MORE() && PEEK() == (c), e)
+#define MUSTEAT(c, e) REQUIRE(MORE() && GETNEXT() == (c), e)
+#define MUSTNOTSEE(c, e) REQUIRE(!MORE() || PEEK() != (c), e)
+#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
+#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
+#define AHEAD(pos) dofwd(p, pos, HERE()-(pos))
+#define ASTERN(sop, pos) EMIT(sop, HERE()-pos)
+#define HERE() (p->slen)
+#define THERE() (p->slen - 1)
+#define THERETHERE() (p->slen - 2)
+#define DROP(n) (p->slen -= (n))
#ifndef NDEBUG
-static int never = 0; /* for use in asserts; shuts lint up */
+static int never = 0; /* for use in asserts; shuts lint up */
+
#else
-#define never 0 /* some <assert.h>s have bugs too */
+#define never 0 /* some <assert.h>s have bugs too */
#endif
/*
- regcomp - interface for parser and compilation
= extern int regcomp(regex_t *, const char *, int);
- = #define REG_BASIC 0000
- = #define REG_EXTENDED 0001
- = #define REG_ICASE 0002
- = #define REG_NOSUB 0004
- = #define REG_NEWLINE 0010
- = #define REG_NOSPEC 0020
- = #define REG_PEND 0040
- = #define REG_DUMP 0200
+ = #define REG_BASIC 0000
+ = #define REG_EXTENDED 0001
+ = #define REG_ICASE 0002
+ = #define REG_NOSUB 0004
+ = #define REG_NEWLINE 0010
+ = #define REG_NOSPEC 0020
+ = #define REG_PEND 0040
+ = #define REG_DUMP 0200
*/
-int /* 0 success, otherwise REG_something */
+int /* 0 success, otherwise REG_something */
pg95_regcomp(preg, pattern, cflags)
-regex_t *preg;
-const char *pattern;
-int cflags;
+regex_t *preg;
+const char *pattern;
+int cflags;
{
- struct parse pa;
+ struct parse pa;
register struct re_guts *g;
register struct parse *p = &pa;
- register int i;
+ register int i;
register size_t len;
+
#ifdef REDEBUG
-# define GOODFLAGS(f) (f)
+#define GOODFLAGS(f) (f)
#else
-# define GOODFLAGS(f) ((f)&~REG_DUMP)
+#define GOODFLAGS(f) ((f)&~REG_DUMP)
#endif
cflags = GOODFLAGS(cflags);
- if ((cflags&REG_EXTENDED) && (cflags&REG_NOSPEC))
- return(REG_INVARG);
+ if ((cflags & REG_EXTENDED) && (cflags & REG_NOSPEC))
+ return (REG_INVARG);
- if (cflags&REG_PEND) {
+ if (cflags & REG_PEND)
+ {
if (preg->re_endp < pattern)
- return(REG_INVARG);
+ return (REG_INVARG);
len = preg->re_endp - pattern;
- } else
- len = strlen((char *)pattern);
+ }
+ else
+ len = strlen((char *) pattern);
/* do the mallocs early so failure handling is easy */
- g = (struct re_guts *)malloc(sizeof(struct re_guts) +
- (NC-1)*sizeof(cat_t));
+ g = (struct re_guts *) malloc(sizeof(struct re_guts) +
+ (NC - 1) * sizeof(cat_t));
if (g == NULL)
- return(REG_ESPACE);
- p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
- p->strip = (sop *)malloc(p->ssize * sizeof(sop));
+ return (REG_ESPACE);
+ p->ssize = len / (size_t) 2 *(size_t) 3 + (size_t) 1; /* ugh */
+
+ p->strip = (sop *) malloc(p->ssize * sizeof(sop));
p->slen = 0;
- if (p->strip == NULL) {
- free((char *)g);
- return(REG_ESPACE);
+ if (p->strip == NULL)
+ {
+ free((char *) g);
+ return (REG_ESPACE);
}
/* set things up */
p->g = g;
- p->next = (char *)pattern; /* convenience; we do not modify it */
+ p->next = (char *) pattern; /* convenience; we do not modify it */
p->end = p->next + len;
p->error = 0;
p->ncsalloc = 0;
- for (i = 0; i < NPAREN; i++) {
+ for (i = 0; i < NPAREN; i++)
+ {
p->pbegin[i] = 0;
p->pend[i] = 0;
}
@@ -234,17 +247,17 @@ int cflags;
g->must = NULL;
g->mlen = 0;
g->nsub = 0;
- g->ncategories = 1; /* category 0 is "everything else" */
+ g->ncategories = 1; /* category 0 is "everything else" */
g->categories = &g->catspace[-(CHAR_MIN)];
- memset((char *)g->catspace, 0, NC*sizeof(cat_t));
+ memset((char *) g->catspace, 0, NC * sizeof(cat_t));
g->backrefs = 0;
/* do it */
EMIT(OEND, 0);
g->firststate = THERE();
- if (cflags&REG_EXTENDED)
+ if (cflags & REG_EXTENDED)
p_ere(p, OUT);
- else if (cflags&REG_NOSPEC)
+ else if (cflags & REG_NOSPEC)
p_str(p);
else
p_bre(p, OUT, OUT);
@@ -262,14 +275,14 @@ int cflags;
preg->re_magic = MAGIC1;
#ifndef REDEBUG
/* not debugging, so can't rely on the assert() in regexec() */
- if (g->iflags&BAD)
+ if (g->iflags & BAD)
SETERROR(REG_ASSERT);
#endif
/* win or lose, we're done */
- if (p->error != 0) /* lose */
+ if (p->error != 0) /* lose */
pg95_regfree(preg);
- return(p->error);
+ return (p->error);
}
/*
@@ -279,26 +292,28 @@ int cflags;
static void
p_ere(p, stop)
register struct parse *p;
-int stop; /* character this ERE should end at */
+int stop; /* character this ERE should end at */
{
- register char c;
- register sopno prevback = 0;
- register sopno prevfwd = 0;
- register sopno conc;
- register int first = 1; /* is this the first alternative? */
-
- for (;;) {
+ register char c;
+ register sopno prevback = 0;
+ register sopno prevfwd = 0;
+ register sopno conc;
+ register int first = 1; /* is this the first alternative? */
+
+ for (;;)
+ {
/* do a bunch of concatenated expressions */
conc = HERE();
while (MORE() && (c = PEEK()) != '|' && c != stop)
p_ere_exp(p);
- REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */
+ REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */
if (!EAT('|'))
- break; /* NOTE BREAK OUT */
+ break; /* NOTE BREAK OUT */
- if (first) {
- INSERT(OCH_, conc); /* offset is wrong */
+ if (first)
+ {
+ INSERT(OCH_, conc); /* offset is wrong */
prevfwd = conc;
prevback = conc;
first = 0;
@@ -310,7 +325,8 @@ int stop; /* character this ERE should end at */
EMIT(OOR2, 0); /* offset is very wrong */
}
- if (!first) { /* tail-end fixups */
+ if (!first)
+ { /* tail-end fixups */
AHEAD(prevfwd);
ASTERN(O_CH, prevback);
}
@@ -326,18 +342,19 @@ static void
p_ere_exp(p)
register struct parse *p;
{
- register char c;
- register sopno pos;
- register int count;
- register int count2;
- register sopno subno;
- int wascaret = 0;
-
- assert(MORE()); /* caller should have ensured this */
+ register char c;
+ register sopno pos;
+ register int count;
+ register int count2;
+ register sopno subno;
+ int wascaret = 0;
+
+ assert(MORE()); /* caller should have ensured this */
c = GETNEXT();
pos = HERE();
- switch (c) {
+ switch (c)
+ {
case '(':
REQUIRE(MORE(), REG_EPAREN);
p->g->nsub++;
@@ -347,7 +364,8 @@ register struct parse *p;
EMIT(OLPAREN, subno);
if (!SEE(')'))
p_ere(p, ')');
- if (subno < NPAREN) {
+ if (subno < NPAREN)
+ {
p->pend[subno] = HERE();
assert(p->pend[subno] != 0);
}
@@ -355,13 +373,13 @@ register struct parse *p;
MUSTEAT(')', REG_EPAREN);
break;
#ifndef POSIX_MISTAKE
- case ')': /* happens only if no current unmatched ( */
+ case ')': /* happens only if no current unmatched ( */
+
/*
- * You may ask, why the ifndef? Because I didn't notice
- * this until slightly too late for 1003.2, and none of the
- * other 1003.2 regular-expression reviewers noticed it at
- * all. So an unmatched ) is legal POSIX, at least until
- * we can get it fixed.
+ * You may ask, why the ifndef? Because I didn't notice this
+ * until slightly too late for 1003.2, and none of the other
+ * 1003.2 regular-expression reviewers noticed it at all. So an
+ * unmatched ) is legal POSIX, at least until we can get it fixed.
*/
SETERROR(REG_EPAREN);
break;
@@ -386,7 +404,7 @@ register struct parse *p;
SETERROR(REG_BADRPT);
break;
case '.':
- if (p->g->cflags&REG_NEWLINE)
+ if (p->g->cflags & REG_NEWLINE)
nonnewline(p);
else
EMIT(OANY, 0);
@@ -399,7 +417,8 @@ register struct parse *p;
c = GETNEXT();
ordinary(p, c);
break;
- case '{': /* okay as ordinary except if digit follows */
+ case '{': /* okay as ordinary except if digit
+ * follows */
REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT);
/* FALLTHROUGH */
default:
@@ -411,14 +430,15 @@ register struct parse *p;
return;
c = PEEK();
/* we call { a repetition if followed by a digit */
- if (!( c == '*' || c == '+' || c == '?' ||
- (c == '{' && MORE2() && isdigit(PEEK2())) ))
- return; /* no repetition, we're done */
+ if (!(c == '*' || c == '+' || c == '?' ||
+ (c == '{' && MORE2() && isdigit(PEEK2()))))
+ return; /* no repetition, we're done */
NEXT();
REQUIRE(!wascaret, REG_BADRPT);
- switch (c) {
- case '*': /* implemented as +? */
+ switch (c)
+ {
+ case '*': /* implemented as +? */
/* this case does not require the (y|) trick, noKLUDGE */
INSERT(OPLUS_, pos);
ASTERN(O_PLUS, pos);
@@ -433,23 +453,30 @@ register struct parse *p;
/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
INSERT(OCH_, pos); /* offset slightly wrong */
ASTERN(OOR1, pos); /* this one's right */
- AHEAD(pos); /* fix the OCH_ */
+ AHEAD(pos); /* fix the OCH_ */
EMIT(OOR2, 0); /* offset very wrong... */
AHEAD(THERE()); /* ...so fix it */
ASTERN(O_CH, THERETHERE());
break;
case '{':
count = p_count(p);
- if (EAT(',')) {
- if (isdigit(PEEK())) {
+ if (EAT(','))
+ {
+ if (isdigit(PEEK()))
+ {
count2 = p_count(p);
REQUIRE(count <= count2, REG_BADBR);
- } else /* single number with comma */
+ }
+ else
+/* single number with comma */
count2 = INFINITY;
- } else /* just a single number */
+ }
+ else
+/* just a single number */
count2 = count;
repeat(p, pos, count, count2);
- if (!EAT('}')) { /* error heuristics */
+ if (!EAT('}'))
+ { /* error heuristics */
while (MORE() && PEEK() != '}')
NEXT();
REQUIRE(MORE(), REG_EBRACE);
@@ -461,8 +488,8 @@ register struct parse *p;
if (!MORE())
return;
c = PEEK();
- if (!( c == '*' || c == '+' || c == '?' ||
- (c == '{' && MORE2() && isdigit(PEEK2())) ) )
+ if (!(c == '*' || c == '+' || c == '?' ||
+ (c == '{' && MORE2() && isdigit(PEEK2()))))
return;
SETERROR(REG_BADRPT);
}
@@ -483,72 +510,78 @@ register struct parse *p;
/*
- p_bre - BRE parser top level, anchoring and concatenation
== static void p_bre(register struct parse *p, register int end1, \
- == register int end2);
+ == register int end2);
* Giving end1 as OUT essentially eliminates the end1/end2 check.
*
* This implementation is a bit of a kludge, in that a trailing $ is first
* taken as an ordinary character and then revised to be an anchor. The
* only undesirable side effect is that '$' gets included as a character
- * category in such cases. This is fairly harmless; not worth fixing.
+ * category in such cases. This is fairly harmless; not worth fixing.
* The amount of lookahead needed to avoid this kludge is excessive.
*/
static void
p_bre(p, end1, end2)
register struct parse *p;
-register int end1; /* first terminating character */
-register int end2; /* second terminating character */
+register int end1; /* first terminating character */
+register int end2; /* second terminating character */
{
- register sopno start = HERE();
- register int first = 1; /* first subexpression? */
- register int wasdollar = 0;
+ register sopno start = HERE();
+ register int first = 1; /* first subexpression? */
+ register int wasdollar = 0;
- if (EAT('^')) {
+ if (EAT('^'))
+ {
EMIT(OBOL, 0);
p->g->iflags |= USEBOL;
p->g->nbol++;
}
- while (MORE() && !SEETWO(end1, end2)) {
+ while (MORE() && !SEETWO(end1, end2))
+ {
wasdollar = p_simp_re(p, first);
first = 0;
}
- if (wasdollar) { /* oops, that was a trailing anchor */
+ if (wasdollar)
+ { /* oops, that was a trailing anchor */
DROP(1);
EMIT(OEOL, 0);
p->g->iflags |= USEEOL;
p->g->neol++;
}
- REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */
+ REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */
}
/*
- p_simp_re - parse a simple RE, an atom possibly followed by a repetition
== static int p_simp_re(register struct parse *p, int starordinary);
*/
-static int /* was the simple RE an unbackslashed $? */
+static int /* was the simple RE an unbackslashed $? */
p_simp_re(p, starordinary)
register struct parse *p;
-int starordinary; /* is a leading * an ordinary character? */
+int starordinary; /* is a leading * an ordinary character? */
{
- register int c;
- register int count;
- register int count2;
- register sopno pos;
- register int i;
- register sopno subno;
-# define BACKSL (1<<CHAR_BIT)
+ register int c;
+ register int count;
+ register int count2;
+ register sopno pos;
+ register int i;
+ register sopno subno;
- pos = HERE(); /* repetion op, if any, covers from here */
+#define BACKSL (1<<CHAR_BIT)
- assert(MORE()); /* caller should have ensured this */
+ pos = HERE(); /* repetion op, if any, covers from here */
+
+ assert(MORE()); /* caller should have ensured this */
c = GETNEXT();
- if (c == '\\') {
+ if (c == '\\')
+ {
REQUIRE(MORE(), REG_EESCAPE);
- c = BACKSL | (unsigned char)GETNEXT();
+ c = BACKSL | (unsigned char) GETNEXT();
}
- switch (c) {
+ switch (c)
+ {
case '.':
- if (p->g->cflags&REG_NEWLINE)
+ if (p->g->cflags & REG_NEWLINE)
nonnewline(p);
else
EMIT(OANY, 0);
@@ -556,10 +589,10 @@ int starordinary; /* is a leading * an ordinary character? */
case '[':
p_bracket(p);
break;
- case BACKSL|'{':
+ case BACKSL | '{':
SETERROR(REG_BADRPT);
break;
- case BACKSL|'(':
+ case BACKSL | '(':
p->g->nsub++;
subno = p->g->nsub;
if (subno < NPAREN)
@@ -568,37 +601,40 @@ int starordinary; /* is a leading * an ordinary character? */
/* the MORE here is an error heuristic */
if (MORE() && !SEETWO('\\', ')'))
p_bre(p, '\\', ')');
- if (subno < NPAREN) {
+ if (subno < NPAREN)
+ {
p->pend[subno] = HERE();
assert(p->pend[subno] != 0);
}
EMIT(ORPAREN, subno);
REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
break;
- case BACKSL|')': /* should not get here -- must be user */
- case BACKSL|'}':
+ case BACKSL | ')': /* should not get here -- must be user */
+ case BACKSL | '}':
SETERROR(REG_EPAREN);
break;
- case BACKSL|'1':
- case BACKSL|'2':
- case BACKSL|'3':
- case BACKSL|'4':
- case BACKSL|'5':
- case BACKSL|'6':
- case BACKSL|'7':
- case BACKSL|'8':
- case BACKSL|'9':
- i = (c&~BACKSL) - '0';
+ case BACKSL | '1':
+ case BACKSL | '2':
+ case BACKSL | '3':
+ case BACKSL | '4':
+ case BACKSL | '5':
+ case BACKSL | '6':
+ case BACKSL | '7':
+ case BACKSL | '8':
+ case BACKSL | '9':
+ i = (c & ~BACKSL) - '0';
assert(i < NPAREN);
- if (p->pend[i] != 0) {
+ if (p->pend[i] != 0)
+ {
assert(i <= p->g->nsub);
EMIT(OBACK_, i);
assert(p->pbegin[i] != 0);
assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
assert(OP(p->strip[p->pend[i]]) == ORPAREN);
- dupl(p, p->pbegin[i]+1, p->pend[i]);
+ dupl(p, p->pbegin[i] + 1, p->pend[i]);
EMIT(O_BACK, i);
- } else
+ }
+ else
SETERROR(REG_ESUBREG);
p->g->backrefs = 1;
break;
@@ -606,57 +642,69 @@ int starordinary; /* is a leading * an ordinary character? */
REQUIRE(starordinary, REG_BADRPT);
/* FALLTHROUGH */
default:
- ordinary(p, c &~ BACKSL);
+ ordinary(p, c & ~BACKSL);
break;
}
- if (EAT('*')) { /* implemented as +? */
+ if (EAT('*'))
+ { /* implemented as +? */
/* this case does not require the (y|) trick, noKLUDGE */
INSERT(OPLUS_, pos);
ASTERN(O_PLUS, pos);
INSERT(OQUEST_, pos);
ASTERN(O_QUEST, pos);
- } else if (EATTWO('\\', '{')) {
+ }
+ else if (EATTWO('\\', '{'))
+ {
count = p_count(p);
- if (EAT(',')) {
- if (MORE() && isdigit(PEEK())) {
+ if (EAT(','))
+ {
+ if (MORE() && isdigit(PEEK()))
+ {
count2 = p_count(p);
REQUIRE(count <= count2, REG_BADBR);
- } else /* single number with comma */
+ }
+ else
+/* single number with comma */
count2 = INFINITY;
- } else /* just a single number */
+ }
+ else
+/* just a single number */
count2 = count;
repeat(p, pos, count, count2);
- if (!EATTWO('\\', '}')) { /* error heuristics */
+ if (!EATTWO('\\', '}'))
+ { /* error heuristics */
while (MORE() && !SEETWO('\\', '}'))
NEXT();
REQUIRE(MORE(), REG_EBRACE);
SETERROR(REG_BADBR);
}
- } else if (c == (unsigned char)'$') /* $ (but not \$) ends it */
- return(1);
+ }
+ else if (c == (unsigned char) '$') /* $ (but not \$) ends it */
+ return (1);
- return(0);
+ return (0);
}
/*
- p_count - parse a repetition count
== static int p_count(register struct parse *p);
*/
-static int /* the value */
+static int /* the value */
p_count(p)
register struct parse *p;
{
- register int count = 0;
- register int ndigits = 0;
+ register int count = 0;
+ register int ndigits = 0;
- while (MORE() && isdigit(PEEK()) && count <= DUPMAX) {
- count = count*10 + (GETNEXT() - '0');
+ while (MORE() && isdigit(PEEK()) && count <= DUPMAX)
+ {
+ count = count * 10 + (GETNEXT() - '0');
ndigits++;
}
REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
- return(count);
+ return (count);
}
/*
@@ -670,23 +718,25 @@ static void
p_bracket(p)
register struct parse *p;
{
- register cset *cs = allocset(p);
- register int invert = 0;
+ register cset *cs = allocset(p);
+ register int invert = 0;
/* Dept of Truly Sickening Special-Case Kludges */
- if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
+ if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0)
+ {
EMIT(OBOW, 0);
NEXTn(6);
return;
}
- if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) {
+ if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0)
+ {
EMIT(OEOW, 0);
NEXTn(6);
return;
}
if (EAT('^'))
- invert++; /* make note to invert set at end */
+ invert++; /* make note to invert set at end */
if (EAT(']'))
CHadd(cs, ']');
else if (EAT('-'))
@@ -697,15 +747,17 @@ register struct parse *p;
CHadd(cs, '-');
MUSTEAT(']', REG_EBRACK);
- if (p->error != 0) /* don't mess things up further */
+ if (p->error != 0) /* don't mess things up further */
return;
- if (p->g->cflags&REG_ICASE) {
- register int i;
- register int ci;
+ if (p->g->cflags & REG_ICASE)
+ {
+ register int i;
+ register int ci;
for (i = p->g->csetsize - 1; i >= 0; i--)
- if (CHIN(cs, i) && isalpha(i)) {
+ if (CHIN(cs, i) && isalpha(i))
+ {
ci = othercase(i);
if (ci != i)
CHadd(cs, ci);
@@ -713,26 +765,29 @@ register struct parse *p;
if (cs->multis != NULL)
mccase(p, cs);
}
- if (invert) {
- register int i;
+ if (invert)
+ {
+ register int i;
for (i = p->g->csetsize - 1; i >= 0; i--)
if (CHIN(cs, i))
CHsub(cs, i);
else
CHadd(cs, i);
- if (p->g->cflags&REG_NEWLINE)
+ if (p->g->cflags & REG_NEWLINE)
CHsub(cs, '\n');
if (cs->multis != NULL)
mcinvert(p, cs);
}
- assert(cs->multis == NULL); /* xxx */
+ assert(cs->multis == NULL); /* xxx */
- if (nch(p, cs) == 1) { /* optimize singleton sets */
+ if (nch(p, cs) == 1)
+ { /* optimize singleton sets */
ordinary(p, firstch(p, cs));
freeset(p, cs);
- } else
+ }
+ else
EMIT(OANYOF, freezeset(p, cs));
}
@@ -743,28 +798,31 @@ register struct parse *p;
static void
p_b_term(p, cs)
register struct parse *p;
-register cset *cs;
+register cset *cs;
{
- register char c;
- register char start, finish;
- register int i;
+ register char c;
+ register char start,
+ finish;
+ register int i;
/* classify what we've got */
- switch ((MORE()) ? PEEK() : '\0') {
+ switch ((MORE()) ? PEEK() : '\0')
+ {
case '[':
c = (MORE2()) ? PEEK2() : '\0';
break;
case '-':
SETERROR(REG_ERANGE);
- return; /* NOTE RETURN */
+ return; /* NOTE RETURN */
break;
default:
c = '\0';
break;
}
- switch (c) {
- case ':': /* character class */
+ switch (c)
+ {
+ case ':': /* character class */
NEXT2();
REQUIRE(MORE(), REG_EBRACK);
c = PEEK();
@@ -773,7 +831,7 @@ register cset *cs;
REQUIRE(MORE(), REG_EBRACK);
REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
break;
- case '=': /* equivalence class */
+ case '=': /* equivalence class */
NEXT2();
REQUIRE(MORE(), REG_EBRACK);
c = PEEK();
@@ -782,17 +840,19 @@ register cset *cs;
REQUIRE(MORE(), REG_EBRACK);
REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
break;
- default: /* symbol, ordinary character, or range */
+ default: /* symbol, ordinary character, or range */
/* xxx revision needed for multichar stuff */
start = p_b_symbol(p);
- if (SEE('-') && MORE2() && PEEK2() != ']') {
+ if (SEE('-') && MORE2() && PEEK2() != ']')
+ {
/* range */
NEXT();
if (EAT('-'))
finish = '-';
else
finish = p_b_symbol(p);
- } else
+ }
+ else
finish = start;
/* xxx what about signed chars here... */
REQUIRE(start <= finish, REG_ERANGE);
@@ -809,13 +869,13 @@ register cset *cs;
static void
p_b_cclass(p, cs)
register struct parse *p;
-register cset *cs;
+register cset *cs;
{
- register char *sp = p->next;
+ register char *sp = p->next;
register struct cclass *cp;
register size_t len;
- register char *u;
- register char c;
+ register char *u;
+ register char c;
while (MORE() && isalpha(PEEK()))
NEXT();
@@ -823,7 +883,8 @@ register cset *cs;
for (cp = cclasses; cp->name != NULL; cp++)
if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
break;
- if (cp->name == NULL) {
+ if (cp->name == NULL)
+ {
/* oops, didn't find it */
SETERROR(REG_ECTYPE);
return;
@@ -845,9 +906,9 @@ register cset *cs;
static void
p_b_eclass(p, cs)
register struct parse *p;
-register cset *cs;
+register cset *cs;
{
- register char c;
+ register char c;
c = p_b_coll_elem(p, '=');
CHadd(cs, c);
@@ -857,66 +918,68 @@ register cset *cs;
- p_b_symbol - parse a character or [..]ed multicharacter collating symbol
== static char p_b_symbol(register struct parse *p);
*/
-static char /* value of symbol */
+static char /* value of symbol */
p_b_symbol(p)
register struct parse *p;
{
- register char value;
+ register char value;
REQUIRE(MORE(), REG_EBRACK);
if (!EATTWO('[', '.'))
- return(GETNEXT());
+ return (GETNEXT());
/* collating symbol */
value = p_b_coll_elem(p, '.');
REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
- return(value);
+ return (value);
}
/*
- p_b_coll_elem - parse a collating-element name and look it up
== static char p_b_coll_elem(register struct parse *p, int endc);
*/
-static char /* value of collating element */
+static char /* value of collating element */
p_b_coll_elem(p, endc)
register struct parse *p;
-int endc; /* name ended by endc,']' */
+int endc; /* name ended by endc,']' */
{
- register char *sp = p->next;
+ register char *sp = p->next;
register struct cname *cp;
- register int len;
+ register int len;
while (MORE() && !SEETWO(endc, ']'))
NEXT();
- if (!MORE()) {
+ if (!MORE())
+ {
SETERROR(REG_EBRACK);
- return(0);
+ return (0);
}
len = p->next - sp;
for (cp = cnames; cp->name != NULL; cp++)
if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
- return(cp->code); /* known name */
+ return (cp->code); /* known name */
if (len == 1)
- return(*sp); /* single character */
- SETERROR(REG_ECOLLATE); /* neither */
- return(0);
+ return (*sp); /* single character */
+ SETERROR(REG_ECOLLATE); /* neither */
+ return (0);
}
/*
- othercase - return the case counterpart of an alphabetic
== static char othercase(int ch);
*/
-static char /* if no counterpart, return ch */
+static char /* if no counterpart, return ch */
othercase(ch)
-int ch;
+int ch;
{
assert(isalpha(ch));
if (isupper(ch))
- return(tolower(ch));
+ return (tolower(ch));
else if (islower(ch))
- return(toupper(ch));
- else /* peculiar, but could happen */
- return(ch);
+ return (toupper(ch));
+ else
+/* peculiar, but could happen */
+ return (ch);
}
/*
@@ -928,20 +991,20 @@ int ch;
static void
bothcases(p, ch)
register struct parse *p;
-int ch;
+int ch;
{
- register char *oldnext = p->next;
- register char *oldend = p->end;
- char bracket[3];
+ register char *oldnext = p->next;
+ register char *oldend = p->end;
+ char bracket[3];
- assert(othercase(ch) != ch); /* p_bracket() would recurse */
+ assert(othercase(ch) != ch);/* p_bracket() would recurse */
p->next = bracket;
- p->end = bracket+2;
+ p->end = bracket + 2;
bracket[0] = ch;
bracket[1] = ']';
bracket[2] = '\0';
p_bracket(p);
- assert(p->next == bracket+2);
+ assert(p->next == bracket + 2);
p->next = oldnext;
p->end = oldend;
}
@@ -953,14 +1016,15 @@ int ch;
static void
ordinary(p, ch)
register struct parse *p;
-register int ch;
+register int ch;
{
register cat_t *cap = p->g->categories;
- if ((p->g->cflags&REG_ICASE) && isalpha(ch) && othercase(ch) != ch)
+ if ((p->g->cflags & REG_ICASE) && isalpha(ch) && othercase(ch) != ch)
bothcases(p, ch);
- else {
- EMIT(OCHAR, (unsigned char)ch);
+ else
+ {
+ EMIT(OCHAR, (unsigned char) ch);
if (cap[ch] == 0)
cap[ch] = p->g->ncategories++;
}
@@ -976,18 +1040,18 @@ static void
nonnewline(p)
register struct parse *p;
{
- register char *oldnext = p->next;
- register char *oldend = p->end;
- char bracket[4];
+ register char *oldnext = p->next;
+ register char *oldend = p->end;
+ char bracket[4];
p->next = bracket;
- p->end = bracket+3;
+ p->end = bracket + 3;
bracket[0] = '^';
bracket[1] = '\n';
bracket[2] = ']';
bracket[3] = '\0';
p_bracket(p);
- assert(p->next == bracket+3);
+ assert(p->next == bracket + 3);
p->next = oldnext;
p->end = oldend;
}
@@ -999,42 +1063,45 @@ register struct parse *p;
static void
repeat(p, start, from, to)
register struct parse *p;
-sopno start; /* operand from here to end of strip */
-int from; /* repeated from this number */
-int to; /* to this number of times (maybe INFINITY) */
+sopno start; /* operand from here to end of strip */
+int from; /* repeated from this number */
+int to; /* to this number of times (maybe
+ * INFINITY) */
{
- register sopno finish = HERE();
-# define N 2
-# define INF 3
-# define REP(f, t) ((f)*8 + (t))
-# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
- register sopno copy;
-
- if (p->error != 0) /* head off possible runaway recursion */
+ register sopno finish = HERE();
+
+#define N 2
+#define INF 3
+#define REP(f, t) ((f)*8 + (t))
+#define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
+ register sopno copy;
+
+ if (p->error != 0) /* head off possible runaway recursion */
return;
assert(from <= to);
- switch (REP(MAP(from), MAP(to))) {
- case REP(0, 0): /* must be user doing this */
- DROP(finish-start); /* drop the operand */
+ switch (REP(MAP(from), MAP(to)))
+ {
+ case REP(0, 0): /* must be user doing this */
+ DROP(finish - start); /* drop the operand */
break;
- case REP(0, 1): /* as x{1,1}? */
- case REP(0, N): /* as x{1,n}? */
- case REP(0, INF): /* as x{1,}? */
+ case REP(0, 1): /* as x{1,1}? */
+ case REP(0, N): /* as x{1,n}? */
+ case REP(0, INF): /* as x{1,}? */
/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
- INSERT(OCH_, start); /* offset is wrong... */
- repeat(p, start+1, 1, to);
+ INSERT(OCH_, start); /* offset is wrong... */
+ repeat(p, start + 1, 1, to);
ASTERN(OOR1, start);
AHEAD(start); /* ... fix it */
EMIT(OOR2, 0);
AHEAD(THERE());
ASTERN(O_CH, THERETHERE());
break;
- case REP(1, 1): /* trivial case */
+ case REP(1, 1): /* trivial case */
/* done */
break;
- case REP(1, N): /* as x?x{1,n-1} */
+ case REP(1, N): /* as x?x{1,n-1} */
/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
INSERT(OCH_, start);
ASTERN(OOR1, start);
@@ -1042,23 +1109,23 @@ int to; /* to this number of times (maybe INFINITY) */
EMIT(OOR2, 0); /* offset very wrong... */
AHEAD(THERE()); /* ...so fix it */
ASTERN(O_CH, THERETHERE());
- copy = dupl(p, start+1, finish+1);
- assert(copy == finish+4);
- repeat(p, copy, 1, to-1);
+ copy = dupl(p, start + 1, finish + 1);
+ assert(copy == finish + 4);
+ repeat(p, copy, 1, to - 1);
break;
- case REP(1, INF): /* as x+ */
+ case REP(1, INF): /* as x+ */
INSERT(OPLUS_, start);
ASTERN(O_PLUS, start);
break;
- case REP(N, N): /* as xx{m-1,n-1} */
+ case REP(N, N): /* as xx{m-1,n-1} */
copy = dupl(p, start, finish);
- repeat(p, copy, from-1, to-1);
+ repeat(p, copy, from - 1, to - 1);
break;
- case REP(N, INF): /* as xx{n-1,INF} */
+ case REP(N, INF): /* as xx{n-1,INF} */
copy = dupl(p, start, finish);
- repeat(p, copy, from-1, to);
+ repeat(p, copy, from - 1, to);
break;
- default: /* "can't happen" */
+ default: /* "can't happen" */
SETERROR(REG_ASSERT); /* just in case */
break;
}
@@ -1068,71 +1135,74 @@ int to; /* to this number of times (maybe INFINITY) */
- seterr - set an error condition
== static int seterr(register struct parse *p, int e);
*/
-static int /* useless but makes type checking happy */
+static int /* useless but makes type checking happy */
seterr(p, e)
register struct parse *p;
-int e;
+int e;
{
- if (p->error == 0) /* keep earliest error condition */
+ if (p->error == 0) /* keep earliest error condition */
p->error = e;
- p->next = nuls; /* try to bring things to a halt */
+ p->next = nuls; /* try to bring things to a halt */
p->end = nuls;
- return(0); /* make the return value well-defined */
+ return (0); /* make the return value well-defined */
}
/*
- allocset - allocate a set of characters for []
== static cset *allocset(register struct parse *p);
*/
-static cset *
+static cset *
allocset(p)
register struct parse *p;
{
- register int no = p->g->ncsets++;
+ register int no = p->g->ncsets++;
register size_t nc;
register size_t nbytes;
- register cset *cs;
- register size_t css = (size_t)p->g->csetsize;
- register int i;
+ register cset *cs;
+ register size_t css = (size_t) p->g->csetsize;
+ register int i;
- if (no >= p->ncsalloc) { /* need another column of space */
+ if (no >= p->ncsalloc)
+ { /* need another column of space */
p->ncsalloc += CHAR_BIT;
nc = p->ncsalloc;
assert(nc % CHAR_BIT == 0);
nbytes = nc / CHAR_BIT * css;
if (p->g->sets == NULL)
- p->g->sets = (cset *)malloc(nc * sizeof(cset));
+ p->g->sets = (cset *) malloc(nc * sizeof(cset));
else
- p->g->sets = (cset *)realloc((char *)p->g->sets,
- nc * sizeof(cset));
+ p->g->sets = (cset *) realloc((char *) p->g->sets,
+ nc * sizeof(cset));
if (p->g->setbits == NULL)
- p->g->setbits = (uch *)malloc(nbytes);
- else {
- p->g->setbits = (uch *)realloc((char *)p->g->setbits,
- nbytes);
+ p->g->setbits = (uch *) malloc(nbytes);
+ else
+ {
+ p->g->setbits = (uch *) realloc((char *) p->g->setbits,
+ nbytes);
/* xxx this isn't right if setbits is now NULL */
for (i = 0; i < no; i++)
- p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);
+ p->g->sets[i].ptr = p->g->setbits + css * (i / CHAR_BIT);
}
if (p->g->sets != NULL && p->g->setbits != NULL)
- memset((char *)p->g->setbits + (nbytes - css),
- 0, css);
- else {
+ memset((char *) p->g->setbits + (nbytes - css),
+ 0, css);
+ else
+ {
no = 0;
SETERROR(REG_ESPACE);
/* caller's responsibility not to do set ops */
}
}
- assert(p->g->sets != NULL); /* xxx */
+ assert(p->g->sets != NULL); /* xxx */
cs = &p->g->sets[no];
- cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);
+ cs->ptr = p->g->setbits + css * ((no) / CHAR_BIT);
cs->mask = 1 << ((no) % CHAR_BIT);
cs->hash = 0;
cs->smultis = 0;
cs->multis = NULL;
- return(cs);
+ return (cs);
}
/*
@@ -1142,15 +1212,15 @@ register struct parse *p;
static void
freeset(p, cs)
register struct parse *p;
-register cset *cs;
+register cset *cs;
{
- register int i;
- register cset *top = &p->g->sets[p->g->ncsets];
- register size_t css = (size_t)p->g->csetsize;
+ register int i;
+ register cset *top = &p->g->sets[p->g->ncsets];
+ register size_t css = (size_t) p->g->csetsize;
for (i = 0; i < css; i++)
CHsub(cs, i);
- if (cs == top-1) /* recover only the easy case */
+ if (cs == top - 1) /* recover only the easy case */
p->g->ncsets--;
}
@@ -1160,24 +1230,25 @@ register cset *cs;
*
* The main task here is merging identical sets. This is usually a waste
* of time (although the hash code minimizes the overhead), but can win
- * big if REG_ICASE is being used. REG_ICASE, by the way, is why the hash
+ * big if REG_ICASE is being used. REG_ICASE, by the way, is why the hash
* is done using addition rather than xor -- all ASCII [aA] sets xor to
* the same value!
*/
-static int /* set number */
+static int /* set number */
freezeset(p, cs)
register struct parse *p;
-register cset *cs;
+register cset *cs;
{
- register uch h = cs->hash;
- register int i;
- register cset *top = &p->g->sets[p->g->ncsets];
- register cset *cs2;
- register size_t css = (size_t)p->g->csetsize;
+ register uch h = cs->hash;
+ register int i;
+ register cset *top = &p->g->sets[p->g->ncsets];
+ register cset *cs2;
+ register size_t css = (size_t) p->g->csetsize;
/* look for an earlier one which is the same */
for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
- if (cs2->hash == h && cs2 != cs) {
+ if (cs2->hash == h && cs2 != cs)
+ {
/* maybe */
for (i = 0; i < css; i++)
if (!!CHIN(cs2, i) != !!CHIN(cs, i))
@@ -1186,31 +1257,32 @@ register cset *cs;
break; /* yes */
}
- if (cs2 < top) { /* found one */
+ if (cs2 < top)
+ { /* found one */
freeset(p, cs);
cs = cs2;
}
- return((int)(cs - p->g->sets));
+ return ((int) (cs - p->g->sets));
}
/*
- firstch - return first character in a set (which must have at least one)
== static int firstch(register struct parse *p, register cset *cs);
*/
-static int /* character; there is no "none" value */
+static int /* character; there is no "none" value */
firstch(p, cs)
register struct parse *p;
-register cset *cs;
+register cset *cs;
{
- register int i;
- register size_t css = (size_t)p->g->csetsize;
+ register int i;
+ register size_t css = (size_t) p->g->csetsize;
for (i = 0; i < css; i++)
if (CHIN(cs, i))
- return((char)i);
+ return ((char) i);
assert(never);
- return(0); /* arbitrary */
+ return (0); /* arbitrary */
}
/*
@@ -1220,28 +1292,28 @@ register cset *cs;
static int
nch(p, cs)
register struct parse *p;
-register cset *cs;
+register cset *cs;
{
- register int i;
- register size_t css = (size_t)p->g->csetsize;
- register int n = 0;
+ register int i;
+ register size_t css = (size_t) p->g->csetsize;
+ register int n = 0;
for (i = 0; i < css; i++)
if (CHIN(cs, i))
n++;
- return(n);
+ return (n);
}
/*
- mcadd - add a collating element to a cset
== static void mcadd(register struct parse *p, register cset *cs, \
- == register char *cp);
+ == register char *cp);
*/
static void
mcadd(p, cs, cp)
register struct parse *p;
-register cset *cs;
-register char *cp;
+register cset *cs;
+register char *cp;
{
register size_t oldend = cs->smultis;
@@ -1250,7 +1322,8 @@ register char *cp;
cs->multis = malloc(cs->smultis);
else
cs->multis = realloc(cs->multis, cs->smultis);
- if (cs->multis == NULL) {
+ if (cs->multis == NULL)
+ {
SETERROR(REG_ESPACE);
return;
}
@@ -1269,22 +1342,22 @@ mcsub(cs, cp)
register cset *cs;
register char *cp;
{
- register char *fp = mcfind(cs, cp);
- register size_t len = strlen(fp);
-
- assert(fp != NULL);
- memmove(fp, fp + len + 1,
- cs->smultis - (fp + len + 1 - cs->multis));
- cs->smultis -= len;
-
- if (cs->smultis == 0) {
- free(cs->multis);
- cs->multis = NULL;
- return;
- }
+ register char *fp = mcfind(cs, cp);
+ register size_t len = strlen(fp);
+
+ assert(fp != NULL);
+ memmove(fp, fp + len + 1,
+ cs->smultis - (fp + len + 1 - cs->multis));
+ cs->smultis -= len;
+
+ if (cs->smultis == 0) {
+ free(cs->multis);
+ cs->multis = NULL;
+ return;
+ }
- cs->multis = realloc(cs->multis, cs->smultis);
- assert(cs->multis != NULL);
+ cs->multis = realloc(cs->multis, cs->smultis);
+ assert(cs->multis != NULL);
}
*/
@@ -1298,7 +1371,7 @@ mcin(cs, cp)
register cset *cs;
register char *cp;
{
- return(mcfind(cs, cp) != NULL);
+ return(mcfind(cs, cp) != NULL);
}
*/
@@ -1312,14 +1385,14 @@ mcfind(cs, cp)
register cset *cs;
register char *cp;
{
- register char *p;
+ register char *p;
- if (cs->multis == NULL)
+ if (cs->multis == NULL)
+ return(NULL);
+ for (p = cs->multis; *p != '\0'; p += strlen(p) + 1)
+ if (strcmp(cp, p) == 0)
+ return(p);
return(NULL);
- for (p = cs->multis; *p != '\0'; p += strlen(p) + 1)
- if (strcmp(cp, p) == 0)
- return(p);
- return(NULL);
}
*/
/*
@@ -1332,9 +1405,9 @@ register char *cp;
static void
mcinvert(p, cs)
register struct parse *p;
-register cset *cs;
+register cset *cs;
{
- assert(cs->multis == NULL); /* xxx */
+ assert(cs->multis == NULL); /* xxx */
}
/*
@@ -1347,51 +1420,51 @@ register cset *cs;
static void
mccase(p, cs)
register struct parse *p;
-register cset *cs;
+register cset *cs;
{
- assert(cs->multis == NULL); /* xxx */
+ assert(cs->multis == NULL); /* xxx */
}
/*
- isinsets - is this character in any sets?
== static int isinsets(register struct re_guts *g, int c);
*/
-static int /* predicate */
+static int /* predicate */
isinsets(g, c)
register struct re_guts *g;
-int c;
+int c;
{
- register uch *col;
- register int i;
- register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
- register unsigned uc = (unsigned char)c;
+ register uch *col;
+ register int i;
+ register int ncols = (g->ncsets + (CHAR_BIT - 1)) / CHAR_BIT;
+ register unsigned uc = (unsigned char) c;
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
if (col[uc] != 0)
- return(1);
- return(0);
+ return (1);
+ return (0);
}
/*
- samesets - are these two characters in exactly the same sets?
== static int samesets(register struct re_guts *g, int c1, int c2);
*/
-static int /* predicate */
+static int /* predicate */
samesets(g, c1, c2)
register struct re_guts *g;
-int c1;
-int c2;
+int c1;
+int c2;
{
- register uch *col;
- register int i;
- register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
- register unsigned uc1 = (unsigned char)c1;
- register unsigned uc2 = (unsigned char)c2;
+ register uch *col;
+ register int i;
+ register int ncols = (g->ncsets + (CHAR_BIT - 1)) / CHAR_BIT;
+ register unsigned uc1 = (unsigned char) c1;
+ register unsigned uc2 = (unsigned char) c2;
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
if (col[uc1] != col[uc2])
- return(0);
- return(1);
+ return (0);
+ return (1);
}
/*
@@ -1400,23 +1473,24 @@ int c2;
*/
static void
categorize(p, g)
-struct parse *p;
+struct parse *p;
register struct re_guts *g;
{
register cat_t *cats = g->categories;
- register int c;
- register int c2;
- register cat_t cat;
+ register int c;
+ register int c2;
+ register cat_t cat;
/* avoid making error situations worse */
if (p->error != 0)
return;
for (c = CHAR_MIN; c <= CHAR_MAX; c++)
- if (cats[c] == 0 && isinsets(g, c)) {
+ if (cats[c] == 0 && isinsets(g, c))
+ {
cat = g->ncategories++;
cats[c] = cat;
- for (c2 = c+1; c2 <= CHAR_MAX; c2++)
+ for (c2 = c + 1; c2 <= CHAR_MAX; c2++)
if (cats[c2] == 0 && samesets(g, c, c2))
cats[c2] = cat;
}
@@ -1426,24 +1500,24 @@ register struct re_guts *g;
- dupl - emit a duplicate of a bunch of sops
== static sopno dupl(register struct parse *p, sopno start, sopno finish);
*/
-static sopno /* start of duplicate */
+static sopno /* start of duplicate */
dupl(p, start, finish)
register struct parse *p;
-sopno start; /* from here */
-sopno finish; /* to this less one */
+sopno start; /* from here */
+sopno finish; /* to this less one */
{
- register sopno ret = HERE();
- register sopno len = finish - start;
+ register sopno ret = HERE();
+ register sopno len = finish - start;
assert(finish >= start);
if (len == 0)
- return(ret);
- enlarge(p, p->ssize + len); /* this many unexpected additions */
+ return (ret);
+ enlarge(p, p->ssize + len); /* this many unexpected additions */
assert(p->ssize >= p->slen + len);
- memcpy((char *)(p->strip + p->slen),
- (char *)(p->strip + start), (size_t)len*sizeof(sop));
+ memcpy((char *) (p->strip + p->slen),
+ (char *) (p->strip + start), (size_t) len * sizeof(sop));
p->slen += len;
- return(ret);
+ return (ret);
}
/*
@@ -1457,19 +1531,19 @@ sopno finish; /* to this less one */
static void
doemit(p, op, opnd)
register struct parse *p;
-sop op;
-size_t opnd;
+sop op;
+size_t opnd;
{
/* avoid making error situations worse */
if (p->error != 0)
return;
/* deal with oversize operands ("can't happen", more or less) */
- assert(opnd < 1<<OPSHIFT);
+ assert(opnd < 1 << OPSHIFT);
/* deal with undersized strip */
if (p->slen >= p->ssize)
- enlarge(p, (p->ssize+1) / 2 * 3); /* +50% */
+ enlarge(p, (p->ssize + 1) / 2 * 3); /* +50% */
assert(p->slen < p->ssize);
/* finally, it's all reduced to the easy case */
@@ -1483,36 +1557,39 @@ size_t opnd;
static void
doinsert(p, op, opnd, pos)
register struct parse *p;
-sop op;
-size_t opnd;
-sopno pos;
+sop op;
+size_t opnd;
+sopno pos;
{
- register sopno sn;
- register sop s;
- register int i;
+ register sopno sn;
+ register sop s;
+ register int i;
/* avoid making error situations worse */
if (p->error != 0)
return;
sn = HERE();
- EMIT(op, opnd); /* do checks, ensure space */
- assert(HERE() == sn+1);
+ EMIT(op, opnd); /* do checks, ensure space */
+ assert(HERE() == sn + 1);
s = p->strip[sn];
/* adjust paren pointers */
assert(pos > 0);
- for (i = 1; i < NPAREN; i++) {
- if (p->pbegin[i] >= pos) {
+ for (i = 1; i < NPAREN; i++)
+ {
+ if (p->pbegin[i] >= pos)
+ {
p->pbegin[i]++;
}
- if (p->pend[i] >= pos) {
+ if (p->pend[i] >= pos)
+ {
p->pend[i]++;
}
}
- memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos],
- (HERE()-pos-1)*sizeof(sop));
+ memmove((char *) &p->strip[pos + 1], (char *) &p->strip[pos],
+ (HERE() - pos - 1) * sizeof(sop));
p->strip[pos] = s;
}
@@ -1523,14 +1600,14 @@ sopno pos;
static void
dofwd(p, pos, value)
register struct parse *p;
-register sopno pos;
-sop value;
+register sopno pos;
+sop value;
{
/* avoid making error situations worse */
if (p->error != 0)
return;
- assert(value < 1<<OPSHIFT);
+ assert(value < 1 << OPSHIFT);
p->strip[pos] = OP(p->strip[pos]) | value;
}
@@ -1541,15 +1618,16 @@ sop value;
static void
enlarge(p, size)
register struct parse *p;
-register sopno size;
+register sopno size;
{
- register sop *sp;
+ register sop *sp;
if (p->ssize >= size)
return;
- sp = (sop *)realloc(p->strip, size*sizeof(sop));
- if (sp == NULL) {
+ sp = (sop *) realloc(p->strip, size * sizeof(sop));
+ if (sp == NULL)
+ {
SETERROR(REG_ESPACE);
return;
}
@@ -1567,8 +1645,9 @@ register struct parse *p;
register struct re_guts *g;
{
g->nstates = p->slen;
- g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
- if (g->strip == NULL) {
+ g->strip = (sop *) realloc((char *) p->strip, p->slen * sizeof(sop));
+ if (g->strip == NULL)
+ {
SETERROR(REG_ESPACE);
g->strip = p->strip;
}
@@ -1586,16 +1665,16 @@ register struct re_guts *g;
*/
static void
findmust(p, g)
-struct parse *p;
+struct parse *p;
register struct re_guts *g;
{
- register sop *scan;
- sop *start = 0;
- register sop *newstart = 0;
- register sopno newlen;
- register sop s;
- register char *cp;
- register sopno i;
+ register sop *scan;
+ sop *start = 0;
+ register sop *newstart = 0;
+ register sopno newlen;
+ register sop s;
+ register char *cp;
+ register sopno i;
/* avoid making error situations worse */
if (p->error != 0)
@@ -1604,34 +1683,39 @@ register struct re_guts *g;
/* find the longest OCHAR sequence in strip */
newlen = 0;
scan = g->strip + 1;
- do {
+ do
+ {
s = *scan++;
- switch (OP(s)) {
- case OCHAR: /* sequence member */
- if (newlen == 0) /* new sequence */
+ switch (OP(s))
+ {
+ case OCHAR: /* sequence member */
+ if (newlen == 0) /* new sequence */
newstart = scan - 1;
newlen++;
break;
- case OPLUS_: /* things that don't break one */
+ case OPLUS_: /* things that don't break one */
case OLPAREN:
case ORPAREN:
break;
- case OQUEST_: /* things that must be skipped */
+ case OQUEST_: /* things that must be skipped */
case OCH_:
scan--;
- do {
+ do
+ {
scan += OPND(s);
s = *scan;
/* assert() interferes w debug printouts */
if (OP(s) != O_QUEST && OP(s) != O_CH &&
- OP(s) != OOR2) {
+ OP(s) != OOR2)
+ {
g->iflags |= BAD;
return;
}
} while (OP(s) != O_QUEST && OP(s) != O_CH);
/* fallthrough */
- default: /* things that break a sequence */
- if (newlen > g->mlen) { /* ends one */
+ default: /* things that break a sequence */
+ if (newlen > g->mlen)
+ { /* ends one */
start = newstart;
g->mlen = newlen;
}
@@ -1640,48 +1724,52 @@ register struct re_guts *g;
}
} while (OP(s) != OEND);
- if (g->mlen == 0) /* there isn't one */
+ if (g->mlen == 0) /* there isn't one */
return;
/* turn it into a character string */
- g->must = malloc((size_t)g->mlen + 1);
- if (g->must == NULL) { /* argh; just forget it */
+ g->must = malloc((size_t) g->mlen + 1);
+ if (g->must == NULL)
+ { /* argh; just forget it */
g->mlen = 0;
return;
}
cp = g->must;
scan = start;
- for (i = g->mlen; i > 0; i--) {
+ for (i = g->mlen; i > 0; i--)
+ {
while (OP(s = *scan++) != OCHAR)
continue;
assert(cp < g->must + g->mlen);
- *cp++ = (char)OPND(s);
+ *cp++ = (char) OPND(s);
}
assert(cp == g->must + g->mlen);
- *cp++ = '\0'; /* just on general principles */
+ *cp++ = '\0'; /* just on general principles */
}
/*
- pluscount - count + nesting
== static sopno pluscount(register struct parse *p, register struct re_guts *g);
*/
-static sopno /* nesting depth */
+static sopno /* nesting depth */
pluscount(p, g)
-struct parse *p;
+struct parse *p;
register struct re_guts *g;
{
- register sop *scan;
- register sop s;
- register sopno plusnest = 0;
- register sopno maxnest = 0;
+ register sop *scan;
+ register sop s;
+ register sopno plusnest = 0;
+ register sopno maxnest = 0;
if (p->error != 0)
- return(0); /* there may not be an OEND */
+ return (0); /* there may not be an OEND */
scan = g->strip + 1;
- do {
+ do
+ {
s = *scan++;
- switch (OP(s)) {
+ switch (OP(s))
+ {
case OPLUS_:
plusnest++;
break;
@@ -1694,5 +1782,5 @@ register struct re_guts *g;
} while (OP(s) != OEND);
if (plusnest != 0)
g->iflags |= BAD;
- return(maxnest);
+ return (maxnest);
}
diff --git a/src/backend/regex/regerror.c b/src/backend/regex/regerror.c
index 7d1d06cbc90..9e6e0e02179 100644
--- a/src/backend/regex/regerror.c
+++ b/src/backend/regex/regerror.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,12 +34,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)regerror.c 8.4 (Berkeley) 3/20/94
+ * @(#)regerror.c 8.4 (Berkeley) 3/20/94
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)regerror.c 8.4 (Berkeley) 3/20/94";
-#endif /* LIBC_SCCS and not lint */
+static char sccsid[] = "@(#)regerror.c 8.4 (Berkeley) 3/20/94";
+
+#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stdio.h>
@@ -54,58 +55,97 @@ static char sccsid[] = "@(#)regerror.c 8.4 (Berkeley) 3/20/94";
/* ========= begin header generated by ./mkh ========= */
#ifdef __cplusplus
-extern "C" {
+extern "C"
+{
#endif
/* === regerror.c === */
-static char *regatoi(const regex_t *preg, char *localbuf);
+ static char *regatoi(const regex_t * preg, char *localbuf);
#ifdef __cplusplus
}
+
#endif
/* ========= end header generated by ./mkh ========= */
/*
- = #define REG_NOMATCH 1
- = #define REG_BADPAT 2
- = #define REG_ECOLLATE 3
- = #define REG_ECTYPE 4
- = #define REG_EESCAPE 5
- = #define REG_ESUBREG 6
- = #define REG_EBRACK 7
- = #define REG_EPAREN 8
- = #define REG_EBRACE 9
- = #define REG_BADBR 10
- = #define REG_ERANGE 11
- = #define REG_ESPACE 12
- = #define REG_BADRPT 13
- = #define REG_EMPTY 14
- = #define REG_ASSERT 15
- = #define REG_INVARG 16
- = #define REG_ATOI 255 // convert name to number (!)
- = #define REG_ITOA 0400 // convert number to name (!)
+ = #define REG_NOMATCH 1
+ = #define REG_BADPAT 2
+ = #define REG_ECOLLATE 3
+ = #define REG_ECTYPE 4
+ = #define REG_EESCAPE 5
+ = #define REG_ESUBREG 6
+ = #define REG_EBRACK 7
+ = #define REG_EPAREN 8
+ = #define REG_EBRACE 9
+ = #define REG_BADBR 10
+ = #define REG_ERANGE 11
+ = #define REG_ESPACE 12
+ = #define REG_BADRPT 13
+ = #define REG_EMPTY 14
+ = #define REG_ASSERT 15
+ = #define REG_INVARG 16
+ = #define REG_ATOI 255 // convert name to number (!)
+ = #define REG_ITOA 0400 // convert number to name (!)
*/
-static struct rerr {
- int code;
- char *name;
- char *explain;
-} rerrs[] = {
- {REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"},
- {REG_BADPAT, "REG_BADPAT", "invalid regular expression"},
- {REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"},
- {REG_ECTYPE, "REG_ECTYPE", "invalid character class"},
- {REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)"},
- {REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"},
- {REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced"},
- {REG_EPAREN, "REG_EPAREN", "parentheses not balanced"},
- {REG_EBRACE, "REG_EBRACE", "braces not balanced"},
- {REG_BADBR, "REG_BADBR", "invalid repetition count(s)"},
- {REG_ERANGE, "REG_ERANGE", "invalid character range"},
- {REG_ESPACE, "REG_ESPACE", "out of memory"},
- {REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid"},
- {REG_EMPTY, "REG_EMPTY", "empty (sub)expression"},
- {REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"},
- {REG_INVARG, "REG_INVARG", "invalid argument to regex routine"},
- {0, "", "*** unknown regexp error code ***"}
+static struct rerr
+{
+ int code;
+ char *name;
+ char *explain;
+} rerrs[] =
+
+{
+ {
+ REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"
+ },
+ {
+ REG_BADPAT, "REG_BADPAT", "invalid regular expression"
+ },
+ {
+ REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"
+ },
+ {
+ REG_ECTYPE, "REG_ECTYPE", "invalid character class"
+ },
+ {
+ REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)"
+ },
+ {
+ REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"
+ },
+ {
+ REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced"
+ },
+ {
+ REG_EPAREN, "REG_EPAREN", "parentheses not balanced"
+ },
+ {
+ REG_EBRACE, "REG_EBRACE", "braces not balanced"
+ },
+ {
+ REG_BADBR, "REG_BADBR", "invalid repetition count(s)"
+ },
+ {
+ REG_ERANGE, "REG_ERANGE", "invalid character range"
+ },
+ {
+ REG_ESPACE, "REG_ESPACE", "out of memory"
+ },
+ {
+ REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid"
+ },
+ {
+ REG_EMPTY, "REG_EMPTY", "empty (sub)expression"
+ },
+ {
+ REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"
+ },
+ {
+ REG_INVARG, "REG_INVARG", "invalid argument to regex routine"
+ },
+ {
+ 0, "", "*** unknown regexp error code ***"
+ }
};
/*
@@ -115,56 +155,61 @@ static struct rerr {
/* ARGSUSED */
size_t
pg95_regerror(errcode, preg, errbuf, errbuf_size)
-int errcode;
-const regex_t *preg;
-char *errbuf;
-size_t errbuf_size;
+int errcode;
+const regex_t *preg;
+char *errbuf;
+size_t errbuf_size;
{
register struct rerr *r;
register size_t len;
- register int target = errcode &~ REG_ITOA;
- register char *s;
- char convbuf[50];
+ register int target = errcode & ~REG_ITOA;
+ register char *s;
+ char convbuf[50];
if (errcode == REG_ATOI)
s = regatoi(preg, convbuf);
- else {
+ else
+ {
for (r = rerrs; r->code != 0; r++)
if (r->code == target)
break;
-
- if (errcode&REG_ITOA) {
+
+ if (errcode & REG_ITOA)
+ {
if (r->code != 0)
strcpy(convbuf, r->name);
else
sprintf(convbuf, "REG_0x%x", target);
assert(strlen(convbuf) < sizeof(convbuf));
s = convbuf;
- } else
+ }
+ else
s = r->explain;
}
len = strlen(s) + 1;
- if (errbuf_size > 0) {
+ if (errbuf_size > 0)
+ {
if (errbuf_size > len)
strcpy(errbuf, s);
- else {
- strncpy(errbuf, s, errbuf_size-1);
- errbuf[errbuf_size-1] = '\0';
+ else
+ {
+ strncpy(errbuf, s, errbuf_size - 1);
+ errbuf[errbuf_size - 1] = '\0';
}
}
- return(len);
+ return (len);
}
/*
- regatoi - internal routine to implement REG_ATOI
== static char *regatoi(const regex_t *preg, char *localbuf);
*/
-static char *
+static char *
regatoi(preg, localbuf)
-const regex_t *preg;
-char *localbuf;
+const regex_t *preg;
+char *localbuf;
{
register struct rerr *r;
@@ -172,8 +217,8 @@ char *localbuf;
if (strcmp(r->name, preg->re_endp) == 0)
break;
if (r->code == 0)
- return("0");
+ return ("0");
sprintf(localbuf, "%d", r->code);
- return(localbuf);
+ return (localbuf);
}
diff --git a/src/backend/regex/regexec.c b/src/backend/regex/regexec.c
index 115a17667bb..5e0021f4299 100644
--- a/src/backend/regex/regexec.c
+++ b/src/backend/regex/regexec.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,12 +34,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)regexec.c 8.3 (Berkeley) 3/20/94
+ * @(#)regexec.c 8.3 (Berkeley) 3/20/94
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)regexec.c 8.3 (Berkeley) 3/20/94";
-#endif /* LIBC_SCCS and not lint */
+static char sccsid[] = "@(#)regexec.c 8.3 (Berkeley) 3/20/94";
+
+#endif /* LIBC_SCCS and not lint */
/*
* the outer shell of regexec()
@@ -60,32 +61,32 @@ static char sccsid[] = "@(#)regexec.c 8.3 (Berkeley) 3/20/94";
#include <regex/utils.h>
#include <regex/regex2.h>
-static int nope = 0; /* for use in asserts; shuts lint up */
+static int nope = 0; /* for use in asserts; shuts lint up */
/* macros for manipulating states, small version */
-#define states long
-#define states1 states /* for later use in regexec() decision */
-#define CLEAR(v) ((v) = 0)
-#define SET0(v, n) ((v) &= ~(1 << (n)))
-#define SET1(v, n) ((v) |= 1 << (n))
-#define ISSET(v, n) ((v) & (1 << (n)))
-#define ASSIGN(d, s) ((d) = (s))
-#define EQ(a, b) ((a) == (b))
-#define STATEVARS int dummy /* dummy version */
-#define STATESETUP(m, n) /* nothing */
-#define STATETEARDOWN(m) /* nothing */
-#define SETUP(v) ((v) = 0)
-#define onestate int
-#define INIT(o, n) ((o) = (unsigned)1 << (n))
-#define INC(o) ((o) <<= 1)
-#define ISSTATEIN(v, o) ((v) & (o))
+#define states long
+#define states1 states /* for later use in regexec() decision */
+#define CLEAR(v) ((v) = 0)
+#define SET0(v, n) ((v) &= ~(1 << (n)))
+#define SET1(v, n) ((v) |= 1 << (n))
+#define ISSET(v, n) ((v) & (1 << (n)))
+#define ASSIGN(d, s) ((d) = (s))
+#define EQ(a, b) ((a) == (b))
+#define STATEVARS int dummy /* dummy version */
+#define STATESETUP(m, n) /* nothing */
+#define STATETEARDOWN(m) /* nothing */
+#define SETUP(v) ((v) = 0)
+#define onestate int
+#define INIT(o, n) ((o) = (unsigned)1 << (n))
+#define INC(o) ((o) <<= 1)
+#define ISSTATEIN(v, o) ((v) & (o))
/* some abbreviations; note that some of these know variable names! */
/* do "if I'm here, I can also be there" etc without branches */
-#define FWD(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) << (n))
-#define BACK(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) >> (n))
-#define ISSETBACK(v, n) ((v) & ((unsigned)here >> (n)))
+#define FWD(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) << (n))
+#define BACK(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) >> (n))
+#define ISSETBACK(v, n) ((v) & ((unsigned)here >> (n)))
/* function names */
-#define SNAMES /* engine.c looks after details */
+#define SNAMES /* engine.c looks after details */
#include "engine.c"
@@ -111,72 +112,73 @@ static int nope = 0; /* for use in asserts; shuts lint up */
#undef SNAMES
/* macros for manipulating states, large version */
-#define states char *
-#define CLEAR(v) memset(v, 0, m->g->nstates)
-#define SET0(v, n) ((v)[n] = 0)
-#define SET1(v, n) ((v)[n] = 1)
-#define ISSET(v, n) ((v)[n])
-#define ASSIGN(d, s) memcpy(d, s, m->g->nstates)
-#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
-#define STATEVARS int vn; char *space
-#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \
- if ((m)->space == NULL) return(REG_ESPACE); \
- (m)->vn = 0; }
-#define STATETEARDOWN(m) { free((m)->space); }
-#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
-#define onestate int
-#define INIT(o, n) ((o) = (n))
-#define INC(o) ((o)++)
-#define ISSTATEIN(v, o) ((v)[o])
+#define states char *
+#define CLEAR(v) memset(v, 0, m->g->nstates)
+#define SET0(v, n) ((v)[n] = 0)
+#define SET1(v, n) ((v)[n] = 1)
+#define ISSET(v, n) ((v)[n])
+#define ASSIGN(d, s) memcpy(d, s, m->g->nstates)
+#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
+#define STATEVARS int vn; char *space
+#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \
+ if ((m)->space == NULL) return(REG_ESPACE); \
+ (m)->vn = 0; }
+#define STATETEARDOWN(m) { free((m)->space); }
+#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
+#define onestate int
+#define INIT(o, n) ((o) = (n))
+#define INC(o) ((o)++)
+#define ISSTATEIN(v, o) ((v)[o])
/* some abbreviations; note that some of these know variable names! */
/* do "if I'm here, I can also be there" etc without branches */
-#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here])
-#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here])
-#define ISSETBACK(v, n) ((v)[here - (n)])
+#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here])
+#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here])
+#define ISSETBACK(v, n) ((v)[here - (n)])
/* function names */
-#define LNAMES /* flag */
+#define LNAMES /* flag */
#include "engine.c"
/*
- regexec - interface for matching
= extern int regexec(const regex_t *, const char *, size_t, \
- = regmatch_t [], int);
- = #define REG_NOTBOL 00001
- = #define REG_NOTEOL 00002
- = #define REG_STARTEND 00004
- = #define REG_TRACE 00400 // tracing of execution
- = #define REG_LARGE 01000 // force large representation
- = #define REG_BACKR 02000 // force use of backref code
+ = regmatch_t [], int);
+ = #define REG_NOTBOL 00001
+ = #define REG_NOTEOL 00002
+ = #define REG_STARTEND 00004
+ = #define REG_TRACE 00400 // tracing of execution
+ = #define REG_LARGE 01000 // force large representation
+ = #define REG_BACKR 02000 // force use of backref code
*
* We put this here so we can exploit knowledge of the state representation
* when choosing which matcher to call. Also, by this point the matchers
* have been prototyped.
*/
-int /* 0 success, REG_NOMATCH failure */
+int /* 0 success, REG_NOMATCH failure */
pg95_regexec(preg, string, nmatch, pmatch, eflags)
-const regex_t *preg;
-const char *string;
-size_t nmatch;
-regmatch_t pmatch[];
-int eflags;
+const regex_t *preg;
+const char *string;
+size_t nmatch;
+regmatch_t pmatch[];
+int eflags;
{
register struct re_guts *g = preg->re_g;
+
#ifdef REDEBUG
-# define GOODFLAGS(f) (f)
+#define GOODFLAGS(f) (f)
#else
-# define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
+#define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
#endif
if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
- return(REG_BADPAT);
- assert(!(g->iflags&BAD));
- if (g->iflags&BAD) /* backstop for no-debug case */
- return(REG_BADPAT);
+ return (REG_BADPAT);
+ assert(!(g->iflags & BAD));
+ if (g->iflags & BAD) /* backstop for no-debug case */
+ return (REG_BADPAT);
eflags = GOODFLAGS(eflags);
- if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags&REG_LARGE))
- return(smatcher(g, (char *)string, nmatch, pmatch, eflags));
+ if (g->nstates <= CHAR_BIT * sizeof(states1) && !(eflags & REG_LARGE))
+ return (smatcher(g, (char *) string, nmatch, pmatch, eflags));
else
- return(lmatcher(g, (char *)string, nmatch, pmatch, eflags));
+ return (lmatcher(g, (char *) string, nmatch, pmatch, eflags));
}
diff --git a/src/backend/regex/regfree.c b/src/backend/regex/regfree.c
index 9a7ff5cb5e1..26ca8863ed6 100644
--- a/src/backend/regex/regfree.c
+++ b/src/backend/regex/regfree.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,12 +34,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)regfree.c 8.3 (Berkeley) 3/20/94
+ * @(#)regfree.c 8.3 (Berkeley) 3/20/94
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)regfree.c 8.3 (Berkeley) 3/20/94";
-#endif /* LIBC_SCCS and not lint */
+static char sccsid[] = "@(#)regfree.c 8.3 (Berkeley) 3/20/94";
+
+#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stdio.h>
@@ -55,26 +56,26 @@ static char sccsid[] = "@(#)regfree.c 8.3 (Berkeley) 3/20/94";
*/
void
pg95_regfree(preg)
-regex_t *preg;
+regex_t *preg;
{
register struct re_guts *g;
- if (preg->re_magic != MAGIC1) /* oops */
- return; /* nice to complain, but hard */
+ if (preg->re_magic != MAGIC1) /* oops */
+ return; /* nice to complain, but hard */
g = preg->re_g;
- if (g == NULL || g->magic != MAGIC2) /* oops again */
+ if (g == NULL || g->magic != MAGIC2) /* oops again */
return;
- preg->re_magic = 0; /* mark it invalid */
- g->magic = 0; /* mark it invalid */
+ preg->re_magic = 0; /* mark it invalid */
+ g->magic = 0; /* mark it invalid */
if (g->strip != NULL)
- free((char *)g->strip);
+ free((char *) g->strip);
if (g->sets != NULL)
- free((char *)g->sets);
+ free((char *) g->sets);
if (g->setbits != NULL)
- free((char *)g->setbits);
+ free((char *) g->setbits);
if (g->must != NULL)
free(g->must);
- free((char *)g);
+ free((char *) g);
}
diff --git a/src/backend/rewrite/locks.c b/src/backend/rewrite/locks.c
index 3171d2c845b..213fae9b321 100644
--- a/src/backend/rewrite/locks.c
+++ b/src/backend/rewrite/locks.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.2 1996/11/10 03:01:50 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.3 1997/09/07 04:48:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,7 +14,7 @@
#include "utils/elog.h" /* for elog */
#include "nodes/pg_list.h" /* lisp support package */
#include "nodes/parsenodes.h"
-#include "nodes/primnodes.h" /* Var node def */
+#include "nodes/primnodes.h" /* Var node def */
#include "utils/syscache.h" /* for SearchSysCache */
#include "rewrite/locks.h" /* for rewrite specific lock defns */
@@ -26,106 +26,115 @@
* if we find at least one such match, we return true
* otherwise, we return false
*/
-static bool
-nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum)
+static bool
+nodeThisLockWasTriggered(Node * node, int varno, AttrNumber attnum)
{
- if (node==NULL)
- return FALSE;
- switch(nodeTag(node)) {
- case T_Var:
+ if (node == NULL)
+ return FALSE;
+ switch (nodeTag(node))
{
- Var *var = (Var *)node;
- if (varno == var->varno &&
- (attnum == var->varattno || attnum == -1))
- return TRUE;
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr*)node;
- return
- nodeThisLockWasTriggered((Node*)expr->args, varno, attnum);
- }
- break;
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
- return
- nodeThisLockWasTriggered(tle->expr, varno, attnum);
- }
- break;
- case T_List:
- {
- List *l;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+
+ if (varno == var->varno &&
+ (attnum == var->varattno || attnum == -1))
+ return TRUE;
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ return
+ nodeThisLockWasTriggered((Node *) expr->args, varno, attnum);
+ }
+ break;
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ return
+ nodeThisLockWasTriggered(tle->expr, varno, attnum);
+ }
+ break;
+ case T_List:
+ {
+ List *l;
- foreach(l, (List*)node) {
- if (nodeThisLockWasTriggered(lfirst(l), varno, attnum))
- return TRUE;
- }
- return FALSE;
+ foreach(l, (List *) node)
+ {
+ if (nodeThisLockWasTriggered(lfirst(l), varno, attnum))
+ return TRUE;
+ }
+ return FALSE;
+ }
+ break;
+ default:
+ break;
}
- break;
- default:
- break;
- }
- return (FALSE);
+ return (FALSE);
}
/*
* thisLockWasTriggered -
- * walk the tree, if there we find a varnode, we check the varattno
- * against the attnum if we find at least one such match, we return true
- * otherwise, we return false
+ * walk the tree, if there we find a varnode, we check the varattno
+ * against the attnum if we find at least one such match, we return true
+ * otherwise, we return false
*/
-static bool
+static bool
thisLockWasTriggered(int varno,
- AttrNumber attnum,
- Query *parsetree)
+ AttrNumber attnum,
+ Query * parsetree)
{
- return
+ return
(nodeThisLockWasTriggered(parsetree->qual, varno, attnum) ||
- nodeThisLockWasTriggered((Node*)parsetree->targetList,
- varno, attnum));
+ nodeThisLockWasTriggered((Node *) parsetree->targetList,
+ varno, attnum));
}
/*
* matchLocks -
- * match the list of locks and returns the matching rules
+ * match the list of locks and returns the matching rules
*/
-List *
+List *
matchLocks(CmdType event,
- RuleLock *rulelocks,
- int varno,
- Query *parsetree)
+ RuleLock * rulelocks,
+ int varno,
+ Query * parsetree)
{
- List *real_locks = NIL;
- int nlocks;
- int i;
-
- Assert(rulelocks != NULL); /* we get called iff there is some lock */
- Assert(parsetree != NULL);
-
- if (parsetree->commandType != CMD_SELECT) {
- if (parsetree->resultRelation != varno) {
- return ( NULL );
+ List *real_locks = NIL;
+ int nlocks;
+ int i;
+
+ Assert(rulelocks != NULL); /* we get called iff there is some lock */
+ Assert(parsetree != NULL);
+
+ if (parsetree->commandType != CMD_SELECT)
+ {
+ if (parsetree->resultRelation != varno)
+ {
+ return (NULL);
+ }
}
- }
-
- nlocks = rulelocks->numLocks;
-
- for (i = 0; i < nlocks; i++) {
- RewriteRule *oneLock = rulelocks->rules[i];
- if (oneLock->event == event) {
- if (parsetree->commandType != CMD_SELECT ||
- thisLockWasTriggered(varno,
- oneLock->attrno,
- parsetree)) {
- real_locks = lappend(real_locks, oneLock);
- }
+ nlocks = rulelocks->numLocks;
+
+ for (i = 0; i < nlocks; i++)
+ {
+ RewriteRule *oneLock = rulelocks->rules[i];
+
+ if (oneLock->event == event)
+ {
+ if (parsetree->commandType != CMD_SELECT ||
+ thisLockWasTriggered(varno,
+ oneLock->attrno,
+ parsetree))
+ {
+ real_locks = lappend(real_locks, oneLock);
+ }
+ }
}
- }
-
- return (real_locks);
-}
+ return (real_locks);
+}
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index a9383fe53da..01b05c4cd0e 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rewriteDefine.c--
- * routines for defining a rewrite rule
+ * routines for defining a rewrite rule
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.3 1997/07/24 20:13:33 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.4 1997/09/07 04:48:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,235 +20,252 @@
#include "utils/builtins.h"
#include "utils/elog.h" /* for elog */
#include "utils/palloc.h"
-#include "utils/lsyscache.h" /* for get_typlen */
+#include "utils/lsyscache.h" /* for get_typlen */
#include "nodes/pg_list.h" /* for Lisp support */
#include "nodes/parsenodes.h"
#include "parser/catalog_utils.h"
-#include "rewrite/locks.h"
+#include "rewrite/locks.h"
#include "rewrite/rewriteDefine.h"
#include "rewrite/rewriteRemove.h"
#include "rewrite/rewriteSupport.h"
#include "tcop/tcopprot.h"
-Oid LastOidProcessed = InvalidOid;
+Oid LastOidProcessed = InvalidOid;
/*
* This is too small for many rule plans, but it'll have to do for now.
* Rule plans, etc will eventually have to be large objects.
- *
+ *
* should this be smaller?
*/
-#define RULE_PLAN_SIZE 8192
+#define RULE_PLAN_SIZE 8192
static void
strcpyq(char *dest, char *source)
{
- char *current=source,*destp= dest;
-
- for(current=source; *current; current++) {
- if (*current == '\"') {
- *destp = '\\';
- destp++;
+ char *current = source,
+ *destp = dest;
+
+ for (current = source; *current; current++)
+ {
+ if (*current == '\"')
+ {
+ *destp = '\\';
+ destp++;
+ }
+ *destp = *current;
+ destp++;
}
- *destp = *current;
- destp++;
- }
- *destp = '\0';
+ *destp = '\0';
}
/*
* InsertRule -
- * takes the arguments and inserts them as attributes into the system
- * relation "pg_rewrite"
+ * takes the arguments and inserts them as attributes into the system
+ * relation "pg_rewrite"
*
- * MODS : changes the value of LastOidProcessed as a side
- * effect of inserting the rule tuple
+ * MODS : changes the value of LastOidProcessed as a side
+ * effect of inserting the rule tuple
*
- * ARGS : rulname - name of the rule
- * evtype - one of RETRIEVE,REPLACE,DELETE,APPEND
- * evobj - name of relation
- * evslot - comma delimited list of slots
- * if null => multi-attr rule
- * evinstead - is an instead rule
- * actiontree - parsetree(s) of rule action
+ * ARGS : rulname - name of the rule
+ * evtype - one of RETRIEVE,REPLACE,DELETE,APPEND
+ * evobj - name of relation
+ * evslot - comma delimited list of slots
+ * if null => multi-attr rule
+ * evinstead - is an instead rule
+ * actiontree - parsetree(s) of rule action
*/
-static Oid
+static Oid
InsertRule(char *rulname,
- int evtype,
- char *evobj,
- char *evslot,
- char *evqual,
- bool evinstead,
- char *actiontree)
+ int evtype,
+ char *evobj,
+ char *evslot,
+ char *evqual,
+ bool evinstead,
+ char *actiontree)
{
- static char rulebuf[RULE_PLAN_SIZE];
- static char actionbuf[RULE_PLAN_SIZE];
- static char qualbuf[RULE_PLAN_SIZE];
- Oid eventrel_oid = InvalidOid;
- AttrNumber evslot_index = InvalidAttrNumber;
- Relation eventrel = NULL;
- char *is_instead = "f";
- extern void eval_as_new_xact();
- char *template;
-
- eventrel = heap_openr(evobj);
- if (eventrel == NULL) {
- elog(WARN, "rules cannot be defined on relations not in schema");
- }
- eventrel_oid = RelationGetRelationId(eventrel);
-
- /*
- * if the slotname is null, we know that this is a multi-attr
- * rule
- */
- if (evslot == NULL)
- evslot_index = -1;
- else
- evslot_index = varattno(eventrel, (char*)evslot);
- heap_close(eventrel);
-
- if (evinstead)
- is_instead = "t";
-
- if (evqual == NULL)
- evqual = "nil";
-
- if (IsDefinedRewriteRule(rulname))
- elog(WARN, "Attempt to insert rule '%s' failed: already exists",
- rulname);
- strcpyq(actionbuf,actiontree);
- strcpyq(qualbuf, evqual);
-
- template = "INSERT INTO pg_rewrite \
+ static char rulebuf[RULE_PLAN_SIZE];
+ static char actionbuf[RULE_PLAN_SIZE];
+ static char qualbuf[RULE_PLAN_SIZE];
+ Oid eventrel_oid = InvalidOid;
+ AttrNumber evslot_index = InvalidAttrNumber;
+ Relation eventrel = NULL;
+ char *is_instead = "f";
+ extern void eval_as_new_xact();
+ char *template;
+
+ eventrel = heap_openr(evobj);
+ if (eventrel == NULL)
+ {
+ elog(WARN, "rules cannot be defined on relations not in schema");
+ }
+ eventrel_oid = RelationGetRelationId(eventrel);
+
+ /*
+ * if the slotname is null, we know that this is a multi-attr rule
+ */
+ if (evslot == NULL)
+ evslot_index = -1;
+ else
+ evslot_index = varattno(eventrel, (char *) evslot);
+ heap_close(eventrel);
+
+ if (evinstead)
+ is_instead = "t";
+
+ if (evqual == NULL)
+ evqual = "nil";
+
+ if (IsDefinedRewriteRule(rulname))
+ elog(WARN, "Attempt to insert rule '%s' failed: already exists",
+ rulname);
+ strcpyq(actionbuf, actiontree);
+ strcpyq(qualbuf, evqual);
+
+ template = "INSERT INTO pg_rewrite \
(rulename, ev_type, ev_class, ev_attr, action, ev_qual, is_instead) VALUES \
('%s', %d::char, %d::oid, %d::int2, '%s'::text, '%s'::text, \
'%s'::bool);";
- if (strlen(template) + strlen(rulname) + strlen(actionbuf) +
- strlen(qualbuf) + 20 /* fudge fac */ > RULE_PLAN_SIZE) {
- elog(WARN, "DefineQueryRewrite: rule plan string too big.");
- }
- sprintf(rulebuf, template,
- rulname, evtype, eventrel_oid, evslot_index, actionbuf,
- qualbuf, is_instead);
-
- pg_eval(rulebuf, (char **) NULL, (Oid *) NULL, 0);
-
- return (LastOidProcessed);
+ if (strlen(template) + strlen(rulname) + strlen(actionbuf) +
+ strlen(qualbuf) + 20 /* fudge fac */ > RULE_PLAN_SIZE)
+ {
+ elog(WARN, "DefineQueryRewrite: rule plan string too big.");
+ }
+ sprintf(rulebuf, template,
+ rulname, evtype, eventrel_oid, evslot_index, actionbuf,
+ qualbuf, is_instead);
+
+ pg_eval(rulebuf, (char **) NULL, (Oid *) NULL, 0);
+
+ return (LastOidProcessed);
}
/*
- * for now, event_object must be a single attribute
+ * for now, event_object must be a single attribute
*/
static void
ValidateRule(int event_type,
- char *eobj_string,
- char *eslot_string,
- Node *event_qual,
- List **action,
- int is_instead,
- Oid event_attype)
+ char *eobj_string,
+ char *eslot_string,
+ Node * event_qual,
+ List ** action,
+ int is_instead,
+ Oid event_attype)
{
- if (((event_type == CMD_INSERT) || (event_type == CMD_DELETE)) &&
- eslot_string) {
- elog(WARN,
- "rules not allowed for insert or delete events to an attribute");
- }
-
- if (event_qual && !*action && is_instead)
- elog(WARN,
- "event_quals on 'instead nothing' rules not currently supported");
-
-#if 0
- /* on retrieve to class.attribute do instead nothing is converted
- * to 'on retrieve to class.attribute do instead
- * retrieve (attribute = NULL)'
- * --- this is also a terrible hack that works well -- glass*/
- if (is_instead && !*action && eslot_string && event_type == CMD_SELECT) {
- char *temp_buffer = (char *) palloc(strlen(template)+80);
- sprintf(temp_buffer, template, event_attype,
- get_typlen(event_attype), eslot_string,
- event_attype);
-
- *action = (List*) stringToNode(temp_buffer);
-
- pfree(temp_buffer);
- }
-#endif
+ if (((event_type == CMD_INSERT) || (event_type == CMD_DELETE)) &&
+ eslot_string)
+ {
+ elog(WARN,
+ "rules not allowed for insert or delete events to an attribute");
+ }
+
+ if (event_qual && !*action && is_instead)
+ elog(WARN,
+ "event_quals on 'instead nothing' rules not currently supported");
+
+#if 0
+
+ /*
+ * on retrieve to class.attribute do instead nothing is converted to
+ * 'on retrieve to class.attribute do instead retrieve (attribute =
+ * NULL)' --- this is also a terrible hack that works well -- glass
+ */
+ if (is_instead && !*action && eslot_string && event_type == CMD_SELECT)
+ {
+ char *temp_buffer = (char *) palloc(strlen(template) + 80);
+
+ sprintf(temp_buffer, template, event_attype,
+ get_typlen(event_attype), eslot_string,
+ event_attype);
+
+ *action = (List *) stringToNode(temp_buffer);
+
+ pfree(temp_buffer);
+ }
+#endif
}
void
-DefineQueryRewrite(RuleStmt *stmt)
+DefineQueryRewrite(RuleStmt * stmt)
{
- CmdType event_type = stmt->event;
- Attr *event_obj = stmt->object;
- Node *event_qual = stmt->whereClause;
- bool is_instead = stmt->instead;
- List *action = stmt->actions;
- Relation event_relation = NULL ;
- Oid ruleId;
- Oid ev_relid = 0;
- char *eslot_string = NULL;
- int event_attno = 0;
- Oid event_attype = 0;
- char *actionP, *event_qualP;
-
- if (event_obj->attrs)
- eslot_string = strVal(lfirst(event_obj->attrs));
- else
- eslot_string = NULL;
-
- event_relation = heap_openr(event_obj->relname);
- if ( event_relation == NULL ) {
- elog(WARN, "virtual relations not supported yet");
- }
- ev_relid = RelationGetRelationId(event_relation);
-
- if (eslot_string == NULL) {
- event_attno = -1;
- event_attype = -1; /* XXX - don't care */
- } else {
- event_attno = varattno(event_relation, eslot_string);
- event_attype = att_typeid(event_relation,event_attno);
- }
- heap_close(event_relation);
-
- /* fix bug about instead nothing */
- ValidateRule(event_type, event_obj->relname,
- eslot_string, event_qual, &action,
- is_instead,event_attype);
-
- if (action == NULL) {
- if (!is_instead) return; /* doesn't do anything */
-
- event_qualP = nodeToString(event_qual);
-
- ruleId = InsertRule(stmt->rulename,
- event_type,
- event_obj->relname,
- eslot_string,
- event_qualP,
- true,
- "nil");
- prs2_addToRelation(ev_relid, ruleId, event_type, event_attno, TRUE,
- event_qual, NIL);
-
- } else {
- event_qualP = nodeToString(event_qual);
- actionP = nodeToString(action);
-
- ruleId = InsertRule(stmt->rulename,
- event_type,
- event_obj->relname,
- eslot_string,
- event_qualP,
- is_instead,
- actionP);
-
- /* what is the max size of type text? XXX -- glass */
- if (length(action) > 15 )
- elog(WARN,"max # of actions exceeded");
- prs2_addToRelation(ev_relid, ruleId, event_type, event_attno,
- is_instead, event_qual, action);
- }
-}
+ CmdType event_type = stmt->event;
+ Attr *event_obj = stmt->object;
+ Node *event_qual = stmt->whereClause;
+ bool is_instead = stmt->instead;
+ List *action = stmt->actions;
+ Relation event_relation = NULL;
+ Oid ruleId;
+ Oid ev_relid = 0;
+ char *eslot_string = NULL;
+ int event_attno = 0;
+ Oid event_attype = 0;
+ char *actionP,
+ *event_qualP;
+
+ if (event_obj->attrs)
+ eslot_string = strVal(lfirst(event_obj->attrs));
+ else
+ eslot_string = NULL;
+
+ event_relation = heap_openr(event_obj->relname);
+ if (event_relation == NULL)
+ {
+ elog(WARN, "virtual relations not supported yet");
+ }
+ ev_relid = RelationGetRelationId(event_relation);
+
+ if (eslot_string == NULL)
+ {
+ event_attno = -1;
+ event_attype = -1; /* XXX - don't care */
+ }
+ else
+ {
+ event_attno = varattno(event_relation, eslot_string);
+ event_attype = att_typeid(event_relation, event_attno);
+ }
+ heap_close(event_relation);
+ /* fix bug about instead nothing */
+ ValidateRule(event_type, event_obj->relname,
+ eslot_string, event_qual, &action,
+ is_instead, event_attype);
+
+ if (action == NULL)
+ {
+ if (!is_instead)
+ return; /* doesn't do anything */
+
+ event_qualP = nodeToString(event_qual);
+
+ ruleId = InsertRule(stmt->rulename,
+ event_type,
+ event_obj->relname,
+ eslot_string,
+ event_qualP,
+ true,
+ "nil");
+ prs2_addToRelation(ev_relid, ruleId, event_type, event_attno, TRUE,
+ event_qual, NIL);
+
+ }
+ else
+ {
+ event_qualP = nodeToString(event_qual);
+ actionP = nodeToString(action);
+
+ ruleId = InsertRule(stmt->rulename,
+ event_type,
+ event_obj->relname,
+ eslot_string,
+ event_qualP,
+ is_instead,
+ actionP);
+
+ /* what is the max size of type text? XXX -- glass */
+ if (length(action) > 15)
+ elog(WARN, "max # of actions exceeded");
+ prs2_addToRelation(ev_relid, ruleId, event_type, event_attno,
+ is_instead, event_qual, action);
+ }
+}
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 093451655d0..980956a4807 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.3 1997/08/12 22:53:41 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.4 1997/09/07 04:48:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,13 +15,13 @@
#include "utils/palloc.h"
#include "utils/elog.h"
#include "utils/rel.h"
-#include "nodes/pg_list.h"
+#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
-#include "parser/parsetree.h" /* for parsetree manipulation */
+#include "parser/parsetree.h" /* for parsetree manipulation */
#include "nodes/parsenodes.h"
-#include "rewrite/rewriteSupport.h"
+#include "rewrite/rewriteSupport.h"
#include "rewrite/rewriteHandler.h"
#include "rewrite/rewriteManip.h"
#include "rewrite/locks.h"
@@ -29,529 +29,580 @@
#include "commands/creatinh.h"
#include "access/heapam.h"
-static void ApplyRetrieveRule(Query *parsetree, RewriteRule *rule,
- int rt_index, int relation_level, int *modified);
-static List *fireRules(Query *parsetree, int rt_index, CmdType event,
- bool *instead_flag, List *locks, List **qual_products);
-static List *deepRewriteQuery(Query *parsetree);
+static void
+ApplyRetrieveRule(Query * parsetree, RewriteRule * rule,
+ int rt_index, int relation_level, int *modified);
+static List *
+fireRules(Query * parsetree, int rt_index, CmdType event,
+ bool * instead_flag, List * locks, List ** qual_products);
+static List *deepRewriteQuery(Query * parsetree);
/*
* gatherRewriteMeta -
- * Gather meta information about parsetree, and rule. Fix rule body
- * and qualifier so that they can be mixed with the parsetree and
- * maintain semantic validity
+ * Gather meta information about parsetree, and rule. Fix rule body
+ * and qualifier so that they can be mixed with the parsetree and
+ * maintain semantic validity
*/
static RewriteInfo *
-gatherRewriteMeta(Query *parsetree,
- Query *rule_action,
- Node *rule_qual,
- int rt_index,
- CmdType event,
- bool *instead_flag)
+gatherRewriteMeta(Query * parsetree,
+ Query * rule_action,
+ Node * rule_qual,
+ int rt_index,
+ CmdType event,
+ bool * instead_flag)
{
- RewriteInfo *info;
- int rt_length;
- int result_reln;
-
- info = (RewriteInfo *) palloc(sizeof(RewriteInfo));
- info->rt_index = rt_index;
- info->event = event;
- info->instead_flag = *instead_flag;
- info->rule_action = (Query*)copyObject(rule_action);
- info->rule_qual = (Node*)copyObject(rule_qual);
- if (info->rule_action == NULL) info->nothing = TRUE;
- else {
- info->nothing = FALSE;
- info->action = info->rule_action->commandType;
- info->current_varno = rt_index;
- info->rt = parsetree->rtable;
- rt_length = length(info->rt);
- info->rt = append(info->rt, info->rule_action->rtable);
-
- info->new_varno = PRS2_NEW_VARNO + rt_length;
- OffsetVarNodes(info->rule_action->qual, rt_length);
- OffsetVarNodes((Node*)info->rule_action->targetList, rt_length);
- OffsetVarNodes(info->rule_qual, rt_length);
- ChangeVarNodes((Node*)info->rule_action->qual,
- PRS2_CURRENT_VARNO+rt_length, rt_index);
- ChangeVarNodes((Node*)info->rule_action->targetList,
- PRS2_CURRENT_VARNO+rt_length, rt_index);
- ChangeVarNodes(info->rule_qual,
- PRS2_CURRENT_VARNO+rt_length, rt_index);
-
- /*
- * bug here about replace CURRENT -- sort of
- * replace current is deprecated now so this code shouldn't really
- * need to be so clutzy but.....
- */
- if (info->action != CMD_SELECT) { /* i.e update XXXXX */
- int new_result_reln = 0;
- result_reln = info->rule_action->resultRelation;
- switch (result_reln) {
- case PRS2_CURRENT_VARNO: new_result_reln = rt_index;
- break;
- case PRS2_NEW_VARNO: /* XXX */
- default:
- new_result_reln = result_reln + rt_length;
- break;
- }
- info->rule_action->resultRelation = new_result_reln;
- }
- }
- return info;
+ RewriteInfo *info;
+ int rt_length;
+ int result_reln;
+
+ info = (RewriteInfo *) palloc(sizeof(RewriteInfo));
+ info->rt_index = rt_index;
+ info->event = event;
+ info->instead_flag = *instead_flag;
+ info->rule_action = (Query *) copyObject(rule_action);
+ info->rule_qual = (Node *) copyObject(rule_qual);
+ if (info->rule_action == NULL)
+ info->nothing = TRUE;
+ else
+ {
+ info->nothing = FALSE;
+ info->action = info->rule_action->commandType;
+ info->current_varno = rt_index;
+ info->rt = parsetree->rtable;
+ rt_length = length(info->rt);
+ info->rt = append(info->rt, info->rule_action->rtable);
+
+ info->new_varno = PRS2_NEW_VARNO + rt_length;
+ OffsetVarNodes(info->rule_action->qual, rt_length);
+ OffsetVarNodes((Node *) info->rule_action->targetList, rt_length);
+ OffsetVarNodes(info->rule_qual, rt_length);
+ ChangeVarNodes((Node *) info->rule_action->qual,
+ PRS2_CURRENT_VARNO + rt_length, rt_index);
+ ChangeVarNodes((Node *) info->rule_action->targetList,
+ PRS2_CURRENT_VARNO + rt_length, rt_index);
+ ChangeVarNodes(info->rule_qual,
+ PRS2_CURRENT_VARNO + rt_length, rt_index);
+
+ /*
+ * bug here about replace CURRENT -- sort of replace current is
+ * deprecated now so this code shouldn't really need to be so
+ * clutzy but.....
+ */
+ if (info->action != CMD_SELECT)
+ { /* i.e update XXXXX */
+ int new_result_reln = 0;
+
+ result_reln = info->rule_action->resultRelation;
+ switch (result_reln)
+ {
+ case PRS2_CURRENT_VARNO:
+ new_result_reln = rt_index;
+ break;
+ case PRS2_NEW_VARNO: /* XXX */
+ default:
+ new_result_reln = result_reln + rt_length;
+ break;
+ }
+ info->rule_action->resultRelation = new_result_reln;
+ }
+ }
+ return info;
}
-static List *
-OptimizeRIRRules(List *locks)
+static List *
+OptimizeRIRRules(List * locks)
{
- List *attr_level = NIL, *i;
- List *relation_level = NIL;
-
- foreach (i, locks) {
- RewriteRule *rule_lock = lfirst(i);
-
- if (rule_lock->attrno == -1)
- relation_level = lappend(relation_level, rule_lock);
- else
- attr_level = lappend(attr_level, rule_lock);
- }
- return nconc(relation_level, attr_level);
+ List *attr_level = NIL,
+ *i;
+ List *relation_level = NIL;
+
+ foreach(i, locks)
+ {
+ RewriteRule *rule_lock = lfirst(i);
+
+ if (rule_lock->attrno == -1)
+ relation_level = lappend(relation_level, rule_lock);
+ else
+ attr_level = lappend(attr_level, rule_lock);
+ }
+ return nconc(relation_level, attr_level);
}
/*
* idea is to put instead rules before regular rules so that
* excess semantically queasy queries aren't processed
*/
-static List *
-orderRules(List *locks)
+static List *
+orderRules(List * locks)
{
- List *regular = NIL, *i;
- List *instead_rules = NIL;
-
- foreach (i, locks) {
- RewriteRule *rule_lock = (RewriteRule *)lfirst(i);
-
- if (rule_lock->isInstead)
- instead_rules = lappend(instead_rules, rule_lock);
- else
- regular = lappend(regular, rule_lock);
- }
- return nconc(regular, instead_rules);
+ List *regular = NIL,
+ *i;
+ List *instead_rules = NIL;
+
+ foreach(i, locks)
+ {
+ RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
+
+ if (rule_lock->isInstead)
+ instead_rules = lappend(instead_rules, rule_lock);
+ else
+ regular = lappend(regular, rule_lock);
+ }
+ return nconc(regular, instead_rules);
}
static int
-AllRetrieve(List *actions)
+AllRetrieve(List * actions)
{
- List *n;
-
- foreach(n, actions) {
- Query *pt = lfirst(n);
-
- /*
- * in the old postgres code, we check whether command_type is
- * a consp of '('*'.commandType). but we've never supported transitive
- * closures. Hence removed - ay 10/94.
- */
- if (pt->commandType != CMD_SELECT)
- return false;
- }
- return true;
+ List *n;
+
+ foreach(n, actions)
+ {
+ Query *pt = lfirst(n);
+
+ /*
+ * in the old postgres code, we check whether command_type is a
+ * consp of '('*'.commandType). but we've never supported
+ * transitive closures. Hence removed - ay 10/94.
+ */
+ if (pt->commandType != CMD_SELECT)
+ return false;
+ }
+ return true;
}
-static List *
-FireRetrieveRulesAtQuery(Query *parsetree,
- int rt_index,
- Relation relation,
- bool *instead_flag,
- int rule_flag)
+static List *
+FireRetrieveRulesAtQuery(Query * parsetree,
+ int rt_index,
+ Relation relation,
+ bool * instead_flag,
+ int rule_flag)
{
- List *i, *locks;
- RuleLock *rt_entry_locks = NULL;
- List *work = NIL;
+ List *i,
+ *locks;
+ RuleLock *rt_entry_locks = NULL;
+ List *work = NIL;
- if ((rt_entry_locks = relation->rd_rules) == NULL)
- return NIL;
-
- locks = matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
-
- /* find all retrieve instead */
- foreach (i, locks) {
- RewriteRule *rule_lock = (RewriteRule *)lfirst(i);
-
- if (!rule_lock->isInstead)
- continue;
- work = lappend(work, rule_lock);
- }
- if (work != NIL) {
- work = OptimizeRIRRules(locks);
- foreach (i, work) {
- RewriteRule *rule_lock = lfirst(i);
- int relation_level;
- int modified = FALSE;
-
- relation_level = (rule_lock->attrno == -1);
- if (rule_lock->actions == NIL) {
- *instead_flag = TRUE;
+ if ((rt_entry_locks = relation->rd_rules) == NULL)
return NIL;
- }
- if (!rule_flag &&
- length(rule_lock->actions) >= 2 &&
- AllRetrieve(rule_lock->actions)) {
- *instead_flag = TRUE;
- return rule_lock->actions;
- }
- ApplyRetrieveRule(parsetree, rule_lock, rt_index, relation_level,
- &modified);
- if (modified) {
- *instead_flag = TRUE;
- FixResdomTypes(parsetree->targetList);
- return lcons(parsetree,NIL);
- }
+
+ locks = matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
+
+ /* find all retrieve instead */
+ foreach(i, locks)
+ {
+ RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
+
+ if (!rule_lock->isInstead)
+ continue;
+ work = lappend(work, rule_lock);
+ }
+ if (work != NIL)
+ {
+ work = OptimizeRIRRules(locks);
+ foreach(i, work)
+ {
+ RewriteRule *rule_lock = lfirst(i);
+ int relation_level;
+ int modified = FALSE;
+
+ relation_level = (rule_lock->attrno == -1);
+ if (rule_lock->actions == NIL)
+ {
+ *instead_flag = TRUE;
+ return NIL;
+ }
+ if (!rule_flag &&
+ length(rule_lock->actions) >= 2 &&
+ AllRetrieve(rule_lock->actions))
+ {
+ *instead_flag = TRUE;
+ return rule_lock->actions;
+ }
+ ApplyRetrieveRule(parsetree, rule_lock, rt_index, relation_level,
+ &modified);
+ if (modified)
+ {
+ *instead_flag = TRUE;
+ FixResdomTypes(parsetree->targetList);
+ return lcons(parsetree, NIL);
+ }
+ }
}
- }
- return NIL;
-}
+ return NIL;
+}
/* Idea is like this:
*
* retrieve-instead-retrieve rules have different semantics than update nodes
- * Separate RIR rules from others. Pass others to FireRules.
+ * Separate RIR rules from others. Pass others to FireRules.
* Order RIR rules and process.
*
* side effect: parsetree's rtable field might be changed
*/
static void
-ApplyRetrieveRule(Query *parsetree,
- RewriteRule *rule,
- int rt_index,
- int relation_level,
- int *modified)
+ApplyRetrieveRule(Query * parsetree,
+ RewriteRule * rule,
+ int rt_index,
+ int relation_level,
+ int *modified)
{
- Query *rule_action = NULL;
- Node *rule_qual;
- List *rtable, *rt;
- int nothing, rt_length;
- int badsql= FALSE;
-
- rule_qual = rule->qual;
- if (rule->actions) {
- if (length(rule->actions) > 1) /* ??? because we don't handle rules
- with more than one action? -ay */
- return;
- rule_action = copyObject(lfirst(rule->actions));
- nothing = FALSE;
- } else {
- nothing = TRUE;
- }
-
- rtable = copyObject(parsetree->rtable);
- foreach (rt, rtable) {
- RangeTblEntry *rte = lfirst(rt);
- /*
- * this is to prevent add_missing_vars_to_base_rels() from
- * adding a bogus entry to the new target list.
- */
- rte->inFromCl = false;
- }
- rt_length = length(rtable);
- rtable = nconc(rtable, copyObject(rule_action->rtable));
- parsetree->rtable = rtable;
-
- rule_action->rtable = rtable;
- OffsetVarNodes(rule_action->qual, rt_length);
- OffsetVarNodes((Node*)rule_action->targetList, rt_length);
- OffsetVarNodes(rule_qual, rt_length);
- ChangeVarNodes(rule_action->qual,
- PRS2_CURRENT_VARNO+rt_length, rt_index);
- ChangeVarNodes((Node*)rule_action->targetList,
- PRS2_CURRENT_VARNO+rt_length, rt_index);
- ChangeVarNodes(rule_qual, PRS2_CURRENT_VARNO+rt_length, rt_index);
- if (relation_level) {
- HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index,
- modified);
- } else {
- HandleRIRAttributeRule(parsetree, rtable, rule_action->targetList,
- rt_index, rule->attrno, modified, &badsql);
- }
- if (*modified && !badsql)
- AddQual(parsetree, rule_action->qual);
+ Query *rule_action = NULL;
+ Node *rule_qual;
+ List *rtable,
+ *rt;
+ int nothing,
+ rt_length;
+ int badsql = FALSE;
+
+ rule_qual = rule->qual;
+ if (rule->actions)
+ {
+ if (length(rule->actions) > 1) /* ??? because we don't handle
+ * rules with more than one
+ * action? -ay */
+ return;
+ rule_action = copyObject(lfirst(rule->actions));
+ nothing = FALSE;
+ }
+ else
+ {
+ nothing = TRUE;
+ }
+
+ rtable = copyObject(parsetree->rtable);
+ foreach(rt, rtable)
+ {
+ RangeTblEntry *rte = lfirst(rt);
+
+ /*
+ * this is to prevent add_missing_vars_to_base_rels() from adding
+ * a bogus entry to the new target list.
+ */
+ rte->inFromCl = false;
+ }
+ rt_length = length(rtable);
+ rtable = nconc(rtable, copyObject(rule_action->rtable));
+ parsetree->rtable = rtable;
+
+ rule_action->rtable = rtable;
+ OffsetVarNodes(rule_action->qual, rt_length);
+ OffsetVarNodes((Node *) rule_action->targetList, rt_length);
+ OffsetVarNodes(rule_qual, rt_length);
+ ChangeVarNodes(rule_action->qual,
+ PRS2_CURRENT_VARNO + rt_length, rt_index);
+ ChangeVarNodes((Node *) rule_action->targetList,
+ PRS2_CURRENT_VARNO + rt_length, rt_index);
+ ChangeVarNodes(rule_qual, PRS2_CURRENT_VARNO + rt_length, rt_index);
+ if (relation_level)
+ {
+ HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index,
+ modified);
+ }
+ else
+ {
+ HandleRIRAttributeRule(parsetree, rtable, rule_action->targetList,
+ rt_index, rule->attrno, modified, &badsql);
+ }
+ if (*modified && !badsql)
+ AddQual(parsetree, rule_action->qual);
}
-static List *
-ProcessRetrieveQuery(Query *parsetree,
- List *rtable,
- bool *instead_flag,
- bool rule)
+static List *
+ProcessRetrieveQuery(Query * parsetree,
+ List * rtable,
+ bool * instead_flag,
+ bool rule)
{
- List *rt;
- List *product_queries = NIL;
- int rt_index = 0;
-
- foreach (rt, rtable) {
- RangeTblEntry *rt_entry = lfirst(rt);
- Relation rt_entry_relation = NULL;
- List *result = NIL;
-
- rt_index++;
- rt_entry_relation = heap_openr(rt_entry->relname);
-
- if (rt_entry_relation->rd_rules != NULL) {
- result =
- FireRetrieveRulesAtQuery(parsetree,
- rt_index,
- rt_entry_relation,
- instead_flag,
- rule);
+ List *rt;
+ List *product_queries = NIL;
+ int rt_index = 0;
+
+ foreach(rt, rtable)
+ {
+ RangeTblEntry *rt_entry = lfirst(rt);
+ Relation rt_entry_relation = NULL;
+ List *result = NIL;
+
+ rt_index++;
+ rt_entry_relation = heap_openr(rt_entry->relname);
+
+ if (rt_entry_relation->rd_rules != NULL)
+ {
+ result =
+ FireRetrieveRulesAtQuery(parsetree,
+ rt_index,
+ rt_entry_relation,
+ instead_flag,
+ rule);
+ }
+ heap_close(rt_entry_relation);
+ if (*instead_flag)
+ return result;
}
- heap_close(rt_entry_relation);
- if (*instead_flag)
- return result;
- }
- if (rule)
- return NIL;
+ if (rule)
+ return NIL;
- foreach (rt, rtable) {
- RangeTblEntry *rt_entry = lfirst(rt);
- Relation rt_entry_relation = NULL;
- RuleLock *rt_entry_locks = NULL;
- List *result = NIL;
- List *locks = NIL;
- List *dummy_products;
-
- rt_index++;
- rt_entry_relation = heap_openr(rt_entry->relname);
- rt_entry_locks = rt_entry_relation->rd_rules;
- heap_close(rt_entry_relation);
-
- if (rt_entry_locks) {
- locks =
- matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
+ foreach(rt, rtable)
+ {
+ RangeTblEntry *rt_entry = lfirst(rt);
+ Relation rt_entry_relation = NULL;
+ RuleLock *rt_entry_locks = NULL;
+ List *result = NIL;
+ List *locks = NIL;
+ List *dummy_products;
+
+ rt_index++;
+ rt_entry_relation = heap_openr(rt_entry->relname);
+ rt_entry_locks = rt_entry_relation->rd_rules;
+ heap_close(rt_entry_relation);
+
+ if (rt_entry_locks)
+ {
+ locks =
+ matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
+ }
+ if (locks != NIL)
+ {
+ result = fireRules(parsetree, rt_index, CMD_SELECT,
+ instead_flag, locks, &dummy_products);
+ if (*instead_flag)
+ return lappend(NIL, result);
+ if (result != NIL)
+ product_queries = nconc(product_queries, result);
+ }
}
- if (locks != NIL) {
- result = fireRules(parsetree, rt_index, CMD_SELECT,
- instead_flag, locks, &dummy_products);
- if (*instead_flag)
- return lappend(NIL, result);
- if (result != NIL)
- product_queries = nconc(product_queries, result);
- }
- }
- return product_queries;
+ return product_queries;
}
-static Query *
-CopyAndAddQual(Query *parsetree,
- List *actions,
- Node *rule_qual,
- int rt_index,
- CmdType event)
+static Query *
+CopyAndAddQual(Query * parsetree,
+ List * actions,
+ Node * rule_qual,
+ int rt_index,
+ CmdType event)
{
- Query *new_tree = (Query *) copyObject(parsetree);
- Node *new_qual = NULL;
- Query *rule_action = NULL;
-
- if (actions)
- rule_action = lfirst(actions);
- if (rule_qual != NULL)
- new_qual = (Node *)copyObject(rule_qual);
- if (rule_action != NULL) {
- List *rtable;
- int rt_length;
-
- rtable = new_tree->rtable;
- rt_length = length(rtable);
- rtable = append(rtable,listCopy(rule_action->rtable));
- new_tree->rtable = rtable;
- OffsetVarNodes(new_qual, rt_length);
- ChangeVarNodes(new_qual, PRS2_CURRENT_VARNO+rt_length, rt_index);
- }
- /* XXX -- where current doesn't work for instead nothing.... yet*/
- AddNotQual(new_tree, new_qual);
-
- return new_tree;
+ Query *new_tree = (Query *) copyObject(parsetree);
+ Node *new_qual = NULL;
+ Query *rule_action = NULL;
+
+ if (actions)
+ rule_action = lfirst(actions);
+ if (rule_qual != NULL)
+ new_qual = (Node *) copyObject(rule_qual);
+ if (rule_action != NULL)
+ {
+ List *rtable;
+ int rt_length;
+
+ rtable = new_tree->rtable;
+ rt_length = length(rtable);
+ rtable = append(rtable, listCopy(rule_action->rtable));
+ new_tree->rtable = rtable;
+ OffsetVarNodes(new_qual, rt_length);
+ ChangeVarNodes(new_qual, PRS2_CURRENT_VARNO + rt_length, rt_index);
+ }
+ /* XXX -- where current doesn't work for instead nothing.... yet */
+ AddNotQual(new_tree, new_qual);
+
+ return new_tree;
}
/*
- * fireRules -
- * Iterate through rule locks applying rules. After an instead rule
- * rule has been applied, return just new parsetree and let RewriteQuery
- * start the process all over again. The locks are reordered to maintain
- * sensible semantics. remember: reality is for dead birds -- glass
+ * fireRules -
+ * Iterate through rule locks applying rules. After an instead rule
+ * rule has been applied, return just new parsetree and let RewriteQuery
+ * start the process all over again. The locks are reordered to maintain
+ * sensible semantics. remember: reality is for dead birds -- glass
*
*/
-static List *
-fireRules(Query *parsetree,
- int rt_index,
- CmdType event,
- bool *instead_flag,
- List *locks,
- List **qual_products)
+static List *
+fireRules(Query * parsetree,
+ int rt_index,
+ CmdType event,
+ bool * instead_flag,
+ List * locks,
+ List ** qual_products)
{
- RewriteInfo *info;
- List *results = NIL;
- List *i;
-
- /* choose rule to fire from list of rules */
- if (locks == NIL) {
- ProcessRetrieveQuery(parsetree,
- parsetree->rtable,
- instead_flag, TRUE);
- if (*instead_flag)
- return lappend(NIL, parsetree);
- else
- return NIL;
- }
-
- locks = orderRules(locks); /* instead rules first */
- foreach (i, locks) {
- RewriteRule *rule_lock = (RewriteRule *)lfirst(i);
- Node *qual, *event_qual;
- List *actions;
- List *r;
- bool orig_instead_flag = *instead_flag;
-
- /* multiple rule action time */
- *instead_flag = rule_lock->isInstead;
- event_qual = rule_lock->qual;
- actions = rule_lock->actions;
- if (event_qual != NULL && *instead_flag)
- *qual_products =
- lappend(*qual_products,
- CopyAndAddQual(parsetree, actions, event_qual,
- rt_index, event));
- foreach (r, actions) {
- Query *rule_action = lfirst(r);
- Node *rule_qual = copyObject(event_qual);
-
- /*--------------------------------------------------
- * Step 1:
- * Rewrite current.attribute or current to tuple variable
- * this appears to be done in parser?
- *--------------------------------------------------
- */
- info = gatherRewriteMeta(parsetree, rule_action, rule_qual,
- rt_index,event,instead_flag);
-
- /* handle escapable cases, or those handled by other code */
- if (info->nothing) {
+ RewriteInfo *info;
+ List *results = NIL;
+ List *i;
+
+ /* choose rule to fire from list of rules */
+ if (locks == NIL)
+ {
+ ProcessRetrieveQuery(parsetree,
+ parsetree->rtable,
+ instead_flag, TRUE);
if (*instead_flag)
- return NIL;
+ return lappend(NIL, parsetree);
else
- continue;
- }
-
- if (info->action == info->event &&
- info->event == CMD_SELECT)
- continue;
-
- /*
- * Event Qualification forces copying of parsetree --- XXX
- * and splitting into two queries one w/rule_qual, one
- * w/NOT rule_qual. Also add user query qual onto rule action
- */
- qual = parsetree->qual;
- AddQual(info->rule_action, qual);
-
- if (info->rule_qual != NULL)
- AddQual(info->rule_action, info->rule_qual);
-
- /*--------------------------------------------------
- * Step 2:
- * Rewrite new.attribute w/ right hand side of target-list
- * entry for appropriate field name in insert/update
- *--------------------------------------------------
- */
- if ((info->event == CMD_INSERT) || (info->event == CMD_UPDATE)) {
- FixNew(info, parsetree);
- }
-
- /*--------------------------------------------------
- * Step 3:
- * rewriting due to retrieve rules
- *--------------------------------------------------
- */
- info->rule_action->rtable = info->rt;
- ProcessRetrieveQuery(info->rule_action, info->rt,
- &orig_instead_flag, TRUE);
-
- /*--------------------------------------------------
- * Step 4
- * Simplify? hey, no algorithm for simplification... let
- * the planner do it.
- *--------------------------------------------------
- */
- results = lappend(results, info->rule_action);
-
- pfree(info);
+ return NIL;
}
- if (*instead_flag) break;
- }
- return results;
+
+ locks = orderRules(locks); /* instead rules first */
+ foreach(i, locks)
+ {
+ RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
+ Node *qual,
+ *event_qual;
+ List *actions;
+ List *r;
+ bool orig_instead_flag = *instead_flag;
+
+ /* multiple rule action time */
+ *instead_flag = rule_lock->isInstead;
+ event_qual = rule_lock->qual;
+ actions = rule_lock->actions;
+ if (event_qual != NULL && *instead_flag)
+ *qual_products =
+ lappend(*qual_products,
+ CopyAndAddQual(parsetree, actions, event_qual,
+ rt_index, event));
+ foreach(r, actions)
+ {
+ Query *rule_action = lfirst(r);
+ Node *rule_qual = copyObject(event_qual);
+
+ /*--------------------------------------------------
+ * Step 1:
+ * Rewrite current.attribute or current to tuple variable
+ * this appears to be done in parser?
+ *--------------------------------------------------
+ */
+ info = gatherRewriteMeta(parsetree, rule_action, rule_qual,
+ rt_index, event, instead_flag);
+
+ /* handle escapable cases, or those handled by other code */
+ if (info->nothing)
+ {
+ if (*instead_flag)
+ return NIL;
+ else
+ continue;
+ }
+
+ if (info->action == info->event &&
+ info->event == CMD_SELECT)
+ continue;
+
+ /*
+ * Event Qualification forces copying of parsetree --- XXX and
+ * splitting into two queries one w/rule_qual, one w/NOT
+ * rule_qual. Also add user query qual onto rule action
+ */
+ qual = parsetree->qual;
+ AddQual(info->rule_action, qual);
+
+ if (info->rule_qual != NULL)
+ AddQual(info->rule_action, info->rule_qual);
+
+ /*--------------------------------------------------
+ * Step 2:
+ * Rewrite new.attribute w/ right hand side of target-list
+ * entry for appropriate field name in insert/update
+ *--------------------------------------------------
+ */
+ if ((info->event == CMD_INSERT) || (info->event == CMD_UPDATE))
+ {
+ FixNew(info, parsetree);
+ }
+
+ /*--------------------------------------------------
+ * Step 3:
+ * rewriting due to retrieve rules
+ *--------------------------------------------------
+ */
+ info->rule_action->rtable = info->rt;
+ ProcessRetrieveQuery(info->rule_action, info->rt,
+ &orig_instead_flag, TRUE);
+
+ /*--------------------------------------------------
+ * Step 4
+ * Simplify? hey, no algorithm for simplification... let
+ * the planner do it.
+ *--------------------------------------------------
+ */
+ results = lappend(results, info->rule_action);
+
+ pfree(info);
+ }
+ if (*instead_flag)
+ break;
+ }
+ return results;
}
-static List *
-RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products)
+static List *
+RewriteQuery(Query * parsetree, bool * instead_flag, List ** qual_products)
{
- CmdType event;
- List *product_queries = NIL;
- int result_relation = 0;
-
- Assert(parsetree != NULL);
-
- event = parsetree->commandType;
-
- if (event == CMD_UTILITY)
- return NIL;
+ CmdType event;
+ List *product_queries = NIL;
+ int result_relation = 0;
- /*
- * only for a delete may the targetlist be NULL
- */
- if (event != CMD_DELETE) {
- Assert(parsetree->targetList != NULL);
- }
-
- result_relation = parsetree->resultRelation;
+ Assert(parsetree != NULL);
+
+ event = parsetree->commandType;
+
+ if (event == CMD_UTILITY)
+ return NIL;
- if (event != CMD_SELECT) {
/*
- * the statement is an update, insert or delete
+ * only for a delete may the targetlist be NULL
*/
- RangeTblEntry *rt_entry;
- Relation rt_entry_relation = NULL;
- RuleLock *rt_entry_locks = NULL;
-
- rt_entry = rt_fetch(result_relation, parsetree->rtable);
- rt_entry_relation = heap_openr(rt_entry->relname);
- rt_entry_locks = rt_entry_relation->rd_rules;
- heap_close(rt_entry_relation);
-
- if (rt_entry_locks != NULL) {
- List *locks =
- matchLocks(event, rt_entry_locks, result_relation, parsetree);
-
- product_queries =
- fireRules(parsetree,
- result_relation,
- event,
- instead_flag,
- locks,
- qual_products);
+ if (event != CMD_DELETE)
+ {
+ Assert(parsetree->targetList != NULL);
+ }
+
+ result_relation = parsetree->resultRelation;
+
+ if (event != CMD_SELECT)
+ {
+
+ /*
+ * the statement is an update, insert or delete
+ */
+ RangeTblEntry *rt_entry;
+ Relation rt_entry_relation = NULL;
+ RuleLock *rt_entry_locks = NULL;
+
+ rt_entry = rt_fetch(result_relation, parsetree->rtable);
+ rt_entry_relation = heap_openr(rt_entry->relname);
+ rt_entry_locks = rt_entry_relation->rd_rules;
+ heap_close(rt_entry_relation);
+
+ if (rt_entry_locks != NULL)
+ {
+ List *locks =
+ matchLocks(event, rt_entry_locks, result_relation, parsetree);
+
+ product_queries =
+ fireRules(parsetree,
+ result_relation,
+ event,
+ instead_flag,
+ locks,
+ qual_products);
+ }
+ return product_queries;
+ }
+ else
+ {
+
+ /*
+ * the statement is a select
+ */
+ Query *other;
+
+ other = copyObject(parsetree); /* ApplyRetrieveRule changes the
+ * range table */
+ return
+ ProcessRetrieveQuery(other, parsetree->rtable,
+ instead_flag, FALSE);
}
- return product_queries;
- }else {
- /*
- * the statement is a select
- */
- Query *other;
-
- other = copyObject(parsetree); /* ApplyRetrieveRule changes the
- range table */
- return
- ProcessRetrieveQuery(other, parsetree->rtable,
- instead_flag, FALSE);
- }
}
/*
@@ -559,61 +610,62 @@ RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products)
* can be rewritten. Detecting cycles is left for the reader as an excercise.
*/
#ifndef REWRITE_INVOKE_MAX
-#define REWRITE_INVOKE_MAX 10
+#define REWRITE_INVOKE_MAX 10
#endif
-static int numQueryRewriteInvoked = 0;
+static int numQueryRewriteInvoked = 0;
/*
* QueryRewrite -
- * rewrite one query via QueryRewrite system, possibly returning 0, or many
- * queries
- */
-List *
-QueryRewrite(Query *parsetree)
+ * rewrite one query via QueryRewrite system, possibly returning 0, or many
+ * queries
+ */
+List *
+QueryRewrite(Query * parsetree)
{
- numQueryRewriteInvoked = 0;
+ numQueryRewriteInvoked = 0;
- /*
- * take a deep breath and apply all the rewrite rules - ay
- */
- return deepRewriteQuery(parsetree);
+ /*
+ * take a deep breath and apply all the rewrite rules - ay
+ */
+ return deepRewriteQuery(parsetree);
}
/*
* deepRewriteQuery -
- * rewrites the query and apply the rules again on the queries rewritten
+ * rewrites the query and apply the rules again on the queries rewritten
*/
-static List *
-deepRewriteQuery(Query *parsetree)
+static List *
+deepRewriteQuery(Query * parsetree)
{
- List *n;
- List *rewritten = NIL;
- List *result = NIL;
- bool instead;
- List *qual_products = NIL;
-
- if (++numQueryRewriteInvoked > REWRITE_INVOKE_MAX) {
- elog(WARN, "query rewritten %d times, may contain cycles",
- numQueryRewriteInvoked-1);
- }
-
- instead = FALSE;
- result = RewriteQuery(parsetree, &instead, &qual_products);
- if (!instead)
- rewritten = lcons(parsetree, NIL);
-
- foreach(n, result) {
- Query *pt = lfirst(n);
- List *newstuff = NIL;
-
- newstuff = deepRewriteQuery(pt);
- if (newstuff != NIL)
- rewritten = nconc(rewritten, newstuff);
- }
- if (qual_products != NIL)
- rewritten = nconc(rewritten, qual_products);
-
- return rewritten;
-}
+ List *n;
+ List *rewritten = NIL;
+ List *result = NIL;
+ bool instead;
+ List *qual_products = NIL;
+
+ if (++numQueryRewriteInvoked > REWRITE_INVOKE_MAX)
+ {
+ elog(WARN, "query rewritten %d times, may contain cycles",
+ numQueryRewriteInvoked - 1);
+ }
+
+ instead = FALSE;
+ result = RewriteQuery(parsetree, &instead, &qual_products);
+ if (!instead)
+ rewritten = lcons(parsetree, NIL);
+ foreach(n, result)
+ {
+ Query *pt = lfirst(n);
+ List *newstuff = NIL;
+
+ newstuff = deepRewriteQuery(pt);
+ if (newstuff != NIL)
+ rewritten = nconc(rewritten, newstuff);
+ }
+ if (qual_products != NIL)
+ rewritten = nconc(rewritten, qual_products);
+
+ return rewritten;
+}
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index 01fad29f773..b8b39b33281 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.4 1996/11/10 03:02:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.5 1997/09/07 04:48:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,7 @@
#include "nodes/nodes.h"
#include "nodes/relation.h"
#include "nodes/primnodes.h"
-#include "parser/parsetree.h" /* for getrelid() */
+#include "parser/parsetree.h" /* for getrelid() */
#include "utils/lsyscache.h"
#include "utils/builtins.h"
#include "rewrite/rewriteHandler.h"
@@ -28,410 +28,463 @@
#include "nodes/plannodes.h"
#include "optimizer/clauses.h"
-static void ResolveNew(RewriteInfo *info, List *targetlist, Node **node);
+static void ResolveNew(RewriteInfo * info, List * targetlist, Node ** node);
void
-OffsetVarNodes(Node *node, int offset)
+OffsetVarNodes(Node * node, int offset)
{
- if (node==NULL)
- return;
- switch (nodeTag(node)) {
- case T_TargetEntry:
+ if (node == NULL)
+ return;
+ switch (nodeTag(node))
{
- TargetEntry *tle = (TargetEntry *)node;
- OffsetVarNodes(tle->expr, offset);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr*)node;
- OffsetVarNodes((Node*)expr->args, offset);
- }
- break;
- case T_Var:
- {
- Var *var = (Var*)node;
- var->varno += offset;
- var->varnoold += offset;
- }
- break;
- case T_List:
- {
- List *l;
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ OffsetVarNodes(tle->expr, offset);
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
- foreach(l, (List*)node) {
- OffsetVarNodes(lfirst(l), offset);
- }
+ OffsetVarNodes((Node *) expr->args, offset);
+ }
+ break;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+
+ var->varno += offset;
+ var->varnoold += offset;
+ }
+ break;
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ OffsetVarNodes(lfirst(l), offset);
+ }
+ }
+ break;
+ default:
+ /* ignore the others */
+ break;
}
- break;
- default:
- /* ignore the others */
- break;
- }
}
void
-ChangeVarNodes(Node *node, int old_varno, int new_varno)
+ChangeVarNodes(Node * node, int old_varno, int new_varno)
{
- if (node==NULL)
- return;
- switch (nodeTag(node)) {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
- ChangeVarNodes(tle->expr, old_varno, new_varno);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr*)node;
- ChangeVarNodes((Node*)expr->args, old_varno, new_varno);
- }
- break;
- case T_Var:
+ if (node == NULL)
+ return;
+ switch (nodeTag(node))
{
- Var *var = (Var*)node;
- if (var->varno == old_varno) {
- var->varno = new_varno;
- var->varnoold = new_varno;
- }
- }
- break;
- case T_List:
- {
- List *l;
- foreach (l, (List*)node) {
- ChangeVarNodes(lfirst(l), old_varno, new_varno);
- }
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ ChangeVarNodes(tle->expr, old_varno, new_varno);
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ ChangeVarNodes((Node *) expr->args, old_varno, new_varno);
+ }
+ break;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+
+ if (var->varno == old_varno)
+ {
+ var->varno = new_varno;
+ var->varnoold = new_varno;
+ }
+ }
+ break;
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ ChangeVarNodes(lfirst(l), old_varno, new_varno);
+ }
+ }
+ break;
+ default:
+ /* ignore the others */
+ break;
}
- break;
- default:
- /* ignore the others */
- break;
- }
}
void
-AddQual(Query *parsetree, Node *qual)
+AddQual(Query * parsetree, Node * qual)
{
- Node *copy, *old;
-
- if (qual == NULL)
- return;
-
- copy = copyObject(qual);
- old = parsetree->qual;
- if (old == NULL)
- parsetree->qual = copy;
- else
- parsetree->qual =
- (Node*)make_andclause(makeList(parsetree->qual, copy, -1));
+ Node *copy,
+ *old;
+
+ if (qual == NULL)
+ return;
+
+ copy = copyObject(qual);
+ old = parsetree->qual;
+ if (old == NULL)
+ parsetree->qual = copy;
+ else
+ parsetree->qual =
+ (Node *) make_andclause(makeList(parsetree->qual, copy, -1));
}
void
-AddNotQual(Query *parsetree, Node *qual)
+AddNotQual(Query * parsetree, Node * qual)
{
- Node *copy;
-
- if (qual == NULL) return;
-
- copy = (Node*)make_notclause(copyObject(qual));
+ Node *copy;
- AddQual(parsetree,copy);
+ if (qual == NULL)
+ return;
+
+ copy = (Node *) make_notclause(copyObject(qual));
+
+ AddQual(parsetree, copy);
}
-static Node *
+static Node *
make_null(Oid type)
{
- Const *c = makeNode(Const);
-
- c->consttype = type;
- c->constlen = get_typlen(type);
- c->constvalue = PointerGetDatum(NULL);
- c->constisnull = true;
- c->constbyval = get_typbyval(type);
- return (Node*)c;
+ Const *c = makeNode(Const);
+
+ c->consttype = type;
+ c->constlen = get_typlen(type);
+ c->constvalue = PointerGetDatum(NULL);
+ c->constisnull = true;
+ c->constbyval = get_typbyval(type);
+ return (Node *) c;
}
void
-FixResdomTypes (List *tlist)
+FixResdomTypes(List * tlist)
{
- List *i;
+ List *i;
- foreach (i, tlist) {
- TargetEntry *tle = lfirst(i);
+ foreach(i, tlist)
+ {
+ TargetEntry *tle = lfirst(i);
- if (nodeTag(tle->expr) == T_Var) {
- Var *var = (Var*)tle->expr;
+ if (nodeTag(tle->expr) == T_Var)
+ {
+ Var *var = (Var *) tle->expr;
- tle->resdom->restype = var->vartype;
- tle->resdom->reslen = get_typlen(var->vartype);
+ tle->resdom->restype = var->vartype;
+ tle->resdom->reslen = get_typlen(var->vartype);
+ }
}
- }
}
-static Node *
-FindMatchingNew(List *tlist, int attno)
+static Node *
+FindMatchingNew(List * tlist, int attno)
{
- List *i;
-
- foreach (i, tlist ) {
- TargetEntry *tle = lfirst(i);
+ List *i;
- if (tle->resdom->resno == attno ) {
- return (tle->expr);
+ foreach(i, tlist)
+ {
+ TargetEntry *tle = lfirst(i);
+
+ if (tle->resdom->resno == attno)
+ {
+ return (tle->expr);
+ }
}
- }
- return NULL;
+ return NULL;
}
-static Node *
-FindMatchingTLEntry(List *tlist, char *e_attname)
+static Node *
+FindMatchingTLEntry(List * tlist, char *e_attname)
{
- List *i;
-
- foreach (i, tlist) {
- TargetEntry *tle = lfirst(i);
- char *resname;
-
- resname = tle->resdom->resname;
- if (!strcmp(e_attname, resname))
- return (tle->expr);
- }
- return NULL;
+ List *i;
+
+ foreach(i, tlist)
+ {
+ TargetEntry *tle = lfirst(i);
+ char *resname;
+
+ resname = tle->resdom->resname;
+ if (!strcmp(e_attname, resname))
+ return (tle->expr);
+ }
+ return NULL;
}
static void
-ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr)
+ResolveNew(RewriteInfo * info, List * targetlist, Node ** nodePtr)
{
- Node *node = *nodePtr;
-
- if (node == NULL)
- return;
-
- switch(nodeTag(node)) {
- case T_TargetEntry:
- ResolveNew(info, targetlist, &((TargetEntry*)node)->expr);
- break;
- case T_Expr:
- ResolveNew(info, targetlist, (Node**)(&(((Expr*)node)->args)));
- break;
- case T_Var: {
- int this_varno = (int)((Var*)node)->varno;
- Node *n;
-
- if (this_varno == info->new_varno) {
- n = FindMatchingNew(targetlist,
- ((Var*)node)->varattno);
- if (n == NULL) {
- if (info->event == CMD_UPDATE) {
- ((Var*)node)->varno = info->current_varno;
- ((Var*)node)->varnoold = info->current_varno;
- } else {
- *nodePtr = make_null(((Var*)node)->vartype);
+ Node *node = *nodePtr;
+
+ if (node == NULL)
+ return;
+
+ switch (nodeTag(node))
+ {
+ case T_TargetEntry:
+ ResolveNew(info, targetlist, &((TargetEntry *) node)->expr);
+ break;
+ case T_Expr:
+ ResolveNew(info, targetlist, (Node **) (&(((Expr *) node)->args)));
+ break;
+ case T_Var:
+ {
+ int this_varno = (int) ((Var *) node)->varno;
+ Node *n;
+
+ if (this_varno == info->new_varno)
+ {
+ n = FindMatchingNew(targetlist,
+ ((Var *) node)->varattno);
+ if (n == NULL)
+ {
+ if (info->event == CMD_UPDATE)
+ {
+ ((Var *) node)->varno = info->current_varno;
+ ((Var *) node)->varnoold = info->current_varno;
+ }
+ else
+ {
+ *nodePtr = make_null(((Var *) node)->vartype);
+ }
+ }
+ else
+ {
+ *nodePtr = n;
+ }
+ }
+ break;
}
- } else {
- *nodePtr = n;
- }
- }
- break;
- }
- case T_List: {
- List *l;
- foreach(l, (List*)node) {
- ResolveNew(info, targetlist, (Node**)&(lfirst(l)));
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ ResolveNew(info, targetlist, (Node **) & (lfirst(l)));
+ }
+ break;
+ }
+ default:
+ /* ignore the others */
+ break;
}
- break;
- }
- default:
- /* ignore the others */
- break;
- }
}
void
-FixNew(RewriteInfo* info, Query *parsetree)
+FixNew(RewriteInfo * info, Query * parsetree)
{
- ResolveNew(info, parsetree->targetList,
- (Node**)&(info->rule_action->targetList));
- ResolveNew(info, parsetree->targetList, &info->rule_action->qual);
+ ResolveNew(info, parsetree->targetList,
+ (Node **) & (info->rule_action->targetList));
+ ResolveNew(info, parsetree->targetList, &info->rule_action->qual);
}
static void
-nodeHandleRIRAttributeRule(Node **nodePtr,
- List *rtable,
- List *targetlist,
- int rt_index,
- int attr_num,
- int *modified,
- int *badsql)
+nodeHandleRIRAttributeRule(Node ** nodePtr,
+ List * rtable,
+ List * targetlist,
+ int rt_index,
+ int attr_num,
+ int *modified,
+ int *badsql)
{
- Node *node = *nodePtr;
+ Node *node = *nodePtr;
- if (node == NULL)
- return;
- switch (nodeTag(node)) {
- case T_List:
- {
- List *i;
- foreach(i, (List*)node) {
- nodeHandleRIRAttributeRule((Node**)(&(lfirst(i))), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql);
- }
- }
- break;
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
- nodeHandleRIRAttributeRule(&tle->expr, rtable, targetlist,
- rt_index, attr_num, modified, badsql);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr *)node;
- nodeHandleRIRAttributeRule((Node**)(&(expr->args)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql);
- }
- break;
- case T_Var:
+ if (node == NULL)
+ return;
+ switch (nodeTag(node))
{
- int this_varno = (int) ((Var*)node)->varno;
- NameData name_to_look_for;
- memset(name_to_look_for.data, 0, NAMEDATALEN);
-
- if (this_varno == rt_index &&
- ((Var*) node)->varattno == attr_num) {
- if (((Var*)node)->vartype == 32) { /* HACK */
- *nodePtr = make_null(((Var*)node)->vartype);
- *modified = TRUE;
- *badsql = TRUE;
- break;
- } else {
- namestrcpy(&name_to_look_for,
- (char *)get_attname(getrelid(this_varno,
- rtable),
- attr_num));
+ case T_List:
+ {
+ List *i;
+
+ foreach(i, (List *) node)
+ {
+ nodeHandleRIRAttributeRule((Node **) (&(lfirst(i))), rtable,
+ targetlist, rt_index, attr_num,
+ modified, badsql);
+ }
}
- }
- if (name_to_look_for.data[0]) {
- Node *n;
-
- n = FindMatchingTLEntry(targetlist, (char *)&name_to_look_for);
- if (n == NULL) {
- *nodePtr = make_null(((Var*) node)->vartype);
- } else {
- *nodePtr = n;
+ break;
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ nodeHandleRIRAttributeRule(&tle->expr, rtable, targetlist,
+ rt_index, attr_num, modified, badsql);
}
- *modified = TRUE;
- }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ nodeHandleRIRAttributeRule((Node **) (&(expr->args)), rtable,
+ targetlist, rt_index, attr_num,
+ modified, badsql);
+ }
+ break;
+ case T_Var:
+ {
+ int this_varno = (int) ((Var *) node)->varno;
+ NameData name_to_look_for;
+
+ memset(name_to_look_for.data, 0, NAMEDATALEN);
+
+ if (this_varno == rt_index &&
+ ((Var *) node)->varattno == attr_num)
+ {
+ if (((Var *) node)->vartype == 32)
+ { /* HACK */
+ *nodePtr = make_null(((Var *) node)->vartype);
+ *modified = TRUE;
+ *badsql = TRUE;
+ break;
+ }
+ else
+ {
+ namestrcpy(&name_to_look_for,
+ (char *) get_attname(getrelid(this_varno,
+ rtable),
+ attr_num));
+ }
+ }
+ if (name_to_look_for.data[0])
+ {
+ Node *n;
+
+ n = FindMatchingTLEntry(targetlist, (char *) &name_to_look_for);
+ if (n == NULL)
+ {
+ *nodePtr = make_null(((Var *) node)->vartype);
+ }
+ else
+ {
+ *nodePtr = n;
+ }
+ *modified = TRUE;
+ }
+ }
+ break;
+ default:
+ /* ignore the others */
+ break;
}
- break;
- default:
- /* ignore the others */
- break;
- }
}
-/*
+/*
* Handles 'on retrieve to relation.attribute
- * do instead retrieve (attribute = expression) w/qual'
+ * do instead retrieve (attribute = expression) w/qual'
*/
void
-HandleRIRAttributeRule(Query *parsetree,
- List *rtable,
- List *targetlist,
- int rt_index,
- int attr_num,
- int *modified,
- int *badsql)
+HandleRIRAttributeRule(Query * parsetree,
+ List * rtable,
+ List * targetlist,
+ int rt_index,
+ int attr_num,
+ int *modified,
+ int *badsql)
{
- nodeHandleRIRAttributeRule((Node**)(&(parsetree->targetList)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql);
- nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
- rt_index, attr_num, modified, badsql);
+ nodeHandleRIRAttributeRule((Node **) (&(parsetree->targetList)), rtable,
+ targetlist, rt_index, attr_num,
+ modified, badsql);
+ nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
+ rt_index, attr_num, modified, badsql);
}
static void
-nodeHandleViewRule(Node **nodePtr,
- List *rtable,
- List *targetlist,
- int rt_index,
- int *modified)
+nodeHandleViewRule(Node ** nodePtr,
+ List * rtable,
+ List * targetlist,
+ int rt_index,
+ int *modified)
{
- Node *node = *nodePtr;
-
- if (node == NULL)
- return;
+ Node *node = *nodePtr;
- switch (nodeTag(node)) {
- case T_List:
- {
- List *l;
- foreach (l, (List*)node) {
- nodeHandleViewRule((Node**) (&(lfirst(l))),
- rtable, targetlist,
- rt_index, modified);
- }
- }
- break;
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
- nodeHandleViewRule(&(tle->expr), rtable, targetlist,
- rt_index, modified);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr*)node;
- nodeHandleViewRule((Node**)(&(expr->args)),
- rtable, targetlist,
- rt_index, modified);
- }
- break;
- case T_Var:
+ if (node == NULL)
+ return;
+
+ switch (nodeTag(node))
{
- Var *var = (Var*)node;
- int this_varno = var->varno;
- Node *n;
-
- if (this_varno == rt_index) {
- n = FindMatchingTLEntry(targetlist,
- get_attname(getrelid(this_varno,
- rtable),
- var->varattno));
- if (n == NULL) {
- *nodePtr = make_null(((Var*) node)->vartype);
- } else {
- *nodePtr = n;
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ nodeHandleViewRule((Node **) (&(lfirst(l))),
+ rtable, targetlist,
+ rt_index, modified);
+ }
+ }
+ break;
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ nodeHandleViewRule(&(tle->expr), rtable, targetlist,
+ rt_index, modified);
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ nodeHandleViewRule((Node **) (&(expr->args)),
+ rtable, targetlist,
+ rt_index, modified);
}
- *modified = TRUE;
- }
- break;
+ break;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+ int this_varno = var->varno;
+ Node *n;
+
+ if (this_varno == rt_index)
+ {
+ n = FindMatchingTLEntry(targetlist,
+ get_attname(getrelid(this_varno,
+ rtable),
+ var->varattno));
+ if (n == NULL)
+ {
+ *nodePtr = make_null(((Var *) node)->vartype);
+ }
+ else
+ {
+ *nodePtr = n;
+ }
+ *modified = TRUE;
+ }
+ break;
+ }
+ default:
+ /* ignore the others */
+ break;
}
- default:
- /* ignore the others */
- break;
- }
}
void
-HandleViewRule(Query *parsetree,
- List *rtable,
- List *targetlist,
- int rt_index,
- int *modified)
+HandleViewRule(Query * parsetree,
+ List * rtable,
+ List * targetlist,
+ int rt_index,
+ int *modified)
{
- nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
- modified);
- nodeHandleViewRule((Node**)(&(parsetree->targetList)), rtable, targetlist,
- rt_index, modified);
+ nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
+ modified);
+ nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist,
+ rt_index, modified);
}
-
diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c
index 3052a59a0df..58ccc5865b0 100644
--- a/src/backend/rewrite/rewriteRemove.c
+++ b/src/backend/rewrite/rewriteRemove.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rewriteRemove.c--
- * routines for removing rewrite rules
+ * routines for removing rewrite rules
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.2 1996/11/03 04:51:51 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.3 1997/09/07 04:48:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,37 +18,37 @@
#include "catalog/pg_rewrite.h"
#include "catalog/catname.h" /* for RewriteRelationName */
#include "utils/syscache.h"
-#include "utils/elog.h" /* for elog stuff */
+#include "utils/elog.h" /* for elog stuff */
#include "utils/palloc.h"
-#include "utils/tqual.h" /* 'NowTimeQual' defined here.. */
-#include "access/heapam.h" /* heap AM calls defined here */
-#include "fmgr.h" /* for CHAR_16_EQ */
+#include "utils/tqual.h" /* 'NowTimeQual' defined here.. */
+#include "access/heapam.h" /* heap AM calls defined here */
+#include "fmgr.h" /* for CHAR_16_EQ */
-#include "rewrite/rewriteRemove.h" /* where the decls go */
+#include "rewrite/rewriteRemove.h" /* where the decls go */
#include "rewrite/rewriteSupport.h"
/*-----------------------------------------------------------------------
* RewriteGetRuleEventRel
*-----------------------------------------------------------------------
*/
-char*
+char *
RewriteGetRuleEventRel(char *rulename)
{
- HeapTuple htp;
- Oid eventrel;
-
- htp = SearchSysCacheTuple(REWRITENAME, PointerGetDatum(rulename),
- 0,0,0);
- if (!HeapTupleIsValid(htp))
- elog(WARN, "RewriteGetRuleEventRel: rule \"%s\" not found",
- rulename);
- eventrel = ((Form_pg_rewrite) GETSTRUCT(htp))->ev_class;
- htp = SearchSysCacheTuple(RELOID, PointerGetDatum(eventrel),
- 0,0,0);
- if (!HeapTupleIsValid(htp))
- elog(WARN, "RewriteGetRuleEventRel: class %d not found",
- eventrel);
- return ((Form_pg_class) GETSTRUCT(htp))->relname.data;
+ HeapTuple htp;
+ Oid eventrel;
+
+ htp = SearchSysCacheTuple(REWRITENAME, PointerGetDatum(rulename),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "RewriteGetRuleEventRel: rule \"%s\" not found",
+ rulename);
+ eventrel = ((Form_pg_rewrite) GETSTRUCT(htp))->ev_class;
+ htp = SearchSysCacheTuple(RELOID, PointerGetDatum(eventrel),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "RewriteGetRuleEventRel: class %d not found",
+ eventrel);
+ return ((Form_pg_class) GETSTRUCT(htp))->relname.data;
}
/* ----------------------------------------------------------------
@@ -58,10 +58,10 @@ RewriteGetRuleEventRel(char *rulename)
* Delete a rule given its rulename.
*
* There are three steps.
- * 1) Find the corresponding tuple in 'pg_rewrite' relation.
- * Find the rule Id (i.e. the Oid of the tuple) and finally delete
- * the tuple.
- * 3) Delete the locks from the 'pg_class' relation.
+ * 1) Find the corresponding tuple in 'pg_rewrite' relation.
+ * Find the rule Id (i.e. the Oid of the tuple) and finally delete
+ * the tuple.
+ * 3) Delete the locks from the 'pg_class' relation.
*
*
* ----------------------------------------------------------------
@@ -69,116 +69,119 @@ RewriteGetRuleEventRel(char *rulename)
void
RemoveRewriteRule(char *ruleName)
{
- Relation RewriteRelation = NULL;
- HeapScanDesc scanDesc = NULL;
- ScanKeyData scanKeyData;
- HeapTuple tuple = NULL;
- Oid ruleId = (Oid)0;
- Oid eventRelationOid = (Oid)NULL;
- Datum eventRelationOidDatum = (Datum)NULL;
- Buffer buffer = (Buffer)NULL;
- bool isNull = false;
-
- /*
- * Open the pg_rewrite relation.
- */
- RewriteRelation = heap_openr(RewriteRelationName);
-
- /*
- * Scan the RuleRelation ('pg_rewrite') until we find a tuple
- */
- ScanKeyEntryInitialize(&scanKeyData, 0, Anum_pg_rewrite_rulename,
- F_CHAR16EQ, NameGetDatum(ruleName));
- scanDesc = heap_beginscan(RewriteRelation,
- 0, NowTimeQual, 1, &scanKeyData);
-
- tuple = heap_getnext(scanDesc, 0, (Buffer *)NULL);
-
- /*
- * complain if no rule with such name existed
- */
- if (!HeapTupleIsValid(tuple)) {
+ Relation RewriteRelation = NULL;
+ HeapScanDesc scanDesc = NULL;
+ ScanKeyData scanKeyData;
+ HeapTuple tuple = NULL;
+ Oid ruleId = (Oid) 0;
+ Oid eventRelationOid = (Oid) NULL;
+ Datum eventRelationOidDatum = (Datum) NULL;
+ Buffer buffer = (Buffer) NULL;
+ bool isNull = false;
+
+ /*
+ * Open the pg_rewrite relation.
+ */
+ RewriteRelation = heap_openr(RewriteRelationName);
+
+ /*
+ * Scan the RuleRelation ('pg_rewrite') until we find a tuple
+ */
+ ScanKeyEntryInitialize(&scanKeyData, 0, Anum_pg_rewrite_rulename,
+ F_CHAR16EQ, NameGetDatum(ruleName));
+ scanDesc = heap_beginscan(RewriteRelation,
+ 0, NowTimeQual, 1, &scanKeyData);
+
+ tuple = heap_getnext(scanDesc, 0, (Buffer *) NULL);
+
+ /*
+ * complain if no rule with such name existed
+ */
+ if (!HeapTupleIsValid(tuple))
+ {
+ heap_close(RewriteRelation);
+ elog(WARN, "No rule with name = '%s' was found.\n", ruleName);
+ }
+
+ /*
+ * Store the OID of the rule (i.e. the tuple's OID) and the event
+ * relation's OID
+ */
+ ruleId = tuple->t_oid;
+ eventRelationOidDatum =
+ PointerGetDatum(heap_getattr(tuple,
+ buffer,
+ Anum_pg_rewrite_ev_class,
+ RelationGetTupleDescriptor(RewriteRelation),
+ &isNull));
+ if (isNull)
+ {
+ /* XXX strange!!! */
+ elog(WARN, "RemoveRewriteRule: null event target relation!");
+ }
+ eventRelationOid = DatumGetObjectId(eventRelationOidDatum);
+
+ /*
+ * Now delete the relation level locks from the updated relation.
+ * (Make sure we do this before we remove the rule from pg_rewrite.
+ * Otherwise, heap_openr on eventRelationOid which reads pg_rwrite for
+ * the rules will fail.)
+ */
+ prs2_deleteFromRelation(eventRelationOid, ruleId);
+
+ /*
+ * Now delete the tuple...
+ */
+ heap_delete(RewriteRelation, &(tuple->t_ctid));
heap_close(RewriteRelation);
- elog(WARN, "No rule with name = '%s' was found.\n", ruleName);
- }
-
- /*
- * Store the OID of the rule (i.e. the tuple's OID)
- * and the event relation's OID
- */
- ruleId = tuple->t_oid;
- eventRelationOidDatum =
- PointerGetDatum(heap_getattr(tuple,
- buffer,
- Anum_pg_rewrite_ev_class,
- RelationGetTupleDescriptor(RewriteRelation),
- &isNull));
- if (isNull) {
- /* XXX strange!!! */
- elog(WARN, "RemoveRewriteRule: null event target relation!");
- }
- eventRelationOid = DatumGetObjectId(eventRelationOidDatum);
-
- /*
- * Now delete the relation level locks from the updated relation.
- * (Make sure we do this before we remove the rule from pg_rewrite.
- * Otherwise, heap_openr on eventRelationOid which reads pg_rwrite
- * for the rules will fail.)
- */
- prs2_deleteFromRelation(eventRelationOid, ruleId);
-
- /*
- * Now delete the tuple...
- */
- heap_delete(RewriteRelation, &(tuple->t_ctid));
- heap_close(RewriteRelation);
- heap_endscan(scanDesc);
+ heap_endscan(scanDesc);
}
/*
* RelationRemoveRules -
- * removes all rules associated with the relation when the relation is
- * being removed.
+ * removes all rules associated with the relation when the relation is
+ * being removed.
*/
void
RelationRemoveRules(Oid relid)
{
- Relation RewriteRelation = NULL;
- HeapScanDesc scanDesc = NULL;
- ScanKeyData scanKeyData;
- HeapTuple tuple = NULL;
-
- /*
- * Open the pg_rewrite relation.
- */
- RewriteRelation = heap_openr(RewriteRelationName);
-
- /*
- * Scan the RuleRelation ('pg_rewrite') for all the tuples that
- * has the same ev_class as relid (the relation to be removed).
- */
- ScanKeyEntryInitialize(&scanKeyData,
- 0,
- Anum_pg_rewrite_ev_class,
- F_OIDEQ,
- ObjectIdGetDatum(relid));
- scanDesc = heap_beginscan(RewriteRelation,
- 0, NowTimeQual, 1, &scanKeyData);
-
- for(;;) {
- tuple = heap_getnext(scanDesc, 0, (Buffer *)NULL);
-
- if (!HeapTupleIsValid(tuple)) {
- break; /* we're done */
- }
-
+ Relation RewriteRelation = NULL;
+ HeapScanDesc scanDesc = NULL;
+ ScanKeyData scanKeyData;
+ HeapTuple tuple = NULL;
+
/*
- * delete the tuple...
+ * Open the pg_rewrite relation.
*/
- heap_delete(RewriteRelation, &(tuple->t_ctid));
- }
+ RewriteRelation = heap_openr(RewriteRelationName);
- heap_endscan(scanDesc);
- heap_close(RewriteRelation);
-}
+ /*
+ * Scan the RuleRelation ('pg_rewrite') for all the tuples that has
+ * the same ev_class as relid (the relation to be removed).
+ */
+ ScanKeyEntryInitialize(&scanKeyData,
+ 0,
+ Anum_pg_rewrite_ev_class,
+ F_OIDEQ,
+ ObjectIdGetDatum(relid));
+ scanDesc = heap_beginscan(RewriteRelation,
+ 0, NowTimeQual, 1, &scanKeyData);
+
+ for (;;)
+ {
+ tuple = heap_getnext(scanDesc, 0, (Buffer *) NULL);
+
+ if (!HeapTupleIsValid(tuple))
+ {
+ break; /* we're done */
+ }
+ /*
+ * delete the tuple...
+ */
+ heap_delete(RewriteRelation, &(tuple->t_ctid));
+ }
+
+ heap_endscan(scanDesc);
+ heap_close(RewriteRelation);
+}
diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c
index 54a8f0c7f97..8d3beb1c10f 100644
--- a/src/backend/rewrite/rewriteSupport.c
+++ b/src/backend/rewrite/rewriteSupport.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rewriteSupport.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.6 1997/08/12 22:53:43 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.7 1997/09/07 04:48:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,7 +19,7 @@
#include "nodes/parsenodes.h"
#include "utils/builtins.h" /* for textout */
#include "utils/rel.h" /* for Relation, RelationData ... */
-#include "utils/elog.h" /* for elog */
+#include "utils/elog.h" /* for elog */
#include "storage/buf.h" /* for InvalidBuffer */
#include "rewrite/rewriteSupport.h"
#include "access/heapam.h"
@@ -31,242 +31,250 @@
#include "utils/palloc.h"
#include "fmgr.h"
-/*
+/*
* RuleIdGetActionInfo -
- * given a rule oid, look it up and return the rule-event-qual and
- * list of parsetrees for the rule (in parseTrees)
+ * given a rule oid, look it up and return the rule-event-qual and
+ * list of parsetrees for the rule (in parseTrees)
*/
#ifdef NOT_USED
-static Node *
-RuleIdGetActionInfo(Oid ruleoid, bool *instead_flag, Query **parseTrees)
+static Node *
+RuleIdGetActionInfo(Oid ruleoid, bool * instead_flag, Query ** parseTrees)
{
- HeapTuple ruletuple;
- char *ruleaction = NULL;
- bool action_is_null = false;
- bool instead_is_null = false;
- Relation ruleRelation = NULL;
- TupleDesc ruleTupdesc = NULL;
- Query *ruleparse = NULL;
- char *rule_evqual_string = NULL;
- Node *rule_evqual = NULL;
-
- ruleRelation = heap_openr (RewriteRelationName);
- ruleTupdesc = RelationGetTupleDescriptor(ruleRelation);
- ruletuple = SearchSysCacheTuple (RULOID,
- ObjectIdGetDatum(ruleoid),
- 0,0,0);
- if (ruletuple == NULL)
- elog(WARN, "rule %u isn't in rewrite system relation", ruleoid);
-
- ruleaction = heap_getattr(ruletuple,
- InvalidBuffer,
- Anum_pg_rewrite_action,
- ruleTupdesc,
- &action_is_null ) ;
- rule_evqual_string = heap_getattr(ruletuple, InvalidBuffer,
- Anum_pg_rewrite_ev_qual,
- ruleTupdesc, &action_is_null) ;
- *instead_flag = !!heap_getattr(ruletuple, InvalidBuffer,
- Anum_pg_rewrite_is_instead,
- ruleTupdesc, &instead_is_null) ;
-
- if (action_is_null || instead_is_null) {
- elog(WARN, "internal error: rewrite rule not properly set up");
- }
-
- ruleaction = textout((struct varlena *)ruleaction);
- rule_evqual_string = textout((struct varlena *)rule_evqual_string);
-
- ruleparse = (Query*)stringToNode(ruleaction);
- rule_evqual = (Node*)stringToNode(rule_evqual_string);
-
- heap_close(ruleRelation);
-
- *parseTrees = ruleparse;
- return rule_evqual;
+ HeapTuple ruletuple;
+ char *ruleaction = NULL;
+ bool action_is_null = false;
+ bool instead_is_null = false;
+ Relation ruleRelation = NULL;
+ TupleDesc ruleTupdesc = NULL;
+ Query *ruleparse = NULL;
+ char *rule_evqual_string = NULL;
+ Node *rule_evqual = NULL;
+
+ ruleRelation = heap_openr(RewriteRelationName);
+ ruleTupdesc = RelationGetTupleDescriptor(ruleRelation);
+ ruletuple = SearchSysCacheTuple(RULOID,
+ ObjectIdGetDatum(ruleoid),
+ 0, 0, 0);
+ if (ruletuple == NULL)
+ elog(WARN, "rule %u isn't in rewrite system relation", ruleoid);
+
+ ruleaction = heap_getattr(ruletuple,
+ InvalidBuffer,
+ Anum_pg_rewrite_action,
+ ruleTupdesc,
+ &action_is_null);
+ rule_evqual_string = heap_getattr(ruletuple, InvalidBuffer,
+ Anum_pg_rewrite_ev_qual,
+ ruleTupdesc, &action_is_null);
+ *instead_flag = !!heap_getattr(ruletuple, InvalidBuffer,
+ Anum_pg_rewrite_is_instead,
+ ruleTupdesc, &instead_is_null);
+
+ if (action_is_null || instead_is_null)
+ {
+ elog(WARN, "internal error: rewrite rule not properly set up");
+ }
+
+ ruleaction = textout((struct varlena *) ruleaction);
+ rule_evqual_string = textout((struct varlena *) rule_evqual_string);
+
+ ruleparse = (Query *) stringToNode(ruleaction);
+ rule_evqual = (Node *) stringToNode(rule_evqual_string);
+
+ heap_close(ruleRelation);
+
+ *parseTrees = ruleparse;
+ return rule_evqual;
}
+
#endif
int
IsDefinedRewriteRule(char *ruleName)
{
- Relation RewriteRelation = NULL;
- HeapScanDesc scanDesc = NULL;
- ScanKeyData scanKey;
- HeapTuple tuple = NULL;
-
-
- /*
- * Open the pg_rewrite relation.
- */
- RewriteRelation = heap_openr(RewriteRelationName);
-
- /*
- * Scan the RuleRelation ('pg_rewrite') until we find a tuple
- */
- ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_rewrite_rulename,
- NameEqualRegProcedure, PointerGetDatum(ruleName));
- scanDesc = heap_beginscan(RewriteRelation,
- 0, NowTimeQual, 1, &scanKey);
-
- tuple = heap_getnext(scanDesc, 0, (Buffer *)NULL);
-
- /*
- * return whether or not the rewrite rule existed
- */
- heap_close(RewriteRelation);
- heap_endscan(scanDesc);
- return (HeapTupleIsValid(tuple));
+ Relation RewriteRelation = NULL;
+ HeapScanDesc scanDesc = NULL;
+ ScanKeyData scanKey;
+ HeapTuple tuple = NULL;
+
+
+ /*
+ * Open the pg_rewrite relation.
+ */
+ RewriteRelation = heap_openr(RewriteRelationName);
+
+ /*
+ * Scan the RuleRelation ('pg_rewrite') until we find a tuple
+ */
+ ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_rewrite_rulename,
+ NameEqualRegProcedure, PointerGetDatum(ruleName));
+ scanDesc = heap_beginscan(RewriteRelation,
+ 0, NowTimeQual, 1, &scanKey);
+
+ tuple = heap_getnext(scanDesc, 0, (Buffer *) NULL);
+
+ /*
+ * return whether or not the rewrite rule existed
+ */
+ heap_close(RewriteRelation);
+ heap_endscan(scanDesc);
+ return (HeapTupleIsValid(tuple));
}
static void
setRelhasrulesInRelation(Oid relationId, bool relhasrules)
{
- Relation relationRelation;
- HeapTuple tuple;
- HeapTuple newTuple;
- Relation idescs[Num_pg_class_indices];
- Form_pg_class relp;
-
- /*
- * Lock a relation given its Oid.
- * Go to the RelationRelation (i.e. pg_relation), find the
- * appropriate tuple, and add the specified lock to it.
- */
- relationRelation = heap_openr(RelationRelationName);
- tuple = ClassOidIndexScan(relationRelation, relationId);
-
- /*
- * Create a new tuple (i.e. a copy of the old tuple
- * with its rule lock field changed and replace the old
- * tuple in the RelationRelation
- * NOTE: XXX ??? do we really need to make that copy ????
- */
- newTuple = heap_copytuple(tuple);
-
- relp = (Form_pg_class) GETSTRUCT(newTuple);
- relp->relhasrules = relhasrules;
-
- heap_replace(relationRelation, &(tuple->t_ctid), newTuple);
-
- /* keep the catalog indices up to date */
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation,
- newTuple);
- CatalogCloseIndices(Num_pg_class_indices, idescs);
-
- /* be tidy */
- pfree(tuple);
- pfree(newTuple);
-
- heap_close(relationRelation);
+ Relation relationRelation;
+ HeapTuple tuple;
+ HeapTuple newTuple;
+ Relation idescs[Num_pg_class_indices];
+ Form_pg_class relp;
+
+ /*
+ * Lock a relation given its Oid. Go to the RelationRelation (i.e.
+ * pg_relation), find the appropriate tuple, and add the specified
+ * lock to it.
+ */
+ relationRelation = heap_openr(RelationRelationName);
+ tuple = ClassOidIndexScan(relationRelation, relationId);
+
+ /*
+ * Create a new tuple (i.e. a copy of the old tuple with its rule lock
+ * field changed and replace the old tuple in the RelationRelation
+ * NOTE: XXX ??? do we really need to make that copy ????
+ */
+ newTuple = heap_copytuple(tuple);
+
+ relp = (Form_pg_class) GETSTRUCT(newTuple);
+ relp->relhasrules = relhasrules;
+
+ heap_replace(relationRelation, &(tuple->t_ctid), newTuple);
+
+ /* keep the catalog indices up to date */
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation,
+ newTuple);
+ CatalogCloseIndices(Num_pg_class_indices, idescs);
+
+ /* be tidy */
+ pfree(tuple);
+ pfree(newTuple);
+
+ heap_close(relationRelation);
}
void
prs2_addToRelation(Oid relid,
- Oid ruleId,
- CmdType event_type,
- AttrNumber attno,
- bool isInstead,
- Node *qual,
- List *actions)
+ Oid ruleId,
+ CmdType event_type,
+ AttrNumber attno,
+ bool isInstead,
+ Node * qual,
+ List * actions)
{
- Relation relation;
- RewriteRule *thisRule;
- RuleLock *rulelock;
- MemoryContext oldcxt;
-
- /*
- * create an in memory RewriteRule data structure which is cached by
- * every Relation descriptor. (see utils/cache/relcache.c)
- */
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
- thisRule = (RewriteRule *)palloc(sizeof(RewriteRule));
- MemoryContextSwitchTo(oldcxt);
-
- thisRule->ruleId = ruleId;
- thisRule->event = event_type;
- thisRule->attrno = attno;
- thisRule->qual = qual;
- thisRule->actions = actions;
- thisRule->isInstead = isInstead;
-
- relation = heap_open(relid);
-
- /*
- * modify or create a RuleLock cached by Relation
- */
- if (relation->rd_rules == NULL) {
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
- rulelock = (RuleLock *)palloc(sizeof(RuleLock));
- rulelock->numLocks = 1;
- rulelock->rules = (RewriteRule **)palloc(sizeof(RewriteRule*));
- rulelock->rules[0] = thisRule;
- relation->rd_rules = rulelock;
- MemoryContextSwitchTo(oldcxt);
+ Relation relation;
+ RewriteRule *thisRule;
+ RuleLock *rulelock;
+ MemoryContext oldcxt;
/*
- * the fact that relation->rd_rules is NULL means the relhasrules
- * attribute of the tuple of this relation in pg_class is false. We
- * need to set it to true.
+ * create an in memory RewriteRule data structure which is cached by
+ * every Relation descriptor. (see utils/cache/relcache.c)
*/
- setRelhasrulesInRelation(relid, TRUE);
- } else {
- int numlock;
-
- rulelock = relation->rd_rules;
- numlock = rulelock->numLocks;
- /* expand, for safety reasons */
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
- rulelock->rules =
- (RewriteRule **)repalloc(rulelock->rules,
- sizeof(RewriteRule*)*(numlock+1));
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ thisRule = (RewriteRule *) palloc(sizeof(RewriteRule));
MemoryContextSwitchTo(oldcxt);
- rulelock->rules[numlock] = thisRule;
- rulelock->numLocks++;
- }
- heap_close(relation);
+ thisRule->ruleId = ruleId;
+ thisRule->event = event_type;
+ thisRule->attrno = attno;
+ thisRule->qual = qual;
+ thisRule->actions = actions;
+ thisRule->isInstead = isInstead;
+
+ relation = heap_open(relid);
+
+ /*
+ * modify or create a RuleLock cached by Relation
+ */
+ if (relation->rd_rules == NULL)
+ {
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ rulelock = (RuleLock *) palloc(sizeof(RuleLock));
+ rulelock->numLocks = 1;
+ rulelock->rules = (RewriteRule **) palloc(sizeof(RewriteRule *));
+ rulelock->rules[0] = thisRule;
+ relation->rd_rules = rulelock;
+ MemoryContextSwitchTo(oldcxt);
- return;
+ /*
+ * the fact that relation->rd_rules is NULL means the relhasrules
+ * attribute of the tuple of this relation in pg_class is false.
+ * We need to set it to true.
+ */
+ setRelhasrulesInRelation(relid, TRUE);
+ }
+ else
+ {
+ int numlock;
+
+ rulelock = relation->rd_rules;
+ numlock = rulelock->numLocks;
+ /* expand, for safety reasons */
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ rulelock->rules =
+ (RewriteRule **) repalloc(rulelock->rules,
+ sizeof(RewriteRule *) * (numlock + 1));
+ MemoryContextSwitchTo(oldcxt);
+ rulelock->rules[numlock] = thisRule;
+ rulelock->numLocks++;
+ }
+
+ heap_close(relation);
+
+ return;
}
void
prs2_deleteFromRelation(Oid relid, Oid ruleId)
{
- RuleLock *rulelock;
- Relation relation;
- int numlock;
- int i;
- MemoryContext oldcxt;
-
- relation = heap_open(relid);
- rulelock = relation->rd_rules;
- Assert(rulelock != NULL);
-
- numlock = rulelock->numLocks;
- for(i=0; i < numlock; i++) {
- if (rulelock->rules[i]->ruleId == ruleId)
- break;
- }
- Assert(i<numlock);
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
- pfree(rulelock->rules[i]);
- MemoryContextSwitchTo(oldcxt);
- if (numlock==1) {
- relation->rd_rules = NULL;
- /*
- * we don't have rules any more, flag the relhasrules attribute of
- * the tuple of this relation in pg_class false.
- */
- setRelhasrulesInRelation(relid, FALSE);
- } else {
- rulelock->rules[i] = rulelock->rules[numlock-1];
- rulelock->rules[numlock-1] = NULL;
- rulelock->numLocks--;
- }
-
- heap_close(relation);
-}
+ RuleLock *rulelock;
+ Relation relation;
+ int numlock;
+ int i;
+ MemoryContext oldcxt;
+ relation = heap_open(relid);
+ rulelock = relation->rd_rules;
+ Assert(rulelock != NULL);
+
+ numlock = rulelock->numLocks;
+ for (i = 0; i < numlock; i++)
+ {
+ if (rulelock->rules[i]->ruleId == ruleId)
+ break;
+ }
+ Assert(i < numlock);
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ pfree(rulelock->rules[i]);
+ MemoryContextSwitchTo(oldcxt);
+ if (numlock == 1)
+ {
+ relation->rd_rules = NULL;
+
+ /*
+ * we don't have rules any more, flag the relhasrules attribute of
+ * the tuple of this relation in pg_class false.
+ */
+ setRelhasrulesInRelation(relid, FALSE);
+ }
+ else
+ {
+ rulelock->rules[i] = rulelock->rules[numlock - 1];
+ rulelock->rules[numlock - 1] = NULL;
+ rulelock->numLocks--;
+ }
+
+ heap_close(relation);
+}
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index 20f8195d1e9..4ce064d6713 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* buf_init.c--
- * buffer manager initialization routines
+ * buffer manager initialization routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.10 1997/07/28 00:54:33 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.11 1997/09/07 04:48:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,98 +35,103 @@
#include "utils/dynahash.h"
#include "utils/hsearch.h"
#include "utils/memutils.h"
-#include "executor/execdebug.h" /* for NDirectFileRead */
+#include "executor/execdebug.h" /* for NDirectFileRead */
#include "catalog/catalog.h"
/*
- * if BMTRACE is defined, we trace the last 200 buffer allocations and
- * deallocations in a circular buffer in shared memory.
+ * if BMTRACE is defined, we trace the last 200 buffer allocations and
+ * deallocations in a circular buffer in shared memory.
*/
#ifdef BMTRACE
-bmtrace *TraceBuf;
-long *CurTraceBuf;
-#define BMT_LIMIT 200
-#endif /* BMTRACE */
-int ShowPinTrace = 0;
-
-int NBuffers = NDBUFS; /* NDBUFS defined in miscadmin.h */
-int Data_Descriptors;
-int Free_List_Descriptor;
-int Lookup_List_Descriptor;
-int Num_Descriptors;
-
-BufferDesc *BufferDescriptors;
-BufferBlock BufferBlocks;
+bmtrace *TraceBuf;
+long *CurTraceBuf;
+
+#define BMT_LIMIT 200
+#endif /* BMTRACE */
+int ShowPinTrace = 0;
+
+int NBuffers = NDBUFS; /* NDBUFS defined in miscadmin.h */
+int Data_Descriptors;
+int Free_List_Descriptor;
+int Lookup_List_Descriptor;
+int Num_Descriptors;
+
+BufferDesc *BufferDescriptors;
+BufferBlock BufferBlocks;
+
#ifndef HAS_TEST_AND_SET
-long *NWaitIOBackendP;
+long *NWaitIOBackendP;
+
#endif
-extern IpcSemaphoreId WaitIOSemId;
+extern IpcSemaphoreId WaitIOSemId;
+
+long *PrivateRefCount;/* also used in freelist.c */
+long *LastRefCount; /* refcounts of last ExecMain level */
+long *CommitInfoNeedsSave; /* to write buffers where we have
+ * filled in */
-long *PrivateRefCount; /* also used in freelist.c */
-long *LastRefCount; /* refcounts of last ExecMain level */
-long *CommitInfoNeedsSave; /* to write buffers where we have filled in */
- /* t_tmin (or t_tmax) */
+ /* t_tmin (or t_tmax) */
/*
* Data Structures:
- * buffers live in a freelist and a lookup data structure.
- *
+ * buffers live in a freelist and a lookup data structure.
+ *
*
* Buffer Lookup:
- * Two important notes. First, the buffer has to be
- * available for lookup BEFORE an IO begins. Otherwise
- * a second process trying to read the buffer will
- * allocate its own copy and the buffeer pool will
- * become inconsistent.
+ * Two important notes. First, the buffer has to be
+ * available for lookup BEFORE an IO begins. Otherwise
+ * a second process trying to read the buffer will
+ * allocate its own copy and the buffeer pool will
+ * become inconsistent.
*
* Buffer Replacement:
- * see freelist.c. A buffer cannot be replaced while in
- * use either by data manager or during IO.
+ * see freelist.c. A buffer cannot be replaced while in
+ * use either by data manager or during IO.
*
* WriteBufferBack:
- * currently, a buffer is only written back at the time
- * it is selected for replacement. It should
- * be done sooner if possible to reduce latency of
- * BufferAlloc(). Maybe there should be a daemon process.
+ * currently, a buffer is only written back at the time
+ * it is selected for replacement. It should
+ * be done sooner if possible to reduce latency of
+ * BufferAlloc(). Maybe there should be a daemon process.
*
* Synchronization/Locking:
*
- * BufMgrLock lock -- must be acquired before manipulating the
- * buffer queues (lookup/freelist). Must be released
- * before exit and before doing any IO.
+ * BufMgrLock lock -- must be acquired before manipulating the
+ * buffer queues (lookup/freelist). Must be released
+ * before exit and before doing any IO.
*
* IO_IN_PROGRESS -- this is a flag in the buffer descriptor.
- * It must be set when an IO is initiated and cleared at
- * the end of the IO. It is there to make sure that one
- * process doesn't start to use a buffer while another is
- * faulting it in. see IOWait/IOSignal.
+ * It must be set when an IO is initiated and cleared at
+ * the end of the IO. It is there to make sure that one
+ * process doesn't start to use a buffer while another is
+ * faulting it in. see IOWait/IOSignal.
*
- * refcount -- A buffer is pinned during IO and immediately
- * after a BufferAlloc(). A buffer is always either pinned
- * or on the freelist but never both. The buffer must be
- * released, written, or flushed before the end of
- * transaction.
+ * refcount -- A buffer is pinned during IO and immediately
+ * after a BufferAlloc(). A buffer is always either pinned
+ * or on the freelist but never both. The buffer must be
+ * released, written, or flushed before the end of
+ * transaction.
*
* PrivateRefCount -- Each buffer also has a private refcount the keeps
- * track of the number of times the buffer is pinned in the current
- * processes. This is used for two purposes, first, if we pin a
- * a buffer more than once, we only need to change the shared refcount
- * once, thus only lock the buffer pool once, second, when a transaction
- * aborts, it should only unpin the buffers exactly the number of times it
- * has pinned them, so that it will not blow away buffers of another
- * backend.
+ * track of the number of times the buffer is pinned in the current
+ * processes. This is used for two purposes, first, if we pin a
+ * a buffer more than once, we only need to change the shared refcount
+ * once, thus only lock the buffer pool once, second, when a transaction
+ * aborts, it should only unpin the buffers exactly the number of times it
+ * has pinned them, so that it will not blow away buffers of another
+ * backend.
*
*/
-SPINLOCK BufMgrLock;
+SPINLOCK BufMgrLock;
-long int ReadBufferCount;
-long int ReadLocalBufferCount;
-long int BufferHitCount;
-long int LocalBufferHitCount;
-long int BufferFlushCount;
-long int LocalBufferFlushCount;
+long int ReadBufferCount;
+long int ReadLocalBufferCount;
+long int BufferHitCount;
+long int LocalBufferHitCount;
+long int BufferFlushCount;
+long int LocalBufferFlushCount;
/*
@@ -138,111 +143,121 @@ long int LocalBufferFlushCount;
void
InitBufferPool(IPCKey key)
{
- bool foundBufs,foundDescs;
- int i;
-
- /* check padding of BufferDesc and BufferHdr */
- /* we need both checks because a sbufdesc_padded > PADDED_SBUFDESC_SIZE
- will shrink sbufdesc to the required size, which is bad */
- if (sizeof(struct sbufdesc) != PADDED_SBUFDESC_SIZE ||
- sizeof(struct sbufdesc_unpadded) > PADDED_SBUFDESC_SIZE)
- elog(WARN,"Internal error: sbufdesc does not have the proper size, "
- "contact the Postgres developers");
- if (sizeof(struct sbufdesc_unpadded) <= PADDED_SBUFDESC_SIZE/2)
- elog(WARN,"Internal error: sbufdesc is greatly over-sized, "
- "contact the Postgres developers");
-
- Data_Descriptors = NBuffers;
- Free_List_Descriptor = Data_Descriptors;
- Lookup_List_Descriptor = Data_Descriptors + 1;
- Num_Descriptors = Data_Descriptors + 1;
-
- SpinAcquire(BufMgrLock);
-
+ bool foundBufs,
+ foundDescs;
+ int i;
+
+ /* check padding of BufferDesc and BufferHdr */
+
+ /*
+ * we need both checks because a sbufdesc_padded >
+ * PADDED_SBUFDESC_SIZE will shrink sbufdesc to the required size,
+ * which is bad
+ */
+ if (sizeof(struct sbufdesc) != PADDED_SBUFDESC_SIZE ||
+ sizeof(struct sbufdesc_unpadded) > PADDED_SBUFDESC_SIZE)
+ elog(WARN, "Internal error: sbufdesc does not have the proper size, "
+ "contact the Postgres developers");
+ if (sizeof(struct sbufdesc_unpadded) <= PADDED_SBUFDESC_SIZE / 2)
+ elog(WARN, "Internal error: sbufdesc is greatly over-sized, "
+ "contact the Postgres developers");
+
+ Data_Descriptors = NBuffers;
+ Free_List_Descriptor = Data_Descriptors;
+ Lookup_List_Descriptor = Data_Descriptors + 1;
+ Num_Descriptors = Data_Descriptors + 1;
+
+ SpinAcquire(BufMgrLock);
+
#ifdef BMTRACE
- CurTraceBuf = (long *) ShmemInitStruct("Buffer trace",
- (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long),
- &foundDescs);
- if (!foundDescs)
- memset(CurTraceBuf, 0, (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long));
-
- TraceBuf = (bmtrace *) &(CurTraceBuf[1]);
+ CurTraceBuf = (long *) ShmemInitStruct("Buffer trace",
+ (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long),
+ &foundDescs);
+ if (!foundDescs)
+ memset(CurTraceBuf, 0, (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long));
+
+ TraceBuf = (bmtrace *) & (CurTraceBuf[1]);
#endif
-
- BufferDescriptors = (BufferDesc *)
- ShmemInitStruct("Buffer Descriptors",
- Num_Descriptors*sizeof(BufferDesc),&foundDescs);
-
- BufferBlocks = (BufferBlock)
- ShmemInitStruct("Buffer Blocks",
- NBuffers*BLCKSZ,&foundBufs);
-
+
+ BufferDescriptors = (BufferDesc *)
+ ShmemInitStruct("Buffer Descriptors",
+ Num_Descriptors * sizeof(BufferDesc), &foundDescs);
+
+ BufferBlocks = (BufferBlock)
+ ShmemInitStruct("Buffer Blocks",
+ NBuffers * BLCKSZ, &foundBufs);
+
#ifndef HAS_TEST_AND_SET
- {
- bool foundNWaitIO;
-
- NWaitIOBackendP = (long *)ShmemInitStruct("#Backends Waiting IO",
- sizeof(long),
- &foundNWaitIO);
- if (!foundNWaitIO)
- *NWaitIOBackendP = 0;
- }
+ {
+ bool foundNWaitIO;
+
+ NWaitIOBackendP = (long *) ShmemInitStruct("#Backends Waiting IO",
+ sizeof(long),
+ &foundNWaitIO);
+ if (!foundNWaitIO)
+ *NWaitIOBackendP = 0;
+ }
#endif
-
- if (foundDescs || foundBufs) {
-
- /* both should be present or neither */
- Assert(foundDescs && foundBufs);
-
- } else {
- BufferDesc *buf;
- unsigned long block;
-
- buf = BufferDescriptors;
- block = (unsigned long) BufferBlocks;
-
- /*
- * link the buffers into a circular, doubly-linked list to
- * initialize free list. Still don't know anything about
- * replacement strategy in this file.
- */
- for (i = 0; i < Data_Descriptors; block+=BLCKSZ,buf++,i++) {
- Assert(ShmemIsValid((unsigned long)block));
-
- buf->freeNext = i+1;
- buf->freePrev = i-1;
-
- CLEAR_BUFFERTAG(&(buf->tag));
- buf->data = MAKE_OFFSET(block);
- buf->flags = (BM_DELETED | BM_FREE | BM_VALID);
- buf->refcount = 0;
- buf->buf_id = i;
+
+ if (foundDescs || foundBufs)
+ {
+
+ /* both should be present or neither */
+ Assert(foundDescs && foundBufs);
+
+ }
+ else
+ {
+ BufferDesc *buf;
+ unsigned long block;
+
+ buf = BufferDescriptors;
+ block = (unsigned long) BufferBlocks;
+
+ /*
+ * link the buffers into a circular, doubly-linked list to
+ * initialize free list. Still don't know anything about
+ * replacement strategy in this file.
+ */
+ for (i = 0; i < Data_Descriptors; block += BLCKSZ, buf++, i++)
+ {
+ Assert(ShmemIsValid((unsigned long) block));
+
+ buf->freeNext = i + 1;
+ buf->freePrev = i - 1;
+
+ CLEAR_BUFFERTAG(&(buf->tag));
+ buf->data = MAKE_OFFSET(block);
+ buf->flags = (BM_DELETED | BM_FREE | BM_VALID);
+ buf->refcount = 0;
+ buf->buf_id = i;
#ifdef HAS_TEST_AND_SET
- S_INIT_LOCK(&(buf->io_in_progress_lock));
+ S_INIT_LOCK(&(buf->io_in_progress_lock));
#endif
+ }
+
+ /* close the circular queue */
+ BufferDescriptors[0].freePrev = Data_Descriptors - 1;
+ BufferDescriptors[Data_Descriptors - 1].freeNext = 0;
}
-
- /* close the circular queue */
- BufferDescriptors[0].freePrev = Data_Descriptors-1;
- BufferDescriptors[Data_Descriptors-1].freeNext = 0;
- }
-
- /* Init the rest of the module */
- InitBufTable();
- InitFreeList(!foundDescs);
-
- SpinRelease(BufMgrLock);
-
+
+ /* Init the rest of the module */
+ InitBufTable();
+ InitFreeList(!foundDescs);
+
+ SpinRelease(BufMgrLock);
+
#ifndef HAS_TEST_AND_SET
- {
- int status;
- WaitIOSemId = IpcSemaphoreCreate(IPCKeyGetWaitIOSemaphoreKey(key),
- 1, IPCProtection, 0, 1, &status);
- }
+ {
+ int status;
+
+ WaitIOSemId = IpcSemaphoreCreate(IPCKeyGetWaitIOSemaphoreKey(key),
+ 1, IPCProtection, 0, 1, &status);
+ }
#endif
- PrivateRefCount = (long *) calloc(NBuffers, sizeof(long));
- LastRefCount = (long *) calloc(NBuffers, sizeof(long));
- CommitInfoNeedsSave = (long *) calloc(NBuffers, sizeof(long));
+ PrivateRefCount = (long *) calloc(NBuffers, sizeof(long));
+ LastRefCount = (long *) calloc(NBuffers, sizeof(long));
+ CommitInfoNeedsSave = (long *) calloc(NBuffers, sizeof(long));
}
/* -----------------------------------------------------
@@ -255,43 +270,41 @@ InitBufferPool(IPCKey key)
int
BufferShmemSize()
{
- int size = 0;
- int nbuckets;
- int nsegs;
- int tmp;
-
- nbuckets = 1 << (int)my_log2((NBuffers - 1) / DEF_FFACTOR + 1);
- nsegs = 1 << (int)my_log2((nbuckets - 1) / DEF_SEGSIZE + 1);
-
- /* size of shmem binding table */
- size += MAXALIGN(my_log2(BTABLE_SIZE) * sizeof(void *)); /* HTAB->dir */
- size += MAXALIGN(sizeof(HHDR)); /* HTAB->hctl */
- size += MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
- size += BUCKET_ALLOC_INCR *
- (MAXALIGN(sizeof(BUCKET_INDEX)) +
- MAXALIGN(BTABLE_KEYSIZE) +
- MAXALIGN(BTABLE_DATASIZE));
-
- /* size of buffer descriptors */
- size += MAXALIGN((NBuffers + 1) * sizeof(BufferDesc));
-
- /* size of data pages */
- size += NBuffers * MAXALIGN(BLCKSZ);
-
- /* size of buffer hash table */
- size += MAXALIGN(my_log2(NBuffers) * sizeof(void *)); /* HTAB->dir */
- size += MAXALIGN(sizeof(HHDR)); /* HTAB->hctl */
- size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
- tmp = (int)ceil((double)NBuffers/BUCKET_ALLOC_INCR);
- size += tmp * BUCKET_ALLOC_INCR *
- (MAXALIGN(sizeof(BUCKET_INDEX)) +
- MAXALIGN(sizeof(BufferTag)) +
- MAXALIGN(sizeof(Buffer)));
-
+ int size = 0;
+ int nbuckets;
+ int nsegs;
+ int tmp;
+
+ nbuckets = 1 << (int) my_log2((NBuffers - 1) / DEF_FFACTOR + 1);
+ nsegs = 1 << (int) my_log2((nbuckets - 1) / DEF_SEGSIZE + 1);
+
+ /* size of shmem binding table */
+ size += MAXALIGN(my_log2(BTABLE_SIZE) * sizeof(void *)); /* HTAB->dir */
+ size += MAXALIGN(sizeof(HHDR)); /* HTAB->hctl */
+ size += MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
+ size += BUCKET_ALLOC_INCR *
+ (MAXALIGN(sizeof(BUCKET_INDEX)) +
+ MAXALIGN(BTABLE_KEYSIZE) +
+ MAXALIGN(BTABLE_DATASIZE));
+
+ /* size of buffer descriptors */
+ size += MAXALIGN((NBuffers + 1) * sizeof(BufferDesc));
+
+ /* size of data pages */
+ size += NBuffers * MAXALIGN(BLCKSZ);
+
+ /* size of buffer hash table */
+ size += MAXALIGN(my_log2(NBuffers) * sizeof(void *)); /* HTAB->dir */
+ size += MAXALIGN(sizeof(HHDR)); /* HTAB->hctl */
+ size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
+ tmp = (int) ceil((double) NBuffers / BUCKET_ALLOC_INCR);
+ size += tmp * BUCKET_ALLOC_INCR *
+ (MAXALIGN(sizeof(BUCKET_INDEX)) +
+ MAXALIGN(sizeof(BufferTag)) +
+ MAXALIGN(sizeof(Buffer)));
+
#ifdef BMTRACE
- size += (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long);
+ size += (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long);
#endif
- return size;
+ return size;
}
-
-
diff --git a/src/backend/storage/buffer/buf_table.c b/src/backend/storage/buffer/buf_table.c
index 61e365ce55e..41b2b4d8ee0 100644
--- a/src/backend/storage/buffer/buf_table.c
+++ b/src/backend/storage/buffer/buf_table.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* buf_table.c--
- * routines for finding buffers in the buffer pool.
+ * routines for finding buffers in the buffer pool.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_table.c,v 1.4 1997/08/19 21:32:34 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_table.c,v 1.5 1997/09/07 04:48:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,30 +16,31 @@
*
* Data Structures:
*
- * Buffers are identified by their BufferTag (buf.h). This
+ * Buffers are identified by their BufferTag (buf.h). This
* file contains routines for allocating a shmem hash table to
* map buffer tags to buffer descriptors.
*
* Synchronization:
- *
- * All routines in this file assume buffer manager spinlock is
- * held by their caller.
+ *
+ * All routines in this file assume buffer manager spinlock is
+ * held by their caller.
*/
#include "postgres.h"
#include "storage/bufmgr.h"
-#include "storage/buf_internals.h" /* where the declarations go */
+#include "storage/buf_internals.h" /* where the declarations go */
#include "storage/shmem.h"
#include "storage/spin.h"
#include "utils/hsearch.h"
-static HTAB *SharedBufHash;
+static HTAB *SharedBufHash;
-typedef struct lookup {
- BufferTag key;
- Buffer id;
-} LookupEnt;
+typedef struct lookup
+{
+ BufferTag key;
+ Buffer id;
+} LookupEnt;
/*
* Initialize shmem hash table for mapping buffers
@@ -47,109 +48,116 @@ typedef struct lookup {
void
InitBufTable()
{
- HASHCTL info;
- int hash_flags;
-
- /* assume lock is held */
-
- /* BufferTag maps to Buffer */
- info.keysize = sizeof(BufferTag);
- info.datasize = sizeof(Buffer);
- info.hash = tag_hash;
-
- hash_flags = (HASH_ELEM | HASH_FUNCTION);
-
-
- SharedBufHash = (HTAB *) ShmemInitHash("Shared Buf Lookup Table",
- NBuffers,NBuffers,
- &info,hash_flags);
-
- if (! SharedBufHash) {
- elog(FATAL,"couldn't initialize shared buffer pool Hash Tbl");
- exit(1);
- }
-
+ HASHCTL info;
+ int hash_flags;
+
+ /* assume lock is held */
+
+ /* BufferTag maps to Buffer */
+ info.keysize = sizeof(BufferTag);
+ info.datasize = sizeof(Buffer);
+ info.hash = tag_hash;
+
+ hash_flags = (HASH_ELEM | HASH_FUNCTION);
+
+
+ SharedBufHash = (HTAB *) ShmemInitHash("Shared Buf Lookup Table",
+ NBuffers, NBuffers,
+ &info, hash_flags);
+
+ if (!SharedBufHash)
+ {
+ elog(FATAL, "couldn't initialize shared buffer pool Hash Tbl");
+ exit(1);
+ }
+
}
-BufferDesc *
-BufTableLookup(BufferTag *tagPtr)
+BufferDesc *
+BufTableLookup(BufferTag * tagPtr)
{
- LookupEnt * result;
- bool found;
-
- if (tagPtr->blockNum == P_NEW)
- return(NULL);
-
- result = (LookupEnt *)
- hash_search(SharedBufHash,(char *) tagPtr,HASH_FIND,&found);
-
- if (! result){
- elog(WARN,"BufTableLookup: BufferLookup table corrupted");
- return(NULL);
- }
- if (! found) {
- return(NULL);
- }
- return(&(BufferDescriptors[result->id]));
+ LookupEnt *result;
+ bool found;
+
+ if (tagPtr->blockNum == P_NEW)
+ return (NULL);
+
+ result = (LookupEnt *)
+ hash_search(SharedBufHash, (char *) tagPtr, HASH_FIND, &found);
+
+ if (!result)
+ {
+ elog(WARN, "BufTableLookup: BufferLookup table corrupted");
+ return (NULL);
+ }
+ if (!found)
+ {
+ return (NULL);
+ }
+ return (&(BufferDescriptors[result->id]));
}
/*
* BufTableDelete
*/
bool
-BufTableDelete(BufferDesc *buf)
+BufTableDelete(BufferDesc * buf)
{
- LookupEnt * result;
- bool found;
-
- /* buffer not initialized or has been removed from
- * table already. BM_DELETED keeps us from removing
- * buffer twice.
- */
- if (buf->flags & BM_DELETED) {
- return(TRUE);
- }
-
- buf->flags |= BM_DELETED;
-
- result = (LookupEnt *)
- hash_search(SharedBufHash,(char *) &(buf->tag),HASH_REMOVE,&found);
-
- if (! (result && found)) {
- elog(WARN,"BufTableDelete: BufferLookup table corrupted");
- return(FALSE);
- }
-
- return(TRUE);
+ LookupEnt *result;
+ bool found;
+
+ /*
+ * buffer not initialized or has been removed from table already.
+ * BM_DELETED keeps us from removing buffer twice.
+ */
+ if (buf->flags & BM_DELETED)
+ {
+ return (TRUE);
+ }
+
+ buf->flags |= BM_DELETED;
+
+ result = (LookupEnt *)
+ hash_search(SharedBufHash, (char *) &(buf->tag), HASH_REMOVE, &found);
+
+ if (!(result && found))
+ {
+ elog(WARN, "BufTableDelete: BufferLookup table corrupted");
+ return (FALSE);
+ }
+
+ return (TRUE);
}
bool
-BufTableInsert(BufferDesc *buf)
+BufTableInsert(BufferDesc * buf)
{
- LookupEnt * result;
- bool found;
-
- /* cannot insert it twice */
- Assert (buf->flags & BM_DELETED);
- buf->flags &= ~(BM_DELETED);
-
- result = (LookupEnt *)
- hash_search(SharedBufHash,(char *) &(buf->tag),HASH_ENTER,&found);
-
- if (! result) {
- Assert(0);
- elog(WARN,"BufTableInsert: BufferLookup table corrupted");
- return(FALSE);
- }
- /* found something else in the table ! */
- if (found) {
- Assert(0);
- elog(WARN,"BufTableInsert: BufferLookup table corrupted");
- return(FALSE);
- }
-
- result->id = buf->buf_id;
- return(TRUE);
+ LookupEnt *result;
+ bool found;
+
+ /* cannot insert it twice */
+ Assert(buf->flags & BM_DELETED);
+ buf->flags &= ~(BM_DELETED);
+
+ result = (LookupEnt *)
+ hash_search(SharedBufHash, (char *) &(buf->tag), HASH_ENTER, &found);
+
+ if (!result)
+ {
+ Assert(0);
+ elog(WARN, "BufTableInsert: BufferLookup table corrupted");
+ return (FALSE);
+ }
+ /* found something else in the table ! */
+ if (found)
+ {
+ Assert(0);
+ elog(WARN, "BufTableInsert: BufferLookup table corrupted");
+ return (FALSE);
+ }
+
+ result->id = buf->buf_id;
+ return (TRUE);
}
/* prints out collision stats for the buf table */
@@ -157,8 +165,9 @@ BufTableInsert(BufferDesc *buf)
void
DBG_LookupListCheck(int nlookup)
{
- nlookup = 10;
-
- hash_stats("Shared",SharedBufHash);
+ nlookup = 10;
+
+ hash_stats("Shared", SharedBufHash);
}
+
#endif
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 466728c4a46..2a53e6bd78c 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -1,44 +1,44 @@
/*-------------------------------------------------------------------------
*
* bufmgr.c--
- * buffer manager interface routines
+ * buffer manager interface routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.19 1997/08/19 21:32:39 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.20 1997/09/07 04:48:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
*
* BufferAlloc() -- lookup a buffer in the buffer table. If
- * it isn't there add it, but do not read it into memory.
- * This is used when we are about to reinitialize the
- * buffer so don't care what the current disk contents are.
- * BufferAlloc() pins the new buffer in memory.
+ * it isn't there add it, but do not read it into memory.
+ * This is used when we are about to reinitialize the
+ * buffer so don't care what the current disk contents are.
+ * BufferAlloc() pins the new buffer in memory.
*
* ReadBuffer() -- same as BufferAlloc() but reads the data
- * on a buffer cache miss.
+ * on a buffer cache miss.
*
* ReleaseBuffer() -- unpin the buffer
*
* WriteNoReleaseBuffer() -- mark the buffer contents as "dirty"
- * but don't unpin. The disk IO is delayed until buffer
- * replacement if WriteMode is BUFFER_LATE_WRITE.
+ * but don't unpin. The disk IO is delayed until buffer
+ * replacement if WriteMode is BUFFER_LATE_WRITE.
*
- * WriteBuffer() -- WriteNoReleaseBuffer() + ReleaseBuffer()
+ * WriteBuffer() -- WriteNoReleaseBuffer() + ReleaseBuffer()
*
* FlushBuffer() -- as above but never delayed write.
*
* BufferSync() -- flush all dirty buffers in the buffer pool.
- *
+ *
* InitBufferPool() -- Init the buffer module.
*
- * See other files:
- * freelist.c -- chooses victim for buffer replacement
- * buf_table.c -- manages the buffer lookup table
+ * See other files:
+ * freelist.c -- chooses victim for buffer replacement
+ * buf_table.c -- manages the buffer lookup table
*/
#include <sys/types.h>
#include <sys/file.h>
@@ -66,7 +66,7 @@
#include "utils/palloc.h"
#include "utils/memutils.h"
#include "utils/relcache.h"
-#include "executor/execdebug.h" /* for NDirectFileRead */
+#include "executor/execdebug.h" /* for NDirectFileRead */
#include "catalog/catalog.h"
extern SPINLOCK BufMgrLock;
@@ -77,76 +77,88 @@ extern long int LocalBufferHitCount;
extern long int BufferFlushCount;
extern long int LocalBufferFlushCount;
-static int WriteMode = BUFFER_LATE_WRITE; /* Delayed write is default */
+static int WriteMode = BUFFER_LATE_WRITE; /* Delayed write is
+ * default */
+
+static void WaitIO(BufferDesc * buf, SPINLOCK spinlock);
-static void WaitIO(BufferDesc *buf, SPINLOCK spinlock);
#ifndef HAS_TEST_AND_SET
-static void SignalIO(BufferDesc *buf);
-extern long *NWaitIOBackendP; /* defined in buf_init.c */
-#endif /* HAS_TEST_AND_SET */
-
-static Buffer ReadBufferWithBufferLock(Relation relation, BlockNumber blockNum,
- bool bufferLockHeld);
-static BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
- bool *foundPtr, bool bufferLockHeld);
-static int FlushBuffer (Buffer buffer, bool release);
-static void BufferSync(void);
-static int BufferReplace(BufferDesc *bufHdr, bool bufferLockHeld);
+static void SignalIO(BufferDesc * buf);
+extern long *NWaitIOBackendP;/* defined in buf_init.c */
+
+#endif /* HAS_TEST_AND_SET */
+
+static Buffer
+ReadBufferWithBufferLock(Relation relation, BlockNumber blockNum,
+ bool bufferLockHeld);
+static BufferDesc *
+BufferAlloc(Relation reln, BlockNumber blockNum,
+ bool * foundPtr, bool bufferLockHeld);
+static int FlushBuffer(Buffer buffer, bool release);
+static void BufferSync(void);
+static int BufferReplace(BufferDesc * bufHdr, bool bufferLockHeld);
/* ---------------------------------------------------
* RelationGetBufferWithBuffer
- * see if the given buffer is what we want
- * if yes, we don't need to bother the buffer manager
+ * see if the given buffer is what we want
+ * if yes, we don't need to bother the buffer manager
* ---------------------------------------------------
*/
Buffer
RelationGetBufferWithBuffer(Relation relation,
- BlockNumber blockNumber,
- Buffer buffer)
+ BlockNumber blockNumber,
+ Buffer buffer)
{
- BufferDesc *bufHdr;
- LRelId lrelId;
-
- if (BufferIsValid(buffer)) {
- if (!BufferIsLocal(buffer)) {
- bufHdr = &BufferDescriptors[buffer-1];
- lrelId = RelationGetLRelId(relation);
- SpinAcquire(BufMgrLock);
- if (bufHdr->tag.blockNum == blockNumber &&
- bufHdr->tag.relId.relId == lrelId.relId &&
- bufHdr->tag.relId.dbId == lrelId.dbId) {
- SpinRelease(BufMgrLock);
- return(buffer);
- }
- return(ReadBufferWithBufferLock(relation, blockNumber, true));
- } else {
- bufHdr = &LocalBufferDescriptors[-buffer-1];
- if (bufHdr->tag.relId.relId == relation->rd_id &&
- bufHdr->tag.blockNum == blockNumber) {
- return(buffer);
- }
+ BufferDesc *bufHdr;
+ LRelId lrelId;
+
+ if (BufferIsValid(buffer))
+ {
+ if (!BufferIsLocal(buffer))
+ {
+ bufHdr = &BufferDescriptors[buffer - 1];
+ lrelId = RelationGetLRelId(relation);
+ SpinAcquire(BufMgrLock);
+ if (bufHdr->tag.blockNum == blockNumber &&
+ bufHdr->tag.relId.relId == lrelId.relId &&
+ bufHdr->tag.relId.dbId == lrelId.dbId)
+ {
+ SpinRelease(BufMgrLock);
+ return (buffer);
+ }
+ return (ReadBufferWithBufferLock(relation, blockNumber, true));
+ }
+ else
+ {
+ bufHdr = &LocalBufferDescriptors[-buffer - 1];
+ if (bufHdr->tag.relId.relId == relation->rd_id &&
+ bufHdr->tag.blockNum == blockNumber)
+ {
+ return (buffer);
+ }
+ }
}
- }
- return(ReadBuffer(relation, blockNumber));
+ return (ReadBuffer(relation, blockNumber));
}
/*
* ReadBuffer -- returns a buffer containing the requested
- * block of the requested relation. If the blknum
- * requested is P_NEW, extend the relation file and
- * allocate a new block.
+ * block of the requested relation. If the blknum
+ * requested is P_NEW, extend the relation file and
+ * allocate a new block.
*
* Returns: the buffer number for the buffer containing
- * the block read or NULL on an error.
+ * the block read or NULL on an error.
*
* Assume when this function is called, that reln has been
- * opened already.
+ * opened already.
*/
-extern int ShowPinTrace;
+extern int ShowPinTrace;
-#undef ReadBuffer /* conflicts with macro when BUFMGR_DEBUG defined */
+#undef ReadBuffer /* conflicts with macro when BUFMGR_DEBUG
+ * defined */
/*
* ReadBuffer --
@@ -155,7 +167,7 @@ extern int ShowPinTrace;
Buffer
ReadBuffer(Relation reln, BlockNumber blockNum)
{
- return ReadBufferWithBufferLock(reln, blockNum, false);
+ return ReadBufferWithBufferLock(reln, blockNum, false);
}
/*
@@ -164,156 +176,176 @@ ReadBuffer(Relation reln, BlockNumber blockNum)
* XXX caller must have already acquired BufMgrLock
*/
#ifdef NOT_USED
-static bool
+static bool
is_userbuffer(Buffer buffer)
{
- BufferDesc *buf = &BufferDescriptors[buffer-1];
-
- if (IsSystemRelationName(buf->sb_relname))
- return false;
- return true;
+ BufferDesc *buf = &BufferDescriptors[buffer - 1];
+
+ if (IsSystemRelationName(buf->sb_relname))
+ return false;
+ return true;
}
+
#endif
#ifdef NOT_USED
Buffer
ReadBuffer_Debug(char *file,
- int line,
- Relation reln,
- BlockNumber blockNum)
+ int line,
+ Relation reln,
+ BlockNumber blockNum)
{
- Buffer buffer;
-
- buffer = ReadBufferWithBufferLock(reln, blockNum, false);
- if (ShowPinTrace && !BufferIsLocal(buffer) && is_userbuffer(buffer)) {
- BufferDesc *buf = &BufferDescriptors[buffer-1];
-
- fprintf(stderr, "PIN(RD) %ld relname = %s, blockNum = %d, \
+ Buffer buffer;
+
+ buffer = ReadBufferWithBufferLock(reln, blockNum, false);
+ if (ShowPinTrace && !BufferIsLocal(buffer) && is_userbuffer(buffer))
+ {
+ BufferDesc *buf = &BufferDescriptors[buffer - 1];
+
+ fprintf(stderr, "PIN(RD) %ld relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n",
- buffer, buf->sb_relname, buf->tag.blockNum,
- PrivateRefCount[buffer - 1], file, line);
- }
- return buffer;
+ buffer, buf->sb_relname, buf->tag.blockNum,
+ PrivateRefCount[buffer - 1], file, line);
+ }
+ return buffer;
}
+
#endif
/*
- * ReadBufferWithBufferLock -- does the work of
- * ReadBuffer() but with the possibility that
- * the buffer lock has already been held. this
- * is yet another effort to reduce the number of
- * semops in the system.
+ * ReadBufferWithBufferLock -- does the work of
+ * ReadBuffer() but with the possibility that
+ * the buffer lock has already been held. this
+ * is yet another effort to reduce the number of
+ * semops in the system.
*/
-static Buffer
+static Buffer
ReadBufferWithBufferLock(Relation reln,
- BlockNumber blockNum,
- bool bufferLockHeld)
+ BlockNumber blockNum,
+ bool bufferLockHeld)
{
- BufferDesc *bufHdr;
- int extend; /* extending the file by one block */
- int status;
- bool found;
- bool isLocalBuf;
-
- extend = (blockNum == P_NEW);
- isLocalBuf = reln->rd_islocal;
-
- if (isLocalBuf) {
- ReadLocalBufferCount++;
- bufHdr = LocalBufferAlloc(reln, blockNum, &found);
- if (found) LocalBufferHitCount++;
- } else {
- ReadBufferCount++;
-
- /* lookup the buffer. IO_IN_PROGRESS is set if the requested
- * block is not currently in memory.
- */
- bufHdr = BufferAlloc(reln, blockNum, &found, bufferLockHeld);
- if (found) BufferHitCount++;
- }
-
- if (!bufHdr) {
- return(InvalidBuffer);
- }
-
- /* if its already in the buffer pool, we're done */
- if (found) {
+ BufferDesc *bufHdr;
+ int extend; /* extending the file by one block */
+ int status;
+ bool found;
+ bool isLocalBuf;
+
+ extend = (blockNum == P_NEW);
+ isLocalBuf = reln->rd_islocal;
+
+ if (isLocalBuf)
+ {
+ ReadLocalBufferCount++;
+ bufHdr = LocalBufferAlloc(reln, blockNum, &found);
+ if (found)
+ LocalBufferHitCount++;
+ }
+ else
+ {
+ ReadBufferCount++;
+
+ /*
+ * lookup the buffer. IO_IN_PROGRESS is set if the requested
+ * block is not currently in memory.
+ */
+ bufHdr = BufferAlloc(reln, blockNum, &found, bufferLockHeld);
+ if (found)
+ BufferHitCount++;
+ }
+
+ if (!bufHdr)
+ {
+ return (InvalidBuffer);
+ }
+
+ /* if its already in the buffer pool, we're done */
+ if (found)
+ {
+
+ /*
+ * This happens when a bogus buffer was returned previously and is
+ * floating around in the buffer pool. A routine calling this
+ * would want this extended.
+ */
+ if (extend)
+ {
+ /* new buffers are zero-filled */
+ memset((char *) MAKE_PTR(bufHdr->data), 0, BLCKSZ);
+ smgrextend(bufHdr->bufsmgr, reln,
+ (char *) MAKE_PTR(bufHdr->data));
+ }
+ return (BufferDescriptorGetBuffer(bufHdr));
+
+ }
+
/*
- * This happens when a bogus buffer was returned previously and is
- * floating around in the buffer pool. A routine calling this would
- * want this extended.
+ * if we have gotten to this point, the reln pointer must be ok and
+ * the relation file must be open.
*/
- if (extend) {
- /* new buffers are zero-filled */
- memset((char *) MAKE_PTR(bufHdr->data), 0, BLCKSZ);
- smgrextend(bufHdr->bufsmgr, reln,
- (char *) MAKE_PTR(bufHdr->data));
+ if (extend)
+ {
+ /* new buffers are zero-filled */
+ memset((char *) MAKE_PTR(bufHdr->data), 0, BLCKSZ);
+ status = smgrextend(bufHdr->bufsmgr, reln,
+ (char *) MAKE_PTR(bufHdr->data));
}
- return (BufferDescriptorGetBuffer(bufHdr));
-
- }
-
- /*
- * if we have gotten to this point, the reln pointer must be ok
- * and the relation file must be open.
- */
- if (extend) {
- /* new buffers are zero-filled */
- memset((char *) MAKE_PTR(bufHdr->data), 0, BLCKSZ);
- status = smgrextend(bufHdr->bufsmgr, reln,
- (char *) MAKE_PTR(bufHdr->data));
- } else {
- status = smgrread(bufHdr->bufsmgr, reln, blockNum,
- (char *) MAKE_PTR(bufHdr->data));
- }
-
- if (isLocalBuf)
- return (BufferDescriptorGetBuffer(bufHdr));
+ else
+ {
+ status = smgrread(bufHdr->bufsmgr, reln, blockNum,
+ (char *) MAKE_PTR(bufHdr->data));
+ }
+
+ if (isLocalBuf)
+ return (BufferDescriptorGetBuffer(bufHdr));
+
+ /* lock buffer manager again to update IO IN PROGRESS */
+ SpinAcquire(BufMgrLock);
+
+ if (status == SM_FAIL)
+ {
+ /* IO Failed. cleanup the data structures and go home */
+
+ if (!BufTableDelete(bufHdr))
+ {
+ SpinRelease(BufMgrLock);
+ elog(FATAL, "BufRead: buffer table broken after IO error\n");
+ }
+ /* remember that BufferAlloc() pinned the buffer */
+ UnpinBuffer(bufHdr);
- /* lock buffer manager again to update IO IN PROGRESS */
- SpinAcquire(BufMgrLock);
-
- if (status == SM_FAIL) {
- /* IO Failed. cleanup the data structures and go home */
-
- if (! BufTableDelete(bufHdr)) {
- SpinRelease(BufMgrLock);
- elog(FATAL,"BufRead: buffer table broken after IO error\n");
+ /*
+ * Have to reset the flag so that anyone waiting for the buffer
+ * can tell that the contents are invalid.
+ */
+ bufHdr->flags |= BM_IO_ERROR;
+ bufHdr->flags &= ~BM_IO_IN_PROGRESS;
}
- /* remember that BufferAlloc() pinned the buffer */
- UnpinBuffer(bufHdr);
-
- /*
- * Have to reset the flag so that anyone waiting for
- * the buffer can tell that the contents are invalid.
- */
- bufHdr->flags |= BM_IO_ERROR;
- bufHdr->flags &= ~BM_IO_IN_PROGRESS;
- } else {
- /* IO Succeeded. clear the flags, finish buffer update */
-
- bufHdr->flags &= ~(BM_IO_ERROR | BM_IO_IN_PROGRESS);
- }
-
- /* If anyone was waiting for IO to complete, wake them up now */
+ else
+ {
+ /* IO Succeeded. clear the flags, finish buffer update */
+
+ bufHdr->flags &= ~(BM_IO_ERROR | BM_IO_IN_PROGRESS);
+ }
+
+ /* If anyone was waiting for IO to complete, wake them up now */
#ifdef HAS_TEST_AND_SET
- S_UNLOCK(&(bufHdr->io_in_progress_lock));
+ S_UNLOCK(&(bufHdr->io_in_progress_lock));
#else
- if (bufHdr->refcount > 1)
- SignalIO(bufHdr);
+ if (bufHdr->refcount > 1)
+ SignalIO(bufHdr);
#endif
-
- SpinRelease(BufMgrLock);
-
- if (status == SM_FAIL)
- return(InvalidBuffer);
-
- return(BufferDescriptorGetBuffer(bufHdr));
+
+ SpinRelease(BufMgrLock);
+
+ if (status == SM_FAIL)
+ return (InvalidBuffer);
+
+ return (BufferDescriptorGetBuffer(bufHdr));
}
/*
* BufferAlloc -- Get a buffer from the buffer pool but dont
- * read it.
+ * read it.
*
* Returns: descriptor for buffer
*
@@ -321,321 +353,339 @@ ReadBufferWithBufferLock(Relation reln,
*/
static BufferDesc *
BufferAlloc(Relation reln,
- BlockNumber blockNum,
- bool *foundPtr,
- bool bufferLockHeld)
+ BlockNumber blockNum,
+ bool * foundPtr,
+ bool bufferLockHeld)
{
- BufferDesc *buf, *buf2;
- BufferTag newTag; /* identity of requested block */
- bool inProgress; /* buffer undergoing IO */
- bool newblock = FALSE;
-
- /* create a new tag so we can lookup the buffer */
- /* assume that the relation is already open */
- if (blockNum == P_NEW) {
- newblock = TRUE;
- blockNum = smgrnblocks(reln->rd_rel->relsmgr, reln);
- }
-
- INIT_BUFFERTAG(&newTag,reln,blockNum);
-
- if (!bufferLockHeld)
- SpinAcquire(BufMgrLock);
-
- /* see if the block is in the buffer pool already */
- buf = BufTableLookup(&newTag);
- if (buf != NULL) {
- /* Found it. Now, (a) pin the buffer so no
- * one steals it from the buffer pool,
- * (b) check IO_IN_PROGRESS, someone may be
- * faulting the buffer into the buffer pool.
- */
-
- PinBuffer(buf);
- inProgress = (buf->flags & BM_IO_IN_PROGRESS);
-
- *foundPtr = TRUE;
- if (inProgress) {
- WaitIO(buf, BufMgrLock);
- if (buf->flags & BM_IO_ERROR) {
- /* wierd race condition:
- *
- * We were waiting for someone else to read the buffer.
- * While we were waiting, the reader boof'd in some
- * way, so the contents of the buffer are still
- * invalid. By saying that we didn't find it, we can
- * make the caller reinitialize the buffer. If two
- * processes are waiting for this block, both will
- * read the block. The second one to finish may overwrite
- * any updates made by the first. (Assume higher level
- * synchronization prevents this from happening).
- *
- * This is never going to happen, don't worry about it.
- */
- *foundPtr = FALSE;
- }
+ BufferDesc *buf,
+ *buf2;
+ BufferTag newTag; /* identity of requested block */
+ bool inProgress; /* buffer undergoing IO */
+ bool newblock = FALSE;
+
+ /* create a new tag so we can lookup the buffer */
+ /* assume that the relation is already open */
+ if (blockNum == P_NEW)
+ {
+ newblock = TRUE;
+ blockNum = smgrnblocks(reln->rd_rel->relsmgr, reln);
}
+
+ INIT_BUFFERTAG(&newTag, reln, blockNum);
+
+ if (!bufferLockHeld)
+ SpinAcquire(BufMgrLock);
+
+ /* see if the block is in the buffer pool already */
+ buf = BufTableLookup(&newTag);
+ if (buf != NULL)
+ {
+
+ /*
+ * Found it. Now, (a) pin the buffer so no one steals it from the
+ * buffer pool, (b) check IO_IN_PROGRESS, someone may be faulting
+ * the buffer into the buffer pool.
+ */
+
+ PinBuffer(buf);
+ inProgress = (buf->flags & BM_IO_IN_PROGRESS);
+
+ *foundPtr = TRUE;
+ if (inProgress)
+ {
+ WaitIO(buf, BufMgrLock);
+ if (buf->flags & BM_IO_ERROR)
+ {
+
+ /*
+ * wierd race condition:
+ *
+ * We were waiting for someone else to read the buffer. While
+ * we were waiting, the reader boof'd in some way, so the
+ * contents of the buffer are still invalid. By saying
+ * that we didn't find it, we can make the caller
+ * reinitialize the buffer. If two processes are waiting
+ * for this block, both will read the block. The second
+ * one to finish may overwrite any updates made by the
+ * first. (Assume higher level synchronization prevents
+ * this from happening).
+ *
+ * This is never going to happen, don't worry about it.
+ */
+ *foundPtr = FALSE;
+ }
+ }
#ifdef BMTRACE
- _bm_trace((reln->rd_rel->relisshared ? 0 : MyDatabaseId), reln->rd_id, blockNum, BufferDescriptorGetBuffer(buf), BMT_ALLOCFND);
-#endif /* BMTRACE */
-
- SpinRelease(BufMgrLock);
-
- return(buf);
- }
-
- *foundPtr = FALSE;
-
- /*
- * Didn't find it in the buffer pool. We'll have
- * to initialize a new buffer. First, grab one from
- * the free list. If it's dirty, flush it to disk.
- * Remember to unlock BufMgr spinlock while doing the IOs.
- */
- inProgress = FALSE;
- for (buf = (BufferDesc *) NULL; buf == (BufferDesc *) NULL; ) {
-
- /* GetFreeBuffer will abort if it can't find a free buffer */
- buf = GetFreeBuffer();
-
- /*
- * But it can return buf == NULL if we are in aborting
- * transaction now and so elog(WARN,...) in GetFreeBuffer
- * will not abort again.
- */
- if ( buf == NULL )
- return (NULL);
-
+ _bm_trace((reln->rd_rel->relisshared ? 0 : MyDatabaseId), reln->rd_id, blockNum, BufferDescriptorGetBuffer(buf), BMT_ALLOCFND);
+#endif /* BMTRACE */
+
+ SpinRelease(BufMgrLock);
+
+ return (buf);
+ }
+
+ *foundPtr = FALSE;
+
/*
- * There should be exactly one pin on the buffer after
- * it is allocated -- ours. If it had a pin it wouldn't
- * have been on the free list. No one else could have
- * pinned it between GetFreeBuffer and here because we
- * have the BufMgrLock.
+ * Didn't find it in the buffer pool. We'll have to initialize a new
+ * buffer. First, grab one from the free list. If it's dirty, flush
+ * it to disk. Remember to unlock BufMgr spinlock while doing the IOs.
*/
- Assert(buf->refcount == 0);
- buf->refcount = 1;
- PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 1;
-
- if (buf->flags & BM_DIRTY) {
- bool smok;
- /*
- * Set BM_IO_IN_PROGRESS to keep anyone from doing anything
- * with the contents of the buffer while we write it out.
- * We don't really care if they try to read it, but if they
- * can complete a BufferAlloc on it they can then scribble
- * into it, and we'd really like to avoid that while we are
- * flushing the buffer. Setting this flag should block them
- * in WaitIO until we're done.
- */
- inProgress = TRUE;
- buf->flags |= BM_IO_IN_PROGRESS;
-#ifdef HAS_TEST_AND_SET
- /*
- * All code paths that acquire this lock pin the buffer
- * first; since no one had it pinned (it just came off the
- * free list), no one else can have this lock.
- */
- Assert(S_LOCK_FREE(&(buf->io_in_progress_lock)));
- S_LOCK(&(buf->io_in_progress_lock));
-#endif /* HAS_TEST_AND_SET */
-
- /*
- * Write the buffer out, being careful to release BufMgrLock
- * before starting the I/O.
- *
- * This #ifndef is here because a few extra semops REALLY kill
- * you on machines that don't have spinlocks. If you don't
- * operate with much concurrency, well...
- */
- smok = BufferReplace(buf, true);
-#ifndef OPTIMIZE_SINGLE
- SpinAcquire(BufMgrLock);
-#endif /* OPTIMIZE_SINGLE */
-
- if ( smok == FALSE )
- {
- elog(NOTICE, "BufferAlloc: cannot write block %u for %s/%s",
- buf->tag.blockNum, buf->sb_dbname, buf->sb_relname);
- inProgress = FALSE;
- buf->flags |= BM_IO_ERROR;
- buf->flags &= ~BM_IO_IN_PROGRESS;
-#ifdef HAS_TEST_AND_SET
- S_UNLOCK(&(buf->io_in_progress_lock));
-#else /* !HAS_TEST_AND_SET */
- if (buf->refcount > 1)
- SignalIO(buf);
-#endif /* !HAS_TEST_AND_SET */
- PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0;
- buf->refcount--;
- if ( buf->refcount == 0 )
- {
- AddBufferToFreelist(buf);
- buf->flags |= BM_FREE;
- }
- buf = (BufferDesc *) NULL;
- }
- else
- {
+ inProgress = FALSE;
+ for (buf = (BufferDesc *) NULL; buf == (BufferDesc *) NULL;)
+ {
+
+ /* GetFreeBuffer will abort if it can't find a free buffer */
+ buf = GetFreeBuffer();
+
/*
- * BM_JUST_DIRTIED cleared by BufferReplace and shouldn't
- * be setted by anyone. - vadim 01/17/97
+ * But it can return buf == NULL if we are in aborting transaction
+ * now and so elog(WARN,...) in GetFreeBuffer will not abort
+ * again.
*/
- if ( buf->flags & BM_JUST_DIRTIED )
- {
- elog (FATAL, "BufferAlloc: content of block %u (%s) changed while flushing",
- buf->tag.blockNum, buf->sb_relname);
- }
- else
- {
- buf->flags &= ~BM_DIRTY;
- }
- }
-
- /*
- * Somebody could have pinned the buffer while we were
- * doing the I/O and had given up the BufMgrLock (though
- * they would be waiting for us to clear the BM_IO_IN_PROGRESS
- * flag). That's why this is a loop -- if so, we need to clear
- * the I/O flags, remove our pin and start all over again.
- *
- * People may be making buffers free at any time, so there's
- * no reason to think that we have an immediate disaster on
- * our hands.
- */
- if ( buf && buf->refcount > 1 )
- {
- inProgress = FALSE;
- buf->flags &= ~BM_IO_IN_PROGRESS;
-#ifdef HAS_TEST_AND_SET
- S_UNLOCK(&(buf->io_in_progress_lock));
-#else /* !HAS_TEST_AND_SET */
- if (buf->refcount > 1)
- SignalIO(buf);
-#endif /* !HAS_TEST_AND_SET */
- PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0;
- buf->refcount--;
- buf = (BufferDesc *) NULL;
- }
-
- /*
- * Somebody could have allocated another buffer for the
- * same block we are about to read in. (While we flush out
- * the dirty buffer, we don't hold the lock and someone could
- * have allocated another buffer for the same block. The problem
- * is we haven't gotten around to insert the new tag into
- * the buffer table. So we need to check here. -ay 3/95
- */
- buf2 = BufTableLookup(&newTag);
- if (buf2 != NULL) {
- /* Found it. Someone has already done what we're about
- * to do. We'll just handle this as if it were found in
- * the buffer pool in the first place.
+ if (buf == NULL)
+ return (NULL);
+
+ /*
+ * There should be exactly one pin on the buffer after it is
+ * allocated -- ours. If it had a pin it wouldn't have been on
+ * the free list. No one else could have pinned it between
+ * GetFreeBuffer and here because we have the BufMgrLock.
*/
- if ( buf != NULL )
+ Assert(buf->refcount == 0);
+ buf->refcount = 1;
+ PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 1;
+
+ if (buf->flags & BM_DIRTY)
{
+ bool smok;
+
+ /*
+ * Set BM_IO_IN_PROGRESS to keep anyone from doing anything
+ * with the contents of the buffer while we write it out. We
+ * don't really care if they try to read it, but if they can
+ * complete a BufferAlloc on it they can then scribble into
+ * it, and we'd really like to avoid that while we are
+ * flushing the buffer. Setting this flag should block them
+ * in WaitIO until we're done.
+ */
+ inProgress = TRUE;
+ buf->flags |= BM_IO_IN_PROGRESS;
#ifdef HAS_TEST_AND_SET
- S_UNLOCK(&(buf->io_in_progress_lock));
-#else /* !HAS_TEST_AND_SET */
- if (buf->refcount > 1)
- SignalIO(buf);
-#endif /* !HAS_TEST_AND_SET */
-
- /* give up the buffer since we don't need it any more */
- buf->refcount--;
- PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0;
- AddBufferToFreelist(buf);
- buf->flags |= BM_FREE;
- buf->flags &= ~BM_IO_IN_PROGRESS;
- }
- PinBuffer(buf2);
- inProgress = (buf2->flags & BM_IO_IN_PROGRESS);
-
- *foundPtr = TRUE;
- if (inProgress) {
- WaitIO(buf2, BufMgrLock);
- if (buf2->flags & BM_IO_ERROR) {
- *foundPtr = FALSE;
- }
+ /*
+ * All code paths that acquire this lock pin the buffer first;
+ * since no one had it pinned (it just came off the free
+ * list), no one else can have this lock.
+ */
+ Assert(S_LOCK_FREE(&(buf->io_in_progress_lock)));
+ S_LOCK(&(buf->io_in_progress_lock));
+#endif /* HAS_TEST_AND_SET */
+
+ /*
+ * Write the buffer out, being careful to release BufMgrLock
+ * before starting the I/O.
+ *
+ * This #ifndef is here because a few extra semops REALLY kill
+ * you on machines that don't have spinlocks. If you don't
+ * operate with much concurrency, well...
+ */
+ smok = BufferReplace(buf, true);
+#ifndef OPTIMIZE_SINGLE
+ SpinAcquire(BufMgrLock);
+#endif /* OPTIMIZE_SINGLE */
+
+ if (smok == FALSE)
+ {
+ elog(NOTICE, "BufferAlloc: cannot write block %u for %s/%s",
+ buf->tag.blockNum, buf->sb_dbname, buf->sb_relname);
+ inProgress = FALSE;
+ buf->flags |= BM_IO_ERROR;
+ buf->flags &= ~BM_IO_IN_PROGRESS;
+#ifdef HAS_TEST_AND_SET
+ S_UNLOCK(&(buf->io_in_progress_lock));
+#else /* !HAS_TEST_AND_SET */
+ if (buf->refcount > 1)
+ SignalIO(buf);
+#endif /* !HAS_TEST_AND_SET */
+ PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0;
+ buf->refcount--;
+ if (buf->refcount == 0)
+ {
+ AddBufferToFreelist(buf);
+ buf->flags |= BM_FREE;
+ }
+ buf = (BufferDesc *) NULL;
+ }
+ else
+ {
+
+ /*
+ * BM_JUST_DIRTIED cleared by BufferReplace and shouldn't
+ * be setted by anyone. - vadim 01/17/97
+ */
+ if (buf->flags & BM_JUST_DIRTIED)
+ {
+ elog(FATAL, "BufferAlloc: content of block %u (%s) changed while flushing",
+ buf->tag.blockNum, buf->sb_relname);
+ }
+ else
+ {
+ buf->flags &= ~BM_DIRTY;
+ }
+ }
+
+ /*
+ * Somebody could have pinned the buffer while we were doing
+ * the I/O and had given up the BufMgrLock (though they would
+ * be waiting for us to clear the BM_IO_IN_PROGRESS flag).
+ * That's why this is a loop -- if so, we need to clear the
+ * I/O flags, remove our pin and start all over again.
+ *
+ * People may be making buffers free at any time, so there's no
+ * reason to think that we have an immediate disaster on our
+ * hands.
+ */
+ if (buf && buf->refcount > 1)
+ {
+ inProgress = FALSE;
+ buf->flags &= ~BM_IO_IN_PROGRESS;
+#ifdef HAS_TEST_AND_SET
+ S_UNLOCK(&(buf->io_in_progress_lock));
+#else /* !HAS_TEST_AND_SET */
+ if (buf->refcount > 1)
+ SignalIO(buf);
+#endif /* !HAS_TEST_AND_SET */
+ PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0;
+ buf->refcount--;
+ buf = (BufferDesc *) NULL;
+ }
+
+ /*
+ * Somebody could have allocated another buffer for the same
+ * block we are about to read in. (While we flush out the
+ * dirty buffer, we don't hold the lock and someone could have
+ * allocated another buffer for the same block. The problem is
+ * we haven't gotten around to insert the new tag into the
+ * buffer table. So we need to check here. -ay 3/95
+ */
+ buf2 = BufTableLookup(&newTag);
+ if (buf2 != NULL)
+ {
+
+ /*
+ * Found it. Someone has already done what we're about to
+ * do. We'll just handle this as if it were found in the
+ * buffer pool in the first place.
+ */
+ if (buf != NULL)
+ {
+#ifdef HAS_TEST_AND_SET
+ S_UNLOCK(&(buf->io_in_progress_lock));
+#else /* !HAS_TEST_AND_SET */
+ if (buf->refcount > 1)
+ SignalIO(buf);
+#endif /* !HAS_TEST_AND_SET */
+
+ /* give up the buffer since we don't need it any more */
+ buf->refcount--;
+ PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0;
+ AddBufferToFreelist(buf);
+ buf->flags |= BM_FREE;
+ buf->flags &= ~BM_IO_IN_PROGRESS;
+ }
+
+ PinBuffer(buf2);
+ inProgress = (buf2->flags & BM_IO_IN_PROGRESS);
+
+ *foundPtr = TRUE;
+ if (inProgress)
+ {
+ WaitIO(buf2, BufMgrLock);
+ if (buf2->flags & BM_IO_ERROR)
+ {
+ *foundPtr = FALSE;
+ }
+ }
+
+ SpinRelease(BufMgrLock);
+
+ return (buf2);
+ }
}
-
+ }
+
+ /*
+ * At this point we should have the sole pin on a non-dirty buffer and
+ * we may or may not already have the BM_IO_IN_PROGRESS flag set.
+ */
+
+ /*
+ * Change the name of the buffer in the lookup table:
+ *
+ * Need to update the lookup table before the read starts. If someone
+ * comes along looking for the buffer while we are reading it in, we
+ * don't want them to allocate a new buffer. For the same reason, we
+ * didn't want to erase the buf table entry for the buffer we were
+ * writing back until now, either.
+ */
+
+ if (!BufTableDelete(buf))
+ {
SpinRelease(BufMgrLock);
-
- return(buf2);
- }
+ elog(FATAL, "buffer wasn't in the buffer table\n");
+
}
- }
- /*
- * At this point we should have the sole pin on a non-dirty
- * buffer and we may or may not already have the BM_IO_IN_PROGRESS
- * flag set.
- */
-
- /*
- * Change the name of the buffer in the lookup table:
- *
- * Need to update the lookup table before the read starts.
- * If someone comes along looking for the buffer while
- * we are reading it in, we don't want them to allocate
- * a new buffer. For the same reason, we didn't want
- * to erase the buf table entry for the buffer we were
- * writing back until now, either.
- */
-
- if (! BufTableDelete(buf)) {
- SpinRelease(BufMgrLock);
- elog(FATAL,"buffer wasn't in the buffer table\n");
-
- }
-
- /* record the database name and relation name for this buffer */
- strcpy (buf->sb_relname, reln->rd_rel->relname.data);
- strcpy (buf->sb_dbname, GetDatabaseName());
-
- /* remember which storage manager is responsible for it */
- buf->bufsmgr = reln->rd_rel->relsmgr;
-
- INIT_BUFFERTAG(&(buf->tag),reln,blockNum);
- if (! BufTableInsert(buf)) {
- SpinRelease(BufMgrLock);
- elog(FATAL,"Buffer in lookup table twice \n");
- }
-
- /* Buffer contents are currently invalid. Have
- * to mark IO IN PROGRESS so no one fiddles with
- * them until the read completes. If this routine
- * has been called simply to allocate a buffer, no
- * io will be attempted, so the flag isnt set.
- */
- if (!inProgress) {
- buf->flags |= BM_IO_IN_PROGRESS;
+
+ /* record the database name and relation name for this buffer */
+ strcpy(buf->sb_relname, reln->rd_rel->relname.data);
+ strcpy(buf->sb_dbname, GetDatabaseName());
+
+ /* remember which storage manager is responsible for it */
+ buf->bufsmgr = reln->rd_rel->relsmgr;
+
+ INIT_BUFFERTAG(&(buf->tag), reln, blockNum);
+ if (!BufTableInsert(buf))
+ {
+ SpinRelease(BufMgrLock);
+ elog(FATAL, "Buffer in lookup table twice \n");
+ }
+
+ /*
+ * Buffer contents are currently invalid. Have to mark IO IN PROGRESS
+ * so no one fiddles with them until the read completes. If this
+ * routine has been called simply to allocate a buffer, no io will be
+ * attempted, so the flag isnt set.
+ */
+ if (!inProgress)
+ {
+ buf->flags |= BM_IO_IN_PROGRESS;
#ifdef HAS_TEST_AND_SET
- Assert(S_LOCK_FREE(&(buf->io_in_progress_lock)));
- S_LOCK(&(buf->io_in_progress_lock));
-#endif /* HAS_TEST_AND_SET */
- }
-
+ Assert(S_LOCK_FREE(&(buf->io_in_progress_lock)));
+ S_LOCK(&(buf->io_in_progress_lock));
+#endif /* HAS_TEST_AND_SET */
+ }
+
#ifdef BMTRACE
- _bm_trace((reln->rd_rel->relisshared ? 0 : MyDatabaseId), reln->rd_id, blockNum, BufferDescriptorGetBuffer(buf), BMT_ALLOCNOTFND);
-#endif /* BMTRACE */
-
- SpinRelease(BufMgrLock);
-
- return (buf);
+ _bm_trace((reln->rd_rel->relisshared ? 0 : MyDatabaseId), reln->rd_id, blockNum, BufferDescriptorGetBuffer(buf), BMT_ALLOCNOTFND);
+#endif /* BMTRACE */
+
+ SpinRelease(BufMgrLock);
+
+ return (buf);
}
/*
* WriteBuffer--
*
- * Pushes buffer contents to disk if WriteMode is BUFFER_FLUSH_WRITE.
- * Otherwise, marks contents as dirty.
+ * Pushes buffer contents to disk if WriteMode is BUFFER_FLUSH_WRITE.
+ * Otherwise, marks contents as dirty.
*
* Assume that buffer is pinned. Assume that reln is
- * valid.
+ * valid.
*
* Side Effects:
- * Pin count is decremented.
+ * Pin count is decremented.
*/
#undef WriteBuffer
@@ -643,92 +693,103 @@ BufferAlloc(Relation reln,
int
WriteBuffer(Buffer buffer)
{
- BufferDesc *bufHdr;
+ BufferDesc *bufHdr;
- if (WriteMode == BUFFER_FLUSH_WRITE) {
- return (FlushBuffer (buffer, TRUE));
- } else {
+ if (WriteMode == BUFFER_FLUSH_WRITE)
+ {
+ return (FlushBuffer(buffer, TRUE));
+ }
+ else
+ {
- if (BufferIsLocal(buffer))
- return WriteLocalBuffer(buffer, TRUE);
-
- if (BAD_BUFFER_ID(buffer))
- return(FALSE);
+ if (BufferIsLocal(buffer))
+ return WriteLocalBuffer(buffer, TRUE);
- bufHdr = &BufferDescriptors[buffer-1];
-
- SpinAcquire(BufMgrLock);
- Assert(bufHdr->refcount > 0);
- bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
- UnpinBuffer(bufHdr);
- SpinRelease(BufMgrLock);
- CommitInfoNeedsSave[buffer - 1] = 0;
- }
- return(TRUE);
-}
+ if (BAD_BUFFER_ID(buffer))
+ return (FALSE);
+
+ bufHdr = &BufferDescriptors[buffer - 1];
+
+ SpinAcquire(BufMgrLock);
+ Assert(bufHdr->refcount > 0);
+ bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
+ UnpinBuffer(bufHdr);
+ SpinRelease(BufMgrLock);
+ CommitInfoNeedsSave[buffer - 1] = 0;
+ }
+ return (TRUE);
+}
#ifdef NOT_USED
void
WriteBuffer_Debug(char *file, int line, Buffer buffer)
{
- WriteBuffer(buffer);
- if (ShowPinTrace && BufferIsLocal(buffer) && is_userbuffer(buffer)) {
- BufferDesc *buf;
- buf = &BufferDescriptors[buffer-1];
- fprintf(stderr, "UNPIN(WR) %ld relname = %s, blockNum = %d, \
+ WriteBuffer(buffer);
+ if (ShowPinTrace && BufferIsLocal(buffer) && is_userbuffer(buffer))
+ {
+ BufferDesc *buf;
+
+ buf = &BufferDescriptors[buffer - 1];
+ fprintf(stderr, "UNPIN(WR) %ld relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n",
- buffer, buf->sb_relname, buf->tag.blockNum,
- PrivateRefCount[buffer - 1], file, line);
- }
+ buffer, buf->sb_relname, buf->tag.blockNum,
+ PrivateRefCount[buffer - 1], file, line);
+ }
}
+
#endif
/*
* DirtyBufferCopy() -- For a given dbid/relid/blockno, if the buffer is
- * in the cache and is dirty, mark it clean and copy
- * it to the requested location. This is a logical
- * write, and has been installed to support the cache
- * management code for write-once storage managers.
+ * in the cache and is dirty, mark it clean and copy
+ * it to the requested location. This is a logical
+ * write, and has been installed to support the cache
+ * management code for write-once storage managers.
*
- * DirtyBufferCopy() -- Copy a given dirty buffer to the requested
- * destination.
+ * DirtyBufferCopy() -- Copy a given dirty buffer to the requested
+ * destination.
*
- * We treat this as a write. If the requested buffer is in the pool
- * and is dirty, we copy it to the location requested and mark it
- * clean. This routine supports the Sony jukebox storage manager,
- * which agrees to take responsibility for the data once we mark
- * it clean.
+ * We treat this as a write. If the requested buffer is in the pool
+ * and is dirty, we copy it to the location requested and mark it
+ * clean. This routine supports the Sony jukebox storage manager,
+ * which agrees to take responsibility for the data once we mark
+ * it clean.
*
- * NOTE: used by sony jukebox code in postgres 4.2 - ay 2/95
+ * NOTE: used by sony jukebox code in postgres 4.2 - ay 2/95
*/
#ifdef NOT_USED
void
DirtyBufferCopy(Oid dbid, Oid relid, BlockNumber blkno, char *dest)
{
- BufferDesc *buf;
- BufferTag btag;
-
- btag.relId.relId = relid;
- btag.relId.dbId = dbid;
- btag.blockNum = blkno;
-
- SpinAcquire(BufMgrLock);
- buf = BufTableLookup(&btag);
-
- if (buf == (BufferDesc *) NULL
- || !(buf->flags & BM_DIRTY)
- || !(buf->flags & BM_VALID)) {
+ BufferDesc *buf;
+ BufferTag btag;
+
+ btag.relId.relId = relid;
+ btag.relId.dbId = dbid;
+ btag.blockNum = blkno;
+
+ SpinAcquire(BufMgrLock);
+ buf = BufTableLookup(&btag);
+
+ if (buf == (BufferDesc *) NULL
+ || !(buf->flags & BM_DIRTY)
+ || !(buf->flags & BM_VALID))
+ {
+ SpinRelease(BufMgrLock);
+ return;
+ }
+
+ /*
+ * hate to do this holding the lock, but release and reacquire is
+ * slower
+ */
+ memmove(dest, (char *) MAKE_PTR(buf->data), BLCKSZ);
+
+ buf->flags &= ~BM_DIRTY;
+
SpinRelease(BufMgrLock);
- return;
- }
-
- /* hate to do this holding the lock, but release and reacquire is slower */
- memmove(dest, (char *) MAKE_PTR(buf->data), BLCKSZ);
-
- buf->flags &= ~BM_DIRTY;
-
- SpinRelease(BufMgrLock);
}
+
#endif
/*
@@ -742,504 +803,541 @@ DirtyBufferCopy(Oid dbid, Oid relid, BlockNumber blkno, char *dest)
static int
FlushBuffer(Buffer buffer, bool release)
{
- BufferDesc *bufHdr;
- Oid bufdb;
- Relation bufrel;
- int status;
-
- if (BufferIsLocal(buffer))
- return FlushLocalBuffer(buffer, release);
-
- if (BAD_BUFFER_ID(buffer))
- return (STATUS_ERROR);
-
- bufHdr = &BufferDescriptors[buffer-1];
- bufdb = bufHdr->tag.relId.dbId;
-
- Assert (bufdb == MyDatabaseId || bufdb == (Oid) NULL);
- bufrel = RelationIdCacheGetRelation (bufHdr->tag.relId.relId);
- Assert (bufrel != (Relation) NULL);
-
- /* To check if block content changed while flushing. - vadim 01/17/97 */
- SpinAcquire(BufMgrLock);
- bufHdr->flags &= ~BM_JUST_DIRTIED;
- SpinRelease(BufMgrLock);
-
- status = smgrflush(bufHdr->bufsmgr, bufrel, bufHdr->tag.blockNum,
- (char *) MAKE_PTR(bufHdr->data));
-
- if (status == SM_FAIL)
- {
- elog(WARN, "FlushBuffer: cannot flush block %u of the relation %s",
- bufHdr->tag.blockNum, bufHdr->sb_relname);
- return (STATUS_ERROR);
- }
- BufferFlushCount++;
-
- SpinAcquire(BufMgrLock);
- /*
- * If this buffer was marked by someone as DIRTY while
- * we were flushing it out we must not clear DIRTY flag
- * - vadim 01/17/97
- */
- if ( bufHdr->flags & BM_JUST_DIRTIED )
- {
- elog (NOTICE, "FlusfBuffer: content of block %u (%s) changed while flushing",
- bufHdr->tag.blockNum, bufHdr->sb_relname);
- }
- else
- {
- bufHdr->flags &= ~BM_DIRTY;
- }
- if ( release )
- UnpinBuffer(bufHdr);
- SpinRelease(BufMgrLock);
- CommitInfoNeedsSave[buffer - 1] = 0;
-
- return(STATUS_OK);
+ BufferDesc *bufHdr;
+ Oid bufdb;
+ Relation bufrel;
+ int status;
+
+ if (BufferIsLocal(buffer))
+ return FlushLocalBuffer(buffer, release);
+
+ if (BAD_BUFFER_ID(buffer))
+ return (STATUS_ERROR);
+
+ bufHdr = &BufferDescriptors[buffer - 1];
+ bufdb = bufHdr->tag.relId.dbId;
+
+ Assert(bufdb == MyDatabaseId || bufdb == (Oid) NULL);
+ bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
+ Assert(bufrel != (Relation) NULL);
+
+ /* To check if block content changed while flushing. - vadim 01/17/97 */
+ SpinAcquire(BufMgrLock);
+ bufHdr->flags &= ~BM_JUST_DIRTIED;
+ SpinRelease(BufMgrLock);
+
+ status = smgrflush(bufHdr->bufsmgr, bufrel, bufHdr->tag.blockNum,
+ (char *) MAKE_PTR(bufHdr->data));
+
+ if (status == SM_FAIL)
+ {
+ elog(WARN, "FlushBuffer: cannot flush block %u of the relation %s",
+ bufHdr->tag.blockNum, bufHdr->sb_relname);
+ return (STATUS_ERROR);
+ }
+ BufferFlushCount++;
+
+ SpinAcquire(BufMgrLock);
+
+ /*
+ * If this buffer was marked by someone as DIRTY while we were
+ * flushing it out we must not clear DIRTY flag - vadim 01/17/97
+ */
+ if (bufHdr->flags & BM_JUST_DIRTIED)
+ {
+ elog(NOTICE, "FlusfBuffer: content of block %u (%s) changed while flushing",
+ bufHdr->tag.blockNum, bufHdr->sb_relname);
+ }
+ else
+ {
+ bufHdr->flags &= ~BM_DIRTY;
+ }
+ if (release)
+ UnpinBuffer(bufHdr);
+ SpinRelease(BufMgrLock);
+ CommitInfoNeedsSave[buffer - 1] = 0;
+
+ return (STATUS_OK);
}
/*
* WriteNoReleaseBuffer -- like WriteBuffer, but do not unpin the buffer
- * when the operation is complete.
+ * when the operation is complete.
*
- * We know that the buffer is for a relation in our private cache,
- * because this routine is called only to write out buffers that
- * were changed by the executing backend.
+ * We know that the buffer is for a relation in our private cache,
+ * because this routine is called only to write out buffers that
+ * were changed by the executing backend.
*/
int
WriteNoReleaseBuffer(Buffer buffer)
{
- BufferDesc *bufHdr;
-
- if (WriteMode == BUFFER_FLUSH_WRITE) {
- return (FlushBuffer (buffer, FALSE));
- } else {
+ BufferDesc *bufHdr;
- if (BufferIsLocal(buffer))
- return WriteLocalBuffer(buffer, FALSE);
-
- if (BAD_BUFFER_ID(buffer))
- return (STATUS_ERROR);
+ if (WriteMode == BUFFER_FLUSH_WRITE)
+ {
+ return (FlushBuffer(buffer, FALSE));
+ }
+ else
+ {
- bufHdr = &BufferDescriptors[buffer-1];
-
- SpinAcquire(BufMgrLock);
- bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
- SpinRelease(BufMgrLock);
- CommitInfoNeedsSave[buffer - 1] = 0;
- }
- return(STATUS_OK);
+ if (BufferIsLocal(buffer))
+ return WriteLocalBuffer(buffer, FALSE);
+
+ if (BAD_BUFFER_ID(buffer))
+ return (STATUS_ERROR);
+
+ bufHdr = &BufferDescriptors[buffer - 1];
+
+ SpinAcquire(BufMgrLock);
+ bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
+ SpinRelease(BufMgrLock);
+ CommitInfoNeedsSave[buffer - 1] = 0;
+ }
+ return (STATUS_OK);
}
#undef ReleaseAndReadBuffer
/*
* ReleaseAndReadBuffer -- combine ReleaseBuffer() and ReadBuffer()
- * so that only one semop needs to be called.
+ * so that only one semop needs to be called.
*
*/
Buffer
ReleaseAndReadBuffer(Buffer buffer,
- Relation relation,
- BlockNumber blockNum)
+ Relation relation,
+ BlockNumber blockNum)
{
- BufferDesc *bufHdr;
- Buffer retbuf;
-
- if (BufferIsLocal(buffer)) {
- Assert(LocalRefCount[-buffer - 1] > 0);
- LocalRefCount[-buffer - 1]--;
- } else {
- if (BufferIsValid(buffer)) {
- bufHdr = &BufferDescriptors[buffer-1];
- Assert(PrivateRefCount[buffer - 1] > 0);
- PrivateRefCount[buffer - 1]--;
- if (PrivateRefCount[buffer - 1] == 0 &&
- LastRefCount[buffer - 1] == 0) {
- /* only release buffer if it is not pinned in previous ExecMain
- level */
- SpinAcquire(BufMgrLock);
- bufHdr->refcount--;
- if (bufHdr->refcount == 0) {
- AddBufferToFreelist(bufHdr);
- bufHdr->flags |= BM_FREE;
- }
- if(CommitInfoNeedsSave[buffer - 1]) {
- bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
- CommitInfoNeedsSave[buffer - 1] = 0;
+ BufferDesc *bufHdr;
+ Buffer retbuf;
+
+ if (BufferIsLocal(buffer))
+ {
+ Assert(LocalRefCount[-buffer - 1] > 0);
+ LocalRefCount[-buffer - 1]--;
+ }
+ else
+ {
+ if (BufferIsValid(buffer))
+ {
+ bufHdr = &BufferDescriptors[buffer - 1];
+ Assert(PrivateRefCount[buffer - 1] > 0);
+ PrivateRefCount[buffer - 1]--;
+ if (PrivateRefCount[buffer - 1] == 0 &&
+ LastRefCount[buffer - 1] == 0)
+ {
+
+ /*
+ * only release buffer if it is not pinned in previous
+ * ExecMain level
+ */
+ SpinAcquire(BufMgrLock);
+ bufHdr->refcount--;
+ if (bufHdr->refcount == 0)
+ {
+ AddBufferToFreelist(bufHdr);
+ bufHdr->flags |= BM_FREE;
+ }
+ if (CommitInfoNeedsSave[buffer - 1])
+ {
+ bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
+ CommitInfoNeedsSave[buffer - 1] = 0;
+ }
+ retbuf = ReadBufferWithBufferLock(relation, blockNum, true);
+ return retbuf;
+ }
}
- retbuf = ReadBufferWithBufferLock(relation, blockNum, true);
- return retbuf;
- }
}
- }
- return (ReadBuffer(relation, blockNum));
+ return (ReadBuffer(relation, blockNum));
}
/*
* BufferSync -- Flush all dirty buffers in the pool.
*
- * This is called at transaction commit time. It does the wrong thing,
- * right now. We should flush only our own changes to stable storage,
- * and we should obey the lock protocol on the buffer manager metadata
- * as we do it. Also, we need to be sure that no other transaction is
- * modifying the page as we flush it. This is only a problem for objects
- * that use a non-two-phase locking protocol, like btree indices. For
- * those objects, we would like to set a write lock for the duration of
- * our IO. Another possibility is to code updates to btree pages
- * carefully, so that writing them out out of order cannot cause
- * any unrecoverable errors.
+ * This is called at transaction commit time. It does the wrong thing,
+ * right now. We should flush only our own changes to stable storage,
+ * and we should obey the lock protocol on the buffer manager metadata
+ * as we do it. Also, we need to be sure that no other transaction is
+ * modifying the page as we flush it. This is only a problem for objects
+ * that use a non-two-phase locking protocol, like btree indices. For
+ * those objects, we would like to set a write lock for the duration of
+ * our IO. Another possibility is to code updates to btree pages
+ * carefully, so that writing them out out of order cannot cause
+ * any unrecoverable errors.
*
- * I don't want to think hard about this right now, so I will try
- * to come back to it later.
+ * I don't want to think hard about this right now, so I will try
+ * to come back to it later.
*/
static void
BufferSync()
-{
- int i;
- Oid bufdb;
- Oid bufrel;
- Relation reln;
- BufferDesc *bufHdr;
- int status;
-
- SpinAcquire(BufMgrLock);
- for (i=0, bufHdr = BufferDescriptors; i < NBuffers; i++, bufHdr++) {
- if ((bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY)) {
- bufdb = bufHdr->tag.relId.dbId;
- bufrel = bufHdr->tag.relId.relId;
- if (bufdb == MyDatabaseId || bufdb == (Oid) 0) {
- reln = RelationIdCacheGetRelation(bufrel);
-
- /*
- * We have to pin buffer to keep anyone from stealing it
- * from the buffer pool while we are flushing it or
- * waiting in WaitIO. It's bad for GetFreeBuffer in
- * BufferAlloc, but there is no other way to prevent
- * writing into disk block data from some other buffer,
- * getting smgr status of some other block and
- * clearing BM_DIRTY of ... - VAdim 09/16/96
- */
- PinBuffer(bufHdr);
- if (bufHdr->flags & BM_IO_IN_PROGRESS)
+{
+ int i;
+ Oid bufdb;
+ Oid bufrel;
+ Relation reln;
+ BufferDesc *bufHdr;
+ int status;
+
+ SpinAcquire(BufMgrLock);
+ for (i = 0, bufHdr = BufferDescriptors; i < NBuffers; i++, bufHdr++)
+ {
+ if ((bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY))
{
- WaitIO(bufHdr, BufMgrLock);
- UnpinBuffer(bufHdr);
- if (bufHdr->flags & BM_IO_ERROR)
- {
- elog(WARN, "BufferSync: write error %u for %s",
- bufHdr->tag.blockNum, bufHdr->sb_relname);
- }
- if (reln != (Relation)NULL)
- RelationDecrementReferenceCount(reln);
- continue;
- }
-
- /*
- * To check if block content changed while flushing
- * (see below). - vadim 01/17/97
- */
- bufHdr->flags &= ~BM_JUST_DIRTIED;
+ bufdb = bufHdr->tag.relId.dbId;
+ bufrel = bufHdr->tag.relId.relId;
+ if (bufdb == MyDatabaseId || bufdb == (Oid) 0)
+ {
+ reln = RelationIdCacheGetRelation(bufrel);
+
+ /*
+ * We have to pin buffer to keep anyone from stealing it
+ * from the buffer pool while we are flushing it or
+ * waiting in WaitIO. It's bad for GetFreeBuffer in
+ * BufferAlloc, but there is no other way to prevent
+ * writing into disk block data from some other buffer,
+ * getting smgr status of some other block and clearing
+ * BM_DIRTY of ... - VAdim 09/16/96
+ */
+ PinBuffer(bufHdr);
+ if (bufHdr->flags & BM_IO_IN_PROGRESS)
+ {
+ WaitIO(bufHdr, BufMgrLock);
+ UnpinBuffer(bufHdr);
+ if (bufHdr->flags & BM_IO_ERROR)
+ {
+ elog(WARN, "BufferSync: write error %u for %s",
+ bufHdr->tag.blockNum, bufHdr->sb_relname);
+ }
+ if (reln != (Relation) NULL)
+ RelationDecrementReferenceCount(reln);
+ continue;
+ }
+
+ /*
+ * To check if block content changed while flushing (see
+ * below). - vadim 01/17/97
+ */
+ bufHdr->flags &= ~BM_JUST_DIRTIED;
+
+ /*
+ * If we didn't have the reldesc in our local cache, flush
+ * this page out using the 'blind write' storage manager
+ * routine. If we did find it, use the standard
+ * interface.
+ */
- /*
- * If we didn't have the reldesc in our local cache, flush this
- * page out using the 'blind write' storage manager routine. If
- * we did find it, use the standard interface.
- */
-
#ifndef OPTIMIZE_SINGLE
- SpinRelease(BufMgrLock);
-#endif /* OPTIMIZE_SINGLE */
- if (reln == (Relation) NULL) {
- status = smgrblindwrt(bufHdr->bufsmgr, bufHdr->sb_dbname,
- bufHdr->sb_relname, bufdb, bufrel,
- bufHdr->tag.blockNum,
- (char *) MAKE_PTR(bufHdr->data));
- } else {
- status = smgrwrite(bufHdr->bufsmgr, reln,
- bufHdr->tag.blockNum,
- (char *) MAKE_PTR(bufHdr->data));
- }
+ SpinRelease(BufMgrLock);
+#endif /* OPTIMIZE_SINGLE */
+ if (reln == (Relation) NULL)
+ {
+ status = smgrblindwrt(bufHdr->bufsmgr, bufHdr->sb_dbname,
+ bufHdr->sb_relname, bufdb, bufrel,
+ bufHdr->tag.blockNum,
+ (char *) MAKE_PTR(bufHdr->data));
+ }
+ else
+ {
+ status = smgrwrite(bufHdr->bufsmgr, reln,
+ bufHdr->tag.blockNum,
+ (char *) MAKE_PTR(bufHdr->data));
+ }
#ifndef OPTIMIZE_SINGLE
- SpinAcquire(BufMgrLock);
-#endif /* OPTIMIZE_SINGLE */
-
- UnpinBuffer(bufHdr);
- if (status == SM_FAIL) {
- bufHdr->flags |= BM_IO_ERROR;
- elog(WARN, "BufferSync: cannot write %u for %s",
- bufHdr->tag.blockNum, bufHdr->sb_relname);
- }
- BufferFlushCount++;
- /*
- * If this buffer was marked by someone as DIRTY while
- * we were flushing it out we must not clear DIRTY flag
- * - vadim 01/17/97
- */
- if ( bufHdr->flags & BM_JUST_DIRTIED )
- {
- elog (NOTICE, "BufferSync: content of block %u (%s) changed while flushing",
- bufHdr->tag.blockNum, bufHdr->sb_relname);
- }
- else
- {
- bufHdr->flags &= ~BM_DIRTY;
+ SpinAcquire(BufMgrLock);
+#endif /* OPTIMIZE_SINGLE */
+
+ UnpinBuffer(bufHdr);
+ if (status == SM_FAIL)
+ {
+ bufHdr->flags |= BM_IO_ERROR;
+ elog(WARN, "BufferSync: cannot write %u for %s",
+ bufHdr->tag.blockNum, bufHdr->sb_relname);
+ }
+ BufferFlushCount++;
+
+ /*
+ * If this buffer was marked by someone as DIRTY while we
+ * were flushing it out we must not clear DIRTY flag -
+ * vadim 01/17/97
+ */
+ if (bufHdr->flags & BM_JUST_DIRTIED)
+ {
+ elog(NOTICE, "BufferSync: content of block %u (%s) changed while flushing",
+ bufHdr->tag.blockNum, bufHdr->sb_relname);
+ }
+ else
+ {
+ bufHdr->flags &= ~BM_DIRTY;
+ }
+ if (reln != (Relation) NULL)
+ RelationDecrementReferenceCount(reln);
+ }
}
- if (reln != (Relation)NULL)
- RelationDecrementReferenceCount(reln);
- }
}
- }
- SpinRelease(BufMgrLock);
+ SpinRelease(BufMgrLock);
- LocalBufferSync();
+ LocalBufferSync();
}
/*
* WaitIO -- Block until the IO_IN_PROGRESS flag on 'buf'
- * is cleared. Because IO_IN_PROGRESS conflicts are
- * expected to be rare, there is only one BufferIO
- * lock in the entire system. All processes block
- * on this semaphore when they try to use a buffer
- * that someone else is faulting in. Whenever a
- * process finishes an IO and someone is waiting for
- * the buffer, BufferIO is signaled (SignalIO). All
- * waiting processes then wake up and check to see
- * if their buffer is now ready. This implementation
- * is simple, but efficient enough if WaitIO is
- * rarely called by multiple processes simultaneously.
+ * is cleared. Because IO_IN_PROGRESS conflicts are
+ * expected to be rare, there is only one BufferIO
+ * lock in the entire system. All processes block
+ * on this semaphore when they try to use a buffer
+ * that someone else is faulting in. Whenever a
+ * process finishes an IO and someone is waiting for
+ * the buffer, BufferIO is signaled (SignalIO). All
+ * waiting processes then wake up and check to see
+ * if their buffer is now ready. This implementation
+ * is simple, but efficient enough if WaitIO is
+ * rarely called by multiple processes simultaneously.
*
- * ProcSleep atomically releases the spinlock and goes to
- * sleep.
+ * ProcSleep atomically releases the spinlock and goes to
+ * sleep.
*
- * Note: there is an easy fix if the queue becomes long.
- * save the id of the buffer we are waiting for in
- * the queue structure. That way signal can figure
- * out which proc to wake up.
+ * Note: there is an easy fix if the queue becomes long.
+ * save the id of the buffer we are waiting for in
+ * the queue structure. That way signal can figure
+ * out which proc to wake up.
*/
#ifdef HAS_TEST_AND_SET
static void
-WaitIO(BufferDesc *buf, SPINLOCK spinlock)
+WaitIO(BufferDesc * buf, SPINLOCK spinlock)
{
- SpinRelease(spinlock);
- S_LOCK(&(buf->io_in_progress_lock));
- S_UNLOCK(&(buf->io_in_progress_lock));
- SpinAcquire(spinlock);
+ SpinRelease(spinlock);
+ S_LOCK(&(buf->io_in_progress_lock));
+ S_UNLOCK(&(buf->io_in_progress_lock));
+ SpinAcquire(spinlock);
}
-#else /* HAS_TEST_AND_SET */
-IpcSemaphoreId WaitIOSemId;
+#else /* HAS_TEST_AND_SET */
+IpcSemaphoreId WaitIOSemId;
static void
-WaitIO(BufferDesc *buf, SPINLOCK spinlock)
+WaitIO(BufferDesc * buf, SPINLOCK spinlock)
{
- bool inProgress;
-
- for (;;) {
-
- /* wait until someone releases IO lock */
- (*NWaitIOBackendP)++;
- SpinRelease(spinlock);
- IpcSemaphoreLock(WaitIOSemId, 0, 1);
- SpinAcquire(spinlock);
- inProgress = (buf->flags & BM_IO_IN_PROGRESS);
- if (!inProgress) break;
- }
+ bool inProgress;
+
+ for (;;)
+ {
+
+ /* wait until someone releases IO lock */
+ (*NWaitIOBackendP)++;
+ SpinRelease(spinlock);
+ IpcSemaphoreLock(WaitIOSemId, 0, 1);
+ SpinAcquire(spinlock);
+ inProgress = (buf->flags & BM_IO_IN_PROGRESS);
+ if (!inProgress)
+ break;
+ }
}
/*
* SignalIO --
*/
static void
-SignalIO(BufferDesc *buf)
+SignalIO(BufferDesc * buf)
{
- /* somebody better be waiting. */
- Assert( buf->refcount > 1);
- IpcSemaphoreUnlock(WaitIOSemId, 0, *NWaitIOBackendP);
- *NWaitIOBackendP = 0;
+ /* somebody better be waiting. */
+ Assert(buf->refcount > 1);
+ IpcSemaphoreUnlock(WaitIOSemId, 0, *NWaitIOBackendP);
+ *NWaitIOBackendP = 0;
}
-#endif /* HAS_TEST_AND_SET */
-long NDirectFileRead; /* some I/O's are direct file access. bypass bufmgr */
-long NDirectFileWrite; /* e.g., I/O in psort and hashjoin. */
+#endif /* HAS_TEST_AND_SET */
+
+long NDirectFileRead;/* some I/O's are direct file access.
+ * bypass bufmgr */
+long NDirectFileWrite; /* e.g., I/O in psort and
+ * hashjoin. */
void
-PrintBufferUsage(FILE *statfp)
+PrintBufferUsage(FILE * statfp)
{
- float hitrate;
- float localhitrate;
-
- if (ReadBufferCount==0)
- hitrate = 0.0;
- else
- hitrate = (float)BufferHitCount * 100.0/ReadBufferCount;
-
- if (ReadLocalBufferCount==0)
- localhitrate = 0.0;
- else
- localhitrate = (float)LocalBufferHitCount * 100.0/ReadLocalBufferCount;
-
- fprintf(statfp, "!\tShared blocks: %10ld read, %10ld written, buffer hit rate = %.2f%%\n",
- ReadBufferCount - BufferHitCount, BufferFlushCount, hitrate);
- fprintf(statfp, "!\tLocal blocks: %10ld read, %10ld written, buffer hit rate = %.2f%%\n",
- ReadLocalBufferCount - LocalBufferHitCount, LocalBufferFlushCount, localhitrate);
- fprintf(statfp, "!\tDirect blocks: %10ld read, %10ld written\n",
- NDirectFileRead, NDirectFileWrite);
+ float hitrate;
+ float localhitrate;
+
+ if (ReadBufferCount == 0)
+ hitrate = 0.0;
+ else
+ hitrate = (float) BufferHitCount *100.0 / ReadBufferCount;
+
+ if (ReadLocalBufferCount == 0)
+ localhitrate = 0.0;
+ else
+ localhitrate = (float) LocalBufferHitCount *100.0 / ReadLocalBufferCount;
+
+ fprintf(statfp, "!\tShared blocks: %10ld read, %10ld written, buffer hit rate = %.2f%%\n",
+ ReadBufferCount - BufferHitCount, BufferFlushCount, hitrate);
+ fprintf(statfp, "!\tLocal blocks: %10ld read, %10ld written, buffer hit rate = %.2f%%\n",
+ ReadLocalBufferCount - LocalBufferHitCount, LocalBufferFlushCount, localhitrate);
+ fprintf(statfp, "!\tDirect blocks: %10ld read, %10ld written\n",
+ NDirectFileRead, NDirectFileWrite);
}
void
ResetBufferUsage()
{
- BufferHitCount = 0;
- ReadBufferCount = 0;
- BufferFlushCount = 0;
- LocalBufferHitCount = 0;
- ReadLocalBufferCount = 0;
- LocalBufferFlushCount = 0;
- NDirectFileRead = 0;
- NDirectFileWrite = 0;
+ BufferHitCount = 0;
+ ReadBufferCount = 0;
+ BufferFlushCount = 0;
+ LocalBufferHitCount = 0;
+ ReadLocalBufferCount = 0;
+ LocalBufferFlushCount = 0;
+ NDirectFileRead = 0;
+ NDirectFileWrite = 0;
}
/* ----------------------------------------------
- * ResetBufferPool
+ * ResetBufferPool
*
- * this routine is supposed to be called when a transaction aborts.
- * it will release all the buffer pins held by the transaciton.
+ * this routine is supposed to be called when a transaction aborts.
+ * it will release all the buffer pins held by the transaciton.
*
* ----------------------------------------------
*/
void
ResetBufferPool()
{
- register int i;
- for (i=1; i<=NBuffers; i++) {
- CommitInfoNeedsSave[i - 1] = 0;
- if (BufferIsValid(i)) {
- while(PrivateRefCount[i - 1] > 0) {
- ReleaseBuffer(i);
- }
+ register int i;
+
+ for (i = 1; i <= NBuffers; i++)
+ {
+ CommitInfoNeedsSave[i - 1] = 0;
+ if (BufferIsValid(i))
+ {
+ while (PrivateRefCount[i - 1] > 0)
+ {
+ ReleaseBuffer(i);
+ }
+ }
+ LastRefCount[i - 1] = 0;
}
- LastRefCount[i - 1] = 0;
- }
- ResetLocalBufferPool();
+ ResetLocalBufferPool();
}
/* -----------------------------------------------
- * BufferPoolCheckLeak
+ * BufferPoolCheckLeak
*
- * check if there is buffer leak
+ * check if there is buffer leak
*
* -----------------------------------------------
*/
int
BufferPoolCheckLeak()
{
- register int i;
- int error = 0;
-
- for (i = 1; i <= NBuffers; i++) {
- if (BufferIsValid(i)) {
- elog(NOTICE,
- "buffer leak [%d] detected in BufferPoolCheckLeak()", i-1);
- error = 1;
+ register int i;
+ int error = 0;
+
+ for (i = 1; i <= NBuffers; i++)
+ {
+ if (BufferIsValid(i))
+ {
+ elog(NOTICE,
+ "buffer leak [%d] detected in BufferPoolCheckLeak()", i - 1);
+ error = 1;
+ }
}
- }
- if(error) {
- PrintBufferDescs();
- return(1);
- }
- return(0);
+ if (error)
+ {
+ PrintBufferDescs();
+ return (1);
+ }
+ return (0);
}
/* ------------------------------------------------
- * FlushBufferPool
+ * FlushBufferPool
*
- * flush all dirty blocks in buffer pool to disk
+ * flush all dirty blocks in buffer pool to disk
*
* ------------------------------------------------
*/
void
FlushBufferPool(int StableMainMemoryFlag)
{
- if (!StableMainMemoryFlag) {
- BufferSync();
- smgrcommit();
- }
+ if (!StableMainMemoryFlag)
+ {
+ BufferSync();
+ smgrcommit();
+ }
}
/*
* BufferIsValid --
- * True iff the refcnt of the local buffer is > 0
+ * True iff the refcnt of the local buffer is > 0
* Note:
- * BufferIsValid(InvalidBuffer) is False.
- * BufferIsValid(UnknownBuffer) is False.
+ * BufferIsValid(InvalidBuffer) is False.
+ * BufferIsValid(UnknownBuffer) is False.
*/
bool
BufferIsValid(Buffer bufnum)
{
- if (BufferIsLocal(bufnum))
- return (bufnum >= -NLocBuffer && LocalRefCount[-bufnum - 1] > 0);
-
- if (BAD_BUFFER_ID(bufnum))
- return(false);
+ if (BufferIsLocal(bufnum))
+ return (bufnum >= -NLocBuffer && LocalRefCount[-bufnum - 1] > 0);
- return ((bool)(PrivateRefCount[bufnum - 1] > 0));
+ if (BAD_BUFFER_ID(bufnum))
+ return (false);
+
+ return ((bool) (PrivateRefCount[bufnum - 1] > 0));
}
/*
* BufferGetBlockNumber --
- * Returns the block number associated with a buffer.
+ * Returns the block number associated with a buffer.
*
* Note:
- * Assumes that the buffer is valid.
+ * Assumes that the buffer is valid.
*/
BlockNumber
BufferGetBlockNumber(Buffer buffer)
{
- Assert(BufferIsValid(buffer));
+ Assert(BufferIsValid(buffer));
- /* XXX should be a critical section */
- if (BufferIsLocal(buffer))
- return (LocalBufferDescriptors[-buffer-1].tag.blockNum);
- else
- return (BufferDescriptors[buffer-1].tag.blockNum);
+ /* XXX should be a critical section */
+ if (BufferIsLocal(buffer))
+ return (LocalBufferDescriptors[-buffer - 1].tag.blockNum);
+ else
+ return (BufferDescriptors[buffer - 1].tag.blockNum);
}
/*
* BufferGetRelation --
- * Returns the relation desciptor associated with a buffer.
+ * Returns the relation desciptor associated with a buffer.
*
* Note:
- * Assumes buffer is valid.
+ * Assumes buffer is valid.
*/
Relation
BufferGetRelation(Buffer buffer)
{
- Relation relation;
- Oid relid;
-
- Assert(BufferIsValid(buffer));
- Assert(!BufferIsLocal(buffer)); /* not supported for local buffers */
-
- /* XXX should be a critical section */
- relid = LRelIdGetRelationId(BufferDescriptors[buffer-1].tag.relId);
- relation = RelationIdGetRelation(relid);
-
- RelationDecrementReferenceCount(relation);
-
- if (RelationHasReferenceCountZero(relation)) {
- /*
- elog(NOTICE, "BufferGetRelation: 0->1");
- */
-
- RelationIncrementReferenceCount(relation);
- }
-
- return (relation);
+ Relation relation;
+ Oid relid;
+
+ Assert(BufferIsValid(buffer));
+ Assert(!BufferIsLocal(buffer)); /* not supported for local buffers */
+
+ /* XXX should be a critical section */
+ relid = LRelIdGetRelationId(BufferDescriptors[buffer - 1].tag.relId);
+ relation = RelationIdGetRelation(relid);
+
+ RelationDecrementReferenceCount(relation);
+
+ if (RelationHasReferenceCountZero(relation))
+ {
+
+ /*
+ * elog(NOTICE, "BufferGetRelation: 0->1");
+ */
+
+ RelationIncrementReferenceCount(relation);
+ }
+
+ return (relation);
}
/*
@@ -1249,217 +1347,232 @@ BufferGetRelation(Buffer buffer)
*
*/
static int
-BufferReplace(BufferDesc *bufHdr, bool bufferLockHeld)
+BufferReplace(BufferDesc * bufHdr, bool bufferLockHeld)
{
- Relation reln;
- Oid bufdb, bufrel;
- int status;
-
- if (!bufferLockHeld)
- SpinAcquire(BufMgrLock);
-
- /*
- * first try to find the reldesc in the cache, if no luck,
- * don't bother to build the reldesc from scratch, just do
- * a blind write.
- */
-
- bufdb = bufHdr->tag.relId.dbId;
- bufrel = bufHdr->tag.relId.relId;
-
- if (bufdb == MyDatabaseId || bufdb == (Oid) NULL)
- reln = RelationIdCacheGetRelation(bufrel);
- else
- reln = (Relation) NULL;
-
- /* To check if block content changed while flushing. - vadim 01/17/97 */
- bufHdr->flags &= ~BM_JUST_DIRTIED;
-
- SpinRelease(BufMgrLock);
-
- if (reln != (Relation) NULL) {
- status = smgrflush(bufHdr->bufsmgr, reln, bufHdr->tag.blockNum,
- (char *) MAKE_PTR(bufHdr->data));
- } else {
-
- /* blind write always flushes */
- status = smgrblindwrt(bufHdr->bufsmgr, bufHdr->sb_dbname,
- bufHdr->sb_relname, bufdb, bufrel,
- bufHdr->tag.blockNum,
- (char *) MAKE_PTR(bufHdr->data));
- }
-
- if (status == SM_FAIL)
- return (FALSE);
-
- BufferFlushCount++;
-
- return (TRUE);
+ Relation reln;
+ Oid bufdb,
+ bufrel;
+ int status;
+
+ if (!bufferLockHeld)
+ SpinAcquire(BufMgrLock);
+
+ /*
+ * first try to find the reldesc in the cache, if no luck, don't
+ * bother to build the reldesc from scratch, just do a blind write.
+ */
+
+ bufdb = bufHdr->tag.relId.dbId;
+ bufrel = bufHdr->tag.relId.relId;
+
+ if (bufdb == MyDatabaseId || bufdb == (Oid) NULL)
+ reln = RelationIdCacheGetRelation(bufrel);
+ else
+ reln = (Relation) NULL;
+
+ /* To check if block content changed while flushing. - vadim 01/17/97 */
+ bufHdr->flags &= ~BM_JUST_DIRTIED;
+
+ SpinRelease(BufMgrLock);
+
+ if (reln != (Relation) NULL)
+ {
+ status = smgrflush(bufHdr->bufsmgr, reln, bufHdr->tag.blockNum,
+ (char *) MAKE_PTR(bufHdr->data));
+ }
+ else
+ {
+
+ /* blind write always flushes */
+ status = smgrblindwrt(bufHdr->bufsmgr, bufHdr->sb_dbname,
+ bufHdr->sb_relname, bufdb, bufrel,
+ bufHdr->tag.blockNum,
+ (char *) MAKE_PTR(bufHdr->data));
+ }
+
+ if (status == SM_FAIL)
+ return (FALSE);
+
+ BufferFlushCount++;
+
+ return (TRUE);
}
/*
* RelationGetNumberOfBlocks --
- * Returns the buffer descriptor associated with a page in a relation.
+ * Returns the buffer descriptor associated with a page in a relation.
*
* Note:
- * XXX may fail for huge relations.
- * XXX should be elsewhere.
- * XXX maybe should be hidden
+ * XXX may fail for huge relations.
+ * XXX should be elsewhere.
+ * XXX maybe should be hidden
*/
BlockNumber
RelationGetNumberOfBlocks(Relation relation)
{
- return
- ((relation->rd_islocal) ? relation->rd_nblocks :
- smgrnblocks(relation->rd_rel->relsmgr, relation));
+ return
+ ((relation->rd_islocal) ? relation->rd_nblocks :
+ smgrnblocks(relation->rd_rel->relsmgr, relation));
}
/*
* BufferGetBlock --
- * Returns a reference to a disk page image associated with a buffer.
+ * Returns a reference to a disk page image associated with a buffer.
*
* Note:
- * Assumes buffer is valid.
+ * Assumes buffer is valid.
*/
Block
BufferGetBlock(Buffer buffer)
{
- Assert(BufferIsValid(buffer));
+ Assert(BufferIsValid(buffer));
- if (BufferIsLocal(buffer))
- return((Block)MAKE_PTR(LocalBufferDescriptors[-buffer-1].data));
- else
- return((Block)MAKE_PTR(BufferDescriptors[buffer-1].data));
+ if (BufferIsLocal(buffer))
+ return ((Block) MAKE_PTR(LocalBufferDescriptors[-buffer - 1].data));
+ else
+ return ((Block) MAKE_PTR(BufferDescriptors[buffer - 1].data));
}
/* ---------------------------------------------------------------------
- * ReleaseRelationBuffers
+ * ReleaseRelationBuffers
*
- * this function unmarks all the dirty pages of a relation
- * in the buffer pool so that at the end of transaction
- * these pages will not be flushed.
- * XXX currently it sequentially searches the buffer pool, should be
- * changed to more clever ways of searching.
+ * this function unmarks all the dirty pages of a relation
+ * in the buffer pool so that at the end of transaction
+ * these pages will not be flushed.
+ * XXX currently it sequentially searches the buffer pool, should be
+ * changed to more clever ways of searching.
* --------------------------------------------------------------------
*/
void
-ReleaseRelationBuffers (Relation rdesc)
+ReleaseRelationBuffers(Relation rdesc)
{
- register int i;
- int holding = 0;
- BufferDesc *buf;
-
- if ( rdesc->rd_islocal )
- {
- for (i = 0; i < NLocBuffer; i++)
- {
- buf = &LocalBufferDescriptors[i];
- if ((buf->flags & BM_DIRTY) &&
- (buf->tag.relId.relId == rdesc->rd_id))
- {
- buf->flags &= ~BM_DIRTY;
- }
- }
- return;
- }
-
- for (i=1; i<=NBuffers; i++) {
- buf = &BufferDescriptors[i-1];
- if (!holding) {
- SpinAcquire(BufMgrLock);
- holding = 1;
+ register int i;
+ int holding = 0;
+ BufferDesc *buf;
+
+ if (rdesc->rd_islocal)
+ {
+ for (i = 0; i < NLocBuffer; i++)
+ {
+ buf = &LocalBufferDescriptors[i];
+ if ((buf->flags & BM_DIRTY) &&
+ (buf->tag.relId.relId == rdesc->rd_id))
+ {
+ buf->flags &= ~BM_DIRTY;
+ }
+ }
+ return;
}
- if ((buf->flags & BM_DIRTY) &&
- (buf->tag.relId.dbId == MyDatabaseId) &&
- (buf->tag.relId.relId == rdesc->rd_id)) {
- buf->flags &= ~BM_DIRTY;
- if (!(buf->flags & BM_FREE)) {
- SpinRelease(BufMgrLock);
- holding = 0;
- ReleaseBuffer(i);
- }
+
+ for (i = 1; i <= NBuffers; i++)
+ {
+ buf = &BufferDescriptors[i - 1];
+ if (!holding)
+ {
+ SpinAcquire(BufMgrLock);
+ holding = 1;
+ }
+ if ((buf->flags & BM_DIRTY) &&
+ (buf->tag.relId.dbId == MyDatabaseId) &&
+ (buf->tag.relId.relId == rdesc->rd_id))
+ {
+ buf->flags &= ~BM_DIRTY;
+ if (!(buf->flags & BM_FREE))
+ {
+ SpinRelease(BufMgrLock);
+ holding = 0;
+ ReleaseBuffer(i);
+ }
+ }
}
- }
- if (holding)
- SpinRelease(BufMgrLock);
+ if (holding)
+ SpinRelease(BufMgrLock);
}
/* ---------------------------------------------------------------------
- * DropBuffers
+ * DropBuffers
*
- * This function marks all the buffers in the buffer cache for a
- * particular database as clean. This is used when we destroy a
- * database, to avoid trying to flush data to disk when the directory
- * tree no longer exists.
+ * This function marks all the buffers in the buffer cache for a
+ * particular database as clean. This is used when we destroy a
+ * database, to avoid trying to flush data to disk when the directory
+ * tree no longer exists.
*
- * This is an exceedingly non-public interface.
+ * This is an exceedingly non-public interface.
* --------------------------------------------------------------------
*/
void
DropBuffers(Oid dbid)
{
- register int i;
- BufferDesc *buf;
-
- SpinAcquire(BufMgrLock);
- for (i=1; i<=NBuffers; i++) {
- buf = &BufferDescriptors[i-1];
- if ((buf->tag.relId.dbId == dbid) && (buf->flags & BM_DIRTY)) {
- buf->flags &= ~BM_DIRTY;
- }
- }
- SpinRelease(BufMgrLock);
+ register int i;
+ BufferDesc *buf;
+
+ SpinAcquire(BufMgrLock);
+ for (i = 1; i <= NBuffers; i++)
+ {
+ buf = &BufferDescriptors[i - 1];
+ if ((buf->tag.relId.dbId == dbid) && (buf->flags & BM_DIRTY))
+ {
+ buf->flags &= ~BM_DIRTY;
+ }
+ }
+ SpinRelease(BufMgrLock);
}
/* -----------------------------------------------------------------
- * PrintBufferDescs
+ * PrintBufferDescs
*
- * this function prints all the buffer descriptors, for debugging
- * use only.
+ * this function prints all the buffer descriptors, for debugging
+ * use only.
* -----------------------------------------------------------------
*/
void
PrintBufferDescs()
{
- int i;
- BufferDesc *buf = BufferDescriptors;
+ int i;
+ BufferDesc *buf = BufferDescriptors;
- if (IsUnderPostmaster) {
- SpinAcquire(BufMgrLock);
- for (i = 0; i < NBuffers; ++i, ++buf) {
- elog(NOTICE, "[%02d] (freeNext=%d, freePrev=%d, relname=%s, \
+ if (IsUnderPostmaster)
+ {
+ SpinAcquire(BufMgrLock);
+ for (i = 0; i < NBuffers; ++i, ++buf)
+ {
+ elog(NOTICE, "[%02d] (freeNext=%d, freePrev=%d, relname=%s, \
blockNum=%d, flags=0x%x, refcount=%d %d)",
- i, buf->freeNext, buf->freePrev,
- buf->sb_relname, buf->tag.blockNum, buf->flags,
- buf->refcount, PrivateRefCount[i]);
+ i, buf->freeNext, buf->freePrev,
+ buf->sb_relname, buf->tag.blockNum, buf->flags,
+ buf->refcount, PrivateRefCount[i]);
+ }
+ SpinRelease(BufMgrLock);
}
- SpinRelease(BufMgrLock);
- } else {
- /* interactive backend */
- for (i = 0; i < NBuffers; ++i, ++buf) {
- printf("[%-2d] (%s, %d) flags=0x%x, refcnt=%d %ld)\n",
- i, buf->sb_relname, buf->tag.blockNum,
- buf->flags, buf->refcount, PrivateRefCount[i]);
+ else
+ {
+ /* interactive backend */
+ for (i = 0; i < NBuffers; ++i, ++buf)
+ {
+ printf("[%-2d] (%s, %d) flags=0x%x, refcnt=%d %ld)\n",
+ i, buf->sb_relname, buf->tag.blockNum,
+ buf->flags, buf->refcount, PrivateRefCount[i]);
+ }
}
- }
}
void
PrintPinnedBufs()
{
- int i;
- BufferDesc *buf = BufferDescriptors;
-
- SpinAcquire(BufMgrLock);
- for (i = 0; i < NBuffers; ++i, ++buf) {
- if (PrivateRefCount[i] > 0)
- elog(NOTICE, "[%02d] (freeNext=%d, freePrev=%d, relname=%s, \
+ int i;
+ BufferDesc *buf = BufferDescriptors;
+
+ SpinAcquire(BufMgrLock);
+ for (i = 0; i < NBuffers; ++i, ++buf)
+ {
+ if (PrivateRefCount[i] > 0)
+ elog(NOTICE, "[%02d] (freeNext=%d, freePrev=%d, relname=%s, \
blockNum=%d, flags=0x%x, refcount=%d %d)\n",
- i, buf->freeNext, buf->freePrev, buf->sb_relname,
- buf->tag.blockNum, buf->flags,
- buf->refcount, PrivateRefCount[i]);
- }
- SpinRelease(BufMgrLock);
+ i, buf->freeNext, buf->freePrev, buf->sb_relname,
+ buf->tag.blockNum, buf->flags,
+ buf->refcount, PrivateRefCount[i]);
+ }
+ SpinRelease(BufMgrLock);
}
/*
@@ -1474,17 +1587,20 @@ blockNum=%d, flags=0x%x, refcount=%d %d)\n",
void
BufferPoolBlowaway()
{
- register int i;
-
- BufferSync();
- for (i=1; i<=NBuffers; i++) {
- if (BufferIsValid(i)) {
- while(BufferIsValid(i))
- ReleaseBuffer(i);
- }
- BufTableDelete(&BufferDescriptors[i-1]);
- }
+ register int i;
+
+ BufferSync();
+ for (i = 1; i <= NBuffers; i++)
+ {
+ if (BufferIsValid(i))
+ {
+ while (BufferIsValid(i))
+ ReleaseBuffer(i);
+ }
+ BufTableDelete(&BufferDescriptors[i - 1]);
+ }
}
+
#endif
#undef IncrBufferRefCount
@@ -1493,297 +1609,328 @@ BufferPoolBlowaway()
void
IncrBufferRefCount(Buffer buffer)
{
- if (BufferIsLocal(buffer)) {
- Assert(LocalRefCount[-buffer - 1] >= 0);
- LocalRefCount[-buffer - 1]++;
- } else {
- Assert(!BAD_BUFFER_ID(buffer));
- Assert(PrivateRefCount[buffer - 1] >= 0);
- PrivateRefCount[buffer - 1]++;
- }
+ if (BufferIsLocal(buffer))
+ {
+ Assert(LocalRefCount[-buffer - 1] >= 0);
+ LocalRefCount[-buffer - 1]++;
+ }
+ else
+ {
+ Assert(!BAD_BUFFER_ID(buffer));
+ Assert(PrivateRefCount[buffer - 1] >= 0);
+ PrivateRefCount[buffer - 1]++;
+ }
}
/*
* ReleaseBuffer -- remove the pin on a buffer without
- * marking it dirty.
+ * marking it dirty.
*
*/
int
ReleaseBuffer(Buffer buffer)
{
- BufferDesc *bufHdr;
-
- if (BufferIsLocal(buffer)) {
- Assert(LocalRefCount[-buffer - 1] > 0);
- LocalRefCount[-buffer - 1]--;
- return (STATUS_OK);
- }
-
- if (BAD_BUFFER_ID(buffer))
- return(STATUS_ERROR);
-
- bufHdr = &BufferDescriptors[buffer-1];
-
- Assert(PrivateRefCount[buffer - 1] > 0);
- PrivateRefCount[buffer - 1]--;
- if (PrivateRefCount[buffer - 1] == 0 && LastRefCount[buffer - 1] == 0) {
- /* only release buffer if it is not pinned in previous ExecMain
- levels */
- SpinAcquire(BufMgrLock);
- bufHdr->refcount--;
- if (bufHdr->refcount == 0) {
- AddBufferToFreelist(bufHdr);
- bufHdr->flags |= BM_FREE;
+ BufferDesc *bufHdr;
+
+ if (BufferIsLocal(buffer))
+ {
+ Assert(LocalRefCount[-buffer - 1] > 0);
+ LocalRefCount[-buffer - 1]--;
+ return (STATUS_OK);
}
- if(CommitInfoNeedsSave[buffer - 1]) {
- bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
- CommitInfoNeedsSave[buffer - 1] = 0;
+
+ if (BAD_BUFFER_ID(buffer))
+ return (STATUS_ERROR);
+
+ bufHdr = &BufferDescriptors[buffer - 1];
+
+ Assert(PrivateRefCount[buffer - 1] > 0);
+ PrivateRefCount[buffer - 1]--;
+ if (PrivateRefCount[buffer - 1] == 0 && LastRefCount[buffer - 1] == 0)
+ {
+
+ /*
+ * only release buffer if it is not pinned in previous ExecMain
+ * levels
+ */
+ SpinAcquire(BufMgrLock);
+ bufHdr->refcount--;
+ if (bufHdr->refcount == 0)
+ {
+ AddBufferToFreelist(bufHdr);
+ bufHdr->flags |= BM_FREE;
+ }
+ if (CommitInfoNeedsSave[buffer - 1])
+ {
+ bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
+ CommitInfoNeedsSave[buffer - 1] = 0;
+ }
+ SpinRelease(BufMgrLock);
}
- SpinRelease(BufMgrLock);
- }
-
- return(STATUS_OK);
+
+ return (STATUS_OK);
}
#ifdef NOT_USED
void
IncrBufferRefCount_Debug(char *file, int line, Buffer buffer)
{
- IncrBufferRefCount(buffer);
- if (ShowPinTrace && !BufferIsLocal(buffer) && is_userbuffer(buffer)) {
- BufferDesc *buf = &BufferDescriptors[buffer-1];
-
- fprintf(stderr, "PIN(Incr) %ld relname = %s, blockNum = %d, \
+ IncrBufferRefCount(buffer);
+ if (ShowPinTrace && !BufferIsLocal(buffer) && is_userbuffer(buffer))
+ {
+ BufferDesc *buf = &BufferDescriptors[buffer - 1];
+
+ fprintf(stderr, "PIN(Incr) %ld relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n",
- buffer, buf->sb_relname, buf->tag.blockNum,
- PrivateRefCount[buffer - 1], file, line);
- }
+ buffer, buf->sb_relname, buf->tag.blockNum,
+ PrivateRefCount[buffer - 1], file, line);
+ }
}
+
#endif
#ifdef NOT_USED
void
ReleaseBuffer_Debug(char *file, int line, Buffer buffer)
{
- ReleaseBuffer(buffer);
- if (ShowPinTrace && !BufferIsLocal(buffer) && is_userbuffer(buffer)) {
- BufferDesc *buf = &BufferDescriptors[buffer-1];
-
- fprintf(stderr, "UNPIN(Rel) %ld relname = %s, blockNum = %d, \
+ ReleaseBuffer(buffer);
+ if (ShowPinTrace && !BufferIsLocal(buffer) && is_userbuffer(buffer))
+ {
+ BufferDesc *buf = &BufferDescriptors[buffer - 1];
+
+ fprintf(stderr, "UNPIN(Rel) %ld relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n",
- buffer, buf->sb_relname, buf->tag.blockNum,
- PrivateRefCount[buffer - 1], file, line);
- }
+ buffer, buf->sb_relname, buf->tag.blockNum,
+ PrivateRefCount[buffer - 1], file, line);
+ }
}
+
#endif
#ifdef NOT_USED
int
ReleaseAndReadBuffer_Debug(char *file,
- int line,
- Buffer buffer,
- Relation relation,
- BlockNumber blockNum)
+ int line,
+ Buffer buffer,
+ Relation relation,
+ BlockNumber blockNum)
{
- bool bufferValid;
- Buffer b;
-
- bufferValid = BufferIsValid(buffer);
- b = ReleaseAndReadBuffer(buffer, relation, blockNum);
- if (ShowPinTrace && bufferValid && BufferIsLocal(buffer)
- && is_userbuffer(buffer)) {
- BufferDesc *buf = &BufferDescriptors[buffer-1];
-
- fprintf(stderr, "UNPIN(Rel&Rd) %ld relname = %s, blockNum = %d, \
+ bool bufferValid;
+ Buffer b;
+
+ bufferValid = BufferIsValid(buffer);
+ b = ReleaseAndReadBuffer(buffer, relation, blockNum);
+ if (ShowPinTrace && bufferValid && BufferIsLocal(buffer)
+ && is_userbuffer(buffer))
+ {
+ BufferDesc *buf = &BufferDescriptors[buffer - 1];
+
+ fprintf(stderr, "UNPIN(Rel&Rd) %ld relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n",
- buffer, buf->sb_relname, buf->tag.blockNum,
- PrivateRefCount[buffer - 1], file, line);
- }
- if (ShowPinTrace && BufferIsLocal(buffer) && is_userbuffer(buffer)) {
- BufferDesc *buf = &BufferDescriptors[b-1];
-
- fprintf(stderr, "PIN(Rel&Rd) %ld relname = %s, blockNum = %d, \
+ buffer, buf->sb_relname, buf->tag.blockNum,
+ PrivateRefCount[buffer - 1], file, line);
+ }
+ if (ShowPinTrace && BufferIsLocal(buffer) && is_userbuffer(buffer))
+ {
+ BufferDesc *buf = &BufferDescriptors[b - 1];
+
+ fprintf(stderr, "PIN(Rel&Rd) %ld relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n",
- b, buf->sb_relname, buf->tag.blockNum,
- PrivateRefCount[b - 1], file, line);
- }
- return b;
+ b, buf->sb_relname, buf->tag.blockNum,
+ PrivateRefCount[b - 1], file, line);
+ }
+ return b;
}
+
#endif
#ifdef BMTRACE
/*
- * trace allocations and deallocations in a circular buffer in
- * shared memory. check the buffer before doing the allocation,
- * and die if there's anything fishy.
+ * trace allocations and deallocations in a circular buffer in
+ * shared memory. check the buffer before doing the allocation,
+ * and die if there's anything fishy.
*/
_bm_trace(Oid dbId, Oid relId, int blkNo, int bufNo, int allocType)
{
- static int mypid = 0;
- long start, cur;
- bmtrace *tb;
-
- if (mypid == 0)
- mypid = getpid();
-
- start = *CurTraceBuf;
-
- if (start > 0)
- cur = start - 1;
- else
- cur = BMT_LIMIT - 1;
-
- for (;;) {
- tb = &TraceBuf[cur];
- if (tb->bmt_op != BMT_NOTUSED) {
- if (tb->bmt_buf == bufNo) {
- if ((tb->bmt_op == BMT_DEALLOC)
- || (tb->bmt_dbid == dbId && tb->bmt_relid == relId
- && tb->bmt_blkno == blkNo))
- goto okay;
-
- /* die holding the buffer lock */
- _bm_die(dbId, relId, blkNo, bufNo, allocType, start, cur);
- }
- }
-
- if (cur == start)
- goto okay;
-
- if (cur == 0)
- cur = BMT_LIMIT - 1;
+ static int mypid = 0;
+ long start,
+ cur;
+ bmtrace *tb;
+
+ if (mypid == 0)
+ mypid = getpid();
+
+ start = *CurTraceBuf;
+
+ if (start > 0)
+ cur = start - 1;
else
- cur--;
- }
-
- okay:
- tb = &TraceBuf[start];
- tb->bmt_pid = mypid;
- tb->bmt_buf = bufNo;
- tb->bmt_dbid = dbId;
- tb->bmt_relid = relId;
- tb->bmt_blkno = blkNo;
- tb->bmt_op = allocType;
-
- *CurTraceBuf = (start + 1) % BMT_LIMIT;
+ cur = BMT_LIMIT - 1;
+
+ for (;;)
+ {
+ tb = &TraceBuf[cur];
+ if (tb->bmt_op != BMT_NOTUSED)
+ {
+ if (tb->bmt_buf == bufNo)
+ {
+ if ((tb->bmt_op == BMT_DEALLOC)
+ || (tb->bmt_dbid == dbId && tb->bmt_relid == relId
+ && tb->bmt_blkno == blkNo))
+ goto okay;
+
+ /* die holding the buffer lock */
+ _bm_die(dbId, relId, blkNo, bufNo, allocType, start, cur);
+ }
+ }
+
+ if (cur == start)
+ goto okay;
+
+ if (cur == 0)
+ cur = BMT_LIMIT - 1;
+ else
+ cur--;
+ }
+
+okay:
+ tb = &TraceBuf[start];
+ tb->bmt_pid = mypid;
+ tb->bmt_buf = bufNo;
+ tb->bmt_dbid = dbId;
+ tb->bmt_relid = relId;
+ tb->bmt_blkno = blkNo;
+ tb->bmt_op = allocType;
+
+ *CurTraceBuf = (start + 1) % BMT_LIMIT;
}
_bm_die(Oid dbId, Oid relId, int blkNo, int bufNo,
- int allocType, long start, long cur)
+ int allocType, long start, long cur)
{
- FILE *fp;
- bmtrace *tb;
- int i;
-
- tb = &TraceBuf[cur];
-
- if ((fp = AllocateFile("/tmp/death_notice", "w")) == NULL)
- elog(FATAL, "buffer alloc trace error and can't open log file");
-
- fprintf(fp, "buffer alloc trace detected the following error:\n\n");
- fprintf(fp, " buffer %d being %s inconsistently with a previous %s\n\n",
- bufNo, (allocType == BMT_DEALLOC ? "deallocated" : "allocated"),
- (tb->bmt_op == BMT_DEALLOC ? "deallocation" : "allocation"));
-
- fprintf(fp, "the trace buffer contains:\n");
-
- i = start;
- for (;;) {
- tb = &TraceBuf[i];
- if (tb->bmt_op != BMT_NOTUSED) {
- fprintf(fp, " [%3d]%spid %d buf %2d for <%d,%d,%d> ",
- i, (i == cur ? " ---> " : "\t"),
- tb->bmt_pid, tb->bmt_buf,
- tb->bmt_dbid, tb->bmt_relid, tb->bmt_blkno);
-
- switch (tb->bmt_op) {
- case BMT_ALLOCFND:
+ FILE *fp;
+ bmtrace *tb;
+ int i;
+
+ tb = &TraceBuf[cur];
+
+ if ((fp = AllocateFile("/tmp/death_notice", "w")) == NULL)
+ elog(FATAL, "buffer alloc trace error and can't open log file");
+
+ fprintf(fp, "buffer alloc trace detected the following error:\n\n");
+ fprintf(fp, " buffer %d being %s inconsistently with a previous %s\n\n",
+ bufNo, (allocType == BMT_DEALLOC ? "deallocated" : "allocated"),
+ (tb->bmt_op == BMT_DEALLOC ? "deallocation" : "allocation"));
+
+ fprintf(fp, "the trace buffer contains:\n");
+
+ i = start;
+ for (;;)
+ {
+ tb = &TraceBuf[i];
+ if (tb->bmt_op != BMT_NOTUSED)
+ {
+ fprintf(fp, " [%3d]%spid %d buf %2d for <%d,%d,%d> ",
+ i, (i == cur ? " ---> " : "\t"),
+ tb->bmt_pid, tb->bmt_buf,
+ tb->bmt_dbid, tb->bmt_relid, tb->bmt_blkno);
+
+ switch (tb->bmt_op)
+ {
+ case BMT_ALLOCFND:
+ fprintf(fp, "allocate (found)\n");
+ break;
+
+ case BMT_ALLOCNOTFND:
+ fprintf(fp, "allocate (not found)\n");
+ break;
+
+ case BMT_DEALLOC:
+ fprintf(fp, "deallocate\n");
+ break;
+
+ default:
+ fprintf(fp, "unknown op type %d\n", tb->bmt_op);
+ break;
+ }
+ }
+
+ i = (i + 1) % BMT_LIMIT;
+ if (i == start)
+ break;
+ }
+
+ fprintf(fp, "\noperation causing error:\n");
+ fprintf(fp, "\tpid %d buf %d for <%d,%d,%d> ",
+ getpid(), bufNo, dbId, relId, blkNo);
+
+ switch (allocType)
+ {
+ case BMT_ALLOCFND:
fprintf(fp, "allocate (found)\n");
break;
-
- case BMT_ALLOCNOTFND:
+
+ case BMT_ALLOCNOTFND:
fprintf(fp, "allocate (not found)\n");
break;
-
- case BMT_DEALLOC:
+
+ case BMT_DEALLOC:
fprintf(fp, "deallocate\n");
break;
-
- default:
- fprintf(fp, "unknown op type %d\n", tb->bmt_op);
+
+ default:
+ fprintf(fp, "unknown op type %d\n", allocType);
break;
- }
}
-
- i = (i + 1) % BMT_LIMIT;
- if (i == start)
- break;
- }
-
- fprintf(fp, "\noperation causing error:\n");
- fprintf(fp, "\tpid %d buf %d for <%d,%d,%d> ",
- getpid(), bufNo, dbId, relId, blkNo);
-
- switch (allocType) {
- case BMT_ALLOCFND:
- fprintf(fp, "allocate (found)\n");
- break;
-
- case BMT_ALLOCNOTFND:
- fprintf(fp, "allocate (not found)\n");
- break;
-
- case BMT_DEALLOC:
- fprintf(fp, "deallocate\n");
- break;
-
- default:
- fprintf(fp, "unknown op type %d\n", allocType);
- break;
- }
-
- FreeFile(fp);
-
- kill(getpid(), SIGILL);
+
+ FreeFile(fp);
+
+ kill(getpid(), SIGILL);
}
-#endif /* BMTRACE */
+#endif /* BMTRACE */
void
BufferRefCountReset(int *refcountsave)
{
- int i;
- for (i=0; i<NBuffers; i++) {
- refcountsave[i] = PrivateRefCount[i];
- LastRefCount[i] += PrivateRefCount[i];
- PrivateRefCount[i] = 0;
- }
+ int i;
+
+ for (i = 0; i < NBuffers; i++)
+ {
+ refcountsave[i] = PrivateRefCount[i];
+ LastRefCount[i] += PrivateRefCount[i];
+ PrivateRefCount[i] = 0;
+ }
}
void
BufferRefCountRestore(int *refcountsave)
{
- int i;
- for (i=0; i<NBuffers; i++) {
- PrivateRefCount[i] = refcountsave[i];
- LastRefCount[i] -= refcountsave[i];
- refcountsave[i] = 0;
- }
+ int i;
+
+ for (i = 0; i < NBuffers; i++)
+ {
+ PrivateRefCount[i] = refcountsave[i];
+ LastRefCount[i] -= refcountsave[i];
+ refcountsave[i] = 0;
+ }
}
-int SetBufferWriteMode (int mode)
+int
+SetBufferWriteMode(int mode)
{
- int old;
-
- old = WriteMode;
- WriteMode = mode;
- return (old);
+ int old;
+
+ old = WriteMode;
+ WriteMode = mode;
+ return (old);
}
-void SetBufferCommitInfoNeedsSave(Buffer buffer)
+void
+SetBufferCommitInfoNeedsSave(Buffer buffer)
{
- if ( !BufferIsLocal(buffer) )
- CommitInfoNeedsSave[buffer - 1]++;
+ if (!BufferIsLocal(buffer))
+ CommitInfoNeedsSave[buffer - 1]++;
}
diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index f4e7bcdc57a..94a8e84b8c6 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* freelist.c--
- * routines for manipulating the buffer pool's replacement strategy
- * freelist.
+ * routines for manipulating the buffer pool's replacement strategy
+ * freelist.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/freelist.c,v 1.4 1997/08/19 21:32:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/freelist.c,v 1.5 1997/09/07 04:48:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,23 +16,23 @@
* OLD COMMENTS
*
* Data Structures:
- * SharedFreeList is a circular queue. Notice that this
- * is a shared memory queue so the next/prev "ptrs" are
- * buffer ids, not addresses.
+ * SharedFreeList is a circular queue. Notice that this
+ * is a shared memory queue so the next/prev "ptrs" are
+ * buffer ids, not addresses.
*
* Sync: all routines in this file assume that the buffer
- * semaphore has been acquired by the caller.
+ * semaphore has been acquired by the caller.
*/
#include <stdio.h>
#include "postgres.h"
#include "storage/bufmgr.h"
-#include "storage/buf_internals.h" /* where declarations go */
+#include "storage/buf_internals.h" /* where declarations go */
#include "storage/spin.h"
-static BufferDesc *SharedFreeList;
+static BufferDesc *SharedFreeList;
/* only actually used in debugging. The lock
* should be acquired before calling the freelist manager.
@@ -40,40 +40,40 @@ static BufferDesc *SharedFreeList;
extern SPINLOCK BufMgrLock;
#define IsInQueue(bf) \
- Assert((bf->freeNext != INVALID_DESCRIPTOR));\
- Assert((bf->freePrev != INVALID_DESCRIPTOR));\
- Assert((bf->flags & BM_FREE))
+ Assert((bf->freeNext != INVALID_DESCRIPTOR));\
+ Assert((bf->freePrev != INVALID_DESCRIPTOR));\
+ Assert((bf->flags & BM_FREE))
#define NotInQueue(bf) \
- Assert((bf->freeNext == INVALID_DESCRIPTOR));\
- Assert((bf->freePrev == INVALID_DESCRIPTOR));\
- Assert(! (bf->flags & BM_FREE))
+ Assert((bf->freeNext == INVALID_DESCRIPTOR));\
+ Assert((bf->freePrev == INVALID_DESCRIPTOR));\
+ Assert(! (bf->flags & BM_FREE))
/*
- * AddBufferToFreelist --
+ * AddBufferToFreelist --
*
* In theory, this is the only routine that needs to be changed
- * if the buffer replacement strategy changes. Just change
+ * if the buffer replacement strategy changes. Just change
* the manner in which buffers are added to the freelist queue.
* Currently, they are added on an LRU basis.
*/
void
-AddBufferToFreelist(BufferDesc *bf)
+AddBufferToFreelist(BufferDesc * bf)
{
#ifdef BMTRACE
- _bm_trace(bf->tag.relId.dbId, bf->tag.relId.relId, bf->tag.blockNum,
- BufferDescriptorGetBuffer(bf), BMT_DEALLOC);
-#endif /* BMTRACE */
- NotInQueue(bf);
-
- /* change bf so it points to inFrontOfNew and its successor */
- bf->freePrev = SharedFreeList->freePrev;
- bf->freeNext = Free_List_Descriptor;
-
- /* insert new into chain */
- BufferDescriptors[bf->freeNext].freePrev = bf->buf_id;
- BufferDescriptors[bf->freePrev].freeNext = bf->buf_id;
+ _bm_trace(bf->tag.relId.dbId, bf->tag.relId.relId, bf->tag.blockNum,
+ BufferDescriptorGetBuffer(bf), BMT_DEALLOC);
+#endif /* BMTRACE */
+ NotInQueue(bf);
+
+ /* change bf so it points to inFrontOfNew and its successor */
+ bf->freePrev = SharedFreeList->freePrev;
+ bf->freeNext = Free_List_Descriptor;
+
+ /* insert new into chain */
+ BufferDescriptors[bf->freeNext].freePrev = bf->buf_id;
+ BufferDescriptors[bf->freePrev].freeNext = bf->buf_id;
}
#undef PinBuffer
@@ -82,47 +82,52 @@ AddBufferToFreelist(BufferDesc *bf)
* PinBuffer -- make buffer unavailable for replacement.
*/
void
-PinBuffer(BufferDesc *buf)
+PinBuffer(BufferDesc * buf)
{
- long b;
-
- /* Assert (buf->refcount < 25); */
-
- if (buf->refcount == 0) {
- IsInQueue(buf);
-
- /* remove from freelist queue */
- BufferDescriptors[buf->freeNext].freePrev = buf->freePrev;
- BufferDescriptors[buf->freePrev].freeNext = buf->freeNext;
- buf->freeNext = buf->freePrev = INVALID_DESCRIPTOR;
-
- /* mark buffer as no longer free */
- buf->flags &= ~BM_FREE;
- } else {
- NotInQueue(buf);
- }
-
- b = BufferDescriptorGetBuffer(buf) - 1;
- Assert(PrivateRefCount[b] >= 0);
- if (PrivateRefCount[b] == 0 && LastRefCount[b] == 0)
- buf->refcount++;
- PrivateRefCount[b]++;
+ long b;
+
+ /* Assert (buf->refcount < 25); */
+
+ if (buf->refcount == 0)
+ {
+ IsInQueue(buf);
+
+ /* remove from freelist queue */
+ BufferDescriptors[buf->freeNext].freePrev = buf->freePrev;
+ BufferDescriptors[buf->freePrev].freeNext = buf->freeNext;
+ buf->freeNext = buf->freePrev = INVALID_DESCRIPTOR;
+
+ /* mark buffer as no longer free */
+ buf->flags &= ~BM_FREE;
+ }
+ else
+ {
+ NotInQueue(buf);
+ }
+
+ b = BufferDescriptorGetBuffer(buf) - 1;
+ Assert(PrivateRefCount[b] >= 0);
+ if (PrivateRefCount[b] == 0 && LastRefCount[b] == 0)
+ buf->refcount++;
+ PrivateRefCount[b]++;
}
#ifdef NOT_USED
void
-PinBuffer_Debug(char *file, int line, BufferDesc *buf)
+PinBuffer_Debug(char *file, int line, BufferDesc * buf)
{
- PinBuffer(buf);
- if (ShowPinTrace) {
- Buffer buffer = BufferDescriptorGetBuffer(buf);
-
- fprintf(stderr, "PIN(Pin) %ld relname = %s, blockNum = %d, \
+ PinBuffer(buf);
+ if (ShowPinTrace)
+ {
+ Buffer buffer = BufferDescriptorGetBuffer(buf);
+
+ fprintf(stderr, "PIN(Pin) %ld relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n",
- buffer, buf->sb_relname, buf->tag.blockNum,
- PrivateRefCount[buffer - 1], file, line);
- }
+ buffer, buf->sb_relname, buf->tag.blockNum,
+ PrivateRefCount[buffer - 1], file, line);
+ }
}
+
#endif
#undef UnpinBuffer
@@ -131,95 +136,102 @@ refcount = %ld, file: %s, line: %d\n",
* UnpinBuffer -- make buffer available for replacement.
*/
void
-UnpinBuffer(BufferDesc *buf)
+UnpinBuffer(BufferDesc * buf)
{
- long b = BufferDescriptorGetBuffer(buf) - 1;
-
- Assert(buf->refcount);
- Assert(PrivateRefCount[b] > 0);
- PrivateRefCount[b]--;
- if (PrivateRefCount[b] == 0 && LastRefCount[b] == 0)
- buf->refcount--;
- NotInQueue(buf);
-
- if (buf->refcount == 0) {
- AddBufferToFreelist(buf);
- buf->flags |= BM_FREE;
- } else {
- /* do nothing */
- }
+ long b = BufferDescriptorGetBuffer(buf) - 1;
+
+ Assert(buf->refcount);
+ Assert(PrivateRefCount[b] > 0);
+ PrivateRefCount[b]--;
+ if (PrivateRefCount[b] == 0 && LastRefCount[b] == 0)
+ buf->refcount--;
+ NotInQueue(buf);
+
+ if (buf->refcount == 0)
+ {
+ AddBufferToFreelist(buf);
+ buf->flags |= BM_FREE;
+ }
+ else
+ {
+ /* do nothing */
+ }
}
#ifdef NOT_USED
void
-UnpinBuffer_Debug(char *file, int line, BufferDesc *buf)
+UnpinBuffer_Debug(char *file, int line, BufferDesc * buf)
{
- UnpinBuffer(buf);
- if (ShowPinTrace) {
- Buffer buffer = BufferDescriptorGetBuffer(buf);
-
- fprintf(stderr, "UNPIN(Unpin) %ld relname = %s, blockNum = %d, \
+ UnpinBuffer(buf);
+ if (ShowPinTrace)
+ {
+ Buffer buffer = BufferDescriptorGetBuffer(buf);
+
+ fprintf(stderr, "UNPIN(Unpin) %ld relname = %s, blockNum = %d, \
refcount = %ld, file: %s, line: %d\n",
- buffer, buf->sb_relname, buf->tag.blockNum,
- PrivateRefCount[buffer - 1], file, line);
- }
+ buffer, buf->sb_relname, buf->tag.blockNum,
+ PrivateRefCount[buffer - 1], file, line);
+ }
}
+
#endif
/*
* GetFreeBuffer() -- get the 'next' buffer from the freelist.
*
*/
-BufferDesc *
+BufferDesc *
GetFreeBuffer()
{
- BufferDesc *buf;
-
- if (Free_List_Descriptor == SharedFreeList->freeNext) {
-
- /* queue is empty. All buffers in the buffer pool are pinned. */
- elog(WARN,"out of free buffers: time to abort !\n");
- return(NULL);
- }
- buf = &(BufferDescriptors[SharedFreeList->freeNext]);
-
- /* remove from freelist queue */
- BufferDescriptors[buf->freeNext].freePrev = buf->freePrev;
- BufferDescriptors[buf->freePrev].freeNext = buf->freeNext;
- buf->freeNext = buf->freePrev = INVALID_DESCRIPTOR;
-
- buf->flags &= ~(BM_FREE);
-
- return(buf);
+ BufferDesc *buf;
+
+ if (Free_List_Descriptor == SharedFreeList->freeNext)
+ {
+
+ /* queue is empty. All buffers in the buffer pool are pinned. */
+ elog(WARN, "out of free buffers: time to abort !\n");
+ return (NULL);
+ }
+ buf = &(BufferDescriptors[SharedFreeList->freeNext]);
+
+ /* remove from freelist queue */
+ BufferDescriptors[buf->freeNext].freePrev = buf->freePrev;
+ BufferDescriptors[buf->freePrev].freeNext = buf->freeNext;
+ buf->freeNext = buf->freePrev = INVALID_DESCRIPTOR;
+
+ buf->flags &= ~(BM_FREE);
+
+ return (buf);
}
/*
* InitFreeList -- initialize the dummy buffer descriptor used
- * as a freelist head.
+ * as a freelist head.
*
* Assume: All of the buffers are already linked in a circular
- * queue. Only called by postmaster and only during
- * initialization.
+ * queue. Only called by postmaster and only during
+ * initialization.
*/
void
InitFreeList(bool init)
{
- SharedFreeList = &(BufferDescriptors[Free_List_Descriptor]);
-
- if (init) {
- /* we only do this once, normally the postmaster */
- SharedFreeList->data = INVALID_OFFSET;
- SharedFreeList->flags = 0;
- SharedFreeList->flags &= ~(BM_VALID | BM_DELETED | BM_FREE);
- SharedFreeList->buf_id = Free_List_Descriptor;
-
- /* insert it into a random spot in the circular queue */
- SharedFreeList->freeNext = BufferDescriptors[0].freeNext;
- SharedFreeList->freePrev = 0;
- BufferDescriptors[SharedFreeList->freeNext].freePrev =
- BufferDescriptors[SharedFreeList->freePrev].freeNext =
- Free_List_Descriptor;
- }
+ SharedFreeList = &(BufferDescriptors[Free_List_Descriptor]);
+
+ if (init)
+ {
+ /* we only do this once, normally the postmaster */
+ SharedFreeList->data = INVALID_OFFSET;
+ SharedFreeList->flags = 0;
+ SharedFreeList->flags &= ~(BM_VALID | BM_DELETED | BM_FREE);
+ SharedFreeList->buf_id = Free_List_Descriptor;
+
+ /* insert it into a random spot in the circular queue */
+ SharedFreeList->freeNext = BufferDescriptors[0].freeNext;
+ SharedFreeList->freePrev = 0;
+ BufferDescriptors[SharedFreeList->freeNext].freePrev =
+ BufferDescriptors[SharedFreeList->freePrev].freeNext =
+ Free_List_Descriptor;
+ }
}
@@ -230,67 +242,78 @@ InitFreeList(bool init)
void
DBG_FreeListCheck(int nfree)
{
- int i;
- BufferDesc *buf;
-
- buf = &(BufferDescriptors[SharedFreeList->freeNext]);
- for (i=0;i<nfree;i++,buf = &(BufferDescriptors[buf->freeNext])) {
-
- if (! (buf->flags & (BM_FREE))){
- if (buf != SharedFreeList) {
- printf("\tfree list corrupted: %d flags %x\n",
- buf->buf_id,buf->flags);
- } else {
- printf("\tfree list corrupted: too short -- %d not %d\n",
- i,nfree);
-
- }
-
-
+ int i;
+ BufferDesc *buf;
+
+ buf = &(BufferDescriptors[SharedFreeList->freeNext]);
+ for (i = 0; i < nfree; i++, buf = &(BufferDescriptors[buf->freeNext]))
+ {
+
+ if (!(buf->flags & (BM_FREE)))
+ {
+ if (buf != SharedFreeList)
+ {
+ printf("\tfree list corrupted: %d flags %x\n",
+ buf->buf_id, buf->flags);
+ }
+ else
+ {
+ printf("\tfree list corrupted: too short -- %d not %d\n",
+ i, nfree);
+
+ }
+
+
+ }
+ if ((BufferDescriptors[buf->freeNext].freePrev != buf->buf_id) ||
+ (BufferDescriptors[buf->freePrev].freeNext != buf->buf_id))
+ {
+ printf("\tfree list links corrupted: %d %ld %ld\n",
+ buf->buf_id, buf->freePrev, buf->freeNext);
+ }
+
}
- if ((BufferDescriptors[buf->freeNext].freePrev != buf->buf_id) ||
- (BufferDescriptors[buf->freePrev].freeNext != buf->buf_id)) {
- printf("\tfree list links corrupted: %d %ld %ld\n",
- buf->buf_id,buf->freePrev,buf->freeNext);
+ if (buf != SharedFreeList)
+ {
+ printf("\tfree list corrupted: %d-th buffer is %d\n",
+ nfree, buf->buf_id);
+
}
-
- }
- if (buf != SharedFreeList) {
- printf("\tfree list corrupted: %d-th buffer is %d\n",
- nfree,buf->buf_id);
-
- }
}
+
#endif
#ifdef NOT_USED
/*
* PrintBufferFreeList -
- * prints the buffer free list, for debugging
+ * prints the buffer free list, for debugging
*/
static void
PrintBufferFreeList()
{
- BufferDesc *buf;
-
- if (SharedFreeList->freeNext == Free_List_Descriptor) {
- printf("free list is empty.\n");
- return;
- }
-
- buf = &(BufferDescriptors[SharedFreeList->freeNext]);
- for (;;) {
- int i = (buf - BufferDescriptors);
- printf("[%-2d] (%s, %d) flags=0x%x, refcnt=%d %ld, nxt=%ld prv=%ld)\n",
- i, buf->sb_relname, buf->tag.blockNum,
- buf->flags, buf->refcount, PrivateRefCount[i],
- buf->freeNext, buf->freePrev);
-
- if (buf->freeNext == Free_List_Descriptor)
- break;
-
- buf = &(BufferDescriptors[buf->freeNext]);
- }
+ BufferDesc *buf;
+
+ if (SharedFreeList->freeNext == Free_List_Descriptor)
+ {
+ printf("free list is empty.\n");
+ return;
+ }
+
+ buf = &(BufferDescriptors[SharedFreeList->freeNext]);
+ for (;;)
+ {
+ int i = (buf - BufferDescriptors);
+
+ printf("[%-2d] (%s, %d) flags=0x%x, refcnt=%d %ld, nxt=%ld prv=%ld)\n",
+ i, buf->sb_relname, buf->tag.blockNum,
+ buf->flags, buf->refcount, PrivateRefCount[i],
+ buf->freeNext, buf->freePrev);
+
+ if (buf->freeNext == Free_List_Descriptor)
+ break;
+
+ buf = &(BufferDescriptors[buf->freeNext]);
+ }
}
#endif
diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c
index 910cb668d7a..072830b3dd6 100644
--- a/src/backend/storage/buffer/localbuf.c
+++ b/src/backend/storage/buffer/localbuf.c
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* localbuf.c--
- * local buffer manager. Fast buffer manager for temporary tables
- * or special cases when the operation is not visible to other backends.
+ * local buffer manager. Fast buffer manager for temporary tables
+ * or special cases when the operation is not visible to other backends.
*
- * When a relation is being created, the descriptor will have rd_islocal
- * set to indicate that the local buffer manager should be used. During
- * the same transaction the relation is being created, any inserts or
- * selects from the newly created relation will use the local buffer
- * pool. rd_islocal is reset at the end of a transaction (commit/abort).
- * This is useful for queries like SELECT INTO TABLE and create index.
+ * When a relation is being created, the descriptor will have rd_islocal
+ * set to indicate that the local buffer manager should be used. During
+ * the same transaction the relation is being created, any inserts or
+ * selects from the newly created relation will use the local buffer
+ * pool. rd_islocal is reset at the end of a transaction (commit/abort).
+ * This is useful for queries like SELECT INTO TABLE and create index.
*
* Copyright (c) 1994-5, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/localbuf.c,v 1.8 1997/07/28 00:54:48 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/localbuf.c,v 1.9 1997/09/07 04:48:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -45,252 +45,262 @@
#include "utils/hsearch.h"
#include "utils/memutils.h"
#include "utils/relcache.h"
-#include "executor/execdebug.h" /* for NDirectFileRead */
+#include "executor/execdebug.h" /* for NDirectFileRead */
#include "catalog/catalog.h"
extern long int LocalBufferFlushCount;
-int NLocBuffer = 64;
-BufferDesc *LocalBufferDescriptors = NULL;
-long *LocalRefCount = NULL;
+int NLocBuffer = 64;
+BufferDesc *LocalBufferDescriptors = NULL;
+long *LocalRefCount = NULL;
-static int nextFreeLocalBuf = 0;
+static int nextFreeLocalBuf = 0;
/*#define LBDEBUG*/
/*
* LocalBufferAlloc -
- * allocate a local buffer. We do round robin allocation for now.
+ * allocate a local buffer. We do round robin allocation for now.
*/
-BufferDesc *
-LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
+BufferDesc *
+LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool * foundPtr)
{
- int i;
- BufferDesc *bufHdr = (BufferDesc *) NULL;
+ int i;
+ BufferDesc *bufHdr = (BufferDesc *) NULL;
- if (blockNum == P_NEW) {
- blockNum = reln->rd_nblocks;
- reln->rd_nblocks++;
- }
+ if (blockNum == P_NEW)
+ {
+ blockNum = reln->rd_nblocks;
+ reln->rd_nblocks++;
+ }
- /* a low tech search for now -- not optimized for scans */
- for (i=0; i < NLocBuffer; i++) {
- if (LocalBufferDescriptors[i].tag.relId.relId == reln->rd_id &&
- LocalBufferDescriptors[i].tag.blockNum == blockNum) {
+ /* a low tech search for now -- not optimized for scans */
+ for (i = 0; i < NLocBuffer; i++)
+ {
+ if (LocalBufferDescriptors[i].tag.relId.relId == reln->rd_id &&
+ LocalBufferDescriptors[i].tag.blockNum == blockNum)
+ {
#ifdef LBDEBUG
- fprintf(stderr, "LB ALLOC (%d,%d) %d\n",
- reln->rd_id, blockNum, -i-1);
-#endif
- LocalRefCount[i]++;
- *foundPtr = TRUE;
- return &LocalBufferDescriptors[i];
+ fprintf(stderr, "LB ALLOC (%d,%d) %d\n",
+ reln->rd_id, blockNum, -i - 1);
+#endif
+ LocalRefCount[i]++;
+ *foundPtr = TRUE;
+ return &LocalBufferDescriptors[i];
+ }
}
- }
#ifdef LBDEBUG
- fprintf(stderr, "LB ALLOC (%d,%d) %d\n",
- reln->rd_id, blockNum, -nextFreeLocalBuf-1);
-#endif
-
- /* need to get a new buffer (round robin for now) */
- for(i=0; i < NLocBuffer; i++) {
- int b = (nextFreeLocalBuf + i) % NLocBuffer;
-
- if (LocalRefCount[b]==0) {
- bufHdr = &LocalBufferDescriptors[b];
- LocalRefCount[b]++;
- nextFreeLocalBuf = (b + 1) % NLocBuffer;
- break;
+ fprintf(stderr, "LB ALLOC (%d,%d) %d\n",
+ reln->rd_id, blockNum, -nextFreeLocalBuf - 1);
+#endif
+
+ /* need to get a new buffer (round robin for now) */
+ for (i = 0; i < NLocBuffer; i++)
+ {
+ int b = (nextFreeLocalBuf + i) % NLocBuffer;
+
+ if (LocalRefCount[b] == 0)
+ {
+ bufHdr = &LocalBufferDescriptors[b];
+ LocalRefCount[b]++;
+ nextFreeLocalBuf = (b + 1) % NLocBuffer;
+ break;
+ }
}
- }
- if (bufHdr==NULL)
- elog(WARN, "no empty local buffer.");
-
- /*
- * this buffer is not referenced but it might still be dirty (the
- * last transaction to touch it doesn't need its contents but has
- * not flushed it). if that's the case, write it out before
- * reusing it!
- */
- if (bufHdr->flags & BM_DIRTY) {
- Relation bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
+ if (bufHdr == NULL)
+ elog(WARN, "no empty local buffer.");
- Assert(bufrel != NULL);
-
- /* flush this page */
- smgrwrite(bufrel->rd_rel->relsmgr, bufrel, bufHdr->tag.blockNum,
- (char *) MAKE_PTR(bufHdr->data));
- LocalBufferFlushCount++;
- }
-
- /*
- * it's all ours now.
- */
- bufHdr->tag.relId.relId = reln->rd_id;
- bufHdr->tag.blockNum = blockNum;
- bufHdr->flags &= ~BM_DIRTY;
-
- /*
- * lazy memory allocation. (see MAKE_PTR for why we need to do
- * MAKE_OFFSET.)
- */
- if (bufHdr->data == (SHMEM_OFFSET)0) {
- char *data = (char *)malloc(BLCKSZ);
-
- bufHdr->data = MAKE_OFFSET(data);
- }
-
- *foundPtr = FALSE;
- return bufHdr;
+ /*
+ * this buffer is not referenced but it might still be dirty (the last
+ * transaction to touch it doesn't need its contents but has not
+ * flushed it). if that's the case, write it out before reusing it!
+ */
+ if (bufHdr->flags & BM_DIRTY)
+ {
+ Relation bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
+
+ Assert(bufrel != NULL);
+
+ /* flush this page */
+ smgrwrite(bufrel->rd_rel->relsmgr, bufrel, bufHdr->tag.blockNum,
+ (char *) MAKE_PTR(bufHdr->data));
+ LocalBufferFlushCount++;
+ }
+
+ /*
+ * it's all ours now.
+ */
+ bufHdr->tag.relId.relId = reln->rd_id;
+ bufHdr->tag.blockNum = blockNum;
+ bufHdr->flags &= ~BM_DIRTY;
+
+ /*
+ * lazy memory allocation. (see MAKE_PTR for why we need to do
+ * MAKE_OFFSET.)
+ */
+ if (bufHdr->data == (SHMEM_OFFSET) 0)
+ {
+ char *data = (char *) malloc(BLCKSZ);
+
+ bufHdr->data = MAKE_OFFSET(data);
+ }
+
+ *foundPtr = FALSE;
+ return bufHdr;
}
/*
* WriteLocalBuffer -
- * writes out a local buffer
+ * writes out a local buffer
*/
int
WriteLocalBuffer(Buffer buffer, bool release)
{
- int bufid;
+ int bufid;
- Assert(BufferIsLocal(buffer));
+ Assert(BufferIsLocal(buffer));
#ifdef LBDEBUG
- fprintf(stderr, "LB WRITE %d\n", buffer);
-#endif
-
- bufid = - (buffer + 1);
- LocalBufferDescriptors[bufid].flags |= BM_DIRTY;
+ fprintf(stderr, "LB WRITE %d\n", buffer);
+#endif
- if (release) {
- Assert(LocalRefCount[bufid] > 0);
- LocalRefCount[bufid]--;
- }
+ bufid = -(buffer + 1);
+ LocalBufferDescriptors[bufid].flags |= BM_DIRTY;
+
+ if (release)
+ {
+ Assert(LocalRefCount[bufid] > 0);
+ LocalRefCount[bufid]--;
+ }
- return true;
+ return true;
}
/*
* FlushLocalBuffer -
- * flushes a local buffer
+ * flushes a local buffer
*/
int
FlushLocalBuffer(Buffer buffer, bool release)
{
- int bufid;
- Relation bufrel;
- BufferDesc *bufHdr;
+ int bufid;
+ Relation bufrel;
+ BufferDesc *bufHdr;
- Assert(BufferIsLocal(buffer));
+ Assert(BufferIsLocal(buffer));
#ifdef LBDEBUG
- fprintf(stderr, "LB FLUSH %d\n", buffer);
-#endif
-
- bufid = - (buffer + 1);
- bufHdr = &LocalBufferDescriptors[bufid];
- bufHdr->flags &= ~BM_DIRTY;
- bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
-
- Assert(bufrel != NULL);
- smgrflush(bufrel->rd_rel->relsmgr, bufrel, bufHdr->tag.blockNum,
- (char *) MAKE_PTR(bufHdr->data));
- LocalBufferFlushCount++;
-
- Assert(LocalRefCount[bufid] > 0);
- if ( release )
- LocalRefCount[bufid]--;
-
- return true;
+ fprintf(stderr, "LB FLUSH %d\n", buffer);
+#endif
+
+ bufid = -(buffer + 1);
+ bufHdr = &LocalBufferDescriptors[bufid];
+ bufHdr->flags &= ~BM_DIRTY;
+ bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
+
+ Assert(bufrel != NULL);
+ smgrflush(bufrel->rd_rel->relsmgr, bufrel, bufHdr->tag.blockNum,
+ (char *) MAKE_PTR(bufHdr->data));
+ LocalBufferFlushCount++;
+
+ Assert(LocalRefCount[bufid] > 0);
+ if (release)
+ LocalRefCount[bufid]--;
+
+ return true;
}
/*
* InitLocalBuffer -
- * init the local buffer cache. Since most queries (esp. multi-user ones)
- * don't involve local buffers, we delay allocating memory for actual the
- * buffer until we need it.
+ * init the local buffer cache. Since most queries (esp. multi-user ones)
+ * don't involve local buffers, we delay allocating memory for actual the
+ * buffer until we need it.
*/
void
InitLocalBuffer(void)
{
- int i;
-
- /*
- * these aren't going away. I'm not gonna use palloc.
- */
- LocalBufferDescriptors =
- (BufferDesc *)malloc(sizeof(BufferDesc) * NLocBuffer);
- memset(LocalBufferDescriptors, 0, sizeof(BufferDesc) * NLocBuffer);
- nextFreeLocalBuf = 0;
-
- for (i = 0; i < NLocBuffer; i++) {
- BufferDesc *buf = &LocalBufferDescriptors[i];
+ int i;
/*
- * negative to indicate local buffer. This is tricky: shared buffers
- * start with 0. We have to start with -2. (Note that the routine
- * BufferDescriptorGetBuffer adds 1 to buf_id so our first buffer id
- * is -1.)
+ * these aren't going away. I'm not gonna use palloc.
*/
- buf->buf_id = - i - 2;
- }
+ LocalBufferDescriptors =
+ (BufferDesc *) malloc(sizeof(BufferDesc) * NLocBuffer);
+ memset(LocalBufferDescriptors, 0, sizeof(BufferDesc) * NLocBuffer);
+ nextFreeLocalBuf = 0;
+
+ for (i = 0; i < NLocBuffer; i++)
+ {
+ BufferDesc *buf = &LocalBufferDescriptors[i];
+
+ /*
+ * negative to indicate local buffer. This is tricky: shared
+ * buffers start with 0. We have to start with -2. (Note that the
+ * routine BufferDescriptorGetBuffer adds 1 to buf_id so our first
+ * buffer id is -1.)
+ */
+ buf->buf_id = -i - 2;
+ }
- LocalRefCount =
- (long *)malloc(sizeof(long) * NLocBuffer);
- memset(LocalRefCount, 0, sizeof(long) * NLocBuffer);
+ LocalRefCount =
+ (long *) malloc(sizeof(long) * NLocBuffer);
+ memset(LocalRefCount, 0, sizeof(long) * NLocBuffer);
}
/*
* LocalBufferSync -
- * flush all dirty buffers in the local buffer cache. Since the buffer
- * cache is only used for keeping relations visible during a transaction,
- * we will not need these buffers again.
+ * flush all dirty buffers in the local buffer cache. Since the buffer
+ * cache is only used for keeping relations visible during a transaction,
+ * we will not need these buffers again.
*/
void
LocalBufferSync(void)
{
- int i;
-
- for (i = 0; i < NLocBuffer; i++) {
- BufferDesc *buf = &LocalBufferDescriptors[i];
- Relation bufrel;
+ int i;
+
+ for (i = 0; i < NLocBuffer; i++)
+ {
+ BufferDesc *buf = &LocalBufferDescriptors[i];
+ Relation bufrel;
- if (buf->flags & BM_DIRTY) {
+ if (buf->flags & BM_DIRTY)
+ {
#ifdef LBDEBUG
- fprintf(stderr, "LB SYNC %d\n", -i-1);
-#endif
- bufrel = RelationIdCacheGetRelation(buf->tag.relId.relId);
-
- Assert(bufrel != NULL);
-
- smgrwrite(bufrel->rd_rel->relsmgr, bufrel, buf->tag.blockNum,
- (char *) MAKE_PTR(buf->data));
- LocalBufferFlushCount++;
-
- buf->tag.relId.relId = InvalidOid;
- buf->flags &= ~BM_DIRTY;
+ fprintf(stderr, "LB SYNC %d\n", -i - 1);
+#endif
+ bufrel = RelationIdCacheGetRelation(buf->tag.relId.relId);
+
+ Assert(bufrel != NULL);
+
+ smgrwrite(bufrel->rd_rel->relsmgr, bufrel, buf->tag.blockNum,
+ (char *) MAKE_PTR(buf->data));
+ LocalBufferFlushCount++;
+
+ buf->tag.relId.relId = InvalidOid;
+ buf->flags &= ~BM_DIRTY;
+ }
}
- }
- memset(LocalRefCount, 0, sizeof(long) * NLocBuffer);
- nextFreeLocalBuf = 0;
+ memset(LocalRefCount, 0, sizeof(long) * NLocBuffer);
+ nextFreeLocalBuf = 0;
}
void
ResetLocalBufferPool(void)
{
- int i;
+ int i;
- for (i = 0; i < NLocBuffer; i++)
- {
- BufferDesc *buf = &LocalBufferDescriptors[i];
+ for (i = 0; i < NLocBuffer; i++)
+ {
+ BufferDesc *buf = &LocalBufferDescriptors[i];
- buf->tag.relId.relId = InvalidOid;
- buf->flags &= ~BM_DIRTY;
- buf->buf_id = - i - 2;
- }
+ buf->tag.relId.relId = InvalidOid;
+ buf->flags &= ~BM_DIRTY;
+ buf->buf_id = -i - 2;
+ }
- memset(LocalRefCount, 0, sizeof(long) * NLocBuffer);
- nextFreeLocalBuf = 0;
+ memset(LocalRefCount, 0, sizeof(long) * NLocBuffer);
+ nextFreeLocalBuf = 0;
}
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 03605332344..2e998f27196 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* fd.c--
- * Virtual file descriptor code.
+ * Virtual file descriptor code.
*
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Id: fd.c,v 1.22 1997/08/19 21:32:48 momjian Exp $
+ * $Id: fd.c,v 1.23 1997/09/07 04:48:25 momjian Exp $
*
* NOTES:
*
@@ -48,7 +48,7 @@
#include <fcntl.h>
#include "postgres.h"
-#include "miscadmin.h" /* for DataDir */
+#include "miscadmin.h" /* for DataDir */
#include "utils/palloc.h"
#include "storage/fd.h"
@@ -67,8 +67,8 @@
* dynamic loading. Keep this here.)
*/
#ifndef RESERVE_FOR_LD
-#define RESERVE_FOR_LD 10
-#endif
+#define RESERVE_FOR_LD 10
+#endif
/*
* We need to ensure that we have at least some file descriptors
@@ -85,9 +85,9 @@
/* Debugging.... */
#ifdef FDDEBUG
-# define DO_DB(A) A
+#define DO_DB(A) A
#else
-# define DO_DB(A) /* A */
+#define DO_DB(A) /* A */
#endif
#define VFD_CLOSED -1
@@ -97,474 +97,501 @@
#define FileIsNotOpen(file) (VfdCache[file].fd == VFD_CLOSED)
-typedef struct vfd {
- signed short fd;
- unsigned short fdstate;
+typedef struct vfd
+{
+ signed short fd;
+ unsigned short fdstate;
-#define FD_DIRTY (1 << 0)
+#define FD_DIRTY (1 << 0)
- File nextFree;
- File lruMoreRecently;
- File lruLessRecently;
- long seekPos;
- char *fileName;
- int fileFlags;
- int fileMode;
-} Vfd;
+ File nextFree;
+ File lruMoreRecently;
+ File lruLessRecently;
+ long seekPos;
+ char *fileName;
+ int fileFlags;
+ int fileMode;
+} Vfd;
/*
- * Virtual File Descriptor array pointer and size. This grows as
+ * Virtual File Descriptor array pointer and size. This grows as
* needed.
*/
-static Vfd *VfdCache;
-static Size SizeVfdCache = 0;
+static Vfd *VfdCache;
+static Size SizeVfdCache = 0;
/*
* Number of file descriptors known to be open.
*/
-static int nfile = 0;
+static int nfile = 0;
-static char Sep_char = '/';
+static char Sep_char = '/';
/*
* Private Routines
*
- * Delete - delete a file from the Lru ring
- * LruDelete - remove a file from the Lru ring and close
- * Insert - put a file at the front of the Lru ring
- * LruInsert - put a file at the front of the Lru ring and open
+ * Delete - delete a file from the Lru ring
+ * LruDelete - remove a file from the Lru ring and close
+ * Insert - put a file at the front of the Lru ring
+ * LruInsert - put a file at the front of the Lru ring and open
* AssertLruRoom - make sure that there is a free fd.
*
* the Last Recently Used ring is a doubly linked list that begins and
* ends on element zero. Element zero is special -- it doesn't represent
- * a file and its "fd" field always == VFD_CLOSED. Element zero is just an
+ * a file and its "fd" field always == VFD_CLOSED. Element zero is just an
* anchor that shows us the beginning/end of the ring.
*
* example:
*
- * /--less----\ /---------\
- * v \ v \
- * #0 --more---> LeastRecentlyUsed --more-\ \
- * ^\ | |
- * \\less--> MostRecentlyUsedFile <---/ |
- * \more---/ \--less--/
+ * /--less----\ /---------\
+ * v \ v \
+ * #0 --more---> LeastRecentlyUsed --more-\ \
+ * ^\ | |
+ * \\less--> MostRecentlyUsedFile <---/ |
+ * \more---/ \--less--/
*
- * AllocateVfd - grab a free (or new) file record (from VfdArray)
- * FreeVfd - free a file record
+ * AllocateVfd - grab a free (or new) file record (from VfdArray)
+ * FreeVfd - free a file record
*
*/
-static void Delete(File file);
-static void LruDelete(File file);
-static void Insert(File file);
-static int LruInsert (File file);
-static void AssertLruRoom(void);
-static File AllocateVfd(void);
-static void FreeVfd(File file);
-
-static int FileAccess(File file);
-static File fileNameOpenFile(FileName fileName, int fileFlags, int fileMode);
-static char *filepath(char *filename);
-static long pg_nofile(void);
+static void Delete(File file);
+static void LruDelete(File file);
+static void Insert(File file);
+static int LruInsert(File file);
+static void AssertLruRoom(void);
+static File AllocateVfd(void);
+static void FreeVfd(File file);
+
+static int FileAccess(File file);
+static File fileNameOpenFile(FileName fileName, int fileFlags, int fileMode);
+static char *filepath(char *filename);
+static long pg_nofile(void);
int
pg_fsync(int fd)
{
- extern int fsyncOff;
- return fsyncOff ? 0 : fsync(fd);
+ extern int fsyncOff;
+
+ return fsyncOff ? 0 : fsync(fd);
}
+
#define fsync pg_fsync
long
pg_nofile(void)
{
- static long no_files = 0;
+ static long no_files = 0;
- if (no_files == 0) {
-#ifndef HAVE_SYSCONF
- no_files = (long)NOFILE;
+ if (no_files == 0)
+ {
+#ifndef HAVE_SYSCONF
+ no_files = (long) NOFILE;
#else
- no_files = sysconf(_SC_OPEN_MAX);
- if (no_files == -1) {
- elog(DEBUG,"pg_nofile: Unable to get _SC_OPEN_MAX using sysconf() using (%d)", NOFILE);
- no_files = (long)NOFILE;
+ no_files = sysconf(_SC_OPEN_MAX);
+ if (no_files == -1)
+ {
+ elog(DEBUG, "pg_nofile: Unable to get _SC_OPEN_MAX using sysconf() using (%d)", NOFILE);
+ no_files = (long) NOFILE;
}
-#endif
- }
+#endif
+ }
if ((no_files - RESERVE_FOR_LD) < FD_MINFREE)
- elog(FATAL,"pg_nofile: insufficient File Descriptors in postmaster to start backend (%ld).\n"
- " O/S allows %ld, Postmaster reserves %d, We need %d (MIN) after that.",
- no_files - RESERVE_FOR_LD, no_files, RESERVE_FOR_LD, FD_MINFREE);
- return no_files - RESERVE_FOR_LD;
+ elog(FATAL, "pg_nofile: insufficient File Descriptors in postmaster to start backend (%ld).\n"
+ " O/S allows %ld, Postmaster reserves %d, We need %d (MIN) after that.",
+ no_files - RESERVE_FOR_LD, no_files, RESERVE_FOR_LD, FD_MINFREE);
+ return no_files - RESERVE_FOR_LD;
}
#if defined(FDDEBUG)
static void
_dump_lru()
{
- int mru = VfdCache[0].lruLessRecently;
- Vfd *vfdP = &VfdCache[mru];
- char buf[2048];
-
- sprintf(buf, "LRU: MOST %d ", mru);
- while (mru != 0)
- {
- mru = vfdP->lruLessRecently;
- vfdP = &VfdCache[mru];
- sprintf (buf + strlen(buf), "%d ", mru);
- }
- sprintf(buf + strlen(buf), "LEAST");
- elog (DEBUG, buf);
+ int mru = VfdCache[0].lruLessRecently;
+ Vfd *vfdP = &VfdCache[mru];
+ char buf[2048];
+
+ sprintf(buf, "LRU: MOST %d ", mru);
+ while (mru != 0)
+ {
+ mru = vfdP->lruLessRecently;
+ vfdP = &VfdCache[mru];
+ sprintf(buf + strlen(buf), "%d ", mru);
+ }
+ sprintf(buf + strlen(buf), "LEAST");
+ elog(DEBUG, buf);
}
-#endif /* FDDEBUG */
+
+#endif /* FDDEBUG */
static void
Delete(File file)
{
- Vfd *fileP;
-
- DO_DB(elog (DEBUG, "Delete %d (%s)",
- file, VfdCache[file].fileName));
- DO_DB(_dump_lru());
-
- Assert(file != 0);
-
- fileP = &VfdCache[file];
-
- VfdCache[fileP->lruLessRecently].lruMoreRecently =
- VfdCache[file].lruMoreRecently;
- VfdCache[fileP->lruMoreRecently].lruLessRecently =
- VfdCache[file].lruLessRecently;
-
- DO_DB(_dump_lru());
+ Vfd *fileP;
+
+ DO_DB(elog(DEBUG, "Delete %d (%s)",
+ file, VfdCache[file].fileName));
+ DO_DB(_dump_lru());
+
+ Assert(file != 0);
+
+ fileP = &VfdCache[file];
+
+ VfdCache[fileP->lruLessRecently].lruMoreRecently =
+ VfdCache[file].lruMoreRecently;
+ VfdCache[fileP->lruMoreRecently].lruLessRecently =
+ VfdCache[file].lruLessRecently;
+
+ DO_DB(_dump_lru());
}
static void
LruDelete(File file)
{
- Vfd *fileP;
- int returnValue;
-
- DO_DB(elog (DEBUG, "LruDelete %d (%s)",
- file, VfdCache[file].fileName));
-
- Assert(file != 0);
-
- fileP = &VfdCache[file];
-
- /* delete the vfd record from the LRU ring */
- Delete(file);
-
- /* save the seek position */
- fileP->seekPos = (long) lseek(fileP->fd, 0L, SEEK_CUR);
- Assert( fileP->seekPos != -1);
-
- /* if we have written to the file, sync it */
- if (fileP->fdstate & FD_DIRTY) {
- returnValue = fsync(fileP->fd);
- Assert(returnValue != -1);
- fileP->fdstate &= ~FD_DIRTY;
- }
-
- /* close the file */
- returnValue = close(fileP->fd);
- Assert(returnValue != -1);
-
- --nfile;
- fileP->fd = VFD_CLOSED;
+ Vfd *fileP;
+ int returnValue;
+
+ DO_DB(elog(DEBUG, "LruDelete %d (%s)",
+ file, VfdCache[file].fileName));
+
+ Assert(file != 0);
+
+ fileP = &VfdCache[file];
+
+ /* delete the vfd record from the LRU ring */
+ Delete(file);
+
+ /* save the seek position */
+ fileP->seekPos = (long) lseek(fileP->fd, 0L, SEEK_CUR);
+ Assert(fileP->seekPos != -1);
+
+ /* if we have written to the file, sync it */
+ if (fileP->fdstate & FD_DIRTY)
+ {
+ returnValue = fsync(fileP->fd);
+ Assert(returnValue != -1);
+ fileP->fdstate &= ~FD_DIRTY;
+ }
+
+ /* close the file */
+ returnValue = close(fileP->fd);
+ Assert(returnValue != -1);
+
+ --nfile;
+ fileP->fd = VFD_CLOSED;
}
static void
Insert(File file)
{
- Vfd *vfdP;
-
- DO_DB(elog(DEBUG, "Insert %d (%s)",
- file, VfdCache[file].fileName));
- DO_DB(_dump_lru());
-
- vfdP = &VfdCache[file];
-
- vfdP->lruMoreRecently = 0;
- vfdP->lruLessRecently = VfdCache[0].lruLessRecently;
- VfdCache[0].lruLessRecently = file;
- VfdCache[vfdP->lruLessRecently].lruMoreRecently = file;
-
- DO_DB(_dump_lru());
+ Vfd *vfdP;
+
+ DO_DB(elog(DEBUG, "Insert %d (%s)",
+ file, VfdCache[file].fileName));
+ DO_DB(_dump_lru());
+
+ vfdP = &VfdCache[file];
+
+ vfdP->lruMoreRecently = 0;
+ vfdP->lruLessRecently = VfdCache[0].lruLessRecently;
+ VfdCache[0].lruLessRecently = file;
+ VfdCache[vfdP->lruLessRecently].lruMoreRecently = file;
+
+ DO_DB(_dump_lru());
}
static int
-LruInsert (File file)
+LruInsert(File file)
{
- Vfd *vfdP;
- int returnValue;
-
- DO_DB(elog(DEBUG, "LruInsert %d (%s)",
- file, VfdCache[file].fileName));
-
- vfdP = &VfdCache[file];
-
- if (FileIsNotOpen(file)) {
-
- if ( nfile >= pg_nofile() )
- AssertLruRoom();
-
- /*
- * Note, we check to see if there's a free file descriptor
- * before attempting to open a file. One general way to do
- * this is to try to open the null device which everybody
- * should be able to open all the time. If this fails, we
- * assume this is because there's no free file descriptors.
- */
- tryAgain:
- vfdP->fd = open(vfdP->fileName,vfdP->fileFlags,vfdP->fileMode);
- if (vfdP->fd < 0 && (errno == EMFILE || errno == ENFILE)) {
- errno = 0;
- AssertLruRoom();
- goto tryAgain;
- }
-
- if (vfdP->fd < 0) {
- DO_DB(elog(DEBUG, "RE_OPEN FAILED: %d",
- errno));
- return (vfdP->fd);
- } else {
- DO_DB(elog (DEBUG, "RE_OPEN SUCCESS"));
- ++nfile;
- }
-
- /* seek to the right position */
- if (vfdP->seekPos != 0L) {
- returnValue =
- lseek(vfdP->fd, vfdP->seekPos, SEEK_SET);
- Assert(returnValue != -1);
- }
-
- /* init state on open */
- vfdP->fdstate = 0x0;
-
- }
-
- /*
- * put it at the head of the Lru ring
- */
-
- Insert(file);
-
- return (0);
+ Vfd *vfdP;
+ int returnValue;
+
+ DO_DB(elog(DEBUG, "LruInsert %d (%s)",
+ file, VfdCache[file].fileName));
+
+ vfdP = &VfdCache[file];
+
+ if (FileIsNotOpen(file))
+ {
+
+ if (nfile >= pg_nofile())
+ AssertLruRoom();
+
+ /*
+ * Note, we check to see if there's a free file descriptor before
+ * attempting to open a file. One general way to do this is to try
+ * to open the null device which everybody should be able to open
+ * all the time. If this fails, we assume this is because there's
+ * no free file descriptors.
+ */
+tryAgain:
+ vfdP->fd = open(vfdP->fileName, vfdP->fileFlags, vfdP->fileMode);
+ if (vfdP->fd < 0 && (errno == EMFILE || errno == ENFILE))
+ {
+ errno = 0;
+ AssertLruRoom();
+ goto tryAgain;
+ }
+
+ if (vfdP->fd < 0)
+ {
+ DO_DB(elog(DEBUG, "RE_OPEN FAILED: %d",
+ errno));
+ return (vfdP->fd);
+ }
+ else
+ {
+ DO_DB(elog(DEBUG, "RE_OPEN SUCCESS"));
+ ++nfile;
+ }
+
+ /* seek to the right position */
+ if (vfdP->seekPos != 0L)
+ {
+ returnValue =
+ lseek(vfdP->fd, vfdP->seekPos, SEEK_SET);
+ Assert(returnValue != -1);
+ }
+
+ /* init state on open */
+ vfdP->fdstate = 0x0;
+
+ }
+
+ /*
+ * put it at the head of the Lru ring
+ */
+
+ Insert(file);
+
+ return (0);
}
static void
AssertLruRoom()
{
- DO_DB(elog(DEBUG, "AssertLruRoom. Opened %d", nfile));
-
- if ( nfile <= 0 )
- elog (FATAL, "AssertLruRoom: No opened files - no one can be closed");
- /*
- * There are opened files and so there should be at least one used vfd
- * in the ring.
- */
- Assert(VfdCache[0].lruMoreRecently != 0);
- LruDelete(VfdCache[0].lruMoreRecently);
+ DO_DB(elog(DEBUG, "AssertLruRoom. Opened %d", nfile));
+
+ if (nfile <= 0)
+ elog(FATAL, "AssertLruRoom: No opened files - no one can be closed");
+
+ /*
+ * There are opened files and so there should be at least one used vfd
+ * in the ring.
+ */
+ Assert(VfdCache[0].lruMoreRecently != 0);
+ LruDelete(VfdCache[0].lruMoreRecently);
}
-static File
+static File
AllocateVfd()
{
- Index i;
- File file;
-
- DO_DB(elog(DEBUG, "AllocateVfd. Size %d", SizeVfdCache));
-
- if (SizeVfdCache == 0) {
-
- /* initialize */
- VfdCache = (Vfd *)malloc(sizeof(Vfd));
- VfdCache->nextFree = 0;
- VfdCache->lruMoreRecently = 0;
- VfdCache->lruLessRecently = 0;
- VfdCache->fd = VFD_CLOSED;
- VfdCache->fdstate = 0x0;
-
- SizeVfdCache = 1;
- }
-
- if (VfdCache[0].nextFree == 0)
- {
- /*
- * The free list is empty so it is time to increase the
- * size of the array
- */
-
- VfdCache =(Vfd *)realloc(VfdCache, sizeof(Vfd)*SizeVfdCache*2);
- Assert(VfdCache != NULL);
-
- /*
- * Set up the free list for the new entries
- */
-
- for (i = SizeVfdCache; i < 2*SizeVfdCache; i++) {
- memset((char *) &(VfdCache[i]), 0, sizeof(VfdCache[0]));
- VfdCache[i].nextFree = i+1;
- VfdCache[i].fd = VFD_CLOSED;
- }
-
- /*
- * Element 0 is the first and last element of the free
- * list
- */
-
- VfdCache[0].nextFree = SizeVfdCache;
- VfdCache[2*SizeVfdCache-1].nextFree = 0;
-
- /*
- * Record the new size
- */
-
- SizeVfdCache *= 2;
- }
- file = VfdCache[0].nextFree;
-
- VfdCache[0].nextFree = VfdCache[file].nextFree;
-
- return file;
+ Index i;
+ File file;
+
+ DO_DB(elog(DEBUG, "AllocateVfd. Size %d", SizeVfdCache));
+
+ if (SizeVfdCache == 0)
+ {
+
+ /* initialize */
+ VfdCache = (Vfd *) malloc(sizeof(Vfd));
+ VfdCache->nextFree = 0;
+ VfdCache->lruMoreRecently = 0;
+ VfdCache->lruLessRecently = 0;
+ VfdCache->fd = VFD_CLOSED;
+ VfdCache->fdstate = 0x0;
+
+ SizeVfdCache = 1;
+ }
+
+ if (VfdCache[0].nextFree == 0)
+ {
+
+ /*
+ * The free list is empty so it is time to increase the size of
+ * the array
+ */
+
+ VfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * SizeVfdCache * 2);
+ Assert(VfdCache != NULL);
+
+ /*
+ * Set up the free list for the new entries
+ */
+
+ for (i = SizeVfdCache; i < 2 * SizeVfdCache; i++)
+ {
+ memset((char *) &(VfdCache[i]), 0, sizeof(VfdCache[0]));
+ VfdCache[i].nextFree = i + 1;
+ VfdCache[i].fd = VFD_CLOSED;
+ }
+
+ /*
+ * Element 0 is the first and last element of the free list
+ */
+
+ VfdCache[0].nextFree = SizeVfdCache;
+ VfdCache[2 * SizeVfdCache - 1].nextFree = 0;
+
+ /*
+ * Record the new size
+ */
+
+ SizeVfdCache *= 2;
+ }
+ file = VfdCache[0].nextFree;
+
+ VfdCache[0].nextFree = VfdCache[file].nextFree;
+
+ return file;
}
static void
FreeVfd(File file)
{
- DO_DB(elog(DEBUG, "FreeVfd: %d (%s)",
- file, VfdCache[file].fileName));
-
- VfdCache[file].nextFree = VfdCache[0].nextFree;
- VfdCache[0].nextFree = file;
+ DO_DB(elog(DEBUG, "FreeVfd: %d (%s)",
+ file, VfdCache[file].fileName));
+
+ VfdCache[file].nextFree = VfdCache[0].nextFree;
+ VfdCache[0].nextFree = file;
}
-static char *
+static char *
filepath(char *filename)
{
- char *buf;
- char basename[16];
- int len;
-
- if (*filename != Sep_char) {
- /* Either /base/ or \base\ */
- sprintf(basename, "%cbase%c", Sep_char, Sep_char);
-
- len = strlen(DataDir) + strlen(basename) + strlen(GetDatabaseName())
- + strlen(filename) + 2;
- buf = (char*) palloc(len);
- sprintf(buf, "%s%s%s%c%s",
- DataDir, basename, GetDatabaseName(), Sep_char, filename);
- } else {
- buf = (char *) palloc(strlen(filename) + 1);
- strcpy(buf, filename);
- }
-
- return(buf);
+ char *buf;
+ char basename[16];
+ int len;
+
+ if (*filename != Sep_char)
+ {
+ /* Either /base/ or \base\ */
+ sprintf(basename, "%cbase%c", Sep_char, Sep_char);
+
+ len = strlen(DataDir) + strlen(basename) + strlen(GetDatabaseName())
+ + strlen(filename) + 2;
+ buf = (char *) palloc(len);
+ sprintf(buf, "%s%s%s%c%s",
+ DataDir, basename, GetDatabaseName(), Sep_char, filename);
+ }
+ else
+ {
+ buf = (char *) palloc(strlen(filename) + 1);
+ strcpy(buf, filename);
+ }
+
+ return (buf);
}
static int
FileAccess(File file)
{
- int returnValue;
-
- DO_DB(elog(DEBUG, "FileAccess %d (%s)",
- file, VfdCache[file].fileName));
-
- /*
- * Is the file open? If not, close the least recently used,
- * then open it and stick it at the head of the used ring
- */
-
- if (FileIsNotOpen(file)) {
-
- returnValue = LruInsert(file);
- if (returnValue != 0)
- return returnValue;
-
- } else {
-
- /*
- * We now know that the file is open and that it is not the
- * last one accessed, so we need to more it to the head of
- * the Lru ring.
- */
-
- Delete(file);
- Insert(file);
- }
-
- return (0);
+ int returnValue;
+
+ DO_DB(elog(DEBUG, "FileAccess %d (%s)",
+ file, VfdCache[file].fileName));
+
+ /*
+ * Is the file open? If not, close the least recently used, then open
+ * it and stick it at the head of the used ring
+ */
+
+ if (FileIsNotOpen(file))
+ {
+
+ returnValue = LruInsert(file);
+ if (returnValue != 0)
+ return returnValue;
+
+ }
+ else
+ {
+
+ /*
+ * We now know that the file is open and that it is not the last
+ * one accessed, so we need to more it to the head of the Lru
+ * ring.
+ */
+
+ Delete(file);
+ Insert(file);
+ }
+
+ return (0);
}
/*
- * Called when we get a shared invalidation message on some relation.
+ * Called when we get a shared invalidation message on some relation.
*/
#ifdef NOT_USED
void
FileInvalidate(File file)
{
- Assert(file > 0);
- if (!FileIsNotOpen(file)) {
- LruDelete(file);
- }
+ Assert(file > 0);
+ if (!FileIsNotOpen(file))
+ {
+ LruDelete(file);
+ }
}
+
#endif
/* VARARGS2 */
-static File
+static File
fileNameOpenFile(FileName fileName,
- int fileFlags,
- int fileMode)
+ int fileFlags,
+ int fileMode)
{
- File file;
- Vfd *vfdP;
-
- DO_DB(elog(DEBUG, "fileNameOpenFile: %s %x %o",
- fileName, fileFlags, fileMode));
-
- file = AllocateVfd();
- vfdP = &VfdCache[file];
-
- if ( nfile >= pg_nofile() )
- AssertLruRoom();
-
- tryAgain:
- vfdP->fd = open(fileName,fileFlags,fileMode);
- if (vfdP->fd < 0 && (errno == EMFILE || errno == ENFILE)) {
- DO_DB(elog(DEBUG, "fileNameOpenFile: not enough descs, retry, er= %d",
- errno));
- errno = 0;
- AssertLruRoom();
- goto tryAgain;
- }
-
- vfdP->fdstate = 0x0;
-
- if (vfdP->fd < 0) {
- FreeVfd(file);
- return -1;
- }
- ++nfile;
- DO_DB(elog(DEBUG, "fileNameOpenFile: success %d",
- vfdP->fd));
-
- Insert(file);
-
- if (fileName==NULL) {
- elog(WARN, "fileNameOpenFile: NULL fname");
- }
- vfdP->fileName = malloc(strlen(fileName)+1);
- strcpy(vfdP->fileName,fileName);
-
- vfdP->fileFlags = fileFlags & ~(O_TRUNC|O_EXCL);
- vfdP->fileMode = fileMode;
- vfdP->seekPos = 0;
-
- return file;
+ File file;
+ Vfd *vfdP;
+
+ DO_DB(elog(DEBUG, "fileNameOpenFile: %s %x %o",
+ fileName, fileFlags, fileMode));
+
+ file = AllocateVfd();
+ vfdP = &VfdCache[file];
+
+ if (nfile >= pg_nofile())
+ AssertLruRoom();
+
+tryAgain:
+ vfdP->fd = open(fileName, fileFlags, fileMode);
+ if (vfdP->fd < 0 && (errno == EMFILE || errno == ENFILE))
+ {
+ DO_DB(elog(DEBUG, "fileNameOpenFile: not enough descs, retry, er= %d",
+ errno));
+ errno = 0;
+ AssertLruRoom();
+ goto tryAgain;
+ }
+
+ vfdP->fdstate = 0x0;
+
+ if (vfdP->fd < 0)
+ {
+ FreeVfd(file);
+ return -1;
+ }
+ ++nfile;
+ DO_DB(elog(DEBUG, "fileNameOpenFile: success %d",
+ vfdP->fd));
+
+ Insert(file);
+
+ if (fileName == NULL)
+ {
+ elog(WARN, "fileNameOpenFile: NULL fname");
+ }
+ vfdP->fileName = malloc(strlen(fileName) + 1);
+ strcpy(vfdP->fileName, fileName);
+
+ vfdP->fileFlags = fileFlags & ~(O_TRUNC | O_EXCL);
+ vfdP->fileMode = fileMode;
+ vfdP->seekPos = 0;
+
+ return file;
}
/*
@@ -573,13 +600,13 @@ fileNameOpenFile(FileName fileName,
File
FileNameOpenFile(FileName fileName, int fileFlags, int fileMode)
{
- File fd;
- char *fname;
-
- fname = filepath(fileName);
- fd = fileNameOpenFile(fname, fileFlags, fileMode);
- pfree(fname);
- return(fd);
+ File fd;
+ char *fname;
+
+ fname = filepath(fileName);
+ fd = fileNameOpenFile(fname, fileFlags, fileMode);
+ pfree(fname);
+ return (fd);
}
/*
@@ -588,150 +615,162 @@ FileNameOpenFile(FileName fileName, int fileFlags, int fileMode)
File
PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
{
- return(fileNameOpenFile(fileName, fileFlags, fileMode));
+ return (fileNameOpenFile(fileName, fileFlags, fileMode));
}
void
FileClose(File file)
{
- int returnValue;
-
- DO_DB(elog(DEBUG, "FileClose: %d (%s)",
- file, VfdCache[file].fileName));
-
- if (!FileIsNotOpen(file)) {
-
- /* remove the file from the lru ring */
- Delete(file);
-
- /* if we did any writes, sync the file before closing */
- if (VfdCache[file].fdstate & FD_DIRTY) {
- returnValue = fsync(VfdCache[file].fd);
- Assert(returnValue != -1);
- VfdCache[file].fdstate &= ~FD_DIRTY;
- }
-
- /* close the file */
- returnValue = close(VfdCache[file].fd);
- Assert(returnValue != -1);
-
- --nfile;
- VfdCache[file].fd = VFD_CLOSED;
- }
- /*
- * Add the Vfd slot to the free list
- */
- FreeVfd(file);
- /*
- * Free the filename string
- */
- free(VfdCache[file].fileName);
+ int returnValue;
+
+ DO_DB(elog(DEBUG, "FileClose: %d (%s)",
+ file, VfdCache[file].fileName));
+
+ if (!FileIsNotOpen(file))
+ {
+
+ /* remove the file from the lru ring */
+ Delete(file);
+
+ /* if we did any writes, sync the file before closing */
+ if (VfdCache[file].fdstate & FD_DIRTY)
+ {
+ returnValue = fsync(VfdCache[file].fd);
+ Assert(returnValue != -1);
+ VfdCache[file].fdstate &= ~FD_DIRTY;
+ }
+
+ /* close the file */
+ returnValue = close(VfdCache[file].fd);
+ Assert(returnValue != -1);
+
+ --nfile;
+ VfdCache[file].fd = VFD_CLOSED;
+ }
+
+ /*
+ * Add the Vfd slot to the free list
+ */
+ FreeVfd(file);
+
+ /*
+ * Free the filename string
+ */
+ free(VfdCache[file].fileName);
}
void
FileUnlink(File file)
{
- int returnValue;
-
- DO_DB(elog(DEBUG, "FileUnlink: %d (%s)",
- file, VfdCache[file].fileName));
-
- if (!FileIsNotOpen(file)) {
-
- /* remove the file from the lru ring */
- Delete(file);
-
- /* if we did any writes, sync the file before closing */
- if (VfdCache[file].fdstate & FD_DIRTY) {
- returnValue = fsync(VfdCache[file].fd);
- Assert(returnValue != -1);
- VfdCache[file].fdstate &= ~FD_DIRTY;
- }
-
- /* close the file */
- returnValue = close(VfdCache[file].fd);
- Assert(returnValue != -1);
-
- --nfile;
- VfdCache[file].fd = VFD_CLOSED;
- }
- /* add the Vfd slot to the free list */
- FreeVfd(file);
-
- /* free the filename string */
- unlink(VfdCache[file].fileName);
- free(VfdCache[file].fileName);
+ int returnValue;
+
+ DO_DB(elog(DEBUG, "FileUnlink: %d (%s)",
+ file, VfdCache[file].fileName));
+
+ if (!FileIsNotOpen(file))
+ {
+
+ /* remove the file from the lru ring */
+ Delete(file);
+
+ /* if we did any writes, sync the file before closing */
+ if (VfdCache[file].fdstate & FD_DIRTY)
+ {
+ returnValue = fsync(VfdCache[file].fd);
+ Assert(returnValue != -1);
+ VfdCache[file].fdstate &= ~FD_DIRTY;
+ }
+
+ /* close the file */
+ returnValue = close(VfdCache[file].fd);
+ Assert(returnValue != -1);
+
+ --nfile;
+ VfdCache[file].fd = VFD_CLOSED;
+ }
+ /* add the Vfd slot to the free list */
+ FreeVfd(file);
+
+ /* free the filename string */
+ unlink(VfdCache[file].fileName);
+ free(VfdCache[file].fileName);
}
int
FileRead(File file, char *buffer, int amount)
{
- int returnCode;
-
- DO_DB(elog(DEBUG, "FileRead: %d (%s) %d %p",
- file, VfdCache[file].fileName, amount, buffer));
-
- FileAccess(file);
- returnCode = read(VfdCache[file].fd, buffer, amount);
- if (returnCode > 0) {
- VfdCache[file].seekPos += returnCode;
- }
-
- return returnCode;
+ int returnCode;
+
+ DO_DB(elog(DEBUG, "FileRead: %d (%s) %d %p",
+ file, VfdCache[file].fileName, amount, buffer));
+
+ FileAccess(file);
+ returnCode = read(VfdCache[file].fd, buffer, amount);
+ if (returnCode > 0)
+ {
+ VfdCache[file].seekPos += returnCode;
+ }
+
+ return returnCode;
}
int
FileWrite(File file, char *buffer, int amount)
{
- int returnCode;
-
- DO_DB(elog(DEBUG, "FileWrite: %d (%s) %d %p",
- file, VfdCache[file].fileName, amount, buffer));
-
- FileAccess(file);
- returnCode = write(VfdCache[file].fd, buffer, amount);
- if (returnCode > 0) { /* changed by Boris with Mao's advice */
- VfdCache[file].seekPos += returnCode;
- }
-
- /* record the write */
- VfdCache[file].fdstate |= FD_DIRTY;
-
- return returnCode;
+ int returnCode;
+
+ DO_DB(elog(DEBUG, "FileWrite: %d (%s) %d %p",
+ file, VfdCache[file].fileName, amount, buffer));
+
+ FileAccess(file);
+ returnCode = write(VfdCache[file].fd, buffer, amount);
+ if (returnCode > 0)
+ { /* changed by Boris with Mao's advice */
+ VfdCache[file].seekPos += returnCode;
+ }
+
+ /* record the write */
+ VfdCache[file].fdstate |= FD_DIRTY;
+
+ return returnCode;
}
long
FileSeek(File file, long offset, int whence)
{
- int returnCode;
-
- DO_DB(elog (DEBUG, "FileSeek: %d (%s) %ld %d",
- file, VfdCache[file].fileName, offset, whence));
-
- if (FileIsNotOpen(file)) {
- switch(whence) {
- case SEEK_SET:
- VfdCache[file].seekPos = offset;
- return offset;
- case SEEK_CUR:
- VfdCache[file].seekPos = VfdCache[file].seekPos +offset;
- return VfdCache[file].seekPos;
- case SEEK_END:
- FileAccess(file);
- returnCode = VfdCache[file].seekPos =
- lseek(VfdCache[file].fd, offset, whence);
- return returnCode;
- default:
- elog(WARN, "FileSeek: invalid whence: %d", whence);
- break;
- }
- } else {
- returnCode = VfdCache[file].seekPos =
- lseek(VfdCache[file].fd, offset, whence);
- return returnCode;
- }
- /*NOTREACHED*/
- return(-1L);
+ int returnCode;
+
+ DO_DB(elog(DEBUG, "FileSeek: %d (%s) %ld %d",
+ file, VfdCache[file].fileName, offset, whence));
+
+ if (FileIsNotOpen(file))
+ {
+ switch (whence)
+ {
+ case SEEK_SET:
+ VfdCache[file].seekPos = offset;
+ return offset;
+ case SEEK_CUR:
+ VfdCache[file].seekPos = VfdCache[file].seekPos + offset;
+ return VfdCache[file].seekPos;
+ case SEEK_END:
+ FileAccess(file);
+ returnCode = VfdCache[file].seekPos =
+ lseek(VfdCache[file].fd, offset, whence);
+ return returnCode;
+ default:
+ elog(WARN, "FileSeek: invalid whence: %d", whence);
+ break;
+ }
+ }
+ else
+ {
+ returnCode = VfdCache[file].seekPos =
+ lseek(VfdCache[file].fd, offset, whence);
+ return returnCode;
+ }
+ /* NOTREACHED */
+ return (-1L);
}
/*
@@ -741,58 +780,61 @@ FileSeek(File file, long offset, int whence)
long
FileTell(File file)
{
- DO_DB(elog(DEBUG, "FileTell %d (%s)",
- file, VfdCache[file].fileName));
- return VfdCache[file].seekPos;
+ DO_DB(elog(DEBUG, "FileTell %d (%s)",
+ file, VfdCache[file].fileName));
+ return VfdCache[file].seekPos;
}
+
#endif
int
FileTruncate(File file, int offset)
{
- int returnCode;
-
- DO_DB(elog(DEBUG, "FileTruncate %d (%s)",
- file, VfdCache[file].fileName));
-
- FileSync(file);
- FileAccess(file);
- returnCode = ftruncate(VfdCache[file].fd, offset);
- return(returnCode);
+ int returnCode;
+
+ DO_DB(elog(DEBUG, "FileTruncate %d (%s)",
+ file, VfdCache[file].fileName));
+
+ FileSync(file);
+ FileAccess(file);
+ returnCode = ftruncate(VfdCache[file].fd, offset);
+ return (returnCode);
}
int
FileSync(File file)
{
- int returnCode;
-
- /*
- * If the file isn't open, then we don't need to sync it; we
- * always sync files when we close them. Also, if we haven't
- * done any writes that we haven't already synced, we can ignore
- * the request.
- */
-
- if (VfdCache[file].fd < 0 || !(VfdCache[file].fdstate & FD_DIRTY)) {
- returnCode = 0;
- } else {
- returnCode = fsync(VfdCache[file].fd);
- VfdCache[file].fdstate &= ~FD_DIRTY;
- }
-
- return returnCode;
+ int returnCode;
+
+ /*
+ * If the file isn't open, then we don't need to sync it; we always
+ * sync files when we close them. Also, if we haven't done any writes
+ * that we haven't already synced, we can ignore the request.
+ */
+
+ if (VfdCache[file].fd < 0 || !(VfdCache[file].fdstate & FD_DIRTY))
+ {
+ returnCode = 0;
+ }
+ else
+ {
+ returnCode = fsync(VfdCache[file].fd);
+ VfdCache[file].fdstate &= ~FD_DIRTY;
+ }
+
+ return returnCode;
}
int
FileNameUnlink(char *filename)
{
- int retval;
- char *fname;
+ int retval;
+ char *fname;
- fname = filepath(filename);
- retval = unlink(fname);
- pfree(fname);
- return(retval);
+ fname = filepath(filename);
+ retval = unlink(fname);
+ pfree(fname);
+ return (retval);
}
/*
@@ -804,33 +846,36 @@ FileNameUnlink(char *filename)
* allocatedFiles keeps track of how many have been allocated so we
* can give a warning if there are too few left.
*/
-static int allocatedFiles = 0;
+static int allocatedFiles = 0;
-FILE *
+FILE *
AllocateFile(char *name, char *mode)
{
- FILE *file;
- int fdleft;
-
- DO_DB(elog(DEBUG, "AllocateFile: Allocated %d.", allocatedFiles));
+ FILE *file;
+ int fdleft;
+
+ DO_DB(elog(DEBUG, "AllocateFile: Allocated %d.", allocatedFiles));
TryAgain:
- if ((file = fopen(name, mode)) == NULL) {
- if (errno == EMFILE || errno == ENFILE) {
- DO_DB(elog(DEBUG, "AllocateFile: not enough descs, retry, er= %d",
- errno));
- errno = 0;
- AssertLruRoom();
- goto TryAgain;
- }
- }
- else {
- ++allocatedFiles;
- fdleft = pg_nofile() - allocatedFiles;
- if (fdleft < 6)
- elog(NOTICE,"warning: few usable file descriptors left (%d)", fdleft);
- }
- return file;
+ if ((file = fopen(name, mode)) == NULL)
+ {
+ if (errno == EMFILE || errno == ENFILE)
+ {
+ DO_DB(elog(DEBUG, "AllocateFile: not enough descs, retry, er= %d",
+ errno));
+ errno = 0;
+ AssertLruRoom();
+ goto TryAgain;
+ }
+ }
+ else
+ {
+ ++allocatedFiles;
+ fdleft = pg_nofile() - allocatedFiles;
+ if (fdleft < 6)
+ elog(NOTICE, "warning: few usable file descriptors left (%d)", fdleft);
+ }
+ return file;
}
/*
@@ -838,22 +883,24 @@ TryAgain:
* AllocateFile()?
*/
void
-FreeFile(FILE *file)
+FreeFile(FILE * file)
{
- DO_DB(elog(DEBUG, "FreeFile: Allocated %d.", allocatedFiles));
+ DO_DB(elog(DEBUG, "FreeFile: Allocated %d.", allocatedFiles));
- Assert(allocatedFiles > 0);
- fclose(file);
- --allocatedFiles;
+ Assert(allocatedFiles > 0);
+ fclose(file);
+ --allocatedFiles;
}
void
closeAllVfds()
{
- int i;
- Assert (FileIsNotOpen(0)); /* Make sure ring not corrupted */
- for (i=1; i<SizeVfdCache; i++) {
- if (!FileIsNotOpen(i))
- LruDelete(i);
- }
+ int i;
+
+ Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
+ for (i = 1; i < SizeVfdCache; i++)
+ {
+ if (!FileIsNotOpen(i))
+ LruDelete(i);
+ }
}
diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c
index a5573e89151..3dd6d2ec094 100644
--- a/src/backend/storage/ipc/ipc.c
+++ b/src/backend/storage/ipc/ipc.c
@@ -1,26 +1,26 @@
/*-------------------------------------------------------------------------
*
* ipc.c--
- * POSTGRES inter-process communication definitions.
+ * POSTGRES inter-process communication definitions.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.11 1997/08/19 21:32:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.12 1997/09/07 04:48:30 momjian Exp $
*
* NOTES
*
- * Currently, semaphores are used (my understanding anyway) in two
- * different ways:
- * 1. as mutexes on machines that don't have test-and-set (eg.
- * mips R3000).
- * 2. for putting processes to sleep when waiting on a lock
- * and waking them up when the lock is free.
- * The number of semaphores in (1) is fixed and those are shared
- * among all backends. In (2), there is 1 semaphore per process and those
- * are not shared with anyone else.
- * -ay 4/95
+ * Currently, semaphores are used (my understanding anyway) in two
+ * different ways:
+ * 1. as mutexes on machines that don't have test-and-set (eg.
+ * mips R3000).
+ * 2. for putting processes to sleep when waiting on a lock
+ * and waking them up when the lock is free.
+ * The number of semaphores in (1) is fixed and those are shared
+ * among all backends. In (2), there is 1 semaphore per process and those
+ * are not shared with anyone else.
+ * -ay 4/95
*
*-------------------------------------------------------------------------
*/
@@ -44,94 +44,98 @@
#endif
#if defined(bsd44)
-int UsePrivateMemory = 1;
+int UsePrivateMemory = 1;
+
#else
-int UsePrivateMemory = 0;
+int UsePrivateMemory = 0;
+
#endif
-static void IpcMemoryDetach(int status, char *shmaddr);
+static void IpcMemoryDetach(int status, char *shmaddr);
/* ----------------------------------------------------------------
- * exit() handling stuff
+ * exit() handling stuff
* ----------------------------------------------------------------
*/
#define MAX_ON_EXITS 20
-static struct ONEXIT {
- void (*function)();
- caddr_t arg;
-} onexit_list[ MAX_ON_EXITS ];
+static struct ONEXIT
+{
+ void (*function) ();
+ caddr_t arg;
+} onexit_list[MAX_ON_EXITS];
-static int onexit_index;
-static void IpcConfigTip(void);
+static int onexit_index;
+static void IpcConfigTip(void);
-typedef struct _PrivateMemStruct {
- int id;
- char *memptr;
-} PrivateMem;
+typedef struct _PrivateMemStruct
+{
+ int id;
+ char *memptr;
+} PrivateMem;
-PrivateMem IpcPrivateMem[16];
+PrivateMem IpcPrivateMem[16];
static int
PrivateMemoryCreate(IpcMemoryKey memKey,
- uint32 size)
+ uint32 size)
{
- static int memid = 0;
-
- UsePrivateMemory = 1;
-
- IpcPrivateMem[memid].id = memid;
- IpcPrivateMem[memid].memptr = malloc(size);
- if (IpcPrivateMem[memid].memptr == NULL)
- elog(WARN, "PrivateMemoryCreate: not enough memory to malloc");
- memset(IpcPrivateMem[memid].memptr, 0, size); /* XXX PURIFY */
-
- return (memid++);
+ static int memid = 0;
+
+ UsePrivateMemory = 1;
+
+ IpcPrivateMem[memid].id = memid;
+ IpcPrivateMem[memid].memptr = malloc(size);
+ if (IpcPrivateMem[memid].memptr == NULL)
+ elog(WARN, "PrivateMemoryCreate: not enough memory to malloc");
+ memset(IpcPrivateMem[memid].memptr, 0, size); /* XXX PURIFY */
+
+ return (memid++);
}
-static char *
+static char *
PrivateMemoryAttach(IpcMemoryId memid)
{
- return ( IpcPrivateMem[memid].memptr );
+ return (IpcPrivateMem[memid].memptr);
}
/* ----------------------------------------------------------------
- * exitpg
+ * exitpg
*
- * this function calls all the callbacks registered
- * for it (to free resources) and then calls exit.
- * This should be the only function to call exit().
- * -cim 2/6/90
+ * this function calls all the callbacks registered
+ * for it (to free resources) and then calls exit.
+ * This should be the only function to call exit().
+ * -cim 2/6/90
* ----------------------------------------------------------------
*/
-static int exitpg_inprogress = 0;
+static int exitpg_inprogress = 0;
void
exitpg(int code)
{
- int i;
-
- /* ----------------
- * if exitpg_inprocess is true, then it means that we
- * are being invoked from within an on_exit() handler
- * and so we return immediately to avoid recursion.
- * ----------------
- */
- if (exitpg_inprogress)
- return;
-
- exitpg_inprogress = 1;
-
- /* ----------------
- * call all the callbacks registered before calling exit().
- * ----------------
- */
- for (i = onexit_index - 1; i >= 0; --i)
- (*onexit_list[i].function)(code, onexit_list[i].arg);
-
- exit(code);
+ int i;
+
+ /* ----------------
+ * if exitpg_inprocess is true, then it means that we
+ * are being invoked from within an on_exit() handler
+ * and so we return immediately to avoid recursion.
+ * ----------------
+ */
+ if (exitpg_inprogress)
+ return;
+
+ exitpg_inprogress = 1;
+
+ /* ----------------
+ * call all the callbacks registered before calling exit().
+ * ----------------
+ */
+ for (i = onexit_index - 1; i >= 0; --i)
+ (*onexit_list[i].function) (code, onexit_list[i].arg);
+
+ exit(code);
}
/* ------------------
@@ -143,591 +147,628 @@ exitpg(int code)
void
quasi_exitpg()
{
- int i;
-
- /* ----------------
- * if exitpg_inprocess is true, then it means that we
- * are being invoked from within an on_exit() handler
- * and so we return immediately to avoid recursion.
- * ----------------
- */
- if (exitpg_inprogress)
- return;
-
- exitpg_inprogress = 1;
-
- /* ----------------
- * call all the callbacks registered before calling exit().
- * ----------------
- */
- for (i = onexit_index - 1; i >= 0; --i)
- (*onexit_list[i].function)(0, onexit_list[i].arg);
-
- onexit_index = 0;
- exitpg_inprogress = 0;
+ int i;
+
+ /* ----------------
+ * if exitpg_inprocess is true, then it means that we
+ * are being invoked from within an on_exit() handler
+ * and so we return immediately to avoid recursion.
+ * ----------------
+ */
+ if (exitpg_inprogress)
+ return;
+
+ exitpg_inprogress = 1;
+
+ /* ----------------
+ * call all the callbacks registered before calling exit().
+ * ----------------
+ */
+ for (i = onexit_index - 1; i >= 0; --i)
+ (*onexit_list[i].function) (0, onexit_list[i].arg);
+
+ onexit_index = 0;
+ exitpg_inprogress = 0;
}
/* ----------------------------------------------------------------
- * on_exitpg
+ * on_exitpg
*
- * this function adds a callback function to the list of
- * functions invoked by exitpg(). -cim 2/6/90
+ * this function adds a callback function to the list of
+ * functions invoked by exitpg(). -cim 2/6/90
* ----------------------------------------------------------------
*/
int
-on_exitpg(void (*function)(), caddr_t arg)
+ on_exitpg(void (*function) (), caddr_t arg)
{
- if (onexit_index >= MAX_ON_EXITS)
- return(-1);
-
- onexit_list[ onexit_index ].function = function;
- onexit_list[ onexit_index ].arg = arg;
-
- ++onexit_index;
-
- return(0);
+ if (onexit_index >= MAX_ON_EXITS)
+ return (-1);
+
+ onexit_list[onexit_index].function = function;
+ onexit_list[onexit_index].arg = arg;
+
+ ++onexit_index;
+
+ return (0);
}
/****************************************************************************/
-/* IPCPrivateSemaphoreKill(status, semId) */
-/* */
+/* IPCPrivateSemaphoreKill(status, semId) */
+/* */
/****************************************************************************/
static void
IPCPrivateSemaphoreKill(int status,
- int semId) /* caddr_t */
+ int semId) /* caddr_t */
{
- union semun semun;
- semctl(semId, 0, IPC_RMID, semun);
+ union semun semun;
+
+ semctl(semId, 0, IPC_RMID, semun);
}
/****************************************************************************/
-/* IPCPrivateMemoryKill(status, shmId) */
-/* */
+/* IPCPrivateMemoryKill(status, shmId) */
+/* */
/****************************************************************************/
static void
IPCPrivateMemoryKill(int status,
- int shmId) /* caddr_t */
+ int shmId) /* caddr_t */
{
- if ( UsePrivateMemory ) {
- /* free ( IpcPrivateMem[shmId].memptr ); */
- } else {
- if (shmctl(shmId, IPC_RMID, (struct shmid_ds *) NULL) < 0) {
- elog(NOTICE, "IPCPrivateMemoryKill: shmctl(%d, %d, 0) failed: %m",
- shmId, IPC_RMID);
+ if (UsePrivateMemory)
+ {
+ /* free ( IpcPrivateMem[shmId].memptr ); */
+ }
+ else
+ {
+ if (shmctl(shmId, IPC_RMID, (struct shmid_ds *) NULL) < 0)
+ {
+ elog(NOTICE, "IPCPrivateMemoryKill: shmctl(%d, %d, 0) failed: %m",
+ shmId, IPC_RMID);
+ }
}
- }
}
/****************************************************************************/
-/* IpcSemaphoreCreate(semKey, semNum, permission, semStartValue) */
-/* */
-/* - returns a semaphore identifier: */
-/* */
+/* IpcSemaphoreCreate(semKey, semNum, permission, semStartValue) */
+/* */
+/* - returns a semaphore identifier: */
+/* */
/* if key doesn't exist: return a new id, status:= IpcSemIdNotExist */
-/* if key exists: return the old id, status:= IpcSemIdExist */
-/* if semNum > MAX : return # of argument, status:=IpcInvalidArgument */
-/* */
+/* if key exists: return the old id, status:= IpcSemIdExist */
+/* if semNum > MAX : return # of argument, status:=IpcInvalidArgument */
+/* */
/****************************************************************************/
/*
* Note:
- * XXX This should be split into two different calls. One should
- * XXX be used to create a semaphore set. The other to "attach" a
+ * XXX This should be split into two different calls. One should
+ * XXX be used to create a semaphore set. The other to "attach" a
* XXX existing set. It should be an error for the semaphore set
* XXX to to already exist or for it not to, respectively.
*
- * Currently, the semaphore sets are "attached" and an error
- * is detected only when a later shared memory attach fails.
+ * Currently, the semaphore sets are "attached" and an error
+ * is detected only when a later shared memory attach fails.
*/
IpcSemaphoreId
IpcSemaphoreCreate(IpcSemaphoreKey semKey,
- int semNum,
- int permission,
- int semStartValue,
- int removeOnExit,
- int *status)
+ int semNum,
+ int permission,
+ int semStartValue,
+ int removeOnExit,
+ int *status)
{
- int i;
- int errStatus;
- int semId;
- u_short array[IPC_NMAXSEM];
- union semun semun;
-
- /* get a semaphore if non-existent */
- /* check arguments */
- if (semNum > IPC_NMAXSEM || semNum <= 0) {
- *status = IpcInvalidArgument;
- return(2); /* returns the number of the invalid argument */
- }
-
- semId = semget(semKey, 0, 0);
-
- if (semId == -1) {
- *status = IpcSemIdNotExist; /* there doesn't exist a semaphore */
+ int i;
+ int errStatus;
+ int semId;
+ u_short array[IPC_NMAXSEM];
+ union semun semun;
+
+ /* get a semaphore if non-existent */
+ /* check arguments */
+ if (semNum > IPC_NMAXSEM || semNum <= 0)
+ {
+ *status = IpcInvalidArgument;
+ return (2); /* returns the number of the invalid
+ * argument */
+ }
+
+ semId = semget(semKey, 0, 0);
+
+ if (semId == -1)
+ {
+ *status = IpcSemIdNotExist; /* there doesn't exist a semaphore */
#ifdef DEBUG_IPC
- fprintf(stderr,"calling semget with %d, %d , %d\n",
- semKey,
- semNum,
- IPC_CREAT|permission );
+ fprintf(stderr, "calling semget with %d, %d , %d\n",
+ semKey,
+ semNum,
+ IPC_CREAT | permission);
#endif
- semId = semget(semKey, semNum, IPC_CREAT|permission);
+ semId = semget(semKey, semNum, IPC_CREAT | permission);
+
+ if (semId < 0)
+ {
+ perror("semget");
+ IpcConfigTip();
+ exitpg(3);
+ }
+ for (i = 0; i < semNum; i++)
+ {
+ array[i] = semStartValue;
+ }
+ semun.array = array;
+ errStatus = semctl(semId, 0, SETALL, semun);
+ if (errStatus == -1)
+ {
+ perror("semctl");
+ IpcConfigTip();
+ }
+
+ if (removeOnExit)
+ on_exitpg(IPCPrivateSemaphoreKill, (caddr_t) semId);
- if (semId < 0) {
- perror("semget");
- IpcConfigTip();
- exitpg(3);
- }
- for (i = 0; i < semNum; i++) {
- array[i] = semStartValue;
}
- semun.array = array;
- errStatus = semctl(semId, 0, SETALL, semun);
- if (errStatus == -1) {
- perror("semctl");
- IpcConfigTip();
+ else
+ {
+ /* there is a semaphore id for this key */
+ *status = IpcSemIdExist;
}
-
- if (removeOnExit)
- on_exitpg(IPCPrivateSemaphoreKill, (caddr_t)semId);
-
- } else {
- /* there is a semaphore id for this key */
- *status = IpcSemIdExist;
- }
-
+
#ifdef DEBUG_IPC
- fprintf(stderr,"\nIpcSemaphoreCreate, status %d, returns %d\n",
- *status,
- semId );
- fflush(stdout);
- fflush(stderr);
+ fprintf(stderr, "\nIpcSemaphoreCreate, status %d, returns %d\n",
+ *status,
+ semId);
+ fflush(stdout);
+ fflush(stderr);
#endif
- return(semId);
+ return (semId);
}
/****************************************************************************/
-/* IpcSemaphoreSet() - sets the initial value of the semaphore */
-/* */
-/* note: the xxx_return variables are only used for debugging. */
+/* IpcSemaphoreSet() - sets the initial value of the semaphore */
+/* */
+/* note: the xxx_return variables are only used for debugging. */
/****************************************************************************/
#ifdef NOT_USED
-static int IpcSemaphoreSet_return;
+static int IpcSemaphoreSet_return;
void
IpcSemaphoreSet(int semId, int semno, int value)
{
- int errStatus;
- union semun semun;
-
- semun.val = value;
- errStatus = semctl(semId, semno, SETVAL, semun);
- IpcSemaphoreSet_return = errStatus;
-
- if (errStatus == -1)
- {
- perror("semctl");
- IpcConfigTip();
- }
+ int errStatus;
+ union semun semun;
+
+ semun.val = value;
+ errStatus = semctl(semId, semno, SETVAL, semun);
+ IpcSemaphoreSet_return = errStatus;
+
+ if (errStatus == -1)
+ {
+ perror("semctl");
+ IpcConfigTip();
+ }
}
+
#endif
/****************************************************************************/
-/* IpcSemaphoreKill(key) - removes a semaphore */
-/* */
+/* IpcSemaphoreKill(key) - removes a semaphore */
+/* */
/****************************************************************************/
void
IpcSemaphoreKill(IpcSemaphoreKey key)
{
- int semId;
- union semun semun;
-
- /* kill semaphore if existent */
-
- semId = semget(key, 0, 0);
- if (semId != -1)
- semctl(semId, 0, IPC_RMID, semun);
+ int semId;
+ union semun semun;
+
+ /* kill semaphore if existent */
+
+ semId = semget(key, 0, 0);
+ if (semId != -1)
+ semctl(semId, 0, IPC_RMID, semun);
}
/****************************************************************************/
-/* IpcSemaphoreLock(semId, sem, lock) - locks a semaphore */
-/* */
-/* note: the xxx_return variables are only used for debugging. */
+/* IpcSemaphoreLock(semId, sem, lock) - locks a semaphore */
+/* */
+/* note: the xxx_return variables are only used for debugging. */
/****************************************************************************/
-static int IpcSemaphoreLock_return;
+static int IpcSemaphoreLock_return;
void
IpcSemaphoreLock(IpcSemaphoreId semId, int sem, int lock)
{
- extern int errno;
- int errStatus;
- struct sembuf sops;
-
- sops.sem_op = lock;
- sops.sem_flg = 0;
- sops.sem_num = sem;
-
- /* ----------------
- * Note: if errStatus is -1 and errno == EINTR then it means we
- * returned from the operation prematurely because we were
- * sent a signal. So we try and lock the semaphore again.
- * I am not certain this is correct, but the semantics aren't
- * clear it fixes problems with parallel abort synchronization,
- * namely that after processing an abort signal, the semaphore
- * call returns with -1 (and errno == EINTR) before it should.
- * -cim 3/28/90
- * ----------------
- */
- do {
- errStatus = semop(semId, &sops, 1);
- } while (errStatus == -1 && errno == EINTR);
-
- IpcSemaphoreLock_return = errStatus;
-
- if (errStatus == -1) {
- perror("semop");
- IpcConfigTip();
- exitpg(255);
- }
+ extern int errno;
+ int errStatus;
+ struct sembuf sops;
+
+ sops.sem_op = lock;
+ sops.sem_flg = 0;
+ sops.sem_num = sem;
+
+ /* ----------------
+ * Note: if errStatus is -1 and errno == EINTR then it means we
+ * returned from the operation prematurely because we were
+ * sent a signal. So we try and lock the semaphore again.
+ * I am not certain this is correct, but the semantics aren't
+ * clear it fixes problems with parallel abort synchronization,
+ * namely that after processing an abort signal, the semaphore
+ * call returns with -1 (and errno == EINTR) before it should.
+ * -cim 3/28/90
+ * ----------------
+ */
+ do
+ {
+ errStatus = semop(semId, &sops, 1);
+ } while (errStatus == -1 && errno == EINTR);
+
+ IpcSemaphoreLock_return = errStatus;
+
+ if (errStatus == -1)
+ {
+ perror("semop");
+ IpcConfigTip();
+ exitpg(255);
+ }
}
/****************************************************************************/
-/* IpcSemaphoreUnlock(semId, sem, lock) - unlocks a semaphore */
-/* */
-/* note: the xxx_return variables are only used for debugging. */
+/* IpcSemaphoreUnlock(semId, sem, lock) - unlocks a semaphore */
+/* */
+/* note: the xxx_return variables are only used for debugging. */
/****************************************************************************/
-static int IpcSemaphoreUnlock_return;
+static int IpcSemaphoreUnlock_return;
void
IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem, int lock)
{
- extern int errno;
- int errStatus;
- struct sembuf sops;
-
- sops.sem_op = -lock;
- sops.sem_flg = 0;
- sops.sem_num = sem;
-
-
- /* ----------------
- * Note: if errStatus is -1 and errno == EINTR then it means we
- * returned from the operation prematurely because we were
- * sent a signal. So we try and lock the semaphore again.
- * I am not certain this is correct, but the semantics aren't
- * clear it fixes problems with parallel abort synchronization,
- * namely that after processing an abort signal, the semaphore
- * call returns with -1 (and errno == EINTR) before it should.
- * -cim 3/28/90
- * ----------------
- */
- do {
- errStatus = semop(semId, &sops, 1);
- } while (errStatus == -1 && errno == EINTR);
-
- IpcSemaphoreUnlock_return = errStatus;
-
- if (errStatus == -1) {
- perror("semop");
- IpcConfigTip();
- exitpg(255);
- }
+ extern int errno;
+ int errStatus;
+ struct sembuf sops;
+
+ sops.sem_op = -lock;
+ sops.sem_flg = 0;
+ sops.sem_num = sem;
+
+
+ /* ----------------
+ * Note: if errStatus is -1 and errno == EINTR then it means we
+ * returned from the operation prematurely because we were
+ * sent a signal. So we try and lock the semaphore again.
+ * I am not certain this is correct, but the semantics aren't
+ * clear it fixes problems with parallel abort synchronization,
+ * namely that after processing an abort signal, the semaphore
+ * call returns with -1 (and errno == EINTR) before it should.
+ * -cim 3/28/90
+ * ----------------
+ */
+ do
+ {
+ errStatus = semop(semId, &sops, 1);
+ } while (errStatus == -1 && errno == EINTR);
+
+ IpcSemaphoreUnlock_return = errStatus;
+
+ if (errStatus == -1)
+ {
+ perror("semop");
+ IpcConfigTip();
+ exitpg(255);
+ }
}
int
-IpcSemaphoreGetCount(IpcSemaphoreId semId, int sem)
+IpcSemaphoreGetCount(IpcSemaphoreId semId, int sem)
{
- int semncnt;
- union semun dummy; /* for Solaris */
-
- semncnt = semctl(semId, sem, GETNCNT, dummy);
- return semncnt;
+ int semncnt;
+ union semun dummy; /* for Solaris */
+
+ semncnt = semctl(semId, sem, GETNCNT, dummy);
+ return semncnt;
}
int
-IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem)
+IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem)
{
- int semval;
- union semun dummy; /* for Solaris */
-
- semval = semctl(semId, sem, GETVAL, dummy);
- return semval;
+ int semval;
+ union semun dummy; /* for Solaris */
+
+ semval = semctl(semId, sem, GETVAL, dummy);
+ return semval;
}
/****************************************************************************/
-/* IpcMemoryCreate(memKey) */
-/* */
-/* - returns the memory identifier, if creation succeeds */
-/* returns IpcMemCreationFailed, if failure */
+/* IpcMemoryCreate(memKey) */
+/* */
+/* - returns the memory identifier, if creation succeeds */
+/* returns IpcMemCreationFailed, if failure */
/****************************************************************************/
IpcMemoryId
IpcMemoryCreate(IpcMemoryKey memKey, uint32 size, int permission)
{
- IpcMemoryId shmid;
-
- if (memKey == PrivateIPCKey) {
- /* private */
- shmid = PrivateMemoryCreate(memKey, size);
- }else {
- shmid = shmget(memKey, size, IPC_CREAT|permission);
- }
-
- if (shmid < 0) {
- fprintf(stderr,"IpcMemoryCreate: memKey=%d , size=%d , permission=%d",
- memKey, size , permission );
- perror("IpcMemoryCreate: shmget(..., create, ...) failed");
- IpcConfigTip();
- return(IpcMemCreationFailed);
- }
-
- /* if (memKey == PrivateIPCKey) */
- on_exitpg(IPCPrivateMemoryKill, (caddr_t)shmid);
-
- return(shmid);
+ IpcMemoryId shmid;
+
+ if (memKey == PrivateIPCKey)
+ {
+ /* private */
+ shmid = PrivateMemoryCreate(memKey, size);
+ }
+ else
+ {
+ shmid = shmget(memKey, size, IPC_CREAT | permission);
+ }
+
+ if (shmid < 0)
+ {
+ fprintf(stderr, "IpcMemoryCreate: memKey=%d , size=%d , permission=%d",
+ memKey, size, permission);
+ perror("IpcMemoryCreate: shmget(..., create, ...) failed");
+ IpcConfigTip();
+ return (IpcMemCreationFailed);
+ }
+
+ /* if (memKey == PrivateIPCKey) */
+ on_exitpg(IPCPrivateMemoryKill, (caddr_t) shmid);
+
+ return (shmid);
}
/****************************************************************************/
-/* IpcMemoryIdGet(memKey, size) returns the shared memory Id */
-/* or IpcMemIdGetFailed */
+/* IpcMemoryIdGet(memKey, size) returns the shared memory Id */
+/* or IpcMemIdGetFailed */
/****************************************************************************/
IpcMemoryId
IpcMemoryIdGet(IpcMemoryKey memKey, uint32 size)
{
- IpcMemoryId shmid;
-
- shmid = shmget(memKey, size, 0);
-
- if (shmid < 0) {
- fprintf(stderr,"IpcMemoryIdGet: memKey=%d , size=%d , permission=%d",
- memKey, size , 0 );
- perror("IpcMemoryIdGet: shmget() failed");
- IpcConfigTip();
- return(IpcMemIdGetFailed);
- }
-
- return(shmid);
+ IpcMemoryId shmid;
+
+ shmid = shmget(memKey, size, 0);
+
+ if (shmid < 0)
+ {
+ fprintf(stderr, "IpcMemoryIdGet: memKey=%d , size=%d , permission=%d",
+ memKey, size, 0);
+ perror("IpcMemoryIdGet: shmget() failed");
+ IpcConfigTip();
+ return (IpcMemIdGetFailed);
+ }
+
+ return (shmid);
}
/****************************************************************************/
-/* IpcMemoryDetach(status, shmaddr) removes a shared memory segment */
-/* from a backend address space */
-/* (only called by backends running under the postmaster) */
+/* IpcMemoryDetach(status, shmaddr) removes a shared memory segment */
+/* from a backend address space */
+/* (only called by backends running under the postmaster) */
/****************************************************************************/
static void
IpcMemoryDetach(int status, char *shmaddr)
{
- if (shmdt(shmaddr) < 0) {
- elog(NOTICE, "IpcMemoryDetach: shmdt(0x%x): %m", shmaddr);
- }
+ if (shmdt(shmaddr) < 0)
+ {
+ elog(NOTICE, "IpcMemoryDetach: shmdt(0x%x): %m", shmaddr);
+ }
}
/****************************************************************************/
-/* IpcMemoryAttach(memId) returns the adress of shared memory */
-/* or IpcMemAttachFailed */
-/* */
-/* CALL IT: addr = (struct <MemoryStructure> *) IpcMemoryAttach(memId); */
-/* */
+/* IpcMemoryAttach(memId) returns the adress of shared memory */
+/* or IpcMemAttachFailed */
+/* */
+/* CALL IT: addr = (struct <MemoryStructure> *) IpcMemoryAttach(memId); */
+/* */
/****************************************************************************/
-char *
+char *
IpcMemoryAttach(IpcMemoryId memId)
{
- char *memAddress;
-
- if (UsePrivateMemory) {
- memAddress = (char *) PrivateMemoryAttach(memId);
- } else {
- memAddress = (char *) shmat(memId, 0, 0);
- }
-
- /* if ( *memAddress == -1) { XXX ??? */
- if ( memAddress == (char *)-1) {
- perror("IpcMemoryAttach: shmat() failed");
- IpcConfigTip();
- return(IpcMemAttachFailed);
- }
-
- if (!UsePrivateMemory)
- on_exitpg(IpcMemoryDetach, (caddr_t) memAddress);
-
- return((char *) memAddress);
+ char *memAddress;
+
+ if (UsePrivateMemory)
+ {
+ memAddress = (char *) PrivateMemoryAttach(memId);
+ }
+ else
+ {
+ memAddress = (char *) shmat(memId, 0, 0);
+ }
+
+ /* if ( *memAddress == -1) { XXX ??? */
+ if (memAddress == (char *) -1)
+ {
+ perror("IpcMemoryAttach: shmat() failed");
+ IpcConfigTip();
+ return (IpcMemAttachFailed);
+ }
+
+ if (!UsePrivateMemory)
+ on_exitpg(IpcMemoryDetach, (caddr_t) memAddress);
+
+ return ((char *) memAddress);
}
/****************************************************************************/
-/* IpcMemoryKill(memKey) removes a shared memory segment */
-/* (only called by the postmaster and standalone backends) */
+/* IpcMemoryKill(memKey) removes a shared memory segment */
+/* (only called by the postmaster and standalone backends) */
/****************************************************************************/
void
IpcMemoryKill(IpcMemoryKey memKey)
-{
- IpcMemoryId shmid;
-
- if (!UsePrivateMemory && (shmid = shmget(memKey, 0, 0)) >= 0) {
- if (shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL) < 0) {
- elog(NOTICE, "IpcMemoryKill: shmctl(%d, %d, 0) failed: %m",
- shmid, IPC_RMID);
+{
+ IpcMemoryId shmid;
+
+ if (!UsePrivateMemory && (shmid = shmget(memKey, 0, 0)) >= 0)
+ {
+ if (shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL) < 0)
+ {
+ elog(NOTICE, "IpcMemoryKill: shmctl(%d, %d, 0) failed: %m",
+ shmid, IPC_RMID);
+ }
}
- }
-}
+}
#ifdef HAS_TEST_AND_SET
/* ------------------
- * use hardware locks to replace semaphores for sequent machines
- * to avoid costs of swapping processes and to provide unlimited
- * supply of locks.
+ * use hardware locks to replace semaphores for sequent machines
+ * to avoid costs of swapping processes and to provide unlimited
+ * supply of locks.
* ------------------
*/
-static SLock *SLockArray = NULL;
-static SLock **FreeSLockPP;
-static int *UnusedSLockIP;
+static SLock *SLockArray = NULL;
+static SLock **FreeSLockPP;
+static int *UnusedSLockIP;
static slock_t *SLockMemoryLock;
static IpcMemoryId SLockMemoryId = -1;
-struct ipcdummy { /* to get alignment/size right */
- SLock *free;
- int unused;
- slock_t memlock;
- SLock slocks[NSLOCKS];
+struct ipcdummy
+{ /* to get alignment/size right */
+ SLock *free;
+ int unused;
+ slock_t memlock;
+ SLock slocks[NSLOCKS];
};
-static int SLockMemorySize = sizeof(struct ipcdummy);
+static int SLockMemorySize = sizeof(struct ipcdummy);
void
CreateAndInitSLockMemory(IPCKey key)
{
- int id;
- SLock *slckP;
-
- SLockMemoryId = IpcMemoryCreate(key,
- SLockMemorySize,
- 0700);
- AttachSLockMemory(key);
- *FreeSLockPP = NULL;
- *UnusedSLockIP = (int)FIRSTFREELOCKID;
- for (id=0; id<(int)FIRSTFREELOCKID; id++) {
- slckP = &(SLockArray[id]);
- S_INIT_LOCK(&(slckP->locklock));
- slckP->flag = NOLOCK;
- slckP->nshlocks = 0;
- S_INIT_LOCK(&(slckP->shlock));
- S_INIT_LOCK(&(slckP->exlock));
- S_INIT_LOCK(&(slckP->comlock));
- slckP->next = NULL;
- }
- return;
+ int id;
+ SLock *slckP;
+
+ SLockMemoryId = IpcMemoryCreate(key,
+ SLockMemorySize,
+ 0700);
+ AttachSLockMemory(key);
+ *FreeSLockPP = NULL;
+ *UnusedSLockIP = (int) FIRSTFREELOCKID;
+ for (id = 0; id < (int) FIRSTFREELOCKID; id++)
+ {
+ slckP = &(SLockArray[id]);
+ S_INIT_LOCK(&(slckP->locklock));
+ slckP->flag = NOLOCK;
+ slckP->nshlocks = 0;
+ S_INIT_LOCK(&(slckP->shlock));
+ S_INIT_LOCK(&(slckP->exlock));
+ S_INIT_LOCK(&(slckP->comlock));
+ slckP->next = NULL;
+ }
+ return;
}
void
AttachSLockMemory(IPCKey key)
{
- struct ipcdummy *slockM;
-
- if (SLockMemoryId == -1)
- SLockMemoryId = IpcMemoryIdGet(key,SLockMemorySize);
- if (SLockMemoryId == -1)
- elog(FATAL, "SLockMemory not in shared memory");
- slockM = (struct ipcdummy *) IpcMemoryAttach(SLockMemoryId);
- if (slockM == IpcMemAttachFailed)
- elog(FATAL, "AttachSLockMemory: could not attach segment");
- FreeSLockPP = (SLock **) &(slockM->free);
- UnusedSLockIP = (int *) &(slockM->unused);
- SLockMemoryLock = (slock_t *) &(slockM->memlock);
- S_INIT_LOCK(SLockMemoryLock);
- SLockArray = (SLock *) &(slockM->slocks[0]);
- return;
+ struct ipcdummy *slockM;
+
+ if (SLockMemoryId == -1)
+ SLockMemoryId = IpcMemoryIdGet(key, SLockMemorySize);
+ if (SLockMemoryId == -1)
+ elog(FATAL, "SLockMemory not in shared memory");
+ slockM = (struct ipcdummy *) IpcMemoryAttach(SLockMemoryId);
+ if (slockM == IpcMemAttachFailed)
+ elog(FATAL, "AttachSLockMemory: could not attach segment");
+ FreeSLockPP = (SLock **) & (slockM->free);
+ UnusedSLockIP = (int *) &(slockM->unused);
+ SLockMemoryLock = (slock_t *) & (slockM->memlock);
+ S_INIT_LOCK(SLockMemoryLock);
+ SLockArray = (SLock *) & (slockM->slocks[0]);
+ return;
}
#ifdef LOCKDEBUG
#define PRINT_LOCK(LOCK) printf("(locklock = %d, flag = %d, nshlocks = %d, \
shlock = %d, exlock =%d)\n", LOCK->locklock, \
- LOCK->flag, LOCK->nshlocks, LOCK->shlock, \
- LOCK->exlock)
+ LOCK->flag, LOCK->nshlocks, LOCK->shlock, \
+ LOCK->exlock)
#endif
void
ExclusiveLock(int lockid)
{
- SLock *slckP;
- slckP = &(SLockArray[lockid]);
+ SLock *slckP;
+
+ slckP = &(SLockArray[lockid]);
#ifdef LOCKDEBUG
- printf("ExclusiveLock(%d)\n", lockid);
- printf("IN: ");
- PRINT_LOCK(slckP);
+ printf("ExclusiveLock(%d)\n", lockid);
+ printf("IN: ");
+ PRINT_LOCK(slckP);
#endif
- ex_try_again:
- S_LOCK(&(slckP->locklock));
- switch (slckP->flag) {
- case NOLOCK:
- slckP->flag = EXCLUSIVELOCK;
- S_LOCK(&(slckP->exlock));
- S_LOCK(&(slckP->shlock));
- S_UNLOCK(&(slckP->locklock));
+ex_try_again:
+ S_LOCK(&(slckP->locklock));
+ switch (slckP->flag)
+ {
+ case NOLOCK:
+ slckP->flag = EXCLUSIVELOCK;
+ S_LOCK(&(slckP->exlock));
+ S_LOCK(&(slckP->shlock));
+ S_UNLOCK(&(slckP->locklock));
#ifdef LOCKDEBUG
- printf("OUT: ");
- PRINT_LOCK(slckP);
+ printf("OUT: ");
+ PRINT_LOCK(slckP);
#endif
- return;
- case SHAREDLOCK:
- case EXCLUSIVELOCK:
- S_UNLOCK(&(slckP->locklock));
- S_LOCK(&(slckP->exlock));
- S_UNLOCK(&(slckP->exlock));
- goto ex_try_again;
- }
+ return;
+ case SHAREDLOCK:
+ case EXCLUSIVELOCK:
+ S_UNLOCK(&(slckP->locklock));
+ S_LOCK(&(slckP->exlock));
+ S_UNLOCK(&(slckP->exlock));
+ goto ex_try_again;
+ }
}
void
ExclusiveUnlock(int lockid)
{
- SLock *slckP;
-
- slckP = &(SLockArray[lockid]);
+ SLock *slckP;
+
+ slckP = &(SLockArray[lockid]);
#ifdef LOCKDEBUG
- printf("ExclusiveUnlock(%d)\n", lockid);
- printf("IN: ");
- PRINT_LOCK(slckP);
+ printf("ExclusiveUnlock(%d)\n", lockid);
+ printf("IN: ");
+ PRINT_LOCK(slckP);
#endif
- S_LOCK(&(slckP->locklock));
- /* -------------
- * give favor to read processes
- * -------------
- */
- slckP->flag = NOLOCK;
- if (slckP->nshlocks > 0) {
- while (slckP->nshlocks > 0) {
- S_UNLOCK(&(slckP->shlock));
- S_LOCK(&(slckP->comlock));
+ S_LOCK(&(slckP->locklock));
+ /* -------------
+ * give favor to read processes
+ * -------------
+ */
+ slckP->flag = NOLOCK;
+ if (slckP->nshlocks > 0)
+ {
+ while (slckP->nshlocks > 0)
+ {
+ S_UNLOCK(&(slckP->shlock));
+ S_LOCK(&(slckP->comlock));
+ }
+ S_UNLOCK(&(slckP->shlock));
}
- S_UNLOCK(&(slckP->shlock));
- }
- else {
- S_UNLOCK(&(slckP->shlock));
- }
- S_UNLOCK(&(slckP->exlock));
- S_UNLOCK(&(slckP->locklock));
+ else
+ {
+ S_UNLOCK(&(slckP->shlock));
+ }
+ S_UNLOCK(&(slckP->exlock));
+ S_UNLOCK(&(slckP->locklock));
#ifdef LOCKDEBUG
- printf("OUT: ");
- PRINT_LOCK(slckP);
+ printf("OUT: ");
+ PRINT_LOCK(slckP);
#endif
- return;
+ return;
}
bool
LockIsFree(int lockid)
{
- return(SLockArray[lockid].flag == NOLOCK);
+ return (SLockArray[lockid].flag == NOLOCK);
}
-#endif /* HAS_TEST_AND_SET */
+#endif /* HAS_TEST_AND_SET */
static void
IpcConfigTip(void)
{
- fprintf(stderr,"This type of error is usually caused by improper\n");
- fprintf(stderr,"shared memory or System V IPC semaphore configuration.\n");
- fprintf(stderr,"See the FAQ for more detailed information\n");
+ fprintf(stderr, "This type of error is usually caused by improper\n");
+ fprintf(stderr, "shared memory or System V IPC semaphore configuration.\n");
+ fprintf(stderr, "See the FAQ for more detailed information\n");
}
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index f949041f44d..4aad8e85f54 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* ipci.c--
- * POSTGRES inter-process communication initialization code.
+ * POSTGRES inter-process communication initialization code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.5 1997/01/08 08:32:03 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.6 1997/09/07 04:48:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,129 +23,131 @@
#include "storage/proc.h"
#include "storage/smgr.h"
#include "storage/lock.h"
-#include "miscadmin.h" /* for DebugLvl */
+#include "miscadmin.h" /* for DebugLvl */
/*
* SystemPortAddressCreateMemoryKey --
- * Returns a memory key given a port address.
+ * Returns a memory key given a port address.
*/
IPCKey
SystemPortAddressCreateIPCKey(SystemPortAddress address)
{
- Assert(address < 32768); /* XXX */
-
- return (SystemPortAddressGetIPCKey(address));
+ Assert(address < 32768); /* XXX */
+
+ return (SystemPortAddressGetIPCKey(address));
}
/*
* CreateSharedMemoryAndSemaphores --
- * Creates and initializes shared memory and semaphores.
+ * Creates and initializes shared memory and semaphores.
*/
/**************************************************
-
+
CreateSharedMemoryAndSemaphores
is called exactly *ONCE* by the postmaster.
It is *NEVER* called by the postgres backend
-
+
0) destroy any existing semaphores for both buffer
and lock managers.
1) create the appropriate *SHARED* memory segments
for the two resource managers.
-
+
**************************************************/
void
CreateSharedMemoryAndSemaphores(IPCKey key)
{
- int size;
-
+ int size;
+
#ifdef HAS_TEST_AND_SET
- /* ---------------
- * create shared memory for slocks
- * --------------
- */
- CreateAndInitSLockMemory(IPCKeyGetSLockSharedMemoryKey(key));
+ /* ---------------
+ * create shared memory for slocks
+ * --------------
+ */
+ CreateAndInitSLockMemory(IPCKeyGetSLockSharedMemoryKey(key));
#endif
- /* ----------------
- * kill and create the buffer manager buffer pool (and semaphore)
- * ----------------
- */
- CreateSpinlocks(IPCKeyGetSpinLockSemaphoreKey(key));
- size = BufferShmemSize() + LockShmemSize();
-
+ /* ----------------
+ * kill and create the buffer manager buffer pool (and semaphore)
+ * ----------------
+ */
+ CreateSpinlocks(IPCKeyGetSpinLockSemaphoreKey(key));
+ size = BufferShmemSize() + LockShmemSize();
+
#ifdef MAIN_MEMORY
- size += MMShmemSize();
-#endif /* MAIN_MEMORY */
-
- if (DebugLvl > 1) {
- fprintf(stderr, "binding ShmemCreate(key=%x, size=%d)\n",
- IPCKeyGetBufferMemoryKey(key), size);
- }
- ShmemCreate(IPCKeyGetBufferMemoryKey(key), size);
- ShmemBindingTabReset();
- InitShmem(key, size);
- InitBufferPool(key);
-
- /* ----------------
- * do the lock table stuff
- * ----------------
- */
- InitLocks();
- InitMultiLevelLockm();
- if (InitMultiLevelLockm() == INVALID_TABLEID)
- elog(FATAL, "Couldn't create the lock table");
-
- /* ----------------
- * do process table stuff
- * ----------------
- */
- InitProcGlobal(key);
- on_exitpg(ProcFreeAllSemaphores, 0);
-
- CreateSharedInvalidationState(key);
+ size += MMShmemSize();
+#endif /* MAIN_MEMORY */
+
+ if (DebugLvl > 1)
+ {
+ fprintf(stderr, "binding ShmemCreate(key=%x, size=%d)\n",
+ IPCKeyGetBufferMemoryKey(key), size);
+ }
+ ShmemCreate(IPCKeyGetBufferMemoryKey(key), size);
+ ShmemBindingTabReset();
+ InitShmem(key, size);
+ InitBufferPool(key);
+
+ /* ----------------
+ * do the lock table stuff
+ * ----------------
+ */
+ InitLocks();
+ InitMultiLevelLockm();
+ if (InitMultiLevelLockm() == INVALID_TABLEID)
+ elog(FATAL, "Couldn't create the lock table");
+
+ /* ----------------
+ * do process table stuff
+ * ----------------
+ */
+ InitProcGlobal(key);
+ on_exitpg(ProcFreeAllSemaphores, 0);
+
+ CreateSharedInvalidationState(key);
}
/*
* AttachSharedMemoryAndSemaphores --
- * Attachs existant shared memory and semaphores.
+ * Attachs existant shared memory and semaphores.
*/
void
AttachSharedMemoryAndSemaphores(IPCKey key)
{
- int size;
-
- /* ----------------
- * create rather than attach if using private key
- * ----------------
- */
- if (key == PrivateIPCKey) {
- CreateSharedMemoryAndSemaphores(key);
- return;
- }
-
+ int size;
+
+ /* ----------------
+ * create rather than attach if using private key
+ * ----------------
+ */
+ if (key == PrivateIPCKey)
+ {
+ CreateSharedMemoryAndSemaphores(key);
+ return;
+ }
+
#ifdef HAS_TEST_AND_SET
- /* ----------------
- * attach the slock shared memory
- * ----------------
- */
- AttachSLockMemory(IPCKeyGetSLockSharedMemoryKey(key));
+ /* ----------------
+ * attach the slock shared memory
+ * ----------------
+ */
+ AttachSLockMemory(IPCKeyGetSLockSharedMemoryKey(key));
#endif
- /* ----------------
- * attach the buffer manager buffer pool (and semaphore)
- * ----------------
- */
- size = BufferShmemSize() + LockShmemSize();
- InitShmem(key, size);
- InitBufferPool(key);
-
- /* ----------------
- * initialize lock table stuff
- * ----------------
- */
- InitLocks();
- if (InitMultiLevelLockm() == INVALID_TABLEID)
- elog(FATAL, "Couldn't attach to the lock table");
-
- AttachSharedInvalidationState(key);
+ /* ----------------
+ * attach the buffer manager buffer pool (and semaphore)
+ * ----------------
+ */
+ size = BufferShmemSize() + LockShmemSize();
+ InitShmem(key, size);
+ InitBufferPool(key);
+
+ /* ----------------
+ * initialize lock table stuff
+ * ----------------
+ */
+ InitLocks();
+ if (InitMultiLevelLockm() == INVALID_TABLEID)
+ elog(FATAL, "Couldn't attach to the lock table");
+
+ AttachSharedInvalidationState(key);
}
diff --git a/src/backend/storage/ipc/s_lock.c b/src/backend/storage/ipc/s_lock.c
index 146c2d7080a..70f0deb62c9 100644
--- a/src/backend/storage/ipc/s_lock.c
+++ b/src/backend/storage/ipc/s_lock.c
@@ -1,40 +1,40 @@
/*-------------------------------------------------------------------------
*
* s_lock.c--
- * This file contains the implementation (if any) for spinlocks.
+ * This file contains the implementation (if any) for spinlocks.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/s_lock.c,v 1.21 1997/09/05 18:10:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/s_lock.c,v 1.22 1997/09/07 04:48:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * DESCRIPTION
- * The following code fragment should be written (in assembly
- * language) on machines that have a native test-and-set instruction:
+ * DESCRIPTION
+ * The following code fragment should be written (in assembly
+ * language) on machines that have a native test-and-set instruction:
*
- * void
- * S_LOCK(char_address)
- * char *char_address;
- * {
- * while (test_and_set(char_address))
- * ;
- * }
+ * void
+ * S_LOCK(char_address)
+ * char *char_address;
+ * {
+ * while (test_and_set(char_address))
+ * ;
+ * }
*
- * If this is not done, POSTGRES will default to using System V
- * semaphores (and take a large performance hit -- around 40% of
- * its time on a DS5000/240 is spent in semop(3)...).
+ * If this is not done, POSTGRES will default to using System V
+ * semaphores (and take a large performance hit -- around 40% of
+ * its time on a DS5000/240 is spent in semop(3)...).
*
- * NOTES
- * AIX has a test-and-set but the recommended interface is the cs(3)
- * system call. This provides an 8-instruction (plus system call
- * overhead) uninterruptible compare-and-set operation. True
- * spinlocks might be faster but using cs(3) still speeds up the
- * regression test suite by about 25%. I don't have an assembler
- * manual for POWER in any case.
+ * NOTES
+ * AIX has a test-and-set but the recommended interface is the cs(3)
+ * system call. This provides an 8-instruction (plus system call
+ * overhead) uninterruptible compare-and-set operation. True
+ * spinlocks might be faster but using cs(3) still speeds up the
+ * regression test suite by about 25%. I don't have an assembler
+ * manual for POWER in any case.
*
*/
#include "postgres.h"
@@ -50,71 +50,71 @@
* slock_t is defined as a struct mutex.
*/
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
mutex_lock(lock);
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
mutex_unlock(lock);
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- mutex_init(lock);
+ mutex_init(lock);
}
/* S_LOCK_FREE should return 1 if lock is free; 0 if lock is locked */
int
- S_LOCK_FREE(slock_t *lock)
+S_LOCK_FREE(slock_t * lock)
{
/* For Mach, we have to delve inside the entrails of `struct mutex'. Ick! */
- return (lock->lock == 0);
+ return (lock->lock == 0);
}
-#endif /* next */
+#endif /* next */
#if defined(irix5)
/*
* SGI IRIX 5
- * slock_t is defined as a struct abilock_t, which has a single unsigned long
+ * slock_t is defined as a struct abilock_t, which has a single unsigned long
* member.
- *
+ *
* This stuff may be supplemented in the future with Masato Kataoka's MIPS-II
* assembly from his NECEWS SVR4 port, but we probably ought to retain this
* for the R3000 chips out there.
*/
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
/* spin_lock(lock); */
while (!acquire_lock(lock))
- ;
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
release_lock(lock);
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- init_lock(lock);
+ init_lock(lock);
}
/* S_LOCK_FREE should return 1 if lock is free; 0 if lock is locked */
int
-S_LOCK_FREE(slock_t *lock)
+S_LOCK_FREE(slock_t * lock)
{
- return(stat_lock(lock)==UNLOCKED);
+ return (stat_lock(lock) == UNLOCKED);
}
-#endif /* irix5 */
+#endif /* irix5 */
/*
@@ -127,62 +127,62 @@ S_LOCK_FREE(slock_t *lock)
#if defined(__alpha__) || defined(__alpha)
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- while (msem_lock(lock, MSEM_IF_NOWAIT) < 0)
- ;
+ while (msem_lock(lock, MSEM_IF_NOWAIT) < 0)
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- msem_unlock(lock, 0);
+ msem_unlock(lock, 0);
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- msem_init(lock, MSEM_UNLOCKED);
+ msem_init(lock, MSEM_UNLOCKED);
}
int
-S_LOCK_FREE(slock_t *lock)
+S_LOCK_FREE(slock_t * lock)
{
- return(lock->msem_state ? 0 : 1);
+ return (lock->msem_state ? 0 : 1);
}
-#endif /* alpha */
+#endif /* alpha */
/*
* Solaris 2
*/
#if defined(i386_solaris) || \
- defined(sparc_solaris)
+ defined(sparc_solaris)
/* for xxxxx_solaris, this is defined in port/.../tas.s */
-static int tas(slock_t *lock);
+static int tas(slock_t * lock);
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- while (tas(lock))
- ;
+ while (tas(lock))
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* i86pc_solaris || sparc_solaris */
+#endif /* i86pc_solaris || sparc_solaris */
/*
* AIX (POWER)
@@ -194,25 +194,25 @@ S_INIT_LOCK(slock_t *lock)
#if defined(aix)
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- while (cs((int *) lock, 0, 1))
- ;
+ while (cs((int *) lock, 0, 1))
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* aix */
+#endif /* aix */
/*
* HP-UX (PA-RISC)
@@ -224,90 +224,90 @@ S_INIT_LOCK(slock_t *lock)
#if defined(hpux)
/*
-* a "set" slock_t has a single word cleared. a "clear" slock_t has
+* a "set" slock_t has a single word cleared. a "clear" slock_t has
* all words set to non-zero.
*/
-static slock_t clear_lock = { -1, -1, -1, -1 };
+static slock_t clear_lock = {-1, -1, -1, -1};
-static int tas(slock_t *lock);
+static int tas(slock_t * lock);
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- while (tas(lock))
- ;
+ while (tas(lock))
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = clear_lock; /* struct assignment */
+ *lock = clear_lock; /* struct assignment */
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
int
-S_LOCK_FREE(slock_t *lock)
+S_LOCK_FREE(slock_t * lock)
{
- register int *lock_word = (int *) (((long) lock + 15) & ~15);
+ register int *lock_word = (int *) (((long) lock + 15) & ~15);
- return(*lock_word != 0);
+ return (*lock_word != 0);
}
-#endif /* hpux */
+#endif /* hpux */
/*
* sun3
*/
-
+
#if defined(sun3)
-static int tas(slock_t *lock);
+static int tas(slock_t * lock);
-void
-S_LOCK(slock_t *lock)
+void
+S_LOCK(slock_t * lock)
{
- while (tas(lock));
+ while (tas(lock));
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
static int
tas_dummy()
{
- asm("LLA0:");
- asm(" .data");
- asm(" .text");
- asm("|#PROC# 04");
- asm(" .globl _tas");
- asm("_tas:");
- asm("|#PROLOGUE# 1");
- asm(" movel sp@(0x4),a0");
- asm(" tas a0@");
- asm(" beq LLA1");
- asm(" moveq #-128,d0");
- asm(" rts");
- asm("LLA1:");
- asm(" moveq #0,d0");
- asm(" rts");
- asm(" .data");
-}
-
-#endif /* sun3 */
+ asm("LLA0:");
+ asm(" .data");
+ asm(" .text");
+ asm("|#PROC# 04");
+ asm(" .globl _tas");
+ asm("_tas:");
+ asm("|#PROLOGUE# 1");
+ asm(" movel sp@(0x4),a0");
+ asm(" tas a0@");
+ asm(" beq LLA1");
+ asm(" moveq #-128,d0");
+ asm(" rts");
+ asm("LLA1:");
+ asm(" moveq #0,d0");
+ asm(" rts");
+ asm(" .data");
+}
+
+#endif /* sun3 */
/*
* sparc machines
@@ -317,48 +317,48 @@ tas_dummy()
/* if we're using -ansi w/ gcc, use __asm__ instead of asm */
#if defined(__STRICT_ANSI__)
-#define asm(x) __asm__(x)
-#endif
+#define asm(x) __asm__(x)
+#endif
-static int tas(slock_t *lock);
+static int tas(slock_t * lock);
static int
tas_dummy()
{
- asm(".seg \"data\"");
- asm(".seg \"text\"");
- asm(".global _tas");
- asm("_tas:");
-
- /*
- * Sparc atomic test and set (sparc calls it "atomic load-store")
- */
-
- asm("ldstub [%r8], %r8");
-
- /*
- * Did test and set actually do the set?
- */
-
- asm("tst %r8");
-
- asm("be,a ReturnZero");
-
- /*
- * otherwise, just return.
- */
-
- asm("clr %r8");
- asm("mov 0x1, %r8");
- asm("ReturnZero:");
- asm("retl");
- asm("nop");
+ asm(".seg \"data\"");
+ asm(".seg \"text\"");
+ asm(".global _tas");
+ asm("_tas:");
+
+ /*
+ * Sparc atomic test and set (sparc calls it "atomic load-store")
+ */
+
+ asm("ldstub [%r8], %r8");
+
+ /*
+ * Did test and set actually do the set?
+ */
+
+ asm("tst %r8");
+
+ asm("be,a ReturnZero");
+
+ /*
+ * otherwise, just return.
+ */
+
+ asm("clr %r8");
+ asm("mov 0x1, %r8");
+ asm("ReturnZero:");
+ asm("retl");
+ asm("nop");
}
void
S_LOCK(unsigned char *addr)
{
- while (tas(addr));
+ while (tas(addr));
}
@@ -368,16 +368,16 @@ S_LOCK(unsigned char *addr)
void
S_UNLOCK(unsigned char *addr)
{
- *addr = 0;
+ *addr = 0;
}
void
S_INIT_LOCK(unsigned char *addr)
{
- *addr = 0;
+ *addr = 0;
}
-#endif /* NEED_SPARC_TAS_ASM */
+#endif /* NEED_SPARC_TAS_ASM */
/*
* i386 based things
@@ -386,39 +386,41 @@ S_INIT_LOCK(unsigned char *addr)
#if defined(NEED_I386_TAS_ASM)
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- slock_t res;
+ slock_t res;
- do{
- __asm__("xchgb %0,%1":"=q" (res),"=m" (*lock):"0" (0x1));
- }while(res != 0);
+ do
+ {
+__asm__("xchgb %0,%1": "=q"(res), "=m"(*lock):"0"(0x1));
+ } while (res != 0);
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* NEED_I386_TAS_ASM */
+#endif /* NEED_I386_TAS_ASM */
#if defined(__alpha__) && defined(linux)
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- slock_t res;
+ slock_t res;
- do{
- __asm__(" ldq $0, %0 \n\
+ do
+ {
+__asm__(" ldq $0, %0 \n\
bne $0, already_set \n\
ldq_l $0, %0 \n\
bne $0, already_set \n\
@@ -430,56 +432,58 @@ S_LOCK(slock_t *lock)
jmp $31, end \n\
stqc_fail: or $31, 1, $0 \n\
already_set: bis $0, $0, %1 \n\
- end: nop " : "=m" (*lock), "=r" (res) :: "0" );
- }while(res != 0);
+ end: nop ": "=m"(*lock), "=r"(res): :"0");
+ } while (res != 0);
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- __asm__("mb");
- *lock = 0;
+ __asm__("mb");
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* defined(__alpha__) && defined(linux) */
+#endif /* defined(__alpha__) && defined(linux) */
#if defined(linux) && defined(sparc)
-
+
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- slock_t res;
+ slock_t res;
- do{
- __asm__("ldstub [%1], %0"
- : "=&r" (res)
- : "r" (lock));
- }while(!res != 0);
+ do
+ {
+ __asm__("ldstub [%1], %0"
+: "=&r"(res)
+: "r"(lock));
+ } while (!res != 0);
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* defined(linux) && defined(sparc) */
+#endif /* defined(linux) && defined(sparc) */
#if defined(linux) && defined(PPC)
-static int tas_dummy()
+static int
+tas_dummy()
{
__asm__(" \n\
tas: \n\
@@ -496,26 +500,26 @@ success: \n\
blr \n\
");
}
-
+
void
-S_LOCK(slock_t *lock)
+S_LOCK(slock_t * lock)
{
- while (tas(lock))
- ;
+ while (tas(lock))
+ ;
}
void
-S_UNLOCK(slock_t *lock)
+S_UNLOCK(slock_t * lock)
{
- *lock = 0;
+ *lock = 0;
}
void
-S_INIT_LOCK(slock_t *lock)
+S_INIT_LOCK(slock_t * lock)
{
- S_UNLOCK(lock);
+ S_UNLOCK(lock);
}
-#endif /* defined(linux) && defined(PPC) */
+#endif /* defined(linux) && defined(PPC) */
-#endif /* HAS_TEST_AND_SET */
+#endif /* HAS_TEST_AND_SET */
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index c839059ea9b..63848171a1f 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* shmem.c--
- * create shared memory and initialize shared memory data structures.
+ * create shared memory and initialize shared memory data structures.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.10 1997/08/12 22:53:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.11 1997/09/07 04:48:37 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,43 +18,43 @@
* allocating and binding to shared memory data structures.
*
* NOTES:
- * (a) There are three kinds of shared memory data structures
- * available to POSTGRES: fixed-size structures, queues and hash
- * tables. Fixed-size structures contain things like global variables
- * for a module and should never be allocated after the process
- * initialization phase. Hash tables have a fixed maximum size, but
- * their actual size can vary dynamically. When entries are added
- * to the table, more space is allocated. Queues link data structures
- * that have been allocated either as fixed size structures or as hash
- * buckets. Each shared data structure has a string name to identify
- * it (assigned in the module that declares it).
+ * (a) There are three kinds of shared memory data structures
+ * available to POSTGRES: fixed-size structures, queues and hash
+ * tables. Fixed-size structures contain things like global variables
+ * for a module and should never be allocated after the process
+ * initialization phase. Hash tables have a fixed maximum size, but
+ * their actual size can vary dynamically. When entries are added
+ * to the table, more space is allocated. Queues link data structures
+ * that have been allocated either as fixed size structures or as hash
+ * buckets. Each shared data structure has a string name to identify
+ * it (assigned in the module that declares it).
*
- * (b) During initialization, each module looks for its
- * shared data structures in a hash table called the "Binding Table".
- * If the data structure is not present, the caller can allocate
- * a new one and initialize it. If the data structure is present,
- * the caller "attaches" to the structure by initializing a pointer
- * in the local address space.
- * The binding table has two purposes: first, it gives us
- * a simple model of how the world looks when a backend process
- * initializes. If something is present in the binding table,
- * it is initialized. If it is not, it is uninitialized. Second,
- * the binding table allows us to allocate shared memory on demand
- * instead of trying to preallocate structures and hard-wire the
- * sizes and locations in header files. If you are using a lot
- * of shared memory in a lot of different places (and changing
- * things during development), this is important.
+ * (b) During initialization, each module looks for its
+ * shared data structures in a hash table called the "Binding Table".
+ * If the data structure is not present, the caller can allocate
+ * a new one and initialize it. If the data structure is present,
+ * the caller "attaches" to the structure by initializing a pointer
+ * in the local address space.
+ * The binding table has two purposes: first, it gives us
+ * a simple model of how the world looks when a backend process
+ * initializes. If something is present in the binding table,
+ * it is initialized. If it is not, it is uninitialized. Second,
+ * the binding table allows us to allocate shared memory on demand
+ * instead of trying to preallocate structures and hard-wire the
+ * sizes and locations in header files. If you are using a lot
+ * of shared memory in a lot of different places (and changing
+ * things during development), this is important.
*
- * (c) memory allocation model: shared memory can never be
- * freed, once allocated. Each hash table has its own free list,
- * so hash buckets can be reused when an item is deleted. However,
- * if one hash table grows very large and then shrinks, its space
- * cannot be redistributed to other tables. We could build a simple
- * hash bucket garbage collector if need be. Right now, it seems
- * unnecessary.
+ * (c) memory allocation model: shared memory can never be
+ * freed, once allocated. Each hash table has its own free list,
+ * so hash buckets can be reused when an item is deleted. However,
+ * if one hash table grows very large and then shrinks, its space
+ * cannot be redistributed to other tables. We could build a simple
+ * hash bucket garbage collector if need be. Right now, it seems
+ * unnecessary.
*
- * See InitSem() in sem.c for an example of how to use the
- * binding table.
+ * See InitSem() in sem.c for an example of how to use the
+ * binding table.
*
*/
#include <stdio.h>
@@ -70,27 +70,23 @@
/* shared memory global variables */
-unsigned long ShmemBase = 0; /* start and end address of
- * shared memory
- */
-static unsigned long ShmemEnd = 0;
-static unsigned long ShmemSize = 0; /* current size (and default) */
+unsigned long ShmemBase = 0; /* start and end address of shared memory */
+static unsigned long ShmemEnd = 0;
+static unsigned long ShmemSize = 0; /* current size (and default) */
-SPINLOCK ShmemLock; /* lock for shared memory allocation */
+SPINLOCK ShmemLock; /* lock for shared memory allocation */
-SPINLOCK BindingLock; /* lock for binding table access */
+SPINLOCK BindingLock; /* lock for binding table access */
-static unsigned long *ShmemFreeStart = NULL; /* pointer to the OFFSET of
- * first free shared memory
- */
-static unsigned long *ShmemBindingTabOffset = NULL; /* start of the binding
- * table (for bootstrap)
- */
-static int ShmemBootstrap = FALSE; /* flag becomes true when shared mem
- * is created by POSTMASTER
- */
+static unsigned long *ShmemFreeStart = NULL; /* pointer to the OFFSET
+ * of first free shared
+ * memory */
+static unsigned long *ShmemBindingTabOffset = NULL; /* start of the binding
+ * table (for bootstrap) */
+static int ShmemBootstrap = FALSE; /* flag becomes true when shared
+ * mem is created by POSTMASTER */
-static HTAB *BindingTable = NULL;
+static HTAB *BindingTable = NULL;
/* ---------------------
* ShmemBindingTabReset() - Resets the binding table to NULL....
@@ -101,16 +97,16 @@ static HTAB *BindingTable = NULL;
void
ShmemBindingTabReset(void)
{
- BindingTable = (HTAB *)NULL;
+ BindingTable = (HTAB *) NULL;
}
/*
- * CreateSharedRegion() --
+ * CreateSharedRegion() --
*
- * This routine is called once by the postmaster to
- * initialize the shared buffer pool. Assume there is
- * only one postmaster so no synchronization is necessary
- * until after this routine completes successfully.
+ * This routine is called once by the postmaster to
+ * initialize the shared buffer pool. Assume there is
+ * only one postmaster so no synchronization is necessary
+ * until after this routine completes successfully.
*
* key is a unique identifier for the shmem region.
* size is the size of the region.
@@ -120,202 +116,220 @@ static IpcMemoryId ShmemId;
void
ShmemCreate(unsigned int key, unsigned int size)
{
- if (size)
- ShmemSize = size;
- /* create shared mem region */
- if ((ShmemId=IpcMemoryCreate(key,ShmemSize,IPCProtection))
- ==IpcMemCreationFailed) {
- elog(FATAL,"ShmemCreate: cannot create region");
- exit(1);
- }
-
- /* ShmemBootstrap is true if shared memory has been
- * created, but not yet initialized. Only the
- * postmaster/creator-of-all-things should have
- * this flag set.
- */
- ShmemBootstrap = TRUE;
+ if (size)
+ ShmemSize = size;
+ /* create shared mem region */
+ if ((ShmemId = IpcMemoryCreate(key, ShmemSize, IPCProtection))
+ == IpcMemCreationFailed)
+ {
+ elog(FATAL, "ShmemCreate: cannot create region");
+ exit(1);
+ }
+
+ /*
+ * ShmemBootstrap is true if shared memory has been created, but not
+ * yet initialized. Only the postmaster/creator-of-all-things should
+ * have this flag set.
+ */
+ ShmemBootstrap = TRUE;
}
/*
- * InitShmem() -- map region into process address space
- * and initialize shared data structures.
+ * InitShmem() -- map region into process address space
+ * and initialize shared data structures.
*
*/
int
InitShmem(unsigned int key, unsigned int size)
{
- Pointer sharedRegion;
- unsigned long currFreeSpace;
-
- HASHCTL info;
- int hash_flags;
- BindingEnt * result,item;
- bool found;
- IpcMemoryId shmid;
-
- /* if zero key, use default memory size */
- if (size)
- ShmemSize = size;
-
- /* default key is 0 */
-
- /* attach to shared memory region (SysV or BSD OS specific) */
- if (ShmemBootstrap && key == PrivateIPCKey)
- /* if we are running backend alone */
- shmid = ShmemId;
- else
- shmid = IpcMemoryIdGet(IPCKeyGetBufferMemoryKey(key), ShmemSize);
- sharedRegion = IpcMemoryAttach(shmid);
- if (sharedRegion == NULL) {
- elog(FATAL,"AttachSharedRegion: couldn't attach to shmem\n");
- return(FALSE);
- }
-
- /* get pointers to the dimensions of shared memory */
- ShmemBase = (unsigned long) sharedRegion;
- ShmemEnd = (unsigned long) sharedRegion + ShmemSize;
- currFreeSpace = 0;
-
- /* First long in shared memory is the count of available space */
- ShmemFreeStart = (unsigned long *) ShmemBase;
- /* next is a shmem pointer to the binding table */
- ShmemBindingTabOffset = ShmemFreeStart + 1;
-
- currFreeSpace +=
- sizeof(ShmemFreeStart) + sizeof(ShmemBindingTabOffset);
-
- /* bootstrap initialize spin locks so we can start to use the
- * allocator and binding table.
- */
- if (! InitSpinLocks(ShmemBootstrap, IPCKeyGetSpinLockSemaphoreKey(key))) {
- return(FALSE);
- }
-
- /* We have just allocated additional space for two spinlocks.
- * Now setup the global free space count
- */
- if (ShmemBootstrap) {
- *ShmemFreeStart = currFreeSpace;
- }
-
- /* if ShmemFreeStart is NULL, then the allocator won't work */
- Assert(*ShmemFreeStart);
-
- /* create OR attach to the shared memory binding table */
- info.keysize = BTABLE_KEYSIZE;
- info.datasize = BTABLE_DATASIZE;
- hash_flags = (HASH_ELEM);
-
- /* This will acquire the binding table lock, but not release it. */
- BindingTable = ShmemInitHash("BindingTable",
- BTABLE_SIZE,BTABLE_SIZE,
- &info,hash_flags);
-
- if (! BindingTable) {
- elog(FATAL,"InitShmem: couldn't initialize Binding Table");
- return(FALSE);
- }
-
- /* Now, check the binding table for an entry to the binding
- * table. If there is an entry there, someone else created
- * the table. Otherwise, we did and we have to initialize it.
- */
- memset(item.key, 0, BTABLE_KEYSIZE);
- strncpy(item.key,"BindingTable",BTABLE_KEYSIZE);
-
- result = (BindingEnt *)
- hash_search(BindingTable,(char *) &item,HASH_ENTER, &found);
-
-
- if (! result ) {
- elog(FATAL,"InitShmem: corrupted binding table");
- return(FALSE);
- }
-
- if (! found) {
- /* bootstrapping shmem: we have to initialize the
- * binding table now.
+ Pointer sharedRegion;
+ unsigned long currFreeSpace;
+
+ HASHCTL info;
+ int hash_flags;
+ BindingEnt *result,
+ item;
+ bool found;
+ IpcMemoryId shmid;
+
+ /* if zero key, use default memory size */
+ if (size)
+ ShmemSize = size;
+
+ /* default key is 0 */
+
+ /* attach to shared memory region (SysV or BSD OS specific) */
+ if (ShmemBootstrap && key == PrivateIPCKey)
+ /* if we are running backend alone */
+ shmid = ShmemId;
+ else
+ shmid = IpcMemoryIdGet(IPCKeyGetBufferMemoryKey(key), ShmemSize);
+ sharedRegion = IpcMemoryAttach(shmid);
+ if (sharedRegion == NULL)
+ {
+ elog(FATAL, "AttachSharedRegion: couldn't attach to shmem\n");
+ return (FALSE);
+ }
+
+ /* get pointers to the dimensions of shared memory */
+ ShmemBase = (unsigned long) sharedRegion;
+ ShmemEnd = (unsigned long) sharedRegion + ShmemSize;
+ currFreeSpace = 0;
+
+ /* First long in shared memory is the count of available space */
+ ShmemFreeStart = (unsigned long *) ShmemBase;
+ /* next is a shmem pointer to the binding table */
+ ShmemBindingTabOffset = ShmemFreeStart + 1;
+
+ currFreeSpace +=
+ sizeof(ShmemFreeStart) + sizeof(ShmemBindingTabOffset);
+
+ /*
+ * bootstrap initialize spin locks so we can start to use the
+ * allocator and binding table.
*/
-
- Assert(ShmemBootstrap);
- result->location = MAKE_OFFSET(BindingTable->hctl);
- *ShmemBindingTabOffset = result->location;
- result->size = BTABLE_SIZE;
-
- ShmemBootstrap = FALSE;
-
- } else {
- Assert(! ShmemBootstrap);
- }
- /* now release the lock acquired in ShmemHashInit */
- SpinRelease (BindingLock);
-
- Assert (result->location == MAKE_OFFSET(BindingTable->hctl));
-
- return(TRUE);
+ if (!InitSpinLocks(ShmemBootstrap, IPCKeyGetSpinLockSemaphoreKey(key)))
+ {
+ return (FALSE);
+ }
+
+ /*
+ * We have just allocated additional space for two spinlocks. Now
+ * setup the global free space count
+ */
+ if (ShmemBootstrap)
+ {
+ *ShmemFreeStart = currFreeSpace;
+ }
+
+ /* if ShmemFreeStart is NULL, then the allocator won't work */
+ Assert(*ShmemFreeStart);
+
+ /* create OR attach to the shared memory binding table */
+ info.keysize = BTABLE_KEYSIZE;
+ info.datasize = BTABLE_DATASIZE;
+ hash_flags = (HASH_ELEM);
+
+ /* This will acquire the binding table lock, but not release it. */
+ BindingTable = ShmemInitHash("BindingTable",
+ BTABLE_SIZE, BTABLE_SIZE,
+ &info, hash_flags);
+
+ if (!BindingTable)
+ {
+ elog(FATAL, "InitShmem: couldn't initialize Binding Table");
+ return (FALSE);
+ }
+
+ /*
+ * Now, check the binding table for an entry to the binding table. If
+ * there is an entry there, someone else created the table.
+ * Otherwise, we did and we have to initialize it.
+ */
+ memset(item.key, 0, BTABLE_KEYSIZE);
+ strncpy(item.key, "BindingTable", BTABLE_KEYSIZE);
+
+ result = (BindingEnt *)
+ hash_search(BindingTable, (char *) &item, HASH_ENTER, &found);
+
+
+ if (!result)
+ {
+ elog(FATAL, "InitShmem: corrupted binding table");
+ return (FALSE);
+ }
+
+ if (!found)
+ {
+
+ /*
+ * bootstrapping shmem: we have to initialize the binding table
+ * now.
+ */
+
+ Assert(ShmemBootstrap);
+ result->location = MAKE_OFFSET(BindingTable->hctl);
+ *ShmemBindingTabOffset = result->location;
+ result->size = BTABLE_SIZE;
+
+ ShmemBootstrap = FALSE;
+
+ }
+ else
+ {
+ Assert(!ShmemBootstrap);
+ }
+ /* now release the lock acquired in ShmemHashInit */
+ SpinRelease(BindingLock);
+
+ Assert(result->location == MAKE_OFFSET(BindingTable->hctl));
+
+ return (TRUE);
}
/*
* ShmemAlloc -- allocate word-aligned byte string from
- * shared memory
+ * shared memory
*
* Assumes ShmemLock and ShmemFreeStart are initialized.
* Returns: real pointer to memory or NULL if we are out
- * of space. Has to return a real pointer in order
- * to be compatable with malloc().
+ * of space. Has to return a real pointer in order
+ * to be compatable with malloc().
*/
-long *
+long *
ShmemAlloc(unsigned long size)
{
- unsigned long tmpFree;
- long *newSpace;
-
- /*
- * ensure space is word aligned.
- *
- * Word-alignment is not good enough. We have to be more
- * conservative: doubles need 8-byte alignment. (We probably only need
- * this on RISC platforms but this is not a big waste of space.)
- * - ay 12/94
- */
- if (size % sizeof(double))
- size += sizeof(double) - (size % sizeof(double));
-
- Assert(*ShmemFreeStart);
-
- SpinAcquire(ShmemLock);
-
- tmpFree = *ShmemFreeStart + size;
- if (tmpFree <= ShmemSize) {
- newSpace = (long *)MAKE_PTR(*ShmemFreeStart);
- *ShmemFreeStart += size;
- } else {
- newSpace = NULL;
- }
-
- SpinRelease(ShmemLock);
-
- if (! newSpace) {
- elog(NOTICE,"ShmemAlloc: out of memory ");
- }
- return(newSpace);
+ unsigned long tmpFree;
+ long *newSpace;
+
+ /*
+ * ensure space is word aligned.
+ *
+ * Word-alignment is not good enough. We have to be more conservative:
+ * doubles need 8-byte alignment. (We probably only need this on RISC
+ * platforms but this is not a big waste of space.) - ay 12/94
+ */
+ if (size % sizeof(double))
+ size += sizeof(double) - (size % sizeof(double));
+
+ Assert(*ShmemFreeStart);
+
+ SpinAcquire(ShmemLock);
+
+ tmpFree = *ShmemFreeStart + size;
+ if (tmpFree <= ShmemSize)
+ {
+ newSpace = (long *) MAKE_PTR(*ShmemFreeStart);
+ *ShmemFreeStart += size;
+ }
+ else
+ {
+ newSpace = NULL;
+ }
+
+ SpinRelease(ShmemLock);
+
+ if (!newSpace)
+ {
+ elog(NOTICE, "ShmemAlloc: out of memory ");
+ }
+ return (newSpace);
}
/*
- * ShmemIsValid -- test if an offset refers to valid shared memory
- *
+ * ShmemIsValid -- test if an offset refers to valid shared memory
+ *
* Returns TRUE if the pointer is valid.
*/
int
ShmemIsValid(unsigned long addr)
{
- return ((addr<ShmemEnd) && (addr>=ShmemBase));
+ return ((addr < ShmemEnd) && (addr >= ShmemBase));
}
/*
- * ShmemInitHash -- Create/Attach to and initialize
- * shared memory hash table.
+ * ShmemInitHash -- Create/Attach to and initialize
+ * shared memory hash table.
*
* Notes:
*
@@ -324,281 +338,308 @@ ShmemIsValid(unsigned long addr)
* table at once. Use SpinAlloc() to create a spinlock
* for the structure before creating the structure itself.
*/
-HTAB *
-ShmemInitHash(char *name, /* table string name for binding */
- long init_size, /* initial size */
- long max_size, /* max size of the table */
- HASHCTL *infoP, /* info about key and bucket size */
- int hash_flags) /* info about infoP */
+HTAB *
+ShmemInitHash(char *name, /* table string name for binding */
+ long init_size, /* initial size */
+ long max_size, /* max size of the table */
+ HASHCTL * infoP, /* info about key and bucket size */
+ int hash_flags) /* info about infoP */
{
- bool found;
- long * location;
-
- /* shared memory hash tables have a fixed max size so that the
- * control structures don't try to grow. The segbase is for
- * calculating pointer values. The shared memory allocator
- * must be specified.
- */
- infoP->segbase = (long *) ShmemBase;
- infoP->alloc = ShmemAlloc;
- infoP->max_size = max_size;
- hash_flags |= HASH_SHARED_MEM;
-
- /* look it up in the binding table */
- location =
- ShmemInitStruct(name,my_log2(max_size) + sizeof(HHDR),&found);
-
- /* binding table is corrupted. Let someone else give the
- * error message since they have more information
- */
- if (location == NULL) {
- return(0);
- }
-
- /* it already exists, attach to it rather than allocate and
- * initialize new space
- */
- if (found) {
- hash_flags |= HASH_ATTACH;
- }
-
- /* these structures were allocated or bound in ShmemInitStruct */
- /* control information and parameters */
- infoP->hctl = (long *) location;
- /* directory for hash lookup */
- infoP->dir = (long *) (location + sizeof(HHDR));
-
- return(hash_create(init_size, infoP, hash_flags));;
+ bool found;
+ long *location;
+
+ /*
+ * shared memory hash tables have a fixed max size so that the control
+ * structures don't try to grow. The segbase is for calculating
+ * pointer values. The shared memory allocator must be specified.
+ */
+ infoP->segbase = (long *) ShmemBase;
+ infoP->alloc = ShmemAlloc;
+ infoP->max_size = max_size;
+ hash_flags |= HASH_SHARED_MEM;
+
+ /* look it up in the binding table */
+ location =
+ ShmemInitStruct(name, my_log2(max_size) + sizeof(HHDR), &found);
+
+ /*
+ * binding table is corrupted. Let someone else give the error
+ * message since they have more information
+ */
+ if (location == NULL)
+ {
+ return (0);
+ }
+
+ /*
+ * it already exists, attach to it rather than allocate and initialize
+ * new space
+ */
+ if (found)
+ {
+ hash_flags |= HASH_ATTACH;
+ }
+
+ /* these structures were allocated or bound in ShmemInitStruct */
+ /* control information and parameters */
+ infoP->hctl = (long *) location;
+ /* directory for hash lookup */
+ infoP->dir = (long *) (location + sizeof(HHDR));
+
+ return (hash_create(init_size, infoP, hash_flags));;
}
/*
* ShmemPIDLookup -- lookup process data structure using process id
*
* Returns: TRUE if no error. locationPtr is initialized if PID is
- * found in the binding table.
+ * found in the binding table.
*
* NOTES:
- * only information about success or failure is the value of
- * locationPtr.
+ * only information about success or failure is the value of
+ * locationPtr.
*/
bool
-ShmemPIDLookup(int pid, SHMEM_OFFSET* locationPtr)
+ShmemPIDLookup(int pid, SHMEM_OFFSET * locationPtr)
{
- BindingEnt * result,item;
- bool found;
-
- Assert (BindingTable);
- memset(item.key, 0, BTABLE_KEYSIZE);
- sprintf(item.key,"PID %d",pid);
-
- SpinAcquire(BindingLock);
- result = (BindingEnt *)
- hash_search(BindingTable,(char *) &item, HASH_ENTER, &found);
-
- if (! result) {
-
+ BindingEnt *result,
+ item;
+ bool found;
+
+ Assert(BindingTable);
+ memset(item.key, 0, BTABLE_KEYSIZE);
+ sprintf(item.key, "PID %d", pid);
+
+ SpinAcquire(BindingLock);
+ result = (BindingEnt *)
+ hash_search(BindingTable, (char *) &item, HASH_ENTER, &found);
+
+ if (!result)
+ {
+
+ SpinRelease(BindingLock);
+ elog(WARN, "ShmemInitPID: BindingTable corrupted");
+ return (FALSE);
+
+ }
+
+ if (found)
+ {
+ *locationPtr = result->location;
+ }
+ else
+ {
+ result->location = *locationPtr;
+ }
+
SpinRelease(BindingLock);
- elog(WARN,"ShmemInitPID: BindingTable corrupted");
- return(FALSE);
-
- }
-
- if (found) {
- *locationPtr = result->location;
- } else {
- result->location = *locationPtr;
- }
-
- SpinRelease(BindingLock);
- return (TRUE);
+ return (TRUE);
}
/*
* ShmemPIDDestroy -- destroy binding table entry for process
- * using process id
+ * using process id
*
* Returns: offset of the process struct in shared memory or
- * INVALID_OFFSET if not found.
+ * INVALID_OFFSET if not found.
*
* Side Effect: removes the entry from the binding table
*/
SHMEM_OFFSET
ShmemPIDDestroy(int pid)
{
- BindingEnt * result,item;
- bool found;
- SHMEM_OFFSET location = 0;
-
- Assert(BindingTable);
-
- memset(item.key, 0, BTABLE_KEYSIZE);
- sprintf(item.key,"PID %d",pid);
-
- SpinAcquire(BindingLock);
- result = (BindingEnt *)
- hash_search(BindingTable,(char *) &item, HASH_REMOVE, &found);
-
- if (found)
- location = result->location;
- SpinRelease(BindingLock);
-
- if (! result) {
-
- elog(WARN,"ShmemPIDDestroy: PID table corrupted");
- return(INVALID_OFFSET);
-
- }
-
- if (found)
- return (location);
- else {
- return(INVALID_OFFSET);
- }
+ BindingEnt *result,
+ item;
+ bool found;
+ SHMEM_OFFSET location = 0;
+
+ Assert(BindingTable);
+
+ memset(item.key, 0, BTABLE_KEYSIZE);
+ sprintf(item.key, "PID %d", pid);
+
+ SpinAcquire(BindingLock);
+ result = (BindingEnt *)
+ hash_search(BindingTable, (char *) &item, HASH_REMOVE, &found);
+
+ if (found)
+ location = result->location;
+ SpinRelease(BindingLock);
+
+ if (!result)
+ {
+
+ elog(WARN, "ShmemPIDDestroy: PID table corrupted");
+ return (INVALID_OFFSET);
+
+ }
+
+ if (found)
+ return (location);
+ else
+ {
+ return (INVALID_OFFSET);
+ }
}
/*
* ShmemInitStruct -- Create/attach to a structure in shared
- * memory.
+ * memory.
*
- * This is called during initialization to find or allocate
- * a data structure in shared memory. If no other processes
- * have created the structure, this routine allocates space
- * for it. If it exists already, a pointer to the existing
- * table is returned.
+ * This is called during initialization to find or allocate
+ * a data structure in shared memory. If no other processes
+ * have created the structure, this routine allocates space
+ * for it. If it exists already, a pointer to the existing
+ * table is returned.
*
- * Returns: real pointer to the object. FoundPtr is TRUE if
- * the object is already in the binding table (hence, already
- * initialized).
+ * Returns: real pointer to the object. FoundPtr is TRUE if
+ * the object is already in the binding table (hence, already
+ * initialized).
*/
-long *
-ShmemInitStruct(char *name, unsigned long size, bool *foundPtr)
+long *
+ShmemInitStruct(char *name, unsigned long size, bool * foundPtr)
{
- BindingEnt * result,item;
- long * structPtr;
-
- strncpy(item.key,name,BTABLE_KEYSIZE);
- item.location = BAD_LOCATION;
-
- SpinAcquire(BindingLock);
-
- if (! BindingTable) {
- /* Assert() is a macro now. substitutes inside quotes. */
-#ifndef NO_ASSERT_CHECKING
- char *strname = "BindingTable";
+ BindingEnt *result,
+ item;
+ long *structPtr;
+
+ strncpy(item.key, name, BTABLE_KEYSIZE);
+ item.location = BAD_LOCATION;
+
+ SpinAcquire(BindingLock);
+
+ if (!BindingTable)
+ {
+ /* Assert() is a macro now. substitutes inside quotes. */
+#ifndef NO_ASSERT_CHECKING
+ char *strname = "BindingTable";
+
#endif
-
- /* If the binding table doesnt exist, we fake it.
- *
- * If we are creating the first binding table, then let
- * shmemalloc() allocate the space for a new HTAB. Otherwise,
- * find the old one and return that. Notice that the
- * BindingLock is held until the binding table has been completely
- * initialized.
- */
- Assert (! strcmp(name,strname)) ;
- if (ShmemBootstrap) {
- /* in POSTMASTER/Single process */
-
- *foundPtr = FALSE;
- return((long *)ShmemAlloc(size));
-
- } else {
- Assert (ShmemBindingTabOffset);
-
- *foundPtr = TRUE;
- return((long *)MAKE_PTR(*ShmemBindingTabOffset));
+
+ /*
+ * If the binding table doesnt exist, we fake it.
+ *
+ * If we are creating the first binding table, then let shmemalloc()
+ * allocate the space for a new HTAB. Otherwise, find the old one
+ * and return that. Notice that the BindingLock is held until the
+ * binding table has been completely initialized.
+ */
+ Assert(!strcmp(name, strname));
+ if (ShmemBootstrap)
+ {
+ /* in POSTMASTER/Single process */
+
+ *foundPtr = FALSE;
+ return ((long *) ShmemAlloc(size));
+
+ }
+ else
+ {
+ Assert(ShmemBindingTabOffset);
+
+ *foundPtr = TRUE;
+ return ((long *) MAKE_PTR(*ShmemBindingTabOffset));
+ }
+
+
}
-
-
- } else {
- /* look it up in the bindint table */
- result = (BindingEnt *)
- hash_search(BindingTable,(char *) &item,HASH_ENTER, foundPtr);
- }
-
- if (! result) {
-
- SpinRelease(BindingLock);
-
- elog(WARN,"ShmemInitStruct: Binding Table corrupted");
- return(NULL);
-
- } else if (*foundPtr) {
- /*
- * Structure is in the binding table so someone else has allocated
- * it already. The size better be the same as the size we are
- * trying to initialize to or there is a name conflict (or worse).
- */
- if (result->size != size) {
- SpinRelease(BindingLock);
-
- elog(NOTICE,"ShmemInitStruct: BindingTable entry size is wrong");
- /* let caller print its message too */
- return(NULL);
+ else
+ {
+ /* look it up in the bindint table */
+ result = (BindingEnt *)
+ hash_search(BindingTable, (char *) &item, HASH_ENTER, foundPtr);
+ }
+
+ if (!result)
+ {
+
+ SpinRelease(BindingLock);
+
+ elog(WARN, "ShmemInitStruct: Binding Table corrupted");
+ return (NULL);
+
}
- structPtr = (long *)MAKE_PTR(result->location);
- } else {
-
- /* It isn't in the table yet. allocate and initialize it */
- structPtr = ShmemAlloc((long)size);
- if (! structPtr) {
- /* out of memory */
- Assert (BindingTable);
- hash_search(BindingTable,(char *) &item,HASH_REMOVE, foundPtr);
- SpinRelease(BindingLock);
- *foundPtr = FALSE;
-
- elog(NOTICE,"ShmemInitStruct: cannot allocate '%s'",
- name);
- return(NULL);
- }
- result->size = size;
- result->location = MAKE_OFFSET(structPtr);
- }
- Assert (ShmemIsValid((unsigned long)structPtr));
-
- SpinRelease(BindingLock);
- return(structPtr);
+ else if (*foundPtr)
+ {
+
+ /*
+ * Structure is in the binding table so someone else has allocated
+ * it already. The size better be the same as the size we are
+ * trying to initialize to or there is a name conflict (or worse).
+ */
+ if (result->size != size)
+ {
+ SpinRelease(BindingLock);
+
+ elog(NOTICE, "ShmemInitStruct: BindingTable entry size is wrong");
+ /* let caller print its message too */
+ return (NULL);
+ }
+ structPtr = (long *) MAKE_PTR(result->location);
+ }
+ else
+ {
+
+ /* It isn't in the table yet. allocate and initialize it */
+ structPtr = ShmemAlloc((long) size);
+ if (!structPtr)
+ {
+ /* out of memory */
+ Assert(BindingTable);
+ hash_search(BindingTable, (char *) &item, HASH_REMOVE, foundPtr);
+ SpinRelease(BindingLock);
+ *foundPtr = FALSE;
+
+ elog(NOTICE, "ShmemInitStruct: cannot allocate '%s'",
+ name);
+ return (NULL);
+ }
+ result->size = size;
+ result->location = MAKE_OFFSET(structPtr);
+ }
+ Assert(ShmemIsValid((unsigned long) structPtr));
+
+ SpinRelease(BindingLock);
+ return (structPtr);
}
/*
* TransactionIdIsInProgress -- is given transaction running by some backend
*
- * Strange place for this func, but we have to lookup process data structures
+ * Strange place for this func, but we have to lookup process data structures
* for all running backends. - vadim 11/26/96
*/
bool
-TransactionIdIsInProgress (TransactionId xid)
+TransactionIdIsInProgress(TransactionId xid)
{
- BindingEnt *result;
- PROC *proc;
-
- Assert (BindingTable);
-
- SpinAcquire(BindingLock);
-
- hash_seq ((HTAB *)NULL);
- while ( (result = (BindingEnt *) hash_seq (BindingTable)) != NULL )
- {
- if ( result == (BindingEnt *) TRUE )
- {
- SpinRelease(BindingLock);
- return (false);
- }
- if ( result->location == INVALID_OFFSET ||
- strncmp (result->key, "PID ", 4) != 0 )
- continue;
- proc = (PROC *) MAKE_PTR (result->location);
- if ( proc->xid == xid )
- {
- SpinRelease(BindingLock);
- return (true);
+ BindingEnt *result;
+ PROC *proc;
+
+ Assert(BindingTable);
+
+ SpinAcquire(BindingLock);
+
+ hash_seq((HTAB *) NULL);
+ while ((result = (BindingEnt *) hash_seq(BindingTable)) != NULL)
+ {
+ if (result == (BindingEnt *) TRUE)
+ {
+ SpinRelease(BindingLock);
+ return (false);
+ }
+ if (result->location == INVALID_OFFSET ||
+ strncmp(result->key, "PID ", 4) != 0)
+ continue;
+ proc = (PROC *) MAKE_PTR(result->location);
+ if (proc->xid == xid)
+ {
+ SpinRelease(BindingLock);
+ return (true);
+ }
}
- }
-
- SpinRelease(BindingLock);
- elog (WARN,"TransactionIdIsInProgress: BindingTable corrupted");
- return (false);
-}
+ SpinRelease(BindingLock);
+ elog(WARN, "TransactionIdIsInProgress: BindingTable corrupted");
+ return (false);
+}
diff --git a/src/backend/storage/ipc/shmqueue.c b/src/backend/storage/ipc/shmqueue.c
index f727b5719f5..8080fc70208 100644
--- a/src/backend/storage/ipc/shmqueue.c
+++ b/src/backend/storage/ipc/shmqueue.c
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* shmqueue.c--
- * shared memory linked lists
+ * shared memory linked lists
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmqueue.c,v 1.3 1997/08/19 21:33:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmqueue.c,v 1.4 1997/09/07 04:48:42 momjian Exp $
*
* NOTES
*
* Package for managing doubly-linked lists in shared memory.
- * The only tricky thing is that SHM_QUEUE will usually be a field
- * in a larger record. SHMQueueGetFirst has to return a pointer
+ * The only tricky thing is that SHM_QUEUE will usually be a field
+ * in a larger record. SHMQueueGetFirst has to return a pointer
* to the record itself instead of a pointer to the SHMQueue field
* of the record. It takes an extra pointer and does some extra
* pointer arithmetic to do this correctly.
@@ -22,178 +22,181 @@
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include "postgres.h"
-#include "storage/shmem.h" /* where the declarations go */
+#include "storage/shmem.h" /* where the declarations go */
/*#define SHMQUEUE_DEBUG*/
#ifdef SHMQUEUE_DEBUG
-#define SHMQUEUE_DEBUG_DEL /* deletions */
-#define SHMQUEUE_DEBUG_HD /* head inserts */
-#define SHMQUEUE_DEBUG_TL /* tail inserts */
+#define SHMQUEUE_DEBUG_DEL /* deletions */
+#define SHMQUEUE_DEBUG_HD /* head inserts */
+#define SHMQUEUE_DEBUG_TL /* tail inserts */
#define SHMQUEUE_DEBUG_ELOG NOTICE
-#endif /* SHMQUEUE_DEBUG */
+#endif /* SHMQUEUE_DEBUG */
/*
* ShmemQueueInit -- make the head of a new queue point
- * to itself
+ * to itself
*/
void
-SHMQueueInit(SHM_QUEUE *queue)
+SHMQueueInit(SHM_QUEUE * queue)
{
- Assert(SHM_PTR_VALID(queue));
- (queue)->prev = (queue)->next = MAKE_OFFSET(queue);
+ Assert(SHM_PTR_VALID(queue));
+ (queue)->prev = (queue)->next = MAKE_OFFSET(queue);
}
/*
* SHMQueueIsDetached -- TRUE if element is not currently
- * in a queue.
+ * in a queue.
*/
#ifdef NOT_USED
bool
-SHMQueueIsDetached(SHM_QUEUE *queue)
+SHMQueueIsDetached(SHM_QUEUE * queue)
{
- Assert(SHM_PTR_VALID(queue));
- return ((queue)->prev == INVALID_OFFSET);
+ Assert(SHM_PTR_VALID(queue));
+ return ((queue)->prev == INVALID_OFFSET);
}
+
#endif
/*
* SHMQueueElemInit -- clear an element's links
*/
void
-SHMQueueElemInit(SHM_QUEUE *queue)
+SHMQueueElemInit(SHM_QUEUE * queue)
{
- Assert(SHM_PTR_VALID(queue));
- (queue)->prev = (queue)->next = INVALID_OFFSET;
+ Assert(SHM_PTR_VALID(queue));
+ (queue)->prev = (queue)->next = INVALID_OFFSET;
}
/*
* SHMQueueDelete -- remove an element from the queue and
- * close the links
+ * close the links
*/
void
-SHMQueueDelete(SHM_QUEUE *queue)
+SHMQueueDelete(SHM_QUEUE * queue)
{
- SHM_QUEUE *nextElem = (SHM_QUEUE *) MAKE_PTR((queue)->next);
- SHM_QUEUE *prevElem = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
-
- Assert(SHM_PTR_VALID(queue));
- Assert(SHM_PTR_VALID(nextElem));
- Assert(SHM_PTR_VALID(prevElem));
-
+ SHM_QUEUE *nextElem = (SHM_QUEUE *) MAKE_PTR((queue)->next);
+ SHM_QUEUE *prevElem = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
+
+ Assert(SHM_PTR_VALID(queue));
+ Assert(SHM_PTR_VALID(nextElem));
+ Assert(SHM_PTR_VALID(prevElem));
+
#ifdef SHMQUEUE_DEBUG_DEL
- dumpQ(queue, "in SHMQueueDelete: begin");
-#endif /* SHMQUEUE_DEBUG_DEL */
-
- prevElem->next = (queue)->next;
- nextElem->prev = (queue)->prev;
-
+ dumpQ(queue, "in SHMQueueDelete: begin");
+#endif /* SHMQUEUE_DEBUG_DEL */
+
+ prevElem->next = (queue)->next;
+ nextElem->prev = (queue)->prev;
+
#ifdef SHMQUEUE_DEBUG_DEL
- dumpQ((SHM_QUEUE *)MAKE_PTR(queue->prev), "in SHMQueueDelete: end");
-#endif /* SHMQUEUE_DEBUG_DEL */
+ dumpQ((SHM_QUEUE *) MAKE_PTR(queue->prev), "in SHMQueueDelete: end");
+#endif /* SHMQUEUE_DEBUG_DEL */
}
#ifdef SHMQUEUE_DEBUG
void
-dumpQ(SHM_QUEUE *q, char *s)
+dumpQ(SHM_QUEUE * q, char *s)
{
- char elem[16];
- char buf[1024];
- SHM_QUEUE *start = q;
- int count = 0;
-
- sprintf(buf, "q prevs: %x", MAKE_OFFSET(q));
- q = (SHM_QUEUE *)MAKE_PTR(q->prev);
- while (q != start)
+ char elem[16];
+ char buf[1024];
+ SHM_QUEUE *start = q;
+ int count = 0;
+
+ sprintf(buf, "q prevs: %x", MAKE_OFFSET(q));
+ q = (SHM_QUEUE *) MAKE_PTR(q->prev);
+ while (q != start)
{
- sprintf(elem, "--->%x", MAKE_OFFSET(q));
- strcat(buf, elem);
- q = (SHM_QUEUE *)MAKE_PTR(q->prev);
- if (q->prev == MAKE_OFFSET(q))
- break;
- if (count++ > 40)
+ sprintf(elem, "--->%x", MAKE_OFFSET(q));
+ strcat(buf, elem);
+ q = (SHM_QUEUE *) MAKE_PTR(q->prev);
+ if (q->prev == MAKE_OFFSET(q))
+ break;
+ if (count++ > 40)
{
- strcat(buf, "BAD PREV QUEUE!!");
- break;
+ strcat(buf, "BAD PREV QUEUE!!");
+ break;
}
}
- sprintf(elem, "--->%x", MAKE_OFFSET(q));
- strcat(buf, elem);
- elog(SHMQUEUE_DEBUG_ELOG, "%s: %s", s, buf);
-
- sprintf(buf, "q nexts: %x", MAKE_OFFSET(q));
- count = 0;
- q = (SHM_QUEUE *)MAKE_PTR(q->next);
- while (q != start)
+ sprintf(elem, "--->%x", MAKE_OFFSET(q));
+ strcat(buf, elem);
+ elog(SHMQUEUE_DEBUG_ELOG, "%s: %s", s, buf);
+
+ sprintf(buf, "q nexts: %x", MAKE_OFFSET(q));
+ count = 0;
+ q = (SHM_QUEUE *) MAKE_PTR(q->next);
+ while (q != start)
{
- sprintf(elem, "--->%x", MAKE_OFFSET(q));
- strcat(buf, elem);
- q = (SHM_QUEUE *)MAKE_PTR(q->next);
- if (q->next == MAKE_OFFSET(q))
- break;
- if (count++ > 10)
+ sprintf(elem, "--->%x", MAKE_OFFSET(q));
+ strcat(buf, elem);
+ q = (SHM_QUEUE *) MAKE_PTR(q->next);
+ if (q->next == MAKE_OFFSET(q))
+ break;
+ if (count++ > 10)
{
- strcat(buf, "BAD NEXT QUEUE!!");
- break;
+ strcat(buf, "BAD NEXT QUEUE!!");
+ break;
}
}
- sprintf(elem, "--->%x", MAKE_OFFSET(q));
- strcat(buf, elem);
- elog(SHMQUEUE_DEBUG_ELOG, "%s: %s", s, buf);
+ sprintf(elem, "--->%x", MAKE_OFFSET(q));
+ strcat(buf, elem);
+ elog(SHMQUEUE_DEBUG_ELOG, "%s: %s", s, buf);
}
-#endif /* SHMQUEUE_DEBUG */
+
+#endif /* SHMQUEUE_DEBUG */
/*
* SHMQueueInsertHD -- put elem in queue between the queue head
- * and its "prev" element.
+ * and its "prev" element.
*/
#ifdef NOT_USED
void
-SHMQueueInsertHD(SHM_QUEUE *queue, SHM_QUEUE *elem)
+SHMQueueInsertHD(SHM_QUEUE * queue, SHM_QUEUE * elem)
{
- SHM_QUEUE *prevPtr = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
- SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
-
- Assert(SHM_PTR_VALID(queue));
- Assert(SHM_PTR_VALID(elem));
-
+ SHM_QUEUE *prevPtr = (SHM_QUEUE *) MAKE_PTR((queue)->prev);
+ SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
+
+ Assert(SHM_PTR_VALID(queue));
+ Assert(SHM_PTR_VALID(elem));
+
#ifdef SHMQUEUE_DEBUG_HD
- dumpQ(queue, "in SHMQueueInsertHD: begin");
-#endif /* SHMQUEUE_DEBUG_HD */
-
- (elem)->next = prevPtr->next;
- (elem)->prev = queue->prev;
- (queue)->prev = elemOffset;
- prevPtr->next = elemOffset;
-
+ dumpQ(queue, "in SHMQueueInsertHD: begin");
+#endif /* SHMQUEUE_DEBUG_HD */
+
+ (elem)->next = prevPtr->next;
+ (elem)->prev = queue->prev;
+ (queue)->prev = elemOffset;
+ prevPtr->next = elemOffset;
+
#ifdef SHMQUEUE_DEBUG_HD
- dumpQ(queue, "in SHMQueueInsertHD: end");
-#endif /* SHMQUEUE_DEBUG_HD */
+ dumpQ(queue, "in SHMQueueInsertHD: end");
+#endif /* SHMQUEUE_DEBUG_HD */
}
+
#endif
void
-SHMQueueInsertTL(SHM_QUEUE *queue, SHM_QUEUE *elem)
+SHMQueueInsertTL(SHM_QUEUE * queue, SHM_QUEUE * elem)
{
- SHM_QUEUE *nextPtr = (SHM_QUEUE *) MAKE_PTR((queue)->next);
- SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
-
- Assert(SHM_PTR_VALID(queue));
- Assert(SHM_PTR_VALID(elem));
-
+ SHM_QUEUE *nextPtr = (SHM_QUEUE *) MAKE_PTR((queue)->next);
+ SHMEM_OFFSET elemOffset = MAKE_OFFSET(elem);
+
+ Assert(SHM_PTR_VALID(queue));
+ Assert(SHM_PTR_VALID(elem));
+
#ifdef SHMQUEUE_DEBUG_TL
- dumpQ(queue, "in SHMQueueInsertTL: begin");
-#endif /* SHMQUEUE_DEBUG_TL */
-
- (elem)->prev = nextPtr->prev;
- (elem)->next = queue->next;
- (queue)->next = elemOffset;
- nextPtr->prev = elemOffset;
-
+ dumpQ(queue, "in SHMQueueInsertTL: begin");
+#endif /* SHMQUEUE_DEBUG_TL */
+
+ (elem)->prev = nextPtr->prev;
+ (elem)->next = queue->next;
+ (queue)->next = elemOffset;
+ nextPtr->prev = elemOffset;
+
#ifdef SHMQUEUE_DEBUG_TL
- dumpQ(queue, "in SHMQueueInsertTL: end");
-#endif /* SHMQUEUE_DEBUG_TL */
+ dumpQ(queue, "in SHMQueueInsertTL: end");
+#endif /* SHMQUEUE_DEBUG_TL */
}
/*
@@ -203,52 +206,51 @@ SHMQueueInsertTL(SHM_QUEUE *queue, SHM_QUEUE *elem)
* a larger structure, we want to return a pointer to the
* whole structure rather than a pointer to its SHMQueue field.
* I.E. struct {
- * int stuff;
- * SHMQueue elem;
- * } ELEMType;
+ * int stuff;
+ * SHMQueue elem;
+ * } ELEMType;
* when this element is in a queue (queue->next) is struct.elem.
* nextQueue allows us to calculate the offset of the SHMQueue
* field in the structure.
*
* call to SHMQueueFirst should take these parameters:
*
- * &(queueHead),&firstElem,&(firstElem->next)
+ * &(queueHead),&firstElem,&(firstElem->next)
*
* Note that firstElem may well be uninitialized. if firstElem
* is initially K, &(firstElem->next) will be K+ the offset to
* next.
*/
void
-SHMQueueFirst(SHM_QUEUE *queue, Pointer *nextPtrPtr, SHM_QUEUE *nextQueue)
+SHMQueueFirst(SHM_QUEUE * queue, Pointer * nextPtrPtr, SHM_QUEUE * nextQueue)
{
- SHM_QUEUE *elemPtr = (SHM_QUEUE *) MAKE_PTR((queue)->next);
-
- Assert(SHM_PTR_VALID(queue));
- *nextPtrPtr = (Pointer) (((unsigned long) *nextPtrPtr) +
- ((unsigned long) elemPtr) - ((unsigned long) nextQueue));
-
- /*
- nextPtrPtr a ptr to a structure linked in the queue
- nextQueue is the SHMQueue field of the structure
- *nextPtrPtr - nextQueue is 0 minus the offset of the queue
- field n the record
- elemPtr + (*nextPtrPtr - nexQueue) is the start of the
- structure containing elemPtr.
- */
+ SHM_QUEUE *elemPtr = (SHM_QUEUE *) MAKE_PTR((queue)->next);
+
+ Assert(SHM_PTR_VALID(queue));
+ *nextPtrPtr = (Pointer) (((unsigned long) *nextPtrPtr) +
+ ((unsigned long) elemPtr) - ((unsigned long) nextQueue));
+
+ /*
+ * nextPtrPtr a ptr to a structure linked in the queue nextQueue is
+ * the SHMQueue field of the structure nextPtrPtr - nextQueue is 0
+ * minus the offset of the queue field n the record elemPtr +
+ * (*nextPtrPtr - nexQueue) is the start of the structure containing
+ * elemPtr.
+ */
}
/*
* SHMQueueEmpty -- TRUE if queue head is only element, FALSE otherwise
*/
bool
-SHMQueueEmpty(SHM_QUEUE *queue)
+SHMQueueEmpty(SHM_QUEUE * queue)
{
- Assert(SHM_PTR_VALID(queue));
-
- if (queue->prev == MAKE_OFFSET(queue))
+ Assert(SHM_PTR_VALID(queue));
+
+ if (queue->prev == MAKE_OFFSET(queue))
{
- Assert(queue->next = MAKE_OFFSET(queue));
- return(TRUE);
+ Assert(queue->next = MAKE_OFFSET(queue));
+ return (TRUE);
}
- return(FALSE);
+ return (FALSE);
}
diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c
index 5f391669113..af16c8a7196 100644
--- a/src/backend/storage/ipc/sinval.c
+++ b/src/backend/storage/ipc/sinval.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* sinval.c--
- * POSTGRES shared cache invalidation communication code.
+ * POSTGRES shared cache invalidation communication code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.7 1997/08/12 22:53:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.8 1997/09/07 04:48:43 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-/* #define INVALIDDEBUG 1 */
+/* #define INVALIDDEBUG 1 */
#include <sys/types.h>
@@ -22,150 +22,156 @@
#include "storage/sinvaladt.h"
#include "storage/spin.h"
-extern SISeg *shmInvalBuffer;/* the shared buffer segment, set by*/
- /* SISegmentAttach() */
-extern BackendId MyBackendId;
-extern BackendTag MyBackendTag;
+extern SISeg *shmInvalBuffer; /* the shared buffer segment, set by */
+
+ /* SISegmentAttach() */
+extern BackendId MyBackendId;
+extern BackendTag MyBackendTag;
SPINLOCK SInvalLock = (SPINLOCK) NULL;
/****************************************************************************/
-/* CreateSharedInvalidationState(key) Create a buffer segment */
-/* */
-/* should be called only by the POSTMASTER */
+/* CreateSharedInvalidationState(key) Create a buffer segment */
+/* */
+/* should be called only by the POSTMASTER */
/****************************************************************************/
void
CreateSharedInvalidationState(IPCKey key)
{
- int status;
-
- /* REMOVED
- SISyncKill(IPCKeyGetSIBufferMemorySemaphoreKey(key));
- SISyncInit(IPCKeyGetSIBufferMemorySemaphoreKey(key));
- */
-
- /* SInvalLock gets set in spin.c, during spinlock init */
- status = SISegmentInit(true, IPCKeyGetSIBufferMemoryBlock(key));
-
- if (status == -1) {
- elog(FATAL, "CreateSharedInvalidationState: failed segment init");
- }
+ int status;
+
+ /*
+ * REMOVED SISyncKill(IPCKeyGetSIBufferMemorySemaphoreKey(key));
+ * SISyncInit(IPCKeyGetSIBufferMemorySemaphoreKey(key));
+ */
+
+ /* SInvalLock gets set in spin.c, during spinlock init */
+ status = SISegmentInit(true, IPCKeyGetSIBufferMemoryBlock(key));
+
+ if (status == -1)
+ {
+ elog(FATAL, "CreateSharedInvalidationState: failed segment init");
+ }
}
+
/****************************************************************************/
-/* AttachSharedInvalidationState(key) Attach a buffer segment */
-/* */
-/* should be called only by the POSTMASTER */
+/* AttachSharedInvalidationState(key) Attach a buffer segment */
+/* */
+/* should be called only by the POSTMASTER */
/****************************************************************************/
void
AttachSharedInvalidationState(IPCKey key)
{
- int status;
-
- if (key == PrivateIPCKey) {
- CreateSharedInvalidationState(key);
- return;
- }
- /* SInvalLock gets set in spin.c, during spinlock init */
- status = SISegmentInit(false, IPCKeyGetSIBufferMemoryBlock(key));
-
- if (status == -1) {
- elog(FATAL, "AttachSharedInvalidationState: failed segment init");
- }
+ int status;
+
+ if (key == PrivateIPCKey)
+ {
+ CreateSharedInvalidationState(key);
+ return;
+ }
+ /* SInvalLock gets set in spin.c, during spinlock init */
+ status = SISegmentInit(false, IPCKeyGetSIBufferMemoryBlock(key));
+
+ if (status == -1)
+ {
+ elog(FATAL, "AttachSharedInvalidationState: failed segment init");
+ }
}
void
InitSharedInvalidationState(void)
{
- SpinAcquire(SInvalLock);
- if (!SIBackendInit(shmInvalBuffer))
+ SpinAcquire(SInvalLock);
+ if (!SIBackendInit(shmInvalBuffer))
{
- SpinRelease(SInvalLock);
- elog(FATAL, "Backend cache invalidation initialization failed");
+ SpinRelease(SInvalLock);
+ elog(FATAL, "Backend cache invalidation initialization failed");
}
- SpinRelease(SInvalLock);
+ SpinRelease(SInvalLock);
}
/*
* RegisterSharedInvalid --
- * Returns a new local cache invalidation state containing a new entry.
+ * Returns a new local cache invalidation state containing a new entry.
*
* Note:
- * Assumes hash index is valid.
- * Assumes item pointer is valid.
+ * Assumes hash index is valid.
+ * Assumes item pointer is valid.
*/
/****************************************************************************/
-/* RegisterSharedInvalid(cacheId, hashIndex, pointer) */
-/* */
-/* register a message in the buffer */
-/* should be called by a backend */
+/* RegisterSharedInvalid(cacheId, hashIndex, pointer) */
+/* */
+/* register a message in the buffer */
+/* should be called by a backend */
/****************************************************************************/
void
-RegisterSharedInvalid(int cacheId, /* XXX */
- Index hashIndex,
- ItemPointer pointer)
+RegisterSharedInvalid(int cacheId, /* XXX */
+ Index hashIndex,
+ ItemPointer pointer)
{
- SharedInvalidData newInvalid;
-
- /*
- * This code has been hacked to accept two types of messages. This might
- * be treated more generally in the future.
- *
- * (1)
- * cacheId= system cache id
- * hashIndex= system cache hash index for a (possibly) cached tuple
- * pointer= pointer of (possibly) cached tuple
- *
- * (2)
- * cacheId= special non-syscache id
- * hashIndex= object id contained in (possibly) cached relation descriptor
- * pointer= null
- */
-
- newInvalid.cacheId = cacheId;
- newInvalid.hashIndex = hashIndex;
-
- if (ItemPointerIsValid(pointer)) {
- ItemPointerCopy(pointer, &newInvalid.pointerData);
- } else {
- ItemPointerSetInvalid(&newInvalid.pointerData);
- }
-
- SpinAcquire(SInvalLock);
- if (!SISetDataEntry(shmInvalBuffer, &newInvalid)) {
- /* buffer full */
- /* release a message, mark process cache states to be invalid */
- SISetProcStateInvalid(shmInvalBuffer);
-
- if (!SIDelDataEntry(shmInvalBuffer)) {
- /* inconsistent buffer state -- shd never happen */
- SpinRelease(SInvalLock);
- elog(FATAL, "RegisterSharedInvalid: inconsistent buffer state");
- }
-
- /* write again */
- SISetDataEntry(shmInvalBuffer, &newInvalid);
- }
- SpinRelease(SInvalLock);
+ SharedInvalidData newInvalid;
+
+ /*
+ * This code has been hacked to accept two types of messages. This
+ * might be treated more generally in the future.
+ *
+ * (1) cacheId= system cache id hashIndex= system cache hash index for a
+ * (possibly) cached tuple pointer= pointer of (possibly) cached tuple
+ *
+ * (2) cacheId= special non-syscache id hashIndex= object id contained in
+ * (possibly) cached relation descriptor pointer= null
+ */
+
+ newInvalid.cacheId = cacheId;
+ newInvalid.hashIndex = hashIndex;
+
+ if (ItemPointerIsValid(pointer))
+ {
+ ItemPointerCopy(pointer, &newInvalid.pointerData);
+ }
+ else
+ {
+ ItemPointerSetInvalid(&newInvalid.pointerData);
+ }
+
+ SpinAcquire(SInvalLock);
+ if (!SISetDataEntry(shmInvalBuffer, &newInvalid))
+ {
+ /* buffer full */
+ /* release a message, mark process cache states to be invalid */
+ SISetProcStateInvalid(shmInvalBuffer);
+
+ if (!SIDelDataEntry(shmInvalBuffer))
+ {
+ /* inconsistent buffer state -- shd never happen */
+ SpinRelease(SInvalLock);
+ elog(FATAL, "RegisterSharedInvalid: inconsistent buffer state");
+ }
+
+ /* write again */
+ SISetDataEntry(shmInvalBuffer, &newInvalid);
+ }
+ SpinRelease(SInvalLock);
}
/*
* InvalidateSharedInvalid --
- * Processes all entries in a shared cache invalidation state.
+ * Processes all entries in a shared cache invalidation state.
*/
/****************************************************************************/
-/* InvalidateSharedInvalid(invalFunction, resetFunction) */
-/* */
-/* invalidate a message in the buffer (read and clean up) */
-/* should be called by a backend */
+/* InvalidateSharedInvalid(invalFunction, resetFunction) */
+/* */
+/* invalidate a message in the buffer (read and clean up) */
+/* should be called by a backend */
/****************************************************************************/
void
-InvalidateSharedInvalid(void (*invalFunction)(),
- void (*resetFunction)())
+ InvalidateSharedInvalid(void (*invalFunction) (),
+ void (*resetFunction) ())
{
- SpinAcquire(SInvalLock);
- SIReadEntryData(shmInvalBuffer, MyBackendId,
- invalFunction, resetFunction);
-
- SIDelExpiredDataEntries(shmInvalBuffer);
- SpinRelease(SInvalLock);
+ SpinAcquire(SInvalLock);
+ SIReadEntryData(shmInvalBuffer, MyBackendId,
+ invalFunction, resetFunction);
+
+ SIDelExpiredDataEntries(shmInvalBuffer);
+ SpinRelease(SInvalLock);
}
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index 9400e872617..43c4d7c0ac2 100644
--- a/src/backend/storage/ipc/sinvaladt.c
+++ b/src/backend/storage/ipc/sinvaladt.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* sinvaladt.c--
- * POSTGRES shared cache invalidation segment definitions.
+ * POSTGRES shared cache invalidation segment definitions.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.5 1997/08/12 22:54:01 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.6 1997/09/07 04:48:44 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,420 +22,445 @@
#include "utils/palloc.h"
/* ----------------
- * global variable notes
+ * global variable notes
*
- * SharedInvalidationSemaphore
+ * SharedInvalidationSemaphore
*
- * shmInvalBuffer
- * the shared buffer segment, set by SISegmentAttach()
+ * shmInvalBuffer
+ * the shared buffer segment, set by SISegmentAttach()
*
- * MyBackendId
- * might be removed later, used only for
- * debugging in debug routines (end of file)
+ * MyBackendId
+ * might be removed later, used only for
+ * debugging in debug routines (end of file)
*
- * SIDbId
- * identification of buffer (disappears)
+ * SIDbId
+ * identification of buffer (disappears)
*
- * SIRelId \
- * SIDummyOid \ identification of buffer
- * SIXidData /
- * SIXid /
+ * SIRelId \
+ * SIDummyOid \ identification of buffer
+ * SIXidData /
+ * SIXid /
*
- * XXX This file really needs to be cleaned up. We switched to using
- * spinlocks to protect critical sections (as opposed to using fake
- * relations and going through the lock manager) and some of the old
- * cruft was 'ifdef'ed out, while other parts (now unused) are still
- * compiled into the system. -mer 5/24/92
+ * XXX This file really needs to be cleaned up. We switched to using
+ * spinlocks to protect critical sections (as opposed to using fake
+ * relations and going through the lock manager) and some of the old
+ * cruft was 'ifdef'ed out, while other parts (now unused) are still
+ * compiled into the system. -mer 5/24/92
* ----------------
*/
#ifdef HAS_TEST_AND_SET
-int SharedInvalidationLockId;
+int SharedInvalidationLockId;
+
#else
IpcSemaphoreId SharedInvalidationSemaphore;
+
#endif
-SISeg *shmInvalBuffer;
+SISeg *shmInvalBuffer;
extern BackendId MyBackendId;
-static void CleanupInvalidationState(int status, SISeg *segInOutP);
-static BackendId SIAssignBackendId(SISeg *segInOutP, BackendTag backendTag);
-static int SIGetNumEntries(SISeg *segP);
+static void CleanupInvalidationState(int status, SISeg * segInOutP);
+static BackendId SIAssignBackendId(SISeg * segInOutP, BackendTag backendTag);
+static int SIGetNumEntries(SISeg * segP);
/************************************************************************/
/* SISetActiveProcess(segP, backendId) set the backend status active */
-/* should be called only by the postmaster when creating a backend */
+/* should be called only by the postmaster when creating a backend */
/************************************************************************/
/* XXX I suspect that the segP parameter is extraneous. -hirohama */
static void
-SISetActiveProcess(SISeg *segInOutP, BackendId backendId)
+SISetActiveProcess(SISeg * segInOutP, BackendId backendId)
{
- /* mark all messages as read */
-
- /* Assert(segP->procState[backendId - 1].tag == MyBackendTag); */
-
- segInOutP->procState[backendId - 1].resetState = false;
- segInOutP->procState[backendId - 1].limit = SIGetNumEntries(segInOutP);
+ /* mark all messages as read */
+
+ /* Assert(segP->procState[backendId - 1].tag == MyBackendTag); */
+
+ segInOutP->procState[backendId - 1].resetState = false;
+ segInOutP->procState[backendId - 1].limit = SIGetNumEntries(segInOutP);
}
/****************************************************************************/
-/* SIBackendInit() initializes a backend to operate on the buffer */
+/* SIBackendInit() initializes a backend to operate on the buffer */
/****************************************************************************/
int
-SIBackendInit(SISeg *segInOutP)
-{
- LRelId LtCreateRelId();
- TransactionId LMITransactionIdCopy();
-
- Assert(MyBackendTag > 0);
-
- MyBackendId = SIAssignBackendId(segInOutP, MyBackendTag);
- if (MyBackendId == InvalidBackendTag)
- return 0;
-
+SIBackendInit(SISeg * segInOutP)
+{
+ LRelId LtCreateRelId();
+ TransactionId LMITransactionIdCopy();
+
+ Assert(MyBackendTag > 0);
+
+ MyBackendId = SIAssignBackendId(segInOutP, MyBackendTag);
+ if (MyBackendId == InvalidBackendTag)
+ return 0;
+
#ifdef INVALIDDEBUG
- elog(DEBUG, "SIBackendInit: backend tag %d; backend id %d.",
- MyBackendTag, MyBackendId);
-#endif /* INVALIDDEBUG */
-
- SISetActiveProcess(segInOutP, MyBackendId);
- on_exitpg(CleanupInvalidationState, (caddr_t)segInOutP);
- return 1;
+ elog(DEBUG, "SIBackendInit: backend tag %d; backend id %d.",
+ MyBackendTag, MyBackendId);
+#endif /* INVALIDDEBUG */
+
+ SISetActiveProcess(segInOutP, MyBackendId);
+ on_exitpg(CleanupInvalidationState, (caddr_t) segInOutP);
+ return 1;
}
/* ----------------
- * SIAssignBackendId
+ * SIAssignBackendId
* ----------------
*/
-static BackendId
-SIAssignBackendId(SISeg *segInOutP, BackendTag backendTag)
-{
- Index index;
- ProcState *stateP;
-
- stateP = NULL;
-
- for (index = 0; index < MaxBackendId; index += 1) {
- if (segInOutP->procState[index].tag == InvalidBackendTag ||
- segInOutP->procState[index].tag == backendTag)
- {
- stateP = &segInOutP->procState[index];
- break;
- }
-
- if (!PointerIsValid(stateP) ||
- (segInOutP->procState[index].resetState &&
- (!stateP->resetState ||
- stateP->tag < backendTag)) ||
- (!stateP->resetState &&
- (segInOutP->procState[index].limit <
- stateP->limit ||
- stateP->tag < backendTag)))
- {
- stateP = &segInOutP->procState[index];
- }
- }
-
- /* verify that all "procState" entries checked for matching tags */
-
- for (index += 1; index < MaxBackendId; index += 1) {
- if (segInOutP->procState[index].tag == backendTag) {
- elog (FATAL, "SIAssignBackendId: tag %d found twice",
- backendTag);
+static BackendId
+SIAssignBackendId(SISeg * segInOutP, BackendTag backendTag)
+{
+ Index index;
+ ProcState *stateP;
+
+ stateP = NULL;
+
+ for (index = 0; index < MaxBackendId; index += 1)
+ {
+ if (segInOutP->procState[index].tag == InvalidBackendTag ||
+ segInOutP->procState[index].tag == backendTag)
+ {
+ stateP = &segInOutP->procState[index];
+ break;
+ }
+
+ if (!PointerIsValid(stateP) ||
+ (segInOutP->procState[index].resetState &&
+ (!stateP->resetState ||
+ stateP->tag < backendTag)) ||
+ (!stateP->resetState &&
+ (segInOutP->procState[index].limit <
+ stateP->limit ||
+ stateP->tag < backendTag)))
+ {
+ stateP = &segInOutP->procState[index];
+ }
+ }
+
+ /* verify that all "procState" entries checked for matching tags */
+
+ for (index += 1; index < MaxBackendId; index += 1)
+ {
+ if (segInOutP->procState[index].tag == backendTag)
+ {
+ elog(FATAL, "SIAssignBackendId: tag %d found twice",
+ backendTag);
+ }
}
- }
-
- if (stateP->tag != InvalidBackendTag) {
- if (stateP->tag == backendTag) {
- elog(NOTICE, "SIAssignBackendId: reusing tag %d",
- backendTag);
- } else {
- elog(NOTICE,
- "SIAssignBackendId: discarding tag %d",
- stateP->tag);
- return InvalidBackendTag;
+
+ if (stateP->tag != InvalidBackendTag)
+ {
+ if (stateP->tag == backendTag)
+ {
+ elog(NOTICE, "SIAssignBackendId: reusing tag %d",
+ backendTag);
+ }
+ else
+ {
+ elog(NOTICE,
+ "SIAssignBackendId: discarding tag %d",
+ stateP->tag);
+ return InvalidBackendTag;
+ }
}
- }
-
- stateP->tag = backendTag;
-
- return (1 + stateP - &segInOutP->procState[0]);
+
+ stateP->tag = backendTag;
+
+ return (1 + stateP - &segInOutP->procState[0]);
}
/************************************************************************/
-/* The following function should be called only by the postmaster !! */
+/* The following function should be called only by the postmaster !! */
/************************************************************************/
/************************************************************************/
-/* SISetDeadProcess(segP, backendId) set the backend status DEAD */
-/* should be called only by the postmaster when a backend died */
+/* SISetDeadProcess(segP, backendId) set the backend status DEAD */
+/* should be called only by the postmaster when a backend died */
/************************************************************************/
static void
-SISetDeadProcess(SISeg *segP, int backendId)
+SISetDeadProcess(SISeg * segP, int backendId)
{
- /* XXX call me.... */
-
- segP->procState[backendId - 1].resetState = false;
- segP->procState[backendId - 1].limit = -1;
- segP->procState[backendId - 1].tag = InvalidBackendTag;
+ /* XXX call me.... */
+
+ segP->procState[backendId - 1].resetState = false;
+ segP->procState[backendId - 1].limit = -1;
+ segP->procState[backendId - 1].tag = InvalidBackendTag;
}
/*
* CleanupInvalidationState --
* Note:
- * This is a temporary hack. ExitBackend should call this instead
- * of exit (via on_exitpg).
+ * This is a temporary hack. ExitBackend should call this instead
+ * of exit (via on_exitpg).
*/
static void
-CleanupInvalidationState(int status, /* XXX */
- SISeg *segInOutP) /* XXX style */
+CleanupInvalidationState(int status, /* XXX */
+ SISeg * segInOutP) /* XXX style */
{
- Assert(PointerIsValid(segInOutP));
-
- SISetDeadProcess(segInOutP, MyBackendId);
+ Assert(PointerIsValid(segInOutP));
+
+ SISetDeadProcess(segInOutP, MyBackendId);
}
/************************************************************************/
-/* SIComputeSize() - retuns the size of a buffer segment */
+/* SIComputeSize() - retuns the size of a buffer segment */
/************************************************************************/
static SISegOffsets *
SIComputeSize(int *segSize)
{
- int A, B, a, b, totalSize;
- SISegOffsets *oP;
-
- A = 0;
- a = SizeSISeg; /* offset to first data entry */
- b = SizeOfOneSISegEntry * MAXNUMMESSAGES;
- B = A + a + b;
- totalSize = B - A;
- *segSize = totalSize;
-
- oP = (SISegOffsets *) palloc(sizeof(SISegOffsets));
- oP->startSegment = A;
- oP->offsetToFirstEntry = a; /* relatiove to A */
- oP->offsetToEndOfSegemnt = totalSize; /* relative to A */
- return(oP);
+ int A,
+ B,
+ a,
+ b,
+ totalSize;
+ SISegOffsets *oP;
+
+ A = 0;
+ a = SizeSISeg; /* offset to first data entry */
+ b = SizeOfOneSISegEntry * MAXNUMMESSAGES;
+ B = A + a + b;
+ totalSize = B - A;
+ *segSize = totalSize;
+
+ oP = (SISegOffsets *) palloc(sizeof(SISegOffsets));
+ oP->startSegment = A;
+ oP->offsetToFirstEntry = a; /* relatiove to A */
+ oP->offsetToEndOfSegemnt = totalSize; /* relative to A */
+ return (oP);
}
/************************************************************************/
-/* SISetStartEntrySection(segP, offset) - sets the offset */
+/* SISetStartEntrySection(segP, offset) - sets the offset */
/************************************************************************/
static void
-SISetStartEntrySection(SISeg *segP, Offset offset)
+SISetStartEntrySection(SISeg * segP, Offset offset)
{
- segP->startEntrySection = offset;
+ segP->startEntrySection = offset;
}
/************************************************************************/
-/* SIGetStartEntrySection(segP) - returnss the offset */
+/* SIGetStartEntrySection(segP) - returnss the offset */
/************************************************************************/
-static Offset
-SIGetStartEntrySection(SISeg *segP)
+static Offset
+SIGetStartEntrySection(SISeg * segP)
{
- return(segP->startEntrySection);
+ return (segP->startEntrySection);
}
/************************************************************************/
-/* SISetEndEntrySection(segP, offset) - sets the offset */
+/* SISetEndEntrySection(segP, offset) - sets the offset */
/************************************************************************/
static void
-SISetEndEntrySection(SISeg *segP, Offset offset)
+SISetEndEntrySection(SISeg * segP, Offset offset)
{
- segP->endEntrySection = offset;
+ segP->endEntrySection = offset;
}
/************************************************************************/
-/* SISetEndEntryChain(segP, offset) - sets the offset */
+/* SISetEndEntryChain(segP, offset) - sets the offset */
/************************************************************************/
static void
-SISetEndEntryChain(SISeg *segP, Offset offset)
+SISetEndEntryChain(SISeg * segP, Offset offset)
{
- segP->endEntryChain = offset;
+ segP->endEntryChain = offset;
}
/************************************************************************/
-/* SIGetEndEntryChain(segP) - returnss the offset */
+/* SIGetEndEntryChain(segP) - returnss the offset */
/************************************************************************/
-static Offset
-SIGetEndEntryChain(SISeg *segP)
+static Offset
+SIGetEndEntryChain(SISeg * segP)
{
- return(segP->endEntryChain);
+ return (segP->endEntryChain);
}
/************************************************************************/
-/* SISetStartEntryChain(segP, offset) - sets the offset */
+/* SISetStartEntryChain(segP, offset) - sets the offset */
/************************************************************************/
static void
-SISetStartEntryChain(SISeg *segP, Offset offset)
+SISetStartEntryChain(SISeg * segP, Offset offset)
{
- segP->startEntryChain = offset;
+ segP->startEntryChain = offset;
}
/************************************************************************/
-/* SIGetStartEntryChain(segP) - returns the offset */
+/* SIGetStartEntryChain(segP) - returns the offset */
/************************************************************************/
-static Offset
-SIGetStartEntryChain(SISeg *segP)
+static Offset
+SIGetStartEntryChain(SISeg * segP)
{
- return(segP->startEntryChain);
+ return (segP->startEntryChain);
}
/************************************************************************/
-/* SISetNumEntries(segP, num) sets the current nuber of entries */
+/* SISetNumEntries(segP, num) sets the current nuber of entries */
/************************************************************************/
-static bool
-SISetNumEntries(SISeg *segP, int num)
+static bool
+SISetNumEntries(SISeg * segP, int num)
{
- if ( num <= MAXNUMMESSAGES) {
- segP->numEntries = num;
- return(true);
- } else {
- return(false); /* table full */
- }
+ if (num <= MAXNUMMESSAGES)
+ {
+ segP->numEntries = num;
+ return (true);
+ }
+ else
+ {
+ return (false); /* table full */
+ }
}
/************************************************************************/
-/* SIGetNumEntries(segP) - returns the current nuber of entries */
+/* SIGetNumEntries(segP) - returns the current nuber of entries */
/************************************************************************/
static int
-SIGetNumEntries(SISeg *segP)
+SIGetNumEntries(SISeg * segP)
{
- return(segP->numEntries);
+ return (segP->numEntries);
}
/************************************************************************/
-/* SISetMaxNumEntries(segP, num) sets the maximal number of entries */
+/* SISetMaxNumEntries(segP, num) sets the maximal number of entries */
/************************************************************************/
-static bool
-SISetMaxNumEntries(SISeg *segP, int num)
+static bool
+SISetMaxNumEntries(SISeg * segP, int num)
{
- if ( num <= MAXNUMMESSAGES) {
- segP->maxNumEntries = num;
- return(true);
- } else {
- return(false); /* wrong number */
- }
+ if (num <= MAXNUMMESSAGES)
+ {
+ segP->maxNumEntries = num;
+ return (true);
+ }
+ else
+ {
+ return (false); /* wrong number */
+ }
}
/************************************************************************/
-/* SIGetProcStateLimit(segP, i) returns the limit of read messages */
+/* SIGetProcStateLimit(segP, i) returns the limit of read messages */
/************************************************************************/
static int
-SIGetProcStateLimit(SISeg *segP, int i)
+SIGetProcStateLimit(SISeg * segP, int i)
{
- return(segP->procState[i].limit);
+ return (segP->procState[i].limit);
}
/************************************************************************/
-/* SIIncNumEntries(segP, num) increments the current nuber of entries */
+/* SIIncNumEntries(segP, num) increments the current nuber of entries */
/************************************************************************/
-static bool
-SIIncNumEntries(SISeg *segP, int num)
+static bool
+SIIncNumEntries(SISeg * segP, int num)
{
- if ((segP->numEntries + num) <= MAXNUMMESSAGES) {
- segP->numEntries = segP->numEntries + num;
- return(true);
- } else {
- return(false); /* table full */
- }
+ if ((segP->numEntries + num) <= MAXNUMMESSAGES)
+ {
+ segP->numEntries = segP->numEntries + num;
+ return (true);
+ }
+ else
+ {
+ return (false); /* table full */
+ }
}
/************************************************************************/
-/* SIDecNumEntries(segP, num) decrements the current nuber of entries */
+/* SIDecNumEntries(segP, num) decrements the current nuber of entries */
/************************************************************************/
-static bool
-SIDecNumEntries(SISeg *segP, int num)
+static bool
+SIDecNumEntries(SISeg * segP, int num)
{
- if ((segP->numEntries - num) >= 0) {
- segP->numEntries = segP->numEntries - num;
- return(true);
- } else {
- return(false); /* not enough entries in table */
- }
+ if ((segP->numEntries - num) >= 0)
+ {
+ segP->numEntries = segP->numEntries - num;
+ return (true);
+ }
+ else
+ {
+ return (false); /* not enough entries in table */
+ }
}
/************************************************************************/
-/* SISetStartFreeSpace(segP, offset) - sets the offset */
+/* SISetStartFreeSpace(segP, offset) - sets the offset */
/************************************************************************/
static void
-SISetStartFreeSpace(SISeg *segP, Offset offset)
+SISetStartFreeSpace(SISeg * segP, Offset offset)
{
- segP->startFreeSpace = offset;
+ segP->startFreeSpace = offset;
}
/************************************************************************/
-/* SIGetStartFreeSpace(segP) - returns the offset */
+/* SIGetStartFreeSpace(segP) - returns the offset */
/************************************************************************/
-static Offset
-SIGetStartFreeSpace(SISeg *segP)
+static Offset
+SIGetStartFreeSpace(SISeg * segP)
{
- return(segP->startFreeSpace);
+ return (segP->startFreeSpace);
}
/************************************************************************/
-/* SIGetFirstDataEntry(segP) returns first data entry */
+/* SIGetFirstDataEntry(segP) returns first data entry */
/************************************************************************/
static SISegEntry *
-SIGetFirstDataEntry(SISeg *segP)
+SIGetFirstDataEntry(SISeg * segP)
{
- SISegEntry *eP;
- Offset startChain;
-
- startChain = SIGetStartEntryChain(segP);
-
- if (startChain == InvalidOffset)
- return(NULL);
-
- eP = (SISegEntry *) ((Pointer) segP +
- SIGetStartEntrySection(segP) +
- startChain );
- return(eP);
+ SISegEntry *eP;
+ Offset startChain;
+
+ startChain = SIGetStartEntryChain(segP);
+
+ if (startChain == InvalidOffset)
+ return (NULL);
+
+ eP = (SISegEntry *) ((Pointer) segP +
+ SIGetStartEntrySection(segP) +
+ startChain);
+ return (eP);
}
/************************************************************************/
-/* SIGetLastDataEntry(segP) returns last data entry in the chain */
+/* SIGetLastDataEntry(segP) returns last data entry in the chain */
/************************************************************************/
static SISegEntry *
-SIGetLastDataEntry(SISeg *segP)
+SIGetLastDataEntry(SISeg * segP)
{
- SISegEntry *eP;
- Offset endChain;
-
- endChain = SIGetEndEntryChain(segP);
-
- if (endChain == InvalidOffset)
- return(NULL);
-
- eP = (SISegEntry *) ((Pointer) segP +
- SIGetStartEntrySection(segP) +
- endChain );
- return(eP);
+ SISegEntry *eP;
+ Offset endChain;
+
+ endChain = SIGetEndEntryChain(segP);
+
+ if (endChain == InvalidOffset)
+ return (NULL);
+
+ eP = (SISegEntry *) ((Pointer) segP +
+ SIGetStartEntrySection(segP) +
+ endChain);
+ return (eP);
}
/************************************************************************/
-/* SIGetNextDataEntry(segP, offset) returns next data entry */
+/* SIGetNextDataEntry(segP, offset) returns next data entry */
/************************************************************************/
static SISegEntry *
-SIGetNextDataEntry(SISeg *segP, Offset offset)
+SIGetNextDataEntry(SISeg * segP, Offset offset)
{
- SISegEntry *eP;
-
- if (offset == InvalidOffset)
- return(NULL);
-
- eP = (SISegEntry *) ((Pointer) segP +
- SIGetStartEntrySection(segP) +
- offset);
- return(eP);
+ SISegEntry *eP;
+
+ if (offset == InvalidOffset)
+ return (NULL);
+
+ eP = (SISegEntry *) ((Pointer) segP +
+ SIGetStartEntrySection(segP) +
+ offset);
+ return (eP);
}
@@ -443,352 +468,396 @@ SIGetNextDataEntry(SISeg *segP, Offset offset)
/* SIGetNthDataEntry(segP, n) returns the n-th data entry in chain */
/************************************************************************/
static SISegEntry *
-SIGetNthDataEntry(SISeg *segP,
- int n) /* must range from 1 to MaxMessages */
+SIGetNthDataEntry(SISeg * segP,
+ int n) /* must range from 1 to MaxMessages */
{
- SISegEntry *eP;
- int i;
-
- if (n <= 0) return(NULL);
-
- eP = SIGetFirstDataEntry(segP);
- for (i = 1; i < n; i++) {
- /* skip one and get the next */
- eP = SIGetNextDataEntry(segP, eP->next);
- }
-
- return(eP);
+ SISegEntry *eP;
+ int i;
+
+ if (n <= 0)
+ return (NULL);
+
+ eP = SIGetFirstDataEntry(segP);
+ for (i = 1; i < n; i++)
+ {
+ /* skip one and get the next */
+ eP = SIGetNextDataEntry(segP, eP->next);
+ }
+
+ return (eP);
}
/************************************************************************/
-/* SIEntryOffset(segP, entryP) returns the offset for an pointer */
+/* SIEntryOffset(segP, entryP) returns the offset for an pointer */
/************************************************************************/
-static Offset
-SIEntryOffset(SISeg *segP, SISegEntry *entryP)
+static Offset
+SIEntryOffset(SISeg * segP, SISegEntry * entryP)
{
- /* relative to B !! */
- return ((Offset) ((Pointer) entryP -
- (Pointer) segP -
- SIGetStartEntrySection(segP) ));
+ /* relative to B !! */
+ return ((Offset) ((Pointer) entryP -
+ (Pointer) segP -
+ SIGetStartEntrySection(segP)));
}
/************************************************************************/
-/* SISetDataEntry(segP, data) - sets a message in the segemnt */
+/* SISetDataEntry(segP, data) - sets a message in the segemnt */
/************************************************************************/
bool
-SISetDataEntry(SISeg *segP, SharedInvalidData *data)
-{
- Offset offsetToNewData;
- SISegEntry *eP, *lastP;
-
- if (!SIIncNumEntries(segP, 1))
- return(false); /* no space */
-
- /* get a free entry */
- offsetToNewData = SIGetStartFreeSpace(segP);
- eP = SIGetNextDataEntry(segP, offsetToNewData); /* it's a free one */
- SISetStartFreeSpace(segP, eP->next);
- /* fill it up */
- eP->entryData = *data;
- eP->isfree = false;
- eP->next = InvalidOffset;
-
- /* handle insertion point at the end of the chain !!*/
- lastP = SIGetLastDataEntry(segP);
- if (lastP == NULL) {
- /* there is no chain, insert the first entry */
- SISetStartEntryChain(segP, SIEntryOffset(segP, eP));
- } else {
- /* there is a last entry in the chain */
- lastP->next = SIEntryOffset(segP, eP);
- }
- SISetEndEntryChain(segP, SIEntryOffset(segP, eP));
- return(true);
-}
-
-
-/************************************************************************/
-/* SIDecProcLimit(segP, num) decrements all process limits */
+SISetDataEntry(SISeg * segP, SharedInvalidData * data)
+{
+ Offset offsetToNewData;
+ SISegEntry *eP,
+ *lastP;
+
+ if (!SIIncNumEntries(segP, 1))
+ return (false); /* no space */
+
+ /* get a free entry */
+ offsetToNewData = SIGetStartFreeSpace(segP);
+ eP = SIGetNextDataEntry(segP, offsetToNewData); /* it's a free one */
+ SISetStartFreeSpace(segP, eP->next);
+ /* fill it up */
+ eP->entryData = *data;
+ eP->isfree = false;
+ eP->next = InvalidOffset;
+
+ /* handle insertion point at the end of the chain !! */
+ lastP = SIGetLastDataEntry(segP);
+ if (lastP == NULL)
+ {
+ /* there is no chain, insert the first entry */
+ SISetStartEntryChain(segP, SIEntryOffset(segP, eP));
+ }
+ else
+ {
+ /* there is a last entry in the chain */
+ lastP->next = SIEntryOffset(segP, eP);
+ }
+ SISetEndEntryChain(segP, SIEntryOffset(segP, eP));
+ return (true);
+}
+
+
+/************************************************************************/
+/* SIDecProcLimit(segP, num) decrements all process limits */
/************************************************************************/
static void
-SIDecProcLimit(SISeg *segP, int num)
-{
- int i;
- for (i=0; i < MaxBackendId; i++) {
- /* decrement only, if there is a limit > 0 */
- if (segP->procState[i].limit > 0) {
- segP->procState[i].limit = segP->procState[i].limit - num;
- if (segP->procState[i].limit < 0) {
- /* limit was not high enough, reset to zero */
- /* negative means it's a dead backend */
- segP->procState[i].limit = 0;
- }
- }
- }
+SIDecProcLimit(SISeg * segP, int num)
+{
+ int i;
+
+ for (i = 0; i < MaxBackendId; i++)
+ {
+ /* decrement only, if there is a limit > 0 */
+ if (segP->procState[i].limit > 0)
+ {
+ segP->procState[i].limit = segP->procState[i].limit - num;
+ if (segP->procState[i].limit < 0)
+ {
+ /* limit was not high enough, reset to zero */
+ /* negative means it's a dead backend */
+ segP->procState[i].limit = 0;
+ }
+ }
+ }
}
/************************************************************************/
-/* SIDelDataEntry(segP) - free the FIRST entry */
+/* SIDelDataEntry(segP) - free the FIRST entry */
/************************************************************************/
bool
-SIDelDataEntry(SISeg *segP)
+SIDelDataEntry(SISeg * segP)
{
- SISegEntry *e1P;
-
- if (!SIDecNumEntries(segP, 1)) {
- /* no entries in buffer */
- return(false);
- }
-
- e1P = SIGetFirstDataEntry(segP);
- SISetStartEntryChain(segP, e1P->next);
- if (SIGetStartEntryChain(segP) == InvalidOffset) {
- /* it was the last entry */
- SISetEndEntryChain(segP, InvalidOffset);
- }
- /* free the entry */
- e1P->isfree = true;
- e1P->next = SIGetStartFreeSpace(segP);
- SISetStartFreeSpace(segP, SIEntryOffset(segP, e1P));
- SIDecProcLimit(segP, 1);
- return(true);
+ SISegEntry *e1P;
+
+ if (!SIDecNumEntries(segP, 1))
+ {
+ /* no entries in buffer */
+ return (false);
+ }
+
+ e1P = SIGetFirstDataEntry(segP);
+ SISetStartEntryChain(segP, e1P->next);
+ if (SIGetStartEntryChain(segP) == InvalidOffset)
+ {
+ /* it was the last entry */
+ SISetEndEntryChain(segP, InvalidOffset);
+ }
+ /* free the entry */
+ e1P->isfree = true;
+ e1P->next = SIGetStartFreeSpace(segP);
+ SISetStartFreeSpace(segP, SIEntryOffset(segP, e1P));
+ SIDecProcLimit(segP, 1);
+ return (true);
}
/************************************************************************/
-/* SISetProcStateInvalid(segP) checks and marks a backends state as */
-/* invalid */
+/* SISetProcStateInvalid(segP) checks and marks a backends state as */
+/* invalid */
/************************************************************************/
void
-SISetProcStateInvalid(SISeg *segP)
-{
- int i;
-
- for (i=0; i < MaxBackendId; i++) {
- if (segP->procState[i].limit == 0) {
- /* backend i didn't read any message */
- segP->procState[i].resetState = true;
- /*XXX signal backend that it has to reset its internal cache ? */
- }
- }
+SISetProcStateInvalid(SISeg * segP)
+{
+ int i;
+
+ for (i = 0; i < MaxBackendId; i++)
+ {
+ if (segP->procState[i].limit == 0)
+ {
+ /* backend i didn't read any message */
+ segP->procState[i].resetState = true;
+
+ /*
+ * XXX signal backend that it has to reset its internal cache
+ * ?
+ */
+ }
+ }
}
/************************************************************************/
-/* SIReadEntryData(segP, backendId, function) */
-/* - marks messages to be read by id */
-/* and executes function */
+/* SIReadEntryData(segP, backendId, function) */
+/* - marks messages to be read by id */
+/* and executes function */
/************************************************************************/
void
-SIReadEntryData(SISeg *segP,
- int backendId,
- void (*invalFunction)(),
- void (*resetFunction)())
-{
- int i = 0;
- SISegEntry *data;
-
- Assert(segP->procState[backendId - 1].tag == MyBackendTag);
-
- if (!segP->procState[backendId - 1].resetState) {
- /* invalidate data, but only those, you have not seen yet !!*/
- /* therefore skip read messages */
- data = SIGetNthDataEntry(segP,
- SIGetProcStateLimit(segP, backendId - 1) + 1);
- while (data != NULL) {
- i++;
- segP->procState[backendId - 1].limit++; /* one more message read */
- invalFunction(data->entryData.cacheId,
- data->entryData.hashIndex,
- &data->entryData.pointerData);
- data = SIGetNextDataEntry(segP, data->next);
- }
- /* SIDelExpiredDataEntries(segP); */
- } else {
- /*backend must not read messages, its own state has to be reset */
- elog(NOTICE, "SIMarkEntryData: cache state reset");
- resetFunction(); /* XXXX call it here, parameters? */
-
- /* new valid state--mark all messages "read" */
- segP->procState[backendId - 1].resetState = false;
- segP->procState[backendId - 1].limit = SIGetNumEntries(segP);
- }
- /* check whether we can remove dead messages */
- if (i > MAXNUMMESSAGES) {
- elog(FATAL, "SIReadEntryData: Invalid segment state");
- }
+SIReadEntryData(SISeg * segP,
+ int backendId,
+ void (*invalFunction) (),
+ void (*resetFunction) ())
+{
+ int i = 0;
+ SISegEntry *data;
+
+ Assert(segP->procState[backendId - 1].tag == MyBackendTag);
+
+ if (!segP->procState[backendId - 1].resetState)
+ {
+ /* invalidate data, but only those, you have not seen yet !! */
+ /* therefore skip read messages */
+ data = SIGetNthDataEntry(segP,
+ SIGetProcStateLimit(segP, backendId - 1) + 1);
+ while (data != NULL)
+ {
+ i++;
+ segP->procState[backendId - 1].limit++; /* one more message read */
+ invalFunction(data->entryData.cacheId,
+ data->entryData.hashIndex,
+ &data->entryData.pointerData);
+ data = SIGetNextDataEntry(segP, data->next);
+ }
+ /* SIDelExpiredDataEntries(segP); */
+ }
+ else
+ {
+ /* backend must not read messages, its own state has to be reset */
+ elog(NOTICE, "SIMarkEntryData: cache state reset");
+ resetFunction(); /* XXXX call it here, parameters? */
+
+ /* new valid state--mark all messages "read" */
+ segP->procState[backendId - 1].resetState = false;
+ segP->procState[backendId - 1].limit = SIGetNumEntries(segP);
+ }
+ /* check whether we can remove dead messages */
+ if (i > MAXNUMMESSAGES)
+ {
+ elog(FATAL, "SIReadEntryData: Invalid segment state");
+ }
}
/************************************************************************/
-/* SIDelExpiredDataEntries (segP) - removes irrelevant messages */
+/* SIDelExpiredDataEntries (segP) - removes irrelevant messages */
/************************************************************************/
void
-SIDelExpiredDataEntries(SISeg *segP)
-{
- int min, i, h;
-
- min = 9999999;
- for (i = 0; i < MaxBackendId; i++) {
- h = SIGetProcStateLimit(segP, i);
- if (h >= 0) { /* backend active */
- if (h < min ) min = h;
- }
- }
- if (min != 9999999) {
- /* we can remove min messages */
- for (i = 1; i <= min; i++) {
- /* this adjusts also the state limits!*/
- if (!SIDelDataEntry(segP)) {
- elog(FATAL, "SIDelExpiredDataEntries: Invalid segment state");
- }
- }
- }
+SIDelExpiredDataEntries(SISeg * segP)
+{
+ int min,
+ i,
+ h;
+
+ min = 9999999;
+ for (i = 0; i < MaxBackendId; i++)
+ {
+ h = SIGetProcStateLimit(segP, i);
+ if (h >= 0)
+ { /* backend active */
+ if (h < min)
+ min = h;
+ }
+ }
+ if (min != 9999999)
+ {
+ /* we can remove min messages */
+ for (i = 1; i <= min; i++)
+ {
+ /* this adjusts also the state limits! */
+ if (!SIDelDataEntry(segP))
+ {
+ elog(FATAL, "SIDelExpiredDataEntries: Invalid segment state");
+ }
+ }
+ }
}
/************************************************************************/
-/* SISegInit(segP) - initializes the segment */
+/* SISegInit(segP) - initializes the segment */
/************************************************************************/
static void
-SISegInit(SISeg *segP)
-{
- SISegOffsets *oP;
- int segSize, i;
- SISegEntry *eP;
-
- oP = SIComputeSize(&segSize);
- /* set sempahore ids in the segment */
- /* XXX */
- SISetStartEntrySection(segP, oP->offsetToFirstEntry);
- SISetEndEntrySection(segP, oP->offsetToEndOfSegemnt);
- SISetStartFreeSpace(segP, 0);
- SISetStartEntryChain(segP, InvalidOffset);
- SISetEndEntryChain(segP, InvalidOffset);
- SISetNumEntries(segP, 0);
- SISetMaxNumEntries(segP, MAXNUMMESSAGES);
- for (i = 0; i < MaxBackendId; i++) {
- segP->procState[i].limit = -1; /* no backend active !!*/
- segP->procState[i].resetState = false;
- segP->procState[i].tag = InvalidBackendTag;
- }
- /* construct a chain of free entries */
- for (i = 1; i < MAXNUMMESSAGES; i++) {
- eP = (SISegEntry *) ((Pointer) segP +
- SIGetStartEntrySection(segP) +
- (i - 1) * sizeof(SISegEntry));
- eP->isfree = true;
- eP->next = i * sizeof(SISegEntry); /* relative to B */
- }
- /* handle the last free entry separate */
- eP = (SISegEntry *) ((Pointer) segP +
- SIGetStartEntrySection(segP) +
- (MAXNUMMESSAGES - 1) * sizeof(SISegEntry));
- eP->isfree = true;
- eP->next = InvalidOffset; /* it's the end of the chain !! */
- /*
- * Be tidy
- */
- pfree(oP);
-
-}
-
-
-
-/************************************************************************/
-/* SISegmentKill(key) - kill any segment */
+SISegInit(SISeg * segP)
+{
+ SISegOffsets *oP;
+ int segSize,
+ i;
+ SISegEntry *eP;
+
+ oP = SIComputeSize(&segSize);
+ /* set sempahore ids in the segment */
+ /* XXX */
+ SISetStartEntrySection(segP, oP->offsetToFirstEntry);
+ SISetEndEntrySection(segP, oP->offsetToEndOfSegemnt);
+ SISetStartFreeSpace(segP, 0);
+ SISetStartEntryChain(segP, InvalidOffset);
+ SISetEndEntryChain(segP, InvalidOffset);
+ SISetNumEntries(segP, 0);
+ SISetMaxNumEntries(segP, MAXNUMMESSAGES);
+ for (i = 0; i < MaxBackendId; i++)
+ {
+ segP->procState[i].limit = -1; /* no backend active !! */
+ segP->procState[i].resetState = false;
+ segP->procState[i].tag = InvalidBackendTag;
+ }
+ /* construct a chain of free entries */
+ for (i = 1; i < MAXNUMMESSAGES; i++)
+ {
+ eP = (SISegEntry *) ((Pointer) segP +
+ SIGetStartEntrySection(segP) +
+ (i - 1) * sizeof(SISegEntry));
+ eP->isfree = true;
+ eP->next = i * sizeof(SISegEntry); /* relative to B */
+ }
+ /* handle the last free entry separate */
+ eP = (SISegEntry *) ((Pointer) segP +
+ SIGetStartEntrySection(segP) +
+ (MAXNUMMESSAGES - 1) * sizeof(SISegEntry));
+ eP->isfree = true;
+ eP->next = InvalidOffset; /* it's the end of the chain !! */
+
+ /*
+ * Be tidy
+ */
+ pfree(oP);
+
+}
+
+
+
+/************************************************************************/
+/* SISegmentKill(key) - kill any segment */
/************************************************************************/
static void
-SISegmentKill(int key) /* the corresponding key for the segment */
-{
- IpcMemoryKill(key);
-}
+SISegmentKill(int key) /* the corresponding key for the segment */
+{
+ IpcMemoryKill(key);
+}
/************************************************************************/
-/* SISegmentGet(key, size) - get a shared segment of size <size> */
-/* returns a segment id */
+/* SISegmentGet(key, size) - get a shared segment of size <size> */
+/* returns a segment id */
/************************************************************************/
-static IpcMemoryId
-SISegmentGet(int key, /* the corresponding key for the segment */
- int size, /* size of segment in bytes */
- bool create)
+static IpcMemoryId
+SISegmentGet(int key, /* the corresponding key for the segment */
+ int size, /* size of segment in bytes */
+ bool create)
{
- IpcMemoryId shmid;
-
- if (create) {
- shmid = IpcMemoryCreate(key, size, IPCProtection);
- } else {
- shmid = IpcMemoryIdGet(key, size);
- }
- return(shmid);
+ IpcMemoryId shmid;
+
+ if (create)
+ {
+ shmid = IpcMemoryCreate(key, size, IPCProtection);
+ }
+ else
+ {
+ shmid = IpcMemoryIdGet(key, size);
+ }
+ return (shmid);
}
/************************************************************************/
-/* SISegmentAttach(shmid) - attach a shared segment with id shmid */
+/* SISegmentAttach(shmid) - attach a shared segment with id shmid */
/************************************************************************/
static void
SISegmentAttach(IpcMemoryId shmid)
{
- shmInvalBuffer = (struct SISeg *) IpcMemoryAttach(shmid);
- if (shmInvalBuffer == IpcMemAttachFailed) {
- /* XXX use validity function */
- elog(NOTICE, "SISegmentAttach: Could not attach segment");
- elog(FATAL, "SISegmentAttach: %m");
- }
+ shmInvalBuffer = (struct SISeg *) IpcMemoryAttach(shmid);
+ if (shmInvalBuffer == IpcMemAttachFailed)
+ {
+ /* XXX use validity function */
+ elog(NOTICE, "SISegmentAttach: Could not attach segment");
+ elog(FATAL, "SISegmentAttach: %m");
+ }
}
/************************************************************************/
-/* SISegmentInit(killExistingSegment, key) initialize segment */
+/* SISegmentInit(killExistingSegment, key) initialize segment */
/************************************************************************/
int
SISegmentInit(bool killExistingSegment, IPCKey key)
-{
- SISegOffsets *oP;
- int segSize;
- IpcMemoryId shmId;
- bool create;
-
- if (killExistingSegment) {
- /* Kill existing segment */
- /* set semaphore */
- SISegmentKill(key);
-
- /* Get a shared segment */
-
- oP = SIComputeSize(&segSize);
- /*
- * Be tidy
- */
- pfree(oP);
-
- create = true;
- shmId = SISegmentGet(key,segSize, create);
- if (shmId < 0) {
- perror("SISegmentGet: failed");
- return(-1); /* an error */
- }
-
- /* Attach the shared cache invalidation segment */
- /* sets the global variable shmInvalBuffer */
- SISegmentAttach(shmId);
-
- /* Init shared memory table */
- SISegInit(shmInvalBuffer);
- } else {
- /* use an existing segment */
- create = false;
- shmId = SISegmentGet(key, 0, create);
- if (shmId < 0) {
- perror("SISegmentGet: getting an existent segment failed");
- return(-1); /* an error */
- }
- /* Attach the shared cache invalidation segment */
- SISegmentAttach(shmId);
- }
- return(1);
-}
+{
+ SISegOffsets *oP;
+ int segSize;
+ IpcMemoryId shmId;
+ bool create;
+
+ if (killExistingSegment)
+ {
+ /* Kill existing segment */
+ /* set semaphore */
+ SISegmentKill(key);
+
+ /* Get a shared segment */
+
+ oP = SIComputeSize(&segSize);
+
+ /*
+ * Be tidy
+ */
+ pfree(oP);
+ create = true;
+ shmId = SISegmentGet(key, segSize, create);
+ if (shmId < 0)
+ {
+ perror("SISegmentGet: failed");
+ return (-1); /* an error */
+ }
+
+ /* Attach the shared cache invalidation segment */
+ /* sets the global variable shmInvalBuffer */
+ SISegmentAttach(shmId);
+
+ /* Init shared memory table */
+ SISegInit(shmInvalBuffer);
+ }
+ else
+ {
+ /* use an existing segment */
+ create = false;
+ shmId = SISegmentGet(key, 0, create);
+ if (shmId < 0)
+ {
+ perror("SISegmentGet: getting an existent segment failed");
+ return (-1); /* an error */
+ }
+ /* Attach the shared cache invalidation segment */
+ SISegmentAttach(shmId);
+ }
+ return (1);
+}
diff --git a/src/backend/storage/ipc/spin.c b/src/backend/storage/ipc/spin.c
index b50d5d9500f..e93d5894a58 100644
--- a/src/backend/storage/ipc/spin.c
+++ b/src/backend/storage/ipc/spin.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* spin.c--
- * routines for managing spin locks
+ * routines for managing spin locks
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.6 1997/08/21 13:43:46 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.7 1997/09/07 04:48:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,8 +21,8 @@
* term semaphores separately anyway.
*
* NOTE: These routines are not supposed to be widely used in Postgres.
- * They are preserved solely for the purpose of porting Mark Sullivan's
- * buffer manager to Postgres.
+ * They are preserved solely for the purpose of porting Mark Sullivan's
+ * buffer manager to Postgres.
*/
#include <errno.h>
#include "postgres.h"
@@ -43,61 +43,62 @@ IpcSemaphoreId SpinLockId;
bool
CreateSpinlocks(IPCKey key)
-{
- /* the spin lock shared memory must have been created by now */
- return(TRUE);
+{
+ /* the spin lock shared memory must have been created by now */
+ return (TRUE);
}
bool
InitSpinLocks(int init, IPCKey key)
{
- extern SPINLOCK ShmemLock;
- extern SPINLOCK BindingLock;
- extern SPINLOCK BufMgrLock;
- extern SPINLOCK LockMgrLock;
- extern SPINLOCK ProcStructLock;
- extern SPINLOCK SInvalLock;
- extern SPINLOCK OidGenLockId;
-
+ extern SPINLOCK ShmemLock;
+ extern SPINLOCK BindingLock;
+ extern SPINLOCK BufMgrLock;
+ extern SPINLOCK LockMgrLock;
+ extern SPINLOCK ProcStructLock;
+ extern SPINLOCK SInvalLock;
+ extern SPINLOCK OidGenLockId;
+
#ifdef MAIN_MEMORY
- extern SPINLOCK MMCacheLock;
-#endif /* SONY_JUKEBOX */
-
- /* These six spinlocks have fixed location is shmem */
- ShmemLock = (SPINLOCK) SHMEMLOCKID;
- BindingLock = (SPINLOCK) BINDINGLOCKID;
- BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
- LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
- ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
- SInvalLock = (SPINLOCK) SINVALLOCKID;
- OidGenLockId = (SPINLOCK) OIDGENLOCKID;
-
+ extern SPINLOCK MMCacheLock;
+
+#endif /* SONY_JUKEBOX */
+
+ /* These six spinlocks have fixed location is shmem */
+ ShmemLock = (SPINLOCK) SHMEMLOCKID;
+ BindingLock = (SPINLOCK) BINDINGLOCKID;
+ BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
+ LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
+ ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
+ SInvalLock = (SPINLOCK) SINVALLOCKID;
+ OidGenLockId = (SPINLOCK) OIDGENLOCKID;
+
#ifdef MAIN_MEMORY
- MMCacheLock = (SPINLOCK) MMCACHELOCKID;
-#endif /* MAIN_MEMORY */
-
- return(TRUE);
+ MMCacheLock = (SPINLOCK) MMCACHELOCKID;
+#endif /* MAIN_MEMORY */
+
+ return (TRUE);
}
void
SpinAcquire(SPINLOCK lock)
{
- ExclusiveLock(lock);
- PROC_INCR_SLOCK(lock);
+ ExclusiveLock(lock);
+ PROC_INCR_SLOCK(lock);
}
void
SpinRelease(SPINLOCK lock)
{
- PROC_DECR_SLOCK(lock);
- ExclusiveUnlock(lock);
+ PROC_DECR_SLOCK(lock);
+ ExclusiveUnlock(lock);
}
-#else /* HAS_TEST_AND_SET */
+#else /* HAS_TEST_AND_SET */
/* Spinlocks are implemented using SysV semaphores */
-static bool AttachSpinLocks(IPCKey key);
-static bool SpinIsLocked(SPINLOCK lock);
+static bool AttachSpinLocks(IPCKey key);
+static bool SpinIsLocked(SPINLOCK lock);
/*
* SpinAcquire -- try to grab a spinlock
@@ -107,86 +108,91 @@ static bool SpinIsLocked(SPINLOCK lock);
void
SpinAcquire(SPINLOCK lock)
{
- IpcSemaphoreLock(SpinLockId, lock, IpcExclusiveLock);
- PROC_INCR_SLOCK(lock);
+ IpcSemaphoreLock(SpinLockId, lock, IpcExclusiveLock);
+ PROC_INCR_SLOCK(lock);
}
/*
* SpinRelease -- release a spin lock
- *
+ *
* FAILS if the semaphore is corrupted
*/
void
SpinRelease(SPINLOCK lock)
{
- Assert(SpinIsLocked(lock))
+ Assert(SpinIsLocked(lock))
PROC_DECR_SLOCK(lock);
- IpcSemaphoreUnlock(SpinLockId, lock, IpcExclusiveLock);
+ IpcSemaphoreUnlock(SpinLockId, lock, IpcExclusiveLock);
}
-static bool
+static bool
SpinIsLocked(SPINLOCK lock)
{
- int semval;
-
- semval = IpcSemaphoreGetValue(SpinLockId, lock);
- return(semval < IpcSemaphoreDefaultStartValue);
+ int semval;
+
+ semval = IpcSemaphoreGetValue(SpinLockId, lock);
+ return (semval < IpcSemaphoreDefaultStartValue);
}
/*
* CreateSpinlocks -- Create a sysV semaphore array for
- * the spinlocks
+ * the spinlocks
*
*/
bool
CreateSpinlocks(IPCKey key)
{
-
- int status;
- IpcSemaphoreId semid;
- semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection,
- IpcSemaphoreDefaultStartValue, 1, &status);
- if (status == IpcSemIdExist) {
- IpcSemaphoreKill(key);
- elog(NOTICE,"Destroying old spinlock semaphore");
- semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection,
- IpcSemaphoreDefaultStartValue, 1, &status);
- }
-
- if (semid >= 0) {
- SpinLockId = semid;
- return(TRUE);
- }
- /* cannot create spinlocks */
- elog(FATAL,"CreateSpinlocks: cannot create spin locks");
- return(FALSE);
+
+ int status;
+ IpcSemaphoreId semid;
+
+ semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection,
+ IpcSemaphoreDefaultStartValue, 1, &status);
+ if (status == IpcSemIdExist)
+ {
+ IpcSemaphoreKill(key);
+ elog(NOTICE, "Destroying old spinlock semaphore");
+ semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection,
+ IpcSemaphoreDefaultStartValue, 1, &status);
+ }
+
+ if (semid >= 0)
+ {
+ SpinLockId = semid;
+ return (TRUE);
+ }
+ /* cannot create spinlocks */
+ elog(FATAL, "CreateSpinlocks: cannot create spin locks");
+ return (FALSE);
}
/*
* Attach to existing spinlock set
*/
-static bool
+static bool
AttachSpinLocks(IPCKey key)
{
- IpcSemaphoreId id;
-
- id = semget (key, MAX_SPINS, 0);
- if (id < 0) {
- if (errno == EEXIST) {
- /* key is the name of someone else's semaphore */
- elog (FATAL,"AttachSpinlocks: SPIN_KEY belongs to someone else");
+ IpcSemaphoreId id;
+
+ id = semget(key, MAX_SPINS, 0);
+ if (id < 0)
+ {
+ if (errno == EEXIST)
+ {
+ /* key is the name of someone else's semaphore */
+ elog(FATAL, "AttachSpinlocks: SPIN_KEY belongs to someone else");
+ }
+ /* cannot create spinlocks */
+ elog(FATAL, "AttachSpinlocks: cannot create spin locks");
+ return (FALSE);
}
- /* cannot create spinlocks */
- elog(FATAL,"AttachSpinlocks: cannot create spin locks");
- return(FALSE);
- }
- SpinLockId = id;
- return(TRUE);
+ SpinLockId = id;
+ return (TRUE);
}
/*
* InitSpinLocks -- Spinlock bootstrapping
- *
+ *
* We need several spinlocks for bootstrapping:
* BindingLock (for the shmem binding table) and
* ShmemLock (for the shmem allocator), BufMgrLock (for buffer
@@ -199,41 +205,47 @@ AttachSpinLocks(IPCKey key)
bool
InitSpinLocks(int init, IPCKey key)
{
- extern SPINLOCK ShmemLock;
- extern SPINLOCK BindingLock;
- extern SPINLOCK BufMgrLock;
- extern SPINLOCK LockMgrLock;
- extern SPINLOCK ProcStructLock;
- extern SPINLOCK SInvalLock;
- extern SPINLOCK OidGenLockId;
-
+ extern SPINLOCK ShmemLock;
+ extern SPINLOCK BindingLock;
+ extern SPINLOCK BufMgrLock;
+ extern SPINLOCK LockMgrLock;
+ extern SPINLOCK ProcStructLock;
+ extern SPINLOCK SInvalLock;
+ extern SPINLOCK OidGenLockId;
+
#ifdef MAIN_MEMORY
- extern SPINLOCK MMCacheLock;
-#endif /* MAIN_MEMORY */
-
- if (!init || key != IPC_PRIVATE) {
- /* if bootstrap and key is IPC_PRIVATE, it means that we are running
- * backend by itself. no need to attach spinlocks
- */
- if (! AttachSpinLocks(key)) {
- elog(FATAL,"InitSpinLocks: couldnt attach spin locks");
- return(FALSE);
+ extern SPINLOCK MMCacheLock;
+
+#endif /* MAIN_MEMORY */
+
+ if (!init || key != IPC_PRIVATE)
+ {
+
+ /*
+ * if bootstrap and key is IPC_PRIVATE, it means that we are
+ * running backend by itself. no need to attach spinlocks
+ */
+ if (!AttachSpinLocks(key))
+ {
+ elog(FATAL, "InitSpinLocks: couldnt attach spin locks");
+ return (FALSE);
+ }
}
- }
-
- /* These five (or six) spinlocks have fixed location is shmem */
- ShmemLock = (SPINLOCK) SHMEMLOCKID;
- BindingLock = (SPINLOCK) BINDINGLOCKID;
- BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
- LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
- ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
- SInvalLock = (SPINLOCK) SINVALLOCKID;
- OidGenLockId = (SPINLOCK) OIDGENLOCKID;
-
+
+ /* These five (or six) spinlocks have fixed location is shmem */
+ ShmemLock = (SPINLOCK) SHMEMLOCKID;
+ BindingLock = (SPINLOCK) BINDINGLOCKID;
+ BufMgrLock = (SPINLOCK) BUFMGRLOCKID;
+ LockMgrLock = (SPINLOCK) LOCKMGRLOCKID;
+ ProcStructLock = (SPINLOCK) PROCSTRUCTLOCKID;
+ SInvalLock = (SPINLOCK) SINVALLOCKID;
+ OidGenLockId = (SPINLOCK) OIDGENLOCKID;
+
#ifdef MAIN_MEMORY
- MMCacheLock = (SPINLOCK) MMCACHELOCKID;
-#endif /* MAIN_MEMORY */
-
- return(TRUE);
+ MMCacheLock = (SPINLOCK) MMCACHELOCKID;
+#endif /* MAIN_MEMORY */
+
+ return (TRUE);
}
-#endif /* HAS_TEST_AND_SET */
+
+#endif /* HAS_TEST_AND_SET */
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index ddf69a6527e..dfde8f469c5 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* inv_api.c--
- * routines for manipulating inversion fs large objects. This file
- * contains the user-level large object application interface routines.
+ * routines for manipulating inversion fs large objects. This file
+ * contains the user-level large object application interface routines.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.13 1997/08/19 21:33:10 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.14 1997/09/07 04:48:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <sys/types.h>
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include <sys/file.h>
#include <sys/stat.h>
@@ -28,11 +28,11 @@
#include "access/xact.h"
#include "access/nbtree.h"
#include "access/tupdesc.h"
-#include "catalog/index.h" /* for index_create() */
+#include "catalog/index.h" /* for index_create() */
#include "catalog/catalog.h" /* for newoid() */
-#include "catalog/pg_am.h" /* for BTREE_AM_OID */
+#include "catalog/pg_am.h" /* for BTREE_AM_OID */
#include "catalog/pg_opclass.h" /* for INT4_OPS_OID */
-#include "catalog/pg_proc.h" /* for INT4GE_PROC_OID */
+#include "catalog/pg_proc.h" /* for INT4GE_PROC_OID */
#include "storage/itemptr.h"
#include "storage/bufpage.h"
#include "storage/bufmgr.h"
@@ -43,226 +43,241 @@
#include "storage/large_object.h"
#include "storage/lmgr.h"
#include "utils/syscache.h"
-#include "utils/builtins.h" /* for namestrcpy() */
+#include "utils/builtins.h" /* for namestrcpy() */
#include "catalog/heap.h"
#include "nodes/pg_list.h"
/*
- * Warning, Will Robinson... In order to pack data into an inversion
- * file as densely as possible, we violate the class abstraction here.
- * When we're appending a new tuple to the end of the table, we check
- * the last page to see how much data we can put on it. If it's more
- * than IMINBLK, we write enough to fill the page. This limits external
- * fragmentation. In no case can we write more than IMAXBLK, since
- * the 8K postgres page size less overhead leaves only this much space
- * for data.
+ * Warning, Will Robinson... In order to pack data into an inversion
+ * file as densely as possible, we violate the class abstraction here.
+ * When we're appending a new tuple to the end of the table, we check
+ * the last page to see how much data we can put on it. If it's more
+ * than IMINBLK, we write enough to fill the page. This limits external
+ * fragmentation. In no case can we write more than IMAXBLK, since
+ * the 8K postgres page size less overhead leaves only this much space
+ * for data.
*/
-#define IFREESPC(p) (PageGetFreeSpace(p) - sizeof(HeapTupleData) - sizeof(struct varlena) - sizeof(int32))
-#define IMAXBLK 8092
-#define IMINBLK 512
+#define IFREESPC(p) (PageGetFreeSpace(p) - sizeof(HeapTupleData) - sizeof(struct varlena) - sizeof(int32))
+#define IMAXBLK 8092
+#define IMINBLK 512
/* non-export function prototypes */
-static HeapTuple inv_newtuple(LargeObjectDesc *obj_desc, Buffer buffer,
- Page page, char *dbuf, int nwrite);
-static HeapTuple inv_fetchtup(LargeObjectDesc *obj_desc, Buffer *bufP);
-static int inv_wrnew(LargeObjectDesc *obj_desc, char *buf, int nbytes);
-static int inv_wrold(LargeObjectDesc *obj_desc, char *dbuf, int nbytes,
- HeapTuple htup, Buffer buffer);
-static void inv_indextup(LargeObjectDesc *obj_desc, HeapTuple htup);
-static int _inv_getsize(Relation hreln, TupleDesc hdesc, Relation ireln);
+static HeapTuple
+inv_newtuple(LargeObjectDesc * obj_desc, Buffer buffer,
+ Page page, char *dbuf, int nwrite);
+static HeapTuple inv_fetchtup(LargeObjectDesc * obj_desc, Buffer * bufP);
+static int inv_wrnew(LargeObjectDesc * obj_desc, char *buf, int nbytes);
+static int
+inv_wrold(LargeObjectDesc * obj_desc, char *dbuf, int nbytes,
+ HeapTuple htup, Buffer buffer);
+static void inv_indextup(LargeObjectDesc * obj_desc, HeapTuple htup);
+static int _inv_getsize(Relation hreln, TupleDesc hdesc, Relation ireln);
/*
- * inv_create -- create a new large object.
+ * inv_create -- create a new large object.
*
- * Arguments:
- * flags -- storage manager to use, archive mode, etc.
+ * Arguments:
+ * flags -- storage manager to use, archive mode, etc.
*
- * Returns:
- * large object descriptor, appropriately filled in.
+ * Returns:
+ * large object descriptor, appropriately filled in.
*/
LargeObjectDesc *
inv_create(int flags)
{
- int file_oid;
- LargeObjectDesc *retval;
- Relation r;
- Relation indr;
- int smgr;
- char archchar;
- TupleDesc tupdesc;
- AttrNumber attNums[1];
- Oid classObjectId[1];
- char objname[NAMEDATALEN];
- char indname[NAMEDATALEN];
-
- /* parse flags */
- smgr = flags & INV_SMGRMASK;
- if (flags & INV_ARCHIVE)
- archchar = 'h';
- else
- archchar = 'n';
-
- /* add one here since the pg_class tuple created
- will have the next oid and we want to have the relation name
- to correspond to the tuple OID */
- file_oid = newoid()+1;
-
- /* come up with some table names */
- sprintf(objname, "xinv%d", file_oid);
- sprintf(indname, "xinx%d", file_oid);
-
- if (SearchSysCacheTuple(RELNAME, PointerGetDatum(objname),
- 0,0,0) != NULL) {
- elog(WARN,
- "internal error: %s already exists -- cannot create large obj",
- objname);
- }
- if (SearchSysCacheTuple(RELNAME, PointerGetDatum(indname),
- 0,0,0) != NULL) {
- elog(WARN,
- "internal error: %s already exists -- cannot create large obj",
- indname);
- }
-
- /* this is pretty painful... want a tuple descriptor */
- tupdesc = CreateTemplateTupleDesc(2);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1,
- "olastbye",
- "int4",
- 0, false);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2,
- "odata",
- "bytea",
- 0, false);
- /*
- * First create the table to hold the inversion large object. It
- * will be located on whatever storage manager the user requested.
- */
-
- heap_create(objname,
- objname,
- (int) archchar, smgr,
- tupdesc);
-
- /* make the relation visible in this transaction */
- CommandCounterIncrement();
- r = heap_openr(objname);
-
- if (!RelationIsValid(r)) {
- elog(WARN, "cannot create large object on %s under inversion",
- smgrout(smgr));
- }
-
- /*
- * Now create a btree index on the relation's olastbyte attribute to
- * make seeks go faster. The hardwired constants are embarassing
- * to me, and are symptomatic of the pressure under which this code
- * was written.
- *
- * ok, mao, let's put in some symbolic constants - jolly
- */
-
- attNums[0] = 1;
- classObjectId[0] = INT4_OPS_OID;
- index_create(objname, indname, NULL, NULL, BTREE_AM_OID,
- 1, &attNums[0], &classObjectId[0],
- 0, (Datum) NULL, NULL, FALSE, FALSE);
-
- /* make the index visible in this transaction */
- CommandCounterIncrement();
- indr = index_openr(indname);
-
- if (!RelationIsValid(indr)) {
- elog(WARN, "cannot create index for large obj on %s under inversion",
- smgrout(smgr));
- }
-
- retval = (LargeObjectDesc *) palloc(sizeof(LargeObjectDesc));
-
- retval->heap_r = r;
- retval->index_r = indr;
- retval->iscan = (IndexScanDesc) NULL;
- retval->hdesc = RelationGetTupleDescriptor(r);
- retval->idesc = RelationGetTupleDescriptor(indr);
- retval->offset = retval->lowbyte =
- retval->highbyte = 0;
- ItemPointerSetInvalid(&(retval->htid));
-
- if (flags & INV_WRITE) {
- RelationSetLockForWrite(r);
- retval->flags = IFS_WRLOCK|IFS_RDLOCK;
- } else if (flags & INV_READ) {
- RelationSetLockForRead(r);
- retval->flags = IFS_RDLOCK;
- }
- retval->flags |= IFS_ATEOF;
-
- return(retval);
+ int file_oid;
+ LargeObjectDesc *retval;
+ Relation r;
+ Relation indr;
+ int smgr;
+ char archchar;
+ TupleDesc tupdesc;
+ AttrNumber attNums[1];
+ Oid classObjectId[1];
+ char objname[NAMEDATALEN];
+ char indname[NAMEDATALEN];
+
+ /* parse flags */
+ smgr = flags & INV_SMGRMASK;
+ if (flags & INV_ARCHIVE)
+ archchar = 'h';
+ else
+ archchar = 'n';
+
+ /*
+ * add one here since the pg_class tuple created will have the next
+ * oid and we want to have the relation name to correspond to the
+ * tuple OID
+ */
+ file_oid = newoid() + 1;
+
+ /* come up with some table names */
+ sprintf(objname, "xinv%d", file_oid);
+ sprintf(indname, "xinx%d", file_oid);
+
+ if (SearchSysCacheTuple(RELNAME, PointerGetDatum(objname),
+ 0, 0, 0) != NULL)
+ {
+ elog(WARN,
+ "internal error: %s already exists -- cannot create large obj",
+ objname);
+ }
+ if (SearchSysCacheTuple(RELNAME, PointerGetDatum(indname),
+ 0, 0, 0) != NULL)
+ {
+ elog(WARN,
+ "internal error: %s already exists -- cannot create large obj",
+ indname);
+ }
+
+ /* this is pretty painful... want a tuple descriptor */
+ tupdesc = CreateTemplateTupleDesc(2);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1,
+ "olastbye",
+ "int4",
+ 0, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 2,
+ "odata",
+ "bytea",
+ 0, false);
+
+ /*
+ * First create the table to hold the inversion large object. It will
+ * be located on whatever storage manager the user requested.
+ */
+
+ heap_create(objname,
+ objname,
+ (int) archchar, smgr,
+ tupdesc);
+
+ /* make the relation visible in this transaction */
+ CommandCounterIncrement();
+ r = heap_openr(objname);
+
+ if (!RelationIsValid(r))
+ {
+ elog(WARN, "cannot create large object on %s under inversion",
+ smgrout(smgr));
+ }
+
+ /*
+ * Now create a btree index on the relation's olastbyte attribute to
+ * make seeks go faster. The hardwired constants are embarassing to
+ * me, and are symptomatic of the pressure under which this code was
+ * written.
+ *
+ * ok, mao, let's put in some symbolic constants - jolly
+ */
+
+ attNums[0] = 1;
+ classObjectId[0] = INT4_OPS_OID;
+ index_create(objname, indname, NULL, NULL, BTREE_AM_OID,
+ 1, &attNums[0], &classObjectId[0],
+ 0, (Datum) NULL, NULL, FALSE, FALSE);
+
+ /* make the index visible in this transaction */
+ CommandCounterIncrement();
+ indr = index_openr(indname);
+
+ if (!RelationIsValid(indr))
+ {
+ elog(WARN, "cannot create index for large obj on %s under inversion",
+ smgrout(smgr));
+ }
+
+ retval = (LargeObjectDesc *) palloc(sizeof(LargeObjectDesc));
+
+ retval->heap_r = r;
+ retval->index_r = indr;
+ retval->iscan = (IndexScanDesc) NULL;
+ retval->hdesc = RelationGetTupleDescriptor(r);
+ retval->idesc = RelationGetTupleDescriptor(indr);
+ retval->offset = retval->lowbyte =
+ retval->highbyte = 0;
+ ItemPointerSetInvalid(&(retval->htid));
+
+ if (flags & INV_WRITE)
+ {
+ RelationSetLockForWrite(r);
+ retval->flags = IFS_WRLOCK | IFS_RDLOCK;
+ }
+ else if (flags & INV_READ)
+ {
+ RelationSetLockForRead(r);
+ retval->flags = IFS_RDLOCK;
+ }
+ retval->flags |= IFS_ATEOF;
+
+ return (retval);
}
LargeObjectDesc *
inv_open(Oid lobjId, int flags)
{
- LargeObjectDesc *retval;
- Relation r;
- char *indname;
- Relation indrel;
-
- r = heap_open(lobjId);
-
- if (!RelationIsValid(r))
- return ((LargeObjectDesc *) NULL);
-
- indname = pstrdup((r->rd_rel->relname).data);
-
- /*
- * hack hack hack... we know that the fourth character of the relation
- * name is a 'v', and that the fourth character of the index name is an
- * 'x', and that they're otherwise identical.
- */
- indname[3] = 'x';
- indrel = index_openr(indname);
-
- if (!RelationIsValid(indrel))
- return ((LargeObjectDesc *) NULL);
-
- retval = (LargeObjectDesc *) palloc(sizeof(LargeObjectDesc));
-
- retval->heap_r = r;
- retval->index_r = indrel;
- retval->iscan = (IndexScanDesc) NULL;
- retval->hdesc = RelationGetTupleDescriptor(r);
- retval->idesc = RelationGetTupleDescriptor(indrel);
- retval->offset = retval->lowbyte = retval->highbyte = 0;
- ItemPointerSetInvalid(&(retval->htid));
-
- if (flags & INV_WRITE) {
- RelationSetLockForWrite(r);
- retval->flags = IFS_WRLOCK|IFS_RDLOCK;
- } else if (flags & INV_READ) {
- RelationSetLockForRead(r);
- retval->flags = IFS_RDLOCK;
- }
-
- return(retval);
+ LargeObjectDesc *retval;
+ Relation r;
+ char *indname;
+ Relation indrel;
+
+ r = heap_open(lobjId);
+
+ if (!RelationIsValid(r))
+ return ((LargeObjectDesc *) NULL);
+
+ indname = pstrdup((r->rd_rel->relname).data);
+
+ /*
+ * hack hack hack... we know that the fourth character of the
+ * relation name is a 'v', and that the fourth character of the index
+ * name is an 'x', and that they're otherwise identical.
+ */
+ indname[3] = 'x';
+ indrel = index_openr(indname);
+
+ if (!RelationIsValid(indrel))
+ return ((LargeObjectDesc *) NULL);
+
+ retval = (LargeObjectDesc *) palloc(sizeof(LargeObjectDesc));
+
+ retval->heap_r = r;
+ retval->index_r = indrel;
+ retval->iscan = (IndexScanDesc) NULL;
+ retval->hdesc = RelationGetTupleDescriptor(r);
+ retval->idesc = RelationGetTupleDescriptor(indrel);
+ retval->offset = retval->lowbyte = retval->highbyte = 0;
+ ItemPointerSetInvalid(&(retval->htid));
+
+ if (flags & INV_WRITE)
+ {
+ RelationSetLockForWrite(r);
+ retval->flags = IFS_WRLOCK | IFS_RDLOCK;
+ }
+ else if (flags & INV_READ)
+ {
+ RelationSetLockForRead(r);
+ retval->flags = IFS_RDLOCK;
+ }
+
+ return (retval);
}
/*
* Closes an existing large object descriptor.
*/
void
-inv_close(LargeObjectDesc *obj_desc)
+inv_close(LargeObjectDesc * obj_desc)
{
- Assert(PointerIsValid(obj_desc));
+ Assert(PointerIsValid(obj_desc));
- if (obj_desc->iscan != (IndexScanDesc) NULL)
- index_endscan(obj_desc->iscan);
+ if (obj_desc->iscan != (IndexScanDesc) NULL)
+ index_endscan(obj_desc->iscan);
- heap_close(obj_desc->heap_r);
- index_close(obj_desc->index_r);
+ heap_close(obj_desc->heap_r);
+ index_close(obj_desc->index_r);
- pfree(obj_desc);
+ pfree(obj_desc);
}
/*
@@ -273,897 +288,941 @@ inv_close(LargeObjectDesc *obj_desc)
int
inv_destroy(Oid lobjId)
{
- Relation r;
+ Relation r;
- r = (Relation) RelationIdGetRelation(lobjId);
- if (!RelationIsValid(r) || r->rd_rel->relkind == RELKIND_INDEX)
- return -1;
+ r = (Relation) RelationIdGetRelation(lobjId);
+ if (!RelationIsValid(r) || r->rd_rel->relkind == RELKIND_INDEX)
+ return -1;
- heap_destroy(r->rd_rel->relname.data);
- return 1;
+ heap_destroy(r->rd_rel->relname.data);
+ return 1;
}
/*
- * inv_stat() -- do a stat on an inversion file.
+ * inv_stat() -- do a stat on an inversion file.
*
- * For the time being, this is an insanely expensive operation. In
- * order to find the size of the file, we seek to the last block in
- * it and compute the size from that. We scan pg_class to determine
- * the file's owner and create time. We don't maintain mod time or
- * access time, yet.
+ * For the time being, this is an insanely expensive operation. In
+ * order to find the size of the file, we seek to the last block in
+ * it and compute the size from that. We scan pg_class to determine
+ * the file's owner and create time. We don't maintain mod time or
+ * access time, yet.
*
- * These fields aren't stored in a table anywhere because they're
- * updated so frequently, and postgres only appends tuples at the
- * end of relations. Once clustering works, we should fix this.
+ * These fields aren't stored in a table anywhere because they're
+ * updated so frequently, and postgres only appends tuples at the
+ * end of relations. Once clustering works, we should fix this.
*/
#ifdef NOT_USED
int
-inv_stat(LargeObjectDesc *obj_desc, struct pgstat *stbuf)
+inv_stat(LargeObjectDesc * obj_desc, struct pgstat * stbuf)
{
- Assert(PointerIsValid(obj_desc));
- Assert(stbuf != NULL);
-
- /* need read lock for stat */
- if (!(obj_desc->flags & IFS_RDLOCK)) {
- RelationSetLockForRead(obj_desc->heap_r);
- obj_desc->flags |= IFS_RDLOCK;
- }
+ Assert(PointerIsValid(obj_desc));
+ Assert(stbuf != NULL);
+
+ /* need read lock for stat */
+ if (!(obj_desc->flags & IFS_RDLOCK))
+ {
+ RelationSetLockForRead(obj_desc->heap_r);
+ obj_desc->flags |= IFS_RDLOCK;
+ }
- stbuf->st_ino = obj_desc->heap_r->rd_id;
+ stbuf->st_ino = obj_desc->heap_r->rd_id;
#if 1
- stbuf->st_mode = (S_IFREG | 0666); /* IFREG|rw-rw-rw- */
+ stbuf->st_mode = (S_IFREG | 0666); /* IFREG|rw-rw-rw- */
#else
- stbuf->st_mode = 100666; /* IFREG|rw-rw-rw- */
+ stbuf->st_mode = 100666; /* IFREG|rw-rw-rw- */
#endif
- stbuf->st_size = _inv_getsize(obj_desc->heap_r,
- obj_desc->hdesc,
- obj_desc->index_r);
+ stbuf->st_size = _inv_getsize(obj_desc->heap_r,
+ obj_desc->hdesc,
+ obj_desc->index_r);
- stbuf->st_uid = obj_desc->heap_r->rd_rel->relowner;
+ stbuf->st_uid = obj_desc->heap_r->rd_rel->relowner;
- /* we have no good way of computing access times right now */
- stbuf->st_atime_s = stbuf->st_mtime_s = stbuf->st_ctime_s = 0;
+ /* we have no good way of computing access times right now */
+ stbuf->st_atime_s = stbuf->st_mtime_s = stbuf->st_ctime_s = 0;
- return (0);
+ return (0);
}
+
#endif
int
-inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
+inv_seek(LargeObjectDesc * obj_desc, int offset, int whence)
{
- int oldOffset;
- Datum d;
- ScanKeyData skey;
-
- Assert(PointerIsValid(obj_desc));
-
- if (whence == SEEK_CUR) {
- offset += obj_desc->offset; /* calculate absolute position */
- return (inv_seek(obj_desc, offset, SEEK_SET));
- }
-
- /*
- * if you seek past the end (offset > 0) I have
- * no clue what happens :-( B.L. 9/1/93
- */
- if (whence == SEEK_END) {
- /* need read lock for getsize */
- if (!(obj_desc->flags & IFS_RDLOCK)) {
- RelationSetLockForRead(obj_desc->heap_r);
- obj_desc->flags |= IFS_RDLOCK;
- }
- offset += _inv_getsize(obj_desc->heap_r,
- obj_desc->hdesc,
- obj_desc->index_r );
- return (inv_seek(obj_desc, offset, SEEK_SET));
- }
-
- /*
- * Whenever we do a seek, we turn off the EOF flag bit to force
- * ourselves to check for real on the next read.
- */
-
- obj_desc->flags &= ~IFS_ATEOF;
- oldOffset = obj_desc->offset;
- obj_desc->offset = offset;
-
- /* try to avoid doing any work, if we can manage it */
- if (offset >= obj_desc->lowbyte
- && offset <= obj_desc->highbyte
- && oldOffset <= obj_desc->highbyte
- && obj_desc->iscan != (IndexScanDesc) NULL)
- return (offset);
-
- /*
- * To do a seek on an inversion file, we start an index scan that
- * will bring us to the right place. Each tuple in an inversion file
- * stores the offset of the last byte that appears on it, and we have
- * an index on this.
- */
-
-
- /* right now, just assume that the operation is SEEK_SET */
- if (obj_desc->iscan != (IndexScanDesc) NULL) {
- d = Int32GetDatum(offset);
- btmovescan(obj_desc->iscan, d);
- } else {
-
- ScanKeyEntryInitialize(&skey, 0x0, 1, INT4GE_PROC_OID,
- Int32GetDatum(offset));
-
- obj_desc->iscan = index_beginscan(obj_desc->index_r,
- (bool) 0, (uint16) 1,
- &skey);
- }
-
- return (offset);
-}
+ int oldOffset;
+ Datum d;
+ ScanKeyData skey;
-int
-inv_tell(LargeObjectDesc *obj_desc)
-{
- Assert(PointerIsValid(obj_desc));
+ Assert(PointerIsValid(obj_desc));
- return (obj_desc->offset);
-}
+ if (whence == SEEK_CUR)
+ {
+ offset += obj_desc->offset; /* calculate absolute position */
+ return (inv_seek(obj_desc, offset, SEEK_SET));
+ }
-int
-inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
-{
- HeapTuple htup;
- Buffer b;
- int nread;
- int off;
- int ncopy;
- Datum d;
- struct varlena *fsblock;
- bool isNull;
-
- Assert(PointerIsValid(obj_desc));
- Assert(buf != NULL);
-
- /* if we're already at EOF, we don't need to do any work here */
- if (obj_desc->flags & IFS_ATEOF)
- return (0);
+ /*
+ * if you seek past the end (offset > 0) I have no clue what happens
+ * :-( B.L. 9/1/93
+ */
+ if (whence == SEEK_END)
+ {
+ /* need read lock for getsize */
+ if (!(obj_desc->flags & IFS_RDLOCK))
+ {
+ RelationSetLockForRead(obj_desc->heap_r);
+ obj_desc->flags |= IFS_RDLOCK;
+ }
+ offset += _inv_getsize(obj_desc->heap_r,
+ obj_desc->hdesc,
+ obj_desc->index_r);
+ return (inv_seek(obj_desc, offset, SEEK_SET));
+ }
- /* make sure we obey two-phase locking */
- if (!(obj_desc->flags & IFS_RDLOCK)) {
- RelationSetLockForRead(obj_desc->heap_r);
- obj_desc->flags |= IFS_RDLOCK;
- }
+ /*
+ * Whenever we do a seek, we turn off the EOF flag bit to force
+ * ourselves to check for real on the next read.
+ */
- nread = 0;
+ obj_desc->flags &= ~IFS_ATEOF;
+ oldOffset = obj_desc->offset;
+ obj_desc->offset = offset;
- /* fetch a block at a time */
- while (nread < nbytes) {
+ /* try to avoid doing any work, if we can manage it */
+ if (offset >= obj_desc->lowbyte
+ && offset <= obj_desc->highbyte
+ && oldOffset <= obj_desc->highbyte
+ && obj_desc->iscan != (IndexScanDesc) NULL)
+ return (offset);
+
+ /*
+ * To do a seek on an inversion file, we start an index scan that will
+ * bring us to the right place. Each tuple in an inversion file
+ * stores the offset of the last byte that appears on it, and we have
+ * an index on this.
+ */
- /* fetch an inversion file system block */
- htup = inv_fetchtup(obj_desc, &b);
- if (!HeapTupleIsValid(htup)) {
- obj_desc->flags |= IFS_ATEOF;
- break;
+ /* right now, just assume that the operation is SEEK_SET */
+ if (obj_desc->iscan != (IndexScanDesc) NULL)
+ {
+ d = Int32GetDatum(offset);
+ btmovescan(obj_desc->iscan, d);
}
+ else
+ {
- /* copy the data from this block into the buffer */
- d = (Datum) heap_getattr(htup, b, 2, obj_desc->hdesc, &isNull);
- fsblock = (struct varlena *) DatumGetPointer(d);
+ ScanKeyEntryInitialize(&skey, 0x0, 1, INT4GE_PROC_OID,
+ Int32GetDatum(offset));
- off = obj_desc->offset - obj_desc->lowbyte;
- ncopy = obj_desc->highbyte - obj_desc->offset + 1;
- if (ncopy > (nbytes - nread))
- ncopy = (nbytes - nread);
- memmove(buf, &(fsblock->vl_dat[off]), ncopy);
+ obj_desc->iscan = index_beginscan(obj_desc->index_r,
+ (bool) 0, (uint16) 1,
+ &skey);
+ }
- /* be a good citizen */
- ReleaseBuffer(b);
+ return (offset);
+}
- /* move pointers past the amount we just read */
- buf += ncopy;
- nread += ncopy;
- obj_desc->offset += ncopy;
- }
+int
+inv_tell(LargeObjectDesc * obj_desc)
+{
+ Assert(PointerIsValid(obj_desc));
- /* that's it */
- return (nread);
+ return (obj_desc->offset);
}
int
-inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
+inv_read(LargeObjectDesc * obj_desc, char *buf, int nbytes)
{
- HeapTuple htup;
- Buffer b;
- int nwritten;
- int tuplen;
+ HeapTuple htup;
+ Buffer b;
+ int nread;
+ int off;
+ int ncopy;
+ Datum d;
+ struct varlena *fsblock;
+ bool isNull;
+
+ Assert(PointerIsValid(obj_desc));
+ Assert(buf != NULL);
+
+ /* if we're already at EOF, we don't need to do any work here */
+ if (obj_desc->flags & IFS_ATEOF)
+ return (0);
+
+ /* make sure we obey two-phase locking */
+ if (!(obj_desc->flags & IFS_RDLOCK))
+ {
+ RelationSetLockForRead(obj_desc->heap_r);
+ obj_desc->flags |= IFS_RDLOCK;
+ }
+
+ nread = 0;
+
+ /* fetch a block at a time */
+ while (nread < nbytes)
+ {
+
+ /* fetch an inversion file system block */
+ htup = inv_fetchtup(obj_desc, &b);
- Assert(PointerIsValid(obj_desc));
- Assert(buf != NULL);
+ if (!HeapTupleIsValid(htup))
+ {
+ obj_desc->flags |= IFS_ATEOF;
+ break;
+ }
- /*
- * Make sure we obey two-phase locking. A write lock entitles you
- * to read the relation, as well.
- */
+ /* copy the data from this block into the buffer */
+ d = (Datum) heap_getattr(htup, b, 2, obj_desc->hdesc, &isNull);
+ fsblock = (struct varlena *) DatumGetPointer(d);
- if (!(obj_desc->flags & IFS_WRLOCK)) {
- RelationSetLockForRead(obj_desc->heap_r);
- obj_desc->flags |= (IFS_WRLOCK|IFS_RDLOCK);
- }
+ off = obj_desc->offset - obj_desc->lowbyte;
+ ncopy = obj_desc->highbyte - obj_desc->offset + 1;
+ if (ncopy > (nbytes - nread))
+ ncopy = (nbytes - nread);
+ memmove(buf, &(fsblock->vl_dat[off]), ncopy);
- nwritten = 0;
+ /* be a good citizen */
+ ReleaseBuffer(b);
- /* write a block at a time */
- while (nwritten < nbytes) {
+ /* move pointers past the amount we just read */
+ buf += ncopy;
+ nread += ncopy;
+ obj_desc->offset += ncopy;
+ }
+
+ /* that's it */
+ return (nread);
+}
+
+int
+inv_write(LargeObjectDesc * obj_desc, char *buf, int nbytes)
+{
+ HeapTuple htup;
+ Buffer b;
+ int nwritten;
+ int tuplen;
+
+ Assert(PointerIsValid(obj_desc));
+ Assert(buf != NULL);
/*
- * Fetch the current inversion file system block. If the
- * class storing the inversion file is empty, we don't want
- * to do an index lookup, since index lookups choke on empty
- * files (should be fixed someday).
+ * Make sure we obey two-phase locking. A write lock entitles you to
+ * read the relation, as well.
*/
- if ((obj_desc->flags & IFS_ATEOF)
- || obj_desc->heap_r->rd_nblocks == 0)
- htup = (HeapTuple) NULL;
- else
- htup = inv_fetchtup(obj_desc, &b);
-
- /* either append or replace a block, as required */
- if (!HeapTupleIsValid(htup)) {
- tuplen = inv_wrnew(obj_desc, buf, nbytes - nwritten);
- } else {
- if (obj_desc->offset > obj_desc->highbyte)
- tuplen = inv_wrnew(obj_desc, buf, nbytes - nwritten);
- else
- tuplen = inv_wrold(obj_desc, buf, nbytes - nwritten, htup, b);
+ if (!(obj_desc->flags & IFS_WRLOCK))
+ {
+ RelationSetLockForRead(obj_desc->heap_r);
+ obj_desc->flags |= (IFS_WRLOCK | IFS_RDLOCK);
}
- /* move pointers past the amount we just wrote */
- buf += tuplen;
- nwritten += tuplen;
- obj_desc->offset += tuplen;
- }
+ nwritten = 0;
+
+ /* write a block at a time */
+ while (nwritten < nbytes)
+ {
+
+ /*
+ * Fetch the current inversion file system block. If the class
+ * storing the inversion file is empty, we don't want to do an
+ * index lookup, since index lookups choke on empty files (should
+ * be fixed someday).
+ */
+
+ if ((obj_desc->flags & IFS_ATEOF)
+ || obj_desc->heap_r->rd_nblocks == 0)
+ htup = (HeapTuple) NULL;
+ else
+ htup = inv_fetchtup(obj_desc, &b);
+
+ /* either append or replace a block, as required */
+ if (!HeapTupleIsValid(htup))
+ {
+ tuplen = inv_wrnew(obj_desc, buf, nbytes - nwritten);
+ }
+ else
+ {
+ if (obj_desc->offset > obj_desc->highbyte)
+ tuplen = inv_wrnew(obj_desc, buf, nbytes - nwritten);
+ else
+ tuplen = inv_wrold(obj_desc, buf, nbytes - nwritten, htup, b);
+ }
+
+ /* move pointers past the amount we just wrote */
+ buf += tuplen;
+ nwritten += tuplen;
+ obj_desc->offset += tuplen;
+ }
- /* that's it */
- return (nwritten);
+ /* that's it */
+ return (nwritten);
}
/*
- * inv_fetchtup -- Fetch an inversion file system block.
+ * inv_fetchtup -- Fetch an inversion file system block.
*
- * This routine finds the file system block containing the offset
- * recorded in the obj_desc structure. Later, we need to think about
- * the effects of non-functional updates (can you rewrite the same
- * block twice in a single transaction?), but for now, we won't bother.
+ * This routine finds the file system block containing the offset
+ * recorded in the obj_desc structure. Later, we need to think about
+ * the effects of non-functional updates (can you rewrite the same
+ * block twice in a single transaction?), but for now, we won't bother.
*
- * Parameters:
- * obj_desc -- the object descriptor.
- * bufP -- pointer to a buffer in the buffer cache; caller
- * must free this.
+ * Parameters:
+ * obj_desc -- the object descriptor.
+ * bufP -- pointer to a buffer in the buffer cache; caller
+ * must free this.
*
- * Returns:
- * A heap tuple containing the desired block, or NULL if no
- * such tuple exists.
+ * Returns:
+ * A heap tuple containing the desired block, or NULL if no
+ * such tuple exists.
*/
-static HeapTuple
-inv_fetchtup(LargeObjectDesc *obj_desc, Buffer *bufP)
+static HeapTuple
+inv_fetchtup(LargeObjectDesc * obj_desc, Buffer * bufP)
{
- HeapTuple htup;
- RetrieveIndexResult res;
- Datum d;
- int firstbyte, lastbyte;
- struct varlena *fsblock;
- bool isNull;
-
- /*
- * If we've exhausted the current block, we need to get the next one.
- * When we support time travel and non-functional updates, we will
- * need to loop over the blocks, rather than just have an 'if', in
- * order to find the one we're really interested in.
- */
-
- if (obj_desc->offset > obj_desc->highbyte
- || obj_desc->offset < obj_desc->lowbyte
- || !ItemPointerIsValid(&(obj_desc->htid))) {
-
- /* initialize scan key if not done */
- if (obj_desc->iscan==(IndexScanDesc)NULL) {
- ScanKeyData skey;
-
- ScanKeyEntryInitialize(&skey, 0x0, 1, INT4GE_PROC_OID,
- Int32GetDatum(0));
- obj_desc->iscan =
- index_beginscan(obj_desc->index_r,
- (bool) 0, (uint16) 1,
- &skey);
- }
+ HeapTuple htup;
+ RetrieveIndexResult res;
+ Datum d;
+ int firstbyte,
+ lastbyte;
+ struct varlena *fsblock;
+ bool isNull;
- do {
- res = index_getnext(obj_desc->iscan, ForwardScanDirection);
+ /*
+ * If we've exhausted the current block, we need to get the next one.
+ * When we support time travel and non-functional updates, we will
+ * need to loop over the blocks, rather than just have an 'if', in
+ * order to find the one we're really interested in.
+ */
+
+ if (obj_desc->offset > obj_desc->highbyte
+ || obj_desc->offset < obj_desc->lowbyte
+ || !ItemPointerIsValid(&(obj_desc->htid)))
+ {
- if (res == (RetrieveIndexResult) NULL) {
- ItemPointerSetInvalid(&(obj_desc->htid));
- return ((HeapTuple) NULL);
- }
+ /* initialize scan key if not done */
+ if (obj_desc->iscan == (IndexScanDesc) NULL)
+ {
+ ScanKeyData skey;
- /*
- * For time travel, we need to use the actual time qual here,
- * rather that NowTimeQual. We currently have no way to pass
- * a time qual in.
- */
+ ScanKeyEntryInitialize(&skey, 0x0, 1, INT4GE_PROC_OID,
+ Int32GetDatum(0));
+ obj_desc->iscan =
+ index_beginscan(obj_desc->index_r,
+ (bool) 0, (uint16) 1,
+ &skey);
+ }
- htup = heap_fetch(obj_desc->heap_r, NowTimeQual,
- &(res->heap_iptr), bufP);
+ do
+ {
+ res = index_getnext(obj_desc->iscan, ForwardScanDirection);
- } while (htup == (HeapTuple) NULL);
+ if (res == (RetrieveIndexResult) NULL)
+ {
+ ItemPointerSetInvalid(&(obj_desc->htid));
+ return ((HeapTuple) NULL);
+ }
- /* remember this tid -- we may need it for later reads/writes */
- ItemPointerCopy(&(res->heap_iptr), &(obj_desc->htid));
+ /*
+ * For time travel, we need to use the actual time qual here,
+ * rather that NowTimeQual. We currently have no way to pass
+ * a time qual in.
+ */
- } else {
- htup = heap_fetch(obj_desc->heap_r, NowTimeQual,
- &(obj_desc->htid), bufP);
- }
+ htup = heap_fetch(obj_desc->heap_r, NowTimeQual,
+ &(res->heap_iptr), bufP);
- /*
- * By here, we have the heap tuple we're interested in. We cache
- * the upper and lower bounds for this block in the object descriptor
- * and return the tuple.
- */
+ } while (htup == (HeapTuple) NULL);
+
+ /* remember this tid -- we may need it for later reads/writes */
+ ItemPointerCopy(&(res->heap_iptr), &(obj_desc->htid));
+
+ }
+ else
+ {
+ htup = heap_fetch(obj_desc->heap_r, NowTimeQual,
+ &(obj_desc->htid), bufP);
+ }
+
+ /*
+ * By here, we have the heap tuple we're interested in. We cache the
+ * upper and lower bounds for this block in the object descriptor and
+ * return the tuple.
+ */
- d = (Datum)heap_getattr(htup, *bufP, 1, obj_desc->hdesc, &isNull);
- lastbyte = (int32) DatumGetInt32(d);
- d = (Datum)heap_getattr(htup, *bufP, 2, obj_desc->hdesc, &isNull);
- fsblock = (struct varlena *) DatumGetPointer(d);
+ d = (Datum) heap_getattr(htup, *bufP, 1, obj_desc->hdesc, &isNull);
+ lastbyte = (int32) DatumGetInt32(d);
+ d = (Datum) heap_getattr(htup, *bufP, 2, obj_desc->hdesc, &isNull);
+ fsblock = (struct varlena *) DatumGetPointer(d);
- /* order of + and - is important -- these are unsigned quantites near 0 */
- firstbyte = (lastbyte + 1 + sizeof(fsblock->vl_len)) - fsblock->vl_len;
+ /*
+ * order of + and - is important -- these are unsigned quantites near
+ * 0
+ */
+ firstbyte = (lastbyte + 1 + sizeof(fsblock->vl_len)) - fsblock->vl_len;
- obj_desc->lowbyte = firstbyte;
- obj_desc->highbyte = lastbyte;
+ obj_desc->lowbyte = firstbyte;
+ obj_desc->highbyte = lastbyte;
- /* done */
- return (htup);
+ /* done */
+ return (htup);
}
/*
- * inv_wrnew() -- append a new filesystem block tuple to the inversion
- * file.
+ * inv_wrnew() -- append a new filesystem block tuple to the inversion
+ * file.
*
- * In response to an inv_write, we append one or more file system
- * blocks to the class containing the large object. We violate the
- * class abstraction here in order to pack things as densely as we
- * are able. We examine the last page in the relation, and write
- * just enough to fill it, assuming that it has above a certain
- * threshold of space available. If the space available is less than
- * the threshold, we allocate a new page by writing a big tuple.
+ * In response to an inv_write, we append one or more file system
+ * blocks to the class containing the large object. We violate the
+ * class abstraction here in order to pack things as densely as we
+ * are able. We examine the last page in the relation, and write
+ * just enough to fill it, assuming that it has above a certain
+ * threshold of space available. If the space available is less than
+ * the threshold, we allocate a new page by writing a big tuple.
*
- * By the time we get here, we know all the parameters passed in
- * are valid, and that we hold the appropriate lock on the heap
- * relation.
+ * By the time we get here, we know all the parameters passed in
+ * are valid, and that we hold the appropriate lock on the heap
+ * relation.
*
- * Parameters:
- * obj_desc: large object descriptor for which to append block.
- * buf: buffer containing data to write.
- * nbytes: amount to write
+ * Parameters:
+ * obj_desc: large object descriptor for which to append block.
+ * buf: buffer containing data to write.
+ * nbytes: amount to write
*
- * Returns:
- * number of bytes actually written to the new tuple.
+ * Returns:
+ * number of bytes actually written to the new tuple.
*/
static int
-inv_wrnew(LargeObjectDesc *obj_desc, char *buf, int nbytes)
+inv_wrnew(LargeObjectDesc * obj_desc, char *buf, int nbytes)
{
- Relation hr;
- HeapTuple ntup;
- Buffer buffer;
- Page page;
- int nblocks;
- int nwritten;
-
- hr = obj_desc->heap_r;
-
- /*
- * Get the last block in the relation. If there's no data in the
- * relation at all, then we just get a new block. Otherwise, we
- * check the last block to see whether it has room to accept some
- * or all of the data that the user wants to write. If it doesn't,
- * then we allocate a new block.
- */
-
- nblocks = RelationGetNumberOfBlocks(hr);
-
- if (nblocks > 0)
- buffer = ReadBuffer(hr, nblocks - 1);
- else
- buffer = ReadBuffer(hr, P_NEW);
-
- page = BufferGetPage(buffer);
-
- /*
- * If the last page is too small to hold all the data, and it's too
- * small to hold IMINBLK, then we allocate a new page. If it will
- * hold at least IMINBLK, but less than all the data requested, then
- * we write IMINBLK here. The caller is responsible for noticing that
- * less than the requested number of bytes were written, and calling
- * this routine again.
- */
-
- nwritten = IFREESPC(page);
- if (nwritten < nbytes) {
- if (nwritten < IMINBLK) {
- ReleaseBuffer(buffer);
- buffer = ReadBuffer(hr, P_NEW);
- page = BufferGetPage(buffer);
- PageInit(page, BufferGetPageSize(buffer), 0);
- if (nbytes > IMAXBLK)
- nwritten = IMAXBLK;
- else
+ Relation hr;
+ HeapTuple ntup;
+ Buffer buffer;
+ Page page;
+ int nblocks;
+ int nwritten;
+
+ hr = obj_desc->heap_r;
+
+ /*
+ * Get the last block in the relation. If there's no data in the
+ * relation at all, then we just get a new block. Otherwise, we check
+ * the last block to see whether it has room to accept some or all of
+ * the data that the user wants to write. If it doesn't, then we
+ * allocate a new block.
+ */
+
+ nblocks = RelationGetNumberOfBlocks(hr);
+
+ if (nblocks > 0)
+ buffer = ReadBuffer(hr, nblocks - 1);
+ else
+ buffer = ReadBuffer(hr, P_NEW);
+
+ page = BufferGetPage(buffer);
+
+ /*
+ * If the last page is too small to hold all the data, and it's too
+ * small to hold IMINBLK, then we allocate a new page. If it will
+ * hold at least IMINBLK, but less than all the data requested, then
+ * we write IMINBLK here. The caller is responsible for noticing that
+ * less than the requested number of bytes were written, and calling
+ * this routine again.
+ */
+
+ nwritten = IFREESPC(page);
+ if (nwritten < nbytes)
+ {
+ if (nwritten < IMINBLK)
+ {
+ ReleaseBuffer(buffer);
+ buffer = ReadBuffer(hr, P_NEW);
+ page = BufferGetPage(buffer);
+ PageInit(page, BufferGetPageSize(buffer), 0);
+ if (nbytes > IMAXBLK)
+ nwritten = IMAXBLK;
+ else
+ nwritten = nbytes;
+ }
+ }
+ else
+ {
nwritten = nbytes;
}
- } else {
- nwritten = nbytes;
- }
- /*
- * Insert a new file system block tuple, index it, and write it out.
- */
+ /*
+ * Insert a new file system block tuple, index it, and write it out.
+ */
- ntup = inv_newtuple(obj_desc, buffer, page, buf, nwritten);
- inv_indextup(obj_desc, ntup);
+ ntup = inv_newtuple(obj_desc, buffer, page, buf, nwritten);
+ inv_indextup(obj_desc, ntup);
- /* new tuple is inserted */
- WriteBuffer(buffer);
+ /* new tuple is inserted */
+ WriteBuffer(buffer);
- return (nwritten);
+ return (nwritten);
}
static int
-inv_wrold(LargeObjectDesc *obj_desc,
- char *dbuf,
- int nbytes,
- HeapTuple htup,
- Buffer buffer)
+inv_wrold(LargeObjectDesc * obj_desc,
+ char *dbuf,
+ int nbytes,
+ HeapTuple htup,
+ Buffer buffer)
{
- Relation hr;
- HeapTuple ntup;
- Buffer newbuf;
- Page page;
- Page newpage;
- int tupbytes;
- Datum d;
- struct varlena *fsblock;
- int nwritten, nblocks, freespc;
- bool isNull;
- int keep_offset;
-
- /*
- * Since we're using a no-overwrite storage manager, the way we
- * overwrite blocks is to mark the old block invalid and append
- * a new block. First mark the old block invalid. This violates
- * the tuple abstraction.
- */
-
- TransactionIdStore(GetCurrentTransactionId(), &(htup->t_xmax));
- htup->t_cmax = GetCurrentCommandId();
-
- /*
- * If we're overwriting the entire block, we're lucky. All we need
- * to do is to insert a new block.
- */
-
- if (obj_desc->offset == obj_desc->lowbyte
- && obj_desc->lowbyte + nbytes >= obj_desc->highbyte) {
- WriteBuffer(buffer);
- return (inv_wrnew(obj_desc, dbuf, nbytes));
- }
-
- /*
- * By here, we need to overwrite part of the data in the current
- * tuple. In order to reduce the degree to which we fragment blocks,
- * we guarantee that no block will be broken up due to an overwrite.
- * This means that we need to allocate a tuple on a new page, if
- * there's not room for the replacement on this one.
- */
-
- newbuf = buffer;
- page = BufferGetPage(buffer);
- newpage = BufferGetPage(newbuf);
- hr = obj_desc->heap_r;
- freespc = IFREESPC(page);
- d = (Datum)heap_getattr(htup, buffer, 2, obj_desc->hdesc, &isNull);
- fsblock = (struct varlena *) DatumGetPointer(d);
- tupbytes = fsblock->vl_len - sizeof(fsblock->vl_len);
-
- if (freespc < tupbytes) {
+ Relation hr;
+ HeapTuple ntup;
+ Buffer newbuf;
+ Page page;
+ Page newpage;
+ int tupbytes;
+ Datum d;
+ struct varlena *fsblock;
+ int nwritten,
+ nblocks,
+ freespc;
+ bool isNull;
+ int keep_offset;
/*
- * First see if there's enough space on the last page of the
- * table to put this tuple.
+ * Since we're using a no-overwrite storage manager, the way we
+ * overwrite blocks is to mark the old block invalid and append a new
+ * block. First mark the old block invalid. This violates the tuple
+ * abstraction.
*/
- nblocks = RelationGetNumberOfBlocks(hr);
+ TransactionIdStore(GetCurrentTransactionId(), &(htup->t_xmax));
+ htup->t_cmax = GetCurrentCommandId();
- if (nblocks > 0)
- newbuf = ReadBuffer(hr, nblocks - 1);
- else
- newbuf = ReadBuffer(hr, P_NEW);
+ /*
+ * If we're overwriting the entire block, we're lucky. All we need to
+ * do is to insert a new block.
+ */
- newpage = BufferGetPage(newbuf);
- freespc = IFREESPC(newpage);
+ if (obj_desc->offset == obj_desc->lowbyte
+ && obj_desc->lowbyte + nbytes >= obj_desc->highbyte)
+ {
+ WriteBuffer(buffer);
+ return (inv_wrnew(obj_desc, dbuf, nbytes));
+ }
/*
- * If there's no room on the last page, allocate a new last
- * page for the table, and put it there.
+ * By here, we need to overwrite part of the data in the current
+ * tuple. In order to reduce the degree to which we fragment blocks,
+ * we guarantee that no block will be broken up due to an overwrite.
+ * This means that we need to allocate a tuple on a new page, if
+ * there's not room for the replacement on this one.
*/
- if (freespc < tupbytes) {
- ReleaseBuffer(newbuf);
- newbuf = ReadBuffer(hr, P_NEW);
- newpage = BufferGetPage(newbuf);
- PageInit(newpage, BufferGetPageSize(newbuf), 0);
+ newbuf = buffer;
+ page = BufferGetPage(buffer);
+ newpage = BufferGetPage(newbuf);
+ hr = obj_desc->heap_r;
+ freespc = IFREESPC(page);
+ d = (Datum) heap_getattr(htup, buffer, 2, obj_desc->hdesc, &isNull);
+ fsblock = (struct varlena *) DatumGetPointer(d);
+ tupbytes = fsblock->vl_len - sizeof(fsblock->vl_len);
+
+ if (freespc < tupbytes)
+ {
+
+ /*
+ * First see if there's enough space on the last page of the table
+ * to put this tuple.
+ */
+
+ nblocks = RelationGetNumberOfBlocks(hr);
+
+ if (nblocks > 0)
+ newbuf = ReadBuffer(hr, nblocks - 1);
+ else
+ newbuf = ReadBuffer(hr, P_NEW);
+
+ newpage = BufferGetPage(newbuf);
+ freespc = IFREESPC(newpage);
+
+ /*
+ * If there's no room on the last page, allocate a new last page
+ * for the table, and put it there.
+ */
+
+ if (freespc < tupbytes)
+ {
+ ReleaseBuffer(newbuf);
+ newbuf = ReadBuffer(hr, P_NEW);
+ newpage = BufferGetPage(newbuf);
+ PageInit(newpage, BufferGetPageSize(newbuf), 0);
+ }
}
- }
-
- nwritten = nbytes;
- if (nwritten > obj_desc->highbyte - obj_desc->offset + 1)
- nwritten = obj_desc->highbyte - obj_desc->offset + 1;
- memmove(VARDATA(fsblock)+ (obj_desc->offset - obj_desc->lowbyte),
- dbuf,nwritten);
- /* we are rewriting the entire old block, therefore
- we reset offset to the lowbyte of the original block
- before jumping into inv_newtuple() */
- keep_offset = obj_desc->offset;
- obj_desc->offset = obj_desc->lowbyte;
- ntup = inv_newtuple(obj_desc, newbuf, newpage, VARDATA(fsblock),
- tupbytes);
- /* after we are done, we restore to the true offset */
- obj_desc->offset = keep_offset;
-
- /*
- * By here, we have a page (newpage) that's guaranteed to have
- * enough space on it to put the new tuple. Call inv_newtuple
- * to do the work. Passing NULL as a buffer to inv_newtuple()
- * keeps it from copying any data into the new tuple. When it
- * returns, the tuple is ready to receive data from the old
- * tuple and the user's data buffer.
- */
-/*
- ntup = inv_newtuple(obj_desc, newbuf, newpage, (char *) NULL, tupbytes);
- dptr = ((char *) ntup) + ntup->t_hoff - sizeof(ntup->t_bits) + sizeof(int4)
- + sizeof(fsblock->vl_len);
- if (obj_desc->offset > obj_desc->lowbyte) {
- memmove(dptr,
- &(fsblock->vl_dat[0]),
- obj_desc->offset - obj_desc->lowbyte);
- dptr += obj_desc->offset - obj_desc->lowbyte;
- }
+ nwritten = nbytes;
+ if (nwritten > obj_desc->highbyte - obj_desc->offset + 1)
+ nwritten = obj_desc->highbyte - obj_desc->offset + 1;
+ memmove(VARDATA(fsblock) + (obj_desc->offset - obj_desc->lowbyte),
+ dbuf, nwritten);
+
+ /*
+ * we are rewriting the entire old block, therefore we reset offset to
+ * the lowbyte of the original block before jumping into
+ * inv_newtuple()
+ */
+ keep_offset = obj_desc->offset;
+ obj_desc->offset = obj_desc->lowbyte;
+ ntup = inv_newtuple(obj_desc, newbuf, newpage, VARDATA(fsblock),
+ tupbytes);
+ /* after we are done, we restore to the true offset */
+ obj_desc->offset = keep_offset;
+
+ /*
+ * By here, we have a page (newpage) that's guaranteed to have enough
+ * space on it to put the new tuple. Call inv_newtuple to do the
+ * work. Passing NULL as a buffer to inv_newtuple() keeps it from
+ * copying any data into the new tuple. When it returns, the tuple is
+ * ready to receive data from the old tuple and the user's data
+ * buffer.
+ */
+/*
+ ntup = inv_newtuple(obj_desc, newbuf, newpage, (char *) NULL, tupbytes);
+ dptr = ((char *) ntup) + ntup->t_hoff - sizeof(ntup->t_bits) + sizeof(int4)
+ + sizeof(fsblock->vl_len);
+
+ if (obj_desc->offset > obj_desc->lowbyte) {
+ memmove(dptr,
+ &(fsblock->vl_dat[0]),
+ obj_desc->offset - obj_desc->lowbyte);
+ dptr += obj_desc->offset - obj_desc->lowbyte;
+ }
- nwritten = nbytes;
- if (nwritten > obj_desc->highbyte - obj_desc->offset + 1)
- nwritten = obj_desc->highbyte - obj_desc->offset + 1;
+ nwritten = nbytes;
+ if (nwritten > obj_desc->highbyte - obj_desc->offset + 1)
+ nwritten = obj_desc->highbyte - obj_desc->offset + 1;
- memmove(dptr, dbuf, nwritten);
- dptr += nwritten;
+ memmove(dptr, dbuf, nwritten);
+ dptr += nwritten;
- if (obj_desc->offset + nwritten < obj_desc->highbyte + 1) {
+ if (obj_desc->offset + nwritten < obj_desc->highbyte + 1) {
*/
/*
- loc = (obj_desc->highbyte - obj_desc->offset)
- + nwritten;
- sz = obj_desc->highbyte - (obj_desc->lowbyte + loc);
+ loc = (obj_desc->highbyte - obj_desc->offset)
+ + nwritten;
+ sz = obj_desc->highbyte - (obj_desc->lowbyte + loc);
- what's going on here?? - jolly
+ what's going on here?? - jolly
*/
/*
- sz = (obj_desc->highbyte + 1) - (obj_desc->offset + nwritten);
- memmove(&(fsblock->vl_dat[0]), dptr, sz);
- }
+ sz = (obj_desc->highbyte + 1) - (obj_desc->offset + nwritten);
+ memmove(&(fsblock->vl_dat[0]), dptr, sz);
+ }
*/
- /* index the new tuple */
- inv_indextup(obj_desc, ntup);
+ /* index the new tuple */
+ inv_indextup(obj_desc, ntup);
- /* move the scandesc forward so we don't reread the newly inserted
- tuple on the next index scan */
- if (obj_desc->iscan)
- index_getnext(obj_desc->iscan, ForwardScanDirection);
+ /*
+ * move the scandesc forward so we don't reread the newly inserted
+ * tuple on the next index scan
+ */
+ if (obj_desc->iscan)
+ index_getnext(obj_desc->iscan, ForwardScanDirection);
- /*
- * Okay, by here, a tuple for the new block is correctly placed,
- * indexed, and filled. Write the changed pages out.
- */
+ /*
+ * Okay, by here, a tuple for the new block is correctly placed,
+ * indexed, and filled. Write the changed pages out.
+ */
- WriteBuffer(buffer);
- if (newbuf != buffer)
- WriteBuffer(newbuf);
+ WriteBuffer(buffer);
+ if (newbuf != buffer)
+ WriteBuffer(newbuf);
- /* done */
- return (nwritten);
+ /* done */
+ return (nwritten);
}
-static HeapTuple
-inv_newtuple(LargeObjectDesc *obj_desc,
- Buffer buffer,
- Page page,
- char *dbuf,
- int nwrite)
+static HeapTuple
+inv_newtuple(LargeObjectDesc * obj_desc,
+ Buffer buffer,
+ Page page,
+ char *dbuf,
+ int nwrite)
{
- HeapTuple ntup;
- PageHeader ph;
- int tupsize;
- int hoff;
- Offset lower;
- Offset upper;
- ItemId itemId;
- OffsetNumber off;
- OffsetNumber limit;
- char *attptr;
-
- /* compute tuple size -- no nulls */
- hoff = sizeof(HeapTupleData) - sizeof(ntup->t_bits);
-
- /* add in olastbyte, varlena.vl_len, varlena.vl_dat */
- tupsize = hoff + (2 * sizeof(int32)) + nwrite;
- tupsize = LONGALIGN(tupsize);
-
- /*
- * Allocate the tuple on the page, violating the page abstraction.
- * This code was swiped from PageAddItem().
- */
-
- ph = (PageHeader) page;
- limit = OffsetNumberNext(PageGetMaxOffsetNumber(page));
-
- /* look for "recyclable" (unused & deallocated) ItemId */
- for (off = FirstOffsetNumber; off < limit; off = OffsetNumberNext(off)) {
+ HeapTuple ntup;
+ PageHeader ph;
+ int tupsize;
+ int hoff;
+ Offset lower;
+ Offset upper;
+ ItemId itemId;
+ OffsetNumber off;
+ OffsetNumber limit;
+ char *attptr;
+
+ /* compute tuple size -- no nulls */
+ hoff = sizeof(HeapTupleData) - sizeof(ntup->t_bits);
+
+ /* add in olastbyte, varlena.vl_len, varlena.vl_dat */
+ tupsize = hoff + (2 * sizeof(int32)) + nwrite;
+ tupsize = LONGALIGN(tupsize);
+
+ /*
+ * Allocate the tuple on the page, violating the page abstraction.
+ * This code was swiped from PageAddItem().
+ */
+
+ ph = (PageHeader) page;
+ limit = OffsetNumberNext(PageGetMaxOffsetNumber(page));
+
+ /* look for "recyclable" (unused & deallocated) ItemId */
+ for (off = FirstOffsetNumber; off < limit; off = OffsetNumberNext(off))
+ {
+ itemId = &ph->pd_linp[off - 1];
+ if ((((*itemId).lp_flags & LP_USED) == 0) &&
+ ((*itemId).lp_len == 0))
+ break;
+ }
+
+ if (off > limit)
+ lower = (Offset) (((char *) (&ph->pd_linp[off])) - ((char *) page));
+ else if (off == limit)
+ lower = ph->pd_lower + sizeof(ItemIdData);
+ else
+ lower = ph->pd_lower;
+
+ upper = ph->pd_upper - tupsize;
+
itemId = &ph->pd_linp[off - 1];
- if ((((*itemId).lp_flags & LP_USED) == 0) &&
- ((*itemId).lp_len == 0))
- break;
- }
-
- if (off > limit)
- lower = (Offset) (((char *) (&ph->pd_linp[off])) - ((char *) page));
- else if (off == limit)
- lower = ph->pd_lower + sizeof (ItemIdData);
- else
- lower = ph->pd_lower;
-
- upper = ph->pd_upper - tupsize;
-
- itemId = &ph->pd_linp[off - 1];
- (*itemId).lp_off = upper;
- (*itemId).lp_len = tupsize;
- (*itemId).lp_flags = LP_USED;
- ph->pd_lower = lower;
- ph->pd_upper = upper;
-
- ntup = (HeapTuple) ((char *) page + upper);
-
- /*
- * Tuple is now allocated on the page. Next, fill in the tuple
- * header. This block of code violates the tuple abstraction.
- */
-
- ntup->t_len = tupsize;
- ItemPointerSet(&(ntup->t_ctid), BufferGetBlockNumber(buffer), off);
- ItemPointerSetInvalid(&(ntup->t_chain));
- LastOidProcessed = ntup->t_oid = newoid();
- TransactionIdStore(GetCurrentTransactionId(), &(ntup->t_xmin));
- ntup->t_cmin = GetCurrentCommandId();
- StoreInvalidTransactionId(&(ntup->t_xmax));
- ntup->t_cmax = 0;
- ntup->t_tmin = INVALID_ABSTIME;
- ntup->t_tmax = CURRENT_ABSTIME;
- ntup->t_natts = 2;
- ntup->t_hoff = hoff;
- ntup->t_vtype = 0;
- ntup->t_infomask = 0x0;
-
- /* if a NULL is passed in, avoid the calculations below */
- if (dbuf == NULL)
- return ntup;
-
- /*
- * Finally, copy the user's data buffer into the tuple. This violates
- * the tuple and class abstractions.
- */
-
- attptr = ((char *) ntup) + hoff;
- *((int32 *) attptr) = obj_desc->offset + nwrite - 1;
- attptr += sizeof(int32);
-
- /*
- ** mer fixed disk layout of varlenas to get rid of the need for this.
- **
- ** *((int32 *) attptr) = nwrite + sizeof(int32);
- ** attptr += sizeof(int32);
- */
-
- *((int32 *) attptr) = nwrite + sizeof(int32);
- attptr += sizeof(int32);
-
- /*
- * If a data buffer was passed in, then copy the data from the buffer
- * to the tuple. Some callers (eg, inv_wrold()) may not pass in a
- * buffer, since they have to copy part of the old tuple data and
- * part of the user's new data into the new tuple.
- */
-
- if (dbuf != (char *) NULL)
- memmove(attptr, dbuf, nwrite);
-
- /* keep track of boundary of current tuple */
- obj_desc->lowbyte = obj_desc->offset;
- obj_desc->highbyte = obj_desc->offset + nwrite - 1;
-
- /* new tuple is filled -- return it */
- return (ntup);
+ (*itemId).lp_off = upper;
+ (*itemId).lp_len = tupsize;
+ (*itemId).lp_flags = LP_USED;
+ ph->pd_lower = lower;
+ ph->pd_upper = upper;
+
+ ntup = (HeapTuple) ((char *) page + upper);
+
+ /*
+ * Tuple is now allocated on the page. Next, fill in the tuple
+ * header. This block of code violates the tuple abstraction.
+ */
+
+ ntup->t_len = tupsize;
+ ItemPointerSet(&(ntup->t_ctid), BufferGetBlockNumber(buffer), off);
+ ItemPointerSetInvalid(&(ntup->t_chain));
+ LastOidProcessed = ntup->t_oid = newoid();
+ TransactionIdStore(GetCurrentTransactionId(), &(ntup->t_xmin));
+ ntup->t_cmin = GetCurrentCommandId();
+ StoreInvalidTransactionId(&(ntup->t_xmax));
+ ntup->t_cmax = 0;
+ ntup->t_tmin = INVALID_ABSTIME;
+ ntup->t_tmax = CURRENT_ABSTIME;
+ ntup->t_natts = 2;
+ ntup->t_hoff = hoff;
+ ntup->t_vtype = 0;
+ ntup->t_infomask = 0x0;
+
+ /* if a NULL is passed in, avoid the calculations below */
+ if (dbuf == NULL)
+ return ntup;
+
+ /*
+ * Finally, copy the user's data buffer into the tuple. This violates
+ * the tuple and class abstractions.
+ */
+
+ attptr = ((char *) ntup) + hoff;
+ *((int32 *) attptr) = obj_desc->offset + nwrite - 1;
+ attptr += sizeof(int32);
+
+ /*
+ * * mer fixed disk layout of varlenas to get rid of the need for
+ * this. *
+ *
+ * *((int32 *) attptr) = nwrite + sizeof(int32); * attptr +=
+ * sizeof(int32);
+ */
+
+ *((int32 *) attptr) = nwrite + sizeof(int32);
+ attptr += sizeof(int32);
+
+ /*
+ * If a data buffer was passed in, then copy the data from the buffer
+ * to the tuple. Some callers (eg, inv_wrold()) may not pass in a
+ * buffer, since they have to copy part of the old tuple data and part
+ * of the user's new data into the new tuple.
+ */
+
+ if (dbuf != (char *) NULL)
+ memmove(attptr, dbuf, nwrite);
+
+ /* keep track of boundary of current tuple */
+ obj_desc->lowbyte = obj_desc->offset;
+ obj_desc->highbyte = obj_desc->offset + nwrite - 1;
+
+ /* new tuple is filled -- return it */
+ return (ntup);
}
static void
-inv_indextup(LargeObjectDesc *obj_desc, HeapTuple htup)
+inv_indextup(LargeObjectDesc * obj_desc, HeapTuple htup)
{
- InsertIndexResult res;
- Datum v[1];
- char n[1];
+ InsertIndexResult res;
+ Datum v[1];
+ char n[1];
- n[0] = ' ';
- v[0] = Int32GetDatum(obj_desc->highbyte);
- res = index_insert(obj_desc->index_r, &v[0], &n[0],
- &(htup->t_ctid), obj_desc->heap_r);
+ n[0] = ' ';
+ v[0] = Int32GetDatum(obj_desc->highbyte);
+ res = index_insert(obj_desc->index_r, &v[0], &n[0],
+ &(htup->t_ctid), obj_desc->heap_r);
- if (res)
- pfree(res);
+ if (res)
+ pfree(res);
}
/*
static void
DumpPage(Page page, int blkno)
{
- ItemId lp;
- HeapTuple tup;
- int flags, i, nline;
- ItemPointerData pointerData;
+ ItemId lp;
+ HeapTuple tup;
+ int flags, i, nline;
+ ItemPointerData pointerData;
+
+ printf("\t[subblock=%d]:lower=%d:upper=%d:special=%d\n", 0,
+ ((PageHeader)page)->pd_lower, ((PageHeader)page)->pd_upper,
+ ((PageHeader)page)->pd_special);
- printf("\t[subblock=%d]:lower=%d:upper=%d:special=%d\n", 0,
- ((PageHeader)page)->pd_lower, ((PageHeader)page)->pd_upper,
- ((PageHeader)page)->pd_special);
+ printf("\t:MaxOffsetNumber=%d\n",
+ (int16) PageGetMaxOffsetNumber(page));
- printf("\t:MaxOffsetNumber=%d\n",
- (int16) PageGetMaxOffsetNumber(page));
-
- nline = (int16) PageGetMaxOffsetNumber(page);
+ nline = (int16) PageGetMaxOffsetNumber(page);
{
- int i;
- char *cp;
+ int i;
+ char *cp;
- i = PageGetSpecialSize(page);
- cp = PageGetSpecialPointer(page);
+ i = PageGetSpecialSize(page);
+ cp = PageGetSpecialPointer(page);
- printf("\t:SpecialData=");
+ printf("\t:SpecialData=");
- while (i > 0) {
- printf(" 0x%02x", *cp);
- cp += 1;
- i -= 1;
- }
- printf("\n");
+ while (i > 0) {
+ printf(" 0x%02x", *cp);
+ cp += 1;
+ i -= 1;
+ }
+ printf("\n");
}
- for (i = 0; i < nline; i++) {
- lp = ((PageHeader)page)->pd_linp + i;
- flags = (*lp).lp_flags;
- ItemPointerSet(&pointerData, blkno, 1 + i);
- printf("%s:off=%d:flags=0x%x:len=%d",
- ItemPointerFormExternal(&pointerData), (*lp).lp_off,
- flags, (*lp).lp_len);
+ for (i = 0; i < nline; i++) {
+ lp = ((PageHeader)page)->pd_linp + i;
+ flags = (*lp).lp_flags;
+ ItemPointerSet(&pointerData, blkno, 1 + i);
+ printf("%s:off=%d:flags=0x%x:len=%d",
+ ItemPointerFormExternal(&pointerData), (*lp).lp_off,
+ flags, (*lp).lp_len);
- if (flags & LP_USED) {
- HeapTupleData htdata;
+ if (flags & LP_USED) {
+ HeapTupleData htdata;
- printf(":USED");
+ printf(":USED");
- memmove((char *) &htdata,
- (char *) &((char *)page)[(*lp).lp_off],
- sizeof(htdata));
+ memmove((char *) &htdata,
+ (char *) &((char *)page)[(*lp).lp_off],
+ sizeof(htdata));
- tup = &htdata;
+ tup = &htdata;
- printf("\n\t:ctid=%s:oid=%d",
- ItemPointerFormExternal(&tup->t_ctid),
- tup->t_oid);
- printf(":natts=%d:thoff=%d:vtype=`%c' (0x%02x):",
- tup->t_natts,
- tup->t_hoff, tup->t_vtype, tup->t_vtype);
+ printf("\n\t:ctid=%s:oid=%d",
+ ItemPointerFormExternal(&tup->t_ctid),
+ tup->t_oid);
+ printf(":natts=%d:thoff=%d:vtype=`%c' (0x%02x):",
+ tup->t_natts,
+ tup->t_hoff, tup->t_vtype, tup->t_vtype);
- printf("\n\t:tmin=%d:cmin=%u:",
- tup->t_tmin, tup->t_cmin);
+ printf("\n\t:tmin=%d:cmin=%u:",
+ tup->t_tmin, tup->t_cmin);
- printf("xmin=%u:", tup->t_xmin);
+ printf("xmin=%u:", tup->t_xmin);
- printf("\n\t:tmax=%d:cmax=%u:",
- tup->t_tmax, tup->t_cmax);
+ printf("\n\t:tmax=%d:cmax=%u:",
+ tup->t_tmax, tup->t_cmax);
- printf("xmax=%u:", tup->t_xmax);
+ printf("xmax=%u:", tup->t_xmax);
- printf("\n\t:chain=%s:\n",
- ItemPointerFormExternal(&tup->t_chain));
- } else
- putchar('\n');
- }
+ printf("\n\t:chain=%s:\n",
+ ItemPointerFormExternal(&tup->t_chain));
+ } else
+ putchar('\n');
+ }
}
static char*
ItemPointerFormExternal(ItemPointer pointer)
{
- static char itemPointerString[32];
-
- if (!ItemPointerIsValid(pointer)) {
- memmove(itemPointerString, "<-,-,->", sizeof "<-,-,->");
- } else {
- sprintf(itemPointerString, "<%u,%u>",
- ItemPointerGetBlockNumber(pointer),
- ItemPointerGetOffsetNumber(pointer));
- }
+ static char itemPointerString[32];
+
+ if (!ItemPointerIsValid(pointer)) {
+ memmove(itemPointerString, "<-,-,->", sizeof "<-,-,->");
+ } else {
+ sprintf(itemPointerString, "<%u,%u>",
+ ItemPointerGetBlockNumber(pointer),
+ ItemPointerGetOffsetNumber(pointer));
+ }
- return (itemPointerString);
+ return (itemPointerString);
}
*/
static int
_inv_getsize(Relation hreln, TupleDesc hdesc, Relation ireln)
{
- IndexScanDesc iscan;
- RetrieveIndexResult res;
- Buffer buf;
- HeapTuple htup;
- Datum d;
- long size;
- bool isNull;
+ IndexScanDesc iscan;
+ RetrieveIndexResult res;
+ Buffer buf;
+ HeapTuple htup;
+ Datum d;
+ long size;
+ bool isNull;
- /* scan backwards from end */
- iscan = index_beginscan(ireln, (bool) 1, 0, (ScanKey) NULL);
+ /* scan backwards from end */
+ iscan = index_beginscan(ireln, (bool) 1, 0, (ScanKey) NULL);
- buf = InvalidBuffer;
+ buf = InvalidBuffer;
- do {
- res = index_getnext(iscan, BackwardScanDirection);
+ do
+ {
+ res = index_getnext(iscan, BackwardScanDirection);
- /*
- * If there are no more index tuples, then the relation is empty,
- * so the file's size is zero.
- */
+ /*
+ * If there are no more index tuples, then the relation is empty,
+ * so the file's size is zero.
+ */
- if (res == (RetrieveIndexResult) NULL) {
- index_endscan(iscan);
- return (0);
- }
+ if (res == (RetrieveIndexResult) NULL)
+ {
+ index_endscan(iscan);
+ return (0);
+ }
- /*
- * For time travel, we need to use the actual time qual here,
- * rather that NowTimeQual. We currently have no way to pass
- * a time qual in.
- */
+ /*
+ * For time travel, we need to use the actual time qual here,
+ * rather that NowTimeQual. We currently have no way to pass a
+ * time qual in.
+ */
- if (buf != InvalidBuffer)
- ReleaseBuffer(buf);
+ if (buf != InvalidBuffer)
+ ReleaseBuffer(buf);
- htup = heap_fetch(hreln, NowTimeQual, &(res->heap_iptr), &buf);
+ htup = heap_fetch(hreln, NowTimeQual, &(res->heap_iptr), &buf);
- } while (!HeapTupleIsValid(htup));
+ } while (!HeapTupleIsValid(htup));
- /* don't need the index scan anymore */
- index_endscan(iscan);
+ /* don't need the index scan anymore */
+ index_endscan(iscan);
- /* get olastbyte attribute */
- d = (Datum) heap_getattr(htup, buf, 1, hdesc, &isNull);
- size = DatumGetInt32(d) + 1;
+ /* get olastbyte attribute */
+ d = (Datum) heap_getattr(htup, buf, 1, hdesc, &isNull);
+ size = DatumGetInt32(d) + 1;
- /* wei hates it if you forget to do this */
- ReleaseBuffer(buf);
+ /* wei hates it if you forget to do this */
+ ReleaseBuffer(buf);
- return (size);
+ return (size);
}
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 0f34f500596..555303fa14e 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -1,22 +1,22 @@
/*-------------------------------------------------------------------------
*
* lmgr.c--
- * POSTGRES lock manager code
+ * POSTGRES lock manager code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.5 1997/08/19 21:33:15 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.6 1997/09/07 04:48:51 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-/* #define LOCKDEBUGALL 1 */
+/* #define LOCKDEBUGALL 1 */
/* #define LOCKDEBUG 1 */
#ifdef LOCKDEBUGALL
-#define LOCKDEBUG 1
-#endif /* LOCKDEBUGALL */
+#define LOCKDEBUG 1
+#endif /* LOCKDEBUGALL */
#include <string.h>
@@ -46,239 +46,246 @@
#include "nodes/memnodes.h"
#include "storage/bufmgr.h"
-#include "access/transam.h" /* for AmiTransactionId */
+#include "access/transam.h" /* for AmiTransactionId */
-static void LRelIdAssign(LRelId *lRelId, Oid dbId, Oid relId);
+static void LRelIdAssign(LRelId * lRelId, Oid dbId, Oid relId);
/* ----------------
- *
+ *
* ----------------
*/
-#define MaxRetries 4 /* XXX about 1/4 minute--a hack */
+#define MaxRetries 4 /* XXX about 1/4 minute--a hack */
#define IntentReadRelationLock 0x0100
-#define ReadRelationLock 0x0200
-#define IntentWriteRelationLock 0x0400
-#define WriteRelationLock 0x0800
-#define IntentReadPageLock 0x1000
-#define ReadTupleLock 0x2000
+#define ReadRelationLock 0x0200
+#define IntentWriteRelationLock 0x0400
+#define WriteRelationLock 0x0800
+#define IntentReadPageLock 0x1000
+#define ReadTupleLock 0x2000
-#define TupleLevelLockCountMask 0x000f
+#define TupleLevelLockCountMask 0x000f
-#define TupleLevelLockLimit 10
+#define TupleLevelLockLimit 10
-extern Oid MyDatabaseId;
+extern Oid MyDatabaseId;
static LRelId VariableRelationLRelId = {
- RelOid_pg_variable,
- InvalidOid
+ RelOid_pg_variable,
+ InvalidOid
};
/* ----------------
- * RelationGetLRelId
+ * RelationGetLRelId
* ----------------
*/
#ifdef LOCKDEBUG
#define LOCKDEBUG_10 \
elog(NOTICE, "RelationGetLRelId(%s) invalid lockInfo", \
- RelationGetRelationName(relation));
+ RelationGetRelationName(relation));
#else
#define LOCKDEBUG_10
-#endif /* LOCKDEBUG */
-
+#endif /* LOCKDEBUG */
+
/*
* RelationGetLRelId --
- * Returns "lock" relation identifier for a relation.
+ * Returns "lock" relation identifier for a relation.
*/
LRelId
RelationGetLRelId(Relation relation)
{
- LockInfo linfo;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- linfo = (LockInfo) relation->lockInfo;
-
- /* ----------------
- * initialize lock info if necessary
- * ----------------
- */
- if (! LockInfoIsValid(linfo)) {
- LOCKDEBUG_10;
- RelationInitLockInfo(relation);
+ LockInfo linfo;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
linfo = (LockInfo) relation->lockInfo;
- }
-
- /* ----------------
- * XXX hack to prevent problems during
- * VARIABLE relation initialization
- * ----------------
- */
- if (strcmp(RelationGetRelationName(relation)->data,
- VariableRelationName) == 0) {
- return (VariableRelationLRelId);
- }
-
- return (linfo->lRelId);
+
+ /* ----------------
+ * initialize lock info if necessary
+ * ----------------
+ */
+ if (!LockInfoIsValid(linfo))
+ {
+ LOCKDEBUG_10;
+ RelationInitLockInfo(relation);
+ linfo = (LockInfo) relation->lockInfo;
+ }
+
+ /* ----------------
+ * XXX hack to prevent problems during
+ * VARIABLE relation initialization
+ * ----------------
+ */
+ if (strcmp(RelationGetRelationName(relation)->data,
+ VariableRelationName) == 0)
+ {
+ return (VariableRelationLRelId);
+ }
+
+ return (linfo->lRelId);
}
/*
* LRelIdGetDatabaseId --
- * Returns database identifier for a "lock" relation identifier.
+ * Returns database identifier for a "lock" relation identifier.
*/
/* ----------------
- * LRelIdGetDatabaseId
+ * LRelIdGetDatabaseId
*
* Note: The argument may not be correct, if it is not used soon
- * after it is created.
+ * after it is created.
* ----------------
*/
#ifdef NOT_USED
Oid
LRelIdGetDatabaseId(LRelId lRelId)
{
- return (lRelId.dbId);
+ return (lRelId.dbId);
}
+
#endif
/*
* LRelIdGetRelationId --
- * Returns relation identifier for a "lock" relation identifier.
+ * Returns relation identifier for a "lock" relation identifier.
*/
-Oid
+Oid
LRelIdGetRelationId(LRelId lRelId)
{
- return (lRelId.relId);
+ return (lRelId.relId);
}
/*
* DatabaseIdIsMyDatabaseId --
- * True iff database object identifier is valid in my present database.
+ * True iff database object identifier is valid in my present database.
*/
#ifdef NOT_USED
bool
DatabaseIdIsMyDatabaseId(Oid databaseId)
{
- return (bool)
- (!OidIsValid(databaseId) || databaseId == MyDatabaseId);
+ return (bool)
+ (!OidIsValid(databaseId) || databaseId == MyDatabaseId);
}
+
#endif
/*
* LRelIdContainsMyDatabaseId --
- * True iff "lock" relation identifier is valid in my present database.
+ * True iff "lock" relation identifier is valid in my present database.
*/
#ifdef NOT_USED
bool
LRelIdContainsMyDatabaseId(LRelId lRelId)
{
- return (bool)
- (!OidIsValid(lRelId.dbId) || lRelId.dbId == MyDatabaseId);
+ return (bool)
+ (!OidIsValid(lRelId.dbId) || lRelId.dbId == MyDatabaseId);
}
+
#endif
/*
* RelationInitLockInfo --
- * Initializes the lock information in a relation descriptor.
+ * Initializes the lock information in a relation descriptor.
*/
/* ----------------
- * RelationInitLockInfo
+ * RelationInitLockInfo
*
- * XXX processingVariable is a hack to prevent problems during
- * VARIABLE relation initialization.
+ * XXX processingVariable is a hack to prevent problems during
+ * VARIABLE relation initialization.
* ----------------
*/
void
RelationInitLockInfo(Relation relation)
{
- LockInfo info;
- char *relname;
- Oid relationid;
- bool processingVariable;
- extern Oid MyDatabaseId; /* XXX use include */
- extern GlobalMemory CacheCxt;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- Assert(OidIsValid(RelationGetRelationId(relation)));
-
- /* ----------------
- * get information from relation descriptor
- * ----------------
- */
- info = (LockInfo) relation->lockInfo;
- relname = (char *) RelationGetRelationName(relation);
- relationid = RelationGetRelationId(relation);
- processingVariable = (strcmp(relname, VariableRelationName) == 0);
-
- /* ----------------
- * create a new lockinfo if not already done
- * ----------------
- */
- if (! PointerIsValid(info))
+ LockInfo info;
+ char *relname;
+ Oid relationid;
+ bool processingVariable;
+ extern Oid MyDatabaseId; /* XXX use include */
+ extern GlobalMemory CacheCxt;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ Assert(OidIsValid(RelationGetRelationId(relation)));
+
+ /* ----------------
+ * get information from relation descriptor
+ * ----------------
+ */
+ info = (LockInfo) relation->lockInfo;
+ relname = (char *) RelationGetRelationName(relation);
+ relationid = RelationGetRelationId(relation);
+ processingVariable = (strcmp(relname, VariableRelationName) == 0);
+
+ /* ----------------
+ * create a new lockinfo if not already done
+ * ----------------
+ */
+ if (!PointerIsValid(info))
{
- MemoryContext oldcxt;
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
- info = (LockInfo)palloc(sizeof(LockInfoData));
- MemoryContextSwitchTo(oldcxt);
+ MemoryContext oldcxt;
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ info = (LockInfo) palloc(sizeof(LockInfoData));
+ MemoryContextSwitchTo(oldcxt);
}
- else if (processingVariable) {
- if (IsTransactionState()) {
- TransactionIdStore(GetCurrentTransactionId(),
- &info->transactionIdData);
+ else if (processingVariable)
+ {
+ if (IsTransactionState())
+ {
+ TransactionIdStore(GetCurrentTransactionId(),
+ &info->transactionIdData);
+ }
+ info->flags = 0x0;
+ return; /* prevent an infinite loop--still true? */
}
- info->flags = 0x0;
- return; /* prevent an infinite loop--still true? */
- }
- else if (info->initialized)
+ else if (info->initialized)
{
- /* ------------
- * If we've already initialized we're done.
- * ------------
- */
- return;
+ /* ------------
+ * If we've already initialized we're done.
+ * ------------
+ */
+ return;
}
-
- /* ----------------
- * initialize lockinfo.dbId and .relId appropriately
- * ----------------
- */
- if (IsSharedSystemRelationName(relname))
- LRelIdAssign(&info->lRelId, InvalidOid, relationid);
- else
- LRelIdAssign(&info->lRelId, MyDatabaseId, relationid);
-
- /* ----------------
- * store the transaction id in the lockInfo field
- * ----------------
- */
- if (processingVariable)
- TransactionIdStore(AmiTransactionId,
- &info->transactionIdData);
- else if (IsTransactionState())
- TransactionIdStore(GetCurrentTransactionId(),
- &info->transactionIdData);
- else
- StoreInvalidTransactionId(&(info->transactionIdData));
-
- /* ----------------
- * initialize rest of lockinfo
- * ----------------
- */
- info->flags = 0x0;
- info->initialized = (bool)true;
- relation->lockInfo = (Pointer) info;
+
+ /* ----------------
+ * initialize lockinfo.dbId and .relId appropriately
+ * ----------------
+ */
+ if (IsSharedSystemRelationName(relname))
+ LRelIdAssign(&info->lRelId, InvalidOid, relationid);
+ else
+ LRelIdAssign(&info->lRelId, MyDatabaseId, relationid);
+
+ /* ----------------
+ * store the transaction id in the lockInfo field
+ * ----------------
+ */
+ if (processingVariable)
+ TransactionIdStore(AmiTransactionId,
+ &info->transactionIdData);
+ else if (IsTransactionState())
+ TransactionIdStore(GetCurrentTransactionId(),
+ &info->transactionIdData);
+ else
+ StoreInvalidTransactionId(&(info->transactionIdData));
+
+ /* ----------------
+ * initialize rest of lockinfo
+ * ----------------
+ */
+ info->flags = 0x0;
+ info->initialized = (bool) true;
+ relation->lockInfo = (Pointer) info;
}
/* ----------------
- * RelationDiscardLockInfo
+ * RelationDiscardLockInfo
* ----------------
*/
#ifdef LOCKDEBUG
@@ -286,456 +293,464 @@ RelationInitLockInfo(Relation relation)
elog(DEBUG, "DiscardLockInfo: NULL relation->lockInfo")
#else
#define LOCKDEBUG_20
-#endif /* LOCKDEBUG */
-
+#endif /* LOCKDEBUG */
+
/*
* RelationDiscardLockInfo --
- * Discards the lock information in a relation descriptor.
+ * Discards the lock information in a relation descriptor.
*/
#ifdef NOT_USED
void
RelationDiscardLockInfo(Relation relation)
{
- if (! LockInfoIsValid(relation->lockInfo)) {
- LOCKDEBUG_20;
- return;
- }
-
- pfree(relation->lockInfo);
- relation->lockInfo = NULL;
+ if (!LockInfoIsValid(relation->lockInfo))
+ {
+ LOCKDEBUG_20;
+ return;
+ }
+
+ pfree(relation->lockInfo);
+ relation->lockInfo = NULL;
}
+
#endif
/*
* RelationSetLockForDescriptorOpen --
- * Sets read locks for a relation descriptor.
+ * Sets read locks for a relation descriptor.
*/
#ifdef LOCKDEBUGALL
#define LOCKDEBUGALL_30 \
elog(DEBUG, "RelationSetLockForDescriptorOpen(%s[%d,%d]) called", \
- RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
+ RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
#else
#define LOCKDEBUGALL_30
-#endif /* LOCKDEBUGALL*/
-
+#endif /* LOCKDEBUGALL */
+
void
RelationSetLockForDescriptorOpen(Relation relation)
{
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- LOCKDEBUGALL_30;
-
- /* ----------------
- * read lock catalog tuples which compose the relation descriptor
- * XXX race condition? XXX For now, do nothing.
- * ----------------
- */
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ LOCKDEBUGALL_30;
+
+ /* ----------------
+ * read lock catalog tuples which compose the relation descriptor
+ * XXX race condition? XXX For now, do nothing.
+ * ----------------
+ */
}
/* ----------------
- * RelationSetLockForRead
+ * RelationSetLockForRead
* ----------------
*/
#ifdef LOCKDEBUG
#define LOCKDEBUG_40 \
elog(DEBUG, "RelationSetLockForRead(%s[%d,%d]) called", \
- RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
+ RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
#else
#define LOCKDEBUG_40
-#endif /* LOCKDEBUG*/
-
+#endif /* LOCKDEBUG */
+
/*
* RelationSetLockForRead --
- * Sets relation level read lock.
+ * Sets relation level read lock.
*/
void
RelationSetLockForRead(Relation relation)
{
- LockInfo linfo;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- LOCKDEBUG_40;
-
- /* ----------------
- * If we don't have lock info on the reln just go ahead and
- * lock it without trying to short circuit the lock manager.
- * ----------------
- */
- if (!LockInfoIsValid(relation->lockInfo))
+ LockInfo linfo;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ LOCKDEBUG_40;
+
+ /* ----------------
+ * If we don't have lock info on the reln just go ahead and
+ * lock it without trying to short circuit the lock manager.
+ * ----------------
+ */
+ if (!LockInfoIsValid(relation->lockInfo))
{
- RelationInitLockInfo(relation);
- linfo = (LockInfo) relation->lockInfo;
- linfo->flags |= ReadRelationLock;
- MultiLockReln(linfo, READ_LOCK);
- return;
+ RelationInitLockInfo(relation);
+ linfo = (LockInfo) relation->lockInfo;
+ linfo->flags |= ReadRelationLock;
+ MultiLockReln(linfo, READ_LOCK);
+ return;
}
- else
- linfo = (LockInfo) relation->lockInfo;
-
- MultiLockReln(linfo, READ_LOCK);
+ else
+ linfo = (LockInfo) relation->lockInfo;
+
+ MultiLockReln(linfo, READ_LOCK);
}
/* ----------------
- * RelationUnsetLockForRead
+ * RelationUnsetLockForRead
* ----------------
*/
#ifdef LOCKDEBUG
#define LOCKDEBUG_50 \
elog(DEBUG, "RelationUnsetLockForRead(%s[%d,%d]) called", \
- RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
+ RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
#else
#define LOCKDEBUG_50
-#endif /* LOCKDEBUG*/
-
+#endif /* LOCKDEBUG */
+
/*
* RelationUnsetLockForRead --
- * Unsets relation level read lock.
+ * Unsets relation level read lock.
*/
void
RelationUnsetLockForRead(Relation relation)
{
- LockInfo linfo;
-
- /* ----------------
- * sanity check
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- linfo = (LockInfo) relation->lockInfo;
-
- /* ----------------
- * If we don't have lock info on the reln just go ahead and
- * release it.
- * ----------------
- */
- if (!LockInfoIsValid(linfo))
+ LockInfo linfo;
+
+ /* ----------------
+ * sanity check
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ linfo = (LockInfo) relation->lockInfo;
+
+ /* ----------------
+ * If we don't have lock info on the reln just go ahead and
+ * release it.
+ * ----------------
+ */
+ if (!LockInfoIsValid(linfo))
{
- elog(WARN,
- "Releasing a lock on %s with invalid lock information",
- RelationGetRelationName(relation));
+ elog(WARN,
+ "Releasing a lock on %s with invalid lock information",
+ RelationGetRelationName(relation));
}
-
- MultiReleaseReln(linfo, READ_LOCK);
+
+ MultiReleaseReln(linfo, READ_LOCK);
}
/* ----------------
- * RelationSetLockForWrite(relation)
+ * RelationSetLockForWrite(relation)
* ----------------
*/
#ifdef LOCKDEBUG
#define LOCKDEBUG_60 \
elog(DEBUG, "RelationSetLockForWrite(%s[%d,%d]) called", \
- RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
+ RelationGetRelationName(relation), lRelId.dbId, lRelId.relId)
#else
#define LOCKDEBUG_60
-#endif /* LOCKDEBUG*/
-
+#endif /* LOCKDEBUG */
+
/*
* RelationSetLockForWrite --
- * Sets relation level write lock.
+ * Sets relation level write lock.
*/
void
RelationSetLockForWrite(Relation relation)
{
- LockInfo linfo;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- LOCKDEBUG_60;
-
- /* ----------------
- * If we don't have lock info on the reln just go ahead and
- * lock it without trying to short circuit the lock manager.
- * ----------------
- */
- if (!LockInfoIsValid(relation->lockInfo))
+ LockInfo linfo;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ LOCKDEBUG_60;
+
+ /* ----------------
+ * If we don't have lock info on the reln just go ahead and
+ * lock it without trying to short circuit the lock manager.
+ * ----------------
+ */
+ if (!LockInfoIsValid(relation->lockInfo))
{
- RelationInitLockInfo(relation);
- linfo = (LockInfo) relation->lockInfo;
- linfo->flags |= WriteRelationLock;
- MultiLockReln(linfo, WRITE_LOCK);
- return;
+ RelationInitLockInfo(relation);
+ linfo = (LockInfo) relation->lockInfo;
+ linfo->flags |= WriteRelationLock;
+ MultiLockReln(linfo, WRITE_LOCK);
+ return;
}
- else
- linfo = (LockInfo) relation->lockInfo;
-
- MultiLockReln(linfo, WRITE_LOCK);
+ else
+ linfo = (LockInfo) relation->lockInfo;
+
+ MultiLockReln(linfo, WRITE_LOCK);
}
/* ----------------
- * RelationUnsetLockForWrite
+ * RelationUnsetLockForWrite
* ----------------
*/
#ifdef LOCKDEBUG
#define LOCKDEBUG_70 \
elog(DEBUG, "RelationUnsetLockForWrite(%s[%d,%d]) called", \
- RelationGetRelationName(relation), lRelId.dbId, lRelId.relId);
+ RelationGetRelationName(relation), lRelId.dbId, lRelId.relId);
#else
#define LOCKDEBUG_70
-#endif /* LOCKDEBUG */
-
+#endif /* LOCKDEBUG */
+
/*
* RelationUnsetLockForWrite --
- * Unsets relation level write lock.
+ * Unsets relation level write lock.
*/
void
RelationUnsetLockForWrite(Relation relation)
{
- LockInfo linfo;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled()) {
- return;
- }
-
- linfo = (LockInfo) relation->lockInfo;
-
- if (!LockInfoIsValid(linfo))
+ LockInfo linfo;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ {
+ return;
+ }
+
+ linfo = (LockInfo) relation->lockInfo;
+
+ if (!LockInfoIsValid(linfo))
{
- elog(WARN,
- "Releasing a lock on %s with invalid lock information",
- RelationGetRelationName(relation));
+ elog(WARN,
+ "Releasing a lock on %s with invalid lock information",
+ RelationGetRelationName(relation));
}
-
- MultiReleaseReln(linfo, WRITE_LOCK);
+
+ MultiReleaseReln(linfo, WRITE_LOCK);
}
/* ----------------
- * RelationSetLockForTupleRead
+ * RelationSetLockForTupleRead
* ----------------
*/
#ifdef LOCKDEBUG
#define LOCKDEBUG_80 \
elog(DEBUG, "RelationSetLockForTupleRead(%s[%d,%d], 0x%x) called", \
- RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, \
- itemPointer)
+ RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, \
+ itemPointer)
#define LOCKDEBUG_81 \
- elog(DEBUG, "RelationSetLockForTupleRead() escalating");
+ elog(DEBUG, "RelationSetLockForTupleRead() escalating");
#else
#define LOCKDEBUG_80
#define LOCKDEBUG_81
-#endif /* LOCKDEBUG */
-
+#endif /* LOCKDEBUG */
+
/*
* RelationSetLockForTupleRead --
- * Sets tuple level read lock.
+ * Sets tuple level read lock.
*/
#ifdef NOT_USED
void
RelationSetLockForTupleRead(Relation relation, ItemPointer itemPointer)
{
- LockInfo linfo;
- TransactionId curXact;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- LOCKDEBUG_80;
-
- /* ---------------------
- * If our lock info is invalid don't bother trying to short circuit
- * the lock manager.
- * ---------------------
- */
- if (!LockInfoIsValid(relation->lockInfo))
+ LockInfo linfo;
+ TransactionId curXact;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ LOCKDEBUG_80;
+
+ /* ---------------------
+ * If our lock info is invalid don't bother trying to short circuit
+ * the lock manager.
+ * ---------------------
+ */
+ if (!LockInfoIsValid(relation->lockInfo))
{
- RelationInitLockInfo(relation);
- linfo = (LockInfo) relation->lockInfo;
- linfo->flags |=
- IntentReadRelationLock |
- IntentReadPageLock |
+ RelationInitLockInfo(relation);
+ linfo = (LockInfo) relation->lockInfo;
+ linfo->flags |=
+ IntentReadRelationLock |
+ IntentReadPageLock |
ReadTupleLock;
- MultiLockTuple(linfo, itemPointer, READ_LOCK);
- return;
+ MultiLockTuple(linfo, itemPointer, READ_LOCK);
+ return;
}
- else
- linfo = (LockInfo) relation->lockInfo;
-
- /* ----------------
- * no need to set a lower granularity lock
- * ----------------
- */
- curXact = GetCurrentTransactionId();
- if ((linfo->flags & ReadRelationLock) &&
- TransactionIdEquals(curXact, linfo->transactionIdData))
+ else
+ linfo = (LockInfo) relation->lockInfo;
+
+ /* ----------------
+ * no need to set a lower granularity lock
+ * ----------------
+ */
+ curXact = GetCurrentTransactionId();
+ if ((linfo->flags & ReadRelationLock) &&
+ TransactionIdEquals(curXact, linfo->transactionIdData))
{
- return;
+ return;
}
-
- /* ----------------
- * If we don't already have a tuple lock this transaction
- * ----------------
- */
- if (!( (linfo->flags & ReadTupleLock) &&
- TransactionIdEquals(curXact, linfo->transactionIdData) )) {
-
- linfo->flags |=
- IntentReadRelationLock |
- IntentReadPageLock |
- ReadTupleLock;
-
- /* clear count */
- linfo->flags &= ~TupleLevelLockCountMask;
-
- } else {
- if (TupleLevelLockLimit == (TupleLevelLockCountMask &
- linfo->flags)) {
- LOCKDEBUG_81;
-
- /* escalate */
- MultiLockReln(linfo, READ_LOCK);
-
- /* clear count */
- linfo->flags &= ~TupleLevelLockCountMask;
- return;
+
+ /* ----------------
+ * If we don't already have a tuple lock this transaction
+ * ----------------
+ */
+ if (!((linfo->flags & ReadTupleLock) &&
+ TransactionIdEquals(curXact, linfo->transactionIdData)))
+ {
+
+ linfo->flags |=
+ IntentReadRelationLock |
+ IntentReadPageLock |
+ ReadTupleLock;
+
+ /* clear count */
+ linfo->flags &= ~TupleLevelLockCountMask;
+
+ }
+ else
+ {
+ if (TupleLevelLockLimit == (TupleLevelLockCountMask &
+ linfo->flags))
+ {
+ LOCKDEBUG_81;
+
+ /* escalate */
+ MultiLockReln(linfo, READ_LOCK);
+
+ /* clear count */
+ linfo->flags &= ~TupleLevelLockCountMask;
+ return;
+ }
+
+ /* increment count */
+ linfo->flags =
+ (linfo->flags & ~TupleLevelLockCountMask) |
+ (1 + (TupleLevelLockCountMask & linfo->flags));
}
-
- /* increment count */
- linfo->flags =
- (linfo->flags & ~TupleLevelLockCountMask) |
- (1 + (TupleLevelLockCountMask & linfo->flags));
- }
-
- TransactionIdStore(curXact, &linfo->transactionIdData);
-
- /* ----------------
- * Lock the tuple.
- * ----------------
- */
- MultiLockTuple(linfo, itemPointer, READ_LOCK);
+
+ TransactionIdStore(curXact, &linfo->transactionIdData);
+
+ /* ----------------
+ * Lock the tuple.
+ * ----------------
+ */
+ MultiLockTuple(linfo, itemPointer, READ_LOCK);
}
+
#endif
/* ----------------
- * RelationSetLockForReadPage
+ * RelationSetLockForReadPage
* ----------------
*/
#ifdef LOCKDEBUG
#define LOCKDEBUG_90 \
elog(DEBUG, "RelationSetLockForReadPage(%s[%d,%d], @%d) called", \
- RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, page);
+ RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, page);
#else
#define LOCKDEBUG_90
-#endif /* LOCKDEBUG*/
-
+#endif /* LOCKDEBUG */
+
/* ----------------
- * RelationSetLockForWritePage
+ * RelationSetLockForWritePage
* ----------------
*/
#ifdef LOCKDEBUG
#define LOCKDEBUG_100 \
elog(DEBUG, "RelationSetLockForWritePage(%s[%d,%d], @%d) called", \
- RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, page);
+ RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, page);
#else
#define LOCKDEBUG_100
-#endif /* LOCKDEBUG */
-
+#endif /* LOCKDEBUG */
+
/*
* RelationSetLockForWritePage --
- * Sets write lock on a page.
+ * Sets write lock on a page.
*/
-void
+void
RelationSetLockForWritePage(Relation relation,
- ItemPointer itemPointer)
+ ItemPointer itemPointer)
{
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- /* ---------------
- * Make sure linfo is initialized
- * ---------------
- */
- if (!LockInfoIsValid(relation->lockInfo))
- RelationInitLockInfo(relation);
-
- /* ----------------
- * attempt to set lock
- * ----------------
- */
- MultiLockPage((LockInfo) relation->lockInfo, itemPointer, WRITE_LOCK);
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ /* ---------------
+ * Make sure linfo is initialized
+ * ---------------
+ */
+ if (!LockInfoIsValid(relation->lockInfo))
+ RelationInitLockInfo(relation);
+
+ /* ----------------
+ * attempt to set lock
+ * ----------------
+ */
+ MultiLockPage((LockInfo) relation->lockInfo, itemPointer, WRITE_LOCK);
}
/* ----------------
- * RelationUnsetLockForReadPage
+ * RelationUnsetLockForReadPage
* ----------------
*/
#ifdef LOCKDEBUG
#define LOCKDEBUG_110 \
elog(DEBUG, "RelationUnsetLockForReadPage(%s[%d,%d], @%d) called", \
- RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, page)
+ RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, page)
#else
#define LOCKDEBUG_110
-#endif /* LOCKDEBUG */
-
+#endif /* LOCKDEBUG */
+
/* ----------------
- * RelationUnsetLockForWritePage
+ * RelationUnsetLockForWritePage
* ----------------
*/
#ifdef LOCKDEBUG
#define LOCKDEBUG_120 \
elog(DEBUG, "RelationUnsetLockForWritePage(%s[%d,%d], @%d) called", \
- RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, page)
+ RelationGetRelationName(relation), lRelId.dbId, lRelId.relId, page)
#else
#define LOCKDEBUG_120
-#endif /* LOCKDEBUG */
-
+#endif /* LOCKDEBUG */
+
/*
- * Set a single level write page lock. Assumes that you already
+ * Set a single level write page lock. Assumes that you already
* have a write intent lock on the relation.
*/
void
RelationSetSingleWLockPage(Relation relation,
- ItemPointer itemPointer)
+ ItemPointer itemPointer)
{
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- if (!LockInfoIsValid(relation->lockInfo))
- RelationInitLockInfo(relation);
-
- SingleLockPage((LockInfo)relation->lockInfo, itemPointer, WRITE_LOCK, !UNLOCK);
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ if (!LockInfoIsValid(relation->lockInfo))
+ RelationInitLockInfo(relation);
+
+ SingleLockPage((LockInfo) relation->lockInfo, itemPointer, WRITE_LOCK, !UNLOCK);
}
/*
@@ -743,23 +758,23 @@ RelationSetSingleWLockPage(Relation relation,
*/
void
RelationUnsetSingleWLockPage(Relation relation,
- ItemPointer itemPointer)
+ ItemPointer itemPointer)
{
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- if (!LockInfoIsValid(relation->lockInfo))
- elog(WARN,
- "Releasing a lock on %s with invalid lock information",
- RelationGetRelationName(relation));
-
- SingleLockPage((LockInfo)relation->lockInfo, itemPointer, WRITE_LOCK, UNLOCK);
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ if (!LockInfoIsValid(relation->lockInfo))
+ elog(WARN,
+ "Releasing a lock on %s with invalid lock information",
+ RelationGetRelationName(relation));
+
+ SingleLockPage((LockInfo) relation->lockInfo, itemPointer, WRITE_LOCK, UNLOCK);
}
/*
@@ -768,45 +783,45 @@ RelationUnsetSingleWLockPage(Relation relation,
*/
void
RelationSetSingleRLockPage(Relation relation,
- ItemPointer itemPointer)
+ ItemPointer itemPointer)
{
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- if (!LockInfoIsValid(relation->lockInfo))
- RelationInitLockInfo(relation);
-
- SingleLockPage((LockInfo)relation->lockInfo, itemPointer, READ_LOCK, !UNLOCK);
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ if (!LockInfoIsValid(relation->lockInfo))
+ RelationInitLockInfo(relation);
+
+ SingleLockPage((LockInfo) relation->lockInfo, itemPointer, READ_LOCK, !UNLOCK);
}
-/*
+/*
* Unset a single level read page lock.
*/
void
RelationUnsetSingleRLockPage(Relation relation,
- ItemPointer itemPointer)
+ ItemPointer itemPointer)
{
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- if (!LockInfoIsValid(relation->lockInfo))
- elog(WARN,
- "Releasing a lock on %s with invalid lock information",
- RelationGetRelationName(relation));
-
- SingleLockPage((LockInfo)relation->lockInfo, itemPointer, READ_LOCK, UNLOCK);
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ if (!LockInfoIsValid(relation->lockInfo))
+ elog(WARN,
+ "Releasing a lock on %s with invalid lock information",
+ RelationGetRelationName(relation));
+
+ SingleLockPage((LockInfo) relation->lockInfo, itemPointer, READ_LOCK, UNLOCK);
}
/*
@@ -821,18 +836,18 @@ RelationUnsetSingleRLockPage(Relation relation,
void
RelationSetRIntentLock(Relation relation)
{
- /* -----------------
- * Sanity check
- * -----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- if (!LockInfoIsValid(relation->lockInfo))
- RelationInitLockInfo(relation);
-
- SingleLockReln((LockInfo)relation->lockInfo, READ_LOCK+INTENT, !UNLOCK);
+ /* -----------------
+ * Sanity check
+ * -----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ if (!LockInfoIsValid(relation->lockInfo))
+ RelationInitLockInfo(relation);
+
+ SingleLockReln((LockInfo) relation->lockInfo, READ_LOCK + INTENT, !UNLOCK);
}
/*
@@ -841,18 +856,18 @@ RelationSetRIntentLock(Relation relation)
void
RelationUnsetRIntentLock(Relation relation)
{
- /* -----------------
- * Sanity check
- * -----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- if (!LockInfoIsValid(relation->lockInfo))
- RelationInitLockInfo(relation);
-
- SingleLockReln((LockInfo)relation->lockInfo, READ_LOCK+INTENT, UNLOCK);
+ /* -----------------
+ * Sanity check
+ * -----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ if (!LockInfoIsValid(relation->lockInfo))
+ RelationInitLockInfo(relation);
+
+ SingleLockReln((LockInfo) relation->lockInfo, READ_LOCK + INTENT, UNLOCK);
}
/*
@@ -862,18 +877,18 @@ RelationUnsetRIntentLock(Relation relation)
void
RelationSetWIntentLock(Relation relation)
{
- /* -----------------
- * Sanity check
- * -----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- if (!LockInfoIsValid(relation->lockInfo))
- RelationInitLockInfo(relation);
-
- SingleLockReln((LockInfo)relation->lockInfo, WRITE_LOCK+INTENT, !UNLOCK);
+ /* -----------------
+ * Sanity check
+ * -----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ if (!LockInfoIsValid(relation->lockInfo))
+ RelationInitLockInfo(relation);
+
+ SingleLockReln((LockInfo) relation->lockInfo, WRITE_LOCK + INTENT, !UNLOCK);
}
/*
@@ -882,69 +897,71 @@ RelationSetWIntentLock(Relation relation)
void
RelationUnsetWIntentLock(Relation relation)
{
- /* -----------------
- * Sanity check
- * -----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- if (!LockInfoIsValid(relation->lockInfo))
- RelationInitLockInfo(relation);
-
- SingleLockReln((LockInfo)relation->lockInfo, WRITE_LOCK+INTENT, UNLOCK);
+ /* -----------------
+ * Sanity check
+ * -----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ if (!LockInfoIsValid(relation->lockInfo))
+ RelationInitLockInfo(relation);
+
+ SingleLockReln((LockInfo) relation->lockInfo, WRITE_LOCK + INTENT, UNLOCK);
}
/*
* Extend locks are used primarily in tertiary storage devices such as
- * a WORM disk jukebox. Sometimes need exclusive access to extend a
+ * a WORM disk jukebox. Sometimes need exclusive access to extend a
* file by a block.
*/
#ifdef NOT_USED
void
RelationSetLockForExtend(Relation relation)
{
- /* -----------------
- * Sanity check
- * -----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- if (!LockInfoIsValid(relation->lockInfo))
- RelationInitLockInfo(relation);
-
- MultiLockReln((LockInfo) relation->lockInfo, EXTEND_LOCK);
+ /* -----------------
+ * Sanity check
+ * -----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ if (!LockInfoIsValid(relation->lockInfo))
+ RelationInitLockInfo(relation);
+
+ MultiLockReln((LockInfo) relation->lockInfo, EXTEND_LOCK);
}
+
#endif
#ifdef NOT_USED
void
RelationUnsetLockForExtend(Relation relation)
{
- /* -----------------
- * Sanity check
- * -----------------
- */
- Assert(RelationIsValid(relation));
- if (LockingDisabled())
- return;
-
- if (!LockInfoIsValid(relation->lockInfo))
- RelationInitLockInfo(relation);
-
- MultiReleaseReln((LockInfo) relation->lockInfo, EXTEND_LOCK);
+ /* -----------------
+ * Sanity check
+ * -----------------
+ */
+ Assert(RelationIsValid(relation));
+ if (LockingDisabled())
+ return;
+
+ if (!LockInfoIsValid(relation->lockInfo))
+ RelationInitLockInfo(relation);
+
+ MultiReleaseReln((LockInfo) relation->lockInfo, EXTEND_LOCK);
}
+
#endif
-/*
+/*
* Create an LRelid --- Why not just pass in a pointer to the storage?
*/
static void
-LRelIdAssign(LRelId *lRelId, Oid dbId, Oid relId)
-{
- lRelId->dbId = dbId;
- lRelId->relId = relId;
+LRelIdAssign(LRelId * lRelId, Oid dbId, Oid relId)
+{
+ lRelId->dbId = dbId;
+ lRelId->relId = relId;
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 15ede2e0ed9..7e592945f1b 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -1,37 +1,37 @@
/*-------------------------------------------------------------------------
*
* lock.c--
- * simple lock acquisition
+ * simple lock acquisition
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.11 1997/08/19 21:33:19 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.12 1997/09/07 04:48:58 momjian Exp $
*
* NOTES
- * Outside modules can create a lock table and acquire/release
- * locks. A lock table is a shared memory hash table. When
- * a process tries to acquire a lock of a type that conflicts
- * with existing locks, it is put to sleep using the routines
- * in storage/lmgr/proc.c.
+ * Outside modules can create a lock table and acquire/release
+ * locks. A lock table is a shared memory hash table. When
+ * a process tries to acquire a lock of a type that conflicts
+ * with existing locks, it is put to sleep using the routines
+ * in storage/lmgr/proc.c.
*
- * Interface:
+ * Interface:
*
- * LockAcquire(), LockRelease(), LockTabInit().
+ * LockAcquire(), LockRelease(), LockTabInit().
*
- * LockReplace() is called only within this module and by the
- * lkchain module. It releases a lock without looking
- * the lock up in the lock table.
+ * LockReplace() is called only within this module and by the
+ * lkchain module. It releases a lock without looking
+ * the lock up in the lock table.
*
- * NOTE: This module is used to define new lock tables. The
- * multi-level lock table (multi.c) used by the heap
- * access methods calls these routines. See multi.c for
- * examples showing how to use this interface.
+ * NOTE: This module is used to define new lock tables. The
+ * multi-level lock table (multi.c) used by the heap
+ * access methods calls these routines. See multi.c for
+ * examples showing how to use this interface.
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
@@ -48,8 +48,9 @@
#include "access/xact.h"
#include "access/transam.h"
-static int WaitOnLock(LOCKTAB *ltable, LockTableId tableId, LOCK *lock,
- LOCKT lockt);
+static int
+WaitOnLock(LOCKTAB * ltable, LockTableId tableId, LOCK * lock,
+ LOCKT lockt);
/*#define LOCK_MGR_DEBUG*/
@@ -60,84 +61,85 @@ static int WaitOnLock(LOCKTAB *ltable, LockTableId tableId, LOCK *lock,
#define LOCK_DUMP_AUX(where,lock,type)
#define XID_PRINT(where,xidentP)
-#else /* LOCK_MGR_DEBUG */
-
-int lockDebug = 0;
-unsigned int lock_debug_oid_min = BootstrapObjectIdData;
-static char *lock_types[] = {
- "NONE",
- "WRITE",
- "READ",
- "WRITE INTENT",
- "READ INTENT",
- "EXTEND"
+#else /* LOCK_MGR_DEBUG */
+
+int lockDebug = 0;
+unsigned int lock_debug_oid_min = BootstrapObjectIdData;
+static char *lock_types[] = {
+ "NONE",
+ "WRITE",
+ "READ",
+ "WRITE INTENT",
+ "READ INTENT",
+ "EXTEND"
};
#define LOCK_PRINT(where,tag,type)\
- if ((lockDebug >= 1) && (tag->relId >= lock_debug_oid_min)) \
- elog(DEBUG, \
- "%s: pid (%d) rel (%d) dbid (%d) tid (%d,%d) type (%s)",where, \
- getpid(),\
- tag->relId, tag->dbId, \
- ((tag->tupleId.ip_blkid.bi_hi<<16)+\
- tag->tupleId.ip_blkid.bi_lo),\
- tag->tupleId.ip_posid, \
- lock_types[type])
+ if ((lockDebug >= 1) && (tag->relId >= lock_debug_oid_min)) \
+ elog(DEBUG, \
+ "%s: pid (%d) rel (%d) dbid (%d) tid (%d,%d) type (%s)",where, \
+ getpid(),\
+ tag->relId, tag->dbId, \
+ ((tag->tupleId.ip_blkid.bi_hi<<16)+\
+ tag->tupleId.ip_blkid.bi_lo),\
+ tag->tupleId.ip_posid, \
+ lock_types[type])
#define LOCK_DUMP(where,lock,type)\
- if ((lockDebug >= 1) && (lock->tag.relId >= lock_debug_oid_min)) \
- LOCK_DUMP_AUX(where,lock,type)
+ if ((lockDebug >= 1) && (lock->tag.relId >= lock_debug_oid_min)) \
+ LOCK_DUMP_AUX(where,lock,type)
#define LOCK_DUMP_AUX(where,lock,type)\
- elog(DEBUG, \
- "%s: pid (%d) rel (%d) dbid (%d) tid (%d,%d) nHolding (%d) "\
- "holders (%d,%d,%d,%d,%d) type (%s)",where, \
- getpid(),\
- lock->tag.relId, lock->tag.dbId, \
- ((lock->tag.tupleId.ip_blkid.bi_hi<<16)+\
- lock->tag.tupleId.ip_blkid.bi_lo),\
- lock->tag.tupleId.ip_posid, \
- lock->nHolding,\
- lock->holders[1],\
- lock->holders[2],\
- lock->holders[3],\
- lock->holders[4],\
- lock->holders[5],\
- lock_types[type])
+ elog(DEBUG, \
+ "%s: pid (%d) rel (%d) dbid (%d) tid (%d,%d) nHolding (%d) "\
+ "holders (%d,%d,%d,%d,%d) type (%s)",where, \
+ getpid(),\
+ lock->tag.relId, lock->tag.dbId, \
+ ((lock->tag.tupleId.ip_blkid.bi_hi<<16)+\
+ lock->tag.tupleId.ip_blkid.bi_lo),\
+ lock->tag.tupleId.ip_posid, \
+ lock->nHolding,\
+ lock->holders[1],\
+ lock->holders[2],\
+ lock->holders[3],\
+ lock->holders[4],\
+ lock->holders[5],\
+ lock_types[type])
#define XID_PRINT(where,xidentP)\
- if ((lockDebug >= 2) && \
- (((LOCK *)MAKE_PTR(xidentP->tag.lock))->tag.relId \
- >= lock_debug_oid_min)) \
- elog(DEBUG,\
- "%s: pid (%d) xid (%d) pid (%d) lock (%x) nHolding (%d) "\
- "holders (%d,%d,%d,%d,%d)",\
- where,\
- getpid(),\
- xidentP->tag.xid,\
- xidentP->tag.pid,\
- xidentP->tag.lock,\
- xidentP->nHolding,\
- xidentP->holders[1],\
- xidentP->holders[2],\
- xidentP->holders[3],\
- xidentP->holders[4],\
- xidentP->holders[5])
-
-#endif /* LOCK_MGR_DEBUG */
-
-SPINLOCK LockMgrLock; /* in Shmem or created in CreateSpinlocks() */
+ if ((lockDebug >= 2) && \
+ (((LOCK *)MAKE_PTR(xidentP->tag.lock))->tag.relId \
+ >= lock_debug_oid_min)) \
+ elog(DEBUG,\
+ "%s: pid (%d) xid (%d) pid (%d) lock (%x) nHolding (%d) "\
+ "holders (%d,%d,%d,%d,%d)",\
+ where,\
+ getpid(),\
+ xidentP->tag.xid,\
+ xidentP->tag.pid,\
+ xidentP->tag.lock,\
+ xidentP->nHolding,\
+ xidentP->holders[1],\
+ xidentP->holders[2],\
+ xidentP->holders[3],\
+ xidentP->holders[4],\
+ xidentP->holders[5])
+
+#endif /* LOCK_MGR_DEBUG */
+
+SPINLOCK LockMgrLock; /* in Shmem or created in
+ * CreateSpinlocks() */
/* This is to simplify/speed up some bit arithmetic */
-static MASK BITS_OFF[MAX_LOCKTYPES];
-static MASK BITS_ON[MAX_LOCKTYPES];
+static MASK BITS_OFF[MAX_LOCKTYPES];
+static MASK BITS_ON[MAX_LOCKTYPES];
/* -----------------
* XXX Want to move this to this file
* -----------------
*/
-static bool LockingIsDisabled;
+static bool LockingIsDisabled;
/* -------------------
* map from tableId to the lock table structure
@@ -149,28 +151,28 @@ static LOCKTAB *AllTables[MAX_TABLES];
* no zero-th table
* -------------------
*/
-static int NumTables = 1;
+static int NumTables = 1;
/* -------------------
* InitLocks -- Init the lock module. Create a private data
- * structure for constructing conflict masks.
+ * structure for constructing conflict masks.
* -------------------
*/
void
InitLocks()
{
- int i;
- int bit;
-
- bit = 1;
- /* -------------------
- * remember 0th locktype is invalid
- * -------------------
- */
- for (i=0;i<MAX_LOCKTYPES;i++,bit <<= 1)
+ int i;
+ int bit;
+
+ bit = 1;
+ /* -------------------
+ * remember 0th locktype is invalid
+ * -------------------
+ */
+ for (i = 0; i < MAX_LOCKTYPES; i++, bit <<= 1)
{
- BITS_ON[i] = bit;
- BITS_OFF[i] = ~bit;
+ BITS_ON[i] = bit;
+ BITS_OFF[i] = ~bit;
}
}
@@ -181,30 +183,30 @@ InitLocks()
void
LockDisable(int status)
{
- LockingIsDisabled = status;
+ LockingIsDisabled = status;
}
/*
* LockTypeInit -- initialize the lock table's lock type
- * structures
+ * structures
*
* Notes: just copying. Should only be called once.
*/
static void
-LockTypeInit(LOCKTAB *ltable,
- MASK *conflictsP,
- int *prioP,
- int ntypes)
+LockTypeInit(LOCKTAB * ltable,
+ MASK * conflictsP,
+ int *prioP,
+ int ntypes)
{
- int i;
-
- ltable->ctl->nLockTypes = ntypes;
- ntypes++;
- for (i=0;i<ntypes;i++,prioP++,conflictsP++)
+ int i;
+
+ ltable->ctl->nLockTypes = ntypes;
+ ntypes++;
+ for (i = 0; i < ntypes; i++, prioP++, conflictsP++)
{
- ltable->ctl->conflictTab[i] = *conflictsP;
- ltable->ctl->prio[i] = *prioP;
+ ltable->ctl->conflictTab[i] = *conflictsP;
+ ltable->ctl->prio[i] = *prioP;
}
}
@@ -212,873 +214,900 @@ LockTypeInit(LOCKTAB *ltable,
* LockTabInit -- initialize a lock table structure
*
* Notes:
- * (a) a lock table has four separate entries in the binding
- * table. This is because every shared hash table and spinlock
- * has its name stored in the binding table at its creation. It
- * is wasteful, in this case, but not much space is involved.
+ * (a) a lock table has four separate entries in the binding
+ * table. This is because every shared hash table and spinlock
+ * has its name stored in the binding table at its creation. It
+ * is wasteful, in this case, but not much space is involved.
*
*/
LockTableId
LockTabInit(char *tabName,
- MASK *conflictsP,
- int *prioP,
- int ntypes)
+ MASK * conflictsP,
+ int *prioP,
+ int ntypes)
{
- LOCKTAB *ltable;
- char *shmemName;
- HASHCTL info;
- int hash_flags;
- bool found;
- int status = TRUE;
-
- if (ntypes > MAX_LOCKTYPES)
+ LOCKTAB *ltable;
+ char *shmemName;
+ HASHCTL info;
+ int hash_flags;
+ bool found;
+ int status = TRUE;
+
+ if (ntypes > MAX_LOCKTYPES)
{
- elog(NOTICE,"LockTabInit: too many lock types %d greater than %d",
- ntypes,MAX_LOCKTYPES);
- return(INVALID_TABLEID);
+ elog(NOTICE, "LockTabInit: too many lock types %d greater than %d",
+ ntypes, MAX_LOCKTYPES);
+ return (INVALID_TABLEID);
}
-
- if (NumTables > MAX_TABLES)
+
+ if (NumTables > MAX_TABLES)
{
- elog(NOTICE,
- "LockTabInit: system limit of MAX_TABLES (%d) lock tables",
- MAX_TABLES);
- return(INVALID_TABLEID);
+ elog(NOTICE,
+ "LockTabInit: system limit of MAX_TABLES (%d) lock tables",
+ MAX_TABLES);
+ return (INVALID_TABLEID);
}
-
- /* allocate a string for the binding table lookup */
- shmemName = (char *) palloc((unsigned)(strlen(tabName)+32));
- if (! shmemName)
+
+ /* allocate a string for the binding table lookup */
+ shmemName = (char *) palloc((unsigned) (strlen(tabName) + 32));
+ if (!shmemName)
{
- elog(NOTICE,"LockTabInit: couldn't malloc string %s \n",tabName);
- return(INVALID_TABLEID);
+ elog(NOTICE, "LockTabInit: couldn't malloc string %s \n", tabName);
+ return (INVALID_TABLEID);
}
-
- /* each lock table has a non-shared header */
- ltable = (LOCKTAB *) palloc((unsigned) sizeof(LOCKTAB));
- if (! ltable)
+
+ /* each lock table has a non-shared header */
+ ltable = (LOCKTAB *) palloc((unsigned) sizeof(LOCKTAB));
+ if (!ltable)
{
- elog(NOTICE,"LockTabInit: couldn't malloc lock table %s\n",tabName);
- pfree (shmemName);
- return(INVALID_TABLEID);
+ elog(NOTICE, "LockTabInit: couldn't malloc lock table %s\n", tabName);
+ pfree(shmemName);
+ return (INVALID_TABLEID);
}
-
- /* ------------------------
- * find/acquire the spinlock for the table
- * ------------------------
- */
- SpinAcquire(LockMgrLock);
-
-
- /* -----------------------
- * allocate a control structure from shared memory or attach to it
- * if it already exists.
- * -----------------------
- */
- sprintf(shmemName,"%s (ctl)",tabName);
- ltable->ctl = (LOCKCTL *)
- ShmemInitStruct(shmemName,(unsigned)sizeof(LOCKCTL),&found);
-
- if (! ltable->ctl)
+
+ /* ------------------------
+ * find/acquire the spinlock for the table
+ * ------------------------
+ */
+ SpinAcquire(LockMgrLock);
+
+
+ /* -----------------------
+ * allocate a control structure from shared memory or attach to it
+ * if it already exists.
+ * -----------------------
+ */
+ sprintf(shmemName, "%s (ctl)", tabName);
+ ltable->ctl = (LOCKCTL *)
+ ShmemInitStruct(shmemName, (unsigned) sizeof(LOCKCTL), &found);
+
+ if (!ltable->ctl)
{
- elog(FATAL,"LockTabInit: couldn't initialize %s",tabName);
- status = FALSE;
+ elog(FATAL, "LockTabInit: couldn't initialize %s", tabName);
+ status = FALSE;
}
-
- /* ----------------
- * we're first - initialize
- * ----------------
- */
- if (! found)
+
+ /* ----------------
+ * we're first - initialize
+ * ----------------
+ */
+ if (!found)
{
- memset(ltable->ctl, 0, sizeof(LOCKCTL));
- ltable->ctl->masterLock = LockMgrLock;
- ltable->ctl->tableId = NumTables;
+ memset(ltable->ctl, 0, sizeof(LOCKCTL));
+ ltable->ctl->masterLock = LockMgrLock;
+ ltable->ctl->tableId = NumTables;
}
-
- /* --------------------
- * other modules refer to the lock table by a tableId
- * --------------------
- */
- AllTables[NumTables] = ltable;
- NumTables++;
- Assert(NumTables <= MAX_TABLES);
-
- /* ----------------------
- * allocate a hash table for the lock tags. This is used
- * to find the different locks.
- * ----------------------
- */
- info.keysize = sizeof(LOCKTAG);
- info.datasize = sizeof(LOCK);
- info.hash = tag_hash;
- hash_flags = (HASH_ELEM | HASH_FUNCTION);
-
- sprintf(shmemName,"%s (lock hash)",tabName);
- ltable->lockHash = (HTAB *) ShmemInitHash(shmemName,
- INIT_TABLE_SIZE,MAX_TABLE_SIZE,
- &info,hash_flags);
-
- Assert( ltable->lockHash->hash == tag_hash);
- if (! ltable->lockHash)
+
+ /* --------------------
+ * other modules refer to the lock table by a tableId
+ * --------------------
+ */
+ AllTables[NumTables] = ltable;
+ NumTables++;
+ Assert(NumTables <= MAX_TABLES);
+
+ /* ----------------------
+ * allocate a hash table for the lock tags. This is used
+ * to find the different locks.
+ * ----------------------
+ */
+ info.keysize = sizeof(LOCKTAG);
+ info.datasize = sizeof(LOCK);
+ info.hash = tag_hash;
+ hash_flags = (HASH_ELEM | HASH_FUNCTION);
+
+ sprintf(shmemName, "%s (lock hash)", tabName);
+ ltable->lockHash = (HTAB *) ShmemInitHash(shmemName,
+ INIT_TABLE_SIZE, MAX_TABLE_SIZE,
+ &info, hash_flags);
+
+ Assert(ltable->lockHash->hash == tag_hash);
+ if (!ltable->lockHash)
{
- elog(FATAL,"LockTabInit: couldn't initialize %s",tabName);
- status = FALSE;
+ elog(FATAL, "LockTabInit: couldn't initialize %s", tabName);
+ status = FALSE;
}
-
- /* -------------------------
- * allocate an xid table. When different transactions hold
- * the same lock, additional information must be saved (locks per tx).
- * -------------------------
- */
- info.keysize = XID_TAGSIZE;
- info.datasize = sizeof(XIDLookupEnt);
- info.hash = tag_hash;
- hash_flags = (HASH_ELEM | HASH_FUNCTION);
-
- sprintf(shmemName,"%s (xid hash)",tabName);
- ltable->xidHash = (HTAB *) ShmemInitHash(shmemName,
- INIT_TABLE_SIZE,MAX_TABLE_SIZE,
- &info,hash_flags);
-
- if (! ltable->xidHash)
+
+ /* -------------------------
+ * allocate an xid table. When different transactions hold
+ * the same lock, additional information must be saved (locks per tx).
+ * -------------------------
+ */
+ info.keysize = XID_TAGSIZE;
+ info.datasize = sizeof(XIDLookupEnt);
+ info.hash = tag_hash;
+ hash_flags = (HASH_ELEM | HASH_FUNCTION);
+
+ sprintf(shmemName, "%s (xid hash)", tabName);
+ ltable->xidHash = (HTAB *) ShmemInitHash(shmemName,
+ INIT_TABLE_SIZE, MAX_TABLE_SIZE,
+ &info, hash_flags);
+
+ if (!ltable->xidHash)
{
- elog(FATAL,"LockTabInit: couldn't initialize %s",tabName);
- status = FALSE;
+ elog(FATAL, "LockTabInit: couldn't initialize %s", tabName);
+ status = FALSE;
}
-
- /* init ctl data structures */
- LockTypeInit(ltable, conflictsP, prioP, ntypes);
-
- SpinRelease(LockMgrLock);
-
- pfree (shmemName);
-
- if (status)
- return(ltable->ctl->tableId);
- else
- return(INVALID_TABLEID);
+
+ /* init ctl data structures */
+ LockTypeInit(ltable, conflictsP, prioP, ntypes);
+
+ SpinRelease(LockMgrLock);
+
+ pfree(shmemName);
+
+ if (status)
+ return (ltable->ctl->tableId);
+ else
+ return (INVALID_TABLEID);
}
/*
* LockTabRename -- allocate another tableId to the same
- * lock table.
+ * lock table.
*
* NOTES: Both the lock module and the lock chain (lchain.c)
- * module use table id's to distinguish between different
- * kinds of locks. Short term and long term locks look
- * the same to the lock table, but are handled differently
- * by the lock chain manager. This function allows the
- * client to use different tableIds when acquiring/releasing
- * short term and long term locks.
+ * module use table id's to distinguish between different
+ * kinds of locks. Short term and long term locks look
+ * the same to the lock table, but are handled differently
+ * by the lock chain manager. This function allows the
+ * client to use different tableIds when acquiring/releasing
+ * short term and long term locks.
*/
#ifdef NOT_USED
LockTableId
LockTabRename(LockTableId tableId)
{
- LockTableId newTableId;
-
- if (NumTables >= MAX_TABLES)
+ LockTableId newTableId;
+
+ if (NumTables >= MAX_TABLES)
{
- return(INVALID_TABLEID);
+ return (INVALID_TABLEID);
}
- if (AllTables[tableId] == INVALID_TABLEID)
+ if (AllTables[tableId] == INVALID_TABLEID)
{
- return(INVALID_TABLEID);
+ return (INVALID_TABLEID);
}
-
- /* other modules refer to the lock table by a tableId */
- newTableId = NumTables;
- NumTables++;
-
- AllTables[newTableId] = AllTables[tableId];
- return(newTableId);
+
+ /* other modules refer to the lock table by a tableId */
+ newTableId = NumTables;
+ NumTables++;
+
+ AllTables[newTableId] = AllTables[tableId];
+ return (newTableId);
}
+
#endif
/*
* LockAcquire -- Check for lock conflicts, sleep if conflict found,
- * set lock if/when no conflicts.
+ * set lock if/when no conflicts.
*
* Returns: TRUE if parameters are correct, FALSE otherwise.
*
* Side Effects: The lock is always acquired. No way to abort
- * a lock acquisition other than aborting the transaction.
- * Lock is recorded in the lkchain.
+ * a lock acquisition other than aborting the transaction.
+ * Lock is recorded in the lkchain.
#ifdef USER_LOCKS
- * Note on User Locks:
- * User locks are handled totally on the application side as
- * long term cooperative locks which extend beyond the normal
- * transaction boundaries. Their purpose is to indicate to an
- * application that someone is `working' on an item. So it is
- * possible to put an user lock on a tuple's oid, retrieve the
- * tuple, work on it for an hour and then update it and remove
- * the lock. While the lock is active other clients can still
- * read and write the tuple but they can be aware that it has
- * been locked at the application level by someone.
- * User locks use lock tags made of an uint16 and an uint32, for
- * example 0 and a tuple oid, or any other arbitrary pair of
- * numbers following a convention established by the application.
- * In this sense tags don't refer to tuples or database entities.
- * User locks and normal locks are completely orthogonal and
- * they don't interfere with each other, so it is possible
- * to acquire a normal lock on an user-locked tuple or user-lock
- * a tuple for which a normal write lock already exists.
- * User locks are always non blocking, therefore they are never
- * acquired if already held by another process. They must be
- * released explicitly by the application but they are released
- * automatically when a backend terminates.
- * They are indicated by a dummy tableId 0 which doesn't have
- * any table allocated but uses the normal lock table, and are
- * distinguished from normal locks for the following differences:
+ * Note on User Locks:
+ * User locks are handled totally on the application side as
+ * long term cooperative locks which extend beyond the normal
+ * transaction boundaries. Their purpose is to indicate to an
+ * application that someone is `working' on an item. So it is
+ * possible to put an user lock on a tuple's oid, retrieve the
+ * tuple, work on it for an hour and then update it and remove
+ * the lock. While the lock is active other clients can still
+ * read and write the tuple but they can be aware that it has
+ * been locked at the application level by someone.
+ * User locks use lock tags made of an uint16 and an uint32, for
+ * example 0 and a tuple oid, or any other arbitrary pair of
+ * numbers following a convention established by the application.
+ * In this sense tags don't refer to tuples or database entities.
+ * User locks and normal locks are completely orthogonal and
+ * they don't interfere with each other, so it is possible
+ * to acquire a normal lock on an user-locked tuple or user-lock
+ * a tuple for which a normal write lock already exists.
+ * User locks are always non blocking, therefore they are never
+ * acquired if already held by another process. They must be
+ * released explicitly by the application but they are released
+ * automatically when a backend terminates.
+ * They are indicated by a dummy tableId 0 which doesn't have
+ * any table allocated but uses the normal lock table, and are
+ * distinguished from normal locks for the following differences:
*
- * normal lock user lock
+ * normal lock user lock
*
- * tableId 1 0
- * tag.relId rel oid 0
- * tag.ItemPointerData.ip_blkid block id lock id2
- * tag.ItemPointerData.ip_posid tuple offset lock id1
- * xid.pid 0 backend pid
- * xid.xid current xid 0
- * persistence transaction user or backend
+ * tableId 1 0
+ * tag.relId rel oid 0
+ * tag.ItemPointerData.ip_blkid block id lock id2
+ * tag.ItemPointerData.ip_posid tuple offset lock id1
+ * xid.pid 0 backend pid
+ * xid.xid current xid 0
+ * persistence transaction user or backend
*
- * The lockt parameter can have the same values for normal locks
- * although probably only WRITE_LOCK can have some practical use.
+ * The lockt parameter can have the same values for normal locks
+ * although probably only WRITE_LOCK can have some practical use.
*
- * DZ - 4 Oct 1996
+ * DZ - 4 Oct 1996
#endif
*/
bool
-LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKT lockt)
+LockAcquire(LockTableId tableId, LOCKTAG * lockName, LOCKT lockt)
{
- XIDLookupEnt *result,item;
- HTAB *xidTable;
- bool found;
- LOCK *lock = NULL;
- SPINLOCK masterLock;
- LOCKTAB *ltable;
- int status;
- TransactionId myXid;
-
+ XIDLookupEnt *result,
+ item;
+ HTAB *xidTable;
+ bool found;
+ LOCK *lock = NULL;
+ SPINLOCK masterLock;
+ LOCKTAB *ltable;
+ int status;
+ TransactionId myXid;
+
#ifdef USER_LOCKS
- int is_user_lock;
+ int is_user_lock;
- is_user_lock = (tableId == 0);
- if (is_user_lock) {
- tableId = 1;
+ is_user_lock = (tableId == 0);
+ if (is_user_lock)
+ {
+ tableId = 1;
#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,"LockAcquire: user lock tag [%u,%u] %d",
- lockName->tupleId.ip_posid,
- ((lockName->tupleId.ip_blkid.bi_hi<<16)+
- lockName->tupleId.ip_blkid.bi_lo),
- lockt);
+ elog(NOTICE, "LockAcquire: user lock tag [%u,%u] %d",
+ lockName->tupleId.ip_posid,
+ ((lockName->tupleId.ip_blkid.bi_hi << 16) +
+ lockName->tupleId.ip_blkid.bi_lo),
+ lockt);
#endif
- }
+ }
#endif
- Assert (tableId < NumTables);
- ltable = AllTables[tableId];
- if (!ltable)
+ Assert(tableId < NumTables);
+ ltable = AllTables[tableId];
+ if (!ltable)
{
- elog(NOTICE,"LockAcquire: bad lock table %d",tableId);
- return (FALSE);
+ elog(NOTICE, "LockAcquire: bad lock table %d", tableId);
+ return (FALSE);
}
-
- if (LockingIsDisabled)
+
+ if (LockingIsDisabled)
{
- return(TRUE);
+ return (TRUE);
}
-
- LOCK_PRINT("Acquire",lockName,lockt);
- masterLock = ltable->ctl->masterLock;
-
- SpinAcquire(masterLock);
-
- Assert( ltable->lockHash->hash == tag_hash);
- lock = (LOCK *)hash_search(ltable->lockHash,(Pointer)lockName,HASH_ENTER,&found);
-
- if (! lock)
+
+ LOCK_PRINT("Acquire", lockName, lockt);
+ masterLock = ltable->ctl->masterLock;
+
+ SpinAcquire(masterLock);
+
+ Assert(ltable->lockHash->hash == tag_hash);
+ lock = (LOCK *) hash_search(ltable->lockHash, (Pointer) lockName, HASH_ENTER, &found);
+
+ if (!lock)
{
- SpinRelease(masterLock);
- elog(FATAL,"LockAcquire: lock table %d is corrupted",tableId);
- return(FALSE);
+ SpinRelease(masterLock);
+ elog(FATAL, "LockAcquire: lock table %d is corrupted", tableId);
+ return (FALSE);
}
-
- /* --------------------
- * if there was nothing else there, complete initialization
- * --------------------
- */
- if (! found)
+
+ /* --------------------
+ * if there was nothing else there, complete initialization
+ * --------------------
+ */
+ if (!found)
{
- lock->mask = 0;
- ProcQueueInit(&(lock->waitProcs));
- memset((char *)lock->holders, 0, sizeof(int)*MAX_LOCKTYPES);
- memset((char *)lock->activeHolders, 0, sizeof(int)*MAX_LOCKTYPES);
- lock->nHolding = 0;
- lock->nActive = 0;
-
- Assert(BlockIdEquals(&(lock->tag.tupleId.ip_blkid),
- &(lockName->tupleId.ip_blkid)));
-
+ lock->mask = 0;
+ ProcQueueInit(&(lock->waitProcs));
+ memset((char *) lock->holders, 0, sizeof(int) * MAX_LOCKTYPES);
+ memset((char *) lock->activeHolders, 0, sizeof(int) * MAX_LOCKTYPES);
+ lock->nHolding = 0;
+ lock->nActive = 0;
+
+ Assert(BlockIdEquals(&(lock->tag.tupleId.ip_blkid),
+ &(lockName->tupleId.ip_blkid)));
+
}
-
- /* ------------------
- * add an element to the lock queue so that we can clear the
- * locks at end of transaction.
- * ------------------
- */
- xidTable = ltable->xidHash;
- myXid = GetCurrentTransactionId();
-
- /* ------------------
- * Zero out all of the tag bytes (this clears the padding bytes for long
- * word alignment and ensures hashing consistency).
- * ------------------
- */
- memset(&item, 0, XID_TAGSIZE);
- TransactionIdStore(myXid, &item.tag.xid);
- item.tag.lock = MAKE_OFFSET(lock);
+
+ /* ------------------
+ * add an element to the lock queue so that we can clear the
+ * locks at end of transaction.
+ * ------------------
+ */
+ xidTable = ltable->xidHash;
+ myXid = GetCurrentTransactionId();
+
+ /* ------------------
+ * Zero out all of the tag bytes (this clears the padding bytes for long
+ * word alignment and ensures hashing consistency).
+ * ------------------
+ */
+ memset(&item, 0, XID_TAGSIZE);
+ TransactionIdStore(myXid, &item.tag.xid);
+ item.tag.lock = MAKE_OFFSET(lock);
#if 0
- item.tag.pid = MyPid;
+ item.tag.pid = MyPid;
#endif
-
+
#ifdef USER_LOCKS
- if (is_user_lock) {
- item.tag.pid = getpid();
- item.tag.xid = myXid = 0;
+ if (is_user_lock)
+ {
+ item.tag.pid = getpid();
+ item.tag.xid = myXid = 0;
#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,"LockAcquire: user lock xid [%d,%d,%d]",
- item.tag.lock, item.tag.pid, item.tag.xid);
+ elog(NOTICE, "LockAcquire: user lock xid [%d,%d,%d]",
+ item.tag.lock, item.tag.pid, item.tag.xid);
#endif
- }
+ }
#endif
- result = (XIDLookupEnt *)hash_search(xidTable, (Pointer)&item, HASH_ENTER, &found);
- if (!result)
+ result = (XIDLookupEnt *) hash_search(xidTable, (Pointer) & item, HASH_ENTER, &found);
+ if (!result)
{
- elog(NOTICE,"LockAcquire: xid table corrupted");
- return(STATUS_ERROR);
+ elog(NOTICE, "LockAcquire: xid table corrupted");
+ return (STATUS_ERROR);
}
- if (!found)
+ if (!found)
{
- XID_PRINT("LockAcquire: queueing XidEnt", result);
- ProcAddLock(&result->queue);
- result->nHolding = 0;
- memset((char *)result->holders, 0, sizeof(int)*MAX_LOCKTYPES);
+ XID_PRINT("LockAcquire: queueing XidEnt", result);
+ ProcAddLock(&result->queue);
+ result->nHolding = 0;
+ memset((char *) result->holders, 0, sizeof(int) * MAX_LOCKTYPES);
}
-
- /* ----------------
- * lock->nholding tells us how many processes have _tried_ to
- * acquire this lock, Regardless of whether they succeeded or
- * failed in doing so.
- * ----------------
- */
- lock->nHolding++;
- lock->holders[lockt]++;
-
- /* --------------------
- * If I'm the only one holding a lock, then there
- * cannot be a conflict. Need to subtract one from the
- * lock's count since we just bumped the count up by 1
- * above.
- * --------------------
- */
- if (result->nHolding == lock->nActive)
+
+ /* ----------------
+ * lock->nholding tells us how many processes have _tried_ to
+ * acquire this lock, Regardless of whether they succeeded or
+ * failed in doing so.
+ * ----------------
+ */
+ lock->nHolding++;
+ lock->holders[lockt]++;
+
+ /* --------------------
+ * If I'm the only one holding a lock, then there
+ * cannot be a conflict. Need to subtract one from the
+ * lock's count since we just bumped the count up by 1
+ * above.
+ * --------------------
+ */
+ if (result->nHolding == lock->nActive)
{
- result->holders[lockt]++;
- result->nHolding++;
- GrantLock(lock, lockt);
- SpinRelease(masterLock);
- return(TRUE);
+ result->holders[lockt]++;
+ result->nHolding++;
+ GrantLock(lock, lockt);
+ SpinRelease(masterLock);
+ return (TRUE);
}
-
- Assert(result->nHolding <= lock->nActive);
-
- status = LockResolveConflicts(ltable, lock, lockt, myXid);
-
- if (status == STATUS_OK)
+
+ Assert(result->nHolding <= lock->nActive);
+
+ status = LockResolveConflicts(ltable, lock, lockt, myXid);
+
+ if (status == STATUS_OK)
{
- GrantLock(lock, lockt);
+ GrantLock(lock, lockt);
}
- else if (status == STATUS_FOUND)
+ else if (status == STATUS_FOUND)
{
#ifdef USER_LOCKS
- /*
- * User locks are non blocking. If we can't acquire a lock
- * remove the xid entry and return FALSE without waiting.
- */
- if (is_user_lock) {
- if (!result->nHolding) {
- SHMQueueDelete(&result->queue);
- hash_search(xidTable, (Pointer)&item, HASH_REMOVE, &found);
- }
- lock->nHolding--;
- lock->holders[lockt]--;
- SpinRelease(masterLock);
+
+ /*
+ * User locks are non blocking. If we can't acquire a lock remove
+ * the xid entry and return FALSE without waiting.
+ */
+ if (is_user_lock)
+ {
+ if (!result->nHolding)
+ {
+ SHMQueueDelete(&result->queue);
+ hash_search(xidTable, (Pointer) & item, HASH_REMOVE, &found);
+ }
+ lock->nHolding--;
+ lock->holders[lockt]--;
+ SpinRelease(masterLock);
#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,"LockAcquire: user lock failed");
+ elog(NOTICE, "LockAcquire: user lock failed");
#endif
- return(FALSE);
- }
+ return (FALSE);
+ }
#endif
- status = WaitOnLock(ltable, tableId, lock, lockt);
- XID_PRINT("Someone granted me the lock", result);
+ status = WaitOnLock(ltable, tableId, lock, lockt);
+ XID_PRINT("Someone granted me the lock", result);
}
-
- SpinRelease(masterLock);
-
- return(status == STATUS_OK);
+
+ SpinRelease(masterLock);
+
+ return (status == STATUS_OK);
}
/* ----------------------------
* LockResolveConflicts -- test for lock conflicts
*
* NOTES:
- * Here's what makes this complicated: one transaction's
+ * Here's what makes this complicated: one transaction's
* locks don't conflict with one another. When many processes
* hold locks, each has to subtract off the other's locks when
* determining whether or not any new lock acquired conflicts with
* the old ones.
*
- * For example, if I am already holding a WRITE_INTENT lock,
- * there will not be a conflict with my own READ_LOCK. If I
- * don't consider the intent lock when checking for conflicts,
- * I find no conflict.
+ * For example, if I am already holding a WRITE_INTENT lock,
+ * there will not be a conflict with my own READ_LOCK. If I
+ * don't consider the intent lock when checking for conflicts,
+ * I find no conflict.
* ----------------------------
*/
int
-LockResolveConflicts(LOCKTAB *ltable,
- LOCK *lock,
- LOCKT lockt,
- TransactionId xid)
+LockResolveConflicts(LOCKTAB * ltable,
+ LOCK * lock,
+ LOCKT lockt,
+ TransactionId xid)
{
- XIDLookupEnt *result,item;
- int *myHolders;
- int nLockTypes;
- HTAB *xidTable;
- bool found;
- int bitmask;
- int i,tmpMask;
-
- nLockTypes = ltable->ctl->nLockTypes;
- xidTable = ltable->xidHash;
-
- /* ---------------------
- * read my own statistics from the xid table. If there
- * isn't an entry, then we'll just add one.
- *
- * Zero out the tag, this clears the padding bytes for long
- * word alignment and ensures hashing consistency.
- * ------------------
- */
- memset(&item, 0, XID_TAGSIZE);
- TransactionIdStore(xid, &item.tag.xid);
- item.tag.lock = MAKE_OFFSET(lock);
+ XIDLookupEnt *result,
+ item;
+ int *myHolders;
+ int nLockTypes;
+ HTAB *xidTable;
+ bool found;
+ int bitmask;
+ int i,
+ tmpMask;
+
+ nLockTypes = ltable->ctl->nLockTypes;
+ xidTable = ltable->xidHash;
+
+ /* ---------------------
+ * read my own statistics from the xid table. If there
+ * isn't an entry, then we'll just add one.
+ *
+ * Zero out the tag, this clears the padding bytes for long
+ * word alignment and ensures hashing consistency.
+ * ------------------
+ */
+ memset(&item, 0, XID_TAGSIZE);
+ TransactionIdStore(xid, &item.tag.xid);
+ item.tag.lock = MAKE_OFFSET(lock);
#if 0
- item.tag.pid = pid;
+ item.tag.pid = pid;
#endif
-
- if (! (result = (XIDLookupEnt *)
- hash_search(xidTable, (Pointer)&item, HASH_ENTER, &found)))
+
+ if (!(result = (XIDLookupEnt *)
+ hash_search(xidTable, (Pointer) & item, HASH_ENTER, &found)))
{
- elog(NOTICE,"LockResolveConflicts: xid table corrupted");
- return(STATUS_ERROR);
+ elog(NOTICE, "LockResolveConflicts: xid table corrupted");
+ return (STATUS_ERROR);
}
- myHolders = result->holders;
-
- if (! found)
+ myHolders = result->holders;
+
+ if (!found)
{
- /* ---------------
- * we're not holding any type of lock yet. Clear
- * the lock stats.
- * ---------------
- */
- memset(result->holders, 0, nLockTypes * sizeof(*(lock->holders)));
- result->nHolding = 0;
+ /* ---------------
+ * we're not holding any type of lock yet. Clear
+ * the lock stats.
+ * ---------------
+ */
+ memset(result->holders, 0, nLockTypes * sizeof(*(lock->holders)));
+ result->nHolding = 0;
}
-
- /* ----------------------------
- * first check for global conflicts: If no locks conflict
- * with mine, then I get the lock.
- *
- * Checking for conflict: lock->mask represents the types of
- * currently held locks. conflictTable[lockt] has a bit
- * set for each type of lock that conflicts with mine. Bitwise
- * compare tells if there is a conflict.
- * ----------------------------
- */
- if (! (ltable->ctl->conflictTab[lockt] & lock->mask))
+
+ /* ----------------------------
+ * first check for global conflicts: If no locks conflict
+ * with mine, then I get the lock.
+ *
+ * Checking for conflict: lock->mask represents the types of
+ * currently held locks. conflictTable[lockt] has a bit
+ * set for each type of lock that conflicts with mine. Bitwise
+ * compare tells if there is a conflict.
+ * ----------------------------
+ */
+ if (!(ltable->ctl->conflictTab[lockt] & lock->mask))
{
-
- result->holders[lockt]++;
- result->nHolding++;
-
- XID_PRINT("Conflict Resolved: updated xid entry stats", result);
-
- return(STATUS_OK);
+
+ result->holders[lockt]++;
+ result->nHolding++;
+
+ XID_PRINT("Conflict Resolved: updated xid entry stats", result);
+
+ return (STATUS_OK);
}
-
- /* ------------------------
- * Rats. Something conflicts. But it could still be my own
- * lock. We have to construct a conflict mask
- * that does not reflect our own locks.
- * ------------------------
- */
- bitmask = 0;
- tmpMask = 2;
- for (i=1;i<=nLockTypes;i++, tmpMask <<= 1)
+
+ /* ------------------------
+ * Rats. Something conflicts. But it could still be my own
+ * lock. We have to construct a conflict mask
+ * that does not reflect our own locks.
+ * ------------------------
+ */
+ bitmask = 0;
+ tmpMask = 2;
+ for (i = 1; i <= nLockTypes; i++, tmpMask <<= 1)
{
- if (lock->activeHolders[i] - myHolders[i])
+ if (lock->activeHolders[i] - myHolders[i])
{
- bitmask |= tmpMask;
+ bitmask |= tmpMask;
}
}
-
- /* ------------------------
- * now check again for conflicts. 'bitmask' describes the types
- * of locks held by other processes. If one of these
- * conflicts with the kind of lock that I want, there is a
- * conflict and I have to sleep.
- * ------------------------
- */
- if (! (ltable->ctl->conflictTab[lockt] & bitmask))
+
+ /* ------------------------
+ * now check again for conflicts. 'bitmask' describes the types
+ * of locks held by other processes. If one of these
+ * conflicts with the kind of lock that I want, there is a
+ * conflict and I have to sleep.
+ * ------------------------
+ */
+ if (!(ltable->ctl->conflictTab[lockt] & bitmask))
{
-
- /* no conflict. Get the lock and go on */
-
- result->holders[lockt]++;
- result->nHolding++;
-
- XID_PRINT("Conflict Resolved: updated xid entry stats", result);
-
- return(STATUS_OK);
-
+
+ /* no conflict. Get the lock and go on */
+
+ result->holders[lockt]++;
+ result->nHolding++;
+
+ XID_PRINT("Conflict Resolved: updated xid entry stats", result);
+
+ return (STATUS_OK);
+
}
-
- return(STATUS_FOUND);
+
+ return (STATUS_FOUND);
}
static int
-WaitOnLock(LOCKTAB *ltable, LockTableId tableId, LOCK *lock, LOCKT lockt)
+WaitOnLock(LOCKTAB * ltable, LockTableId tableId, LOCK * lock, LOCKT lockt)
{
- PROC_QUEUE *waitQueue = &(lock->waitProcs);
-
- int prio = ltable->ctl->prio[lockt];
-
- /* the waitqueue is ordered by priority. I insert myself
- * according to the priority of the lock I am acquiring.
- *
- * SYNC NOTE: I am assuming that the lock table spinlock
- * is sufficient synchronization for this queue. That
- * will not be true if/when people can be deleted from
- * the queue by a SIGINT or something.
- */
- LOCK_DUMP_AUX("WaitOnLock: sleeping on lock", lock, lockt);
- if (ProcSleep(waitQueue,
- ltable->ctl->masterLock,
- lockt,
- prio,
- lock) != NO_ERROR)
+ PROC_QUEUE *waitQueue = &(lock->waitProcs);
+
+ int prio = ltable->ctl->prio[lockt];
+
+ /*
+ * the waitqueue is ordered by priority. I insert myself according to
+ * the priority of the lock I am acquiring.
+ *
+ * SYNC NOTE: I am assuming that the lock table spinlock is sufficient
+ * synchronization for this queue. That will not be true if/when
+ * people can be deleted from the queue by a SIGINT or something.
+ */
+ LOCK_DUMP_AUX("WaitOnLock: sleeping on lock", lock, lockt);
+ if (ProcSleep(waitQueue,
+ ltable->ctl->masterLock,
+ lockt,
+ prio,
+ lock) != NO_ERROR)
{
- /* -------------------
- * This could have happend as a result of a deadlock, see HandleDeadLock()
- * Decrement the lock nHolding and holders fields as we are no longer
- * waiting on this lock.
- * -------------------
- */
- lock->nHolding--;
- lock->holders[lockt]--;
- LOCK_DUMP_AUX("WaitOnLock: aborting on lock", lock, lockt);
- SpinRelease(ltable->ctl->masterLock);
- elog(WARN,"WaitOnLock: error on wakeup - Aborting this transaction");
+ /* -------------------
+ * This could have happend as a result of a deadlock, see HandleDeadLock()
+ * Decrement the lock nHolding and holders fields as we are no longer
+ * waiting on this lock.
+ * -------------------
+ */
+ lock->nHolding--;
+ lock->holders[lockt]--;
+ LOCK_DUMP_AUX("WaitOnLock: aborting on lock", lock, lockt);
+ SpinRelease(ltable->ctl->masterLock);
+ elog(WARN, "WaitOnLock: error on wakeup - Aborting this transaction");
}
-
- LOCK_DUMP_AUX("WaitOnLock: wakeup on lock", lock, lockt);
- return(STATUS_OK);
+
+ LOCK_DUMP_AUX("WaitOnLock: wakeup on lock", lock, lockt);
+ return (STATUS_OK);
}
/*
* LockRelease -- look up 'lockName' in lock table 'tableId' and
- * release it.
+ * release it.
*
* Side Effects: if the lock no longer conflicts with the highest
- * priority waiting process, that process is granted the lock
- * and awoken. (We have to grant the lock here to avoid a
- * race between the waking process and any new process to
- * come along and request the lock).
+ * priority waiting process, that process is granted the lock
+ * and awoken. (We have to grant the lock here to avoid a
+ * race between the waking process and any new process to
+ * come along and request the lock).
*/
bool
-LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKT lockt)
+LockRelease(LockTableId tableId, LOCKTAG * lockName, LOCKT lockt)
{
- LOCK *lock = NULL;
- SPINLOCK masterLock;
- bool found;
- LOCKTAB *ltable;
- XIDLookupEnt *result,item;
- HTAB *xidTable;
- bool wakeupNeeded = true;
-
+ LOCK *lock = NULL;
+ SPINLOCK masterLock;
+ bool found;
+ LOCKTAB *ltable;
+ XIDLookupEnt *result,
+ item;
+ HTAB *xidTable;
+ bool wakeupNeeded = true;
+
#ifdef USER_LOCKS
- int is_user_lock;
+ int is_user_lock;
- is_user_lock = (tableId == 0);
- if (is_user_lock) {
- tableId = 1;
+ is_user_lock = (tableId == 0);
+ if (is_user_lock)
+ {
+ tableId = 1;
#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,"LockRelease: user lock tag [%u,%u] %d",
- lockName->tupleId.ip_posid,
- ((lockName->tupleId.ip_blkid.bi_hi<<16)+
- lockName->tupleId.ip_blkid.bi_lo),
- lockt);
+ elog(NOTICE, "LockRelease: user lock tag [%u,%u] %d",
+ lockName->tupleId.ip_posid,
+ ((lockName->tupleId.ip_blkid.bi_hi << 16) +
+ lockName->tupleId.ip_blkid.bi_lo),
+ lockt);
#endif
- }
+ }
#endif
- Assert (tableId < NumTables);
- ltable = AllTables[tableId];
- if (!ltable) {
- elog(NOTICE, "ltable is null in LockRelease");
- return (FALSE);
- }
-
- if (LockingIsDisabled)
+ Assert(tableId < NumTables);
+ ltable = AllTables[tableId];
+ if (!ltable)
+ {
+ elog(NOTICE, "ltable is null in LockRelease");
+ return (FALSE);
+ }
+
+ if (LockingIsDisabled)
{
- return(TRUE);
+ return (TRUE);
}
-
- LOCK_PRINT("Release",lockName,lockt);
-
- masterLock = ltable->ctl->masterLock;
- xidTable = ltable->xidHash;
-
- SpinAcquire(masterLock);
-
- Assert( ltable->lockHash->hash == tag_hash);
- lock = (LOCK *)
- hash_search(ltable->lockHash,(Pointer)lockName,HASH_FIND_SAVE,&found);
-
+
+ LOCK_PRINT("Release", lockName, lockt);
+
+ masterLock = ltable->ctl->masterLock;
+ xidTable = ltable->xidHash;
+
+ SpinAcquire(masterLock);
+
+ Assert(ltable->lockHash->hash == tag_hash);
+ lock = (LOCK *)
+ hash_search(ltable->lockHash, (Pointer) lockName, HASH_FIND_SAVE, &found);
+
#ifdef USER_LOCKS
- /*
- * If the entry is not found hash_search returns TRUE
- * instead of NULL, so we must check it explicitly.
- */
- if ((is_user_lock) && (lock == (LOCK *)TRUE)) {
- SpinRelease(masterLock);
- elog(NOTICE,"LockRelease: there are no locks with this tag");
- return(FALSE);
- }
+
+ /*
+ * If the entry is not found hash_search returns TRUE instead of NULL,
+ * so we must check it explicitly.
+ */
+ if ((is_user_lock) && (lock == (LOCK *) TRUE))
+ {
+ SpinRelease(masterLock);
+ elog(NOTICE, "LockRelease: there are no locks with this tag");
+ return (FALSE);
+ }
#endif
- /* let the caller print its own error message, too.
- * Do not elog(WARN).
- */
- if (! lock)
+ /*
+ * let the caller print its own error message, too. Do not elog(WARN).
+ */
+ if (!lock)
{
- SpinRelease(masterLock);
- elog(NOTICE,"LockRelease: locktable corrupted");
- return(FALSE);
+ SpinRelease(masterLock);
+ elog(NOTICE, "LockRelease: locktable corrupted");
+ return (FALSE);
}
-
- if (! found)
+
+ if (!found)
{
- SpinRelease(masterLock);
- elog(NOTICE,"LockRelease: locktable lookup failed, no lock");
- return(FALSE);
+ SpinRelease(masterLock);
+ elog(NOTICE, "LockRelease: locktable lookup failed, no lock");
+ return (FALSE);
}
-
- Assert(lock->nHolding > 0);
-
+
+ Assert(lock->nHolding > 0);
+
#ifdef USER_LOCKS
- /*
- * If this is an user lock it can be removed only after
- * checking that it was acquired by the current process,
- * so this code is skipped and executed later.
- */
- if (!is_user_lock) {
-#endif
- /*
- * fix the general lock stats
- */
- lock->nHolding--;
- lock->holders[lockt]--;
- lock->nActive--;
- lock->activeHolders[lockt]--;
-
- Assert(lock->nActive >= 0);
-
- if (! lock->nHolding)
+
+ /*
+ * If this is an user lock it can be removed only after checking that
+ * it was acquired by the current process, so this code is skipped and
+ * executed later.
+ */
+ if (!is_user_lock)
{
- /* ------------------
- * if there's no one waiting in the queue,
- * we just released the last lock.
- * Delete it from the lock table.
- * ------------------
- */
- Assert( ltable->lockHash->hash == tag_hash);
- lock = (LOCK *) hash_search(ltable->lockHash,
- (Pointer) &(lock->tag),
- HASH_REMOVE_SAVED,
- &found);
- Assert(lock && found);
- wakeupNeeded = false;
- }
+#endif
+
+ /*
+ * fix the general lock stats
+ */
+ lock->nHolding--;
+ lock->holders[lockt]--;
+ lock->nActive--;
+ lock->activeHolders[lockt]--;
+
+ Assert(lock->nActive >= 0);
+
+ if (!lock->nHolding)
+ {
+ /* ------------------
+ * if there's no one waiting in the queue,
+ * we just released the last lock.
+ * Delete it from the lock table.
+ * ------------------
+ */
+ Assert(ltable->lockHash->hash == tag_hash);
+ lock = (LOCK *) hash_search(ltable->lockHash,
+ (Pointer) & (lock->tag),
+ HASH_REMOVE_SAVED,
+ &found);
+ Assert(lock && found);
+ wakeupNeeded = false;
+ }
#ifdef USER_LOCKS
- }
+ }
#endif
-
- /* ------------------
- * Zero out all of the tag bytes (this clears the padding bytes for long
- * word alignment and ensures hashing consistency).
- * ------------------
- */
- memset(&item, 0, XID_TAGSIZE);
-
- TransactionIdStore(GetCurrentTransactionId(), &item.tag.xid);
- item.tag.lock = MAKE_OFFSET(lock);
+
+ /* ------------------
+ * Zero out all of the tag bytes (this clears the padding bytes for long
+ * word alignment and ensures hashing consistency).
+ * ------------------
+ */
+ memset(&item, 0, XID_TAGSIZE);
+
+ TransactionIdStore(GetCurrentTransactionId(), &item.tag.xid);
+ item.tag.lock = MAKE_OFFSET(lock);
#if 0
- item.tag.pid = MyPid;
+ item.tag.pid = MyPid;
#endif
-
+
#ifdef USER_LOCKS
- if (is_user_lock) {
- item.tag.pid = getpid();
- item.tag.xid = 0;
+ if (is_user_lock)
+ {
+ item.tag.pid = getpid();
+ item.tag.xid = 0;
#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,"LockRelease: user lock xid [%d,%d,%d]",
- item.tag.lock, item.tag.pid, item.tag.xid);
+ elog(NOTICE, "LockRelease: user lock xid [%d,%d,%d]",
+ item.tag.lock, item.tag.pid, item.tag.xid);
#endif
- }
+ }
#endif
- if (! ( result = (XIDLookupEnt *) hash_search(xidTable,
- (Pointer)&item,
- HASH_FIND_SAVE,
- &found) )
- || !found)
+ if (!(result = (XIDLookupEnt *) hash_search(xidTable,
+ (Pointer) & item,
+ HASH_FIND_SAVE,
+ &found))
+ || !found)
{
- SpinRelease(masterLock);
+ SpinRelease(masterLock);
#ifdef USER_LOCKS
- if ((is_user_lock) && (result)) {
- elog(NOTICE,"LockRelease: you don't have a lock on this tag");
- } else {
- elog(NOTICE,"LockRelease: find xid, table corrupted");
- }
+ if ((is_user_lock) && (result))
+ {
+ elog(NOTICE, "LockRelease: you don't have a lock on this tag");
+ }
+ else
+ {
+ elog(NOTICE, "LockRelease: find xid, table corrupted");
+ }
#else
- elog(NOTICE,"LockReplace: xid table corrupted");
+ elog(NOTICE, "LockReplace: xid table corrupted");
#endif
- return(FALSE);
+ return (FALSE);
}
- /*
- * now check to see if I have any private locks. If I do,
- * decrement the counts associated with them.
- */
- result->holders[lockt]--;
- result->nHolding--;
-
- XID_PRINT("LockRelease updated xid stats", result);
-
- /*
- * If this was my last hold on this lock, delete my entry
- * in the XID table.
- */
- if (! result->nHolding)
+
+ /*
+ * now check to see if I have any private locks. If I do, decrement
+ * the counts associated with them.
+ */
+ result->holders[lockt]--;
+ result->nHolding--;
+
+ XID_PRINT("LockRelease updated xid stats", result);
+
+ /*
+ * If this was my last hold on this lock, delete my entry in the XID
+ * table.
+ */
+ if (!result->nHolding)
{
#ifdef USER_LOCKS
- if (result->queue.prev == INVALID_OFFSET) {
- elog(NOTICE,"LockRelease: xid.prev == INVALID_OFFSET");
- }
- if (result->queue.next == INVALID_OFFSET) {
- elog(NOTICE,"LockRelease: xid.next == INVALID_OFFSET");
- }
+ if (result->queue.prev == INVALID_OFFSET)
+ {
+ elog(NOTICE, "LockRelease: xid.prev == INVALID_OFFSET");
+ }
+ if (result->queue.next == INVALID_OFFSET)
+ {
+ elog(NOTICE, "LockRelease: xid.next == INVALID_OFFSET");
+ }
#endif
- if (result->queue.next != INVALID_OFFSET)
- SHMQueueDelete(&result->queue);
- if (! (result = (XIDLookupEnt *)
- hash_search(xidTable, (Pointer)&item, HASH_REMOVE_SAVED, &found)) ||
- ! found)
+ if (result->queue.next != INVALID_OFFSET)
+ SHMQueueDelete(&result->queue);
+ if (!(result = (XIDLookupEnt *)
+ hash_search(xidTable, (Pointer) & item, HASH_REMOVE_SAVED, &found)) ||
+ !found)
{
- SpinRelease(masterLock);
+ SpinRelease(masterLock);
#ifdef USER_LOCKS
- elog(NOTICE,"LockRelease: remove xid, table corrupted");
+ elog(NOTICE, "LockRelease: remove xid, table corrupted");
#else
- elog(NOTICE,"LockReplace: xid table corrupted");
+ elog(NOTICE, "LockReplace: xid table corrupted");
#endif
- return(FALSE);
+ return (FALSE);
}
}
-
+
#ifdef USER_LOCKS
- /*
- * If this is an user lock remove it now, after the
- * corresponding xid entry has been found and deleted.
- */
- if (is_user_lock) {
- /*
- * fix the general lock stats
- */
- lock->nHolding--;
- lock->holders[lockt]--;
- lock->nActive--;
- lock->activeHolders[lockt]--;
-
- Assert(lock->nActive >= 0);
-
- if (! lock->nHolding)
+
+ /*
+ * If this is an user lock remove it now, after the corresponding xid
+ * entry has been found and deleted.
+ */
+ if (is_user_lock)
{
- /* ------------------
- * if there's no one waiting in the queue,
- * we just released the last lock.
- * Delete it from the lock table.
- * ------------------
- */
- Assert( ltable->lockHash->hash == tag_hash);
- lock = (LOCK *) hash_search(ltable->lockHash,
- (Pointer) &(lock->tag),
- HASH_REMOVE,
- &found);
- Assert(lock && found);
- wakeupNeeded = false;
+
+ /*
+ * fix the general lock stats
+ */
+ lock->nHolding--;
+ lock->holders[lockt]--;
+ lock->nActive--;
+ lock->activeHolders[lockt]--;
+
+ Assert(lock->nActive >= 0);
+
+ if (!lock->nHolding)
+ {
+ /* ------------------
+ * if there's no one waiting in the queue,
+ * we just released the last lock.
+ * Delete it from the lock table.
+ * ------------------
+ */
+ Assert(ltable->lockHash->hash == tag_hash);
+ lock = (LOCK *) hash_search(ltable->lockHash,
+ (Pointer) & (lock->tag),
+ HASH_REMOVE,
+ &found);
+ Assert(lock && found);
+ wakeupNeeded = false;
+ }
}
- }
#endif
- /* --------------------------
- * If there are still active locks of the type I just released, no one
- * should be woken up. Whoever is asleep will still conflict
- * with the remaining locks.
- * --------------------------
- */
- if (! (lock->activeHolders[lockt]))
+ /* --------------------------
+ * If there are still active locks of the type I just released, no one
+ * should be woken up. Whoever is asleep will still conflict
+ * with the remaining locks.
+ * --------------------------
+ */
+ if (!(lock->activeHolders[lockt]))
{
- /* change the conflict mask. No more of this lock type. */
- lock->mask &= BITS_OFF[lockt];
+ /* change the conflict mask. No more of this lock type. */
+ lock->mask &= BITS_OFF[lockt];
}
-
- if (wakeupNeeded)
+
+ if (wakeupNeeded)
{
- /* --------------------------
- * Wake the first waiting process and grant him the lock if it
- * doesn't conflict. The woken process must record the lock
- * himself.
- * --------------------------
- */
- ProcLockWakeup(&(lock->waitProcs), (char *) ltable, (char *) lock);
+ /* --------------------------
+ * Wake the first waiting process and grant him the lock if it
+ * doesn't conflict. The woken process must record the lock
+ * himself.
+ * --------------------------
+ */
+ ProcLockWakeup(&(lock->waitProcs), (char *) ltable, (char *) lock);
}
-
- SpinRelease(masterLock);
- return(TRUE);
+
+ SpinRelease(masterLock);
+ return (TRUE);
}
/*
* GrantLock -- udpate the lock data structure to show
- * the new lock holder.
+ * the new lock holder.
*/
void
-GrantLock(LOCK *lock, LOCKT lockt)
+GrantLock(LOCK * lock, LOCKT lockt)
{
- lock->nActive++;
- lock->activeHolders[lockt]++;
- lock->mask |= BITS_ON[lockt];
+ lock->nActive++;
+ lock->activeHolders[lockt]++;
+ lock->mask |= BITS_ON[lockt];
}
#ifdef USER_LOCKS
@@ -1086,265 +1115,281 @@ GrantLock(LOCK *lock, LOCKT lockt)
* LockReleaseAll -- Release all locks in a process lock queue.
*
* Note: This code is a little complicated by the presence in the
- * same queue of user locks which can't be removed from the
- * normal lock queue at the end of a transaction. They must
- * however be removed when the backend exits.
- * A dummy tableId 0 is used to indicate that we are releasing
- * the user locks, from the code added to ProcKill().
+ * same queue of user locks which can't be removed from the
+ * normal lock queue at the end of a transaction. They must
+ * however be removed when the backend exits.
+ * A dummy tableId 0 is used to indicate that we are releasing
+ * the user locks, from the code added to ProcKill().
*/
#endif
bool
-LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue)
+LockReleaseAll(LockTableId tableId, SHM_QUEUE * lockQueue)
{
- PROC_QUEUE *waitQueue;
- int done;
- XIDLookupEnt *xidLook = NULL;
- XIDLookupEnt *tmp = NULL;
- SHMEM_OFFSET end = MAKE_OFFSET(lockQueue);
- SPINLOCK masterLock;
- LOCKTAB *ltable;
- int i,nLockTypes;
- LOCK *lock;
- bool found;
-
+ PROC_QUEUE *waitQueue;
+ int done;
+ XIDLookupEnt *xidLook = NULL;
+ XIDLookupEnt *tmp = NULL;
+ SHMEM_OFFSET end = MAKE_OFFSET(lockQueue);
+ SPINLOCK masterLock;
+ LOCKTAB *ltable;
+ int i,
+ nLockTypes;
+ LOCK *lock;
+ bool found;
+
#ifdef USER_LOCKS
- int is_user_lock_table, my_pid, count, nskip;
+ int is_user_lock_table,
+ my_pid,
+ count,
+ nskip;
- is_user_lock_table = (tableId == 0);
- my_pid = getpid();
+ is_user_lock_table = (tableId == 0);
+ my_pid = getpid();
#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,"LockReleaseAll: tableId=%d, pid=%d", tableId, my_pid);
+ elog(NOTICE, "LockReleaseAll: tableId=%d, pid=%d", tableId, my_pid);
#endif
- if (is_user_lock_table) {
- tableId = 1;
- }
+ if (is_user_lock_table)
+ {
+ tableId = 1;
+ }
#endif
- Assert (tableId < NumTables);
- ltable = AllTables[tableId];
- if (!ltable)
- return (FALSE);
-
- nLockTypes = ltable->ctl->nLockTypes;
- masterLock = ltable->ctl->masterLock;
-
- if (SHMQueueEmpty(lockQueue))
- return TRUE;
-
+ Assert(tableId < NumTables);
+ ltable = AllTables[tableId];
+ if (!ltable)
+ return (FALSE);
+
+ nLockTypes = ltable->ctl->nLockTypes;
+ masterLock = ltable->ctl->masterLock;
+
+ if (SHMQueueEmpty(lockQueue))
+ return TRUE;
+
#ifdef USER_LOCKS
- SpinAcquire(masterLock);
+ SpinAcquire(masterLock);
#endif
- SHMQueueFirst(lockQueue,(Pointer*)&xidLook,&xidLook->queue);
-
- XID_PRINT("LockReleaseAll", xidLook);
-
+ SHMQueueFirst(lockQueue, (Pointer *) & xidLook, &xidLook->queue);
+
+ XID_PRINT("LockReleaseAll", xidLook);
+
#ifndef USER_LOCKS
- SpinAcquire(masterLock);
+ SpinAcquire(masterLock);
#else
- count = nskip = 0;
+ count = nskip = 0;
#endif
- for (;;)
+ for (;;)
{
- /* ---------------------------
- * XXX Here we assume the shared memory queue is circular and
- * that we know its internal structure. Should have some sort of
- * macros to allow one to walk it. mer 20 July 1991
- * ---------------------------
- */
- done = (xidLook->queue.next == end);
- lock = (LOCK *) MAKE_PTR(xidLook->tag.lock);
-
- LOCK_PRINT("ReleaseAll",(&lock->tag),0);
-
+ /* ---------------------------
+ * XXX Here we assume the shared memory queue is circular and
+ * that we know its internal structure. Should have some sort of
+ * macros to allow one to walk it. mer 20 July 1991
+ * ---------------------------
+ */
+ done = (xidLook->queue.next == end);
+ lock = (LOCK *) MAKE_PTR(xidLook->tag.lock);
+
+ LOCK_PRINT("ReleaseAll", (&lock->tag), 0);
+
#ifdef USER_LOCKS
- /*
- * Sometimes the queue appears to be messed up.
- */
- if (count++ > 2000) {
- elog(NOTICE,"LockReleaseAll: xid loop detected, giving up");
- nskip = 0;
- break;
- }
- if (is_user_lock_table) {
- if ((xidLook->tag.pid == 0) || (xidLook->tag.xid != 0)) {
-#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,"LockReleaseAll: skip normal lock [%d,%d,%d]",
- xidLook->tag.lock,xidLook->tag.pid,xidLook->tag.xid);
-#endif
- nskip++;
- goto next_item;
+
+ /*
+ * Sometimes the queue appears to be messed up.
+ */
+ if (count++ > 2000)
+ {
+ elog(NOTICE, "LockReleaseAll: xid loop detected, giving up");
+ nskip = 0;
+ break;
}
- if (xidLook->tag.pid != my_pid) {
- /* This should never happen */
+ if (is_user_lock_table)
+ {
+ if ((xidLook->tag.pid == 0) || (xidLook->tag.xid != 0))
+ {
#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,
- "LockReleaseAll: skip other pid [%u,%u] [%d,%d,%d]",
- lock->tag.tupleId.ip_posid,
- ((lock->tag.tupleId.ip_blkid.bi_hi<<16)+
- lock->tag.tupleId.ip_blkid.bi_lo),
- xidLook->tag.lock,xidLook->tag.pid,xidLook->tag.xid);
+ elog(NOTICE, "LockReleaseAll: skip normal lock [%d,%d,%d]",
+ xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
#endif
- nskip++;
- goto next_item;
- }
+ nskip++;
+ goto next_item;
+ }
+ if (xidLook->tag.pid != my_pid)
+ {
+ /* This should never happen */
#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,
- "LockReleaseAll: release user lock [%u,%u] [%d,%d,%d]",
- lock->tag.tupleId.ip_posid,
- ((lock->tag.tupleId.ip_blkid.bi_hi<<16)+
- lock->tag.tupleId.ip_blkid.bi_lo),
- xidLook->tag.lock,xidLook->tag.pid,xidLook->tag.xid);
+ elog(NOTICE,
+ "LockReleaseAll: skip other pid [%u,%u] [%d,%d,%d]",
+ lock->tag.tupleId.ip_posid,
+ ((lock->tag.tupleId.ip_blkid.bi_hi << 16) +
+ lock->tag.tupleId.ip_blkid.bi_lo),
+ xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
#endif
- } else {
- if ((xidLook->tag.pid != 0) || (xidLook->tag.xid == 0)) {
+ nskip++;
+ goto next_item;
+ }
#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,
- "LockReleaseAll: skip user lock [%u,%u] [%d,%d,%d]",
- lock->tag.tupleId.ip_posid,
- ((lock->tag.tupleId.ip_blkid.bi_hi<<16)+
- lock->tag.tupleId.ip_blkid.bi_lo),
- xidLook->tag.lock,xidLook->tag.pid,xidLook->tag.xid);
+ elog(NOTICE,
+ "LockReleaseAll: release user lock [%u,%u] [%d,%d,%d]",
+ lock->tag.tupleId.ip_posid,
+ ((lock->tag.tupleId.ip_blkid.bi_hi << 16) +
+ lock->tag.tupleId.ip_blkid.bi_lo),
+ xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
#endif
- nskip++;
- goto next_item;
}
+ else
+ {
+ if ((xidLook->tag.pid != 0) || (xidLook->tag.xid == 0))
+ {
#ifdef USER_LOCKS_DEBUG
- elog(NOTICE,"LockReleaseAll: release normal lock [%d,%d,%d]",
- xidLook->tag.lock,xidLook->tag.pid,xidLook->tag.xid);
+ elog(NOTICE,
+ "LockReleaseAll: skip user lock [%u,%u] [%d,%d,%d]",
+ lock->tag.tupleId.ip_posid,
+ ((lock->tag.tupleId.ip_blkid.bi_hi << 16) +
+ lock->tag.tupleId.ip_blkid.bi_lo),
+ xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
#endif
- }
+ nskip++;
+ goto next_item;
+ }
+#ifdef USER_LOCKS_DEBUG
+ elog(NOTICE, "LockReleaseAll: release normal lock [%d,%d,%d]",
+ xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
+#endif
+ }
#endif
- /* ------------------
- * fix the general lock stats
- * ------------------
- */
- if (lock->nHolding != xidLook->nHolding)
+ /* ------------------
+ * fix the general lock stats
+ * ------------------
+ */
+ if (lock->nHolding != xidLook->nHolding)
{
- lock->nHolding -= xidLook->nHolding;
- lock->nActive -= xidLook->nHolding;
- Assert(lock->nActive >= 0);
- for (i=1; i<=nLockTypes; i++)
+ lock->nHolding -= xidLook->nHolding;
+ lock->nActive -= xidLook->nHolding;
+ Assert(lock->nActive >= 0);
+ for (i = 1; i <= nLockTypes; i++)
{
- lock->holders[i] -= xidLook->holders[i];
- lock->activeHolders[i] -= xidLook->holders[i];
- if (! lock->activeHolders[i])
- lock->mask &= BITS_OFF[i];
+ lock->holders[i] -= xidLook->holders[i];
+ lock->activeHolders[i] -= xidLook->holders[i];
+ if (!lock->activeHolders[i])
+ lock->mask &= BITS_OFF[i];
}
}
- else
+ else
{
- /* --------------
- * set nHolding to zero so that we can garbage collect the lock
- * down below...
- * --------------
- */
- lock->nHolding = 0;
+ /* --------------
+ * set nHolding to zero so that we can garbage collect the lock
+ * down below...
+ * --------------
+ */
+ lock->nHolding = 0;
}
- /* ----------------
- * always remove the xidLookup entry, we're done with it now
- * ----------------
- */
+ /* ----------------
+ * always remove the xidLookup entry, we're done with it now
+ * ----------------
+ */
#ifdef USER_LOCKS
- SHMQueueDelete(&xidLook->queue);
+ SHMQueueDelete(&xidLook->queue);
#endif
- if ((! hash_search(ltable->xidHash, (Pointer)xidLook, HASH_REMOVE, &found))
- || !found)
+ if ((!hash_search(ltable->xidHash, (Pointer) xidLook, HASH_REMOVE, &found))
+ || !found)
{
- SpinRelease(masterLock);
+ SpinRelease(masterLock);
#ifdef USER_LOCKS
- elog(NOTICE,"LockReleaseAll: xid table corrupted");
+ elog(NOTICE, "LockReleaseAll: xid table corrupted");
#else
- elog(NOTICE,"LockReplace: xid table corrupted");
+ elog(NOTICE, "LockReplace: xid table corrupted");
#endif
- return(FALSE);
+ return (FALSE);
}
-
- if (! lock->nHolding)
+
+ if (!lock->nHolding)
{
- /* --------------------
- * if there's no one waiting in the queue, we've just released
- * the last lock.
- * --------------------
- */
-
- Assert( ltable->lockHash->hash == tag_hash);
- lock = (LOCK *)
- hash_search(ltable->lockHash,(Pointer)&(lock->tag),HASH_REMOVE, &found);
- if ((! lock) || (!found))
+ /* --------------------
+ * if there's no one waiting in the queue, we've just released
+ * the last lock.
+ * --------------------
+ */
+
+ Assert(ltable->lockHash->hash == tag_hash);
+ lock = (LOCK *)
+ hash_search(ltable->lockHash, (Pointer) & (lock->tag), HASH_REMOVE, &found);
+ if ((!lock) || (!found))
{
- SpinRelease(masterLock);
+ SpinRelease(masterLock);
#ifdef USER_LOCKS
- elog(NOTICE,"LockReleaseAll: cannot remove lock from HTAB");
+ elog(NOTICE, "LockReleaseAll: cannot remove lock from HTAB");
#else
- elog(NOTICE,"LockReplace: cannot remove lock from HTAB");
+ elog(NOTICE, "LockReplace: cannot remove lock from HTAB");
#endif
- return(FALSE);
+ return (FALSE);
}
}
- else
+ else
{
- /* --------------------
- * Wake the first waiting process and grant him the lock if it
- * doesn't conflict. The woken process must record the lock
- * him/herself.
- * --------------------
- */
- waitQueue = &(lock->waitProcs);
- ProcLockWakeup(waitQueue, (char *) ltable, (char *) lock);
+ /* --------------------
+ * Wake the first waiting process and grant him the lock if it
+ * doesn't conflict. The woken process must record the lock
+ * him/herself.
+ * --------------------
+ */
+ waitQueue = &(lock->waitProcs);
+ ProcLockWakeup(waitQueue, (char *) ltable, (char *) lock);
}
-
+
#ifdef USER_LOCKS
- next_item:
+next_item:
#endif
- if (done)
- break;
- SHMQueueFirst(&xidLook->queue,(Pointer*)&tmp,&tmp->queue);
- xidLook = tmp;
+ if (done)
+ break;
+ SHMQueueFirst(&xidLook->queue, (Pointer *) & tmp, &tmp->queue);
+ xidLook = tmp;
}
- SpinRelease(masterLock);
+ SpinRelease(masterLock);
#ifdef USER_LOCKS
- /*
- * Reinitialize the queue only if nothing has been left in.
- */
- if (nskip == 0)
+
+ /*
+ * Reinitialize the queue only if nothing has been left in.
+ */
+ if (nskip == 0)
#endif
- SHMQueueInit(lockQueue);
- return TRUE;
+ SHMQueueInit(lockQueue);
+ return TRUE;
}
int
LockShmemSize()
{
- int size = 0;
- int nLockBuckets, nLockSegs;
- int nXidBuckets, nXidSegs;
-
- nLockBuckets = 1 << (int)my_log2((NLOCKENTS - 1) / DEF_FFACTOR + 1);
- nLockSegs = 1 << (int)my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1);
-
- nXidBuckets = 1 << (int)my_log2((NLOCKS_PER_XACT-1) / DEF_FFACTOR + 1);
- nXidSegs = 1 << (int)my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1);
-
- size += MAXALIGN(NBACKENDS * sizeof(PROC)); /* each MyProc */
- size += MAXALIGN(NBACKENDS * sizeof(LOCKCTL)); /* each ltable->ctl */
- size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
-
- size += MAXALIGN(my_log2(NLOCKENTS) * sizeof(void *));
- size += MAXALIGN(sizeof(HHDR));
- size += nLockSegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
- size += NLOCKENTS * /* XXX not multiple of BUCKET_ALLOC_INCR? */
- (MAXALIGN(sizeof(BUCKET_INDEX)) +
- MAXALIGN(sizeof(LOCK))); /* contains hash key */
-
- size += MAXALIGN(my_log2(NBACKENDS) * sizeof(void *));
- size += MAXALIGN(sizeof(HHDR));
- size += nXidSegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
- size += NBACKENDS * /* XXX not multiple of BUCKET_ALLOC_INCR? */
- (MAXALIGN(sizeof(BUCKET_INDEX)) +
- MAXALIGN(sizeof(XIDLookupEnt))); /* contains hash key */
-
- return size;
+ int size = 0;
+ int nLockBuckets,
+ nLockSegs;
+ int nXidBuckets,
+ nXidSegs;
+
+ nLockBuckets = 1 << (int) my_log2((NLOCKENTS - 1) / DEF_FFACTOR + 1);
+ nLockSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1);
+
+ nXidBuckets = 1 << (int) my_log2((NLOCKS_PER_XACT - 1) / DEF_FFACTOR + 1);
+ nXidSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1);
+
+ size += MAXALIGN(NBACKENDS * sizeof(PROC)); /* each MyProc */
+ size += MAXALIGN(NBACKENDS * sizeof(LOCKCTL)); /* each ltable->ctl */
+ size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */
+
+ size += MAXALIGN(my_log2(NLOCKENTS) * sizeof(void *));
+ size += MAXALIGN(sizeof(HHDR));
+ size += nLockSegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
+ size += NLOCKENTS * /* XXX not multiple of BUCKET_ALLOC_INCR? */
+ (MAXALIGN(sizeof(BUCKET_INDEX)) +
+ MAXALIGN(sizeof(LOCK))); /* contains hash key */
+
+ size += MAXALIGN(my_log2(NBACKENDS) * sizeof(void *));
+ size += MAXALIGN(sizeof(HHDR));
+ size += nXidSegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
+ size += NBACKENDS * /* XXX not multiple of BUCKET_ALLOC_INCR? */
+ (MAXALIGN(sizeof(BUCKET_INDEX)) +
+ MAXALIGN(sizeof(XIDLookupEnt))); /* contains hash key */
+
+ return size;
}
/* -----------------
@@ -1354,7 +1399,7 @@ LockShmemSize()
bool
LockingDisabled()
{
- return LockingIsDisabled;
+ return LockingIsDisabled;
}
#ifdef DEADLOCK_DEBUG
@@ -1364,67 +1409,71 @@ LockingDisabled()
void
DumpLocks()
{
- SHMEM_OFFSET location;
- PROC *proc;
- SHM_QUEUE *lockQueue;
- int done;
- XIDLookupEnt *xidLook = NULL;
- XIDLookupEnt *tmp = NULL;
- SHMEM_OFFSET end;
- SPINLOCK masterLock;
- int nLockTypes;
- LOCK *lock;
- int pid, count;
- int tableId = 1;
- LOCKTAB *ltable;
-
- pid = getpid();
- ShmemPIDLookup(pid,&location);
- if (location == INVALID_OFFSET)
- return;
- proc = (PROC *) MAKE_PTR(location);
- if (proc != MyProc)
- return;
- lockQueue = &proc->lockQueue;
-
- Assert (tableId < NumTables);
- ltable = AllTables[tableId];
- if (!ltable)
- return;
-
- nLockTypes = ltable->ctl->nLockTypes;
- masterLock = ltable->ctl->masterLock;
-
- if (SHMQueueEmpty(lockQueue))
- return;
-
- SHMQueueFirst(lockQueue,(Pointer*)&xidLook,&xidLook->queue);
- end = MAKE_OFFSET(lockQueue);
-
- LOCK_DUMP("DumpLocks", MyProc->waitLock, 0);
- XID_PRINT("DumpLocks", xidLook);
-
- for (count=0;;) {
- /* ---------------------------
- * XXX Here we assume the shared memory queue is circular and
- * that we know its internal structure. Should have some sort of
- * macros to allow one to walk it. mer 20 July 1991
- * ---------------------------
- */
- done = (xidLook->queue.next == end);
- lock = (LOCK *) MAKE_PTR(xidLook->tag.lock);
-
- LOCK_DUMP("DumpLocks",lock,0);
-
- if (count++ > 2000) {
- elog(NOTICE,"DumpLocks: xid loop detected, giving up");
- break;
+ SHMEM_OFFSET location;
+ PROC *proc;
+ SHM_QUEUE *lockQueue;
+ int done;
+ XIDLookupEnt *xidLook = NULL;
+ XIDLookupEnt *tmp = NULL;
+ SHMEM_OFFSET end;
+ SPINLOCK masterLock;
+ int nLockTypes;
+ LOCK *lock;
+ int pid,
+ count;
+ int tableId = 1;
+ LOCKTAB *ltable;
+
+ pid = getpid();
+ ShmemPIDLookup(pid, &location);
+ if (location == INVALID_OFFSET)
+ return;
+ proc = (PROC *) MAKE_PTR(location);
+ if (proc != MyProc)
+ return;
+ lockQueue = &proc->lockQueue;
+
+ Assert(tableId < NumTables);
+ ltable = AllTables[tableId];
+ if (!ltable)
+ return;
+
+ nLockTypes = ltable->ctl->nLockTypes;
+ masterLock = ltable->ctl->masterLock;
+
+ if (SHMQueueEmpty(lockQueue))
+ return;
+
+ SHMQueueFirst(lockQueue, (Pointer *) & xidLook, &xidLook->queue);
+ end = MAKE_OFFSET(lockQueue);
+
+ LOCK_DUMP("DumpLocks", MyProc->waitLock, 0);
+ XID_PRINT("DumpLocks", xidLook);
+
+ for (count = 0;;)
+ {
+ /* ---------------------------
+ * XXX Here we assume the shared memory queue is circular and
+ * that we know its internal structure. Should have some sort of
+ * macros to allow one to walk it. mer 20 July 1991
+ * ---------------------------
+ */
+ done = (xidLook->queue.next == end);
+ lock = (LOCK *) MAKE_PTR(xidLook->tag.lock);
+
+ LOCK_DUMP("DumpLocks", lock, 0);
+
+ if (count++ > 2000)
+ {
+ elog(NOTICE, "DumpLocks: xid loop detected, giving up");
+ break;
+ }
+
+ if (done)
+ break;
+ SHMQueueFirst(&xidLook->queue, (Pointer *) & tmp, &tmp->queue);
+ xidLook = tmp;
}
-
- if (done)
- break;
- SHMQueueFirst(&xidLook->queue,(Pointer*)&tmp,&tmp->queue);
- xidLook = tmp;
- }
}
+
#endif
diff --git a/src/backend/storage/lmgr/multi.c b/src/backend/storage/lmgr/multi.c
index 9cd3a36b48c..d5466fce04c 100644
--- a/src/backend/storage/lmgr/multi.c
+++ b/src/backend/storage/lmgr/multi.c
@@ -1,22 +1,22 @@
/*-------------------------------------------------------------------------
*
* multi.c--
- * multi level lock table manager
+ * multi level lock table manager
*
- * Standard multi-level lock manager as per the Gray paper
- * (at least, that is what it is supposed to be). We implement
- * three levels -- RELN, PAGE, TUPLE. Tuple is actually TID
- * a physical record pointer. It isn't an object id.
+ * Standard multi-level lock manager as per the Gray paper
+ * (at least, that is what it is supposed to be). We implement
+ * three levels -- RELN, PAGE, TUPLE. Tuple is actually TID
+ * a physical record pointer. It isn't an object id.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/multi.c,v 1.4 1997/08/19 21:33:25 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/multi.c,v 1.5 1997/09/07 04:49:02 momjian Exp $
*
* NOTES:
- * (1) The lock.c module assumes that the caller here is doing
- * two phase locking.
+ * (1) The lock.c module assumes that the caller here is doing
+ * two phase locking.
*
*-------------------------------------------------------------------------
*/
@@ -27,53 +27,59 @@
#include "storage/multilev.h"
#include "utils/rel.h"
-#include "miscadmin.h" /* MyDatabaseId */
+#include "miscadmin.h" /* MyDatabaseId */
-static bool MultiAcquire(LockTableId tableId, LOCKTAG *tag, LOCKT lockt,
+static bool
+MultiAcquire(LockTableId tableId, LOCKTAG * tag, LOCKT lockt,
LOCK_LEVEL level);
-static bool MultiRelease(LockTableId tableId, LOCKTAG *tag, LOCKT lockt,
+static bool
+MultiRelease(LockTableId tableId, LOCKTAG * tag, LOCKT lockt,
LOCK_LEVEL level);
/*
* INTENT indicates to higher level that a lower level lock has been
- * set. For example, a write lock on a tuple conflicts with a write
- * lock on a relation. This conflict is detected as a WRITE_INTENT/
+ * set. For example, a write lock on a tuple conflicts with a write
+ * lock on a relation. This conflict is detected as a WRITE_INTENT/
* WRITE conflict between the tuple's intent lock and the relation's
* write lock.
*/
-static int MultiConflicts[] = {
- (int)NULL,
- /* All reads and writes at any level conflict with a write lock */
- (1 << WRITE_LOCK)|(1 << WRITE_INTENT)|(1 << READ_LOCK)|(1 << READ_INTENT),
- /* read locks conflict with write locks at curr and lower levels */
- (1 << WRITE_LOCK)| (1 << WRITE_INTENT),
- /* write intent locks */
- (1 << READ_LOCK) | (1 << WRITE_LOCK),
- /* read intent locks*/
- (1 << WRITE_LOCK),
- /* extend locks for archive storage manager conflict only w/extend locks */
- (1 << EXTEND_LOCK)
+static int MultiConflicts[] = {
+ (int) NULL,
+ /* All reads and writes at any level conflict with a write lock */
+ (1 << WRITE_LOCK) | (1 << WRITE_INTENT) | (1 << READ_LOCK) | (1 << READ_INTENT),
+ /* read locks conflict with write locks at curr and lower levels */
+ (1 << WRITE_LOCK) | (1 << WRITE_INTENT),
+ /* write intent locks */
+ (1 << READ_LOCK) | (1 << WRITE_LOCK),
+ /* read intent locks */
+ (1 << WRITE_LOCK),
+
+ /*
+ * extend locks for archive storage manager conflict only w/extend
+ * locks
+ */
+ (1 << EXTEND_LOCK)
};
/*
* write locks have higher priority than read locks and extend locks. May
* want to treat INTENT locks differently.
*/
-static int MultiPrios[] = {
- (int)NULL,
- 2,
- 1,
- 2,
- 1,
- 1
+static int MultiPrios[] = {
+ (int) NULL,
+ 2,
+ 1,
+ 2,
+ 1,
+ 1
};
-/*
+/*
* Lock table identifier for this lock table. The multi-level
* lock table is ONE lock table, not three.
*/
-LockTableId MultiTableId = (LockTableId)NULL;
-LockTableId ShortTermTableId = (LockTableId)NULL;
+LockTableId MultiTableId = (LockTableId) NULL;
+LockTableId ShortTermTableId = (LockTableId) NULL;
/*
* Create the lock table described by MultiConflicts and Multiprio.
@@ -81,30 +87,31 @@ LockTableId ShortTermTableId = (LockTableId)NULL;
LockTableId
InitMultiLevelLockm()
{
- int tableId;
-
- /* -----------------------
- * If we're already initialized just return the table id.
- * -----------------------
- */
- if (MultiTableId)
+ int tableId;
+
+ /* -----------------------
+ * If we're already initialized just return the table id.
+ * -----------------------
+ */
+ if (MultiTableId)
+ return MultiTableId;
+
+ tableId = LockTabInit("LockTable", MultiConflicts, MultiPrios, 5);
+ MultiTableId = tableId;
+ if (!(MultiTableId))
+ {
+ elog(WARN, "InitMultiLockm: couldnt initialize lock table");
+ }
+ /* -----------------------
+ * No short term lock table for now. -Jeff 15 July 1991
+ *
+ * ShortTermTableId = LockTabRename(tableId);
+ * if (! (ShortTermTableId)) {
+ * elog(WARN,"InitMultiLockm: couldnt rename lock table");
+ * }
+ * -----------------------
+ */
return MultiTableId;
-
- tableId = LockTabInit("LockTable", MultiConflicts, MultiPrios, 5);
- MultiTableId = tableId;
- if (! (MultiTableId)) {
- elog(WARN,"InitMultiLockm: couldnt initialize lock table");
- }
- /* -----------------------
- * No short term lock table for now. -Jeff 15 July 1991
- *
- * ShortTermTableId = LockTabRename(tableId);
- * if (! (ShortTermTableId)) {
- * elog(WARN,"InitMultiLockm: couldnt rename lock table");
- * }
- * -----------------------
- */
- return MultiTableId;
}
/*
@@ -115,16 +122,16 @@ InitMultiLevelLockm()
bool
MultiLockReln(LockInfo linfo, LOCKT lockt)
{
- LOCKTAG tag;
-
- /* LOCKTAG has two bytes of padding, unfortunately. The
- * hash function will return miss if the padding bytes aren't
- * zero'd.
- */
- memset(&tag,0,sizeof(tag));
- tag.relId = linfo->lRelId.relId;
- tag.dbId = linfo->lRelId.dbId;
- return(MultiAcquire(MultiTableId, &tag, lockt, RELN_LEVEL));
+ LOCKTAG tag;
+
+ /*
+ * LOCKTAG has two bytes of padding, unfortunately. The hash function
+ * will return miss if the padding bytes aren't zero'd.
+ */
+ memset(&tag, 0, sizeof(tag));
+ tag.relId = linfo->lRelId.relId;
+ tag.dbId = linfo->lRelId.dbId;
+ return (MultiAcquire(MultiTableId, &tag, lockt, RELN_LEVEL));
}
/*
@@ -133,25 +140,25 @@ MultiLockReln(LockInfo linfo, LOCKT lockt)
* Returns: TRUE if lock is set, FALSE otherwise.
*
* Side Effects: causes intention level locks to be set
- * at the page and relation level.
+ * at the page and relation level.
*/
bool
MultiLockTuple(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt)
{
- LOCKTAG tag;
-
- /* LOCKTAG has two bytes of padding, unfortunately. The
- * hash function will return miss if the padding bytes aren't
- * zero'd.
- */
- memset(&tag,0,sizeof(tag));
-
- tag.relId = linfo->lRelId.relId;
- tag.dbId = linfo->lRelId.dbId;
-
- /* not locking any valid Tuple, just the page */
- tag.tupleId = *tidPtr;
- return(MultiAcquire(MultiTableId, &tag, lockt, TUPLE_LEVEL));
+ LOCKTAG tag;
+
+ /*
+ * LOCKTAG has two bytes of padding, unfortunately. The hash function
+ * will return miss if the padding bytes aren't zero'd.
+ */
+ memset(&tag, 0, sizeof(tag));
+
+ tag.relId = linfo->lRelId.relId;
+ tag.dbId = linfo->lRelId.dbId;
+
+ /* not locking any valid Tuple, just the page */
+ tag.tupleId = *tidPtr;
+ return (MultiAcquire(MultiTableId, &tag, lockt, TUPLE_LEVEL));
}
/*
@@ -160,28 +167,28 @@ MultiLockTuple(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt)
bool
MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt)
{
- LOCKTAG tag;
-
- /* LOCKTAG has two bytes of padding, unfortunately. The
- * hash function will return miss if the padding bytes aren't
- * zero'd.
- */
- memset(&tag,0,sizeof(tag));
-
-
- /* ----------------------------
- * Now we want to set the page offset to be invalid
- * and lock the block. There is some confusion here as to what
- * a page is. In Postgres a page is an 8k block, however this
- * block may be partitioned into many subpages which are sometimes
- * also called pages. The term is overloaded, so don't be fooled
- * when we say lock the page we mean the 8k block. -Jeff 16 July 1991
- * ----------------------------
- */
- tag.relId = linfo->lRelId.relId;
- tag.dbId = linfo->lRelId.dbId;
- BlockIdCopy(&(tag.tupleId.ip_blkid), &(tidPtr->ip_blkid));
- return(MultiAcquire(MultiTableId, &tag, lockt, PAGE_LEVEL));
+ LOCKTAG tag;
+
+ /*
+ * LOCKTAG has two bytes of padding, unfortunately. The hash function
+ * will return miss if the padding bytes aren't zero'd.
+ */
+ memset(&tag, 0, sizeof(tag));
+
+
+ /* ----------------------------
+ * Now we want to set the page offset to be invalid
+ * and lock the block. There is some confusion here as to what
+ * a page is. In Postgres a page is an 8k block, however this
+ * block may be partitioned into many subpages which are sometimes
+ * also called pages. The term is overloaded, so don't be fooled
+ * when we say lock the page we mean the 8k block. -Jeff 16 July 1991
+ * ----------------------------
+ */
+ tag.relId = linfo->lRelId.relId;
+ tag.dbId = linfo->lRelId.dbId;
+ BlockIdCopy(&(tag.tupleId.ip_blkid), &(tidPtr->ip_blkid));
+ return (MultiAcquire(MultiTableId, &tag, lockt, PAGE_LEVEL));
}
/*
@@ -190,102 +197,110 @@ MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt)
* Returns: TRUE if lock is set, FALSE if not
* Side Effects:
*/
-static bool
+static bool
MultiAcquire(LockTableId tableId,
- LOCKTAG *tag,
- LOCKT lockt,
- LOCK_LEVEL level)
+ LOCKTAG * tag,
+ LOCKT lockt,
+ LOCK_LEVEL level)
{
- LOCKT locks[N_LEVELS];
- int i,status;
- LOCKTAG xxTag, *tmpTag = &xxTag;
- int retStatus = TRUE;
-
- /*
- * Three levels implemented. If we set a low level (e.g. Tuple)
- * lock, we must set INTENT locks on the higher levels. The
- * intent lock detects conflicts between the low level lock
- * and an existing high level lock. For example, setting a
- * write lock on a tuple in a relation is disallowed if there
- * is an existing read lock on the entire relation. The
- * write lock would set a WRITE + INTENT lock on the relation
- * and that lock would conflict with the read.
- */
- switch (level) {
- case RELN_LEVEL:
- locks[0] = lockt;
- locks[1] = NO_LOCK;
- locks[2] = NO_LOCK;
- break;
- case PAGE_LEVEL:
- locks[0] = lockt + INTENT;
- locks[1] = lockt;
- locks[2] = NO_LOCK;
- break;
- case TUPLE_LEVEL:
- locks[0] = lockt + INTENT;
- locks[1] = lockt + INTENT;
- locks[2] = lockt;
- break;
- default:
- elog(WARN,"MultiAcquire: bad lock level");
- return(FALSE);
- }
-
- /*
- * construct a new tag as we go. Always loop through all levels,
- * but if we arent' seting a low level lock, locks[i] is set to
- * NO_LOCK for the lower levels. Always start from the highest
- * level and go to the lowest level.
- */
- memset(tmpTag,0,sizeof(*tmpTag));
- tmpTag->relId = tag->relId;
- tmpTag->dbId = tag->dbId;
-
- for (i=0;i<N_LEVELS;i++) {
- if (locks[i] != NO_LOCK) {
- switch (i) {
- case RELN_LEVEL:
- /* -------------
- * Set the block # and offset to invalid
- * -------------
- */
- BlockIdSet(&(tmpTag->tupleId.ip_blkid), InvalidBlockNumber);
- tmpTag->tupleId.ip_posid = InvalidOffsetNumber;
- break;
- case PAGE_LEVEL:
- /* -------------
- * Copy the block #, set the offset to invalid
- * -------------
- */
- BlockIdCopy(&(tmpTag->tupleId.ip_blkid),
- &(tag->tupleId.ip_blkid));
- tmpTag->tupleId.ip_posid = InvalidOffsetNumber;
+ LOCKT locks[N_LEVELS];
+ int i,
+ status;
+ LOCKTAG xxTag,
+ *tmpTag = &xxTag;
+ int retStatus = TRUE;
+
+ /*
+ * Three levels implemented. If we set a low level (e.g. Tuple) lock,
+ * we must set INTENT locks on the higher levels. The intent lock
+ * detects conflicts between the low level lock and an existing high
+ * level lock. For example, setting a write lock on a tuple in a
+ * relation is disallowed if there is an existing read lock on the
+ * entire relation. The write lock would set a WRITE + INTENT lock on
+ * the relation and that lock would conflict with the read.
+ */
+ switch (level)
+ {
+ case RELN_LEVEL:
+ locks[0] = lockt;
+ locks[1] = NO_LOCK;
+ locks[2] = NO_LOCK;
break;
- case TUPLE_LEVEL:
- /* --------------
- * Copy the entire tuple id.
- * --------------
- */
- ItemPointerCopy(&tmpTag->tupleId, &tag->tupleId);
+ case PAGE_LEVEL:
+ locks[0] = lockt + INTENT;
+ locks[1] = lockt;
+ locks[2] = NO_LOCK;
break;
- }
-
- status = LockAcquire(tableId, tmpTag, locks[i]);
- if (! status) {
- /* failed for some reason. Before returning we have
- * to release all of the locks we just acquired.
- * MultiRelease(xx,xx,xx, i) means release starting from
- * the last level lock we successfully acquired
- */
- retStatus = FALSE;
- MultiRelease(tableId, tag, lockt, i);
- /* now leave the loop. Don't try for any more locks */
+ case TUPLE_LEVEL:
+ locks[0] = lockt + INTENT;
+ locks[1] = lockt + INTENT;
+ locks[2] = lockt;
break;
- }
+ default:
+ elog(WARN, "MultiAcquire: bad lock level");
+ return (FALSE);
}
- }
- return(retStatus);
+
+ /*
+ * construct a new tag as we go. Always loop through all levels, but
+ * if we arent' seting a low level lock, locks[i] is set to NO_LOCK
+ * for the lower levels. Always start from the highest level and go
+ * to the lowest level.
+ */
+ memset(tmpTag, 0, sizeof(*tmpTag));
+ tmpTag->relId = tag->relId;
+ tmpTag->dbId = tag->dbId;
+
+ for (i = 0; i < N_LEVELS; i++)
+ {
+ if (locks[i] != NO_LOCK)
+ {
+ switch (i)
+ {
+ case RELN_LEVEL:
+ /* -------------
+ * Set the block # and offset to invalid
+ * -------------
+ */
+ BlockIdSet(&(tmpTag->tupleId.ip_blkid), InvalidBlockNumber);
+ tmpTag->tupleId.ip_posid = InvalidOffsetNumber;
+ break;
+ case PAGE_LEVEL:
+ /* -------------
+ * Copy the block #, set the offset to invalid
+ * -------------
+ */
+ BlockIdCopy(&(tmpTag->tupleId.ip_blkid),
+ &(tag->tupleId.ip_blkid));
+ tmpTag->tupleId.ip_posid = InvalidOffsetNumber;
+ break;
+ case TUPLE_LEVEL:
+ /* --------------
+ * Copy the entire tuple id.
+ * --------------
+ */
+ ItemPointerCopy(&tmpTag->tupleId, &tag->tupleId);
+ break;
+ }
+
+ status = LockAcquire(tableId, tmpTag, locks[i]);
+ if (!status)
+ {
+
+ /*
+ * failed for some reason. Before returning we have to
+ * release all of the locks we just acquired.
+ * MultiRelease(xx,xx,xx, i) means release starting from
+ * the last level lock we successfully acquired
+ */
+ retStatus = FALSE;
+ MultiRelease(tableId, tag, lockt, i);
+ /* now leave the loop. Don't try for any more locks */
+ break;
+ }
+ }
+ }
+ return (retStatus);
}
/* ------------------
@@ -294,24 +309,25 @@ MultiAcquire(LockTableId tableId,
*/
#ifdef NOT_USED
bool
-MultiReleasePage(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt)
+MultiReleasePage(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt)
{
- LOCKTAG tag;
-
- /* ------------------
- * LOCKTAG has two bytes of padding, unfortunately. The
- * hash function will return miss if the padding bytes aren't
- * zero'd.
- * ------------------
- */
- memset(&tag, 0,sizeof(LOCKTAG));
-
- tag.relId = linfo->lRelId.relId;
- tag.dbId = linfo->lRelId.dbId;
- BlockIdCopy(&(tag.tupleId.ip_blkid), &(tidPtr->ip_blkid));
-
- return (MultiRelease(MultiTableId, &tag, lockt, PAGE_LEVEL));
+ LOCKTAG tag;
+
+ /* ------------------
+ * LOCKTAG has two bytes of padding, unfortunately. The
+ * hash function will return miss if the padding bytes aren't
+ * zero'd.
+ * ------------------
+ */
+ memset(&tag, 0, sizeof(LOCKTAG));
+
+ tag.relId = linfo->lRelId.relId;
+ tag.dbId = linfo->lRelId.dbId;
+ BlockIdCopy(&(tag.tupleId.ip_blkid), &(tidPtr->ip_blkid));
+
+ return (MultiRelease(MultiTableId, &tag, lockt, PAGE_LEVEL));
}
+
#endif
/* ------------------
@@ -319,21 +335,21 @@ MultiReleasePage(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt)
* ------------------
*/
bool
-MultiReleaseReln(LockInfo linfo, LOCKT lockt)
+MultiReleaseReln(LockInfo linfo, LOCKT lockt)
{
- LOCKTAG tag;
-
- /* ------------------
- * LOCKTAG has two bytes of padding, unfortunately. The
- * hash function will return miss if the padding bytes aren't
- * zero'd.
- * ------------------
- */
- memset(&tag, 0, sizeof(LOCKTAG));
- tag.relId = linfo->lRelId.relId;
- tag.dbId = linfo->lRelId.dbId;
-
- return (MultiRelease(MultiTableId, &tag, lockt, RELN_LEVEL));
+ LOCKTAG tag;
+
+ /* ------------------
+ * LOCKTAG has two bytes of padding, unfortunately. The
+ * hash function will return miss if the padding bytes aren't
+ * zero'd.
+ * ------------------
+ */
+ memset(&tag, 0, sizeof(LOCKTAG));
+ tag.relId = linfo->lRelId.relId;
+ tag.dbId = linfo->lRelId.dbId;
+
+ return (MultiRelease(MultiTableId, &tag, lockt, RELN_LEVEL));
}
/*
@@ -341,81 +357,88 @@ MultiReleaseReln(LockInfo linfo, LOCKT lockt)
*
* Returns: TRUE if successful, FALSE otherwise.
*/
-static bool
+static bool
MultiRelease(LockTableId tableId,
- LOCKTAG *tag,
- LOCKT lockt,
- LOCK_LEVEL level)
+ LOCKTAG * tag,
+ LOCKT lockt,
+ LOCK_LEVEL level)
{
- LOCKT locks[N_LEVELS];
- int i,status;
- LOCKTAG xxTag, *tmpTag = &xxTag;
-
- /*
- * same level scheme as MultiAcquire().
- */
- switch (level) {
- case RELN_LEVEL:
- locks[0] = lockt;
- locks[1] = NO_LOCK;
- locks[2] = NO_LOCK;
- break;
- case PAGE_LEVEL:
- locks[0] = lockt + INTENT;
- locks[1] = lockt;
- locks[2] = NO_LOCK;
- break;
- case TUPLE_LEVEL:
- locks[0] = lockt + INTENT;
- locks[1] = lockt + INTENT;
- locks[2] = lockt;
- break;
- default:
- elog(WARN,"MultiRelease: bad lockt");
- }
-
- /*
- * again, construct the tag on the fly. This time, however,
- * we release the locks in the REVERSE order -- from lowest
- * level to highest level.
- *
- * Must zero out the tag to set padding byes to zero and ensure
- * hashing consistency.
- */
- memset(tmpTag, 0, sizeof(*tmpTag));
- tmpTag->relId = tag->relId;
- tmpTag->dbId = tag->dbId;
-
- for (i=(N_LEVELS-1); i>=0; i--) {
- if (locks[i] != NO_LOCK) {
- switch (i) {
- case RELN_LEVEL:
- /* -------------
- * Set the block # and offset to invalid
- * -------------
- */
- BlockIdSet(&(tmpTag->tupleId.ip_blkid), InvalidBlockNumber);
- tmpTag->tupleId.ip_posid = InvalidOffsetNumber;
+ LOCKT locks[N_LEVELS];
+ int i,
+ status;
+ LOCKTAG xxTag,
+ *tmpTag = &xxTag;
+
+ /*
+ * same level scheme as MultiAcquire().
+ */
+ switch (level)
+ {
+ case RELN_LEVEL:
+ locks[0] = lockt;
+ locks[1] = NO_LOCK;
+ locks[2] = NO_LOCK;
break;
- case PAGE_LEVEL:
- /* -------------
- * Copy the block #, set the offset to invalid
- * -------------
- */
- BlockIdCopy(&(tmpTag->tupleId.ip_blkid),
- &(tag->tupleId.ip_blkid));
- tmpTag->tupleId.ip_posid = InvalidOffsetNumber;
+ case PAGE_LEVEL:
+ locks[0] = lockt + INTENT;
+ locks[1] = lockt;
+ locks[2] = NO_LOCK;
break;
- case TUPLE_LEVEL:
- ItemPointerCopy(&tmpTag->tupleId, &tag->tupleId);
+ case TUPLE_LEVEL:
+ locks[0] = lockt + INTENT;
+ locks[1] = lockt + INTENT;
+ locks[2] = lockt;
break;
- }
- status = LockRelease(tableId, tmpTag, locks[i]);
- if (! status) {
- elog(WARN,"MultiRelease: couldn't release after error");
- }
+ default:
+ elog(WARN, "MultiRelease: bad lockt");
+ }
+
+ /*
+ * again, construct the tag on the fly. This time, however, we
+ * release the locks in the REVERSE order -- from lowest level to
+ * highest level.
+ *
+ * Must zero out the tag to set padding byes to zero and ensure hashing
+ * consistency.
+ */
+ memset(tmpTag, 0, sizeof(*tmpTag));
+ tmpTag->relId = tag->relId;
+ tmpTag->dbId = tag->dbId;
+
+ for (i = (N_LEVELS - 1); i >= 0; i--)
+ {
+ if (locks[i] != NO_LOCK)
+ {
+ switch (i)
+ {
+ case RELN_LEVEL:
+ /* -------------
+ * Set the block # and offset to invalid
+ * -------------
+ */
+ BlockIdSet(&(tmpTag->tupleId.ip_blkid), InvalidBlockNumber);
+ tmpTag->tupleId.ip_posid = InvalidOffsetNumber;
+ break;
+ case PAGE_LEVEL:
+ /* -------------
+ * Copy the block #, set the offset to invalid
+ * -------------
+ */
+ BlockIdCopy(&(tmpTag->tupleId.ip_blkid),
+ &(tag->tupleId.ip_blkid));
+ tmpTag->tupleId.ip_posid = InvalidOffsetNumber;
+ break;
+ case TUPLE_LEVEL:
+ ItemPointerCopy(&tmpTag->tupleId, &tag->tupleId);
+ break;
+ }
+ status = LockRelease(tableId, tmpTag, locks[i]);
+ if (!status)
+ {
+ elog(WARN, "MultiRelease: couldn't release after error");
+ }
+ }
}
- }
- /* shouldn't reach here */
- return false;
+ /* shouldn't reach here */
+ return false;
}
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 528bfa1e35d..e3872091dfc 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* proc.c--
- * routines to manage per-process shared memory data structure
+ * routines to manage per-process shared memory data structure
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.18 1997/08/19 21:33:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.19 1997/09/07 04:49:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * Each postgres backend gets one of these. We'll use it to
- * clean up after the process should the process suddenly die.
+ * Each postgres backend gets one of these. We'll use it to
+ * clean up after the process should the process suddenly die.
*
*
* Interface (a):
- * ProcSleep(), ProcWakeup(), ProcWakeupNext(),
- * ProcQueueAlloc() -- create a shm queue for sleeping processes
- * ProcQueueInit() -- create a queue without allocing memory
+ * ProcSleep(), ProcWakeup(), ProcWakeupNext(),
+ * ProcQueueAlloc() -- create a shm queue for sleeping processes
+ * ProcQueueInit() -- create a queue without allocing memory
*
* Locking and waiting for buffers can cause the backend to be
* put to sleep. Whoever releases the lock, etc. wakes the
@@ -30,23 +30,23 @@
*
* ProcReleaseLocks -- frees the locks associated with this process,
* ProcKill -- destroys the shared memory state (and locks)
- * associated with the process.
+ * associated with the process.
*
* 5/15/91 -- removed the buffer pool based lock chain in favor
- * of a shared memory lock chain. The write-protection is
- * more expensive if the lock chain is in the buffer pool.
- * The only reason I kept the lock chain in the buffer pool
- * in the first place was to allow the lock table to grow larger
- * than available shared memory and that isn't going to work
- * without a lot of unimplemented support anyway.
+ * of a shared memory lock chain. The write-protection is
+ * more expensive if the lock chain is in the buffer pool.
+ * The only reason I kept the lock chain in the buffer pool
+ * in the first place was to allow the lock table to grow larger
+ * than available shared memory and that isn't going to work
+ * without a lot of unimplemented support anyway.
*
* 4/7/95 -- instead of allocating a set of 1 semaphore per process, we
- * allocate a semaphore from a set of PROC_NSEMS_PER_SET semaphores
- * shared among backends (we keep a few sets of semaphores around).
- * This is so that we can support more backends. (system-wide semaphore
- * sets run out pretty fast.) -ay 4/95
+ * allocate a semaphore from a set of PROC_NSEMS_PER_SET semaphores
+ * shared among backends (we keep a few sets of semaphores around).
+ * This is so that we can support more backends. (system-wide semaphore
+ * sets run out pretty fast.) -ay 4/95
*
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.18 1997/08/19 21:33:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.19 1997/09/07 04:49:03 momjian Exp $
*/
#include <sys/time.h>
#include <unistd.h>
@@ -69,21 +69,21 @@
#include "storage/ipc.h"
/* In Ultrix, sem.h must be included after ipc.h */
#include <sys/sem.h>
-#include "storage/buf.h"
+#include "storage/buf.h"
#include "storage/lock.h"
#include "storage/lmgr.h"
#include "storage/shmem.h"
#include "storage/spin.h"
#include "storage/proc.h"
-static void HandleDeadLock(int sig);
-static PROC *ProcWakeup(PROC *proc, int errType);
+static void HandleDeadLock(int sig);
+static PROC *ProcWakeup(PROC * proc, int errType);
/*
* timeout (in seconds) for resolving possible deadlock
*/
#ifndef DEADLOCK_TIMEOUT
-#define DEADLOCK_TIMEOUT 60
+#define DEADLOCK_TIMEOUT 60
#endif
/* --------------------
@@ -93,51 +93,52 @@ static PROC *ProcWakeup(PROC *proc, int errType);
* memory. -mer 17 July 1991
* --------------------
*/
-SPINLOCK ProcStructLock;
+SPINLOCK ProcStructLock;
/*
* For cleanup routines. Don't cleanup if the initialization
* has not happened.
*/
-static bool ProcInitialized = FALSE;
+static bool ProcInitialized = FALSE;
static PROC_HDR *ProcGlobal = NULL;
-PROC *MyProc = NULL;
+PROC *MyProc = NULL;
+
+static void ProcKill(int exitStatus, int pid);
+static void ProcGetNewSemKeyAndNum(IPCKey * key, int *semNum);
+static void ProcFreeSem(IpcSemaphoreKey semKey, int semNum);
-static void ProcKill(int exitStatus, int pid);
-static void ProcGetNewSemKeyAndNum(IPCKey *key, int *semNum);
-static void ProcFreeSem(IpcSemaphoreKey semKey, int semNum);
/*
* InitProcGlobal -
- * initializes the global process table. We put it here so that
- * the postmaster can do this initialization. (ProcFreeAllSem needs
- * to read this table on exiting the postmaster. If we have the first
- * backend do this, starting up and killing the postmaster without
- * starting any backends will be a problem.)
+ * initializes the global process table. We put it here so that
+ * the postmaster can do this initialization. (ProcFreeAllSem needs
+ * to read this table on exiting the postmaster. If we have the first
+ * backend do this, starting up and killing the postmaster without
+ * starting any backends will be a problem.)
*/
void
InitProcGlobal(IPCKey key)
{
- bool found = false;
+ bool found = false;
- /* attach to the free list */
- ProcGlobal = (PROC_HDR *)
- ShmemInitStruct("Proc Header",(unsigned)sizeof(PROC_HDR),&found);
+ /* attach to the free list */
+ ProcGlobal = (PROC_HDR *)
+ ShmemInitStruct("Proc Header", (unsigned) sizeof(PROC_HDR), &found);
- /* --------------------
- * We're the first - initialize.
- * --------------------
- */
- if (! found)
+ /* --------------------
+ * We're the first - initialize.
+ * --------------------
+ */
+ if (!found)
{
- int i;
+ int i;
- ProcGlobal->numProcs = 0;
- ProcGlobal->freeProcs = INVALID_OFFSET;
- ProcGlobal->currKey = IPCGetProcessSemaphoreInitKey(key);
- for (i=0; i < MAX_PROC_SEMS/PROC_NSEMS_PER_SET; i++)
- ProcGlobal->freeSemMap[i] = 0;
+ ProcGlobal->numProcs = 0;
+ ProcGlobal->freeProcs = INVALID_OFFSET;
+ ProcGlobal->currKey = IPCGetProcessSemaphoreInitKey(key);
+ for (i = 0; i < MAX_PROC_SEMS / PROC_NSEMS_PER_SET; i++)
+ ProcGlobal->freeSemMap[i] = 0;
}
}
@@ -149,141 +150,149 @@ InitProcGlobal(IPCKey key)
void
InitProcess(IPCKey key)
{
- bool found = false;
- int pid;
- int semstat;
- unsigned long location, myOffset;
-
- /* ------------------
- * Routine called if deadlock timer goes off. See ProcSleep()
- * ------------------
- */
- pqsignal(SIGALRM, HandleDeadLock);
-
- SpinAcquire(ProcStructLock);
-
- /* attach to the free list */
- ProcGlobal = (PROC_HDR *)
- ShmemInitStruct("Proc Header",(unsigned)sizeof(PROC_HDR),&found);
- if (!found) {
- /* this should not happen. InitProcGlobal() is called before this. */
- elog(WARN, "InitProcess: Proc Header uninitialized");
- }
-
- if (MyProc != NULL)
+ bool found = false;
+ int pid;
+ int semstat;
+ unsigned long location,
+ myOffset;
+
+ /* ------------------
+ * Routine called if deadlock timer goes off. See ProcSleep()
+ * ------------------
+ */
+ pqsignal(SIGALRM, HandleDeadLock);
+
+ SpinAcquire(ProcStructLock);
+
+ /* attach to the free list */
+ ProcGlobal = (PROC_HDR *)
+ ShmemInitStruct("Proc Header", (unsigned) sizeof(PROC_HDR), &found);
+ if (!found)
{
- SpinRelease(ProcStructLock);
- elog(WARN,"ProcInit: you already exist");
- return;
+ /* this should not happen. InitProcGlobal() is called before this. */
+ elog(WARN, "InitProcess: Proc Header uninitialized");
}
-
- /* try to get a proc from the free list first */
-
- myOffset = ProcGlobal->freeProcs;
-
- if (myOffset != INVALID_OFFSET)
+
+ if (MyProc != NULL)
{
- MyProc = (PROC *) MAKE_PTR(myOffset);
- ProcGlobal->freeProcs = MyProc->links.next;
+ SpinRelease(ProcStructLock);
+ elog(WARN, "ProcInit: you already exist");
+ return;
}
- else
+
+ /* try to get a proc from the free list first */
+
+ myOffset = ProcGlobal->freeProcs;
+
+ if (myOffset != INVALID_OFFSET)
{
- /* have to allocate one. We can't use the normal binding
- * table mechanism because the proc structure is stored
- * by PID instead of by a global name (need to look it
- * up by PID when we cleanup dead processes).
- */
-
- MyProc = (PROC *) ShmemAlloc((unsigned)sizeof(PROC));
- if (! MyProc)
+ MyProc = (PROC *) MAKE_PTR(myOffset);
+ ProcGlobal->freeProcs = MyProc->links.next;
+ }
+ else
+ {
+
+ /*
+ * have to allocate one. We can't use the normal binding table
+ * mechanism because the proc structure is stored by PID instead
+ * of by a global name (need to look it up by PID when we cleanup
+ * dead processes).
+ */
+
+ MyProc = (PROC *) ShmemAlloc((unsigned) sizeof(PROC));
+ if (!MyProc)
{
- SpinRelease(ProcStructLock);
- elog (FATAL,"cannot create new proc: out of memory");
+ SpinRelease(ProcStructLock);
+ elog(FATAL, "cannot create new proc: out of memory");
}
-
- /* this cannot be initialized until after the buffer pool */
- SHMQueueInit(&(MyProc->lockQueue));
- MyProc->procId = ProcGlobal->numProcs;
- ProcGlobal->numProcs++;
+
+ /* this cannot be initialized until after the buffer pool */
+ SHMQueueInit(&(MyProc->lockQueue));
+ MyProc->procId = ProcGlobal->numProcs;
+ ProcGlobal->numProcs++;
}
-
- /*
- * zero out the spin lock counts and set the sLocks field for
- * ProcStructLock to 1 as we have acquired this spinlock above but
- * didn't record it since we didn't have MyProc until now.
- */
- memset(MyProc->sLocks, 0, sizeof(MyProc->sLocks));
- MyProc->sLocks[ProcStructLock] = 1;
-
-
- if (IsUnderPostmaster) {
- IPCKey semKey;
- int semNum;
- int semId;
- union semun semun;
-
- ProcGetNewSemKeyAndNum(&semKey, &semNum);
-
- semId = IpcSemaphoreCreate(semKey,
- PROC_NSEMS_PER_SET,
- IPCProtection,
- IpcSemaphoreDefaultStartValue,
- 0,
- &semstat);
+
/*
- * we might be reusing a semaphore that belongs to a dead
- * backend. So be careful and reinitialize its value here.
+ * zero out the spin lock counts and set the sLocks field for
+ * ProcStructLock to 1 as we have acquired this spinlock above but
+ * didn't record it since we didn't have MyProc until now.
*/
- semun.val = IpcSemaphoreDefaultStartValue;
- semctl(semId, semNum, SETVAL, semun);
-
- IpcSemaphoreLock(semId, semNum, IpcExclusiveLock);
- MyProc->sem.semId = semId;
- MyProc->sem.semNum = semNum;
- MyProc->sem.semKey = semKey;
- } else {
- MyProc->sem.semId = -1;
- }
-
- /* ----------------------
- * Release the lock.
- * ----------------------
- */
- SpinRelease(ProcStructLock);
-
- MyProc->pid = 0;
- MyProc->xid = InvalidTransactionId;
+ memset(MyProc->sLocks, 0, sizeof(MyProc->sLocks));
+ MyProc->sLocks[ProcStructLock] = 1;
+
+
+ if (IsUnderPostmaster)
+ {
+ IPCKey semKey;
+ int semNum;
+ int semId;
+ union semun semun;
+
+ ProcGetNewSemKeyAndNum(&semKey, &semNum);
+
+ semId = IpcSemaphoreCreate(semKey,
+ PROC_NSEMS_PER_SET,
+ IPCProtection,
+ IpcSemaphoreDefaultStartValue,
+ 0,
+ &semstat);
+
+ /*
+ * we might be reusing a semaphore that belongs to a dead backend.
+ * So be careful and reinitialize its value here.
+ */
+ semun.val = IpcSemaphoreDefaultStartValue;
+ semctl(semId, semNum, SETVAL, semun);
+
+ IpcSemaphoreLock(semId, semNum, IpcExclusiveLock);
+ MyProc->sem.semId = semId;
+ MyProc->sem.semNum = semNum;
+ MyProc->sem.semKey = semKey;
+ }
+ else
+ {
+ MyProc->sem.semId = -1;
+ }
+
+ /* ----------------------
+ * Release the lock.
+ * ----------------------
+ */
+ SpinRelease(ProcStructLock);
+
+ MyProc->pid = 0;
+ MyProc->xid = InvalidTransactionId;
#if 0
- MyProc->pid = MyPid;
+ MyProc->pid = MyPid;
#endif
-
- /* ----------------
- * Start keeping spin lock stats from here on. Any botch before
- * this initialization is forever botched
- * ----------------
- */
- memset(MyProc->sLocks, 0, MAX_SPINS*sizeof(*MyProc->sLocks));
-
- /* -------------------------
- * Install ourselves in the binding table. The name to
- * use is determined by the OS-assigned process id. That
- * allows the cleanup process to find us after any untimely
- * exit.
- * -------------------------
- */
- pid = getpid();
- location = MAKE_OFFSET(MyProc);
- if ((! ShmemPIDLookup(pid,&location)) || (location != MAKE_OFFSET(MyProc)))
+
+ /* ----------------
+ * Start keeping spin lock stats from here on. Any botch before
+ * this initialization is forever botched
+ * ----------------
+ */
+ memset(MyProc->sLocks, 0, MAX_SPINS * sizeof(*MyProc->sLocks));
+
+ /* -------------------------
+ * Install ourselves in the binding table. The name to
+ * use is determined by the OS-assigned process id. That
+ * allows the cleanup process to find us after any untimely
+ * exit.
+ * -------------------------
+ */
+ pid = getpid();
+ location = MAKE_OFFSET(MyProc);
+ if ((!ShmemPIDLookup(pid, &location)) || (location != MAKE_OFFSET(MyProc)))
{
- elog(FATAL,"InitProc: ShmemPID table broken");
+ elog(FATAL, "InitProc: ShmemPID table broken");
}
-
- MyProc->errType = NO_ERROR;
- SHMQueueElemInit(&(MyProc->links));
-
- on_exitpg(ProcKill, (caddr_t)pid);
-
- ProcInitialized = TRUE;
+
+ MyProc->errType = NO_ERROR;
+ SHMQueueElemInit(&(MyProc->links));
+
+ on_exitpg(ProcKill, (caddr_t) pid);
+
+ ProcInitialized = TRUE;
}
/*
@@ -293,109 +302,112 @@ InitProcess(IPCKey key)
void
ProcReleaseLocks()
{
- if (!MyProc)
- return;
- LockReleaseAll(1,&MyProc->lockQueue);
+ if (!MyProc)
+ return;
+ LockReleaseAll(1, &MyProc->lockQueue);
}
/*
* ProcRemove -
- * used by the postmaster to clean up the global tables. This also frees
- * up the semaphore used for the lmgr of the process. (We have to do
- * this is the postmaster instead of doing a IpcSemaphoreKill on exiting
- * the process because the semaphore set is shared among backends and
- * we don't want to remove other's semaphores on exit.)
+ * used by the postmaster to clean up the global tables. This also frees
+ * up the semaphore used for the lmgr of the process. (We have to do
+ * this is the postmaster instead of doing a IpcSemaphoreKill on exiting
+ * the process because the semaphore set is shared among backends and
+ * we don't want to remove other's semaphores on exit.)
*/
bool
ProcRemove(int pid)
{
- SHMEM_OFFSET location;
- PROC *proc;
-
- location = INVALID_OFFSET;
-
- location = ShmemPIDDestroy(pid);
- if (location == INVALID_OFFSET)
- return(FALSE);
- proc = (PROC *) MAKE_PTR(location);
-
- SpinAcquire(ProcStructLock);
-
- ProcFreeSem(proc->sem.semKey, proc->sem.semNum);
-
- proc->links.next = ProcGlobal->freeProcs;
- ProcGlobal->freeProcs = MAKE_OFFSET(proc);
-
- SpinRelease(ProcStructLock);
-
- return(TRUE);
+ SHMEM_OFFSET location;
+ PROC *proc;
+
+ location = INVALID_OFFSET;
+
+ location = ShmemPIDDestroy(pid);
+ if (location == INVALID_OFFSET)
+ return (FALSE);
+ proc = (PROC *) MAKE_PTR(location);
+
+ SpinAcquire(ProcStructLock);
+
+ ProcFreeSem(proc->sem.semKey, proc->sem.semNum);
+
+ proc->links.next = ProcGlobal->freeProcs;
+ ProcGlobal->freeProcs = MAKE_OFFSET(proc);
+
+ SpinRelease(ProcStructLock);
+
+ return (TRUE);
}
/*
* ProcKill() -- Destroy the per-proc data structure for
- * this process. Release any of its held spin locks.
+ * this process. Release any of its held spin locks.
*/
static void
ProcKill(int exitStatus, int pid)
{
- PROC *proc;
- SHMEM_OFFSET location;
-
- /* --------------------
- * If this is a FATAL exit the postmaster will have to kill all the
- * existing backends and reinitialize shared memory. So all we don't
- * need to do anything here.
- * --------------------
- */
- if (exitStatus != 0)
- return;
-
- if (! pid)
+ PROC *proc;
+ SHMEM_OFFSET location;
+
+ /* --------------------
+ * If this is a FATAL exit the postmaster will have to kill all the
+ * existing backends and reinitialize shared memory. So all we don't
+ * need to do anything here.
+ * --------------------
+ */
+ if (exitStatus != 0)
+ return;
+
+ if (!pid)
{
- pid = getpid();
+ pid = getpid();
}
-
- ShmemPIDLookup(pid,&location);
- if (location == INVALID_OFFSET)
- return;
-
- proc = (PROC *) MAKE_PTR(location);
-
- if (proc != MyProc) {
- Assert( pid != getpid() );
- } else
- MyProc = NULL;
-
- /* ---------------
- * Assume one lock table.
- * ---------------
- */
- ProcReleaseSpins(proc);
- LockReleaseAll(1,&proc->lockQueue);
-
+
+ ShmemPIDLookup(pid, &location);
+ if (location == INVALID_OFFSET)
+ return;
+
+ proc = (PROC *) MAKE_PTR(location);
+
+ if (proc != MyProc)
+ {
+ Assert(pid != getpid());
+ }
+ else
+ MyProc = NULL;
+
+ /* ---------------
+ * Assume one lock table.
+ * ---------------
+ */
+ ProcReleaseSpins(proc);
+ LockReleaseAll(1, &proc->lockQueue);
+
#ifdef USER_LOCKS
- LockReleaseAll(0,&proc->lockQueue);
+ LockReleaseAll(0, &proc->lockQueue);
#endif
- /* ----------------
- * get off the wait queue
- * ----------------
- */
- LockLockTable();
- if (proc->links.next != INVALID_OFFSET) {
- Assert(proc->waitLock->waitProcs.size > 0);
- SHMQueueDelete(&(proc->links));
- --proc->waitLock->waitProcs.size;
- }
- SHMQueueElemInit(&(proc->links));
- UnlockLockTable();
-
- return;
+ /* ----------------
+ * get off the wait queue
+ * ----------------
+ */
+ LockLockTable();
+ if (proc->links.next != INVALID_OFFSET)
+ {
+ Assert(proc->waitLock->waitProcs.size > 0);
+ SHMQueueDelete(&(proc->links));
+ --proc->waitLock->waitProcs.size;
+ }
+ SHMQueueElemInit(&(proc->links));
+ UnlockLockTable();
+
+ return;
}
/*
* ProcQueue package: routines for putting processes to sleep
- * and waking them up
+ * and waking them up
*/
/*
@@ -405,33 +417,34 @@ ProcKill(int exitStatus, int pid)
* Side Effects: Initializes the queue if we allocated one
*/
#ifdef NOT_USED
-PROC_QUEUE *
+PROC_QUEUE *
ProcQueueAlloc(char *name)
{
- bool found;
- PROC_QUEUE *queue = (PROC_QUEUE *)
- ShmemInitStruct(name,(unsigned)sizeof(PROC_QUEUE),&found);
-
- if (! queue)
+ bool found;
+ PROC_QUEUE *queue = (PROC_QUEUE *)
+ ShmemInitStruct(name, (unsigned) sizeof(PROC_QUEUE), &found);
+
+ if (!queue)
{
- return(NULL);
+ return (NULL);
}
- if (! found)
+ if (!found)
{
- ProcQueueInit(queue);
+ ProcQueueInit(queue);
}
- return(queue);
+ return (queue);
}
+
#endif
/*
* ProcQueueInit -- initialize a shared memory process queue
*/
void
-ProcQueueInit(PROC_QUEUE *queue)
+ProcQueueInit(PROC_QUEUE * queue)
{
- SHMQueueInit(&(queue->links));
- queue->size = 0;
+ SHMQueueInit(&(queue->links));
+ queue->size = 0;
}
@@ -444,124 +457,126 @@ ProcQueueInit(PROC_QUEUE *queue)
* to acquire it, we sleep.
*
* ASSUME: that no one will fiddle with the queue until after
- * we release the spin lock.
+ * we release the spin lock.
*
* NOTES: The process queue is now a priority queue for locking.
*/
int
-ProcSleep(PROC_QUEUE *queue,
- SPINLOCK spinlock,
- int token,
- int prio,
- LOCK *lock)
+ProcSleep(PROC_QUEUE * queue,
+ SPINLOCK spinlock,
+ int token,
+ int prio,
+ LOCK * lock)
{
- int i;
- PROC *proc;
- struct itimerval timeval, dummy;
-
- proc = (PROC *) MAKE_PTR(queue->links.prev);
- for (i=0;i<queue->size;i++)
+ int i;
+ PROC *proc;
+ struct itimerval timeval,
+ dummy;
+
+ proc = (PROC *) MAKE_PTR(queue->links.prev);
+ for (i = 0; i < queue->size; i++)
{
- if (proc->prio < prio)
- proc = (PROC *) MAKE_PTR(proc->links.prev);
- else
- break;
+ if (proc->prio < prio)
+ proc = (PROC *) MAKE_PTR(proc->links.prev);
+ else
+ break;
}
-
- MyProc->prio = prio;
- MyProc->token = token;
- MyProc->waitLock = lock;
-
- /* -------------------
- * currently, we only need this for the ProcWakeup routines
- * -------------------
- */
- TransactionIdStore((TransactionId) GetCurrentTransactionId(), &MyProc->xid);
-
- /* -------------------
- * assume that these two operations are atomic (because
- * of the spinlock).
- * -------------------
- */
- SHMQueueInsertTL(&(proc->links),&(MyProc->links));
- queue->size++;
-
- SpinRelease(spinlock);
-
- /* --------------
- * Postgres does not have any deadlock detection code and for this
- * reason we must set a timer to wake up the process in the event of
- * a deadlock. For now the timer is set for 1 minute and we assume that
- * any process which sleeps for this amount of time is deadlocked and will
- * receive a SIGALRM signal. The handler should release the processes
- * semaphore and abort the current transaction.
- *
- * Need to zero out struct to set the interval and the micro seconds fields
- * to 0.
- * --------------
- */
- memset(&timeval, 0, sizeof(struct itimerval));
- timeval.it_value.tv_sec = DEADLOCK_TIMEOUT;
-
- if (setitimer(ITIMER_REAL, &timeval, &dummy))
- elog(FATAL, "ProcSleep: Unable to set timer for process wakeup");
-
- /* --------------
- * if someone wakes us between SpinRelease and IpcSemaphoreLock,
- * IpcSemaphoreLock will not block. The wakeup is "saved" by
- * the semaphore implementation.
- * --------------
- */
- IpcSemaphoreLock(MyProc->sem.semId, MyProc->sem.semNum, IpcExclusiveLock);
-
- /* ---------------
- * We were awoken before a timeout - now disable the timer
- * ---------------
- */
- timeval.it_value.tv_sec = 0;
-
-
- if (setitimer(ITIMER_REAL, &timeval, &dummy))
- elog(FATAL, "ProcSleep: Unable to diable timer for process wakeup");
-
- /* ----------------
- * We were assumed to be in a critical section when we went
- * to sleep.
- * ----------------
- */
- SpinAcquire(spinlock);
-
- return(MyProc->errType);
+
+ MyProc->prio = prio;
+ MyProc->token = token;
+ MyProc->waitLock = lock;
+
+ /* -------------------
+ * currently, we only need this for the ProcWakeup routines
+ * -------------------
+ */
+ TransactionIdStore((TransactionId) GetCurrentTransactionId(), &MyProc->xid);
+
+ /* -------------------
+ * assume that these two operations are atomic (because
+ * of the spinlock).
+ * -------------------
+ */
+ SHMQueueInsertTL(&(proc->links), &(MyProc->links));
+ queue->size++;
+
+ SpinRelease(spinlock);
+
+ /* --------------
+ * Postgres does not have any deadlock detection code and for this
+ * reason we must set a timer to wake up the process in the event of
+ * a deadlock. For now the timer is set for 1 minute and we assume that
+ * any process which sleeps for this amount of time is deadlocked and will
+ * receive a SIGALRM signal. The handler should release the processes
+ * semaphore and abort the current transaction.
+ *
+ * Need to zero out struct to set the interval and the micro seconds fields
+ * to 0.
+ * --------------
+ */
+ memset(&timeval, 0, sizeof(struct itimerval));
+ timeval.it_value.tv_sec = DEADLOCK_TIMEOUT;
+
+ if (setitimer(ITIMER_REAL, &timeval, &dummy))
+ elog(FATAL, "ProcSleep: Unable to set timer for process wakeup");
+
+ /* --------------
+ * if someone wakes us between SpinRelease and IpcSemaphoreLock,
+ * IpcSemaphoreLock will not block. The wakeup is "saved" by
+ * the semaphore implementation.
+ * --------------
+ */
+ IpcSemaphoreLock(MyProc->sem.semId, MyProc->sem.semNum, IpcExclusiveLock);
+
+ /* ---------------
+ * We were awoken before a timeout - now disable the timer
+ * ---------------
+ */
+ timeval.it_value.tv_sec = 0;
+
+
+ if (setitimer(ITIMER_REAL, &timeval, &dummy))
+ elog(FATAL, "ProcSleep: Unable to diable timer for process wakeup");
+
+ /* ----------------
+ * We were assumed to be in a critical section when we went
+ * to sleep.
+ * ----------------
+ */
+ SpinAcquire(spinlock);
+
+ return (MyProc->errType);
}
/*
* ProcWakeup -- wake up a process by releasing its private semaphore.
*
- * remove the process from the wait queue and set its links invalid.
- * RETURN: the next process in the wait queue.
+ * remove the process from the wait queue and set its links invalid.
+ * RETURN: the next process in the wait queue.
*/
-static PROC *
-ProcWakeup(PROC *proc, int errType)
+static PROC *
+ProcWakeup(PROC * proc, int errType)
{
- PROC *retProc;
- /* assume that spinlock has been acquired */
-
- if (proc->links.prev == INVALID_OFFSET ||
- proc->links.next == INVALID_OFFSET)
- return((PROC *) NULL);
-
- retProc = (PROC *) MAKE_PTR(proc->links.prev);
-
- /* you have to update waitLock->waitProcs.size yourself */
- SHMQueueDelete(&(proc->links));
- SHMQueueElemInit(&(proc->links));
-
- proc->errType = errType;
-
- IpcSemaphoreUnlock(proc->sem.semId, proc->sem.semNum, IpcExclusiveLock);
-
- return retProc;
+ PROC *retProc;
+
+ /* assume that spinlock has been acquired */
+
+ if (proc->links.prev == INVALID_OFFSET ||
+ proc->links.next == INVALID_OFFSET)
+ return ((PROC *) NULL);
+
+ retProc = (PROC *) MAKE_PTR(proc->links.prev);
+
+ /* you have to update waitLock->waitProcs.size yourself */
+ SHMQueueDelete(&(proc->links));
+ SHMQueueElemInit(&(proc->links));
+
+ proc->errType = errType;
+
+ IpcSemaphoreUnlock(proc->sem.semId, proc->sem.semNum, IpcExclusiveLock);
+
+ return retProc;
}
@@ -572,61 +587,64 @@ ProcWakeup(PROC *proc, int errType)
int
ProcGetId()
{
- return( MyProc->procId );
+ return (MyProc->procId);
}
+
#endif
/*
* ProcLockWakeup -- routine for waking up processes when a lock is
- * released.
+ * released.
*/
int
-ProcLockWakeup(PROC_QUEUE *queue, char *ltable, char *lock)
+ProcLockWakeup(PROC_QUEUE * queue, char *ltable, char *lock)
{
- PROC *proc;
- int count;
-
- if (! queue->size)
- return(STATUS_NOT_FOUND);
-
- proc = (PROC *) MAKE_PTR(queue->links.prev);
- count = 0;
- while ((LockResolveConflicts ((LOCKTAB *) ltable,
- (LOCK *) lock,
- proc->token,
- proc->xid) == STATUS_OK))
+ PROC *proc;
+ int count;
+
+ if (!queue->size)
+ return (STATUS_NOT_FOUND);
+
+ proc = (PROC *) MAKE_PTR(queue->links.prev);
+ count = 0;
+ while ((LockResolveConflicts((LOCKTAB *) ltable,
+ (LOCK *) lock,
+ proc->token,
+ proc->xid) == STATUS_OK))
{
- /* there was a waiting process, grant it the lock before waking it
- * up. This will prevent another process from seizing the lock
- * between the time we release the lock master (spinlock) and
- * the time that the awoken process begins executing again.
- */
- GrantLock((LOCK *) lock, proc->token);
- queue->size--;
-
- /*
- * ProcWakeup removes proc from the lock waiting process queue and
- * returns the next proc in chain. If a writer just dropped
- * its lock and there are several waiting readers, wake them all up.
- */
- proc = ProcWakeup(proc, NO_ERROR);
-
- count++;
- if (!proc || queue->size == 0)
- break;
+
+ /*
+ * there was a waiting process, grant it the lock before waking it
+ * up. This will prevent another process from seizing the lock
+ * between the time we release the lock master (spinlock) and the
+ * time that the awoken process begins executing again.
+ */
+ GrantLock((LOCK *) lock, proc->token);
+ queue->size--;
+
+ /*
+ * ProcWakeup removes proc from the lock waiting process queue and
+ * returns the next proc in chain. If a writer just dropped its
+ * lock and there are several waiting readers, wake them all up.
+ */
+ proc = ProcWakeup(proc, NO_ERROR);
+
+ count++;
+ if (!proc || queue->size == 0)
+ break;
}
-
- if (count)
- return(STATUS_OK);
- else
- /* Something is still blocking us. May have deadlocked. */
- return(STATUS_NOT_FOUND);
+
+ if (count)
+ return (STATUS_OK);
+ else
+ /* Something is still blocking us. May have deadlocked. */
+ return (STATUS_NOT_FOUND);
}
void
-ProcAddLock(SHM_QUEUE *elem)
+ProcAddLock(SHM_QUEUE * elem)
{
- SHMQueueInsertTL(&MyProc->lockQueue,elem);
+ SHMQueueInsertTL(&MyProc->lockQueue, elem);
}
/* --------------------
@@ -634,194 +652,201 @@ ProcAddLock(SHM_QUEUE *elem)
* while waiting for a lock to be released by some other process. After
* the one minute deadline we assume we have a deadlock and must abort
* this transaction. We must also indicate that I'm no longer waiting
- * on a lock so that other processes don't try to wake me up and screw
+ * on a lock so that other processes don't try to wake me up and screw
* up my semaphore.
* --------------------
*/
static void
HandleDeadLock(int sig)
{
- LOCK *lock;
- int size;
-
- LockLockTable();
-
- /* ---------------------
- * Check to see if we've been awoken by anyone in the interim.
- *
- * If we have we can return and resume our transaction -- happy day.
- * Before we are awoken the process releasing the lock grants it to
- * us so we know that we don't have to wait anymore.
- *
- * Damn these names are LONG! -mer
- * ---------------------
- */
- if (IpcSemaphoreGetCount(MyProc->sem.semId, MyProc->sem.semNum) ==
- IpcSemaphoreDefaultStartValue) {
- UnlockLockTable();
- return;
- }
-
- /*
- * you would think this would be unnecessary, but...
- *
- * this also means we've been removed already. in some ports
- * (e.g., sparc and aix) the semop(2) implementation is such that
- * we can actually end up in this handler after someone has removed
- * us from the queue and bopped the semaphore *but the test above
- * fails to detect the semaphore update* (presumably something weird
- * having to do with the order in which the semaphore wakeup signal
- * and SIGALRM get handled).
- */
- if (MyProc->links.prev == INVALID_OFFSET ||
- MyProc->links.next == INVALID_OFFSET) {
- UnlockLockTable();
- return;
- }
-
- lock = MyProc->waitLock;
- size = lock->waitProcs.size; /* so we can look at this in the core */
-
+ LOCK *lock;
+ int size;
+
+ LockLockTable();
+
+ /* ---------------------
+ * Check to see if we've been awoken by anyone in the interim.
+ *
+ * If we have we can return and resume our transaction -- happy day.
+ * Before we are awoken the process releasing the lock grants it to
+ * us so we know that we don't have to wait anymore.
+ *
+ * Damn these names are LONG! -mer
+ * ---------------------
+ */
+ if (IpcSemaphoreGetCount(MyProc->sem.semId, MyProc->sem.semNum) ==
+ IpcSemaphoreDefaultStartValue)
+ {
+ UnlockLockTable();
+ return;
+ }
+
+ /*
+ * you would think this would be unnecessary, but...
+ *
+ * this also means we've been removed already. in some ports (e.g.,
+ * sparc and aix) the semop(2) implementation is such that we can
+ * actually end up in this handler after someone has removed us from
+ * the queue and bopped the semaphore *but the test above fails to
+ * detect the semaphore update* (presumably something weird having to
+ * do with the order in which the semaphore wakeup signal and SIGALRM
+ * get handled).
+ */
+ if (MyProc->links.prev == INVALID_OFFSET ||
+ MyProc->links.next == INVALID_OFFSET)
+ {
+ UnlockLockTable();
+ return;
+ }
+
+ lock = MyProc->waitLock;
+ size = lock->waitProcs.size;/* so we can look at this in the core */
+
#ifdef DEADLOCK_DEBUG
- DumpLocks();
+ DumpLocks();
#endif
- /* ------------------------
- * Get this process off the lock's wait queue
- * ------------------------
- */
- Assert(lock->waitProcs.size > 0);
- --lock->waitProcs.size;
- SHMQueueDelete(&(MyProc->links));
- SHMQueueElemInit(&(MyProc->links));
-
- /* ------------------
- * Unlock my semaphore so that the count is right for next time.
- * I was awoken by a signal, not by someone unlocking my semaphore.
- * ------------------
- */
- IpcSemaphoreUnlock(MyProc->sem.semId, MyProc->sem.semNum, IpcExclusiveLock);
-
- /* -------------
- * Set MyProc->errType to STATUS_ERROR so that we abort after
- * returning from this handler.
- * -------------
- */
- MyProc->errType = STATUS_ERROR;
-
- /*
- * if this doesn't follow the IpcSemaphoreUnlock then we get lock
- * table corruption ("LockReplace: xid table corrupted") due to
- * race conditions. i don't claim to understand this...
- */
- UnlockLockTable();
-
- elog(NOTICE, "Timeout -- possible deadlock");
- return;
+ /* ------------------------
+ * Get this process off the lock's wait queue
+ * ------------------------
+ */
+ Assert(lock->waitProcs.size > 0);
+ --lock->waitProcs.size;
+ SHMQueueDelete(&(MyProc->links));
+ SHMQueueElemInit(&(MyProc->links));
+
+ /* ------------------
+ * Unlock my semaphore so that the count is right for next time.
+ * I was awoken by a signal, not by someone unlocking my semaphore.
+ * ------------------
+ */
+ IpcSemaphoreUnlock(MyProc->sem.semId, MyProc->sem.semNum, IpcExclusiveLock);
+
+ /* -------------
+ * Set MyProc->errType to STATUS_ERROR so that we abort after
+ * returning from this handler.
+ * -------------
+ */
+ MyProc->errType = STATUS_ERROR;
+
+ /*
+ * if this doesn't follow the IpcSemaphoreUnlock then we get lock
+ * table corruption ("LockReplace: xid table corrupted") due to race
+ * conditions. i don't claim to understand this...
+ */
+ UnlockLockTable();
+
+ elog(NOTICE, "Timeout -- possible deadlock");
+ return;
}
void
-ProcReleaseSpins(PROC *proc)
+ProcReleaseSpins(PROC * proc)
{
- int i;
-
- if (!proc)
- proc = MyProc;
-
- if (!proc)
- return;
- for (i=0; i < (int)MAX_SPINS; i++)
+ int i;
+
+ if (!proc)
+ proc = MyProc;
+
+ if (!proc)
+ return;
+ for (i = 0; i < (int) MAX_SPINS; i++)
{
- if (proc->sLocks[i])
+ if (proc->sLocks[i])
{
- Assert(proc->sLocks[i] == 1);
- SpinRelease(i);
+ Assert(proc->sLocks[i] == 1);
+ SpinRelease(i);
}
}
}
/*****************************************************************************
- *
+ *
*****************************************************************************/
/*
* ProcGetNewSemKeyAndNum -
- * scan the free semaphore bitmap and allocate a single semaphore from
- * a semaphore set. (If the semaphore set doesn't exist yet,
- * IpcSemaphoreCreate will create it. Otherwise, we use the existing
- * semaphore set.)
+ * scan the free semaphore bitmap and allocate a single semaphore from
+ * a semaphore set. (If the semaphore set doesn't exist yet,
+ * IpcSemaphoreCreate will create it. Otherwise, we use the existing
+ * semaphore set.)
*/
static void
-ProcGetNewSemKeyAndNum(IPCKey *key, int *semNum)
+ProcGetNewSemKeyAndNum(IPCKey * key, int *semNum)
{
- int i;
- int32 *freeSemMap = ProcGlobal->freeSemMap;
- unsigned int fullmask;
-
- /*
- * we hold ProcStructLock when entering this routine. We scan through
- * the bitmap to look for a free semaphore.
- */
- fullmask = ~0 >> (32 - PROC_NSEMS_PER_SET);
- for(i=0; i < MAX_PROC_SEMS/PROC_NSEMS_PER_SET; i++) {
- int mask = 1;
- int j;
-
- if (freeSemMap[i] == fullmask)
- continue; /* none free for this set */
-
- for(j = 0; j < PROC_NSEMS_PER_SET; j++) {
- if ((freeSemMap[i] & mask) == 0) {
- /*
- * a free semaphore found. Mark it as allocated.
- */
- freeSemMap[i] |= mask;
+ int i;
+ int32 *freeSemMap = ProcGlobal->freeSemMap;
+ unsigned int fullmask;
- *key = ProcGlobal->currKey + i;
- *semNum = j;
- return;
- }
- mask <<= 1;
+ /*
+ * we hold ProcStructLock when entering this routine. We scan through
+ * the bitmap to look for a free semaphore.
+ */
+ fullmask = ~0 >> (32 - PROC_NSEMS_PER_SET);
+ for (i = 0; i < MAX_PROC_SEMS / PROC_NSEMS_PER_SET; i++)
+ {
+ int mask = 1;
+ int j;
+
+ if (freeSemMap[i] == fullmask)
+ continue; /* none free for this set */
+
+ for (j = 0; j < PROC_NSEMS_PER_SET; j++)
+ {
+ if ((freeSemMap[i] & mask) == 0)
+ {
+
+ /*
+ * a free semaphore found. Mark it as allocated.
+ */
+ freeSemMap[i] |= mask;
+
+ *key = ProcGlobal->currKey + i;
+ *semNum = j;
+ return;
+ }
+ mask <<= 1;
+ }
}
- }
- /* if we reach here, all the semaphores are in use. */
- elog(WARN, "InitProc: cannot allocate a free semaphore");
+ /* if we reach here, all the semaphores are in use. */
+ elog(WARN, "InitProc: cannot allocate a free semaphore");
}
/*
* ProcFreeSem -
- * free up our semaphore in the semaphore set. If we're the last one
- * in the set, also remove the semaphore set.
+ * free up our semaphore in the semaphore set. If we're the last one
+ * in the set, also remove the semaphore set.
*/
static void
ProcFreeSem(IpcSemaphoreKey semKey, int semNum)
{
- int mask;
- int i;
- int32 *freeSemMap = ProcGlobal->freeSemMap;
+ int mask;
+ int i;
+ int32 *freeSemMap = ProcGlobal->freeSemMap;
- i = semKey - ProcGlobal->currKey;
- mask = ~(1 << semNum);
- freeSemMap[i] &= mask;
+ i = semKey - ProcGlobal->currKey;
+ mask = ~(1 << semNum);
+ freeSemMap[i] &= mask;
- if (freeSemMap[i]==0)
- IpcSemaphoreKill(semKey);
+ if (freeSemMap[i] == 0)
+ IpcSemaphoreKill(semKey);
}
/*
* ProcFreeAllSemaphores -
- * on exiting the postmaster, we free up all the semaphores allocated
- * to the lmgrs of the backends.
+ * on exiting the postmaster, we free up all the semaphores allocated
+ * to the lmgrs of the backends.
*/
void
ProcFreeAllSemaphores()
{
- int i;
- int32 *freeSemMap = ProcGlobal->freeSemMap;
+ int i;
+ int32 *freeSemMap = ProcGlobal->freeSemMap;
- for(i=0; i < MAX_PROC_SEMS/PROC_NSEMS_PER_SET; i++) {
- if (freeSemMap[i]!=0)
- IpcSemaphoreKill(ProcGlobal->currKey + i);
- }
+ for (i = 0; i < MAX_PROC_SEMS / PROC_NSEMS_PER_SET; i++)
+ {
+ if (freeSemMap[i] != 0)
+ IpcSemaphoreKill(ProcGlobal->currKey + i);
+ }
}
diff --git a/src/backend/storage/lmgr/single.c b/src/backend/storage/lmgr/single.c
index 20feddbed9f..80220368437 100644
--- a/src/backend/storage/lmgr/single.c
+++ b/src/backend/storage/lmgr/single.c
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* single.c--
- * set single locks in the multi-level lock hierarchy
+ * set single locks in the multi-level lock hierarchy
*
- * Sometimes we don't want to set all levels of the multi-level
- * lock hierarchy at once. This allows us to set and release
- * one level at a time. It's useful in index scans when
- * you can set an intent lock at the beginning and thereafter
- * only set page locks. Tends to speed things up.
+ * Sometimes we don't want to set all levels of the multi-level
+ * lock hierarchy at once. This allows us to set and release
+ * one level at a time. It's useful in index scans when
+ * you can set an intent lock at the beginning and thereafter
+ * only set page locks. Tends to speed things up.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/single.c,v 1.2 1996/11/03 05:07:33 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/single.c,v 1.3 1997/09/07 04:49:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,7 +21,7 @@
#include "postgres.h"
-#include "storage/lmgr.h" /* where the declarations go */
+#include "storage/lmgr.h" /* where the declarations go */
#include "storage/lock.h"
#include "storage/multilev.h"
#include "utils/rel.h"
@@ -34,28 +34,27 @@
bool
SingleLockReln(LockInfo linfo, LOCKT lockt, int action)
{
- LOCKTAG tag;
-
- /*
- * LOCKTAG has two bytes of padding, unfortunately. The
- * hash function will return miss if the padding bytes aren't
- * zero'd.
- */
- memset(&tag,0,sizeof(tag));
- tag.relId = linfo->lRelId.relId;
- tag.dbId = linfo->lRelId.dbId;
- BlockIdSet(&(tag.tupleId.ip_blkid), InvalidBlockNumber);
- tag.tupleId.ip_posid = InvalidOffsetNumber;
-
- if (action == UNLOCK)
- return(LockRelease(MultiTableId, &tag, lockt));
- else
- return(LockAcquire(MultiTableId, &tag, lockt));
+ LOCKTAG tag;
+
+ /*
+ * LOCKTAG has two bytes of padding, unfortunately. The hash function
+ * will return miss if the padding bytes aren't zero'd.
+ */
+ memset(&tag, 0, sizeof(tag));
+ tag.relId = linfo->lRelId.relId;
+ tag.dbId = linfo->lRelId.dbId;
+ BlockIdSet(&(tag.tupleId.ip_blkid), InvalidBlockNumber);
+ tag.tupleId.ip_posid = InvalidOffsetNumber;
+
+ if (action == UNLOCK)
+ return (LockRelease(MultiTableId, &tag, lockt));
+ else
+ return (LockAcquire(MultiTableId, &tag, lockt));
}
/*
* SingleLockPage -- use multi-level lock table, but lock
- * only at the page level.
+ * only at the page level.
*
* Assumes that an INTENT lock has already been set in the
* multi-level lock table.
@@ -63,27 +62,25 @@ SingleLockReln(LockInfo linfo, LOCKT lockt, int action)
*/
bool
SingleLockPage(LockInfo linfo,
- ItemPointer tidPtr,
- LOCKT lockt,
- int action)
+ ItemPointer tidPtr,
+ LOCKT lockt,
+ int action)
{
- LOCKTAG tag;
-
- /*
- * LOCKTAG has two bytes of padding, unfortunately. The
- * hash function will return miss if the padding bytes aren't
- * zero'd.
- */
- memset(&tag,0,sizeof(tag));
- tag.relId = linfo->lRelId.relId;
- tag.dbId = linfo->lRelId.dbId;
- BlockIdCopy(&(tag.tupleId.ip_blkid), &(tidPtr->ip_blkid));
- tag.tupleId.ip_posid = InvalidOffsetNumber;
-
-
- if (action == UNLOCK)
- return(LockRelease(MultiTableId, &tag, lockt));
- else
- return(LockAcquire(MultiTableId, &tag, lockt));
-}
+ LOCKTAG tag;
+ /*
+ * LOCKTAG has two bytes of padding, unfortunately. The hash function
+ * will return miss if the padding bytes aren't zero'd.
+ */
+ memset(&tag, 0, sizeof(tag));
+ tag.relId = linfo->lRelId.relId;
+ tag.dbId = linfo->lRelId.dbId;
+ BlockIdCopy(&(tag.tupleId.ip_blkid), &(tidPtr->ip_blkid));
+ tag.tupleId.ip_posid = InvalidOffsetNumber;
+
+
+ if (action == UNLOCK)
+ return (LockRelease(MultiTableId, &tag, lockt));
+ else
+ return (LockAcquire(MultiTableId, &tag, lockt));
+}
diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c
index 98d1c59d5f0..75e1b5da9e7 100644
--- a/src/backend/storage/page/bufpage.c
+++ b/src/backend/storage/page/bufpage.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* bufpage.c--
- * POSTGRES standard buffer page code.
+ * POSTGRES standard buffer page code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/page/bufpage.c,v 1.8 1997/08/24 23:07:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/page/bufpage.c,v 1.9 1997/09/07 04:49:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,341 +26,368 @@
#include "lib/qsort.h"
-static void PageIndexTupleDeleteAdjustLinePointers(PageHeader phdr,
- char *location, Size size);
+static void
+PageIndexTupleDeleteAdjustLinePointers(PageHeader phdr,
+ char *location, Size size);
-static bool PageManagerShuffle = true; /* default is shuffle mode */
+static bool PageManagerShuffle = true; /* default is shuffle mode */
/* ----------------------------------------------------------------
- * Page support functions
+ * Page support functions
* ----------------------------------------------------------------
*/
/*
* PageInit --
- * Initializes the contents of a page.
+ * Initializes the contents of a page.
*/
void
PageInit(Page page, Size pageSize, Size specialSize)
{
- PageHeader p = (PageHeader) page;
-
- Assert(pageSize == BLCKSZ);
- Assert(pageSize >
- specialSize + sizeof(PageHeaderData) - sizeof(ItemIdData));
-
- specialSize = DOUBLEALIGN(specialSize);
-
- p->pd_lower = sizeof(PageHeaderData) - sizeof(ItemIdData);
- p->pd_upper = pageSize - specialSize;
- p->pd_special = pageSize - specialSize;
- PageSetPageSize(page, pageSize);
+ PageHeader p = (PageHeader) page;
+
+ Assert(pageSize == BLCKSZ);
+ Assert(pageSize >
+ specialSize + sizeof(PageHeaderData) - sizeof(ItemIdData));
+
+ specialSize = DOUBLEALIGN(specialSize);
+
+ p->pd_lower = sizeof(PageHeaderData) - sizeof(ItemIdData);
+ p->pd_upper = pageSize - specialSize;
+ p->pd_special = pageSize - specialSize;
+ PageSetPageSize(page, pageSize);
}
/*
* PageAddItem --
- * Adds item to the given page.
+ * Adds item to the given page.
*
* Note:
- * This does not assume that the item resides on a single page.
- * It is the responsiblity of the caller to act appropriately
- * depending on this fact. The "pskip" routines provide a
- * friendlier interface, in this case.
- *
- * This does change the status of any of the resources passed.
- * The semantics may change in the future.
+ * This does not assume that the item resides on a single page.
+ * It is the responsiblity of the caller to act appropriately
+ * depending on this fact. The "pskip" routines provide a
+ * friendlier interface, in this case.
+ *
+ * This does change the status of any of the resources passed.
+ * The semantics may change in the future.
*
- * This routine should probably be combined with others?
+ * This routine should probably be combined with others?
*/
/* ----------------
- * PageAddItem
+ * PageAddItem
*
- * add an item to a page.
+ * add an item to a page.
*
- * Notes on interface:
- * If offsetNumber is valid, shuffle ItemId's down to make room
- * to use it, if PageManagerShuffle is true. If PageManagerShuffle is
- * false, then overwrite the specified ItemId. (PageManagerShuffle is
- * true by default, and is modified by calling PageManagerModeSet.)
- * If offsetNumber is not valid, then assign one by finding the first
- * one that is both unused and deallocated.
+ * Notes on interface:
+ * If offsetNumber is valid, shuffle ItemId's down to make room
+ * to use it, if PageManagerShuffle is true. If PageManagerShuffle is
+ * false, then overwrite the specified ItemId. (PageManagerShuffle is
+ * true by default, and is modified by calling PageManagerModeSet.)
+ * If offsetNumber is not valid, then assign one by finding the first
+ * one that is both unused and deallocated.
*
- * NOTE: If offsetNumber is valid, and PageManagerShuffle is true, it
- * is assumed that there is room on the page to shuffle the ItemId's
- * down by one.
+ * NOTE: If offsetNumber is valid, and PageManagerShuffle is true, it
+ * is assumed that there is room on the page to shuffle the ItemId's
+ * down by one.
* ----------------
*/
OffsetNumber
PageAddItem(Page page,
- Item item,
- Size size,
- OffsetNumber offsetNumber,
- ItemIdFlags flags)
+ Item item,
+ Size size,
+ OffsetNumber offsetNumber,
+ ItemIdFlags flags)
{
- register i;
- Size alignedSize;
- Offset lower;
- Offset upper;
- ItemId itemId;
- ItemId fromitemId, toitemId;
- OffsetNumber limit;
-
- bool shuffled = false;
-
- /*
- * Find first unallocated offsetNumber
- */
- limit = OffsetNumberNext(PageGetMaxOffsetNumber(page));
-
- /* was offsetNumber passed in? */
- if (OffsetNumberIsValid(offsetNumber)) {
- if (PageManagerShuffle == true) {
- /* shuffle ItemId's (Do the PageManager Shuffle...) */
- for (i = (limit - 1); i >= offsetNumber; i--) {
- fromitemId = &((PageHeader)page)->pd_linp[i - 1];
- toitemId = &((PageHeader)page)->pd_linp[i];
- *toitemId = *fromitemId;
- }
- shuffled = true; /* need to increase "lower" */
- } else { /* overwrite mode */
- itemId = &((PageHeader)page)->pd_linp[offsetNumber - 1];
- if (((*itemId).lp_flags & LP_USED) ||
- ((*itemId).lp_len != 0)) {
- elog(WARN, "PageAddItem: tried overwrite of used ItemId");
- return (InvalidOffsetNumber);
- }
+ register i;
+ Size alignedSize;
+ Offset lower;
+ Offset upper;
+ ItemId itemId;
+ ItemId fromitemId,
+ toitemId;
+ OffsetNumber limit;
+
+ bool shuffled = false;
+
+ /*
+ * Find first unallocated offsetNumber
+ */
+ limit = OffsetNumberNext(PageGetMaxOffsetNumber(page));
+
+ /* was offsetNumber passed in? */
+ if (OffsetNumberIsValid(offsetNumber))
+ {
+ if (PageManagerShuffle == true)
+ {
+ /* shuffle ItemId's (Do the PageManager Shuffle...) */
+ for (i = (limit - 1); i >= offsetNumber; i--)
+ {
+ fromitemId = &((PageHeader) page)->pd_linp[i - 1];
+ toitemId = &((PageHeader) page)->pd_linp[i];
+ *toitemId = *fromitemId;
+ }
+ shuffled = true; /* need to increase "lower" */
+ }
+ else
+ { /* overwrite mode */
+ itemId = &((PageHeader) page)->pd_linp[offsetNumber - 1];
+ if (((*itemId).lp_flags & LP_USED) ||
+ ((*itemId).lp_len != 0))
+ {
+ elog(WARN, "PageAddItem: tried overwrite of used ItemId");
+ return (InvalidOffsetNumber);
+ }
+ }
}
- } else { /* offsetNumber was not passed in, so find one */
- /* look for "recyclable" (unused & deallocated) ItemId */
- for (offsetNumber = 1; offsetNumber < limit; offsetNumber++) {
- itemId = &((PageHeader)page)->pd_linp[offsetNumber - 1];
- if ((((*itemId).lp_flags & LP_USED) == 0) &&
- ((*itemId).lp_len == 0))
- break;
+ else
+ { /* offsetNumber was not passed in, so find
+ * one */
+ /* look for "recyclable" (unused & deallocated) ItemId */
+ for (offsetNumber = 1; offsetNumber < limit; offsetNumber++)
+ {
+ itemId = &((PageHeader) page)->pd_linp[offsetNumber - 1];
+ if ((((*itemId).lp_flags & LP_USED) == 0) &&
+ ((*itemId).lp_len == 0))
+ break;
+ }
}
- }
- if (offsetNumber > limit)
- lower = (Offset) (((char *) (&((PageHeader)page)->pd_linp[offsetNumber])) - ((char *) page));
- else if (offsetNumber == limit || shuffled == true)
- lower = ((PageHeader)page)->pd_lower + sizeof (ItemIdData);
- else
- lower = ((PageHeader)page)->pd_lower;
-
- alignedSize = DOUBLEALIGN(size);
-
- upper = ((PageHeader)page)->pd_upper - alignedSize;
-
- if (lower > upper) {
- return (InvalidOffsetNumber);
- }
-
- itemId = &((PageHeader)page)->pd_linp[offsetNumber - 1];
- (*itemId).lp_off = upper;
- (*itemId).lp_len = size;
- (*itemId).lp_flags = flags;
- memmove((char *)page + upper, item, size);
- ((PageHeader)page)->pd_lower = lower;
- ((PageHeader)page)->pd_upper = upper;
-
- return (offsetNumber);
+ if (offsetNumber > limit)
+ lower = (Offset) (((char *) (&((PageHeader) page)->pd_linp[offsetNumber])) - ((char *) page));
+ else if (offsetNumber == limit || shuffled == true)
+ lower = ((PageHeader) page)->pd_lower + sizeof(ItemIdData);
+ else
+ lower = ((PageHeader) page)->pd_lower;
+
+ alignedSize = DOUBLEALIGN(size);
+
+ upper = ((PageHeader) page)->pd_upper - alignedSize;
+
+ if (lower > upper)
+ {
+ return (InvalidOffsetNumber);
+ }
+
+ itemId = &((PageHeader) page)->pd_linp[offsetNumber - 1];
+ (*itemId).lp_off = upper;
+ (*itemId).lp_len = size;
+ (*itemId).lp_flags = flags;
+ memmove((char *) page + upper, item, size);
+ ((PageHeader) page)->pd_lower = lower;
+ ((PageHeader) page)->pd_upper = upper;
+
+ return (offsetNumber);
}
/*
* PageGetTempPage --
- * Get a temporary page in local memory for special processing
+ * Get a temporary page in local memory for special processing
*/
Page
PageGetTempPage(Page page, Size specialSize)
{
- Size pageSize;
- Size size;
- Page temp;
- PageHeader thdr;
-
- pageSize = PageGetPageSize(page);
-
- if ((temp = (Page) palloc(pageSize)) == (Page) NULL)
- elog(FATAL, "Cannot allocate %d bytes for temp page.", pageSize);
- thdr = (PageHeader) temp;
-
- /* copy old page in */
- memmove(temp, page, pageSize);
-
- /* clear out the middle */
- size = (pageSize - sizeof(PageHeaderData)) + sizeof(ItemIdData);
- size -= DOUBLEALIGN(specialSize);
- memset((char *) &(thdr->pd_linp[0]), 0, size);
-
- /* set high, low water marks */
- thdr->pd_lower = sizeof (PageHeaderData) - sizeof (ItemIdData);
- thdr->pd_upper = pageSize - DOUBLEALIGN(specialSize);
-
- return (temp);
+ Size pageSize;
+ Size size;
+ Page temp;
+ PageHeader thdr;
+
+ pageSize = PageGetPageSize(page);
+
+ if ((temp = (Page) palloc(pageSize)) == (Page) NULL)
+ elog(FATAL, "Cannot allocate %d bytes for temp page.", pageSize);
+ thdr = (PageHeader) temp;
+
+ /* copy old page in */
+ memmove(temp, page, pageSize);
+
+ /* clear out the middle */
+ size = (pageSize - sizeof(PageHeaderData)) + sizeof(ItemIdData);
+ size -= DOUBLEALIGN(specialSize);
+ memset((char *) &(thdr->pd_linp[0]), 0, size);
+
+ /* set high, low water marks */
+ thdr->pd_lower = sizeof(PageHeaderData) - sizeof(ItemIdData);
+ thdr->pd_upper = pageSize - DOUBLEALIGN(specialSize);
+
+ return (temp);
}
/*
* PageRestoreTempPage --
- * Copy temporary page back to permanent page after special processing
- * and release the temporary page.
+ * Copy temporary page back to permanent page after special processing
+ * and release the temporary page.
*/
void
PageRestoreTempPage(Page tempPage, Page oldPage)
{
- Size pageSize;
-
- pageSize = PageGetPageSize(tempPage);
- memmove((char *) oldPage, (char *) tempPage, pageSize);
-
- pfree(tempPage);
+ Size pageSize;
+
+ pageSize = PageGetPageSize(tempPage);
+ memmove((char *) oldPage, (char *) tempPage, pageSize);
+
+ pfree(tempPage);
}
/*
* PageGetMaxOffsetNumber --
- * Returns the maximum offset number used by the given page.
+ * Returns the maximum offset number used by the given page.
*
- * NOTE: The offset is invalid if the page is non-empty.
- * Test whether PageIsEmpty before calling this routine
- * and/or using its return value.
+ * NOTE: The offset is invalid if the page is non-empty.
+ * Test whether PageIsEmpty before calling this routine
+ * and/or using its return value.
*/
OffsetNumber
PageGetMaxOffsetNumber(Page page)
{
- LocationIndex low;
- OffsetNumber i;
-
- low = ((PageHeader) page)->pd_lower;
- i = (low - (sizeof(PageHeaderData) - sizeof(ItemIdData)))
- / sizeof(ItemIdData);
-
- return(i);
-}
+ LocationIndex low;
+ OffsetNumber i;
+
+ low = ((PageHeader) page)->pd_lower;
+ i = (low - (sizeof(PageHeaderData) - sizeof(ItemIdData)))
+ / sizeof(ItemIdData);
+
+ return (i);
+}
/* ----------------
- * itemid stuff for PageRepairFragmentation
+ * itemid stuff for PageRepairFragmentation
* ----------------
*/
-struct itemIdSortData {
- int offsetindex; /* linp array index */
- ItemIdData itemiddata;
+struct itemIdSortData
+{
+ int offsetindex;/* linp array index */
+ ItemIdData itemiddata;
};
static int
itemidcompare(void *itemidp1, void *itemidp2)
{
- if (((struct itemIdSortData *)itemidp1)->itemiddata.lp_off ==
- ((struct itemIdSortData *)itemidp2)->itemiddata.lp_off)
- return(0);
- else if (((struct itemIdSortData *)itemidp1)->itemiddata.lp_off <
- ((struct itemIdSortData *)itemidp2)->itemiddata.lp_off)
- return(1);
- else
- return(-1);
+ if (((struct itemIdSortData *) itemidp1)->itemiddata.lp_off ==
+ ((struct itemIdSortData *) itemidp2)->itemiddata.lp_off)
+ return (0);
+ else if (((struct itemIdSortData *) itemidp1)->itemiddata.lp_off <
+ ((struct itemIdSortData *) itemidp2)->itemiddata.lp_off)
+ return (1);
+ else
+ return (-1);
}
/*
* PageRepairFragmentation --
- * Frees fragmented space on a page.
+ * Frees fragmented space on a page.
*/
void
PageRepairFragmentation(Page page)
{
- int i;
- struct itemIdSortData *itemidbase, *itemidptr;
- ItemId lp;
- int nline, nused;
- Offset upper;
- Size alignedSize;
-
- nline = (int16) PageGetMaxOffsetNumber(page);
- nused = 0;
- for (i=0; i<nline; i++) {
- lp = ((PageHeader)page)->pd_linp + i;
- if ((*lp).lp_flags & LP_USED)
- nused++;
- }
-
- if (nused == 0) {
- for (i=0; i<nline; i++) {
- lp = ((PageHeader)page)->pd_linp + i;
- if ((*lp).lp_len > 0) /* unused, but allocated */
- (*lp).lp_len = 0; /* indicate unused & deallocated */
+ int i;
+ struct itemIdSortData *itemidbase,
+ *itemidptr;
+ ItemId lp;
+ int nline,
+ nused;
+ Offset upper;
+ Size alignedSize;
+
+ nline = (int16) PageGetMaxOffsetNumber(page);
+ nused = 0;
+ for (i = 0; i < nline; i++)
+ {
+ lp = ((PageHeader) page)->pd_linp + i;
+ if ((*lp).lp_flags & LP_USED)
+ nused++;
}
-
- ((PageHeader)page)->pd_upper = ((PageHeader)page)->pd_special;
- } else { /* nused != 0 */
- itemidbase = (struct itemIdSortData *)
- palloc(sizeof(struct itemIdSortData) * nused);
- memset((char *) itemidbase, 0, sizeof(struct itemIdSortData) * nused);
- itemidptr = itemidbase;
- for (i=0; i<nline; i++) {
- lp = ((PageHeader)page)->pd_linp + i;
- if ((*lp).lp_flags & LP_USED) {
- itemidptr->offsetindex = i;
- itemidptr->itemiddata = *lp;
- itemidptr++;
- } else {
- if ((*lp).lp_len > 0) /* unused, but allocated */
- (*lp).lp_len = 0; /* indicate unused & deallocated */
- }
+
+ if (nused == 0)
+ {
+ for (i = 0; i < nline; i++)
+ {
+ lp = ((PageHeader) page)->pd_linp + i;
+ if ((*lp).lp_len > 0) /* unused, but allocated */
+ (*lp).lp_len = 0; /* indicate unused & deallocated */
+ }
+
+ ((PageHeader) page)->pd_upper = ((PageHeader) page)->pd_special;
}
-
- /* sort itemIdSortData array...*/
- pg_qsort((char *) itemidbase, nused, sizeof(struct itemIdSortData),
- itemidcompare);
-
- /* compactify page */
- ((PageHeader)page)->pd_upper = ((PageHeader)page)->pd_special;
-
- for (i=0, itemidptr = itemidbase; i<nused; i++, itemidptr++) {
- lp = ((PageHeader)page)->pd_linp + itemidptr->offsetindex;
- alignedSize = DOUBLEALIGN((*lp).lp_len);
- upper = ((PageHeader)page)->pd_upper - alignedSize;
- memmove((char *) page + upper,
- (char *)page + (*lp).lp_off,
- (*lp).lp_len);
- (*lp).lp_off = upper;
- ((PageHeader)page)->pd_upper = upper;
+ else
+ { /* nused != 0 */
+ itemidbase = (struct itemIdSortData *)
+ palloc(sizeof(struct itemIdSortData) * nused);
+ memset((char *) itemidbase, 0, sizeof(struct itemIdSortData) * nused);
+ itemidptr = itemidbase;
+ for (i = 0; i < nline; i++)
+ {
+ lp = ((PageHeader) page)->pd_linp + i;
+ if ((*lp).lp_flags & LP_USED)
+ {
+ itemidptr->offsetindex = i;
+ itemidptr->itemiddata = *lp;
+ itemidptr++;
+ }
+ else
+ {
+ if ((*lp).lp_len > 0) /* unused, but allocated */
+ (*lp).lp_len = 0; /* indicate unused & deallocated */
+ }
+ }
+
+ /* sort itemIdSortData array... */
+ pg_qsort((char *) itemidbase, nused, sizeof(struct itemIdSortData),
+ itemidcompare);
+
+ /* compactify page */
+ ((PageHeader) page)->pd_upper = ((PageHeader) page)->pd_special;
+
+ for (i = 0, itemidptr = itemidbase; i < nused; i++, itemidptr++)
+ {
+ lp = ((PageHeader) page)->pd_linp + itemidptr->offsetindex;
+ alignedSize = DOUBLEALIGN((*lp).lp_len);
+ upper = ((PageHeader) page)->pd_upper - alignedSize;
+ memmove((char *) page + upper,
+ (char *) page + (*lp).lp_off,
+ (*lp).lp_len);
+ (*lp).lp_off = upper;
+ ((PageHeader) page)->pd_upper = upper;
+ }
+
+ pfree(itemidbase);
}
-
- pfree(itemidbase);
- }
}
/*
* PageGetFreeSpace --
- * Returns the size of the free (allocatable) space on a page.
+ * Returns the size of the free (allocatable) space on a page.
*/
Size
PageGetFreeSpace(Page page)
{
- Size space;
-
-
- space = ((PageHeader)page)->pd_upper - ((PageHeader)page)->pd_lower;
-
- if (space < sizeof (ItemIdData)) {
- return (0);
- }
- space -= sizeof (ItemIdData); /* XXX not always true */
-
- return (space);
+ Size space;
+
+
+ space = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
+
+ if (space < sizeof(ItemIdData))
+ {
+ return (0);
+ }
+ space -= sizeof(ItemIdData);/* XXX not always true */
+
+ return (space);
}
/*
* PageManagerModeSet --
*
- * Sets mode to either: ShufflePageManagerMode (the default) or
- * OverwritePageManagerMode. For use by access methods code
- * for determining semantics of PageAddItem when the offsetNumber
- * argument is passed in.
+ * Sets mode to either: ShufflePageManagerMode (the default) or
+ * OverwritePageManagerMode. For use by access methods code
+ * for determining semantics of PageAddItem when the offsetNumber
+ * argument is passed in.
*/
void
PageManagerModeSet(PageManagerMode mode)
{
- if (mode == ShufflePageManagerMode)
- PageManagerShuffle = true;
- else if (mode == OverwritePageManagerMode)
- PageManagerShuffle = false;
+ if (mode == ShufflePageManagerMode)
+ PageManagerShuffle = true;
+ else if (mode == OverwritePageManagerMode)
+ PageManagerShuffle = false;
}
/*
@@ -368,65 +395,64 @@ PageManagerModeSet(PageManagerMode mode)
* PageIndexTupleDelete
*----------------------------------------------------------------
*
- * This routine does the work of removing a tuple from an index page.
+ * This routine does the work of removing a tuple from an index page.
*/
void
PageIndexTupleDelete(Page page, OffsetNumber offnum)
{
- PageHeader phdr;
- char *addr;
- ItemId tup;
- Size size;
- char *locn;
- int nbytes;
- int offidx;
-
- phdr = (PageHeader) page;
-
- /* change offset number to offset index */
- offidx = offnum - 1;
-
- tup = PageGetItemId(page, offnum);
- size = ItemIdGetLength(tup);
- size = DOUBLEALIGN(size);
-
- /* location of deleted tuple data */
- locn = (char *) (page + ItemIdGetOffset(tup));
-
- /*
- * First, we want to get rid of the pd_linp entry for the index
- * tuple. We copy all subsequent linp's back one slot in the
- * array.
- */
-
- nbytes = phdr->pd_lower -
- ((char *)&phdr->pd_linp[offidx + 1] - (char *) phdr);
- memmove((char *) &(phdr->pd_linp[offidx]),
- (char *) &(phdr->pd_linp[offidx + 1]),
- nbytes);
-
- /*
- * Now move everything between the old upper bound (beginning of tuple
- * space) and the beginning of the deleted tuple forward, so that
- * space in the middle of the page is left free. If we've just deleted
- * the tuple at the beginning of tuple space, then there's no need
- * to do the copy (and bcopy on some architectures SEGV's if asked
- * to move zero bytes).
- */
-
- /* beginning of tuple space */
- addr = (char *) (page + phdr->pd_upper);
-
- if (locn != addr)
- memmove(addr + size, addr, (int) (locn - addr));
-
- /* adjust free space boundary pointers */
- phdr->pd_upper += size;
- phdr->pd_lower -= sizeof (ItemIdData);
-
- /* finally, we need to adjust the linp entries that remain */
- if (!PageIsEmpty(page))
- PageIndexTupleDeleteAdjustLinePointers(phdr, locn, size);
+ PageHeader phdr;
+ char *addr;
+ ItemId tup;
+ Size size;
+ char *locn;
+ int nbytes;
+ int offidx;
+
+ phdr = (PageHeader) page;
+
+ /* change offset number to offset index */
+ offidx = offnum - 1;
+
+ tup = PageGetItemId(page, offnum);
+ size = ItemIdGetLength(tup);
+ size = DOUBLEALIGN(size);
+
+ /* location of deleted tuple data */
+ locn = (char *) (page + ItemIdGetOffset(tup));
+
+ /*
+ * First, we want to get rid of the pd_linp entry for the index tuple.
+ * We copy all subsequent linp's back one slot in the array.
+ */
+
+ nbytes = phdr->pd_lower -
+ ((char *) &phdr->pd_linp[offidx + 1] - (char *) phdr);
+ memmove((char *) &(phdr->pd_linp[offidx]),
+ (char *) &(phdr->pd_linp[offidx + 1]),
+ nbytes);
+
+ /*
+ * Now move everything between the old upper bound (beginning of tuple
+ * space) and the beginning of the deleted tuple forward, so that
+ * space in the middle of the page is left free. If we've just
+ * deleted the tuple at the beginning of tuple space, then there's no
+ * need to do the copy (and bcopy on some architectures SEGV's if
+ * asked to move zero bytes).
+ */
+
+ /* beginning of tuple space */
+ addr = (char *) (page + phdr->pd_upper);
+
+ if (locn != addr)
+ memmove(addr + size, addr, (int) (locn - addr));
+
+ /* adjust free space boundary pointers */
+ phdr->pd_upper += size;
+ phdr->pd_lower -= sizeof(ItemIdData);
+
+ /* finally, we need to adjust the linp entries that remain */
+ if (!PageIsEmpty(page))
+ PageIndexTupleDeleteAdjustLinePointers(phdr, locn, size);
}
/*
@@ -434,33 +460,35 @@ PageIndexTupleDelete(Page page, OffsetNumber offnum)
* PageIndexTupleDeleteAdjustLinePointers
*----------------------------------------------------------------
*
- * Once the line pointers and tuple data have been shifted around
- * on the page, we need to go down the line pointer vector and
- * adjust pointers to reflect new locations. Anything that used
- * to be before the deleted tuple's data was moved forward by the
- * size of the deleted tuple.
+ * Once the line pointers and tuple data have been shifted around
+ * on the page, we need to go down the line pointer vector and
+ * adjust pointers to reflect new locations. Anything that used
+ * to be before the deleted tuple's data was moved forward by the
+ * size of the deleted tuple.
*
- * This routine does the work of adjusting the line pointers.
- * Location is where the tuple data used to lie; size is how
- * much space it occupied. We assume that size has been aligned
- * as required by the time we get here.
+ * This routine does the work of adjusting the line pointers.
+ * Location is where the tuple data used to lie; size is how
+ * much space it occupied. We assume that size has been aligned
+ * as required by the time we get here.
*
- * This routine should never be called on an empty page.
+ * This routine should never be called on an empty page.
*/
static void
PageIndexTupleDeleteAdjustLinePointers(PageHeader phdr,
- char *location,
- Size size)
+ char *location,
+ Size size)
{
- int i;
- unsigned offset;
-
- /* location is an index into the page... */
- offset = (unsigned)(location - (char *)phdr);
-
- for (i = PageGetMaxOffsetNumber((Page) phdr) - 1; i >= 0; i--) {
- if (phdr->pd_linp[i].lp_off <= offset) {
- phdr->pd_linp[i].lp_off += size;
+ int i;
+ unsigned offset;
+
+ /* location is an index into the page... */
+ offset = (unsigned) (location - (char *) phdr);
+
+ for (i = PageGetMaxOffsetNumber((Page) phdr) - 1; i >= 0; i--)
+ {
+ if (phdr->pd_linp[i].lp_off <= offset)
+ {
+ phdr->pd_linp[i].lp_off += size;
+ }
}
- }
}
diff --git a/src/backend/storage/page/itemptr.c b/src/backend/storage/page/itemptr.c
index 608fbf03379..25daebab23c 100644
--- a/src/backend/storage/page/itemptr.c
+++ b/src/backend/storage/page/itemptr.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* itemptr.c--
- * POSTGRES disk item pointer code.
+ * POSTGRES disk item pointer code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/page/itemptr.c,v 1.2 1996/11/03 05:07:46 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/page/itemptr.c,v 1.3 1997/09/07 04:49:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,21 +20,20 @@
/*
* ItemPointerEquals --
- * Returns true if both item pointers point to the same item,
- * otherwise returns false.
+ * Returns true if both item pointers point to the same item,
+ * otherwise returns false.
*
* Note:
- * Assumes that the disk item pointers are not NULL.
+ * Assumes that the disk item pointers are not NULL.
*/
bool
ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
{
- if (ItemPointerGetBlockNumber(pointer1) ==
- ItemPointerGetBlockNumber(pointer2) &&
- ItemPointerGetOffsetNumber(pointer1) ==
- ItemPointerGetOffsetNumber(pointer2))
- return(true);
- else
- return(false);
+ if (ItemPointerGetBlockNumber(pointer1) ==
+ ItemPointerGetBlockNumber(pointer2) &&
+ ItemPointerGetOffsetNumber(pointer1) ==
+ ItemPointerGetOffsetNumber(pointer2))
+ return (true);
+ else
+ return (false);
}
-
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index 2688ad3aed1..7a2903fff5c 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -1,28 +1,28 @@
/*-------------------------------------------------------------------------
*
* md.c--
- * This code manages relations that reside on magnetic disk.
+ * This code manages relations that reside on magnetic disk.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.18 1997/08/18 20:53:14 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.19 1997/09/07 04:49:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <unistd.h>
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
-#include <fcntl.h> /* for open() flags */
+#include <fcntl.h> /* for open() flags */
#include <sys/file.h>
#include "postgres.h"
-#include "miscadmin.h" /* for DataDir */
+#include "miscadmin.h" /* for DataDir */
#include "storage/block.h"
#include "storage/fd.h"
-#include "storage/smgr.h" /* where the declarations go */
+#include "storage/smgr.h" /* where the declarations go */
#include "storage/fd.h"
#include "utils/mcxt.h"
#include "utils/rel.h"
@@ -32,764 +32,802 @@
#undef DIAGNOSTIC
/*
- * The magnetic disk storage manager keeps track of open file descriptors
- * in its own descriptor pool. This happens for two reasons. First, at
- * transaction boundaries, we walk the list of descriptors and flush
- * anything that we've dirtied in the current transaction. Second, we
- * have to support relations of > 4GBytes. In order to do this, we break
- * relations up into chunks of < 2GBytes and store one chunk in each of
- * several files that represent the relation.
+ * The magnetic disk storage manager keeps track of open file descriptors
+ * in its own descriptor pool. This happens for two reasons. First, at
+ * transaction boundaries, we walk the list of descriptors and flush
+ * anything that we've dirtied in the current transaction. Second, we
+ * have to support relations of > 4GBytes. In order to do this, we break
+ * relations up into chunks of < 2GBytes and store one chunk in each of
+ * several files that represent the relation.
*/
-typedef struct _MdfdVec {
- int mdfd_vfd; /* fd number in vfd pool */
- uint16 mdfd_flags; /* clean, dirty, free */
- int mdfd_lstbcnt; /* most recent block count */
- int mdfd_nextFree; /* next free vector */
- struct _MdfdVec *mdfd_chain; /* for large relations */
-} MdfdVec;
+typedef struct _MdfdVec
+{
+ int mdfd_vfd; /* fd number in vfd pool */
+ uint16 mdfd_flags; /* clean, dirty, free */
+ int mdfd_lstbcnt; /* most recent block count */
+ int mdfd_nextFree; /* next free vector */
+ struct _MdfdVec *mdfd_chain;/* for large relations */
+} MdfdVec;
-static int Nfds = 100;
-static MdfdVec *Md_fdvec = (MdfdVec *) NULL;
-static int Md_Free = -1;
-static int CurFd = 0;
-static MemoryContext MdCxt;
+static int Nfds = 100;
+static MdfdVec *Md_fdvec = (MdfdVec *) NULL;
+static int Md_Free = -1;
+static int CurFd = 0;
+static MemoryContext MdCxt;
-#define MDFD_DIRTY (uint16) 0x01
-#define MDFD_FREE (uint16) 0x02
+#define MDFD_DIRTY (uint16) 0x01
+#define MDFD_FREE (uint16) 0x02
-#define RELSEG_SIZE 262144 /* (2 ** 31) / 8192 -- 2GB file */
+#define RELSEG_SIZE 262144 /* (2 ** 31) / 8192 -- 2GB file */
/* routines declared here */
-static MdfdVec *_mdfd_openseg(Relation reln, int segno, int oflags);
-static MdfdVec *_mdfd_getseg(Relation reln, int blkno, int oflag);
-static int _fdvec_alloc (void);
-static void _fdvec_free (int);
+static MdfdVec *_mdfd_openseg(Relation reln, int segno, int oflags);
+static MdfdVec *_mdfd_getseg(Relation reln, int blkno, int oflag);
+static int _fdvec_alloc(void);
+static void _fdvec_free(int);
static BlockNumber _mdnblocks(File file, Size blcksz);
/*
- * mdinit() -- Initialize private state for magnetic disk storage manager.
+ * mdinit() -- Initialize private state for magnetic disk storage manager.
*
- * We keep a private table of all file descriptors. Whenever we do
- * a write to one, we mark it dirty in our table. Whenever we force
- * changes to disk, we mark the file descriptor clean. At transaction
- * commit, we force changes to disk for all dirty file descriptors.
- * This routine allocates and initializes the table.
+ * We keep a private table of all file descriptors. Whenever we do
+ * a write to one, we mark it dirty in our table. Whenever we force
+ * changes to disk, we mark the file descriptor clean. At transaction
+ * commit, we force changes to disk for all dirty file descriptors.
+ * This routine allocates and initializes the table.
*
- * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
+ * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
*/
int
mdinit()
{
- MemoryContext oldcxt;
- int i;
+ MemoryContext oldcxt;
+ int i;
- MdCxt = (MemoryContext) CreateGlobalMemory("MdSmgr");
- if (MdCxt == (MemoryContext) NULL)
- return (SM_FAIL);
+ MdCxt = (MemoryContext) CreateGlobalMemory("MdSmgr");
+ if (MdCxt == (MemoryContext) NULL)
+ return (SM_FAIL);
- oldcxt = MemoryContextSwitchTo(MdCxt);
- Md_fdvec = (MdfdVec *) palloc(Nfds * sizeof(MdfdVec));
- MemoryContextSwitchTo(oldcxt);
+ oldcxt = MemoryContextSwitchTo(MdCxt);
+ Md_fdvec = (MdfdVec *) palloc(Nfds * sizeof(MdfdVec));
+ MemoryContextSwitchTo(oldcxt);
- if (Md_fdvec == (MdfdVec *) NULL)
- return (SM_FAIL);
+ if (Md_fdvec == (MdfdVec *) NULL)
+ return (SM_FAIL);
- memset(Md_fdvec, 0, Nfds * sizeof(MdfdVec));
+ memset(Md_fdvec, 0, Nfds * sizeof(MdfdVec));
- /* Set free list */
- for (i = 0; i < Nfds; i++ )
- {
- Md_fdvec[i].mdfd_nextFree = i + 1;
- Md_fdvec[i].mdfd_flags = MDFD_FREE;
- }
- Md_Free = 0;
- Md_fdvec[Nfds - 1].mdfd_nextFree = -1;
+ /* Set free list */
+ for (i = 0; i < Nfds; i++)
+ {
+ Md_fdvec[i].mdfd_nextFree = i + 1;
+ Md_fdvec[i].mdfd_flags = MDFD_FREE;
+ }
+ Md_Free = 0;
+ Md_fdvec[Nfds - 1].mdfd_nextFree = -1;
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
int
mdcreate(Relation reln)
{
- int fd, vfd;
- char *path;
-
- path = relpath(&(reln->rd_rel->relname.data[0]));
- fd = FileNameOpenFile(path, O_RDWR|O_CREAT|O_EXCL, 0600);
-
- /*
- * If the file already exists and is empty, we pretend that the
- * create succeeded. During bootstrap processing, we skip that check,
- * because pg_time, pg_variable, and pg_log get created before their
- * .bki file entries are processed.
- *
- * As the result of this pretence it was possible to have in
- * pg_class > 1 records with the same relname. Actually, it
- * should be fixed in upper levels, too, but... - vadim 05/06/97
- */
-
- if (fd < 0)
- {
- if ( !IsBootstrapProcessingMode() )
- return (-1);
- fd = FileNameOpenFile(path, O_RDWR, 0600); /* Bootstrap */
- if ( fd < 0 )
- return (-1);
- }
-
- vfd = _fdvec_alloc ();
- if ( vfd < 0 )
- return (-1);
-
- Md_fdvec[vfd].mdfd_vfd = fd;
- Md_fdvec[vfd].mdfd_flags = (uint16) 0;
- Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL;
- Md_fdvec[vfd].mdfd_lstbcnt = 0;
-
- return (vfd);
+ int fd,
+ vfd;
+ char *path;
+
+ path = relpath(&(reln->rd_rel->relname.data[0]));
+ fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL, 0600);
+
+ /*
+ * If the file already exists and is empty, we pretend that the create
+ * succeeded. During bootstrap processing, we skip that check,
+ * because pg_time, pg_variable, and pg_log get created before their
+ * .bki file entries are processed.
+ *
+ * As the result of this pretence it was possible to have in pg_class > 1
+ * records with the same relname. Actually, it should be fixed in
+ * upper levels, too, but... - vadim 05/06/97
+ */
+
+ if (fd < 0)
+ {
+ if (!IsBootstrapProcessingMode())
+ return (-1);
+ fd = FileNameOpenFile(path, O_RDWR, 0600); /* Bootstrap */
+ if (fd < 0)
+ return (-1);
+ }
+
+ vfd = _fdvec_alloc();
+ if (vfd < 0)
+ return (-1);
+
+ Md_fdvec[vfd].mdfd_vfd = fd;
+ Md_fdvec[vfd].mdfd_flags = (uint16) 0;
+ Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL;
+ Md_fdvec[vfd].mdfd_lstbcnt = 0;
+
+ return (vfd);
}
/*
- * mdunlink() -- Unlink a relation.
+ * mdunlink() -- Unlink a relation.
*/
int
mdunlink(Relation reln)
{
- int fd;
- int i;
- MdfdVec *v, *ov;
- MemoryContext oldcxt;
- char fname[NAMEDATALEN];
- char tname[NAMEDATALEN+10]; /* leave room for overflow suffixes*/
-
- /* On Windows NT you can't unlink a file if it is open so we have
- ** to do this.
- */
+ int fd;
+ int i;
+ MdfdVec *v,
+ *ov;
+ MemoryContext oldcxt;
+ char fname[NAMEDATALEN];
+ char tname[NAMEDATALEN + 10]; /* leave room for overflow
+ * suffixes */
+
+ /*
+ * On Windows NT you can't unlink a file if it is open so we have * to
+ * do this.
+ */
+
+ strNcpy(fname, RelationGetRelationName(reln)->data, NAMEDATALEN - 1);
+
+ if (FileNameUnlink(fname) < 0)
+ return (SM_FAIL);
+
+ /* unlink all the overflow files for large relations */
+ for (i = 1;; i++)
+ {
+ sprintf(tname, "%s.%d", fname, i);
+ if (FileNameUnlink(tname) < 0)
+ break;
+ }
+
+ /* finally, clean out the mdfd vector */
+ fd = RelationGetFile(reln);
+ Md_fdvec[fd].mdfd_flags = (uint16) 0;
+
+ oldcxt = MemoryContextSwitchTo(MdCxt);
+ for (v = &Md_fdvec[fd]; v != (MdfdVec *) NULL;)
+ {
+ FileUnlink(v->mdfd_vfd);
+ ov = v;
+ v = v->mdfd_chain;
+ if (ov != &Md_fdvec[fd])
+ pfree(ov);
+ }
+ Md_fdvec[fd].mdfd_chain = (MdfdVec *) NULL;
+ MemoryContextSwitchTo(oldcxt);
- strNcpy(fname, RelationGetRelationName(reln)->data, NAMEDATALEN-1);
-
- if (FileNameUnlink(fname) < 0)
- return (SM_FAIL);
-
- /* unlink all the overflow files for large relations */
- for (i = 1; ; i++) {
- sprintf(tname, "%s.%d", fname, i);
- if (FileNameUnlink(tname) < 0)
- break;
- }
-
- /* finally, clean out the mdfd vector */
- fd = RelationGetFile(reln);
- Md_fdvec[fd].mdfd_flags = (uint16) 0;
-
- oldcxt = MemoryContextSwitchTo(MdCxt);
- for (v = &Md_fdvec[fd]; v != (MdfdVec *) NULL; )
- {
- FileUnlink(v->mdfd_vfd);
- ov = v;
- v = v->mdfd_chain;
- if (ov != &Md_fdvec[fd])
- pfree(ov);
- }
- Md_fdvec[fd].mdfd_chain = (MdfdVec *) NULL;
- MemoryContextSwitchTo(oldcxt);
-
- _fdvec_free (fd);
-
- return (SM_SUCCESS);
+ _fdvec_free(fd);
+
+ return (SM_SUCCESS);
}
/*
- * mdextend() -- Add a block to the specified relation.
+ * mdextend() -- Add a block to the specified relation.
*
- * This routine returns SM_FAIL or SM_SUCCESS, with errno set as
- * appropriate.
+ * This routine returns SM_FAIL or SM_SUCCESS, with errno set as
+ * appropriate.
*/
int
mdextend(Relation reln, char *buffer)
{
- long pos;
- int nblocks;
- MdfdVec *v;
+ long pos;
+ int nblocks;
+ MdfdVec *v;
- nblocks = mdnblocks(reln);
- v = _mdfd_getseg(reln, nblocks, O_CREAT);
+ nblocks = mdnblocks(reln);
+ v = _mdfd_getseg(reln, nblocks, O_CREAT);
- if ((pos = FileSeek(v->mdfd_vfd, 0L, SEEK_END)) < 0)
- return (SM_FAIL);
+ if ((pos = FileSeek(v->mdfd_vfd, 0L, SEEK_END)) < 0)
+ return (SM_FAIL);
- if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ)
- return (SM_FAIL);
+ if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ)
+ return (SM_FAIL);
- /* remember that we did a write, so we can sync at xact commit */
- v->mdfd_flags |= MDFD_DIRTY;
+ /* remember that we did a write, so we can sync at xact commit */
+ v->mdfd_flags |= MDFD_DIRTY;
- /* try to keep the last block count current, though it's just a hint */
- if ((v->mdfd_lstbcnt = (++nblocks % RELSEG_SIZE)) == 0)
- v->mdfd_lstbcnt = RELSEG_SIZE;
+ /* try to keep the last block count current, though it's just a hint */
+ if ((v->mdfd_lstbcnt = (++nblocks % RELSEG_SIZE)) == 0)
+ v->mdfd_lstbcnt = RELSEG_SIZE;
#ifdef DIAGNOSTIC
- if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > RELSEG_SIZE
- || v->mdfd_lstbcnt > RELSEG_SIZE)
- elog(FATAL, "segment too big!");
+ if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > RELSEG_SIZE
+ || v->mdfd_lstbcnt > RELSEG_SIZE)
+ elog(FATAL, "segment too big!");
#endif
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
/*
- * mdopen() -- Open the specified relation.
+ * mdopen() -- Open the specified relation.
*/
int
mdopen(Relation reln)
{
- char *path;
- int fd;
- int vfd;
+ char *path;
+ int fd;
+ int vfd;
- path = relpath(&(reln->rd_rel->relname.data[0]));
+ path = relpath(&(reln->rd_rel->relname.data[0]));
- fd = FileNameOpenFile(path, O_RDWR, 0600);
+ fd = FileNameOpenFile(path, O_RDWR, 0600);
- /* this should only happen during bootstrap processing */
- if (fd < 0)
- fd = FileNameOpenFile(path, O_RDWR|O_CREAT|O_EXCL, 0600);
+ /* this should only happen during bootstrap processing */
+ if (fd < 0)
+ fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL, 0600);
- vfd = _fdvec_alloc ();
- if ( vfd < 0 )
- return (-1);
+ vfd = _fdvec_alloc();
+ if (vfd < 0)
+ return (-1);
- Md_fdvec[vfd].mdfd_vfd = fd;
- Md_fdvec[vfd].mdfd_flags = (uint16) 0;
- Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL;
- Md_fdvec[vfd].mdfd_lstbcnt = _mdnblocks(fd, BLCKSZ);
+ Md_fdvec[vfd].mdfd_vfd = fd;
+ Md_fdvec[vfd].mdfd_flags = (uint16) 0;
+ Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL;
+ Md_fdvec[vfd].mdfd_lstbcnt = _mdnblocks(fd, BLCKSZ);
#ifdef DIAGNOSTIC
- if (Md_fdvec[vfd].mdfd_lstbcnt > RELSEG_SIZE)
- elog(FATAL, "segment too big on relopen!");
+ if (Md_fdvec[vfd].mdfd_lstbcnt > RELSEG_SIZE)
+ elog(FATAL, "segment too big on relopen!");
#endif
- return (vfd);
+ return (vfd);
}
/*
- * mdclose() -- Close the specified relation
+ * mdclose() -- Close the specified relation
*
- * AND FREE fd vector! It may be re-used for other relation!
- * reln should be flushed from cache after closing !..
+ * AND FREE fd vector! It may be re-used for other relation!
+ * reln should be flushed from cache after closing !..
*
- * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
+ * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
*/
int
mdclose(Relation reln)
{
- int fd;
- MdfdVec *v, *ov;
- MemoryContext oldcxt;
+ int fd;
+ MdfdVec *v,
+ *ov;
+ MemoryContext oldcxt;
- fd = RelationGetFile(reln);
+ fd = RelationGetFile(reln);
- oldcxt = MemoryContextSwitchTo(MdCxt);
- for (v = &Md_fdvec[fd]; v != (MdfdVec *) NULL; )
- {
- /* if not closed already */
- if ( v->mdfd_vfd >= 0 )
+ oldcxt = MemoryContextSwitchTo(MdCxt);
+ for (v = &Md_fdvec[fd]; v != (MdfdVec *) NULL;)
{
- /*
- * We sync the file descriptor so that we don't need to reopen it at
- * transaction commit to force changes to disk.
- */
+ /* if not closed already */
+ if (v->mdfd_vfd >= 0)
+ {
+
+ /*
+ * We sync the file descriptor so that we don't need to reopen
+ * it at transaction commit to force changes to disk.
+ */
+
+ FileSync(v->mdfd_vfd);
+ FileClose(v->mdfd_vfd);
+
+ /* mark this file descriptor as clean in our private table */
+ v->mdfd_flags &= ~MDFD_DIRTY;
+ }
+ /* Now free vector */
+ ov = v;
+ v = v->mdfd_chain;
+ if (ov != &Md_fdvec[fd])
+ pfree(ov);
+ }
- FileSync(v->mdfd_vfd);
- FileClose(v->mdfd_vfd);
+ MemoryContextSwitchTo(oldcxt);
+ Md_fdvec[fd].mdfd_chain = (MdfdVec *) NULL;
- /* mark this file descriptor as clean in our private table */
- v->mdfd_flags &= ~MDFD_DIRTY;
- }
- /* Now free vector */
- ov = v;
- v = v->mdfd_chain;
- if (ov != &Md_fdvec[fd])
- pfree(ov);
- }
-
- MemoryContextSwitchTo(oldcxt);
- Md_fdvec[fd].mdfd_chain = (MdfdVec *) NULL;
-
- _fdvec_free (fd);
-
- return (SM_SUCCESS);
+ _fdvec_free(fd);
+
+ return (SM_SUCCESS);
}
/*
- * mdread() -- Read the specified block from a relation.
+ * mdread() -- Read the specified block from a relation.
*
- * Returns SM_SUCCESS or SM_FAIL.
+ * Returns SM_SUCCESS or SM_FAIL.
*/
int
mdread(Relation reln, BlockNumber blocknum, char *buffer)
{
- int status;
- long seekpos;
- int nbytes;
- MdfdVec *v;
+ int status;
+ long seekpos;
+ int nbytes;
+ MdfdVec *v;
- v = _mdfd_getseg(reln, blocknum, 0);
+ v = _mdfd_getseg(reln, blocknum, 0);
- seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
+ seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
#ifdef DIAGNOSTIC
- if (seekpos >= BLCKSZ * RELSEG_SIZE)
- elog(FATAL, "seekpos too big!");
+ if (seekpos >= BLCKSZ * RELSEG_SIZE)
+ elog(FATAL, "seekpos too big!");
#endif
- if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) {
- return (SM_FAIL);
- }
+ if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos)
+ {
+ return (SM_FAIL);
+ }
- status = SM_SUCCESS;
- if ((nbytes = FileRead(v->mdfd_vfd, buffer, BLCKSZ)) != BLCKSZ) {
- if (nbytes == 0) {
- memset(buffer, 0, BLCKSZ);
- } else {
- status = SM_FAIL;
+ status = SM_SUCCESS;
+ if ((nbytes = FileRead(v->mdfd_vfd, buffer, BLCKSZ)) != BLCKSZ)
+ {
+ if (nbytes == 0)
+ {
+ memset(buffer, 0, BLCKSZ);
+ }
+ else
+ {
+ status = SM_FAIL;
+ }
}
- }
- return (status);
+ return (status);
}
/*
- * mdwrite() -- Write the supplied block at the appropriate location.
+ * mdwrite() -- Write the supplied block at the appropriate location.
*
- * Returns SM_SUCCESS or SM_FAIL.
+ * Returns SM_SUCCESS or SM_FAIL.
*/
int
mdwrite(Relation reln, BlockNumber blocknum, char *buffer)
{
- int status;
- long seekpos;
- MdfdVec *v;
+ int status;
+ long seekpos;
+ MdfdVec *v;
- v = _mdfd_getseg(reln, blocknum, 0);
+ v = _mdfd_getseg(reln, blocknum, 0);
- seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
+ seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
#ifdef DIAGNOSTIC
- if (seekpos >= BLCKSZ * RELSEG_SIZE)
- elog(FATAL, "seekpos too big!");
+ if (seekpos >= BLCKSZ * RELSEG_SIZE)
+ elog(FATAL, "seekpos too big!");
#endif
- if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) {
- return (SM_FAIL);
- }
+ if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos)
+ {
+ return (SM_FAIL);
+ }
- status = SM_SUCCESS;
- if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ)
- status = SM_FAIL;
+ status = SM_SUCCESS;
+ if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ)
+ status = SM_FAIL;
- v->mdfd_flags |= MDFD_DIRTY;
+ v->mdfd_flags |= MDFD_DIRTY;
- return (status);
+ return (status);
}
/*
- * mdflush() -- Synchronously write a block to disk.
+ * mdflush() -- Synchronously write a block to disk.
*
- * This is exactly like mdwrite(), but doesn't return until the file
- * system buffer cache has been flushed.
+ * This is exactly like mdwrite(), but doesn't return until the file
+ * system buffer cache has been flushed.
*/
int
mdflush(Relation reln, BlockNumber blocknum, char *buffer)
{
- int status;
- long seekpos;
- MdfdVec *v;
+ int status;
+ long seekpos;
+ MdfdVec *v;
- v = _mdfd_getseg(reln, blocknum, 0);
+ v = _mdfd_getseg(reln, blocknum, 0);
- seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
+ seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE));
#ifdef DIAGNOSTIC
- if (seekpos >= BLCKSZ * RELSEG_SIZE)
- elog(FATAL, "seekpos too big!");
+ if (seekpos >= BLCKSZ * RELSEG_SIZE)
+ elog(FATAL, "seekpos too big!");
#endif
- if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) {
- return (SM_FAIL);
- }
+ if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos)
+ {
+ return (SM_FAIL);
+ }
- /* write and sync the block */
- status = SM_SUCCESS;
- if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ
- || FileSync(v->mdfd_vfd) < 0)
- status = SM_FAIL;
+ /* write and sync the block */
+ status = SM_SUCCESS;
+ if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ
+ || FileSync(v->mdfd_vfd) < 0)
+ status = SM_FAIL;
- /*
- * By here, the block is written and changes have been forced to stable
- * storage. Mark the descriptor as clean until the next write, so we
- * don't sync it again unnecessarily at transaction commit.
- */
+ /*
+ * By here, the block is written and changes have been forced to
+ * stable storage. Mark the descriptor as clean until the next write,
+ * so we don't sync it again unnecessarily at transaction commit.
+ */
- v->mdfd_flags &= ~MDFD_DIRTY;
+ v->mdfd_flags &= ~MDFD_DIRTY;
- return (status);
+ return (status);
}
/*
- * mdblindwrt() -- Write a block to disk blind.
+ * mdblindwrt() -- Write a block to disk blind.
*
- * We have to be able to do this using only the name and OID of
- * the database and relation in which the block belongs. This
- * is a synchronous write.
+ * We have to be able to do this using only the name and OID of
+ * the database and relation in which the block belongs. This
+ * is a synchronous write.
*/
int
mdblindwrt(char *dbstr,
- char *relstr,
- Oid dbid,
- Oid relid,
- BlockNumber blkno,
- char *buffer)
+ char *relstr,
+ Oid dbid,
+ Oid relid,
+ BlockNumber blkno,
+ char *buffer)
{
- int fd;
- int segno;
- long seekpos;
- int status;
- char *path;
- int nchars;
-
- /* be sure we have enough space for the '.segno', if any */
- segno = blkno / RELSEG_SIZE;
- if (segno > 0)
- nchars = 10;
- else
- nchars = 0;
-
- /* construct the path to the file and open it */
- if (dbid == (Oid) 0) {
- path = (char *) palloc(strlen(DataDir) + sizeof(NameData) + 2 + nchars);
- if (segno == 0)
- sprintf(path, "%s/%s", DataDir, relstr);
+ int fd;
+ int segno;
+ long seekpos;
+ int status;
+ char *path;
+ int nchars;
+
+ /* be sure we have enough space for the '.segno', if any */
+ segno = blkno / RELSEG_SIZE;
+ if (segno > 0)
+ nchars = 10;
else
- sprintf(path, "%s/%s.%d", DataDir, relstr, segno);
- } else {
- path = (char *) palloc(strlen(DataDir) + strlen("/base/") + 2 * sizeof(NameData) + 2 + nchars);
- if (segno == 0)
- sprintf(path, "%s/base/%s/%s", DataDir,
- dbstr, relstr);
+ nchars = 0;
+
+ /* construct the path to the file and open it */
+ if (dbid == (Oid) 0)
+ {
+ path = (char *) palloc(strlen(DataDir) + sizeof(NameData) + 2 + nchars);
+ if (segno == 0)
+ sprintf(path, "%s/%s", DataDir, relstr);
+ else
+ sprintf(path, "%s/%s.%d", DataDir, relstr, segno);
+ }
else
- sprintf(path, "%s/base/%s/%s.%d", DataDir, dbstr,
- relstr, segno);
- }
+ {
+ path = (char *) palloc(strlen(DataDir) + strlen("/base/") + 2 * sizeof(NameData) + 2 + nchars);
+ if (segno == 0)
+ sprintf(path, "%s/base/%s/%s", DataDir,
+ dbstr, relstr);
+ else
+ sprintf(path, "%s/base/%s/%s.%d", DataDir, dbstr,
+ relstr, segno);
+ }
- if ((fd = open(path, O_RDWR, 0600)) < 0)
- return (SM_FAIL);
+ if ((fd = open(path, O_RDWR, 0600)) < 0)
+ return (SM_FAIL);
- /* seek to the right spot */
- seekpos = (long) (BLCKSZ * (blkno % RELSEG_SIZE));
- if (lseek(fd, seekpos, SEEK_SET) != seekpos) {
- close(fd);
- return (SM_FAIL);
- }
+ /* seek to the right spot */
+ seekpos = (long) (BLCKSZ * (blkno % RELSEG_SIZE));
+ if (lseek(fd, seekpos, SEEK_SET) != seekpos)
+ {
+ close(fd);
+ return (SM_FAIL);
+ }
- status = SM_SUCCESS;
+ status = SM_SUCCESS;
- /* write and sync the block */
- if (write(fd, buffer, BLCKSZ) != BLCKSZ || (pg_fsync(fd) < 0))
- status = SM_FAIL;
+ /* write and sync the block */
+ if (write(fd, buffer, BLCKSZ) != BLCKSZ || (pg_fsync(fd) < 0))
+ status = SM_FAIL;
- if (close(fd) < 0)
- status = SM_FAIL;
+ if (close(fd) < 0)
+ status = SM_FAIL;
- pfree(path);
+ pfree(path);
- return (status);
+ return (status);
}
/*
- * mdnblocks() -- Get the number of blocks stored in a relation.
+ * mdnblocks() -- Get the number of blocks stored in a relation.
*
- * Returns # of blocks or -1 on error.
+ * Returns # of blocks or -1 on error.
*/
int
mdnblocks(Relation reln)
{
- int fd;
- MdfdVec *v;
- int nblocks;
- int segno;
+ int fd;
+ MdfdVec *v;
+ int nblocks;
+ int segno;
- fd = RelationGetFile(reln);
- v = &Md_fdvec[fd];
+ fd = RelationGetFile(reln);
+ v = &Md_fdvec[fd];
#ifdef DIAGNOSTIC
- if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > RELSEG_SIZE)
- elog(FATAL, "segment too big in getseg!");
+ if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > RELSEG_SIZE)
+ elog(FATAL, "segment too big in getseg!");
#endif
- segno = 0;
- for (;;) {
- if (v->mdfd_lstbcnt == RELSEG_SIZE
- || (nblocks = _mdnblocks(v->mdfd_vfd, BLCKSZ)) == RELSEG_SIZE) {
-
- v->mdfd_lstbcnt = RELSEG_SIZE;
- segno++;
-
- if (v->mdfd_chain == (MdfdVec *) NULL) {
- v->mdfd_chain = _mdfd_openseg(reln, segno, O_CREAT);
- if (v->mdfd_chain == (MdfdVec *) NULL)
- elog(WARN, "cannot count blocks for %.16s -- open failed",
- RelationGetRelationName(reln));
- }
-
- v = v->mdfd_chain;
- } else {
- return ((segno * RELSEG_SIZE) + nblocks);
+ segno = 0;
+ for (;;)
+ {
+ if (v->mdfd_lstbcnt == RELSEG_SIZE
+ || (nblocks = _mdnblocks(v->mdfd_vfd, BLCKSZ)) == RELSEG_SIZE)
+ {
+
+ v->mdfd_lstbcnt = RELSEG_SIZE;
+ segno++;
+
+ if (v->mdfd_chain == (MdfdVec *) NULL)
+ {
+ v->mdfd_chain = _mdfd_openseg(reln, segno, O_CREAT);
+ if (v->mdfd_chain == (MdfdVec *) NULL)
+ elog(WARN, "cannot count blocks for %.16s -- open failed",
+ RelationGetRelationName(reln));
+ }
+
+ v = v->mdfd_chain;
+ }
+ else
+ {
+ return ((segno * RELSEG_SIZE) + nblocks);
+ }
}
- }
}
/*
- * mdtruncate() -- Truncate relation to specified number of blocks.
+ * mdtruncate() -- Truncate relation to specified number of blocks.
*
- * Returns # of blocks or -1 on error.
+ * Returns # of blocks or -1 on error.
*/
int
-mdtruncate (Relation reln, int nblocks)
+mdtruncate(Relation reln, int nblocks)
{
- int fd;
- MdfdVec *v;
- int curnblk;
+ int fd;
+ MdfdVec *v;
+ int curnblk;
- curnblk = mdnblocks (reln);
- if ( curnblk / RELSEG_SIZE > 0 )
- {
- elog (NOTICE, "Can't truncate multi-segments relation %s",
- &(reln->rd_rel->relname.data[0]));
- return (curnblk);
- }
+ curnblk = mdnblocks(reln);
+ if (curnblk / RELSEG_SIZE > 0)
+ {
+ elog(NOTICE, "Can't truncate multi-segments relation %s",
+ &(reln->rd_rel->relname.data[0]));
+ return (curnblk);
+ }
+
+ fd = RelationGetFile(reln);
+ v = &Md_fdvec[fd];
- fd = RelationGetFile(reln);
- v = &Md_fdvec[fd];
+ if (FileTruncate(v->mdfd_vfd, nblocks * BLCKSZ) < 0)
+ return (-1);
- if ( FileTruncate (v->mdfd_vfd, nblocks * BLCKSZ) < 0 )
- return (-1);
-
- return (nblocks);
+ return (nblocks);
-} /* mdtruncate */
+} /* mdtruncate */
/*
- * mdcommit() -- Commit a transaction.
+ * mdcommit() -- Commit a transaction.
*
- * All changes to magnetic disk relations must be forced to stable
- * storage. This routine makes a pass over the private table of
- * file descriptors. Any descriptors to which we have done writes,
- * but not synced, are synced here.
+ * All changes to magnetic disk relations must be forced to stable
+ * storage. This routine makes a pass over the private table of
+ * file descriptors. Any descriptors to which we have done writes,
+ * but not synced, are synced here.
*
- * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
+ * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
*/
int
mdcommit()
{
- int i;
- MdfdVec *v;
+ int i;
+ MdfdVec *v;
- for (i = 0; i < CurFd; i++) {
- for (v = &Md_fdvec[i]; v != (MdfdVec *) NULL; v = v->mdfd_chain) {
- if (v->mdfd_flags & MDFD_DIRTY) {
- if (FileSync(v->mdfd_vfd) < 0)
- return (SM_FAIL);
-
- v->mdfd_flags &= ~MDFD_DIRTY;
- }
+ for (i = 0; i < CurFd; i++)
+ {
+ for (v = &Md_fdvec[i]; v != (MdfdVec *) NULL; v = v->mdfd_chain)
+ {
+ if (v->mdfd_flags & MDFD_DIRTY)
+ {
+ if (FileSync(v->mdfd_vfd) < 0)
+ return (SM_FAIL);
+
+ v->mdfd_flags &= ~MDFD_DIRTY;
+ }
+ }
}
- }
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
/*
- * mdabort() -- Abort a transaction.
+ * mdabort() -- Abort a transaction.
*
- * Changes need not be forced to disk at transaction abort. We mark
- * all file descriptors as clean here. Always returns SM_SUCCESS.
+ * Changes need not be forced to disk at transaction abort. We mark
+ * all file descriptors as clean here. Always returns SM_SUCCESS.
*/
int
mdabort()
{
- int i;
- MdfdVec *v;
+ int i;
+ MdfdVec *v;
- for (i = 0; i < CurFd; i++) {
- for (v = &Md_fdvec[i]; v != (MdfdVec *) NULL; v = v->mdfd_chain) {
- v->mdfd_flags &= ~MDFD_DIRTY;
+ for (i = 0; i < CurFd; i++)
+ {
+ for (v = &Md_fdvec[i]; v != (MdfdVec *) NULL; v = v->mdfd_chain)
+ {
+ v->mdfd_flags &= ~MDFD_DIRTY;
+ }
}
- }
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
/*
- * _fdvec_alloc () -- grab a free (or new) md file descriptor vector.
+ * _fdvec_alloc () -- grab a free (or new) md file descriptor vector.
*
*/
static
-int _fdvec_alloc ()
+int
+_fdvec_alloc()
{
- MdfdVec *nvec;
- int fdvec, i;
- MemoryContext oldcxt;
-
- if ( Md_Free >= 0 ) /* get from free list */
- {
- fdvec = Md_Free;
- Md_Free = Md_fdvec[fdvec].mdfd_nextFree;
- Assert ( Md_fdvec[fdvec].mdfd_flags == MDFD_FREE );
- Md_fdvec[fdvec].mdfd_flags = 0;
- if ( fdvec >= CurFd )
+ MdfdVec *nvec;
+ int fdvec,
+ i;
+ MemoryContext oldcxt;
+
+ if (Md_Free >= 0) /* get from free list */
{
- Assert ( fdvec == CurFd );
- CurFd++;
+ fdvec = Md_Free;
+ Md_Free = Md_fdvec[fdvec].mdfd_nextFree;
+ Assert(Md_fdvec[fdvec].mdfd_flags == MDFD_FREE);
+ Md_fdvec[fdvec].mdfd_flags = 0;
+ if (fdvec >= CurFd)
+ {
+ Assert(fdvec == CurFd);
+ CurFd++;
+ }
+ return (fdvec);
}
- return (fdvec);
- }
- /* Must allocate more room */
-
- if ( Nfds != CurFd )
- elog (FATAL, "_fdvec_alloc error");
-
- Nfds *= 2;
+ /* Must allocate more room */
+
+ if (Nfds != CurFd)
+ elog(FATAL, "_fdvec_alloc error");
- oldcxt = MemoryContextSwitchTo(MdCxt);
+ Nfds *= 2;
- nvec = (MdfdVec *) palloc(Nfds * sizeof(MdfdVec));
- memset(nvec, 0, Nfds * sizeof(MdfdVec));
- memmove(nvec, (char *) Md_fdvec, CurFd * sizeof(MdfdVec));
- pfree(Md_fdvec);
+ oldcxt = MemoryContextSwitchTo(MdCxt);
- MemoryContextSwitchTo(oldcxt);
+ nvec = (MdfdVec *) palloc(Nfds * sizeof(MdfdVec));
+ memset(nvec, 0, Nfds * sizeof(MdfdVec));
+ memmove(nvec, (char *) Md_fdvec, CurFd * sizeof(MdfdVec));
+ pfree(Md_fdvec);
- Md_fdvec = nvec;
+ MemoryContextSwitchTo(oldcxt);
- /* Set new free list */
- for (i = CurFd; i < Nfds; i++ )
- {
- Md_fdvec[i].mdfd_nextFree = i + 1;
- Md_fdvec[i].mdfd_flags = MDFD_FREE;
- }
- Md_fdvec[Nfds - 1].mdfd_nextFree = -1;
- Md_Free = CurFd + 1;
+ Md_fdvec = nvec;
- fdvec = CurFd;
- CurFd++;
- Md_fdvec[fdvec].mdfd_flags = 0;
+ /* Set new free list */
+ for (i = CurFd; i < Nfds; i++)
+ {
+ Md_fdvec[i].mdfd_nextFree = i + 1;
+ Md_fdvec[i].mdfd_flags = MDFD_FREE;
+ }
+ Md_fdvec[Nfds - 1].mdfd_nextFree = -1;
+ Md_Free = CurFd + 1;
- return (fdvec);
+ fdvec = CurFd;
+ CurFd++;
+ Md_fdvec[fdvec].mdfd_flags = 0;
+
+ return (fdvec);
}
/*
- * _fdvec_free () -- free md file descriptor vector.
+ * _fdvec_free () -- free md file descriptor vector.
*
*/
static
-void _fdvec_free (int fdvec)
+void
+_fdvec_free(int fdvec)
{
-
- Assert ( Md_Free < 0 || Md_fdvec[Md_Free].mdfd_flags == MDFD_FREE );
- Md_fdvec[fdvec].mdfd_nextFree = Md_Free;
- Md_fdvec[fdvec].mdfd_flags = MDFD_FREE;
- Md_Free = fdvec;
+
+ Assert(Md_Free < 0 || Md_fdvec[Md_Free].mdfd_flags == MDFD_FREE);
+ Md_fdvec[fdvec].mdfd_nextFree = Md_Free;
+ Md_fdvec[fdvec].mdfd_flags = MDFD_FREE;
+ Md_Free = fdvec;
}
static MdfdVec *
_mdfd_openseg(Relation reln, int segno, int oflags)
{
- MemoryContext oldcxt;
- MdfdVec *v;
- int fd;
- bool dofree;
- char *path, *fullpath;
-
- /* be sure we have enough space for the '.segno', if any */
- path = relpath(RelationGetRelationName(reln)->data);
-
- dofree = false;
- if (segno > 0) {
- dofree = true;
- fullpath = (char *) palloc(strlen(path) + 12);
- sprintf(fullpath, "%s.%d", path, segno);
- } else
- fullpath = path;
-
- /* open the file */
- fd = PathNameOpenFile(fullpath, O_RDWR|oflags, 0600);
-
- if (dofree)
- pfree(fullpath);
-
- if (fd < 0)
- return ((MdfdVec *) NULL);
-
- /* allocate an mdfdvec entry for it */
- oldcxt = MemoryContextSwitchTo(MdCxt);
- v = (MdfdVec *) palloc(sizeof(MdfdVec));
- MemoryContextSwitchTo(oldcxt);
-
- /* fill the entry */
- v->mdfd_vfd = fd;
- v->mdfd_flags = (uint16) 0;
- v->mdfd_chain = (MdfdVec *) NULL;
- v->mdfd_lstbcnt = _mdnblocks(fd, BLCKSZ);
+ MemoryContext oldcxt;
+ MdfdVec *v;
+ int fd;
+ bool dofree;
+ char *path,
+ *fullpath;
+
+ /* be sure we have enough space for the '.segno', if any */
+ path = relpath(RelationGetRelationName(reln)->data);
+
+ dofree = false;
+ if (segno > 0)
+ {
+ dofree = true;
+ fullpath = (char *) palloc(strlen(path) + 12);
+ sprintf(fullpath, "%s.%d", path, segno);
+ }
+ else
+ fullpath = path;
+
+ /* open the file */
+ fd = PathNameOpenFile(fullpath, O_RDWR | oflags, 0600);
+
+ if (dofree)
+ pfree(fullpath);
+
+ if (fd < 0)
+ return ((MdfdVec *) NULL);
+
+ /* allocate an mdfdvec entry for it */
+ oldcxt = MemoryContextSwitchTo(MdCxt);
+ v = (MdfdVec *) palloc(sizeof(MdfdVec));
+ MemoryContextSwitchTo(oldcxt);
+
+ /* fill the entry */
+ v->mdfd_vfd = fd;
+ v->mdfd_flags = (uint16) 0;
+ v->mdfd_chain = (MdfdVec *) NULL;
+ v->mdfd_lstbcnt = _mdnblocks(fd, BLCKSZ);
#ifdef DIAGNOSTIC
- if (v->mdfd_lstbcnt > RELSEG_SIZE)
- elog(FATAL, "segment too big on open!");
+ if (v->mdfd_lstbcnt > RELSEG_SIZE)
+ elog(FATAL, "segment too big on open!");
#endif
- /* all done */
- return (v);
+ /* all done */
+ return (v);
}
static MdfdVec *
_mdfd_getseg(Relation reln, int blkno, int oflag)
{
- MdfdVec *v;
- int segno;
- int fd;
- int i;
-
- fd = RelationGetFile(reln);
- if (fd < 0) {
- if ((fd = mdopen(reln)) < 0)
- elog(WARN, "cannot open relation %.16s",
- RelationGetRelationName(reln));
- reln->rd_fd = fd;
- }
-
- for (v = &Md_fdvec[fd], segno = blkno / RELSEG_SIZE, i = 1;
- segno > 0;
- i++, segno--) {
-
- if (v->mdfd_chain == (MdfdVec *) NULL) {
- v->mdfd_chain = _mdfd_openseg(reln, i, oflag);
-
- if (v->mdfd_chain == (MdfdVec *) NULL)
- elog(WARN, "cannot open segment %d of relation %.16s",
- i, RelationGetRelationName(reln));
+ MdfdVec *v;
+ int segno;
+ int fd;
+ int i;
+
+ fd = RelationGetFile(reln);
+ if (fd < 0)
+ {
+ if ((fd = mdopen(reln)) < 0)
+ elog(WARN, "cannot open relation %.16s",
+ RelationGetRelationName(reln));
+ reln->rd_fd = fd;
+ }
+
+ for (v = &Md_fdvec[fd], segno = blkno / RELSEG_SIZE, i = 1;
+ segno > 0;
+ i++, segno--)
+ {
+
+ if (v->mdfd_chain == (MdfdVec *) NULL)
+ {
+ v->mdfd_chain = _mdfd_openseg(reln, i, oflag);
+
+ if (v->mdfd_chain == (MdfdVec *) NULL)
+ elog(WARN, "cannot open segment %d of relation %.16s",
+ i, RelationGetRelationName(reln));
+ }
+ v = v->mdfd_chain;
}
- v = v->mdfd_chain;
- }
- return (v);
+ return (v);
}
-static BlockNumber
+static BlockNumber
_mdnblocks(File file, Size blcksz)
{
- long len;
-
- len = FileSeek(file, 0L, SEEK_END) - 1;
- return((BlockNumber)((len < 0) ? 0 : 1 + len / blcksz));
+ long len;
+
+ len = FileSeek(file, 0L, SEEK_END) - 1;
+ return ((BlockNumber) ((len < 0) ? 0 : 1 + len / blcksz));
}
diff --git a/src/backend/storage/smgr/mm.c b/src/backend/storage/smgr/mm.c
index fd6c32da3a3..d0015e4f138 100644
--- a/src/backend/storage/smgr/mm.c
+++ b/src/backend/storage/smgr/mm.c
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* mm.c--
- * main memory storage manager
+ * main memory storage manager
*
- * This code manages relations that reside in (presumably stable)
- * main memory.
+ * This code manages relations that reside in (presumably stable)
+ * main memory.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.4 1996/11/08 05:59:11 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.5 1997/09/07 04:49:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,7 +20,7 @@
#include <math.h>
#include "storage/ipc.h"
-#include "storage/smgr.h" /* where the declarations go */
+#include "storage/smgr.h" /* where the declarations go */
#include "storage/block.h"
#include "storage/shmem.h"
#include "storage/spin.h"
@@ -31,555 +31,582 @@
#include "utils/memutils.h"
/*
- * MMCacheTag -- Unique triplet for blocks stored by the main memory
- * storage manager.
+ * MMCacheTag -- Unique triplet for blocks stored by the main memory
+ * storage manager.
*/
-typedef struct MMCacheTag {
- Oid mmct_dbid;
- Oid mmct_relid;
- BlockNumber mmct_blkno;
-} MMCacheTag;
+typedef struct MMCacheTag
+{
+ Oid mmct_dbid;
+ Oid mmct_relid;
+ BlockNumber mmct_blkno;
+} MMCacheTag;
/*
- * Shared-memory hash table for main memory relations contains
- * entries of this form.
+ * Shared-memory hash table for main memory relations contains
+ * entries of this form.
*/
-typedef struct MMHashEntry {
- MMCacheTag mmhe_tag;
- int mmhe_bufno;
-} MMHashEntry;
+typedef struct MMHashEntry
+{
+ MMCacheTag mmhe_tag;
+ int mmhe_bufno;
+} MMHashEntry;
/*
* MMRelTag -- Unique identifier for each relation that is stored in the
- * main-memory storage manager.
+ * main-memory storage manager.
*/
-typedef struct MMRelTag {
- Oid mmrt_dbid;
- Oid mmrt_relid;
-} MMRelTag;
+typedef struct MMRelTag
+{
+ Oid mmrt_dbid;
+ Oid mmrt_relid;
+} MMRelTag;
/*
- * Shared-memory hash table for # blocks in main memory relations contains
- * entries of this form.
+ * Shared-memory hash table for # blocks in main memory relations contains
+ * entries of this form.
*/
-typedef struct MMRelHashEntry {
- MMRelTag mmrhe_tag;
- int mmrhe_nblocks;
-} MMRelHashEntry;
+typedef struct MMRelHashEntry
+{
+ MMRelTag mmrhe_tag;
+ int mmrhe_nblocks;
+} MMRelHashEntry;
-#define MMNBUFFERS 10
+#define MMNBUFFERS 10
#define MMNRELATIONS 2
-SPINLOCK MMCacheLock;
-extern bool IsPostmaster;
-extern Oid MyDatabaseId;
+SPINLOCK MMCacheLock;
+extern bool IsPostmaster;
+extern Oid MyDatabaseId;
-static int *MMCurTop;
-static int *MMCurRelno;
-static MMCacheTag *MMBlockTags;
-static char *MMBlockCache;
-static HTAB *MMCacheHT;
-static HTAB *MMRelCacheHT;
+static int *MMCurTop;
+static int *MMCurRelno;
+static MMCacheTag *MMBlockTags;
+static char *MMBlockCache;
+static HTAB *MMCacheHT;
+static HTAB *MMRelCacheHT;
int
mminit()
{
- char *mmcacheblk;
- int mmsize = 0;
- bool found;
- HASHCTL info;
+ char *mmcacheblk;
+ int mmsize = 0;
+ bool found;
+ HASHCTL info;
- SpinAcquire(MMCacheLock);
+ SpinAcquire(MMCacheLock);
- mmsize += MAXALIGN(BLCKSZ * MMNBUFFERS);
- mmsize += MAXALIGN(sizeof(*MMCurTop));
- mmsize += MAXALIGN(sizeof(*MMCurRelno));
- mmsize += MAXALIGN((MMNBUFFERS * sizeof(MMCacheTag)));
- mmcacheblk = (char *) ShmemInitStruct("Main memory smgr", mmsize, &found);
+ mmsize += MAXALIGN(BLCKSZ * MMNBUFFERS);
+ mmsize += MAXALIGN(sizeof(*MMCurTop));
+ mmsize += MAXALIGN(sizeof(*MMCurRelno));
+ mmsize += MAXALIGN((MMNBUFFERS * sizeof(MMCacheTag)));
+ mmcacheblk = (char *) ShmemInitStruct("Main memory smgr", mmsize, &found);
- if (mmcacheblk == (char *) NULL) {
- SpinRelease(MMCacheLock);
- return (SM_FAIL);
- }
+ if (mmcacheblk == (char *) NULL)
+ {
+ SpinRelease(MMCacheLock);
+ return (SM_FAIL);
+ }
- info.keysize = sizeof(MMCacheTag);
- info.datasize = sizeof(int);
- info.hash = tag_hash;
+ info.keysize = sizeof(MMCacheTag);
+ info.datasize = sizeof(int);
+ info.hash = tag_hash;
- MMCacheHT = (HTAB *) ShmemInitHash("Main memory store HT",
- MMNBUFFERS, MMNBUFFERS,
- &info, (HASH_ELEM|HASH_FUNCTION));
+ MMCacheHT = (HTAB *) ShmemInitHash("Main memory store HT",
+ MMNBUFFERS, MMNBUFFERS,
+ &info, (HASH_ELEM | HASH_FUNCTION));
- if (MMCacheHT == (HTAB *) NULL) {
- SpinRelease(MMCacheLock);
- return (SM_FAIL);
- }
+ if (MMCacheHT == (HTAB *) NULL)
+ {
+ SpinRelease(MMCacheLock);
+ return (SM_FAIL);
+ }
- info.keysize = sizeof(MMRelTag);
- info.datasize = sizeof(int);
- info.hash = tag_hash;
+ info.keysize = sizeof(MMRelTag);
+ info.datasize = sizeof(int);
+ info.hash = tag_hash;
- MMRelCacheHT = (HTAB *) ShmemInitHash("Main memory rel HT",
- MMNRELATIONS, MMNRELATIONS,
- &info, (HASH_ELEM|HASH_FUNCTION));
+ MMRelCacheHT = (HTAB *) ShmemInitHash("Main memory rel HT",
+ MMNRELATIONS, MMNRELATIONS,
+ &info, (HASH_ELEM | HASH_FUNCTION));
- if (MMRelCacheHT == (HTAB *) NULL) {
- SpinRelease(MMCacheLock);
- return (SM_FAIL);
- }
+ if (MMRelCacheHT == (HTAB *) NULL)
+ {
+ SpinRelease(MMCacheLock);
+ return (SM_FAIL);
+ }
- if (IsPostmaster) {
- memset(mmcacheblk, 0, mmsize);
- SpinRelease(MMCacheLock);
- return (SM_SUCCESS);
- }
+ if (IsPostmaster)
+ {
+ memset(mmcacheblk, 0, mmsize);
+ SpinRelease(MMCacheLock);
+ return (SM_SUCCESS);
+ }
- SpinRelease(MMCacheLock);
+ SpinRelease(MMCacheLock);
- MMCurTop = (int *) mmcacheblk;
- mmcacheblk += sizeof(int);
- MMCurRelno = (int *) mmcacheblk;
- mmcacheblk += sizeof(int);
- MMBlockTags = (MMCacheTag *) mmcacheblk;
- mmcacheblk += (MMNBUFFERS * sizeof(MMCacheTag));
- MMBlockCache = mmcacheblk;
+ MMCurTop = (int *) mmcacheblk;
+ mmcacheblk += sizeof(int);
+ MMCurRelno = (int *) mmcacheblk;
+ mmcacheblk += sizeof(int);
+ MMBlockTags = (MMCacheTag *) mmcacheblk;
+ mmcacheblk += (MMNBUFFERS * sizeof(MMCacheTag));
+ MMBlockCache = mmcacheblk;
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
int
mmshutdown()
{
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
int
mmcreate(Relation reln)
{
- MMRelHashEntry *entry;
- bool found;
- MMRelTag tag;
+ MMRelHashEntry *entry;
+ bool found;
+ MMRelTag tag;
- SpinAcquire(MMCacheLock);
+ SpinAcquire(MMCacheLock);
- if (*MMCurRelno == MMNRELATIONS) {
- SpinRelease(MMCacheLock);
- return (SM_FAIL);
- }
+ if (*MMCurRelno == MMNRELATIONS)
+ {
+ SpinRelease(MMCacheLock);
+ return (SM_FAIL);
+ }
- (*MMCurRelno)++;
+ (*MMCurRelno)++;
- tag.mmrt_relid = reln->rd_id;
- if (reln->rd_rel->relisshared)
- tag.mmrt_dbid = (Oid) 0;
- else
- tag.mmrt_dbid = MyDatabaseId;
+ tag.mmrt_relid = reln->rd_id;
+ if (reln->rd_rel->relisshared)
+ tag.mmrt_dbid = (Oid) 0;
+ else
+ tag.mmrt_dbid = MyDatabaseId;
- entry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
- (char *) &tag, HASH_ENTER, &found);
+ entry = (MMRelHashEntry *) hash_search(MMRelCacheHT,
+ (char *) &tag, HASH_ENTER, &found);
- if (entry == (MMRelHashEntry *) NULL) {
- SpinRelease(MMCacheLock);
- elog(FATAL, "main memory storage mgr rel cache hash table corrupt");
- }
+ if (entry == (MMRelHashEntry *) NULL)
+ {
+ SpinRelease(MMCacheLock);
+ elog(FATAL, "main memory storage mgr rel cache hash table corrupt");
+ }
- if (found) {
- /* already exists */
- SpinRelease(MMCacheLock);
- return (SM_FAIL);
- }
+ if (found)
+ {
+ /* already exists */
+ SpinRelease(MMCacheLock);
+ return (SM_FAIL);
+ }
- entry->mmrhe_nblocks = 0;
+ entry->mmrhe_nblocks = 0;
- SpinRelease(MMCacheLock);
+ SpinRelease(MMCacheLock);
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
/*
- * mmunlink() -- Unlink a relation.
+ * mmunlink() -- Unlink a relation.
*/
int
mmunlink(Relation reln)
{
- int i;
- Oid reldbid;
- MMHashEntry *entry;
- MMRelHashEntry *rentry;
- bool found;
- MMRelTag rtag;
-
- if (reln->rd_rel->relisshared)
- reldbid = (Oid) 0;
- else
- reldbid = MyDatabaseId;
-
- SpinAcquire(MMCacheLock);
-
- for (i = 0; i < MMNBUFFERS; i++) {
- if (MMBlockTags[i].mmct_dbid == reldbid
- && MMBlockTags[i].mmct_relid == reln->rd_id) {
- entry = (MMHashEntry *) hash_search(MMCacheHT,
- (char *) &MMBlockTags[i],
- HASH_REMOVE, &found);
- if (entry == (MMHashEntry *) NULL || !found) {
- SpinRelease(MMCacheLock);
- elog(FATAL, "mmunlink: cache hash table corrupted");
- }
- MMBlockTags[i].mmct_dbid = (Oid) 0;
- MMBlockTags[i].mmct_relid = (Oid) 0;
- MMBlockTags[i].mmct_blkno = (BlockNumber) 0;
+ int i;
+ Oid reldbid;
+ MMHashEntry *entry;
+ MMRelHashEntry *rentry;
+ bool found;
+ MMRelTag rtag;
+
+ if (reln->rd_rel->relisshared)
+ reldbid = (Oid) 0;
+ else
+ reldbid = MyDatabaseId;
+
+ SpinAcquire(MMCacheLock);
+
+ for (i = 0; i < MMNBUFFERS; i++)
+ {
+ if (MMBlockTags[i].mmct_dbid == reldbid
+ && MMBlockTags[i].mmct_relid == reln->rd_id)
+ {
+ entry = (MMHashEntry *) hash_search(MMCacheHT,
+ (char *) &MMBlockTags[i],
+ HASH_REMOVE, &found);
+ if (entry == (MMHashEntry *) NULL || !found)
+ {
+ SpinRelease(MMCacheLock);
+ elog(FATAL, "mmunlink: cache hash table corrupted");
+ }
+ MMBlockTags[i].mmct_dbid = (Oid) 0;
+ MMBlockTags[i].mmct_relid = (Oid) 0;
+ MMBlockTags[i].mmct_blkno = (BlockNumber) 0;
+ }
}
- }
- rtag.mmrt_dbid = reldbid;
- rtag.mmrt_relid = reln->rd_id;
+ rtag.mmrt_dbid = reldbid;
+ rtag.mmrt_relid = reln->rd_id;
- rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag,
- HASH_REMOVE, &found);
+ rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag,
+ HASH_REMOVE, &found);
- if (rentry == (MMRelHashEntry *) NULL || !found) {
- SpinRelease(MMCacheLock);
- elog(FATAL, "mmunlink: rel cache hash table corrupted");
- }
+ if (rentry == (MMRelHashEntry *) NULL || !found)
+ {
+ SpinRelease(MMCacheLock);
+ elog(FATAL, "mmunlink: rel cache hash table corrupted");
+ }
- (*MMCurRelno)--;
+ (*MMCurRelno)--;
- SpinRelease(MMCacheLock);
- return 1;
+ SpinRelease(MMCacheLock);
+ return 1;
}
/*
- * mmextend() -- Add a block to the specified relation.
+ * mmextend() -- Add a block to the specified relation.
*
- * This routine returns SM_FAIL or SM_SUCCESS, with errno set as
- * appropriate.
+ * This routine returns SM_FAIL or SM_SUCCESS, with errno set as
+ * appropriate.
*/
int
mmextend(Relation reln, char *buffer)
{
- MMRelHashEntry *rentry;
- MMHashEntry *entry;
- int i;
- Oid reldbid;
- int offset;
- bool found;
- MMRelTag rtag;
- MMCacheTag tag;
-
- if (reln->rd_rel->relisshared)
- reldbid = (Oid) 0;
- else
- reldbid = MyDatabaseId;
-
- tag.mmct_dbid = rtag.mmrt_dbid = reldbid;
- tag.mmct_relid = rtag.mmrt_relid = reln->rd_id;
-
- SpinAcquire(MMCacheLock);
-
- if (*MMCurTop == MMNBUFFERS) {
- for (i = 0; i < MMNBUFFERS; i++) {
- if (MMBlockTags[i].mmct_dbid == 0 &&
- MMBlockTags[i].mmct_relid == 0)
- break;
+ MMRelHashEntry *rentry;
+ MMHashEntry *entry;
+ int i;
+ Oid reldbid;
+ int offset;
+ bool found;
+ MMRelTag rtag;
+ MMCacheTag tag;
+
+ if (reln->rd_rel->relisshared)
+ reldbid = (Oid) 0;
+ else
+ reldbid = MyDatabaseId;
+
+ tag.mmct_dbid = rtag.mmrt_dbid = reldbid;
+ tag.mmct_relid = rtag.mmrt_relid = reln->rd_id;
+
+ SpinAcquire(MMCacheLock);
+
+ if (*MMCurTop == MMNBUFFERS)
+ {
+ for (i = 0; i < MMNBUFFERS; i++)
+ {
+ if (MMBlockTags[i].mmct_dbid == 0 &&
+ MMBlockTags[i].mmct_relid == 0)
+ break;
+ }
+ if (i == MMNBUFFERS)
+ {
+ SpinRelease(MMCacheLock);
+ return (SM_FAIL);
+ }
}
- if (i == MMNBUFFERS) {
- SpinRelease(MMCacheLock);
- return (SM_FAIL);
+ else
+ {
+ i = *MMCurTop;
+ (*MMCurTop)++;
}
- } else {
- i = *MMCurTop;
- (*MMCurTop)++;
- }
-
- rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag,
- HASH_FIND, &found);
- if (rentry == (MMRelHashEntry *) NULL || !found) {
- SpinRelease(MMCacheLock);
- elog(FATAL, "mmextend: rel cache hash table corrupt");
- }
- tag.mmct_blkno = rentry->mmrhe_nblocks;
+ rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag,
+ HASH_FIND, &found);
+ if (rentry == (MMRelHashEntry *) NULL || !found)
+ {
+ SpinRelease(MMCacheLock);
+ elog(FATAL, "mmextend: rel cache hash table corrupt");
+ }
- entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag,
- HASH_ENTER, &found);
- if (entry == (MMHashEntry *) NULL || found) {
- SpinRelease(MMCacheLock);
- elog(FATAL, "mmextend: cache hash table corrupt");
- }
+ tag.mmct_blkno = rentry->mmrhe_nblocks;
- entry->mmhe_bufno = i;
- MMBlockTags[i].mmct_dbid = reldbid;
- MMBlockTags[i].mmct_relid = reln->rd_id;
- MMBlockTags[i].mmct_blkno = rentry->mmrhe_nblocks;
+ entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag,
+ HASH_ENTER, &found);
+ if (entry == (MMHashEntry *) NULL || found)
+ {
+ SpinRelease(MMCacheLock);
+ elog(FATAL, "mmextend: cache hash table corrupt");
+ }
- /* page numbers are zero-based, so we increment this at the end */
- (rentry->mmrhe_nblocks)++;
+ entry->mmhe_bufno = i;
+ MMBlockTags[i].mmct_dbid = reldbid;
+ MMBlockTags[i].mmct_relid = reln->rd_id;
+ MMBlockTags[i].mmct_blkno = rentry->mmrhe_nblocks;
- /* write the extended page */
- offset = (i * BLCKSZ);
- memmove(&(MMBlockCache[offset]), buffer, BLCKSZ);
+ /* page numbers are zero-based, so we increment this at the end */
+ (rentry->mmrhe_nblocks)++;
- SpinRelease(MMCacheLock);
+ /* write the extended page */
+ offset = (i * BLCKSZ);
+ memmove(&(MMBlockCache[offset]), buffer, BLCKSZ);
- return (SM_SUCCESS);
+ SpinRelease(MMCacheLock);
+
+ return (SM_SUCCESS);
}
/*
- * mmopen() -- Open the specified relation.
+ * mmopen() -- Open the specified relation.
*/
int
mmopen(Relation reln)
{
- /* automatically successful */
- return (0);
+ /* automatically successful */
+ return (0);
}
/*
- * mmclose() -- Close the specified relation.
+ * mmclose() -- Close the specified relation.
*
- * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
+ * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
*/
int
mmclose(Relation reln)
{
- /* automatically successful */
- return (SM_SUCCESS);
+ /* automatically successful */
+ return (SM_SUCCESS);
}
/*
- * mmread() -- Read the specified block from a relation.
+ * mmread() -- Read the specified block from a relation.
*
- * Returns SM_SUCCESS or SM_FAIL.
+ * Returns SM_SUCCESS or SM_FAIL.
*/
int
mmread(Relation reln, BlockNumber blocknum, char *buffer)
{
- MMHashEntry *entry;
- bool found;
- int offset;
- MMCacheTag tag;
+ MMHashEntry *entry;
+ bool found;
+ int offset;
+ MMCacheTag tag;
- if (reln->rd_rel->relisshared)
- tag.mmct_dbid = (Oid) 0;
- else
- tag.mmct_dbid = MyDatabaseId;
+ if (reln->rd_rel->relisshared)
+ tag.mmct_dbid = (Oid) 0;
+ else
+ tag.mmct_dbid = MyDatabaseId;
- tag.mmct_relid = reln->rd_id;
- tag.mmct_blkno = blocknum;
+ tag.mmct_relid = reln->rd_id;
+ tag.mmct_blkno = blocknum;
- SpinAcquire(MMCacheLock);
- entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag,
- HASH_FIND, &found);
+ SpinAcquire(MMCacheLock);
+ entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag,
+ HASH_FIND, &found);
- if (entry == (MMHashEntry *) NULL) {
- SpinRelease(MMCacheLock);
- elog(FATAL, "mmread: hash table corrupt");
- }
+ if (entry == (MMHashEntry *) NULL)
+ {
+ SpinRelease(MMCacheLock);
+ elog(FATAL, "mmread: hash table corrupt");
+ }
- if (!found) {
- /* reading nonexistent pages is defined to fill them with zeroes */
- SpinRelease(MMCacheLock);
- memset(buffer, 0, BLCKSZ);
- return (SM_SUCCESS);
- }
+ if (!found)
+ {
+ /* reading nonexistent pages is defined to fill them with zeroes */
+ SpinRelease(MMCacheLock);
+ memset(buffer, 0, BLCKSZ);
+ return (SM_SUCCESS);
+ }
- offset = (entry->mmhe_bufno * BLCKSZ);
- memmove(buffer, &MMBlockCache[offset], BLCKSZ);
+ offset = (entry->mmhe_bufno * BLCKSZ);
+ memmove(buffer, &MMBlockCache[offset], BLCKSZ);
- SpinRelease(MMCacheLock);
+ SpinRelease(MMCacheLock);
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
/*
- * mmwrite() -- Write the supplied block at the appropriate location.
+ * mmwrite() -- Write the supplied block at the appropriate location.
*
- * Returns SM_SUCCESS or SM_FAIL.
+ * Returns SM_SUCCESS or SM_FAIL.
*/
int
mmwrite(Relation reln, BlockNumber blocknum, char *buffer)
{
- MMHashEntry *entry;
- bool found;
- int offset;
- MMCacheTag tag;
+ MMHashEntry *entry;
+ bool found;
+ int offset;
+ MMCacheTag tag;
- if (reln->rd_rel->relisshared)
- tag.mmct_dbid = (Oid) 0;
- else
- tag.mmct_dbid = MyDatabaseId;
+ if (reln->rd_rel->relisshared)
+ tag.mmct_dbid = (Oid) 0;
+ else
+ tag.mmct_dbid = MyDatabaseId;
- tag.mmct_relid = reln->rd_id;
- tag.mmct_blkno = blocknum;
+ tag.mmct_relid = reln->rd_id;
+ tag.mmct_blkno = blocknum;
- SpinAcquire(MMCacheLock);
- entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag,
- HASH_FIND, &found);
+ SpinAcquire(MMCacheLock);
+ entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag,
+ HASH_FIND, &found);
- if (entry == (MMHashEntry *) NULL) {
- SpinRelease(MMCacheLock);
- elog(FATAL, "mmread: hash table corrupt");
- }
+ if (entry == (MMHashEntry *) NULL)
+ {
+ SpinRelease(MMCacheLock);
+ elog(FATAL, "mmread: hash table corrupt");
+ }
- if (!found) {
- SpinRelease(MMCacheLock);
- elog(FATAL, "mmwrite: hash table missing requested page");
- }
+ if (!found)
+ {
+ SpinRelease(MMCacheLock);
+ elog(FATAL, "mmwrite: hash table missing requested page");
+ }
- offset = (entry->mmhe_bufno * BLCKSZ);
- memmove(&MMBlockCache[offset], buffer, BLCKSZ);
+ offset = (entry->mmhe_bufno * BLCKSZ);
+ memmove(&MMBlockCache[offset], buffer, BLCKSZ);
- SpinRelease(MMCacheLock);
+ SpinRelease(MMCacheLock);
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
/*
- * mmflush() -- Synchronously write a block to stable storage.
+ * mmflush() -- Synchronously write a block to stable storage.
*
- * For main-memory relations, this is exactly equivalent to mmwrite().
+ * For main-memory relations, this is exactly equivalent to mmwrite().
*/
int
mmflush(Relation reln, BlockNumber blocknum, char *buffer)
{
- return (mmwrite(reln, blocknum, buffer));
+ return (mmwrite(reln, blocknum, buffer));
}
/*
- * mmblindwrt() -- Write a block to stable storage blind.
+ * mmblindwrt() -- Write a block to stable storage blind.
*
- * We have to be able to do this using only the name and OID of
- * the database and relation in which the block belongs.
+ * We have to be able to do this using only the name and OID of
+ * the database and relation in which the block belongs.
*/
int
mmblindwrt(char *dbstr,
- char *relstr,
- Oid dbid,
- Oid relid,
- BlockNumber blkno,
- char *buffer)
+ char *relstr,
+ Oid dbid,
+ Oid relid,
+ BlockNumber blkno,
+ char *buffer)
{
- return (SM_FAIL);
+ return (SM_FAIL);
}
/*
- * mmnblocks() -- Get the number of blocks stored in a relation.
+ * mmnblocks() -- Get the number of blocks stored in a relation.
*
- * Returns # of blocks or -1 on error.
+ * Returns # of blocks or -1 on error.
*/
int
mmnblocks(Relation reln)
{
- MMRelTag rtag;
- MMRelHashEntry *rentry;
- bool found;
- int nblocks;
+ MMRelTag rtag;
+ MMRelHashEntry *rentry;
+ bool found;
+ int nblocks;
- if (reln->rd_rel->relisshared)
- rtag.mmrt_dbid = (Oid) 0;
- else
- rtag.mmrt_dbid = MyDatabaseId;
+ if (reln->rd_rel->relisshared)
+ rtag.mmrt_dbid = (Oid) 0;
+ else
+ rtag.mmrt_dbid = MyDatabaseId;
- rtag.mmrt_relid = reln->rd_id;
+ rtag.mmrt_relid = reln->rd_id;
- SpinAcquire(MMCacheLock);
+ SpinAcquire(MMCacheLock);
- rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag,
- HASH_FIND, &found);
+ rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag,
+ HASH_FIND, &found);
- if (rentry == (MMRelHashEntry *) NULL) {
- SpinRelease(MMCacheLock);
- elog(FATAL, "mmnblocks: rel cache hash table corrupt");
- }
+ if (rentry == (MMRelHashEntry *) NULL)
+ {
+ SpinRelease(MMCacheLock);
+ elog(FATAL, "mmnblocks: rel cache hash table corrupt");
+ }
- if (found)
- nblocks = rentry->mmrhe_nblocks;
- else
- nblocks = -1;
+ if (found)
+ nblocks = rentry->mmrhe_nblocks;
+ else
+ nblocks = -1;
- SpinRelease(MMCacheLock);
+ SpinRelease(MMCacheLock);
- return (nblocks);
+ return (nblocks);
}
/*
- * mmcommit() -- Commit a transaction.
+ * mmcommit() -- Commit a transaction.
*
- * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
+ * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
*/
int
mmcommit()
{
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
/*
- * mmabort() -- Abort a transaction.
+ * mmabort() -- Abort a transaction.
*/
int
mmabort()
{
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
/*
- * MMShmemSize() -- Declare amount of shared memory we require.
+ * MMShmemSize() -- Declare amount of shared memory we require.
*
- * The shared memory initialization code creates a block of shared
- * memory exactly big enough to hold all the structures it needs to.
- * This routine declares how much space the main memory storage
- * manager will use.
+ * The shared memory initialization code creates a block of shared
+ * memory exactly big enough to hold all the structures it needs to.
+ * This routine declares how much space the main memory storage
+ * manager will use.
*/
int
MMShmemSize()
{
- int size = 0;
- int nbuckets;
- int nsegs;
- int tmp;
-
- /*
- * first compute space occupied by the (dbid,relid,blkno) hash table
- */
-
- nbuckets = 1 << (int)my_log2((MMNBUFFERS - 1) / DEF_FFACTOR + 1);
- nsegs = 1 << (int)my_log2((nbuckets - 1) / DEF_SEGSIZE + 1);
-
- size += MAXALIGN(my_log2(MMNBUFFERS) * sizeof(void *));
- size += MAXALIGN(sizeof(HHDR));
- size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
- tmp = (int)ceil((double)MMNBUFFERS/BUCKET_ALLOC_INCR);
- size += tmp * BUCKET_ALLOC_INCR *
- (MAXALIGN(sizeof(BUCKET_INDEX)) +
- MAXALIGN(sizeof(MMHashEntry))); /* contains hash key */
-
- /*
- * now do the same for the rel hash table
- */
-
- size += MAXALIGN(my_log2(MMNRELATIONS) * sizeof(void *));
- size += MAXALIGN(sizeof(HHDR));
- size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
- tmp = (int)ceil((double)MMNRELATIONS/BUCKET_ALLOC_INCR);
- size += tmp * BUCKET_ALLOC_INCR *
- (MAXALIGN(sizeof(BUCKET_INDEX)) +
- MAXALIGN(sizeof(MMRelHashEntry))); /* contains hash key */
-
- /*
- * finally, add in the memory block we use directly
- */
-
- size += MAXALIGN(BLCKSZ * MMNBUFFERS);
- size += MAXALIGN(sizeof(*MMCurTop));
- size += MAXALIGN(sizeof(*MMCurRelno));
- size += MAXALIGN(MMNBUFFERS * sizeof(MMCacheTag));
-
- return (size);
+ int size = 0;
+ int nbuckets;
+ int nsegs;
+ int tmp;
+
+ /*
+ * first compute space occupied by the (dbid,relid,blkno) hash table
+ */
+
+ nbuckets = 1 << (int) my_log2((MMNBUFFERS - 1) / DEF_FFACTOR + 1);
+ nsegs = 1 << (int) my_log2((nbuckets - 1) / DEF_SEGSIZE + 1);
+
+ size += MAXALIGN(my_log2(MMNBUFFERS) * sizeof(void *));
+ size += MAXALIGN(sizeof(HHDR));
+ size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
+ tmp = (int) ceil((double) MMNBUFFERS / BUCKET_ALLOC_INCR);
+ size += tmp * BUCKET_ALLOC_INCR *
+ (MAXALIGN(sizeof(BUCKET_INDEX)) +
+ MAXALIGN(sizeof(MMHashEntry))); /* contains hash key */
+
+ /*
+ * now do the same for the rel hash table
+ */
+
+ size += MAXALIGN(my_log2(MMNRELATIONS) * sizeof(void *));
+ size += MAXALIGN(sizeof(HHDR));
+ size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT));
+ tmp = (int) ceil((double) MMNRELATIONS / BUCKET_ALLOC_INCR);
+ size += tmp * BUCKET_ALLOC_INCR *
+ (MAXALIGN(sizeof(BUCKET_INDEX)) +
+ MAXALIGN(sizeof(MMRelHashEntry))); /* contains hash key */
+
+ /*
+ * finally, add in the memory block we use directly
+ */
+
+ size += MAXALIGN(BLCKSZ * MMNBUFFERS);
+ size += MAXALIGN(sizeof(*MMCurTop));
+ size += MAXALIGN(sizeof(*MMCurRelno));
+ size += MAXALIGN(MMNBUFFERS * sizeof(MMCacheTag));
+
+ return (size);
}
-#endif /* MAIN_MEMORY */
+#endif /* MAIN_MEMORY */
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index 89ac5e92cb7..9fc395da0d9 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* smgr.c--
- * public interface routines to storage manager switch.
+ * public interface routines to storage manager switch.
*
- * All file system operations in POSTGRES dispatch through these
- * routines.
+ * All file system operations in POSTGRES dispatch through these
+ * routines.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.8 1997/08/19 21:33:38 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.9 1997/09/07 04:49:25 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,380 +23,390 @@
#include "utils/rel.h"
#include "utils/palloc.h"
-static void smgrshutdown(int dummy);
-
-typedef struct f_smgr {
- int (*smgr_init)(); /* may be NULL */
- int (*smgr_shutdown)(); /* may be NULL */
- int (*smgr_create)();
- int (*smgr_unlink)();
- int (*smgr_extend)();
- int (*smgr_open)();
- int (*smgr_close)();
- int (*smgr_read)();
- int (*smgr_write)();
- int (*smgr_flush)();
- int (*smgr_blindwrt)();
- int (*smgr_nblocks)();
- int (*smgr_truncate)();
- int (*smgr_commit)(); /* may be NULL */
- int (*smgr_abort)(); /* may be NULL */
-} f_smgr;
+static void smgrshutdown(int dummy);
+
+typedef struct f_smgr
+{
+ int (*smgr_init) (); /* may be NULL */
+ int (*smgr_shutdown) (); /* may be NULL */
+ int (*smgr_create) ();
+ int (*smgr_unlink) ();
+ int (*smgr_extend) ();
+ int (*smgr_open) ();
+ int (*smgr_close) ();
+ int (*smgr_read) ();
+ int (*smgr_write) ();
+ int (*smgr_flush) ();
+ int (*smgr_blindwrt) ();
+ int (*smgr_nblocks) ();
+ int (*smgr_truncate) ();
+ int (*smgr_commit) (); /* may be NULL */
+ int (*smgr_abort) (); /* may be NULL */
+} f_smgr;
/*
- * The weird placement of commas in this init block is to keep the compiler
- * happy, regardless of what storage managers we have (or don't have).
+ * The weird placement of commas in this init block is to keep the compiler
+ * happy, regardless of what storage managers we have (or don't have).
*/
-static f_smgr smgrsw[] = {
+static f_smgr smgrsw[] = {
- /* magnetic disk */
- { mdinit, NULL, mdcreate, mdunlink, mdextend, mdopen, mdclose,
- mdread, mdwrite, mdflush, mdblindwrt, mdnblocks, mdtruncate,
- mdcommit, mdabort },
+ /* magnetic disk */
+ {mdinit, NULL, mdcreate, mdunlink, mdextend, mdopen, mdclose,
+ mdread, mdwrite, mdflush, mdblindwrt, mdnblocks, mdtruncate,
+ mdcommit, mdabort},
#ifdef MAIN_MEMORY
- /* main memory */
- { mminit, mmshutdown, mmcreate, mmunlink, mmextend, mmopen, mmclose,
- mmread, mmwrite, mmflush, mmblindwrt, mmnblocks, NULL,
- mmcommit, mmabort },
+ /* main memory */
+ {mminit, mmshutdown, mmcreate, mmunlink, mmextend, mmopen, mmclose,
+ mmread, mmwrite, mmflush, mmblindwrt, mmnblocks, NULL,
+ mmcommit, mmabort},
-#endif /* MAIN_MEMORY */
+#endif /* MAIN_MEMORY */
};
/*
- * This array records which storage managers are write-once, and which
- * support overwrite. A 'true' entry means that the storage manager is
- * write-once. In the best of all possible worlds, there would be no
- * write-once storage managers.
+ * This array records which storage managers are write-once, and which
+ * support overwrite. A 'true' entry means that the storage manager is
+ * write-once. In the best of all possible worlds, there would be no
+ * write-once storage managers.
*/
-static bool smgrwo[] = {
- false, /* magnetic disk */
+static bool smgrwo[] = {
+ false, /* magnetic disk */
#ifdef MAIN_MEMORY
- false, /* main memory*/
-#endif /* MAIN_MEMORY */
+ false, /* main memory */
+#endif /* MAIN_MEMORY */
};
-static int NSmgr = lengthof(smgrsw);
+static int NSmgr = lengthof(smgrsw);
/*
- * smgrinit(), smgrshutdown() -- Initialize or shut down all storage
- * managers.
+ * smgrinit(), smgrshutdown() -- Initialize or shut down all storage
+ * managers.
*
*/
int
smgrinit()
{
- int i;
-
- for (i = 0; i < NSmgr; i++) {
- if (smgrsw[i].smgr_init) {
- if ((*(smgrsw[i].smgr_init))() == SM_FAIL)
- elog(FATAL, "initialization failed on %s", smgrout(i));
+ int i;
+
+ for (i = 0; i < NSmgr; i++)
+ {
+ if (smgrsw[i].smgr_init)
+ {
+ if ((*(smgrsw[i].smgr_init)) () == SM_FAIL)
+ elog(FATAL, "initialization failed on %s", smgrout(i));
+ }
}
- }
- /* register the shutdown proc */
- on_exitpg(smgrshutdown, 0);
+ /* register the shutdown proc */
+ on_exitpg(smgrshutdown, 0);
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
static void
smgrshutdown(int dummy)
{
- int i;
-
- for (i = 0; i < NSmgr; i++) {
- if (smgrsw[i].smgr_shutdown) {
- if ((*(smgrsw[i].smgr_shutdown))() == SM_FAIL)
- elog(FATAL, "shutdown failed on %s", smgrout(i));
+ int i;
+
+ for (i = 0; i < NSmgr; i++)
+ {
+ if (smgrsw[i].smgr_shutdown)
+ {
+ if ((*(smgrsw[i].smgr_shutdown)) () == SM_FAIL)
+ elog(FATAL, "shutdown failed on %s", smgrout(i));
+ }
}
- }
}
/*
- * smgrcreate() -- Create a new relation.
+ * smgrcreate() -- Create a new relation.
*
- * This routine takes a reldesc, creates the relation on the appropriate
- * device, and returns a file descriptor for it.
+ * This routine takes a reldesc, creates the relation on the appropriate
+ * device, and returns a file descriptor for it.
*/
int
smgrcreate(int16 which, Relation reln)
{
- int fd;
+ int fd;
- if ((fd = (*(smgrsw[which].smgr_create))(reln)) < 0)
- elog(WARN, "cannot open %s",
- &(reln->rd_rel->relname.data[0]));
+ if ((fd = (*(smgrsw[which].smgr_create)) (reln)) < 0)
+ elog(WARN, "cannot open %s",
+ &(reln->rd_rel->relname.data[0]));
- return (fd);
+ return (fd);
}
/*
- * smgrunlink() -- Unlink a relation.
+ * smgrunlink() -- Unlink a relation.
*
- * The relation is removed from the store.
+ * The relation is removed from the store.
*/
int
smgrunlink(int16 which, Relation reln)
{
- int status;
+ int status;
- if ((status = (*(smgrsw[which].smgr_unlink))(reln)) == SM_FAIL)
- elog(WARN, "cannot unlink %s",
- &(reln->rd_rel->relname.data[0]));
+ if ((status = (*(smgrsw[which].smgr_unlink)) (reln)) == SM_FAIL)
+ elog(WARN, "cannot unlink %s",
+ &(reln->rd_rel->relname.data[0]));
- return (status);
+ return (status);
}
/*
- * smgrextend() -- Add a new block to a file.
+ * smgrextend() -- Add a new block to a file.
*
- * Returns SM_SUCCESS on success; aborts the current transaction on
- * failure.
+ * Returns SM_SUCCESS on success; aborts the current transaction on
+ * failure.
*/
int
smgrextend(int16 which, Relation reln, char *buffer)
{
- int status;
+ int status;
- status = (*(smgrsw[which].smgr_extend))(reln, buffer);
+ status = (*(smgrsw[which].smgr_extend)) (reln, buffer);
- if (status == SM_FAIL)
- elog(WARN, "%s: cannot extend",
- &(reln->rd_rel->relname.data[0]));
+ if (status == SM_FAIL)
+ elog(WARN, "%s: cannot extend",
+ &(reln->rd_rel->relname.data[0]));
- return (status);
+ return (status);
}
/*
- * smgropen() -- Open a relation using a particular storage manager.
+ * smgropen() -- Open a relation using a particular storage manager.
*
- * Returns the fd for the open relation on success, aborts the
- * transaction on failure.
+ * Returns the fd for the open relation on success, aborts the
+ * transaction on failure.
*/
int
smgropen(int16 which, Relation reln)
{
- int fd;
+ int fd;
- if ((fd = (*(smgrsw[which].smgr_open))(reln)) < 0)
- elog(WARN, "cannot open %s",
- &(reln->rd_rel->relname.data[0]));
+ if ((fd = (*(smgrsw[which].smgr_open)) (reln)) < 0)
+ elog(WARN, "cannot open %s",
+ &(reln->rd_rel->relname.data[0]));
- return (fd);
+ return (fd);
}
/*
- * smgrclose() -- Close a relation.
+ * smgrclose() -- Close a relation.
*
- * NOTE: mdclose frees fd vector! It may be re-used for other relation!
- * reln should be flushed from cache after closing !..
- * Currently, smgrclose is calling by
- * relcache.c:RelationPurgeLocalRelation() only.
- * It would be nice to have smgrfree(), but because of
- * smgrclose is called from single place... - vadim 05/22/97
+ * NOTE: mdclose frees fd vector! It may be re-used for other relation!
+ * reln should be flushed from cache after closing !..
+ * Currently, smgrclose is calling by
+ * relcache.c:RelationPurgeLocalRelation() only.
+ * It would be nice to have smgrfree(), but because of
+ * smgrclose is called from single place... - vadim 05/22/97
*
- * Returns SM_SUCCESS on success, aborts on failure.
+ * Returns SM_SUCCESS on success, aborts on failure.
*/
int
smgrclose(int16 which, Relation reln)
{
- if ((*(smgrsw[which].smgr_close))(reln) == SM_FAIL)
- elog(WARN, "cannot close %s",
- &(reln->rd_rel->relname.data[0]));
+ if ((*(smgrsw[which].smgr_close)) (reln) == SM_FAIL)
+ elog(WARN, "cannot close %s",
+ &(reln->rd_rel->relname.data[0]));
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
/*
- * smgrread() -- read a particular block from a relation into the supplied
- * buffer.
+ * smgrread() -- read a particular block from a relation into the supplied
+ * buffer.
*
- * This routine is called from the buffer manager in order to
- * instantiate pages in the shared buffer cache. All storage managers
- * return pages in the format that POSTGRES expects. This routine
- * dispatches the read. On success, it returns SM_SUCCESS. On failure,
- * the current transaction is aborted.
+ * This routine is called from the buffer manager in order to
+ * instantiate pages in the shared buffer cache. All storage managers
+ * return pages in the format that POSTGRES expects. This routine
+ * dispatches the read. On success, it returns SM_SUCCESS. On failure,
+ * the current transaction is aborted.
*/
int
smgrread(int16 which, Relation reln, BlockNumber blocknum, char *buffer)
{
- int status;
+ int status;
- status = (*(smgrsw[which].smgr_read))(reln, blocknum, buffer);
+ status = (*(smgrsw[which].smgr_read)) (reln, blocknum, buffer);
- if (status == SM_FAIL)
- elog(WARN, "cannot read block %d of %s",
- blocknum, &(reln->rd_rel->relname.data[0]));
+ if (status == SM_FAIL)
+ elog(WARN, "cannot read block %d of %s",
+ blocknum, &(reln->rd_rel->relname.data[0]));
- return (status);
+ return (status);
}
/*
- * smgrwrite() -- Write the supplied buffer out.
+ * smgrwrite() -- Write the supplied buffer out.
*
- * This is not a synchronous write -- the interface for that is
- * smgrflush(). The buffer is written out via the appropriate
- * storage manager. This routine returns SM_SUCCESS or aborts
- * the current transaction.
+ * This is not a synchronous write -- the interface for that is
+ * smgrflush(). The buffer is written out via the appropriate
+ * storage manager. This routine returns SM_SUCCESS or aborts
+ * the current transaction.
*/
int
smgrwrite(int16 which, Relation reln, BlockNumber blocknum, char *buffer)
{
- int status;
+ int status;
- status = (*(smgrsw[which].smgr_write))(reln, blocknum, buffer);
+ status = (*(smgrsw[which].smgr_write)) (reln, blocknum, buffer);
- if (status == SM_FAIL)
- elog(WARN, "cannot write block %d of %s",
- blocknum, &(reln->rd_rel->relname.data[0]));
+ if (status == SM_FAIL)
+ elog(WARN, "cannot write block %d of %s",
+ blocknum, &(reln->rd_rel->relname.data[0]));
- return (status);
+ return (status);
}
/*
- * smgrflush() -- A synchronous smgrwrite().
+ * smgrflush() -- A synchronous smgrwrite().
*/
int
smgrflush(int16 which, Relation reln, BlockNumber blocknum, char *buffer)
{
- int status;
+ int status;
- status = (*(smgrsw[which].smgr_flush))(reln, blocknum, buffer);
+ status = (*(smgrsw[which].smgr_flush)) (reln, blocknum, buffer);
- if (status == SM_FAIL)
- elog(WARN, "cannot flush block %d of %s to stable store",
- blocknum, &(reln->rd_rel->relname.data[0]));
+ if (status == SM_FAIL)
+ elog(WARN, "cannot flush block %d of %s to stable store",
+ blocknum, &(reln->rd_rel->relname.data[0]));
- return (status);
+ return (status);
}
/*
- * smgrblindwrt() -- Write a page out blind.
+ * smgrblindwrt() -- Write a page out blind.
*
- * In some cases, we may find a page in the buffer cache that we
- * can't make a reldesc for. This happens, for example, when we
- * want to reuse a dirty page that was written by a transaction
- * that has not yet committed, which created a new relation. In
- * this case, the buffer manager will call smgrblindwrt() with
- * the name and OID of the database and the relation to which the
- * buffer belongs. Every storage manager must be able to force
- * this page down to stable storage in this circumstance.
+ * In some cases, we may find a page in the buffer cache that we
+ * can't make a reldesc for. This happens, for example, when we
+ * want to reuse a dirty page that was written by a transaction
+ * that has not yet committed, which created a new relation. In
+ * this case, the buffer manager will call smgrblindwrt() with
+ * the name and OID of the database and the relation to which the
+ * buffer belongs. Every storage manager must be able to force
+ * this page down to stable storage in this circumstance.
*/
int
smgrblindwrt(int16 which,
- char *dbname,
- char *relname,
- Oid dbid,
- Oid relid,
- BlockNumber blkno,
- char *buffer)
+ char *dbname,
+ char *relname,
+ Oid dbid,
+ Oid relid,
+ BlockNumber blkno,
+ char *buffer)
{
- char *dbstr;
- char *relstr;
- int status;
+ char *dbstr;
+ char *relstr;
+ int status;
- dbstr = pstrdup(dbname);
- relstr = pstrdup(relname);
+ dbstr = pstrdup(dbname);
+ relstr = pstrdup(relname);
- status = (*(smgrsw[which].smgr_blindwrt))(dbstr, relstr, dbid, relid,
- blkno, buffer);
+ status = (*(smgrsw[which].smgr_blindwrt)) (dbstr, relstr, dbid, relid,
+ blkno, buffer);
- if (status == SM_FAIL)
- elog(WARN, "cannot write block %d of %s [%s] blind",
- blkno, relstr, dbstr);
+ if (status == SM_FAIL)
+ elog(WARN, "cannot write block %d of %s [%s] blind",
+ blkno, relstr, dbstr);
- pfree(dbstr);
- pfree(relstr);
+ pfree(dbstr);
+ pfree(relstr);
- return (status);
+ return (status);
}
/*
- * smgrnblocks() -- Calculate the number of POSTGRES blocks in the
- * supplied relation.
+ * smgrnblocks() -- Calculate the number of POSTGRES blocks in the
+ * supplied relation.
*
- * Returns the number of blocks on success, aborts the current
- * transaction on failure.
+ * Returns the number of blocks on success, aborts the current
+ * transaction on failure.
*/
int
smgrnblocks(int16 which, Relation reln)
{
- int nblocks;
+ int nblocks;
- if ((nblocks = (*(smgrsw[which].smgr_nblocks))(reln)) < 0)
- elog(WARN, "cannot count blocks for %s",
- &(reln->rd_rel->relname.data[0]));
+ if ((nblocks = (*(smgrsw[which].smgr_nblocks)) (reln)) < 0)
+ elog(WARN, "cannot count blocks for %s",
+ &(reln->rd_rel->relname.data[0]));
- return (nblocks);
+ return (nblocks);
}
/*
- * smgrtruncate() -- Truncate supplied relation to a specified number
- * of blocks
+ * smgrtruncate() -- Truncate supplied relation to a specified number
+ * of blocks
*
- * Returns the number of blocks on success, aborts the current
- * transaction on failure.
+ * Returns the number of blocks on success, aborts the current
+ * transaction on failure.
*/
int
smgrtruncate(int16 which, Relation reln, int nblocks)
{
- int newblks;
-
- newblks = nblocks;
- if (smgrsw[which].smgr_truncate)
- {
- if ((newblks = (*(smgrsw[which].smgr_truncate))(reln, nblocks)) < 0)
- elog(WARN, "cannot truncate %s to %d blocks",
- &(reln->rd_rel->relname.data[0]), nblocks);
- }
-
- return (newblks);
+ int newblks;
+
+ newblks = nblocks;
+ if (smgrsw[which].smgr_truncate)
+ {
+ if ((newblks = (*(smgrsw[which].smgr_truncate)) (reln, nblocks)) < 0)
+ elog(WARN, "cannot truncate %s to %d blocks",
+ &(reln->rd_rel->relname.data[0]), nblocks);
+ }
+
+ return (newblks);
}
/*
- * smgrcommit(), smgrabort() -- Commit or abort changes made during the
- * current transaction.
+ * smgrcommit(), smgrabort() -- Commit or abort changes made during the
+ * current transaction.
*/
int
smgrcommit()
{
- int i;
-
- for (i = 0; i < NSmgr; i++) {
- if (smgrsw[i].smgr_commit) {
- if ((*(smgrsw[i].smgr_commit))() == SM_FAIL)
- elog(FATAL, "transaction commit failed on %s", smgrout(i));
+ int i;
+
+ for (i = 0; i < NSmgr; i++)
+ {
+ if (smgrsw[i].smgr_commit)
+ {
+ if ((*(smgrsw[i].smgr_commit)) () == SM_FAIL)
+ elog(FATAL, "transaction commit failed on %s", smgrout(i));
+ }
}
- }
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
#ifdef NOT_USED
int
smgrabort()
{
- int i;
-
- for (i = 0; i < NSmgr; i++) {
- if (smgrsw[i].smgr_abort) {
- if ((*(smgrsw[i].smgr_abort))() == SM_FAIL)
- elog(FATAL, "transaction abort failed on %s", smgrout(i));
+ int i;
+
+ for (i = 0; i < NSmgr; i++)
+ {
+ if (smgrsw[i].smgr_abort)
+ {
+ if ((*(smgrsw[i].smgr_abort)) () == SM_FAIL)
+ elog(FATAL, "transaction abort failed on %s", smgrout(i));
+ }
}
- }
- return (SM_SUCCESS);
+ return (SM_SUCCESS);
}
+
#endif
bool
smgriswo(int16 smgrno)
{
- if (smgrno < 0 || smgrno >= NSmgr)
- elog(WARN, "illegal storage manager number %d", smgrno);
+ if (smgrno < 0 || smgrno >= NSmgr)
+ elog(WARN, "illegal storage manager number %d", smgrno);
- return (smgrwo[smgrno]);
+ return (smgrwo[smgrno]);
}
diff --git a/src/backend/storage/smgr/smgrtype.c b/src/backend/storage/smgr/smgrtype.c
index cb32d458b82..64fb53c9c2e 100644
--- a/src/backend/storage/smgr/smgrtype.c
+++ b/src/backend/storage/smgr/smgrtype.c
@@ -1,81 +1,83 @@
/*-------------------------------------------------------------------------
*
* smgrtype.c--
- * storage manager type
+ * storage manager type
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgrtype.c,v 1.2 1996/11/03 05:08:01 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgrtype.c,v 1.3 1997/09/07 04:49:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <string.h>
#include "postgres.h"
-#include "utils/builtins.h" /* where the declarations go */
+#include "utils/builtins.h" /* where the declarations go */
#include "utils/palloc.h"
#include "storage/smgr.h"
-typedef struct smgrid {
- char *smgr_name;
-} smgrid;
+typedef struct smgrid
+{
+ char *smgr_name;
+} smgrid;
/*
- * StorageManager[] -- List of defined storage managers.
+ * StorageManager[] -- List of defined storage managers.
*
- * The weird comma placement is to keep compilers happy no matter
- * which of these is (or is not) defined.
+ * The weird comma placement is to keep compilers happy no matter
+ * which of these is (or is not) defined.
*/
-static smgrid StorageManager[] = {
+static smgrid StorageManager[] = {
{"magnetic disk"},
#ifdef MAIN_MEMORY
{"main memory"}
-#endif /* MAIN_MEMORY */
+#endif /* MAIN_MEMORY */
};
-static int NStorageManagers = lengthof(StorageManager);
+static int NStorageManagers = lengthof(StorageManager);
int2
smgrin(char *s)
{
- int i;
+ int i;
- for (i = 0; i < NStorageManagers; i++) {
- if (strcmp(s, StorageManager[i].smgr_name) == 0)
- return((int2) i);
- }
- elog(WARN, "smgrin: illegal storage manager name %s", s);
- return 0;
+ for (i = 0; i < NStorageManagers; i++)
+ {
+ if (strcmp(s, StorageManager[i].smgr_name) == 0)
+ return ((int2) i);
+ }
+ elog(WARN, "smgrin: illegal storage manager name %s", s);
+ return 0;
}
-char *
+char *
smgrout(int2 i)
{
- char *s;
+ char *s;
- if (i >= NStorageManagers || i < 0)
- elog(WARN, "Illegal storage manager id %d", i);
+ if (i >= NStorageManagers || i < 0)
+ elog(WARN, "Illegal storage manager id %d", i);
- s = (char *) palloc(strlen(StorageManager[i].smgr_name) + 1);
- strcpy(s, StorageManager[i].smgr_name);
- return (s);
+ s = (char *) palloc(strlen(StorageManager[i].smgr_name) + 1);
+ strcpy(s, StorageManager[i].smgr_name);
+ return (s);
}
bool
smgreq(int2 a, int2 b)
{
- if (a == b)
- return (true);
- return (false);
+ if (a == b)
+ return (true);
+ return (false);
}
bool
smgrne(int2 a, int2 b)
{
- if (a == b)
- return (false);
- return (true);
+ if (a == b)
+ return (false);
+ return (true);
}
diff --git a/src/backend/tcop/aclchk.c b/src/backend/tcop/aclchk.c
index fade9d09826..db6932586b7 100644
--- a/src/backend/tcop/aclchk.c
+++ b/src/backend/tcop/aclchk.c
@@ -1,23 +1,23 @@
/*-------------------------------------------------------------------------
*
* aclchk.c--
- * Routines to check access control permissions.
+ * Routines to check access control permissions.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/Attic/aclchk.c,v 1.13 1997/08/19 21:33:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/Attic/aclchk.c,v 1.14 1997/09/07 04:49:28 momjian Exp $
*
* NOTES
- * See acl.h.
+ * See acl.h.
*
*-------------------------------------------------------------------------
*/
#include <string.h>
#include "postgres.h"
-#include "utils/acl.h" /* where declarations for this file go */
+#include "utils/acl.h" /* where declarations for this file go */
#include "access/heapam.h"
#include "access/htup.h"
#include "access/tupmacs.h"
@@ -36,7 +36,7 @@
#include "parser/catalog_utils.h"
#include "fmgr.h"
-static int32 aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode);
+static int32 aclcheck(Acl * acl, AclId id, AclIdType idtype, AclMode mode);
/*
* Enable use of user relations in place of real system catalogs.
@@ -49,209 +49,226 @@ static int32 aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode);
* relname and relowner are in the same place, happily.
*/
#undef Anum_pg_class_relacl
-#define Anum_pg_class_relacl 3
+#define Anum_pg_class_relacl 3
#undef Natts_pg_class
-#define Natts_pg_class 3
+#define Natts_pg_class 3
#undef Name_pg_class
-#define Name_pg_class "pgacls"
+#define Name_pg_class "pgacls"
#undef Name_pg_group
-#define Name_pg_group "pggroup"
+#define Name_pg_group "pggroup"
#endif
/* warning messages, now more explicit. */
/* should correspond to the order of the ACLCHK_* result codes above. */
-char *aclcheck_error_strings[] = {
- "No error.",
- "Permission denied.",
- "Table does not exist.",
- "Must be table owner."
+char *aclcheck_error_strings[] = {
+ "No error.",
+ "Permission denied.",
+ "Table does not exist.",
+ "Must be table owner."
};
#ifdef ACLDEBUG_TRACE
static
-dumpacl(Acl *acl)
+dumpacl(Acl * acl)
{
- register unsigned i;
- AclItem *aip;
-
- elog(DEBUG, "acl size = %d, # acls = %d",
- ACL_SIZE(acl), ACL_NUM(acl));
- aip = (AclItem *) ACL_DAT(acl);
- for (i = 0; i < ACL_NUM(acl); ++i)
- elog(DEBUG, " acl[%d]: %s", i, aclitemout(aip + i));
+ register unsigned i;
+ AclItem *aip;
+
+ elog(DEBUG, "acl size = %d, # acls = %d",
+ ACL_SIZE(acl), ACL_NUM(acl));
+ aip = (AclItem *) ACL_DAT(acl);
+ for (i = 0; i < ACL_NUM(acl); ++i)
+ elog(DEBUG, " acl[%d]: %s", i, aclitemout(aip + i));
}
+
#endif
/*
- *
+ *
*/
void
-ChangeAcl(char *relname,
- AclItem *mod_aip,
- unsigned modechg)
+ChangeAcl(char *relname,
+ AclItem * mod_aip,
+ unsigned modechg)
{
- register unsigned i;
- Acl *old_acl = (Acl *) NULL, *new_acl;
- Relation relation;
- static ScanKeyData relkey[1] = {
- { 0, Anum_pg_class_relname, NameEqualRegProcedure }
- };
- HeapScanDesc hsdp;
- HeapTuple htp;
- Buffer buffer;
- Datum values[Natts_pg_class];
- char nulls[Natts_pg_class];
- char replaces[Natts_pg_class];
- ItemPointerData tmp_ipd;
- Relation idescs[Num_pg_class_indices];
- int free_old_acl = 0;
-
- /*
- * Find the pg_class tuple matching 'relname' and extract the ACL.
- * If there's no ACL, create a default using the pg_class.relowner
- * field.
- *
- * We can't use the syscache here, since we need to do a heap_replace
- * on the tuple we find. Feh.
- */
- relation = heap_openr(RelationRelationName);
- if (!RelationIsValid(relation))
- elog(WARN, "ChangeAcl: could not open '%s'??",
- RelationRelationName);
- fmgr_info(NameEqualRegProcedure, &relkey[0].sk_func, &relkey[0].sk_nargs);
- relkey[0].sk_argument = NameGetDatum(relname);
- hsdp = heap_beginscan(relation,
- 0,
- NowTimeQual,
- (unsigned) 1,
- relkey);
- htp = heap_getnext(hsdp, 0, &buffer);
- if (!HeapTupleIsValid(htp)) {
- heap_endscan(hsdp);
- heap_close(relation);
- elog(WARN, "ChangeAcl: class \"%s\" not found",
- relname);
- return;
- }
- if (!heap_attisnull(htp, Anum_pg_class_relacl))
- old_acl = (Acl *) heap_getattr(htp, buffer,
- Anum_pg_class_relacl,
- RelationGetTupleDescriptor(relation),
- (bool *) NULL);
- if (!old_acl || ACL_NUM(old_acl) < 1) {
+ register unsigned i;
+ Acl *old_acl = (Acl *) NULL,
+ *new_acl;
+ Relation relation;
+ static ScanKeyData relkey[1] = {
+ {0, Anum_pg_class_relname, NameEqualRegProcedure}
+ };
+ HeapScanDesc hsdp;
+ HeapTuple htp;
+ Buffer buffer;
+ Datum values[Natts_pg_class];
+ char nulls[Natts_pg_class];
+ char replaces[Natts_pg_class];
+ ItemPointerData tmp_ipd;
+ Relation idescs[Num_pg_class_indices];
+ int free_old_acl = 0;
+
+ /*
+ * Find the pg_class tuple matching 'relname' and extract the ACL. If
+ * there's no ACL, create a default using the pg_class.relowner field.
+ *
+ * We can't use the syscache here, since we need to do a heap_replace on
+ * the tuple we find. Feh.
+ */
+ relation = heap_openr(RelationRelationName);
+ if (!RelationIsValid(relation))
+ elog(WARN, "ChangeAcl: could not open '%s'??",
+ RelationRelationName);
+ fmgr_info(NameEqualRegProcedure, &relkey[0].sk_func, &relkey[0].sk_nargs);
+ relkey[0].sk_argument = NameGetDatum(relname);
+ hsdp = heap_beginscan(relation,
+ 0,
+ NowTimeQual,
+ (unsigned) 1,
+ relkey);
+ htp = heap_getnext(hsdp, 0, &buffer);
+ if (!HeapTupleIsValid(htp))
+ {
+ heap_endscan(hsdp);
+ heap_close(relation);
+ elog(WARN, "ChangeAcl: class \"%s\" not found",
+ relname);
+ return;
+ }
+ if (!heap_attisnull(htp, Anum_pg_class_relacl))
+ old_acl = (Acl *) heap_getattr(htp, buffer,
+ Anum_pg_class_relacl,
+ RelationGetTupleDescriptor(relation),
+ (bool *) NULL);
+ if (!old_acl || ACL_NUM(old_acl) < 1)
+ {
#ifdef ACLDEBUG_TRACE
- elog(DEBUG, "ChangeAcl: using default ACL");
+ elog(DEBUG, "ChangeAcl: using default ACL");
#endif
-/* old_acl = acldefault(((Form_pg_class) GETSTRUCT(htp))->relowner); */
- old_acl = acldefault();
- free_old_acl = 1;
- }
+/* old_acl = acldefault(((Form_pg_class) GETSTRUCT(htp))->relowner); */
+ old_acl = acldefault();
+ free_old_acl = 1;
+ }
#ifdef ACLDEBUG_TRACE
- dumpacl(old_acl);
+ dumpacl(old_acl);
#endif
- new_acl = aclinsert3(old_acl, mod_aip, modechg);
+ new_acl = aclinsert3(old_acl, mod_aip, modechg);
#ifdef ACLDEBUG_TRACE
- dumpacl(new_acl);
+ dumpacl(new_acl);
#endif
- for (i = 0; i < Natts_pg_class; ++i) {
- replaces[i] = ' ';
- nulls[i] = ' '; /* ignored if replaces[i] == ' ' anyway */
- values[i] = (Datum)NULL;/* ignored if replaces[i] == ' ' anyway */
- }
- replaces[Anum_pg_class_relacl - 1] = 'r';
- values[Anum_pg_class_relacl - 1] = (Datum)new_acl;
- htp = heap_modifytuple(htp, buffer, relation, values, nulls, replaces);
- /* XXX is this necessary? */
- ItemPointerCopy(&htp->t_ctid, &tmp_ipd);
- /* XXX handle index on pg_class? */
- setheapoverride(true);
- heap_replace(relation, &tmp_ipd, htp);
- setheapoverride(false);
- heap_endscan(hsdp);
-
- /* keep the catalog indices up to date */
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices,
- idescs);
- CatalogIndexInsert(idescs, Num_pg_class_indices, relation, htp);
- CatalogCloseIndices(Num_pg_class_indices, idescs);
-
- heap_close(relation);
- if (free_old_acl)
- pfree(old_acl);
- pfree(new_acl);
+ for (i = 0; i < Natts_pg_class; ++i)
+ {
+ replaces[i] = ' ';
+ nulls[i] = ' '; /* ignored if replaces[i] == ' ' anyway */
+ values[i] = (Datum) NULL; /* ignored if replaces[i] == ' '
+ * anyway */
+ }
+ replaces[Anum_pg_class_relacl - 1] = 'r';
+ values[Anum_pg_class_relacl - 1] = (Datum) new_acl;
+ htp = heap_modifytuple(htp, buffer, relation, values, nulls, replaces);
+ /* XXX is this necessary? */
+ ItemPointerCopy(&htp->t_ctid, &tmp_ipd);
+ /* XXX handle index on pg_class? */
+ setheapoverride(true);
+ heap_replace(relation, &tmp_ipd, htp);
+ setheapoverride(false);
+ heap_endscan(hsdp);
+
+ /* keep the catalog indices up to date */
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices,
+ idescs);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, relation, htp);
+ CatalogCloseIndices(Num_pg_class_indices, idescs);
+
+ heap_close(relation);
+ if (free_old_acl)
+ pfree(old_acl);
+ pfree(new_acl);
}
AclId
get_grosysid(char *groname)
{
- HeapTuple htp;
- AclId id = 0;
-
- htp = SearchSysCacheTuple(GRONAME, PointerGetDatum(groname),
- 0,0,0);
- if (HeapTupleIsValid(htp)) {
- id = ((Form_pg_group) GETSTRUCT(htp))->grosysid;
- } else {
- elog(WARN, "non-existent group \"%s\"", groname);
- }
- return(id);
+ HeapTuple htp;
+ AclId id = 0;
+
+ htp = SearchSysCacheTuple(GRONAME, PointerGetDatum(groname),
+ 0, 0, 0);
+ if (HeapTupleIsValid(htp))
+ {
+ id = ((Form_pg_group) GETSTRUCT(htp))->grosysid;
+ }
+ else
+ {
+ elog(WARN, "non-existent group \"%s\"", groname);
+ }
+ return (id);
}
-char*
+char *
get_groname(AclId grosysid)
{
- HeapTuple htp;
- char *name = NULL;
-
- htp = SearchSysCacheTuple(GROSYSID, PointerGetDatum(grosysid),
- 0,0,0);
- if (HeapTupleIsValid(htp)) {
- name = (((Form_pg_group) GETSTRUCT(htp))->groname).data;
- } else {
- elog(NOTICE, "get_groname: group %d not found", grosysid);
- }
- return(name);
+ HeapTuple htp;
+ char *name = NULL;
+
+ htp = SearchSysCacheTuple(GROSYSID, PointerGetDatum(grosysid),
+ 0, 0, 0);
+ if (HeapTupleIsValid(htp))
+ {
+ name = (((Form_pg_group) GETSTRUCT(htp))->groname).data;
+ }
+ else
+ {
+ elog(NOTICE, "get_groname: group %d not found", grosysid);
+ }
+ return (name);
}
-static int32
+static int32
in_group(AclId uid, AclId gid)
{
- Relation relation;
- HeapTuple htp;
- Acl *tmp;
- unsigned i, num;
- AclId *aidp;
- int32 found = 0;
+ Relation relation;
+ HeapTuple htp;
+ Acl *tmp;
+ unsigned i,
+ num;
+ AclId *aidp;
+ int32 found = 0;
relation = heap_openr(GroupRelationName);
- if (!RelationIsValid(relation)) {
+ if (!RelationIsValid(relation))
+ {
elog(NOTICE, "in_group: could not open \"%s\"??",
- GroupRelationName);
- return(0);
+ GroupRelationName);
+ return (0);
}
htp = SearchSysCacheTuple(GROSYSID, ObjectIdGetDatum(gid),
- 0,0,0);
+ 0, 0, 0);
if (HeapTupleIsValid(htp) &&
- !heap_attisnull(htp, Anum_pg_group_grolist)) {
+ !heap_attisnull(htp, Anum_pg_group_grolist))
+ {
tmp = (IdList *) heap_getattr(htp, InvalidBuffer,
- Anum_pg_group_grolist,
- RelationGetTupleDescriptor(relation),
- (bool *) NULL);
+ Anum_pg_group_grolist,
+ RelationGetTupleDescriptor(relation),
+ (bool *) NULL);
/* XXX make me a function */
num = IDLIST_NUM(tmp);
aidp = IDLIST_DAT(tmp);
for (i = 0; i < num; ++i)
- if (aidp[i] == uid) {
+ if (aidp[i] == uid)
+ {
found = 1;
break;
}
- } else {
+ }
+ else
+ {
elog(NOTICE, "in_group: group %d not found", gid);
}
heap_close(relation);
- return(found);
+ return (found);
}
/*
@@ -259,348 +276,387 @@ in_group(AclId uid, AclId gid)
* Returns 1 if the 'id' of type 'idtype' has ACL entries in 'acl' to satisfy
* any one of the requirements of 'mode'. Returns 0 otherwise.
*/
-static int32
-aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
+static int32
+aclcheck(Acl * acl, AclId id, AclIdType idtype, AclMode mode)
{
- register unsigned i;
- register AclItem *aip, *aidat;
- unsigned num, found_group;
-
- /* if no acl is found, use world default */
- if (!acl) {
- acl = acldefault();
- }
-
- num = ACL_NUM(acl);
- aidat = ACL_DAT(acl);
-
- /*
- * We'll treat the empty ACL like that, too, although this is more
- * like an error (i.e., you manually blew away your ACL array) --
- * the system never creates an empty ACL.
- */
- if (num < 1) {
+ register unsigned i;
+ register AclItem *aip,
+ *aidat;
+ unsigned num,
+ found_group;
+
+ /* if no acl is found, use world default */
+ if (!acl)
+ {
+ acl = acldefault();
+ }
+
+ num = ACL_NUM(acl);
+ aidat = ACL_DAT(acl);
+
+ /*
+ * We'll treat the empty ACL like that, too, although this is more
+ * like an error (i.e., you manually blew away your ACL array) -- the
+ * system never creates an empty ACL.
+ */
+ if (num < 1)
+ {
#if ACLDEBUG_TRACE || 1
- elog(DEBUG, "aclcheck: zero-length ACL, returning 1");
+ elog(DEBUG, "aclcheck: zero-length ACL, returning 1");
#endif
- return ACLCHECK_OK;
- }
-
- switch (idtype) {
- case ACL_IDTYPE_UID:
- for (i = 1, aip = aidat + 1; /* skip world entry */
- i < num && aip->ai_idtype == ACL_IDTYPE_UID;
- ++i, ++aip) {
- if (aip->ai_id == id) {
+ return ACLCHECK_OK;
+ }
+
+ switch (idtype)
+ {
+ case ACL_IDTYPE_UID:
+ for (i = 1, aip = aidat + 1; /* skip world entry */
+ i < num && aip->ai_idtype == ACL_IDTYPE_UID;
+ ++i, ++aip)
+ {
+ if (aip->ai_id == id)
+ {
#ifdef ACLDEBUG_TRACE
- elog(DEBUG, "aclcheck: found %d/%d",
- aip->ai_id, aip->ai_mode);
+ elog(DEBUG, "aclcheck: found %d/%d",
+ aip->ai_id, aip->ai_mode);
#endif
- return((aip->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
- }
- }
- for (found_group = 0;
- i < num && aip->ai_idtype == ACL_IDTYPE_GID;
- ++i, ++aip) {
- if (in_group(id, aip->ai_id)) {
- if (aip->ai_mode & mode) {
- found_group = 1;
- break;
+ return ((aip->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
+ }
}
- }
- }
- if (found_group) {
+ for (found_group = 0;
+ i < num && aip->ai_idtype == ACL_IDTYPE_GID;
+ ++i, ++aip)
+ {
+ if (in_group(id, aip->ai_id))
+ {
+ if (aip->ai_mode & mode)
+ {
+ found_group = 1;
+ break;
+ }
+ }
+ }
+ if (found_group)
+ {
#ifdef ACLDEBUG_TRACE
- elog(DEBUG,"aclcheck: all groups ok");
+ elog(DEBUG, "aclcheck: all groups ok");
#endif
- return ACLCHECK_OK;
- }
- break;
- case ACL_IDTYPE_GID:
- for (i = 1, aip = aidat + 1; /* skip world entry and UIDs */
- i < num && aip->ai_idtype == ACL_IDTYPE_UID;
- ++i, ++aip)
- ;
- for (;
- i < num && aip->ai_idtype == ACL_IDTYPE_GID;
- ++i, ++aip) {
- if (aip->ai_id == id) {
+ return ACLCHECK_OK;
+ }
+ break;
+ case ACL_IDTYPE_GID:
+ for (i = 1, aip = aidat + 1; /* skip world entry and UIDs */
+ i < num && aip->ai_idtype == ACL_IDTYPE_UID;
+ ++i, ++aip)
+ ;
+ for (;
+ i < num && aip->ai_idtype == ACL_IDTYPE_GID;
+ ++i, ++aip)
+ {
+ if (aip->ai_id == id)
+ {
#ifdef ACLDEBUG_TRACE
- elog(DEBUG, "aclcheck: found %d/%d",
- aip->ai_id, aip->ai_mode);
+ elog(DEBUG, "aclcheck: found %d/%d",
+ aip->ai_id, aip->ai_mode);
#endif
- return((aip->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
- }
+ return ((aip->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
+ }
+ }
+ break;
+ case ACL_IDTYPE_WORLD:
+ break;
+ default:
+ elog(WARN, "aclcheck: bogus ACL id type: %d", idtype);
+ break;
}
- break;
- case ACL_IDTYPE_WORLD:
- break;
- default:
- elog(WARN, "aclcheck: bogus ACL id type: %d", idtype);
- break;
- }
-
+
#ifdef ACLDEBUG_TRACE
- elog(DEBUG, "aclcheck: using world=%d", aidat->ai_mode);
+ elog(DEBUG, "aclcheck: using world=%d", aidat->ai_mode);
#endif
- return((aidat->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
+ return ((aidat->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
}
int32
pg_aclcheck(char *relname, char *usename, AclMode mode)
{
- HeapTuple htp;
- AclId id;
- Acl *acl = (Acl *) NULL, *tmp;
- int32 result;
- Relation relation;
-
- htp = SearchSysCacheTuple(USENAME, PointerGetDatum(usename),
- 0,0,0);
- if (!HeapTupleIsValid(htp))
- elog(WARN, "pg_aclcheck: user \"%s\" not found",
- usename);
- id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid;
-
- /* for the 'pg_database' relation, check the usecreatedb
- field before checking normal permissions */
- if ( strcmp(DatabaseRelationName, relname) == 0 &&
- (((Form_pg_user) GETSTRUCT(htp))->usecreatedb)) {
- /* note that even though the user can now append to the
- pg_database table, there is still additional permissions checking
- in dbcommands.c */
- if (mode & ACL_AP)
- return ACLCHECK_OK;
- }
-
- /*
- * Deny anyone permission to update a system catalog unless
- * pg_user.usecatupd is set. (This is to let superusers protect
- * themselves from themselves.)
- */
- if (((mode & ACL_WR) || (mode & ACL_AP)) &&
- IsSystemRelationName(relname) &&
- !((Form_pg_user) GETSTRUCT(htp))->usecatupd) {
- elog(DEBUG, "pg_aclcheck: catalog update to \"%s\": permission denied",
- relname);
- return ACLCHECK_NO_PRIV;
- }
-
- /*
- * Otherwise, superusers bypass all permission-checking.
- */
- if (((Form_pg_user) GETSTRUCT(htp))->usesuper) {
+ HeapTuple htp;
+ AclId id;
+ Acl *acl = (Acl *) NULL,
+ *tmp;
+ int32 result;
+ Relation relation;
+
+ htp = SearchSysCacheTuple(USENAME, PointerGetDatum(usename),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "pg_aclcheck: user \"%s\" not found",
+ usename);
+ id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid;
+
+ /*
+ * for the 'pg_database' relation, check the usecreatedb field before
+ * checking normal permissions
+ */
+ if (strcmp(DatabaseRelationName, relname) == 0 &&
+ (((Form_pg_user) GETSTRUCT(htp))->usecreatedb))
+ {
+
+ /*
+ * note that even though the user can now append to the
+ * pg_database table, there is still additional permissions
+ * checking in dbcommands.c
+ */
+ if (mode & ACL_AP)
+ return ACLCHECK_OK;
+ }
+
+ /*
+ * Deny anyone permission to update a system catalog unless
+ * pg_user.usecatupd is set. (This is to let superusers protect
+ * themselves from themselves.)
+ */
+ if (((mode & ACL_WR) || (mode & ACL_AP)) &&
+ IsSystemRelationName(relname) &&
+ !((Form_pg_user) GETSTRUCT(htp))->usecatupd)
+ {
+ elog(DEBUG, "pg_aclcheck: catalog update to \"%s\": permission denied",
+ relname);
+ return ACLCHECK_NO_PRIV;
+ }
+
+ /*
+ * Otherwise, superusers bypass all permission-checking.
+ */
+ if (((Form_pg_user) GETSTRUCT(htp))->usesuper)
+ {
#ifdef ACLDEBUG_TRACE
- elog(DEBUG, "pg_aclcheck: \"%s\" is superuser",
- usename);
+ elog(DEBUG, "pg_aclcheck: \"%s\" is superuser",
+ usename);
#endif
- return ACLCHECK_OK;
- }
-
-#ifndef ACLDEBUG
- htp = SearchSysCacheTuple(RELNAME, PointerGetDatum(relname),
- 0,0,0);
- if (!HeapTupleIsValid(htp)) {
- elog(WARN, "pg_aclcheck: class \"%s\" not found",
- relname);
- /* an elog(WARN) kills us, so no need to return anything. */
- }
- if (!heap_attisnull(htp, Anum_pg_class_relacl)) {
- relation = heap_openr(RelationRelationName);
- tmp = (Acl *) heap_getattr(htp, InvalidBuffer,
- Anum_pg_class_relacl,
- RelationGetTupleDescriptor(relation),
- (bool *) NULL);
- acl = makeacl(ACL_NUM(tmp));
- memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
- heap_close(relation);
- } else {
- /* if the acl is null, by default the owner can do whatever
- he wants to with it */
- Oid ownerId;
- relation = heap_openr(RelationRelationName);
- ownerId = (Oid)heap_getattr(htp, InvalidBuffer,
- Anum_pg_class_relowner,
- RelationGetTupleDescriptor(relation),
- (bool*) NULL);
- acl = aclownerdefault(ownerId);
- }
-#else
- { /* This is why the syscache is great... */
- static ScanKeyData relkey[1] = {
- { 0, Anum_pg_class_relname, NameEqualRegProcedure }
- };
- HeapScanDesc hsdp;
+ return ACLCHECK_OK;
+ }
- relation = heap_openr(RelationRelationName);
- if (!RelationIsValid(relation)) {
- elog(NOTICE, "pg_checkacl: could not open \"%-.*s\"??",
- RelationRelationName);
- return ACLCHECK_NO_CLASS;
+#ifndef ACLDEBUG
+ htp = SearchSysCacheTuple(RELNAME, PointerGetDatum(relname),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ {
+ elog(WARN, "pg_aclcheck: class \"%s\" not found",
+ relname);
+ /* an elog(WARN) kills us, so no need to return anything. */
}
- fmgr_info(NameEqualRegProcedure,
- &relkey[0].sk_func,
- &relkey[0].sk_nargs);
- relkey[0].sk_argument = NameGetDatum(relname);
- hsdp = heap_beginscan(relation, 0, NowTimeQual, 1, relkey);
- htp = heap_getnext(hsdp, 0, (Buffer *) 0);
- if (HeapTupleIsValid(htp) &&
- !heap_attisnull(htp, Anum_pg_class_relacl)) {
- tmp = (Acl *) heap_getattr(htp, InvalidBuffer,
- Anum_pg_class_relacl,
- RelationGetTupleDescriptor(relation),
- (bool *) NULL);
- acl = makeacl(ACL_NUM(tmp));
- memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
+ if (!heap_attisnull(htp, Anum_pg_class_relacl))
+ {
+ relation = heap_openr(RelationRelationName);
+ tmp = (Acl *) heap_getattr(htp, InvalidBuffer,
+ Anum_pg_class_relacl,
+ RelationGetTupleDescriptor(relation),
+ (bool *) NULL);
+ acl = makeacl(ACL_NUM(tmp));
+ memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
+ heap_close(relation);
+ }
+ else
+ {
+
+ /*
+ * if the acl is null, by default the owner can do whatever he
+ * wants to with it
+ */
+ Oid ownerId;
+
+ relation = heap_openr(RelationRelationName);
+ ownerId = (Oid) heap_getattr(htp, InvalidBuffer,
+ Anum_pg_class_relowner,
+ RelationGetTupleDescriptor(relation),
+ (bool *) NULL);
+ acl = aclownerdefault(ownerId);
+ }
+#else
+ { /* This is why the syscache is great... */
+ static ScanKeyData relkey[1] = {
+ {0, Anum_pg_class_relname, NameEqualRegProcedure}
+ };
+ HeapScanDesc hsdp;
+
+ relation = heap_openr(RelationRelationName);
+ if (!RelationIsValid(relation))
+ {
+ elog(NOTICE, "pg_checkacl: could not open \"%-.*s\"??",
+ RelationRelationName);
+ return ACLCHECK_NO_CLASS;
+ }
+ fmgr_info(NameEqualRegProcedure,
+ &relkey[0].sk_func,
+ &relkey[0].sk_nargs);
+ relkey[0].sk_argument = NameGetDatum(relname);
+ hsdp = heap_beginscan(relation, 0, NowTimeQual, 1, relkey);
+ htp = heap_getnext(hsdp, 0, (Buffer *) 0);
+ if (HeapTupleIsValid(htp) &&
+ !heap_attisnull(htp, Anum_pg_class_relacl))
+ {
+ tmp = (Acl *) heap_getattr(htp, InvalidBuffer,
+ Anum_pg_class_relacl,
+ RelationGetTupleDescriptor(relation),
+ (bool *) NULL);
+ acl = makeacl(ACL_NUM(tmp));
+ memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
+ }
+ heap_endscan(hsdp);
+ heap_close(relation);
}
- heap_endscan(hsdp);
- heap_close(relation);
- }
#endif
- result = aclcheck(acl, id, (AclIdType) ACL_IDTYPE_UID, mode);
- if (acl)
- pfree(acl);
- return(result);
+ result = aclcheck(acl, id, (AclIdType) ACL_IDTYPE_UID, mode);
+ if (acl)
+ pfree(acl);
+ return (result);
}
int32
pg_ownercheck(char *usename,
- char *value,
- int cacheid)
+ char *value,
+ int cacheid)
{
- HeapTuple htp;
- AclId user_id, owner_id = 0;
-
- htp = SearchSysCacheTuple(USENAME, PointerGetDatum(usename),
- 0,0,0);
- if (!HeapTupleIsValid(htp))
- elog(WARN, "pg_ownercheck: user \"%s\" not found",
- usename);
- user_id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid;
-
- /*
- * Superusers bypass all permission-checking.
- */
- if (((Form_pg_user) GETSTRUCT(htp))->usesuper) {
+ HeapTuple htp;
+ AclId user_id,
+ owner_id = 0;
+
+ htp = SearchSysCacheTuple(USENAME, PointerGetDatum(usename),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "pg_ownercheck: user \"%s\" not found",
+ usename);
+ user_id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid;
+
+ /*
+ * Superusers bypass all permission-checking.
+ */
+ if (((Form_pg_user) GETSTRUCT(htp))->usesuper)
+ {
#ifdef ACLDEBUG_TRACE
- elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser",
- usename);
+ elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser",
+ usename);
#endif
- return(1);
- }
+ return (1);
+ }
- htp = SearchSysCacheTuple(cacheid, PointerGetDatum(value),
- 0,0,0);
- switch (cacheid) {
- case OPROID:
- if (!HeapTupleIsValid(htp))
- elog(WARN, "pg_ownercheck: operator %ld not found",
- PointerGetDatum(value));
- owner_id = ((OperatorTupleForm) GETSTRUCT(htp))->oprowner;
- break;
- case PRONAME:
- if (!HeapTupleIsValid(htp))
- elog(WARN, "pg_ownercheck: function \"%s\" not found",
- value);
- owner_id = ((Form_pg_proc) GETSTRUCT(htp))->proowner;
- break;
- case RELNAME:
- if (!HeapTupleIsValid(htp))
- elog(WARN, "pg_ownercheck: class \"%s\" not found",
- value);
- owner_id = ((Form_pg_class) GETSTRUCT(htp))->relowner;
- break;
- case TYPNAME:
- if (!HeapTupleIsValid(htp))
- elog(WARN, "pg_ownercheck: type \"%s\" not found",
- value);
- owner_id = ((TypeTupleForm) GETSTRUCT(htp))->typowner;
- break;
- default:
- elog(WARN, "pg_ownercheck: invalid cache id: %d",
- cacheid);
- break;
- }
-
- return(user_id == owner_id);
+ htp = SearchSysCacheTuple(cacheid, PointerGetDatum(value),
+ 0, 0, 0);
+ switch (cacheid)
+ {
+ case OPROID:
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "pg_ownercheck: operator %ld not found",
+ PointerGetDatum(value));
+ owner_id = ((OperatorTupleForm) GETSTRUCT(htp))->oprowner;
+ break;
+ case PRONAME:
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "pg_ownercheck: function \"%s\" not found",
+ value);
+ owner_id = ((Form_pg_proc) GETSTRUCT(htp))->proowner;
+ break;
+ case RELNAME:
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "pg_ownercheck: class \"%s\" not found",
+ value);
+ owner_id = ((Form_pg_class) GETSTRUCT(htp))->relowner;
+ break;
+ case TYPNAME:
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "pg_ownercheck: type \"%s\" not found",
+ value);
+ owner_id = ((TypeTupleForm) GETSTRUCT(htp))->typowner;
+ break;
+ default:
+ elog(WARN, "pg_ownercheck: invalid cache id: %d",
+ cacheid);
+ break;
+ }
+
+ return (user_id == owner_id);
}
int32
-pg_func_ownercheck(char *usename,
- char *funcname,
- int nargs,
- Oid *arglist)
+pg_func_ownercheck(char *usename,
+ char *funcname,
+ int nargs,
+ Oid * arglist)
{
- HeapTuple htp;
- AclId user_id, owner_id;
-
- htp = SearchSysCacheTuple(USENAME, PointerGetDatum(usename),
- 0,0,0);
- if (!HeapTupleIsValid(htp))
- elog(WARN, "pg_func_ownercheck: user \"%s\" not found",
- usename);
- user_id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid;
-
- /*
- * Superusers bypass all permission-checking.
- */
- if (((Form_pg_user) GETSTRUCT(htp))->usesuper) {
+ HeapTuple htp;
+ AclId user_id,
+ owner_id;
+
+ htp = SearchSysCacheTuple(USENAME, PointerGetDatum(usename),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "pg_func_ownercheck: user \"%s\" not found",
+ usename);
+ user_id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid;
+
+ /*
+ * Superusers bypass all permission-checking.
+ */
+ if (((Form_pg_user) GETSTRUCT(htp))->usesuper)
+ {
#ifdef ACLDEBUG_TRACE
- elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser",
- usename);
+ elog(DEBUG, "pg_ownercheck: user \"%s\" is superuser",
+ usename);
#endif
- return(1);
- }
-
- htp = SearchSysCacheTuple(PRONAME,
- PointerGetDatum(funcname),
- PointerGetDatum(nargs),
- PointerGetDatum(arglist),
- 0);
- if (!HeapTupleIsValid(htp))
- func_error("pg_func_ownercheck", funcname, nargs, arglist);
-
- owner_id = ((Form_pg_proc) GETSTRUCT(htp))->proowner;
-
- return(user_id == owner_id);
+ return (1);
+ }
+
+ htp = SearchSysCacheTuple(PRONAME,
+ PointerGetDatum(funcname),
+ PointerGetDatum(nargs),
+ PointerGetDatum(arglist),
+ 0);
+ if (!HeapTupleIsValid(htp))
+ func_error("pg_func_ownercheck", funcname, nargs, arglist);
+
+ owner_id = ((Form_pg_proc) GETSTRUCT(htp))->proowner;
+
+ return (user_id == owner_id);
}
int32
-pg_aggr_ownercheck(char *usename,
- char *aggname,
- Oid basetypeID)
+pg_aggr_ownercheck(char *usename,
+ char *aggname,
+ Oid basetypeID)
{
- HeapTuple htp;
- AclId user_id, owner_id;
-
- htp = SearchSysCacheTuple(USENAME, PointerGetDatum(usename),
- 0,0,0);
- if (!HeapTupleIsValid(htp))
- elog(WARN, "pg_aggr_ownercheck: user \"%s\" not found",
- usename);
- user_id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid;
-
- /*
- * Superusers bypass all permission-checking.
- */
- if (((Form_pg_user) GETSTRUCT(htp))->usesuper) {
+ HeapTuple htp;
+ AclId user_id,
+ owner_id;
+
+ htp = SearchSysCacheTuple(USENAME, PointerGetDatum(usename),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "pg_aggr_ownercheck: user \"%s\" not found",
+ usename);
+ user_id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid;
+
+ /*
+ * Superusers bypass all permission-checking.
+ */
+ if (((Form_pg_user) GETSTRUCT(htp))->usesuper)
+ {
#ifdef ACLDEBUG_TRACE
- elog(DEBUG, "pg_aggr_ownercheck: user \"%s\" is superuser",
- usename);
+ elog(DEBUG, "pg_aggr_ownercheck: user \"%s\" is superuser",
+ usename);
#endif
- return(1);
- }
+ return (1);
+ }
- htp = SearchSysCacheTuple(AGGNAME,
- PointerGetDatum(aggname),
- PointerGetDatum(basetypeID),
- 0,
- 0);
+ htp = SearchSysCacheTuple(AGGNAME,
+ PointerGetDatum(aggname),
+ PointerGetDatum(basetypeID),
+ 0,
+ 0);
+
+ if (!HeapTupleIsValid(htp))
+ agg_error("pg_aggr_ownercheck", aggname, basetypeID);
- if (!HeapTupleIsValid(htp))
- agg_error("pg_aggr_ownercheck", aggname, basetypeID);
+ owner_id = ((Form_pg_aggregate) GETSTRUCT(htp))->aggowner;
- owner_id = ((Form_pg_aggregate) GETSTRUCT(htp))->aggowner;
-
- return(user_id == owner_id);
+ return (user_id == owner_id);
}
diff --git a/src/backend/tcop/dest.c b/src/backend/tcop/dest.c
index ea1548cd3de..1c0306b18d9 100644
--- a/src/backend/tcop/dest.c
+++ b/src/backend/tcop/dest.c
@@ -1,29 +1,29 @@
/*-------------------------------------------------------------------------
*
* dest.c--
- * support for various communication destinations - see lib/H/tcop/dest.h
+ * support for various communication destinations - see lib/H/tcop/dest.h
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.10 1997/08/29 09:04:18 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.11 1997/09/07 04:49:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * INTERFACE ROUTINES
- * BeginCommand - prepare destination for tuples of the given type
- * EndCommand - tell destination that no more tuples will arrive
- * NullCommand - tell dest that the last of a query sequence was processed
- *
- * NOTES
- * These routines do the appropriate work before and after
- * tuples are returned by a query to keep the backend and the
- * "destination" portals synchronized.
+ * INTERFACE ROUTINES
+ * BeginCommand - prepare destination for tuples of the given type
+ * EndCommand - tell destination that no more tuples will arrive
+ * NullCommand - tell dest that the last of a query sequence was processed
+ *
+ * NOTES
+ * These routines do the appropriate work before and after
+ * tuples are returned by a query to keep the backend and the
+ * "destination" portals synchronized.
*
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include "postgres.h"
@@ -43,10 +43,10 @@
#include "commands/async.h"
-static char CommandInfo[32] = {0};
+static char CommandInfo[32] = {0};
/* ----------------
- * output functions
+ * output functions
* ----------------
*/
static void
@@ -54,85 +54,88 @@ donothing(HeapTuple tuple, TupleDesc attrdesc)
{
}
-extern void spi_printtup (HeapTuple tuple, TupleDesc tupdesc);
+extern void spi_printtup(HeapTuple tuple, TupleDesc tupdesc);
-void (*DestToFunction(CommandDest dest))(HeapTuple, TupleDesc)
+void (*
+ DestToFunction(CommandDest dest)) (HeapTuple, TupleDesc)
{
- switch (dest) {
- case RemoteInternal:
- return printtup_internal;
- break;
-
- case Remote:
- return printtup;
- break;
-
- case Local:
- return be_printtup;
- break;
-
- case Debug:
- return debugtup;
- break;
-
- case SPI:
- return spi_printtup;
- break;
-
- case None:
- default:
+ switch (dest)
+ {
+ case RemoteInternal:
+ return printtup_internal;
+ break;
+
+ case Remote:
+ return printtup;
+ break;
+
+ case Local:
+ return be_printtup;
+ break;
+
+ case Debug:
+ return debugtup;
+ break;
+
+ case SPI:
+ return spi_printtup;
+ break;
+
+ case None:
+ default:
+ return donothing;
+ break;
+ }
+
+ /*
+ * never gets here, but DECstation lint appears to be stupid...
+ */
+
return donothing;
- break;
- }
-
- /*
- * never gets here, but DECstation lint appears to be stupid...
- */
-
- return donothing;
}
/* ----------------
- * EndCommand - tell destination that no more tuples will arrive
+ * EndCommand - tell destination that no more tuples will arrive
* ----------------
*/
void
EndCommand(char *commandTag, CommandDest dest)
{
- char buf[64];
-
- switch (dest) {
- case RemoteInternal:
- case Remote:
- /* ----------------
- * tell the fe that the query is over
- * ----------------
- */
- pq_putnchar("C", 1);
- sprintf(buf, "%s%s", commandTag, CommandInfo);
- CommandInfo[0] = 0;
- pq_putstr(buf);
- pq_flush();
- break;
-
- case Local:
- case Debug:
- break;
- case CopyEnd:
- pq_putnchar("Z", 1);
- pq_flush();
- break;
- case None:
- default:
- break;
- }
+ char buf[64];
+
+ switch (dest)
+ {
+ case RemoteInternal:
+ case Remote:
+ /* ----------------
+ * tell the fe that the query is over
+ * ----------------
+ */
+ pq_putnchar("C", 1);
+ sprintf(buf, "%s%s", commandTag, CommandInfo);
+ CommandInfo[0] = 0;
+ pq_putstr(buf);
+ pq_flush();
+ break;
+
+ case Local:
+ case Debug:
+ break;
+ case CopyEnd:
+ pq_putnchar("Z", 1);
+ pq_flush();
+ break;
+ case None:
+ default:
+ break;
+ }
}
/*
* These are necessary to sync communications between fe/be processes doing
* COPY rel TO stdout
- *
- * or
+ *
+ * or
*
* COPY rel FROM stdin
*
@@ -140,198 +143,211 @@ EndCommand(char *commandTag, CommandDest dest)
void
SendCopyBegin(void)
{
- pq_putnchar("B", 1);
-/* pq_putint(0, 4); */
- pq_flush();
+ pq_putnchar("B", 1);
+/* pq_putint(0, 4); */
+ pq_flush();
}
void
ReceiveCopyBegin(void)
{
- pq_putnchar("D", 1);
-/* pq_putint(0, 4); */
- pq_flush();
+ pq_putnchar("D", 1);
+/* pq_putint(0, 4); */
+ pq_flush();
}
/* ----------------
- * NullCommand - tell dest that the last of a query sequence was processed
- *
- * Necessary to implement the hacky FE/BE interface to handle
- * multiple-return queries.
+ * NullCommand - tell dest that the last of a query sequence was processed
+ *
+ * Necessary to implement the hacky FE/BE interface to handle
+ * multiple-return queries.
* ----------------
*/
void
NullCommand(CommandDest dest)
{
- switch (dest) {
- case RemoteInternal:
- case Remote: {
+ switch (dest)
+ {
+ case RemoteInternal:
+ case Remote:
+ {
#if 0
- /* Do any asynchronous notification. If front end wants to poll,
- it can send null queries to call this function.
- */
- PQNotifyList *nPtr;
- MemoryContext orig;
-
- if (notifyContext == NULL) {
- notifyContext = CreateGlobalMemory("notify");
- }
- orig = MemoryContextSwitchTo((MemoryContext)notifyContext);
-
- for (nPtr = PQnotifies() ;
- nPtr != NULL;
- nPtr = (PQNotifyList *)SLGetSucc(&nPtr->Node)) {
- pq_putnchar("A",1);
- pq_putint(0, 4);
- pq_putstr(nPtr->relname);
- pq_putint(nPtr->be_pid,4);
- PQremoveNotify(nPtr);
- }
- pq_flush();
- PQcleanNotify(); /* garbage collect */
- MemoryContextSwitchTo(orig);
+
+ /*
+ * Do any asynchronous notification. If front end wants to
+ * poll, it can send null queries to call this function.
+ */
+ PQNotifyList *nPtr;
+ MemoryContext orig;
+
+ if (notifyContext == NULL)
+ {
+ notifyContext = CreateGlobalMemory("notify");
+ }
+ orig = MemoryContextSwitchTo((MemoryContext) notifyContext);
+
+ for (nPtr = PQnotifies();
+ nPtr != NULL;
+ nPtr = (PQNotifyList *) SLGetSucc(&nPtr->Node))
+ {
+ pq_putnchar("A", 1);
+ pq_putint(0, 4);
+ pq_putstr(nPtr->relname);
+ pq_putint(nPtr->be_pid, 4);
+ PQremoveNotify(nPtr);
+ }
+ pq_flush();
+ PQcleanNotify(); /* garbage collect */
+ MemoryContextSwitchTo(orig);
#endif
- /* ----------------
- * tell the fe that the last of the queries has finished
- * ----------------
- */
-/* pq_putnchar("I", 1); */
- pq_putstr("I");
- /* pq_putint(0, 4);*/
- pq_flush();
- }
- break;
-
- case Local:
- case Debug:
- case None:
- default:
- break;
- }
+ /* ----------------
+ * tell the fe that the last of the queries has finished
+ * ----------------
+ */
+/* pq_putnchar("I", 1); */
+ pq_putstr("I");
+ /* pq_putint(0, 4); */
+ pq_flush();
+ }
+ break;
+
+ case Local:
+ case Debug:
+ case None:
+ default:
+ break;
+ }
}
/* ----------------
- * BeginCommand - prepare destination for tuples of the given type
+ * BeginCommand - prepare destination for tuples of the given type
* ----------------
*/
void
BeginCommand(char *pname,
- int operation,
- TupleDesc tupdesc,
- bool isIntoRel,
- bool isIntoPortal,
- char *tag,
- CommandDest dest)
+ int operation,
+ TupleDesc tupdesc,
+ bool isIntoRel,
+ bool isIntoPortal,
+ char *tag,
+ CommandDest dest)
{
- PortalEntry *entry;
- AttributeTupleForm *attrs = tupdesc->attrs;
- int natts = tupdesc->natts;
- int i;
- char *p;
-
- switch (dest) {
- case RemoteInternal:
- case Remote:
- /* ----------------
- * if this is a "retrieve portal" query, just return
- * because nothing needs to be sent to the fe.
- * ----------------
- */
- CommandInfo[0] = 0;
- if (isIntoPortal)
- return;
-
- /* ----------------
- * if portal name not specified for remote query,
- * use the "blank" portal.
- * ----------------
- */
- if (pname == NULL)
- pname = "blank";
-
- /* ----------------
- * send fe info on tuples we're about to send
- * ----------------
- */
- pq_flush();
- pq_putnchar("P", 1); /* new portal.. */
- pq_putstr(pname); /* portal name */
-
- /* ----------------
- * if this is a retrieve, then we send back the tuple
- * descriptor of the tuples. "retrieve into" is an
- * exception because no tuples are returned in that case.
- * ----------------
- */
- if (operation == CMD_SELECT && !isIntoRel) {
- pq_putnchar("T", 1); /* type info to follow.. */
- pq_putint(natts, 2); /* number of attributes in tuples */
-
- for (i = 0; i < natts; ++i) {
- pq_putstr(attrs[i]->attname.data);/* if 16 char name oops.. */
- pq_putint((int) attrs[i]->atttypid, 4);
- pq_putint(attrs[i]->attlen, 2);
- }
- }
- pq_flush();
- break;
-
- case Local:
- /* ----------------
- * prepare local portal buffer for query results
- * and setup result for PQexec()
- * ----------------
- */
- entry = be_currentportal();
- if (pname != NULL)
- pbuf_setportalinfo(entry, pname);
-
- if (operation == CMD_SELECT && !isIntoRel) {
- be_typeinit(entry, tupdesc, natts);
- p = (char *) palloc(strlen(entry->name)+2);
- p[0] = 'P';
- strcpy(p+1,entry->name);
- } else {
- p = (char *) palloc(strlen(tag)+2);
- p[0] = 'C';
- strcpy(p+1,tag);
+ PortalEntry *entry;
+ AttributeTupleForm *attrs = tupdesc->attrs;
+ int natts = tupdesc->natts;
+ int i;
+ char *p;
+
+ switch (dest)
+ {
+ case RemoteInternal:
+ case Remote:
+ /* ----------------
+ * if this is a "retrieve portal" query, just return
+ * because nothing needs to be sent to the fe.
+ * ----------------
+ */
+ CommandInfo[0] = 0;
+ if (isIntoPortal)
+ return;
+
+ /* ----------------
+ * if portal name not specified for remote query,
+ * use the "blank" portal.
+ * ----------------
+ */
+ if (pname == NULL)
+ pname = "blank";
+
+ /* ----------------
+ * send fe info on tuples we're about to send
+ * ----------------
+ */
+ pq_flush();
+ pq_putnchar("P", 1); /* new portal.. */
+ pq_putstr(pname); /* portal name */
+
+ /* ----------------
+ * if this is a retrieve, then we send back the tuple
+ * descriptor of the tuples. "retrieve into" is an
+ * exception because no tuples are returned in that case.
+ * ----------------
+ */
+ if (operation == CMD_SELECT && !isIntoRel)
+ {
+ pq_putnchar("T", 1);/* type info to follow.. */
+ pq_putint(natts, 2);/* number of attributes in tuples */
+
+ for (i = 0; i < natts; ++i)
+ {
+ pq_putstr(attrs[i]->attname.data); /* if 16 char name
+ * oops.. */
+ pq_putint((int) attrs[i]->atttypid, 4);
+ pq_putint(attrs[i]->attlen, 2);
+ }
+ }
+ pq_flush();
+ break;
+
+ case Local:
+ /* ----------------
+ * prepare local portal buffer for query results
+ * and setup result for PQexec()
+ * ----------------
+ */
+ entry = be_currentportal();
+ if (pname != NULL)
+ pbuf_setportalinfo(entry, pname);
+
+ if (operation == CMD_SELECT && !isIntoRel)
+ {
+ be_typeinit(entry, tupdesc, natts);
+ p = (char *) palloc(strlen(entry->name) + 2);
+ p[0] = 'P';
+ strcpy(p + 1, entry->name);
+ }
+ else
+ {
+ p = (char *) palloc(strlen(tag) + 2);
+ p[0] = 'C';
+ strcpy(p + 1, tag);
+ }
+ entry->result = p;
+ break;
+
+ case Debug:
+ /* ----------------
+ * show the return type of the tuples
+ * ----------------
+ */
+ if (pname == NULL)
+ pname = "blank";
+
+ showatts(pname, tupdesc);
+ break;
+
+ case None:
+ default:
+ break;
}
- entry->result = p;
- break;
-
- case Debug:
- /* ----------------
- * show the return type of the tuples
- * ----------------
- */
- if (pname == NULL)
- pname = "blank";
-
- showatts(pname, tupdesc);
- break;
-
- case None:
- default:
- break;
- }
}
void
-UpdateCommandInfo (int operation, Oid lastoid, uint32 tuples)
+UpdateCommandInfo(int operation, Oid lastoid, uint32 tuples)
{
- switch (operation)
- {
- case CMD_INSERT :
- if ( tuples > 1 )
- lastoid = InvalidOid;
- sprintf (CommandInfo, " %u %u", lastoid, tuples);
- break;
- case CMD_DELETE :
- case CMD_UPDATE :
- sprintf (CommandInfo, " %u", tuples);
- break;
- default :
- CommandInfo[0] = 0;
- }
- return;
+ switch (operation)
+ {
+ case CMD_INSERT:
+ if (tuples > 1)
+ lastoid = InvalidOid;
+ sprintf(CommandInfo, " %u %u", lastoid, tuples);
+ break;
+ case CMD_DELETE:
+ case CMD_UPDATE:
+ sprintf(CommandInfo, " %u", tuples);
+ break;
+ default:
+ CommandInfo[0] = 0;
+ }
+ return;
}
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index 20951fa4cb0..27c01ff1a17 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -1,59 +1,59 @@
/*-------------------------------------------------------------------------
*
* fastpath.c--
- * routines to handle function requests from the frontend
+ * routines to handle function requests from the frontend
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.4 1997/03/12 21:07:50 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.5 1997/09/07 04:49:32 momjian Exp $
*
* NOTES
- * This cruft is the server side of PQfn.
+ * This cruft is the server side of PQfn.
*
- * - jolly 07/11/95:
+ * - jolly 07/11/95:
*
- * no longer rely on return sizes provided by the frontend. Always
- * use the true lengths for the catalogs. Assume that the frontend
- * has allocated enough space to handle the result value returned.
- *
- * trust that the user knows what he is doing with the args. If the
- * sys catalog says it is a varlena, assume that the user is only sending
- * down VARDATA and that the argsize is the VARSIZE. If the arg is
- * fixed len, assume that the argsize given by the user is correct.
- *
- * if the function returns by value, then only send 4 bytes value
- * back to the frontend. If the return returns by reference,
- * send down only the data portion and set the return size appropriately.
- *
- * OLD COMMENTS FOLLOW
+ * no longer rely on return sizes provided by the frontend. Always
+ * use the true lengths for the catalogs. Assume that the frontend
+ * has allocated enough space to handle the result value returned.
*
- * The VAR_LENGTH_{ARGS,RESULT} stuff is limited to MAX_STRING_LENGTH
- * (see src/backend/tmp/fastpath.h) for no obvious reason. Since its
- * primary use (for us) is for Inversion path names, it should probably
- * be increased to 256 (MAXPATHLEN for Inversion, hidden in pg_type
- * as well as utils/adt/filename.c).
+ * trust that the user knows what he is doing with the args. If the
+ * sys catalog says it is a varlena, assume that the user is only sending
+ * down VARDATA and that the argsize is the VARSIZE. If the arg is
+ * fixed len, assume that the argsize given by the user is correct.
*
- * Quoth PMA on 08/15/93:
+ * if the function returns by value, then only send 4 bytes value
+ * back to the frontend. If the return returns by reference,
+ * send down only the data portion and set the return size appropriately.
*
- * This code has been almost completely rewritten with an eye to
- * keeping it as compatible as possible with the previous (broken)
- * implementation.
+ * OLD COMMENTS FOLLOW
*
- * The previous implementation would assume (1) that any value of
- * length <= 4 bytes was passed-by-value, and that any other value
- * was a struct varlena (by-reference). There was NO way to pass a
- * fixed-length by-reference argument (like char16) or a struct
- * varlena of size <= 4 bytes.
- *
- * The new implementation checks the catalogs to determine whether
- * a value is by-value (type "0" is null-delimited character string,
- * as it is for, e.g., the parser). The only other item obtained
- * from the catalogs is whether or not the value should be placed in
- * a struct varlena or not. Otherwise, the size given by the
- * frontend is assumed to be correct (probably a bad decision, but
- * we do strange things in the name of compatibility).
+ * The VAR_LENGTH_{ARGS,RESULT} stuff is limited to MAX_STRING_LENGTH
+ * (see src/backend/tmp/fastpath.h) for no obvious reason. Since its
+ * primary use (for us) is for Inversion path names, it should probably
+ * be increased to 256 (MAXPATHLEN for Inversion, hidden in pg_type
+ * as well as utils/adt/filename.c).
+ *
+ * Quoth PMA on 08/15/93:
+ *
+ * This code has been almost completely rewritten with an eye to
+ * keeping it as compatible as possible with the previous (broken)
+ * implementation.
+ *
+ * The previous implementation would assume (1) that any value of
+ * length <= 4 bytes was passed-by-value, and that any other value
+ * was a struct varlena (by-reference). There was NO way to pass a
+ * fixed-length by-reference argument (like char16) or a struct
+ * varlena of size <= 4 bytes.
+ *
+ * The new implementation checks the catalogs to determine whether
+ * a value is by-value (type "0" is null-delimited character string,
+ * as it is for, e.g., the parser). The only other item obtained
+ * from the catalogs is whether or not the value should be placed in
+ * a struct varlena or not. Otherwise, the size given by the
+ * frontend is assumed to be correct (probably a bad decision, but
+ * we do strange things in the name of compatibility).
*
*-------------------------------------------------------------------------
*/
@@ -65,11 +65,11 @@
#include "utils/palloc.h"
#include "fmgr.h"
-#include "utils/builtins.h" /* for oideq */
+#include "utils/builtins.h" /* for oideq */
#include "tcop/fastpath.h"
#include "libpq/libpq.h"
-#include "access/xact.h" /* for TransactionId/CommandId protos */
+#include "access/xact.h" /* for TransactionId/CommandId protos */
#include "utils/syscache.h"
#include "catalog/pg_proc.h"
@@ -77,90 +77,98 @@
/* ----------------
- * SendFunctionResult
+ * SendFunctionResult
* ----------------
*/
static void
-SendFunctionResult(Oid fid, /* function id */
- char *retval, /* actual return value */
- bool retbyval,
- int retlen /* the length according to the catalogs */
- )
+SendFunctionResult(Oid fid, /* function id */
+ char *retval,/* actual return value */
+ bool retbyval,
+ int retlen /* the length according to the catalogs */
+)
{
- pq_putnchar("V", 1);
-
- if (retlen != 0) {
- pq_putnchar("G", 1);
- if (retbyval) { /* by-value */
- pq_putint(retlen, 4);
- pq_putint((int)(Datum)retval, retlen);
- } else { /* by-reference ... */
- if (retlen < 0) { /* ... varlena */
- pq_putint(VARSIZE(retval) - VARHDRSZ, 4);
- pq_putnchar(VARDATA(retval), VARSIZE(retval) - VARHDRSZ);
- } else { /* ... fixed */
- pq_putint(retlen, 4);
- pq_putnchar(retval, retlen);
- }
+ pq_putnchar("V", 1);
+
+ if (retlen != 0)
+ {
+ pq_putnchar("G", 1);
+ if (retbyval)
+ { /* by-value */
+ pq_putint(retlen, 4);
+ pq_putint((int) (Datum) retval, retlen);
+ }
+ else
+ { /* by-reference ... */
+ if (retlen < 0)
+ { /* ... varlena */
+ pq_putint(VARSIZE(retval) - VARHDRSZ, 4);
+ pq_putnchar(VARDATA(retval), VARSIZE(retval) - VARHDRSZ);
+ }
+ else
+ { /* ... fixed */
+ pq_putint(retlen, 4);
+ pq_putnchar(retval, retlen);
+ }
+ }
}
- }
- pq_putnchar("0", 1);
- pq_flush();
+ pq_putnchar("0", 1);
+ pq_flush();
}
/*
* This structure saves enough state so that one can avoid having to
- * do catalog lookups over and over again. (Each RPC can require up
+ * do catalog lookups over and over again. (Each RPC can require up
* to MAXFMGRARGS+2 lookups, which is quite tedious.)
*
* The previous incarnation of this code just assumed that any argument
- * of size <= 4 was by value; this is not correct. There is no cheap
+ * of size <= 4 was by value; this is not correct. There is no cheap
* way to determine function argument length etc.; one must simply pay
* the price of catalog lookups.
*/
-struct fp_info {
- Oid funcid;
- int nargs;
- bool argbyval[MAXFMGRARGS];
- int32 arglen[MAXFMGRARGS]; /* signed (for varlena) */
- bool retbyval;
- int32 retlen; /* signed (for varlena) */
- TransactionId xid;
- CommandId cid;
+struct fp_info
+{
+ Oid funcid;
+ int nargs;
+ bool argbyval[MAXFMGRARGS];
+ int32 arglen[MAXFMGRARGS]; /* signed (for varlena) */
+ bool retbyval;
+ int32 retlen; /* signed (for varlena) */
+ TransactionId xid;
+ CommandId cid;
};
/*
- * We implement one-back caching here. If we need to do more, we can.
+ * We implement one-back caching here. If we need to do more, we can.
* Most routines in tight loops (like PQfswrite -> F_LOWRITE) will do
* the same thing repeatedly.
*/
-static struct fp_info last_fp = { InvalidOid };
+static struct fp_info last_fp = {InvalidOid};
/*
* valid_fp_info
*
* RETURNS:
- * 1 if the state in 'fip' is valid
- * 0 otherwise
+ * 1 if the state in 'fip' is valid
+ * 0 otherwise
*
* "valid" means:
* The saved state was either uninitialized, for another function,
- * or from a previous command. (Commands can do updates, which
- * may invalidate catalog entries for subsequent commands. This
+ * or from a previous command. (Commands can do updates, which
+ * may invalidate catalog entries for subsequent commands. This
* is overly pessimistic but since there is no smarter invalidation
* scheme...).
*/
static int
-valid_fp_info(Oid func_id, struct fp_info *fip)
+valid_fp_info(Oid func_id, struct fp_info * fip)
{
- Assert(OidIsValid(func_id));
- Assert(fip != (struct fp_info *) NULL);
-
- return(OidIsValid(fip->funcid) &&
- oideq(func_id, fip->funcid) &&
- TransactionIdIsCurrentTransactionId(fip->xid) &&
- CommandIdIsCurrentCommandId(fip->cid));
+ Assert(OidIsValid(func_id));
+ Assert(fip != (struct fp_info *) NULL);
+
+ return (OidIsValid(fip->funcid) &&
+ oideq(func_id, fip->funcid) &&
+ TransactionIdIsCurrentTransactionId(fip->xid) &&
+ CommandIdIsCurrentCommandId(fip->cid));
}
/*
@@ -170,79 +178,86 @@ valid_fp_info(Oid func_id, struct fp_info *fip)
* function 'func_id'.
*
* RETURNS:
- * The correct information in 'fip'. Sets 'fip->funcid' to
- * InvalidOid if an exception occurs.
+ * The correct information in 'fip'. Sets 'fip->funcid' to
+ * InvalidOid if an exception occurs.
*/
static void
-update_fp_info(Oid func_id, struct fp_info *fip)
+update_fp_info(Oid func_id, struct fp_info * fip)
{
- Oid *argtypes; /* an oid8 */
- Oid rettype;
- HeapTuple func_htp, type_htp;
- TypeTupleForm tp;
- Form_pg_proc pp;
- int i;
-
- Assert(OidIsValid(func_id));
- Assert(fip != (struct fp_info *) NULL);
-
- /*
- * Since the validity of this structure is determined by whether
- * the funcid is OK, we clear the funcid here. It must not be
- * set to the correct value until we are about to return with
- * a good struct fp_info, since we can be interrupted (i.e., with
- * an elog(WARN, ...)) at any time.
- */
- memset((char *) fip, 0, (int) sizeof(struct fp_info));
- fip->funcid = InvalidOid;
-
- func_htp = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(func_id),
- 0,0,0);
- if (!HeapTupleIsValid(func_htp)) {
- elog(WARN, "update_fp_info: cache lookup for function %d failed",
- func_id);
- }
- pp = (Form_pg_proc) GETSTRUCT(func_htp);
- fip->nargs = pp->pronargs;
- rettype = pp->prorettype;
- argtypes = pp->proargtypes;
-
- for (i = 0; i < fip->nargs; ++i) {
- if (OidIsValid(argtypes[i])) {
- type_htp = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(argtypes[i]),
- 0,0,0);
- if (!HeapTupleIsValid(type_htp)) {
- elog(WARN, "update_fp_info: bad argument type %d for %d",
- argtypes[i], func_id);
- }
- tp = (TypeTupleForm) GETSTRUCT(type_htp);
- fip->argbyval[i] = tp->typbyval;
- fip->arglen[i] = tp->typlen;
- } /* else it had better be VAR_LENGTH_ARG */
- }
-
- if (OidIsValid(rettype)) {
- type_htp = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(rettype),
- 0,0,0);
- if (!HeapTupleIsValid(type_htp)) {
- elog(WARN, "update_fp_info: bad return type %d for %d",
- rettype, func_id);
+ Oid *argtypes; /* an oid8 */
+ Oid rettype;
+ HeapTuple func_htp,
+ type_htp;
+ TypeTupleForm tp;
+ Form_pg_proc pp;
+ int i;
+
+ Assert(OidIsValid(func_id));
+ Assert(fip != (struct fp_info *) NULL);
+
+ /*
+ * Since the validity of this structure is determined by whether the
+ * funcid is OK, we clear the funcid here. It must not be set to the
+ * correct value until we are about to return with a good struct
+ * fp_info, since we can be interrupted (i.e., with an elog(WARN,
+ * ...)) at any time.
+ */
+ memset((char *) fip, 0, (int) sizeof(struct fp_info));
+ fip->funcid = InvalidOid;
+
+ func_htp = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(func_id),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(func_htp))
+ {
+ elog(WARN, "update_fp_info: cache lookup for function %d failed",
+ func_id);
}
- tp = (TypeTupleForm) GETSTRUCT(type_htp);
- fip->retbyval = tp->typbyval;
- fip->retlen = tp->typlen;
- } /* else it had better by VAR_LENGTH_RESULT */
-
- fip->xid = GetCurrentTransactionId();
- fip->cid = GetCurrentCommandId();
-
- /*
- * This must be last!
- */
- fip->funcid = func_id;
+ pp = (Form_pg_proc) GETSTRUCT(func_htp);
+ fip->nargs = pp->pronargs;
+ rettype = pp->prorettype;
+ argtypes = pp->proargtypes;
+
+ for (i = 0; i < fip->nargs; ++i)
+ {
+ if (OidIsValid(argtypes[i]))
+ {
+ type_htp = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(argtypes[i]),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(type_htp))
+ {
+ elog(WARN, "update_fp_info: bad argument type %d for %d",
+ argtypes[i], func_id);
+ }
+ tp = (TypeTupleForm) GETSTRUCT(type_htp);
+ fip->argbyval[i] = tp->typbyval;
+ fip->arglen[i] = tp->typlen;
+ } /* else it had better be VAR_LENGTH_ARG */
+ }
+
+ if (OidIsValid(rettype))
+ {
+ type_htp = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(rettype),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(type_htp))
+ {
+ elog(WARN, "update_fp_info: bad return type %d for %d",
+ rettype, func_id);
+ }
+ tp = (TypeTupleForm) GETSTRUCT(type_htp);
+ fip->retbyval = tp->typbyval;
+ fip->retlen = tp->typlen;
+ } /* else it had better by VAR_LENGTH_RESULT */
+
+ fip->xid = GetCurrentTransactionId();
+ fip->cid = GetCurrentCommandId();
+
+ /*
+ * This must be last!
+ */
+ fip->funcid = func_id;
}
-
+
/*
* HandleFunctionRequest
@@ -251,104 +266,119 @@ update_fp_info(Oid func_id, struct fp_info *fip)
* This corresponds to the libpq protocol symbol "F".
*
* RETURNS:
- * nothing of significance.
- * All errors result in elog(WARN,...).
+ * nothing of significance.
+ * All errors result in elog(WARN,...).
*/
int
HandleFunctionRequest()
{
- Oid fid;
- int argsize;
- int nargs;
- char *arg[8];
- char *retval;
- int i;
- uint32 palloced;
- char *p;
- struct fp_info *fip;
-
- fid = (Oid) pq_getint(4); /* function oid */
- nargs = pq_getint(4); /* # of arguments */
-
- /*
- * This is where the one-back caching is done.
- * If you want to save more state, make this a loop around an array.
- */
- fip = &last_fp;
- if (!valid_fp_info(fid, fip)) {
- update_fp_info(fid, fip);
- }
-
- if (fip->nargs != nargs) {
- elog(WARN, "HandleFunctionRequest: actual arguments (%d) != registered arguments (%d)",
- nargs, fip->nargs);
- }
-
- /*
- * Copy arguments into arg vector. If we palloc() an argument, we need
- * to remember, so that we pfree() it after the call.
- */
- palloced = 0x0;
- for (i = 0; i < 8; ++i) {
- if (i >= nargs) {
- arg[i] = (char *) NULL;
- } else {
- argsize = pq_getint(4);
-
- Assert(argsize > 0);
- if (fip->argbyval[i]) { /* by-value */
- Assert(argsize <= 4);
- arg[i] = (char *) pq_getint(argsize);
- } else { /* by-reference ... */
- if (fip->arglen[i] < 0) { /* ... varlena */
- if (!(p = palloc(argsize + VARHDRSZ))) {
- elog(WARN, "HandleFunctionRequest: palloc failed");
- }
- VARSIZE(p) = argsize + VARHDRSZ;
- pq_getnchar(VARDATA(p), 0, argsize);
- } else { /* ... fixed */
- /* XXX cross our fingers and trust "argsize" */
- if (!(p = palloc(argsize))) {
- elog(WARN, "HandleFunctionRequest: palloc failed");
+ Oid fid;
+ int argsize;
+ int nargs;
+ char *arg[8];
+ char *retval;
+ int i;
+ uint32 palloced;
+ char *p;
+ struct fp_info *fip;
+
+ fid = (Oid) pq_getint(4); /* function oid */
+ nargs = pq_getint(4); /* # of arguments */
+
+ /*
+ * This is where the one-back caching is done. If you want to save
+ * more state, make this a loop around an array.
+ */
+ fip = &last_fp;
+ if (!valid_fp_info(fid, fip))
+ {
+ update_fp_info(fid, fip);
+ }
+
+ if (fip->nargs != nargs)
+ {
+ elog(WARN, "HandleFunctionRequest: actual arguments (%d) != registered arguments (%d)",
+ nargs, fip->nargs);
+ }
+
+ /*
+ * Copy arguments into arg vector. If we palloc() an argument, we
+ * need to remember, so that we pfree() it after the call.
+ */
+ palloced = 0x0;
+ for (i = 0; i < 8; ++i)
+ {
+ if (i >= nargs)
+ {
+ arg[i] = (char *) NULL;
+ }
+ else
+ {
+ argsize = pq_getint(4);
+
+ Assert(argsize > 0);
+ if (fip->argbyval[i])
+ { /* by-value */
+ Assert(argsize <= 4);
+ arg[i] = (char *) pq_getint(argsize);
}
- pq_getnchar(p, 0, argsize);
- }
- palloced |= (1 << i);
- arg[i] = p;
- }
+ else
+ { /* by-reference ... */
+ if (fip->arglen[i] < 0)
+ { /* ... varlena */
+ if (!(p = palloc(argsize + VARHDRSZ)))
+ {
+ elog(WARN, "HandleFunctionRequest: palloc failed");
+ }
+ VARSIZE(p) = argsize + VARHDRSZ;
+ pq_getnchar(VARDATA(p), 0, argsize);
+ }
+ else
+ { /* ... fixed */
+ /* XXX cross our fingers and trust "argsize" */
+ if (!(p = palloc(argsize)))
+ {
+ elog(WARN, "HandleFunctionRequest: palloc failed");
+ }
+ pq_getnchar(p, 0, argsize);
+ }
+ palloced |= (1 << i);
+ arg[i] = p;
+ }
+ }
}
- }
#ifndef NO_FASTPATH
- retval = fmgr(fid,
- arg[0], arg[1], arg[2], arg[3],
- arg[4], arg[5], arg[6], arg[7]);
+ retval = fmgr(fid,
+ arg[0], arg[1], arg[2], arg[3],
+ arg[4], arg[5], arg[6], arg[7]);
#else
- retval = NULL;
-#endif /* NO_FASTPATH */
-
- /* free palloc'ed arguments */
- for (i = 0; i < nargs; ++i) {
- if (palloced & (1 << i))
- pfree(arg[i]);
- }
-
- /*
- * If this is an ordinary query (not a retrieve portal p ...), then
- * we return the data to the user. If the return value was palloc'ed,
- * then it must also be freed.
- */
+ retval = NULL;
+#endif /* NO_FASTPATH */
+
+ /* free palloc'ed arguments */
+ for (i = 0; i < nargs; ++i)
+ {
+ if (palloced & (1 << i))
+ pfree(arg[i]);
+ }
+
+ /*
+ * If this is an ordinary query (not a retrieve portal p ...), then we
+ * return the data to the user. If the return value was palloc'ed,
+ * then it must also be freed.
+ */
#ifndef NO_FASTPATH
- SendFunctionResult(fid, retval, fip->retbyval, fip->retlen);
+ SendFunctionResult(fid, retval, fip->retbyval, fip->retlen);
#else
- SendFunctionResult(fid, retval, fip->retbyval, 0);
-#endif /* NO_FASTPATH */
+ SendFunctionResult(fid, retval, fip->retbyval, 0);
+#endif /* NO_FASTPATH */
+
+ if (!fip->retbyval)
+ pfree(retval);
+
- if (!fip->retbyval)
- pfree(retval);
-
-
- return(0);
+ return (0);
}
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index cd658704f03..f70d30434bb 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* postgres.c--
- * POSTGRES C Backend Interface
+ * POSTGRES C Backend Interface
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.42 1997/08/19 21:34:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.43 1997/09/07 04:49:33 momjian Exp $
*
* NOTES
- * this is the "main" module of the postgres backend and
- * hence the main module of the "traffic cop".
+ * this is the "main" module of the postgres backend and
+ * hence the main module of the "traffic cop".
*
*-------------------------------------------------------------------------
*/
@@ -25,17 +25,17 @@
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
-#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
+#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
#ifndef MAXHOSTNAMELEN
-#include <netdb.h> /* for MAXHOSTNAMELEN on some */
+#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#endif
-#ifndef MAXHOSTNAMELEN /* for MAXHOSTNAMELEN under sco3.2v5.0.2 */
+#ifndef MAXHOSTNAMELEN /* for MAXHOSTNAMELEN under sco3.2v5.0.2 */
#include <sys/socket.h>
#endif
#include <errno.h>
#ifdef aix
#include <sys/select.h>
-#endif /* aix */
+#endif /* aix */
#include "postgres.h"
@@ -46,9 +46,9 @@
#include "lib/dllist.h"
#include "parser/catalog_utils.h"
-#include "parser/parse_query.h" /* for MakeTimeRange() */
+#include "parser/parse_query.h" /* for MakeTimeRange() */
#include "commands/async.h"
-#include "tcop/tcopprot.h" /* where declarations for this file go */
+#include "tcop/tcopprot.h" /* where declarations for this file go */
#include "optimizer/planner.h"
#include "tcop/tcopprot.h"
@@ -88,1488 +88,1623 @@
#include "libpq/libpq.h"
#include "libpq/pqsignal.h"
-#include "rewrite/rewriteHandler.h" /* for QueryRewrite() */
+#include "rewrite/rewriteHandler.h" /* for QueryRewrite() */
-static void quickdie(SIGNAL_ARGS);
+static void quickdie(SIGNAL_ARGS);
/* ----------------
- * global variables
+ * global variables
* ----------------
*/
-static bool DebugPrintQuery = false;
-static bool DebugPrintPlan = false;
-static bool DebugPrintParse = false;
-static bool DebugPrintRewrittenParsetree = false;
-/*static bool EnableRewrite = true; , never changes why have it*/
-CommandDest whereToSendOutput;
+static bool DebugPrintQuery = false;
+static bool DebugPrintPlan = false;
+static bool DebugPrintParse = false;
+static bool DebugPrintRewrittenParsetree = false;
+
+/*static bool EnableRewrite = true; , never changes why have it*/
+CommandDest whereToSendOutput;
#ifdef LOCK_MGR_DEBUG
-extern int lockDebug;
+extern int lockDebug;
+
#endif
-extern int lockingOff;
-extern int NBuffers;
+extern int lockingOff;
+extern int NBuffers;
-int dontExecute = 0;
-static int ShowStats;
-static bool IsEmptyQuery = false;
+int dontExecute = 0;
+static int ShowStats;
+static bool IsEmptyQuery = false;
-char relname[80]; /* current relation name */
+char relname[80]; /* current relation name */
#if defined(nextstep)
-jmp_buf Warn_restart;
-#define sigsetjmp(x,y) setjmp(x)
+jmp_buf Warn_restart;
+
+#define sigsetjmp(x,y) setjmp(x)
#define siglongjmp longjmp
#else
-sigjmp_buf Warn_restart;
-#endif /* defined(nextstep) */
-int InWarn;
-
-extern int NBuffers;
-
-static int EchoQuery = 0; /* default don't echo */
-time_t tim;
-char pg_pathname[256];
-static int ShowParserStats;
-static int ShowPlannerStats;
-int ShowExecutorStats;
-FILE *StatFp;
-
-typedef struct frontend {
- bool fn_connected;
- Port fn_port;
- FILE *fn_Pfin; /* the input fd */
- FILE *fn_Pfout; /* the output fd */
- bool fn_done; /* set after the frontend closes its connection */
-} FrontEnd;
-
-static Dllist* frontendList;
+sigjmp_buf Warn_restart;
+
+#endif /* defined(nextstep) */
+int InWarn;
+
+extern int NBuffers;
+
+static int EchoQuery = 0; /* default don't echo */
+time_t tim;
+char pg_pathname[256];
+static int ShowParserStats;
+static int ShowPlannerStats;
+int ShowExecutorStats;
+FILE *StatFp;
+
+typedef struct frontend
+{
+ bool fn_connected;
+ Port fn_port;
+ FILE *fn_Pfin; /* the input fd */
+ FILE *fn_Pfout; /* the output fd */
+ bool fn_done; /* set after the frontend closes its
+ * connection */
+} FrontEnd;
+
+static Dllist *frontendList;
/* ----------------
- * people who want to use EOF should #define DONTUSENEWLINE in
- * tcop/tcopdebug.h
+ * people who want to use EOF should #define DONTUSENEWLINE in
+ * tcop/tcopdebug.h
* ----------------
*/
#ifndef TCOP_DONTUSENEWLINE
-int UseNewLine = 1; /* Use newlines query delimiters (the default) */
+int UseNewLine = 1; /* Use newlines query delimiters (the
+ * default) */
+
#else
-int UseNewLine = 0; /* Use EOF as query delimiters */
-#endif /* TCOP_DONTUSENEWLINE */
+int UseNewLine = 0; /* Use EOF as query delimiters */
+
+#endif /* TCOP_DONTUSENEWLINE */
/* ----------------
- * bushy tree plan flag: if true planner will generate bushy-tree
- * plans
+ * bushy tree plan flag: if true planner will generate bushy-tree
+ * plans
* ----------------
*/
-int BushyPlanFlag = 0; /* default to false -- consider only left-deep trees */
+int BushyPlanFlag = 0; /* default to false -- consider
+ * only left-deep trees */
/*
** Flags for expensive function optimization -- JMH 3/9/92
*/
-int XfuncMode = 0;
+int XfuncMode = 0;
/*
* ----------------
- * Note: _exec_repeat_ defaults to 1 but may be changed
- * by a DEBUG command. If you set this to a large
- * number N, run a single query, and then set it
- * back to 1 and run N queries, you can get an idea
- * of how much time is being spent in the parser and
- * planner b/c in the first case this overhead only
- * happens once. -cim 6/9/91
+ * Note: _exec_repeat_ defaults to 1 but may be changed
+ * by a DEBUG command. If you set this to a large
+ * number N, run a single query, and then set it
+ * back to 1 and run N queries, you can get an idea
+ * of how much time is being spent in the parser and
+ * planner b/c in the first case this overhead only
+ * happens once. -cim 6/9/91
* ----------------
*/
-int _exec_repeat_ = 1;
+int _exec_repeat_ = 1;
/* ----------------------------------------------------------------
- * decls for routines only used in this file
+ * decls for routines only used in this file
* ----------------------------------------------------------------
*/
-static char InteractiveBackend(char *inBuf);
-static char SocketBackend(char *inBuf, bool multiplexedBackend);
-static char ReadCommand(char *inBuf, bool multiplexedBackend);
+static char InteractiveBackend(char *inBuf);
+static char SocketBackend(char *inBuf, bool multiplexedBackend);
+static char ReadCommand(char *inBuf, bool multiplexedBackend);
/* ----------------------------------------------------------------
- * routines to obtain user input
+ * routines to obtain user input
* ----------------------------------------------------------------
*/
/* ----------------
- * InteractiveBackend() is called for user interactive connections
- * the string entered by the user is placed in its parameter inBuf.
+ * InteractiveBackend() is called for user interactive connections
+ * the string entered by the user is placed in its parameter inBuf.
* ----------------
*/
static char
InteractiveBackend(char *inBuf)
{
- char *stuff = inBuf; /* current place in input buffer */
- int c; /* character read from getc() */
- bool end = false; /* end-of-input flag */
- bool backslashSeen = false; /* have we seen a \ ? */
-
- /* ----------------
- * display a prompt and obtain input from the user
- * ----------------
- */
- printf("> ");
-
- for (;;) {
- if (UseNewLine) {
- /* ----------------
- * if we are using \n as a delimiter, then read
- * characters until the \n.
- * ----------------
- */
- while ( (c = getc(stdin)) != EOF) {
- if (c == '\n') {
- if (backslashSeen) {
- stuff--;
- continue;
- } else {
- /* keep the newline character */
- *stuff++ = '\n';
- *stuff++ = '\0';
- break;
- }
- } else if (c == '\\')
- backslashSeen = true;
- else
- backslashSeen = false;
-
- *stuff++ = (char)c;
- }
-
- if (c == EOF)
- end = true;
- } else {
- /* ----------------
- * otherwise read characters until EOF.
- * ----------------
- */
- while ( (c = getc(stdin)) != EOF )
- *stuff++ = (char)c;
-
- if ( stuff == inBuf )
- end = true;
- }
-
- if (end) {
- if (!Quiet) puts("EOF");
- IsEmptyQuery = true;
- exitpg(0);
- }
-
- /* ----------------
- * otherwise we have a user query so process it.
- * ----------------
- */
- break;
- }
-
- /* ----------------
- * if the query echo flag was given, print the query..
- * ----------------
- */
- if (EchoQuery)
- printf("query is: %s\n", inBuf);
-
- return('Q');
+ char *stuff = inBuf; /* current place in input buffer */
+ int c; /* character read from getc() */
+ bool end = false;/* end-of-input flag */
+ bool backslashSeen = false; /* have we seen a \ ? */
+
+ /* ----------------
+ * display a prompt and obtain input from the user
+ * ----------------
+ */
+ printf("> ");
+
+ for (;;)
+ {
+ if (UseNewLine)
+ {
+ /* ----------------
+ * if we are using \n as a delimiter, then read
+ * characters until the \n.
+ * ----------------
+ */
+ while ((c = getc(stdin)) != EOF)
+ {
+ if (c == '\n')
+ {
+ if (backslashSeen)
+ {
+ stuff--;
+ continue;
+ }
+ else
+ {
+ /* keep the newline character */
+ *stuff++ = '\n';
+ *stuff++ = '\0';
+ break;
+ }
+ }
+ else if (c == '\\')
+ backslashSeen = true;
+ else
+ backslashSeen = false;
+
+ *stuff++ = (char) c;
+ }
+
+ if (c == EOF)
+ end = true;
+ }
+ else
+ {
+ /* ----------------
+ * otherwise read characters until EOF.
+ * ----------------
+ */
+ while ((c = getc(stdin)) != EOF)
+ *stuff++ = (char) c;
+
+ if (stuff == inBuf)
+ end = true;
+ }
+
+ if (end)
+ {
+ if (!Quiet)
+ puts("EOF");
+ IsEmptyQuery = true;
+ exitpg(0);
+ }
+
+ /* ----------------
+ * otherwise we have a user query so process it.
+ * ----------------
+ */
+ break;
+ }
+
+ /* ----------------
+ * if the query echo flag was given, print the query..
+ * ----------------
+ */
+ if (EchoQuery)
+ printf("query is: %s\n", inBuf);
+
+ return ('Q');
}
/* ----------------
- * SocketBackend() Is called for frontend-backend connections
+ * SocketBackend() Is called for frontend-backend connections
*
- * If the input is a query (case 'Q') then the string entered by
- * the user is placed in its parameter inBuf.
+ * If the input is a query (case 'Q') then the string entered by
+ * the user is placed in its parameter inBuf.
*
- * If the input is a fastpath function call (case 'F') then
- * the function call is processed in HandleFunctionRequest().
- * (now called from PostgresMain())
+ * If the input is a fastpath function call (case 'F') then
+ * the function call is processed in HandleFunctionRequest().
+ * (now called from PostgresMain())
* ----------------
*/
static char
SocketBackend(char *inBuf, bool multiplexedBackend)
{
- char qtype[2];
- char result = '\0';
-
- /* ----------------
- * get input from the frontend
- * ----------------
- */
- strcpy(qtype, "?");
- if (pq_getnchar(qtype,0,1) == EOF) {
- /* ------------
- * when front-end applications quits/dies
- * ------------
- */
- if (multiplexedBackend) {
- return 'X';
- }
- else
- exitpg(0);
- }
-
- switch(*qtype) {
- /* ----------------
- * 'Q': user entered a query
- * ----------------
- */
- case 'Q':
- pq_getstr(inBuf, MAX_PARSE_BUFFER);
- result = 'Q';
- break;
-
- /* ----------------
- * 'F': calling user/system functions
- * ----------------
- */
- case 'F':
- pq_getstr(inBuf, MAX_PARSE_BUFFER);/* ignore the rest of the line */
- result = 'F';
- break;
-
- /* ----------------
- * 'X': frontend is exiting
- * ----------------
- */
- case 'X':
- result = 'X';
- break;
-
- /* ----------------
- * otherwise we got garbage from the frontend.
- *
- * XXX are we certain that we want to do an elog(FATAL) here?
- * -cim 1/24/90
- * ----------------
- */
- default:
- elog(FATAL, "Socket command type %c unknown\n", *qtype);
- break;
- }
- return result;
+ char qtype[2];
+ char result = '\0';
+
+ /* ----------------
+ * get input from the frontend
+ * ----------------
+ */
+ strcpy(qtype, "?");
+ if (pq_getnchar(qtype, 0, 1) == EOF)
+ {
+ /* ------------
+ * when front-end applications quits/dies
+ * ------------
+ */
+ if (multiplexedBackend)
+ {
+ return 'X';
+ }
+ else
+ exitpg(0);
+ }
+
+ switch (*qtype)
+ {
+ /* ----------------
+ * 'Q': user entered a query
+ * ----------------
+ */
+ case 'Q':
+ pq_getstr(inBuf, MAX_PARSE_BUFFER);
+ result = 'Q';
+ break;
+
+ /* ----------------
+ * 'F': calling user/system functions
+ * ----------------
+ */
+ case 'F':
+ pq_getstr(inBuf, MAX_PARSE_BUFFER); /* ignore the rest of the
+ * line */
+ result = 'F';
+ break;
+
+ /* ----------------
+ * 'X': frontend is exiting
+ * ----------------
+ */
+ case 'X':
+ result = 'X';
+ break;
+
+ /* ----------------
+ * otherwise we got garbage from the frontend.
+ *
+ * XXX are we certain that we want to do an elog(FATAL) here?
+ * -cim 1/24/90
+ * ----------------
+ */
+ default:
+ elog(FATAL, "Socket command type %c unknown\n", *qtype);
+ break;
+ }
+ return result;
}
/* ----------------
- * ReadCommand reads a command from either the frontend or
- * standard input, places it in inBuf, and returns a char
- * representing whether the string is a 'Q'uery or a 'F'astpath
- * call.
+ * ReadCommand reads a command from either the frontend or
+ * standard input, places it in inBuf, and returns a char
+ * representing whether the string is a 'Q'uery or a 'F'astpath
+ * call.
* ----------------
*/
static char
ReadCommand(char *inBuf, bool multiplexedBackend)
{
- if (IsUnderPostmaster || multiplexedBackend)
- return SocketBackend(inBuf, multiplexedBackend);
- else
- return InteractiveBackend(inBuf);
+ if (IsUnderPostmaster || multiplexedBackend)
+ return SocketBackend(inBuf, multiplexedBackend);
+ else
+ return InteractiveBackend(inBuf);
}
-List *
-pg_plan(char *query_string, /* string to execute */
- Oid *typev, /* argument types */
- int nargs, /* number of arguments */
- QueryTreeList **queryListP, /* pointer to the parse trees */
- CommandDest dest) /* where results should go */
+List *
+pg_plan(char *query_string, /* string to execute */
+ Oid * typev, /* argument types */
+ int nargs, /* number of arguments */
+ QueryTreeList ** queryListP, /* pointer to the parse trees */
+ CommandDest dest) /* where results should go */
{
- QueryTreeList *querytree_list;
- int i;
- List *plan_list = NIL;
- Plan *plan;
- int j;
- QueryTreeList *new_list;
- List *rewritten = NIL;
- Query* querytree;
-
- /* ----------------
- * (1) parse the request string into a list of parse trees
- * ----------------
- */
- if (ShowParserStats)
- ResetUsage();
-
- querytree_list = parser(query_string, typev, nargs);
-
- if (ShowParserStats) {
- fprintf(stderr, "! Parser Stats:\n");
- ShowUsage();
- }
-
- /* new_list holds the rewritten queries */
- new_list = (QueryTreeList*)malloc(sizeof(QueryTreeList));
- new_list->len = querytree_list->len;
- new_list->qtrees = (Query**)malloc(new_list->len * sizeof(Query*));
-
- /* ----------------
- * (2) rewrite the queries, as necessary
- * ----------------
- */
- j = 0; /* counter for the new_list, new_list can be longer than
- old list as a result of rewrites */
- for (i=0;i<querytree_list->len;i++) {
- querytree = querytree_list->qtrees[i];
-
-
- /* don't rewrite utilites */
- if (querytree->commandType == CMD_UTILITY) {
- new_list->qtrees[j++] = querytree;
- continue;
- }
-
- if ( DebugPrintQuery == true ) {
- printf("\n---- \tquery is:\n%s\n",query_string);
- printf("\n");
- fflush(stdout);
- }
-
- if ( DebugPrintParse == true ) {
- printf("\n---- \tparser outputs :\n");
- nodeDisplay(querytree);
- printf("\n");
- }
-
- /* rewrite queries (retrieve, append, delete, replace) */
- rewritten = QueryRewrite(querytree);
- if (rewritten != NULL) {
- int len, k;
- len = length(rewritten);
- if (len == 1)
- new_list->qtrees[j++] = (Query*)lfirst(rewritten);
- else {
- /* rewritten queries are longer than original query */
- /* grow the new_list to accommodate */
- new_list->len += len - 1; /* - 1 because originally we
- allocated one space for the query */
- new_list->qtrees = realloc(new_list->qtrees,
- new_list->len * sizeof(Query*));
- for (k=0;k<len;k++)
- new_list->qtrees[j++] = (Query*)nth(k, rewritten);
- }
- }
- }
-
- /* we're done with the original lists, free it */
- free(querytree_list->qtrees);
- free(querytree_list);
-
- querytree_list = new_list;
-
- /* ----------------
- * Fix time range quals
- * this _must_ go here, because it must take place after rewrites
- * ( if they take place ) so that time quals are usable by the executor
- *
- * Also, need to frob the range table entries here to plan union
- * queries for archived relations.
- * ----------------
- */
- for (i=0;i<querytree_list->len;i++) {
- List *l;
- List *rt = NULL;
-
- querytree = querytree_list->qtrees[i];
-
- /* ----------------
- * utilities don't have time ranges
- * ----------------
- */
- if (querytree->commandType == CMD_UTILITY)
- continue;
-
- rt = querytree->rtable;
-
- foreach (l, rt) {
- RangeTblEntry *rte = lfirst(l);
- TimeRange *timequal = rte->timeRange;
-
- if (timequal) {
- int timecode = (rte->timeRange->endDate == NULL)? 0 : 1;
-
- rte->timeQual = makeTimeRange(rte->timeRange->startDate,
- rte->timeRange->endDate,
- timecode);
- }else {
- rte->timeQual = NULL;
- }
- }
-
- /* check for archived relations */
- plan_archive(rt);
- }
-
- if (DebugPrintRewrittenParsetree == true) {
- printf("\n---- \tafter rewriting:\n");
-
- for (i=0; i<querytree_list->len; i++) {
- print(querytree_list->qtrees[i]);
- printf("\n");
- }
- }
-
- for (i=0; i<querytree_list->len;i++) {
- querytree = querytree_list->qtrees[i];
-
- /*
- * For each query that isn't a utility invocation,
- * generate a plan.
- */
-
- if (querytree->commandType != CMD_UTILITY) {
-
- if (IsAbortedTransactionBlockState()) {
- /* ----------------
- * the EndCommand() stuff is to tell the frontend
- * that the command ended. -cim 6/1/90
- * ----------------
- */
- char *tag = "*ABORT STATE*";
- EndCommand(tag, dest);
-
- elog(NOTICE, "(transaction aborted): %s",
- "queries ignored until END");
-
- *queryListP = (QueryTreeList*)NULL;
- return (List*)NULL;
- }
-
- if (ShowPlannerStats) ResetUsage();
- plan = planner(querytree);
- if (ShowPlannerStats) {
- fprintf(stderr, "! Planner Stats:\n");
- ShowUsage();
- }
- plan_list = lappend(plan_list, plan);
+ QueryTreeList *querytree_list;
+ int i;
+ List *plan_list = NIL;
+ Plan *plan;
+ int j;
+ QueryTreeList *new_list;
+ List *rewritten = NIL;
+ Query *querytree;
+
+ /* ----------------
+ * (1) parse the request string into a list of parse trees
+ * ----------------
+ */
+ if (ShowParserStats)
+ ResetUsage();
+
+ querytree_list = parser(query_string, typev, nargs);
+
+ if (ShowParserStats)
+ {
+ fprintf(stderr, "! Parser Stats:\n");
+ ShowUsage();
+ }
+
+ /* new_list holds the rewritten queries */
+ new_list = (QueryTreeList *) malloc(sizeof(QueryTreeList));
+ new_list->len = querytree_list->len;
+ new_list->qtrees = (Query **) malloc(new_list->len * sizeof(Query *));
+
+ /* ----------------
+ * (2) rewrite the queries, as necessary
+ * ----------------
+ */
+ j = 0; /* counter for the new_list, new_list can
+ * be longer than old list as a result of
+ * rewrites */
+ for (i = 0; i < querytree_list->len; i++)
+ {
+ querytree = querytree_list->qtrees[i];
+
+
+ /* don't rewrite utilites */
+ if (querytree->commandType == CMD_UTILITY)
+ {
+ new_list->qtrees[j++] = querytree;
+ continue;
+ }
+
+ if (DebugPrintQuery == true)
+ {
+ printf("\n---- \tquery is:\n%s\n", query_string);
+ printf("\n");
+ fflush(stdout);
+ }
+
+ if (DebugPrintParse == true)
+ {
+ printf("\n---- \tparser outputs :\n");
+ nodeDisplay(querytree);
+ printf("\n");
+ }
+
+ /* rewrite queries (retrieve, append, delete, replace) */
+ rewritten = QueryRewrite(querytree);
+ if (rewritten != NULL)
+ {
+ int len,
+ k;
+
+ len = length(rewritten);
+ if (len == 1)
+ new_list->qtrees[j++] = (Query *) lfirst(rewritten);
+ else
+ {
+ /* rewritten queries are longer than original query */
+ /* grow the new_list to accommodate */
+ new_list->len += len - 1; /* - 1 because originally
+ * we allocated one space
+ * for the query */
+ new_list->qtrees = realloc(new_list->qtrees,
+ new_list->len * sizeof(Query *));
+ for (k = 0; k < len; k++)
+ new_list->qtrees[j++] = (Query *) nth(k, rewritten);
+ }
+ }
+ }
+
+ /* we're done with the original lists, free it */
+ free(querytree_list->qtrees);
+ free(querytree_list);
+
+ querytree_list = new_list;
+
+ /* ----------------
+ * Fix time range quals
+ * this _must_ go here, because it must take place after rewrites
+ * ( if they take place ) so that time quals are usable by the executor
+ *
+ * Also, need to frob the range table entries here to plan union
+ * queries for archived relations.
+ * ----------------
+ */
+ for (i = 0; i < querytree_list->len; i++)
+ {
+ List *l;
+ List *rt = NULL;
+
+ querytree = querytree_list->qtrees[i];
+
+ /* ----------------
+ * utilities don't have time ranges
+ * ----------------
+ */
+ if (querytree->commandType == CMD_UTILITY)
+ continue;
+
+ rt = querytree->rtable;
+
+ foreach(l, rt)
+ {
+ RangeTblEntry *rte = lfirst(l);
+ TimeRange *timequal = rte->timeRange;
+
+ if (timequal)
+ {
+ int timecode = (rte->timeRange->endDate == NULL) ? 0 : 1;
+
+ rte->timeQual = makeTimeRange(rte->timeRange->startDate,
+ rte->timeRange->endDate,
+ timecode);
+ }
+ else
+ {
+ rte->timeQual = NULL;
+ }
+ }
+
+ /* check for archived relations */
+ plan_archive(rt);
+ }
+
+ if (DebugPrintRewrittenParsetree == true)
+ {
+ printf("\n---- \tafter rewriting:\n");
+
+ for (i = 0; i < querytree_list->len; i++)
+ {
+ print(querytree_list->qtrees[i]);
+ printf("\n");
+ }
+ }
+
+ for (i = 0; i < querytree_list->len; i++)
+ {
+ querytree = querytree_list->qtrees[i];
+
+ /*
+ * For each query that isn't a utility invocation, generate a
+ * plan.
+ */
+
+ if (querytree->commandType != CMD_UTILITY)
+ {
+
+ if (IsAbortedTransactionBlockState())
+ {
+ /* ----------------
+ * the EndCommand() stuff is to tell the frontend
+ * that the command ended. -cim 6/1/90
+ * ----------------
+ */
+ char *tag = "*ABORT STATE*";
+
+ EndCommand(tag, dest);
+
+ elog(NOTICE, "(transaction aborted): %s",
+ "queries ignored until END");
+
+ *queryListP = (QueryTreeList *) NULL;
+ return (List *) NULL;
+ }
+
+ if (ShowPlannerStats)
+ ResetUsage();
+ plan = planner(querytree);
+ if (ShowPlannerStats)
+ {
+ fprintf(stderr, "! Planner Stats:\n");
+ ShowUsage();
+ }
+ plan_list = lappend(plan_list, plan);
#ifdef INDEXSCAN_PATCH
- /* ----------------
- * Print plan if debugging.
- * This has been moved here to get debugging output
- * also for queries in functions. DZ - 27-8-1996
- * ----------------
- */
- if ( DebugPrintPlan == true ) {
- printf("\n---- \tplan is :\n");
- nodeDisplay(plan);
- printf("\n");
- }
+ /* ----------------
+ * Print plan if debugging.
+ * This has been moved here to get debugging output
+ * also for queries in functions. DZ - 27-8-1996
+ * ----------------
+ */
+ if (DebugPrintPlan == true)
+ {
+ printf("\n---- \tplan is :\n");
+ nodeDisplay(plan);
+ printf("\n");
+ }
#endif
- }
+ }
#ifdef FUNC_UTIL_PATCH
- /*
- * If the command is an utility append a null plan. This is
- * needed to keep the plan_list aligned with the querytree_list
- * or the function executor will crash. DZ - 30-8-1996
- */
- else {
- plan_list = lappend(plan_list, NULL);
- }
+
+ /*
+ * If the command is an utility append a null plan. This is needed
+ * to keep the plan_list aligned with the querytree_list or the
+ * function executor will crash. DZ - 30-8-1996
+ */
+ else
+ {
+ plan_list = lappend(plan_list, NULL);
+ }
#endif
- }
-
- if (queryListP)
- *queryListP = querytree_list;
-
- return (plan_list);
+ }
+
+ if (queryListP)
+ *queryListP = querytree_list;
+
+ return (plan_list);
}
/* ----------------------------------------------------------------
- * pg_eval()
- *
- * Takes a querystring, runs the parser/utilities or
- * parser/planner/executor over it as necessary
- * Begin Transaction Should have been called before this
- * and CommitTransaction After this is called
- * This is strictly because we do not allow for nested xactions.
+ * pg_eval()
+ *
+ * Takes a querystring, runs the parser/utilities or
+ * parser/planner/executor over it as necessary
+ * Begin Transaction Should have been called before this
+ * and CommitTransaction After this is called
+ * This is strictly because we do not allow for nested xactions.
*
- * NON-OBVIOUS-RESTRICTIONS
- * this function _MUST_ allocate a new "parsetree" each time,
- * since it may be stored in a named portal and should not
- * change its value.
+ * NON-OBVIOUS-RESTRICTIONS
+ * this function _MUST_ allocate a new "parsetree" each time,
+ * since it may be stored in a named portal and should not
+ * change its value.
*
* ----------------------------------------------------------------
*/
void
-pg_eval(char *query_string, char **argv, Oid *typev, int nargs)
+pg_eval(char *query_string, char **argv, Oid * typev, int nargs)
{
- pg_eval_dest(query_string, argv, typev, nargs, whereToSendOutput);
+ pg_eval_dest(query_string, argv, typev, nargs, whereToSendOutput);
}
void
-pg_eval_dest(char *query_string, /* string to execute */
- char **argv, /* arguments */
- Oid *typev, /* argument types */
- int nargs, /* number of arguments */
- CommandDest dest) /* where results should go */
+pg_eval_dest(char *query_string,/* string to execute */
+ char **argv, /* arguments */
+ Oid * typev, /* argument types */
+ int nargs, /* number of arguments */
+ CommandDest dest) /* where results should go */
{
- List *plan_list;
- Plan *plan;
- Query *querytree;
- int i,j;
- QueryTreeList *querytree_list;
-
- /* plan the queries */
- plan_list = pg_plan(query_string, typev, nargs, &querytree_list, dest);
-
- /* pg_plan could have failed */
- if (querytree_list == NULL)
- return;
-
- for (i=0;i<querytree_list->len;i++) {
- querytree = querytree_list->qtrees[i];
-
+ List *plan_list;
+ Plan *plan;
+ Query *querytree;
+ int i,
+ j;
+ QueryTreeList *querytree_list;
+
+ /* plan the queries */
+ plan_list = pg_plan(query_string, typev, nargs, &querytree_list, dest);
+
+ /* pg_plan could have failed */
+ if (querytree_list == NULL)
+ return;
+
+ for (i = 0; i < querytree_list->len; i++)
+ {
+ querytree = querytree_list->qtrees[i];
+
#ifdef FUNC_UTIL_PATCH
- /*
- * Advance on the plan_list in every case. Now the plan_list
- * has the same length of the querytree_list. DZ - 30-8-1996
- */
- plan = (Plan *) lfirst(plan_list);
- plan_list = lnext(plan_list);
+
+ /*
+ * Advance on the plan_list in every case. Now the plan_list has
+ * the same length of the querytree_list. DZ - 30-8-1996
+ */
+ plan = (Plan *) lfirst(plan_list);
+ plan_list = lnext(plan_list);
#endif
- if (querytree->commandType == CMD_UTILITY) {
- /* ----------------
- * process utility functions (create, destroy, etc..)
- *
- * Note: we do not check for the transaction aborted state
- * because that is done in ProcessUtility.
- * ----------------
- */
- if (! Quiet) {
- time(&tim);
- printf("\tProcessUtility() at %s\n", ctime(&tim));
- }
-
- ProcessUtility(querytree->utilityStmt, dest);
-
- } else {
+ if (querytree->commandType == CMD_UTILITY)
+ {
+ /* ----------------
+ * process utility functions (create, destroy, etc..)
+ *
+ * Note: we do not check for the transaction aborted state
+ * because that is done in ProcessUtility.
+ * ----------------
+ */
+ if (!Quiet)
+ {
+ time(&tim);
+ printf("\tProcessUtility() at %s\n", ctime(&tim));
+ }
+
+ ProcessUtility(querytree->utilityStmt, dest);
+
+ }
+ else
+ {
#ifndef FUNC_UTIL_PATCH
- /*
- * Moved before the if. DZ - 30-8-1996
- */
- plan = (Plan *) lfirst(plan_list);
- plan_list = lnext(plan_list);
+
+ /*
+ * Moved before the if. DZ - 30-8-1996
+ */
+ plan = (Plan *) lfirst(plan_list);
+ plan_list = lnext(plan_list);
#endif
-
+
#ifdef INDEXSCAN_PATCH
- /*
- * Print moved in pg_plan. DZ - 27-8-1996
- */
+
+ /*
+ * Print moved in pg_plan. DZ - 27-8-1996
+ */
#else
- /* ----------------
- * print plan if debugging
- * ----------------
- */
- if ( DebugPrintPlan == true ) {
- printf("\n---- plan is :\n");
- nodeDisplay(plan);
- printf("\n");
- }
+ /* ----------------
+ * print plan if debugging
+ * ----------------
+ */
+ if (DebugPrintPlan == true)
+ {
+ printf("\n---- plan is :\n");
+ nodeDisplay(plan);
+ printf("\n");
+ }
#endif
-
- /* ----------------
- * execute the plan
- *
- */
- if (ShowExecutorStats)
- ResetUsage();
-
- for (j = 0; j < _exec_repeat_; j++) {
- if (! Quiet) {
- time(&tim);
- printf("\tProcessQuery() at %s\n", ctime(&tim));
- }
- ProcessQuery(querytree, plan, argv, typev, nargs, dest);
- }
-
- if (ShowExecutorStats) {
- fprintf(stderr, "! Executor Stats:\n");
- ShowUsage();
- }
- }
- /*
- * In a query block, we want to increment the command counter
- * between queries so that the effects of early queries are
- * visible to subsequent ones.
- */
-
- if (querytree_list)
- CommandCounterIncrement();
- }
-
- free(querytree_list->qtrees);
- free(querytree_list);
+
+ /* ----------------
+ * execute the plan
+ *
+ */
+ if (ShowExecutorStats)
+ ResetUsage();
+
+ for (j = 0; j < _exec_repeat_; j++)
+ {
+ if (!Quiet)
+ {
+ time(&tim);
+ printf("\tProcessQuery() at %s\n", ctime(&tim));
+ }
+ ProcessQuery(querytree, plan, argv, typev, nargs, dest);
+ }
+
+ if (ShowExecutorStats)
+ {
+ fprintf(stderr, "! Executor Stats:\n");
+ ShowUsage();
+ }
+ }
+
+ /*
+ * In a query block, we want to increment the command counter
+ * between queries so that the effects of early queries are
+ * visible to subsequent ones.
+ */
+
+ if (querytree_list)
+ CommandCounterIncrement();
+ }
+
+ free(querytree_list->qtrees);
+ free(querytree_list);
}
/* --------------------------------
- * signal handler routines used in PostgresMain()
+ * signal handler routines used in PostgresMain()
*
- * handle_warn() is used to catch kill(getpid(),1) which
- * occurs when elog(WARN) is called.
+ * handle_warn() is used to catch kill(getpid(),1) which
+ * occurs when elog(WARN) is called.
*
- * quickdie() occurs when signalled by the postmaster, some backend
- * has bought the farm we need to stop what we're doing and exit.
+ * quickdie() occurs when signalled by the postmaster, some backend
+ * has bought the farm we need to stop what we're doing and exit.
*
- * die() preforms an orderly cleanup via ExitPostgres()
+ * die() preforms an orderly cleanup via ExitPostgres()
* --------------------------------
*/
void
handle_warn(SIGNAL_ARGS)
{
- siglongjmp(Warn_restart, 1);
+ siglongjmp(Warn_restart, 1);
}
static void
quickdie(SIGNAL_ARGS)
{
- elog(NOTICE, "I have been signalled by the postmaster.");
- elog(NOTICE, "Some backend process has died unexpectedly and possibly");
- elog(NOTICE, "corrupted shared memory. The current transaction was");
- elog(NOTICE, "aborted, and I am going to exit. Please resend the");
- elog(NOTICE, "last query. -- The postgres backend");
-
- /*
- * DO NOT ExitPostgres(0) -- we're here because shared memory may be
- * corrupted, so we don't want to flush any shared state to stable
- * storage. Just nail the windows shut and get out of town.
- */
-
- exit (0);
+ elog(NOTICE, "I have been signalled by the postmaster.");
+ elog(NOTICE, "Some backend process has died unexpectedly and possibly");
+ elog(NOTICE, "corrupted shared memory. The current transaction was");
+ elog(NOTICE, "aborted, and I am going to exit. Please resend the");
+ elog(NOTICE, "last query. -- The postgres backend");
+
+ /*
+ * DO NOT ExitPostgres(0) -- we're here because shared memory may be
+ * corrupted, so we don't want to flush any shared state to stable
+ * storage. Just nail the windows shut and get out of town.
+ */
+
+ exit(0);
}
void
die(SIGNAL_ARGS)
{
- ExitPostgres(0);
+ ExitPostgres(0);
}
/* signal handler for floating point exception */
static void
FloatExceptionHandler(SIGNAL_ARGS)
{
- elog(WARN, "floating point exception! the last floating point operation eit\
+ elog(WARN, "floating point exception! the last floating point operation eit\
her exceeded legal ranges or was a divide by zero");
}
-static void usage(char* progname)
+static void
+usage(char *progname)
{
- fprintf(stderr,
- "Usage: %s [-B nbufs] [-d lvl] ] [-f plantype] \t[-m portno] [\t -o filename]\n",
- progname);
- fprintf(stderr,"\t[-P portno] [-t tracetype] [-x opttype] [-bCEiLFNopQSs] [dbname]\n");
- fprintf(stderr, " b: consider bushy plan trees during optimization\n");
- fprintf(stderr, " B: set number of buffers in buffer pool\n");
- fprintf(stderr, " C: supress version info\n");
- fprintf(stderr, " d: set debug level\n");
- fprintf(stderr, " E: echo query before execution\n");
- fprintf(stderr, " e turn on European date format\n");
- fprintf(stderr, " F: turn off fsync\n");
- fprintf(stderr, " f: forbid plantype generation\n");
- fprintf(stderr, " i: don't execute the query, just show the plan tree\n");
+ fprintf(stderr,
+ "Usage: %s [-B nbufs] [-d lvl] ] [-f plantype] \t[-m portno] [\t -o filename]\n",
+ progname);
+ fprintf(stderr, "\t[-P portno] [-t tracetype] [-x opttype] [-bCEiLFNopQSs] [dbname]\n");
+ fprintf(stderr, " b: consider bushy plan trees during optimization\n");
+ fprintf(stderr, " B: set number of buffers in buffer pool\n");
+ fprintf(stderr, " C: supress version info\n");
+ fprintf(stderr, " d: set debug level\n");
+ fprintf(stderr, " E: echo query before execution\n");
+ fprintf(stderr, " e turn on European date format\n");
+ fprintf(stderr, " F: turn off fsync\n");
+ fprintf(stderr, " f: forbid plantype generation\n");
+ fprintf(stderr, " i: don't execute the query, just show the plan tree\n");
#ifdef LOCK_MGR_DEBUG
- fprintf(stderr, " K: set locking debug level [0|1|2]\n");
+ fprintf(stderr, " K: set locking debug level [0|1|2]\n");
#endif
- fprintf(stderr, " L: turn off locking\n");
- fprintf(stderr, " m: set up a listening backend at portno to support multiple front-ends\n");
- fprintf(stderr, " M: start as postmaster\n");
- fprintf(stderr, " N: don't use newline as query delimiter\n");
- fprintf(stderr, " o: send stdout and stderr to given filename \n");
- fprintf(stderr, " p: backend started by postmaster\n");
- fprintf(stderr, " P: set port file descriptor\n");
- fprintf(stderr, " Q: suppress informational messages\n");
- fprintf(stderr, " S: set amount of sort memory available\n");
- fprintf(stderr, " s: show stats after each query\n");
- fprintf(stderr, " t: trace component execution times\n");
- fprintf(stderr, " T: execute all possible plans for each query\n");
- fprintf(stderr, " x: control expensive function optimization\n");
+ fprintf(stderr, " L: turn off locking\n");
+ fprintf(stderr, " m: set up a listening backend at portno to support multiple front-ends\n");
+ fprintf(stderr, " M: start as postmaster\n");
+ fprintf(stderr, " N: don't use newline as query delimiter\n");
+ fprintf(stderr, " o: send stdout and stderr to given filename \n");
+ fprintf(stderr, " p: backend started by postmaster\n");
+ fprintf(stderr, " P: set port file descriptor\n");
+ fprintf(stderr, " Q: suppress informational messages\n");
+ fprintf(stderr, " S: set amount of sort memory available\n");
+ fprintf(stderr, " s: show stats after each query\n");
+ fprintf(stderr, " t: trace component execution times\n");
+ fprintf(stderr, " T: execute all possible plans for each query\n");
+ fprintf(stderr, " x: control expensive function optimization\n");
}
/* ----------------------------------------------------------------
- * PostgresMain
- * postgres main loop
- * all backends, interactive or otherwise start here
+ * PostgresMain
+ * postgres main loop
+ * all backends, interactive or otherwise start here
* ----------------------------------------------------------------
*/
int
PostgresMain(int argc, char *argv[])
{
- int flagC;
- int flagQ;
- int flagE;
- int flagEu;
- int flag;
-
- char *DBName = NULL;
- int errs = 0;
-
- char firstchar;
- char parser_input[MAX_PARSE_BUFFER];
- char *userName;
-
- bool multiplexedBackend;
- char* hostName; /* the host name of the backend server */
- char hostbuf[MAXHOSTNAMELEN];
- int serverSock;
- int serverPortnum = 0;
- int nSelected; /* number of descriptors ready from select(); */
- int maxFd = 0; /* max file descriptor + 1 */
- fd_set rmask, basemask;
- FrontEnd *newFE, *currentFE = NULL;
- int numFE = 0; /* keep track of number of active frontends */
- Port *newPort;
- int newFd;
- Dlelem *curr;
- int status;
-
- extern int optind;
- extern char *optarg;
- extern short DebugLvl;
-
- /* ----------------
- * register signal handlers.
- * ----------------
- */
- pqsignal(SIGINT, die);
-
- pqsignal(SIGHUP, die);
- pqsignal(SIGTERM, die);
- pqsignal(SIGPIPE, die);
- pqsignal(SIGUSR1, quickdie);
- pqsignal(SIGUSR2, Async_NotifyHandler);
- pqsignal(SIGFPE, FloatExceptionHandler);
-
- /* --------------------
- * initialize globals
- * -------------------
- */
-
- MasterPid = getpid();
-
- /* ----------------
- * parse command line arguments
- * ----------------
- */
- flagC = flagQ = flagE = flagEu = ShowStats = 0;
- ShowParserStats = ShowPlannerStats = ShowExecutorStats = 0;
+ int flagC;
+ int flagQ;
+ int flagE;
+ int flagEu;
+ int flag;
+
+ char *DBName = NULL;
+ int errs = 0;
+
+ char firstchar;
+ char parser_input[MAX_PARSE_BUFFER];
+ char *userName;
+
+ bool multiplexedBackend;
+ char *hostName; /* the host name of the backend server */
+ char hostbuf[MAXHOSTNAMELEN];
+ int serverSock;
+ int serverPortnum = 0;
+ int nSelected; /* number of descriptors ready from
+ * select(); */
+ int maxFd = 0; /* max file descriptor + 1 */
+ fd_set rmask,
+ basemask;
+ FrontEnd *newFE,
+ *currentFE = NULL;
+ int numFE = 0; /* keep track of number of active
+ * frontends */
+ Port *newPort;
+ int newFd;
+ Dlelem *curr;
+ int status;
+
+ extern int optind;
+ extern char *optarg;
+ extern short DebugLvl;
+
+ /* ----------------
+ * register signal handlers.
+ * ----------------
+ */
+ pqsignal(SIGINT, die);
+
+ pqsignal(SIGHUP, die);
+ pqsignal(SIGTERM, die);
+ pqsignal(SIGPIPE, die);
+ pqsignal(SIGUSR1, quickdie);
+ pqsignal(SIGUSR2, Async_NotifyHandler);
+ pqsignal(SIGFPE, FloatExceptionHandler);
+
+ /* --------------------
+ * initialize globals
+ * -------------------
+ */
+
+ MasterPid = getpid();
+
+ /* ----------------
+ * parse command line arguments
+ * ----------------
+ */
+ flagC = flagQ = flagE = flagEu = ShowStats = 0;
+ ShowParserStats = ShowPlannerStats = ShowExecutorStats = 0;
#ifdef LOCK_MGR_DEBUG
- lockDebug = 0;
+ lockDebug = 0;
#endif
- /* get hostname is either the environment variable PGHOST
- or 'localhost' */
- if (!(hostName = getenv("PGHOST"))) {
- if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
- strcpy(hostbuf, "localhost");
- hostName = hostbuf;
- }
-
- DataDir = getenv("PGDATA"); /* default */
- multiplexedBackend = false; /* default */
-
- while ((flag = getopt(argc, argv, "B:bCD:d:Eef:iK:Lm:MNo:P:pQSst:x:F"))
- != EOF)
- switch (flag) {
-
- case 'b':
- /* ----------------
- * set BushyPlanFlag to true.
- * ----------------
- */
- BushyPlanFlag = 1;
- break;
- case 'B':
- /* ----------------
- * specify the size of buffer pool
- * ----------------
- */
- NBuffers = atoi(optarg);
- break;
-
- case 'C':
- /* ----------------
- * don't print version string (don't know why this is 'C' --mao)
- * ----------------
- */
- flagC = 1;
- break;
-
- case 'D': /* PGDATA directory */
- DataDir = optarg;
-
- case 'd': /* debug level */
- flagQ = 0;
- DebugLvl = (short)atoi(optarg);
- if (DebugLvl > 1)
- DebugPrintQuery = true;
- if (DebugLvl > 2)
- {
- DebugPrintParse = true;
- DebugPrintPlan = true;
- DebugPrintRewrittenParsetree = true;
- }
- break;
-
- case 'E':
- /* ----------------
- * E - echo the query the user entered
- * ----------------
- */
- flagE = 1;
- break;
-
- case 'e':
- /* --------------------------
- * Use european date formats.
- * --------------------------
- */
- flagEu = 1;
- break;
-
- case 'F':
- /* --------------------
- * turn off fsync
- * --------------------
- */
- fsyncOff = 1;
- break;
-
- case 'f':
- /* -----------------
- * f - forbid generation of certain plans
- * -----------------
- */
- switch (optarg[0]) {
- case 's': /* seqscan */
- _enable_seqscan_ = false;
- break;
- case 'i': /* indexscan */
- _enable_indexscan_ = false;
- break;
- case 'n': /* nestloop */
- _enable_nestloop_ = false;
- break;
- case 'm': /* mergejoin */
- _enable_mergesort_ = false;
- break;
- case 'h': /* hashjoin */
- _enable_hashjoin_ = false;
- break;
- default:
- errs++;
- }
- break;
-
- case 'i':
- dontExecute = 1;
- break;
-
- case 'K':
+ /*
+ * get hostname is either the environment variable PGHOST or
+ * 'localhost'
+ */
+ if (!(hostName = getenv("PGHOST")))
+ {
+ if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
+ strcpy(hostbuf, "localhost");
+ hostName = hostbuf;
+ }
+
+ DataDir = getenv("PGDATA"); /* default */
+ multiplexedBackend = false; /* default */
+
+ while ((flag = getopt(argc, argv, "B:bCD:d:Eef:iK:Lm:MNo:P:pQSst:x:F"))
+ != EOF)
+ switch (flag)
+ {
+
+ case 'b':
+ /* ----------------
+ * set BushyPlanFlag to true.
+ * ----------------
+ */
+ BushyPlanFlag = 1;
+ break;
+ case 'B':
+ /* ----------------
+ * specify the size of buffer pool
+ * ----------------
+ */
+ NBuffers = atoi(optarg);
+ break;
+
+ case 'C':
+ /* ----------------
+ * don't print version string (don't know why this is 'C' --mao)
+ * ----------------
+ */
+ flagC = 1;
+ break;
+
+ case 'D': /* PGDATA directory */
+ DataDir = optarg;
+
+ case 'd': /* debug level */
+ flagQ = 0;
+ DebugLvl = (short) atoi(optarg);
+ if (DebugLvl > 1)
+ DebugPrintQuery = true;
+ if (DebugLvl > 2)
+ {
+ DebugPrintParse = true;
+ DebugPrintPlan = true;
+ DebugPrintRewrittenParsetree = true;
+ }
+ break;
+
+ case 'E':
+ /* ----------------
+ * E - echo the query the user entered
+ * ----------------
+ */
+ flagE = 1;
+ break;
+
+ case 'e':
+ /* --------------------------
+ * Use european date formats.
+ * --------------------------
+ */
+ flagEu = 1;
+ break;
+
+ case 'F':
+ /* --------------------
+ * turn off fsync
+ * --------------------
+ */
+ fsyncOff = 1;
+ break;
+
+ case 'f':
+ /* -----------------
+ * f - forbid generation of certain plans
+ * -----------------
+ */
+ switch (optarg[0])
+ {
+ case 's': /* seqscan */
+ _enable_seqscan_ = false;
+ break;
+ case 'i': /* indexscan */
+ _enable_indexscan_ = false;
+ break;
+ case 'n': /* nestloop */
+ _enable_nestloop_ = false;
+ break;
+ case 'm': /* mergejoin */
+ _enable_mergesort_ = false;
+ break;
+ case 'h': /* hashjoin */
+ _enable_hashjoin_ = false;
+ break;
+ default:
+ errs++;
+ }
+ break;
+
+ case 'i':
+ dontExecute = 1;
+ break;
+
+ case 'K':
#ifdef LOCK_MGR_DEBUG
- lockDebug = atoi(optarg);
+ lockDebug = atoi(optarg);
#else
- fprintf(stderr, "Lock debug not compiled in\n");
+ fprintf(stderr, "Lock debug not compiled in\n");
#endif
- break;
-
- case 'L':
- /* --------------------
- * turn off locking
- * --------------------
- */
- lockingOff = 1;
- break;
-
- case 'm':
- /* start up a listening backend that can respond to
- multiple front-ends. (Note: all the front-end connections
- are still connected to a single-threaded backend. Requests
- are FCFS. Everything is in one transaction
- */
- multiplexedBackend = true;
- serverPortnum = atoi(optarg);
- break;
- case 'M':
- exit(PostmasterMain(argc, argv));
- break;
- case 'N':
- /* ----------------
- * N - Don't use newline as a query delimiter
- * ----------------
- */
- UseNewLine = 0;
- break;
-
- case 'o':
- /* ----------------
- * o - send output (stdout and stderr) to the given file
- * ----------------
- */
- strNcpy(OutputFileName, optarg, MAXPGPATH);
- break;
-
- case 'p': /* started by postmaster */
- /* ----------------
- * p - special flag passed if backend was forked
- * by a postmaster.
- * ----------------
- */
- IsUnderPostmaster = true;
- break;
-
- case 'P':
- /* ----------------
- * P - Use the passed file descriptor number as the port
- * on which to communicate with the user. This is ONLY
- * useful for debugging when fired up by the postmaster.
- * ----------------
- */
- Portfd = atoi(optarg);
- break;
-
- case 'Q':
- /* ----------------
- * Q - set Quiet mode (reduce debugging output)
- * ----------------
- */
- flagQ = 1;
- break;
-
- case 'S':
- /* ----------------
- * S - amount of sort memory to use in 1k bytes
- * ----------------
- */
- SortMem = atoi(optarg);
- break;
-
- case 's':
- /* ----------------
- * s - report usage statistics (timings) after each query
- * ----------------
- */
- ShowStats = 1;
- StatFp = stderr;
- break;
-
- case 't':
- /* ----------------
- * tell postgres to report usage statistics (timings) for
- * each query
- *
- * -tpa[rser] = print stats for parser time of each query
- * -tpl[anner] = print stats for planner time of each query
- * -te[xecutor] = print stats for executor time of each query
- * caution: -s can not be used together with -t.
- * ----------------
- */
- StatFp = stderr;
- switch (optarg[0]) {
- case 'p': if (optarg[1] == 'a')
- ShowParserStats = 1;
- else if (optarg[1] == 'l')
- ShowPlannerStats = 1;
- else
- errs++;
- break;
- case 'e': ShowExecutorStats = 1; break;
- default: errs++; break;
- }
- break;
-
- case 'x':
-#if 0 /* planner/xfunc.h */
- /* control joey hellerstein's expensive function optimization */
- if (XfuncMode != 0)
- {
- fprintf(stderr, "only one -x flag is allowed\n");
- errs++;
- break;
- }
- if (strcmp(optarg, "off") == 0)
- XfuncMode = XFUNC_OFF;
- else if (strcmp(optarg, "nor") == 0)
- XfuncMode = XFUNC_NOR;
- else if (strcmp(optarg, "nopull") == 0)
- XfuncMode = XFUNC_NOPULL;
- else if (strcmp(optarg, "nopm") == 0)
- XfuncMode = XFUNC_NOPM;
- else if (strcmp(optarg, "pullall") == 0)
- XfuncMode = XFUNC_PULLALL;
- else if (strcmp(optarg, "wait") == 0)
- XfuncMode = XFUNC_WAIT;
- else {
- fprintf(stderr, "use -x {off,nor,nopull,nopm,pullall,wait}\n");
- errs++;
- }
+ break;
+
+ case 'L':
+ /* --------------------
+ * turn off locking
+ * --------------------
+ */
+ lockingOff = 1;
+ break;
+
+ case 'm':
+
+ /*
+ * start up a listening backend that can respond to multiple
+ * front-ends. (Note: all the front-end connections are
+ * still connected to a single-threaded backend. Requests are
+ * FCFS. Everything is in one transaction
+ */
+ multiplexedBackend = true;
+ serverPortnum = atoi(optarg);
+ break;
+ case 'M':
+ exit(PostmasterMain(argc, argv));
+ break;
+ case 'N':
+ /* ----------------
+ * N - Don't use newline as a query delimiter
+ * ----------------
+ */
+ UseNewLine = 0;
+ break;
+
+ case 'o':
+ /* ----------------
+ * o - send output (stdout and stderr) to the given file
+ * ----------------
+ */
+ strNcpy(OutputFileName, optarg, MAXPGPATH);
+ break;
+
+ case 'p': /* started by postmaster */
+ /* ----------------
+ * p - special flag passed if backend was forked
+ * by a postmaster.
+ * ----------------
+ */
+ IsUnderPostmaster = true;
+ break;
+
+ case 'P':
+ /* ----------------
+ * P - Use the passed file descriptor number as the port
+ * on which to communicate with the user. This is ONLY
+ * useful for debugging when fired up by the postmaster.
+ * ----------------
+ */
+ Portfd = atoi(optarg);
+ break;
+
+ case 'Q':
+ /* ----------------
+ * Q - set Quiet mode (reduce debugging output)
+ * ----------------
+ */
+ flagQ = 1;
+ break;
+
+ case 'S':
+ /* ----------------
+ * S - amount of sort memory to use in 1k bytes
+ * ----------------
+ */
+ SortMem = atoi(optarg);
+ break;
+
+ case 's':
+ /* ----------------
+ * s - report usage statistics (timings) after each query
+ * ----------------
+ */
+ ShowStats = 1;
+ StatFp = stderr;
+ break;
+
+ case 't':
+ /* ----------------
+ * tell postgres to report usage statistics (timings) for
+ * each query
+ *
+ * -tpa[rser] = print stats for parser time of each query
+ * -tpl[anner] = print stats for planner time of each query
+ * -te[xecutor] = print stats for executor time of each query
+ * caution: -s can not be used together with -t.
+ * ----------------
+ */
+ StatFp = stderr;
+ switch (optarg[0])
+ {
+ case 'p':
+ if (optarg[1] == 'a')
+ ShowParserStats = 1;
+ else if (optarg[1] == 'l')
+ ShowPlannerStats = 1;
+ else
+ errs++;
+ break;
+ case 'e':
+ ShowExecutorStats = 1;
+ break;
+ default:
+ errs++;
+ break;
+ }
+ break;
+
+ case 'x':
+#if 0 /* planner/xfunc.h */
+ /* control joey hellerstein's expensive function optimization */
+ if (XfuncMode != 0)
+ {
+ fprintf(stderr, "only one -x flag is allowed\n");
+ errs++;
+ break;
+ }
+ if (strcmp(optarg, "off") == 0)
+ XfuncMode = XFUNC_OFF;
+ else if (strcmp(optarg, "nor") == 0)
+ XfuncMode = XFUNC_NOR;
+ else if (strcmp(optarg, "nopull") == 0)
+ XfuncMode = XFUNC_NOPULL;
+ else if (strcmp(optarg, "nopm") == 0)
+ XfuncMode = XFUNC_NOPM;
+ else if (strcmp(optarg, "pullall") == 0)
+ XfuncMode = XFUNC_PULLALL;
+ else if (strcmp(optarg, "wait") == 0)
+ XfuncMode = XFUNC_WAIT;
+ else
+ {
+ fprintf(stderr, "use -x {off,nor,nopull,nopm,pullall,wait}\n");
+ errs++;
+ }
#endif
- break;
-
- default:
- /* ----------------
- * default: bad command line option
- * ----------------
- */
- errs++;
- }
-
- /* ----------------
- * get user name and pathname and check command line validity
- * ----------------
- */
- SetPgUserName();
- userName = GetPgUserName();
-
- if (FindBackend(pg_pathname, argv[0]) < 0)
- elog(FATAL, "%s: could not locate executable, bailing out...",
- argv[0]);
-
- if (errs || argc - optind > 1) {
- usage (argv[0]);
- exitpg(1);
- } else if (argc - optind == 1) {
- DBName = argv[optind];
- } else if ((DBName = userName) == NULL) {
- fprintf(stderr, "%s: USER undefined and no database specified\n",
- argv[0]);
- exitpg(1);
- }
-
- if (ShowStats &&
- (ShowParserStats || ShowPlannerStats || ShowExecutorStats)) {
- fprintf(stderr, "-s can not be used together with -t.\n");
- exitpg(1);
- }
-
- if (!DataDir) {
- fprintf(stderr, "%s does not know where to find the database system "
- "data. You must specify the directory that contains the "
- "database system either by specifying the -D invocation "
- "option or by setting the PGDATA environment variable.\n\n",
- argv[0]);
- exitpg(1);
- }
-
- Noversion = flagC;
- Quiet = flagQ;
- EchoQuery = flagE;
- EuroDates = flagEu;
-
- /* ----------------
- * print flags
- * ----------------
- */
- if (! Quiet) {
- puts("\t---debug info---");
- printf("\tQuiet = %c\n", Quiet ? 't' : 'f');
- printf("\tNoversion = %c\n", Noversion ? 't' : 'f');
- printf("\ttimings = %c\n", ShowStats ? 't' : 'f');
- printf("\tdates = %s\n", EuroDates ? "European" : "Normal");
- printf("\tbufsize = %d\n", NBuffers);
- printf("\tsortmem = %d\n", SortMem);
-
- printf("\tquery echo = %c\n", EchoQuery ? 't' : 'f');
- printf("\tmultiplexed backend? = %c\n", multiplexedBackend ? 't' : 'f');
- printf("\tDatabaseName = [%s]\n", DBName);
- puts("\t----------------\n");
- }
-
- /* ----------------
- * initialize portal file descriptors
- * ----------------
- */
- if (IsUnderPostmaster == true) {
- if (Portfd < 0) {
- fprintf(stderr,
- "Postmaster flag set: no port number specified, use /dev/null\n");
- Portfd = open(NULL_DEV, O_RDWR, 0666);
- }
- pq_init(Portfd);
- }
-
- if (multiplexedBackend) {
- if (serverPortnum == 0 ||
- StreamServerPort(hostName, serverPortnum, &serverSock) != STATUS_OK)
- {
- fprintf(stderr, "Postgres: cannot create stream port %d\n", serverPortnum);
- exit(1);
- }
+ break;
+
+ default:
+ /* ----------------
+ * default: bad command line option
+ * ----------------
+ */
+ errs++;
+ }
+
+ /* ----------------
+ * get user name and pathname and check command line validity
+ * ----------------
+ */
+ SetPgUserName();
+ userName = GetPgUserName();
+
+ if (FindBackend(pg_pathname, argv[0]) < 0)
+ elog(FATAL, "%s: could not locate executable, bailing out...",
+ argv[0]);
+
+ if (errs || argc - optind > 1)
+ {
+ usage(argv[0]);
+ exitpg(1);
+ }
+ else if (argc - optind == 1)
+ {
+ DBName = argv[optind];
+ }
+ else if ((DBName = userName) == NULL)
+ {
+ fprintf(stderr, "%s: USER undefined and no database specified\n",
+ argv[0]);
+ exitpg(1);
+ }
+
+ if (ShowStats &&
+ (ShowParserStats || ShowPlannerStats || ShowExecutorStats))
+ {
+ fprintf(stderr, "-s can not be used together with -t.\n");
+ exitpg(1);
+ }
+
+ if (!DataDir)
+ {
+ fprintf(stderr, "%s does not know where to find the database system "
+ "data. You must specify the directory that contains the "
+ "database system either by specifying the -D invocation "
+ "option or by setting the PGDATA environment variable.\n\n",
+ argv[0]);
+ exitpg(1);
+ }
+
+ Noversion = flagC;
+ Quiet = flagQ;
+ EchoQuery = flagE;
+ EuroDates = flagEu;
+
+ /* ----------------
+ * print flags
+ * ----------------
+ */
+ if (!Quiet)
+ {
+ puts("\t---debug info---");
+ printf("\tQuiet = %c\n", Quiet ? 't' : 'f');
+ printf("\tNoversion = %c\n", Noversion ? 't' : 'f');
+ printf("\ttimings = %c\n", ShowStats ? 't' : 'f');
+ printf("\tdates = %s\n", EuroDates ? "European" : "Normal");
+ printf("\tbufsize = %d\n", NBuffers);
+ printf("\tsortmem = %d\n", SortMem);
+
+ printf("\tquery echo = %c\n", EchoQuery ? 't' : 'f');
+ printf("\tmultiplexed backend? = %c\n", multiplexedBackend ? 't' : 'f');
+ printf("\tDatabaseName = [%s]\n", DBName);
+ puts("\t----------------\n");
+ }
+
+ /* ----------------
+ * initialize portal file descriptors
+ * ----------------
+ */
+ if (IsUnderPostmaster == true)
+ {
+ if (Portfd < 0)
+ {
+ fprintf(stderr,
+ "Postmaster flag set: no port number specified, use /dev/null\n");
+ Portfd = open(NULL_DEV, O_RDWR, 0666);
+ }
+ pq_init(Portfd);
+ }
+
+ if (multiplexedBackend)
+ {
+ if (serverPortnum == 0 ||
+ StreamServerPort(hostName, serverPortnum, &serverSock) != STATUS_OK)
+ {
+ fprintf(stderr, "Postgres: cannot create stream port %d\n", serverPortnum);
+ exit(1);
+ }
/*
{
- char buf[100];
- sprintf(buf, "stream port %d created, socket = %d\n", serverPortnum, serverSock);
- puts(buf);
+ char buf[100];
+ sprintf(buf, "stream port %d created, socket = %d\n", serverPortnum, serverSock);
+ puts(buf);
}
*/
- FD_ZERO(&rmask);
- FD_ZERO(&basemask);
- FD_SET(serverSock, &basemask);
-
- frontendList = DLNewList();
- /* add the original FrontEnd to the list */
- if (IsUnderPostmaster == true) {
- FrontEnd *fe = malloc(sizeof(FrontEnd));
-
- FD_SET(Portfd, &basemask);
- maxFd = Max(serverSock,Portfd) + 1;
-
- fe->fn_connected = true;
- fe->fn_Pfin = Pfin;
- fe->fn_Pfout = Pfout;
- fe->fn_done = false;
- (fe->fn_port).sock = Portfd;
- DLAddHead(frontendList, DLNewElem(fe));
- numFE++;
- } else {
- numFE = 1;
- maxFd = serverSock + 1;
- }
- }
-
- if (IsUnderPostmaster || multiplexedBackend)
- whereToSendOutput = Remote;
- else
- whereToSendOutput = Debug;
-
- SetProcessingMode(InitProcessing);
-
- /* initialize */
- if (! Quiet) {
- puts("\tInitPostgres()..");
- }
-
- InitPostgres(DBName);
-
- /* ----------------
- * if an exception is encountered, processing resumes here
- * so we abort the current transaction and start a new one.
- * This must be done after we initialize the slave backends
- * so that the slaves signal the master to abort the transaction
- * rather than calling AbortCurrentTransaction() themselves.
- *
- * Note: elog(WARN) causes a kill(getpid(),1) to occur sending
- * us back here.
- * ----------------
- */
-
- pqsignal(SIGHUP, handle_warn);
-
- if (sigsetjmp(Warn_restart, 1) != 0) {
- InWarn = 1;
-
- time(&tim);
-
- if (! Quiet)
- printf("\tAbortCurrentTransaction() at %s\n", ctime(&tim));
-
- memset(parser_input, 0, MAX_PARSE_BUFFER);
-
- AbortCurrentTransaction();
- }
- InWarn = 0;
-
- /* ----------------
- * POSTGRES main processing loop begins here
- * ----------------
- */
- if (IsUnderPostmaster == false) {
- puts("\nPOSTGRES backend interactive interface");
- puts("$Revision: 1.42 $ $Date: 1997/08/19 21:34:04 $");
- }
-
- /* ----------------
- * if stable main memory is assumed (-S(old) flag is set), it is necessary
- * to flush all dirty shared buffers before exit
- * plai 8/7/90
- * ----------------
- */
- if (!TransactionFlushEnabled())
- on_exitpg(FlushBufferPool, (caddr_t) 0);
-
- for (;;) {
-
- if (multiplexedBackend) {
- if (numFE == 0)
- break;
-
- memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set));
- nSelected = select(maxFd, &rmask,0,0,0);
-
- if (nSelected < 0) {
-
- if (errno == EINTR) continue;
- fprintf(stderr,"postgres: multiplexed backend select failed\n");
- exitpg(1);
- }
- if (FD_ISSET(serverSock, &rmask)) {
- /* new connection pending on our well-known port's socket */
- newFE = (FrontEnd*) malloc (sizeof(FrontEnd));
- memset(newFE, 0, sizeof(FrontEnd));
- newFE->fn_connected = false;
- newFE->fn_done = false;
- newPort = &(newFE->fn_port);
- if (StreamConnection(serverSock,newPort) != STATUS_OK) {
- StreamClose(newPort->sock);
- newFd = -1;
- }
- else {
- DLAddHead(frontendList, DLNewElem(newFE));
- numFE++;
- newFd = newPort->sock;
- if (newFd >= maxFd) maxFd = newFd + 1;
- FD_SET(newFd, &rmask);
- FD_SET(newFd, &basemask);
- --nSelected;
- FD_CLR(serverSock, &rmask);
- }
- continue;
- } /* if FD_ISSET(serverSock) */
-
- /* if we get here, it means that the serverSocket was not the one
- selected. Instead, one of the front ends was selected.
- find which one */
- curr = DLGetHead(frontendList);
- while (curr) {
- FrontEnd *fe = (FrontEnd*)DLE_VAL(curr);
- Port *port = &(fe->fn_port);
-
- /* this is lifted from postmaster.c */
- if (FD_ISSET(port->sock, &rmask)) {
- if (fe->fn_connected == false) {
- /* we have a message from a new frontEnd */
- status = PacketReceive(port, &port->buf, NON_BLOCKING);
- if (status == STATUS_OK) {
- fe->fn_connected = true;
- pq_init(port->sock);
- fe->fn_Pfin = Pfin;
- fe->fn_Pfout = Pfout;
- }
- else
- fprintf(stderr,"Multiplexed backend: error in reading packets from %d\n", port->sock);
- }
- else /* we have a query from an existing, active FrontEnd */
- {
- Pfin = fe->fn_Pfin;
- Pfout = fe->fn_Pfout;
- currentFE = fe;
- }
- if (fe->fn_done)
- {
- Dlelem *c = curr;
- curr = DLGetSucc(curr);
- DLRemove(c);
- }
- break;
- }
- else
- curr = DLGetSucc(curr);
- }
- }
- /* ----------------
- * (1) read a command.
- * ----------------
- */
- memset(parser_input, 0, MAX_PARSE_BUFFER);
-
- firstchar = ReadCommand(parser_input, multiplexedBackend);
- /* process the command */
- switch (firstchar) {
- /* ----------------
- * 'F' indicates a fastpath call.
- * XXX HandleFunctionRequest
- * ----------------
- */
- case 'F':
- IsEmptyQuery = false;
-
- /* start an xact for this function invocation */
- if (! Quiet) {
- time(&tim);
- printf("\tStartTransactionCommand() at %s\n", ctime(&tim));
- }
-
- StartTransactionCommand();
- HandleFunctionRequest();
- break;
-
- /* ----------------
- * 'Q' indicates a user query
- * ----------------
- */
- case 'Q':
- fflush(stdout);
-
- if ( strspn(parser_input," \t\n") == strlen(parser_input)) {
- /* ----------------
- * if there is nothing in the input buffer, don't bother
- * trying to parse and execute anything..
- * ----------------
- */
- IsEmptyQuery = true;
- } else {
- /* ----------------
- * otherwise, process the input string.
- * ----------------
- */
- IsEmptyQuery = false;
- if (ShowStats)
- ResetUsage();
-
- /* start an xact for this query */
- if (! Quiet) {
- time(&tim);
- printf("\tStartTransactionCommand() at %s\n", ctime(&tim));
- }
- StartTransactionCommand();
-
- pg_eval(parser_input, (char **) NULL, (Oid *) NULL, 0);
-
- if (ShowStats)
- ShowUsage();
- }
- break;
-
- /* ----------------
- * 'X' means that the frontend is closing down the socket
- * ----------------
- */
- case 'X':
- IsEmptyQuery = true;
- if (multiplexedBackend) {
- FD_CLR(currentFE->fn_port.sock, &basemask);
- currentFE->fn_done = true;
- numFE--;
- }
- pq_close();
- break;
-
- default:
- elog(WARN,"unknown frontend message was recieved");
- }
-
- /* ----------------
- * (3) commit the current transaction
- *
- * Note: if we had an empty input buffer, then we didn't
- * call pg_eval, so we don't bother to commit this transaction.
- * ----------------
- */
- if (! IsEmptyQuery) {
- if (! Quiet) {
- time(&tim);
- printf("\tCommitTransactionCommand() at %s\n", ctime(&tim));
- }
- CommitTransactionCommand();
-
- } else {
- if (IsUnderPostmaster || multiplexedBackend)
- NullCommand(Remote);
- }
-
-} /* infinite for-loop */
- exitpg(0);
- return 1;
+ FD_ZERO(&rmask);
+ FD_ZERO(&basemask);
+ FD_SET(serverSock, &basemask);
+
+ frontendList = DLNewList();
+ /* add the original FrontEnd to the list */
+ if (IsUnderPostmaster == true)
+ {
+ FrontEnd *fe = malloc(sizeof(FrontEnd));
+
+ FD_SET(Portfd, &basemask);
+ maxFd = Max(serverSock, Portfd) + 1;
+
+ fe->fn_connected = true;
+ fe->fn_Pfin = Pfin;
+ fe->fn_Pfout = Pfout;
+ fe->fn_done = false;
+ (fe->fn_port).sock = Portfd;
+ DLAddHead(frontendList, DLNewElem(fe));
+ numFE++;
+ }
+ else
+ {
+ numFE = 1;
+ maxFd = serverSock + 1;
+ }
+ }
+
+ if (IsUnderPostmaster || multiplexedBackend)
+ whereToSendOutput = Remote;
+ else
+ whereToSendOutput = Debug;
+
+ SetProcessingMode(InitProcessing);
+
+ /* initialize */
+ if (!Quiet)
+ {
+ puts("\tInitPostgres()..");
+ }
+
+ InitPostgres(DBName);
+
+ /* ----------------
+ * if an exception is encountered, processing resumes here
+ * so we abort the current transaction and start a new one.
+ * This must be done after we initialize the slave backends
+ * so that the slaves signal the master to abort the transaction
+ * rather than calling AbortCurrentTransaction() themselves.
+ *
+ * Note: elog(WARN) causes a kill(getpid(),1) to occur sending
+ * us back here.
+ * ----------------
+ */
+
+ pqsignal(SIGHUP, handle_warn);
+
+ if (sigsetjmp(Warn_restart, 1) != 0)
+ {
+ InWarn = 1;
+
+ time(&tim);
+
+ if (!Quiet)
+ printf("\tAbortCurrentTransaction() at %s\n", ctime(&tim));
+
+ memset(parser_input, 0, MAX_PARSE_BUFFER);
+
+ AbortCurrentTransaction();
+ }
+ InWarn = 0;
+
+ /* ----------------
+ * POSTGRES main processing loop begins here
+ * ----------------
+ */
+ if (IsUnderPostmaster == false)
+ {
+ puts("\nPOSTGRES backend interactive interface");
+ puts("$Revision: 1.43 $ $Date: 1997/09/07 04:49:33 $");
+ }
+
+ /* ----------------
+ * if stable main memory is assumed (-S(old) flag is set), it is necessary
+ * to flush all dirty shared buffers before exit
+ * plai 8/7/90
+ * ----------------
+ */
+ if (!TransactionFlushEnabled())
+ on_exitpg(FlushBufferPool, (caddr_t) 0);
+
+ for (;;)
+ {
+
+ if (multiplexedBackend)
+ {
+ if (numFE == 0)
+ break;
+
+ memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set));
+ nSelected = select(maxFd, &rmask, 0, 0, 0);
+
+ if (nSelected < 0)
+ {
+
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "postgres: multiplexed backend select failed\n");
+ exitpg(1);
+ }
+ if (FD_ISSET(serverSock, &rmask))
+ {
+ /* new connection pending on our well-known port's socket */
+ newFE = (FrontEnd *) malloc(sizeof(FrontEnd));
+ memset(newFE, 0, sizeof(FrontEnd));
+ newFE->fn_connected = false;
+ newFE->fn_done = false;
+ newPort = &(newFE->fn_port);
+ if (StreamConnection(serverSock, newPort) != STATUS_OK)
+ {
+ StreamClose(newPort->sock);
+ newFd = -1;
+ }
+ else
+ {
+ DLAddHead(frontendList, DLNewElem(newFE));
+ numFE++;
+ newFd = newPort->sock;
+ if (newFd >= maxFd)
+ maxFd = newFd + 1;
+ FD_SET(newFd, &rmask);
+ FD_SET(newFd, &basemask);
+ --nSelected;
+ FD_CLR(serverSock, &rmask);
+ }
+ continue;
+ } /* if FD_ISSET(serverSock) */
+
+ /*
+ * if we get here, it means that the serverSocket was not the
+ * one selected. Instead, one of the front ends was selected.
+ * find which one
+ */
+ curr = DLGetHead(frontendList);
+ while (curr)
+ {
+ FrontEnd *fe = (FrontEnd *) DLE_VAL(curr);
+ Port *port = &(fe->fn_port);
+
+ /* this is lifted from postmaster.c */
+ if (FD_ISSET(port->sock, &rmask))
+ {
+ if (fe->fn_connected == false)
+ {
+ /* we have a message from a new frontEnd */
+ status = PacketReceive(port, &port->buf, NON_BLOCKING);
+ if (status == STATUS_OK)
+ {
+ fe->fn_connected = true;
+ pq_init(port->sock);
+ fe->fn_Pfin = Pfin;
+ fe->fn_Pfout = Pfout;
+ }
+ else
+ fprintf(stderr, "Multiplexed backend: error in reading packets from %d\n", port->sock);
+ }
+ else
+/* we have a query from an existing, active FrontEnd */
+ {
+ Pfin = fe->fn_Pfin;
+ Pfout = fe->fn_Pfout;
+ currentFE = fe;
+ }
+ if (fe->fn_done)
+ {
+ Dlelem *c = curr;
+
+ curr = DLGetSucc(curr);
+ DLRemove(c);
+ }
+ break;
+ }
+ else
+ curr = DLGetSucc(curr);
+ }
+ }
+ /* ----------------
+ * (1) read a command.
+ * ----------------
+ */
+ memset(parser_input, 0, MAX_PARSE_BUFFER);
+
+ firstchar = ReadCommand(parser_input, multiplexedBackend);
+ /* process the command */
+ switch (firstchar)
+ {
+ /* ----------------
+ * 'F' indicates a fastpath call.
+ * XXX HandleFunctionRequest
+ * ----------------
+ */
+ case 'F':
+ IsEmptyQuery = false;
+
+ /* start an xact for this function invocation */
+ if (!Quiet)
+ {
+ time(&tim);
+ printf("\tStartTransactionCommand() at %s\n", ctime(&tim));
+ }
+
+ StartTransactionCommand();
+ HandleFunctionRequest();
+ break;
+
+ /* ----------------
+ * 'Q' indicates a user query
+ * ----------------
+ */
+ case 'Q':
+ fflush(stdout);
+
+ if (strspn(parser_input, " \t\n") == strlen(parser_input))
+ {
+ /* ----------------
+ * if there is nothing in the input buffer, don't bother
+ * trying to parse and execute anything..
+ * ----------------
+ */
+ IsEmptyQuery = true;
+ }
+ else
+ {
+ /* ----------------
+ * otherwise, process the input string.
+ * ----------------
+ */
+ IsEmptyQuery = false;
+ if (ShowStats)
+ ResetUsage();
+
+ /* start an xact for this query */
+ if (!Quiet)
+ {
+ time(&tim);
+ printf("\tStartTransactionCommand() at %s\n", ctime(&tim));
+ }
+ StartTransactionCommand();
+
+ pg_eval(parser_input, (char **) NULL, (Oid *) NULL, 0);
+
+ if (ShowStats)
+ ShowUsage();
+ }
+ break;
+
+ /* ----------------
+ * 'X' means that the frontend is closing down the socket
+ * ----------------
+ */
+ case 'X':
+ IsEmptyQuery = true;
+ if (multiplexedBackend)
+ {
+ FD_CLR(currentFE->fn_port.sock, &basemask);
+ currentFE->fn_done = true;
+ numFE--;
+ }
+ pq_close();
+ break;
+
+ default:
+ elog(WARN, "unknown frontend message was recieved");
+ }
+
+ /* ----------------
+ * (3) commit the current transaction
+ *
+ * Note: if we had an empty input buffer, then we didn't
+ * call pg_eval, so we don't bother to commit this transaction.
+ * ----------------
+ */
+ if (!IsEmptyQuery)
+ {
+ if (!Quiet)
+ {
+ time(&tim);
+ printf("\tCommitTransactionCommand() at %s\n", ctime(&tim));
+ }
+ CommitTransactionCommand();
+
+ }
+ else
+ {
+ if (IsUnderPostmaster || multiplexedBackend)
+ NullCommand(Remote);
+ }
+
+ } /* infinite for-loop */
+ exitpg(0);
+ return 1;
}
#ifndef HAVE_GETRUSAGE
#include "rusagestub.h"
-#else /* HAVE_GETRUSAGE */
+#else /* HAVE_GETRUSAGE */
#include <sys/resource.h>
-#endif /* HAVE_GETRUSAGE */
+#endif /* HAVE_GETRUSAGE */
-struct rusage Save_r;
-struct timeval Save_t;
+struct rusage Save_r;
+struct timeval Save_t;
void
ResetUsage(void)
{
- struct timezone tz;
- getrusage(RUSAGE_SELF, &Save_r);
- gettimeofday(&Save_t, &tz);
- ResetBufferUsage();
-/* ResetTupleCount(); */
+ struct timezone tz;
+
+ getrusage(RUSAGE_SELF, &Save_r);
+ gettimeofday(&Save_t, &tz);
+ ResetBufferUsage();
+/* ResetTupleCount(); */
}
void
ShowUsage(void)
{
- struct timeval user, sys;
- struct timeval elapse_t;
- struct timezone tz;
- struct rusage r;
-
- getrusage(RUSAGE_SELF, &r);
- gettimeofday(&elapse_t, &tz);
- memmove((char *)&user, (char *)&r.ru_utime, sizeof(user));
- memmove((char *)&sys, (char *)&r.ru_stime,sizeof(sys));
- if (elapse_t.tv_usec < Save_t.tv_usec) {
- elapse_t.tv_sec--;
- elapse_t.tv_usec += 1000000;
- }
- if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec) {
- r.ru_utime.tv_sec--;
- r.ru_utime.tv_usec += 1000000;
- }
- if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec) {
- r.ru_stime.tv_sec--;
- r.ru_stime.tv_usec += 1000000;
- }
-
- /*
- * the only stats we don't show here are for memory usage -- i can't
- * figure out how to interpret the relevant fields in the rusage
- * struct, and they change names across o/s platforms, anyway.
- * if you can figure out what the entries mean, you can somehow
- * extract resident set size, shared text size, and unshared data
- * and stack sizes.
- */
-
- fprintf(StatFp, "! system usage stats:\n");
- fprintf(StatFp,
- "!\t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system sec\n",
- (long int) elapse_t.tv_sec - Save_t.tv_sec,
- (long int) elapse_t.tv_usec - Save_t.tv_usec,
- (long int) r.ru_utime.tv_sec - Save_r.ru_utime.tv_sec,
- (long int) r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec,
- (long int) r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec,
- (long int) r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec);
- fprintf(StatFp,
- "!\t[%ld.%06ld user %ld.%06ld sys total]\n",
- (long int) user.tv_sec,
- (long int) user.tv_usec,
- (long int) sys.tv_sec,
- (long int) sys.tv_usec);
+ struct timeval user,
+ sys;
+ struct timeval elapse_t;
+ struct timezone tz;
+ struct rusage r;
+
+ getrusage(RUSAGE_SELF, &r);
+ gettimeofday(&elapse_t, &tz);
+ memmove((char *) &user, (char *) &r.ru_utime, sizeof(user));
+ memmove((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
+ if (elapse_t.tv_usec < Save_t.tv_usec)
+ {
+ elapse_t.tv_sec--;
+ elapse_t.tv_usec += 1000000;
+ }
+ if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec)
+ {
+ r.ru_utime.tv_sec--;
+ r.ru_utime.tv_usec += 1000000;
+ }
+ if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec)
+ {
+ r.ru_stime.tv_sec--;
+ r.ru_stime.tv_usec += 1000000;
+ }
+
+ /*
+ * the only stats we don't show here are for memory usage -- i can't
+ * figure out how to interpret the relevant fields in the rusage
+ * struct, and they change names across o/s platforms, anyway. if you
+ * can figure out what the entries mean, you can somehow extract
+ * resident set size, shared text size, and unshared data and stack
+ * sizes.
+ */
+
+ fprintf(StatFp, "! system usage stats:\n");
+ fprintf(StatFp,
+ "!\t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system sec\n",
+ (long int) elapse_t.tv_sec - Save_t.tv_sec,
+ (long int) elapse_t.tv_usec - Save_t.tv_usec,
+ (long int) r.ru_utime.tv_sec - Save_r.ru_utime.tv_sec,
+ (long int) r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec,
+ (long int) r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec,
+ (long int) r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec);
+ fprintf(StatFp,
+ "!\t[%ld.%06ld user %ld.%06ld sys total]\n",
+ (long int) user.tv_sec,
+ (long int) user.tv_usec,
+ (long int) sys.tv_sec,
+ (long int) sys.tv_usec);
#ifdef HAVE_GETRUSAGE
- fprintf(StatFp,
- "!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
- r.ru_inblock - Save_r.ru_inblock,
- /* they only drink coffee at dec */
- r.ru_oublock - Save_r.ru_oublock,
- r.ru_inblock, r.ru_oublock);
- fprintf(StatFp,
- "!\t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swaps\n",
- r.ru_majflt - Save_r.ru_majflt,
- r.ru_minflt - Save_r.ru_minflt,
- r.ru_majflt, r.ru_minflt,
- r.ru_nswap - Save_r.ru_nswap,
- r.ru_nswap);
- fprintf(StatFp,
- "!\t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sent\n",
- r.ru_nsignals - Save_r.ru_nsignals,
- r.ru_nsignals,
- r.ru_msgrcv - Save_r.ru_msgrcv,
- r.ru_msgsnd - Save_r.ru_msgsnd,
- r.ru_msgrcv, r.ru_msgsnd);
- fprintf(StatFp,
- "!\t%ld/%ld [%ld/%ld] voluntary/involuntary context switches\n",
- r.ru_nvcsw - Save_r.ru_nvcsw,
- r.ru_nivcsw - Save_r.ru_nivcsw,
- r.ru_nvcsw, r.ru_nivcsw);
-#endif /* HAVE_GETRUSAGE */
- fprintf(StatFp, "! postgres usage stats:\n");
- PrintBufferUsage(StatFp);
-/* DisplayTupleCount(StatFp); */
+ fprintf(StatFp,
+ "!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
+ r.ru_inblock - Save_r.ru_inblock,
+ /* they only drink coffee at dec */
+ r.ru_oublock - Save_r.ru_oublock,
+ r.ru_inblock, r.ru_oublock);
+ fprintf(StatFp,
+ "!\t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swaps\n",
+ r.ru_majflt - Save_r.ru_majflt,
+ r.ru_minflt - Save_r.ru_minflt,
+ r.ru_majflt, r.ru_minflt,
+ r.ru_nswap - Save_r.ru_nswap,
+ r.ru_nswap);
+ fprintf(StatFp,
+ "!\t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sent\n",
+ r.ru_nsignals - Save_r.ru_nsignals,
+ r.ru_nsignals,
+ r.ru_msgrcv - Save_r.ru_msgrcv,
+ r.ru_msgsnd - Save_r.ru_msgsnd,
+ r.ru_msgrcv, r.ru_msgsnd);
+ fprintf(StatFp,
+ "!\t%ld/%ld [%ld/%ld] voluntary/involuntary context switches\n",
+ r.ru_nvcsw - Save_r.ru_nvcsw,
+ r.ru_nivcsw - Save_r.ru_nivcsw,
+ r.ru_nvcsw, r.ru_nivcsw);
+#endif /* HAVE_GETRUSAGE */
+ fprintf(StatFp, "! postgres usage stats:\n");
+ PrintBufferUsage(StatFp);
+/* DisplayTupleCount(StatFp); */
}
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index 1d11cbeae49..ca649291355 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* pquery.c--
- * POSTGRES process query command code
+ * POSTGRES process query command code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.7 1997/08/27 09:03:15 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.8 1997/09/07 04:49:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,332 +38,341 @@
#include "commands/command.h"
-static char* CreateOperationTag(int operationType);
-static void ProcessQueryDesc(QueryDesc *queryDesc);
+static char *CreateOperationTag(int operationType);
+static void ProcessQueryDesc(QueryDesc * queryDesc);
/* ----------------------------------------------------------------
- * CreateQueryDesc
+ * CreateQueryDesc
* ----------------------------------------------------------------
*/
-QueryDesc *
-CreateQueryDesc(Query *parsetree,
- Plan *plantree,
- CommandDest dest)
+QueryDesc *
+CreateQueryDesc(Query * parsetree,
+ Plan * plantree,
+ CommandDest dest)
{
- QueryDesc *qd = (QueryDesc *)palloc(sizeof(QueryDesc));
-
- qd->operation = parsetree->commandType; /* operation */
- qd->parsetree = parsetree; /* parse tree */
- qd->plantree = plantree; /* plan */
- qd->dest = dest; /* output dest */
- return qd;
+ QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc));
+
+ qd->operation = parsetree->commandType; /* operation */
+ qd->parsetree = parsetree; /* parse tree */
+ qd->plantree = plantree; /* plan */
+ qd->dest = dest; /* output dest */
+ return qd;
}
/* ----------------------------------------------------------------
- * CreateExecutorState
+ * CreateExecutorState
*
- * Note: this may someday take parameters -cim 9/18/89
+ * Note: this may someday take parameters -cim 9/18/89
* ----------------------------------------------------------------
*/
-EState *
+EState *
CreateExecutorState(void)
{
- EState *state;
- extern int NBuffers;
- long *refcount;
-
- /* ----------------
- * create a new executor state
- * ----------------
- */
- state = makeNode(EState);
-
- /* ----------------
- * initialize the Executor State structure
- * ----------------
- */
- state->es_direction = ForwardScanDirection;
- state->es_range_table = NIL;
-
- state->es_into_relation_descriptor = NULL;
- state->es_result_relation_info = NULL;
-
- state->es_param_list_info = NULL;
-
- state->es_BaseId = 0;
- state->es_tupleTable = NULL;
-
- state->es_junkFilter = NULL;
-
- refcount = (long *) palloc(NBuffers * sizeof(long));
- memset((char *) refcount, 0, NBuffers * sizeof(long));
- state->es_refcount = (int *) refcount;
-
- /* ----------------
- * return the executor state structure
- * ----------------
- */
- return state;
+ EState *state;
+ extern int NBuffers;
+ long *refcount;
+
+ /* ----------------
+ * create a new executor state
+ * ----------------
+ */
+ state = makeNode(EState);
+
+ /* ----------------
+ * initialize the Executor State structure
+ * ----------------
+ */
+ state->es_direction = ForwardScanDirection;
+ state->es_range_table = NIL;
+
+ state->es_into_relation_descriptor = NULL;
+ state->es_result_relation_info = NULL;
+
+ state->es_param_list_info = NULL;
+
+ state->es_BaseId = 0;
+ state->es_tupleTable = NULL;
+
+ state->es_junkFilter = NULL;
+
+ refcount = (long *) palloc(NBuffers * sizeof(long));
+ memset((char *) refcount, 0, NBuffers * sizeof(long));
+ state->es_refcount = (int *) refcount;
+
+ /* ----------------
+ * return the executor state structure
+ * ----------------
+ */
+ return state;
}
/* ----------------------------------------------------------------
- * CreateOperationTag
+ * CreateOperationTag
*
- * utility to get a string representation of the
- * query operation.
+ * utility to get a string representation of the
+ * query operation.
* ----------------------------------------------------------------
*/
-static char*
+static char *
CreateOperationTag(int operationType)
{
- char* tag;
-
- switch (operationType) {
- case CMD_SELECT:
- tag = "SELECT";
- break;
- case CMD_INSERT:
- tag = "INSERT";
- break;
- case CMD_DELETE:
- tag = "DELETE";
- break;
- case CMD_UPDATE:
- tag = "UPDATE";
- break;
- default:
- elog(DEBUG, "CreateOperationTag: unknown operation type %d",
- operationType);
- tag = NULL;
- break;
- }
-
- return tag;
+ char *tag;
+
+ switch (operationType)
+ {
+ case CMD_SELECT:
+ tag = "SELECT";
+ break;
+ case CMD_INSERT:
+ tag = "INSERT";
+ break;
+ case CMD_DELETE:
+ tag = "DELETE";
+ break;
+ case CMD_UPDATE:
+ tag = "UPDATE";
+ break;
+ default:
+ elog(DEBUG, "CreateOperationTag: unknown operation type %d",
+ operationType);
+ tag = NULL;
+ break;
+ }
+
+ return tag;
}
/* ----------------
- * ProcessPortal
+ * ProcessPortal
* ----------------
*/
void
-ProcessPortal(char* portalName,
- Query *parseTree,
- Plan *plan,
- EState *state,
- TupleDesc attinfo,
- CommandDest dest)
+ProcessPortal(char *portalName,
+ Query * parseTree,
+ Plan * plan,
+ EState * state,
+ TupleDesc attinfo,
+ CommandDest dest)
{
- Portal portal;
- MemoryContext portalContext;
-
- /* ----------------
- * convert the current blank portal into the user-specified
- * portal and initialize the state and query descriptor.
- * ----------------
- */
-
- if (PortalNameIsSpecial(portalName))
- elog(WARN,
- "The portal name %s is reserved for internal use",
- portalName);
-
- portal = BlankPortalAssignName(portalName);
-
- PortalSetQuery(portal,
- CreateQueryDesc(parseTree, plan, dest),
- attinfo,
- state,
- PortalCleanup);
-
- /* ----------------
- * now create a new blank portal and switch to it.
- * Otherwise, the new named portal will be cleaned.
- *
- * Note: portals will only be supported within a BEGIN...END
- * block in the near future. Later, someone will fix it to
- * do what is possible across transaction boundries. -hirohama
- * ----------------
- */
- portalContext = (MemoryContext)
- PortalGetHeapMemory(GetPortalByName(NULL));
-
- MemoryContextSwitchTo(portalContext);
-
- StartPortalAllocMode(DefaultAllocMode, 0);
+ Portal portal;
+ MemoryContext portalContext;
+
+ /* ----------------
+ * convert the current blank portal into the user-specified
+ * portal and initialize the state and query descriptor.
+ * ----------------
+ */
+
+ if (PortalNameIsSpecial(portalName))
+ elog(WARN,
+ "The portal name %s is reserved for internal use",
+ portalName);
+
+ portal = BlankPortalAssignName(portalName);
+
+ PortalSetQuery(portal,
+ CreateQueryDesc(parseTree, plan, dest),
+ attinfo,
+ state,
+ PortalCleanup);
+
+ /* ----------------
+ * now create a new blank portal and switch to it.
+ * Otherwise, the new named portal will be cleaned.
+ *
+ * Note: portals will only be supported within a BEGIN...END
+ * block in the near future. Later, someone will fix it to
+ * do what is possible across transaction boundries. -hirohama
+ * ----------------
+ */
+ portalContext = (MemoryContext)
+ PortalGetHeapMemory(GetPortalByName(NULL));
+
+ MemoryContextSwitchTo(portalContext);
+
+ StartPortalAllocMode(DefaultAllocMode, 0);
}
/* ----------------------------------------------------------------
- * ProcessQueryDesc
+ * ProcessQueryDesc
*
- * Read the comments for ProcessQuery() below...
+ * Read the comments for ProcessQuery() below...
* ----------------------------------------------------------------
*/
static void
-ProcessQueryDesc(QueryDesc *queryDesc)
+ProcessQueryDesc(QueryDesc * queryDesc)
{
- Query *parseTree;
- Plan *plan;
- int operation;
- char* tag;
- EState *state;
- TupleDesc attinfo;
-
- bool isRetrieveIntoPortal;
- bool isRetrieveIntoRelation;
- char* intoName = NULL;
- CommandDest dest;
-
- /* ----------------
- * get info from the query desc
- * ----------------
- */
- parseTree = queryDesc->parsetree;
- plan = queryDesc->plantree;
-
- operation = queryDesc->operation;
- tag = CreateOperationTag(operation);
- dest = queryDesc->dest;
-
- /* ----------------
- * initialize portal/into relation status
- * ----------------
- */
- isRetrieveIntoPortal = false;
- isRetrieveIntoRelation = false;
-
- if (operation == CMD_SELECT) {
- if (parseTree->isPortal) {
- isRetrieveIntoPortal = true;
- intoName = parseTree->into;
- if (parseTree->isBinary) {
- /*
- * For internal format portals, we change Remote
- * (externalized form) to RemoteInternal (internalized
- * form)
- */
- dest = queryDesc->dest = RemoteInternal;
- }
- } else if (parseTree->into != NULL) {
- /* select into table */
- isRetrieveIntoRelation = true;
+ Query *parseTree;
+ Plan *plan;
+ int operation;
+ char *tag;
+ EState *state;
+ TupleDesc attinfo;
+
+ bool isRetrieveIntoPortal;
+ bool isRetrieveIntoRelation;
+ char *intoName = NULL;
+ CommandDest dest;
+
+ /* ----------------
+ * get info from the query desc
+ * ----------------
+ */
+ parseTree = queryDesc->parsetree;
+ plan = queryDesc->plantree;
+
+ operation = queryDesc->operation;
+ tag = CreateOperationTag(operation);
+ dest = queryDesc->dest;
+
+ /* ----------------
+ * initialize portal/into relation status
+ * ----------------
+ */
+ isRetrieveIntoPortal = false;
+ isRetrieveIntoRelation = false;
+
+ if (operation == CMD_SELECT)
+ {
+ if (parseTree->isPortal)
+ {
+ isRetrieveIntoPortal = true;
+ intoName = parseTree->into;
+ if (parseTree->isBinary)
+ {
+
+ /*
+ * For internal format portals, we change Remote
+ * (externalized form) to RemoteInternal (internalized
+ * form)
+ */
+ dest = queryDesc->dest = RemoteInternal;
+ }
+ }
+ else if (parseTree->into != NULL)
+ {
+ /* select into table */
+ isRetrieveIntoRelation = true;
+ }
+
}
- }
-
- /* ----------------
- * when performing a retrieve into, we override the normal
- * communication destination during the processing of the
- * the query. This only affects the tuple-output function
- * - the correct destination will still see BeginCommand()
- * and EndCommand() messages.
- * ----------------
- */
- if (isRetrieveIntoRelation)
- queryDesc->dest = (int) None;
-
- /* ----------------
- * create a default executor state..
- * ----------------
- */
- state = CreateExecutorState();
-
- /* ----------------
- * call ExecStart to prepare the plan for execution
- * ----------------
- */
- attinfo = ExecutorStart(queryDesc, state);
-
- /* ----------------
- * report the query's result type information
- * back to the front end or to whatever destination
- * we're dealing with.
- * ----------------
- */
- BeginCommand(NULL,
- operation,
- attinfo,
- isRetrieveIntoRelation,
- isRetrieveIntoPortal,
- tag,
- dest);
-
- /* ----------------
- * Named portals do not do a "fetch all" initially, so now
- * we return since ExecMain has been called with EXEC_START
- * to initialize the query plan.
- *
- * Note: ProcessPortal transforms the current "blank" portal
- * into a named portal and creates a new blank portal so
- * everything we allocated in the current "blank" memory
- * context will be preserved across queries. -cim 2/22/91
- * ----------------
- */
- if (isRetrieveIntoPortal) {
- PortalExecutorHeapMemory = NULL;
-
- ProcessPortal(intoName,
- parseTree,
- plan,
- state,
- attinfo,
- dest);
-
+ /* ----------------
+ * when performing a retrieve into, we override the normal
+ * communication destination during the processing of the
+ * the query. This only affects the tuple-output function
+ * - the correct destination will still see BeginCommand()
+ * and EndCommand() messages.
+ * ----------------
+ */
+ if (isRetrieveIntoRelation)
+ queryDesc->dest = (int) None;
+
+ /* ----------------
+ * create a default executor state..
+ * ----------------
+ */
+ state = CreateExecutorState();
+
+ /* ----------------
+ * call ExecStart to prepare the plan for execution
+ * ----------------
+ */
+ attinfo = ExecutorStart(queryDesc, state);
+
+ /* ----------------
+ * report the query's result type information
+ * back to the front end or to whatever destination
+ * we're dealing with.
+ * ----------------
+ */
+ BeginCommand(NULL,
+ operation,
+ attinfo,
+ isRetrieveIntoRelation,
+ isRetrieveIntoPortal,
+ tag,
+ dest);
+
+ /* ----------------
+ * Named portals do not do a "fetch all" initially, so now
+ * we return since ExecMain has been called with EXEC_START
+ * to initialize the query plan.
+ *
+ * Note: ProcessPortal transforms the current "blank" portal
+ * into a named portal and creates a new blank portal so
+ * everything we allocated in the current "blank" memory
+ * context will be preserved across queries. -cim 2/22/91
+ * ----------------
+ */
+ if (isRetrieveIntoPortal)
+ {
+ PortalExecutorHeapMemory = NULL;
+
+ ProcessPortal(intoName,
+ parseTree,
+ plan,
+ state,
+ attinfo,
+ dest);
+
+ EndCommand(tag, dest);
+ return;
+ }
+
+ /* ----------------
+ * Now we get to the important call to ExecutorRun() where we
+ * actually run the plan..
+ * ----------------
+ */
+ ExecutorRun(queryDesc, state, EXEC_RUN, 0);
+
+ /* save infos for EndCommand */
+ UpdateCommandInfo(operation, state->es_lastoid, state->es_processed);
+
+ /* ----------------
+ * now, we close down all the scans and free allocated resources...
+ * with ExecutorEnd()
+ * ----------------
+ */
+ ExecutorEnd(queryDesc, state);
+
+ /* ----------------
+ * Notify the destination of end of processing.
+ * ----------------
+ */
EndCommand(tag, dest);
- return;
- }
-
- /* ----------------
- * Now we get to the important call to ExecutorRun() where we
- * actually run the plan..
- * ----------------
- */
- ExecutorRun(queryDesc, state, EXEC_RUN, 0);
-
- /* save infos for EndCommand */
- UpdateCommandInfo (operation, state->es_lastoid, state->es_processed);
-
- /* ----------------
- * now, we close down all the scans and free allocated resources...
- * with ExecutorEnd()
- * ----------------
- */
- ExecutorEnd(queryDesc, state);
-
- /* ----------------
- * Notify the destination of end of processing.
- * ----------------
- */
- EndCommand(tag, dest);
}
/* ----------------------------------------------------------------
- * ProcessQuery
+ * ProcessQuery
*
- * Execute a plan, the non-parallel version
+ * Execute a plan, the non-parallel version
* ----------------------------------------------------------------
*/
void
-ProcessQuery(Query *parsetree,
- Plan *plan,
- char *argv[],
- Oid *typev,
- int nargs,
- CommandDest dest)
+ProcessQuery(Query * parsetree,
+ Plan * plan,
+ char *argv[],
+ Oid * typev,
+ int nargs,
+ CommandDest dest)
{
- QueryDesc *queryDesc;
- extern int dontExecute; /* from postgres.c */
- extern void print_plan (Plan* p, Query* parsetree); /* from print.c */
+ QueryDesc *queryDesc;
+ extern int dontExecute;/* from postgres.c */
+ extern void print_plan(Plan * p, Query * parsetree); /* from print.c */
- queryDesc = CreateQueryDesc(parsetree, plan, dest);
+ queryDesc = CreateQueryDesc(parsetree, plan, dest);
- if (dontExecute) {
- /* don't execute it, just show the query plan */
- print_plan(plan, parsetree);
- } else
- ProcessQueryDesc(queryDesc);
+ if (dontExecute)
+ {
+ /* don't execute it, just show the query plan */
+ print_plan(plan, parsetree);
+ }
+ else
+ ProcessQueryDesc(queryDesc);
}
-
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 1edb41b46e0..d309ac69a27 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1,15 +1,15 @@
/*-------------------------------------------------------------------------
*
* utility.c--
- * Contains functions which control the execution of the POSTGRES utility
- * commands. At one time acted as an interface between the Lisp and C
- * systems.
+ * Contains functions which control the execution of the POSTGRES utility
+ * commands. At one time acted as an interface between the Lisp and C
+ * systems.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.21 1997/08/31 11:41:55 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.22 1997/09/07 04:49:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -47,7 +47,7 @@
#include "tcop/dest.h"
#include "tcop/variable.h"
#include "tcop/utility.h"
-#include "fmgr.h" /* For load_file() */
+#include "fmgr.h" /* For load_file() */
#include "storage/fd.h"
#ifndef NO_SECURITY
@@ -58,649 +58,673 @@
/* ----------------
- * CHECK_IF_ABORTED() is used to avoid doing unnecessary
- * processing within an aborted transaction block.
+ * CHECK_IF_ABORTED() is used to avoid doing unnecessary
+ * processing within an aborted transaction block.
* ----------------
*/
#define CHECK_IF_ABORTED() \
- if (IsAbortedTransactionBlockState()) { \
- elog(NOTICE, "(transaction aborted): %s", \
- "queries ignored until END"); \
- commandTag = "*ABORT STATE*"; \
- break; \
- } \
-
+ if (IsAbortedTransactionBlockState()) { \
+ elog(NOTICE, "(transaction aborted): %s", \
+ "queries ignored until END"); \
+ commandTag = "*ABORT STATE*"; \
+ break; \
+ } \
+
/* ----------------
- * general utility function invoker
+ * general utility function invoker
* ----------------
*/
void
-ProcessUtility(Node *parsetree,
- CommandDest dest)
+ProcessUtility(Node * parsetree,
+ CommandDest dest)
{
- char *commandTag = NULL;
- char *relname;
- char *relationName;
- char *userName;
-
- userName = GetPgUserName();
-
- switch (nodeTag(parsetree)) {
- /* ********************************
- * transactions
- * ********************************
- */
- case T_TransactionStmt:
- {
- TransactionStmt *stmt = (TransactionStmt *)parsetree;
- switch (stmt->command) {
- case BEGIN_TRANS:
- commandTag = "BEGIN";
- CHECK_IF_ABORTED();
- BeginTransactionBlock();
- break;
-
- case END_TRANS:
- commandTag = "END";
- EndTransactionBlock();
- break;
-
- case ABORT_TRANS:
- commandTag = "ABORT";
- UserAbortTransactionBlock();
- break;
- }
- }
- break;
-
- /* ********************************
- * portal manipulation
- * ********************************
- */
- case T_ClosePortalStmt:
- {
- ClosePortalStmt *stmt = (ClosePortalStmt *)parsetree;
-
- commandTag = "CLOSE";
- CHECK_IF_ABORTED();
-
- PerformPortalClose(stmt->portalname, dest);
- }
- break;
-
- case T_FetchStmt:
- {
- FetchStmt *stmt = (FetchStmt *)parsetree;
- char *portalName = stmt->portalname;
- bool forward;
- int count;
-
- commandTag = "FETCH";
- CHECK_IF_ABORTED();
-
- forward = (bool)(stmt->direction == FORWARD);
-
- /* parser ensures that count is >= 0 and
- 'fetch ALL' -> 0 */
-
- count = stmt->howMany;
- PerformPortalFetch(portalName, forward, count, commandTag, dest);
- }
- break;
-
- /* ********************************
- * relation and attribute manipulation
- * ********************************
- */
- case T_CreateStmt:
- commandTag = "CREATE";
- CHECK_IF_ABORTED();
-
- DefineRelation((CreateStmt *)parsetree);
- break;
-
- case T_DestroyStmt:
- {
- DestroyStmt *stmt = (DestroyStmt *)parsetree;
- List *arg;
- List *args = stmt->relNames;
- Relation rel;
-
- commandTag = "DROP";
- CHECK_IF_ABORTED();
-
- foreach (arg, args) {
- relname = strVal(lfirst(arg));
- if (IsSystemRelationName(relname))
- elog(WARN, "class \"%s\" is a system catalog",
- relname);
- rel = heap_openr (relname);
- if ( RelationIsValid (rel) )
- {
- if ( stmt->sequence &&
- rel->rd_rel->relkind != RELKIND_SEQUENCE )
- elog (WARN, "Use DROP TABLE to drop table '%s'",
- relname);
- if ( !(stmt->sequence) &&
- rel->rd_rel->relkind == RELKIND_SEQUENCE )
- elog (WARN, "Use DROP SEQUENCE to drop sequence '%s'",
- relname);
- heap_close (rel);
- }
-#ifndef NO_SECURITY
- if (!pg_ownercheck(userName, relname, RELNAME))
- elog(WARN, "you do not own class \"%s\"",
- relname);
-#endif
- }
- foreach (arg, args) {
- relname = strVal(lfirst(arg));
- RemoveRelation(relname);
- }
- }
- break;
-
- case T_PurgeStmt:
- {
- PurgeStmt *stmt = (PurgeStmt *)parsetree;
-
- commandTag = "PURGE";
- CHECK_IF_ABORTED();
-
- RelationPurge(stmt->relname,
- stmt->beforeDate, /* absolute time string */
- stmt->afterDate); /* relative time string */
- }
- break;
-
- case T_CopyStmt:
- {
- CopyStmt *stmt = (CopyStmt *)parsetree;
-
- commandTag = "COPY";
- CHECK_IF_ABORTED();
-
- DoCopy(stmt->relname,
- stmt->binary,
- stmt->oids,
- (bool)(stmt->direction == FROM),
- (bool)(stmt->filename == NULL),
- /* null filename means copy to/from stdout/stdin,
- rather than to/from a file.
- */
- stmt->filename,
- stmt->delimiter);
- }
- break;
-
- case T_AddAttrStmt:
- {
- AddAttrStmt *stmt = (AddAttrStmt *)parsetree;
-
- commandTag = "ADD";
- CHECK_IF_ABORTED();
-
- /* owner checking done in PerformAddAttribute (now recursive) */
- PerformAddAttribute(stmt->relname,
- userName,
- stmt->inh,
- stmt->colDef);
- }
- break;
-
- /*
- * schema
- */
- case T_RenameStmt:
+ char *commandTag = NULL;
+ char *relname;
+ char *relationName;
+ char *userName;
+
+ userName = GetPgUserName();
+
+ switch (nodeTag(parsetree))
{
- RenameStmt *stmt = (RenameStmt *)parsetree;
-
- commandTag = "RENAME";
- CHECK_IF_ABORTED();
-
- relname = stmt->relname;
- if (IsSystemRelationName(relname))
- elog(WARN, "class \"%s\" is a system catalog",
- relname);
-#ifndef NO_SECURITY
- if (!pg_ownercheck(userName, relname, RELNAME))
- elog(WARN, "you do not own class \"%s\"",
- relname);
-#endif
-
- /* ----------------
- * XXX using len == 3 to tell the difference
- * between "rename rel to newrel" and
- * "rename att in rel to newatt" will not
- * work soon because "rename type/operator/rule"
- * stuff is being added. - cim 10/24/90
- * ----------------
- * [another piece of amuzing but useless anecdote -- ay]
- */
- if (stmt->column == NULL) {
- /* ----------------
- * rename relation
+
+ /*
+ * ******************************** transactions ********************************
*
- * Note: we also rename the "type" tuple
- * corresponding to the relation.
- * ----------------
*/
- renamerel(relname, /* old name */
- stmt->newname); /* new name */
- TypeRename(relname, /* old name */
- stmt->newname); /* new name */
- } else {
- /* ----------------
- * rename attribute
- * ----------------
+ case T_TransactionStmt:
+ {
+ TransactionStmt *stmt = (TransactionStmt *) parsetree;
+
+ switch (stmt->command)
+ {
+ case BEGIN_TRANS:
+ commandTag = "BEGIN";
+ CHECK_IF_ABORTED();
+ BeginTransactionBlock();
+ break;
+
+ case END_TRANS:
+ commandTag = "END";
+ EndTransactionBlock();
+ break;
+
+ case ABORT_TRANS:
+ commandTag = "ABORT";
+ UserAbortTransactionBlock();
+ break;
+ }
+ }
+ break;
+
+ /*
+ * ******************************** portal manipulation ********************************
+ *
*/
- renameatt(relname, /* relname */
- stmt->column, /* old att name */
- stmt->newname, /* new att name */
- userName,
- stmt->inh); /* recursive? */
- }
- }
- break;
-
- case T_ChangeACLStmt:
- {
- ChangeACLStmt *stmt = (ChangeACLStmt *)parsetree;
- List *i;
- AclItem *aip;
- unsigned modechg;
-
- commandTag = "CHANGE";
- CHECK_IF_ABORTED();
-
- aip = stmt->aclitem;
- modechg = stmt->modechg;
+ case T_ClosePortalStmt:
+ {
+ ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
+
+ commandTag = "CLOSE";
+ CHECK_IF_ABORTED();
+
+ PerformPortalClose(stmt->portalname, dest);
+ }
+ break;
+
+ case T_FetchStmt:
+ {
+ FetchStmt *stmt = (FetchStmt *) parsetree;
+ char *portalName = stmt->portalname;
+ bool forward;
+ int count;
+
+ commandTag = "FETCH";
+ CHECK_IF_ABORTED();
+
+ forward = (bool) (stmt->direction == FORWARD);
+
+ /*
+ * parser ensures that count is >= 0 and 'fetch ALL' -> 0
+ */
+
+ count = stmt->howMany;
+ PerformPortalFetch(portalName, forward, count, commandTag, dest);
+ }
+ break;
+
+ /*
+ * ******************************** relation and attribute
+ * manipulation ********************************
+ *
+ */
+ case T_CreateStmt:
+ commandTag = "CREATE";
+ CHECK_IF_ABORTED();
+
+ DefineRelation((CreateStmt *) parsetree);
+ break;
+
+ case T_DestroyStmt:
+ {
+ DestroyStmt *stmt = (DestroyStmt *) parsetree;
+ List *arg;
+ List *args = stmt->relNames;
+ Relation rel;
+
+ commandTag = "DROP";
+ CHECK_IF_ABORTED();
+
+ foreach(arg, args)
+ {
+ relname = strVal(lfirst(arg));
+ if (IsSystemRelationName(relname))
+ elog(WARN, "class \"%s\" is a system catalog",
+ relname);
+ rel = heap_openr(relname);
+ if (RelationIsValid(rel))
+ {
+ if (stmt->sequence &&
+ rel->rd_rel->relkind != RELKIND_SEQUENCE)
+ elog(WARN, "Use DROP TABLE to drop table '%s'",
+ relname);
+ if (!(stmt->sequence) &&
+ rel->rd_rel->relkind == RELKIND_SEQUENCE)
+ elog(WARN, "Use DROP SEQUENCE to drop sequence '%s'",
+ relname);
+ heap_close(rel);
+ }
#ifndef NO_SECURITY
- foreach (i, stmt->relNames) {
- relname = strVal(lfirst(i));
- if (!pg_ownercheck(userName, relname, RELNAME))
- elog(WARN, "you do not own class \"%s\"",
- relname);
- }
+ if (!pg_ownercheck(userName, relname, RELNAME))
+ elog(WARN, "you do not own class \"%s\"",
+ relname);
#endif
- foreach (i, stmt->relNames) {
- relname = strVal(lfirst(i));
- ChangeAcl(relname, aip, modechg);
- }
+ }
+ foreach(arg, args)
+ {
+ relname = strVal(lfirst(arg));
+ RemoveRelation(relname);
+ }
+ }
+ break;
- }
- break;
-
- /* ********************************
- * object creation / destruction
- * ********************************
- */
- case T_DefineStmt:
- {
- DefineStmt *stmt = (DefineStmt *)parsetree;
+ case T_PurgeStmt:
+ {
+ PurgeStmt *stmt = (PurgeStmt *) parsetree;
- commandTag = "CREATE";
- CHECK_IF_ABORTED();
+ commandTag = "PURGE";
+ CHECK_IF_ABORTED();
- switch(stmt->defType) {
- case OPERATOR:
- DefineOperator(stmt->defname, /* operator name */
- stmt->definition); /* rest */
+ RelationPurge(stmt->relname,
+ stmt->beforeDate, /* absolute time string */
+ stmt->afterDate); /* relative time string */
+ }
break;
- case P_TYPE:
+
+ case T_CopyStmt:
{
- DefineType (stmt->defname, stmt->definition);
+ CopyStmt *stmt = (CopyStmt *) parsetree;
+
+ commandTag = "COPY";
+ CHECK_IF_ABORTED();
+
+ DoCopy(stmt->relname,
+ stmt->binary,
+ stmt->oids,
+ (bool) (stmt->direction == FROM),
+ (bool) (stmt->filename == NULL),
+
+ /*
+ * null filename means copy to/from stdout/stdin, rather than
+ * to/from a file.
+ */
+ stmt->filename,
+ stmt->delimiter);
}
break;
- case AGGREGATE:
- DefineAggregate(stmt->defname, /*aggregate name */
- stmt->definition); /* rest */
+
+ case T_AddAttrStmt:
+ {
+ AddAttrStmt *stmt = (AddAttrStmt *) parsetree;
+
+ commandTag = "ADD";
+ CHECK_IF_ABORTED();
+
+ /* owner checking done in PerformAddAttribute (now recursive) */
+ PerformAddAttribute(stmt->relname,
+ userName,
+ stmt->inh,
+ stmt->colDef);
+ }
break;
- }
- }
- break;
-
- case T_ViewStmt: /* CREATE VIEW */
- {
- ViewStmt *stmt = (ViewStmt *)parsetree;
- commandTag = "CREATE";
- CHECK_IF_ABORTED();
- DefineView (stmt->viewname, stmt->query); /* retrieve parsetree */
- }
- break;
-
- case T_ProcedureStmt: /* CREATE FUNCTION */
- commandTag = "CREATE";
- CHECK_IF_ABORTED();
- CreateFunction((ProcedureStmt *)parsetree, dest); /* everything */
- break;
-
- case T_IndexStmt: /* CREATE INDEX */
- {
- IndexStmt *stmt = (IndexStmt *)parsetree;
-
- commandTag = "CREATE";
- CHECK_IF_ABORTED();
- /* XXX no support for ARCHIVE indices, yet */
- DefineIndex(stmt->relname, /* relation name */
- stmt->idxname, /* index name */
- stmt->accessMethod, /* am name */
- stmt->indexParams, /* parameters */
- stmt->withClause,
- stmt->unique,
- (Expr*)stmt->whereClause,
- stmt->rangetable);
- }
- break;
-
- case T_RuleStmt: /* CREATE RULE */
- {
- RuleStmt *stmt = (RuleStmt *)parsetree;
- int aclcheck_result;
+ /*
+ * schema
+ */
+ case T_RenameStmt:
+ {
+ RenameStmt *stmt = (RenameStmt *) parsetree;
+ commandTag = "RENAME";
+ CHECK_IF_ABORTED();
+
+ relname = stmt->relname;
+ if (IsSystemRelationName(relname))
+ elog(WARN, "class \"%s\" is a system catalog",
+ relname);
#ifndef NO_SECURITY
- relname = stmt->object->relname;
- aclcheck_result = pg_aclcheck(relname, userName, ACL_RU);
- if(aclcheck_result != ACLCHECK_OK)
- elog(WARN, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
-#endif
- commandTag = "CREATE";
- CHECK_IF_ABORTED();
- DefineQueryRewrite(stmt);
- }
- break;
-
- case T_CreateSeqStmt:
- commandTag = "CREATE";
- CHECK_IF_ABORTED();
-
- DefineSequence((CreateSeqStmt *)parsetree);
- break;
-
- case T_ExtendStmt:
- {
- ExtendStmt *stmt = (ExtendStmt *)parsetree;
-
- commandTag = "EXTEND";
- CHECK_IF_ABORTED();
-
- ExtendIndex(stmt->idxname, /* index name */
- (Expr*)stmt->whereClause, /* where */
- stmt->rangetable);
- }
- break;
-
- case T_RemoveStmt:
- {
- RemoveStmt *stmt = (RemoveStmt *)parsetree;
-
- commandTag = "DROP";
- CHECK_IF_ABORTED();
-
- switch(stmt->removeType) {
- case INDEX:
- relname = stmt->name;
- if (IsSystemRelationName(relname))
- elog(WARN, "class \"%s\" is a system catalog index",
- relname);
-#ifndef NO_SECURITY
- if (!pg_ownercheck(userName, relname, RELNAME))
- elog(WARN, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+ if (!pg_ownercheck(userName, relname, RELNAME))
+ elog(WARN, "you do not own class \"%s\"",
+ relname);
#endif
- RemoveIndex(relname);
+
+ /* ----------------
+ * XXX using len == 3 to tell the difference
+ * between "rename rel to newrel" and
+ * "rename att in rel to newatt" will not
+ * work soon because "rename type/operator/rule"
+ * stuff is being added. - cim 10/24/90
+ * ----------------
+ * [another piece of amuzing but useless anecdote -- ay]
+ */
+ if (stmt->column == NULL)
+ {
+ /* ----------------
+ * rename relation
+ *
+ * Note: we also rename the "type" tuple
+ * corresponding to the relation.
+ * ----------------
+ */
+ renamerel(relname, /* old name */
+ stmt->newname); /* new name */
+ TypeRename(relname, /* old name */
+ stmt->newname); /* new name */
+ }
+ else
+ {
+ /* ----------------
+ * rename attribute
+ * ----------------
+ */
+ renameatt(relname, /* relname */
+ stmt->column, /* old att name */
+ stmt->newname, /* new att name */
+ userName,
+ stmt->inh); /* recursive? */
+ }
+ }
break;
- case RULE:
+
+ case T_ChangeACLStmt:
{
- char *rulename = stmt->name;
- int aclcheck_result;
+ ChangeACLStmt *stmt = (ChangeACLStmt *) parsetree;
+ List *i;
+ AclItem *aip;
+ unsigned modechg;
+
+ commandTag = "CHANGE";
+ CHECK_IF_ABORTED();
+
+ aip = stmt->aclitem;
+ modechg = stmt->modechg;
#ifndef NO_SECURITY
-
- relationName = RewriteGetRuleEventRel(rulename);
- aclcheck_result = pg_aclcheck(relationName, userName, ACL_RU);
- if(aclcheck_result != ACLCHECK_OK) {
- elog(WARN, "%s: %s", relationName, aclcheck_error_strings[aclcheck_result]);
- }
+ foreach(i, stmt->relNames)
+ {
+ relname = strVal(lfirst(i));
+ if (!pg_ownercheck(userName, relname, RELNAME))
+ elog(WARN, "you do not own class \"%s\"",
+ relname);
+ }
#endif
- RemoveRewriteRule(rulename);
+ foreach(i, stmt->relNames)
+ {
+ relname = strVal(lfirst(i));
+ ChangeAcl(relname, aip, modechg);
+ }
+
+ }
+ break;
+
+ /*
+ * ******************************** object creation / destruction ********************************
+ *
+ */
+ case T_DefineStmt:
+ {
+ DefineStmt *stmt = (DefineStmt *) parsetree;
+
+ commandTag = "CREATE";
+ CHECK_IF_ABORTED();
+
+ switch (stmt->defType)
+ {
+ case OPERATOR:
+ DefineOperator(stmt->defname, /* operator name */
+ stmt->definition); /* rest */
+ break;
+ case P_TYPE:
+ {
+ DefineType(stmt->defname, stmt->definition);
+ }
+ break;
+ case AGGREGATE:
+ DefineAggregate(stmt->defname, /* aggregate name */
+ stmt->definition); /* rest */
+ break;
+ }
+ }
+ break;
+
+ case T_ViewStmt: /* CREATE VIEW */
+ {
+ ViewStmt *stmt = (ViewStmt *) parsetree;
+
+ commandTag = "CREATE";
+ CHECK_IF_ABORTED();
+ DefineView(stmt->viewname, stmt->query); /* retrieve parsetree */
+ }
+ break;
+
+ case T_ProcedureStmt: /* CREATE FUNCTION */
+ commandTag = "CREATE";
+ CHECK_IF_ABORTED();
+ CreateFunction((ProcedureStmt *) parsetree, dest); /* everything */
+ break;
+
+ case T_IndexStmt: /* CREATE INDEX */
+ {
+ IndexStmt *stmt = (IndexStmt *) parsetree;
+
+ commandTag = "CREATE";
+ CHECK_IF_ABORTED();
+ /* XXX no support for ARCHIVE indices, yet */
+ DefineIndex(stmt->relname, /* relation name */
+ stmt->idxname, /* index name */
+ stmt->accessMethod, /* am name */
+ stmt->indexParams, /* parameters */
+ stmt->withClause,
+ stmt->unique,
+ (Expr *) stmt->whereClause,
+ stmt->rangetable);
}
break;
- case P_TYPE:
+
+ case T_RuleStmt: /* CREATE RULE */
+ {
+ RuleStmt *stmt = (RuleStmt *) parsetree;
+ int aclcheck_result;
+
#ifndef NO_SECURITY
- /* XXX moved to remove.c */
+ relname = stmt->object->relname;
+ aclcheck_result = pg_aclcheck(relname, userName, ACL_RU);
+ if (aclcheck_result != ACLCHECK_OK)
+ elog(WARN, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
#endif
- RemoveType(stmt->name);
+ commandTag = "CREATE";
+ CHECK_IF_ABORTED();
+ DefineQueryRewrite(stmt);
+ }
+ break;
+
+ case T_CreateSeqStmt:
+ commandTag = "CREATE";
+ CHECK_IF_ABORTED();
+
+ DefineSequence((CreateSeqStmt *) parsetree);
+ break;
+
+ case T_ExtendStmt:
+ {
+ ExtendStmt *stmt = (ExtendStmt *) parsetree;
+
+ commandTag = "EXTEND";
+ CHECK_IF_ABORTED();
+
+ ExtendIndex(stmt->idxname, /* index name */
+ (Expr *) stmt->whereClause, /* where */
+ stmt->rangetable);
+ }
break;
- case VIEW:
+
+ case T_RemoveStmt:
{
- char *viewName = stmt->name;
- char *ruleName;
+ RemoveStmt *stmt = (RemoveStmt *) parsetree;
+
+ commandTag = "DROP";
+ CHECK_IF_ABORTED();
+
+ switch (stmt->removeType)
+ {
+ case INDEX:
+ relname = stmt->name;
+ if (IsSystemRelationName(relname))
+ elog(WARN, "class \"%s\" is a system catalog index",
+ relname);
+#ifndef NO_SECURITY
+ if (!pg_ownercheck(userName, relname, RELNAME))
+ elog(WARN, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+#endif
+ RemoveIndex(relname);
+ break;
+ case RULE:
+ {
+ char *rulename = stmt->name;
+ int aclcheck_result;
#ifndef NO_SECURITY
-
- ruleName = MakeRetrieveViewRuleName(viewName);
- relationName = RewriteGetRuleEventRel(ruleName);
- if (!pg_ownercheck(userName, relationName, RELNAME))
- elog(WARN, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
- pfree(ruleName);
+
+ relationName = RewriteGetRuleEventRel(rulename);
+ aclcheck_result = pg_aclcheck(relationName, userName, ACL_RU);
+ if (aclcheck_result != ACLCHECK_OK)
+ {
+ elog(WARN, "%s: %s", relationName, aclcheck_error_strings[aclcheck_result]);
+ }
+#endif
+ RemoveRewriteRule(rulename);
+ }
+ break;
+ case P_TYPE:
+#ifndef NO_SECURITY
+ /* XXX moved to remove.c */
+#endif
+ RemoveType(stmt->name);
+ break;
+ case VIEW:
+ {
+ char *viewName = stmt->name;
+ char *ruleName;
+
+#ifndef NO_SECURITY
+
+ ruleName = MakeRetrieveViewRuleName(viewName);
+ relationName = RewriteGetRuleEventRel(ruleName);
+ if (!pg_ownercheck(userName, relationName, RELNAME))
+ elog(WARN, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+ pfree(ruleName);
#endif
- RemoveView(viewName);
+ RemoveView(viewName);
+ }
+ break;
+ }
+ break;
}
break;
- }
- break;
- }
- break;
- case T_RemoveAggrStmt:
- {
- RemoveAggrStmt *stmt = (RemoveAggrStmt *)parsetree;
- commandTag = "DROP";
- CHECK_IF_ABORTED();
- RemoveAggregate(stmt->aggname, stmt->aggtype);
- }
- break;
-
- case T_RemoveFuncStmt:
- {
- RemoveFuncStmt *stmt = (RemoveFuncStmt *)parsetree;
- commandTag = "DROP";
- CHECK_IF_ABORTED();
- RemoveFunction(stmt->funcname,
- length(stmt->args),
- stmt->args);
- }
- break;
-
- case T_RemoveOperStmt:
- {
- RemoveOperStmt *stmt = (RemoveOperStmt *)parsetree;
- char* type1 = (char*) NULL;
- char *type2 = (char*) NULL;
-
- commandTag = "DROP";
- CHECK_IF_ABORTED();
-
- if (lfirst(stmt->args)!=NULL)
- type1 = strVal(lfirst(stmt->args));
- if (lsecond(stmt->args)!=NULL)
- type2 = strVal(lsecond(stmt->args));
- RemoveOperator(stmt->opname, type1, type2);
- }
- break;
-
- case T_VersionStmt:
- {
- elog(WARN, "CREATE VERSION is not currently implemented");
- }
- break;
-
- case T_CreatedbStmt:
- {
- CreatedbStmt *stmt = (CreatedbStmt *)parsetree;
+ case T_RemoveAggrStmt:
+ {
+ RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
- commandTag = "CREATEDB";
- CHECK_IF_ABORTED();
- createdb(stmt->dbname);
- }
- break;
-
- case T_DestroydbStmt:
- {
- DestroydbStmt *stmt = (DestroydbStmt *)parsetree;
+ commandTag = "DROP";
+ CHECK_IF_ABORTED();
+ RemoveAggregate(stmt->aggname, stmt->aggtype);
+ }
+ break;
- commandTag = "DESTROYDB";
- CHECK_IF_ABORTED();
- destroydb(stmt->dbname);
- }
- break;
-
- /* Query-level asynchronous notification */
- case T_NotifyStmt:
- {
- NotifyStmt *stmt = (NotifyStmt *)parsetree;
+ case T_RemoveFuncStmt:
+ {
+ RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
- commandTag = "NOTIFY";
- CHECK_IF_ABORTED();
+ commandTag = "DROP";
+ CHECK_IF_ABORTED();
+ RemoveFunction(stmt->funcname,
+ length(stmt->args),
+ stmt->args);
+ }
+ break;
- Async_Notify(stmt->relname);
- }
- break;
-
- case T_ListenStmt:
- {
- ListenStmt *stmt = (ListenStmt *)parsetree;
+ case T_RemoveOperStmt:
+ {
+ RemoveOperStmt *stmt = (RemoveOperStmt *) parsetree;
+ char *type1 = (char *) NULL;
+ char *type2 = (char *) NULL;
+
+ commandTag = "DROP";
+ CHECK_IF_ABORTED();
+
+ if (lfirst(stmt->args) != NULL)
+ type1 = strVal(lfirst(stmt->args));
+ if (lsecond(stmt->args) != NULL)
+ type2 = strVal(lsecond(stmt->args));
+ RemoveOperator(stmt->opname, type1, type2);
+ }
+ break;
- commandTag = "LISTEN";
- CHECK_IF_ABORTED();
+ case T_VersionStmt:
+ {
+ elog(WARN, "CREATE VERSION is not currently implemented");
+ }
+ break;
- Async_Listen(stmt->relname,MasterPid);
- }
- break;
-
- /* ********************************
- * dynamic loader
- * ********************************
- */
- case T_LoadStmt:
- {
- LoadStmt *stmt = (LoadStmt *)parsetree;
- FILE *fp;
- char *filename;
-
- commandTag = "LOAD";
- CHECK_IF_ABORTED();
-
- filename = stmt->filename;
- closeAllVfds();
- if ((fp = AllocateFile(filename, "r")) == NULL)
- elog(WARN, "LOAD: could not open file %s", filename);
- FreeFile(fp);
- load_file(filename);
- }
- break;
+ case T_CreatedbStmt:
+ {
+ CreatedbStmt *stmt = (CreatedbStmt *) parsetree;
- case T_ClusterStmt:
- {
- ClusterStmt *stmt = (ClusterStmt *)parsetree;
+ commandTag = "CREATEDB";
+ CHECK_IF_ABORTED();
+ createdb(stmt->dbname);
+ }
+ break;
- commandTag = "CLUSTER";
- CHECK_IF_ABORTED();
+ case T_DestroydbStmt:
+ {
+ DestroydbStmt *stmt = (DestroydbStmt *) parsetree;
- cluster(stmt->relname, stmt->indexname);
- }
- break;
-
- case T_VacuumStmt:
- commandTag = "VACUUM";
- CHECK_IF_ABORTED();
- vacuum( ((VacuumStmt *) parsetree)->vacrel,
- ((VacuumStmt *) parsetree)->verbose,
- ((VacuumStmt *) parsetree)->analyze,
- ((VacuumStmt *) parsetree)->va_spec);
- break;
-
- case T_ExplainStmt:
- {
- ExplainStmt *stmt = (ExplainStmt *)parsetree;
+ commandTag = "DESTROYDB";
+ CHECK_IF_ABORTED();
+ destroydb(stmt->dbname);
+ }
+ break;
- commandTag = "EXPLAIN";
- CHECK_IF_ABORTED();
+ /* Query-level asynchronous notification */
+ case T_NotifyStmt:
+ {
+ NotifyStmt *stmt = (NotifyStmt *) parsetree;
- ExplainQuery(stmt->query, stmt->verbose, dest);
- }
- break;
-
- /* ********************************
- Tioga-related statements
- *********************************/
- case T_RecipeStmt:
- {
- RecipeStmt* stmt = (RecipeStmt*)parsetree;
- commandTag="EXECUTE RECIPE";
- CHECK_IF_ABORTED();
- beginRecipe(stmt);
- }
- break;
+ commandTag = "NOTIFY";
+ CHECK_IF_ABORTED();
- /* ********************************
- * set variable statements
- *********************************/
- case T_VariableSetStmt:
- {
- VariableSetStmt *n = (VariableSetStmt *) parsetree;
- SetPGVariable(n->name, n->value);
- commandTag = "SET VARIABLE";
- }
- break;
-
- case T_VariableShowStmt:
- {
- VariableShowStmt *n = (VariableShowStmt *) parsetree;
- GetPGVariable(n->name);
- commandTag = "SHOW VARIABLE";
- }
- break;
-
- case T_VariableResetStmt:
- {
- VariableResetStmt *n = (VariableResetStmt *) parsetree;
- ResetPGVariable(n->name);
- commandTag = "RESET VARIABLE";
+ Async_Notify(stmt->relname);
+ }
+ break;
+
+ case T_ListenStmt:
+ {
+ ListenStmt *stmt = (ListenStmt *) parsetree;
+
+ commandTag = "LISTEN";
+ CHECK_IF_ABORTED();
+
+ Async_Listen(stmt->relname, MasterPid);
+ }
+ break;
+
+ /*
+ * ******************************** dynamic loader ********************************
+ *
+ */
+ case T_LoadStmt:
+ {
+ LoadStmt *stmt = (LoadStmt *) parsetree;
+ FILE *fp;
+ char *filename;
+
+ commandTag = "LOAD";
+ CHECK_IF_ABORTED();
+
+ filename = stmt->filename;
+ closeAllVfds();
+ if ((fp = AllocateFile(filename, "r")) == NULL)
+ elog(WARN, "LOAD: could not open file %s", filename);
+ FreeFile(fp);
+ load_file(filename);
+ }
+ break;
+
+ case T_ClusterStmt:
+ {
+ ClusterStmt *stmt = (ClusterStmt *) parsetree;
+
+ commandTag = "CLUSTER";
+ CHECK_IF_ABORTED();
+
+ cluster(stmt->relname, stmt->indexname);
+ }
+ break;
+
+ case T_VacuumStmt:
+ commandTag = "VACUUM";
+ CHECK_IF_ABORTED();
+ vacuum(((VacuumStmt *) parsetree)->vacrel,
+ ((VacuumStmt *) parsetree)->verbose,
+ ((VacuumStmt *) parsetree)->analyze,
+ ((VacuumStmt *) parsetree)->va_spec);
+ break;
+
+ case T_ExplainStmt:
+ {
+ ExplainStmt *stmt = (ExplainStmt *) parsetree;
+
+ commandTag = "EXPLAIN";
+ CHECK_IF_ABORTED();
+
+ ExplainQuery(stmt->query, stmt->verbose, dest);
+ }
+ break;
+
+ /*
+ * ******************************** Tioga-related statements *******************************
+ */
+ case T_RecipeStmt:
+ {
+ RecipeStmt *stmt = (RecipeStmt *) parsetree;
+
+ commandTag = "EXECUTE RECIPE";
+ CHECK_IF_ABORTED();
+ beginRecipe(stmt);
+ }
+ break;
+
+ /*
+ * ******************************** set variable statements *******************************
+ */
+ case T_VariableSetStmt:
+ {
+ VariableSetStmt *n = (VariableSetStmt *) parsetree;
+
+ SetPGVariable(n->name, n->value);
+ commandTag = "SET VARIABLE";
+ }
+ break;
+
+ case T_VariableShowStmt:
+ {
+ VariableShowStmt *n = (VariableShowStmt *) parsetree;
+
+ GetPGVariable(n->name);
+ commandTag = "SHOW VARIABLE";
+ }
+ break;
+
+ case T_VariableResetStmt:
+ {
+ VariableResetStmt *n = (VariableResetStmt *) parsetree;
+
+ ResetPGVariable(n->name);
+ commandTag = "RESET VARIABLE";
+ }
+ break;
+
+ /*
+ * ******************************** TRIGGER statements *******************************
+ */
+ case T_CreateTrigStmt:
+ commandTag = "CREATE";
+ CHECK_IF_ABORTED();
+
+ CreateTrigger((CreateTrigStmt *) parsetree);
+ break;
+
+ case T_DropTrigStmt:
+ commandTag = "DROP";
+ CHECK_IF_ABORTED();
+
+ DropTrigger((DropTrigStmt *) parsetree);
+ break;
+
+ /*
+ * ******************************** default ********************************
+ *
+ */
+ default:
+ elog(WARN, "ProcessUtility: command #%d unsupported",
+ nodeTag(parsetree));
+ break;
}
- break;
-
- /* ********************************
- * TRIGGER statements
- *********************************/
- case T_CreateTrigStmt:
- commandTag = "CREATE";
- CHECK_IF_ABORTED();
-
- CreateTrigger((CreateTrigStmt *)parsetree);
- break;
-
- case T_DropTrigStmt:
- commandTag = "DROP";
- CHECK_IF_ABORTED();
-
- DropTrigger((DropTrigStmt *)parsetree);
- break;
-
- /* ********************************
- * default
- * ********************************
+
+ /* ----------------
+ * tell fe/be or whatever that we're done.
+ * ----------------
*/
- default:
- elog(WARN, "ProcessUtility: command #%d unsupported",
- nodeTag(parsetree));
- break;
- }
-
- /* ----------------
- * tell fe/be or whatever that we're done.
- * ----------------
- */
- EndCommand(commandTag, dest);
+ EndCommand(commandTag, dest);
}
-
diff --git a/src/backend/tcop/variable.c b/src/backend/tcop/variable.c
index c2a2a754e95..d394881ab3a 100644
--- a/src/backend/tcop/variable.c
+++ b/src/backend/tcop/variable.c
@@ -2,7 +2,7 @@
* Routines for handling of 'SET var TO', 'SHOW var' and 'RESET var'
* statements.
*
- * $Id: variable.c,v 1.13 1997/08/12 20:15:50 momjian Exp $
+ * $Id: variable.c,v 1.14 1997/09/07 04:49:37 momjian Exp $
*
*/
@@ -15,421 +15,471 @@
#include "utils/builtins.h"
#include "optimizer/internal.h"
-extern Cost _cpu_page_wight_;
-extern Cost _cpu_index_page_wight_;
-extern bool _use_geqo_;
-extern int32 _use_geqo_rels_;
-extern bool _use_right_sided_plans_;
+extern Cost _cpu_page_wight_;
+extern Cost _cpu_index_page_wight_;
+extern bool _use_geqo_;
+extern int32 _use_geqo_rels_;
+extern bool _use_right_sided_plans_;
/*-----------------------------------------------------------------------*/
#if USE_EURODATES
-#define DATE_EURO TRUE
+#define DATE_EURO TRUE
#else
#define DATE_EURO FALSE
#endif
/*-----------------------------------------------------------------------*/
struct PGVariables PGVariables =
- {
- { DATE_EURO, Date_Postgres }
- };
+{
+ {DATE_EURO, Date_Postgres}
+};
/*-----------------------------------------------------------------------*/
-static const char *get_token(char **tok, char **val, const char *str)
+static const char *
+get_token(char **tok, char **val, const char *str)
{
- const char *start;
- int len = 0;
-
- *tok = NULL;
- if (val != NULL) *val = NULL;
-
- if ( !(*str) )
- return NULL;
-
- /* skip white spaces */
- while (isspace(*str)) str++;
- if ( *str == ',' || *str == '=' )
- elog(WARN, "Syntax error near (%s): empty setting", str);
-
- /* end of string? then return NULL */
- if ( !(*str) )
- return NULL;
-
- /* OK, at beginning of non-NULL string... */
- start = str;
-
- /*
- * count chars in token until we hit white space or comma
- * or '=' or end of string
- */
- while ( *str && (! isspace(*str))
- && *str != ',' && *str != '=' )
- {
- str++;
- len++;
- }
-
- *tok = (char*) PALLOC(len + 1);
- strNcpy (*tok, start, len);
-
- /* skip white spaces */
- while ( isspace(*str)) str++;
-
- /* end of string? */
- if ( !(*str) ) {
- return(str);
-
- /* delimiter? */
- } else if ( *str == ',' ) {
- return (++str);
-
- } else if ((val == NULL) || ( *str != '=' )) {
+ const char *start;
+ int len = 0;
+
+ *tok = NULL;
+ if (val != NULL)
+ *val = NULL;
+
+ if (!(*str))
+ return NULL;
+
+ /* skip white spaces */
+ while (isspace(*str))
+ str++;
+ if (*str == ',' || *str == '=')
+ elog(WARN, "Syntax error near (%s): empty setting", str);
+
+ /* end of string? then return NULL */
+ if (!(*str))
+ return NULL;
+
+ /* OK, at beginning of non-NULL string... */
+ start = str;
+
+ /*
+ * count chars in token until we hit white space or comma or '=' or
+ * end of string
+ */
+ while (*str && (!isspace(*str))
+ && *str != ',' && *str != '=')
+ {
+ str++;
+ len++;
+ }
+
+ *tok = (char *) PALLOC(len + 1);
+ strNcpy(*tok, start, len);
+
+ /* skip white spaces */
+ while (isspace(*str))
+ str++;
+
+ /* end of string? */
+ if (!(*str))
+ {
+ return (str);
+
+ /* delimiter? */
+ }
+ else if (*str == ',')
+ {
+ return (++str);
+
+ }
+ else if ((val == NULL) || (*str != '='))
+ {
+ elog(WARN, "Syntax error near (%s)", str);
+ };
+
+ str++; /* '=': get value */
+ len = 0;
+
+ /* skip white spaces */
+ while (isspace(*str))
+ str++;
+
+ if (*str == ',' || !(*str))
+ elog(WARN, "Syntax error near (=%s)", str);
+
+ start = str;
+
+ /*
+ * count chars in token's value until we hit white space or comma or
+ * end of string
+ */
+ while (*str && (!isspace(*str)) && *str != ',')
+ {
+ str++;
+ len++;
+ }
+
+ *val = (char *) PALLOC(len + 1);
+ strNcpy(*val, start, len);
+
+ /* skip white spaces */
+ while (isspace(*str))
+ str++;
+
+ if (!(*str))
+ return (NULL);
+ if (*str == ',')
+ return (++str);
+
elog(WARN, "Syntax error near (%s)", str);
- };
-
- str++; /* '=': get value */
- len = 0;
-
- /* skip white spaces */
- while ( isspace(*str)) str++;
-
- if ( *str == ',' || !(*str) )
- elog(WARN, "Syntax error near (=%s)", str);
-
- start = str;
-
- /*
- * count chars in token's value until we hit white space or comma
- * or end of string
- */
- while ( *str && (! isspace(*str)) && *str != ',' )
- {
- str++;
- len++;
- }
-
- *val = (char*) PALLOC(len + 1);
- strNcpy (*val, start, len);
-
- /* skip white spaces */
- while ( isspace(*str)) str++;
-
- if ( !(*str) )
- return (NULL);
- if ( *str == ',' )
- return (++str);
-
- elog(WARN, "Syntax error near (%s)", str);
-
- return str;
+
+ return str;
}
/*-----------------------------------------------------------------------*/
-static bool parse_null(const char *value)
- {
+static bool
+parse_null(const char *value)
+{
return TRUE;
- }
+}
-static bool show_null(const char *value)
- {
+static bool
+show_null(const char *value)
+{
return TRUE;
- }
+}
-static bool reset_null(const char *value)
- {
+static bool
+reset_null(const char *value)
+{
return TRUE;
- }
+}
-static bool parse_geqo (const char *value)
+static bool
+parse_geqo(const char *value)
{
- const char *rest;
- char *tok, *val;
-
- rest = get_token (&tok, &val, value);
- if ( tok == NULL )
- elog(WARN, "Value undefined");
-
- if (( rest ) && ( *rest != '\0' ))
- elog(WARN, "Unable to parse '%s'", value);
-
- if ( strcasecmp (tok, "on") == 0 )
- {
- int32 geqo_rels = GEQO_RELS;
-
- if ( val != NULL )
- {
- geqo_rels = pg_atoi (val, sizeof(int32), '\0');
- if ( geqo_rels <= 1 )
- elog(WARN, "Bad value for # of relations (%s)", val);
- PFREE(val);
- }
- _use_geqo_ = true;
- _use_geqo_rels_ = geqo_rels;
- }
- else if ( strcasecmp (tok, "off") == 0 )
- {
- if (( val != NULL ) && ( *val != '\0' ))
- elog(WARN, "%s does not allow a parameter",tok);
- _use_geqo_ = false;
- }
- else
- elog(WARN, "Bad value for GEQO (%s)", value);
-
- PFREE(tok);
- return TRUE;
+ const char *rest;
+ char *tok,
+ *val;
+
+ rest = get_token(&tok, &val, value);
+ if (tok == NULL)
+ elog(WARN, "Value undefined");
+
+ if ((rest) && (*rest != '\0'))
+ elog(WARN, "Unable to parse '%s'", value);
+
+ if (strcasecmp(tok, "on") == 0)
+ {
+ int32 geqo_rels = GEQO_RELS;
+
+ if (val != NULL)
+ {
+ geqo_rels = pg_atoi(val, sizeof(int32), '\0');
+ if (geqo_rels <= 1)
+ elog(WARN, "Bad value for # of relations (%s)", val);
+ PFREE(val);
+ }
+ _use_geqo_ = true;
+ _use_geqo_rels_ = geqo_rels;
+ }
+ else if (strcasecmp(tok, "off") == 0)
+ {
+ if ((val != NULL) && (*val != '\0'))
+ elog(WARN, "%s does not allow a parameter", tok);
+ _use_geqo_ = false;
+ }
+ else
+ elog(WARN, "Bad value for GEQO (%s)", value);
+
+ PFREE(tok);
+ return TRUE;
}
-static bool show_geqo ()
+static bool
+show_geqo()
{
- if ( _use_geqo_ )
- elog (NOTICE, "GEQO is ON beginning with %d relations", _use_geqo_rels_);
- else
- elog (NOTICE, "GEQO is OFF");
- return TRUE;
+ if (_use_geqo_)
+ elog(NOTICE, "GEQO is ON beginning with %d relations", _use_geqo_rels_);
+ else
+ elog(NOTICE, "GEQO is OFF");
+ return TRUE;
}
-static bool reset_geqo ()
+static bool
+reset_geqo()
{
#ifdef GEQO
- _use_geqo_ = true;
+ _use_geqo_ = true;
#else
- _use_geqo_ = false;
+ _use_geqo_ = false;
#endif
- _use_geqo_rels_ = GEQO_RELS;
- return TRUE;
+ _use_geqo_rels_ = GEQO_RELS;
+ return TRUE;
}
-static bool parse_r_plans (const char *value)
+static bool
+parse_r_plans(const char *value)
{
- if ( strcasecmp (value, "on") == 0 )
- _use_right_sided_plans_ = true;
- else if ( strcasecmp (value, "off") == 0 )
- _use_right_sided_plans_ = false;
- else
- elog(WARN, "Bad value for Right-sided Plans (%s)", value);
-
- return TRUE;
+ if (strcasecmp(value, "on") == 0)
+ _use_right_sided_plans_ = true;
+ else if (strcasecmp(value, "off") == 0)
+ _use_right_sided_plans_ = false;
+ else
+ elog(WARN, "Bad value for Right-sided Plans (%s)", value);
+
+ return TRUE;
}
-static bool show_r_plans ()
+static bool
+show_r_plans()
{
- if ( _use_right_sided_plans_ )
- elog (NOTICE, "Right-sided Plans are ON");
- else
- elog (NOTICE, "Right-sided Plans are OFF");
- return TRUE;
+ if (_use_right_sided_plans_)
+ elog(NOTICE, "Right-sided Plans are ON");
+ else
+ elog(NOTICE, "Right-sided Plans are OFF");
+ return TRUE;
}
-static bool reset_r_plans ()
+static bool
+reset_r_plans()
{
#ifdef USE_RIGHT_SIDED_PLANS
- _use_right_sided_plans_ = true;
+ _use_right_sided_plans_ = true;
#else
- _use_right_sided_plans_ = false;
+ _use_right_sided_plans_ = false;
#endif
- return TRUE;
+ return TRUE;
}
-static bool parse_cost_heap (const char *value)
+static bool
+parse_cost_heap(const char *value)
{
- float32 res = float4in ((char*)value);
-
- _cpu_page_wight_ = *res;
-
- return TRUE;
+ float32 res = float4in((char *) value);
+
+ _cpu_page_wight_ = *res;
+
+ return TRUE;
}
-static bool show_cost_heap ()
+static bool
+show_cost_heap()
{
- elog (NOTICE, "COST_HEAP is %f", _cpu_page_wight_);
- return TRUE;
+ elog(NOTICE, "COST_HEAP is %f", _cpu_page_wight_);
+ return TRUE;
}
-static bool reset_cost_heap ()
+static bool
+reset_cost_heap()
{
- _cpu_page_wight_ = _CPU_PAGE_WEIGHT_;
- return TRUE;
+ _cpu_page_wight_ = _CPU_PAGE_WEIGHT_;
+ return TRUE;
}
-static bool parse_cost_index (const char *value)
+static bool
+parse_cost_index(const char *value)
{
- float32 res = float4in ((char*)value);
-
- _cpu_index_page_wight_ = *res;
-
- return TRUE;
+ float32 res = float4in((char *) value);
+
+ _cpu_index_page_wight_ = *res;
+
+ return TRUE;
}
-static bool show_cost_index ()
+static bool
+show_cost_index()
{
- elog (NOTICE, "COST_INDEX is %f", _cpu_index_page_wight_);
- return TRUE;
+ elog(NOTICE, "COST_INDEX is %f", _cpu_index_page_wight_);
+ return TRUE;
}
-static bool reset_cost_index ()
+static bool
+reset_cost_index()
{
- _cpu_index_page_wight_ = _CPU_INDEX_PAGE_WEIGHT_;
- return TRUE;
+ _cpu_index_page_wight_ = _CPU_INDEX_PAGE_WEIGHT_;
+ return TRUE;
}
-static bool parse_date(const char *value)
+static bool
+parse_date(const char *value)
{
- char *tok;
- int dcnt = 0, ecnt = 0;
+ char *tok;
+ int dcnt = 0,
+ ecnt = 0;
- while((value = get_token(&tok, NULL, value)) != 0)
+ while ((value = get_token(&tok, NULL, value)) != 0)
{
/* Ugh. Somebody ought to write a table driven version -- mjl */
- if(!strcasecmp(tok, "iso"))
- {
+ if (!strcasecmp(tok, "iso"))
+ {
DateStyle = USE_ISO_DATES;
dcnt++;
- }
- else if(!strcasecmp(tok, "sql"))
- {
+ }
+ else if (!strcasecmp(tok, "sql"))
+ {
DateStyle = USE_SQL_DATES;
dcnt++;
- }
- else if(!strcasecmp(tok, "postgres"))
- {
+ }
+ else if (!strcasecmp(tok, "postgres"))
+ {
DateStyle = USE_POSTGRES_DATES;
dcnt++;
- }
- else if(!strncasecmp(tok, "euro", 4))
- {
+ }
+ else if (!strncasecmp(tok, "euro", 4))
+ {
EuroDates = TRUE;
ecnt++;
- }
- else if((!strcasecmp(tok, "us"))
- || (!strncasecmp(tok, "noneuro", 7)))
- {
+ }
+ else if ((!strcasecmp(tok, "us"))
+ || (!strncasecmp(tok, "noneuro", 7)))
+ {
EuroDates = FALSE;
ecnt++;
- }
- else if(!strcasecmp(tok, "default"))
- {
+ }
+ else if (!strcasecmp(tok, "default"))
+ {
DateStyle = USE_POSTGRES_DATES;
EuroDates = FALSE;
ecnt++;
- }
+ }
else
- {
+ {
elog(WARN, "Bad value for date style (%s)", tok);
- }
+ }
PFREE(tok);
}
- if(dcnt > 1 || ecnt > 1)
+ if (dcnt > 1 || ecnt > 1)
elog(NOTICE, "Conflicting settings for date");
return TRUE;
}
-static bool show_date()
- {
- char buf[64];
+static bool
+show_date()
+{
+ char buf[64];
- strcpy( buf, "DateStyle is ");
- switch (DateStyle) {
+ strcpy(buf, "DateStyle is ");
+ switch (DateStyle)
+ {
case USE_ISO_DATES:
- strcat( buf, "ISO");
+ strcat(buf, "ISO");
break;
case USE_SQL_DATES:
- strcat( buf, "SQL");
+ strcat(buf, "SQL");
break;
default:
- strcat( buf, "Postgres");
+ strcat(buf, "Postgres");
break;
};
- strcat( buf, " with ");
- strcat( buf, ((EuroDates)? "European": "US (NonEuropean)"));
- strcat( buf, " conventions");
+ strcat(buf, " with ");
+ strcat(buf, ((EuroDates) ? "European" : "US (NonEuropean)"));
+ strcat(buf, " conventions");
elog(NOTICE, buf, NULL);
return TRUE;
- }
+}
-static bool reset_date()
- {
+static bool
+reset_date()
+{
DateStyle = USE_POSTGRES_DATES;
EuroDates = FALSE;
return TRUE;
- }
+}
/*-----------------------------------------------------------------------*/
struct VariableParsers
+{
+ const char *name;
+ bool(*parser) (const char *);
+ bool(*show) ();
+ bool(*reset) ();
+} VariableParsers[] =
+
+{
{
- const char *name;
- bool (*parser)(const char *);
- bool (*show)();
- bool (*reset)();
- } VariableParsers[] =
+ "datestyle", parse_date, show_date, reset_date
+ },
{
- { "datestyle", parse_date, show_date, reset_date },
- { "timezone", parse_null, show_null, reset_null },
- { "cost_heap", parse_cost_heap,
- show_cost_heap, reset_cost_heap },
- { "cost_index", parse_cost_index,
- show_cost_index, reset_cost_index },
- { "geqo", parse_geqo, show_geqo, reset_geqo },
- { "r_plans", parse_r_plans, show_r_plans, reset_r_plans },
- { NULL, NULL, NULL }
- };
+ "timezone", parse_null, show_null, reset_null
+ },
+ {
+ "cost_heap", parse_cost_heap,
+ show_cost_heap, reset_cost_heap
+ },
+ {
+ "cost_index", parse_cost_index,
+ show_cost_index, reset_cost_index
+ },
+ {
+ "geqo", parse_geqo, show_geqo, reset_geqo
+ },
+ {
+ "r_plans", parse_r_plans, show_r_plans, reset_r_plans
+ },
+ {
+ NULL, NULL, NULL
+ }
+};
/*-----------------------------------------------------------------------*/
-bool SetPGVariable(const char *name, const char *value)
- {
+bool
+SetPGVariable(const char *name, const char *value)
+{
struct VariableParsers *vp;
- for(vp = VariableParsers; vp->name; vp++)
- {
- if(!strcasecmp(vp->name, name))
- return (vp->parser)(value);
- }
+ for (vp = VariableParsers; vp->name; vp++)
+ {
+ if (!strcasecmp(vp->name, name))
+ return (vp->parser) (value);
+ }
elog(NOTICE, "Unrecognized variable %s", name);
return TRUE;
- }
+}
/*-----------------------------------------------------------------------*/
-bool GetPGVariable(const char *name)
- {
+bool
+GetPGVariable(const char *name)
+{
struct VariableParsers *vp;
- for(vp = VariableParsers; vp->name; vp++)
- {
- if(!strcasecmp(vp->name, name))
- return (vp->show)();
- }
+ for (vp = VariableParsers; vp->name; vp++)
+ {
+ if (!strcasecmp(vp->name, name))
+ return (vp->show) ();
+ }
elog(NOTICE, "Unrecognized variable %s", name);
return TRUE;
- }
+}
/*-----------------------------------------------------------------------*/
-bool ResetPGVariable(const char *name)
- {
+bool
+ResetPGVariable(const char *name)
+{
struct VariableParsers *vp;
- for(vp = VariableParsers; vp->name; vp++)
- {
- if(!strcasecmp(vp->name, name))
- return (vp->reset)();
- }
+ for (vp = VariableParsers; vp->name; vp++)
+ {
+ if (!strcasecmp(vp->name, name))
+ return (vp->reset) ();
+ }
elog(NOTICE, "Unrecognized variable %s", name);
return TRUE;
- }
+}
diff --git a/src/backend/tioga/Arr_TgRecipe.h b/src/backend/tioga/Arr_TgRecipe.h
index 365f4647d6e..c6992732c7f 100644
--- a/src/backend/tioga/Arr_TgRecipe.h
+++ b/src/backend/tioga/Arr_TgRecipe.h
@@ -14,7 +14,7 @@
#define Arr_TgNodePtr_INITIAL_SIZE 32
#endif
/***************************************************************/
-/* Do not modify anything below this line. */
+/* Do not modify anything below this line. */
/***************************************************************/
/* -- Defining types and function for Arr_TgString type -- */
@@ -27,15 +27,17 @@
#define _ARR_TgString_
#ifndef ARR_TgString_INITIAL_SIZE
-#define ARR_TgString_INITIAL_SIZE 32 /* change this size to suit your need */
-#endif /* ARR_TgString_INITIAL_SIZE */
-
-typedef struct Arr_TgString {
- size_t num;
- size_t size;
- size_t valSize;
- TgString *val;
-} Arr_TgString;
+#define ARR_TgString_INITIAL_SIZE 32 /* change this size to suit your
+ * need */
+#endif /* ARR_TgString_INITIAL_SIZE */
+
+typedef struct Arr_TgString
+{
+ size_t num;
+ size_t size;
+ size_t valSize;
+ TgString *val;
+} Arr_TgString;
#define newArr_TgString() \
(Arr_TgString *) NewVarray(ARR_TgString_INITIAL_SIZE, sizeof(TgString))
@@ -49,7 +51,7 @@ typedef struct Arr_TgString {
#define deleteArr_TgString(A) FreeVarray(A)
-#endif /* _ARR_TgString_ */
+#endif /* _ARR_TgString_ */
/* -- Defining types and function for Arr_TgElementPtr type -- */
/* -- the following must be supplied by the user:
@@ -61,15 +63,17 @@ typedef struct Arr_TgString {
#define _ARR_TgElementPtr_
#ifndef ARR_TgElementPtr_INITIAL_SIZE
-#define ARR_TgElementPtr_INITIAL_SIZE 32 /* change this size to suit your need */
-#endif /* ARR_TgElementPtr_INITIAL_SIZE */
-
-typedef struct Arr_TgElementPtr {
- size_t num;
- size_t size;
- size_t valSize;
- TgElementPtr *val;
-} Arr_TgElementPtr;
+#define ARR_TgElementPtr_INITIAL_SIZE 32 /* change this size to
+ * suit your need */
+#endif /* ARR_TgElementPtr_INITIAL_SIZE */
+
+typedef struct Arr_TgElementPtr
+{
+ size_t num;
+ size_t size;
+ size_t valSize;
+ TgElementPtr *val;
+} Arr_TgElementPtr;
#define newArr_TgElementPtr() \
(Arr_TgElementPtr *) NewVarray(ARR_TgElementPtr_INITIAL_SIZE, sizeof(TgElementPtr))
@@ -83,7 +87,7 @@ typedef struct Arr_TgElementPtr {
#define deleteArr_TgElementPtr(A) FreeVarray(A)
-#endif /* _ARR_TgElementPtr_ */
+#endif /* _ARR_TgElementPtr_ */
/* -- Defining types and function for Arr_TgNodePtr type -- */
/* -- the following must be supplied by the user:
@@ -95,15 +99,17 @@ typedef struct Arr_TgElementPtr {
#define _ARR_TgNodePtr_
#ifndef ARR_TgNodePtr_INITIAL_SIZE
-#define ARR_TgNodePtr_INITIAL_SIZE 32 /* change this size to suit your need */
-#endif /* ARR_TgNodePtr_INITIAL_SIZE */
-
-typedef struct Arr_TgNodePtr {
- size_t num;
- size_t size;
- size_t valSize;
- TgNodePtr *val;
-} Arr_TgNodePtr;
+#define ARR_TgNodePtr_INITIAL_SIZE 32 /* change this size to suit your
+ * need */
+#endif /* ARR_TgNodePtr_INITIAL_SIZE */
+
+typedef struct Arr_TgNodePtr
+{
+ size_t num;
+ size_t size;
+ size_t valSize;
+ TgNodePtr *val;
+} Arr_TgNodePtr;
#define newArr_TgNodePtr() \
(Arr_TgNodePtr *) NewVarray(ARR_TgNodePtr_INITIAL_SIZE, sizeof(TgNodePtr))
@@ -117,4 +123,4 @@ typedef struct Arr_TgNodePtr {
#define deleteArr_TgNodePtr(A) FreeVarray(A)
-#endif /* _ARR_TgNodePtr_ */
+#endif /* _ARR_TgNodePtr_ */
diff --git a/src/backend/tioga/Varray.c b/src/backend/tioga/Varray.c
index 3ed45c66561..6279616f7ba 100644
--- a/src/backend/tioga/Varray.c
+++ b/src/backend/tioga/Varray.c
@@ -2,47 +2,49 @@
*
* Varray.c --
*
- * routines to provide a generic set of functions to handle variable sized
- * arrays. originally by Jiang Wu
+ * routines to provide a generic set of functions to handle variable sized
+ * arrays. originally by Jiang Wu
* ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "Varray.h"
-Varray *NewVarray(size_t nobj, size_t size)
+Varray *
+NewVarray(size_t nobj, size_t size)
/*
* NewVarray -- allocate a Varray to contain an array of val each of which
- * is size valSize. Returns the Varray if successful,
- * returns NULL otherwise.
+ * is size valSize. Returns the Varray if successful,
+ * returns NULL otherwise.
*/
{
- Varray *result;
+ Varray *result;
- if (nobj == 0)
- nobj = VARRAY_INITIAL_SIZE;
- result = (Varray *) malloc(sizeof(Varray));
- result->val = (void *) calloc(nobj, size);
- if (result == NULL)
- return NULL;
- result->size = size;
- result->nobj = 0;
- result->maxObj = nobj;
- return result;
+ if (nobj == 0)
+ nobj = VARRAY_INITIAL_SIZE;
+ result = (Varray *) malloc(sizeof(Varray));
+ result->val = (void *) calloc(nobj, size);
+ if (result == NULL)
+ return NULL;
+ result->size = size;
+ result->nobj = 0;
+ result->maxObj = nobj;
+ return result;
}
-int AppendVarray(Varray *array, void *value, CopyingFunct copy)
+int
+AppendVarray(Varray * array, void *value, CopyingFunct copy)
/*
* AppendVarray -- append value to the end of array. This function
- * returns the size of the array after the addition of
- * the new element.
+ * returns the size of the array after the addition of
+ * the new element.
*/
{
- copy(value, VARRAY_NTH(array->val, array->size, array->nobj));
- array->nobj++;
- if (array->nobj >= array->maxObj) {
- ENLARGE_VARRAY(array, array->maxObj / 2);
- }
- return array->nobj;
+ copy(value, VARRAY_NTH(array->val, array->size, array->nobj));
+ array->nobj++;
+ if (array->nobj >= array->maxObj)
+ {
+ ENLARGE_VARRAY(array, array->maxObj / 2);
+ }
+ return array->nobj;
}
-
diff --git a/src/backend/tioga/Varray.h b/src/backend/tioga/Varray.h
index f6d01c23db4..82251d78b3f 100644
--- a/src/backend/tioga/Varray.h
+++ b/src/backend/tioga/Varray.h
@@ -1,45 +1,46 @@
/* ********************************************************************
*
* Varray.h -- header file for varray.c which provides a generic
- * set of functions to handle variable sized arrays.
+ * set of functions to handle variable sized arrays.
*
- * originally by Jiang Wu
+ * originally by Jiang Wu
* ********************************************************************/
#ifndef _VARRAY_H_
#define _VARRAY_H_
-typedef struct _varray {
- size_t nobj; /* number of objects in this array */
- size_t maxObj; /* max. number of objects in this array */
- size_t size; /* size of each element in the array */
- void *val; /* array of elements */
-} Varray;
+typedef struct _varray
+{
+ size_t nobj; /* number of objects in this array */
+ size_t maxObj; /* max. number of objects in this array */
+ size_t size; /* size of each element in the array */
+ void *val; /* array of elements */
+} Varray;
/* type for custom copying function */
-typedef void (*CopyingFunct) (void *from, void *to);
+typedef void (*CopyingFunct) (void *from, void *to);
#define VARRAY_INITIAL_SIZE 32
#define ENLARGE_VARRAY(ARRAY, INC) \
(ARRAY)->maxObj += (INC); \
(ARRAY)->val = (void *) realloc((ARRAY)->val, \
- (ARRAY)->size * (ARRAY)->maxObj)
+ (ARRAY)->size * (ARRAY)->maxObj)
#define VARRAY_NTH(VAL, SIZE, N) (((char *) (VAL)) + (SIZE) * (N))
#define FreeVarray(ARRAY) \
if ((ARRAY) != NULL) { free((ARRAY)->val); free((ARRAY)); (ARRAY) = NULL ; }
-
+
#define ModifyVarray(ARRAY, N, NEW, COPY) \
if ((N) < (ARRAY)->nobj) \
- (COPY)(VARRAY_NTH((ARRAY)->val, (ARRAY)->size, (N)), (NEW))
+ (COPY)(VARRAY_NTH((ARRAY)->val, (ARRAY)->size, (N)), (NEW))
#define GetVarray(ARRAY, N) \
((N) < (ARRAY)->nobj ? VARRAY_NTH((ARRAY)->val, (ARRAY)->size, (N)) \
- : NULL)
+ : NULL)
-extern Varray *NewVarray(size_t nobj, size_t size);
-extern int AppendVarray(Varray *array, void *value, CopyingFunct copy);
+extern Varray *NewVarray(size_t nobj, size_t size);
+extern int AppendVarray(Varray * array, void *value, CopyingFunct copy);
-#endif /* _VARRAY_H_ */
+#endif /* _VARRAY_H_ */
diff --git a/src/backend/tioga/tgRecipe.c b/src/backend/tioga/tgRecipe.c
index ef08f8e3f58..effc221610e 100644
--- a/src/backend/tioga/tgRecipe.c
+++ b/src/backend/tioga/tgRecipe.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* tgRecipe.c--
- * Tioga recipe-related definitions
- * these functions can be used in both the frontend and the
- * backend
- *
- * this file must be kept current with recipe-schema.sql
+ * Tioga recipe-related definitions
+ * these functions can be used in both the frontend and the
+ * backend
+ *
+ * this file must be kept current with recipe-schema.sql
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tioga/Attic/tgRecipe.c,v 1.3 1997/08/12 20:15:52 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tioga/Attic/tgRecipe.c,v 1.4 1997/09/07 04:49:48 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,7 +20,7 @@
#include "postgres.h"
#include "tioga/tgRecipe.h"
-#include "catalog/catalog.h" /*for newoid() */
+#include "catalog/catalog.h" /* for newoid() */
static Arr_TgString *TextArray2ArrTgString(char *str);
@@ -31,81 +31,89 @@ static Arr_TgString *TextArray2ArrTgString(char *str);
#define ARRAY_ELEM_SEPARATOR ','
/* maximum length of query string */
-#define MAX_QBUF_LENGTH 2048
+#define MAX_QBUF_LENGTH 2048
/**** the queries being used ********/
#define Q_RETRIEVE_RECIPE_BYNAME \
- "select * from Recipes where Recipes.elemName = '%s';"
+ "select * from Recipes where Recipes.elemName = '%s';"
#define Q_RETRIEVE_ELEMENTS_IN_RECIPE \
- "select e.* from Element e, Node n where n.belongsTo = '%s' and n.nodeElem = e.elemName;"
+ "select e.* from Element e, Node n where n.belongsTo = '%s' and n.nodeElem = e.elemName;"
#define Q_RETRIEVE_NODES_IN_RECIPE \
- "select * from Node n where n.belongsTo = '%s'"
+ "select * from Node n where n.belongsTo = '%s'"
#define Q_LOOKUP_EDGES_IN_RECIPE \
- "select * from Edge e where e.belongsTo = '%s'"
+ "select * from Edge e where e.belongsTo = '%s'"
/* static functions only used here */
-static void fillTgElement(TgElement *elem, PortalBuffer *pbuf, int tupno);
-static void fillTgNode(TgRecipe *r, TgNode *node, PortalBuffer *pbuf, int tupno);
-static TgRecipe* fillTgRecipe(PortalBuffer* pbuf, int tupno);
-static void lookupEdges(TgRecipe *r, char* name);
-static void fillAllNodes(TgRecipe *r, char* name);
-static void fillAllElements(TgRecipe *r, char* name);
-static TgNode* connectTee(TgRecipe *r, TgNodePtr fromNode, TgNodePtr toNode,
- int fromPort, int toPort);
+static void fillTgElement(TgElement * elem, PortalBuffer * pbuf, int tupno);
+static void fillTgNode(TgRecipe * r, TgNode * node, PortalBuffer * pbuf, int tupno);
+static TgRecipe *fillTgRecipe(PortalBuffer * pbuf, int tupno);
+static void lookupEdges(TgRecipe * r, char *name);
+static void fillAllNodes(TgRecipe * r, char *name);
+static void fillAllElements(TgRecipe * r, char *name);
+static TgNode *
+connectTee(TgRecipe * r, TgNodePtr fromNode, TgNodePtr toNode,
+ int fromPort, int toPort);
/*
* TextArray2ArrTgString -- take a string of the form:
- * {"fooo", "bar", "xxxxx"} (for postgres)
- * and parse it into a Array of TgString's
+ * {"fooo", "bar", "xxxxx"} (for postgres)
+ * and parse it into a Array of TgString's
*
* always returns a valid Arr_TgString. It could be a newly initialized one with
* zero elements
*/
-Arr_TgString*
+Arr_TgString *
TextArray2ArrTgString(char *str)
{
- Arr_TgString *result;
-
- char* beginQuote;
- char* endQuote;
- int nextlen;
- char* word;
-
- result = newArr_TgString();
-
- if ((str == NULL) || (str[0] == '\0'))
- return result;
-
- if (*str != ARRAY_LEFT_DELIM) {
- elog(NOTICE,"TextArray2ArrTgString: badly formed string, must have %c as \
+ Arr_TgString *result;
+
+ char *beginQuote;
+ char *endQuote;
+ int nextlen;
+ char *word;
+
+ result = newArr_TgString();
+
+ if ((str == NULL) || (str[0] == '\0'))
+ return result;
+
+ if (*str != ARRAY_LEFT_DELIM)
+ {
+ elog(NOTICE, "TextArray2ArrTgString: badly formed string, must have %c as \
first character\n", ARRAY_LEFT_DELIM);
- return result;
- }
-
- str++; /* skip the first { */
- while ( *str != '}' ) {
- if (*str == '\0') {
- elog(NOTICE,"TextArray2ArrTgString: text string ended prematurely\n");
- return result;
- }
-
- if ((beginQuote = index(str, ARRAY_ELEM_LEFT)) == NULL) {
- elog(NOTICE,"textArray2ArrTgString: missing a begin quote\n");
- return result;
- }
- if ( (endQuote = index(beginQuote+1,'"')) == NULL) {
- elog(NOTICE,"textArray2ArrTgString: missing an end quote\n");
- return result;
- }
- nextlen = endQuote - beginQuote; /* don't subtract one here because we
- need the extra character for \0 anyway */
- word = (char*) malloc(nextlen);
- strNcpy(word, beginQuote+1, nextlen-1);
- addArr_TgString(result, (TgString*)&word);
- free (word);
- str = endQuote + 1;
- }
- return result;
+ return result;
+ }
+
+ str++; /* skip the first { */
+ while (*str != '}')
+ {
+ if (*str == '\0')
+ {
+ elog(NOTICE, "TextArray2ArrTgString: text string ended prematurely\n");
+ return result;
+ }
+
+ if ((beginQuote = index(str, ARRAY_ELEM_LEFT)) == NULL)
+ {
+ elog(NOTICE, "textArray2ArrTgString: missing a begin quote\n");
+ return result;
+ }
+ if ((endQuote = index(beginQuote + 1, '"')) == NULL)
+ {
+ elog(NOTICE, "textArray2ArrTgString: missing an end quote\n");
+ return result;
+ }
+ nextlen = endQuote - beginQuote; /* don't subtract one here
+ * because we need the
+ * extra character for \0
+ * anyway */
+ word = (char *) malloc(nextlen);
+ strNcpy(word, beginQuote + 1, nextlen - 1);
+ addArr_TgString(result, (TgString *) & word);
+ free(word);
+ str = endQuote + 1;
+ }
+ return result;
}
/* -------------------------------------
@@ -115,20 +123,21 @@ findElemInRecipe()
XXX Currently, this is done by linear search. Change to using a hash table.
-------------------------------------- */
-TgElement*
-findElemInRecipe(TgRecipe *r, char* elemName)
+TgElement *
+findElemInRecipe(TgRecipe * r, char *elemName)
{
- int i;
- Arr_TgElementPtr* arr = r->elements;
- TgElement* e;
-
- for (i=0;i<arr->num;i++) {
- e = (TgElement*)arr->val[i];
- if (strcmp(e->elemName, elemName) == 0)
- return e;
- }
- elog (NOTICE, "Element named %s not found in recipe named %s", elemName, r->elmValue.elemName);
- return NULL;
+ int i;
+ Arr_TgElementPtr *arr = r->elements;
+ TgElement *e;
+
+ for (i = 0; i < arr->num; i++)
+ {
+ e = (TgElement *) arr->val[i];
+ if (strcmp(e->elemName, elemName) == 0)
+ return e;
+ }
+ elog(NOTICE, "Element named %s not found in recipe named %s", elemName, r->elmValue.elemName);
+ return NULL;
}
/* -------------------------------------
@@ -138,271 +147,306 @@ findNodeInRecipe()
XXX Currently, this is done by linear search. Change to using a hash table.
-------------------------------------- */
-TgNode*
-findNodeInRecipe(TgRecipe *r, char* nodeName)
+TgNode *
+findNodeInRecipe(TgRecipe * r, char *nodeName)
{
- int i;
- Arr_TgNodePtr* arr = r->allNodes;
- TgNode *n;
-
- for (i=0;i<arr->num;i++) {
- n = (TgNode*)arr->val[i];
- if (strcmp(n->nodeName, nodeName) == 0)
- return n;
- }
- elog (NOTICE, "Node named %s not found in recipe named %s", nodeName, r->elmValue.elemName);
- return NULL;
+ int i;
+ Arr_TgNodePtr *arr = r->allNodes;
+ TgNode *n;
+
+ for (i = 0; i < arr->num; i++)
+ {
+ n = (TgNode *) arr->val[i];
+ if (strcmp(n->nodeName, nodeName) == 0)
+ return n;
+ }
+ elog(NOTICE, "Node named %s not found in recipe named %s", nodeName, r->elmValue.elemName);
+ return NULL;
}
/* -------------------------------------
fillTgNode
- takes a query result in the PortalBuffer containing a Node
- and converts it to a C Node strcture.
- The Node structure passed in is 'filled' appropriately
+ takes a query result in the PortalBuffer containing a Node
+ and converts it to a C Node strcture.
+ The Node structure passed in is 'filled' appropriately
-------------------------------------- */
void
-fillTgNode(TgRecipe* r, TgNode *node, PortalBuffer *pbuf, int tupno)
+fillTgNode(TgRecipe * r, TgNode * node, PortalBuffer * pbuf, int tupno)
{
- char* nodeType;
- char* nodeElem;
- char* locString; /* ascii string rep of the point */
- static int attnums_initialized = 0;
- static int nodeName_attnum;
- static int nodeElem_attnum;
- static int nodeType_attnum;
- static int loc_attnum;
- TgNodePtr BlankNodePtr;
- int i;
-
- if (!attnums_initialized) {
- /* the first time fillTgNode is called,
- we find out all the relevant attribute numbers in a TgNode
- so subsequent calls are speeded up,
- the assumption is that the schema won't change between calls*/
- nodeName_attnum = PQfnumber(pbuf, tupno, "nodeName");
- nodeElem_attnum = PQfnumber(pbuf, tupno, "nodeElem");
- nodeType_attnum = PQfnumber(pbuf, tupno, "nodeType");
- loc_attnum = PQfnumber(pbuf, tupno, "loc");
- attnums_initialized = 1;
- }
- node->nodeName = PQgetAttr(pbuf, tupno, nodeName_attnum);
- locString = PQgetvalue(pbuf, tupno, loc_attnum);
- if (locString == NULL || locString[0] == '\0') {
- node->loc.x = 0; node->loc.y = 0; /* assign to zero for default */
- }
- else
- {
- float x,y;
- sscanf(locString, "(%f, %f)", &x, &y);
- node->loc.x = x;
- node->loc.y = y;
- }
- nodeElem = PQgetvalue(pbuf, tupno, nodeElem_attnum);
- node->nodeElem = findElemInRecipe(r,nodeElem);
- node->inNodes = newArr_TgNodePtr();
- node->outNodes = newArr_TgNodePtr();
-
- /* fill the inNodes array with as many NULL's are there are inPorts in
- * the underlying element */
- BlankNodePtr = (TgNodePtr)NULL;
- for (i = 0 ; i < node->nodeElem->inPorts->num ; i++)
- addArr_TgNodePtr(node->inNodes, &BlankNodePtr);
-
- /* fill the outNodes array with as many NULL's are there are inPorts in
- * the underlying element */
- for (i = 0 ; i < node->nodeElem->outPorts->num ; i++)
- addArr_TgNodePtr(node->outNodes, &BlankNodePtr);
-
- nodeType = PQgetvalue(pbuf, tupno, nodeType_attnum);
-
- if (strcmp(nodeType, "Ingred") == 0)
- node->nodeType = TG_INGRED_NODE;
- else if (strcmp(nodeType, "Eye") == 0)
- node->nodeType = TG_EYE_NODE;
- else if (strcmp(nodeType, "Recipe") == 0)
- node->nodeType = TG_RECIPE_NODE;
- else
- elog(NOTICE, "fillTgNode: unknown nodeType field value : %s\n", nodeType);
-
+ char *nodeType;
+ char *nodeElem;
+ char *locString; /* ascii string rep of the point */
+ static int attnums_initialized = 0;
+ static int nodeName_attnum;
+ static int nodeElem_attnum;
+ static int nodeType_attnum;
+ static int loc_attnum;
+ TgNodePtr BlankNodePtr;
+ int i;
+
+ if (!attnums_initialized)
+ {
+
+ /*
+ * the first time fillTgNode is called, we find out all the
+ * relevant attribute numbers in a TgNode so subsequent calls are
+ * speeded up, the assumption is that the schema won't change
+ * between calls
+ */
+ nodeName_attnum = PQfnumber(pbuf, tupno, "nodeName");
+ nodeElem_attnum = PQfnumber(pbuf, tupno, "nodeElem");
+ nodeType_attnum = PQfnumber(pbuf, tupno, "nodeType");
+ loc_attnum = PQfnumber(pbuf, tupno, "loc");
+ attnums_initialized = 1;
+ }
+ node->nodeName = PQgetAttr(pbuf, tupno, nodeName_attnum);
+ locString = PQgetvalue(pbuf, tupno, loc_attnum);
+ if (locString == NULL || locString[0] == '\0')
+ {
+ node->loc.x = 0;
+ node->loc.y = 0; /* assign to zero for default */
+ }
+ else
+ {
+ float x,
+ y;
+
+ sscanf(locString, "(%f, %f)", &x, &y);
+ node->loc.x = x;
+ node->loc.y = y;
+ }
+ nodeElem = PQgetvalue(pbuf, tupno, nodeElem_attnum);
+ node->nodeElem = findElemInRecipe(r, nodeElem);
+ node->inNodes = newArr_TgNodePtr();
+ node->outNodes = newArr_TgNodePtr();
+
+ /*
+ * fill the inNodes array with as many NULL's are there are inPorts in
+ * the underlying element
+ */
+ BlankNodePtr = (TgNodePtr) NULL;
+ for (i = 0; i < node->nodeElem->inPorts->num; i++)
+ addArr_TgNodePtr(node->inNodes, &BlankNodePtr);
+
+ /*
+ * fill the outNodes array with as many NULL's are there are inPorts
+ * in the underlying element
+ */
+ for (i = 0; i < node->nodeElem->outPorts->num; i++)
+ addArr_TgNodePtr(node->outNodes, &BlankNodePtr);
+
+ nodeType = PQgetvalue(pbuf, tupno, nodeType_attnum);
+
+ if (strcmp(nodeType, "Ingred") == 0)
+ node->nodeType = TG_INGRED_NODE;
+ else if (strcmp(nodeType, "Eye") == 0)
+ node->nodeType = TG_EYE_NODE;
+ else if (strcmp(nodeType, "Recipe") == 0)
+ node->nodeType = TG_RECIPE_NODE;
+ else
+ elog(NOTICE, "fillTgNode: unknown nodeType field value : %s\n", nodeType);
+
}
/* -------------------------------------
fillTgElement
- takes a query result in the PortalBuffer containing a Element
- and converts it to a C TgElement strcture.
- The TgElement structure passed in is 'filled' appropriately
+ takes a query result in the PortalBuffer containing a Element
+ and converts it to a C TgElement strcture.
+ The TgElement structure passed in is 'filled' appropriately
------------------------------------ */
void
-fillTgElement(TgElement *elem, PortalBuffer *pbuf, int tupno)
+fillTgElement(TgElement * elem, PortalBuffer * pbuf, int tupno)
{
- char* srcLang, *elemType;
- static int attnums_initialized = 0;
- static int elemName_attnum;
- static int elemType_attnum;
- static int inPorts_attnum;
- static int inTypes_attnum;
- static int outPorts_attnum;
- static int outTypes_attnum;
- static int doc_attnum;
- static int keywords_attnum;
- static int icon_attnum;
- static int srcLang_attnum;
- static int src_attnum;
- static int owner_attnum;
-
- if (!attnums_initialized) {
- /* the first time fillTgElement is called,
- we find out all the relevant attribute numbers in a TgElement
- so subsequent calls are speeded up,
- the assumption is that the schema won't change between calls*/
- elemName_attnum = PQfnumber(pbuf, tupno, "elemName");
- elemType_attnum = PQfnumber(pbuf, tupno, "elemType");
- inPorts_attnum = PQfnumber(pbuf, tupno, "inPorts");
- inTypes_attnum = PQfnumber(pbuf, tupno, "inTypes");
- outPorts_attnum = PQfnumber(pbuf, tupno, "outPorts");
- outTypes_attnum = PQfnumber(pbuf, tupno, "outTypes");
- doc_attnum = PQfnumber(pbuf, tupno, "doc");
- keywords_attnum = PQfnumber(pbuf, tupno, "keywords");
- icon_attnum = PQfnumber(pbuf, tupno, "icon");
- srcLang_attnum = PQfnumber(pbuf, tupno, "srcLang");
- src_attnum = PQfnumber(pbuf, tupno, "src");
- attnums_initialized = 1;
- }
-
- elem->elemName = PQgetAttr(pbuf, tupno, elemName_attnum);
- elem->inPorts = TextArray2ArrTgString(PQgetvalue(pbuf, tupno, inPorts_attnum));
- elem->inTypes = TextArray2ArrTgString(PQgetvalue(pbuf, tupno, inTypes_attnum));
- elem->outPorts = TextArray2ArrTgString(PQgetvalue(pbuf, tupno, outPorts_attnum));
- elem->outTypes = TextArray2ArrTgString(PQgetvalue(pbuf, tupno, outTypes_attnum));
- elem->doc = PQgetAttr(pbuf, tupno, doc_attnum);
- elem->keywords = TextArray2ArrTgString(PQgetvalue(pbuf, tupno, keywords_attnum));
- elem->icon = PQgetAttr(pbuf,tupno, icon_attnum);
- elem->src = PQgetAttr(pbuf,tupno, src_attnum);
- elem->owner = PQgetAttr(pbuf,tupno, owner_attnum);
-
- /* we don't need to keep the value returned so use PQgetvalue()
- instead of PQgetAttr() */
- srcLang = PQgetvalue(pbuf,tupno, srcLang_attnum);
-
- if (strcmp(srcLang, "SQL") == 0)
- elem->srcLang = TG_SQL;
- else
- if (strcmp(srcLang, "C") == 0)
- elem->srcLang = TG_C;
- else
- if (strcmp(srcLang, "RecipeGraph") == 0)
- elem->srcLang = TG_RECIPE_GRAPH;
- else
- if (strcmp(srcLang, "Compiled") == 0)
- elem->srcLang = TG_COMPILED;
- else
- elog(NOTICE, "fillTgElement(): unknown srcLang field value : %s\n", srcLang);
-
- elemType = PQgetvalue(pbuf, tupno, elemType_attnum);
- if (strcmp(elemType, "Ingred") == 0)
- elem->elemType = TG_INGRED;
- else if (strcmp(elemType, "Eye") == 0)
- elem->elemType = TG_EYE;
- else if (strcmp(elemType, "Recipe") == 0)
- elem->elemType = TG_RECIPE;
- else
- elog(NOTICE, "fillTgElement(): unknown elemType field value : %s\n", elemType);
+ char *srcLang,
+ *elemType;
+ static int attnums_initialized = 0;
+ static int elemName_attnum;
+ static int elemType_attnum;
+ static int inPorts_attnum;
+ static int inTypes_attnum;
+ static int outPorts_attnum;
+ static int outTypes_attnum;
+ static int doc_attnum;
+ static int keywords_attnum;
+ static int icon_attnum;
+ static int srcLang_attnum;
+ static int src_attnum;
+ static int owner_attnum;
+
+ if (!attnums_initialized)
+ {
+
+ /*
+ * the first time fillTgElement is called, we find out all the
+ * relevant attribute numbers in a TgElement so subsequent calls
+ * are speeded up, the assumption is that the schema won't change
+ * between calls
+ */
+ elemName_attnum = PQfnumber(pbuf, tupno, "elemName");
+ elemType_attnum = PQfnumber(pbuf, tupno, "elemType");
+ inPorts_attnum = PQfnumber(pbuf, tupno, "inPorts");
+ inTypes_attnum = PQfnumber(pbuf, tupno, "inTypes");
+ outPorts_attnum = PQfnumber(pbuf, tupno, "outPorts");
+ outTypes_attnum = PQfnumber(pbuf, tupno, "outTypes");
+ doc_attnum = PQfnumber(pbuf, tupno, "doc");
+ keywords_attnum = PQfnumber(pbuf, tupno, "keywords");
+ icon_attnum = PQfnumber(pbuf, tupno, "icon");
+ srcLang_attnum = PQfnumber(pbuf, tupno, "srcLang");
+ src_attnum = PQfnumber(pbuf, tupno, "src");
+ attnums_initialized = 1;
+ }
+
+ elem->elemName = PQgetAttr(pbuf, tupno, elemName_attnum);
+ elem->inPorts = TextArray2ArrTgString(PQgetvalue(pbuf, tupno, inPorts_attnum));
+ elem->inTypes = TextArray2ArrTgString(PQgetvalue(pbuf, tupno, inTypes_attnum));
+ elem->outPorts = TextArray2ArrTgString(PQgetvalue(pbuf, tupno, outPorts_attnum));
+ elem->outTypes = TextArray2ArrTgString(PQgetvalue(pbuf, tupno, outTypes_attnum));
+ elem->doc = PQgetAttr(pbuf, tupno, doc_attnum);
+ elem->keywords = TextArray2ArrTgString(PQgetvalue(pbuf, tupno, keywords_attnum));
+ elem->icon = PQgetAttr(pbuf, tupno, icon_attnum);
+ elem->src = PQgetAttr(pbuf, tupno, src_attnum);
+ elem->owner = PQgetAttr(pbuf, tupno, owner_attnum);
+
+ /*
+ * we don't need to keep the value returned so use PQgetvalue()
+ * instead of PQgetAttr()
+ */
+ srcLang = PQgetvalue(pbuf, tupno, srcLang_attnum);
+
+ if (strcmp(srcLang, "SQL") == 0)
+ elem->srcLang = TG_SQL;
+ else if (strcmp(srcLang, "C") == 0)
+ elem->srcLang = TG_C;
+ else if (strcmp(srcLang, "RecipeGraph") == 0)
+ elem->srcLang = TG_RECIPE_GRAPH;
+ else if (strcmp(srcLang, "Compiled") == 0)
+ elem->srcLang = TG_COMPILED;
+ else
+ elog(NOTICE, "fillTgElement(): unknown srcLang field value : %s\n", srcLang);
+
+ elemType = PQgetvalue(pbuf, tupno, elemType_attnum);
+ if (strcmp(elemType, "Ingred") == 0)
+ elem->elemType = TG_INGRED;
+ else if (strcmp(elemType, "Eye") == 0)
+ elem->elemType = TG_EYE;
+ else if (strcmp(elemType, "Recipe") == 0)
+ elem->elemType = TG_RECIPE;
+ else
+ elog(NOTICE, "fillTgElement(): unknown elemType field value : %s\n", elemType);
}
+
/* -------------------------------------
-lookupEdges -
- look up the edges of a recipe and fill in the inNodes
- and outNodes of each node.
- In the process of connecting edges, we detect tee's and create
- teeNodes. We add the teeNodes to the allNodes field of r as well
+lookupEdges -
+ look up the edges of a recipe and fill in the inNodes
+ and outNodes of each node.
+ In the process of connecting edges, we detect tee's and create
+ teeNodes. We add the teeNodes to the allNodes field of r as well
------------------------------------ */
-void
-lookupEdges(TgRecipe *r, char* name)
+void
+lookupEdges(TgRecipe * r, char *name)
{
- char qbuf[MAX_QBUF_LENGTH];
- int i;
- char *pqres;
- char *pbufname;
- PortalBuffer *pbuf;
- int ntups;
- int fromNode_attnum;
- int fromPort_attnum;
- int toPort_attnum;
- int toNode_attnum;
- char *toNode, *fromNode;
- char *toPortStr, *fromPortStr;
- int toPort, fromPort;
-
- TgNodePtr fromNodePtr, toNodePtr;
-
- sprintf(qbuf, Q_LOOKUP_EDGES_IN_RECIPE, name);
- pqres = PQexec(qbuf);
- pqres = PQexec(qbuf);
- if (*pqres == 'R' || *pqres == 'E') {
- elog(NOTICE, "lookupEdges(): Error while executing query : %s\n", qbuf);
- elog(NOTICE, "result = %s, error is %s\n", pqres, PQerrormsg);
- return;
- }
- pbufname = ++pqres;
- pbuf = PQparray(pbufname);
- ntups = PQntuplesGroup(pbuf,0);
-
- if (ntups == 0) { return; }
-
- fromNode_attnum = PQfnumber(pbuf, 0, "fromNode");
- fromPort_attnum = PQfnumber(pbuf, 0, "fromPort");
- toNode_attnum = PQfnumber(pbuf, 0, "toNode");
- toPort_attnum = PQfnumber(pbuf, 0, "toPort");
-
- for (i=0;i<ntups;i++) {
-
- fromNode = PQgetvalue(pbuf, i, fromNode_attnum);
- toNode = PQgetvalue(pbuf, i, toNode_attnum);
- fromPortStr = PQgetvalue(pbuf, i, fromPort_attnum);
- toPortStr = PQgetvalue(pbuf, i, toPort_attnum);
-
- if (!fromPortStr || fromPortStr[0] == '\0') {
- elog(NOTICE, "lookupEdges(): SANITY CHECK failed. Edge with invalid fromPort value!");
- return;
- }
- if (!toPortStr || toPortStr[0] == '\0') {
- elog(NOTICE, "lookupEdges(): SANITY CHECK failed. Edge with invalid toPort value!!");
- return;
- }
- fromPort = atoi(fromPortStr);
- toPort = atoi(toPortStr);
-
- fromNodePtr = findNodeInRecipe(r, fromNode);
- if (!fromNodePtr) {
- elog(NOTICE, "lookupEdges(): SANITY CHECK failed. Edge with bad fromNode value!");
- return;
- }
- toNodePtr = findNodeInRecipe(r, toNode);
- if (!toNodePtr) {
- elog(NOTICE, "lookupEdges(): SANITY CHECK failed. Edge with bad toNode value!");
- return;
- }
-
- /* check to see if the from port is already connected.
- if it is, then this means we should construct a Tee node
- */
- if (fromNodePtr->outNodes->val[fromPort-1] != NULL) {
- TgNodePtr tn;
-
- tn = connectTee(r,fromNodePtr, toNodePtr, fromPort, toPort);
- addArr_TgNodePtr(r->allNodes,&tn);
- } else {
- fromNodePtr->outNodes->val[fromPort-1] = toNodePtr;
- toNodePtr->inNodes->val[toPort-1] = fromNodePtr;
- }
- }
-
- PQclear(pbufname);
+ char qbuf[MAX_QBUF_LENGTH];
+ int i;
+ char *pqres;
+ char *pbufname;
+ PortalBuffer *pbuf;
+ int ntups;
+ int fromNode_attnum;
+ int fromPort_attnum;
+ int toPort_attnum;
+ int toNode_attnum;
+ char *toNode,
+ *fromNode;
+ char *toPortStr,
+ *fromPortStr;
+ int toPort,
+ fromPort;
+
+ TgNodePtr fromNodePtr,
+ toNodePtr;
+
+ sprintf(qbuf, Q_LOOKUP_EDGES_IN_RECIPE, name);
+ pqres = PQexec(qbuf);
+ pqres = PQexec(qbuf);
+ if (*pqres == 'R' || *pqres == 'E')
+ {
+ elog(NOTICE, "lookupEdges(): Error while executing query : %s\n", qbuf);
+ elog(NOTICE, "result = %s, error is %s\n", pqres, PQerrormsg);
+ return;
+ }
+ pbufname = ++pqres;
+ pbuf = PQparray(pbufname);
+ ntups = PQntuplesGroup(pbuf, 0);
+
+ if (ntups == 0)
+ {
+ return;
+ }
+
+ fromNode_attnum = PQfnumber(pbuf, 0, "fromNode");
+ fromPort_attnum = PQfnumber(pbuf, 0, "fromPort");
+ toNode_attnum = PQfnumber(pbuf, 0, "toNode");
+ toPort_attnum = PQfnumber(pbuf, 0, "toPort");
+
+ for (i = 0; i < ntups; i++)
+ {
+
+ fromNode = PQgetvalue(pbuf, i, fromNode_attnum);
+ toNode = PQgetvalue(pbuf, i, toNode_attnum);
+ fromPortStr = PQgetvalue(pbuf, i, fromPort_attnum);
+ toPortStr = PQgetvalue(pbuf, i, toPort_attnum);
+
+ if (!fromPortStr || fromPortStr[0] == '\0')
+ {
+ elog(NOTICE, "lookupEdges(): SANITY CHECK failed. Edge with invalid fromPort value!");
+ return;
+ }
+ if (!toPortStr || toPortStr[0] == '\0')
+ {
+ elog(NOTICE, "lookupEdges(): SANITY CHECK failed. Edge with invalid toPort value!!");
+ return;
+ }
+ fromPort = atoi(fromPortStr);
+ toPort = atoi(toPortStr);
+
+ fromNodePtr = findNodeInRecipe(r, fromNode);
+ if (!fromNodePtr)
+ {
+ elog(NOTICE, "lookupEdges(): SANITY CHECK failed. Edge with bad fromNode value!");
+ return;
+ }
+ toNodePtr = findNodeInRecipe(r, toNode);
+ if (!toNodePtr)
+ {
+ elog(NOTICE, "lookupEdges(): SANITY CHECK failed. Edge with bad toNode value!");
+ return;
+ }
+
+ /*
+ * check to see if the from port is already connected. if it is,
+ * then this means we should construct a Tee node
+ */
+ if (fromNodePtr->outNodes->val[fromPort - 1] != NULL)
+ {
+ TgNodePtr tn;
+
+ tn = connectTee(r, fromNodePtr, toNodePtr, fromPort, toPort);
+ addArr_TgNodePtr(r->allNodes, &tn);
+ }
+ else
+ {
+ fromNodePtr->outNodes->val[fromPort - 1] = toNodePtr;
+ toNodePtr->inNodes->val[toPort - 1] = fromNodePtr;
+ }
+ }
+
+ PQclear(pbufname);
}
/*
@@ -412,216 +456,235 @@ lookupEdges(TgRecipe *r, char* name)
returns the teeNode created
*/
-static TgNode*
-connectTee(TgRecipe *r, TgNodePtr fromNode, TgNodePtr toNode,
- int fromPort, int toPort)
+static TgNode *
+connectTee(TgRecipe * r, TgNodePtr fromNode, TgNodePtr toNode,
+ int fromPort, int toPort)
{
- TgNodePtr origToNode;
- TgNodePtr tn;
- TgNodePtr BlankNodePtr;
- int origToPort;
- int i;
-
- /* the toNode formerly pointed to */
- origToNode = fromNode->outNodes->val[fromPort-1];
-
- if (origToNode == NULL) {
- elog(NOTICE,"Internal Error: connectTee() called with a null origToNode");
- return;
- }
-
- for (i=0;i<origToNode->inNodes->num;i++) {
- if (origToNode->inNodes->val[i] == fromNode)
- break;
- }
-
- /* the inport of the former toNode */
- /* ports start with 1, array indices start from 0 */
- origToPort = i + 1;
-
- /* add a tee node now. */
- tn = malloc(sizeof(TgNode));
- /* generate a name for the tee node table */
- tn->nodeName = malloc(50);
- sprintf(tn->nodeName, "tee_%d", newoid());
-/* tn->nodeName = NULL; */
-
- tn->nodeType = TG_TEE_NODE;
- tn->nodeElem = NULL;
- tn->inNodes = newArr_TgNodePtr();
- tn->outNodes = newArr_TgNodePtr();
-
- BlankNodePtr = (TgNodePtr)NULL;
- /* each TgTeeNode has one input and two outputs, NULL them initiallly */
- addArr_TgNodePtr(tn->inNodes, &BlankNodePtr);
- addArr_TgNodePtr(tn->outNodes, &BlankNodePtr);
- addArr_TgNodePtr(tn->outNodes, &BlankNodePtr);
-
- /* make the old toNode the left parent of the tee node
- add the new toNode as the right parent of the tee node */
- tn->outNodes->val[0] = origToNode;
- origToNode->inNodes->val[origToPort-1] = tn;
-
- tn->outNodes->val[1] = toNode;
- toNode->inNodes->val[toPort-1] = tn;
-
- /* connect the fromNode to the new tee node */
- fromNode->outNodes->val[fromPort-1] = tn;
- tn->inNodes->val[0] = fromNode;
-
- return tn;
+ TgNodePtr origToNode;
+ TgNodePtr tn;
+ TgNodePtr BlankNodePtr;
+ int origToPort;
+ int i;
+
+ /* the toNode formerly pointed to */
+ origToNode = fromNode->outNodes->val[fromPort - 1];
+
+ if (origToNode == NULL)
+ {
+ elog(NOTICE, "Internal Error: connectTee() called with a null origToNode");
+ return;
+ }
+
+ for (i = 0; i < origToNode->inNodes->num; i++)
+ {
+ if (origToNode->inNodes->val[i] == fromNode)
+ break;
+ }
+
+ /* the inport of the former toNode */
+ /* ports start with 1, array indices start from 0 */
+ origToPort = i + 1;
+
+ /* add a tee node now. */
+ tn = malloc(sizeof(TgNode));
+ /* generate a name for the tee node table */
+ tn->nodeName = malloc(50);
+ sprintf(tn->nodeName, "tee_%d", newoid());
+/* tn->nodeName = NULL; */
+
+ tn->nodeType = TG_TEE_NODE;
+ tn->nodeElem = NULL;
+ tn->inNodes = newArr_TgNodePtr();
+ tn->outNodes = newArr_TgNodePtr();
+
+ BlankNodePtr = (TgNodePtr) NULL;
+ /* each TgTeeNode has one input and two outputs, NULL them initiallly */
+ addArr_TgNodePtr(tn->inNodes, &BlankNodePtr);
+ addArr_TgNodePtr(tn->outNodes, &BlankNodePtr);
+ addArr_TgNodePtr(tn->outNodes, &BlankNodePtr);
+
+ /*
+ * make the old toNode the left parent of the tee node add the new
+ * toNode as the right parent of the tee node
+ */
+ tn->outNodes->val[0] = origToNode;
+ origToNode->inNodes->val[origToPort - 1] = tn;
+
+ tn->outNodes->val[1] = toNode;
+ toNode->inNodes->val[toPort - 1] = tn;
+
+ /* connect the fromNode to the new tee node */
+ fromNode->outNodes->val[fromPort - 1] = tn;
+ tn->inNodes->val[0] = fromNode;
+
+ return tn;
}
/* -------------------------------------
fillAllNodes
- fill out the nodes of a recipe
+ fill out the nodes of a recipe
------------------------------------ */
-void
-fillAllNodes(TgRecipe *r, char* name)
+void
+fillAllNodes(TgRecipe * r, char *name)
{
- char qbuf[MAX_QBUF_LENGTH];
- int i;
- char *pqres;
- char *pbufname;
- PortalBuffer *pbuf;
- int ntups;
- TgElement *elem;
- TgNode *node;
-
- /* 1) fill out the elements that are in the recipe */
- sprintf(qbuf, Q_RETRIEVE_ELEMENTS_IN_RECIPE, name);
- pqres = PQexec(qbuf);
- if (*pqres == 'R' || *pqres == 'E') {
- elog(NOTICE, "fillAllNodes(): Error while executing query : %s\n", qbuf);
- elog(NOTICE, "result = %s, error is %s\n", pqres, PQerrormsg);
- return;
- }
- pbufname = ++pqres;
- pbuf = PQparray(pbufname);
- ntups = PQntuplesGroup(pbuf,0);
- for (i=0;i<ntups;i++) {
- elem = malloc(sizeof(TgElement));
- fillTgElement(elem, pbuf, i);
- addArr_TgElementPtr(r->elements, &elem);
- }
- PQclear(pbufname);
-
- sprintf(qbuf, Q_RETRIEVE_NODES_IN_RECIPE, name);
- pqres = PQexec(qbuf);
- if (*pqres == 'R' || *pqres == 'E') {
- elog(NOTICE, "fillAllNodes(): Error while executing query : %s\n", qbuf);
- elog(NOTICE, "result = %s, error is %s\n", pqres, PQerrormsg);
- return;
- }
- pbufname = ++pqres;
- pbuf = PQparray(pbufname);
- ntups = PQntuplesGroup(pbuf,0);
- for (i=0;i<ntups;i++) {
- node = malloc(sizeof(TgNode));
- fillTgNode(r, node, pbuf, i);
- addArr_TgNodePtr(r->allNodes, &node);
- }
- PQclear(pbufname);
+ char qbuf[MAX_QBUF_LENGTH];
+ int i;
+ char *pqres;
+ char *pbufname;
+ PortalBuffer *pbuf;
+ int ntups;
+ TgElement *elem;
+ TgNode *node;
+
+ /* 1) fill out the elements that are in the recipe */
+ sprintf(qbuf, Q_RETRIEVE_ELEMENTS_IN_RECIPE, name);
+ pqres = PQexec(qbuf);
+ if (*pqres == 'R' || *pqres == 'E')
+ {
+ elog(NOTICE, "fillAllNodes(): Error while executing query : %s\n", qbuf);
+ elog(NOTICE, "result = %s, error is %s\n", pqres, PQerrormsg);
+ return;
+ }
+ pbufname = ++pqres;
+ pbuf = PQparray(pbufname);
+ ntups = PQntuplesGroup(pbuf, 0);
+ for (i = 0; i < ntups; i++)
+ {
+ elem = malloc(sizeof(TgElement));
+ fillTgElement(elem, pbuf, i);
+ addArr_TgElementPtr(r->elements, &elem);
+ }
+ PQclear(pbufname);
+
+ sprintf(qbuf, Q_RETRIEVE_NODES_IN_RECIPE, name);
+ pqres = PQexec(qbuf);
+ if (*pqres == 'R' || *pqres == 'E')
+ {
+ elog(NOTICE, "fillAllNodes(): Error while executing query : %s\n", qbuf);
+ elog(NOTICE, "result = %s, error is %s\n", pqres, PQerrormsg);
+ return;
+ }
+ pbufname = ++pqres;
+ pbuf = PQparray(pbufname);
+ ntups = PQntuplesGroup(pbuf, 0);
+ for (i = 0; i < ntups; i++)
+ {
+ node = malloc(sizeof(TgNode));
+ fillTgNode(r, node, pbuf, i);
+ addArr_TgNodePtr(r->allNodes, &node);
+ }
+ PQclear(pbufname);
}
/* -------------------------------------
fillAllElements
- fill out the elements of a recipe
+ fill out the elements of a recipe
------------------------------------ */
-void
-fillAllElements(TgRecipe *r, char* name)
+void
+fillAllElements(TgRecipe * r, char *name)
{
- char qbuf[MAX_QBUF_LENGTH];
- int i;
- char *pqres;
- char *pbufname;
- PortalBuffer *pbuf;
- int ntups;
- TgElement *elem;
-
- sprintf(qbuf, Q_RETRIEVE_ELEMENTS_IN_RECIPE, name);
- pqres = PQexec(qbuf);
- if (*pqres == 'R' || *pqres == 'E') {
- elog(NOTICE, "fillAllElements(): Error while executing query : %s\n", qbuf);
- elog(NOTICE, "result = %s, error is %s\n", pqres, PQerrormsg);
- return;
- }
- pbufname = ++pqres;
- pbuf = PQparray(pbufname);
- ntups = PQntuplesGroup(pbuf,0);
- for (i=0;i<ntups;i++) {
- elem = malloc(sizeof(TgElement));
- fillTgElement(elem, pbuf, i);
- addArr_TgElementPtr(r->elements, &elem);
- }
- PQclear(pbufname);
-
+ char qbuf[MAX_QBUF_LENGTH];
+ int i;
+ char *pqres;
+ char *pbufname;
+ PortalBuffer *pbuf;
+ int ntups;
+ TgElement *elem;
+
+ sprintf(qbuf, Q_RETRIEVE_ELEMENTS_IN_RECIPE, name);
+ pqres = PQexec(qbuf);
+ if (*pqres == 'R' || *pqres == 'E')
+ {
+ elog(NOTICE, "fillAllElements(): Error while executing query : %s\n", qbuf);
+ elog(NOTICE, "result = %s, error is %s\n", pqres, PQerrormsg);
+ return;
+ }
+ pbufname = ++pqres;
+ pbuf = PQparray(pbufname);
+ ntups = PQntuplesGroup(pbuf, 0);
+ for (i = 0; i < ntups; i++)
+ {
+ elem = malloc(sizeof(TgElement));
+ fillTgElement(elem, pbuf, i);
+ addArr_TgElementPtr(r->elements, &elem);
+ }
+ PQclear(pbufname);
+
}
/* -------------------------------------
fillTgRecipe
- takes a query result in the PortalBuffer containing a Recipe
- and converts it to a C TgRecipe strcture
+ takes a query result in the PortalBuffer containing a Recipe
+ and converts it to a C TgRecipe strcture
------------------------------------ */
-TgRecipe*
-fillTgRecipe(PortalBuffer* pbuf, int tupno)
+TgRecipe *
+fillTgRecipe(PortalBuffer * pbuf, int tupno)
{
- TgRecipe* r;
- int i,j;
-
- /* 1) set up the recipe structure */
- r = (TgRecipe*)malloc(sizeof(TgRecipe));
- fillTgElement(&r->elmValue, pbuf, 0);
- r->elmValue.elemType = TG_RECIPE;
- r->allNodes = newArr_TgNodePtr();
- r->rootNodes = newArr_TgNodePtr();
- r->eyes = newArr_TgNodePtr();
- r->tees = newArr_TgNodePtr();
- r->elements = newArr_TgElementPtr();
-
- /* 2) find all the elements. There may be less elements than nodes
- because you can have multiple instantiations of an element
- in a recipe*/
- fillAllElements(r, r->elmValue.elemName);
-
- /* 3) find all the nodes in the recipe*/
- fillAllNodes(r, r->elmValue.elemName);
-
- /* 4) find all the edges, and connect the nodes,
- may also add tee nodes to the allNodes field*/
- lookupEdges(r, r->elmValue.elemName);
-
- /* 5) find all the rootNodes in the recipe */
- /* root nodes are nodes with no incoming nodes or
- whose incoming nodes are all null */
- /* 6) find all the eyes in the recipe */
- /* eye nodes are nodes with the node type TG_EYE_NODE */
- /* 7) find all the tee nodes in the recipe */
- /* tee nodes are nodes with the node type TG_TEE_NODE */
- for (i=0;i<r->allNodes->num;i++) {
- TgNode* nptr = r->allNodes->val[i];
-
- if (nptr->nodeType == TG_EYE_NODE)
- addArr_TgNodePtr(r->eyes, &nptr);
- else
- if (nptr->nodeType == TG_TEE_NODE)
- addArr_TgNodePtr(r->tees, &nptr);
-
- if (nptr->inNodes->num == 0)
- addArr_TgNodePtr(r->rootNodes, &nptr);
- else {
- for (j=0;
- j<nptr->inNodes->num && (nptr->inNodes->val[j] == NULL);
- j++);
- if (j == nptr->inNodes->num)
- addArr_TgNodePtr(r->rootNodes, &nptr);
- }
- }
-
- return r;
+ TgRecipe *r;
+ int i,
+ j;
+
+ /* 1) set up the recipe structure */
+ r = (TgRecipe *) malloc(sizeof(TgRecipe));
+ fillTgElement(&r->elmValue, pbuf, 0);
+ r->elmValue.elemType = TG_RECIPE;
+ r->allNodes = newArr_TgNodePtr();
+ r->rootNodes = newArr_TgNodePtr();
+ r->eyes = newArr_TgNodePtr();
+ r->tees = newArr_TgNodePtr();
+ r->elements = newArr_TgElementPtr();
+
+ /*
+ * 2) find all the elements. There may be less elements than nodes
+ * because you can have multiple instantiations of an element in a
+ * recipe
+ */
+ fillAllElements(r, r->elmValue.elemName);
+
+ /* 3) find all the nodes in the recipe */
+ fillAllNodes(r, r->elmValue.elemName);
+
+ /*
+ * 4) find all the edges, and connect the nodes, may also add tee
+ * nodes to the allNodes field
+ */
+ lookupEdges(r, r->elmValue.elemName);
+
+ /* 5) find all the rootNodes in the recipe */
+
+ /*
+ * root nodes are nodes with no incoming nodes or whose incoming nodes
+ * are all null
+ */
+ /* 6) find all the eyes in the recipe */
+ /* eye nodes are nodes with the node type TG_EYE_NODE */
+ /* 7) find all the tee nodes in the recipe */
+ /* tee nodes are nodes with the node type TG_TEE_NODE */
+ for (i = 0; i < r->allNodes->num; i++)
+ {
+ TgNode *nptr = r->allNodes->val[i];
+
+ if (nptr->nodeType == TG_EYE_NODE)
+ addArr_TgNodePtr(r->eyes, &nptr);
+ else if (nptr->nodeType == TG_TEE_NODE)
+ addArr_TgNodePtr(r->tees, &nptr);
+
+ if (nptr->inNodes->num == 0)
+ addArr_TgNodePtr(r->rootNodes, &nptr);
+ else
+ {
+ for (j = 0;
+ j < nptr->inNodes->num && (nptr->inNodes->val[j] == NULL);
+ j++);
+ if (j == nptr->inNodes->num)
+ addArr_TgNodePtr(r->rootNodes, &nptr);
+ }
+ }
+
+ return r;
}
@@ -630,65 +693,72 @@ fillTgRecipe(PortalBuffer* pbuf, int tupno)
retrieveRecipe
find the recipe with the given name
------------------------------------ */
-TgRecipe*
-retrieveRecipe(char* name)
+TgRecipe *
+retrieveRecipe(char *name)
{
- char qbuf[MAX_QBUF_LENGTH];
- TgRecipe* recipe;
- char *pqres;
- char *pbufname;
- PortalBuffer *pbuf;
- int ntups;
-
- sprintf(qbuf, Q_RETRIEVE_RECIPE_BYNAME, name);
-
- pqres = PQexec(qbuf);
- if (*pqres == 'R' || *pqres == 'E') {
- elog(NOTICE, "retrieveRecipe: Error while executing query : %s\n", qbuf);
- elog(NOTICE, "result = %s, error is %s\n", pqres, PQerrormsg);
- return NULL;
- }
- pbufname = ++pqres;
- pbuf = PQparray(pbufname);
- ntups = PQntuplesGroup(pbuf,0);
- if (ntups == 0) {
- elog(NOTICE, "retrieveRecipe(): No recipe named %s exists\n", name);
- return NULL;
- }
- if (ntups != 1) {
- elog(NOTICE, "retrieveRecipe(): Multiple (%d) recipes named %s exists\n", ntups, name);
- return NULL;
- }
-
- recipe = fillTgRecipe(pbuf,0);
-
- PQclear(pbufname);
- return recipe;
+ char qbuf[MAX_QBUF_LENGTH];
+ TgRecipe *recipe;
+ char *pqres;
+ char *pbufname;
+ PortalBuffer *pbuf;
+ int ntups;
+
+ sprintf(qbuf, Q_RETRIEVE_RECIPE_BYNAME, name);
+
+ pqres = PQexec(qbuf);
+ if (*pqres == 'R' || *pqres == 'E')
+ {
+ elog(NOTICE, "retrieveRecipe: Error while executing query : %s\n", qbuf);
+ elog(NOTICE, "result = %s, error is %s\n", pqres, PQerrormsg);
+ return NULL;
+ }
+ pbufname = ++pqres;
+ pbuf = PQparray(pbufname);
+ ntups = PQntuplesGroup(pbuf, 0);
+ if (ntups == 0)
+ {
+ elog(NOTICE, "retrieveRecipe(): No recipe named %s exists\n", name);
+ return NULL;
+ }
+ if (ntups != 1)
+ {
+ elog(NOTICE, "retrieveRecipe(): Multiple (%d) recipes named %s exists\n", ntups, name);
+ return NULL;
+ }
+
+ recipe = fillTgRecipe(pbuf, 0);
+
+ PQclear(pbufname);
+ return recipe;
}
/* -------------------- copyXXX functions ----------------------- */
-void copyTgElementPtr(TgElementPtr* from, TgElementPtr* to)
+void
+copyTgElementPtr(TgElementPtr * from, TgElementPtr * to)
{
- *to = *from;
+ *to = *from;
}
-void copyTgNodePtr(TgNodePtr* from, TgNodePtr* to)
+void
+copyTgNodePtr(TgNodePtr * from, TgNodePtr * to)
{
- *to = *from;
+ *to = *from;
}
-void copyTgRecipePtr(TgRecipePtr* from, TgRecipePtr* to)
+void
+copyTgRecipePtr(TgRecipePtr * from, TgRecipePtr * to)
{
- *to = *from;
+ *to = *from;
}
-void copyTgString(TgString* from, TgString* to)
+void
+copyTgString(TgString * from, TgString * to)
{
- TgString fromTgString = *from;
- TgString toTgString;
- toTgString = (TgString)malloc(strlen(fromTgString)+1);
- strcpy(toTgString, fromTgString);
- *to = toTgString;
-}
+ TgString fromTgString = *from;
+ TgString toTgString;
+ toTgString = (TgString) malloc(strlen(fromTgString) + 1);
+ strcpy(toTgString, fromTgString);
+ *to = toTgString;
+}
diff --git a/src/backend/tioga/tgRecipe.h b/src/backend/tioga/tgRecipe.h
index c6ee78e5068..669092982bc 100644
--- a/src/backend/tioga/tgRecipe.h
+++ b/src/backend/tioga/tgRecipe.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* tgRecipe.h--
- * Tioga recipe-related definitions and declarations
- * these functions can be used in both the frontend and the
- * backend
- *
- * to use this header, you must also include
- * "utils/geo-decls.h"
- * and "libpq/libpq.h"
+ * Tioga recipe-related definitions and declarations
+ * these functions can be used in both the frontend and the
+ * backend
+ *
+ * to use this header, you must also include
+ * "utils/geo-decls.h"
+ * and "libpq/libpq.h"
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: tgRecipe.h,v 1.1.1.1 1996/07/09 06:22:00 scrappy Exp $
+ * $Id: tgRecipe.h,v 1.2 1997/09/07 04:49:50 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,99 +23,112 @@
#include "utils/geo-decls.h"
#else
#include "libpq-fe.h"
-typedef struct {
- double x, y;
-} Point; /* this should match whatever is in geo-decls.h*/
-#endif /* TIOGA_FRONTEND */
-
-typedef enum {TG_INGRED,
- TG_EYE,
- TG_RECIPE} TgElemType;
-
-typedef enum { TG_SQL,
- TG_C,
- TG_RECIPE_GRAPH,
- TG_COMPILED
- } TgSrcLangType;
-
-typedef enum { TG_INGRED_NODE,
- TG_EYE_NODE,
- TG_RECIPE_NODE,
- TG_TEE_NODE /* tee nodes are not stored in the db
- we create them when we read the recipe
- back */
- } TgNodeType;
+typedef struct
+{
+ double x,
+ y;
+} Point; /* this should match whatever is in
+
+ * geo-decls.h */
+
+#endif /* TIOGA_FRONTEND */
+
+typedef enum
+{
+ TG_INGRED,
+ TG_EYE,
+ TG_RECIPE
+} TgElemType;
+
+typedef enum
+{
+ TG_SQL,
+ TG_C,
+ TG_RECIPE_GRAPH,
+ TG_COMPILED
+} TgSrcLangType;
+
+typedef enum
+{
+ TG_INGRED_NODE,
+ TG_EYE_NODE,
+ TG_RECIPE_NODE,
+ TG_TEE_NODE /* tee nodes are not stored in the db we
+ * create them when we read the recipe
+ * back */
+} TgNodeType;
/* -- type definition for setting up in memory Tioga recipe structure -- */
/* -- see 'recipe-schema.sql' for their corresponding database types -- */
-typedef char *TgString;
+typedef char *TgString;
typedef struct _tgelement *TgElementPtr;
-typedef struct _tgnode *TgNodePtr;
-typedef struct _tgrecipe *TgRecipePtr;
+typedef struct _tgnode *TgNodePtr;
+typedef struct _tgrecipe *TgRecipePtr;
/* auto-generated header containing Arr_TgString, Arr_TgElementPtr,
and Arr_TgNodePtr */
-#include "tioga/Arr_TgRecipe.h"
+#include "tioga/Arr_TgRecipe.h"
/* C structure representation of a Tioga Element */
-typedef struct _tgelement {
- char *elemName; /* name of function this element represent */
- TgElemType elemType; /* type of this element */
- Arr_TgString *inPorts; /* names of inputs */
- Arr_TgString *inTypes; /* name of input types */
- Arr_TgString *outPorts; /* type of output */
- Arr_TgString *outTypes; /* name of output types */
- char *doc; /* description of this element */
- Arr_TgString *keywords; /* keywords used to search for this element */
- char *icon; /* iconic representation */
- char *src; /* source code for this element */
- TgSrcLangType srcLang; /* source language */
- char *owner; /* owner recipe name */
-} TgElement;
+typedef struct _tgelement
+{
+ char *elemName; /* name of function this element represent */
+ TgElemType elemType; /* type of this element */
+ Arr_TgString *inPorts; /* names of inputs */
+ Arr_TgString *inTypes; /* name of input types */
+ Arr_TgString *outPorts; /* type of output */
+ Arr_TgString *outTypes; /* name of output types */
+ char *doc; /* description of this element */
+ Arr_TgString *keywords; /* keywords used to search for this
+ * element */
+ char *icon; /* iconic representation */
+ char *src; /* source code for this element */
+ TgSrcLangType srcLang; /* source language */
+ char *owner; /* owner recipe name */
+} TgElement;
/* C structure representation of a Tioga Node */
-typedef struct _tgnode {
- char *nodeName; /* name of this node */
- TgNodeType nodeType; /* type of this node */
- Point loc; /* screen location of the node. */
- TgElement *nodeElem; /* the underlying element of this node */
- Arr_TgNodePtr *inNodes; /* variable array of in node pointers
- * a NULL TgNodePtr indicates a run-time
- * parameter*/
- Arr_TgNodePtr *outNodes; /* variable array of out node pointers. */
-} TgNode;
+typedef struct _tgnode
+{
+ char *nodeName; /* name of this node */
+ TgNodeType nodeType; /* type of this node */
+ Point loc; /* screen location of the node. */
+ TgElement *nodeElem; /* the underlying element of this node */
+ Arr_TgNodePtr *inNodes; /* variable array of in node pointers a
+ * NULL TgNodePtr indicates a run-time
+ * parameter */
+ Arr_TgNodePtr *outNodes; /* variable array of out node pointers. */
+} TgNode;
/* C structure representation of a Tioga Recipe */
-typedef struct _tgrecipe {
- TgElement elmValue; /* "inherits" TgElement attributes. */
- Arr_TgNodePtr *allNodes; /* array of all nodes for this recipe. */
- Arr_TgNodePtr *rootNodes; /* array of root nodes for this recipe. --
- root nodes are nodes with no parents */
- Arr_TgNodePtr *eyes; /* array of pointers for the browser nodes
- * recipe, execution of recipe starts
- * by traversing the recipe C structure
- * from the eye nodes pointed by these
- * pointers. */
- Arr_TgNodePtr *tees; /* array of pointers of all the tee nodes */
- Arr_TgElementPtr *elements; /* array of all the elements in this recipe,
- * elements may be shared by multiple nodes */
-
-} TgRecipe;
+typedef struct _tgrecipe
+{
+ TgElement elmValue; /* "inherits" TgElement attributes. */
+ Arr_TgNodePtr *allNodes; /* array of all nodes for this recipe. */
+ Arr_TgNodePtr *rootNodes; /* array of root nodes for this recipe. --
+ * root nodes are nodes with no parents */
+ Arr_TgNodePtr *eyes; /* array of pointers for the browser nodes
+ * recipe, execution of recipe starts by
+ * traversing the recipe C structure from
+ * the eye nodes pointed by these
+ * pointers. */
+ Arr_TgNodePtr *tees; /* array of pointers of all the tee nodes */
+ Arr_TgElementPtr *elements; /* array of all the elements in this
+ * recipe, elements may be shared by
+ * multiple nodes */
+
+} TgRecipe;
/* functions defined in tgRecipe.c */
-extern TgRecipe* retrieveRecipe(char* name);
-extern TgElement* findElemInRecipe(TgRecipe *r, char* elemName);
-extern TgNode* findNodeInRecipe(TgRecipe *r, char* nodeName);
+extern TgRecipe *retrieveRecipe(char *name);
+extern TgElement *findElemInRecipe(TgRecipe * r, char *elemName);
+extern TgNode *findNodeInRecipe(TgRecipe * r, char *nodeName);
/* ---- copyXXX functions ---- */
-extern void copyTgElementPtr(TgElementPtr *, TgElementPtr *);
-extern void copyTgNodePtr(TgNodePtr *, TgNodePtr *);
-extern void copyTgRecipePtr(TgRecipePtr *, TgRecipePtr *);
-extern void copyTgString(TgString *, TgString *);
-
-
-
-
+extern void copyTgElementPtr(TgElementPtr *, TgElementPtr *);
+extern void copyTgNodePtr(TgNodePtr *, TgNodePtr *);
+extern void copyTgRecipePtr(TgRecipePtr *, TgRecipePtr *);
+extern void copyTgString(TgString *, TgString *);
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 33580a95125..d4b8f1ca0b6 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* acl.c--
- * Basic access control list data structures manipulation routines.
+ * Basic access control list data structures manipulation routines.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.13 1997/08/19 21:34:10 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.14 1997/09/07 04:49:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,561 +21,629 @@
#include "utils/syscache.h"
#include "miscadmin.h"
-static char *getid(char *s, char *n);
-static int32 aclitemeq(AclItem *a1, AclItem *a2);
-static int32 aclitemgt(AclItem *a1, AclItem *a2);
-static char *aclparse(char *s, AclItem *aip, unsigned *modechg);
+static char *getid(char *s, char *n);
+static int32 aclitemeq(AclItem * a1, AclItem * a2);
+static int32 aclitemgt(AclItem * a1, AclItem * a2);
+static char *aclparse(char *s, AclItem * aip, unsigned *modechg);
-#define ACL_IDTYPE_GID_KEYWORD "group"
-#define ACL_IDTYPE_UID_KEYWORD "user"
+#define ACL_IDTYPE_GID_KEYWORD "group"
+#define ACL_IDTYPE_UID_KEYWORD "user"
/*
* getid
- * Consumes the first alphanumeric string (identifier) found in string
- * 's', ignoring any leading white space.
+ * Consumes the first alphanumeric string (identifier) found in string
+ * 's', ignoring any leading white space.
*
* RETURNS:
- * the string position in 's' that points to the next non-space character
- * in 's'. Also:
- * - loads the identifier into 'name'. (If no identifier is found, 'name'
- * contains an empty string).
+ * the string position in 's' that points to the next non-space character
+ * in 's'. Also:
+ * - loads the identifier into 'name'. (If no identifier is found, 'name'
+ * contains an empty string).
*/
-static char *
+static char *
getid(char *s, char *n)
{
- unsigned len;
- char *id;
-
- Assert(s && n);
-
- while (isspace(*s))
- ++s;
- for (id = s, len = 0; isalnum(*s) || *s == '_'; ++len, ++s)
- ;
- if (len > sizeof(NameData))
- elog(WARN, "getid: identifier cannot be >%d characters",
- sizeof(NameData));
- if (len > 0)
- memmove(n, id, len);
- n[len] = '\0';
- while (isspace(*s))
- ++s;
- return(s);
+ unsigned len;
+ char *id;
+
+ Assert(s && n);
+
+ while (isspace(*s))
+ ++s;
+ for (id = s, len = 0; isalnum(*s) || *s == '_'; ++len, ++s)
+ ;
+ if (len > sizeof(NameData))
+ elog(WARN, "getid: identifier cannot be >%d characters",
+ sizeof(NameData));
+ if (len > 0)
+ memmove(n, id, len);
+ n[len] = '\0';
+ while (isspace(*s))
+ ++s;
+ return (s);
}
/*
* aclparse
- * Consumes and parses an ACL specification of the form:
- * [group|user] [A-Za-z0-9]*[+-=][rwaR]*
- * from string 's', ignoring any leading white space or white space
- * between the optional id type keyword (group|user) and the actual
- * ACL specification.
+ * Consumes and parses an ACL specification of the form:
+ * [group|user] [A-Za-z0-9]*[+-=][rwaR]*
+ * from string 's', ignoring any leading white space or white space
+ * between the optional id type keyword (group|user) and the actual
+ * ACL specification.
*
- * This routine is called by the parser as well as aclitemin(), hence
- * the added generality.
+ * This routine is called by the parser as well as aclitemin(), hence
+ * the added generality.
*
* RETURNS:
- * the string position in 's' immediately following the ACL
- * specification. Also:
- * - loads the structure pointed to by 'aip' with the appropriate
- * UID/GID, id type identifier and mode type values.
- * - loads 'modechg' with the mode change flag.
+ * the string position in 's' immediately following the ACL
+ * specification. Also:
+ * - loads the structure pointed to by 'aip' with the appropriate
+ * UID/GID, id type identifier and mode type values.
+ * - loads 'modechg' with the mode change flag.
*/
-static char *
-aclparse(char *s, AclItem *aip, unsigned *modechg)
+static char *
+aclparse(char *s, AclItem * aip, unsigned *modechg)
{
- HeapTuple htp;
- char name[NAMEDATALEN];
-
- Assert(s && aip && modechg);
-
- aip->ai_idtype = ACL_IDTYPE_UID;
- s = getid(s, name);
- if (*s != ACL_MODECHG_ADD_CHR &&
- *s != ACL_MODECHG_DEL_CHR &&
- *s != ACL_MODECHG_EQL_CHR)
- { /* we just read a keyword, not a name */
- if (!strcmp(name, ACL_IDTYPE_GID_KEYWORD)) {
- aip->ai_idtype = ACL_IDTYPE_GID;
- } else if (strcmp(name, ACL_IDTYPE_UID_KEYWORD)) {
- elog(WARN, "aclparse: bad keyword, must be [group|user]");
+ HeapTuple htp;
+ char name[NAMEDATALEN];
+
+ Assert(s && aip && modechg);
+
+ aip->ai_idtype = ACL_IDTYPE_UID;
+ s = getid(s, name);
+ if (*s != ACL_MODECHG_ADD_CHR &&
+ *s != ACL_MODECHG_DEL_CHR &&
+ *s != ACL_MODECHG_EQL_CHR)
+ { /* we just read a keyword, not a name */
+ if (!strcmp(name, ACL_IDTYPE_GID_KEYWORD))
+ {
+ aip->ai_idtype = ACL_IDTYPE_GID;
+ }
+ else if (strcmp(name, ACL_IDTYPE_UID_KEYWORD))
+ {
+ elog(WARN, "aclparse: bad keyword, must be [group|user]");
+ }
+ s = getid(s, name); /* move s to the name beyond the keyword */
+ if (name[0] == '\0')
+ elog(WARN, "aclparse: a name must follow the [group|user] keyword");
}
- s = getid(s, name); /* move s to the name beyond the keyword */
if (name[0] == '\0')
- elog(WARN, "aclparse: a name must follow the [group|user] keyword");
- }
- if (name[0] == '\0')
- aip->ai_idtype = ACL_IDTYPE_WORLD;
-
- switch (*s) {
- case ACL_MODECHG_ADD_CHR: *modechg = ACL_MODECHG_ADD; break;
- case ACL_MODECHG_DEL_CHR: *modechg = ACL_MODECHG_DEL; break;
- case ACL_MODECHG_EQL_CHR: *modechg = ACL_MODECHG_EQL; break;
- default: elog(WARN, "aclparse: mode change flag must use \"%s\"",
- ACL_MODECHG_STR);
- }
-
- aip->ai_mode = ACL_NO;
- while (isalpha(*++s)) {
- switch (*s) {
- case ACL_MODE_AP_CHR: aip->ai_mode |= ACL_AP; break;
- case ACL_MODE_RD_CHR: aip->ai_mode |= ACL_RD; break;
- case ACL_MODE_WR_CHR: aip->ai_mode |= ACL_WR; break;
- case ACL_MODE_RU_CHR: aip->ai_mode |= ACL_RU; break;
- default: elog(WARN, "aclparse: mode flags must use \"%s\"",
- ACL_MODE_STR);
+ aip->ai_idtype = ACL_IDTYPE_WORLD;
+
+ switch (*s)
+ {
+ case ACL_MODECHG_ADD_CHR:
+ *modechg = ACL_MODECHG_ADD;
+ break;
+ case ACL_MODECHG_DEL_CHR:
+ *modechg = ACL_MODECHG_DEL;
+ break;
+ case ACL_MODECHG_EQL_CHR:
+ *modechg = ACL_MODECHG_EQL;
+ break;
+ default:
+ elog(WARN, "aclparse: mode change flag must use \"%s\"",
+ ACL_MODECHG_STR);
}
- }
-
- switch (aip->ai_idtype) {
- case ACL_IDTYPE_UID:
- htp = SearchSysCacheTuple(USENAME, PointerGetDatum(name),
- 0,0,0);
- if (!HeapTupleIsValid(htp))
- elog(WARN, "aclparse: non-existent user \"%s\"", name);
- aip->ai_id = ((Form_pg_user) GETSTRUCT(htp))->usesysid;
- break;
- case ACL_IDTYPE_GID:
- aip->ai_id = get_grosysid(name);
- break;
- case ACL_IDTYPE_WORLD:
- aip->ai_id = ACL_ID_WORLD;
- break;
- }
-
+
+ aip->ai_mode = ACL_NO;
+ while (isalpha(*++s))
+ {
+ switch (*s)
+ {
+ case ACL_MODE_AP_CHR:
+ aip->ai_mode |= ACL_AP;
+ break;
+ case ACL_MODE_RD_CHR:
+ aip->ai_mode |= ACL_RD;
+ break;
+ case ACL_MODE_WR_CHR:
+ aip->ai_mode |= ACL_WR;
+ break;
+ case ACL_MODE_RU_CHR:
+ aip->ai_mode |= ACL_RU;
+ break;
+ default:
+ elog(WARN, "aclparse: mode flags must use \"%s\"",
+ ACL_MODE_STR);
+ }
+ }
+
+ switch (aip->ai_idtype)
+ {
+ case ACL_IDTYPE_UID:
+ htp = SearchSysCacheTuple(USENAME, PointerGetDatum(name),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "aclparse: non-existent user \"%s\"", name);
+ aip->ai_id = ((Form_pg_user) GETSTRUCT(htp))->usesysid;
+ break;
+ case ACL_IDTYPE_GID:
+ aip->ai_id = get_grosysid(name);
+ break;
+ case ACL_IDTYPE_WORLD:
+ aip->ai_id = ACL_ID_WORLD;
+ break;
+ }
+
#ifdef ACLDEBUG_TRACE
- elog(DEBUG, "aclparse: correctly read [%x %d %x], modechg=%x",
- aip->ai_idtype, aip->ai_id, aip->ai_mode, *modechg);
+ elog(DEBUG, "aclparse: correctly read [%x %d %x], modechg=%x",
+ aip->ai_idtype, aip->ai_id, aip->ai_mode, *modechg);
#endif
- return(s);
+ return (s);
}
/*
* makeacl
- * Allocates storage for a new Acl with 'n' entries.
+ * Allocates storage for a new Acl with 'n' entries.
*
* RETURNS:
- * the new Acl
+ * the new Acl
*/
-Acl *
+Acl *
makeacl(int n)
{
- Acl *new_acl;
- Size size;
-
- if (n < 0)
- elog(WARN, "makeacl: invalid size: %d\n", n);
- size = ACL_N_SIZE(n);
- if (!(new_acl = (Acl *) palloc(size)))
- elog(WARN, "makeacl: palloc failed on %d\n", size);
- memset((char *) new_acl, 0, size);
- new_acl->size = size;
- new_acl->ndim = 1;
- new_acl->flags = 0;
- ARR_LBOUND(new_acl)[0] = 0;
- ARR_DIMS(new_acl)[0] = n;
- return(new_acl);
+ Acl *new_acl;
+ Size size;
+
+ if (n < 0)
+ elog(WARN, "makeacl: invalid size: %d\n", n);
+ size = ACL_N_SIZE(n);
+ if (!(new_acl = (Acl *) palloc(size)))
+ elog(WARN, "makeacl: palloc failed on %d\n", size);
+ memset((char *) new_acl, 0, size);
+ new_acl->size = size;
+ new_acl->ndim = 1;
+ new_acl->flags = 0;
+ ARR_LBOUND(new_acl)[0] = 0;
+ ARR_DIMS(new_acl)[0] = n;
+ return (new_acl);
}
/*
* aclitemin
- * Allocates storage for, and fills in, a new AclItem given a string
- * 's' that contains an ACL specification. See aclparse for details.
+ * Allocates storage for, and fills in, a new AclItem given a string
+ * 's' that contains an ACL specification. See aclparse for details.
*
* RETURNS:
- * the new AclItem
+ * the new AclItem
*/
-AclItem *
+AclItem *
aclitemin(char *s)
{
- unsigned modechg;
- AclItem *aip;
-
- if (!s)
- elog(WARN, "aclitemin: null string");
-
- aip = (AclItem *) palloc(sizeof(AclItem));
- if (!aip)
- elog(WARN, "aclitemin: palloc failed");
- s = aclparse(s, aip, &modechg);
- if (modechg != ACL_MODECHG_EQL)
- elog(WARN, "aclitemin: cannot accept anything but = ACLs");
- while (isspace(*s))
- ++s;
- if (*s)
- elog(WARN, "aclitemin: extra garbage at end of specification");
- return(aip);
+ unsigned modechg;
+ AclItem *aip;
+
+ if (!s)
+ elog(WARN, "aclitemin: null string");
+
+ aip = (AclItem *) palloc(sizeof(AclItem));
+ if (!aip)
+ elog(WARN, "aclitemin: palloc failed");
+ s = aclparse(s, aip, &modechg);
+ if (modechg != ACL_MODECHG_EQL)
+ elog(WARN, "aclitemin: cannot accept anything but = ACLs");
+ while (isspace(*s))
+ ++s;
+ if (*s)
+ elog(WARN, "aclitemin: extra garbage at end of specification");
+ return (aip);
}
/*
* aclitemout
- * Allocates storage for, and fills in, a new null-delimited string
- * containing a formatted ACL specification. See aclparse for details.
+ * Allocates storage for, and fills in, a new null-delimited string
+ * containing a formatted ACL specification. See aclparse for details.
*
* RETURNS:
- * the new string
+ * the new string
*/
-char *
-aclitemout(AclItem *aip)
+char *
+aclitemout(AclItem * aip)
{
- register char *p;
- char *out;
- HeapTuple htp;
- unsigned i;
- static AclItem default_aclitem = { ACL_ID_WORLD,
- ACL_IDTYPE_WORLD,
- ACL_WORLD_DEFAULT };
- extern char *int2out();
- char *tmpname;
-
- if (!aip)
- aip = &default_aclitem;
-
- p = out = palloc(strlen("group =arwR ") + 1 + NAMEDATALEN);
- if (!out)
- elog(WARN, "aclitemout: palloc failed");
- *p = '\0';
-
- switch (aip->ai_idtype) {
- case ACL_IDTYPE_UID:
- htp = SearchSysCacheTuple(USESYSID, ObjectIdGetDatum(aip->ai_id),
- 0,0,0);
- if (!HeapTupleIsValid(htp)) {
- char *tmp = int2out(aip->ai_id);
-
- elog(NOTICE, "aclitemout: usesysid %d not found",
- aip->ai_id);
- strcat(p, tmp);
- pfree(tmp);
- } else
- strncat(p, (char *) &((Form_pg_user)
- GETSTRUCT(htp))->usename,
- sizeof(NameData));
- break;
- case ACL_IDTYPE_GID:
- strcat(p, "group ");
- tmpname = get_groname(aip->ai_id);
- strncat(p, tmpname, NAMEDATALEN);
- break;
- case ACL_IDTYPE_WORLD:
- break;
- default:
- elog(WARN, "aclitemout: bad ai_idtype: %d", aip->ai_idtype);
- break;
- }
- while (*p)
- ++p;
- *p++ = '=';
- for (i = 0; i < N_ACL_MODES; ++i)
- if ((aip->ai_mode >> i) & 01)
- *p++ = ACL_MODE_STR[i];
- *p = '\0';
-
- return(out);
+ register char *p;
+ char *out;
+ HeapTuple htp;
+ unsigned i;
+ static AclItem default_aclitem = {ACL_ID_WORLD,
+ ACL_IDTYPE_WORLD,
+ ACL_WORLD_DEFAULT};
+ extern char *int2out();
+ char *tmpname;
+
+ if (!aip)
+ aip = &default_aclitem;
+
+ p = out = palloc(strlen("group =arwR ") + 1 + NAMEDATALEN);
+ if (!out)
+ elog(WARN, "aclitemout: palloc failed");
+ *p = '\0';
+
+ switch (aip->ai_idtype)
+ {
+ case ACL_IDTYPE_UID:
+ htp = SearchSysCacheTuple(USESYSID, ObjectIdGetDatum(aip->ai_id),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(htp))
+ {
+ char *tmp = int2out(aip->ai_id);
+
+ elog(NOTICE, "aclitemout: usesysid %d not found",
+ aip->ai_id);
+ strcat(p, tmp);
+ pfree(tmp);
+ }
+ else
+ strncat(p, (char *) &((Form_pg_user)
+ GETSTRUCT(htp))->usename,
+ sizeof(NameData));
+ break;
+ case ACL_IDTYPE_GID:
+ strcat(p, "group ");
+ tmpname = get_groname(aip->ai_id);
+ strncat(p, tmpname, NAMEDATALEN);
+ break;
+ case ACL_IDTYPE_WORLD:
+ break;
+ default:
+ elog(WARN, "aclitemout: bad ai_idtype: %d", aip->ai_idtype);
+ break;
+ }
+ while (*p)
+ ++p;
+ *p++ = '=';
+ for (i = 0; i < N_ACL_MODES; ++i)
+ if ((aip->ai_mode >> i) & 01)
+ *p++ = ACL_MODE_STR[i];
+ *p = '\0';
+
+ return (out);
}
/*
* aclitemeq
* aclitemgt
- * AclItem equality and greater-than comparison routines.
- * Two AclItems are equal iff they are both NULL or they have the
- * same identifier (and identifier type).
+ * AclItem equality and greater-than comparison routines.
+ * Two AclItems are equal iff they are both NULL or they have the
+ * same identifier (and identifier type).
*
* RETURNS:
- * a boolean value indicating = or >
+ * a boolean value indicating = or >
*/
-static int32
-aclitemeq(AclItem *a1, AclItem *a2)
+static int32
+aclitemeq(AclItem * a1, AclItem * a2)
{
- if (!a1 && !a2)
- return(1);
- if (!a1 || !a2)
- return(0);
- return(a1->ai_idtype == a2->ai_idtype && a1->ai_id == a2->ai_id);
+ if (!a1 && !a2)
+ return (1);
+ if (!a1 || !a2)
+ return (0);
+ return (a1->ai_idtype == a2->ai_idtype && a1->ai_id == a2->ai_id);
}
-static int32
-aclitemgt(AclItem *a1, AclItem *a2)
+static int32
+aclitemgt(AclItem * a1, AclItem * a2)
{
- if (a1 && !a2)
- return(1);
- if (!a1 || !a2)
- return(0);
- return((a1->ai_idtype > a2->ai_idtype) ||
- (a1->ai_idtype == a2->ai_idtype && a1->ai_id > a2->ai_id));
+ if (a1 && !a2)
+ return (1);
+ if (!a1 || !a2)
+ return (0);
+ return ((a1->ai_idtype > a2->ai_idtype) ||
+ (a1->ai_idtype == a2->ai_idtype && a1->ai_id > a2->ai_id));
}
-Acl *
+Acl *
aclownerdefault(AclId ownerid)
{
- Acl *acl;
- AclItem *aip;
-
- acl = makeacl(2);
- aip = ACL_DAT(acl);
- aip[0].ai_idtype = ACL_IDTYPE_WORLD;
- aip[0].ai_id = ACL_ID_WORLD;
- aip[0].ai_mode = ACL_WORLD_DEFAULT;
- aip[1].ai_idtype = ACL_IDTYPE_UID;
- aip[1].ai_id = ownerid;
- aip[1].ai_mode = ACL_OWNER_DEFAULT;
- return(acl);
+ Acl *acl;
+ AclItem *aip;
+
+ acl = makeacl(2);
+ aip = ACL_DAT(acl);
+ aip[0].ai_idtype = ACL_IDTYPE_WORLD;
+ aip[0].ai_id = ACL_ID_WORLD;
+ aip[0].ai_mode = ACL_WORLD_DEFAULT;
+ aip[1].ai_idtype = ACL_IDTYPE_UID;
+ aip[1].ai_id = ownerid;
+ aip[1].ai_mode = ACL_OWNER_DEFAULT;
+ return (acl);
}
-Acl *
+Acl *
acldefault(void)
{
- Acl *acl;
- AclItem *aip;
-
- acl = makeacl(1);
- aip = ACL_DAT(acl);
- aip[0].ai_idtype = ACL_IDTYPE_WORLD;
- aip[0].ai_id = ACL_ID_WORLD;
- aip[0].ai_mode = ACL_WORLD_DEFAULT;
- return(acl);
+ Acl *acl;
+ AclItem *aip;
+
+ acl = makeacl(1);
+ aip = ACL_DAT(acl);
+ aip[0].ai_idtype = ACL_IDTYPE_WORLD;
+ aip[0].ai_id = ACL_ID_WORLD;
+ aip[0].ai_mode = ACL_WORLD_DEFAULT;
+ return (acl);
}
-Acl *
-aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
+Acl *
+aclinsert3(Acl * old_acl, AclItem * mod_aip, unsigned modechg)
{
- Acl *new_acl;
- AclItem *old_aip, *new_aip;
- unsigned src, dst, num;
-
- if (!old_acl || ACL_NUM(old_acl) < 1) {
- new_acl = makeacl(0);
- return(new_acl);
- }
- if (!mod_aip) {
- new_acl = makeacl(ACL_NUM(old_acl));
- memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
- return(new_acl);
- }
-
- num = ACL_NUM(old_acl);
- old_aip = ACL_DAT(old_acl);
-
- /*
- * Search the ACL for an existing entry for 'id'. If one exists,
- * just modify the entry in-place (well, in the same position, since
- * we actually return a copy); otherwise, insert the new entry in
- * sort-order.
- */
- /* find the first element not less than the element to be inserted */
- for (dst = 0; dst < num && aclitemgt(mod_aip, old_aip+dst); ++dst)
- ;
- if (dst < num && aclitemeq(mod_aip, old_aip+dst)) {
- /* modify in-place */
- new_acl = makeacl(ACL_NUM(old_acl));
- memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
- new_aip = ACL_DAT(new_acl);
- src = dst;
- } else {
- new_acl = makeacl(num + 1);
- new_aip = ACL_DAT(new_acl);
- if (dst == 0) { /* start */
- elog(WARN, "aclinsert3: insertion before world ACL??");
- } else if (dst >= num) { /* end */
- memmove((char *) new_aip,
- (char *) old_aip,
- num * sizeof(AclItem));
- } else { /* middle */
- memmove((char *) new_aip,
- (char *) old_aip,
- dst * sizeof(AclItem));
- memmove((char *) (new_aip+dst+1),
- (char *) (old_aip+dst),
- (num - dst) * sizeof(AclItem));
+ Acl *new_acl;
+ AclItem *old_aip,
+ *new_aip;
+ unsigned src,
+ dst,
+ num;
+
+ if (!old_acl || ACL_NUM(old_acl) < 1)
+ {
+ new_acl = makeacl(0);
+ return (new_acl);
}
- new_aip[dst].ai_id = mod_aip->ai_id;
- new_aip[dst].ai_idtype = mod_aip->ai_idtype;
- num++; /* set num to the size of new_acl */
- src = 0; /* world entry */
- }
- switch (modechg) {
- case ACL_MODECHG_ADD: new_aip[dst].ai_mode =
- old_aip[src].ai_mode | mod_aip->ai_mode;
- break;
- case ACL_MODECHG_DEL: new_aip[dst].ai_mode =
- old_aip[src].ai_mode & ~mod_aip->ai_mode;
- break;
- case ACL_MODECHG_EQL: new_aip[dst].ai_mode =
- mod_aip->ai_mode;
- break;
- }
- /* if the newly added entry has no permissions, delete it from
- the list. For example, this helps in removing entries for users who
- no longer exists...*/
- for (dst = 1; dst < num; dst++) {
- if (new_aip[dst].ai_mode == 0) {
- int i;
- for (i=dst+1; i<num; i++) {
- new_aip[i-1].ai_id = new_aip[i].ai_id;
- new_aip[i-1].ai_idtype = new_aip[i].ai_idtype;
- new_aip[i-1].ai_mode = new_aip[i].ai_mode;
- }
- ARR_DIMS(new_acl)[0] = num -1 ;
- /* Adjust also the array size because it is used for memmove */
- ARR_SIZE(new_acl) -= sizeof(AclItem);
- break;
+ if (!mod_aip)
+ {
+ new_acl = makeacl(ACL_NUM(old_acl));
+ memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
+ return (new_acl);
}
- }
- return(new_acl);
+ num = ACL_NUM(old_acl);
+ old_aip = ACL_DAT(old_acl);
+
+ /*
+ * Search the ACL for an existing entry for 'id'. If one exists, just
+ * modify the entry in-place (well, in the same position, since we
+ * actually return a copy); otherwise, insert the new entry in
+ * sort-order.
+ */
+ /* find the first element not less than the element to be inserted */
+ for (dst = 0; dst < num && aclitemgt(mod_aip, old_aip + dst); ++dst)
+ ;
+ if (dst < num && aclitemeq(mod_aip, old_aip + dst))
+ {
+ /* modify in-place */
+ new_acl = makeacl(ACL_NUM(old_acl));
+ memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
+ new_aip = ACL_DAT(new_acl);
+ src = dst;
+ }
+ else
+ {
+ new_acl = makeacl(num + 1);
+ new_aip = ACL_DAT(new_acl);
+ if (dst == 0)
+ { /* start */
+ elog(WARN, "aclinsert3: insertion before world ACL??");
+ }
+ else if (dst >= num)
+ { /* end */
+ memmove((char *) new_aip,
+ (char *) old_aip,
+ num * sizeof(AclItem));
+ }
+ else
+ { /* middle */
+ memmove((char *) new_aip,
+ (char *) old_aip,
+ dst * sizeof(AclItem));
+ memmove((char *) (new_aip + dst + 1),
+ (char *) (old_aip + dst),
+ (num - dst) * sizeof(AclItem));
+ }
+ new_aip[dst].ai_id = mod_aip->ai_id;
+ new_aip[dst].ai_idtype = mod_aip->ai_idtype;
+ num++; /* set num to the size of new_acl */
+ src = 0; /* world entry */
+ }
+ switch (modechg)
+ {
+ case ACL_MODECHG_ADD:
+ new_aip[dst].ai_mode =
+ old_aip[src].ai_mode | mod_aip->ai_mode;
+ break;
+ case ACL_MODECHG_DEL:
+ new_aip[dst].ai_mode =
+ old_aip[src].ai_mode & ~mod_aip->ai_mode;
+ break;
+ case ACL_MODECHG_EQL:
+ new_aip[dst].ai_mode =
+ mod_aip->ai_mode;
+ break;
+ }
+
+ /*
+ * if the newly added entry has no permissions, delete it from the
+ * list. For example, this helps in removing entries for users who no
+ * longer exists...
+ */
+ for (dst = 1; dst < num; dst++)
+ {
+ if (new_aip[dst].ai_mode == 0)
+ {
+ int i;
+
+ for (i = dst + 1; i < num; i++)
+ {
+ new_aip[i - 1].ai_id = new_aip[i].ai_id;
+ new_aip[i - 1].ai_idtype = new_aip[i].ai_idtype;
+ new_aip[i - 1].ai_mode = new_aip[i].ai_mode;
+ }
+ ARR_DIMS(new_acl)[0] = num - 1;
+ /* Adjust also the array size because it is used for memmove */
+ ARR_SIZE(new_acl) -= sizeof(AclItem);
+ break;
+ }
+ }
+
+ return (new_acl);
}
/*
* aclinsert
*
*/
-Acl *
-aclinsert(Acl *old_acl, AclItem *mod_aip)
+Acl *
+aclinsert(Acl * old_acl, AclItem * mod_aip)
{
- return(aclinsert3(old_acl, mod_aip, ACL_MODECHG_EQL));
+ return (aclinsert3(old_acl, mod_aip, ACL_MODECHG_EQL));
}
-Acl *
-aclremove(Acl *old_acl, AclItem *mod_aip)
+Acl *
+aclremove(Acl * old_acl, AclItem * mod_aip)
{
- Acl *new_acl;
- AclItem *old_aip, *new_aip;
- unsigned dst, old_num, new_num;
-
- if (!old_acl || ACL_NUM(old_acl) < 1) {
- new_acl = makeacl(0);
- return(new_acl);
- }
- if (!mod_aip) {
- new_acl = makeacl(ACL_NUM(old_acl));
- memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
- return(new_acl);
- }
-
- old_num = ACL_NUM(old_acl);
- old_aip = ACL_DAT(old_acl);
-
- for (dst = 0; dst < old_num && !aclitemeq(mod_aip, old_aip+dst); ++dst)
- ;
- if (dst >= old_num) { /* not found or empty */
- new_acl = makeacl(ACL_NUM(old_acl));
- memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
- } else {
- new_num = old_num - 1;
- new_acl = makeacl(ACL_NUM(old_acl) - 1);
- new_aip = ACL_DAT(new_acl);
- if (dst == 0) { /* start */
- elog(WARN, "aclremove: removal of the world ACL??");
- } else if (dst == old_num - 1) {/* end */
- memmove((char *) new_aip,
- (char *) old_aip,
- new_num * sizeof(AclItem));
- } else { /* middle */
- memmove((char *) new_aip,
- (char *) old_aip,
- dst * sizeof(AclItem));
- memmove((char *) (new_aip+dst),
- (char *) (old_aip+dst+1),
- (new_num - dst) * sizeof(AclItem));
+ Acl *new_acl;
+ AclItem *old_aip,
+ *new_aip;
+ unsigned dst,
+ old_num,
+ new_num;
+
+ if (!old_acl || ACL_NUM(old_acl) < 1)
+ {
+ new_acl = makeacl(0);
+ return (new_acl);
}
- }
- return(new_acl);
+ if (!mod_aip)
+ {
+ new_acl = makeacl(ACL_NUM(old_acl));
+ memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
+ return (new_acl);
+ }
+
+ old_num = ACL_NUM(old_acl);
+ old_aip = ACL_DAT(old_acl);
+
+ for (dst = 0; dst < old_num && !aclitemeq(mod_aip, old_aip + dst); ++dst)
+ ;
+ if (dst >= old_num)
+ { /* not found or empty */
+ new_acl = makeacl(ACL_NUM(old_acl));
+ memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
+ }
+ else
+ {
+ new_num = old_num - 1;
+ new_acl = makeacl(ACL_NUM(old_acl) - 1);
+ new_aip = ACL_DAT(new_acl);
+ if (dst == 0)
+ { /* start */
+ elog(WARN, "aclremove: removal of the world ACL??");
+ }
+ else if (dst == old_num - 1)
+ { /* end */
+ memmove((char *) new_aip,
+ (char *) old_aip,
+ new_num * sizeof(AclItem));
+ }
+ else
+ { /* middle */
+ memmove((char *) new_aip,
+ (char *) old_aip,
+ dst * sizeof(AclItem));
+ memmove((char *) (new_aip + dst),
+ (char *) (old_aip + dst + 1),
+ (new_num - dst) * sizeof(AclItem));
+ }
+ }
+ return (new_acl);
}
int32
-aclcontains(Acl *acl, AclItem *aip)
+aclcontains(Acl * acl, AclItem * aip)
{
- unsigned i, num;
- AclItem *aidat;
-
- if (!acl || !aip || ((num = ACL_NUM(acl)) < 1))
- return(0);
- aidat = ACL_DAT(acl);
- for (i = 0; i < num; ++i)
- if (aclitemeq(aip, aidat+i))
- return(1);
- return(0);
+ unsigned i,
+ num;
+ AclItem *aidat;
+
+ if (!acl || !aip || ((num = ACL_NUM(acl)) < 1))
+ return (0);
+ aidat = ACL_DAT(acl);
+ for (i = 0; i < num; ++i)
+ if (aclitemeq(aip, aidat + i))
+ return (1);
+ return (0);
}
/* parser support routines */
/*
* aclmakepriv
- * make a acl privilege string out of an existing privilege string
+ * make a acl privilege string out of an existing privilege string
* and a new privilege
*
* does not add duplicate privileges
- *
+ *
* the CALLER is reponsible for free'ing the string returned
*/
-char*
-aclmakepriv(char* old_privlist, char new_priv)
+char *
+aclmakepriv(char *old_privlist, char new_priv)
{
- char* priv;
- int i;
- int l;
+ char *priv;
+ int i;
+ int l;
- Assert(strlen(old_privlist)<5);
- priv = malloc(5); /* at most "rwaR" */;
+ Assert(strlen(old_privlist) < 5);
+ priv = malloc(5); /* at most "rwaR" */ ;
- if (old_privlist == NULL || old_privlist[0] == '\0') {
- priv[0] = new_priv;
- priv[1] = '\0';
- return priv;
- }
+ if (old_privlist == NULL || old_privlist[0] == '\0')
+ {
+ priv[0] = new_priv;
+ priv[1] = '\0';
+ return priv;
+ }
+
+ strcpy(priv, old_privlist);
+
+ l = strlen(old_privlist);
- strcpy(priv,old_privlist);
-
- l = strlen(old_privlist);
+ if (l == 4)
+ { /* can't add any more privileges */
+ return priv;
+ }
+
+ /* check to see if the new privilege is already in the old string */
+ for (i = 0; i < l; i++)
+ {
+ if (priv[i] == new_priv)
+ break;
+ }
+ if (i == l)
+ { /* we really have a new privilege */
+ priv[l] = new_priv;
+ priv[l + 1] = '\0';
+ }
- if (l == 4) { /* can't add any more privileges */
return priv;
- }
-
- /* check to see if the new privilege is already in the old string */
- for (i=0;i<l;i++) {
- if (priv[i] == new_priv)
- break;
- }
- if (i == l) { /* we really have a new privilege*/
- priv[l] = new_priv;
- priv[l+1] = '\0';
- }
-
- return priv;
}
/*
* aclmakeuser
- * user_type must be "A" - all users
- * "G" - group
- * "U" - user
+ * user_type must be "A" - all users
+ * "G" - group
+ * "U" - user
*
* concatentates the two strings together with a space in between
- *
+ *
* this routine is used in the parser
- *
+ *
* the CALLER is responsible for freeing the memory allocated
*/
-char*
-aclmakeuser(char* user_type, char* user)
+char *
+aclmakeuser(char *user_type, char *user)
{
- char* user_list;
-
- user_list = malloc(strlen(user) + 3);
- sprintf(user_list, "%s %s", user_type, user);
- return user_list;
+ char *user_list;
+
+ user_list = malloc(strlen(user) + 3);
+ sprintf(user_list, "%s %s", user_type, user);
+ return user_list;
}
/*
* makeAclStmt:
- * this is a helper routine called by the parser
+ * this is a helper routine called by the parser
* create a ChangeAclStmt
- * we take in the privilegs, relation_name_list, and grantee
+ * we take in the privilegs, relation_name_list, and grantee
* as well as a single character '+' or '-' to indicate grant or revoke
*
* returns a new ChangeACLStmt*
@@ -584,35 +652,34 @@ aclmakeuser(char* user_type, char* user)
* then calling aclparse;
*/
-ChangeACLStmt*
-makeAclStmt(char* privileges, List* rel_list, char* grantee,
- char grant_or_revoke)
+ChangeACLStmt *
+makeAclStmt(char *privileges, List * rel_list, char *grantee,
+ char grant_or_revoke)
{
- ChangeACLStmt *n = makeNode(ChangeACLStmt);
- char str[MAX_PARSE_BUFFER];
-
- n->aclitem = (AclItem*)palloc(sizeof(AclItem));
- /* the grantee string is "G <group_name>", "U <user_name>", or "ALL" */
- if (grantee[0] == 'G') /* group permissions */
+ ChangeACLStmt *n = makeNode(ChangeACLStmt);
+ char str[MAX_PARSE_BUFFER];
+
+ n->aclitem = (AclItem *) palloc(sizeof(AclItem));
+ /* the grantee string is "G <group_name>", "U <user_name>", or "ALL" */
+ if (grantee[0] == 'G') /* group permissions */
{
- sprintf(str,"%s %s%c%s",
- ACL_IDTYPE_GID_KEYWORD,
- grantee+2, grant_or_revoke,privileges);
- }
- else if (grantee[0] == 'U') /* user permission */
+ sprintf(str, "%s %s%c%s",
+ ACL_IDTYPE_GID_KEYWORD,
+ grantee + 2, grant_or_revoke, privileges);
+ }
+ else if (grantee[0] == 'U') /* user permission */
{
- sprintf(str,"%s %s%c%s",
- ACL_IDTYPE_UID_KEYWORD,
- grantee+2, grant_or_revoke,privileges);
+ sprintf(str, "%s %s%c%s",
+ ACL_IDTYPE_UID_KEYWORD,
+ grantee + 2, grant_or_revoke, privileges);
}
- else /* all permission */
+ else
+/* all permission */
{
- sprintf(str,"%c%s",
- grant_or_revoke,privileges);
+ sprintf(str, "%c%s",
+ grant_or_revoke, privileges);
}
- n->relNames = rel_list;
- aclparse(str, n->aclitem, (unsigned*)&n->modechg);
- return n;
+ n->relNames = rel_list;
+ aclparse(str, n->aclitem, (unsigned *) &n->modechg);
+ return n;
}
-
-
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 48a78366b01..073b0a1fd01 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* arrayfuncs.c--
- * Special functions for arrays.
+ * Special functions for arrays.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.15 1997/08/19 21:34:18 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.16 1997/09/07 04:49:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,1411 +30,1707 @@
#include "libpq/libpq-fs.h"
#include "libpq/be-fsstubs.h"
-#define ASSGN "="
+#define ASSGN "="
/* An array has the following internal structure:
- * <nbytes> - total number of bytes
- * <ndim> - number of dimensions of the array
- * <flags> - bit mask of flags
- * <dim> - size of each array axis
- * <dim_lower> - lower boundary of each dimension
- * <actual data> - whatever is the stored data
+ * <nbytes> - total number of bytes
+ * <ndim> - number of dimensions of the array
+ * <flags> - bit mask of flags
+ * <dim> - size of each array axis
+ * <dim_lower> - lower boundary of each dimension
+ * <actual data> - whatever is the stored data
*/
/*-=-=--=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-*/
-static int _ArrayCount(char *str, int dim[], int typdelim);
-static char *_ReadArrayStr(char *arrayStr, int nitems, int ndim, int dim[],
- func_ptr inputproc, Oid typelem, char typdelim,
- int typlen, bool typbyval, char typalign,
- int *nbytes);
+static int _ArrayCount(char *str, int dim[], int typdelim);
+static char *
+_ReadArrayStr(char *arrayStr, int nitems, int ndim, int dim[],
+ func_ptr inputproc, Oid typelem, char typdelim,
+ int typlen, bool typbyval, char typalign,
+ int *nbytes);
+
#ifdef LOARRAY
-static char *_ReadLOArray(char *str, int *nbytes, int *fd, bool *chunkFlag,
- int ndim, int dim[], int baseSize);
+static char *
+_ReadLOArray(char *str, int *nbytes, int *fd, bool * chunkFlag,
+ int ndim, int dim[], int baseSize);
+
#endif
-static void _CopyArrayEls(char **values, char *p, int nitems, int typlen,
+static void
+_CopyArrayEls(char **values, char *p, int nitems, int typlen,
char typalign, bool typbyval);
-static void system_cache_lookup(Oid element_type, bool input, int *typlen,
- bool *typbyval, char *typdelim, Oid *typelem, Oid *proc,
- char *typalign);
-static Datum _ArrayCast(char *value, bool byval, int len);
+static void
+system_cache_lookup(Oid element_type, bool input, int *typlen,
+ bool * typbyval, char *typdelim, Oid * typelem, Oid * proc,
+ char *typalign);
+static Datum _ArrayCast(char *value, bool byval, int len);
+
#ifdef LOARRAY
-static char *_AdvanceBy1word(char *str, char **word);
+static char *_AdvanceBy1word(char *str, char **word);
+
#endif
-static void _ArrayRange(int st[], int endp[], int bsize, char *destPtr,
- ArrayType *array, int from);
-static int _ArrayClipCount(int stI[], int endpI[], ArrayType *array);
-static void _LOArrayRange(int st[], int endp[], int bsize, int srcfd,
- int destfd, ArrayType *array, int isSrcLO, bool *isNull);
-static void _ReadArray (int st[], int endp[], int bsize, int srcfd, int destfd,
- ArrayType *array, int isDestLO, bool *isNull);
-static ArrayCastAndSet(char *src, bool typbyval, int typlen, char *dest);
-static SanityCheckInput(int ndim, int n, int dim[], int lb[], int indx[]);
-static int array_read(char *destptr, int eltsize, int nitems, char *srcptr);
-static char *array_seek(char *ptr, int eltsize, int nitems);
+static void
+_ArrayRange(int st[], int endp[], int bsize, char *destPtr,
+ ArrayType * array, int from);
+static int _ArrayClipCount(int stI[], int endpI[], ArrayType * array);
+static void
+_LOArrayRange(int st[], int endp[], int bsize, int srcfd,
+ int destfd, ArrayType * array, int isSrcLO, bool * isNull);
+static void
+_ReadArray(int st[], int endp[], int bsize, int srcfd, int destfd,
+ ArrayType * array, int isDestLO, bool * isNull);
+static ArrayCastAndSet(char *src, bool typbyval, int typlen, char *dest);
+static SanityCheckInput(int ndim, int n, int dim[], int lb[], int indx[]);
+static int array_read(char *destptr, int eltsize, int nitems, char *srcptr);
+static char *array_seek(char *ptr, int eltsize, int nitems);
/*---------------------------------------------------------------------
- * array_in :
- * converts an array from the external format in "string" to
- * it internal format.
+ * array_in :
+ * converts an array from the external format in "string" to
+ * it internal format.
* return value :
- * the internal representation of the input array
+ * the internal representation of the input array
*--------------------------------------------------------------------
*/
-char *
-array_in(char *string, /* input array in external form */
- Oid element_type) /* type OID of an array element */
+char *
+array_in(char *string, /* input array in external form */
+ Oid element_type) /* type OID of an array element */
{
- int typlen;
- bool typbyval, done;
- char typdelim;
- Oid typinput;
- Oid typelem;
- char *string_save, *p, *q, *r;
- func_ptr inputproc;
- int i, nitems, dummy;
- int32 nbytes;
- char *dataPtr;
- ArrayType *retval = NULL;
- int ndim, dim[MAXDIM], lBound[MAXDIM];
- char typalign;
-
- system_cache_lookup(element_type, true, &typlen, &typbyval, &typdelim,
- &typelem, &typinput, &typalign);
-
- fmgr_info(typinput, &inputproc, &dummy);
-
- string_save = (char *) palloc(strlen(string) + 3);
- strcpy(string_save, string);
-
- /* --- read array dimensions ---------- */
- p = q = string_save; done = false;
- for ( ndim = 0; !done; ) {
- while (isspace(*p)) p++;
- if (*p == '[' ) {
- p++;
- if ((r = (char *)strchr(p, ':')) == (char *)NULL)
- lBound[ndim] = 1;
- else {
- *r = '\0';
- lBound[ndim] = atoi(p);
- p = r + 1;
- }
- for (q = p; isdigit(*q); q++);
- if (*q != ']')
- elog(WARN, "array_in: missing ']' in array declaration");
- *q = '\0';
- dim[ndim] = atoi(p);
- if ((dim[ndim] < 0) || (lBound[ndim] < 0))
- elog(WARN,"array_in: array dimensions need to be positive");
- dim[ndim] = dim[ndim] - lBound[ndim] + 1;
- if (dim[ndim] < 0)
- elog(WARN, "array_in: upper_bound cannot be < lower_bound");
- p = q + 1; ndim++;
- } else {
- done = true;
- }
- }
-
- if (ndim == 0) {
- if (*p == '{') {
- ndim = _ArrayCount(p, dim, typdelim);
- for (i = 0; i < ndim; lBound[i++] = 1);
- } else {
- elog(WARN,"array_in: Need to specify dimension");
- }
- } else {
- while (isspace(*p)) p++;
- if (strncmp(p, ASSGN, strlen(ASSGN)))
- elog(WARN, "array_in: missing assignment operator");
- p+= strlen(ASSGN);
- while (isspace(*p)) p++;
- }
-
+ int typlen;
+ bool typbyval,
+ done;
+ char typdelim;
+ Oid typinput;
+ Oid typelem;
+ char *string_save,
+ *p,
+ *q,
+ *r;
+ func_ptr inputproc;
+ int i,
+ nitems,
+ dummy;
+ int32 nbytes;
+ char *dataPtr;
+ ArrayType *retval = NULL;
+ int ndim,
+ dim[MAXDIM],
+ lBound[MAXDIM];
+ char typalign;
+
+ system_cache_lookup(element_type, true, &typlen, &typbyval, &typdelim,
+ &typelem, &typinput, &typalign);
+
+ fmgr_info(typinput, &inputproc, &dummy);
+
+ string_save = (char *) palloc(strlen(string) + 3);
+ strcpy(string_save, string);
+
+ /* --- read array dimensions ---------- */
+ p = q = string_save;
+ done = false;
+ for (ndim = 0; !done;)
+ {
+ while (isspace(*p))
+ p++;
+ if (*p == '[')
+ {
+ p++;
+ if ((r = (char *) strchr(p, ':')) == (char *) NULL)
+ lBound[ndim] = 1;
+ else
+ {
+ *r = '\0';
+ lBound[ndim] = atoi(p);
+ p = r + 1;
+ }
+ for (q = p; isdigit(*q); q++);
+ if (*q != ']')
+ elog(WARN, "array_in: missing ']' in array declaration");
+ *q = '\0';
+ dim[ndim] = atoi(p);
+ if ((dim[ndim] < 0) || (lBound[ndim] < 0))
+ elog(WARN, "array_in: array dimensions need to be positive");
+ dim[ndim] = dim[ndim] - lBound[ndim] + 1;
+ if (dim[ndim] < 0)
+ elog(WARN, "array_in: upper_bound cannot be < lower_bound");
+ p = q + 1;
+ ndim++;
+ }
+ else
+ {
+ done = true;
+ }
+ }
+
+ if (ndim == 0)
+ {
+ if (*p == '{')
+ {
+ ndim = _ArrayCount(p, dim, typdelim);
+ for (i = 0; i < ndim; lBound[i++] = 1);
+ }
+ else
+ {
+ elog(WARN, "array_in: Need to specify dimension");
+ }
+ }
+ else
+ {
+ while (isspace(*p))
+ p++;
+ if (strncmp(p, ASSGN, strlen(ASSGN)))
+ elog(WARN, "array_in: missing assignment operator");
+ p += strlen(ASSGN);
+ while (isspace(*p))
+ p++;
+ }
+
#ifdef ARRAYDEBUG
-printf( "array_in- ndim %d (", ndim);
-for (i = 0; i < ndim; i++) {
- printf(" %d", dim[i]);
-};
-printf( ") for %s\n", string);
+ printf("array_in- ndim %d (", ndim);
+ for (i = 0; i < ndim; i++)
+ {
+ printf(" %d", dim[i]);
+ };
+ printf(") for %s\n", string);
#endif
- nitems = getNitems( ndim, dim);
- if (nitems == 0) {
- char *emptyArray = palloc(sizeof(ArrayType));
- memset(emptyArray, 0, sizeof(ArrayType));
- * (int32 *) emptyArray = sizeof(ArrayType);
- return emptyArray;
- }
-
- if (*p == '{') {
- /* array not a large object */
- dataPtr =
- (char *) _ReadArrayStr(p, nitems, ndim, dim, inputproc, typelem,
- typdelim, typlen, typbyval, typalign,
- &nbytes );
- nbytes += ARR_OVERHEAD(ndim);
- retval = (ArrayType *) palloc(nbytes);
- memset(retval,0, nbytes);
- memmove(retval, (char *)&nbytes, sizeof(int));
- memmove((char*)ARR_NDIM_PTR(retval), (char *)&ndim, sizeof(int));
- SET_LO_FLAG (false, retval);
- memmove((char *)ARR_DIMS(retval), (char *)dim, ndim*sizeof(int));
- memmove((char *)ARR_LBOUND(retval), (char *)lBound,
- ndim*sizeof(int));
- /* dataPtr is an array of arbitraystuff even though its type is char*
- cast to char** to pass to _CopyArrayEls for now - jolly */
- _CopyArrayEls((char**)dataPtr,
- ARR_DATA_PTR(retval), nitems,
- typlen, typalign, typbyval);
- } else {
+ nitems = getNitems(ndim, dim);
+ if (nitems == 0)
+ {
+ char *emptyArray = palloc(sizeof(ArrayType));
+
+ memset(emptyArray, 0, sizeof(ArrayType));
+ *(int32 *) emptyArray = sizeof(ArrayType);
+ return emptyArray;
+ }
+
+ if (*p == '{')
+ {
+ /* array not a large object */
+ dataPtr =
+ (char *) _ReadArrayStr(p, nitems, ndim, dim, inputproc, typelem,
+ typdelim, typlen, typbyval, typalign,
+ &nbytes);
+ nbytes += ARR_OVERHEAD(ndim);
+ retval = (ArrayType *) palloc(nbytes);
+ memset(retval, 0, nbytes);
+ memmove(retval, (char *) &nbytes, sizeof(int));
+ memmove((char *) ARR_NDIM_PTR(retval), (char *) &ndim, sizeof(int));
+ SET_LO_FLAG(false, retval);
+ memmove((char *) ARR_DIMS(retval), (char *) dim, ndim * sizeof(int));
+ memmove((char *) ARR_LBOUND(retval), (char *) lBound,
+ ndim * sizeof(int));
+
+ /*
+ * dataPtr is an array of arbitraystuff even though its type is
+ * char* cast to char** to pass to _CopyArrayEls for now - jolly
+ */
+ _CopyArrayEls((char **) dataPtr,
+ ARR_DATA_PTR(retval), nitems,
+ typlen, typalign, typbyval);
+ }
+ else
+ {
#ifdef LOARRAY
- int dummy, bytes;
- bool chunked = false;
-
- dataPtr = _ReadLOArray(p, &bytes, &dummy, &chunked, ndim,
- dim, typlen );
- nbytes = bytes + ARR_OVERHEAD(ndim);
- retval = (ArrayType *) palloc(nbytes);
- memset(retval, 0,nbytes);
- memmove(retval, (char *)&nbytes, sizeof(int));
- memmove((char *)ARR_NDIM_PTR(retval), (char *)&ndim, sizeof(int));
- SET_LO_FLAG (true, retval);
- SET_CHUNK_FLAG (chunked, retval);
- memmove((char *)ARR_DIMS(retval), (char *)dim, ndim*sizeof(int));
- memmove((char *)ARR_LBOUND(retval),(char *)lBound, ndim*sizeof(int));
- memmove(ARR_DATA_PTR(retval), dataPtr, bytes);
+ int dummy,
+ bytes;
+ bool chunked = false;
+
+ dataPtr = _ReadLOArray(p, &bytes, &dummy, &chunked, ndim,
+ dim, typlen);
+ nbytes = bytes + ARR_OVERHEAD(ndim);
+ retval = (ArrayType *) palloc(nbytes);
+ memset(retval, 0, nbytes);
+ memmove(retval, (char *) &nbytes, sizeof(int));
+ memmove((char *) ARR_NDIM_PTR(retval), (char *) &ndim, sizeof(int));
+ SET_LO_FLAG(true, retval);
+ SET_CHUNK_FLAG(chunked, retval);
+ memmove((char *) ARR_DIMS(retval), (char *) dim, ndim * sizeof(int));
+ memmove((char *) ARR_LBOUND(retval), (char *) lBound, ndim * sizeof(int));
+ memmove(ARR_DATA_PTR(retval), dataPtr, bytes);
#endif
- elog(WARN, "large object arrays not supported");
- }
- pfree(string_save);
- return((char *)retval);
+ elog(WARN, "large object arrays not supported");
+ }
+ pfree(string_save);
+ return ((char *) retval);
}
/*-----------------------------------------------------------------------------
* _ArrayCount --
- * Counts the number of dimensions and the dim[] array for an array string.
- * The syntax for array input is C-like nested curly braces
+ * Counts the number of dimensions and the dim[] array for an array string.
+ * The syntax for array input is C-like nested curly braces
*-----------------------------------------------------------------------------
*/
static int
_ArrayCount(char *str, int dim[], int typdelim)
{
- int nest_level = 0, i;
- int ndim = 0, temp[MAXDIM];
- bool scanning_string = false;
- bool eoArray = false;
- char *q;
-
- for (i = 0; i < MAXDIM; ++i) {
- temp[i] = dim[i] = 0;
- }
-
- if (strncmp (str, "{}", 2) == 0) return(0);
-
- q = str;
- while (eoArray != true) {
- bool done = false;
- while (!done) {
- switch (*q) {
- case '\\':
- /* skip escaped characters (\ and ") inside strings */
- if (scanning_string && *(q+1)) {
- q++;
- }
- break;
- case '\0':
- /* Signal a premature end of the string. DZ - 2-9-1996 */
- elog(WARN, "malformed array constant: %s", str);
- break;
- case '\"':
- scanning_string = ! scanning_string;
- break;
- case '{':
- if (!scanning_string) {
- temp[nest_level] = 0;
- nest_level++;
- }
- break;
- case '}':
- if (!scanning_string) {
- if (!ndim) ndim = nest_level;
- nest_level--;
- if (nest_level) temp[nest_level-1]++;
- if (nest_level == 0) eoArray = done = true;
+ int nest_level = 0,
+ i;
+ int ndim = 0,
+ temp[MAXDIM];
+ bool scanning_string = false;
+ bool eoArray = false;
+ char *q;
+
+ for (i = 0; i < MAXDIM; ++i)
+ {
+ temp[i] = dim[i] = 0;
+ }
+
+ if (strncmp(str, "{}", 2) == 0)
+ return (0);
+
+ q = str;
+ while (eoArray != true)
+ {
+ bool done = false;
+
+ while (!done)
+ {
+ switch (*q)
+ {
+ case '\\':
+ /* skip escaped characters (\ and ") inside strings */
+ if (scanning_string && *(q + 1))
+ {
+ q++;
+ }
+ break;
+ case '\0':
+ /* Signal a premature end of the string. DZ - 2-9-1996 */
+ elog(WARN, "malformed array constant: %s", str);
+ break;
+ case '\"':
+ scanning_string = !scanning_string;
+ break;
+ case '{':
+ if (!scanning_string)
+ {
+ temp[nest_level] = 0;
+ nest_level++;
+ }
+ break;
+ case '}':
+ if (!scanning_string)
+ {
+ if (!ndim)
+ ndim = nest_level;
+ nest_level--;
+ if (nest_level)
+ temp[nest_level - 1]++;
+ if (nest_level == 0)
+ eoArray = done = true;
+ }
+ break;
+ default:
+ if (!ndim)
+ ndim = nest_level;
+ if (*q == typdelim && !scanning_string)
+ done = true;
+ break;
+ }
+ if (!done)
+ q++;
}
- break;
- default:
- if (!ndim) ndim = nest_level;
- if (*q == typdelim && !scanning_string )
- done = true;
- break;
- }
- if (!done) q++;
- }
- temp[ndim-1]++;
- q++;
- if (!eoArray)
- while (isspace(*q)) q++;
- }
- for (i = 0; i < ndim; ++i) {
- dim[i] = temp[i];
- }
-
- return(ndim);
+ temp[ndim - 1]++;
+ q++;
+ if (!eoArray)
+ while (isspace(*q))
+ q++;
+ }
+ for (i = 0; i < ndim; ++i)
+ {
+ dim[i] = temp[i];
+ }
+
+ return (ndim);
}
/*---------------------------------------------------------------------------
* _ReadArrayStr :
- * parses the array string pointed by "arrayStr" and converts it in the
- * internal format. The external format expected is like C array
- * declaration. Unspecified elements are initialized to zero for fixed length
- * base types and to empty varlena structures for variable length base
- * types.
+ * parses the array string pointed by "arrayStr" and converts it in the
+ * internal format. The external format expected is like C array
+ * declaration. Unspecified elements are initialized to zero for fixed length
+ * base types and to empty varlena structures for variable length base
+ * types.
* result :
- * returns the internal representation of the array elements
- * nbytes is set to the size of the array in its internal representation.
+ * returns the internal representation of the array elements
+ * nbytes is set to the size of the array in its internal representation.
*---------------------------------------------------------------------------
*/
-static char *
+static char *
_ReadArrayStr(char *arrayStr,
- int nitems,
- int ndim,
- int dim[],
- func_ptr inputproc, /* function used for the conversion */
- Oid typelem,
- char typdelim,
- int typlen,
- bool typbyval,
- char typalign,
- int *nbytes)
+ int nitems,
+ int ndim,
+ int dim[],
+ func_ptr inputproc, /* function used for the
+ * conversion */
+ Oid typelem,
+ char typdelim,
+ int typlen,
+ bool typbyval,
+ char typalign,
+ int *nbytes)
{
- int i, nest_level = 0;
- char *p, *q, *r, **values;
- bool scanning_string = false;
- int indx[MAXDIM], prod[MAXDIM];
- bool eoArray = false;
-
- mda_get_prod(ndim, dim, prod);
- for (i = 0; i < ndim; indx[i++] = 0);
- /* read array enclosed within {} */
- values = (char **) palloc(nitems * sizeof(char *));
- memset(values, 0, nitems * sizeof(char *));
- q = p = arrayStr;
-
- while ( ! eoArray ) {
- bool done = false;
- int i = -1;
-
- while (!done) {
- switch (*q) {
- case '\\':
- /* Crunch the string on top of the backslash. */
- for (r = q; *r != '\0'; r++) *r = *(r+1);
- break;
- case '\"':
- if (!scanning_string ) {
- while (p != q) p++;
- p++; /* get p past first doublequote */
- } else
- *q = '\0';
- scanning_string = ! scanning_string;
- break;
- case '{':
- if (!scanning_string) {
- p++;
- nest_level++;
- if (nest_level > ndim)
- elog(WARN, "array_in: illformed array constant");
- indx[nest_level - 1] = 0;
- indx[ndim - 1] = 0;
- }
- break;
- case '}':
- if (!scanning_string) {
- if (i == -1)
- i = tuple2linear(ndim, indx, prod);
- nest_level--;
- if (nest_level == 0)
- eoArray = done = true;
- else {
- *q = '\0';
- indx[nest_level - 1]++;
- }
- }
- break;
- default:
- if (*q == typdelim && !scanning_string ) {
- if (i == -1)
- i = tuple2linear(ndim, indx, prod);
- done = true;
- indx[ndim - 1]++;
+ int i,
+ nest_level = 0;
+ char *p,
+ *q,
+ *r,
+ **values;
+ bool scanning_string = false;
+ int indx[MAXDIM],
+ prod[MAXDIM];
+ bool eoArray = false;
+
+ mda_get_prod(ndim, dim, prod);
+ for (i = 0; i < ndim; indx[i++] = 0);
+ /* read array enclosed within {} */
+ values = (char **) palloc(nitems * sizeof(char *));
+ memset(values, 0, nitems * sizeof(char *));
+ q = p = arrayStr;
+
+ while (!eoArray)
+ {
+ bool done = false;
+ int i = -1;
+
+ while (!done)
+ {
+ switch (*q)
+ {
+ case '\\':
+ /* Crunch the string on top of the backslash. */
+ for (r = q; *r != '\0'; r++)
+ *r = *(r + 1);
+ break;
+ case '\"':
+ if (!scanning_string)
+ {
+ while (p != q)
+ p++;
+ p++; /* get p past first doublequote */
+ }
+ else
+ *q = '\0';
+ scanning_string = !scanning_string;
+ break;
+ case '{':
+ if (!scanning_string)
+ {
+ p++;
+ nest_level++;
+ if (nest_level > ndim)
+ elog(WARN, "array_in: illformed array constant");
+ indx[nest_level - 1] = 0;
+ indx[ndim - 1] = 0;
+ }
+ break;
+ case '}':
+ if (!scanning_string)
+ {
+ if (i == -1)
+ i = tuple2linear(ndim, indx, prod);
+ nest_level--;
+ if (nest_level == 0)
+ eoArray = done = true;
+ else
+ {
+ *q = '\0';
+ indx[nest_level - 1]++;
+ }
+ }
+ break;
+ default:
+ if (*q == typdelim && !scanning_string)
+ {
+ if (i == -1)
+ i = tuple2linear(ndim, indx, prod);
+ done = true;
+ indx[ndim - 1]++;
+ }
+ break;
+ }
+ if (!done)
+ q++;
}
- break;
- }
- if (!done)
- q++;
- }
- *q = '\0';
- if (i >= nitems)
- elog(WARN, "array_in: illformed array constant");
- values[i] = (*inputproc) (p, typelem);
- p = ++q;
- if (!eoArray)
- /*
- * if not at the end of the array skip white space
- */
- while (isspace(*q)) {
- p++;
- q++;
- }
- }
- if (typlen > 0) {
- *nbytes = nitems * typlen;
- if (!typbyval)
- for (i = 0; i < nitems; i++)
- if (!values[i]) {
- values[i] = palloc(typlen);
- memset(values[i], 0, typlen);
- }
- } else {
- for (i = 0, *nbytes = 0; i < nitems; i++) {
- if (values[i]) {
- if (typalign=='d') {
- *nbytes += DOUBLEALIGN(* (int32 *) values[i]);
- } else {
- *nbytes += INTALIGN(* (int32 *) values[i]);
+ *q = '\0';
+ if (i >= nitems)
+ elog(WARN, "array_in: illformed array constant");
+ values[i] = (*inputproc) (p, typelem);
+ p = ++q;
+ if (!eoArray)
+
+ /*
+ * if not at the end of the array skip white space
+ */
+ while (isspace(*q))
+ {
+ p++;
+ q++;
+ }
+ }
+ if (typlen > 0)
+ {
+ *nbytes = nitems * typlen;
+ if (!typbyval)
+ for (i = 0; i < nitems; i++)
+ if (!values[i])
+ {
+ values[i] = palloc(typlen);
+ memset(values[i], 0, typlen);
+ }
+ }
+ else
+ {
+ for (i = 0, *nbytes = 0; i < nitems; i++)
+ {
+ if (values[i])
+ {
+ if (typalign == 'd')
+ {
+ *nbytes += DOUBLEALIGN(*(int32 *) values[i]);
+ }
+ else
+ {
+ *nbytes += INTALIGN(*(int32 *) values[i]);
+ }
+ }
+ else
+ {
+ *nbytes += sizeof(int32);
+ values[i] = palloc(sizeof(int32));
+ *(int32 *) values[i] = sizeof(int32);
+ }
}
- } else {
- *nbytes += sizeof(int32);
- values[i] = palloc(sizeof(int32));
- *(int32 *)values[i] = sizeof(int32);
- }
- }
- }
- return((char *)values);
+ }
+ return ((char *) values);
}
/*----------------------------------------------------------------------------
- * Read data about an array to be stored as a large object
+ * Read data about an array to be stored as a large object
*----------------------------------------------------------------------------
*/
#ifdef LOARRAY
-static char *
+static char *
_ReadLOArray(char *str,
- int *nbytes,
- int *fd,
- bool *chunkFlag,
- int ndim,
- int dim[],
- int baseSize)
+ int *nbytes,
+ int *fd,
+ bool * chunkFlag,
+ int ndim,
+ int dim[],
+ int baseSize)
{
- char *inputfile, *accessfile = NULL, *chunkfile = NULL;
- char *retStr, *_AdvanceBy1word();
- Oid lobjId;
-
- str = _AdvanceBy1word(str, &inputfile);
-
- while (str != NULL) {
- char *word;
-
- str = _AdvanceBy1word(str, &word);
-
- if (!strcmp (word, "-chunk")) {
- if (str == NULL)
- elog(WARN, "array_in: access pattern file required");
- str = _AdvanceBy1word(str, &accessfile);
- }
- else if (!strcmp (word, "-noreorg")) {
- if (str == NULL)
- elog(WARN, "array_in: chunk file required");
- str = _AdvanceBy1word(str, &chunkfile);
- } else {
- elog(WARN, "usage: <input file> -chunk DEFAULT/<access pattern file> -invert/-native [-noreorg <chunk file>]");
+ char *inputfile,
+ *accessfile = NULL,
+ *chunkfile = NULL;
+ char *retStr,
+ *_AdvanceBy1word();
+ Oid lobjId;
+
+ str = _AdvanceBy1word(str, &inputfile);
+
+ while (str != NULL)
+ {
+ char *word;
+
+ str = _AdvanceBy1word(str, &word);
+
+ if (!strcmp(word, "-chunk"))
+ {
+ if (str == NULL)
+ elog(WARN, "array_in: access pattern file required");
+ str = _AdvanceBy1word(str, &accessfile);
+ }
+ else if (!strcmp(word, "-noreorg"))
+ {
+ if (str == NULL)
+ elog(WARN, "array_in: chunk file required");
+ str = _AdvanceBy1word(str, &chunkfile);
+ }
+ else
+ {
+ elog(WARN, "usage: <input file> -chunk DEFAULT/<access pattern file> -invert/-native [-noreorg <chunk file>]");
+ }
+ }
+
+ if (inputfile == NULL)
+ elog(WARN, "array_in: missing file name");
+ lobjId = lo_creat(0);
+ *fd = lo_open(lobjId, INV_READ);
+ if (*fd < 0)
+ elog(WARN, "Large object create failed");
+ retStr = inputfile;
+ *nbytes = strlen(retStr) + 2;
+
+ if (accessfile)
+ {
+ FILE *afd;
+
+ if ((afd = AllocateFile(accessfile, "r")) == NULL)
+ elog(WARN, "unable to open access pattern file");
+ *chunkFlag = true;
+ retStr = _ChunkArray(*fd, afd, ndim, dim, baseSize, nbytes,
+ chunkfile);
+ FreeFile(afd);
}
- }
-
- if (inputfile == NULL)
- elog(WARN, "array_in: missing file name");
- lobjId = lo_creat(0);
- *fd = lo_open(lobjId, INV_READ);
- if ( *fd < 0 )
- elog(WARN, "Large object create failed");
- retStr = inputfile;
- *nbytes = strlen(retStr) + 2;
-
- if ( accessfile ) {
- FILE *afd;
- if ((afd = AllocateFile(accessfile, "r")) == NULL)
- elog(WARN, "unable to open access pattern file");
- *chunkFlag = true;
- retStr = _ChunkArray(*fd, afd, ndim, dim, baseSize, nbytes,
- chunkfile);
- FreeFile(afd);
- }
- return(retStr);
+ return (retStr);
}
+
#endif
static void
-_CopyArrayEls(char **values,
- char *p,
- int nitems,
- int typlen,
- char typalign,
- bool typbyval)
+_CopyArrayEls(char **values,
+ char *p,
+ int nitems,
+ int typlen,
+ char typalign,
+ bool typbyval)
{
- int i;
-
- for (i = 0; i < nitems; i++) {
- int inc;
- inc = ArrayCastAndSet(values[i], typbyval, typlen, p);
- p += inc;
- if (!typbyval)
- pfree(values[i]);
- }
- pfree(values);
+ int i;
+
+ for (i = 0; i < nitems; i++)
+ {
+ int inc;
+
+ inc = ArrayCastAndSet(values[i], typbyval, typlen, p);
+ p += inc;
+ if (!typbyval)
+ pfree(values[i]);
+ }
+ pfree(values);
}
/*-------------------------------------------------------------------------
- * array_out :
- * takes the internal representation of an array and returns a string
- * containing the array in its external format.
+ * array_out :
+ * takes the internal representation of an array and returns a string
+ * containing the array in its external format.
*-------------------------------------------------------------------------
*/
-char *
-array_out(ArrayType *v, Oid element_type)
+char *
+array_out(ArrayType * v, Oid element_type)
{
- int typlen;
- bool typbyval;
- char typdelim;
- Oid typoutput, typelem;
- func_ptr outputproc;
- char typalign;
-
- char *p, *retval, **values, delim[2];
- int nitems, overall_length, i, j, k, indx[MAXDIM];
- bool dummy_bool;
- int dummy_int;
- int ndim, *dim;
-
- if (v == (ArrayType *) NULL)
- return ((char *) NULL);
-
- if (ARR_IS_LO(v) == true) {
- char *p, *save_p;
- int nbytes;
-
- /* get a wide string to print to */
- p = array_dims(v, &dummy_bool);
- nbytes = strlen(ARR_DATA_PTR(v)) + 4 + *(int *)p;
-
- save_p = (char *) palloc(nbytes);
-
- strcpy(save_p, p + sizeof(int));
- strcat(save_p, ASSGN);
- strcat(save_p, ARR_DATA_PTR(v));
- pfree(p);
- return (save_p);
- }
-
- system_cache_lookup(element_type, false, &typlen, &typbyval,
- &typdelim, &typelem, &typoutput, &typalign);
- fmgr_info(typoutput, & outputproc, &dummy_int);
- sprintf(delim, "%c", typdelim);
- ndim = ARR_NDIM(v);
- dim = ARR_DIMS(v);
- nitems = getNitems(ndim, dim);
-
- if (nitems == 0) {
- char *emptyArray = palloc(3);
- emptyArray[0] = '{';
- emptyArray[1] = '}';
- emptyArray[2] = '\0';
- return emptyArray;
- }
-
- p = ARR_DATA_PTR(v);
- overall_length = 1; /* [TRH] don't forget to count \0 at end. */
- values = (char **) palloc(nitems * sizeof (char *));
- for (i = 0; i < nitems; i++) {
- if (typbyval) {
- switch(typlen) {
- case 1:
- values[i] = (*outputproc) (*p, typelem);
- break;
- case 2:
- values[i] = (*outputproc) (* (int16 *) p, typelem);
- break;
- case 3:
- case 4:
- values[i] = (*outputproc) (* (int32 *) p, typelem);
- break;
- }
- p += typlen;
- } else {
- values[i] = (*outputproc) (p, typelem);
- if (typlen > 0)
- p += typlen;
- else
- p += INTALIGN(* (int32 *) p);
- /*
- * For the pair of double quotes
- */
- overall_length += 2;
- }
- overall_length += (strlen(values[i]) + 1);
- }
-
- /*
- * count total number of curly braces in output string
- */
- for (i = j = 0, k = 1; i < ndim; k *= dim[i++], j += k);
-
- p = (char *) palloc(overall_length + 2*j);
- retval = p;
-
- strcpy(p, "{");
- for (i = 0; i < ndim; indx[i++] = 0);
- j = 0; k = 0;
- do {
- for (i = j; i < ndim - 1; i++)
- strcat(p, "{");
- /*
- * Surround anything that is not passed by value in double quotes.
- * See above for more details.
+ int typlen;
+ bool typbyval;
+ char typdelim;
+ Oid typoutput,
+ typelem;
+ func_ptr outputproc;
+ char typalign;
+
+ char *p,
+ *retval,
+ **values,
+ delim[2];
+ int nitems,
+ overall_length,
+ i,
+ j,
+ k,
+ indx[MAXDIM];
+ bool dummy_bool;
+ int dummy_int;
+ int ndim,
+ *dim;
+
+ if (v == (ArrayType *) NULL)
+ return ((char *) NULL);
+
+ if (ARR_IS_LO(v) == true)
+ {
+ char *p,
+ *save_p;
+ int nbytes;
+
+ /* get a wide string to print to */
+ p = array_dims(v, &dummy_bool);
+ nbytes = strlen(ARR_DATA_PTR(v)) + 4 + *(int *) p;
+
+ save_p = (char *) palloc(nbytes);
+
+ strcpy(save_p, p + sizeof(int));
+ strcat(save_p, ASSGN);
+ strcat(save_p, ARR_DATA_PTR(v));
+ pfree(p);
+ return (save_p);
+ }
+
+ system_cache_lookup(element_type, false, &typlen, &typbyval,
+ &typdelim, &typelem, &typoutput, &typalign);
+ fmgr_info(typoutput, &outputproc, &dummy_int);
+ sprintf(delim, "%c", typdelim);
+ ndim = ARR_NDIM(v);
+ dim = ARR_DIMS(v);
+ nitems = getNitems(ndim, dim);
+
+ if (nitems == 0)
+ {
+ char *emptyArray = palloc(3);
+
+ emptyArray[0] = '{';
+ emptyArray[1] = '}';
+ emptyArray[2] = '\0';
+ return emptyArray;
+ }
+
+ p = ARR_DATA_PTR(v);
+ overall_length = 1; /* [TRH] don't forget to count \0 at end. */
+ values = (char **) palloc(nitems * sizeof(char *));
+ for (i = 0; i < nitems; i++)
+ {
+ if (typbyval)
+ {
+ switch (typlen)
+ {
+ case 1:
+ values[i] = (*outputproc) (*p, typelem);
+ break;
+ case 2:
+ values[i] = (*outputproc) (*(int16 *) p, typelem);
+ break;
+ case 3:
+ case 4:
+ values[i] = (*outputproc) (*(int32 *) p, typelem);
+ break;
+ }
+ p += typlen;
+ }
+ else
+ {
+ values[i] = (*outputproc) (p, typelem);
+ if (typlen > 0)
+ p += typlen;
+ else
+ p += INTALIGN(*(int32 *) p);
+
+ /*
+ * For the pair of double quotes
+ */
+ overall_length += 2;
+ }
+ overall_length += (strlen(values[i]) + 1);
+ }
+
+ /*
+ * count total number of curly braces in output string
*/
- if (!typbyval) {
- strcat(p, "\"");
- strcat(p, values[k]);
- strcat(p, "\"");
- } else
- strcat(p, values[k]);
- pfree(values[k++]);
-
- for (i = ndim - 1; i >= 0; i--) {
- indx[i] = (indx[i] + 1)%dim[i];
- if (indx[i]) {
- strcat (p, delim);
- break;
- } else
- strcat (p, "}");
- }
- j = i;
- } while (j != -1);
-
- pfree(values);
- return(retval);
+ for (i = j = 0, k = 1; i < ndim; k *= dim[i++], j += k);
+
+ p = (char *) palloc(overall_length + 2 * j);
+ retval = p;
+
+ strcpy(p, "{");
+ for (i = 0; i < ndim; indx[i++] = 0);
+ j = 0;
+ k = 0;
+ do
+ {
+ for (i = j; i < ndim - 1; i++)
+ strcat(p, "{");
+
+ /*
+ * Surround anything that is not passed by value in double quotes.
+ * See above for more details.
+ */
+ if (!typbyval)
+ {
+ strcat(p, "\"");
+ strcat(p, values[k]);
+ strcat(p, "\"");
+ }
+ else
+ strcat(p, values[k]);
+ pfree(values[k++]);
+
+ for (i = ndim - 1; i >= 0; i--)
+ {
+ indx[i] = (indx[i] + 1) % dim[i];
+ if (indx[i])
+ {
+ strcat(p, delim);
+ break;
+ }
+ else
+ strcat(p, "}");
+ }
+ j = i;
+ } while (j != -1);
+
+ pfree(values);
+ return (retval);
}
/*-----------------------------------------------------------------------------
* array_dims :
- * returns the dimension of the array pointed to by "v"
- *----------------------------------------------------------------------------
+ * returns the dimension of the array pointed to by "v"
+ *----------------------------------------------------------------------------
*/
-char *
-array_dims(ArrayType *v, bool *isNull)
+char *
+array_dims(ArrayType * v, bool * isNull)
{
- char *p, *save_p;
- int nbytes, i;
- int *dimv, *lb;
-
- if (v == (ArrayType *) NULL) RETURN_NULL;
- nbytes = ARR_NDIM(v)*33;
- /*
- * 33 since we assume 15 digits per number + ':' +'[]'
- */
- save_p = p = (char *) palloc(nbytes + 4);
- memset(save_p, 0, nbytes + 4);
- dimv = ARR_DIMS(v); lb = ARR_LBOUND(v);
- p += 4;
- for (i = 0; i < ARR_NDIM(v); i++) {
- sprintf(p, "[%d:%d]", lb[i], dimv[i]+lb[i]-1);
- p += strlen(p);
- }
- nbytes = strlen(save_p + 4) + 4;
- memmove(save_p, &nbytes,4);
- return (save_p);
-}
+ char *p,
+ *save_p;
+ int nbytes,
+ i;
+ int *dimv,
+ *lb;
+
+ if (v == (ArrayType *) NULL)
+ RETURN_NULL;
+ nbytes = ARR_NDIM(v) * 33;
+
+ /*
+ * 33 since we assume 15 digits per number + ':' +'[]'
+ */
+ save_p = p = (char *) palloc(nbytes + 4);
+ memset(save_p, 0, nbytes + 4);
+ dimv = ARR_DIMS(v);
+ lb = ARR_LBOUND(v);
+ p += 4;
+ for (i = 0; i < ARR_NDIM(v); i++)
+ {
+ sprintf(p, "[%d:%d]", lb[i], dimv[i] + lb[i] - 1);
+ p += strlen(p);
+ }
+ nbytes = strlen(save_p + 4) + 4;
+ memmove(save_p, &nbytes, 4);
+ return (save_p);
+}
/*---------------------------------------------------------------------------
* array_ref :
- * This routing takes an array pointer and an index array and returns
- * a pointer to the referred element if element is passed by
- * reference otherwise returns the value of the referred element.
+ * This routing takes an array pointer and an index array and returns
+ * a pointer to the referred element if element is passed by
+ * reference otherwise returns the value of the referred element.
*---------------------------------------------------------------------------
*/
Datum
-array_ref(ArrayType *array,
- int n,
- int indx[],
- int reftype,
- int elmlen,
- int arraylen,
- bool *isNull)
+array_ref(ArrayType * array,
+ int n,
+ int indx[],
+ int reftype,
+ int elmlen,
+ int arraylen,
+ bool * isNull)
{
- int i, ndim, *dim, *lb, offset, nbytes;
- struct varlena *v = NULL;
- char *retval = NULL;
-
- if (array == (ArrayType *) NULL) RETURN_NULL;
- if (arraylen > 0) {
- /*
- * fixed length arrays -- these are assumed to be 1-d
- */
- if (indx[0]*elmlen > arraylen)
- elog(WARN, "array_ref: array bound exceeded");
- retval = (char *)array + indx[0]*elmlen;
- return _ArrayCast(retval, reftype, elmlen);
- }
- dim = ARR_DIMS(array);
- lb = ARR_LBOUND(array);
- ndim = ARR_NDIM(array);
- nbytes = (* (int32 *) array) - ARR_OVERHEAD(ndim);
-
- if (!SanityCheckInput(ndim, n, dim, lb, indx))
- RETURN_NULL;
-
- offset = GetOffset(n, dim, lb, indx);
-
- if (ARR_IS_LO(array)) {
- char * lo_name;
- int fd = 0;
-
- /* We are assuming fixed element lengths here */
- offset *= elmlen;
- lo_name = (char *)ARR_DATA_PTR(array);
+ int i,
+ ndim,
+ *dim,
+ *lb,
+ offset,
+ nbytes;
+ struct varlena *v = NULL;
+ char *retval = NULL;
+
+ if (array == (ArrayType *) NULL)
+ RETURN_NULL;
+ if (arraylen > 0)
+ {
+
+ /*
+ * fixed length arrays -- these are assumed to be 1-d
+ */
+ if (indx[0] * elmlen > arraylen)
+ elog(WARN, "array_ref: array bound exceeded");
+ retval = (char *) array + indx[0] * elmlen;
+ return _ArrayCast(retval, reftype, elmlen);
+ }
+ dim = ARR_DIMS(array);
+ lb = ARR_LBOUND(array);
+ ndim = ARR_NDIM(array);
+ nbytes = (*(int32 *) array) - ARR_OVERHEAD(ndim);
+
+ if (!SanityCheckInput(ndim, n, dim, lb, indx))
+ RETURN_NULL;
+
+ offset = GetOffset(n, dim, lb, indx);
+
+ if (ARR_IS_LO(array))
+ {
+ char *lo_name;
+ int fd = 0;
+
+ /* We are assuming fixed element lengths here */
+ offset *= elmlen;
+ lo_name = (char *) ARR_DATA_PTR(array);
#ifdef LOARRAY
- if ((fd = LOopen(lo_name, ARR_IS_INV(array)?INV_READ:O_RDONLY)) < 0)
- RETURN_NULL;
-#endif
- if (ARR_IS_CHUNKED(array))
- v = _ReadChunkArray1El(indx, elmlen, fd, array, isNull);
- else {
- if (lo_lseek(fd, offset, SEEK_SET) < 0)
- RETURN_NULL;
+ if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_READ : O_RDONLY)) < 0)
+ RETURN_NULL;
+#endif
+ if (ARR_IS_CHUNKED(array))
+ v = _ReadChunkArray1El(indx, elmlen, fd, array, isNull);
+ else
+ {
+ if (lo_lseek(fd, offset, SEEK_SET) < 0)
+ RETURN_NULL;
#ifdef LOARRAY
- v = (struct varlena *) LOread(fd, elmlen);
+ v = (struct varlena *) LOread(fd, elmlen);
#endif
- }
- if (*isNull) RETURN_NULL;
- if (VARSIZE(v) - 4 < elmlen)
- RETURN_NULL;
- lo_close(fd);
- retval = (char *)_ArrayCast((char *)VARDATA(v), reftype, elmlen);
- if ( reftype == 0) { /* not by value */
- char * tempdata = palloc (elmlen);
- memmove(tempdata, retval, elmlen);
- retval = tempdata;
+ }
+ if (*isNull)
+ RETURN_NULL;
+ if (VARSIZE(v) - 4 < elmlen)
+ RETURN_NULL;
+ lo_close(fd);
+ retval = (char *) _ArrayCast((char *) VARDATA(v), reftype, elmlen);
+ if (reftype == 0)
+ { /* not by value */
+ char *tempdata = palloc(elmlen);
+
+ memmove(tempdata, retval, elmlen);
+ retval = tempdata;
+ }
+ pfree(v);
+ return (Datum) retval;
+ }
+
+ if (elmlen > 0)
+ {
+ offset = offset * elmlen;
+ /* off the end of the array */
+ if (nbytes - offset < 1)
+ RETURN_NULL;
+ retval = ARR_DATA_PTR(array) + offset;
+ return _ArrayCast(retval, reftype, elmlen);
+ }
+ else
+ {
+ bool done = false;
+ char *temp;
+ int bytes = nbytes;
+
+ temp = ARR_DATA_PTR(array);
+ i = 0;
+ while (bytes > 0 && !done)
+ {
+ if (i == offset)
+ {
+ retval = temp;
+ done = true;
+ }
+ bytes -= INTALIGN(*(int32 *) temp);
+ temp += INTALIGN(*(int32 *) temp);
+ i++;
+ }
+ if (!done)
+ RETURN_NULL;
+ return (Datum) retval;
}
- pfree(v);
- return (Datum) retval;
- }
-
- if (elmlen > 0) {
- offset = offset * elmlen;
- /* off the end of the array */
- if (nbytes - offset < 1) RETURN_NULL;
- retval = ARR_DATA_PTR (array) + offset;
- return _ArrayCast(retval, reftype, elmlen);
- } else {
- bool done = false;
- char *temp;
- int bytes = nbytes;
- temp = ARR_DATA_PTR (array);
- i = 0;
- while (bytes > 0 && !done) {
- if (i == offset) {
- retval = temp;
- done = true;
- }
- bytes -= INTALIGN(* (int32 *) temp);
- temp += INTALIGN(* (int32 *) temp);
- i++;
- }
- if (! done)
- RETURN_NULL;
- return (Datum) retval;
- }
}
/*-----------------------------------------------------------------------------
* array_clip :
- * This routine takes an array and a range of indices (upperIndex and
- * lowerIndx), creates a new array structure for the referred elements
- * and returns a pointer to it.
+ * This routine takes an array and a range of indices (upperIndex and
+ * lowerIndx), creates a new array structure for the referred elements
+ * and returns a pointer to it.
*-----------------------------------------------------------------------------
*/
Datum
-array_clip(ArrayType *array,
- int n,
- int upperIndx[],
- int lowerIndx[],
- int reftype,
- int len,
- bool *isNull)
+array_clip(ArrayType * array,
+ int n,
+ int upperIndx[],
+ int lowerIndx[],
+ int reftype,
+ int len,
+ bool * isNull)
{
- int i, ndim, *dim, *lb, nbytes;
- ArrayType *newArr;
- int bytes, span[MAXDIM];
-
- /* timer_start(); */
- if (array == (ArrayType *) NULL)
- RETURN_NULL;
- dim = ARR_DIMS(array);
- lb = ARR_LBOUND(array);
- ndim = ARR_NDIM(array);
- nbytes = (* (int32 *) array) - ARR_OVERHEAD(ndim);
-
- if (!SanityCheckInput(ndim, n, dim, lb, upperIndx))
- RETURN_NULL;
-
- if (!SanityCheckInput(ndim, n, dim, lb, lowerIndx))
- RETURN_NULL;
-
- for (i = 0; i < n; i++)
- if (lowerIndx[i] > upperIndx[i])
- elog(WARN, "lowerIndex cannot be larger than upperIndx");
- mda_get_range(n, span, lowerIndx, upperIndx);
-
- if (ARR_IS_LO(array)) {
+ int i,
+ ndim,
+ *dim,
+ *lb,
+ nbytes;
+ ArrayType *newArr;
+ int bytes,
+ span[MAXDIM];
+
+ /* timer_start(); */
+ if (array == (ArrayType *) NULL)
+ RETURN_NULL;
+ dim = ARR_DIMS(array);
+ lb = ARR_LBOUND(array);
+ ndim = ARR_NDIM(array);
+ nbytes = (*(int32 *) array) - ARR_OVERHEAD(ndim);
+
+ if (!SanityCheckInput(ndim, n, dim, lb, upperIndx))
+ RETURN_NULL;
+
+ if (!SanityCheckInput(ndim, n, dim, lb, lowerIndx))
+ RETURN_NULL;
+
+ for (i = 0; i < n; i++)
+ if (lowerIndx[i] > upperIndx[i])
+ elog(WARN, "lowerIndex cannot be larger than upperIndx");
+ mda_get_range(n, span, lowerIndx, upperIndx);
+
+ if (ARR_IS_LO(array))
+ {
#ifdef LOARRAY
- char * lo_name;
+ char *lo_name;
+
#endif
- char *newname = NULL;
- int fd = 0, newfd = 0, isDestLO = true, rsize;
-
- if (len < 0)
- elog(WARN, "array_clip: array of variable length objects not supported");
+ char *newname = NULL;
+ int fd = 0,
+ newfd = 0,
+ isDestLO = true,
+ rsize;
+
+ if (len < 0)
+ elog(WARN, "array_clip: array of variable length objects not supported");
#ifdef LOARRAY
- lo_name = (char *)ARR_DATA_PTR(array);
- if ((fd = LOopen(lo_name, ARR_IS_INV(array)?INV_READ:O_RDONLY)) < 0)
- RETURN_NULL;
- newname = _array_newLO( &newfd, Unix );
+ lo_name = (char *) ARR_DATA_PTR(array);
+ if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_READ : O_RDONLY)) < 0)
+ RETURN_NULL;
+ newname = _array_newLO(&newfd, Unix);
#endif
- bytes = strlen(newname) + 1 + ARR_OVERHEAD(n);
- newArr = (ArrayType *) palloc(bytes);
- memmove(newArr, array, sizeof(ArrayType));
- memmove(newArr, &bytes, sizeof(int));
- memmove(ARR_DIMS(newArr), span, n*sizeof(int));
- memmove(ARR_LBOUND(newArr), lowerIndx, n*sizeof(int));
- strcpy(ARR_DATA_PTR(newArr), newname);
-
- rsize = compute_size (lowerIndx, upperIndx, n, len);
- if (rsize < MAX_BUFF_SIZE) {
- char *buff;
- rsize += 4;
- buff = palloc(rsize);
- if ( buff )
- isDestLO = false;
- if (ARR_IS_CHUNKED(array)) {
- _ReadChunkArray(lowerIndx, upperIndx, len, fd, &(buff[4]),
- array,0,isNull);
- } else {
- _ReadArray(lowerIndx, upperIndx, len, fd, (int)&(buff[4]),
- array,
- 0,isNull);
- }
- memmove(buff, &rsize, 4);
+ bytes = strlen(newname) + 1 + ARR_OVERHEAD(n);
+ newArr = (ArrayType *) palloc(bytes);
+ memmove(newArr, array, sizeof(ArrayType));
+ memmove(newArr, &bytes, sizeof(int));
+ memmove(ARR_DIMS(newArr), span, n * sizeof(int));
+ memmove(ARR_LBOUND(newArr), lowerIndx, n * sizeof(int));
+ strcpy(ARR_DATA_PTR(newArr), newname);
+
+ rsize = compute_size(lowerIndx, upperIndx, n, len);
+ if (rsize < MAX_BUFF_SIZE)
+ {
+ char *buff;
+
+ rsize += 4;
+ buff = palloc(rsize);
+ if (buff)
+ isDestLO = false;
+ if (ARR_IS_CHUNKED(array))
+ {
+ _ReadChunkArray(lowerIndx, upperIndx, len, fd, &(buff[4]),
+ array, 0, isNull);
+ }
+ else
+ {
+ _ReadArray(lowerIndx, upperIndx, len, fd, (int) &(buff[4]),
+ array,
+ 0, isNull);
+ }
+ memmove(buff, &rsize, 4);
#ifdef LOARRAY
- if (! *isNull)
- bytes = LOwrite(newfd, (struct varlena *)buff);
+ if (!*isNull)
+ bytes = LOwrite(newfd, (struct varlena *) buff);
#endif
- pfree (buff);
- }
- if (isDestLO)
- if (ARR_IS_CHUNKED(array)) {
- _ReadChunkArray(lowerIndx, upperIndx, len, fd, (char*)newfd, array,
- 1,isNull);
- } else {
- _ReadArray(lowerIndx, upperIndx, len, fd, newfd, array, 1,isNull);
- }
+ pfree(buff);
+ }
+ if (isDestLO)
+ if (ARR_IS_CHUNKED(array))
+ {
+ _ReadChunkArray(lowerIndx, upperIndx, len, fd, (char *) newfd, array,
+ 1, isNull);
+ }
+ else
+ {
+ _ReadArray(lowerIndx, upperIndx, len, fd, newfd, array, 1, isNull);
+ }
#ifdef LOARRAY
- LOclose(fd);
- LOclose(newfd);
+ LOclose(fd);
+ LOclose(newfd);
#endif
- if (*isNull) {
- pfree(newArr);
- newArr = NULL;
- }
- /* timer_end(); */
- return ((Datum) newArr);
- }
-
- if (len > 0) {
- bytes = getNitems(n, span);
- bytes = bytes*len + ARR_OVERHEAD(n);
- } else {
- bytes = _ArrayClipCount(lowerIndx, upperIndx, array);
- bytes += ARR_OVERHEAD(n);
- }
- newArr = (ArrayType *) palloc(bytes);
- memmove(newArr, array, sizeof(ArrayType));
- memmove(newArr, &bytes, sizeof(int));
- memmove(ARR_DIMS(newArr), span, n*sizeof(int));
- memmove(ARR_LBOUND(newArr), lowerIndx, n*sizeof(int));
- _ArrayRange(lowerIndx, upperIndx, len, ARR_DATA_PTR(newArr), array, 1);
- return (Datum) newArr;
+ if (*isNull)
+ {
+ pfree(newArr);
+ newArr = NULL;
+ }
+ /* timer_end(); */
+ return ((Datum) newArr);
+ }
+
+ if (len > 0)
+ {
+ bytes = getNitems(n, span);
+ bytes = bytes * len + ARR_OVERHEAD(n);
+ }
+ else
+ {
+ bytes = _ArrayClipCount(lowerIndx, upperIndx, array);
+ bytes += ARR_OVERHEAD(n);
+ }
+ newArr = (ArrayType *) palloc(bytes);
+ memmove(newArr, array, sizeof(ArrayType));
+ memmove(newArr, &bytes, sizeof(int));
+ memmove(ARR_DIMS(newArr), span, n * sizeof(int));
+ memmove(ARR_LBOUND(newArr), lowerIndx, n * sizeof(int));
+ _ArrayRange(lowerIndx, upperIndx, len, ARR_DATA_PTR(newArr), array, 1);
+ return (Datum) newArr;
}
/*-----------------------------------------------------------------------------
* array_set :
- * This routine sets the value of an array location (specified by an index array)
- * to a new value specified by "dataPtr".
+ * This routine sets the value of an array location (specified by an index array)
+ * to a new value specified by "dataPtr".
* result :
- * returns a pointer to the modified array.
+ * returns a pointer to the modified array.
*-----------------------------------------------------------------------------
*/
-char *
-array_set(ArrayType *array,
- int n,
- int indx[],
- char *dataPtr,
- int reftype,
- int elmlen,
- int arraylen,
- bool *isNull)
+char *
+array_set(ArrayType * array,
+ int n,
+ int indx[],
+ char *dataPtr,
+ int reftype,
+ int elmlen,
+ int arraylen,
+ bool * isNull)
{
- int ndim, *dim, *lb, offset, nbytes;
- char *pos;
-
- if (array == (ArrayType *) NULL)
- RETURN_NULL;
- if (arraylen > 0) {
- /*
- * fixed length arrays -- these are assumed to be 1-d
- */
- if (indx[0]*elmlen > arraylen)
- elog(WARN, "array_ref: array bound exceeded");
- pos = (char *)array + indx[0]*elmlen;
- ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos);
- return((char *)array);
- }
- dim = ARR_DIMS(array);
- lb = ARR_LBOUND(array);
- ndim = ARR_NDIM(array);
- nbytes = (* (int32 *) array) - ARR_OVERHEAD(ndim);
-
- if (!SanityCheckInput(ndim, n, dim, lb, indx))
- {
- elog(WARN, "array_set: array bound exceeded");
- return((char *)array);
- }
- offset = GetOffset( n, dim, lb, indx);
-
- if (ARR_IS_LO(array)) {
- int fd = 0;
- struct varlena *v;
-
- /* We are assuming fixed element lengths here */
- offset *= elmlen;
+ int ndim,
+ *dim,
+ *lb,
+ offset,
+ nbytes;
+ char *pos;
+
+ if (array == (ArrayType *) NULL)
+ RETURN_NULL;
+ if (arraylen > 0)
+ {
+
+ /*
+ * fixed length arrays -- these are assumed to be 1-d
+ */
+ if (indx[0] * elmlen > arraylen)
+ elog(WARN, "array_ref: array bound exceeded");
+ pos = (char *) array + indx[0] * elmlen;
+ ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos);
+ return ((char *) array);
+ }
+ dim = ARR_DIMS(array);
+ lb = ARR_LBOUND(array);
+ ndim = ARR_NDIM(array);
+ nbytes = (*(int32 *) array) - ARR_OVERHEAD(ndim);
+
+ if (!SanityCheckInput(ndim, n, dim, lb, indx))
+ {
+ elog(WARN, "array_set: array bound exceeded");
+ return ((char *) array);
+ }
+ offset = GetOffset(n, dim, lb, indx);
+
+ if (ARR_IS_LO(array))
+ {
+ int fd = 0;
+ struct varlena *v;
+
+ /* We are assuming fixed element lengths here */
+ offset *= elmlen;
#ifdef LOARRAY
- char * lo_name;
-
- lo_name = ARR_DATA_PTR(array);
- if ((fd = LOopen(lo_name, ARR_IS_INV(array)?INV_WRITE:O_WRONLY)) < 0)
- return((char *)array);
-#endif
- if (lo_lseek(fd, offset, SEEK_SET) < 0)
- return((char *)array);
- v = (struct varlena *) palloc(elmlen + 4);
- VARSIZE (v) = elmlen + 4;
- ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, VARDATA(v));
+ char *lo_name;
+
+ lo_name = ARR_DATA_PTR(array);
+ if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_WRITE : O_WRONLY)) < 0)
+ return ((char *) array);
+#endif
+ if (lo_lseek(fd, offset, SEEK_SET) < 0)
+ return ((char *) array);
+ v = (struct varlena *) palloc(elmlen + 4);
+ VARSIZE(v) = elmlen + 4;
+ ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, VARDATA(v));
#ifdef LOARRAY
- n = LOwrite(fd, v);
+ n = LOwrite(fd, v);
#endif
- /* if (n < VARSIZE(v) - 4)
- RETURN_NULL;
- */
- pfree(v);
- lo_close(fd);
- return((char *)array);
- }
- if (elmlen > 0) {
- offset = offset * elmlen;
- /* off the end of the array */
- if (nbytes - offset < 1) return((char *)array);
- pos = ARR_DATA_PTR (array) + offset;
- } else {
- ArrayType *newarray;
- char *elt_ptr;
- int oldsize, newsize, oldlen, newlen, lth0, lth1, lth2;
-
- elt_ptr = array_seek(ARR_DATA_PTR(array), -1, offset);
- oldlen = INTALIGN(*(int32 *)elt_ptr);
- newlen = INTALIGN(*(int32 *)dataPtr);
-
- if (oldlen == newlen) {
- /* new element with same size, overwrite old data */
- ArrayCastAndSet(dataPtr, (bool)reftype, elmlen, elt_ptr);
- return((char *)array);
+
+ /*
+ * if (n < VARSIZE(v) - 4) RETURN_NULL;
+ */
+ pfree(v);
+ lo_close(fd);
+ return ((char *) array);
}
+ if (elmlen > 0)
+ {
+ offset = offset * elmlen;
+ /* off the end of the array */
+ if (nbytes - offset < 1)
+ return ((char *) array);
+ pos = ARR_DATA_PTR(array) + offset;
+ }
+ else
+ {
+ ArrayType *newarray;
+ char *elt_ptr;
+ int oldsize,
+ newsize,
+ oldlen,
+ newlen,
+ lth0,
+ lth1,
+ lth2;
+
+ elt_ptr = array_seek(ARR_DATA_PTR(array), -1, offset);
+ oldlen = INTALIGN(*(int32 *) elt_ptr);
+ newlen = INTALIGN(*(int32 *) dataPtr);
+
+ if (oldlen == newlen)
+ {
+ /* new element with same size, overwrite old data */
+ ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, elt_ptr);
+ return ((char *) array);
+ }
+
+ /* new element with different size, reallocate the array */
+ oldsize = array->size;
+ lth0 = ARR_OVERHEAD(n);
+ lth1 = (int) (elt_ptr - ARR_DATA_PTR(array));
+ lth2 = (int) (oldsize - lth0 - lth1 - oldlen);
+ newsize = lth0 + lth1 + newlen + lth2;
+
+ newarray = (ArrayType *) palloc(newsize);
+ memmove((char *) newarray, (char *) array, lth0 + lth1);
+ newarray->size = newsize;
+ newlen = ArrayCastAndSet(dataPtr, (bool) reftype, elmlen,
+ (char *) newarray + lth0 + lth1);
+ memmove((char *) newarray + lth0 + lth1 + newlen,
+ (char *) array + lth0 + lth1 + oldlen, lth2);
- /* new element with different size, reallocate the array */
- oldsize = array->size;
- lth0 = ARR_OVERHEAD(n);
- lth1 = (int)(elt_ptr - ARR_DATA_PTR(array));
- lth2 = (int)(oldsize - lth0 - lth1 - oldlen);
- newsize = lth0 + lth1 + newlen + lth2;
-
- newarray = (ArrayType *)palloc(newsize);
- memmove((char *)newarray, (char *)array, lth0+lth1);
- newarray->size = newsize;
- newlen = ArrayCastAndSet(dataPtr, (bool)reftype, elmlen,
- (char *)newarray+lth0+lth1);
- memmove((char *)newarray+lth0+lth1+newlen,
- (char *)array+lth0+lth1+oldlen, lth2);
-
- /* ??? who should free this storage ??? */
- return((char *)newarray);
- }
- ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos);
- return((char *)array);
+ /* ??? who should free this storage ??? */
+ return ((char *) newarray);
+ }
+ ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos);
+ return ((char *) array);
}
/*----------------------------------------------------------------------------
* array_assgn :
- * This routine sets the value of a range of array locations (specified
- * by upper and lower index values ) to new values passed as
- * another array
+ * This routine sets the value of a range of array locations (specified
+ * by upper and lower index values ) to new values passed as
+ * another array
* result :
- * returns a pointer to the modified array.
+ * returns a pointer to the modified array.
*----------------------------------------------------------------------------
*/
-char *
-array_assgn(ArrayType *array,
- int n,
- int upperIndx[],
- int lowerIndx[],
- ArrayType *newArr,
- int reftype,
- int len,
- bool *isNull)
+char *
+array_assgn(ArrayType * array,
+ int n,
+ int upperIndx[],
+ int lowerIndx[],
+ ArrayType * newArr,
+ int reftype,
+ int len,
+ bool * isNull)
{
- int i, ndim, *dim, *lb;
-
- if (array == (ArrayType *) NULL)
- RETURN_NULL;
- if (len < 0)
- elog(WARN,"array_assgn:updates on arrays of variable length elements not allowed");
-
- dim = ARR_DIMS(array);
- lb = ARR_LBOUND(array);
- ndim = ARR_NDIM(array);
-
- if (!SanityCheckInput(ndim, n, dim, lb, upperIndx) ||
- !SanityCheckInput(ndim, n, dim, lb, lowerIndx)) {
- return((char *)array);
- }
-
- for (i = 0; i < n; i++)
- if (lowerIndx[i] > upperIndx[i])
- elog(WARN, "lowerIndex larger than upperIndx");
-
- if (ARR_IS_LO(array)) {
- int fd = 0, newfd = 0;
-
+ int i,
+ ndim,
+ *dim,
+ *lb;
+
+ if (array == (ArrayType *) NULL)
+ RETURN_NULL;
+ if (len < 0)
+ elog(WARN, "array_assgn:updates on arrays of variable length elements not allowed");
+
+ dim = ARR_DIMS(array);
+ lb = ARR_LBOUND(array);
+ ndim = ARR_NDIM(array);
+
+ if (!SanityCheckInput(ndim, n, dim, lb, upperIndx) ||
+ !SanityCheckInput(ndim, n, dim, lb, lowerIndx))
+ {
+ return ((char *) array);
+ }
+
+ for (i = 0; i < n; i++)
+ if (lowerIndx[i] > upperIndx[i])
+ elog(WARN, "lowerIndex larger than upperIndx");
+
+ if (ARR_IS_LO(array))
+ {
+ int fd = 0,
+ newfd = 0;
+
#ifdef LOARRAY
- char * lo_name;
+ char *lo_name;
- lo_name = (char *)ARR_DATA_PTR(array);
- if ((fd = LOopen(lo_name, ARR_IS_INV(array)?INV_WRITE:O_WRONLY)) < 0)
- return((char *)array);
+ lo_name = (char *) ARR_DATA_PTR(array);
+ if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_WRITE : O_WRONLY)) < 0)
+ return ((char *) array);
#endif
- if (ARR_IS_LO(newArr)) {
+ if (ARR_IS_LO(newArr))
+ {
#ifdef LOARRAY
- lo_name = (char *)ARR_DATA_PTR(newArr);
- if ((newfd = LOopen(lo_name, ARR_IS_INV(newArr)?INV_READ:O_RDONLY)) < 0)
- return((char *)array);
+ lo_name = (char *) ARR_DATA_PTR(newArr);
+ if ((newfd = LOopen(lo_name, ARR_IS_INV(newArr) ? INV_READ : O_RDONLY)) < 0)
+ return ((char *) array);
#endif
- _LOArrayRange(lowerIndx, upperIndx, len, fd, newfd, array, 1, isNull);
- lo_close(newfd);
- } else {
- _LOArrayRange(lowerIndx, upperIndx, len, fd, (int)ARR_DATA_PTR(newArr),
- array, 0, isNull);
- }
- lo_close(fd);
- return ((char *) array);
- }
- _ArrayRange(lowerIndx, upperIndx, len, ARR_DATA_PTR(newArr), array, 0);
- return (char *) array;
+ _LOArrayRange(lowerIndx, upperIndx, len, fd, newfd, array, 1, isNull);
+ lo_close(newfd);
+ }
+ else
+ {
+ _LOArrayRange(lowerIndx, upperIndx, len, fd, (int) ARR_DATA_PTR(newArr),
+ array, 0, isNull);
+ }
+ lo_close(fd);
+ return ((char *) array);
+ }
+ _ArrayRange(lowerIndx, upperIndx, len, ARR_DATA_PTR(newArr), array, 0);
+ return (char *) array;
}
/*-----------------------------------------------------------------------------
* array_eq :
- * compares two arrays for equality
+ * compares two arrays for equality
* result :
- * returns 1 if the arrays are equal, 0 otherwise.
+ * returns 1 if the arrays are equal, 0 otherwise.
*-----------------------------------------------------------------------------
*/
int
-array_eq (ArrayType *array1, ArrayType *array2)
+array_eq(ArrayType * array1, ArrayType * array2)
{
- if ((array1 == NULL) || (array2 == NULL))
- return(0);
- if (*(int *)array1 != *(int *)array2)
- return (0);
- if (memcmp(array1, array2, *(int *)array1))
- return(0);
- return(1);
+ if ((array1 == NULL) || (array2 == NULL))
+ return (0);
+ if (*(int *) array1 != *(int *) array2)
+ return (0);
+ if (memcmp(array1, array2, *(int *) array1))
+ return (0);
+ return (1);
}
/***************************************************************************/
-/******************| Support Routines |*****************/
+/******************| Support Routines |*****************/
/***************************************************************************/
static void
system_cache_lookup(Oid element_type,
- bool input,
- int *typlen,
- bool *typbyval,
- char *typdelim,
- Oid *typelem,
- Oid *proc,
- char *typalign)
+ bool input,
+ int *typlen,
+ bool * typbyval,
+ char *typdelim,
+ Oid * typelem,
+ Oid * proc,
+ char *typalign)
{
- HeapTuple typeTuple;
- TypeTupleForm typeStruct;
-
- typeTuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(element_type),
- 0,0,0);
-
- if (!HeapTupleIsValid(typeTuple)) {
- elog(WARN, "array_out: Cache lookup failed for type %d\n",
- element_type);
- return;
- }
- typeStruct = (TypeTupleForm) GETSTRUCT(typeTuple);
- *typlen = typeStruct->typlen;
- *typbyval = typeStruct->typbyval;
- *typdelim = typeStruct->typdelim;
- *typelem = typeStruct->typelem;
- *typalign = typeStruct->typalign;
- if (input) {
- *proc = typeStruct->typinput;
- } else {
- *proc = typeStruct->typoutput;
- }
+ HeapTuple typeTuple;
+ TypeTupleForm typeStruct;
+
+ typeTuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(element_type),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(typeTuple))
+ {
+ elog(WARN, "array_out: Cache lookup failed for type %d\n",
+ element_type);
+ return;
+ }
+ typeStruct = (TypeTupleForm) GETSTRUCT(typeTuple);
+ *typlen = typeStruct->typlen;
+ *typbyval = typeStruct->typbyval;
+ *typdelim = typeStruct->typdelim;
+ *typelem = typeStruct->typelem;
+ *typalign = typeStruct->typalign;
+ if (input)
+ {
+ *proc = typeStruct->typinput;
+ }
+ else
+ {
+ *proc = typeStruct->typoutput;
+ }
}
-static Datum
+static Datum
_ArrayCast(char *value, bool byval, int len)
{
- if (byval) {
- switch (len) {
- case 1:
- return((Datum) * value);
- case 2:
- return((Datum) * (int16 *) value);
- case 3:
- case 4:
- return((Datum) * (int32 *) value);
- default:
- elog(WARN, "array_ref: byval and elt len > 4!");
- break;
- }
- } else {
- return (Datum) value;
- }
- return 0;
+ if (byval)
+ {
+ switch (len)
+ {
+ case 1:
+ return ((Datum) * value);
+ case 2:
+ return ((Datum) * (int16 *) value);
+ case 3:
+ case 4:
+ return ((Datum) * (int32 *) value);
+ default:
+ elog(WARN, "array_ref: byval and elt len > 4!");
+ break;
+ }
+ }
+ else
+ {
+ return (Datum) value;
+ }
+ return 0;
}
static int
ArrayCastAndSet(char *src,
- bool typbyval,
- int typlen,
- char *dest)
+ bool typbyval,
+ int typlen,
+ char *dest)
{
- int inc;
-
- if (typlen > 0) {
- if (typbyval) {
- switch(typlen) {
- case 1:
- *dest = DatumGetChar(src);
- break;
- case 2:
- * (int16 *) dest = DatumGetInt16(src);
- break;
- case 4:
- * (int32 *) dest = (int32)src;
- break;
- }
- } else {
- memmove(dest, src, typlen);
- }
- inc = typlen;
- } else {
- memmove(dest, src, *(int32 *)src);
- inc = (INTALIGN(* (int32 *) src));
- }
- return(inc);
-}
+ int inc;
+
+ if (typlen > 0)
+ {
+ if (typbyval)
+ {
+ switch (typlen)
+ {
+ case 1:
+ *dest = DatumGetChar(src);
+ break;
+ case 2:
+ *(int16 *) dest = DatumGetInt16(src);
+ break;
+ case 4:
+ *(int32 *) dest = (int32) src;
+ break;
+ }
+ }
+ else
+ {
+ memmove(dest, src, typlen);
+ }
+ inc = typlen;
+ }
+ else
+ {
+ memmove(dest, src, *(int32 *) src);
+ inc = (INTALIGN(*(int32 *) src));
+ }
+ return (inc);
+}
#ifdef LOARRAY
-static char *
+static char *
_AdvanceBy1word(char *str, char **word)
{
- char *retstr, *space;
-
- *word = NULL;
- if (str == NULL) return str;
- while (isspace(*str)) str++;
- *word = str;
- if ((space = (char *)strchr(str, ' ')) != (char *) NULL) {
- retstr = space + 1;
- *space = '\0';
- }
- else
- retstr = NULL;
- return retstr;
+ char *retstr,
+ *space;
+
+ *word = NULL;
+ if (str == NULL)
+ return str;
+ while (isspace(*str))
+ str++;
+ *word = str;
+ if ((space = (char *) strchr(str, ' ')) != (char *) NULL)
+ {
+ retstr = space + 1;
+ *space = '\0';
+ }
+ else
+ retstr = NULL;
+ return retstr;
}
+
#endif
static int
SanityCheckInput(int ndim, int n, int dim[], int lb[], int indx[])
{
- int i;
- /* Do Sanity check on input */
- if (n != ndim) return 0;
- for (i = 0; i < ndim; i++)
- if ((lb[i] > indx[i]) || (indx[i] >= (dim[i] + lb[i])))
- return 0;
- return 1;
+ int i;
+
+ /* Do Sanity check on input */
+ if (n != ndim)
+ return 0;
+ for (i = 0; i < ndim; i++)
+ if ((lb[i] > indx[i]) || (indx[i] >= (dim[i] + lb[i])))
+ return 0;
+ return 1;
}
static void
_ArrayRange(int st[],
- int endp[],
- int bsize,
- char *destPtr,
- ArrayType *array,
- int from)
+ int endp[],
+ int bsize,
+ char *destPtr,
+ ArrayType * array,
+ int from)
{
- int n, *dim, *lb, st_pos, prod[MAXDIM];
- int span[MAXDIM], dist[MAXDIM], indx[MAXDIM];
- int i, j, inc;
- char *srcPtr;
-
- n = ARR_NDIM(array); dim = ARR_DIMS(array);
- lb = ARR_LBOUND(array); srcPtr = ARR_DATA_PTR(array);
- for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++);
- mda_get_prod(n, dim, prod);
- st_pos = tuple2linear(n, st, prod);
- srcPtr = array_seek(srcPtr, bsize, st_pos);
- mda_get_range(n, span, st, endp);
- mda_get_offset_values(n, dist, prod, span);
- for (i=0; i < n; indx[i++]=0);
- i = j = n-1; inc = bsize;
- do {
- srcPtr = array_seek(srcPtr, bsize, dist[j]);
- if (from)
- inc = array_read(destPtr, bsize, 1, srcPtr);
- else
- inc = array_read(srcPtr, bsize, 1, destPtr);
- destPtr += inc; srcPtr += inc;
- } while ((j = next_tuple(i+1, indx, span)) != -1);
+ int n,
+ *dim,
+ *lb,
+ st_pos,
+ prod[MAXDIM];
+ int span[MAXDIM],
+ dist[MAXDIM],
+ indx[MAXDIM];
+ int i,
+ j,
+ inc;
+ char *srcPtr;
+
+ n = ARR_NDIM(array);
+ dim = ARR_DIMS(array);
+ lb = ARR_LBOUND(array);
+ srcPtr = ARR_DATA_PTR(array);
+ for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++);
+ mda_get_prod(n, dim, prod);
+ st_pos = tuple2linear(n, st, prod);
+ srcPtr = array_seek(srcPtr, bsize, st_pos);
+ mda_get_range(n, span, st, endp);
+ mda_get_offset_values(n, dist, prod, span);
+ for (i = 0; i < n; indx[i++] = 0);
+ i = j = n - 1;
+ inc = bsize;
+ do
+ {
+ srcPtr = array_seek(srcPtr, bsize, dist[j]);
+ if (from)
+ inc = array_read(destPtr, bsize, 1, srcPtr);
+ else
+ inc = array_read(srcPtr, bsize, 1, destPtr);
+ destPtr += inc;
+ srcPtr += inc;
+ } while ((j = next_tuple(i + 1, indx, span)) != -1);
}
static int
-_ArrayClipCount(int stI[], int endpI[], ArrayType *array)
+_ArrayClipCount(int stI[], int endpI[], ArrayType * array)
{
- int n, *dim, *lb, st_pos, prod[MAXDIM];
- int span[MAXDIM], dist[MAXDIM], indx[MAXDIM];
- int i, j, inc, st[MAXDIM], endp[MAXDIM];
- int count = 0;
- char *ptr;
-
- n = ARR_NDIM(array); dim = ARR_DIMS(array);
- lb = ARR_LBOUND(array); ptr = ARR_DATA_PTR(array);
- for (i = 0; i < n; st[i] = stI[i]-lb[i], endp[i]=endpI[i]-lb[i], i++);
- mda_get_prod(n, dim, prod);
- st_pos = tuple2linear(n, st, prod);
- ptr = array_seek(ptr, -1, st_pos);
- mda_get_range(n, span, st, endp);
- mda_get_offset_values(n, dist, prod, span);
- for (i=0; i < n; indx[i++]=0);
- i = j = n-1;
- do {
- ptr = array_seek(ptr, -1, dist[j]);
- inc = INTALIGN(* (int32 *) ptr);
- ptr += inc; count += inc;
- } while ((j = next_tuple(i+1, indx, span)) != -1);
- return count;
+ int n,
+ *dim,
+ *lb,
+ st_pos,
+ prod[MAXDIM];
+ int span[MAXDIM],
+ dist[MAXDIM],
+ indx[MAXDIM];
+ int i,
+ j,
+ inc,
+ st[MAXDIM],
+ endp[MAXDIM];
+ int count = 0;
+ char *ptr;
+
+ n = ARR_NDIM(array);
+ dim = ARR_DIMS(array);
+ lb = ARR_LBOUND(array);
+ ptr = ARR_DATA_PTR(array);
+ for (i = 0; i < n; st[i] = stI[i] - lb[i], endp[i] = endpI[i] - lb[i], i++);
+ mda_get_prod(n, dim, prod);
+ st_pos = tuple2linear(n, st, prod);
+ ptr = array_seek(ptr, -1, st_pos);
+ mda_get_range(n, span, st, endp);
+ mda_get_offset_values(n, dist, prod, span);
+ for (i = 0; i < n; indx[i++] = 0);
+ i = j = n - 1;
+ do
+ {
+ ptr = array_seek(ptr, -1, dist[j]);
+ inc = INTALIGN(*(int32 *) ptr);
+ ptr += inc;
+ count += inc;
+ } while ((j = next_tuple(i + 1, indx, span)) != -1);
+ return count;
}
-static char *
+static char *
array_seek(char *ptr, int eltsize, int nitems)
{
- int i;
-
- if (eltsize > 0)
- return(ptr + eltsize*nitems);
- for (i = 0; i < nitems; i++)
- ptr += INTALIGN(* (int32 *) ptr);
- return(ptr);
+ int i;
+
+ if (eltsize > 0)
+ return (ptr + eltsize * nitems);
+ for (i = 0; i < nitems; i++)
+ ptr += INTALIGN(*(int32 *) ptr);
+ return (ptr);
}
static int
array_read(char *destptr, int eltsize, int nitems, char *srcptr)
{
- int i, inc, tmp;
-
- if (eltsize > 0) {
- memmove(destptr, srcptr, eltsize*nitems);
- return(eltsize*nitems);
- }
- for (i = inc = 0; i < nitems; i++) {
- tmp = (INTALIGN(* (int32 *) srcptr));
- memmove(destptr, srcptr, tmp);
- srcptr += tmp;
- destptr += tmp;
- inc += tmp;
- }
- return(inc);
+ int i,
+ inc,
+ tmp;
+
+ if (eltsize > 0)
+ {
+ memmove(destptr, srcptr, eltsize * nitems);
+ return (eltsize * nitems);
+ }
+ for (i = inc = 0; i < nitems; i++)
+ {
+ tmp = (INTALIGN(*(int32 *) srcptr));
+ memmove(destptr, srcptr, tmp);
+ srcptr += tmp;
+ destptr += tmp;
+ inc += tmp;
+ }
+ return (inc);
}
static void
_LOArrayRange(int st[],
- int endp[],
- int bsize,
- int srcfd,
- int destfd,
- ArrayType *array,
- int isSrcLO,
- bool *isNull)
+ int endp[],
+ int bsize,
+ int srcfd,
+ int destfd,
+ ArrayType * array,
+ int isSrcLO,
+ bool * isNull)
{
- int n, *dim, st_pos, prod[MAXDIM];
- int span[MAXDIM], dist[MAXDIM], indx[MAXDIM];
- int i, j, inc, tmp, *lb, offset;
-
- n = ARR_NDIM(array); dim = ARR_DIMS(array);
- lb = ARR_LBOUND(array);
- for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++);
-
- mda_get_prod(n, dim, prod);
- st_pos = tuple2linear(n, st, prod);
- offset = st_pos*bsize;
- if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
- return;
- mda_get_range(n, span, st, endp);
- mda_get_offset_values(n, dist, prod, span);
- for (i=0; i < n; indx[i++]=0);
- for (i = n-1, inc = bsize; i >= 0; inc *= span[i--])
- if (dist[i])
- break;
- j = n-1;
- do {
- offset += (dist[j]*bsize);
- if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
- return;
- tmp = _LOtransfer((char**)&srcfd, inc, 1, (char**)&destfd, isSrcLO, 1);
- if ( tmp < inc )
- return;
- offset += inc;
- } while ((j = next_tuple(i+1, indx, span)) != -1);
+ int n,
+ *dim,
+ st_pos,
+ prod[MAXDIM];
+ int span[MAXDIM],
+ dist[MAXDIM],
+ indx[MAXDIM];
+ int i,
+ j,
+ inc,
+ tmp,
+ *lb,
+ offset;
+
+ n = ARR_NDIM(array);
+ dim = ARR_DIMS(array);
+ lb = ARR_LBOUND(array);
+ for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++);
+
+ mda_get_prod(n, dim, prod);
+ st_pos = tuple2linear(n, st, prod);
+ offset = st_pos * bsize;
+ if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
+ return;
+ mda_get_range(n, span, st, endp);
+ mda_get_offset_values(n, dist, prod, span);
+ for (i = 0; i < n; indx[i++] = 0);
+ for (i = n - 1, inc = bsize; i >= 0; inc *= span[i--])
+ if (dist[i])
+ break;
+ j = n - 1;
+ do
+ {
+ offset += (dist[j] * bsize);
+ if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
+ return;
+ tmp = _LOtransfer((char **) &srcfd, inc, 1, (char **) &destfd, isSrcLO, 1);
+ if (tmp < inc)
+ return;
+ offset += inc;
+ } while ((j = next_tuple(i + 1, indx, span)) != -1);
}
static void
-_ReadArray (int st[],
- int endp[],
- int bsize,
- int srcfd,
- int destfd,
- ArrayType *array,
- int isDestLO,
- bool *isNull)
+_ReadArray(int st[],
+ int endp[],
+ int bsize,
+ int srcfd,
+ int destfd,
+ ArrayType * array,
+ int isDestLO,
+ bool * isNull)
{
- int n, *dim, st_pos, prod[MAXDIM];
- int span[MAXDIM], dist[MAXDIM], indx[MAXDIM];
- int i, j, inc, tmp, *lb, offset;
-
- n = ARR_NDIM(array); dim = ARR_DIMS(array);
- lb = ARR_LBOUND(array);
- for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++);
-
- mda_get_prod(n, dim, prod);
- st_pos = tuple2linear(n, st, prod);
- offset = st_pos*bsize;
- if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
- return;
- mda_get_range(n, span, st, endp);
- mda_get_offset_values(n, dist, prod, span);
- for (i=0; i < n; indx[i++]=0);
- for (i = n-1, inc = bsize; i >= 0; inc *= span[i--])
- if (dist[i])
- break;
- j = n-1;
- do {
- offset += (dist[j]*bsize);
- if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
- return;
- tmp = _LOtransfer((char**)&destfd, inc, 1, (char**)&srcfd, 1, isDestLO);
- if ( tmp < inc )
- return;
- offset += inc;
- } while ((j = next_tuple(i+1, indx, span)) != -1);
+ int n,
+ *dim,
+ st_pos,
+ prod[MAXDIM];
+ int span[MAXDIM],
+ dist[MAXDIM],
+ indx[MAXDIM];
+ int i,
+ j,
+ inc,
+ tmp,
+ *lb,
+ offset;
+
+ n = ARR_NDIM(array);
+ dim = ARR_DIMS(array);
+ lb = ARR_LBOUND(array);
+ for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++);
+
+ mda_get_prod(n, dim, prod);
+ st_pos = tuple2linear(n, st, prod);
+ offset = st_pos * bsize;
+ if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
+ return;
+ mda_get_range(n, span, st, endp);
+ mda_get_offset_values(n, dist, prod, span);
+ for (i = 0; i < n; indx[i++] = 0);
+ for (i = n - 1, inc = bsize; i >= 0; inc *= span[i--])
+ if (dist[i])
+ break;
+ j = n - 1;
+ do
+ {
+ offset += (dist[j] * bsize);
+ if (lo_lseek(srcfd, offset, SEEK_SET) < 0)
+ return;
+ tmp = _LOtransfer((char **) &destfd, inc, 1, (char **) &srcfd, 1, isDestLO);
+ if (tmp < inc)
+ return;
+ offset += inc;
+ } while ((j = next_tuple(i + 1, indx, span)) != -1);
}
int
_LOtransfer(char **destfd,
- int size,
- int nitems,
- char **srcfd,
- int isSrcLO,
- int isDestLO)
+ int size,
+ int nitems,
+ char **srcfd,
+ int isSrcLO,
+ int isDestLO)
{
#define MAX_READ (512 * 1024)
#define min(a, b) (a < b ? a : b)
- struct varlena *v = NULL;
- int tmp, inc, resid;
-
- inc = nitems*size;
- if (isSrcLO && isDestLO && inc > 0)
- for (tmp = 0, resid = inc;
- resid > 0 && (inc = min(resid, MAX_READ)) > 0; resid -= inc) {
+ struct varlena *v = NULL;
+ int tmp,
+ inc,
+ resid;
+
+ inc = nitems * size;
+ if (isSrcLO && isDestLO && inc > 0)
+ for (tmp = 0, resid = inc;
+ resid > 0 && (inc = min(resid, MAX_READ)) > 0; resid -= inc)
+ {
#ifdef LOARRAY
- v = (struct varlena *) LOread((int) *srcfd, inc);
- if (VARSIZE(v) - 4 < inc)
- {pfree(v); return(-1);}
- tmp += LOwrite((int) *destfd, v);
+ v = (struct varlena *) LOread((int) *srcfd, inc);
+ if (VARSIZE(v) - 4 < inc)
+ {
+ pfree(v);
+ return (-1);
+ }
+ tmp += LOwrite((int) *destfd, v);
#endif
- pfree(v);
-
- }
- else if (!isSrcLO && isDestLO) {
- tmp = lo_write((int) *destfd, *srcfd, inc);
- *srcfd = *srcfd + tmp;
- }
- else if (isSrcLO && !isDestLO) {
- tmp = lo_read((int) *srcfd, *destfd, inc);
- *destfd = *destfd + tmp;
- }
- else {
- memmove(*destfd, *srcfd, inc);
- tmp = inc;
- *srcfd += inc;
- *destfd += inc;
- }
- return(tmp);
+ pfree(v);
+
+ }
+ else if (!isSrcLO && isDestLO)
+ {
+ tmp = lo_write((int) *destfd, *srcfd, inc);
+ *srcfd = *srcfd + tmp;
+ }
+ else if (isSrcLO && !isDestLO)
+ {
+ tmp = lo_read((int) *srcfd, *destfd, inc);
+ *destfd = *destfd + tmp;
+ }
+ else
+ {
+ memmove(*destfd, *srcfd, inc);
+ tmp = inc;
+ *srcfd += inc;
+ *destfd += inc;
+ }
+ return (tmp);
#undef MAX_READ
}
-char *
+char *
_array_newLO(int *fd, int flag)
{
- char *p;
- char saveName[NAME_LEN];
-
- p = (char *) palloc(NAME_LEN);
- sprintf(p, "/Arry.%d", newoid());
- strcpy (saveName, p);
+ char *p;
+ char saveName[NAME_LEN];
+
+ p = (char *) palloc(NAME_LEN);
+ sprintf(p, "/Arry.%d", newoid());
+ strcpy(saveName, p);
#ifdef LOARRAY
- if ( (*fd = LOcreat (saveName, 0600, flag)) < 0)
- elog(WARN, "Large object create failed");
+ if ((*fd = LOcreat(saveName, 0600, flag)) < 0)
+ elog(WARN, "Large object create failed");
#endif
- return (p);
+ return (p);
}
-
diff --git a/src/backend/utils/adt/arrayutils.c b/src/backend/utils/adt/arrayutils.c
index fce0b0ddd57..09a58d46e2c 100644
--- a/src/backend/utils/adt/arrayutils.c
+++ b/src/backend/utils/adt/arrayutils.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* arrayutils.c--
- * This file contains some support routines required for array functions.
+ * This file contains some support routines required for array functions.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayutils.c,v 1.3 1996/11/10 03:03:03 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayutils.c,v 1.4 1997/09/07 04:49:57 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,94 +20,109 @@
int
GetOffset(int n, int dim[], int lb[], int indx[])
-{
- int i, scale, offset;
- for (i = n-1, scale = 1, offset = 0; i >= 0; scale*=dim[i--])
- offset += (indx[i] - lb[i])*scale;
- return offset ;
+{
+ int i,
+ scale,
+ offset;
+
+ for (i = n - 1, scale = 1, offset = 0; i >= 0; scale *= dim[i--])
+ offset += (indx[i] - lb[i]) * scale;
+ return offset;
}
int
getNitems(int n, int a[])
-{
- int i, ret;
- for (i = 0, ret = 1; i < n; ret *= a[i++]);
- if (n == 0) ret = 0;
- return ret;
+{
+ int i,
+ ret;
+
+ for (i = 0, ret = 1; i < n; ret *= a[i++]);
+ if (n == 0)
+ ret = 0;
+ return ret;
}
int
compute_size(int st[], int endp[], int n, int base)
{
- int i, ret;
- for (i = 0, ret = base; i < n; i++)
- ret *= (endp[i] - st[i] + 1);
- return ret;
+ int i,
+ ret;
+
+ for (i = 0, ret = base; i < n; i++)
+ ret *= (endp[i] - st[i] + 1);
+ return ret;
}
void
mda_get_offset_values(int n, int dist[], int PC[], int span[])
-{
- int i, j;
- for (j = n-2, dist[n-1]=0; j >= 0; j--)
- for (i = j+1, dist[j] = PC[j]-1; i < n;
- dist[j] -= (span[i] - 1)*PC[i], i++);
-}
+{
+ int i,
+ j;
+
+ for (j = n - 2, dist[n - 1] = 0; j >= 0; j--)
+ for (i = j + 1, dist[j] = PC[j] - 1; i < n;
+ dist[j] -= (span[i] - 1) * PC[i], i++);
+}
void
mda_get_range(int n, int span[], int st[], int endp[])
-{
- int i;
- for (i= 0; i < n; i++)
- span[i] = endp[i] - st[i] + 1;
-}
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ span[i] = endp[i] - st[i] + 1;
+}
void
mda_get_prod(int n, int range[], int P[])
-{
- int i;
- for (i= n-2, P[n-1] = 1; i >= 0; i--)
- P[i] = P[i+1] * range[i + 1];
-}
+{
+ int i;
+
+ for (i = n - 2, P[n - 1] = 1; i >= 0; i--)
+ P[i] = P[i + 1] * range[i + 1];
+}
int
tuple2linear(int n, int tup[], int scale[])
{
- int i, lin;
- for (i= lin = 0; i < n; i++)
- lin += tup[i]*scale[i];
- return lin;
-}
+ int i,
+ lin;
+
+ for (i = lin = 0; i < n; i++)
+ lin += tup[i] * scale[i];
+ return lin;
+}
void
array2chunk_coord(int n, int C[], int a_coord[], int c_coord[])
{
- int i;
- for (i= 0; i < n; i++)
- c_coord[i] = a_coord[i]/C[i];
+ int i;
+
+ for (i = 0; i < n; i++)
+ c_coord[i] = a_coord[i] / C[i];
}
/*-----------------------------------------------------------------------------
generates the tuple that is lexicographically one greater than the current
n-tuple in "curr", with the restriction that the i-th element of "curr" is
less than the i-th element of "span".
- RETURNS 0 if no next tuple exists
+ RETURNS 0 if no next tuple exists
1 otherwise
-----------------------------------------------------------------------------*/
int
next_tuple(int n, int curr[], int span[])
{
- int i;
-
- if (!n) return(-1);
- curr[n-1] = (curr[n-1]+1)%span[n-1];
- for (i = n-1; i*(!curr[i]); i--)
- curr[i-1] = (curr[i-1]+1)%span[i-1];
-
- if (i)
- return(i);
- if (curr[0])
- return(0);
- return(-1);
-}
+ int i;
+ if (!n)
+ return (-1);
+ curr[n - 1] = (curr[n - 1] + 1) % span[n - 1];
+ for (i = n - 1; i * (!curr[i]); i--)
+ curr[i - 1] = (curr[i - 1] + 1) % span[i - 1];
+
+ if (i)
+ return (i);
+ if (curr[0])
+ return (0);
+ return (-1);
+}
diff --git a/src/backend/utils/adt/bool.c b/src/backend/utils/adt/bool.c
index cb9163f020f..d02661efa67 100644
--- a/src/backend/utils/adt/bool.c
+++ b/src/backend/utils/adt/bool.c
@@ -1,74 +1,74 @@
/*-------------------------------------------------------------------------
*
* bool.c--
- * Functions for the built-in type "bool".
+ * Functions for the built-in type "bool".
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/bool.c,v 1.4 1997/04/27 19:20:07 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/bool.c,v 1.5 1997/09/07 04:49:58 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include "utils/builtins.h" /* where the declarations go */
+#include "utils/builtins.h" /* where the declarations go */
#include "utils/palloc.h"
-/*****************************************************************************
- * USER I/O ROUTINES *
+/*****************************************************************************
+ * USER I/O ROUTINES *
*****************************************************************************/
/*
- * boolin - converts "t" or "f" to 1 or 0
+ * boolin - converts "t" or "f" to 1 or 0
*/
bool
boolin(char *b)
{
- if (b == NULL)
- elog(WARN, "Bad input string for type bool");
- return((bool) (*b == 't') || (*b == 'T'));
+ if (b == NULL)
+ elog(WARN, "Bad input string for type bool");
+ return ((bool) (*b == 't') || (*b == 'T'));
}
/*
- * boolout - converts 1 or 0 to "t" or "f"
+ * boolout - converts 1 or 0 to "t" or "f"
*/
-char *
+char *
boolout(long b)
{
- char *result = (char *) palloc(2);
-
- *result = (b) ? 't' : 'f';
- result[1] = '\0';
- return(result);
+ char *result = (char *) palloc(2);
+
+ *result = (b) ? 't' : 'f';
+ result[1] = '\0';
+ return (result);
}
-/*****************************************************************************
- * PUBLIC ROUTINES *
+/*****************************************************************************
+ * PUBLIC ROUTINES *
*****************************************************************************/
bool
-booleq(int8 arg1, int8 arg2)
-{
- return(arg1 == arg2);
+booleq(int8 arg1, int8 arg2)
+{
+ return (arg1 == arg2);
}
bool
-boolne(int8 arg1, int8 arg2)
+boolne(int8 arg1, int8 arg2)
{
- return(arg1 != arg2);
+ return (arg1 != arg2);
}
bool
-boollt(int8 arg1, int8 arg2)
-{
- return(arg1 < arg2);
+boollt(int8 arg1, int8 arg2)
+{
+ return (arg1 < arg2);
}
bool
-boolgt(int8 arg1, int8 arg2)
-{
- return(arg1 > arg2);
+boolgt(int8 arg1, int8 arg2)
+{
+ return (arg1 > arg2);
}
diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c
index 1cadb742e62..763ac5856ce 100644
--- a/src/backend/utils/adt/cash.c
+++ b/src/backend/utils/adt/cash.c
@@ -8,8 +8,8 @@
* A slightly modified version of this file and a discussion of the
* workings can be found in the book "Software Solutions in C" by
* Dale Schumacher, Academic Press, ISBN: 0-12-632360-7.
- *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.9 1997/08/22 07:12:52 momjian Exp $
+ *
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.10 1997/09/07 04:49:59 momjian Exp $
*/
#include <stdio.h>
@@ -26,332 +26,363 @@
static const char *num_word(Cash value);
/* when we go to 64 bit values we will have to modify this */
-#define CASH_BUFSZ 24
+#define CASH_BUFSZ 24
-#define TERMINATOR (CASH_BUFSZ - 1)
-#define LAST_PAREN (TERMINATOR - 1)
-#define LAST_DIGIT (LAST_PAREN - 1)
+#define TERMINATOR (CASH_BUFSZ - 1)
+#define LAST_PAREN (TERMINATOR - 1)
+#define LAST_DIGIT (LAST_PAREN - 1)
#ifdef USE_LOCALE
static struct lconv *lconv = NULL;
+
#endif
/* cash_in()
* Convert a string to a cash data type.
* Format is [$]###[,]###[.##]
* Examples: 123.45 $123.45 $123,456.78
- *
+ *
* This is currently implemented as a 32-bit integer.
* XXX HACK It looks as though some of the symbols for
- * monetary values returned by localeconv() can be multiple
- * bytes/characters. This code assumes one byte only. - tgl 97/04/14
+ * monetary values returned by localeconv() can be multiple
+ * bytes/characters. This code assumes one byte only. - tgl 97/04/14
*/
-Cash *
+Cash *
cash_in(const char *str)
{
- Cash *result;
-
- Cash value = 0;
- Cash dec = 0;
- Cash sgn = 1;
- int seen_dot = 0;
- const char *s = str;
- int fpoint;
- char dsymbol, ssymbol, psymbol, nsymbol, csymbol;
+ Cash *result;
+
+ Cash value = 0;
+ Cash dec = 0;
+ Cash sgn = 1;
+ int seen_dot = 0;
+ const char *s = str;
+ int fpoint;
+ char dsymbol,
+ ssymbol,
+ psymbol,
+ nsymbol,
+ csymbol;
#ifdef USE_LOCALE
- if (lconv == NULL) lconv = localeconv();
-
- /* frac_digits in the C locale seems to return CHAR_MAX */
- /* best guess is 2 in this case I think */
- fpoint = ((lconv->frac_digits != CHAR_MAX)? lconv->frac_digits: 2); /* int_frac_digits? */
-
- dsymbol = *lconv->mon_decimal_point;
- ssymbol = *lconv->mon_thousands_sep;
- csymbol = *lconv->currency_symbol;
- psymbol = *lconv->positive_sign;
- nsymbol = *lconv->negative_sign;
+ if (lconv == NULL)
+ lconv = localeconv();
+
+ /* frac_digits in the C locale seems to return CHAR_MAX */
+ /* best guess is 2 in this case I think */
+ fpoint = ((lconv->frac_digits != CHAR_MAX) ? lconv->frac_digits : 2); /* int_frac_digits? */
+
+ dsymbol = *lconv->mon_decimal_point;
+ ssymbol = *lconv->mon_thousands_sep;
+ csymbol = *lconv->currency_symbol;
+ psymbol = *lconv->positive_sign;
+ nsymbol = *lconv->negative_sign;
#else
- fpoint = 2;
- dsymbol = '.';
- ssymbol = ',';
- csymbol = '$';
- psymbol = '+';
- nsymbol = '-';
+ fpoint = 2;
+ dsymbol = '.';
+ ssymbol = ',';
+ csymbol = '$';
+ psymbol = '+';
+ nsymbol = '-';
#endif
- /* we need to add all sorts of checking here. For now just */
- /* strip all leading whitespace and any leading dollar sign */
- while (isspace(*s) || *s == csymbol) s++;
-
- /* a leading minus or paren signifies a negative number */
- /* again, better heuristics needed */
- if (*s == nsymbol || *s == '(') {
- sgn = -1;
- s++;
-
- } else if (*s == psymbol) {
- s++;
- }
-
- while (isspace(*s) || *s == csymbol) s++;
-
- for (; ; s++) {
- /* we look for digits as int4 as we have less */
- /* than the required number of decimal places */
- if (isdigit(*s) && dec < fpoint) {
- value = (value * 10) + *s - '0';
-
- if (seen_dot)
- dec++;
-
- /* decimal point? then start counting fractions... */
- } else if (*s == dsymbol && !seen_dot) {
- seen_dot = 1;
+ /* we need to add all sorts of checking here. For now just */
+ /* strip all leading whitespace and any leading dollar sign */
+ while (isspace(*s) || *s == csymbol)
+ s++;
- /* "thousands" separator? then skip... */
- } else if (*s == ssymbol) {
+ /* a leading minus or paren signifies a negative number */
+ /* again, better heuristics needed */
+ if (*s == nsymbol || *s == '(')
+ {
+ sgn = -1;
+ s++;
- } else {
- /* round off */
- if (isdigit(*s) && *s >= '5')
- value++;
-
- /* adjust for less than required decimal places */
- for (; dec < fpoint; dec++)
- value *= 10;
+ }
+ else if (*s == psymbol)
+ {
+ s++;
+ }
- break;
+ while (isspace(*s) || *s == csymbol)
+ s++;
+
+ for (;; s++)
+ {
+ /* we look for digits as int4 as we have less */
+ /* than the required number of decimal places */
+ if (isdigit(*s) && dec < fpoint)
+ {
+ value = (value * 10) + *s - '0';
+
+ if (seen_dot)
+ dec++;
+
+ /* decimal point? then start counting fractions... */
+ }
+ else if (*s == dsymbol && !seen_dot)
+ {
+ seen_dot = 1;
+
+ /* "thousands" separator? then skip... */
+ }
+ else if (*s == ssymbol)
+ {
+
+ }
+ else
+ {
+ /* round off */
+ if (isdigit(*s) && *s >= '5')
+ value++;
+
+ /* adjust for less than required decimal places */
+ for (; dec < fpoint; dec++)
+ value *= 10;
+
+ break;
+ }
}
- }
- while (isspace(*s) || *s == '0' || *s == ')') s++;
+ while (isspace(*s) || *s == '0' || *s == ')')
+ s++;
- if (*s != '\0')
- elog(WARN,"Bad money external representation %s",str);
+ if (*s != '\0')
+ elog(WARN, "Bad money external representation %s", str);
- if (!PointerIsValid(result = PALLOCTYPE(Cash)))
- elog(WARN,"Memory allocation failed, can't input cash '%s'",str);
+ if (!PointerIsValid(result = PALLOCTYPE(Cash)))
+ elog(WARN, "Memory allocation failed, can't input cash '%s'", str);
- *result = (value * sgn);
+ *result = (value * sgn);
- return(result);
-} /* cash_in() */
+ return (result);
+} /* cash_in() */
/* cash_out()
* Function to convert cash to a dollars and cents representation.
* XXX HACK This code appears to assume US conventions for
- * positive-valued amounts. - tgl 97/04/14
+ * positive-valued amounts. - tgl 97/04/14
*/
-const char *
-cash_out(Cash *value)
+const char *
+cash_out(Cash * value)
{
- char *result;
- char buf[CASH_BUFSZ];
- int minus = 0;
- int count = LAST_DIGIT;
- int point_pos;
- int comma_position = 0;
- char mon_group, comma, points;
- char csymbol, dsymbol, *nsymbol;
- char convention;
+ char *result;
+ char buf[CASH_BUFSZ];
+ int minus = 0;
+ int count = LAST_DIGIT;
+ int point_pos;
+ int comma_position = 0;
+ char mon_group,
+ comma,
+ points;
+ char csymbol,
+ dsymbol,
+ *nsymbol;
+ char convention;
#ifdef USE_LOCALE
- if (lconv == NULL) lconv = localeconv();
-
- mon_group = *lconv->mon_grouping;
- comma = *lconv->mon_thousands_sep;
- csymbol = *lconv->currency_symbol;
- dsymbol = *lconv->mon_decimal_point;
- nsymbol = lconv->negative_sign;
- /* frac_digits in the C locale seems to return CHAR_MAX */
- /* best guess is 2 in this case I think */
- points = ((lconv->frac_digits != CHAR_MAX)? lconv->frac_digits: 2); /* int_frac_digits? */
- convention = lconv->n_sign_posn;
+ if (lconv == NULL)
+ lconv = localeconv();
+
+ mon_group = *lconv->mon_grouping;
+ comma = *lconv->mon_thousands_sep;
+ csymbol = *lconv->currency_symbol;
+ dsymbol = *lconv->mon_decimal_point;
+ nsymbol = lconv->negative_sign;
+ /* frac_digits in the C locale seems to return CHAR_MAX */
+ /* best guess is 2 in this case I think */
+ points = ((lconv->frac_digits != CHAR_MAX) ? lconv->frac_digits : 2); /* int_frac_digits? */
+ convention = lconv->n_sign_posn;
#else
- mon_group = 3;
- comma = ',';
- csymbol = '$';
- dsymbol = '.';
- nsymbol = "-";
- points = 2;
- convention = 0;
+ mon_group = 3;
+ comma = ',';
+ csymbol = '$';
+ dsymbol = '.';
+ nsymbol = "-";
+ points = 2;
+ convention = 0;
#endif
- point_pos = LAST_DIGIT - points;
+ point_pos = LAST_DIGIT - points;
- /* We're playing a little fast and loose with this. Shoot me. */
- if (!mon_group || mon_group == CHAR_MAX)
- mon_group = 3;
+ /* We're playing a little fast and loose with this. Shoot me. */
+ if (!mon_group || mon_group == CHAR_MAX)
+ mon_group = 3;
+
+ /* allow more than three decimal points and separate them */
+ if (comma)
+ {
+ point_pos -= (points - 1) / mon_group;
+ comma_position = point_pos % (mon_group + 1);
+ }
+
+ /* we work with positive amounts and add the minus sign at the end */
+ if (*value < 0)
+ {
+ minus = 1;
+ *value *= -1;
+ }
- /* allow more than three decimal points and separate them */
- if (comma) {
- point_pos -= (points - 1)/mon_group;
- comma_position = point_pos % (mon_group + 1);
- }
-
- /* we work with positive amounts and add the minus sign at the end */
- if (*value < 0) {
- minus = 1;
- *value *= -1;
- }
-
- /* allow for trailing negative strings */
- memset(buf, ' ', CASH_BUFSZ);
- buf[TERMINATOR] = buf[LAST_PAREN] = '\0';
-
- while (*value || count > (point_pos - 2)) {
- if (points && count == point_pos)
- buf[count--] = dsymbol;
- else if (comma && count % (mon_group + 1) == comma_position)
- buf[count--] = comma;
-
- buf[count--] = (*value % 10) + '0';
- *value /= 10;
- }
-
- buf[count] = csymbol;
-
- if (buf[LAST_DIGIT] == ',')
- buf[LAST_DIGIT] = buf[LAST_PAREN];
-
- /* see if we need to signify negative amount */
- if (minus) {
- if (!PointerIsValid(result = PALLOC(CASH_BUFSZ + 2 - count + strlen(nsymbol))))
- elog(WARN,"Memory allocation failed, can't output cash",NULL);
-
- /* Position code of 0 means use parens */
- if (convention == 0)
- sprintf(result, "(%s)", buf + count);
- else if (convention == 2)
- sprintf(result, "%s%s", buf + count, nsymbol);
+ /* allow for trailing negative strings */
+ memset(buf, ' ', CASH_BUFSZ);
+ buf[TERMINATOR] = buf[LAST_PAREN] = '\0';
+
+ while (*value || count > (point_pos - 2))
+ {
+ if (points && count == point_pos)
+ buf[count--] = dsymbol;
+ else if (comma && count % (mon_group + 1) == comma_position)
+ buf[count--] = comma;
+
+ buf[count--] = (*value % 10) + '0';
+ *value /= 10;
+ }
+
+ buf[count] = csymbol;
+
+ if (buf[LAST_DIGIT] == ',')
+ buf[LAST_DIGIT] = buf[LAST_PAREN];
+
+ /* see if we need to signify negative amount */
+ if (minus)
+ {
+ if (!PointerIsValid(result = PALLOC(CASH_BUFSZ + 2 - count + strlen(nsymbol))))
+ elog(WARN, "Memory allocation failed, can't output cash", NULL);
+
+ /* Position code of 0 means use parens */
+ if (convention == 0)
+ sprintf(result, "(%s)", buf + count);
+ else if (convention == 2)
+ sprintf(result, "%s%s", buf + count, nsymbol);
+ else
+ sprintf(result, "%s%s", nsymbol, buf + count);
+ }
else
- sprintf(result, "%s%s", nsymbol, buf + count);
- } else {
- if (!PointerIsValid(result = PALLOC(CASH_BUFSZ + 2 - count)))
- elog(WARN,"Memory allocation failed, can't output cash",NULL);
+ {
+ if (!PointerIsValid(result = PALLOC(CASH_BUFSZ + 2 - count)))
+ elog(WARN, "Memory allocation failed, can't output cash", NULL);
- strcpy(result, buf + count);
- }
+ strcpy(result, buf + count);
+ }
- return(result);
-} /* cash_out() */
+ return (result);
+} /* cash_out() */
bool
-cash_eq(Cash *c1, Cash *c2)
+cash_eq(Cash * c1, Cash * c2)
{
- if (!PointerIsValid(c1) || !PointerIsValid(c2))
- return(FALSE);
+ if (!PointerIsValid(c1) || !PointerIsValid(c2))
+ return (FALSE);
- return(*c1 == *c2);
-} /* cash_eq() */
+ return (*c1 == *c2);
+} /* cash_eq() */
bool
-cash_ne(Cash *c1, Cash *c2)
+cash_ne(Cash * c1, Cash * c2)
{
- if (!PointerIsValid(c1) || !PointerIsValid(c2))
- return(FALSE);
+ if (!PointerIsValid(c1) || !PointerIsValid(c2))
+ return (FALSE);
- return(*c1 != *c2);
-} /* cash_ne() */
+ return (*c1 != *c2);
+} /* cash_ne() */
bool
-cash_lt(Cash *c1, Cash *c2)
+cash_lt(Cash * c1, Cash * c2)
{
- if (!PointerIsValid(c1) || !PointerIsValid(c2))
- return(FALSE);
+ if (!PointerIsValid(c1) || !PointerIsValid(c2))
+ return (FALSE);
- return(*c1 < *c2);
-} /* cash_lt() */
+ return (*c1 < *c2);
+} /* cash_lt() */
bool
-cash_le(Cash *c1, Cash *c2)
+cash_le(Cash * c1, Cash * c2)
{
- if (!PointerIsValid(c1) || !PointerIsValid(c2))
- return(FALSE);
+ if (!PointerIsValid(c1) || !PointerIsValid(c2))
+ return (FALSE);
- return(*c1 <= *c2);
-} /* cash_le() */
+ return (*c1 <= *c2);
+} /* cash_le() */
bool
-cash_gt(Cash *c1, Cash *c2)
+cash_gt(Cash * c1, Cash * c2)
{
- if (!PointerIsValid(c1) || !PointerIsValid(c2))
- return(FALSE);
+ if (!PointerIsValid(c1) || !PointerIsValid(c2))
+ return (FALSE);
- return(*c1 > *c2);
-} /* cash_gt() */
+ return (*c1 > *c2);
+} /* cash_gt() */
bool
-cash_ge(Cash *c1, Cash *c2)
+cash_ge(Cash * c1, Cash * c2)
{
- if (!PointerIsValid(c1) || !PointerIsValid(c2))
- return(FALSE);
+ if (!PointerIsValid(c1) || !PointerIsValid(c2))
+ return (FALSE);
- return(*c1 >= *c2);
-} /* cash_ge() */
+ return (*c1 >= *c2);
+} /* cash_ge() */
/* cash_pl()
* Add two cash values.
*/
-Cash *
-cash_pl(Cash *c1, Cash *c2)
+Cash *
+cash_pl(Cash * c1, Cash * c2)
{
- Cash *result;
+ Cash *result;
- if (!PointerIsValid(c1) || !PointerIsValid(c2))
- return(NULL);
+ if (!PointerIsValid(c1) || !PointerIsValid(c2))
+ return (NULL);
- if (!PointerIsValid(result = PALLOCTYPE(Cash)))
- elog(WARN,"Memory allocation failed, can't add cash",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(Cash)))
+ elog(WARN, "Memory allocation failed, can't add cash", NULL);
- *result = (*c1 + *c2);
+ *result = (*c1 + *c2);
- return(result);
-} /* cash_pl() */
+ return (result);
+} /* cash_pl() */
/* cash_mi()
* Subtract two cash values.
*/
-Cash *
-cash_mi(Cash *c1, Cash *c2)
+Cash *
+cash_mi(Cash * c1, Cash * c2)
{
- Cash *result;
+ Cash *result;
- if (!PointerIsValid(c1) || !PointerIsValid(c2))
- return(NULL);
+ if (!PointerIsValid(c1) || !PointerIsValid(c2))
+ return (NULL);
- if (!PointerIsValid(result = PALLOCTYPE(Cash)))
- elog(WARN,"Memory allocation failed, can't subtract cash",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(Cash)))
+ elog(WARN, "Memory allocation failed, can't subtract cash", NULL);
- *result = (*c1 - *c2);
+ *result = (*c1 - *c2);
- return(result);
-} /* cash_mi() */
+ return (result);
+} /* cash_mi() */
/* cash_mul()
* Multiply cash by floating point number.
*/
-Cash *
-cash_mul(Cash *c, float8 *f)
+Cash *
+cash_mul(Cash * c, float8 * f)
{
- Cash *result;
+ Cash *result;
- if (!PointerIsValid(f) || !PointerIsValid(c))
- return(NULL);
+ if (!PointerIsValid(f) || !PointerIsValid(c))
+ return (NULL);
- if (!PointerIsValid(result = PALLOCTYPE(Cash)))
- elog(WARN,"Memory allocation failed, can't multiply cash",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(Cash)))
+ elog(WARN, "Memory allocation failed, can't multiply cash", NULL);
- *result = ((*f) * (*c));
+ *result = ((*f) * (*c));
- return(result);
-} /* cash_mul() */
+ return (result);
+} /* cash_mul() */
/* cash_div()
@@ -360,116 +391,121 @@ cash_mul(Cash *c, float8 *f)
* XXX Don't know if rounding or truncating is correct behavior.
* Round for now. - tgl 97/04/15
*/
-Cash *
-cash_div(Cash *c, float8 *f)
+Cash *
+cash_div(Cash * c, float8 * f)
{
- Cash *result;
+ Cash *result;
- if (!PointerIsValid(f) || !PointerIsValid(c))
- return(NULL);
+ if (!PointerIsValid(f) || !PointerIsValid(c))
+ return (NULL);
- if (!PointerIsValid(result = PALLOCTYPE(Cash)))
- elog(WARN,"Memory allocation failed, can't divide cash",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(Cash)))
+ elog(WARN, "Memory allocation failed, can't divide cash", NULL);
- if (*f == 0.0)
- elog(WARN,"cash_div: divide by 0.0 error");
+ if (*f == 0.0)
+ elog(WARN, "cash_div: divide by 0.0 error");
- *result = rint(*c / *f);
+ *result = rint(*c / *f);
- return(result);
-} /* cash_div() */
+ return (result);
+} /* cash_div() */
/* cashlarger()
* Return larger of two cash values.
*/
-Cash *
-cashlarger(Cash *c1, Cash *c2)
+Cash *
+cashlarger(Cash * c1, Cash * c2)
{
- Cash *result;
+ Cash *result;
- if (!PointerIsValid(c1) || !PointerIsValid(c2))
- return(NULL);
+ if (!PointerIsValid(c1) || !PointerIsValid(c2))
+ return (NULL);
- if (!PointerIsValid(result = PALLOCTYPE(Cash)))
- elog(WARN,"Memory allocation failed, can't return larger cash",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(Cash)))
+ elog(WARN, "Memory allocation failed, can't return larger cash", NULL);
- *result = ((*c1 > *c2)? *c1: *c2);
+ *result = ((*c1 > *c2) ? *c1 : *c2);
- return(result);
-} /* cashlarger() */
+ return (result);
+} /* cashlarger() */
/* cashsmaller()
* Return smaller of two cash values.
*/
-Cash *
-cashsmaller(Cash *c1, Cash *c2)
+Cash *
+cashsmaller(Cash * c1, Cash * c2)
{
- Cash *result;
+ Cash *result;
- if (!PointerIsValid(c1) || !PointerIsValid(c2))
- return(NULL);
+ if (!PointerIsValid(c1) || !PointerIsValid(c2))
+ return (NULL);
- if (!PointerIsValid(result = PALLOCTYPE(Cash)))
- elog(WARN,"Memory allocation failed, can't return smaller cash",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(Cash)))
+ elog(WARN, "Memory allocation failed, can't return smaller cash", NULL);
- *result = ((*c1 < *c2)? *c1: *c2);
+ *result = ((*c1 < *c2) ? *c1 : *c2);
- return(result);
-} /* cashsmaller() */
+ return (result);
+} /* cashsmaller() */
/* cash_words_out()
* This converts a int4 as well but to a representation using words
* Obviously way North American centric - sorry
*/
-const char *
-cash_words_out(Cash *value)
+const char *
+cash_words_out(Cash * value)
{
- static char buf[128];
- char *p = buf;
- Cash m0;
- Cash m1;
- Cash m2;
- Cash m3;
-
- /* work with positive numbers */
- if (*value < 0) {
- *value *= -1;
- strcpy(buf, "minus ");
- p += 6;
- } else {
- *buf = 0;
- }
-
- m0 = *value % 100; /* cents */
- m1 = (*value/100) % 1000; /* hundreds */
- m2 = (*value/100000) % 1000; /* thousands */
- m3 = *value/100000000 % 1000; /* millions */
-
- if (m3) {
- strcat(buf, num_word(m3));
- strcat(buf, " million ");
- }
-
- if (m2) {
- strcat(buf, num_word(m2));
- strcat(buf, " thousand ");
- }
-
- if (m1)
- strcat(buf, num_word(m1));
-
- if (!*p)
- strcat(buf, "zero");
-
- strcat(buf, (int)(*value/100) == 1 ? " dollar and " : " dollars and ");
- strcat(buf, num_word(m0));
- strcat(buf, m0 == 1 ? " cent" : " cents");
- *buf = toupper(*buf);
- return(buf);
-} /* cash_words_out() */
+ static char buf[128];
+ char *p = buf;
+ Cash m0;
+ Cash m1;
+ Cash m2;
+ Cash m3;
+
+ /* work with positive numbers */
+ if (*value < 0)
+ {
+ *value *= -1;
+ strcpy(buf, "minus ");
+ p += 6;
+ }
+ else
+ {
+ *buf = 0;
+ }
+
+ m0 = *value % 100; /* cents */
+ m1 = (*value / 100) % 1000; /* hundreds */
+ m2 = (*value / 100000) % 1000; /* thousands */
+ m3 = *value / 100000000 % 1000; /* millions */
+
+ if (m3)
+ {
+ strcat(buf, num_word(m3));
+ strcat(buf, " million ");
+ }
+
+ if (m2)
+ {
+ strcat(buf, num_word(m2));
+ strcat(buf, " thousand ");
+ }
+
+ if (m1)
+ strcat(buf, num_word(m1));
+
+ if (!*p)
+ strcat(buf, "zero");
+
+ strcat(buf, (int) (*value / 100) == 1 ? " dollar and " : " dollars and ");
+ strcat(buf, num_word(m0));
+ strcat(buf, m0 == 1 ? " cent" : " cents");
+ *buf = toupper(*buf);
+ return (buf);
+} /* cash_words_out() */
/*************************************************************************
@@ -479,48 +515,52 @@ cash_words_out(Cash *value)
static const char *
num_word(Cash value)
{
- static char buf[128];
- static const char *small[] = {
- "zero", "one", "two", "three", "four", "five", "six", "seven",
- "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
- "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty",
- "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"
- };
- const char **big = small + 18;
- int tu = value % 100;
-
- /* deal with the simple cases first */
- if (value <= 20)
- return(small[value]);
-
- /* is it an even multiple of 100? */
- if (!tu) {
- sprintf(buf, "%s hundred", small[value/100]);
- return(buf);
- }
-
- /* more than 99? */
- if (value > 99) {
- /* is it an even multiple of 10 other than 10? */
- if (value % 10 == 0 && tu > 10)
- sprintf(buf, "%s hundred %s",
- small[value/100], big[tu/10]);
- else if (tu < 20)
- sprintf(buf, "%s hundred and %s",
- small[value/100], small[tu]);
- else
- sprintf(buf, "%s hundred %s %s",
- small[value/100], big[tu/10], small[tu % 10]);
-
- } else {
- /* is it an even multiple of 10 other than 10? */
- if (value % 10 == 0 && tu > 10)
- sprintf(buf, "%s", big[tu/10]);
- else if (tu < 20)
- sprintf(buf, "%s", small[tu]);
+ static char buf[128];
+ static const char *small[] = {
+ "zero", "one", "two", "three", "four", "five", "six", "seven",
+ "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
+ "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty",
+ "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"
+ };
+ const char **big = small + 18;
+ int tu = value % 100;
+
+ /* deal with the simple cases first */
+ if (value <= 20)
+ return (small[value]);
+
+ /* is it an even multiple of 100? */
+ if (!tu)
+ {
+ sprintf(buf, "%s hundred", small[value / 100]);
+ return (buf);
+ }
+
+ /* more than 99? */
+ if (value > 99)
+ {
+ /* is it an even multiple of 10 other than 10? */
+ if (value % 10 == 0 && tu > 10)
+ sprintf(buf, "%s hundred %s",
+ small[value / 100], big[tu / 10]);
+ else if (tu < 20)
+ sprintf(buf, "%s hundred and %s",
+ small[value / 100], small[tu]);
+ else
+ sprintf(buf, "%s hundred %s %s",
+ small[value / 100], big[tu / 10], small[tu % 10]);
+
+ }
else
- sprintf(buf, "%s %s", big[tu/10], small[tu % 10]);
- }
+ {
+ /* is it an even multiple of 10 other than 10? */
+ if (value % 10 == 0 && tu > 10)
+ sprintf(buf, "%s", big[tu / 10]);
+ else if (tu < 20)
+ sprintf(buf, "%s", small[tu]);
+ else
+ sprintf(buf, "%s %s", big[tu / 10], small[tu % 10]);
+ }
- return(buf);
-} /* num_word() */
+ return (buf);
+} /* num_word() */
diff --git a/src/backend/utils/adt/char.c b/src/backend/utils/adt/char.c
index afb87a4d8b3..24e30054b6b 100644
--- a/src/backend/utils/adt/char.c
+++ b/src/backend/utils/adt/char.c
@@ -1,384 +1,460 @@
/*-------------------------------------------------------------------------
*
* char.c--
- * Functions for the built-in type "char".
- * Functions for the built-in type "cid".
- * Functions for the built-in type "char2".
- * Functions for the built-in type "char4".
- * Functions for the built-in type "char8".
- * Functions for the built-in type "char16".
+ * Functions for the built-in type "char".
+ * Functions for the built-in type "cid".
+ * Functions for the built-in type "char2".
+ * Functions for the built-in type "char4".
+ * Functions for the built-in type "char8".
+ * Functions for the built-in type "char16".
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/char.c,v 1.7 1997/08/12 20:39:16 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/char.c,v 1.8 1997/09/07 04:50:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include "postgres.h"
#include "utils/palloc.h"
#include "utils/builtins.h" /* where the declarations go */
-/*****************************************************************************
- * USER I/O ROUTINES *
+/*****************************************************************************
+ * USER I/O ROUTINES *
*****************************************************************************/
/*
- * charin - converts "x" to 'x'
+ * charin - converts "x" to 'x'
*/
-int32 charin(char *ch)
+int32
+charin(char *ch)
{
- if (ch == NULL)
- return((int32) NULL);
- return((int32) *ch);
+ if (ch == NULL)
+ return ((int32) NULL);
+ return ((int32) * ch);
}
/*
- * charout - converts 'x' to "x"
+ * charout - converts 'x' to "x"
*/
-char *charout(int32 ch)
+char *
+charout(int32 ch)
{
- char *result = (char *) palloc(2);
-
- result[0] = (char) ch;
- result[1] = '\0';
- return(result);
+ char *result = (char *) palloc(2);
+
+ result[0] = (char) ch;
+ result[1] = '\0';
+ return (result);
}
/*
- * cidin - converts "..." to internal representation.
+ * cidin - converts "..." to internal representation.
*
- * NOTE: we must not use 'charin' because cid might be a non
- * printable character...
+ * NOTE: we must not use 'charin' because cid might be a non
+ * printable character...
*/
-int32 cidin(char *s)
+int32
+cidin(char *s)
{
- CommandId c;
-
- if (s==NULL)
- c = 0;
- else
- c = atoi(s);
-
- return((int32)c);
+ CommandId c;
+
+ if (s == NULL)
+ c = 0;
+ else
+ c = atoi(s);
+
+ return ((int32) c);
}
/*
- * cidout - converts a cid to "..."
+ * cidout - converts a cid to "..."
*
- * NOTE: we must no use 'charout' because cid might be a non
- * printable character...
+ * NOTE: we must no use 'charout' because cid might be a non
+ * printable character...
*/
-char *cidout(int32 c)
-{
- char *result;
- CommandId c2;
-
- /*
- * cid is a number between 0 .. 2^16-1, therefore we need at most
- * 6 chars for the string (5 digits + '\0')
- * NOTE: print it as an UNSIGNED int!
- */
- result = palloc(6);
- c2 = (CommandId)c;
- sprintf(result, "%u", (unsigned)(c2));
- return(result);
+char *
+cidout(int32 c)
+{
+ char *result;
+ CommandId c2;
+
+ /*
+ * cid is a number between 0 .. 2^16-1, therefore we need at most 6
+ * chars for the string (5 digits + '\0') NOTE: print it as an
+ * UNSIGNED int!
+ */
+ result = palloc(6);
+ c2 = (CommandId) c;
+ sprintf(result, "%u", (unsigned) (c2));
+ return (result);
}
/*
- * char16in - converts "..." to internal reprsentation
+ * char16in - converts "..." to internal reprsentation
*
- * Note:
- * Currently if strlen(s) < 14, the extra chars are nulls
+ * Note:
+ * Currently if strlen(s) < 14, the extra chars are nulls
*/
-char *char16in(char *s)
+char *
+char16in(char *s)
{
- char *result;
+ char *result;
- if (s == NULL)
- return(NULL);
- result = (char *) palloc(16);
- strncpy(result, s, 16);
- return(result);
+ if (s == NULL)
+ return (NULL);
+ result = (char *) palloc(16);
+ strncpy(result, s, 16);
+ return (result);
}
/*
- * char16out - converts internal reprsentation to "..."
+ * char16out - converts internal reprsentation to "..."
*/
-char *char16out(char *s)
+char *
+char16out(char *s)
{
- char *result = (char *) palloc(17);
-
- if (s == NULL) {
- result[0] = '-';
- result[1] = '\0';
- } else
- strNcpy(result, s, 16);
- return(result);
+ char *result = (char *) palloc(17);
+
+ if (s == NULL)
+ {
+ result[0] = '-';
+ result[1] = '\0';
+ }
+ else
+ strNcpy(result, s, 16);
+ return (result);
}
-/*****************************************************************************
- * PUBLIC ROUTINES *
+/*****************************************************************************
+ * PUBLIC ROUTINES *
*****************************************************************************/
-bool chareq(int8 arg1, int8 arg2) { return(arg1 == arg2); }
-bool charne(int8 arg1, int8 arg2) { return(arg1 != arg2); }
-bool charlt(int8 arg1, int8 arg2) { return((uint8)arg1 < (uint8)arg2); }
-bool charle(int8 arg1, int8 arg2) { return((uint8)arg1 <= (uint8)arg2); }
-bool chargt(int8 arg1, int8 arg2) { return((uint8)arg1 > (uint8)arg2); }
-bool charge(int8 arg1, int8 arg2) { return((uint8)arg1 >= (uint8)arg2); }
-int8 charpl(int8 arg1, int8 arg2) { return(arg1 + arg2); }
-int8 charmi(int8 arg1, int8 arg2) { return(arg1 - arg2); }
-int8 charmul(int8 arg1, int8 arg2) { return(arg1 * arg2); }
-int8 chardiv(int8 arg1, int8 arg2) { return(arg1 / arg2); }
+bool chareq(int8 arg1, int8 arg2)
+{
+ return (arg1 == arg2);
+}
+bool charne(int8 arg1, int8 arg2)
+{
+ return (arg1 != arg2);
+}
+bool charlt(int8 arg1, int8 arg2)
+{
+ return ((uint8) arg1 < (uint8) arg2);
+}
+bool charle(int8 arg1, int8 arg2)
+{
+ return ((uint8) arg1 <= (uint8) arg2);
+}
+bool chargt(int8 arg1, int8 arg2)
+{
+ return ((uint8) arg1 > (uint8) arg2);
+}
+bool charge(int8 arg1, int8 arg2)
+{
+ return ((uint8) arg1 >= (uint8) arg2);
+}
+int8 charpl(int8 arg1, int8 arg2)
+{
+ return (arg1 + arg2);
+}
+int8 charmi(int8 arg1, int8 arg2)
+{
+ return (arg1 - arg2);
+}
+int8 charmul(int8 arg1, int8 arg2)
+{
+ return (arg1 * arg2);
+}
+int8 chardiv(int8 arg1, int8 arg2)
+{
+ return (arg1 / arg2);
+}
-bool cideq(int8 arg1, int8 arg2) { return(arg1 == arg2); }
+bool cideq(int8 arg1, int8 arg2)
+{
+ return (arg1 == arg2);
+}
/*
- * char16eq - returns 1 iff arguments are equal
- * char16ne - returns 1 iff arguments are not equal
+ * char16eq - returns 1 iff arguments are equal
+ * char16ne - returns 1 iff arguments are not equal
*
- * BUGS:
- * Assumes that "xy\0\0a" should be equal to "xy\0b".
- * If not, can do the comparison backwards for efficiency.
+ * BUGS:
+ * Assumes that "xy\0\0a" should be equal to "xy\0b".
+ * If not, can do the comparison backwards for efficiency.
*
- * char16lt - returns 1 iff a < b
- * char16le - returns 1 iff a <= b
- * char16gt - returns 1 iff a < b
- * char16ge - returns 1 iff a <= b
+ * char16lt - returns 1 iff a < b
+ * char16le - returns 1 iff a <= b
+ * char16gt - returns 1 iff a < b
+ * char16ge - returns 1 iff a <= b
*
*/
-bool char16eq(char *arg1, char *arg2)
+bool
+char16eq(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return(strncmp(arg1, arg2, 16) == 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return (strncmp(arg1, arg2, 16) == 0);
}
-bool char16ne(char *arg1, char *arg2)
+bool
+char16ne(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return(strncmp(arg1, arg2, 16) != 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return (strncmp(arg1, arg2, 16) != 0);
}
-bool char16lt(char *arg1, char *arg2)
+bool
+char16lt(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return(strncmp(arg1, arg2, 16) < 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return (strncmp(arg1, arg2, 16) < 0);
}
-bool char16le(char *arg1, char *arg2)
+bool
+char16le(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return(strncmp(arg1, arg2, 16) <= 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return (strncmp(arg1, arg2, 16) <= 0);
}
-bool char16gt(char *arg1, char *arg2)
+bool
+char16gt(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
-
- return(strncmp(arg1, arg2, 16) > 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+
+ return (strncmp(arg1, arg2, 16) > 0);
}
-bool char16ge(char *arg1, char *arg2)
+bool
+char16ge(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
-
- return(strncmp(arg1, arg2, 16) >= 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+
+ return (strncmp(arg1, arg2, 16) >= 0);
}
/* ============================== char2 ============================== */
-uint16 char2in(char *s)
+uint16
+char2in(char *s)
{
- uint16 res;
-
- if (s == NULL)
- return(0);
-
- strncpy((char *) &res, s, 2);
- return(res);
+ uint16 res;
+
+ if (s == NULL)
+ return (0);
+
+ strncpy((char *) &res, s, 2);
+ return (res);
}
-char *char2out(uint16 s)
+char *
+char2out(uint16 s)
{
- char *result = (char *) palloc(3);
-
- strNcpy(result, (char *) &s, 2);
-
- return(result);
+ char *result = (char *) palloc(3);
+
+ strNcpy(result, (char *) &s, 2);
+
+ return (result);
}
-bool char2eq(uint16 a, uint16 b)
+bool
+char2eq(uint16 a, uint16 b)
{
- return(strncmp((char *) &a, (char *) &b, 2) == 0);
+ return (strncmp((char *) &a, (char *) &b, 2) == 0);
}
-bool char2ne(uint16 a, uint16 b)
+bool
+char2ne(uint16 a, uint16 b)
{
- return(strncmp((char *) &a, (char *) &b, 2) != 0);
+ return (strncmp((char *) &a, (char *) &b, 2) != 0);
}
-bool char2lt(uint16 a, uint16 b)
+bool
+char2lt(uint16 a, uint16 b)
{
- return(strncmp((char *) &a, (char *) &b, 2) < 0);
+ return (strncmp((char *) &a, (char *) &b, 2) < 0);
}
-bool char2le(uint16 a, uint16 b)
+bool
+char2le(uint16 a, uint16 b)
{
- return(strncmp((char *) &a, (char *) &b, 2) <= 0);
+ return (strncmp((char *) &a, (char *) &b, 2) <= 0);
}
-bool char2gt(uint16 a, uint16 b)
+bool
+char2gt(uint16 a, uint16 b)
{
- return(strncmp((char *) &a, (char *) &b, 2) > 0);
+ return (strncmp((char *) &a, (char *) &b, 2) > 0);
}
-bool char2ge(uint16 a, uint16 b)
+bool
+char2ge(uint16 a, uint16 b)
{
- return(strncmp((char *) &a, (char *) &b, 2) >= 0);
+ return (strncmp((char *) &a, (char *) &b, 2) >= 0);
}
-int32 char2cmp(uint16 a, uint16 b)
+int32
+char2cmp(uint16 a, uint16 b)
{
- return (strncmp((char *) &a, (char *) &b, 2));
+ return (strncmp((char *) &a, (char *) &b, 2));
}
/* ============================== char4 ============================== */
-uint32 char4in(char *s)
+uint32
+char4in(char *s)
{
- uint32 res;
-
- if (s == NULL)
- return(0);
-
- strncpy((char *) &res, s, 4);
-
- return(res);
+ uint32 res;
+
+ if (s == NULL)
+ return (0);
+
+ strncpy((char *) &res, s, 4);
+
+ return (res);
}
-char *char4out(s)
- uint32 s;
+char *
+char4out(s)
+uint32 s;
{
- char *result = (char *) palloc(5);
-
- strNcpy(result, (char *) &s, 4);
-
- return(result);
+ char *result = (char *) palloc(5);
+
+ strNcpy(result, (char *) &s, 4);
+
+ return (result);
}
-bool char4eq(uint32 a, uint32 b)
+bool
+char4eq(uint32 a, uint32 b)
{
- return(strncmp((char *) &a, (char *) &b, 4) == 0);
+ return (strncmp((char *) &a, (char *) &b, 4) == 0);
}
-bool char4ne(uint32 a, uint32 b)
+bool
+char4ne(uint32 a, uint32 b)
{
- return(strncmp((char *) &a, (char *) &b, 4) != 0);
+ return (strncmp((char *) &a, (char *) &b, 4) != 0);
}
-bool char4lt(uint32 a, uint32 b)
+bool
+char4lt(uint32 a, uint32 b)
{
- return(strncmp((char *) &a, (char *) &b, 4) < 0);
+ return (strncmp((char *) &a, (char *) &b, 4) < 0);
}
-bool char4le(uint32 a, uint32 b)
+bool
+char4le(uint32 a, uint32 b)
{
- return(strncmp((char *) &a, (char *) &b, 4) <= 0);
+ return (strncmp((char *) &a, (char *) &b, 4) <= 0);
}
-bool char4gt(uint32 a, uint32 b)
+bool
+char4gt(uint32 a, uint32 b)
{
- return(strncmp((char *) &a, (char *) &b, 4) > 0);
+ return (strncmp((char *) &a, (char *) &b, 4) > 0);
}
-bool char4ge(uint32 a, uint32 b)
+bool
+char4ge(uint32 a, uint32 b)
{
- return(strncmp((char *) &a, (char *) &b, 4) >= 0);
+ return (strncmp((char *) &a, (char *) &b, 4) >= 0);
}
-int32 char4cmp(uint32 a, uint32 b)
+int32
+char4cmp(uint32 a, uint32 b)
{
- return(strncmp((char *) &a, (char *) &b, 4));
+ return (strncmp((char *) &a, (char *) &b, 4));
}
/* ============================== char8 ============================== */
-char *char8in(char *s)
+char *
+char8in(char *s)
{
- char *result;
-
- if (s == NULL)
- return((char *) NULL);
-
- result = (char *) palloc(8);
- strncpy(result, s, 8);
- return(result);
+ char *result;
+
+ if (s == NULL)
+ return ((char *) NULL);
+
+ result = (char *) palloc(8);
+ strncpy(result, s, 8);
+ return (result);
}
-char *char8out(char *s)
+char *
+char8out(char *s)
{
- char *result = (char *) palloc(9);
-
- if (s == NULL) {
- result[0] = '-';
- result[1] = '\0';
- } else
- strNcpy(result, s, 8);
- return(result);
+ char *result = (char *) palloc(9);
+
+ if (s == NULL)
+ {
+ result[0] = '-';
+ result[1] = '\0';
+ }
+ else
+ strNcpy(result, s, 8);
+ return (result);
}
-bool char8eq(char *arg1, char *arg2)
+bool
+char8eq(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return(strncmp(arg1, arg2, 8) == 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return (strncmp(arg1, arg2, 8) == 0);
}
-bool char8ne(char *arg1, char *arg2)
+bool
+char8ne(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return(strncmp(arg1, arg2, 8) != 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return (strncmp(arg1, arg2, 8) != 0);
}
-bool char8lt(char *arg1, char *arg2)
+bool
+char8lt(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return(strncmp(arg1, arg2, 8) < 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return (strncmp(arg1, arg2, 8) < 0);
}
-bool char8le(char *arg1, char *arg2)
+bool
+char8le(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return(strncmp(arg1, arg2, 8) <= 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return (strncmp(arg1, arg2, 8) <= 0);
}
-bool char8gt(char *arg1, char *arg2)
+bool
+char8gt(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return(strncmp(arg1, arg2, 8) > 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return (strncmp(arg1, arg2, 8) > 0);
}
-bool char8ge(char *arg1, char *arg2)
+bool
+char8ge(char *arg1, char *arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return(strncmp(arg1, arg2, 8) >= 0);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return (strncmp(arg1, arg2, 8) >= 0);
}
-int32 char8cmp(char *arg1, char *arg2)
+int32
+char8cmp(char *arg1, char *arg2)
{
- return(strncmp(arg1, arg2, 8));
+ return (strncmp(arg1, arg2, 8));
}
diff --git a/src/backend/utils/adt/chunk.c b/src/backend/utils/adt/chunk.c
index 3d9aec0d9e4..fcfc8cdaeb5 100644
--- a/src/backend/utils/adt/chunk.c
+++ b/src/backend/utils/adt/chunk.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/chunk.c,v 1.6 1997/08/19 21:34:27 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/chunk.c,v 1.7 1997/09/07 04:50:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,7 +20,7 @@
#include "utils/memutils.h"
#include "libpq/libpq-fs.h"
-#include "storage/fd.h" /* for SEEK_ */
+#include "storage/fd.h" /* for SEEK_ */
#include "catalog/pg_type.h"
@@ -29,581 +29,666 @@
#include "optimizer/internal.h"
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
#define INFTY 500000000
#define MANY 10000
#define MAXPAT 20
-#define quot_ceil(x,y) (((x)+(y)-1)/(y))
-#define min(x,y) (((x) < (y))? (x) : (y))
-#define max(x,y) (((x) > (y))? (x) : (y))
+#define quot_ceil(x,y) (((x)+(y)-1)/(y))
+#define min(x,y) (((x) < (y))? (x) : (y))
+#define max(x,y) (((x) > (y))? (x) : (y))
static CHUNK_INFO cInfo;
/* non-export function prototypes */
-static int _FindBestChunk(int size, int dmax[], int dbest[], int dim,
- int A[MAXPAT][MAXDIM+1], int N);
-static int get_next(int d[], int k, int C, int dmax[]);
-static void initialize_info(CHUNK_INFO *A, int ndim, int dim[], int chunk[]);
+static int
+_FindBestChunk(int size, int dmax[], int dbest[], int dim,
+ int A[MAXPAT][MAXDIM + 1], int N);
+static int get_next(int d[], int k, int C, int dmax[]);
+static void initialize_info(CHUNK_INFO * A, int ndim, int dim[], int chunk[]);
+
#ifdef LOARRAY
-static void _ConvertToChunkFile(int n, int baseSize, int dim[], int C[],
- int srcfd, int destfd);
-static void read_chunk(int chunk_no[], int C[], char a_chunk[], int srcfd,
- int n, int baseSize, int PX[], int dist[]);
-static int write_chunk(struct varlena * a_chunk, int ofile);
-static int seek_and_read(int pos, int size, char buff[], int fp, int from);
+static void
+_ConvertToChunkFile(int n, int baseSize, int dim[], int C[],
+ int srcfd, int destfd);
+static void
+read_chunk(int chunk_no[], int C[], char a_chunk[], int srcfd,
+ int n, int baseSize, int PX[], int dist[]);
+static int write_chunk(struct varlena * a_chunk, int ofile);
+static int seek_and_read(int pos, int size, char buff[], int fp, int from);
+
#endif
-static int GetChunkSize(FILE *fd, int ndim, int dim[MAXDIM], int baseSize,
- int d[MAXDIM]);
+static int
+GetChunkSize(FILE * fd, int ndim, int dim[MAXDIM], int baseSize,
+ int d[MAXDIM]);
/*------------------------------------------------------------------------
* _ChunkArray ---
- * converts an input array to chunked format using the information
- * provided by the access pattern.
+ * converts an input array to chunked format using the information
+ * provided by the access pattern.
* Results:
- * creates a new file that stores the chunked array and returns
- * information about the chunked file
+ * creates a new file that stores the chunked array and returns
+ * information about the chunked file
*-----------------------------------------------------------------------
*/
-char *
+char *
_ChunkArray(int fd,
- FILE *afd,
- int ndim,
- int dim[],
- int baseSize,
- int *nbytes,
- char *chunkfile)
+ FILE * afd,
+ int ndim,
+ int dim[],
+ int baseSize,
+ int *nbytes,
+ char *chunkfile)
{
#ifdef LOARRAY
-int cfd = 0;
+ int cfd = 0;
+
#endif
- int chunk[MAXDIM], csize;
- bool reorgFlag;
-
- if (chunkfile == NULL)
- reorgFlag = true;
- else
- reorgFlag = false;
-
+ int chunk[MAXDIM],
+ csize;
+ bool reorgFlag;
+
+ if (chunkfile == NULL)
+ reorgFlag = true;
+ else
+ reorgFlag = false;
+
#ifdef LOARRAY
- if (reorgFlag)
- /* create new LO for chunked file */
- chunkfile = _array_newLO( &cfd, fileFlag );
- else
- cfd = LOopen(chunkfile, O_RDONLY);
- if (cfd < 0)
- elog(WARN, "Unable to open chunk file");
+ if (reorgFlag)
+ /* create new LO for chunked file */
+ chunkfile = _array_newLO(&cfd, fileFlag);
+ else
+ cfd = LOopen(chunkfile, O_RDONLY);
+ if (cfd < 0)
+ elog(WARN, "Unable to open chunk file");
#endif
- strcpy (cInfo.lo_name, chunkfile);
-
- /* find chunk size */
- csize = GetChunkSize(afd, ndim, dim, baseSize, chunk);
-
+ strcpy(cInfo.lo_name, chunkfile);
+
+ /* find chunk size */
+ csize = GetChunkSize(afd, ndim, dim, baseSize, chunk);
+
#ifdef LOARRAY
- if (reorgFlag)
- /* copy data from input file to chunked file */
- _ConvertToChunkFile(ndim, baseSize, dim, chunk, fd, cfd);
+ if (reorgFlag)
+ /* copy data from input file to chunked file */
+ _ConvertToChunkFile(ndim, baseSize, dim, chunk, fd, cfd);
#endif
-
- initialize_info(&cInfo, ndim, dim, chunk);
- *nbytes = sizeof(CHUNK_INFO);
- return (char *) &cInfo ;
+
+ initialize_info(&cInfo, ndim, dim, chunk);
+ *nbytes = sizeof(CHUNK_INFO);
+ return (char *) &cInfo;
}
/*--------------------------------------------------------------------------
* GetChunkSize --
- * given an access pattern and array dimensionality etc, this program
- * returns the dimensions of the chunk in "d"
+ * given an access pattern and array dimensionality etc, this program
+ * returns the dimensions of the chunk in "d"
*-----------------------------------------------------------------------
*/
static int
-GetChunkSize(FILE *fd,
- int ndim,
- int dim[MAXDIM],
- int baseSize,
- int d[MAXDIM])
+GetChunkSize(FILE * fd,
+ int ndim,
+ int dim[MAXDIM],
+ int baseSize,
+ int d[MAXDIM])
{
- int N, i, j, csize;
- int A[MAXPAT][MAXDIM+1], dmax[MAXDIM];
-
- /*
- * ----------- read input ------------
- */
- fscanf(fd, "%d", &N);
- if ( N > MAXPAT )
- elog(WARN, "array_in: too many access pattern elements");
- for (i = 0; i < N; i++)
- for (j = 0; j < ndim+1; j++)
- if (fscanf(fd, "%d ", &(A[i][j])) == EOF)
- elog (WARN, "array_in: bad access pattern input");
-
- /*
- * estimate chunk size
- */
- for (i = 0; i < ndim; i++)
- for (j = 0, dmax[i] = 1; j < N; j++)
- if (dmax[i] < A[j][i])
- dmax[i] = A[j][i];
- csize = BLCKSZ/baseSize;
-
- _FindBestChunk (csize, dmax, d, ndim, A, N);
-
- return csize;
+ int N,
+ i,
+ j,
+ csize;
+ int A[MAXPAT][MAXDIM + 1],
+ dmax[MAXDIM];
+
+ /*
+ * ----------- read input ------------
+ */
+ fscanf(fd, "%d", &N);
+ if (N > MAXPAT)
+ elog(WARN, "array_in: too many access pattern elements");
+ for (i = 0; i < N; i++)
+ for (j = 0; j < ndim + 1; j++)
+ if (fscanf(fd, "%d ", &(A[i][j])) == EOF)
+ elog(WARN, "array_in: bad access pattern input");
+
+ /*
+ * estimate chunk size
+ */
+ for (i = 0; i < ndim; i++)
+ for (j = 0, dmax[i] = 1; j < N; j++)
+ if (dmax[i] < A[j][i])
+ dmax[i] = A[j][i];
+ csize = BLCKSZ / baseSize;
+
+ _FindBestChunk(csize, dmax, d, ndim, A, N);
+
+ return csize;
}
/*-------------------------------------------------------------------------
* _FindBestChunk --
- * This routine does most of the number crunching to compute the
- * optimal chunk shape.
+ * This routine does most of the number crunching to compute the
+ * optimal chunk shape.
* Called by GetChunkSize
*------------------------------------------------------------------------
*/
static int
_FindBestChunk(int size,
- int dmax[],
- int dbest[],
- int dim,
- int A[MAXPAT][MAXDIM+1],
- int N)
+ int dmax[],
+ int dbest[],
+ int dim,
+ int A[MAXPAT][MAXDIM + 1],
+ int N)
{
- int d[MAXDIM];
- int tc, mintc = INFTY;
-
- d[0] = 0;
- mintc = INFTY;
- while (get_next(d,dim,size, dmax)) {
- /*
- * compute the number of page fetches for a given
- * chunk size (d[]) and access pattern (A[][])
- */
- register int i,j, nc;
- for (i = 0, tc = 0; i < N; i++){
- for (j = 0, nc = 1; j < dim; j++)
- nc *= quot_ceil(A[i][j], d[j]);
- nc *= A[i][dim];
- tc += nc;
+ int d[MAXDIM];
+ int tc,
+ mintc = INFTY;
+
+ d[0] = 0;
+ mintc = INFTY;
+ while (get_next(d, dim, size, dmax))
+ {
+
+ /*
+ * compute the number of page fetches for a given chunk size (d[])
+ * and access pattern (A[][])
+ */
+ register int i,
+ j,
+ nc;
+
+ for (i = 0, tc = 0; i < N; i++)
+ {
+ for (j = 0, nc = 1; j < dim; j++)
+ nc *= quot_ceil(A[i][j], d[j]);
+ nc *= A[i][dim];
+ tc += nc;
+ }
+
+ /*
+ * tc holds the total number of page fetches
+ */
+ if (mintc >= tc)
+ {
+ mintc = tc;
+ for (j = 0; j < dim; dbest[j] = d[j], j++)
+ ;
+ }
}
- /*
- * tc holds the total number of page fetches
- */
- if (mintc >= tc) {
- mintc = tc;
- for (j = 0; j < dim; dbest[j] = d[j], j++)
- ;
- }
- }
- return(mintc);
+ return (mintc);
}
/*----------------------------------------------------------------------
* get_next --
- * Called by _GetBestChunk to get the next tuple in the lexicographic order
+ * Called by _GetBestChunk to get the next tuple in the lexicographic order
*---------------------------------------------------------------------
*/
static int
get_next(int d[], int k, int C, int dmax[])
{
- register int i,j, temp;
-
- if (!d[0]) {
- temp = C;
- for (j = k-1; j >= 0; j--){
- d[j] = min(temp, dmax[j]);
- temp = max(1, temp/d[j]);
- }
- return(1);
- }
-
- for (j = 0, temp = 1; j < k; j++)
- temp *= d[j];
-
- for (i=k-1; i >= 0; i--){
- temp = temp/d[i];
- if (((temp*(d[i]+1)) < C) && (d[i]+1 <= dmax[i]))
- break;
- }
- if (i < 0)
- return(0);
-
- d[i]++;
- j = C/temp;
- d[i] = min(dmax[i], j/(j/d[i]));
- temp = temp*d[i];
- temp = C/temp;
-
- for (j = k-1; j > i; j--){
- d[j] = min(temp, dmax[j]);
- temp = max(1, temp/d[j]);
- }
- return(1);
+ register int i,
+ j,
+ temp;
+
+ if (!d[0])
+ {
+ temp = C;
+ for (j = k - 1; j >= 0; j--)
+ {
+ d[j] = min(temp, dmax[j]);
+ temp = max(1, temp / d[j]);
+ }
+ return (1);
+ }
+
+ for (j = 0, temp = 1; j < k; j++)
+ temp *= d[j];
+
+ for (i = k - 1; i >= 0; i--)
+ {
+ temp = temp / d[i];
+ if (((temp * (d[i] + 1)) < C) && (d[i] + 1 <= dmax[i]))
+ break;
+ }
+ if (i < 0)
+ return (0);
+
+ d[i]++;
+ j = C / temp;
+ d[i] = min(dmax[i], j / (j / d[i]));
+ temp = temp * d[i];
+ temp = C / temp;
+
+ for (j = k - 1; j > i; j--)
+ {
+ d[j] = min(temp, dmax[j]);
+ temp = max(1, temp / d[j]);
+ }
+ return (1);
}
#ifdef LOARRAY
-static char a_chunk[BLCKSZ + 4]; /* 4 since a_chunk is in
- varlena format */
+static char a_chunk[BLCKSZ + 4]; /* 4 since a_chunk is in varlena
+ * format */
+
#endif
static void
-initialize_info(CHUNK_INFO *A, int ndim, int dim[], int chunk[])
+initialize_info(CHUNK_INFO * A, int ndim, int dim[], int chunk[])
{
- int i;
-
- for ( i = 0; i < ndim; i++)
- A->C[i] = chunk[i];
+ int i;
+
+ for (i = 0; i < ndim; i++)
+ A->C[i] = chunk[i];
}
/*--------------------------------------------------------------------------
* Procedure reorganize_data():
- * This procedure reads the input multidimensional array that is organised
- * in the order specified by array "X" and breaks it up into chunks of
- * dimensions specified in "C".
+ * This procedure reads the input multidimensional array that is organised
+ * in the order specified by array "X" and breaks it up into chunks of
+ * dimensions specified in "C".
*
- * This is a very slow process, since reading and writing of LARGE files
- * may be involved.
+ * This is a very slow process, since reading and writing of LARGE files
+ * may be involved.
*
*-------------------------------------------------------------------------
*/
#ifdef LOARRAY
static void
_ConvertToChunkFile(int n,
- int baseSize,
- int dim[],
- int C[],
- int srcfd,
- int destfd)
+ int baseSize,
+ int dim[],
+ int C[],
+ int srcfd,
+ int destfd)
{
- int max_chunks[MAXDIM], chunk_no[MAXDIM];
- int PX[MAXDIM], dist[MAXDIM];
- int csize = 1, i, temp;
-
- for (i = 0; i < n; chunk_no[i++] = 0) {
- max_chunks[i] = dim[i]/C[i];
- csize *= C[i];
- }
- csize *= baseSize;
- temp = csize + 4;
- memmove(a_chunk, &temp, 4);
-
- mda_get_prod(n, dim, PX);
- mda_get_offset_values(n, dist, PX, C);
- for (i = 0; i < n; dist[i] *= baseSize, i++)
- ;
- do {
- read_chunk(chunk_no, C, &(a_chunk[4]), srcfd, n, baseSize, PX, dist);
- write_chunk((struct varlena*)a_chunk, destfd);
- } while (next_tuple(n, chunk_no, max_chunks) != -1);
+ int max_chunks[MAXDIM],
+ chunk_no[MAXDIM];
+ int PX[MAXDIM],
+ dist[MAXDIM];
+ int csize = 1,
+ i,
+ temp;
+
+ for (i = 0; i < n; chunk_no[i++] = 0)
+ {
+ max_chunks[i] = dim[i] / C[i];
+ csize *= C[i];
+ }
+ csize *= baseSize;
+ temp = csize + 4;
+ memmove(a_chunk, &temp, 4);
+
+ mda_get_prod(n, dim, PX);
+ mda_get_offset_values(n, dist, PX, C);
+ for (i = 0; i < n; dist[i] *= baseSize, i++)
+ ;
+ do
+ {
+ read_chunk(chunk_no, C, &(a_chunk[4]), srcfd, n, baseSize, PX, dist);
+ write_chunk((struct varlena *) a_chunk, destfd);
+ } while (next_tuple(n, chunk_no, max_chunks) != -1);
}
/*--------------------------------------------------------------------------
* read_chunk
- * reads a chunk from the input files into a_chunk, the position of the
- * chunk is specified by chunk_no
+ * reads a chunk from the input files into a_chunk, the position of the
+ * chunk is specified by chunk_no
*--------------------------------------------------------------------------
*/
static void
read_chunk(int chunk_no[],
- int C[],
- char a_chunk[],
- int srcfd,
- int n,
- int baseSize,
- int PX[],
- int dist[])
+ int C[],
+ char a_chunk[],
+ int srcfd,
+ int n,
+ int baseSize,
+ int PX[],
+ int dist[])
{
- int i, j, cp, unit_transfer;
- int start_pos, pos[MAXDIM];
- int indx[MAXDIM];
- int fpOff;
-
- for ( i = start_pos = 0; i < n; i++) {
- pos[i] = chunk_no[i] * C[i];
- start_pos += pos[i]*PX[i];
- }
- start_pos *= baseSize;
-
- /* Read a block of dimesion C starting at co-ordinates pos */
- unit_transfer = C[n-1] * baseSize;
-
- for (i = 0; i < n; indx[i++] = 0)
- ;
- fpOff = start_pos;
- seek_and_read(fpOff, unit_transfer, a_chunk, srcfd, SEEK_SET);
- fpOff += unit_transfer;
- cp = unit_transfer;
-
- while ((j = next_tuple(n-1, indx, C)) != -1) {
- fpOff += dist[j];
- seek_and_read(fpOff, unit_transfer, &(a_chunk[cp]), srcfd, SEEK_SET);
- cp += unit_transfer;
- fpOff += unit_transfer;
- }
+ int i,
+ j,
+ cp,
+ unit_transfer;
+ int start_pos,
+ pos[MAXDIM];
+ int indx[MAXDIM];
+ int fpOff;
+
+ for (i = start_pos = 0; i < n; i++)
+ {
+ pos[i] = chunk_no[i] * C[i];
+ start_pos += pos[i] * PX[i];
+ }
+ start_pos *= baseSize;
+
+ /* Read a block of dimesion C starting at co-ordinates pos */
+ unit_transfer = C[n - 1] * baseSize;
+
+ for (i = 0; i < n; indx[i++] = 0)
+ ;
+ fpOff = start_pos;
+ seek_and_read(fpOff, unit_transfer, a_chunk, srcfd, SEEK_SET);
+ fpOff += unit_transfer;
+ cp = unit_transfer;
+
+ while ((j = next_tuple(n - 1, indx, C)) != -1)
+ {
+ fpOff += dist[j];
+ seek_and_read(fpOff, unit_transfer, &(a_chunk[cp]), srcfd, SEEK_SET);
+ cp += unit_transfer;
+ fpOff += unit_transfer;
+ }
}
/*--------------------------------------------------------------------------
* write_chunk()
- * writes a chunk of size csize into the output file
+ * writes a chunk of size csize into the output file
*--------------------------------------------------------------------------
*/
static int
write_chunk(struct varlena * a_chunk, int ofile)
{
- int got_n = 0;
+ int got_n = 0;
+
#ifdef LOARRAY
- got_n = LOwrite (ofile, a_chunk);
+ got_n = LOwrite(ofile, a_chunk);
#endif
- return(got_n);
+ return (got_n);
}
/*--------------------------------------------------------------------------
* seek_and_read()
- * seeks to the asked location in the input file and reads the
- * appropriate number of blocks
- * Called By: read_chunk()
+ * seeks to the asked location in the input file and reads the
+ * appropriate number of blocks
+ * Called By: read_chunk()
*--------------------------------------------------------------------------
*/
static int
seek_and_read(int pos, int size, char buff[], int fp, int from)
{
- struct varlena *v = NULL;
-
- /* Assuming only one file */
- if ( lo_lseek(fp, pos, from ) < 0)
- elog(WARN, "File seek error");
+ struct varlena *v = NULL;
+
+ /* Assuming only one file */
+ if (lo_lseek(fp, pos, from) < 0)
+ elog(WARN, "File seek error");
#ifdef LOARRAY
- v = (struct varlena *) LOread(fp, size);
+ v = (struct varlena *) LOread(fp, size);
#endif
- if (VARSIZE(v) - 4 < size)
- elog(WARN, "File read error");
- memmove(buff, VARDATA(v), size);
- pfree(v);
- return(1);
-
+ if (VARSIZE(v) - 4 < size)
+ elog(WARN, "File read error");
+ memmove(buff, VARDATA(v), size);
+ pfree(v);
+ return (1);
+
}
-#endif /* LOARRAY */
+
+#endif /* LOARRAY */
/*----------------------------------------------------------------------------
* _ReadChunkArray --
- * returns the subarray specified bu the range indices "st" and "endp"
- * from the chunked array stored in file "fp"
+ * returns the subarray specified bu the range indices "st" and "endp"
+ * from the chunked array stored in file "fp"
*---------------------------------------------------------------------------
*/
int
_ReadChunkArray(int st[],
- int endp[],
- int bsize,
- int fp,
- char *destfp,
- ArrayType *array,
- int isDestLO,
- bool *isNull)
+ int endp[],
+ int bsize,
+ int fp,
+ char *destfp,
+ ArrayType * array,
+ int isDestLO,
+ bool * isNull)
{
- int i,j,jj;
- int n, temp, words_read;
- int chunk_span[MAXDIM], chunk_off[MAXDIM];
- int chunk_st[MAXDIM], chunk_end[MAXDIM];
- int block_seek;
-
- int bptr, *C, csize, *dim, *lb;
- int range_st[MAXDIM], range_end[MAXDIM],
- range[MAXDIM], array_span[MAXDIM];
- int PA[MAXDIM], PCHUNK[MAXDIM], PC[MAXDIM];
- int to_read;
- int cdist[MAXDIM], adist[MAXDIM];
- int dist[MAXDIM], temp_seek;
-
- int srcOff; /* Needed since LO don't understand SEEK_CUR*/
- char *baseDestFp = (char *)destfp;
-
- CHUNK_INFO *A = (CHUNK_INFO *) ARR_DATA_PTR(array);
- n = ARR_NDIM(array);
- dim = ARR_DIMS(array);
- lb = ARR_LBOUND(array);
- C = A->C;
-
- csize = C[n-1];
- PC[n-1] = 1;
- temp = dim[n - 1]/C[n-1];
- for (i = n-2; i >= 0; i--){
- PC[i] = PC[i+1] * temp;
- temp = dim[i] / C[i];
- csize *= C[i];
- }
-
- for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++)
- ;
- mda_get_prod(n, C, PCHUNK);
- mda_get_range(n, array_span, st, endp);
- mda_get_prod(n, array_span, PA);
-
- array2chunk_coord(n, C, st, chunk_st);
- array2chunk_coord(n, C, endp, chunk_end);
- mda_get_range(n, chunk_span, chunk_st, chunk_end);
- mda_get_offset_values(n, dist, PC, chunk_span);
-
- for (i = 0; i < n; i++) {
- range_st[i] = st[i];
- range_end[i] = min(chunk_st[i]*C[i]+C[i]-1, endp[i]);
- }
-
- for (i = j = 0; i < n; i++)
- j+= chunk_st[i]*PC[i];
- temp_seek = srcOff = j * csize * bsize;
- if (lo_lseek(fp, srcOff, SEEK_SET) < 0) RETURN_NULL;
-
- jj = n-1;
- for (i = 0; i < n; chunk_off[i++] = 0)
- ;
- words_read = 0; temp_seek = 0;
- do {
- /* Write chunk (chunk_st) to output buffer */
- mda_get_range(n, array_span, range_st, range_end);
- mda_get_offset_values(n, adist, PA, array_span);
- mda_get_offset_values(n, cdist, PCHUNK, array_span);
- for (i=0; i < n; range[i] = range_st[i]-st[i], i++);
- bptr = tuple2linear(n, range, PA);
- for (i = 0; i < n; range[i++] = 0);
- j = n-1; bptr *= bsize;
- if (isDestLO) {
- if (lo_lseek((int)destfp, bptr, SEEK_SET) < 0)
- RETURN_NULL;
- }
- else
- destfp = baseDestFp + bptr;
- for(i = 0, block_seek = 0; i < n; i++)
- block_seek += (range_st[i]-(chunk_st[i] + chunk_off[i])
- *C[i])*PCHUNK[i];
- if (dist[jj] + block_seek + temp_seek) {
- temp = (dist[jj]*csize+block_seek+temp_seek)*bsize;
- srcOff += temp;
- if (lo_lseek(fp, srcOff, SEEK_SET) < 0)
- RETURN_NULL;
- }
- for (i = n-1, to_read = bsize; i >= 0;
- to_read *= min(C[i], array_span[i]), i--)
- if (cdist[i] || adist[i])
- break;
- do {
- if (cdist[j]) {
- srcOff += (cdist[j]*bsize);
- if (lo_lseek(fp, srcOff, SEEK_SET) < 0)
- RETURN_NULL;
- }
- block_seek += cdist[j];
- bptr += adist[j]*bsize;
- if (isDestLO) {
- if (lo_lseek((int)destfp, bptr, SEEK_SET) < 0)
- RETURN_NULL;
- }
- else
- destfp = baseDestFp + bptr;
- temp = _LOtransfer ((char**)&destfp, to_read, 1, (char**)&fp, 1, isDestLO);
- if (temp < to_read)
+ int i,
+ j,
+ jj;
+ int n,
+ temp,
+ words_read;
+ int chunk_span[MAXDIM],
+ chunk_off[MAXDIM];
+ int chunk_st[MAXDIM],
+ chunk_end[MAXDIM];
+ int block_seek;
+
+ int bptr,
+ *C,
+ csize,
+ *dim,
+ *lb;
+ int range_st[MAXDIM],
+ range_end[MAXDIM],
+ range[MAXDIM],
+ array_span[MAXDIM];
+ int PA[MAXDIM],
+ PCHUNK[MAXDIM],
+ PC[MAXDIM];
+ int to_read;
+ int cdist[MAXDIM],
+ adist[MAXDIM];
+ int dist[MAXDIM],
+ temp_seek;
+
+ int srcOff; /* Needed since LO don't understand
+ * SEEK_CUR */
+ char *baseDestFp = (char *) destfp;
+
+ CHUNK_INFO *A = (CHUNK_INFO *) ARR_DATA_PTR(array);
+
+ n = ARR_NDIM(array);
+ dim = ARR_DIMS(array);
+ lb = ARR_LBOUND(array);
+ C = A->C;
+
+ csize = C[n - 1];
+ PC[n - 1] = 1;
+ temp = dim[n - 1] / C[n - 1];
+ for (i = n - 2; i >= 0; i--)
+ {
+ PC[i] = PC[i + 1] * temp;
+ temp = dim[i] / C[i];
+ csize *= C[i];
+ }
+
+ for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++)
+ ;
+ mda_get_prod(n, C, PCHUNK);
+ mda_get_range(n, array_span, st, endp);
+ mda_get_prod(n, array_span, PA);
+
+ array2chunk_coord(n, C, st, chunk_st);
+ array2chunk_coord(n, C, endp, chunk_end);
+ mda_get_range(n, chunk_span, chunk_st, chunk_end);
+ mda_get_offset_values(n, dist, PC, chunk_span);
+
+ for (i = 0; i < n; i++)
+ {
+ range_st[i] = st[i];
+ range_end[i] = min(chunk_st[i] * C[i] + C[i] - 1, endp[i]);
+ }
+
+ for (i = j = 0; i < n; i++)
+ j += chunk_st[i] * PC[i];
+ temp_seek = srcOff = j * csize * bsize;
+ if (lo_lseek(fp, srcOff, SEEK_SET) < 0)
RETURN_NULL;
- srcOff += to_read;
- words_read+=to_read;
- bptr += to_read;
- block_seek += (to_read/bsize);
- /*
- * compute next tuple in range[]
- */
- {
- int x;
- if (!(i+1))
- j = -1;
- else {
- range[i] = (range[i]+1)%array_span[i];
- for (x = i; x*(!range[x]); x--)
- range[x-1] = (range[x-1]+1)%array_span[x-1];
- if (x)
- j = x;
- else {
- if (range[0])
- j = 0;
- else
- j = -1;
- }
- }
- }
- /*
- * end of compute next tuple --
- * j is set to -1 if tuple generation is over
- */
- } while (j != -1);
-
- block_seek = csize - block_seek;
- temp_seek = block_seek;
- jj = next_tuple(n, chunk_off, chunk_span);
- if (jj == -1)
- break;
- range_st[jj] = (chunk_st[jj]+chunk_off[jj])*C[jj];
- range_end[jj] = min(range_st[jj] + C[jj]-1, endp[jj]);
-
- for (i = jj+1; i < n; i++) {
- range_st[i] = st[i];
- range_end[i] = min((chunk_st[i]+chunk_off[i])*C[i]+C[i]-1, endp[i]);
- }
- } while (jj != -1);
- return(words_read);
+
+ jj = n - 1;
+ for (i = 0; i < n; chunk_off[i++] = 0)
+ ;
+ words_read = 0;
+ temp_seek = 0;
+ do
+ {
+ /* Write chunk (chunk_st) to output buffer */
+ mda_get_range(n, array_span, range_st, range_end);
+ mda_get_offset_values(n, adist, PA, array_span);
+ mda_get_offset_values(n, cdist, PCHUNK, array_span);
+ for (i = 0; i < n; range[i] = range_st[i] - st[i], i++);
+ bptr = tuple2linear(n, range, PA);
+ for (i = 0; i < n; range[i++] = 0);
+ j = n - 1;
+ bptr *= bsize;
+ if (isDestLO)
+ {
+ if (lo_lseek((int) destfp, bptr, SEEK_SET) < 0)
+ RETURN_NULL;
+ }
+ else
+ destfp = baseDestFp + bptr;
+ for (i = 0, block_seek = 0; i < n; i++)
+ block_seek += (range_st[i] - (chunk_st[i] + chunk_off[i])
+ * C[i]) * PCHUNK[i];
+ if (dist[jj] + block_seek + temp_seek)
+ {
+ temp = (dist[jj] * csize + block_seek + temp_seek) * bsize;
+ srcOff += temp;
+ if (lo_lseek(fp, srcOff, SEEK_SET) < 0)
+ RETURN_NULL;
+ }
+ for (i = n - 1, to_read = bsize; i >= 0;
+ to_read *= min(C[i], array_span[i]), i--)
+ if (cdist[i] || adist[i])
+ break;
+ do
+ {
+ if (cdist[j])
+ {
+ srcOff += (cdist[j] * bsize);
+ if (lo_lseek(fp, srcOff, SEEK_SET) < 0)
+ RETURN_NULL;
+ }
+ block_seek += cdist[j];
+ bptr += adist[j] * bsize;
+ if (isDestLO)
+ {
+ if (lo_lseek((int) destfp, bptr, SEEK_SET) < 0)
+ RETURN_NULL;
+ }
+ else
+ destfp = baseDestFp + bptr;
+ temp = _LOtransfer((char **) &destfp, to_read, 1, (char **) &fp, 1, isDestLO);
+ if (temp < to_read)
+ RETURN_NULL;
+ srcOff += to_read;
+ words_read += to_read;
+ bptr += to_read;
+ block_seek += (to_read / bsize);
+
+ /*
+ * compute next tuple in range[]
+ */
+ {
+ int x;
+
+ if (!(i + 1))
+ j = -1;
+ else
+ {
+ range[i] = (range[i] + 1) % array_span[i];
+ for (x = i; x * (!range[x]); x--)
+ range[x - 1] = (range[x - 1] + 1) % array_span[x - 1];
+ if (x)
+ j = x;
+ else
+ {
+ if (range[0])
+ j = 0;
+ else
+ j = -1;
+ }
+ }
+ }
+
+ /*
+ * end of compute next tuple -- j is set to -1 if tuple
+ * generation is over
+ */
+ } while (j != -1);
+
+ block_seek = csize - block_seek;
+ temp_seek = block_seek;
+ jj = next_tuple(n, chunk_off, chunk_span);
+ if (jj == -1)
+ break;
+ range_st[jj] = (chunk_st[jj] + chunk_off[jj]) * C[jj];
+ range_end[jj] = min(range_st[jj] + C[jj] - 1, endp[jj]);
+
+ for (i = jj + 1; i < n; i++)
+ {
+ range_st[i] = st[i];
+ range_end[i] = min((chunk_st[i] + chunk_off[i]) * C[i] + C[i] - 1, endp[i]);
+ }
+ } while (jj != -1);
+ return (words_read);
}
/*------------------------------------------------------------------------
* _ReadChunkArray1El --
- * returns one element of the chunked array as specified by the index "st"
- * the chunked file descriptor is "fp"
+ * returns one element of the chunked array as specified by the index "st"
+ * the chunked file descriptor is "fp"
*-------------------------------------------------------------------------
*/
struct varlena *
_ReadChunkArray1El(int st[],
- int bsize,
- int fp,
- ArrayType *array,
- bool *isNull)
+ int bsize,
+ int fp,
+ ArrayType * array,
+ bool * isNull)
{
- int i, j, n, temp, srcOff;
- int chunk_st[MAXDIM];
-
- int *C, csize, *dim, *lb;
- int PCHUNK[MAXDIM], PC[MAXDIM];
-
- CHUNK_INFO *A = (CHUNK_INFO *) ARR_DATA_PTR(array);
-
- n = ARR_NDIM(array);
- lb = ARR_LBOUND(array);
- C = A->C;
- dim = ARR_DIMS(array);
-
- csize = C[n-1];
- PC[n-1] = 1;
- temp = dim[n - 1]/C[n-1];
- for (i = n-2; i >= 0; i--){
- PC[i] = PC[i+1] * temp;
- temp = dim[i] / C[i];
- csize *= C[i];
- }
-
- for (i = 0; i < n; st[i] -= lb[i], i++);
- mda_get_prod(n, C, PCHUNK);
-
- array2chunk_coord(n, C, st, chunk_st);
-
- for (i = j = 0; i < n; i++)
- j+= chunk_st[i]*PC[i];
- srcOff = j * csize;
-
- for(i = 0; i < n; i++)
- srcOff += (st[i]-chunk_st[i]*C[i])*PCHUNK[i];
-
- srcOff *= bsize;
- if (lo_lseek(fp, srcOff, SEEK_SET) < 0)
- RETURN_NULL;
+ int i,
+ j,
+ n,
+ temp,
+ srcOff;
+ int chunk_st[MAXDIM];
+
+ int *C,
+ csize,
+ *dim,
+ *lb;
+ int PCHUNK[MAXDIM],
+ PC[MAXDIM];
+
+ CHUNK_INFO *A = (CHUNK_INFO *) ARR_DATA_PTR(array);
+
+ n = ARR_NDIM(array);
+ lb = ARR_LBOUND(array);
+ C = A->C;
+ dim = ARR_DIMS(array);
+
+ csize = C[n - 1];
+ PC[n - 1] = 1;
+ temp = dim[n - 1] / C[n - 1];
+ for (i = n - 2; i >= 0; i--)
+ {
+ PC[i] = PC[i + 1] * temp;
+ temp = dim[i] / C[i];
+ csize *= C[i];
+ }
+
+ for (i = 0; i < n; st[i] -= lb[i], i++);
+ mda_get_prod(n, C, PCHUNK);
+
+ array2chunk_coord(n, C, st, chunk_st);
+
+ for (i = j = 0; i < n; i++)
+ j += chunk_st[i] * PC[i];
+ srcOff = j * csize;
+
+ for (i = 0; i < n; i++)
+ srcOff += (st[i] - chunk_st[i] * C[i]) * PCHUNK[i];
+
+ srcOff *= bsize;
+ if (lo_lseek(fp, srcOff, SEEK_SET) < 0)
+ RETURN_NULL;
#ifdef LOARRAY
- return (struct varlena *) LOread(fp, bsize);
+ return (struct varlena *) LOread(fp, bsize);
#endif
- return (struct varlena *) 0;
+ return (struct varlena *) 0;
}
-
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index d86bc29429a..40369f9a84e 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* date.c--
- * Utilities for the built-in type "AbsoluteTime" (defined in nabstime).
- * Functions for the built-in type "RelativeTime".
- * Functions for the built-in type "TimeInterval".
+ * Utilities for the built-in type "AbsoluteTime" (defined in nabstime).
+ * Functions for the built-in type "RelativeTime".
+ * Functions for the built-in type "TimeInterval".
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.14 1997/09/05 18:11:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.15 1997/09/07 04:50:06 momjian Exp $
*
* NOTES
- * This code is actually (almost) unused.
- * It needs to be integrated with Time and struct trange.
+ * This code is actually (almost) unused.
+ * It needs to be integrated with Time and struct trange.
*
* XXX This code needs to be rewritten to work with the "new" definitions
* XXX in h/tim.h. Look for int32's, int, long, etc. in the code. The
* XXX definitions in h/tim.h may need to be rethought also.
*
- * XXX This code has been cleaned up some - avi 07/07/93
+ * XXX This code has been cleaned up some - avi 07/07/93
*
*-------------------------------------------------------------------------
*/
@@ -33,910 +33,1017 @@
#include "postgres.h"
#include "miscadmin.h"
#ifdef HAVE_FLOAT_H
-# include <float.h>
+#include <float.h>
#endif
#ifdef HAVE_LIMITS_H
-# include <limits.h>
+#include <limits.h>
#endif
#include "access/xact.h"
-#include "utils/builtins.h" /* where function declarations go */
+#include "utils/builtins.h" /* where function declarations go */
#include "utils/palloc.h"
#include "utils/dt.h"
-#define INVALID_RELTIME_STR "Undefined RelTime"
-#define INVALID_RELTIME_STR_LEN (sizeof(INVALID_RELTIME_STR)-1)
-#define RELTIME_LABEL '@'
-#define RELTIME_PAST "ago"
-#define DIRMAXLEN (sizeof(RELTIME_PAST)-1)
+#define INVALID_RELTIME_STR "Undefined RelTime"
+#define INVALID_RELTIME_STR_LEN (sizeof(INVALID_RELTIME_STR)-1)
+#define RELTIME_LABEL '@'
+#define RELTIME_PAST "ago"
+#define DIRMAXLEN (sizeof(RELTIME_PAST)-1)
/*
- * Unix epoch is Jan 1 00:00:00 1970. Postgres knows about times
- * sixty-eight years on either side of that.
- */
+ * Unix epoch is Jan 1 00:00:00 1970. Postgres knows about times
+ * sixty-eight years on either side of that.
+ */
-#define IsSpace(C) ((C) == ' ')
+#define IsSpace(C) ((C) == ' ')
-#define T_INTERVAL_INVAL 0 /* data represents no valid interval */
-#define T_INTERVAL_VALID 1 /* data represents a valid interval */
+#define T_INTERVAL_INVAL 0 /* data represents no valid interval */
+#define T_INTERVAL_VALID 1 /* data represents a valid interval */
/*
* ['Mon May 10 23:59:12 1943 PST' 'Sun Jan 14 03:14:21 1973 PST']
- * 0 1 2 3 4 5 6
+ * 0 1 2 3 4 5 6
* 1234567890123456789012345678901234567890123456789012345678901234
*
* we allocate some extra -- timezones are usually 3 characters but
* this is not in the POSIX standard...
*/
-#define T_INTERVAL_LEN 80
-#define INVALID_INTERVAL_STR "Undefined Range"
-#define INVALID_INTERVAL_STR_LEN (sizeof(INVALID_INTERVAL_STR)-1)
+#define T_INTERVAL_LEN 80
+#define INVALID_INTERVAL_STR "Undefined Range"
+#define INVALID_INTERVAL_STR_LEN (sizeof(INVALID_INTERVAL_STR)-1)
#define ABSTIMEMIN(t1, t2) abstimele((t1),(t2)) ? (t1) : (t2)
#define ABSTIMEMAX(t1, t2) abstimelt((t1),(t2)) ? (t2) : (t1)
#if FALSE
-static char *unit_tab[] = {
+static char *unit_tab[] = {
"second", "seconds", "minute", "minutes",
"hour", "hours", "day", "days", "week", "weeks",
- "month", "months", "year", "years"};
-#define UNITMAXLEN 7 /* max length of a unit name */
-#define NUNITS 14 /* number of different units */
+"month", "months", "year", "years"};
+
+#define UNITMAXLEN 7 /* max length of a unit name */
+#define NUNITS 14 /* number of different units */
/* table of seconds per unit (month = 30 days, year = 365 days) */
-static int sec_tab[] = {
- 1,1, 60, 60,
- 3600, 3600, 86400, 86400, 604800, 604800,
- 2592000, 2592000, 31536000, 31536000 };
+static int sec_tab[] = {
+ 1, 1, 60, 60,
+ 3600, 3600, 86400, 86400, 604800, 604800,
+2592000, 2592000, 31536000, 31536000};
+
#endif
/*
* Function prototypes -- internal to this file only
*/
-static void reltime2tm(int32 time, struct tm *tm);
+static void reltime2tm(int32 time, struct tm * tm);
#if FALSE
-static int correct_unit(char unit[], int *unptr);
-static int correct_dir(char direction[], int *signptr);
+static int correct_unit(char unit[], int *unptr);
+static int correct_dir(char direction[], int *signptr);
+
#endif
-static int istinterval(char *i_string,
- AbsoluteTime *i_start,
- AbsoluteTime *i_end);
+static int
+istinterval(char *i_string,
+ AbsoluteTime * i_start,
+ AbsoluteTime * i_end);
-/*****************************************************************************
- * USER I/O ROUTINES *
+/*****************************************************************************
+ * USER I/O ROUTINES *
*****************************************************************************/
/*
- * reltimein - converts a reltime string in an internal format
+ * reltimein - converts a reltime string in an internal format
*/
RelativeTime
reltimein(char *str)
{
- RelativeTime result;
+ RelativeTime result;
- struct tm tt, *tm = &tt;
- double fsec;
- int dtype;
- char *field[MAXDATEFIELDS];
- int nf, ftype[MAXDATEFIELDS];
- char lowstr[MAXDATELEN+1];
+ struct tm tt,
+ *tm = &tt;
+ double fsec;
+ int dtype;
+ char *field[MAXDATEFIELDS];
+ int nf,
+ ftype[MAXDATEFIELDS];
+ char lowstr[MAXDATELEN + 1];
- if (!PointerIsValid(str))
- elog(WARN,"Bad (null) date external representation",NULL);
+ if (!PointerIsValid(str))
+ elog(WARN, "Bad (null) date external representation", NULL);
- if (strlen(str) > MAXDATELEN)
- elog( WARN, "Bad (length) reltime external representation '%s'",str);
+ if (strlen(str) > MAXDATELEN)
+ elog(WARN, "Bad (length) reltime external representation '%s'", str);
- if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeDateDelta( field, ftype, nf, &dtype, tm, &fsec) != 0))
- elog(WARN,"Bad reltime external representation '%s'",str);
+ if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
+ || (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0))
+ elog(WARN, "Bad reltime external representation '%s'", str);
#ifdef DATEDEBUG
-printf( "reltimein- %d fields are type %d (DTK_DATE=%d)\n", nf, dtype, DTK_DATE);
+ printf("reltimein- %d fields are type %d (DTK_DATE=%d)\n", nf, dtype, DTK_DATE);
#endif
- switch (dtype) {
- case DTK_DELTA:
- result = ((((tm->tm_hour*60)+tm->tm_min)*60)+tm->tm_sec);
- result += (((tm->tm_year*365)+(tm->tm_mon*30)+tm->tm_mday)*(24*60*60));
- return(result);
+ switch (dtype)
+ {
+ case DTK_DELTA:
+ result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec);
+ result += (((tm->tm_year * 365) + (tm->tm_mon * 30) + tm->tm_mday) * (24 * 60 * 60));
+ return (result);
- default:
- return(INVALID_RELTIME);
- }
+ default:
+ return (INVALID_RELTIME);
+ }
- elog(WARN,"Bad reltime (internal coding error) '%s'",str);
- return(INVALID_RELTIME);
-} /* reltimein() */
+ elog(WARN, "Bad reltime (internal coding error) '%s'", str);
+ return (INVALID_RELTIME);
+} /* reltimein() */
/*
- * reltimeout - converts the internal format to a reltime string
+ * reltimeout - converts the internal format to a reltime string
*/
-char *reltimeout(int32 time)
+char *
+reltimeout(int32 time)
{
- char *result;
- struct tm tt, *tm = &tt;
- char buf[MAXDATELEN+1];
+ char *result;
+ struct tm tt,
+ *tm = &tt;
+ char buf[MAXDATELEN + 1];
- if (time == INVALID_RELTIME) {
- strcpy( buf, INVALID_RELTIME_STR);
+ if (time == INVALID_RELTIME)
+ {
+ strcpy(buf, INVALID_RELTIME_STR);
- } else {
- reltime2tm(time, tm);
- EncodeTimeSpan( tm, 0, DateStyle, buf);
- }
+ }
+ else
+ {
+ reltime2tm(time, tm);
+ EncodeTimeSpan(tm, 0, DateStyle, buf);
+ }
- result = PALLOC(strlen(buf)+1);
- strcpy( result, buf);
+ result = PALLOC(strlen(buf) + 1);
+ strcpy(result, buf);
- return(result);
-} /* reltimeout() */
+ return (result);
+} /* reltimeout() */
#define TMODULO(t,q,u) {q = (t / u); \
- if (q != 0) t -= (q * u);}
+ if (q != 0) t -= (q * u);}
static void
-reltime2tm(int32 time, struct tm *tm)
+reltime2tm(int32 time, struct tm * tm)
{
- TMODULO(time, tm->tm_year, 31536000);
- TMODULO(time, tm->tm_mon, 2592000);
- TMODULO(time, tm->tm_mday, 86400);
- TMODULO(time, tm->tm_hour, 3600);
- TMODULO(time, tm->tm_min, 60);
- TMODULO(time, tm->tm_sec, 1);
+ TMODULO(time, tm->tm_year, 31536000);
+ TMODULO(time, tm->tm_mon, 2592000);
+ TMODULO(time, tm->tm_mday, 86400);
+ TMODULO(time, tm->tm_hour, 3600);
+ TMODULO(time, tm->tm_min, 60);
+ TMODULO(time, tm->tm_sec, 1);
- return;
-} /* reltime2tm() */
+ return;
+} /* reltime2tm() */
#if FALSE
- char *timestring;
- long quantity;
- register int i;
- int unitnr;
-
- timestring = (char *) palloc(Max(strlen(INVALID_RELTIME_STR),
- UNITMAXLEN) + 1);
- if (timevalue == INVALID_RELTIME) {
- strcpy(timestring,INVALID_RELTIME_STR);
- return(timestring);
- }
- if (timevalue == 0)
- i = 1; /* unit = 'seconds' */
- else
- for (i = 12; i >= 0; i = i-2)
- if ((timevalue % sec_tab[i]) == 0)
- break; /* appropriate unit found */
- unitnr = i;
- quantity = (timevalue / sec_tab[unitnr]);
- if (quantity > 1 || quantity < -1)
- unitnr++; /* adjust index for PLURAL of unit */
- if (quantity >= 0)
- sprintf( timestring, "%c %lu %s", RELTIME_LABEL,
- quantity, unit_tab[unitnr]);
- else
- sprintf( timestring, "%c %lu %s %s", RELTIME_LABEL,
- (quantity * -1), unit_tab[unitnr], RELTIME_PAST);
- return(timestring);
+char *timestring;
+long quantity;
+register int i;
+int unitnr;
+
+timestring = (char *) palloc(Max(strlen(INVALID_RELTIME_STR),
+ UNITMAXLEN) + 1);
+if (timevalue == INVALID_RELTIME)
+{
+ strcpy(timestring, INVALID_RELTIME_STR);
+ return (timestring);
+}
+
+if (timevalue == 0)
+ i = 1; /* unit = 'seconds' */
+else
+ for (i = 12; i >= 0; i = i - 2)
+ if ((timevalue % sec_tab[i]) == 0)
+ break; /* appropriate unit found */
+unitnr = i;
+quantity = (timevalue / sec_tab[unitnr]);
+if (quantity > 1 || quantity < -1)
+ unitnr++; /* adjust index for PLURAL of unit */
+if (quantity >= 0)
+ sprintf(timestring, "%c %lu %s", RELTIME_LABEL,
+ quantity, unit_tab[unitnr]);
+else
+ sprintf(timestring, "%c %lu %s %s", RELTIME_LABEL,
+ (quantity * -1), unit_tab[unitnr], RELTIME_PAST);
+return (timestring);
}
+
#endif
/*
- * tintervalin - converts an interval string to an internal format
+ * tintervalin - converts an interval string to an internal format
*/
-TimeInterval tintervalin(char *intervalstr)
-{
- int error;
- AbsoluteTime i_start, i_end, t1, t2;
- TimeInterval interval;
-
- interval = (TimeInterval) palloc(sizeof(TimeIntervalData));
- error = istinterval(intervalstr, &t1, &t2);
- if (error == 0)
- interval->status = T_INTERVAL_INVAL;
- if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- interval->status = T_INTERVAL_INVAL; /* undefined */
- else {
- i_start = ABSTIMEMIN(t1, t2);
- i_end = ABSTIMEMAX(t1, t2);
- interval->data[0] = i_start;
- interval->data[1] = i_end;
- interval->status = T_INTERVAL_VALID;
- }
- return(interval);
+TimeInterval
+tintervalin(char *intervalstr)
+{
+ int error;
+ AbsoluteTime i_start,
+ i_end,
+ t1,
+ t2;
+ TimeInterval interval;
+
+ interval = (TimeInterval) palloc(sizeof(TimeIntervalData));
+ error = istinterval(intervalstr, &t1, &t2);
+ if (error == 0)
+ interval->status = T_INTERVAL_INVAL;
+ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
+ interval->status = T_INTERVAL_INVAL; /* undefined */
+ else
+ {
+ i_start = ABSTIMEMIN(t1, t2);
+ i_end = ABSTIMEMAX(t1, t2);
+ interval->data[0] = i_start;
+ interval->data[1] = i_end;
+ interval->status = T_INTERVAL_VALID;
+ }
+ return (interval);
}
/*
- * tintervalout - converts an internal interval format to a string
+ * tintervalout - converts an internal interval format to a string
*
*/
-char *tintervalout(TimeInterval interval)
-{
- char *i_str, *p;
-
- i_str = (char *) palloc( T_INTERVAL_LEN ); /* ['...' '...'] */
- strcpy(i_str,"[\"");
- if (interval->status == T_INTERVAL_INVAL)
- strcat(i_str,INVALID_INTERVAL_STR);
- else {
- p = nabstimeout(interval->data[0]);
- strcat(i_str,p);
- pfree(p);
- strcat(i_str,"\" \"");
- p = nabstimeout(interval->data[1]);
- strcat(i_str,p);
- pfree(p);
- }
- strcat(i_str,"\"]\0");
- return(i_str);
-}
-
-
-/*****************************************************************************
- * PUBLIC ROUTINES *
+char *
+tintervalout(TimeInterval interval)
+{
+ char *i_str,
+ *p;
+
+ i_str = (char *) palloc(T_INTERVAL_LEN); /* ['...' '...'] */
+ strcpy(i_str, "[\"");
+ if (interval->status == T_INTERVAL_INVAL)
+ strcat(i_str, INVALID_INTERVAL_STR);
+ else
+ {
+ p = nabstimeout(interval->data[0]);
+ strcat(i_str, p);
+ pfree(p);
+ strcat(i_str, "\" \"");
+ p = nabstimeout(interval->data[1]);
+ strcat(i_str, p);
+ pfree(p);
+ }
+ strcat(i_str, "\"]\0");
+ return (i_str);
+}
+
+
+/*****************************************************************************
+ * PUBLIC ROUTINES *
*****************************************************************************/
RelativeTime
-timespan_reltime(TimeSpan *timespan)
+timespan_reltime(TimeSpan * timespan)
{
- RelativeTime time;
- int year, month;
- double span;
+ RelativeTime time;
+ int year,
+ month;
+ double span;
- if (!PointerIsValid(timespan))
- time = INVALID_RELTIME;
+ if (!PointerIsValid(timespan))
+ time = INVALID_RELTIME;
- if (TIMESPAN_IS_INVALID(*timespan)) {
- time = INVALID_RELTIME;
+ if (TIMESPAN_IS_INVALID(*timespan))
+ {
+ time = INVALID_RELTIME;
- } else {
- if (timespan->month == 0) {
- year = 0;
- month = 0;
+ }
+ else
+ {
+ if (timespan->month == 0)
+ {
+ year = 0;
+ month = 0;
- } else if (abs(timespan->month) >= 12) {
- year = (timespan->month / 12);
- month = (timespan->month % 12);
+ }
+ else if (abs(timespan->month) >= 12)
+ {
+ year = (timespan->month / 12);
+ month = (timespan->month % 12);
- } else {
- year = 0;
- month = timespan->month;
- }
+ }
+ else
+ {
+ year = 0;
+ month = timespan->month;
+ }
- span = (((((double) 365*year)+((double) 30*month))*86400) + timespan->time);
+ span = (((((double) 365 * year) + ((double) 30 * month)) * 86400) + timespan->time);
#ifdef DATEDEBUG
-printf( "timespan_reltime- convert m%d s%f to %f [%d %d]\n",
- timespan->month, timespan->time, span, INT_MIN, INT_MAX);
+ printf("timespan_reltime- convert m%d s%f to %f [%d %d]\n",
+ timespan->month, timespan->time, span, INT_MIN, INT_MAX);
#endif
- time = (((span > INT_MIN) && (span < INT_MAX))? span: INVALID_RELTIME);
- }
+ time = (((span > INT_MIN) && (span < INT_MAX)) ? span : INVALID_RELTIME);
+ }
- return(time);
-} /* timespan_reltime() */
+ return (time);
+} /* timespan_reltime() */
-TimeSpan *
+TimeSpan *
reltime_timespan(RelativeTime reltime)
{
- TimeSpan *result;
- int year, month;
+ TimeSpan *result;
+ int year,
+ month;
- if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
- elog(WARN,"Memory allocation failed, can't convert reltime to timespan",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
+ elog(WARN, "Memory allocation failed, can't convert reltime to timespan", NULL);
- switch(reltime) {
- case INVALID_RELTIME:
- TIMESPAN_INVALID(*result);
- break;
+ switch (reltime)
+ {
+ case INVALID_RELTIME:
+ TIMESPAN_INVALID(*result);
+ break;
- default:
- TMODULO(reltime, year, 31536000);
- TMODULO(reltime, month, 2592000);
+ default:
+ TMODULO(reltime, year, 31536000);
+ TMODULO(reltime, month, 2592000);
- result->time = reltime;
- result->month = ((12*year)+month);
- }
+ result->time = reltime;
+ result->month = ((12 * year) + month);
+ }
- return(result);
-} /* reltime_timespan() */
+ return (result);
+} /* reltime_timespan() */
/*
- * mktinterval - creates a time interval with endpoints t1 and t2
+ * mktinterval - creates a time interval with endpoints t1 and t2
*/
-TimeInterval mktinterval(AbsoluteTime t1, AbsoluteTime t2)
+TimeInterval
+mktinterval(AbsoluteTime t1, AbsoluteTime t2)
{
- AbsoluteTime tstart = ABSTIMEMIN(t1, t2), tend = ABSTIMEMAX(t1, t2);
- TimeInterval interval;
-
- interval = (TimeInterval) palloc(sizeof(TimeIntervalData));
- if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- interval->status = T_INTERVAL_INVAL;
- else {
- interval->status = T_INTERVAL_VALID;
- interval->data[0] = tstart;
- interval->data[1] = tend;
- }
-
- return interval;
+ AbsoluteTime tstart = ABSTIMEMIN(t1, t2),
+ tend = ABSTIMEMAX(t1, t2);
+ TimeInterval interval;
+
+ interval = (TimeInterval) palloc(sizeof(TimeIntervalData));
+ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
+ interval->status = T_INTERVAL_INVAL;
+ else
+ {
+ interval->status = T_INTERVAL_VALID;
+ interval->data[0] = tstart;
+ interval->data[1] = tend;
+ }
+
+ return interval;
}
/*
- * timepl, timemi and abstimemi use the formula
- * abstime + reltime = abstime
- * so abstime - reltime = abstime
- * and abstime - abstime = reltime
+ * timepl, timemi and abstimemi use the formula
+ * abstime + reltime = abstime
+ * so abstime - reltime = abstime
+ * and abstime - abstime = reltime
*/
/*
- * timepl - returns the value of (abstime t1 + relime t2)
+ * timepl - returns the value of (abstime t1 + relime t2)
*/
-AbsoluteTime timepl(AbsoluteTime t1, RelativeTime t2)
+AbsoluteTime
+timepl(AbsoluteTime t1, RelativeTime t2)
{
- if (t1 == CURRENT_ABSTIME)
- t1 = GetCurrentTransactionStartTime();
-
- if (AbsoluteTimeIsReal(t1) &&
- RelativeTimeIsValid(t2) &&
- ((t2 > 0) ? (t1 < NOEND_ABSTIME - t2)
- : (t1 > NOSTART_ABSTIME - t2))) /* prevent overflow */
- return (t1 + t2);
-
- return(INVALID_ABSTIME);
+ if (t1 == CURRENT_ABSTIME)
+ t1 = GetCurrentTransactionStartTime();
+
+ if (AbsoluteTimeIsReal(t1) &&
+ RelativeTimeIsValid(t2) &&
+ ((t2 > 0) ? (t1 < NOEND_ABSTIME - t2)
+ : (t1 > NOSTART_ABSTIME - t2))) /* prevent overflow */
+ return (t1 + t2);
+
+ return (INVALID_ABSTIME);
}
/*
- * timemi - returns the value of (abstime t1 - reltime t2)
+ * timemi - returns the value of (abstime t1 - reltime t2)
*/
-AbsoluteTime timemi(AbsoluteTime t1, RelativeTime t2)
+AbsoluteTime
+timemi(AbsoluteTime t1, RelativeTime t2)
{
- if (t1 == CURRENT_ABSTIME)
- t1 = GetCurrentTransactionStartTime();
-
- if (AbsoluteTimeIsReal(t1) &&
- RelativeTimeIsValid(t2) &&
- ((t2 > 0) ? (t1 > NOSTART_ABSTIME + t2)
- : (t1 < NOEND_ABSTIME + t2))) /* prevent overflow */
- return (t1 - t2);
-
- return(INVALID_ABSTIME);
+ if (t1 == CURRENT_ABSTIME)
+ t1 = GetCurrentTransactionStartTime();
+
+ if (AbsoluteTimeIsReal(t1) &&
+ RelativeTimeIsValid(t2) &&
+ ((t2 > 0) ? (t1 > NOSTART_ABSTIME + t2)
+ : (t1 < NOEND_ABSTIME + t2))) /* prevent overflow */
+ return (t1 - t2);
+
+ return (INVALID_ABSTIME);
}
/*
- * abstimemi - returns the value of (abstime t1 - abstime t2)
+ * abstimemi - returns the value of (abstime t1 - abstime t2)
*/
-static RelativeTime abstimemi(AbsoluteTime t1, AbsoluteTime t2)
+static RelativeTime
+abstimemi(AbsoluteTime t1, AbsoluteTime t2)
{
- if (t1 == CURRENT_ABSTIME)
- t1 = GetCurrentTransactionStartTime();
- if (t2 == CURRENT_ABSTIME)
- t2 = GetCurrentTransactionStartTime();
-
- if (AbsoluteTimeIsReal(t1) &&
- AbsoluteTimeIsReal(t2))
- return (t1 - t2);
-
- return(INVALID_RELTIME);
+ if (t1 == CURRENT_ABSTIME)
+ t1 = GetCurrentTransactionStartTime();
+ if (t2 == CURRENT_ABSTIME)
+ t2 = GetCurrentTransactionStartTime();
+
+ if (AbsoluteTimeIsReal(t1) &&
+ AbsoluteTimeIsReal(t2))
+ return (t1 - t2);
+
+ return (INVALID_RELTIME);
}
/*
- * ininterval - returns 1, iff absolute date is in the interval
+ * ininterval - returns 1, iff absolute date is in the interval
*/
-int ininterval(AbsoluteTime t, TimeInterval interval)
+int
+ininterval(AbsoluteTime t, TimeInterval interval)
{
- if (interval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME)
- return (abstimege(t, interval->data[0]) &&
- abstimele(t, interval->data[1]));
- return(0);
+ if (interval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME)
+ return (abstimege(t, interval->data[0]) &&
+ abstimele(t, interval->data[1]));
+ return (0);
}
/*
- * intervalrel - returns relative time corresponding to interval
+ * intervalrel - returns relative time corresponding to interval
*/
-RelativeTime intervalrel(TimeInterval interval)
+RelativeTime
+intervalrel(TimeInterval interval)
{
- if (interval->status == T_INTERVAL_VALID)
- return(abstimemi(interval->data[1], interval->data[0]));
- else
- return(INVALID_RELTIME);
+ if (interval->status == T_INTERVAL_VALID)
+ return (abstimemi(interval->data[1], interval->data[0]));
+ else
+ return (INVALID_RELTIME);
}
/*
- * timenow - returns time "now", internal format
+ * timenow - returns time "now", internal format
*
- * Now AbsoluteTime is time since Jan 1 1970 -mer 7 Feb 1992
+ * Now AbsoluteTime is time since Jan 1 1970 -mer 7 Feb 1992
*/
-AbsoluteTime timenow()
+AbsoluteTime
+timenow()
{
- time_t sec;
- if (time(&sec) < 0)
- return(INVALID_ABSTIME);
- return((AbsoluteTime) sec);
+ time_t sec;
+
+ if (time(&sec) < 0)
+ return (INVALID_ABSTIME);
+ return ((AbsoluteTime) sec);
}
/*
- * reltimeeq - returns 1, iff arguments are equal
- * reltimene - returns 1, iff arguments are not equal
- * reltimelt - returns 1, iff t1 less than t2
- * reltimegt - returns 1, iff t1 greater than t2
- * reltimele - returns 1, iff t1 less than or equal to t2
- * reltimege - returns 1, iff t1 greater than or equal to t2
+ * reltimeeq - returns 1, iff arguments are equal
+ * reltimene - returns 1, iff arguments are not equal
+ * reltimelt - returns 1, iff t1 less than t2
+ * reltimegt - returns 1, iff t1 greater than t2
+ * reltimele - returns 1, iff t1 less than or equal to t2
+ * reltimege - returns 1, iff t1 greater than or equal to t2
*/
-bool reltimeeq(RelativeTime t1, RelativeTime t2)
+bool
+reltimeeq(RelativeTime t1, RelativeTime t2)
{
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- return 0;
- return(t1 == t2);
+ if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
+ return 0;
+ return (t1 == t2);
}
-bool reltimene(RelativeTime t1, RelativeTime t2)
+bool
+reltimene(RelativeTime t1, RelativeTime t2)
{
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- return 0;
- return(t1 != t2);
+ if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
+ return 0;
+ return (t1 != t2);
}
-bool reltimelt(RelativeTime t1, RelativeTime t2)
+bool
+reltimelt(RelativeTime t1, RelativeTime t2)
{
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- return 0;
- return(t1 < t2);
+ if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
+ return 0;
+ return (t1 < t2);
}
-bool reltimegt(RelativeTime t1, RelativeTime t2)
+bool
+reltimegt(RelativeTime t1, RelativeTime t2)
{
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- return 0;
- return(t1 > t2);
+ if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
+ return 0;
+ return (t1 > t2);
}
-bool reltimele(RelativeTime t1, RelativeTime t2)
+bool
+reltimele(RelativeTime t1, RelativeTime t2)
{
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- return 0;
- return(t1 <= t2);
+ if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
+ return 0;
+ return (t1 <= t2);
}
-bool reltimege(RelativeTime t1, RelativeTime t2)
+bool
+reltimege(RelativeTime t1, RelativeTime t2)
{
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- return 0;
- return(t1 >= t2);
+ if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
+ return 0;
+ return (t1 >= t2);
}
/*
- * intervaleq - returns 1, iff interval i1 is equal to interval i2
+ * intervaleq - returns 1, iff interval i1 is equal to interval i2
*/
-bool intervaleq(TimeInterval i1, TimeInterval i2)
+bool
+intervaleq(TimeInterval i1, TimeInterval i2)
{
- if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
- return(0); /* invalid interval */
- return(abstimeeq(i1->data[0], i2->data[0]) &&
- abstimeeq(i1->data[1], i2->data[1]));
+ if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
+ return (0); /* invalid interval */
+ return (abstimeeq(i1->data[0], i2->data[0]) &&
+ abstimeeq(i1->data[1], i2->data[1]));
}
/*
- * intervalleneq - returns 1, iff length of interval i is equal to
- * reltime t
+ * intervalleneq - returns 1, iff length of interval i is equal to
+ * reltime t
*/
-bool intervalleneq(TimeInterval i, RelativeTime t)
+bool
+intervalleneq(TimeInterval i, RelativeTime t)
{
- RelativeTime rt;
-
- if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
- return(0);
- rt = intervalrel(i);
- return (rt != INVALID_RELTIME && rt == t);
+ RelativeTime rt;
+
+ if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
+ return (0);
+ rt = intervalrel(i);
+ return (rt != INVALID_RELTIME && rt == t);
}
/*
- * intervallenne - returns 1, iff length of interval i is not equal
- * to reltime t
+ * intervallenne - returns 1, iff length of interval i is not equal
+ * to reltime t
*/
-bool intervallenne(TimeInterval i, RelativeTime t)
+bool
+intervallenne(TimeInterval i, RelativeTime t)
{
- RelativeTime rt;
-
- if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
- return(0);
- rt = intervalrel(i);
- return (rt != INVALID_RELTIME && rt != t);
+ RelativeTime rt;
+
+ if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
+ return (0);
+ rt = intervalrel(i);
+ return (rt != INVALID_RELTIME && rt != t);
}
/*
- * intervallenlt - returns 1, iff length of interval i is less than
- * reltime t
+ * intervallenlt - returns 1, iff length of interval i is less than
+ * reltime t
*/
-bool intervallenlt(TimeInterval i, RelativeTime t)
+bool
+intervallenlt(TimeInterval i, RelativeTime t)
{
- RelativeTime rt;
-
- if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
- return(0);
- rt = intervalrel(i);
- return (rt != INVALID_RELTIME && rt < t);
+ RelativeTime rt;
+
+ if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
+ return (0);
+ rt = intervalrel(i);
+ return (rt != INVALID_RELTIME && rt < t);
}
/*
- * intervallengt - returns 1, iff length of interval i is greater than
- * reltime t
+ * intervallengt - returns 1, iff length of interval i is greater than
+ * reltime t
*/
-bool intervallengt(TimeInterval i, RelativeTime t)
+bool
+intervallengt(TimeInterval i, RelativeTime t)
{
- RelativeTime rt;
-
- if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
- return(0);
- rt = intervalrel(i);
- return (rt != INVALID_RELTIME && rt > t);
+ RelativeTime rt;
+
+ if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
+ return (0);
+ rt = intervalrel(i);
+ return (rt != INVALID_RELTIME && rt > t);
}
/*
- * intervallenle - returns 1, iff length of interval i is less or equal
- * than reltime t
+ * intervallenle - returns 1, iff length of interval i is less or equal
+ * than reltime t
*/
-bool intervallenle(TimeInterval i, RelativeTime t)
-{
- RelativeTime rt;
-
- if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
- return(0);
- rt = intervalrel(i);
- return (rt != INVALID_RELTIME && rt <= t);
+bool
+intervallenle(TimeInterval i, RelativeTime t)
+{
+ RelativeTime rt;
+
+ if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
+ return (0);
+ rt = intervalrel(i);
+ return (rt != INVALID_RELTIME && rt <= t);
}
/*
- * intervallenge - returns 1, iff length of interval i is greater or
- * equal than reltime t
+ * intervallenge - returns 1, iff length of interval i is greater or
+ * equal than reltime t
*/
-bool intervallenge(TimeInterval i, RelativeTime t)
+bool
+intervallenge(TimeInterval i, RelativeTime t)
{
- RelativeTime rt;
-
- if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
- return(0);
- rt = intervalrel(i);
- return (rt != INVALID_RELTIME && rt >= t);
+ RelativeTime rt;
+
+ if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
+ return (0);
+ rt = intervalrel(i);
+ return (rt != INVALID_RELTIME && rt >= t);
}
/*
- * intervalct - returns 1, iff interval i1 contains interval i2
+ * intervalct - returns 1, iff interval i1 contains interval i2
*/
-bool intervalct(TimeInterval i1, TimeInterval i2)
+bool
+intervalct(TimeInterval i1, TimeInterval i2)
{
- if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
- return(0);
- return(abstimele(i1->data[0], i2->data[0]) &&
- abstimege(i1->data[1], i2->data[1]));
+ if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
+ return (0);
+ return (abstimele(i1->data[0], i2->data[0]) &&
+ abstimege(i1->data[1], i2->data[1]));
}
/*
- * intervalov - returns 1, iff interval i1 (partially) overlaps i2
+ * intervalov - returns 1, iff interval i1 (partially) overlaps i2
*/
-bool intervalov(TimeInterval i1, TimeInterval i2)
+bool
+intervalov(TimeInterval i1, TimeInterval i2)
{
- if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
- return(0);
- return(! (abstimelt(i1->data[1], i2->data[0]) ||
- abstimegt(i1->data[0], i2->data[1])));
+ if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
+ return (0);
+ return (!(abstimelt(i1->data[1], i2->data[0]) ||
+ abstimegt(i1->data[0], i2->data[1])));
}
/*
- * intervalstart - returns the start of interval i
+ * intervalstart - returns the start of interval i
*/
-AbsoluteTime intervalstart(TimeInterval i)
+AbsoluteTime
+intervalstart(TimeInterval i)
{
- if (i->status == T_INTERVAL_INVAL)
- return INVALID_ABSTIME;
- return(i->data[0]);
+ if (i->status == T_INTERVAL_INVAL)
+ return INVALID_ABSTIME;
+ return (i->data[0]);
}
/*
- * intervalend - returns the end of interval i
+ * intervalend - returns the end of interval i
*/
-AbsoluteTime intervalend(TimeInterval i)
+AbsoluteTime
+intervalend(TimeInterval i)
{
- if (i->status == T_INTERVAL_INVAL)
- return INVALID_ABSTIME;
- return(i->data[1]);
+ if (i->status == T_INTERVAL_INVAL)
+ return INVALID_ABSTIME;
+ return (i->data[1]);
}
-/*****************************************************************************
- * PRIVATE ROUTINES *
+/*****************************************************************************
+ * PRIVATE ROUTINES *
*****************************************************************************/
/*
- * isreltime - returns 1, iff datestring is of type reltime
- * 2, iff datestring is 'invalid time' identifier
- * 0, iff datestring contains a syntax error
- * VALID time less or equal +/- `@ 68 years'
+ * isreltime - returns 1, iff datestring is of type reltime
+ * 2, iff datestring is 'invalid time' identifier
+ * 0, iff datestring contains a syntax error
+ * VALID time less or equal +/- `@ 68 years'
*
*/
-int isreltime(char *str)
+int
+isreltime(char *str)
{
- struct tm tt, *tm = &tt;
- double fsec;
- int dtype;
- char *field[MAXDATEFIELDS];
- int nf, ftype[MAXDATEFIELDS];
- char lowstr[MAXDATELEN+1];
-
- if (!PointerIsValid(str))
- return 0;
-
- if (strlen(str) > MAXDATELEN)
- return 0;
-
- if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeDateDelta( field, ftype, nf, &dtype, tm, &fsec) != 0))
- return 0;
+ struct tm tt,
+ *tm = &tt;
+ double fsec;
+ int dtype;
+ char *field[MAXDATEFIELDS];
+ int nf,
+ ftype[MAXDATEFIELDS];
+ char lowstr[MAXDATELEN + 1];
+
+ if (!PointerIsValid(str))
+ return 0;
+
+ if (strlen(str) > MAXDATELEN)
+ return 0;
+
+ if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
+ || (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0))
+ return 0;
+
+ switch (dtype)
+ {
+ case (DTK_DELTA):
+ return ((abs(tm->tm_year) <= 68) ? 1 : 0);
+ break;
- switch (dtype) {
- case (DTK_DELTA):
- return((abs(tm->tm_year) <= 68)? 1: 0);
- break;
+ case (DTK_INVALID):
+ return 2;
+ break;
- case (DTK_INVALID):
- return 2;
- break;
+ default:
+ return 0;
+ break;
+ }
- default:
return 0;
- break;
- }
-
- return 0;
-} /* isreltime() */
+} /* isreltime() */
#if FALSE
- register char *p;
- register char c;
- int i;
- char unit[UNITMAXLEN] ;
- char direction[DIRMAXLEN];
- int localSign;
- int localUnitNumber;
- long localQuantity;
-
- if (!PointerIsValid(sign)) {
+register char *p;
+register char c;
+int i;
+char unit[UNITMAXLEN];
+char direction[DIRMAXLEN];
+int localSign;
+int localUnitNumber;
+long localQuantity;
+
+if (!PointerIsValid(sign))
+{
sign = &localSign;
- }
- if (!PointerIsValid(unitnr)) {
+}
+
+if (!PointerIsValid(unitnr))
+{
unitnr = &localUnitNumber;
- }
- if (!PointerIsValid(quantity)) {
+}
+
+if (!PointerIsValid(quantity))
+{
quantity = &localQuantity;
- }
- unit[0] = '\0';
- direction[0] = '\0';
- p = timestring;
- /* skip leading blanks */
- while ((c = *p) != '\0') {
+}
+
+unit[0] = '\0';
+direction[0] = '\0';
+p = timestring;
+ /* skip leading blanks */
+while ((c = *p) != '\0')
+{
if (c != ' ')
- break;
+ break;
p++;
- }
- /* Test whether 'invalid time' identifier or not */
- if (!strncmp(INVALID_RELTIME_STR,p,strlen(INVALID_RELTIME_STR) + 1))
- return(2); /* correct 'invalid time' identifier found */
-
- /* handle label of relative time */
- if (c != RELTIME_LABEL)
- return(0); /*syntax error*/
- c = *++p;
- if (c != ' ') return(0); /*syntax error*/
- p++;
- /* handle the quantity */
- *quantity = 0;
- for (;;) {
+}
+
+ /* Test whether 'invalid time' identifier or not */
+if (!strncmp(INVALID_RELTIME_STR, p, strlen(INVALID_RELTIME_STR) + 1))
+ return (2); /* correct 'invalid time' identifier found */
+
+ /* handle label of relative time */
+if (c != RELTIME_LABEL)
+ return (0); /* syntax error */
+c = *++p;
+if (c != ' ')
+ return (0); /* syntax error */
+p++;
+ /* handle the quantity */
+*quantity = 0;
+for (;;)
+{
c = *p;
- if (isdigit(c)) {
- *quantity = *quantity * 10 + (c -'0');
- p++;
- } else {
- if (c == ' ' )
- break; /* correct quantity found */
- else
- return(0); /* syntax error */
+ if (isdigit(c))
+ {
+ *quantity = *quantity * 10 + (c - '0');
+ p++;
+ }
+ else
+ {
+ if (c == ' ')
+ break; /* correct quantity found */
+ else
+ return (0); /* syntax error */
}
- }
- /* handle unit */
- p++;
- i = 0;
- for (;;) {
+}
+
+ /* handle unit */
+p++;
+i = 0;
+for (;;)
+{
c = *p;
- if (c >= 'a' && c <= 'z' && i <= (UNITMAXLEN - 1)) {
- unit[i] = c;
- p++;
- i++;
- } else {
- if ((c == ' ' || c == '\0')
- && correct_unit(unit, unitnr))
- break; /* correct unit found */
- else
- return(0); /* syntax error */
+ if (c >= 'a' && c <= 'z' && i <= (UNITMAXLEN - 1))
+ {
+ unit[i] = c;
+ p++;
+ i++;
+ }
+ else
+ {
+ if ((c == ' ' || c == '\0')
+ && correct_unit(unit, unitnr))
+ break; /* correct unit found */
+ else
+ return (0); /* syntax error */
}
- }
- /* handle optional direction */
- if (c == ' ')
+}
+
+ /* handle optional direction */
+if (c == ' ')
p++;
- i = 0;
- *sign = 1;
- for (;;) {
+i = 0;
+*sign = 1;
+for (;;)
+{
c = *p;
- if (c >= 'a' && c <= 'z' && i <= (DIRMAXLEN - 1)) {
- direction[i] = c;
- p++;
- i++;
- } else {
- if ((c == ' ' || c == '\0') && i == 0) {
- *sign = 1;
- break; /* no direction specified */
- }
- if ((c == ' ' || c == '\0') && i != 0)
+ if (c >= 'a' && c <= 'z' && i <= (DIRMAXLEN - 1))
+ {
+ direction[i] = c;
+ p++;
+ i++;
+ }
+ else
+ {
+ if ((c == ' ' || c == '\0') && i == 0)
{
- direction[i] = '\0';
- correct_dir(direction, sign);
- break; /* correct direction found */
+ *sign = 1;
+ break; /* no direction specified */
}
- else
- return(0); /* syntax error*/
+ if ((c == ' ' || c == '\0') && i != 0)
+ {
+ direction[i] = '\0';
+ correct_dir(direction, sign);
+ break; /* correct direction found */
+ }
+ else
+ return (0); /* syntax error */
}
- }
- return(1);
+}
+
+return (1);
}
/*
- * correct_unit - returns 1, iff unit is a correct unit description
+ * correct_unit - returns 1, iff unit is a correct unit description
*
- * output parameter:
- * unptr: points to an integer which is the appropriate unit number
- * (see function isreltime())
- */
-static int correct_unit(char unit[], int *unptr)
-{
- int j = 0;
-
- while (j < NUNITS) {
- if (strncmp(unit, unit_tab[j], strlen(unit_tab[j])) == 0) {
- *unptr = j;
- return(1);
+ * output parameter:
+ * unptr: points to an integer which is the appropriate unit number
+ * (see function isreltime())
+ */
+static int
+correct_unit(char unit[], int *unptr)
+{
+ int j = 0;
+
+ while (j < NUNITS)
+ {
+ if (strncmp(unit, unit_tab[j], strlen(unit_tab[j])) == 0)
+ {
+ *unptr = j;
+ return (1);
+ }
+ j++;
}
- j++;
- }
- return (0); /* invalid unit descriptor */
+ return (0); /* invalid unit descriptor */
}
/*
- * correct_dir - returns 1, iff direction is a correct identifier
+ * correct_dir - returns 1, iff direction is a correct identifier
*
- * output parameter:
- * signptr: points to -1 if dir corresponds to past tense
- * else to 1
- */
-static int correct_dir(char direction[], int *signptr)
-{
- *signptr = 1;
- if (strncmp(RELTIME_PAST, direction, strlen(RELTIME_PAST)+1) == 0)
+ * output parameter:
+ * signptr: points to -1 if dir corresponds to past tense
+ * else to 1
+ */
+static int
+correct_dir(char direction[], int *signptr)
+{
+ *signptr = 1;
+ if (strncmp(RELTIME_PAST, direction, strlen(RELTIME_PAST) + 1) == 0)
{
- *signptr = -1;
- return(1);
- } else
- return (0); /* invalid direction descriptor */
+ *signptr = -1;
+ return (1);
+ }
+ else
+ return (0); /* invalid direction descriptor */
}
+
#endif
/*
- * istinterval - returns 1, iff i_string is a valid interval descr.
- * 0, iff i_string is NOT a valid interval desc.
- * 2, iff any time is INVALID_ABSTIME
+ * istinterval - returns 1, iff i_string is a valid interval descr.
+ * 0, iff i_string is NOT a valid interval desc.
+ * 2, iff any time is INVALID_ABSTIME
*
- * output parameter:
- * i_start, i_end: interval margins
+ * output parameter:
+ * i_start, i_end: interval margins
*
- * Time interval:
- * `[' {` '} `'' <AbsTime> `'' {` '} `'' <AbsTime> `'' {` '} `]'
+ * Time interval:
+ * `[' {` '} `'' <AbsTime> `'' {` '} `'' <AbsTime> `'' {` '} `]'
*
- * OR `Undefined Range' (see also INVALID_INTERVAL_STR)
+ * OR `Undefined Range' (see also INVALID_INTERVAL_STR)
*
- * where <AbsTime> satisfies the syntax of absolute time.
+ * where <AbsTime> satisfies the syntax of absolute time.
*
- * e.g. [ ' Jan 18 1902' 'Jan 1 00:00:00 1970']
- */
-static int istinterval(char *i_string,
- AbsoluteTime *i_start,
- AbsoluteTime *i_end)
-{
- register char *p,*p1;
- register char c;
-
- p = i_string;
- /* skip leading blanks up to '[' */
- while ((c = *p) != '\0') {
- if ( IsSpace(c))
- p++;
- else if (c != '[')
- return(0); /* syntax error */
- else
- break;
- }
- p++;
- /* skip leading blanks up to "'" */
- while ((c = *p) != '\0') {
- if (IsSpace(c))
- p++;
- else if (c != '"')
- return (0); /* syntax error */
- else
- break;
- }
- p++;
- if (strncmp(INVALID_INTERVAL_STR,p,strlen(INVALID_INTERVAL_STR)) == 0)
- return(0); /* undefined range, handled like a syntax err.*/
- /* search for the end of the first date and change it to a NULL*/
- p1 = p;
- while ((c = *p1) != '\0') {
- if ( c == '"') {
- *p1 = '\0';
- break;
+ * e.g. [ ' Jan 18 1902' 'Jan 1 00:00:00 1970']
+ */
+static int
+istinterval(char *i_string,
+ AbsoluteTime * i_start,
+ AbsoluteTime * i_end)
+{
+ register char *p,
+ *p1;
+ register char c;
+
+ p = i_string;
+ /* skip leading blanks up to '[' */
+ while ((c = *p) != '\0')
+ {
+ if (IsSpace(c))
+ p++;
+ else if (c != '[')
+ return (0); /* syntax error */
+ else
+ break;
}
- p1++;
- }
- /* get the first date */
- *i_start = nabstimein(p); /* first absolute date */
- /* rechange NULL at the end of the first date to a "'" */
- *p1 = '"';
- p = ++p1;
- /* skip blanks up to "'", beginning of second date*/
- while ((c = *p) != '\0') {
- if (IsSpace(c))
- p++;
- else if (c != '"')
- return (0); /* syntax error */
- else
- break;
- }
- p++;
- /* search for the end of the second date and change it to a NULL*/
- p1 = p;
- while ((c = *p1) != '\0') {
- if ( c == '"') {
- *p1 = '\0';
- break;
+ p++;
+ /* skip leading blanks up to "'" */
+ while ((c = *p) != '\0')
+ {
+ if (IsSpace(c))
+ p++;
+ else if (c != '"')
+ return (0); /* syntax error */
+ else
+ break;
}
- p1++;
- }
- /* get the second date */
- *i_end = nabstimein(p); /* second absolute date */
- /* rechange NULL at the end of the first date to a ''' */
- *p1 = '"';
- p = ++p1;
- /* skip blanks up to ']'*/
- while ((c = *p) != '\0') {
- if ( IsSpace(c))
- p++;
- else if (c != ']')
- return(0); /*syntax error */
- else
- break;
- }
- p++;
- c = *p;
- if ( c != '\0' )
- return (0); /* syntax error */
- /* it seems to be a valid interval */
- return(1);
+ p++;
+ if (strncmp(INVALID_INTERVAL_STR, p, strlen(INVALID_INTERVAL_STR)) == 0)
+ return (0); /* undefined range, handled like a syntax
+ * err. */
+ /* search for the end of the first date and change it to a NULL */
+ p1 = p;
+ while ((c = *p1) != '\0')
+ {
+ if (c == '"')
+ {
+ *p1 = '\0';
+ break;
+ }
+ p1++;
+ }
+ /* get the first date */
+ *i_start = nabstimein(p); /* first absolute date */
+ /* rechange NULL at the end of the first date to a "'" */
+ *p1 = '"';
+ p = ++p1;
+ /* skip blanks up to "'", beginning of second date */
+ while ((c = *p) != '\0')
+ {
+ if (IsSpace(c))
+ p++;
+ else if (c != '"')
+ return (0); /* syntax error */
+ else
+ break;
+ }
+ p++;
+ /* search for the end of the second date and change it to a NULL */
+ p1 = p;
+ while ((c = *p1) != '\0')
+ {
+ if (c == '"')
+ {
+ *p1 = '\0';
+ break;
+ }
+ p1++;
+ }
+ /* get the second date */
+ *i_end = nabstimein(p); /* second absolute date */
+ /* rechange NULL at the end of the first date to a ''' */
+ *p1 = '"';
+ p = ++p1;
+ /* skip blanks up to ']' */
+ while ((c = *p) != '\0')
+ {
+ if (IsSpace(c))
+ p++;
+ else if (c != ']')
+ return (0); /* syntax error */
+ else
+ break;
+ }
+ p++;
+ c = *p;
+ if (c != '\0')
+ return (0); /* syntax error */
+ /* it seems to be a valid interval */
+ return (1);
}
@@ -946,30 +1053,30 @@ static int istinterval(char *i_string,
/*
* timeofday -
- * returns the current time as a text. similar to timenow() but returns
- * seconds with more precision (up to microsecs). (I need this to compare
- * the Wisconsin benchmark with Illustra whose TimeNow() shows current
- * time with precision up to microsecs.) - ay 3/95
+ * returns the current time as a text. similar to timenow() but returns
+ * seconds with more precision (up to microsecs). (I need this to compare
+ * the Wisconsin benchmark with Illustra whose TimeNow() shows current
+ * time with precision up to microsecs.) - ay 3/95
*/
-text *
+text *
timeofday(void)
{
- struct timeval tp;
- struct timezone tpz;
- char templ[500];
- char buf[500];
- text *tm;
- int len = 0;
-
- gettimeofday(&tp, &tpz);
- strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%d %Y %Z",
- localtime((time_t *) &tp.tv_sec));
- sprintf(buf, templ, tp.tv_usec);
-
- len = VARHDRSZ + strlen(buf);
- tm = (text *)palloc(len);
- VARSIZE(tm) = len;
- strncpy(VARDATA(tm), buf, strlen(buf));
- return tm;
+ struct timeval tp;
+ struct timezone tpz;
+ char templ[500];
+ char buf[500];
+ text *tm;
+ int len = 0;
+
+ gettimeofday(&tp, &tpz);
+ strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%d %Y %Z",
+ localtime((time_t *) & tp.tv_sec));
+ sprintf(buf, templ, tp.tv_usec);
+
+ len = VARHDRSZ + strlen(buf);
+ tm = (text *) palloc(len);
+ VARSIZE(tm) = len;
+ strncpy(VARDATA(tm), buf, strlen(buf));
+ return tm;
}
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 9809ebf5f11..a88bea36e9c 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* datetime.c--
- * implements DATE and TIME data types specified in SQL-92 standard
+ * implements DATE and TIME data types specified in SQL-92 standard
*
* Copyright (c) 1994-5, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.13 1997/09/05 18:11:10 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.14 1997/09/07 04:50:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include <limits.h>
@@ -25,12 +25,12 @@
#include "utils/datetime.h"
#include "access/xact.h"
-static int date2tm(DateADT dateVal, int *tzp, struct tm *tm, double *fsec, char **tzn);
+static int date2tm(DateADT dateVal, int *tzp, struct tm * tm, double *fsec, char **tzn);
-static int day_tab[2][12] = {
- {31,28,31,30,31,30,31,31,30,31,30,31},
- {31,29,31,30,31,30,31,31,30,31,30,31} };
+static int day_tab[2][12] = {
+ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
#define isleap(y) (((y % 4) == 0 && (y % 100) != 0) || (y % 400) == 0)
@@ -49,7 +49,7 @@ static int day_tab[2][12] = {
|| ((m == UTIME_MAXMONTH) && (d <= UTIME_MAXDAY))))))
/*****************************************************************************
- * Date ADT
+ * Date ADT
*****************************************************************************/
@@ -59,234 +59,250 @@ static int day_tab[2][12] = {
DateADT
date_in(char *str)
{
- DateADT date;
- double fsec;
- struct tm tt, *tm = &tt;
- int tzp;
- int dtype;
- int nf;
- char *field[MAXDATEFIELDS];
- int ftype[MAXDATEFIELDS];
- char lowstr[MAXDATELEN+1];
-
- if (!PointerIsValid(str))
- elog(WARN,"Bad (null) date external representation",NULL);
+ DateADT date;
+ double fsec;
+ struct tm tt,
+ *tm = &tt;
+ int tzp;
+ int dtype;
+ int nf;
+ char *field[MAXDATEFIELDS];
+ int ftype[MAXDATEFIELDS];
+ char lowstr[MAXDATELEN + 1];
+
+ if (!PointerIsValid(str))
+ elog(WARN, "Bad (null) date external representation", NULL);
#ifdef DATEDEBUG
-printf( "date_in- input string is %s\n", str);
+ printf("date_in- input string is %s\n", str);
#endif
- if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeDateTime( field, ftype, nf, &dtype, tm, &fsec, &tzp) != 0))
- elog(WARN,"Bad date external representation %s",str);
-
- switch (dtype) {
- case DTK_DATE:
- break;
-
- case DTK_CURRENT:
- GetCurrentTime(tm);
- break;
-
- case DTK_EPOCH:
- tm->tm_year = 1970;
- tm->tm_mon = 1;
- tm->tm_mday = 1;
- break;
-
- default:
- elog(WARN,"Unrecognized date external representation %s",str);
- }
+ if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
+ || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp) != 0))
+ elog(WARN, "Bad date external representation %s", str);
+
+ switch (dtype)
+ {
+ case DTK_DATE:
+ break;
+
+ case DTK_CURRENT:
+ GetCurrentTime(tm);
+ break;
+
+ case DTK_EPOCH:
+ tm->tm_year = 1970;
+ tm->tm_mon = 1;
+ tm->tm_mday = 1;
+ break;
+
+ default:
+ elog(WARN, "Unrecognized date external representation %s", str);
+ }
- if (tm->tm_year < 0 || tm->tm_year > 32767)
- elog(WARN, "date_in: year must be limited to values 0 through 32767 in '%s'", str);
- if (tm->tm_mon < 1 || tm->tm_mon > 12)
- elog(WARN, "date_in: month must be limited to values 1 through 12 in '%s'", str);
- if (tm->tm_mday < 1 || tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon-1])
- elog(WARN, "date_in: day must be limited to values 1 through %d in '%s'",
- day_tab[isleap(tm->tm_year)][tm->tm_mon-1], str);
+ if (tm->tm_year < 0 || tm->tm_year > 32767)
+ elog(WARN, "date_in: year must be limited to values 0 through 32767 in '%s'", str);
+ if (tm->tm_mon < 1 || tm->tm_mon > 12)
+ elog(WARN, "date_in: month must be limited to values 1 through 12 in '%s'", str);
+ if (tm->tm_mday < 1 || tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
+ elog(WARN, "date_in: day must be limited to values 1 through %d in '%s'",
+ day_tab[isleap(tm->tm_year)][tm->tm_mon - 1], str);
- date = (date2j( tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000,1,1));
+ date = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1));
- return(date);
-} /* date_in() */
+ return (date);
+} /* date_in() */
/* date_out()
* Given internal format date, convert to text string.
*/
-char *
+char *
date_out(DateADT date)
{
- char *result;
- struct tm tt, *tm = &tt;
- char buf[MAXDATELEN+1];
+ char *result;
+ struct tm tt,
+ *tm = &tt;
+ char buf[MAXDATELEN + 1];
#if FALSE
- int year, month, day;
+ int year,
+ month,
+ day;
+
#endif
- j2date( (date + date2j(2000,1,1)),
- &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
+ j2date((date + date2j(2000, 1, 1)),
+ &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
- EncodeDateOnly( tm, DateStyle, buf);
+ EncodeDateOnly(tm, DateStyle, buf);
#if FALSE
- if (EuroDates == 1) /* Output European-format dates */
- sprintf(buf, "%02d-%02d-%04d", day, month, year);
- else
- sprintf(buf, "%02d-%02d-%04d", month, day, year);
+ if (EuroDates == 1) /* Output European-format dates */
+ sprintf(buf, "%02d-%02d-%04d", day, month, year);
+ else
+ sprintf(buf, "%02d-%02d-%04d", month, day, year);
#endif
- result = PALLOC(strlen(buf)+1);
+ result = PALLOC(strlen(buf) + 1);
- strcpy( result, buf);
+ strcpy(result, buf);
- return(result);
-} /* date_out() */
+ return (result);
+} /* date_out() */
bool
date_eq(DateADT dateVal1, DateADT dateVal2)
{
- return(dateVal1 == dateVal2);
+ return (dateVal1 == dateVal2);
}
bool
date_ne(DateADT dateVal1, DateADT dateVal2)
{
- return(dateVal1 != dateVal2);
+ return (dateVal1 != dateVal2);
}
bool
date_lt(DateADT dateVal1, DateADT dateVal2)
{
- return(dateVal1 < dateVal2);
-} /* date_lt() */
+ return (dateVal1 < dateVal2);
+} /* date_lt() */
bool
date_le(DateADT dateVal1, DateADT dateVal2)
{
- return(dateVal1 <= dateVal2);
-} /* date_le() */
+ return (dateVal1 <= dateVal2);
+} /* date_le() */
bool
date_gt(DateADT dateVal1, DateADT dateVal2)
{
- return(dateVal1 > dateVal2);
-} /* date_gt() */
+ return (dateVal1 > dateVal2);
+} /* date_gt() */
bool
date_ge(DateADT dateVal1, DateADT dateVal2)
{
- return(dateVal1 >= dateVal2);
-} /* date_ge() */
+ return (dateVal1 >= dateVal2);
+} /* date_ge() */
int
date_cmp(DateADT dateVal1, DateADT dateVal2)
{
- if (dateVal1 < dateVal2) {
- return -1;
- } else if (dateVal1 > dateVal2) {
- return 1;
- }
- return 0;
-} /* date_cmp() */
+ if (dateVal1 < dateVal2)
+ {
+ return -1;
+ }
+ else if (dateVal1 > dateVal2)
+ {
+ return 1;
+ }
+ return 0;
+} /* date_cmp() */
DateADT
date_larger(DateADT dateVal1, DateADT dateVal2)
{
- return(date_gt(dateVal1, dateVal2) ? dateVal1 : dateVal2);
-} /* date_larger() */
+ return (date_gt(dateVal1, dateVal2) ? dateVal1 : dateVal2);
+} /* date_larger() */
DateADT
date_smaller(DateADT dateVal1, DateADT dateVal2)
{
- return(date_lt(dateVal1, dateVal2) ? dateVal1 : dateVal2);
-} /* date_smaller() */
+ return (date_lt(dateVal1, dateVal2) ? dateVal1 : dateVal2);
+} /* date_smaller() */
/* Compute difference between two dates in days. */
int4
date_mi(DateADT dateVal1, DateADT dateVal2)
{
- return(dateVal1-dateVal2);
-} /* date_mi() */
+ return (dateVal1 - dateVal2);
+} /* date_mi() */
/* Add a number of days to a date, giving a new date.
- Must handle both positive and negative numbers of days. */
+ Must handle both positive and negative numbers of days. */
DateADT
date_pli(DateADT dateVal, int4 days)
{
- return(dateVal+days);
-} /* date_pli() */
+ return (dateVal + days);
+} /* date_pli() */
/* Subtract a number of days from a date, giving a new date. */
DateADT
date_mii(DateADT dateVal, int4 days)
{
- return(date_pli(dateVal, -days));
-} /* date_mii() */
+ return (date_pli(dateVal, -days));
+} /* date_mii() */
/* date_datetime()
* Convert date to datetime data type.
*/
-DateTime *
+DateTime *
date_datetime(DateADT dateVal)
{
- DateTime *result;
- struct tm tt, *tm = &tt;
- int tz;
- double fsec = 0;
- char *tzn;
+ DateTime *result;
+ struct tm tt,
+ *tm = &tt;
+ int tz;
+ double fsec = 0;
+ char *tzn;
- result = PALLOCTYPE(DateTime);
+ result = PALLOCTYPE(DateTime);
- if (date2tm( dateVal, &tz, tm, &fsec, &tzn) != 0)
- elog(WARN,"Unable to convert date to datetime",NULL);
+ if (date2tm(dateVal, &tz, tm, &fsec, &tzn) != 0)
+ elog(WARN, "Unable to convert date to datetime", NULL);
#ifdef DATEDEBUG
-printf( "date_datetime- date is %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
-printf( "date_datetime- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
+ printf("date_datetime- date is %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
+ printf("date_datetime- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
#endif
- if (tm2datetime( tm, fsec, &tz, result) != 0)
- elog(WARN,"Datetime out of range",NULL);
+ if (tm2datetime(tm, fsec, &tz, result) != 0)
+ elog(WARN, "Datetime out of range", NULL);
- return(result);
-} /* date_datetime() */
+ return (result);
+} /* date_datetime() */
/* datetime_date()
* Convert datetime to date data type.
*/
DateADT
-datetime_date(DateTime *datetime)
+datetime_date(DateTime * datetime)
{
- DateADT result;
- struct tm tt, *tm = &tt;
- int tz;
- double fsec;
- char *tzn;
+ DateADT result;
+ struct tm tt,
+ *tm = &tt;
+ int tz;
+ double fsec;
+ char *tzn;
- if (!PointerIsValid(datetime))
- elog(WARN,"Unable to convert null datetime to date",NULL);
+ if (!PointerIsValid(datetime))
+ elog(WARN, "Unable to convert null datetime to date", NULL);
- if (DATETIME_NOT_FINITE(*datetime))
- elog(WARN,"Unable to convert datetime to date",NULL);
+ if (DATETIME_NOT_FINITE(*datetime))
+ elog(WARN, "Unable to convert datetime to date", NULL);
- if (DATETIME_IS_EPOCH(*datetime)) {
- datetime2tm( SetDateTime(*datetime), NULL, tm, &fsec, NULL);
+ if (DATETIME_IS_EPOCH(*datetime))
+ {
+ datetime2tm(SetDateTime(*datetime), NULL, tm, &fsec, NULL);
- } else if (DATETIME_IS_CURRENT(*datetime)) {
- datetime2tm( SetDateTime(*datetime), &tz, tm, &fsec, &tzn);
+ }
+ else if (DATETIME_IS_CURRENT(*datetime))
+ {
+ datetime2tm(SetDateTime(*datetime), &tz, tm, &fsec, &tzn);
- } else {
- if (datetime2tm( *datetime, &tz, tm, &fsec, &tzn) != 0)
- elog(WARN,"Unable to convert datetime to date",NULL);
- }
+ }
+ else
+ {
+ if (datetime2tm(*datetime, &tz, tm, &fsec, &tzn) != 0)
+ elog(WARN, "Unable to convert datetime to date", NULL);
+ }
- result = (date2j( tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j( 2000, 1, 1));
+ result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1));
- return(result);
-} /* datetime_date() */
+ return (result);
+} /* datetime_date() */
/* abstime_date()
@@ -295,289 +311,320 @@ datetime_date(DateTime *datetime)
DateADT
abstime_date(AbsoluteTime abstime)
{
- DateADT result;
- struct tm tt, *tm = &tt;
- int tz;
-
- switch (abstime) {
- case INVALID_ABSTIME:
- case NOSTART_ABSTIME:
- case NOEND_ABSTIME:
- elog(WARN,"Unable to convert reserved abstime value to date",NULL);
- /* pretend to drop through to make compiler think that result will be set */
-
- case EPOCH_ABSTIME:
- result = date2j(1970,1,1) - date2j(2000,1,1);
- break;
-
- case CURRENT_ABSTIME:
- GetCurrentTime(tm);
- result = date2j( tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000,1,1);
- break;
-
- default:
- abstime2tm(abstime, &tz, tm, NULL);
- result = date2j(tm->tm_year,tm->tm_mon,tm->tm_mday) - date2j(2000,1,1);
- break;
- }
+ DateADT result;
+ struct tm tt,
+ *tm = &tt;
+ int tz;
+
+ switch (abstime)
+ {
+ case INVALID_ABSTIME:
+ case NOSTART_ABSTIME:
+ case NOEND_ABSTIME:
+ elog(WARN, "Unable to convert reserved abstime value to date", NULL);
+
+ /*
+ * pretend to drop through to make compiler think that result will
+ * be set
+ */
+
+ case EPOCH_ABSTIME:
+ result = date2j(1970, 1, 1) - date2j(2000, 1, 1);
+ break;
+
+ case CURRENT_ABSTIME:
+ GetCurrentTime(tm);
+ result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
+ break;
+
+ default:
+ abstime2tm(abstime, &tz, tm, NULL);
+ result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
+ break;
+ }
- return(result);
-} /* abstime_date() */
+ return (result);
+} /* abstime_date() */
/* date2tm()
* Convert date to time structure.
* Note that date is an implicit local time, but the system calls assume
- * that everything is GMT. So, convert to GMT, rotate to local time,
- * and then convert again to try to get the time zones correct.
+ * that everything is GMT. So, convert to GMT, rotate to local time,
+ * and then convert again to try to get the time zones correct.
*/
static int
-date2tm(DateADT dateVal, int *tzp, struct tm *tm, double *fsec, char **tzn)
+date2tm(DateADT dateVal, int *tzp, struct tm * tm, double *fsec, char **tzn)
{
- struct tm *tx;
- time_t utime;
- *fsec = 0;
+ struct tm *tx;
+ time_t utime;
- j2date( (dateVal + date2j( 2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
- tm->tm_isdst = -1;
+ *fsec = 0;
- if (IS_VALID_UTIME( tm->tm_year, tm->tm_mon, tm->tm_mday)) {
+ j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+ tm->tm_isdst = -1;
+
+ if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
+ {
- /* convert to system time */
- utime = ((dateVal + (date2j(2000,1,1)-date2j(1970,1,1)))*86400);
- utime += (12*60*60); /* rotate to noon to get the right day in time zone */
+ /* convert to system time */
+ utime = ((dateVal + (date2j(2000, 1, 1) - date2j(1970, 1, 1))) * 86400);
+ utime += (12 * 60 * 60);/* rotate to noon to get the right day in
+ * time zone */
#ifdef USE_POSIX_TIME
- tx = localtime(&utime);
+ tx = localtime(&utime);
#ifdef DATEDEBUG
#ifdef HAVE_INT_TIMEZONE
-printf( "date2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
- tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, (double) tm->tm_sec,
- tzname[0], tzname[1], tx->tm_isdst);
+ printf("date2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
+ tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, (double) tm->tm_sec,
+ tzname[0], tzname[1], tx->tm_isdst);
#endif
#endif
- tm->tm_year = tx->tm_year + 1900;
- tm->tm_mon = tx->tm_mon + 1;
- tm->tm_mday = tx->tm_mday;
+ tm->tm_year = tx->tm_year + 1900;
+ tm->tm_mon = tx->tm_mon + 1;
+ tm->tm_mday = tx->tm_mday;
#if FALSE
- tm->tm_hour = tx->tm_hour;
- tm->tm_min = tx->tm_min;
- tm->tm_sec = tx->tm_sec;
+ tm->tm_hour = tx->tm_hour;
+ tm->tm_min = tx->tm_min;
+ tm->tm_sec = tx->tm_sec;
#endif
- tm->tm_isdst = tx->tm_isdst;
+ tm->tm_isdst = tx->tm_isdst;
#ifdef HAVE_INT_TIMEZONE
- *tzp = (tm->tm_isdst? (timezone - 3600): timezone);
- if (tzn != NULL) *tzn = tzname[(tm->tm_isdst > 0)];
-
-#else /* !HAVE_INT_TIMEZONE */
- tm->tm_gmtoff = tx->tm_gmtoff;
- tm->tm_zone = tx->tm_zone;
-
- *tzp = (tm->tm_isdst? (tm->tm_gmtoff - 3600): tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
- if (tzn != NULL) *tzn = tm->tm_zone;
+ *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
+ if (tzn != NULL)
+ *tzn = tzname[(tm->tm_isdst > 0)];
+
+#else /* !HAVE_INT_TIMEZONE */
+ tm->tm_gmtoff = tx->tm_gmtoff;
+ tm->tm_zone = tx->tm_zone;
+
+ *tzp = (tm->tm_isdst ? (tm->tm_gmtoff - 3600) : tm->tm_gmtoff); /* tm_gmtoff is
+ * Sun/DEC-ism */
+ if (tzn != NULL)
+ *tzn = tm->tm_zone;
#endif
-#else /* !USE_POSIX_TIME */
- *tzp = CTimeZone; /* V7 conventions; don't know timezone? */
- if (tzn != NULL) *tzn = CTZName;
+#else /* !USE_POSIX_TIME */
+ *tzp = CTimeZone; /* V7 conventions; don't know timezone? */
+ if (tzn != NULL)
+ *tzn = CTZName;
#endif
- /* otherwise, outside of timezone range so convert to GMT... */
- } else {
+ /* otherwise, outside of timezone range so convert to GMT... */
+ }
+ else
+ {
#if FALSE
- j2date( (dateVal + date2j( 2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
+ j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
#endif
#ifdef DATEDEBUG
-printf( "date2tm- convert %d-%d-%d %d:%d%d to datetime\n",
- tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+ printf("date2tm- convert %d-%d-%d %d:%d%d to datetime\n",
+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
#endif
- *tzp = 0;
- tm->tm_isdst = 0;
- if (tzn != NULL) *tzn = NULL;
- }
+ *tzp = 0;
+ tm->tm_isdst = 0;
+ if (tzn != NULL)
+ *tzn = NULL;
+ }
- return 0;
-} /* date2tm() */
+ return 0;
+} /* date2tm() */
/*****************************************************************************
- * Time ADT
+ * Time ADT
*****************************************************************************/
-TimeADT *
+TimeADT *
time_in(char *str)
{
- TimeADT *time;
+ TimeADT *time;
- double fsec;
- struct tm tt, *tm = &tt;
+ double fsec;
+ struct tm tt,
+ *tm = &tt;
- int nf;
- char lowstr[MAXDATELEN+1];
- char *field[MAXDATEFIELDS];
- int dtype;
- int ftype[MAXDATEFIELDS];
+ int nf;
+ char lowstr[MAXDATELEN + 1];
+ char *field[MAXDATEFIELDS];
+ int dtype;
+ int ftype[MAXDATEFIELDS];
- if (!PointerIsValid(str))
- elog(WARN,"Bad (null) time external representation",NULL);
+ if (!PointerIsValid(str))
+ elog(WARN, "Bad (null) time external representation", NULL);
- if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeTimeOnly( field, ftype, nf, &dtype, tm, &fsec) != 0))
- elog(WARN,"Bad time external representation '%s'",str);
+ if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
+ || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec) != 0))
+ elog(WARN, "Bad time external representation '%s'", str);
- if ((tm->tm_hour < 0) || (tm->tm_hour > 23))
- elog(WARN,"Hour must be limited to values 0 through 23 in '%s'",str);
- if ((tm->tm_min < 0) || (tm->tm_min > 59))
- elog(WARN,"Minute must be limited to values 0 through 59 in '%s'",str);
- if ((tm->tm_sec < 0) || ((tm->tm_sec + fsec) >= 60))
- elog(WARN,"Second must be limited to values 0 through < 60 in '%s'",str);
+ if ((tm->tm_hour < 0) || (tm->tm_hour > 23))
+ elog(WARN, "Hour must be limited to values 0 through 23 in '%s'", str);
+ if ((tm->tm_min < 0) || (tm->tm_min > 59))
+ elog(WARN, "Minute must be limited to values 0 through 59 in '%s'", str);
+ if ((tm->tm_sec < 0) || ((tm->tm_sec + fsec) >= 60))
+ elog(WARN, "Second must be limited to values 0 through < 60 in '%s'", str);
- time = PALLOCTYPE(TimeADT);
+ time = PALLOCTYPE(TimeADT);
- *time = ((((tm->tm_hour*60)+tm->tm_min)*60)+tm->tm_sec+fsec);
+ *time = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
- return(time);
-} /* time_in() */
+ return (time);
+} /* time_in() */
-char *
-time_out(TimeADT *time)
+char *
+time_out(TimeADT * time)
{
- char *result;
- struct tm tt, *tm = &tt;
+ char *result;
+ struct tm tt,
+ *tm = &tt;
+
#if FALSE
- int hour, min, sec;
+ int hour,
+ min,
+ sec;
+
#endif
- double fsec;
- char buf[MAXDATELEN+1];
+ double fsec;
+ char buf[MAXDATELEN + 1];
- if (!PointerIsValid(time))
- return NULL;
+ if (!PointerIsValid(time))
+ return NULL;
- tm->tm_hour = (*time / (60*60));
- tm->tm_min = (((int) (*time / 60)) % 60);
- tm->tm_sec = (((int) *time) % 60);
+ tm->tm_hour = (*time / (60 * 60));
+ tm->tm_min = (((int) (*time / 60)) % 60);
+ tm->tm_sec = (((int) *time) % 60);
- fsec = 0;
+ fsec = 0;
- EncodeTimeOnly( tm, fsec, DateStyle, buf);
+ EncodeTimeOnly(tm, fsec, DateStyle, buf);
#if FALSE
- if (sec == 0.0) {
- sprintf(buf, "%02d:%02d", hour, min);
-
- } else {
- if (fsec == 0) {
- sprintf(buf, "%02d:%02d:%02d", hour, min, sec);
- } else {
- sprintf(buf, "%02d:%02d:%05.2f", hour, min, (sec+fsec));
+ if (sec == 0.0)
+ {
+ sprintf(buf, "%02d:%02d", hour, min);
+
+ }
+ else
+ {
+ if (fsec == 0)
+ {
+ sprintf(buf, "%02d:%02d:%02d", hour, min, sec);
+ }
+ else
+ {
+ sprintf(buf, "%02d:%02d:%05.2f", hour, min, (sec + fsec));
+ }
}
- }
#endif
- result = PALLOC(strlen(buf)+1);
+ result = PALLOC(strlen(buf) + 1);
- strcpy( result, buf);
+ strcpy(result, buf);
- return(result);
-} /* time_out() */
+ return (result);
+} /* time_out() */
bool
-time_eq(TimeADT *time1, TimeADT *time2)
+time_eq(TimeADT * time1, TimeADT * time2)
{
- if (!PointerIsValid(time1) || !PointerIsValid(time2))
- return(FALSE);
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return (FALSE);
- return(*time1 == *time2);
-} /* time_eq() */
+ return (*time1 == *time2);
+} /* time_eq() */
bool
-time_ne(TimeADT *time1, TimeADT *time2)
+time_ne(TimeADT * time1, TimeADT * time2)
{
- if (!PointerIsValid(time1) || !PointerIsValid(time2))
- return(FALSE);
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return (FALSE);
- return(*time1 != *time2);
-} /* time_eq() */
+ return (*time1 != *time2);
+} /* time_eq() */
bool
-time_lt(TimeADT *time1, TimeADT *time2)
+time_lt(TimeADT * time1, TimeADT * time2)
{
- if (!PointerIsValid(time1) || !PointerIsValid(time2))
- return(FALSE);
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return (FALSE);
- return(*time1 < *time2);
-} /* time_eq() */
+ return (*time1 < *time2);
+} /* time_eq() */
bool
-time_le(TimeADT *time1, TimeADT *time2)
+time_le(TimeADT * time1, TimeADT * time2)
{
- if (!PointerIsValid(time1) || !PointerIsValid(time2))
- return(FALSE);
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return (FALSE);
- return(*time1 <= *time2);
-} /* time_eq() */
+ return (*time1 <= *time2);
+} /* time_eq() */
bool
-time_gt(TimeADT *time1, TimeADT *time2)
+time_gt(TimeADT * time1, TimeADT * time2)
{
- if (!PointerIsValid(time1) || !PointerIsValid(time2))
- return(FALSE);
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return (FALSE);
- return(*time1 > *time2);
-} /* time_eq() */
+ return (*time1 > *time2);
+} /* time_eq() */
bool
-time_ge(TimeADT *time1, TimeADT *time2)
+time_ge(TimeADT * time1, TimeADT * time2)
{
- if (!PointerIsValid(time1) || !PointerIsValid(time2))
- return(FALSE);
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return (FALSE);
- return(*time1 >= *time2);
-} /* time_eq() */
+ return (*time1 >= *time2);
+} /* time_eq() */
int
-time_cmp(TimeADT *time1, TimeADT *time2)
+time_cmp(TimeADT * time1, TimeADT * time2)
{
- return((*time1 < *time2)? -1: (((*time1 > *time2)? 1: 0)));
-} /* time_cmp() */
+ return ((*time1 < *time2) ? -1 : (((*time1 > *time2) ? 1 : 0)));
+} /* time_cmp() */
/* datetime_datetime()
* Convert date and time to datetime data type.
*/
-DateTime *
-datetime_datetime(DateADT date, TimeADT *time)
+DateTime *
+datetime_datetime(DateADT date, TimeADT * time)
{
- DateTime *result;
+ DateTime *result;
- if (!PointerIsValid(time)) {
- result = PALLOCTYPE(DateTime);
- DATETIME_INVALID(*result);
+ if (!PointerIsValid(time))
+ {
+ result = PALLOCTYPE(DateTime);
+ DATETIME_INVALID(*result);
- } else {
- result = date_datetime(date);
- *result += *time;
- }
+ }
+ else
+ {
+ result = date_datetime(date);
+ *result += *time;
+ }
- return(result);
-} /* datetime_datetime() */
+ return (result);
+} /* datetime_datetime() */
-int32 /* RelativeTime */
+int32 /* RelativeTime */
int42reltime(int32 timevalue)
{
- return(timevalue);
+ return (timevalue);
}
diff --git a/src/backend/utils/adt/datum.c b/src/backend/utils/adt/datum.c
index 493843071cd..eb314176bab 100644
--- a/src/backend/utils/adt/datum.c
+++ b/src/backend/utils/adt/datum.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/datum.c,v 1.5 1997/08/19 21:34:33 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/datum.c,v 1.6 1997/09/07 04:50:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -49,39 +49,51 @@
Size
datumGetSize(Datum value, Oid type, bool byVal, Size len)
{
-
- struct varlena *s;
- Size size = 0;
-
- if (byVal) {
- if (len <= sizeof(Datum)) {
- size = len;
- } else {
- elog(WARN,
- "datumGetSize: Error: type=%ld, byVaL with len=%d",
- (long) type, len);
+
+ struct varlena *s;
+ Size size = 0;
+
+ if (byVal)
+ {
+ if (len <= sizeof(Datum))
+ {
+ size = len;
+ }
+ else
+ {
+ elog(WARN,
+ "datumGetSize: Error: type=%ld, byVaL with len=%d",
+ (long) type, len);
+ }
}
- } else { /* not byValue */
- if (len == -1) {
- /*
- * variable length type
- * Look at the varlena struct for its real length...
- */
- s = (struct varlena *) DatumGetPointer(value);
- if (!PointerIsValid(s)) {
- elog(WARN,
- "datumGetSize: Invalid Datum Pointer");
- }
- size = (Size) VARSIZE(s);
- } else {
- /*
- * fixed length type
- */
- size = len;
+ else
+ { /* not byValue */
+ if (len == -1)
+ {
+
+ /*
+ * variable length type Look at the varlena struct for its
+ * real length...
+ */
+ s = (struct varlena *) DatumGetPointer(value);
+ if (!PointerIsValid(s))
+ {
+ elog(WARN,
+ "datumGetSize: Invalid Datum Pointer");
+ }
+ size = (Size) VARSIZE(s);
+ }
+ else
+ {
+
+ /*
+ * fixed length type
+ */
+ size = len;
+ }
}
- }
-
- return(size);
+
+ return (size);
}
/*-------------------------------------------------------------------------
@@ -97,29 +109,35 @@ datumGetSize(Datum value, Oid type, bool byVal, Size len)
Datum
datumCopy(Datum value, Oid type, bool byVal, Size len)
{
-
- Size realSize;
- Datum res;
- char *s;
-
-
- if (byVal) {
- res = value;
- } else {
- if (value == 0) return((Datum)NULL);
- realSize = datumGetSize(value, type, byVal, len);
- /*
- * the value is a pointer. Allocate enough space
- * and copy the pointed data.
- */
- s = (char *) palloc(realSize);
- if (s == NULL) {
- elog(WARN,"datumCopy: out of memory\n");
+
+ Size realSize;
+ Datum res;
+ char *s;
+
+
+ if (byVal)
+ {
+ res = value;
}
- memmove(s, DatumGetPointer(value), realSize);
- res = (Datum)s;
- }
- return(res);
+ else
+ {
+ if (value == 0)
+ return ((Datum) NULL);
+ realSize = datumGetSize(value, type, byVal, len);
+
+ /*
+ * the value is a pointer. Allocate enough space and copy the
+ * pointed data.
+ */
+ s = (char *) palloc(realSize);
+ if (s == NULL)
+ {
+ elog(WARN, "datumCopy: out of memory\n");
+ }
+ memmove(s, DatumGetPointer(value), realSize);
+ res = (Datum) s;
+ }
+ return (res);
}
/*-------------------------------------------------------------------------
@@ -135,20 +153,23 @@ datumCopy(Datum value, Oid type, bool byVal, Size len)
void
datumFree(Datum value, Oid type, bool byVal, Size len)
{
-
- Size realSize;
- Pointer s;
-
- realSize = datumGetSize(value, type, byVal, len);
-
- if (!byVal) {
- /*
- * free the space palloced by "datumCopy()"
- */
- s = DatumGetPointer(value);
- pfree(s);
- }
+
+ Size realSize;
+ Pointer s;
+
+ realSize = datumGetSize(value, type, byVal, len);
+
+ if (!byVal)
+ {
+
+ /*
+ * free the space palloced by "datumCopy()"
+ */
+ s = DatumGetPointer(value);
+ pfree(s);
+ }
}
+
#endif
/*-------------------------------------------------------------------------
@@ -167,36 +188,40 @@ datumFree(Datum value, Oid type, bool byVal, Size len)
bool
datumIsEqual(Datum value1, Datum value2, Oid type, bool byVal, Size len)
{
- Size size1, size2;
- char *s1, *s2;
-
- if (byVal) {
- /*
- * just compare the two datums.
- * NOTE: just comparing "len" bytes will not do the
- * work, because we do not know how these bytes
- * are aligned inside the "Datum".
- */
- if (value1 == value2)
- return(true);
- else
- return(false);
- } else {
- /*
- * byVal = false
- * Compare the bytes pointed by the pointers stored in the
- * datums.
- */
- size1 = datumGetSize(value1, type, byVal, len);
- size2 = datumGetSize(value2, type, byVal, len);
- if (size1 != size2)
- return(false);
- s1 = (char *) DatumGetPointer(value1);
- s2 = (char *) DatumGetPointer(value2);
- if (!memcmp(s1, s2, size1))
- return(true);
+ Size size1,
+ size2;
+ char *s1,
+ *s2;
+
+ if (byVal)
+ {
+
+ /*
+ * just compare the two datums. NOTE: just comparing "len" bytes
+ * will not do the work, because we do not know how these bytes
+ * are aligned inside the "Datum".
+ */
+ if (value1 == value2)
+ return (true);
+ else
+ return (false);
+ }
else
- return(false);
- }
-}
+ {
+ /*
+ * byVal = false Compare the bytes pointed by the pointers stored
+ * in the datums.
+ */
+ size1 = datumGetSize(value1, type, byVal, len);
+ size2 = datumGetSize(value2, type, byVal, len);
+ if (size1 != size2)
+ return (false);
+ s1 = (char *) DatumGetPointer(value1);
+ s2 = (char *) DatumGetPointer(value2);
+ if (!memcmp(s1, s2, size1))
+ return (true);
+ else
+ return (false);
+ }
+}
diff --git a/src/backend/utils/adt/dt.c b/src/backend/utils/adt/dt.c
index 803f0d63669..b3eca30144c 100644
--- a/src/backend/utils/adt/dt.c
+++ b/src/backend/utils/adt/dt.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* dt.c--
- * Functions for the built-in type "dt".
+ * Functions for the built-in type "dt".
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.37 1997/09/06 00:22:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.38 1997/09/07 04:50:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,54 +21,57 @@
#include "postgres.h"
#include "miscadmin.h"
#ifdef HAVE_FLOAT_H
-# include <float.h>
+#include <float.h>
#endif
#ifdef HAVE_LIMITS_H
-# include <limits.h>
+#include <limits.h>
#endif
#ifndef USE_POSIX_TIME
#include <sys/timeb.h>
#endif
#include "utils/builtins.h"
-static int DecodeDate(char *str, int fmask, int *tmask, struct tm *tm);
-static int DecodeNumber( int flen, char *field,
- int fmask, int *tmask, struct tm *tm, double *fsec);
-static int DecodeNumberField( int len, char *str,
- int fmask, int *tmask, struct tm *tm, double *fsec);
-static int DecodeSpecial(int field, char *lowtoken, int *val);
-static int DecodeTime(char *str, int fmask, int *tmask,
- struct tm *tm, double *fsec);
-static int DecodeTimezone( char *str, int *tzp);
-static int DecodeUnits(int field, char *lowtoken, int *val);
-static int EncodeSpecialDateTime(DateTime dt, char *str);
-static datetkn *datebsearch(char *key, datetkn *base, unsigned int nel);
-static DateTime dt2local( DateTime dt, int timezone);
-static void dt2time(DateTime dt, int *hour, int *min, double *sec);
-static int j2day( int jd);
-static int timespan2tm(TimeSpan span, struct tm *tm, float8 *fsec);
-static int tm2timespan(struct tm *tm, double fsec, TimeSpan *span);
+static int DecodeDate(char *str, int fmask, int *tmask, struct tm * tm);
+static int
+DecodeNumber(int flen, char *field,
+ int fmask, int *tmask, struct tm * tm, double *fsec);
+static int
+DecodeNumberField(int len, char *str,
+ int fmask, int *tmask, struct tm * tm, double *fsec);
+static int DecodeSpecial(int field, char *lowtoken, int *val);
+static int
+DecodeTime(char *str, int fmask, int *tmask,
+ struct tm * tm, double *fsec);
+static int DecodeTimezone(char *str, int *tzp);
+static int DecodeUnits(int field, char *lowtoken, int *val);
+static int EncodeSpecialDateTime(DateTime dt, char *str);
+static datetkn *datebsearch(char *key, datetkn * base, unsigned int nel);
+static DateTime dt2local(DateTime dt, int timezone);
+static void dt2time(DateTime dt, int *hour, int *min, double *sec);
+static int j2day(int jd);
+static int timespan2tm(TimeSpan span, struct tm * tm, float8 * fsec);
+static int tm2timespan(struct tm * tm, double fsec, TimeSpan * span);
#define USE_DATE_CACHE 1
#define ROUND_ALL 0
#define isleap(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
-int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
+int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
-char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
+char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
-char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday", NULL};
+char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
+"Thursday", "Friday", "Saturday", NULL};
/* TMODULO()
* Macro to replace modf(), which is broken on some platforms.
*/
#define TMODULO(t,q,u) {q = ((t < 0)? ceil(t / u): floor(t / u)); \
- if (q != 0) t -= rint(q * u);}
+ if (q != 0) t -= rint(q * u);}
-static void GetEpochTime( struct tm *tm);
+static void GetEpochTime(struct tm * tm);
#define UTIME_MINYEAR (1901)
#define UTIME_MINMONTH (12)
@@ -85,1728 +88,1975 @@ static void GetEpochTime( struct tm *tm);
|| ((m == UTIME_MAXMONTH) && (d <= UTIME_MAXDAY))))))
-/*****************************************************************************
- * USER I/O ROUTINES *
+/*****************************************************************************
+ * USER I/O ROUTINES *
*****************************************************************************/
/* datetime_in()
* Convert a string to internal form.
*/
-DateTime *
+DateTime *
datetime_in(char *str)
{
- DateTime *result;
+ DateTime *result;
- double fsec;
- struct tm tt, *tm = &tt;
- int tz;
- int dtype;
- int nf;
- char *field[MAXDATEFIELDS];
- int ftype[MAXDATEFIELDS];
- char lowstr[MAXDATELEN+1];
+ double fsec;
+ struct tm tt,
+ *tm = &tt;
+ int tz;
+ int dtype;
+ int nf;
+ char *field[MAXDATEFIELDS];
+ int ftype[MAXDATEFIELDS];
+ char lowstr[MAXDATELEN + 1];
- if (!PointerIsValid(str))
- elog(WARN,"Bad (null) datetime external representation",NULL);
+ if (!PointerIsValid(str))
+ elog(WARN, "Bad (null) datetime external representation", NULL);
- if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeDateTime( field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
- elog(WARN,"Bad datetime external representation %s",str);
+ if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
+ || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
+ elog(WARN, "Bad datetime external representation %s", str);
- result = PALLOCTYPE(DateTime);
+ result = PALLOCTYPE(DateTime);
- switch (dtype) {
- case DTK_DATE:
- if (tm2datetime( tm, fsec, &tz, result) != 0)
- elog(WARN,"Datetime out of range %s",str);
+ switch (dtype)
+ {
+ case DTK_DATE:
+ if (tm2datetime(tm, fsec, &tz, result) != 0)
+ elog(WARN, "Datetime out of range %s", str);
#ifdef DATEDEBUG
-printf( "datetime_in- date is %f\n", *result);
+ printf("datetime_in- date is %f\n", *result);
#endif
- break;
+ break;
- case DTK_EPOCH:
- DATETIME_EPOCH(*result);
- break;
+ case DTK_EPOCH:
+ DATETIME_EPOCH(*result);
+ break;
- case DTK_CURRENT:
- DATETIME_CURRENT(*result);
- break;
+ case DTK_CURRENT:
+ DATETIME_CURRENT(*result);
+ break;
- case DTK_LATE:
- DATETIME_NOEND(*result);
- break;
+ case DTK_LATE:
+ DATETIME_NOEND(*result);
+ break;
- case DTK_EARLY:
- DATETIME_NOBEGIN(*result);
- break;
+ case DTK_EARLY:
+ DATETIME_NOBEGIN(*result);
+ break;
- case DTK_INVALID:
- DATETIME_INVALID(*result);
- break;
+ case DTK_INVALID:
+ DATETIME_INVALID(*result);
+ break;
- default:
- elog(WARN,"Internal coding error, can't input datetime '%s'",str);
- }
+ default:
+ elog(WARN, "Internal coding error, can't input datetime '%s'", str);
+ }
- return(result);
-} /* datetime_in() */
+ return (result);
+} /* datetime_in() */
/* datetime_out()
* Convert a datetime to external form.
*/
-char *
-datetime_out(DateTime *dt)
+char *
+datetime_out(DateTime * dt)
{
- char *result;
- int tz;
- struct tm tt, *tm = &tt;
- double fsec;
- char *tzn;
- char buf[MAXDATELEN+1];
+ char *result;
+ int tz;
+ struct tm tt,
+ *tm = &tt;
+ double fsec;
+ char *tzn;
+ char buf[MAXDATELEN + 1];
- if (!PointerIsValid(dt))
- return(NULL);
+ if (!PointerIsValid(dt))
+ return (NULL);
- if (DATETIME_IS_RESERVED(*dt)) {
- EncodeSpecialDateTime(*dt, buf);
+ if (DATETIME_IS_RESERVED(*dt))
+ {
+ EncodeSpecialDateTime(*dt, buf);
- } else if (datetime2tm( *dt, &tz, tm, &fsec, &tzn) == 0) {
- EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
+ }
+ else if (datetime2tm(*dt, &tz, tm, &fsec, &tzn) == 0)
+ {
+ EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
- } else {
- EncodeSpecialDateTime(DT_INVALID, buf);
- }
+ }
+ else
+ {
+ EncodeSpecialDateTime(DT_INVALID, buf);
+ }
- result = PALLOC(strlen(buf)+1);
+ result = PALLOC(strlen(buf) + 1);
- strcpy( result, buf);
+ strcpy(result, buf);
- return( result);
-} /* datetime_out() */
+ return (result);
+} /* datetime_out() */
/* timespan_in()
* Convert a string to internal form.
*
* External format(s):
- * Uses the generic date/time parsing and decoding routines.
+ * Uses the generic date/time parsing and decoding routines.
*/
-TimeSpan *
+TimeSpan *
timespan_in(char *str)
{
- TimeSpan *span;
+ TimeSpan *span;
- double fsec;
- struct tm tt, *tm = &tt;
- int dtype;
- int nf;
- char *field[MAXDATEFIELDS];
- int ftype[MAXDATEFIELDS];
- char lowstr[MAXDATELEN+1];
+ double fsec;
+ struct tm tt,
+ *tm = &tt;
+ int dtype;
+ int nf;
+ char *field[MAXDATEFIELDS];
+ int ftype[MAXDATEFIELDS];
+ char lowstr[MAXDATELEN + 1];
- tm->tm_year = 0;
- tm->tm_mon = 0;
- tm->tm_mday = 0;
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
- fsec = 0;
+ tm->tm_year = 0;
+ tm->tm_mon = 0;
+ tm->tm_mday = 0;
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+ fsec = 0;
- if (!PointerIsValid(str))
- elog(WARN,"Bad (null) timespan external representation",NULL);
+ if (!PointerIsValid(str))
+ elog(WARN, "Bad (null) timespan external representation", NULL);
- if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeDateDelta( field, ftype, nf, &dtype, tm, &fsec) != 0))
- elog(WARN,"Bad timespan external representation '%s'",str);
+ if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
+ || (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0))
+ elog(WARN, "Bad timespan external representation '%s'", str);
- span = PALLOCTYPE(TimeSpan);
+ span = PALLOCTYPE(TimeSpan);
- switch (dtype) {
- case DTK_DELTA:
- if (tm2timespan(tm, fsec, span) != 0) {
+ switch (dtype)
+ {
+ case DTK_DELTA:
+ if (tm2timespan(tm, fsec, span) != 0)
+ {
#if FALSE
- TIMESPAN_INVALID(span);
+ TIMESPAN_INVALID(span);
#endif
- elog(WARN,"Bad timespan external representation %s",str);
- }
- break;
+ elog(WARN, "Bad timespan external representation %s", str);
+ }
+ break;
- default:
- elog(WARN,"Internal coding error, can't input timespan '%s'",str);
- }
+ default:
+ elog(WARN, "Internal coding error, can't input timespan '%s'", str);
+ }
- return(span);
-} /* timespan_in() */
+ return (span);
+} /* timespan_in() */
/* timespan_out()
* Convert a time span to external form.
*/
-char *
-timespan_out(TimeSpan *span)
+char *
+timespan_out(TimeSpan * span)
{
- char *result;
+ char *result;
- struct tm tt, *tm = &tt;
- double fsec;
- char buf[MAXDATELEN+1];
+ struct tm tt,
+ *tm = &tt;
+ double fsec;
+ char buf[MAXDATELEN + 1];
- if (!PointerIsValid(span))
- return(NULL);
+ if (!PointerIsValid(span))
+ return (NULL);
- if (timespan2tm(*span, tm, &fsec) != 0)
- return(NULL);
+ if (timespan2tm(*span, tm, &fsec) != 0)
+ return (NULL);
- if (EncodeTimeSpan(tm, fsec, DateStyle, buf) != 0)
- elog(WARN,"Unable to format timespan",NULL);
+ if (EncodeTimeSpan(tm, fsec, DateStyle, buf) != 0)
+ elog(WARN, "Unable to format timespan", NULL);
- result = PALLOC(strlen(buf)+1);
+ result = PALLOC(strlen(buf) + 1);
- strcpy( result, buf);
- return( result);
-} /* timespan_out() */
+ strcpy(result, buf);
+ return (result);
+} /* timespan_out() */
-/*****************************************************************************
- * PUBLIC ROUTINES *
+/*****************************************************************************
+ * PUBLIC ROUTINES *
*****************************************************************************/
bool
-datetime_finite(DateTime *datetime)
+datetime_finite(DateTime * datetime)
{
- if (!PointerIsValid(datetime))
- return FALSE;
+ if (!PointerIsValid(datetime))
+ return FALSE;
- return(! DATETIME_NOT_FINITE(*datetime));
-} /* datetime_finite() */
+ return (!DATETIME_NOT_FINITE(*datetime));
+} /* datetime_finite() */
#ifdef NOT_USED
bool
-timespan_finite(TimeSpan *timespan)
+timespan_finite(TimeSpan * timespan)
{
- if (!PointerIsValid(timespan))
- return FALSE;
+ if (!PointerIsValid(timespan))
+ return FALSE;
+
+ return (!TIMESPAN_NOT_FINITE(*timespan));
+} /* timespan_finite() */
- return(! TIMESPAN_NOT_FINITE(*timespan));
-} /* timespan_finite() */
#endif
/*----------------------------------------------------------
- * Relational operators for datetime.
+ * Relational operators for datetime.
*---------------------------------------------------------*/
static void
-GetEpochTime( struct tm *tm)
+GetEpochTime(struct tm * tm)
{
- struct tm *t0;
- time_t epoch = 0;
+ struct tm *t0;
+ time_t epoch = 0;
- t0 = gmtime( &epoch);
+ t0 = gmtime(&epoch);
- tm->tm_year = t0->tm_year;
- tm->tm_mon = t0->tm_mon;
- tm->tm_mday = t0->tm_mday;
- tm->tm_hour = t0->tm_hour;
- tm->tm_min = t0->tm_min;
- tm->tm_sec = t0->tm_sec;
+ tm->tm_year = t0->tm_year;
+ tm->tm_mon = t0->tm_mon;
+ tm->tm_mday = t0->tm_mday;
+ tm->tm_hour = t0->tm_hour;
+ tm->tm_min = t0->tm_min;
+ tm->tm_sec = t0->tm_sec;
- if (tm->tm_year < 1900) tm->tm_year += 1900;
- tm->tm_mon++;
+ if (tm->tm_year < 1900)
+ tm->tm_year += 1900;
+ tm->tm_mon++;
#ifdef DATEDEBUG
-printf( "GetEpochTime- %04d-%02d-%02d %02d:%02d:%02d\n",
- tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+ printf("GetEpochTime- %04d-%02d-%02d %02d:%02d:%02d\n",
+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
#endif
- return;
-} /* GetEpochTime() */
+ return;
+} /* GetEpochTime() */
DateTime
-SetDateTime( DateTime dt) {
- struct tm tt;
+SetDateTime(DateTime dt)
+{
+ struct tm tt;
- if (DATETIME_IS_CURRENT(dt)) {
- GetCurrentTime(&tt);
- tm2datetime( &tt, 0, NULL, &dt);
- dt = dt2local( dt, -CTimeZone);
+ if (DATETIME_IS_CURRENT(dt))
+ {
+ GetCurrentTime(&tt);
+ tm2datetime(&tt, 0, NULL, &dt);
+ dt = dt2local(dt, -CTimeZone);
#ifdef DATEDEBUG
-printf( "SetDateTime- current time is %f\n", dt);
+ printf("SetDateTime- current time is %f\n", dt);
#endif
- } else { /* if (DATETIME_IS_EPOCH(dt1)) */
- GetEpochTime(&tt);
- tm2datetime( &tt, 0, NULL, &dt);
+ }
+ else
+ { /* if (DATETIME_IS_EPOCH(dt1)) */
+ GetEpochTime(&tt);
+ tm2datetime(&tt, 0, NULL, &dt);
#ifdef DATEDEBUG
-printf( "SetDateTime- epoch time is %f\n", dt);
+ printf("SetDateTime- epoch time is %f\n", dt);
#endif
- }
+ }
- return(dt);
-} /* SetDateTime() */
+ return (dt);
+} /* SetDateTime() */
-/* datetime_relop - is datetime1 relop datetime2
+/* datetime_relop - is datetime1 relop datetime2
*/
bool
-datetime_eq(DateTime *datetime1, DateTime *datetime2)
+datetime_eq(DateTime * datetime1, DateTime * datetime2)
{
- DateTime dt1, dt2;
+ DateTime dt1,
+ dt2;
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return FALSE;
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return FALSE;
- dt1 = *datetime1;
- dt2 = *datetime2;
+ dt1 = *datetime1;
+ dt2 = *datetime2;
- if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
- return FALSE;
+ if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
+ return FALSE;
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
- return( dt1 == dt2);
-} /* datetime_eq() */
+ return (dt1 == dt2);
+} /* datetime_eq() */
bool
-datetime_ne(DateTime *datetime1, DateTime *datetime2)
+datetime_ne(DateTime * datetime1, DateTime * datetime2)
{
- DateTime dt1, dt2;
+ DateTime dt1,
+ dt2;
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return FALSE;
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return FALSE;
- dt1 = *datetime1;
- dt2 = *datetime2;
+ dt1 = *datetime1;
+ dt2 = *datetime2;
- if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
- return FALSE;
+ if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
+ return FALSE;
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
- return( dt1 != dt2);
-} /* datetime_ne() */
+ return (dt1 != dt2);
+} /* datetime_ne() */
bool
-datetime_lt(DateTime *datetime1, DateTime *datetime2)
+datetime_lt(DateTime * datetime1, DateTime * datetime2)
{
- DateTime dt1, dt2;
+ DateTime dt1,
+ dt2;
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return FALSE;
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return FALSE;
- dt1 = *datetime1;
- dt2 = *datetime2;
+ dt1 = *datetime1;
+ dt2 = *datetime2;
- if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
- return FALSE;
+ if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
+ return FALSE;
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
- return( dt1 < dt2);
-} /* datetime_lt() */
+ return (dt1 < dt2);
+} /* datetime_lt() */
bool
-datetime_gt(DateTime *datetime1, DateTime *datetime2)
+datetime_gt(DateTime * datetime1, DateTime * datetime2)
{
- DateTime dt1, dt2;
+ DateTime dt1,
+ dt2;
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return FALSE;
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return FALSE;
- dt1 = *datetime1;
- dt2 = *datetime2;
+ dt1 = *datetime1;
+ dt2 = *datetime2;
- if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
- return FALSE;
+ if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
+ return FALSE;
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
#ifdef DATEDEBUG
-printf( "datetime_gt- %f %s greater than %f\n", dt1, ((dt1 > dt2)? "is": "is not"), dt2);
+ printf("datetime_gt- %f %s greater than %f\n", dt1, ((dt1 > dt2) ? "is" : "is not"), dt2);
#endif
- return( dt1 > dt2);
-} /* datetime_gt() */
+ return (dt1 > dt2);
+} /* datetime_gt() */
bool
-datetime_le(DateTime *datetime1, DateTime *datetime2)
+datetime_le(DateTime * datetime1, DateTime * datetime2)
{
- DateTime dt1, dt2;
+ DateTime dt1,
+ dt2;
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return FALSE;
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return FALSE;
- dt1 = *datetime1;
- dt2 = *datetime2;
+ dt1 = *datetime1;
+ dt2 = *datetime2;
- if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
- return FALSE;
+ if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
+ return FALSE;
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
- return( dt1 <= dt2);
-} /* datetime_le() */
+ return (dt1 <= dt2);
+} /* datetime_le() */
bool
-datetime_ge(DateTime *datetime1, DateTime *datetime2)
+datetime_ge(DateTime * datetime1, DateTime * datetime2)
{
- DateTime dt1, dt2;
+ DateTime dt1,
+ dt2;
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return FALSE;
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return FALSE;
- dt1 = *datetime1;
- dt2 = *datetime2;
+ dt1 = *datetime1;
+ dt2 = *datetime2;
- if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
- return FALSE;
+ if (DATETIME_IS_INVALID(dt1) || DATETIME_IS_INVALID(dt2))
+ return FALSE;
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
- return( dt1 >= dt2);
-} /* datetime_ge() */
+ return (dt1 >= dt2);
+} /* datetime_ge() */
-/* datetime_cmp - 3-state comparison for datetime
- * collate invalid datetime at the end
+/* datetime_cmp - 3-state comparison for datetime
+ * collate invalid datetime at the end
*/
int
-datetime_cmp(DateTime *datetime1, DateTime *datetime2)
+datetime_cmp(DateTime * datetime1, DateTime * datetime2)
{
- DateTime dt1, dt2;
+ DateTime dt1,
+ dt2;
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return 0;
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return 0;
- dt1 = *datetime1;
- dt2 = *datetime2;
+ dt1 = *datetime1;
+ dt2 = *datetime2;
- if (DATETIME_IS_INVALID(dt1)) {
- return( (DATETIME_IS_INVALID(dt2)? 0: 1));
+ if (DATETIME_IS_INVALID(dt1))
+ {
+ return ((DATETIME_IS_INVALID(dt2) ? 0 : 1));
- } else if (DATETIME_IS_INVALID(dt2)) {
- return( -1);
+ }
+ else if (DATETIME_IS_INVALID(dt2))
+ {
+ return (-1);
- } else {
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
- }
+ }
+ else
+ {
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
+ }
- return( ((dt1 < dt2)? -1: ((dt1 > dt2)? 1: 0)));
-} /* datetime_cmp() */
+ return (((dt1 < dt2) ? -1 : ((dt1 > dt2) ? 1 : 0)));
+} /* datetime_cmp() */
-/* timespan_relop - is timespan1 relop timespan2
+/* timespan_relop - is timespan1 relop timespan2
*/
bool
-timespan_eq(TimeSpan *timespan1, TimeSpan *timespan2)
+timespan_eq(TimeSpan * timespan1, TimeSpan * timespan2)
{
- if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
- return FALSE;
+ if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
+ return FALSE;
- if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
- return FALSE;
+ if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
+ return FALSE;
- return( (timespan1->time == timespan2->time)
- && (timespan1->month == timespan2->month));
-} /* timespan_eq() */
+ return ((timespan1->time == timespan2->time)
+ && (timespan1->month == timespan2->month));
+} /* timespan_eq() */
bool
-timespan_ne(TimeSpan *timespan1, TimeSpan *timespan2)
+timespan_ne(TimeSpan * timespan1, TimeSpan * timespan2)
{
- if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
- return FALSE;
+ if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
+ return FALSE;
- if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
- return FALSE;
+ if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
+ return FALSE;
- return( (timespan1->time != timespan2->time)
- || (timespan1->month != timespan2->month));
-} /* timespan_ne() */
+ return ((timespan1->time != timespan2->time)
+ || (timespan1->month != timespan2->month));
+} /* timespan_ne() */
bool
-timespan_lt(TimeSpan *timespan1, TimeSpan *timespan2)
+timespan_lt(TimeSpan * timespan1, TimeSpan * timespan2)
{
- double span1, span2;
+ double span1,
+ span2;
- if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
- return FALSE;
+ if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
+ return FALSE;
- if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
- return FALSE;
+ if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
+ return FALSE;
- span1 = timespan1->time;
- if (timespan1->month != 0) span1 += (timespan1->month * (30.0*86400));
- span2 = timespan2->time;
- if (timespan2->month != 0) span2 += (timespan2->month * (30.0*86400));
+ span1 = timespan1->time;
+ if (timespan1->month != 0)
+ span1 += (timespan1->month * (30.0 * 86400));
+ span2 = timespan2->time;
+ if (timespan2->month != 0)
+ span2 += (timespan2->month * (30.0 * 86400));
- return( span1 < span2);
-} /* timespan_lt() */
+ return (span1 < span2);
+} /* timespan_lt() */
bool
-timespan_gt(TimeSpan *timespan1, TimeSpan *timespan2)
+timespan_gt(TimeSpan * timespan1, TimeSpan * timespan2)
{
- double span1, span2;
+ double span1,
+ span2;
- if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
- return FALSE;
+ if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
+ return FALSE;
- if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
- return FALSE;
+ if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
+ return FALSE;
- span1 = timespan1->time;
- if (timespan1->month != 0) span1 += (timespan1->month * (30.0*86400));
- span2 = timespan2->time;
- if (timespan2->month != 0) span2 += (timespan2->month * (30.0*86400));
+ span1 = timespan1->time;
+ if (timespan1->month != 0)
+ span1 += (timespan1->month * (30.0 * 86400));
+ span2 = timespan2->time;
+ if (timespan2->month != 0)
+ span2 += (timespan2->month * (30.0 * 86400));
- return( span1 > span2);
-} /* timespan_gt() */
+ return (span1 > span2);
+} /* timespan_gt() */
bool
-timespan_le(TimeSpan *timespan1, TimeSpan *timespan2)
+timespan_le(TimeSpan * timespan1, TimeSpan * timespan2)
{
- double span1, span2;
+ double span1,
+ span2;
- if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
- return FALSE;
+ if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
+ return FALSE;
- if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
- return FALSE;
+ if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
+ return FALSE;
- span1 = timespan1->time;
- if (timespan1->month != 0) span1 += (timespan1->month * (30.0*86400));
- span2 = timespan2->time;
- if (timespan2->month != 0) span2 += (timespan2->month * (30.0*86400));
+ span1 = timespan1->time;
+ if (timespan1->month != 0)
+ span1 += (timespan1->month * (30.0 * 86400));
+ span2 = timespan2->time;
+ if (timespan2->month != 0)
+ span2 += (timespan2->month * (30.0 * 86400));
- return( span1 <= span2);
-} /* timespan_le() */
+ return (span1 <= span2);
+} /* timespan_le() */
bool
-timespan_ge(TimeSpan *timespan1, TimeSpan *timespan2)
+timespan_ge(TimeSpan * timespan1, TimeSpan * timespan2)
{
- double span1, span2;
+ double span1,
+ span2;
- if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
- return FALSE;
+ if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
+ return FALSE;
- if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
- return FALSE;
+ if (TIMESPAN_IS_INVALID(*timespan1) || TIMESPAN_IS_INVALID(*timespan2))
+ return FALSE;
- span1 = timespan1->time;
- if (timespan1->month != 0) span1 += (timespan1->month * (30.0*86400));
- span2 = timespan2->time;
- if (timespan2->month != 0) span2 += (timespan2->month * (30.0*86400));
+ span1 = timespan1->time;
+ if (timespan1->month != 0)
+ span1 += (timespan1->month * (30.0 * 86400));
+ span2 = timespan2->time;
+ if (timespan2->month != 0)
+ span2 += (timespan2->month * (30.0 * 86400));
- return( span1 >= span2);
-} /* timespan_ge() */
+ return (span1 >= span2);
+} /* timespan_ge() */
-/* timespan_cmp - 3-state comparison for timespan
+/* timespan_cmp - 3-state comparison for timespan
*/
int
-timespan_cmp(TimeSpan *timespan1, TimeSpan *timespan2)
+timespan_cmp(TimeSpan * timespan1, TimeSpan * timespan2)
{
- double span1, span2;
+ double span1,
+ span2;
- if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
- return 0;
+ if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
+ return 0;
- if (TIMESPAN_IS_INVALID(*timespan1)) {
- return( TIMESPAN_IS_INVALID(*timespan2)? 0: 1);
+ if (TIMESPAN_IS_INVALID(*timespan1))
+ {
+ return (TIMESPAN_IS_INVALID(*timespan2) ? 0 : 1);
- } else if (TIMESPAN_IS_INVALID(*timespan2)) {
- return( -1);
- }
+ }
+ else if (TIMESPAN_IS_INVALID(*timespan2))
+ {
+ return (-1);
+ }
- span1 = timespan1->time;
- if (timespan1->month != 0) span1 += (timespan1->month * (30.0*86400));
- span2 = timespan2->time;
- if (timespan2->month != 0) span2 += (timespan2->month * (30.0*86400));
+ span1 = timespan1->time;
+ if (timespan1->month != 0)
+ span1 += (timespan1->month * (30.0 * 86400));
+ span2 = timespan2->time;
+ if (timespan2->month != 0)
+ span2 += (timespan2->month * (30.0 * 86400));
- return( (span1 < span2)? -1: (span1 > span2)? 1: 0);
-} /* timespan_cmp() */
+ return ((span1 < span2) ? -1 : (span1 > span2) ? 1 : 0);
+} /* timespan_cmp() */
/*----------------------------------------------------------
- * "Arithmetic" operators on date/times.
- * datetime_foo returns foo as an object (pointer) that
- * can be passed between languages.
- * datetime_xx is an internal routine which returns the
- * actual value.
+ * "Arithmetic" operators on date/times.
+ * datetime_foo returns foo as an object (pointer) that
+ * can be passed between languages.
+ * datetime_xx is an internal routine which returns the
+ * actual value.
*---------------------------------------------------------*/
-DateTime *
-datetime_smaller(DateTime *datetime1, DateTime *datetime2)
+DateTime *
+datetime_smaller(DateTime * datetime1, DateTime * datetime2)
{
- DateTime *result;
+ DateTime *result;
- DateTime dt1, dt2;
+ DateTime dt1,
+ dt2;
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return NULL;
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return NULL;
- dt1 = *datetime1;
- dt2 = *datetime2;
+ dt1 = *datetime1;
+ dt2 = *datetime2;
- result = PALLOCTYPE(DateTime);
+ result = PALLOCTYPE(DateTime);
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
- if (DATETIME_IS_INVALID(dt1)) {
- *result = dt2;
- } else if (DATETIME_IS_INVALID(dt2)) {
- *result = dt1;
- } else {
- *result = ((dt2 < dt1)? dt2: dt1);
- }
+ if (DATETIME_IS_INVALID(dt1))
+ {
+ *result = dt2;
+ }
+ else if (DATETIME_IS_INVALID(dt2))
+ {
+ *result = dt1;
+ }
+ else
+ {
+ *result = ((dt2 < dt1) ? dt2 : dt1);
+ }
- return(result);
-} /* datetime_smaller() */
+ return (result);
+} /* datetime_smaller() */
-DateTime *
-datetime_larger(DateTime *datetime1, DateTime *datetime2)
+DateTime *
+datetime_larger(DateTime * datetime1, DateTime * datetime2)
{
- DateTime *result;
+ DateTime *result;
- DateTime dt1, dt2;
+ DateTime dt1,
+ dt2;
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return NULL;
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return NULL;
- dt1 = *datetime1;
- dt2 = *datetime2;
+ dt1 = *datetime1;
+ dt2 = *datetime2;
- result = PALLOCTYPE(DateTime);
+ result = PALLOCTYPE(DateTime);
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
- if (DATETIME_IS_INVALID(dt1)) {
- *result = dt2;
- } else if (DATETIME_IS_INVALID(dt2)) {
- *result = dt1;
- } else {
- *result = ((dt2 > dt1)? dt2: dt1);
- }
+ if (DATETIME_IS_INVALID(dt1))
+ {
+ *result = dt2;
+ }
+ else if (DATETIME_IS_INVALID(dt2))
+ {
+ *result = dt1;
+ }
+ else
+ {
+ *result = ((dt2 > dt1) ? dt2 : dt1);
+ }
- return(result);
-} /* datetime_larger() */
+ return (result);
+} /* datetime_larger() */
-TimeSpan *
-datetime_mi(DateTime *datetime1, DateTime *datetime2)
+TimeSpan *
+datetime_mi(DateTime * datetime1, DateTime * datetime2)
{
- TimeSpan *result;
+ TimeSpan *result;
- DateTime dt1, dt2;
+ DateTime dt1,
+ dt2;
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return NULL;
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return NULL;
- dt1 = *datetime1;
- dt2 = *datetime2;
+ dt1 = *datetime1;
+ dt2 = *datetime2;
- result = PALLOCTYPE(TimeSpan);
+ result = PALLOCTYPE(TimeSpan);
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
#ifdef DATEDEBUG
-printf( "datetime_mi- evaluate %f - %f\n", dt1, dt2);
+ printf("datetime_mi- evaluate %f - %f\n", dt1, dt2);
#endif
- if (DATETIME_IS_INVALID(dt1)
- || DATETIME_IS_INVALID(dt2)) {
- DATETIME_INVALID( result->time);
+ if (DATETIME_IS_INVALID(dt1)
+ || DATETIME_IS_INVALID(dt2))
+ {
+ DATETIME_INVALID(result->time);
- } else {
- result->time = JROUND(dt1 - dt2);
- }
- result->month = 0;
+ }
+ else
+ {
+ result->time = JROUND(dt1 - dt2);
+ }
+ result->month = 0;
- return(result);
-} /* datetime_mi() */
+ return (result);
+} /* datetime_mi() */
/* datetime_pl_span()
* Add a timespan to a datetime data type.
* Note that timespan has provisions for qualitative year/month
- * units, so try to do the right thing with them.
+ * units, so try to do the right thing with them.
* To add a month, increment the month, and use the same day of month.
* Then, if the next month has fewer days, set the day of month
- * to the last day of month.
+ * to the last day of month.
*/
-DateTime *
-datetime_pl_span(DateTime *datetime, TimeSpan *span)
+DateTime *
+datetime_pl_span(DateTime * datetime, TimeSpan * span)
{
- DateTime *result;
- DateTime dt;
- int tz;
- char *tzn;
+ DateTime *result;
+ DateTime dt;
+ int tz;
+ char *tzn;
- if ((!PointerIsValid(datetime)) || (!PointerIsValid(span)))
- return NULL;
+ if ((!PointerIsValid(datetime)) || (!PointerIsValid(span)))
+ return NULL;
- result = PALLOCTYPE(DateTime);
+ result = PALLOCTYPE(DateTime);
#ifdef DATEDEBUG
-printf( "datetime_pl_span- add %f to %d %f\n", *datetime, span->month, span->time);
+ printf("datetime_pl_span- add %f to %d %f\n", *datetime, span->month, span->time);
#endif
- if (DATETIME_NOT_FINITE(*datetime)) {
- *result = *datetime;
+ if (DATETIME_NOT_FINITE(*datetime))
+ {
+ *result = *datetime;
- } else if (TIMESPAN_IS_INVALID(*span)) {
- DATETIME_INVALID(*result);
+ }
+ else if (TIMESPAN_IS_INVALID(*span))
+ {
+ DATETIME_INVALID(*result);
- } else {
- dt = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime);
+ }
+ else
+ {
+ dt = (DATETIME_IS_RELATIVE(*datetime) ? SetDateTime(*datetime) : *datetime);
#ifdef ROUND_ALL
- dt = JROUND(dt + span->time);
+ dt = JROUND(dt + span->time);
#else
- dt += span->time;
+ dt += span->time;
#endif
- if (span->month != 0) {
- struct tm tt, *tm = &tt;
- double fsec;
+ if (span->month != 0)
+ {
+ struct tm tt,
+ *tm = &tt;
+ double fsec;
- if (datetime2tm( dt, &tz, tm, &fsec, &tzn) == 0) {
+ if (datetime2tm(dt, &tz, tm, &fsec, &tzn) == 0)
+ {
#ifdef DATEDEBUG
-printf( "datetime_pl_span- date was %04d-%02d-%02d %02d:%02d:%02d\n",
- tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+ printf("datetime_pl_span- date was %04d-%02d-%02d %02d:%02d:%02d\n",
+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
#endif
- tm->tm_mon += span->month;
- if (tm->tm_mon > 12) {
- tm->tm_year += ((tm->tm_mon-1) / 12);
- tm->tm_mon = (((tm->tm_mon-1) % 12) + 1);
- } else if (tm->tm_mon < 1) {
- tm->tm_year += ((tm->tm_mon / 12) - 1);
- tm->tm_mon = ((tm->tm_mon % 12) + 12);
- }
-
- /* adjust for end of month boundary problems... */
- if (tm->tm_mday > mdays[ tm->tm_mon-1]) {
- if ((tm->tm_mon == 2) && isleap( tm->tm_year)) {
- tm->tm_mday = (mdays[ tm->tm_mon-1]+1);
- } else {
- tm->tm_mday = mdays[ tm->tm_mon-1];
- }
- }
+ tm->tm_mon += span->month;
+ if (tm->tm_mon > 12)
+ {
+ tm->tm_year += ((tm->tm_mon - 1) / 12);
+ tm->tm_mon = (((tm->tm_mon - 1) % 12) + 1);
+ }
+ else if (tm->tm_mon < 1)
+ {
+ tm->tm_year += ((tm->tm_mon / 12) - 1);
+ tm->tm_mon = ((tm->tm_mon % 12) + 12);
+ }
+
+ /* adjust for end of month boundary problems... */
+ if (tm->tm_mday > mdays[tm->tm_mon - 1])
+ {
+ if ((tm->tm_mon == 2) && isleap(tm->tm_year))
+ {
+ tm->tm_mday = (mdays[tm->tm_mon - 1] + 1);
+ }
+ else
+ {
+ tm->tm_mday = mdays[tm->tm_mon - 1];
+ }
+ }
#ifdef DATEDEBUG
-printf( "datetime_pl_span- date becomes %04d-%02d-%02d %02d:%02d:%02d\n",
- tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+ printf("datetime_pl_span- date becomes %04d-%02d-%02d %02d:%02d:%02d\n",
+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
#endif
- if (tm2datetime( tm, fsec, &tz, &dt) != 0)
- elog(WARN,"Unable to add datetime and timespan",NULL);
+ if (tm2datetime(tm, fsec, &tz, &dt) != 0)
+ elog(WARN, "Unable to add datetime and timespan", NULL);
+
+ }
+ else
+ {
+ DATETIME_INVALID(dt);
+ }
+ }
- } else {
- DATETIME_INVALID(dt);
- }
+ *result = dt;
}
- *result = dt;
- }
-
- return(result);
-} /* datetime_pl_span() */
+ return (result);
+} /* datetime_pl_span() */
-DateTime *
-datetime_mi_span(DateTime *datetime, TimeSpan *span)
+DateTime *
+datetime_mi_span(DateTime * datetime, TimeSpan * span)
{
- DateTime *result;
- TimeSpan tspan;
+ DateTime *result;
+ TimeSpan tspan;
- if (!PointerIsValid(datetime) || !PointerIsValid(span))
- return NULL;
+ if (!PointerIsValid(datetime) || !PointerIsValid(span))
+ return NULL;
- tspan.month = -span->month;
- tspan.time = -span->time;
+ tspan.month = -span->month;
+ tspan.time = -span->time;
- result = datetime_pl_span( datetime, &tspan);
+ result = datetime_pl_span(datetime, &tspan);
- return(result);
-} /* datetime_mi_span() */
+ return (result);
+} /* datetime_mi_span() */
-TimeSpan *
-timespan_um(TimeSpan *timespan)
+TimeSpan *
+timespan_um(TimeSpan * timespan)
{
- TimeSpan *result;
+ TimeSpan *result;
- if (!PointerIsValid(timespan))
- return NULL;
+ if (!PointerIsValid(timespan))
+ return NULL;
- result = PALLOCTYPE(TimeSpan);
+ result = PALLOCTYPE(TimeSpan);
- result->time = -(timespan->time);
- result->month = -(timespan->month);
+ result->time = -(timespan->time);
+ result->month = -(timespan->month);
- return(result);
-} /* timespan_um() */
+ return (result);
+} /* timespan_um() */
-TimeSpan *
-timespan_smaller(TimeSpan *timespan1, TimeSpan *timespan2)
+TimeSpan *
+timespan_smaller(TimeSpan * timespan1, TimeSpan * timespan2)
{
- TimeSpan *result;
+ TimeSpan *result;
- double span1, span2;
+ double span1,
+ span2;
- if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
- return NULL;
+ if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
+ return NULL;
- result = PALLOCTYPE(TimeSpan);
+ result = PALLOCTYPE(TimeSpan);
- if (TIMESPAN_IS_INVALID(*timespan1)) {
- result->time = timespan2->time;
- result->month = timespan2->month;
+ if (TIMESPAN_IS_INVALID(*timespan1))
+ {
+ result->time = timespan2->time;
+ result->month = timespan2->month;
- } else if (TIMESPAN_IS_INVALID(*timespan2)) {
- result->time = timespan1->time;
- result->month = timespan1->month;
+ }
+ else if (TIMESPAN_IS_INVALID(*timespan2))
+ {
+ result->time = timespan1->time;
+ result->month = timespan1->month;
- } else {
- span1 = timespan1->time;
- if (timespan1->month != 0) span1 += (timespan1->month * (30.0*86400));
- span2 = timespan2->time;
- if (timespan2->month != 0) span2 += (timespan2->month * (30.0*86400));
+ }
+ else
+ {
+ span1 = timespan1->time;
+ if (timespan1->month != 0)
+ span1 += (timespan1->month * (30.0 * 86400));
+ span2 = timespan2->time;
+ if (timespan2->month != 0)
+ span2 += (timespan2->month * (30.0 * 86400));
#ifdef DATEDEBUG
-printf( "timespan_smaller- months %d %d times %f %f spans %f %f\n",
- timespan1->month, timespan2->month, timespan1->time, timespan2->time, span1, span2);
+ printf("timespan_smaller- months %d %d times %f %f spans %f %f\n",
+ timespan1->month, timespan2->month, timespan1->time, timespan2->time, span1, span2);
#endif
- if (span2 < span1) {
- result->time = timespan2->time;
- result->month = timespan2->month;
+ if (span2 < span1)
+ {
+ result->time = timespan2->time;
+ result->month = timespan2->month;
- } else {
- result->time = timespan1->time;
- result->month = timespan1->month;
+ }
+ else
+ {
+ result->time = timespan1->time;
+ result->month = timespan1->month;
+ }
}
- }
- return(result);
-} /* timespan_smaller() */
+ return (result);
+} /* timespan_smaller() */
-TimeSpan *
-timespan_larger(TimeSpan *timespan1, TimeSpan *timespan2)
+TimeSpan *
+timespan_larger(TimeSpan * timespan1, TimeSpan * timespan2)
{
- TimeSpan *result;
+ TimeSpan *result;
- double span1, span2;
+ double span1,
+ span2;
- if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
- return NULL;
+ if (!PointerIsValid(timespan1) || !PointerIsValid(timespan2))
+ return NULL;
- result = PALLOCTYPE(TimeSpan);
+ result = PALLOCTYPE(TimeSpan);
- if (TIMESPAN_IS_INVALID(*timespan1)) {
- result->time = timespan2->time;
- result->month = timespan2->month;
+ if (TIMESPAN_IS_INVALID(*timespan1))
+ {
+ result->time = timespan2->time;
+ result->month = timespan2->month;
- } else if (TIMESPAN_IS_INVALID(*timespan2)) {
- result->time = timespan1->time;
- result->month = timespan1->month;
+ }
+ else if (TIMESPAN_IS_INVALID(*timespan2))
+ {
+ result->time = timespan1->time;
+ result->month = timespan1->month;
- } else {
- span1 = timespan1->time;
- if (timespan1->month != 0) span1 += (timespan1->month * (30.0*86400));
- span2 = timespan2->time;
- if (timespan2->month != 0) span2 += (timespan2->month * (30.0*86400));
+ }
+ else
+ {
+ span1 = timespan1->time;
+ if (timespan1->month != 0)
+ span1 += (timespan1->month * (30.0 * 86400));
+ span2 = timespan2->time;
+ if (timespan2->month != 0)
+ span2 += (timespan2->month * (30.0 * 86400));
#ifdef DATEDEBUG
-printf( "timespan_larger- months %d %d times %f %f spans %f %f\n",
- timespan1->month, timespan2->month, timespan1->time, timespan2->time, span1, span2);
+ printf("timespan_larger- months %d %d times %f %f spans %f %f\n",
+ timespan1->month, timespan2->month, timespan1->time, timespan2->time, span1, span2);
#endif
- if (span2 > span1) {
- result->time = timespan2->time;
- result->month = timespan2->month;
+ if (span2 > span1)
+ {
+ result->time = timespan2->time;
+ result->month = timespan2->month;
- } else {
- result->time = timespan1->time;
- result->month = timespan1->month;
+ }
+ else
+ {
+ result->time = timespan1->time;
+ result->month = timespan1->month;
+ }
}
- }
- return(result);
-} /* timespan_larger() */
+ return (result);
+} /* timespan_larger() */
-TimeSpan *
-timespan_pl(TimeSpan *span1, TimeSpan *span2)
+TimeSpan *
+timespan_pl(TimeSpan * span1, TimeSpan * span2)
{
- TimeSpan *result;
+ TimeSpan *result;
- if ((!PointerIsValid(span1)) || (!PointerIsValid(span2)))
- return NULL;
+ if ((!PointerIsValid(span1)) || (!PointerIsValid(span2)))
+ return NULL;
- result = PALLOCTYPE(TimeSpan);
+ result = PALLOCTYPE(TimeSpan);
- result->month = (span1->month + span2->month);
- result->time = JROUND(span1->time + span2->time);
+ result->month = (span1->month + span2->month);
+ result->time = JROUND(span1->time + span2->time);
- return(result);
-} /* timespan_pl() */
+ return (result);
+} /* timespan_pl() */
-TimeSpan *
-timespan_mi(TimeSpan *span1, TimeSpan *span2)
+TimeSpan *
+timespan_mi(TimeSpan * span1, TimeSpan * span2)
{
- TimeSpan *result;
+ TimeSpan *result;
- if ((!PointerIsValid(span1)) || (!PointerIsValid(span2)))
- return NULL;
+ if ((!PointerIsValid(span1)) || (!PointerIsValid(span2)))
+ return NULL;
- result = PALLOCTYPE(TimeSpan);
+ result = PALLOCTYPE(TimeSpan);
- result->month = (span1->month - span2->month);
- result->time = JROUND(span1->time - span2->time);
+ result->month = (span1->month - span2->month);
+ result->time = JROUND(span1->time - span2->time);
- return(result);
-} /* timespan_mi() */
+ return (result);
+} /* timespan_mi() */
-TimeSpan *
-timespan_div(TimeSpan *span1, float8 *arg2)
+TimeSpan *
+timespan_div(TimeSpan * span1, float8 * arg2)
{
- TimeSpan *result;
+ TimeSpan *result;
- if ((!PointerIsValid(span1)) || (!PointerIsValid(arg2)))
- return NULL;
+ if ((!PointerIsValid(span1)) || (!PointerIsValid(arg2)))
+ return NULL;
- if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
- elog(WARN,"Memory allocation failed, can't subtract timespans",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
+ elog(WARN, "Memory allocation failed, can't subtract timespans", NULL);
- if (*arg2 == 0.0)
- elog(WARN,"timespan_div: divide by 0.0 error");
+ if (*arg2 == 0.0)
+ elog(WARN, "timespan_div: divide by 0.0 error");
- result->month = rint(span1->month / *arg2);
- result->time = JROUND(span1->time / *arg2);
+ result->month = rint(span1->month / *arg2);
+ result->time = JROUND(span1->time / *arg2);
- return(result);
-} /* timespan_div() */
+ return (result);
+} /* timespan_div() */
/* datetime_age()
* Calculate time difference while retaining year/month fields.
* Note that this does not result in an accurate absolute time span
- * since year and month are out of context once the arithmetic
- * is done.
+ * since year and month are out of context once the arithmetic
+ * is done.
*/
-TimeSpan *
-datetime_age(DateTime *datetime1, DateTime *datetime2)
+TimeSpan *
+datetime_age(DateTime * datetime1, DateTime * datetime2)
{
- TimeSpan *result;
-
- DateTime dt1, dt2;
- double fsec, fsec1, fsec2;
- struct tm tt, *tm = &tt;
- struct tm tt1, *tm1 = &tt1;
- struct tm tt2, *tm2 = &tt2;
+ TimeSpan *result;
+
+ DateTime dt1,
+ dt2;
+ double fsec,
+ fsec1,
+ fsec2;
+ struct tm tt,
+ *tm = &tt;
+ struct tm tt1,
+ *tm1 = &tt1;
+ struct tm tt2,
+ *tm2 = &tt2;
+
+ if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
+ return NULL;
+
+ result = PALLOCTYPE(TimeSpan);
+
+ dt1 = *datetime1;
+ dt2 = *datetime2;
+
+ if (DATETIME_IS_RELATIVE(dt1))
+ dt1 = SetDateTime(dt1);
+ if (DATETIME_IS_RELATIVE(dt2))
+ dt2 = SetDateTime(dt2);
+
+ if (DATETIME_IS_INVALID(dt1)
+ || DATETIME_IS_INVALID(dt2))
+ {
+ DATETIME_INVALID(result->time);
- if (!PointerIsValid(datetime1) || !PointerIsValid(datetime2))
- return NULL;
-
- result = PALLOCTYPE(TimeSpan);
-
- dt1 = *datetime1;
- dt2 = *datetime2;
-
- if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
- if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
-
- if (DATETIME_IS_INVALID(dt1)
- || DATETIME_IS_INVALID(dt2)) {
- DATETIME_INVALID( result->time);
-
- } else if ((datetime2tm( dt1, NULL, tm1, &fsec1, NULL) == 0)
- &&(datetime2tm( dt2, NULL, tm2, &fsec2, NULL) == 0)) {
- fsec = (fsec1 - fsec2);
- tm->tm_sec = (tm1->tm_sec - tm2->tm_sec);
- tm->tm_min = (tm1->tm_min - tm2->tm_min);
- tm->tm_hour = (tm1->tm_hour - tm2->tm_hour);
- tm->tm_mday = (tm1->tm_mday - tm2->tm_mday);
- tm->tm_mon = (tm1->tm_mon - tm2->tm_mon);
- tm->tm_year = (tm1->tm_year - tm2->tm_year);
-
- /* flip sign if necessary... */
- if (dt1 < dt2) {
- fsec = -fsec;
- tm->tm_sec = -tm->tm_sec;
- tm->tm_min = -tm->tm_min;
- tm->tm_hour = -tm->tm_hour;
- tm->tm_mday = -tm->tm_mday;
- tm->tm_mon = -tm->tm_mon;
- tm->tm_year = -tm->tm_year;
}
+ else if ((datetime2tm(dt1, NULL, tm1, &fsec1, NULL) == 0)
+ && (datetime2tm(dt2, NULL, tm2, &fsec2, NULL) == 0))
+ {
+ fsec = (fsec1 - fsec2);
+ tm->tm_sec = (tm1->tm_sec - tm2->tm_sec);
+ tm->tm_min = (tm1->tm_min - tm2->tm_min);
+ tm->tm_hour = (tm1->tm_hour - tm2->tm_hour);
+ tm->tm_mday = (tm1->tm_mday - tm2->tm_mday);
+ tm->tm_mon = (tm1->tm_mon - tm2->tm_mon);
+ tm->tm_year = (tm1->tm_year - tm2->tm_year);
+
+ /* flip sign if necessary... */
+ if (dt1 < dt2)
+ {
+ fsec = -fsec;
+ tm->tm_sec = -tm->tm_sec;
+ tm->tm_min = -tm->tm_min;
+ tm->tm_hour = -tm->tm_hour;
+ tm->tm_mday = -tm->tm_mday;
+ tm->tm_mon = -tm->tm_mon;
+ tm->tm_year = -tm->tm_year;
+ }
- if (tm->tm_sec < 0) {
- tm->tm_sec += 60;
- tm->tm_min--;
- }
+ if (tm->tm_sec < 0)
+ {
+ tm->tm_sec += 60;
+ tm->tm_min--;
+ }
- if (tm->tm_min < 0) {
- tm->tm_min += 60;
- tm->tm_hour--;
- }
+ if (tm->tm_min < 0)
+ {
+ tm->tm_min += 60;
+ tm->tm_hour--;
+ }
- if (tm->tm_hour < 0) {
- tm->tm_hour += 24;
- tm->tm_mday--;
- }
+ if (tm->tm_hour < 0)
+ {
+ tm->tm_hour += 24;
+ tm->tm_mday--;
+ }
- if (tm->tm_mday < 0) {
- if (dt1 < dt2) {
- tm->tm_mday += mdays[tm1->tm_mon-1];
- if (isleap(tm1->tm_year) && (tm1->tm_mon == 2)) tm->tm_mday++;
- tm->tm_mon--;
- } else {
- tm->tm_mday += mdays[tm2->tm_mon-1];
- if (isleap(tm2->tm_year) && (tm2->tm_mon == 2)) tm->tm_mday++;
- tm->tm_mon--;
- }
- }
+ if (tm->tm_mday < 0)
+ {
+ if (dt1 < dt2)
+ {
+ tm->tm_mday += mdays[tm1->tm_mon - 1];
+ if (isleap(tm1->tm_year) && (tm1->tm_mon == 2))
+ tm->tm_mday++;
+ tm->tm_mon--;
+ }
+ else
+ {
+ tm->tm_mday += mdays[tm2->tm_mon - 1];
+ if (isleap(tm2->tm_year) && (tm2->tm_mon == 2))
+ tm->tm_mday++;
+ tm->tm_mon--;
+ }
+ }
- if (tm->tm_mon < 0) {
- tm->tm_mon += 12;
- tm->tm_year--;
- }
+ if (tm->tm_mon < 0)
+ {
+ tm->tm_mon += 12;
+ tm->tm_year--;
+ }
- /* recover sign if necessary... */
- if (dt1 < dt2) {
- fsec = -fsec;
- tm->tm_sec = -tm->tm_sec;
- tm->tm_min = -tm->tm_min;
- tm->tm_hour = -tm->tm_hour;
- tm->tm_mday = -tm->tm_mday;
- tm->tm_mon = -tm->tm_mon;
- tm->tm_year = -tm->tm_year;
- }
+ /* recover sign if necessary... */
+ if (dt1 < dt2)
+ {
+ fsec = -fsec;
+ tm->tm_sec = -tm->tm_sec;
+ tm->tm_min = -tm->tm_min;
+ tm->tm_hour = -tm->tm_hour;
+ tm->tm_mday = -tm->tm_mday;
+ tm->tm_mon = -tm->tm_mon;
+ tm->tm_year = -tm->tm_year;
+ }
- if (tm2timespan(tm, fsec, result) != 0) {
- elog(WARN,"Unable to decode datetime",NULL);
- }
+ if (tm2timespan(tm, fsec, result) != 0)
+ {
+ elog(WARN, "Unable to decode datetime", NULL);
+ }
#if FALSE
- result->time = (fsec2 - fsec1);
- result->time += (tm2->tm_sec - tm1->tm_sec);
- result->time += 60*(tm2->tm_min - tm1->tm_min);
- result->time += 3600*(tm2->tm_hour - tm1->tm_hour);
- result->time += 86400*(tm2->tm_mday - tm1->tm_mday);
-
- result->month = 12*(tm2->tm_year - tm1->tm_year);
- result->month += (tm2->tm_mon - tm1->tm_mon);
+ result->time = (fsec2 - fsec1);
+ result->time += (tm2->tm_sec - tm1->tm_sec);
+ result->time += 60 * (tm2->tm_min - tm1->tm_min);
+ result->time += 3600 * (tm2->tm_hour - tm1->tm_hour);
+ result->time += 86400 * (tm2->tm_mday - tm1->tm_mday);
+
+ result->month = 12 * (tm2->tm_year - tm1->tm_year);
+ result->month += (tm2->tm_mon - tm1->tm_mon);
#endif
- } else {
- elog(WARN,"Unable to decode datetime",NULL);
- }
+ }
+ else
+ {
+ elog(WARN, "Unable to decode datetime", NULL);
+ }
- return(result);
-} /* datetime_age() */
+ return (result);
+} /* datetime_age() */
/*----------------------------------------------------------
- * Conversion operators.
+ * Conversion operators.
*---------------------------------------------------------*/
/* datetime_text()
* Convert datetime to text data type.
*/
-text *
-datetime_text(DateTime *datetime)
+text *
+datetime_text(DateTime * datetime)
{
- text *result;
- char *str;
- int len;
+ text *result;
+ char *str;
+ int len;
- if (!PointerIsValid(datetime))
- return NULL;
+ if (!PointerIsValid(datetime))
+ return NULL;
- str = datetime_out(datetime);
+ str = datetime_out(datetime);
- if (!PointerIsValid(str))
- return NULL;
+ if (!PointerIsValid(str))
+ return NULL;
- len = (strlen(str)+VARHDRSZ);
+ len = (strlen(str) + VARHDRSZ);
- result = PALLOC(len);
+ result = PALLOC(len);
- VARSIZE(result) = len;
- memmove(VARDATA(result), str, (len-VARHDRSZ));
+ VARSIZE(result) = len;
+ memmove(VARDATA(result), str, (len - VARHDRSZ));
- PFREE(str);
+ PFREE(str);
- return(result);
-} /* datetime_text() */
+ return (result);
+} /* datetime_text() */
/* text_datetime()
* Convert text string to datetime.
* Text type is not null terminated, so use temporary string
- * then call the standard input routine.
+ * then call the standard input routine.
*/
-DateTime *
-text_datetime(text *str)
+DateTime *
+text_datetime(text * str)
{
- DateTime *result;
- int i;
- char *sp, *dp, dstr[MAXDATELEN+1];
+ DateTime *result;
+ int i;
+ char *sp,
+ *dp,
+ dstr[MAXDATELEN + 1];
- if (!PointerIsValid(str))
- return NULL;
+ if (!PointerIsValid(str))
+ return NULL;
- sp = VARDATA(str);
- dp = dstr;
- for (i = 0; i < (VARSIZE(str)-VARHDRSZ); i++) *dp++ = *sp++;
- *dp = '\0';
+ sp = VARDATA(str);
+ dp = dstr;
+ for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
+ *dp++ = *sp++;
+ *dp = '\0';
- result = datetime_in(dstr);
+ result = datetime_in(dstr);
- return(result);
-} /* text_datetime() */
+ return (result);
+} /* text_datetime() */
/* timespan_text()
* Convert timespan to text data type.
*/
-text *
-timespan_text(TimeSpan *timespan)
+text *
+timespan_text(TimeSpan * timespan)
{
- text *result;
- char *str;
- int len;
+ text *result;
+ char *str;
+ int len;
- if (!PointerIsValid(timespan))
- return NULL;
+ if (!PointerIsValid(timespan))
+ return NULL;
- str = timespan_out(timespan);
+ str = timespan_out(timespan);
- if (!PointerIsValid(str))
- return NULL;
+ if (!PointerIsValid(str))
+ return NULL;
- len = (strlen(str)+VARHDRSZ);
+ len = (strlen(str) + VARHDRSZ);
- result = PALLOC(len);
+ result = PALLOC(len);
- VARSIZE(result) = len;
- memmove(VARDATA(result), str, (len-VARHDRSZ));
+ VARSIZE(result) = len;
+ memmove(VARDATA(result), str, (len - VARHDRSZ));
- PFREE(str);
+ PFREE(str);
- return(result);
-} /* timespan_text() */
+ return (result);
+} /* timespan_text() */
/* text_timespan()
* Convert text string to timespan.
* Text type may not be null terminated, so copy to temporary string
- * then call the standard input routine.
+ * then call the standard input routine.
*/
#ifdef NOT_USED
-TimeSpan *
-text_timespan(text *str)
+TimeSpan *
+text_timespan(text * str)
{
- TimeSpan *result;
- int i;
- char *sp, *dp, dstr[MAXDATELEN+1];
+ TimeSpan *result;
+ int i;
+ char *sp,
+ *dp,
+ dstr[MAXDATELEN + 1];
- if (!PointerIsValid(str))
- return NULL;
+ if (!PointerIsValid(str))
+ return NULL;
+
+ sp = VARDATA(str);
+ dp = dstr;
+ for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
+ *dp++ = *sp++;
+ *dp = '\0';
- sp = VARDATA(str);
- dp = dstr;
- for (i = 0; i < (VARSIZE(str)-VARHDRSZ); i++) *dp++ = *sp++;
- *dp = '\0';
+ result = timespan_in(dstr);
- result = timespan_in(dstr);
+ return (result);
+} /* text_timespan() */
- return(result);
-} /* text_timespan() */
#endif
/* datetime_trunc()
* Extract specified field from datetime.
*/
-DateTime *
-datetime_trunc(text *units, DateTime *datetime)
+DateTime *
+datetime_trunc(text * units, DateTime * datetime)
{
- DateTime *result;
-
- DateTime dt;
- int tz;
- int type, val;
- int i;
- char *up, *lp, lowunits[MAXDATELEN+1];
- double fsec;
- char *tzn;
- struct tm tt, *tm = &tt;
-
- if ((!PointerIsValid(units)) || (!PointerIsValid(datetime)))
- return NULL;
-
- result = PALLOCTYPE(DateTime);
-
- up = VARDATA(units);
- lp = lowunits;
- for (i = 0; i < (VARSIZE(units)-VARHDRSZ); i++) *lp++ = tolower( *up++);
- *lp = '\0';
-
- type = DecodeUnits( 0, lowunits, &val);
+ DateTime *result;
+
+ DateTime dt;
+ int tz;
+ int type,
+ val;
+ int i;
+ char *up,
+ *lp,
+ lowunits[MAXDATELEN + 1];
+ double fsec;
+ char *tzn;
+ struct tm tt,
+ *tm = &tt;
+
+ if ((!PointerIsValid(units)) || (!PointerIsValid(datetime)))
+ return NULL;
+
+ result = PALLOCTYPE(DateTime);
+
+ up = VARDATA(units);
+ lp = lowunits;
+ for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
+ *lp++ = tolower(*up++);
+ *lp = '\0';
+
+ type = DecodeUnits(0, lowunits, &val);
#if FALSE
- if (type == IGNORE) {
- type = DecodeSpecial( 0, lowunits, &val);
- }
+ if (type == IGNORE)
+ {
+ type = DecodeSpecial(0, lowunits, &val);
+ }
#endif
#ifdef DATEDEBUG
-if (type == IGNORE) strcpy(lowunits, "(unknown)");
-printf( "datetime_trunc- units %s type=%d value=%d\n", lowunits, type, val);
+ if (type == IGNORE)
+ strcpy(lowunits, "(unknown)");
+ printf("datetime_trunc- units %s type=%d value=%d\n", lowunits, type, val);
#endif
- if (DATETIME_NOT_FINITE(*datetime)) {
+ if (DATETIME_NOT_FINITE(*datetime))
+ {
#if FALSE
/* should return null but Postgres doesn't like that currently. - tgl 97/06/12 */
- elog(WARN,"Datetime is not finite",NULL);
-#endif
- *result = 0;
-
- } else {
- dt = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime);
-
- if ((type == UNITS) && (datetime2tm( dt, &tz, tm, &fsec, &tzn) == 0)) {
- switch (val) {
- case DTK_MILLENIUM:
- tm->tm_year = (tm->tm_year/1000)*1000;
- case DTK_CENTURY:
- tm->tm_year = (tm->tm_year/100)*100;
- case DTK_DECADE:
- tm->tm_year = (tm->tm_year/10)*10;
- case DTK_YEAR:
- tm->tm_mon = 1;
- case DTK_QUARTER:
- tm->tm_mon = (3*(tm->tm_mon/4))+1;
- case DTK_MONTH:
- tm->tm_mday = 1;
- case DTK_DAY:
- tm->tm_hour = 0;
- case DTK_HOUR:
- tm->tm_min = 0;
- case DTK_MINUTE:
- tm->tm_sec = 0;
- case DTK_SECOND:
- fsec = 0;
- break;
-
- case DTK_MILLISEC:
- fsec = rint(fsec*1000)/1000;
- break;
-
- case DTK_MICROSEC:
- fsec = rint(fsec*1000)/1000;
- break;
-
- default:
- elog(WARN,"Datetime units %s not supported",lowunits);
- result = NULL;
- }
+ elog(WARN, "Datetime is not finite", NULL);
+#endif
+ *result = 0;
- if (IS_VALID_UTIME( tm->tm_year, tm->tm_mon, tm->tm_mday)) {
+ }
+ else
+ {
+ dt = (DATETIME_IS_RELATIVE(*datetime) ? SetDateTime(*datetime) : *datetime);
+
+ if ((type == UNITS) && (datetime2tm(dt, &tz, tm, &fsec, &tzn) == 0))
+ {
+ switch (val)
+ {
+ case DTK_MILLENIUM:
+ tm->tm_year = (tm->tm_year / 1000) * 1000;
+ case DTK_CENTURY:
+ tm->tm_year = (tm->tm_year / 100) * 100;
+ case DTK_DECADE:
+ tm->tm_year = (tm->tm_year / 10) * 10;
+ case DTK_YEAR:
+ tm->tm_mon = 1;
+ case DTK_QUARTER:
+ tm->tm_mon = (3 * (tm->tm_mon / 4)) + 1;
+ case DTK_MONTH:
+ tm->tm_mday = 1;
+ case DTK_DAY:
+ tm->tm_hour = 0;
+ case DTK_HOUR:
+ tm->tm_min = 0;
+ case DTK_MINUTE:
+ tm->tm_sec = 0;
+ case DTK_SECOND:
+ fsec = 0;
+ break;
+
+ case DTK_MILLISEC:
+ fsec = rint(fsec * 1000) / 1000;
+ break;
+
+ case DTK_MICROSEC:
+ fsec = rint(fsec * 1000) / 1000;
+ break;
+
+ default:
+ elog(WARN, "Datetime units %s not supported", lowunits);
+ result = NULL;
+ }
+
+ if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
+ {
#ifdef USE_POSIX_TIME
- tm->tm_isdst = -1;
- tm->tm_year -= 1900;
- tm->tm_mon -= 1;
- tm->tm_isdst = -1;
- mktime(tm);
- tm->tm_year += 1900;
- tm->tm_mon += 1;
+ tm->tm_isdst = -1;
+ tm->tm_year -= 1900;
+ tm->tm_mon -= 1;
+ tm->tm_isdst = -1;
+ mktime(tm);
+ tm->tm_year += 1900;
+ tm->tm_mon += 1;
#ifdef HAVE_INT_TIMEZONE
- tz = ((tm->tm_isdst > 0)? (timezone - 3600): timezone);
+ tz = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
-#else /* !HAVE_INT_TIMEZONE */
- tz = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
+#else /* !HAVE_INT_TIMEZONE */
+ tz = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
#endif
-#else /* !USE_POSIX_TIME */
- tz = CTimeZone;
+#else /* !USE_POSIX_TIME */
+ tz = CTimeZone;
#endif
- } else {
- tm->tm_isdst = 0;
- tz = 0;
- }
+ }
+ else
+ {
+ tm->tm_isdst = 0;
+ tz = 0;
+ }
- if (tm2datetime( tm, fsec, &tz, result) != 0)
- elog(WARN,"Unable to truncate datetime to %s",lowunits);
+ if (tm2datetime(tm, fsec, &tz, result) != 0)
+ elog(WARN, "Unable to truncate datetime to %s", lowunits);
#if FALSE
- } else if ((type == RESERV) && (val == DTK_EPOCH)) {
- DATETIME_EPOCH(*result);
- *result = dt - SetDateTime(*result);
+ }
+ else if ((type == RESERV) && (val == DTK_EPOCH))
+ {
+ DATETIME_EPOCH(*result);
+ *result = dt - SetDateTime(*result);
#endif
- } else {
- elog(WARN,"Datetime units %s not recognized",lowunits);
- result = NULL;
+ }
+ else
+ {
+ elog(WARN, "Datetime units %s not recognized", lowunits);
+ result = NULL;
+ }
}
- }
- return(result);
-} /* datetime_trunc() */
+ return (result);
+} /* datetime_trunc() */
/* timespan_trunc()
* Extract specified field from timespan.
*/
-TimeSpan *
-timespan_trunc(text *units, TimeSpan *timespan)
+TimeSpan *
+timespan_trunc(text * units, TimeSpan * timespan)
{
- TimeSpan *result;
-
- int type, val;
- int i;
- char *up, *lp, lowunits[MAXDATELEN+1];
- double fsec;
- struct tm tt, *tm = &tt;
-
- if ((!PointerIsValid(units)) || (!PointerIsValid(timespan)))
- return NULL;
-
- result = PALLOCTYPE(TimeSpan);
-
- up = VARDATA(units);
- lp = lowunits;
- for (i = 0; i < (VARSIZE(units)-VARHDRSZ); i++) *lp++ = tolower( *up++);
- *lp = '\0';
-
- type = DecodeUnits( 0, lowunits, &val);
+ TimeSpan *result;
+
+ int type,
+ val;
+ int i;
+ char *up,
+ *lp,
+ lowunits[MAXDATELEN + 1];
+ double fsec;
+ struct tm tt,
+ *tm = &tt;
+
+ if ((!PointerIsValid(units)) || (!PointerIsValid(timespan)))
+ return NULL;
+
+ result = PALLOCTYPE(TimeSpan);
+
+ up = VARDATA(units);
+ lp = lowunits;
+ for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
+ *lp++ = tolower(*up++);
+ *lp = '\0';
+
+ type = DecodeUnits(0, lowunits, &val);
#if FALSE
- if (type == IGNORE) {
- type = DecodeSpecial( 0, lowunits, &val);
- }
+ if (type == IGNORE)
+ {
+ type = DecodeSpecial(0, lowunits, &val);
+ }
#endif
#ifdef DATEDEBUG
-if (type == IGNORE) strcpy(lowunits, "(unknown)");
-printf( "timespan_trunc- units %s type=%d value=%d\n", lowunits, type, val);
+ if (type == IGNORE)
+ strcpy(lowunits, "(unknown)");
+ printf("timespan_trunc- units %s type=%d value=%d\n", lowunits, type, val);
#endif
- if (TIMESPAN_IS_INVALID(*timespan)) {
+ if (TIMESPAN_IS_INVALID(*timespan))
+ {
#if FALSE
- elog(WARN,"Timespan is not finite",NULL);
+ elog(WARN, "Timespan is not finite", NULL);
#endif
- result = NULL;
-
- } else if (type == UNITS) {
-
- if (timespan2tm(*timespan, tm, &fsec) == 0) {
- switch (val) {
- case DTK_MILLENIUM:
- tm->tm_year = (tm->tm_year/1000)*1000;
- case DTK_CENTURY:
- tm->tm_year = (tm->tm_year/100)*100;
- case DTK_DECADE:
- tm->tm_year = (tm->tm_year/10)*10;
- case DTK_YEAR:
- tm->tm_mon = 0;
- case DTK_QUARTER:
- tm->tm_mon = (3*(tm->tm_mon/4));
- case DTK_MONTH:
- tm->tm_mday = 0;
- case DTK_DAY:
- tm->tm_hour = 0;
- case DTK_HOUR:
- tm->tm_min = 0;
- case DTK_MINUTE:
- tm->tm_sec = 0;
- case DTK_SECOND:
- fsec = 0;
- break;
-
- case DTK_MILLISEC:
- fsec = rint(fsec*1000)/1000;
- break;
-
- case DTK_MICROSEC:
- fsec = rint(fsec*1000)/1000;
- break;
-
- default:
- elog(WARN,"Timespan units %s not supported",lowunits);
result = NULL;
- }
-
- if (tm2timespan(tm, fsec, result) != 0)
- elog(WARN,"Unable to truncate timespan to %s",lowunits);
- } else {
- elog(NOTICE,"Timespan out of range",NULL);
- result = NULL;
}
+ else if (type == UNITS)
+ {
+
+ if (timespan2tm(*timespan, tm, &fsec) == 0)
+ {
+ switch (val)
+ {
+ case DTK_MILLENIUM:
+ tm->tm_year = (tm->tm_year / 1000) * 1000;
+ case DTK_CENTURY:
+ tm->tm_year = (tm->tm_year / 100) * 100;
+ case DTK_DECADE:
+ tm->tm_year = (tm->tm_year / 10) * 10;
+ case DTK_YEAR:
+ tm->tm_mon = 0;
+ case DTK_QUARTER:
+ tm->tm_mon = (3 * (tm->tm_mon / 4));
+ case DTK_MONTH:
+ tm->tm_mday = 0;
+ case DTK_DAY:
+ tm->tm_hour = 0;
+ case DTK_HOUR:
+ tm->tm_min = 0;
+ case DTK_MINUTE:
+ tm->tm_sec = 0;
+ case DTK_SECOND:
+ fsec = 0;
+ break;
+
+ case DTK_MILLISEC:
+ fsec = rint(fsec * 1000) / 1000;
+ break;
+
+ case DTK_MICROSEC:
+ fsec = rint(fsec * 1000) / 1000;
+ break;
+
+ default:
+ elog(WARN, "Timespan units %s not supported", lowunits);
+ result = NULL;
+ }
+
+ if (tm2timespan(tm, fsec, result) != 0)
+ elog(WARN, "Unable to truncate timespan to %s", lowunits);
+
+ }
+ else
+ {
+ elog(NOTICE, "Timespan out of range", NULL);
+ result = NULL;
+ }
#if FALSE
- } else if ((type == RESERV) && (val == DTK_EPOCH)) {
- *result = timespan->time;
- if (timespan->month != 0) {
- *result += ((365.25*86400)*(timespan->month / 12));
- *result += ((30*86400)*(timespan->month % 12));
}
+ else if ((type == RESERV) && (val == DTK_EPOCH))
+ {
+ *result = timespan->time;
+ if (timespan->month != 0)
+ {
+ *result += ((365.25 * 86400) * (timespan->month / 12));
+ *result += ((30 * 86400) * (timespan->month % 12));
+ }
#endif
- } else {
- elog(WARN,"Timespan units %s not recognized",units);
- result = NULL;
- }
+ }
+ else
+ {
+ elog(WARN, "Timespan units %s not recognized", units);
+ result = NULL;
+ }
- return(result);
-} /* timespan_trunc() */
+ return (result);
+} /* timespan_trunc() */
/* datetime_part()
* Extract specified field from datetime.
*/
float64
-datetime_part(text *units, DateTime *datetime)
+datetime_part(text * units, DateTime * datetime)
{
- float64 result;
-
- DateTime dt;
- int tz;
- int type, val;
- int i;
- char *up, *lp, lowunits[MAXDATELEN+1];
- double fsec;
- char *tzn;
- struct tm tt, *tm = &tt;
-
- if ((!PointerIsValid(units)) || (!PointerIsValid(datetime)))
- return NULL;
-
- result = PALLOCTYPE(float64data);
-
- up = VARDATA(units);
- lp = lowunits;
- for (i = 0; i < (VARSIZE(units)-VARHDRSZ); i++) *lp++ = tolower( *up++);
- *lp = '\0';
-
- type = DecodeUnits( 0, lowunits, &val);
- if (type == IGNORE) {
- type = DecodeSpecial( 0, lowunits, &val);
- }
+ float64 result;
+
+ DateTime dt;
+ int tz;
+ int type,
+ val;
+ int i;
+ char *up,
+ *lp,
+ lowunits[MAXDATELEN + 1];
+ double fsec;
+ char *tzn;
+ struct tm tt,
+ *tm = &tt;
+
+ if ((!PointerIsValid(units)) || (!PointerIsValid(datetime)))
+ return NULL;
+
+ result = PALLOCTYPE(float64data);
+
+ up = VARDATA(units);
+ lp = lowunits;
+ for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
+ *lp++ = tolower(*up++);
+ *lp = '\0';
+
+ type = DecodeUnits(0, lowunits, &val);
+ if (type == IGNORE)
+ {
+ type = DecodeSpecial(0, lowunits, &val);
+ }
#ifdef DATEDEBUG
-if (type == IGNORE) strcpy(lowunits, "(unknown)");
-printf( "datetime_part- units %s type=%d value=%d\n", lowunits, type, val);
+ if (type == IGNORE)
+ strcpy(lowunits, "(unknown)");
+ printf("datetime_part- units %s type=%d value=%d\n", lowunits, type, val);
#endif
- if (DATETIME_NOT_FINITE(*datetime)) {
+ if (DATETIME_NOT_FINITE(*datetime))
+ {
#if FALSE
/* should return null but Postgres doesn't like that currently. - tgl 97/06/12 */
- elog(WARN,"Datetime is not finite",NULL);
+ elog(WARN, "Datetime is not finite", NULL);
#endif
- *result = 0;
-
- } else {
- dt = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime);
-
- if ((type == UNITS) && (datetime2tm( dt, &tz, tm, &fsec, &tzn) == 0)) {
- switch (val) {
- case DTK_TZ:
- *result = tz;
- break;
-
- case DTK_MICROSEC:
- *result = (fsec*1000000);
- break;
-
- case DTK_MILLISEC:
- *result = (fsec*1000);
- break;
-
- case DTK_SECOND:
- *result = (tm->tm_sec + fsec);
- break;
-
- case DTK_MINUTE:
- *result = tm->tm_min;
- break;
-
- case DTK_HOUR:
- *result = tm->tm_hour;
- break;
-
- case DTK_DAY:
- *result = tm->tm_mday;
- break;
-
- case DTK_MONTH:
- *result = tm->tm_mon;
- break;
-
- case DTK_QUARTER:
- *result = (tm->tm_mon/4)+1;
- break;
-
- case DTK_YEAR:
- *result = tm->tm_year;
- break;
-
- case DTK_DECADE:
- *result = (tm->tm_year/10)+1;
- break;
-
- case DTK_CENTURY:
- *result = (tm->tm_year/100)+1;
- break;
-
- case DTK_MILLENIUM:
- *result = (tm->tm_year/1000)+1;
- break;
-
- default:
- elog(WARN,"Datetime units %s not supported",lowunits);
*result = 0;
- }
-
- } else if (type == RESERV) {
- switch (val) {
- case DTK_EPOCH:
- DATETIME_EPOCH(*result);
- *result = dt - SetDateTime(*result);
- break;
- case DTK_DOW:
- if (datetime2tm( dt, &tz, tm, &fsec, &tzn) != 0)
- elog(WARN,"Unable to encode datetime",NULL);
-
- *result = j2day( date2j( tm->tm_year, tm->tm_mon, tm->tm_mday));
- break;
+ }
+ else
+ {
+ dt = (DATETIME_IS_RELATIVE(*datetime) ? SetDateTime(*datetime) : *datetime);
+
+ if ((type == UNITS) && (datetime2tm(dt, &tz, tm, &fsec, &tzn) == 0))
+ {
+ switch (val)
+ {
+ case DTK_TZ:
+ *result = tz;
+ break;
+
+ case DTK_MICROSEC:
+ *result = (fsec * 1000000);
+ break;
+
+ case DTK_MILLISEC:
+ *result = (fsec * 1000);
+ break;
+
+ case DTK_SECOND:
+ *result = (tm->tm_sec + fsec);
+ break;
+
+ case DTK_MINUTE:
+ *result = tm->tm_min;
+ break;
+
+ case DTK_HOUR:
+ *result = tm->tm_hour;
+ break;
+
+ case DTK_DAY:
+ *result = tm->tm_mday;
+ break;
+
+ case DTK_MONTH:
+ *result = tm->tm_mon;
+ break;
+
+ case DTK_QUARTER:
+ *result = (tm->tm_mon / 4) + 1;
+ break;
+
+ case DTK_YEAR:
+ *result = tm->tm_year;
+ break;
+
+ case DTK_DECADE:
+ *result = (tm->tm_year / 10) + 1;
+ break;
+
+ case DTK_CENTURY:
+ *result = (tm->tm_year / 100) + 1;
+ break;
+
+ case DTK_MILLENIUM:
+ *result = (tm->tm_year / 1000) + 1;
+ break;
+
+ default:
+ elog(WARN, "Datetime units %s not supported", lowunits);
+ *result = 0;
+ }
- default:
- elog(WARN,"Datetime units %s not supported",lowunits);
- *result = 0;
- }
+ }
+ else if (type == RESERV)
+ {
+ switch (val)
+ {
+ case DTK_EPOCH:
+ DATETIME_EPOCH(*result);
+ *result = dt - SetDateTime(*result);
+ break;
+
+ case DTK_DOW:
+ if (datetime2tm(dt, &tz, tm, &fsec, &tzn) != 0)
+ elog(WARN, "Unable to encode datetime", NULL);
+
+ *result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
+ break;
+
+ default:
+ elog(WARN, "Datetime units %s not supported", lowunits);
+ *result = 0;
+ }
- } else {
- elog(WARN,"Datetime units %s not recognized",lowunits);
- *result = 0;
+ }
+ else
+ {
+ elog(WARN, "Datetime units %s not recognized", lowunits);
+ *result = 0;
+ }
}
- }
- return(result);
-} /* datetime_part() */
+ return (result);
+} /* datetime_part() */
/* timespan_part()
* Extract specified field from timespan.
*/
float64
-timespan_part(text *units, TimeSpan *timespan)
+timespan_part(text * units, TimeSpan * timespan)
{
- float64 result;
-
- int type, val;
- int i;
- char *up, *lp, lowunits[MAXDATELEN+1];
- double fsec;
- struct tm tt, *tm = &tt;
-
- if ((!PointerIsValid(units)) || (!PointerIsValid(timespan)))
- return NULL;
-
- result = PALLOCTYPE(float64data);
-
- up = VARDATA(units);
- lp = lowunits;
- for (i = 0; i < (VARSIZE(units)-VARHDRSZ); i++) *lp++ = tolower( *up++);
- *lp = '\0';
-
- type = DecodeUnits( 0, lowunits, &val);
- if (type == IGNORE) {
- type = DecodeSpecial( 0, lowunits, &val);
- }
+ float64 result;
+
+ int type,
+ val;
+ int i;
+ char *up,
+ *lp,
+ lowunits[MAXDATELEN + 1];
+ double fsec;
+ struct tm tt,
+ *tm = &tt;
+
+ if ((!PointerIsValid(units)) || (!PointerIsValid(timespan)))
+ return NULL;
+
+ result = PALLOCTYPE(float64data);
+
+ up = VARDATA(units);
+ lp = lowunits;
+ for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
+ *lp++ = tolower(*up++);
+ *lp = '\0';
+
+ type = DecodeUnits(0, lowunits, &val);
+ if (type == IGNORE)
+ {
+ type = DecodeSpecial(0, lowunits, &val);
+ }
#ifdef DATEDEBUG
-if (type == IGNORE) strcpy(lowunits, "(unknown)");
-printf( "timespan_part- units %s type=%d value=%d\n", lowunits, type, val);
+ if (type == IGNORE)
+ strcpy(lowunits, "(unknown)");
+ printf("timespan_part- units %s type=%d value=%d\n", lowunits, type, val);
#endif
- if (TIMESPAN_IS_INVALID(*timespan)) {
+ if (TIMESPAN_IS_INVALID(*timespan))
+ {
#if FALSE
- elog(WARN,"Timespan is not finite",NULL);
+ elog(WARN, "Timespan is not finite", NULL);
#endif
- *result = 0;
-
- } else if (type == UNITS) {
-
- if (timespan2tm(*timespan, tm, &fsec) == 0) {
- switch (val) {
- case DTK_MICROSEC:
- *result = (fsec*1000000);
- break;
-
- case DTK_MILLISEC:
- *result = (fsec*1000);
- break;
-
- case DTK_SECOND:
- *result = (tm->tm_sec + fsec);
- break;
-
- case DTK_MINUTE:
- *result = tm->tm_min;
- break;
-
- case DTK_HOUR:
- *result = tm->tm_hour;
- break;
-
- case DTK_DAY:
- *result = tm->tm_mday;
- break;
-
- case DTK_MONTH:
- *result = tm->tm_mon;
- break;
-
- case DTK_QUARTER:
- *result = (tm->tm_mon/4)+1;
- break;
-
- case DTK_YEAR:
- *result = tm->tm_year;
- break;
-
- case DTK_DECADE:
- *result = (tm->tm_year/10)+1;
- break;
-
- case DTK_CENTURY:
- *result = (tm->tm_year/100)+1;
- break;
+ *result = 0;
- case DTK_MILLENIUM:
- *result = (tm->tm_year/1000)+1;
- break;
+ }
+ else if (type == UNITS)
+ {
+
+ if (timespan2tm(*timespan, tm, &fsec) == 0)
+ {
+ switch (val)
+ {
+ case DTK_MICROSEC:
+ *result = (fsec * 1000000);
+ break;
+
+ case DTK_MILLISEC:
+ *result = (fsec * 1000);
+ break;
+
+ case DTK_SECOND:
+ *result = (tm->tm_sec + fsec);
+ break;
+
+ case DTK_MINUTE:
+ *result = tm->tm_min;
+ break;
+
+ case DTK_HOUR:
+ *result = tm->tm_hour;
+ break;
+
+ case DTK_DAY:
+ *result = tm->tm_mday;
+ break;
+
+ case DTK_MONTH:
+ *result = tm->tm_mon;
+ break;
+
+ case DTK_QUARTER:
+ *result = (tm->tm_mon / 4) + 1;
+ break;
+
+ case DTK_YEAR:
+ *result = tm->tm_year;
+ break;
+
+ case DTK_DECADE:
+ *result = (tm->tm_year / 10) + 1;
+ break;
+
+ case DTK_CENTURY:
+ *result = (tm->tm_year / 100) + 1;
+ break;
+
+ case DTK_MILLENIUM:
+ *result = (tm->tm_year / 1000) + 1;
+ break;
+
+ default:
+ elog(WARN, "Timespan units %s not yet supported", units);
+ result = NULL;
+ }
- default:
- elog(WARN,"Timespan units %s not yet supported",units);
- result = NULL;
- }
+ }
+ else
+ {
+ elog(NOTICE, "Timespan out of range", NULL);
+ *result = 0;
+ }
- } else {
- elog(NOTICE,"Timespan out of range",NULL);
- *result = 0;
}
+ else if ((type == RESERV) && (val == DTK_EPOCH))
+ {
+ *result = timespan->time;
+ if (timespan->month != 0)
+ {
+ *result += ((365.25 * 86400) * (timespan->month / 12));
+ *result += ((30 * 86400) * (timespan->month % 12));
+ }
- } else if ((type == RESERV) && (val == DTK_EPOCH)) {
- *result = timespan->time;
- if (timespan->month != 0) {
- *result += ((365.25*86400)*(timespan->month / 12));
- *result += ((30*86400)*(timespan->month % 12));
+ }
+ else
+ {
+ elog(WARN, "Timespan units %s not recognized", units);
+ *result = 0;
}
- } else {
- elog(WARN,"Timespan units %s not recognized",units);
- *result = 0;
- }
-
- return(result);
-} /* timespan_part() */
+ return (result);
+} /* timespan_part() */
/* datetime_zone()
* Encode datetime type with specified time zone.
*/
-text *
-datetime_zone(text *zone, DateTime *datetime)
-{
- text *result;
-
- DateTime dt;
- int tz;
- int type, val;
- int i;
- char *up, *lp, lowzone[MAXDATELEN+1];
- char *tzn, upzone[MAXDATELEN+1];
- double fsec;
- struct tm tt, *tm = &tt;
- char buf[MAXDATELEN+1];
- int len;
-
- if ((!PointerIsValid(zone)) || (!PointerIsValid(datetime)))
- return NULL;
-
- up = VARDATA(zone);
- lp = lowzone;
- for (i = 0; i < (VARSIZE(zone)-VARHDRSZ); i++) *lp++ = tolower( *up++);
- *lp = '\0';
+text *
+datetime_zone(text * zone, DateTime * datetime)
+{
+ text *result;
+
+ DateTime dt;
+ int tz;
+ int type,
+ val;
+ int i;
+ char *up,
+ *lp,
+ lowzone[MAXDATELEN + 1];
+ char *tzn,
+ upzone[MAXDATELEN + 1];
+ double fsec;
+ struct tm tt,
+ *tm = &tt;
+ char buf[MAXDATELEN + 1];
+ int len;
+
+ if ((!PointerIsValid(zone)) || (!PointerIsValid(datetime)))
+ return NULL;
+
+ up = VARDATA(zone);
+ lp = lowzone;
+ for (i = 0; i < (VARSIZE(zone) - VARHDRSZ); i++)
+ *lp++ = tolower(*up++);
+ *lp = '\0';
- type = DecodeSpecial( 0, lowzone, &val);
+ type = DecodeSpecial(0, lowzone, &val);
#ifdef DATEDEBUG
-if (type == IGNORE) strcpy(lowzone, "(unknown)");
-printf( "datetime_zone- zone %s type=%d value=%d\n", lowzone, type, val);
+ if (type == IGNORE)
+ strcpy(lowzone, "(unknown)");
+ printf("datetime_zone- zone %s type=%d value=%d\n", lowzone, type, val);
#endif
- if (DATETIME_NOT_FINITE(*datetime)) {
- /* could return null but Postgres doesn't like that currently. - tgl 97/06/12 */
- elog(WARN,"Datetime is not finite",NULL);
- result = NULL;
+ if (DATETIME_NOT_FINITE(*datetime))
+ {
- } else if ((type == TZ) || (type == DTZ)) {
- tm->tm_isdst = ((type == DTZ)? 1: 0);
- tz = val * 60;
+ /*
+ * could return null but Postgres doesn't like that currently. -
+ * tgl 97/06/12
+ */
+ elog(WARN, "Datetime is not finite", NULL);
+ result = NULL;
- dt = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime);
- dt = dt2local( dt, tz);
+ }
+ else if ((type == TZ) || (type == DTZ))
+ {
+ tm->tm_isdst = ((type == DTZ) ? 1 : 0);
+ tz = val * 60;
- if (datetime2tm( dt, NULL, tm, &fsec, NULL) != 0)
- elog(WARN,"Datetime not legal",NULL);
+ dt = (DATETIME_IS_RELATIVE(*datetime) ? SetDateTime(*datetime) : *datetime);
+ dt = dt2local(dt, tz);
- up = upzone;
- lp = lowzone;
- for (i = 0; *lp != '\0'; i++) *up++ = toupper( *lp++);
- *up = '\0';
+ if (datetime2tm(dt, NULL, tm, &fsec, NULL) != 0)
+ elog(WARN, "Datetime not legal", NULL);
- tzn = upzone;
- EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
+ up = upzone;
+ lp = lowzone;
+ for (i = 0; *lp != '\0'; i++)
+ *up++ = toupper(*lp++);
+ *up = '\0';
- len = (strlen(buf)+VARHDRSZ);
+ tzn = upzone;
+ EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
- result = PALLOC(len);
+ len = (strlen(buf) + VARHDRSZ);
- VARSIZE(result) = len;
- memmove(VARDATA(result), buf, (len-VARHDRSZ));
+ result = PALLOC(len);
+
+ VARSIZE(result) = len;
+ memmove(VARDATA(result), buf, (len - VARHDRSZ));
- } else {
- elog(WARN,"Time zone %s not recognized",lowzone);
- result = NULL;
- }
+ }
+ else
+ {
+ elog(WARN, "Time zone %s not recognized", lowzone);
+ result = NULL;
+ }
- return(result);
-} /* datetime_zone() */
+ return (result);
+} /* datetime_zone() */
-/*****************************************************************************
- * PRIVATE ROUTINES *
+/*****************************************************************************
+ * PRIVATE ROUTINES *
*****************************************************************************/
/* definitions for squeezing values into "value" */
-#define ABS_SIGNBIT (char) 0200
-#define VALMASK (char) 0177
-#define NEG(n) ((n)|ABS_SIGNBIT)
+#define ABS_SIGNBIT (char) 0200
+#define VALMASK (char) 0177
+#define NEG(n) ((n)|ABS_SIGNBIT)
#define SIGNEDCHAR(c) ((c)&ABS_SIGNBIT? -((c)&VALMASK): (c))
-#define FROMVAL(tp) (-SIGNEDCHAR((tp)->value) * 10) /* uncompress */
+#define FROMVAL(tp) (-SIGNEDCHAR((tp)->value) * 10) /* uncompress */
#define TOVAL(tp, v) ((tp)->value = ((v) < 0? NEG((-(v))/10): (v)/10))
/*
@@ -1814,253 +2064,270 @@ printf( "datetime_zone- zone %s type=%d value=%d\n", lowzone, type, val);
* entries by 10 and truncate the text field at MAXTOKLEN characters.
* the text field is not guaranteed to be NULL-terminated.
*/
-static datetkn datetktbl[] = {
-/* text token lexval */
-{ EARLY, RESERV, DTK_EARLY}, /* "-infinity" reserved for "early time" */
-{ "acsst", DTZ, 63}, /* Cent. Australia */
-{ "acst", TZ, 57}, /* Cent. Australia */
-{ DA_D, ADBC, AD}, /* "ad" for years >= 0 */
-{ "abstime", IGNORE, 0}, /* "abstime" for pre-v6.1 "Invalid Abstime" */
-{ "adt", DTZ, NEG(18)}, /* Atlantic Daylight Time */
-{ "aesst", DTZ, 66}, /* E. Australia */
-{ "aest", TZ, 60}, /* Australia Eastern Std Time */
-{ "ahst", TZ, 60}, /* Alaska-Hawaii Std Time */
-{ "allballs", RESERV, DTK_ZULU}, /* 00:00:00 */
-{ "am", AMPM, AM},
-{ "apr", MONTH, 4},
-{ "april", MONTH, 4},
-{ "ast", TZ, NEG(24)}, /* Atlantic Std Time (Canada) */
-{ "at", IGNORE, 0}, /* "at" (throwaway) */
-{ "aug", MONTH, 8},
-{ "august", MONTH, 8},
-{ "awsst", DTZ, 54}, /* W. Australia */
-{ "awst", TZ, 48}, /* W. Australia */
-{ DB_C, ADBC, BC}, /* "bc" for years < 0 */
-{ "bst", TZ, 6}, /* British Summer Time */
-{ "bt", TZ, 18}, /* Baghdad Time */
-{ "cadt", DTZ, 63}, /* Central Australian DST */
-{ "cast", TZ, 57}, /* Central Australian ST */
-{ "cat", TZ, NEG(60)}, /* Central Alaska Time */
-{ "cct", TZ, 48}, /* China Coast */
-{ "cdt", DTZ, NEG(30)}, /* Central Daylight Time */
-{ "cet", TZ, 6}, /* Central European Time */
-{ "cetdst", DTZ, 12}, /* Central European Dayl.Time */
-{ "cst", TZ, NEG(36)}, /* Central Standard Time */
-{ DCURRENT, RESERV, DTK_CURRENT}, /* "current" is always now */
-{ "dec", MONTH, 12},
-{ "december", MONTH, 12},
-{ "dnt", TZ, 6}, /* Dansk Normal Tid */
-{ "dow", RESERV, DTK_DOW}, /* day of week */
-{ "dst", DTZMOD, 6},
-{ "east", TZ, NEG(60)}, /* East Australian Std Time */
-{ "edt", DTZ, NEG(24)}, /* Eastern Daylight Time */
-{ "eet", TZ, 12}, /* East. Europe, USSR Zone 1 */
-{ "eetdst", DTZ, 18}, /* Eastern Europe */
-{ EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */
+static datetkn datetktbl[] = {
+/* text token lexval */
+ {EARLY, RESERV, DTK_EARLY}, /* "-infinity" reserved for "early time" */
+ {"acsst", DTZ, 63}, /* Cent. Australia */
+ {"acst", TZ, 57}, /* Cent. Australia */
+ {DA_D, ADBC, AD}, /* "ad" for years >= 0 */
+ {"abstime", IGNORE, 0}, /* "abstime" for pre-v6.1 "Invalid
+ * Abstime" */
+ {"adt", DTZ, NEG(18)}, /* Atlantic Daylight Time */
+ {"aesst", DTZ, 66}, /* E. Australia */
+ {"aest", TZ, 60}, /* Australia Eastern Std Time */
+ {"ahst", TZ, 60}, /* Alaska-Hawaii Std Time */
+ {"allballs", RESERV, DTK_ZULU}, /* 00:00:00 */
+ {"am", AMPM, AM},
+ {"apr", MONTH, 4},
+ {"april", MONTH, 4},
+ {"ast", TZ, NEG(24)}, /* Atlantic Std Time (Canada) */
+ {"at", IGNORE, 0}, /* "at" (throwaway) */
+ {"aug", MONTH, 8},
+ {"august", MONTH, 8},
+ {"awsst", DTZ, 54}, /* W. Australia */
+ {"awst", TZ, 48}, /* W. Australia */
+ {DB_C, ADBC, BC}, /* "bc" for years < 0 */
+ {"bst", TZ, 6}, /* British Summer Time */
+ {"bt", TZ, 18}, /* Baghdad Time */
+ {"cadt", DTZ, 63}, /* Central Australian DST */
+ {"cast", TZ, 57}, /* Central Australian ST */
+ {"cat", TZ, NEG(60)}, /* Central Alaska Time */
+ {"cct", TZ, 48}, /* China Coast */
+ {"cdt", DTZ, NEG(30)}, /* Central Daylight Time */
+ {"cet", TZ, 6}, /* Central European Time */
+ {"cetdst", DTZ, 12}, /* Central European Dayl.Time */
+ {"cst", TZ, NEG(36)}, /* Central Standard Time */
+ {DCURRENT, RESERV, DTK_CURRENT}, /* "current" is always now */
+ {"dec", MONTH, 12},
+ {"december", MONTH, 12},
+ {"dnt", TZ, 6}, /* Dansk Normal Tid */
+ {"dow", RESERV, DTK_DOW}, /* day of week */
+ {"dst", DTZMOD, 6},
+ {"east", TZ, NEG(60)}, /* East Australian Std Time */
+ {"edt", DTZ, NEG(24)}, /* Eastern Daylight Time */
+ {"eet", TZ, 12}, /* East. Europe, USSR Zone 1 */
+ {"eetdst", DTZ, 18}, /* Eastern Europe */
+ {EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */
#if USE_AUSTRALIAN_RULES
-{ "est", TZ, 60}, /* Australia Eastern Std Time */
+ {"est", TZ, 60}, /* Australia Eastern Std Time */
#else
-{ "est", TZ, NEG(30)}, /* Eastern Standard Time */
-#endif
-{ "feb", MONTH, 2},
-{ "february", MONTH, 2},
-{ "fri", DOW, 5},
-{ "friday", DOW, 5},
-{ "fst", TZ, 6}, /* French Summer Time */
-{ "fwt", DTZ, 12}, /* French Winter Time */
-{ "gmt", TZ, 0}, /* Greenwish Mean Time */
-{ "gst", TZ, 60}, /* Guam Std Time, USSR Zone 9 */
-{ "hdt", DTZ, NEG(54)}, /* Hawaii/Alaska */
-{ "hmt", DTZ, 18}, /* Hellas ? ? */
-{ "hst", TZ, NEG(60)}, /* Hawaii Std Time */
-{ "idle", TZ, 72}, /* Intl. Date Line, East */
-{ "idlw", TZ, NEG(72)}, /* Intl. Date Line, West */
-{ LATE, RESERV, DTK_LATE}, /* "infinity" reserved for "late time" */
-{ INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for invalid time */
-{ "ist", TZ, 12}, /* Israel */
-{ "it", TZ, 22}, /* Iran Time */
-{ "jan", MONTH, 1},
-{ "january", MONTH, 1},
-{ "jst", TZ, 54}, /* Japan Std Time,USSR Zone 8 */
-{ "jt", TZ, 45}, /* Java Time */
-{ "jul", MONTH, 7},
-{ "july", MONTH, 7},
-{ "jun", MONTH, 6},
-{ "june", MONTH, 6},
-{ "kst", TZ, 54}, /* Korea Standard Time */
-{ "ligt", TZ, 60}, /* From Melbourne, Australia */
-{ "mar", MONTH, 3},
-{ "march", MONTH, 3},
-{ "may", MONTH, 5},
-{ "mdt", DTZ, NEG(36)}, /* Mountain Daylight Time */
-{ "mest", DTZ, 12}, /* Middle Europe Summer Time */
-{ "met", TZ, 6}, /* Middle Europe Time */
-{ "metdst", DTZ, 12}, /* Middle Europe Daylight Time*/
-{ "mewt", TZ, 6}, /* Middle Europe Winter Time */
-{ "mez", TZ, 6}, /* Middle Europe Zone */
-{ "mon", DOW, 1},
-{ "monday", DOW, 1},
-{ "mst", TZ, NEG(42)}, /* Mountain Standard Time */
-{ "mt", TZ, 51}, /* Moluccas Time */
-{ "ndt", DTZ, NEG(15)}, /* Nfld. Daylight Time */
-{ "nft", TZ, NEG(21)}, /* Newfoundland Standard Time */
-{ "nor", TZ, 6}, /* Norway Standard Time */
-{ "nov", MONTH, 11},
-{ "november", MONTH, 11},
-{ NOW, RESERV, DTK_NOW}, /* current transaction time */
-{ "nst", TZ, NEG(21)}, /* Nfld. Standard Time */
-{ "nt", TZ, NEG(66)}, /* Nome Time */
-{ "nzdt", DTZ, 78}, /* New Zealand Daylight Time */
-{ "nzst", TZ, 72}, /* New Zealand Standard Time */
-{ "nzt", TZ, 72}, /* New Zealand Time */
-{ "oct", MONTH, 10},
-{ "october", MONTH, 10},
-{ "on", IGNORE, 0}, /* "on" (throwaway) */
-{ "pdt", DTZ, NEG(42)}, /* Pacific Daylight Time */
-{ "pm", AMPM, PM},
-{ "pst", TZ, NEG(48)}, /* Pacific Standard Time */
-{ "sadt", DTZ, 63}, /* S. Australian Dayl. Time */
-{ "sast", TZ, 57}, /* South Australian Std Time */
-{ "sat", DOW, 6},
-{ "saturday", DOW, 6},
-{ "sep", MONTH, 9},
-{ "sept", MONTH, 9},
-{ "september", MONTH, 9},
-{ "set", TZ, NEG(6)}, /* Seychelles Time ?? */
-{ "sst", DTZ, 12}, /* Swedish Summer Time */
-{ "sun", DOW, 0},
-{ "sunday", DOW, 0},
-{ "swt", TZ, 6}, /* Swedish Winter Time */
-{ "thu", DOW, 4},
-{ "thur", DOW, 4},
-{ "thurs", DOW, 4},
-{ "thursday", DOW, 4},
-{ TODAY, RESERV, DTK_TODAY}, /* midnight */
-{ TOMORROW, RESERV, DTK_TOMORROW}, /* tomorrow midnight */
-{ "tue", DOW, 2},
-{ "tues", DOW, 2},
-{ "tuesday", DOW, 2},
-{ "undefined", RESERV, DTK_INVALID}, /* "undefined" pre-v6.1 invalid time */
-{ "ut", TZ, 0},
-{ "utc", TZ, 0},
-{ "wadt", DTZ, 48}, /* West Australian DST */
-{ "wast", TZ, 42}, /* West Australian Std Time */
-{ "wat", TZ, NEG(6)}, /* West Africa Time */
-{ "wdt", DTZ, 54}, /* West Australian DST */
-{ "wed", DOW, 3},
-{ "wednesday", DOW, 3},
-{ "weds", DOW, 3},
-{ "wet", TZ, 0}, /* Western Europe */
-{ "wetdst", DTZ, 6}, /* Western Europe */
-{ "wst", TZ, 48}, /* West Australian Std Time */
-{ "ydt", DTZ, NEG(48)}, /* Yukon Daylight Time */
-{ YESTERDAY, RESERV, DTK_YESTERDAY}, /* yesterday midnight */
-{ "yst", TZ, NEG(54)}, /* Yukon Standard Time */
-{ "zp4", TZ, NEG(24)}, /* GMT +4 hours. */
-{ "zp5", TZ, NEG(30)}, /* GMT +5 hours. */
-{ "zp6", TZ, NEG(36)}, /* GMT +6 hours. */
-{ "z", RESERV, DTK_ZULU}, /* 00:00:00 */
-{ ZULU, RESERV, DTK_ZULU}, /* 00:00:00 */
+ {"est", TZ, NEG(30)}, /* Eastern Standard Time */
+#endif
+ {"feb", MONTH, 2},
+ {"february", MONTH, 2},
+ {"fri", DOW, 5},
+ {"friday", DOW, 5},
+ {"fst", TZ, 6}, /* French Summer Time */
+ {"fwt", DTZ, 12}, /* French Winter Time */
+ {"gmt", TZ, 0}, /* Greenwish Mean Time */
+ {"gst", TZ, 60}, /* Guam Std Time, USSR Zone 9 */
+ {"hdt", DTZ, NEG(54)}, /* Hawaii/Alaska */
+ {"hmt", DTZ, 18}, /* Hellas ? ? */
+ {"hst", TZ, NEG(60)}, /* Hawaii Std Time */
+ {"idle", TZ, 72}, /* Intl. Date Line, East */
+ {"idlw", TZ, NEG(72)}, /* Intl. Date Line, West */
+ {LATE, RESERV, DTK_LATE}, /* "infinity" reserved for "late time" */
+ {INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for invalid
+ * time */
+ {"ist", TZ, 12}, /* Israel */
+ {"it", TZ, 22}, /* Iran Time */
+ {"jan", MONTH, 1},
+ {"january", MONTH, 1},
+ {"jst", TZ, 54}, /* Japan Std Time,USSR Zone 8 */
+ {"jt", TZ, 45}, /* Java Time */
+ {"jul", MONTH, 7},
+ {"july", MONTH, 7},
+ {"jun", MONTH, 6},
+ {"june", MONTH, 6},
+ {"kst", TZ, 54}, /* Korea Standard Time */
+ {"ligt", TZ, 60}, /* From Melbourne, Australia */
+ {"mar", MONTH, 3},
+ {"march", MONTH, 3},
+ {"may", MONTH, 5},
+ {"mdt", DTZ, NEG(36)}, /* Mountain Daylight Time */
+ {"mest", DTZ, 12}, /* Middle Europe Summer Time */
+ {"met", TZ, 6}, /* Middle Europe Time */
+ {"metdst", DTZ, 12}, /* Middle Europe Daylight Time */
+ {"mewt", TZ, 6}, /* Middle Europe Winter Time */
+ {"mez", TZ, 6}, /* Middle Europe Zone */
+ {"mon", DOW, 1},
+ {"monday", DOW, 1},
+ {"mst", TZ, NEG(42)}, /* Mountain Standard Time */
+ {"mt", TZ, 51}, /* Moluccas Time */
+ {"ndt", DTZ, NEG(15)}, /* Nfld. Daylight Time */
+ {"nft", TZ, NEG(21)}, /* Newfoundland Standard Time */
+ {"nor", TZ, 6}, /* Norway Standard Time */
+ {"nov", MONTH, 11},
+ {"november", MONTH, 11},
+ {NOW, RESERV, DTK_NOW}, /* current transaction time */
+ {"nst", TZ, NEG(21)}, /* Nfld. Standard Time */
+ {"nt", TZ, NEG(66)}, /* Nome Time */
+ {"nzdt", DTZ, 78}, /* New Zealand Daylight Time */
+ {"nzst", TZ, 72}, /* New Zealand Standard Time */
+ {"nzt", TZ, 72}, /* New Zealand Time */
+ {"oct", MONTH, 10},
+ {"october", MONTH, 10},
+ {"on", IGNORE, 0}, /* "on" (throwaway) */
+ {"pdt", DTZ, NEG(42)}, /* Pacific Daylight Time */
+ {"pm", AMPM, PM},
+ {"pst", TZ, NEG(48)}, /* Pacific Standard Time */
+ {"sadt", DTZ, 63}, /* S. Australian Dayl. Time */
+ {"sast", TZ, 57}, /* South Australian Std Time */
+ {"sat", DOW, 6},
+ {"saturday", DOW, 6},
+ {"sep", MONTH, 9},
+ {"sept", MONTH, 9},
+ {"september", MONTH, 9},
+ {"set", TZ, NEG(6)}, /* Seychelles Time ?? */
+ {"sst", DTZ, 12}, /* Swedish Summer Time */
+ {"sun", DOW, 0},
+ {"sunday", DOW, 0},
+ {"swt", TZ, 6}, /* Swedish Winter Time */
+ {"thu", DOW, 4},
+ {"thur", DOW, 4},
+ {"thurs", DOW, 4},
+ {"thursday", DOW, 4},
+ {TODAY, RESERV, DTK_TODAY}, /* midnight */
+ {TOMORROW, RESERV, DTK_TOMORROW}, /* tomorrow midnight */
+ {"tue", DOW, 2},
+ {"tues", DOW, 2},
+ {"tuesday", DOW, 2},
+ {"undefined", RESERV, DTK_INVALID}, /* "undefined" pre-v6.1 invalid
+ * time */
+ {"ut", TZ, 0},
+ {"utc", TZ, 0},
+ {"wadt", DTZ, 48}, /* West Australian DST */
+ {"wast", TZ, 42}, /* West Australian Std Time */
+ {"wat", TZ, NEG(6)}, /* West Africa Time */
+ {"wdt", DTZ, 54}, /* West Australian DST */
+ {"wed", DOW, 3},
+ {"wednesday", DOW, 3},
+ {"weds", DOW, 3},
+ {"wet", TZ, 0}, /* Western Europe */
+ {"wetdst", DTZ, 6}, /* Western Europe */
+ {"wst", TZ, 48}, /* West Australian Std Time */
+ {"ydt", DTZ, NEG(48)}, /* Yukon Daylight Time */
+ {YESTERDAY, RESERV, DTK_YESTERDAY}, /* yesterday midnight */
+ {"yst", TZ, NEG(54)}, /* Yukon Standard Time */
+ {"zp4", TZ, NEG(24)}, /* GMT +4 hours. */
+ {"zp5", TZ, NEG(30)}, /* GMT +5 hours. */
+ {"zp6", TZ, NEG(36)}, /* GMT +6 hours. */
+ {"z", RESERV, DTK_ZULU}, /* 00:00:00 */
+ {ZULU, RESERV, DTK_ZULU}, /* 00:00:00 */
};
static unsigned int szdatetktbl = sizeof datetktbl / sizeof datetktbl[0];
-static datetkn deltatktbl[] = {
-/* text token lexval */
-{ "@", IGNORE, 0}, /* postgres relative time prefix */
-{ DAGO, AGO, 0}, /* "ago" indicates negative time offset */
-{ "c", UNITS, DTK_CENTURY}, /* "century" relative time units */
-{ "cent", UNITS, DTK_CENTURY}, /* "century" relative time units */
-{ "centuries", UNITS, DTK_CENTURY}, /* "centuries" relative time units */
-{ DCENTURY, UNITS, DTK_CENTURY}, /* "century" relative time units */
-{ "d", UNITS, DTK_DAY}, /* "day" relative time units */
-{ DDAY, UNITS, DTK_DAY}, /* "day" relative time units */
-{ "days", UNITS, DTK_DAY}, /* "days" relative time units */
-{ "dec", UNITS, DTK_DECADE}, /* "decade" relative time units */
-{ "decs", UNITS, DTK_DECADE}, /* "decades" relative time units */
-{ DDECADE, UNITS, DTK_DECADE}, /* "decade" relative time units */
-{ "decades", UNITS, DTK_DECADE}, /* "decades" relative time units */
-{ "h", UNITS, DTK_HOUR}, /* "hour" relative time units */
-{ DHOUR, UNITS, DTK_HOUR}, /* "hour" relative time units */
-{ "hours", UNITS, DTK_HOUR}, /* "hours" relative time units */
-{ "hr", UNITS, DTK_HOUR}, /* "hour" relative time units */
-{ "hrs", UNITS, DTK_HOUR}, /* "hours" relative time units */
-{ INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for invalid time */
-{ "m", UNITS, DTK_MINUTE}, /* "minute" relative time units */
-{ "microsecon", UNITS, DTK_MILLISEC}, /* "microsecond" relative time units */
-{ "mil", UNITS, DTK_MILLENIUM}, /* "millenium" relative time units */
-{ "mils", UNITS, DTK_MILLENIUM}, /* "millenia" relative time units */
-{ "millenia", UNITS, DTK_MILLENIUM}, /* "millenia" relative time units */
-{ DMILLENIUM, UNITS, DTK_MILLENIUM}, /* "millenium" relative time units */
-{ "millisecon", UNITS, DTK_MILLISEC}, /* "millisecond" relative time units */
-{ "min", UNITS, DTK_MINUTE}, /* "minute" relative time units */
-{ "mins", UNITS, DTK_MINUTE}, /* "minutes" relative time units */
-{ "mins", UNITS, DTK_MINUTE}, /* "minutes" relative time units */
-{ DMINUTE, UNITS, DTK_MINUTE}, /* "minute" relative time units */
-{ "minutes", UNITS, DTK_MINUTE}, /* "minutes" relative time units */
-{ "mon", UNITS, DTK_MONTH}, /* "months" relative time units */
-{ "mons", UNITS, DTK_MONTH}, /* "months" relative time units */
-{ DMONTH, UNITS, DTK_MONTH}, /* "month" relative time units */
-{ "months", UNITS, DTK_MONTH}, /* "months" relative time units */
-{ "ms", UNITS, DTK_MILLISEC}, /* "millisecond" relative time units */
-{ "msec", UNITS, DTK_MILLISEC}, /* "millisecond" relative time units */
-{ DMILLISEC, UNITS, DTK_MILLISEC}, /* "millisecond" relative time units */
-{ "mseconds", UNITS, DTK_MILLISEC}, /* "milliseconds" relative time units */
-{ "msecs", UNITS, DTK_MILLISEC}, /* "milliseconds" relative time units */
-{ "qtr", UNITS, DTK_QUARTER}, /* "quarter" relative time units */
-{ DQUARTER, UNITS, DTK_QUARTER}, /* "quarter" relative time units */
-{ "reltime", IGNORE, 0}, /* "reltime" for pre-v6.1 "Undefined Reltime" */
-{ "s", UNITS, DTK_SECOND}, /* "second" relative time units */
-{ "sec", UNITS, DTK_SECOND}, /* "second" relative time units */
-{ DSECOND, UNITS, DTK_SECOND}, /* "second" relative time units */
-{ "seconds", UNITS, DTK_SECOND}, /* "seconds" relative time units */
-{ "secs", UNITS, DTK_SECOND}, /* "seconds" relative time units */
-{ DTIMEZONE, UNITS, DTK_TZ}, /* "timezone" time offset */
-{ "tz", UNITS, DTK_TZ}, /* "timezone" time offset */
-{ "undefined", RESERV, DTK_INVALID}, /* "undefined" pre-v6.1 invalid time */
-{ "us", UNITS, DTK_MICROSEC}, /* "microsecond" relative time units */
-{ "usec", UNITS, DTK_MICROSEC}, /* "microsecond" relative time units */
-{ DMICROSEC, UNITS, DTK_MICROSEC}, /* "microsecond" relative time units */
-{ "useconds", UNITS, DTK_MICROSEC}, /* "microseconds" relative time units */
-{ "usecs", UNITS, DTK_MICROSEC}, /* "microseconds" relative time units */
-{ "w", UNITS, DTK_WEEK}, /* "week" relative time units */
-{ DWEEK, UNITS, DTK_WEEK}, /* "week" relative time units */
-{ "weeks", UNITS, DTK_WEEK}, /* "weeks" relative time units */
-{ "y", UNITS, DTK_YEAR}, /* "year" relative time units */
-{ DYEAR, UNITS, DTK_YEAR}, /* "year" relative time units */
-{ "years", UNITS, DTK_YEAR}, /* "years" relative time units */
-{ "yr", UNITS, DTK_YEAR}, /* "year" relative time units */
-{ "yrs", UNITS, DTK_YEAR}, /* "years" relative time units */
+static datetkn deltatktbl[] = {
+/* text token lexval */
+ {"@", IGNORE, 0}, /* postgres relative time prefix */
+ {DAGO, AGO, 0}, /* "ago" indicates negative time offset */
+ {"c", UNITS, DTK_CENTURY}, /* "century" relative time units */
+ {"cent", UNITS, DTK_CENTURY}, /* "century" relative time units */
+ {"centuries", UNITS, DTK_CENTURY}, /* "centuries" relative time units */
+ {DCENTURY, UNITS, DTK_CENTURY}, /* "century" relative time units */
+ {"d", UNITS, DTK_DAY}, /* "day" relative time units */
+ {DDAY, UNITS, DTK_DAY}, /* "day" relative time units */
+ {"days", UNITS, DTK_DAY}, /* "days" relative time units */
+ {"dec", UNITS, DTK_DECADE}, /* "decade" relative time units */
+ {"decs", UNITS, DTK_DECADE},/* "decades" relative time units */
+ {DDECADE, UNITS, DTK_DECADE}, /* "decade" relative time units */
+ {"decades", UNITS, DTK_DECADE}, /* "decades" relative time units */
+ {"h", UNITS, DTK_HOUR}, /* "hour" relative time units */
+ {DHOUR, UNITS, DTK_HOUR}, /* "hour" relative time units */
+ {"hours", UNITS, DTK_HOUR}, /* "hours" relative time units */
+ {"hr", UNITS, DTK_HOUR}, /* "hour" relative time units */
+ {"hrs", UNITS, DTK_HOUR}, /* "hours" relative time units */
+ {INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for invalid
+ * time */
+ {"m", UNITS, DTK_MINUTE}, /* "minute" relative time units */
+ {"microsecon", UNITS, DTK_MILLISEC}, /* "microsecond" relative
+ * time units */
+ {"mil", UNITS, DTK_MILLENIUM}, /* "millenium" relative time units */
+ {"mils", UNITS, DTK_MILLENIUM}, /* "millenia" relative time units */
+ {"millenia", UNITS, DTK_MILLENIUM}, /* "millenia" relative time units */
+ {DMILLENIUM, UNITS, DTK_MILLENIUM}, /* "millenium" relative time units */
+ {"millisecon", UNITS, DTK_MILLISEC}, /* "millisecond" relative
+ * time units */
+ {"min", UNITS, DTK_MINUTE}, /* "minute" relative time units */
+ {"mins", UNITS, DTK_MINUTE},/* "minutes" relative time units */
+ {"mins", UNITS, DTK_MINUTE},/* "minutes" relative time units */
+ {DMINUTE, UNITS, DTK_MINUTE}, /* "minute" relative time units */
+ {"minutes", UNITS, DTK_MINUTE}, /* "minutes" relative time units */
+ {"mon", UNITS, DTK_MONTH}, /* "months" relative time units */
+ {"mons", UNITS, DTK_MONTH}, /* "months" relative time units */
+ {DMONTH, UNITS, DTK_MONTH}, /* "month" relative time units */
+ {"months", UNITS, DTK_MONTH}, /* "months" relative time units */
+ {"ms", UNITS, DTK_MILLISEC},/* "millisecond" relative time units */
+ {"msec", UNITS, DTK_MILLISEC}, /* "millisecond" relative time
+ * units */
+ {DMILLISEC, UNITS, DTK_MILLISEC}, /* "millisecond" relative time
+ * units */
+ {"mseconds", UNITS, DTK_MILLISEC}, /* "milliseconds" relative time
+ * units */
+ {"msecs", UNITS, DTK_MILLISEC}, /* "milliseconds" relative time
+ * units */
+ {"qtr", UNITS, DTK_QUARTER},/* "quarter" relative time units */
+ {DQUARTER, UNITS, DTK_QUARTER}, /* "quarter" relative time units */
+ {"reltime", IGNORE, 0}, /* "reltime" for pre-v6.1 "Undefined
+ * Reltime" */
+ {"s", UNITS, DTK_SECOND}, /* "second" relative time units */
+ {"sec", UNITS, DTK_SECOND}, /* "second" relative time units */
+ {DSECOND, UNITS, DTK_SECOND}, /* "second" relative time units */
+ {"seconds", UNITS, DTK_SECOND}, /* "seconds" relative time units */
+ {"secs", UNITS, DTK_SECOND},/* "seconds" relative time units */
+ {DTIMEZONE, UNITS, DTK_TZ}, /* "timezone" time offset */
+ {"tz", UNITS, DTK_TZ}, /* "timezone" time offset */
+ {"undefined", RESERV, DTK_INVALID}, /* "undefined" pre-v6.1 invalid
+ * time */
+ {"us", UNITS, DTK_MICROSEC},/* "microsecond" relative time units */
+ {"usec", UNITS, DTK_MICROSEC}, /* "microsecond" relative time
+ * units */
+ {DMICROSEC, UNITS, DTK_MICROSEC}, /* "microsecond" relative time
+ * units */
+ {"useconds", UNITS, DTK_MICROSEC}, /* "microseconds" relative time
+ * units */
+ {"usecs", UNITS, DTK_MICROSEC}, /* "microseconds" relative time
+ * units */
+ {"w", UNITS, DTK_WEEK}, /* "week" relative time units */
+ {DWEEK, UNITS, DTK_WEEK}, /* "week" relative time units */
+ {"weeks", UNITS, DTK_WEEK}, /* "weeks" relative time units */
+ {"y", UNITS, DTK_YEAR}, /* "year" relative time units */
+ {DYEAR, UNITS, DTK_YEAR}, /* "year" relative time units */
+ {"years", UNITS, DTK_YEAR}, /* "years" relative time units */
+ {"yr", UNITS, DTK_YEAR}, /* "year" relative time units */
+ {"yrs", UNITS, DTK_YEAR}, /* "years" relative time units */
};
static unsigned int szdeltatktbl = sizeof deltatktbl / sizeof deltatktbl[0];
#if USE_DATE_CACHE
-datetkn *datecache[MAXDATEFIELDS] = {NULL};
+datetkn *datecache[MAXDATEFIELDS] = {NULL};
+
+datetkn *deltacache[MAXDATEFIELDS] = {NULL};
-datetkn *deltacache[MAXDATEFIELDS] = {NULL};
#endif
/*
* Calendar time to Julian date conversions.
* Julian date is commonly used in astronomical applications,
- * since it is numerically accurate and computationally simple.
+ * since it is numerically accurate and computationally simple.
* The algorithms here will accurately convert between Julian day
- * and calendar date for all non-negative Julian days
- * (i.e. from Nov 23, -4713 on).
+ * and calendar date for all non-negative Julian days
+ * (i.e. from Nov 23, -4713 on).
*
* Ref: Explanatory Supplement to the Astronomical Almanac, 1992.
- * University Science Books, 20 Edgehill Rd. Mill Valley CA 94941.
+ * University Science Books, 20 Edgehill Rd. Mill Valley CA 94941.
*
* Use the algorithm by Henry Fliegel, a former NASA/JPL colleague
- * now at Aerospace Corp. (hi, Henry!)
+ * now at Aerospace Corp. (hi, Henry!)
*
* These routines will be used by other date/time packages - tgl 97/02/25
*/
/* Set the minimum year to one greater than the year of the first valid day
- * to avoid having to check year and day both. - tgl 97/05/08
+ * to avoid having to check year and day both. - tgl 97/05/08
*/
#define JULIAN_MINYEAR (-4713)
@@ -2074,45 +2341,50 @@ datetkn *deltacache[MAXDATEFIELDS] = {NULL};
int
date2j(int y, int m, int d)
{
- int m12 = (m-14)/12;
+ int m12 = (m - 14) / 12;
- return((1461*(y+4800+m12))/4 + (367*(m-2-12*(m12)))/12
- - (3*((y+4900+m12)/100))/4 + d - 32075);
-} /* date2j() */
+ return ((1461 * (y + 4800 + m12)) / 4 + (367 * (m - 2 - 12 * (m12))) / 12
+ - (3 * ((y + 4900 + m12) / 100)) / 4 + d - 32075);
+} /* date2j() */
void
-j2date( int jd, int *year, int *month, int *day)
+j2date(int jd, int *year, int *month, int *day)
{
- int j, y, m, d;
-
- int i, l, n;
-
- l = jd + 68569;
- n = (4*l)/146097;
- l -= (146097*n+3)/4;
- i = (4000*(l+1))/1461001;
- l += 31 - (1461*i)/4;
- j = (80*l)/2447;
- d = l - (2447*j)/80;
- l = j/11;
- m = (j+2) - (12*l);
- y = 100*(n-49)+i+l;
-
- *year = y;
- *month = m;
- *day = d;
- return;
-} /* j2date() */
+ int j,
+ y,
+ m,
+ d;
+
+ int i,
+ l,
+ n;
+
+ l = jd + 68569;
+ n = (4 * l) / 146097;
+ l -= (146097 * n + 3) / 4;
+ i = (4000 * (l + 1)) / 1461001;
+ l += 31 - (1461 * i) / 4;
+ j = (80 * l) / 2447;
+ d = l - (2447 * j) / 80;
+ l = j / 11;
+ m = (j + 2) - (12 * l);
+ y = 100 * (n - 49) + i + l;
+
+ *year = y;
+ *month = m;
+ *day = d;
+ return;
+} /* j2date() */
static int
-j2day( int date)
+j2day(int date)
{
- int day;
+ int day;
- day = (date+1) % 7;
+ day = (date + 1) % 7;
- return(day);
-} /* j2day() */
+ return (day);
+} /* j2day() */
/* datetime2tm()
@@ -2120,141 +2392,159 @@ j2day( int date)
* Note that year is _not_ 1900-based, but is an explicit full value.
* Also, month is one-based, _not_ zero-based.
* Returns:
- * 0 on success
- * -1 on out of range
+ * 0 on success
+ * -1 on out of range
*
* For dates within the system-supported time_t range, convert to the
- * local time zone. If out of this range, leave as GMT. - tgl 97/05/27
+ * local time zone. If out of this range, leave as GMT. - tgl 97/05/27
*/
int
-datetime2tm( DateTime dt, int *tzp, struct tm *tm, double *fsec, char **tzn)
+datetime2tm(DateTime dt, int *tzp, struct tm * tm, double *fsec, char **tzn)
{
- double date, date0, time, sec;
- time_t utime;
+ double date,
+ date0,
+ time,
+ sec;
+ time_t utime;
+
#ifdef USE_POSIX_TIME
- struct tm *tx;
+ struct tm *tx;
+
#endif
- date0 = date2j(2000,1,1);
+ date0 = date2j(2000, 1, 1);
- time = dt;
- TMODULO(time,date,86400e0);
+ time = dt;
+ TMODULO(time, date, 86400e0);
- if (time < 0) {
- time += 86400;
- date -= 1;
- }
+ if (time < 0)
+ {
+ time += 86400;
+ date -= 1;
+ }
- /* Julian day routine does not work for negative Julian days */
- if (date < -date0)
- return -1;
+ /* Julian day routine does not work for negative Julian days */
+ if (date < -date0)
+ return -1;
- /* add offset to go from J2000 back to standard Julian date */
- date += date0;
+ /* add offset to go from J2000 back to standard Julian date */
+ date += date0;
#ifdef DATEDEBUG
-printf( "datetime2tm- date is %f (%f %f)\n", dt, date, time);
+ printf("datetime2tm- date is %f (%f %f)\n", dt, date, time);
#endif
- j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
- dt2time( time, &tm->tm_hour, &tm->tm_min, &sec);
+ j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+ dt2time(time, &tm->tm_hour, &tm->tm_min, &sec);
#ifdef DATEDEBUG
-printf( "datetime2tm- date is %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
-printf( "datetime2tm- time is %02d:%02d:%02.0f\n", tm->tm_hour, tm->tm_min, sec);
+ printf("datetime2tm- date is %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
+ printf("datetime2tm- time is %02d:%02d:%02.0f\n", tm->tm_hour, tm->tm_min, sec);
#endif
- *fsec = JROUND(sec);
- TMODULO(*fsec,tm->tm_sec,1);
+ *fsec = JROUND(sec);
+ TMODULO(*fsec, tm->tm_sec, 1);
#ifdef DATEDEBUG
-printf( "datetime2tm- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
+ printf("datetime2tm- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
#endif
- if (tzp != NULL) {
- if (IS_VALID_UTIME( tm->tm_year, tm->tm_mon, tm->tm_mday)) {
- utime = (dt + (date0-date2j(1970,1,1))*86400);
+ if (tzp != NULL)
+ {
+ if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
+ {
+ utime = (dt + (date0 - date2j(1970, 1, 1)) * 86400);
#if FALSE
- if (utime < -1) utime++;
+ if (utime < -1)
+ utime++;
#endif
#ifdef USE_POSIX_TIME
- tx = localtime(&utime);
+ tx = localtime(&utime);
#ifdef DATEDEBUG
#ifdef HAVE_INT_TIMEZONE
-printf( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
- tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, sec,
- tzname[0], tzname[1], tx->tm_isdst);
+ printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
+ tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, sec,
+ tzname[0], tzname[1], tx->tm_isdst);
#else
-printf( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s dst=%d\n",
- tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, sec,
- tx->tm_zone, tx->tm_isdst);
+ printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s dst=%d\n",
+ tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, sec,
+ tx->tm_zone, tx->tm_isdst);
#endif
#else
#endif
- tm->tm_year = tx->tm_year + 1900;
- tm->tm_mon = tx->tm_mon + 1;
- tm->tm_mday = tx->tm_mday;
- tm->tm_hour = tx->tm_hour;
- tm->tm_min = tx->tm_min;
+ tm->tm_year = tx->tm_year + 1900;
+ tm->tm_mon = tx->tm_mon + 1;
+ tm->tm_mday = tx->tm_mday;
+ tm->tm_hour = tx->tm_hour;
+ tm->tm_min = tx->tm_min;
#if FALSE
/* XXX HACK
* Argh! My Linux box puts in a 1 second offset for dates less than 1970
- * but only if the seconds field was non-zero. So, don't copy the seconds
- * field and instead carry forward from the original - tgl 97/06/18
+ * but only if the seconds field was non-zero. So, don't copy the seconds
+ * field and instead carry forward from the original - tgl 97/06/18
* Note that GNU/Linux uses the standard freeware zic package as do
- * many other platforms so this may not be GNU/Linux/ix86-specific.
+ * many other platforms so this may not be GNU/Linux/ix86-specific.
*/
- tm->tm_sec = tx->tm_sec;
+ tm->tm_sec = tx->tm_sec;
#endif
- tm->tm_isdst = tx->tm_isdst;
+ tm->tm_isdst = tx->tm_isdst;
#ifdef HAVE_INT_TIMEZONE
- *tzp = (tm->tm_isdst? (timezone - 3600): timezone);
- if (tzn != NULL) *tzn = tzname[(tm->tm_isdst > 0)];
+ *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
+ if (tzn != NULL)
+ *tzn = tzname[(tm->tm_isdst > 0)];
-#else /* !HAVE_INT_TIMEZONE */
- tm->tm_gmtoff = tx->tm_gmtoff;
- tm->tm_zone = tx->tm_zone;
+#else /* !HAVE_INT_TIMEZONE */
+ tm->tm_gmtoff = tx->tm_gmtoff;
+ tm->tm_zone = tx->tm_zone;
- *tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
- if (tzn != NULL) *tzn = tm->tm_zone;
+ *tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
+ if (tzn != NULL)
+ *tzn = tm->tm_zone;
#endif
-#else /* !USE_POSIX_TIME */
- *tzp = CTimeZone; /* V7 conventions; don't know timezone? */
- if (tzn != NULL) *tzn = CTZName;
+#else /* !USE_POSIX_TIME */
+ *tzp = CTimeZone; /* V7 conventions; don't know timezone? */
+ if (tzn != NULL)
+ *tzn = CTZName;
#endif
- } else {
- *tzp = 0;
- tm->tm_isdst = 0;
- if (tzn != NULL) *tzn = NULL;
- }
+ }
+ else
+ {
+ *tzp = 0;
+ tm->tm_isdst = 0;
+ if (tzn != NULL)
+ *tzn = NULL;
+ }
- dt = dt2local( dt, *tzp);
+ dt = dt2local(dt, *tzp);
- } else {
- tm->tm_isdst = 0;
- if (tzn != NULL) *tzn = NULL;
- }
+ }
+ else
+ {
+ tm->tm_isdst = 0;
+ if (tzn != NULL)
+ *tzn = NULL;
+ }
#ifdef DATEDEBUG
-printf( "datetime2tm- date is %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
-printf( "datetime2tm- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
+ printf("datetime2tm- date is %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
+ printf("datetime2tm- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
#endif
#ifdef DATEDEBUG
#ifdef USE_POSIX_TIME
#ifdef HAVE_INT_TIMEZONE
-printf( "datetime2tm- timezone is %s; offset is %d (%d); daylight is %d\n",
- tzname[tm->tm_isdst != 0], ((tzp != NULL)? *tzp: 0), CTimeZone, CDayLight);
+ printf("datetime2tm- timezone is %s; offset is %d (%d); daylight is %d\n",
+ tzname[tm->tm_isdst != 0], ((tzp != NULL) ? *tzp : 0), CTimeZone, CDayLight);
#endif
#endif
#endif
- return 0;
-} /* datetime2tm() */
+ return 0;
+} /* datetime2tm() */
/* tm2datetime()
@@ -2263,109 +2553,115 @@ printf( "datetime2tm- timezone is %s; offset is %d (%d); daylight is %d\n",
* Also, month is one-based, _not_ zero-based.
*/
int
-tm2datetime( struct tm *tm, double fsec, int *tzp, DateTime *result) {
+tm2datetime(struct tm * tm, double fsec, int *tzp, DateTime * result)
+{
- double date, time;
+ double date,
+ time;
- /* Julian day routines are not correct for negative Julian days */
- if (! IS_VALID_JULIAN( tm->tm_year, tm->tm_mon, tm->tm_mday))
- return(-1);
+ /* Julian day routines are not correct for negative Julian days */
+ if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
+ return (-1);
- date = date2j(tm->tm_year,tm->tm_mon,tm->tm_mday) - date2j(2000,1,1);
- time = time2t(tm->tm_hour,tm->tm_min,(tm->tm_sec + fsec));
- *result = (date*86400+time);
+ date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
+ time = time2t(tm->tm_hour, tm->tm_min, (tm->tm_sec + fsec));
+ *result = (date * 86400 + time);
#ifdef DATEDEBUG
-printf( "tm2datetime- date is %f (%f %f %d)\n", *result, date, time, (((tm->tm_hour*60)+tm->tm_min)*60+tm->tm_sec));
-printf( "tm2datetime- time is %f %02d:%02d:%02d %f\n", time, tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
+ printf("tm2datetime- date is %f (%f %f %d)\n", *result, date, time, (((tm->tm_hour * 60) + tm->tm_min) * 60 + tm->tm_sec));
+ printf("tm2datetime- time is %f %02d:%02d:%02d %f\n", time, tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
#endif
- if (tzp != NULL) *result = dt2local(*result, -(*tzp));
+ if (tzp != NULL)
+ *result = dt2local(*result, -(*tzp));
- return 0;
-} /* tm2datetime() */
+ return 0;
+} /* tm2datetime() */
/* timespan2tm()
* Convert a timespan data type to a tm structure.
*/
static int
-timespan2tm(TimeSpan span, struct tm *tm, float8 *fsec)
+timespan2tm(TimeSpan span, struct tm * tm, float8 * fsec)
{
- double time;
+ double time;
- if (span.month != 0) {
- tm->tm_year = span.month / 12;
- tm->tm_mon = span.month % 12;
+ if (span.month != 0)
+ {
+ tm->tm_year = span.month / 12;
+ tm->tm_mon = span.month % 12;
- } else {
- tm->tm_year = 0;
- tm->tm_mon = 0;
- }
+ }
+ else
+ {
+ tm->tm_year = 0;
+ tm->tm_mon = 0;
+ }
#ifdef ROUND_ALL
- time = JROUND(span.time);
+ time = JROUND(span.time);
#else
- time = span.time;
+ time = span.time;
#endif
- TMODULO(time, tm->tm_mday, 86400e0);
- TMODULO(time, tm->tm_hour, 3600e0);
- TMODULO(time, tm->tm_min, 60e0);
- TMODULO(time, tm->tm_sec, 1);
- *fsec = time;
+ TMODULO(time, tm->tm_mday, 86400e0);
+ TMODULO(time, tm->tm_hour, 3600e0);
+ TMODULO(time, tm->tm_min, 60e0);
+ TMODULO(time, tm->tm_sec, 1);
+ *fsec = time;
#ifdef DATEDEBUG
-printf( "timespan2tm- %d %f = %04d-%02d-%02d %02d:%02d:%02d %.2f\n", span.month, span.time,
- tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
+ printf("timespan2tm- %d %f = %04d-%02d-%02d %02d:%02d:%02d %.2f\n", span.month, span.time,
+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
#endif
- return 0;
-} /* timespan2tm() */
+ return 0;
+} /* timespan2tm() */
static int
-tm2timespan( struct tm *tm, double fsec, TimeSpan *span)
+tm2timespan(struct tm * tm, double fsec, TimeSpan * span)
{
- span->month = ((tm->tm_year*12)+tm->tm_mon);
- span->time = ((((((tm->tm_mday*24)+tm->tm_hour)*60)+tm->tm_min)*60)+tm->tm_sec);
- span->time = JROUND(span->time + fsec);
+ span->month = ((tm->tm_year * 12) + tm->tm_mon);
+ span->time = ((((((tm->tm_mday * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60) + tm->tm_sec);
+ span->time = JROUND(span->time + fsec);
#ifdef DATEDEBUG
-printf( "tm2timespan- %d %f = %04d-%02d-%02d %02d:%02d:%02d %.2f\n", span->month, span->time,
- tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
+ printf("tm2timespan- %d %f = %04d-%02d-%02d %02d:%02d:%02d %.2f\n", span->month, span->time,
+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
#endif
- return 0;
-} /* tm2timespan() */
+ return 0;
+} /* tm2timespan() */
-static DateTime
+static DateTime
dt2local(DateTime dt, int tz)
{
- dt -= tz;
- dt = JROUND(dt);
- return(dt);
-} /* dt2local() */
+ dt -= tz;
+ dt = JROUND(dt);
+ return (dt);
+} /* dt2local() */
double
time2t(const int hour, const int min, const double sec)
{
- return((((hour*60)+min)*60)+sec);
-} /* time2t() */
+ return ((((hour * 60) + min) * 60) + sec);
+} /* time2t() */
static void
dt2time(DateTime jd, int *hour, int *min, double *sec)
{
- double time;
+ double time;
- time = jd;
+ time = jd;
- *hour = (time/3600);
- time -= ((*hour)*3600);
- *min = (time/60);
- time -= ((*min)*60);
- *sec = JROUND(time);
+ *hour = (time / 3600);
+ time -= ((*hour) * 3600);
+ *min = (time / 60);
+ time -= ((*min) * 60);
+ *sec = JROUND(time);
- return;
-} /* dt2time() */
+ return;
+} /* dt2time() */
/*
@@ -2378,469 +2674,561 @@ dt2time(DateTime jd, int *hour, int *min, double *sec)
* Break string into tokens based on a date/time context.
*/
int
-ParseDateTime( char *timestr, char *lowstr,
- char *field[], int ftype[], int maxfields, int *numfields)
-{
- int nf = 0;
- char *cp = timestr;
- char *lp = lowstr;
-
-#ifdef DATEDEBUG
-printf( "ParseDateTime- input string is %s\n", timestr);
-#endif
- /* outer loop through fields */
- while (*cp != '\0') {
- field[nf] = lp;
-
- /* leading digit? then date or time */
- if (isdigit(*cp)) {
- *lp++ = *cp++;
- while (isdigit(*cp)) *lp++ = *cp++;
- /* time field? */
- if (*cp == ':') {
- ftype[nf] = DTK_TIME;
- while (isdigit(*cp) || (*cp == ':') || (*cp == '.'))
- *lp++ = *cp++;
-
- /* date field? allow embedded text month */
- } else if ((*cp == '-') || (*cp == '/') || (*cp == '.')) {
- ftype[nf] = DTK_DATE;
- while (isalnum(*cp) || (*cp == '-') || (*cp == '/') || (*cp == '.'))
- *lp++ = tolower(*cp++);
-
- /* otherwise, number only and will determine year, month, or day later */
- } else {
- ftype[nf] = DTK_NUMBER;
- }
-
- /* text? then date string, month, day of week, special, or timezone */
- } else if (isalpha(*cp)) {
- ftype[nf] = DTK_STRING;
- *lp++ = tolower(*cp++);
- while (isalpha(*cp)) *lp++ = tolower(*cp++);
-
- /* full date string with leading text month? */
- if ((*cp == '-') || (*cp == '/') || (*cp == '.')) {
- ftype[nf] = DTK_DATE;
- while (isdigit(*cp) || (*cp == '-') || (*cp == '/') || (*cp == '.'))
- *lp++ = tolower(*cp++);
- }
-
- /* skip leading spaces */
- } else if (isspace(*cp)) {
- cp++;
- continue;
-
- /* sign? then special or numeric timezone */
- } else if ((*cp == '+') || (*cp == '-')) {
- *lp++ = *cp++;
- /* soak up leading whitespace */
- while (isspace(*cp)) cp++;
- /* numeric timezone? */
- if (isdigit(*cp)) {
- ftype[nf] = DTK_TZ;
- *lp++ = *cp++;
- while (isdigit(*cp) || (*cp == ':')) *lp++ = *cp++;
-
- /* special? */
- } else if (isalpha(*cp)) {
- ftype[nf] = DTK_SPECIAL;
- *lp++ = tolower(*cp++);
- while (isalpha(*cp)) *lp++ = tolower(*cp++);
-
- /* otherwise something wrong... */
- } else {
- return -1;
- }
+ParseDateTime(char *timestr, char *lowstr,
+ char *field[], int ftype[], int maxfields, int *numfields)
+{
+ int nf = 0;
+ char *cp = timestr;
+ char *lp = lowstr;
- /* ignore punctuation but use as delimiter */
- } else if (ispunct(*cp)) {
- cp++;
- continue;
+#ifdef DATEDEBUG
+ printf("ParseDateTime- input string is %s\n", timestr);
+#endif
+ /* outer loop through fields */
+ while (*cp != '\0')
+ {
+ field[nf] = lp;
+
+ /* leading digit? then date or time */
+ if (isdigit(*cp))
+ {
+ *lp++ = *cp++;
+ while (isdigit(*cp))
+ *lp++ = *cp++;
+ /* time field? */
+ if (*cp == ':')
+ {
+ ftype[nf] = DTK_TIME;
+ while (isdigit(*cp) || (*cp == ':') || (*cp == '.'))
+ *lp++ = *cp++;
+
+ /* date field? allow embedded text month */
+ }
+ else if ((*cp == '-') || (*cp == '/') || (*cp == '.'))
+ {
+ ftype[nf] = DTK_DATE;
+ while (isalnum(*cp) || (*cp == '-') || (*cp == '/') || (*cp == '.'))
+ *lp++ = tolower(*cp++);
+
+ /*
+ * otherwise, number only and will determine year, month,
+ * or day later
+ */
+ }
+ else
+ {
+ ftype[nf] = DTK_NUMBER;
+ }
+
+ /*
+ * text? then date string, month, day of week, special, or
+ * timezone
+ */
+ }
+ else if (isalpha(*cp))
+ {
+ ftype[nf] = DTK_STRING;
+ *lp++ = tolower(*cp++);
+ while (isalpha(*cp))
+ *lp++ = tolower(*cp++);
+
+ /* full date string with leading text month? */
+ if ((*cp == '-') || (*cp == '/') || (*cp == '.'))
+ {
+ ftype[nf] = DTK_DATE;
+ while (isdigit(*cp) || (*cp == '-') || (*cp == '/') || (*cp == '.'))
+ *lp++ = tolower(*cp++);
+ }
+
+ /* skip leading spaces */
+ }
+ else if (isspace(*cp))
+ {
+ cp++;
+ continue;
- } else {
- return -1;
- }
+ /* sign? then special or numeric timezone */
+ }
+ else if ((*cp == '+') || (*cp == '-'))
+ {
+ *lp++ = *cp++;
+ /* soak up leading whitespace */
+ while (isspace(*cp))
+ cp++;
+ /* numeric timezone? */
+ if (isdigit(*cp))
+ {
+ ftype[nf] = DTK_TZ;
+ *lp++ = *cp++;
+ while (isdigit(*cp) || (*cp == ':'))
+ *lp++ = *cp++;
+
+ /* special? */
+ }
+ else if (isalpha(*cp))
+ {
+ ftype[nf] = DTK_SPECIAL;
+ *lp++ = tolower(*cp++);
+ while (isalpha(*cp))
+ *lp++ = tolower(*cp++);
+
+ /* otherwise something wrong... */
+ }
+ else
+ {
+ return -1;
+ }
+
+ /* ignore punctuation but use as delimiter */
+ }
+ else if (ispunct(*cp))
+ {
+ cp++;
+ continue;
- /* force in a delimiter */
- *lp++ = '\0';
- nf++;
- if (nf > MAXDATEFIELDS) {
- return -1;
- }
+ }
+ else
+ {
+ return -1;
+ }
+
+ /* force in a delimiter */
+ *lp++ = '\0';
+ nf++;
+ if (nf > MAXDATEFIELDS)
+ {
+ return -1;
+ }
#ifdef DATEDEBUG
-printf( "ParseDateTime- set field[%d] to %s type %d\n", (nf-1), field[nf-1], ftype[nf-1]);
+ printf("ParseDateTime- set field[%d] to %s type %d\n", (nf - 1), field[nf - 1], ftype[nf - 1]);
#endif
- }
+ }
- *numfields = nf;
+ *numfields = nf;
- return 0;
-} /* ParseDateTime() */
+ return 0;
+} /* ParseDateTime() */
/* DecodeDateTime()
* Interpret previously parsed fields for general date and time.
* Return 0 if full date, 1 if only time, and -1 if problems.
- * External format(s):
- * "<weekday> <month>-<day>-<year> <hour>:<minute>:<second>"
- * "Fri Feb-7-1997 15:23:27"
- * "Feb-7-1997 15:23:27"
- * "2-7-1997 15:23:27"
- * "1997-2-7 15:23:27"
- * "1997.038 15:23:27" (day of year 1-366)
- * Also supports input in compact time:
- * "970207 152327"
- * "97038 152327"
+ * External format(s):
+ * "<weekday> <month>-<day>-<year> <hour>:<minute>:<second>"
+ * "Fri Feb-7-1997 15:23:27"
+ * "Feb-7-1997 15:23:27"
+ * "2-7-1997 15:23:27"
+ * "1997-2-7 15:23:27"
+ * "1997.038 15:23:27" (day of year 1-366)
+ * Also supports input in compact time:
+ * "970207 152327"
+ * "97038 152327"
*
* Use the system-provided functions to get the current time zone
- * if not specified in the input string.
+ * if not specified in the input string.
* If the date is outside the time_t system-supported time range,
- * then assume GMT time zone. - tgl 97/05/27
+ * then assume GMT time zone. - tgl 97/05/27
*/
int
-DecodeDateTime( char *field[], int ftype[], int nf,
- int *dtype, struct tm *tm, double *fsec, int *tzp)
+DecodeDateTime(char *field[], int ftype[], int nf,
+ int *dtype, struct tm * tm, double *fsec, int *tzp)
{
- int fmask = 0, tmask, type;
- int i;
- int flen, val;
- int mer = HR24;
- int bc = FALSE;
+ int fmask = 0,
+ tmask,
+ type;
+ int i;
+ int flen,
+ val;
+ int mer = HR24;
+ int bc = FALSE;
+
+ *dtype = DTK_DATE;
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+ *fsec = 0;
+ tm->tm_isdst = -1; /* don't know daylight savings time status
+ * apriori */
+ if (tzp != NULL)
+ *tzp = 0;
- *dtype = DTK_DATE;
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
- *fsec = 0;
- tm->tm_isdst = -1; /* don't know daylight savings time status apriori */
- if (tzp != NULL) *tzp = 0;
+ for (i = 0; i < nf; i++)
+ {
+#ifdef DATEDEBUG
+ printf("DecodeDateTime- field[%d] is %s (type %d)\n", i, field[i], ftype[i]);
+#endif
+ switch (ftype[i])
+ {
+ case DTK_DATE:
+ if (DecodeDate(field[i], fmask, &tmask, tm) != 0)
+ return -1;
+ break;
+
+ case DTK_TIME:
+ if (DecodeTime(field[i], fmask, &tmask, tm, fsec) != 0)
+ return -1;
+
+ /*
+ * check upper limit on hours; other limits checked in
+ * DecodeTime()
+ */
+ if (tm->tm_hour > 23)
+ return -1;
+ break;
+
+ case DTK_TZ:
+ if (tzp == NULL)
+ return -1;
+ if (DecodeTimezone(field[i], tzp) != 0)
+ return -1;
+ tmask = DTK_M(TZ);
+ break;
+
+ case DTK_NUMBER:
+ flen = strlen(field[i]);
+
+ if (flen > 4)
+ {
+ if (DecodeNumberField(flen, field[i], fmask, &tmask, tm, fsec) != 0)
+ return -1;
+
+ }
+ else
+ {
+ if (DecodeNumber(flen, field[i], fmask, &tmask, tm, fsec) != 0)
+ return -1;
+ }
+ break;
+
+ case DTK_STRING:
+ case DTK_SPECIAL:
+ type = DecodeSpecial(i, field[i], &val);
+#ifdef DATEDEBUG
+ printf("DecodeDateTime- special field[%d] %s type=%d value=%d\n", i, field[i], type, val);
+#endif
+ if (type == IGNORE)
+ continue;
- for (i = 0; i < nf; i++) {
+ tmask = DTK_M(type);
+ switch (type)
+ {
+ case RESERV:
#ifdef DATEDEBUG
-printf( "DecodeDateTime- field[%d] is %s (type %d)\n", i, field[i], ftype[i]);
+ printf("DecodeDateTime- RESERV field %s value is %d\n", field[i], val);
#endif
- switch (ftype[i]) {
- case DTK_DATE:
- if (DecodeDate(field[i], fmask, &tmask, tm) != 0) return -1;
- break;
-
- case DTK_TIME:
- if (DecodeTime(field[i], fmask, &tmask, tm, fsec) != 0) return -1;
- /* check upper limit on hours; other limits checked in DecodeTime() */
- if (tm->tm_hour > 23) return -1;
- break;
-
- case DTK_TZ:
- if (tzp == NULL) return -1;
- if (DecodeTimezone( field[i], tzp) != 0) return -1;
- tmask = DTK_M(TZ);
- break;
-
- case DTK_NUMBER:
- flen = strlen(field[i]);
-
- if (flen > 4) {
- if (DecodeNumberField( flen, field[i], fmask, &tmask, tm, fsec) != 0)
- return -1;
-
- } else {
- if (DecodeNumber( flen, field[i], fmask, &tmask, tm, fsec) != 0)
- return -1;
- }
- break;
-
- case DTK_STRING:
- case DTK_SPECIAL:
- type = DecodeSpecial( i, field[i], &val);
-#ifdef DATEDEBUG
-printf( "DecodeDateTime- special field[%d] %s type=%d value=%d\n", i, field[i], type, val);
-#endif
- if (type == IGNORE) continue;
-
- tmask = DTK_M(type);
- switch (type) {
- case RESERV:
-#ifdef DATEDEBUG
-printf( "DecodeDateTime- RESERV field %s value is %d\n", field[i], val);
-#endif
- switch (val) {
- case DTK_NOW:
- tmask = (DTK_DATE_M | DTK_TIME_M | DTK_M(TZ));
- *dtype = DTK_DATE;
- GetCurrentTime(tm);
- if (tzp != NULL) *tzp = CTimeZone;
- break;
-
- case DTK_YESTERDAY:
- tmask = DTK_DATE_M;
- *dtype = DTK_DATE;
- GetCurrentTime(tm);
- j2date( (date2j( tm->tm_year, tm->tm_mon, tm->tm_mday)-1),
- &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
- break;
-
- case DTK_TODAY:
- tmask = DTK_DATE_M;
- *dtype = DTK_DATE;
- GetCurrentTime(tm);
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
- break;
-
- case DTK_TOMORROW:
- tmask = DTK_DATE_M;
- *dtype = DTK_DATE;
- GetCurrentTime(tm);
- j2date( (date2j( tm->tm_year, tm->tm_mon, tm->tm_mday)+1),
- &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
- break;
-
- case DTK_ZULU:
- tmask = (DTK_TIME_M | DTK_M(TZ));
- *dtype = DTK_DATE;
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
- if (tzp != NULL) *tzp = 0;
- break;
+ switch (val)
+ {
+ case DTK_NOW:
+ tmask = (DTK_DATE_M | DTK_TIME_M | DTK_M(TZ));
+ *dtype = DTK_DATE;
+ GetCurrentTime(tm);
+ if (tzp != NULL)
+ *tzp = CTimeZone;
+ break;
+
+ case DTK_YESTERDAY:
+ tmask = DTK_DATE_M;
+ *dtype = DTK_DATE;
+ GetCurrentTime(tm);
+ j2date((date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - 1),
+ &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+ break;
+
+ case DTK_TODAY:
+ tmask = DTK_DATE_M;
+ *dtype = DTK_DATE;
+ GetCurrentTime(tm);
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+ break;
+
+ case DTK_TOMORROW:
+ tmask = DTK_DATE_M;
+ *dtype = DTK_DATE;
+ GetCurrentTime(tm);
+ j2date((date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + 1),
+ &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+ break;
+
+ case DTK_ZULU:
+ tmask = (DTK_TIME_M | DTK_M(TZ));
+ *dtype = DTK_DATE;
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+ if (tzp != NULL)
+ *tzp = 0;
+ break;
+
+ default:
+ *dtype = val;
+ }
+
+ break;
+
+ case MONTH:
+#ifdef DATEDEBUG
+ printf("DecodeDateTime- month field %s value is %d\n", field[i], val);
+#endif
+ tm->tm_mon = val;
+ break;
+
+ /*
+ * daylight savings time modifier (solves "MET DST"
+ * syntax)
+ */
+ case DTZMOD:
+ tmask |= DTK_M(DTZ);
+ tm->tm_isdst = 1;
+ if (tzp == NULL)
+ return -1;
+ *tzp += val * 60;
+ break;
+
+ case DTZ:
+
+ /*
+ * set mask for TZ here _or_ check for DTZ later when
+ * getting default timezone
+ */
+ tmask |= DTK_M(TZ);
+ tm->tm_isdst = 1;
+ if (tzp == NULL)
+ return -1;
+ *tzp = val * 60;
+ break;
+
+ case TZ:
+ tm->tm_isdst = 0;
+ if (tzp == NULL)
+ return -1;
+ *tzp = val * 60;
+ break;
+
+ case IGNORE:
+ break;
+
+ case AMPM:
+ mer = val;
+ break;
+
+ case ADBC:
+ bc = (val == BC);
+ break;
+
+ case DOW:
+ tm->tm_wday = val;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
default:
- *dtype = val;
+ return -1;
}
- break;
-
- case MONTH:
#ifdef DATEDEBUG
-printf( "DecodeDateTime- month field %s value is %d\n", field[i], val);
+ printf("DecodeDateTime- field[%d] %s (%08x/%08x) value is %d\n",
+ i, field[i], fmask, tmask, val);
#endif
- tm->tm_mon = val;
- break;
- /* daylight savings time modifier (solves "MET DST" syntax) */
- case DTZMOD:
- tmask |= DTK_M(DTZ);
- tm->tm_isdst = 1;
- if (tzp == NULL) return -1;
- *tzp += val * 60;
- break;
-
- case DTZ:
- /* set mask for TZ here _or_ check for DTZ later when getting default timezone */
- tmask |= DTK_M(TZ);
- tm->tm_isdst = 1;
- if (tzp == NULL) return -1;
- *tzp = val * 60;
- break;
-
- case TZ:
- tm->tm_isdst = 0;
- if (tzp == NULL) return -1;
- *tzp = val * 60;
- break;
-
- case IGNORE:
- break;
-
- case AMPM:
- mer = val;
- break;
-
- case ADBC:
- bc = (val == BC);
- break;
-
- case DOW:
- tm->tm_wday = val;
- break;
-
- default:
- return -1;
- }
- break;
-
- default:
- return -1;
+ if (tmask & fmask)
+ return -1;
+ fmask |= tmask;
}
-#ifdef DATEDEBUG
-printf( "DecodeDateTime- field[%d] %s (%08x/%08x) value is %d\n",
- i, field[i], fmask, tmask, val);
-#endif
-
- if (tmask & fmask) return -1;
- fmask |= tmask;
- }
+ /* there is no year zero in AD/BC notation; i.e. "1 BC" == year 0 */
+ if (bc)
+ tm->tm_year = -(tm->tm_year - 1);
- /* there is no year zero in AD/BC notation; i.e. "1 BC" == year 0 */
- if (bc) tm->tm_year = -(tm->tm_year-1);
-
- if ((mer != HR24) && (tm->tm_hour > 12))
- return -1;
- if (mer == PM) tm->tm_hour += 12;
+ if ((mer != HR24) && (tm->tm_hour > 12))
+ return -1;
+ if (mer == PM)
+ tm->tm_hour += 12;
#ifdef DATEDEBUG
-printf( "DecodeDateTime- mask %08x (%08x)", fmask, DTK_DATE_M);
-printf( " set y%04d m%02d d%02d", tm->tm_year, tm->tm_mon, tm->tm_mday);
-printf( " %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
+ printf("DecodeDateTime- mask %08x (%08x)", fmask, DTK_DATE_M);
+ printf(" set y%04d m%02d d%02d", tm->tm_year, tm->tm_mon, tm->tm_mday);
+ printf(" %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
#endif
- if ((*dtype == DTK_DATE) && ((fmask & DTK_DATE_M) != DTK_DATE_M))
- return(((fmask & DTK_TIME_M) == DTK_TIME_M)? 1: -1);
+ if ((*dtype == DTK_DATE) && ((fmask & DTK_DATE_M) != DTK_DATE_M))
+ return (((fmask & DTK_TIME_M) == DTK_TIME_M) ? 1 : -1);
- /* timezone not specified? then find local timezone if possible */
- if ((*dtype == DTK_DATE) && ((fmask & DTK_DATE_M) == DTK_DATE_M)
- && (tzp != NULL) && (! (fmask & DTK_M(TZ)))) {
+ /* timezone not specified? then find local timezone if possible */
+ if ((*dtype == DTK_DATE) && ((fmask & DTK_DATE_M) == DTK_DATE_M)
+ && (tzp != NULL) && (!(fmask & DTK_M(TZ))))
+ {
- /* daylight savings time modifier but no standard timezone? then error */
- if (fmask & DTK_M(DTZMOD)) return -1;
+ /*
+ * daylight savings time modifier but no standard timezone? then
+ * error
+ */
+ if (fmask & DTK_M(DTZMOD))
+ return -1;
- if (IS_VALID_UTIME( tm->tm_year, tm->tm_mon, tm->tm_mday)) {
+ if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
+ {
#ifdef USE_POSIX_TIME
- tm->tm_year -= 1900;
- tm->tm_mon -= 1;
- tm->tm_isdst = -1;
- mktime(tm);
- tm->tm_year += 1900;
- tm->tm_mon += 1;
+ tm->tm_year -= 1900;
+ tm->tm_mon -= 1;
+ tm->tm_isdst = -1;
+ mktime(tm);
+ tm->tm_year += 1900;
+ tm->tm_mon += 1;
#ifdef HAVE_INT_TIMEZONE
- *tzp = ((tm->tm_isdst > 0)? (timezone - 3600): timezone);
+ *tzp = ((tm->tm_isdst > 0) ? (timezone - 3600) : timezone);
-#else /* !HAVE_INT_TIMEZONE */
- *tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
+#else /* !HAVE_INT_TIMEZONE */
+ *tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
#endif
-#else /* !USE_POSIX_TIME */
- *tzp = CTimeZone;
+#else /* !USE_POSIX_TIME */
+ *tzp = CTimeZone;
#endif
- } else {
- tm->tm_isdst = 0;
- *tzp = 0;
+ }
+ else
+ {
+ tm->tm_isdst = 0;
+ *tzp = 0;
+ }
}
- }
- return 0;
-} /* DecodeDateTime() */
+ return 0;
+} /* DecodeDateTime() */
/* DecodeTimeOnly()
* Interpret parsed string as time fields only.
*/
int
-DecodeTimeOnly( char *field[], int ftype[], int nf, int *dtype, struct tm *tm, double *fsec)
+DecodeTimeOnly(char *field[], int ftype[], int nf, int *dtype, struct tm * tm, double *fsec)
{
- int fmask, tmask, type;
- int i;
- int flen, val;
- int mer = HR24;
-
- *dtype = DTK_TIME;
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
- tm->tm_isdst = -1; /* don't know daylight savings time status apriori */
+ int fmask,
+ tmask,
+ type;
+ int i;
+ int flen,
+ val;
+ int mer = HR24;
+
+ *dtype = DTK_TIME;
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+ tm->tm_isdst = -1; /* don't know daylight savings time status
+ * apriori */
- fmask = DTK_DATE_M;
+ fmask = DTK_DATE_M;
- for (i = 0; i < nf; i++) {
+ for (i = 0; i < nf; i++)
+ {
#ifdef DATEDEBUG
-printf( "DecodeTimeOnly- field[%d] is %s (type %d)\n", i, field[i], ftype[i]);
+ printf("DecodeTimeOnly- field[%d] is %s (type %d)\n", i, field[i], ftype[i]);
#endif
- switch (ftype[i]) {
- case DTK_TIME:
- if (DecodeTime(field[i], fmask, &tmask, tm, fsec) != 0) return -1;
- break;
-
- case DTK_NUMBER:
- flen = strlen(field[i]);
-
- if (DecodeNumberField( flen, field[i], fmask, &tmask, tm, fsec) != 0)
- return -1;
- break;
-
- case DTK_STRING:
- case DTK_SPECIAL:
- type = DecodeSpecial( i, field[i], &val);
+ switch (ftype[i])
+ {
+ case DTK_TIME:
+ if (DecodeTime(field[i], fmask, &tmask, tm, fsec) != 0)
+ return -1;
+ break;
+
+ case DTK_NUMBER:
+ flen = strlen(field[i]);
+
+ if (DecodeNumberField(flen, field[i], fmask, &tmask, tm, fsec) != 0)
+ return -1;
+ break;
+
+ case DTK_STRING:
+ case DTK_SPECIAL:
+ type = DecodeSpecial(i, field[i], &val);
#ifdef DATEDEBUG
-printf( "DecodeTimeOnly- special field[%d] %s type=%d value=%d\n", i, field[i], type, val);
+ printf("DecodeTimeOnly- special field[%d] %s type=%d value=%d\n", i, field[i], type, val);
#endif
- if (type == IGNORE) continue;
+ if (type == IGNORE)
+ continue;
- tmask = DTK_M(type);
- switch (type) {
- case RESERV:
+ tmask = DTK_M(type);
+ switch (type)
+ {
+ case RESERV:
#ifdef DATEDEBUG
-printf( "DecodeTimeOnly- RESERV field %s value is %d\n", field[i], val);
+ printf("DecodeTimeOnly- RESERV field %s value is %d\n", field[i], val);
#endif
- switch (val) {
- case DTK_NOW:
- tmask = DTK_TIME_M;
- *dtype = DTK_TIME;
- GetCurrentTime(tm);
- break;
-
- case DTK_ZULU:
- tmask = (DTK_TIME_M | DTK_M(TZ));
- *dtype = DTK_TIME;
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
- tm->tm_isdst = 0;
- break;
+ switch (val)
+ {
+ case DTK_NOW:
+ tmask = DTK_TIME_M;
+ *dtype = DTK_TIME;
+ GetCurrentTime(tm);
+ break;
+
+ case DTK_ZULU:
+ tmask = (DTK_TIME_M | DTK_M(TZ));
+ *dtype = DTK_TIME;
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+ tm->tm_isdst = 0;
+ break;
+
+ default:
+ return -1;
+ }
+
+ break;
+
+ case IGNORE:
+ break;
+
+ case AMPM:
+ mer = val;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
default:
- return -1;
+ return -1;
}
- break;
-
- case IGNORE:
- break;
-
- case AMPM:
- mer = val;
- break;
-
- default:
- return -1;
- }
- break;
-
- default:
- return -1;
- }
-
- if (tmask & fmask) return -1;
- fmask |= tmask;
+ if (tmask & fmask)
+ return -1;
+ fmask |= tmask;
#ifdef DATEDEBUG
-printf( "DecodeTimeOnly- field[%d] %s value is %d\n", i, field[i], val);
+ printf("DecodeTimeOnly- field[%d] %s value is %d\n", i, field[i], val);
#endif
- }
+ }
#ifdef DATEDEBUG
-printf( "DecodeTimeOnly- mask %08x (%08x)", fmask, DTK_TIME_M);
-printf( " %02d:%02d:%02d (%f)\n", tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
+ printf("DecodeTimeOnly- mask %08x (%08x)", fmask, DTK_TIME_M);
+ printf(" %02d:%02d:%02d (%f)\n", tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
#endif
- if ((mer != HR24) && (tm->tm_hour > 12))
- return -1;
- if (mer == PM) tm->tm_hour += 12;
+ if ((mer != HR24) && (tm->tm_hour > 12))
+ return -1;
+ if (mer == PM)
+ tm->tm_hour += 12;
- if ((fmask & DTK_TIME_M) != DTK_TIME_M)
- return -1;
+ if ((fmask & DTK_TIME_M) != DTK_TIME_M)
+ return -1;
- return 0;
-} /* DecodeTimeOnly() */
+ return 0;
+} /* DecodeTimeOnly() */
/* DecodeDate()
@@ -2848,390 +3236,472 @@ printf( " %02d:%02d:%02d (%f)\n", tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
* Insist on a complete set of fields.
*/
static int
-DecodeDate(char *str, int fmask, int *tmask, struct tm *tm)
+DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
{
- double fsec;
-
- int nf = 0;
- int i, len;
- int type, val, dmask = 0;
- char *field[MAXDATEFIELDS];
-
- /* parse this string... */
- while ((*str != '\0') && (nf < MAXDATEFIELDS)) {
- /* skip field separators */
- while (! isalnum(*str)) str++;
+ double fsec;
+
+ int nf = 0;
+ int i,
+ len;
+ int type,
+ val,
+ dmask = 0;
+ char *field[MAXDATEFIELDS];
+
+ /* parse this string... */
+ while ((*str != '\0') && (nf < MAXDATEFIELDS))
+ {
+ /* skip field separators */
+ while (!isalnum(*str))
+ str++;
+
+ field[nf] = str;
+ if (isdigit(*str))
+ {
+ while (isdigit(*str))
+ str++;
+ }
+ else if (isalpha(*str))
+ {
+ while (isalpha(*str))
+ str++;
+ }
- field[nf] = str;
- if (isdigit(*str)) {
- while (isdigit(*str)) str++;
- } else if (isalpha(*str)) {
- while (isalpha(*str)) str++;
+ if (*str != '\0')
+ *str++ = '\0';
+ nf++;
}
- if (*str != '\0') *str++ = '\0';
- nf++;
- }
-
- /* don't allow too many fields */
- if (nf > 3) return -1;
-
- *tmask = 0;
-
- /* look first for text fields, since that will be unambiguous month */
- for (i = 0; i < nf; i++) {
- if (isalpha(*field[i])) {
- type = DecodeSpecial( i, field[i], &val);
- if (type == IGNORE) continue;
+ /* don't allow too many fields */
+ if (nf > 3)
+ return -1;
- dmask = DTK_M(type);
- switch (type) {
- case MONTH:
+ *tmask = 0;
+
+ /* look first for text fields, since that will be unambiguous month */
+ for (i = 0; i < nf; i++)
+ {
+ if (isalpha(*field[i]))
+ {
+ type = DecodeSpecial(i, field[i], &val);
+ if (type == IGNORE)
+ continue;
+
+ dmask = DTK_M(type);
+ switch (type)
+ {
+ case MONTH:
#ifdef DATEDEBUG
-printf( "DecodeDate- month field %s value is %d\n", field[i], val);
+ printf("DecodeDate- month field %s value is %d\n", field[i], val);
#endif
- tm->tm_mon = val;
- break;
+ tm->tm_mon = val;
+ break;
- default:
+ default:
#ifdef DATEDEBUG
-printf( "DecodeDate- illegal field %s value is %d\n", field[i], val);
+ printf("DecodeDate- illegal field %s value is %d\n", field[i], val);
#endif
- return -1;
- }
- if (fmask & dmask) return -1;
+ return -1;
+ }
+ if (fmask & dmask)
+ return -1;
- fmask |= dmask;
- *tmask |= dmask;
+ fmask |= dmask;
+ *tmask |= dmask;
- /* mark this field as being completed */
- field[i] = NULL;
+ /* mark this field as being completed */
+ field[i] = NULL;
+ }
}
- }
- /* now pick up remaining numeric fields */
- for (i = 0; i < nf; i++) {
- if (field[i] == NULL) continue;
+ /* now pick up remaining numeric fields */
+ for (i = 0; i < nf; i++)
+ {
+ if (field[i] == NULL)
+ continue;
- if ((len = strlen(field[i])) <= 0)
- return -1;
+ if ((len = strlen(field[i])) <= 0)
+ return -1;
- if (DecodeNumber( len, field[i], fmask, &dmask, tm, &fsec) != 0)
- return -1;
+ if (DecodeNumber(len, field[i], fmask, &dmask, tm, &fsec) != 0)
+ return -1;
- if (fmask & dmask) return -1;
+ if (fmask & dmask)
+ return -1;
- fmask |= dmask;
- *tmask |= dmask;
- }
+ fmask |= dmask;
+ *tmask |= dmask;
+ }
- return 0;
-} /* DecodeDate() */
+ return 0;
+} /* DecodeDate() */
/* DecodeTime()
* Decode time string which includes delimiters.
* Only check the lower limit on hours, since this same code
- * can be used to represent time spans.
+ * can be used to represent time spans.
*/
static int
-DecodeTime(char *str, int fmask, int *tmask, struct tm *tm, double *fsec)
+DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, double *fsec)
{
- char *cp;
+ char *cp;
- *tmask = DTK_TIME_M;
+ *tmask = DTK_TIME_M;
- tm->tm_hour = strtol( str, &cp, 10);
- if (*cp != ':') return -1;
- str = cp+1;
- tm->tm_min = strtol( str, &cp, 10);
- if (*cp == '\0') {
- tm->tm_sec = 0;
- *fsec = 0;
+ tm->tm_hour = strtol(str, &cp, 10);
+ if (*cp != ':')
+ return -1;
+ str = cp + 1;
+ tm->tm_min = strtol(str, &cp, 10);
+ if (*cp == '\0')
+ {
+ tm->tm_sec = 0;
+ *fsec = 0;
- } else if (*cp != ':') {
- return -1;
+ }
+ else if (*cp != ':')
+ {
+ return -1;
- } else {
- str = cp+1;
- tm->tm_sec = strtol( str, &cp, 10);
- if (*cp == '\0') {
- *fsec = 0;
- } else if (*cp == '.') {
- str = cp;
- *fsec = strtod( str, &cp);
- if (cp == str) return -1;
- } else {
- return -1;
}
- }
+ else
+ {
+ str = cp + 1;
+ tm->tm_sec = strtol(str, &cp, 10);
+ if (*cp == '\0')
+ {
+ *fsec = 0;
+ }
+ else if (*cp == '.')
+ {
+ str = cp;
+ *fsec = strtod(str, &cp);
+ if (cp == str)
+ return -1;
+ }
+ else
+ {
+ return -1;
+ }
+ }
- /* do a sanity check */
- if ((tm->tm_hour < 0)
- || (tm->tm_min < 0) || (tm->tm_min > 59)
- || (tm->tm_sec < 0) || (tm->tm_sec > 59)) return -1;
+ /* do a sanity check */
+ if ((tm->tm_hour < 0)
+ || (tm->tm_min < 0) || (tm->tm_min > 59)
+ || (tm->tm_sec < 0) || (tm->tm_sec > 59))
+ return -1;
- return 0;
-} /* DecodeTime() */
+ return 0;
+} /* DecodeTime() */
/* DecodeNumber()
* Interpret numeric field as a date value in context.
*/
static int
-DecodeNumber( int flen, char *str, int fmask, int *tmask, struct tm *tm, double *fsec)
+DecodeNumber(int flen, char *str, int fmask, int *tmask, struct tm * tm, double *fsec)
{
- int val;
- char *cp;
+ int val;
+ char *cp;
- *tmask = 0;
+ *tmask = 0;
- val = strtol( str, &cp, 10);
- if (cp == str) return -1;
- if (*cp == '.') {
- *fsec = strtod( cp, &cp);
- if (*cp != '\0') return -1;
- }
+ val = strtol(str, &cp, 10);
+ if (cp == str)
+ return -1;
+ if (*cp == '.')
+ {
+ *fsec = strtod(cp, &cp);
+ if (*cp != '\0')
+ return -1;
+ }
#ifdef DATEDEBUG
-printf( "DecodeNumber- %s is %d fmask=%08x tmask=%08x\n", str, val, fmask, *tmask);
+ printf("DecodeNumber- %s is %d fmask=%08x tmask=%08x\n", str, val, fmask, *tmask);
#endif
- /* enough digits to be unequivocal year? */
- if (flen == 4) {
+ /* enough digits to be unequivocal year? */
+ if (flen == 4)
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumber- match %d (%s) as year\n", val, str);
+ printf("DecodeNumber- match %d (%s) as year\n", val, str);
#endif
- *tmask = DTK_M(YEAR);
-
- /* already have a year? then see if we can substitute... */
- if (fmask & DTK_M(YEAR)) {
- if ((!(fmask & DTK_M(DAY)))
- && ((tm->tm_year >= 1) && (tm->tm_year <= 31))) {
+ *tmask = DTK_M(YEAR);
+
+ /* already have a year? then see if we can substitute... */
+ if (fmask & DTK_M(YEAR))
+ {
+ if ((!(fmask & DTK_M(DAY)))
+ && ((tm->tm_year >= 1) && (tm->tm_year <= 31)))
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumber- misidentified year previously; swap with day %d\n", tm->tm_mday);
+ printf("DecodeNumber- misidentified year previously; swap with day %d\n", tm->tm_mday);
#endif
- tm->tm_mday = tm->tm_year;
- *tmask = DTK_M(DAY);
- }
- }
-
- tm->tm_year = val;
+ tm->tm_mday = tm->tm_year;
+ *tmask = DTK_M(DAY);
+ }
+ }
- /* special case day of year? */
- } else if ((flen == 3) && (fmask & DTK_M(YEAR))
- && ((val >= 1) && (val <= 366))) {
- *tmask = (DTK_M(DOY) | DTK_M(MONTH) | DTK_M(DAY));
- tm->tm_yday = val;
- j2date((date2j(tm->tm_year,1,1)+tm->tm_yday-1),
- &tm->tm_year,&tm->tm_mon,&tm->tm_mday);
+ tm->tm_year = val;
- /* already have year? then could be month */
- } else if ((fmask & DTK_M(YEAR)) && (! (fmask & DTK_M(MONTH)))
- && ((val >= 1) && (val <= 12))) {
+ /* special case day of year? */
+ }
+ else if ((flen == 3) && (fmask & DTK_M(YEAR))
+ && ((val >= 1) && (val <= 366)))
+ {
+ *tmask = (DTK_M(DOY) | DTK_M(MONTH) | DTK_M(DAY));
+ tm->tm_yday = val;
+ j2date((date2j(tm->tm_year, 1, 1) + tm->tm_yday - 1),
+ &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+
+ /* already have year? then could be month */
+ }
+ else if ((fmask & DTK_M(YEAR)) && (!(fmask & DTK_M(MONTH)))
+ && ((val >= 1) && (val <= 12)))
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumber- match %d (%s) as month\n", val, str);
+ printf("DecodeNumber- match %d (%s) as month\n", val, str);
#endif
- *tmask = DTK_M(MONTH);
- tm->tm_mon = val;
+ *tmask = DTK_M(MONTH);
+ tm->tm_mon = val;
- /* no year and EuroDates enabled? then could be day */
- } else if ((EuroDates || (fmask & DTK_M(MONTH)))
- && (!(fmask & DTK_M(YEAR)) && !(fmask & DTK_M(DAY)))
- && ((val >= 1) && (val <= 31))) {
+ /* no year and EuroDates enabled? then could be day */
+ }
+ else if ((EuroDates || (fmask & DTK_M(MONTH)))
+ && (!(fmask & DTK_M(YEAR)) && !(fmask & DTK_M(DAY)))
+ && ((val >= 1) && (val <= 31)))
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumber- match %d (%s) as day\n", val, str);
+ printf("DecodeNumber- match %d (%s) as day\n", val, str);
#endif
- *tmask = DTK_M(DAY);
- tm->tm_mday = val;
+ *tmask = DTK_M(DAY);
+ tm->tm_mday = val;
- } else if ((! (fmask & DTK_M(MONTH)))
- && ((val >= 1) && (val <= 12))) {
+ }
+ else if ((!(fmask & DTK_M(MONTH)))
+ && ((val >= 1) && (val <= 12)))
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumber- (2) match %d (%s) as month\n", val, str);
+ printf("DecodeNumber- (2) match %d (%s) as month\n", val, str);
#endif
- *tmask = DTK_M(MONTH);
- tm->tm_mon = val;
+ *tmask = DTK_M(MONTH);
+ tm->tm_mon = val;
- } else if ((! (fmask & DTK_M(DAY)))
- && ((val >= 1) && (val <= 31))) {
+ }
+ else if ((!(fmask & DTK_M(DAY)))
+ && ((val >= 1) && (val <= 31)))
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumber- (2) match %d (%s) as day\n", val, str);
+ printf("DecodeNumber- (2) match %d (%s) as day\n", val, str);
#endif
- *tmask = DTK_M(DAY);
- tm->tm_mday = val;
+ *tmask = DTK_M(DAY);
+ tm->tm_mday = val;
- } else if (! (fmask & DTK_M(YEAR))) {
+ }
+ else if (!(fmask & DTK_M(YEAR)))
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumber- (2) match %d (%s) as year\n", val, str);
+ printf("DecodeNumber- (2) match %d (%s) as year\n", val, str);
#endif
- *tmask = DTK_M(YEAR);
- tm->tm_year = val;
- if (tm->tm_year < 70) {
- tm->tm_year += 2000;
- } else if (tm->tm_year < 100) {
- tm->tm_year += 1900;
- }
+ *tmask = DTK_M(YEAR);
+ tm->tm_year = val;
+ if (tm->tm_year < 70)
+ {
+ tm->tm_year += 2000;
+ }
+ else if (tm->tm_year < 100)
+ {
+ tm->tm_year += 1900;
+ }
- } else {
- return -1;
- }
+ }
+ else
+ {
+ return -1;
+ }
- return 0;
-} /* DecodeNumber() */
+ return 0;
+} /* DecodeNumber() */
/* DecodeNumberField()
* Interpret numeric string as a concatenated date field.
*/
static int
-DecodeNumberField( int len, char *str, int fmask, int *tmask, struct tm *tm, double *fsec)
+DecodeNumberField(int len, char *str, int fmask, int *tmask, struct tm * tm, double *fsec)
{
- char *cp;
+ char *cp;
- /* yyyymmdd? */
- if (len == 8) {
+ /* yyyymmdd? */
+ if (len == 8)
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumberField- %s is 8 character date fmask=%08x tmask=%08x\n", str, fmask, *tmask);
+ printf("DecodeNumberField- %s is 8 character date fmask=%08x tmask=%08x\n", str, fmask, *tmask);
#endif
- *tmask = DTK_DATE_M;
+ *tmask = DTK_DATE_M;
- tm->tm_mday = atoi(str+6);
- *(str+6) = '\0';
- tm->tm_mon = atoi(str+4);
- *(str+4) = '\0';
- tm->tm_year = atoi(str+0);
+ tm->tm_mday = atoi(str + 6);
+ *(str + 6) = '\0';
+ tm->tm_mon = atoi(str + 4);
+ *(str + 4) = '\0';
+ tm->tm_year = atoi(str + 0);
- /* yymmdd or hhmmss? */
- } else if (len == 6) {
+ /* yymmdd or hhmmss? */
+ }
+ else if (len == 6)
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumberField- %s is 6 characters fmask=%08x tmask=%08x\n", str, fmask, *tmask);
+ printf("DecodeNumberField- %s is 6 characters fmask=%08x tmask=%08x\n", str, fmask, *tmask);
#endif
- if (fmask & DTK_DATE_M) {
+ if (fmask & DTK_DATE_M)
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumberField- %s is time field fmask=%08x tmask=%08x\n", str, fmask, *tmask);
+ printf("DecodeNumberField- %s is time field fmask=%08x tmask=%08x\n", str, fmask, *tmask);
#endif
- *tmask = DTK_TIME_M;
- tm->tm_sec = atoi(str+4);
- *(str+4) = '\0';
- tm->tm_min = atoi(str+2);
- *(str+2) = '\0';
- tm->tm_hour = atoi(str+0);
+ *tmask = DTK_TIME_M;
+ tm->tm_sec = atoi(str + 4);
+ *(str + 4) = '\0';
+ tm->tm_min = atoi(str + 2);
+ *(str + 2) = '\0';
+ tm->tm_hour = atoi(str + 0);
- } else {
+ }
+ else
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumberField- %s is date field fmask=%08x tmask=%08x\n", str, fmask, *tmask);
+ printf("DecodeNumberField- %s is date field fmask=%08x tmask=%08x\n", str, fmask, *tmask);
#endif
- *tmask = DTK_DATE_M;
- tm->tm_mday = atoi(str+4);
- *(str+4) = '\0';
- tm->tm_mon = atoi(str+2);
- *(str+2) = '\0';
- tm->tm_year = atoi(str+0);
- }
+ *tmask = DTK_DATE_M;
+ tm->tm_mday = atoi(str + 4);
+ *(str + 4) = '\0';
+ tm->tm_mon = atoi(str + 2);
+ *(str + 2) = '\0';
+ tm->tm_year = atoi(str + 0);
+ }
- } else if (strchr(str,'.') != NULL) {
+ }
+ else if (strchr(str, '.') != NULL)
+ {
#ifdef DATEDEBUG
-printf( "DecodeNumberField- %s is time field fmask=%08x tmask=%08x\n", str, fmask, *tmask);
+ printf("DecodeNumberField- %s is time field fmask=%08x tmask=%08x\n", str, fmask, *tmask);
#endif
- *tmask = DTK_TIME_M;
- tm->tm_sec = strtod( (str+4), &cp);
- if (cp == (str+4)) return -1;
- if (*cp == '.') {
- *fsec = strtod( cp, NULL);
- }
- *(str+4) = '\0';
- tm->tm_min = strtod( (str+2), &cp);
- *(str+2) = '\0';
- tm->tm_hour = strtod( (str+0), &cp);
+ *tmask = DTK_TIME_M;
+ tm->tm_sec = strtod((str + 4), &cp);
+ if (cp == (str + 4))
+ return -1;
+ if (*cp == '.')
+ {
+ *fsec = strtod(cp, NULL);
+ }
+ *(str + 4) = '\0';
+ tm->tm_min = strtod((str + 2), &cp);
+ *(str + 2) = '\0';
+ tm->tm_hour = strtod((str + 0), &cp);
- } else {
- return -1;
- }
+ }
+ else
+ {
+ return -1;
+ }
- return 0;
-} /* DecodeNumberField() */
+ return 0;
+} /* DecodeNumberField() */
/* DecodeTimezone()
* Interpret string as a numeric timezone.
*/
static int
-DecodeTimezone( char *str, int *tzp)
+DecodeTimezone(char *str, int *tzp)
{
- int tz;
- int hr, min;
- char *cp;
- int len;
+ int tz;
+ int hr,
+ min;
+ char *cp;
+ int len;
- /* assume leading character is "+" or "-" */
- hr = strtol( (str+1), &cp, 10);
+ /* assume leading character is "+" or "-" */
+ hr = strtol((str + 1), &cp, 10);
- /* explicit delimiter? */
- if (*cp == ':') {
- min = strtol( (cp+1), &cp, 10);
+ /* explicit delimiter? */
+ if (*cp == ':')
+ {
+ min = strtol((cp + 1), &cp, 10);
- /* otherwise, might have run things together... */
- } else if ((*cp == '\0') && ((len = strlen(str)) > 3)) {
- min = strtol( (str+len-2), &cp, 10);
- *(str+len-2) = '\0';
- hr = strtol( (str+1), &cp, 10);
+ /* otherwise, might have run things together... */
+ }
+ else if ((*cp == '\0') && ((len = strlen(str)) > 3))
+ {
+ min = strtol((str + len - 2), &cp, 10);
+ *(str + len - 2) = '\0';
+ hr = strtol((str + 1), &cp, 10);
- } else {
- min = 0;
- }
+ }
+ else
+ {
+ min = 0;
+ }
- tz = (hr*60+min)*60;
- if (*str == '-') tz = -tz;
+ tz = (hr * 60 + min) * 60;
+ if (*str == '-')
+ tz = -tz;
- *tzp = -tz;
- return( *cp != '\0');
-} /* DecodeTimezone() */
+ *tzp = -tz;
+ return (*cp != '\0');
+} /* DecodeTimezone() */
/* DecodeSpecial()
* Decode text string using lookup table.
* Implement a cache lookup since it is likely that dates
- * will be related in format.
+ * will be related in format.
*/
static int
DecodeSpecial(int field, char *lowtoken, int *val)
{
- int type;
- datetkn *tp;
+ int type;
+ datetkn *tp;
#if USE_DATE_CACHE
- if ((datecache[field] != NULL)
- && (strncmp(lowtoken,datecache[field]->token,TOKMAXLEN) == 0)) {
- tp = datecache[field];
- } else {
+ if ((datecache[field] != NULL)
+ && (strncmp(lowtoken, datecache[field]->token, TOKMAXLEN) == 0))
+ {
+ tp = datecache[field];
+ }
+ else
+ {
#endif
- tp = datebsearch(lowtoken, datetktbl, szdatetktbl);
+ tp = datebsearch(lowtoken, datetktbl, szdatetktbl);
#if USE_DATE_CACHE
- }
- datecache[field] = tp;
-#endif
- if (tp == NULL) {
- type = IGNORE;
- *val = 0;
- } else {
- type = tp->type;
- switch (type) {
- case TZ:
- case DTZ:
- case DTZMOD:
- *val = FROMVAL(tp);
- break;
+ }
+ datecache[field] = tp;
+#endif
+ if (tp == NULL)
+ {
+ type = IGNORE;
+ *val = 0;
+ }
+ else
+ {
+ type = tp->type;
+ switch (type)
+ {
+ case TZ:
+ case DTZ:
+ case DTZMOD:
+ *val = FROMVAL(tp);
+ break;
- default:
- *val = tp->value;
- break;
+ default:
+ *val = tp->value;
+ break;
+ }
}
- }
- return(type);
-} /* DecodeSpecial() */
+ return (type);
+} /* DecodeSpecial() */
/* DecodeDateDelta()
@@ -3239,212 +3709,239 @@ DecodeSpecial(int field, char *lowtoken, int *val)
* Return 0 if decoded and -1 if problems.
*
* If code is changed to read fields from first to last,
- * then use READ_FORWARD-bracketed code to allow sign
- * to persist to subsequent unsigned fields.
+ * then use READ_FORWARD-bracketed code to allow sign
+ * to persist to subsequent unsigned fields.
*/
int
-DecodeDateDelta( char *field[], int ftype[], int nf, int *dtype, struct tm *tm, double *fsec)
+DecodeDateDelta(char *field[], int ftype[], int nf, int *dtype, struct tm * tm, double *fsec)
{
- int is_before = FALSE;
+ int is_before = FALSE;
+
#if READ_FORWARD
- int is_neg = FALSE;
+ int is_neg = FALSE;
+
#endif
- int fmask = 0, tmask, type;
- int i, ii;
- int flen, val;
- char *cp;
- double sec;
+ int fmask = 0,
+ tmask,
+ type;
+ int i,
+ ii;
+ int flen,
+ val;
+ char *cp;
+ double sec;
- *dtype = DTK_DELTA;
+ *dtype = DTK_DELTA;
- type = SECOND;
- tm->tm_year = 0;
- tm->tm_mon = 0;
- tm->tm_mday = 0;
- tm->tm_hour = 0;
- tm->tm_min = 0;
- tm->tm_sec = 0;
- *fsec = 0;
+ type = SECOND;
+ tm->tm_year = 0;
+ tm->tm_mon = 0;
+ tm->tm_mday = 0;
+ tm->tm_hour = 0;
+ tm->tm_min = 0;
+ tm->tm_sec = 0;
+ *fsec = 0;
- /* read through list forwards to pick up initial time fields, if any */
- for (ii = 0; ii < nf; ii++) {
+ /* read through list forwards to pick up initial time fields, if any */
+ for (ii = 0; ii < nf; ii++)
+ {
#ifdef DATEDEBUG
-printf( "DecodeDateDelta- field[%d] is %s (type %d)\n", ii, field[ii], ftype[ii]);
+ printf("DecodeDateDelta- field[%d] is %s (type %d)\n", ii, field[ii], ftype[ii]);
#endif
- if (ftype[ii] == DTK_TIME) {
- if (DecodeTime(field[ii], fmask, &tmask, tm, fsec) != 0) return -1;
- fmask |= tmask;
+ if (ftype[ii] == DTK_TIME)
+ {
+ if (DecodeTime(field[ii], fmask, &tmask, tm, fsec) != 0)
+ return -1;
+ fmask |= tmask;
- } else {
- break;
+ }
+ else
+ {
+ break;
+ }
}
- }
- /* read through remaining list backwards to pick up units before values */
- for (i = nf-1; i >= ii; i--) {
+ /*
+ * read through remaining list backwards to pick up units before
+ * values
+ */
+ for (i = nf - 1; i >= ii; i--)
+ {
#ifdef DATEDEBUG
-printf( "DecodeDateDelta- field[%d] is %s (type %d)\n", i, field[i], ftype[i]);
+ printf("DecodeDateDelta- field[%d] is %s (type %d)\n", i, field[i], ftype[i]);
#endif
- switch (ftype[i]) {
- case DTK_TIME:
- /* already read in forward-scan above so return error */
+ switch (ftype[i])
+ {
+ case DTK_TIME:
+ /* already read in forward-scan above so return error */
#if FALSE
- if (DecodeTime(field[i], fmask, &tmask, tm, fsec) != 0) return -1;
+ if (DecodeTime(field[i], fmask, &tmask, tm, fsec) != 0)
+ return -1;
#endif
- return -1;
- break;
+ return -1;
+ break;
- case DTK_TZ: /* timezone is a token with a leading sign character */
+ case DTK_TZ: /* timezone is a token with a leading sign
+ * character */
#if READ_FORWARD
- is_neg = (*field[i] == '-');
+ is_neg = (*field[i] == '-');
#endif
- case DTK_NUMBER:
- val = strtol( field[i], &cp, 10);
+ case DTK_NUMBER:
+ val = strtol(field[i], &cp, 10);
#if READ_FORWARD
- if (is_neg && (val > 0)) val = -val;
-#endif
- if (*cp == '.') {
- *fsec = strtod( cp, NULL);
- if (val < 0) *fsec = - (*fsec);
- }
- flen = strlen(field[i]);
- tmask = 0; /* DTK_M(type); */
-
- switch (type) {
- case DTK_MICROSEC:
- *fsec += (val * 1e-6);
- break;
-
- case DTK_MILLISEC:
- *fsec += (val * 1e-3);
- break;
-
- case DTK_SECOND:
- tm->tm_sec += val;
- tmask = DTK_M(SECOND);
- break;
-
- case DTK_MINUTE:
- tm->tm_min += val;
- tmask = DTK_M(MINUTE);
- break;
-
- case DTK_HOUR:
- tm->tm_hour += val;
- tmask = DTK_M(HOUR);
- break;
-
- case DTK_DAY:
- tm->tm_mday += val;
- tmask = ((fmask & DTK_M(DAY))? 0: DTK_M(DAY));
- break;
-
- case DTK_WEEK:
- tm->tm_mday += val*7;
- tmask = ((fmask & DTK_M(DAY))? 0: DTK_M(DAY));
- break;
-
- case DTK_MONTH:
- tm->tm_mon += val;
- tmask = DTK_M(MONTH);
- break;
-
- case DTK_YEAR:
- tm->tm_year += val;
- tmask = ((fmask & DTK_M(YEAR))? 0: DTK_M(YEAR));
- break;
-
- case DTK_DECADE:
- tm->tm_year += val*10;
- tmask = ((fmask & DTK_M(YEAR))? 0: DTK_M(YEAR));
- break;
-
- case DTK_CENTURY:
- tm->tm_year += val*100;
- tmask = ((fmask & DTK_M(YEAR))? 0: DTK_M(YEAR));
- break;
-
- case DTK_MILLENIUM:
- tm->tm_year += val*1000;
- tmask = ((fmask & DTK_M(YEAR))? 0: DTK_M(YEAR));
- break;
-
- default:
- return -1;
- }
- break;
-
- case DTK_STRING:
- case DTK_SPECIAL:
- type = DecodeUnits( i, field[i], &val);
+ if (is_neg && (val > 0))
+ val = -val;
+#endif
+ if (*cp == '.')
+ {
+ *fsec = strtod(cp, NULL);
+ if (val < 0)
+ *fsec = -(*fsec);
+ }
+ flen = strlen(field[i]);
+ tmask = 0; /* DTK_M(type); */
+
+ switch (type)
+ {
+ case DTK_MICROSEC:
+ *fsec += (val * 1e-6);
+ break;
+
+ case DTK_MILLISEC:
+ *fsec += (val * 1e-3);
+ break;
+
+ case DTK_SECOND:
+ tm->tm_sec += val;
+ tmask = DTK_M(SECOND);
+ break;
+
+ case DTK_MINUTE:
+ tm->tm_min += val;
+ tmask = DTK_M(MINUTE);
+ break;
+
+ case DTK_HOUR:
+ tm->tm_hour += val;
+ tmask = DTK_M(HOUR);
+ break;
+
+ case DTK_DAY:
+ tm->tm_mday += val;
+ tmask = ((fmask & DTK_M(DAY)) ? 0 : DTK_M(DAY));
+ break;
+
+ case DTK_WEEK:
+ tm->tm_mday += val * 7;
+ tmask = ((fmask & DTK_M(DAY)) ? 0 : DTK_M(DAY));
+ break;
+
+ case DTK_MONTH:
+ tm->tm_mon += val;
+ tmask = DTK_M(MONTH);
+ break;
+
+ case DTK_YEAR:
+ tm->tm_year += val;
+ tmask = ((fmask & DTK_M(YEAR)) ? 0 : DTK_M(YEAR));
+ break;
+
+ case DTK_DECADE:
+ tm->tm_year += val * 10;
+ tmask = ((fmask & DTK_M(YEAR)) ? 0 : DTK_M(YEAR));
+ break;
+
+ case DTK_CENTURY:
+ tm->tm_year += val * 100;
+ tmask = ((fmask & DTK_M(YEAR)) ? 0 : DTK_M(YEAR));
+ break;
+
+ case DTK_MILLENIUM:
+ tm->tm_year += val * 1000;
+ tmask = ((fmask & DTK_M(YEAR)) ? 0 : DTK_M(YEAR));
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case DTK_STRING:
+ case DTK_SPECIAL:
+ type = DecodeUnits(i, field[i], &val);
#ifdef DATEDEBUG
-printf( "DecodeDateDelta- special field[%d] %s type=%d value=%d\n", i, field[i], type, val);
+ printf("DecodeDateDelta- special field[%d] %s type=%d value=%d\n", i, field[i], type, val);
#endif
- if (type == IGNORE) continue;
+ if (type == IGNORE)
+ continue;
- tmask = 0; /* DTK_M(type); */
- switch (type) {
- case UNITS:
+ tmask = 0; /* DTK_M(type); */
+ switch (type)
+ {
+ case UNITS:
#ifdef DATEDEBUG
-printf( "DecodeDateDelta- UNITS field %s value is %d\n", field[i], val);
+ printf("DecodeDateDelta- UNITS field %s value is %d\n", field[i], val);
#endif
- type = val;
- break;
+ type = val;
+ break;
- case AGO:
- is_before = TRUE;
- type = val;
- break;
+ case AGO:
+ is_before = TRUE;
+ type = val;
+ break;
- case RESERV:
- tmask = (DTK_DATE_M || DTK_TIME_M);
- *dtype = val;
- break;
+ case RESERV:
+ tmask = (DTK_DATE_M || DTK_TIME_M);
+ *dtype = val;
+ break;
- default:
- return -1;
- }
- break;
+ default:
+ return -1;
+ }
+ break;
- default:
- return -1;
- }
+ default:
+ return -1;
+ }
#ifdef DATEDEBUG
-printf( "DecodeDateDelta- (%08x/%08x) field[%d] %s value is %d\n",
- fmask, tmask, i, field[i], val);
+ printf("DecodeDateDelta- (%08x/%08x) field[%d] %s value is %d\n",
+ fmask, tmask, i, field[i], val);
#endif
- if (tmask & fmask) return -1;
- fmask |= tmask;
- }
+ if (tmask & fmask)
+ return -1;
+ fmask |= tmask;
+ }
- if (*fsec != 0) {
- TMODULO(*fsec,sec,1);
- tm->tm_sec += sec;
- }
+ if (*fsec != 0)
+ {
+ TMODULO(*fsec, sec, 1);
+ tm->tm_sec += sec;
+ }
- if (is_before) {
- *fsec = -(*fsec);
- tm->tm_sec = -(tm->tm_sec);
- tm->tm_min = -(tm->tm_min);
- tm->tm_hour = -(tm->tm_hour);
- tm->tm_mday = -(tm->tm_mday);
- tm->tm_mon = -(tm->tm_mon);
- tm->tm_year = -(tm->tm_year);
- }
+ if (is_before)
+ {
+ *fsec = -(*fsec);
+ tm->tm_sec = -(tm->tm_sec);
+ tm->tm_min = -(tm->tm_min);
+ tm->tm_hour = -(tm->tm_hour);
+ tm->tm_mday = -(tm->tm_mday);
+ tm->tm_mon = -(tm->tm_mon);
+ tm->tm_year = -(tm->tm_year);
+ }
#ifdef DATEDEBUG
-printf( "DecodeDateDelta- mask %08x (%08x)", fmask, DTK_DATE_M);
-printf( " set y%04d m%02d d%02d", tm->tm_year, tm->tm_mon, tm->tm_mday);
-printf( " %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
+ printf("DecodeDateDelta- mask %08x (%08x)", fmask, DTK_DATE_M);
+ printf(" set y%04d m%02d d%02d", tm->tm_year, tm->tm_mon, tm->tm_mday);
+ printf(" %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
#endif
- /* ensure that at least one time field has been found */
- return((fmask != 0)? 0: -1);
-} /* DecodeDateDelta() */
+ /* ensure that at least one time field has been found */
+ return ((fmask != 0) ? 0 : -1);
+} /* DecodeDateDelta() */
/* DecodeUnits()
@@ -3454,34 +3951,43 @@ printf( " %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
static int
DecodeUnits(int field, char *lowtoken, int *val)
{
- int type;
- datetkn *tp;
+ int type;
+ datetkn *tp;
#if USE_DATE_CACHE
- if ((deltacache[field] != NULL)
- && (strncmp(lowtoken,deltacache[field]->token,TOKMAXLEN) == 0)) {
- tp = deltacache[field];
- } else {
+ if ((deltacache[field] != NULL)
+ && (strncmp(lowtoken, deltacache[field]->token, TOKMAXLEN) == 0))
+ {
+ tp = deltacache[field];
+ }
+ else
+ {
#endif
- tp = datebsearch(lowtoken, deltatktbl, szdeltatktbl);
+ tp = datebsearch(lowtoken, deltatktbl, szdeltatktbl);
#if USE_DATE_CACHE
- }
- deltacache[field] = tp;
+ }
+ deltacache[field] = tp;
#endif
- if (tp == NULL) {
- type = IGNORE;
- *val = 0;
- } else {
- type = tp->type;
- if ((type == TZ) || (type == DTZ)) {
- *val = FROMVAL(tp);
- } else {
- *val = tp->value;
+ if (tp == NULL)
+ {
+ type = IGNORE;
+ *val = 0;
+ }
+ else
+ {
+ type = tp->type;
+ if ((type == TZ) || (type == DTZ))
+ {
+ *val = FROMVAL(tp);
+ }
+ else
+ {
+ *val = tp->value;
+ }
}
- }
- return(type);
-} /* DecodeUnits() */
+ return (type);
+} /* DecodeUnits() */
/* datebsearch()
@@ -3489,25 +3995,28 @@ DecodeUnits(int field, char *lowtoken, int *val)
* is WAY faster than the generic bsearch().
*/
static datetkn *
-datebsearch(char *key, datetkn *base, unsigned int nel)
+datebsearch(char *key, datetkn * base, unsigned int nel)
{
- register datetkn *last = base + nel - 1, *position;
- register int result;
-
- while (last >= base) {
- position = base + ((last - base) >> 1);
- result = key[0] - position->token[0];
- if (result == 0) {
- result = strncmp(key, position->token, TOKMAXLEN);
- if (result == 0)
- return position;
+ register datetkn *last = base + nel - 1,
+ *position;
+ register int result;
+
+ while (last >= base)
+ {
+ position = base + ((last - base) >> 1);
+ result = key[0] - position->token[0];
+ if (result == 0)
+ {
+ result = strncmp(key, position->token, TOKMAXLEN);
+ if (result == 0)
+ return position;
+ }
+ if (result < 0)
+ last = position - 1;
+ else
+ base = position + 1;
}
- if (result < 0)
- last = position - 1;
- else
- base = position + 1;
- }
- return NULL;
+ return NULL;
}
@@ -3517,373 +4026,466 @@ datebsearch(char *key, datetkn *base, unsigned int nel)
static int
EncodeSpecialDateTime(DateTime dt, char *str)
{
- if (DATETIME_IS_RESERVED(dt)) {
- if (DATETIME_IS_INVALID(dt)) {
- strcpy( str, INVALID);
+ if (DATETIME_IS_RESERVED(dt))
+ {
+ if (DATETIME_IS_INVALID(dt))
+ {
+ strcpy(str, INVALID);
- } else if (DATETIME_IS_NOBEGIN(dt)) {
- strcpy( str, EARLY);
+ }
+ else if (DATETIME_IS_NOBEGIN(dt))
+ {
+ strcpy(str, EARLY);
- } else if (DATETIME_IS_NOEND(dt)) {
- strcpy( str, LATE);
+ }
+ else if (DATETIME_IS_NOEND(dt))
+ {
+ strcpy(str, LATE);
- } else if (DATETIME_IS_CURRENT(dt)) {
- strcpy( str, DCURRENT);
+ }
+ else if (DATETIME_IS_CURRENT(dt))
+ {
+ strcpy(str, DCURRENT);
- } else if (DATETIME_IS_EPOCH(dt)) {
- strcpy( str, EPOCH);
+ }
+ else if (DATETIME_IS_EPOCH(dt))
+ {
+ strcpy(str, EPOCH);
- } else {
+ }
+ else
+ {
#ifdef DATEDEBUG
-printf( "EncodeSpecialDateTime- unrecognized date\n");
+ printf("EncodeSpecialDateTime- unrecognized date\n");
#endif
- strcpy( str, INVALID);
+ strcpy(str, INVALID);
+ }
+ return (TRUE);
}
- return(TRUE);
- }
- return(FALSE);
-} /* EncodeSpecialDateTime() */
+ return (FALSE);
+} /* EncodeSpecialDateTime() */
/* EncodeDateOnly()
* Encode date as local time.
*/
-int EncodeDateOnly(struct tm *tm, int style, char *str)
+int
+EncodeDateOnly(struct tm * tm, int style, char *str)
{
#if FALSE
- int day;
+ int day;
+
#endif
- if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
- return -1;
+ if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
+ return -1;
- /* compatible with ISO date formats */
- if (style == USE_ISO_DATES) {
- if (tm->tm_year > 0) {
- sprintf( str, "%04d-%02d-%02d",
- tm->tm_year, tm->tm_mon, tm->tm_mday);
+ /* compatible with ISO date formats */
+ if (style == USE_ISO_DATES)
+ {
+ if (tm->tm_year > 0)
+ {
+ sprintf(str, "%04d-%02d-%02d",
+ tm->tm_year, tm->tm_mon, tm->tm_mday);
- } else {
- sprintf( str, "%04d-%02d-%02d %s",
- -(tm->tm_year-1), tm->tm_mon, tm->tm_mday, "BC");
- }
+ }
+ else
+ {
+ sprintf(str, "%04d-%02d-%02d %s",
+ -(tm->tm_year - 1), tm->tm_mon, tm->tm_mday, "BC");
+ }
- /* compatible with Oracle/Ingres date formats */
- } else if (style == USE_SQL_DATES) {
- if (EuroDates) {
- sprintf( str, "%02d/%02d", tm->tm_mday, tm->tm_mon);
- } else {
- sprintf( str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
+ /* compatible with Oracle/Ingres date formats */
}
- if (tm->tm_year > 0) {
- sprintf( (str+5), "/%04d", tm->tm_year);
+ else if (style == USE_SQL_DATES)
+ {
+ if (EuroDates)
+ {
+ sprintf(str, "%02d/%02d", tm->tm_mday, tm->tm_mon);
+ }
+ else
+ {
+ sprintf(str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
+ }
+ if (tm->tm_year > 0)
+ {
+ sprintf((str + 5), "/%04d", tm->tm_year);
- } else {
- sprintf( (str+5), "/%04d %s", -(tm->tm_year-1), "BC");
- }
+ }
+ else
+ {
+ sprintf((str + 5), "/%04d %s", -(tm->tm_year - 1), "BC");
+ }
- /* backward-compatible with traditional Postgres abstime dates */
- } else { /* if (style == USE_POSTGRES_DATES) */
+ /* backward-compatible with traditional Postgres abstime dates */
+ }
+ else
+ { /* if (style == USE_POSTGRES_DATES) */
#if FALSE
- day = date2j( tm->tm_year, tm->tm_mon, tm->tm_mday);
+ day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
#ifdef DATEDEBUG
-printf( "EncodeDateOnly- day is %d\n", day);
+ printf("EncodeDateOnly- day is %d\n", day);
#endif
- tm->tm_wday = j2day( day);
+ tm->tm_wday = j2day(day);
- strncpy( str, days[tm->tm_wday], 3);
- strcpy( (str+3), " ");
+ strncpy(str, days[tm->tm_wday], 3);
+ strcpy((str + 3), " ");
- if (EuroDates) {
- sprintf( (str+4), "%02d %3s", tm->tm_mday, months[tm->tm_mon-1]);
- } else {
- sprintf( (str+4), "%3s %02d", months[tm->tm_mon-1], tm->tm_mday);
- }
- if (tm->tm_year > 0) {
- sprintf( (str+10), " %04d", tm->tm_year);
+ if (EuroDates)
+ {
+ sprintf((str + 4), "%02d %3s", tm->tm_mday, months[tm->tm_mon - 1]);
+ }
+ else
+ {
+ sprintf((str + 4), "%3s %02d", months[tm->tm_mon - 1], tm->tm_mday);
+ }
+ if (tm->tm_year > 0)
+ {
+ sprintf((str + 10), " %04d", tm->tm_year);
- } else {
- sprintf( (str+10), " %04d %s", -(tm->tm_year-1), "BC");
- }
+ }
+ else
+ {
+ sprintf((str + 10), " %04d %s", -(tm->tm_year - 1), "BC");
+ }
#endif
- /* traditional date-only style for Postgres */
- if (EuroDates) {
- sprintf( str, "%02d-%02d", tm->tm_mday, tm->tm_mon);
- } else {
- sprintf( str, "%02d-%02d", tm->tm_mon, tm->tm_mday);
- }
- if (tm->tm_year > 0) {
- sprintf( (str+5), "-%04d", tm->tm_year);
+ /* traditional date-only style for Postgres */
+ if (EuroDates)
+ {
+ sprintf(str, "%02d-%02d", tm->tm_mday, tm->tm_mon);
+ }
+ else
+ {
+ sprintf(str, "%02d-%02d", tm->tm_mon, tm->tm_mday);
+ }
+ if (tm->tm_year > 0)
+ {
+ sprintf((str + 5), "-%04d", tm->tm_year);
- } else {
- sprintf( (str+5), "-%04d %s", -(tm->tm_year-1), "BC");
+ }
+ else
+ {
+ sprintf((str + 5), "-%04d %s", -(tm->tm_year - 1), "BC");
+ }
}
- }
#ifdef DATEDEBUG
-printf( "EncodeDateOnly- date result is %s\n", str);
+ printf("EncodeDateOnly- date result is %s\n", str);
#endif
- return(TRUE);
-} /* EncodeDateOnly() */
+ return (TRUE);
+} /* EncodeDateOnly() */
/* EncodeTimeOnly()
* Encode time fields only.
*/
-int EncodeTimeOnly(struct tm *tm, double fsec, int style, char *str)
+int
+EncodeTimeOnly(struct tm * tm, double fsec, int style, char *str)
{
- double sec;
+ double sec;
- if ((tm->tm_hour < 0) || (tm->tm_hour > 24))
- return -1;
+ if ((tm->tm_hour < 0) || (tm->tm_hour > 24))
+ return -1;
- sec = (tm->tm_sec + fsec);
+ sec = (tm->tm_sec + fsec);
- sprintf( str, "%02d:%02d:", tm->tm_hour, tm->tm_min);
- sprintf( (str+6), ((fsec != 0)? "%05.2f": "%02.0f"), sec);
+ sprintf(str, "%02d:%02d:", tm->tm_hour, tm->tm_min);
+ sprintf((str + 6), ((fsec != 0) ? "%05.2f" : "%02.0f"), sec);
#ifdef DATEDEBUG
-printf( "EncodeTimeOnly- time result is %s\n", str);
+ printf("EncodeTimeOnly- time result is %s\n", str);
#endif
- return(TRUE);
-} /* EncodeTimeOnly() */
+ return (TRUE);
+} /* EncodeTimeOnly() */
/* EncodeDateTime()
* Encode date and time interpreted as local time.
*/
-int EncodeDateTime(struct tm *tm, double fsec, int *tzp, char **tzn, int style, char *str)
+int
+EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, char *str)
{
- int day, hour, min;
- double sec;
+ int day,
+ hour,
+ min;
+ double sec;
- if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
- return -1;
+ if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
+ return -1;
- sec = (tm->tm_sec + fsec);
+ sec = (tm->tm_sec + fsec);
#ifdef DATEDEBUG
#ifdef USE_POSIX_TIME
#ifdef HAVE_INT_TIMEZONE
-printf( "EncodeDateTime- timezone is %s (%s); offset is %d (%d); daylight is %d (%d)\n",
- *tzn, tzname[0], *tzp, CTimeZone, tm->tm_isdst, CDayLight);
+ printf("EncodeDateTime- timezone is %s (%s); offset is %d (%d); daylight is %d (%d)\n",
+ *tzn, tzname[0], *tzp, CTimeZone, tm->tm_isdst, CDayLight);
#else
-printf( "EncodeDateTime- timezone is %s (%s); offset is %ld (%d); daylight is %d (%d)\n",
- *tzn, tm->tm_zone, (- tm->tm_gmtoff), CTimeZone, tm->tm_isdst, CDayLight);
+ printf("EncodeDateTime- timezone is %s (%s); offset is %ld (%d); daylight is %d (%d)\n",
+ *tzn, tm->tm_zone, (-tm->tm_gmtoff), CTimeZone, tm->tm_isdst, CDayLight);
#endif
#else
-printf( "EncodeDateTime- timezone is %s (%s); offset is %d; daylight is %d\n",
- *tzn, CTZName, CTimeZone, CDayLight);
+ printf("EncodeDateTime- timezone is %s (%s); offset is %d; daylight is %d\n",
+ *tzn, CTZName, CTimeZone, CDayLight);
#endif
#endif
- /* compatible with ISO date formats */
- if (style == USE_ISO_DATES) {
- if (tm->tm_year > 0) {
- sprintf( str, "%04d-%02d-%02d %02d:%02d:",
- tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);
- sprintf( (str+17), ((fsec != 0)? "%05.2f": "%02.0f"), sec);
+ /* compatible with ISO date formats */
+ if (style == USE_ISO_DATES)
+ {
+ if (tm->tm_year > 0)
+ {
+ sprintf(str, "%04d-%02d-%02d %02d:%02d:",
+ tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);
+ sprintf((str + 17), ((fsec != 0) ? "%05.2f" : "%02.0f"), sec);
+
+ if ((*tzn != NULL) && (tm->tm_isdst >= 0))
+ {
+ if (tzp != NULL)
+ {
+ hour = -(*tzp / 3600);
+ min = ((abs(*tzp) / 60) % 60);
+ }
+ else
+ {
+ hour = 0;
+ min = 0;
+ }
+ sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
+ }
- if ((*tzn != NULL) && (tm->tm_isdst >= 0)) {
- if (tzp != NULL) {
- hour = -(*tzp / 3600);
- min = ((abs(*tzp) / 60) % 60);
- } else {
- hour = 0;
- min = 0;
}
- sprintf( (str+strlen(str)), ((min != 0)? "%+03d:%02d": "%+03d"), hour, min);
- }
+ else
+ {
+ if (tm->tm_hour || tm->tm_min)
+ {
+ sprintf(str, "%04d-%02d-%02d %02d:%02d %s",
+ -(tm->tm_year - 1), tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, "BC");
+ }
+ else
+ {
+ sprintf(str, "%04d-%02d-%02d %s",
+ -(tm->tm_year - 1), tm->tm_mon, tm->tm_mday, "BC");
+ }
+ }
- } else {
- if (tm->tm_hour || tm->tm_min) {
- sprintf( str, "%04d-%02d-%02d %02d:%02d %s",
- -(tm->tm_year-1), tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, "BC");
- } else {
- sprintf( str, "%04d-%02d-%02d %s",
- -(tm->tm_year-1), tm->tm_mon, tm->tm_mday, "BC");
- }
+ /* compatible with Oracle/Ingres date formats */
}
+ else if (style == USE_SQL_DATES)
+ {
+ if (EuroDates)
+ {
+ sprintf(str, "%02d/%02d", tm->tm_mday, tm->tm_mon);
+ }
+ else
+ {
+ sprintf(str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
+ }
+ if (tm->tm_year > 0)
+ {
+ sprintf((str + 5), "/%04d %02d:%02d:%05.2f",
+ tm->tm_year, tm->tm_hour, tm->tm_min, sec);
- /* compatible with Oracle/Ingres date formats */
- } else if (style == USE_SQL_DATES) {
- if (EuroDates) {
- sprintf( str, "%02d/%02d", tm->tm_mday, tm->tm_mon);
- } else {
- sprintf( str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
- }
- if (tm->tm_year > 0) {
- sprintf( (str+5), "/%04d %02d:%02d:%05.2f",
- tm->tm_year, tm->tm_hour, tm->tm_min, sec);
+ if ((*tzn != NULL) && (tm->tm_isdst >= 0))
+ {
+ strcpy((str + 22), " ");
+ strcpy((str + 23), *tzn);
+ }
- if ((*tzn != NULL) && (tm->tm_isdst >= 0)) {
- strcpy( (str+22), " ");
- strcpy( (str+23), *tzn);
- }
+ }
+ else
+ {
+ sprintf((str + 5), "/%04d %02d:%02d %s",
+ -(tm->tm_year - 1), tm->tm_hour, tm->tm_min, "BC");
+ }
- } else {
- sprintf( (str+5), "/%04d %02d:%02d %s",
- -(tm->tm_year-1), tm->tm_hour, tm->tm_min, "BC");
+ /* backward-compatible with traditional Postgres abstime dates */
}
-
- /* backward-compatible with traditional Postgres abstime dates */
- } else { /* if (style == USE_POSTGRES_DATES) */
- day = date2j( tm->tm_year, tm->tm_mon, tm->tm_mday);
+ else
+ { /* if (style == USE_POSTGRES_DATES) */
+ day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
#ifdef DATEDEBUG
-printf( "EncodeDateTime- day is %d\n", day);
+ printf("EncodeDateTime- day is %d\n", day);
#endif
- tm->tm_wday = j2day( day);
+ tm->tm_wday = j2day(day);
- strncpy( str, days[tm->tm_wday], 3);
- strcpy( (str+3), " ");
+ strncpy(str, days[tm->tm_wday], 3);
+ strcpy((str + 3), " ");
- if (EuroDates) {
- sprintf( (str+4), "%02d %3s", tm->tm_mday, months[tm->tm_mon-1]);
- } else {
- sprintf( (str+4), "%3s %02d", months[tm->tm_mon-1], tm->tm_mday);
- }
- if (tm->tm_year > 0) {
- sprintf( (str+10), " %02d:%02d", tm->tm_hour, tm->tm_min);
- if (fsec != 0) {
- sprintf( (str+16), ":%05.2f %04d", sec, tm->tm_year);
- if ((*tzn != NULL) && (tm->tm_isdst >= 0)) {
- strcpy( (str+27), " ");
- strcpy( (str+28), *tzn);
+ if (EuroDates)
+ {
+ sprintf((str + 4), "%02d %3s", tm->tm_mday, months[tm->tm_mon - 1]);
}
- } else {
- sprintf( (str+16), ":%02.0f %04d", sec, tm->tm_year);
- if ((*tzn != NULL) && (tm->tm_isdst >= 0)) {
- strcpy( (str+24), " ");
- strcpy( (str+25), *tzn);
+ else
+ {
+ sprintf((str + 4), "%3s %02d", months[tm->tm_mon - 1], tm->tm_mday);
}
- }
+ if (tm->tm_year > 0)
+ {
+ sprintf((str + 10), " %02d:%02d", tm->tm_hour, tm->tm_min);
+ if (fsec != 0)
+ {
+ sprintf((str + 16), ":%05.2f %04d", sec, tm->tm_year);
+ if ((*tzn != NULL) && (tm->tm_isdst >= 0))
+ {
+ strcpy((str + 27), " ");
+ strcpy((str + 28), *tzn);
+ }
+ }
+ else
+ {
+ sprintf((str + 16), ":%02.0f %04d", sec, tm->tm_year);
+ if ((*tzn != NULL) && (tm->tm_isdst >= 0))
+ {
+ strcpy((str + 24), " ");
+ strcpy((str + 25), *tzn);
+ }
+ }
- } else {
- sprintf( (str+10), " %02d:%02d %04d %s",
- tm->tm_hour, tm->tm_min, -(tm->tm_year-1), "BC");
+ }
+ else
+ {
+ sprintf((str + 10), " %02d:%02d %04d %s",
+ tm->tm_hour, tm->tm_min, -(tm->tm_year - 1), "BC");
+ }
}
- }
#ifdef DATEDEBUG
-printf( "EncodeDateTime- date result is %s\n", str);
+ printf("EncodeDateTime- date result is %s\n", str);
#endif
- return(TRUE);
-} /* EncodeDateTime() */
+ return (TRUE);
+} /* EncodeDateTime() */
/* EncodeTimeSpan()
* Interpret time structure as a delta time and convert to string.
*
* Pass a flag to specify the style of string, but only implement
- * the traditional Postgres style for now. - tgl 97/03/27
+ * the traditional Postgres style for now. - tgl 97/03/27
*/
-int EncodeTimeSpan(struct tm *tm, double fsec, int style, char *str)
-{
- int is_before = FALSE;
- int is_nonzero = FALSE;
- char *cp;
-
- strcpy( str, "@");
- cp = str+strlen(str);
-
- if (tm->tm_year != 0) {
- is_nonzero = TRUE;
- is_before |= (tm->tm_year < 0);
- sprintf( cp, " %d year%s", abs(tm->tm_year), ((abs(tm->tm_year) != 1)? "s": ""));
- cp += strlen(cp);
- }
-
- if (tm->tm_mon != 0) {
- is_nonzero = TRUE;
- is_before |= (tm->tm_mon < 0);
- sprintf( cp, " %d mon%s", abs(tm->tm_mon), ((abs(tm->tm_mon) != 1)? "s": ""));
- cp += strlen(cp);
- }
-
- if (tm->tm_mday != 0) {
- is_nonzero = TRUE;
- is_before |= (tm->tm_mday < 0);
- sprintf( cp, " %d day%s", abs(tm->tm_mday), ((abs(tm->tm_mday) != 1)? "s": ""));
- cp += strlen(cp);
- }
-
- if (tm->tm_hour != 0) {
- is_nonzero = TRUE;
- is_before |= (tm->tm_hour < 0);
- sprintf( cp, " %d hour%s", abs(tm->tm_hour), ((abs(tm->tm_hour) != 1)? "s": ""));
- cp += strlen(cp);
- }
-
- if (tm->tm_min != 0) {
- is_nonzero = TRUE;
- is_before |= (tm->tm_min < 0);
- sprintf( cp, " %d min%s", abs(tm->tm_min), ((abs(tm->tm_min) != 1)? "s": ""));
- cp += strlen(cp);
- }
-
- /* fractional seconds? */
- if (fsec != 0) {
- is_nonzero = TRUE;
- fsec += tm->tm_sec;
- is_before |= (fsec < 0);
- sprintf( cp, " %.2f secs", fabs(fsec));
- cp += strlen(cp);
-
- /* otherwise, integer seconds only? */
- } else if (tm->tm_sec != 0) {
- is_nonzero = TRUE;
- is_before |= (tm->tm_sec < 0);
- sprintf( cp, " %d sec%s", abs(tm->tm_sec), ((abs(tm->tm_sec) != 1)? "s": ""));
- cp += strlen(cp);
- }
-
- /* identically zero? then put in a unitless zero... */
- if (! is_nonzero) {
- strcat( cp, " 0");
- cp += strlen(cp);
- }
-
- if (is_before) {
- strcat( cp, " ago");
- cp += strlen(cp);
- }
-
-#ifdef DATEDEBUG
-printf( "EncodeTimeSpan- result is %s\n", str);
-#endif
-
- return 0;
-} /* EncodeTimeSpan() */
+int
+EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str)
+{
+ int is_before = FALSE;
+ int is_nonzero = FALSE;
+ char *cp;
+
+ strcpy(str, "@");
+ cp = str + strlen(str);
+
+ if (tm->tm_year != 0)
+ {
+ is_nonzero = TRUE;
+ is_before |= (tm->tm_year < 0);
+ sprintf(cp, " %d year%s", abs(tm->tm_year), ((abs(tm->tm_year) != 1) ? "s" : ""));
+ cp += strlen(cp);
+ }
+
+ if (tm->tm_mon != 0)
+ {
+ is_nonzero = TRUE;
+ is_before |= (tm->tm_mon < 0);
+ sprintf(cp, " %d mon%s", abs(tm->tm_mon), ((abs(tm->tm_mon) != 1) ? "s" : ""));
+ cp += strlen(cp);
+ }
+
+ if (tm->tm_mday != 0)
+ {
+ is_nonzero = TRUE;
+ is_before |= (tm->tm_mday < 0);
+ sprintf(cp, " %d day%s", abs(tm->tm_mday), ((abs(tm->tm_mday) != 1) ? "s" : ""));
+ cp += strlen(cp);
+ }
+
+ if (tm->tm_hour != 0)
+ {
+ is_nonzero = TRUE;
+ is_before |= (tm->tm_hour < 0);
+ sprintf(cp, " %d hour%s", abs(tm->tm_hour), ((abs(tm->tm_hour) != 1) ? "s" : ""));
+ cp += strlen(cp);
+ }
+
+ if (tm->tm_min != 0)
+ {
+ is_nonzero = TRUE;
+ is_before |= (tm->tm_min < 0);
+ sprintf(cp, " %d min%s", abs(tm->tm_min), ((abs(tm->tm_min) != 1) ? "s" : ""));
+ cp += strlen(cp);
+ }
+
+ /* fractional seconds? */
+ if (fsec != 0)
+ {
+ is_nonzero = TRUE;
+ fsec += tm->tm_sec;
+ is_before |= (fsec < 0);
+ sprintf(cp, " %.2f secs", fabs(fsec));
+ cp += strlen(cp);
+
+ /* otherwise, integer seconds only? */
+ }
+ else if (tm->tm_sec != 0)
+ {
+ is_nonzero = TRUE;
+ is_before |= (tm->tm_sec < 0);
+ sprintf(cp, " %d sec%s", abs(tm->tm_sec), ((abs(tm->tm_sec) != 1) ? "s" : ""));
+ cp += strlen(cp);
+ }
+
+ /* identically zero? then put in a unitless zero... */
+ if (!is_nonzero)
+ {
+ strcat(cp, " 0");
+ cp += strlen(cp);
+ }
+
+ if (is_before)
+ {
+ strcat(cp, " ago");
+ cp += strlen(cp);
+ }
+
+#ifdef DATEDEBUG
+ printf("EncodeTimeSpan- result is %s\n", str);
+#endif
+
+ return 0;
+} /* EncodeTimeSpan() */
#if defined(linux) && defined(PPC)
-int datetime_is_epoch(double j)
+int
+datetime_is_epoch(double j)
{
- static union {
- double epoch;
- unsigned char c[8];
- } u;
+ static union
+ {
+ double epoch;
+ unsigned char c[8];
+ } u;
- u.c[0] = 0x80; /* sign bit */
- u.c[1] = 0x10; /* DBL_MIN */
+ u.c[0] = 0x80; /* sign bit */
+ u.c[1] = 0x10; /* DBL_MIN */
- return(j == u.epoch);
+ return (j == u.epoch);
}
-int datetime_is_current(double j)
+int
+datetime_is_current(double j)
{
- static union {
- double current;
- unsigned char c[8];
- } u;
+ static union
+ {
+ double current;
+ unsigned char c[8];
+ } u;
- u.c[1] = 0x10; /* DBL_MIN */
+ u.c[1] = 0x10; /* DBL_MIN */
- return(j == u.current);
+ return (j == u.current);
}
+
#endif
diff --git a/src/backend/utils/adt/filename.c b/src/backend/utils/adt/filename.c
index a14b8283b59..445de98a77a 100644
--- a/src/backend/utils/adt/filename.c
+++ b/src/backend/utils/adt/filename.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* filename.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/filename.c,v 1.8 1997/08/12 20:15:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/filename.c,v 1.9 1997/09/07 04:50:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,95 +20,118 @@
#include "postgres.h"
#include <miscadmin.h>
-#include "utils/builtins.h" /* where function declarations go */
+#include "utils/builtins.h" /* where function declarations go */
-char *
+char *
filename_in(char *file)
{
- char *str;
- int ind = 0;
-
- /*
- * XXX - HACK CITY --- REDO
- * should let the shell do expansions (shexpand)
- */
+ char *str;
+ int ind = 0;
- str = (char *) palloc(MAXPATHLEN * sizeof(*str));
- str[0] = '\0';
- if (file[0] == '~') {
- if (file[1] == '\0' || file[1] == '/') {
- /* Home directory */
-
- char *userName;
- struct passwd *pw;
-
- userName = GetPgUserName();
-
- if ((pw = getpwnam(userName)) == NULL) {
- elog(WARN, "User %s is not a Unix user on the db server.",
- userName);
- }
-
- strcpy(str, pw->pw_dir);
-
- ind = 1;
- } else {
- /* Someone else's directory */
- char name[16], *p;
- struct passwd *pw;
- int len;
-
- if ((p = (char *) strchr(file, '/')) == NULL) {
- strcpy(name, file+1);
- len = strlen(name);
- } else {
- len = (p - file) - 1;
- strNcpy(name, file+1, len);
- }
- /*printf("name: %s\n");*/
- if ((pw = getpwnam(name)) == NULL) {
- elog(WARN, "No such user: %s\n", name);
- ind = 0;
- } else {
- strcpy(str, pw->pw_dir);
- ind = len + 1;
- }
- }
- } else if (file[0] == '$') { /* $POSTGRESHOME, etc. expand it. */
- char environment[80], *envirp, *p;
- int len;
-
- if ((p = (char *) strchr(file, '/')) == NULL) {
- strcpy(environment, file+1);
- len = strlen(environment);
- } else {
- len = (p - file) - 1;
- strNcpy(environment, file+1, len);
+ /*
+ * XXX - HACK CITY --- REDO should let the shell do expansions
+ * (shexpand)
+ */
+
+ str = (char *) palloc(MAXPATHLEN * sizeof(*str));
+ str[0] = '\0';
+ if (file[0] == '~')
+ {
+ if (file[1] == '\0' || file[1] == '/')
+ {
+ /* Home directory */
+
+ char *userName;
+ struct passwd *pw;
+
+ userName = GetPgUserName();
+
+ if ((pw = getpwnam(userName)) == NULL)
+ {
+ elog(WARN, "User %s is not a Unix user on the db server.",
+ userName);
+ }
+
+ strcpy(str, pw->pw_dir);
+
+ ind = 1;
+ }
+ else
+ {
+ /* Someone else's directory */
+ char name[16],
+ *p;
+ struct passwd *pw;
+ int len;
+
+ if ((p = (char *) strchr(file, '/')) == NULL)
+ {
+ strcpy(name, file + 1);
+ len = strlen(name);
+ }
+ else
+ {
+ len = (p - file) - 1;
+ strNcpy(name, file + 1, len);
+ }
+ /* printf("name: %s\n"); */
+ if ((pw = getpwnam(name)) == NULL)
+ {
+ elog(WARN, "No such user: %s\n", name);
+ ind = 0;
+ }
+ else
+ {
+ strcpy(str, pw->pw_dir);
+ ind = len + 1;
+ }
+ }
}
- envirp = getenv(environment);
- if (envirp) {
- strcpy(str, envirp);
- ind = len + 1;
+ else if (file[0] == '$')
+ { /* $POSTGRESHOME, etc. expand it. */
+ char environment[80],
+ *envirp,
+ *p;
+ int len;
+
+ if ((p = (char *) strchr(file, '/')) == NULL)
+ {
+ strcpy(environment, file + 1);
+ len = strlen(environment);
+ }
+ else
+ {
+ len = (p - file) - 1;
+ strNcpy(environment, file + 1, len);
+ }
+ envirp = getenv(environment);
+ if (envirp)
+ {
+ strcpy(str, envirp);
+ ind = len + 1;
+ }
+ else
+ {
+ elog(WARN, "Couldn't find %s in your environment", environment);
+ }
}
- else {
- elog(WARN,"Couldn't find %s in your environment", environment);
+ else
+ {
+ ind = 0;
}
- } else {
- ind = 0;
- }
- strcat(str, file+ind);
- return(str);
+ strcat(str, file + ind);
+ return (str);
}
-char *
+char *
filename_out(char *s)
{
- char *ret;
-
- if (!s)
- return((char *) NULL);
- ret = (char *) palloc(strlen(s) + 1);
- if (!ret)
- elog(WARN, "filename_out: palloc failed");
- return(strcpy(ret, s));
+ char *ret;
+
+ if (!s)
+ return ((char *) NULL);
+ ret = (char *) palloc(strlen(s) + 1);
+ if (!ret)
+ elog(WARN, "filename_out: palloc failed");
+ return (strcpy(ret, s));
}
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 3518fd7d4cc..32d78fb2ba7 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -1,66 +1,66 @@
/*-------------------------------------------------------------------------
*
* float.c--
- * Functions for the built-in floating-point types.
+ * Functions for the built-in floating-point types.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.17 1997/07/28 00:55:49 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.18 1997/09/07 04:50:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* OLD COMMENTS
- * Basic float4 ops:
- * float4in, float4out, float4abs, float4um
- * Basic float8 ops:
- * float8in, float8inAd, float8out, float8outAd, float8abs, float8um
- * Arithmetic operators:
- * float4pl, float4mi, float4mul, float4div
- * float8pl, float8mi, float8mul, float8div
- * Comparison operators:
- * float4eq, float4ne, float4lt, float4le, float4gt, float4ge
- * float8eq, float8ne, float8lt, float8le, float8gt, float8ge
- * Conversion routines:
- * ftod, dtof, i4tod, dtoi4, i2tod, dtoi2, itof, ftoi, i2tof, ftoi2
+ * Basic float4 ops:
+ * float4in, float4out, float4abs, float4um
+ * Basic float8 ops:
+ * float8in, float8inAd, float8out, float8outAd, float8abs, float8um
+ * Arithmetic operators:
+ * float4pl, float4mi, float4mul, float4div
+ * float8pl, float8mi, float8mul, float8div
+ * Comparison operators:
+ * float4eq, float4ne, float4lt, float4le, float4gt, float4ge
+ * float8eq, float8ne, float8lt, float8le, float8gt, float8ge
+ * Conversion routines:
+ * ftod, dtof, i4tod, dtoi4, i2tod, dtoi2, itof, ftoi, i2tof, ftoi2
*
- * Random float8 ops:
- * dround, dtrunc, dsqrt, dcbrt, dpow, dexp, dlog1
- * Arithmetic operators:
- * float48pl, float48mi, float48mul, float48div
- * float84pl, float84mi, float84mul, float84div
- * Comparison operators:
- * float48eq, float48ne, float48lt, float48le, float48gt, float48ge
- * float84eq, float84ne, float84lt, float84le, float84gt, float84ge
+ * Random float8 ops:
+ * dround, dtrunc, dsqrt, dcbrt, dpow, dexp, dlog1
+ * Arithmetic operators:
+ * float48pl, float48mi, float48mul, float48div
+ * float84pl, float84mi, float84mul, float84div
+ * Comparison operators:
+ * float48eq, float48ne, float48lt, float48le, float48gt, float48ge
+ * float84eq, float84ne, float84lt, float84le, float84gt, float84ge
*
- * (You can do the arithmetic and comparison stuff using conversion
- * routines, but then you pay the overhead of converting...)
+ * (You can do the arithmetic and comparison stuff using conversion
+ * routines, but then you pay the overhead of converting...)
*
* XXX GLUESOME STUFF. FIX IT! -AY '94
*
- * Added some additional conversion routines and cleaned up
- * a bit of the existing code. Need to change the error checking
- * for calls to pow(), exp() since on some machines (my Linux box
- * included) these routines do not set errno. - tgl 97/05/10
+ * Added some additional conversion routines and cleaned up
+ * a bit of the existing code. Need to change the error checking
+ * for calls to pow(), exp() since on some machines (my Linux box
+ * included) these routines do not set errno. - tgl 97/05/10
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <errno.h>
-#include <float.h> /* faked on sunos4 */
+#include <float.h> /* faked on sunos4 */
#include <math.h>
#include "postgres.h"
#ifdef HAVE_LIMITS_H
-# include <limits.h>
+#include <limits.h>
#endif
#include "fmgr.h"
-#include "utils/builtins.h" /* for ftod() prototype */
+#include "utils/builtins.h" /* for ftod() prototype */
#include "utils/palloc.h"
@@ -71,65 +71,73 @@
#define SHRT_MIN (-32768)
#endif
-#define FORMAT 'g' /* use "g" output format as standard format */
+#define FORMAT 'g' /* use "g" output format as standard
+ * format */
/* not sure what the following should be, but better to make it over-sufficient */
-#define MAXFLOATWIDTH 64
+#define MAXFLOATWIDTH 64
#define MAXDOUBLEWIDTH 128
#if !(NeXT && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_2)
- /* NS3.3 has conflicting declarations of these in <math.h> */
+ /* NS3.3 has conflicting declarations of these in <math.h> */
#ifndef atof
extern double atof(const char *p);
+
#endif
#ifndef HAVE_CBRT
-# define cbrt my_cbrt
- static double cbrt(double x);
-#else
-# if !defined(nextstep)
- extern double cbrt(double x);
-# endif
-#endif
+#define cbrt my_cbrt
+static double cbrt(double x);
+
+#else
+#if !defined(nextstep)
+extern double cbrt(double x);
+
+#endif
+#endif
#ifndef HAVE_RINT
-# define rint my_rint
- static double rint(double x);
-#else
- extern double rint(double x);
-#endif
+#define rint my_rint
+static double rint(double x);
+
+#else
+extern double rint(double x);
+
+#endif
#ifndef HAVE_ISINF
-# define isinf my_isinf
- static int isinf(double x);
-#else
- extern int isinf(double x);
-#endif
+#define isinf my_isinf
+static int isinf(double x);
+
+#else
+extern int isinf(double x);
-#endif
+#endif
+
+#endif
/* ========== USER I/O ROUTINES ========== */
-
-
-#define FLOAT4_MAX FLT_MAX
-#define FLOAT4_MIN FLT_MIN
-#define FLOAT8_MAX DBL_MAX
-#define FLOAT8_MIN DBL_MIN
-
-/*
+
+
+#define FLOAT4_MAX FLT_MAX
+#define FLOAT4_MIN FLT_MIN
+#define FLOAT8_MAX DBL_MAX
+#define FLOAT8_MIN DBL_MIN
+
+/*
* if FLOAT8_MIN and FLOAT8_MAX are the limits of the range a
* double can store, then how are we ever going to wind up
* with something stored in a double that is outside those
- * limits? (and similarly for FLOAT4_{MIN,MAX}/float.)
+ * limits? (and similarly for FLOAT4_{MIN,MAX}/float.)
* doesn't make sense to me, and it causes a
* floating point exception on linuxalpha, so UNSAFE_FLOATS
* it is.
* (maybe someone wanted to allow for values other than DBL_MIN/
* DBL_MAX for FLOAT8_MIN/FLOAT8_MAX?)
- * --djm 12/12/96
- * according to Richard Henderson this is a known bug in gcc on
- * the Alpha. might as well leave the workaround in
+ * --djm 12/12/96
+ * according to Richard Henderson this is a known bug in gcc on
+ * the Alpha. might as well leave the workaround in
* until the distributions are updated.
- * --djm 12/16/96
+ * --djm 12/16/96
*/
#if defined(linuxalpha) && !defined(UNSAFE_FLOATS)
#define UNSAFE_FLOATS
@@ -138,1157 +146,1240 @@ extern double atof(const char *p);
/*
check to see if a float4 val is outside of
the FLOAT4_MIN, FLOAT4_MAX bounds.
-
+
raise an elog warning if it is
*/
-static void CheckFloat4Val(double val)
+static void
+CheckFloat4Val(double val)
{
- /* defining unsafe floats's will make float4 and float8 ops faster
- at the cost of safety, of course! */
+
+ /*
+ * defining unsafe floats's will make float4 and float8 ops faster at
+ * the cost of safety, of course!
+ */
#ifdef UNSAFE_FLOATS
- return;
+ return;
#else
- if (fabs(val) > FLOAT4_MAX)
- elog(WARN,"\tBad float4 input format -- overflow\n");
- if (val != 0.0 && fabs(val) < FLOAT4_MIN)
- elog(WARN,"\tBad float4 input format -- underflow\n");
- return;
-#endif /* UNSAFE_FLOATS */
+ if (fabs(val) > FLOAT4_MAX)
+ elog(WARN, "\tBad float4 input format -- overflow\n");
+ if (val != 0.0 && fabs(val) < FLOAT4_MIN)
+ elog(WARN, "\tBad float4 input format -- underflow\n");
+ return;
+#endif /* UNSAFE_FLOATS */
}
/*
check to see if a float8 val is outside of
the FLOAT8_MIN, FLOAT8_MAX bounds.
-
+
raise an elog warning if it is
*/
-void CheckFloat8Val(double val)
+void
+CheckFloat8Val(double val)
{
- /* defining unsafe floats's will make float4 and float8 ops faster
- at the cost of safety, of course! */
+
+ /*
+ * defining unsafe floats's will make float4 and float8 ops faster at
+ * the cost of safety, of course!
+ */
#ifdef UNSAFE_FLOATS
- return;
+ return;
#else
- if (fabs(val) > FLOAT8_MAX)
- elog(WARN,"\tBad float8 input format -- overflow\n");
- if (val != 0.0 && fabs(val) < FLOAT8_MIN)
- elog(WARN,"\tBad float8 input format -- underflow\n");
- return;
-#endif /* UNSAFE_FLOATS */
+ if (fabs(val) > FLOAT8_MAX)
+ elog(WARN, "\tBad float8 input format -- overflow\n");
+ if (val != 0.0 && fabs(val) < FLOAT8_MIN)
+ elog(WARN, "\tBad float8 input format -- underflow\n");
+ return;
+#endif /* UNSAFE_FLOATS */
}
/*
- * float4in - converts "num" to float
- * restricted syntax:
- * {<sp>} [+|-] {digit} [.{digit}] [<exp>]
- * where <sp> is a space, digit is 0-9,
- * <exp> is "e" or "E" followed by an integer.
+ * float4in - converts "num" to float
+ * restricted syntax:
+ * {<sp>} [+|-] {digit} [.{digit}] [<exp>]
+ * where <sp> is a space, digit is 0-9,
+ * <exp> is "e" or "E" followed by an integer.
*/
-float32 float4in(char *num)
-{
- float32 result = (float32) palloc(sizeof(float32data));
- double val;
- char* endptr;
-
- errno = 0;
- val = strtod(num,&endptr);
- if (*endptr != '\0' || errno == ERANGE)
- elog(WARN,"\tBad float4 input format\n");
-
- /* if we get here, we have a legal double, still need to check to see
- if it's a legal float */
-
- CheckFloat4Val(val);
-
- *result = val;
- return result;
+float32
+float4in(char *num)
+{
+ float32 result = (float32) palloc(sizeof(float32data));
+ double val;
+ char *endptr;
+
+ errno = 0;
+ val = strtod(num, &endptr);
+ if (*endptr != '\0' || errno == ERANGE)
+ elog(WARN, "\tBad float4 input format\n");
+
+ /*
+ * if we get here, we have a legal double, still need to check to see
+ * if it's a legal float
+ */
+
+ CheckFloat4Val(val);
+
+ *result = val;
+ return result;
}
/*
- * float4out - converts a float4 number to a string
- * using a standard output format
+ * float4out - converts a float4 number to a string
+ * using a standard output format
*/
-char *float4out(float32 num)
+char *
+float4out(float32 num)
{
- char *ascii = (char *)palloc(MAXFLOATWIDTH+1);
-
- if (!num)
- return strcpy(ascii, "(null)");
-
- sprintf(ascii, "%.*g", FLT_DIG, *num);
- return(ascii);
+ char *ascii = (char *) palloc(MAXFLOATWIDTH + 1);
+
+ if (!num)
+ return strcpy(ascii, "(null)");
+
+ sprintf(ascii, "%.*g", FLT_DIG, *num);
+ return (ascii);
}
/*
- * float8in - converts "num" to float8
- * restricted syntax:
- * {<sp>} [+|-] {digit} [.{digit}] [<exp>]
- * where <sp> is a space, digit is 0-9,
- * <exp> is "e" or "E" followed by an integer.
+ * float8in - converts "num" to float8
+ * restricted syntax:
+ * {<sp>} [+|-] {digit} [.{digit}] [<exp>]
+ * where <sp> is a space, digit is 0-9,
+ * <exp> is "e" or "E" followed by an integer.
*/
-float64 float8in(char *num)
+float64
+float8in(char *num)
{
- float64 result = (float64) palloc(sizeof(float64data));
- double val;
- char* endptr;
-
- errno = 0;
- val = strtod(num,&endptr);
- if (*endptr != '\0' || errno == ERANGE)
- elog(WARN,"\tBad float8 input format\n");
-
- CheckFloat8Val(val);
- *result = val;
- return(result);
+ float64 result = (float64) palloc(sizeof(float64data));
+ double val;
+ char *endptr;
+
+ errno = 0;
+ val = strtod(num, &endptr);
+ if (*endptr != '\0' || errno == ERANGE)
+ elog(WARN, "\tBad float8 input format\n");
+
+ CheckFloat8Val(val);
+ *result = val;
+ return (result);
}
/*
- * float8out - converts float8 number to a string
- * using a standard output format
+ * float8out - converts float8 number to a string
+ * using a standard output format
*/
-char *float8out(float64 num)
+char *
+float8out(float64 num)
{
- char *ascii = (char *)palloc(MAXDOUBLEWIDTH+1);
-
- if (!num)
- return strcpy(ascii, "(null)");
+ char *ascii = (char *) palloc(MAXDOUBLEWIDTH + 1);
+
+ if (!num)
+ return strcpy(ascii, "(null)");
- if (isnan(*num))
- return strcpy(ascii, "NaN");
- if (isinf(*num))
- return strcpy(ascii, "Infinity");
+ if (isnan(*num))
+ return strcpy(ascii, "NaN");
+ if (isinf(*num))
+ return strcpy(ascii, "Infinity");
- sprintf(ascii, "%.*g", DBL_DIG, *num);
- return(ascii);
+ sprintf(ascii, "%.*g", DBL_DIG, *num);
+ return (ascii);
}
/* ========== PUBLIC ROUTINES ========== */
/*
- * ======================
- * FLOAT4 BASE OPERATIONS
- * ======================
+ * ======================
+ * FLOAT4 BASE OPERATIONS
+ * ======================
*/
/*
- * float4abs - returns a pointer to |arg1| (absolute value)
+ * float4abs - returns a pointer to |arg1| (absolute value)
*/
-float32 float4abs(float32 arg1)
+float32
+float4abs(float32 arg1)
{
- float32 result;
- double val;
-
- if (!arg1)
- return (float32)NULL;
-
- val = fabs(*arg1);
+ float32 result;
+ double val;
- CheckFloat4Val(val);
+ if (!arg1)
+ return (float32) NULL;
- result = (float32) palloc(sizeof(float32data));
- *result = val;
- return(result);
+ val = fabs(*arg1);
+
+ CheckFloat4Val(val);
+
+ result = (float32) palloc(sizeof(float32data));
+ *result = val;
+ return (result);
}
/*
- * float4um - returns a pointer to -arg1 (unary minus)
+ * float4um - returns a pointer to -arg1 (unary minus)
*/
-float32 float4um(float32 arg1)
+float32
+float4um(float32 arg1)
{
- float32 result;
- double val;
-
- if (!arg1)
- return (float32)NULL;
-
- val = ((*arg1 != 0) ? -(*arg1): *arg1);
- CheckFloat4Val(val);
+ float32 result;
+ double val;
+
+ if (!arg1)
+ return (float32) NULL;
+
+ val = ((*arg1 != 0) ? -(*arg1) : *arg1);
+ CheckFloat4Val(val);
- result = (float32) palloc(sizeof(float32data));
- *result = val;
- return(result);
+ result = (float32) palloc(sizeof(float32data));
+ *result = val;
+ return (result);
}
-float32 float4larger(float32 arg1, float32 arg2)
+float32
+float4larger(float32 arg1, float32 arg2)
{
- float32 result;
-
- if (!arg1 || !arg2)
- return (float32)NULL;
-
- result = (float32) palloc(sizeof(float32data));
-
- *result = ((*arg1 > *arg2) ? *arg1 : *arg2);
- return result;
+ float32 result;
+
+ if (!arg1 || !arg2)
+ return (float32) NULL;
+
+ result = (float32) palloc(sizeof(float32data));
+
+ *result = ((*arg1 > *arg2) ? *arg1 : *arg2);
+ return result;
}
-float32 float4smaller(float32 arg1, float32 arg2)
+float32
+float4smaller(float32 arg1, float32 arg2)
{
- float32 result;
-
- if (!arg1 || !arg2)
- return (float32)NULL;
-
- result = (float32) palloc(sizeof(float32data));
-
- *result = ((*arg1 > *arg2) ? *arg2 : *arg1);
- return result;
+ float32 result;
+
+ if (!arg1 || !arg2)
+ return (float32) NULL;
+
+ result = (float32) palloc(sizeof(float32data));
+
+ *result = ((*arg1 > *arg2) ? *arg2 : *arg1);
+ return result;
}
/*
- * ======================
- * FLOAT8 BASE OPERATIONS
- * ======================
+ * ======================
+ * FLOAT8 BASE OPERATIONS
+ * ======================
*/
/*
- * float8abs - returns a pointer to |arg1| (absolute value)
+ * float8abs - returns a pointer to |arg1| (absolute value)
*/
-float64 float8abs(float64 arg1)
+float64
+float8abs(float64 arg1)
{
- float64 result;
- double val;
-
- if (!arg1)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- val = fabs(*arg1);
- CheckFloat8Val(val);
- *result = val;
- return(result);
+ float64 result;
+ double val;
+
+ if (!arg1)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ val = fabs(*arg1);
+ CheckFloat8Val(val);
+ *result = val;
+ return (result);
}
/*
- * float8um - returns a pointer to -arg1 (unary minus)
+ * float8um - returns a pointer to -arg1 (unary minus)
*/
-float64 float8um(float64 arg1)
+float64
+float8um(float64 arg1)
{
- float64 result;
- double val;
+ float64 result;
+ double val;
+
+ if (!arg1)
+ return (float64) NULL;
+
+ val = ((*arg1 != 0) ? -(*arg1) : *arg1);
- if (!arg1)
- return (float64)NULL;
-
- val = ((*arg1 != 0)? -(*arg1): *arg1);
-
- CheckFloat8Val(val);
- result = (float64) palloc(sizeof(float64data));
- *result = val;
- return(result);
+ CheckFloat8Val(val);
+ result = (float64) palloc(sizeof(float64data));
+ *result = val;
+ return (result);
}
-float64 float8larger(float64 arg1, float64 arg2)
+float64
+float8larger(float64 arg1, float64 arg2)
{
- float64 result;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- *result = ((*arg1 > *arg2) ? *arg1 : *arg2);
- return result;
+ float64 result;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ *result = ((*arg1 > *arg2) ? *arg1 : *arg2);
+ return result;
}
-float64 float8smaller(float64 arg1, float64 arg2)
+float64
+float8smaller(float64 arg1, float64 arg2)
{
- float64 result;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- *result = ((*arg1 > *arg2) ? *arg2 : *arg1);
- return result;
+ float64 result;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ *result = ((*arg1 > *arg2) ? *arg2 : *arg1);
+ return result;
}
/*
- * ====================
- * ARITHMETIC OPERATORS
- * ====================
+ * ====================
+ * ARITHMETIC OPERATORS
+ * ====================
*/
/*
- * float4pl - returns a pointer to arg1 + arg2
- * float4mi - returns a pointer to arg1 - arg2
- * float4mul - returns a pointer to arg1 * arg2
- * float4div - returns a pointer to arg1 / arg2
- * float4inc - returns a poniter to arg1 + 1.0
+ * float4pl - returns a pointer to arg1 + arg2
+ * float4mi - returns a pointer to arg1 - arg2
+ * float4mul - returns a pointer to arg1 * arg2
+ * float4div - returns a pointer to arg1 / arg2
+ * float4inc - returns a poniter to arg1 + 1.0
*/
-float32 float4pl(float32 arg1, float32 arg2)
+float32
+float4pl(float32 arg1, float32 arg2)
{
- float32 result;
- double val;
-
- if (!arg1 || !arg2)
- return (float32)NULL;
-
- val = *arg1 + *arg2;
- CheckFloat4Val(val);
+ float32 result;
+ double val;
+
+ if (!arg1 || !arg2)
+ return (float32) NULL;
- result = (float32) palloc(sizeof(float32data));
- *result = val;
+ val = *arg1 + *arg2;
+ CheckFloat4Val(val);
- return(result);
+ result = (float32) palloc(sizeof(float32data));
+ *result = val;
+
+ return (result);
}
-float32 float4mi(float32 arg1, float32 arg2)
+float32
+float4mi(float32 arg1, float32 arg2)
{
- float32 result;
- double val;
-
- if (!arg1 || !arg2)
- return (float32)NULL;
-
- val = *arg1 - *arg2;
+ float32 result;
+ double val;
+
+ if (!arg1 || !arg2)
+ return (float32) NULL;
+
+ val = *arg1 - *arg2;
- CheckFloat4Val(val);
- result = (float32) palloc(sizeof(float32data));
- *result = val;
- return(result);
+ CheckFloat4Val(val);
+ result = (float32) palloc(sizeof(float32data));
+ *result = val;
+ return (result);
}
-float32 float4mul(float32 arg1, float32 arg2)
+float32
+float4mul(float32 arg1, float32 arg2)
{
- float32 result;
- double val;
-
- if (!arg1 || !arg2)
- return (float32)NULL;
-
- val = *arg1 * *arg2;
+ float32 result;
+ double val;
- CheckFloat4Val(val);
- result = (float32) palloc(sizeof(float32data));
- *result = val;
- return(result);
+ if (!arg1 || !arg2)
+ return (float32) NULL;
+
+ val = *arg1 * *arg2;
+
+ CheckFloat4Val(val);
+ result = (float32) palloc(sizeof(float32data));
+ *result = val;
+ return (result);
}
-float32 float4div(float32 arg1, float32 arg2)
+float32
+float4div(float32 arg1, float32 arg2)
{
- float32 result;
- double val;
-
- if (!arg1 || !arg2)
- return (float32)NULL;
-
- if (*arg2 == 0.0)
- elog(WARN,"float4div: divide by 0.0 error");
+ float32 result;
+ double val;
+
+ if (!arg1 || !arg2)
+ return (float32) NULL;
+
+ if (*arg2 == 0.0)
+ elog(WARN, "float4div: divide by 0.0 error");
- val = *arg1 / *arg2;
-
- CheckFloat4Val(val);
- result = (float32) palloc(sizeof(float32data));
- *result = *arg1 / *arg2;
- return(result);
+ val = *arg1 / *arg2;
+
+ CheckFloat4Val(val);
+ result = (float32) palloc(sizeof(float32data));
+ *result = *arg1 / *arg2;
+ return (result);
}
-float32 float4inc(float32 arg1)
+float32
+float4inc(float32 arg1)
{
- double val;
+ double val;
+
+ if (!arg1)
+ return (float32) NULL;
- if (!arg1)
- return (float32)NULL;
-
- val = *arg1 + (float32data)1.0;
- CheckFloat4Val(val);
- *arg1 = val;
- return arg1;
+ val = *arg1 + (float32data) 1.0;
+ CheckFloat4Val(val);
+ *arg1 = val;
+ return arg1;
}
/*
- * float8pl - returns a pointer to arg1 + arg2
- * float8mi - returns a pointer to arg1 - arg2
- * float8mul - returns a pointer to arg1 * arg2
- * float8div - returns a pointer to arg1 / arg2
- * float8inc - returns a pointer to arg1 + 1.0
+ * float8pl - returns a pointer to arg1 + arg2
+ * float8mi - returns a pointer to arg1 - arg2
+ * float8mul - returns a pointer to arg1 * arg2
+ * float8div - returns a pointer to arg1 / arg2
+ * float8inc - returns a pointer to arg1 + 1.0
*/
-float64 float8pl(float64 arg1, float64 arg2)
-{
- float64 result;
- double val;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- val = *arg1 + *arg2;
- CheckFloat8Val(val);
- *result = val;
- return(result);
-}
-
-float64 float8mi(float64 arg1, float64 arg2)
-{
- float64 result;
- double val;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- val = *arg1 - *arg2;
- CheckFloat8Val(val);
- *result = val;
- return(result);
-}
-
-float64 float8mul(float64 arg1, float64 arg2)
-{
- float64 result;
- double val;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- val = *arg1 * *arg2;
- CheckFloat8Val(val);
- *result = val;
- return(result);
-}
-
-float64 float8div(float64 arg1, float64 arg2)
-{
- float64 result;
- double val;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- if (*arg2 == 0.0)
- elog(WARN,"float8div: divide by 0.0 error");
-
- val = *arg1 / *arg2;
- CheckFloat8Val(val);
- *result = val;
- return(result);
-}
-
-float64 float8inc(float64 arg1)
-{
- double val;
- if (!arg1)
- return (float64)NULL;
-
- val = *arg1 + (float64data)1.0;
- CheckFloat8Val(val);
- *arg1 = val;
- return(arg1);
+float64
+float8pl(float64 arg1, float64 arg2)
+{
+ float64 result;
+ double val;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ val = *arg1 + *arg2;
+ CheckFloat8Val(val);
+ *result = val;
+ return (result);
+}
+
+float64
+float8mi(float64 arg1, float64 arg2)
+{
+ float64 result;
+ double val;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ val = *arg1 - *arg2;
+ CheckFloat8Val(val);
+ *result = val;
+ return (result);
+}
+
+float64
+float8mul(float64 arg1, float64 arg2)
+{
+ float64 result;
+ double val;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ val = *arg1 * *arg2;
+ CheckFloat8Val(val);
+ *result = val;
+ return (result);
+}
+
+float64
+float8div(float64 arg1, float64 arg2)
+{
+ float64 result;
+ double val;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ if (*arg2 == 0.0)
+ elog(WARN, "float8div: divide by 0.0 error");
+
+ val = *arg1 / *arg2;
+ CheckFloat8Val(val);
+ *result = val;
+ return (result);
+}
+
+float64
+float8inc(float64 arg1)
+{
+ double val;
+
+ if (!arg1)
+ return (float64) NULL;
+
+ val = *arg1 + (float64data) 1.0;
+ CheckFloat8Val(val);
+ *arg1 = val;
+ return (arg1);
}
/*
- * ====================
- * COMPARISON OPERATORS
- * ====================
+ * ====================
+ * COMPARISON OPERATORS
+ * ====================
*/
/*
- * float4{eq,ne,lt,le,gt,ge} - float4/float4 comparison operations
+ * float4{eq,ne,lt,le,gt,ge} - float4/float4 comparison operations
*/
-bool float4eq(float32 arg1, float32 arg2)
+bool
+float4eq(float32 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
+ if (!arg1 || !arg2)
+ return 0;
- return(*arg1 == *arg2);
+ return (*arg1 == *arg2);
}
-bool float4ne(float32 arg1, float32 arg2)
+bool
+float4ne(float32 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 != *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 != *arg2);
}
-bool float4lt(float32 arg1, float32 arg2)
+bool
+float4lt(float32 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 < *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 < *arg2);
}
-bool float4le(float32 arg1, float32 arg2)
+bool
+float4le(float32 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 <= *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 <= *arg2);
}
-bool float4gt(float32 arg1, float32 arg2)
+bool
+float4gt(float32 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 > *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 > *arg2);
}
-bool float4ge(float32 arg1, float32 arg2)
+bool
+float4ge(float32 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 >= *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 >= *arg2);
}
/*
- * float8{eq,ne,lt,le,gt,ge} - float8/float8 comparison operations
+ * float8{eq,ne,lt,le,gt,ge} - float8/float8 comparison operations
*/
-bool float8eq(float64 arg1, float64 arg2)
+bool
+float8eq(float64 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 == *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 == *arg2);
}
-bool float8ne(float64 arg1, float64 arg2)
+bool
+float8ne(float64 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 != *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 != *arg2);
}
-bool float8lt(float64 arg1, float64 arg2)
+bool
+float8lt(float64 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 < *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 < *arg2);
}
-bool float8le(float64 arg1, float64 arg2)
+bool
+float8le(float64 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 <= *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 <= *arg2);
}
-bool float8gt(float64 arg1, float64 arg2)
+bool
+float8gt(float64 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 > *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 > *arg2);
}
-bool float8ge(float64 arg1, float64 arg2)
+bool
+float8ge(float64 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 >= *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 >= *arg2);
}
/*
- * ===================
- * CONVERSION ROUTINES
- * ===================
+ * ===================
+ * CONVERSION ROUTINES
+ * ===================
*/
/*
- * ftod - converts a float4 number to a float8 number
+ * ftod - converts a float4 number to a float8 number
*/
-float64 ftod(float32 num)
+float64
+ftod(float32 num)
{
- float64 result;
-
- if (!num)
- return (float64)NULL;
+ float64 result;
+
+ if (!num)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
- result = (float64) palloc(sizeof(float64data));
-
- *result = *num;
- return(result);
+ *result = *num;
+ return (result);
}
/*
- * dtof - converts a float8 number to a float4 number
+ * dtof - converts a float8 number to a float4 number
*/
-float32 dtof(float64 num)
+float32
+dtof(float64 num)
{
- float32 result;
-
- if (!num)
- return (float32)NULL;
+ float32 result;
- CheckFloat4Val(*num);
+ if (!num)
+ return (float32) NULL;
- result = (float32) palloc(sizeof(float32data));
+ CheckFloat4Val(*num);
- *result = *num;
- return(result);
+ result = (float32) palloc(sizeof(float32data));
+
+ *result = *num;
+ return (result);
}
/*
- * dtoi4 - converts a float8 number to an int4 number
+ * dtoi4 - converts a float8 number to an int4 number
*/
-int32 dtoi4(float64 num)
+int32
+dtoi4(float64 num)
{
- int32 result;
-
- if (!num)
- elog(WARN,"dtoi4: unable to convert null",NULL);
+ int32 result;
+
+ if (!num)
+ elog(WARN, "dtoi4: unable to convert null", NULL);
- if ((*num < INT_MIN) || (*num > INT_MAX))
- elog(WARN,"dtoi4: integer out of range",NULL);
+ if ((*num < INT_MIN) || (*num > INT_MAX))
+ elog(WARN, "dtoi4: integer out of range", NULL);
- result = rint(*num);
- return(result);
+ result = rint(*num);
+ return (result);
}
/*
- * dtoi2 - converts a float8 number to an int2 number
+ * dtoi2 - converts a float8 number to an int2 number
*/
-int16 dtoi2(float64 num)
+int16
+dtoi2(float64 num)
{
- int16 result;
-
- if (!num)
- elog(WARN,"dtoi2: unable to convert null",NULL);
+ int16 result;
+
+ if (!num)
+ elog(WARN, "dtoi2: unable to convert null", NULL);
- if ((*num < SHRT_MIN) || (*num > SHRT_MAX))
- elog(WARN,"dtoi2: integer out of range",NULL);
+ if ((*num < SHRT_MIN) || (*num > SHRT_MAX))
+ elog(WARN, "dtoi2: integer out of range", NULL);
- result = rint(*num);
- return(result);
+ result = rint(*num);
+ return (result);
}
/*
- * i4tod - converts an int4 number to a float8 number
+ * i4tod - converts an int4 number to a float8 number
*/
-float64 i4tod(int32 num)
+float64
+i4tod(int32 num)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
-
- *result = num;
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ *result = num;
+ return (result);
}
/*
- * i2tod - converts an int2 number to a float8 number
+ * i2tod - converts an int2 number to a float8 number
*/
-float64 i2tod(int16 num)
+float64
+i2tod(int16 num)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
-
- *result = num;
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ *result = num;
+ return (result);
}
/*
- * ftoi4 - converts a float8 number to an int4 number
+ * ftoi4 - converts a float8 number to an int4 number
*/
-int32 ftoi4(float32 num)
+int32
+ftoi4(float32 num)
{
- int32 result;
-
- if (!num)
- elog(WARN,"ftoi4: unable to convert null",NULL);
+ int32 result;
- if ((*num < INT_MIN) || (*num > INT_MAX))
- elog(WARN,"ftoi4: integer out of range",NULL);
+ if (!num)
+ elog(WARN, "ftoi4: unable to convert null", NULL);
- result = rint(*num);
- return(result);
+ if ((*num < INT_MIN) || (*num > INT_MAX))
+ elog(WARN, "ftoi4: integer out of range", NULL);
+
+ result = rint(*num);
+ return (result);
}
/*
- * ftoi2 - converts a float8 number to an int2 number
+ * ftoi2 - converts a float8 number to an int2 number
*/
-int16 ftoi2(float32 num)
+int16
+ftoi2(float32 num)
{
- int16 result;
-
- if (!num)
- elog(WARN,"ftoi2: unable to convert null",NULL);
+ int16 result;
+
+ if (!num)
+ elog(WARN, "ftoi2: unable to convert null", NULL);
- if ((*num < SHRT_MIN) || (*num > SHRT_MAX))
- elog(WARN,"ftoi2: integer out of range",NULL);
+ if ((*num < SHRT_MIN) || (*num > SHRT_MAX))
+ elog(WARN, "ftoi2: integer out of range", NULL);
- result = rint(*num);
- return(result);
+ result = rint(*num);
+ return (result);
}
/*
- * i4tof - converts an int4 number to a float8 number
+ * i4tof - converts an int4 number to a float8 number
*/
-float32 i4tof(int32 num)
+float32
+i4tof(int32 num)
{
- float32 result;
-
- result = (float32) palloc(sizeof(float32data));
-
- *result = num;
- return(result);
+ float32 result;
+
+ result = (float32) palloc(sizeof(float32data));
+
+ *result = num;
+ return (result);
}
/*
- * i2tof - converts an int2 number to a float8 number
+ * i2tof - converts an int2 number to a float8 number
*/
-float32 i2tof(int16 num)
+float32
+i2tof(int16 num)
{
- float32 result;
-
- result = (float32) palloc(sizeof(float32data));
-
- *result = num;
- return(result);
+ float32 result;
+
+ result = (float32) palloc(sizeof(float32data));
+
+ *result = num;
+ return (result);
}
/*
- * =======================
- * RANDOM FLOAT8 OPERATORS
- * =======================
+ * =======================
+ * RANDOM FLOAT8 OPERATORS
+ * =======================
*/
/*
- * dround - returns a pointer to ROUND(arg1)
+ * dround - returns a pointer to ROUND(arg1)
*/
-float64 dround(float64 arg1)
+float64
+dround(float64 arg1)
{
- float64 result;
- double tmp;
-
- if (!arg1)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- tmp = *arg1;
- *result = (float64data) rint(tmp);
- return(result);
+ float64 result;
+ double tmp;
+
+ if (!arg1)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ tmp = *arg1;
+ *result = (float64data) rint(tmp);
+ return (result);
}
/*
- * dtrunc - returns a pointer to truncation of arg1,
- * arg1 >= 0 ... the greatest integer as float8 less
- * than or equal to arg1
- * arg1 < 0 ... the greatest integer as float8 greater
- * than or equal to arg1
+ * dtrunc - returns a pointer to truncation of arg1,
+ * arg1 >= 0 ... the greatest integer as float8 less
+ * than or equal to arg1
+ * arg1 < 0 ... the greatest integer as float8 greater
+ * than or equal to arg1
*/
-float64 dtrunc(float64 arg1)
-{
- float64 result;
- double tmp;
-
- if (!arg1)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- tmp = *arg1;
- if (*arg1 >= 0)
- *result = (float64data) floor(tmp);
- else
- *result = (float64data) -(floor(-tmp));
- return(result);
-}
-
-
-/*
- * dsqrt - returns a pointer to square root of arg1
+float64
+dtrunc(float64 arg1)
+{
+ float64 result;
+ double tmp;
+
+ if (!arg1)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ tmp = *arg1;
+ if (*arg1 >= 0)
+ *result = (float64data) floor(tmp);
+ else
+ *result = (float64data) - (floor(-tmp));
+ return (result);
+}
+
+
+/*
+ * dsqrt - returns a pointer to square root of arg1
*/
-float64 dsqrt(float64 arg1)
+float64
+dsqrt(float64 arg1)
{
- float64 result;
- double tmp;
-
- if (!arg1)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- tmp = *arg1;
- *result = (float64data) sqrt(tmp);
- return (result);
+ float64 result;
+ double tmp;
+
+ if (!arg1)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ tmp = *arg1;
+ *result = (float64data) sqrt(tmp);
+ return (result);
}
/*
- * dcbrt - returns a pointer to cube root of arg1
+ * dcbrt - returns a pointer to cube root of arg1
*/
-float64 dcbrt(float64 arg1)
+float64
+dcbrt(float64 arg1)
{
- float64 result;
- double tmp;
-
- if (!arg1)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- tmp = *arg1;
- *result = (float64data) cbrt(tmp);
- return(result);
+ float64 result;
+ double tmp;
+
+ if (!arg1)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ tmp = *arg1;
+ *result = (float64data) cbrt(tmp);
+ return (result);
}
/*
- * dpow - returns a pointer to pow(arg1,arg2)
+ * dpow - returns a pointer to pow(arg1,arg2)
*/
-float64 dpow(float64 arg1, float64 arg2)
-{
- float64 result;
- double tmp1, tmp2;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- tmp1 = *arg1;
- tmp2 = *arg2;
+float64
+dpow(float64 arg1, float64 arg2)
+{
+ float64 result;
+ double tmp1,
+ tmp2;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ tmp1 = *arg1;
+ tmp2 = *arg2;
#ifndef finite
- errno = 0;
+ errno = 0;
#endif
- *result = (float64data) pow(tmp1, tmp2);
+ *result = (float64data) pow(tmp1, tmp2);
#ifndef finite
- if (errno == ERANGE)
+ if (errno == ERANGE)
#else
- if (!finite(*result))
+ if (!finite(*result))
#endif
- elog(WARN, "pow() returned a floating point out of the range\n");
+ elog(WARN, "pow() returned a floating point out of the range\n");
- CheckFloat8Val(*result);
- return(result);
+ CheckFloat8Val(*result);
+ return (result);
}
/*
- * dexp - returns a pointer to the exponential function of arg1
+ * dexp - returns a pointer to the exponential function of arg1
*/
-float64 dexp(float64 arg1)
-{
- float64 result;
- double tmp;
-
- if (!arg1)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- tmp = *arg1;
+float64
+dexp(float64 arg1)
+{
+ float64 result;
+ double tmp;
+
+ if (!arg1)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ tmp = *arg1;
#ifndef finite
- errno = 0;
+ errno = 0;
#endif
- *result = (float64data) exp(tmp);
+ *result = (float64data) exp(tmp);
#ifndef finite
- if (errno == ERANGE)
+ if (errno == ERANGE)
#else
- if (!finite(*result))
+ if (!finite(*result))
#endif
- elog(WARN, "exp() returned a floating point out of range\n");
+ elog(WARN, "exp() returned a floating point out of range\n");
- CheckFloat8Val(*result);
- return(result);
+ CheckFloat8Val(*result);
+ return (result);
}
/*
- * dlog1 - returns a pointer to the natural logarithm of arg1
- * ("dlog" is already a logging routine...)
+ * dlog1 - returns a pointer to the natural logarithm of arg1
+ * ("dlog" is already a logging routine...)
*/
-float64 dlog1(float64 arg1)
+float64
+dlog1(float64 arg1)
{
- float64 result;
- double tmp;
-
- if (!arg1)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- tmp = *arg1;
- if (tmp == 0.0)
- elog(WARN, "can't take log of 0!");
- if (tmp < 0)
- elog(WARN, "can't take log of a negative number");
- *result = (float64data) log(tmp);
+ float64 result;
+ double tmp;
+
+ if (!arg1)
+ return (float64) NULL;
- CheckFloat8Val(*result);
- return(result);
+ result = (float64) palloc(sizeof(float64data));
+
+ tmp = *arg1;
+ if (tmp == 0.0)
+ elog(WARN, "can't take log of 0!");
+ if (tmp < 0)
+ elog(WARN, "can't take log of a negative number");
+ *result = (float64data) log(tmp);
+
+ CheckFloat8Val(*result);
+ return (result);
}
/*
- * ====================
- * ARITHMETIC OPERATORS
- * ====================
+ * ====================
+ * ARITHMETIC OPERATORS
+ * ====================
*/
/*
- * float48pl - returns a pointer to arg1 + arg2
- * float48mi - returns a pointer to arg1 - arg2
- * float48mul - returns a pointer to arg1 * arg2
- * float48div - returns a pointer to arg1 / arg2
+ * float48pl - returns a pointer to arg1 + arg2
+ * float48mi - returns a pointer to arg1 - arg2
+ * float48mul - returns a pointer to arg1 * arg2
+ * float48div - returns a pointer to arg1 / arg2
*/
-float64 float48pl(float32 arg1, float64 arg2)
-{
- float64 result;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- *result = *arg1 + *arg2;
- CheckFloat8Val(*result);
- return(result);
-}
-
-float64 float48mi(float32 arg1, float64 arg2)
-{
- float64 result;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- *result = *arg1 - *arg2;
- CheckFloat8Val(*result);
- return(result);
-}
-
-float64 float48mul(float32 arg1, float64 arg2)
-{
- float64 result;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- *result = *arg1 * *arg2;
- CheckFloat8Val(*result);
- return(result);
-}
-
-float64 float48div(float32 arg1, float64 arg2)
-{
- float64 result;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- if (*arg2 == 0.0)
- elog(WARN, "float48div: divide by 0.0 error!");
-
- *result = *arg1 / *arg2;
- CheckFloat8Val(*result);
- return(result);
+float64
+float48pl(float32 arg1, float64 arg2)
+{
+ float64 result;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ *result = *arg1 + *arg2;
+ CheckFloat8Val(*result);
+ return (result);
+}
+
+float64
+float48mi(float32 arg1, float64 arg2)
+{
+ float64 result;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ *result = *arg1 - *arg2;
+ CheckFloat8Val(*result);
+ return (result);
+}
+
+float64
+float48mul(float32 arg1, float64 arg2)
+{
+ float64 result;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ *result = *arg1 * *arg2;
+ CheckFloat8Val(*result);
+ return (result);
+}
+
+float64
+float48div(float32 arg1, float64 arg2)
+{
+ float64 result;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ if (*arg2 == 0.0)
+ elog(WARN, "float48div: divide by 0.0 error!");
+
+ *result = *arg1 / *arg2;
+ CheckFloat8Val(*result);
+ return (result);
}
/*
- * float84pl - returns a pointer to arg1 + arg2
- * float84mi - returns a pointer to arg1 - arg2
- * float84mul - returns a pointer to arg1 * arg2
- * float84div - returns a pointer to arg1 / arg2
+ * float84pl - returns a pointer to arg1 + arg2
+ * float84mi - returns a pointer to arg1 - arg2
+ * float84mul - returns a pointer to arg1 * arg2
+ * float84div - returns a pointer to arg1 / arg2
*/
-float64 float84pl(float64 arg1, float32 arg2)
-{
- float64 result;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- *result = *arg1 + *arg2;
- CheckFloat8Val(*result);
- return(result);
-}
-
-float64 float84mi(float64 arg1, float32 arg2)
-{
- float64 result;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- *result = *arg1 - *arg2;
- CheckFloat8Val(*result);
- return(result);
-}
-
-float64 float84mul(float64 arg1, float32 arg2)
-{
-
- float64 result;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- *result = *arg1 * *arg2;
- CheckFloat8Val(*result);
- return(result);
-}
-
-float64 float84div(float64 arg1, float32 arg2)
-{
- float64 result;
-
- if (!arg1 || !arg2)
- return (float64)NULL;
-
- result = (float64) palloc(sizeof(float64data));
-
- if (*arg2 == 0.0)
- elog(WARN, "float48div: divide by 0.0 error!");
-
- *result = *arg1 / *arg2;
- CheckFloat8Val(*result);
- return(result);
+float64
+float84pl(float64 arg1, float32 arg2)
+{
+ float64 result;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ *result = *arg1 + *arg2;
+ CheckFloat8Val(*result);
+ return (result);
+}
+
+float64
+float84mi(float64 arg1, float32 arg2)
+{
+ float64 result;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ *result = *arg1 - *arg2;
+ CheckFloat8Val(*result);
+ return (result);
+}
+
+float64
+float84mul(float64 arg1, float32 arg2)
+{
+
+ float64 result;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ *result = *arg1 * *arg2;
+ CheckFloat8Val(*result);
+ return (result);
+}
+
+float64
+float84div(float64 arg1, float32 arg2)
+{
+ float64 result;
+
+ if (!arg1 || !arg2)
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ if (*arg2 == 0.0)
+ elog(WARN, "float48div: divide by 0.0 error!");
+
+ *result = *arg1 / *arg2;
+ CheckFloat8Val(*result);
+ return (result);
}
/*
- * ====================
- * COMPARISON OPERATORS
- * ====================
+ * ====================
+ * COMPARISON OPERATORS
+ * ====================
*/
/*
- * float48{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
+ * float48{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
*/
-bool float48eq(float32 arg1, float64 arg2)
+bool
+float48eq(float32 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 == (float)*arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 == (float) *arg2);
}
-bool float48ne(float32 arg1, float64 arg2)
+bool
+float48ne(float32 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 != (float)*arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 != (float) *arg2);
}
-bool float48lt(float32 arg1, float64 arg2)
+bool
+float48lt(float32 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 < (float)*arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 < (float) *arg2);
}
-bool float48le(float32 arg1, float64 arg2)
+bool
+float48le(float32 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 <= (float)*arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 <= (float) *arg2);
}
-bool float48gt(float32 arg1, float64 arg2)
+bool
+float48gt(float32 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 > (float)*arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 > (float) *arg2);
}
-bool float48ge(float32 arg1, float64 arg2)
+bool
+float48ge(float32 arg1, float64 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return(*arg1 >= (float)*arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return (*arg1 >= (float) *arg2);
}
/*
- * float84{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
+ * float84{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
*/
-bool float84eq(float64 arg1, float32 arg2)
+bool
+float84eq(float64 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return((float)*arg1 == *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return ((float) *arg1 == *arg2);
}
-bool float84ne(float64 arg1, float32 arg2)
+bool
+float84ne(float64 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return((float)*arg1 != *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return ((float) *arg1 != *arg2);
}
-bool float84lt(float64 arg1, float32 arg2)
+bool
+float84lt(float64 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return((float)*arg1 < *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return ((float) *arg1 < *arg2);
}
-bool float84le(float64 arg1, float32 arg2)
+bool
+float84le(float64 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return((float)*arg1 <= *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return ((float) *arg1 <= *arg2);
}
-bool float84gt(float64 arg1, float32 arg2)
+bool
+float84gt(float64 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return((float)*arg1 > *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return ((float) *arg1 > *arg2);
}
-bool float84ge(float64 arg1, float32 arg2)
+bool
+float84ge(float64 arg1, float32 arg2)
{
- if (!arg1 || !arg2)
- return 0;
-
- return((float)*arg1 >= *arg2);
+ if (!arg1 || !arg2)
+ return 0;
+
+ return ((float) *arg1 >= *arg2);
}
/* ========== PRIVATE ROUTINES ========== */
@@ -1304,7 +1395,7 @@ bool float84ge(float64 arg1, float32 arg2)
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
+ * software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
@@ -1314,89 +1405,115 @@ bool float84ge(float64 arg1, float32 arg2)
* Return x rounded to integral value according to the prevailing
* rounding mode.
* Method:
- * Using floating addition.
+ * Using floating addition.
* Exception:
- * Inexact flag raised if x not equal to rint(x).
+ * Inexact flag raised if x not equal to rint(x).
*/
#ifdef __STDC__
static const double
#else
- static double
+static double
#endif
- one = 1.0,
- TWO52[2]={
+ one = 1.0,
+ TWO52[2] = {
4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
- -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
- };
+ -4.50359962737049600000e+15,/* 0xC3300000, 0x00000000 */
+};
#ifdef __STDC__
-static double rint(double x)
+static double
+rint(double x)
#else
- static double rint(x)
- double x;
+static double
+rint(x)
+double x;
+
#endif
{
- int i0,n0,j0,sx;
- unsigned i,i1;
- double w,t;
- n0 = (*((int *)&one)>>29)^1;
- i0 = *(n0+(int*)&x);
- sx = (i0>>31)&1;
- i1 = *(1-n0+(int*)&x);
- j0 = ((i0>>20)&0x7ff)-0x3ff;
- if(j0<20) {
- if(j0<0) {
- if(((i0&0x7fffffff)|i1)==0) return x;
- i1 |= (i0&0x0fffff);
- i0 &= 0xfffe0000;
- i0 |= ((i1|-i1)>>12)&0x80000;
- *(n0+(int*)&x)=i0;
- w = TWO52[sx]+x;
- t = w-TWO52[sx];
- i0 = *(n0+(int*)&t);
- *(n0+(int*)&t) = (i0&0x7fffffff)|(sx<<31);
- return t;
- } else {
- i = (0x000fffff)>>j0;
- if(((i0&i)|i1)==0) return x; /* x is integral */
- i>>=1;
- if(((i0&i)|i1)!=0) {
- if(j0==19) i1 = 0x40000000; else
- i0 = (i0&(~i))|((0x20000)>>j0);
- }
+ int i0,
+ n0,
+ j0,
+ sx;
+ unsigned i,
+ i1;
+ double w,
+ t;
+
+ n0 = (*((int *) &one) >> 29) ^ 1;
+ i0 = *(n0 + (int *) &x);
+ sx = (i0 >> 31) & 1;
+ i1 = *(1 - n0 + (int *) &x);
+ j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
+ if (j0 < 20)
+ {
+ if (j0 < 0)
+ {
+ if (((i0 & 0x7fffffff) | i1) == 0)
+ return x;
+ i1 |= (i0 & 0x0fffff);
+ i0 &= 0xfffe0000;
+ i0 |= ((i1 | -i1) >> 12) & 0x80000;
+ *(n0 + (int *) &x) = i0;
+ w = TWO52[sx] + x;
+ t = w - TWO52[sx];
+ i0 = *(n0 + (int *) &t);
+ *(n0 + (int *) &t) = (i0 & 0x7fffffff) | (sx << 31);
+ return t;
+ }
+ else
+ {
+ i = (0x000fffff) >> j0;
+ if (((i0 & i) | i1) == 0)
+ return x; /* x is integral */
+ i >>= 1;
+ if (((i0 & i) | i1) != 0)
+ {
+ if (j0 == 19)
+ i1 = 0x40000000;
+ else
+ i0 = (i0 & (~i)) | ((0x20000) >> j0);
+ }
+ }
+ }
+ else if (j0 > 51)
+ {
+ if (j0 == 0x400)
+ return x + x; /* inf or NaN */
+ else
+ return x; /* x is integral */
+ }
+ else
+ {
+ i = ((unsigned) (0xffffffff)) >> (j0 - 20);
+ if ((i1 & i) == 0)
+ return x; /* x is integral */
+ i >>= 1;
+ if ((i1 & i) != 0)
+ i1 = (i1 & (~i)) | ((0x40000000) >> (j0 - 20));
}
- } else if (j0>51) {
- if(j0==0x400) return x+x; /* inf or NaN */
- else return x; /* x is integral */
- } else {
- i = ((unsigned)(0xffffffff))>>(j0-20);
- if((i1&i)==0) return x; /* x is integral */
- i>>=1;
- if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
- }
- *(n0+(int*)&x) = i0;
- *(1-n0+(int*)&x) = i1;
- w = TWO52[sx]+x;
- return w-TWO52[sx];
-}
-
-#endif /* !HAVE_RINT */
+ *(n0 + (int *) &x) = i0;
+ *(1 - n0 + (int *) &x) = i1;
+ w = TWO52[sx] + x;
+ return w - TWO52[sx];
+}
+
+#endif /* !HAVE_RINT */
#ifndef HAVE_CBRT
static
- double
- cbrt(x)
-double x;
+double
+cbrt(x)
+double x;
{
- int isneg = (x < 0.0);
- double tmpres = pow(fabs(x), (double) 1.0 / (double) 3.0);
-
- return(isneg ? -tmpres : tmpres);
+ int isneg = (x < 0.0);
+ double tmpres = pow(fabs(x), (double) 1.0 / (double) 3.0);
+
+ return (isneg ? -tmpres : tmpres);
}
-#endif /* !HAVE_CBRT */
+#endif /* !HAVE_CBRT */
#ifndef HAVE_ISINF
@@ -1404,89 +1521,104 @@ double x;
#ifdef CLASS_CONFLICT
/* we want the math symbol */
#undef class
-#endif /* CLASS_CONFICT */
+#endif /* CLASS_CONFICT */
-static int isinf(x)
- double x;
+static int
+isinf(x)
+double x;
{
- int fpclass = class(x);
- if (fpclass == FP_PLUS_INF)
- return(1);
- if (fpclass == FP_MINUS_INF)
- return(-1);
- return(0);
+ int fpclass = class(x);
+
+ if (fpclass == FP_PLUS_INF)
+ return (1);
+ if (fpclass == FP_MINUS_INF)
+ return (-1);
+ return (0);
}
-#endif /* aix */
+
+#endif /* aix */
#if defined(ultrix4)
#include <fp_class.h>
-static int isinf(x)
- double x;
+static int
+isinf(x)
+double x;
{
- int fpclass = fp_class_d(x);
- if (fpclass == FP_POS_INF)
- return(1);
- if (fpclass == FP_NEG_INF)
- return(-1);
- return(0);
+ int fpclass = fp_class_d(x);
+
+ if (fpclass == FP_POS_INF)
+ return (1);
+ if (fpclass == FP_NEG_INF)
+ return (-1);
+ return (0);
}
-#endif /* ultrix4 */
+
+#endif /* ultrix4 */
#if defined(alpha)
#include <fp_class.h>
-static int isinf(x)
- double x;
+static int
+isinf(x)
+double x;
{
- int fpclass = fp_class(x);
- if (fpclass == FP_POS_INF)
- return(1);
- if (fpclass == FP_NEG_INF)
- return(-1);
- return(0);
+ int fpclass = fp_class(x);
+
+ if (fpclass == FP_POS_INF)
+ return (1);
+ if (fpclass == FP_NEG_INF)
+ return (-1);
+ return (0);
}
-#endif /* alpha */
+
+#endif /* alpha */
#if defined(sparc_solaris) || defined(i386_solaris) || defined(svr4) || \
- defined(sco)
+ defined(sco)
#include <ieeefp.h>
static int
- isinf(d)
-double d;
-{
- fpclass_t type = fpclass(d);
- switch (type) {
- case FP_SNAN:
- case FP_QNAN:
- case FP_NINF:
- case FP_PINF:
- return (1);
- default:
- break;
- }
-
- return (0);
-}
-#endif /* sparc_solaris */
+isinf(d)
+double d;
+{
+ fpclass_t type = fpclass(d);
+
+ switch (type)
+ {
+ case FP_SNAN:
+ case FP_QNAN:
+ case FP_NINF:
+ case FP_PINF:
+ return (1);
+ default:
+ break;
+ }
+
+ return (0);
+}
+
+#endif /* sparc_solaris */
#if defined(irix5)
#include <ieeefp.h>
static int
- isinf(d)
-double d;
-{
- fpclass_t type = fpclass(d);
- switch (type) {
- case FP_SNAN:
- case FP_QNAN:
- case FP_NINF:
- case FP_PINF:
- return (1);
- default:
- break;
- }
-
- return (0);
-}
-#endif /* irix5 */
-
-#endif /* !HAVE_ISINF */
+isinf(d)
+double d;
+{
+ fpclass_t type = fpclass(d);
+
+ switch (type)
+ {
+ case FP_SNAN:
+ case FP_QNAN:
+ case FP_NINF:
+ case FP_PINF:
+ return (1);
+ default:
+ break;
+ }
+
+ return (0);
+}
+
+#endif /* irix5 */
+
+#endif /* !HAVE_ISINF */
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index d805ba7a220..71b478788ef 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* geo_ops.c--
- * 2D geometric operations
+ * 2D geometric operations
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.19 1997/09/05 20:20:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.20 1997/09/07 04:50:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <math.h>
#include <limits.h>
#include <float.h>
-#include <stdio.h> /* for sprintf proto, etc. */
-#include <stdlib.h> /* for strtod, etc. */
+#include <stdio.h> /* for sprintf proto, etc. */
+#include <stdlib.h> /* for strtod, etc. */
#include <string.h>
#include <ctype.h>
@@ -28,38 +28,38 @@
#define PI 3.1415926536
#endif
-static int point_inside( Point *p, int npts, Point plist[]);
-static int lseg_crossing( double x, double y, double px, double py);
-static BOX *box_construct(double x1, double x2, double y1, double y2);
-static BOX *box_copy(BOX *box);
-static BOX *box_fill(BOX *result, double x1, double x2, double y1, double y2);
-static double box_ht(BOX *box);
-static double box_wd(BOX *box);
-static double circle_ar(CIRCLE *circle);
-static CIRCLE *circle_copy(CIRCLE *circle);
-static LINE *line_construct_pm(Point *pt, double m);
-static bool line_horizontal(LINE *line);
-static Point *line_interpt(LINE *l1, LINE *l2);
-static bool line_intersect(LINE *l1, LINE *l2);
-static bool line_parallel(LINE *l1, LINE *l2);
-static bool line_vertical(LINE *line);
-static double lseg_dt(LSEG *l1, LSEG *l2);
-static void make_bound_box(POLYGON *poly);
-static PATH *path_copy(PATH *path);
-static bool plist_same(int npts, Point p1[], Point p2[]);
-static Point *point_construct(double x, double y);
-static Point *point_copy(Point *pt);
-static int single_decode(char *str, float8 *x, char **ss);
-static int single_encode(float8 x, char *str);
-static int pair_decode(char *str, float8 *x, float8 *y, char **s);
-static int pair_encode(float8 x, float8 y, char *str);
-static int pair_count(char *s, char delim);
-static int path_decode(int opentype, int npts, char *str, int *isopen, char **ss, Point *p);
-static char *path_encode( bool closed, int npts, Point *pt);
-static void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2);
-static double box_ar(BOX *box);
-static Point *interpt_sl(LSEG *lseg, LINE *line);
-static LINE *line_construct_pp(Point *pt1, Point *pt2);
+static int point_inside(Point * p, int npts, Point plist[]);
+static int lseg_crossing(double x, double y, double px, double py);
+static BOX *box_construct(double x1, double x2, double y1, double y2);
+static BOX *box_copy(BOX * box);
+static BOX *box_fill(BOX * result, double x1, double x2, double y1, double y2);
+static double box_ht(BOX * box);
+static double box_wd(BOX * box);
+static double circle_ar(CIRCLE * circle);
+static CIRCLE *circle_copy(CIRCLE * circle);
+static LINE *line_construct_pm(Point * pt, double m);
+static bool line_horizontal(LINE * line);
+static Point *line_interpt(LINE * l1, LINE * l2);
+static bool line_intersect(LINE * l1, LINE * l2);
+static bool line_parallel(LINE * l1, LINE * l2);
+static bool line_vertical(LINE * line);
+static double lseg_dt(LSEG * l1, LSEG * l2);
+static void make_bound_box(POLYGON * poly);
+static PATH *path_copy(PATH * path);
+static bool plist_same(int npts, Point p1[], Point p2[]);
+static Point *point_construct(double x, double y);
+static Point *point_copy(Point * pt);
+static int single_decode(char *str, float8 * x, char **ss);
+static int single_encode(float8 x, char *str);
+static int pair_decode(char *str, float8 * x, float8 * y, char **s);
+static int pair_encode(float8 x, float8 y, char *str);
+static int pair_count(char *s, char delim);
+static int path_decode(int opentype, int npts, char *str, int *isopen, char **ss, Point * p);
+static char *path_encode(bool closed, int npts, Point * pt);
+static void statlseg_construct(LSEG * lseg, Point * pt1, Point * pt2);
+static double box_ar(BOX * box);
+static Point *interpt_sl(LSEG * lseg, LINE * line);
+static LINE *line_construct_pp(Point * pt1, Point * pt2);
/*
@@ -68,203 +68,248 @@ static LINE *line_construct_pp(Point *pt1, Point *pt2);
* LDELIM_EP, RDELIM_EP are left and right delimiters for paths with endpoints.
*/
-#define LDELIM '('
-#define RDELIM ')'
-#define DELIM ','
-#define LDELIM_EP '['
-#define RDELIM_EP ']'
-#define LDELIM_C '<'
-#define RDELIM_C '>'
+#define LDELIM '('
+#define RDELIM ')'
+#define DELIM ','
+#define LDELIM_EP '['
+#define RDELIM_EP ']'
+#define LDELIM_C '<'
+#define RDELIM_C '>'
/* Maximum number of output digits printed */
#define P_MAXDIG DBL_DIG
#define P_MAXLEN (2*(P_MAXDIG+7)+1)
-static int digits8 = P_MAXDIG;
+static int digits8 = P_MAXDIG;
/*
* Geometric data types are composed of points.
* This code tries to support a common format throughout the data types,
- * to allow for more predictable usage and data type conversion.
+ * to allow for more predictable usage and data type conversion.
* The fundamental unit is the point. Other units are line segments,
- * open paths, boxes, closed paths, and polygons (which should be considered
- * non-intersecting closed paths).
+ * open paths, boxes, closed paths, and polygons (which should be considered
+ * non-intersecting closed paths).
*
* Data representation is as follows:
- * point: (x,y)
- * line segment: [(x1,y1),(x2,y2)]
- * box: (x1,y1),(x2,y2)
- * open path: [(x1,y1),...,(xn,yn)]
- * closed path: ((x1,y1),...,(xn,yn))
- * polygon: ((x1,y1),...,(xn,yn))
+ * point: (x,y)
+ * line segment: [(x1,y1),(x2,y2)]
+ * box: (x1,y1),(x2,y2)
+ * open path: [(x1,y1),...,(xn,yn)]
+ * closed path: ((x1,y1),...,(xn,yn))
+ * polygon: ((x1,y1),...,(xn,yn))
*
* For boxes, the points are opposite corners with the first point at the top right.
* For closed paths and polygons, the points should be reordered to allow
- * fast and correct equality comparisons.
+ * fast and correct equality comparisons.
*
* XXX perhaps points in complex shapes should be reordered internally
- * to allow faster internal operations, but should keep track of input order
- * and restore that order for text output - tgl 97/01/16
+ * to allow faster internal operations, but should keep track of input order
+ * and restore that order for text output - tgl 97/01/16
*/
-static int single_decode(char *str, float8 *x, char **s)
+static int
+single_decode(char *str, float8 * x, char **s)
{
- char *cp;
+ char *cp;
- if (!PointerIsValid(str))
- return(FALSE);
+ if (!PointerIsValid(str))
+ return (FALSE);
- while (isspace( *str)) str++;
- *x = strtod( str, &cp);
+ while (isspace(*str))
+ str++;
+ *x = strtod(str, &cp);
#ifdef GEODEBUG
-fprintf( stderr, "single_decode- (%x) try decoding %s to %g\n", (cp-str), str, *x);
+ fprintf(stderr, "single_decode- (%x) try decoding %s to %g\n", (cp - str), str, *x);
#endif
- if (cp <= str) return(FALSE);
- while (isspace( *cp)) cp++;
-
- if (s != NULL) *s = cp;
+ if (cp <= str)
+ return (FALSE);
+ while (isspace(*cp))
+ cp++;
- return(TRUE);
-} /* single_decode() */
+ if (s != NULL)
+ *s = cp;
-static int single_encode(float8 x, char *str)
-{
- sprintf(str, "%.*g", digits8, x);
- return(TRUE);
-} /* single_encode() */
+ return (TRUE);
+} /* single_decode() */
-static int pair_decode(char *str, float8 *x, float8 *y, char **s)
+static int
+single_encode(float8 x, char *str)
{
- int has_delim;
- char *cp;
-
- if (!PointerIsValid(str))
- return(FALSE);
-
- while (isspace( *str)) str++;
- if ((has_delim = (*str == LDELIM))) str++;
+ sprintf(str, "%.*g", digits8, x);
+ return (TRUE);
+} /* single_encode() */
- while (isspace( *str)) str++;
- *x = strtod( str, &cp);
- if (cp <= str) return(FALSE);
- while (isspace( *cp)) cp++;
- if (*cp++ != DELIM) return(FALSE);
- while (isspace( *cp)) cp++;
- *y = strtod( cp, &str);
- if (str <= cp) return(FALSE);
- while (isspace( *str)) str++;
- if (has_delim) {
- if (*str != RDELIM) return(FALSE);
- str++;
- while (isspace( *str)) str++;
- }
- if (s != NULL) *s = str;
+static int
+pair_decode(char *str, float8 * x, float8 * y, char **s)
+{
+ int has_delim;
+ char *cp;
+
+ if (!PointerIsValid(str))
+ return (FALSE);
+
+ while (isspace(*str))
+ str++;
+ if ((has_delim = (*str == LDELIM)))
+ str++;
+
+ while (isspace(*str))
+ str++;
+ *x = strtod(str, &cp);
+ if (cp <= str)
+ return (FALSE);
+ while (isspace(*cp))
+ cp++;
+ if (*cp++ != DELIM)
+ return (FALSE);
+ while (isspace(*cp))
+ cp++;
+ *y = strtod(cp, &str);
+ if (str <= cp)
+ return (FALSE);
+ while (isspace(*str))
+ str++;
+ if (has_delim)
+ {
+ if (*str != RDELIM)
+ return (FALSE);
+ str++;
+ while (isspace(*str))
+ str++;
+ }
+ if (s != NULL)
+ *s = str;
- return(TRUE);
+ return (TRUE);
}
-static int pair_encode(float8 x, float8 y, char *str)
+static int
+pair_encode(float8 x, float8 y, char *str)
{
- sprintf(str, "%.*g,%.*g", digits8, x, digits8, y);
- return(TRUE);
+ sprintf(str, "%.*g,%.*g", digits8, x, digits8, y);
+ return (TRUE);
}
-static int path_decode(int opentype, int npts, char *str, int *isopen, char **ss, Point *p)
-{
- int depth = 0;
- char *s, *cp;
- int i;
-
- s = str;
- while (isspace( *s)) s++;
- if ((*isopen = (*s == LDELIM_EP))) {
- /* no open delimiter allowed? */
- if (! opentype) return(FALSE);
- depth++;
- s++;
- while (isspace( *s)) s++;
+static int
+path_decode(int opentype, int npts, char *str, int *isopen, char **ss, Point * p)
+{
+ int depth = 0;
+ char *s,
+ *cp;
+ int i;
+
+ s = str;
+ while (isspace(*s))
+ s++;
+ if ((*isopen = (*s == LDELIM_EP)))
+ {
+ /* no open delimiter allowed? */
+ if (!opentype)
+ return (FALSE);
+ depth++;
+ s++;
+ while (isspace(*s))
+ s++;
- } else if (*s == LDELIM) {
- cp = (s+1);
- while (isspace( *cp)) cp++;
- if (*cp == LDELIM) {
- /* nested delimiters with only one point? */
- if (npts <= 1) return(FALSE);
- depth++;
- s = cp;
- } else if (strrchr( s, LDELIM) == s) {
- depth++;
- s = cp;
}
- }
-
- for (i = 0; i < npts; i++) {
- if (! pair_decode( s, &(p->x), &(p->y), &s))
- return(FALSE);
+ else if (*s == LDELIM)
+ {
+ cp = (s + 1);
+ while (isspace(*cp))
+ cp++;
+ if (*cp == LDELIM)
+ {
+ /* nested delimiters with only one point? */
+ if (npts <= 1)
+ return (FALSE);
+ depth++;
+ s = cp;
+ }
+ else if (strrchr(s, LDELIM) == s)
+ {
+ depth++;
+ s = cp;
+ }
+ }
- if (*s == DELIM) s++;
- p++;
- }
+ for (i = 0; i < npts; i++)
+ {
+ if (!pair_decode(s, &(p->x), &(p->y), &s))
+ return (FALSE);
- while (depth > 0) {
- if ((*s == RDELIM)
- || ((*s == RDELIM_EP) && (*isopen) && (depth == 1))) {
- depth--;
- s++;
- while (isspace( *s)) s++;
- } else {
- return(FALSE);
+ if (*s == DELIM)
+ s++;
+ p++;
}
- }
- *ss = s;
- return(TRUE);
-} /* path_decode() */
+ while (depth > 0)
+ {
+ if ((*s == RDELIM)
+ || ((*s == RDELIM_EP) && (*isopen) && (depth == 1)))
+ {
+ depth--;
+ s++;
+ while (isspace(*s))
+ s++;
+ }
+ else
+ {
+ return (FALSE);
+ }
+ }
+ *ss = s;
+
+ return (TRUE);
+} /* path_decode() */
+
+static char *
+path_encode(bool closed, int npts, Point * pt)
+{
+ char *result = PALLOC(npts * (P_MAXLEN + 3) + 2);
+
+ char *cp;
+ int i;
+
+ cp = result;
+ switch (closed)
+ {
+ case TRUE:
+ *cp++ = LDELIM;
+ break;
+ case FALSE:
+ *cp++ = LDELIM_EP;
+ break;
+ default:
+ break;
+ }
-static char *path_encode( bool closed, int npts, Point *pt)
-{
- char *result = PALLOC(npts*(P_MAXLEN+3)+2);
+ for (i = 0; i < npts; i++)
+ {
+ *cp++ = LDELIM;
+ if (!pair_encode(pt->x, pt->y, cp))
+ elog(WARN, "Unable to format path", NULL);
+ cp += strlen(cp);
+ *cp++ = RDELIM;
+ *cp++ = DELIM;
+ pt++;
+ }
+ cp--;
+ switch (closed)
+ {
+ case TRUE:
+ *cp++ = RDELIM;
+ break;
+ case FALSE:
+ *cp++ = RDELIM_EP;
+ break;
+ default:
+ break;
+ }
+ *cp = '\0';
- char *cp;
- int i;
-
- cp = result;
- switch (closed) {
- case TRUE:
- *cp++ = LDELIM;
- break;
- case FALSE:
- *cp++ = LDELIM_EP;
- break;
- default:
- break;
- }
-
- for (i = 0; i < npts; i++) {
- *cp++ = LDELIM;
- if (! pair_encode( pt->x, pt->y, cp))
- elog (WARN, "Unable to format path", NULL);
- cp += strlen(cp);
- *cp++ = RDELIM;
- *cp++ = DELIM;
- pt++;
- }
- cp--;
- switch (closed) {
- case TRUE:
- *cp++ = RDELIM;
- break;
- case FALSE:
- *cp++ = RDELIM_EP;
- break;
- default:
- break;
- }
- *cp = '\0';
-
- return(result);
-} /* path_encode() */
+ return (result);
+} /* path_encode() */
/*-------------------------------------------------------------
* pair_count - count the number of points
@@ -273,20 +318,22 @@ static char *path_encode( bool closed, int npts, Point *pt)
* '(1,3,2,4)'
* require an odd number of delim characters in the string
*-------------------------------------------------------------*/
-static int pair_count(char *s, char delim)
+static int
+pair_count(char *s, char delim)
{
- int ndelim = 0;
+ int ndelim = 0;
- while ((s = strchr( s, delim)) != NULL) {
- ndelim++;
- s++;
- }
- return((ndelim % 2)? ((ndelim+1)/2): -1);
+ while ((s = strchr(s, delim)) != NULL)
+ {
+ ndelim++;
+ s++;
+ }
+ return ((ndelim % 2) ? ((ndelim + 1) / 2) : -1);
}
/***********************************************************************
**
- ** Routines for two-dimensional boxes.
+ ** Routines for two-dimensional boxes.
**
***********************************************************************/
@@ -294,716 +341,795 @@ static int pair_count(char *s, char delim)
* Formatting and conversion routines.
*---------------------------------------------------------*/
-/* box_in - convert a string to internal form.
+/* box_in - convert a string to internal form.
*
- * External format: (two corners of box)
- * "(f8, f8), (f8, f8)"
- * also supports the older style "(f8, f8, f8, f8)"
+ * External format: (two corners of box)
+ * "(f8, f8), (f8, f8)"
+ * also supports the older style "(f8, f8, f8, f8)"
*/
-BOX *box_in(char *str)
+BOX *
+box_in(char *str)
{
- BOX *box = PALLOCTYPE(BOX);
+ BOX *box = PALLOCTYPE(BOX);
- int isopen;
- char *s;
- double x, y;
+ int isopen;
+ char *s;
+ double x,
+ y;
- if (!PointerIsValid(str))
- elog (WARN," Bad (null) box external representation",NULL);
+ if (!PointerIsValid(str))
+ elog(WARN, " Bad (null) box external representation", NULL);
- if ((! path_decode(FALSE, 2, str, &isopen, &s, &(box->high)))
- || (*s != '\0'))
- elog (WARN, "Bad box external representation '%s'",str);
+ if ((!path_decode(FALSE, 2, str, &isopen, &s, &(box->high)))
+ || (*s != '\0'))
+ elog(WARN, "Bad box external representation '%s'", str);
- /* reorder corners if necessary... */
- if (box->high.x < box->low.x) {
- x = box->high.x;
- box->high.x = box->low.x;
- box->low.x = x;
- }
- if (box->high.y < box->low.y) {
- y = box->high.y;
- box->high.y = box->low.y;
- box->low.y = y;
- }
+ /* reorder corners if necessary... */
+ if (box->high.x < box->low.x)
+ {
+ x = box->high.x;
+ box->high.x = box->low.x;
+ box->low.x = x;
+ }
+ if (box->high.y < box->low.y)
+ {
+ y = box->high.y;
+ box->high.y = box->low.y;
+ box->low.y = y;
+ }
- return(box);
-} /* box_in() */
+ return (box);
+} /* box_in() */
-/* box_out - convert a box to external form.
+/* box_out - convert a box to external form.
*/
-char *box_out(BOX *box)
+char *
+box_out(BOX * box)
{
- if (!PointerIsValid(box))
- return(NULL);
+ if (!PointerIsValid(box))
+ return (NULL);
- return( path_encode( -1, 2, (Point *) &(box->high)));
-} /* box_out() */
+ return (path_encode(-1, 2, (Point *) & (box->high)));
+} /* box_out() */
-/* box_construct - fill in a new box.
+/* box_construct - fill in a new box.
*/
-static BOX *box_construct(double x1, double x2, double y1, double y2)
+static BOX *
+box_construct(double x1, double x2, double y1, double y2)
{
- BOX *result = PALLOCTYPE(BOX);
+ BOX *result = PALLOCTYPE(BOX);
- return( box_fill(result, x1, x2, y1, y2) );
+ return (box_fill(result, x1, x2, y1, y2));
}
-/* box_fill - fill in a static box
+/* box_fill - fill in a static box
*/
-static BOX *box_fill(BOX *result, double x1, double x2, double y1, double y2)
+static BOX *
+box_fill(BOX * result, double x1, double x2, double y1, double y2)
{
- if (x1 > x2) {
- result->high.x = x1;
- result->low.x = x2;
- } else {
- result->high.x = x2;
- result->low.x = x1;
- }
- if (y1 > y2) {
- result->high.y = y1;
- result->low.y = y2;
- } else {
- result->high.y = y2;
- result->low.y = y1;
- }
-
- return(result);
+ if (x1 > x2)
+ {
+ result->high.x = x1;
+ result->low.x = x2;
+ }
+ else
+ {
+ result->high.x = x2;
+ result->low.x = x1;
+ }
+ if (y1 > y2)
+ {
+ result->high.y = y1;
+ result->low.y = y2;
+ }
+ else
+ {
+ result->high.y = y2;
+ result->low.y = y1;
+ }
+
+ return (result);
}
-/* box_copy - copy a box
+/* box_copy - copy a box
*/
-static BOX *box_copy(BOX *box)
+static BOX *
+box_copy(BOX * box)
{
- BOX *result = PALLOCTYPE(BOX);
+ BOX *result = PALLOCTYPE(BOX);
- memmove((char *) result, (char *) box, sizeof(BOX));
-
- return(result);
+ memmove((char *) result, (char *) box, sizeof(BOX));
+
+ return (result);
}
/*----------------------------------------------------------
- * Relational operators for BOXes.
- * <, >, <=, >=, and == are based on box area.
+ * Relational operators for BOXes.
+ * <, >, <=, >=, and == are based on box area.
*---------------------------------------------------------*/
-/* box_same - are two boxes identical?
+/* box_same - are two boxes identical?
*/
-bool box_same(BOX *box1, BOX *box2)
+bool
+box_same(BOX * box1, BOX * box2)
{
- return((FPeq(box1->high.x,box2->high.x) && FPeq(box1->low.x,box2->low.x)) &&
- (FPeq(box1->high.y,box2->high.y) && FPeq(box1->low.y,box2->low.y)));
+ return ((FPeq(box1->high.x, box2->high.x) && FPeq(box1->low.x, box2->low.x)) &&
+ (FPeq(box1->high.y, box2->high.y) && FPeq(box1->low.y, box2->low.y)));
}
-/* box_overlap - does box1 overlap box2?
+/* box_overlap - does box1 overlap box2?
*/
-bool box_overlap(BOX *box1, BOX *box2)
+bool
+box_overlap(BOX * box1, BOX * box2)
{
- return(((FPge(box1->high.x,box2->high.x) && FPle(box1->low.x,box2->high.x)) ||
- (FPge(box2->high.x,box1->high.x) && FPle(box2->low.x,box1->high.x))) &&
- ((FPge(box1->high.y,box2->high.y) && FPle(box1->low.y,box2->high.y)) ||
- (FPge(box2->high.y,box1->high.y) && FPle(box2->low.y,box1->high.y))) );
+ return (((FPge(box1->high.x, box2->high.x) && FPle(box1->low.x, box2->high.x)) ||
+ (FPge(box2->high.x, box1->high.x) && FPle(box2->low.x, box1->high.x))) &&
+ ((FPge(box1->high.y, box2->high.y) && FPle(box1->low.y, box2->high.y)) ||
+ (FPge(box2->high.y, box1->high.y) && FPle(box2->low.y, box1->high.y))));
}
-/* box_overleft - is the right edge of box1 to the left of
- * the right edge of box2?
+/* box_overleft - is the right edge of box1 to the left of
+ * the right edge of box2?
*
- * This is "less than or equal" for the end of a time range,
- * when time ranges are stored as rectangles.
+ * This is "less than or equal" for the end of a time range,
+ * when time ranges are stored as rectangles.
*/
-bool box_overleft(BOX *box1, BOX *box2)
+bool
+box_overleft(BOX * box1, BOX * box2)
{
- return(FPle(box1->high.x,box2->high.x));
+ return (FPle(box1->high.x, box2->high.x));
}
-/* box_left - is box1 strictly left of box2?
+/* box_left - is box1 strictly left of box2?
*/
-bool box_left(BOX *box1, BOX *box2)
+bool
+box_left(BOX * box1, BOX * box2)
{
- return(FPlt(box1->high.x,box2->low.x));
+ return (FPlt(box1->high.x, box2->low.x));
}
-/* box_right - is box1 strictly right of box2?
+/* box_right - is box1 strictly right of box2?
*/
-bool box_right(BOX *box1, BOX *box2)
+bool
+box_right(BOX * box1, BOX * box2)
{
- return(FPgt(box1->low.x,box2->high.x));
+ return (FPgt(box1->low.x, box2->high.x));
}
-/* box_overright - is the left edge of box1 to the right of
- * the left edge of box2?
+/* box_overright - is the left edge of box1 to the right of
+ * the left edge of box2?
*
- * This is "greater than or equal" for time ranges, when time ranges
- * are stored as rectangles.
+ * This is "greater than or equal" for time ranges, when time ranges
+ * are stored as rectangles.
*/
-bool box_overright(BOX *box1, BOX *box2)
+bool
+box_overright(BOX * box1, BOX * box2)
{
- return(box1->low.x >= box2->low.x);
+ return (box1->low.x >= box2->low.x);
}
-/* box_contained - is box1 contained by box2?
+/* box_contained - is box1 contained by box2?
*/
-bool box_contained(BOX *box1, BOX *box2)
+bool
+box_contained(BOX * box1, BOX * box2)
{
- return((FPle(box1->high.x,box2->high.x) && FPge(box1->low.x,box2->low.x)) &&
- (FPle(box1->high.y,box2->high.y) && FPge(box1->low.y,box2->low.y)));
+ return ((FPle(box1->high.x, box2->high.x) && FPge(box1->low.x, box2->low.x)) &&
+ (FPle(box1->high.y, box2->high.y) && FPge(box1->low.y, box2->low.y)));
}
-/* box_contain - does box1 contain box2?
+/* box_contain - does box1 contain box2?
*/
-bool box_contain(BOX *box1, BOX *box2)
+bool
+box_contain(BOX * box1, BOX * box2)
{
- return((FPge(box1->high.x,box2->high.x) && FPle(box1->low.x,box2->low.x) &&
- FPge(box1->high.y,box2->high.y) && FPle(box1->low.y,box2->low.y)));
+ return ((FPge(box1->high.x, box2->high.x) && FPle(box1->low.x, box2->low.x) &&
+ FPge(box1->high.y, box2->high.y) && FPle(box1->low.y, box2->low.y)));
}
-/* box_positionop -
- * is box1 entirely {above,below} box2?
+/* box_positionop -
+ * is box1 entirely {above,below} box2?
*/
-bool box_below(BOX *box1, BOX *box2)
+bool
+box_below(BOX * box1, BOX * box2)
{
- return( FPle(box1->high.y,box2->low.y) );
+ return (FPle(box1->high.y, box2->low.y));
}
-bool box_above(BOX *box1, BOX *box2)
+bool
+box_above(BOX * box1, BOX * box2)
{
- return( FPge(box1->low.y,box2->high.y) );
+ return (FPge(box1->low.y, box2->high.y));
}
-/* box_relop - is area(box1) relop area(box2), within
- * our accuracy constraint?
+/* box_relop - is area(box1) relop area(box2), within
+ * our accuracy constraint?
*/
-bool box_lt(BOX *box1, BOX *box2)
+bool
+box_lt(BOX * box1, BOX * box2)
{
- return( FPlt(box_ar(box1), box_ar(box2)) );
+ return (FPlt(box_ar(box1), box_ar(box2)));
}
-bool box_gt(BOX *box1, BOX *box2)
+bool
+box_gt(BOX * box1, BOX * box2)
{
- return( FPgt(box_ar(box1), box_ar(box2)) );
+ return (FPgt(box_ar(box1), box_ar(box2)));
}
-bool box_eq(BOX *box1, BOX *box2)
+bool
+box_eq(BOX * box1, BOX * box2)
{
- return( FPeq(box_ar(box1), box_ar(box2)) );
+ return (FPeq(box_ar(box1), box_ar(box2)));
}
-bool box_le(BOX *box1, BOX *box2)
+bool
+box_le(BOX * box1, BOX * box2)
{
- return( FPle(box_ar(box1), box_ar(box2)) );
+ return (FPle(box_ar(box1), box_ar(box2)));
}
-bool box_ge(BOX *box1, BOX *box2)
+bool
+box_ge(BOX * box1, BOX * box2)
{
- return( FPge(box_ar(box1), box_ar(box2)) );
+ return (FPge(box_ar(box1), box_ar(box2)));
}
/*----------------------------------------------------------
- * "Arithmetic" operators on boxes.
- * box_foo returns foo as an object (pointer) that
+ * "Arithmetic" operators on boxes.
+ * box_foo returns foo as an object (pointer) that
can be passed between languages.
- * box_xx is an internal routine which returns the
- * actual value (and cannot be handed back to
- * LISP).
+ * box_xx is an internal routine which returns the
+ * actual value (and cannot be handed back to
+ * LISP).
*---------------------------------------------------------*/
-/* box_area - returns the area of the box.
+/* box_area - returns the area of the box.
*/
-double *box_area(BOX *box)
+double *
+box_area(BOX * box)
{
- double *result = PALLOCTYPE(double);
+ double *result = PALLOCTYPE(double);
- *result = box_wd(box) * box_ht(box);
-
- return(result);
+ *result = box_wd(box) * box_ht(box);
+
+ return (result);
}
-/* box_width - returns the width of the box
- * (horizontal magnitude).
+/* box_width - returns the width of the box
+ * (horizontal magnitude).
*/
-double *box_width(BOX *box)
+double *
+box_width(BOX * box)
{
- double *result = PALLOCTYPE(double);
+ double *result = PALLOCTYPE(double);
+
+ *result = box->high.x - box->low.x;
- *result = box->high.x - box->low.x;
-
- return(result);
-} /* box_width() */
+ return (result);
+} /* box_width() */
-/* box_height - returns the height of the box
- * (vertical magnitude).
+/* box_height - returns the height of the box
+ * (vertical magnitude).
*/
-double *box_height(BOX *box)
+double *
+box_height(BOX * box)
{
- double *result = PALLOCTYPE(double);
+ double *result = PALLOCTYPE(double);
+
+ *result = box->high.y - box->low.y;
- *result = box->high.y - box->low.y;
-
- return(result);
+ return (result);
}
-/* box_distance - returns the distance between the
- * center points of two boxes.
+/* box_distance - returns the distance between the
+ * center points of two boxes.
*/
-double *box_distance(BOX *box1, BOX *box2)
+double *
+box_distance(BOX * box1, BOX * box2)
{
- double *result = PALLOCTYPE(double);
- Point *a, *b;
-
- a = box_center(box1);
- b = box_center(box2);
- *result = HYPOT(a->x - b->x, a->y - b->y);
-
- PFREE(a);
- PFREE(b);
- return(result);
+ double *result = PALLOCTYPE(double);
+ Point *a,
+ *b;
+
+ a = box_center(box1);
+ b = box_center(box2);
+ *result = HYPOT(a->x - b->x, a->y - b->y);
+
+ PFREE(a);
+ PFREE(b);
+ return (result);
}
-/* box_center - returns the center point of the box.
+/* box_center - returns the center point of the box.
*/
-Point *box_center(BOX *box)
+Point *
+box_center(BOX * box)
{
- Point *result = PALLOCTYPE(Point);
+ Point *result = PALLOCTYPE(Point);
- result->x = (box->high.x + box->low.x) / 2.0;
- result->y = (box->high.y + box->low.y) / 2.0;
-
- return(result);
+ result->x = (box->high.x + box->low.x) / 2.0;
+ result->y = (box->high.y + box->low.y) / 2.0;
+
+ return (result);
}
-/* box_ar - returns the area of the box.
+/* box_ar - returns the area of the box.
*/
-static double box_ar(BOX *box)
+static double
+box_ar(BOX * box)
{
- return( box_wd(box) * box_ht(box) );
+ return (box_wd(box) * box_ht(box));
}
-/* box_wd - returns the width (length) of the box
- * (horizontal magnitude).
+/* box_wd - returns the width (length) of the box
+ * (horizontal magnitude).
*/
-static double box_wd(BOX *box)
+static double
+box_wd(BOX * box)
{
- return( box->high.x - box->low.x );
+ return (box->high.x - box->low.x);
}
-/* box_ht - returns the height of the box
- * (vertical magnitude).
+/* box_ht - returns the height of the box
+ * (vertical magnitude).
*/
-static double box_ht(BOX *box)
+static double
+box_ht(BOX * box)
{
- return( box->high.y - box->low.y );
+ return (box->high.y - box->low.y);
}
-/* box_dt - returns the distance between the
- * center points of two boxes.
+/* box_dt - returns the distance between the
+ * center points of two boxes.
*/
#ifdef NOT_USED
-static double box_dt(BOX *box1, BOX *box2)
-{
- double result;
- Point *a, *b;
-
- a = box_center(box1);
- b = box_center(box2);
- result = HYPOT(a->x - b->x, a->y - b->y);
-
- PFREE(a);
- PFREE(b);
- return(result);
+static double
+box_dt(BOX * box1, BOX * box2)
+{
+ double result;
+ Point *a,
+ *b;
+
+ a = box_center(box1);
+ b = box_center(box2);
+ result = HYPOT(a->x - b->x, a->y - b->y);
+
+ PFREE(a);
+ PFREE(b);
+ return (result);
}
+
#endif
/*----------------------------------------------------------
- * Funky operations.
+ * Funky operations.
*---------------------------------------------------------*/
-/* box_intersect -
- * returns the overlapping portion of two boxes,
- * or NULL if they do not intersect.
+/* box_intersect -
+ * returns the overlapping portion of two boxes,
+ * or NULL if they do not intersect.
*/
-BOX *box_intersect(BOX *box1, BOX *box2)
+BOX *
+box_intersect(BOX * box1, BOX * box2)
{
- BOX *result;
+ BOX *result;
+
+ if (!box_overlap(box1, box2))
+ return (NULL);
- if (! box_overlap(box1,box2))
- return(NULL);
+ result = PALLOCTYPE(BOX);
- result = PALLOCTYPE(BOX);
+ result->high.x = Min(box1->high.x, box2->high.x);
+ result->low.x = Max(box1->low.x, box2->low.x);
+ result->high.y = Min(box1->high.y, box2->high.y);
+ result->low.y = Max(box1->low.y, box2->low.y);
- result->high.x = Min(box1->high.x, box2->high.x);
- result->low.x = Max(box1->low.x, box2->low.x);
- result->high.y = Min(box1->high.y, box2->high.y);
- result->low.y = Max(box1->low.y, box2->low.y);
-
- return(result);
+ return (result);
}
-/* box_diagonal -
- * returns a line segment which happens to be the
- * positive-slope diagonal of "box".
- * provided, of course, we have LSEGs.
+/* box_diagonal -
+ * returns a line segment which happens to be the
+ * positive-slope diagonal of "box".
+ * provided, of course, we have LSEGs.
*/
-LSEG *box_diagonal(BOX *box)
+LSEG *
+box_diagonal(BOX * box)
{
- Point p1, p2;
-
- p1.x = box->high.x;
- p1.y = box->high.y;
- p2.x = box->low.x;
- p2.y = box->low.y;
- return( lseg_construct( &p1, &p2 ) );
-
+ Point p1,
+ p2;
+
+ p1.x = box->high.x;
+ p1.y = box->high.y;
+ p2.x = box->low.x;
+ p2.y = box->low.y;
+ return (lseg_construct(&p1, &p2));
+
}
/***********************************************************************
**
- ** Routines for 2D lines.
- ** Lines are not intended to be used as ADTs per se,
- ** but their ops are useful tools for other ADT ops. Thus,
- ** there are few relops.
+ ** Routines for 2D lines.
+ ** Lines are not intended to be used as ADTs per se,
+ ** but their ops are useful tools for other ADT ops. Thus,
+ ** there are few relops.
**
***********************************************************************/
/*----------------------------------------------------------
- * Conversion routines from one line formula to internal.
- * Internal form: Ax+By+C=0
+ * Conversion routines from one line formula to internal.
+ * Internal form: Ax+By+C=0
*---------------------------------------------------------*/
-static LINE * /* point-slope */
-line_construct_pm(Point *pt, double m)
+static LINE * /* point-slope */
+line_construct_pm(Point * pt, double m)
{
- LINE *result = PALLOCTYPE(LINE);
+ LINE *result = PALLOCTYPE(LINE);
- /* use "mx - y + yinter = 0" */
- result->A = m;
- result->B = -1.0;
- result->C = pt->y - m * pt->x;
+ /* use "mx - y + yinter = 0" */
+ result->A = m;
+ result->B = -1.0;
+ result->C = pt->y - m * pt->x;
- result->m = m;
+ result->m = m;
- return(result);
-} /* line_construct_pm() */
+ return (result);
+} /* line_construct_pm() */
-static LINE * /* two points */
-line_construct_pp(Point *pt1, Point *pt2)
+static LINE * /* two points */
+line_construct_pp(Point * pt1, Point * pt2)
{
- LINE *result = PALLOCTYPE(LINE);
+ LINE *result = PALLOCTYPE(LINE);
- if (FPeq(pt1->x, pt2->x)) { /* vertical */
- /* use "x = C" */
- result->A = -1;
- result->B = 0;
- result->C = pt1->x;
+ if (FPeq(pt1->x, pt2->x))
+ { /* vertical */
+ /* use "x = C" */
+ result->A = -1;
+ result->B = 0;
+ result->C = pt1->x;
#ifdef GEODEBUG
-printf( "line_construct_pp- line is vertical\n");
+ printf("line_construct_pp- line is vertical\n");
#endif
- result->m = DBL_MAX;
+ result->m = DBL_MAX;
- } else if (FPeq(pt1->y, pt2->y)) { /* horizontal */
- /* use "x = C" */
- result->A = 0;
- result->B = -1;
- result->C = pt1->y;
+ }
+ else if (FPeq(pt1->y, pt2->y))
+ { /* horizontal */
+ /* use "x = C" */
+ result->A = 0;
+ result->B = -1;
+ result->C = pt1->y;
#ifdef GEODEBUG
-printf( "line_construct_pp- line is horizontal\n");
+ printf("line_construct_pp- line is horizontal\n");
#endif
- result->m = 0.0;
+ result->m = 0.0;
- } else {
- /* use "mx - y + yinter = 0" */
+ }
+ else
+ {
+ /* use "mx - y + yinter = 0" */
#if FALSE
- result->A = (pt1->y - pt2->y) / (pt1->x - pt2->x);
+ result->A = (pt1->y - pt2->y) / (pt1->x - pt2->x);
#endif
- result->A = (pt2->y - pt1->y) / (pt2->x - pt1->x);
- result->B = -1.0;
- result->C = pt1->y - result->A * pt1->x;
+ result->A = (pt2->y - pt1->y) / (pt2->x - pt1->x);
+ result->B = -1.0;
+ result->C = pt1->y - result->A * pt1->x;
#ifdef GEODEBUG
-printf( "line_construct_pp- line is neither vertical nor horizontal (diffs x=%.*g, y=%.*g\n",
- digits8, (pt2->x - pt1->x), digits8, (pt2->y - pt1->y));
+ printf("line_construct_pp- line is neither vertical nor horizontal (diffs x=%.*g, y=%.*g\n",
+ digits8, (pt2->x - pt1->x), digits8, (pt2->y - pt1->y));
#endif
- result->m = result->A;
- }
- return(result);
-} /* line_construct_pp() */
+ result->m = result->A;
+ }
+ return (result);
+} /* line_construct_pp() */
/*----------------------------------------------------------
- * Relative position routines.
+ * Relative position routines.
*---------------------------------------------------------*/
-static bool line_intersect(LINE *l1, LINE *l2)
+static bool
+line_intersect(LINE * l1, LINE * l2)
{
- return( ! line_parallel(l1, l2) );
+ return (!line_parallel(l1, l2));
}
-static bool line_parallel(LINE *l1, LINE *l2)
+static bool
+line_parallel(LINE * l1, LINE * l2)
{
#if FALSE
- return( FPeq(l1->m, l2->m) );
+ return (FPeq(l1->m, l2->m));
#endif
- if (FPzero(l1->B)) {
- return(FPzero(l2->B));
- }
+ if (FPzero(l1->B))
+ {
+ return (FPzero(l2->B));
+ }
- return(FPeq(l2->A, l1->A*(l2->B / l1->B)));
-} /* line_parallel() */
+ return (FPeq(l2->A, l1->A * (l2->B / l1->B)));
+} /* line_parallel() */
#ifdef NOT_USED
-bool line_perp(LINE *l1, LINE *l2)
+bool
+line_perp(LINE * l1, LINE * l2)
{
#if FALSE
- if (l1->m)
- return( FPeq(l2->m / l1->m, -1.0) );
- else if (l2->m)
- return( FPeq(l1->m / l2->m, -1.0) );
+ if (l1->m)
+ return (FPeq(l2->m / l1->m, -1.0));
+ else if (l2->m)
+ return (FPeq(l1->m / l2->m, -1.0));
#endif
- if (FPzero(l1->A)) {
- return( FPzero(l2->B) );
- } else if (FPzero(l1->B)) {
- return( FPzero(l2->A) );
- }
-
- return( FPeq(((l1->A * l2->B) / (l1->B * l2->A)), -1.0) );
-} /* line_perp() */
+ if (FPzero(l1->A))
+ {
+ return (FPzero(l2->B));
+ }
+ else if (FPzero(l1->B))
+ {
+ return (FPzero(l2->A));
+ }
+
+ return (FPeq(((l1->A * l2->B) / (l1->B * l2->A)), -1.0));
+} /* line_perp() */
+
#endif
-static bool line_vertical(LINE *line)
+static bool
+line_vertical(LINE * line)
{
#if FALSE
- return( FPeq(line->A, -1.0) && FPzero(line->B) );
+ return (FPeq(line->A, -1.0) && FPzero(line->B));
#endif
- return( FPzero(line->B) );
-} /* line_vertical() */
+ return (FPzero(line->B));
+} /* line_vertical() */
-static bool line_horizontal(LINE *line)
+static bool
+line_horizontal(LINE * line)
{
#if FALSE
- return( FPzero(line->m) );
+ return (FPzero(line->m));
#endif
- return( FPzero(line->A) );
-} /* line_horizontal() */
+ return (FPzero(line->A));
+} /* line_horizontal() */
#ifdef NOT_USED
-bool line_eq(LINE *l1, LINE *l2)
-{
- double k;
-
- if (! FPzero(l2->A))
- k = l1->A / l2->A;
- else if (! FPzero(l2->B))
- k = l1->B / l2->B;
- else if (! FPzero(l2->C))
- k = l1->C / l2->C;
- else
- k = 1.0;
-
- return( FPeq(l1->A, k * l2->A) &&
- FPeq(l1->B, k * l2->B) &&
- FPeq(l1->C, k * l2->C) );
+bool
+line_eq(LINE * l1, LINE * l2)
+{
+ double k;
+
+ if (!FPzero(l2->A))
+ k = l1->A / l2->A;
+ else if (!FPzero(l2->B))
+ k = l1->B / l2->B;
+ else if (!FPzero(l2->C))
+ k = l1->C / l2->C;
+ else
+ k = 1.0;
+
+ return (FPeq(l1->A, k * l2->A) &&
+ FPeq(l1->B, k * l2->B) &&
+ FPeq(l1->C, k * l2->C));
}
+
#endif
/*----------------------------------------------------------
- * Line arithmetic routines.
+ * Line arithmetic routines.
*---------------------------------------------------------*/
-double * /* distance between l1, l2 */
-line_distance(LINE *l1, LINE *l2)
-{
- double *result = PALLOCTYPE(double);
- Point *tmp;
-
- if (line_intersect(l1, l2)) {
- *result = 0.0;
- return(result);
- }
- if (line_vertical(l1))
- *result = fabs(l1->C - l2->C);
- else {
- tmp = point_construct(0.0, l1->C);
- result = dist_pl(tmp, l2);
- PFREE(tmp);
- }
- return(result);
+double * /* distance between l1, l2 */
+line_distance(LINE * l1, LINE * l2)
+{
+ double *result = PALLOCTYPE(double);
+ Point *tmp;
+
+ if (line_intersect(l1, l2))
+ {
+ *result = 0.0;
+ return (result);
+ }
+ if (line_vertical(l1))
+ *result = fabs(l1->C - l2->C);
+ else
+ {
+ tmp = point_construct(0.0, l1->C);
+ result = dist_pl(tmp, l2);
+ PFREE(tmp);
+ }
+ return (result);
}
/* line_interpt()
* Point where two lines l1, l2 intersect (if any)
*/
-static Point *
-line_interpt(LINE *l1, LINE *l2)
+static Point *
+line_interpt(LINE * l1, LINE * l2)
{
- Point *result;
- double x, y;
-
- if (line_parallel(l1, l2))
- return(NULL);
+ Point *result;
+ double x,
+ y;
+
+ if (line_parallel(l1, l2))
+ return (NULL);
#if FALSE
- if (line_vertical(l1))
- result = point_construct(l2->m * l1->C + l2->C, l1->C);
- else if (line_vertical(l2))
- result = point_construct(l1->m * l2->C + l1->C, l2->C);
- else {
- x = (l1->C - l2->C) / (l2->A - l1->A);
- result = point_construct(x, l1->m * x + l1->C);
- }
+ if (line_vertical(l1))
+ result = point_construct(l2->m * l1->C + l2->C, l1->C);
+ else if (line_vertical(l2))
+ result = point_construct(l1->m * l2->C + l1->C, l2->C);
+ else
+ {
+ x = (l1->C - l2->C) / (l2->A - l1->A);
+ result = point_construct(x, l1->m * x + l1->C);
+ }
#endif
- if (line_vertical(l1)) {
+ if (line_vertical(l1))
+ {
#if FALSE
- x = l1->C;
- y = -((l2->A * x + l2->C) / l2->B);
+ x = l1->C;
+ y = -((l2->A * x + l2->C) / l2->B);
#endif
- x = l1->C;
- y = (l2->A * x + l2->C);
+ x = l1->C;
+ y = (l2->A * x + l2->C);
- } else if (line_vertical(l2)) {
+ }
+ else if (line_vertical(l2))
+ {
#if FALSE
- x = l2->C;
- y = -((l1->A * x + l1->C) / l1->B);
+ x = l2->C;
+ y = -((l1->A * x + l1->C) / l1->B);
#endif
- x = l2->C;
- y = (l1->A * x + l1->C);
+ x = l2->C;
+ y = (l1->A * x + l1->C);
- } else {
+ }
+ else
+ {
#if FALSE
- x = (l2->B * l1->C - l1->B * l2->C) / (l2->A * l1->B - l1->A * l2->B);
- y = -((l1->A * x + l1->C) / l1->B);
+ x = (l2->B * l1->C - l1->B * l2->C) / (l2->A * l1->B - l1->A * l2->B);
+ y = -((l1->A * x + l1->C) / l1->B);
#endif
- x = (l1->C - l2->C) / (l2->A - l1->A);
- y = (l1->A * x + l1->C);
- }
- result = point_construct(x, y);
+ x = (l1->C - l2->C) / (l2->A - l1->A);
+ y = (l1->A * x + l1->C);
+ }
+ result = point_construct(x, y);
#ifdef GEODEBUG
-printf( "line_interpt- lines are A=%.*g, B=%.*g, C=%.*g, A=%.*g, B=%.*g, C=%.*g\n",
- digits8, l1->A, digits8, l1->B, digits8, l1->C, digits8, l2->A, digits8, l2->B, digits8, l2->C);
-printf( "line_interpt- lines intersect at (%.*g,%.*g)\n", digits8, x, digits8, y);
+ printf("line_interpt- lines are A=%.*g, B=%.*g, C=%.*g, A=%.*g, B=%.*g, C=%.*g\n",
+ digits8, l1->A, digits8, l1->B, digits8, l1->C, digits8, l2->A, digits8, l2->B, digits8, l2->C);
+ printf("line_interpt- lines intersect at (%.*g,%.*g)\n", digits8, x, digits8, y);
#endif
- return(result);
-} /* line_interpt() */
+ return (result);
+} /* line_interpt() */
/***********************************************************************
**
- ** Routines for 2D paths (sequences of line segments, also
- ** called `polylines').
+ ** Routines for 2D paths (sequences of line segments, also
+ ** called `polylines').
**
- ** This is not a general package for geometric paths,
- ** which of course include polygons; the emphasis here
- ** is on (for example) usefulness in wire layout.
+ ** This is not a general package for geometric paths,
+ ** which of course include polygons; the emphasis here
+ ** is on (for example) usefulness in wire layout.
**
***********************************************************************/
/*----------------------------------------------------------
- * String to path / path to string conversion.
- * External format:
- * "((xcoord, ycoord),... )"
- * "[(xcoord, ycoord),... ]"
- * "(xcoord, ycoord),... "
- * "[xcoord, ycoord,... ]"
- * Also support older format:
- * "(closed, npts, xcoord, ycoord,... )"
+ * String to path / path to string conversion.
+ * External format:
+ * "((xcoord, ycoord),... )"
+ * "[(xcoord, ycoord),... ]"
+ * "(xcoord, ycoord),... "
+ * "[xcoord, ycoord,... ]"
+ * Also support older format:
+ * "(closed, npts, xcoord, ycoord,... )"
*---------------------------------------------------------*/
-PATH *path_in(char *str)
+PATH *
+path_in(char *str)
{
- PATH *path;
+ PATH *path;
- int isopen;
- char *s;
- int npts;
- int size;
- int depth = 0;
+ int isopen;
+ char *s;
+ int npts;
+ int size;
+ int depth = 0;
- if (!PointerIsValid(str))
- elog(WARN, "Bad (null) path external representation");
+ if (!PointerIsValid(str))
+ elog(WARN, "Bad (null) path external representation");
- if ((npts = pair_count(str, ',')) <= 0)
- elog(WARN, "Bad path external representation '%s'", str);
+ if ((npts = pair_count(str, ',')) <= 0)
+ elog(WARN, "Bad path external representation '%s'", str);
- s = str;
- while (isspace( *s)) s++;
+ s = str;
+ while (isspace(*s))
+ s++;
- /* skip single leading paren */
- if ((*s == LDELIM) && (strrchr( s, LDELIM) == s)) {
- s++;
- depth++;
- }
+ /* skip single leading paren */
+ if ((*s == LDELIM) && (strrchr(s, LDELIM) == s))
+ {
+ s++;
+ depth++;
+ }
- size = offsetof(PATH, p[0]) + (sizeof(path->p[0]) * npts);
- path = PALLOC(size);
+ size = offsetof(PATH, p[0]) + (sizeof(path->p[0]) * npts);
+ path = PALLOC(size);
- path->size = size;
- path->npts = npts;
+ path->size = size;
+ path->npts = npts;
- if ((!path_decode(TRUE, npts, s, &isopen, &s, &(path->p[0])))
- && (!((depth == 0) && (*s == '\0'))) && !((depth >= 1) && (*s == RDELIM)))
- elog (WARN, "Bad path external representation '%s'",str);
+ if ((!path_decode(TRUE, npts, s, &isopen, &s, &(path->p[0])))
+ && (!((depth == 0) && (*s == '\0'))) && !((depth >= 1) && (*s == RDELIM)))
+ elog(WARN, "Bad path external representation '%s'", str);
- path->closed = (! isopen);
+ path->closed = (!isopen);
- return(path);
-} /* path_in() */
+ return (path);
+} /* path_in() */
-char *path_out(PATH *path)
+char *
+path_out(PATH * path)
{
- if (!PointerIsValid(path))
- return NULL;
+ if (!PointerIsValid(path))
+ return NULL;
- return( path_encode( path->closed, path->npts, (Point *) &(path->p[0])));
-} /* path_out() */
+ return (path_encode(path->closed, path->npts, (Point *) & (path->p[0])));
+} /* path_out() */
/*----------------------------------------------------------
- * Relational operators.
- * These are based on the path cardinality,
- * as stupid as that sounds.
+ * Relational operators.
+ * These are based on the path cardinality,
+ * as stupid as that sounds.
*
- * Better relops and access methods coming soon.
+ * Better relops and access methods coming soon.
*---------------------------------------------------------*/
-bool path_n_lt(PATH *p1, PATH *p2)
+bool
+path_n_lt(PATH * p1, PATH * p2)
{
- return( (p1->npts < p2->npts ) );
+ return ((p1->npts < p2->npts));
}
-bool path_n_gt(PATH *p1, PATH *p2)
+bool
+path_n_gt(PATH * p1, PATH * p2)
{
- return( (p1->npts > p2->npts ) );
+ return ((p1->npts > p2->npts));
}
-bool path_n_eq(PATH *p1, PATH *p2)
+bool
+path_n_eq(PATH * p1, PATH * p2)
{
- return( (p1->npts == p2->npts) );
+ return ((p1->npts == p2->npts));
}
-bool path_n_le(PATH *p1, PATH *p2)
+bool
+path_n_le(PATH * p1, PATH * p2)
{
- return( (p1->npts <= p2->npts ) );
+ return ((p1->npts <= p2->npts));
}
-bool path_n_ge(PATH *p1, PATH *p2)
+bool
+path_n_ge(PATH * p1, PATH * p2)
{
- return( (p1->npts >= p2->npts ) );
+ return ((p1->npts >= p2->npts));
}
@@ -1012,1206 +1138,1350 @@ bool path_n_ge(PATH *p1, PATH *p2)
*---------------------------------------------------------*/
bool
-path_isclosed( PATH *path)
+path_isclosed(PATH * path)
{
- if (!PointerIsValid(path))
- return FALSE;
+ if (!PointerIsValid(path))
+ return FALSE;
- return(path->closed);
-} /* path_isclosed() */
+ return (path->closed);
+} /* path_isclosed() */
bool
-path_isopen( PATH *path)
+path_isopen(PATH * path)
{
- if (!PointerIsValid(path))
- return FALSE;
+ if (!PointerIsValid(path))
+ return FALSE;
- return(! path->closed);
-} /* path_isopen() */
+ return (!path->closed);
+} /* path_isopen() */
int4
-path_npoints( PATH *path)
+path_npoints(PATH * path)
{
- if (!PointerIsValid(path))
- return 0;
+ if (!PointerIsValid(path))
+ return 0;
- return(path->npts);
-} /* path_npoints() */
+ return (path->npts);
+} /* path_npoints() */
-PATH *
-path_close(PATH *path)
+PATH *
+path_close(PATH * path)
{
- PATH *result;
+ PATH *result;
- if (!PointerIsValid(path))
- return(NULL);
+ if (!PointerIsValid(path))
+ return (NULL);
- result = path_copy(path);
- result->closed = TRUE;
+ result = path_copy(path);
+ result->closed = TRUE;
- return(result);
-} /* path_close() */
+ return (result);
+} /* path_close() */
-PATH *
-path_open(PATH *path)
+PATH *
+path_open(PATH * path)
{
- PATH *result;
+ PATH *result;
- if (!PointerIsValid(path))
- return(NULL);
+ if (!PointerIsValid(path))
+ return (NULL);
- result = path_copy(path);
- result->closed = FALSE;
+ result = path_copy(path);
+ result->closed = FALSE;
- return(result);
-} /* path_open() */
+ return (result);
+} /* path_open() */
-PATH *
-path_copy(PATH *path)
+PATH *
+path_copy(PATH * path)
{
- PATH *result;
- int size;
+ PATH *result;
+ int size;
- size = offsetof(PATH, p[0]) + (sizeof(path->p[0]) * path->npts);
- result = PALLOC(size);
+ size = offsetof(PATH, p[0]) + (sizeof(path->p[0]) * path->npts);
+ result = PALLOC(size);
- memmove((char *) result, (char *) path, size);
- return(result);
-} /* path_copy() */
+ memmove((char *) result, (char *) path, size);
+ return (result);
+} /* path_copy() */
/* path_inter -
- * Does p1 intersect p2 at any point?
- * Use bounding boxes for a quick (O(n)) check, then do a
- * O(n^2) iterative edge check.
- */
-bool path_inter(PATH *p1, PATH *p2)
-{
- BOX b1, b2;
- int i, j;
- LSEG seg1, seg2;
-
- b1.high.x = b1.low.x = p1->p[0].x;
- b1.high.y = b1.low.y = p1->p[0].y;
- for (i = 1; i < p1->npts; i++) {
- b1.high.x = Max(p1->p[i].x, b1.high.x);
- b1.high.y = Max(p1->p[i].y, b1.high.y);
- b1.low.x = Min(p1->p[i].x, b1.low.x);
- b1.low.y = Min(p1->p[i].y, b1.low.y);
- }
- b2.high.x = b2.low.x = p2->p[0].x;
- b2.high.y = b2.low.y = p2->p[0].y;
- for (i = 1; i < p2->npts; i++) {
- b2.high.x = Max(p2->p[i].x, b2.high.x);
- b2.high.y = Max(p2->p[i].y, b2.high.y);
- b2.low.x = Min(p2->p[i].x, b2.low.x);
- b2.low.y = Min(p2->p[i].y, b2.low.y);
- }
- if (! box_overlap(&b1, &b2))
- return(0);
-
- /* pairwise check lseg intersections */
- for (i = 0; i < p1->npts - 1; i++) {
- for (j = 0; j < p2->npts - 1; j++) {
- statlseg_construct(&seg1, &p1->p[i], &p1->p[i+1]);
- statlseg_construct(&seg2, &p2->p[j], &p2->p[j+1]);
- if (lseg_intersect(&seg1, &seg2))
- return(1);
- }
- }
-
- /* if we dropped through, no two segs intersected */
- return(0);
+ * Does p1 intersect p2 at any point?
+ * Use bounding boxes for a quick (O(n)) check, then do a
+ * O(n^2) iterative edge check.
+ */
+bool
+path_inter(PATH * p1, PATH * p2)
+{
+ BOX b1,
+ b2;
+ int i,
+ j;
+ LSEG seg1,
+ seg2;
+
+ b1.high.x = b1.low.x = p1->p[0].x;
+ b1.high.y = b1.low.y = p1->p[0].y;
+ for (i = 1; i < p1->npts; i++)
+ {
+ b1.high.x = Max(p1->p[i].x, b1.high.x);
+ b1.high.y = Max(p1->p[i].y, b1.high.y);
+ b1.low.x = Min(p1->p[i].x, b1.low.x);
+ b1.low.y = Min(p1->p[i].y, b1.low.y);
+ }
+ b2.high.x = b2.low.x = p2->p[0].x;
+ b2.high.y = b2.low.y = p2->p[0].y;
+ for (i = 1; i < p2->npts; i++)
+ {
+ b2.high.x = Max(p2->p[i].x, b2.high.x);
+ b2.high.y = Max(p2->p[i].y, b2.high.y);
+ b2.low.x = Min(p2->p[i].x, b2.low.x);
+ b2.low.y = Min(p2->p[i].y, b2.low.y);
+ }
+ if (!box_overlap(&b1, &b2))
+ return (0);
+
+ /* pairwise check lseg intersections */
+ for (i = 0; i < p1->npts - 1; i++)
+ {
+ for (j = 0; j < p2->npts - 1; j++)
+ {
+ statlseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);
+ statlseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);
+ if (lseg_intersect(&seg1, &seg2))
+ return (1);
+ }
+ }
+
+ /* if we dropped through, no two segs intersected */
+ return (0);
}
/* this essentially does a cartesian product of the lsegs in the
two paths, and finds the min distance between any two lsegs */
-double *path_distance(PATH *p1, PATH *p2)
+double *
+path_distance(PATH * p1, PATH * p2)
{
- double *min = NULL, *tmp;
- int i,j;
- LSEG seg1, seg2;
+ double *min = NULL,
+ *tmp;
+ int i,
+ j;
+ LSEG seg1,
+ seg2;
/*
- statlseg_construct(&seg1, &p1->p[0], &p1->p[1]);
- statlseg_construct(&seg2, &p2->p[0], &p2->p[1]);
- min = lseg_distance(&seg1, &seg2);
+ statlseg_construct(&seg1, &p1->p[0], &p1->p[1]);
+ statlseg_construct(&seg2, &p2->p[0], &p2->p[1]);
+ min = lseg_distance(&seg1, &seg2);
*/
- for (i = 0; i < p1->npts - 1; i++)
- for (j = 0; j < p2->npts - 1; j++)
- {
- statlseg_construct(&seg1, &p1->p[i], &p1->p[i+1]);
- statlseg_construct(&seg2, &p2->p[j], &p2->p[j+1]);
-
- tmp = lseg_distance(&seg1, &seg2);
- if ((min == NULL) || (*min < *tmp)) {
- if (min != NULL) PFREE(min);
- min = tmp;
- } else {
- PFREE(tmp);
+ for (i = 0; i < p1->npts - 1; i++)
+ for (j = 0; j < p2->npts - 1; j++)
+ {
+ statlseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);
+ statlseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);
+
+ tmp = lseg_distance(&seg1, &seg2);
+ if ((min == NULL) || (*min < *tmp))
+ {
+ if (min != NULL)
+ PFREE(min);
+ min = tmp;
+ }
+ else
+ {
+ PFREE(tmp);
+ }
}
- }
- return(min);
+ return (min);
}
/*----------------------------------------------------------
- * "Arithmetic" operations.
+ * "Arithmetic" operations.
*---------------------------------------------------------*/
-double *path_length(PATH *path)
+double *
+path_length(PATH * path)
{
- double *result;
- int i;
+ double *result;
+ int i;
- result = PALLOCTYPE(double);
+ result = PALLOCTYPE(double);
- *result = 0;
- for (i = 0; i < (path->npts - 1); i++)
- *result += point_dt(&path->p[i], &path->p[i+1]);
+ *result = 0;
+ for (i = 0; i < (path->npts - 1); i++)
+ *result += point_dt(&path->p[i], &path->p[i + 1]);
- return(result);
-} /* path_length() */
+ return (result);
+} /* path_length() */
#ifdef NOT_USED
-double path_ln(PATH *path)
+double
+path_ln(PATH * path)
{
- double result;
- int i;
+ double result;
+ int i;
- result = 0;
- for (i = 0; i < (path->npts - 1); i++)
- result += point_dt(&path->p[i], &path->p[i+1]);
+ result = 0;
+ for (i = 0; i < (path->npts - 1); i++)
+ result += point_dt(&path->p[i], &path->p[i + 1]);
+
+ return (result);
+} /* path_ln() */
- return(result);
-} /* path_ln() */
#endif
/***********************************************************************
**
- ** Routines for 2D points.
+ ** Routines for 2D points.
**
***********************************************************************/
/*----------------------------------------------------------
- * String to point, point to string conversion.
- * External format:
- * "(x,y)"
- * "x,y"
+ * String to point, point to string conversion.
+ * External format:
+ * "(x,y)"
+ * "x,y"
*---------------------------------------------------------*/
-Point *
+Point *
point_in(char *str)
{
- Point *point;
+ Point *point;
+
+ double x,
+ y;
+ char *s;
- double x, y;
- char *s;
-
- if (! PointerIsValid( str))
- elog(WARN, "Bad (null) point external representation");
+ if (!PointerIsValid(str))
+ elog(WARN, "Bad (null) point external representation");
- if (! pair_decode( str, &x, &y, &s) || (strlen(s) > 0))
- elog (WARN, "Bad point external representation '%s'",str);
+ if (!pair_decode(str, &x, &y, &s) || (strlen(s) > 0))
+ elog(WARN, "Bad point external representation '%s'", str);
- point = PALLOCTYPE(Point);
+ point = PALLOCTYPE(Point);
- point->x = x;
- point->y = y;
+ point->x = x;
+ point->y = y;
- return(point);
-} /* point_in() */
+ return (point);
+} /* point_in() */
-char *
-point_out(Point *pt)
+char *
+point_out(Point * pt)
{
- if (! PointerIsValid(pt))
- return(NULL);
+ if (!PointerIsValid(pt))
+ return (NULL);
- return( path_encode( -1, 1, pt));
-} /* point_out() */
+ return (path_encode(-1, 1, pt));
+} /* point_out() */
-static Point *point_construct(double x, double y)
+static Point *
+point_construct(double x, double y)
{
- Point *result = PALLOCTYPE(Point);
+ Point *result = PALLOCTYPE(Point);
- result->x = x;
- result->y = y;
- return(result);
+ result->x = x;
+ result->y = y;
+ return (result);
}
-static Point *point_copy(Point *pt)
+static Point *
+point_copy(Point * pt)
{
- Point *result;
+ Point *result;
- if (! PointerIsValid( pt))
- return(NULL);
+ if (!PointerIsValid(pt))
+ return (NULL);
- result = PALLOCTYPE(Point);
+ result = PALLOCTYPE(Point);
- result->x = pt->x;
- result->y = pt->y;
- return(result);
+ result->x = pt->x;
+ result->y = pt->y;
+ return (result);
}
/*----------------------------------------------------------
- * Relational operators for Points.
- * Since we do have a sense of coordinates being
- * "equal" to a given accuracy (point_vert, point_horiz),
- * the other ops must preserve that sense. This means
- * that results may, strictly speaking, be a lie (unless
- * EPSILON = 0.0).
+ * Relational operators for Points.
+ * Since we do have a sense of coordinates being
+ * "equal" to a given accuracy (point_vert, point_horiz),
+ * the other ops must preserve that sense. This means
+ * that results may, strictly speaking, be a lie (unless
+ * EPSILON = 0.0).
*---------------------------------------------------------*/
-bool point_left(Point *pt1, Point *pt2)
+bool
+point_left(Point * pt1, Point * pt2)
{
- return( FPlt(pt1->x, pt2->x) );
+ return (FPlt(pt1->x, pt2->x));
}
-bool point_right(Point *pt1, Point *pt2)
+bool
+point_right(Point * pt1, Point * pt2)
{
- return( FPgt(pt1->x, pt2->x) );
+ return (FPgt(pt1->x, pt2->x));
}
-bool point_above(Point *pt1, Point *pt2)
+bool
+point_above(Point * pt1, Point * pt2)
{
- return( FPgt(pt1->y, pt2->y) );
+ return (FPgt(pt1->y, pt2->y));
}
-bool point_below(Point *pt1, Point *pt2)
+bool
+point_below(Point * pt1, Point * pt2)
{
- return( FPlt(pt1->y, pt2->y) );
+ return (FPlt(pt1->y, pt2->y));
}
-bool point_vert(Point *pt1, Point *pt2)
+bool
+point_vert(Point * pt1, Point * pt2)
{
- return( FPeq( pt1->x, pt2->x ) );
+ return (FPeq(pt1->x, pt2->x));
}
-bool point_horiz(Point *pt1, Point *pt2)
+bool
+point_horiz(Point * pt1, Point * pt2)
{
- return( FPeq( pt1->y, pt2->y ) );
+ return (FPeq(pt1->y, pt2->y));
}
-bool point_eq(Point *pt1, Point *pt2)
+bool
+point_eq(Point * pt1, Point * pt2)
{
- return( point_horiz(pt1, pt2) && point_vert(pt1, pt2) );
+ return (point_horiz(pt1, pt2) && point_vert(pt1, pt2));
}
/*----------------------------------------------------------
- * "Arithmetic" operators on points.
+ * "Arithmetic" operators on points.
*---------------------------------------------------------*/
-int32 pointdist(Point *p1, Point *p2)
+int32
+pointdist(Point * p1, Point * p2)
{
- int32 result;
-
- result = point_dt(p1, p2);
- return(result);
+ int32 result;
+
+ result = point_dt(p1, p2);
+ return (result);
}
-double *point_distance(Point *pt1, Point *pt2)
+double *
+point_distance(Point * pt1, Point * pt2)
{
- double *result = PALLOCTYPE(double);
+ double *result = PALLOCTYPE(double);
- *result = HYPOT( pt1->x - pt2->x, pt1->y - pt2->y );
- return(result);
+ *result = HYPOT(pt1->x - pt2->x, pt1->y - pt2->y);
+ return (result);
}
-double point_dt(Point *pt1, Point *pt2)
+double
+point_dt(Point * pt1, Point * pt2)
{
- return( HYPOT( pt1->x - pt2->x, pt1->y - pt2->y ) );
+ return (HYPOT(pt1->x - pt2->x, pt1->y - pt2->y));
}
-double *point_slope(Point *pt1, Point *pt2)
+double *
+point_slope(Point * pt1, Point * pt2)
{
- double *result = PALLOCTYPE(double);
+ double *result = PALLOCTYPE(double);
- if (point_vert(pt1, pt2))
- *result = (double)DBL_MAX;
- else
- *result = (pt1->y - pt2->y) / (pt1->x - pt1->x);
- return(result);
+ if (point_vert(pt1, pt2))
+ *result = (double) DBL_MAX;
+ else
+ *result = (pt1->y - pt2->y) / (pt1->x - pt1->x);
+ return (result);
}
-double point_sl(Point *pt1, Point *pt2)
+double
+point_sl(Point * pt1, Point * pt2)
{
- return( point_vert(pt1, pt2)
- ? (double)DBL_MAX
- : (pt1->y - pt2->y) / (pt1->x - pt2->x) );
+ return (point_vert(pt1, pt2)
+ ? (double) DBL_MAX
+ : (pt1->y - pt2->y) / (pt1->x - pt2->x));
}
/***********************************************************************
**
- ** Routines for 2D line segments.
+ ** Routines for 2D line segments.
**
***********************************************************************/
/*----------------------------------------------------------
- * String to lseg, lseg to string conversion.
- * External forms: "[(x1, y1), (x2, y2)]"
- * "(x1, y1), (x2, y2)"
- * "x1, y1, x2, y2"
- * closed form ok "((x1, y1), (x2, y2))"
- * (old form) "(x1, y1, x2, y2)"
+ * String to lseg, lseg to string conversion.
+ * External forms: "[(x1, y1), (x2, y2)]"
+ * "(x1, y1), (x2, y2)"
+ * "x1, y1, x2, y2"
+ * closed form ok "((x1, y1), (x2, y2))"
+ * (old form) "(x1, y1, x2, y2)"
*---------------------------------------------------------*/
-LSEG *lseg_in(char *str)
+LSEG *
+lseg_in(char *str)
{
- LSEG *lseg;
+ LSEG *lseg;
+
+ int isopen;
+ char *s;
- int isopen;
- char *s;
+ if (!PointerIsValid(str))
+ elog(WARN, " Bad (null) lseg external representation", NULL);
- if (!PointerIsValid(str))
- elog (WARN," Bad (null) lseg external representation",NULL);
+ lseg = PALLOCTYPE(LSEG);
- lseg = PALLOCTYPE(LSEG);
+ if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg->p[0])))
+ || (*s != '\0'))
+ elog(WARN, "Bad lseg external representation '%s'", str);
- if ((! path_decode(TRUE, 2, str, &isopen, &s, &(lseg->p[0])))
- || (*s != '\0'))
- elog (WARN, "Bad lseg external representation '%s'",str);
+ lseg->m = point_sl(&lseg->p[0], &lseg->p[1]);
- lseg->m = point_sl(&lseg->p[0], &lseg->p[1]);
-
- return(lseg);
-} /* lseg_in() */
+ return (lseg);
+} /* lseg_in() */
-char *lseg_out(LSEG *ls)
+char *
+lseg_out(LSEG * ls)
{
- if (!PointerIsValid(ls))
- return(NULL);
+ if (!PointerIsValid(ls))
+ return (NULL);
- return( path_encode( FALSE, 2, (Point *) &(ls->p[0])));
-} /* lseg_out() */
+ return (path_encode(FALSE, 2, (Point *) & (ls->p[0])));
+} /* lseg_out() */
/* lseg_construct -
- * form a LSEG from two Points.
+ * form a LSEG from two Points.
*/
-LSEG *lseg_construct(Point *pt1, Point *pt2)
+LSEG *
+lseg_construct(Point * pt1, Point * pt2)
{
- LSEG *result = PALLOCTYPE(LSEG);
+ LSEG *result = PALLOCTYPE(LSEG);
- result->p[0].x = pt1->x;
- result->p[0].y = pt1->y;
- result->p[1].x = pt2->x;
- result->p[1].y = pt2->y;
+ result->p[0].x = pt1->x;
+ result->p[0].y = pt1->y;
+ result->p[1].x = pt2->x;
+ result->p[1].y = pt2->y;
- result->m = point_sl(pt1, pt2);
-
- return(result);
+ result->m = point_sl(pt1, pt2);
+
+ return (result);
}
/* like lseg_construct, but assume space already allocated */
-static void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2)
+static void
+statlseg_construct(LSEG * lseg, Point * pt1, Point * pt2)
{
- lseg->p[0].x = pt1->x;
- lseg->p[0].y = pt1->y;
- lseg->p[1].x = pt2->x;
- lseg->p[1].y = pt2->y;
+ lseg->p[0].x = pt1->x;
+ lseg->p[0].y = pt1->y;
+ lseg->p[1].x = pt2->x;
+ lseg->p[1].y = pt2->y;
- lseg->m = point_sl(pt1, pt2);
+ lseg->m = point_sl(pt1, pt2);
}
/*----------------------------------------------------------
- * Relative position routines.
+ * Relative position routines.
*---------------------------------------------------------*/
/*
- ** find intersection of the two lines, and see if it falls on
+ ** find intersection of the two lines, and see if it falls on
** both segments.
*/
-bool lseg_intersect(LSEG *l1, LSEG *l2)
-{
- LINE *ln;
- Point *interpt;
- bool retval;
-
- ln = line_construct_pp(&l2->p[0], &l2->p[1]);
- interpt = interpt_sl(l1, ln);
-
- if (interpt != NULL && on_ps(interpt, l2)) /* interpt on l1 and l2 */
- retval = TRUE;
- else retval = FALSE;
- if (interpt != NULL) PFREE(interpt);
- PFREE(ln);
- return(retval);
+bool
+lseg_intersect(LSEG * l1, LSEG * l2)
+{
+ LINE *ln;
+ Point *interpt;
+ bool retval;
+
+ ln = line_construct_pp(&l2->p[0], &l2->p[1]);
+ interpt = interpt_sl(l1, ln);
+
+ if (interpt != NULL && on_ps(interpt, l2)) /* interpt on l1 and l2 */
+ retval = TRUE;
+ else
+ retval = FALSE;
+ if (interpt != NULL)
+ PFREE(interpt);
+ PFREE(ln);
+ return (retval);
}
-bool lseg_parallel(LSEG *l1, LSEG *l2)
+bool
+lseg_parallel(LSEG * l1, LSEG * l2)
{
#if FALSE
- return( FPeq(l1->m, l2->m) );
+ return (FPeq(l1->m, l2->m));
#endif
- return( FPeq( point_sl( &(l1->p[0]), &(l1->p[1])),
- point_sl( &(l2->p[0]), &(l2->p[1]))) );
-} /* lseg_parallel() */
+ return (FPeq(point_sl(&(l1->p[0]), &(l1->p[1])),
+ point_sl(&(l2->p[0]), &(l2->p[1]))));
+} /* lseg_parallel() */
-bool lseg_perp(LSEG *l1, LSEG *l2)
+bool
+lseg_perp(LSEG * l1, LSEG * l2)
{
- double m1, m2;
+ double m1,
+ m2;
- m1 = point_sl( &(l1->p[0]), &(l1->p[1]));
- m2 = point_sl( &(l2->p[0]), &(l2->p[1]));
+ m1 = point_sl(&(l1->p[0]), &(l1->p[1]));
+ m2 = point_sl(&(l2->p[0]), &(l2->p[1]));
- if (! FPzero(m1))
- return( FPeq(m2 / m1, -1.0) );
- else if (! FPzero(m2))
- return( FPeq(m1 / m2, -1.0) );
- return(0); /* both 0.0 */
-} /* lseg_perp() */
+ if (!FPzero(m1))
+ return (FPeq(m2 / m1, -1.0));
+ else if (!FPzero(m2))
+ return (FPeq(m1 / m2, -1.0));
+ return (0); /* both 0.0 */
+} /* lseg_perp() */
-bool lseg_vertical(LSEG *lseg)
+bool
+lseg_vertical(LSEG * lseg)
{
- return( FPeq(lseg->p[0].x, lseg->p[1].x) );
+ return (FPeq(lseg->p[0].x, lseg->p[1].x));
}
-bool lseg_horizontal(LSEG *lseg)
+bool
+lseg_horizontal(LSEG * lseg)
{
- return( FPeq(lseg->p[0].y, lseg->p[1].y) );
+ return (FPeq(lseg->p[0].y, lseg->p[1].y));
}
-bool lseg_eq(LSEG *l1, LSEG *l2)
+bool
+lseg_eq(LSEG * l1, LSEG * l2)
{
- return( FPeq(l1->p[0].x, l2->p[0].x) &&
- FPeq(l1->p[1].y, l2->p[1].y) &&
- FPeq(l1->p[0].x, l2->p[0].x) &&
- FPeq(l1->p[1].y, l2->p[1].y) );
+ return (FPeq(l1->p[0].x, l2->p[0].x) &&
+ FPeq(l1->p[1].y, l2->p[1].y) &&
+ FPeq(l1->p[0].x, l2->p[0].x) &&
+ FPeq(l1->p[1].y, l2->p[1].y));
}
/*----------------------------------------------------------
- * Line arithmetic routines.
+ * Line arithmetic routines.
*---------------------------------------------------------*/
/* lseg_distance -
- * If two segments don't intersect, then the closest
- * point will be from one of the endpoints to the other
- * segment.
+ * If two segments don't intersect, then the closest
+ * point will be from one of the endpoints to the other
+ * segment.
*/
-double *lseg_distance(LSEG *l1, LSEG *l2)
+double *
+lseg_distance(LSEG * l1, LSEG * l2)
{
- double *result = PALLOCTYPE(double);
+ double *result = PALLOCTYPE(double);
- *result = lseg_dt( l1, l2);
+ *result = lseg_dt(l1, l2);
- return(result);
+ return (result);
}
/* distance between l1, l2 */
static double
-lseg_dt(LSEG *l1, LSEG *l2)
-{
- double *d, result;
-
- if (lseg_intersect(l1, l2))
- return(0.0);
-
- d = dist_ps(&l1->p[0], l2);
- result = *d;
- PFREE(d);
- d = dist_ps(&l1->p[1], l2);
- result = Min(result, *d);
- PFREE(d);
+lseg_dt(LSEG * l1, LSEG * l2)
+{
+ double *d,
+ result;
+
+ if (lseg_intersect(l1, l2))
+ return (0.0);
+
+ d = dist_ps(&l1->p[0], l2);
+ result = *d;
+ PFREE(d);
+ d = dist_ps(&l1->p[1], l2);
+ result = Min(result, *d);
+ PFREE(d);
#if FALSE
/* XXX Why are we checking distances from all endpoints to the other segment?
* One set of endpoints should be sufficient - tgl 97/07/03
*/
- d = dist_ps(&l2->p[0], l1);
- result = Min(result, *d);
- PFREE(d);
- d = dist_ps(&l2->p[1], l1);
- result = Min(result, *d);
- PFREE(d);
+ d = dist_ps(&l2->p[0], l1);
+ result = Min(result, *d);
+ PFREE(d);
+ d = dist_ps(&l2->p[1], l1);
+ result = Min(result, *d);
+ PFREE(d);
#endif
-
- return(result);
-} /* lseg_dt() */
+
+ return (result);
+} /* lseg_dt() */
-Point *
-lseg_center(LSEG *lseg)
+Point *
+lseg_center(LSEG * lseg)
{
- Point *result;
+ Point *result;
- if (!PointerIsValid(lseg))
- return(NULL);
+ if (!PointerIsValid(lseg))
+ return (NULL);
- result = PALLOCTYPE(Point);
+ result = PALLOCTYPE(Point);
- result->x = (lseg->p[0].x - lseg->p[1].x) / 2;
- result->y = (lseg->p[0].y - lseg->p[1].y) / 2;
+ result->x = (lseg->p[0].x - lseg->p[1].x) / 2;
+ result->y = (lseg->p[0].y - lseg->p[1].y) / 2;
- return(result);
-} /* lseg_center() */
+ return (result);
+} /* lseg_center() */
/* lseg_interpt -
- * Find the intersection point of two segments (if any).
- * Find the intersection of the appropriate lines; if the
- * point is not on a given segment, there is no valid segment
- * intersection point at all.
+ * Find the intersection point of two segments (if any).
+ * Find the intersection of the appropriate lines; if the
+ * point is not on a given segment, there is no valid segment
+ * intersection point at all.
* If there is an intersection, then check explicitly for matching
- * endpoints since there may be rounding effects with annoying
- * lsb residue. - tgl 1997-07-09
- */
-Point *
-lseg_interpt(LSEG *l1, LSEG *l2)
-{
- Point *result;
- LINE *tmp1, *tmp2;
-
- if (!PointerIsValid(l1) || !PointerIsValid(l2))
- return(NULL);
-
- tmp1 = line_construct_pp(&l1->p[0], &l1->p[1]);
- tmp2 = line_construct_pp(&l2->p[0], &l2->p[1]);
- result = line_interpt(tmp1, tmp2);
- if (PointerIsValid(result)) {
- if (on_ps(result, l1)) {
- if ((FPeq( l1->p[0].x, l2->p[0].x) && FPeq( l1->p[0].y, l2->p[0].y))
- || (FPeq( l1->p[0].x, l2->p[1].x) && FPeq( l1->p[0].y, l2->p[1].y))) {
- result->x = l1->p[0].x;
- result->y = l1->p[0].y;
-
- } else if ((FPeq( l1->p[1].x, l2->p[0].x) && FPeq( l1->p[1].y, l2->p[0].y))
- || (FPeq( l1->p[1].x, l2->p[1].x) && FPeq( l1->p[1].y, l2->p[1].y))) {
- result->x = l1->p[1].x;
- result->y = l1->p[1].y;
- }
- } else {
- PFREE(result);
- result = NULL;
- }
- }
- PFREE(tmp1);
- PFREE(tmp2);
-
- return(result);
-} /* lseg_interpt() */
+ * endpoints since there may be rounding effects with annoying
+ * lsb residue. - tgl 1997-07-09
+ */
+Point *
+lseg_interpt(LSEG * l1, LSEG * l2)
+{
+ Point *result;
+ LINE *tmp1,
+ *tmp2;
+
+ if (!PointerIsValid(l1) || !PointerIsValid(l2))
+ return (NULL);
+
+ tmp1 = line_construct_pp(&l1->p[0], &l1->p[1]);
+ tmp2 = line_construct_pp(&l2->p[0], &l2->p[1]);
+ result = line_interpt(tmp1, tmp2);
+ if (PointerIsValid(result))
+ {
+ if (on_ps(result, l1))
+ {
+ if ((FPeq(l1->p[0].x, l2->p[0].x) && FPeq(l1->p[0].y, l2->p[0].y))
+ || (FPeq(l1->p[0].x, l2->p[1].x) && FPeq(l1->p[0].y, l2->p[1].y)))
+ {
+ result->x = l1->p[0].x;
+ result->y = l1->p[0].y;
+
+ }
+ else if ((FPeq(l1->p[1].x, l2->p[0].x) && FPeq(l1->p[1].y, l2->p[0].y))
+ || (FPeq(l1->p[1].x, l2->p[1].x) && FPeq(l1->p[1].y, l2->p[1].y)))
+ {
+ result->x = l1->p[1].x;
+ result->y = l1->p[1].y;
+ }
+ }
+ else
+ {
+ PFREE(result);
+ result = NULL;
+ }
+ }
+ PFREE(tmp1);
+ PFREE(tmp2);
+
+ return (result);
+} /* lseg_interpt() */
/***********************************************************************
**
- ** Routines for position comparisons of differently-typed
- ** 2D objects.
+ ** Routines for position comparisons of differently-typed
+ ** 2D objects.
**
***********************************************************************/
-#define ABOVE 1
-#define BELOW 0
-#define UNDEF -1
+#define ABOVE 1
+#define BELOW 0
+#define UNDEF -1
/*---------------------------------------------------------------------
- * dist_
- * Minimum distance from one object to another.
+ * dist_
+ * Minimum distance from one object to another.
*-------------------------------------------------------------------*/
-double *dist_pl(Point *pt, LINE *line)
+double *
+dist_pl(Point * pt, LINE * line)
{
- double *result = PALLOCTYPE(double);
+ double *result = PALLOCTYPE(double);
- *result = (line->A * pt->x + line->B * pt->y + line->C) /
- HYPOT(line->A, line->B);
-
- return(result);
+ *result = (line->A * pt->x + line->B * pt->y + line->C) /
+ HYPOT(line->A, line->B);
+
+ return (result);
}
-double *dist_ps(Point *pt, LSEG *lseg)
+double *
+dist_ps(Point * pt, LSEG * lseg)
{
- double m; /* slope of perp. */
- LINE *ln;
- double *result, *tmpdist;
- Point *ip;
+ double m; /* slope of perp. */
+ LINE *ln;
+ double *result,
+ *tmpdist;
+ Point *ip;
/*
* Construct a line perpendicular to the input segment
* and through the input point
*/
- if (lseg->p[1].x == lseg->p[0].x) {
- m = 0;
- } else if (lseg->p[1].y == lseg->p[0].y) { /* slope is infinite */
- m = (double)DBL_MAX;
- } else {
+ if (lseg->p[1].x == lseg->p[0].x)
+ {
+ m = 0;
+ }
+ else if (lseg->p[1].y == lseg->p[0].y)
+ { /* slope is infinite */
+ m = (double) DBL_MAX;
+ }
+ else
+ {
#if FALSE
- m = (-1) * (lseg->p[1].y - lseg->p[0].y) /
- (lseg->p[1].x - lseg->p[0].x);
+ m = (-1) * (lseg->p[1].y - lseg->p[0].y) /
+ (lseg->p[1].x - lseg->p[0].x);
#endif
- m = ((lseg->p[0].y - lseg->p[1].y) / (lseg->p[1].x - lseg->p[0].x));
- }
- ln = line_construct_pm(pt, m);
+ m = ((lseg->p[0].y - lseg->p[1].y) / (lseg->p[1].x - lseg->p[0].x));
+ }
+ ln = line_construct_pm(pt, m);
#ifdef GEODEBUG
-printf( "dist_ps- line is A=%g B=%g C=%g from (point) slope (%f,%f) %g\n",
- ln->A, ln->B, ln->C, pt->x, pt->y, m);
+ printf("dist_ps- line is A=%g B=%g C=%g from (point) slope (%f,%f) %g\n",
+ ln->A, ln->B, ln->C, pt->x, pt->y, m);
#endif
/*
* Calculate distance to the line segment
- * or to the endpoints of the segment.
+ * or to the endpoints of the segment.
*/
- /* intersection is on the line segment? */
- if ((ip = interpt_sl(lseg, ln)) != NULL) {
- result = point_distance(pt, ip);
+ /* intersection is on the line segment? */
+ if ((ip = interpt_sl(lseg, ln)) != NULL)
+ {
+ result = point_distance(pt, ip);
#ifdef GEODEBUG
-printf( "dist_ps- distance is %f to intersection point is (%f,%f)\n",
- *result, ip->x, ip->y);
+ printf("dist_ps- distance is %f to intersection point is (%f,%f)\n",
+ *result, ip->x, ip->y);
#endif
- /* otherwise, intersection is not on line segment */
- } else {
- result = point_distance(pt, &lseg->p[0]);
- tmpdist = point_distance(pt, &lseg->p[1]);
- if (*tmpdist < *result) *result = *tmpdist;
- PFREE (tmpdist);
- }
-
- if (ip != NULL) PFREE(ip);
- PFREE(ln);
- return (result);
+ /* otherwise, intersection is not on line segment */
+ }
+ else
+ {
+ result = point_distance(pt, &lseg->p[0]);
+ tmpdist = point_distance(pt, &lseg->p[1]);
+ if (*tmpdist < *result)
+ *result = *tmpdist;
+ PFREE(tmpdist);
+ }
+
+ if (ip != NULL)
+ PFREE(ip);
+ PFREE(ln);
+ return (result);
}
/*
- ** Distance from a point to a path
- */
-double *dist_ppath(Point *pt, PATH *path)
-{
- double *result;
- double *tmp;
- int i;
- LSEG lseg;
-
- switch (path->npts) {
- /* no points in path? then result is undefined... */
- case 0:
- result = NULL;
- break;
- /* one point in path? then get distance between two points... */
- case 1:
- result = point_distance(pt, &path->p[0]);
- break;
- default:
- /* make sure the path makes sense... */
- Assert(path->npts > 1);
- /*
- * the distance from a point to a path is the smallest distance
- * from the point to any of its constituent segments.
- */
- result = PALLOCTYPE(double);
- for (i = 0; i < path->npts - 1; i++) {
- statlseg_construct(&lseg, &path->p[i], &path->p[i+1]);
- tmp = dist_ps(pt, &lseg);
- if (i == 0 || *tmp < *result)
- *result = *tmp;
- PFREE(tmp);
+ ** Distance from a point to a path
+ */
+double *
+dist_ppath(Point * pt, PATH * path)
+{
+ double *result;
+ double *tmp;
+ int i;
+ LSEG lseg;
+
+ switch (path->npts)
+ {
+ /* no points in path? then result is undefined... */
+ case 0:
+ result = NULL;
+ break;
+ /* one point in path? then get distance between two points... */
+ case 1:
+ result = point_distance(pt, &path->p[0]);
+ break;
+ default:
+ /* make sure the path makes sense... */
+ Assert(path->npts > 1);
+
+ /*
+ * the distance from a point to a path is the smallest distance
+ * from the point to any of its constituent segments.
+ */
+ result = PALLOCTYPE(double);
+ for (i = 0; i < path->npts - 1; i++)
+ {
+ statlseg_construct(&lseg, &path->p[i], &path->p[i + 1]);
+ tmp = dist_ps(pt, &lseg);
+ if (i == 0 || *tmp < *result)
+ *result = *tmp;
+ PFREE(tmp);
+ }
+ break;
}
- break;
- }
- return(result);
+ return (result);
}
-double *dist_pb(Point *pt, BOX *box)
+double *
+dist_pb(Point * pt, BOX * box)
{
- Point *tmp;
- double *result;
-
- tmp = close_pb(pt, box);
- result = point_distance(tmp, pt);
- PFREE(tmp);
+ Point *tmp;
+ double *result;
+
+ tmp = close_pb(pt, box);
+ result = point_distance(tmp, pt);
+ PFREE(tmp);
- return(result);
+ return (result);
}
-double *dist_sl(LSEG *lseg, LINE *line)
+double *
+dist_sl(LSEG * lseg, LINE * line)
{
- double *result, *d2;
+ double *result,
+ *d2;
- if (inter_sl(lseg, line)) {
- result = PALLOCTYPE(double);
- *result = 0.0;
+ if (inter_sl(lseg, line))
+ {
+ result = PALLOCTYPE(double);
+ *result = 0.0;
- } else {
- result = dist_pl(&lseg->p[0], line);
- d2 = dist_pl(&lseg->p[1], line);
- if (*d2 > *result) {
- PFREE( result);
- result = d2;
- } else {
- PFREE( d2);
}
- }
-
- return(result);
+ else
+ {
+ result = dist_pl(&lseg->p[0], line);
+ d2 = dist_pl(&lseg->p[1], line);
+ if (*d2 > *result)
+ {
+ PFREE(result);
+ result = d2;
+ }
+ else
+ {
+ PFREE(d2);
+ }
+ }
+
+ return (result);
}
-double *dist_sb(LSEG *lseg, BOX *box)
+double *
+dist_sb(LSEG * lseg, BOX * box)
{
- Point *tmp;
- double *result;
-
- tmp = close_sb(lseg, box);
- if (tmp == NULL) {
- result = PALLOCTYPE(double);
- *result = 0.0;
- } else {
- result = dist_pb(tmp, box);
- PFREE(tmp);
- }
-
- return(result);
+ Point *tmp;
+ double *result;
+
+ tmp = close_sb(lseg, box);
+ if (tmp == NULL)
+ {
+ result = PALLOCTYPE(double);
+ *result = 0.0;
+ }
+ else
+ {
+ result = dist_pb(tmp, box);
+ PFREE(tmp);
+ }
+
+ return (result);
}
-double *dist_lb(LINE *line, BOX *box)
+double *
+dist_lb(LINE * line, BOX * box)
{
- Point *tmp;
- double *result;
-
- tmp = close_lb(line, box);
- if (tmp == NULL) {
- result = PALLOCTYPE(double);
- *result = 0.0;
- } else {
- result = dist_pb(tmp, box);
- PFREE(tmp);
- }
-
- return(result);
+ Point *tmp;
+ double *result;
+
+ tmp = close_lb(line, box);
+ if (tmp == NULL)
+ {
+ result = PALLOCTYPE(double);
+ *result = 0.0;
+ }
+ else
+ {
+ result = dist_pb(tmp, box);
+ PFREE(tmp);
+ }
+
+ return (result);
}
-double *
-dist_cpoly(CIRCLE *circle, POLYGON *poly)
+double *
+dist_cpoly(CIRCLE * circle, POLYGON * poly)
{
- double *result;
- int i;
- double *d;
- LSEG seg;
+ double *result;
+ int i;
+ double *d;
+ LSEG seg;
- if (!PointerIsValid(circle) || !PointerIsValid(poly))
- elog (WARN, "Invalid (null) input for distance", NULL);
+ if (!PointerIsValid(circle) || !PointerIsValid(poly))
+ elog(WARN, "Invalid (null) input for distance", NULL);
- if (point_inside( &(circle->center), poly->npts, poly->p)) {
+ if (point_inside(&(circle->center), poly->npts, poly->p))
+ {
#ifdef GEODEBUG
-printf( "dist_cpoly- center inside of polygon\n");
+ printf("dist_cpoly- center inside of polygon\n");
#endif
- result = PALLOCTYPE(double);
+ result = PALLOCTYPE(double);
- *result = 0;
- return(result);
- }
-
- /* initialize distance with segment between first and last points */
- seg.p[0].x = poly->p[0].x;
- seg.p[0].y = poly->p[0].y;
- seg.p[1].x = poly->p[poly->npts-1].x;
- seg.p[1].y = poly->p[poly->npts-1].y;
- result = dist_ps( &(circle->center), &seg);
+ *result = 0;
+ return (result);
+ }
+
+ /* initialize distance with segment between first and last points */
+ seg.p[0].x = poly->p[0].x;
+ seg.p[0].y = poly->p[0].y;
+ seg.p[1].x = poly->p[poly->npts - 1].x;
+ seg.p[1].y = poly->p[poly->npts - 1].y;
+ result = dist_ps(&(circle->center), &seg);
#ifdef GEODEBUG
-printf( "dist_cpoly- segment 0/n distance is %f\n", *result);
+ printf("dist_cpoly- segment 0/n distance is %f\n", *result);
#endif
- /* check distances for other segments */
- for (i = 0; (i < poly->npts - 1); i++) {
- seg.p[0].x = poly->p[i].x;
- seg.p[0].y = poly->p[i].y;
- seg.p[1].x = poly->p[i+1].x;
- seg.p[1].y = poly->p[i+1].y;
- d = dist_ps( &(circle->center), &seg);
+ /* check distances for other segments */
+ for (i = 0; (i < poly->npts - 1); i++)
+ {
+ seg.p[0].x = poly->p[i].x;
+ seg.p[0].y = poly->p[i].y;
+ seg.p[1].x = poly->p[i + 1].x;
+ seg.p[1].y = poly->p[i + 1].y;
+ d = dist_ps(&(circle->center), &seg);
#ifdef GEODEBUG
-printf( "dist_cpoly- segment %d distance is %f\n", (i+1), *d);
+ printf("dist_cpoly- segment %d distance is %f\n", (i + 1), *d);
#endif
- if (*d < *result) *result = *d;
- PFREE(d);
- }
+ if (*d < *result)
+ *result = *d;
+ PFREE(d);
+ }
- *result -= circle->radius;
- if (*result < 0) *result = 0;
+ *result -= circle->radius;
+ if (*result < 0)
+ *result = 0;
- return(result);
-} /* dist_cpoly() */
+ return (result);
+} /* dist_cpoly() */
/*---------------------------------------------------------------------
- * interpt_
- * Intersection point of objects.
- * We choose to ignore the "point" of intersection between
- * lines and boxes, since there are typically two.
+ * interpt_
+ * Intersection point of objects.
+ * We choose to ignore the "point" of intersection between
+ * lines and boxes, since there are typically two.
*-------------------------------------------------------------------*/
-static Point *interpt_sl(LSEG *lseg, LINE *line)
+static Point *
+interpt_sl(LSEG * lseg, LINE * line)
{
- LINE *tmp;
- Point *p;
-
- tmp = line_construct_pp(&lseg->p[0], &lseg->p[1]);
- p = line_interpt(tmp, line);
+ LINE *tmp;
+ Point *p;
+
+ tmp = line_construct_pp(&lseg->p[0], &lseg->p[1]);
+ p = line_interpt(tmp, line);
#ifdef GEODEBUG
-printf( "interpt_sl- segment is (%.*g %.*g) (%.*g %.*g)\n",
- digits8, lseg->p[0].x, digits8, lseg->p[0].y, digits8, lseg->p[1].x, digits8, lseg->p[1].y);
-printf( "interpt_sl- segment becomes line A=%.*g B=%.*g C=%.*g\n",
- digits8, tmp->A, digits8, tmp->B, digits8, tmp->C);
+ printf("interpt_sl- segment is (%.*g %.*g) (%.*g %.*g)\n",
+ digits8, lseg->p[0].x, digits8, lseg->p[0].y, digits8, lseg->p[1].x, digits8, lseg->p[1].y);
+ printf("interpt_sl- segment becomes line A=%.*g B=%.*g C=%.*g\n",
+ digits8, tmp->A, digits8, tmp->B, digits8, tmp->C);
#endif
- if (PointerIsValid(p)) {
+ if (PointerIsValid(p))
+ {
#ifdef GEODEBUG
-printf( "interpt_sl- intersection point is (%.*g %.*g)\n", digits8, p->x, digits8, p->y);
+ printf("interpt_sl- intersection point is (%.*g %.*g)\n", digits8, p->x, digits8, p->y);
#endif
- if (on_ps(p, lseg)) {
+ if (on_ps(p, lseg))
+ {
#ifdef GEODEBUG
-printf( "interpt_sl- intersection point is on segment\n");
+ printf("interpt_sl- intersection point is on segment\n");
#endif
- } else {
- PFREE(p);
- p = NULL;
+ }
+ else
+ {
+ PFREE(p);
+ p = NULL;
+ }
}
- }
-
- PFREE(tmp);
- return(p);
+
+ PFREE(tmp);
+ return (p);
}
/*---------------------------------------------------------------------
- * close_
- * Point of closest proximity between objects.
+ * close_
+ * Point of closest proximity between objects.
*-------------------------------------------------------------------*/
-/* close_pl -
- * The intersection point of a perpendicular of the line
- * through the point.
+/* close_pl -
+ * The intersection point of a perpendicular of the line
+ * through the point.
*/
-Point *close_pl(Point *pt, LINE *line)
+Point *
+close_pl(Point * pt, LINE * line)
{
- Point *result;
- LINE *tmp;
- double invm;
-
- result = PALLOCTYPE(Point);
+ Point *result;
+ LINE *tmp;
+ double invm;
+
+ result = PALLOCTYPE(Point);
#if FALSE
- if (FPeq(line->A, -1.0) && FPzero(line->B)) { /* vertical */
- }
+ if (FPeq(line->A, -1.0) && FPzero(line->B))
+ { /* vertical */
+ }
#endif
- if (line_vertical(line)) {
- result->x = line->C;
- result->y = pt->y;
- return(result);
+ if (line_vertical(line))
+ {
+ result->x = line->C;
+ result->y = pt->y;
+ return (result);
#if FALSE
- } else if (FPzero(line->m)) { /* horizontal */
+ }
+ else if (FPzero(line->m))
+ { /* horizontal */
#endif
- } else if (line_horizontal(line)) {
- result->x = pt->x;
- result->y = line->C;
- return(result);
- }
- /* drop a perpendicular and find the intersection point */
+ }
+ else if (line_horizontal(line))
+ {
+ result->x = pt->x;
+ result->y = line->C;
+ return (result);
+ }
+ /* drop a perpendicular and find the intersection point */
#if FALSE
- invm = -1.0 / line->m;
+ invm = -1.0 / line->m;
#endif
- /* invert and flip the sign on the slope to get a perpendicular */
- invm = line->B / line->A;
- tmp = line_construct_pm(pt, invm);
- result = line_interpt(tmp, line);
- return(result);
-} /* close_pl() */
-
-
-/* close_ps -
- * Take the closest endpoint if the point is left, right,
- * above, or below the segment, otherwise find the intersection
- * point of the segment and its perpendicular through the point.
- */
-Point *close_ps(Point *pt, LSEG *lseg)
-{
- Point *result;
- LINE *tmp;
- double invm;
- int xh, yh;
-
- result = NULL;
- xh = lseg->p[0].x < lseg->p[1].x;
- yh = lseg->p[0].y < lseg->p[1].y;
- if (pt->x < lseg->p[!xh].x)
- result = point_copy(&lseg->p[!xh]);
- else if (pt->x > lseg->p[xh].x)
- result = point_copy(&lseg->p[xh]);
- else if (pt->y < lseg->p[!yh].y)
- result = point_copy(&lseg->p[!yh]);
- else if (pt->y > lseg->p[yh].y)
- result = point_copy(&lseg->p[yh]);
- if (result)
- return(result);
+ /* invert and flip the sign on the slope to get a perpendicular */
+ invm = line->B / line->A;
+ tmp = line_construct_pm(pt, invm);
+ result = line_interpt(tmp, line);
+ return (result);
+} /* close_pl() */
+
+
+/* close_ps -
+ * Take the closest endpoint if the point is left, right,
+ * above, or below the segment, otherwise find the intersection
+ * point of the segment and its perpendicular through the point.
+ */
+Point *
+close_ps(Point * pt, LSEG * lseg)
+{
+ Point *result;
+ LINE *tmp;
+ double invm;
+ int xh,
+ yh;
+
+ result = NULL;
+ xh = lseg->p[0].x < lseg->p[1].x;
+ yh = lseg->p[0].y < lseg->p[1].y;
+ if (pt->x < lseg->p[!xh].x)
+ result = point_copy(&lseg->p[!xh]);
+ else if (pt->x > lseg->p[xh].x)
+ result = point_copy(&lseg->p[xh]);
+ else if (pt->y < lseg->p[!yh].y)
+ result = point_copy(&lseg->p[!yh]);
+ else if (pt->y > lseg->p[yh].y)
+ result = point_copy(&lseg->p[yh]);
+ if (result)
+ return (result);
#if FALSE
- if (FPeq(lseg->p[0].x, lseg->p[1].x)) /* vertical */
+ if (FPeq(lseg->p[0].x, lseg->p[1].x)) /* vertical */
#endif
- if (lseg_vertical(lseg)) {
- result->x = lseg->p[0].x;
- result->y = pt->y;
- return(result);
+ if (lseg_vertical(lseg))
+ {
+ result->x = lseg->p[0].x;
+ result->y = pt->y;
+ return (result);
#if FALSE
- } else if (FPzero(lseg->m)) { /* horizontal */
+ }
+ else if (FPzero(lseg->m))
+ { /* horizontal */
#endif
- } else if (lseg_horizontal(lseg)) {
- result->x = pt->x;
- result->y = lseg->p[0].y;
- return(result);
- }
-
+ }
+ else if (lseg_horizontal(lseg))
+ {
+ result->x = pt->x;
+ result->y = lseg->p[0].y;
+ return (result);
+ }
+
#if FALSE
- invm = -1.0 / lseg->m;
+ invm = -1.0 / lseg->m;
#endif
- invm = -1.0 / point_sl(&(lseg->p[0]), &(lseg->p[1]));
- tmp = line_construct_pm(pt, invm);
- result = interpt_sl(lseg, tmp);
- return(result);
-} /* close_ps() */
+ invm = -1.0 / point_sl(&(lseg->p[0]), &(lseg->p[1]));
+ tmp = line_construct_pm(pt, invm);
+ result = interpt_sl(lseg, tmp);
+ return (result);
+} /* close_ps() */
-Point *close_pb(Point *pt, BOX *box)
+Point *
+close_pb(Point * pt, BOX * box)
{
- /* think about this one for a while */
- elog(WARN, "close_pb not implemented", NULL);
+ /* think about this one for a while */
+ elog(WARN, "close_pb not implemented", NULL);
- return(NULL);
+ return (NULL);
}
-Point *close_sl(LSEG *lseg, LINE *line)
+Point *
+close_sl(LSEG * lseg, LINE * line)
{
- Point *result;
- double *d1, *d2;
+ Point *result;
+ double *d1,
+ *d2;
- result = interpt_sl(lseg, line);
- if (result)
- return(result);
- d1 = dist_pl(&lseg->p[0], line);
- d2 = dist_pl(&lseg->p[1], line);
- if (d1 < d2)
- result = point_copy(&lseg->p[0]);
- else
- result = point_copy(&lseg->p[1]);
-
- PFREE(d1);
- PFREE(d2);
- return(result);
+ result = interpt_sl(lseg, line);
+ if (result)
+ return (result);
+ d1 = dist_pl(&lseg->p[0], line);
+ d2 = dist_pl(&lseg->p[1], line);
+ if (d1 < d2)
+ result = point_copy(&lseg->p[0]);
+ else
+ result = point_copy(&lseg->p[1]);
+
+ PFREE(d1);
+ PFREE(d2);
+ return (result);
}
-Point *close_sb(LSEG *lseg, BOX *box)
+Point *
+close_sb(LSEG * lseg, BOX * box)
{
- /* think about this one for a while */
- elog(WARN, "close_sb not implemented", NULL);
+ /* think about this one for a while */
+ elog(WARN, "close_sb not implemented", NULL);
- return(NULL);
+ return (NULL);
}
-Point *close_lb(LINE *line, BOX *box)
+Point *
+close_lb(LINE * line, BOX * box)
{
- /* think about this one for a while */
- elog(WARN, "close_lb not implemented", NULL);
+ /* think about this one for a while */
+ elog(WARN, "close_lb not implemented", NULL);
- return(NULL);
+ return (NULL);
}
/*---------------------------------------------------------------------
- * on_
- * Whether one object lies completely within another.
+ * on_
+ * Whether one object lies completely within another.
*-------------------------------------------------------------------*/
/* on_pl -
- * Does the point satisfy the equation?
+ * Does the point satisfy the equation?
*/
-bool on_pl(Point *pt, LINE *line)
+bool
+on_pl(Point * pt, LINE * line)
{
- if (!PointerIsValid(pt) || !PointerIsValid(line))
- return(FALSE);
+ if (!PointerIsValid(pt) || !PointerIsValid(line))
+ return (FALSE);
- return( FPzero(line->A * pt->x + line->B * pt->y + line->C) );
+ return (FPzero(line->A * pt->x + line->B * pt->y + line->C));
}
/* on_ps -
- * Determine colinearity by detecting a triangle inequality.
+ * Determine colinearity by detecting a triangle inequality.
* This algorithm seems to behave nicely even with lsb residues - tgl 1997-07-09
*/
-bool on_ps(Point *pt, LSEG *lseg)
+bool
+on_ps(Point * pt, LSEG * lseg)
{
- if (!PointerIsValid(pt) || !PointerIsValid(lseg))
- return(FALSE);
+ if (!PointerIsValid(pt) || !PointerIsValid(lseg))
+ return (FALSE);
- return( FPeq (point_dt(pt, &lseg->p[0]) + point_dt(pt, &lseg->p[1]),
- point_dt(&lseg->p[0], &lseg->p[1])) );
+ return (FPeq(point_dt(pt, &lseg->p[0]) + point_dt(pt, &lseg->p[1]),
+ point_dt(&lseg->p[0], &lseg->p[1])));
}
-bool on_pb(Point *pt, BOX *box)
+bool
+on_pb(Point * pt, BOX * box)
{
- if (!PointerIsValid(pt) || !PointerIsValid(box))
- return(FALSE);
+ if (!PointerIsValid(pt) || !PointerIsValid(box))
+ return (FALSE);
- return( pt->x <= box->high.x && pt->x >= box->low.x &&
- pt->y <= box->high.y && pt->y >= box->low.y );
+ return (pt->x <= box->high.x && pt->x >= box->low.x &&
+ pt->y <= box->high.y && pt->y >= box->low.y);
}
-/* on_ppath -
- * Whether a point lies within (on) a polyline.
- * If open, we have to (groan) check each segment.
+/* on_ppath -
+ * Whether a point lies within (on) a polyline.
+ * If open, we have to (groan) check each segment.
* (uses same algorithm as for point intersecting segment - tgl 1997-07-09)
- * If closed, we use the old O(n) ray method for point-in-polygon.
- * The ray is horizontal, from pt out to the right.
- * Each segment that crosses the ray counts as an
- * intersection; note that an endpoint or edge may touch
- * but not cross.
- * (we can do p-in-p in lg(n), but it takes preprocessing)
+ * If closed, we use the old O(n) ray method for point-in-polygon.
+ * The ray is horizontal, from pt out to the right.
+ * Each segment that crosses the ray counts as an
+ * intersection; note that an endpoint or edge may touch
+ * but not cross.
+ * (we can do p-in-p in lg(n), but it takes preprocessing)
*/
-#define NEXT(A) ((A+1) % path->npts) /* cyclic "i+1" */
+#define NEXT(A) ((A+1) % path->npts) /* cyclic "i+1" */
-bool on_ppath(Point *pt, PATH *path)
+bool
+on_ppath(Point * pt, PATH * path)
{
#if FALSE
- int above, next, /* is the seg above the ray? */
- inter, /* # of times path crosses ray */
- hi; /* index inc of higher seg (0,1) */
- double x, yh, yl, xh, xl;
+ int above,
+ next, /* is the seg above the ray? */
+ inter, /* # of times path crosses ray */
+ hi; /* index inc of higher seg (0,1) */
+ double x,
+ yh,
+ yl,
+ xh,
+ xl;
+
#endif
- int i, n;
- double a, b;
-
- if (!PointerIsValid(pt) || !PointerIsValid(path))
- return(FALSE);
-
- if (! path->closed) { /*-- OPEN --*/
- n = path->npts - 1;
- a = point_dt(pt, &path->p[0]);
- for (i = 0; i < n; i++) {
- b = point_dt(pt, &path->p[i+1]);
- if (FPeq(a+b,
- point_dt(&path->p[i], &path->p[i+1])))
- return(1);
- a = b;
- }
- return(0);
- }
-
- return(point_inside( pt, path->npts, path->p));
+ int i,
+ n;
+ double a,
+ b;
+
+ if (!PointerIsValid(pt) || !PointerIsValid(path))
+ return (FALSE);
+
+ if (!path->closed)
+ { /*-- OPEN --*/
+ n = path->npts - 1;
+ a = point_dt(pt, &path->p[0]);
+ for (i = 0; i < n; i++)
+ {
+ b = point_dt(pt, &path->p[i + 1]);
+ if (FPeq(a + b,
+ point_dt(&path->p[i], &path->p[i + 1])))
+ return (1);
+ a = b;
+ }
+ return (0);
+ }
+
+ return (point_inside(pt, path->npts, path->p));
#if FALSE
- inter = 0; /*-- CLOSED --*/
- above = FPgt(path->p[0].y, pt->y) ? ABOVE :
- FPlt(path->p[0].y, pt->y) ? BELOW : UNDEF;
-
- for (i = 0; i < path->npts; i++) {
- hi = path->p[i].y < path->p[NEXT(i)].y;
- /* must take care of wrap around to original vertex for closed paths */
- yh = (i+hi < path->npts) ? path->p[i+hi].y : path->p[0].y;
- yl = (i+!hi < path->npts) ? path->p[i+!hi].y : path->p[0].y;
- hi = path->p[i].x < path->p[NEXT(i)].x;
- xh = (i+hi < path->npts) ? path->p[i+hi].x : path->p[0].x;
- xl = (i+!hi < path->npts) ? path->p[i+!hi].x : path->p[0].x;
- /* skip seg if it doesn't touch the ray */
-
- if (FPeq(yh, yl)) /* horizontal seg? */
- if (FPge(pt->x, xl) && FPle(pt->x, xh) &&
- FPeq(pt->y, yh))
- return(1); /* pt lies on seg */
- else
- continue; /* skip other hz segs */
- if (FPlt(yh, pt->y) || /* pt is strictly below seg */
- FPgt(yl, pt->y)) /* strictly above */
- continue;
-
- /* seg touches the ray, find out where */
-
- x = FPeq(xh, xl) /* vertical seg? */
- ? path->p[i].x
- : (pt->y - path->p[i].y) /
- point_sl(&path->p[i],
- &path->p[NEXT(i)]) +
- path->p[i].x;
- if (FPeq(x, pt->x)) /* pt lies on this seg */
- return(1);
-
- /* does the seg actually cross the ray? */
-
- next = FPgt(path->p[NEXT(i)].y, pt->y) ? ABOVE :
- FPlt(path->p[NEXT(i)].y, pt->y) ? BELOW : above;
- inter += FPge(x, pt->x) && next != above;
- above = next;
- }
- return( above == UNDEF || /* path is horizontal */
- inter % 2); /* odd # of intersections */
+ inter = 0; /*-- CLOSED --*/
+ above = FPgt(path->p[0].y, pt->y) ? ABOVE :
+ FPlt(path->p[0].y, pt->y) ? BELOW : UNDEF;
+
+ for (i = 0; i < path->npts; i++)
+ {
+ hi = path->p[i].y < path->p[NEXT(i)].y;
+
+ /*
+ * must take care of wrap around to original vertex for closed
+ * paths
+ */
+ yh = (i + hi < path->npts) ? path->p[i + hi].y : path->p[0].y;
+ yl = (i + !hi < path->npts) ? path->p[i + !hi].y : path->p[0].y;
+ hi = path->p[i].x < path->p[NEXT(i)].x;
+ xh = (i + hi < path->npts) ? path->p[i + hi].x : path->p[0].x;
+ xl = (i + !hi < path->npts) ? path->p[i + !hi].x : path->p[0].x;
+ /* skip seg if it doesn't touch the ray */
+
+ if (FPeq(yh, yl)) /* horizontal seg? */
+ if (FPge(pt->x, xl) && FPle(pt->x, xh) &&
+ FPeq(pt->y, yh))
+ return (1); /* pt lies on seg */
+ else
+ continue; /* skip other hz segs */
+ if (FPlt(yh, pt->y) || /* pt is strictly below seg */
+ FPgt(yl, pt->y)) /* strictly above */
+ continue;
+
+ /* seg touches the ray, find out where */
+
+ x = FPeq(xh, xl) /* vertical seg? */
+ ? path->p[i].x
+ : (pt->y - path->p[i].y) /
+ point_sl(&path->p[i],
+ &path->p[NEXT(i)]) +
+ path->p[i].x;
+ if (FPeq(x, pt->x)) /* pt lies on this seg */
+ return (1);
+
+ /* does the seg actually cross the ray? */
+
+ next = FPgt(path->p[NEXT(i)].y, pt->y) ? ABOVE :
+ FPlt(path->p[NEXT(i)].y, pt->y) ? BELOW : above;
+ inter += FPge(x, pt->x) && next != above;
+ above = next;
+ }
+ return (above == UNDEF || /* path is horizontal */
+ inter % 2); /* odd # of intersections */
#endif
-} /* on_ppath() */
+} /* on_ppath() */
-bool on_sl(LSEG *lseg, LINE *line)
+bool
+on_sl(LSEG * lseg, LINE * line)
{
- if (!PointerIsValid(lseg) || !PointerIsValid(line))
- return(FALSE);
+ if (!PointerIsValid(lseg) || !PointerIsValid(line))
+ return (FALSE);
- return( on_pl(&lseg->p[0], line) && on_pl(&lseg->p[1], line) );
-} /* on_sl() */
+ return (on_pl(&lseg->p[0], line) && on_pl(&lseg->p[1], line));
+} /* on_sl() */
-bool on_sb(LSEG *lseg, BOX *box)
+bool
+on_sb(LSEG * lseg, BOX * box)
{
- if (!PointerIsValid(lseg) || !PointerIsValid(box))
- return(FALSE);
+ if (!PointerIsValid(lseg) || !PointerIsValid(box))
+ return (FALSE);
- return( on_pb(&lseg->p[0], box) && on_pb(&lseg->p[1], box) );
-} /* on_sb() */
+ return (on_pb(&lseg->p[0], box) && on_pb(&lseg->p[1], box));
+} /* on_sb() */
/*---------------------------------------------------------------------
- * inter_
- * Whether one object intersects another.
+ * inter_
+ * Whether one object intersects another.
*-------------------------------------------------------------------*/
-bool inter_sl(LSEG *lseg, LINE *line)
+bool
+inter_sl(LSEG * lseg, LINE * line)
{
- Point *tmp;
+ Point *tmp;
- if (!PointerIsValid(lseg) || !PointerIsValid(line))
- return(FALSE);
+ if (!PointerIsValid(lseg) || !PointerIsValid(line))
+ return (FALSE);
- tmp = interpt_sl(lseg, line);
- if (tmp) {
- PFREE(tmp);
- return(1);
- }
- return(0);
+ tmp = interpt_sl(lseg, line);
+ if (tmp)
+ {
+ PFREE(tmp);
+ return (1);
+ }
+ return (0);
}
/* XXX segment and box should be able to intersect; tgl - 97/01/09 */
-bool inter_sb(LSEG *lseg, BOX *box)
+bool
+inter_sb(LSEG * lseg, BOX * box)
{
- return(0);
+ return (0);
}
/* XXX line and box should be able to intersect; tgl - 97/01/09 */
-bool inter_lb(LINE *line, BOX *box)
+bool
+inter_lb(LINE * line, BOX * box)
{
- return(0);
+ return (0);
}
/*------------------------------------------------------------------
* The following routines define a data type and operator class for
- * POLYGONS .... Part of which (the polygon's bounding box) is built on
+ * POLYGONS .... Part of which (the polygon's bounding box) is built on
* top of the BOX data type.
*
* make_bound_box - create the bounding box for the input polygon
@@ -2220,77 +2490,91 @@ bool inter_lb(LINE *line, BOX *box)
/*---------------------------------------------------------------------
* Make the smallest bounding box for the given polygon.
*---------------------------------------------------------------------*/
-static void make_bound_box(POLYGON *poly)
-{
- int i;
- double x1,y1,x2,y2;
+static void
+make_bound_box(POLYGON * poly)
+{
+ int i;
+ double x1,
+ y1,
+ x2,
+ y2;
+
+ if (poly->npts > 0)
+ {
+ x2 = x1 = poly->p[0].x;
+ y2 = y1 = poly->p[0].y;
+ for (i = 1; i < poly->npts; i++)
+ {
+ if (poly->p[i].x < x1)
+ x1 = poly->p[i].x;
+ if (poly->p[i].x > x2)
+ x2 = poly->p[i].x;
+ if (poly->p[i].y < y1)
+ y1 = poly->p[i].y;
+ if (poly->p[i].y > y2)
+ y2 = poly->p[i].y;
+ }
- if (poly->npts > 0) {
- x2 = x1 = poly->p[0].x;
- y2 = y1 = poly->p[0].y;
- for (i = 1; i < poly->npts; i++) {
- if (poly->p[i].x < x1) x1 = poly->p[i].x;
- if (poly->p[i].x > x2) x2 = poly->p[i].x;
- if (poly->p[i].y < y1) y1 = poly->p[i].y;
- if (poly->p[i].y > y2) y2 = poly->p[i].y;
+ box_fill(&(poly->boundbox), x1, x2, y1, y2);
+ }
+ else
+ {
+ elog(WARN, "Unable to create bounding box for empty polygon", NULL);
}
-
- box_fill(&(poly->boundbox), x1, x2, y1, y2);
- } else {
- elog (WARN, "Unable to create bounding box for empty polygon", NULL);
- }
}
/*------------------------------------------------------------------
* poly_in - read in the polygon from a string specification
*
- * External format:
- * "((x0,y0),...,(xn,yn))"
- * "x0,y0,...,xn,yn"
- * also supports the older style "(x1,...,xn,y1,...yn)"
+ * External format:
+ * "((x0,y0),...,(xn,yn))"
+ * "x0,y0,...,xn,yn"
+ * also supports the older style "(x1,...,xn,y1,...yn)"
*------------------------------------------------------------------*/
-POLYGON *poly_in(char *str)
+POLYGON *
+poly_in(char *str)
{
- POLYGON *poly;
- int npts;
- int size;
- int isopen;
- char *s;
+ POLYGON *poly;
+ int npts;
+ int size;
+ int isopen;
+ char *s;
- if (!PointerIsValid(str))
- elog (WARN," Bad (null) polygon external representation");
+ if (!PointerIsValid(str))
+ elog(WARN, " Bad (null) polygon external representation");
- if ((npts = pair_count(str, ',')) <= 0)
- elog(WARN, "Bad polygon external representation '%s'", str);
+ if ((npts = pair_count(str, ',')) <= 0)
+ elog(WARN, "Bad polygon external representation '%s'", str);
- size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * npts);
- poly = PALLOC(size);
+ size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * npts);
+ poly = PALLOC(size);
- memset((char *) poly, 0, size); /* zero any holes */
- poly->size = size;
- poly->npts = npts;
+ memset((char *) poly, 0, size); /* zero any holes */
+ poly->size = size;
+ poly->npts = npts;
- if ((! path_decode(FALSE, npts, str, &isopen, &s, &(poly->p[0])))
- || (*s != '\0'))
- elog (WARN, "Bad polygon external representation '%s'",str);
+ if ((!path_decode(FALSE, npts, str, &isopen, &s, &(poly->p[0])))
+ || (*s != '\0'))
+ elog(WARN, "Bad polygon external representation '%s'", str);
- make_bound_box(poly);
+ make_bound_box(poly);
- return( poly);
-} /* poly_in() */
+ return (poly);
+} /* poly_in() */
/*---------------------------------------------------------------
- * poly_out - convert internal POLYGON representation to the
- * character string format "((f8,f8),...,(f8,f8))"
- * also support old format "(f8,f8,...,f8,f8)"
+ * poly_out - convert internal POLYGON representation to the
+ * character string format "((f8,f8),...,(f8,f8))"
+ * also support old format "(f8,f8,...,f8,f8)"
*---------------------------------------------------------------*/
-char *poly_out(POLYGON *poly)
+char *
+poly_out(POLYGON * poly)
{
- if (!PointerIsValid(poly))
- return NULL;
+ if (!PointerIsValid(poly))
+ return NULL;
- return( path_encode( TRUE, poly->npts, &(poly->p[0])));
-} /* poly_out() */
+ return (path_encode(TRUE, poly->npts, &(poly->p[0])));
+} /* poly_out() */
/*-------------------------------------------------------
@@ -2298,9 +2582,10 @@ char *poly_out(POLYGON *poly)
* the right most point of A left of the left most point
* of B?
*-------------------------------------------------------*/
-bool poly_left(POLYGON *polya, POLYGON *polyb)
+bool
+poly_left(POLYGON * polya, POLYGON * polyb)
{
- return (polya->boundbox.high.x < polyb->boundbox.low.x);
+ return (polya->boundbox.high.x < polyb->boundbox.low.x);
}
/*-------------------------------------------------------
@@ -2308,9 +2593,10 @@ bool poly_left(POLYGON *polya, POLYGON *polyb)
* the left most point of A left of the right most point
* of B?
*-------------------------------------------------------*/
-bool poly_overleft(POLYGON *polya, POLYGON *polyb)
+bool
+poly_overleft(POLYGON * polya, POLYGON * polyb)
{
- return (polya->boundbox.low.x <= polyb->boundbox.high.x);
+ return (polya->boundbox.low.x <= polyb->boundbox.high.x);
}
/*-------------------------------------------------------
@@ -2318,9 +2604,10 @@ bool poly_overleft(POLYGON *polya, POLYGON *polyb)
* the left most point of A right of the right most point
* of B?
*-------------------------------------------------------*/
-bool poly_right(POLYGON *polya, POLYGON *polyb)
+bool
+poly_right(POLYGON * polya, POLYGON * polyb)
{
- return( polya->boundbox.low.x > polyb->boundbox.high.x);
+ return (polya->boundbox.low.x > polyb->boundbox.high.x);
}
/*-------------------------------------------------------
@@ -2328,45 +2615,49 @@ bool poly_right(POLYGON *polya, POLYGON *polyb)
* the right most point of A right of the left most point
* of B?
*-------------------------------------------------------*/
-bool poly_overright(POLYGON *polya, POLYGON *polyb)
+bool
+poly_overright(POLYGON * polya, POLYGON * polyb)
{
- return( polya->boundbox.high.x > polyb->boundbox.low.x);
+ return (polya->boundbox.high.x > polyb->boundbox.low.x);
}
/*-------------------------------------------------------
* Is polygon A the same as polygon B? i.e. are all the
* points the same?
* Check all points for matches in both forward and reverse
- * direction since polygons are non-directional and are
- * closed shapes.
+ * direction since polygons are non-directional and are
+ * closed shapes.
*-------------------------------------------------------*/
-bool poly_same(POLYGON *polya, POLYGON *polyb)
+bool
+poly_same(POLYGON * polya, POLYGON * polyb)
{
- if (! PointerIsValid( polya) || ! PointerIsValid( polyb))
- return FALSE;
+ if (!PointerIsValid(polya) || !PointerIsValid(polyb))
+ return FALSE;
- if (polya->npts != polyb->npts)
- return FALSE;
+ if (polya->npts != polyb->npts)
+ return FALSE;
- return(plist_same( polya->npts, polya->p, polyb->p));
+ return (plist_same(polya->npts, polya->p, polyb->p));
#if FALSE
- for (i = 0; i < polya->npts; i++) {
- if ((polya->p[i].x != polyb->p[i].x)
- || (polya->p[i].y != polyb->p[i].y))
- return FALSE;
- }
- return TRUE;
+ for (i = 0; i < polya->npts; i++)
+ {
+ if ((polya->p[i].x != polyb->p[i].x)
+ || (polya->p[i].y != polyb->p[i].y))
+ return FALSE;
+ }
+ return TRUE;
#endif
-} /* poly_same() */
+} /* poly_same() */
/*-----------------------------------------------------------------
* Determine if polygon A overlaps polygon B by determining if
* their bounding boxes overlap.
*-----------------------------------------------------------------*/
-bool poly_overlap(POLYGON *polya, POLYGON *polyb)
+bool
+poly_overlap(POLYGON * polya, POLYGON * polyb)
{
- return box_overlap(&(polya->boundbox), &(polyb->boundbox));
+ return box_overlap(&(polya->boundbox), &(polyb->boundbox));
}
@@ -2375,484 +2666,504 @@ bool poly_overlap(POLYGON *polya, POLYGON *polyb)
* bounding box contains B's bounding box.
*-----------------------------------------------------------------*/
#if FALSE
-bool poly_contain(POLYGON *polya, POLYGON *polyb)
+bool
+poly_contain(POLYGON * polya, POLYGON * polyb)
{
- return box_contain(&(polya->boundbox), &(polyb->boundbox));
+ return box_contain(&(polya->boundbox), &(polyb->boundbox));
}
+
#endif
bool
-poly_contain(POLYGON *polya, POLYGON *polyb)
+poly_contain(POLYGON * polya, POLYGON * polyb)
{
- int i;
+ int i;
- if (!PointerIsValid(polya) || !PointerIsValid(polyb))
- return(FALSE);
+ if (!PointerIsValid(polya) || !PointerIsValid(polyb))
+ return (FALSE);
- if (box_contain(&(polya->boundbox), &(polyb->boundbox))) {
- for (i = 0; i < polyb->npts; i++) {
- if (point_inside(&(polyb->p[i]), polya->npts, &(polya->p[0])) == 0) {
+ if (box_contain(&(polya->boundbox), &(polyb->boundbox)))
+ {
+ for (i = 0; i < polyb->npts; i++)
+ {
+ if (point_inside(&(polyb->p[i]), polya->npts, &(polya->p[0])) == 0)
+ {
#if GEODEBUG
-printf( "poly_contain- point (%f,%f) not in polygon\n", polyb->p[i].x, polyb->p[i].y);
+ printf("poly_contain- point (%f,%f) not in polygon\n", polyb->p[i].x, polyb->p[i].y);
#endif
- return(FALSE);
- }
- }
- for (i = 0; i < polya->npts; i++) {
- if (point_inside(&(polya->p[i]), polyb->npts, &(polyb->p[0])) == 1) {
+ return (FALSE);
+ }
+ }
+ for (i = 0; i < polya->npts; i++)
+ {
+ if (point_inside(&(polya->p[i]), polyb->npts, &(polyb->p[0])) == 1)
+ {
#if GEODEBUG
-printf( "poly_contain- point (%f,%f) in polygon\n", polya->p[i].x, polya->p[i].y);
+ printf("poly_contain- point (%f,%f) in polygon\n", polya->p[i].x, polya->p[i].y);
#endif
- return(FALSE);
- }
+ return (FALSE);
+ }
+ }
+ return (TRUE);
}
- return(TRUE);
- }
#if GEODEBUG
-printf( "poly_contain- bound box ((%f,%f),(%f,%f)) not inside ((%f,%f),(%f,%f))\n",
- polyb->boundbox.low.x,polyb->boundbox.low.y,polyb->boundbox.high.x,polyb->boundbox.high.y,
- polya->boundbox.low.x,polya->boundbox.low.y,polya->boundbox.high.x,polya->boundbox.high.y);
+ printf("poly_contain- bound box ((%f,%f),(%f,%f)) not inside ((%f,%f),(%f,%f))\n",
+ polyb->boundbox.low.x, polyb->boundbox.low.y, polyb->boundbox.high.x, polyb->boundbox.high.y,
+ polya->boundbox.low.x, polya->boundbox.low.y, polya->boundbox.high.x, polya->boundbox.high.y);
#endif
- return(FALSE);
-} /* poly_contain() */
+ return (FALSE);
+} /* poly_contain() */
/*-----------------------------------------------------------------
- * Determine if polygon A is contained by polygon B by determining
+ * Determine if polygon A is contained by polygon B by determining
* if A's bounding box is contained by B's bounding box.
*-----------------------------------------------------------------*/
#if FALSE
-bool poly_contained(POLYGON *polya, POLYGON *polyb)
+bool
+poly_contained(POLYGON * polya, POLYGON * polyb)
{
- return(box_contained(&(polya->boundbox), &(polyb->boundbox)));
+ return (box_contained(&(polya->boundbox), &(polyb->boundbox)));
}
+
#endif
-bool poly_contained(POLYGON *polya, POLYGON *polyb)
+bool
+poly_contained(POLYGON * polya, POLYGON * polyb)
{
- return(poly_contain(polyb, polya));
-} /* poly_contained() */
+ return (poly_contain(polyb, polya));
+} /* poly_contained() */
/* poly_contain_pt()
* Test to see if the point is inside the polygon.
* Code adapted from integer-based routines in
- * Wn: A Server for the HTTP
- * File: wn/image.c
- * Version 1.15.1
- * Copyright (C) 1995 <by John Franks>
+ * Wn: A Server for the HTTP
+ * File: wn/image.c
+ * Version 1.15.1
+ * Copyright (C) 1995 <by John Franks>
* (code offered for use by J. Franks in Linux Journal letter.)
*/
bool
-poly_contain_pt( POLYGON *poly, Point *p)
+poly_contain_pt(POLYGON * poly, Point * p)
{
- if (!PointerIsValid(poly) || !PointerIsValid(p))
- return(FALSE);
+ if (!PointerIsValid(poly) || !PointerIsValid(p))
+ return (FALSE);
- return(point_inside(p, poly->npts, &(poly->p[0])) != 0);
-} /* poly_contain_pt() */
+ return (point_inside(p, poly->npts, &(poly->p[0])) != 0);
+} /* poly_contain_pt() */
bool
-pt_contained_poly( Point *p, POLYGON *poly)
+pt_contained_poly(Point * p, POLYGON * poly)
{
- if (!PointerIsValid(p) || !PointerIsValid(poly))
- return(FALSE);
+ if (!PointerIsValid(p) || !PointerIsValid(poly))
+ return (FALSE);
- return(poly_contain_pt( poly, p));
-} /* pt_contained_poly() */
+ return (poly_contain_pt(poly, p));
+} /* pt_contained_poly() */
-double *
-poly_distance( POLYGON *polya, POLYGON *polyb)
+double *
+poly_distance(POLYGON * polya, POLYGON * polyb)
{
- double *result;
+ double *result;
- if (!PointerIsValid(polya) || !PointerIsValid(polyb))
- return(NULL);
+ if (!PointerIsValid(polya) || !PointerIsValid(polyb))
+ return (NULL);
- result = PALLOCTYPE(double);
+ result = PALLOCTYPE(double);
- *result = 0;
+ *result = 0;
- return(result);
-} /* poly_distance() */
+ return (result);
+} /* poly_distance() */
/***********************************************************************
**
- ** Routines for 2D points.
+ ** Routines for 2D points.
**
***********************************************************************/
-Point *
-point(float8 *x, float8 *y)
+Point *
+point(float8 * x, float8 * y)
{
- if (! (PointerIsValid(x) && PointerIsValid(y)))
- return(NULL);
+ if (!(PointerIsValid(x) && PointerIsValid(y)))
+ return (NULL);
- return(point_construct(*x, *y));
-} /* point() */
+ return (point_construct(*x, *y));
+} /* point() */
-Point *
-point_add(Point *p1, Point *p2)
+Point *
+point_add(Point * p1, Point * p2)
{
- Point *result;
+ Point *result;
- if (! (PointerIsValid(p1) && PointerIsValid(p2)))
- return(NULL);
+ if (!(PointerIsValid(p1) && PointerIsValid(p2)))
+ return (NULL);
- result = PALLOCTYPE(Point);
+ result = PALLOCTYPE(Point);
- result->x = (p1->x + p2->x);
- result->y = (p1->y + p2->y);
+ result->x = (p1->x + p2->x);
+ result->y = (p1->y + p2->y);
- return(result);
-} /* point_add() */
+ return (result);
+} /* point_add() */
-Point *
-point_sub(Point *p1, Point *p2)
+Point *
+point_sub(Point * p1, Point * p2)
{
- Point *result;
+ Point *result;
- if (! (PointerIsValid(p1) && PointerIsValid(p2)))
- return(NULL);
+ if (!(PointerIsValid(p1) && PointerIsValid(p2)))
+ return (NULL);
- result = PALLOCTYPE(Point);
+ result = PALLOCTYPE(Point);
- result->x = (p1->x - p2->x);
- result->y = (p1->y - p2->y);
+ result->x = (p1->x - p2->x);
+ result->y = (p1->y - p2->y);
- return(result);
-} /* point_sub() */
+ return (result);
+} /* point_sub() */
-Point *
-point_mul(Point *p1, Point *p2)
+Point *
+point_mul(Point * p1, Point * p2)
{
- Point *result;
+ Point *result;
- if (! (PointerIsValid(p1) && PointerIsValid(p2)))
- return(NULL);
+ if (!(PointerIsValid(p1) && PointerIsValid(p2)))
+ return (NULL);
- result = PALLOCTYPE(Point);
+ result = PALLOCTYPE(Point);
- result->x = (p1->x*p2->x) - (p1->y*p2->y);
- result->y = (p1->x*p2->y) + (p1->y*p2->x);
+ result->x = (p1->x * p2->x) - (p1->y * p2->y);
+ result->y = (p1->x * p2->y) + (p1->y * p2->x);
- return(result);
-} /* point_mul() */
+ return (result);
+} /* point_mul() */
-Point *
-point_div(Point *p1, Point *p2)
+Point *
+point_div(Point * p1, Point * p2)
{
- Point *result;
- double div;
+ Point *result;
+ double div;
- if (! (PointerIsValid(p1) && PointerIsValid(p2)))
- return(NULL);
+ if (!(PointerIsValid(p1) && PointerIsValid(p2)))
+ return (NULL);
- result = PALLOCTYPE(Point);
+ result = PALLOCTYPE(Point);
- div = (p2->x*p2->x) + (p2->y*p2->y);
+ div = (p2->x * p2->x) + (p2->y * p2->y);
- if (div == 0.0)
- elog(WARN,"point_div: divide by 0.0 error");
+ if (div == 0.0)
+ elog(WARN, "point_div: divide by 0.0 error");
- result->x = ((p1->x*p2->x) + (p1->y*p2->y)) / div;
- result->y = ((p2->x*p1->y) - (p2->y*p1->x)) / div;
+ result->x = ((p1->x * p2->x) + (p1->y * p2->y)) / div;
+ result->y = ((p2->x * p1->y) - (p2->y * p1->x)) / div;
- return(result);
-} /* point_div() */
+ return (result);
+} /* point_div() */
/***********************************************************************
**
- ** Routines for 2D boxes.
+ ** Routines for 2D boxes.
**
***********************************************************************/
-BOX *
-box(Point *p1, Point *p2)
+BOX *
+box(Point * p1, Point * p2)
{
- BOX *result;
+ BOX *result;
- if (! (PointerIsValid(p1) && PointerIsValid(p2)))
- return(NULL);
+ if (!(PointerIsValid(p1) && PointerIsValid(p2)))
+ return (NULL);
- result = box_construct( p1->x, p2->x, p1->y, p2->y);
+ result = box_construct(p1->x, p2->x, p1->y, p2->y);
- return(result);
-} /* box() */
+ return (result);
+} /* box() */
-BOX *
-box_add(BOX *box, Point *p)
+BOX *
+box_add(BOX * box, Point * p)
{
- BOX *result;
+ BOX *result;
- if (! (PointerIsValid(box) && PointerIsValid(p)))
- return(NULL);
+ if (!(PointerIsValid(box) && PointerIsValid(p)))
+ return (NULL);
- result = box_construct( (box->high.x + p->x), (box->low.x + p->x),
- (box->high.y + p->y), (box->low.y + p->y));
+ result = box_construct((box->high.x + p->x), (box->low.x + p->x),
+ (box->high.y + p->y), (box->low.y + p->y));
- return(result);
-} /* box_add() */
+ return (result);
+} /* box_add() */
-BOX *
-box_sub(BOX *box, Point *p)
+BOX *
+box_sub(BOX * box, Point * p)
{
- BOX *result;
+ BOX *result;
- if (! (PointerIsValid(box) && PointerIsValid(p)))
- return(NULL);
+ if (!(PointerIsValid(box) && PointerIsValid(p)))
+ return (NULL);
- result = box_construct( (box->high.x - p->x), (box->low.x - p->x),
- (box->high.y - p->y), (box->low.y - p->y));
+ result = box_construct((box->high.x - p->x), (box->low.x - p->x),
+ (box->high.y - p->y), (box->low.y - p->y));
- return(result);
-} /* box_sub() */
+ return (result);
+} /* box_sub() */
-BOX *
-box_mul(BOX *box, Point *p)
+BOX *
+box_mul(BOX * box, Point * p)
{
- BOX *result;
- Point *high, *low;
+ BOX *result;
+ Point *high,
+ *low;
- if (! (PointerIsValid(box) && PointerIsValid(p)))
- return(NULL);
+ if (!(PointerIsValid(box) && PointerIsValid(p)))
+ return (NULL);
- high = point_mul( &box->high, p);
- low = point_mul( &box->low, p);
+ high = point_mul(&box->high, p);
+ low = point_mul(&box->low, p);
- result = box_construct( high->x, low->x, high->y, low->y);
- PFREE( high);
- PFREE( low);
+ result = box_construct(high->x, low->x, high->y, low->y);
+ PFREE(high);
+ PFREE(low);
- return(result);
-} /* box_mul() */
+ return (result);
+} /* box_mul() */
-BOX *
-box_div(BOX *box, Point *p)
+BOX *
+box_div(BOX * box, Point * p)
{
- BOX *result;
- Point *high, *low;
+ BOX *result;
+ Point *high,
+ *low;
- if (! (PointerIsValid(box) && PointerIsValid(p)))
- return(NULL);
+ if (!(PointerIsValid(box) && PointerIsValid(p)))
+ return (NULL);
- high = point_div( &box->high, p);
- low = point_div( &box->low, p);
+ high = point_div(&box->high, p);
+ low = point_div(&box->low, p);
- result = box_construct( high->x, low->x, high->y, low->y);
- PFREE( high);
- PFREE( low);
+ result = box_construct(high->x, low->x, high->y, low->y);
+ PFREE(high);
+ PFREE(low);
- return(result);
-} /* box_div() */
+ return (result);
+} /* box_div() */
/***********************************************************************
**
- ** Routines for 2D lines.
- ** Lines are not intended to be used as ADTs per se,
- ** but their ops are useful tools for other ADT ops. Thus,
- ** there are few relops.
+ ** Routines for 2D lines.
+ ** Lines are not intended to be used as ADTs per se,
+ ** but their ops are useful tools for other ADT ops. Thus,
+ ** there are few relops.
**
***********************************************************************/
/***********************************************************************
**
- ** Routines for 2D paths.
+ ** Routines for 2D paths.
**
***********************************************************************/
/* path_add()
* Concatenate two paths (only if they are both open).
*/
-PATH *
-path_add(PATH *p1, PATH *p2)
+PATH *
+path_add(PATH * p1, PATH * p2)
{
- PATH *result;
- int size;
- int i;
+ PATH *result;
+ int size;
+ int i;
- if (! (PointerIsValid(p1) && PointerIsValid(p2))
- || p1->closed || p2->closed)
- return(NULL);
+ if (!(PointerIsValid(p1) && PointerIsValid(p2))
+ || p1->closed || p2->closed)
+ return (NULL);
- size = offsetof(PATH, p[0]) + (sizeof(p1->p[0]) * (p1->npts+p2->npts));
- result = PALLOC(size);
+ size = offsetof(PATH, p[0]) + (sizeof(p1->p[0]) * (p1->npts + p2->npts));
+ result = PALLOC(size);
- result->size = size;
- result->npts = (p1->npts+p2->npts);
- result->closed = p1->closed;
+ result->size = size;
+ result->npts = (p1->npts + p2->npts);
+ result->closed = p1->closed;
- for (i=0; i<p1->npts; i++) {
- result->p[i].x = p1->p[i].x;
- result->p[i].y = p1->p[i].y;
- }
- for (i=0; i<p2->npts; i++) {
- result->p[i+p1->npts].x = p2->p[i].x;
- result->p[i+p1->npts].y = p2->p[i].y;
- }
+ for (i = 0; i < p1->npts; i++)
+ {
+ result->p[i].x = p1->p[i].x;
+ result->p[i].y = p1->p[i].y;
+ }
+ for (i = 0; i < p2->npts; i++)
+ {
+ result->p[i + p1->npts].x = p2->p[i].x;
+ result->p[i + p1->npts].y = p2->p[i].y;
+ }
- return(result);
-} /* path_add() */
+ return (result);
+} /* path_add() */
/* path_add_pt()
* Translation operator.
*/
-PATH *
-path_add_pt(PATH *path, Point *point)
+PATH *
+path_add_pt(PATH * path, Point * point)
{
- PATH *result;
- int i;
+ PATH *result;
+ int i;
- if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
- return(NULL);
+ if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
+ return (NULL);
- result = path_copy(path);
+ result = path_copy(path);
- for (i=0; i<path->npts; i++) {
- result->p[i].x += point->x;
- result->p[i].y += point->y;
- }
+ for (i = 0; i < path->npts; i++)
+ {
+ result->p[i].x += point->x;
+ result->p[i].y += point->y;
+ }
- return(result);
-} /* path_add_pt() */
+ return (result);
+} /* path_add_pt() */
-PATH *
-path_sub_pt(PATH *path, Point *point)
+PATH *
+path_sub_pt(PATH * path, Point * point)
{
- PATH *result;
- int i;
+ PATH *result;
+ int i;
- if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
- return(NULL);
+ if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
+ return (NULL);
- result = path_copy(path);
+ result = path_copy(path);
- for (i=0; i<path->npts; i++) {
- result->p[i].x -= point->x;
- result->p[i].y -= point->y;
- }
+ for (i = 0; i < path->npts; i++)
+ {
+ result->p[i].x -= point->x;
+ result->p[i].y -= point->y;
+ }
- return(result);
-} /* path_sub_pt() */
+ return (result);
+} /* path_sub_pt() */
/* path_mul_pt()
* Rotation and scaling operators.
*/
-PATH *
-path_mul_pt(PATH *path, Point *point)
+PATH *
+path_mul_pt(PATH * path, Point * point)
{
- PATH *result;
- Point *p;
- int i;
+ PATH *result;
+ Point *p;
+ int i;
- if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
- return(NULL);
+ if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
+ return (NULL);
- result = path_copy(path);
+ result = path_copy(path);
- for (i=0; i<path->npts; i++) {
- p = point_mul( &path->p[i], point);
- result->p[i].x = p->x;
- result->p[i].y = p->y;
- PFREE(p);
- }
+ for (i = 0; i < path->npts; i++)
+ {
+ p = point_mul(&path->p[i], point);
+ result->p[i].x = p->x;
+ result->p[i].y = p->y;
+ PFREE(p);
+ }
- return(result);
-} /* path_mul_pt() */
+ return (result);
+} /* path_mul_pt() */
-PATH *
-path_div_pt(PATH *path, Point *point)
+PATH *
+path_div_pt(PATH * path, Point * point)
{
- PATH *result;
- Point *p;
- int i;
+ PATH *result;
+ Point *p;
+ int i;
- if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
- return(NULL);
+ if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
+ return (NULL);
- result = path_copy(path);
+ result = path_copy(path);
- for (i=0; i<path->npts; i++) {
- p = point_div( &path->p[i], point);
- result->p[i].x = p->x;
- result->p[i].y = p->y;
- PFREE(p);
- }
+ for (i = 0; i < path->npts; i++)
+ {
+ p = point_div(&path->p[i], point);
+ result->p[i].x = p->x;
+ result->p[i].y = p->y;
+ PFREE(p);
+ }
- return(result);
-} /* path_div_pt() */
+ return (result);
+} /* path_div_pt() */
bool
-path_contain_pt( PATH *path, Point *p)
+path_contain_pt(PATH * path, Point * p)
{
- if (!PointerIsValid(path) || !PointerIsValid(p))
- return(FALSE);
+ if (!PointerIsValid(path) || !PointerIsValid(p))
+ return (FALSE);
- return( (path->closed? (point_inside(p, path->npts, &(path->p[0])) != 0): FALSE));
-} /* path_contain_pt() */
+ return ((path->closed ? (point_inside(p, path->npts, &(path->p[0])) != 0) : FALSE));
+} /* path_contain_pt() */
bool
-pt_contained_path( Point *p, PATH *path)
+pt_contained_path(Point * p, PATH * path)
{
- if (!PointerIsValid(p) || !PointerIsValid(path))
- return(FALSE);
+ if (!PointerIsValid(p) || !PointerIsValid(path))
+ return (FALSE);
- return( path_contain_pt( path, p));
-} /* pt_contained_path() */
+ return (path_contain_pt(path, p));
+} /* pt_contained_path() */
-Point *
-path_center(PATH *path)
+Point *
+path_center(PATH * path)
{
- Point *result;
+ Point *result;
- if (!PointerIsValid(path))
- return(NULL);
+ if (!PointerIsValid(path))
+ return (NULL);
- elog(WARN, "path_center not implemented", NULL);
+ elog(WARN, "path_center not implemented", NULL);
- result = PALLOCTYPE(Point);
- result = NULL;
+ result = PALLOCTYPE(Point);
+ result = NULL;
- return(result);
-} /* path_center() */
+ return (result);
+} /* path_center() */
-POLYGON *path_poly(PATH *path)
+POLYGON *
+path_poly(PATH * path)
{
- POLYGON *poly;
- int size;
- int i;
+ POLYGON *poly;
+ int size;
+ int i;
- if (!PointerIsValid(path))
- return(NULL);
+ if (!PointerIsValid(path))
+ return (NULL);
- if (!path->closed)
- elog(WARN, "Open path cannot be converted to polygon",NULL);
+ if (!path->closed)
+ elog(WARN, "Open path cannot be converted to polygon", NULL);
- size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * path->npts);
- poly = PALLOC(size);
+ size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * path->npts);
+ poly = PALLOC(size);
- poly->size = size;
- poly->npts = path->npts;
+ poly->size = size;
+ poly->npts = path->npts;
- for (i=0; i<path->npts; i++) {
- poly->p[i].x = path->p[i].x;
- poly->p[i].y = path->p[i].y;
- }
+ for (i = 0; i < path->npts; i++)
+ {
+ poly->p[i].x = path->p[i].x;
+ poly->p[i].y = path->p[i].y;
+ }
- make_bound_box(poly);
+ make_bound_box(poly);
- return(poly);
-} /* path_polygon() */
+ return (poly);
+} /* path_polygon() */
/* upgradepath()
@@ -2860,157 +3171,163 @@ POLYGON *path_poly(PATH *path)
*
* Old-style: '(closed,#pts,x1,y1,...)' where closed is a boolean flag
* New-style: '((x1,y1),...)' for closed path
- * '[(x1,y1),...]' for open path
+ * '[(x1,y1),...]' for open path
*/
PATH
-*upgradepath(PATH *path)
+* upgradepath(PATH * path)
{
- PATH *result;
- int size, npts;
- int i;
+ PATH *result;
+ int size,
+ npts;
+ int i;
- if (!PointerIsValid(path) || (path->npts < 2))
- return(NULL);
+ if (!PointerIsValid(path) || (path->npts < 2))
+ return (NULL);
- if (! isoldpath(path))
- elog(WARN,"upgradepath: path already upgraded?",NULL);
+ if (!isoldpath(path))
+ elog(WARN, "upgradepath: path already upgraded?", NULL);
- npts = (path->npts-1);
- size = offsetof(PATH, p[0]) + (sizeof(path->p[0]) * npts);
- result = PALLOC(size);
- memset((char *) result, 0, size);
+ npts = (path->npts - 1);
+ size = offsetof(PATH, p[0]) + (sizeof(path->p[0]) * npts);
+ result = PALLOC(size);
+ memset((char *) result, 0, size);
- result->size = size;
- result->npts = npts;
- result->closed = (path->p[0].x != 0);
+ result->size = size;
+ result->npts = npts;
+ result->closed = (path->p[0].x != 0);
- for (i=0; i<result->npts; i++) {
- result->p[i].x = path->p[i+1].x;
- result->p[i].y = path->p[i+1].y;
- }
+ for (i = 0; i < result->npts; i++)
+ {
+ result->p[i].x = path->p[i + 1].x;
+ result->p[i].y = path->p[i + 1].y;
+ }
- return(result);
-} /* upgradepath() */
+ return (result);
+} /* upgradepath() */
bool
-isoldpath(PATH *path)
+isoldpath(PATH * path)
{
- if (!PointerIsValid(path) || (path->npts < 2))
- return(FALSE);
+ if (!PointerIsValid(path) || (path->npts < 2))
+ return (FALSE);
- return(path->npts == (path->p[0].y+1));
-} /* isoldpath() */
+ return (path->npts == (path->p[0].y + 1));
+} /* isoldpath() */
/***********************************************************************
**
- ** Routines for 2D polygons.
+ ** Routines for 2D polygons.
**
***********************************************************************/
int4
-poly_npoints(POLYGON *poly)
+poly_npoints(POLYGON * poly)
{
- if (!PointerIsValid(poly))
- return(0);
+ if (!PointerIsValid(poly))
+ return (0);
- return(poly->npts);
-} /* poly_npoints() */
+ return (poly->npts);
+} /* poly_npoints() */
-Point *
-poly_center(POLYGON *poly)
+Point *
+poly_center(POLYGON * poly)
{
- Point *result;
- CIRCLE *circle;
+ Point *result;
+ CIRCLE *circle;
- if (!PointerIsValid(poly))
- return(NULL);
+ if (!PointerIsValid(poly))
+ return (NULL);
- if (PointerIsValid(circle = poly_circle(poly))) {
- result = circle_center(circle);
- PFREE(circle);
+ if (PointerIsValid(circle = poly_circle(poly)))
+ {
+ result = circle_center(circle);
+ PFREE(circle);
- } else {
- result = NULL;
- }
+ }
+ else
+ {
+ result = NULL;
+ }
- return(result);
-} /* poly_center() */
+ return (result);
+} /* poly_center() */
-BOX *
-poly_box(POLYGON *poly)
+BOX *
+poly_box(POLYGON * poly)
{
- BOX *box;
+ BOX *box;
- if (!PointerIsValid(poly) || (poly->npts < 1))
- return(NULL);
+ if (!PointerIsValid(poly) || (poly->npts < 1))
+ return (NULL);
- box = box_copy( &poly->boundbox);
+ box = box_copy(&poly->boundbox);
- return(box);
-} /* poly_box() */
+ return (box);
+} /* poly_box() */
/* box_poly()
* Convert a box to a polygon.
*/
-POLYGON *
-box_poly(BOX *box)
+POLYGON *
+box_poly(BOX * box)
{
- POLYGON *poly;
- int size;
+ POLYGON *poly;
+ int size;
- if (!PointerIsValid(box))
- return(NULL);
+ if (!PointerIsValid(box))
+ return (NULL);
- /* map four corners of the box to a polygon */
- size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * 4);
- poly = PALLOC(size);
+ /* map four corners of the box to a polygon */
+ size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * 4);
+ poly = PALLOC(size);
- poly->size = size;
- poly->npts = 4;
+ poly->size = size;
+ poly->npts = 4;
- poly->p[0].x = box->low.x;
- poly->p[0].y = box->low.y;
- poly->p[1].x = box->low.x;
- poly->p[1].y = box->high.y;
- poly->p[2].x = box->high.x;
- poly->p[2].y = box->high.y;
- poly->p[3].x = box->high.x;
- poly->p[3].y = box->low.y;
+ poly->p[0].x = box->low.x;
+ poly->p[0].y = box->low.y;
+ poly->p[1].x = box->low.x;
+ poly->p[1].y = box->high.y;
+ poly->p[2].x = box->high.x;
+ poly->p[2].y = box->high.y;
+ poly->p[3].x = box->high.x;
+ poly->p[3].y = box->low.y;
- box_fill( &poly->boundbox, box->high.x, box->low.x, box->high.y, box->low.y);
+ box_fill(&poly->boundbox, box->high.x, box->low.x, box->high.y, box->low.y);
- return(poly);
-} /* box_poly() */
+ return (poly);
+} /* box_poly() */
-PATH *
-poly_path(POLYGON *poly)
+PATH *
+poly_path(POLYGON * poly)
{
- PATH *path;
- int size;
- int i;
+ PATH *path;
+ int size;
+ int i;
- if (!PointerIsValid(poly) || (poly->npts < 0))
- return(NULL);
+ if (!PointerIsValid(poly) || (poly->npts < 0))
+ return (NULL);
- size = offsetof(PATH, p[0]) + (sizeof(path->p[0]) * poly->npts);
- path = PALLOC(size);
+ size = offsetof(PATH, p[0]) + (sizeof(path->p[0]) * poly->npts);
+ path = PALLOC(size);
- path->size = size;
- path->npts = poly->npts;
- path->closed = TRUE;
+ path->size = size;
+ path->npts = poly->npts;
+ path->closed = TRUE;
- for (i=0; i<poly->npts; i++) {
- path->p[i].x = poly->p[i].x;
- path->p[i].y = poly->p[i].y;
- }
+ for (i = 0; i < poly->npts; i++)
+ {
+ path->p[i].x = poly->p[i].x;
+ path->p[i].y = poly->p[i].y;
+ }
- return(path);
-} /* poly_path() */
+ return (path);
+} /* poly_path() */
/* upgradepoly()
@@ -3019,86 +3336,98 @@ poly_path(POLYGON *poly)
* New-style: '(x1,y1,x2,y2,...)'
*/
POLYGON
-*upgradepoly(POLYGON *poly)
+* upgradepoly(POLYGON * poly)
{
- POLYGON *result;
- int size;
- int n2, i, ii;
+ POLYGON *result;
+ int size;
+ int n2,
+ i,
+ ii;
- if (!PointerIsValid(poly) || (poly->npts < 1))
- return(NULL);
+ if (!PointerIsValid(poly) || (poly->npts < 1))
+ return (NULL);
- size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * poly->npts);
- result = PALLOC(size);
- memset((char *) result, 0, size);
+ size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * poly->npts);
+ result = PALLOC(size);
+ memset((char *) result, 0, size);
- result->size = size;
- result->npts = poly->npts;
+ result->size = size;
+ result->npts = poly->npts;
- n2 = poly->npts/2;
+ n2 = poly->npts / 2;
- for (i=0; i<n2; i++) {
- result->p[2*i].x = poly->p[i].x; /* even indices */
- result->p[2*i+1].x = poly->p[i].y; /* odd indices */
- }
+ for (i = 0; i < n2; i++)
+ {
+ result->p[2 * i].x = poly->p[i].x; /* even indices */
+ result->p[2 * i + 1].x = poly->p[i].y; /* odd indices */
+ }
- if ((ii = ((poly->npts % 2)? 1: 0))) {
- result->p[poly->npts-1].x = poly->p[n2].x;
- result->p[0].y = poly->p[n2].y;
- }
+ if ((ii = ((poly->npts % 2) ? 1 : 0)))
+ {
+ result->p[poly->npts - 1].x = poly->p[n2].x;
+ result->p[0].y = poly->p[n2].y;
+ }
- for (i=0; i<n2; i++) {
- result->p[2*i+ii].y = poly->p[i+n2+ii].x; /* even (+offset) indices */
- result->p[2*i+ii+1].y = poly->p[i+n2+ii].y; /* odd (+offset) indices */
- }
+ for (i = 0; i < n2; i++)
+ {
+ result->p[2 * i + ii].y = poly->p[i + n2 + ii].x; /* even (+offset)
+ * indices */
+ result->p[2 * i + ii + 1].y = poly->p[i + n2 + ii].y; /* odd (+offset) indices */
+ }
- return(result);
-} /* upgradepoly() */
+ return (result);
+} /* upgradepoly() */
/* revertpoly()
* Reverse effect of upgradepoly().
*/
POLYGON
-*revertpoly(POLYGON *poly)
+* revertpoly(POLYGON * poly)
{
- POLYGON *result;
- int size;
- int n2, i, ii;
+ POLYGON *result;
+ int size;
+ int n2,
+ i,
+ ii;
- if (!PointerIsValid(poly) || (poly->npts < 1))
- return(NULL);
+ if (!PointerIsValid(poly) || (poly->npts < 1))
+ return (NULL);
- size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * poly->npts);
- result = PALLOC(size);
- memset((char *) result, 0, size);
+ size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * poly->npts);
+ result = PALLOC(size);
+ memset((char *) result, 0, size);
- result->size = size;
- result->npts = poly->npts;
+ result->size = size;
+ result->npts = poly->npts;
- n2 = poly->npts/2;
+ n2 = poly->npts / 2;
- for (i=0; i<n2; i++) {
- result->p[i].x = poly->p[2*i].x; /* even indices */
- result->p[i].y = poly->p[2*i+1].x; /* odd indices */
- }
+ for (i = 0; i < n2; i++)
+ {
+ result->p[i].x = poly->p[2 * i].x; /* even indices */
+ result->p[i].y = poly->p[2 * i + 1].x; /* odd indices */
+ }
- if ((ii = ((poly->npts % 2)? 1: 0))) {
- result->p[n2].x = poly->p[poly->npts-1].x;
- result->p[n2].y = poly->p[0].y;
- }
+ if ((ii = ((poly->npts % 2) ? 1 : 0)))
+ {
+ result->p[n2].x = poly->p[poly->npts - 1].x;
+ result->p[n2].y = poly->p[0].y;
+ }
- for (i=0; i<n2; i++) {
- result->p[i+n2+ii].x = poly->p[2*i+ii].y; /* even (+offset) indices */
- result->p[i+n2+ii].y = poly->p[2*i+ii+1].y; /* odd (+offset) indices */
- }
+ for (i = 0; i < n2; i++)
+ {
+ result->p[i + n2 + ii].x = poly->p[2 * i + ii].y; /* even (+offset)
+ * indices */
+ result->p[i + n2 + ii].y = poly->p[2 * i + ii + 1].y; /* odd (+offset) indices */
+ }
- return(result);
-} /* revertpoly() */
+ return (result);
+} /* revertpoly() */
/***********************************************************************
**
- ** Routines for circles.
+ ** Routines for circles.
**
***********************************************************************/
@@ -3106,594 +3435,645 @@ POLYGON
* Formatting and conversion routines.
*---------------------------------------------------------*/
-/* circle_in - convert a string to internal form.
+/* circle_in - convert a string to internal form.
*
- * External format: (center and radius of circle)
- * "((f8,f8)<f8>)"
- * also supports quick entry style "(f8,f8,f8)"
+ * External format: (center and radius of circle)
+ * "((f8,f8)<f8>)"
+ * also supports quick entry style "(f8,f8,f8)"
*/
-CIRCLE *circle_in(char *str)
-{
- CIRCLE *circle;
-
- char *s, *cp;
- int depth = 0;
-
- if (!PointerIsValid(str))
- elog (WARN," Bad (null) circle external representation",NULL);
-
- circle = PALLOCTYPE(CIRCLE);
-
- s = str;
- while (isspace( *s)) s++;
- if ((*s == LDELIM_C) || (*s == LDELIM)) {
- depth++;
- cp = (s+1);
- while (isspace( *cp)) cp++;
- if (*cp == LDELIM) {
- s = cp;
+CIRCLE *
+circle_in(char *str)
+{
+ CIRCLE *circle;
+
+ char *s,
+ *cp;
+ int depth = 0;
+
+ if (!PointerIsValid(str))
+ elog(WARN, " Bad (null) circle external representation", NULL);
+
+ circle = PALLOCTYPE(CIRCLE);
+
+ s = str;
+ while (isspace(*s))
+ s++;
+ if ((*s == LDELIM_C) || (*s == LDELIM))
+ {
+ depth++;
+ cp = (s + 1);
+ while (isspace(*cp))
+ cp++;
+ if (*cp == LDELIM)
+ {
+ s = cp;
+ }
}
- }
-
- if (! pair_decode( s, &circle->center.x, &circle->center.y, &s))
- elog (WARN, "Bad circle external representation '%s'",str);
-
- if (*s == DELIM) s++;
- while (isspace( *s)) s++;
- if ((! single_decode( s, &circle->radius, &s)) || (circle->radius < 0))
- elog (WARN, "Bad circle external representation '%s'",str);
-
- while (depth > 0) {
- if ((*s == RDELIM)
- || ((*s == RDELIM_C) && (depth == 1))) {
- depth--;
- s++;
- while (isspace( *s)) s++;
- } else {
- elog (WARN, "Bad circle external representation '%s'",str);
+ if (!pair_decode(s, &circle->center.x, &circle->center.y, &s))
+ elog(WARN, "Bad circle external representation '%s'", str);
+
+ if (*s == DELIM)
+ s++;
+ while (isspace(*s))
+ s++;
+
+ if ((!single_decode(s, &circle->radius, &s)) || (circle->radius < 0))
+ elog(WARN, "Bad circle external representation '%s'", str);
+
+ while (depth > 0)
+ {
+ if ((*s == RDELIM)
+ || ((*s == RDELIM_C) && (depth == 1)))
+ {
+ depth--;
+ s++;
+ while (isspace(*s))
+ s++;
+ }
+ else
+ {
+ elog(WARN, "Bad circle external representation '%s'", str);
+ }
}
- }
- if (*s != '\0')
- elog (WARN, "Bad circle external representation '%s'",str);
+ if (*s != '\0')
+ elog(WARN, "Bad circle external representation '%s'", str);
- return(circle);
-} /* circle_in() */
+ return (circle);
+} /* circle_in() */
-/* circle_out - convert a circle to external form.
+/* circle_out - convert a circle to external form.
*/
-char *circle_out(CIRCLE *circle)
+char *
+circle_out(CIRCLE * circle)
{
- char *result;
- char *cp;
+ char *result;
+ char *cp;
- if (!PointerIsValid(circle))
- return(NULL);
+ if (!PointerIsValid(circle))
+ return (NULL);
- result = PALLOC(3*(P_MAXLEN+1)+3);
+ result = PALLOC(3 * (P_MAXLEN + 1) + 3);
- cp = result;
- *cp++ = LDELIM_C;
- *cp++ = LDELIM;
- if (! pair_encode( circle->center.x, circle->center.y, cp))
- elog (WARN, "Unable to format circle", NULL);
+ cp = result;
+ *cp++ = LDELIM_C;
+ *cp++ = LDELIM;
+ if (!pair_encode(circle->center.x, circle->center.y, cp))
+ elog(WARN, "Unable to format circle", NULL);
- cp += strlen(cp);
- *cp++ = RDELIM;
- *cp++ = DELIM;
- if (! single_encode( circle->radius, cp))
- elog (WARN, "Unable to format circle", NULL);
+ cp += strlen(cp);
+ *cp++ = RDELIM;
+ *cp++ = DELIM;
+ if (!single_encode(circle->radius, cp))
+ elog(WARN, "Unable to format circle", NULL);
- cp += strlen(cp);
- *cp++ = RDELIM_C;
- *cp = '\0';
+ cp += strlen(cp);
+ *cp++ = RDELIM_C;
+ *cp = '\0';
- return(result);
-} /* circle_out() */
+ return (result);
+} /* circle_out() */
/*----------------------------------------------------------
- * Relational operators for CIRCLEs.
- * <, >, <=, >=, and == are based on circle area.
+ * Relational operators for CIRCLEs.
+ * <, >, <=, >=, and == are based on circle area.
*---------------------------------------------------------*/
-/* circles identical?
+/* circles identical?
*/
-bool circle_same(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_same(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPeq(circle1->radius,circle2->radius)
- && FPeq(circle1->center.x,circle2->center.x)
- && FPeq(circle1->center.y,circle2->center.y));
+ return (FPeq(circle1->radius, circle2->radius)
+ && FPeq(circle1->center.x, circle2->center.x)
+ && FPeq(circle1->center.y, circle2->center.y));
}
-/* circle_overlap - does circle1 overlap circle2?
+/* circle_overlap - does circle1 overlap circle2?
*/
-bool circle_overlap(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_overlap(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPle(point_dt(&circle1->center,&circle2->center),(circle1->radius+circle2->radius)));
+ return (FPle(point_dt(&circle1->center, &circle2->center), (circle1->radius + circle2->radius)));
}
-/* circle_overleft - is the right edge of circle1 to the left of
- * the right edge of circle2?
+/* circle_overleft - is the right edge of circle1 to the left of
+ * the right edge of circle2?
*/
-bool circle_overleft(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_overleft(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPle((circle1->center.x+circle1->radius),(circle2->center.x+circle2->radius)));
+ return (FPle((circle1->center.x + circle1->radius), (circle2->center.x + circle2->radius)));
}
-/* circle_left - is circle1 strictly left of circle2?
+/* circle_left - is circle1 strictly left of circle2?
*/
-bool circle_left(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_left(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPle((circle1->center.x+circle1->radius),(circle2->center.x-circle2->radius)));
+ return (FPle((circle1->center.x + circle1->radius), (circle2->center.x - circle2->radius)));
}
-/* circle_right - is circle1 strictly right of circle2?
+/* circle_right - is circle1 strictly right of circle2?
*/
-bool circle_right(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_right(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPge((circle1->center.x-circle1->radius),(circle2->center.x+circle2->radius)));
+ return (FPge((circle1->center.x - circle1->radius), (circle2->center.x + circle2->radius)));
}
-/* circle_overright - is the left edge of circle1 to the right of
- * the left edge of circle2?
+/* circle_overright - is the left edge of circle1 to the right of
+ * the left edge of circle2?
*/
-bool circle_overright(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_overright(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPge((circle1->center.x-circle1->radius),(circle2->center.x-circle2->radius)));
+ return (FPge((circle1->center.x - circle1->radius), (circle2->center.x - circle2->radius)));
}
-/* circle_contained - is circle1 contained by circle2?
+/* circle_contained - is circle1 contained by circle2?
*/
-bool circle_contained(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_contained(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPle((point_dt(&circle1->center,&circle2->center)+circle1->radius),circle2->radius));
+ return (FPle((point_dt(&circle1->center, &circle2->center) + circle1->radius), circle2->radius));
}
-/* circle_contain - does circle1 contain circle2?
+/* circle_contain - does circle1 contain circle2?
*/
-bool circle_contain(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_contain(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPle((point_dt(&circle1->center,&circle2->center)+circle2->radius),circle1->radius));
+ return (FPle((point_dt(&circle1->center, &circle2->center) + circle2->radius), circle1->radius));
}
-/* circle_positionop -
- * is circle1 entirely {above,below} circle2?
+/* circle_positionop -
+ * is circle1 entirely {above,below} circle2?
*/
-bool circle_below(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_below(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPle((circle1->center.y+circle1->radius),(circle2->center.y-circle2->radius)));
+ return (FPle((circle1->center.y + circle1->radius), (circle2->center.y - circle2->radius)));
}
-bool circle_above(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_above(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPge((circle1->center.y-circle1->radius),(circle2->center.y+circle2->radius)));
+ return (FPge((circle1->center.y - circle1->radius), (circle2->center.y + circle2->radius)));
}
-/* circle_relop - is area(circle1) relop area(circle2), within
- * our accuracy constraint?
+/* circle_relop - is area(circle1) relop area(circle2), within
+ * our accuracy constraint?
*/
-bool circle_eq(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_eq(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPeq(circle_ar(circle1), circle_ar(circle2)) );
-} /* circle_eq() */
+ return (FPeq(circle_ar(circle1), circle_ar(circle2)));
+} /* circle_eq() */
-bool circle_ne(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_ne(CIRCLE * circle1, CIRCLE * circle2)
{
- return( !circle_eq(circle1, circle2));
-} /* circle_ne() */
+ return (!circle_eq(circle1, circle2));
+} /* circle_ne() */
-bool circle_lt(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_lt(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPlt(circle_ar(circle1), circle_ar(circle2)) );
-} /* circle_lt() */
+ return (FPlt(circle_ar(circle1), circle_ar(circle2)));
+} /* circle_lt() */
-bool circle_gt(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_gt(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPgt(circle_ar(circle1), circle_ar(circle2)) );
-} /* circle_gt() */
+ return (FPgt(circle_ar(circle1), circle_ar(circle2)));
+} /* circle_gt() */
-bool circle_le(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_le(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPle(circle_ar(circle1), circle_ar(circle2)) );
-} /* circle_le() */
+ return (FPle(circle_ar(circle1), circle_ar(circle2)));
+} /* circle_le() */
-bool circle_ge(CIRCLE *circle1, CIRCLE *circle2)
+bool
+circle_ge(CIRCLE * circle1, CIRCLE * circle2)
{
- return( FPge(circle_ar(circle1), circle_ar(circle2)) );
-} /* circle_ge() */
+ return (FPge(circle_ar(circle1), circle_ar(circle2)));
+} /* circle_ge() */
/*----------------------------------------------------------
- * "Arithmetic" operators on circles.
- * circle_foo returns foo as an object (pointer) that
+ * "Arithmetic" operators on circles.
+ * circle_foo returns foo as an object (pointer) that
can be passed between languages.
- * circle_xx is an internal routine which returns the
- * actual value.
+ * circle_xx is an internal routine which returns the
+ * actual value.
*---------------------------------------------------------*/
-static CIRCLE *
-circle_copy(CIRCLE *circle)
+static CIRCLE *
+circle_copy(CIRCLE * circle)
{
- CIRCLE *result;
+ CIRCLE *result;
- if (!PointerIsValid(circle))
- return NULL;
+ if (!PointerIsValid(circle))
+ return NULL;
- result = PALLOCTYPE(CIRCLE);
+ result = PALLOCTYPE(CIRCLE);
- memmove((char *) result, (char *) circle, sizeof(CIRCLE));
- return(result);
-} /* circle_copy() */
+ memmove((char *) result, (char *) circle, sizeof(CIRCLE));
+ return (result);
+} /* circle_copy() */
/* circle_add_pt()
* Translation operator.
*/
-CIRCLE *
-circle_add_pt(CIRCLE *circle, Point *point)
+CIRCLE *
+circle_add_pt(CIRCLE * circle, Point * point)
{
- CIRCLE *result;
+ CIRCLE *result;
- if (!PointerIsValid(circle) || !PointerIsValid(point))
- return(NULL);
+ if (!PointerIsValid(circle) || !PointerIsValid(point))
+ return (NULL);
- result = circle_copy(circle);
+ result = circle_copy(circle);
- result->center.x += point->x;
- result->center.y += point->y;
+ result->center.x += point->x;
+ result->center.y += point->y;
- return(result);
-} /* circle_add_pt() */
+ return (result);
+} /* circle_add_pt() */
-CIRCLE *
-circle_sub_pt(CIRCLE *circle, Point *point)
+CIRCLE *
+circle_sub_pt(CIRCLE * circle, Point * point)
{
- CIRCLE *result;
+ CIRCLE *result;
- if (!PointerIsValid(circle) || !PointerIsValid(point))
- return(NULL);
+ if (!PointerIsValid(circle) || !PointerIsValid(point))
+ return (NULL);
- result = circle_copy(circle);
+ result = circle_copy(circle);
- result->center.x -= point->x;
- result->center.y -= point->y;
+ result->center.x -= point->x;
+ result->center.y -= point->y;
- return(result);
-} /* circle_sub_pt() */
+ return (result);
+} /* circle_sub_pt() */
/* circle_mul_pt()
* Rotation and scaling operators.
*/
-CIRCLE *
-circle_mul_pt(CIRCLE *circle, Point *point)
+CIRCLE *
+circle_mul_pt(CIRCLE * circle, Point * point)
{
- CIRCLE *result;
- Point *p;
+ CIRCLE *result;
+ Point *p;
- if (!PointerIsValid(circle) || !PointerIsValid(point))
- return(NULL);
+ if (!PointerIsValid(circle) || !PointerIsValid(point))
+ return (NULL);
- result = circle_copy(circle);
+ result = circle_copy(circle);
- p = point_mul( &circle->center, point);
- result->center.x = p->x;
- result->center.y = p->y;
- PFREE(p);
- result->radius *= HYPOT( point->x, point->y);
+ p = point_mul(&circle->center, point);
+ result->center.x = p->x;
+ result->center.y = p->y;
+ PFREE(p);
+ result->radius *= HYPOT(point->x, point->y);
- return(result);
-} /* circle_mul_pt() */
+ return (result);
+} /* circle_mul_pt() */
-CIRCLE *
-circle_div_pt(CIRCLE *circle, Point *point)
+CIRCLE *
+circle_div_pt(CIRCLE * circle, Point * point)
{
- CIRCLE *result;
- Point *p;
+ CIRCLE *result;
+ Point *p;
- if (!PointerIsValid(circle) || !PointerIsValid(point))
- return(NULL);
+ if (!PointerIsValid(circle) || !PointerIsValid(point))
+ return (NULL);
- result = circle_copy(circle);
+ result = circle_copy(circle);
- p = point_div( &circle->center, point);
- result->center.x = p->x;
- result->center.y = p->y;
- PFREE(p);
- result->radius /= HYPOT( point->x, point->y);
+ p = point_div(&circle->center, point);
+ result->center.x = p->x;
+ result->center.y = p->y;
+ PFREE(p);
+ result->radius /= HYPOT(point->x, point->y);
- return(result);
-} /* circle_div_pt() */
+ return (result);
+} /* circle_div_pt() */
-/* circle_area - returns the area of the circle.
+/* circle_area - returns the area of the circle.
*/
-double *circle_area(CIRCLE *circle)
+double *
+circle_area(CIRCLE * circle)
{
- double *result;
+ double *result;
- result = PALLOCTYPE(double);
- *result = circle_ar(circle);
+ result = PALLOCTYPE(double);
+ *result = circle_ar(circle);
- return(result);
+ return (result);
}
-/* circle_diameter - returns the diameter of the circle.
+/* circle_diameter - returns the diameter of the circle.
*/
-double *circle_diameter(CIRCLE *circle)
+double *
+circle_diameter(CIRCLE * circle)
{
- double *result;
+ double *result;
- result = PALLOCTYPE(double);
- *result = (2*circle->radius);
+ result = PALLOCTYPE(double);
+ *result = (2 * circle->radius);
- return(result);
+ return (result);
}
-/* circle_radius - returns the radius of the circle.
+/* circle_radius - returns the radius of the circle.
*/
-double *circle_radius(CIRCLE *circle)
+double *
+circle_radius(CIRCLE * circle)
{
- double *result;
+ double *result;
- result = PALLOCTYPE(double);
- *result = circle->radius;
+ result = PALLOCTYPE(double);
+ *result = circle->radius;
- return(result);
+ return (result);
}
-/* circle_distance - returns the distance between
- * two circles.
+/* circle_distance - returns the distance between
+ * two circles.
*/
-double *circle_distance(CIRCLE *circle1, CIRCLE *circle2)
+double *
+circle_distance(CIRCLE * circle1, CIRCLE * circle2)
{
- double *result;
+ double *result;
- result = PALLOCTYPE(double);
- *result = (point_dt(&circle1->center,&circle2->center)
- - (circle1->radius + circle2->radius));
- if (*result < 0) *result = 0;
+ result = PALLOCTYPE(double);
+ *result = (point_dt(&circle1->center, &circle2->center)
+ - (circle1->radius + circle2->radius));
+ if (*result < 0)
+ *result = 0;
- return(result);
-} /* circle_distance() */
+ return (result);
+} /* circle_distance() */
bool
-circle_contain_pt(CIRCLE *circle, Point *point)
+circle_contain_pt(CIRCLE * circle, Point * point)
{
- bool within;
- double *d;
+ bool within;
+ double *d;
- if (!PointerIsValid(circle) || !PointerIsValid(point))
- return(FALSE);
+ if (!PointerIsValid(circle) || !PointerIsValid(point))
+ return (FALSE);
- d = point_distance(&(circle->center), point);
- within = (*d <= circle->radius);
- PFREE(d);
+ d = point_distance(&(circle->center), point);
+ within = (*d <= circle->radius);
+ PFREE(d);
- return(within);
-} /* circle_contain_pt() */
+ return (within);
+} /* circle_contain_pt() */
bool
-pt_contained_circle(Point *point, CIRCLE *circle)
+pt_contained_circle(Point * point, CIRCLE * circle)
{
- return(circle_contain_pt(circle,point));
-} /* circle_contain_pt() */
+ return (circle_contain_pt(circle, point));
+} /* circle_contain_pt() */
-/* dist_pc - returns the distance between
- * a point and a circle.
+/* dist_pc - returns the distance between
+ * a point and a circle.
*/
-double *dist_pc(Point *point, CIRCLE *circle)
+double *
+dist_pc(Point * point, CIRCLE * circle)
{
- double *result;
+ double *result;
- result = PALLOCTYPE(double);
+ result = PALLOCTYPE(double);
- *result = (point_dt(point,&circle->center) - circle->radius);
- if (*result < 0) *result = 0;
+ *result = (point_dt(point, &circle->center) - circle->radius);
+ if (*result < 0)
+ *result = 0;
- return(result);
-} /* dist_pc() */
+ return (result);
+} /* dist_pc() */
-/* circle_center - returns the center point of the circle.
+/* circle_center - returns the center point of the circle.
*/
-Point *circle_center(CIRCLE *circle)
+Point *
+circle_center(CIRCLE * circle)
{
- Point *result;
+ Point *result;
- result = PALLOCTYPE(Point);
- result->x = circle->center.x;
- result->y = circle->center.y;
+ result = PALLOCTYPE(Point);
+ result->x = circle->center.x;
+ result->y = circle->center.y;
- return(result);
+ return (result);
}
-/* circle_ar - returns the area of the circle.
+/* circle_ar - returns the area of the circle.
*/
-static double circle_ar(CIRCLE *circle)
+static double
+circle_ar(CIRCLE * circle)
{
- return(PI*(circle->radius*circle->radius));
+ return (PI * (circle->radius * circle->radius));
}
-/* circle_dt - returns the distance between the
- * center points of two circlees.
+/* circle_dt - returns the distance between the
+ * center points of two circlees.
*/
#ifdef NOT_USED
-double circle_dt(CIRCLE *circle1, CIRCLE *circle2)
+double
+circle_dt(CIRCLE * circle1, CIRCLE * circle2)
{
- double result;
+ double result;
- result = point_dt(&circle1->center,&circle2->center);
+ result = point_dt(&circle1->center, &circle2->center);
- return(result);
+ return (result);
}
+
#endif
/*----------------------------------------------------------
- * Conversion operators.
+ * Conversion operators.
*---------------------------------------------------------*/
-CIRCLE *circle(Point *center, float8 *radius)
+CIRCLE *
+circle(Point * center, float8 * radius)
{
- CIRCLE *result;
+ CIRCLE *result;
- if (! (PointerIsValid(center) && PointerIsValid(radius)))
- return(NULL);
+ if (!(PointerIsValid(center) && PointerIsValid(radius)))
+ return (NULL);
- result = PALLOCTYPE(CIRCLE);
+ result = PALLOCTYPE(CIRCLE);
- result->center.x = center->x;
- result->center.y = center->y;
- result->radius = *radius;
+ result->center.x = center->x;
+ result->center.y = center->y;
+ result->radius = *radius;
- return(result);
+ return (result);
}
-BOX *
-circle_box(CIRCLE *circle)
+BOX *
+circle_box(CIRCLE * circle)
{
- BOX *box;
- double delta;
+ BOX *box;
+ double delta;
- if (!PointerIsValid(circle))
- return(NULL);
+ if (!PointerIsValid(circle))
+ return (NULL);
- box = PALLOCTYPE(BOX);
+ box = PALLOCTYPE(BOX);
- delta = circle->radius / sqrt(2.0e0);
+ delta = circle->radius / sqrt(2.0e0);
- box->high.x = circle->center.x + delta;
- box->low.x = circle->center.x - delta;
- box->high.y = circle->center.y + delta;
- box->low.y = circle->center.y - delta;
+ box->high.x = circle->center.x + delta;
+ box->low.x = circle->center.x - delta;
+ box->high.y = circle->center.y + delta;
+ box->low.y = circle->center.y - delta;
- return(box);
-} /* circle_box() */
+ return (box);
+} /* circle_box() */
/* box_circle()
* Convert a box to a circle.
*/
-CIRCLE *
-box_circle(BOX *box)
+CIRCLE *
+box_circle(BOX * box)
{
- CIRCLE *circle;
+ CIRCLE *circle;
- if (!PointerIsValid(box))
- return(NULL);
+ if (!PointerIsValid(box))
+ return (NULL);
- circle = PALLOCTYPE(CIRCLE);
+ circle = PALLOCTYPE(CIRCLE);
- circle->center.x = (box->high.x + box->low.x) / 2;
- circle->center.y = (box->high.y + box->low.y) / 2;
+ circle->center.x = (box->high.x + box->low.x) / 2;
+ circle->center.y = (box->high.y + box->low.y) / 2;
- circle->radius = point_dt(&circle->center, &box->high);
+ circle->radius = point_dt(&circle->center, &box->high);
- return(circle);
-} /* box_circle() */
+ return (circle);
+} /* box_circle() */
-POLYGON *circle_poly(int npts, CIRCLE *circle)
+POLYGON *
+circle_poly(int npts, CIRCLE * circle)
{
- POLYGON *poly;
- int size;
- int i;
- double angle;
+ POLYGON *poly;
+ int size;
+ int i;
+ double angle;
- if (!PointerIsValid(circle))
- return(NULL);
+ if (!PointerIsValid(circle))
+ return (NULL);
- if (FPzero(circle->radius) || (npts < 2))
- elog (WARN, "Unable to convert circle to polygon", NULL);
+ if (FPzero(circle->radius) || (npts < 2))
+ elog(WARN, "Unable to convert circle to polygon", NULL);
- size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * npts);
- poly = PALLOC(size);
+ size = offsetof(POLYGON, p[0]) + (sizeof(poly->p[0]) * npts);
+ poly = PALLOC(size);
- memset((char *) poly, 0, size); /* zero any holes */
- poly->size = size;
- poly->npts = npts;
+ memset((char *) poly, 0, size); /* zero any holes */
+ poly->size = size;
+ poly->npts = npts;
- for (i=0;i<npts;i++) {
- angle = i*(2*PI/npts);
- poly->p[i].x = circle->center.x - (circle->radius*cos(angle));
- poly->p[i].y = circle->center.y + (circle->radius*sin(angle));
- }
+ for (i = 0; i < npts; i++)
+ {
+ angle = i * (2 * PI / npts);
+ poly->p[i].x = circle->center.x - (circle->radius * cos(angle));
+ poly->p[i].y = circle->center.y + (circle->radius * sin(angle));
+ }
- make_bound_box(poly);
+ make_bound_box(poly);
- return(poly);
+ return (poly);
}
-/* poly_circle - convert polygon to circle
+/* poly_circle - convert polygon to circle
*
* XXX This algorithm should use weighted means of line segments
- * rather than straight average values of points - tgl 97/01/21.
+ * rather than straight average values of points - tgl 97/01/21.
*/
-CIRCLE *poly_circle(POLYGON *poly)
+CIRCLE *
+poly_circle(POLYGON * poly)
{
- CIRCLE *circle;
- int i;
+ CIRCLE *circle;
+ int i;
- if (!PointerIsValid(poly))
- return(NULL);
+ if (!PointerIsValid(poly))
+ return (NULL);
- if (poly->npts < 2)
- elog (WARN, "Unable to convert polygon to circle", NULL);
+ if (poly->npts < 2)
+ elog(WARN, "Unable to convert polygon to circle", NULL);
- circle = PALLOCTYPE(CIRCLE);
+ circle = PALLOCTYPE(CIRCLE);
- circle->center.x = 0;
- circle->center.y = 0;
- circle->radius = 0;
+ circle->center.x = 0;
+ circle->center.y = 0;
+ circle->radius = 0;
- for (i=0;i<poly->npts;i++) {
- circle->center.x += poly->p[i].x;
- circle->center.y += poly->p[i].y;
- }
- circle->center.x /= poly->npts;
- circle->center.y /= poly->npts;
+ for (i = 0; i < poly->npts; i++)
+ {
+ circle->center.x += poly->p[i].x;
+ circle->center.y += poly->p[i].y;
+ }
+ circle->center.x /= poly->npts;
+ circle->center.y /= poly->npts;
- for (i=0;i<poly->npts;i++) {
- circle->radius += point_dt( &poly->p[i], &circle->center);
- }
- circle->radius /= poly->npts;
+ for (i = 0; i < poly->npts; i++)
+ {
+ circle->radius += point_dt(&poly->p[i], &circle->center);
+ }
+ circle->radius /= poly->npts;
- if (FPzero(circle->radius))
- elog (WARN, "Unable to convert polygon to circle", NULL);
+ if (FPzero(circle->radius))
+ elog(WARN, "Unable to convert polygon to circle", NULL);
- return(circle);
-} /* poly_circle() */
+ return (circle);
+} /* poly_circle() */
/***********************************************************************
**
- ** Private routines for multiple types.
+ ** Private routines for multiple types.
**
***********************************************************************/
#define HIT_IT INT_MAX
static int
-point_inside( Point *p, int npts, Point plist[])
+point_inside(Point * p, int npts, Point plist[])
{
- double x0, y0;
- double px, py;
+ double x0,
+ y0;
+ double px,
+ py;
- int i;
- double x, y;
- int cross, crossnum;
+ int i;
+ double x,
+ y;
+ int cross,
+ crossnum;
/*
* We calculate crossnum, which is twice the crossing number of a
@@ -3704,36 +4084,41 @@ point_inside( Point *p, int npts, Point plist[])
* positive X-axis.
*/
- crossnum = 0;
- i = 0;
- if (npts <= 0) return 0;
+ crossnum = 0;
+ i = 0;
+ if (npts <= 0)
+ return 0;
+
+ x0 = plist[0].x - p->x;
+ y0 = plist[0].y - p->y;
- x0 = plist[0].x - p->x;
- y0 = plist[0].y - p->y;
+ px = x0;
+ py = y0;
+ for (i = 1; i < npts; i++)
+ {
+ x = plist[i].x - p->x;
+ y = plist[i].y - p->y;
- px = x0;
- py = y0;
- for (i = 1; i < npts; i++) {
- x = plist[i].x - p->x;
- y = plist[i].y - p->y;
+ if ((cross = lseg_crossing(x, y, px, py)) == HIT_IT)
+ {
+ return 2;
+ }
+ crossnum += cross;
- if ( (cross = lseg_crossing( x, y, px, py)) == HIT_IT ) {
- return 2;
+ px = x;
+ py = y;
+ }
+ if ((cross = lseg_crossing(x0, y0, px, py)) == HIT_IT)
+ {
+ return 2;
}
crossnum += cross;
-
- px = x;
- py = y;
- }
- if ( (cross = lseg_crossing( x0, y0, px, py)) == HIT_IT ) {
- return 2;
- }
- crossnum += cross;
- if ( crossnum != 0 ) {
- return 1;
- }
- return 0;
-} /* point_inside() */
+ if (crossnum != 0)
+ {
+ return 1;
+ }
+ return 0;
+} /* point_inside() */
/* lseg_crossing()
@@ -3745,91 +4130,115 @@ point_inside( Point *p, int npts, Point plist[])
*/
static int
-lseg_crossing( double x, double y, double px, double py)
+lseg_crossing(double x, double y, double px, double py)
{
- double z;
- int sgn;
+ double z;
+ int sgn;
- /* If (px,py) = (0,0) and not first call we have already sent HIT_IT */
+ /* If (px,py) = (0,0) and not first call we have already sent HIT_IT */
- if (FPzero( y)) {
- if (FPzero( x)) {
- return(HIT_IT);
+ if (FPzero(y))
+ {
+ if (FPzero(x))
+ {
+ return (HIT_IT);
- } else if (FPgt( x, 0)) {
- if (FPzero( py)) return(FPgt( px, 0)? 0 : HIT_IT);
- return(FPlt( py, 0)? 1 : -1);
+ }
+ else if (FPgt(x, 0))
+ {
+ if (FPzero(py))
+ return (FPgt(px, 0) ? 0 : HIT_IT);
+ return (FPlt(py, 0) ? 1 : -1);
- } else { /* x < 0 */
- if (FPzero( py)) return(FPlt( px, 0)? 0 : HIT_IT);
- return(0);
+ }
+ else
+ { /* x < 0 */
+ if (FPzero(py))
+ return (FPlt(px, 0) ? 0 : HIT_IT);
+ return (0);
+ }
}
- }
- /* Now we know y != 0; set sgn to sign of y */
- sgn = (FPgt( y, 0)? 1 : -1);
- if (FPzero( py)) return(FPlt( px, 0)? 0 : sgn);
+ /* Now we know y != 0; set sgn to sign of y */
+ sgn = (FPgt(y, 0) ? 1 : -1);
+ if (FPzero(py))
+ return (FPlt(px, 0) ? 0 : sgn);
- if (FPgt( (sgn * py), 0)) { /* y and py have same sign */
- return(0);
+ if (FPgt((sgn * py), 0))
+ { /* y and py have same sign */
+ return (0);
- } else { /* y and py have opposite signs */
- if (FPge( x, 0) && FPgt( px, 0)) return(2 * sgn);
- if (FPlt( x, 0) && FPle( px, 0)) return(0);
-
- z = (x-px) * y - (y-py) * x;
- if (FPzero( z)) return(HIT_IT);
- return( FPgt( (sgn*z), 0)? 0 : 2 * sgn);
- }
-} /* lseg_crossing() */
+ }
+ else
+ { /* y and py have opposite signs */
+ if (FPge(x, 0) && FPgt(px, 0))
+ return (2 * sgn);
+ if (FPlt(x, 0) && FPle(px, 0))
+ return (0);
+
+ z = (x - px) * y - (y - py) * x;
+ if (FPzero(z))
+ return (HIT_IT);
+ return (FPgt((sgn * z), 0) ? 0 : 2 * sgn);
+ }
+} /* lseg_crossing() */
-static bool
+static bool
plist_same(int npts, Point p1[], Point p2[])
{
- int i, ii, j;
-
- /* find match for first point */
- for (i = 0; i < npts; i++) {
- if ((FPeq( p2[i].x, p1[0].x))
- && (FPeq( p2[i].y, p1[0].y))) {
-
- /* match found? then look forward through remaining points */
- for (ii = 1, j = i+1; ii < npts; ii++, j++) {
- if (j >= npts) j = 0;
- if ((!FPeq( p2[j].x, p1[ii].x))
- || (!FPeq( p2[j].y, p1[ii].y))) {
+ int i,
+ ii,
+ j;
+
+ /* find match for first point */
+ for (i = 0; i < npts; i++)
+ {
+ if ((FPeq(p2[i].x, p1[0].x))
+ && (FPeq(p2[i].y, p1[0].y)))
+ {
+
+ /* match found? then look forward through remaining points */
+ for (ii = 1, j = i + 1; ii < npts; ii++, j++)
+ {
+ if (j >= npts)
+ j = 0;
+ if ((!FPeq(p2[j].x, p1[ii].x))
+ || (!FPeq(p2[j].y, p1[ii].y)))
+ {
#ifdef GEODEBUG
-printf( "plist_same- %d failed forward match with %d\n", j, ii);
+ printf("plist_same- %d failed forward match with %d\n", j, ii);
#endif
- break;
- }
- }
+ break;
+ }
+ }
#ifdef GEODEBUG
-printf( "plist_same- ii = %d/%d after forward match\n", ii, npts);
+ printf("plist_same- ii = %d/%d after forward match\n", ii, npts);
#endif
- if (ii == npts)
- return(TRUE);
-
- /* match not found forwards? then look backwards */
- for (ii = 1, j = i-1; ii < npts; ii++, j--) {
- if (j < 0) j = (npts-1);
- if ((!FPeq( p2[j].x, p1[ii].x))
- || (!FPeq( p2[j].y, p1[ii].y))) {
+ if (ii == npts)
+ return (TRUE);
+
+ /* match not found forwards? then look backwards */
+ for (ii = 1, j = i - 1; ii < npts; ii++, j--)
+ {
+ if (j < 0)
+ j = (npts - 1);
+ if ((!FPeq(p2[j].x, p1[ii].x))
+ || (!FPeq(p2[j].y, p1[ii].y)))
+ {
#ifdef GEODEBUG
-printf( "plist_same- %d failed reverse match with %d\n", j, ii);
+ printf("plist_same- %d failed reverse match with %d\n", j, ii);
#endif
- break;
- }
- }
+ break;
+ }
+ }
#ifdef GEODEBUG
-printf( "plist_same- ii = %d/%d after reverse match\n", ii, npts);
+ printf("plist_same- ii = %d/%d after reverse match\n", ii, npts);
#endif
- if (ii == npts)
- return(TRUE);
+ if (ii == npts)
+ return (TRUE);
+ }
}
- }
-
- return(FALSE);
-} /* plist_same() */
+ return (FALSE);
+} /* plist_same() */
diff --git a/src/backend/utils/adt/geo_selfuncs.c b/src/backend/utils/adt/geo_selfuncs.c
index f0f7bc48d5f..240639d6eda 100644
--- a/src/backend/utils/adt/geo_selfuncs.c
+++ b/src/backend/utils/adt/geo_selfuncs.c
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* geo-selfuncs.c--
- * Selectivity routines registered in the operator catalog in the
- * "oprrest" and "oprjoin" attributes.
+ * Selectivity routines registered in the operator catalog in the
+ * "oprrest" and "oprjoin" attributes.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.3 1997/08/19 21:34:40 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.4 1997/09/07 04:50:20 momjian Exp $
*
- * XXX These are totally bogus.
+ * XXX These are totally bogus.
*
*-------------------------------------------------------------------------
*/
@@ -22,112 +22,116 @@
#include "utils/builtins.h"
float64
-areasel(Oid opid,
- Oid relid,
- AttrNumber attno,
- char *value,
- int32 flag)
+areasel(Oid opid,
+ Oid relid,
+ AttrNumber attno,
+ char *value,
+ int32 flag)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
- *result = 1.0 / 4.0;
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+ *result = 1.0 / 4.0;
+ return (result);
}
float64
areajoinsel(Oid opid,
- Oid relid,
- AttrNumber attno,
- char *value,
- int32 flag)
+ Oid relid,
+ AttrNumber attno,
+ char *value,
+ int32 flag)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
- *result = 1.0 / 4.0;
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+ *result = 1.0 / 4.0;
+ return (result);
}
/*
- * Selectivity functions for rtrees. These are bogus -- unless we know
- * the actual key distribution in the index, we can't make a good prediction
- * of the selectivity of these operators.
+ * Selectivity functions for rtrees. These are bogus -- unless we know
+ * the actual key distribution in the index, we can't make a good prediction
+ * of the selectivity of these operators.
*
- * In general, rtrees need to search multiple subtrees in order to guarantee
- * that all occurrences of the same key have been found. Because of this,
- * the heuristic selectivity functions we return are higher than they would
- * otherwise be.
+ * In general, rtrees need to search multiple subtrees in order to guarantee
+ * that all occurrences of the same key have been found. Because of this,
+ * the heuristic selectivity functions we return are higher than they would
+ * otherwise be.
*/
/*
- * left_sel -- How likely is a box to be strictly left of (right of, above,
- * below) a given box?
+ * left_sel -- How likely is a box to be strictly left of (right of, above,
+ * below) a given box?
*/
#ifdef NOT_USED
float64
leftsel(Oid opid,
- Oid relid,
- AttrNumber attno,
- char *value,
- int32 flag)
+ Oid relid,
+ AttrNumber attno,
+ char *value,
+ int32 flag)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
- *result = 1.0 / 6.0;
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+ *result = 1.0 / 6.0;
+ return (result);
}
+
#endif
#ifdef NOT_USED
float64
leftjoinsel(Oid opid,
- Oid relid,
- AttrNumber attno,
- char *value,
- int32 flag)
+ Oid relid,
+ AttrNumber attno,
+ char *value,
+ int32 flag)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
- *result = 1.0 / 6.0;
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+ *result = 1.0 / 6.0;
+ return (result);
}
+
#endif
/*
- * contsel -- How likely is a box to contain (be contained by) a given box?
+ * contsel -- How likely is a box to contain (be contained by) a given box?
*/
#ifdef NOT_USED
float64
contsel(Oid opid,
- Oid relid,
- AttrNumber attno,
- char *value,
- int32 flag)
+ Oid relid,
+ AttrNumber attno,
+ char *value,
+ int32 flag)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
- *result = 1.0 / 10.0;
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+ *result = 1.0 / 10.0;
+ return (result);
}
+
#endif
#ifdef NOT_USED
float64
contjoinsel(Oid opid,
- Oid relid,
- AttrNumber attno,
- char *value,
- int32 flag)
+ Oid relid,
+ AttrNumber attno,
+ char *value,
+ int32 flag)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
- *result = 1.0 / 10.0;
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+ *result = 1.0 / 10.0;
+ return (result);
}
+
#endif
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index 57f5b32d132..c7ea5f71fcc 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -1,29 +1,29 @@
/*-------------------------------------------------------------------------
*
* int.c--
- * Functions for the built-in integer types.
+ * Functions for the built-in integer types.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.4 1997/03/14 23:20:26 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.5 1997/09/07 04:50:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* OLD COMMENTS
- * I/O routines:
- * int2in, int2out, int28in, int28out, int4in, int4out
- * Conversion routines:
- * itoi
- * Boolean operators:
- * inteq, intne, intlt, intle, intgt, intge
- * Arithmetic operators:
- * intpl, intmi, int4mul, intdiv
+ * I/O routines:
+ * int2in, int2out, int28in, int28out, int4in, int4out
+ * Conversion routines:
+ * itoi
+ * Boolean operators:
+ * inteq, intne, intlt, intle, intgt, intge
+ * Arithmetic operators:
+ * intpl, intmi, int4mul, intdiv
*
- * Arithmetic operators:
- * intmod, int4fac
+ * Arithmetic operators:
+ * intmod, int4fac
*
* XXX makes massive and possibly unwarranted type promotion assumptions.
* fix me when we figure out what we want to do about ANSIfication...
@@ -32,311 +32,482 @@
#include "postgres.h"
#include "fmgr.h"
-#include "utils/builtins.h" /* where the declarations go */
+#include "utils/builtins.h" /* where the declarations go */
-/*****************************************************************************
- * USER I/O ROUTINES *
+/*****************************************************************************
+ * USER I/O ROUTINES *
*****************************************************************************/
/*
- * int2in - converts "num" to short
+ * int2in - converts "num" to short
*/
-int32 int2in(char *num)
+int32
+int2in(char *num)
{
- return((int32) pg_atoi(num, sizeof(int16), '\0'));
+ return ((int32) pg_atoi(num, sizeof(int16), '\0'));
}
/*
- * int2out - converts short to "num"
+ * int2out - converts short to "num"
*/
-char *int2out(int16 sh)
+char *
+int2out(int16 sh)
{
- char *result;
-
- result = (char *)palloc(7); /* assumes sign, 5 digits, '\0' */
- itoa((int) sh, result);
- return(result);
+ char *result;
+
+ result = (char *) palloc(7);/* assumes sign, 5 digits, '\0' */
+ itoa((int) sh, result);
+ return (result);
}
/*
- * int28in - converts "num num ..." to internal form
+ * int28in - converts "num num ..." to internal form
*
- * Note:
- * Fills any nonexistent digits with NULLs.
+ * Note:
+ * Fills any nonexistent digits with NULLs.
*/
-int16 *int28in(char *shs)
-{
- register int16 (*result)[];
- int nums;
-
- if (shs == NULL)
- return(NULL);
- result = (int16 (*)[]) palloc(sizeof(int16 [8]));
- if ((nums = sscanf(shs, "%hd%hd%hd%hd%hd%hd%hd%hd",
- *result,
- *result + 1,
- *result + 2,
- *result + 3,
- *result + 4,
- *result + 5,
- *result + 6,
- *result + 7)) != 8) {
- do
- (*result)[nums++] = 0;
- while (nums < 8);
- }
- return((int16 *) result);
+int16 *
+int28in(char *shs)
+{
+ register int16(*result)[];
+ int nums;
+
+ if (shs == NULL)
+ return (NULL);
+ result = (int16(*)[]) palloc(sizeof(int16[8]));
+ if ((nums = sscanf(shs, "%hd%hd%hd%hd%hd%hd%hd%hd",
+ *result,
+ *result + 1,
+ *result + 2,
+ *result + 3,
+ *result + 4,
+ *result + 5,
+ *result + 6,
+ *result + 7)) != 8)
+ {
+ do
+ (*result)[nums++] = 0;
+ while (nums < 8);
+ }
+ return ((int16 *) result);
}
/*
- * int28out - converts internal form to "num num ..."
+ * int28out - converts internal form to "num num ..."
*/
-char *int28out(int16 (*shs)[])
-{
- register int num;
- register int16 *sp;
- register char *rp;
- char *result;
-
- if (shs == NULL) {
- result = (char *)palloc(2);
- result[0] = '-';
- result[1] = '\0';
- return(result);
- }
- rp = result = (char *)palloc(8 * 7); /* assumes sign, 5 digits, ' ' */
- sp = *shs;
- for (num = 8; num != 0; num--) {
- itoa(*sp++, rp);
- while (*++rp != '\0')
- ;
- *rp++ = ' ';
- }
- *--rp = '\0';
- return(result);
+char *
+int28out(int16(*shs)[])
+{
+ register int num;
+ register int16 *sp;
+ register char *rp;
+ char *result;
+
+ if (shs == NULL)
+ {
+ result = (char *) palloc(2);
+ result[0] = '-';
+ result[1] = '\0';
+ return (result);
+ }
+ rp = result = (char *) palloc(8 * 7); /* assumes sign, 5 digits,
+ * ' ' */
+ sp = *shs;
+ for (num = 8; num != 0; num--)
+ {
+ itoa(*sp++, rp);
+ while (*++rp != '\0')
+ ;
+ *rp++ = ' ';
+ }
+ *--rp = '\0';
+ return (result);
}
/*
- * int28in - converts "num num ..." to internal form
+ * int28in - converts "num num ..." to internal form
*
- * Note:
- * Fills any nonexistent digits with NULLs.
+ * Note:
+ * Fills any nonexistent digits with NULLs.
*/
-int32 *int44in(char *input_string)
-{
- int32 *foo = (int32 *)palloc(4*sizeof(int32));
- register int i = 0;
-
- i = sscanf(input_string,
- "%d, %d, %d, %d",
- &foo[0],
- &foo[1],
- &foo[2],
- &foo[3]);
- while (i < 4)
- foo[i++] = 0;
-
- return(foo);
+int32 *
+int44in(char *input_string)
+{
+ int32 *foo = (int32 *) palloc(4 * sizeof(int32));
+ register int i = 0;
+
+ i = sscanf(input_string,
+ "%d, %d, %d, %d",
+ &foo[0],
+ &foo[1],
+ &foo[2],
+ &foo[3]);
+ while (i < 4)
+ foo[i++] = 0;
+
+ return (foo);
}
/*
- * int28out - converts internal form to "num num ..."
+ * int28out - converts internal form to "num num ..."
*/
-char *int44out(int32 an_array[])
-{
- int temp = 4;
- char *output_string = NULL;
- int i;
-
- if ( temp > 0 ) {
- char *walk;
- output_string = (char *)palloc(16*temp); /* assume 15 digits + sign */
- walk = output_string;
- for ( i = 0 ; i < temp ; i++ ) {
- itoa(an_array[i],walk);
- while (*++walk != '\0')
- ;
- *walk++ = ' ';
+char *
+int44out(int32 an_array[])
+{
+ int temp = 4;
+ char *output_string = NULL;
+ int i;
+
+ if (temp > 0)
+ {
+ char *walk;
+
+ output_string = (char *) palloc(16 * temp); /* assume 15 digits +
+ * sign */
+ walk = output_string;
+ for (i = 0; i < temp; i++)
+ {
+ itoa(an_array[i], walk);
+ while (*++walk != '\0')
+ ;
+ *walk++ = ' ';
+ }
+ *--walk = '\0';
}
- *--walk = '\0';
- }
- return(output_string);
+ return (output_string);
}
-/*****************************************************************************
- * PUBLIC ROUTINES *
+/*****************************************************************************
+ * PUBLIC ROUTINES *
*****************************************************************************/
/*
- * int4in - converts "num" to int4
+ * int4in - converts "num" to int4
*/
-int32 int4in(char *num)
+int32
+int4in(char *num)
{
- return(pg_atoi(num, sizeof(int32), '\0'));
+ return (pg_atoi(num, sizeof(int32), '\0'));
}
/*
- * int4out - converts int4 to "num"
+ * int4out - converts int4 to "num"
*/
-char *int4out(int32 l)
+char *
+int4out(int32 l)
{
- char *result;
-
- result = (char *)palloc(12); /* assumes sign, 10 digits, '\0' */
- ltoa(l, result);
- return(result);
+ char *result;
+
+ result = (char *) palloc(12); /* assumes sign, 10 digits, '\0' */
+ ltoa(l, result);
+ return (result);
}
/*
- * ===================
- * CONVERSION ROUTINES
- * ===================
+ * ===================
+ * CONVERSION ROUTINES
+ * ===================
*/
-int32 i2toi4(int16 arg1)
+int32
+i2toi4(int16 arg1)
{
- return((int32) arg1);
+ return ((int32) arg1);
}
-int16 i4toi2(int32 arg1)
+int16
+i4toi2(int32 arg1)
{
- if (arg1< -0x8000)
- elog(NOTICE, "i4toi2: \"%d\" causes int2 underflow", arg1);
- if (arg1 > 0x7FFF)
- elog(NOTICE, "i4toi2: \"%d\" causes int2 overflow", arg1);
-
- return((int16) arg1);
+ if (arg1 < -0x8000)
+ elog(NOTICE, "i4toi2: \"%d\" causes int2 underflow", arg1);
+ if (arg1 > 0x7FFF)
+ elog(NOTICE, "i4toi2: \"%d\" causes int2 overflow", arg1);
+
+ return ((int16) arg1);
}
/*
- * =========================
- * BOOLEAN OPERATOR ROUTINES
- * =========================
+ * =========================
+ * BOOLEAN OPERATOR ROUTINES
+ * =========================
*/
/*
- * inteq - returns 1 iff arg1 == arg2
- * intne - returns 1 iff arg1 != arg2
- * intlt - returns 1 iff arg1 < arg2
- * intle - returns 1 iff arg1 <= arg2
- * intgt - returns 1 iff arg1 > arg2
- * intge - returns 1 iff arg1 >= arg2
+ * inteq - returns 1 iff arg1 == arg2
+ * intne - returns 1 iff arg1 != arg2
+ * intlt - returns 1 iff arg1 < arg2
+ * intle - returns 1 iff arg1 <= arg2
+ * intgt - returns 1 iff arg1 > arg2
+ * intge - returns 1 iff arg1 >= arg2
*/
-bool int4eq(int32 arg1, int32 arg2) { return(arg1 == arg2); }
-bool int4ne(int32 arg1, int32 arg2) { return(arg1 != arg2); }
-bool int4lt(int32 arg1, int32 arg2) { return(arg1 < arg2); }
-bool int4le(int32 arg1, int32 arg2) { return(arg1 <= arg2); }
-bool int4gt(int32 arg1, int32 arg2) { return(arg1 > arg2); }
-bool int4ge(int32 arg1, int32 arg2) { return(arg1 >= arg2); }
-
-bool int2eq(int16 arg1, int16 arg2) { return(arg1 == arg2); }
-bool int2ne(int16 arg1, int16 arg2) { return(arg1 != arg2); }
-bool int2lt(int16 arg1, int16 arg2) { return(arg1 < arg2); }
-bool int2le(int16 arg1, int16 arg2) { return(arg1 <= arg2); }
-bool int2gt(int16 arg1, int16 arg2) { return(arg1 > arg2); }
-bool int2ge(int16 arg1, int16 arg2) { return(arg1 >= arg2); }
-
-bool int24eq(int32 arg1, int32 arg2) { return(arg1 == arg2); }
-bool int24ne(int32 arg1, int32 arg2) { return(arg1 != arg2); }
-bool int24lt(int32 arg1, int32 arg2) { return(arg1 < arg2); }
-bool int24le(int32 arg1, int32 arg2) { return(arg1 <= arg2); }
-bool int24gt(int32 arg1, int32 arg2) { return(arg1 > arg2); }
-bool int24ge(int32 arg1, int32 arg2) { return(arg1 >= arg2); }
-
-bool int42eq(int32 arg1, int32 arg2) { return(arg1 == arg2); }
-bool int42ne(int32 arg1, int32 arg2) { return(arg1 != arg2); }
-bool int42lt(int32 arg1, int32 arg2) { return(arg1 < arg2); }
-bool int42le(int32 arg1, int32 arg2) { return(arg1 <= arg2); }
-bool int42gt(int32 arg1, int32 arg2) { return(arg1 > arg2); }
-bool int42ge(int32 arg1, int32 arg2) { return(arg1 >= arg2); }
-
-
-bool keyfirsteq(int16 *arg1, int16 arg2) { return(*arg1 == arg2); }
+bool int4eq(int32 arg1, int32 arg2)
+{
+ return (arg1 == arg2);
+}
+bool int4ne(int32 arg1, int32 arg2)
+{
+ return (arg1 != arg2);
+}
+bool int4lt(int32 arg1, int32 arg2)
+{
+ return (arg1 < arg2);
+}
+bool int4le(int32 arg1, int32 arg2)
+{
+ return (arg1 <= arg2);
+}
+bool int4gt(int32 arg1, int32 arg2)
+{
+ return (arg1 > arg2);
+}
+bool int4ge(int32 arg1, int32 arg2)
+{
+ return (arg1 >= arg2);
+}
+
+bool int2eq(int16 arg1, int16 arg2)
+{
+ return (arg1 == arg2);
+}
+bool int2ne(int16 arg1, int16 arg2)
+{
+ return (arg1 != arg2);
+}
+bool int2lt(int16 arg1, int16 arg2)
+{
+ return (arg1 < arg2);
+}
+bool int2le(int16 arg1, int16 arg2)
+{
+ return (arg1 <= arg2);
+}
+bool int2gt(int16 arg1, int16 arg2)
+{
+ return (arg1 > arg2);
+}
+bool int2ge(int16 arg1, int16 arg2)
+{
+ return (arg1 >= arg2);
+}
+
+bool int24eq(int32 arg1, int32 arg2)
+{
+ return (arg1 == arg2);
+}
+bool int24ne(int32 arg1, int32 arg2)
+{
+ return (arg1 != arg2);
+}
+bool int24lt(int32 arg1, int32 arg2)
+{
+ return (arg1 < arg2);
+}
+bool int24le(int32 arg1, int32 arg2)
+{
+ return (arg1 <= arg2);
+}
+bool int24gt(int32 arg1, int32 arg2)
+{
+ return (arg1 > arg2);
+}
+bool int24ge(int32 arg1, int32 arg2)
+{
+ return (arg1 >= arg2);
+}
+
+bool int42eq(int32 arg1, int32 arg2)
+{
+ return (arg1 == arg2);
+}
+bool int42ne(int32 arg1, int32 arg2)
+{
+ return (arg1 != arg2);
+}
+bool int42lt(int32 arg1, int32 arg2)
+{
+ return (arg1 < arg2);
+}
+bool int42le(int32 arg1, int32 arg2)
+{
+ return (arg1 <= arg2);
+}
+bool int42gt(int32 arg1, int32 arg2)
+{
+ return (arg1 > arg2);
+}
+bool int42ge(int32 arg1, int32 arg2)
+{
+ return (arg1 >= arg2);
+}
+
+
+bool keyfirsteq(int16 * arg1, int16 arg2)
+{
+ return (*arg1 == arg2);
+}
/*
- * int[24]pl - returns arg1 + arg2
- * int[24]mi - returns arg1 - arg2
- * int[24]mul - returns arg1 * arg2
- * int[24]div - returns arg1 / arg2
+ * int[24]pl - returns arg1 + arg2
+ * int[24]mi - returns arg1 - arg2
+ * int[24]mul - returns arg1 * arg2
+ * int[24]div - returns arg1 / arg2
*/
-int32 int4um(int32 arg) { return(-arg); }
-int32 int4pl(int32 arg1, int32 arg2) { return(arg1 + arg2); }
-int32 int4mi(int32 arg1, int32 arg2) { return(arg1 - arg2); }
-int32 int4mul(int32 arg1, int32 arg2) { return(arg1 * arg2); }
-int32 int4div(int32 arg1, int32 arg2) { return(arg1 / arg2); }
-int32 int4inc(int32 arg) { return(arg + (int32)1); }
-
-int16 int2um(int16 arg) { return(-arg); }
-int16 int2pl(int16 arg1, int16 arg2) { return(arg1 + arg2); }
-int16 int2mi(int16 arg1, int16 arg2) { return(arg1 - arg2); }
-int16 int2mul(int16 arg1, int16 arg2) { return(arg1 * arg2); }
-int16 int2div(int16 arg1, int16 arg2) { return(arg1 / arg2); }
-int16 int2inc(int16 arg) { return(arg + (int16)1); }
-
-int32 int24pl(int32 arg1, int32 arg2) { return(arg1 + arg2); }
-int32 int24mi(int32 arg1, int32 arg2) { return(arg1 - arg2); }
-int32 int24mul(int32 arg1, int32 arg2) { return(arg1 * arg2); }
-int32 int24div(int32 arg1, int32 arg2) { return(arg1 / arg2); }
-
-int32 int42pl(int32 arg1, int32 arg2) { return(arg1 + arg2); }
-int32 int42mi(int32 arg1, int32 arg2) { return(arg1 - arg2); }
-int32 int42mul(int32 arg1, int32 arg2) { return(arg1 * arg2); }
-int32 int42div(int32 arg1, int32 arg2) { return(arg1 / arg2); }
-
+int32 int4um(int32 arg)
+{
+ return (-arg);
+}
+int32 int4pl(int32 arg1, int32 arg2)
+{
+ return (arg1 + arg2);
+}
+int32 int4mi(int32 arg1, int32 arg2)
+{
+ return (arg1 - arg2);
+}
+int32 int4mul(int32 arg1, int32 arg2)
+{
+ return (arg1 * arg2);
+}
+int32 int4div(int32 arg1, int32 arg2)
+{
+ return (arg1 / arg2);
+}
+int32 int4inc(int32 arg)
+{
+ return (arg + (int32) 1);
+}
+
+int16 int2um(int16 arg)
+{
+ return (-arg);
+}
+int16 int2pl(int16 arg1, int16 arg2)
+{
+ return (arg1 + arg2);
+}
+int16 int2mi(int16 arg1, int16 arg2)
+{
+ return (arg1 - arg2);
+}
+int16 int2mul(int16 arg1, int16 arg2)
+{
+ return (arg1 * arg2);
+}
+int16 int2div(int16 arg1, int16 arg2)
+{
+ return (arg1 / arg2);
+}
+int16 int2inc(int16 arg)
+{
+ return (arg + (int16) 1);
+}
+
+int32 int24pl(int32 arg1, int32 arg2)
+{
+ return (arg1 + arg2);
+}
+int32 int24mi(int32 arg1, int32 arg2)
+{
+ return (arg1 - arg2);
+}
+int32 int24mul(int32 arg1, int32 arg2)
+{
+ return (arg1 * arg2);
+}
+int32 int24div(int32 arg1, int32 arg2)
+{
+ return (arg1 / arg2);
+}
+
+int32 int42pl(int32 arg1, int32 arg2)
+{
+ return (arg1 + arg2);
+}
+int32 int42mi(int32 arg1, int32 arg2)
+{
+ return (arg1 - arg2);
+}
+int32 int42mul(int32 arg1, int32 arg2)
+{
+ return (arg1 * arg2);
+}
+int32 int42div(int32 arg1, int32 arg2)
+{
+ return (arg1 / arg2);
+}
+
/*
- * int[24]mod - returns arg1 mod arg2
+ * int[24]mod - returns arg1 mod arg2
*/
-int32 int4mod(int32 arg1, int32 arg2) { return(arg1 % arg2); }
-int32 int2mod(int16 arg1, int16 arg2) { return(arg1 % arg2); }
-int32 int24mod(int32 arg1, int32 arg2) { return(arg1 % arg2); }
-int32 int42mod(int32 arg1, int32 arg2) { return(arg1 % arg2); }
-
+int32 int4mod(int32 arg1, int32 arg2)
+{
+ return (arg1 % arg2);
+}
+int32 int2mod(int16 arg1, int16 arg2)
+{
+ return (arg1 % arg2);
+}
+int32 int24mod(int32 arg1, int32 arg2)
+{
+ return (arg1 % arg2);
+}
+int32 int42mod(int32 arg1, int32 arg2)
+{
+ return (arg1 % arg2);
+}
+
/*
- * int[24]fac - returns arg1!
+ * int[24]fac - returns arg1!
*/
-int32 int4fac(int32 arg1)
+int32
+int4fac(int32 arg1)
{
- int32 result;
-
- if (arg1 < 1)
- result = 0;
- else
- for (result = 1; arg1 > 0; --arg1)
- result *= arg1;
- return(result);
+ int32 result;
+
+ if (arg1 < 1)
+ result = 0;
+ else
+ for (result = 1; arg1 > 0; --arg1)
+ result *= arg1;
+ return (result);
}
-int32 int2fac(int16 arg1)
+int32
+int2fac(int16 arg1)
{
- int16 result;
-
- if (arg1 < 1)
- result = 0;
- else
- for (result = 1; arg1 > 0; --arg1)
- result *= arg1;
- return(result);
+ int16 result;
+
+ if (arg1 < 1)
+ result = 0;
+ else
+ for (result = 1; arg1 > 0; --arg1)
+ result *= arg1;
+ return (result);
}
-int16 int2larger(int16 arg1, int16 arg2)
+int16
+int2larger(int16 arg1, int16 arg2)
{
- return ((arg1 > arg2) ? arg1 : arg2);
+ return ((arg1 > arg2) ? arg1 : arg2);
}
-int16 int2smaller(int16 arg1, int16 arg2)
+int16
+int2smaller(int16 arg1, int16 arg2)
{
- return ((arg1 < arg2) ? arg1 : arg2);
+ return ((arg1 < arg2) ? arg1 : arg2);
}
-int32 int4larger(int32 arg1, int32 arg2)
+int32
+int4larger(int32 arg1, int32 arg2)
{
- return ((arg1 > arg2) ? arg1 : arg2);
+ return ((arg1 > arg2) ? arg1 : arg2);
}
-int32 int4smaller(int32 arg1, int32 arg2)
+int32
+int4smaller(int32 arg1, int32 arg2)
{
- return ((arg1 < arg2) ? arg1 : arg2);
+ return ((arg1 < arg2) ? arg1 : arg2);
}
diff --git a/src/backend/utils/adt/like.c b/src/backend/utils/adt/like.c
index 50b31514b2a..a3fdbce8855 100644
--- a/src/backend/utils/adt/like.c
+++ b/src/backend/utils/adt/like.c
@@ -1,225 +1,236 @@
/*-------------------------------------------------------------------------
*
* like.c--
- * like expression handling code.
+ * like expression handling code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/utils/adt/like.c,v 1.1 1995/07/30 23:55:36 emkxp01 Exp
+ * /usr/local/devel/pglite/cvs/src/backend/utils/adt/like.c,v 1.1 1995/07/30 23:55:36 emkxp01 Exp
*
*
- * NOTES
- * A big hack of the regexp.c code!! Contributed by
- * Keith Parks <emkxp01@mtcc.demon.co.uk> (7/95).
+ * NOTES
+ * A big hack of the regexp.c code!! Contributed by
+ * Keith Parks <emkxp01@mtcc.demon.co.uk> (7/95).
*
*
*-------------------------------------------------------------------------
*/
#include <string.h>
-#include "postgres.h" /* postgres system include file */
+#include "postgres.h" /* postgres system include file */
#include "utils/palloc.h"
-#include "utils/builtins.h" /* where the function declarations go */
+#include "utils/builtins.h" /* where the function declarations go */
-static int like(char *text, char *p);
+static int like(char *text, char *p);
/*
- * interface routines called by the function manager
+ * interface routines called by the function manager
*/
/*
fixedlen_like:
a generic fixed length like routine
- s - the string to match against (not necessarily null-terminated)
- p - the pattern
- charlen - the length of the string
+ s - the string to match against (not necessarily null-terminated)
+ p - the pattern
+ charlen - the length of the string
*/
-static bool
-fixedlen_like(char *s, struct varlena* p, int charlen)
+static bool
+fixedlen_like(char *s, struct varlena * p, int charlen)
{
- char *sterm, *pterm;
- int result;
-
- if (!s || !p)
- return FALSE;
-
- /* be sure sterm is null-terminated */
- sterm = (char *) palloc(charlen + 1);
- strNcpy(sterm, s, charlen);
-
- /* p is a text = varlena, not a string so we have to make
- * a string from the vl_data field of the struct. */
-
- /* palloc the length of the text + the null character */
- pterm = (char *) palloc(VARSIZE(p) - VARHDRSZ + 1);
- memmove(pterm, VARDATA(p), VARSIZE(p) - VARHDRSZ);
- *(pterm + VARSIZE(p) - VARHDRSZ) = (char)NULL;
-
- /* do the regexp matching */
- result = like(sterm, pterm);
-
- pfree(sterm);
- pfree(pterm);
-
- return ((bool) result);
+ char *sterm,
+ *pterm;
+ int result;
+
+ if (!s || !p)
+ return FALSE;
+
+ /* be sure sterm is null-terminated */
+ sterm = (char *) palloc(charlen + 1);
+ strNcpy(sterm, s, charlen);
+
+ /*
+ * p is a text = varlena, not a string so we have to make a string
+ * from the vl_data field of the struct.
+ */
+
+ /* palloc the length of the text + the null character */
+ pterm = (char *) palloc(VARSIZE(p) - VARHDRSZ + 1);
+ memmove(pterm, VARDATA(p), VARSIZE(p) - VARHDRSZ);
+ *(pterm + VARSIZE(p) - VARHDRSZ) = (char) NULL;
+
+ /* do the regexp matching */
+ result = like(sterm, pterm);
+
+ pfree(sterm);
+ pfree(pterm);
+
+ return ((bool) result);
}
-bool
-char2like(uint16 arg1, struct varlena *p)
+bool
+char2like(uint16 arg1, struct varlena * p)
{
- char *s = (char *) &arg1;
- return (fixedlen_like(s, p, 2));
-}
+ char *s = (char *) &arg1;
-bool
-char2nlike(uint16 arg1, struct varlena *p)
+ return (fixedlen_like(s, p, 2));
+}
+
+bool
+char2nlike(uint16 arg1, struct varlena * p)
{
- return (!char2like(arg1, p));
+ return (!char2like(arg1, p));
}
-bool
-char4like(uint32 arg1, struct varlena *p)
+bool
+char4like(uint32 arg1, struct varlena * p)
{
- char *s = (char *) &arg1;
- return (fixedlen_like(s, p, 4));
+ char *s = (char *) &arg1;
+
+ return (fixedlen_like(s, p, 4));
}
-bool
-char4nlike(uint32 arg1, struct varlena *p)
+bool
+char4nlike(uint32 arg1, struct varlena * p)
{
- return (!char4like(arg1, p));
+ return (!char4like(arg1, p));
}
-bool
-char8like(char *s, struct varlena *p)
+bool
+char8like(char *s, struct varlena * p)
{
- return (fixedlen_like(s, p, 8));
+ return (fixedlen_like(s, p, 8));
}
-bool
-char8nlike(char *s, struct varlena *p)
+bool
+char8nlike(char *s, struct varlena * p)
{
- return (!char8like(s, p));
+ return (!char8like(s, p));
}
-bool
-char16like(char *s, struct varlena *p)
+bool
+char16like(char *s, struct varlena * p)
{
- return (fixedlen_like(s, p, 16));
+ return (fixedlen_like(s, p, 16));
}
-bool
-char16nlike(char *s, struct varlena *p)
+
+bool
+char16nlike(char *s, struct varlena * p)
{
- return (!char16like(s, p));
+ return (!char16like(s, p));
}
-bool
-namelike(NameData *n, struct varlena *p)
+bool
+namelike(NameData * n, struct varlena * p)
{
- if (!n) return FALSE;
- return (fixedlen_like(n->data, p, NAMEDATALEN));
+ if (!n)
+ return FALSE;
+ return (fixedlen_like(n->data, p, NAMEDATALEN));
}
-bool
-namenlike(NameData *s, struct varlena *p)
+bool
+namenlike(NameData * s, struct varlena * p)
{
- return (!namelike(s, p));
+ return (!namelike(s, p));
}
-bool
-textlike(struct varlena *s, struct varlena *p)
+bool
+textlike(struct varlena * s, struct varlena * p)
{
- if (!s) return FALSE;
- return (fixedlen_like(VARDATA(s), p, VARSIZE(s) - VARHDRSZ));
+ if (!s)
+ return FALSE;
+ return (fixedlen_like(VARDATA(s), p, VARSIZE(s) - VARHDRSZ));
}
-bool textnlike(struct varlena *s, struct varlena *p)
+bool
+textnlike(struct varlena * s, struct varlena * p)
{
- return (!textlike(s, p));
+ return (!textlike(s, p));
}
-/* $Revision: 1.6 $
-** "like.c" A first attempt at a LIKE operator for Postgres95.
+/* $Revision: 1.7 $
+** "like.c" A first attempt at a LIKE operator for Postgres95.
+**
+** Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
+** Rich $alz is now <rsalz@bbn.com>.
+** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the LABORT code.
+**
+** This code was shamelessly stolen from the "pql" code by myself and
+** slightly modified :)
+**
+** All references to the word "star" were replaced by "percent"
+** All references to the word "wild" were replaced by "like"
+**
+** All the nice shell RE matching stuff was replaced by just "_" and "%"
**
-** Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
-** Rich $alz is now <rsalz@bbn.com>.
-** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the LABORT code.
-**
-** This code was shamelessly stolen from the "pql" code by myself and
-** slightly modified :)
-**
-** All references to the word "star" were replaced by "percent"
-** All references to the word "wild" were replaced by "like"
-**
-** All the nice shell RE matching stuff was replaced by just "_" and "%"
-**
-** As I don't have a copy of the SQL standard handy I wasn't sure whether
-** to leave in the '\' escape character handling. (I suspect the standard
-** handles "%%" as a single literal percent)
+** As I don't have a copy of the SQL standard handy I wasn't sure whether
+** to leave in the '\' escape character handling. (I suspect the standard
+** handles "%%" as a single literal percent)
**
-** Keith Parks. <keith@mtcc.demon.co.uk>
+** Keith Parks. <keith@mtcc.demon.co.uk>
**
-** [SQL92 lets you specify the escape character by saying
-** LIKE <pattern> ESCAPE <escape character>. We are a small operation
-** so we force you to use '\'. - ay 7/95]
+** [SQL92 lets you specify the escape character by saying
+** LIKE <pattern> ESCAPE <escape character>. We are a small operation
+** so we force you to use '\'. - ay 7/95]
**
*/
-#define LIKE_TRUE 1
-#define LIKE_FALSE 0
-#define LIKE_ABORT -1
+#define LIKE_TRUE 1
+#define LIKE_FALSE 0
+#define LIKE_ABORT -1
/*
-** Match text and p, return LIKE_TRUE, LIKE_FALSE, or LIKE_ABORT.
+** Match text and p, return LIKE_TRUE, LIKE_FALSE, or LIKE_ABORT.
*/
static int
DoMatch(register char *text, register char *p)
{
- register int matched;
-
- for ( ; *p; text++, p++) {
- if (*text == '\0' && *p != '%')
- return LIKE_ABORT;
- switch (*p) {
- case '\\':
- /* Literal match with following character. */
- p++;
- /* FALLTHROUGH */
- default:
- if (*text != *p)
- return LIKE_FALSE;
- continue;
- case '_':
- /* Match anything. */
- continue;
- case '%':
- while (*++p == '%')
- /* Consecutive percents act just like one. */
- continue;
- if (*p == '\0')
- /* Trailing percent matches everything. */
- return LIKE_TRUE;
- while (*text)
- if ((matched = DoMatch(text++, p)) != LIKE_FALSE)
- return matched;
- return LIKE_ABORT;
+ register int matched;
+
+ for (; *p; text++, p++)
+ {
+ if (*text == '\0' && *p != '%')
+ return LIKE_ABORT;
+ switch (*p)
+ {
+ case '\\':
+ /* Literal match with following character. */
+ p++;
+ /* FALLTHROUGH */
+ default:
+ if (*text != *p)
+ return LIKE_FALSE;
+ continue;
+ case '_':
+ /* Match anything. */
+ continue;
+ case '%':
+ while (*++p == '%')
+ /* Consecutive percents act just like one. */
+ continue;
+ if (*p == '\0')
+ /* Trailing percent matches everything. */
+ return LIKE_TRUE;
+ while (*text)
+ if ((matched = DoMatch(text++, p)) != LIKE_FALSE)
+ return matched;
+ return LIKE_ABORT;
+ }
}
- }
- return *text == '\0';
+ return *text == '\0';
}
/*
-** User-level routine. Returns TRUE or FALSE.
+** User-level routine. Returns TRUE or FALSE.
*/
static int
like(char *text, char *p)
{
- if (p[0] == '%' && p[1] == '\0')
- return TRUE;
- return (DoMatch(text, p) == LIKE_TRUE);
+ if (p[0] == '%' && p[1] == '\0')
+ return TRUE;
+ return (DoMatch(text, p) == LIKE_TRUE);
}
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 95dfcfc8ca1..f04152cf6d2 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* misc.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/misc.c,v 1.7 1997/07/28 00:55:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/misc.c,v 1.8 1997/09/07 04:50:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,70 +18,73 @@
#include "catalog/pg_type.h"
#include "utils/builtins.h"
-#include "port-protos.h" /* For random(), sometimes */
+#include "port-protos.h" /* For random(), sometimes */
/*-------------------------------------------------------------------------
- * Check if data is Null
+ * Check if data is Null
*/
bool
-nullvalue(Datum value, bool *isNull)
+nullvalue(Datum value, bool * isNull)
{
- if (*isNull) {
- *isNull = false;
- return(true);
- }
- return(false);
-
+ if (*isNull)
+ {
+ *isNull = false;
+ return (true);
+ }
+ return (false);
+
}
/*----------------------------------------------------------------------*
- * check if data is not Null *
+ * check if data is not Null *
*--------------------------------------------------------------------- */
bool
-nonnullvalue(Datum value, bool *isNull)
+nonnullvalue(Datum value, bool * isNull)
{
- if (*isNull) {
- *isNull = false;
- return(false);
- }
- return(true);
-
+ if (*isNull)
+ {
+ *isNull = false;
+ return (false);
+ }
+ return (true);
+
}
/*
* oidrand (oid o, int4 X)-
- * takes in an oid and a int4 X, and will return 'true'
- * about 1/X of the time.
- * Useful for doing random sampling or subsetting.
- * if X == 0, this will always return true;
+ * takes in an oid and a int4 X, and will return 'true'
+ * about 1/X of the time.
+ * Useful for doing random sampling or subsetting.
+ * if X == 0, this will always return true;
*
* Example use:
- * select * from TEMP where oidrand(TEMP.oid, 10)
+ * select * from TEMP where oidrand(TEMP.oid, 10)
* will return about 1/10 of the tuples in TEMP
*
*/
-bool
+bool
oidrand(Oid o, int32 X)
{
- bool result;
+ bool result;
- if (X == 0) return true;
+ if (X == 0)
+ return true;
- result = (random() % X == 0);
- return result;
+ result = (random() % X == 0);
+ return result;
}
/*
oidsrand(int32 X) -
- seeds the random number generator
- always return true
-*/
+ seeds the random number generator
+ always return true
+*/
bool
oidsrand(int32 X)
{
- srand(X);
- return true;
+ srand(X);
+ return true;
}
@@ -89,5 +92,5 @@ oidsrand(int32 X)
int32
userfntest(int i)
{
- return (i);
+ return (i);
}
diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c
index 0e56a2816ee..9eb5ed36281 100644
--- a/src/backend/utils/adt/nabstime.c
+++ b/src/backend/utils/adt/nabstime.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* nabstime.c--
- * parse almost any absolute date getdate(3) can (& some it can't)
+ * parse almost any absolute date getdate(3) can (& some it can't)
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.31 1997/08/19 21:34:42 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.32 1997/09/07 04:50:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,10 +19,10 @@
#include "postgres.h"
#include <miscadmin.h>
#ifdef HAVE_FLOAT_H
-# include <float.h>
+#include <float.h>
#endif
#ifdef HAVE_LIMITS_H
-# include <limits.h>
+#include <limits.h>
#endif
#ifndef USE_POSIX_TIME
#include <sys/timeb.h>
@@ -30,10 +30,10 @@
#include "utils/builtins.h"
#include "access/xact.h"
-static AbsoluteTime tm2abstime(struct tm *tm, int tz);
+static AbsoluteTime tm2abstime(struct tm * tm, int tz);
-#define MIN_DAYNUM -24856 /* December 13, 1901 */
-#define MAX_DAYNUM 24854 /* January 18, 2038 */
+#define MIN_DAYNUM -24856 /* December 13, 1901 */
+#define MAX_DAYNUM 24854 /* January 18, 2038 */
/* GetCurrentAbsoluteTime()
@@ -45,300 +45,344 @@ static AbsoluteTime tm2abstime(struct tm *tm, int tz);
AbsoluteTime
GetCurrentAbsoluteTime(void)
{
- time_t now;
+ time_t now;
#ifdef USE_POSIX_TIME
- struct tm *tm;
+ struct tm *tm;
- now = time(NULL);
-#else /* ! USE_POSIX_TIME */
- struct timeb tb; /* the old V7-ism */
+ now = time(NULL);
+#else /* ! USE_POSIX_TIME */
+ struct timeb tb; /* the old V7-ism */
- ftime(&tb);
- now = tb.time;
+ ftime(&tb);
+ now = tb.time;
#endif
- if (! HasCTZSet) {
+ if (!HasCTZSet)
+ {
#ifdef USE_POSIX_TIME
#if defined(HAVE_TZSET) && defined(HAVE_INT_TIMEZONE)
- tm = localtime(&now);
-
- CDayLight = tm->tm_isdst;
- CTimeZone = (tm->tm_isdst? (timezone - 3600): timezone);
- strcpy( CTZName, tzname[tm->tm_isdst]);
-#else /* !HAVE_TZSET */
- tm = localtime(&now);
-
- CTimeZone = - tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
- CDayLight = (tm->tm_isdst > 0);
- /* XXX is there a better way to get local timezone string w/o tzname? - tgl 97/03/18 */
- strftime( CTZName, MAXTZLEN, "%Z", tm);
- /* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */
- strcpy(CTZName, tm->tm_zone);
+ tm = localtime(&now);
+
+ CDayLight = tm->tm_isdst;
+ CTimeZone = (tm->tm_isdst ? (timezone - 3600) : timezone);
+ strcpy(CTZName, tzname[tm->tm_isdst]);
+#else /* !HAVE_TZSET */
+ tm = localtime(&now);
+
+ CTimeZone = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
+ CDayLight = (tm->tm_isdst > 0);
+
+ /*
+ * XXX is there a better way to get local timezone string w/o
+ * tzname? - tgl 97/03/18
+ */
+ strftime(CTZName, MAXTZLEN, "%Z", tm);
+
+ /*
+ * XXX FreeBSD man pages indicate that this should work - tgl
+ * 97/04/23
+ */
+ strcpy(CTZName, tm->tm_zone);
+#endif
+#else /* ! USE_POSIX_TIME */
+ CTimeZone = tb.timezone * 60;
+ CDayLight = (tb.dstflag != 0);
+
+ /*
+ * XXX does this work to get the local timezone string in V7? -
+ * tgl 97/03/18
+ */
+ strftime(CTZName, MAXTZLEN, "%Z", localtime(&now));
#endif
-#else /* ! USE_POSIX_TIME */
- CTimeZone = tb.timezone * 60;
- CDayLight = (tb.dstflag != 0);
- /* XXX does this work to get the local timezone string in V7? - tgl 97/03/18 */
- strftime( CTZName, MAXTZLEN, "%Z", localtime(&now));
-#endif
- };
+ };
#ifdef DATEDEBUG
-printf( "GetCurrentAbsoluteTime- timezone is %s -> %d seconds from UTC\n",
- CTZName, CTimeZone);
+ printf("GetCurrentAbsoluteTime- timezone is %s -> %d seconds from UTC\n",
+ CTZName, CTimeZone);
#endif
- return((AbsoluteTime) now);
-} /* GetCurrentAbsoluteTime() */
+ return ((AbsoluteTime) now);
+} /* GetCurrentAbsoluteTime() */
void
-GetCurrentTime(struct tm *tm)
+GetCurrentTime(struct tm * tm)
{
- int tz;
+ int tz;
- abstime2tm( GetCurrentTransactionStartTime(), &tz, tm, NULL);
+ abstime2tm(GetCurrentTransactionStartTime(), &tz, tm, NULL);
- return;
-} /* GetCurrentTime() */
+ return;
+} /* GetCurrentTime() */
void
-abstime2tm(AbsoluteTime time, int *tzp, struct tm *tm, char *tzn)
+abstime2tm(AbsoluteTime time, int *tzp, struct tm * tm, char *tzn)
{
#ifdef USE_POSIX_TIME
- struct tm *tx;
-#else /* ! USE_POSIX_TIME */
- struct timeb tb; /* the old V7-ism */
+ struct tm *tx;
- ftime(&tb);
+#else /* ! USE_POSIX_TIME */
+ struct timeb tb; /* the old V7-ism */
+
+ ftime(&tb);
#endif
#ifdef USE_POSIX_TIME
- if (tzp != NULL) {
- tx = localtime((time_t *) &time);
- } else {
- tx = gmtime((time_t *) &time);
- };
+ if (tzp != NULL)
+ {
+ tx = localtime((time_t *) & time);
+ }
+ else
+ {
+ tx = gmtime((time_t *) & time);
+ };
#else
#endif
#ifdef DATEDEBUG
#ifdef HAVE_INT_TIMEZONE
-printf( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s %s dst=%d\n",
- tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec,
- tzname[0], tzname[1], tx->tm_isdst);
+ printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s %s dst=%d\n",
+ tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec,
+ tzname[0], tzname[1], tx->tm_isdst);
#else
-printf( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s dst=%d\n",
- tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec,
- tx->tm_zone, tx->tm_isdst);
+ printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s dst=%d\n",
+ tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec,
+ tx->tm_zone, tx->tm_isdst);
#endif
#else
#endif
- tm->tm_year = tx->tm_year+1900;
- tm->tm_mon = tx->tm_mon+1;
- tm->tm_mday = tx->tm_mday;
- tm->tm_hour = tx->tm_hour;
- tm->tm_min = tx->tm_min;
- tm->tm_sec = tx->tm_sec;
- tm->tm_isdst = tx->tm_isdst;
+ tm->tm_year = tx->tm_year + 1900;
+ tm->tm_mon = tx->tm_mon + 1;
+ tm->tm_mday = tx->tm_mday;
+ tm->tm_hour = tx->tm_hour;
+ tm->tm_min = tx->tm_min;
+ tm->tm_sec = tx->tm_sec;
+ tm->tm_isdst = tx->tm_isdst;
#ifdef USE_POSIX_TIME
#ifdef HAVE_INT_TIMEZONE
- if (tzp != NULL) *tzp = (tm->tm_isdst? (timezone - 3600): timezone);
- if (tzn != NULL) strcpy( tzn, tzname[tm->tm_isdst]);
-#else /* !HAVE_INT_TIMEZONE */
- tm->tm_gmtoff = tx->tm_gmtoff;
- tm->tm_zone = tx->tm_zone;
-
- if (tzp != NULL) *tzp = - tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
- /* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */
- if (tzn != NULL) strcpy( tzn, tm->tm_zone);
+ if (tzp != NULL)
+ *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
+ if (tzn != NULL)
+ strcpy(tzn, tzname[tm->tm_isdst]);
+#else /* !HAVE_INT_TIMEZONE */
+ tm->tm_gmtoff = tx->tm_gmtoff;
+ tm->tm_zone = tx->tm_zone;
+
+ if (tzp != NULL)
+ *tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
+ /* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */
+ if (tzn != NULL)
+ strcpy(tzn, tm->tm_zone);
+#endif
+#else /* ! USE_POSIX_TIME */
+ if (tzp != NULL)
+ *tzp = tb.timezone * 60;
+
+ /*
+ * XXX does this work to get the local timezone string in V7? - tgl
+ * 97/03/18
+ */
+ if (tzn != NULL)
+ strftime(tzn, MAXTZLEN, "%Z", localtime(&now));
#endif
-#else /* ! USE_POSIX_TIME */
- if (tzp != NULL) *tzp = tb.timezone * 60;
- /* XXX does this work to get the local timezone string in V7? - tgl 97/03/18 */
- if (tzn != NULL) strftime( tzn, MAXTZLEN, "%Z", localtime(&now));
-#endif
- return;
-} /* abstime2tm() */
+ return;
+} /* abstime2tm() */
/* tm2abstime()
* Convert a tm structure to abstime.
* Note that tm has full year (not 1900-based) and 1-based month.
*/
-static AbsoluteTime
-tm2abstime( struct tm *tm, int tz)
+static AbsoluteTime
+tm2abstime(struct tm * tm, int tz)
{
- int day, sec;
+ int day,
+ sec;
- /* validate, before going out of range on some members */
- if (tm->tm_year < 1901 || tm->tm_year > 2038
- || tm->tm_mon < 1 || tm->tm_mon > 12
- || tm->tm_mday < 1 || tm->tm_mday > 31
- || tm->tm_hour < 0 || tm->tm_hour >= 24
- || tm->tm_min < 0 || tm->tm_min > 59
- || tm->tm_sec < 0 || tm->tm_sec > 59)
- return(INVALID_ABSTIME);
+ /* validate, before going out of range on some members */
+ if (tm->tm_year < 1901 || tm->tm_year > 2038
+ || tm->tm_mon < 1 || tm->tm_mon > 12
+ || tm->tm_mday < 1 || tm->tm_mday > 31
+ || tm->tm_hour < 0 || tm->tm_hour >= 24
+ || tm->tm_min < 0 || tm->tm_min > 59
+ || tm->tm_sec < 0 || tm->tm_sec > 59)
+ return (INVALID_ABSTIME);
- day = (date2j( tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j( 1970, 1, 1));
+ day = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(1970, 1, 1));
- /* check for time out of range */
- if ((day < MIN_DAYNUM) || (day > MAX_DAYNUM))
- return(INVALID_ABSTIME);
+ /* check for time out of range */
+ if ((day < MIN_DAYNUM) || (day > MAX_DAYNUM))
+ return (INVALID_ABSTIME);
- /* convert to seconds */
- sec = tm->tm_sec + tz + (tm->tm_min +(day*24 + tm->tm_hour)*60)*60;
+ /* convert to seconds */
+ sec = tm->tm_sec + tz + (tm->tm_min + (day * 24 + tm->tm_hour) * 60) * 60;
- /* check for overflow */
- if ((day == MAX_DAYNUM && sec < 0) ||
- (day == MIN_DAYNUM && sec > 0))
- return(INVALID_ABSTIME);
+ /* check for overflow */
+ if ((day == MAX_DAYNUM && sec < 0) ||
+ (day == MIN_DAYNUM && sec > 0))
+ return (INVALID_ABSTIME);
- /* check for reserved values (e.g. "current" on edge of usual range */
- if (!AbsoluteTimeIsReal(sec))
- return(INVALID_ABSTIME);
+ /* check for reserved values (e.g. "current" on edge of usual range */
+ if (!AbsoluteTimeIsReal(sec))
+ return (INVALID_ABSTIME);
- return(sec);
-} /* tm2abstime() */
+ return (sec);
+} /* tm2abstime() */
/* nabstimein()
* Decode date/time string and return abstime.
*/
AbsoluteTime
-nabstimein(char* str)
+nabstimein(char *str)
{
- AbsoluteTime result;
+ AbsoluteTime result;
- double fsec;
- int tz = 0;
- struct tm date, *tm = &date;
+ double fsec;
+ int tz = 0;
+ struct tm date,
+ *tm = &date;
- char *field[MAXDATEFIELDS];
- char lowstr[MAXDATELEN+1];
- int dtype;
- int nf, ftype[MAXDATEFIELDS];
+ char *field[MAXDATEFIELDS];
+ char lowstr[MAXDATELEN + 1];
+ int dtype;
+ int nf,
+ ftype[MAXDATEFIELDS];
- if (!PointerIsValid(str))
- elog(WARN,"Bad (null) abstime external representation",NULL);
+ if (!PointerIsValid(str))
+ elog(WARN, "Bad (null) abstime external representation", NULL);
- if (strlen(str) > MAXDATELEN)
- elog( WARN, "Bad (length) abstime external representation '%s'",str);
+ if (strlen(str) > MAXDATELEN)
+ elog(WARN, "Bad (length) abstime external representation '%s'", str);
- if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeDateTime( field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
- elog( WARN, "Bad abstime external representation '%s'",str);
+ if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
+ || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
+ elog(WARN, "Bad abstime external representation '%s'", str);
#ifdef DATEDEBUG
-printf( "nabstimein- %d fields are type %d (DTK_DATE=%d)\n", nf, dtype, DTK_DATE);
+ printf("nabstimein- %d fields are type %d (DTK_DATE=%d)\n", nf, dtype, DTK_DATE);
#endif
- switch (dtype) {
- case DTK_DATE:
- result = tm2abstime(tm, tz);
- break;
+ switch (dtype)
+ {
+ case DTK_DATE:
+ result = tm2abstime(tm, tz);
+ break;
- case DTK_EPOCH:
- result = EPOCH_ABSTIME;
- break;
+ case DTK_EPOCH:
+ result = EPOCH_ABSTIME;
+ break;
- case DTK_CURRENT:
- result = CURRENT_ABSTIME;
- break;
+ case DTK_CURRENT:
+ result = CURRENT_ABSTIME;
+ break;
- case DTK_LATE:
- result = NOEND_ABSTIME;
- break;
+ case DTK_LATE:
+ result = NOEND_ABSTIME;
+ break;
- case DTK_EARLY:
- result = NOSTART_ABSTIME;
- break;
+ case DTK_EARLY:
+ result = NOSTART_ABSTIME;
+ break;
- case DTK_INVALID:
- result = INVALID_ABSTIME;
- break;
+ case DTK_INVALID:
+ result = INVALID_ABSTIME;
+ break;
- default:
- elog(WARN,"Bad abstime (internal coding error) '%s'",str);
- result = INVALID_ABSTIME;
- break;
- };
+ default:
+ elog(WARN, "Bad abstime (internal coding error) '%s'", str);
+ result = INVALID_ABSTIME;
+ break;
+ };
- return result;
-} /* nabstimein() */
+ return result;
+} /* nabstimein() */
/* nabstimeout()
* Given an AbsoluteTime return the English text version of the date
*/
-char *
+char *
nabstimeout(AbsoluteTime time)
{
- char* result;
- int tz;
- double fsec = 0;
- struct tm tt, *tm = &tt;
- char buf[MAXDATELEN+1];
- char zone[MAXDATELEN+1], *tzn = zone;
-
- switch (time) {
- case EPOCH_ABSTIME: strcpy(buf, EPOCH); break;
- case INVALID_ABSTIME: strcpy(buf, INVALID); break;
- case CURRENT_ABSTIME: strcpy(buf, DCURRENT); break;
- case NOEND_ABSTIME: strcpy(buf, LATE); break;
- case NOSTART_ABSTIME: strcpy(buf, EARLY); break;
- default:
- abstime2tm( time, &tz, tm, tzn);
+ char *result;
+ int tz;
+ double fsec = 0;
+ struct tm tt,
+ *tm = &tt;
+ char buf[MAXDATELEN + 1];
+ char zone[MAXDATELEN + 1],
+ *tzn = zone;
+
+ switch (time)
+ {
+ case EPOCH_ABSTIME:
+ strcpy(buf, EPOCH);
+ break;
+ case INVALID_ABSTIME:
+ strcpy(buf, INVALID);
+ break;
+ case CURRENT_ABSTIME:
+ strcpy(buf, DCURRENT);
+ break;
+ case NOEND_ABSTIME:
+ strcpy(buf, LATE);
+ break;
+ case NOSTART_ABSTIME:
+ strcpy(buf, EARLY);
+ break;
+ default:
+ abstime2tm(time, &tz, tm, tzn);
#if DATEDEBUG
#endif
- EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
- break;
- }
+ EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
+ break;
+ }
- result = PALLOC(strlen(buf) + 1);
- strcpy(result, buf);
+ result = PALLOC(strlen(buf) + 1);
+ strcpy(result, buf);
- return(result);
-} /* nabstimeout() */
+ return (result);
+} /* nabstimeout() */
/*
- * AbsoluteTimeIsBefore -- true iff time1 is before time2.
- * AbsoluteTimeIsBefore -- true iff time1 is after time2.
+ * AbsoluteTimeIsBefore -- true iff time1 is before time2.
+ * AbsoluteTimeIsBefore -- true iff time1 is after time2.
*/
bool
AbsoluteTimeIsBefore(AbsoluteTime time1, AbsoluteTime time2)
{
- Assert(AbsoluteTimeIsValid(time1));
- Assert(AbsoluteTimeIsValid(time2));
+ Assert(AbsoluteTimeIsValid(time1));
+ Assert(AbsoluteTimeIsValid(time2));
- if (time1 == CURRENT_ABSTIME)
- time1 = GetCurrentTransactionStartTime();
+ if (time1 == CURRENT_ABSTIME)
+ time1 = GetCurrentTransactionStartTime();
- if (time2 == CURRENT_ABSTIME)
- time2 = GetCurrentTransactionStartTime();
+ if (time2 == CURRENT_ABSTIME)
+ time2 = GetCurrentTransactionStartTime();
- return (time1 < time2);
+ return (time1 < time2);
}
bool
AbsoluteTimeIsAfter(AbsoluteTime time1, AbsoluteTime time2)
{
- Assert(AbsoluteTimeIsValid(time1));
- Assert(AbsoluteTimeIsValid(time2));
+ Assert(AbsoluteTimeIsValid(time1));
+ Assert(AbsoluteTimeIsValid(time2));
- if (time1 == CURRENT_ABSTIME)
- time1 = GetCurrentTransactionStartTime();
+ if (time1 == CURRENT_ABSTIME)
+ time1 = GetCurrentTransactionStartTime();
- if (time2 == CURRENT_ABSTIME)
- time2 = GetCurrentTransactionStartTime();
+ if (time2 == CURRENT_ABSTIME)
+ time2 = GetCurrentTransactionStartTime();
- return (time1 > time2);
+ return (time1 > time2);
}
@@ -347,95 +391,95 @@ AbsoluteTimeIsAfter(AbsoluteTime time1, AbsoluteTime time2)
bool
abstime_finite(AbsoluteTime abstime)
{
- return((abstime != INVALID_ABSTIME)
- && (abstime != NOSTART_ABSTIME) && (abstime != NOEND_ABSTIME));
-} /* abstime_datetime() */
+ return ((abstime != INVALID_ABSTIME)
+ && (abstime != NOSTART_ABSTIME) && (abstime != NOEND_ABSTIME));
+} /* abstime_datetime() */
/*
- * abstimeeq - returns 1, iff arguments are equal
- * abstimene - returns 1, iff arguments are not equal
- * abstimelt - returns 1, iff t1 less than t2
- * abstimegt - returns 1, iff t1 greater than t2
- * abstimele - returns 1, iff t1 less than or equal to t2
- * abstimege - returns 1, iff t1 greater than or equal to t2
+ * abstimeeq - returns 1, iff arguments are equal
+ * abstimene - returns 1, iff arguments are not equal
+ * abstimelt - returns 1, iff t1 less than t2
+ * abstimegt - returns 1, iff t1 greater than t2
+ * abstimele - returns 1, iff t1 less than or equal to t2
+ * abstimege - returns 1, iff t1 greater than or equal to t2
*/
bool
abstimeeq(AbsoluteTime t1, AbsoluteTime t2)
{
- if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return(FALSE);
- if (t1 == CURRENT_ABSTIME)
- t1 = GetCurrentTransactionStartTime();
- if (t2 == CURRENT_ABSTIME)
- t2 = GetCurrentTransactionStartTime();
-
- return(t1 == t2);
+ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
+ return (FALSE);
+ if (t1 == CURRENT_ABSTIME)
+ t1 = GetCurrentTransactionStartTime();
+ if (t2 == CURRENT_ABSTIME)
+ t2 = GetCurrentTransactionStartTime();
+
+ return (t1 == t2);
}
bool
abstimene(AbsoluteTime t1, AbsoluteTime t2)
-{
- if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return(FALSE);
- if (t1 == CURRENT_ABSTIME)
- t1 = GetCurrentTransactionStartTime();
- if (t2 == CURRENT_ABSTIME)
- t2 = GetCurrentTransactionStartTime();
-
- return(t1 != t2);
+{
+ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
+ return (FALSE);
+ if (t1 == CURRENT_ABSTIME)
+ t1 = GetCurrentTransactionStartTime();
+ if (t2 == CURRENT_ABSTIME)
+ t2 = GetCurrentTransactionStartTime();
+
+ return (t1 != t2);
}
bool
abstimelt(AbsoluteTime t1, AbsoluteTime t2)
-{
- if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return(FALSE);
- if (t1 == CURRENT_ABSTIME)
- t1 = GetCurrentTransactionStartTime();
- if (t2 == CURRENT_ABSTIME)
- t2 = GetCurrentTransactionStartTime();
-
- return(t1 < t2);
+{
+ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
+ return (FALSE);
+ if (t1 == CURRENT_ABSTIME)
+ t1 = GetCurrentTransactionStartTime();
+ if (t2 == CURRENT_ABSTIME)
+ t2 = GetCurrentTransactionStartTime();
+
+ return (t1 < t2);
}
bool
abstimegt(AbsoluteTime t1, AbsoluteTime t2)
-{
- if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return(FALSE);
- if (t1 == CURRENT_ABSTIME)
- t1 = GetCurrentTransactionStartTime();
- if (t2 == CURRENT_ABSTIME)
- t2 = GetCurrentTransactionStartTime();
-
- return(t1 > t2);
+{
+ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
+ return (FALSE);
+ if (t1 == CURRENT_ABSTIME)
+ t1 = GetCurrentTransactionStartTime();
+ if (t2 == CURRENT_ABSTIME)
+ t2 = GetCurrentTransactionStartTime();
+
+ return (t1 > t2);
}
bool
abstimele(AbsoluteTime t1, AbsoluteTime t2)
-{
- if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return(FALSE);
- if (t1 == CURRENT_ABSTIME)
- t1 = GetCurrentTransactionStartTime();
- if (t2 == CURRENT_ABSTIME)
- t2 = GetCurrentTransactionStartTime();
-
- return(t1 <= t2);
+{
+ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
+ return (FALSE);
+ if (t1 == CURRENT_ABSTIME)
+ t1 = GetCurrentTransactionStartTime();
+ if (t2 == CURRENT_ABSTIME)
+ t2 = GetCurrentTransactionStartTime();
+
+ return (t1 <= t2);
}
bool
abstimege(AbsoluteTime t1, AbsoluteTime t2)
-{
- if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return(FALSE);
- if (t1 == CURRENT_ABSTIME)
- t1 = GetCurrentTransactionStartTime();
- if (t2 == CURRENT_ABSTIME)
- t2 = GetCurrentTransactionStartTime();
-
- return(t1 >= t2);
+{
+ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
+ return (FALSE);
+ if (t1 == CURRENT_ABSTIME)
+ t1 = GetCurrentTransactionStartTime();
+ if (t2 == CURRENT_ABSTIME)
+ t2 = GetCurrentTransactionStartTime();
+
+ return (t1 >= t2);
}
@@ -443,77 +487,93 @@ abstimege(AbsoluteTime t1, AbsoluteTime t2)
* Convert datetime to abstime.
*/
AbsoluteTime
-datetime_abstime(DateTime *datetime)
+datetime_abstime(DateTime * datetime)
{
- AbsoluteTime result;
-
- double fsec;
- struct tm tt, *tm = &tt;
-
- if (!PointerIsValid(datetime)) {
- result = INVALID_ABSTIME;
-
- } else if (DATETIME_IS_INVALID(*datetime)) {
- result = INVALID_ABSTIME;
-
- } else if (DATETIME_IS_NOBEGIN(*datetime)) {
- result = NOSTART_ABSTIME;
-
- } else if (DATETIME_IS_NOEND(*datetime)) {
- result = NOEND_ABSTIME;
-
- } else {
- if (DATETIME_IS_RELATIVE(*datetime)) {
- datetime2tm( SetDateTime(*datetime), NULL, tm, &fsec, NULL);
- result = tm2abstime( tm, 0);
-
- } else if (datetime2tm( *datetime, NULL, tm, &fsec, NULL) == 0) {
- result = tm2abstime( tm, 0);
-
- } else {
- result = INVALID_ABSTIME;
+ AbsoluteTime result;
+
+ double fsec;
+ struct tm tt,
+ *tm = &tt;
+
+ if (!PointerIsValid(datetime))
+ {
+ result = INVALID_ABSTIME;
+
+ }
+ else if (DATETIME_IS_INVALID(*datetime))
+ {
+ result = INVALID_ABSTIME;
+
+ }
+ else if (DATETIME_IS_NOBEGIN(*datetime))
+ {
+ result = NOSTART_ABSTIME;
+
+ }
+ else if (DATETIME_IS_NOEND(*datetime))
+ {
+ result = NOEND_ABSTIME;
+
+ }
+ else
+ {
+ if (DATETIME_IS_RELATIVE(*datetime))
+ {
+ datetime2tm(SetDateTime(*datetime), NULL, tm, &fsec, NULL);
+ result = tm2abstime(tm, 0);
+
+ }
+ else if (datetime2tm(*datetime, NULL, tm, &fsec, NULL) == 0)
+ {
+ result = tm2abstime(tm, 0);
+
+ }
+ else
+ {
+ result = INVALID_ABSTIME;
+ };
};
- };
- return(result);
-} /* datetime_abstime() */
+ return (result);
+} /* datetime_abstime() */
/* abstime_datetime()
* Convert datetime to abstime.
*/
-DateTime *
+DateTime *
abstime_datetime(AbsoluteTime abstime)
{
- DateTime *result;
+ DateTime *result;
- if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
- elog(WARN,"Unable to allocate space to convert abstime to datetime",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
+ elog(WARN, "Unable to allocate space to convert abstime to datetime", NULL);
- switch (abstime) {
- case INVALID_ABSTIME:
- DATETIME_INVALID(*result);
- break;
+ switch (abstime)
+ {
+ case INVALID_ABSTIME:
+ DATETIME_INVALID(*result);
+ break;
- case NOSTART_ABSTIME:
- DATETIME_NOBEGIN(*result);
- break;
+ case NOSTART_ABSTIME:
+ DATETIME_NOBEGIN(*result);
+ break;
- case NOEND_ABSTIME:
- DATETIME_NOEND(*result);
- break;
+ case NOEND_ABSTIME:
+ DATETIME_NOEND(*result);
+ break;
- case EPOCH_ABSTIME:
- DATETIME_EPOCH(*result);
- break;
+ case EPOCH_ABSTIME:
+ DATETIME_EPOCH(*result);
+ break;
- case CURRENT_ABSTIME:
- DATETIME_CURRENT(*result);
- break;
+ case CURRENT_ABSTIME:
+ DATETIME_CURRENT(*result);
+ break;
- default:
- *result = abstime + ((date2j( 1970, 1, 1) - date2j( 2000, 1, 1))*86400);
- break;
- };
+ default:
+ *result = abstime + ((date2j(1970, 1, 1) - date2j(2000, 1, 1)) * 86400);
+ break;
+ };
- return(result);
-} /* abstime_datetime() */
+ return (result);
+} /* abstime_datetime() */
diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c
index 7ef599b3dee..b0de03ff602 100644
--- a/src/backend/utils/adt/name.c
+++ b/src/backend/utils/adt/name.c
@@ -1,203 +1,221 @@
/*-------------------------------------------------------------------------
*
* name.c--
- * Functions for the built-in type "name".
+ * Functions for the built-in type "name".
* name replaces char16 and is carefully implemented so that it
* is a string of length NAMEDATALEN. DO NOT use hard-coded constants anywhere
* always use NAMEDATALEN as the symbolic constant! - jolly 8/21/95
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.6 1997/08/19 21:34:45 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.7 1997/09/07 04:50:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <string.h>
#include "postgres.h"
-#include "utils/builtins.h" /* where the declarations go */
-#include "utils/palloc.h" /* where the declarations go */
+#include "utils/builtins.h" /* where the declarations go */
+#include "utils/palloc.h" /* where the declarations go */
-/*****************************************************************************
- * USER I/O ROUTINES (none) *
+/*****************************************************************************
+ * USER I/O ROUTINES (none) *
*****************************************************************************/
/*
- * namein - converts "..." to internal representation
+ * namein - converts "..." to internal representation
*
- * Note:
- * [Old] Currently if strlen(s) < NAMEDATALEN, the extra chars are nulls
- * Now, always NULL terminated
+ * Note:
+ * [Old] Currently if strlen(s) < NAMEDATALEN, the extra chars are nulls
+ * Now, always NULL terminated
*/
-NameData *namein(char *s)
+NameData *
+namein(char *s)
{
- NameData *result;
-
- if (s == NULL)
- return(NULL);
- result = (NameData*) palloc(NAMEDATALEN);
- /* always keep it null-padded */
- strNcpy(result->data, s, NAMEDATALEN-1);
- return(result);
+ NameData *result;
+
+ if (s == NULL)
+ return (NULL);
+ result = (NameData *) palloc(NAMEDATALEN);
+ /* always keep it null-padded */
+ strNcpy(result->data, s, NAMEDATALEN - 1);
+ return (result);
}
/*
- * nameout - converts internal reprsentation to "..."
+ * nameout - converts internal reprsentation to "..."
*/
-char *nameout(NameData *s)
+char *
+nameout(NameData * s)
{
- if (s == NULL)
- return "-";
- else
- return pstrdup(s->data);
+ if (s == NULL)
+ return "-";
+ else
+ return pstrdup(s->data);
}
-/*****************************************************************************
- * PUBLIC ROUTINES *
+/*****************************************************************************
+ * PUBLIC ROUTINES *
*****************************************************************************/
/*
- * nameeq - returns 1 iff arguments are equal
- * namene - returns 1 iff arguments are not equal
+ * nameeq - returns 1 iff arguments are equal
+ * namene - returns 1 iff arguments are not equal
*
- * BUGS:
- * Assumes that "xy\0\0a" should be equal to "xy\0b".
- * If not, can do the comparison backwards for efficiency.
+ * BUGS:
+ * Assumes that "xy\0\0a" should be equal to "xy\0b".
+ * If not, can do the comparison backwards for efficiency.
*
- * namelt - returns 1 iff a < b
- * namele - returns 1 iff a <= b
- * namegt - returns 1 iff a < b
- * namege - returns 1 iff a <= b
+ * namelt - returns 1 iff a < b
+ * namele - returns 1 iff a <= b
+ * namegt - returns 1 iff a < b
+ * namege - returns 1 iff a <= b
*
*/
-bool nameeq(NameData *arg1, NameData *arg2)
+bool
+nameeq(NameData * arg1, NameData * arg2)
{
- if (!arg1 || !arg2)
- return 0;
- else
- return ((bool) strncmp(arg1->data, arg2->data, NAMEDATALEN) == 0);
+ if (!arg1 || !arg2)
+ return 0;
+ else
+ return ((bool) strncmp(arg1->data, arg2->data, NAMEDATALEN) == 0);
}
-bool namene(NameData *arg1, NameData *arg2)
+bool
+namene(NameData * arg1, NameData * arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return((bool) (strncmp(arg1->data, arg2->data, NAMEDATALEN) != 0));
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return ((bool) (strncmp(arg1->data, arg2->data, NAMEDATALEN) != 0));
}
-bool namelt(NameData *arg1, NameData *arg2)
+bool
+namelt(NameData * arg1, NameData * arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return((bool) (strncmp(arg1->data, arg2->data, NAMEDATALEN) < 0));
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return ((bool) (strncmp(arg1->data, arg2->data, NAMEDATALEN) < 0));
}
-bool namele(NameData *arg1, NameData *arg2)
+bool
+namele(NameData * arg1, NameData * arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- return((bool) (strncmp(arg1->data, arg2->data, NAMEDATALEN) <= 0));
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ return ((bool) (strncmp(arg1->data, arg2->data, NAMEDATALEN) <= 0));
}
-bool namegt(NameData *arg1, NameData *arg2)
+bool
+namegt(NameData * arg1, NameData * arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
-
- return((bool) (strncmp(arg1->data, arg2->data, NAMEDATALEN) > 0));
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+
+ return ((bool) (strncmp(arg1->data, arg2->data, NAMEDATALEN) > 0));
}
-bool namege(NameData *arg1, NameData *arg2)
+bool
+namege(NameData * arg1, NameData * arg2)
{
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
-
- return((bool) (strncmp(arg1->data, arg2->data, NAMEDATALEN) >= 0));
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+
+ return ((bool) (strncmp(arg1->data, arg2->data, NAMEDATALEN) >= 0));
}
/* (see char.c for comparison/operation routines) */
-int namecpy(Name n1, Name n2)
+int
+namecpy(Name n1, Name n2)
{
- if (!n1 || !n2)
- return(-1);
- strncpy(n1->data, n2->data, NAMEDATALEN);
- return(0);
+ if (!n1 || !n2)
+ return (-1);
+ strncpy(n1->data, n2->data, NAMEDATALEN);
+ return (0);
}
#ifdef NOT_USED
-int namecat(Name n1, Name n2)
+int
+namecat(Name n1, Name n2)
{
- return(namestrcat(n1, n2->data)); /* n2 can't be any longer than n1 */
+ return (namestrcat(n1, n2->data)); /* n2 can't be any longer than n1 */
}
+
#endif
-int namecmp(Name n1, Name n2)
+int
+namecmp(Name n1, Name n2)
{
- return(strncmp(n1->data, n2->data, NAMEDATALEN));
+ return (strncmp(n1->data, n2->data, NAMEDATALEN));
}
-int
+int
namestrcpy(Name name, char *str)
{
- if (!name || !str)
- return(-1);
- strNcpy(name->data, str, NAMEDATALEN-1);
- return(0);
+ if (!name || !str)
+ return (-1);
+ strNcpy(name->data, str, NAMEDATALEN - 1);
+ return (0);
}
#ifdef NOT_USED
-int namestrcat(Name name, char *str)
+int
+namestrcat(Name name, char *str)
{
- int i;
- char *p, *q;
-
- if (!name || !str)
- return(-1);
- for (i = 0, p = name->data; i < NAMEDATALEN && *p; ++i, ++p)
- ;
- for (q = str; i < NAMEDATALEN; ++i, ++p, ++q) {
- *p = *q;
- if (!*q)
- break;
- }
- return(0);
+ int i;
+ char *p,
+ *q;
+
+ if (!name || !str)
+ return (-1);
+ for (i = 0, p = name->data; i < NAMEDATALEN && *p; ++i, ++p)
+ ;
+ for (q = str; i < NAMEDATALEN; ++i, ++p, ++q)
+ {
+ *p = *q;
+ if (!*q)
+ break;
+ }
+ return (0);
}
+
#endif
-int
+int
namestrcmp(Name name, char *str)
{
- if (!name && !str)
- return(0);
- if (!name)
- return(-1); /* NULL < anything */
- if (!str)
- return(1); /* NULL < anything */
- return(strncmp(name->data, str, NAMEDATALEN));
+ if (!name && !str)
+ return (0);
+ if (!name)
+ return (-1); /* NULL < anything */
+ if (!str)
+ return (1); /* NULL < anything */
+ return (strncmp(name->data, str, NAMEDATALEN));
}
-/*****************************************************************************
- * PRIVATE ROUTINES *
+/*****************************************************************************
+ * PRIVATE ROUTINES *
*****************************************************************************/
#ifdef NOT_USED
-uint32
+uint32
NameComputeLength(Name name)
{
- char *charP;
- int length;
-
- for (length = 0, charP = name->data;
- length < NAMEDATALEN && *charP != '\0';
- length++, charP++) {
- ;
- }
- return (uint32)length;
+ char *charP;
+ int length;
+
+ for (length = 0, charP = name->data;
+ length < NAMEDATALEN && *charP != '\0';
+ length++, charP++)
+ {
+ ;
+ }
+ return (uint32) length;
}
+
#endif
diff --git a/src/backend/utils/adt/not_in.c b/src/backend/utils/adt/not_in.c
index a78e7dc31ce..0bc51eb6f19 100644
--- a/src/backend/utils/adt/not_in.c
+++ b/src/backend/utils/adt/not_in.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* not_in.c--
- * Executes the "not_in" operator for any data type
+ * Executes the "not_in" operator for any data type
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.3 1997/08/19 21:34:48 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.4 1997/09/07 04:50:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,81 +27,85 @@
#include "postgres.h"
#include "access/heapam.h"
#include "access/relscan.h"
-#include "utils/builtins.h" /* where function decls go */
+#include "utils/builtins.h" /* where function decls go */
-static int my_varattno(Relation rd, char *a);
+static int my_varattno(Relation rd, char *a);
/* ----------------------------------------------------------------
- *
+ *
* ----------------------------------------------------------------
*/
bool
int4notin(int16 not_in_arg, char *relation_and_attr)
{
- Relation relation_to_scan;
- int left_side_argument, integer_value;
- HeapTuple current_tuple;
- HeapScanDesc scan_descriptor;
- bool dummy, retval;
- int attrid;
- char *relation, *attribute;
- char my_copy[32];
- Datum value;
- NameData relNameData;
- ScanKeyData skeyData;
-
- strcpy(my_copy, relation_and_attr);
-
- relation = (char *) strtok(my_copy, ".");
- attribute = (char *) strtok(NULL, ".");
-
-
- /* fetch tuple OID */
-
- left_side_argument = not_in_arg;
-
- /* Open the relation and get a relation descriptor */
-
- namestrcpy(&relNameData,relation);
- relation_to_scan = heap_openr(relNameData.data);
- attrid = my_varattno(relation_to_scan, attribute);
-
- /* the last argument should be a ScanKey, not an integer! - jolly*/
- /* it looks like the arguments are out of order, too */
- /* but skeyData is never initialized! does this work?? - ay 2/95 */
- scan_descriptor = heap_beginscan(relation_to_scan, false, NULL, 0,
- &skeyData);
-
- retval = true;
-
- /* do a scan of the relation, and do the check */
- for (current_tuple = heap_getnext(scan_descriptor, 0, NULL);
- current_tuple != NULL && retval;
- current_tuple = heap_getnext(scan_descriptor, 0, NULL))
+ Relation relation_to_scan;
+ int left_side_argument,
+ integer_value;
+ HeapTuple current_tuple;
+ HeapScanDesc scan_descriptor;
+ bool dummy,
+ retval;
+ int attrid;
+ char *relation,
+ *attribute;
+ char my_copy[32];
+ Datum value;
+ NameData relNameData;
+ ScanKeyData skeyData;
+
+ strcpy(my_copy, relation_and_attr);
+
+ relation = (char *) strtok(my_copy, ".");
+ attribute = (char *) strtok(NULL, ".");
+
+
+ /* fetch tuple OID */
+
+ left_side_argument = not_in_arg;
+
+ /* Open the relation and get a relation descriptor */
+
+ namestrcpy(&relNameData, relation);
+ relation_to_scan = heap_openr(relNameData.data);
+ attrid = my_varattno(relation_to_scan, attribute);
+
+ /* the last argument should be a ScanKey, not an integer! - jolly */
+ /* it looks like the arguments are out of order, too */
+ /* but skeyData is never initialized! does this work?? - ay 2/95 */
+ scan_descriptor = heap_beginscan(relation_to_scan, false, NULL, 0,
+ &skeyData);
+
+ retval = true;
+
+ /* do a scan of the relation, and do the check */
+ for (current_tuple = heap_getnext(scan_descriptor, 0, NULL);
+ current_tuple != NULL && retval;
+ current_tuple = heap_getnext(scan_descriptor, 0, NULL))
{
- value = PointerGetDatum(heap_getattr(current_tuple,
- InvalidBuffer,
- (AttrNumber) attrid,
- RelationGetTupleDescriptor(relation_to_scan),
- &dummy));
-
- integer_value = DatumGetInt16(value);
- if (left_side_argument == integer_value)
+ value = PointerGetDatum(heap_getattr(current_tuple,
+ InvalidBuffer,
+ (AttrNumber) attrid,
+ RelationGetTupleDescriptor(relation_to_scan),
+ &dummy));
+
+ integer_value = DatumGetInt16(value);
+ if (left_side_argument == integer_value)
{
- retval = false;
+ retval = false;
}
}
-
- /* close the relation */
- heap_close(relation_to_scan);
- return(retval);
+
+ /* close the relation */
+ heap_close(relation_to_scan);
+ return (retval);
}
-bool oidnotin(Oid the_oid, char *compare)
+bool
+oidnotin(Oid the_oid, char *compare)
{
- if (the_oid == InvalidOid)
- return false;
- return(int4notin(the_oid, compare));
+ if (the_oid == InvalidOid)
+ return false;
+ return (int4notin(the_oid, compare));
}
/*
@@ -109,15 +113,17 @@ bool oidnotin(Oid the_oid, char *compare)
* If varattno (in parser/catalog_utils.h) ever is added to
* cinterface.a, this routine should go away
*/
-static int my_varattno(Relation rd, char *a)
+static int
+my_varattno(Relation rd, char *a)
{
- int i;
-
- for (i = 0; i < rd->rd_rel->relnatts; i++) {
- if (!namestrcmp(&rd->rd_att->attrs[i]->attname, a)) {
- return(i+1);
+ int i;
+
+ for (i = 0; i < rd->rd_rel->relnatts; i++)
+ {
+ if (!namestrcmp(&rd->rd_att->attrs[i]->attname, a))
+ {
+ return (i + 1);
+ }
}
- }
- return(-1);
+ return (-1);
}
-
diff --git a/src/backend/utils/adt/numutils.c b/src/backend/utils/adt/numutils.c
index 7f14317a700..3fd4ae382be 100644
--- a/src/backend/utils/adt/numutils.c
+++ b/src/backend/utils/adt/numutils.c
@@ -1,410 +1,449 @@
/*-------------------------------------------------------------------------
*
* numutils.c--
- * utility functions for I/O of built-in numeric types.
+ * utility functions for I/O of built-in numeric types.
*
- * integer: itoa, ltoa
- * floating point: ftoa, atof1
+ * integer: itoa, ltoa
+ * floating point: ftoa, atof1
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/numutils.c,v 1.13 1997/08/19 21:34:51 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/numutils.c,v 1.14 1997/09/07 04:50:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <errno.h>
#include <math.h>
#include "postgres.h"
#include "utils/builtins.h" /* where the declarations go */
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-#include <port-protos.h> /* ecvt(), fcvt() */
+#include <port-protos.h> /* ecvt(), fcvt() */
int32
pg_atoi(char *s, int size, int c)
{
- long l;
- char *badp = (char *) NULL;
-
- Assert(s);
-
- errno = 0;
- l = strtol(s, &badp, 10);
- if (errno) /* strtol must set ERANGE */
- elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
- if (badp && *badp && (*badp != c))
- elog(WARN, "pg_atoi: error in \"%s\": can\'t parse \"%s\"", s, badp);
-
- switch (size) {
- case sizeof(int32):
+ long l;
+ char *badp = (char *) NULL;
+
+ Assert(s);
+
+ errno = 0;
+ l = strtol(s, &badp, 10);
+ if (errno) /* strtol must set ERANGE */
+ elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
+ if (badp && *badp && (*badp != c))
+ elog(WARN, "pg_atoi: error in \"%s\": can\'t parse \"%s\"", s, badp);
+
+ switch (size)
+ {
+ case sizeof(int32):
#ifdef HAS_LONG_LONG
- /* won't get ERANGE on these with 64-bit longs... */
- if (l < -0x80000000L) {
- errno = ERANGE;
- elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
- }
- if (l > 0x7fffffffL) {
- errno = ERANGE;
- elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
- }
-#endif /* HAS_LONG_LONG */
- break;
- case sizeof(int16):
- if (l < -0x8000) {
- errno = ERANGE;
- elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
- }
- if (l > 0x7fff) {
- errno = ERANGE;
- elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
- }
- break;
- case sizeof(int8):
- if (l < -0x80) {
- errno = ERANGE;
- elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
- }
- if (l > 0x7f) {
- errno = ERANGE;
- elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
+ /* won't get ERANGE on these with 64-bit longs... */
+ if (l < -0x80000000L)
+ {
+ errno = ERANGE;
+ elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
+ }
+ if (l > 0x7fffffffL)
+ {
+ errno = ERANGE;
+ elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
+ }
+#endif /* HAS_LONG_LONG */
+ break;
+ case sizeof(int16):
+ if (l < -0x8000)
+ {
+ errno = ERANGE;
+ elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
+ }
+ if (l > 0x7fff)
+ {
+ errno = ERANGE;
+ elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
+ }
+ break;
+ case sizeof(int8):
+ if (l < -0x80)
+ {
+ errno = ERANGE;
+ elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
+ }
+ if (l > 0x7f)
+ {
+ errno = ERANGE;
+ elog(WARN, "pg_atoi: error reading \"%s\": %m", s);
+ }
+ break;
+ default:
+ elog(WARN, "pg_atoi: invalid result size: %d", size);
}
- break;
- default:
- elog(WARN, "pg_atoi: invalid result size: %d", size);
- }
- return((int32) l);
+ return ((int32) l);
}
/*
- * itoa - converts a short int to its string represention
+ * itoa - converts a short int to its string represention
*
- * Note:
- * previously based on ~ingres/source/gutil/atoi.c
- * now uses vendor's sprintf conversion
+ * Note:
+ * previously based on ~ingres/source/gutil/atoi.c
+ * now uses vendor's sprintf conversion
*/
void
itoa(int i, char *a)
{
- sprintf(a, "%hd", (short)i);
+ sprintf(a, "%hd", (short) i);
}
/*
- * ltoa - converts a long int to its string represention
+ * ltoa - converts a long int to its string represention
*
- * Note:
- * previously based on ~ingres/source/gutil/atoi.c
- * now uses vendor's sprintf conversion
+ * Note:
+ * previously based on ~ingres/source/gutil/atoi.c
+ * now uses vendor's sprintf conversion
*/
void
ltoa(int32 l, char *a)
{
- sprintf(a, "%d", l);
+ sprintf(a, "%d", l);
}
/*
- ** ftoa - FLOATING POINT TO ASCII CONVERSION
+ ** ftoa - FLOATING POINT TO ASCII CONVERSION
**
- ** CODE derived from ingres, ~ingres/source/gutil/ftoa.c
+ ** CODE derived from ingres, ~ingres/source/gutil/ftoa.c
**
- ** 'Value' is converted to an ascii character string and stored
- ** into 'ascii'. Ascii should have room for at least 'width' + 1
- ** characters. 'Width' is the width of the output field (max).
- ** 'Prec' is the number of characters to put after the decimal
- ** point. The format of the output string is controlled by
- ** 'format'.
+ ** 'Value' is converted to an ascii character string and stored
+ ** into 'ascii'. Ascii should have room for at least 'width' + 1
+ ** characters. 'Width' is the width of the output field (max).
+ ** 'Prec' is the number of characters to put after the decimal
+ ** point. The format of the output string is controlled by
+ ** 'format'.
**
- ** 'Format' can be:
- ** e or E: "E" format output
- ** f or F: "F" format output
- ** g or G: "F" format output if it will fit, otherwise
- ** use "E" format.
- ** n or N: same as G, but decimal points will not always
- ** be aligned.
+ ** 'Format' can be:
+ ** e or E: "E" format output
+ ** f or F: "F" format output
+ ** g or G: "F" format output if it will fit, otherwise
+ ** use "E" format.
+ ** n or N: same as G, but decimal points will not always
+ ** be aligned.
**
- ** If 'format' is upper case, the "E" comes out in upper case;
- ** otherwise it comes out in lower case.
+ ** If 'format' is upper case, the "E" comes out in upper case;
+ ** otherwise it comes out in lower case.
**
- ** When the field width is not big enough, it fills the field with
- ** stars ("*****") and returns zero. Normal return is the width
- ** of the output field (sometimes shorter than 'width').
+ ** When the field width is not big enough, it fills the field with
+ ** stars ("*****") and returns zero. Normal return is the width
+ ** of the output field (sometimes shorter than 'width').
*/
#ifdef NOT_USED
int
ftoa(double value, char *ascii, int width, int prec1, char format)
{
#ifndef HAVE_FCVT
- char out[256];
- char fmt[256];
- int ret;
+ char out[256];
+ char fmt[256];
+ int ret;
sprintf(fmt, "%%%d.%d%c", width, prec1, format);
sprintf(out, fmt, value);
- if ((ret = strlen(out)) > width) {
+ if ((ret = strlen(out)) > width)
+ {
memset(ascii, '*', width - 2);
ascii[width] = 0;
- return(0);
+ return (0);
}
strcpy(ascii, out);
- return(ret);
+ return (ret);
#else
- auto int expon;
- auto int sign;
- register int avail = 0;
- register char *a = NULL;
- register char *p = NULL;
- char mode;
- int lowercase;
- int prec;
-/* extern char *ecvt(), *fcvt();*/
-
- prec = prec1;
- mode = format;
- lowercase = 'a' - 'A';
- if (mode >= 'a')
- mode -= 'a' - 'A';
- else
- lowercase = 0;
-
- if (mode != 'E') {
- /* try 'F' style output */
- p = fcvt(value, prec, &expon, &sign);
- avail = width;
- a = ascii;
-
- /* output sign */
- if (sign) {
- avail--;
- *a++ = '-';
+ auto int expon;
+ auto int sign;
+ register int avail = 0;
+ register char *a = NULL;
+ register char *p = NULL;
+ char mode;
+ int lowercase;
+ int prec;
+
+/* extern char *ecvt(), *fcvt();*/
+
+ prec = prec1;
+ mode = format;
+ lowercase = 'a' - 'A';
+ if (mode >= 'a')
+ mode -= 'a' - 'A';
+ else
+ lowercase = 0;
+
+ if (mode != 'E')
+ {
+ /* try 'F' style output */
+ p = fcvt(value, prec, &expon, &sign);
+ avail = width;
+ a = ascii;
+
+ /* output sign */
+ if (sign)
+ {
+ avail--;
+ *a++ = '-';
+ }
+
+ /* output '0' before the decimal point */
+ if (expon <= 0)
+ {
+ *a++ = '0';
+ avail--;
+ }
+
+ /* compute space length left after dec pt and fraction */
+ avail -= prec + 1;
+ if (mode == 'G')
+ avail -= 4;
+
+ if (avail >= expon)
+ {
+
+ /* it fits. output */
+ while (expon > 0)
+ {
+ /* output left of dp */
+ expon--;
+ if (*p)
+ {
+ *a++ = *p++;
+ }
+ else
+ *a++ = '0';
+ }
+
+ /* output fraction (right of dec pt) */
+ avail = expon;
+ goto frac_out;
+ }
+ /* won't fit; let's hope for G format */
}
-
- /* output '0' before the decimal point */
- if (expon <= 0) {
- *a++ = '0';
- avail--;
+
+ if (mode != 'F')
+ {
+ /* try to do E style output */
+ p = ecvt(value, prec + 1, &expon, &sign);
+ avail = width - 5;
+ a = ascii;
+
+ /* output the sign */
+ if (sign)
+ {
+ *a++ = '-';
+ avail--;
+ }
}
-
- /* compute space length left after dec pt and fraction */
- avail -= prec + 1;
- if (mode == 'G')
- avail -= 4;
-
- if (avail >= expon) {
-
- /* it fits. output */
- while (expon > 0) {
- /* output left of dp */
- expon--;
- if (*p) {
- *a++ = *p++;
- } else
- *a++ = '0';
- }
-
- /* output fraction (right of dec pt) */
- avail = expon;
- goto frac_out;
+
+ /* check for field too small */
+ if (mode == 'F' || avail < prec)
+ {
+ /* sorry joker, you lose */
+ a = ascii;
+ for (avail = width; avail > 0; avail--)
+ *a++ = '*';
+ *a = 0;
+ return (0);
}
- /* won't fit; let's hope for G format */
- }
-
- if (mode != 'F') {
- /* try to do E style output */
- p = ecvt(value, prec + 1, &expon, &sign);
- avail = width - 5;
- a = ascii;
-
- /* output the sign */
- if (sign) {
- *a++ = '-';
- avail--;
+
+ /* it fits; output the number */
+ mode = 'E';
+
+ /* output the LHS single digit */
+ *a++ = *p++;
+ expon--;
+
+ /* output the rhs */
+ avail = 1;
+
+frac_out:
+ *a++ = '.';
+ while (prec > 0)
+ {
+ prec--;
+ if (avail < 0)
+ {
+ avail++;
+ *a++ = '0';
+ }
+ else
+ {
+ if (*p)
+ *a++ = *p++;
+ else
+ *a++ = '0';
+ }
}
- }
-
- /* check for field too small */
- if (mode == 'F' || avail < prec) {
- /* sorry joker, you lose */
- a = ascii;
- for (avail = width; avail > 0; avail--)
- *a++ = '*';
- *a = 0;
- return (0);
- }
-
- /* it fits; output the number */
- mode = 'E';
-
- /* output the LHS single digit */
- *a++ = *p++;
- expon--;
-
- /* output the rhs */
- avail = 1;
-
- frac_out:
- *a++ = '.';
- while (prec > 0) {
- prec--;
- if (avail < 0) {
- avail++;
- *a++ = '0';
- } else {
- if (*p)
- *a++ = *p++;
- else
- *a++ = '0';
+
+ /* output the exponent */
+ if (mode == 'E')
+ {
+ *a++ = 'E' + lowercase;
+ if (expon < 0)
+ {
+ *a++ = '-';
+ expon = -expon;
+ }
+ else
+ *a++ = '+';
+ *a++ = (expon / 10) % 10 + '0';
+ *a++ = expon % 10 + '0';
}
- }
-
- /* output the exponent */
- if (mode == 'E') {
- *a++ = 'E' + lowercase;
- if (expon < 0) {
- *a++ = '-';
- expon = -expon;
- } else
- *a++ = '+';
- *a++ = (expon / 10) % 10 + '0';
- *a++ = expon % 10 + '0';
- }
-
- /* output spaces on the end in G format */
- if (mode == 'G') {
- *a++ = ' ';
- *a++ = ' ';
- *a++ = ' ';
- *a++ = ' ';
- }
-
- /* finally, we can return */
- *a = 0;
- avail = a - ascii;
- return (avail);
-#endif /* !BSD44_derived */
+
+ /* output spaces on the end in G format */
+ if (mode == 'G')
+ {
+ *a++ = ' ';
+ *a++ = ' ';
+ *a++ = ' ';
+ *a++ = ' ';
+ }
+
+ /* finally, we can return */
+ *a = 0;
+ avail = a - ascii;
+ return (avail);
+#endif /* !BSD44_derived */
}
+
#endif
/*
- ** atof1 - ASCII TO FLOATING CONVERSION
+ ** atof1 - ASCII TO FLOATING CONVERSION
**
- ** CODE derived from ~ingres/source/gutil/atof.c
+ ** CODE derived from ~ingres/source/gutil/atof.c
**
- ** Converts the string 'str' to floating point and stores the
- ** result into the cell pointed to by 'val'.
+ ** Converts the string 'str' to floating point and stores the
+ ** result into the cell pointed to by 'val'.
**
- ** The syntax which it accepts is pretty much what you would
- ** expect. Basically, it is:
- ** {<sp>} [+|-] {<sp>} {<digit>} [.{digit}] {<sp>} [<exp>]
- ** where <exp> is "e" or "E" followed by an integer, <sp> is a
- ** space character, <digit> is zero through nine, [] is zero or
- ** one, and {} is zero or more.
+ ** The syntax which it accepts is pretty much what you would
+ ** expect. Basically, it is:
+ ** {<sp>} [+|-] {<sp>} {<digit>} [.{digit}] {<sp>} [<exp>]
+ ** where <exp> is "e" or "E" followed by an integer, <sp> is a
+ ** space character, <digit> is zero through nine, [] is zero or
+ ** one, and {} is zero or more.
**
- ** Parameters:
- ** str -- string to convert.
- ** val -- pointer to place to put the result (which
- ** must be type double).
+ ** Parameters:
+ ** str -- string to convert.
+ ** val -- pointer to place to put the result (which
+ ** must be type double).
**
- ** Returns:
- ** zero -- ok.
- ** -1 -- syntax error.
- ** +1 -- overflow (not implemented).
+ ** Returns:
+ ** zero -- ok.
+ ** -1 -- syntax error.
+ ** +1 -- overflow (not implemented).
**
- ** Side Effects:
- ** clobbers *val.
+ ** Side Effects:
+ ** clobbers *val.
*/
#ifdef NOT_USED
int
atof1(char *str, double *val)
{
- register char *p;
- double v;
- double fact;
- int minus;
- register char c;
- int expon;
- register int gotmant;
-
- v = 0.0;
- p = str;
- minus = 0;
-
- /* skip leading blanks */
- while ((c = *p) != '\0') {
- if (c != ' ')
- break;
- p++;
- }
-
- /* handle possible sign */
- switch (c) {
- case '-':
- minus++;
-
- case '+':
- p++;
- }
-
- /* skip blanks after sign */
- while ((c = *p) != '\0') {
- if (c != ' ')
- break;
- p++;
- }
-
- /* start collecting the number to the decimal point */
- gotmant = 0;
- for (;;) {
- c = *p;
- if (c < '0' || c > '9')
- break;
- v = v * 10.0 + (c - '0');
- gotmant++;
- p++;
- }
-
- /* check for fractional part */
- if (c == '.') {
- fact = 1.0;
- for (;;) {
- c = *++p;
- if (c < '0' || c > '9')
- break;
- fact *= 0.1;
- v += (c - '0') * fact;
- gotmant++;
+ register char *p;
+ double v;
+ double fact;
+ int minus;
+ register char c;
+ int expon;
+ register int gotmant;
+
+ v = 0.0;
+ p = str;
+ minus = 0;
+
+ /* skip leading blanks */
+ while ((c = *p) != '\0')
+ {
+ if (c != ' ')
+ break;
+ p++;
+ }
+
+ /* handle possible sign */
+ switch (c)
+ {
+ case '-':
+ minus++;
+
+ case '+':
+ p++;
}
- }
-
- /* skip blanks before possible exponent */
- while ((c = *p) != '\0') {
- if (c != ' ')
- break;
- p++;
- }
-
- /* test for exponent */
- if (c == 'e' || c == 'E') {
- p++;
- expon = pg_atoi(p, sizeof(expon), '\0');
- if (!gotmant)
- v = 1.0;
- fact = expon;
- v *= pow(10.0, fact);
- } else {
- /* if no exponent, then nothing */
- if (c != 0)
- return (-1);
- }
-
- /* store the result and exit */
- if (minus)
- v = -v;
- *val = v;
- return (0);
+
+ /* skip blanks after sign */
+ while ((c = *p) != '\0')
+ {
+ if (c != ' ')
+ break;
+ p++;
+ }
+
+ /* start collecting the number to the decimal point */
+ gotmant = 0;
+ for (;;)
+ {
+ c = *p;
+ if (c < '0' || c > '9')
+ break;
+ v = v * 10.0 + (c - '0');
+ gotmant++;
+ p++;
+ }
+
+ /* check for fractional part */
+ if (c == '.')
+ {
+ fact = 1.0;
+ for (;;)
+ {
+ c = *++p;
+ if (c < '0' || c > '9')
+ break;
+ fact *= 0.1;
+ v += (c - '0') * fact;
+ gotmant++;
+ }
+ }
+
+ /* skip blanks before possible exponent */
+ while ((c = *p) != '\0')
+ {
+ if (c != ' ')
+ break;
+ p++;
+ }
+
+ /* test for exponent */
+ if (c == 'e' || c == 'E')
+ {
+ p++;
+ expon = pg_atoi(p, sizeof(expon), '\0');
+ if (!gotmant)
+ v = 1.0;
+ fact = expon;
+ v *= pow(10.0, fact);
+ }
+ else
+ {
+ /* if no exponent, then nothing */
+ if (c != 0)
+ return (-1);
+ }
+
+ /* store the result and exit */
+ if (minus)
+ v = -v;
+ *val = v;
+ return (0);
}
+
#endif
diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c
index 977fe87fbca..864c272c793 100644
--- a/src/backend/utils/adt/oid.c
+++ b/src/backend/utils/adt/oid.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* oid.c--
- * Functions for the built-in type Oid.
+ * Functions for the built-in type Oid.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.8 1997/08/24 23:07:35 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.9 1997/09/07 04:50:34 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,114 +16,125 @@
#include <string.h>
#include "postgres.h"
-#include "utils/builtins.h" /* where function declarations go */
+#include "utils/builtins.h" /* where function declarations go */
-/*****************************************************************************
- * USER I/O ROUTINES *
+/*****************************************************************************
+ * USER I/O ROUTINES *
*****************************************************************************/
/*
- * oid8in - converts "num num ..." to internal form
+ * oid8in - converts "num num ..." to internal form
*
- * Note:
- * Fills any nonexistent digits with NULL oids.
+ * Note:
+ * Fills any nonexistent digits with NULL oids.
*/
-Oid *oid8in(char *oidString)
+Oid *
+oid8in(char *oidString)
{
- register Oid (*result)[];
- int nums;
-
- if (oidString == NULL)
- return(NULL);
- result = (Oid (*)[]) palloc(sizeof(Oid [8]));
- if ((nums = sscanf(oidString, "%d%d%d%d%d%d%d%d",
- &(*result)[0],
- &(*result)[1],
- &(*result)[2],
- &(*result)[3],
- &(*result)[4],
- &(*result)[5],
- &(*result)[6],
- &(*result)[7])) != 8) {
- do
- (*result)[nums++] = 0;
- while (nums < 8);
- }
- return((Oid *) result);
+ register Oid(*result)[];
+ int nums;
+
+ if (oidString == NULL)
+ return (NULL);
+ result = (Oid(*)[]) palloc(sizeof(Oid[8]));
+ if ((nums = sscanf(oidString, "%d%d%d%d%d%d%d%d",
+ &(*result)[0],
+ &(*result)[1],
+ &(*result)[2],
+ &(*result)[3],
+ &(*result)[4],
+ &(*result)[5],
+ &(*result)[6],
+ &(*result)[7])) != 8)
+ {
+ do
+ (*result)[nums++] = 0;
+ while (nums < 8);
+ }
+ return ((Oid *) result);
}
/*
- * oid8out - converts internal form to "num num ..."
+ * oid8out - converts internal form to "num num ..."
*/
-char *oid8out(Oid (*oidArray)[])
+char *
+oid8out(Oid(*oidArray)[])
{
- register int num;
- register Oid *sp;
- register char *rp;
- char *result;
-
- if (oidArray == NULL) {
- result = (char *) palloc(2);
- result[0] = '-';
- result[1] = '\0';
- return(result);
- }
-
- /* assumes sign, 10 digits, ' ' */
- rp = result = (char *) palloc(8 * 12);
- sp = *oidArray;
- for (num = 8; num != 0; num--) {
- ltoa(*sp++, rp);
- while (*++rp != '\0')
- ;
- *rp++ = ' ';
- }
- *--rp = '\0';
- return(result);
+ register int num;
+ register Oid *sp;
+ register char *rp;
+ char *result;
+
+ if (oidArray == NULL)
+ {
+ result = (char *) palloc(2);
+ result[0] = '-';
+ result[1] = '\0';
+ return (result);
+ }
+
+ /* assumes sign, 10 digits, ' ' */
+ rp = result = (char *) palloc(8 * 12);
+ sp = *oidArray;
+ for (num = 8; num != 0; num--)
+ {
+ ltoa(*sp++, rp);
+ while (*++rp != '\0')
+ ;
+ *rp++ = ' ';
+ }
+ *--rp = '\0';
+ return (result);
}
-Oid oidin(char *s)
+Oid
+oidin(char *s)
{
- return(int4in(s));
+ return (int4in(s));
}
-char *oidout(Oid o)
+char *
+oidout(Oid o)
{
- return(int4out(o));
+ return (int4out(o));
}
-/*****************************************************************************
- * PUBLIC ROUTINES *
+/*****************************************************************************
+ * PUBLIC ROUTINES *
*****************************************************************************/
/*
* If you change this function, change heap_keytest()
* because we have hardcoded this in there as an optimization
*/
-bool oideq(Oid arg1, Oid arg2)
+bool
+oideq(Oid arg1, Oid arg2)
{
- return(arg1 == arg2);
+ return (arg1 == arg2);
}
-bool oidne(Oid arg1, Oid arg2)
+bool
+oidne(Oid arg1, Oid arg2)
{
- return(arg1 != arg2);
+ return (arg1 != arg2);
}
-bool oid8eq(Oid arg1[], Oid arg2[])
+bool
+oid8eq(Oid arg1[], Oid arg2[])
{
- return (bool)(memcmp(arg1, arg2, 8 * sizeof(Oid)) == 0);
+ return (bool) (memcmp(arg1, arg2, 8 * sizeof(Oid)) == 0);
}
-bool oideqint4(Oid arg1, int32 arg2)
+bool
+oideqint4(Oid arg1, int32 arg2)
{
/* oid is unsigned, but int4 is signed */
- return (arg2 >= 0 && arg1 == arg2);
+ return (arg2 >= 0 && arg1 == arg2);
}
-bool int4eqoid(int32 arg1, Oid arg2)
+bool
+int4eqoid(int32 arg1, Oid arg2)
{
/* oid is unsigned, but int4 is signed */
- return (arg1 >= 0 && arg1 == arg2);
+ return (arg1 >= 0 && arg1 == arg2);
}
-
diff --git a/src/backend/utils/adt/oidint2.c b/src/backend/utils/adt/oidint2.c
index 4d92821e8d8..009ab233f78 100644
--- a/src/backend/utils/adt/oidint2.c
+++ b/src/backend/utils/adt/oidint2.c
@@ -1,120 +1,120 @@
/*-------------------------------------------------------------------------
*
* oidint2.c--
- * Functions for the built-in type "oidint2".
+ * Functions for the built-in type "oidint2".
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/oidint2.c,v 1.1.1.1 1996/07/09 06:22:05 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/oidint2.c,v 1.2 1997/09/07 04:50:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <stdio.h>
#include "postgres.h"
#include "utils/palloc.h"
-#include "utils/builtins.h" /* for pg_atoi() */
+#include "utils/builtins.h" /* for pg_atoi() */
#include "utils/oidcompos.h" /* where function declarations go */
OidInt2
oidint2in(char *o)
{
- OidInt2 oi;
- char *p;
-
- oi = (OidInt2) palloc(sizeof(OidInt2Data));
-
- for (p = o; *p != '\0' && *p != '/'; p++)
- continue;
-
- oi->oi_oid = (Oid) pg_atoi(o, sizeof(Oid), '/');
- if (*p == '\0') {
- oi->oi_int2 = 0;
- } else {
- oi->oi_int2 = (int16) pg_atoi(++p, sizeof(int2), '\0');
- }
-
- return (oi);
+ OidInt2 oi;
+ char *p;
+
+ oi = (OidInt2) palloc(sizeof(OidInt2Data));
+
+ for (p = o; *p != '\0' && *p != '/'; p++)
+ continue;
+
+ oi->oi_oid = (Oid) pg_atoi(o, sizeof(Oid), '/');
+ if (*p == '\0')
+ {
+ oi->oi_int2 = 0;
+ }
+ else
+ {
+ oi->oi_int2 = (int16) pg_atoi(++p, sizeof(int2), '\0');
+ }
+
+ return (oi);
}
-char *
+char *
oidint2out(OidInt2 o)
{
- char *r;
-
- /*
- * -2147483647/-32767
- * 0 1
- * 1234567890123456789
- */
- r = (char *) palloc(19);
- sprintf(r, "%d/%d", o->oi_oid, o->oi_int2);
-
- return (r);
+ char *r;
+
+ /*
+ * -2147483647/-32767 0 1 1234567890123456789
+ */
+ r = (char *) palloc(19);
+ sprintf(r, "%d/%d", o->oi_oid, o->oi_int2);
+
+ return (r);
}
bool
oidint2lt(OidInt2 o1, OidInt2 o2)
{
- return
- ((bool) (o1->oi_oid < o2->oi_oid ||
- (o1->oi_oid == o2->oi_oid && o1->oi_int2 < o2->oi_int2)));
+ return
+ ((bool) (o1->oi_oid < o2->oi_oid ||
+ (o1->oi_oid == o2->oi_oid && o1->oi_int2 < o2->oi_int2)));
}
bool
oidint2le(OidInt2 o1, OidInt2 o2)
{
- return ((bool) (o1->oi_oid < o2->oi_oid ||
- (o1->oi_oid == o2->oi_oid && o1->oi_int2 <= o2->oi_int2)));
+ return ((bool) (o1->oi_oid < o2->oi_oid ||
+ (o1->oi_oid == o2->oi_oid && o1->oi_int2 <= o2->oi_int2)));
}
bool
oidint2eq(OidInt2 o1, OidInt2 o2)
{
- return ((bool) (o1->oi_oid == o2->oi_oid && o1->oi_int2 == o2->oi_int2));
+ return ((bool) (o1->oi_oid == o2->oi_oid && o1->oi_int2 == o2->oi_int2));
}
bool
oidint2ge(OidInt2 o1, OidInt2 o2)
{
- return ((bool) (o1->oi_oid > o2->oi_oid ||
- (o1->oi_oid == o2->oi_oid && o1->oi_int2 >= o2->oi_int2)));
+ return ((bool) (o1->oi_oid > o2->oi_oid ||
+ (o1->oi_oid == o2->oi_oid && o1->oi_int2 >= o2->oi_int2)));
}
bool
oidint2gt(OidInt2 o1, OidInt2 o2)
{
- return ((bool) (o1->oi_oid > o2->oi_oid ||
- (o1->oi_oid == o2->oi_oid && o1->oi_int2 > o2->oi_int2)));
+ return ((bool) (o1->oi_oid > o2->oi_oid ||
+ (o1->oi_oid == o2->oi_oid && o1->oi_int2 > o2->oi_int2)));
}
bool
oidint2ne(OidInt2 o1, OidInt2 o2)
{
- return ((bool) (o1->oi_oid != o2->oi_oid || o1->oi_int2 != o2->oi_int2));
+ return ((bool) (o1->oi_oid != o2->oi_oid || o1->oi_int2 != o2->oi_int2));
}
int
oidint2cmp(OidInt2 o1, OidInt2 o2)
{
- if (oidint2lt(o1, o2))
- return (-1);
- else if (oidint2eq(o1, o2))
- return (0);
- else
- return (1);
+ if (oidint2lt(o1, o2))
+ return (-1);
+ else if (oidint2eq(o1, o2))
+ return (0);
+ else
+ return (1);
}
OidInt2
mkoidint2(Oid v_oid, uint16 v_int2)
{
- OidInt2 o;
-
- o = (OidInt2) palloc(sizeof(OidInt2Data));
- o->oi_oid = v_oid;
- o->oi_int2 = v_int2;
- return (o);
-}
+ OidInt2 o;
+ o = (OidInt2) palloc(sizeof(OidInt2Data));
+ o->oi_oid = v_oid;
+ o->oi_int2 = v_int2;
+ return (o);
+}
diff --git a/src/backend/utils/adt/oidint4.c b/src/backend/utils/adt/oidint4.c
index d0844411a73..c4da5141acf 100644
--- a/src/backend/utils/adt/oidint4.c
+++ b/src/backend/utils/adt/oidint4.c
@@ -1,111 +1,120 @@
/*-------------------------------------------------------------------------
*
* oidint4.c--
- * Functions for the built-in type "oidint4".
+ * Functions for the built-in type "oidint4".
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/oidint4.c,v 1.1.1.1 1996/07/09 06:22:05 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/oidint4.c,v 1.2 1997/09/07 04:50:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include "postgres.h"
#include "utils/palloc.h"
#include "utils/builtins.h"
#include "utils/oidcompos.h" /* where function declarations go */
-OidInt4 oidint4in(char *o)
+OidInt4
+oidint4in(char *o)
{
- OidInt4 oi;
- char *p;
-
- oi = (OidInt4) palloc(sizeof(OidInt4Data));
-
- for (p = o; *p != '\0' && *p != '/'; p++)
- continue;
-
- oi->oi_oid = (Oid) pg_atoi(o, sizeof(Oid), '/');
- if (*p == '\0') {
- oi->oi_int4 = 0;
- } else {
- oi->oi_int4 = pg_atoi(++p, sizeof(int4), '\0');
- }
-
- return (oi);
+ OidInt4 oi;
+ char *p;
+
+ oi = (OidInt4) palloc(sizeof(OidInt4Data));
+
+ for (p = o; *p != '\0' && *p != '/'; p++)
+ continue;
+
+ oi->oi_oid = (Oid) pg_atoi(o, sizeof(Oid), '/');
+ if (*p == '\0')
+ {
+ oi->oi_int4 = 0;
+ }
+ else
+ {
+ oi->oi_int4 = pg_atoi(++p, sizeof(int4), '\0');
+ }
+
+ return (oi);
}
-char *oidint4out(OidInt4 o)
+char *
+oidint4out(OidInt4 o)
{
- char *r;
-
- /*
- * -2147483647/-2147483647
- * 0 1 2
- * 123456789012345678901234
- */
- r = (char *) palloc(24);
- sprintf(r, "%d/%d", o->oi_oid, o->oi_int4);
-
- return (r);
+ char *r;
+
+ /*
+ * -2147483647/-2147483647 0 1 2
+ * 123456789012345678901234
+ */
+ r = (char *) palloc(24);
+ sprintf(r, "%d/%d", o->oi_oid, o->oi_int4);
+
+ return (r);
}
-bool oidint4lt(OidInt4 o1, OidInt4 o2)
+bool
+oidint4lt(OidInt4 o1, OidInt4 o2)
{
- return
+ return
((bool) (o1->oi_oid < o2->oi_oid ||
- (o1->oi_oid == o2->oi_oid && o1->oi_int4 < o2->oi_int4)));
+ (o1->oi_oid == o2->oi_oid && o1->oi_int4 < o2->oi_int4)));
}
-bool oidint4le(OidInt4 o1, OidInt4 o2)
+bool
+oidint4le(OidInt4 o1, OidInt4 o2)
{
- return ((bool) (o1->oi_oid < o2->oi_oid ||
- (o1->oi_oid == o2->oi_oid && o1->oi_int4 <= o2->oi_int4)));
+ return ((bool) (o1->oi_oid < o2->oi_oid ||
+ (o1->oi_oid == o2->oi_oid && o1->oi_int4 <= o2->oi_int4)));
}
-bool oidint4eq(OidInt4 o1, OidInt4 o2)
+bool
+oidint4eq(OidInt4 o1, OidInt4 o2)
{
- return ((bool) (o1->oi_oid == o2->oi_oid && o1->oi_int4 == o2->oi_int4));
+ return ((bool) (o1->oi_oid == o2->oi_oid && o1->oi_int4 == o2->oi_int4));
}
-bool oidint4ge(OidInt4 o1, OidInt4 o2)
+bool
+oidint4ge(OidInt4 o1, OidInt4 o2)
{
- return ((bool) (o1->oi_oid > o2->oi_oid ||
- (o1->oi_oid == o2->oi_oid && o1->oi_int4 >= o2->oi_int4)));
+ return ((bool) (o1->oi_oid > o2->oi_oid ||
+ (o1->oi_oid == o2->oi_oid && o1->oi_int4 >= o2->oi_int4)));
}
-bool oidint4gt(OidInt4 o1, OidInt4 o2)
+bool
+oidint4gt(OidInt4 o1, OidInt4 o2)
{
- return ((bool) (o1->oi_oid > o2->oi_oid ||
- (o1->oi_oid == o2->oi_oid && o1->oi_int4 > o2->oi_int4)));
+ return ((bool) (o1->oi_oid > o2->oi_oid ||
+ (o1->oi_oid == o2->oi_oid && o1->oi_int4 > o2->oi_int4)));
}
-bool oidint4ne(OidInt4 o1, OidInt4 o2)
+bool
+oidint4ne(OidInt4 o1, OidInt4 o2)
{
- return ((bool) (o1->oi_oid != o2->oi_oid || o1->oi_int4 != o2->oi_int4));
+ return ((bool) (o1->oi_oid != o2->oi_oid || o1->oi_int4 != o2->oi_int4));
}
-int oidint4cmp(OidInt4 o1, OidInt4 o2)
+int
+oidint4cmp(OidInt4 o1, OidInt4 o2)
{
- if (oidint4lt(o1, o2))
- return (-1);
- else if (oidint4eq(o1, o2))
- return (0);
- else
- return (1);
+ if (oidint4lt(o1, o2))
+ return (-1);
+ else if (oidint4eq(o1, o2))
+ return (0);
+ else
+ return (1);
}
-OidInt4 mkoidint4(Oid v_oid, uint32 v_int4)
+OidInt4
+mkoidint4(Oid v_oid, uint32 v_int4)
{
- OidInt4 o;
-
- o = (OidInt4) palloc(sizeof(OidInt4Data));
- o->oi_oid = v_oid;
- o->oi_int4 = v_int4;
- return (o);
-}
-
-
+ OidInt4 o;
+ o = (OidInt4) palloc(sizeof(OidInt4Data));
+ o->oi_oid = v_oid;
+ o->oi_int4 = v_int4;
+ return (o);
+}
diff --git a/src/backend/utils/adt/oidname.c b/src/backend/utils/adt/oidname.c
index 425fa78f65c..30a081f2531 100644
--- a/src/backend/utils/adt/oidname.c
+++ b/src/backend/utils/adt/oidname.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* oidname.c--
- * adt for multiple key indices involving oid and name. Used for cache
- * index scans (could also be used in the general case with name).
+ * adt for multiple key indices involving oid and name. Used for cache
+ * index scans (could also be used in the general case with name).
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/oidname.c,v 1.4 1997/08/12 20:16:03 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/oidname.c,v 1.5 1997/09/07 04:50:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,106 +17,109 @@
#include "postgres.h"
#include "utils/oidcompos.h" /* where function declarations go */
-#include "utils/builtins.h" /* for pg_atoi() */
+#include "utils/builtins.h" /* for pg_atoi() */
#include "utils/palloc.h"
OidName
oidnamein(char *inStr)
{
- OidName oc;
- char *inptr;
-
- oc = (OidName) palloc(sizeof(OidNameData));
-
- memset(oc, 0, sizeof(OidNameData));
- for (inptr = inStr; *inptr && *inptr != ','; inptr++)
- ;
-
- if (*inptr) {
- oc->id = (Oid) pg_atoi(inStr, sizeof(Oid), ',');
- /* copy one less to ensure null-padding */
- ++inptr;
- strNcpy(oc->name.data,inptr,NAMEDATALEN-1);
- }else
- elog(WARN, "Bad input data for type oidname");
-
- return oc;
+ OidName oc;
+ char *inptr;
+
+ oc = (OidName) palloc(sizeof(OidNameData));
+
+ memset(oc, 0, sizeof(OidNameData));
+ for (inptr = inStr; *inptr && *inptr != ','; inptr++)
+ ;
+
+ if (*inptr)
+ {
+ oc->id = (Oid) pg_atoi(inStr, sizeof(Oid), ',');
+ /* copy one less to ensure null-padding */
+ ++inptr;
+ strNcpy(oc->name.data, inptr, NAMEDATALEN - 1);
+ }
+ else
+ elog(WARN, "Bad input data for type oidname");
+
+ return oc;
}
-char *
+char *
oidnameout(OidName oidname)
{
- char buf[30+NAMEDATALEN]; /* oidname length + oid length + some safety */
- char *res;
-
- sprintf(buf, "%d,%s", oidname->id, oidname->name.data);
- res = pstrdup(buf);
- return(res);
+ char buf[30 + NAMEDATALEN]; /* oidname length + oid
+ * length + some safety */
+ char *res;
+
+ sprintf(buf, "%d,%s", oidname->id, oidname->name.data);
+ res = pstrdup(buf);
+ return (res);
}
bool
oidnamelt(OidName o1, OidName o2)
{
- return (bool)
- (o1->id < o2->id ||
- (o1->id == o2->id && namecmp(&o1->name, &o2->name) < 0));
+ return (bool)
+ (o1->id < o2->id ||
+ (o1->id == o2->id && namecmp(&o1->name, &o2->name) < 0));
}
bool
oidnamele(OidName o1, OidName o2)
{
- return (bool)
- (o1->id < o2->id ||
- (o1->id == o2->id && namecmp(&o1->name,&o2->name) <= 0));
+ return (bool)
+ (o1->id < o2->id ||
+ (o1->id == o2->id && namecmp(&o1->name, &o2->name) <= 0));
}
bool
oidnameeq(OidName o1, OidName o2)
{
- return (bool)
- (o1->id == o2->id &&
- (namecmp(&o1->name, &o2->name) == 0));
+ return (bool)
+ (o1->id == o2->id &&
+ (namecmp(&o1->name, &o2->name) == 0));
}
bool
oidnamene(OidName o1, OidName o2)
{
- return (bool)
- (o1->id != o2->id ||
- (namecmp(&o1->name,&o2->name) != 0));
+ return (bool)
+ (o1->id != o2->id ||
+ (namecmp(&o1->name, &o2->name) != 0));
}
bool
oidnamege(OidName o1, OidName o2)
{
- return (bool) (o1->id > o2->id || (o1->id == o2->id &&
- namecmp(&o1->name, &o2->name) >= 0));
+ return (bool) (o1->id > o2->id || (o1->id == o2->id &&
+ namecmp(&o1->name, &o2->name) >= 0));
}
bool
oidnamegt(OidName o1, OidName o2)
{
- return (bool) (o1->id > o2->id || (o1->id == o2->id &&
- namecmp(&o1->name, &o2->name) > 0));
+ return (bool) (o1->id > o2->id || (o1->id == o2->id &&
+ namecmp(&o1->name, &o2->name) > 0));
}
int
oidnamecmp(OidName o1, OidName o2)
{
- if (o1->id == o2->id)
- return (namecmp(&o1->name,&o2->name));
-
- return (o1->id < o2->id) ? -1 : 1;
+ if (o1->id == o2->id)
+ return (namecmp(&o1->name, &o2->name));
+
+ return (o1->id < o2->id) ? -1 : 1;
}
OidName
mkoidname(Oid id, char *name)
{
- OidName oidname;
-
- oidname = (OidName) palloc(sizeof(Oid)+NAMEDATALEN);
-
- oidname->id = id;
- namestrcpy(&oidname->name,name);
- return oidname;
+ OidName oidname;
+
+ oidname = (OidName) palloc(sizeof(Oid) + NAMEDATALEN);
+
+ oidname->id = id;
+ namestrcpy(&oidname->name, name);
+ return oidname;
}
diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c
index 6082311c54a..99acb57b58f 100644
--- a/src/backend/utils/adt/oracle_compat.c
+++ b/src/backend/utils/adt/oracle_compat.c
@@ -1,7 +1,7 @@
/*
- * Edmund Mergl <E.Mergl@bawue.de>
+ * Edmund Mergl <E.Mergl@bawue.de>
*
- * $Id: oracle_compat.c,v 1.7 1997/07/29 16:12:01 thomas Exp $
+ * $Id: oracle_compat.c,v 1.8 1997/09/07 04:50:38 momjian Exp $
*
*/
@@ -10,16 +10,16 @@
#include "postgres.h"
-text *lower(text *string);
-text *upper(text *string);
-text *initcap(text *string);
-text *lpad(text *string1, int4 len, text *string2);
-text *rpad(text *string1, int4 len, text *string2);
-text *btrim(text *string, text *set);
-text *ltrim(text *string, text *set);
-text *rtrim(text *string, text *set);
-text *substr(text *string, int4 m, int4 n);
-text *translate(text *string, char from, char to);
+text *lower(text * string);
+text *upper(text * string);
+text *initcap(text * string);
+text *lpad(text * string1, int4 len, text * string2);
+text *rpad(text * string1, int4 len, text * string2);
+text *btrim(text * string, text * set);
+text *ltrim(text * string, text * set);
+text *rtrim(text * string, text * set);
+text *substr(text * string, int4 m, int4 n);
+text *translate(text * string, char from, char to);
/********************************************************************
@@ -28,35 +28,37 @@ text *translate(text *string, char from, char to);
*
* Syntax:
*
- * text *lower(text *string)
+ * text *lower(text *string)
*
* Purpose:
*
- * Returns string, with all letters forced to lowercase.
+ * Returns string, with all letters forced to lowercase.
*
********************************************************************/
-text *
-lower(text *string)
+text *
+lower(text * string)
{
- text *ret;
- char *ptr, *ptr_ret;
- int m;
+ text *ret;
+ char *ptr,
+ *ptr_ret;
+ int m;
- if ((string == (text *)NULL) || ((m = VARSIZE(string) - VARHDRSZ) <= 0))
- return string;
+ if ((string == (text *) NULL) || ((m = VARSIZE(string) - VARHDRSZ) <= 0))
+ return string;
- ret = (text *)palloc(VARSIZE(string));
- VARSIZE(ret) = VARSIZE(string);
+ ret = (text *) palloc(VARSIZE(string));
+ VARSIZE(ret) = VARSIZE(string);
- ptr = VARDATA(string);
- ptr_ret = VARDATA(ret);
+ ptr = VARDATA(string);
+ ptr_ret = VARDATA(ret);
- while (m--) {
- *ptr_ret++ = tolower(*ptr++);
- }
+ while (m--)
+ {
+ *ptr_ret++ = tolower(*ptr++);
+ }
- return ret;
+ return ret;
}
@@ -66,35 +68,37 @@ lower(text *string)
*
* Syntax:
*
- * text *upper(text *string)
+ * text *upper(text *string)
*
* Purpose:
*
- * Returns string, with all letters forced to uppercase.
+ * Returns string, with all letters forced to uppercase.
*
********************************************************************/
-text *
-upper(text *string)
+text *
+upper(text * string)
{
- text *ret;
- char *ptr, *ptr_ret;
- int m;
+ text *ret;
+ char *ptr,
+ *ptr_ret;
+ int m;
- if ((string == (text *)NULL) || ((m = VARSIZE(string) - VARHDRSZ) <= 0))
- return string;
+ if ((string == (text *) NULL) || ((m = VARSIZE(string) - VARHDRSZ) <= 0))
+ return string;
- ret = (text *)palloc(VARSIZE(string));
- VARSIZE(ret) = VARSIZE(string);
+ ret = (text *) palloc(VARSIZE(string));
+ VARSIZE(ret) = VARSIZE(string);
- ptr = VARDATA(string);
- ptr_ret = VARDATA(ret);
+ ptr = VARDATA(string);
+ ptr_ret = VARDATA(ret);
- while (m--) {
- *ptr_ret++ = toupper(*ptr++);
- }
+ while (m--)
+ {
+ *ptr_ret++ = toupper(*ptr++);
+ }
- return ret;
+ return ret;
}
@@ -104,44 +108,49 @@ upper(text *string)
*
* Syntax:
*
- * text *initcap(text *string)
+ * text *initcap(text *string)
*
* Purpose:
*
- * Returns string, with first letter of each word in uppercase,
- * all other letters in lowercase. A word is delimited by white
- * space.
+ * Returns string, with first letter of each word in uppercase,
+ * all other letters in lowercase. A word is delimited by white
+ * space.
*
********************************************************************/
-text *
-initcap(text *string)
+text *
+initcap(text * string)
{
- text *ret;
- char *ptr, *ptr_ret;
- int m;
-
- if ((string == (text *)NULL) || ((m = VARSIZE(string) - VARHDRSZ) <= 0))
- return string;
-
- ret = (text *)palloc(VARSIZE(string));
- VARSIZE(ret) = VARSIZE(string);
-
- ptr = VARDATA(string);
- ptr_ret = VARDATA(ret);
-
- *ptr_ret++ = toupper(*ptr++);
- --m;
-
- while (m--) {
- if (*(ptr_ret - 1) == ' ' || *(ptr_ret - 1) == ' ') {
- *ptr_ret++ = toupper(*ptr++);
- } else {
- *ptr_ret++ = tolower(*ptr++);
- }
- }
-
- return ret;
+ text *ret;
+ char *ptr,
+ *ptr_ret;
+ int m;
+
+ if ((string == (text *) NULL) || ((m = VARSIZE(string) - VARHDRSZ) <= 0))
+ return string;
+
+ ret = (text *) palloc(VARSIZE(string));
+ VARSIZE(ret) = VARSIZE(string);
+
+ ptr = VARDATA(string);
+ ptr_ret = VARDATA(ret);
+
+ *ptr_ret++ = toupper(*ptr++);
+ --m;
+
+ while (m--)
+ {
+ if (*(ptr_ret - 1) == ' ' || *(ptr_ret - 1) == ' ')
+ {
+ *ptr_ret++ = toupper(*ptr++);
+ }
+ else
+ {
+ *ptr_ret++ = tolower(*ptr++);
+ }
+ }
+
+ return ret;
}
@@ -151,48 +160,53 @@ initcap(text *string)
*
* Syntax:
*
- * text *lpad(text *string1, int4 len, text *string2)
+ * text *lpad(text *string1, int4 len, text *string2)
*
* Purpose:
*
- * Returns string1, left-padded to length len with the sequence of
- * characters in string2.
+ * Returns string1, left-padded to length len with the sequence of
+ * characters in string2.
*
********************************************************************/
-text *
-lpad(text *string1, int4 len, text *string2)
+text *
+lpad(text * string1, int4 len, text * string2)
{
- text *ret;
- char *ptr1, *ptr2, *ptr_ret;
- int m, n;
-
- if ((string1 == (text *)NULL) ||
- (len <= (VARSIZE(string1) - VARHDRSZ)) ||
- ((m = len - VARSIZE(string1) + VARHDRSZ) <= 0) ||
- (string2 == (text *)NULL) ||
- ((VARSIZE(string2) - VARHDRSZ) <= 0))
- return string1;
-
- ret = (text *)palloc(VARHDRSZ + len);
- VARSIZE(ret) = VARHDRSZ + len;
-
- ptr2 = VARDATA(string2);
- ptr_ret = VARDATA(ret);
-
- while (m--) {
- *ptr_ret++ = *ptr2;
- ptr2 = ptr2 == VARDATA(string2) + VARSIZE(string2) - VARHDRSZ - 1 ? VARDATA(string2) : ++ptr2;
- }
-
- n = VARSIZE(string1) - VARHDRSZ;
- ptr1 = VARDATA(string1);
-
- while (n--) {
- *ptr_ret++ = *ptr1++;
- }
-
- return ret;
+ text *ret;
+ char *ptr1,
+ *ptr2,
+ *ptr_ret;
+ int m,
+ n;
+
+ if ((string1 == (text *) NULL) ||
+ (len <= (VARSIZE(string1) - VARHDRSZ)) ||
+ ((m = len - VARSIZE(string1) + VARHDRSZ) <= 0) ||
+ (string2 == (text *) NULL) ||
+ ((VARSIZE(string2) - VARHDRSZ) <= 0))
+ return string1;
+
+ ret = (text *) palloc(VARHDRSZ + len);
+ VARSIZE(ret) = VARHDRSZ + len;
+
+ ptr2 = VARDATA(string2);
+ ptr_ret = VARDATA(ret);
+
+ while (m--)
+ {
+ *ptr_ret++ = *ptr2;
+ ptr2 = ptr2 == VARDATA(string2) + VARSIZE(string2) - VARHDRSZ - 1 ? VARDATA(string2) : ++ptr2;
+ }
+
+ n = VARSIZE(string1) - VARHDRSZ;
+ ptr1 = VARDATA(string1);
+
+ while (n--)
+ {
+ *ptr_ret++ = *ptr1++;
+ }
+
+ return ret;
}
@@ -202,48 +216,53 @@ lpad(text *string1, int4 len, text *string2)
*
* Syntax:
*
- * text *rpad(text *string1, int4 len, text *string2)
+ * text *rpad(text *string1, int4 len, text *string2)
*
* Purpose:
*
- * Returns string1, right-padded to length len with the sequence of
- * characters in string2.
+ * Returns string1, right-padded to length len with the sequence of
+ * characters in string2.
*
********************************************************************/
-text *
-rpad(text *string1, int4 len, text *string2)
+text *
+rpad(text * string1, int4 len, text * string2)
{
- text *ret;
- char *ptr1, *ptr2, *ptr_ret;
- int m, n;
-
- if ((string1 == (text *)NULL) ||
- (len <= (VARSIZE(string1) - VARHDRSZ)) ||
- ((m = len - VARSIZE(string1) + VARHDRSZ) <= 0) ||
- (string2 == (text *)NULL) ||
- ((VARSIZE(string2) - VARHDRSZ) <= 0))
- return string1;
-
- ret = (text *)palloc(VARHDRSZ + len);
- VARSIZE(ret) = VARHDRSZ + len;
-
- n = VARSIZE(string1) - VARHDRSZ;
- ptr1 = VARDATA(string1);
- ptr_ret = VARDATA(ret);
-
- while (n--) {
- *ptr_ret++ = *ptr1++;
- }
-
- ptr2 = VARDATA(string2);
-
- while (m--) {
- *ptr_ret++ = *ptr2;
- ptr2 = ptr2 == VARDATA(string2) + VARSIZE(string2) - VARHDRSZ - 1 ? VARDATA(string2) : ++ptr2;
- }
-
- return ret;
+ text *ret;
+ char *ptr1,
+ *ptr2,
+ *ptr_ret;
+ int m,
+ n;
+
+ if ((string1 == (text *) NULL) ||
+ (len <= (VARSIZE(string1) - VARHDRSZ)) ||
+ ((m = len - VARSIZE(string1) + VARHDRSZ) <= 0) ||
+ (string2 == (text *) NULL) ||
+ ((VARSIZE(string2) - VARHDRSZ) <= 0))
+ return string1;
+
+ ret = (text *) palloc(VARHDRSZ + len);
+ VARSIZE(ret) = VARHDRSZ + len;
+
+ n = VARSIZE(string1) - VARHDRSZ;
+ ptr1 = VARDATA(string1);
+ ptr_ret = VARDATA(ret);
+
+ while (n--)
+ {
+ *ptr_ret++ = *ptr1++;
+ }
+
+ ptr2 = VARDATA(string2);
+
+ while (m--)
+ {
+ *ptr_ret++ = *ptr2;
+ ptr2 = ptr2 == VARDATA(string2) + VARSIZE(string2) - VARHDRSZ - 1 ? VARDATA(string2) : ++ptr2;
+ }
+
+ return ret;
}
@@ -253,73 +272,84 @@ rpad(text *string1, int4 len, text *string2)
*
* Syntax:
*
- * text *btrim(text *string, text *set)
+ * text *btrim(text *string, text *set)
*
* Purpose:
*
- * Returns string with characters removed from the front and back
- * up to the first character not in set.
+ * Returns string with characters removed from the front and back
+ * up to the first character not in set.
*
********************************************************************/
-text *
-btrim(text *string, text *set)
+text *
+btrim(text * string, text * set)
{
- text *ret;
- char *ptr, *end, *ptr2, *end2;
- int m;
-
- if ((string == (text *)NULL) ||
- ((m = VARSIZE(string) - VARHDRSZ) <= 0) ||
- (set == (text *)NULL) ||
- ((VARSIZE(set) - VARHDRSZ) <= 0))
- return string;
-
- ptr = VARDATA(string);
- ptr2 = VARDATA(set);
- end2 = VARDATA(set) + VARSIZE(set) - VARHDRSZ - 1;
-
- while (m--) {
- while (ptr2 <= end2) {
- if (*ptr == *ptr2) {
- break;
- }
- ++ptr2;
- }
- if (*ptr != *ptr2) {
- break;
- }
- ptr++;
- ptr2 = VARDATA(set);
- }
-
- ++m;
-
- end = VARDATA(string) + VARSIZE(string) - VARHDRSZ - 1;
- ptr2 = VARDATA(set);
-
- while (m--) {
- while (ptr2 <= end2) {
- if (*end == *ptr2) {
- break;
- }
- ++ptr2;
- }
- if (*end != *ptr2) {
- break;
- }
- --end;
- ptr2 = VARDATA(set);
- }
-
- ++m;
-
- ret = (text *)palloc(VARHDRSZ + m);
- VARSIZE(ret) = VARHDRSZ + m;
- memcpy(VARDATA(ret),ptr,m);
-
- return ret;
-} /* btrim() */
+ text *ret;
+ char *ptr,
+ *end,
+ *ptr2,
+ *end2;
+ int m;
+
+ if ((string == (text *) NULL) ||
+ ((m = VARSIZE(string) - VARHDRSZ) <= 0) ||
+ (set == (text *) NULL) ||
+ ((VARSIZE(set) - VARHDRSZ) <= 0))
+ return string;
+
+ ptr = VARDATA(string);
+ ptr2 = VARDATA(set);
+ end2 = VARDATA(set) + VARSIZE(set) - VARHDRSZ - 1;
+
+ while (m--)
+ {
+ while (ptr2 <= end2)
+ {
+ if (*ptr == *ptr2)
+ {
+ break;
+ }
+ ++ptr2;
+ }
+ if (*ptr != *ptr2)
+ {
+ break;
+ }
+ ptr++;
+ ptr2 = VARDATA(set);
+ }
+
+ ++m;
+
+ end = VARDATA(string) + VARSIZE(string) - VARHDRSZ - 1;
+ ptr2 = VARDATA(set);
+
+ while (m--)
+ {
+ while (ptr2 <= end2)
+ {
+ if (*end == *ptr2)
+ {
+ break;
+ }
+ ++ptr2;
+ }
+ if (*end != *ptr2)
+ {
+ break;
+ }
+ --end;
+ ptr2 = VARDATA(set);
+ }
+
+ ++m;
+
+ ret = (text *) palloc(VARHDRSZ + m);
+ VARSIZE(ret) = VARHDRSZ + m;
+ memcpy(VARDATA(ret), ptr, m);
+
+ return ret;
+} /* btrim() */
/********************************************************************
@@ -328,54 +358,60 @@ btrim(text *string, text *set)
*
* Syntax:
*
- * text *ltrim(text *string, text *set)
+ * text *ltrim(text *string, text *set)
*
* Purpose:
*
- * Returns string with initial characters removed up to the first
- * character not in set.
+ * Returns string with initial characters removed up to the first
+ * character not in set.
*
********************************************************************/
-text *
-ltrim(text *string, text *set)
+text *
+ltrim(text * string, text * set)
{
- text *ret;
- char *ptr, *ptr2, *end2;
- int m;
-
- if ((string == (text *)NULL) ||
- ((m = VARSIZE(string) - VARHDRSZ) <= 0) ||
- (set == (text *)NULL) ||
- ((VARSIZE(set) - VARHDRSZ) <= 0))
- return string;
-
- ptr = VARDATA(string);
- ptr2 = VARDATA(set);
- end2 = VARDATA(set) + VARSIZE(set) - VARHDRSZ - 1;
-
- while (m--) {
- while (ptr2 <= end2) {
- if (*ptr == *ptr2) {
- break;
- }
- ++ptr2;
- }
- if (*ptr != *ptr2) {
- break;
- }
- ptr++;
- ptr2 = VARDATA(set);
- }
-
- ++m;
-
- ret = (text *)palloc(VARHDRSZ + m);
- VARSIZE(ret) = VARHDRSZ + m;
-
- memcpy(VARDATA(ret),ptr,m);
-
- return ret;
+ text *ret;
+ char *ptr,
+ *ptr2,
+ *end2;
+ int m;
+
+ if ((string == (text *) NULL) ||
+ ((m = VARSIZE(string) - VARHDRSZ) <= 0) ||
+ (set == (text *) NULL) ||
+ ((VARSIZE(set) - VARHDRSZ) <= 0))
+ return string;
+
+ ptr = VARDATA(string);
+ ptr2 = VARDATA(set);
+ end2 = VARDATA(set) + VARSIZE(set) - VARHDRSZ - 1;
+
+ while (m--)
+ {
+ while (ptr2 <= end2)
+ {
+ if (*ptr == *ptr2)
+ {
+ break;
+ }
+ ++ptr2;
+ }
+ if (*ptr != *ptr2)
+ {
+ break;
+ }
+ ptr++;
+ ptr2 = VARDATA(set);
+ }
+
+ ++m;
+
+ ret = (text *) palloc(VARHDRSZ + m);
+ VARSIZE(ret) = VARHDRSZ + m;
+
+ memcpy(VARDATA(ret), ptr, m);
+
+ return ret;
}
@@ -385,61 +421,69 @@ ltrim(text *string, text *set)
*
* Syntax:
*
- * text *rtrim(text *string, text *set)
+ * text *rtrim(text *string, text *set)
*
* Purpose:
*
- * Returns string with final characters removed after the last
- * character not in set.
+ * Returns string with final characters removed after the last
+ * character not in set.
*
********************************************************************/
-text *
-rtrim(text *string, text *set)
+text *
+rtrim(text * string, text * set)
{
- text *ret;
- char *ptr, *ptr2, *end2, *ptr_ret;
- int m;
-
- if ((string == (text *)NULL) ||
- ((m = VARSIZE(string) - VARHDRSZ) <= 0) ||
- (set == (text *)NULL) ||
- ((VARSIZE(set) - VARHDRSZ) <= 0))
- return string;
-
- ptr = VARDATA(string) + VARSIZE(string) - VARHDRSZ - 1;
- ptr2 = VARDATA(set);
- end2 = VARDATA(set) + VARSIZE(set) - VARHDRSZ - 1;
-
- while (m--) {
- while (ptr2 <= end2) {
- if (*ptr == *ptr2) {
- break;
- }
- ++ptr2;
- }
- if (*ptr != *ptr2) {
- break;
- }
- --ptr;
- ptr2 = VARDATA(set);
- }
-
- ++m;
-
- ret = (text *)palloc(VARHDRSZ + m);
- VARSIZE(ret) = VARHDRSZ + m;
+ text *ret;
+ char *ptr,
+ *ptr2,
+ *end2,
+ *ptr_ret;
+ int m;
+
+ if ((string == (text *) NULL) ||
+ ((m = VARSIZE(string) - VARHDRSZ) <= 0) ||
+ (set == (text *) NULL) ||
+ ((VARSIZE(set) - VARHDRSZ) <= 0))
+ return string;
+
+ ptr = VARDATA(string) + VARSIZE(string) - VARHDRSZ - 1;
+ ptr2 = VARDATA(set);
+ end2 = VARDATA(set) + VARSIZE(set) - VARHDRSZ - 1;
+
+ while (m--)
+ {
+ while (ptr2 <= end2)
+ {
+ if (*ptr == *ptr2)
+ {
+ break;
+ }
+ ++ptr2;
+ }
+ if (*ptr != *ptr2)
+ {
+ break;
+ }
+ --ptr;
+ ptr2 = VARDATA(set);
+ }
+
+ ++m;
+
+ ret = (text *) palloc(VARHDRSZ + m);
+ VARSIZE(ret) = VARHDRSZ + m;
#if FALSE
- memcpy(VARDATA(ret),ptr-VARSIZE(ret)+m,m);
+ memcpy(VARDATA(ret), ptr - VARSIZE(ret) + m, m);
#endif
- ptr_ret = VARDATA(ret) + m - 1;
+ ptr_ret = VARDATA(ret) + m - 1;
- while (m--) {
- *ptr_ret-- = *ptr--;
- }
+ while (m--)
+ {
+ *ptr_ret-- = *ptr--;
+ }
- return ret;
+ return ret;
}
@@ -449,40 +493,42 @@ rtrim(text *string, text *set)
*
* Syntax:
*
- * text *substr(text *string, int4 m, int4 n)
+ * text *substr(text *string, int4 m, int4 n)
*
* Purpose:
*
- * Returns a portion of string, beginning at character m, n
- * characters long. The first position of string is 1.
+ * Returns a portion of string, beginning at character m, n
+ * characters long. The first position of string is 1.
*
********************************************************************/
-text *
-substr(text *string, int4 m, int4 n)
+text *
+substr(text * string, int4 m, int4 n)
{
- text *ret;
- char *ptr, *ptr_ret;
- int len;
+ text *ret;
+ char *ptr,
+ *ptr_ret;
+ int len;
- if ((string == (text *)NULL) ||
- (m <= 0) || (n <= 0) ||
- ((len = VARSIZE(string) - VARHDRSZ - m) <= 0))
- return string;
+ if ((string == (text *) NULL) ||
+ (m <= 0) || (n <= 0) ||
+ ((len = VARSIZE(string) - VARHDRSZ - m) <= 0))
+ return string;
- len = len + 1 < n ? len + 1 : n;
+ len = len + 1 < n ? len + 1 : n;
- ret = (text *)palloc(VARHDRSZ + len);
- VARSIZE(ret) = VARHDRSZ + len;
+ ret = (text *) palloc(VARHDRSZ + len);
+ VARSIZE(ret) = VARHDRSZ + len;
- ptr = VARDATA(string) + m - 1;
- ptr_ret = VARDATA(ret);
+ ptr = VARDATA(string) + m - 1;
+ ptr_ret = VARDATA(ret);
- while (len--) {
- *ptr_ret++ = *ptr++;
- }
+ while (len--)
+ {
+ *ptr_ret++ = *ptr++;
+ }
- return ret;
+ return ret;
}
@@ -492,39 +538,41 @@ substr(text *string, int4 m, int4 n)
*
* Syntax:
*
- * text *translate(text *string, char from, char to)
+ * text *translate(text *string, char from, char to)
*
* Purpose:
*
- * Returns string after replacing all occurences of from with
- * the corresponding character in to. TRANSLATE will not remove
- * characters.
+ * Returns string after replacing all occurences of from with
+ * the corresponding character in to. TRANSLATE will not remove
+ * characters.
*
********************************************************************/
-text *
-translate(text *string, char from, char to)
+text *
+translate(text * string, char from, char to)
{
- text *ret;
- char *ptr, *ptr_ret;
- int m;
+ text *ret;
+ char *ptr,
+ *ptr_ret;
+ int m;
- if ((string == (text *)NULL) ||
- ((m = VARSIZE(string) - VARHDRSZ) <= 0))
- return string;
+ if ((string == (text *) NULL) ||
+ ((m = VARSIZE(string) - VARHDRSZ) <= 0))
+ return string;
- ret = (text *)palloc(VARSIZE(string));
- VARSIZE(ret) = VARSIZE(string);
+ ret = (text *) palloc(VARSIZE(string));
+ VARSIZE(ret) = VARSIZE(string);
- ptr = VARDATA(string);
- ptr_ret = VARDATA(ret);
+ ptr = VARDATA(string);
+ ptr_ret = VARDATA(ret);
- while (m--) {
- *ptr_ret++ = *ptr == from ? to : *ptr;
- ptr++;
- }
+ while (m--)
+ {
+ *ptr_ret++ = *ptr == from ? to : *ptr;
+ ptr++;
+ }
- return ret;
+ return ret;
}
diff --git a/src/backend/utils/adt/regexp.c b/src/backend/utils/adt/regexp.c
index a0d61b8304c..e7d982785ba 100644
--- a/src/backend/utils/adt/regexp.c
+++ b/src/backend/utils/adt/regexp.c
@@ -1,42 +1,42 @@
/*-------------------------------------------------------------------------
*
* regexp.c--
- * regular expression handling code.
+ * regular expression handling code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/regexp.c,v 1.7 1997/08/12 22:54:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/regexp.c,v 1.8 1997/09/07 04:50:39 momjian Exp $
*
- * Alistair Crooks added the code for the regex caching
- * agc - cached the regular expressions used - there's a good chance
- * that we'll get a hit, so this saves a compile step for every
- * attempted match. I haven't actually measured the speed improvement,
- * but it `looks' a lot quicker visually when watching regression
- * test output.
+ * Alistair Crooks added the code for the regex caching
+ * agc - cached the regular expressions used - there's a good chance
+ * that we'll get a hit, so this saves a compile step for every
+ * attempted match. I haven't actually measured the speed improvement,
+ * but it `looks' a lot quicker visually when watching regression
+ * test output.
*
- * agc - incorporated Keith Bostic's Berkeley regex code into
- * the tree for all ports. To distinguish this regex code from any that
- * is existent on a platform, I've prepended the string "pg95_" to
- * the functions regcomp, regerror, regexec and regfree.
- * Fixed a bug that was originally a typo by me, where `i' was used
- * instead of `oldest' when compiling regular expressions - benign
- * results mostly, although occasionally it bit you...
+ * agc - incorporated Keith Bostic's Berkeley regex code into
+ * the tree for all ports. To distinguish this regex code from any that
+ * is existent on a platform, I've prepended the string "pg95_" to
+ * the functions regcomp, regerror, regexec and regfree.
+ * Fixed a bug that was originally a typo by me, where `i' was used
+ * instead of `oldest' when compiling regular expressions - benign
+ * results mostly, although occasionally it bit you...
*
*
*-------------------------------------------------------------------------
*/
#include <string.h>
-#include "postgres.h" /* postgres system include file */
+#include "postgres.h" /* postgres system include file */
#include <regex/regex.h>
-#include "utils/builtins.h" /* where the function declarations go */
+#include "utils/builtins.h" /* where the function declarations go */
#if defined(DISABLE_XOPEN_NLS)
#undef _XOPEN_SOURCE
-#endif /* DISABLE_XOPEN_NLS */
+#endif /* DISABLE_XOPEN_NLS */
/* this is the number of cached regular expressions held. */
#ifndef MAX_CACHED_RES
@@ -44,297 +44,329 @@
#endif
/* this structure describes a cached regular expression */
-struct cached_re_str {
- struct varlena *cre_text; /* pattern as a text* */
- char *cre_s; /* pattern as null-terminated string */
- int cre_type; /* compiled-type: extended,icase etc */
- regex_t cre_re; /* the compiled regular expression */
+struct cached_re_str
+{
+ struct varlena *cre_text; /* pattern as a text* */
+ char *cre_s; /* pattern as null-terminated string */
+ int cre_type; /* compiled-type: extended,icase etc */
+ regex_t cre_re; /* the compiled regular expression */
unsigned long cre_lru; /* lru tag */
};
-static int rec = 0; /* # of cached re's */
-static struct cached_re_str rev[MAX_CACHED_RES]; /* cached re's */
-static unsigned long lru; /* system lru tag */
+static int rec = 0; /* # of cached re's */
+static struct cached_re_str rev[MAX_CACHED_RES]; /* cached re's */
+static unsigned long lru; /* system lru tag */
/* attempt to compile `re' as an re, then match it against text */
/* cflags - flag to regcomp indicates case sensitivity */
static int
-RE_compile_and_execute(struct varlena *text_re, char *text, int cflags)
+RE_compile_and_execute(struct varlena * text_re, char *text, int cflags)
{
- int oldest;
- int n;
- int i;
- char *re;
- int regcomp_result;
-
- re = textout(text_re);
- /* find a previously compiled regular expression */
- for (i = 0 ; i < rec ; i++) {
- if (rev[i].cre_s) {
- if (strcmp(rev[i].cre_s, re) == 0) {
- if (rev[i].cre_type == cflags) {
- rev[i].cre_lru = ++lru;
- pfree(re);
- return(pg95_regexec(&rev[i].cre_re,
- text, 0,
- (regmatch_t *) NULL, 0) == 0);
- }
+ int oldest;
+ int n;
+ int i;
+ char *re;
+ int regcomp_result;
+
+ re = textout(text_re);
+ /* find a previously compiled regular expression */
+ for (i = 0; i < rec; i++)
+ {
+ if (rev[i].cre_s)
+ {
+ if (strcmp(rev[i].cre_s, re) == 0)
+ {
+ if (rev[i].cre_type == cflags)
+ {
+ rev[i].cre_lru = ++lru;
+ pfree(re);
+ return (pg95_regexec(&rev[i].cre_re,
+ text, 0,
+ (regmatch_t *) NULL, 0) == 0);
+ }
+ }
}
- }
- }
-
+ }
+
/* we didn't find it - make room in the cache for it */
- if (rec == MAX_CACHED_RES) {
+ if (rec == MAX_CACHED_RES)
+ {
/* cache is full - find the oldest entry */
- for (oldest = 0, i = 1 ; i < rec ; i++) {
- if (rev[i].cre_lru < rev[oldest].cre_lru) {
+ for (oldest = 0, i = 1; i < rec; i++)
+ {
+ if (rev[i].cre_lru < rev[oldest].cre_lru)
+ {
oldest = i;
}
}
- } else {
+ }
+ else
+ {
oldest = rec++;
}
/* if there was an old re, then de-allocate the space it used */
- if (rev[oldest].cre_s != (char *) NULL) {
- for (lru = i = 0 ; i < rec ; i++) {
+ if (rev[oldest].cre_s != (char *) NULL)
+ {
+ for (lru = i = 0; i < rec; i++)
+ {
rev[i].cre_lru =
(rev[i].cre_lru - rev[oldest].cre_lru) / 2;
- if (rev[i].cre_lru > lru) {
+ if (rev[i].cre_lru > lru)
+ {
lru = rev[i].cre_lru;
}
- }
+ }
pg95_regfree(&rev[oldest].cre_re);
- /* use malloc/free for the cre_s field because the storage
- has to persist across transactions */
- free(rev[oldest].cre_s);
+
+ /*
+ * use malloc/free for the cre_s field because the storage has to
+ * persist across transactions
+ */
+ free(rev[oldest].cre_s);
}
/* compile the re */
regcomp_result = pg95_regcomp(&rev[oldest].cre_re, re, cflags);
- if ( regcomp_result == 0) {
+ if (regcomp_result == 0)
+ {
n = strlen(re);
- /* use malloc/free for the cre_s field because the storage
- has to persist across transactions */
+
+ /*
+ * use malloc/free for the cre_s field because the storage has to
+ * persist across transactions
+ */
rev[oldest].cre_s = (char *) malloc(n + 1);
memmove(rev[oldest].cre_s, re, n);
rev[oldest].cre_s[n] = 0;
- rev[oldest].cre_text = text_re;
+ rev[oldest].cre_text = text_re;
rev[oldest].cre_lru = ++lru;
- rev[oldest].cre_type = cflags;
+ rev[oldest].cre_type = cflags;
pfree(re);
- /* agc - fixed an old typo here */
- return(pg95_regexec(&rev[oldest].cre_re, text, 0,
- (regmatch_t *) NULL, 0) == 0);
- } else {
- char errMsg[1000];
- /* re didn't compile */
- rev[oldest].cre_s = (char *) NULL;
- pg95_regerror(regcomp_result, &rev[oldest].cre_re, errMsg,
- sizeof(errMsg));
- elog(WARN,"regcomp failed with error %s",errMsg);
+ /* agc - fixed an old typo here */
+ return (pg95_regexec(&rev[oldest].cre_re, text, 0,
+ (regmatch_t *) NULL, 0) == 0);
+ }
+ else
+ {
+ char errMsg[1000];
+
+ /* re didn't compile */
+ rev[oldest].cre_s = (char *) NULL;
+ pg95_regerror(regcomp_result, &rev[oldest].cre_re, errMsg,
+ sizeof(errMsg));
+ elog(WARN, "regcomp failed with error %s", errMsg);
}
/* not reached */
- return(0);
+ return (0);
}
/*
- * interface routines called by the function manager
+ * interface routines called by the function manager
*/
/*
fixedlen_regexeq:
a generic fixed length regexp routine
- s - the string to match against (not necessarily null-terminated)
- p - the pattern
- charlen - the length of the string
+ s - the string to match against (not necessarily null-terminated)
+ p - the pattern
+ charlen - the length of the string
*/
-static bool
-fixedlen_regexeq(char *s, struct varlena* p, int charlen, int cflags)
+static bool
+fixedlen_regexeq(char *s, struct varlena * p, int charlen, int cflags)
{
- char *sterm;
- int result;
-
- if (!s || !p)
- return FALSE;
-
- /* be sure sterm is null-terminated */
- sterm = (char *) palloc(charlen + 1);
- strNcpy(sterm, s, charlen);
-
- result = RE_compile_and_execute(p, sterm, cflags);
-
- pfree(sterm);
-
- return ((bool) result);
+ char *sterm;
+ int result;
+
+ if (!s || !p)
+ return FALSE;
+
+ /* be sure sterm is null-terminated */
+ sterm = (char *) palloc(charlen + 1);
+ strNcpy(sterm, s, charlen);
+
+ result = RE_compile_and_execute(p, sterm, cflags);
+
+ pfree(sterm);
+
+ return ((bool) result);
}
/*
- * routines that use the regexp stuff
+ * routines that use the regexp stuff
*/
-bool
-char2regexeq(uint16 arg1, struct varlena *p)
+bool
+char2regexeq(uint16 arg1, struct varlena * p)
{
- char *s = (char *) &arg1;
- return (fixedlen_regexeq(s, p, 2, REG_EXTENDED));
+ char *s = (char *) &arg1;
+
+ return (fixedlen_regexeq(s, p, 2, REG_EXTENDED));
}
-bool
-char2regexne(uint16 arg1, struct varlena *p)
+bool
+char2regexne(uint16 arg1, struct varlena * p)
{
- return (!char2regexeq(arg1, p));
+ return (!char2regexeq(arg1, p));
}
-bool
-char4regexeq(uint32 arg1, struct varlena *p)
+bool
+char4regexeq(uint32 arg1, struct varlena * p)
{
- char *s = (char *) &arg1;
- return (fixedlen_regexeq(s, p, 4, REG_EXTENDED));
+ char *s = (char *) &arg1;
+
+ return (fixedlen_regexeq(s, p, 4, REG_EXTENDED));
}
-bool
-char4regexne(uint32 arg1, struct varlena *p)
+bool
+char4regexne(uint32 arg1, struct varlena * p)
{
- return (!char4regexeq(arg1, p));
+ return (!char4regexeq(arg1, p));
}
-bool
-char8regexeq(char *s, struct varlena *p)
+bool
+char8regexeq(char *s, struct varlena * p)
{
- return (fixedlen_regexeq(s, p, 8, REG_EXTENDED));
+ return (fixedlen_regexeq(s, p, 8, REG_EXTENDED));
}
-bool
-char8regexne(char *s, struct varlena *p)
+bool
+char8regexne(char *s, struct varlena * p)
{
- return (!char8regexeq(s, p));
+ return (!char8regexeq(s, p));
}
-bool
-char16regexeq(char *s, struct varlena *p)
+bool
+char16regexeq(char *s, struct varlena * p)
{
- return (fixedlen_regexeq(s, p, 16, REG_EXTENDED));
+ return (fixedlen_regexeq(s, p, 16, REG_EXTENDED));
}
-bool
-char16regexne(char *s, struct varlena *p)
+bool
+char16regexne(char *s, struct varlena * p)
{
- return (!char16regexeq(s, p));
+ return (!char16regexeq(s, p));
}
-bool
-nameregexeq(NameData *n, struct varlena *p)
+bool
+nameregexeq(NameData * n, struct varlena * p)
{
- if (!n) return FALSE;
- return (fixedlen_regexeq(n->data, p, NAMEDATALEN, REG_EXTENDED));
+ if (!n)
+ return FALSE;
+ return (fixedlen_regexeq(n->data, p, NAMEDATALEN, REG_EXTENDED));
}
-bool
-nameregexne(NameData *s, struct varlena *p)
+
+bool
+nameregexne(NameData * s, struct varlena * p)
{
- return (!nameregexeq(s, p));
+ return (!nameregexeq(s, p));
}
-bool
-textregexeq(struct varlena *s, struct varlena *p)
+bool
+textregexeq(struct varlena * s, struct varlena * p)
{
- if (!s) return (FALSE);
- return (fixedlen_regexeq(VARDATA(s), p, VARSIZE(s) - VARHDRSZ, REG_EXTENDED));
+ if (!s)
+ return (FALSE);
+ return (fixedlen_regexeq(VARDATA(s), p, VARSIZE(s) - VARHDRSZ, REG_EXTENDED));
}
-bool
-textregexne(struct varlena *s, struct varlena *p)
+bool
+textregexne(struct varlena * s, struct varlena * p)
{
- return (!textregexeq(s, p));
+ return (!textregexeq(s, p));
}
/*
* routines that use the regexp stuff, but ignore the case.
- * for this, we use the REG_ICASE flag to pg95_regcomp
+ * for this, we use the REG_ICASE flag to pg95_regcomp
*/
-bool
-char2icregexeq(uint16 arg1, struct varlena *p)
+bool
+char2icregexeq(uint16 arg1, struct varlena * p)
{
- char *s = (char *) &arg1;
- return (fixedlen_regexeq(s, p, 2, REG_ICASE | REG_EXTENDED));
+ char *s = (char *) &arg1;
+
+ return (fixedlen_regexeq(s, p, 2, REG_ICASE | REG_EXTENDED));
}
-
-bool
-char2icregexne(uint16 arg1, struct varlena *p)
+
+bool
+char2icregexne(uint16 arg1, struct varlena * p)
{
- return (!char2icregexeq(arg1, p));
+ return (!char2icregexeq(arg1, p));
}
-bool
-char4icregexeq(uint32 arg1, struct varlena *p)
+bool
+char4icregexeq(uint32 arg1, struct varlena * p)
{
- char *s = (char *) &arg1;
- return (fixedlen_regexeq(s, p, 4, REG_ICASE | REG_EXTENDED ));
+ char *s = (char *) &arg1;
+
+ return (fixedlen_regexeq(s, p, 4, REG_ICASE | REG_EXTENDED));
}
-bool
-char4icregexne(uint32 arg1, struct varlena *p)
+bool
+char4icregexne(uint32 arg1, struct varlena * p)
{
- return (!char4icregexeq(arg1, p));
+ return (!char4icregexeq(arg1, p));
}
-
-bool
-char8icregexeq(char *s, struct varlena *p)
+
+bool
+char8icregexeq(char *s, struct varlena * p)
{
- return (fixedlen_regexeq(s, p, 8, REG_ICASE | REG_EXTENDED));
+ return (fixedlen_regexeq(s, p, 8, REG_ICASE | REG_EXTENDED));
}
-bool
-char8icregexne(char *s, struct varlena *p)
+bool
+char8icregexne(char *s, struct varlena * p)
{
- return (!char8icregexeq(s, p));
+ return (!char8icregexeq(s, p));
}
-bool
-char16icregexeq(char *s, struct varlena *p)
+bool
+char16icregexeq(char *s, struct varlena * p)
{
- return (fixedlen_regexeq(s, p, 16, REG_ICASE | REG_EXTENDED));
+ return (fixedlen_regexeq(s, p, 16, REG_ICASE | REG_EXTENDED));
}
-bool
-char16icregexne(char *s, struct varlena *p)
+bool
+char16icregexne(char *s, struct varlena * p)
{
- return (!char16icregexeq(s, p));
+ return (!char16icregexeq(s, p));
}
-bool
-texticregexeq(struct varlena *s, struct varlena *p)
+bool
+texticregexeq(struct varlena * s, struct varlena * p)
{
- if (!s) return FALSE;
- return (fixedlen_regexeq(VARDATA(s), p, VARSIZE(s) - VARHDRSZ,
- REG_ICASE | REG_EXTENDED));
+ if (!s)
+ return FALSE;
+ return (fixedlen_regexeq(VARDATA(s), p, VARSIZE(s) - VARHDRSZ,
+ REG_ICASE | REG_EXTENDED));
}
-bool
-texticregexne(struct varlena *s, struct varlena *p)
+bool
+texticregexne(struct varlena * s, struct varlena * p)
{
- return (!texticregexeq(s, p));
+ return (!texticregexeq(s, p));
}
-bool
-nameicregexeq(NameData *n, struct varlena *p)
+bool
+nameicregexeq(NameData * n, struct varlena * p)
{
- if (!n) return FALSE;
- return (fixedlen_regexeq(n->data, p, NAMEDATALEN,
- REG_ICASE | REG_EXTENDED));
+ if (!n)
+ return FALSE;
+ return (fixedlen_regexeq(n->data, p, NAMEDATALEN,
+ REG_ICASE | REG_EXTENDED));
}
-bool
-nameicregexne(NameData *s, struct varlena *p)
+
+bool
+nameicregexne(NameData * s, struct varlena * p)
{
- return (!nameicregexeq(s, p));
+ return (!nameicregexeq(s, p));
}
-
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 04442cb42df..6a4e8b01e50 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* regproc.c--
- * Functions for the built-in type "RegProcedure".
+ * Functions for the built-in type "RegProcedure".
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.5 1997/08/12 20:16:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.6 1997/09/07 04:50:41 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,129 +19,140 @@
#include "utils/palloc.h"
#include "catalog/catname.h"
-#include "utils/builtins.h" /* where function declarations go */
+#include "utils/builtins.h" /* where function declarations go */
-/*****************************************************************************
- * USER I/O ROUTINES *
+/*****************************************************************************
+ * USER I/O ROUTINES *
*****************************************************************************/
/*
- * regprocin - converts "proname" to proid
+ * regprocin - converts "proname" to proid
*
- * proid of NULL signifies unknown
+ * proid of NULL signifies unknown
*/
-int32 regprocin(char *proname)
+int32
+regprocin(char *proname)
{
- Relation proc;
- HeapScanDesc procscan;
- HeapTuple proctup;
- ScanKeyData key;
- RegProcedure result = (Oid)0;
- bool isnull;
-
- if (proname == NULL)
- return(0);
- proc = heap_openr(ProcedureRelationName);
- if (!RelationIsValid(proc)) {
- elog(WARN, "regprocin: could not open %s",
- ProcedureRelationName);
- return(0);
- }
- ScanKeyEntryInitialize(&key,
- (bits16)0,
- (AttrNumber)1,
- (RegProcedure)F_CHAR16EQ,
- (Datum)proname);
-
- procscan = heap_beginscan(proc, 0, NowTimeQual, 1, &key);
- if (!HeapScanIsValid(procscan)) {
- heap_close(proc);
- elog(WARN, "regprocin: could not being scan of %s",
- ProcedureRelationName);
- return(0);
- }
- proctup = heap_getnext(procscan, 0, (Buffer *) NULL);
- switch (HeapTupleIsValid(proctup)) {
- case 1:
- result = (RegProcedure) heap_getattr(proctup,
- InvalidBuffer,
- ObjectIdAttributeNumber,
- RelationGetTupleDescriptor(proc),
- &isnull);
- if (isnull) {
- elog(FATAL, "regprocin: null procedure %s", proname);
+ Relation proc;
+ HeapScanDesc procscan;
+ HeapTuple proctup;
+ ScanKeyData key;
+ RegProcedure result = (Oid) 0;
+ bool isnull;
+
+ if (proname == NULL)
+ return (0);
+ proc = heap_openr(ProcedureRelationName);
+ if (!RelationIsValid(proc))
+ {
+ elog(WARN, "regprocin: could not open %s",
+ ProcedureRelationName);
+ return (0);
+ }
+ ScanKeyEntryInitialize(&key,
+ (bits16) 0,
+ (AttrNumber) 1,
+ (RegProcedure) F_CHAR16EQ,
+ (Datum) proname);
+
+ procscan = heap_beginscan(proc, 0, NowTimeQual, 1, &key);
+ if (!HeapScanIsValid(procscan))
+ {
+ heap_close(proc);
+ elog(WARN, "regprocin: could not being scan of %s",
+ ProcedureRelationName);
+ return (0);
}
- break;
- case 0:
- result = (RegProcedure) 0;
+ proctup = heap_getnext(procscan, 0, (Buffer *) NULL);
+ switch (HeapTupleIsValid(proctup))
+ {
+ case 1:
+ result = (RegProcedure) heap_getattr(proctup,
+ InvalidBuffer,
+ ObjectIdAttributeNumber,
+ RelationGetTupleDescriptor(proc),
+ &isnull);
+ if (isnull)
+ {
+ elog(FATAL, "regprocin: null procedure %s", proname);
+ }
+ break;
+ case 0:
+ result = (RegProcedure) 0;
#ifdef EBUG
- elog(DEBUG, "regprocin: no such procedure %s", proname);
-#endif /* defined(EBUG) */
- }
- heap_endscan(procscan);
- heap_close(proc);
- return((int32) result);
+ elog(DEBUG, "regprocin: no such procedure %s", proname);
+#endif /* defined(EBUG) */
+ }
+ heap_endscan(procscan);
+ heap_close(proc);
+ return ((int32) result);
}
/*
- * regprocout - converts proid to "proname"
+ * regprocout - converts proid to "proname"
*/
-char *regprocout(RegProcedure proid)
+char *
+regprocout(RegProcedure proid)
{
- Relation proc;
- HeapScanDesc procscan;
- HeapTuple proctup;
- char *result;
- ScanKeyData key;
-
- result = (char *)palloc(NAMEDATALEN);
- proc = heap_openr(ProcedureRelationName);
- if (!RelationIsValid(proc)) {
- elog(WARN, "regprocout: could not open %s",
- ProcedureRelationName);
- return(0);
- }
- ScanKeyEntryInitialize(&key,
- (bits16)0,
- (AttrNumber)ObjectIdAttributeNumber,
- (RegProcedure)F_INT4EQ,
- (Datum)proid);
-
- procscan = heap_beginscan(proc, 0, NowTimeQual, 1, &key);
- if (!HeapScanIsValid(procscan)) {
- heap_close(proc);
- elog(WARN, "regprocin: could not being scan of %s",
- ProcedureRelationName);
- return(0);
- }
- proctup = heap_getnext(procscan, 0, (Buffer *)NULL);
- switch (HeapTupleIsValid(proctup)) {
- char *s;
- bool isnull;
- case 1:
- s = (char *) heap_getattr(proctup, InvalidBuffer, 1,
- RelationGetTupleDescriptor(proc), &isnull);
- if (!isnull) {
- strNcpy(result, s, 16);
- break;
+ Relation proc;
+ HeapScanDesc procscan;
+ HeapTuple proctup;
+ char *result;
+ ScanKeyData key;
+
+ result = (char *) palloc(NAMEDATALEN);
+ proc = heap_openr(ProcedureRelationName);
+ if (!RelationIsValid(proc))
+ {
+ elog(WARN, "regprocout: could not open %s",
+ ProcedureRelationName);
+ return (0);
+ }
+ ScanKeyEntryInitialize(&key,
+ (bits16) 0,
+ (AttrNumber) ObjectIdAttributeNumber,
+ (RegProcedure) F_INT4EQ,
+ (Datum) proid);
+
+ procscan = heap_beginscan(proc, 0, NowTimeQual, 1, &key);
+ if (!HeapScanIsValid(procscan))
+ {
+ heap_close(proc);
+ elog(WARN, "regprocin: could not being scan of %s",
+ ProcedureRelationName);
+ return (0);
}
- elog(FATAL, "regprocout: null procedure %d", proid);
- /*FALLTHROUGH*/
- case 0:
- result[0] = '-';
- result[1] = '\0';
+ proctup = heap_getnext(procscan, 0, (Buffer *) NULL);
+ switch (HeapTupleIsValid(proctup))
+ {
+ char *s;
+ bool isnull;
+
+ case 1:
+ s = (char *) heap_getattr(proctup, InvalidBuffer, 1,
+ RelationGetTupleDescriptor(proc), &isnull);
+ if (!isnull)
+ {
+ strNcpy(result, s, 16);
+ break;
+ }
+ elog(FATAL, "regprocout: null procedure %d", proid);
+ /* FALLTHROUGH */
+ case 0:
+ result[0] = '-';
+ result[1] = '\0';
#ifdef EBUG
- elog(DEBUG, "regprocout: no such procedure %d", proid);
-#endif /* defined(EBUG) */
- }
- heap_endscan(procscan);
- heap_close(proc);
- return(result);
+ elog(DEBUG, "regprocout: no such procedure %d", proid);
+#endif /* defined(EBUG) */
+ }
+ heap_endscan(procscan);
+ heap_close(proc);
+ return (result);
}
-/*****************************************************************************
- * PUBLIC ROUTINES *
+/*****************************************************************************
+ * PUBLIC ROUTINES *
*****************************************************************************/
/* regproctooid()
@@ -149,13 +160,13 @@ char *regprocout(RegProcedure proid)
* Define RegprocToOid() as a macro in builtins.h.
* Referenced in pg_proc.h. - tgl 97/04/26
*/
-Oid regproctooid(RegProcedure rp)
+Oid
+regproctooid(RegProcedure rp)
{
- return (Oid)rp;
+ return (Oid) rp;
}
/* (see int.c for comparison/operation routines) */
/* ========== PRIVATE ROUTINES ========== */
-
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index fe90feda72d..3f8c225ca9e 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* selfuncs.c--
- * Selectivity functions for system catalogs and builtin types
+ * Selectivity functions for system catalogs and builtin types
*
- * These routines are registered in the operator catalog in the
- * "oprrest" and "oprjoin" attributes.
+ * These routines are registered in the operator catalog in the
+ * "oprrest" and "oprjoin" attributes.
*
- * XXX check all the functions--I suspect them to be 1-based.
+ * XXX check all the functions--I suspect them to be 1-based.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.8 1997/08/21 03:02:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.9 1997/09/07 04:50:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,10 +22,10 @@
#include "postgres.h"
#include "access/heapam.h"
-#include "utils/tqual.h" /* for NowTimeQual */
+#include "utils/tqual.h" /* for NowTimeQual */
#include "fmgr.h"
-#include "utils/builtins.h" /* for textout() prototype
- and where the declarations go */
+#include "utils/builtins.h" /* for textout() prototype and where the
+ * declarations go */
#include "utils/palloc.h"
#include "catalog/catname.h"
@@ -34,580 +34,624 @@
#include "catalog/pg_statistic.h"
/* N is not a valid var/constant or relation id */
-#define NONVALUE(N) ((N) == -1)
+#define NONVALUE(N) ((N) == -1)
-/*
+/*
* generalize the test for functional index selectivity request
*/
#define FunctionalSelectivity(nIndKeys,attNum) (attNum==InvalidAttrNumber)
static float32data getattdisbursion(Oid relid, AttrNumber attnum);
-static void gethilokey(Oid relid, AttrNumber attnum, Oid opid,
- char **high, char **low);
+static void
+gethilokey(Oid relid, AttrNumber attnum, Oid opid,
+ char **high, char **low);
/*
- * eqsel - Selectivity of "=" for any data type.
+ * eqsel - Selectivity of "=" for any data type.
*/
float64
eqsel(Oid opid,
- Oid relid,
- AttrNumber attno,
- char *value,
- int32 flag)
+ Oid relid,
+ AttrNumber attno,
+ char *value,
+ int32 flag)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
- if (NONVALUE(attno) || NONVALUE(relid))
- *result = 0.1;
- else
- *result = (float64data)getattdisbursion(relid, (int) attno);
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+ if (NONVALUE(attno) || NONVALUE(relid))
+ *result = 0.1;
+ else
+ *result = (float64data) getattdisbursion(relid, (int) attno);
+ return (result);
}
/*
- * neqsel - Selectivity of "!=" for any data type.
+ * neqsel - Selectivity of "!=" for any data type.
*/
float64
neqsel(Oid opid,
- Oid relid,
- AttrNumber attno,
- char *value,
- int32 flag)
+ Oid relid,
+ AttrNumber attno,
+ char *value,
+ int32 flag)
{
- float64 result;
-
- result = eqsel(opid, relid, attno, value, flag);
- *result = 1.0 - *result;
- return(result);
+ float64 result;
+
+ result = eqsel(opid, relid, attno, value, flag);
+ *result = 1.0 - *result;
+ return (result);
}
/*
- * intltsel - Selectivity of "<" for integers.
- * Should work for both longs and shorts.
+ * intltsel - Selectivity of "<" for integers.
+ * Should work for both longs and shorts.
*/
float64
intltsel(Oid opid,
- Oid relid,
- AttrNumber attno,
- int32 value,
- int32 flag)
+ Oid relid,
+ AttrNumber attno,
+ int32 value,
+ int32 flag)
{
- float64 result;
- char *highchar, *lowchar;
- long val, high, low, top, bottom;
-
- result = (float64) palloc(sizeof(float64data));
- if (NONVALUE(attno) || NONVALUE(relid))
- *result = 1.0 / 3;
- else {
- /* XXX val = atol(value);*/
- val = value;
- gethilokey(relid, (int) attno, opid, &highchar, &lowchar);
- if (*highchar == 'n' || *lowchar == 'n') {
- *result = 1.0/3.0;
- return (result);
- }
- high = atol(highchar);
- low = atol(lowchar);
- if ((flag & SEL_RIGHT && val < low) ||
- (!(flag & SEL_RIGHT) && val > high)) {
- float32data nvals;
- nvals = getattdisbursion(relid, (int) attno);
- if (nvals == 0)
- *result = 1.0 / 3.0;
- else {
- *result = 3.0 * (float64data)nvals;
- if (*result > 1.0)
- *result = 1;
- }
- }else {
- bottom = high - low;
- if (bottom == 0)
- ++bottom;
- if (flag & SEL_RIGHT)
- top = val - low;
- else
- top = high - val;
- if (top > bottom)
- *result = 1.0;
- else {
- if (top == 0)
- ++top;
- *result = ((1.0 * top) / bottom);
- }
+ float64 result;
+ char *highchar,
+ *lowchar;
+ long val,
+ high,
+ low,
+ top,
+ bottom;
+
+ result = (float64) palloc(sizeof(float64data));
+ if (NONVALUE(attno) || NONVALUE(relid))
+ *result = 1.0 / 3;
+ else
+ {
+ /* XXX val = atol(value); */
+ val = value;
+ gethilokey(relid, (int) attno, opid, &highchar, &lowchar);
+ if (*highchar == 'n' || *lowchar == 'n')
+ {
+ *result = 1.0 / 3.0;
+ return (result);
+ }
+ high = atol(highchar);
+ low = atol(lowchar);
+ if ((flag & SEL_RIGHT && val < low) ||
+ (!(flag & SEL_RIGHT) && val > high))
+ {
+ float32data nvals;
+
+ nvals = getattdisbursion(relid, (int) attno);
+ if (nvals == 0)
+ *result = 1.0 / 3.0;
+ else
+ {
+ *result = 3.0 * (float64data) nvals;
+ if (*result > 1.0)
+ *result = 1;
+ }
+ }
+ else
+ {
+ bottom = high - low;
+ if (bottom == 0)
+ ++bottom;
+ if (flag & SEL_RIGHT)
+ top = val - low;
+ else
+ top = high - val;
+ if (top > bottom)
+ *result = 1.0;
+ else
+ {
+ if (top == 0)
+ ++top;
+ *result = ((1.0 * top) / bottom);
+ }
+ }
}
- }
- return(result);
+ return (result);
}
/*
- * intgtsel - Selectivity of ">" for integers.
- * Should work for both longs and shorts.
+ * intgtsel - Selectivity of ">" for integers.
+ * Should work for both longs and shorts.
*/
float64
intgtsel(Oid opid,
- Oid relid,
- AttrNumber attno,
- int32 value,
- int32 flag)
+ Oid relid,
+ AttrNumber attno,
+ int32 value,
+ int32 flag)
{
- float64 result;
- int notflag;
-
- if (flag & 0)
- notflag = flag & ~SEL_RIGHT;
- else
- notflag = flag | SEL_RIGHT;
- result = intltsel(opid, relid, attno, value, (int32) notflag);
- return(result);
+ float64 result;
+ int notflag;
+
+ if (flag & 0)
+ notflag = flag & ~SEL_RIGHT;
+ else
+ notflag = flag | SEL_RIGHT;
+ result = intltsel(opid, relid, attno, value, (int32) notflag);
+ return (result);
}
/*
- * eqjoinsel - Join selectivity of "="
+ * eqjoinsel - Join selectivity of "="
*/
float64
eqjoinsel(Oid opid,
- Oid relid1,
- AttrNumber attno1,
- Oid relid2,
- AttrNumber attno2)
+ Oid relid1,
+ AttrNumber attno1,
+ Oid relid2,
+ AttrNumber attno2)
{
- float64 result;
- float32data num1, num2, max;
-
- result = (float64) palloc(sizeof(float64data));
- if (NONVALUE(attno1) || NONVALUE(relid1) ||
- NONVALUE(attno2) || NONVALUE(relid2))
- *result = 0.1;
- else {
- num1 = getattdisbursion(relid1, (int) attno1);
- num2 = getattdisbursion(relid2, (int) attno2);
- max = (num1 > num2) ? num1 : num2;
- if (max == 0)
- *result = 1.0;
+ float64 result;
+ float32data num1,
+ num2,
+ max;
+
+ result = (float64) palloc(sizeof(float64data));
+ if (NONVALUE(attno1) || NONVALUE(relid1) ||
+ NONVALUE(attno2) || NONVALUE(relid2))
+ *result = 0.1;
else
- *result = (float64data)max;
- }
- return(result);
+ {
+ num1 = getattdisbursion(relid1, (int) attno1);
+ num2 = getattdisbursion(relid2, (int) attno2);
+ max = (num1 > num2) ? num1 : num2;
+ if (max == 0)
+ *result = 1.0;
+ else
+ *result = (float64data) max;
+ }
+ return (result);
}
/*
- * neqjoinsel - Join selectivity of "!="
+ * neqjoinsel - Join selectivity of "!="
*/
float64
neqjoinsel(Oid opid,
- Oid relid1,
- AttrNumber attno1,
- Oid relid2,
- AttrNumber attno2)
+ Oid relid1,
+ AttrNumber attno1,
+ Oid relid2,
+ AttrNumber attno2)
{
- float64 result;
-
- result = eqjoinsel(opid, relid1, attno1, relid2, attno2);
- *result = 1.0 - *result;
- return(result);
+ float64 result;
+
+ result = eqjoinsel(opid, relid1, attno1, relid2, attno2);
+ *result = 1.0 - *result;
+ return (result);
}
/*
- * intltjoinsel - Join selectivity of "<"
+ * intltjoinsel - Join selectivity of "<"
*/
float64
intltjoinsel(Oid opid,
- Oid relid1,
- AttrNumber attno1,
- Oid relid2,
- AttrNumber attno2)
+ Oid relid1,
+ AttrNumber attno1,
+ Oid relid2,
+ AttrNumber attno2)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
- *result = 1.0 / 3.0;
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+ *result = 1.0 / 3.0;
+ return (result);
}
/*
- * intgtjoinsel - Join selectivity of ">"
+ * intgtjoinsel - Join selectivity of ">"
*/
float64
intgtjoinsel(Oid opid,
- Oid relid1,
- AttrNumber attno1,
- Oid relid2,
- AttrNumber attno2)
+ Oid relid1,
+ AttrNumber attno1,
+ Oid relid2,
+ AttrNumber attno2)
{
- float64 result;
-
- result = (float64) palloc(sizeof(float64data));
- *result = 1.0 / 3.0;
- return(result);
+ float64 result;
+
+ result = (float64) palloc(sizeof(float64data));
+ *result = 1.0 / 3.0;
+ return (result);
}
/*
- * getattdisbursion - Retrieves the number of values within an attribute.
+ * getattdisbursion - Retrieves the number of values within an attribute.
*
- * Note:
- * getattdisbursion and gethilokey both currently use keyed
- * relation scans and amgetattr. Alternatively,
- * the relation scan could be non-keyed and the tuple
- * returned could be cast (struct X *) tuple + tuple->t_hoff.
- * The first method is good for testing the implementation,
- * but the second may ultimately be faster?!? In any case,
- * using the cast instead of amgetattr would be
- * more efficient. However, the cast will not work
- * for gethilokey which accesses stahikey in struct statistic.
+ * Note:
+ * getattdisbursion and gethilokey both currently use keyed
+ * relation scans and amgetattr. Alternatively,
+ * the relation scan could be non-keyed and the tuple
+ * returned could be cast (struct X *) tuple + tuple->t_hoff.
+ * The first method is good for testing the implementation,
+ * but the second may ultimately be faster?!? In any case,
+ * using the cast instead of amgetattr would be
+ * more efficient. However, the cast will not work
+ * for gethilokey which accesses stahikey in struct statistic.
*/
-static float32data
+static float32data
getattdisbursion(Oid relid, AttrNumber attnum)
{
- HeapTuple atp;
- float32data nvals;
- int32 ntuples;
-
- atp = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(relid),
- Int16GetDatum(attnum),
- 0,0);
- if (!HeapTupleIsValid(atp)) {
- elog(WARN, "getattdisbursion: no attribute tuple %d %d",
- relid, attnum);
- return(0);
- }
- nvals = ((AttributeTupleForm ) GETSTRUCT(atp))->attdisbursion;
- if (nvals > 0) return(nvals);
-
- atp = SearchSysCacheTuple(RELOID, ObjectIdGetDatum(relid),
- 0,0,0);
- /* XXX -- use number of tuples as number of distinctive values
- just for now, in case number of distinctive values is
- not cached */
- if (!HeapTupleIsValid(atp)) {
- elog(WARN, "getattdisbursion: no relation tuple %d", relid);
- return(0);
- }
- ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
- /* Look above how nvals is used. - vadim 04/09/97 */
- if ( ntuples > 0 )
- nvals = 1.0 / ntuples;
-
- return(nvals);
+ HeapTuple atp;
+ float32data nvals;
+ int32 ntuples;
+
+ atp = SearchSysCacheTuple(ATTNUM,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum),
+ 0, 0);
+ if (!HeapTupleIsValid(atp))
+ {
+ elog(WARN, "getattdisbursion: no attribute tuple %d %d",
+ relid, attnum);
+ return (0);
+ }
+ nvals = ((AttributeTupleForm) GETSTRUCT(atp))->attdisbursion;
+ if (nvals > 0)
+ return (nvals);
+
+ atp = SearchSysCacheTuple(RELOID, ObjectIdGetDatum(relid),
+ 0, 0, 0);
+
+ /*
+ * XXX -- use number of tuples as number of distinctive values just
+ * for now, in case number of distinctive values is not cached
+ */
+ if (!HeapTupleIsValid(atp))
+ {
+ elog(WARN, "getattdisbursion: no relation tuple %d", relid);
+ return (0);
+ }
+ ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
+ /* Look above how nvals is used. - vadim 04/09/97 */
+ if (ntuples > 0)
+ nvals = 1.0 / ntuples;
+
+ return (nvals);
}
/*
- * gethilokey - Returns a pointer to strings containing
- * the high and low keys within an attribute.
+ * gethilokey - Returns a pointer to strings containing
+ * the high and low keys within an attribute.
*
- * Currently returns "0", and "0" in high and low if the statistic
- * catalog does not contain the proper tuple. Eventually, the
- * statistic demon should have the tuple maintained, and it should
- * elog() if the tuple is missing.
+ * Currently returns "0", and "0" in high and low if the statistic
+ * catalog does not contain the proper tuple. Eventually, the
+ * statistic demon should have the tuple maintained, and it should
+ * elog() if the tuple is missing.
*
- * XXX Question: is this worth sticking in the catalog caches,
- * or will this get invalidated too often?
+ * XXX Question: is this worth sticking in the catalog caches,
+ * or will this get invalidated too often?
*/
static void
gethilokey(Oid relid,
- AttrNumber attnum,
- Oid opid,
- char **high,
- char **low)
+ AttrNumber attnum,
+ Oid opid,
+ char **high,
+ char **low)
{
- register Relation rdesc;
- register HeapScanDesc sdesc;
- static ScanKeyData key[3] = {
- { 0, Anum_pg_statistic_starelid, F_OIDEQ },
- { 0, Anum_pg_statistic_staattnum, F_INT2EQ },
- { 0, Anum_pg_statistic_staop, F_OIDEQ }
- };
- bool isnull;
- HeapTuple tuple;
-
- rdesc = heap_openr(StatisticRelationName);
-
- key[0].sk_argument = ObjectIdGetDatum(relid);
- key[1].sk_argument = Int16GetDatum((int16) attnum);
- key[2].sk_argument = ObjectIdGetDatum(opid);
- sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 3, key);
- tuple = heap_getnext(sdesc, 0, (Buffer *) NULL);
- if (!HeapTupleIsValid(tuple)) {
- *high = "n";
- *low = "n";
- /* XXX elog(WARN, "gethilokey: statistic tuple not found");*/
- return;
- }
- *high = textout((struct varlena *)
- heap_getattr(tuple,
- InvalidBuffer,
- Anum_pg_statistic_stahikey,
- RelationGetTupleDescriptor(rdesc),
- &isnull));
- if (isnull)
- elog(DEBUG, "gethilokey: high key is null");
- *low = textout((struct varlena *)
- heap_getattr(tuple,
- InvalidBuffer,
- Anum_pg_statistic_stalokey,
- RelationGetTupleDescriptor(rdesc),
- &isnull));
- if (isnull)
- elog(DEBUG, "gethilokey: low key is null");
- heap_endscan(sdesc);
- heap_close(rdesc);
+ register Relation rdesc;
+ register HeapScanDesc sdesc;
+ static ScanKeyData key[3] = {
+ {0, Anum_pg_statistic_starelid, F_OIDEQ},
+ {0, Anum_pg_statistic_staattnum, F_INT2EQ},
+ {0, Anum_pg_statistic_staop, F_OIDEQ}
+ };
+ bool isnull;
+ HeapTuple tuple;
+
+ rdesc = heap_openr(StatisticRelationName);
+
+ key[0].sk_argument = ObjectIdGetDatum(relid);
+ key[1].sk_argument = Int16GetDatum((int16) attnum);
+ key[2].sk_argument = ObjectIdGetDatum(opid);
+ sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 3, key);
+ tuple = heap_getnext(sdesc, 0, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ *high = "n";
+ *low = "n";
+
+ /*
+ * XXX elog(WARN, "gethilokey: statistic tuple not
+ * found");
+ */
+ return;
+ }
+ *high = textout((struct varlena *)
+ heap_getattr(tuple,
+ InvalidBuffer,
+ Anum_pg_statistic_stahikey,
+ RelationGetTupleDescriptor(rdesc),
+ &isnull));
+ if (isnull)
+ elog(DEBUG, "gethilokey: high key is null");
+ *low = textout((struct varlena *)
+ heap_getattr(tuple,
+ InvalidBuffer,
+ Anum_pg_statistic_stalokey,
+ RelationGetTupleDescriptor(rdesc),
+ &isnull));
+ if (isnull)
+ elog(DEBUG, "gethilokey: low key is null");
+ heap_endscan(sdesc);
+ heap_close(rdesc);
}
float64
btreesel(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+ Oid indrelid,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag,
+ int32 nIndexKeys,
+ Oid indexrelid)
{
- float64 result;
- float64data resultData;
-
- if (FunctionalSelectivity(nIndexKeys, attributeNumber)) {
- /*
- * Need to call the functions selectivity
- * function here. For now simply assume it's
- * 1/3 since functions don't currently
- * have selectivity functions
- */
- resultData = 1.0 / 3.0;
- result = &resultData;
- }
- else {
- result = (float64)fmgr(get_oprrest (operatorObjectId),
- (char*)operatorObjectId,
- (char*)indrelid,
- (char*)(int)attributeNumber,
- (char*)constValue,
- (char*)constFlag,
- NULL);
- }
-
- if (!PointerIsValid(result))
- elog(WARN, "Btree Selectivity: bad pointer");
- if (*result < 0.0 || *result > 1.0)
- elog(WARN, "Btree Selectivity: bad value %lf", *result);
-
- return(result);
+ float64 result;
+ float64data resultData;
+
+ if (FunctionalSelectivity(nIndexKeys, attributeNumber))
+ {
+
+ /*
+ * Need to call the functions selectivity function here. For now
+ * simply assume it's 1/3 since functions don't currently have
+ * selectivity functions
+ */
+ resultData = 1.0 / 3.0;
+ result = &resultData;
+ }
+ else
+ {
+ result = (float64) fmgr(get_oprrest(operatorObjectId),
+ (char *) operatorObjectId,
+ (char *) indrelid,
+ (char *) (int) attributeNumber,
+ (char *) constValue,
+ (char *) constFlag,
+ NULL);
+ }
+
+ if (!PointerIsValid(result))
+ elog(WARN, "Btree Selectivity: bad pointer");
+ if (*result < 0.0 || *result > 1.0)
+ elog(WARN, "Btree Selectivity: bad value %lf", *result);
+
+ return (result);
}
float64
btreenpage(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+ Oid indrelid,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag,
+ int32 nIndexKeys,
+ Oid indexrelid)
{
- float64 temp, result;
- float64data tempData;
- HeapTuple atp;
- int npage;
-
- if (FunctionalSelectivity(nIndexKeys, attributeNumber)) {
- /*
- * Need to call the functions selectivity
- * function here. For now simply assume it's
- * 1/3 since functions don't currently
- * have selectivity functions
- */
- tempData = 1.0 / 3.0;
- temp = &tempData;
- }
- else {
- temp = (float64)fmgr(get_oprrest (operatorObjectId),
- (char*)operatorObjectId,
- (char*)indrelid,
- (char*)(int)attributeNumber,
- (char*)constValue,
- (char*)constFlag,
- NULL);
- }
- atp = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(indexrelid),
- 0,0,0);
- if (!HeapTupleIsValid(atp)) {
- elog(WARN, "btreenpage: no index tuple %d", indexrelid);
- return(0);
- }
-
- npage = ((Form_pg_class) GETSTRUCT(atp))->relpages;
- result = (float64)palloc(sizeof(float64data));
- *result = *temp * npage;
- return(result);
+ float64 temp,
+ result;
+ float64data tempData;
+ HeapTuple atp;
+ int npage;
+
+ if (FunctionalSelectivity(nIndexKeys, attributeNumber))
+ {
+
+ /*
+ * Need to call the functions selectivity function here. For now
+ * simply assume it's 1/3 since functions don't currently have
+ * selectivity functions
+ */
+ tempData = 1.0 / 3.0;
+ temp = &tempData;
+ }
+ else
+ {
+ temp = (float64) fmgr(get_oprrest(operatorObjectId),
+ (char *) operatorObjectId,
+ (char *) indrelid,
+ (char *) (int) attributeNumber,
+ (char *) constValue,
+ (char *) constFlag,
+ NULL);
+ }
+ atp = SearchSysCacheTuple(RELOID,
+ ObjectIdGetDatum(indexrelid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(atp))
+ {
+ elog(WARN, "btreenpage: no index tuple %d", indexrelid);
+ return (0);
+ }
+
+ npage = ((Form_pg_class) GETSTRUCT(atp))->relpages;
+ result = (float64) palloc(sizeof(float64data));
+ *result = *temp * npage;
+ return (result);
}
float64
hashsel(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+ Oid indrelid,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag,
+ int32 nIndexKeys,
+ Oid indexrelid)
{
-
- float64 result;
- float64data resultData;
- HeapTuple atp;
- int ntuples;
-
- if (FunctionalSelectivity(nIndexKeys, attributeNumber)) {
- /*
- * Need to call the functions selectivity
- * function here. For now simply use 1/Number of Tuples
- * since functions don't currently
- * have selectivity functions
- */
-
- atp = SearchSysCacheTuple(RELOID, ObjectIdGetDatum(indexrelid),
- 0,0,0);
- if (!HeapTupleIsValid(atp)) {
- elog(WARN, "hashsel: no index tuple %d", indexrelid);
- return(0);
- }
- ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
- if (ntuples > 0) {
- resultData = 1.0 / (float64data) ntuples;
+
+ float64 result;
+ float64data resultData;
+ HeapTuple atp;
+ int ntuples;
+
+ if (FunctionalSelectivity(nIndexKeys, attributeNumber))
+ {
+
+ /*
+ * Need to call the functions selectivity function here. For now
+ * simply use 1/Number of Tuples since functions don't currently
+ * have selectivity functions
+ */
+
+ atp = SearchSysCacheTuple(RELOID, ObjectIdGetDatum(indexrelid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(atp))
+ {
+ elog(WARN, "hashsel: no index tuple %d", indexrelid);
+ return (0);
+ }
+ ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
+ if (ntuples > 0)
+ {
+ resultData = 1.0 / (float64data) ntuples;
+ }
+ else
+ {
+ resultData = (float64data) (1.0 / 100.0);
+ }
+ result = &resultData;
+
}
- else {
- resultData = (float64data) (1.0 / 100.0);
+ else
+ {
+ result = (float64) fmgr(get_oprrest(operatorObjectId),
+ (char *) operatorObjectId,
+ (char *) indrelid,
+ (char *) (int) attributeNumber,
+ (char *) constValue,
+ (char *) constFlag,
+ NULL);
}
- result = &resultData;
-
- }
- else {
- result = (float64)fmgr(get_oprrest (operatorObjectId),
- (char*)operatorObjectId,
- (char*)indrelid,
- (char*)(int)attributeNumber,
- (char*)constValue,
- (char*)constFlag,
- NULL);
- }
-
- if (!PointerIsValid(result))
- elog(WARN, "Hash Table Selectivity: bad pointer");
- if (*result < 0.0 || *result > 1.0)
- elog(WARN, "Hash Table Selectivity: bad value %lf", *result);
-
- return(result);
-
-
+
+ if (!PointerIsValid(result))
+ elog(WARN, "Hash Table Selectivity: bad pointer");
+ if (*result < 0.0 || *result > 1.0)
+ elog(WARN, "Hash Table Selectivity: bad value %lf", *result);
+
+ return (result);
+
+
}
float64
hashnpage(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+ Oid indrelid,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag,
+ int32 nIndexKeys,
+ Oid indexrelid)
{
- float64 temp, result;
- float64data tempData;
- HeapTuple atp;
- int npage;
- int ntuples;
-
- atp = SearchSysCacheTuple(RELOID, ObjectIdGetDatum(indexrelid),
- 0,0,0);
- if (!HeapTupleIsValid(atp)) {
- elog(WARN, "hashsel: no index tuple %d", indexrelid);
- return(0);
- }
-
-
- if (FunctionalSelectivity(nIndexKeys, attributeNumber)) {
- /*
- * Need to call the functions selectivity
- * function here. For now, use 1/Number of Tuples
- * since functions don't currently
- * have selectivity functions
- */
-
- ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
- if (ntuples > 0) {
- tempData = 1.0 / (float64data) ntuples;
+ float64 temp,
+ result;
+ float64data tempData;
+ HeapTuple atp;
+ int npage;
+ int ntuples;
+
+ atp = SearchSysCacheTuple(RELOID, ObjectIdGetDatum(indexrelid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(atp))
+ {
+ elog(WARN, "hashsel: no index tuple %d", indexrelid);
+ return (0);
+ }
+
+
+ if (FunctionalSelectivity(nIndexKeys, attributeNumber))
+ {
+
+ /*
+ * Need to call the functions selectivity function here. For now,
+ * use 1/Number of Tuples since functions don't currently have
+ * selectivity functions
+ */
+
+ ntuples = ((Form_pg_class) GETSTRUCT(atp))->reltuples;
+ if (ntuples > 0)
+ {
+ tempData = 1.0 / (float64data) ntuples;
+ }
+ else
+ {
+ tempData = (float64data) (1.0 / 100.0);
+ }
+ temp = &tempData;
+
}
- else {
- tempData = (float64data) (1.0 / 100.0);
+ else
+ {
+ temp = (float64) fmgr(get_oprrest(operatorObjectId),
+ (char *) operatorObjectId,
+ (char *) indrelid,
+ (char *) (int) attributeNumber,
+ (char *) constValue,
+ (char *) constFlag,
+ NULL);
}
- temp = &tempData;
-
- }
- else {
- temp = (float64)fmgr(get_oprrest (operatorObjectId),
- (char*)operatorObjectId,
- (char*)indrelid,
- (char*)(int)attributeNumber,
- (char*)constValue,
- (char*)constFlag,
- NULL);
- }
-
- npage = ((Form_pg_class) GETSTRUCT(atp))->relpages;
- result = (float64)palloc(sizeof(float64data));
- *result = *temp * npage;
- return(result);
+
+ npage = ((Form_pg_class) GETSTRUCT(atp))->relpages;
+ result = (float64) palloc(sizeof(float64data));
+ *result = *temp * npage;
+ return (result);
}
float64
rtsel(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+ Oid indrelid,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag,
+ int32 nIndexKeys,
+ Oid indexrelid)
{
- return (btreesel(operatorObjectId, indrelid, attributeNumber,
- constValue, constFlag, nIndexKeys, indexrelid));
+ return (btreesel(operatorObjectId, indrelid, attributeNumber,
+ constValue, constFlag, nIndexKeys, indexrelid));
}
float64
rtnpage(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+ Oid indrelid,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag,
+ int32 nIndexKeys,
+ Oid indexrelid)
{
- return (btreenpage(operatorObjectId, indrelid, attributeNumber,
- constValue, constFlag, nIndexKeys, indexrelid));
+ return (btreenpage(operatorObjectId, indrelid, attributeNumber,
+ constValue, constFlag, nIndexKeys, indexrelid));
}
float64
gistsel(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+ Oid indrelid,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag,
+ int32 nIndexKeys,
+ Oid indexrelid)
{
- return (btreesel(operatorObjectId, indrelid, attributeNumber,
- constValue, constFlag, nIndexKeys, indexrelid));
+ return (btreesel(operatorObjectId, indrelid, attributeNumber,
+ constValue, constFlag, nIndexKeys, indexrelid));
}
float64
gistnpage(Oid operatorObjectId,
- Oid indrelid,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag,
- int32 nIndexKeys,
- Oid indexrelid)
+ Oid indrelid,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag,
+ int32 nIndexKeys,
+ Oid indexrelid)
{
- return (btreenpage(operatorObjectId, indrelid, attributeNumber,
- constValue, constFlag, nIndexKeys, indexrelid));
+ return (btreenpage(operatorObjectId, indrelid, attributeNumber,
+ constValue, constFlag, nIndexKeys, indexrelid));
}
diff --git a/src/backend/utils/adt/sets.c b/src/backend/utils/adt/sets.c
index 55ca1f4b643..72f0a615a66 100644
--- a/src/backend/utils/adt/sets.c
+++ b/src/backend/utils/adt/sets.c
@@ -1,163 +1,173 @@
/*-------------------------------------------------------------------------
*
* sets.c--
- * Functions for sets, which are defined by queries.
- * Example: a set is defined as being the result of the query
- * retrieve (X.all)
+ * Functions for sets, which are defined by queries.
+ * Example: a set is defined as being the result of the query
+ * retrieve (X.all)
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.5 1997/08/12 22:54:38 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.6 1997/09/07 04:50:43 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include "postgres.h"
#include "access/heapam.h"
#include "access/relscan.h"
#include "access/xact.h"
-#include "catalog/pg_proc.h" /* for Form_pg_proc */
-#include "utils/syscache.h" /* for PROOID */
-#include "catalog/catname.h" /* for ProcedureRelationName */
-#include "catalog/indexing.h" /* for Num_pg_proc_indices */
+#include "catalog/pg_proc.h" /* for Form_pg_proc */
+#include "utils/syscache.h" /* for PROOID */
+#include "catalog/catname.h" /* for ProcedureRelationName */
+#include "catalog/indexing.h" /* for Num_pg_proc_indices */
#include "storage/lmgr.h"
-#include "utils/sets.h" /* for GENERICSETNAME */
+#include "utils/sets.h" /* for GENERICSETNAME */
#include "tcop/dest.h"
#include "fmgr.h"
-extern CommandDest whereToSendOutput; /* defined in tcop/postgres.c */
+extern CommandDest whereToSendOutput; /* defined in tcop/postgres.c */
/*
- * SetDefine - converts query string defining set to an oid
+ * SetDefine - converts query string defining set to an oid
*
- * The query string is used to store the set as a function in
- * pg_proc. The name of the function is then changed to use the
- * OID of its tuple in pg_proc.
+ * The query string is used to store the set as a function in
+ * pg_proc. The name of the function is then changed to use the
+ * OID of its tuple in pg_proc.
*/
Oid
SetDefine(char *querystr, char *typename)
{
- Oid setoid;
- char *procname = GENERICSETNAME;
- char *fileName = "-";
- char realprocname[16];
- HeapTuple tup, newtup = NULL;
- Form_pg_proc proc;
- Relation procrel;
- int i;
- Datum replValue[Natts_pg_proc];
- char replNull[Natts_pg_proc];
- char repl[Natts_pg_proc];
- HeapScanDesc pg_proc_scan;
- Buffer buffer;
- ItemPointerData ipdata;
-
- static ScanKeyData oidKey[1] = {
- { 0, ObjectIdAttributeNumber, ObjectIdEqualRegProcedure }};
-
-
- setoid = ProcedureCreate(procname, /* changed below, after oid known */
- true, /* returnsSet */
- typename, /* returnTypeName */
- "sql", /* languageName */
- querystr, /* sourceCode */
- fileName, /* fileName */
- false, /* canCache */
- true, /* trusted */
- 100, /* byte_pct */
- 0, /* perbyte_cpu */
- 0, /* percall_cpu */
- 100, /* outin_ratio */
- NIL, /* argList */
- whereToSendOutput);
- /* Since we're still inside this command of the transaction, we can't
- * see the results of the procedure definition unless we pretend
- * we've started the next command. (Postgres's solution to the
- * Halloween problem is to not allow you to see the results of your
- * command until you start the next command.)
- */
- CommandCounterIncrement();
- tup = SearchSysCacheTuple(PROOID,
- ObjectIdGetDatum(setoid),
- 0,0,0);
- if (!HeapTupleIsValid(tup))
- elog(WARN, "setin: unable to define set %s", querystr);
-
- /* We can tell whether the set was already defined by checking
- * the name. If it's GENERICSETNAME, the set is new. If it's
- * "set<some oid>" it's already defined.
- */
- proc = (Form_pg_proc)GETSTRUCT(tup);
- if (!strcmp((char*)procname, (char*)&(proc->proname))) {
- /* make the real proc name */
- sprintf(realprocname, "set%u", setoid);
-
- /* set up the attributes to be modified or kept the same */
- repl[0] = 'r';
- for (i = 1; i < Natts_pg_proc; i++) repl[i] = ' ';
- replValue[0] = (Datum)realprocname;
- for (i = 1; i < Natts_pg_proc; i++) replValue[i] = (Datum)0;
- for (i = 0; i < Natts_pg_proc; i++) replNull[i] = ' ';
-
- /* change the pg_proc tuple */
- procrel = heap_openr(ProcedureRelationName);
- RelationSetLockForWrite(procrel);
- fmgr_info(ObjectIdEqualRegProcedure,
- &oidKey[0].sk_func,
- &oidKey[0].sk_nargs);
- oidKey[0].sk_argument = ObjectIdGetDatum(setoid);
- pg_proc_scan = heap_beginscan(procrel,
- 0,
- SelfTimeQual,
- 1,
- oidKey);
- tup = heap_getnext(pg_proc_scan, 0, &buffer);
- if (HeapTupleIsValid(tup)) {
- newtup = heap_modifytuple(tup,
- buffer,
- procrel,
- replValue,
- replNull,
- repl);
-
- /* XXX may not be necessary */
- ItemPointerCopy(&tup->t_ctid, &ipdata);
-
- setheapoverride(true);
- heap_replace(procrel, &ipdata, newtup);
- setheapoverride(false);
-
- setoid = newtup->t_oid;
- } else
- elog(WARN, "setin: could not find new set oid tuple");
- heap_endscan(pg_proc_scan);
-
- if (RelationGetRelationTupleForm(procrel)->relhasindex)
- {
- Relation idescs[Num_pg_proc_indices];
-
- CatalogOpenIndices(Num_pg_proc_indices, Name_pg_proc_indices, idescs);
- CatalogIndexInsert(idescs, Num_pg_proc_indices, procrel, newtup);
- CatalogCloseIndices(Num_pg_proc_indices, idescs);
- }
- RelationUnsetLockForWrite(procrel);
- heap_close(procrel);
- }
- return setoid;
+ Oid setoid;
+ char *procname = GENERICSETNAME;
+ char *fileName = "-";
+ char realprocname[16];
+ HeapTuple tup,
+ newtup = NULL;
+ Form_pg_proc proc;
+ Relation procrel;
+ int i;
+ Datum replValue[Natts_pg_proc];
+ char replNull[Natts_pg_proc];
+ char repl[Natts_pg_proc];
+ HeapScanDesc pg_proc_scan;
+ Buffer buffer;
+ ItemPointerData ipdata;
+
+ static ScanKeyData oidKey[1] = {
+ {0, ObjectIdAttributeNumber, ObjectIdEqualRegProcedure}};
+
+
+ setoid = ProcedureCreate(procname, /* changed below, after oid known */
+ true, /* returnsSet */
+ typename, /* returnTypeName */
+ "sql", /* languageName */
+ querystr, /* sourceCode */
+ fileName, /* fileName */
+ false, /* canCache */
+ true, /* trusted */
+ 100, /* byte_pct */
+ 0, /* perbyte_cpu */
+ 0, /* percall_cpu */
+ 100, /* outin_ratio */
+ NIL, /* argList */
+ whereToSendOutput);
+
+ /*
+ * Since we're still inside this command of the transaction, we can't
+ * see the results of the procedure definition unless we pretend we've
+ * started the next command. (Postgres's solution to the Halloween
+ * problem is to not allow you to see the results of your command
+ * until you start the next command.)
+ */
+ CommandCounterIncrement();
+ tup = SearchSysCacheTuple(PROOID,
+ ObjectIdGetDatum(setoid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(WARN, "setin: unable to define set %s", querystr);
+
+ /*
+ * We can tell whether the set was already defined by checking the
+ * name. If it's GENERICSETNAME, the set is new. If it's "set<some
+ * oid>" it's already defined.
+ */
+ proc = (Form_pg_proc) GETSTRUCT(tup);
+ if (!strcmp((char *) procname, (char *) &(proc->proname)))
+ {
+ /* make the real proc name */
+ sprintf(realprocname, "set%u", setoid);
+
+ /* set up the attributes to be modified or kept the same */
+ repl[0] = 'r';
+ for (i = 1; i < Natts_pg_proc; i++)
+ repl[i] = ' ';
+ replValue[0] = (Datum) realprocname;
+ for (i = 1; i < Natts_pg_proc; i++)
+ replValue[i] = (Datum) 0;
+ for (i = 0; i < Natts_pg_proc; i++)
+ replNull[i] = ' ';
+
+ /* change the pg_proc tuple */
+ procrel = heap_openr(ProcedureRelationName);
+ RelationSetLockForWrite(procrel);
+ fmgr_info(ObjectIdEqualRegProcedure,
+ &oidKey[0].sk_func,
+ &oidKey[0].sk_nargs);
+ oidKey[0].sk_argument = ObjectIdGetDatum(setoid);
+ pg_proc_scan = heap_beginscan(procrel,
+ 0,
+ SelfTimeQual,
+ 1,
+ oidKey);
+ tup = heap_getnext(pg_proc_scan, 0, &buffer);
+ if (HeapTupleIsValid(tup))
+ {
+ newtup = heap_modifytuple(tup,
+ buffer,
+ procrel,
+ replValue,
+ replNull,
+ repl);
+
+ /* XXX may not be necessary */
+ ItemPointerCopy(&tup->t_ctid, &ipdata);
+
+ setheapoverride(true);
+ heap_replace(procrel, &ipdata, newtup);
+ setheapoverride(false);
+
+ setoid = newtup->t_oid;
+ }
+ else
+ elog(WARN, "setin: could not find new set oid tuple");
+ heap_endscan(pg_proc_scan);
+
+ if (RelationGetRelationTupleForm(procrel)->relhasindex)
+ {
+ Relation idescs[Num_pg_proc_indices];
+
+ CatalogOpenIndices(Num_pg_proc_indices, Name_pg_proc_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_proc_indices, procrel, newtup);
+ CatalogCloseIndices(Num_pg_proc_indices, idescs);
+ }
+ RelationUnsetLockForWrite(procrel);
+ heap_close(procrel);
+ }
+ return setoid;
}
-/* This function is a placeholder. The parser uses the OID of this
+/* This function is a placeholder. The parser uses the OID of this
* function to fill in the :funcid field of a set. This routine is
- * never executed. At runtime, the OID of the actual set is substituted
+ * never executed. At runtime, the OID of the actual set is substituted
* into the :funcid.
*/
int
seteval(Oid funcoid)
{
- return 17;
+ return 17;
}
diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c
index 6fb4e589ad8..fe10f2b58e3 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -1,89 +1,90 @@
/*-------------------------------------------------------------------------
*
* tid.c--
- * Functions for the built-in type tuple id
+ * Functions for the built-in type tuple id
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.2 1996/11/06 06:50:05 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.3 1997/09/07 04:50:46 momjian Exp $
*
* NOTES
- * input routine largely stolen from boxin().
+ * input routine largely stolen from boxin().
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include "postgres.h"
#include "storage/bufpage.h"
#include "utils/palloc.h"
-#include "utils/builtins.h" /* where function declarations go */
+#include "utils/builtins.h" /* where function declarations go */
-#define LDELIM '('
-#define RDELIM ')'
-#define DELIM ','
-#define NTIDARGS 2
+#define LDELIM '('
+#define RDELIM ')'
+#define DELIM ','
+#define NTIDARGS 2
/* ----------------------------------------------------------------
- * tidin
+ * tidin
* ----------------------------------------------------------------
*/
ItemPointer
tidin(char *str)
{
- char *p, *coord[NTIDARGS];
- int i;
- ItemPointer result;
-
- BlockNumber blockNumber;
- OffsetNumber offsetNumber;
-
- if (str == NULL)
- return NULL;
-
- for (i = 0, p = str; *p && i < NTIDARGS && *p != RDELIM; p++)
- if (*p == DELIM || (*p == LDELIM && !i))
- coord[i++] = p + 1;
-
- if (i < NTIDARGS - 1)
- return NULL;
-
- blockNumber = (BlockNumber) atoi(coord[0]);
- offsetNumber = (OffsetNumber) atoi(coord[1]);
-
- result = (ItemPointer) palloc(sizeof(ItemPointerData));
-
- ItemPointerSet(result, blockNumber, offsetNumber);
-
- return result;
+ char *p,
+ *coord[NTIDARGS];
+ int i;
+ ItemPointer result;
+
+ BlockNumber blockNumber;
+ OffsetNumber offsetNumber;
+
+ if (str == NULL)
+ return NULL;
+
+ for (i = 0, p = str; *p && i < NTIDARGS && *p != RDELIM; p++)
+ if (*p == DELIM || (*p == LDELIM && !i))
+ coord[i++] = p + 1;
+
+ if (i < NTIDARGS - 1)
+ return NULL;
+
+ blockNumber = (BlockNumber) atoi(coord[0]);
+ offsetNumber = (OffsetNumber) atoi(coord[1]);
+
+ result = (ItemPointer) palloc(sizeof(ItemPointerData));
+
+ ItemPointerSet(result, blockNumber, offsetNumber);
+
+ return result;
}
/* ----------------------------------------------------------------
- * tidout
+ * tidout
* ----------------------------------------------------------------
*/
-char *
+char *
tidout(ItemPointer itemPtr)
{
- BlockNumber blockNumber;
- OffsetNumber offsetNumber;
- BlockId blockId;
- char buf[32];
- char *str;
-
- blockId = &(itemPtr->ip_blkid);
-
- blockNumber = BlockIdGetBlockNumber(blockId);
- offsetNumber = itemPtr->ip_posid;
-
- sprintf(buf, "(%d,%d)", blockNumber, offsetNumber);
-
- str = (char *) palloc(strlen(buf)+1);
- strcpy(str, buf);
-
- return str;
+ BlockNumber blockNumber;
+ OffsetNumber offsetNumber;
+ BlockId blockId;
+ char buf[32];
+ char *str;
+
+ blockId = &(itemPtr->ip_blkid);
+
+ blockNumber = BlockIdGetBlockNumber(blockId);
+ offsetNumber = itemPtr->ip_posid;
+
+ sprintf(buf, "(%d,%d)", blockNumber, offsetNumber);
+
+ str = (char *) palloc(strlen(buf) + 1);
+ strcpy(str, buf);
+
+ return str;
}
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 4d3a8f9af21..d9ed6d299c5 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -16,7 +16,7 @@
static const char *
cpstr(const char *s, char *buf)
{
- char in = 0;
+ char in = 0;
while (isspace(*s))
s++;
@@ -26,7 +26,7 @@ cpstr(const char *s, char *buf)
if (strchr("-,:/", *s))
{
buf[in] = 0;
- return(s + 1);
+ return (s + 1);
}
if (in < 16)
@@ -36,72 +36,76 @@ cpstr(const char *s, char *buf)
buf[in] = 0;
return s;
}
+
#endif
/* assumes dd/mm/yyyy unless first item is month in word form */
time_t
timestamp_in(const char *timestamp_str)
{
- int4 result;
+ int4 result;
#if FALSE
- struct tm input_time;
- char buf[18];
- const char *p;
+ struct tm input_time;
+ char buf[18];
+ const char *p;
static const char *mstr[] = {
"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december"
};
- memset(&input_time, 0, sizeof(input_time));
+ memset(&input_time, 0, sizeof(input_time));
p = cpstr(timestamp_str, buf);
- if (isdigit(buf[0])) /* must be dd/mm/yyyy */
+ if (isdigit(buf[0])) /* must be dd/mm/yyyy */
{
input_time.tm_mday = atoi(buf);
p = cpstr(p, buf);
if (!buf[0])
elog(WARN, "timestamp_in: timestamp \"%s\" not a proper date",
- timestamp_str);
+ timestamp_str);
if (isdigit(buf[0]))
{
input_time.tm_mon = atoi(buf) - 1;
if (input_time.tm_mon < 0 || input_time.tm_mon > 11)
elog(WARN, "timestamp_in: timestamp \"%s\" invalid month",
- timestamp_str);
+ timestamp_str);
}
else
{
- int i;
+ int i;
+
for (i = 0; i < 12; i++)
if (strncmp(mstr[i], buf, strlen(buf)) == 0)
break;
if (1 > 11)
elog(WARN, "timestamp_in: timestamp \"%s\" invalid month",
- timestamp_str);
+ timestamp_str);
input_time.tm_mon = i;
}
}
- else /* must be month/dd/yyyy */
+ else
+/* must be month/dd/yyyy */
{
- int i;
+ int i;
+
for (i = 0; i < 12; i++)
if (strncmp(mstr[i], buf, strlen(buf)) == 0)
break;
if (1 > 11)
elog(WARN, "timestamp_in: timestamp \"%s\" invalid month",
- timestamp_str);
+ timestamp_str);
input_time.tm_mon = i;
p = cpstr(p, buf);
input_time.tm_mday = atoi(buf);
if (!input_time.tm_mday || input_time.tm_mday > 31)
elog(WARN, "timestamp_in: timestamp \"%s\" not a proper date",
- timestamp_str);
- }
+ timestamp_str);
+ }
p = cpstr(p, buf);
if (!buf[0] || !isdigit(buf[0]))
elog(WARN, "timestamp_in: timestamp \"%s\" not a proper date",
- timestamp_str);
+ timestamp_str);
if ((input_time.tm_year = atoi(buf)) < 1900)
input_time.tm_year += 1900;
@@ -113,102 +117,104 @@ timestamp_in(const char *timestamp_str)
p = cpstr(p, buf);
input_time.tm_sec = atoi(buf);
- /* use mktime(), but make this GMT, not local time */
- result = mktime(&input_time);
+ /* use mktime(), but make this GMT, not local time */
+ result = mktime(&input_time);
#endif
- result = nabstimein( (char *) timestamp_str);
+ result = nabstimein((char *) timestamp_str);
- return result;
+ return result;
}
-char *
+char *
timestamp_out(time_t timestamp)
{
- char *result;
- int tz;
- double fsec = 0;
- struct tm tt, *tm = &tt;
- char buf[MAXDATELEN+1];
- char zone[MAXDATELEN+1], *tzn = zone;
+ char *result;
+ int tz;
+ double fsec = 0;
+ struct tm tt,
+ *tm = &tt;
+ char buf[MAXDATELEN + 1];
+ char zone[MAXDATELEN + 1],
+ *tzn = zone;
#if FALSE
- time = localtime(&timestamp);
+ time = localtime(&timestamp);
- sprintf(result, "%04d-%02d-%02d %02d:%02d:%02d",
- time->tm_year+1900, time->tm_mon+1, time->tm_mday,
- time->tm_hour, time->tm_min, time->tm_sec);
+ sprintf(result, "%04d-%02d-%02d %02d:%02d:%02d",
+ time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
+ time->tm_hour, time->tm_min, time->tm_sec);
#endif
- abstime2tm( timestamp, &tz, tm, tzn);
- EncodeDateTime( tm, fsec, &tz, &tzn, USE_ISO_DATES, buf);
+ abstime2tm(timestamp, &tz, tm, tzn);
+ EncodeDateTime(tm, fsec, &tz, &tzn, USE_ISO_DATES, buf);
- result = palloc(strlen(buf)+1);
- strcpy( result, buf);
- return result;
+ result = palloc(strlen(buf) + 1);
+ strcpy(result, buf);
+ return result;
}
time_t
now(void)
{
- time_t sec;
+ time_t sec;
- time(&sec);
- return(sec);
+ time(&sec);
+ return (sec);
}
bool
timestampeq(time_t t1, time_t t2)
{
- return difftime(t1, t2) == 0;
+ return difftime(t1, t2) == 0;
}
bool
timestampne(time_t t1, time_t t2)
{
- return difftime(t1, t2) != 0;
+ return difftime(t1, t2) != 0;
}
bool
timestamplt(time_t t1, time_t t2)
{
- return difftime(t1, t2) > 0;
+ return difftime(t1, t2) > 0;
}
bool
timestampgt(time_t t1, time_t t2)
{
- return difftime(t1, t2) < 0;
+ return difftime(t1, t2) < 0;
}
bool
timestample(time_t t1, time_t t2)
{
- return difftime(t1, t2) >= 0;
+ return difftime(t1, t2) >= 0;
}
bool
timestampge(time_t t1, time_t t2)
{
- return difftime(t1, t2) <= 0;
+ return difftime(t1, t2) <= 0;
}
-DateTime *
+DateTime *
timestamp_datetime(time_t timestamp)
{
- DateTime *result;
+ DateTime *result;
- double fsec = 0;
- struct tm *tm;
+ double fsec = 0;
+ struct tm *tm;
- if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
- elog(WARN,"Memory allocation failed, can't convert timestamp to datetime",NULL);
+ if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
+ elog(WARN, "Memory allocation failed, can't convert timestamp to datetime", NULL);
- tm = localtime((time_t *) &timestamp);
- tm->tm_year += 1900;
- tm->tm_mon += 1;
+ tm = localtime((time_t *) & timestamp);
+ tm->tm_year += 1900;
+ tm->tm_mon += 1;
- if (tm2datetime(tm, fsec, NULL, result) != 0)
- elog(WARN,"Unable to convert timestamp to datetime",timestamp_out(timestamp));
+ if (tm2datetime(tm, fsec, NULL, result) != 0)
+ elog(WARN, "Unable to convert timestamp to datetime", timestamp_out(timestamp));
- return(result);
-} /* timestamp_datetime() */
+ return (result);
+} /* timestamp_datetime() */
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 538063c6225..106ff5dad26 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* varchar.c--
- * Functions for the built-in type char() and varchar().
+ * Functions for the built-in type char() and varchar().
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.8 1997/08/12 20:16:07 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.9 1997/09/07 04:52:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <string.h>
#include "postgres.h"
#include "utils/builtins.h"
@@ -35,488 +35,524 @@
* the length for the comparison functions. (The difference between "text"
* is that we truncate and possibly blank-pad the string at insertion time.)
*
- * - ay 6/95
+ * - ay 6/95
*/
-/*****************************************************************************
- * bpchar - char() *
+/*****************************************************************************
+ * bpchar - char() *
*****************************************************************************/
/*
* bpcharin -
- * converts a string of char() type to the internal representation.
- * len is the length specified in () plus 4 bytes. (XXX dummy is here
- * because we pass typelem as the second argument for array_in.)
+ * converts a string of char() type to the internal representation.
+ * len is the length specified in () plus 4 bytes. (XXX dummy is here
+ * because we pass typelem as the second argument for array_in.)
*/
-char *
+char *
bpcharin(char *s, int dummy, int typlen)
{
- char *result, *r;
- int len = typlen - 4;
- int i;
-
- if (s == NULL)
- return((char *) NULL);
-
- if (typlen == -1) {
- /*
- * this is here because some functions can't supply the typlen
- */
- len = strlen(s);
- typlen = len + 4;
- }
-
- if (len > 4096)
- elog(WARN, "bpcharin: length of char() must be less than 4096");
-
- result = (char *) palloc(typlen);
- *(int32*)result = typlen;
- r = result + 4;
- for(i=0; i < len; i++, r++, s++) {
- *r = *s;
- if (*r == '\0')
- break;
- }
- /* blank pad the string if necessary */
- for(; i < len; i++) {
- *r++ = ' ';
- }
- return(result);
+ char *result,
+ *r;
+ int len = typlen - 4;
+ int i;
+
+ if (s == NULL)
+ return ((char *) NULL);
+
+ if (typlen == -1)
+ {
+
+ /*
+ * this is here because some functions can't supply the typlen
+ */
+ len = strlen(s);
+ typlen = len + 4;
+ }
+
+ if (len > 4096)
+ elog(WARN, "bpcharin: length of char() must be less than 4096");
+
+ result = (char *) palloc(typlen);
+ *(int32 *) result = typlen;
+ r = result + 4;
+ for (i = 0; i < len; i++, r++, s++)
+ {
+ *r = *s;
+ if (*r == '\0')
+ break;
+ }
+ /* blank pad the string if necessary */
+ for (; i < len; i++)
+ {
+ *r++ = ' ';
+ }
+ return (result);
}
-char *
+char *
bpcharout(char *s)
{
- char *result;
- int len;
-
- if (s == NULL) {
- result = (char *) palloc(2);
- result[0] = '-';
- result[1] = '\0';
- } else {
- len = *(int32*)s - 4;
- result = (char *) palloc(len+1);
- strNcpy(result, s+4, len); /* these are blank-padded */
- }
- return(result);
+ char *result;
+ int len;
+
+ if (s == NULL)
+ {
+ result = (char *) palloc(2);
+ result[0] = '-';
+ result[1] = '\0';
+ }
+ else
+ {
+ len = *(int32 *) s - 4;
+ result = (char *) palloc(len + 1);
+ strNcpy(result, s + 4, len); /* these are blank-padded */
+ }
+ return (result);
}
-/*****************************************************************************
- * varchar - varchar() *
+/*****************************************************************************
+ * varchar - varchar() *
*****************************************************************************/
/*
* vcharin -
- * converts a string of varchar() type to the internal representation.
- * len is the length specified in () plus 4 bytes. (XXX dummy is here
- * because we pass typelem as the second argument for array_in.)
+ * converts a string of varchar() type to the internal representation.
+ * len is the length specified in () plus 4 bytes. (XXX dummy is here
+ * because we pass typelem as the second argument for array_in.)
*/
-char *
+char *
varcharin(char *s, int dummy, int typlen)
{
- char *result;
- int len = typlen - 4;
-
- if (s == NULL)
- return((char *) NULL);
-
- if (typlen == -1) {
- /*
- * this is here because some functions can't supply the typlen
- */
- len = strlen(s);
- typlen = len + 4;
- }
-
- if (len > 4096)
- elog(WARN, "varcharin: length of char() must be less than 4096");
-
- result = (char *) palloc(typlen);
- *(int32*)result = typlen;
- strncpy(result+4, s, len);
-
- return(result);
+ char *result;
+ int len = typlen - 4;
+
+ if (s == NULL)
+ return ((char *) NULL);
+
+ if (typlen == -1)
+ {
+
+ /*
+ * this is here because some functions can't supply the typlen
+ */
+ len = strlen(s);
+ typlen = len + 4;
+ }
+
+ if (len > 4096)
+ elog(WARN, "varcharin: length of char() must be less than 4096");
+
+ result = (char *) palloc(typlen);
+ *(int32 *) result = typlen;
+ strncpy(result + 4, s, len);
+
+ return (result);
}
-char *
+char *
varcharout(char *s)
{
- char *result;
- int len;
-
- if (s == NULL) {
- result = (char *) palloc(2);
- result[0] = '-';
- result[1] = '\0';
- } else {
- len = *(int32*)s - 4;
- result = (char *) palloc(len+1);
- strNcpy(result, s+4, len);
- }
- return(result);
+ char *result;
+ int len;
+
+ if (s == NULL)
+ {
+ result = (char *) palloc(2);
+ result[0] = '-';
+ result[1] = '\0';
+ }
+ else
+ {
+ len = *(int32 *) s - 4;
+ result = (char *) palloc(len + 1);
+ strNcpy(result, s + 4, len);
+ }
+ return (result);
}
/*****************************************************************************
- * Comparison Functions used for bpchar
+ * Comparison Functions used for bpchar
*****************************************************************************/
static int
bcTruelen(char *arg)
{
- char *s = arg + 4;
- int i;
- int len;
-
- len = *(int32*)arg - 4;
- for(i=len-1; i >= 0; i--) {
- if (s[i] != ' ')
- break;
- }
- return (i+1);
+ char *s = arg + 4;
+ int i;
+ int len;
+
+ len = *(int32 *) arg - 4;
+ for (i = len - 1; i >= 0; i--)
+ {
+ if (s[i] != ' ')
+ break;
+ }
+ return (i + 1);
}
bool
bpchareq(char *arg1, char *arg2)
{
- int len1, len2;
+ int len1,
+ len2;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = bcTruelen(arg1);
+ len2 = bcTruelen(arg2);
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = bcTruelen(arg1);
- len2 = bcTruelen(arg2);
+ if (len1 != len2)
+ return 0;
- if (len1!=len2)
- return 0;
-
- return(strncmp(arg1+4, arg2+4, len1) == 0);
+ return (strncmp(arg1 + 4, arg2 + 4, len1) == 0);
}
bool
bpcharne(char *arg1, char *arg2)
{
- int len1, len2;
+ int len1,
+ len2;
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = bcTruelen(arg1);
- len2 = bcTruelen(arg2);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = bcTruelen(arg1);
+ len2 = bcTruelen(arg2);
- if (len1!=len2)
- return 1;
+ if (len1 != len2)
+ return 1;
- return(strncmp(arg1+4, arg2+4, len1) != 0);
+ return (strncmp(arg1 + 4, arg2 + 4, len1) != 0);
}
bool
bpcharlt(char *arg1, char *arg2)
{
- int len1, len2;
- int cmp;
-
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = bcTruelen(arg1);
- len2 = bcTruelen(arg2);
-
- cmp = strncmp(arg1+4, arg2+4, Min(len1,len2));
- if (cmp == 0)
- return (len1<len2);
- else
- return (cmp < 0);
+ int len1,
+ len2;
+ int cmp;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = bcTruelen(arg1);
+ len2 = bcTruelen(arg2);
+
+ cmp = strncmp(arg1 + 4, arg2 + 4, Min(len1, len2));
+ if (cmp == 0)
+ return (len1 < len2);
+ else
+ return (cmp < 0);
}
bool
bpcharle(char *arg1, char *arg2)
{
- int len1, len2;
- int cmp;
-
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = bcTruelen(arg1);
- len2 = bcTruelen(arg2);
-
- cmp = strncmp(arg1+4, arg2+4, Min(len1,len2));
- if (0 == cmp)
- return (bool)(len1 <= len2 ? 1 : 0);
- else
- return (bool)(cmp <= 0);
+ int len1,
+ len2;
+ int cmp;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = bcTruelen(arg1);
+ len2 = bcTruelen(arg2);
+
+ cmp = strncmp(arg1 + 4, arg2 + 4, Min(len1, len2));
+ if (0 == cmp)
+ return (bool) (len1 <= len2 ? 1 : 0);
+ else
+ return (bool) (cmp <= 0);
}
bool
bpchargt(char *arg1, char *arg2)
{
- int len1, len2;
- int cmp;
-
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = bcTruelen(arg1);
- len2 = bcTruelen(arg2);
-
- cmp = strncmp(arg1+4, arg2+4, Min(len1,len2));
- if (cmp == 0)
- return (len1 > len2);
- else
- return (cmp > 0);
+ int len1,
+ len2;
+ int cmp;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = bcTruelen(arg1);
+ len2 = bcTruelen(arg2);
+
+ cmp = strncmp(arg1 + 4, arg2 + 4, Min(len1, len2));
+ if (cmp == 0)
+ return (len1 > len2);
+ else
+ return (cmp > 0);
}
bool
bpcharge(char *arg1, char *arg2)
{
- int len1, len2;
- int cmp;
-
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = bcTruelen(arg1);
- len2 = bcTruelen(arg2);
-
- cmp = strncmp(arg1+4, arg2+4, Min(len1,len2));
- if (0 == cmp)
- return (bool)(len1 >= len2 ? 1 : 0);
- else
- return (bool)(cmp >= 0);
+ int len1,
+ len2;
+ int cmp;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = bcTruelen(arg1);
+ len2 = bcTruelen(arg2);
+
+ cmp = strncmp(arg1 + 4, arg2 + 4, Min(len1, len2));
+ if (0 == cmp)
+ return (bool) (len1 >= len2 ? 1 : 0);
+ else
+ return (bool) (cmp >= 0);
}
int32
bpcharcmp(char *arg1, char *arg2)
{
- int len1, len2;
- int cmp;
-
- len1 = bcTruelen(arg1);
- len2 = bcTruelen(arg2);
-
- cmp = strncmp(arg1+4, arg2+4, Min(len1,len2));
- if ((0 == cmp) && (len1 != len2))
- return (int32)(len1 < len2 ? -1 : 1);
- else
- return cmp;
+ int len1,
+ len2;
+ int cmp;
+
+ len1 = bcTruelen(arg1);
+ len2 = bcTruelen(arg2);
+
+ cmp = strncmp(arg1 + 4, arg2 + 4, Min(len1, len2));
+ if ((0 == cmp) && (len1 != len2))
+ return (int32) (len1 < len2 ? -1 : 1);
+ else
+ return cmp;
}
/*****************************************************************************
- * Comparison Functions used for varchar
+ * Comparison Functions used for varchar
*****************************************************************************/
static int
vcTruelen(char *arg)
{
- char *s = arg + 4;
- int i;
- int len;
-
- len = *(int32*)arg - 4;
- for(i=0; i < len; i++) {
- if (*s++ == '\0')
- break;
- }
- return i;
+ char *s = arg + 4;
+ int i;
+ int len;
+
+ len = *(int32 *) arg - 4;
+ for (i = 0; i < len; i++)
+ {
+ if (*s++ == '\0')
+ break;
+ }
+ return i;
}
bool
varchareq(char *arg1, char *arg2)
{
- int len1, len2;
+ int len1,
+ len2;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = vcTruelen(arg1);
+ len2 = vcTruelen(arg2);
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = vcTruelen(arg1);
- len2 = vcTruelen(arg2);
+ if (len1 != len2)
+ return 0;
- if (len1!=len2)
- return 0;
-
- return(strncmp(arg1+4, arg2+4, len1) == 0);
+ return (strncmp(arg1 + 4, arg2 + 4, len1) == 0);
}
bool
varcharne(char *arg1, char *arg2)
{
- int len1, len2;
+ int len1,
+ len2;
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = vcTruelen(arg1);
- len2 = vcTruelen(arg2);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = vcTruelen(arg1);
+ len2 = vcTruelen(arg2);
- if (len1!=len2)
- return 1;
+ if (len1 != len2)
+ return 1;
- return(strncmp(arg1+4, arg2+4, len1) != 0);
+ return (strncmp(arg1 + 4, arg2 + 4, len1) != 0);
}
bool
varcharlt(char *arg1, char *arg2)
{
- int len1, len2;
- int cmp;
-
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = vcTruelen(arg1);
- len2 = vcTruelen(arg2);
-
- cmp = strncmp(arg1+4, arg2+4, Min(len1,len2));
- if (cmp == 0)
- return (len1<len2);
- else
- return (cmp < 0);
+ int len1,
+ len2;
+ int cmp;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = vcTruelen(arg1);
+ len2 = vcTruelen(arg2);
+
+ cmp = strncmp(arg1 + 4, arg2 + 4, Min(len1, len2));
+ if (cmp == 0)
+ return (len1 < len2);
+ else
+ return (cmp < 0);
}
bool
varcharle(char *arg1, char *arg2)
{
- int len1, len2;
- int cmp;
-
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = vcTruelen(arg1);
- len2 = vcTruelen(arg2);
-
- cmp = strncmp(arg1+4, arg2+4, Min(len1,len2));
- if (0 == cmp)
- return (bool)( len1 <= len2 ? 1 : 0);
- else
- return (bool)(cmp <= 0);
+ int len1,
+ len2;
+ int cmp;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = vcTruelen(arg1);
+ len2 = vcTruelen(arg2);
+
+ cmp = strncmp(arg1 + 4, arg2 + 4, Min(len1, len2));
+ if (0 == cmp)
+ return (bool) (len1 <= len2 ? 1 : 0);
+ else
+ return (bool) (cmp <= 0);
}
bool
varchargt(char *arg1, char *arg2)
{
- int len1, len2;
- int cmp;
-
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = vcTruelen(arg1);
- len2 = vcTruelen(arg2);
-
- cmp = strncmp(arg1+4, arg2+4, Min(len1,len2));
- if (cmp == 0)
- return (len1 > len2);
- else
- return (cmp > 0);
+ int len1,
+ len2;
+ int cmp;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = vcTruelen(arg1);
+ len2 = vcTruelen(arg2);
+
+ cmp = strncmp(arg1 + 4, arg2 + 4, Min(len1, len2));
+ if (cmp == 0)
+ return (len1 > len2);
+ else
+ return (cmp > 0);
}
bool
varcharge(char *arg1, char *arg2)
{
- int len1, len2;
- int cmp;
+ int len1,
+ len2;
+ int cmp;
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
- len1 = vcTruelen(arg1);
- len2 = vcTruelen(arg2);
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+ len1 = vcTruelen(arg1);
+ len2 = vcTruelen(arg2);
- cmp = strncmp(arg1+4, arg2+4, Min(len1,len2));
- if (0 == cmp)
- return (bool)(len1 >= len2 ? 1 : 0);
- else
- return (bool)(cmp >= 0);
+ cmp = strncmp(arg1 + 4, arg2 + 4, Min(len1, len2));
+ if (0 == cmp)
+ return (bool) (len1 >= len2 ? 1 : 0);
+ else
+ return (bool) (cmp >= 0);
}
int32
varcharcmp(char *arg1, char *arg2)
{
- int len1, len2;
- int cmp;
-
- len1 = vcTruelen(arg1);
- len2 = vcTruelen(arg2);
- cmp = (strncmp(arg1+4, arg2+4, Min(len1,len2)));
- if ((0 == cmp) && (len1 != len2))
- return (int32)(len1 < len2 ? -1 : 1);
- else
- return (int32)(cmp);
+ int len1,
+ len2;
+ int cmp;
+
+ len1 = vcTruelen(arg1);
+ len2 = vcTruelen(arg2);
+ cmp = (strncmp(arg1 + 4, arg2 + 4, Min(len1, len2)));
+ if ((0 == cmp) && (len1 != len2))
+ return (int32) (len1 < len2 ? -1 : 1);
+ else
+ return (int32) (cmp);
}
/*****************************************************************************
* Hash functions (modified from hashtext in access/hash/hashfunc.c)
*****************************************************************************/
-uint32 hashbpchar(struct varlena *key)
+uint32
+hashbpchar(struct varlena * key)
{
- int keylen;
- char *keydata;
- uint32 n;
- int loop;
-
- keydata = VARDATA(key);
- keylen = bcTruelen((char*)key);
-
-#define HASHC n = *keydata++ + 65599 * n
-
- n = 0;
- if (keylen > 0) {
- loop = (keylen + 8 - 1) >> 3;
-
- switch (keylen & (8 - 1)) {
- case 0:
- do { /* All fall throughs */
- HASHC;
- case 7:
- HASHC;
- case 6:
- HASHC;
- case 5:
- HASHC;
- case 4:
- HASHC;
- case 3:
- HASHC;
- case 2:
- HASHC;
- case 1:
- HASHC;
- } while (--loop);
+ int keylen;
+ char *keydata;
+ uint32 n;
+ int loop;
+
+ keydata = VARDATA(key);
+ keylen = bcTruelen((char *) key);
+
+#define HASHC n = *keydata++ + 65599 * n
+
+ n = 0;
+ if (keylen > 0)
+ {
+ loop = (keylen + 8 - 1) >> 3;
+
+ switch (keylen & (8 - 1))
+ {
+ case 0:
+ do
+ { /* All fall throughs */
+ HASHC;
+ case 7:
+ HASHC;
+ case 6:
+ HASHC;
+ case 5:
+ HASHC;
+ case 4:
+ HASHC;
+ case 3:
+ HASHC;
+ case 2:
+ HASHC;
+ case 1:
+ HASHC;
+ } while (--loop);
+ }
}
- }
- return (n);
-}
+ return (n);
+}
-uint32 hashvarchar(struct varlena *key)
+uint32
+hashvarchar(struct varlena * key)
{
- int keylen;
- char *keydata;
- uint32 n;
- int loop;
-
- keydata = VARDATA(key);
- keylen = vcTruelen((char*)key);
-
-#define HASHC n = *keydata++ + 65599 * n
-
- n = 0;
- if (keylen > 0) {
- loop = (keylen + 8 - 1) >> 3;
-
- switch (keylen & (8 - 1)) {
- case 0:
- do { /* All fall throughs */
- HASHC;
- case 7:
- HASHC;
- case 6:
- HASHC;
- case 5:
- HASHC;
- case 4:
- HASHC;
- case 3:
- HASHC;
- case 2:
- HASHC;
- case 1:
- HASHC;
- } while (--loop);
+ int keylen;
+ char *keydata;
+ uint32 n;
+ int loop;
+
+ keydata = VARDATA(key);
+ keylen = vcTruelen((char *) key);
+
+#define HASHC n = *keydata++ + 65599 * n
+
+ n = 0;
+ if (keylen > 0)
+ {
+ loop = (keylen + 8 - 1) >> 3;
+
+ switch (keylen & (8 - 1))
+ {
+ case 0:
+ do
+ { /* All fall throughs */
+ HASHC;
+ case 7:
+ HASHC;
+ case 6:
+ HASHC;
+ case 5:
+ HASHC;
+ case 4:
+ HASHC;
+ case 3:
+ HASHC;
+ case 2:
+ HASHC;
+ case 1:
+ HASHC;
+ } while (--loop);
+ }
}
- }
- return (n);
-}
-
+ return (n);
+}
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 7c25cfd67b8..273fae92e9e 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* varlena.c--
- * Functions for the variable-length built-in types.
+ * Functions for the variable-length built-in types.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.18 1997/08/19 21:34:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.19 1997/09/07 04:52:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,64 +16,65 @@
#include "postgres.h"
#include "utils/palloc.h"
-#include "utils/builtins.h" /* where function declarations go */
+#include "utils/builtins.h" /* where function declarations go */
-/*****************************************************************************
- * USER I/O ROUTINES *
+/*****************************************************************************
+ * USER I/O ROUTINES *
*****************************************************************************/
-#define VAL(CH) ((CH) - '0')
-#define DIG(VAL) ((VAL) + '0')
+#define VAL(CH) ((CH) - '0')
+#define DIG(VAL) ((VAL) + '0')
/*
- * byteain - converts from printable representation of byte array
+ * byteain - converts from printable representation of byte array
*
- * Non-printable characters must be passed as '\nnn' (octal) and are
- * converted to internal form. '\' must be passed as '\\'.
- * elog(WARN, ...) if bad form.
+ * Non-printable characters must be passed as '\nnn' (octal) and are
+ * converted to internal form. '\' must be passed as '\\'.
+ * elog(WARN, ...) if bad form.
*
- * BUGS:
- * The input is scaned twice.
- * The error checking of input is minimal.
+ * BUGS:
+ * The input is scaned twice.
+ * The error checking of input is minimal.
*/
struct varlena *
byteain(char *inputText)
{
- register char *tp;
- register char *rp;
- register int byte;
- struct varlena *result;
-
- if (inputText == NULL)
- elog(WARN, "Bad input string for type bytea");
-
- for (byte = 0, tp = inputText; *tp != '\0'; byte++)
- if (*tp++ == '\\')
- {
- if (*tp == '\\')
- tp++;
- else if (!isdigit(*tp++) ||
- !isdigit(*tp++) ||
- !isdigit(*tp++))
- elog(WARN, "Bad input string for type bytea");
- }
- tp = inputText;
- byte += sizeof(int32); /* varlena? */
- result = (struct varlena *) palloc(byte);
- result->vl_len = byte; /* varlena? */
- rp = result->vl_dat;
- while (*tp != '\0')
- if (*tp != '\\' || *++tp == '\\')
- *rp++ = *tp++;
- else {
- byte = VAL(*tp++);
- byte <<= 3;
- byte += VAL(*tp++);
- byte <<= 3;
- *rp++ = byte + VAL(*tp++);
- }
- return(result);
+ register char *tp;
+ register char *rp;
+ register int byte;
+ struct varlena *result;
+
+ if (inputText == NULL)
+ elog(WARN, "Bad input string for type bytea");
+
+ for (byte = 0, tp = inputText; *tp != '\0'; byte++)
+ if (*tp++ == '\\')
+ {
+ if (*tp == '\\')
+ tp++;
+ else if (!isdigit(*tp++) ||
+ !isdigit(*tp++) ||
+ !isdigit(*tp++))
+ elog(WARN, "Bad input string for type bytea");
+ }
+ tp = inputText;
+ byte += sizeof(int32); /* varlena? */
+ result = (struct varlena *) palloc(byte);
+ result->vl_len = byte; /* varlena? */
+ rp = result->vl_dat;
+ while (*tp != '\0')
+ if (*tp != '\\' || *++tp == '\\')
+ *rp++ = *tp++;
+ else
+ {
+ byte = VAL(*tp++);
+ byte <<= 3;
+ byte += VAL(*tp++);
+ byte <<= 3;
+ *rp++ = byte + VAL(*tp++);
+ }
+ return (result);
}
/*
@@ -85,114 +86,120 @@ byteain(char *inputText)
struct varlena *
shove_bytes(unsigned char *stuff, int len)
{
- struct varlena *result;
-
- result = (struct varlena *) palloc(len + sizeof(int32));
- result->vl_len = len;
- memmove(result->vl_dat,
- stuff + sizeof(int32),
- len - sizeof(int32));
- return(result);
+ struct varlena *result;
+
+ result = (struct varlena *) palloc(len + sizeof(int32));
+ result->vl_len = len;
+ memmove(result->vl_dat,
+ stuff + sizeof(int32),
+ len - sizeof(int32));
+ return (result);
}
+
#endif
/*
- * byteaout - converts to printable representation of byte array
+ * byteaout - converts to printable representation of byte array
*
- * Non-printable characters are inserted as '\nnn' (octal) and '\' as
- * '\\'.
+ * Non-printable characters are inserted as '\nnn' (octal) and '\' as
+ * '\\'.
*
- * NULL vlena should be an error--returning string with NULL for now.
+ * NULL vlena should be an error--returning string with NULL for now.
*/
-char *
-byteaout(struct varlena *vlena)
+char *
+byteaout(struct varlena * vlena)
{
- register char *vp;
- register char *rp;
- register int val; /* holds unprintable chars */
- int i;
- int len;
- static char *result;
-
- if (vlena == NULL) {
- result = (char *) palloc(2);
- result[0] = '-';
- result[1] = '\0';
- return(result);
- }
- vp = vlena->vl_dat;
- len = 1; /* empty string has 1 char */
- for (i = vlena->vl_len - sizeof(int32); i != 0; i--, vp++) /* varlena? */
- if (*vp == '\\')
- len += 2;
- else if (isascii(*vp) && isprint(*vp))
- len++;
- else
- len += 4;
- rp = result = (char *) palloc(len);
- vp = vlena->vl_dat;
- for (i = vlena->vl_len - sizeof(int32); i != 0; i--) /* varlena? */
- if (*vp == '\\') {
- vp++;
- *rp++ = '\\';
- *rp++ = '\\';
- } else if (isascii(*vp) && isprint(*vp))
- *rp++ = *vp++;
- else {
- val = *vp++;
- *rp = '\\';
- rp += 3;
- *rp-- = DIG(val & 07);
- val >>= 3;
- *rp-- = DIG(val & 07);
- val >>= 3;
- *rp = DIG(val & 03);
- rp += 3;
+ register char *vp;
+ register char *rp;
+ register int val; /* holds unprintable chars */
+ int i;
+ int len;
+ static char *result;
+
+ if (vlena == NULL)
+ {
+ result = (char *) palloc(2);
+ result[0] = '-';
+ result[1] = '\0';
+ return (result);
}
- *rp = '\0';
- return(result);
+ vp = vlena->vl_dat;
+ len = 1; /* empty string has 1 char */
+ for (i = vlena->vl_len - sizeof(int32); i != 0; i--, vp++) /* varlena? */
+ if (*vp == '\\')
+ len += 2;
+ else if (isascii(*vp) && isprint(*vp))
+ len++;
+ else
+ len += 4;
+ rp = result = (char *) palloc(len);
+ vp = vlena->vl_dat;
+ for (i = vlena->vl_len - sizeof(int32); i != 0; i--) /* varlena? */
+ if (*vp == '\\')
+ {
+ vp++;
+ *rp++ = '\\';
+ *rp++ = '\\';
+ }
+ else if (isascii(*vp) && isprint(*vp))
+ *rp++ = *vp++;
+ else
+ {
+ val = *vp++;
+ *rp = '\\';
+ rp += 3;
+ *rp-- = DIG(val & 07);
+ val >>= 3;
+ *rp-- = DIG(val & 07);
+ val >>= 3;
+ *rp = DIG(val & 03);
+ rp += 3;
+ }
+ *rp = '\0';
+ return (result);
}
/*
- * textin - converts "..." to internal representation
+ * textin - converts "..." to internal representation
*/
struct varlena *
textin(char *inputText)
{
- struct varlena *result;
- int len;
-
- if (inputText == NULL)
- return(NULL);
- len = strlen(inputText) + VARHDRSZ;
- result = (struct varlena *) palloc(len);
- VARSIZE(result) = len;
- memmove(VARDATA(result), inputText, len - VARHDRSZ);
- return(result);
+ struct varlena *result;
+ int len;
+
+ if (inputText == NULL)
+ return (NULL);
+ len = strlen(inputText) + VARHDRSZ;
+ result = (struct varlena *) palloc(len);
+ VARSIZE(result) = len;
+ memmove(VARDATA(result), inputText, len - VARHDRSZ);
+ return (result);
}
/*
- * textout - converts internal representation to "..."
+ * textout - converts internal representation to "..."
*/
-char *
-textout(struct varlena *vlena)
+char *
+textout(struct varlena * vlena)
{
- int len;
- char *result;
-
- if (vlena == NULL) {
- result = (char *) palloc(2);
- result[0] = '-';
- result[1] = '\0';
- return(result);
- }
- len = VARSIZE(vlena) - VARHDRSZ;
- result = (char *) palloc(len + 1);
- memmove(result, VARDATA(vlena), len);
- result[len] = '\0';
- return(result);
+ int len;
+ char *result;
+
+ if (vlena == NULL)
+ {
+ result = (char *) palloc(2);
+ result[0] = '-';
+ result[1] = '\0';
+ return (result);
+ }
+ len = VARSIZE(vlena) - VARHDRSZ;
+ result = (char *) palloc(len + 1);
+ memmove(result, VARDATA(vlena), len);
+ result[len] = '\0';
+ return (result);
}
@@ -200,25 +207,28 @@ textout(struct varlena *vlena)
/*
* textlen -
- * returns the actual length of a text* (which may be less than
- * the VARSIZE of the text*)
+ * returns the actual length of a text* (which may be less than
+ * the VARSIZE of the text*)
*/
#ifdef NOT_USED
-int textlen (text* t)
+int
+textlen(text * t)
{
- int i = 0;
- int max = VARSIZE(t) - VARHDRSZ;
- char *ptr = VARDATA(t);
- while (i < max && *ptr++)
- i++;
- return i;
+ int i = 0;
+ int max = VARSIZE(t) - VARHDRSZ;
+ char *ptr = VARDATA(t);
+
+ while (i < max && *ptr++)
+ i++;
+ return i;
}
+
#endif
/*
* textcat -
- * takes two text* and returns a text* that is the concatentation of
- * the two.
+ * takes two text* and returns a text* that is the concatentation of
+ * the two.
*
* Rewritten by Sapa, sapa@hq.icb.chel.su. 8-Jul-96.
* Updated by Thomas, Thomas.Lockhart@jpl.nasa.gov 1997-07-10.
@@ -228,222 +238,241 @@ int textlen (text* t)
* Is this OK?
*/
-text*
-textcat(text* t1, text* t2)
+text *
+textcat(text * t1, text * t2)
{
- int len1, len2, len;
- char *ptr;
- text* result;
+ int len1,
+ len2,
+ len;
+ char *ptr;
+ text *result;
- if (!PointerIsValid(t1) && !PointerIsValid(t2))
- return(NULL);
+ if (!PointerIsValid(t1) && !PointerIsValid(t2))
+ return (NULL);
- len1 = (PointerIsValid(t1)? (VARSIZE(t1) - VARHDRSZ): 0);
- if (len1 < 0) len1 = 0;
- len2 = (PointerIsValid(t2)? (VARSIZE(t2) - VARHDRSZ): 0);
- if (len2 < 0) len2 = 0;
+ len1 = (PointerIsValid(t1) ? (VARSIZE(t1) - VARHDRSZ) : 0);
+ if (len1 < 0)
+ len1 = 0;
+ len2 = (PointerIsValid(t2) ? (VARSIZE(t2) - VARHDRSZ) : 0);
+ if (len2 < 0)
+ len2 = 0;
- result = PALLOC(len = len1 + len2 + VARHDRSZ);
+ result = PALLOC(len = len1 + len2 + VARHDRSZ);
- /* Fill data field of result string... */
- ptr = VARDATA(result);
- if (PointerIsValid(t1)) memcpy(ptr, VARDATA(t1), len1);
- if (PointerIsValid(t2)) memcpy(ptr + len1, VARDATA(t2), len2);
+ /* Fill data field of result string... */
+ ptr = VARDATA(result);
+ if (PointerIsValid(t1))
+ memcpy(ptr, VARDATA(t1), len1);
+ if (PointerIsValid(t2))
+ memcpy(ptr + len1, VARDATA(t2), len2);
- /* Set size of result string... */
- VARSIZE(result) = len;
+ /* Set size of result string... */
+ VARSIZE(result) = len;
- return(result);
-} /* textcat() */
+ return (result);
+} /* textcat() */
/*
* textpos -
- * Return the position of the specified substring.
- * Implements the SQL92 POSITION() function.
- * Ref: A Guide To The SQL Standard, Date & Darwen, 1997
+ * Return the position of the specified substring.
+ * Implements the SQL92 POSITION() function.
+ * Ref: A Guide To The SQL Standard, Date & Darwen, 1997
* - thomas 1997-07-27
*/
int32
-textpos(text* t1, text* t2)
+textpos(text * t1, text * t2)
{
- int pos;
- int px, p;
- int len1, len2;
- char *p1, *p2;
-
- if (!PointerIsValid(t1) || !PointerIsValid(t2))
- return(0);
-
- if (VARSIZE(t2) <= 0)
- return(1);
-
- len1 = (VARSIZE(t1) - VARHDRSZ);
- len2 = (VARSIZE(t2) - VARHDRSZ);
- p1 = VARDATA(t1);
- p2 = VARDATA(t2);
- pos = 0;
- px = (len1 - len2);
- for (p = 0; p <= px; p++) {
- if ((*p2 == *p1) && (strncmp(p1, p2, len2) == 0)) {
- pos = p + 1;
- break;
+ int pos;
+ int px,
+ p;
+ int len1,
+ len2;
+ char *p1,
+ *p2;
+
+ if (!PointerIsValid(t1) || !PointerIsValid(t2))
+ return (0);
+
+ if (VARSIZE(t2) <= 0)
+ return (1);
+
+ len1 = (VARSIZE(t1) - VARHDRSZ);
+ len2 = (VARSIZE(t2) - VARHDRSZ);
+ p1 = VARDATA(t1);
+ p2 = VARDATA(t2);
+ pos = 0;
+ px = (len1 - len2);
+ for (p = 0; p <= px; p++)
+ {
+ if ((*p2 == *p1) && (strncmp(p1, p2, len2) == 0))
+ {
+ pos = p + 1;
+ break;
+ };
+ p1++;
};
- p1++;
- };
- return(pos);
-} /* textpos() */
+ return (pos);
+} /* textpos() */
/*
- * texteq - returns 1 iff arguments are equal
- * textne - returns 1 iff arguments are not equal
+ * texteq - returns 1 iff arguments are equal
+ * textne - returns 1 iff arguments are not equal
*/
bool
-texteq(struct varlena *arg1, struct varlena *arg2)
+texteq(struct varlena * arg1, struct varlena * arg2)
{
- register int len;
- register char *a1p, *a2p;
-
- if (arg1 == NULL || arg2 == NULL)
- return((bool) NULL);
- if ((len = arg1->vl_len) != arg2->vl_len)
- return((bool) 0);
- a1p = arg1->vl_dat;
- a2p = arg2->vl_dat;
- /*
- * Varlenas are stored as the total size (data + size variable)
- * followed by the data.
- * Use VARHDRSZ instead of explicit sizeof() - thomas 1997-07-10
- */
- len -= VARHDRSZ;
- while (len-- != 0)
- if (*a1p++ != *a2p++)
- return((bool) 0);
- return((bool) 1);
-} /* texteq() */
+ register int len;
+ register char *a1p,
+ *a2p;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) NULL);
+ if ((len = arg1->vl_len) != arg2->vl_len)
+ return ((bool) 0);
+ a1p = arg1->vl_dat;
+ a2p = arg2->vl_dat;
+
+ /*
+ * Varlenas are stored as the total size (data + size variable)
+ * followed by the data. Use VARHDRSZ instead of explicit sizeof() -
+ * thomas 1997-07-10
+ */
+ len -= VARHDRSZ;
+ while (len-- != 0)
+ if (*a1p++ != *a2p++)
+ return ((bool) 0);
+ return ((bool) 1);
+} /* texteq() */
bool
-textne(struct varlena *arg1, struct varlena *arg2)
+textne(struct varlena * arg1, struct varlena * arg2)
{
- return((bool) !texteq(arg1, arg2));
+ return ((bool) ! texteq(arg1, arg2));
}
/* text_lt()
* Comparison function for text strings.
* Includes locale support, but must copy strings to temporary memory
- * to allow null-termination for inputs to strcoll().
+ * to allow null-termination for inputs to strcoll().
* XXX HACK code for textlen() indicates that there can be embedded nulls
- * but it appears that most routines (incl. this one) assume not! - tgl 97/04/07
+ * but it appears that most routines (incl. this one) assume not! - tgl 97/04/07
*/
bool
-text_lt(struct varlena *arg1, struct varlena *arg2)
+text_lt(struct varlena * arg1, struct varlena * arg2)
{
- bool result;
+ bool result;
#ifdef USE_LOCALE
- int cval;
+ int cval;
+
#endif
- int len;
- unsigned char *a1p, *a2p;
-
- if (arg1 == NULL || arg2 == NULL)
- return((bool) FALSE);
-
- len = (((VARSIZE(arg1) <= VARSIZE(arg2))? VARSIZE(arg1): VARSIZE(arg2))-VARHDRSZ);
-
+ int len;
+ unsigned char *a1p,
+ *a2p;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) FALSE);
+
+ len = (((VARSIZE(arg1) <= VARSIZE(arg2)) ? VARSIZE(arg1) : VARSIZE(arg2)) - VARHDRSZ);
+
#ifdef USE_LOCALE
- a1p = (unsigned char *) palloc (len+1);
- a2p = (unsigned char *) palloc (len+1);
+ a1p = (unsigned char *) palloc(len + 1);
+ a2p = (unsigned char *) palloc(len + 1);
- memcpy(a1p, VARDATA(arg1), len);
- *(a1p+len) = '\0';
- memcpy(a2p, VARDATA(arg2), len);
- *(a2p+len) = '\0';
+ memcpy(a1p, VARDATA(arg1), len);
+ *(a1p + len) = '\0';
+ memcpy(a2p, VARDATA(arg2), len);
+ *(a2p + len) = '\0';
- cval = strcoll(a1p,a2p);
- result = ((cval < 0) || ((cval == 0) && (VARSIZE(arg1) < VARSIZE(arg2))));
+ cval = strcoll(a1p, a2p);
+ result = ((cval < 0) || ((cval == 0) && (VARSIZE(arg1) < VARSIZE(arg2))));
- pfree (a1p);
- pfree (a2p);
+ pfree(a1p);
+ pfree(a2p);
#else
- a1p = (unsigned char *)VARDATA(arg1);
- a2p = (unsigned char *)VARDATA(arg2);
-
- while (len != 0 && *a1p == *a2p) {
- a1p++;
- a2p++;
- len--;
- };
-
- result = (len? (*a1p < *a2p): (VARSIZE(arg1) < VARSIZE(arg2)));
+ a1p = (unsigned char *) VARDATA(arg1);
+ a2p = (unsigned char *) VARDATA(arg2);
+
+ while (len != 0 && *a1p == *a2p)
+ {
+ a1p++;
+ a2p++;
+ len--;
+ };
+
+ result = (len ? (*a1p < *a2p) : (VARSIZE(arg1) < VARSIZE(arg2)));
#endif
- return(result);
-} /* text_lt() */
+ return (result);
+} /* text_lt() */
/* text_le()
* Comparison function for text strings.
* Includes locale support, but must copy strings to temporary memory
- * to allow null-termination for inputs to strcoll().
+ * to allow null-termination for inputs to strcoll().
* XXX HACK code for textlen() indicates that there can be embedded nulls
- * but it appears that most routines (incl. this one) assume not! - tgl 97/04/07
+ * but it appears that most routines (incl. this one) assume not! - tgl 97/04/07
*/
bool
-text_le(struct varlena *arg1, struct varlena *arg2)
+text_le(struct varlena * arg1, struct varlena * arg2)
{
- bool result;
+ bool result;
#ifdef USE_LOCALE
- int cval;
+ int cval;
+
#endif
- int len;
- unsigned char *a1p, *a2p;
-
- if (arg1 == NULL || arg2 == NULL)
- return((bool) 0);
-
- len = (((VARSIZE(arg1) <= VARSIZE(arg2))? VARSIZE(arg1): VARSIZE(arg2))-VARHDRSZ);
-
+ int len;
+ unsigned char *a1p,
+ *a2p;
+
+ if (arg1 == NULL || arg2 == NULL)
+ return ((bool) 0);
+
+ len = (((VARSIZE(arg1) <= VARSIZE(arg2)) ? VARSIZE(arg1) : VARSIZE(arg2)) - VARHDRSZ);
+
#ifdef USE_LOCALE
- a1p = (unsigned char *) palloc (len+1);
- a2p = (unsigned char *) palloc (len+1);
+ a1p = (unsigned char *) palloc(len + 1);
+ a2p = (unsigned char *) palloc(len + 1);
- memcpy(a1p, VARDATA(arg1), len);
- *(a1p+len) = '\0';
- memcpy(a2p, VARDATA(arg2), len);
- *(a2p+len) = '\0';
+ memcpy(a1p, VARDATA(arg1), len);
+ *(a1p + len) = '\0';
+ memcpy(a2p, VARDATA(arg2), len);
+ *(a2p + len) = '\0';
- cval = strcoll(a1p,a2p);
- result = ((cval < 0) || ((cval == 0) && (VARSIZE(arg1) <= VARSIZE(arg2))));
+ cval = strcoll(a1p, a2p);
+ result = ((cval < 0) || ((cval == 0) && (VARSIZE(arg1) <= VARSIZE(arg2))));
- pfree (a1p);
- pfree (a2p);
+ pfree(a1p);
+ pfree(a2p);
#else
- a1p = (unsigned char *)VARDATA(arg1);
- a2p = (unsigned char *)VARDATA(arg2);
-
- while (len != 0 && *a1p == *a2p) {
- a1p++;
- a2p++;
- len--;
- };
-
- result = (len? (*a1p <= *a2p): (VARSIZE(arg1) <= VARSIZE(arg2)));
+ a1p = (unsigned char *) VARDATA(arg1);
+ a2p = (unsigned char *) VARDATA(arg2);
+
+ while (len != 0 && *a1p == *a2p)
+ {
+ a1p++;
+ a2p++;
+ len--;
+ };
+
+ result = (len ? (*a1p <= *a2p) : (VARSIZE(arg1) <= VARSIZE(arg2)));
#endif
- return(result);
-} /* text_le() */
+ return (result);
+} /* text_le() */
bool
-text_gt(struct varlena *arg1, struct varlena *arg2)
+text_gt(struct varlena * arg1, struct varlena * arg2)
{
- return ((bool) !text_le(arg1, arg2));
+ return ((bool) ! text_le(arg1, arg2));
}
bool
-text_ge(struct varlena *arg1, struct varlena *arg2)
+text_ge(struct varlena * arg1, struct varlena * arg2)
{
- return ((bool) !text_lt(arg1, arg2));
+ return ((bool) ! text_lt(arg1, arg2));
}
/*-------------------------------------------------------------
@@ -453,13 +482,13 @@ text_ge(struct varlena *arg1, struct varlena *arg2)
*-------------------------------------------------------------
*/
int32
-byteaGetSize(struct varlena *v)
+byteaGetSize(struct varlena * v)
{
- register int len;
-
- len = v->vl_len - sizeof(v->vl_len);
-
- return(len);
+ register int len;
+
+ len = v->vl_len - sizeof(v->vl_len);
+
+ return (len);
}
/*-------------------------------------------------------------
@@ -471,21 +500,22 @@ byteaGetSize(struct varlena *v)
*-------------------------------------------------------------
*/
int32
-byteaGetByte(struct varlena *v, int32 n)
+byteaGetByte(struct varlena * v, int32 n)
{
- int len;
- int byte;
-
- len = byteaGetSize(v);
-
- if (n>=len) {
- elog(WARN, "byteaGetByte: index (=%d) out of range [0..%d]",
- n,len-1);
- }
-
- byte = (unsigned char) (v->vl_dat[n]);
-
- return((int32) byte);
+ int len;
+ int byte;
+
+ len = byteaGetSize(v);
+
+ if (n >= len)
+ {
+ elog(WARN, "byteaGetByte: index (=%d) out of range [0..%d]",
+ n, len - 1);
+ }
+
+ byte = (unsigned char) (v->vl_dat[n]);
+
+ return ((int32) byte);
}
/*-------------------------------------------------------------
@@ -498,22 +528,27 @@ byteaGetByte(struct varlena *v, int32 n)
*-------------------------------------------------------------
*/
int32
-byteaGetBit(struct varlena *v, int32 n)
+byteaGetBit(struct varlena * v, int32 n)
{
- int byteNo, bitNo;
- int byte;
-
- byteNo = n/8;
- bitNo = n%8;
-
- byte = byteaGetByte(v, byteNo);
-
- if (byte & (1<<bitNo)) {
- return((int32)1);
- } else {
- return((int32)0);
- }
+ int byteNo,
+ bitNo;
+ int byte;
+
+ byteNo = n / 8;
+ bitNo = n % 8;
+
+ byte = byteaGetByte(v, byteNo);
+
+ if (byte & (1 << bitNo))
+ {
+ return ((int32) 1);
+ }
+ else
+ {
+ return ((int32) 0);
+ }
}
+
/*-------------------------------------------------------------
* byteaSetByte
*
@@ -523,35 +558,37 @@ byteaGetBit(struct varlena *v, int32 n)
*-------------------------------------------------------------
*/
struct varlena *
-byteaSetByte(struct varlena *v, int32 n, int32 newByte)
+byteaSetByte(struct varlena * v, int32 n, int32 newByte)
{
- int len;
- struct varlena *res;
-
- len = byteaGetSize(v);
-
- if (n>=len) {
- elog(WARN,
- "byteaSetByte: index (=%d) out of range [0..%d]",
- n, len-1);
- }
-
- /*
- * Make a copy of the original varlena.
- */
- res = (struct varlena *) palloc(VARSIZE(v));
- if (res==NULL) {
- elog(WARN, "byteaSetByte: Out of memory (%d bytes requested)",
- VARSIZE(v));
- }
- memmove((char *)res, (char *)v, VARSIZE(v));
-
- /*
- * Now set the byte.
- */
- res->vl_dat[n] = newByte;
-
- return(res);
+ int len;
+ struct varlena *res;
+
+ len = byteaGetSize(v);
+
+ if (n >= len)
+ {
+ elog(WARN,
+ "byteaSetByte: index (=%d) out of range [0..%d]",
+ n, len - 1);
+ }
+
+ /*
+ * Make a copy of the original varlena.
+ */
+ res = (struct varlena *) palloc(VARSIZE(v));
+ if (res == NULL)
+ {
+ elog(WARN, "byteaSetByte: Out of memory (%d bytes requested)",
+ VARSIZE(v));
+ }
+ memmove((char *) res, (char *) v, VARSIZE(v));
+
+ /*
+ * Now set the byte.
+ */
+ res->vl_dat[n] = newByte;
+
+ return (res);
}
/*-------------------------------------------------------------
@@ -563,39 +600,45 @@ byteaSetByte(struct varlena *v, int32 n, int32 newByte)
*-------------------------------------------------------------
*/
struct varlena *
-byteaSetBit(struct varlena *v, int32 n, int32 newBit)
+byteaSetBit(struct varlena * v, int32 n, int32 newBit)
{
- struct varlena *res;
- int oldByte, newByte;
- int byteNo, bitNo;
-
- /*
- * sanity check!
- */
- if (newBit != 0 && newBit != 1) {
- elog(WARN, "byteaSetByte: new bit must be 0 or 1");
- }
-
- /*
- * get the byte where the bit we want is stored.
- */
- byteNo = n / 8;
- bitNo = n % 8;
- oldByte = byteaGetByte(v, byteNo);
-
- /*
- * calculate the new value for that byte
- */
- if (newBit == 0) {
- newByte = oldByte & (~(1<<bitNo));
- } else {
- newByte = oldByte | (1<<bitNo);
- }
-
- /*
- * NOTE: 'byteaSetByte' creates a copy of 'v' & sets the byte.
- */
- res = byteaSetByte(v, byteNo, newByte);
-
- return(res);
+ struct varlena *res;
+ int oldByte,
+ newByte;
+ int byteNo,
+ bitNo;
+
+ /*
+ * sanity check!
+ */
+ if (newBit != 0 && newBit != 1)
+ {
+ elog(WARN, "byteaSetByte: new bit must be 0 or 1");
+ }
+
+ /*
+ * get the byte where the bit we want is stored.
+ */
+ byteNo = n / 8;
+ bitNo = n % 8;
+ oldByte = byteaGetByte(v, byteNo);
+
+ /*
+ * calculate the new value for that byte
+ */
+ if (newBit == 0)
+ {
+ newByte = oldByte & (~(1 << bitNo));
+ }
+ else
+ {
+ newByte = oldByte | (1 << bitNo);
+ }
+
+ /*
+ * NOTE: 'byteaSetByte' creates a copy of 'v' & sets the byte.
+ */
+ res = byteaSetByte(v, byteNo, newByte);
+
+ return (res);
}
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index aee835943e3..3edddd3c1aa 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* catcache.c--
- * System catalog cache for tuples matching a key.
+ * System catalog cache for tuples matching a key.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.10 1997/08/26 19:24:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.11 1997/09/07 04:52:56 momjian Exp $
*
* Notes:
- * XXX This needs to use exception.h to handle recovery when
- * an abort occurs during DisableCache.
- *
+ * XXX This needs to use exception.h to handle recovery when
+ * an abort occurs during DisableCache.
+ *
*-------------------------------------------------------------------------
*/
#include <string.h>
@@ -26,7 +26,7 @@
#include "miscadmin.h"
#include "utils/portal.h"
#include "utils/catcache.h"
-#include "fmgr.h" /* for F_BOOLEQ, etc. DANGER */
+#include "fmgr.h" /* for F_BOOLEQ, etc. DANGER */
#include "utils/elog.h"
#include "utils/palloc.h"
#include "utils/mcxt.h"
@@ -34,29 +34,31 @@
#include "catalog/pg_type.h" /* for OID of int28 type */
#include "lib/dllist.h"
-static void CatCacheRemoveCTup(CatCache *cache, Dlelem *e);
-static Index CatalogCacheComputeHashIndex(struct catcache *cacheInP);
-static Index CatalogCacheComputeTupleHashIndex(struct catcache *cacheInOutP,
- Relation relation, HeapTuple tuple);
-static void CatalogCacheInitializeCache(struct catcache *cache,
- Relation relation);
-static long comphash(long l, char *v);
+static void CatCacheRemoveCTup(CatCache * cache, Dlelem * e);
+static Index CatalogCacheComputeHashIndex(struct catcache * cacheInP);
+static Index
+CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP,
+ Relation relation, HeapTuple tuple);
+static void
+CatalogCacheInitializeCache(struct catcache * cache,
+ Relation relation);
+static long comphash(long l, char *v);
/* ----------------
- * variables, macros and other stuff
+ * variables, macros and other stuff
*
- * note CCSIZE allocates 51 buckets .. one was already allocated in
- * the catcache structure.
+ * note CCSIZE allocates 51 buckets .. one was already allocated in
+ * the catcache structure.
* ----------------
*/
#ifdef CACHEDEBUG
-#define CACHE1_elog(a,b) elog(a,b)
-#define CACHE2_elog(a,b,c) elog(a,b,c)
-#define CACHE3_elog(a,b,c,d) elog(a,b,c,d)
-#define CACHE4_elog(a,b,c,d,e) elog(a,b,c,d,e)
-#define CACHE5_elog(a,b,c,d,e,f) elog(a,b,c,d,e,f)
-#define CACHE6_elog(a,b,c,d,e,f,g) elog(a,b,c,d,e,f,g)
+#define CACHE1_elog(a,b) elog(a,b)
+#define CACHE2_elog(a,b,c) elog(a,b,c)
+#define CACHE3_elog(a,b,c,d) elog(a,b,c,d)
+#define CACHE4_elog(a,b,c,d,e) elog(a,b,c,d,e)
+#define CACHE5_elog(a,b,c,d,e,f) elog(a,b,c,d,e,f)
+#define CACHE6_elog(a,b,c,d,e,f,g) elog(a,b,c,d,e,f,g)
#else
#define CACHE1_elog(a,b)
#define CACHE2_elog(a,b,c)
@@ -66,209 +68,217 @@ static long comphash(long l, char *v);
#define CACHE6_elog(a,b,c,d,e,f,g)
#endif
-CatCache *Caches = NULL;
+CatCache *Caches = NULL;
GlobalMemory CacheCxt;
-static int DisableCache;
+static int DisableCache;
/* ----------------
- * EQPROC is used in CatalogCacheInitializeCache
- * XXX this should be replaced by catalog lookups soon
+ * EQPROC is used in CatalogCacheInitializeCache
+ * XXX this should be replaced by catalog lookups soon
* ----------------
*/
-static long eqproc[] = {
- F_BOOLEQ, 0l, F_CHAREQ, F_CHAR16EQ, 0l,
- F_INT2EQ, F_KEYFIRSTEQ, F_INT4EQ, 0l, F_TEXTEQ,
- F_OIDEQ, 0l, 0l, 0l, F_OID8EQ
+static long eqproc[] = {
+ F_BOOLEQ, 0l, F_CHAREQ, F_CHAR16EQ, 0l,
+ F_INT2EQ, F_KEYFIRSTEQ, F_INT4EQ, 0l, F_TEXTEQ,
+ F_OIDEQ, 0l, 0l, 0l, F_OID8EQ
};
-#define EQPROC(SYSTEMTYPEOID) eqproc[(SYSTEMTYPEOID)-16]
+#define EQPROC(SYSTEMTYPEOID) eqproc[(SYSTEMTYPEOID)-16]
/* ----------------------------------------------------------------
- * internal support functions
+ * internal support functions
* ----------------------------------------------------------------
*/
/* --------------------------------
- * CatalogCacheInitializeCache
+ * CatalogCacheInitializeCache
* --------------------------------
*/
#ifdef CACHEDEBUG
#define CatalogCacheInitializeCache_DEBUG1 \
- elog(DEBUG, "CatalogCacheInitializeCache: cache @%08lx", cache); \
- if (relation) \
- elog(DEBUG, "CatalogCacheInitializeCache: called w/relation(inval)"); \
- else \
- elog(DEBUG, "CatalogCacheInitializeCache: called w/relname %s", \
- cache->cc_relname)
+ elog(DEBUG, "CatalogCacheInitializeCache: cache @%08lx", cache); \
+ if (relation) \
+ elog(DEBUG, "CatalogCacheInitializeCache: called w/relation(inval)"); \
+ else \
+ elog(DEBUG, "CatalogCacheInitializeCache: called w/relname %s", \
+ cache->cc_relname)
#define CatalogCacheInitializeCache_DEBUG2 \
- if (cache->cc_key[i] > 0) { \
- elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d, %d", \
- i+1, cache->cc_nkeys, cache->cc_key[i], \
- relation->rd_att->attrs[cache->cc_key[i] - 1]->attlen); \
- } else { \
- elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d", \
- i+1, cache->cc_nkeys, cache->cc_key[i]); \
- }
+ if (cache->cc_key[i] > 0) { \
+ elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d, %d", \
+ i+1, cache->cc_nkeys, cache->cc_key[i], \
+ relation->rd_att->attrs[cache->cc_key[i] - 1]->attlen); \
+ } else { \
+ elog(DEBUG, "CatalogCacheInitializeCache: load %d/%d w/%d", \
+ i+1, cache->cc_nkeys, cache->cc_key[i]); \
+ }
#else
#define CatalogCacheInitializeCache_DEBUG1
#define CatalogCacheInitializeCache_DEBUG2
#endif
static void
-CatalogCacheInitializeCache(struct catcache *cache,
- Relation relation)
+CatalogCacheInitializeCache(struct catcache * cache,
+ Relation relation)
{
- MemoryContext oldcxt;
- short didopen = 0;
- short i;
- TupleDesc tupdesc;
-
- CatalogCacheInitializeCache_DEBUG1;
-
- /* ----------------
- * first switch to the cache context so our allocations
- * do not vanish at the end of a transaction
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * If no relation was passed we must open it to get access to
- * its fields. If one of the other caches has already opened
- * it we use heap_open() instead of heap_openr()
- * ----------------
- */
- if (! RelationIsValid(relation)) {
- struct catcache *cp;
+ MemoryContext oldcxt;
+ short didopen = 0;
+ short i;
+ TupleDesc tupdesc;
+
+ CatalogCacheInitializeCache_DEBUG1;
+
/* ----------------
- * scan the caches to see if any other cache has opened the relation
+ * first switch to the cache context so our allocations
+ * do not vanish at the end of a transaction
* ----------------
*/
- for (cp = Caches; cp; cp = cp->cc_next) {
- if (strncmp(cp->cc_relname, cache->cc_relname, NAMEDATALEN) == 0) {
- if (cp->relationId != InvalidOid)
- break;
- }
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * If no relation was passed we must open it to get access to
+ * its fields. If one of the other caches has already opened
+ * it we use heap_open() instead of heap_openr()
+ * ----------------
+ */
+ if (!RelationIsValid(relation))
+ {
+ struct catcache *cp;
+
+ /* ----------------
+ * scan the caches to see if any other cache has opened the relation
+ * ----------------
+ */
+ for (cp = Caches; cp; cp = cp->cc_next)
+ {
+ if (strncmp(cp->cc_relname, cache->cc_relname, NAMEDATALEN) == 0)
+ {
+ if (cp->relationId != InvalidOid)
+ break;
+ }
+ }
+
+ /* ----------------
+ * open the relation by name or by id
+ * ----------------
+ */
+ if (cp)
+ relation = heap_open(cp->relationId);
+ else
+ {
+ relation = heap_openr(cache->cc_relname);
+ }
+
+ didopen = 1;
}
-
+
/* ----------------
- * open the relation by name or by id
+ * initialize the cache's relation id
* ----------------
*/
- if (cp)
- relation = heap_open(cp->relationId);
- else
- {
- relation = heap_openr(cache->cc_relname);
- }
-
- didopen = 1;
- }
-
- /* ----------------
- * initialize the cache's relation id
- * ----------------
- */
- Assert(RelationIsValid(relation));
- cache->relationId = RelationGetRelationId(relation);
- tupdesc = cache->cc_tupdesc = RelationGetTupleDescriptor(relation);
-
- CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: relid %d, %d keys",
- cache->relationId, cache->cc_nkeys);
-
- /* ----------------
- * initialize cache's key information
- * ----------------
- */
- for (i = 0; i < cache->cc_nkeys; ++i) {
- CatalogCacheInitializeCache_DEBUG2;
-
- if (cache->cc_key[i] > 0) {
-
- /*
- * Yoiks. The implementation of the hashing code and the
- * implementation of int28's are at loggerheads. The right
- * thing to do is to throw out the implementation of int28's
- * altogether; until that happens, we do the right thing here
- * to guarantee that the hash key generator doesn't try to
- * dereference an int2 by mistake.
- */
-
- if (tupdesc->attrs[cache->cc_key[i]-1]->atttypid == INT28OID)
- cache->cc_klen[i] = sizeof (short);
- else
- cache->cc_klen[i] = tupdesc->attrs[cache->cc_key[i]-1]->attlen;
-
- cache->cc_skey[i].sk_procedure =
- EQPROC(tupdesc->attrs[cache->cc_key[i]-1]->atttypid);
-
- fmgr_info(cache->cc_skey[i].sk_procedure,
- (func_ptr *) &cache->cc_skey[i].sk_func,
- (int *) &cache->cc_skey[i].sk_nargs);
-
- CACHE5_elog(DEBUG, "CatalogCacheInit %16s %d %d %x",
- &relation->rd_rel->relname,
- i,
- tupdesc->attrs[ cache->cc_key[i]-1 ]->attlen,
- cache);
+ Assert(RelationIsValid(relation));
+ cache->relationId = RelationGetRelationId(relation);
+ tupdesc = cache->cc_tupdesc = RelationGetTupleDescriptor(relation);
+
+ CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: relid %d, %d keys",
+ cache->relationId, cache->cc_nkeys);
+
+ /* ----------------
+ * initialize cache's key information
+ * ----------------
+ */
+ for (i = 0; i < cache->cc_nkeys; ++i)
+ {
+ CatalogCacheInitializeCache_DEBUG2;
+
+ if (cache->cc_key[i] > 0)
+ {
+
+ /*
+ * Yoiks. The implementation of the hashing code and the
+ * implementation of int28's are at loggerheads. The right
+ * thing to do is to throw out the implementation of int28's
+ * altogether; until that happens, we do the right thing here
+ * to guarantee that the hash key generator doesn't try to
+ * dereference an int2 by mistake.
+ */
+
+ if (tupdesc->attrs[cache->cc_key[i] - 1]->atttypid == INT28OID)
+ cache->cc_klen[i] = sizeof(short);
+ else
+ cache->cc_klen[i] = tupdesc->attrs[cache->cc_key[i] - 1]->attlen;
+
+ cache->cc_skey[i].sk_procedure =
+ EQPROC(tupdesc->attrs[cache->cc_key[i] - 1]->atttypid);
+
+ fmgr_info(cache->cc_skey[i].sk_procedure,
+ (func_ptr *) & cache->cc_skey[i].sk_func,
+ (int *) &cache->cc_skey[i].sk_nargs);
+
+ CACHE5_elog(DEBUG, "CatalogCacheInit %16s %d %d %x",
+ &relation->rd_rel->relname,
+ i,
+ tupdesc->attrs[cache->cc_key[i] - 1]->attlen,
+ cache);
+ }
}
- }
-
- /* ----------------
- * close the relation if we opened it
- * ----------------
- */
- if (didopen)
- heap_close(relation);
-
- /* ----------------
- * initialize index information for the cache. this
- * should only be done once per cache.
- * ----------------
- */
- if (cache->cc_indname != NULL && cache->indexId == InvalidOid)
+
+ /* ----------------
+ * close the relation if we opened it
+ * ----------------
+ */
+ if (didopen)
+ heap_close(relation);
+
+ /* ----------------
+ * initialize index information for the cache. this
+ * should only be done once per cache.
+ * ----------------
+ */
+ if (cache->cc_indname != NULL && cache->indexId == InvalidOid)
{
- if (RelationGetRelationTupleForm(relation)->relhasindex)
+ if (RelationGetRelationTupleForm(relation)->relhasindex)
{
- /*
- * If the index doesn't exist we are in trouble.
- */
- relation = index_openr( cache->cc_indname);
- Assert(relation);
- cache->indexId = RelationGetRelationId(relation);
- index_close(relation);
+
+ /*
+ * If the index doesn't exist we are in trouble.
+ */
+ relation = index_openr(cache->cc_indname);
+ Assert(relation);
+ cache->indexId = RelationGetRelationId(relation);
+ index_close(relation);
}
- else
- cache->cc_indname = NULL;
+ else
+ cache->cc_indname = NULL;
}
-
- /* ----------------
- * return to the proper memory context
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
+
+ /* ----------------
+ * return to the proper memory context
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldcxt);
}
/* --------------------------------
- * CatalogCacheSetId
+ * CatalogCacheSetId
*
- * XXX temporary function
+ * XXX temporary function
* --------------------------------
*/
#ifdef NOT_USED
void
-CatalogCacheSetId(CatCache *cacheInOutP, int id)
+CatalogCacheSetId(CatCache * cacheInOutP, int id)
{
- Assert(id == InvalidCatalogCacheId || id >= 0);
- cacheInOutP->id = id;
+ Assert(id == InvalidCatalogCacheId || id >= 0);
+ cacheInOutP->id = id;
}
+
#endif
/* ----------------
* comphash --
- * Compute a hash value, somehow.
+ * Compute a hash value, somehow.
*
* XXX explain algorithm here.
*
@@ -279,798 +289,846 @@ CatalogCacheSetId(CatCache *cacheInOutP, int id)
static long
comphash(long l, register char *v)
{
- long i;
- NameData n;
-
- CACHE3_elog(DEBUG, "comphash (%d,%x)", l, v);
-
- switch (l) {
- case 1:
- case 2:
- case 4:
- return((long) v);
- }
-
- if (l == NAMEDATALEN) {
- /* if it's a name, make sure that the values
- are null-padded.
-
- Note that this other fixed-length types can also have
- the same typelen so this may break them - XXX
- */
- namestrcpy(&n,v);
- v = n.data;
- } else
- if (l < 0)
- l = VARSIZE(v);
-
- i = 0;
- while (l--) {
- i += *v++;
- }
- return(i);
+ long i;
+ NameData n;
+
+ CACHE3_elog(DEBUG, "comphash (%d,%x)", l, v);
+
+ switch (l)
+ {
+ case 1:
+ case 2:
+ case 4:
+ return ((long) v);
+ }
+
+ if (l == NAMEDATALEN)
+ {
+
+ /*
+ * if it's a name, make sure that the values are null-padded.
+ *
+ * Note that this other fixed-length types can also have the same
+ * typelen so this may break them - XXX
+ */
+ namestrcpy(&n, v);
+ v = n.data;
+ }
+ else if (l < 0)
+ l = VARSIZE(v);
+
+ i = 0;
+ while (l--)
+ {
+ i += *v++;
+ }
+ return (i);
}
/* --------------------------------
- * CatalogCacheComputeHashIndex
+ * CatalogCacheComputeHashIndex
* --------------------------------
*/
-static Index
-CatalogCacheComputeHashIndex(struct catcache *cacheInP)
+static Index
+CatalogCacheComputeHashIndex(struct catcache * cacheInP)
{
- Index hashIndex;
- hashIndex = 0x0;
- CACHE6_elog(DEBUG,"CatalogCacheComputeHashIndex %s %d %d %d %x",
- cacheInP->cc_relname,
- cacheInP->cc_nkeys,
- cacheInP->cc_klen[0],
- cacheInP->cc_klen[1],
- cacheInP);
-
- switch (cacheInP->cc_nkeys) {
- case 4:
- hashIndex ^= comphash(cacheInP->cc_klen[3],
- (char*)cacheInP->cc_skey[3].sk_argument) << 9;
- /* FALLTHROUGH */
- case 3:
- hashIndex ^= comphash(cacheInP->cc_klen[2],
- (char*)cacheInP->cc_skey[2].sk_argument) << 6;
- /* FALLTHROUGH */
- case 2:
- hashIndex ^= comphash(cacheInP->cc_klen[1],
- (char*)cacheInP->cc_skey[1].sk_argument) << 3;
- /* FALLTHROUGH */
- case 1:
- hashIndex ^= comphash(cacheInP->cc_klen[0],
- (char*)cacheInP->cc_skey[0].sk_argument);
- break;
- default:
- elog(FATAL, "CCComputeHashIndex: %d cc_nkeys", cacheInP->cc_nkeys);
- break;
- }
- hashIndex %= cacheInP->cc_size;
- return (hashIndex);
+ Index hashIndex;
+
+ hashIndex = 0x0;
+ CACHE6_elog(DEBUG, "CatalogCacheComputeHashIndex %s %d %d %d %x",
+ cacheInP->cc_relname,
+ cacheInP->cc_nkeys,
+ cacheInP->cc_klen[0],
+ cacheInP->cc_klen[1],
+ cacheInP);
+
+ switch (cacheInP->cc_nkeys)
+ {
+ case 4:
+ hashIndex ^= comphash(cacheInP->cc_klen[3],
+ (char *) cacheInP->cc_skey[3].sk_argument) << 9;
+ /* FALLTHROUGH */
+ case 3:
+ hashIndex ^= comphash(cacheInP->cc_klen[2],
+ (char *) cacheInP->cc_skey[2].sk_argument) << 6;
+ /* FALLTHROUGH */
+ case 2:
+ hashIndex ^= comphash(cacheInP->cc_klen[1],
+ (char *) cacheInP->cc_skey[1].sk_argument) << 3;
+ /* FALLTHROUGH */
+ case 1:
+ hashIndex ^= comphash(cacheInP->cc_klen[0],
+ (char *) cacheInP->cc_skey[0].sk_argument);
+ break;
+ default:
+ elog(FATAL, "CCComputeHashIndex: %d cc_nkeys", cacheInP->cc_nkeys);
+ break;
+ }
+ hashIndex %= cacheInP->cc_size;
+ return (hashIndex);
}
/* --------------------------------
- * CatalogCacheComputeTupleHashIndex
+ * CatalogCacheComputeTupleHashIndex
* --------------------------------
*/
-static Index
-CatalogCacheComputeTupleHashIndex(struct catcache *cacheInOutP,
- Relation relation,
- HeapTuple tuple)
+static Index
+CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP,
+ Relation relation,
+ HeapTuple tuple)
{
- bool isNull = '\0';
- if (cacheInOutP->relationId == InvalidOid)
- CatalogCacheInitializeCache(cacheInOutP, relation);
- switch (cacheInOutP->cc_nkeys) {
- case 4:
- cacheInOutP->cc_skey[3].sk_argument =
- (cacheInOutP->cc_key[3] == ObjectIdAttributeNumber)
- ? (Datum)tuple->t_oid
- : (Datum)fastgetattr(tuple,
- cacheInOutP->cc_key[3],
- RelationGetTupleDescriptor(relation),
- &isNull);
- Assert(!isNull);
- /* FALLTHROUGH */
- case 3:
- cacheInOutP->cc_skey[2].sk_argument =
- (cacheInOutP->cc_key[2] == ObjectIdAttributeNumber)
- ? (Datum)tuple->t_oid
- : (Datum)fastgetattr(tuple,
- cacheInOutP->cc_key[2],
- RelationGetTupleDescriptor(relation),
- &isNull);
- Assert(!isNull);
- /* FALLTHROUGH */
- case 2:
- cacheInOutP->cc_skey[1].sk_argument =
- (cacheInOutP->cc_key[1] == ObjectIdAttributeNumber)
- ? (Datum)tuple->t_oid
- : (Datum)fastgetattr(tuple,
- cacheInOutP->cc_key[1],
- RelationGetTupleDescriptor(relation),
- &isNull);
- Assert(!isNull);
- /* FALLTHROUGH */
- case 1:
- cacheInOutP->cc_skey[0].sk_argument =
- (cacheInOutP->cc_key[0] == ObjectIdAttributeNumber)
- ? (Datum)tuple->t_oid
- : (Datum)fastgetattr(tuple,
- cacheInOutP->cc_key[0],
- RelationGetTupleDescriptor(relation),
- &isNull);
- Assert(!isNull);
- break;
- default:
- elog(FATAL, "CCComputeTupleHashIndex: %d cc_nkeys",
- cacheInOutP->cc_nkeys
- );
- break;
- }
-
- return
- CatalogCacheComputeHashIndex(cacheInOutP);
+ bool isNull = '\0';
+
+ if (cacheInOutP->relationId == InvalidOid)
+ CatalogCacheInitializeCache(cacheInOutP, relation);
+ switch (cacheInOutP->cc_nkeys)
+ {
+ case 4:
+ cacheInOutP->cc_skey[3].sk_argument =
+ (cacheInOutP->cc_key[3] == ObjectIdAttributeNumber)
+ ? (Datum) tuple->t_oid
+ : (Datum) fastgetattr(tuple,
+ cacheInOutP->cc_key[3],
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+ Assert(!isNull);
+ /* FALLTHROUGH */
+ case 3:
+ cacheInOutP->cc_skey[2].sk_argument =
+ (cacheInOutP->cc_key[2] == ObjectIdAttributeNumber)
+ ? (Datum) tuple->t_oid
+ : (Datum) fastgetattr(tuple,
+ cacheInOutP->cc_key[2],
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+ Assert(!isNull);
+ /* FALLTHROUGH */
+ case 2:
+ cacheInOutP->cc_skey[1].sk_argument =
+ (cacheInOutP->cc_key[1] == ObjectIdAttributeNumber)
+ ? (Datum) tuple->t_oid
+ : (Datum) fastgetattr(tuple,
+ cacheInOutP->cc_key[1],
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+ Assert(!isNull);
+ /* FALLTHROUGH */
+ case 1:
+ cacheInOutP->cc_skey[0].sk_argument =
+ (cacheInOutP->cc_key[0] == ObjectIdAttributeNumber)
+ ? (Datum) tuple->t_oid
+ : (Datum) fastgetattr(tuple,
+ cacheInOutP->cc_key[0],
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+ Assert(!isNull);
+ break;
+ default:
+ elog(FATAL, "CCComputeTupleHashIndex: %d cc_nkeys",
+ cacheInOutP->cc_nkeys
+ );
+ break;
+ }
+
+ return
+ CatalogCacheComputeHashIndex(cacheInOutP);
}
/* --------------------------------
- * CatCacheRemoveCTup
+ * CatCacheRemoveCTup
* --------------------------------
*/
static void
-CatCacheRemoveCTup(CatCache *cache, Dlelem *elt)
+CatCacheRemoveCTup(CatCache * cache, Dlelem * elt)
{
- CatCTup *ct;
- CatCTup *other_ct;
- Dlelem *other_elt;
-
- if (elt)
- ct = (CatCTup*) DLE_VAL(elt);
- else
- return;
-
- other_elt = ct->ct_node;
- other_ct = (CatCTup*)DLE_VAL(other_elt);
- DLRemove(other_elt);
- DLFreeElem(other_elt);
- free(other_ct);
- DLRemove(elt);
- DLFreeElem(elt);
- free(ct);
- --cache->cc_ntup;
+ CatCTup *ct;
+ CatCTup *other_ct;
+ Dlelem *other_elt;
+
+ if (elt)
+ ct = (CatCTup *) DLE_VAL(elt);
+ else
+ return;
+
+ other_elt = ct->ct_node;
+ other_ct = (CatCTup *) DLE_VAL(other_elt);
+ DLRemove(other_elt);
+ DLFreeElem(other_elt);
+ free(other_ct);
+ DLRemove(elt);
+ DLFreeElem(elt);
+ free(ct);
+ --cache->cc_ntup;
}
/* --------------------------------
- * CatalogCacheIdInvalidate()
+ * CatalogCacheIdInvalidate()
*
- * Invalidate a tuple given a cache id. In this case the id should always
- * be found (whether the cache has opened its relation or not). Of course,
- * if the cache has yet to open its relation, there will be no tuples so
- * no problem.
+ * Invalidate a tuple given a cache id. In this case the id should always
+ * be found (whether the cache has opened its relation or not). Of course,
+ * if the cache has yet to open its relation, there will be no tuples so
+ * no problem.
* --------------------------------
*/
void
-CatalogCacheIdInvalidate(int cacheId, /* XXX */
- Index hashIndex,
- ItemPointer pointer)
+CatalogCacheIdInvalidate(int cacheId, /* XXX */
+ Index hashIndex,
+ ItemPointer pointer)
{
- CatCache *ccp;
- CatCTup *ct;
- Dlelem *elt;
- MemoryContext oldcxt;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(hashIndex < NCCBUCK);
- Assert(ItemPointerIsValid(pointer));
- CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: called");
-
- /* ----------------
- * switch to the cache context for our memory allocations
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * inspect every cache that could contain the tuple
- * ----------------
- */
- for (ccp = Caches; ccp; ccp = ccp->cc_next) {
- if (cacheId != ccp->id)
- continue;
+ CatCache *ccp;
+ CatCTup *ct;
+ Dlelem *elt;
+ MemoryContext oldcxt;
+
/* ----------------
- * inspect the hash bucket until we find a match or exhaust
+ * sanity checks
* ----------------
*/
- for (elt = DLGetHead(ccp->cc_cache[hashIndex]);
- elt;
- elt = DLGetSucc(elt))
- {
- ct = (CatCTup*) DLE_VAL(elt);
- if (ItemPointerEquals(pointer, &ct->ct_tup->t_ctid))
- break;
- }
-
+ Assert(hashIndex < NCCBUCK);
+ Assert(ItemPointerIsValid(pointer));
+ CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: called");
+
/* ----------------
- * if we found a matching tuple, invalidate it.
+ * switch to the cache context for our memory allocations
* ----------------
*/
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * inspect every cache that could contain the tuple
+ * ----------------
+ */
+ for (ccp = Caches; ccp; ccp = ccp->cc_next)
+ {
+ if (cacheId != ccp->id)
+ continue;
+ /* ----------------
+ * inspect the hash bucket until we find a match or exhaust
+ * ----------------
+ */
+ for (elt = DLGetHead(ccp->cc_cache[hashIndex]);
+ elt;
+ elt = DLGetSucc(elt))
+ {
+ ct = (CatCTup *) DLE_VAL(elt);
+ if (ItemPointerEquals(pointer, &ct->ct_tup->t_ctid))
+ break;
+ }
- if (elt) {
- CatCacheRemoveCTup(ccp, elt);
+ /* ----------------
+ * if we found a matching tuple, invalidate it.
+ * ----------------
+ */
- CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: invalidated");
+ if (elt)
+ {
+ CatCacheRemoveCTup(ccp, elt);
+
+ CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: invalidated");
+ }
+
+ if (cacheId != InvalidCatalogCacheId)
+ break;
}
-
- if (cacheId != InvalidCatalogCacheId)
- break;
- }
-
- /* ----------------
- * return to the proper memory context
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
- /* sendpm('I', "Invalidated tuple"); */
+
+ /* ----------------
+ * return to the proper memory context
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldcxt);
+ /* sendpm('I', "Invalidated tuple"); */
}
/* ----------------------------------------------------------------
- * public functions
+ * public functions
*
- * ResetSystemCache
- * InitIndexedSysCache
- * InitSysCache
- * SearchSysCache
- * RelationInvalidateCatalogCacheTuple
+ * ResetSystemCache
+ * InitIndexedSysCache
+ * InitSysCache
+ * SearchSysCache
+ * RelationInvalidateCatalogCacheTuple
* ----------------------------------------------------------------
*/
/* --------------------------------
- * ResetSystemCache
+ * ResetSystemCache
* --------------------------------
*/
void
ResetSystemCache()
{
- MemoryContext oldcxt;
- struct catcache *cache;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- CACHE1_elog(DEBUG, "ResetSystemCache called");
- if (DisableCache) {
- elog(WARN, "ResetSystemCache: Called while cache disabled");
- return;
- }
-
- /* ----------------
- * first switch to the cache context so our allocations
- * do not vanish at the end of a transaction
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * here we purge the contents of all the caches
- *
- * for each system cache
- * for each hash bucket
- * for each tuple in hash bucket
- * remove the tuple
- * ----------------
- */
- for (cache = Caches; PointerIsValid(cache); cache = cache->cc_next) {
- int hash;
- for (hash = 0; hash < NCCBUCK; hash += 1) {
- Dlelem *elt, *nextelt;
- for (elt = DLGetHead(cache->cc_cache[hash]); elt; elt = nextelt) {
- nextelt = DLGetSucc(elt);
- CatCacheRemoveCTup(cache, elt);
- if (cache->cc_ntup == -1)
- elog(WARN, "ResetSystemCache: cc_ntup<0 (software error)");
- }
+ MemoryContext oldcxt;
+ struct catcache *cache;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ CACHE1_elog(DEBUG, "ResetSystemCache called");
+ if (DisableCache)
+ {
+ elog(WARN, "ResetSystemCache: Called while cache disabled");
+ return;
+ }
+
+ /* ----------------
+ * first switch to the cache context so our allocations
+ * do not vanish at the end of a transaction
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * here we purge the contents of all the caches
+ *
+ * for each system cache
+ * for each hash bucket
+ * for each tuple in hash bucket
+ * remove the tuple
+ * ----------------
+ */
+ for (cache = Caches; PointerIsValid(cache); cache = cache->cc_next)
+ {
+ int hash;
+
+ for (hash = 0; hash < NCCBUCK; hash += 1)
+ {
+ Dlelem *elt,
+ *nextelt;
+
+ for (elt = DLGetHead(cache->cc_cache[hash]); elt; elt = nextelt)
+ {
+ nextelt = DLGetSucc(elt);
+ CatCacheRemoveCTup(cache, elt);
+ if (cache->cc_ntup == -1)
+ elog(WARN, "ResetSystemCache: cc_ntup<0 (software error)");
+ }
+ }
+ cache->cc_ntup = 0; /* in case of WARN error above */
}
- cache->cc_ntup = 0; /* in case of WARN error above */
- }
-
- CACHE1_elog(DEBUG, "end of ResetSystemCache call");
-
- /* ----------------
- * back to the old context before we return...
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
+
+ CACHE1_elog(DEBUG, "end of ResetSystemCache call");
+
+ /* ----------------
+ * back to the old context before we return...
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldcxt);
}
/* --------------------------------
- * InitIndexedSysCache
+ * InitIndexedSysCache
*
- * This allocates and initializes a cache for a system catalog relation.
- * Actually, the cache is only partially initialized to avoid opening the
- * relation. The relation will be opened and the rest of the cache
- * structure initialized on the first access.
+ * This allocates and initializes a cache for a system catalog relation.
+ * Actually, the cache is only partially initialized to avoid opening the
+ * relation. The relation will be opened and the rest of the cache
+ * structure initialized on the first access.
* --------------------------------
*/
#ifdef CACHEDEBUG
#define InitSysCache_DEBUG1 \
elog(DEBUG, "InitSysCache: rid=%d id=%d nkeys=%d size=%d\n", \
- cp->relationId, cp->id, cp->cc_nkeys, cp->cc_size); \
- for (i = 0; i < nkeys; i += 1) { \
- elog(DEBUG, "InitSysCache: key=%d len=%d skey=[%d %d %d %d]\n", \
- cp->cc_key[i], cp->cc_klen[i], \
- cp->cc_skey[i].sk_flags, \
- cp->cc_skey[i].sk_attno, \
- cp->cc_skey[i].sk_procedure, \
- cp->cc_skey[i].sk_argument); \
- }
+ cp->relationId, cp->id, cp->cc_nkeys, cp->cc_size); \
+ for (i = 0; i < nkeys; i += 1) { \
+ elog(DEBUG, "InitSysCache: key=%d len=%d skey=[%d %d %d %d]\n", \
+ cp->cc_key[i], cp->cc_klen[i], \
+ cp->cc_skey[i].sk_flags, \
+ cp->cc_skey[i].sk_attno, \
+ cp->cc_skey[i].sk_procedure, \
+ cp->cc_skey[i].sk_argument); \
+ }
#else
#define InitSysCache_DEBUG1
#endif
-CatCache*
+CatCache *
InitSysCache(char *relname,
- char *iname,
- int id,
- int nkeys,
- int key[],
- HeapTuple (*iScanfuncP)())
+ char *iname,
+ int id,
+ int nkeys,
+ int key[],
+ HeapTuple(*iScanfuncP) ())
{
- CatCache *cp;
- register int i;
- MemoryContext oldcxt;
-
- char *indname;
-
- indname = (iname) ? iname : NULL;
-
- /* ----------------
- * first switch to the cache context so our allocations
- * do not vanish at the end of a transaction
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * allocate a new cache structure
- * ----------------
- */
- cp = (CatCache *)palloc(sizeof(CatCache));
- memset((char*)cp, 0, sizeof(CatCache));
-
- /* ----------------
- * initialize the cache buckets (each bucket is a list header)
- * and the LRU tuple list
- * ----------------
- */
- {
- /*
- * We can only do this optimization because the number of hash
- * buckets never changes. Without it, we call malloc() too much.
- * We could move this to dllist.c, but the way we do this is not
- * dynamic/portabl, so why allow other routines to use it.
- */
- Dllist *cache_begin = malloc((NCCBUCK+1)*sizeof(Dllist));
- for (i = 0; i <= NCCBUCK; ++i) {
- cp->cc_cache[i] = &cache_begin[i];
- cp->cc_cache[i]->dll_head = 0;
- cp->cc_cache[i]->dll_tail = 0;
- }
- }
-
- cp->cc_lrulist = DLNewList();
-
- /* ----------------
- * Caches is the pointer to the head of the list of all the
- * system caches. here we add the new cache to the top of the list.
- * ----------------
- */
- cp->cc_next = Caches; /* list of caches (single link) */
- Caches = cp;
-
- /* ----------------
- * initialize the cache's relation information for the relation
- * corresponding to this cache and initialize some of the the new
- * cache's other internal fields.
- * ----------------
- */
- cp->relationId = InvalidOid;
- cp->indexId = InvalidOid;
- cp->cc_relname = relname;
- cp->cc_indname = indname;
- cp->cc_tupdesc = (TupleDesc) NULL;
- cp->id = id;
- cp->cc_maxtup = MAXTUP;
- cp->cc_size = NCCBUCK;
- cp->cc_nkeys = nkeys;
- cp->cc_iscanfunc = iScanfuncP;
-
- /* ----------------
- * initialize the cache's key information
- * ----------------
- */
- for (i = 0; i < nkeys; ++i) {
- cp->cc_key[i] = key[i];
- if (!key[i]) {
- elog(FATAL, "InitSysCache: called with 0 key[%d]", i);
- }
- if (key[i] < 0) {
- if (key[i] != ObjectIdAttributeNumber) {
- elog(FATAL, "InitSysCache: called with %d key[%d]", key[i], i);
- } else {
- cp->cc_klen[i] = sizeof(Oid);
+ CatCache *cp;
+ register int i;
+ MemoryContext oldcxt;
+
+ char *indname;
+
+ indname = (iname) ? iname : NULL;
+
+ /* ----------------
+ * first switch to the cache context so our allocations
+ * do not vanish at the end of a transaction
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * allocate a new cache structure
+ * ----------------
+ */
+ cp = (CatCache *) palloc(sizeof(CatCache));
+ memset((char *) cp, 0, sizeof(CatCache));
+
+ /* ----------------
+ * initialize the cache buckets (each bucket is a list header)
+ * and the LRU tuple list
+ * ----------------
+ */
+ {
+
/*
- * ScanKeyEntryData and struct skey are equivalent. It looks
- * like a move was made to obsolete struct skey, but it
- * didn't reach this file. Someday we should clean up this
- * code and consolidate to ScanKeyEntry - mer 10 Nov 1991
+ * We can only do this optimization because the number of hash
+ * buckets never changes. Without it, we call malloc() too much.
+ * We could move this to dllist.c, but the way we do this is not
+ * dynamic/portabl, so why allow other routines to use it.
*/
- ScanKeyEntryInitialize(&cp->cc_skey[i],
- (bits16)0,
- (AttrNumber)key[i],
- (RegProcedure)F_OIDEQ,
- (Datum)0);
- continue;
- }
+ Dllist *cache_begin = malloc((NCCBUCK + 1) * sizeof(Dllist));
+
+ for (i = 0; i <= NCCBUCK; ++i)
+ {
+ cp->cc_cache[i] = &cache_begin[i];
+ cp->cc_cache[i]->dll_head = 0;
+ cp->cc_cache[i]->dll_tail = 0;
+ }
+ }
+
+ cp->cc_lrulist = DLNewList();
+
+ /* ----------------
+ * Caches is the pointer to the head of the list of all the
+ * system caches. here we add the new cache to the top of the list.
+ * ----------------
+ */
+ cp->cc_next = Caches; /* list of caches (single link) */
+ Caches = cp;
+
+ /* ----------------
+ * initialize the cache's relation information for the relation
+ * corresponding to this cache and initialize some of the the new
+ * cache's other internal fields.
+ * ----------------
+ */
+ cp->relationId = InvalidOid;
+ cp->indexId = InvalidOid;
+ cp->cc_relname = relname;
+ cp->cc_indname = indname;
+ cp->cc_tupdesc = (TupleDesc) NULL;
+ cp->id = id;
+ cp->cc_maxtup = MAXTUP;
+ cp->cc_size = NCCBUCK;
+ cp->cc_nkeys = nkeys;
+ cp->cc_iscanfunc = iScanfuncP;
+
+ /* ----------------
+ * initialize the cache's key information
+ * ----------------
+ */
+ for (i = 0; i < nkeys; ++i)
+ {
+ cp->cc_key[i] = key[i];
+ if (!key[i])
+ {
+ elog(FATAL, "InitSysCache: called with 0 key[%d]", i);
+ }
+ if (key[i] < 0)
+ {
+ if (key[i] != ObjectIdAttributeNumber)
+ {
+ elog(FATAL, "InitSysCache: called with %d key[%d]", key[i], i);
+ }
+ else
+ {
+ cp->cc_klen[i] = sizeof(Oid);
+
+ /*
+ * ScanKeyEntryData and struct skey are equivalent. It
+ * looks like a move was made to obsolete struct skey, but
+ * it didn't reach this file. Someday we should clean up
+ * this code and consolidate to ScanKeyEntry - mer 10 Nov
+ * 1991
+ */
+ ScanKeyEntryInitialize(&cp->cc_skey[i],
+ (bits16) 0,
+ (AttrNumber) key[i],
+ (RegProcedure) F_OIDEQ,
+ (Datum) 0);
+ continue;
+ }
+ }
+
+ cp->cc_skey[i].sk_attno = key[i];
}
-
- cp->cc_skey[i].sk_attno = key[i];
- }
-
- /* ----------------
- * all done. new cache is initialized. print some debugging
- * information, if appropriate.
- * ----------------
- */
- InitSysCache_DEBUG1;
-
- /* ----------------
- * back to the old context before we return...
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
- return(cp);
+
+ /* ----------------
+ * all done. new cache is initialized. print some debugging
+ * information, if appropriate.
+ * ----------------
+ */
+ InitSysCache_DEBUG1;
+
+ /* ----------------
+ * back to the old context before we return...
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldcxt);
+ return (cp);
}
/* --------------------------------
- * SearchSysCache
+ * SearchSysCache
*
- * This call searches a system cache for a tuple, opening the relation
- * if necessary (the first access to a particular cache).
+ * This call searches a system cache for a tuple, opening the relation
+ * if necessary (the first access to a particular cache).
* --------------------------------
*/
HeapTuple
-SearchSysCache(struct catcache *cache,
- Datum v1,
- Datum v2,
- Datum v3,
- Datum v4)
+SearchSysCache(struct catcache * cache,
+ Datum v1,
+ Datum v2,
+ Datum v3,
+ Datum v4)
{
- unsigned hash;
- CatCTup *ct = NULL;
- CatCTup *nct;
- CatCTup *nct2;
- Dlelem *elt;
- HeapTuple ntp = 0;
- Buffer buffer;
-
- Relation relation;
- MemoryContext oldcxt;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- if (cache->relationId == InvalidOid)
- CatalogCacheInitializeCache(cache, NULL);
-
- /* ----------------
- * initialize the search key information
- * ----------------
- */
- cache->cc_skey[0].sk_argument = v1;
- cache->cc_skey[1].sk_argument = v2;
- cache->cc_skey[2].sk_argument = v3;
- cache->cc_skey[3].sk_argument = v4;
-
- /* ----------------
- * find the hash bucket in which to look for the tuple
- * ----------------
- */
- hash = CatalogCacheComputeHashIndex(cache);
-
- /* ----------------
- * scan the hash bucket until we find a match or exhaust our tuples
- * ----------------
- */
- for (elt = DLGetHead(cache->cc_cache[hash]);
- elt;
- elt = DLGetSucc(elt))
+ unsigned hash;
+ CatCTup *ct = NULL;
+ CatCTup *nct;
+ CatCTup *nct2;
+ Dlelem *elt;
+ HeapTuple ntp = 0;
+ Buffer buffer;
+
+ Relation relation;
+ MemoryContext oldcxt;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ if (cache->relationId == InvalidOid)
+ CatalogCacheInitializeCache(cache, NULL);
+
+ /* ----------------
+ * initialize the search key information
+ * ----------------
+ */
+ cache->cc_skey[0].sk_argument = v1;
+ cache->cc_skey[1].sk_argument = v2;
+ cache->cc_skey[2].sk_argument = v3;
+ cache->cc_skey[3].sk_argument = v4;
+
+ /* ----------------
+ * find the hash bucket in which to look for the tuple
+ * ----------------
+ */
+ hash = CatalogCacheComputeHashIndex(cache);
+
+ /* ----------------
+ * scan the hash bucket until we find a match or exhaust our tuples
+ * ----------------
+ */
+ for (elt = DLGetHead(cache->cc_cache[hash]);
+ elt;
+ elt = DLGetSucc(elt))
{
- ct = (CatCTup*)DLE_VAL(elt);
- /* ----------------
- * see if the cached tuple matches our key.
- * (should we be worried about time ranges? -cim 10/2/90)
- * ----------------
- */
- if (heap_keytest(ct->ct_tup,
- cache->cc_tupdesc,
- cache->cc_nkeys,
- cache->cc_skey))
- break;
+ ct = (CatCTup *) DLE_VAL(elt);
+ /* ----------------
+ * see if the cached tuple matches our key.
+ * (should we be worried about time ranges? -cim 10/2/90)
+ * ----------------
+ */
+ if (heap_keytest(ct->ct_tup,
+ cache->cc_tupdesc,
+ cache->cc_nkeys,
+ cache->cc_skey))
+ break;
}
-
- /* ----------------
- * if we found a tuple in the cache, move it to the top of the
- * lru list, and return it.
- * ----------------
- */
- if (elt) {
- Dlelem* old_lru_elt;
- old_lru_elt = ((CatCTup*)DLE_VAL(elt))->ct_node;
- DLRemove(old_lru_elt);
- DLAddHead(cache->cc_lrulist, old_lru_elt);
+
+ /* ----------------
+ * if we found a tuple in the cache, move it to the top of the
+ * lru list, and return it.
+ * ----------------
+ */
+ if (elt)
+ {
+ Dlelem *old_lru_elt;
+
+ old_lru_elt = ((CatCTup *) DLE_VAL(elt))->ct_node;
+ DLRemove(old_lru_elt);
+ DLAddHead(cache->cc_lrulist, old_lru_elt);
#ifdef CACHEDEBUG
+ relation = heap_open(cache->relationId);
+ CACHE3_elog(DEBUG, "SearchSysCache(%s): found in bucket %d",
+ RelationGetRelationName(relation), hash);
+ heap_close(relation);
+#endif /* CACHEDEBUG */
+
+ return (ct->ct_tup);
+ }
+
+ /* ----------------
+ * Tuple was not found in cache, so we have to try and
+ * retrieve it directly from the relation. If it's found,
+ * we add it to the cache. We must avoid recursion here,
+ * so we disable cache operations. If operations are
+ * currently disabled and we couldn't find the requested item
+ * in the cache, then this may be a recursive request, and we
+ * abort with an error.
+ * ----------------
+ */
+
+ if (DisableCache)
+ {
+ elog(WARN, "SearchSysCache: Called while cache disabled");
+ return ((HeapTuple) NULL);
+ }
+
+ /* ----------------
+ * open the relation associated with the cache
+ * ----------------
+ */
relation = heap_open(cache->relationId);
- CACHE3_elog(DEBUG, "SearchSysCache(%s): found in bucket %d",
- RelationGetRelationName(relation), hash);
- heap_close(relation);
-#endif /* CACHEDEBUG */
-
- return (ct->ct_tup);
- }
-
- /* ----------------
- * Tuple was not found in cache, so we have to try and
- * retrieve it directly from the relation. If it's found,
- * we add it to the cache. We must avoid recursion here,
- * so we disable cache operations. If operations are
- * currently disabled and we couldn't find the requested item
- * in the cache, then this may be a recursive request, and we
- * abort with an error.
- * ----------------
- */
-
- if (DisableCache) {
- elog(WARN, "SearchSysCache: Called while cache disabled");
- return((HeapTuple) NULL);
- }
-
- /* ----------------
- * open the relation associated with the cache
- * ----------------
- */
- relation = heap_open(cache->relationId);
- CACHE2_elog(DEBUG, "SearchSysCache(%s)",
- RelationGetRelationName(relation));
-
- /* ----------------
- * DisableCache and then switch to the cache memory context.
- * ----------------
- */
- DisableCache = 1;
-
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * Scan the relation to find the tuple. If there's an index, and
- * if this isn't bootstrap (initdb) time, use the index.
- * ----------------
- */
- CACHE2_elog(DEBUG, "SearchSysCache: performing scan (override==%d)",
- heapisoverride());
-
- if ((RelationGetRelationTupleForm(relation))->relhasindex
- && !IsBootstrapProcessingMode())
+ CACHE2_elog(DEBUG, "SearchSysCache(%s)",
+ RelationGetRelationName(relation));
+
+ /* ----------------
+ * DisableCache and then switch to the cache memory context.
+ * ----------------
+ */
+ DisableCache = 1;
+
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * Scan the relation to find the tuple. If there's an index, and
+ * if this isn't bootstrap (initdb) time, use the index.
+ * ----------------
+ */
+ CACHE2_elog(DEBUG, "SearchSysCache: performing scan (override==%d)",
+ heapisoverride());
+
+ if ((RelationGetRelationTupleForm(relation))->relhasindex
+ && !IsBootstrapProcessingMode())
{
- /* ----------
- * Switch back to old memory context so memory not freed
- * in the scan function will go away at transaction end.
- * wieck - 10/18/1996
- * ----------
- */
- MemoryContextSwitchTo(oldcxt);
- Assert(cache->cc_iscanfunc);
- switch(cache->cc_nkeys)
+ /* ----------
+ * Switch back to old memory context so memory not freed
+ * in the scan function will go away at transaction end.
+ * wieck - 10/18/1996
+ * ----------
+ */
+ MemoryContextSwitchTo(oldcxt);
+ Assert(cache->cc_iscanfunc);
+ switch (cache->cc_nkeys)
+ {
+ case 4:
+ ntp = cache->cc_iscanfunc(relation, v1, v2, v3, v4);
+ break;
+ case 3:
+ ntp = cache->cc_iscanfunc(relation, v1, v2, v3);
+ break;
+ case 2:
+ ntp = cache->cc_iscanfunc(relation, v1, v2);
+ break;
+ case 1:
+ ntp = cache->cc_iscanfunc(relation, v1);
+ break;
+ }
+ /* ----------
+ * Back to Cache context. If we got a tuple copy it
+ * into our context.
+ * wieck - 10/18/1996
+ * ----------
+ */
+ MemoryContextSwitchTo((MemoryContext) CacheCxt);
+ if (HeapTupleIsValid(ntp))
{
- case 4: ntp = cache->cc_iscanfunc(relation,v1,v2,v3,v4); break;
- case 3: ntp = cache->cc_iscanfunc(relation,v1,v2,v3); break;
- case 2: ntp = cache->cc_iscanfunc(relation,v1,v2); break;
- case 1: ntp = cache->cc_iscanfunc(relation,v1); break;
+ ntp = heap_copytuple(ntp);
}
- /* ----------
- * Back to Cache context. If we got a tuple copy it
- * into our context.
- * wieck - 10/18/1996
- * ----------
- */
- MemoryContextSwitchTo((MemoryContext)CacheCxt);
- if(HeapTupleIsValid(ntp)) {
- ntp = heap_copytuple(ntp);
- }
}
- else
+ else
{
- HeapScanDesc sd;
-
- /* ----------
- * As above do the lookup in the callers memory
- * context.
- * wieck - 10/18/1996
- * ----------
- */
- MemoryContextSwitchTo(oldcxt);
-
- sd = heap_beginscan(relation, 0, NowTimeQual,
- cache->cc_nkeys, cache->cc_skey);
-
- /* should this buffer be ReleaseBuffer'd? --djm 8/20/96 */
- ntp = heap_getnext(sd, 0, &buffer);
-
- MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- if (HeapTupleIsValid(ntp)) {
- CACHE1_elog(DEBUG, "SearchSysCache: found tuple");
- ntp = heap_copytuple(ntp);
- }
-
- MemoryContextSwitchTo(oldcxt);
-
- heap_endscan(sd);
-
- MemoryContextSwitchTo((MemoryContext)CacheCxt);
+ HeapScanDesc sd;
+
+ /* ----------
+ * As above do the lookup in the callers memory
+ * context.
+ * wieck - 10/18/1996
+ * ----------
+ */
+ MemoryContextSwitchTo(oldcxt);
+
+ sd = heap_beginscan(relation, 0, NowTimeQual,
+ cache->cc_nkeys, cache->cc_skey);
+
+ /* should this buffer be ReleaseBuffer'd? --djm 8/20/96 */
+ ntp = heap_getnext(sd, 0, &buffer);
+
+ MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ if (HeapTupleIsValid(ntp))
+ {
+ CACHE1_elog(DEBUG, "SearchSysCache: found tuple");
+ ntp = heap_copytuple(ntp);
+ }
+
+ MemoryContextSwitchTo(oldcxt);
+
+ heap_endscan(sd);
+
+ MemoryContextSwitchTo((MemoryContext) CacheCxt);
}
-
- DisableCache = 0;
-
- /* ----------------
- * scan is complete. if tup is valid, we copy it and add the copy to
- * the cache.
- * ----------------
- */
- if (HeapTupleIsValid(ntp)) {
+
+ DisableCache = 0;
+
/* ----------------
- * allocate a new cache tuple holder, store the pointer
- * to the heap tuple there and initialize the list pointers.
+ * scan is complete. if tup is valid, we copy it and add the copy to
+ * the cache.
* ----------------
*/
- Dlelem *lru_elt;
-
- /* this is a little cumbersome here because we want the Dlelem's
- in both doubly linked lists to point to one another.
- That makes it easier to remove something from both the cache bucket
- and the lru list at the same time */
- nct = (CatCTup*) malloc(sizeof(CatCTup));
- nct->ct_tup = ntp;
- elt = DLNewElem(nct);
- nct2 = (CatCTup*) malloc(sizeof(CatCTup));
- nct2->ct_tup = ntp;
- lru_elt = DLNewElem(nct2);
- nct2->ct_node = elt;
- nct->ct_node = lru_elt;
-
- DLAddHead(cache->cc_lrulist, lru_elt);
- DLAddHead(cache->cc_cache[hash], elt);
+ if (HeapTupleIsValid(ntp))
+ {
+ /* ----------------
+ * allocate a new cache tuple holder, store the pointer
+ * to the heap tuple there and initialize the list pointers.
+ * ----------------
+ */
+ Dlelem *lru_elt;
+
+ /*
+ * this is a little cumbersome here because we want the Dlelem's
+ * in both doubly linked lists to point to one another. That makes
+ * it easier to remove something from both the cache bucket and
+ * the lru list at the same time
+ */
+ nct = (CatCTup *) malloc(sizeof(CatCTup));
+ nct->ct_tup = ntp;
+ elt = DLNewElem(nct);
+ nct2 = (CatCTup *) malloc(sizeof(CatCTup));
+ nct2->ct_tup = ntp;
+ lru_elt = DLNewElem(nct2);
+ nct2->ct_node = elt;
+ nct->ct_node = lru_elt;
+
+ DLAddHead(cache->cc_lrulist, lru_elt);
+ DLAddHead(cache->cc_cache[hash], elt);
+
+ /* ----------------
+ * deal with hash bucket overflow
+ * ----------------
+ */
+ if (++cache->cc_ntup > cache->cc_maxtup)
+ {
+ CatCTup *ct;
+
+ elt = DLGetTail(cache->cc_lrulist);
+ ct = (CatCTup *) DLE_VAL(elt);
+
+ if (ct != nct)
+ {
+ CACHE2_elog(DEBUG, "SearchSysCache(%s): Overflow, LRU removal",
+ RelationGetRelationName(relation));
+
+ CatCacheRemoveCTup(cache, elt);
+
+ }
+ }
+
+ CACHE4_elog(DEBUG, "SearchSysCache(%s): Contains %d/%d tuples",
+ RelationGetRelationName(relation),
+ cache->cc_ntup, cache->cc_maxtup);
+ CACHE3_elog(DEBUG, "SearchSysCache(%s): put in bucket %d",
+ RelationGetRelationName(relation), hash);
+ }
/* ----------------
- * deal with hash bucket overflow
+ * close the relation, switch back to the original memory context
+ * and return the tuple we found (or NULL)
* ----------------
*/
- if (++cache->cc_ntup > cache->cc_maxtup) {
- CatCTup *ct;
- elt = DLGetTail(cache->cc_lrulist);
- ct = (CatCTup *) DLE_VAL(elt);
-
- if (ct != nct) {
- CACHE2_elog(DEBUG, "SearchSysCache(%s): Overflow, LRU removal",
- RelationGetRelationName(relation));
-
- CatCacheRemoveCTup(cache, elt);
-
- }
- }
-
- CACHE4_elog(DEBUG, "SearchSysCache(%s): Contains %d/%d tuples",
- RelationGetRelationName(relation),
- cache->cc_ntup, cache->cc_maxtup);
- CACHE3_elog(DEBUG, "SearchSysCache(%s): put in bucket %d",
- RelationGetRelationName(relation), hash);
- }
-
- /* ----------------
- * close the relation, switch back to the original memory context
- * and return the tuple we found (or NULL)
- * ----------------
- */
- heap_close(relation);
-
- MemoryContextSwitchTo(oldcxt);
- return ntp;
+ heap_close(relation);
+
+ MemoryContextSwitchTo(oldcxt);
+ return ntp;
}
/* --------------------------------
- * RelationInvalidateCatalogCacheTuple()
+ * RelationInvalidateCatalogCacheTuple()
*
- * Invalidate a tuple from a specific relation. This call determines the
- * cache in question and calls CatalogCacheIdInvalidate(). It is -ok-
- * if the relation cannot be found, it simply means this backend has yet
- * to open it.
+ * Invalidate a tuple from a specific relation. This call determines the
+ * cache in question and calls CatalogCacheIdInvalidate(). It is -ok-
+ * if the relation cannot be found, it simply means this backend has yet
+ * to open it.
* --------------------------------
*/
void
RelationInvalidateCatalogCacheTuple(Relation relation,
- HeapTuple tuple,
- void (*function)(int, Index, ItemPointer))
+ HeapTuple tuple,
+ void (*function) (int, Index, ItemPointer))
{
- struct catcache *ccp;
- MemoryContext oldcxt;
- Oid relationId;
-
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- Assert(HeapTupleIsValid(tuple));
- CACHE1_elog(DEBUG, "RelationInvalidateCatalogCacheTuple: called");
-
- /* ----------------
- * switch to the cache memory context
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * for each cache
- * if the cache contains tuples from the specified relation
- * call the invalidation function on the tuples
- * in the proper hash bucket
- * ----------------
- */
- relationId = RelationGetRelationId(relation);
-
- for (ccp = Caches; ccp; ccp = ccp->cc_next) {
- if (relationId != ccp->relationId)
- continue;
-
- /* OPT inline simplification of CatalogCacheIdInvalidate */
- if (!PointerIsValid(function)) {
- function = CatalogCacheIdInvalidate;
+ struct catcache *ccp;
+ MemoryContext oldcxt;
+ Oid relationId;
+
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ Assert(HeapTupleIsValid(tuple));
+ CACHE1_elog(DEBUG, "RelationInvalidateCatalogCacheTuple: called");
+
+ /* ----------------
+ * switch to the cache memory context
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * for each cache
+ * if the cache contains tuples from the specified relation
+ * call the invalidation function on the tuples
+ * in the proper hash bucket
+ * ----------------
+ */
+ relationId = RelationGetRelationId(relation);
+
+ for (ccp = Caches; ccp; ccp = ccp->cc_next)
+ {
+ if (relationId != ccp->relationId)
+ continue;
+
+ /* OPT inline simplification of CatalogCacheIdInvalidate */
+ if (!PointerIsValid(function))
+ {
+ function = CatalogCacheIdInvalidate;
+ }
+
+ (*function) (ccp->id,
+ CatalogCacheComputeTupleHashIndex(ccp, relation, tuple),
+ &tuple->t_ctid);
+
+ heap_close(relation);
}
-
- (*function)(ccp->id,
- CatalogCacheComputeTupleHashIndex(ccp, relation, tuple),
- &tuple->t_ctid);
-
- heap_close(relation);
- }
-
- /* ----------------
- * return to the proper memory context
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
-
- /* sendpm('I', "Invalidated tuple"); */
-}
+ /* ----------------
+ * return to the proper memory context
+ * ----------------
+ */
+ MemoryContextSwitchTo(oldcxt);
+
+ /* sendpm('I', "Invalidated tuple"); */
+}
diff --git a/src/backend/utils/cache/fcache.c b/src/backend/utils/cache/fcache.c
index 1d86364abda..ad174c6fdf5 100644
--- a/src/backend/utils/cache/fcache.c
+++ b/src/backend/utils/cache/fcache.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* fcache.c--
- * Code for the 'function cache' used in Oper and Func nodes....
+ * Code for the 'function cache' used in Oper and Func nodes....
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.4 1996/11/10 03:03:22 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.5 1997/09/07 04:52:59 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,23 +23,24 @@
#include "catalog/pg_proc.h"
#include "catalog/pg_language.h"
#include "catalog/pg_class.h"
-#include "parser/parsetree.h" /* for getrelname() */
+#include "parser/parsetree.h" /* for getrelname() */
#include "utils/builtins.h"
#include "utils/fcache.h"
#include "utils/fcache2.h"
#include "nodes/primnodes.h"
#include "nodes/execnodes.h"
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static Oid GetDynamicFuncArgType(Var *arg, ExprContext *econtext);
-static FunctionCachePtr init_fcache(Oid foid,
- bool use_syscache,
- List *argList,
- ExprContext *econtext);
+static Oid GetDynamicFuncArgType(Var * arg, ExprContext * econtext);
+static FunctionCachePtr
+init_fcache(Oid foid,
+ bool use_syscache,
+ List * argList,
+ ExprContext * econtext);
/*-----------------------------------------------------------------
*
@@ -47,259 +48,269 @@ static FunctionCachePtr init_fcache(Oid foid,
*
*
* NOTE: This function can be called when the system cache is being
- * initialized. Therefore, use_syscache should ONLY be true
- * when the function return type is interesting (ie: set_fcache).
+ * initialized. Therefore, use_syscache should ONLY be true
+ * when the function return type is interesting (ie: set_fcache).
*-----------------------------------------------------------------
*/
#define FuncArgTypeIsDynamic(arg) \
- (IsA(arg,Var) && ((Var*)arg)->varattno == InvalidAttrNumber)
+ (IsA(arg,Var) && ((Var*)arg)->varattno == InvalidAttrNumber)
-static Oid
-GetDynamicFuncArgType(Var *arg, ExprContext *econtext)
+static Oid
+GetDynamicFuncArgType(Var * arg, ExprContext * econtext)
{
- char *relname;
- int rtid;
- HeapTuple tup;
-
- Assert(IsA(arg,Var));
-
- rtid = ((Var*)arg)->varno;
- relname = (char*)getrelname(rtid, econtext->ecxt_range_table);
-
-
- tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(relname),
- 0,0,0);
- if (!tup)
- elog(WARN, "Lookup failed on type tuple for class %s",
- relname);
-
- return tup->t_oid;
+ char *relname;
+ int rtid;
+ HeapTuple tup;
+
+ Assert(IsA(arg, Var));
+
+ rtid = ((Var *) arg)->varno;
+ relname = (char *) getrelname(rtid, econtext->ecxt_range_table);
+
+
+ tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(relname),
+ 0, 0, 0);
+ if (!tup)
+ elog(WARN, "Lookup failed on type tuple for class %s",
+ relname);
+
+ return tup->t_oid;
}
-static FunctionCachePtr
+static FunctionCachePtr
init_fcache(Oid foid,
- bool use_syscache,
- List *argList,
- ExprContext *econtext)
+ bool use_syscache,
+ List * argList,
+ ExprContext * econtext)
{
- HeapTuple procedureTuple;
- HeapTuple typeTuple;
- Form_pg_proc procedureStruct;
- TypeTupleForm typeStruct;
- FunctionCachePtr retval;
- text *tmp;
- int nargs;
-
- /* ----------------
- * get the procedure tuple corresponding to the given
- * functionOid. If this fails, returnValue has been
- * pre-initialized to "null" so we just return it.
- * ----------------
- */
- retval = (FunctionCachePtr) palloc(sizeof(FunctionCache));
-
- if (!use_syscache)
- elog(WARN, "what the ????, init the fcache without the catalogs?");
-
- procedureTuple = SearchSysCacheTuple(PROOID,
- ObjectIdGetDatum(foid),
- 0,0,0);
-
- if (!HeapTupleIsValid(procedureTuple))
- elog(WARN,
- "init_fcache: %s %d",
- "Cache lookup failed for procedure", foid);
-
- /* ----------------
- * get the return type from the procedure tuple
- * ----------------
- */
- procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
-
- /* ----------------
- * get the type tuple corresponding to the return type
- * If this fails, returnValue has been pre-initialized
- * to "null" so we just return it.
- * ----------------
- */
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(procedureStruct->prorettype),
- 0,0,0);
-
- if (!HeapTupleIsValid(typeTuple))
- elog(WARN,
- "init_fcache: %s %d",
- "Cache lookup failed for type",
- (procedureStruct)->prorettype);
-
- /* ----------------
- * get the type length and by-value from the type tuple and
- * save the information in our one element cache.
- * ----------------
- */
- typeStruct = (TypeTupleForm) GETSTRUCT(typeTuple);
-
- retval->typlen = (typeStruct)->typlen;
- if ((typeStruct)->typrelid == InvalidOid) {
- /* The return type is not a relation, so just use byval */
- retval->typbyval = (typeStruct)->typbyval ? true : false ;
- } else {
- /* This is a hack. We assume here that any function returning
- * a relation returns it by reference. This needs to be
- * fixed.
+ HeapTuple procedureTuple;
+ HeapTuple typeTuple;
+ Form_pg_proc procedureStruct;
+ TypeTupleForm typeStruct;
+ FunctionCachePtr retval;
+ text *tmp;
+ int nargs;
+
+ /* ----------------
+ * get the procedure tuple corresponding to the given
+ * functionOid. If this fails, returnValue has been
+ * pre-initialized to "null" so we just return it.
+ * ----------------
+ */
+ retval = (FunctionCachePtr) palloc(sizeof(FunctionCache));
+
+ if (!use_syscache)
+ elog(WARN, "what the ????, init the fcache without the catalogs?");
+
+ procedureTuple = SearchSysCacheTuple(PROOID,
+ ObjectIdGetDatum(foid),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(procedureTuple))
+ elog(WARN,
+ "init_fcache: %s %d",
+ "Cache lookup failed for procedure", foid);
+
+ /* ----------------
+ * get the return type from the procedure tuple
+ * ----------------
+ */
+ procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
+
+ /* ----------------
+ * get the type tuple corresponding to the return type
+ * If this fails, returnValue has been pre-initialized
+ * to "null" so we just return it.
+ * ----------------
+ */
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(procedureStruct->prorettype),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(typeTuple))
+ elog(WARN,
+ "init_fcache: %s %d",
+ "Cache lookup failed for type",
+ (procedureStruct)->prorettype);
+
+ /* ----------------
+ * get the type length and by-value from the type tuple and
+ * save the information in our one element cache.
+ * ----------------
*/
- retval->typbyval = false;
- }
- retval->foid = foid;
- retval->language = procedureStruct->prolang;
- retval->func_state = (char *)NULL;
- retval->setArg = NULL;
- retval->hasSetArg = false;
- retval->oneResult = ! procedureStruct->proretset;
- retval->istrusted = procedureStruct->proistrusted;
-
- /*
- * If we are returning exactly one result then we have to copy
- * tuples and by reference results because we have to end the execution
- * before we return the results. When you do this everything allocated
- * by the executor (i.e. slots and tuples) is freed.
- */
- if ((retval->language == SQLlanguageId) &&
- (retval->oneResult) &&
- !(retval->typbyval))
+ typeStruct = (TypeTupleForm) GETSTRUCT(typeTuple);
+
+ retval->typlen = (typeStruct)->typlen;
+ if ((typeStruct)->typrelid == InvalidOid)
+ {
+ /* The return type is not a relation, so just use byval */
+ retval->typbyval = (typeStruct)->typbyval ? true : false;
+ }
+ else
{
- Form_pg_class relationStruct;
- HeapTuple relationTuple;
- TupleDesc td;
- TupleTableSlot *slot;
-
- slot = makeNode(TupleTableSlot);
- slot->ttc_shouldFree = true;
- slot->ttc_descIsNew = true;
- slot->ttc_tupleDescriptor = (TupleDesc) NULL;
- slot->ttc_buffer = InvalidBuffer;
- slot->ttc_whichplan = -1;
- retval->funcSlot = (Pointer)slot;
-
- relationTuple = (HeapTuple)
- SearchSysCacheTuple(RELNAME,
- PointerGetDatum(&typeStruct->typname),
- 0,0,0);
-
- if (relationTuple)
+
+ /*
+ * This is a hack. We assume here that any function returning a
+ * relation returns it by reference. This needs to be fixed.
+ */
+ retval->typbyval = false;
+ }
+ retval->foid = foid;
+ retval->language = procedureStruct->prolang;
+ retval->func_state = (char *) NULL;
+ retval->setArg = NULL;
+ retval->hasSetArg = false;
+ retval->oneResult = !procedureStruct->proretset;
+ retval->istrusted = procedureStruct->proistrusted;
+
+ /*
+ * If we are returning exactly one result then we have to copy tuples
+ * and by reference results because we have to end the execution
+ * before we return the results. When you do this everything
+ * allocated by the executor (i.e. slots and tuples) is freed.
+ */
+ if ((retval->language == SQLlanguageId) &&
+ (retval->oneResult) &&
+ !(retval->typbyval))
+ {
+ Form_pg_class relationStruct;
+ HeapTuple relationTuple;
+ TupleDesc td;
+ TupleTableSlot *slot;
+
+ slot = makeNode(TupleTableSlot);
+ slot->ttc_shouldFree = true;
+ slot->ttc_descIsNew = true;
+ slot->ttc_tupleDescriptor = (TupleDesc) NULL;
+ slot->ttc_buffer = InvalidBuffer;
+ slot->ttc_whichplan = -1;
+ retval->funcSlot = (Pointer) slot;
+
+ relationTuple = (HeapTuple)
+ SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(&typeStruct->typname),
+ 0, 0, 0);
+
+ if (relationTuple)
{
- relationStruct = (Form_pg_class)GETSTRUCT(relationTuple);
- td = CreateTemplateTupleDesc(relationStruct->relnatts);
+ relationStruct = (Form_pg_class) GETSTRUCT(relationTuple);
+ td = CreateTemplateTupleDesc(relationStruct->relnatts);
}
- else
- td = CreateTemplateTupleDesc(1);
-
- ((TupleTableSlot*)retval->funcSlot)->ttc_tupleDescriptor = td;
+ else
+ td = CreateTemplateTupleDesc(1);
+
+ ((TupleTableSlot *) retval->funcSlot)->ttc_tupleDescriptor = td;
}
- else
- retval->funcSlot = (char *)NULL;
-
- nargs = procedureStruct->pronargs;
- retval->nargs = nargs;
-
- if (nargs > 0)
+ else
+ retval->funcSlot = (char *) NULL;
+
+ nargs = procedureStruct->pronargs;
+ retval->nargs = nargs;
+
+ if (nargs > 0)
{
- Oid *argTypes;
-
- retval->nullVect = (bool *)palloc((retval->nargs)*sizeof(bool));
-
- if (retval->language == SQLlanguageId)
+ Oid *argTypes;
+
+ retval->nullVect = (bool *) palloc((retval->nargs) * sizeof(bool));
+
+ if (retval->language == SQLlanguageId)
{
- int i;
- List *oneArg;
-
- retval->argOidVect =
- (Oid *)palloc(retval->nargs*sizeof(Oid));
- argTypes = procedureStruct->proargtypes;
- memmove(retval->argOidVect,
- argTypes,
- (retval->nargs)*sizeof(Oid));
-
- for (i=0;
- argList;
- i++, argList = lnext(argList))
+ int i;
+ List *oneArg;
+
+ retval->argOidVect =
+ (Oid *) palloc(retval->nargs * sizeof(Oid));
+ argTypes = procedureStruct->proargtypes;
+ memmove(retval->argOidVect,
+ argTypes,
+ (retval->nargs) * sizeof(Oid));
+
+ for (i = 0;
+ argList;
+ i++, argList = lnext(argList))
{
- oneArg = lfirst(argList);
- if (FuncArgTypeIsDynamic(oneArg))
- retval->argOidVect[i] = GetDynamicFuncArgType((Var*)oneArg,
- econtext);
+ oneArg = lfirst(argList);
+ if (FuncArgTypeIsDynamic(oneArg))
+ retval->argOidVect[i] = GetDynamicFuncArgType((Var *) oneArg,
+ econtext);
}
}
- else
- retval->argOidVect = (Oid *)NULL;
+ else
+ retval->argOidVect = (Oid *) NULL;
}
- else
+ else
{
- retval->argOidVect = (Oid *)NULL;
- retval->nullVect = (BoolPtr)NULL;
+ retval->argOidVect = (Oid *) NULL;
+ retval->nullVect = (BoolPtr) NULL;
}
-
- /*
- * XXX this is the first varlena in the struct. If the order
- * changes for some reason this will fail.
- */
- if (procedureStruct->prolang == SQLlanguageId)
+
+ /*
+ * XXX this is the first varlena in the struct. If the order changes
+ * for some reason this will fail.
+ */
+ if (procedureStruct->prolang == SQLlanguageId)
{
- retval->src = textout(&(procedureStruct->prosrc));
- retval->bin = (char *) NULL;
+ retval->src = textout(&(procedureStruct->prosrc));
+ retval->bin = (char *) NULL;
}
- else
+ else
{
-
- /*
- * I'm not sure that we even need to do this at all.
- */
-
- /*
- * We do for untrusted functions.
- */
-
- if (procedureStruct->proistrusted)
- retval->bin = (char *) NULL;
- else {
- tmp = (text *)
- SearchSysCacheGetAttribute(PROOID,
- Anum_pg_proc_probin,
- ObjectIdGetDatum(foid),
- 0,0,0);
- retval->bin = textout(tmp);
- }
- retval->src = (char *) NULL;
+
+ /*
+ * I'm not sure that we even need to do this at all.
+ */
+
+ /*
+ * We do for untrusted functions.
+ */
+
+ if (procedureStruct->proistrusted)
+ retval->bin = (char *) NULL;
+ else
+ {
+ tmp = (text *)
+ SearchSysCacheGetAttribute(PROOID,
+ Anum_pg_proc_probin,
+ ObjectIdGetDatum(foid),
+ 0, 0, 0);
+ retval->bin = textout(tmp);
+ }
+ retval->src = (char *) NULL;
}
-
-
-
-
- if (retval->language != SQLlanguageId)
- fmgr_info(foid, &(retval->func), &(retval->nargs));
- else
- retval->func = (func_ptr)NULL;
-
-
- return(retval);
+
+
+
+
+ if (retval->language != SQLlanguageId)
+ fmgr_info(foid, &(retval->func), &(retval->nargs));
+ else
+ retval->func = (func_ptr) NULL;
+
+
+ return (retval);
}
void
-setFcache(Node *node, Oid foid, List *argList, ExprContext *econtext)
+setFcache(Node * node, Oid foid, List * argList, ExprContext * econtext)
{
- Func *fnode;
- Oper *onode;
- FunctionCachePtr fcache;
-
- fcache = init_fcache(foid, true, argList, econtext);
-
- if (IsA(node,Oper)) {
- onode = (Oper*) node;
- onode->op_fcache = fcache;
- }else if (IsA(node,Func)) {
- fnode = (Func*) node;
- fnode->func_fcache = fcache;
- }else {
- elog(WARN, "init_fcache: node must be Oper or Func!");
- }
+ Func *fnode;
+ Oper *onode;
+ FunctionCachePtr fcache;
+
+ fcache = init_fcache(foid, true, argList, econtext);
+
+ if (IsA(node, Oper))
+ {
+ onode = (Oper *) node;
+ onode->op_fcache = fcache;
+ }
+ else if (IsA(node, Func))
+ {
+ fnode = (Func *) node;
+ fnode->func_fcache = fcache;
+ }
+ else
+ {
+ elog(WARN, "init_fcache: node must be Oper or Func!");
+ }
}
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index 4f52e4e5f4c..4fb8a5eb6ed 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* inval.c--
- * POSTGRES cache invalidation dispatcher code.
+ * POSTGRES cache invalidation dispatcher code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.4 1997/08/19 21:35:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.5 1997/09/07 04:53:01 momjian Exp $
*
* Note - this code is real crufty...
*
@@ -17,11 +17,11 @@
#include <miscadmin.h>
-#include "access/heapam.h" /* XXX to support hacks below */
+#include "access/heapam.h" /* XXX to support hacks below */
#include "access/htup.h"
#include "catalog/catalog.h"
#include "storage/bufpage.h"
-#include "storage/buf.h" /* XXX for InvalidBuffer */
+#include "storage/buf.h" /* XXX for InvalidBuffer */
#include "storage/ipc.h"
#include "storage/sinval.h"
#include "utils/catcache.h"
@@ -29,593 +29,615 @@
#include "utils/rel.h"
#include "utils/relcache.h"
#include "catalog/catname.h" /* XXX to support hacks below */
-#include "utils/syscache.h" /* XXX to support the hacks below */
+#include "utils/syscache.h" /* XXX to support the hacks below */
static InvalidationEntry InvalidationEntryAllocate(uint16 size);
-static void LocalInvalidInvalidate(LocalInvalid invalid, void (*function)());
-static LocalInvalid LocalInvalidRegister(LocalInvalid invalid,
+static void LocalInvalidInvalidate(LocalInvalid invalid, void (*function) ());
+static LocalInvalid
+LocalInvalidRegister(LocalInvalid invalid,
InvalidationEntry entry);
-static void getmyrelids(void);
+static void getmyrelids(void);
/* ----------------
- * private invalidation structures
+ * private invalidation structures
* ----------------
*/
-typedef struct CatalogInvalidationData {
- Index cacheId;
- Index hashIndex;
- ItemPointerData pointerData;
-} CatalogInvalidationData;
+typedef struct CatalogInvalidationData
+{
+ Index cacheId;
+ Index hashIndex;
+ ItemPointerData pointerData;
+} CatalogInvalidationData;
-typedef struct RelationInvalidationData {
- Oid relationId;
- Oid objectId;
-} RelationInvalidationData;
+typedef struct RelationInvalidationData
+{
+ Oid relationId;
+ Oid objectId;
+} RelationInvalidationData;
-typedef union AnyInvalidation {
- CatalogInvalidationData catalog;
- RelationInvalidationData relation;
-} AnyInvalidation;
+typedef union AnyInvalidation
+{
+ CatalogInvalidationData catalog;
+ RelationInvalidationData relation;
+} AnyInvalidation;
-typedef struct InvalidationMessageData {
- char kind;
- AnyInvalidation any;
-} InvalidationMessageData;
+typedef struct InvalidationMessageData
+{
+ char kind;
+ AnyInvalidation any;
+} InvalidationMessageData;
-typedef InvalidationMessageData *InvalidationMessage;
+typedef InvalidationMessageData *InvalidationMessage;
/* ----------------
- * variables and macros
+ * variables and macros
* ----------------
*/
-static LocalInvalid Invalid = EmptyLocalInvalid; /* XXX global */
-static bool RefreshWhenInvalidate = false;
+static LocalInvalid Invalid = EmptyLocalInvalid; /* XXX global */
+static bool RefreshWhenInvalidate = false;
-Oid MyRelationRelationId = InvalidOid;
-Oid MyAttributeRelationId = InvalidOid;
-Oid MyAMRelationId = InvalidOid;
-Oid MyAMOPRelationId = InvalidOid;
+Oid MyRelationRelationId = InvalidOid;
+Oid MyAttributeRelationId = InvalidOid;
+Oid MyAMRelationId = InvalidOid;
+Oid MyAMOPRelationId = InvalidOid;
#define ValidateHacks() \
- if (!OidIsValid(MyRelationRelationId)) getmyrelids()
+ if (!OidIsValid(MyRelationRelationId)) getmyrelids()
/* ----------------------------------------------------------------
- * "local" invalidation support functions
+ * "local" invalidation support functions
* ----------------------------------------------------------------
*/
/* --------------------------------
- * InvalidationEntryAllocate--
- * Allocates an invalidation entry.
+ * InvalidationEntryAllocate--
+ * Allocates an invalidation entry.
* --------------------------------
*/
-static InvalidationEntry
+static InvalidationEntry
InvalidationEntryAllocate(uint16 size)
{
- InvalidationEntryData *entryDataP;
- entryDataP = (InvalidationEntryData *)
- malloc(sizeof (char *) + size); /* XXX alignment */
- entryDataP->nextP = NULL;
- return ((Pointer) &entryDataP->userData);
+ InvalidationEntryData *entryDataP;
+
+ entryDataP = (InvalidationEntryData *)
+ malloc(sizeof(char *) + size); /* XXX alignment */
+ entryDataP->nextP = NULL;
+ return ((Pointer) & entryDataP->userData);
}
/* --------------------------------
- * LocalInvalidRegister --
- * Returns a new local cache invalidation state containing a new entry.
+ * LocalInvalidRegister --
+ * Returns a new local cache invalidation state containing a new entry.
* --------------------------------
*/
-static LocalInvalid
+static LocalInvalid
LocalInvalidRegister(LocalInvalid invalid,
- InvalidationEntry entry)
+ InvalidationEntry entry)
{
- Assert(PointerIsValid(entry));
-
- ((InvalidationUserData *)entry)->dataP[-1] =
- (InvalidationUserData *)invalid;
-
- return (entry);
+ Assert(PointerIsValid(entry));
+
+ ((InvalidationUserData *) entry)->dataP[-1] =
+ (InvalidationUserData *) invalid;
+
+ return (entry);
}
/* --------------------------------
- * LocalInvalidInvalidate--
- * Processes, then frees all entries in a local cache
- * invalidation state.
+ * LocalInvalidInvalidate--
+ * Processes, then frees all entries in a local cache
+ * invalidation state.
* --------------------------------
*/
static void
-LocalInvalidInvalidate(LocalInvalid invalid, void (*function)())
+LocalInvalidInvalidate(LocalInvalid invalid, void (*function) ())
{
- InvalidationEntryData *entryDataP;
-
- while (PointerIsValid(invalid)) {
- entryDataP = (InvalidationEntryData *)
- &((InvalidationUserData *)invalid)->dataP[-1];
-
- if (PointerIsValid(function)) {
- (*function)((Pointer) &entryDataP->userData);
+ InvalidationEntryData *entryDataP;
+
+ while (PointerIsValid(invalid))
+ {
+ entryDataP = (InvalidationEntryData *)
+ & ((InvalidationUserData *) invalid)->dataP[-1];
+
+ if (PointerIsValid(function))
+ {
+ (*function) ((Pointer) & entryDataP->userData);
+ }
+
+ invalid = (Pointer) entryDataP->nextP;
+
+ /* help catch errors */
+ entryDataP->nextP = (InvalidationUserData *) NULL;
+
+ free((Pointer) entryDataP);
}
-
- invalid = (Pointer) entryDataP->nextP;
-
- /* help catch errors */
- entryDataP->nextP = (InvalidationUserData *) NULL;
-
- free((Pointer)entryDataP);
- }
}
/* ----------------------------------------------------------------
- * private support functions
+ * private support functions
* ----------------------------------------------------------------
*/
/* --------------------------------
- * CacheIdRegisterLocalInvalid
+ * CacheIdRegisterLocalInvalid
* --------------------------------
*/
#ifdef INVALIDDEBUG
#define CacheIdRegisterLocalInvalid_DEBUG1 \
elog(DEBUG, "CacheIdRegisterLocalInvalid(%d, %d, [%d, %d])", \
- cacheId, hashIndex, ItemPointerGetBlockNumber(pointer), \
- ItemPointerGetOffsetNumber(pointer))
+ cacheId, hashIndex, ItemPointerGetBlockNumber(pointer), \
+ ItemPointerGetOffsetNumber(pointer))
#else
#define CacheIdRegisterLocalInvalid_DEBUG1
-#endif /* INVALIDDEBUG */
-
+#endif /* INVALIDDEBUG */
+
static void
CacheIdRegisterLocalInvalid(Index cacheId,
- Index hashIndex,
- ItemPointer pointer)
+ Index hashIndex,
+ ItemPointer pointer)
{
- InvalidationMessage message;
-
- /* ----------------
- * debugging stuff
- * ----------------
- */
- CacheIdRegisterLocalInvalid_DEBUG1;
-
- /* ----------------
- * create a message describing the system catalog tuple
- * we wish to invalidate.
- * ----------------
- */
- message = (InvalidationMessage)
- InvalidationEntryAllocate(sizeof (InvalidationMessageData));
-
- message->kind = 'c';
- message->any.catalog.cacheId = cacheId;
- message->any.catalog.hashIndex = hashIndex;
-
- ItemPointerCopy(pointer, &message->any.catalog.pointerData);
-
- /* ----------------
- * Note: Invalid is a global variable
- * ----------------
- */
- Invalid = LocalInvalidRegister(Invalid, (InvalidationEntry)message);
+ InvalidationMessage message;
+
+ /* ----------------
+ * debugging stuff
+ * ----------------
+ */
+ CacheIdRegisterLocalInvalid_DEBUG1;
+
+ /* ----------------
+ * create a message describing the system catalog tuple
+ * we wish to invalidate.
+ * ----------------
+ */
+ message = (InvalidationMessage)
+ InvalidationEntryAllocate(sizeof(InvalidationMessageData));
+
+ message->kind = 'c';
+ message->any.catalog.cacheId = cacheId;
+ message->any.catalog.hashIndex = hashIndex;
+
+ ItemPointerCopy(pointer, &message->any.catalog.pointerData);
+
+ /* ----------------
+ * Note: Invalid is a global variable
+ * ----------------
+ */
+ Invalid = LocalInvalidRegister(Invalid, (InvalidationEntry) message);
}
/* --------------------------------
- * RelationIdRegisterLocalInvalid
+ * RelationIdRegisterLocalInvalid
* --------------------------------
*/
static void
RelationIdRegisterLocalInvalid(Oid relationId, Oid objectId)
{
- InvalidationMessage message;
-
- /* ----------------
- * debugging stuff
- * ----------------
- */
+ InvalidationMessage message;
+
+ /* ----------------
+ * debugging stuff
+ * ----------------
+ */
#ifdef INVALIDDEBUG
- elog(DEBUG, "RelationRegisterLocalInvalid(%d, %d)", relationId,
- objectId);
-#endif /* defined(INVALIDDEBUG) */
-
- /* ----------------
- * create a message describing the relation descriptor
- * we wish to invalidate.
- * ----------------
- */
- message = (InvalidationMessage)
- InvalidationEntryAllocate(sizeof (InvalidationMessageData));
-
- message->kind = 'r';
- message->any.relation.relationId = relationId;
- message->any.relation.objectId = objectId;
-
- /* ----------------
- * Note: Invalid is a global variable
- * ----------------
- */
- Invalid = LocalInvalidRegister(Invalid, (InvalidationEntry)message);
+ elog(DEBUG, "RelationRegisterLocalInvalid(%d, %d)", relationId,
+ objectId);
+#endif /* defined(INVALIDDEBUG) */
+
+ /* ----------------
+ * create a message describing the relation descriptor
+ * we wish to invalidate.
+ * ----------------
+ */
+ message = (InvalidationMessage)
+ InvalidationEntryAllocate(sizeof(InvalidationMessageData));
+
+ message->kind = 'r';
+ message->any.relation.relationId = relationId;
+ message->any.relation.objectId = objectId;
+
+ /* ----------------
+ * Note: Invalid is a global variable
+ * ----------------
+ */
+ Invalid = LocalInvalidRegister(Invalid, (InvalidationEntry) message);
}
/* --------------------------------
- * getmyrelids
+ * getmyrelids
* --------------------------------
*/
static void
getmyrelids()
{
- HeapTuple tuple;
-
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(RelationRelationName),
- 0,0,0);
- Assert(HeapTupleIsValid(tuple));
- MyRelationRelationId = tuple->t_oid;
-
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(AttributeRelationName),
- 0,0,0);
- Assert(HeapTupleIsValid(tuple));
- MyAttributeRelationId = tuple->t_oid;
-
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(AccessMethodRelationName),
- 0,0,0);
- Assert(HeapTupleIsValid(tuple));
- MyAMRelationId = tuple->t_oid;
-
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(AccessMethodOperatorRelationName),
- 0,0,0);
- Assert(HeapTupleIsValid(tuple));
- MyAMOPRelationId = tuple->t_oid;
+ HeapTuple tuple;
+
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(RelationRelationName),
+ 0, 0, 0);
+ Assert(HeapTupleIsValid(tuple));
+ MyRelationRelationId = tuple->t_oid;
+
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(AttributeRelationName),
+ 0, 0, 0);
+ Assert(HeapTupleIsValid(tuple));
+ MyAttributeRelationId = tuple->t_oid;
+
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(AccessMethodRelationName),
+ 0, 0, 0);
+ Assert(HeapTupleIsValid(tuple));
+ MyAMRelationId = tuple->t_oid;
+
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(AccessMethodOperatorRelationName),
+ 0, 0, 0);
+ Assert(HeapTupleIsValid(tuple));
+ MyAMOPRelationId = tuple->t_oid;
}
/* --------------------------------
- * CacheIdInvalidate
+ * CacheIdInvalidate
*
- * This routine can invalidate an tuple in a system catalog cache
- * or a cached relation descriptor. You pay your money and you
- * take your chances...
+ * This routine can invalidate an tuple in a system catalog cache
+ * or a cached relation descriptor. You pay your money and you
+ * take your chances...
* --------------------------------
*/
#ifdef INVALIDDEBUG
#define CacheIdInvalidate_DEBUG1 \
elog(DEBUG, "CacheIdInvalidate(%d, %d, 0x%x[%d])", cacheId, hashIndex,\
- pointer, ItemPointerIsValid(pointer))
+ pointer, ItemPointerIsValid(pointer))
#else
#define CacheIdInvalidate_DEBUG1
-#endif /* defined(INVALIDDEBUG) */
-
+#endif /* defined(INVALIDDEBUG) */
+
static void
CacheIdInvalidate(Index cacheId,
- Index hashIndex,
- ItemPointer pointer)
+ Index hashIndex,
+ ItemPointer pointer)
{
- /* ----------------
- * assume that if the item pointer is valid, then we are
- * invalidating an item in the specified system catalog cache.
- * ----------------
- */
- if (ItemPointerIsValid(pointer)) {
- CatalogCacheIdInvalidate(cacheId, hashIndex, pointer);
- return;
- }
-
- CacheIdInvalidate_DEBUG1;
-
- ValidateHacks(); /* XXX */
-
- /* ----------------
- * if the cacheId is the oid of any of the tuples in the
- * following system relations, then assume we are invalidating
- * a relation descriptor
- * ----------------
- */
- if (cacheId == MyRelationRelationId) {
- RelationIdInvalidateRelationCacheByRelationId(hashIndex);
- return;
- }
-
- if (cacheId == MyAttributeRelationId) {
- RelationIdInvalidateRelationCacheByRelationId(hashIndex);
- return;
- }
-
- if (cacheId == MyAMRelationId) {
- RelationIdInvalidateRelationCacheByAccessMethodId(hashIndex);
- return;
- }
-
- if (cacheId == MyAMOPRelationId) {
- RelationIdInvalidateRelationCacheByAccessMethodId(InvalidOid);
- return;
- }
-
- /* ----------------
- * Yow! the caller asked us to invalidate something else.
- * ----------------
- */
- elog(FATAL, "CacheIdInvalidate: cacheId=%d relation id?", cacheId);
+ /* ----------------
+ * assume that if the item pointer is valid, then we are
+ * invalidating an item in the specified system catalog cache.
+ * ----------------
+ */
+ if (ItemPointerIsValid(pointer))
+ {
+ CatalogCacheIdInvalidate(cacheId, hashIndex, pointer);
+ return;
+ }
+
+ CacheIdInvalidate_DEBUG1;
+
+ ValidateHacks(); /* XXX */
+
+ /* ----------------
+ * if the cacheId is the oid of any of the tuples in the
+ * following system relations, then assume we are invalidating
+ * a relation descriptor
+ * ----------------
+ */
+ if (cacheId == MyRelationRelationId)
+ {
+ RelationIdInvalidateRelationCacheByRelationId(hashIndex);
+ return;
+ }
+
+ if (cacheId == MyAttributeRelationId)
+ {
+ RelationIdInvalidateRelationCacheByRelationId(hashIndex);
+ return;
+ }
+
+ if (cacheId == MyAMRelationId)
+ {
+ RelationIdInvalidateRelationCacheByAccessMethodId(hashIndex);
+ return;
+ }
+
+ if (cacheId == MyAMOPRelationId)
+ {
+ RelationIdInvalidateRelationCacheByAccessMethodId(InvalidOid);
+ return;
+ }
+
+ /* ----------------
+ * Yow! the caller asked us to invalidate something else.
+ * ----------------
+ */
+ elog(FATAL, "CacheIdInvalidate: cacheId=%d relation id?", cacheId);
}
/* --------------------------------
- * ResetSystemCaches
+ * ResetSystemCaches
*
- * this blows away all tuples in the system catalog caches and
- * all the cached relation descriptors (and closes the files too).
+ * this blows away all tuples in the system catalog caches and
+ * all the cached relation descriptors (and closes the files too).
* --------------------------------
*/
static void
ResetSystemCaches()
{
- ResetSystemCache();
- RelationCacheInvalidate(false);
+ ResetSystemCache();
+ RelationCacheInvalidate(false);
}
/* --------------------------------
- * InvalidationMessageRegisterSharedInvalid
+ * InvalidationMessageRegisterSharedInvalid
* --------------------------------
*/
#ifdef INVALIDDEBUG
#define InvalidationMessageRegisterSharedInvalid_DEBUG1 \
elog(DEBUG,\
- "InvalidationMessageRegisterSharedInvalid(c, %d, %d, [%d, %d])",\
- message->any.catalog.cacheId,\
- message->any.catalog.hashIndex,\
- ItemPointerGetBlockNumber(&message->any.catalog.pointerData),\
- ItemPointerGetOffsetNumber(&message->any.catalog.pointerData))
+ "InvalidationMessageRegisterSharedInvalid(c, %d, %d, [%d, %d])",\
+ message->any.catalog.cacheId,\
+ message->any.catalog.hashIndex,\
+ ItemPointerGetBlockNumber(&message->any.catalog.pointerData),\
+ ItemPointerGetOffsetNumber(&message->any.catalog.pointerData))
#define InvalidationMessageRegisterSharedInvalid_DEBUG2 \
- elog(DEBUG, \
- "InvalidationMessageRegisterSharedInvalid(r, %d, %d)", \
- message->any.relation.relationId, \
- message->any.relation.objectId)
-#else
+ elog(DEBUG, \
+ "InvalidationMessageRegisterSharedInvalid(r, %d, %d)", \
+ message->any.relation.relationId, \
+ message->any.relation.objectId)
+#else
#define InvalidationMessageRegisterSharedInvalid_DEBUG1
#define InvalidationMessageRegisterSharedInvalid_DEBUG2
-#endif /* INVALIDDEBUG */
-
+#endif /* INVALIDDEBUG */
+
static void
InvalidationMessageRegisterSharedInvalid(InvalidationMessage message)
{
- Assert(PointerIsValid(message));
-
- switch (message->kind) {
- case 'c': /* cached system catalog tuple */
- InvalidationMessageRegisterSharedInvalid_DEBUG1;
-
- RegisterSharedInvalid(message->any.catalog.cacheId,
- message->any.catalog.hashIndex,
- &message->any.catalog.pointerData);
- break;
-
- case 'r': /* cached relation descriptor */
- InvalidationMessageRegisterSharedInvalid_DEBUG2;
-
- RegisterSharedInvalid(message->any.relation.relationId,
- message->any.relation.objectId,
- (ItemPointer) NULL);
- break;
-
- default:
- elog(FATAL,
- "InvalidationMessageRegisterSharedInvalid: `%c' kind",
- message->kind);
- }
+ Assert(PointerIsValid(message));
+
+ switch (message->kind)
+ {
+ case 'c': /* cached system catalog tuple */
+ InvalidationMessageRegisterSharedInvalid_DEBUG1;
+
+ RegisterSharedInvalid(message->any.catalog.cacheId,
+ message->any.catalog.hashIndex,
+ &message->any.catalog.pointerData);
+ break;
+
+ case 'r': /* cached relation descriptor */
+ InvalidationMessageRegisterSharedInvalid_DEBUG2;
+
+ RegisterSharedInvalid(message->any.relation.relationId,
+ message->any.relation.objectId,
+ (ItemPointer) NULL);
+ break;
+
+ default:
+ elog(FATAL,
+ "InvalidationMessageRegisterSharedInvalid: `%c' kind",
+ message->kind);
+ }
}
/* --------------------------------
- * InvalidationMessageCacheInvalidate
+ * InvalidationMessageCacheInvalidate
* --------------------------------
*/
#ifdef INVALIDDEBUG
#define InvalidationMessageCacheInvalidate_DEBUG1 \
elog(DEBUG, "InvalidationMessageCacheInvalidate(c, %d, %d, [%d, %d])",\
- message->any.catalog.cacheId,\
- message->any.catalog.hashIndex,\
- ItemPointerGetBlockNumber(&message->any.catalog.pointerData),\
- ItemPointerGetOffsetNumber(&message->any.catalog.pointerData))
+ message->any.catalog.cacheId,\
+ message->any.catalog.hashIndex,\
+ ItemPointerGetBlockNumber(&message->any.catalog.pointerData),\
+ ItemPointerGetOffsetNumber(&message->any.catalog.pointerData))
#define InvalidationMessageCacheInvalidate_DEBUG2 \
- elog(DEBUG, "InvalidationMessageCacheInvalidate(r, %d, %d)", \
- message->any.relation.relationId, \
- message->any.relation.objectId)
+ elog(DEBUG, "InvalidationMessageCacheInvalidate(r, %d, %d)", \
+ message->any.relation.relationId, \
+ message->any.relation.objectId)
#else
#define InvalidationMessageCacheInvalidate_DEBUG1
#define InvalidationMessageCacheInvalidate_DEBUG2
-#endif /* defined(INVALIDDEBUG) */
-
+#endif /* defined(INVALIDDEBUG) */
+
static void
InvalidationMessageCacheInvalidate(InvalidationMessage message)
{
- Assert(PointerIsValid(message));
-
- switch (message->kind) {
- case 'c': /* cached system catalog tuple */
- InvalidationMessageCacheInvalidate_DEBUG1;
-
- CatalogCacheIdInvalidate(message->any.catalog.cacheId,
- message->any.catalog.hashIndex,
- &message->any.catalog.pointerData);
- break;
-
- case 'r': /* cached relation descriptor */
- InvalidationMessageCacheInvalidate_DEBUG2;
-
- /* XXX ignore this--is this correct ??? */
- break;
-
- default:
- elog(FATAL, "InvalidationMessageCacheInvalidate: `%c' kind",
- message->kind);
- }
+ Assert(PointerIsValid(message));
+
+ switch (message->kind)
+ {
+ case 'c': /* cached system catalog tuple */
+ InvalidationMessageCacheInvalidate_DEBUG1;
+
+ CatalogCacheIdInvalidate(message->any.catalog.cacheId,
+ message->any.catalog.hashIndex,
+ &message->any.catalog.pointerData);
+ break;
+
+ case 'r': /* cached relation descriptor */
+ InvalidationMessageCacheInvalidate_DEBUG2;
+
+ /* XXX ignore this--is this correct ??? */
+ break;
+
+ default:
+ elog(FATAL, "InvalidationMessageCacheInvalidate: `%c' kind",
+ message->kind);
+ }
}
/* --------------------------------
- * RelationInvalidateRelationCache
+ * RelationInvalidateRelationCache
* --------------------------------
*/
static void
RelationInvalidateRelationCache(Relation relation,
- HeapTuple tuple,
- void (*function)())
+ HeapTuple tuple,
+ void (*function) ())
{
- Oid relationId;
- Oid objectId = (Oid)0;
-
- /* ----------------
- * get the relation object id
- * ----------------
- */
- ValidateHacks(); /* XXX */
- relationId = RelationGetRelationId(relation);
-
- /* ----------------
- *
- * ----------------
- */
- if (relationId == MyRelationRelationId) {
- objectId = tuple->t_oid;
- } else if (relationId == MyAttributeRelationId) {
- objectId = ((AttributeTupleForm)GETSTRUCT(tuple))->attrelid;
- } else if (relationId == MyAMRelationId) {
- objectId = tuple->t_oid;
- } else if (relationId == MyAMOPRelationId) {
- ; /* objectId is unused */
- } else
- return;
-
- /* ----------------
- * can't handle immediate relation descriptor invalidation
- * ----------------
- */
- Assert(PointerIsValid(function));
-
- (*function)(relationId, objectId);
+ Oid relationId;
+ Oid objectId = (Oid) 0;
+
+ /* ----------------
+ * get the relation object id
+ * ----------------
+ */
+ ValidateHacks(); /* XXX */
+ relationId = RelationGetRelationId(relation);
+
+ /* ----------------
+ *
+ * ----------------
+ */
+ if (relationId == MyRelationRelationId)
+ {
+ objectId = tuple->t_oid;
+ }
+ else if (relationId == MyAttributeRelationId)
+ {
+ objectId = ((AttributeTupleForm) GETSTRUCT(tuple))->attrelid;
+ }
+ else if (relationId == MyAMRelationId)
+ {
+ objectId = tuple->t_oid;
+ }
+ else if (relationId == MyAMOPRelationId)
+ {
+ ; /* objectId is unused */
+ }
+ else
+ return;
+
+ /* ----------------
+ * can't handle immediate relation descriptor invalidation
+ * ----------------
+ */
+ Assert(PointerIsValid(function));
+
+ (*function) (relationId, objectId);
}
/*
* DiscardInvalid --
- * Causes the invalidated cache state to be discarded.
+ * Causes the invalidated cache state to be discarded.
*
* Note:
- * This should be called as the first step in processing a transaction.
- * This should be called while waiting for a query from the front end
- * when other backends are active.
+ * This should be called as the first step in processing a transaction.
+ * This should be called while waiting for a query from the front end
+ * when other backends are active.
*/
void
DiscardInvalid()
{
- /* ----------------
- * debugging stuff
- * ----------------
- */
+ /* ----------------
+ * debugging stuff
+ * ----------------
+ */
#ifdef INVALIDDEBUG
- elog(DEBUG, "DiscardInvalid called");
-#endif /* defined(INVALIDDEBUG) */
-
- InvalidateSharedInvalid(CacheIdInvalidate, ResetSystemCaches);
+ elog(DEBUG, "DiscardInvalid called");
+#endif /* defined(INVALIDDEBUG) */
+
+ InvalidateSharedInvalid(CacheIdInvalidate, ResetSystemCaches);
}
/*
* RegisterInvalid --
- * Causes registration of invalidated state with other backends iff true.
+ * Causes registration of invalidated state with other backends iff true.
*
* Note:
- * This should be called as the last step in processing a transaction.
+ * This should be called as the last step in processing a transaction.
*/
void
RegisterInvalid(bool send)
{
- /* ----------------
- * debugging stuff
- * ----------------
- */
+ /* ----------------
+ * debugging stuff
+ * ----------------
+ */
#ifdef INVALIDDEBUG
- elog(DEBUG, "RegisterInvalid(%d) called", send);
-#endif /* defined(INVALIDDEBUG) */
-
- /* ----------------
- * Note: Invalid is a global variable
- * ----------------
- */
- if (send)
- LocalInvalidInvalidate(Invalid,
- InvalidationMessageRegisterSharedInvalid);
- else
- LocalInvalidInvalidate(Invalid,
- InvalidationMessageCacheInvalidate);
-
- Invalid = EmptyLocalInvalid;
+ elog(DEBUG, "RegisterInvalid(%d) called", send);
+#endif /* defined(INVALIDDEBUG) */
+
+ /* ----------------
+ * Note: Invalid is a global variable
+ * ----------------
+ */
+ if (send)
+ LocalInvalidInvalidate(Invalid,
+ InvalidationMessageRegisterSharedInvalid);
+ else
+ LocalInvalidInvalidate(Invalid,
+ InvalidationMessageCacheInvalidate);
+
+ Invalid = EmptyLocalInvalid;
}
/*
* SetRefreshWhenInvalidate --
- * Causes the local caches to be immediately refreshed iff true.
+ * Causes the local caches to be immediately refreshed iff true.
*/
void
SetRefreshWhenInvalidate(bool on)
{
#ifdef INVALIDDEBUG
- elog(DEBUG, "RefreshWhenInvalidate(%d) called", on);
-#endif /* defined(INVALIDDEBUG) */
-
- RefreshWhenInvalidate = on;
+ elog(DEBUG, "RefreshWhenInvalidate(%d) called", on);
+#endif /* defined(INVALIDDEBUG) */
+
+ RefreshWhenInvalidate = on;
}
/*
* RelationIdInvalidateHeapTuple --
- * Causes the given tuple in a relation to be invalidated.
+ * Causes the given tuple in a relation to be invalidated.
*
* Note:
- * Assumes object id is valid.
- * Assumes tuple is valid.
+ * Assumes object id is valid.
+ * Assumes tuple is valid.
*/
#ifdef INVALIDDEBUG
#define RelationInvalidateHeapTuple_DEBUG1 \
elog(DEBUG, "RelationInvalidateHeapTuple(%.16s, [%d,%d])", \
- RelationGetRelationName(relation), \
- ItemPointerGetBlockNumber(&tuple->t_ctid), \
- ItemPointerGetOffsetNumber(&tuple->t_ctid))
+ RelationGetRelationName(relation), \
+ ItemPointerGetBlockNumber(&tuple->t_ctid), \
+ ItemPointerGetOffsetNumber(&tuple->t_ctid))
#else
#define RelationInvalidateHeapTuple_DEBUG1
-#endif /* defined(INVALIDDEBUG) */
-
+#endif /* defined(INVALIDDEBUG) */
+
void
RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple)
{
- /* ----------------
- * sanity checks
- * ----------------
- */
- Assert(RelationIsValid(relation));
- Assert(HeapTupleIsValid(tuple));
-
- if (IsBootstrapProcessingMode())
- return;
- /* ----------------
- * this only works for system relations now
- * ----------------
- */
- if (! IsSystemRelationName(RelationGetRelationTupleForm(relation)->relname.data))
- return;
-
- /* ----------------
- * debugging stuff
- * ----------------
- */
- RelationInvalidateHeapTuple_DEBUG1;
-
- /* ----------------
- *
- * ----------------
- */
- RelationInvalidateCatalogCacheTuple(relation,
- tuple,
- CacheIdRegisterLocalInvalid);
-
- RelationInvalidateRelationCache(relation,
- tuple,
- RelationIdRegisterLocalInvalid);
-
- if (RefreshWhenInvalidate)
+ /* ----------------
+ * sanity checks
+ * ----------------
+ */
+ Assert(RelationIsValid(relation));
+ Assert(HeapTupleIsValid(tuple));
+
+ if (IsBootstrapProcessingMode())
+ return;
+ /* ----------------
+ * this only works for system relations now
+ * ----------------
+ */
+ if (!IsSystemRelationName(RelationGetRelationTupleForm(relation)->relname.data))
+ return;
+
+ /* ----------------
+ * debugging stuff
+ * ----------------
+ */
+ RelationInvalidateHeapTuple_DEBUG1;
+
+ /* ----------------
+ *
+ * ----------------
+ */
RelationInvalidateCatalogCacheTuple(relation,
- tuple,
- (void (*)()) NULL);
-}
+ tuple,
+ CacheIdRegisterLocalInvalid);
+ RelationInvalidateRelationCache(relation,
+ tuple,
+ RelationIdRegisterLocalInvalid);
+
+ if (RefreshWhenInvalidate)
+ RelationInvalidateCatalogCacheTuple(relation,
+ tuple,
+ (void (*) ()) NULL);
+}
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 9de0c3fb89b..37280036970 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* lsyscache.c--
- * Routines to access information within system caches
+ * Routines to access information within system caches
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.3 1997/08/19 21:35:11 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.4 1997/09/07 04:53:04 momjian Exp $
*
* NOTES
- * Eventually, the index information should go through here, too.
- *
- * Most of these routines call SearchSysCacheStruct() and thus simply
- * (1) allocate some space for the return struct and (2) call it.
- *
+ * Eventually, the index information should go through here, too.
+ *
+ * Most of these routines call SearchSysCacheStruct() and thus simply
+ * (1) allocate some space for the return struct and (2) call it.
+ *
*-------------------------------------------------------------------------
*/
#include <string.h>
@@ -34,99 +34,100 @@
#include "catalog/pg_operator.h"
#include "catalog/pg_type.h"
-/* ---------- AMOP CACHES ---------- */
+/* ---------- AMOP CACHES ---------- */
-/*
+/*
* op_class -
- *
- * Return t iff operator 'opno' is in operator class 'opclass'.
- *
+ *
+ * Return t iff operator 'opno' is in operator class 'opclass'.
+ *
*/
bool
op_class(Oid opno, int32 opclass, Oid amopid)
{
- FormData_pg_amop amoptup;
-
- if (SearchSysCacheStruct(AMOPOPID,
- (char *) &amoptup,
- ObjectIdGetDatum(opclass),
- ObjectIdGetDatum(opno),
- ObjectIdGetDatum(amopid),
- 0))
- return(true);
- else
- return(false);
+ FormData_pg_amop amoptup;
+
+ if (SearchSysCacheStruct(AMOPOPID,
+ (char *) &amoptup,
+ ObjectIdGetDatum(opclass),
+ ObjectIdGetDatum(opno),
+ ObjectIdGetDatum(amopid),
+ 0))
+ return (true);
+ else
+ return (false);
}
-/* ---------- ATTRIBUTE CACHES ---------- */
+/* ---------- ATTRIBUTE CACHES ---------- */
-/*
+/*
* get_attname -
- *
- * Given the relation id and the attribute number,
- * return the "attname" field from the attribute relation.
- *
+ *
+ * Given the relation id and the attribute number,
+ * return the "attname" field from the attribute relation.
+ *
*/
-char*
+char *
get_attname(Oid relid, AttrNumber attnum)
{
- FormData_pg_attribute att_tup;
- char *retval;
-
- if (SearchSysCacheStruct(ATTNUM,
- (char*)&att_tup,
- ObjectIdGetDatum(relid),
- UInt16GetDatum(attnum),
- 0,0)) {
- retval = pstrdup(att_tup.attname.data);
-
- return(retval);
- }
- else
- return(NULL);
+ FormData_pg_attribute att_tup;
+ char *retval;
+
+ if (SearchSysCacheStruct(ATTNUM,
+ (char *) &att_tup,
+ ObjectIdGetDatum(relid),
+ UInt16GetDatum(attnum),
+ 0, 0))
+ {
+ retval = pstrdup(att_tup.attname.data);
+
+ return (retval);
+ }
+ else
+ return (NULL);
}
-/*
+/*
* get_attnum -
- *
- * Given the relation id and the attribute name,
- * return the "attnum" field from the attribute relation.
- *
+ *
+ * Given the relation id and the attribute name,
+ * return the "attnum" field from the attribute relation.
+ *
*/
AttrNumber
get_attnum(Oid relid, char *attname)
{
- FormData_pg_attribute att_tup;
-
- if (SearchSysCacheStruct(ATTNAME, (char *) &att_tup,
- ObjectIdGetDatum(relid),
- PointerGetDatum(attname),
- 0,0))
- return(att_tup.attnum);
- else
- return(InvalidAttrNumber);
+ FormData_pg_attribute att_tup;
+
+ if (SearchSysCacheStruct(ATTNAME, (char *) &att_tup,
+ ObjectIdGetDatum(relid),
+ PointerGetDatum(attname),
+ 0, 0))
+ return (att_tup.attnum);
+ else
+ return (InvalidAttrNumber);
}
-/*
+/*
* get_atttype -
- *
- * Given the relation OID and the attribute number with the relation,
- * return the attribute type OID.
- *
+ *
+ * Given the relation OID and the attribute number with the relation,
+ * return the attribute type OID.
+ *
*/
Oid
get_atttype(Oid relid, AttrNumber attnum)
{
- AttributeTupleForm att_tup = (AttributeTupleForm)palloc(sizeof(*att_tup));
-
- if (SearchSysCacheStruct(ATTNUM,
- (char *) att_tup,
- ObjectIdGetDatum(relid),
- UInt16GetDatum(attnum),
- 0,0))
- return(att_tup->atttypid);
- else
- return((Oid)NULL);
+ AttributeTupleForm att_tup = (AttributeTupleForm) palloc(sizeof(*att_tup));
+
+ if (SearchSysCacheStruct(ATTNUM,
+ (char *) att_tup,
+ ObjectIdGetDatum(relid),
+ UInt16GetDatum(attnum),
+ 0, 0))
+ return (att_tup->atttypid);
+ else
+ return ((Oid) NULL);
}
/* This routine uses the attname instead of the attnum because it
@@ -136,353 +137,366 @@ get_atttype(Oid relid, AttrNumber attnum)
bool
get_attisset(Oid relid, char *attname)
{
- HeapTuple htup;
- AttrNumber attno;
- AttributeTupleForm att_tup;
-
- attno = get_attnum(relid, attname);
-
- htup = SearchSysCacheTuple(ATTNAME,
- ObjectIdGetDatum(relid),
- PointerGetDatum(attname),
- 0,0);
- if (!HeapTupleIsValid(htup))
- elog(WARN, "get_attisset: no attribute %.16s in relation %d",
- attname, relid);
- if (heap_attisnull(htup, attno))
- return(false);
- else {
- att_tup = (AttributeTupleForm)GETSTRUCT(htup);
- return(att_tup->attisset);
- }
+ HeapTuple htup;
+ AttrNumber attno;
+ AttributeTupleForm att_tup;
+
+ attno = get_attnum(relid, attname);
+
+ htup = SearchSysCacheTuple(ATTNAME,
+ ObjectIdGetDatum(relid),
+ PointerGetDatum(attname),
+ 0, 0);
+ if (!HeapTupleIsValid(htup))
+ elog(WARN, "get_attisset: no attribute %.16s in relation %d",
+ attname, relid);
+ if (heap_attisnull(htup, attno))
+ return (false);
+ else
+ {
+ att_tup = (AttributeTupleForm) GETSTRUCT(htup);
+ return (att_tup->attisset);
+ }
}
-/* ---------- INDEX CACHE ---------- */
+/* ---------- INDEX CACHE ---------- */
-/* watch this space...
+/* watch this space...
*/
-/* ---------- OPERATOR CACHE ---------- */
+/* ---------- OPERATOR CACHE ---------- */
-/*
+/*
* get_opcode -
- *
- * Returns the regproc id of the routine used to implement an
- * operator given the operator uid.
- *
+ *
+ * Returns the regproc id of the routine used to implement an
+ * operator given the operator uid.
+ *
*/
RegProcedure
get_opcode(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return(optup.oprcode);
- else
- return((RegProcedure)NULL);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (optup.oprcode);
+ else
+ return ((RegProcedure) NULL);
}
/*
* get_opname -
- * returns the name of the operator with the given opno
+ * returns the name of the operator with the given opno
*
* Note: return the struct so that it gets copied.
*/
-char*
+char *
get_opname(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return (pstrdup(optup.oprname.data));
- else {
- elog(WARN, "can't look up operator %d\n", opno);
- return NULL;
- }
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (pstrdup(optup.oprname.data));
+ else
+ {
+ elog(WARN, "can't look up operator %d\n", opno);
+ return NULL;
+ }
}
-/*
+/*
* op_mergesortable -
- *
- * Returns the left and right sort operators and types corresponding to a
- * mergesortable operator, or nil if the operator is not mergesortable.
- *
+ *
+ * Returns the left and right sort operators and types corresponding to a
+ * mergesortable operator, or nil if the operator is not mergesortable.
+ *
*/
bool
-op_mergesortable(Oid opno, Oid ltype, Oid rtype, Oid *leftOp, Oid *rightOp)
+op_mergesortable(Oid opno, Oid ltype, Oid rtype, Oid * leftOp, Oid * rightOp)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0) &&
- optup.oprlsortop &&
- optup.oprrsortop &&
- optup.oprleft == ltype &&
- optup.oprright == rtype) {
-
- *leftOp = ObjectIdGetDatum(optup.oprlsortop);
- *rightOp = ObjectIdGetDatum(optup.oprrsortop);
- return TRUE;
- } else {
- return FALSE;
- }
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0) &&
+ optup.oprlsortop &&
+ optup.oprrsortop &&
+ optup.oprleft == ltype &&
+ optup.oprright == rtype)
+ {
+
+ *leftOp = ObjectIdGetDatum(optup.oprlsortop);
+ *rightOp = ObjectIdGetDatum(optup.oprrsortop);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
}
-/*
+/*
* op_hashjoinable--
- *
- * Returns the hash operator corresponding to a hashjoinable operator,
+ *
+ * Returns the hash operator corresponding to a hashjoinable operator,
* or nil if the operator is not hashjoinable.
- *
+ *
*/
Oid
op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0) &&
- optup.oprcanhash &&
- optup.oprleft == ltype &&
- optup.oprright == rtype)
- return(opno);
- else
- return(InvalidOid);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0) &&
+ optup.oprcanhash &&
+ optup.oprleft == ltype &&
+ optup.oprright == rtype)
+ return (opno);
+ else
+ return (InvalidOid);
}
-/*
+/*
* get_commutator -
- *
- * Returns the corresponding commutator of an operator.
- *
+ *
+ * Returns the corresponding commutator of an operator.
+ *
*/
Oid
get_commutator(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return(optup.oprcom);
- else
- return((Oid)NULL);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (optup.oprcom);
+ else
+ return ((Oid) NULL);
}
HeapTuple
get_operator_tuple(Oid opno)
{
- HeapTuple optup;
-
- if ((optup = SearchSysCacheTuple(OPROID,
- ObjectIdGetDatum(opno),
- 0,0,0)))
- return(optup);
- else
- return((HeapTuple)NULL);
+ HeapTuple optup;
+
+ if ((optup = SearchSysCacheTuple(OPROID,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0)))
+ return (optup);
+ else
+ return ((HeapTuple) NULL);
}
-/*
+/*
* get_negator -
- *
- * Returns the corresponding negator of an operator.
- *
+ *
+ * Returns the corresponding negator of an operator.
+ *
*/
Oid
get_negator(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return(optup.oprnegate);
- else
- return((Oid)NULL);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (optup.oprnegate);
+ else
+ return ((Oid) NULL);
}
-/*
+/*
* get_oprrest -
- *
- * Returns procedure id for computing selectivity of an operator.
- *
+ *
+ * Returns procedure id for computing selectivity of an operator.
+ *
*/
RegProcedure
get_oprrest(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return(optup.oprrest );
- else
- return((RegProcedure) NULL);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (optup.oprrest);
+ else
+ return ((RegProcedure) NULL);
}
-/*
+/*
* get_oprjoin -
- *
- * Returns procedure id for computing selectivity of a join.
- *
+ *
+ * Returns procedure id for computing selectivity of a join.
+ *
*/
RegProcedure
get_oprjoin(Oid opno)
{
- FormData_pg_operator optup;
-
- if (SearchSysCacheStruct(OPROID, (char *) &optup,
- ObjectIdGetDatum(opno),
- 0,0,0))
- return(optup.oprjoin);
- else
- return((RegProcedure)NULL);
+ FormData_pg_operator optup;
+
+ if (SearchSysCacheStruct(OPROID, (char *) &optup,
+ ObjectIdGetDatum(opno),
+ 0, 0, 0))
+ return (optup.oprjoin);
+ else
+ return ((RegProcedure) NULL);
}
-/* ---------- RELATION CACHE ---------- */
+/* ---------- RELATION CACHE ---------- */
-/*
+/*
* get_relnatts -
- *
- * Returns the number of attributes for a given relation.
- *
+ *
+ * Returns the number of attributes for a given relation.
+ *
*/
int
get_relnatts(Oid relid)
{
- FormData_pg_class reltup;
-
- if (SearchSysCacheStruct(RELOID, (char *) &reltup,
- ObjectIdGetDatum(relid),
- 0,0,0))
- return(reltup.relnatts);
- else
- return(InvalidAttrNumber);
+ FormData_pg_class reltup;
+
+ if (SearchSysCacheStruct(RELOID, (char *) &reltup,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0))
+ return (reltup.relnatts);
+ else
+ return (InvalidAttrNumber);
}
-/*
+/*
* get_rel_name -
- *
- * Returns the name of a given relation.
- *
+ *
+ * Returns the name of a given relation.
+ *
*/
-char*
+char *
get_rel_name(Oid relid)
{
- FormData_pg_class reltup;
-
- if ((SearchSysCacheStruct(RELOID,
- (char*)&reltup,
- ObjectIdGetDatum(relid),
- 0,0,0))) {
- return (pstrdup(reltup.relname.data));
- } else
- return(NULL);
+ FormData_pg_class reltup;
+
+ if ((SearchSysCacheStruct(RELOID,
+ (char *) &reltup,
+ ObjectIdGetDatum(relid),
+ 0, 0, 0)))
+ {
+ return (pstrdup(reltup.relname.data));
+ }
+ else
+ return (NULL);
}
-/* ---------- TYPE CACHE ---------- */
+/* ---------- TYPE CACHE ---------- */
-/*
+/*
* get_typlen -
- *
- * Given the type OID, return the length of the type.
- *
+ *
+ * Given the type OID, return the length of the type.
+ *
*/
int16
get_typlen(Oid typid)
{
- TypeTupleFormData typtup;
-
- if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
- ObjectIdGetDatum(typid),
- 0,0,0))
- return(typtup.typlen);
- else
- return((int16)NULL);
+ TypeTupleFormData typtup;
+
+ if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0))
+ return (typtup.typlen);
+ else
+ return ((int16) NULL);
}
-/*
+/*
* get_typbyval -
- *
- * Given the type OID, determine whether the type is returned by value or
- * not. Returns 1 if by value, 0 if by reference.
- *
+ *
+ * Given the type OID, determine whether the type is returned by value or
+ * not. Returns 1 if by value, 0 if by reference.
+ *
*/
bool
get_typbyval(Oid typid)
{
- TypeTupleFormData typtup;
-
- if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
- ObjectIdGetDatum(typid),
- 0,0,0))
- return((bool)typtup.typbyval);
- else
- return(false);
+ TypeTupleFormData typtup;
+
+ if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0))
+ return ((bool) typtup.typbyval);
+ else
+ return (false);
}
-/*
+/*
* get_typbyval -
- *
- * Given the type OID, determine whether the type is returned by value or
- * not. Returns 1 if by value, 0 if by reference.
- *
+ *
+ * Given the type OID, determine whether the type is returned by value or
+ * not. Returns 1 if by value, 0 if by reference.
+ *
*/
#ifdef NOT_USED
char
get_typalign(Oid typid)
{
- TypeTupleFormData typtup;
-
- if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
- ObjectIdGetDatum(typid),
- 0,0,0))
- return(typtup.typalign);
- else
- return ('i');
+ TypeTupleFormData typtup;
+
+ if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0))
+ return (typtup.typalign);
+ else
+ return ('i');
}
+
#endif
-/*
- * get_typdefault -
- *
- * Given the type OID, return the default value of the ADT.
- *
+/*
+ * get_typdefault -
+ *
+ * Given the type OID, return the default value of the ADT.
+ *
*/
struct varlena *
get_typdefault(Oid typid)
{
- struct varlena *typdefault =
- (struct varlena *)TypeDefaultRetrieve (typid);
- return(typdefault);
+ struct varlena *typdefault =
+ (struct varlena *) TypeDefaultRetrieve(typid);
+
+ return (typdefault);
}
-/*
+/*
* get_typtype -
- *
- * Given the type OID, find if it is a basic type, a named relation
- * or the generic type 'relation'.
- * It returns the null char if the cache lookup fails...
- *
+ *
+ * Given the type OID, find if it is a basic type, a named relation
+ * or the generic type 'relation'.
+ * It returns the null char if the cache lookup fails...
+ *
*/
#ifdef NOT_USED
char
get_typtype(Oid typid)
{
- TypeTupleFormData typtup;
-
- if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
- ObjectIdGetDatum(typid),
- 0,0,0)) {
- return(typtup.typtype);
- } else {
- return('\0');
- }
+ TypeTupleFormData typtup;
+
+ if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
+ ObjectIdGetDatum(typid),
+ 0, 0, 0))
+ {
+ return (typtup.typtype);
+ }
+ else
+ {
+ return ('\0');
+ }
}
+
#endif
diff --git a/src/backend/utils/cache/rel.c b/src/backend/utils/cache/rel.c
index 33eabad1a85..4e45138037c 100644
--- a/src/backend/utils/cache/rel.c
+++ b/src/backend/utils/cache/rel.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* rel.c--
- * POSTGRES relation descriptor code.
+ * POSTGRES relation descriptor code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/rel.c,v 1.1.1.1 1996/07/09 06:22:06 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/rel.c,v 1.2 1997/09/07 04:53:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,57 +21,56 @@
#include "storage/fd.h"
-/*
- * RelationIsValid is now a macro in rel.h -cim 4/27/91
+/*
+ * RelationIsValid is now a macro in rel.h -cim 4/27/91
*
- * Many of the RelationGet...() functions are now macros in rel.h
- * -mer 3/2/92
+ * Many of the RelationGet...() functions are now macros in rel.h
+ * -mer 3/2/92
*/
/*
* RelationGetIndexStrategy --
- * Returns index strategy for a relation.
+ * Returns index strategy for a relation.
*
* Note:
- * Assumes relation descriptor is valid.
- * Assumes relation descriptor is for an index relation.
+ * Assumes relation descriptor is valid.
+ * Assumes relation descriptor is for an index relation.
*/
IndexStrategy
RelationGetIndexStrategy(Relation relation)
{
- return relation->rd_istrat;
+ return relation->rd_istrat;
}
/*
* RelationSetIndexSupport --
- * Sets index strategy and support info for a relation.
+ * Sets index strategy and support info for a relation.
*
* Note:
- * Assumes relation descriptor is a valid pointer to sufficient space.
- * Assumes index strategy is valid. Assumes support is valid if non-
- * NULL.
+ * Assumes relation descriptor is a valid pointer to sufficient space.
+ * Assumes index strategy is valid. Assumes support is valid if non-
+ * NULL.
*/
/* ----------------
- * RelationSetIndexSupport
+ * RelationSetIndexSupport
*
- * This routine saves two pointers -- one to the IndexStrategy, and
- * one to the RegProcs that support the indexed access method. These
- * pointers are stored in the space following the attribute data in the
- * reldesc.
+ * This routine saves two pointers -- one to the IndexStrategy, and
+ * one to the RegProcs that support the indexed access method. These
+ * pointers are stored in the space following the attribute data in the
+ * reldesc.
*
- * NEW: the index strategy and support are now stored in real fields
- * at the end of the structure - jolly
+ * NEW: the index strategy and support are now stored in real fields
+ * at the end of the structure - jolly
* ----------------
*/
void
RelationSetIndexSupport(Relation relation,
- IndexStrategy strategy,
- RegProcedure *support)
+ IndexStrategy strategy,
+ RegProcedure * support)
{
- Assert(PointerIsValid(relation));
- Assert(IndexStrategyIsValid(strategy));
-
- relation->rd_istrat = strategy;
- relation->rd_support = support;
-}
+ Assert(PointerIsValid(relation));
+ Assert(IndexStrategyIsValid(strategy));
+ relation->rd_istrat = strategy;
+ relation->rd_support = support;
+}
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index a54f1d81387..704d673279b 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1,41 +1,41 @@
/*-------------------------------------------------------------------------
*
* relcache.c--
- * POSTGRES relation descriptor cache code
+ * POSTGRES relation descriptor cache code
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.20 1997/09/01 08:04:38 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.21 1997/09/07 04:53:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * RelationInitialize - initialize relcache
- * RelationIdCacheGetRelation - get a reldesc from the cache (id)
- * RelationNameCacheGetRelation - get a reldesc from the cache (name)
- * RelationIdGetRelation - get a reldesc by relation id
- * RelationNameGetRelation - get a reldesc by relation name
- * RelationClose - close an open relation
- * RelationFlushRelation - flush relation information
+ * RelationInitialize - initialize relcache
+ * RelationIdCacheGetRelation - get a reldesc from the cache (id)
+ * RelationNameCacheGetRelation - get a reldesc from the cache (name)
+ * RelationIdGetRelation - get a reldesc by relation id
+ * RelationNameGetRelation - get a reldesc by relation name
+ * RelationClose - close an open relation
+ * RelationFlushRelation - flush relation information
*
* NOTES
- * This file is in the process of being cleaned up
- * before I add system attribute indexing. -cim 1/13/91
+ * This file is in the process of being cleaned up
+ * before I add system attribute indexing. -cim 1/13/91
*
- * The following code contains many undocumented hacks. Please be
- * careful....
+ * The following code contains many undocumented hacks. Please be
+ * careful....
*
*/
#include <sys/types.h>
-#include <stdio.h> /* for sprintf() */
+#include <stdio.h> /* for sprintf() */
#include <errno.h>
#include <sys/file.h>
#include <fcntl.h>
#include <string.h>
-
+
#include "postgres.h"
#include "miscadmin.h"
@@ -51,21 +51,21 @@
#include "access/tupdesc.h"
#include "access/tupmacs.h"
#include "access/xact.h"
-
+
#include "storage/buf.h"
-#include "storage/fd.h" /* for SEEK_ */
+#include "storage/fd.h" /* for SEEK_ */
#include "storage/lmgr.h"
#include "storage/bufmgr.h"
-
+
#include "lib/hasht.h"
-
+
#include "utils/memutils.h"
#include "utils/mcxt.h"
#include "utils/rel.h"
#include "utils/relcache.h"
#include "utils/hsearch.h"
#include "utils/relcache.h"
-
+
#include "catalog/catname.h"
#include "catalog/catalog.h"
#include "utils/syscache.h"
@@ -87,1744 +87,1813 @@
#include "catalog/index.h"
#include "fmgr.h"
-static void RelationFlushRelation(Relation *relationPtr,
- bool onlyFlushReferenceCountZero);
+static void
+RelationFlushRelation(Relation * relationPtr,
+ bool onlyFlushReferenceCountZero);
static Relation RelationNameCacheGetRelation(char *relationName);
-static void init_irels(void);
-static void write_irels(void);
+static void init_irels(void);
+static void write_irels(void);
/* ----------------
- * defines
+ * defines
* ----------------
*/
#define private static
#define INIT_FILENAME "pg_internal.init"
/* ----------------
- * externs
+ * externs
* ----------------
*/
-extern bool AMI_OVERRIDE; /* XXX style */
+extern bool AMI_OVERRIDE; /* XXX style */
extern GlobalMemory CacheCxt; /* from utils/cache/catcache.c */
/* ----------------
- * hardcoded tuple descriptors. see lib/backend/catalog/pg_attribute.h
+ * hardcoded tuple descriptors. see lib/backend/catalog/pg_attribute.h
* ----------------
*/
-FormData_pg_attribute Desc_pg_class[Natts_pg_class] = { Schema_pg_class };
-FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = { Schema_pg_attribute };
-FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = { Schema_pg_proc };
-FormData_pg_attribute Desc_pg_type[Natts_pg_type] = { Schema_pg_type };
-FormData_pg_attribute Desc_pg_variable[Natts_pg_variable] = { Schema_pg_variable };
-FormData_pg_attribute Desc_pg_log[Natts_pg_log] = { Schema_pg_log };
-FormData_pg_attribute Desc_pg_time[Natts_pg_time] = { Schema_pg_time };
+FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
+FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
+FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = {Schema_pg_proc};
+FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
+FormData_pg_attribute Desc_pg_variable[Natts_pg_variable] = {Schema_pg_variable};
+FormData_pg_attribute Desc_pg_log[Natts_pg_log] = {Schema_pg_log};
+FormData_pg_attribute Desc_pg_time[Natts_pg_time] = {Schema_pg_time};
/* ----------------
- * global variables
+ * global variables
*
- * Relations are cached two ways, by name and by id,
- * thus there are two hash tables for referencing them.
+ * Relations are cached two ways, by name and by id,
+ * thus there are two hash tables for referencing them.
* ----------------
*/
-HTAB *RelationNameCache;
-HTAB *RelationIdCache;
+HTAB *RelationNameCache;
+HTAB *RelationIdCache;
/* ----------------
- * RelationBuildDescInfo exists so code can be shared
- * between RelationIdGetRelation() and RelationNameGetRelation()
+ * RelationBuildDescInfo exists so code can be shared
+ * between RelationIdGetRelation() and RelationNameGetRelation()
* ----------------
*/
-typedef struct RelationBuildDescInfo {
- int infotype; /* lookup by id or by name */
+typedef struct RelationBuildDescInfo
+{
+ int infotype; /* lookup by id or by name */
#define INFO_RELID 1
#define INFO_RELNAME 2
- union {
- Oid info_id; /* relation object id */
- char *info_name; /* relation name */
- } i;
-} RelationBuildDescInfo;
-
-typedef struct relidcacheent {
- Oid reloid;
- Relation reldesc;
-} RelIdCacheEnt;
-
-typedef struct relnamecacheent {
- NameData relname;
- Relation reldesc;
-} RelNameCacheEnt;
+ union
+ {
+ Oid info_id;/* relation object id */
+ char *info_name; /* relation name */
+ } i;
+} RelationBuildDescInfo;
+
+typedef struct relidcacheent
+{
+ Oid reloid;
+ Relation reldesc;
+} RelIdCacheEnt;
+
+typedef struct relnamecacheent
+{
+ NameData relname;
+ Relation reldesc;
+} RelNameCacheEnt;
/* -----------------
- * macros to manipulate name cache and id cache
+ * macros to manipulate name cache and id cache
* -----------------
*/
#define RelationCacheInsert(RELATION) \
- { RelIdCacheEnt *idhentry; RelNameCacheEnt *namehentry; \
- char *relname; Oid reloid; bool found; \
- relname = (RELATION->rd_rel->relname).data; \
- namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
- relname, \
- HASH_ENTER, \
- &found); \
- if (namehentry == NULL) { \
- elog(FATAL, "can't insert into relation descriptor cache"); \
- } \
- if (found && !IsBootstrapProcessingMode()) { \
- /* used to give notice -- now just keep quiet */ ; \
- } \
- namehentry->reldesc = RELATION; \
- reloid = RELATION->rd_id; \
- idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
- (char *)&reloid, \
- HASH_ENTER, \
- &found); \
- if (idhentry == NULL) { \
- elog(FATAL, "can't insert into relation descriptor cache"); \
- } \
- if (found && !IsBootstrapProcessingMode()) { \
- /* used to give notice -- now just keep quiet */ ; \
- } \
- idhentry->reldesc = RELATION; \
- }
-#define RelationNameCacheLookup(NAME, RELATION) \
- { RelNameCacheEnt *hentry; bool found; \
- hentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
- (char *)NAME,HASH_FIND,&found); \
- if (hentry == NULL) { \
- elog(FATAL, "error in CACHE"); \
- } \
- if (found) { \
- RELATION = hentry->reldesc; \
- } \
- else { \
- RELATION = NULL; \
- } \
- }
-#define RelationIdCacheLookup(ID, RELATION) \
- { RelIdCacheEnt *hentry; bool found; \
- hentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
- (char *)&(ID),HASH_FIND, &found); \
- if (hentry == NULL) { \
- elog(FATAL, "error in CACHE"); \
- } \
- if (found) { \
- RELATION = hentry->reldesc; \
- } \
- else { \
- RELATION = NULL; \
- } \
- }
+ { RelIdCacheEnt *idhentry; RelNameCacheEnt *namehentry; \
+ char *relname; Oid reloid; bool found; \
+ relname = (RELATION->rd_rel->relname).data; \
+ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
+ relname, \
+ HASH_ENTER, \
+ &found); \
+ if (namehentry == NULL) { \
+ elog(FATAL, "can't insert into relation descriptor cache"); \
+ } \
+ if (found && !IsBootstrapProcessingMode()) { \
+ /* used to give notice -- now just keep quiet */ ; \
+ } \
+ namehentry->reldesc = RELATION; \
+ reloid = RELATION->rd_id; \
+ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
+ (char *)&reloid, \
+ HASH_ENTER, \
+ &found); \
+ if (idhentry == NULL) { \
+ elog(FATAL, "can't insert into relation descriptor cache"); \
+ } \
+ if (found && !IsBootstrapProcessingMode()) { \
+ /* used to give notice -- now just keep quiet */ ; \
+ } \
+ idhentry->reldesc = RELATION; \
+ }
+#define RelationNameCacheLookup(NAME, RELATION) \
+ { RelNameCacheEnt *hentry; bool found; \
+ hentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
+ (char *)NAME,HASH_FIND,&found); \
+ if (hentry == NULL) { \
+ elog(FATAL, "error in CACHE"); \
+ } \
+ if (found) { \
+ RELATION = hentry->reldesc; \
+ } \
+ else { \
+ RELATION = NULL; \
+ } \
+ }
+#define RelationIdCacheLookup(ID, RELATION) \
+ { RelIdCacheEnt *hentry; bool found; \
+ hentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
+ (char *)&(ID),HASH_FIND, &found); \
+ if (hentry == NULL) { \
+ elog(FATAL, "error in CACHE"); \
+ } \
+ if (found) { \
+ RELATION = hentry->reldesc; \
+ } \
+ else { \
+ RELATION = NULL; \
+ } \
+ }
#define RelationCacheDelete(RELATION) \
- { RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \
- char *relname; Oid reloid; bool found; \
- relname = (RELATION->rd_rel->relname).data; \
- namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
- relname, \
- HASH_REMOVE, \
- &found); \
- if (namehentry == NULL) { \
- elog(FATAL, "can't delete from relation descriptor cache"); \
- } \
- if (!found) { \
- elog(NOTICE, "trying to delete a reldesc that does not exist."); \
- } \
- reloid = RELATION->rd_id; \
- idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
- (char *)&reloid, \
- HASH_REMOVE, &found); \
- if (idhentry == NULL) { \
- elog(FATAL, "can't delete from relation descriptor cache"); \
- } \
- if (!found) { \
- elog(NOTICE, "trying to delete a reldesc that does not exist."); \
- } \
- }
+ { RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \
+ char *relname; Oid reloid; bool found; \
+ relname = (RELATION->rd_rel->relname).data; \
+ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
+ relname, \
+ HASH_REMOVE, \
+ &found); \
+ if (namehentry == NULL) { \
+ elog(FATAL, "can't delete from relation descriptor cache"); \
+ } \
+ if (!found) { \
+ elog(NOTICE, "trying to delete a reldesc that does not exist."); \
+ } \
+ reloid = RELATION->rd_id; \
+ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
+ (char *)&reloid, \
+ HASH_REMOVE, &found); \
+ if (idhentry == NULL) { \
+ elog(FATAL, "can't delete from relation descriptor cache"); \
+ } \
+ if (!found) { \
+ elog(NOTICE, "trying to delete a reldesc that does not exist."); \
+ } \
+ }
/* non-export function prototypes */
-static void formrdesc(char *relationName, u_int natts,
- FormData_pg_attribute att[]);
+static void
+formrdesc(char *relationName, u_int natts,
+ FormData_pg_attribute att[]);
+
+#if 0 /* See comments at line 1304 */
+static void RelationFlushIndexes(Relation * r, Oid accessMethodId);
-#if 0 /* See comments at line 1304 */
-static void RelationFlushIndexes(Relation *r, Oid accessMethodId);
#endif
static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo);
static HeapTuple scan_pg_rel_seq(RelationBuildDescInfo buildinfo);
static HeapTuple scan_pg_rel_ind(RelationBuildDescInfo buildinfo);
static Relation AllocateRelationDesc(u_int natts, Form_pg_class relp);
-static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
- Relation relation, u_int natts);
-static void build_tupdesc_seq(RelationBuildDescInfo buildinfo,
- Relation relation, u_int natts);
-static void build_tupdesc_ind(RelationBuildDescInfo buildinfo,
- Relation relation, u_int natts);
+static void
+RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
+ Relation relation, u_int natts);
+static void
+build_tupdesc_seq(RelationBuildDescInfo buildinfo,
+ Relation relation, u_int natts);
+static void
+build_tupdesc_ind(RelationBuildDescInfo buildinfo,
+ Relation relation, u_int natts);
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo);
-static void IndexedAccessMethodInitialize(Relation relation);
-static void AttrDefaultFetch (Relation relation);
-static void RelCheckFetch (Relation relation);
+static void IndexedAccessMethodInitialize(Relation relation);
+static void AttrDefaultFetch(Relation relation);
+static void RelCheckFetch(Relation relation);
-extern void RelationBuildTriggers (Relation relation);
-extern void FreeTriggerDesc (Relation relation);
+extern void RelationBuildTriggers(Relation relation);
+extern void FreeTriggerDesc(Relation relation);
/*
* newlyCreatedRelns -
- * relations created during this transaction. We need to keep track of
- * these.
+ * relations created during this transaction. We need to keep track of
+ * these.
*/
-static List *newlyCreatedRelns = NULL;
+static List *newlyCreatedRelns = NULL;
/* ----------------------------------------------------------------
- * RelationIdGetRelation() and RelationNameGetRelation()
- * support functions
+ * RelationIdGetRelation() and RelationNameGetRelation()
+ * support functions
* ----------------------------------------------------------------
*/
-
-#if NOT_USED /* XXX This doesn't seem to be used anywhere */
+
+#if NOT_USED /* XXX This doesn't seem to be used
+ * anywhere */
/* --------------------------------
- * BuildDescInfoError returns a string appropriate to
- * the buildinfo passed to it
+ * BuildDescInfoError returns a string appropriate to
+ * the buildinfo passed to it
* --------------------------------
*/
-static char *
+static char *
BuildDescInfoError(RelationBuildDescInfo buildinfo)
{
- static char errBuf[64];
-
- memset(errBuf, 0, (int) sizeof(errBuf));
- switch(buildinfo.infotype) {
- case INFO_RELID:
- sprintf(errBuf, "(relation id %d)", buildinfo.i.info_id);
- break;
- case INFO_RELNAME:
- sprintf(errBuf, "(relation name %s)", buildinfo.i.info_name);
- break;
- }
-
- return errBuf;
+ static char errBuf[64];
+
+ memset(errBuf, 0, (int) sizeof(errBuf));
+ switch (buildinfo.infotype)
+ {
+ case INFO_RELID:
+ sprintf(errBuf, "(relation id %d)", buildinfo.i.info_id);
+ break;
+ case INFO_RELNAME:
+ sprintf(errBuf, "(relation name %s)", buildinfo.i.info_name);
+ break;
+ }
+
+ return errBuf;
}
+
#endif
/* --------------------------------
- * ScanPgRelation
+ * ScanPgRelation
*
- * this is used by RelationBuildDesc to find a pg_class
- * tuple matching either a relation name or a relation id
- * as specified in buildinfo.
+ * this is used by RelationBuildDesc to find a pg_class
+ * tuple matching either a relation name or a relation id
+ * as specified in buildinfo.
* --------------------------------
*/
-static HeapTuple
+static HeapTuple
ScanPgRelation(RelationBuildDescInfo buildinfo)
{
- /*
- * If this is bootstrap time (initdb), then we can't use the system
- * catalog indices, because they may not exist yet. Otherwise, we
- * can, and do.
- */
-
- if (IsBootstrapProcessingMode())
- return (scan_pg_rel_seq(buildinfo));
- else
- return (scan_pg_rel_ind(buildinfo));
+
+ /*
+ * If this is bootstrap time (initdb), then we can't use the system
+ * catalog indices, because they may not exist yet. Otherwise, we
+ * can, and do.
+ */
+
+ if (IsBootstrapProcessingMode())
+ return (scan_pg_rel_seq(buildinfo));
+ else
+ return (scan_pg_rel_ind(buildinfo));
}
-static HeapTuple
+static HeapTuple
scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
{
- HeapTuple pg_class_tuple;
- HeapTuple return_tuple;
- Relation pg_class_desc;
- HeapScanDesc pg_class_scan;
- ScanKeyData key;
- Buffer buf;
-
- /* ----------------
- * form a scan key
- * ----------------
- */
- switch (buildinfo.infotype) {
- case INFO_RELID:
- ScanKeyEntryInitialize(&key, 0,
- ObjectIdAttributeNumber,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(buildinfo.i.info_id));
- break;
-
- case INFO_RELNAME:
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_class_relname,
- Character16EqualRegProcedure,
- NameGetDatum(buildinfo.i.info_name));
- break;
-
- default:
- elog(WARN, "ScanPgRelation: bad buildinfo");
- return NULL;
- }
-
- /* ----------------
- * open pg_class and fetch a tuple
- * ----------------
- */
- pg_class_desc = heap_openr(RelationRelationName);
- if (!IsInitProcessingMode())
- RelationSetLockForRead(pg_class_desc);
- pg_class_scan =
- heap_beginscan(pg_class_desc, 0, NowTimeQual, 1, &key);
- pg_class_tuple = heap_getnext(pg_class_scan, 0, &buf);
-
- /* ----------------
- * get set to return tuple
- * ----------------
- */
- if (! HeapTupleIsValid(pg_class_tuple)) {
- return_tuple = pg_class_tuple;
- } else {
- /* ------------------
- * a satanic bug used to live here: pg_class_tuple used to be
- * returned here without having the corresponding buffer pinned.
- * so when the buffer gets replaced, all hell breaks loose.
- * this bug is discovered and killed by wei on 9/27/91.
- * -------------------
+ HeapTuple pg_class_tuple;
+ HeapTuple return_tuple;
+ Relation pg_class_desc;
+ HeapScanDesc pg_class_scan;
+ ScanKeyData key;
+ Buffer buf;
+
+ /* ----------------
+ * form a scan key
+ * ----------------
*/
- return_tuple = (HeapTuple) palloc((Size) pg_class_tuple->t_len);
- memmove((char *) return_tuple,
- (char *) pg_class_tuple,
- (int) pg_class_tuple->t_len);
- ReleaseBuffer(buf);
- }
-
- /* all done */
- heap_endscan(pg_class_scan);
- if (!IsInitProcessingMode())
- RelationUnsetLockForRead(pg_class_desc);
- heap_close(pg_class_desc);
-
- return return_tuple;
+ switch (buildinfo.infotype)
+ {
+ case INFO_RELID:
+ ScanKeyEntryInitialize(&key, 0,
+ ObjectIdAttributeNumber,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(buildinfo.i.info_id));
+ break;
+
+ case INFO_RELNAME:
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_class_relname,
+ Character16EqualRegProcedure,
+ NameGetDatum(buildinfo.i.info_name));
+ break;
+
+ default:
+ elog(WARN, "ScanPgRelation: bad buildinfo");
+ return NULL;
+ }
+
+ /* ----------------
+ * open pg_class and fetch a tuple
+ * ----------------
+ */
+ pg_class_desc = heap_openr(RelationRelationName);
+ if (!IsInitProcessingMode())
+ RelationSetLockForRead(pg_class_desc);
+ pg_class_scan =
+ heap_beginscan(pg_class_desc, 0, NowTimeQual, 1, &key);
+ pg_class_tuple = heap_getnext(pg_class_scan, 0, &buf);
+
+ /* ----------------
+ * get set to return tuple
+ * ----------------
+ */
+ if (!HeapTupleIsValid(pg_class_tuple))
+ {
+ return_tuple = pg_class_tuple;
+ }
+ else
+ {
+ /* ------------------
+ * a satanic bug used to live here: pg_class_tuple used to be
+ * returned here without having the corresponding buffer pinned.
+ * so when the buffer gets replaced, all hell breaks loose.
+ * this bug is discovered and killed by wei on 9/27/91.
+ * -------------------
+ */
+ return_tuple = (HeapTuple) palloc((Size) pg_class_tuple->t_len);
+ memmove((char *) return_tuple,
+ (char *) pg_class_tuple,
+ (int) pg_class_tuple->t_len);
+ ReleaseBuffer(buf);
+ }
+
+ /* all done */
+ heap_endscan(pg_class_scan);
+ if (!IsInitProcessingMode())
+ RelationUnsetLockForRead(pg_class_desc);
+ heap_close(pg_class_desc);
+
+ return return_tuple;
}
-static HeapTuple
+static HeapTuple
scan_pg_rel_ind(RelationBuildDescInfo buildinfo)
{
- Relation pg_class_desc;
- HeapTuple return_tuple;
-
- pg_class_desc = heap_openr(RelationRelationName);
- if (!IsInitProcessingMode())
- RelationSetLockForRead(pg_class_desc);
-
- switch (buildinfo.infotype) {
- case INFO_RELID:
- return_tuple = ClassOidIndexScan(pg_class_desc, buildinfo.i.info_id);
- break;
-
- case INFO_RELNAME:
- return_tuple = ClassNameIndexScan(pg_class_desc,
- buildinfo.i.info_name);
- break;
-
- default:
- elog(WARN, "ScanPgRelation: bad buildinfo");
- /* XXX I hope this is right. It seems better than returning
- * an uninitialized value */
- return_tuple = NULL;
- }
-
- /* all done */
- if (!IsInitProcessingMode())
- RelationUnsetLockForRead(pg_class_desc);
- heap_close(pg_class_desc);
-
- return return_tuple;
+ Relation pg_class_desc;
+ HeapTuple return_tuple;
+
+ pg_class_desc = heap_openr(RelationRelationName);
+ if (!IsInitProcessingMode())
+ RelationSetLockForRead(pg_class_desc);
+
+ switch (buildinfo.infotype)
+ {
+ case INFO_RELID:
+ return_tuple = ClassOidIndexScan(pg_class_desc, buildinfo.i.info_id);
+ break;
+
+ case INFO_RELNAME:
+ return_tuple = ClassNameIndexScan(pg_class_desc,
+ buildinfo.i.info_name);
+ break;
+
+ default:
+ elog(WARN, "ScanPgRelation: bad buildinfo");
+
+ /*
+ * XXX I hope this is right. It seems better than returning an
+ * uninitialized value
+ */
+ return_tuple = NULL;
+ }
+
+ /* all done */
+ if (!IsInitProcessingMode())
+ RelationUnsetLockForRead(pg_class_desc);
+ heap_close(pg_class_desc);
+
+ return return_tuple;
}
/* ----------------
- * AllocateRelationDesc
+ * AllocateRelationDesc
*
- * This is used to allocate memory for a new relation descriptor
- * and initialize the rd_rel field.
+ * This is used to allocate memory for a new relation descriptor
+ * and initialize the rd_rel field.
* ----------------
*/
-static Relation
+static Relation
AllocateRelationDesc(u_int natts, Form_pg_class relp)
{
- Relation relation;
- Size len;
- Form_pg_class relationTupleForm;
-
- /* ----------------
- * allocate space for the relation tuple form
- * ----------------
- */
- relationTupleForm = (Form_pg_class)
- palloc((Size) (sizeof(FormData_pg_class)));
-
- memmove((char *) relationTupleForm, (char *) relp, CLASS_TUPLE_SIZE);
-
- /* ----------------
- * allocate space for new relation descriptor
- */
- len = sizeof(RelationData) + 10; /* + 10 is voodoo XXX mao */
-
- relation = (Relation) palloc(len);
-
- /* ----------------
- * clear new reldesc
- * ----------------
- */
- memset((char *) relation, 0, len);
-
- /* initialize attribute tuple form */
- relation->rd_att = CreateTemplateTupleDesc(natts);
-
- /*and initialize relation tuple form */
- relation->rd_rel = relationTupleForm;
-
- return relation;
+ Relation relation;
+ Size len;
+ Form_pg_class relationTupleForm;
+
+ /* ----------------
+ * allocate space for the relation tuple form
+ * ----------------
+ */
+ relationTupleForm = (Form_pg_class)
+ palloc((Size) (sizeof(FormData_pg_class)));
+
+ memmove((char *) relationTupleForm, (char *) relp, CLASS_TUPLE_SIZE);
+
+ /* ----------------
+ * allocate space for new relation descriptor
+ */
+ len = sizeof(RelationData) + 10; /* + 10 is voodoo XXX mao */
+
+ relation = (Relation) palloc(len);
+
+ /* ----------------
+ * clear new reldesc
+ * ----------------
+ */
+ memset((char *) relation, 0, len);
+
+ /* initialize attribute tuple form */
+ relation->rd_att = CreateTemplateTupleDesc(natts);
+
+ /* and initialize relation tuple form */
+ relation->rd_rel = relationTupleForm;
+
+ return relation;
}
/* --------------------------------
- * RelationBuildTupleDesc
+ * RelationBuildTupleDesc
*
- * Form the relation's tuple descriptor from information in
- * the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
+ * Form the relation's tuple descriptor from information in
+ * the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
* --------------------------------
*/
static void
-RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
- Relation relation,
- u_int natts)
+RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
+ Relation relation,
+ u_int natts)
{
- /*
- * If this is bootstrap time (initdb), then we can't use the system
- * catalog indices, because they may not exist yet. Otherwise, we
- * can, and do.
- */
-
- if (IsBootstrapProcessingMode())
- build_tupdesc_seq(buildinfo, relation, natts);
- else
- build_tupdesc_ind(buildinfo, relation, natts);
+
+ /*
+ * If this is bootstrap time (initdb), then we can't use the system
+ * catalog indices, because they may not exist yet. Otherwise, we
+ * can, and do.
+ */
+
+ if (IsBootstrapProcessingMode())
+ build_tupdesc_seq(buildinfo, relation, natts);
+ else
+ build_tupdesc_ind(buildinfo, relation, natts);
}
static void
build_tupdesc_seq(RelationBuildDescInfo buildinfo,
- Relation relation,
- u_int natts)
+ Relation relation,
+ u_int natts)
{
- HeapTuple pg_attribute_tuple;
- Relation pg_attribute_desc;
- HeapScanDesc pg_attribute_scan;
- AttributeTupleForm attp;
- ScanKeyData key;
- int need;
-
- /* ----------------
- * form a scan key
- * ----------------
- */
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_attribute_attrelid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relation->rd_id));
-
- /* ----------------
- * open pg_attribute and begin a scan
- * ----------------
- */
- pg_attribute_desc = heap_openr(AttributeRelationName);
- pg_attribute_scan =
- heap_beginscan(pg_attribute_desc, 0, NowTimeQual, 1, &key);
-
- /* ----------------
- * add attribute data to relation->rd_att
- * ----------------
- */
- need = natts;
-
- pg_attribute_tuple = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL);
- while (HeapTupleIsValid(pg_attribute_tuple) && need > 0) {
- attp = (AttributeTupleForm) GETSTRUCT(pg_attribute_tuple);
-
- if (attp->attnum > 0) {
- relation->rd_att->attrs[attp->attnum - 1] =
- (AttributeTupleForm)palloc(ATTRIBUTE_TUPLE_SIZE);
-
- memmove((char *) (relation->rd_att->attrs[attp->attnum - 1]),
- (char *) attp,
- ATTRIBUTE_TUPLE_SIZE);
- need--;
+ HeapTuple pg_attribute_tuple;
+ Relation pg_attribute_desc;
+ HeapScanDesc pg_attribute_scan;
+ AttributeTupleForm attp;
+ ScanKeyData key;
+ int need;
+
+ /* ----------------
+ * form a scan key
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_attribute_attrelid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relation->rd_id));
+
+ /* ----------------
+ * open pg_attribute and begin a scan
+ * ----------------
+ */
+ pg_attribute_desc = heap_openr(AttributeRelationName);
+ pg_attribute_scan =
+ heap_beginscan(pg_attribute_desc, 0, NowTimeQual, 1, &key);
+
+ /* ----------------
+ * add attribute data to relation->rd_att
+ * ----------------
+ */
+ need = natts;
+
+ pg_attribute_tuple = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL);
+ while (HeapTupleIsValid(pg_attribute_tuple) && need > 0)
+ {
+ attp = (AttributeTupleForm) GETSTRUCT(pg_attribute_tuple);
+
+ if (attp->attnum > 0)
+ {
+ relation->rd_att->attrs[attp->attnum - 1] =
+ (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+
+ memmove((char *) (relation->rd_att->attrs[attp->attnum - 1]),
+ (char *) attp,
+ ATTRIBUTE_TUPLE_SIZE);
+ need--;
+ }
+ pg_attribute_tuple = heap_getnext(pg_attribute_scan,
+ 0, (Buffer *) NULL);
}
- pg_attribute_tuple = heap_getnext(pg_attribute_scan,
- 0, (Buffer *) NULL);
- }
-
- if (need > 0)
- elog(WARN, "catalog is missing %d attribute%s for relid %d",
- need, (need == 1 ? "" : "s"), relation->rd_id);
-
- /* ----------------
- * end the scan and close the attribute relation
- * ----------------
- */
- heap_endscan(pg_attribute_scan);
- heap_close(pg_attribute_desc);
+
+ if (need > 0)
+ elog(WARN, "catalog is missing %d attribute%s for relid %d",
+ need, (need == 1 ? "" : "s"), relation->rd_id);
+
+ /* ----------------
+ * end the scan and close the attribute relation
+ * ----------------
+ */
+ heap_endscan(pg_attribute_scan);
+ heap_close(pg_attribute_desc);
}
static void
build_tupdesc_ind(RelationBuildDescInfo buildinfo,
- Relation relation,
- u_int natts)
+ Relation relation,
+ u_int natts)
{
- Relation attrel;
- HeapTuple atttup;
- AttributeTupleForm attp;
- TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
- AttrDefault *attrdef = NULL;
- int ndef = 0;
- int i;
-
- constr->has_not_null = false;
-
- attrel = heap_openr(AttributeRelationName);
-
- for (i = 1; i <= relation->rd_rel->relnatts; i++) {
-
- atttup = (HeapTuple) AttributeNumIndexScan(attrel, relation->rd_id, i);
-
- if (!HeapTupleIsValid(atttup))
- elog(WARN, "cannot find attribute %d of relation %.*s", i,
- NAMEDATALEN, &(relation->rd_rel->relname.data[0]));
- attp = (AttributeTupleForm) GETSTRUCT(atttup);
-
- relation->rd_att->attrs[i - 1] =
- (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
-
- memmove((char *) (relation->rd_att->attrs[i - 1]),
- (char *) attp,
- ATTRIBUTE_TUPLE_SIZE);
-
- /* Update if this attribute have a constraint */
- if (attp->attnotnull)
- constr->has_not_null = true;
-
- if (attp->atthasdef)
+ Relation attrel;
+ HeapTuple atttup;
+ AttributeTupleForm attp;
+ TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
+ AttrDefault *attrdef = NULL;
+ int ndef = 0;
+ int i;
+
+ constr->has_not_null = false;
+
+ attrel = heap_openr(AttributeRelationName);
+
+ for (i = 1; i <= relation->rd_rel->relnatts; i++)
{
- if ( attrdef == NULL )
- attrdef = (AttrDefault*) palloc (relation->rd_rel->relnatts *
- sizeof (AttrDefault));
- attrdef[ndef].adnum = i;
- attrdef[ndef].adbin = NULL;
- attrdef[ndef].adsrc = NULL;
- ndef++;
+
+ atttup = (HeapTuple) AttributeNumIndexScan(attrel, relation->rd_id, i);
+
+ if (!HeapTupleIsValid(atttup))
+ elog(WARN, "cannot find attribute %d of relation %.*s", i,
+ NAMEDATALEN, &(relation->rd_rel->relname.data[0]));
+ attp = (AttributeTupleForm) GETSTRUCT(atttup);
+
+ relation->rd_att->attrs[i - 1] =
+ (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+
+ memmove((char *) (relation->rd_att->attrs[i - 1]),
+ (char *) attp,
+ ATTRIBUTE_TUPLE_SIZE);
+
+ /* Update if this attribute have a constraint */
+ if (attp->attnotnull)
+ constr->has_not_null = true;
+
+ if (attp->atthasdef)
+ {
+ if (attrdef == NULL)
+ attrdef = (AttrDefault *) palloc(relation->rd_rel->relnatts *
+ sizeof(AttrDefault));
+ attrdef[ndef].adnum = i;
+ attrdef[ndef].adbin = NULL;
+ attrdef[ndef].adsrc = NULL;
+ ndef++;
+ }
}
- }
-
- heap_close(attrel);
-
- if ( constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks )
- {
- relation->rd_att->constr = constr;
-
- if ( ndef > 0 ) /* DEFAULTs */
- {
- if ( ndef < relation->rd_rel->relnatts )
- constr->defval = (AttrDefault*)
- repalloc (attrdef, ndef * sizeof (AttrDefault));
- else
- constr->defval = attrdef;
- constr->num_defval = ndef;
- AttrDefaultFetch (relation);
- }
- else
- constr->num_defval = 0;
-
- if ( relation->rd_rel->relchecks > 0 ) /* CHECKs */
+
+ heap_close(attrel);
+
+ if (constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks)
{
- constr->num_check = relation->rd_rel->relchecks;
- constr->check = (ConstrCheck *) palloc (constr->num_check *
- sizeof (ConstrCheck));
- memset (constr->check, 0, constr->num_check * sizeof (ConstrCheck));
- RelCheckFetch (relation);
+ relation->rd_att->constr = constr;
+
+ if (ndef > 0) /* DEFAULTs */
+ {
+ if (ndef < relation->rd_rel->relnatts)
+ constr->defval = (AttrDefault *)
+ repalloc(attrdef, ndef * sizeof(AttrDefault));
+ else
+ constr->defval = attrdef;
+ constr->num_defval = ndef;
+ AttrDefaultFetch(relation);
+ }
+ else
+ constr->num_defval = 0;
+
+ if (relation->rd_rel->relchecks > 0) /* CHECKs */
+ {
+ constr->num_check = relation->rd_rel->relchecks;
+ constr->check = (ConstrCheck *) palloc(constr->num_check *
+ sizeof(ConstrCheck));
+ memset(constr->check, 0, constr->num_check * sizeof(ConstrCheck));
+ RelCheckFetch(relation);
+ }
+ else
+ constr->num_check = 0;
}
else
- constr->num_check = 0;
- }
- else
- {
- pfree (constr);
- relation->rd_att->constr = NULL;
- }
-
+ {
+ pfree(constr);
+ relation->rd_att->constr = NULL;
+ }
+
}
/* --------------------------------
- * RelationBuildRuleLock
+ * RelationBuildRuleLock
*
- * Form the relation's rewrite rules from information in
- * the pg_rewrite system catalog.
+ * Form the relation's rewrite rules from information in
+ * the pg_rewrite system catalog.
* --------------------------------
*/
static void
RelationBuildRuleLock(Relation relation)
{
- HeapTuple pg_rewrite_tuple;
- Relation pg_rewrite_desc;
- TupleDesc pg_rewrite_tupdesc;
- HeapScanDesc pg_rewrite_scan;
- ScanKeyData key;
- RuleLock *rulelock;
- int numlocks;
- RewriteRule **rules;
- int maxlocks;
-
- /* ----------------
- * form an array to hold the rewrite rules (the array is extended if
- * necessary)
- * ----------------
- */
- maxlocks = 4;
- rules = (RewriteRule **)palloc(sizeof(RewriteRule*)*maxlocks);
- numlocks = 0;
-
- /* ----------------
- * form a scan key
- * ----------------
- */
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_rewrite_ev_class,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relation->rd_id));
-
- /* ----------------
- * open pg_attribute and begin a scan
- * ----------------
- */
- pg_rewrite_desc = heap_openr(RewriteRelationName);
- pg_rewrite_scan =
- heap_beginscan(pg_rewrite_desc, 0, NowTimeQual, 1, &key);
- pg_rewrite_tupdesc =
- RelationGetTupleDescriptor(pg_rewrite_desc);
-
- /* ----------------
- * add attribute data to relation->rd_att
- * ----------------
- */
- while ((pg_rewrite_tuple = heap_getnext(pg_rewrite_scan, 0,
- (Buffer *) NULL)) != NULL) {
- bool isnull;
- char *ruleaction = NULL;
- char *rule_evqual_string;
- RewriteRule *rule;
-
- rule = (RewriteRule *)palloc(sizeof(RewriteRule));
-
- rule->ruleId = pg_rewrite_tuple->t_oid;
-
- rule->event =
- (int)heap_getattr(pg_rewrite_tuple, InvalidBuffer,
- Anum_pg_rewrite_ev_type, pg_rewrite_tupdesc,
- &isnull) - 48;
- rule->attrno =
- (int)heap_getattr(pg_rewrite_tuple, InvalidBuffer,
- Anum_pg_rewrite_ev_attr, pg_rewrite_tupdesc,
- &isnull);
- rule->isInstead =
- !!heap_getattr(pg_rewrite_tuple, InvalidBuffer,
- Anum_pg_rewrite_is_instead, pg_rewrite_tupdesc,
- &isnull);
-
- ruleaction =
- heap_getattr(pg_rewrite_tuple, InvalidBuffer,
- Anum_pg_rewrite_action, pg_rewrite_tupdesc,
- &isnull);
- rule_evqual_string =
- heap_getattr(pg_rewrite_tuple, InvalidBuffer,
- Anum_pg_rewrite_ev_qual, pg_rewrite_tupdesc,
- &isnull);
-
- ruleaction = textout((struct varlena *)ruleaction);
- rule_evqual_string = textout((struct varlena *)rule_evqual_string);
-
- rule->actions = (List*)stringToNode(ruleaction);
- rule->qual = (Node*)stringToNode(rule_evqual_string);
-
- rules[numlocks++] = rule;
- if (numlocks==maxlocks) {
- maxlocks *= 2;
- rules =
- (RewriteRule **)repalloc(rules, sizeof(RewriteRule*)*maxlocks);
+ HeapTuple pg_rewrite_tuple;
+ Relation pg_rewrite_desc;
+ TupleDesc pg_rewrite_tupdesc;
+ HeapScanDesc pg_rewrite_scan;
+ ScanKeyData key;
+ RuleLock *rulelock;
+ int numlocks;
+ RewriteRule **rules;
+ int maxlocks;
+
+ /* ----------------
+ * form an array to hold the rewrite rules (the array is extended if
+ * necessary)
+ * ----------------
+ */
+ maxlocks = 4;
+ rules = (RewriteRule **) palloc(sizeof(RewriteRule *) * maxlocks);
+ numlocks = 0;
+
+ /* ----------------
+ * form a scan key
+ * ----------------
+ */
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_rewrite_ev_class,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relation->rd_id));
+
+ /* ----------------
+ * open pg_attribute and begin a scan
+ * ----------------
+ */
+ pg_rewrite_desc = heap_openr(RewriteRelationName);
+ pg_rewrite_scan =
+ heap_beginscan(pg_rewrite_desc, 0, NowTimeQual, 1, &key);
+ pg_rewrite_tupdesc =
+ RelationGetTupleDescriptor(pg_rewrite_desc);
+
+ /* ----------------
+ * add attribute data to relation->rd_att
+ * ----------------
+ */
+ while ((pg_rewrite_tuple = heap_getnext(pg_rewrite_scan, 0,
+ (Buffer *) NULL)) != NULL)
+ {
+ bool isnull;
+ char *ruleaction = NULL;
+ char *rule_evqual_string;
+ RewriteRule *rule;
+
+ rule = (RewriteRule *) palloc(sizeof(RewriteRule));
+
+ rule->ruleId = pg_rewrite_tuple->t_oid;
+
+ rule->event =
+ (int) heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+ Anum_pg_rewrite_ev_type, pg_rewrite_tupdesc,
+ &isnull) - 48;
+ rule->attrno =
+ (int) heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+ Anum_pg_rewrite_ev_attr, pg_rewrite_tupdesc,
+ &isnull);
+ rule->isInstead =
+ !!heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+ Anum_pg_rewrite_is_instead, pg_rewrite_tupdesc,
+ &isnull);
+
+ ruleaction =
+ heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+ Anum_pg_rewrite_action, pg_rewrite_tupdesc,
+ &isnull);
+ rule_evqual_string =
+ heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+ Anum_pg_rewrite_ev_qual, pg_rewrite_tupdesc,
+ &isnull);
+
+ ruleaction = textout((struct varlena *) ruleaction);
+ rule_evqual_string = textout((struct varlena *) rule_evqual_string);
+
+ rule->actions = (List *) stringToNode(ruleaction);
+ rule->qual = (Node *) stringToNode(rule_evqual_string);
+
+ rules[numlocks++] = rule;
+ if (numlocks == maxlocks)
+ {
+ maxlocks *= 2;
+ rules =
+ (RewriteRule **) repalloc(rules, sizeof(RewriteRule *) * maxlocks);
+ }
}
- }
-
- /* ----------------
- * end the scan and close the attribute relation
- * ----------------
- */
- heap_endscan(pg_rewrite_scan);
- heap_close(pg_rewrite_desc);
-
- /* ----------------
- * form a RuleLock and insert into relation
- * ----------------
- */
- rulelock = (RuleLock *)palloc(sizeof(RuleLock));
- rulelock->numLocks = numlocks;
- rulelock->rules = rules;
-
- relation->rd_rules = rulelock;
- return;
+
+ /* ----------------
+ * end the scan and close the attribute relation
+ * ----------------
+ */
+ heap_endscan(pg_rewrite_scan);
+ heap_close(pg_rewrite_desc);
+
+ /* ----------------
+ * form a RuleLock and insert into relation
+ * ----------------
+ */
+ rulelock = (RuleLock *) palloc(sizeof(RuleLock));
+ rulelock->numLocks = numlocks;
+ rulelock->rules = rules;
+
+ relation->rd_rules = rulelock;
+ return;
}
/* --------------------------------
- * RelationBuildDesc
- *
- * To build a relation descriptor, we have to allocate space,
- * open the underlying unix file and initialize the following
- * fields:
+ * RelationBuildDesc
+ *
+ * To build a relation descriptor, we have to allocate space,
+ * open the underlying unix file and initialize the following
+ * fields:
*
- * File rd_fd; open file descriptor
- * int rd_nblocks; number of blocks in rel
- * it will be set in ambeginscan()
- * uint16 rd_refcnt; reference count
- * Form_pg_am rd_am; AM tuple
- * Form_pg_class rd_rel; RELATION tuple
- * Oid rd_id; relations's object id
- * Pointer lockInfo; ptr. to misc. info.
- * TupleDesc rd_att; tuple desciptor
+ * File rd_fd; open file descriptor
+ * int rd_nblocks; number of blocks in rel
+ * it will be set in ambeginscan()
+ * uint16 rd_refcnt; reference count
+ * Form_pg_am rd_am; AM tuple
+ * Form_pg_class rd_rel; RELATION tuple
+ * Oid rd_id; relations's object id
+ * Pointer lockInfo; ptr. to misc. info.
+ * TupleDesc rd_att; tuple desciptor
*
- * Note: rd_ismem (rel is in-memory only) is currently unused
- * by any part of the system. someday this will indicate that
- * the relation lives only in the main-memory buffer pool
- * -cim 2/4/91
+ * Note: rd_ismem (rel is in-memory only) is currently unused
+ * by any part of the system. someday this will indicate that
+ * the relation lives only in the main-memory buffer pool
+ * -cim 2/4/91
* --------------------------------
*/
-static Relation
+static Relation
RelationBuildDesc(RelationBuildDescInfo buildinfo)
{
- File fd;
- Relation relation;
- u_int natts;
- Oid relid;
- Oid relam;
- Form_pg_class relp;
-
- MemoryContext oldcxt;
-
- HeapTuple pg_class_tuple;
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * find the tuple in pg_class corresponding to the given relation id
- * ----------------
- */
- pg_class_tuple = ScanPgRelation(buildinfo);
-
- /* ----------------
- * if no such tuple exists, return NULL
- * ----------------
- */
- if (! HeapTupleIsValid(pg_class_tuple)) {
-
- MemoryContextSwitchTo(oldcxt);
-
- return NULL;
- }
-
- /* ----------------
- * get information from the pg_class_tuple
- * ----------------
- */
- relid = pg_class_tuple->t_oid;
- relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
- natts = relp->relnatts;
-
- /* ----------------
- * allocate storage for the relation descriptor,
- * initialize relation->rd_rel and get the access method id.
- * ----------------
- */
- relation = AllocateRelationDesc(natts, relp);
- relam = relation->rd_rel->relam;
-
- /* ----------------
- * initialize the relation's relation id (relation->rd_id)
- * ----------------
- */
- relation->rd_id = relid;
-
- /* ----------------
- * initialize relation->rd_refcnt
- * ----------------
- */
- RelationSetReferenceCount(relation, 1);
-
- /* ----------------
- * normal relations are not nailed into the cache
- * ----------------
- */
- relation->rd_isnailed = false;
-
- /* ----------------
- * initialize the access method information (relation->rd_am)
- * ----------------
- */
- if (OidIsValid(relam)) {
- relation->rd_am = (Form_pg_am)
- AccessMethodObjectIdGetAccessMethodTupleForm(relam);
- }
-
- /* ----------------
- * initialize the tuple descriptor (relation->rd_att).
- * remember, rd_att is an array of attribute pointers that lives
- * off the end of the relation descriptor structure so space was
- * already allocated for it by AllocateRelationDesc.
- * ----------------
- */
- RelationBuildTupleDesc(buildinfo, relation, natts);
-
- /* ----------------
- * initialize rules that affect this relation
- * ----------------
- */
- if (relp->relhasrules) {
- RelationBuildRuleLock(relation);
- } else {
- relation->rd_rules = NULL;
- }
-
- /* Triggers */
- if ( relp->reltriggers > 0 )
- RelationBuildTriggers (relation);
- else
- relation->trigdesc = NULL;
-
- /* ----------------
- * initialize index strategy and support information for this relation
- * ----------------
- */
- if (OidIsValid(relam)) {
- IndexedAccessMethodInitialize(relation);
- }
-
- /* ----------------
- * initialize the relation lock manager information
- * ----------------
- */
- RelationInitLockInfo(relation); /* see lmgr.c */
-
- /* ----------------
- * open the relation and assign the file descriptor returned
- * by the storage manager code to rd_fd.
- * ----------------
- */
- fd = smgropen(relp->relsmgr, relation);
-
- Assert (fd >= -1);
- if (fd == -1)
- elog(NOTICE, "RelationIdBuildRelation: smgropen(%s): %m",
- &relp->relname);
-
- relation->rd_fd = fd;
-
- /* ----------------
- * insert newly created relation into proper relcaches,
- * restore memory context and return the new reldesc.
- * ----------------
- */
-
- RelationCacheInsert(relation);
-
- /* -------------------
- * free the memory allocated for pg_class_tuple
- * and for lock data pointed to by pg_class_tuple
- * -------------------
- */
- pfree(pg_class_tuple);
-
- MemoryContextSwitchTo(oldcxt);
-
- return relation;
+ File fd;
+ Relation relation;
+ u_int natts;
+ Oid relid;
+ Oid relam;
+ Form_pg_class relp;
+
+ MemoryContext oldcxt;
+
+ HeapTuple pg_class_tuple;
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * find the tuple in pg_class corresponding to the given relation id
+ * ----------------
+ */
+ pg_class_tuple = ScanPgRelation(buildinfo);
+
+ /* ----------------
+ * if no such tuple exists, return NULL
+ * ----------------
+ */
+ if (!HeapTupleIsValid(pg_class_tuple))
+ {
+
+ MemoryContextSwitchTo(oldcxt);
+
+ return NULL;
+ }
+
+ /* ----------------
+ * get information from the pg_class_tuple
+ * ----------------
+ */
+ relid = pg_class_tuple->t_oid;
+ relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
+ natts = relp->relnatts;
+
+ /* ----------------
+ * allocate storage for the relation descriptor,
+ * initialize relation->rd_rel and get the access method id.
+ * ----------------
+ */
+ relation = AllocateRelationDesc(natts, relp);
+ relam = relation->rd_rel->relam;
+
+ /* ----------------
+ * initialize the relation's relation id (relation->rd_id)
+ * ----------------
+ */
+ relation->rd_id = relid;
+
+ /* ----------------
+ * initialize relation->rd_refcnt
+ * ----------------
+ */
+ RelationSetReferenceCount(relation, 1);
+
+ /* ----------------
+ * normal relations are not nailed into the cache
+ * ----------------
+ */
+ relation->rd_isnailed = false;
+
+ /* ----------------
+ * initialize the access method information (relation->rd_am)
+ * ----------------
+ */
+ if (OidIsValid(relam))
+ {
+ relation->rd_am = (Form_pg_am)
+ AccessMethodObjectIdGetAccessMethodTupleForm(relam);
+ }
+
+ /* ----------------
+ * initialize the tuple descriptor (relation->rd_att).
+ * remember, rd_att is an array of attribute pointers that lives
+ * off the end of the relation descriptor structure so space was
+ * already allocated for it by AllocateRelationDesc.
+ * ----------------
+ */
+ RelationBuildTupleDesc(buildinfo, relation, natts);
+
+ /* ----------------
+ * initialize rules that affect this relation
+ * ----------------
+ */
+ if (relp->relhasrules)
+ {
+ RelationBuildRuleLock(relation);
+ }
+ else
+ {
+ relation->rd_rules = NULL;
+ }
+
+ /* Triggers */
+ if (relp->reltriggers > 0)
+ RelationBuildTriggers(relation);
+ else
+ relation->trigdesc = NULL;
+
+ /* ----------------
+ * initialize index strategy and support information for this relation
+ * ----------------
+ */
+ if (OidIsValid(relam))
+ {
+ IndexedAccessMethodInitialize(relation);
+ }
+
+ /* ----------------
+ * initialize the relation lock manager information
+ * ----------------
+ */
+ RelationInitLockInfo(relation); /* see lmgr.c */
+
+ /* ----------------
+ * open the relation and assign the file descriptor returned
+ * by the storage manager code to rd_fd.
+ * ----------------
+ */
+ fd = smgropen(relp->relsmgr, relation);
+
+ Assert(fd >= -1);
+ if (fd == -1)
+ elog(NOTICE, "RelationIdBuildRelation: smgropen(%s): %m",
+ &relp->relname);
+
+ relation->rd_fd = fd;
+
+ /* ----------------
+ * insert newly created relation into proper relcaches,
+ * restore memory context and return the new reldesc.
+ * ----------------
+ */
+
+ RelationCacheInsert(relation);
+
+ /* -------------------
+ * free the memory allocated for pg_class_tuple
+ * and for lock data pointed to by pg_class_tuple
+ * -------------------
+ */
+ pfree(pg_class_tuple);
+
+ MemoryContextSwitchTo(oldcxt);
+
+ return relation;
}
static void
IndexedAccessMethodInitialize(Relation relation)
{
- IndexStrategy strategy;
- RegProcedure *support;
- int natts;
- Size stratSize;
- Size supportSize;
- uint16 relamstrategies;
- uint16 relamsupport;
-
- natts = relation->rd_rel->relnatts;
- relamstrategies = relation->rd_am->amstrategies;
- stratSize = AttributeNumberGetIndexStrategySize(natts, relamstrategies);
- strategy = (IndexStrategy) palloc(stratSize);
- relamsupport = relation->rd_am->amsupport;
-
- if (relamsupport > 0) {
- supportSize = natts * (relamsupport * sizeof (RegProcedure));
- support = (RegProcedure *) palloc(supportSize);
- } else {
- support = (RegProcedure *) NULL;
- }
-
- IndexSupportInitialize(strategy, support,
- relation->rd_att->attrs[0]->attrelid,
- relation->rd_rel->relam,
- relamstrategies, relamsupport, natts);
-
- RelationSetIndexSupport(relation, strategy, support);
+ IndexStrategy strategy;
+ RegProcedure *support;
+ int natts;
+ Size stratSize;
+ Size supportSize;
+ uint16 relamstrategies;
+ uint16 relamsupport;
+
+ natts = relation->rd_rel->relnatts;
+ relamstrategies = relation->rd_am->amstrategies;
+ stratSize = AttributeNumberGetIndexStrategySize(natts, relamstrategies);
+ strategy = (IndexStrategy) palloc(stratSize);
+ relamsupport = relation->rd_am->amsupport;
+
+ if (relamsupport > 0)
+ {
+ supportSize = natts * (relamsupport * sizeof(RegProcedure));
+ support = (RegProcedure *) palloc(supportSize);
+ }
+ else
+ {
+ support = (RegProcedure *) NULL;
+ }
+
+ IndexSupportInitialize(strategy, support,
+ relation->rd_att->attrs[0]->attrelid,
+ relation->rd_rel->relam,
+ relamstrategies, relamsupport, natts);
+
+ RelationSetIndexSupport(relation, strategy, support);
}
/* --------------------------------
- * formrdesc
+ * formrdesc
*
- * This is a special version of RelationBuildDesc()
- * used by RelationInitialize() in initializing the
- * relcache. The system relation descriptors built
- * here are all nailed in the descriptor caches, for
- * bootstrapping.
+ * This is a special version of RelationBuildDesc()
+ * used by RelationInitialize() in initializing the
+ * relcache. The system relation descriptors built
+ * here are all nailed in the descriptor caches, for
+ * bootstrapping.
* --------------------------------
*/
static void
formrdesc(char *relationName,
- u_int natts,
- FormData_pg_attribute att[])
+ u_int natts,
+ FormData_pg_attribute att[])
{
- Relation relation;
- Size len;
- int i;
-
- /* ----------------
- * allocate new relation desc
- * ----------------
- */
- len = sizeof (RelationData);
- relation = (Relation) palloc(len);
- memset((char *)relation, 0,len);
-
- /* ----------------
- * don't open the unix file yet..
- * ----------------
- */
- relation->rd_fd = -1;
-
- /* ----------------
- * initialize reference count
- * ----------------
- */
- RelationSetReferenceCount(relation, 1);
-
- /* ----------------
- * initialize relation tuple form
- * ----------------
- */
- relation->rd_rel = (Form_pg_class)
- palloc((Size) (sizeof(*relation->rd_rel)));
- memset(relation->rd_rel, 0, sizeof(FormData_pg_class));
- namestrcpy(&relation->rd_rel->relname, relationName);
-
- /* ----------------
- initialize attribute tuple form
- */
- relation->rd_att = CreateTemplateTupleDesc(natts);
-
- /*
- * For debugging purposes, it's important to distinguish between
- * shared and non-shared relations, even at bootstrap time. There's
- * code in the buffer manager that traces allocations that has to
- * know about this.
- */
-
- if (IsSystemRelationName(relationName)) {
- relation->rd_rel->relowner = 6; /* XXX use sym const */
- relation->rd_rel->relisshared =
- IsSharedSystemRelationName(relationName);
- } else {
- relation->rd_rel->relowner = InvalidOid; /* XXX incorrect*/
- relation->rd_rel->relisshared = false;
- }
-
- relation->rd_rel->relpages = 1; /* XXX */
- relation->rd_rel->reltuples = 1; /* XXX */
- relation->rd_rel->relkind = RELKIND_RELATION;
- relation->rd_rel->relarch = 'n';
- relation->rd_rel->relnatts = (uint16) natts;
- relation->rd_isnailed = true;
-
- /* ----------------
- * initialize tuple desc info
- * ----------------
- */
- for (i = 0; i < natts; i++) {
- relation->rd_att->attrs[i] =
- (AttributeTupleForm)palloc(ATTRIBUTE_TUPLE_SIZE);
-
- memset((char *)relation->rd_att->attrs[i], 0,
- ATTRIBUTE_TUPLE_SIZE);
- memmove((char *)relation->rd_att->attrs[i],
- (char *)&att[i],
- ATTRIBUTE_TUPLE_SIZE);
- }
-
- /* ----------------
- * initialize relation id
- * ----------------
- */
- relation->rd_id = relation->rd_att->attrs[0]->attrelid;
-
- /* ----------------
- * add new reldesc to relcache
- * ----------------
- */
- RelationCacheInsert(relation);
- /*
- * Determining this requires a scan on pg_class, but to do the
- * scan the rdesc for pg_class must already exist. Therefore
- * we must do the check (and possible set) after cache insertion.
- */
- relation->rd_rel->relhasindex =
- CatalogHasIndex(relationName, relation->rd_id);
+ Relation relation;
+ Size len;
+ int i;
+
+ /* ----------------
+ * allocate new relation desc
+ * ----------------
+ */
+ len = sizeof(RelationData);
+ relation = (Relation) palloc(len);
+ memset((char *) relation, 0, len);
+
+ /* ----------------
+ * don't open the unix file yet..
+ * ----------------
+ */
+ relation->rd_fd = -1;
+
+ /* ----------------
+ * initialize reference count
+ * ----------------
+ */
+ RelationSetReferenceCount(relation, 1);
+
+ /* ----------------
+ * initialize relation tuple form
+ * ----------------
+ */
+ relation->rd_rel = (Form_pg_class)
+ palloc((Size) (sizeof(*relation->rd_rel)));
+ memset(relation->rd_rel, 0, sizeof(FormData_pg_class));
+ namestrcpy(&relation->rd_rel->relname, relationName);
+
+ /* ----------------
+ initialize attribute tuple form
+ */
+ relation->rd_att = CreateTemplateTupleDesc(natts);
+
+ /*
+ * For debugging purposes, it's important to distinguish between
+ * shared and non-shared relations, even at bootstrap time. There's
+ * code in the buffer manager that traces allocations that has to know
+ * about this.
+ */
+
+ if (IsSystemRelationName(relationName))
+ {
+ relation->rd_rel->relowner = 6; /* XXX use sym const */
+ relation->rd_rel->relisshared =
+ IsSharedSystemRelationName(relationName);
+ }
+ else
+ {
+ relation->rd_rel->relowner = InvalidOid; /* XXX incorrect */
+ relation->rd_rel->relisshared = false;
+ }
+
+ relation->rd_rel->relpages = 1; /* XXX */
+ relation->rd_rel->reltuples = 1; /* XXX */
+ relation->rd_rel->relkind = RELKIND_RELATION;
+ relation->rd_rel->relarch = 'n';
+ relation->rd_rel->relnatts = (uint16) natts;
+ relation->rd_isnailed = true;
+
+ /* ----------------
+ * initialize tuple desc info
+ * ----------------
+ */
+ for (i = 0; i < natts; i++)
+ {
+ relation->rd_att->attrs[i] =
+ (AttributeTupleForm) palloc(ATTRIBUTE_TUPLE_SIZE);
+
+ memset((char *) relation->rd_att->attrs[i], 0,
+ ATTRIBUTE_TUPLE_SIZE);
+ memmove((char *) relation->rd_att->attrs[i],
+ (char *) &att[i],
+ ATTRIBUTE_TUPLE_SIZE);
+ }
+
+ /* ----------------
+ * initialize relation id
+ * ----------------
+ */
+ relation->rd_id = relation->rd_att->attrs[0]->attrelid;
+
+ /* ----------------
+ * add new reldesc to relcache
+ * ----------------
+ */
+ RelationCacheInsert(relation);
+
+ /*
+ * Determining this requires a scan on pg_class, but to do the scan
+ * the rdesc for pg_class must already exist. Therefore we must do
+ * the check (and possible set) after cache insertion.
+ */
+ relation->rd_rel->relhasindex =
+ CatalogHasIndex(relationName, relation->rd_id);
}
/* ----------------------------------------------------------------
- * Relation Descriptor Lookup Interface
+ * Relation Descriptor Lookup Interface
* ----------------------------------------------------------------
*/
/* --------------------------------
- * RelationIdCacheGetRelation
+ * RelationIdCacheGetRelation
*
- * only try to get the reldesc by looking up the cache
- * do not go to the disk. this is used by BlockPrepareFile()
- * and RelationIdGetRelation below.
+ * only try to get the reldesc by looking up the cache
+ * do not go to the disk. this is used by BlockPrepareFile()
+ * and RelationIdGetRelation below.
* --------------------------------
*/
Relation
RelationIdCacheGetRelation(Oid relationId)
{
- Relation rd;
-
- RelationIdCacheLookup(relationId, rd);
-
- if (RelationIsValid(rd)) {
- if (rd->rd_fd == -1) {
- rd->rd_fd = smgropen(rd->rd_rel->relsmgr, rd);
- Assert(rd->rd_fd != -1);
+ Relation rd;
+
+ RelationIdCacheLookup(relationId, rd);
+
+ if (RelationIsValid(rd))
+ {
+ if (rd->rd_fd == -1)
+ {
+ rd->rd_fd = smgropen(rd->rd_rel->relsmgr, rd);
+ Assert(rd->rd_fd != -1);
+ }
+
+ RelationIncrementReferenceCount(rd);
+ RelationSetLockForDescriptorOpen(rd);
+
}
-
- RelationIncrementReferenceCount(rd);
- RelationSetLockForDescriptorOpen(rd);
-
- }
-
- return(rd);
+
+ return (rd);
}
/* --------------------------------
- * RelationNameCacheGetRelation
+ * RelationNameCacheGetRelation
* --------------------------------
*/
-static Relation
+static Relation
RelationNameCacheGetRelation(char *relationName)
{
- Relation rd;
- NameData name;
-
- /* make sure that the name key used for hash lookup is properly
- null-padded */
- namestrcpy(&name, relationName);
- RelationNameCacheLookup(name.data, rd);
-
- if (RelationIsValid(rd)) {
- if (rd->rd_fd == -1) {
- rd->rd_fd = smgropen(rd->rd_rel->relsmgr, rd);
- Assert(rd->rd_fd != -1);
+ Relation rd;
+ NameData name;
+
+ /*
+ * make sure that the name key used for hash lookup is properly
+ * null-padded
+ */
+ namestrcpy(&name, relationName);
+ RelationNameCacheLookup(name.data, rd);
+
+ if (RelationIsValid(rd))
+ {
+ if (rd->rd_fd == -1)
+ {
+ rd->rd_fd = smgropen(rd->rd_rel->relsmgr, rd);
+ Assert(rd->rd_fd != -1);
+ }
+
+ RelationIncrementReferenceCount(rd);
+ RelationSetLockForDescriptorOpen(rd);
+
}
-
- RelationIncrementReferenceCount(rd);
- RelationSetLockForDescriptorOpen(rd);
-
- }
-
- return(rd);
+
+ return (rd);
}
/* --------------------------------
- * RelationIdGetRelation
+ * RelationIdGetRelation
*
- * return a relation descriptor based on its id.
- * return a cached value if possible
+ * return a relation descriptor based on its id.
+ * return a cached value if possible
* --------------------------------
*/
Relation
RelationIdGetRelation(Oid relationId)
{
- Relation rd;
- RelationBuildDescInfo buildinfo;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_RelationIdGetRelation);
- IncrHeapAccessStat(global_RelationIdGetRelation);
-
- /* ----------------
- * first try and get a reldesc from the cache
- * ----------------
- */
- rd = RelationIdCacheGetRelation(relationId);
- if (RelationIsValid(rd))
- return rd;
-
- /* ----------------
- * no reldesc in the cache, so have RelationBuildDesc()
- * build one and add it.
- * ----------------
- */
- buildinfo.infotype = INFO_RELID;
- buildinfo.i.info_id = relationId;
-
- rd = RelationBuildDesc(buildinfo);
- return
- rd;
+ Relation rd;
+ RelationBuildDescInfo buildinfo;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_RelationIdGetRelation);
+ IncrHeapAccessStat(global_RelationIdGetRelation);
+
+ /* ----------------
+ * first try and get a reldesc from the cache
+ * ----------------
+ */
+ rd = RelationIdCacheGetRelation(relationId);
+ if (RelationIsValid(rd))
+ return rd;
+
+ /* ----------------
+ * no reldesc in the cache, so have RelationBuildDesc()
+ * build one and add it.
+ * ----------------
+ */
+ buildinfo.infotype = INFO_RELID;
+ buildinfo.i.info_id = relationId;
+
+ rd = RelationBuildDesc(buildinfo);
+ return
+ rd;
}
/* --------------------------------
- * RelationNameGetRelation
+ * RelationNameGetRelation
*
- * return a relation descriptor based on its name.
- * return a cached value if possible
+ * return a relation descriptor based on its name.
+ * return a cached value if possible
* --------------------------------
*/
Relation
RelationNameGetRelation(char *relationName)
{
- Relation rd;
- RelationBuildDescInfo buildinfo;
-
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_RelationNameGetRelation);
- IncrHeapAccessStat(global_RelationNameGetRelation);
-
- /* ----------------
- * first try and get a reldesc from the cache
- * ----------------
- */
- rd = RelationNameCacheGetRelation(relationName);
- if (RelationIsValid(rd))
+ Relation rd;
+ RelationBuildDescInfo buildinfo;
+
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_RelationNameGetRelation);
+ IncrHeapAccessStat(global_RelationNameGetRelation);
+
+ /* ----------------
+ * first try and get a reldesc from the cache
+ * ----------------
+ */
+ rd = RelationNameCacheGetRelation(relationName);
+ if (RelationIsValid(rd))
+ return rd;
+
+ /* ----------------
+ * no reldesc in the cache, so have RelationBuildDesc()
+ * build one and add it.
+ * ----------------
+ */
+ buildinfo.infotype = INFO_RELNAME;
+ buildinfo.i.info_name = relationName;
+
+ rd = RelationBuildDesc(buildinfo);
return rd;
-
- /* ----------------
- * no reldesc in the cache, so have RelationBuildDesc()
- * build one and add it.
- * ----------------
- */
- buildinfo.infotype = INFO_RELNAME;
- buildinfo.i.info_name = relationName;
-
- rd = RelationBuildDesc(buildinfo);
- return rd;
}
/* ----------------
- * old "getreldesc" interface.
+ * old "getreldesc" interface.
* ----------------
*/
#ifdef NOT_USED
Relation
getreldesc(char *relationName)
{
- /* ----------------
- * increment access statistics
- * ----------------
- */
- IncrHeapAccessStat(local_getreldesc);
- IncrHeapAccessStat(global_getreldesc);
-
- return RelationNameGetRelation(relationName);
+ /* ----------------
+ * increment access statistics
+ * ----------------
+ */
+ IncrHeapAccessStat(local_getreldesc);
+ IncrHeapAccessStat(global_getreldesc);
+
+ return RelationNameGetRelation(relationName);
}
+
#endif
/* ----------------------------------------------------------------
- * cache invalidation support routines
+ * cache invalidation support routines
* ----------------------------------------------------------------
*/
/* --------------------------------
- * RelationClose - close an open relation
+ * RelationClose - close an open relation
* --------------------------------
*/
void
RelationClose(Relation relation)
{
- /* Note: no locking manipulations needed */
- RelationDecrementReferenceCount(relation);
+ /* Note: no locking manipulations needed */
+ RelationDecrementReferenceCount(relation);
}
/* --------------------------------
* RelationFlushRelation
*
- * Actually blows away a relation... RelationFree doesn't do
- * anything anymore.
+ * Actually blows away a relation... RelationFree doesn't do
+ * anything anymore.
* --------------------------------
*/
static void
-RelationFlushRelation(Relation *relationPtr,
- bool onlyFlushReferenceCountZero)
+RelationFlushRelation(Relation * relationPtr,
+ bool onlyFlushReferenceCountZero)
{
- MemoryContext oldcxt;
- Relation relation = *relationPtr;
-
- if (relation->rd_isnailed) {
- /* this is a nailed special relation for bootstraping */
- return;
- }
-
- if (!onlyFlushReferenceCountZero ||
- RelationHasReferenceCountZero(relation)) {
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- RelationCacheDelete(relation);
-
- FreeTupleDesc (relation->rd_att);
-
- FreeTriggerDesc (relation);
+ MemoryContext oldcxt;
+ Relation relation = *relationPtr;
-#if 0
- if (relation->rd_rules) {
- int j;
- for(j=0; j < relation->rd_rules->numLocks; j++) {
- pfree(relation->rd_rules->rules[j]);
- }
- pfree(relation->rd_rules->rules);
- pfree(relation->rd_rules);
+ if (relation->rd_isnailed)
+ {
+ /* this is a nailed special relation for bootstraping */
+ return;
}
+
+ if (!onlyFlushReferenceCountZero ||
+ RelationHasReferenceCountZero(relation))
+ {
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ RelationCacheDelete(relation);
+
+ FreeTupleDesc(relation->rd_att);
+
+ FreeTriggerDesc(relation);
+
+#if 0
+ if (relation->rd_rules)
+ {
+ int j;
+
+ for (j = 0; j < relation->rd_rules->numLocks; j++)
+ {
+ pfree(relation->rd_rules->rules[j]);
+ }
+ pfree(relation->rd_rules->rules);
+ pfree(relation->rd_rules);
+ }
#endif
-
- pfree(RelationGetLockInfo(relation));
- pfree(RelationGetRelationTupleForm(relation));
- pfree(relation);
-
- MemoryContextSwitchTo(oldcxt);
- }
+
+ pfree(RelationGetLockInfo(relation));
+ pfree(RelationGetRelationTupleForm(relation));
+ pfree(relation);
+
+ MemoryContextSwitchTo(oldcxt);
+ }
}
/* --------------------------------
- * RelationForgetRelation -
- * RelationFlushRelation + if the relation is local then get rid of
- * the relation descriptor from the newly created relation list.
+ * RelationForgetRelation -
+ * RelationFlushRelation + if the relation is local then get rid of
+ * the relation descriptor from the newly created relation list.
* --------------------------------
*/
void
-RelationForgetRelation (Oid rid)
+RelationForgetRelation(Oid rid)
{
- Relation relation;
-
- RelationIdCacheLookup (rid, relation);
- Assert ( PointerIsValid (relation) );
-
- if ( relation->rd_islocal )
- {
- MemoryContext oldcxt;
- List *curr;
- List *prev = NIL;
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- foreach (curr, newlyCreatedRelns)
- {
- Relation reln = lfirst(curr);
-
- Assert ( reln != NULL && reln->rd_islocal );
- if ( reln->rd_id == rid )
- break;
- prev = curr;
- }
- if ( curr == NIL )
- elog (FATAL, "Local relation %s not found in list",
- (RelationGetRelationName(relation))->data);
- if ( prev == NIL )
- newlyCreatedRelns = lnext (newlyCreatedRelns);
- else
- lnext (prev) = lnext (curr);
- pfree (curr);
- MemoryContextSwitchTo(oldcxt);
- }
-
- RelationFlushRelation (&relation, false);
+ Relation relation;
+
+ RelationIdCacheLookup(rid, relation);
+ Assert(PointerIsValid(relation));
+
+ if (relation->rd_islocal)
+ {
+ MemoryContext oldcxt;
+ List *curr;
+ List *prev = NIL;
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ foreach(curr, newlyCreatedRelns)
+ {
+ Relation reln = lfirst(curr);
+
+ Assert(reln != NULL && reln->rd_islocal);
+ if (reln->rd_id == rid)
+ break;
+ prev = curr;
+ }
+ if (curr == NIL)
+ elog(FATAL, "Local relation %s not found in list",
+ (RelationGetRelationName(relation))->data);
+ if (prev == NIL)
+ newlyCreatedRelns = lnext(newlyCreatedRelns);
+ else
+ lnext(prev) = lnext(curr);
+ pfree(curr);
+ MemoryContextSwitchTo(oldcxt);
+ }
+
+ RelationFlushRelation(&relation, false);
}
/* --------------------------------
- * RelationIdInvalidateRelationCacheByRelationId
+ * RelationIdInvalidateRelationCacheByRelationId
* --------------------------------
*/
void
RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
{
- Relation relation;
-
- RelationIdCacheLookup(relationId, relation);
-
- /*
- * "local" relations are invalidated by RelationPurgeLocalRelation.
- * (This is to make LocalBufferSync's life easier: want the descriptor
- * to hang around for a while. In fact, won't we want this for
- * BufferSync also? But I'll leave it for now since I don't want to
- * break anything.) - ay 3/95
- */
- if (PointerIsValid(relation) && !relation->rd_islocal) {
+ Relation relation;
+
+ RelationIdCacheLookup(relationId, relation);
+
/*
- * The boolean onlyFlushReferenceCountZero in RelationFlushReln()
- * should be set to true when we are incrementing the command
- * counter and to false when we are starting a new xaction. This
- * can be determined by checking the current xaction status.
+ * "local" relations are invalidated by RelationPurgeLocalRelation.
+ * (This is to make LocalBufferSync's life easier: want the descriptor
+ * to hang around for a while. In fact, won't we want this for
+ * BufferSync also? But I'll leave it for now since I don't want to
+ * break anything.) - ay 3/95
*/
- RelationFlushRelation(&relation, CurrentXactInProgress());
- }
+ if (PointerIsValid(relation) && !relation->rd_islocal)
+ {
+
+ /*
+ * The boolean onlyFlushReferenceCountZero in RelationFlushReln()
+ * should be set to true when we are incrementing the command
+ * counter and to false when we are starting a new xaction. This
+ * can be determined by checking the current xaction status.
+ */
+ RelationFlushRelation(&relation, CurrentXactInProgress());
+ }
}
-#if NOT_USED /* See comments at line 1304 */
+#if NOT_USED /* See comments at line 1304 */
/* --------------------------------
- * RelationIdInvalidateRelationCacheByAccessMethodId
+ * RelationIdInvalidateRelationCacheByAccessMethodId
*
- * RelationFlushIndexes is needed for use with HashTableWalk..
+ * RelationFlushIndexes is needed for use with HashTableWalk..
* --------------------------------
*/
static void
-RelationFlushIndexes(Relation *r,
- Oid accessMethodId)
+RelationFlushIndexes(Relation * r,
+ Oid accessMethodId)
{
- Relation relation = *r;
-
- if (!RelationIsValid(relation)) {
- elog(NOTICE, "inval call to RFI");
- return;
- }
-
- if (relation->rd_rel->relkind == RELKIND_INDEX && /* XXX style */
- (!OidIsValid(accessMethodId) ||
- relation->rd_rel->relam == accessMethodId))
+ Relation relation = *r;
+
+ if (!RelationIsValid(relation))
+ {
+ elog(NOTICE, "inval call to RFI");
+ return;
+ }
+
+ if (relation->rd_rel->relkind == RELKIND_INDEX && /* XXX style */
+ (!OidIsValid(accessMethodId) ||
+ relation->rd_rel->relam == accessMethodId))
{
- RelationFlushRelation(&relation, false);
+ RelationFlushRelation(&relation, false);
}
}
+
#endif
void
RelationIdInvalidateRelationCacheByAccessMethodId(Oid accessMethodId)
{
-# if 0
- /*
- * 25 aug 1992: mao commented out the ht walk below. it should be
- * doing the right thing, in theory, but flushing reldescs for index
- * relations apparently doesn't work. we want to cut 4.0.1, and i
- * don't want to introduce new bugs. this code never executed before,
- * so i'm turning it off for now. after the release is cut, i'll
- * fix this up.
- */
-
- HashTableWalk(RelationNameCache, (HashtFunc) RelationFlushIndexes,
- accessMethodId);
-# else
- return;
-# endif
+#if 0
+
+ /*
+ * 25 aug 1992: mao commented out the ht walk below. it should be
+ * doing the right thing, in theory, but flushing reldescs for index
+ * relations apparently doesn't work. we want to cut 4.0.1, and i
+ * don't want to introduce new bugs. this code never executed before,
+ * so i'm turning it off for now. after the release is cut, i'll fix
+ * this up.
+ */
+
+ HashTableWalk(RelationNameCache, (HashtFunc) RelationFlushIndexes,
+ accessMethodId);
+#else
+ return;
+#endif
}
/*
* RelationCacheInvalidate
*
- * Will blow away either all the cached relation descriptors or
- * those that have a zero reference count.
+ * Will blow away either all the cached relation descriptors or
+ * those that have a zero reference count.
*
*/
void
RelationCacheInvalidate(bool onlyFlushReferenceCountZero)
{
- HashTableWalk(RelationNameCache, (HashtFunc) RelationFlushRelation,
- onlyFlushReferenceCountZero);
-
- /*
- * nailed-in reldescs will still be in the cache...
- * 7 hardwired heaps + 3 hardwired indices == 10 total.
- */
- if (!onlyFlushReferenceCountZero) {
- Assert(RelationNameCache->hctl->nkeys == 10);
- Assert(RelationIdCache->hctl->nkeys == 10);
- }
+ HashTableWalk(RelationNameCache, (HashtFunc) RelationFlushRelation,
+ onlyFlushReferenceCountZero);
+
+ /*
+ * nailed-in reldescs will still be in the cache... 7 hardwired heaps
+ * + 3 hardwired indices == 10 total.
+ */
+ if (!onlyFlushReferenceCountZero)
+ {
+ Assert(RelationNameCache->hctl->nkeys == 10);
+ Assert(RelationIdCache->hctl->nkeys == 10);
+ }
}
-
+
/* --------------------------------
- * RelationRegisterRelation -
- * register the Relation descriptor of a newly created relation
- * with the relation descriptor Cache.
+ * RelationRegisterRelation -
+ * register the Relation descriptor of a newly created relation
+ * with the relation descriptor Cache.
* --------------------------------
*/
void
RelationRegisterRelation(Relation relation)
{
- MemoryContext oldcxt;
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- if (oldcxt != (MemoryContext)CacheCxt)
- elog(NOIND,"RelationRegisterRelation: WARNING: Context != CacheCxt");
-
- RelationCacheInsert(relation);
-
- RelationInitLockInfo(relation);
-
- /*
- * we've just created the relation. It is invisible to anyone else
- * before the transaction is committed. Setting rd_islocal allows us
- * to use the local buffer manager for select/insert/etc before the end
- * of transaction. (We also need to keep track of relations
- * created during a transaction and does the necessary clean up at
- * the end of the transaction.) - ay 3/95
- */
- relation->rd_islocal = TRUE;
- newlyCreatedRelns = lcons(relation, newlyCreatedRelns);
-
- MemoryContextSwitchTo(oldcxt);
+ MemoryContext oldcxt;
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ if (oldcxt != (MemoryContext) CacheCxt)
+ elog(NOIND, "RelationRegisterRelation: WARNING: Context != CacheCxt");
+
+ RelationCacheInsert(relation);
+
+ RelationInitLockInfo(relation);
+
+ /*
+ * we've just created the relation. It is invisible to anyone else
+ * before the transaction is committed. Setting rd_islocal allows us
+ * to use the local buffer manager for select/insert/etc before the
+ * end of transaction. (We also need to keep track of relations
+ * created during a transaction and does the necessary clean up at the
+ * end of the transaction.) - ay 3/95
+ */
+ relation->rd_islocal = TRUE;
+ newlyCreatedRelns = lcons(relation, newlyCreatedRelns);
+
+ MemoryContextSwitchTo(oldcxt);
}
/*
* RelationPurgeLocalRelation -
- * find all the Relation descriptors marked rd_islocal and reset them.
- * This should be called at the end of a transaction (commit/abort) when
- * the "local" relations will become visible to others and the multi-user
- * buffer pool should be used.
+ * find all the Relation descriptors marked rd_islocal and reset them.
+ * This should be called at the end of a transaction (commit/abort) when
+ * the "local" relations will become visible to others and the multi-user
+ * buffer pool should be used.
*/
void
RelationPurgeLocalRelation(bool xactCommitted)
{
- MemoryContext oldcxt;
-
- if (newlyCreatedRelns==NULL)
- return;
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- while (newlyCreatedRelns) {
- List *l = newlyCreatedRelns;
- Relation reln = lfirst(l);
-
- Assert(reln!=NULL && reln->rd_islocal);
-
- if (!xactCommitted) {
- /*
- * remove the file if we abort. This is so that files for
- * tables created inside a transaction block get removed.
- */
- if(reln->rd_istemp) {
- if(!(reln->rd_tmpunlinked)) {
- smgrunlink(reln->rd_rel->relsmgr, reln);
- reln->rd_tmpunlinked = TRUE;
- }
- } else {
- smgrunlink(reln->rd_rel->relsmgr, reln);
- }
- }
- else if ( !IsBootstrapProcessingMode () && !(reln->rd_istemp) )
- /*
- * RelationFlushRelation () below will flush relation information
- * from the cache. We must call smgrclose to flush relation
- * information from SMGR & FMGR, too. We assume that for temp
- * relations smgrunlink is already called by heap_destroyr
- * and we skip smgrclose for them. - vadim 05/22/97
- */
- smgrclose(reln->rd_rel->relsmgr, reln);
-
- reln->rd_islocal = FALSE;
+ MemoryContext oldcxt;
- if (!IsBootstrapProcessingMode())
- RelationFlushRelation(&reln, FALSE);
-
- newlyCreatedRelns = lnext(newlyCreatedRelns);
- pfree(l);
- }
+ if (newlyCreatedRelns == NULL)
+ return;
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
- MemoryContextSwitchTo(oldcxt);
+ while (newlyCreatedRelns)
+ {
+ List *l = newlyCreatedRelns;
+ Relation reln = lfirst(l);
+
+ Assert(reln != NULL && reln->rd_islocal);
+
+ if (!xactCommitted)
+ {
+
+ /*
+ * remove the file if we abort. This is so that files for
+ * tables created inside a transaction block get removed.
+ */
+ if (reln->rd_istemp)
+ {
+ if (!(reln->rd_tmpunlinked))
+ {
+ smgrunlink(reln->rd_rel->relsmgr, reln);
+ reln->rd_tmpunlinked = TRUE;
+ }
+ }
+ else
+ {
+ smgrunlink(reln->rd_rel->relsmgr, reln);
+ }
+ }
+ else if (!IsBootstrapProcessingMode() && !(reln->rd_istemp))
+
+ /*
+ * RelationFlushRelation () below will flush relation
+ * information from the cache. We must call smgrclose to flush
+ * relation information from SMGR & FMGR, too. We assume that
+ * for temp relations smgrunlink is already called by
+ * heap_destroyr and we skip smgrclose for them. -
+ * vadim 05/22/97
+ */
+ smgrclose(reln->rd_rel->relsmgr, reln);
+
+ reln->rd_islocal = FALSE;
+
+ if (!IsBootstrapProcessingMode())
+ RelationFlushRelation(&reln, FALSE);
+
+ newlyCreatedRelns = lnext(newlyCreatedRelns);
+ pfree(l);
+ }
+
+ MemoryContextSwitchTo(oldcxt);
}
/* --------------------------------
- * RelationInitialize
+ * RelationInitialize
*
- * This initializes the relation descriptor cache.
+ * This initializes the relation descriptor cache.
* --------------------------------
*/
-#define INITRELCACHESIZE 400
+#define INITRELCACHESIZE 400
void
RelationInitialize(void)
{
- MemoryContext oldcxt;
- HASHCTL ctl;
-
- /* ----------------
- * switch to cache memory context
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
-
- oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
-
- /* ----------------
- * create global caches
- * ----------------
- */
- memset(&ctl,0, (int) sizeof(ctl));
- ctl.keysize = sizeof(NameData);
- ctl.datasize = sizeof(Relation);
- RelationNameCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM);
-
- ctl.keysize = sizeof(Oid);
- ctl.hash = tag_hash;
- RelationIdCache = hash_create(INITRELCACHESIZE, &ctl,
- HASH_ELEM | HASH_FUNCTION);
-
- /* ----------------
- * initialize the cache with pre-made relation descriptors
- * for some of the more important system relations. These
- * relations should always be in the cache.
- * ----------------
- */
- formrdesc(RelationRelationName, Natts_pg_class, Desc_pg_class);
- formrdesc(AttributeRelationName, Natts_pg_attribute, Desc_pg_attribute);
- formrdesc(ProcedureRelationName, Natts_pg_proc, Desc_pg_proc);
- formrdesc(TypeRelationName, Natts_pg_type, Desc_pg_type);
- formrdesc(VariableRelationName, Natts_pg_variable, Desc_pg_variable);
- formrdesc(LogRelationName, Natts_pg_log, Desc_pg_log);
- formrdesc(TimeRelationName, Natts_pg_time, Desc_pg_time);
-
- /*
- * If this isn't initdb time, then we want to initialize some index
- * relation descriptors, as well. The descriptors are for pg_attnumind
- * (to make building relation descriptors fast) and possibly others,
- * as they're added.
- */
-
- if (!IsBootstrapProcessingMode())
- init_irels();
-
- MemoryContextSwitchTo(oldcxt);
+ MemoryContext oldcxt;
+ HASHCTL ctl;
+
+ /* ----------------
+ * switch to cache memory context
+ * ----------------
+ */
+ if (!CacheCxt)
+ CacheCxt = CreateGlobalMemory("Cache");
+
+ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
+
+ /* ----------------
+ * create global caches
+ * ----------------
+ */
+ memset(&ctl, 0, (int) sizeof(ctl));
+ ctl.keysize = sizeof(NameData);
+ ctl.datasize = sizeof(Relation);
+ RelationNameCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM);
+
+ ctl.keysize = sizeof(Oid);
+ ctl.hash = tag_hash;
+ RelationIdCache = hash_create(INITRELCACHESIZE, &ctl,
+ HASH_ELEM | HASH_FUNCTION);
+
+ /* ----------------
+ * initialize the cache with pre-made relation descriptors
+ * for some of the more important system relations. These
+ * relations should always be in the cache.
+ * ----------------
+ */
+ formrdesc(RelationRelationName, Natts_pg_class, Desc_pg_class);
+ formrdesc(AttributeRelationName, Natts_pg_attribute, Desc_pg_attribute);
+ formrdesc(ProcedureRelationName, Natts_pg_proc, Desc_pg_proc);
+ formrdesc(TypeRelationName, Natts_pg_type, Desc_pg_type);
+ formrdesc(VariableRelationName, Natts_pg_variable, Desc_pg_variable);
+ formrdesc(LogRelationName, Natts_pg_log, Desc_pg_log);
+ formrdesc(TimeRelationName, Natts_pg_time, Desc_pg_time);
+
+ /*
+ * If this isn't initdb time, then we want to initialize some index
+ * relation descriptors, as well. The descriptors are for
+ * pg_attnumind (to make building relation descriptors fast) and
+ * possibly others, as they're added.
+ */
+
+ if (!IsBootstrapProcessingMode())
+ init_irels();
+
+ MemoryContextSwitchTo(oldcxt);
}
static void
-AttrDefaultFetch (Relation relation)
+AttrDefaultFetch(Relation relation)
{
- AttrDefault *attrdef = relation->rd_att->constr->defval;
- int ndef = relation->rd_att->constr->num_defval;
- Relation adrel;
- Relation irel;
- ScanKeyData skey;
- HeapTuple tuple;
- Form_pg_attrdef adform;
- IndexScanDesc sd;
- RetrieveIndexResult indexRes;
- Buffer buffer;
- ItemPointer iptr;
- struct varlena *val;
- bool isnull;
- int found;
- int i;
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relation->rd_id));
-
- adrel = heap_openr(AttrDefaultRelationName);
- irel = index_openr(AttrDefaultIndex);
- sd = index_beginscan(irel, false, 1, &skey);
- tuple = (HeapTuple)NULL;
-
- for (found = 0; ; )
- {
- indexRes = index_getnext(sd, ForwardScanDirection);
- if (!indexRes)
- break;
-
- iptr = &indexRes->heap_iptr;
- tuple = heap_fetch(adrel, NowTimeQual, iptr, &buffer);
- pfree(indexRes);
- if (!HeapTupleIsValid(tuple))
- continue;
- found++;
- adform = (Form_pg_attrdef) GETSTRUCT(tuple);
- for (i = 0; i < ndef; i++)
- {
- if ( adform->adnum != attrdef[i].adnum )
- continue;
- if ( attrdef[i].adsrc != NULL )
- elog (WARN, "AttrDefaultFetch: second record found for attr %.*s in rel %.*s",
- NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
- NAMEDATALEN, relation->rd_rel->relname.data);
-
- val = (struct varlena*) fastgetattr (tuple,
- Anum_pg_attrdef_adbin,
- adrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "AttrDefaultFetch: adbin IS NULL for attr %.*s in rel %.*s",
- NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
- NAMEDATALEN, relation->rd_rel->relname.data);
- attrdef[i].adbin = textout (val);
- val = (struct varlena*) fastgetattr (tuple,
- Anum_pg_attrdef_adsrc,
- adrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "AttrDefaultFetch: adsrc IS NULL for attr %.*s in rel %.*s",
- NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
- NAMEDATALEN, relation->rd_rel->relname.data);
- attrdef[i].adsrc = textout (val);
- break;
- }
-
- if ( i >= ndef )
- elog (WARN, "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s",
- adform->adnum,
- NAMEDATALEN, relation->rd_rel->relname.data);
- ReleaseBuffer(buffer);
- }
-
- if ( found < ndef )
- elog (WARN, "AttrDefaultFetch: %d record not found for rel %.*s",
- ndef - found,
- NAMEDATALEN, relation->rd_rel->relname.data);
-
- index_endscan (sd);
- pfree (sd);
- index_close (irel);
- heap_close (adrel);
-
+ AttrDefault *attrdef = relation->rd_att->constr->defval;
+ int ndef = relation->rd_att->constr->num_defval;
+ Relation adrel;
+ Relation irel;
+ ScanKeyData skey;
+ HeapTuple tuple;
+ Form_pg_attrdef adform;
+ IndexScanDesc sd;
+ RetrieveIndexResult indexRes;
+ Buffer buffer;
+ ItemPointer iptr;
+ struct varlena *val;
+ bool isnull;
+ int found;
+ int i;
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relation->rd_id));
+
+ adrel = heap_openr(AttrDefaultRelationName);
+ irel = index_openr(AttrDefaultIndex);
+ sd = index_beginscan(irel, false, 1, &skey);
+ tuple = (HeapTuple) NULL;
+
+ for (found = 0;;)
+ {
+ indexRes = index_getnext(sd, ForwardScanDirection);
+ if (!indexRes)
+ break;
+
+ iptr = &indexRes->heap_iptr;
+ tuple = heap_fetch(adrel, NowTimeQual, iptr, &buffer);
+ pfree(indexRes);
+ if (!HeapTupleIsValid(tuple))
+ continue;
+ found++;
+ adform = (Form_pg_attrdef) GETSTRUCT(tuple);
+ for (i = 0; i < ndef; i++)
+ {
+ if (adform->adnum != attrdef[i].adnum)
+ continue;
+ if (attrdef[i].adsrc != NULL)
+ elog(WARN, "AttrDefaultFetch: second record found for attr %.*s in rel %.*s",
+ NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+
+ val = (struct varlena *) fastgetattr(tuple,
+ Anum_pg_attrdef_adbin,
+ adrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "AttrDefaultFetch: adbin IS NULL for attr %.*s in rel %.*s",
+ NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ attrdef[i].adbin = textout(val);
+ val = (struct varlena *) fastgetattr(tuple,
+ Anum_pg_attrdef_adsrc,
+ adrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "AttrDefaultFetch: adsrc IS NULL for attr %.*s in rel %.*s",
+ NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ attrdef[i].adsrc = textout(val);
+ break;
+ }
+
+ if (i >= ndef)
+ elog(WARN, "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s",
+ adform->adnum,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ ReleaseBuffer(buffer);
+ }
+
+ if (found < ndef)
+ elog(WARN, "AttrDefaultFetch: %d record not found for rel %.*s",
+ ndef - found,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+
+ index_endscan(sd);
+ pfree(sd);
+ index_close(irel);
+ heap_close(adrel);
+
}
static void
-RelCheckFetch (Relation relation)
+RelCheckFetch(Relation relation)
{
- ConstrCheck *check = relation->rd_att->constr->check;
- int ncheck = relation->rd_att->constr->num_check;
- Relation rcrel;
- Relation irel;
- ScanKeyData skey;
- HeapTuple tuple;
- IndexScanDesc sd;
- RetrieveIndexResult indexRes;
- Buffer buffer;
- ItemPointer iptr;
- Name rcname;
- struct varlena *val;
- bool isnull;
- int found;
-
- ScanKeyEntryInitialize(&skey,
- (bits16)0x0,
- (AttrNumber)1,
- (RegProcedure)ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(relation->rd_id));
-
- rcrel = heap_openr(RelCheckRelationName);
- irel = index_openr(RelCheckIndex);
- sd = index_beginscan(irel, false, 1, &skey);
- tuple = (HeapTuple)NULL;
-
- for (found = 0; ; )
- {
- indexRes = index_getnext(sd, ForwardScanDirection);
- if (!indexRes)
- break;
-
- iptr = &indexRes->heap_iptr;
- tuple = heap_fetch(rcrel, NowTimeQual, iptr, &buffer);
- pfree(indexRes);
- if (!HeapTupleIsValid(tuple))
- continue;
- if ( found == ncheck )
- elog (WARN, "RelCheckFetch: unexpected record found for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
-
- rcname = (Name) fastgetattr (tuple,
- Anum_pg_relcheck_rcname,
- rcrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "RelCheckFetch: rcname IS NULL for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
- check[found].ccname = nameout (rcname);
- val = (struct varlena*) fastgetattr (tuple,
- Anum_pg_relcheck_rcbin,
- rcrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "RelCheckFetch: rcbin IS NULL for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
- check[found].ccbin = textout (val);
- val = (struct varlena*) fastgetattr (tuple,
- Anum_pg_relcheck_rcsrc,
- rcrel->rd_att, &isnull);
- if ( isnull )
- elog (WARN, "RelCheckFetch: rcsrc IS NULL for rel %.*s",
- NAMEDATALEN, relation->rd_rel->relname.data);
- check[found].ccsrc = textout (val);
- found++;
-
- ReleaseBuffer(buffer);
- }
-
- if ( found < ncheck )
- elog (WARN, "RelCheckFetch: %d record not found for rel %.*s",
- ncheck - found,
- NAMEDATALEN, relation->rd_rel->relname.data);
-
- index_endscan (sd);
- pfree (sd);
- index_close (irel);
- heap_close (rcrel);
-
+ ConstrCheck *check = relation->rd_att->constr->check;
+ int ncheck = relation->rd_att->constr->num_check;
+ Relation rcrel;
+ Relation irel;
+ ScanKeyData skey;
+ HeapTuple tuple;
+ IndexScanDesc sd;
+ RetrieveIndexResult indexRes;
+ Buffer buffer;
+ ItemPointer iptr;
+ Name rcname;
+ struct varlena *val;
+ bool isnull;
+ int found;
+
+ ScanKeyEntryInitialize(&skey,
+ (bits16) 0x0,
+ (AttrNumber) 1,
+ (RegProcedure) ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(relation->rd_id));
+
+ rcrel = heap_openr(RelCheckRelationName);
+ irel = index_openr(RelCheckIndex);
+ sd = index_beginscan(irel, false, 1, &skey);
+ tuple = (HeapTuple) NULL;
+
+ for (found = 0;;)
+ {
+ indexRes = index_getnext(sd, ForwardScanDirection);
+ if (!indexRes)
+ break;
+
+ iptr = &indexRes->heap_iptr;
+ tuple = heap_fetch(rcrel, NowTimeQual, iptr, &buffer);
+ pfree(indexRes);
+ if (!HeapTupleIsValid(tuple))
+ continue;
+ if (found == ncheck)
+ elog(WARN, "RelCheckFetch: unexpected record found for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+
+ rcname = (Name) fastgetattr(tuple,
+ Anum_pg_relcheck_rcname,
+ rcrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "RelCheckFetch: rcname IS NULL for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ check[found].ccname = nameout(rcname);
+ val = (struct varlena *) fastgetattr(tuple,
+ Anum_pg_relcheck_rcbin,
+ rcrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "RelCheckFetch: rcbin IS NULL for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ check[found].ccbin = textout(val);
+ val = (struct varlena *) fastgetattr(tuple,
+ Anum_pg_relcheck_rcsrc,
+ rcrel->rd_att, &isnull);
+ if (isnull)
+ elog(WARN, "RelCheckFetch: rcsrc IS NULL for rel %.*s",
+ NAMEDATALEN, relation->rd_rel->relname.data);
+ check[found].ccsrc = textout(val);
+ found++;
+
+ ReleaseBuffer(buffer);
+ }
+
+ if (found < ncheck)
+ elog(WARN, "RelCheckFetch: %d record not found for rel %.*s",
+ ncheck - found,
+ NAMEDATALEN, relation->rd_rel->relname.data);
+
+ index_endscan(sd);
+ pfree(sd);
+ index_close(irel);
+ heap_close(rcrel);
+
}
/*
- * init_irels(), write_irels() -- handle special-case initialization of
- * index relation descriptors.
+ * init_irels(), write_irels() -- handle special-case initialization of
+ * index relation descriptors.
*
- * In late 1992, we started regularly having databases with more than
- * a thousand classes in them. With this number of classes, it became
- * critical to do indexed lookups on the system catalogs.
+ * In late 1992, we started regularly having databases with more than
+ * a thousand classes in them. With this number of classes, it became
+ * critical to do indexed lookups on the system catalogs.
*
- * Bootstrapping these lookups is very hard. We want to be able to
- * use an index on pg_attribute, for example, but in order to do so,
- * we must have read pg_attribute for the attributes in the index,
- * which implies that we need to use the index.
+ * Bootstrapping these lookups is very hard. We want to be able to
+ * use an index on pg_attribute, for example, but in order to do so,
+ * we must have read pg_attribute for the attributes in the index,
+ * which implies that we need to use the index.
*
- * In order to get around the problem, we do the following:
+ * In order to get around the problem, we do the following:
*
- * + When the database system is initialized (at initdb time), we
- * don't use indices on pg_attribute. We do sequential scans.
+ * + When the database system is initialized (at initdb time), we
+ * don't use indices on pg_attribute. We do sequential scans.
*
- * + When the backend is started up in normal mode, we load an image
- * of the appropriate relation descriptors, in internal format,
- * from an initialization file in the data/base/... directory.
+ * + When the backend is started up in normal mode, we load an image
+ * of the appropriate relation descriptors, in internal format,
+ * from an initialization file in the data/base/... directory.
*
- * + If the initialization file isn't there, then we create the
- * relation descriptor using sequential scans and write it to
- * the initialization file for use by subsequent backends.
+ * + If the initialization file isn't there, then we create the
+ * relation descriptor using sequential scans and write it to
+ * the initialization file for use by subsequent backends.
*
- * This is complicated and interferes with system changes, but
- * performance is so bad that we're willing to pay the tax.
+ * This is complicated and interferes with system changes, but
+ * performance is so bad that we're willing to pay the tax.
*/
/* pg_attnumind, pg_classnameind, pg_classoidind */
@@ -1833,268 +1902,288 @@ RelCheckFetch (Relation relation)
static void
init_irels(void)
{
- Size len;
- int nread;
- File fd;
- Relation irel[Num_indices_bootstrap];
- Relation ird;
- Form_pg_am am;
- Form_pg_class relform;
- IndexStrategy strat;
- RegProcedure *support;
- int i;
- int relno;
-
- if ((fd = FileNameOpenFile(INIT_FILENAME, O_RDONLY, 0600)) < 0) {
- write_irels();
- return;
- }
-
- FileSeek(fd, 0L, SEEK_SET);
-
- for (relno = 0; relno < Num_indices_bootstrap; relno++) {
- /* first read the relation descriptor length*/
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- ird = irel[relno] = (Relation) palloc(len);
- memset(ird, 0, len);
-
- /* then, read the Relation structure */
- if ((nread = FileRead(fd, (char*)ird, len)) != len) {
- write_irels();
- return;
- }
-
- /* the file descriptor is not yet opened */
- ird->rd_fd = -1;
-
- /* lock info is not initialized */
- ird->lockInfo = (char *) NULL;
-
- /* next, read the access method tuple form */
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- am = (Form_pg_am) palloc(len);
- if ((nread = FileRead(fd, (char*)am, len)) != len) {
- write_irels();
- return;
- }
-
- ird->rd_am = am;
-
- /* next read the relation tuple form */
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- relform = (Form_pg_class) palloc(len);
- if ((nread = FileRead(fd, (char*)relform, len)) != len) {
- write_irels();
- return;
- }
-
- ird->rd_rel = relform;
-
- /* initialize attribute tuple forms */
- ird->rd_att = CreateTemplateTupleDesc(relform->relnatts);
-
- /* next read all the attribute tuple form data entries */
- len = ATTRIBUTE_TUPLE_SIZE;
- for (i = 0; i < relform->relnatts; i++) {
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- ird->rd_att->attrs[i] = (AttributeTupleForm) palloc(len);
-
- if ((nread = FileRead(fd, (char*)ird->rd_att->attrs[i], len)) != len) {
+ Size len;
+ int nread;
+ File fd;
+ Relation irel[Num_indices_bootstrap];
+ Relation ird;
+ Form_pg_am am;
+ Form_pg_class relform;
+ IndexStrategy strat;
+ RegProcedure *support;
+ int i;
+ int relno;
+
+ if ((fd = FileNameOpenFile(INIT_FILENAME, O_RDONLY, 0600)) < 0)
+ {
write_irels();
return;
- }
- }
-
- /* next, read the index strategy map */
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- strat = (IndexStrategy) palloc(len);
- if ((nread = FileRead(fd, (char*)strat, len)) != len) {
- write_irels();
- return;
}
-
- /* oh, for god's sake... */
+
+ FileSeek(fd, 0L, SEEK_SET);
+
+ for (relno = 0; relno < Num_indices_bootstrap; relno++)
+ {
+ /* first read the relation descriptor length */
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ ird = irel[relno] = (Relation) palloc(len);
+ memset(ird, 0, len);
+
+ /* then, read the Relation structure */
+ if ((nread = FileRead(fd, (char *) ird, len)) != len)
+ {
+ write_irels();
+ return;
+ }
+
+ /* the file descriptor is not yet opened */
+ ird->rd_fd = -1;
+
+ /* lock info is not initialized */
+ ird->lockInfo = (char *) NULL;
+
+ /* next, read the access method tuple form */
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ am = (Form_pg_am) palloc(len);
+ if ((nread = FileRead(fd, (char *) am, len)) != len)
+ {
+ write_irels();
+ return;
+ }
+
+ ird->rd_am = am;
+
+ /* next read the relation tuple form */
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ relform = (Form_pg_class) palloc(len);
+ if ((nread = FileRead(fd, (char *) relform, len)) != len)
+ {
+ write_irels();
+ return;
+ }
+
+ ird->rd_rel = relform;
+
+ /* initialize attribute tuple forms */
+ ird->rd_att = CreateTemplateTupleDesc(relform->relnatts);
+
+ /* next read all the attribute tuple form data entries */
+ len = ATTRIBUTE_TUPLE_SIZE;
+ for (i = 0; i < relform->relnatts; i++)
+ {
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ ird->rd_att->attrs[i] = (AttributeTupleForm) palloc(len);
+
+ if ((nread = FileRead(fd, (char *) ird->rd_att->attrs[i], len)) != len)
+ {
+ write_irels();
+ return;
+ }
+ }
+
+ /* next, read the index strategy map */
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ strat = (IndexStrategy) palloc(len);
+ if ((nread = FileRead(fd, (char *) strat, len)) != len)
+ {
+ write_irels();
+ return;
+ }
+
+ /* oh, for god's sake... */
#define SMD(i) strat[0].strategyMapData[i].entry[0]
-
- /* have to reinit the function pointers in the strategy maps */
- for (i = 0; i < am->amstrategies; i++)
- fmgr_info(SMD(i).sk_procedure,
- &(SMD(i).sk_func), &(SMD(i).sk_nargs));
-
-
- /* use a real field called rd_istrat instead of the
- bogosity of hanging invisible fields off the end of a structure
- - jolly */
- ird->rd_istrat = strat;
-
- /* finally, read the vector of support procedures */
- if ((nread = FileRead(fd, (char*)&len, sizeof(int))) != sizeof(int)) {
- write_irels();
- return;
- }
-
- support = (RegProcedure *) palloc(len);
- if ((nread = FileRead(fd, (char*)support, len)) != len) {
- write_irels();
- return;
- }
-
- /*
- p += sizeof(IndexStrategy);
- *((RegProcedure **) p) = support;
- */
- ird->rd_support = support;
-
- RelationCacheInsert(ird);
- }
+ /* have to reinit the function pointers in the strategy maps */
+ for (i = 0; i < am->amstrategies; i++)
+ fmgr_info(SMD(i).sk_procedure,
+ &(SMD(i).sk_func), &(SMD(i).sk_nargs));
+
+
+ /*
+ * use a real field called rd_istrat instead of the bogosity of
+ * hanging invisible fields off the end of a structure - jolly
+ */
+ ird->rd_istrat = strat;
+
+ /* finally, read the vector of support procedures */
+ if ((nread = FileRead(fd, (char *) &len, sizeof(int))) != sizeof(int))
+ {
+ write_irels();
+ return;
+ }
+
+ support = (RegProcedure *) palloc(len);
+ if ((nread = FileRead(fd, (char *) support, len)) != len)
+ {
+ write_irels();
+ return;
+ }
+
+ /*
+ * p += sizeof(IndexStrategy); ((RegProcedure **) p) = support;
+ */
+
+ ird->rd_support = support;
+
+ RelationCacheInsert(ird);
+ }
}
static void
write_irels(void)
{
- int len;
- int nwritten;
- File fd;
- Relation irel[Num_indices_bootstrap];
- Relation ird;
- Form_pg_am am;
- Form_pg_class relform;
- IndexStrategy strat;
- RegProcedure *support;
- ProcessingMode oldmode;
- int i;
- int relno;
- RelationBuildDescInfo bi;
-
- fd = FileNameOpenFile(INIT_FILENAME, O_WRONLY|O_CREAT|O_TRUNC, 0600);
- if (fd < 0)
- elog(FATAL, "cannot create init file %s", INIT_FILENAME);
-
- FileSeek(fd, 0L, SEEK_SET);
-
- /*
- * Build a relation descriptor for pg_attnumind without resort to the
- * descriptor cache. In order to do this, we set ProcessingMode
- * to Bootstrap. The effect of this is to disable indexed relation
- * searches -- a necessary step, since we're trying to instantiate
- * the index relation descriptors here.
- */
-
- oldmode = GetProcessingMode();
- SetProcessingMode(BootstrapProcessing);
-
- bi.infotype = INFO_RELNAME;
- bi.i.info_name = AttributeNumIndex;
- irel[0] = RelationBuildDesc(bi);
- irel[0]->rd_isnailed = true;
-
- bi.i.info_name = ClassNameIndex;
- irel[1] = RelationBuildDesc(bi);
- irel[1]->rd_isnailed = true;
-
- bi.i.info_name = ClassOidIndex;
- irel[2] = RelationBuildDesc(bi);
- irel[2]->rd_isnailed = true;
-
- SetProcessingMode(oldmode);
-
- /* nail the descriptor in the cache */
- for (relno = 0; relno < Num_indices_bootstrap; relno++) {
- ird = irel[relno];
-
- /* save the volatile fields in the relation descriptor */
- am = ird->rd_am;
- ird->rd_am = (Form_pg_am) NULL;
- relform = ird->rd_rel;
- ird->rd_rel = (Form_pg_class) NULL;
- strat = ird->rd_istrat;
- support = ird->rd_support;
-
- /* first write the relation descriptor , excluding strategy and support */
- len = sizeof(RelationData);
-
- /* first, write the relation descriptor length */
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- descriptor length");
-
- /* next, write out the Relation structure */
- if ((nwritten = FileWrite(fd, (char*) ird, len)) != len)
- elog(FATAL, "cannot write init file -- reldesc");
-
- /* next, write the access method tuple form */
- len = sizeof(FormData_pg_am);
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- am tuple form length");
-
- if ((nwritten = FileWrite(fd, (char*) am, len)) != len)
- elog(FATAL, "cannot write init file -- am tuple form");
-
- /* next write the relation tuple form */
- len = sizeof(FormData_pg_class);
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- relation tuple form length");
-
- if ((nwritten = FileWrite(fd, (char*) relform, len)) != len)
- elog(FATAL, "cannot write init file -- relation tuple form");
-
- /* next, do all the attribute tuple form data entries */
- len = ATTRIBUTE_TUPLE_SIZE;
- for (i = 0; i < relform->relnatts; i++) {
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- length of attdesc %d", i);
- if ((nwritten = FileWrite(fd, (char*) ird->rd_att->attrs[i], len))
- != len)
- elog(FATAL, "cannot write init file -- attdesc %d", i);
+ int len;
+ int nwritten;
+ File fd;
+ Relation irel[Num_indices_bootstrap];
+ Relation ird;
+ Form_pg_am am;
+ Form_pg_class relform;
+ IndexStrategy strat;
+ RegProcedure *support;
+ ProcessingMode oldmode;
+ int i;
+ int relno;
+ RelationBuildDescInfo bi;
+
+ fd = FileNameOpenFile(INIT_FILENAME, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0)
+ elog(FATAL, "cannot create init file %s", INIT_FILENAME);
+
+ FileSeek(fd, 0L, SEEK_SET);
+
+ /*
+ * Build a relation descriptor for pg_attnumind without resort to the
+ * descriptor cache. In order to do this, we set ProcessingMode to
+ * Bootstrap. The effect of this is to disable indexed relation
+ * searches -- a necessary step, since we're trying to instantiate the
+ * index relation descriptors here.
+ */
+
+ oldmode = GetProcessingMode();
+ SetProcessingMode(BootstrapProcessing);
+
+ bi.infotype = INFO_RELNAME;
+ bi.i.info_name = AttributeNumIndex;
+ irel[0] = RelationBuildDesc(bi);
+ irel[0]->rd_isnailed = true;
+
+ bi.i.info_name = ClassNameIndex;
+ irel[1] = RelationBuildDesc(bi);
+ irel[1]->rd_isnailed = true;
+
+ bi.i.info_name = ClassOidIndex;
+ irel[2] = RelationBuildDesc(bi);
+ irel[2]->rd_isnailed = true;
+
+ SetProcessingMode(oldmode);
+
+ /* nail the descriptor in the cache */
+ for (relno = 0; relno < Num_indices_bootstrap; relno++)
+ {
+ ird = irel[relno];
+
+ /* save the volatile fields in the relation descriptor */
+ am = ird->rd_am;
+ ird->rd_am = (Form_pg_am) NULL;
+ relform = ird->rd_rel;
+ ird->rd_rel = (Form_pg_class) NULL;
+ strat = ird->rd_istrat;
+ support = ird->rd_support;
+
+ /*
+ * first write the relation descriptor , excluding strategy and
+ * support
+ */
+ len = sizeof(RelationData);
+
+ /* first, write the relation descriptor length */
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- descriptor length");
+
+ /* next, write out the Relation structure */
+ if ((nwritten = FileWrite(fd, (char *) ird, len)) != len)
+ elog(FATAL, "cannot write init file -- reldesc");
+
+ /* next, write the access method tuple form */
+ len = sizeof(FormData_pg_am);
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- am tuple form length");
+
+ if ((nwritten = FileWrite(fd, (char *) am, len)) != len)
+ elog(FATAL, "cannot write init file -- am tuple form");
+
+ /* next write the relation tuple form */
+ len = sizeof(FormData_pg_class);
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- relation tuple form length");
+
+ if ((nwritten = FileWrite(fd, (char *) relform, len)) != len)
+ elog(FATAL, "cannot write init file -- relation tuple form");
+
+ /* next, do all the attribute tuple form data entries */
+ len = ATTRIBUTE_TUPLE_SIZE;
+ for (i = 0; i < relform->relnatts; i++)
+ {
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- length of attdesc %d", i);
+ if ((nwritten = FileWrite(fd, (char *) ird->rd_att->attrs[i], len))
+ != len)
+ elog(FATAL, "cannot write init file -- attdesc %d", i);
+ }
+
+ /* next, write the index strategy map */
+ len = AttributeNumberGetIndexStrategySize(relform->relnatts,
+ am->amstrategies);
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- strategy map length");
+
+ if ((nwritten = FileWrite(fd, (char *) strat, len)) != len)
+ elog(FATAL, "cannot write init file -- strategy map");
+
+ /* finally, write the vector of support procedures */
+ len = relform->relnatts * (am->amsupport * sizeof(RegProcedure));
+ if ((nwritten = FileWrite(fd, (char *) &len, sizeof(int)))
+ != sizeof(int))
+ elog(FATAL, "cannot write init file -- support vector length");
+
+ if ((nwritten = FileWrite(fd, (char *) support, len)) != len)
+ elog(FATAL, "cannot write init file -- support vector");
+
+ /* restore volatile fields */
+ ird->rd_am = am;
+ ird->rd_rel = relform;
}
-
- /* next, write the index strategy map */
- len = AttributeNumberGetIndexStrategySize(relform->relnatts,
- am->amstrategies);
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- strategy map length");
-
- if ((nwritten = FileWrite(fd, (char*) strat, len)) != len)
- elog(FATAL, "cannot write init file -- strategy map");
-
- /* finally, write the vector of support procedures */
- len = relform->relnatts * (am->amsupport * sizeof(RegProcedure));
- if ((nwritten = FileWrite(fd, (char*) &len, sizeof(int)))
- != sizeof(int))
- elog(FATAL, "cannot write init file -- support vector length");
-
- if ((nwritten = FileWrite(fd, (char*) support, len)) != len)
- elog(FATAL, "cannot write init file -- support vector");
-
- /* restore volatile fields */
- ird->rd_am = am;
- ird->rd_rel = relform;
- }
-
- FileClose(fd);
+
+ FileClose(fd);
}
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 460e8d40af0..5f6c22b95fc 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -1,37 +1,37 @@
/*-------------------------------------------------------------------------
*
* syscache.c--
- * System cache management routines
+ * System cache management routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.4 1996/11/06 10:31:29 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.5 1997/09/07 04:53:10 momjian Exp $
*
* NOTES
- * These routines allow the parser/planner/executor to perform
- * rapid lookups on the contents of the system catalogs.
+ * These routines allow the parser/planner/executor to perform
+ * rapid lookups on the contents of the system catalogs.
*
- * see catalog/syscache.h for a list of the cache id's
+ * see catalog/syscache.h for a list of the cache id's
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-
+
#include "access/heapam.h"
#include "access/htup.h"
#include "catalog/catname.h"
#include "utils/catcache.h"
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-
+
/* ----------------
- * hardwired attribute information comes from system catalog files.
+ * hardwired attribute information comes from system catalog files.
* ----------------
*/
#include "catalog/pg_am.h"
@@ -51,592 +51,625 @@
#include "catalog/pg_user.h"
#include "storage/large_object.h"
#include "catalog/pg_listener.h"
-
-extern bool AMI_OVERRIDE; /* XXX style */
-
+
+extern bool AMI_OVERRIDE; /* XXX style */
+
#include "utils/syscache.h"
#include "catalog/indexing.h"
-
-typedef HeapTuple (*ScanFunc)();
+
+typedef HeapTuple(*ScanFunc) ();
/* ----------------
- * Warning: cacheinfo[] below is changed, then be sure and
- * update the magic constants in syscache.h!
+ * Warning: cacheinfo[] below is changed, then be sure and
+ * update the magic constants in syscache.h!
* ----------------
*/
static struct cachedesc cacheinfo[] = {
- { AccessMethodOperatorRelationName, /* AMOPOPID */
- 3,
- { Anum_pg_amop_amopclaid,
- Anum_pg_amop_amopopr,
- Anum_pg_amop_amopid,
- 0 },
- sizeof(FormData_pg_amop),
- NULL,
- (ScanFunc) NULL },
- { AccessMethodOperatorRelationName, /* AMOPSTRATEGY */
- 3,
- { Anum_pg_amop_amopid,
- Anum_pg_amop_amopclaid,
- Anum_pg_amop_amopstrategy,
- 0 },
- sizeof(FormData_pg_amop),
- NULL,
- (ScanFunc) NULL },
- { AttributeRelationName, /* ATTNAME */
- 2,
- { Anum_pg_attribute_attrelid,
- Anum_pg_attribute_attname,
- 0,
- 0 },
- ATTRIBUTE_TUPLE_SIZE,
- AttributeNameIndex,
- (ScanFunc) AttributeNameIndexScan },
- { AttributeRelationName, /* ATTNUM */
- 2,
- { Anum_pg_attribute_attrelid,
- Anum_pg_attribute_attnum,
- 0,
- 0 },
- ATTRIBUTE_TUPLE_SIZE,
- AttributeNumIndex,
- (ScanFunc) AttributeNumIndexScan },
- { IndexRelationName, /* INDEXRELID */
- 1,
- { Anum_pg_index_indexrelid,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_index, indpred),
- NULL,
- NULL },
- { LanguageRelationName, /* LANNAME */
- 1,
- { Anum_pg_language_lanname,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_language, lancompiler),
- NULL,
- NULL },
- { OperatorRelationName, /* OPRNAME */
- 4,
- { Anum_pg_operator_oprname,
- Anum_pg_operator_oprleft,
- Anum_pg_operator_oprright,
- Anum_pg_operator_oprkind },
- sizeof(FormData_pg_operator),
- NULL,
- NULL },
- { OperatorRelationName, /* OPROID */
- 1,
- { ObjectIdAttributeNumber,
- 0,
- 0,
- 0 },
- sizeof(FormData_pg_operator),
- NULL,
- (ScanFunc) NULL },
- { ProcedureRelationName, /* PRONAME */
- 3,
- { Anum_pg_proc_proname,
- Anum_pg_proc_pronargs,
- Anum_pg_proc_proargtypes,
- 0 },
- offsetof(FormData_pg_proc, prosrc),
- ProcedureNameIndex,
- (ScanFunc) ProcedureNameIndexScan },
- { ProcedureRelationName, /* PROOID */
- 1,
- { ObjectIdAttributeNumber,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_proc, prosrc),
- ProcedureOidIndex,
- (ScanFunc) ProcedureOidIndexScan },
- { RelationRelationName, /* RELNAME */
- 1,
- { Anum_pg_class_relname,
- 0,
- 0,
- 0 },
- CLASS_TUPLE_SIZE,
- ClassNameIndex,
- (ScanFunc) ClassNameIndexScan },
- { RelationRelationName, /* RELOID */
- 1,
- { ObjectIdAttributeNumber,
- 0,
- 0,
- 0 },
- CLASS_TUPLE_SIZE,
- ClassOidIndex,
- (ScanFunc) ClassOidIndexScan },
- { TypeRelationName, /* TYPNAME */
- 1,
- { Anum_pg_type_typname,
- 0,
- 0,
- 0 },
- offsetof(TypeTupleFormData,typalign)+sizeof(char),
- TypeNameIndex,
- TypeNameIndexScan },
- { TypeRelationName, /* TYPOID */
- 1,
- { ObjectIdAttributeNumber,
- 0,
- 0,
+ {AccessMethodOperatorRelationName, /* AMOPOPID */
+ 3,
+ {Anum_pg_amop_amopclaid,
+ Anum_pg_amop_amopopr,
+ Anum_pg_amop_amopid,
+ 0},
+ sizeof(FormData_pg_amop),
+ NULL,
+ (ScanFunc) NULL},
+ {AccessMethodOperatorRelationName, /* AMOPSTRATEGY */
+ 3,
+ {Anum_pg_amop_amopid,
+ Anum_pg_amop_amopclaid,
+ Anum_pg_amop_amopstrategy,
+ 0},
+ sizeof(FormData_pg_amop),
+ NULL,
+ (ScanFunc) NULL},
+ {AttributeRelationName, /* ATTNAME */
+ 2,
+ {Anum_pg_attribute_attrelid,
+ Anum_pg_attribute_attname,
+ 0,
+ 0},
+ ATTRIBUTE_TUPLE_SIZE,
+ AttributeNameIndex,
+ (ScanFunc) AttributeNameIndexScan},
+ {AttributeRelationName, /* ATTNUM */
+ 2,
+ {Anum_pg_attribute_attrelid,
+ Anum_pg_attribute_attnum,
+ 0,
+ 0},
+ ATTRIBUTE_TUPLE_SIZE,
+ AttributeNumIndex,
+ (ScanFunc) AttributeNumIndexScan},
+ {IndexRelationName, /* INDEXRELID */
+ 1,
+ {Anum_pg_index_indexrelid,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_index, indpred),
+ NULL,
+ NULL},
+ {LanguageRelationName, /* LANNAME */
+ 1,
+ {Anum_pg_language_lanname,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_language, lancompiler),
+ NULL,
+ NULL},
+ {OperatorRelationName, /* OPRNAME */
+ 4,
+ {Anum_pg_operator_oprname,
+ Anum_pg_operator_oprleft,
+ Anum_pg_operator_oprright,
+ Anum_pg_operator_oprkind},
+ sizeof(FormData_pg_operator),
+ NULL,
+ NULL},
+ {OperatorRelationName, /* OPROID */
+ 1,
+ {ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0},
+ sizeof(FormData_pg_operator),
+ NULL,
+ (ScanFunc) NULL},
+ {ProcedureRelationName, /* PRONAME */
+ 3,
+ {Anum_pg_proc_proname,
+ Anum_pg_proc_pronargs,
+ Anum_pg_proc_proargtypes,
+ 0},
+ offsetof(FormData_pg_proc, prosrc),
+ ProcedureNameIndex,
+ (ScanFunc) ProcedureNameIndexScan},
+ {ProcedureRelationName, /* PROOID */
+ 1,
+ {ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_proc, prosrc),
+ ProcedureOidIndex,
+ (ScanFunc) ProcedureOidIndexScan},
+ {RelationRelationName, /* RELNAME */
+ 1,
+ {Anum_pg_class_relname,
+ 0,
+ 0,
+ 0},
+ CLASS_TUPLE_SIZE,
+ ClassNameIndex,
+ (ScanFunc) ClassNameIndexScan},
+ {RelationRelationName, /* RELOID */
+ 1,
+ {ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0},
+ CLASS_TUPLE_SIZE,
+ ClassOidIndex,
+ (ScanFunc) ClassOidIndexScan},
+ {TypeRelationName, /* TYPNAME */
+ 1,
+ {Anum_pg_type_typname,
+ 0,
+ 0,
+ 0},
+ offsetof(TypeTupleFormData, typalign) + sizeof(char),
+ TypeNameIndex,
+ TypeNameIndexScan},
+ {TypeRelationName, /* TYPOID */
+ 1,
+ {ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0},
+ offsetof(TypeTupleFormData, typalign) +sizeof(char),
+ TypeOidIndex,
+ TypeOidIndexScan},
+ {AccessMethodRelationName, /* AMNAME */
+ 1,
+ {Anum_pg_am_amname,
+ 0,
+ 0,
+ 0},
+ sizeof(FormData_pg_am),
+ NULL,
+ NULL},
+ {OperatorClassRelationName, /* CLANAME */
+ 1,
+ {Anum_pg_opclass_opcname,
+ 0,
+ 0,
+ 0},
+ sizeof(FormData_pg_opclass),
+ NULL,
+ NULL},
+ {IndexRelationName, /* INDRELIDKEY */
+ 2,
+ {Anum_pg_index_indrelid,
+ Anum_pg_index_indkey,
+ 0,
+ 0},
+ offsetof(FormData_pg_index, indpred),
+ NULL,
+ (ScanFunc) NULL},
+ {InheritsRelationName, /* INHRELID */
+ 2,
+ {Anum_pg_inherits_inhrel,
+ Anum_pg_inherits_inhseqno,
+ 0,
0},
- offsetof(TypeTupleFormData,typalign)+sizeof(char),
- TypeOidIndex,
- TypeOidIndexScan },
- { AccessMethodRelationName, /* AMNAME */
- 1,
- { Anum_pg_am_amname,
- 0,
- 0,
+ sizeof(FormData_pg_inherits),
+ NULL,
+ (ScanFunc) NULL},
+ {RewriteRelationName, /* RULOID */
+ 1,
+ {ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_rewrite, ev_qual),
+ NULL,
+ (ScanFunc) NULL},
+ {AggregateRelationName, /* AGGNAME */
+ 2,
+ {Anum_pg_aggregate_aggname,
+ Anum_pg_aggregate_aggbasetype,
+ 0,
0},
- sizeof(FormData_pg_am),
- NULL,
- NULL },
- { OperatorClassRelationName, /* CLANAME */
- 1,
- { Anum_pg_opclass_opcname,
- 0,
- 0,
+ offsetof(FormData_pg_aggregate, agginitval1),
+ NULL,
+ (ScanFunc) NULL},
+ {ListenerRelationName, /* LISTENREL */
+ 2,
+ {Anum_pg_listener_relname,
+ Anum_pg_listener_pid,
+ 0,
0},
- sizeof(FormData_pg_opclass),
- NULL,
- NULL },
- { IndexRelationName, /* INDRELIDKEY */
- 2,
- { Anum_pg_index_indrelid,
- Anum_pg_index_indkey,
- 0,
+ sizeof(FormData_pg_listener),
+ NULL,
+ (ScanFunc) NULL},
+ {UserRelationName, /* USENAME */
+ 1,
+ {Anum_pg_user_usename,
+ 0,
+ 0,
0},
- offsetof(FormData_pg_index, indpred),
- NULL,
- (ScanFunc) NULL },
- { InheritsRelationName, /* INHRELID */
- 2,
- { Anum_pg_inherits_inhrel,
- Anum_pg_inherits_inhseqno,
- 0,
+ sizeof(FormData_pg_user),
+ NULL,
+ (ScanFunc) NULL},
+ {UserRelationName, /* USESYSID */
+ 1,
+ {Anum_pg_user_usesysid,
+ 0,
+ 0,
+ 0},
+ sizeof(FormData_pg_user),
+ NULL,
+ (ScanFunc) NULL},
+ {GroupRelationName, /* GRONAME */
+ 1,
+ {Anum_pg_group_groname,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_group, grolist[0]),
+ NULL,
+ (ScanFunc) NULL},
+ {GroupRelationName, /* GROSYSID */
+ 1,
+ {Anum_pg_group_grosysid,
+ 0,
+ 0,
0},
- sizeof(FormData_pg_inherits),
- NULL,
- (ScanFunc) NULL },
- { RewriteRelationName, /* RULOID */
- 1,
- { ObjectIdAttributeNumber,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_rewrite, ev_qual),
- NULL,
- (ScanFunc) NULL },
- { AggregateRelationName, /*AGGNAME*/
- 2,
- { Anum_pg_aggregate_aggname,
- Anum_pg_aggregate_aggbasetype,
- 0,
- 0 },
- offsetof(FormData_pg_aggregate, agginitval1),
- NULL,
- (ScanFunc) NULL },
- { ListenerRelationName, /* LISTENREL */
- 2,
- { Anum_pg_listener_relname,
- Anum_pg_listener_pid,
- 0,
- 0 },
- sizeof(FormData_pg_listener),
- NULL,
- (ScanFunc) NULL },
- { UserRelationName, /* USENAME */
- 1,
- { Anum_pg_user_usename,
- 0,
- 0,
- 0 },
- sizeof(FormData_pg_user),
- NULL,
- (ScanFunc) NULL },
- { UserRelationName, /* USESYSID */
- 1,
- { Anum_pg_user_usesysid,
- 0,
- 0,
- 0 },
- sizeof(FormData_pg_user),
- NULL,
- (ScanFunc) NULL },
- { GroupRelationName, /* GRONAME */
- 1,
- { Anum_pg_group_groname,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_group, grolist[0]),
- NULL,
- (ScanFunc) NULL },
- { GroupRelationName, /* GROSYSID */
- 1,
- { Anum_pg_group_grosysid,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_group, grolist[0]),
- NULL,
- (ScanFunc) NULL },
- { RewriteRelationName, /* REWRITENAME */
- 1,
- { Anum_pg_rewrite_rulename,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_rewrite, ev_qual),
- NULL,
- (ScanFunc) NULL },
- { ProcedureRelationName, /* PROSRC */
- 1,
- { Anum_pg_proc_prosrc,
- 0,
- 0,
- 0 },
- offsetof(FormData_pg_proc, prosrc),
- ProcedureSrcIndex,
- (ScanFunc) ProcedureSrcIndexScan },
- { OperatorClassRelationName, /* CLADEFTYPE */
- 1,
- { Anum_pg_opclass_opcdeftype,
- 0,
- 0,
- 0 },
- sizeof(FormData_pg_opclass),
- NULL,
- (ScanFunc) NULL }
+ offsetof(FormData_pg_group, grolist[0]),
+ NULL,
+ (ScanFunc) NULL},
+ {RewriteRelationName, /* REWRITENAME */
+ 1,
+ {Anum_pg_rewrite_rulename,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_rewrite, ev_qual),
+ NULL,
+ (ScanFunc) NULL},
+ {ProcedureRelationName, /* PROSRC */
+ 1,
+ {Anum_pg_proc_prosrc,
+ 0,
+ 0,
+ 0},
+ offsetof(FormData_pg_proc, prosrc),
+ ProcedureSrcIndex,
+ (ScanFunc) ProcedureSrcIndexScan},
+ {OperatorClassRelationName, /* CLADEFTYPE */
+ 1,
+ {Anum_pg_opclass_opcdeftype,
+ 0,
+ 0,
+ 0},
+ sizeof(FormData_pg_opclass),
+ NULL,
+ (ScanFunc) NULL}
};
-
-static struct catcache *SysCache[lengthof(cacheinfo)];
-static int32 SysCacheSize = lengthof(cacheinfo);
-
-
+
+static struct catcache *SysCache[
+ lengthof(cacheinfo)];
+static int32 SysCacheSize = lengthof(cacheinfo);
+
+
/*
* zerocaches--
*
- * Make sure the SysCache structure is zero'd.
+ * Make sure the SysCache structure is zero'd.
*/
void
zerocaches()
{
- memset((char *) SysCache, 0, SysCacheSize * sizeof(struct catcache *));
+ memset((char *) SysCache, 0, SysCacheSize * sizeof(struct catcache *));
}
/*
* Note:
- * This function was written because the initialized catalog caches
- * are used to determine which caches may contain tuples which need
- * to be invalidated in other backends.
+ * This function was written because the initialized catalog caches
+ * are used to determine which caches may contain tuples which need
+ * to be invalidated in other backends.
*/
void
InitCatalogCache()
{
- int cacheId; /* XXX type */
-
- if (!AMI_OVERRIDE) {
- for (cacheId = 0; cacheId < SysCacheSize; cacheId += 1) {
-
- Assert(!PointerIsValid((Pointer)SysCache[cacheId]));
-
- SysCache[cacheId] =
- InitSysCache(cacheinfo[cacheId].name,
- cacheinfo[cacheId].indname,
- cacheId,
- cacheinfo[cacheId].nkeys,
- cacheinfo[cacheId].key,
- cacheinfo[cacheId].iScanFunc);
- if (!PointerIsValid((char *)SysCache[cacheId])) {
- elog(WARN,
- "InitCatalogCache: Can't init cache %.16s(%d)",
- cacheinfo[cacheId].name,
- cacheId);
- }
-
+ int cacheId; /* XXX type */
+
+ if (!AMI_OVERRIDE)
+ {
+ for (cacheId = 0; cacheId < SysCacheSize; cacheId += 1)
+ {
+
+ Assert(!PointerIsValid((Pointer) SysCache[cacheId]));
+
+ SysCache[cacheId] =
+ InitSysCache(cacheinfo[cacheId].name,
+ cacheinfo[cacheId].indname,
+ cacheId,
+ cacheinfo[cacheId].nkeys,
+ cacheinfo[cacheId].key,
+ cacheinfo[cacheId].iScanFunc);
+ if (!PointerIsValid((char *) SysCache[cacheId]))
+ {
+ elog(WARN,
+ "InitCatalogCache: Can't init cache %.16s(%d)",
+ cacheinfo[cacheId].name,
+ cacheId);
+ }
+
+ }
}
- }
}
/*
* SearchSysCacheTuple--
*
- * A layer on top of SearchSysCache that does the initialization and
- * key-setting for you.
+ * A layer on top of SearchSysCache that does the initialization and
+ * key-setting for you.
*
* Returns the tuple if one is found, NULL if not.
*
* XXX The tuple that is returned is NOT supposed to be pfree'd!
*/
HeapTuple
-SearchSysCacheTuple(int cacheId, /* cache selection code */
- Datum key1,
- Datum key2,
- Datum key3,
- Datum key4)
+SearchSysCacheTuple(int cacheId, /* cache selection code */
+ Datum key1,
+ Datum key2,
+ Datum key3,
+ Datum key4)
{
- register HeapTuple tp;
-
- if (cacheId < 0 || cacheId >= SysCacheSize) {
- elog(WARN, "SearchSysCacheTuple: Bad cache id %d", cacheId);
- return((HeapTuple) NULL);
- }
-
- if (!AMI_OVERRIDE) {
- Assert(PointerIsValid(SysCache[cacheId]));
- } else {
- if (!PointerIsValid(SysCache[cacheId])) {
- SysCache[cacheId] =
- InitSysCache(cacheinfo[cacheId].name,
- cacheinfo[cacheId].indname,
- cacheId,
- cacheinfo[cacheId].nkeys,
- cacheinfo[cacheId].key,
- cacheinfo[cacheId].iScanFunc);
- if (!PointerIsValid(SysCache[cacheId])) {
- elog(WARN,
- "InitCatalogCache: Can't init cache %.16s(%d)",
- cacheinfo[cacheId].name,
- cacheId);
- }
-
+ register HeapTuple tp;
+
+ if (cacheId < 0 || cacheId >= SysCacheSize)
+ {
+ elog(WARN, "SearchSysCacheTuple: Bad cache id %d", cacheId);
+ return ((HeapTuple) NULL);
+ }
+
+ if (!AMI_OVERRIDE)
+ {
+ Assert(PointerIsValid(SysCache[cacheId]));
+ }
+ else
+ {
+ if (!PointerIsValid(SysCache[cacheId]))
+ {
+ SysCache[cacheId] =
+ InitSysCache(cacheinfo[cacheId].name,
+ cacheinfo[cacheId].indname,
+ cacheId,
+ cacheinfo[cacheId].nkeys,
+ cacheinfo[cacheId].key,
+ cacheinfo[cacheId].iScanFunc);
+ if (!PointerIsValid(SysCache[cacheId]))
+ {
+ elog(WARN,
+ "InitCatalogCache: Can't init cache %.16s(%d)",
+ cacheinfo[cacheId].name,
+ cacheId);
+ }
+
+ }
}
- }
-
- tp = SearchSysCache(SysCache[cacheId], key1, key2, key3, key4);
- if (!HeapTupleIsValid(tp)) {
+
+ tp = SearchSysCache(SysCache[cacheId], key1, key2, key3, key4);
+ if (!HeapTupleIsValid(tp))
+ {
#ifdef CACHEDEBUG
- elog(DEBUG,
- "SearchSysCacheTuple: Search %s(%d) %d %d %d %d failed",
- (*cacheinfo[cacheId].name)->data,
- cacheId, key1, key2, key3, key4);
+ elog(DEBUG,
+ "SearchSysCacheTuple: Search %s(%d) %d %d %d %d failed",
+ (*cacheinfo[cacheId].name)->data,
+ cacheId, key1, key2, key3, key4);
#endif
- return((HeapTuple) NULL);
- }
- return(tp);
+ return ((HeapTuple) NULL);
+ }
+ return (tp);
}
/*
* SearchSysCacheStruct--
- * Fills 's' with the information retrieved by calling SearchSysCache()
- * with arguments key1...key4. Retrieves only the portion of the tuple
- * which is not variable-length.
+ * Fills 's' with the information retrieved by calling SearchSysCache()
+ * with arguments key1...key4. Retrieves only the portion of the tuple
+ * which is not variable-length.
*
* NOTE: we are assuming that non-variable-length fields in the system
- * catalogs will always be defined!
+ * catalogs will always be defined!
*
* Returns 1L if a tuple was found, 0L if not.
*/
int32
SearchSysCacheStruct(int cacheId, /* cache selection code */
- char *returnStruct, /* (preallocated!) */
- Datum key1,
- Datum key2,
- Datum key3,
- Datum key4)
+ char *returnStruct, /* (preallocated!) */
+ Datum key1,
+ Datum key2,
+ Datum key3,
+ Datum key4)
{
- HeapTuple tp;
-
- if (!PointerIsValid(returnStruct)) {
- elog(WARN, "SearchSysCacheStruct: No receiving struct");
- return(0);
- }
- tp = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
- if (!HeapTupleIsValid(tp))
- return(0);
- memmove(returnStruct, (char *) GETSTRUCT(tp), cacheinfo[cacheId].size);
- return(1);
+ HeapTuple tp;
+
+ if (!PointerIsValid(returnStruct))
+ {
+ elog(WARN, "SearchSysCacheStruct: No receiving struct");
+ return (0);
+ }
+ tp = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
+ if (!HeapTupleIsValid(tp))
+ return (0);
+ memmove(returnStruct, (char *) GETSTRUCT(tp), cacheinfo[cacheId].size);
+ return (1);
}
/*
* SearchSysCacheGetAttribute--
- * Returns the attribute corresponding to 'attributeNumber' for
- * a given cached tuple.
+ * Returns the attribute corresponding to 'attributeNumber' for
+ * a given cached tuple.
*
* XXX This re-opens a relation, so this is slower.
*
* [callers all assume this returns a (struct varlena *). -ay 10/94]
*/
-void *
+void *
SearchSysCacheGetAttribute(int cacheId,
- AttrNumber attributeNumber,
- Datum key1,
- Datum key2,
- Datum key3,
- Datum key4)
+ AttrNumber attributeNumber,
+ Datum key1,
+ Datum key2,
+ Datum key3,
+ Datum key4)
{
- HeapTuple tp;
- char *cacheName;
- Relation relation;
- int32 attributeLength, attributeByValue;
- bool isNull;
- char *attributeValue;
- void *returnValue;
-
- tp = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
- cacheName = cacheinfo[cacheId].name;
-
- if (!HeapTupleIsValid(tp)) {
+ HeapTuple tp;
+ char *cacheName;
+ Relation relation;
+ int32 attributeLength,
+ attributeByValue;
+ bool isNull;
+ char *attributeValue;
+ void *returnValue;
+
+ tp = SearchSysCacheTuple(cacheId, key1, key2, key3, key4);
+ cacheName = cacheinfo[cacheId].name;
+
+ if (!HeapTupleIsValid(tp))
+ {
#ifdef CACHEDEBUG
- elog(DEBUG,
- "SearchSysCacheGetAttribute: Lookup in %s(%d) failed",
- cacheName, cacheId);
-#endif /* defined(CACHEDEBUG) */
- return(NULL);
- }
-
- relation = heap_openr(cacheName);
-
- if (attributeNumber < 0 &&
- attributeNumber > FirstLowInvalidHeapAttributeNumber) {
- attributeLength = heap_sysattrlen(attributeNumber);
- attributeByValue = heap_sysattrbyval(attributeNumber);
- } else if (attributeNumber > 0 &&
- attributeNumber <= relation->rd_rel->relnatts) {
- attributeLength =
- relation->rd_att->attrs[attributeNumber-1]->attlen;
- attributeByValue =
- relation->rd_att->attrs[attributeNumber-1]->attbyval;
- } else {
- elog(WARN,
- "SearchSysCacheGetAttribute: Bad attr # %d in %s(%d)",
- attributeNumber, cacheName, cacheId);
- return(NULL);
- }
-
- attributeValue = heap_getattr(tp,
- (Buffer) 0,
- attributeNumber,
- RelationGetTupleDescriptor(relation),
- &isNull);
-
- if (isNull) {
- /*
- * Used to be an elog(DEBUG, ...) here and a claim that it should
- * be a FATAL error, I don't think either is warranted -mer 6/9/92
- */
- return(NULL);
- }
-
- if (attributeByValue) {
- returnValue = (void *)attributeValue;
- } else {
- char *tmp;
- int size = (attributeLength < 0)
- ? VARSIZE((struct varlena *) attributeValue) /* variable length */
- : attributeLength; /* fixed length */
-
- tmp = (char *) palloc(size);
- memmove(tmp, attributeValue, size);
- returnValue = (void *)tmp;
- }
-
- heap_close(relation);
- return(returnValue);
+ elog(DEBUG,
+ "SearchSysCacheGetAttribute: Lookup in %s(%d) failed",
+ cacheName, cacheId);
+#endif /* defined(CACHEDEBUG) */
+ return (NULL);
+ }
+
+ relation = heap_openr(cacheName);
+
+ if (attributeNumber < 0 &&
+ attributeNumber > FirstLowInvalidHeapAttributeNumber)
+ {
+ attributeLength = heap_sysattrlen(attributeNumber);
+ attributeByValue = heap_sysattrbyval(attributeNumber);
+ }
+ else if (attributeNumber > 0 &&
+ attributeNumber <= relation->rd_rel->relnatts)
+ {
+ attributeLength =
+ relation->rd_att->attrs[attributeNumber - 1]->attlen;
+ attributeByValue =
+ relation->rd_att->attrs[attributeNumber - 1]->attbyval;
+ }
+ else
+ {
+ elog(WARN,
+ "SearchSysCacheGetAttribute: Bad attr # %d in %s(%d)",
+ attributeNumber, cacheName, cacheId);
+ return (NULL);
+ }
+
+ attributeValue = heap_getattr(tp,
+ (Buffer) 0,
+ attributeNumber,
+ RelationGetTupleDescriptor(relation),
+ &isNull);
+
+ if (isNull)
+ {
+
+ /*
+ * Used to be an elog(DEBUG, ...) here and a claim that it should
+ * be a FATAL error, I don't think either is warranted -mer 6/9/92
+ */
+ return (NULL);
+ }
+
+ if (attributeByValue)
+ {
+ returnValue = (void *) attributeValue;
+ }
+ else
+ {
+ char *tmp;
+ int size = (attributeLength < 0)
+ ? VARSIZE((struct varlena *) attributeValue) /* variable length */
+ : attributeLength; /* fixed length */
+
+ tmp = (char *) palloc(size);
+ memmove(tmp, attributeValue, size);
+ returnValue = (void *) tmp;
+ }
+
+ heap_close(relation);
+ return (returnValue);
}
/*
* TypeDefaultRetrieve--
*
- * Given a type OID, return the typdefault field associated with that
- * type. The typdefault is returned as the car of a dotted pair which
- * is passed to TypeDefaultRetrieve by the calling routine.
+ * Given a type OID, return the typdefault field associated with that
+ * type. The typdefault is returned as the car of a dotted pair which
+ * is passed to TypeDefaultRetrieve by the calling routine.
*
* Returns a fixnum for types which are passed by value and a ppreserve'd
* vectori for types which are not.
*
* [identical to get_typdefault, expecting a (struct varlena *) as ret val.
- * some day, either of the functions should be removed -ay 10/94]
+ * some day, either of the functions should be removed -ay 10/94]
*/
-void *
+void *
TypeDefaultRetrieve(Oid typId)
{
- HeapTuple typeTuple;
- TypeTupleForm type;
- int32 typByVal, typLen;
- struct varlena *typDefault;
- int32 dataSize;
- void *returnValue;
-
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(typId),
- 0,0,0);
-
- if (!HeapTupleIsValid(typeTuple)) {
-#ifdef CACHEDEBUG
- elog(DEBUG, "TypeDefaultRetrieve: Lookup in %s(%d) failed",
- (*cacheinfo[TYPOID].name)->data, TYPOID);
-#endif /* defined(CACHEDEBUG) */
- return(NULL);
- }
-
- type = (TypeTupleForm) GETSTRUCT(typeTuple);
- typByVal = type->typbyval;
- typLen = type->typlen;
-
- typDefault = (struct varlena *)
- SearchSysCacheGetAttribute(TYPOID,
- Anum_pg_type_typdefault,
- ObjectIdGetDatum(typId),
- 0,0,0);
-
- if (typDefault == (struct varlena *)NULL) {
+ HeapTuple typeTuple;
+ TypeTupleForm type;
+ int32 typByVal,
+ typLen;
+ struct varlena *typDefault;
+ int32 dataSize;
+ void *returnValue;
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(typId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(typeTuple))
+ {
#ifdef CACHEDEBUG
- elog(DEBUG, "TypeDefaultRetrieve: No extractable typdefault",
- (*cacheinfo[TYPOID].name)->data, TYPOID);
-#endif /* defined(CACHEDEBUG) */
- return (NULL);
-
- }
-
- dataSize = VARSIZE(typDefault) - VARHDRSZ;
-
- if (typByVal) {
- int8 i8;
- int16 i16;
- int32 i32;
-
- if (dataSize == typLen) {
- switch (typLen) {
- case sizeof(int8):
- memmove((char *) &i8, VARDATA(typDefault), sizeof(int8));
- i32 = i8;
- break;
- case sizeof(int16):
- memmove((char *) &i16, VARDATA(typDefault), sizeof(int16));
- i32 = i16;
- break;
- case sizeof(int32):
- memmove((char *) &i32, VARDATA(typDefault), sizeof(int32));
- break;
- }
- returnValue = (void *)i32;
- } else {
- returnValue = NULL;
+ elog(DEBUG, "TypeDefaultRetrieve: Lookup in %s(%d) failed",
+ (*cacheinfo[TYPOID].name)->data, TYPOID);
+#endif /* defined(CACHEDEBUG) */
+ return (NULL);
}
- } else {
- if ((typLen < 0 && dataSize < 0) || dataSize != typLen)
- returnValue = NULL;
- else {
- returnValue = (void *)palloc(VARSIZE(typDefault));
- memmove((char *) returnValue,
- (char *) typDefault,
- (int) VARSIZE(typDefault));
+
+ type = (TypeTupleForm) GETSTRUCT(typeTuple);
+ typByVal = type->typbyval;
+ typLen = type->typlen;
+
+ typDefault = (struct varlena *)
+ SearchSysCacheGetAttribute(TYPOID,
+ Anum_pg_type_typdefault,
+ ObjectIdGetDatum(typId),
+ 0, 0, 0);
+
+ if (typDefault == (struct varlena *) NULL)
+ {
+#ifdef CACHEDEBUG
+ elog(DEBUG, "TypeDefaultRetrieve: No extractable typdefault",
+ (*cacheinfo[TYPOID].name)->data, TYPOID);
+#endif /* defined(CACHEDEBUG) */
+ return (NULL);
+
}
- }
-
- return(returnValue);
-}
+ dataSize = VARSIZE(typDefault) - VARHDRSZ;
+ if (typByVal)
+ {
+ int8 i8;
+ int16 i16;
+ int32 i32;
+
+ if (dataSize == typLen)
+ {
+ switch (typLen)
+ {
+ case sizeof(int8):
+ memmove((char *) &i8, VARDATA(typDefault), sizeof(int8));
+ i32 = i8;
+ break;
+ case sizeof(int16):
+ memmove((char *) &i16, VARDATA(typDefault), sizeof(int16));
+ i32 = i16;
+ break;
+ case sizeof(int32):
+ memmove((char *) &i32, VARDATA(typDefault), sizeof(int32));
+ break;
+ }
+ returnValue = (void *) i32;
+ }
+ else
+ {
+ returnValue = NULL;
+ }
+ }
+ else
+ {
+ if ((typLen < 0 && dataSize < 0) || dataSize != typLen)
+ returnValue = NULL;
+ else
+ {
+ returnValue = (void *) palloc(VARSIZE(typDefault));
+ memmove((char *) returnValue,
+ (char *) typDefault,
+ (int) VARSIZE(typDefault));
+ }
+ }
+
+ return (returnValue);
+}
diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c
index 4fb99ced1b9..2c46dde02b8 100644
--- a/src/backend/utils/error/assert.c
+++ b/src/backend/utils/error/assert.c
@@ -1,67 +1,71 @@
/*-------------------------------------------------------------------------
*
* assert.c--
- * Assert code.
+ * Assert code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/error/assert.c,v 1.4 1997/04/17 20:38:26 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/assert.c,v 1.5 1997/09/07 04:53:11 momjian Exp $
*
* NOTE
- * This should eventually work with elog(), dlog(), etc.
+ * This should eventually work with elog(), dlog(), etc.
*
*-------------------------------------------------------------------------
*/
#include <stdio.h>
-#include "postgres.h" /* where the declaration goes */
+#include "postgres.h" /* where the declaration goes */
#include "utils/module.h"
#include "utils/exc.h"
int
-ExceptionalCondition(char* conditionName,
- Exception *exceptionP,
- char* detail,
- char* fileName,
- int lineNumber)
+ExceptionalCondition(char *conditionName,
+ Exception * exceptionP,
+ char *detail,
+ char *fileName,
+ int lineNumber)
{
- extern char* ExcFileName; /* XXX */
- extern Index ExcLineNumber; /* XXX */
-
- ExcFileName = fileName;
- ExcLineNumber = lineNumber;
-
- if (!PointerIsValid(conditionName)
- || !PointerIsValid(fileName)
- || !PointerIsValid(exceptionP)) {
- fprintf(stderr, "ExceptionalCondition: bad arguments\n");
-
- ExcAbort(exceptionP,
- (ExcDetail)detail,
- (ExcData)NULL,
- (ExcMessage)NULL);
- } else {
- fprintf(stderr,
- "%s(\"%s:%s\", File: \"%s\", Line: %d)\n",
+ extern char *ExcFileName;/* XXX */
+ extern Index ExcLineNumber; /* XXX */
+
+ ExcFileName = fileName;
+ ExcLineNumber = lineNumber;
+
+ if (!PointerIsValid(conditionName)
+ || !PointerIsValid(fileName)
+ || !PointerIsValid(exceptionP))
+ {
+ fprintf(stderr, "ExceptionalCondition: bad arguments\n");
+
+ ExcAbort(exceptionP,
+ (ExcDetail) detail,
+ (ExcData) NULL,
+ (ExcMessage) NULL);
+ }
+ else
+ {
+ fprintf(stderr,
+ "%s(\"%s:%s\", File: \"%s\", Line: %d)\n",
exceptionP->message, conditionName, detail == NULL ? "" : detail,
- fileName, lineNumber);
- }
+ fileName, lineNumber);
+ }
#ifdef ABORT_ON_ASSERT
- abort();
+ abort();
#endif
- /*
- * XXX Depending on the Exception and tracing conditions, you will
- * XXX want to stop here immediately and maybe dump core.
- * XXX This may be especially true for Assert(), etc.
- */
-
- /* TraceDump(); dump the trace stack */
-
- /* XXX FIXME: detail is lost */
- ExcRaise(exceptionP, (ExcDetail)0, (ExcData)NULL, conditionName);
- return(0);
+
+ /*
+ * XXX Depending on the Exception and tracing conditions, you will XXX
+ * want to stop here immediately and maybe dump core. XXX This may be
+ * especially true for Assert(), etc.
+ */
+
+ /* TraceDump(); dump the trace stack */
+
+ /* XXX FIXME: detail is lost */
+ ExcRaise(exceptionP, (ExcDetail) 0, (ExcData) NULL, conditionName);
+ return (0);
}
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index fae4c1adeef..e4cdc6d595b 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* elog.c--
- * error logger
+ * error logger
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.17 1997/08/12 22:54:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.18 1997/09/07 04:53:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,7 @@
#include <fcntl.h>
#ifndef O_RDONLY
#include <sys/file.h>
-#endif /* O_RDONLY */
+#endif /* O_RDONLY */
#include <sys/types.h>
#include <stdarg.h>
#include <errno.h>
@@ -29,204 +29,236 @@
#include "libpq/libpq.h"
#include "storage/proc.h"
-static int Debugfile = -1;
-static int Err_file = -1;
-static int ElogDebugIndentLevel = 0;
+static int Debugfile = -1;
+static int Err_file = -1;
+static int ElogDebugIndentLevel = 0;
-extern char OutputFileName[];
+extern char OutputFileName[];
/*
* elog --
- * Old error logging function.
+ * Old error logging function.
*/
void
-elog(int lev, const char *fmt, ... )
+elog(int lev, const char *fmt,...)
{
- va_list ap;
- char buf[ELOG_MAXLEN], line[ELOG_MAXLEN];
- register char *bp;
- register const char *cp;
- extern int errno, sys_nerr;
+ va_list ap;
+ char buf[ELOG_MAXLEN],
+ line[ELOG_MAXLEN];
+ register char *bp;
+ register const char *cp;
+ extern int errno,
+ sys_nerr;
+
#ifndef PG_STANDALONE
- extern FILE *Pfout;
-#endif /* !PG_STANDALONE */
+ extern FILE *Pfout;
+
+#endif /* !PG_STANDALONE */
#ifdef ELOG_TIMESTAMPS
- time_t tim;
+ time_t tim;
+
#endif
- int len;
- int i = 0;
-
- va_start(ap, fmt);
- if (lev == DEBUG && Debugfile < 0) {
- return;
- }
- switch (lev) {
- case NOIND:
- i = ElogDebugIndentLevel-1;
- if (i < 0) i = 0;
- if (i > 30) i = i%30;
- cp = "DEBUG:";
- break;
- case DEBUG:
- i = ElogDebugIndentLevel;
- if (i < 0) i = 0;
- if (i > 30) i = i%30;
- cp = "DEBUG:";
- break;
- case NOTICE:
- cp = "NOTICE:";
- break;
- case WARN:
- cp = "WARN:";
- break;
- default:
- sprintf(line, "FATAL %d:", lev);
- cp = line;
- }
+ int len;
+ int i = 0;
+
+ va_start(ap, fmt);
+ if (lev == DEBUG && Debugfile < 0)
+ {
+ return;
+ }
+ switch (lev)
+ {
+ case NOIND:
+ i = ElogDebugIndentLevel - 1;
+ if (i < 0)
+ i = 0;
+ if (i > 30)
+ i = i % 30;
+ cp = "DEBUG:";
+ break;
+ case DEBUG:
+ i = ElogDebugIndentLevel;
+ if (i < 0)
+ i = 0;
+ if (i > 30)
+ i = i % 30;
+ cp = "DEBUG:";
+ break;
+ case NOTICE:
+ cp = "NOTICE:";
+ break;
+ case WARN:
+ cp = "WARN:";
+ break;
+ default:
+ sprintf(line, "FATAL %d:", lev);
+ cp = line;
+ }
#ifdef ELOG_TIMESTAMPS
- time(&tim);
- strcat(strcpy(buf, cp), ctime(&tim)+4);
- bp = buf+strlen(buf)-6;
- *bp++ = ':';
+ time(&tim);
+ strcat(strcpy(buf, cp), ctime(&tim) + 4);
+ bp = buf + strlen(buf) - 6;
+ *bp++ = ':';
#else
- strcpy(buf,cp);
- bp = buf+strlen(buf);
+ strcpy(buf, cp);
+ bp = buf + strlen(buf);
#endif
- while (i-- >0) *bp++ = ' ';
- for (cp = fmt; *cp; cp++)
- if (*cp == '%' && *(cp+1) == 'm') {
- if (errno < sys_nerr && errno >= 0)
- strcpy(bp, strerror(errno));
- else
- sprintf(bp, "error %d", errno);
- bp += strlen(bp);
- cp++;
- } else
- *bp++ = *cp;
- *bp = '\0';
- vsprintf(line, buf, ap);
- va_end(ap);
- len = strlen(strcat(line, "\n"));
- if (Debugfile > -1)
- write(Debugfile, line, len);
- if (lev == DEBUG || lev == NOIND)
- return;
-
- /*
- * If there's an error log file other than our channel to the
- * front-end program, write to it first. This is important
- * because there's a bug in the socket code on ultrix. If the
- * front end has gone away (so the channel to it has been closed
- * at the other end), then writing here can cause this backend
- * to exit without warning -- that is, write() does an exit().
- * In this case, our only hope of finding out what's going on
- * is if Err_file was set to some disk log. This is a major pain.
- */
-
- if (Err_file > -1 && Debugfile != Err_file) {
- if (write(Err_file, line, len) < 0) {
- write(open("/dev/console", O_WRONLY, 0666), line, len);
- fflush(stdout);
- fflush(stderr);
- exitpg(lev);
- }
- fsync(Err_file);
- }
-
-#ifndef PG_STANDALONE
- /* Send IPC message to the front-end program */
- if (Pfout != NULL && lev > DEBUG) {
- /* notices are not exactly errors, handle it differently */
- if (lev == NOTICE)
- pq_putnchar("N", 1);
- else
- pq_putnchar("E", 1);
- /* pq_putint(-101, 4);*/ /* should be query id */
- pq_putstr(line);
- pq_flush();
- }
-#endif /* !PG_STANDALONE */
-
- if (lev == WARN) {
- extern int InWarn;
- ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */
- if (!InWarn) {
- kill(getpid(), 1); /* abort to traffic cop */
- pause();
- }
- /*
- * The pause(3) is just to avoid race conditions where the
- * thread of control on an MP system gets past here (i.e.,
- * the signal is not received instantaneously).
- */
- }
-
- if (lev == FATAL) {
+ while (i-- > 0)
+ *bp++ = ' ';
+ for (cp = fmt; *cp; cp++)
+ if (*cp == '%' && *(cp + 1) == 'm')
+ {
+ if (errno < sys_nerr && errno >= 0)
+ strcpy(bp, strerror(errno));
+ else
+ sprintf(bp, "error %d", errno);
+ bp += strlen(bp);
+ cp++;
+ }
+ else
+ *bp++ = *cp;
+ *bp = '\0';
+ vsprintf(line, buf, ap);
+ va_end(ap);
+ len = strlen(strcat(line, "\n"));
+ if (Debugfile > -1)
+ write(Debugfile, line, len);
+ if (lev == DEBUG || lev == NOIND)
+ return;
+
/*
- * Assume that if we have detected the failure we can
- * exit with a normal exit status. This will prevent
- * the postmaster from cleaning up when it's not needed.
+ * If there's an error log file other than our channel to the
+ * front-end program, write to it first. This is important because
+ * there's a bug in the socket code on ultrix. If the front end has
+ * gone away (so the channel to it has been closed at the other end),
+ * then writing here can cause this backend to exit without warning --
+ * that is, write() does an exit(). In this case, our only hope of
+ * finding out what's going on is if Err_file was set to some disk
+ * log. This is a major pain.
*/
- fflush(stdout);
- fflush(stderr);
- ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */
- ProcReleaseLocks(); /* get rid of real locks we hold */
- exitpg(0);
- }
-
- if (lev > FATAL) {
- fflush(stdout);
- fflush(stderr);
- exitpg(lev);
- }
+
+ if (Err_file > -1 && Debugfile != Err_file)
+ {
+ if (write(Err_file, line, len) < 0)
+ {
+ write(open("/dev/console", O_WRONLY, 0666), line, len);
+ fflush(stdout);
+ fflush(stderr);
+ exitpg(lev);
+ }
+ fsync(Err_file);
+ }
+
+#ifndef PG_STANDALONE
+ /* Send IPC message to the front-end program */
+ if (Pfout != NULL && lev > DEBUG)
+ {
+ /* notices are not exactly errors, handle it differently */
+ if (lev == NOTICE)
+ pq_putnchar("N", 1);
+ else
+ pq_putnchar("E", 1);
+ /* pq_putint(-101, 4); *//* should be query id */
+ pq_putstr(line);
+ pq_flush();
+ }
+#endif /* !PG_STANDALONE */
+
+ if (lev == WARN)
+ {
+ extern int InWarn;
+
+ ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */
+ if (!InWarn)
+ {
+ kill(getpid(), 1); /* abort to traffic cop */
+ pause();
+ }
+
+ /*
+ * The pause(3) is just to avoid race conditions where the thread
+ * of control on an MP system gets past here (i.e., the signal is
+ * not received instantaneously).
+ */
+ }
+
+ if (lev == FATAL)
+ {
+
+ /*
+ * Assume that if we have detected the failure we can exit with a
+ * normal exit status. This will prevent the postmaster from
+ * cleaning up when it's not needed.
+ */
+ fflush(stdout);
+ fflush(stderr);
+ ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */
+ ProcReleaseLocks(); /* get rid of real locks we hold */
+ exitpg(0);
+ }
+
+ if (lev > FATAL)
+ {
+ fflush(stdout);
+ fflush(stderr);
+ exitpg(lev);
+ }
}
#ifndef PG_STANDALONE
int
DebugFileOpen(void)
{
- int fd, istty;
-
- Err_file = Debugfile = -1;
- ElogDebugIndentLevel = 0;
-
- if (OutputFileName[0]) {
- OutputFileName[MAXPGPATH-1] = '\0';
- if ((fd = open(OutputFileName, O_CREAT|O_APPEND|O_WRONLY,
- 0666)) < 0)
- elog(FATAL, "DebugFileOpen: open of %s: %m",
- OutputFileName);
- istty = isatty(fd);
- close(fd);
- /* If the file is a tty and we're running under the
- * postmaster, try to send stdout there as well (if it
- * isn't a tty then stderr will block out stdout, so we
- * may as well let stdout go wherever it was going before).
+ int fd,
+ istty;
+
+ Err_file = Debugfile = -1;
+ ElogDebugIndentLevel = 0;
+
+ if (OutputFileName[0])
+ {
+ OutputFileName[MAXPGPATH - 1] = '\0';
+ if ((fd = open(OutputFileName, O_CREAT | O_APPEND | O_WRONLY,
+ 0666)) < 0)
+ elog(FATAL, "DebugFileOpen: open of %s: %m",
+ OutputFileName);
+ istty = isatty(fd);
+ close(fd);
+
+ /*
+ * If the file is a tty and we're running under the postmaster,
+ * try to send stdout there as well (if it isn't a tty then stderr
+ * will block out stdout, so we may as well let stdout go wherever
+ * it was going before).
+ */
+ if (istty &&
+ IsUnderPostmaster &&
+ !freopen(OutputFileName, "a", stdout))
+ elog(FATAL, "DebugFileOpen: %s reopen as stdout: %m",
+ OutputFileName);
+ if (!freopen(OutputFileName, "a", stderr))
+ elog(FATAL, "DebugFileOpen: %s reopen as stderr: %m",
+ OutputFileName);
+ Err_file = Debugfile = fileno(stderr);
+ return (Debugfile);
+ }
+
+ /*
+ * If no filename was specified, send debugging output to stderr. If
+ * stderr has been hosed, try to open a file.
*/
- if (istty &&
- IsUnderPostmaster &&
- !freopen(OutputFileName, "a", stdout))
- elog(FATAL, "DebugFileOpen: %s reopen as stdout: %m",
- OutputFileName);
- if (!freopen(OutputFileName, "a", stderr))
- elog(FATAL, "DebugFileOpen: %s reopen as stderr: %m",
- OutputFileName);
- Err_file = Debugfile = fileno(stderr);
- return(Debugfile);
- }
- /* If no filename was specified, send debugging output to stderr.
- * If stderr has been hosed, try to open a file.
- */
- fd = fileno(stderr);
- if (fcntl(fd, F_GETFD, 0) < 0) {
- sprintf(OutputFileName, "%s/pg.errors.%d",
- DataDir, (int)getpid());
- fd = open(OutputFileName, O_CREAT|O_APPEND|O_WRONLY, 0666);
- }
- if (fd < 0)
- elog(FATAL, "DebugFileOpen: could not open debugging file");
-
- Err_file = Debugfile = fd;
- return(Debugfile);
+ fd = fileno(stderr);
+ if (fcntl(fd, F_GETFD, 0) < 0)
+ {
+ sprintf(OutputFileName, "%s/pg.errors.%d",
+ DataDir, (int) getpid());
+ fd = open(OutputFileName, O_CREAT | O_APPEND | O_WRONLY, 0666);
+ }
+ if (fd < 0)
+ elog(FATAL, "DebugFileOpen: could not open debugging file");
+
+ Err_file = Debugfile = fd;
+ return (Debugfile);
}
+
#endif
diff --git a/src/backend/utils/error/exc.c b/src/backend/utils/error/exc.c
index 3366996fad1..fd169b94a18 100644
--- a/src/backend/utils/error/exc.c
+++ b/src/backend/utils/error/exc.c
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* exc.c--
- * POSTGRES exception handling code.
+ * POSTGRES exception handling code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/exc.c,v 1.15 1997/08/19 21:35:17 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/exc.c,v 1.16 1997/09/07 04:53:16 momjian Exp $
*
* NOTE
- * XXX this code needs improvement--check for state violations and
- * XXX reset after handling an exception.
+ * XXX this code needs improvement--check for state violations and
+ * XXX reset after handling an exception.
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* XXX use own I/O routines */
+#include <stdio.h> /* XXX use own I/O routines */
#include <errno.h>
#include <string.h>
@@ -24,24 +24,26 @@
#include "utils/exc.h"
#include "storage/ipc.h"
-static void ExcUnCaught(Exception *excP, ExcDetail detail, ExcData data,
+static void
+ExcUnCaught(Exception * excP, ExcDetail detail, ExcData data,
ExcMessage message);
-static void ExcPrint(Exception *excP, ExcDetail detail, ExcData data,
- ExcMessage message);
+static void
+ExcPrint(Exception * excP, ExcDetail detail, ExcData data,
+ ExcMessage message);
/*
* Global Variables
*/
-static bool ExceptionHandlingEnabled = false;
+static bool ExceptionHandlingEnabled = false;
-char* ExcFileName = NULL;
+char *ExcFileName = NULL;
Index ExcLineNumber = 0;
-ExcFrame *ExcCurFrameP = NULL;
+ExcFrame *ExcCurFrameP = NULL;
-static ExcProc *ExcUnCaughtP = NULL;
+static ExcProc *ExcUnCaughtP = NULL;
-extern char* ProgramName;
+extern char *ProgramName;
/*
* Exported Functions
@@ -49,148 +51,157 @@ extern char* ProgramName;
/*
* EnableExceptionHandling --
- * Enables/disables the exception handling system.
+ * Enables/disables the exception handling system.
*
* Note:
- * This must be called before any exceptions occur. I.e., call this first!
- * This routine will not return if an error is detected.
- * This does not follow the usual Enable... protocol.
- * This should be merged more closely with the error logging and tracing
- * packages.
+ * This must be called before any exceptions occur. I.e., call this first!
+ * This routine will not return if an error is detected.
+ * This does not follow the usual Enable... protocol.
+ * This should be merged more closely with the error logging and tracing
+ * packages.
*
* Exceptions:
- * none
+ * none
*/
/*
* Excection handling should be supported by the language, thus there should
* be no need to explicitly enable exception processing.
*
* This function should probably not be called, ever. Currently it does
- * almost nothing. If there is a need for this intialization and checking.
+ * almost nothing. If there is a need for this intialization and checking.
* then this function should be converted to the new-style Enable code and
* called by all the other module Enable functions.
*/
void
EnableExceptionHandling(bool on)
{
- if (on == ExceptionHandlingEnabled) {
- /* XXX add logging of failed state */
- exitpg(255);
- /* ExitPostgres(FatalExitStatus); */
- }
-
- if (on) { /* initialize */
- ;
- } else { /* cleanup */
- ExcFileName = NULL;
- ExcLineNumber = 0;
- ExcCurFrameP = NULL;
- ExcUnCaughtP = NULL;
- }
-
- ExceptionHandlingEnabled = on;
+ if (on == ExceptionHandlingEnabled)
+ {
+ /* XXX add logging of failed state */
+ exitpg(255);
+ /* ExitPostgres(FatalExitStatus); */
+ }
+
+ if (on)
+ { /* initialize */
+ ;
+ }
+ else
+ { /* cleanup */
+ ExcFileName = NULL;
+ ExcLineNumber = 0;
+ ExcCurFrameP = NULL;
+ ExcUnCaughtP = NULL;
+ }
+
+ ExceptionHandlingEnabled = on;
}
static void
-ExcPrint(Exception *excP,
- ExcDetail detail,
- ExcData data,
- ExcMessage message)
+ExcPrint(Exception * excP,
+ ExcDetail detail,
+ ExcData data,
+ ExcMessage message)
{
- extern int errno;
- extern int sys_nerr;
-
+ extern int errno;
+ extern int sys_nerr;
+
#ifdef lint
- data = data;
+ data = data;
#endif
-
- fflush(stdout); /* In case stderr is buffered */
-
-#if 0
- if (ProgramName != NULL && *ProgramName != '\0')
- fprintf(stderr, "%s: ", ProgramName);
+
+ fflush(stdout); /* In case stderr is buffered */
+
+#if 0
+ if (ProgramName != NULL && *ProgramName != '\0')
+ fprintf(stderr, "%s: ", ProgramName);
#endif
-
- if (message != NULL)
- fprintf(stderr, "%s", message);
- else if (excP->message != NULL)
- fprintf(stderr, "%s", excP->message);
- else
+
+ if (message != NULL)
+ fprintf(stderr, "%s", message);
+ else if (excP->message != NULL)
+ fprintf(stderr, "%s", excP->message);
+ else
#ifdef lint
- fprintf(stderr, "UNNAMED EXCEPTION 0x%lx", excP);
+ fprintf(stderr, "UNNAMED EXCEPTION 0x%lx", excP);
#else
- fprintf(stderr, "UNNAMED EXCEPTION 0x%lx", (long)excP);
+ fprintf(stderr, "UNNAMED EXCEPTION 0x%lx", (long) excP);
#endif
-
- fprintf(stderr, " (%ld)", detail);
-
- if (errno > 0 && errno < sys_nerr)
- fprintf(stderr, " [%s]", strerror(errno));
- else if (errno != 0)
- fprintf(stderr, " [Error %d]", errno);
-
- fprintf(stderr, "\n");
-
- fflush(stderr);
+
+ fprintf(stderr, " (%ld)", detail);
+
+ if (errno > 0 && errno < sys_nerr)
+ fprintf(stderr, " [%s]", strerror(errno));
+ else if (errno != 0)
+ fprintf(stderr, " [Error %d]", errno);
+
+ fprintf(stderr, "\n");
+
+ fflush(stderr);
}
#ifdef NOT_USED
-ExcProc *
+ExcProc *
ExcGetUnCaught(void)
{
- return (ExcUnCaughtP);
+ return (ExcUnCaughtP);
}
+
#endif
#ifdef NOT_USED
-ExcProc *
-ExcSetUnCaught(ExcProc *newP)
+ExcProc *
+ExcSetUnCaught(ExcProc * newP)
{
- ExcProc *oldP = ExcUnCaughtP;
-
- ExcUnCaughtP = newP;
-
- return (oldP);
+ ExcProc *oldP = ExcUnCaughtP;
+
+ ExcUnCaughtP = newP;
+
+ return (oldP);
}
+
#endif
static void
-ExcUnCaught(Exception *excP,
- ExcDetail detail,
- ExcData data,
- ExcMessage message)
+ExcUnCaught(Exception * excP,
+ ExcDetail detail,
+ ExcData data,
+ ExcMessage message)
{
- ExcPrint(excP, detail, data, message);
-
- ExcAbort(excP, detail, data, message);
+ ExcPrint(excP, detail, data, message);
+
+ ExcAbort(excP, detail, data, message);
}
void
-ExcRaise(Exception *excP,
- ExcDetail detail,
- ExcData data,
- ExcMessage message)
+ExcRaise(Exception * excP,
+ ExcDetail detail,
+ ExcData data,
+ ExcMessage message)
{
- register ExcFrame *efp;
-
- efp = ExcCurFrameP;
- if (efp == NULL) {
- if (ExcUnCaughtP != NULL)
- (*ExcUnCaughtP)(excP, detail, data, message);
-
- ExcUnCaught(excP, detail, data, message);
- } else {
- efp->id = excP;
- efp->detail = detail;
- efp->data = data;
- efp->message = message;
-
- ExcCurFrameP = efp->link;
-
+ register ExcFrame *efp;
+
+ efp = ExcCurFrameP;
+ if (efp == NULL)
+ {
+ if (ExcUnCaughtP != NULL)
+ (*ExcUnCaughtP) (excP, detail, data, message);
+
+ ExcUnCaught(excP, detail, data, message);
+ }
+ else
+ {
+ efp->id = excP;
+ efp->detail = detail;
+ efp->data = data;
+ efp->message = message;
+
+ ExcCurFrameP = efp->link;
+
#if defined (JMP_BUF)
- longjmp(efp->context, 1);
+ longjmp(efp->context, 1);
#else
- siglongjmp(efp->context, 1);
+ siglongjmp(efp->context, 1);
#endif
- }
+ }
}
diff --git a/src/backend/utils/error/excabort.c b/src/backend/utils/error/excabort.c
index 29fd64ab7d5..3240f326496 100644
--- a/src/backend/utils/error/excabort.c
+++ b/src/backend/utils/error/excabort.c
@@ -1,31 +1,31 @@
/*-------------------------------------------------------------------------
*
* excabort.c--
- * Default exception abort code.
+ * Default exception abort code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/excabort.c,v 1.2 1996/11/03 06:53:32 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/excabort.c,v 1.3 1997/09/07 04:53:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include "utils/exc.h" /* where function declarations go */
+#include "utils/exc.h" /* where function declarations go */
void
-ExcAbort(const Exception *excP,
- ExcDetail detail,
- ExcData data,
- ExcMessage message)
+ExcAbort(const Exception * excP,
+ ExcDetail detail,
+ ExcData data,
+ ExcMessage message)
{
#ifdef __SABER__
- saber_stop();
+ saber_stop();
#else
- /* dump core */
- abort();
+ /* dump core */
+ abort();
#endif
}
diff --git a/src/backend/utils/error/excid.c b/src/backend/utils/error/excid.c
index 410d7a56c88..ada9dabed70 100644
--- a/src/backend/utils/error/excid.c
+++ b/src/backend/utils/error/excid.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* excid.c--
- * POSTGRES known exception identifier code.
+ * POSTGRES known exception identifier code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/excid.c,v 1.2 1996/11/03 06:53:35 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/excid.c,v 1.3 1997/09/07 04:53:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,51 +17,51 @@
#include "utils/excid.h"
/*****************************************************************************
- * Generic Recoverable Exceptions *
+ * Generic Recoverable Exceptions *
*****************************************************************************/
/*
* FailedAssertion --
- * Indicates an Assert(...) failed.
+ * Indicates an Assert(...) failed.
*/
-Exception FailedAssertion = { "Failed Assertion" };
+Exception FailedAssertion = {"Failed Assertion"};
/*
* BadState --
- * Indicates a function call request is inconsistent with module state.
+ * Indicates a function call request is inconsistent with module state.
*/
-Exception BadState = { "Bad State for Function Call" };
+Exception BadState = {"Bad State for Function Call"};
/*
* BadArg --
- * Indicates a function call argument or arguments is out-of-bounds.
+ * Indicates a function call argument or arguments is out-of-bounds.
*/
-Exception BadArg = { "Bad Argument to Function Call" };
+Exception BadArg = {"Bad Argument to Function Call"};
/*****************************************************************************
- * Specific Recoverable Exceptions *
+ * Specific Recoverable Exceptions *
*****************************************************************************/
/*
* BadAllocSize --
- * Indicates that an allocation request is of unreasonable size.
+ * Indicates that an allocation request is of unreasonable size.
*/
-Exception BadAllocSize = { "Too Large Allocation Request" };
+Exception BadAllocSize = {"Too Large Allocation Request"};
/*
* ExhaustedMemory --
- * Indicates an dynamic memory allocation failed.
+ * Indicates an dynamic memory allocation failed.
*/
-Exception ExhaustedMemory = { "Memory Allocation Failed" };
+Exception ExhaustedMemory = {"Memory Allocation Failed"};
/*
* Unimplemented --
- * Indicates a function call request requires unimplemented code.
+ * Indicates a function call request requires unimplemented code.
*/
-Exception Unimplemented = { "Unimplemented Functionality" };
+Exception Unimplemented = {"Unimplemented Functionality"};
-Exception CatalogFailure = {"Catalog failure"}; /* XXX inconsistent */
-Exception InternalError = {"Internal Error"}; /* XXX inconsistent */
-Exception SemanticError = {"Semantic Error"}; /* XXX inconsistent */
-Exception SystemError = {"System Error"}; /* XXX inconsistent */
+Exception CatalogFailure = {"Catalog failure"}; /* XXX inconsistent */
+Exception InternalError = {"Internal Error"}; /* XXX inconsistent */
+Exception SemanticError = {"Semantic Error"}; /* XXX inconsistent */
+Exception SystemError = {"System Error"}; /* XXX inconsistent */
diff --git a/src/backend/utils/error/format.c b/src/backend/utils/error/format.c
index bdbaddb402f..f996dbb8eb7 100644
--- a/src/backend/utils/error/format.c
+++ b/src/backend/utils/error/format.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* format.c--
- * a wrapper around code that does what vsprintf does.
+ * a wrapper around code that does what vsprintf does.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/format.c,v 1.3 1997/08/12 22:54:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/format.c,v 1.4 1997/09/07 04:53:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,26 +15,26 @@
#include <stdarg.h>
#include "c.h"
-#define FormMaxSize 1024
-#define FormMinSize (FormMaxSize / 8)
+#define FormMaxSize 1024
+#define FormMinSize (FormMaxSize / 8)
-static char FormBuf[FormMaxSize];
+static char FormBuf[FormMaxSize];
/* ----------------
- * form
+ * form
* ----------------
*/
-char *
-form(const char *fmt, ... )
+char *
+form(const char *fmt,...)
{
- va_list args;
+ va_list args;
- va_start(args, fmt);
-
- vsprintf(FormBuf, fmt, args);
+ va_start(args, fmt);
- va_end(args);
-
- return (FormBuf);
+ vsprintf(FormBuf, fmt, args);
+
+ va_end(args);
+
+ return (FormBuf);
}
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 079c9d0a173..0be7524290f 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* dfmgr.c--
- * Dynamic function manager code.
+ * Dynamic function manager code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.9 1997/09/01 08:06:17 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.10 1997/09/07 04:53:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,15 +18,15 @@
#include "postgres.h"
-#include "config.h" /* for MAXPATHLEN */
-#include "fmgr.h" /* generated by Gen_fmgrtab.sh */
+#include "config.h" /* for MAXPATHLEN */
+#include "fmgr.h" /* generated by Gen_fmgrtab.sh */
#include "utils/dynamic_loader.h"
#include "utils/elog.h"
#include "utils/builtins.h"
#include "access/heapam.h"
#include "nodes/pg_list.h"
-#include "port-protos.h" /* system specific function prototypes */
+#include "port-protos.h" /* system specific function prototypes */
#ifdef __ultrix
#include <dl.h>
#endif
@@ -39,178 +39,197 @@ static DynamicFileList *file_list = (DynamicFileList *) NULL;
static DynamicFileList *file_tail = (DynamicFileList *) NULL;
#define NOT_EQUAL(A, B) (((A).st_ino != (B).inode) \
- || ((A).st_dev != (B).device))
+ || ((A).st_dev != (B).device))
-static Oid procedureId_save = -1;
-static int pronargs_save;
+static Oid procedureId_save = -1;
+static int pronargs_save;
static func_ptr user_fn_save = (func_ptr) NULL;
static func_ptr handle_load(char *filename, char *funcname);
-func_ptr trigger_dynamic (char *filename, char *funcname);
+func_ptr trigger_dynamic(char *filename, char *funcname);
func_ptr
fmgr_dynamic(Oid procedureId, int *pronargs)
{
- HeapTuple procedureTuple;
- Form_pg_proc procedureStruct;
- char *proname;
- char *probinattr, *probinstring;
- func_ptr user_fn;
- Relation rdesc;
- bool isnull;
-
- if (procedureId == procedureId_save) {
- *pronargs = pronargs_save;
- return(user_fn_save);
- }
-
- /*
- * The procedure isn't a builtin, so we'll have to do a catalog
- * lookup to find its pg_proc entry.
- */
- procedureTuple = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(procedureId),
- 0,0,0);
- if (!HeapTupleIsValid(procedureTuple)) {
- elog(WARN, "fmgr: Cache lookup failed for procedure %d\n",
- procedureId);
- return((func_ptr) NULL);
- }
-
- procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
- proname = procedureStruct->proname.data;
- pronargs_save = *pronargs = procedureStruct->pronargs;
-
- /*
- * Extract the procedure info from the pg_proc tuple.
- * Since probin is varlena, do a amgetattr() on the procedure
- * tuple. To do that, we need the rdesc for the procedure
- * relation, so...
- */
-
- /* open pg_procedure */
-
- rdesc = heap_openr(ProcedureRelationName);
- if (!RelationIsValid(rdesc)) {
- elog(WARN, "fmgr: Could not open relation %s",
- ProcedureRelationName);
- return((func_ptr) NULL);
- }
- probinattr = heap_getattr(procedureTuple, (Buffer) 0,
- Anum_pg_proc_probin,
- RelationGetTupleDescriptor(rdesc), &isnull);
- if (!PointerIsValid(probinattr) /*|| isnull*/) {
- heap_close(rdesc);
- elog(WARN, "fmgr: Could not extract probin for %d from %s",
- procedureId, ProcedureRelationName);
- return((func_ptr) NULL);
- }
- probinstring = textout((struct varlena *) probinattr);
-
- user_fn = handle_load(probinstring, proname);
-
- procedureId_save = procedureId;
- user_fn_save = user_fn;
-
- return(user_fn);
+ HeapTuple procedureTuple;
+ Form_pg_proc procedureStruct;
+ char *proname;
+ char *probinattr,
+ *probinstring;
+ func_ptr user_fn;
+ Relation rdesc;
+ bool isnull;
+
+ if (procedureId == procedureId_save)
+ {
+ *pronargs = pronargs_save;
+ return (user_fn_save);
+ }
+
+ /*
+ * The procedure isn't a builtin, so we'll have to do a catalog lookup
+ * to find its pg_proc entry.
+ */
+ procedureTuple = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(procedureId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(procedureTuple))
+ {
+ elog(WARN, "fmgr: Cache lookup failed for procedure %d\n",
+ procedureId);
+ return ((func_ptr) NULL);
+ }
+
+ procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
+ proname = procedureStruct->proname.data;
+ pronargs_save = *pronargs = procedureStruct->pronargs;
+
+ /*
+ * Extract the procedure info from the pg_proc tuple. Since probin is
+ * varlena, do a amgetattr() on the procedure tuple. To do that, we
+ * need the rdesc for the procedure relation, so...
+ */
+
+ /* open pg_procedure */
+
+ rdesc = heap_openr(ProcedureRelationName);
+ if (!RelationIsValid(rdesc))
+ {
+ elog(WARN, "fmgr: Could not open relation %s",
+ ProcedureRelationName);
+ return ((func_ptr) NULL);
+ }
+ probinattr = heap_getattr(procedureTuple, (Buffer) 0,
+ Anum_pg_proc_probin,
+ RelationGetTupleDescriptor(rdesc), &isnull);
+ if (!PointerIsValid(probinattr) /* || isnull */ )
+ {
+ heap_close(rdesc);
+ elog(WARN, "fmgr: Could not extract probin for %d from %s",
+ procedureId, ProcedureRelationName);
+ return ((func_ptr) NULL);
+ }
+ probinstring = textout((struct varlena *) probinattr);
+
+ user_fn = handle_load(probinstring, proname);
+
+ procedureId_save = procedureId;
+ user_fn_save = user_fn;
+
+ return (user_fn);
}
-static func_ptr
+static func_ptr
handle_load(char *filename, char *funcname)
{
- DynamicFileList *file_scanner = (DynamicFileList *) NULL;
- func_ptr retval = (func_ptr) NULL;
- char *load_error;
- struct stat stat_buf;
-
- /*
- * Do this because loading files may screw up the dynamic function
- * manager otherwise.
- */
- procedureId_save = -1;
-
- /*
- * Scan the list of loaded FILES to see if the function
- * has been loaded.
- */
-
- if (filename != (char *) NULL) {
- for (file_scanner = file_list;
- file_scanner != (DynamicFileList *) NULL
- && file_scanner->filename != (char *) NULL
- && strcmp(filename, file_scanner->filename) != 0;
- file_scanner = file_scanner->next)
- ;
- if (file_scanner == (DynamicFileList *) NULL) {
- if (stat(filename, &stat_buf) == -1) {
- elog(WARN, "stat failed on file %s", filename);
- }
-
- for (file_scanner = file_list;
- file_scanner != (DynamicFileList *) NULL
- && (NOT_EQUAL(stat_buf, *file_scanner));
- file_scanner = file_scanner->next)
- ;
- /*
- * Same files - different paths (ie, symlink or link)
- */
- if (file_scanner != (DynamicFileList *) NULL)
- strcpy(file_scanner->filename, filename);
-
- }
- } else {
- file_scanner = (DynamicFileList *) NULL;
- }
-
- /*
- * File not loaded yet.
- */
-
- if (file_scanner == (DynamicFileList *) NULL) {
- if (file_list == (DynamicFileList *) NULL) {
- file_list = (DynamicFileList *)
- malloc(sizeof(DynamicFileList));
- file_scanner = file_list;
- } else {
- file_tail->next = (DynamicFileList *)
- malloc(sizeof(DynamicFileList));
- file_scanner = file_tail->next;
- }
- memset((char *) file_scanner, 0, sizeof(DynamicFileList));
-
- strcpy(file_scanner->filename, filename);
- file_scanner->device = stat_buf.st_dev;
- file_scanner->inode = stat_buf.st_ino;
- file_scanner->next = (DynamicFileList *) NULL;
-
- file_scanner->handle = pg_dlopen(filename);
- if (file_scanner->handle == (void *)NULL) {
- load_error = (char *) pg_dlerror();
- if (file_scanner == file_list) {
- file_list = (DynamicFileList *) NULL;
- } else {
- file_tail->next = (DynamicFileList *) NULL;
- }
-
- free((char *) file_scanner);
- elog(WARN, "Load of file %s failed: %s", filename, load_error);
- }
-
+ DynamicFileList *file_scanner = (DynamicFileList *) NULL;
+ func_ptr retval = (func_ptr) NULL;
+ char *load_error;
+ struct stat stat_buf;
+
+ /*
+ * Do this because loading files may screw up the dynamic function
+ * manager otherwise.
+ */
+ procedureId_save = -1;
+
/*
- * Just load the file - we are done with that so return.
+ * Scan the list of loaded FILES to see if the function has been
+ * loaded.
*/
- file_tail = file_scanner;
-
- if (funcname == (char *) NULL)
- return((func_ptr) NULL);
- }
-
- retval = (func_ptr) pg_dlsym(file_scanner->handle, funcname);
-
- if (retval == (func_ptr) NULL) {
- elog(WARN, "Can't find function %s in file %s", funcname, filename);
- }
-
- return(retval);
+
+ if (filename != (char *) NULL)
+ {
+ for (file_scanner = file_list;
+ file_scanner != (DynamicFileList *) NULL
+ && file_scanner->filename != (char *) NULL
+ && strcmp(filename, file_scanner->filename) != 0;
+ file_scanner = file_scanner->next)
+ ;
+ if (file_scanner == (DynamicFileList *) NULL)
+ {
+ if (stat(filename, &stat_buf) == -1)
+ {
+ elog(WARN, "stat failed on file %s", filename);
+ }
+
+ for (file_scanner = file_list;
+ file_scanner != (DynamicFileList *) NULL
+ && (NOT_EQUAL(stat_buf, *file_scanner));
+ file_scanner = file_scanner->next)
+ ;
+
+ /*
+ * Same files - different paths (ie, symlink or link)
+ */
+ if (file_scanner != (DynamicFileList *) NULL)
+ strcpy(file_scanner->filename, filename);
+
+ }
+ }
+ else
+ {
+ file_scanner = (DynamicFileList *) NULL;
+ }
+
+ /*
+ * File not loaded yet.
+ */
+
+ if (file_scanner == (DynamicFileList *) NULL)
+ {
+ if (file_list == (DynamicFileList *) NULL)
+ {
+ file_list = (DynamicFileList *)
+ malloc(sizeof(DynamicFileList));
+ file_scanner = file_list;
+ }
+ else
+ {
+ file_tail->next = (DynamicFileList *)
+ malloc(sizeof(DynamicFileList));
+ file_scanner = file_tail->next;
+ }
+ memset((char *) file_scanner, 0, sizeof(DynamicFileList));
+
+ strcpy(file_scanner->filename, filename);
+ file_scanner->device = stat_buf.st_dev;
+ file_scanner->inode = stat_buf.st_ino;
+ file_scanner->next = (DynamicFileList *) NULL;
+
+ file_scanner->handle = pg_dlopen(filename);
+ if (file_scanner->handle == (void *) NULL)
+ {
+ load_error = (char *) pg_dlerror();
+ if (file_scanner == file_list)
+ {
+ file_list = (DynamicFileList *) NULL;
+ }
+ else
+ {
+ file_tail->next = (DynamicFileList *) NULL;
+ }
+
+ free((char *) file_scanner);
+ elog(WARN, "Load of file %s failed: %s", filename, load_error);
+ }
+
+ /*
+ * Just load the file - we are done with that so return.
+ */
+ file_tail = file_scanner;
+
+ if (funcname == (char *) NULL)
+ return ((func_ptr) NULL);
+ }
+
+ retval = (func_ptr) pg_dlsym(file_scanner->handle, funcname);
+
+ if (retval == (func_ptr) NULL)
+ {
+ elog(WARN, "Can't find function %s in file %s", funcname, filename);
+ }
+
+ return (retval);
}
/*
@@ -218,7 +237,7 @@ handle_load(char *filename, char *funcname)
*
* If the file is already loaded:
* o Zero out that file's loaded space (so it doesn't screw up linking)
- * o Free all space associated with that file
+ * o Free all space associated with that file
* o Free that file's descriptor.
*
* Now load the file by calling handle_load with a NULL argument as the
@@ -227,49 +246,61 @@ handle_load(char *filename, char *funcname)
void
load_file(char *filename)
{
- DynamicFileList *file_scanner, *p;
- struct stat stat_buf;
-
- int done = 0;
-
- if (stat(filename, &stat_buf) == -1) {
- elog(WARN, "stat failed on file %s", filename);
- }
-
- if (file_list != (DynamicFileList *) NULL
- && !NOT_EQUAL(stat_buf, *file_list)) {
- file_scanner = file_list;
- file_list = file_list->next;
- pg_dlclose(file_scanner->handle);
- free((char *) file_scanner);
- } else if (file_list != (DynamicFileList *) NULL) {
- file_scanner = file_list;
- while (!done) {
- if (file_scanner->next == (DynamicFileList *) NULL) {
- done = 1;
- } else if (!NOT_EQUAL(stat_buf, *(file_scanner->next))) {
- done = 1;
- } else {
- file_scanner = file_scanner->next;
- }
- }
-
- if (file_scanner->next != (DynamicFileList *) NULL) {
- p = file_scanner->next;
- file_scanner->next = file_scanner->next->next;
- pg_dlclose(file_scanner->handle);
- free((char *)p);
- }
- }
- handle_load(filename, (char *) NULL);
+ DynamicFileList *file_scanner,
+ *p;
+ struct stat stat_buf;
+
+ int done = 0;
+
+ if (stat(filename, &stat_buf) == -1)
+ {
+ elog(WARN, "stat failed on file %s", filename);
+ }
+
+ if (file_list != (DynamicFileList *) NULL
+ && !NOT_EQUAL(stat_buf, *file_list))
+ {
+ file_scanner = file_list;
+ file_list = file_list->next;
+ pg_dlclose(file_scanner->handle);
+ free((char *) file_scanner);
+ }
+ else if (file_list != (DynamicFileList *) NULL)
+ {
+ file_scanner = file_list;
+ while (!done)
+ {
+ if (file_scanner->next == (DynamicFileList *) NULL)
+ {
+ done = 1;
+ }
+ else if (!NOT_EQUAL(stat_buf, *(file_scanner->next)))
+ {
+ done = 1;
+ }
+ else
+ {
+ file_scanner = file_scanner->next;
+ }
+ }
+
+ if (file_scanner->next != (DynamicFileList *) NULL)
+ {
+ p = file_scanner->next;
+ file_scanner->next = file_scanner->next->next;
+ pg_dlclose(file_scanner->handle);
+ free((char *) p);
+ }
+ }
+ handle_load(filename, (char *) NULL);
}
func_ptr
-trigger_dynamic (char *filename, char *funcname)
+trigger_dynamic(char *filename, char *funcname)
{
- func_ptr trigger_fn;
-
- trigger_fn = handle_load (filename, funcname);
-
- return (trigger_fn);
+ func_ptr trigger_fn;
+
+ trigger_fn = handle_load(filename, funcname);
+
+ return (trigger_fn);
}
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 1da0ab18773..f7d7b29d0a6 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* fmgr.c--
- * Interface routines for the table-driven function manager.
+ * Interface routines for the table-driven function manager.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.3 1997/08/19 21:35:21 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.4 1997/09/07 04:53:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,7 @@
#include "postgres.h"
/* these 2 files are generated by Gen_fmgrtab.sh; contain the declarations */
-#include "fmgr.h"
+#include "fmgr.h"
#include "utils/fmgrtab.h"
#include "nodes/pg_list.h"
@@ -29,173 +29,183 @@
#include "utils/elog.h"
-char *
+char *
fmgr_c(func_ptr user_fn,
- Oid func_id,
- int n_arguments,
- FmgrValues *values,
- bool *isNull)
+ Oid func_id,
+ int n_arguments,
+ FmgrValues * values,
+ bool * isNull)
{
- char *returnValue = (char *) NULL;
+ char *returnValue = (char *) NULL;
-
- if (user_fn == (func_ptr) NULL) {
- /*
- * a NULL func_ptr denotes untrusted function (in postgres 4.2).
- * Untrusted functions have very limited use and is clumsy. We
- * just get rid of it.
- */
- elog(WARN, "internal error: untrusted function not supported.");
- }
-
- switch (n_arguments) {
- case 0:
- returnValue = (*user_fn)();
- break;
- case 1:
- /* NullValue() uses isNull to check if args[0] is NULL */
- returnValue = (*user_fn)(values->data[0], isNull);
- break;
- case 2:
- returnValue = (*user_fn)(values->data[0], values->data[1]);
- break;
- case 3:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2]);
- break;
- case 4:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3]);
- break;
- case 5:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3],
- values->data[4]);
- break;
- case 6:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3],
- values->data[4], values->data[5]);
- break;
- case 7:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3],
- values->data[4], values->data[5],
- values->data[6]);
- break;
- case 8:
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3],
- values->data[4], values->data[5],
- values->data[6], values->data[7]);
- break;
- case 9:
- /*
- * XXX Note that functions with >8 arguments can only be
- * called from inside the system, not from the user level,
- * since the catalogs only store 8 argument types for user
- * type-checking!
- */
- returnValue = (*user_fn)(values->data[0], values->data[1],
- values->data[2], values->data[3],
- values->data[4], values->data[5],
- values->data[6], values->data[7],
- values->data[8]);
- break;
- default:
- elog(WARN, "fmgr_c: function %d: too many arguments (%d > %d)",
- func_id, n_arguments, MAXFMGRARGS);
- break;
- }
- return(returnValue);
+
+ if (user_fn == (func_ptr) NULL)
+ {
+
+ /*
+ * a NULL func_ptr denotes untrusted function (in postgres 4.2).
+ * Untrusted functions have very limited use and is clumsy. We
+ * just get rid of it.
+ */
+ elog(WARN, "internal error: untrusted function not supported.");
+ }
+
+ switch (n_arguments)
+ {
+ case 0:
+ returnValue = (*user_fn) ();
+ break;
+ case 1:
+ /* NullValue() uses isNull to check if args[0] is NULL */
+ returnValue = (*user_fn) (values->data[0], isNull);
+ break;
+ case 2:
+ returnValue = (*user_fn) (values->data[0], values->data[1]);
+ break;
+ case 3:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2]);
+ break;
+ case 4:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3]);
+ break;
+ case 5:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3],
+ values->data[4]);
+ break;
+ case 6:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3],
+ values->data[4], values->data[5]);
+ break;
+ case 7:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3],
+ values->data[4], values->data[5],
+ values->data[6]);
+ break;
+ case 8:
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3],
+ values->data[4], values->data[5],
+ values->data[6], values->data[7]);
+ break;
+ case 9:
+
+ /*
+ * XXX Note that functions with >8 arguments can only be called
+ * from inside the system, not from the user level, since the
+ * catalogs only store 8 argument types for user type-checking!
+ */
+ returnValue = (*user_fn) (values->data[0], values->data[1],
+ values->data[2], values->data[3],
+ values->data[4], values->data[5],
+ values->data[6], values->data[7],
+ values->data[8]);
+ break;
+ default:
+ elog(WARN, "fmgr_c: function %d: too many arguments (%d > %d)",
+ func_id, n_arguments, MAXFMGRARGS);
+ break;
+ }
+ return (returnValue);
}
void
-fmgr_info(Oid procedureId, func_ptr *function, int *nargs)
+fmgr_info(Oid procedureId, func_ptr * function, int *nargs)
{
- func_ptr user_fn = NULL;
- FmgrCall *fcp;
- HeapTuple procedureTuple;
- FormData_pg_proc *procedureStruct;
- Oid language;
-
- if (!(fcp = fmgr_isbuiltin(procedureId))) {
- procedureTuple = SearchSysCacheTuple(PROOID,
- ObjectIdGetDatum(procedureId),
- 0,0,0);
- if (!HeapTupleIsValid(procedureTuple)) {
- elog(WARN, "fmgr_info: function %d: cache lookup failed\n",
- procedureId);
+ func_ptr user_fn = NULL;
+ FmgrCall *fcp;
+ HeapTuple procedureTuple;
+ FormData_pg_proc *procedureStruct;
+ Oid language;
+
+ if (!(fcp = fmgr_isbuiltin(procedureId)))
+ {
+ procedureTuple = SearchSysCacheTuple(PROOID,
+ ObjectIdGetDatum(procedureId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(procedureTuple))
+ {
+ elog(WARN, "fmgr_info: function %d: cache lookup failed\n",
+ procedureId);
+ }
+ procedureStruct = (FormData_pg_proc *)
+ GETSTRUCT(procedureTuple);
+ if (!procedureStruct->proistrusted)
+ {
+ *function = (func_ptr) NULL;
+ *nargs = procedureStruct->pronargs;
+ return;
+ }
+ language = procedureStruct->prolang;
+ switch (language)
+ {
+ case INTERNALlanguageId:
+ user_fn = fmgr_lookupByName(procedureStruct->proname.data);
+ if (!user_fn)
+ elog(WARN, "fmgr_info: function %s: not in internal table",
+ procedureStruct->proname.data);
+ break;
+ case ClanguageId:
+ user_fn = fmgr_dynamic(procedureId, nargs);
+ break;
+ case SQLlanguageId:
+ user_fn = (func_ptr) NULL;
+ *nargs = procedureStruct->pronargs;
+ break;
+ default:
+ elog(WARN, "fmgr_info: function %d: unknown language %d",
+ procedureId, language);
+ }
}
- procedureStruct = (FormData_pg_proc *)
- GETSTRUCT(procedureTuple);
- if (!procedureStruct->proistrusted) {
- *function = (func_ptr) NULL;
- *nargs = procedureStruct->pronargs;
- return;
+ else
+ {
+ user_fn = fcp->func;
+ *nargs = fcp->nargs;
}
- language = procedureStruct->prolang;
- switch (language) {
- case INTERNALlanguageId:
- user_fn = fmgr_lookupByName(procedureStruct->proname.data);
- if (!user_fn)
- elog(WARN, "fmgr_info: function %s: not in internal table",
- procedureStruct->proname.data);
- break;
- case ClanguageId:
- user_fn = fmgr_dynamic(procedureId, nargs);
- break;
- case SQLlanguageId:
- user_fn = (func_ptr) NULL;
- *nargs = procedureStruct->pronargs;
- break;
- default:
- elog(WARN, "fmgr_info: function %d: unknown language %d",
- procedureId, language);
- }
- } else {
- user_fn = fcp->func;
- *nargs = fcp->nargs;
- }
- *function = user_fn;
+ *function = user_fn;
}
/*
- * fmgr - return the value of a function call
+ * fmgr - return the value of a function call
*
- * If the function is a system routine, it's compiled in, so call
- * it directly.
+ * If the function is a system routine, it's compiled in, so call
+ * it directly.
*
- * Otherwise pass it to the the appropriate 'language' function caller.
+ * Otherwise pass it to the the appropriate 'language' function caller.
*
- * Returns the return value of the invoked function if succesful,
- * 0 if unsuccessful.
+ * Returns the return value of the invoked function if succesful,
+ * 0 if unsuccessful.
*/
-char *
-fmgr(Oid procedureId, ... )
+char *
+fmgr(Oid procedureId,...)
{
- va_list pvar;
- register i;
- int pronargs;
- FmgrValues values;
- func_ptr user_fn;
- bool isNull = false;
-
- va_start(pvar, procedureId);
-
- fmgr_info(procedureId, &user_fn, &pronargs);
-
- if (pronargs > MAXFMGRARGS) {
- elog(WARN, "fmgr: function %d: too many arguments (%d > %d)",
- procedureId, pronargs, MAXFMGRARGS);
- }
- for (i = 0; i < pronargs; ++i)
- values.data[i] = va_arg(pvar, char *);
- va_end(pvar);
-
- /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
- return(fmgr_c(user_fn, procedureId, pronargs, &values,
- &isNull));
+ va_list pvar;
+ register i;
+ int pronargs;
+ FmgrValues values;
+ func_ptr user_fn;
+ bool isNull = false;
+
+ va_start(pvar, procedureId);
+
+ fmgr_info(procedureId, &user_fn, &pronargs);
+
+ if (pronargs > MAXFMGRARGS)
+ {
+ elog(WARN, "fmgr: function %d: too many arguments (%d > %d)",
+ procedureId, pronargs, MAXFMGRARGS);
+ }
+ for (i = 0; i < pronargs; ++i)
+ values.data[i] = va_arg(pvar, char *);
+ va_end(pvar);
+
+ /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
+ return (fmgr_c(user_fn, procedureId, pronargs, &values,
+ &isNull));
}
/*
@@ -204,33 +214,35 @@ fmgr(Oid procedureId, ... )
* if you have all of this information you're likely to just jump through
* the pointer, but it's available for use with macros in fmgr.h if you
* want this routine to do sanity-checking for you.
- *
+ *
* func_ptr, func_id, n_arguments, args...
*/
#ifdef NOT_USED
-char *
-fmgr_ptr(func_ptr user_fn, Oid func_id, ...)
+char *
+fmgr_ptr(func_ptr user_fn, Oid func_id,...)
{
- va_list pvar;
- register i;
- int n_arguments;
- FmgrValues values;
- bool isNull = false;
-
- va_start(pvar, func_id);
- n_arguments = va_arg(pvar, int);
- if (n_arguments > MAXFMGRARGS) {
- elog(WARN, "fmgr_ptr: function %d: too many arguments (%d > %d)",
- func_id, n_arguments, MAXFMGRARGS);
- }
- for (i = 0; i < n_arguments; ++i)
- values.data[i] = va_arg(pvar, char *);
- va_end(pvar);
-
- /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
- return(fmgr_c(user_fn, func_id, n_arguments, &values,
- &isNull));
+ va_list pvar;
+ register i;
+ int n_arguments;
+ FmgrValues values;
+ bool isNull = false;
+
+ va_start(pvar, func_id);
+ n_arguments = va_arg(pvar, int);
+ if (n_arguments > MAXFMGRARGS)
+ {
+ elog(WARN, "fmgr_ptr: function %d: too many arguments (%d > %d)",
+ func_id, n_arguments, MAXFMGRARGS);
+ }
+ for (i = 0; i < n_arguments; ++i)
+ values.data[i] = va_arg(pvar, char *);
+ va_end(pvar);
+
+ /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
+ return (fmgr_c(user_fn, func_id, n_arguments, &values,
+ &isNull));
}
+
#endif
/*
@@ -238,19 +250,19 @@ fmgr_ptr(func_ptr user_fn, Oid func_id, ...)
* function pointer field to FuncIndexInfo, it will be replace by calls
* to fmgr_c().
*/
-char *
-fmgr_array_args(Oid procedureId, int nargs, char *args[], bool *isNull)
+char *
+fmgr_array_args(Oid procedureId, int nargs, char *args[], bool * isNull)
{
- func_ptr user_fn;
- int true_arguments;
-
- fmgr_info(procedureId, &user_fn, &true_arguments);
-
- /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
- return
- (fmgr_c(user_fn,
- procedureId,
- true_arguments,
- (FmgrValues*)args,
- isNull));
+ func_ptr user_fn;
+ int true_arguments;
+
+ fmgr_info(procedureId, &user_fn, &true_arguments);
+
+ /* XXX see WAY_COOL_ORTHOGONAL_FUNCTIONS */
+ return
+ (fmgr_c(user_fn,
+ procedureId,
+ true_arguments,
+ (FmgrValues *) args,
+ isNull));
}
diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c
index db209e1c338..736ca39d09f 100644
--- a/src/backend/utils/hash/dynahash.c
+++ b/src/backend/utils/hash/dynahash.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* dynahash.c--
- * dynamic hashing
+ * dynamic hashing
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.7 1997/08/12 22:54:50 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.8 1997/09/07 04:53:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- *
+ *
* Dynamic hashing, after CACM April 1988 pp 446-457, by Per-Ake Larson.
* Coded into C, with minor code improvements, and with hsearch(3) interface,
* by ejp@ausmelb.oz, Jul 26, 1988: 13:16;
@@ -35,27 +35,27 @@
* concatenation property, in probably unnecessary code 'optimisation'.
*
* Modified margo@postgres.berkeley.edu February 1990
- * added multiple table interface
+ * added multiple table interface
* Modified by sullivan@postgres.berkeley.edu April 1990
- * changed ctl structure for shared memory
+ * changed ctl structure for shared memory
*/
-# include <stdio.h>
-# include <sys/types.h>
-# include <string.h>
-# include "postgres.h"
-# include "utils/dynahash.h"
-# include "utils/hsearch.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include "postgres.h"
+#include "utils/dynahash.h"
+#include "utils/hsearch.h"
#ifndef FRONTEND
-# include "utils/mcxt.h"
-#endif /* !FRONTEND */
-# include "utils/palloc.h"
+#include "utils/mcxt.h"
+#endif /* !FRONTEND */
+#include "utils/palloc.h"
/*
* Fast arithmetic, relying on powers of 2,
* and on pre-processor concatenation property
*/
-# define MOD(x,y) ((x) & ((y)-1))
+#define MOD(x,y) ((x) & ((y)-1))
/*
* external routines
@@ -64,14 +64,14 @@
/*
* Private function prototypes
*/
-static long *DynaHashAlloc(unsigned int size);
-static void DynaHashFree(Pointer ptr);
-static uint32 call_hash(HTAB *hashp, char *k, int len);
-static SEG_OFFSET seg_alloc(HTAB *hashp);
-static int bucket_alloc(HTAB *hashp);
-static int dir_realloc(HTAB *hashp);
+static long *DynaHashAlloc(unsigned int size);
+static void DynaHashFree(Pointer ptr);
+static uint32 call_hash(HTAB * hashp, char *k, int len);
+static SEG_OFFSET seg_alloc(HTAB * hashp);
+static int bucket_alloc(HTAB * hashp);
+static int dir_realloc(HTAB * hashp);
-typedef long * ((*dhalloc_ptr)());
+typedef long *((*dhalloc_ptr) ());
#ifndef FRONTEND
/* ----------------
@@ -82,54 +82,54 @@ typedef long * ((*dhalloc_ptr)());
* garbage collector is going to corrupt them. -wei
*
* ??? the "cache" memory context is intended to store only
- * system cache information. The user of the hashing
- * routines should specify which context to use or we
- * should create a separate memory context for these
- * hash routines. For now I have modified this code to
- * do the latter -cim 1/19/91
+ * system cache information. The user of the hashing
+ * routines should specify which context to use or we
+ * should create a separate memory context for these
+ * hash routines. For now I have modified this code to
+ * do the latter -cim 1/19/91
* ----------------
*/
-GlobalMemory DynaHashCxt = (GlobalMemory) NULL;
+GlobalMemory DynaHashCxt = (GlobalMemory) NULL;
-static long *
+static long *
DynaHashAlloc(unsigned int size)
{
- if (! DynaHashCxt)
- DynaHashCxt = CreateGlobalMemory("DynaHash");
+ if (!DynaHashCxt)
+ DynaHashCxt = CreateGlobalMemory("DynaHash");
- return (long *)
- MemoryContextAlloc((MemoryContext)DynaHashCxt, size);
+ return (long *)
+ MemoryContextAlloc((MemoryContext) DynaHashCxt, size);
}
static void
DynaHashFree(Pointer ptr)
{
- MemoryContextFree((MemoryContext)DynaHashCxt, ptr);
+ MemoryContextFree((MemoryContext) DynaHashCxt, ptr);
}
-#define MEM_ALLOC DynaHashAlloc
-#define MEM_FREE DynaHashFree
+#define MEM_ALLOC DynaHashAlloc
+#define MEM_FREE DynaHashFree
-#else /* FRONTEND */
+#else /* FRONTEND */
-#define MEM_ALLOC palloc
-#define MEM_FREE pfree
+#define MEM_ALLOC palloc
+#define MEM_FREE pfree
-#endif /* FRONTEND */
+#endif /* FRONTEND */
/* ----------------
* Internal routines
* ----------------
*/
-static int expand_table(HTAB *hashp);
-static int hdefault(HTAB *hashp);
-static int init_htab(HTAB *hashp, int nelem);
+static int expand_table(HTAB * hashp);
+static int hdefault(HTAB * hashp);
+static int init_htab(HTAB * hashp, int nelem);
/*
* pointer access macros. Shared memory implementation cannot
- * store pointers in the hash table data structures because
+ * store pointers in the hash table data structures because
* pointer values will be different in different address spaces.
* these macros convert offsets to pointers and pointers to offsets.
* Shared memory need not be contiguous, but all addresses must be
@@ -145,282 +145,318 @@ static int init_htab(HTAB *hashp, int nelem);
#define MAKE_HASHOFFSET(hp,ptr)\
( ((unsigned long) ptr) - ((unsigned long) (hp)->segbase) )
-# if HASH_STATISTICS
-static long hash_accesses, hash_collisions, hash_expansions;
-# endif
+#if HASH_STATISTICS
+static long hash_accesses,
+ hash_collisions,
+ hash_expansions;
+
+#endif
/************************** CREATE ROUTINES **********************/
-HTAB *
-hash_create(int nelem, HASHCTL *info, int flags)
+HTAB *
+hash_create(int nelem, HASHCTL * info, int flags)
{
- register HHDR * hctl;
- HTAB * hashp;
-
-
- hashp = (HTAB *) MEM_ALLOC((unsigned long) sizeof(HTAB));
- memset(hashp, 0, sizeof(HTAB));
-
- if ( flags & HASH_FUNCTION ) {
- hashp->hash = info->hash;
- } else {
- /* default */
- hashp->hash = string_hash;
- }
-
- if ( flags & HASH_SHARED_MEM ) {
- /* ctl structure is preallocated for shared memory tables */
-
- hashp->hctl = (HHDR *) info->hctl;
- hashp->segbase = (char *) info->segbase;
- hashp->alloc = info->alloc;
- hashp->dir = (SEG_OFFSET *)info->dir;
-
- /* hash table already exists, we're just attaching to it */
- if (flags & HASH_ATTACH) {
- return(hashp);
+ register HHDR *hctl;
+ HTAB *hashp;
+
+
+ hashp = (HTAB *) MEM_ALLOC((unsigned long) sizeof(HTAB));
+ memset(hashp, 0, sizeof(HTAB));
+
+ if (flags & HASH_FUNCTION)
+ {
+ hashp->hash = info->hash;
+ }
+ else
+ {
+ /* default */
+ hashp->hash = string_hash;
+ }
+
+ if (flags & HASH_SHARED_MEM)
+ {
+ /* ctl structure is preallocated for shared memory tables */
+
+ hashp->hctl = (HHDR *) info->hctl;
+ hashp->segbase = (char *) info->segbase;
+ hashp->alloc = info->alloc;
+ hashp->dir = (SEG_OFFSET *) info->dir;
+
+ /* hash table already exists, we're just attaching to it */
+ if (flags & HASH_ATTACH)
+ {
+ return (hashp);
+ }
+
+ }
+ else
+ {
+ /* setup hash table defaults */
+
+ hashp->alloc = (dhalloc_ptr) MEM_ALLOC;
+ hashp->dir = NULL;
+ hashp->segbase = NULL;
+
}
-
- } else {
- /* setup hash table defaults */
-
- hashp->alloc = (dhalloc_ptr) MEM_ALLOC;
- hashp->dir = NULL;
- hashp->segbase = NULL;
-
- }
-
- if (! hashp->hctl) {
- hashp->hctl = (HHDR *) hashp->alloc((unsigned long)sizeof(HHDR));
- if (! hashp->hctl) {
- return(0);
+
+ if (!hashp->hctl)
+ {
+ hashp->hctl = (HHDR *) hashp->alloc((unsigned long) sizeof(HHDR));
+ if (!hashp->hctl)
+ {
+ return (0);
+ }
}
- }
-
- if ( !hdefault(hashp) ) return(0);
- hctl = hashp->hctl;
+
+ if (!hdefault(hashp))
+ return (0);
+ hctl = hashp->hctl;
#ifdef HASH_STATISTICS
- hctl->accesses = hctl->collisions = 0;
+ hctl->accesses = hctl->collisions = 0;
#endif
-
- if ( flags & HASH_BUCKET ) {
- hctl->bsize = info->bsize;
- hctl->bshift = my_log2(info->bsize);
- }
- if ( flags & HASH_SEGMENT ) {
- hctl->ssize = info->ssize;
- hctl->sshift = my_log2(info->ssize);
- }
- if ( flags & HASH_FFACTOR ) {
- hctl->ffactor = info->ffactor;
- }
-
- /*
- * SHM hash tables have fixed maximum size (allocate
- * a maximal sized directory).
- */
- if ( flags & HASH_DIRSIZE ) {
- hctl->max_dsize = my_log2(info->max_size);
- hctl->dsize = my_log2(info->dsize);
- }
- /* hash table now allocates space for key and data
- * but you have to say how much space to allocate
- */
- if ( flags & HASH_ELEM ) {
- hctl->keysize = info->keysize;
- hctl->datasize = info->datasize;
- }
- if ( flags & HASH_ALLOC ) {
- hashp->alloc = info->alloc;
- }
-
- if ( init_htab (hashp, nelem ) ) {
- hash_destroy(hashp);
- return(0);
- }
- return(hashp);
+
+ if (flags & HASH_BUCKET)
+ {
+ hctl->bsize = info->bsize;
+ hctl->bshift = my_log2(info->bsize);
+ }
+ if (flags & HASH_SEGMENT)
+ {
+ hctl->ssize = info->ssize;
+ hctl->sshift = my_log2(info->ssize);
+ }
+ if (flags & HASH_FFACTOR)
+ {
+ hctl->ffactor = info->ffactor;
+ }
+
+ /*
+ * SHM hash tables have fixed maximum size (allocate a maximal sized
+ * directory).
+ */
+ if (flags & HASH_DIRSIZE)
+ {
+ hctl->max_dsize = my_log2(info->max_size);
+ hctl->dsize = my_log2(info->dsize);
+ }
+
+ /*
+ * hash table now allocates space for key and data but you have to say
+ * how much space to allocate
+ */
+ if (flags & HASH_ELEM)
+ {
+ hctl->keysize = info->keysize;
+ hctl->datasize = info->datasize;
+ }
+ if (flags & HASH_ALLOC)
+ {
+ hashp->alloc = info->alloc;
+ }
+
+ if (init_htab(hashp, nelem))
+ {
+ hash_destroy(hashp);
+ return (0);
+ }
+ return (hashp);
}
/*
- Allocate and initialize an HTAB structure
+ Allocate and initialize an HTAB structure
*/
static int
-hdefault(HTAB *hashp)
+hdefault(HTAB * hashp)
{
- HHDR *hctl;
-
- memset(hashp->hctl, 0, sizeof(HHDR));
-
- hctl = hashp->hctl;
- hctl->bsize = DEF_BUCKET_SIZE;
- hctl->bshift = DEF_BUCKET_SHIFT;
- hctl->ssize = DEF_SEGSIZE;
- hctl->sshift = DEF_SEGSIZE_SHIFT;
- hctl->dsize = DEF_DIRSIZE;
- hctl->ffactor = DEF_FFACTOR;
- hctl->nkeys = 0;
- hctl->nsegs = 0;
-
- /* I added these MS. */
-
- /* default memory allocation for hash buckets */
- hctl->keysize = sizeof(char *);
- hctl->datasize = sizeof(char *);
-
- /* table has no fixed maximum size */
- hctl->max_dsize = NO_MAX_DSIZE;
-
- /* garbage collection for HASH_REMOVE */
- hctl->freeBucketIndex = INVALID_INDEX;
-
- return(1);
+ HHDR *hctl;
+
+ memset(hashp->hctl, 0, sizeof(HHDR));
+
+ hctl = hashp->hctl;
+ hctl->bsize = DEF_BUCKET_SIZE;
+ hctl->bshift = DEF_BUCKET_SHIFT;
+ hctl->ssize = DEF_SEGSIZE;
+ hctl->sshift = DEF_SEGSIZE_SHIFT;
+ hctl->dsize = DEF_DIRSIZE;
+ hctl->ffactor = DEF_FFACTOR;
+ hctl->nkeys = 0;
+ hctl->nsegs = 0;
+
+ /* I added these MS. */
+
+ /* default memory allocation for hash buckets */
+ hctl->keysize = sizeof(char *);
+ hctl->datasize = sizeof(char *);
+
+ /* table has no fixed maximum size */
+ hctl->max_dsize = NO_MAX_DSIZE;
+
+ /* garbage collection for HASH_REMOVE */
+ hctl->freeBucketIndex = INVALID_INDEX;
+
+ return (1);
}
static int
-init_htab (HTAB *hashp, int nelem)
+init_htab(HTAB * hashp, int nelem)
{
- register SEG_OFFSET *segp;
- register int nbuckets;
- register int nsegs;
- int l2;
- HHDR *hctl;
-
- hctl = hashp->hctl;
- /*
- * Divide number of elements by the fill factor and determine a desired
- * number of buckets. Allocate space for the next greater power of
- * two number of buckets
- */
- nelem = (nelem - 1) / hctl->ffactor + 1;
-
- l2 = my_log2(nelem);
- nbuckets = 1 << l2;
-
- hctl->max_bucket = hctl->low_mask = nbuckets - 1;
- hctl->high_mask = (nbuckets << 1) - 1;
-
- nsegs = (nbuckets - 1) / hctl->ssize + 1;
- nsegs = 1 << my_log2(nsegs);
-
- if ( nsegs > hctl->dsize ) {
- hctl->dsize = nsegs;
- }
-
- /* Use two low order bits of points ???? */
- /*
- if ( !(hctl->mem = bit_alloc ( nbuckets )) ) return(-1);
- if ( !(hctl->mod = bit_alloc ( nbuckets )) ) return(-1);
- */
-
- /* allocate a directory */
- if (!(hashp->dir)) {
- hashp->dir =
- (SEG_OFFSET *)hashp->alloc(hctl->dsize * sizeof(SEG_OFFSET));
- if (! hashp->dir)
- return(-1);
- }
-
- /* Allocate initial segments */
- for (segp = hashp->dir; hctl->nsegs < nsegs; hctl->nsegs++, segp++ ) {
- *segp = seg_alloc(hashp);
- if ( *segp == (SEG_OFFSET)0 ) {
- hash_destroy(hashp);
- return (0);
+ register SEG_OFFSET *segp;
+ register int nbuckets;
+ register int nsegs;
+ int l2;
+ HHDR *hctl;
+
+ hctl = hashp->hctl;
+
+ /*
+ * Divide number of elements by the fill factor and determine a
+ * desired number of buckets. Allocate space for the next greater
+ * power of two number of buckets
+ */
+ nelem = (nelem - 1) / hctl->ffactor + 1;
+
+ l2 = my_log2(nelem);
+ nbuckets = 1 << l2;
+
+ hctl->max_bucket = hctl->low_mask = nbuckets - 1;
+ hctl->high_mask = (nbuckets << 1) - 1;
+
+ nsegs = (nbuckets - 1) / hctl->ssize + 1;
+ nsegs = 1 << my_log2(nsegs);
+
+ if (nsegs > hctl->dsize)
+ {
+ hctl->dsize = nsegs;
+ }
+
+ /* Use two low order bits of points ???? */
+
+ /*
+ * if ( !(hctl->mem = bit_alloc ( nbuckets )) ) return(-1); if (
+ * !(hctl->mod = bit_alloc ( nbuckets )) ) return(-1);
+ */
+
+ /* allocate a directory */
+ if (!(hashp->dir))
+ {
+ hashp->dir =
+ (SEG_OFFSET *) hashp->alloc(hctl->dsize * sizeof(SEG_OFFSET));
+ if (!hashp->dir)
+ return (-1);
+ }
+
+ /* Allocate initial segments */
+ for (segp = hashp->dir; hctl->nsegs < nsegs; hctl->nsegs++, segp++)
+ {
+ *segp = seg_alloc(hashp);
+ if (*segp == (SEG_OFFSET) 0)
+ {
+ hash_destroy(hashp);
+ return (0);
+ }
}
- }
-
-# if HASH_DEBUG
- fprintf(stderr, "%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
- "init_htab:",
- "TABLE POINTER ", hashp,
- "BUCKET SIZE ", hctl->bsize,
- "BUCKET SHIFT ", hctl->bshift,
- "DIRECTORY SIZE ", hctl->dsize,
- "SEGMENT SIZE ", hctl->ssize,
- "SEGMENT SHIFT ", hctl->sshift,
- "FILL FACTOR ", hctl->ffactor,
- "MAX BUCKET ", hctl->max_bucket,
- "HIGH MASK ", hctl->high_mask,
- "LOW MASK ", hctl->low_mask,
- "NSEGS ", hctl->nsegs,
- "NKEYS ", hctl->nkeys );
-# endif
- return (0);
+
+#if HASH_DEBUG
+ fprintf(stderr, "%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
+ "init_htab:",
+ "TABLE POINTER ", hashp,
+ "BUCKET SIZE ", hctl->bsize,
+ "BUCKET SHIFT ", hctl->bshift,
+ "DIRECTORY SIZE ", hctl->dsize,
+ "SEGMENT SIZE ", hctl->ssize,
+ "SEGMENT SHIFT ", hctl->sshift,
+ "FILL FACTOR ", hctl->ffactor,
+ "MAX BUCKET ", hctl->max_bucket,
+ "HIGH MASK ", hctl->high_mask,
+ "LOW MASK ", hctl->low_mask,
+ "NSEGS ", hctl->nsegs,
+ "NKEYS ", hctl->nkeys);
+#endif
+ return (0);
}
/********************** DESTROY ROUTINES ************************/
void
-hash_destroy (HTAB *hashp)
+hash_destroy(HTAB * hashp)
{
- /* cannot destroy a shared memory hash table */
- Assert(! hashp->segbase);
-
- if (hashp != NULL) {
- register SEG_OFFSET segNum;
- SEGMENT segp;
- int nsegs = hashp->hctl->nsegs;
- int j;
- BUCKET_INDEX *elp,p,q;
- ELEMENT *curr;
-
- for (segNum = 0; nsegs > 0; nsegs--, segNum++) {
-
- segp = GET_SEG(hashp,segNum);
- for (j = 0, elp = segp; j < hashp->hctl->ssize; j++, elp++) {
- for ( p = *elp; p != INVALID_INDEX; p = q ){
- curr = GET_BUCKET(hashp,p);
- q = curr->next;
- MEM_FREE((char *) curr);
+ /* cannot destroy a shared memory hash table */
+ Assert(!hashp->segbase);
+
+ if (hashp != NULL)
+ {
+ register SEG_OFFSET segNum;
+ SEGMENT segp;
+ int nsegs = hashp->hctl->nsegs;
+ int j;
+ BUCKET_INDEX *elp,
+ p,
+ q;
+ ELEMENT *curr;
+
+ for (segNum = 0; nsegs > 0; nsegs--, segNum++)
+ {
+
+ segp = GET_SEG(hashp, segNum);
+ for (j = 0, elp = segp; j < hashp->hctl->ssize; j++, elp++)
+ {
+ for (p = *elp; p != INVALID_INDEX; p = q)
+ {
+ curr = GET_BUCKET(hashp, p);
+ q = curr->next;
+ MEM_FREE((char *) curr);
+ }
+ }
+ free((char *) segp);
}
- }
- free((char *)segp);
+ MEM_FREE((char *) hashp->dir);
+ MEM_FREE((char *) hashp->hctl);
+ hash_stats("destroy", hashp);
+ MEM_FREE((char *) hashp);
}
- MEM_FREE( (char *) hashp->dir);
- MEM_FREE( (char *) hashp->hctl);
- hash_stats("destroy",hashp);
- MEM_FREE( (char *) hashp);
- }
}
void
-hash_stats(char *where, HTAB *hashp)
+hash_stats(char *where, HTAB * hashp)
{
-# if HASH_STATISTICS
-
- fprintf(stderr,"%s: this HTAB -- accesses %ld collisions %ld\n",
- where,hashp->hctl->accesses,hashp->hctl->collisions);
-
- fprintf(stderr,"hash_stats: keys %ld keysize %ld maxp %d segmentcount %d\n",
- hashp->hctl->nkeys, hashp->hctl->keysize,
- hashp->hctl->max_bucket, hashp->hctl->nsegs);
- fprintf(stderr,"%s: total accesses %ld total collisions %ld\n",
- where, hash_accesses, hash_collisions);
- fprintf(stderr,"hash_stats: total expansions %ld\n",
- hash_expansions);
-
-# endif
-
+#if HASH_STATISTICS
+
+ fprintf(stderr, "%s: this HTAB -- accesses %ld collisions %ld\n",
+ where, hashp->hctl->accesses, hashp->hctl->collisions);
+
+ fprintf(stderr, "hash_stats: keys %ld keysize %ld maxp %d segmentcount %d\n",
+ hashp->hctl->nkeys, hashp->hctl->keysize,
+ hashp->hctl->max_bucket, hashp->hctl->nsegs);
+ fprintf(stderr, "%s: total accesses %ld total collisions %ld\n",
+ where, hash_accesses, hash_collisions);
+ fprintf(stderr, "hash_stats: total expansions %ld\n",
+ hash_expansions);
+
+#endif
+
}
/*******************************SEARCH ROUTINES *****************************/
-static uint32
-call_hash(HTAB *hashp, char *k, int len)
+static uint32
+call_hash(HTAB * hashp, char *k, int len)
{
- long hash_val, bucket;
- HHDR *hctl;
-
- hctl = hashp->hctl;
- hash_val = hashp->hash(k, len);
-
- bucket = hash_val & hctl->high_mask;
- if ( bucket > hctl->max_bucket ) {
- bucket = bucket & hctl->low_mask;
- }
-
- return(bucket);
+ long hash_val,
+ bucket;
+ HHDR *hctl;
+
+ hctl = hashp->hctl;
+ hash_val = hashp->hash(k, len);
+
+ bucket = hash_val & hctl->high_mask;
+ if (bucket > hctl->max_bucket)
+ {
+ bucket = bucket & hctl->low_mask;
+ }
+
+ return (bucket);
}
/*
@@ -429,430 +465,462 @@ call_hash(HTAB *hashp, char *k, int len)
* action is one of HASH_FIND/HASH_ENTER/HASH_REMOVE
*
* RETURNS: NULL if table is corrupted, a pointer to the element
- * found/removed/entered if applicable, TRUE otherwise.
- * foundPtr is TRUE if we found an element in the table
- * (FALSE if we entered one).
+ * found/removed/entered if applicable, TRUE otherwise.
+ * foundPtr is TRUE if we found an element in the table
+ * (FALSE if we entered one).
*/
-long *
-hash_search(HTAB *hashp,
- char *keyPtr,
- HASHACTION action, /*
- * HASH_FIND / HASH_ENTER / HASH_REMOVE
- * HASH_FIND_SAVE / HASH_REMOVE_SAVED
- */
- bool *foundPtr)
+long *
+hash_search(HTAB * hashp,
+ char *keyPtr,
+ HASHACTION action, /* HASH_FIND / HASH_ENTER / HASH_REMOVE
+ * HASH_FIND_SAVE / HASH_REMOVE_SAVED */
+ bool * foundPtr)
{
- uint32 bucket;
- long segment_num;
- long segment_ndx;
- SEGMENT segp;
- register ELEMENT *curr;
- HHDR *hctl;
- BUCKET_INDEX currIndex;
- BUCKET_INDEX *prevIndexPtr;
- char * destAddr;
- static struct State {
- ELEMENT *currElem;
- BUCKET_INDEX currIndex;
- BUCKET_INDEX *prevIndex;
- } saveState;
-
- Assert((hashp && keyPtr));
- Assert((action == HASH_FIND) || (action == HASH_REMOVE) || (action == HASH_ENTER) || (action == HASH_FIND_SAVE) || (action == HASH_REMOVE_SAVED));
-
- hctl = hashp->hctl;
-
-# if HASH_STATISTICS
- hash_accesses++;
- hashp->hctl->accesses++;
-# endif
- if (action == HASH_REMOVE_SAVED)
- {
- curr = saveState.currElem;
- currIndex = saveState.currIndex;
- prevIndexPtr = saveState.prevIndex;
- /*
- * Try to catch subsequent errors
- */
- Assert(saveState.currElem && !(saveState.currElem = 0));
+ uint32 bucket;
+ long segment_num;
+ long segment_ndx;
+ SEGMENT segp;
+ register ELEMENT *curr;
+ HHDR *hctl;
+ BUCKET_INDEX currIndex;
+ BUCKET_INDEX *prevIndexPtr;
+ char *destAddr;
+ static struct State
+ {
+ ELEMENT *currElem;
+ BUCKET_INDEX currIndex;
+ BUCKET_INDEX *prevIndex;
+ } saveState;
+
+ Assert((hashp && keyPtr));
+ Assert((action == HASH_FIND) || (action == HASH_REMOVE) || (action == HASH_ENTER) || (action == HASH_FIND_SAVE) || (action == HASH_REMOVE_SAVED));
+
+ hctl = hashp->hctl;
+
+#if HASH_STATISTICS
+ hash_accesses++;
+ hashp->hctl->accesses++;
+#endif
+ if (action == HASH_REMOVE_SAVED)
+ {
+ curr = saveState.currElem;
+ currIndex = saveState.currIndex;
+ prevIndexPtr = saveState.prevIndex;
+
+ /*
+ * Try to catch subsequent errors
+ */
+ Assert(saveState.currElem && !(saveState.currElem = 0));
}
- else
- {
- bucket = call_hash(hashp, keyPtr, hctl->keysize);
- segment_num = bucket >> hctl->sshift;
- segment_ndx = bucket & ( hctl->ssize - 1 );
-
- segp = GET_SEG(hashp,segment_num);
-
- Assert(segp);
-
- prevIndexPtr = &segp[segment_ndx];
- currIndex = *prevIndexPtr;
- /*
- * Follow collision chain
- */
- for (curr = NULL;currIndex != INVALID_INDEX;) {
- /* coerce bucket index into a pointer */
- curr = GET_BUCKET(hashp,currIndex);
-
- if (! memcmp((char *)&(curr->key), keyPtr, hctl->keysize)) {
- break;
- }
- prevIndexPtr = &(curr->next);
+ else
+ {
+ bucket = call_hash(hashp, keyPtr, hctl->keysize);
+ segment_num = bucket >> hctl->sshift;
+ segment_ndx = bucket & (hctl->ssize - 1);
+
+ segp = GET_SEG(hashp, segment_num);
+
+ Assert(segp);
+
+ prevIndexPtr = &segp[segment_ndx];
currIndex = *prevIndexPtr;
-# if HASH_STATISTICS
- hash_collisions++;
- hashp->hctl->collisions++;
-# endif
- }
- }
-
- /*
- * if we found an entry or if we weren't trying
- * to insert, we're done now.
- */
- *foundPtr = (bool) (currIndex != INVALID_INDEX);
- switch (action) {
- case HASH_ENTER:
- if (currIndex != INVALID_INDEX)
- return(&(curr->key));
- break;
- case HASH_REMOVE:
- case HASH_REMOVE_SAVED:
- if (currIndex != INVALID_INDEX) {
- Assert(hctl->nkeys > 0);
- hctl->nkeys--;
-
- /* add the bucket to the freelist for this table. */
- *prevIndexPtr = curr->next;
- curr->next = hctl->freeBucketIndex;
- hctl->freeBucketIndex = currIndex;
-
- /* better hope the caller is synchronizing access to
- * this element, because someone else is going to reuse
- * it the next time something is added to the table
- */
- return (&(curr->key));
+
+ /*
+ * Follow collision chain
+ */
+ for (curr = NULL; currIndex != INVALID_INDEX;)
+ {
+ /* coerce bucket index into a pointer */
+ curr = GET_BUCKET(hashp, currIndex);
+
+ if (!memcmp((char *) &(curr->key), keyPtr, hctl->keysize))
+ {
+ break;
+ }
+ prevIndexPtr = &(curr->next);
+ currIndex = *prevIndexPtr;
+#if HASH_STATISTICS
+ hash_collisions++;
+ hashp->hctl->collisions++;
+#endif
+ }
}
- return((long *) TRUE);
- case HASH_FIND:
- if (currIndex != INVALID_INDEX)
- return(&(curr->key));
- return((long *)TRUE);
- case HASH_FIND_SAVE:
- if (currIndex != INVALID_INDEX)
- {
- saveState.currElem = curr;
- saveState.prevIndex = prevIndexPtr;
- saveState.currIndex = currIndex;
- return(&(curr->key));
- }
- return((long *)TRUE);
- default:
- /* can't get here */
- return (NULL);
- }
-
- /*
- If we got here, then we didn't find the element and
- we have to insert it into the hash table
- */
- Assert(currIndex == INVALID_INDEX);
-
- /* get the next free bucket */
- currIndex = hctl->freeBucketIndex;
- if (currIndex == INVALID_INDEX) {
-
- /* no free elements. allocate another chunk of buckets */
- if (! bucket_alloc(hashp)) {
- return(NULL);
+
+ /*
+ * if we found an entry or if we weren't trying to insert, we're done
+ * now.
+ */
+ *foundPtr = (bool) (currIndex != INVALID_INDEX);
+ switch (action)
+ {
+ case HASH_ENTER:
+ if (currIndex != INVALID_INDEX)
+ return (&(curr->key));
+ break;
+ case HASH_REMOVE:
+ case HASH_REMOVE_SAVED:
+ if (currIndex != INVALID_INDEX)
+ {
+ Assert(hctl->nkeys > 0);
+ hctl->nkeys--;
+
+ /* add the bucket to the freelist for this table. */
+ *prevIndexPtr = curr->next;
+ curr->next = hctl->freeBucketIndex;
+ hctl->freeBucketIndex = currIndex;
+
+ /*
+ * better hope the caller is synchronizing access to this
+ * element, because someone else is going to reuse it the next
+ * time something is added to the table
+ */
+ return (&(curr->key));
+ }
+ return ((long *) TRUE);
+ case HASH_FIND:
+ if (currIndex != INVALID_INDEX)
+ return (&(curr->key));
+ return ((long *) TRUE);
+ case HASH_FIND_SAVE:
+ if (currIndex != INVALID_INDEX)
+ {
+ saveState.currElem = curr;
+ saveState.prevIndex = prevIndexPtr;
+ saveState.currIndex = currIndex;
+ return (&(curr->key));
+ }
+ return ((long *) TRUE);
+ default:
+ /* can't get here */
+ return (NULL);
}
+
+ /*
+ * If we got here, then we didn't find the element and we have to
+ * insert it into the hash table
+ */
+ Assert(currIndex == INVALID_INDEX);
+
+ /* get the next free bucket */
currIndex = hctl->freeBucketIndex;
- }
- Assert(currIndex != INVALID_INDEX);
-
- curr = GET_BUCKET(hashp,currIndex);
- hctl->freeBucketIndex = curr->next;
-
- /* link into chain */
- *prevIndexPtr = currIndex;
-
- /* copy key and data */
- destAddr = (char *) &(curr->key);
- memmove(destAddr,keyPtr,hctl->keysize);
- curr->next = INVALID_INDEX;
-
- /* let the caller initialize the data field after
- * hash_search returns.
- */
- /* memmove(destAddr,keyPtr,hctl->keysize+hctl->datasize);*/
-
- /*
- * Check if it is time to split the segment
- */
- if (++hctl->nkeys / (hctl->max_bucket+1) > hctl->ffactor) {
+ if (currIndex == INVALID_INDEX)
+ {
+
+ /* no free elements. allocate another chunk of buckets */
+ if (!bucket_alloc(hashp))
+ {
+ return (NULL);
+ }
+ currIndex = hctl->freeBucketIndex;
+ }
+ Assert(currIndex != INVALID_INDEX);
+
+ curr = GET_BUCKET(hashp, currIndex);
+ hctl->freeBucketIndex = curr->next;
+
+ /* link into chain */
+ *prevIndexPtr = currIndex;
+
+ /* copy key and data */
+ destAddr = (char *) &(curr->key);
+ memmove(destAddr, keyPtr, hctl->keysize);
+ curr->next = INVALID_INDEX;
+
/*
- fprintf(stderr,"expanding on '%s'\n",keyPtr);
- hash_stats("expanded table",hashp);
- */
- if (! expand_table(hashp))
- return(NULL);
- }
- return (&(curr->key));
+ * let the caller initialize the data field after hash_search returns.
+ */
+ /* memmove(destAddr,keyPtr,hctl->keysize+hctl->datasize); */
+
+ /*
+ * Check if it is time to split the segment
+ */
+ if (++hctl->nkeys / (hctl->max_bucket + 1) > hctl->ffactor)
+ {
+
+ /*
+ * fprintf(stderr,"expanding on '%s'\n",keyPtr);
+ * hash_stats("expanded table",hashp);
+ */
+ if (!expand_table(hashp))
+ return (NULL);
+ }
+ return (&(curr->key));
}
/*
* hash_seq -- sequentially search through hash table and return
- * all the elements one by one, return NULL on error and
- * return TRUE in the end.
+ * all the elements one by one, return NULL on error and
+ * return TRUE in the end.
*
*/
-long *
-hash_seq(HTAB *hashp)
+long *
+hash_seq(HTAB * hashp)
{
- static uint32 curBucket = 0;
- static BUCKET_INDEX curIndex;
- ELEMENT *curElem;
- long segment_num;
- long segment_ndx;
- SEGMENT segp;
- HHDR *hctl;
-
- if (hashp == NULL)
- {
- /*
- * reset static state
- */
- curBucket = 0;
- curIndex = INVALID_INDEX;
- return((long *) NULL);
+ static uint32 curBucket = 0;
+ static BUCKET_INDEX curIndex;
+ ELEMENT *curElem;
+ long segment_num;
+ long segment_ndx;
+ SEGMENT segp;
+ HHDR *hctl;
+
+ if (hashp == NULL)
+ {
+
+ /*
+ * reset static state
+ */
+ curBucket = 0;
+ curIndex = INVALID_INDEX;
+ return ((long *) NULL);
}
-
- hctl = hashp->hctl;
- while (curBucket <= hctl->max_bucket) {
- if (curIndex != INVALID_INDEX) {
- curElem = GET_BUCKET(hashp, curIndex);
- curIndex = curElem->next;
- if (curIndex == INVALID_INDEX) /* end of this bucket */
- ++curBucket;
- return(&(curElem->key));
+
+ hctl = hashp->hctl;
+ while (curBucket <= hctl->max_bucket)
+ {
+ if (curIndex != INVALID_INDEX)
+ {
+ curElem = GET_BUCKET(hashp, curIndex);
+ curIndex = curElem->next;
+ if (curIndex == INVALID_INDEX) /* end of this bucket */
+ ++curBucket;
+ return (&(curElem->key));
+ }
+
+ /*
+ * initialize the search within this bucket.
+ */
+ segment_num = curBucket >> hctl->sshift;
+ segment_ndx = curBucket & (hctl->ssize - 1);
+
+ /*
+ * first find the right segment in the table directory.
+ */
+ segp = GET_SEG(hashp, segment_num);
+ if (segp == NULL)
+ /* this is probably an error */
+ return ((long *) NULL);
+
+ /*
+ * now find the right index into the segment for the first item in
+ * this bucket's chain. if the bucket is not empty (its entry in
+ * the dir is valid), we know this must correspond to a valid
+ * element and not a freed element because it came out of the
+ * directory of valid stuff. if there are elements in the bucket
+ * chains that point to the freelist we're in big trouble.
+ */
+ curIndex = segp[segment_ndx];
+
+ if (curIndex == INVALID_INDEX) /* empty bucket */
+ ++curBucket;
}
-
- /*
- * initialize the search within this bucket.
- */
- segment_num = curBucket >> hctl->sshift;
- segment_ndx = curBucket & ( hctl->ssize - 1 );
-
- /*
- * first find the right segment in the table directory.
- */
- segp = GET_SEG(hashp, segment_num);
- if (segp == NULL)
- /* this is probably an error */
- return((long *) NULL);
-
- /*
- * now find the right index into the segment for the first
- * item in this bucket's chain. if the bucket is not empty
- * (its entry in the dir is valid), we know this must
- * correspond to a valid element and not a freed element
- * because it came out of the directory of valid stuff. if
- * there are elements in the bucket chains that point to the
- * freelist we're in big trouble.
- */
- curIndex = segp[segment_ndx];
-
- if (curIndex == INVALID_INDEX) /* empty bucket */
- ++curBucket;
- }
-
- return((long *) TRUE); /* out of buckets */
+
+ return ((long *) TRUE); /* out of buckets */
}
/********************************* UTILITIES ************************/
static int
-expand_table(HTAB *hashp)
+expand_table(HTAB * hashp)
{
- HHDR *hctl;
- SEGMENT old_seg,new_seg;
- long old_bucket, new_bucket;
- long new_segnum, new_segndx;
- long old_segnum, old_segndx;
- ELEMENT *chain;
- BUCKET_INDEX *old,*newbi;
- register BUCKET_INDEX chainIndex,nextIndex;
-
+ HHDR *hctl;
+ SEGMENT old_seg,
+ new_seg;
+ long old_bucket,
+ new_bucket;
+ long new_segnum,
+ new_segndx;
+ long old_segnum,
+ old_segndx;
+ ELEMENT *chain;
+ BUCKET_INDEX *old,
+ *newbi;
+ register BUCKET_INDEX chainIndex,
+ nextIndex;
+
#ifdef HASH_STATISTICS
- hash_expansions++;
+ hash_expansions++;
#endif
-
- hctl = hashp->hctl;
- new_bucket = ++hctl->max_bucket;
- old_bucket = (hctl->max_bucket & hctl->low_mask);
-
- new_segnum = new_bucket >> hctl->sshift;
- new_segndx = MOD ( new_bucket, hctl->ssize );
-
- if ( new_segnum >= hctl->nsegs ) {
-
- /* Allocate new segment if necessary */
- if (new_segnum >= hctl->dsize) {
- dir_realloc(hashp);
+
+ hctl = hashp->hctl;
+ new_bucket = ++hctl->max_bucket;
+ old_bucket = (hctl->max_bucket & hctl->low_mask);
+
+ new_segnum = new_bucket >> hctl->sshift;
+ new_segndx = MOD(new_bucket, hctl->ssize);
+
+ if (new_segnum >= hctl->nsegs)
+ {
+
+ /* Allocate new segment if necessary */
+ if (new_segnum >= hctl->dsize)
+ {
+ dir_realloc(hashp);
+ }
+ if (!(hashp->dir[new_segnum] = seg_alloc(hashp)))
+ {
+ return (0);
+ }
+ hctl->nsegs++;
}
- if (! (hashp->dir[new_segnum] = seg_alloc(hashp))) {
- return (0);
+
+
+ if (new_bucket > hctl->high_mask)
+ {
+ /* Starting a new doubling */
+ hctl->low_mask = hctl->high_mask;
+ hctl->high_mask = new_bucket | hctl->low_mask;
}
- hctl->nsegs++;
- }
-
-
- if ( new_bucket > hctl->high_mask ) {
- /* Starting a new doubling */
- hctl->low_mask = hctl->high_mask;
- hctl->high_mask = new_bucket | hctl->low_mask;
- }
-
- /*
- * Relocate records to the new bucket
- */
- old_segnum = old_bucket >> hctl->sshift;
- old_segndx = MOD(old_bucket, hctl->ssize);
-
- old_seg = GET_SEG(hashp,old_segnum);
- new_seg = GET_SEG(hashp,new_segnum);
-
- old = &old_seg[old_segndx];
- newbi = &new_seg[new_segndx];
- for (chainIndex = *old;
- chainIndex != INVALID_INDEX;
- chainIndex = nextIndex){
-
- chain = GET_BUCKET(hashp,chainIndex);
- nextIndex = chain->next;
- if ( call_hash(hashp,
- (char *)&(chain->key),
- hctl->keysize) == old_bucket ) {
- *old = chainIndex;
- old = &chain->next;
- } else {
- *newbi = chainIndex;
- newbi = &chain->next;
+
+ /*
+ * Relocate records to the new bucket
+ */
+ old_segnum = old_bucket >> hctl->sshift;
+ old_segndx = MOD(old_bucket, hctl->ssize);
+
+ old_seg = GET_SEG(hashp, old_segnum);
+ new_seg = GET_SEG(hashp, new_segnum);
+
+ old = &old_seg[old_segndx];
+ newbi = &new_seg[new_segndx];
+ for (chainIndex = *old;
+ chainIndex != INVALID_INDEX;
+ chainIndex = nextIndex)
+ {
+
+ chain = GET_BUCKET(hashp, chainIndex);
+ nextIndex = chain->next;
+ if (call_hash(hashp,
+ (char *) &(chain->key),
+ hctl->keysize) == old_bucket)
+ {
+ *old = chainIndex;
+ old = &chain->next;
+ }
+ else
+ {
+ *newbi = chainIndex;
+ newbi = &chain->next;
+ }
+ chain->next = INVALID_INDEX;
}
- chain->next = INVALID_INDEX;
- }
- return (1);
+ return (1);
}
static int
-dir_realloc(HTAB *hashp)
+dir_realloc(HTAB * hashp)
{
- register char *p;
- char **p_ptr;
- long old_dirsize;
- long new_dirsize;
-
-
- if (hashp->hctl->max_dsize != NO_MAX_DSIZE)
+ register char *p;
+ char **p_ptr;
+ long old_dirsize;
+ long new_dirsize;
+
+
+ if (hashp->hctl->max_dsize != NO_MAX_DSIZE)
+ return (0);
+
+ /* Reallocate directory */
+ old_dirsize = hashp->hctl->dsize * sizeof(SEGMENT *);
+ new_dirsize = old_dirsize << 1;
+
+ p_ptr = (char **) hashp->dir;
+ p = (char *) hashp->alloc((unsigned long) new_dirsize);
+ if (p != NULL)
+ {
+ memmove(p, *p_ptr, old_dirsize);
+ memset(*p_ptr + old_dirsize, 0, new_dirsize - old_dirsize);
+ free((char *) *p_ptr);
+ *p_ptr = p;
+ hashp->hctl->dsize = new_dirsize;
+ return (1);
+ }
return (0);
-
- /* Reallocate directory */
- old_dirsize = hashp->hctl->dsize * sizeof ( SEGMENT * );
- new_dirsize = old_dirsize << 1;
-
- p_ptr = (char **) hashp->dir;
- p = (char *) hashp->alloc((unsigned long) new_dirsize );
- if (p != NULL) {
- memmove(p, *p_ptr, old_dirsize );
- memset ( *p_ptr + old_dirsize, 0, new_dirsize-old_dirsize );
- free( (char *)*p_ptr);
- *p_ptr = p;
- hashp->hctl->dsize = new_dirsize;
- return(1);
- }
- return (0);
-
+
}
-static SEG_OFFSET
+static SEG_OFFSET
seg_alloc(HTAB * hashp)
{
- SEGMENT segp;
- SEG_OFFSET segOffset;
-
-
- segp = (SEGMENT) hashp->alloc((unsigned long)
- sizeof(SEGMENT)*hashp->hctl->ssize);
-
- if (! segp) {
- return(0);
- }
-
- memset((char *)segp, 0,
- (long) sizeof(SEGMENT)*hashp->hctl->ssize);
-
- segOffset = MAKE_HASHOFFSET(hashp,segp);
- return(segOffset);
+ SEGMENT segp;
+ SEG_OFFSET segOffset;
+
+
+ segp = (SEGMENT) hashp->alloc((unsigned long)
+ sizeof(SEGMENT) * hashp->hctl->ssize);
+
+ if (!segp)
+ {
+ return (0);
+ }
+
+ memset((char *) segp, 0,
+ (long) sizeof(SEGMENT) * hashp->hctl->ssize);
+
+ segOffset = MAKE_HASHOFFSET(hashp, segp);
+ return (segOffset);
}
/*
* allocate some new buckets and link them into the free list
*/
static int
-bucket_alloc(HTAB *hashp)
+bucket_alloc(HTAB * hashp)
{
- int i;
- ELEMENT *tmpBucket;
- long bucketSize;
- BUCKET_INDEX tmpIndex,lastIndex;
-
- bucketSize =
- sizeof(BUCKET_INDEX) + hashp->hctl->keysize + hashp->hctl->datasize;
-
- /* make sure its aligned correctly */
- bucketSize += sizeof(long *) - (bucketSize % sizeof(long *));
-
- /* tmpIndex is the shmem offset into the first bucket of
- * the array.
- */
- tmpBucket = (ELEMENT *)
- hashp->alloc((unsigned long) BUCKET_ALLOC_INCR*bucketSize);
-
- if (! tmpBucket) {
- return(0);
- }
-
- tmpIndex = MAKE_HASHOFFSET(hashp,tmpBucket);
-
- /* set the freebucket list to point to the first bucket */
- lastIndex = hashp->hctl->freeBucketIndex;
- hashp->hctl->freeBucketIndex = tmpIndex;
-
- /* initialize each bucket to point to the one behind it */
- for (i=0;i<(BUCKET_ALLOC_INCR-1);i++) {
- tmpBucket = GET_BUCKET(hashp,tmpIndex);
- tmpIndex += bucketSize;
- tmpBucket->next = tmpIndex;
- }
-
- /* the last bucket points to the old freelist head (which is
- * probably invalid or we wouldnt be here)
- */
- tmpBucket->next = lastIndex;
-
- return(1);
+ int i;
+ ELEMENT *tmpBucket;
+ long bucketSize;
+ BUCKET_INDEX tmpIndex,
+ lastIndex;
+
+ bucketSize =
+ sizeof(BUCKET_INDEX) + hashp->hctl->keysize + hashp->hctl->datasize;
+
+ /* make sure its aligned correctly */
+ bucketSize += sizeof(long *) - (bucketSize % sizeof(long *));
+
+ /*
+ * tmpIndex is the shmem offset into the first bucket of the array.
+ */
+ tmpBucket = (ELEMENT *)
+ hashp->alloc((unsigned long) BUCKET_ALLOC_INCR * bucketSize);
+
+ if (!tmpBucket)
+ {
+ return (0);
+ }
+
+ tmpIndex = MAKE_HASHOFFSET(hashp, tmpBucket);
+
+ /* set the freebucket list to point to the first bucket */
+ lastIndex = hashp->hctl->freeBucketIndex;
+ hashp->hctl->freeBucketIndex = tmpIndex;
+
+ /* initialize each bucket to point to the one behind it */
+ for (i = 0; i < (BUCKET_ALLOC_INCR - 1); i++)
+ {
+ tmpBucket = GET_BUCKET(hashp, tmpIndex);
+ tmpIndex += bucketSize;
+ tmpBucket->next = tmpIndex;
+ }
+
+ /*
+ * the last bucket points to the old freelist head (which is probably
+ * invalid or we wouldnt be here)
+ */
+ tmpBucket->next = lastIndex;
+
+ return (1);
}
/* calculate the log base 2 of num */
int
my_log2(long num)
{
- int i = 1;
- int limit;
-
- for ( i = 0, limit = 1; limit < num; limit = 2 * limit, i++ );
- return (i);
+ int i = 1;
+ int limit;
+
+ for (i = 0, limit = 1; limit < num; limit = 2 * limit, i++);
+ return (i);
}
diff --git a/src/backend/utils/hash/hashfn.c b/src/backend/utils/hash/hashfn.c
index 3b2f0ec19a9..f7b8f3fde6e 100644
--- a/src/backend/utils/hash/hashfn.c
+++ b/src/backend/utils/hash/hashfn.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* hashfn.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/hash/hashfn.c,v 1.3 1997/08/19 21:35:33 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/hash/hashfn.c,v 1.4 1997/09/07 04:53:38 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,96 +24,97 @@
long
string_hash(char *key, int keysize)
{
- int h;
- register unsigned char *k = (unsigned char *) key;
-
- h = 0;
- /*
- * Convert string to integer
- */
- while (*k)
- h = h * PRIME1 ^ (*k++ - ' ');
- h %= PRIME2;
-
- return (h);
+ int h;
+ register unsigned char *k = (unsigned char *) key;
+
+ h = 0;
+
+ /*
+ * Convert string to integer
+ */
+ while (*k)
+ h = h * PRIME1 ^ (*k++ - ' ');
+ h %= PRIME2;
+
+ return (h);
}
long
tag_hash(int *key, int keysize)
{
- register long h = 0;
-
- /*
- * Convert tag to integer; Use four byte chunks in a "jump table"
- * to go a little faster. Currently the maximum keysize is 16
- * (mar 17 1992) I have put in cases for up to 24. Bigger than
- * this will resort to the old behavior of the for loop. (see the
- * default case).
- */
- switch (keysize)
+ register long h = 0;
+
+ /*
+ * Convert tag to integer; Use four byte chunks in a "jump table" to
+ * go a little faster. Currently the maximum keysize is 16 (mar 17
+ * 1992) I have put in cases for up to 24. Bigger than this will
+ * resort to the old behavior of the for loop. (see the default case).
+ */
+ switch (keysize)
{
- case 6*sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
- /* fall through */
-
- case 5*sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
- /* fall through */
-
- case 4*sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
- /* fall through */
-
- case 3*sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
- /* fall through */
-
- case 2*sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
- /* fall through */
-
+ case 6 * sizeof(int):
+ h = h * PRIME1 ^ (*key);
+ key++;
+ /* fall through */
+
+ case 5 * sizeof(int):
+ h = h * PRIME1 ^ (*key);
+ key++;
+ /* fall through */
+
+ case 4 * sizeof(int):
+ h = h * PRIME1 ^ (*key);
+ key++;
+ /* fall through */
+
+ case 3 * sizeof(int):
+ h = h * PRIME1 ^ (*key);
+ key++;
+ /* fall through */
+
+ case 2 * sizeof(int):
+ h = h * PRIME1 ^ (*key);
+ key++;
+ /* fall through */
+
case sizeof(int):
- h = h * PRIME1 ^ (*key);
- key++;
- break;
-
- default:
- for(; keysize > (sizeof(int)-1); keysize -= sizeof(int), key++)
h = h * PRIME1 ^ (*key);
- /*
- * now let's grab the last few bytes of the tag if the tag
- * has (size % 4) != 0 (which it sometimes will on a sun3).
- */
- if (keysize)
+ key++;
+ break;
+
+ default:
+ for (; keysize > (sizeof(int) - 1); keysize -= sizeof(int), key++)
+ h = h * PRIME1 ^ (*key);
+
+ /*
+ * now let's grab the last few bytes of the tag if the tag has
+ * (size % 4) != 0 (which it sometimes will on a sun3).
+ */
+ if (keysize)
{
- char *keytmp = (char *)key;
-
- switch (keysize)
+ char *keytmp = (char *) key;
+
+ switch (keysize)
{
case 3:
- h = h * PRIME1 ^ (*keytmp);
- keytmp++;
- /* fall through */
+ h = h * PRIME1 ^ (*keytmp);
+ keytmp++;
+ /* fall through */
case 2:
- h = h * PRIME1 ^ (*keytmp);
- keytmp++;
- /* fall through */
+ h = h * PRIME1 ^ (*keytmp);
+ keytmp++;
+ /* fall through */
case 1:
- h = h * PRIME1 ^ (*keytmp);
- break;
+ h = h * PRIME1 ^ (*keytmp);
+ break;
}
}
- break;
+ break;
}
-
- h %= PRIME2;
- return (h);
+
+ h %= PRIME2;
+ return (h);
}
/*
@@ -129,31 +130,42 @@ tag_hash(int *key, int keysize)
long
disk_hash(char *key)
{
- register int n = 0;
- register char *str = key;
- register int len = strlen(key);
- register int loop;
-
-#define HASHC n = *str++ + 65599 * n
-
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch(len & (8 - 1)) {
- case 0: do { /* All fall throughs */
- HASHC;
- case 7: HASHC;
- case 6: HASHC;
- case 5: HASHC;
- case 4: HASHC;
- case 3: HASHC;
- case 2: HASHC;
- case 1: HASHC;
- } while (--loop);
+ register int n = 0;
+ register char *str = key;
+ register int len = strlen(key);
+ register int loop;
+
+#define HASHC n = *str++ + 65599 * n
+
+ if (len > 0)
+ {
+ loop = (len + 8 - 1) >> 3;
+
+ switch (len & (8 - 1))
+ {
+ case 0:
+ do
+ { /* All fall throughs */
+ HASHC;
+ case 7:
+ HASHC;
+ case 6:
+ HASHC;
+ case 5:
+ HASHC;
+ case 4:
+ HASHC;
+ case 3:
+ HASHC;
+ case 2:
+ HASHC;
+ case 1:
+ HASHC;
+ } while (--loop);
+ }
+
}
-
- }
- return(n);
+ return (n);
}
-#endif
+#endif
diff --git a/src/backend/utils/init/enbl.c b/src/backend/utils/init/enbl.c
index 995ab9d9567..dfcf295e34c 100644
--- a/src/backend/utils/init/enbl.c
+++ b/src/backend/utils/init/enbl.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* enbl.c--
- * POSTGRES module enable and disable support code.
+ * POSTGRES module enable and disable support code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/Attic/enbl.c,v 1.1.1.1 1996/07/09 06:22:08 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/Attic/enbl.c,v 1.2 1997/09/07 04:53:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,15 +16,15 @@
/*
* BypassEnable --
- * False iff enable/disable processing is required given on and "*countP."
+ * False iff enable/disable processing is required given on and "*countP."
*
* Note:
- * As a side-effect, *countP is modified. It should be 0 initially.
+ * As a side-effect, *countP is modified. It should be 0 initially.
*
* Exceptions:
- * BadState if called with pointer to value 0 and false.
- * BadArg if "countP" is invalid pointer.
- * BadArg if on is invalid.
+ * BadState if called with pointer to value 0 and false.
+ * BadArg if "countP" is invalid pointer.
+ * BadArg if on is invalid.
*/
bool
BypassEnable(int *enableCountInOutP, bool on)
@@ -32,14 +32,15 @@ BypassEnable(int *enableCountInOutP, bool on)
AssertArg(PointerIsValid(enableCountInOutP));
AssertArg(BoolIsValid(on));
- if (on) {
+ if (on)
+ {
*enableCountInOutP += 1;
- return ((bool)(*enableCountInOutP >= 2));
+ return ((bool) (*enableCountInOutP >= 2));
}
AssertState(*enableCountInOutP >= 1);
*enableCountInOutP -= 1;
- return ((bool)(*enableCountInOutP >= 1));
+ return ((bool) (*enableCountInOutP >= 1));
}
diff --git a/src/backend/utils/init/findbe.c b/src/backend/utils/init/findbe.c
index 8718e3f91d6..5e6aa7412a6 100644
--- a/src/backend/utils/init/findbe.c
+++ b/src/backend/utils/init/findbe.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/Attic/findbe.c,v 1.5 1997/08/27 03:48:38 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/Attic/findbe.c,v 1.6 1997/09/07 04:53:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,213 +19,230 @@
#include <unistd.h>
#include "postgres.h"
-#include "miscadmin.h" /* for DebugLvl */
+#include "miscadmin.h" /* for DebugLvl */
-#ifndef S_IRUSR /* XXX [TRH] should be in a header */
-# define S_IRUSR S_IREAD
-# define S_IWUSR S_IWRITE
-# define S_IXUSR S_IEXEC
-# define S_IRGRP ((S_IRUSR)>>3)
-# define S_IWGRP ((S_IWUSR)>>3)
-# define S_IXGRP ((S_IXUSR)>>3)
-# define S_IROTH ((S_IRUSR)>>6)
-# define S_IWOTH ((S_IWUSR)>>6)
-# define S_IXOTH ((S_IXUSR)>>6)
+#ifndef S_IRUSR /* XXX [TRH] should be in a header */
+#define S_IRUSR S_IREAD
+#define S_IWUSR S_IWRITE
+#define S_IXUSR S_IEXEC
+#define S_IRGRP ((S_IRUSR)>>3)
+#define S_IWGRP ((S_IWUSR)>>3)
+#define S_IXGRP ((S_IXUSR)>>3)
+#define S_IROTH ((S_IRUSR)>>6)
+#define S_IWOTH ((S_IWUSR)>>6)
+#define S_IXOTH ((S_IXUSR)>>6)
#endif
/*
* ValidateBackend -- validate "path" as a POSTGRES executable file
*
* returns 0 if the file is found and no error is encountered.
- * -1 if the regular file "path" does not exist or cannot be executed.
- * -2 if the file is otherwise valid but cannot be read.
+ * -1 if the regular file "path" does not exist or cannot be executed.
+ * -2 if the file is otherwise valid but cannot be read.
*/
int
ValidateBackend(char *path)
{
- struct stat buf;
- uid_t euid;
- struct group *gp;
- struct passwd *pwp;
- int i;
- int is_r = 0;
- int is_x = 0;
- int in_grp = 0;
-
- /*
- * Ensure that the file exists and is a regular file.
- *
- * XXX if you have a broken system where stat() looks at the symlink
- * instead of the underlying file, you lose.
- */
- if (strlen(path) >= MAXPGPATH) {
- if (DebugLvl > 1)
- fprintf(stderr, "ValidateBackend: pathname \"%s\" is too long\n",
- path);
- return(-1);
- }
+ struct stat buf;
+ uid_t euid;
+ struct group *gp;
+ struct passwd *pwp;
+ int i;
+ int is_r = 0;
+ int is_x = 0;
+ int in_grp = 0;
- if (stat(path, &buf) < 0) {
- if (DebugLvl > 1)
- fprintf(stderr, "ValidateBackend: can't stat \"%s\"\n",
- path);
- return(-1);
- }
- if (!(buf.st_mode & S_IFREG)) {
- if (DebugLvl > 1)
- fprintf(stderr, "ValidateBackend: \"%s\" is not a regular file\n",
- path);
- return(-1);
- }
-
- /*
- * Ensure that we are using an authorized backend.
- *
- * XXX I'm open to suggestions here. I would like to enforce ownership
- * of backends by user "postgres" but people seem to like to run
- * as users other than "postgres"...
- */
-
- /*
- * Ensure that the file is both executable and readable (required for
- * dynamic loading).
- *
- * We use the effective uid here because the backend will not have
- * executed setuid() by the time it calls this routine.
- */
- euid = geteuid();
- if (euid == buf.st_uid) {
- is_r = buf.st_mode & S_IRUSR;
- is_x = buf.st_mode & S_IXUSR;
- if (DebugLvl > 1 && !(is_r && is_x))
- fprintf(stderr, "ValidateBackend: \"%s\" is not user read/execute\n",
- path);
- return(is_x ? (is_r ? 0 : -2) : -1);
- }
- pwp = getpwuid(euid);
- if (pwp) {
- if (pwp->pw_gid == buf.st_gid) {
- ++in_grp;
- } else if (pwp->pw_name &&
- (gp = getgrgid(buf.st_gid))) {
- for (i = 0; gp->gr_mem[i]; ++i) {
- if (!strcmp(gp->gr_mem[i], pwp->pw_name)) {
- ++in_grp;
- break;
- }
- }
+ /*
+ * Ensure that the file exists and is a regular file.
+ *
+ * XXX if you have a broken system where stat() looks at the symlink
+ * instead of the underlying file, you lose.
+ */
+ if (strlen(path) >= MAXPGPATH)
+ {
+ if (DebugLvl > 1)
+ fprintf(stderr, "ValidateBackend: pathname \"%s\" is too long\n",
+ path);
+ return (-1);
}
- if (in_grp) {
- is_r = buf.st_mode & S_IRGRP;
- is_x = buf.st_mode & S_IXGRP;
- if (DebugLvl > 1 && !(is_r && is_x))
- fprintf(stderr, "ValidateBackend: \"%s\" is not group read/execute\n",
- path);
- return(is_x ? (is_r ? 0 : -2) : -1);
+
+ if (stat(path, &buf) < 0)
+ {
+ if (DebugLvl > 1)
+ fprintf(stderr, "ValidateBackend: can't stat \"%s\"\n",
+ path);
+ return (-1);
}
- }
- is_r = buf.st_mode & S_IROTH;
- is_x = buf.st_mode & S_IXOTH;
- if (DebugLvl > 1 && !(is_r && is_x))
- fprintf(stderr, "ValidateBackend: \"%s\" is not other read/execute\n",
- path);
- return(is_x ? (is_r ? 0 : -2) : -1);
+ if (!(buf.st_mode & S_IFREG))
+ {
+ if (DebugLvl > 1)
+ fprintf(stderr, "ValidateBackend: \"%s\" is not a regular file\n",
+ path);
+ return (-1);
+ }
+
+ /*
+ * Ensure that we are using an authorized backend.
+ *
+ * XXX I'm open to suggestions here. I would like to enforce ownership
+ * of backends by user "postgres" but people seem to like to run as
+ * users other than "postgres"...
+ */
+
+ /*
+ * Ensure that the file is both executable and readable (required for
+ * dynamic loading).
+ *
+ * We use the effective uid here because the backend will not have
+ * executed setuid() by the time it calls this routine.
+ */
+ euid = geteuid();
+ if (euid == buf.st_uid)
+ {
+ is_r = buf.st_mode & S_IRUSR;
+ is_x = buf.st_mode & S_IXUSR;
+ if (DebugLvl > 1 && !(is_r && is_x))
+ fprintf(stderr, "ValidateBackend: \"%s\" is not user read/execute\n",
+ path);
+ return (is_x ? (is_r ? 0 : -2) : -1);
+ }
+ pwp = getpwuid(euid);
+ if (pwp)
+ {
+ if (pwp->pw_gid == buf.st_gid)
+ {
+ ++in_grp;
+ }
+ else if (pwp->pw_name &&
+ (gp = getgrgid(buf.st_gid)))
+ {
+ for (i = 0; gp->gr_mem[i]; ++i)
+ {
+ if (!strcmp(gp->gr_mem[i], pwp->pw_name))
+ {
+ ++in_grp;
+ break;
+ }
+ }
+ }
+ if (in_grp)
+ {
+ is_r = buf.st_mode & S_IRGRP;
+ is_x = buf.st_mode & S_IXGRP;
+ if (DebugLvl > 1 && !(is_r && is_x))
+ fprintf(stderr, "ValidateBackend: \"%s\" is not group read/execute\n",
+ path);
+ return (is_x ? (is_r ? 0 : -2) : -1);
+ }
+ }
+ is_r = buf.st_mode & S_IROTH;
+ is_x = buf.st_mode & S_IXOTH;
+ if (DebugLvl > 1 && !(is_r && is_x))
+ fprintf(stderr, "ValidateBackend: \"%s\" is not other read/execute\n",
+ path);
+ return (is_x ? (is_r ? 0 : -2) : -1);
}
/*
* FindBackend -- find an absolute path to a valid backend executable
*
* The reason we have to work so hard to find an absolute path is that
- * we need to feed the backend server the location of its actual
+ * we need to feed the backend server the location of its actual
* executable file -- otherwise, we can't do dynamic loading.
*/
int
FindBackend(char *backend, char *argv0)
{
- char buf[MAXPGPATH + 2];
- char *p;
- char *path, *startp, *endp;
- int pathlen;
-
- /*
- * for the postmaster:
- * First try: use the backend that's located in the same directory
- * as the postmaster, if it was invoked with an explicit path.
- * Presumably the user used an explicit path because it wasn't in
- * PATH, and we don't want to use incompatible executables.
- *
- * This has the neat property that it works for installed binaries,
- * old source trees (obj/support/post{master,gres}) and new marc
- * source trees (obj/post{master,gres}) because they all put the
- * two binaries in the same place.
- *
- * for the backend server:
- * First try: if we're given some kind of path, use it (making sure
- * that a relative path is made absolute before returning it).
- */
- if (argv0 && (p = strrchr(argv0, '/')) && *++p) {
- if (*argv0 == '/' || !getcwd(buf, MAXPGPATH))
- buf[0] = '\0';
- else
- strcat(buf, "/");
- strcat(buf, argv0);
- p = strrchr(buf, '/');
- strcpy(++p, "postgres");
- if (!ValidateBackend(buf)) {
- strncpy(backend, buf, MAXPGPATH);
- if (DebugLvl)
- fprintf(stderr, "FindBackend: found \"%s\" using argv[0]\n",
- backend);
- return(0);
+ char buf[MAXPGPATH + 2];
+ char *p;
+ char *path,
+ *startp,
+ *endp;
+ int pathlen;
+
+ /*
+ * for the postmaster: First try: use the backend that's located in
+ * the same directory as the postmaster, if it was invoked with an
+ * explicit path. Presumably the user used an explicit path because it
+ * wasn't in PATH, and we don't want to use incompatible executables.
+ *
+ * This has the neat property that it works for installed binaries, old
+ * source trees (obj/support/post{master,gres}) and new marc source
+ * trees (obj/post{master,gres}) because they all put the two binaries
+ * in the same place.
+ *
+ * for the backend server: First try: if we're given some kind of path,
+ * use it (making sure that a relative path is made absolute before
+ * returning it).
+ */
+ if (argv0 && (p = strrchr(argv0, '/')) && *++p)
+ {
+ if (*argv0 == '/' || !getcwd(buf, MAXPGPATH))
+ buf[0] = '\0';
+ else
+ strcat(buf, "/");
+ strcat(buf, argv0);
+ p = strrchr(buf, '/');
+ strcpy(++p, "postgres");
+ if (!ValidateBackend(buf))
+ {
+ strncpy(backend, buf, MAXPGPATH);
+ if (DebugLvl)
+ fprintf(stderr, "FindBackend: found \"%s\" using argv[0]\n",
+ backend);
+ return (0);
+ }
+ fprintf(stderr, "FindBackend: invalid backend \"%s\"\n",
+ buf);
+ return (-1);
}
- fprintf(stderr, "FindBackend: invalid backend \"%s\"\n",
- buf);
- return(-1);
- }
-
- /*
- * Second try: since no explicit path was supplied, the user must
- * have been relying on PATH. We'll use the same PATH.
- */
- if ((p = getenv("PATH")) && *p) {
- if (DebugLvl)
- fprintf(stderr, "FindBackend: searching PATH ...\n");
- pathlen = strlen(p);
- path = malloc(pathlen + 1);
- strcpy(path, p);
- for (startp = path, endp = strchr(path, ':');
- startp && *startp;
- startp = endp + 1, endp = strchr(startp, ':')) {
- if (startp == endp) /* it's a "::" */
- continue;
- if (endp)
- *endp = '\0';
- if (*startp == '/' || !getcwd(buf, MAXPGPATH))
- buf[0] = '\0';
- strcat(buf, startp);
- strcat(buf, "/postgres");
- switch (ValidateBackend(buf)) {
- case 0: /* found ok */
- strncpy(backend, buf, MAXPGPATH);
+
+ /*
+ * Second try: since no explicit path was supplied, the user must have
+ * been relying on PATH. We'll use the same PATH.
+ */
+ if ((p = getenv("PATH")) && *p)
+ {
if (DebugLvl)
- fprintf(stderr, "FindBackend: found \"%s\" using PATH\n",
- backend);
- free(path);
- return(0);
- case -1: /* wasn't even a candidate, keep looking */
- break;
- case -2: /* found but disqualified */
- fprintf(stderr, "FindBackend: could not read backend \"%s\"\n",
- buf);
+ fprintf(stderr, "FindBackend: searching PATH ...\n");
+ pathlen = strlen(p);
+ path = malloc(pathlen + 1);
+ strcpy(path, p);
+ for (startp = path, endp = strchr(path, ':');
+ startp && *startp;
+ startp = endp + 1, endp = strchr(startp, ':'))
+ {
+ if (startp == endp) /* it's a "::" */
+ continue;
+ if (endp)
+ *endp = '\0';
+ if (*startp == '/' || !getcwd(buf, MAXPGPATH))
+ buf[0] = '\0';
+ strcat(buf, startp);
+ strcat(buf, "/postgres");
+ switch (ValidateBackend(buf))
+ {
+ case 0: /* found ok */
+ strncpy(backend, buf, MAXPGPATH);
+ if (DebugLvl)
+ fprintf(stderr, "FindBackend: found \"%s\" using PATH\n",
+ backend);
+ free(path);
+ return (0);
+ case -1: /* wasn't even a candidate, keep looking */
+ break;
+ case -2: /* found but disqualified */
+ fprintf(stderr, "FindBackend: could not read backend \"%s\"\n",
+ buf);
+ free(path);
+ return (-1);
+ }
+ if (!endp) /* last one */
+ break;
+ }
free(path);
- return(-1);
- }
- if (!endp) /* last one */
- break;
}
- free(path);
- }
- fprintf(stderr, "FindBackend: could not find a backend to execute...\n");
- return(-1);
+ fprintf(stderr, "FindBackend: could not find a backend to execute...\n");
+ return (-1);
}
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 053bcbb8775..2ed0c83e0b2 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* globals.c--
- * global variable declarations
+ * global variable declarations
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.10 1997/08/14 16:11:21 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.11 1997/09/07 04:53:48 momjian Exp $
*
* NOTES
- * Globals used all over the place should be declared here and not
- * in other modules.
+ * Globals used all over the place should be declared here and not
+ * in other modules.
*
*-------------------------------------------------------------------------
*/
@@ -24,7 +24,7 @@
#include <unistd.h>
#include "postgres.h"
-#include "miscadmin.h" /* where the declarations go */
+#include "miscadmin.h" /* where the declarations go */
#include <storage/backendid.h>
#include "access/heapam.h"
@@ -36,83 +36,86 @@
#include "catalog/catname.h"
-int Portfd = -1;
-int Noversion = 0;
-int Quiet = 1;
+int Portfd = -1;
+int Noversion = 0;
+int Quiet = 1;
-int MasterPid;
-char *DataDir;
- /* The PGDATA directory user says to use, or defaults to via environment
- variable. NULL if no option given and no environment variable set
+int MasterPid;
+char *DataDir;
+
+ /*
+ * The PGDATA directory user says to use, or defaults to via environment
+ * variable. NULL if no option given and no environment variable set
*/
-Relation reldesc; /* current relation descriptor */
-
-char OutputFileName[MAXPGPATH] = "";
+Relation reldesc; /* current relation descriptor */
+
+char OutputFileName[MAXPGPATH] = "";
-BackendId MyBackendId;
-BackendTag MyBackendTag;
+BackendId MyBackendId;
+BackendTag MyBackendTag;
-char *UserName = NULL;
-char *DatabaseName = NULL;
-char *DatabasePath = NULL;
+char *UserName = NULL;
+char *DatabaseName = NULL;
+char *DatabasePath = NULL;
-bool MyDatabaseIdIsInitialized = false;
-Oid MyDatabaseId = InvalidOid;
-bool TransactionInitWasProcessed = false;
+bool MyDatabaseIdIsInitialized = false;
+Oid MyDatabaseId = InvalidOid;
+bool TransactionInitWasProcessed = false;
-bool IsUnderPostmaster = false;
-bool IsPostmaster = false;
+bool IsUnderPostmaster = false;
+bool IsPostmaster = false;
-short DebugLvl = 0;
+short DebugLvl = 0;
-int DateStyle = USE_POSTGRES_DATES;
-bool EuroDates = false;
-bool HasCTZSet = false;
-bool CDayLight = false;
-int CTimeZone = 0;
-char CTZName[MAXTZLEN+1] = "";
+int DateStyle = USE_POSTGRES_DATES;
+bool EuroDates = false;
+bool HasCTZSet = false;
+bool CDayLight = false;
+int CTimeZone = 0;
+char CTZName[MAXTZLEN + 1] = "";
-char DateFormat[20] = "%d-%m-%Y"; /* mjl: sizes! or better malloc? XXX */
-char FloatFormat[20] = "%f";
+char DateFormat[20] = "%d-%m-%Y"; /* mjl: sizes! or better
+ * malloc? XXX */
+char FloatFormat[20] = "%f";
-int fsyncOff = 0;
-int SortMem = 512;
+int fsyncOff = 0;
+int SortMem = 512;
-char *IndexedCatalogNames[] = {
- AttributeRelationName,
- ProcedureRelationName,
- TypeRelationName,
- RelationRelationName,
- 0
+char *IndexedCatalogNames[] = {
+ AttributeRelationName,
+ ProcedureRelationName,
+ TypeRelationName,
+ RelationRelationName,
+ 0
};
/* ----------------
* we just do a linear search now so there's no requirement that the list
- * be ordered. The list is so small it shouldn't make much difference.
+ * be ordered. The list is so small it shouldn't make much difference.
* make sure the list is null-terminated
- * - jolly 8/19/95
- *
+ * - jolly 8/19/95
+ *
* OLD COMMENT
- * WARNING WARNING WARNING WARNING WARNING WARNING
+ * WARNING WARNING WARNING WARNING WARNING WARNING
*
- * keep SharedSystemRelationNames[] in SORTED order! A binary search
- * is done on it in catalog.c!
+ * keep SharedSystemRelationNames[] in SORTED order! A binary search
+ * is done on it in catalog.c!
*
- * XXX this is a serious hack which should be fixed -cim 1/26/90
+ * XXX this is a serious hack which should be fixed -cim 1/26/90
* ----------------
*/
-char *SharedSystemRelationNames[] = {
- DatabaseRelationName,
- DefaultsRelationName,
- DemonRelationName,
- GroupRelationName,
- HostsRelationName,
- LogRelationName,
- MagicRelationName,
- ServerRelationName,
- TimeRelationName,
- UserRelationName,
- VariableRelationName,
- 0
+char *SharedSystemRelationNames[] = {
+ DatabaseRelationName,
+ DefaultsRelationName,
+ DemonRelationName,
+ GroupRelationName,
+ HostsRelationName,
+ LogRelationName,
+ MagicRelationName,
+ ServerRelationName,
+ TimeRelationName,
+ UserRelationName,
+ VariableRelationName,
+ 0
};
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 2fe002bd914..71efb80d120 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -1,55 +1,55 @@
/*-------------------------------------------------------------------------
*
* miscinit.c--
- * miscellanious initialization support stuff
+ * miscellanious initialization support stuff
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.6 1997/08/19 21:35:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.7 1997/09/07 04:53:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <string.h>
-#include <sys/param.h> /* for MAXPATHLEN */
+#include <sys/param.h> /* for MAXPATHLEN */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <stdio.h>
#include <unistd.h>
-#include <grp.h> /* for getgrgid */
-#include <pwd.h> /* for getpwuid */
+#include <grp.h> /* for getgrgid */
+#include <pwd.h> /* for getpwuid */
#include "postgres.h"
-#include "utils/portal.h" /* for EnablePortalManager, etc. */
-#include "utils/exc.h" /* for EnableExceptionHandling, etc. */
-#include "utils/mcxt.h" /* for EnableMemoryContext, etc. */
+#include "utils/portal.h" /* for EnablePortalManager, etc. */
+#include "utils/exc.h" /* for EnableExceptionHandling, etc. */
+#include "utils/mcxt.h" /* for EnableMemoryContext, etc. */
#include "utils/elog.h"
#include "utils/builtins.h"
-#include "miscadmin.h" /* where the declarations go */
+#include "miscadmin.h" /* where the declarations go */
#include "catalog/catname.h"
#include "catalog/pg_user.h"
#include "catalog/pg_proc.h"
#include "utils/syscache.h"
-#include "storage/fd.h" /* for O_ */
+#include "storage/fd.h" /* for O_ */
/*
* EnableAbortEnvVarName --
- * Enables system abort iff set to a non-empty string in environment.
+ * Enables system abort iff set to a non-empty string in environment.
*/
#define EnableAbortEnvVarName "POSTGRESABORT"
-extern char *getenv(const char *name); /* XXX STDLIB */
+extern char *getenv(const char *name); /* XXX STDLIB */
-/* from globals.c */
-extern char *DatabaseName;
-extern char *UserName;
-extern char *DatabasePath;
+/* from globals.c */
+extern char *DatabaseName;
+extern char *UserName;
+extern char *DatabasePath;
/*
@@ -59,282 +59,286 @@ extern char *DatabasePath;
#define USE_ENVIRONMENT
/* ----------------------------------------------------------------
- * some of the 19 ways to leave postgres
+ * some of the 19 ways to leave postgres
* ----------------------------------------------------------------
*/
/*
* ExitPostgres --
- * Exit POSTGRES with a status code.
+ * Exit POSTGRES with a status code.
*
* Note:
- * This function never returns.
- * ...
+ * This function never returns.
+ * ...
*
* Side effects:
- * ...
+ * ...
*
* Exceptions:
- * none
+ * none
*/
void
ExitPostgres(ExitStatus status)
{
#ifdef __SABER__
- saber_stop();
+ saber_stop();
#endif
- exitpg(status);
+ exitpg(status);
}
/*
* AbortPostgres --
- * Abort POSTGRES dumping core.
+ * Abort POSTGRES dumping core.
*
* Note:
- * This function never returns.
- * ...
+ * This function never returns.
+ * ...
*
* Side effects:
- * Core is dumped iff EnableAbortEnvVarName is set to a non-empty string.
- * ...
+ * Core is dumped iff EnableAbortEnvVarName is set to a non-empty string.
+ * ...
*
* Exceptions:
- * none
+ * none
*/
#ifdef NOT_USED
void
AbortPostgres()
{
- char *abortValue = getenv(EnableAbortEnvVarName);
-
+ char *abortValue = getenv(EnableAbortEnvVarName);
+
#ifdef __SABER__
- saber_stop();
+ saber_stop();
#endif
-
- if (PointerIsValid(abortValue) && abortValue[0] != '\0')
- abort();
- else
- exitpg(FatalExitStatus);
+
+ if (PointerIsValid(abortValue) && abortValue[0] != '\0')
+ abort();
+ else
+ exitpg(FatalExitStatus);
}
+
#endif
/* ----------------
- * StatusBackendExit
+ * StatusBackendExit
* ----------------
*/
void
StatusBackendExit(int status)
{
- /* someday, do some real cleanup and then call the LISP exit */
- /* someday, call StatusPostmasterExit if running without postmaster */
- exitpg(status);
+ /* someday, do some real cleanup and then call the LISP exit */
+ /* someday, call StatusPostmasterExit if running without postmaster */
+ exitpg(status);
}
/* ----------------
- * StatusPostmasterExit
+ * StatusPostmasterExit
* ----------------
*/
void
StatusPostmasterExit(int status)
{
- /* someday, do some real cleanup and then call the LISP exit */
- exitpg(status);
+ /* someday, do some real cleanup and then call the LISP exit */
+ exitpg(status);
}
/* ----------------------------------------------------------------
- * processing mode support stuff (used to be in pmod.c)
+ * processing mode support stuff (used to be in pmod.c)
* ----------------------------------------------------------------
*/
-static ProcessingMode Mode = NoProcessing;
+static ProcessingMode Mode = NoProcessing;
/*
* IsNoProcessingMode --
- * True iff processing mode is NoProcessing.
+ * True iff processing mode is NoProcessing.
*/
bool
IsNoProcessingMode()
{
- return ((bool)(Mode == NoProcessing));
+ return ((bool) (Mode == NoProcessing));
}
/*
* IsBootstrapProcessingMode --
- * True iff processing mode is BootstrapProcessing.
+ * True iff processing mode is BootstrapProcessing.
*/
bool
IsBootstrapProcessingMode()
{
- return ((bool)(Mode == BootstrapProcessing));
+ return ((bool) (Mode == BootstrapProcessing));
}
/*
* IsInitProcessingMode --
- * True iff processing mode is InitProcessing.
+ * True iff processing mode is InitProcessing.
*/
bool
IsInitProcessingMode()
{
- return ((bool)(Mode == InitProcessing));
+ return ((bool) (Mode == InitProcessing));
}
/*
* IsNormalProcessingMode --
- * True iff processing mode is NormalProcessing.
+ * True iff processing mode is NormalProcessing.
*/
bool
IsNormalProcessingMode()
{
- return ((bool)(Mode == NormalProcessing));
+ return ((bool) (Mode == NormalProcessing));
}
/*
* SetProcessingMode --
- * Sets mode of processing as specified.
+ * Sets mode of processing as specified.
*
* Exceptions:
- * BadArg if called with invalid mode.
+ * BadArg if called with invalid mode.
*
* Note:
- * Mode is NoProcessing before the first time this is called.
+ * Mode is NoProcessing before the first time this is called.
*/
void
SetProcessingMode(ProcessingMode mode)
{
- AssertArg(mode == NoProcessing || mode == BootstrapProcessing ||
- mode == InitProcessing || mode == NormalProcessing);
-
- Mode = mode;
+ AssertArg(mode == NoProcessing || mode == BootstrapProcessing ||
+ mode == InitProcessing || mode == NormalProcessing);
+
+ Mode = mode;
}
ProcessingMode
GetProcessingMode()
{
- return (Mode);
+ return (Mode);
}
/* ----------------------------------------------------------------
- * database path / name support stuff
+ * database path / name support stuff
* ----------------------------------------------------------------
*/
/*
* GetDatabasePath --
- * Returns path to database.
+ * Returns path to database.
*
*/
-char*
+char *
GetDatabasePath()
{
- return DatabasePath;
+ return DatabasePath;
}
/*
* GetDatabaseName --
- * Returns name of database.
+ * Returns name of database.
*/
-char*
+char *
GetDatabaseName()
{
- return DatabaseName;
+ return DatabaseName;
}
void
SetDatabasePath(char *path)
{
- /* use malloc since this is done before memory contexts are set up */
- if (DatabasePath)
- free(DatabasePath);
- DatabasePath = malloc(strlen(path)+1);
- strcpy(DatabasePath, path);
+ /* use malloc since this is done before memory contexts are set up */
+ if (DatabasePath)
+ free(DatabasePath);
+ DatabasePath = malloc(strlen(path) + 1);
+ strcpy(DatabasePath, path);
}
void
SetDatabaseName(char *name)
{
- if (DatabaseName)
- free (DatabaseName);
- DatabaseName = malloc(strlen(name)+1);
- strcpy(DatabaseName, name);
+ if (DatabaseName)
+ free(DatabaseName);
+ DatabaseName = malloc(strlen(name) + 1);
+ strcpy(DatabaseName, name);
}
/* ----------------
- * GetPgUserName and SetPgUserName
+ * GetPgUserName and SetPgUserName
*
- * SetPgUserName must be called before InitPostgres, since the setuid()
- * is done there.
+ * SetPgUserName must be called before InitPostgres, since the setuid()
+ * is done there.
*
- * Replace GetPgUserName() with a lower-case version
- * to allow use in new case-insensitive SQL (referenced
- * in pg_proc.h). Define GetPgUserName() as a macro - tgl 97/04/26
+ * Replace GetPgUserName() with a lower-case version
+ * to allow use in new case-insensitive SQL (referenced
+ * in pg_proc.h). Define GetPgUserName() as a macro - tgl 97/04/26
* ----------------
*/
-char*
+char *
getpgusername()
{
- return UserName;
+ return UserName;
}
void
SetPgUserName()
{
#ifndef NO_SECURITY
- char *p;
- struct passwd *pw;
-
- if (IsUnderPostmaster) {
- /* use the (possibly) authenticated name that's provided */
- if (!(p = getenv("PG_USER")))
- elog(FATAL, "SetPgUserName: PG_USER environment variable unset");
- } else {
- /* setuid() has not yet been done, see above comment */
- if (!(pw = getpwuid(geteuid())))
- elog(FATAL, "SetPgUserName: no entry in passwd file");
- p = pw->pw_name;
- }
- if (UserName)
- free(UserName);
- UserName = malloc(strlen(p)+1);
- strcpy(UserName, p);
-#endif /* NO_SECURITY */
+ char *p;
+ struct passwd *pw;
+
+ if (IsUnderPostmaster)
+ {
+ /* use the (possibly) authenticated name that's provided */
+ if (!(p = getenv("PG_USER")))
+ elog(FATAL, "SetPgUserName: PG_USER environment variable unset");
+ }
+ else
+ {
+ /* setuid() has not yet been done, see above comment */
+ if (!(pw = getpwuid(geteuid())))
+ elog(FATAL, "SetPgUserName: no entry in passwd file");
+ p = pw->pw_name;
+ }
+ if (UserName)
+ free(UserName);
+ UserName = malloc(strlen(p) + 1);
+ strcpy(UserName, p);
+#endif /* NO_SECURITY */
}
/* ----------------------------------------------------------------
- * GetUserId and SetUserId
+ * GetUserId and SetUserId
* ----------------------------------------------------------------
*/
-static Oid UserId = InvalidOid;
+static Oid UserId = InvalidOid;
Oid
GetUserId()
{
- Assert(OidIsValid(UserId));
- return(UserId);
+ Assert(OidIsValid(UserId));
+ return (UserId);
}
void
SetUserId()
{
- HeapTuple userTup;
- char *userName;
-
- Assert(!OidIsValid(UserId)); /* only once */
-
- /*
- * Don't do scans if we're bootstrapping, none of the system
- * catalogs exist yet, and they should be owned by postgres
- * anyway.
- */
- if (IsBootstrapProcessingMode()) {
- UserId = geteuid();
- return;
- }
-
- userName = GetPgUserName();
- userTup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName),
- 0,0,0);
- if (!HeapTupleIsValid(userTup))
- elog(FATAL, "SetUserId: user \"%s\" is not in \"%s\"",
- userName,
- UserRelationName);
- UserId = (Oid) ((Form_pg_user) GETSTRUCT(userTup))->usesysid;
+ HeapTuple userTup;
+ char *userName;
+
+ Assert(!OidIsValid(UserId));/* only once */
+
+ /*
+ * Don't do scans if we're bootstrapping, none of the system catalogs
+ * exist yet, and they should be owned by postgres anyway.
+ */
+ if (IsBootstrapProcessingMode())
+ {
+ UserId = geteuid();
+ return;
+ }
+
+ userName = GetPgUserName();
+ userTup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(userTup))
+ elog(FATAL, "SetUserId: user \"%s\" is not in \"%s\"",
+ userName,
+ UserRelationName);
+ UserId = (Oid) ((Form_pg_user) GETSTRUCT(userTup))->usesysid;
}
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index fb21e51a492..5a8a1a83d4d 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -1,28 +1,28 @@
/*-------------------------------------------------------------------------
*
* postinit.c--
- * postgres initialization utilities
+ * postgres initialization utilities
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.12 1997/08/27 03:48:39 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.13 1997/09/07 04:53:50 momjian Exp $
*
* NOTES
- * InitPostgres() is the function called from PostgresMain
- * which does all non-trival initialization, mainly by calling
- * all the other initialization functions. InitPostgres()
- * is only used within the "postgres" backend and so that routine
- * is in tcop/postgres.c InitPostgres() is needed in cinterface.a
- * because things like the bootstrap backend program need it. Hence
- * you find that in this file...
+ * InitPostgres() is the function called from PostgresMain
+ * which does all non-trival initialization, mainly by calling
+ * all the other initialization functions. InitPostgres()
+ * is only used within the "postgres" backend and so that routine
+ * is in tcop/postgres.c InitPostgres() is needed in cinterface.a
+ * because things like the bootstrap backend program need it. Hence
+ * you find that in this file...
*
- * If you feel the need to add more initialization code, it should be
- * done in InitPostgres() or someplace lower. Do not start
- * putting stuff in PostgresMain - if you do then someone
- * will have to clean it up later, and it's not going to be me!
- * -cim 10/3/90
+ * If you feel the need to add more initialization code, it should be
+ * done in InitPostgres() or someplace lower. Do not start
+ * putting stuff in PostgresMain - if you do then someone
+ * will have to clean it up later, and it's not going to be me!
+ * -cim 10/3/90
*
*-------------------------------------------------------------------------
*/
@@ -47,22 +47,22 @@
#include "access/heapam.h"
#include "access/xact.h"
#include "storage/bufmgr.h"
-#include "access/transam.h" /* XXX dependency problem */
+#include "access/transam.h" /* XXX dependency problem */
#include "utils/tqual.h"
#include "utils/syscache.h"
-#include "storage/bufpage.h" /* for page layout, for InitMyDatabaseId() */
+#include "storage/bufpage.h" /* for page layout, for InitMyDatabaseId() */
#include "storage/sinval.h"
#include "storage/sinvaladt.h"
#include "storage/lmgr.h"
-#include "miscadmin.h" /* for global decls */
-#include "utils/portal.h" /* for EnablePortalManager, etc. */
+#include "miscadmin.h" /* for global decls */
+#include "utils/portal.h" /* for EnablePortalManager, etc. */
-#include "utils/exc.h" /* for EnableExceptionHandling, etc. */
-#include "fmgr.h" /* for EnableDynamicFunctionManager, etc. */
+#include "utils/exc.h" /* for EnableExceptionHandling, etc. */
+#include "fmgr.h" /* for EnableDynamicFunctionManager, etc. */
#include "utils/elog.h"
#include "utils/palloc.h"
-#include "utils/mcxt.h" /* for EnableMemoryContext, etc. */
+#include "utils/mcxt.h" /* for EnableMemoryContext, etc. */
#include "catalog/catname.h"
#include "catalog/pg_database.h"
@@ -70,584 +70,612 @@
#include "port-protos.h"
#include "libpq/libpq-be.h"
-static void InitCommunication(void);
-static void InitMyDatabaseId(void);
-static void InitStdio(void);
-static void InitUserid(void);
+static void InitCommunication(void);
+static void InitMyDatabaseId(void);
+static void InitStdio(void);
+static void InitUserid(void);
-static IPCKey PostgresIpcKey;
+static IPCKey PostgresIpcKey;
/* ----------------------------------------------------------------
- * InitPostgres support
+ * InitPostgres support
* ----------------------------------------------------------------
*/
/* --------------------------------
- * InitMyDatabaseId() -- Find and record the OID of the database we are
- * to open.
+ * InitMyDatabaseId() -- Find and record the OID of the database we are
+ * to open.
*
- * The database's oid forms half of the unique key for the system
- * caches and lock tables. We therefore want it initialized before
- * we open any relations, since opening relations puts things in the
- * cache. To get around this problem, this code opens and scans the
- * pg_database relation by hand.
+ * The database's oid forms half of the unique key for the system
+ * caches and lock tables. We therefore want it initialized before
+ * we open any relations, since opening relations puts things in the
+ * cache. To get around this problem, this code opens and scans the
+ * pg_database relation by hand.
*
- * This algorithm relies on the fact that first attribute in the
- * pg_database relation schema is the database name. It also knows
- * about the internal format of tuples on disk and the length of
- * the datname attribute. It knows the location of the pg_database
- * file.
+ * This algorithm relies on the fact that first attribute in the
+ * pg_database relation schema is the database name. It also knows
+ * about the internal format of tuples on disk and the length of
+ * the datname attribute. It knows the location of the pg_database
+ * file.
*
- * This code is called from InitDatabase(), after we chdir() to the
- * database directory but before we open any relations.
+ * This code is called from InitDatabase(), after we chdir() to the
+ * database directory but before we open any relations.
* --------------------------------
*/
static void
InitMyDatabaseId()
{
- int dbfd;
- int fileflags;
- int nbytes;
- int max, i;
- HeapTuple tup;
- Page pg;
- PageHeader ph;
- char *dbfname;
- Form_pg_database tup_db;
-
- /*
- * At bootstrap time, we don't need to check the oid of the database
- * in use, since we're not using shared memory. This is lucky, since
- * the database may not be in the tables yet.
- */
-
- if (IsBootstrapProcessingMode()) {
- LockDisable(true);
- return;
- }
-
- dbfname = (char *) palloc(strlen(DataDir) + strlen("pg_database") + 2);
- sprintf(dbfname, "%s%cpg_database", DataDir, SEP_CHAR);
- fileflags = O_RDONLY;
-
- if ((dbfd = open(dbfname, O_RDONLY, 0)) < 0)
- elog(FATAL, "Cannot open %s", dbfname);
-
- pfree(dbfname);
-
- /* ----------------
- * read and examine every page in pg_database
- *
- * Raw I/O! Read those tuples the hard way! Yow!
- *
- * Why don't we use the access methods or move this code
- * someplace else? This is really pg_database schema dependent
- * code. Perhaps it should go in lib/catalog/pg_database?
- * -cim 10/3/90
- *
- * mao replies 4 apr 91: yeah, maybe this should be moved to
- * lib/catalog. however, we CANNOT use the access methods since
- * those use the buffer cache, which uses the relation cache, which
- * requires that the dbid be set, which is what we're trying to do
- * here.
- * ----------------
- */
- pg = (Page) palloc(BLCKSZ);
- ph = (PageHeader) pg;
-
- while ((nbytes = read(dbfd, pg, BLCKSZ)) == BLCKSZ) {
- max = PageGetMaxOffsetNumber(pg);
-
- /* look at each tuple on the page */
- for (i = 0; i <= max; i++) {
- int offset;
-
- /* if it's a freed tuple, ignore it */
- if (!(ph->pd_linp[i].lp_flags & LP_USED))
- continue;
-
- /* get a pointer to the tuple itself */
- offset = (int) ph->pd_linp[i].lp_off;
- tup = (HeapTuple) (((char *) pg) + offset);
-
- /*
- * if the tuple has been deleted (the database was destroyed),
- * skip this tuple. XXX warning, will robinson: violation of
- * transaction semantics happens right here. we should check
- * to be sure that the xact that deleted this tuple actually
- * committed. only way to do this at init time is to paw over
- * the log relation by hand, too. let's be optimistic.
- *
- * XXX This is an evil type cast. tup->t_xmax is char[5] while
- * TransactionId is struct * { char data[5] }. It works but
- * if data is ever moved and no longer the first field this
- * will be broken!! -mer 11 Nov 1991.
- */
- if (TransactionIdIsValid((TransactionId)tup->t_xmax))
- continue;
-
- /*
- * Okay, see if this is the one we want.
- * XXX 1 july 91: mao and mer discover that tuples now squash
- * t_bits. Why is this?
- *
- * 24 july 92: mer realizes that the t_bits field is only
- * used in the event of null values. If no
- * fields are null we reduce the header size
- * by doing the squash. t_hoff tells you exactly
- * how big the header actually is. use the PC
- * means of getting at sys cat attrs.
- */
- tup_db = (Form_pg_database)GETSTRUCT(tup);
-
- if (strncmp(GetDatabaseName(),
- &(tup_db->datname.data[0]),
- 16) == 0)
- {
- MyDatabaseId = tup->t_oid;
- goto done;
- }
- }
- }
-
- done:
- close(dbfd);
- pfree(pg);
-
- if (!OidIsValid(MyDatabaseId))
- elog(FATAL,
- "Database %s does not exist in %s",
- GetDatabaseName(),
- DatabaseRelationName);
+ int dbfd;
+ int fileflags;
+ int nbytes;
+ int max,
+ i;
+ HeapTuple tup;
+ Page pg;
+ PageHeader ph;
+ char *dbfname;
+ Form_pg_database tup_db;
+
+ /*
+ * At bootstrap time, we don't need to check the oid of the database
+ * in use, since we're not using shared memory. This is lucky, since
+ * the database may not be in the tables yet.
+ */
+
+ if (IsBootstrapProcessingMode())
+ {
+ LockDisable(true);
+ return;
+ }
+
+ dbfname = (char *) palloc(strlen(DataDir) + strlen("pg_database") + 2);
+ sprintf(dbfname, "%s%cpg_database", DataDir, SEP_CHAR);
+ fileflags = O_RDONLY;
+
+ if ((dbfd = open(dbfname, O_RDONLY, 0)) < 0)
+ elog(FATAL, "Cannot open %s", dbfname);
+
+ pfree(dbfname);
+
+ /* ----------------
+ * read and examine every page in pg_database
+ *
+ * Raw I/O! Read those tuples the hard way! Yow!
+ *
+ * Why don't we use the access methods or move this code
+ * someplace else? This is really pg_database schema dependent
+ * code. Perhaps it should go in lib/catalog/pg_database?
+ * -cim 10/3/90
+ *
+ * mao replies 4 apr 91: yeah, maybe this should be moved to
+ * lib/catalog. however, we CANNOT use the access methods since
+ * those use the buffer cache, which uses the relation cache, which
+ * requires that the dbid be set, which is what we're trying to do
+ * here.
+ * ----------------
+ */
+ pg = (Page) palloc(BLCKSZ);
+ ph = (PageHeader) pg;
+
+ while ((nbytes = read(dbfd, pg, BLCKSZ)) == BLCKSZ)
+ {
+ max = PageGetMaxOffsetNumber(pg);
+
+ /* look at each tuple on the page */
+ for (i = 0; i <= max; i++)
+ {
+ int offset;
+
+ /* if it's a freed tuple, ignore it */
+ if (!(ph->pd_linp[i].lp_flags & LP_USED))
+ continue;
+
+ /* get a pointer to the tuple itself */
+ offset = (int) ph->pd_linp[i].lp_off;
+ tup = (HeapTuple) (((char *) pg) + offset);
+
+ /*
+ * if the tuple has been deleted (the database was destroyed),
+ * skip this tuple. XXX warning, will robinson: violation of
+ * transaction semantics happens right here. we should check
+ * to be sure that the xact that deleted this tuple actually
+ * committed. only way to do this at init time is to paw over
+ * the log relation by hand, too. let's be optimistic.
+ *
+ * XXX This is an evil type cast. tup->t_xmax is char[5] while
+ * TransactionId is struct * { char data[5] }. It works but
+ * if data is ever moved and no longer the first field this
+ * will be broken!! -mer 11 Nov 1991.
+ */
+ if (TransactionIdIsValid((TransactionId) tup->t_xmax))
+ continue;
+
+ /*
+ * Okay, see if this is the one we want. XXX 1 july 91: mao
+ * and mer discover that tuples now squash t_bits. Why is
+ * this?
+ *
+ * 24 july 92: mer realizes that the t_bits field is only used
+ * in the event of null values. If no fields are null we
+ * reduce the header size by doing the squash. t_hoff tells
+ * you exactly how big the header actually is. use the PC
+ * means of getting at sys cat attrs.
+ */
+ tup_db = (Form_pg_database) GETSTRUCT(tup);
+
+ if (strncmp(GetDatabaseName(),
+ &(tup_db->datname.data[0]),
+ 16) == 0)
+ {
+ MyDatabaseId = tup->t_oid;
+ goto done;
+ }
+ }
+ }
+
+done:
+ close(dbfd);
+ pfree(pg);
+
+ if (!OidIsValid(MyDatabaseId))
+ elog(FATAL,
+ "Database %s does not exist in %s",
+ GetDatabaseName(),
+ DatabaseRelationName);
}
/*
* DoChdirAndInitDatabaseNameAndPath --
- * Set current directory to the database directory for the database
- * named <name>.
- * Also set global variables DatabasePath and DatabaseName to those
- * values. Also check for proper version of database system and
- * database. Exit program via elog() if anything doesn't check out.
+ * Set current directory to the database directory for the database
+ * named <name>.
+ * Also set global variables DatabasePath and DatabaseName to those
+ * values. Also check for proper version of database system and
+ * database. Exit program via elog() if anything doesn't check out.
*
* Arguments:
- * Path and name are invalid if it invalid as a string.
- * Path is "badly formated" if it is not a string containing a path
- * to a writable directory.
- * Name is "badly formated" if it contains more than 16 characters or if
- * it is a bad file name (e.g., it contains a '/' or an 8-bit character).
+ * Path and name are invalid if it invalid as a string.
+ * Path is "badly formated" if it is not a string containing a path
+ * to a writable directory.
+ * Name is "badly formated" if it contains more than 16 characters or if
+ * it is a bad file name (e.g., it contains a '/' or an 8-bit character).
*
* Exceptions:
- * BadState if called more than once.
- * BadArg if both path and name are "badly formated" or invalid.
- * BadArg if path and name are both "inconsistent" and valid.
+ * BadState if called more than once.
+ * BadArg if both path and name are "badly formated" or invalid.
+ * BadArg if path and name are both "inconsistent" and valid.
*
- * This routine is inappropriate in bootstrap mode, since the directories
- * and version files need not exist yet if we're in bootstrap mode.
+ * This routine is inappropriate in bootstrap mode, since the directories
+ * and version files need not exist yet if we're in bootstrap mode.
*/
static void
-DoChdirAndInitDatabaseNameAndPath(char *name) {
- char *reason;
- /* Failure reason returned by some function. NULL if no failure */
- int fd;
- char errormsg[1000];
-
- if ((fd = open(DataDir, O_RDONLY,0)) == -1)
- sprintf(errormsg, "Database system does not exist. "
- "PGDATA directory '%s' not found. Normally, you "
- "create a database system by running initdb.",
- DataDir);
- else {
- char myPath[MAXPGPATH]; /* DatabasePath points here! */
-
- close(fd);
- if (strlen(DataDir) + strlen(name) + 10 > sizeof(myPath))
- sprintf(errormsg, "Internal error in postinit.c: database "
- "pathname exceeds maximum allowable length.");
- else {
- sprintf(myPath, "%s/base/%s", DataDir, name);
-
- if ((fd = open(myPath, O_RDONLY,0)) == -1)
- sprintf(errormsg,
- "Database '%s' does not exist. "
- "(We know this because the directory '%s' "
- "does not exist). You can create a database "
- "with the SQL command CREATE DATABASE. To see "
- "what databases exist, look at the subdirectories "
- "of '%s/base/'.",
- name, myPath, DataDir);
- else {
- close(fd);
- ValidatePgVersion(DataDir, &reason);
- if (reason != NULL)
- sprintf(errormsg,
- "InitPostgres could not validate that the database "
- "system version is compatible with this level of "
- "Postgres. You may need to run initdb to create "
- "a new database system. %s",
- reason);
- else {
- ValidatePgVersion(myPath, &reason);
- if (reason != NULL)
- sprintf(errormsg,
- "InitPostgres could not validate that the "
- "database version is compatible with this level "
- "of Postgres, even though the database system "
- "as a whole appears to be at a compatible level. "
- "You may need to recreate the database with SQL "
- "commands DROP DATABASE and CREATE DATABASE. "
- "%s",
- reason);
- else {
- /* The directories and PG_VERSION files are in order.*/
- int rc; /* return code from some function we call */
-
- SetDatabasePath(myPath);
- SetDatabaseName(name);
- rc = chdir(myPath);
- if (rc < 0)
- sprintf(errormsg,
- "InitPostgres unable to change "
- "current directory to '%s', errno = %s (%d).",
- myPath, strerror(errno), errno);
- else errormsg[0] = '\0';
- }
- }
- }
- }
- }
- if (errormsg[0] != '\0')
- elog(FATAL, errormsg);
- /* Above does not return */
+DoChdirAndInitDatabaseNameAndPath(char *name)
+{
+ char *reason;
+
+ /* Failure reason returned by some function. NULL if no failure */
+ int fd;
+ char errormsg[1000];
+
+ if ((fd = open(DataDir, O_RDONLY, 0)) == -1)
+ sprintf(errormsg, "Database system does not exist. "
+ "PGDATA directory '%s' not found. Normally, you "
+ "create a database system by running initdb.",
+ DataDir);
+ else
+ {
+ char myPath[MAXPGPATH]; /* DatabasePath points
+ * here! */
+
+ close(fd);
+ if (strlen(DataDir) + strlen(name) + 10 > sizeof(myPath))
+ sprintf(errormsg, "Internal error in postinit.c: database "
+ "pathname exceeds maximum allowable length.");
+ else
+ {
+ sprintf(myPath, "%s/base/%s", DataDir, name);
+
+ if ((fd = open(myPath, O_RDONLY, 0)) == -1)
+ sprintf(errormsg,
+ "Database '%s' does not exist. "
+ "(We know this because the directory '%s' "
+ "does not exist). You can create a database "
+ "with the SQL command CREATE DATABASE. To see "
+ "what databases exist, look at the subdirectories "
+ "of '%s/base/'.",
+ name, myPath, DataDir);
+ else
+ {
+ close(fd);
+ ValidatePgVersion(DataDir, &reason);
+ if (reason != NULL)
+ sprintf(errormsg,
+ "InitPostgres could not validate that the database "
+ "system version is compatible with this level of "
+ "Postgres. You may need to run initdb to create "
+ "a new database system. %s",
+ reason);
+ else
+ {
+ ValidatePgVersion(myPath, &reason);
+ if (reason != NULL)
+ sprintf(errormsg,
+ "InitPostgres could not validate that the "
+ "database version is compatible with this level "
+ "of Postgres, even though the database system "
+ "as a whole appears to be at a compatible level. "
+ "You may need to recreate the database with SQL "
+ "commands DROP DATABASE and CREATE DATABASE. "
+ "%s",
+ reason);
+ else
+ {
+
+ /*
+ * The directories and PG_VERSION files are in
+ * order.
+ */
+ int rc; /* return code from some
+ * function we call */
+
+ SetDatabasePath(myPath);
+ SetDatabaseName(name);
+ rc = chdir(myPath);
+ if (rc < 0)
+ sprintf(errormsg,
+ "InitPostgres unable to change "
+ "current directory to '%s', errno = %s (%d).",
+ myPath, strerror(errno), errno);
+ else
+ errormsg[0] = '\0';
+ }
+ }
+ }
+ }
+ }
+ if (errormsg[0] != '\0')
+ elog(FATAL, errormsg);
+ /* Above does not return */
}
/* --------------------------------
- * InitUserid
+ * InitUserid
*
- * initializes crap associated with the user id.
+ * initializes crap associated with the user id.
* --------------------------------
*/
static void
InitUserid()
{
- setuid(geteuid());
- SetUserId();
+ setuid(geteuid());
+ SetUserId();
}
/* --------------------------------
- * InitCommunication
+ * InitCommunication
*
- * This routine initializes stuff needed for ipc, locking, etc.
- * it should be called something more informative.
+ * This routine initializes stuff needed for ipc, locking, etc.
+ * it should be called something more informative.
*
* Note:
- * This does not set MyBackendId. MyBackendTag is set, however.
+ * This does not set MyBackendId. MyBackendTag is set, however.
* --------------------------------
*/
static void
InitCommunication()
{
- char *postid;
- char *postport;
- IPCKey key = 0;
-
- /* ----------------
- * try and get the backend tag from POSTID
- * ----------------
- */
- MyBackendId = -1;
-
- postid = getenv("POSTID");
- if (!PointerIsValid(postid)) {
- MyBackendTag = -1;
- } else {
- MyBackendTag = atoi(postid);
- Assert(MyBackendTag >= 0);
- }
-
- /* ----------------
- * try and get the ipc key from POSTPORT
- * ----------------
- */
- postport = getenv("POSTPORT");
-
- if (PointerIsValid(postport)) {
- SystemPortAddress address = atoi(postport);
-
- if (address == 0)
- elog(FATAL, "InitCommunication: invalid POSTPORT");
-
- if (MyBackendTag == -1)
- elog(FATAL, "InitCommunication: missing POSTID");
-
- key = SystemPortAddressCreateIPCKey(address);
-
- /*
- * Enable this if you are trying to force the backend to run as if it
- * is running under the postmaster.
- *
- * This goto forces Postgres to attach to shared memory instead of
- * using malloc'ed memory (which is the normal behavior if run
- * directly).
- *
- * To enable emulation, run the following shell commands (in addition
- * to enabling this goto)
- *
- * % setenv POSTID 1
- * % setenv POSTPORT 4321
- * % postmaster &
- * % kill -9 %1
- *
- * Upon doing this, Postmaster will have allocated the shared memory
- * resources that Postgres will attach to if you enable
- * EMULATE_UNDER_POSTMASTER.
- *
- * This comment may well age with time - it is current as of
- * 8 January 1990
- *
- * Greg
- */
-
+ char *postid;
+ char *postport;
+ IPCKey key = 0;
+
+ /* ----------------
+ * try and get the backend tag from POSTID
+ * ----------------
+ */
+ MyBackendId = -1;
+
+ postid = getenv("POSTID");
+ if (!PointerIsValid(postid))
+ {
+ MyBackendTag = -1;
+ }
+ else
+ {
+ MyBackendTag = atoi(postid);
+ Assert(MyBackendTag >= 0);
+ }
+
+ /* ----------------
+ * try and get the ipc key from POSTPORT
+ * ----------------
+ */
+ postport = getenv("POSTPORT");
+
+ if (PointerIsValid(postport))
+ {
+ SystemPortAddress address = atoi(postport);
+
+ if (address == 0)
+ elog(FATAL, "InitCommunication: invalid POSTPORT");
+
+ if (MyBackendTag == -1)
+ elog(FATAL, "InitCommunication: missing POSTID");
+
+ key = SystemPortAddressCreateIPCKey(address);
+
+ /*
+ * Enable this if you are trying to force the backend to run as if
+ * it is running under the postmaster.
+ *
+ * This goto forces Postgres to attach to shared memory instead of
+ * using malloc'ed memory (which is the normal behavior if run
+ * directly).
+ *
+ * To enable emulation, run the following shell commands (in addition
+ * to enabling this goto)
+ *
+ * % setenv POSTID 1 % setenv POSTPORT 4321 % postmaster & % kill -9
+ * %1
+ *
+ * Upon doing this, Postmaster will have allocated the shared memory
+ * resources that Postgres will attach to if you enable
+ * EMULATE_UNDER_POSTMASTER.
+ *
+ * This comment may well age with time - it is current as of 8
+ * January 1990
+ *
+ * Greg
+ */
+
#ifdef EMULATE_UNDER_POSTMASTER
-
- goto forcesharedmemory;
-
+
+ goto forcesharedmemory;
+
#endif
-
- } else if (IsUnderPostmaster) {
- elog(FATAL,
- "InitCommunication: under postmaster and POSTPORT not set");
- } else {
- /* ----------------
- * assume we're running a postgres backend by itself with
- * no front end or postmaster.
- * ----------------
- */
- if (MyBackendTag == -1) {
- MyBackendTag = 1;
- }
-
- key = PrivateIPCKey;
- }
-
- /* ----------------
- * initialize shared memory and semaphores appropriately.
- * ----------------
- */
+
+ }
+ else if (IsUnderPostmaster)
+ {
+ elog(FATAL,
+ "InitCommunication: under postmaster and POSTPORT not set");
+ }
+ else
+ {
+ /* ----------------
+ * assume we're running a postgres backend by itself with
+ * no front end or postmaster.
+ * ----------------
+ */
+ if (MyBackendTag == -1)
+ {
+ MyBackendTag = 1;
+ }
+
+ key = PrivateIPCKey;
+ }
+
+ /* ----------------
+ * initialize shared memory and semaphores appropriately.
+ * ----------------
+ */
#ifdef EMULATE_UNDER_POSTMASTER
-
- forcesharedmemory:
-
+
+forcesharedmemory:
+
#endif
-
- PostgresIpcKey = key;
- AttachSharedMemoryAndSemaphores(key);
+
+ PostgresIpcKey = key;
+ AttachSharedMemoryAndSemaphores(key);
}
/* --------------------------------
- * InitStdio
+ * InitStdio
*
- * this routine consists of a bunch of code fragments
- * that used to be randomly scattered through cinit().
- * they all seem to do stuff associated with io.
+ * this routine consists of a bunch of code fragments
+ * that used to be randomly scattered through cinit().
+ * they all seem to do stuff associated with io.
* --------------------------------
*/
static void
InitStdio()
{
- DebugFileOpen();
+ DebugFileOpen();
}
/* --------------------------------
* InitPostgres --
- * Initialize POSTGRES.
+ * Initialize POSTGRES.
*
* Note:
- * Be very careful with the order of calls in the InitPostgres function.
+ * Be very careful with the order of calls in the InitPostgres function.
* --------------------------------
*/
-bool PostgresIsInitialized = false;
-extern int NBuffers;
+bool PostgresIsInitialized = false;
+extern int NBuffers;
/*
- * this global is used by wei for testing his code, but must be declared
- * here rather than in postgres.c so that it's defined for cinterface.a
- * applications.
+ * this global is used by wei for testing his code, but must be declared
+ * here rather than in postgres.c so that it's defined for cinterface.a
+ * applications.
*/
-/*int testFlag = 0;*/
-int lockingOff = 0;
+/*int testFlag = 0;*/
+int lockingOff = 0;
/*
*/
void
-InitPostgres(char *name) /* database name */
+InitPostgres(char *name) /* database name */
{
- bool bootstrap; /* true if BootstrapProcessing */
-
- /* ----------------
- * see if we're running in BootstrapProcessing mode
- * ----------------
- */
- bootstrap = IsBootstrapProcessingMode();
-
- /* ----------------
- * turn on the exception handler. Note: we cannot use elog, Assert,
- * AssertState, etc. until after exception handling is on.
- * ----------------
- */
- EnableExceptionHandling(true);
-
- /* ----------------
- * A stupid check to make sure we don't call this more than once.
- * But things like ReinitPostgres() get around this by just diddling
- * the PostgresIsInitialized flag.
- * ----------------
- */
- AssertState(!PostgresIsInitialized);
-
- /* ----------------
- * Memory system initialization.
- * (we may call palloc after EnableMemoryContext())
- *
- * Note EnableMemoryContext() must happen before EnablePortalManager().
- * ----------------
- */
- EnableMemoryContext(true); /* initializes the "top context" */
- EnablePortalManager(true); /* memory for portal/transaction stuff */
-
- /* ----------------
- * initialize the backend local portal stack used by
- * internal PQ function calls. see src/lib/libpq/be-dumpdata.c
- * This is different from the "portal manager" so this goes here.
- * -cim 2/12/91
- * ----------------
- */
- be_portalinit();
-
- /* ----------------
- * attach to shared memory and semaphores, and initialize our
- * input/output/debugging file descriptors.
- * ----------------
- */
- InitCommunication();
- InitStdio();
-
- /*
- * initialize the local buffer manager
- */
- InitLocalBuffer();
-
- if (!TransactionFlushEnabled())
- on_exitpg(FlushBufferPool, (caddr_t) NULL);
-
- if (bootstrap) {
- SetDatabasePath(".");
- SetDatabaseName(name);
- } else {
- DoChdirAndInitDatabaseNameAndPath(name);
- }
-
- /* ********************************
- * code after this point assumes we are in the proper directory!
- * ********************************
- */
-
- /* ----------------
- * initialize the database id used for system caches and lock tables
- * ----------------
- */
- InitMyDatabaseId();
-
- smgrinit();
-
- /* ----------------
- * initialize the transaction system and the relation descriptor
- * cache. Note we have to make certain the lock manager is off while
- * we do this.
- * ----------------
- */
- AmiTransactionOverride(IsBootstrapProcessingMode());
- LockDisable(true);
-
- /*
- * Part of the initialization processing done here sets a read
- * lock on pg_log. Since locking is disabled the set doesn't have
- * intended effect of locking out writers, but this is ok, since
- * we only lock it to examine AMI transaction status, and this is
- * never written after initdb is done. -mer 15 June 1992
- */
- RelationInitialize(); /* pre-allocated reldescs created here */
- InitializeTransactionSystem(); /* pg_log,etc init/crash recovery here */
-
- LockDisable(false);
-
- /* ----------------
- * anyone knows what this does? something having to do with
- * system catalog cache invalidation in the case of multiple
- * backends, I think -cim 10/3/90
- * Sets up MyBackendId a unique backend identifier.
- * ----------------
- */
- InitSharedInvalidationState();
-
- /* ----------------
- * Set up a per backend process in shared memory. Must be done after
- * InitSharedInvalidationState() as it relies on MyBackendId being
- * initialized already. XXX -mer 11 Aug 1991
- * ----------------
- */
- InitProcess(PostgresIpcKey);
-
- if (MyBackendId > MaxBackendId || MyBackendId <= 0) {
- elog(FATAL, "cinit2: bad backend id %d (%d)",
- MyBackendTag,
- MyBackendId);
- }
-
- /* ----------------
- * initialize the access methods.
- * ----------------
- */
- initam();
-
- /* ----------------
- * initialize all the system catalog caches.
- * ----------------
- */
- zerocaches();
- InitCatalogCache();
-
- /* ----------------
- * set ourselves to the proper user id and figure out our postgres
- * user id. If we ever add security so that we check for valid
- * postgres users, we might do it here.
- * ----------------
- */
- InitUserid();
-
- /* ----------------
- * ok, all done, now let's make sure we don't do it again.
- * ----------------
- */
- PostgresIsInitialized = true;
-/* on_exitpg(DestroyLocalRelList, (caddr_t) NULL); */
-
- /* ----------------
- * Done with "InitPostgres", now change to NormalProcessing unless
- * we're in BootstrapProcessing mode.
- * ----------------
- */
- if (!bootstrap)
- SetProcessingMode(NormalProcessing);
-/* if (testFlag || lockingOff) */
- if (lockingOff)
- LockDisable(true);
-}
+ bool bootstrap; /* true if BootstrapProcessing */
+
+ /* ----------------
+ * see if we're running in BootstrapProcessing mode
+ * ----------------
+ */
+ bootstrap = IsBootstrapProcessingMode();
+
+ /* ----------------
+ * turn on the exception handler. Note: we cannot use elog, Assert,
+ * AssertState, etc. until after exception handling is on.
+ * ----------------
+ */
+ EnableExceptionHandling(true);
+
+ /* ----------------
+ * A stupid check to make sure we don't call this more than once.
+ * But things like ReinitPostgres() get around this by just diddling
+ * the PostgresIsInitialized flag.
+ * ----------------
+ */
+ AssertState(!PostgresIsInitialized);
+
+ /* ----------------
+ * Memory system initialization.
+ * (we may call palloc after EnableMemoryContext())
+ *
+ * Note EnableMemoryContext() must happen before EnablePortalManager().
+ * ----------------
+ */
+ EnableMemoryContext(true); /* initializes the "top context" */
+ EnablePortalManager(true); /* memory for portal/transaction stuff */
+
+ /* ----------------
+ * initialize the backend local portal stack used by
+ * internal PQ function calls. see src/lib/libpq/be-dumpdata.c
+ * This is different from the "portal manager" so this goes here.
+ * -cim 2/12/91
+ * ----------------
+ */
+ be_portalinit();
+
+ /* ----------------
+ * attach to shared memory and semaphores, and initialize our
+ * input/output/debugging file descriptors.
+ * ----------------
+ */
+ InitCommunication();
+ InitStdio();
+
+ /*
+ * initialize the local buffer manager
+ */
+ InitLocalBuffer();
+ if (!TransactionFlushEnabled())
+ on_exitpg(FlushBufferPool, (caddr_t) NULL);
+ if (bootstrap)
+ {
+ SetDatabasePath(".");
+ SetDatabaseName(name);
+ }
+ else
+ {
+ DoChdirAndInitDatabaseNameAndPath(name);
+ }
+
+ /*
+ * ******************************** code after this point assumes we
+ * are in the proper directory! ********************************
+ *
+ */
+
+ /* ----------------
+ * initialize the database id used for system caches and lock tables
+ * ----------------
+ */
+ InitMyDatabaseId();
+
+ smgrinit();
+
+ /* ----------------
+ * initialize the transaction system and the relation descriptor
+ * cache. Note we have to make certain the lock manager is off while
+ * we do this.
+ * ----------------
+ */
+ AmiTransactionOverride(IsBootstrapProcessingMode());
+ LockDisable(true);
+
+ /*
+ * Part of the initialization processing done here sets a read lock on
+ * pg_log. Since locking is disabled the set doesn't have intended
+ * effect of locking out writers, but this is ok, since we only lock
+ * it to examine AMI transaction status, and this is never written
+ * after initdb is done. -mer 15 June 1992
+ */
+ RelationInitialize(); /* pre-allocated reldescs created here */
+ InitializeTransactionSystem(); /* pg_log,etc init/crash recovery
+ * here */
+
+ LockDisable(false);
+
+ /* ----------------
+ * anyone knows what this does? something having to do with
+ * system catalog cache invalidation in the case of multiple
+ * backends, I think -cim 10/3/90
+ * Sets up MyBackendId a unique backend identifier.
+ * ----------------
+ */
+ InitSharedInvalidationState();
+
+ /* ----------------
+ * Set up a per backend process in shared memory. Must be done after
+ * InitSharedInvalidationState() as it relies on MyBackendId being
+ * initialized already. XXX -mer 11 Aug 1991
+ * ----------------
+ */
+ InitProcess(PostgresIpcKey);
+
+ if (MyBackendId > MaxBackendId || MyBackendId <= 0)
+ {
+ elog(FATAL, "cinit2: bad backend id %d (%d)",
+ MyBackendTag,
+ MyBackendId);
+ }
+
+ /* ----------------
+ * initialize the access methods.
+ * ----------------
+ */
+ initam();
+
+ /* ----------------
+ * initialize all the system catalog caches.
+ * ----------------
+ */
+ zerocaches();
+ InitCatalogCache();
+
+ /* ----------------
+ * set ourselves to the proper user id and figure out our postgres
+ * user id. If we ever add security so that we check for valid
+ * postgres users, we might do it here.
+ * ----------------
+ */
+ InitUserid();
+
+ /* ----------------
+ * ok, all done, now let's make sure we don't do it again.
+ * ----------------
+ */
+ PostgresIsInitialized = true;
+/* on_exitpg(DestroyLocalRelList, (caddr_t) NULL); */
+
+ /* ----------------
+ * Done with "InitPostgres", now change to NormalProcessing unless
+ * we're in BootstrapProcessing mode.
+ * ----------------
+ */
+ if (!bootstrap)
+ SetProcessingMode(NormalProcessing);
+/* if (testFlag || lockingOff) */
+ if (lockingOff)
+ LockDisable(true);
+}
diff --git a/src/backend/utils/misc/superuser.c b/src/backend/utils/misc/superuser.c
index b939c2c05e1..57a9950dea3 100644
--- a/src/backend/utils/misc/superuser.c
+++ b/src/backend/utils/misc/superuser.c
@@ -2,16 +2,16 @@
*
* superuser.c--
*
- * The superuser() function. Determines if user has superuser privilege.
+ * The superuser() function. Determines if user has superuser privilege.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.2 1996/11/03 23:46:28 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.3 1997/09/07 04:53:52 momjian Exp $
*
* DESCRIPTION
- * See superuser().
+ * See superuser().
*-------------------------------------------------------------------------
*/
@@ -20,20 +20,18 @@
#include <catalog/pg_user.h>
bool
-superuser(void) {
+superuser(void)
+{
/*--------------------------------------------------------------------------
- The Postgres user running this command has Postgres superuser
- privileges.
+ The Postgres user running this command has Postgres superuser
+ privileges.
--------------------------------------------------------------------------*/
- extern char *UserName; /* defined in global.c */
+ extern char *UserName; /* defined in global.c */
- HeapTuple utup;
+ HeapTuple utup;
- utup = SearchSysCacheTuple(USENAME, PointerGetDatum(UserName),
- 0,0,0);
- Assert(utup != NULL);
- return ((Form_pg_user)GETSTRUCT(utup))->usesuper;
+ utup = SearchSysCacheTuple(USENAME, PointerGetDatum(UserName),
+ 0, 0, 0);
+ Assert(utup != NULL);
+ return ((Form_pg_user) GETSTRUCT(utup))->usesuper;
}
-
-
-
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index 8e0482de38c..c07fb1bd587 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -1,33 +1,34 @@
/*-------------------------------------------------------------------------
*
* aset.c--
- * Allocation set definitions.
+ * Allocation set definitions.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.5 1997/08/19 21:35:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.6 1997/09/07 04:54:01 momjian Exp $
*
* NOTE
- * XXX This is a preliminary implementation which lacks fail-fast
- * XXX validity checking of arguments.
+ * XXX This is a preliminary implementation which lacks fail-fast
+ * XXX validity checking of arguments.
*
*-------------------------------------------------------------------------
*/
#include <stdio.h>
#include "postgres.h"
-#include "utils/excid.h" /* for ExhaustedMemory */
-#include "utils/memutils.h" /* where funnction declarations go */
+#include "utils/excid.h" /* for ExhaustedMemory */
+#include "utils/memutils.h" /* where funnction declarations go */
#ifndef HAVE_MEMMOVE
-# include <regex/utils.h>
+#include <regex/utils.h>
#else
-# include <string.h>
+#include <string.h>
#endif
-static void AllocPointerDump(AllocPointer pointer);
-static int AllocSetIterate(AllocSet set,
- void (*function)(AllocPointer pointer));
+static void AllocPointerDump(AllocPointer pointer);
+static int
+AllocSetIterate(AllocSet set,
+ void (*function) (AllocPointer pointer));
#undef AllocSetReset
#undef malloc
@@ -39,12 +40,13 @@ static int AllocSetIterate(AllocSet set,
/*
* AllocElem --
- * Allocation element.
+ * Allocation element.
*/
-typedef struct AllocElemData {
- OrderedElemData elemData; /* elem in AllocSet */
- Size size;
-} AllocElemData;
+typedef struct AllocElemData
+{
+ OrderedElemData elemData; /* elem in AllocSet */
+ Size size;
+} AllocElemData;
typedef AllocElemData *AllocElem;
@@ -55,21 +57,21 @@ typedef AllocElemData *AllocElem;
/*
* AllocPointerGetAllocElem --
- * Returns allocation (internal) elem given (external) pointer.
+ * Returns allocation (internal) elem given (external) pointer.
*/
-#define AllocPointerGetAllocElem(pointer) (&((AllocElem)(pointer))[-1])
+#define AllocPointerGetAllocElem(pointer) (&((AllocElem)(pointer))[-1])
/*
* AllocElemGetAllocPointer --
- * Returns allocation (external) pointer given (internal) elem.
+ * Returns allocation (external) pointer given (internal) elem.
*/
-#define AllocElemGetAllocPointer(alloc) ((AllocPointer)&(alloc)[1])
+#define AllocElemGetAllocPointer(alloc) ((AllocPointer)&(alloc)[1])
/*
* AllocElemIsValid --
- * True iff alloc is valid.
+ * True iff alloc is valid.
*/
-#define AllocElemIsValid(alloc) PointerIsValid(alloc)
+#define AllocElemIsValid(alloc) PointerIsValid(alloc)
/* non-export function prototypes */
static AllocPointer AllocSetGetFirst(AllocSet set);
@@ -79,242 +81,250 @@ static AllocPointer AllocPointerGetNext(AllocPointer pointer);
* Public routines
*/
-/*
- * AllocPointerIsValid(pointer)
- * AllocSetIsValid(set)
+/*
+ * AllocPointerIsValid(pointer)
+ * AllocSetIsValid(set)
*
- * .. are now macros in aset.h -cim 4/27/91
+ * .. are now macros in aset.h -cim 4/27/91
*/
/*
* AllocSetInit --
- * Initializes given allocation set.
+ * Initializes given allocation set.
*
* Note:
- * The semantics of the mode are explained above. Limit is ignored
- * for dynamic and static modes.
+ * The semantics of the mode are explained above. Limit is ignored
+ * for dynamic and static modes.
*
* Exceptions:
- * BadArg if set is invalid pointer.
- * BadArg if mode is invalid.
+ * BadArg if set is invalid pointer.
+ * BadArg if mode is invalid.
*/
void
AllocSetInit(AllocSet set, AllocMode mode, Size limit)
{
- AssertArg(PointerIsValid(set));
- AssertArg((int)DynamicAllocMode <= (int)mode);
- AssertArg((int)mode <= (int)BoundedAllocMode);
-
- /*
- * XXX mode is currently ignored and treated as DynamicAllocMode.
- * XXX limit is also ignored. This affects this whole file.
- */
-
- OrderedSetInit(&set->setData, offsetof(AllocElemData, elemData));
+ AssertArg(PointerIsValid(set));
+ AssertArg((int) DynamicAllocMode <= (int) mode);
+ AssertArg((int) mode <= (int) BoundedAllocMode);
+
+ /*
+ * XXX mode is currently ignored and treated as DynamicAllocMode. XXX
+ * limit is also ignored. This affects this whole file.
+ */
+
+ OrderedSetInit(&set->setData, offsetof(AllocElemData, elemData));
}
/*
* AllocSetReset --
- * Frees memory which is allocated in the given set.
+ * Frees memory which is allocated in the given set.
*
* Exceptions:
- * BadArg if set is invalid.
+ * BadArg if set is invalid.
*/
void
AllocSetReset(AllocSet set)
{
- AllocPointer pointer;
-
- AssertArg(AllocSetIsValid(set));
-
- while (AllocPointerIsValid(pointer = AllocSetGetFirst(set))) {
- AllocSetFree(set, pointer);
- }
+ AllocPointer pointer;
+
+ AssertArg(AllocSetIsValid(set));
+
+ while (AllocPointerIsValid(pointer = AllocSetGetFirst(set)))
+ {
+ AllocSetFree(set, pointer);
+ }
}
#ifdef NOT_USED
void
AllocSetReset_debug(char *file, int line, AllocSet set)
{
- AllocPointer pointer;
-
- AssertArg(AllocSetIsValid(set));
-
- while (AllocPointerIsValid(pointer = AllocSetGetFirst(set))) {
- AllocSetFree(set, pointer);
- }
+ AllocPointer pointer;
+
+ AssertArg(AllocSetIsValid(set));
+
+ while (AllocPointerIsValid(pointer = AllocSetGetFirst(set)))
+ {
+ AllocSetFree(set, pointer);
+ }
}
+
#endif
/*
* AllocSetContains --
- * True iff allocation set contains given allocation element.
+ * True iff allocation set contains given allocation element.
*
* Exceptions:
- * BadArg if set is invalid.
- * BadArg if pointer is invalid.
+ * BadArg if set is invalid.
+ * BadArg if pointer is invalid.
*/
bool
AllocSetContains(AllocSet set, AllocPointer pointer)
{
- AssertArg(AllocSetIsValid(set));
- AssertArg(AllocPointerIsValid(pointer));
-
- return (OrderedSetContains(&set->setData,
- &AllocPointerGetAllocElem(pointer)->elemData));
+ AssertArg(AllocSetIsValid(set));
+ AssertArg(AllocPointerIsValid(pointer));
+
+ return (OrderedSetContains(&set->setData,
+ &AllocPointerGetAllocElem(pointer)->elemData));
}
/*
* AllocSetAlloc --
- * Returns pointer to allocated memory of given size; memory is added
- * to the set.
+ * Returns pointer to allocated memory of given size; memory is added
+ * to the set.
*
* Exceptions:
- * BadArg if set is invalid.
- * MemoryExhausted if allocation fails.
+ * BadArg if set is invalid.
+ * MemoryExhausted if allocation fails.
*/
AllocPointer
AllocSetAlloc(AllocSet set, Size size)
{
- AllocElem alloc;
-
- AssertArg(AllocSetIsValid(set));
-
- /* allocate */
- alloc = (AllocElem)malloc(sizeof (*alloc) + size);
-
- if (!PointerIsValid(alloc)) {
- elog (FATAL, "palloc failure: memory exhausted");
- }
-
- /* add to allocation list */
- OrderedElemPushInto(&alloc->elemData, &set->setData);
-
- /* set size */
- alloc->size = size;
-
- return (AllocElemGetAllocPointer(alloc));
+ AllocElem alloc;
+
+ AssertArg(AllocSetIsValid(set));
+
+ /* allocate */
+ alloc = (AllocElem) malloc(sizeof(*alloc) + size);
+
+ if (!PointerIsValid(alloc))
+ {
+ elog(FATAL, "palloc failure: memory exhausted");
+ }
+
+ /* add to allocation list */
+ OrderedElemPushInto(&alloc->elemData, &set->setData);
+
+ /* set size */
+ alloc->size = size;
+
+ return (AllocElemGetAllocPointer(alloc));
}
/*
* AllocSetFree --
- * Frees allocated memory; memory is removed from the set.
+ * Frees allocated memory; memory is removed from the set.
*
* Exceptions:
- * BadArg if set is invalid.
- * BadArg if pointer is invalid.
- * BadArg if pointer is not member of set.
+ * BadArg if set is invalid.
+ * BadArg if pointer is invalid.
+ * BadArg if pointer is not member of set.
*/
void
AllocSetFree(AllocSet set, AllocPointer pointer)
{
- AllocElem alloc;
-
- /* AssertArg(AllocSetIsValid(set)); */
- /* AssertArg(AllocPointerIsValid(pointer)); */
- AssertArg(AllocSetContains(set, pointer));
-
- alloc = AllocPointerGetAllocElem(pointer);
-
- /* remove from allocation set */
- OrderedElemPop(&alloc->elemData);
-
- /* free storage */
- free(alloc);
+ AllocElem alloc;
+
+ /* AssertArg(AllocSetIsValid(set)); */
+ /* AssertArg(AllocPointerIsValid(pointer)); */
+ AssertArg(AllocSetContains(set, pointer));
+
+ alloc = AllocPointerGetAllocElem(pointer);
+
+ /* remove from allocation set */
+ OrderedElemPop(&alloc->elemData);
+
+ /* free storage */
+ free(alloc);
}
/*
* AllocSetRealloc --
- * Returns new pointer to allocated memory of given size; this memory
- * is added to the set. Memory associated with given pointer is copied
- * into the new memory, and the old memory is freed.
+ * Returns new pointer to allocated memory of given size; this memory
+ * is added to the set. Memory associated with given pointer is copied
+ * into the new memory, and the old memory is freed.
*
* Exceptions:
- * BadArg if set is invalid.
- * BadArg if pointer is invalid.
- * BadArg if pointer is not member of set.
- * MemoryExhausted if allocation fails.
+ * BadArg if set is invalid.
+ * BadArg if pointer is invalid.
+ * BadArg if pointer is not member of set.
+ * MemoryExhausted if allocation fails.
*/
AllocPointer
AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size)
{
- AllocPointer newPointer;
- AllocElem alloc;
-
- /* AssertArg(AllocSetIsValid(set)); */
- /* AssertArg(AllocPointerIsValid(pointer)); */
- AssertArg(AllocSetContains(set, pointer));
-
- /*
- * Calling realloc(3) directly is not be possible (unless we use
- * our own hacked version of malloc) since we must keep the
- * allocations in the allocation set.
- */
-
- alloc = AllocPointerGetAllocElem(pointer);
-
- /* allocate new pointer */
- newPointer = AllocSetAlloc(set, size);
-
- /* fill new memory */
- memmove(newPointer, pointer, (alloc->size < size) ? alloc->size : size);
-
- /* free old pointer */
- AllocSetFree(set, pointer);
-
- return (newPointer);
+ AllocPointer newPointer;
+ AllocElem alloc;
+
+ /* AssertArg(AllocSetIsValid(set)); */
+ /* AssertArg(AllocPointerIsValid(pointer)); */
+ AssertArg(AllocSetContains(set, pointer));
+
+ /*
+ * Calling realloc(3) directly is not be possible (unless we use our
+ * own hacked version of malloc) since we must keep the allocations in
+ * the allocation set.
+ */
+
+ alloc = AllocPointerGetAllocElem(pointer);
+
+ /* allocate new pointer */
+ newPointer = AllocSetAlloc(set, size);
+
+ /* fill new memory */
+ memmove(newPointer, pointer, (alloc->size < size) ? alloc->size : size);
+
+ /* free old pointer */
+ AllocSetFree(set, pointer);
+
+ return (newPointer);
}
/*
* AllocSetIterate --
- * Returns size of set. Iterates through set elements calling function
- * (if valid) on each.
+ * Returns size of set. Iterates through set elements calling function
+ * (if valid) on each.
*
* Note:
- * This was written as an aid to debugging. It is intended for
- * debugging use only.
+ * This was written as an aid to debugging. It is intended for
+ * debugging use only.
*
* Exceptions:
- * BadArg if set is invalid.
+ * BadArg if set is invalid.
*/
static int
AllocSetIterate(AllocSet set,
- void (*function)(AllocPointer pointer))
+ void (*function) (AllocPointer pointer))
{
- int count = 0;
- AllocPointer pointer;
-
- AssertArg(AllocSetIsValid(set));
-
- for (pointer = AllocSetGetFirst(set);
- AllocPointerIsValid(pointer);
- pointer = AllocPointerGetNext(pointer)) {
-
- if (PointerIsValid(function)) {
- (*function)(pointer);
+ int count = 0;
+ AllocPointer pointer;
+
+ AssertArg(AllocSetIsValid(set));
+
+ for (pointer = AllocSetGetFirst(set);
+ AllocPointerIsValid(pointer);
+ pointer = AllocPointerGetNext(pointer))
+ {
+
+ if (PointerIsValid(function))
+ {
+ (*function) (pointer);
+ }
+ count += 1;
}
- count += 1;
- }
-
- return (count);
+
+ return (count);
}
#ifdef NOT_USED
int
AllocSetCount(AllocSet set)
{
- int count = 0;
- AllocPointer pointer;
-
- AssertArg(AllocSetIsValid(set));
-
- for (pointer = AllocSetGetFirst(set);
- AllocPointerIsValid(pointer);
- pointer = AllocPointerGetNext(pointer)) {
- count++;
- }
- return count;
+ int count = 0;
+ AllocPointer pointer;
+
+ AssertArg(AllocSetIsValid(set));
+
+ for (pointer = AllocSetGetFirst(set);
+ AllocPointerIsValid(pointer);
+ pointer = AllocPointerGetNext(pointer))
+ {
+ count++;
+ }
+ return count;
}
+
#endif
/*
@@ -323,45 +333,47 @@ AllocSetCount(AllocSet set)
/*
* AllocSetGetFirst --
- * Returns "first" allocation pointer in a set.
+ * Returns "first" allocation pointer in a set.
*
* Note:
- * Assumes set is valid.
+ * Assumes set is valid.
*/
-static AllocPointer
+static AllocPointer
AllocSetGetFirst(AllocSet set)
{
- AllocElem alloc;
-
- alloc = (AllocElem)OrderedSetGetHead(&set->setData);
-
- if (!AllocElemIsValid(alloc)) {
- return (NULL);
- }
-
- return (AllocElemGetAllocPointer(alloc));
+ AllocElem alloc;
+
+ alloc = (AllocElem) OrderedSetGetHead(&set->setData);
+
+ if (!AllocElemIsValid(alloc))
+ {
+ return (NULL);
+ }
+
+ return (AllocElemGetAllocPointer(alloc));
}
/*
* AllocPointerGetNext --
- * Returns "successor" allocation pointer.
+ * Returns "successor" allocation pointer.
*
* Note:
- * Assumes pointer is valid.
+ * Assumes pointer is valid.
*/
-static AllocPointer
+static AllocPointer
AllocPointerGetNext(AllocPointer pointer)
{
- AllocElem alloc;
-
- alloc = (AllocElem)
- OrderedElemGetSuccessor(&AllocPointerGetAllocElem(pointer)->elemData);
-
- if (!AllocElemIsValid(alloc)) {
- return (NULL);
- }
-
- return (AllocElemGetAllocPointer(alloc));
+ AllocElem alloc;
+
+ alloc = (AllocElem)
+ OrderedElemGetSuccessor(&AllocPointerGetAllocElem(pointer)->elemData);
+
+ if (!AllocElemIsValid(alloc))
+ {
+ return (NULL);
+ }
+
+ return (AllocElemGetAllocPointer(alloc));
}
@@ -371,22 +383,23 @@ AllocPointerGetNext(AllocPointer pointer)
/*
* XXX AllocPointerDump --
- * Displays allocated pointer.
+ * Displays allocated pointer.
*/
static void
AllocPointerDump(AllocPointer pointer)
{
- printf("\t%-10ld@ %0#lx\n", ((long*)pointer)[-1], (long)pointer); /* XXX */
+ printf("\t%-10ld@ %0#lx\n", ((long *) pointer)[-1], (long) pointer); /* XXX */
}
/*
* AllocSetDump --
- * Displays allocated set.
+ * Displays allocated set.
*/
void
AllocSetDump(AllocSet set)
{
- int count;
- count = AllocSetIterate(set, AllocPointerDump);
- printf("\ttotal %d allocations\n", count);
+ int count;
+
+ count = AllocSetIterate(set, AllocPointerDump);
+ printf("\ttotal %d allocations\n", count);
}
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index df2eb480817..dbd1b6e19f6 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* mcxt.c--
- * POSTGRES memory context code.
+ * POSTGRES memory context code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.3 1997/08/19 21:35:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.4 1997/09/07 04:54:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#include <stdio.h> /* XXX for printf debugging */
+#include <stdio.h> /* XXX for printf debugging */
#include "postgres.h"
@@ -35,90 +35,93 @@
/*
* Global State
*/
-static int MemoryContextEnableCount = 0;
+static int MemoryContextEnableCount = 0;
+
#define MemoryContextEnabled (MemoryContextEnableCount > 0)
-static OrderedSetData ActiveGlobalMemorySetData; /* uninitialized */
+static OrderedSetData ActiveGlobalMemorySetData; /* uninitialized */
+
#define ActiveGlobalMemorySet (&ActiveGlobalMemorySetData)
/*
* description of allocated memory representation goes here
*/
-#define PSIZE(PTR) (*((int32 *)(PTR) - 1))
+#define PSIZE(PTR) (*((int32 *)(PTR) - 1))
#define PSIZEALL(PTR) (*((int32 *)(PTR) - 1) + sizeof (int32))
#define PSIZESKIP(PTR) ((char *)((int32 *)(PTR) + 1))
#define PSIZEFIND(PTR) ((char *)((int32 *)(PTR) - 1))
-#define PSIZESPACE(LEN) ((LEN) + sizeof (int32))
+#define PSIZESPACE(LEN) ((LEN) + sizeof (int32))
/*
* AllocSizeIsValid --
- * True iff 0 < size and size <= MaxAllocSize.
+ * True iff 0 < size and size <= MaxAllocSize.
*/
-#define AllocSizeIsValid(size) (0 < (size) && (size) <= MaxAllocSize)
+#define AllocSizeIsValid(size) (0 < (size) && (size) <= MaxAllocSize)
/*****************************************************************************
- * GLOBAL MEMORY *
+ * GLOBAL MEMORY *
*****************************************************************************/
/*
* CurrentMemoryContext --
- * Memory context for general global allocations.
+ * Memory context for general global allocations.
*/
MemoryContext CurrentMemoryContext = NULL;
/*****************************************************************************
- * PRIVATE DEFINITIONS *
+ * PRIVATE DEFINITIONS *
*****************************************************************************/
-static Pointer GlobalMemoryAlloc(GlobalMemory this, Size size);
-static void GlobalMemoryFree(GlobalMemory this, Pointer pointer);
-static Pointer GlobalMemoryRealloc(GlobalMemory this, Pointer pointer,
- Size size);
-static char *GlobalMemoryGetName(GlobalMemory this);
-static void GlobalMemoryDump(GlobalMemory this);
+static Pointer GlobalMemoryAlloc(GlobalMemory this, Size size);
+static void GlobalMemoryFree(GlobalMemory this, Pointer pointer);
+static Pointer
+GlobalMemoryRealloc(GlobalMemory this, Pointer pointer,
+ Size size);
+static char *GlobalMemoryGetName(GlobalMemory this);
+static void GlobalMemoryDump(GlobalMemory this);
+
#ifdef NOT_USED
-static void DumpGlobalMemories(void);
+static void DumpGlobalMemories(void);
+
#endif
/*
* Global Memory Methods
*/
-static struct MemoryContextMethodsData GlobalContextMethodsData = {
- GlobalMemoryAlloc, /* Pointer (*)(this, uint32) palloc */
- GlobalMemoryFree, /* void (*)(this, Pointer) pfree */
- GlobalMemoryRealloc, /* Pointer (*)(this, Pointer) repalloc */
- GlobalMemoryGetName, /* char* (*)(this) getName */
- GlobalMemoryDump /* void (*)(this) dump */
+static struct MemoryContextMethodsData GlobalContextMethodsData = {
+ GlobalMemoryAlloc, /* Pointer (*)(this, uint32) palloc */
+ GlobalMemoryFree, /* void (*)(this, Pointer) pfree */
+ GlobalMemoryRealloc, /* Pointer (*)(this, Pointer) repalloc */
+ GlobalMemoryGetName, /* char* (*)(this) getName */
+ GlobalMemoryDump /* void (*)(this) dump */
};
/*
* Note:
- * TopGlobalMemory is handled specially because of bootstrapping.
+ * TopGlobalMemory is handled specially because of bootstrapping.
*/
/* extern bool EqualGlobalMemory(); */
static struct GlobalMemory TopGlobalMemoryData = {
- T_GlobalMemory, /* NodeTag tag */
- &GlobalContextMethodsData, /* ContextMethods method */
- { { 0 } }, /* uninitialized
- * OrderedSetData allocSetD
- */
- "TopGlobal", /* char* name */
- { 0 } /* uninitialized OrderedElemData elemD */
+ T_GlobalMemory, /* NodeTag tag */
+ &GlobalContextMethodsData, /* ContextMethods method */
+ {{0}}, /* uninitialized OrderedSetData allocSetD */
+ "TopGlobal", /* char* name */
+ {0} /* uninitialized OrderedElemData elemD */
};
/*
* TopMemoryContext --
- * Memory context for general global allocations.
+ * Memory context for general global allocations.
*
* Note:
- * Don't use this memory context for random allocations. If you
- * allocate something here, you are expected to clean it up when
- * appropriate.
+ * Don't use this memory context for random allocations. If you
+ * allocate something here, you are expected to clean it up when
+ * appropriate.
*/
-MemoryContext TopMemoryContext = (MemoryContext)&TopGlobalMemoryData;
+MemoryContext TopMemoryContext = (MemoryContext) & TopGlobalMemoryData;
@@ -129,213 +132,223 @@ MemoryContext TopMemoryContext = (MemoryContext)&TopGlobalMemoryData;
/*
* EnableMemoryContext --
- * Enables/disables memory management and global contexts.
+ * Enables/disables memory management and global contexts.
*
* Note:
- * This must be called before creating contexts or allocating memory.
- * This must be called before other contexts are created.
+ * This must be called before creating contexts or allocating memory.
+ * This must be called before other contexts are created.
*
* Exceptions:
- * BadArg if on is invalid.
- * BadState if on is false when disabled.
+ * BadArg if on is invalid.
+ * BadState if on is false when disabled.
*/
void
EnableMemoryContext(bool on)
{
- static bool processing = false;
-
- AssertState(!processing);
- AssertArg(BoolIsValid(on));
-
- if (BypassEnable(&MemoryContextEnableCount, on)) {
- return;
- }
-
- processing = true;
-
- if (on) { /* initialize */
- /* initialize TopGlobalMemoryData.setData */
- AllocSetInit(&TopGlobalMemoryData.setData, DynamicAllocMode,
- (Size)0);
-
- /* make TopGlobalMemoryData member of ActiveGlobalMemorySet */
- OrderedSetInit(ActiveGlobalMemorySet,
- offsetof(struct GlobalMemory, elemData));
- OrderedElemPushInto(&TopGlobalMemoryData.elemData,
- ActiveGlobalMemorySet);
-
- /* initialize CurrentMemoryContext */
- CurrentMemoryContext = TopMemoryContext;
-
- } else { /* cleanup */
- GlobalMemory context;
-
- /* walk the list of allocations */
- while (PointerIsValid(context = (GlobalMemory)
- OrderedSetGetHead(ActiveGlobalMemorySet))) {
-
- if (context == &TopGlobalMemoryData) {
- /* don't free it and clean it last */
- OrderedElemPop(&TopGlobalMemoryData.elemData);
- } else {
- GlobalMemoryDestroy(context);
- }
- /* what is needed for the top? */
+ static bool processing = false;
+
+ AssertState(!processing);
+ AssertArg(BoolIsValid(on));
+
+ if (BypassEnable(&MemoryContextEnableCount, on))
+ {
+ return;
}
-
- /*
- * Freeing memory here should be safe as this is called
- * only after all modules which allocate in TopMemoryContext
- * have been disabled.
- */
-
- /* step through remaining allocations and log */
- /* AllocSetStep(...); */
-
- /* deallocate whatever is left */
- AllocSetReset(&TopGlobalMemoryData.setData);
- }
-
- processing = false;
+
+ processing = true;
+
+ if (on)
+ { /* initialize */
+ /* initialize TopGlobalMemoryData.setData */
+ AllocSetInit(&TopGlobalMemoryData.setData, DynamicAllocMode,
+ (Size) 0);
+
+ /* make TopGlobalMemoryData member of ActiveGlobalMemorySet */
+ OrderedSetInit(ActiveGlobalMemorySet,
+ offsetof(struct GlobalMemory, elemData));
+ OrderedElemPushInto(&TopGlobalMemoryData.elemData,
+ ActiveGlobalMemorySet);
+
+ /* initialize CurrentMemoryContext */
+ CurrentMemoryContext = TopMemoryContext;
+
+ }
+ else
+ { /* cleanup */
+ GlobalMemory context;
+
+ /* walk the list of allocations */
+ while (PointerIsValid(context = (GlobalMemory)
+ OrderedSetGetHead(ActiveGlobalMemorySet)))
+ {
+
+ if (context == &TopGlobalMemoryData)
+ {
+ /* don't free it and clean it last */
+ OrderedElemPop(&TopGlobalMemoryData.elemData);
+ }
+ else
+ {
+ GlobalMemoryDestroy(context);
+ }
+ /* what is needed for the top? */
+ }
+
+ /*
+ * Freeing memory here should be safe as this is called only after
+ * all modules which allocate in TopMemoryContext have been
+ * disabled.
+ */
+
+ /* step through remaining allocations and log */
+ /* AllocSetStep(...); */
+
+ /* deallocate whatever is left */
+ AllocSetReset(&TopGlobalMemoryData.setData);
+ }
+
+ processing = false;
}
/*
* MemoryContextAlloc --
- * Returns pointer to aligned allocated memory in the given context.
+ * Returns pointer to aligned allocated memory in the given context.
*
* Note:
- * none
+ * none
*
* Exceptions:
- * BadState if called before InitMemoryManager.
- * BadArg if context is invalid or if size is 0.
- * BadAllocSize if size is larger than MaxAllocSize.
+ * BadState if called before InitMemoryManager.
+ * BadArg if context is invalid or if size is 0.
+ * BadAllocSize if size is larger than MaxAllocSize.
*/
Pointer
MemoryContextAlloc(MemoryContext context, Size size)
{
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
-
- LogTrap(!AllocSizeIsValid(size), BadAllocSize,
- ("size=%d [0x%x]", size, size));
-
- return (context->method->alloc(context, size));
+ AssertState(MemoryContextEnabled);
+ AssertArg(MemoryContextIsValid(context));
+
+ LogTrap(!AllocSizeIsValid(size), BadAllocSize,
+ ("size=%d [0x%x]", size, size));
+
+ return (context->method->alloc(context, size));
}
/*
* MemoryContextFree --
- * Frees allocated memory referenced by pointer in the given context.
+ * Frees allocated memory referenced by pointer in the given context.
*
* Note:
- * none
+ * none
*
* Exceptions:
- * ???
- * BadArgumentsErr if firstTime is true for subsequent calls.
+ * ???
+ * BadArgumentsErr if firstTime is true for subsequent calls.
*/
void
MemoryContextFree(MemoryContext context, Pointer pointer)
{
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
- AssertArg(PointerIsValid(pointer));
-
- context->method->free_p(context, pointer);
+ AssertState(MemoryContextEnabled);
+ AssertArg(MemoryContextIsValid(context));
+ AssertArg(PointerIsValid(pointer));
+
+ context->method->free_p(context, pointer);
}
/*
* MemoryContextRelloc --
- * Returns pointer to aligned allocated memory in the given context.
+ * Returns pointer to aligned allocated memory in the given context.
*
* Note:
- * none
+ * none
*
* Exceptions:
- * ???
- * BadArgumentsErr if firstTime is true for subsequent calls.
+ * ???
+ * BadArgumentsErr if firstTime is true for subsequent calls.
*/
Pointer
MemoryContextRealloc(MemoryContext context,
- Pointer pointer,
- Size size)
+ Pointer pointer,
+ Size size)
{
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
- AssertArg(PointerIsValid(pointer));
-
- LogTrap(!AllocSizeIsValid(size), BadAllocSize,
- ("size=%d [0x%x]", size, size));
-
- return (context->method->realloc(context, pointer, size));
+ AssertState(MemoryContextEnabled);
+ AssertArg(MemoryContextIsValid(context));
+ AssertArg(PointerIsValid(pointer));
+
+ LogTrap(!AllocSizeIsValid(size), BadAllocSize,
+ ("size=%d [0x%x]", size, size));
+
+ return (context->method->realloc(context, pointer, size));
}
/*
* MemoryContextGetName --
- * Returns pointer to aligned allocated memory in the given context.
+ * Returns pointer to aligned allocated memory in the given context.
*
* Note:
- * none
+ * none
*
* Exceptions:
- * ???
- * BadArgumentsErr if firstTime is true for subsequent calls.
+ * ???
+ * BadArgumentsErr if firstTime is true for subsequent calls.
*/
#ifdef NOT_USED
-char*
+char *
MemoryContextGetName(MemoryContext context)
{
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
-
- return (context->method->getName(context));
+ AssertState(MemoryContextEnabled);
+ AssertArg(MemoryContextIsValid(context));
+
+ return (context->method->getName(context));
}
+
#endif
/*
* PointerGetAllocSize --
- * Returns size of aligned allocated memory given pointer to it.
+ * Returns size of aligned allocated memory given pointer to it.
*
* Note:
- * none
+ * none
*
* Exceptions:
- * ???
- * BadArgumentsErr if firstTime is true for subsequent calls.
+ * ???
+ * BadArgumentsErr if firstTime is true for subsequent calls.
*/
#ifdef NOT_USED
Size
PointerGetAllocSize(Pointer pointer)
{
- AssertState(MemoryContextEnabled);
- AssertArg(PointerIsValid(pointer));
-
- return (PSIZE(pointer));
+ AssertState(MemoryContextEnabled);
+ AssertArg(PointerIsValid(pointer));
+
+ return (PSIZE(pointer));
}
+
#endif
/*
* MemoryContextSwitchTo --
- * Returns the current context; installs the given context.
+ * Returns the current context; installs the given context.
*
* Note:
- * none
+ * none
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if context is invalid.
+ * BadState if called when disabled.
+ * BadArg if context is invalid.
*/
MemoryContext
MemoryContextSwitchTo(MemoryContext context)
{
- MemoryContext old;
-
- AssertState(MemoryContextEnabled);
- AssertArg(MemoryContextIsValid(context));
-
- old = CurrentMemoryContext;
- CurrentMemoryContext = context;
- return (old);
+ MemoryContext old;
+
+ AssertState(MemoryContextEnabled);
+ AssertArg(MemoryContextIsValid(context));
+
+ old = CurrentMemoryContext;
+ CurrentMemoryContext = context;
+ return (old);
}
/*
@@ -343,174 +356,178 @@ MemoryContextSwitchTo(MemoryContext context)
*/
/*
* CreateGlobalMemory --
- * Returns new global memory context.
+ * Returns new global memory context.
*
* Note:
- * Assumes name is static.
+ * Assumes name is static.
*
* Exceptions:
- * BadState if called when disabled.
- * BadState if called outside TopMemoryContext (TopGlobalMemory).
- * BadArg if name is invalid.
+ * BadState if called when disabled.
+ * BadState if called outside TopMemoryContext (TopGlobalMemory).
+ * BadArg if name is invalid.
*/
GlobalMemory
-CreateGlobalMemory(char *name) /* XXX MemoryContextName */
+CreateGlobalMemory(char *name) /* XXX MemoryContextName */
{
- GlobalMemory context;
- MemoryContext savecxt;
-
- AssertState(MemoryContextEnabled);
-
- savecxt = MemoryContextSwitchTo(TopMemoryContext);
-
- context = (GlobalMemory)newNode(sizeof(struct GlobalMemory), T_GlobalMemory);
- context->method = &GlobalContextMethodsData;
- context->name = name; /* assumes name is static */
- AllocSetInit(&context->setData, DynamicAllocMode, (Size)0);
-
- /* link the context */
- OrderedElemPushInto(&context->elemData, ActiveGlobalMemorySet);
-
- MemoryContextSwitchTo(savecxt);
- return (context);
+ GlobalMemory context;
+ MemoryContext savecxt;
+
+ AssertState(MemoryContextEnabled);
+
+ savecxt = MemoryContextSwitchTo(TopMemoryContext);
+
+ context = (GlobalMemory) newNode(sizeof(struct GlobalMemory), T_GlobalMemory);
+ context->method = &GlobalContextMethodsData;
+ context->name = name; /* assumes name is static */
+ AllocSetInit(&context->setData, DynamicAllocMode, (Size) 0);
+
+ /* link the context */
+ OrderedElemPushInto(&context->elemData, ActiveGlobalMemorySet);
+
+ MemoryContextSwitchTo(savecxt);
+ return (context);
}
/*
* GlobalMemoryDestroy --
- * Destroys given global memory context.
+ * Destroys given global memory context.
*
* Exceptions:
- * BadState if called when disabled.
- * BadState if called outside TopMemoryContext (TopGlobalMemory).
- * BadArg if context is invalid GlobalMemory.
- * BadArg if context is TopMemoryContext (TopGlobalMemory).
+ * BadState if called when disabled.
+ * BadState if called outside TopMemoryContext (TopGlobalMemory).
+ * BadArg if context is invalid GlobalMemory.
+ * BadArg if context is TopMemoryContext (TopGlobalMemory).
*/
void
GlobalMemoryDestroy(GlobalMemory context)
{
- AssertState(MemoryContextEnabled);
- AssertArg(IsA(context,GlobalMemory));
- AssertArg(context != &TopGlobalMemoryData);
-
- AllocSetReset(&context->setData);
-
- /* unlink and delete the context */
- OrderedElemPop(&context->elemData);
- MemoryContextFree(TopMemoryContext, (Pointer)context);
+ AssertState(MemoryContextEnabled);
+ AssertArg(IsA(context, GlobalMemory));
+ AssertArg(context != &TopGlobalMemoryData);
+
+ AllocSetReset(&context->setData);
+
+ /* unlink and delete the context */
+ OrderedElemPop(&context->elemData);
+ MemoryContextFree(TopMemoryContext, (Pointer) context);
}
/*****************************************************************************
- * PRIVATE *
+ * PRIVATE *
*****************************************************************************/
/*
* GlobalMemoryAlloc --
- * Returns pointer to aligned space in the global context.
+ * Returns pointer to aligned space in the global context.
*
* Exceptions:
- * ExhaustedMemory if allocation fails.
+ * ExhaustedMemory if allocation fails.
*/
-static Pointer
+static Pointer
GlobalMemoryAlloc(GlobalMemory this, Size size)
{
- return (AllocSetAlloc(&this->setData, size));
+ return (AllocSetAlloc(&this->setData, size));
}
/*
* GlobalMemoryFree --
- * Frees allocated memory in the global context.
+ * Frees allocated memory in the global context.
*
* Exceptions:
- * BadContextErr if current context is not the global context.
- * BadArgumentsErr if pointer is invalid.
+ * BadContextErr if current context is not the global context.
+ * BadArgumentsErr if pointer is invalid.
*/
static void
GlobalMemoryFree(GlobalMemory this,
- Pointer pointer)
+ Pointer pointer)
{
- AllocSetFree(&this->setData, pointer);
+ AllocSetFree(&this->setData, pointer);
}
/*
* GlobalMemoryRealloc --
- * Returns pointer to aligned space in the global context.
+ * Returns pointer to aligned space in the global context.
*
* Note:
- * Memory associated with the pointer is freed before return.
+ * Memory associated with the pointer is freed before return.
*
* Exceptions:
- * BadContextErr if current context is not the global context.
- * BadArgumentsErr if pointer is invalid.
- * NoMoreMemoryErr if allocation fails.
+ * BadContextErr if current context is not the global context.
+ * BadArgumentsErr if pointer is invalid.
+ * NoMoreMemoryErr if allocation fails.
*/
-static Pointer
+static Pointer
GlobalMemoryRealloc(GlobalMemory this,
- Pointer pointer,
- Size size)
+ Pointer pointer,
+ Size size)
{
- return (AllocSetRealloc(&this->setData, pointer, size));
+ return (AllocSetRealloc(&this->setData, pointer, size));
}
/*
* GlobalMemoryGetName --
- * Returns name string for context.
+ * Returns name string for context.
*
* Exceptions:
- * ???
+ * ???
*/
-static char*
+static char *
GlobalMemoryGetName(GlobalMemory this)
{
- return (this->name);
+ return (this->name);
}
/*
* GlobalMemoryDump --
- * Dumps global memory context for debugging.
+ * Dumps global memory context for debugging.
*
* Exceptions:
- * ???
+ * ???
*/
static void
GlobalMemoryDump(GlobalMemory this)
{
- GlobalMemory context;
-
- printf("--\n%s:\n", GlobalMemoryGetName(this));
-
- context = (GlobalMemory)OrderedElemGetPredecessor(&this->elemData);
- if (PointerIsValid(context)) {
- printf("\tpredecessor=%s\n", GlobalMemoryGetName(context));
- }
-
- context = (GlobalMemory)OrderedElemGetSuccessor(&this->elemData);
- if (PointerIsValid(context)) {
- printf("\tsucessor=%s\n", GlobalMemoryGetName(context));
- }
-
- AllocSetDump(&this->setData); /* XXX is this right interface */
+ GlobalMemory context;
+
+ printf("--\n%s:\n", GlobalMemoryGetName(this));
+
+ context = (GlobalMemory) OrderedElemGetPredecessor(&this->elemData);
+ if (PointerIsValid(context))
+ {
+ printf("\tpredecessor=%s\n", GlobalMemoryGetName(context));
+ }
+
+ context = (GlobalMemory) OrderedElemGetSuccessor(&this->elemData);
+ if (PointerIsValid(context))
+ {
+ printf("\tsucessor=%s\n", GlobalMemoryGetName(context));
+ }
+
+ AllocSetDump(&this->setData); /* XXX is this right interface */
}
/*
* DumpGlobalMemories --
- * Dumps all global memory contexts for debugging.
+ * Dumps all global memory contexts for debugging.
*
* Exceptions:
- * ???
+ * ???
*/
#ifdef NOT_USED
static void
DumpGlobalMemories()
{
- GlobalMemory context;
-
- context = (GlobalMemory)OrderedSetGetHead(&ActiveGlobalMemorySetData);
-
- while (PointerIsValid(context)) {
- GlobalMemoryDump(context);
-
- context = (GlobalMemory)OrderedElemGetSuccessor(
- &context->elemData);
- }
+ GlobalMemory context;
+
+ context = (GlobalMemory) OrderedSetGetHead(&ActiveGlobalMemorySetData);
+
+ while (PointerIsValid(context))
+ {
+ GlobalMemoryDump(context);
+
+ context = (GlobalMemory) OrderedElemGetSuccessor(
+ &context->elemData);
+ }
}
+
#endif
diff --git a/src/backend/utils/mmgr/oset.c b/src/backend/utils/mmgr/oset.c
index 6b42ee45d72..758b701ff55 100644
--- a/src/backend/utils/mmgr/oset.c
+++ b/src/backend/utils/mmgr/oset.c
@@ -1,39 +1,39 @@
/*-------------------------------------------------------------------------
*
* oset.c--
- * Fixed format ordered set definitions.
+ * Fixed format ordered set definitions.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/Attic/oset.c,v 1.3 1997/08/24 23:07:50 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/Attic/oset.c,v 1.4 1997/09/07 04:54:11 momjian Exp $
*
* NOTE
- * XXX This is a preliminary implementation which lacks fail-fast
- * XXX validity checking of arguments.
+ * XXX This is a preliminary implementation which lacks fail-fast
+ * XXX validity checking of arguments.
*
*-------------------------------------------------------------------------
*/
#include "c.h"
-#include "utils/memutils.h" /* where declarations of this file goes */
+#include "utils/memutils.h" /* where declarations of this file goes */
-static Pointer OrderedElemGetBase(OrderedElem elem);
-static void OrderedElemPush(OrderedElem elem);
-static void OrderedElemPushHead(OrderedElem elem);
+static Pointer OrderedElemGetBase(OrderedElem elem);
+static void OrderedElemPush(OrderedElem elem);
+static void OrderedElemPushHead(OrderedElem elem);
/*
* OrderedElemGetBase --
- * Returns base of enclosing structure.
+ * Returns base of enclosing structure.
*/
-static Pointer
+static Pointer
OrderedElemGetBase(OrderedElem elem)
{
- if (elem == (OrderedElem) NULL)
- return (Pointer) NULL;
-
- return ((Pointer)((char*)(elem) - (elem)->set->offset));
+ if (elem == (OrderedElem) NULL)
+ return (Pointer) NULL;
+
+ return ((Pointer) ((char *) (elem) - (elem)->set->offset));
}
/*
@@ -42,20 +42,20 @@ OrderedElemGetBase(OrderedElem elem)
void
OrderedSetInit(OrderedSet set, Offset offset)
{
- set->head = (OrderedElem)&set->dummy;
- set->dummy = NULL;
- set->tail = (OrderedElem)&set->head;
- set->offset = offset;
+ set->head = (OrderedElem) & set->dummy;
+ set->dummy = NULL;
+ set->tail = (OrderedElem) & set->head;
+ set->offset = offset;
}
/*
* OrderedSetContains --
- * True iff ordered set contains given element.
+ * True iff ordered set contains given element.
*/
bool
OrderedSetContains(OrderedSet set, OrderedElem elem)
{
- return ((bool)(elem->set == set && (elem->next || elem->prev)));
+ return ((bool) (elem->set == set && (elem->next || elem->prev)));
}
/*
@@ -64,13 +64,14 @@ OrderedSetContains(OrderedSet set, OrderedElem elem)
Pointer
OrderedSetGetHead(OrderedSet set)
{
- register OrderedElem elem;
-
- elem = set->head;
- if (elem->next) {
- return (OrderedElemGetBase(elem));
- }
- return (NULL);
+ register OrderedElem elem;
+
+ elem = set->head;
+ if (elem->next)
+ {
+ return (OrderedElemGetBase(elem));
+ }
+ return (NULL);
}
/*
@@ -80,14 +81,16 @@ OrderedSetGetHead(OrderedSet set)
Pointer
OrderedSetGetTail(OrderedSet set)
{
- register OrderedElem elem;
-
- elem = set->tail;
- if (elem->prev) {
- return (OrderedElemGetBase(elem));
- }
- return (NULL);
+ register OrderedElem elem;
+
+ elem = set->tail;
+ if (elem->prev)
+ {
+ return (OrderedElemGetBase(elem));
+ }
+ return (NULL);
}
+
#endif
/*
@@ -96,11 +99,12 @@ OrderedSetGetTail(OrderedSet set)
Pointer
OrderedElemGetPredecessor(OrderedElem elem)
{
- elem = elem->prev;
- if (elem->prev) {
- return (OrderedElemGetBase(elem));
- }
- return (NULL);
+ elem = elem->prev;
+ if (elem->prev)
+ {
+ return (OrderedElemGetBase(elem));
+ }
+ return (NULL);
}
/*
@@ -109,24 +113,25 @@ OrderedElemGetPredecessor(OrderedElem elem)
Pointer
OrderedElemGetSuccessor(OrderedElem elem)
{
- elem = elem->next;
- if (elem->next) {
- return (OrderedElemGetBase(elem));
- }
- return (NULL);
+ elem = elem->next;
+ if (elem->next)
+ {
+ return (OrderedElemGetBase(elem));
+ }
+ return (NULL);
}
/*
* OrderedElemPop --
*/
-void
+void
OrderedElemPop(OrderedElem elem)
{
- elem->next->prev = elem->prev;
- elem->prev->next = elem->next;
- /* assignments used only for error detection */
- elem->next = NULL;
- elem->prev = NULL;
+ elem->next->prev = elem->prev;
+ elem->prev->next = elem->next;
+ /* assignments used only for error detection */
+ elem->next = NULL;
+ elem->prev = NULL;
}
/*
@@ -135,11 +140,11 @@ OrderedElemPop(OrderedElem elem)
void
OrderedElemPushInto(OrderedElem elem, OrderedSet set)
{
- elem->set = set;
- /* mark as unattached */
- elem->next = NULL;
- elem->prev = NULL;
- OrderedElemPush(elem);
+ elem->set = set;
+ /* mark as unattached */
+ elem->next = NULL;
+ elem->prev = NULL;
+ OrderedElemPush(elem);
}
/*
@@ -148,7 +153,7 @@ OrderedElemPushInto(OrderedElem elem, OrderedSet set)
static void
OrderedElemPush(OrderedElem elem)
{
- OrderedElemPushHead(elem);
+ OrderedElemPushHead(elem);
}
/*
@@ -157,9 +162,8 @@ OrderedElemPush(OrderedElem elem)
static void
OrderedElemPushHead(OrderedElem elem)
{
- elem->next = elem->set->head;
- elem->prev = (OrderedElem)&elem->set->head;
- elem->next->prev = elem;
- elem->prev->next = elem;
+ elem->next = elem->set->head;
+ elem->prev = (OrderedElem) & elem->set->head;
+ elem->next->prev = elem;
+ elem->prev->next = elem;
}
-
diff --git a/src/backend/utils/mmgr/palloc.c b/src/backend/utils/mmgr/palloc.c
index 8830a21f40a..f644706c911 100644
--- a/src/backend/utils/mmgr/palloc.c
+++ b/src/backend/utils/mmgr/palloc.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* palloc.c--
- * POSTGRES memory allocator code.
+ * POSTGRES memory allocator code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/Attic/palloc.c,v 1.3 1996/11/26 03:19:12 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/Attic/palloc.c,v 1.4 1997/09/07 04:54:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,7 +25,7 @@
#include "utils/palloc.h"
/* ----------------------------------------------------------------
- * User library functions
+ * User library functions
* ----------------------------------------------------------------
*/
@@ -36,84 +36,84 @@
#undef malloc
#undef free
-/* define PALLOC_IS_MALLOC if you want palloc to go straight to the
+/* define PALLOC_IS_MALLOC if you want palloc to go straight to the
raw malloc, without concern for the extra bookkeeping needed to
ensure garbage is collected at the end of transactions - jolly 1/12/94 */
/*
* palloc --
- * Returns pointer to aligned memory of specified size.
+ * Returns pointer to aligned memory of specified size.
*
* Exceptions:
- * BadArgument if size < 1 or size >= MaxAllocSize.
- * ExhaustedMemory if allocation fails.
- * NonallocatedPointer if pointer was not returned by palloc or repalloc
- * or may have been freed already.
+ * BadArgument if size < 1 or size >= MaxAllocSize.
+ * ExhaustedMemory if allocation fails.
+ * NonallocatedPointer if pointer was not returned by palloc or repalloc
+ * or may have been freed already.
*
* pfree --
- * Frees memory associated with pointer returned from palloc or repalloc.
+ * Frees memory associated with pointer returned from palloc or repalloc.
*
* Exceptions:
- * BadArgument if pointer is invalid.
- * FreeInWrongContext if pointer was allocated in a different "context."
- * NonallocatedPointer if pointer was not returned by palloc or repalloc
- * or may have been subsequently freed.
+ * BadArgument if pointer is invalid.
+ * FreeInWrongContext if pointer was allocated in a different "context."
+ * NonallocatedPointer if pointer was not returned by palloc or repalloc
+ * or may have been subsequently freed.
*/
-void*
+void *
palloc(Size size)
{
#ifdef PALLOC_IS_MALLOC
- return malloc(size);
+ return malloc(size);
#else
- return (MemoryContextAlloc(CurrentMemoryContext, size));
-#endif /* PALLOC_IS_MALLOC */
+ return (MemoryContextAlloc(CurrentMemoryContext, size));
+#endif /* PALLOC_IS_MALLOC */
}
void
pfree(void *pointer)
-{
+{
#ifdef PALLOC_IS_MALLOC
- free(pointer);
+ free(pointer);
#else
- MemoryContextFree(CurrentMemoryContext, pointer);
-#endif /* PALLOC_IS_MALLOC */
+ MemoryContextFree(CurrentMemoryContext, pointer);
+#endif /* PALLOC_IS_MALLOC */
}
/*
* repalloc --
- * Returns pointer to aligned memory of specified size.
+ * Returns pointer to aligned memory of specified size.
*
* Side effects:
- * The returned memory is first filled with the contents of *pointer
- * up to the minimum of size and psize(pointer). Pointer is freed.
+ * The returned memory is first filled with the contents of *pointer
+ * up to the minimum of size and psize(pointer). Pointer is freed.
*
* Exceptions:
- * BadArgument if pointer is invalid or size < 1 or size >= MaxAllocSize.
- * ExhaustedMemory if allocation fails.
- * NonallocatedPointer if pointer was not returned by palloc or repalloc
- * or may have been freed already.
+ * BadArgument if pointer is invalid or size < 1 or size >= MaxAllocSize.
+ * ExhaustedMemory if allocation fails.
+ * NonallocatedPointer if pointer was not returned by palloc or repalloc
+ * or may have been freed already.
*/
-void *
+void *
repalloc(void *pointer, Size size)
{
#ifdef PALLOC_IS_MALLOC
- return realloc(pointer, size);
+ return realloc(pointer, size);
#else
- return (MemoryContextRealloc(CurrentMemoryContext, pointer, size));
+ return (MemoryContextRealloc(CurrentMemoryContext, pointer, size));
#endif
}
-/* pstrdup
- allocates space for and copies a string
- just like strdup except it uses palloc instead of malloc */
-char*
-pstrdup(char* string)
+/* pstrdup
+ allocates space for and copies a string
+ just like strdup except it uses palloc instead of malloc */
+char *
+pstrdup(char *string)
{
- char *nstr;
+ char *nstr;
- nstr = (char *)palloc(strlen(string)+1);
- strcpy(nstr, string);
+ nstr = (char *) palloc(strlen(string) + 1);
+ strcpy(nstr, string);
- return nstr;
+ return nstr;
}
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 7f1674d88db..595153b0ce6 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -1,86 +1,86 @@
/*-------------------------------------------------------------------------
*
* portalmem.c--
- * backend portal memory context management stuff
+ * backend portal memory context management stuff
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.5 1997/08/19 21:36:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.6 1997/09/07 04:54:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* NOTES
- * Do not confuse "Portal" with "PortalEntry" (or "PortalBuffer").
- * When a PQexec() routine is run, the resulting tuples
- * find their way into a "PortalEntry". The contents of the resulting
- * "PortalEntry" can then be inspected by other PQxxx functions.
- *
- * A "Portal" is a structure used to keep track of queries of the
- * form:
- * retrieve portal FOO ( blah... ) where blah...
- *
- * When the backend sees a "retrieve portal" query, it allocates
- * a "PortalD" structure, plans the query and then stores the query
- * in the portal without executing it. Later, when the backend
- * sees a
- * fetch 1 into FOO
- *
- * the system looks up the portal named "FOO" in the portal table,
- * gets the planned query and then calls the executor with a feature of
- * '(EXEC_FOR 1). The executor then runs the query and returns a single
- * tuple. The problem is that we have to hold onto the state of the
- * portal query until we see a "close p". This means we have to be
- * careful about memory management.
- *
- * Having said all that, here is what a PortalD currently looks like:
+ * Do not confuse "Portal" with "PortalEntry" (or "PortalBuffer").
+ * When a PQexec() routine is run, the resulting tuples
+ * find their way into a "PortalEntry". The contents of the resulting
+ * "PortalEntry" can then be inspected by other PQxxx functions.
+ *
+ * A "Portal" is a structure used to keep track of queries of the
+ * form:
+ * retrieve portal FOO ( blah... ) where blah...
+ *
+ * When the backend sees a "retrieve portal" query, it allocates
+ * a "PortalD" structure, plans the query and then stores the query
+ * in the portal without executing it. Later, when the backend
+ * sees a
+ * fetch 1 into FOO
+ *
+ * the system looks up the portal named "FOO" in the portal table,
+ * gets the planned query and then calls the executor with a feature of
+ * '(EXEC_FOR 1). The executor then runs the query and returns a single
+ * tuple. The problem is that we have to hold onto the state of the
+ * portal query until we see a "close p". This means we have to be
+ * careful about memory management.
+ *
+ * Having said all that, here is what a PortalD currently looks like:
*
* struct PortalD {
- * char* name;
- * classObj(PortalVariableMemory) variable;
- * classObj(PortalHeapMemory) heap;
- * List queryDesc;
- * EState state;
- * void (*cleanup) ARGS((Portal portal));
+ * char* name;
+ * classObj(PortalVariableMemory) variable;
+ * classObj(PortalHeapMemory) heap;
+ * List queryDesc;
+ * EState state;
+ * void (*cleanup) ARGS((Portal portal));
* };
*
- * I hope this makes things clearer to whoever reads this -cim 2/22/91
+ * I hope this makes things clearer to whoever reads this -cim 2/22/91
*
- * Here is an old comment taken from nodes/memnodes.h
+ * Here is an old comment taken from nodes/memnodes.h
*
* MemoryContext --
- * A logical context in which memory allocations occur.
+ * A logical context in which memory allocations occur.
*
* The types of memory contexts can be thought of as members of the
* following inheritance hierarchy with properties summarized below.
*
- * Node
- * |
- * MemoryContext___
- * / \
- * GlobalMemory PortalMemoryContext
- * / \
- * PortalVariableMemory PortalHeapMemory
+ * Node
+ * |
+ * MemoryContext___
+ * / \
+ * GlobalMemory PortalMemoryContext
+ * / \
+ * PortalVariableMemory PortalHeapMemory
*
- * Flushed at Flushed at Checkpoints
- * Transaction Portal
- * Commit Close
+ * Flushed at Flushed at Checkpoints
+ * Transaction Portal
+ * Commit Close
*
- * GlobalMemory n n n
- * PortalVariableMemory n y n
- * PortalHeapMemory y y y *
+ * GlobalMemory n n n
+ * PortalVariableMemory n y n
+ * PortalHeapMemory y y y *
*
*/
-#include <stdio.h> /* for sprintf() */
-#include <string.h> /* for strlen, strncpy */
+#include <stdio.h> /* for sprintf() */
+#include <string.h> /* for strlen, strncpy */
#include "postgres.h"
#include "lib/hasht.h"
#include "utils/module.h"
-#include "utils/excid.h" /* for Unimplemented */
+#include "utils/excid.h" /* for Unimplemented */
#include "utils/mcxt.h"
#include "utils/hsearch.h"
@@ -91,324 +91,330 @@
#include "utils/portal.h"
-static void CollectNamedPortals(Portal *portalP, int destroy);
-static Portal PortalHeapMemoryGetPortal(PortalHeapMemory context);
+static void CollectNamedPortals(Portal * portalP, int destroy);
+static Portal PortalHeapMemoryGetPortal(PortalHeapMemory context);
static PortalVariableMemory PortalHeapMemoryGetVariableMemory(PortalHeapMemory context);
-static void PortalResetHeapMemory(Portal portal);
-static Portal PortalVariableMemoryGetPortal(PortalVariableMemory context);
+static void PortalResetHeapMemory(Portal portal);
+static Portal PortalVariableMemoryGetPortal(PortalVariableMemory context);
/* ----------------
- * ALLOCFREE_ERROR_ABORT
- * define this if you want a core dump when you try to
- * free memory already freed -cim 2/9/91
+ * ALLOCFREE_ERROR_ABORT
+ * define this if you want a core dump when you try to
+ * free memory already freed -cim 2/9/91
* ----------------
*/
#undef ALLOCFREE_ERROR_ABORT
/* ----------------
- * Global state
+ * Global state
* ----------------
*/
-static int PortalManagerEnableCount = 0;
-#define MAX_PORTALNAME_LEN 64 /* XXX LONGALIGNable value */
+static int PortalManagerEnableCount = 0;
-typedef struct portalhashent {
- char portalname[MAX_PORTALNAME_LEN];
- Portal portal;
-} PortalHashEnt;
+#define MAX_PORTALNAME_LEN 64 /* XXX LONGALIGNable value */
+
+typedef struct portalhashent
+{
+ char portalname[MAX_PORTALNAME_LEN];
+ Portal portal;
+} PortalHashEnt;
#define PortalManagerEnabled (PortalManagerEnableCount >= 1)
-static HTAB *PortalHashTable = NULL;
+static HTAB *PortalHashTable = NULL;
+
#define PortalHashTableLookup(NAME, PORTAL) \
- { PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
- memset(key, 0, MAX_PORTALNAME_LEN); \
- sprintf(key, "%s", NAME); \
- hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
- key, HASH_FIND, &found); \
- if (hentry == NULL) \
- elog(FATAL, "error in PortalHashTable"); \
- if (found) \
- PORTAL = hentry->portal; \
- else \
- PORTAL = NULL; \
- }
+ { PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
+ memset(key, 0, MAX_PORTALNAME_LEN); \
+ sprintf(key, "%s", NAME); \
+ hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
+ key, HASH_FIND, &found); \
+ if (hentry == NULL) \
+ elog(FATAL, "error in PortalHashTable"); \
+ if (found) \
+ PORTAL = hentry->portal; \
+ else \
+ PORTAL = NULL; \
+ }
#define PortalHashTableInsert(PORTAL) \
- { PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
- memset(key, 0, MAX_PORTALNAME_LEN); \
- sprintf(key, "%s", PORTAL->name); \
- hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
- key, HASH_ENTER, &found); \
- if (hentry == NULL) \
- elog(FATAL, "error in PortalHashTable"); \
- if (found) \
- elog(NOTICE, "trying to insert a portal name that exists."); \
- hentry->portal = PORTAL; \
- }
+ { PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
+ memset(key, 0, MAX_PORTALNAME_LEN); \
+ sprintf(key, "%s", PORTAL->name); \
+ hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
+ key, HASH_ENTER, &found); \
+ if (hentry == NULL) \
+ elog(FATAL, "error in PortalHashTable"); \
+ if (found) \
+ elog(NOTICE, "trying to insert a portal name that exists."); \
+ hentry->portal = PORTAL; \
+ }
#define PortalHashTableDelete(PORTAL) \
- { PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
- memset(key, 0, MAX_PORTALNAME_LEN); \
- sprintf(key, "%s", PORTAL->name); \
- hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
- key, HASH_REMOVE, &found); \
- if (hentry == NULL) \
- elog(FATAL, "error in PortalHashTable"); \
- if (!found) \
- elog(NOTICE, "trying to delete portal name that does not exist."); \
- }
-
-static GlobalMemory PortalMemory = NULL;
+ { PortalHashEnt *hentry; bool found; char key[MAX_PORTALNAME_LEN]; \
+ memset(key, 0, MAX_PORTALNAME_LEN); \
+ sprintf(key, "%s", PORTAL->name); \
+ hentry = (PortalHashEnt*)hash_search(PortalHashTable, \
+ key, HASH_REMOVE, &found); \
+ if (hentry == NULL) \
+ elog(FATAL, "error in PortalHashTable"); \
+ if (!found) \
+ elog(NOTICE, "trying to delete portal name that does not exist."); \
+ }
+
+static GlobalMemory PortalMemory = NULL;
static char PortalMemoryName[] = "Portal";
-static Portal BlankPortal = NULL;
+static Portal BlankPortal = NULL;
/* ----------------
- * Internal class definitions
+ * Internal class definitions
* ----------------
*/
-typedef struct HeapMemoryBlockData {
- AllocSetData setData;
- FixedItemData itemData;
-} HeapMemoryBlockData;
+typedef struct HeapMemoryBlockData
+{
+ AllocSetData setData;
+ FixedItemData itemData;
+} HeapMemoryBlockData;
-typedef HeapMemoryBlockData *HeapMemoryBlock;
+typedef HeapMemoryBlockData *HeapMemoryBlock;
#define HEAPMEMBLOCK(context) \
- ((HeapMemoryBlock)(context)->block)
+ ((HeapMemoryBlock)(context)->block)
/* ----------------------------------------------------------------
- * Variable and heap memory methods
+ * Variable and heap memory methods
* ----------------------------------------------------------------
*/
/* ----------------
- * PortalVariableMemoryAlloc
+ * PortalVariableMemoryAlloc
* ----------------
*/
-static Pointer
+static Pointer
PortalVariableMemoryAlloc(PortalVariableMemory this,
- Size size)
+ Size size)
{
- return (AllocSetAlloc(&this->setData, size));
+ return (AllocSetAlloc(&this->setData, size));
}
/* ----------------
- * PortalVariableMemoryFree
+ * PortalVariableMemoryFree
* ----------------
*/
static void
PortalVariableMemoryFree(PortalVariableMemory this,
- Pointer pointer)
+ Pointer pointer)
{
- AllocSetFree(&this->setData, pointer);
+ AllocSetFree(&this->setData, pointer);
}
/* ----------------
- * PortalVariableMemoryRealloc
+ * PortalVariableMemoryRealloc
* ----------------
*/
-static Pointer
+static Pointer
PortalVariableMemoryRealloc(PortalVariableMemory this,
- Pointer pointer,
- Size size)
+ Pointer pointer,
+ Size size)
{
- return (AllocSetRealloc(&this->setData, pointer, size));
+ return (AllocSetRealloc(&this->setData, pointer, size));
}
/* ----------------
- * PortalVariableMemoryGetName
+ * PortalVariableMemoryGetName
* ----------------
*/
-static char*
+static char *
PortalVariableMemoryGetName(PortalVariableMemory this)
{
- return (form("%s-var", PortalVariableMemoryGetPortal(this)->name));
+ return (form("%s-var", PortalVariableMemoryGetPortal(this)->name));
}
/* ----------------
- * PortalVariableMemoryDump
+ * PortalVariableMemoryDump
* ----------------
*/
static void
PortalVariableMemoryDump(PortalVariableMemory this)
{
- printf("--\n%s:\n", PortalVariableMemoryGetName(this));
-
- AllocSetDump(&this->setData); /* XXX is this the right interface */
+ printf("--\n%s:\n", PortalVariableMemoryGetName(this));
+
+ AllocSetDump(&this->setData); /* XXX is this the right interface */
}
/* ----------------
- * PortalHeapMemoryAlloc
+ * PortalHeapMemoryAlloc
* ----------------
*/
-static Pointer
+static Pointer
PortalHeapMemoryAlloc(PortalHeapMemory this,
- Size size)
+ Size size)
{
- HeapMemoryBlock block = HEAPMEMBLOCK(this);
-
- AssertState(PointerIsValid(block));
-
- return (AllocSetAlloc(&block->setData, size));
+ HeapMemoryBlock block = HEAPMEMBLOCK(this);
+
+ AssertState(PointerIsValid(block));
+
+ return (AllocSetAlloc(&block->setData, size));
}
/* ----------------
- * PortalHeapMemoryFree
+ * PortalHeapMemoryFree
* ----------------
*/
static void
PortalHeapMemoryFree(PortalHeapMemory this,
- Pointer pointer)
-{
- HeapMemoryBlock block = HEAPMEMBLOCK(this);
-
- AssertState(PointerIsValid(block));
-
- if (AllocSetContains(&block->setData, pointer))
- AllocSetFree(&block->setData, pointer);
- else {
- elog(NOTICE,
- "PortalHeapMemoryFree: 0x%x not in alloc set!",
- pointer);
+ Pointer pointer)
+{
+ HeapMemoryBlock block = HEAPMEMBLOCK(this);
+
+ AssertState(PointerIsValid(block));
+
+ if (AllocSetContains(&block->setData, pointer))
+ AllocSetFree(&block->setData, pointer);
+ else
+ {
+ elog(NOTICE,
+ "PortalHeapMemoryFree: 0x%x not in alloc set!",
+ pointer);
#ifdef ALLOCFREE_ERROR_ABORT
- Assert(AllocSetContains(&block->setData, pointer));
-#endif /* ALLOCFREE_ERROR_ABORT*/
- }
+ Assert(AllocSetContains(&block->setData, pointer));
+#endif /* ALLOCFREE_ERROR_ABORT */
+ }
}
/* ----------------
- * PortalHeapMemoryRealloc
+ * PortalHeapMemoryRealloc
* ----------------
*/
-static Pointer
+static Pointer
PortalHeapMemoryRealloc(PortalHeapMemory this,
- Pointer pointer,
- Size size)
+ Pointer pointer,
+ Size size)
{
- HeapMemoryBlock block = HEAPMEMBLOCK(this);
-
- AssertState(PointerIsValid(block));
-
- return (AllocSetRealloc(&block->setData, pointer, size));
+ HeapMemoryBlock block = HEAPMEMBLOCK(this);
+
+ AssertState(PointerIsValid(block));
+
+ return (AllocSetRealloc(&block->setData, pointer, size));
}
/* ----------------
- * PortalHeapMemoryGetName
+ * PortalHeapMemoryGetName
* ----------------
*/
-static char*
+static char *
PortalHeapMemoryGetName(PortalHeapMemory this)
{
- return (form("%s-heap", PortalHeapMemoryGetPortal(this)->name));
+ return (form("%s-heap", PortalHeapMemoryGetPortal(this)->name));
}
/* ----------------
- * PortalHeapMemoryDump
+ * PortalHeapMemoryDump
* ----------------
*/
static void
PortalHeapMemoryDump(PortalHeapMemory this)
{
- HeapMemoryBlock block;
-
- printf("--\n%s:\n", PortalHeapMemoryGetName(this));
-
- /* XXX is this the right interface */
- if (PointerIsValid(this->block))
- AllocSetDump(&HEAPMEMBLOCK(this)->setData);
-
- /* dump the stack too */
- for (block = (HeapMemoryBlock)FixedStackGetTop(&this->stackData);
- PointerIsValid(block);
- block = (HeapMemoryBlock)
- FixedStackGetNext(&this->stackData, (Pointer)block)) {
-
- printf("--\n");
- AllocSetDump(&block->setData);
- }
+ HeapMemoryBlock block;
+
+ printf("--\n%s:\n", PortalHeapMemoryGetName(this));
+
+ /* XXX is this the right interface */
+ if (PointerIsValid(this->block))
+ AllocSetDump(&HEAPMEMBLOCK(this)->setData);
+
+ /* dump the stack too */
+ for (block = (HeapMemoryBlock) FixedStackGetTop(&this->stackData);
+ PointerIsValid(block);
+ block = (HeapMemoryBlock)
+ FixedStackGetNext(&this->stackData, (Pointer) block))
+ {
+
+ printf("--\n");
+ AllocSetDump(&block->setData);
+ }
}
/* ----------------------------------------------------------------
- * variable / heap context method tables
+ * variable / heap context method tables
* ----------------------------------------------------------------
*/
-static struct MemoryContextMethodsData PortalVariableContextMethodsData = {
- PortalVariableMemoryAlloc, /* Pointer (*)(this, uint32) palloc */
- PortalVariableMemoryFree, /* void (*)(this, Pointer) pfree */
- PortalVariableMemoryRealloc,/* Pointer (*)(this, Pointer) repalloc */
- PortalVariableMemoryGetName,/* char* (*)(this) getName */
- PortalVariableMemoryDump /* void (*)(this) dump */
+static struct MemoryContextMethodsData PortalVariableContextMethodsData = {
+ PortalVariableMemoryAlloc, /* Pointer (*)(this, uint32) palloc */
+ PortalVariableMemoryFree, /* void (*)(this, Pointer) pfree */
+ PortalVariableMemoryRealloc,/* Pointer (*)(this, Pointer) repalloc */
+ PortalVariableMemoryGetName,/* char* (*)(this) getName */
+ PortalVariableMemoryDump /* void (*)(this) dump */
};
-static struct MemoryContextMethodsData PortalHeapContextMethodsData = {
- PortalHeapMemoryAlloc, /* Pointer (*)(this, uint32) palloc */
- PortalHeapMemoryFree, /* void (*)(this, Pointer) pfree */
- PortalHeapMemoryRealloc, /* Pointer (*)(this, Pointer) repalloc */
- PortalHeapMemoryGetName, /* char* (*)(this) getName */
- PortalHeapMemoryDump /* void (*)(this) dump */
+static struct MemoryContextMethodsData PortalHeapContextMethodsData = {
+ PortalHeapMemoryAlloc, /* Pointer (*)(this, uint32) palloc */
+ PortalHeapMemoryFree, /* void (*)(this, Pointer) pfree */
+ PortalHeapMemoryRealloc, /* Pointer (*)(this, Pointer) repalloc */
+ PortalHeapMemoryGetName, /* char* (*)(this) getName */
+ PortalHeapMemoryDump /* void (*)(this) dump */
};
/* ----------------------------------------------------------------
- * private internal support routines
+ * private internal support routines
* ----------------------------------------------------------------
*/
/* ----------------
- * CreateNewBlankPortal
+ * CreateNewBlankPortal
* ----------------
*/
static void
CreateNewBlankPortal()
{
- Portal portal;
-
- AssertState(!PortalIsValid(BlankPortal));
-
- /*
- * make new portal structure
- */
- portal = (Portal)
- MemoryContextAlloc((MemoryContext)PortalMemory, sizeof *portal);
-
- /*
- * initialize portal variable context
- */
- NodeSetTag((Node*)&portal->variable, T_PortalVariableMemory);
- AllocSetInit(&portal->variable.setData, DynamicAllocMode, (Size)0);
- portal->variable.method = &PortalVariableContextMethodsData;
-
- /*
- * initialize portal heap context
- */
- NodeSetTag((Node*)&portal->heap, T_PortalHeapMemory);
- portal->heap.block = NULL;
- FixedStackInit(&portal->heap.stackData,
- offsetof (HeapMemoryBlockData, itemData));
- portal->heap.method = &PortalHeapContextMethodsData;
-
- /*
- * set bogus portal name
- */
- portal->name = "** Blank Portal **";
-
- /* initialize portal query */
- portal->queryDesc = NULL;
- portal->attinfo = NULL;
- portal->state = NULL;
- portal->cleanup = NULL;
-
- /*
- * install blank portal
- */
- BlankPortal = portal;
+ Portal portal;
+
+ AssertState(!PortalIsValid(BlankPortal));
+
+ /*
+ * make new portal structure
+ */
+ portal = (Portal)
+ MemoryContextAlloc((MemoryContext) PortalMemory, sizeof *portal);
+
+ /*
+ * initialize portal variable context
+ */
+ NodeSetTag((Node *) & portal->variable, T_PortalVariableMemory);
+ AllocSetInit(&portal->variable.setData, DynamicAllocMode, (Size) 0);
+ portal->variable.method = &PortalVariableContextMethodsData;
+
+ /*
+ * initialize portal heap context
+ */
+ NodeSetTag((Node *) & portal->heap, T_PortalHeapMemory);
+ portal->heap.block = NULL;
+ FixedStackInit(&portal->heap.stackData,
+ offsetof(HeapMemoryBlockData, itemData));
+ portal->heap.method = &PortalHeapContextMethodsData;
+
+ /*
+ * set bogus portal name
+ */
+ portal->name = "** Blank Portal **";
+
+ /* initialize portal query */
+ portal->queryDesc = NULL;
+ portal->attinfo = NULL;
+ portal->state = NULL;
+ portal->cleanup = NULL;
+
+ /*
+ * install blank portal
+ */
+ BlankPortal = portal;
}
bool
PortalNameIsSpecial(char *pname)
{
- if (strcmp(pname, VACPNAME) == 0)
- return true;
- return false;
+ if (strcmp(pname, VACPNAME) == 0)
+ return true;
+ return false;
}
/*
@@ -420,572 +426,586 @@ PortalNameIsSpecial(char *pname)
* and screws up the sequential walk of the table). -mer 17 Aug 1992
*/
static void
-CollectNamedPortals(Portal *portalP, int destroy)
-{
- static Portal *portalList = (Portal *)NULL;
- static int listIndex = 0;
- static int maxIndex = 9;
-
- if (portalList == (Portal *)NULL)
- portalList = (Portal *)malloc(10*sizeof(Portal));
-
- if (destroy != 0)
+CollectNamedPortals(Portal * portalP, int destroy)
+{
+ static Portal *portalList = (Portal *) NULL;
+ static int listIndex = 0;
+ static int maxIndex = 9;
+
+ if (portalList == (Portal *) NULL)
+ portalList = (Portal *) malloc(10 * sizeof(Portal));
+
+ if (destroy != 0)
{
- int i;
-
- for (i = 0; i < listIndex; i++)
- PortalDestroy(&portalList[i]);
- listIndex = 0;
+ int i;
+
+ for (i = 0; i < listIndex; i++)
+ PortalDestroy(&portalList[i]);
+ listIndex = 0;
}
- else
+ else
{
- Assert(portalP);
- Assert(*portalP);
-
- /*
- * Don't delete special portals, up to portal creator to do this
- */
- if (PortalNameIsSpecial((*portalP)->name))
- return;
-
- portalList[listIndex] = *portalP;
- listIndex++;
- if (listIndex == maxIndex)
+ Assert(portalP);
+ Assert(*portalP);
+
+ /*
+ * Don't delete special portals, up to portal creator to do this
+ */
+ if (PortalNameIsSpecial((*portalP)->name))
+ return;
+
+ portalList[listIndex] = *portalP;
+ listIndex++;
+ if (listIndex == maxIndex)
{
- portalList = (Portal *)
- realloc(portalList, (maxIndex+11)*sizeof(Portal));
- maxIndex += 10;
+ portalList = (Portal *)
+ realloc(portalList, (maxIndex + 11) * sizeof(Portal));
+ maxIndex += 10;
}
}
- return;
+ return;
}
void
AtEOXact_portals()
{
- HashTableWalk(PortalHashTable, CollectNamedPortals, 0);
- CollectNamedPortals(NULL, 1);
+ HashTableWalk(PortalHashTable, CollectNamedPortals, 0);
+ CollectNamedPortals(NULL, 1);
}
/* ----------------
- * PortalDump
+ * PortalDump
* ----------------
*/
#ifdef NOT_USED
static void
-PortalDump(Portal *thisP)
+PortalDump(Portal * thisP)
{
- /* XXX state/argument checking here */
-
- PortalVariableMemoryDump(PortalGetVariableMemory(*thisP));
- PortalHeapMemoryDump(PortalGetHeapMemory(*thisP));
+ /* XXX state/argument checking here */
+
+ PortalVariableMemoryDump(PortalGetVariableMemory(*thisP));
+ PortalHeapMemoryDump(PortalGetHeapMemory(*thisP));
}
+
#endif
/* ----------------
- * DumpPortals
+ * DumpPortals
* ----------------
*/
#ifdef NOT_USED
static void
DumpPortals()
{
- /* XXX state checking here */
-
- HashTableWalk(PortalHashTable, PortalDump, 0);
+ /* XXX state checking here */
+
+ HashTableWalk(PortalHashTable, PortalDump, 0);
}
+
#endif
-
+
/* ----------------------------------------------------------------
- * public portal interface functions
+ * public portal interface functions
* ----------------------------------------------------------------
*/
/*
* EnablePortalManager --
- * Enables/disables the portal management module.
+ * Enables/disables the portal management module.
*/
void
EnablePortalManager(bool on)
{
- static bool processing = false;
- HASHCTL ctl;
-
- AssertState(!processing);
- AssertArg(BoolIsValid(on));
-
- if (BypassEnable(&PortalManagerEnableCount, on))
- return;
-
- processing = true;
-
- if (on) { /* initialize */
- EnableMemoryContext(true);
-
- PortalMemory = CreateGlobalMemory(PortalMemoryName);
-
- ctl.keysize = MAX_PORTALNAME_LEN;
- ctl.datasize = sizeof(Portal);
-
- /* use PORTALS_PER_USER, defined in utils/portal.h
- * as a guess of how many hash table entries to create, initially
- */
- PortalHashTable = hash_create(PORTALS_PER_USER * 3, &ctl, HASH_ELEM);
-
- CreateNewBlankPortal();
-
- } else { /* cleanup */
- if (PortalIsValid(BlankPortal)) {
- PortalDestroy(&BlankPortal);
- MemoryContextFree((MemoryContext)PortalMemory,
- (Pointer)BlankPortal);
- BlankPortal = NULL;
+ static bool processing = false;
+ HASHCTL ctl;
+
+ AssertState(!processing);
+ AssertArg(BoolIsValid(on));
+
+ if (BypassEnable(&PortalManagerEnableCount, on))
+ return;
+
+ processing = true;
+
+ if (on)
+ { /* initialize */
+ EnableMemoryContext(true);
+
+ PortalMemory = CreateGlobalMemory(PortalMemoryName);
+
+ ctl.keysize = MAX_PORTALNAME_LEN;
+ ctl.datasize = sizeof(Portal);
+
+ /*
+ * use PORTALS_PER_USER, defined in utils/portal.h as a guess of
+ * how many hash table entries to create, initially
+ */
+ PortalHashTable = hash_create(PORTALS_PER_USER * 3, &ctl, HASH_ELEM);
+
+ CreateNewBlankPortal();
+
}
- /*
- * Each portal must free its non-memory resources specially.
- */
- HashTableWalk(PortalHashTable, PortalDestroy, 0);
- hash_destroy(PortalHashTable);
- PortalHashTable = NULL;
-
- GlobalMemoryDestroy(PortalMemory);
- PortalMemory = NULL;
-
- EnableMemoryContext(true);
- }
-
- processing = false;
+ else
+ { /* cleanup */
+ if (PortalIsValid(BlankPortal))
+ {
+ PortalDestroy(&BlankPortal);
+ MemoryContextFree((MemoryContext) PortalMemory,
+ (Pointer) BlankPortal);
+ BlankPortal = NULL;
+ }
+
+ /*
+ * Each portal must free its non-memory resources specially.
+ */
+ HashTableWalk(PortalHashTable, PortalDestroy, 0);
+ hash_destroy(PortalHashTable);
+ PortalHashTable = NULL;
+
+ GlobalMemoryDestroy(PortalMemory);
+ PortalMemory = NULL;
+
+ EnableMemoryContext(true);
+ }
+
+ processing = false;
}
/*
* GetPortalByName --
- * Returns a portal given a portal name; returns blank portal given
+ * Returns a portal given a portal name; returns blank portal given
* NULL; returns invalid portal if portal not found.
*
* Exceptions:
- * BadState if called when disabled.
+ * BadState if called when disabled.
*/
Portal
GetPortalByName(char *name)
{
- Portal portal;
-
- AssertState(PortalManagerEnabled);
-
- if (PointerIsValid(name)) {
- PortalHashTableLookup(name, portal);
- }
- else {
- if (!PortalIsValid(BlankPortal))
- CreateNewBlankPortal();
- portal = BlankPortal;
- }
-
- return (portal);
+ Portal portal;
+
+ AssertState(PortalManagerEnabled);
+
+ if (PointerIsValid(name))
+ {
+ PortalHashTableLookup(name, portal);
+ }
+ else
+ {
+ if (!PortalIsValid(BlankPortal))
+ CreateNewBlankPortal();
+ portal = BlankPortal;
+ }
+
+ return (portal);
}
/*
* BlankPortalAssignName --
- * Returns former blank portal as portal with given name.
+ * Returns former blank portal as portal with given name.
*
* Side effect:
- * All references to the former blank portal become incorrect.
+ * All references to the former blank portal become incorrect.
*
* Exceptions:
- * BadState if called when disabled.
- * BadState if called without an intervening call to GetPortalByName(NULL).
- * BadArg if portal name is invalid.
- * "WARN" if portal name is in use.
+ * BadState if called when disabled.
+ * BadState if called without an intervening call to GetPortalByName(NULL).
+ * BadArg if portal name is invalid.
+ * "WARN" if portal name is in use.
*/
Portal
-BlankPortalAssignName(char *name) /* XXX PortalName */
-{
- Portal portal;
- uint16 length;
-
- AssertState(PortalManagerEnabled);
- AssertState(PortalIsValid(BlankPortal));
- AssertArg(PointerIsValid(name)); /* XXX PortalName */
-
- portal = GetPortalByName(name);
- if (PortalIsValid(portal)) {
- elog(NOTICE, "BlankPortalAssignName: portal %s already exists", name);
+BlankPortalAssignName(char *name) /* XXX PortalName */
+{
+ Portal portal;
+ uint16 length;
+
+ AssertState(PortalManagerEnabled);
+ AssertState(PortalIsValid(BlankPortal));
+ AssertArg(PointerIsValid(name)); /* XXX PortalName */
+
+ portal = GetPortalByName(name);
+ if (PortalIsValid(portal))
+ {
+ elog(NOTICE, "BlankPortalAssignName: portal %s already exists", name);
+ return (portal);
+ }
+
+ /*
+ * remove blank portal
+ */
+ portal = BlankPortal;
+ BlankPortal = NULL;
+
+ /*
+ * initialize portal name
+ */
+ length = 1 + strlen(name);
+ portal->name = (char *)
+ MemoryContextAlloc((MemoryContext) & portal->variable, length);
+
+ strncpy(portal->name, name, length);
+
+ /*
+ * put portal in table
+ */
+ PortalHashTableInsert(portal);
+
return (portal);
- }
-
- /*
- * remove blank portal
- */
- portal = BlankPortal;
- BlankPortal = NULL;
-
- /*
- * initialize portal name
- */
- length = 1 + strlen(name);
- portal->name = (char*)
- MemoryContextAlloc((MemoryContext)&portal->variable, length);
-
- strncpy(portal->name, name, length);
-
- /*
- * put portal in table
- */
- PortalHashTableInsert(portal);
-
- return (portal);
}
/*
* PortalSetQuery --
- * Attaches a "query" to portal.
+ * Attaches a "query" to portal.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if portal is invalid.
- * BadArg if queryDesc is "invalid."
- * BadArg if state is "invalid."
+ * BadState if called when disabled.
+ * BadArg if portal is invalid.
+ * BadArg if queryDesc is "invalid."
+ * BadArg if state is "invalid."
*/
void
PortalSetQuery(Portal portal,
- QueryDesc *queryDesc,
- TupleDesc attinfo,
- EState *state,
- void (*cleanup)(Portal portal))
+ QueryDesc * queryDesc,
+ TupleDesc attinfo,
+ EState * state,
+ void (*cleanup) (Portal portal))
{
- AssertState(PortalManagerEnabled);
- AssertArg(PortalIsValid(portal));
- AssertArg(IsA((Node*)state,EState));
-
- portal->queryDesc = queryDesc;
- portal->state = state;
- portal->attinfo = attinfo;
- portal->cleanup = cleanup;
+ AssertState(PortalManagerEnabled);
+ AssertArg(PortalIsValid(portal));
+ AssertArg(IsA((Node *) state, EState));
+
+ portal->queryDesc = queryDesc;
+ portal->state = state;
+ portal->attinfo = attinfo;
+ portal->cleanup = cleanup;
}
/*
* PortalGetQueryDesc --
- * Returns query attached to portal.
+ * Returns query attached to portal.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if portal is invalid.
+ * BadState if called when disabled.
+ * BadArg if portal is invalid.
*/
-QueryDesc *
+QueryDesc *
PortalGetQueryDesc(Portal portal)
{
- AssertState(PortalManagerEnabled);
- AssertArg(PortalIsValid(portal));
-
- return (portal->queryDesc);
+ AssertState(PortalManagerEnabled);
+ AssertArg(PortalIsValid(portal));
+
+ return (portal->queryDesc);
}
/*
* PortalGetState --
- * Returns state attached to portal.
+ * Returns state attached to portal.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if portal is invalid.
+ * BadState if called when disabled.
+ * BadArg if portal is invalid.
*/
-EState *
+EState *
PortalGetState(Portal portal)
{
- AssertState(PortalManagerEnabled);
- AssertArg(PortalIsValid(portal));
-
- return (portal->state);
+ AssertState(PortalManagerEnabled);
+ AssertArg(PortalIsValid(portal));
+
+ return (portal->state);
}
/*
* CreatePortal --
- * Returns a new portal given a name.
+ * Returns a new portal given a name.
*
* Note:
- * This is expected to be of very limited usability. See instead,
+ * This is expected to be of very limited usability. See instead,
* BlankPortalAssignName.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if portal name is invalid.
- * "WARN" if portal name is in use.
+ * BadState if called when disabled.
+ * BadArg if portal name is invalid.
+ * "WARN" if portal name is in use.
*/
Portal
-CreatePortal(char *name) /* XXX PortalName */
-{
- Portal portal;
- uint16 length;
-
- AssertState(PortalManagerEnabled);
- AssertArg(PointerIsValid(name)); /* XXX PortalName */
-
- portal = GetPortalByName(name);
- if (PortalIsValid(portal)) {
- elog(NOTICE, "CreatePortal: portal %s already exists", name);
+CreatePortal(char *name) /* XXX PortalName */
+{
+ Portal portal;
+ uint16 length;
+
+ AssertState(PortalManagerEnabled);
+ AssertArg(PointerIsValid(name)); /* XXX PortalName */
+
+ portal = GetPortalByName(name);
+ if (PortalIsValid(portal))
+ {
+ elog(NOTICE, "CreatePortal: portal %s already exists", name);
+ return (portal);
+ }
+
+ /* make new portal structure */
+ portal = (Portal)
+ MemoryContextAlloc((MemoryContext) PortalMemory, sizeof *portal);
+
+ /* initialize portal variable context */
+ NodeSetTag((Node *) & portal->variable, T_PortalVariableMemory);
+ AllocSetInit(&portal->variable.setData, DynamicAllocMode, (Size) 0);
+ portal->variable.method = &PortalVariableContextMethodsData;
+
+ /* initialize portal heap context */
+ NodeSetTag((Node *) & portal->heap, T_PortalHeapMemory);
+ portal->heap.block = NULL;
+ FixedStackInit(&portal->heap.stackData,
+ offsetof(HeapMemoryBlockData, itemData));
+ portal->heap.method = &PortalHeapContextMethodsData;
+
+ /* initialize portal name */
+ length = 1 + strlen(name);
+ portal->name = (char *)
+ MemoryContextAlloc((MemoryContext) & portal->variable, length);
+ strncpy(portal->name, name, length);
+
+ /* initialize portal query */
+ portal->queryDesc = NULL;
+ portal->attinfo = NULL;
+ portal->state = NULL;
+ portal->cleanup = NULL;
+
+ /* put portal in table */
+ PortalHashTableInsert(portal);
+
+ /* Trap(PointerIsValid(name), Unimplemented); */
return (portal);
- }
-
- /* make new portal structure */
- portal = (Portal)
- MemoryContextAlloc((MemoryContext)PortalMemory, sizeof *portal);
-
- /* initialize portal variable context */
- NodeSetTag((Node*)&portal->variable, T_PortalVariableMemory);
- AllocSetInit(&portal->variable.setData, DynamicAllocMode, (Size)0);
- portal->variable.method = &PortalVariableContextMethodsData;
-
- /* initialize portal heap context */
- NodeSetTag((Node*)&portal->heap, T_PortalHeapMemory);
- portal->heap.block = NULL;
- FixedStackInit(&portal->heap.stackData,
- offsetof (HeapMemoryBlockData, itemData));
- portal->heap.method = &PortalHeapContextMethodsData;
-
- /* initialize portal name */
- length = 1 + strlen(name);
- portal->name = (char*)
- MemoryContextAlloc((MemoryContext)&portal->variable, length);
- strncpy(portal->name, name, length);
-
- /* initialize portal query */
- portal->queryDesc = NULL;
- portal->attinfo = NULL;
- portal->state = NULL;
- portal->cleanup = NULL;
-
- /* put portal in table */
- PortalHashTableInsert(portal);
-
- /* Trap(PointerIsValid(name), Unimplemented); */
- return (portal);
}
/*
* PortalDestroy --
- * Destroys portal.
+ * Destroys portal.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if portal is invalid.
+ * BadState if called when disabled.
+ * BadArg if portal is invalid.
*/
void
-PortalDestroy(Portal *portalP)
-{
- Portal portal = *portalP;
-
- AssertState(PortalManagerEnabled);
- AssertArg(PortalIsValid(portal));
-
- /* remove portal from table if not blank portal */
- if (portal != BlankPortal)
- PortalHashTableDelete(portal);
-
- /* reset portal */
- if (PointerIsValid(portal->cleanup))
- (*portal->cleanup)(portal);
-
- PortalResetHeapMemory(portal);
- MemoryContextFree((MemoryContext)&portal->variable,
- (Pointer)portal->name);
- AllocSetReset(&portal->variable.setData); /* XXX log */
-
- if (portal != BlankPortal)
- MemoryContextFree((MemoryContext)PortalMemory, (Pointer)portal);
+PortalDestroy(Portal * portalP)
+{
+ Portal portal = *portalP;
+
+ AssertState(PortalManagerEnabled);
+ AssertArg(PortalIsValid(portal));
+
+ /* remove portal from table if not blank portal */
+ if (portal != BlankPortal)
+ PortalHashTableDelete(portal);
+
+ /* reset portal */
+ if (PointerIsValid(portal->cleanup))
+ (*portal->cleanup) (portal);
+
+ PortalResetHeapMemory(portal);
+ MemoryContextFree((MemoryContext) & portal->variable,
+ (Pointer) portal->name);
+ AllocSetReset(&portal->variable.setData); /* XXX log */
+
+ if (portal != BlankPortal)
+ MemoryContextFree((MemoryContext) PortalMemory, (Pointer) portal);
}
/* ----------------
- * PortalResetHeapMemory --
- * Resets portal's heap memory context.
+ * PortalResetHeapMemory --
+ * Resets portal's heap memory context.
*
* Someday, Reset, Start, and End can be optimized by keeping a global
* portal module stack of free HeapMemoryBlock's. This will make Start
* and End be fast.
*
* Exceptions:
- * BadState if called when disabled.
- * BadState if called when not in PortalHeapMemory context.
- * BadArg if mode is invalid.
+ * BadState if called when disabled.
+ * BadState if called when not in PortalHeapMemory context.
+ * BadArg if mode is invalid.
* ----------------
*/
static void
PortalResetHeapMemory(Portal portal)
{
- PortalHeapMemory context;
- MemoryContext currentContext;
-
- context = PortalGetHeapMemory(portal);
-
- if (PointerIsValid(context->block)) {
- /* save present context */
- currentContext = MemoryContextSwitchTo((MemoryContext)context);
-
- do {
- EndPortalAllocMode();
- } while (PointerIsValid(context->block));
-
- /* restore context */
- MemoryContextSwitchTo(currentContext);
- }
+ PortalHeapMemory context;
+ MemoryContext currentContext;
+
+ context = PortalGetHeapMemory(portal);
+
+ if (PointerIsValid(context->block))
+ {
+ /* save present context */
+ currentContext = MemoryContextSwitchTo((MemoryContext) context);
+
+ do
+ {
+ EndPortalAllocMode();
+ } while (PointerIsValid(context->block));
+
+ /* restore context */
+ MemoryContextSwitchTo(currentContext);
+ }
}
/*
* StartPortalAllocMode --
- * Starts a new block of portal heap allocation using mode and limit;
- * the current block is disabled until EndPortalAllocMode is called.
+ * Starts a new block of portal heap allocation using mode and limit;
+ * the current block is disabled until EndPortalAllocMode is called.
*
* Note:
- * Note blocks may be stacked and restored arbitarily.
- * The semantics of mode and limit are described in aset.h.
+ * Note blocks may be stacked and restored arbitarily.
+ * The semantics of mode and limit are described in aset.h.
*
* Exceptions:
- * BadState if called when disabled.
- * BadState if called when not in PortalHeapMemory context.
- * BadArg if mode is invalid.
+ * BadState if called when disabled.
+ * BadState if called when not in PortalHeapMemory context.
+ * BadArg if mode is invalid.
*/
void
StartPortalAllocMode(AllocMode mode, Size limit)
{
- PortalHeapMemory context;
-
- AssertState(PortalManagerEnabled);
- AssertState(IsA(CurrentMemoryContext,PortalHeapMemory));
- /* AssertArg(AllocModeIsValid); */
-
- context = (PortalHeapMemory)CurrentMemoryContext;
-
- /* stack current mode */
- if (PointerIsValid(context->block))
- FixedStackPush(&context->stackData, context->block);
-
- /* allocate and initialize new block */
- context->block =
- MemoryContextAlloc(
- (MemoryContext)PortalHeapMemoryGetVariableMemory(context),
- sizeof (HeapMemoryBlockData) );
-
- /* XXX careful, context->block has never been stacked => bad state */
-
- AllocSetInit(&HEAPMEMBLOCK(context)->setData, mode, limit);
+ PortalHeapMemory context;
+
+ AssertState(PortalManagerEnabled);
+ AssertState(IsA(CurrentMemoryContext, PortalHeapMemory));
+ /* AssertArg(AllocModeIsValid); */
+
+ context = (PortalHeapMemory) CurrentMemoryContext;
+
+ /* stack current mode */
+ if (PointerIsValid(context->block))
+ FixedStackPush(&context->stackData, context->block);
+
+ /* allocate and initialize new block */
+ context->block =
+ MemoryContextAlloc(
+ (MemoryContext) PortalHeapMemoryGetVariableMemory(context),
+ sizeof(HeapMemoryBlockData));
+
+ /* XXX careful, context->block has never been stacked => bad state */
+
+ AllocSetInit(&HEAPMEMBLOCK(context)->setData, mode, limit);
}
/*
* EndPortalAllocMode --
- * Ends current block of portal heap allocation; previous block is
- * reenabled.
+ * Ends current block of portal heap allocation; previous block is
+ * reenabled.
*
* Note:
- * Note blocks may be stacked and restored arbitarily.
+ * Note blocks may be stacked and restored arbitarily.
*
* Exceptions:
- * BadState if called when disabled.
- * BadState if called when not in PortalHeapMemory context.
+ * BadState if called when disabled.
+ * BadState if called when not in PortalHeapMemory context.
*/
void
EndPortalAllocMode()
{
- PortalHeapMemory context;
-
- AssertState(PortalManagerEnabled);
- AssertState(IsA(CurrentMemoryContext,PortalHeapMemory));
-
- context = (PortalHeapMemory)CurrentMemoryContext;
- AssertState(PointerIsValid(context->block)); /* XXX Trap(...) */
-
- /* free current mode */
- AllocSetReset(&HEAPMEMBLOCK(context)->setData);
- MemoryContextFree((MemoryContext)PortalHeapMemoryGetVariableMemory(context),
- context->block);
-
- /* restore previous mode */
- context->block = FixedStackPop(&context->stackData);
+ PortalHeapMemory context;
+
+ AssertState(PortalManagerEnabled);
+ AssertState(IsA(CurrentMemoryContext, PortalHeapMemory));
+
+ context = (PortalHeapMemory) CurrentMemoryContext;
+ AssertState(PointerIsValid(context->block)); /* XXX Trap(...) */
+
+ /* free current mode */
+ AllocSetReset(&HEAPMEMBLOCK(context)->setData);
+ MemoryContextFree((MemoryContext) PortalHeapMemoryGetVariableMemory(context),
+ context->block);
+
+ /* restore previous mode */
+ context->block = FixedStackPop(&context->stackData);
}
/*
* PortalGetVariableMemory --
- * Returns variable memory context for a given portal.
+ * Returns variable memory context for a given portal.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if portal is invalid.
+ * BadState if called when disabled.
+ * BadArg if portal is invalid.
*/
PortalVariableMemory
PortalGetVariableMemory(Portal portal)
{
- return (&portal->variable);
+ return (&portal->variable);
}
/*
* PortalGetHeapMemory --
- * Returns heap memory context for a given portal.
+ * Returns heap memory context for a given portal.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if portal is invalid.
+ * BadState if called when disabled.
+ * BadArg if portal is invalid.
*/
PortalHeapMemory
PortalGetHeapMemory(Portal portal)
{
- return (&portal->heap);
+ return (&portal->heap);
}
/*
* PortalVariableMemoryGetPortal --
- * Returns portal containing given variable memory context.
+ * Returns portal containing given variable memory context.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if context is invalid.
+ * BadState if called when disabled.
+ * BadArg if context is invalid.
*/
-static Portal
+static Portal
PortalVariableMemoryGetPortal(PortalVariableMemory context)
{
- return ((Portal)((char *)context - offsetof (PortalD, variable)));
+ return ((Portal) ((char *) context - offsetof(PortalD, variable)));
}
/*
* PortalHeapMemoryGetPortal --
- * Returns portal containing given heap memory context.
+ * Returns portal containing given heap memory context.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if context is invalid.
+ * BadState if called when disabled.
+ * BadArg if context is invalid.
*/
-static Portal
+static Portal
PortalHeapMemoryGetPortal(PortalHeapMemory context)
{
- return ((Portal)((char *)context - offsetof (PortalD, heap)));
+ return ((Portal) ((char *) context - offsetof(PortalD, heap)));
}
/*
* PortalVariableMemoryGetHeapMemory --
- * Returns heap memory context associated with given variable memory.
+ * Returns heap memory context associated with given variable memory.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if context is invalid.
+ * BadState if called when disabled.
+ * BadArg if context is invalid.
*/
#ifdef NOT_USED
PortalHeapMemory
PortalVariableMemoryGetHeapMemory(PortalVariableMemory context)
{
- return ((PortalHeapMemory)((char *)context
- - offsetof (PortalD, variable)
- + offsetof (PortalD, heap)));
+ return ((PortalHeapMemory) ((char *) context
+ - offsetof(PortalD, variable)
+ + offsetof(PortalD, heap)));
}
+
#endif
/*
* PortalHeapMemoryGetVariableMemory --
- * Returns variable memory context associated with given heap memory.
+ * Returns variable memory context associated with given heap memory.
*
* Exceptions:
- * BadState if called when disabled.
- * BadArg if context is invalid.
+ * BadState if called when disabled.
+ * BadArg if context is invalid.
*/
-static PortalVariableMemory
+static PortalVariableMemory
PortalHeapMemoryGetVariableMemory(PortalHeapMemory context)
{
- return ((PortalVariableMemory)((char *)context
- - offsetof (PortalD, heap)
- + offsetof (PortalD, variable)));
+ return ((PortalVariableMemory) ((char *) context
+ - offsetof(PortalD, heap)
+ + offsetof(PortalD, variable)));
}
-
diff --git a/src/backend/utils/sort/lselect.c b/src/backend/utils/sort/lselect.c
index 6797bd40ca0..bc6948292b3 100644
--- a/src/backend/utils/sort/lselect.c
+++ b/src/backend/utils/sort/lselect.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* lselect.c--
- * leftist tree selection algorithm (linked priority queue--Knuth, Vol.3,
- * pp.150-52)
+ * leftist tree selection algorithm (linked priority queue--Knuth, Vol.3,
+ * pp.150-52)
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/lselect.c,v 1.5 1997/08/12 22:55:00 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/lselect.c,v 1.6 1997/09/07 04:54:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,295 +26,340 @@
#include "utils/psort.h"
#include "utils/lselect.h"
-#define PUTTUP(TUP, FP) fwrite((char *)TUP, (TUP)->t_len, 1, FP)
+#define PUTTUP(TUP, FP) fwrite((char *)TUP, (TUP)->t_len, 1, FP)
/*
- * USEMEM - record use of memory
- * FREEMEM - record freeing of memory
+ * USEMEM - record use of memory
+ * FREEMEM - record freeing of memory
*/
-#define USEMEM(context,AMT) context->sortMem -= (AMT)
-#define FREEMEM(context,AMT) context->sortMem += (AMT)
+#define USEMEM(context,AMT) context->sortMem -= (AMT)
+#define FREEMEM(context,AMT) context->sortMem += (AMT)
/*
- * lmerge - merges two leftist trees into one
+ * lmerge - merges two leftist trees into one
*
- * Note:
- * Enforcing the rule that pt->lt_dist >= qt->lt_dist may
- * simplifify much of the code. Removing recursion will not
- * speed up code significantly.
+ * Note:
+ * Enforcing the rule that pt->lt_dist >= qt->lt_dist may
+ * simplifify much of the code. Removing recursion will not
+ * speed up code significantly.
*/
struct leftist *
-lmerge(struct leftist *pt, struct leftist *qt, LeftistContext context)
+lmerge(struct leftist * pt, struct leftist * qt, LeftistContext context)
{
- register struct leftist *root, *majorLeftist, *minorLeftist;
- int dist;
-
- if (tuplecmp(pt->lt_tuple, qt->lt_tuple, context)) {
- root = pt;
- majorLeftist = qt;
- } else {
- root = qt;
- majorLeftist = pt;
- }
- if (root->lt_left == NULL)
- root->lt_left = majorLeftist;
- else {
- if ((minorLeftist = root->lt_right) != NULL)
- majorLeftist = lmerge(majorLeftist, minorLeftist, context);
- if ((dist = root->lt_left->lt_dist) < majorLeftist->lt_dist) {
- root->lt_dist = 1 + dist;
- root->lt_right = root->lt_left;
- root->lt_left = majorLeftist;
- } else {
- root->lt_dist = 1 + majorLeftist->lt_dist;
- root->lt_right = majorLeftist;
+ register struct leftist *root,
+ *majorLeftist,
+ *minorLeftist;
+ int dist;
+
+ if (tuplecmp(pt->lt_tuple, qt->lt_tuple, context))
+ {
+ root = pt;
+ majorLeftist = qt;
+ }
+ else
+ {
+ root = qt;
+ majorLeftist = pt;
}
- }
- return(root);
+ if (root->lt_left == NULL)
+ root->lt_left = majorLeftist;
+ else
+ {
+ if ((minorLeftist = root->lt_right) != NULL)
+ majorLeftist = lmerge(majorLeftist, minorLeftist, context);
+ if ((dist = root->lt_left->lt_dist) < majorLeftist->lt_dist)
+ {
+ root->lt_dist = 1 + dist;
+ root->lt_right = root->lt_left;
+ root->lt_left = majorLeftist;
+ }
+ else
+ {
+ root->lt_dist = 1 + majorLeftist->lt_dist;
+ root->lt_right = majorLeftist;
+ }
+ }
+ return (root);
}
static struct leftist *
-linsert(struct leftist *root, struct leftist *new1, LeftistContext context)
+linsert(struct leftist * root, struct leftist * new1, LeftistContext context)
{
- register struct leftist *left, *right;
-
- if (! tuplecmp(root->lt_tuple, new1->lt_tuple, context)) {
- new1->lt_left = root;
- return(new1);
- }
- left = root->lt_left;
- right = root->lt_right;
- if (right == NULL) {
- if (left == NULL)
- root->lt_left = new1;
- else {
- root->lt_right = new1;
- root->lt_dist = 2;
+ register struct leftist *left,
+ *right;
+
+ if (!tuplecmp(root->lt_tuple, new1->lt_tuple, context))
+ {
+ new1->lt_left = root;
+ return (new1);
+ }
+ left = root->lt_left;
+ right = root->lt_right;
+ if (right == NULL)
+ {
+ if (left == NULL)
+ root->lt_left = new1;
+ else
+ {
+ root->lt_right = new1;
+ root->lt_dist = 2;
+ }
+ return (root);
+ }
+ right = linsert(right, new1, context);
+ if (right->lt_dist < left->lt_dist)
+ {
+ root->lt_dist = 1 + left->lt_dist;
+ root->lt_left = right;
+ root->lt_right = left;
+ }
+ else
+ {
+ root->lt_dist = 1 + right->lt_dist;
+ root->lt_right = right;
}
- return(root);
- }
- right = linsert(right, new1, context);
- if (right->lt_dist < left->lt_dist) {
- root->lt_dist = 1 + left->lt_dist;
- root->lt_left = right;
- root->lt_right = left;
- } else {
- root->lt_dist = 1 + right->lt_dist;
- root->lt_right = right;
- }
- return(root);
+ return (root);
}
/*
- * gettuple - returns tuple at top of tree (Tuples)
+ * gettuple - returns tuple at top of tree (Tuples)
*
- * Returns:
- * tuple at top of tree, NULL if failed ALLOC()
- * *devnum is set to the devnum of tuple returned
- * *treep is set to the new tree
+ * Returns:
+ * tuple at top of tree, NULL if failed ALLOC()
+ * *devnum is set to the devnum of tuple returned
+ * *treep is set to the new tree
*
- * Note:
- * *treep must not be NULL
- * NULL is currently never returned BUG
+ * Note:
+ * *treep must not be NULL
+ * NULL is currently never returned BUG
*/
HeapTuple
-gettuple(struct leftist **treep,
- short *devnum, /* device from which tuple came */
- LeftistContext context)
+gettuple(struct leftist ** treep,
+ short *devnum, /* device from which tuple came */
+ LeftistContext context)
{
- register struct leftist *tp;
- HeapTuple tup;
-
- tp = *treep;
- tup = tp->lt_tuple;
- *devnum = tp->lt_devnum;
- if (tp->lt_dist == 1) /* lt_left == NULL */
- *treep = tp->lt_left;
- else
- *treep = lmerge(tp->lt_left, tp->lt_right, context);
-
- FREEMEM(context,sizeof (struct leftist));
- FREE(tp);
- return(tup);
+ register struct leftist *tp;
+ HeapTuple tup;
+
+ tp = *treep;
+ tup = tp->lt_tuple;
+ *devnum = tp->lt_devnum;
+ if (tp->lt_dist == 1) /* lt_left == NULL */
+ *treep = tp->lt_left;
+ else
+ *treep = lmerge(tp->lt_left, tp->lt_right, context);
+
+ FREEMEM(context, sizeof(struct leftist));
+ FREE(tp);
+ return (tup);
}
/*
- * puttuple - inserts new tuple into tree
+ * puttuple - inserts new tuple into tree
*
- * Returns:
- * NULL iff failed ALLOC()
+ * Returns:
+ * NULL iff failed ALLOC()
*
- * Note:
- * Currently never returns NULL BUG
+ * Note:
+ * Currently never returns NULL BUG
*/
void
-puttuple(struct leftist **treep,
- HeapTuple newtuple,
- short devnum,
- LeftistContext context)
+puttuple(struct leftist ** treep,
+ HeapTuple newtuple,
+ short devnum,
+ LeftistContext context)
{
- register struct leftist *new1;
- register struct leftist *tp;
-
- new1 = (struct leftist *) palloc((unsigned) sizeof (struct leftist));
- USEMEM(context,sizeof (struct leftist));
- new1->lt_dist = 1;
- new1->lt_devnum = devnum;
- new1->lt_tuple = newtuple;
- new1->lt_left = NULL;
- new1->lt_right = NULL;
- if ((tp = *treep) == NULL)
- *treep = new1;
- else
- *treep = linsert(tp, new1, context);
- return;
+ register struct leftist *new1;
+ register struct leftist *tp;
+
+ new1 = (struct leftist *) palloc((unsigned) sizeof(struct leftist));
+ USEMEM(context, sizeof(struct leftist));
+ new1->lt_dist = 1;
+ new1->lt_devnum = devnum;
+ new1->lt_tuple = newtuple;
+ new1->lt_left = NULL;
+ new1->lt_right = NULL;
+ if ((tp = *treep) == NULL)
+ *treep = new1;
+ else
+ *treep = linsert(tp, new1, context);
+ return;
}
/*
- * tuplecmp - Compares two tuples with respect CmpList
+ * tuplecmp - Compares two tuples with respect CmpList
*
- * Returns:
- * 1 if left < right ;0 otherwise
- * Assumtions:
+ * Returns:
+ * 1 if left < right ;0 otherwise
+ * Assumtions:
*/
int
tuplecmp(HeapTuple ltup, HeapTuple rtup, LeftistContext context)
{
- register char *lattr, *rattr;
- int nkey = 0;
- int result = 0;
- bool isnull;
-
- if (ltup == (HeapTuple)NULL)
- return(0);
- if (rtup == (HeapTuple)NULL)
- return(1);
- while (nkey < context->nKeys && !result) {
- lattr = heap_getattr(ltup, InvalidBuffer,
- context->scanKeys[nkey].sk_attno,
- context->tupDesc, &isnull);
- if (isnull)
- return(0);
- rattr = heap_getattr(rtup, InvalidBuffer,
- context->scanKeys[nkey].sk_attno,
- context->tupDesc,
- &isnull);
- if (isnull)
- return(1);
- if (context->scanKeys[nkey].sk_flags & SK_COMMUTE) {
- if (!(result =
- (long) (*context->scanKeys[nkey].sk_func) (rattr, lattr)))
- result =
- -(long) (*context->scanKeys[nkey].sk_func) (lattr, rattr);
- } else if (!(result =
- (long) (*context->scanKeys[nkey].sk_func) (lattr, rattr)))
- result =
- -(long) (*context->scanKeys[nkey].sk_func) (rattr, lattr);
- nkey++;
- }
- return (result == 1);
+ register char *lattr,
+ *rattr;
+ int nkey = 0;
+ int result = 0;
+ bool isnull;
+
+ if (ltup == (HeapTuple) NULL)
+ return (0);
+ if (rtup == (HeapTuple) NULL)
+ return (1);
+ while (nkey < context->nKeys && !result)
+ {
+ lattr = heap_getattr(ltup, InvalidBuffer,
+ context->scanKeys[nkey].sk_attno,
+ context->tupDesc, &isnull);
+ if (isnull)
+ return (0);
+ rattr = heap_getattr(rtup, InvalidBuffer,
+ context->scanKeys[nkey].sk_attno,
+ context->tupDesc,
+ &isnull);
+ if (isnull)
+ return (1);
+ if (context->scanKeys[nkey].sk_flags & SK_COMMUTE)
+ {
+ if (!(result =
+ (long) (*context->scanKeys[nkey].sk_func) (rattr, lattr)))
+ result =
+ -(long) (*context->scanKeys[nkey].sk_func) (lattr, rattr);
+ }
+ else if (!(result =
+ (long) (*context->scanKeys[nkey].sk_func) (lattr, rattr)))
+ result =
+ -(long) (*context->scanKeys[nkey].sk_func) (rattr, lattr);
+ nkey++;
+ }
+ return (result == 1);
}
#ifdef EBUG
void
-checktree(struct leftist *tree, LeftistContext context)
+checktree(struct leftist * tree, LeftistContext context)
{
- int lnodes;
- int rnodes;
-
- if (tree == NULL) {
- puts("Null tree.");
- return;
- }
- lnodes = checktreer(tree->lt_left, 1, context);
- rnodes = checktreer(tree->lt_right, 1, context);
- if (lnodes < 0) {
- lnodes = -lnodes;
- puts("0:\tBad left side.");
- }
- if (rnodes < 0) {
- rnodes = -rnodes;
- puts("0:\tBad right side.");
- }
- if (lnodes == 0) {
- if (rnodes != 0)
- puts("0:\tLeft and right reversed.");
- if (tree->lt_dist != 1)
- puts("0:\tDistance incorrect.");
- } else if (rnodes == 0) {
- if (tree->lt_dist != 1)
- puts("0:\tDistance incorrect.");
- } else if (tree->lt_left->lt_dist < tree->lt_right->lt_dist) {
- puts("0:\tLeft and right reversed.");
- if (tree->lt_dist != 1 + tree->lt_left->lt_dist)
- puts("0:\tDistance incorrect.");
- } else if (tree->lt_dist != 1+ tree->lt_right->lt_dist)
- puts("0:\tDistance incorrect.");
- if (lnodes > 0)
- if (tuplecmp(tree->lt_left->lt_tuple, tree->lt_tuple, context))
- printf("%d:\tLeft child < parent.\n");
- if (rnodes > 0)
- if (tuplecmp(tree->lt_right->lt_tuple, tree->lt_tuple, context))
- printf("%d:\tRight child < parent.\n");
- printf("Tree has %d nodes\n", 1 + lnodes + rnodes);
+ int lnodes;
+ int rnodes;
+
+ if (tree == NULL)
+ {
+ puts("Null tree.");
+ return;
+ }
+ lnodes = checktreer(tree->lt_left, 1, context);
+ rnodes = checktreer(tree->lt_right, 1, context);
+ if (lnodes < 0)
+ {
+ lnodes = -lnodes;
+ puts("0:\tBad left side.");
+ }
+ if (rnodes < 0)
+ {
+ rnodes = -rnodes;
+ puts("0:\tBad right side.");
+ }
+ if (lnodes == 0)
+ {
+ if (rnodes != 0)
+ puts("0:\tLeft and right reversed.");
+ if (tree->lt_dist != 1)
+ puts("0:\tDistance incorrect.");
+ }
+ else if (rnodes == 0)
+ {
+ if (tree->lt_dist != 1)
+ puts("0:\tDistance incorrect.");
+ }
+ else if (tree->lt_left->lt_dist < tree->lt_right->lt_dist)
+ {
+ puts("0:\tLeft and right reversed.");
+ if (tree->lt_dist != 1 + tree->lt_left->lt_dist)
+ puts("0:\tDistance incorrect.");
+ }
+ else if (tree->lt_dist != 1 + tree->lt_right->lt_dist)
+ puts("0:\tDistance incorrect.");
+ if (lnodes > 0)
+ if (tuplecmp(tree->lt_left->lt_tuple, tree->lt_tuple, context))
+ printf("%d:\tLeft child < parent.\n");
+ if (rnodes > 0)
+ if (tuplecmp(tree->lt_right->lt_tuple, tree->lt_tuple, context))
+ printf("%d:\tRight child < parent.\n");
+ printf("Tree has %d nodes\n", 1 + lnodes + rnodes);
}
int
-checktreer(struct leftist *tree, int level, LeftistContext context)
+checktreer(struct leftist * tree, int level, LeftistContext context)
{
- int lnodes, rnodes;
- int error = 0;
-
- if (tree == NULL)
- return(0);
- lnodes = checktreer(tree->lt_left, level + 1, context);
- rnodes = checktreer(tree->lt_right, level + 1, context);
- if (lnodes < 0) {
- error = 1;
- lnodes = -lnodes;
- printf("%d:\tBad left side.\n", level);
- }
- if (rnodes < 0) {
- error = 1;
- rnodes = -rnodes;
- printf("%d:\tBad right side.\n", level);
- }
- if (lnodes == 0) {
- if (rnodes != 0) {
- error = 1;
- printf("%d:\tLeft and right reversed.\n", level);
+ int lnodes,
+ rnodes;
+ int error = 0;
+
+ if (tree == NULL)
+ return (0);
+ lnodes = checktreer(tree->lt_left, level + 1, context);
+ rnodes = checktreer(tree->lt_right, level + 1, context);
+ if (lnodes < 0)
+ {
+ error = 1;
+ lnodes = -lnodes;
+ printf("%d:\tBad left side.\n", level);
}
- if (tree->lt_dist != 1) {
- error = 1;
- printf("%d:\tDistance incorrect.\n", level);
+ if (rnodes < 0)
+ {
+ error = 1;
+ rnodes = -rnodes;
+ printf("%d:\tBad right side.\n", level);
}
- } else if (rnodes == 0) {
- if (tree->lt_dist != 1) {
- error = 1;
- printf("%d:\tDistance incorrect.\n", level);
- }
- } else if (tree->lt_left->lt_dist < tree->lt_right->lt_dist) {
- error = 1;
- printf("%d:\tLeft and right reversed.\n", level);
- if (tree->lt_dist != 1 + tree->lt_left->lt_dist)
- printf("%d:\tDistance incorrect.\n", level);
- } else if (tree->lt_dist != 1+ tree->lt_right->lt_dist) {
- error = 1;
- printf("%d:\tDistance incorrect.\n", level);
- }
- if (lnodes > 0)
- if (tuplecmp(tree->lt_left->lt_tuple, tree->lt_tuple, context)) {
- error = 1;
- printf("%d:\tLeft child < parent.\n");
+ if (lnodes == 0)
+ {
+ if (rnodes != 0)
+ {
+ error = 1;
+ printf("%d:\tLeft and right reversed.\n", level);
+ }
+ if (tree->lt_dist != 1)
+ {
+ error = 1;
+ printf("%d:\tDistance incorrect.\n", level);
+ }
}
- if (rnodes > 0)
- if (tuplecmp(tree->lt_right->lt_tuple, tree->lt_tuple, context)) {
- error = 1;
- printf("%d:\tRight child < parent.\n");
+ else if (rnodes == 0)
+ {
+ if (tree->lt_dist != 1)
+ {
+ error = 1;
+ printf("%d:\tDistance incorrect.\n", level);
+ }
}
- if (error)
- return(-1 + -lnodes + -rnodes);
- return(1 + lnodes + rnodes);
+ else if (tree->lt_left->lt_dist < tree->lt_right->lt_dist)
+ {
+ error = 1;
+ printf("%d:\tLeft and right reversed.\n", level);
+ if (tree->lt_dist != 1 + tree->lt_left->lt_dist)
+ printf("%d:\tDistance incorrect.\n", level);
+ }
+ else if (tree->lt_dist != 1 + tree->lt_right->lt_dist)
+ {
+ error = 1;
+ printf("%d:\tDistance incorrect.\n", level);
+ }
+ if (lnodes > 0)
+ if (tuplecmp(tree->lt_left->lt_tuple, tree->lt_tuple, context))
+ {
+ error = 1;
+ printf("%d:\tLeft child < parent.\n");
+ }
+ if (rnodes > 0)
+ if (tuplecmp(tree->lt_right->lt_tuple, tree->lt_tuple, context))
+ {
+ error = 1;
+ printf("%d:\tRight child < parent.\n");
+ }
+ if (error)
+ return (-1 + -lnodes + -rnodes);
+ return (1 + lnodes + rnodes);
}
+
#endif
diff --git a/src/backend/utils/sort/psort.c b/src/backend/utils/sort/psort.c
index 12486166268..00cbfbacba5 100644
--- a/src/backend/utils/sort/psort.c
+++ b/src/backend/utils/sort/psort.c
@@ -1,36 +1,36 @@
/*-------------------------------------------------------------------------
*
* psort.c--
- * Polyphase merge sort.
+ * Polyphase merge sort.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/psort.c,v 1.18 1997/09/05 00:09:23 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/psort.c,v 1.19 1997/09/07 04:54:17 momjian Exp $
*
* NOTES
- * Sorts the first relation into the second relation.
+ * Sorts the first relation into the second relation.
*
- * The old psort.c's routines formed a temporary relation from the merged
+ * The old psort.c's routines formed a temporary relation from the merged
* sort files. This version keeps the files around instead of generating the
* relation from them, and provides interface functions to the file so that
* you can grab tuples, mark a position in the file, restore a position in the
* file. You must now explicitly call an interface function to end the sort,
* psort_end, when you are done.
- * Now most of the global variables are stuck in the Sort nodes, and
+ * Now most of the global variables are stuck in the Sort nodes, and
* accessed from there (they are passed to all the psort routines) so that
* each sort running has its own separate state. This is facilitated by having
* the Sort nodes passed in to all the interface functions.
- * The one global variable that all the sorts still share is SortMemory.
- * You should now be allowed to run two or more psorts concurrently,
+ * The one global variable that all the sorts still share is SortMemory.
+ * You should now be allowed to run two or more psorts concurrently,
* so long as the memory they eat up is not greater than SORTMEM, the initial
- * value of SortMemory. -Rex 2.15.1995
+ * value of SortMemory. -Rex 2.15.1995
*
- * Use the tape-splitting method (Knuth, Vol. III, pp281-86) in the future.
+ * Use the tape-splitting method (Knuth, Vol. III, pp281-86) in the future.
*
- * Arguments? Variables?
- * MAXMERGE, MAXTAPES
+ * Arguments? Variables?
+ * MAXMERGE, MAXTAPES
*-------------------------------------------------------------------------
*/
#include <stdio.h>
@@ -46,11 +46,11 @@
#include "access/htup.h"
#include "access/relscan.h"
#include "access/skey.h"
-#include "utils/tqual.h" /* for NowTimeQual */
+#include "utils/tqual.h" /* for NowTimeQual */
#include "storage/buf.h"
-#include "storage/bufmgr.h" /* for BLCKSZ */
-#include "utils/portal.h" /* for {Start,End}PortalAllocMode */
+#include "storage/bufmgr.h" /* for BLCKSZ */
+#include "utils/portal.h" /* for {Start,End}PortalAllocMode */
#include "utils/elog.h"
#include "utils/rel.h"
@@ -64,47 +64,47 @@
#include "miscadmin.h"
#include "storage/fd.h"
-static bool createrun(Sort *node, FILE *file, bool *empty);
-static void destroytape(FILE *file);
-static void dumptuples(FILE *file, Sort *node);
-static FILE *gettape(void);
-static void initialrun(Sort *node, bool *empty);
-static void inittapes(Sort *node);
-static void merge(Sort *node, struct tape *dest);
-static FILE *mergeruns(Sort *node);
+static bool createrun(Sort * node, FILE * file, bool * empty);
+static void destroytape(FILE * file);
+static void dumptuples(FILE * file, Sort * node);
+static FILE *gettape(void);
+static void initialrun(Sort * node, bool * empty);
+static void inittapes(Sort * node);
+static void merge(Sort * node, struct tape * dest);
+static FILE *mergeruns(Sort * node);
static HeapTuple tuplecopy(HeapTuple tup);
-#define TEMPDIR "./"
+#define TEMPDIR "./"
-static long shortzero = 0; /* used to delimit runs */
+static long shortzero = 0; /* used to delimit runs */
/*
* old psort global variables
*
* (These are the global variables from the old psort. They are still used,
- * but are now accessed from Sort nodes using the PS macro. Note that while
- * these variables will be accessed by PS(node)->whatever, they will still
- * be called by their original names within the comments! -Rex 2.10.1995)
+ * but are now accessed from Sort nodes using the PS macro. Note that while
+ * these variables will be accessed by PS(node)->whatever, they will still
+ * be called by their original names within the comments! -Rex 2.10.1995)
*
- * LeftistContextData treeContext;
+ * LeftistContextData treeContext;
*
- * static int TapeRange; number of tapes - 1 (T)
- * static int Level; (l)
- * static int TotalDummy; summation of tp_dummy
- * static struct tape *Tape;
+ * static int TapeRange; number of tapes - 1 (T)
+ * static int Level; (l)
+ * static int TotalDummy; summation of tp_dummy
+ * static struct tape *Tape;
*
- * static int BytesRead; to keep track of # of IO
- * static int BytesWritten;
+ * static int BytesRead; to keep track of # of IO
+ * static int BytesWritten;
*
- * struct leftist *Tuples; current tuples in memory
+ * struct leftist *Tuples; current tuples in memory
*
- * FILE *psort_grab_file; this holds tuples grabbed
- * from merged sort runs
- * long psort_current; current file position
- * long psort_saved; file position saved for
- * mark and restore
+ * FILE *psort_grab_file; this holds tuples grabbed
+ * from merged sort runs
+ * long psort_current; current file position
+ * long psort_saved; file position saved for
+ * mark and restore
*/
/*
@@ -113,730 +113,777 @@ static long shortzero = 0; /* used to delimit runs */
#define PS(N) ((Psortstate *)N->psortstate)
/*
- * psort_begin - polyphase merge sort entry point. Sorts the subplan
- * into a temporary file psort_grab_file. After
- * this is called, calling the interface function
- * psort_grabtuple iteratively will get you the sorted
- * tuples. psort_end then finishes the sort off, after
- * all the tuples have been grabbed.
+ * psort_begin - polyphase merge sort entry point. Sorts the subplan
+ * into a temporary file psort_grab_file. After
+ * this is called, calling the interface function
+ * psort_grabtuple iteratively will get you the sorted
+ * tuples. psort_end then finishes the sort off, after
+ * all the tuples have been grabbed.
*
- * Allocates and initializes sort node's psort state.
+ * Allocates and initializes sort node's psort state.
*/
bool
-psort_begin(Sort *node, int nkeys, ScanKey key)
+psort_begin(Sort * node, int nkeys, ScanKey key)
{
- bool empty; /* to answer: is child node empty? */
-
- node->psortstate = (struct Psortstate *)palloc(sizeof(struct Psortstate));
- if (node->psortstate == NULL)
- return false;
-
- AssertArg(nkeys >= 1);
- AssertArg(key[0].sk_attno != 0);
- AssertArg(key[0].sk_procedure != 0);
-
- PS(node)->BytesRead = 0;
- PS(node)->BytesWritten = 0;
- PS(node)->treeContext.tupDesc =
- ExecGetTupType(outerPlan((Plan *)node));
- PS(node)->treeContext.nKeys = nkeys;
- PS(node)->treeContext.scanKeys = key;
- PS(node)->treeContext.sortMem = SortMem * 1024;
-
- PS(node)->Tuples = NULL;
- PS(node)->tupcount = 0;
-
- PS(node)->using_tape_files = false;
- PS(node)->memtuples = NULL;
-
- initialrun(node, &empty);
-
- if (empty)
- return false;
-
- if (PS(node)->using_tape_files)
- PS(node)->psort_grab_file = mergeruns(node);
-
- PS(node)->psort_current = 0;
- PS(node)->psort_saved = 0;
-
- return true;
+ bool empty; /* to answer: is child node empty? */
+
+ node->psortstate = (struct Psortstate *) palloc(sizeof(struct Psortstate));
+ if (node->psortstate == NULL)
+ return false;
+
+ AssertArg(nkeys >= 1);
+ AssertArg(key[0].sk_attno != 0);
+ AssertArg(key[0].sk_procedure != 0);
+
+ PS(node)->BytesRead = 0;
+ PS(node)->BytesWritten = 0;
+ PS(node)->treeContext.tupDesc =
+ ExecGetTupType(outerPlan((Plan *) node));
+ PS(node)->treeContext.nKeys = nkeys;
+ PS(node)->treeContext.scanKeys = key;
+ PS(node)->treeContext.sortMem = SortMem * 1024;
+
+ PS(node)->Tuples = NULL;
+ PS(node)->tupcount = 0;
+
+ PS(node)->using_tape_files = false;
+ PS(node)->memtuples = NULL;
+
+ initialrun(node, &empty);
+
+ if (empty)
+ return false;
+
+ if (PS(node)->using_tape_files)
+ PS(node)->psort_grab_file = mergeruns(node);
+
+ PS(node)->psort_current = 0;
+ PS(node)->psort_saved = 0;
+
+ return true;
}
/*
- * inittapes - initializes the tapes
- * - (polyphase merge Alg.D(D1)--Knuth, Vol.3, p.270)
- * Returns:
- * number of allocated tapes
+ * inittapes - initializes the tapes
+ * - (polyphase merge Alg.D(D1)--Knuth, Vol.3, p.270)
+ * Returns:
+ * number of allocated tapes
*/
static void
-inittapes(Sort *node)
+inittapes(Sort * node)
{
- register int i;
- register struct tape *tp;
-
- Assert(node != (Sort *) NULL);
- Assert(PS(node) != (Psortstate *) NULL);
-
- /*
- ASSERT(ntapes >= 3 && ntapes <= MAXTAPES,
- "inittapes: Invalid number of tapes to initialize.\n");
- */
-
- tp = PS(node)->Tape;
- for (i = 0; i < MAXTAPES && (tp->tp_file = gettape()) != NULL; i++) {
- tp->tp_dummy = 1;
- tp->tp_fib = 1;
- tp->tp_prev = tp - 1;
- tp++;
- }
- PS(node)->TapeRange = --tp - PS(node)->Tape;
- tp->tp_dummy = 0;
- tp->tp_fib = 0;
- PS(node)->Tape[0].tp_prev = tp;
-
- if (PS(node)->TapeRange <= 1)
- elog(WARN, "inittapes: Could only allocate %d < 3 tapes\n",
- PS(node)->TapeRange + 1);
-
- PS(node)->Level = 1;
- PS(node)->TotalDummy = PS(node)->TapeRange;
-
- PS(node)->using_tape_files = true;
+ register int i;
+ register struct tape *tp;
+
+ Assert(node != (Sort *) NULL);
+ Assert(PS(node) != (Psortstate *) NULL);
+
+ /*
+ * ASSERT(ntapes >= 3 && ntapes <= MAXTAPES, "inittapes: Invalid
+ * number of tapes to initialize.\n");
+ */
+
+ tp = PS(node)->Tape;
+ for (i = 0; i < MAXTAPES && (tp->tp_file = gettape()) != NULL; i++)
+ {
+ tp->tp_dummy = 1;
+ tp->tp_fib = 1;
+ tp->tp_prev = tp - 1;
+ tp++;
+ }
+ PS(node)->TapeRange = --tp - PS(node)->Tape;
+ tp->tp_dummy = 0;
+ tp->tp_fib = 0;
+ PS(node)->Tape[0].tp_prev = tp;
+
+ if (PS(node)->TapeRange <= 1)
+ elog(WARN, "inittapes: Could only allocate %d < 3 tapes\n",
+ PS(node)->TapeRange + 1);
+
+ PS(node)->Level = 1;
+ PS(node)->TotalDummy = PS(node)->TapeRange;
+
+ PS(node)->using_tape_files = true;
}
/*
- * PUTTUP - writes the next tuple
- * ENDRUN - mark end of run
- * GETLEN - reads the length of the next tuple
- * ALLOCTUP - returns space for the new tuple
- * SETTUPLEN - stores the length into the tuple
- * GETTUP - reads the tuple
+ * PUTTUP - writes the next tuple
+ * ENDRUN - mark end of run
+ * GETLEN - reads the length of the next tuple
+ * ALLOCTUP - returns space for the new tuple
+ * SETTUPLEN - stores the length into the tuple
+ * GETTUP - reads the tuple
*
- * Note:
- * LEN field must be a short; FP is a stream
+ * Note:
+ * LEN field must be a short; FP is a stream
*/
-#define PUTTUP(NODE, TUP, FP) do {\
- ((Psortstate *)NODE->psortstate)->BytesWritten += (TUP)->t_len; \
- fwrite((char *)TUP, (TUP)->t_len, 1, FP);} while (0)
-#define ENDRUN(FP) fwrite((char *)&shortzero, sizeof (shortzero), 1, FP)
-#define GETLEN(LEN, FP) fread((char *)&(LEN), sizeof (shortzero), 1, FP)
-#define ALLOCTUP(LEN) ((HeapTuple)palloc((unsigned)LEN))
-#define GETTUP(NODE, TUP, LEN, FP) do {\
- IncrProcessed(); \
- ((Psortstate *)NODE->psortstate)->BytesRead += (LEN) - sizeof (shortzero); \
- fread((char *)(TUP) + sizeof (shortzero), (LEN) - sizeof (shortzero), 1, FP);} \
- while (0)
-#define SETTUPLEN(TUP, LEN) (TUP)->t_len = LEN
-
- /*
- * USEMEM - record use of memory
- * FREEMEM - record freeing of memory
- * FULLMEM - 1 iff a tuple will fit
- */
-
-#define USEMEM(NODE,AMT) PS(node)->treeContext.sortMem -= (AMT)
-#define FREEMEM(NODE,AMT) PS(node)->treeContext.sortMem += (AMT)
-#define LACKMEM(NODE) (PS(node)->treeContext.sortMem <= MAXBLCKSZ) /* not accurate */
-#define TRACEMEM(FUNC)
-#define TRACEOUT(FUNC, TUP)
+#define PUTTUP(NODE, TUP, FP) do {\
+ ((Psortstate *)NODE->psortstate)->BytesWritten += (TUP)->t_len; \
+ fwrite((char *)TUP, (TUP)->t_len, 1, FP);} while (0)
+#define ENDRUN(FP) fwrite((char *)&shortzero, sizeof (shortzero), 1, FP)
+#define GETLEN(LEN, FP) fread((char *)&(LEN), sizeof (shortzero), 1, FP)
+#define ALLOCTUP(LEN) ((HeapTuple)palloc((unsigned)LEN))
+#define GETTUP(NODE, TUP, LEN, FP) do {\
+ IncrProcessed(); \
+ ((Psortstate *)NODE->psortstate)->BytesRead += (LEN) - sizeof (shortzero); \
+ fread((char *)(TUP) + sizeof (shortzero), (LEN) - sizeof (shortzero), 1, FP);} \
+ while (0)
+#define SETTUPLEN(TUP, LEN) (TUP)->t_len = LEN
+
+ /*
+ * USEMEM - record use of memory FREEMEM - record
+ * freeing of memory FULLMEM - 1 iff a tuple will fit
+ */
+
+#define USEMEM(NODE,AMT) PS(node)->treeContext.sortMem -= (AMT)
+#define FREEMEM(NODE,AMT) PS(node)->treeContext.sortMem += (AMT)
+#define LACKMEM(NODE) (PS(node)->treeContext.sortMem <= MAXBLCKSZ) /* not accurate */
+#define TRACEMEM(FUNC)
+#define TRACEOUT(FUNC, TUP)
/*
- * initialrun - distributes tuples from the relation
- * - (replacement selection(R2-R3)--Knuth, Vol.3, p.257)
- * - (polyphase merge Alg.D(D2-D4)--Knuth, Vol.3, p.271)
+ * initialrun - distributes tuples from the relation
+ * - (replacement selection(R2-R3)--Knuth, Vol.3, p.257)
+ * - (polyphase merge Alg.D(D2-D4)--Knuth, Vol.3, p.271)
*
- * Explaination:
- * Tuples are distributed to the tapes as in Algorithm D.
- * A "tuple" with t_size == 0 is used to mark the end of a run.
+ * Explaination:
+ * Tuples are distributed to the tapes as in Algorithm D.
+ * A "tuple" with t_size == 0 is used to mark the end of a run.
*
- * Note:
- * The replacement selection algorithm has been modified
- * to go from R1 directly to R3 skipping R2 the first time.
+ * Note:
+ * The replacement selection algorithm has been modified
+ * to go from R1 directly to R3 skipping R2 the first time.
*
- * Maybe should use closer(rdesc) before return
- * Perhaps should adjust the number of tapes if less than n.
- * used--v. likely to have problems in mergeruns().
- * Must know if should open/close files before each
- * call to psort()? If should--messy??
+ * Maybe should use closer(rdesc) before return
+ * Perhaps should adjust the number of tapes if less than n.
+ * used--v. likely to have problems in mergeruns().
+ * Must know if should open/close files before each
+ * call to psort()? If should--messy??
*
- * Possible optimization:
- * put the first xxx runs in quickly--problem here since
- * I (perhaps prematurely) combined the 2 algorithms.
- * Also, perhaps allocate tapes when needed. Split into 2 funcs.
+ * Possible optimization:
+ * put the first xxx runs in quickly--problem here since
+ * I (perhaps prematurely) combined the 2 algorithms.
+ * Also, perhaps allocate tapes when needed. Split into 2 funcs.
*/
static void
-initialrun(Sort *node, bool *empty)
+initialrun(Sort * node, bool * empty)
{
- /* register struct tuple *tup; */
- register struct tape *tp;
- int baseruns; /* D:(a) */
- int extrapasses; /* EOF */
-
- Assert(node != (Sort *) NULL);
- Assert(PS(node) != (Psortstate *) NULL);
-
- tp = PS(node)->Tape;
-
- if ((bool)createrun(node, NULL, empty) != false) {
- if (! PS(node)->using_tape_files)
- inittapes(node);
- extrapasses = 0;
- }
- else {
- /* if empty or rows fit in memory, we never access tape stuff */
- if (*empty || ! PS(node)->using_tape_files)
- return;
- if (! PS(node)->using_tape_files)
- inittapes(node);
- extrapasses = 1 + (PS(node)->Tuples != NULL); /* (T != N) ? 2 : 1 */
- }
-
- for ( ; ; ) {
- tp->tp_dummy--;
- PS(node)->TotalDummy--;
- if (tp->tp_dummy < (tp + 1)->tp_dummy)
- tp++;
- else if (tp->tp_dummy != 0)
- tp = PS(node)->Tape;
- else {
- PS(node)->Level++;
- baseruns = PS(node)->Tape[0].tp_fib;
- for (tp = PS(node)->Tape;
- tp - PS(node)->Tape < PS(node)->TapeRange; tp++) {
- PS(node)->TotalDummy +=
- (tp->tp_dummy = baseruns
- + (tp + 1)->tp_fib
- - tp->tp_fib);
- tp->tp_fib = baseruns
- + (tp + 1)->tp_fib;
- }
- tp = PS(node)->Tape; /* D4 */
- } /* D3 */
- if (extrapasses)
- if (--extrapasses) {
- dumptuples(tp->tp_file, node);
- ENDRUN(tp->tp_file);
- continue;
- } else
- break;
-
- if ((bool)createrun(node, tp->tp_file, empty) == false)
- extrapasses = 1 + (PS(node)->Tuples != NULL);
- /* D2 */
- }
- for (tp = PS(node)->Tape + PS(node)->TapeRange; tp >= PS(node)->Tape; tp--)
- rewind(tp->tp_file); /* D. */
+ /* register struct tuple *tup; */
+ register struct tape *tp;
+ int baseruns; /* D:(a) */
+ int extrapasses;/* EOF */
+
+ Assert(node != (Sort *) NULL);
+ Assert(PS(node) != (Psortstate *) NULL);
+
+ tp = PS(node)->Tape;
+
+ if ((bool) createrun(node, NULL, empty) != false)
+ {
+ if (!PS(node)->using_tape_files)
+ inittapes(node);
+ extrapasses = 0;
+ }
+ else
+ {
+ /* if empty or rows fit in memory, we never access tape stuff */
+ if (*empty || !PS(node)->using_tape_files)
+ return;
+ if (!PS(node)->using_tape_files)
+ inittapes(node);
+ extrapasses = 1 + (PS(node)->Tuples != NULL); /* (T != N) ? 2 : 1 */
+ }
+
+ for (;;)
+ {
+ tp->tp_dummy--;
+ PS(node)->TotalDummy--;
+ if (tp->tp_dummy < (tp + 1)->tp_dummy)
+ tp++;
+ else if (tp->tp_dummy != 0)
+ tp = PS(node)->Tape;
+ else
+ {
+ PS(node)->Level++;
+ baseruns = PS(node)->Tape[0].tp_fib;
+ for (tp = PS(node)->Tape;
+ tp - PS(node)->Tape < PS(node)->TapeRange; tp++)
+ {
+ PS(node)->TotalDummy +=
+ (tp->tp_dummy = baseruns
+ + (tp + 1)->tp_fib
+ - tp->tp_fib);
+ tp->tp_fib = baseruns
+ + (tp + 1)->tp_fib;
+ }
+ tp = PS(node)->Tape;/* D4 */
+ } /* D3 */
+ if (extrapasses)
+ if (--extrapasses)
+ {
+ dumptuples(tp->tp_file, node);
+ ENDRUN(tp->tp_file);
+ continue;
+ }
+ else
+ break;
+
+ if ((bool) createrun(node, tp->tp_file, empty) == false)
+ extrapasses = 1 + (PS(node)->Tuples != NULL);
+ /* D2 */
+ }
+ for (tp = PS(node)->Tape + PS(node)->TapeRange; tp >= PS(node)->Tape; tp--)
+ rewind(tp->tp_file); /* D. */
}
/*
- * createrun - places the next run on file, grabbing the tuples by
- * executing the subplan passed in
+ * createrun - places the next run on file, grabbing the tuples by
+ * executing the subplan passed in
*
- * Uses:
- * Tuples, which should contain any tuples for this run
+ * Uses:
+ * Tuples, which should contain any tuples for this run
*
- * Returns:
- * FALSE iff process through end of relation
- * Tuples contains the tuples for the following run upon exit
+ * Returns:
+ * FALSE iff process through end of relation
+ * Tuples contains the tuples for the following run upon exit
*/
-static bool
-createrun(Sort *node, FILE *file, bool *empty)
+static bool
+createrun(Sort * node, FILE * file, bool * empty)
{
- register HeapTuple lasttuple;
- register HeapTuple tup;
- struct leftist *nextrun;
- bool foundeor;
- short junk;
-
- int cr_tuples = 0; /* Count tuples grabbed from plannode */
- TupleTableSlot *cr_slot;
-
- Assert(node != (Sort *) NULL);
- Assert(PS(node) != (Psortstate *) NULL);
-
- lasttuple = NULL;
- nextrun = NULL;
- foundeor = false;
- for ( ; ; ) {
- while (LACKMEM(node) && PS(node)->Tuples != NULL) {
- if (lasttuple != NULL) {
- FREEMEM(node,lasttuple->t_len);
- FREE(lasttuple);
- TRACEMEM(createrun);
- }
- lasttuple = tup = gettuple(&PS(node)->Tuples, &junk,
- &PS(node)->treeContext);
- if (! PS(node)->using_tape_files) {
- inittapes(node);
- if (! file)
- file = PS(node)->Tape->tp_file; /* was NULL */
- }
- PUTTUP(node, tup, file);
- TRACEOUT(createrun, tup);
- }
- if (LACKMEM(node))
- break;
+ register HeapTuple lasttuple;
+ register HeapTuple tup;
+ struct leftist *nextrun;
+ bool foundeor;
+ short junk;
- /* About to call ExecProcNode, it can mess up the state if it
- * eventually calls another Sort node. So must stow it away here for
- * the meantime. -Rex 2.2.1995
- */
+ int cr_tuples = 0; /* Count tuples grabbed from
+ * plannode */
+ TupleTableSlot *cr_slot;
- cr_slot = ExecProcNode(outerPlan((Plan *)node), (Plan *)node);
+ Assert(node != (Sort *) NULL);
+ Assert(PS(node) != (Psortstate *) NULL);
+
+ lasttuple = NULL;
+ nextrun = NULL;
+ foundeor = false;
+ for (;;)
+ {
+ while (LACKMEM(node) && PS(node)->Tuples != NULL)
+ {
+ if (lasttuple != NULL)
+ {
+ FREEMEM(node, lasttuple->t_len);
+ FREE(lasttuple);
+ TRACEMEM(createrun);
+ }
+ lasttuple = tup = gettuple(&PS(node)->Tuples, &junk,
+ &PS(node)->treeContext);
+ if (!PS(node)->using_tape_files)
+ {
+ inittapes(node);
+ if (!file)
+ file = PS(node)->Tape->tp_file; /* was NULL */
+ }
+ PUTTUP(node, tup, file);
+ TRACEOUT(createrun, tup);
+ }
+ if (LACKMEM(node))
+ break;
+
+ /*
+ * About to call ExecProcNode, it can mess up the state if it
+ * eventually calls another Sort node. So must stow it away here
+ * for the meantime. -Rex
+ * 2.2.1995
+ */
+
+ cr_slot = ExecProcNode(outerPlan((Plan *) node), (Plan *) node);
+
+ if (TupIsNull(cr_slot))
+ {
+ foundeor = true;
+ break;
+ }
+ else
+ {
+ tup = tuplecopy(cr_slot->val);
+ ExecClearTuple(cr_slot);
+ PS(node)->tupcount++;
+ cr_tuples++;
+ }
- if (TupIsNull(cr_slot)) {
- foundeor = true;
- break;
+ IncrProcessed();
+ USEMEM(node, tup->t_len);
+ TRACEMEM(createrun);
+ if (lasttuple != NULL && tuplecmp(tup, lasttuple,
+ &PS(node)->treeContext))
+ puttuple(&nextrun, tup, 0, &PS(node)->treeContext);
+ else
+ puttuple(&PS(node)->Tuples, tup, 0, &PS(node)->treeContext);
}
- else {
- tup = tuplecopy(cr_slot->val);
- ExecClearTuple(cr_slot);
- PS(node)->tupcount++;
- cr_tuples++;
+ if (lasttuple != NULL)
+ {
+ FREEMEM(node, lasttuple->t_len);
+ FREE(lasttuple);
+ TRACEMEM(createrun);
}
+ dumptuples(file, node);
+ if (PS(node)->using_tape_files)
+ ENDRUN(file);
+ /* delimit the end of the run */
+ PS(node)->Tuples = nextrun;
- IncrProcessed();
- USEMEM(node,tup->t_len);
- TRACEMEM(createrun);
- if (lasttuple != NULL && tuplecmp(tup, lasttuple,
- &PS(node)->treeContext))
- puttuple(&nextrun, tup, 0, &PS(node)->treeContext);
- else
- puttuple(&PS(node)->Tuples, tup, 0, &PS(node)->treeContext);
- }
- if (lasttuple != NULL) {
- FREEMEM(node,lasttuple->t_len);
- FREE(lasttuple);
- TRACEMEM(createrun);
- }
- dumptuples(file, node);
- if (PS(node)->using_tape_files)
- ENDRUN(file);
- /* delimit the end of the run */
- PS(node)->Tuples = nextrun;
-
- /* if we did not see any tuples, mark empty */
- *empty = (cr_tuples > 0) ? false : true;
-
- return((bool)! foundeor); /* XXX - works iff bool is {0,1} */
+ /* if we did not see any tuples, mark empty */
+ *empty = (cr_tuples > 0) ? false : true;
+
+ return ((bool) ! foundeor); /* XXX - works iff bool is {0,1} */
}
/*
- * tuplecopy - see also tuple.c:palloctup()
+ * tuplecopy - see also tuple.c:palloctup()
*
- * This should eventually go there under that name? And this will
- * then use palloc directly (see version -r1.2).
+ * This should eventually go there under that name? And this will
+ * then use palloc directly (see version -r1.2).
*/
-static HeapTuple
+static HeapTuple
tuplecopy(HeapTuple tup)
{
- HeapTuple rettup;
-
- if (!HeapTupleIsValid(tup)) {
- return(NULL); /* just in case */
- }
- rettup = (HeapTuple)palloc(tup->t_len);
- memmove((char *)rettup, (char *)tup, tup->t_len); /* XXX */
- return(rettup);
+ HeapTuple rettup;
+
+ if (!HeapTupleIsValid(tup))
+ {
+ return (NULL); /* just in case */
+ }
+ rettup = (HeapTuple) palloc(tup->t_len);
+ memmove((char *) rettup, (char *) tup, tup->t_len); /* XXX */
+ return (rettup);
}
/*
- * mergeruns - merges all runs from input tapes
- * (polyphase merge Alg.D(D6)--Knuth, Vol.3, p271)
+ * mergeruns - merges all runs from input tapes
+ * (polyphase merge Alg.D(D6)--Knuth, Vol.3, p271)
*
- * Returns:
- * file of tuples in order
+ * Returns:
+ * file of tuples in order
*/
-static FILE *
-mergeruns(Sort *node)
+static FILE *
+mergeruns(Sort * node)
{
- register struct tape *tp;
+ register struct tape *tp;
- Assert(node != (Sort *) NULL);
- Assert(PS(node) != (Psortstate *) NULL);
- Assert(PS(node)->using_tape_files == true);
+ Assert(node != (Sort *) NULL);
+ Assert(PS(node) != (Psortstate *) NULL);
+ Assert(PS(node)->using_tape_files == true);
- tp = PS(node)->Tape + PS(node)->TapeRange;
- merge(node, tp);
- rewind(tp->tp_file);
- while (--PS(node)->Level != 0) {
- tp = tp->tp_prev;
- rewind(tp->tp_file);
- /* resettape(tp->tp_file); -not sufficient */
+ tp = PS(node)->Tape + PS(node)->TapeRange;
merge(node, tp);
rewind(tp->tp_file);
- }
- return(tp->tp_file);
+ while (--PS(node)->Level != 0)
+ {
+ tp = tp->tp_prev;
+ rewind(tp->tp_file);
+ /* resettape(tp->tp_file); -not sufficient */
+ merge(node, tp);
+ rewind(tp->tp_file);
+ }
+ return (tp->tp_file);
}
/*
- * merge - handles a single merge of the tape
- * (polyphase merge Alg.D(D5)--Knuth, Vol.3, p271)
+ * merge - handles a single merge of the tape
+ * (polyphase merge Alg.D(D5)--Knuth, Vol.3, p271)
*/
static void
-merge(Sort *node, struct tape *dest)
+merge(Sort * node, struct tape * dest)
{
- register HeapTuple tup;
- register struct tape *lasttp; /* (TAPE[P]) */
- register struct tape *tp;
- struct leftist *tuples;
- FILE *destfile;
- int times; /* runs left to merge */
- int outdummy; /* complete dummy runs */
- short fromtape;
- long tuplen;
-
- Assert(node != (Sort *) NULL);
- Assert(PS(node) != (Psortstate *) NULL);
- Assert(PS(node)->using_tape_files == true);
-
- lasttp = dest->tp_prev;
- times = lasttp->tp_fib;
- for (tp = lasttp ; tp != dest; tp = tp->tp_prev)
- tp->tp_fib -= times;
- tp->tp_fib += times;
- /* Tape[].tp_fib (A[]) is set to proper exit values */
-
- if (PS(node)->TotalDummy < PS(node)->TapeRange)/* no complete dummy runs */
- outdummy = 0;
- else {
- outdummy = PS(node)->TotalDummy; /* a large positive number */
- for (tp = lasttp; tp != dest; tp = tp->tp_prev)
- if (outdummy > tp->tp_dummy)
- outdummy = tp->tp_dummy;
+ register HeapTuple tup;
+ register struct tape *lasttp; /* (TAPE[P]) */
+ register struct tape *tp;
+ struct leftist *tuples;
+ FILE *destfile;
+ int times; /* runs left to merge */
+ int outdummy; /* complete dummy runs */
+ short fromtape;
+ long tuplen;
+
+ Assert(node != (Sort *) NULL);
+ Assert(PS(node) != (Psortstate *) NULL);
+ Assert(PS(node)->using_tape_files == true);
+
+ lasttp = dest->tp_prev;
+ times = lasttp->tp_fib;
for (tp = lasttp; tp != dest; tp = tp->tp_prev)
- tp->tp_dummy -= outdummy;
- tp->tp_dummy += outdummy;
- PS(node)->TotalDummy -= outdummy * PS(node)->TapeRange;
- /* do not add the outdummy runs yet */
- times -= outdummy;
- }
- destfile = dest->tp_file;
- while (times-- != 0) { /* merge one run */
- tuples = NULL;
- if (PS(node)->TotalDummy == 0)
- for (tp = dest->tp_prev; tp != dest; tp = tp->tp_prev) {
- GETLEN(tuplen, tp->tp_file);
- tup = ALLOCTUP(tuplen);
- USEMEM(node,tuplen);
- TRACEMEM(merge);
- SETTUPLEN(tup, tuplen);
- GETTUP(node, tup, tuplen, tp->tp_file);
- puttuple(&tuples, tup, tp - PS(node)->Tape,
- &PS(node)->treeContext);
- }
- else {
- for (tp = dest->tp_prev; tp != dest; tp = tp->tp_prev) {
- if (tp->tp_dummy != 0) {
- tp->tp_dummy--;
- PS(node)->TotalDummy--;
- } else {
- GETLEN(tuplen, tp->tp_file);
- tup = ALLOCTUP(tuplen);
- USEMEM(node,tuplen);
- TRACEMEM(merge);
- SETTUPLEN(tup, tuplen);
- GETTUP(node, tup, tuplen, tp->tp_file);
- puttuple(&tuples, tup, tp - PS(node)->Tape,
- &PS(node)->treeContext);
+ tp->tp_fib -= times;
+ tp->tp_fib += times;
+ /* Tape[].tp_fib (A[]) is set to proper exit values */
+
+ if (PS(node)->TotalDummy < PS(node)->TapeRange) /* no complete dummy
+ * runs */
+ outdummy = 0;
+ else
+ {
+ outdummy = PS(node)->TotalDummy; /* a large positive number */
+ for (tp = lasttp; tp != dest; tp = tp->tp_prev)
+ if (outdummy > tp->tp_dummy)
+ outdummy = tp->tp_dummy;
+ for (tp = lasttp; tp != dest; tp = tp->tp_prev)
+ tp->tp_dummy -= outdummy;
+ tp->tp_dummy += outdummy;
+ PS(node)->TotalDummy -= outdummy * PS(node)->TapeRange;
+ /* do not add the outdummy runs yet */
+ times -= outdummy;
+ }
+ destfile = dest->tp_file;
+ while (times-- != 0)
+ { /* merge one run */
+ tuples = NULL;
+ if (PS(node)->TotalDummy == 0)
+ for (tp = dest->tp_prev; tp != dest; tp = tp->tp_prev)
+ {
+ GETLEN(tuplen, tp->tp_file);
+ tup = ALLOCTUP(tuplen);
+ USEMEM(node, tuplen);
+ TRACEMEM(merge);
+ SETTUPLEN(tup, tuplen);
+ GETTUP(node, tup, tuplen, tp->tp_file);
+ puttuple(&tuples, tup, tp - PS(node)->Tape,
+ &PS(node)->treeContext);
+ }
+ else
+ {
+ for (tp = dest->tp_prev; tp != dest; tp = tp->tp_prev)
+ {
+ if (tp->tp_dummy != 0)
+ {
+ tp->tp_dummy--;
+ PS(node)->TotalDummy--;
+ }
+ else
+ {
+ GETLEN(tuplen, tp->tp_file);
+ tup = ALLOCTUP(tuplen);
+ USEMEM(node, tuplen);
+ TRACEMEM(merge);
+ SETTUPLEN(tup, tuplen);
+ GETTUP(node, tup, tuplen, tp->tp_file);
+ puttuple(&tuples, tup, tp - PS(node)->Tape,
+ &PS(node)->treeContext);
+ }
+ }
+ }
+ while (tuples != NULL)
+ {
+ /* possible optimization by using count in tuples */
+ tup = gettuple(&tuples, &fromtape, &PS(node)->treeContext);
+ PUTTUP(node, tup, destfile);
+ FREEMEM(node, tup->t_len);
+ FREE(tup);
+ TRACEMEM(merge);
+ GETLEN(tuplen, PS(node)->Tape[fromtape].tp_file);
+ if (tuplen == 0)
+ ;
+ else
+ {
+ tup = ALLOCTUP(tuplen);
+ USEMEM(node, tuplen);
+ TRACEMEM(merge);
+ SETTUPLEN(tup, tuplen);
+ GETTUP(node, tup, tuplen, PS(node)->Tape[fromtape].tp_file);
+ puttuple(&tuples, tup, fromtape, &PS(node)->treeContext);
+ }
}
- }
+ ENDRUN(destfile);
}
- while (tuples != NULL) {
- /* possible optimization by using count in tuples */
- tup = gettuple(&tuples, &fromtape, &PS(node)->treeContext);
- PUTTUP(node, tup, destfile);
- FREEMEM(node,tup->t_len);
- FREE(tup);
- TRACEMEM(merge);
- GETLEN(tuplen, PS(node)->Tape[fromtape].tp_file);
- if (tuplen == 0)
- ;
- else {
- tup = ALLOCTUP(tuplen);
- USEMEM(node,tuplen);
- TRACEMEM(merge);
- SETTUPLEN(tup, tuplen);
- GETTUP(node, tup, tuplen, PS(node)->Tape[fromtape].tp_file);
- puttuple(&tuples, tup, fromtape, &PS(node)->treeContext);
- }
- }
- ENDRUN(destfile);
- }
- PS(node)->TotalDummy += outdummy;
+ PS(node)->TotalDummy += outdummy;
}
/*
* dumptuples - stores all the tuples in tree into file
*/
static void
-dumptuples(FILE *file, Sort *node)
+dumptuples(FILE * file, Sort * node)
{
- register struct leftist *tp;
- register struct leftist *newp;
- struct leftist **treep = &PS(node)->Tuples;
- LeftistContext context = &PS(node)->treeContext;
- HeapTuple tup;
- int memtupindex = 0;
-
- if (! PS(node)->using_tape_files && PS(node)->tupcount) {
- Assert(PS(node)->memtuples == NULL);
- PS(node)->memtuples = palloc(PS(node)->tupcount * sizeof(HeapTuple));
- }
-
- tp = *treep;
- while (tp != NULL) {
- tup = tp->lt_tuple;
- if (tp->lt_dist == 1) /* lt_right == NULL */
- newp = tp->lt_left;
- else
- newp = lmerge(tp->lt_left, tp->lt_right, context);
- FREEMEM(node,sizeof (struct leftist));
- FREE(tp);
- if (PS(node)->using_tape_files) {
- PUTTUP(node, tup, file);
- FREEMEM(node,tup->t_len);
- FREE(tup);
+ register struct leftist *tp;
+ register struct leftist *newp;
+ struct leftist **treep = &PS(node)->Tuples;
+ LeftistContext context = &PS(node)->treeContext;
+ HeapTuple tup;
+ int memtupindex = 0;
+
+ if (!PS(node)->using_tape_files && PS(node)->tupcount)
+ {
+ Assert(PS(node)->memtuples == NULL);
+ PS(node)->memtuples = palloc(PS(node)->tupcount * sizeof(HeapTuple));
}
- else
- PS(node)->memtuples[memtupindex++] = tup;
- tp = newp;
- }
- *treep = NULL;
+ tp = *treep;
+ while (tp != NULL)
+ {
+ tup = tp->lt_tuple;
+ if (tp->lt_dist == 1) /* lt_right == NULL */
+ newp = tp->lt_left;
+ else
+ newp = lmerge(tp->lt_left, tp->lt_right, context);
+ FREEMEM(node, sizeof(struct leftist));
+ FREE(tp);
+ if (PS(node)->using_tape_files)
+ {
+ PUTTUP(node, tup, file);
+ FREEMEM(node, tup->t_len);
+ FREE(tup);
+ }
+ else
+ PS(node)->memtuples[memtupindex++] = tup;
+
+ tp = newp;
+ }
+ *treep = NULL;
}
/*
- * psort_grabtuple - gets a tuple from the sorted file and returns it.
- * If there are no tuples left, returns NULL.
- * Should not call psort_end unless this has returned
- * a NULL indicating the last tuple has been processed.
+ * psort_grabtuple - gets a tuple from the sorted file and returns it.
+ * If there are no tuples left, returns NULL.
+ * Should not call psort_end unless this has returned
+ * a NULL indicating the last tuple has been processed.
*/
HeapTuple
-psort_grabtuple(Sort *node)
+psort_grabtuple(Sort * node)
{
- register HeapTuple tup;
- long tuplen;
-
- Assert(node != (Sort *) NULL);
- Assert(PS(node) != (Psortstate *) NULL);
-
- if (PS(node)->using_tape_files == true) {
- if (!feof(PS(node)->psort_grab_file)) {
- if (GETLEN(tuplen, PS(node)->psort_grab_file) && tuplen != 0) {
- tup = (HeapTuple)palloc((unsigned)tuplen);
- SETTUPLEN(tup, tuplen);
- GETTUP(node, tup, tuplen, PS(node)->psort_grab_file);
-
- /* Update current merged sort file position */
- PS(node)->psort_current += tuplen;
-
- return tup;
- }
- else
- return NULL;
- }
- else
- return NULL;
- }
- else {
- if (PS(node)->psort_current < PS(node)->tupcount)
- return PS(node)->memtuples[PS(node)->psort_current++];
- else
- return NULL;
- }
+ register HeapTuple tup;
+ long tuplen;
+
+ Assert(node != (Sort *) NULL);
+ Assert(PS(node) != (Psortstate *) NULL);
+
+ if (PS(node)->using_tape_files == true)
+ {
+ if (!feof(PS(node)->psort_grab_file))
+ {
+ if (GETLEN(tuplen, PS(node)->psort_grab_file) && tuplen != 0)
+ {
+ tup = (HeapTuple) palloc((unsigned) tuplen);
+ SETTUPLEN(tup, tuplen);
+ GETTUP(node, tup, tuplen, PS(node)->psort_grab_file);
+
+ /* Update current merged sort file position */
+ PS(node)->psort_current += tuplen;
+
+ return tup;
+ }
+ else
+ return NULL;
+ }
+ else
+ return NULL;
+ }
+ else
+ {
+ if (PS(node)->psort_current < PS(node)->tupcount)
+ return PS(node)->memtuples[PS(node)->psort_current++];
+ else
+ return NULL;
+ }
}
/*
- * psort_markpos - saves current position in the merged sort file
+ * psort_markpos - saves current position in the merged sort file
*/
void
-psort_markpos(Sort *node)
+psort_markpos(Sort * node)
{
- Assert(node != (Sort *) NULL);
- Assert(PS(node) != (Psortstate *) NULL);
+ Assert(node != (Sort *) NULL);
+ Assert(PS(node) != (Psortstate *) NULL);
- PS(node)->psort_saved = PS(node)->psort_current;
+ PS(node)->psort_saved = PS(node)->psort_current;
}
/*
- * psort_restorepos- restores current position in merged sort file to
- * last saved position
+ * psort_restorepos- restores current position in merged sort file to
+ * last saved position
*/
void
-psort_restorepos(Sort *node)
+psort_restorepos(Sort * node)
{
- Assert(node != (Sort *) NULL);
- Assert(PS(node) != (Psortstate *) NULL);
+ Assert(node != (Sort *) NULL);
+ Assert(PS(node) != (Psortstate *) NULL);
- if (PS(node)->using_tape_files == true)
- fseek(PS(node)->psort_grab_file, PS(node)->psort_saved, SEEK_SET);
- PS(node)->psort_current = PS(node)->psort_saved;
+ if (PS(node)->using_tape_files == true)
+ fseek(PS(node)->psort_grab_file, PS(node)->psort_saved, SEEK_SET);
+ PS(node)->psort_current = PS(node)->psort_saved;
}
/*
- * psort_end - unlinks the tape files, and cleans up. Should not be
- * called unless psort_grabtuple has returned a NULL.
+ * psort_end - unlinks the tape files, and cleans up. Should not be
+ * called unless psort_grabtuple has returned a NULL.
*/
void
-psort_end(Sort *node)
+psort_end(Sort * node)
{
- register struct tape *tp;
-
- if (!node->cleaned) {
- Assert(node != (Sort *) NULL);
-/* Assert(PS(node) != (Psortstate *) NULL); */
-
- /*
- * I'm changing this because if we are sorting a relation
- * with no tuples, psortstate is NULL.
- */
- if (PS(node) != (Psortstate *) NULL) {
- if (PS(node)->using_tape_files == true)
- for (tp = PS(node)->Tape + PS(node)->TapeRange; tp >= PS(node)->Tape; tp--)
- destroytape(tp->tp_file);
- else if (PS(node)->memtuples)
- pfree(PS(node)->memtuples);
-
- NDirectFileRead +=
- (int)ceil((double)PS(node)->BytesRead / BLCKSZ);
- NDirectFileWrite +=
- (int)ceil((double)PS(node)->BytesWritten / BLCKSZ);
-
- pfree((void *)node->psortstate);
-
- node->cleaned = TRUE;
+ register struct tape *tp;
+
+ if (!node->cleaned)
+ {
+ Assert(node != (Sort *) NULL);
+/* Assert(PS(node) != (Psortstate *) NULL); */
+
+ /*
+ * I'm changing this because if we are sorting a relation with no
+ * tuples, psortstate is NULL.
+ */
+ if (PS(node) != (Psortstate *) NULL)
+ {
+ if (PS(node)->using_tape_files == true)
+ for (tp = PS(node)->Tape + PS(node)->TapeRange; tp >= PS(node)->Tape; tp--)
+ destroytape(tp->tp_file);
+ else if (PS(node)->memtuples)
+ pfree(PS(node)->memtuples);
+
+ NDirectFileRead +=
+ (int) ceil((double) PS(node)->BytesRead / BLCKSZ);
+ NDirectFileWrite +=
+ (int) ceil((double) PS(node)->BytesWritten / BLCKSZ);
+
+ pfree((void *) node->psortstate);
+
+ node->cleaned = TRUE;
+ }
}
- }
}
/*
- * gettape - handles access temporary files in polyphase merging
+ * gettape - handles access temporary files in polyphase merging
*
- * Optimizations:
- * If guarenteed that only one sort running/process,
- * can simplify the file generation--and need not store the
- * name for later unlink.
+ * Optimizations:
+ * If guarenteed that only one sort running/process,
+ * can simplify the file generation--and need not store the
+ * name for later unlink.
*/
-struct tapelst {
- char *tl_name;
- int tl_fd;
- struct tapelst *tl_next;
+struct tapelst
+{
+ char *tl_name;
+ int tl_fd;
+ struct tapelst *tl_next;
};
-static struct tapelst *Tapes = NULL;
+static struct tapelst *Tapes = NULL;
/*
- * gettape - returns an open stream for writing/reading
+ * gettape - returns an open stream for writing/reading
*
- * Returns:
- * Open stream for writing/reading.
- * NULL if unable to open temporary file.
+ * Returns:
+ * Open stream for writing/reading.
+ * NULL if unable to open temporary file.
*/
-static FILE *
+static FILE *
gettape()
{
- register struct tapelst *tp;
- FILE *file;
- static int tapeinit = 0;
- char *mktemp();
- static unsigned int uniqueFileId = 0;
- extern int errno;
- char uniqueName[MAXPGPATH];
-
- tp = (struct tapelst *)palloc((unsigned)sizeof (struct tapelst));
-
- sprintf(uniqueName, "%spg_psort.%d.%d", TEMPDIR, (int)getpid(), uniqueFileId);
- uniqueFileId++;
-
- tapeinit = 1;
-
- tp->tl_name = palloc((unsigned)sizeof(uniqueName));
-
- /*
- * now, copy template with final null into palloc'd space
- */
-
- memmove(tp->tl_name, uniqueName, strlen(uniqueName));
-
-
- file = AllocateFile(tp->tl_name, "w+");
- if (file == NULL)
- elog(WARN,"Open: %s in %s line %d, %s", tp->tl_name,
- __FILE__, __LINE__, strerror(errno));
-
- tp->tl_fd = fileno(file);
- tp->tl_next = Tapes;
- Tapes = tp;
- return(file);
+ register struct tapelst *tp;
+ FILE *file;
+ static int tapeinit = 0;
+ char *mktemp();
+ static unsigned int uniqueFileId = 0;
+ extern int errno;
+ char uniqueName[MAXPGPATH];
+
+ tp = (struct tapelst *) palloc((unsigned) sizeof(struct tapelst));
+
+ sprintf(uniqueName, "%spg_psort.%d.%d", TEMPDIR, (int) getpid(), uniqueFileId);
+ uniqueFileId++;
+
+ tapeinit = 1;
+
+ tp->tl_name = palloc((unsigned) sizeof(uniqueName));
+
+ /*
+ * now, copy template with final null into palloc'd space
+ */
+
+ memmove(tp->tl_name, uniqueName, strlen(uniqueName));
+
+
+ file = AllocateFile(tp->tl_name, "w+");
+ if (file == NULL)
+ elog(WARN, "Open: %s in %s line %d, %s", tp->tl_name,
+ __FILE__, __LINE__, strerror(errno));
+
+ tp->tl_fd = fileno(file);
+ tp->tl_next = Tapes;
+ Tapes = tp;
+ return (file);
}
/*
- * resettape - resets the tape to size 0
+ * resettape - resets the tape to size 0
*/
#ifdef NOT_USED
static void
-resettape(FILE *file)
+resettape(FILE * file)
{
- register struct tapelst *tp;
- register int fd;
-
- Assert(PointerIsValid(file));
-
- fd = fileno(file);
- for (tp = Tapes; tp != NULL && tp->tl_fd != fd; tp = tp->tl_next)
- ;
- if (tp == NULL)
- elog(WARN, "resettape: tape not found");
-
- file = freopen(tp->tl_name, "w+", file);
- if (file == NULL) {
- elog(FATAL, "could not freopen temporary file");
- }
+ register struct tapelst *tp;
+ register int fd;
+
+ Assert(PointerIsValid(file));
+
+ fd = fileno(file);
+ for (tp = Tapes; tp != NULL && tp->tl_fd != fd; tp = tp->tl_next)
+ ;
+ if (tp == NULL)
+ elog(WARN, "resettape: tape not found");
+
+ file = freopen(tp->tl_name, "w+", file);
+ if (file == NULL)
+ {
+ elog(FATAL, "could not freopen temporary file");
+ }
}
+
#endif
/*
- * distroytape - unlinks the tape
+ * distroytape - unlinks the tape
*
- * Efficiency note:
- * More efficient to destroy more recently allocated tapes first.
+ * Efficiency note:
+ * More efficient to destroy more recently allocated tapes first.
*
- * Possible bugs:
- * Exits instead of returning status, if given invalid tape.
+ * Possible bugs:
+ * Exits instead of returning status, if given invalid tape.
*/
static void
-destroytape(FILE *file)
+destroytape(FILE * file)
{
- register struct tapelst *tp, *tq;
- register int fd;
-
- if ((tp = Tapes) == NULL)
- elog(FATAL, "destroytape: tape not found");
-
- if ((fd = fileno(file)) == tp->tl_fd) {
- Tapes = tp->tl_next;
- FreeFile(file);
- unlink(tp->tl_name);
- FREE(tp->tl_name);
- FREE(tp);
- } else
- for ( ; ; ) {
- if (tp->tl_next == NULL)
+ register struct tapelst *tp,
+ *tq;
+ register int fd;
+
+ if ((tp = Tapes) == NULL)
elog(FATAL, "destroytape: tape not found");
- if (tp->tl_next->tl_fd == fd) {
+
+ if ((fd = fileno(file)) == tp->tl_fd)
+ {
+ Tapes = tp->tl_next;
FreeFile(file);
- tq = tp->tl_next;
- tp->tl_next = tq->tl_next;
- unlink(tq->tl_name);
- FREE((tq->tl_name));
- FREE(tq);
- break;
- }
- tp = tp->tl_next;
+ unlink(tp->tl_name);
+ FREE(tp->tl_name);
+ FREE(tp);
}
+ else
+ for (;;)
+ {
+ if (tp->tl_next == NULL)
+ elog(FATAL, "destroytape: tape not found");
+ if (tp->tl_next->tl_fd == fd)
+ {
+ FreeFile(file);
+ tq = tp->tl_next;
+ tp->tl_next = tq->tl_next;
+ unlink(tq->tl_name);
+ FREE((tq->tl_name));
+ FREE(tq);
+ break;
+ }
+ tp = tp->tl_next;
+ }
}
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c
index 1fcf3679fe4..2a85ecd712b 100644
--- a/src/backend/utils/time/tqual.c
+++ b/src/backend/utils/time/tqual.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* tqual.c--
- * POSTGRES time qualification code.
+ * POSTGRES time qualification code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.4 1997/08/29 09:04:54 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.5 1997/09/07 04:54:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,23 +29,23 @@
static AbsoluteTime TimeQualGetEndTime(TimeQual qual);
static AbsoluteTime TimeQualGetSnapshotTime(TimeQual qual);
static AbsoluteTime TimeQualGetStartTime(TimeQual qual);
-static bool TimeQualIncludesNow(TimeQual qual);
-static bool TimeQualIndicatesDisableValidityChecking(TimeQual qual);
-static bool TimeQualIsLegal(TimeQual qual);
-static bool TimeQualIsRanged(TimeQual qual);
-static bool TimeQualIsSnapshot(TimeQual qual);
-static bool TimeQualIsValid(TimeQual qual);
+static bool TimeQualIncludesNow(TimeQual qual);
+static bool TimeQualIndicatesDisableValidityChecking(TimeQual qual);
+static bool TimeQualIsLegal(TimeQual qual);
+static bool TimeQualIsRanged(TimeQual qual);
+static bool TimeQualIsSnapshot(TimeQual qual);
+static bool TimeQualIsValid(TimeQual qual);
/*
* TimeQualMode --
- * Mode indicator for treatment of time qualifications.
+ * Mode indicator for treatment of time qualifications.
*/
typedef uint16 TimeQualMode;
-#define TimeQualAt 0x1
+#define TimeQualAt 0x1
#define TimeQualNewer 0x2
#define TimeQualOlder 0x4
-#define TimeQualAll 0x8
+#define TimeQualAll 0x8
#define TimeQualMask 0xf
@@ -53,820 +53,903 @@ typedef uint16 TimeQualMode;
#define TimeQualRange (TimeQualNewer | TimeQualOlder)
#define TimeQualAllAt (TimeQualAt | TimeQualAll)
-typedef struct TimeQualData {
- AbsoluteTime start;
- AbsoluteTime end;
- TimeQualMode mode;
-} TimeQualData;
+typedef struct TimeQualData
+{
+ AbsoluteTime start;
+ AbsoluteTime end;
+ TimeQualMode mode;
+} TimeQualData;
-typedef TimeQualData *InternalTimeQual;
+typedef TimeQualData *InternalTimeQual;
-static TimeQualData SelfTimeQualData;
-TimeQual SelfTimeQual = (Pointer)&SelfTimeQualData;
+static TimeQualData SelfTimeQualData;
+TimeQual SelfTimeQual = (Pointer) & SelfTimeQualData;
extern bool PostgresIsInitialized;
/*
* XXX Transaction system override hacks start here
*/
-#ifndef GOODAMI
+#ifndef GOODAMI
-static TransactionId HeapSpecialTransactionId = InvalidTransactionId;
-static CommandId HeapSpecialCommandId = FirstCommandId;
+static TransactionId HeapSpecialTransactionId = InvalidTransactionId;
+static CommandId HeapSpecialCommandId = FirstCommandId;
void
setheapoverride(bool on)
{
- if (on) {
- TransactionIdStore(GetCurrentTransactionId(),
- &HeapSpecialTransactionId);
- HeapSpecialCommandId = GetCurrentCommandId();
- } else {
- HeapSpecialTransactionId = InvalidTransactionId;
- }
+ if (on)
+ {
+ TransactionIdStore(GetCurrentTransactionId(),
+ &HeapSpecialTransactionId);
+ HeapSpecialCommandId = GetCurrentCommandId();
+ }
+ else
+ {
+ HeapSpecialTransactionId = InvalidTransactionId;
+ }
}
/* static */
bool
heapisoverride()
{
- if (!TransactionIdIsValid(HeapSpecialTransactionId)) {
- return (false);
- }
-
- if (!TransactionIdEquals(GetCurrentTransactionId(),
- HeapSpecialTransactionId) ||
- GetCurrentCommandId() != HeapSpecialCommandId) {
- HeapSpecialTransactionId = InvalidTransactionId;
-
- return (false);
- }
- return (true);
+ if (!TransactionIdIsValid(HeapSpecialTransactionId))
+ {
+ return (false);
+ }
+
+ if (!TransactionIdEquals(GetCurrentTransactionId(),
+ HeapSpecialTransactionId) ||
+ GetCurrentCommandId() != HeapSpecialCommandId)
+ {
+ HeapSpecialTransactionId = InvalidTransactionId;
+
+ return (false);
+ }
+ return (true);
}
-#endif /* !defined(GOODAMI) */
+#endif /* !defined(GOODAMI) */
/*
* XXX Transaction system override hacks end here
*/
-static bool HeapTupleSatisfiesItself(HeapTuple tuple);
-static bool HeapTupleSatisfiesNow(HeapTuple tuple);
-static bool HeapTupleSatisfiesSnapshotInternalTimeQual(HeapTuple tuple,
- InternalTimeQual qual);
-static bool HeapTupleSatisfiesUpperBoundedInternalTimeQual(HeapTuple tuple,
- InternalTimeQual qual);
-static bool HeapTupleSatisfiesUpperUnboundedInternalTimeQual(HeapTuple tuple,
- InternalTimeQual qual);
+static bool HeapTupleSatisfiesItself(HeapTuple tuple);
+static bool HeapTupleSatisfiesNow(HeapTuple tuple);
+static bool
+HeapTupleSatisfiesSnapshotInternalTimeQual(HeapTuple tuple,
+ InternalTimeQual qual);
+static bool
+HeapTupleSatisfiesUpperBoundedInternalTimeQual(HeapTuple tuple,
+ InternalTimeQual qual);
+static bool
+HeapTupleSatisfiesUpperUnboundedInternalTimeQual(HeapTuple tuple,
+ InternalTimeQual qual);
+
-
/*
* TimeQualIsValid --
- * True iff time qualification is valid.
+ * True iff time qualification is valid.
*/
-static bool
+static bool
TimeQualIsValid(TimeQual qual)
{
- bool hasStartTime;
-
- if (!PointerIsValid(qual) || qual == SelfTimeQual) {
+ bool hasStartTime;
+
+ if (!PointerIsValid(qual) || qual == SelfTimeQual)
+ {
+ return (true);
+ }
+
+ if (((InternalTimeQual) qual)->mode & ~TimeQualMask)
+ {
+ return (false);
+ }
+
+ if (((InternalTimeQual) qual)->mode & TimeQualAt)
+ {
+ return (AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual) qual)->start));
+ }
+
+ hasStartTime = false;
+
+ if (((InternalTimeQual) qual)->mode & TimeQualNewer)
+ {
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual) qual)->start))
+ {
+ return (false);
+ }
+ hasStartTime = true;
+ }
+
+ if (((InternalTimeQual) qual)->mode & TimeQualOlder)
+ {
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual) qual)->end))
+ {
+ return (false);
+ }
+ if (hasStartTime)
+ {
+ return ((bool) ! AbsoluteTimeIsBefore(
+ ((InternalTimeQual) qual)->end,
+ ((InternalTimeQual) qual)->start));
+ }
+ }
return (true);
- }
-
- if (((InternalTimeQual)qual)->mode & ~TimeQualMask) {
- return (false);
- }
-
- if (((InternalTimeQual)qual)->mode & TimeQualAt) {
- return (AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual)qual)->start));
- }
-
- hasStartTime = false;
-
- if (((InternalTimeQual)qual)->mode & TimeQualNewer) {
- if (!AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual)qual)->start)) {
- return (false);
- }
- hasStartTime = true;
- }
-
- if (((InternalTimeQual)qual)->mode & TimeQualOlder) {
- if (!AbsoluteTimeIsBackwardCompatiblyValid(((InternalTimeQual)qual)->end)) {
- return (false);
- }
- if (hasStartTime) {
- return ((bool)!AbsoluteTimeIsBefore(
- ((InternalTimeQual)qual)->end,
- ((InternalTimeQual)qual)->start));
- }
- }
- return (true);
}
/*
* TimeQualIsLegal --
- * True iff time qualification is legal.
- * I.e., true iff time qualification does not intersects the future,
- * relative to the transaction start time.
+ * True iff time qualification is legal.
+ * I.e., true iff time qualification does not intersects the future,
+ * relative to the transaction start time.
*
* Note:
- * Assumes time qualification is valid.
+ * Assumes time qualification is valid.
*/
-static bool
+static bool
TimeQualIsLegal(TimeQual qual)
{
- Assert(TimeQualIsValid(qual));
-
- if (qual == NowTimeQual || qual == SelfTimeQual) {
+ Assert(TimeQualIsValid(qual));
+
+ if (qual == NowTimeQual || qual == SelfTimeQual)
+ {
+ return (true);
+ }
+
+ /* TimeQualAt */
+ if (((InternalTimeQual) qual)->mode & TimeQualAt)
+ {
+ AbsoluteTime a,
+ b;
+
+ a = ((InternalTimeQual) qual)->start;
+ b = GetCurrentTransactionStartTime();
+
+ if (AbsoluteTimeIsAfter(a, b))
+ return (false);
+ else
+ return (true);
+ }
+
+ /* TimeQualOlder or TimeQualRange */
+ if (((InternalTimeQual) qual)->mode & TimeQualOlder)
+ {
+ AbsoluteTime a,
+ b;
+
+ a = ((InternalTimeQual) qual)->end;
+ b = GetCurrentTransactionStartTime();
+
+ if (AbsoluteTimeIsAfter(a, b))
+ return (false);
+ else
+ return (true);
+ }
+
+ /* TimeQualNewer */
+ if (((InternalTimeQual) qual)->mode & TimeQualNewer)
+ {
+ AbsoluteTime a,
+ b;
+
+ a = ((InternalTimeQual) qual)->start;
+ b = GetCurrentTransactionStartTime();
+
+ if (AbsoluteTimeIsAfter(a, b))
+ return (false);
+ else
+ return (true);
+ }
+
+ /* TimeQualEvery */
return (true);
- }
-
- /* TimeQualAt */
- if (((InternalTimeQual)qual)->mode & TimeQualAt) {
- AbsoluteTime a, b;
-
- a = ((InternalTimeQual)qual)->start;
- b = GetCurrentTransactionStartTime();
-
- if (AbsoluteTimeIsAfter(a, b))
- return (false);
- else
- return (true);
- }
-
- /* TimeQualOlder or TimeQualRange */
- if (((InternalTimeQual)qual)->mode & TimeQualOlder) {
- AbsoluteTime a, b;
-
- a = ((InternalTimeQual)qual)->end;
- b = GetCurrentTransactionStartTime();
-
- if (AbsoluteTimeIsAfter(a, b))
- return (false);
- else
- return (true);
- }
-
- /* TimeQualNewer */
- if (((InternalTimeQual)qual)->mode & TimeQualNewer) {
- AbsoluteTime a, b;
-
- a = ((InternalTimeQual)qual)->start;
- b = GetCurrentTransactionStartTime();
-
- if (AbsoluteTimeIsAfter(a, b))
- return (false);
- else
- return (true);
- }
-
- /* TimeQualEvery */
- return (true);
}
/*
* TimeQualIncludesNow --
- * True iff time qualification includes "now."
+ * True iff time qualification includes "now."
*
* Note:
- * Assumes time qualification is valid.
+ * Assumes time qualification is valid.
*/
-static bool
+static bool
TimeQualIncludesNow(TimeQual qual)
{
- Assert(TimeQualIsValid(qual));
-
- if (qual == NowTimeQual || qual == SelfTimeQual) {
+ Assert(TimeQualIsValid(qual));
+
+ if (qual == NowTimeQual || qual == SelfTimeQual)
+ {
+ return (true);
+ }
+
+ if (((InternalTimeQual) qual)->mode & TimeQualAt)
+ {
+ return (false);
+ }
+ if (((InternalTimeQual) qual)->mode & TimeQualOlder &&
+ !AbsoluteTimeIsAfter(
+ ((InternalTimeQual) qual)->end,
+ GetCurrentTransactionStartTime()))
+ {
+
+ return (false);
+ }
return (true);
- }
-
- if (((InternalTimeQual)qual)->mode & TimeQualAt) {
- return (false);
- }
- if (((InternalTimeQual)qual)->mode & TimeQualOlder &&
- !AbsoluteTimeIsAfter(
- ((InternalTimeQual)qual)->end,
- GetCurrentTransactionStartTime())) {
-
- return (false);
- }
- return (true);
}
/*
* TimeQualIncludesPast --
- * True iff time qualification includes some time in the past.
+ * True iff time qualification includes some time in the past.
*
* Note:
- * Assumes time qualification is valid.
- * XXX may not be needed?
+ * Assumes time qualification is valid.
+ * XXX may not be needed?
*/
#ifdef NOT_USED
bool
TimeQualIncludesPast(TimeQual qual)
{
- Assert(TimeQualIsValid(qual));
-
- if (qual == NowTimeQual || qual == SelfTimeQual) {
- return (false);
- }
-
- /* otherwise, must check archive (setting locks as appropriate) */
- return (true);
+ Assert(TimeQualIsValid(qual));
+
+ if (qual == NowTimeQual || qual == SelfTimeQual)
+ {
+ return (false);
+ }
+
+ /* otherwise, must check archive (setting locks as appropriate) */
+ return (true);
}
+
#endif
/*
* TimeQualIsSnapshot --
- * True iff time qualification is a snapshot qualification.
+ * True iff time qualification is a snapshot qualification.
*
* Note:
- * Assumes time qualification is valid.
+ * Assumes time qualification is valid.
*/
-static bool
+static bool
TimeQualIsSnapshot(TimeQual qual)
{
- Assert(TimeQualIsValid(qual));
-
- if (qual == NowTimeQual || qual == SelfTimeQual) {
- return (false);
- }
-
- return ((bool)!!(((InternalTimeQual)qual)->mode & TimeQualAt));
+ Assert(TimeQualIsValid(qual));
+
+ if (qual == NowTimeQual || qual == SelfTimeQual)
+ {
+ return (false);
+ }
+
+ return ((bool) ! !(((InternalTimeQual) qual)->mode & TimeQualAt));
}
/*
* TimeQualIsRanged --
- * True iff time qualification is a ranged qualification.
+ * True iff time qualification is a ranged qualification.
*
* Note:
- * Assumes time qualification is valid.
+ * Assumes time qualification is valid.
*/
-static bool
+static bool
TimeQualIsRanged(TimeQual qual)
{
- Assert(TimeQualIsValid(qual));
-
- if (qual == NowTimeQual || qual == SelfTimeQual) {
- return (false);
- }
-
- return ((bool)!(((InternalTimeQual)qual)->mode & TimeQualAt));
+ Assert(TimeQualIsValid(qual));
+
+ if (qual == NowTimeQual || qual == SelfTimeQual)
+ {
+ return (false);
+ }
+
+ return ((bool) ! (((InternalTimeQual) qual)->mode & TimeQualAt));
}
/*
* TimeQualIndicatesDisableValidityChecking --
- * True iff time qualification indicates validity checking should be
- * disabled.
+ * True iff time qualification indicates validity checking should be
+ * disabled.
*
* Note:
- * XXX This should not be implemented since this does not make sense.
+ * XXX This should not be implemented since this does not make sense.
*/
-static bool
+static bool
TimeQualIndicatesDisableValidityChecking(TimeQual qual)
{
- Assert (TimeQualIsValid(qual));
-
- if (qual == NowTimeQual || qual == SelfTimeQual) {
+ Assert(TimeQualIsValid(qual));
+
+ if (qual == NowTimeQual || qual == SelfTimeQual)
+ {
+ return (false);
+ }
+
+ if (((InternalTimeQual) qual)->mode & TimeQualAll)
+ {
+ return (true);
+ }
return (false);
- }
-
- if (((InternalTimeQual)qual)->mode & TimeQualAll) {
- return (true);
- }
- return (false);
}
/*
* TimeQualGetSnapshotTime --
- * Returns time for a snapshot time qual.
+ * Returns time for a snapshot time qual.
*
* Note:
- * Assumes time qual is valid snapshot time qual.
+ * Assumes time qual is valid snapshot time qual.
*/
-static AbsoluteTime
+static AbsoluteTime
TimeQualGetSnapshotTime(TimeQual qual)
{
- Assert(TimeQualIsSnapshot(qual));
-
- return (((InternalTimeQual)qual)->start);
+ Assert(TimeQualIsSnapshot(qual));
+
+ return (((InternalTimeQual) qual)->start);
}
/*
* TimeQualGetStartTime --
- * Returns start time for a ranged time qual.
+ * Returns start time for a ranged time qual.
*
* Note:
- * Assumes time qual is valid ranged time qual.
+ * Assumes time qual is valid ranged time qual.
*/
-static AbsoluteTime
+static AbsoluteTime
TimeQualGetStartTime(TimeQual qual)
{
- Assert(TimeQualIsRanged(qual));
-
- return (((InternalTimeQual)qual)->start);
+ Assert(TimeQualIsRanged(qual));
+
+ return (((InternalTimeQual) qual)->start);
}
/*
* TimeQualGetEndTime --
- * Returns end time for a ranged time qual.
+ * Returns end time for a ranged time qual.
*
* Note:
- * Assumes time qual is valid ranged time qual.
+ * Assumes time qual is valid ranged time qual.
*/
-static AbsoluteTime
+static AbsoluteTime
TimeQualGetEndTime(TimeQual qual)
{
- Assert(TimeQualIsRanged(qual));
-
- return (((InternalTimeQual)qual)->end);
+ Assert(TimeQualIsRanged(qual));
+
+ return (((InternalTimeQual) qual)->end);
}
/*
* TimeFormSnapshotTimeQual --
- * Returns snapshot time qual for a time.
+ * Returns snapshot time qual for a time.
*
* Note:
- * Assumes time is valid.
+ * Assumes time is valid.
*/
TimeQual
TimeFormSnapshotTimeQual(AbsoluteTime time)
{
- InternalTimeQual qual;
-
- Assert(AbsoluteTimeIsBackwardCompatiblyValid(time));
-
- qual = (InternalTimeQual)palloc(sizeof *qual);
-
- qual->start = time;
- qual->end = INVALID_ABSTIME;
- qual->mode = TimeQualAt;
-
- return ((TimeQual)qual);
+ InternalTimeQual qual;
+
+ Assert(AbsoluteTimeIsBackwardCompatiblyValid(time));
+
+ qual = (InternalTimeQual) palloc(sizeof *qual);
+
+ qual->start = time;
+ qual->end = INVALID_ABSTIME;
+ qual->mode = TimeQualAt;
+
+ return ((TimeQual) qual);
}
/*
* TimeFormRangedTimeQual --
- * Returns ranged time qual for a pair of times.
+ * Returns ranged time qual for a pair of times.
*
* Note:
- * If start time is invalid, it is regarded as the epoch.
- * If end time is invalid, it is regarded as "now."
- * Assumes start time is before (or the same as) end time.
+ * If start time is invalid, it is regarded as the epoch.
+ * If end time is invalid, it is regarded as "now."
+ * Assumes start time is before (or the same as) end time.
*/
TimeQual
TimeFormRangedTimeQual(AbsoluteTime startTime,
- AbsoluteTime endTime)
+ AbsoluteTime endTime)
{
- InternalTimeQual qual;
-
- qual = (InternalTimeQual)palloc(sizeof *qual);
-
- qual->start = startTime;
- qual->end = endTime;
- qual->mode = TimeQualEvery;
-
- if (AbsoluteTimeIsBackwardCompatiblyValid(startTime)) {
- qual->mode |= TimeQualNewer;
- }
- if (AbsoluteTimeIsBackwardCompatiblyValid(endTime)) {
- qual->mode |= TimeQualOlder;
- }
-
- return ((TimeQual)qual);
+ InternalTimeQual qual;
+
+ qual = (InternalTimeQual) palloc(sizeof *qual);
+
+ qual->start = startTime;
+ qual->end = endTime;
+ qual->mode = TimeQualEvery;
+
+ if (AbsoluteTimeIsBackwardCompatiblyValid(startTime))
+ {
+ qual->mode |= TimeQualNewer;
+ }
+ if (AbsoluteTimeIsBackwardCompatiblyValid(endTime))
+ {
+ qual->mode |= TimeQualOlder;
+ }
+
+ return ((TimeQual) qual);
}
/*
* HeapTupleSatisfiesTimeQual --
- * True iff heap tuple satsifies a time qual.
+ * True iff heap tuple satsifies a time qual.
*
* Note:
- * Assumes heap tuple is valid.
- * Assumes time qual is valid.
- * XXX Many of the checks may be simplified and still remain correct.
- * XXX Partial answers to the checks may be cached in an ItemId.
+ * Assumes heap tuple is valid.
+ * Assumes time qual is valid.
+ * XXX Many of the checks may be simplified and still remain correct.
+ * XXX Partial answers to the checks may be cached in an ItemId.
*/
bool
HeapTupleSatisfiesTimeQual(HeapTuple tuple, TimeQual qual)
{
-/* extern TransactionId AmiTransactionId; */
-
- Assert(HeapTupleIsValid(tuple));
- Assert(TimeQualIsValid(qual));
-
- if (TransactionIdEquals(tuple->t_xmax, AmiTransactionId))
- return(false);
-
- if (qual == SelfTimeQual || heapisoverride()) {
- return (HeapTupleSatisfiesItself(tuple));
- }
-
- if (qual == NowTimeQual) {
- return (HeapTupleSatisfiesNow(tuple));
- }
-
- if (!TimeQualIsLegal(qual)) {
- elog(WARN, "HeapTupleSatisfiesTimeQual: illegal time qual");
- }
-
- if (TimeQualIndicatesDisableValidityChecking(qual)) {
- elog(WARN, "HeapTupleSatisfiesTimeQual: no disabled validity checking (yet)");
- }
-
- if (TimeQualIsSnapshot(qual)) {
- return (HeapTupleSatisfiesSnapshotInternalTimeQual(tuple,
- (InternalTimeQual)qual));
- }
-
- if (TimeQualIncludesNow(qual)) {
- return (HeapTupleSatisfiesUpperUnboundedInternalTimeQual(tuple,
- (InternalTimeQual)qual));
- }
-
- return (HeapTupleSatisfiesUpperBoundedInternalTimeQual(tuple,
- (InternalTimeQual)qual));
+/* extern TransactionId AmiTransactionId; */
+
+ Assert(HeapTupleIsValid(tuple));
+ Assert(TimeQualIsValid(qual));
+
+ if (TransactionIdEquals(tuple->t_xmax, AmiTransactionId))
+ return (false);
+
+ if (qual == SelfTimeQual || heapisoverride())
+ {
+ return (HeapTupleSatisfiesItself(tuple));
+ }
+
+ if (qual == NowTimeQual)
+ {
+ return (HeapTupleSatisfiesNow(tuple));
+ }
+
+ if (!TimeQualIsLegal(qual))
+ {
+ elog(WARN, "HeapTupleSatisfiesTimeQual: illegal time qual");
+ }
+
+ if (TimeQualIndicatesDisableValidityChecking(qual))
+ {
+ elog(WARN, "HeapTupleSatisfiesTimeQual: no disabled validity checking (yet)");
+ }
+
+ if (TimeQualIsSnapshot(qual))
+ {
+ return (HeapTupleSatisfiesSnapshotInternalTimeQual(tuple,
+ (InternalTimeQual) qual));
+ }
+
+ if (TimeQualIncludesNow(qual))
+ {
+ return (HeapTupleSatisfiesUpperUnboundedInternalTimeQual(tuple,
+ (InternalTimeQual) qual));
+ }
+
+ return (HeapTupleSatisfiesUpperBoundedInternalTimeQual(tuple,
+ (InternalTimeQual) qual));
}
/*
* HeapTupleSatisfiesItself --
- * True iff heap tuple is valid for "itself."
- * "{it}self" means valid as of everything that's happened
- * in the current transaction, _including_ the current command.
+ * True iff heap tuple is valid for "itself."
+ * "{it}self" means valid as of everything that's happened
+ * in the current transaction, _including_ the current command.
*
* Note:
- * Assumes heap tuple is valid.
+ * Assumes heap tuple is valid.
*/
/*
* The satisfaction of "itself" requires the following:
*
- * ((Xmin == my-transaction && the row was updated by the current transaction, and
- * (Xmax is null it was not deleted
- * [|| Xmax != my-transaction)]) [or it was deleted by another transaction]
+ * ((Xmin == my-transaction && the row was updated by the current transaction, and
+ * (Xmax is null it was not deleted
+ * [|| Xmax != my-transaction)]) [or it was deleted by another transaction]
* ||
*
- * (Xmin is committed && the row was modified by a committed transaction, and
- * (Xmax is null || the row has not been deleted, or
- * (Xmax != my-transaction && the row was deleted by another transaction
- * Xmax is not committed))) that has not been committed
+ * (Xmin is committed && the row was modified by a committed transaction, and
+ * (Xmax is null || the row has not been deleted, or
+ * (Xmax != my-transaction && the row was deleted by another transaction
+ * Xmax is not committed))) that has not been committed
*/
-static bool
+static bool
HeapTupleSatisfiesItself(HeapTuple tuple)
{
- /*
- * XXX Several evil casts are made in this routine. Casting XID to be
- * TransactionId works only because TransactionId->data is the first
- * (and only) field of the structure.
- */
- if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) {
- if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) &&
- !TransactionIdIsValid((TransactionId)tuple->t_xmax)) {
- return (true);
- }
-
- if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) {
- return (false);
- }
-
- tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin);
- }
- /* the tuple was inserted validly */
-
- if (AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) {
- return (false);
- }
-
- if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) {
- return (true);
- }
-
- if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)) {
- return (false);
- }
- if (!TransactionIdDidCommit((TransactionId)tuple->t_xmax)) {
- return (true);
- }
-
- /* by here, deleting transaction has committed */
- tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax);
+ /*
+ * XXX Several evil casts are made in this routine. Casting XID to be
+ * TransactionId works only because TransactionId->data is the first
+ * (and only) field of the structure.
+ */
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin))
+ {
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmin) &&
+ !TransactionIdIsValid((TransactionId) tuple->t_xmax))
+ {
+ return (true);
+ }
+
+ if (!TransactionIdDidCommit((TransactionId) tuple->t_xmin))
+ {
+ return (false);
+ }
+
+ tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin);
+ }
+ /* the tuple was inserted validly */
- return (false);
+ if (AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax))
+ {
+ return (false);
+ }
+
+ if (!TransactionIdIsValid((TransactionId) tuple->t_xmax))
+ {
+ return (true);
+ }
+
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmax))
+ {
+ return (false);
+ }
+
+ if (!TransactionIdDidCommit((TransactionId) tuple->t_xmax))
+ {
+ return (true);
+ }
+
+ /* by here, deleting transaction has committed */
+ tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax);
+
+ return (false);
}
/*
* HeapTupleSatisfiesNow --
- * True iff heap tuple is valid "now."
- * "now" means valid including everything that's happened
- * in the current transaction _up to, but not including,_
- * the current command.
+ * True iff heap tuple is valid "now."
+ * "now" means valid including everything that's happened
+ * in the current transaction _up to, but not including,_
+ * the current command.
*
* Note:
- * Assumes heap tuple is valid.
+ * Assumes heap tuple is valid.
*/
/*
* The satisfaction of "now" requires the following:
*
- * ((Xmin == my-transaction && changed by the current transaction
- * Cmin != my-command && but not by this command, and
- * (Xmax is null || the row has not been deleted, or
- * (Xmax == my-transaction && it was deleted by the current transaction
- * Cmax != my-command))) but not by this command,
- * || or
+ * ((Xmin == my-transaction && changed by the current transaction
+ * Cmin != my-command && but not by this command, and
+ * (Xmax is null || the row has not been deleted, or
+ * (Xmax == my-transaction && it was deleted by the current transaction
+ * Cmax != my-command))) but not by this command,
+ * || or
*
- * (Xmin is committed && the row was modified by a committed transaction, and
- * (Xmax is null || the row has not been deleted, or
- * (Xmax == my-transaction && the row is being deleted by this command, or
- * Cmax == my-command) ||
- * (Xmax is not committed && the row was deleted by another transaction
- * Xmax != my-transaction)))) that has not been committed
+ * (Xmin is committed && the row was modified by a committed transaction, and
+ * (Xmax is null || the row has not been deleted, or
+ * (Xmax == my-transaction && the row is being deleted by this command, or
+ * Cmax == my-command) ||
+ * (Xmax is not committed && the row was deleted by another transaction
+ * Xmax != my-transaction)))) that has not been committed
*
* XXX
- * CommandId stuff didn't work properly if one used SQL-functions in
- * UPDATE/INSERT(fromSELECT)/DELETE scans: SQL-funcs call
- * CommandCounterIncrement and made tuples changed/inserted by
- * current command visible to command itself (so we had multiple
- * update of updated tuples, etc). - vadim 08/29/97
- *
- * mao says 17 march 1993: the tests in this routine are correct;
- * if you think they're not, you're wrong, and you should think
- * about it again. i know, it happened to me. we don't need to
- * check commit time against the start time of this transaction
- * because 2ph locking protects us from doing the wrong thing.
- * if you mess around here, you'll break serializability. the only
- * problem with this code is that it does the wrong thing for system
- * catalog updates, because the catalogs aren't subject to 2ph, so
- * the serializability guarantees we provide don't extend to xacts
- * that do catalog accesses. this is unfortunate, but not critical.
+ * CommandId stuff didn't work properly if one used SQL-functions in
+ * UPDATE/INSERT(fromSELECT)/DELETE scans: SQL-funcs call
+ * CommandCounterIncrement and made tuples changed/inserted by
+ * current command visible to command itself (so we had multiple
+ * update of updated tuples, etc). - vadim 08/29/97
+ *
+ * mao says 17 march 1993: the tests in this routine are correct;
+ * if you think they're not, you're wrong, and you should think
+ * about it again. i know, it happened to me. we don't need to
+ * check commit time against the start time of this transaction
+ * because 2ph locking protects us from doing the wrong thing.
+ * if you mess around here, you'll break serializability. the only
+ * problem with this code is that it does the wrong thing for system
+ * catalog updates, because the catalogs aren't subject to 2ph, so
+ * the serializability guarantees we provide don't extend to xacts
+ * that do catalog accesses. this is unfortunate, but not critical.
*/
-static bool
+static bool
HeapTupleSatisfiesNow(HeapTuple tuple)
{
- if (AMI_OVERRIDE)
- return true;
- /*
- * If the transaction system isn't yet initialized, then we assume
- * that transactions committed. We only look at system catalogs
- * during startup, so this is less awful than it seems, but it's
- * still pretty awful.
- */
-
- if (!PostgresIsInitialized)
- return ((bool)(TransactionIdIsValid((TransactionId)tuple->t_xmin) &&
- !TransactionIdIsValid((TransactionId)tuple->t_xmax)));
-
- /*
- * XXX Several evil casts are made in this routine. Casting XID to be
- * TransactionId works only because TransactionId->data is the first
- * (and only) field of the structure.
- */
- if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) {
-
- if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin)
- && CommandIdGEScanCommandId(tuple->t_cmin)) {
-
- return (false);
- }
-
- if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin)
- && !CommandIdGEScanCommandId(tuple->t_cmin)) {
-
- if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) {
- return (true);
- }
-
- Assert(TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax));
-
- if (CommandIdGEScanCommandId(tuple->t_cmax)) {
- return (true);
- }
- }
-
+ if (AMI_OVERRIDE)
+ return true;
+
/*
- * this call is VERY expensive - requires a log table lookup.
+ * If the transaction system isn't yet initialized, then we assume
+ * that transactions committed. We only look at system catalogs
+ * during startup, so this is less awful than it seems, but it's still
+ * pretty awful.
*/
-
- if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) {
- return (false);
- }
- /*
- * the transaction has been committed--store the commit time _now_
- * instead of waiting for a vacuum so we avoid the expensive call
- * next time.
+ if (!PostgresIsInitialized)
+ return ((bool) (TransactionIdIsValid((TransactionId) tuple->t_xmin) &&
+ !TransactionIdIsValid((TransactionId) tuple->t_xmax)));
+
+ /*
+ * XXX Several evil casts are made in this routine. Casting XID to be
+ * TransactionId works only because TransactionId->data is the first
+ * (and only) field of the structure.
*/
- tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin);
- }
-
- /* by here, the inserting transaction has committed */
- if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) {
- return (true);
- }
-
- if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)) {
- return (false);
- }
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin))
+ {
+
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmin)
+ && CommandIdGEScanCommandId(tuple->t_cmin))
+ {
+
+ return (false);
+ }
+
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmin)
+ && !CommandIdGEScanCommandId(tuple->t_cmin))
+ {
+
+ if (!TransactionIdIsValid((TransactionId) tuple->t_xmax))
+ {
+ return (true);
+ }
+
+ Assert(TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmax));
+
+ if (CommandIdGEScanCommandId(tuple->t_cmax))
+ {
+ return (true);
+ }
+ }
+
+ /*
+ * this call is VERY expensive - requires a log table lookup.
+ */
+
+ if (!TransactionIdDidCommit((TransactionId) tuple->t_xmin))
+ {
+ return (false);
+ }
+
+ /*
+ * the transaction has been committed--store the commit time _now_
+ * instead of waiting for a vacuum so we avoid the expensive call
+ * next time.
+ */
+ tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin);
+ }
- if (AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) {
- return (false);
- }
+ /* by here, the inserting transaction has committed */
+ if (!TransactionIdIsValid((TransactionId) tuple->t_xmax))
+ {
+ return (true);
+ }
- if (!TransactionIdDidCommit((TransactionId)tuple->t_xmax)) {
- return (true);
- }
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmax))
+ {
+ return (false);
+ }
+
+ if (AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax))
+ {
+ return (false);
+ }
- /* xmax transaction committed, but no tmax set. so set it. */
- tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax);
+ if (!TransactionIdDidCommit((TransactionId) tuple->t_xmax))
+ {
+ return (true);
+ }
+
+ /* xmax transaction committed, but no tmax set. so set it. */
+ tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax);
- return (false);
+ return (false);
}
/*
* HeapTupleSatisfiesSnapshotInternalTimeQual --
- * True iff heap tuple is valid at the snapshot time qualification.
+ * True iff heap tuple is valid at the snapshot time qualification.
*
* Note:
- * Assumes heap tuple is valid.
- * Assumes internal time qualification is valid snapshot qualification.
+ * Assumes heap tuple is valid.
+ * Assumes internal time qualification is valid snapshot qualification.
*/
/*
* The satisfaction of Rel[T] requires the following:
*
* (Xmin is committed && Tmin <= T &&
- * (Xmax is null || (Xmax is not committed && Xmax != my-transaction) ||
- * Tmax >= T))
+ * (Xmax is null || (Xmax is not committed && Xmax != my-transaction) ||
+ * Tmax >= T))
*/
-static bool
+static bool
HeapTupleSatisfiesSnapshotInternalTimeQual(HeapTuple tuple,
- InternalTimeQual qual)
+ InternalTimeQual qual)
{
- /*
- * XXX Several evil casts are made in this routine. Casting XID to be
- * TransactionId works only because TransactionId->data is the first
- * (and only) field of the structure.
- */
- if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) {
-
- if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) {
- return (false);
- }
-
- tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin);
- }
-
- if (AbsoluteTimeIsBefore(TimeQualGetSnapshotTime((TimeQual)qual), tuple->t_tmin)) {
- return (false);
- }
- /* the tuple was inserted validly before the snapshot time */
-
- if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) {
-
- if (!TransactionIdIsValid((TransactionId)tuple->t_xmax) ||
- !TransactionIdDidCommit((TransactionId)tuple->t_xmax)) {
-
- return (true);
- }
-
- tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax);
- }
-
- return ((bool)
- AbsoluteTimeIsAfter(tuple->t_tmax,
- TimeQualGetSnapshotTime((TimeQual)qual)));
+
+ /*
+ * XXX Several evil casts are made in this routine. Casting XID to be
+ * TransactionId works only because TransactionId->data is the first
+ * (and only) field of the structure.
+ */
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin))
+ {
+
+ if (!TransactionIdDidCommit((TransactionId) tuple->t_xmin))
+ {
+ return (false);
+ }
+
+ tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin);
+ }
+
+ if (AbsoluteTimeIsBefore(TimeQualGetSnapshotTime((TimeQual) qual), tuple->t_tmin))
+ {
+ return (false);
+ }
+ /* the tuple was inserted validly before the snapshot time */
+
+ if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax))
+ {
+
+ if (!TransactionIdIsValid((TransactionId) tuple->t_xmax) ||
+ !TransactionIdDidCommit((TransactionId) tuple->t_xmax))
+ {
+
+ return (true);
+ }
+
+ tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax);
+ }
+
+ return ((bool)
+ AbsoluteTimeIsAfter(tuple->t_tmax,
+ TimeQualGetSnapshotTime((TimeQual) qual)));
}
/*
* HeapTupleSatisfiesUpperBoundedInternalTimeQual --
- * True iff heap tuple is valid within a upper bounded time qualification.
+ * True iff heap tuple is valid within a upper bounded time qualification.
*
* Note:
- * Assumes heap tuple is valid.
- * Assumes time qualification is valid ranged qualification with fixed
- * upper bound.
+ * Assumes heap tuple is valid.
+ * Assumes time qualification is valid ranged qualification with fixed
+ * upper bound.
*/
/*
* The satisfaction of [T1,T2] requires the following:
*
* (Xmin is committed && Tmin <= T2 &&
- * (Xmax is null || (Xmax is not committed && Xmax != my-transaction) ||
- * T1 is null || Tmax >= T1))
+ * (Xmax is null || (Xmax is not committed && Xmax != my-transaction) ||
+ * T1 is null || Tmax >= T1))
*/
-static bool
+static bool
HeapTupleSatisfiesUpperBoundedInternalTimeQual(HeapTuple tuple,
- InternalTimeQual qual)
+ InternalTimeQual qual)
{
- /*
- * XXX Several evil casts are made in this routine. Casting XID to be
- * TransactionId works only because TransactionId->data is the first
- * (and only) field of the structure.
- */
- if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) {
-
- if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) {
- return (false);
- }
-
- tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin);
- }
-
- if (AbsoluteTimeIsBefore(TimeQualGetEndTime((TimeQual)qual), tuple->t_tmin)) {
- return (false);
- }
- /* the tuple was inserted validly before the range end */
-
- if (!AbsoluteTimeIsBackwardCompatiblyValid(TimeQualGetStartTime((TimeQual)qual))) {
- return (true);
- }
-
- if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) {
-
- if (!TransactionIdIsValid((TransactionId)tuple->t_xmax) ||
- !TransactionIdDidCommit((TransactionId)tuple->t_xmax)) {
-
- return (true);
- }
-
- tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax);
- }
-
- return ((bool)AbsoluteTimeIsAfter(tuple->t_tmax,
- TimeQualGetStartTime((TimeQual)qual)));
+
+ /*
+ * XXX Several evil casts are made in this routine. Casting XID to be
+ * TransactionId works only because TransactionId->data is the first
+ * (and only) field of the structure.
+ */
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin))
+ {
+
+ if (!TransactionIdDidCommit((TransactionId) tuple->t_xmin))
+ {
+ return (false);
+ }
+
+ tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin);
+ }
+
+ if (AbsoluteTimeIsBefore(TimeQualGetEndTime((TimeQual) qual), tuple->t_tmin))
+ {
+ return (false);
+ }
+ /* the tuple was inserted validly before the range end */
+
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(TimeQualGetStartTime((TimeQual) qual)))
+ {
+ return (true);
+ }
+
+ if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax))
+ {
+
+ if (!TransactionIdIsValid((TransactionId) tuple->t_xmax) ||
+ !TransactionIdDidCommit((TransactionId) tuple->t_xmax))
+ {
+
+ return (true);
+ }
+
+ tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax);
+ }
+
+ return ((bool) AbsoluteTimeIsAfter(tuple->t_tmax,
+ TimeQualGetStartTime((TimeQual) qual)));
}
/*
* HeapTupleSatisfiesUpperUnboundedInternalTimeQual --
- * True iff heap tuple is valid within a upper bounded time qualification.
+ * True iff heap tuple is valid within a upper bounded time qualification.
*
* Note:
- * Assumes heap tuple is valid.
- * Assumes time qualification is valid ranged qualification with no
- * upper bound.
+ * Assumes heap tuple is valid.
+ * Assumes time qualification is valid ranged qualification with no
+ * upper bound.
*/
/*
* The satisfaction of [T1,] requires the following:
*
* ((Xmin == my-transaction && Cmin != my-command &&
- * (Xmax is null || (Xmax == my-transaction && Cmax != my-command)))
+ * (Xmax is null || (Xmax == my-transaction && Cmax != my-command)))
* ||
*
* (Xmin is committed &&
- * (Xmax is null || (Xmax == my-transaction && Cmax == my-command) ||
- * (Xmax is not committed && Xmax != my-transaction) ||
- * T1 is null || Tmax >= T1)))
+ * (Xmax is null || (Xmax == my-transaction && Cmax == my-command) ||
+ * (Xmax is not committed && Xmax != my-transaction) ||
+ * T1 is null || Tmax >= T1)))
*/
-static bool
+static bool
HeapTupleSatisfiesUpperUnboundedInternalTimeQual(HeapTuple tuple,
- InternalTimeQual qual)
+ InternalTimeQual qual)
{
- if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) {
-
- if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) &&
- CommandIdGEScanCommandId(tuple->t_cmin)) {
-
- return (false);
- }
-
- if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) &&
- !CommandIdGEScanCommandId(tuple->t_cmin)) {
-
- if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) {
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin))
+ {
+
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmin) &&
+ CommandIdGEScanCommandId(tuple->t_cmin))
+ {
+
+ return (false);
+ }
+
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmin) &&
+ !CommandIdGEScanCommandId(tuple->t_cmin))
+ {
+
+ if (!TransactionIdIsValid((TransactionId) tuple->t_xmax))
+ {
+ return (true);
+ }
+
+ Assert(TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmax));
+
+ return ((bool) ! CommandIdGEScanCommandId(tuple->t_cmax));
+ }
+
+ if (!TransactionIdDidCommit((TransactionId) tuple->t_xmin))
+ {
+ return (false);
+ }
+
+ tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin);
+ }
+ /* the tuple was inserted validly */
+
+ if (!AbsoluteTimeIsBackwardCompatiblyValid(TimeQualGetStartTime((TimeQual) qual)))
+ {
return (true);
- }
-
- Assert(TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax));
-
- return ((bool) !CommandIdGEScanCommandId(tuple->t_cmax));
- }
-
- if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) {
- return (false);
- }
-
- tuple->t_tmin = TransactionIdGetCommitTime(tuple->t_xmin);
- }
- /* the tuple was inserted validly */
-
- if (!AbsoluteTimeIsBackwardCompatiblyValid(TimeQualGetStartTime((TimeQual)qual))) {
- return (true);
- }
-
- if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax)) {
-
- if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) {
- return (true);
- }
-
- if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)) {
- return (CommandIdGEScanCommandId(tuple->t_cmin));
- /* it looks like error ^^^^ */
- }
-
- if (!TransactionIdDidCommit((TransactionId)tuple->t_xmax)) {
- return (true);
- }
-
- tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax);
- }
-
- return ((bool)AbsoluteTimeIsAfter(tuple->t_tmax,
- TimeQualGetStartTime((TimeQual)qual)));
+ }
+
+ if (!AbsoluteTimeIsBackwardCompatiblyReal(tuple->t_tmax))
+ {
+
+ if (!TransactionIdIsValid((TransactionId) tuple->t_xmax))
+ {
+ return (true);
+ }
+
+ if (TransactionIdIsCurrentTransactionId((TransactionId) tuple->t_xmax))
+ {
+ return (CommandIdGEScanCommandId(tuple->t_cmin));
+ /* it looks like error ^^^^ */
+ }
+
+ if (!TransactionIdDidCommit((TransactionId) tuple->t_xmax))
+ {
+ return (true);
+ }
+
+ tuple->t_tmax = TransactionIdGetCommitTime(tuple->t_xmax);
+ }
+
+ return ((bool) AbsoluteTimeIsAfter(tuple->t_tmax,
+ TimeQualGetStartTime((TimeQual) qual)));
}
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 15729fe7b3a..c8d3c755b6f 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* common.c--
- * common routines between pg_dump and pg4_dump
+ * common routines between pg_dump and pg4_dump
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.13 1997/08/19 21:36:25 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.14 1997/09/07 04:54:28 momjian Exp $
*
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
*
- * - Fixed dumpTable output to output lengths for char and varchar types!
- * - Added single. quote to twin single quote expansion for 'insert' string
- * mode.
+ * - Fixed dumpTable output to output lengths for char and varchar types!
+ * - Added single. quote to twin single quote expansion for 'insert' string
+ * mode.
*
*-------------------------------------------------------------------------
*/
@@ -22,9 +22,9 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
+#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
#ifdef sparc_solaris
-#include <netdb.h> /* for MAXHOSTNAMELEN on some */
+#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#endif
#include "postgres.h"
@@ -35,391 +35,446 @@
#include "pg_dump.h"
-static char** findParentsByOid(TableInfo* tbinfo, int numTables,
- InhInfo* inhinfo, int numInherits,
- const char *oid,
- int *numParents);
-static int findTableByOid(TableInfo *tbinfo, int numTables, const char *oid);
-static void flagInhAttrs(TableInfo* tbinfo, int numTables,
- InhInfo* inhinfo, int numInherits);
-static int strInArray(const char* pattern, char** arr, int arr_size);
+static char **
+findParentsByOid(TableInfo * tbinfo, int numTables,
+ InhInfo * inhinfo, int numInherits,
+ const char *oid,
+ int *numParents);
+static int findTableByOid(TableInfo * tbinfo, int numTables, const char *oid);
+static void
+flagInhAttrs(TableInfo * tbinfo, int numTables,
+ InhInfo * inhinfo, int numInherits);
+static int strInArray(const char *pattern, char **arr, int arr_size);
/*
- * findTypeByOid
- * given an oid of a type, return its typename
+ * findTypeByOid
+ * given an oid of a type, return its typename
*
* if oid is "0", return "opaque" -- this is a special case
*
* NOTE: should hash this, but just do linear search for now
*/
-char*
-findTypeByOid(TypeInfo* tinfo, int numTypes, const char* oid)
+char *
+findTypeByOid(TypeInfo * tinfo, int numTypes, const char *oid)
{
- int i;
+ int i;
- if (strcmp(oid, "0") == 0) return g_opaque_type;
+ if (strcmp(oid, "0") == 0)
+ return g_opaque_type;
- for (i=0;i<numTypes;i++) {
- if (strcmp(tinfo[i].oid, oid) == 0)
- return tinfo[i].typname;
- }
+ for (i = 0; i < numTypes; i++)
+ {
+ if (strcmp(tinfo[i].oid, oid) == 0)
+ return tinfo[i].typname;
+ }
- /* should never get here */
- fprintf(stderr,"failed sanity check, type with oid %s was not found\n",
- oid);
- exit(2);
+ /* should never get here */
+ fprintf(stderr, "failed sanity check, type with oid %s was not found\n",
+ oid);
+ exit(2);
}
/*
* findOprByOid
- * given the oid of an operator, return the name of the operator
+ * given the oid of an operator, return the name of the operator
*
*
* NOTE: should hash this, but just do linear search for now
- *
+ *
*/
-char*
-findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid)
+char *
+findOprByOid(OprInfo * oprinfo, int numOprs, const char *oid)
{
- int i;
- for (i=0;i<numOprs;i++) {
- if (strcmp(oprinfo[i].oid, oid) == 0)
- return oprinfo[i].oprname;
- }
-
- /* should never get here */
- fprintf(stderr,"failed sanity check, opr with oid %s was not found\n",
- oid);
- exit(2);
+ int i;
+
+ for (i = 0; i < numOprs; i++)
+ {
+ if (strcmp(oprinfo[i].oid, oid) == 0)
+ return oprinfo[i].oprname;
+ }
+
+ /* should never get here */
+ fprintf(stderr, "failed sanity check, opr with oid %s was not found\n",
+ oid);
+ exit(2);
}
/*
* findParentsByOid --
- * given the oid of a class, return the names of its parent classes
+ * given the oid of a class, return the names of its parent classes
* and assign the number of parents to the last argument.
*
*
* returns NULL if none
*/
-static char**
-findParentsByOid(TableInfo* tblinfo, int numTables,
- InhInfo* inhinfo, int numInherits, const char *oid,
- int *numParentsPtr)
+static char **
+findParentsByOid(TableInfo * tblinfo, int numTables,
+ InhInfo * inhinfo, int numInherits, const char *oid,
+ int *numParentsPtr)
{
- int i,j;
- int parentInd;
- char** result;
- int numParents;
-
- numParents = 0;
- for (i=0;i<numInherits;i++) {
- if ( strcmp(inhinfo[i].inhrel, oid) == 0) {
- numParents++;
+ int i,
+ j;
+ int parentInd;
+ char **result;
+ int numParents;
+
+ numParents = 0;
+ for (i = 0; i < numInherits; i++)
+ {
+ if (strcmp(inhinfo[i].inhrel, oid) == 0)
+ {
+ numParents++;
+ }
}
- }
-
- *numParentsPtr = numParents;
- if (numParents > 0) {
- result = (char**)malloc(sizeof(char*) * numParents);
- j = 0;
- for (i=0;i<numInherits;i++) {
- if ( strcmp(inhinfo[i].inhrel, oid) == 0) {
- parentInd = findTableByOid(tblinfo, numTables,
- inhinfo[i].inhparent);
- result[j++] = tblinfo[parentInd].relname;
- }
+ *numParentsPtr = numParents;
+
+ if (numParents > 0)
+ {
+ result = (char **) malloc(sizeof(char *) * numParents);
+ j = 0;
+ for (i = 0; i < numInherits; i++)
+ {
+ if (strcmp(inhinfo[i].inhrel, oid) == 0)
+ {
+ parentInd = findTableByOid(tblinfo, numTables,
+ inhinfo[i].inhparent);
+ result[j++] = tblinfo[parentInd].relname;
+ }
+ }
+ return result;
}
- return result;
- }
- else
- return NULL;
+ else
+ return NULL;
}
/*
* parseArgTypes
- * parse a string of eight numbers delimited by spaces
+ * parse a string of eight numbers delimited by spaces
* into a character array
*/
-void
-parseArgTypes(char **argtypes, const char* str)
+void
+parseArgTypes(char **argtypes, const char *str)
{
- int j, argNum;
- char temp[100];
- char s;
-
- argNum = 0;
- j = 0;
- while ( (s = *str) != '\0') {
- if (s == ' ') {
- temp[j] = '\0';
- argtypes[argNum] = strdup(temp);
- argNum++;
- j = 0;
- } else {
- temp[j] = s;
- j++;
+ int j,
+ argNum;
+ char temp[100];
+ char s;
+
+ argNum = 0;
+ j = 0;
+ while ((s = *str) != '\0')
+ {
+ if (s == ' ')
+ {
+ temp[j] = '\0';
+ argtypes[argNum] = strdup(temp);
+ argNum++;
+ j = 0;
+ }
+ else
+ {
+ temp[j] = s;
+ j++;
+ }
+ str++;
+ }
+ if (j != 0)
+ {
+ temp[j] = '\0';
+ argtypes[argNum] = strdup(temp);
}
- str++;
- }
- if (j != 0) {
- temp[j] = '\0';
- argtypes[argNum] = strdup(temp);
- }
-
+
}
/*
* strInArray:
- * takes in a string and a string array and the number of elements in the
- * string array.
- * returns the index if the string is somewhere in the array, -1 otherwise
+ * takes in a string and a string array and the number of elements in the
+ * string array.
+ * returns the index if the string is somewhere in the array, -1 otherwise
*
*/
-static int
-strInArray(const char* pattern, char** arr, int arr_size)
+static int
+strInArray(const char *pattern, char **arr, int arr_size)
{
- int i;
- for (i=0;i<arr_size;i++) {
- if (strcmp(pattern, arr[i]) == 0)
- return i;
- }
- return -1;
+ int i;
+
+ for (i = 0; i < arr_size; i++)
+ {
+ if (strcmp(pattern, arr[i]) == 0)
+ return i;
+ }
+ return -1;
}
/*
* dumpSchema:
- * we have a valid connection, we are now going to dump the schema
+ * we have a valid connection, we are now going to dump the schema
* into the file
*
*/
-TableInfo *
-dumpSchema(FILE *fout,
- int *numTablesPtr,
- const char *tablename,
- const bool acls)
+TableInfo *
+dumpSchema(FILE * fout,
+ int *numTablesPtr,
+ const char *tablename,
+ const bool acls)
{
- int numTypes;
- int numFuncs;
- int numTables;
- int numInherits;
- int numAggregates;
- int numOperators;
- TypeInfo *tinfo=NULL;
- FuncInfo *finfo=NULL;
- AggInfo *agginfo=NULL;
- TableInfo *tblinfo=NULL;
- InhInfo *inhinfo=NULL;
- OprInfo *oprinfo=NULL;
-
-if (g_verbose) fprintf(stderr,"%s reading user-defined types %s\n",
- g_comment_start, g_comment_end);
- tinfo = getTypes(&numTypes);
-
-if (g_verbose) fprintf(stderr,"%s reading user-defined functions %s\n",
- g_comment_start, g_comment_end);
- finfo = getFuncs(&numFuncs);
-
-if (g_verbose) fprintf(stderr,"%s reading user-defined aggregates %s\n",
- g_comment_start, g_comment_end);
- agginfo = getAggregates(&numAggregates);
-
-if (g_verbose) fprintf(stderr,"%s reading user-defined operators %s\n",
- g_comment_start, g_comment_end);
- oprinfo = getOperators(&numOperators);
-
-if (g_verbose) fprintf(stderr,"%s reading user-defined tables %s\n",
- g_comment_start, g_comment_end);
- tblinfo = getTables(&numTables);
-
-if (g_verbose) fprintf(stderr,"%s reading table inheritance information %s\n",
- g_comment_start, g_comment_end);
- inhinfo = getInherits(&numInherits);
-
-if (g_verbose) fprintf(stderr, "%s finding the attribute names and types for each table %s\n",
- g_comment_start, g_comment_end);
- getTableAttrs(tblinfo, numTables);
-
-if (g_verbose) fprintf(stderr, "%s flagging inherited attributes in subtables %s\n",
- g_comment_start, g_comment_end);
- flagInhAttrs(tblinfo, numTables, inhinfo, numInherits);
-
-if (!tablename && fout) {
- if (g_verbose) fprintf(stderr,"%s dumping out user-defined types %s\n",
- g_comment_start, g_comment_end);
- dumpTypes(fout, finfo, numFuncs, tinfo, numTypes);
-}
-
-if (fout) {
- if (g_verbose) fprintf(stderr,"%s dumping out tables %s\n",
- g_comment_start, g_comment_end);
- dumpTables(fout, tblinfo, numTables, inhinfo, numInherits,
- tinfo, numTypes, tablename, acls);
-}
-
-if (!tablename && fout) {
- if (g_verbose) fprintf(stderr,"%s dumping out user-defined functions %s\n",
- g_comment_start, g_comment_end);
- dumpFuncs(fout, finfo, numFuncs, tinfo, numTypes);
-}
+ int numTypes;
+ int numFuncs;
+ int numTables;
+ int numInherits;
+ int numAggregates;
+ int numOperators;
+ TypeInfo *tinfo = NULL;
+ FuncInfo *finfo = NULL;
+ AggInfo *agginfo = NULL;
+ TableInfo *tblinfo = NULL;
+ InhInfo *inhinfo = NULL;
+ OprInfo *oprinfo = NULL;
+
+ if (g_verbose)
+ fprintf(stderr, "%s reading user-defined types %s\n",
+ g_comment_start, g_comment_end);
+ tinfo = getTypes(&numTypes);
+
+ if (g_verbose)
+ fprintf(stderr, "%s reading user-defined functions %s\n",
+ g_comment_start, g_comment_end);
+ finfo = getFuncs(&numFuncs);
+
+ if (g_verbose)
+ fprintf(stderr, "%s reading user-defined aggregates %s\n",
+ g_comment_start, g_comment_end);
+ agginfo = getAggregates(&numAggregates);
+
+ if (g_verbose)
+ fprintf(stderr, "%s reading user-defined operators %s\n",
+ g_comment_start, g_comment_end);
+ oprinfo = getOperators(&numOperators);
+
+ if (g_verbose)
+ fprintf(stderr, "%s reading user-defined tables %s\n",
+ g_comment_start, g_comment_end);
+ tblinfo = getTables(&numTables);
+
+ if (g_verbose)
+ fprintf(stderr, "%s reading table inheritance information %s\n",
+ g_comment_start, g_comment_end);
+ inhinfo = getInherits(&numInherits);
+
+ if (g_verbose)
+ fprintf(stderr, "%s finding the attribute names and types for each table %s\n",
+ g_comment_start, g_comment_end);
+ getTableAttrs(tblinfo, numTables);
+
+ if (g_verbose)
+ fprintf(stderr, "%s flagging inherited attributes in subtables %s\n",
+ g_comment_start, g_comment_end);
+ flagInhAttrs(tblinfo, numTables, inhinfo, numInherits);
+
+ if (!tablename && fout)
+ {
+ if (g_verbose)
+ fprintf(stderr, "%s dumping out user-defined types %s\n",
+ g_comment_start, g_comment_end);
+ dumpTypes(fout, finfo, numFuncs, tinfo, numTypes);
+ }
-if (!tablename && fout) {
- if (g_verbose) fprintf(stderr,"%s dumping out user-defined functions %s\n",
- g_comment_start, g_comment_end);
- dumpAggs(fout, agginfo, numAggregates, tinfo, numTypes);
-}
+ if (fout)
+ {
+ if (g_verbose)
+ fprintf(stderr, "%s dumping out tables %s\n",
+ g_comment_start, g_comment_end);
+ dumpTables(fout, tblinfo, numTables, inhinfo, numInherits,
+ tinfo, numTypes, tablename, acls);
+ }
-if (!tablename && fout) {
- if (g_verbose) fprintf(stderr,"%s dumping out user-defined operators %s\n",
- g_comment_start, g_comment_end);
- dumpOprs(fout, oprinfo, numOperators, tinfo, numTypes);
-}
+ if (!tablename && fout)
+ {
+ if (g_verbose)
+ fprintf(stderr, "%s dumping out user-defined functions %s\n",
+ g_comment_start, g_comment_end);
+ dumpFuncs(fout, finfo, numFuncs, tinfo, numTypes);
+ }
+
+ if (!tablename && fout)
+ {
+ if (g_verbose)
+ fprintf(stderr, "%s dumping out user-defined functions %s\n",
+ g_comment_start, g_comment_end);
+ dumpAggs(fout, agginfo, numAggregates, tinfo, numTypes);
+ }
+
+ if (!tablename && fout)
+ {
+ if (g_verbose)
+ fprintf(stderr, "%s dumping out user-defined operators %s\n",
+ g_comment_start, g_comment_end);
+ dumpOprs(fout, oprinfo, numOperators, tinfo, numTypes);
+ }
- *numTablesPtr = numTables;
- clearAggInfo(agginfo,numAggregates);
- clearOprInfo(oprinfo,numOperators);
- clearTypeInfo(tinfo, numTypes);
- clearFuncInfo(finfo,numFuncs);
- clearInhInfo(inhinfo,numInherits);
- return tblinfo;
+ *numTablesPtr = numTables;
+ clearAggInfo(agginfo, numAggregates);
+ clearOprInfo(oprinfo, numOperators);
+ clearTypeInfo(tinfo, numTypes);
+ clearFuncInfo(finfo, numFuncs);
+ clearInhInfo(inhinfo, numInherits);
+ return tblinfo;
}
/*
* dumpSchemaIdx:
- * dump indexes at the end for performance
+ * dump indexes at the end for performance
*
*/
extern void
-dumpSchemaIdx(FILE *fout, int *numTablesPtr, const char *tablename,
- TableInfo* tblinfo, int numTables)
+dumpSchemaIdx(FILE * fout, int *numTablesPtr, const char *tablename,
+ TableInfo * tblinfo, int numTables)
{
- int numIndices;
- IndInfo *indinfo;
-
- if (g_verbose) fprintf(stderr,"%s reading indices information %s\n",
- g_comment_start, g_comment_end);
- indinfo = getIndices(&numIndices);
-
- if (fout) {
- if (g_verbose) fprintf(stderr,"%s dumping out indices %s\n",
- g_comment_start, g_comment_end);
- dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename);
- }
- clearIndInfo(indinfo,numIndices);
+ int numIndices;
+ IndInfo *indinfo;
+
+ if (g_verbose)
+ fprintf(stderr, "%s reading indices information %s\n",
+ g_comment_start, g_comment_end);
+ indinfo = getIndices(&numIndices);
+
+ if (fout)
+ {
+ if (g_verbose)
+ fprintf(stderr, "%s dumping out indices %s\n",
+ g_comment_start, g_comment_end);
+ dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename);
+ }
+ clearIndInfo(indinfo, numIndices);
}
/* flagInhAttrs -
- * for each table in tblinfo, flag its inherited attributes
+ * for each table in tblinfo, flag its inherited attributes
* so when we dump the table out, we don't dump out the inherited attributes
- *
+ *
* initializes the parentRels field of each table
*
* modifies tblinfo
*
*/
static void
-flagInhAttrs(TableInfo* tblinfo, int numTables,
- InhInfo* inhinfo, int numInherits)
+flagInhAttrs(TableInfo * tblinfo, int numTables,
+ InhInfo * inhinfo, int numInherits)
{
- int i,j,k;
- int parentInd;
-
- /* we go backwards because the tables in tblinfo are in OID
- order, meaning the subtables are after the parent tables
- we flag inherited attributes from child tables first */
- for (i = numTables-1; i >= 0; i--) {
- tblinfo[i].parentRels = findParentsByOid(tblinfo, numTables,
- inhinfo, numInherits,
- tblinfo[i].oid,
- &tblinfo[i].numParents);
- for (k=0;k<tblinfo[i].numParents;k++) {
- parentInd = findTableByName(tblinfo, numTables,
- tblinfo[i].parentRels[k]);
- for (j=0;j<tblinfo[i].numatts;j++) {
- if (strInArray(tblinfo[i].attnames[j],
- tblinfo[parentInd].attnames,
- tblinfo[parentInd].numatts) != -1) {
- tblinfo[i].inhAttrs[j] = 1;
+ int i,
+ j,
+ k;
+ int parentInd;
+
+ /*
+ * we go backwards because the tables in tblinfo are in OID order,
+ * meaning the subtables are after the parent tables we flag inherited
+ * attributes from child tables first
+ */
+ for (i = numTables - 1; i >= 0; i--)
+ {
+ tblinfo[i].parentRels = findParentsByOid(tblinfo, numTables,
+ inhinfo, numInherits,
+ tblinfo[i].oid,
+ &tblinfo[i].numParents);
+ for (k = 0; k < tblinfo[i].numParents; k++)
+ {
+ parentInd = findTableByName(tblinfo, numTables,
+ tblinfo[i].parentRels[k]);
+ for (j = 0; j < tblinfo[i].numatts; j++)
+ {
+ if (strInArray(tblinfo[i].attnames[j],
+ tblinfo[parentInd].attnames,
+ tblinfo[parentInd].numatts) != -1)
+ {
+ tblinfo[i].inhAttrs[j] = 1;
+ }
+ }
}
- }
}
- }
}
/*
* findTableByName
- * finds the index (in tblinfo) of the table with the given relname
- * returns -1 if not found
+ * finds the index (in tblinfo) of the table with the given relname
+ * returns -1 if not found
*
* NOTE: should hash this, but just do linear search for now
*/
int
-findTableByName(TableInfo* tblinfo, int numTables, const char* relname)
+findTableByName(TableInfo * tblinfo, int numTables, const char *relname)
{
- int i;
- for (i=0;i<numTables;i++) {
- if (strcmp(tblinfo[i].relname, relname) == 0)
- return i;
- }
- return -1;
+ int i;
+
+ for (i = 0; i < numTables; i++)
+ {
+ if (strcmp(tblinfo[i].relname, relname) == 0)
+ return i;
+ }
+ return -1;
}
/*
* findTableByOid
- * finds the index (in tblinfo) of the table with the given oid
- * returns -1 if not found
+ * finds the index (in tblinfo) of the table with the given oid
+ * returns -1 if not found
*
* NOTE: should hash this, but just do linear search for now
*/
static int
-findTableByOid(TableInfo* tblinfo, int numTables, const char* oid)
+findTableByOid(TableInfo * tblinfo, int numTables, const char *oid)
{
- int i;
- for (i=0;i<numTables;i++) {
- if (strcmp(tblinfo[i].oid, oid) == 0)
- return i;
- }
- return -1;
+ int i;
+
+ for (i = 0; i < numTables; i++)
+ {
+ if (strcmp(tblinfo[i].oid, oid) == 0)
+ return i;
+ }
+ return -1;
}
/*
* findFuncByName
- * finds the index (in finfo) of the function with the given name
- * returns -1 if not found
+ * finds the index (in finfo) of the function with the given name
+ * returns -1 if not found
*
* NOTE: should hash this, but just do linear search for now
*/
int
-findFuncByName(FuncInfo* finfo, int numFuncs, const char* name)
+findFuncByName(FuncInfo * finfo, int numFuncs, const char *name)
{
- int i;
- for (i=0;i<numFuncs;i++) {
- if (strcmp(finfo[i].proname, name) == 0)
- return i;
- }
- return -1;
+ int i;
+
+ for (i = 0; i < numFuncs; i++)
+ {
+ if (strcmp(finfo[i].proname, name) == 0)
+ return i;
+ }
+ return -1;
}
/*
* isArchiveName
*
- * returns true if the relation name is an archive name, false otherwise
- */
+ * returns true if the relation name is an archive name, false otherwise
+ */
int
-isArchiveName(const char* relname)
+isArchiveName(const char *relname)
{
- return (strlen(relname) > 1 && relname[1] == ',');
+ return (strlen(relname) > 1 && relname[1] == ',');
}
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index c006505a13b..8192d5c30b6 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* pg_dump.c--
- * pg_dump is an utility for dumping out a postgres database
+ * pg_dump is an utility for dumping out a postgres database
* into a script file.
*
- * pg_dump will read the system catalogs in a database and
- * dump out a script that reproduces
- * the schema of the database in terms of
- * user-defined types
- * user-defined functions
- * tables
- * indices
- * aggregates
- * operators
- * ACL - grant/revoke
+ * pg_dump will read the system catalogs in a database and
+ * dump out a script that reproduces
+ * the schema of the database in terms of
+ * user-defined types
+ * user-defined functions
+ * tables
+ * indices
+ * aggregates
+ * operators
+ * ACL - grant/revoke
*
* the output script is SQL that is understood by PostgreSQL
*
@@ -21,39 +21,39 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.40 1997/08/22 17:15:41 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.41 1997/09/07 04:54:38 momjian Exp $
*
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
*
- * Applied 'insert string' patch from "Marc G. Fournier" <scrappy@ki.net>
- * Added '-t table' option
- * Added '-a' option
- * Added '-da' option
+ * Applied 'insert string' patch from "Marc G. Fournier" <scrappy@ki.net>
+ * Added '-t table' option
+ * Added '-a' option
+ * Added '-da' option
*
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
*
- * - Fixed dumpTable output to output lengths for char and varchar types!
- * - Added single. quote to twin single quote expansion for 'insert' string
- * mode.
+ * - Fixed dumpTable output to output lengths for char and varchar types!
+ * - Added single. quote to twin single quote expansion for 'insert' string
+ * mode.
*
* Modifications - 7/26/96 - asussman@vidya.com
*
- * - Fixed ouput lengths for char and varchar type where the length is variable (-1)
+ * - Fixed ouput lengths for char and varchar type where the length is variable (-1)
*
* Modifications - 6/1/97 - igor@sba.miami.edu
* - Added functions to free allocated memory used for retrieving
- * indices,tables,inheritance,types,functions and aggregates.
- * No more leaks reported by Purify.
+ * indices,tables,inheritance,types,functions and aggregates.
+ * No more leaks reported by Purify.
*-------------------------------------------------------------------------
*/
#include <stdlib.h>
-#include <unistd.h> /* for getopt() */
+#include <unistd.h> /* for getopt() */
#include <stdio.h>
#include <string.h>
-#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
+#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
#ifdef sparc_solaris
-#include <netdb.h> /* for MAXHOSTNAMELEN on some */
+#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#endif
#include "postgres.h"
@@ -67,1946 +67,2202 @@
#include "pg_dump.h"
-static void dumpSequence (FILE* fout, TableInfo tbinfo);
-static char *checkForQuote(const char* s);
-static void clearTableInfo(TableInfo*, int);
-static void dumpOneFunc(FILE* fout, FuncInfo* finfo, int i,
- TypeInfo *tinfo, int numTypes);
-static int findLastBuiltinOid(void);
-static bool isViewRule(char *relname);
-static void setMaxOid(FILE *fout);
+static void dumpSequence(FILE * fout, TableInfo tbinfo);
+static char *checkForQuote(const char *s);
+static void clearTableInfo(TableInfo *, int);
+static void
+dumpOneFunc(FILE * fout, FuncInfo * finfo, int i,
+ TypeInfo * tinfo, int numTypes);
+static int findLastBuiltinOid(void);
+static bool isViewRule(char *relname);
+static void setMaxOid(FILE * fout);
-extern char *optarg;
-extern int optind, opterr;
+extern char *optarg;
+extern int optind,
+ opterr;
/* global decls */
-bool g_verbose; /* User wants verbose narration of our activities. */
-int g_last_builtin_oid; /* value of the last builtin oid */
-FILE *g_fout; /* the script file */
-PGconn *g_conn; /* the database connection */
-int dumpData; /* dump data using proper insert strings */
-int attrNames; /* put attr names into insert strings */
-int schemaOnly;
-int dataOnly;
-
-char g_opaque_type[10]; /* name for the opaque type */
+bool g_verbose; /* User wants verbose narration of our
+ * activities. */
+int g_last_builtin_oid; /* value of the last builtin oid */
+FILE *g_fout; /* the script file */
+PGconn *g_conn; /* the database connection */
+int dumpData; /* dump data using proper insert strings */
+int attrNames; /* put attr names into insert strings */
+int schemaOnly;
+int dataOnly;
+
+char g_opaque_type[10]; /* name for the opaque type */
/* placeholders for the delimiters for comments */
-char g_comment_start[10];
-char g_comment_end[10];
+char g_comment_start[10];
+char g_comment_end[10];
static void
-usage(const char* progname)
+usage(const char *progname)
{
- fprintf(stderr,
- "%s - version 1.13.dhb.2\n\n",progname);
- fprintf(stderr,
- "usage: %s [options] [dbname]\n",progname);
- fprintf(stderr,
- "\t -f filename \t\t script output filename\n");
- fprintf(stderr,
- "\t -H hostname \t\t server host name\n");
- fprintf(stderr,
- "\t -p port \t\t server port number\n");
- fprintf(stderr,
- "\t -v \t\t verbose\n");
- fprintf(stderr,
- "\t -d \t\t dump data as proper insert strings\n");
- fprintf(stderr,
- "\t -D \t\t dump data as inserts with attribute names\n");
- fprintf(stderr,
- "\t -S \t\t dump out only the schema, no data\n");
- fprintf(stderr,
- "\t -a \t\t dump out only the data, no schema\n");
- fprintf(stderr,
- "\t -t table \t\t dump for this table only\n");
- fprintf(stderr,
- "\t -o \t\t dump object id's (oids)\n");
- fprintf(stderr,
- "\t -z \t\t dump ACLs (grant/revoke)\n");
- fprintf(stderr,
- "\nIf dbname is not supplied, then the DATABASE environment "
- "variable value is used.\n");
- fprintf(stderr, "\n");
-
- exit(1);
+ fprintf(stderr,
+ "%s - version 1.13.dhb.2\n\n", progname);
+ fprintf(stderr,
+ "usage: %s [options] [dbname]\n", progname);
+ fprintf(stderr,
+ "\t -f filename \t\t script output filename\n");
+ fprintf(stderr,
+ "\t -H hostname \t\t server host name\n");
+ fprintf(stderr,
+ "\t -p port \t\t server port number\n");
+ fprintf(stderr,
+ "\t -v \t\t verbose\n");
+ fprintf(stderr,
+ "\t -d \t\t dump data as proper insert strings\n");
+ fprintf(stderr,
+ "\t -D \t\t dump data as inserts with attribute names\n");
+ fprintf(stderr,
+ "\t -S \t\t dump out only the schema, no data\n");
+ fprintf(stderr,
+ "\t -a \t\t dump out only the data, no schema\n");
+ fprintf(stderr,
+ "\t -t table \t\t dump for this table only\n");
+ fprintf(stderr,
+ "\t -o \t\t dump object id's (oids)\n");
+ fprintf(stderr,
+ "\t -z \t\t dump ACLs (grant/revoke)\n");
+ fprintf(stderr,
+ "\nIf dbname is not supplied, then the DATABASE environment "
+ "variable value is used.\n");
+ fprintf(stderr, "\n");
+
+ exit(1);
}
-static void
-exit_nicely(PGconn* conn)
+static void
+exit_nicely(PGconn * conn)
{
- PQfinish(conn);
- exit(1);
+ PQfinish(conn);
+ exit(1);
}
/*
* isViewRule
- * Determine if the relation is a VIEW
+ * Determine if the relation is a VIEW
*
*/
-static bool
+static bool
isViewRule(char *relname)
{
- PGresult *res;
- int ntups;
- char query[MAXQUERYLEN];
-
- res = PQexec(g_conn, "begin");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
-
- sprintf(query, "select relname from pg_class, pg_rewrite "
- "where pg_class.oid = ev_class "
- "and rulename = '_RET%s'", relname);
-
- res = PQexec(g_conn, query);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"isViewRule(): SELECT failed\n");
- exit_nicely(g_conn);
- }
-
- ntups = PQntuples(res);
-
- PQclear(res);
- res = PQexec(g_conn, "end");
- PQclear(res);
- return ntups > 0 ? TRUE : FALSE;
+ PGresult *res;
+ int ntups;
+ char query[MAXQUERYLEN];
+
+ res = PQexec(g_conn, "begin");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+
+ sprintf(query, "select relname from pg_class, pg_rewrite "
+ "where pg_class.oid = ev_class "
+ "and rulename = '_RET%s'", relname);
+
+ res = PQexec(g_conn, query);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "isViewRule(): SELECT failed\n");
+ exit_nicely(g_conn);
+ }
+
+ ntups = PQntuples(res);
+
+ PQclear(res);
+ res = PQexec(g_conn, "end");
+ PQclear(res);
+ return ntups > 0 ? TRUE : FALSE;
}
-#define COPYBUFSIZ 8192
-
-
-static void
-dumpClasses_nodumpData(FILE *fout, const char *classname, const bool oids) {
-
- PGresult *res;
- char query[255];
- int ret;
- bool copydone;
- char copybuf[COPYBUFSIZ];
-
- if (oids) {
- fprintf(fout, "COPY %s WITH OIDS FROM stdin;\n",
- classname);
- sprintf(query, "COPY %s WITH OIDS TO stdout;\n",
- classname);
- } else {
- fprintf(fout, "COPY %s FROM stdin;\n", classname);
- sprintf(query, "COPY %s TO stdout;\n", classname);
- }
- res = PQexec(g_conn, query);
- if (!res) {
- fprintf(stderr, "SQL query to dump the contents of Table %s "
- "did not execute. Explanation from backend: '%s'.\n"
- "The query was: '%s'.\n",
- classname, PQerrorMessage(g_conn), query);
- exit_nicely(g_conn);
- } else {
- if (PQresultStatus(res) != PGRES_COPY_OUT) {
- fprintf(stderr,"SQL query to dump the contents of Table %s "
- "executed abnormally.\n"
- "PQexec() returned status %d when %d was expected.\n"
- "The query was: '%s'.\n",
- classname, PQresultStatus(res), PGRES_COPY_OUT, query);
- exit_nicely(g_conn);
- } else {
- copydone = false;
- while (!copydone) {
- ret = PQgetline(res->conn, copybuf, COPYBUFSIZ);
-
- if (copybuf[0] == '\\' &&
- copybuf[1] == '.' &&
- copybuf[2] == '\0') {
- copydone = true; /* don't print this... */
- } else {
- fputs(copybuf, fout);
- switch (ret) {
- case EOF:
- copydone = true;
- /*FALLTHROUGH*/
- case 0:
- fputc('\n', fout);
- break;
- case 1:
- break;
- }
- }
- }
- fprintf(fout, "\\.\n");
- }
- ret = PQendcopy(res->conn);
- if (ret != 0) {
- fprintf(stderr, "SQL query to dump the contents of Table %s "
- "did not execute correctly. After we read all the "
- "table contents from the backend, PQendcopy() failed. "
- "Explanation from backend: '%s'.\n"
- "The query was: '%s'.\n",
- classname, PQerrorMessage(g_conn), query);
- if(res) PQclear(res);
- exit_nicely(g_conn);
- }
- if(res) PQclear(res);
- }
+#define COPYBUFSIZ 8192
+
+
+static void
+dumpClasses_nodumpData(FILE * fout, const char *classname, const bool oids)
+{
+
+ PGresult *res;
+ char query[255];
+ int ret;
+ bool copydone;
+ char copybuf[COPYBUFSIZ];
+
+ if (oids)
+ {
+ fprintf(fout, "COPY %s WITH OIDS FROM stdin;\n",
+ classname);
+ sprintf(query, "COPY %s WITH OIDS TO stdout;\n",
+ classname);
+ }
+ else
+ {
+ fprintf(fout, "COPY %s FROM stdin;\n", classname);
+ sprintf(query, "COPY %s TO stdout;\n", classname);
+ }
+ res = PQexec(g_conn, query);
+ if (!res)
+ {
+ fprintf(stderr, "SQL query to dump the contents of Table %s "
+ "did not execute. Explanation from backend: '%s'.\n"
+ "The query was: '%s'.\n",
+ classname, PQerrorMessage(g_conn), query);
+ exit_nicely(g_conn);
+ }
+ else
+ {
+ if (PQresultStatus(res) != PGRES_COPY_OUT)
+ {
+ fprintf(stderr, "SQL query to dump the contents of Table %s "
+ "executed abnormally.\n"
+ "PQexec() returned status %d when %d was expected.\n"
+ "The query was: '%s'.\n",
+ classname, PQresultStatus(res), PGRES_COPY_OUT, query);
+ exit_nicely(g_conn);
+ }
+ else
+ {
+ copydone = false;
+ while (!copydone)
+ {
+ ret = PQgetline(res->conn, copybuf, COPYBUFSIZ);
+
+ if (copybuf[0] == '\\' &&
+ copybuf[1] == '.' &&
+ copybuf[2] == '\0')
+ {
+ copydone = true; /* don't print this... */
+ }
+ else
+ {
+ fputs(copybuf, fout);
+ switch (ret)
+ {
+ case EOF:
+ copydone = true;
+ /* FALLTHROUGH */
+ case 0:
+ fputc('\n', fout);
+ break;
+ case 1:
+ break;
+ }
+ }
+ }
+ fprintf(fout, "\\.\n");
+ }
+ ret = PQendcopy(res->conn);
+ if (ret != 0)
+ {
+ fprintf(stderr, "SQL query to dump the contents of Table %s "
+ "did not execute correctly. After we read all the "
+ "table contents from the backend, PQendcopy() failed. "
+ "Explanation from backend: '%s'.\n"
+ "The query was: '%s'.\n",
+ classname, PQerrorMessage(g_conn), query);
+ if (res)
+ PQclear(res);
+ exit_nicely(g_conn);
+ }
+ if (res)
+ PQclear(res);
+ }
}
static void
-dumpClasses_dumpData(FILE *fout, const char *classname,
- const TableInfo tblinfo, bool oids) {
-
- PGresult *res;
- char query[255];
- int actual_atts; /* number of attrs in this a table */
- char expandbuf[COPYBUFSIZ];
- char q[MAXQUERYLEN];
- int tuple;
- int field;
-
- sprintf(query, "select * from %s", classname);
- res = PQexec(g_conn, query);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"dumpClasses(): command failed\n");
- exit_nicely(g_conn);
- }
- tuple=0;
- while(tuple < PQntuples(res)) {
- fprintf(fout, "insert into %s ", classname);
- if (attrNames) {
- int j;
- actual_atts = 0;
- sprintf(q, "(");
- for (j=0;j<tblinfo.numatts;j++) {
- if (tblinfo.inhAttrs[j] == 0) {
- sprintf(q, "%s%s%s",
- q,
- (actual_atts > 0) ? "," : "",
- tblinfo.attnames[j]);
- actual_atts++;
- }
- }
- sprintf(q,"%s%s",q, ") ");
- fprintf(fout, q);
- }
- fprintf(fout, "values (");
- field=0;
- do {
- if (PQgetisnull(res,tuple,field)) {
- fprintf(fout,"NULL");
- } else {
- switch(PQftype(res,field)) {
- case INT2OID: case INT4OID: case OIDOID: /* int types */
- case FLOAT4OID: case FLOAT8OID: /* float types */
- fprintf(fout, "%s",
- PQgetvalue(res,tuple,field));
- break;
- default: {
- char *expsrc,*expdest;
-
- /* Before outputting string value, expand all
- single quotes to twin single quotes -
- dhb - 6/11/96 */
- expsrc=PQgetvalue(res,tuple,field);
- expdest=expandbuf;
- while (*expsrc) {
- *expdest++=*expsrc;
- if (*expsrc == (char)0x27) /*single quote*/
- *expdest++ = *expsrc;
- expsrc++;
- }
- *expdest=*expsrc; /* null term. */
-
- fprintf(fout, "'%s'", expandbuf);
- }
- break;
- }
- }
- field++;
- if(field != PQnfields(res))
- fprintf(fout, ",");
- } while(field < PQnfields(res));
- fprintf(fout, ");\n");
- tuple++;
- }
- PQclear(res);
+dumpClasses_dumpData(FILE * fout, const char *classname,
+ const TableInfo tblinfo, bool oids)
+{
+
+ PGresult *res;
+ char query[255];
+ int actual_atts;/* number of attrs in this a table */
+ char expandbuf[COPYBUFSIZ];
+ char q[MAXQUERYLEN];
+ int tuple;
+ int field;
+
+ sprintf(query, "select * from %s", classname);
+ res = PQexec(g_conn, query);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "dumpClasses(): command failed\n");
+ exit_nicely(g_conn);
+ }
+ tuple = 0;
+ while (tuple < PQntuples(res))
+ {
+ fprintf(fout, "insert into %s ", classname);
+ if (attrNames)
+ {
+ int j;
+
+ actual_atts = 0;
+ sprintf(q, "(");
+ for (j = 0; j < tblinfo.numatts; j++)
+ {
+ if (tblinfo.inhAttrs[j] == 0)
+ {
+ sprintf(q, "%s%s%s",
+ q,
+ (actual_atts > 0) ? "," : "",
+ tblinfo.attnames[j]);
+ actual_atts++;
+ }
+ }
+ sprintf(q, "%s%s", q, ") ");
+ fprintf(fout, q);
+ }
+ fprintf(fout, "values (");
+ field = 0;
+ do
+ {
+ if (PQgetisnull(res, tuple, field))
+ {
+ fprintf(fout, "NULL");
+ }
+ else
+ {
+ switch (PQftype(res, field))
+ {
+ case INT2OID:
+ case INT4OID:
+ case OIDOID: /* int types */
+ case FLOAT4OID:
+ case FLOAT8OID:/* float types */
+ fprintf(fout, "%s",
+ PQgetvalue(res, tuple, field));
+ break;
+ default:
+ {
+ char *expsrc,
+ *expdest;
+
+ /*
+ * Before outputting string value, expand all
+ * single quotes to twin single quotes - dhb -
+ * 6/11/96
+ */
+ expsrc = PQgetvalue(res, tuple, field);
+ expdest = expandbuf;
+ while (*expsrc)
+ {
+ *expdest++ = *expsrc;
+ if (*expsrc == (char) 0x27) /* single quote */
+ *expdest++ = *expsrc;
+ expsrc++;
+ }
+ *expdest = *expsrc; /* null term. */
+
+ fprintf(fout, "'%s'", expandbuf);
+ }
+ break;
+ }
+ }
+ field++;
+ if (field != PQnfields(res))
+ fprintf(fout, ",");
+ } while (field < PQnfields(res));
+ fprintf(fout, ");\n");
+ tuple++;
+ }
+ PQclear(res);
}
/*
* DumpClasses -
- * dump the contents of all the classes.
+ * dump the contents of all the classes.
*/
static void
-dumpClasses(const TableInfo tblinfo[], const int numTables, FILE *fout,
- const char *onlytable, const bool oids) {
-
- int i;
- char *all_only;
-
- if (onlytable == NULL) all_only = "all";
- else all_only = "one";
-
- if (g_verbose)
- fprintf(stderr, "%s dumping out the contents of %s of %d tables %s\n",
- g_comment_start, all_only, numTables, g_comment_end);
-
- for(i = 0; i < numTables; i++) {
- const char *classname = tblinfo[i].relname;
-
- /* Skip VIEW relations */
- if (isViewRule(tblinfo[i].relname))
- continue;
-
- if (!onlytable || (!strcmp(classname,onlytable)))
- {
- if ( tblinfo[i].sequence )
- {
- if ( dataOnly ) /* i.e. SCHEMA didn't dumped */
- {
- if ( g_verbose )
- fprintf (stderr, "%s dumping out schema of sequence %s %s\n",
- g_comment_start, classname, g_comment_end);
- dumpSequence (fout, tblinfo[i]);
+dumpClasses(const TableInfo tblinfo[], const int numTables, FILE * fout,
+ const char *onlytable, const bool oids)
+{
+
+ int i;
+ char *all_only;
+
+ if (onlytable == NULL)
+ all_only = "all";
+ else
+ all_only = "one";
+
+ if (g_verbose)
+ fprintf(stderr, "%s dumping out the contents of %s of %d tables %s\n",
+ g_comment_start, all_only, numTables, g_comment_end);
+
+ for (i = 0; i < numTables; i++)
+ {
+ const char *classname = tblinfo[i].relname;
+
+ /* Skip VIEW relations */
+ if (isViewRule(tblinfo[i].relname))
+ continue;
+
+ if (!onlytable || (!strcmp(classname, onlytable)))
+ {
+ if (tblinfo[i].sequence)
+ {
+ if (dataOnly) /* i.e. SCHEMA didn't dumped */
+ {
+ if (g_verbose)
+ fprintf(stderr, "%s dumping out schema of sequence %s %s\n",
+ g_comment_start, classname, g_comment_end);
+ dumpSequence(fout, tblinfo[i]);
+ }
+ else if (g_verbose)
+ fprintf(stderr, "%s contents of sequence '%s' dumped in schema %s\n",
+ g_comment_start, classname, g_comment_end);
+ continue;
+ }
+
+ if (g_verbose)
+ fprintf(stderr, "%s dumping out the contents of Table %s %s\n",
+ g_comment_start, classname, g_comment_end);
+
+ /* skip archive names */
+ if (isArchiveName(classname))
+ continue;
+
+ if (!dumpData)
+ dumpClasses_nodumpData(fout, classname, oids);
+ else
+ dumpClasses_dumpData(fout, classname, tblinfo[i], oids);
}
- else if ( g_verbose )
- fprintf (stderr, "%s contents of sequence '%s' dumped in schema %s\n",
- g_comment_start, classname, g_comment_end);
- continue;
- }
-
- if (g_verbose)
- fprintf(stderr, "%s dumping out the contents of Table %s %s\n",
- g_comment_start, classname, g_comment_end);
-
- /* skip archive names*/
- if (isArchiveName(classname))
- continue;
-
- if(!dumpData)
- dumpClasses_nodumpData(fout, classname, oids);
- else
- dumpClasses_dumpData(fout, classname, tblinfo[i], oids);
- }
- }
+ }
}
int
-main(int argc, char** argv)
+main(int argc, char **argv)
{
- int c;
- const char* progname;
- const char* filename = NULL;
- const char* dbname = NULL;
- const char *pghost = NULL;
- const char *pgport = NULL;
- const char *tablename = NULL;
- int oids = 0, acls = 0;
- TableInfo *tblinfo;
- int numTables;
-
- g_verbose = false;
-
- strcpy(g_comment_start,"-- ");
- g_comment_end[0] = '\0';
- strcpy(g_opaque_type, "opaque");
-
- dataOnly = schemaOnly = dumpData = attrNames = 0;
-
- progname = *argv;
-
- while ((c = getopt(argc, argv,"f:H:p:t:vSDdDaoz")) != EOF) {
- switch(c) {
- case 'f': /* output file name */
- filename = optarg;
- break;
- case 'H' : /* server host */
- pghost = optarg;
- break;
- case 'p' : /* server port */
- pgport = optarg;
- break;
- case 'v': /* verbose */
- g_verbose = true;
- break;
- case 'S': /* dump schema only */
- schemaOnly = 1;
- break;
- case 'd': /* dump data as proper insert strings */
- dumpData = 1;
- break;
- case 'D': /* dump data as proper insert strings with attr names */
- dumpData = 1;
- attrNames = 1;
- break;
- case 't': /* Dump data for this table only */
- tablename = optarg;
- break;
- case 'a': /* Dump data only */
- dataOnly = 1;
- break;
- case 'o': /* Dump oids */
- oids = 1;
- break;
- case 'z': /* Dump oids */
- acls = 1;
- break;
- default:
- usage(progname);
- break;
- }
- }
-
- /* open the output file */
- if (filename == NULL) {
- g_fout = stdout;
- } else {
- g_fout = fopen(filename, "w");
- if (g_fout == NULL) {
- fprintf(stderr,
- "%s: could not open output file named %s for writing\n",
- progname, filename);
- exit(2);
- }
- }
-
- /* find database */
- if (!(dbname = argv[optind]) &&
- !(dbname = getenv("DATABASE")) ) {
- fprintf(stderr, "%s: no database name specified\n",progname);
- exit (2);
- }
-
- g_conn = PQsetdb(pghost, pgport, NULL, NULL, dbname);
- /* check to see that the backend connection was successfully made */
- if (PQstatus(g_conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", dbname);
- fprintf(stderr,"%s\n",PQerrorMessage(g_conn));
- exit_nicely(g_conn);
- }
-
- g_last_builtin_oid = findLastBuiltinOid();
-
- if (oids)
- setMaxOid(g_fout);
- if (!dataOnly) {
- if (g_verbose)
- fprintf(stderr, "%s last builtin oid is %d %s\n",
- g_comment_start, g_last_builtin_oid, g_comment_end);
- tblinfo = dumpSchema(g_fout, &numTables, tablename, acls);
- }
- else
- tblinfo = dumpSchema(NULL, &numTables, tablename, acls);
-
- if (!schemaOnly) {
- dumpClasses(tblinfo, numTables, g_fout, tablename, oids);
- }
-
- if (!dataOnly) /* dump indexes at the end for performance */
- dumpSchemaIdx(g_fout, &numTables, tablename, tblinfo, numTables);
-
- fflush(g_fout);
- fclose(g_fout);
- clearTableInfo(tblinfo, numTables);
- PQfinish(g_conn);
- exit(0);
+ int c;
+ const char *progname;
+ const char *filename = NULL;
+ const char *dbname = NULL;
+ const char *pghost = NULL;
+ const char *pgport = NULL;
+ const char *tablename = NULL;
+ int oids = 0,
+ acls = 0;
+ TableInfo *tblinfo;
+ int numTables;
+
+ g_verbose = false;
+
+ strcpy(g_comment_start, "-- ");
+ g_comment_end[0] = '\0';
+ strcpy(g_opaque_type, "opaque");
+
+ dataOnly = schemaOnly = dumpData = attrNames = 0;
+
+ progname = *argv;
+
+ while ((c = getopt(argc, argv, "f:H:p:t:vSDdDaoz")) != EOF)
+ {
+ switch (c)
+ {
+ case 'f': /* output file name */
+ filename = optarg;
+ break;
+ case 'H': /* server host */
+ pghost = optarg;
+ break;
+ case 'p': /* server port */
+ pgport = optarg;
+ break;
+ case 'v': /* verbose */
+ g_verbose = true;
+ break;
+ case 'S': /* dump schema only */
+ schemaOnly = 1;
+ break;
+ case 'd': /* dump data as proper insert strings */
+ dumpData = 1;
+ break;
+ case 'D': /* dump data as proper insert strings with
+ * attr names */
+ dumpData = 1;
+ attrNames = 1;
+ break;
+ case 't': /* Dump data for this table only */
+ tablename = optarg;
+ break;
+ case 'a': /* Dump data only */
+ dataOnly = 1;
+ break;
+ case 'o': /* Dump oids */
+ oids = 1;
+ break;
+ case 'z': /* Dump oids */
+ acls = 1;
+ break;
+ default:
+ usage(progname);
+ break;
+ }
+ }
+
+ /* open the output file */
+ if (filename == NULL)
+ {
+ g_fout = stdout;
+ }
+ else
+ {
+ g_fout = fopen(filename, "w");
+ if (g_fout == NULL)
+ {
+ fprintf(stderr,
+ "%s: could not open output file named %s for writing\n",
+ progname, filename);
+ exit(2);
+ }
+ }
+
+ /* find database */
+ if (!(dbname = argv[optind]) &&
+ !(dbname = getenv("DATABASE")))
+ {
+ fprintf(stderr, "%s: no database name specified\n", progname);
+ exit(2);
+ }
+
+ g_conn = PQsetdb(pghost, pgport, NULL, NULL, dbname);
+ /* check to see that the backend connection was successfully made */
+ if (PQstatus(g_conn) == CONNECTION_BAD)
+ {
+ fprintf(stderr, "Connection to database '%s' failed.\n", dbname);
+ fprintf(stderr, "%s\n", PQerrorMessage(g_conn));
+ exit_nicely(g_conn);
+ }
+
+ g_last_builtin_oid = findLastBuiltinOid();
+
+ if (oids)
+ setMaxOid(g_fout);
+ if (!dataOnly)
+ {
+ if (g_verbose)
+ fprintf(stderr, "%s last builtin oid is %d %s\n",
+ g_comment_start, g_last_builtin_oid, g_comment_end);
+ tblinfo = dumpSchema(g_fout, &numTables, tablename, acls);
+ }
+ else
+ tblinfo = dumpSchema(NULL, &numTables, tablename, acls);
+
+ if (!schemaOnly)
+ {
+ dumpClasses(tblinfo, numTables, g_fout, tablename, oids);
+ }
+
+ if (!dataOnly) /* dump indexes at the end for performance */
+ dumpSchemaIdx(g_fout, &numTables, tablename, tblinfo, numTables);
+
+ fflush(g_fout);
+ fclose(g_fout);
+ clearTableInfo(tblinfo, numTables);
+ PQfinish(g_conn);
+ exit(0);
}
/*
- * getTypes:
- * read all base types in the system catalogs and return them in the
+ * getTypes:
+ * read all base types in the system catalogs and return them in the
* TypeInfo* structure
*
- * numTypes is set to the number of types read in
+ * numTypes is set to the number of types read in
*
*/
-TypeInfo*
+TypeInfo *
getTypes(int *numTypes)
{
- PGresult *res;
- int ntups;
- int i;
- char query[MAXQUERYLEN];
- TypeInfo *tinfo;
-
- int i_oid;
- int i_typowner;
- int i_typname;
- int i_typlen;
- int i_typprtlen;
- int i_typinput;
- int i_typoutput;
- int i_typreceive;
- int i_typsend;
- int i_typelem;
- int i_typdelim;
- int i_typdefault;
- int i_typrelid;
- int i_typbyval;
- int i_usename;
-
- res = PQexec(g_conn, "begin");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
-
- /* find all base types */
- /* we include even the built-in types
- because those may be used as array elements by user-defined types */
- /* we filter out the built-in types when
- we dump out the types */
-
- sprintf(query, "SELECT pg_type.oid, typowner,typname, typlen, typprtlen, "
- "typinput, typoutput, typreceive, typsend, typelem, typdelim, "
- "typdefault, typrelid,typbyval, usename from pg_type, pg_user "
- "where typowner = usesysid");
-
- res = PQexec(g_conn,query);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"getTypes(): SELECT failed\n");
- exit_nicely(g_conn);
- }
-
- ntups = PQntuples(res);
-
- tinfo = (TypeInfo*)malloc(ntups * sizeof(TypeInfo));
-
- i_oid = PQfnumber(res,"oid");
- i_typowner = PQfnumber(res,"typowner");
- i_typname = PQfnumber(res,"typname");
- i_typlen = PQfnumber(res,"typlen");
- i_typprtlen = PQfnumber(res,"typprtlen");
- i_typinput = PQfnumber(res,"typinput");
- i_typoutput = PQfnumber(res,"typoutput");
- i_typreceive = PQfnumber(res,"typreceive");
- i_typsend = PQfnumber(res,"typsend");
- i_typelem = PQfnumber(res,"typelem");
- i_typdelim = PQfnumber(res,"typdelim");
- i_typdefault = PQfnumber(res,"typdefault");
- i_typrelid = PQfnumber(res,"typrelid");
- i_typbyval = PQfnumber(res,"typbyval");
- i_usename = PQfnumber(res,"usename");
-
- for (i=0;i<ntups;i++) {
- tinfo[i].oid = strdup(PQgetvalue(res,i,i_oid));
- tinfo[i].typowner = strdup(PQgetvalue(res,i,i_typowner));
- tinfo[i].typname = strdup(PQgetvalue(res,i,i_typname));
- tinfo[i].typlen = strdup(PQgetvalue(res,i,i_typlen));
- tinfo[i].typprtlen = strdup(PQgetvalue(res,i,i_typprtlen));
- tinfo[i].typinput = strdup(PQgetvalue(res,i,i_typinput));
- tinfo[i].typoutput = strdup(PQgetvalue(res,i,i_typoutput));
- tinfo[i].typreceive = strdup(PQgetvalue(res,i,i_typreceive));
- tinfo[i].typsend = strdup(PQgetvalue(res,i,i_typsend));
- tinfo[i].typelem = strdup(PQgetvalue(res,i,i_typelem));
- tinfo[i].typdelim = strdup(PQgetvalue(res,i,i_typdelim));
- tinfo[i].typdefault = strdup(PQgetvalue(res,i,i_typdefault));
- tinfo[i].typrelid = strdup(PQgetvalue(res,i,i_typrelid));
- tinfo[i].usename = strdup(PQgetvalue(res,i,i_usename));
-
- if (strcmp(PQgetvalue(res,i,i_typbyval), "f") == 0)
- tinfo[i].passedbyvalue = 0;
- else
- tinfo[i].passedbyvalue = 1;
-
- /* check for user-defined array types,
- omit system generated ones */
- if ( (strcmp(tinfo[i].typelem, "0") != 0) &&
- tinfo[i].typname[0] != '_')
- tinfo[i].isArray = 1;
- else
- tinfo[i].isArray = 0;
- }
-
- *numTypes = ntups;
-
- PQclear(res);
-
- res = PQexec(g_conn,"end");
- PQclear(res);
-
- return tinfo;
+ PGresult *res;
+ int ntups;
+ int i;
+ char query[MAXQUERYLEN];
+ TypeInfo *tinfo;
+
+ int i_oid;
+ int i_typowner;
+ int i_typname;
+ int i_typlen;
+ int i_typprtlen;
+ int i_typinput;
+ int i_typoutput;
+ int i_typreceive;
+ int i_typsend;
+ int i_typelem;
+ int i_typdelim;
+ int i_typdefault;
+ int i_typrelid;
+ int i_typbyval;
+ int i_usename;
+
+ res = PQexec(g_conn, "begin");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+
+ /* find all base types */
+
+ /*
+ * we include even the built-in types because those may be used as
+ * array elements by user-defined types
+ */
+
+ /*
+ * we filter out the built-in types when we dump out the types
+ */
+
+ sprintf(query, "SELECT pg_type.oid, typowner,typname, typlen, typprtlen, "
+ "typinput, typoutput, typreceive, typsend, typelem, typdelim, "
+ "typdefault, typrelid,typbyval, usename from pg_type, pg_user "
+ "where typowner = usesysid");
+
+ res = PQexec(g_conn, query);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "getTypes(): SELECT failed\n");
+ exit_nicely(g_conn);
+ }
+
+ ntups = PQntuples(res);
+
+ tinfo = (TypeInfo *) malloc(ntups * sizeof(TypeInfo));
+
+ i_oid = PQfnumber(res, "oid");
+ i_typowner = PQfnumber(res, "typowner");
+ i_typname = PQfnumber(res, "typname");
+ i_typlen = PQfnumber(res, "typlen");
+ i_typprtlen = PQfnumber(res, "typprtlen");
+ i_typinput = PQfnumber(res, "typinput");
+ i_typoutput = PQfnumber(res, "typoutput");
+ i_typreceive = PQfnumber(res, "typreceive");
+ i_typsend = PQfnumber(res, "typsend");
+ i_typelem = PQfnumber(res, "typelem");
+ i_typdelim = PQfnumber(res, "typdelim");
+ i_typdefault = PQfnumber(res, "typdefault");
+ i_typrelid = PQfnumber(res, "typrelid");
+ i_typbyval = PQfnumber(res, "typbyval");
+ i_usename = PQfnumber(res, "usename");
+
+ for (i = 0; i < ntups; i++)
+ {
+ tinfo[i].oid = strdup(PQgetvalue(res, i, i_oid));
+ tinfo[i].typowner = strdup(PQgetvalue(res, i, i_typowner));
+ tinfo[i].typname = strdup(PQgetvalue(res, i, i_typname));
+ tinfo[i].typlen = strdup(PQgetvalue(res, i, i_typlen));
+ tinfo[i].typprtlen = strdup(PQgetvalue(res, i, i_typprtlen));
+ tinfo[i].typinput = strdup(PQgetvalue(res, i, i_typinput));
+ tinfo[i].typoutput = strdup(PQgetvalue(res, i, i_typoutput));
+ tinfo[i].typreceive = strdup(PQgetvalue(res, i, i_typreceive));
+ tinfo[i].typsend = strdup(PQgetvalue(res, i, i_typsend));
+ tinfo[i].typelem = strdup(PQgetvalue(res, i, i_typelem));
+ tinfo[i].typdelim = strdup(PQgetvalue(res, i, i_typdelim));
+ tinfo[i].typdefault = strdup(PQgetvalue(res, i, i_typdefault));
+ tinfo[i].typrelid = strdup(PQgetvalue(res, i, i_typrelid));
+ tinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+
+ if (strcmp(PQgetvalue(res, i, i_typbyval), "f") == 0)
+ tinfo[i].passedbyvalue = 0;
+ else
+ tinfo[i].passedbyvalue = 1;
+
+ /*
+ * check for user-defined array types, omit system generated ones
+ */
+ if ((strcmp(tinfo[i].typelem, "0") != 0) &&
+ tinfo[i].typname[0] != '_')
+ tinfo[i].isArray = 1;
+ else
+ tinfo[i].isArray = 0;
+ }
+
+ *numTypes = ntups;
+
+ PQclear(res);
+
+ res = PQexec(g_conn, "end");
+ PQclear(res);
+
+ return tinfo;
}
/*
* getOperators:
- * read all operators in the system catalogs and return them in the
+ * read all operators in the system catalogs and return them in the
* OprInfo* structure
*
- * numOprs is set to the number of operators read in
- *
+ * numOprs is set to the number of operators read in
+ *
*
*/
-OprInfo*
+OprInfo *
getOperators(int *numOprs)
{
- PGresult *res;
- int ntups;
- int i;
- char query[MAXQUERYLEN];
-
- OprInfo* oprinfo;
-
- int i_oid;
- int i_oprname;
- int i_oprkind;
- int i_oprcode;
- int i_oprleft;
- int i_oprright;
- int i_oprcom;
- int i_oprnegate;
- int i_oprrest;
- int i_oprjoin;
- int i_oprcanhash;
- int i_oprlsortop;
- int i_oprrsortop;
- int i_usename;
-
- /* find all operators, including builtin operators,
- filter out system-defined operators at dump-out time */
- res = PQexec(g_conn, "begin");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
-
- sprintf(query, "SELECT pg_operator.oid, oprname, oprkind, oprcode, "
- "oprleft, oprright, oprcom, oprnegate, oprrest, oprjoin, "
- "oprcanhash, oprlsortop, oprrsortop, usename "
- "from pg_operator, pg_user "
- "where oprowner = usesysid");
-
- res = PQexec(g_conn, query);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"getOperators(): SELECT failed\n");
- exit_nicely(g_conn);
- }
-
- ntups = PQntuples(res);
- *numOprs = ntups;
-
- oprinfo = (OprInfo*)malloc(ntups * sizeof(OprInfo));
-
- i_oid = PQfnumber(res,"oid");
- i_oprname = PQfnumber(res,"oprname");
- i_oprkind = PQfnumber(res,"oprkind");
- i_oprcode = PQfnumber(res,"oprcode");
- i_oprleft = PQfnumber(res,"oprleft");
- i_oprright = PQfnumber(res,"oprright");
- i_oprcom = PQfnumber(res,"oprcom");
- i_oprnegate = PQfnumber(res,"oprnegate");
- i_oprrest = PQfnumber(res,"oprrest");
- i_oprjoin = PQfnumber(res,"oprjoin");
- i_oprcanhash = PQfnumber(res,"oprcanhash");
- i_oprlsortop = PQfnumber(res,"oprlsortop");
- i_oprrsortop = PQfnumber(res,"oprrsortop");
- i_usename = PQfnumber(res,"usename");
-
- for (i=0;i<ntups;i++) {
- oprinfo[i].oid = strdup(PQgetvalue(res,i,i_oid));
- oprinfo[i].oprname = strdup(PQgetvalue(res,i,i_oprname));
- oprinfo[i].oprkind = strdup(PQgetvalue(res,i,i_oprkind));
- oprinfo[i].oprcode = strdup(PQgetvalue(res,i,i_oprcode));
- oprinfo[i].oprleft = strdup(PQgetvalue(res,i,i_oprleft));
- oprinfo[i].oprright = strdup(PQgetvalue(res,i,i_oprright));
- oprinfo[i].oprcom = strdup(PQgetvalue(res,i,i_oprcom));
- oprinfo[i].oprnegate = strdup(PQgetvalue(res,i,i_oprnegate));
- oprinfo[i].oprrest = strdup(PQgetvalue(res,i,i_oprrest));
- oprinfo[i].oprjoin = strdup(PQgetvalue(res,i,i_oprjoin));
- oprinfo[i].oprcanhash = strdup(PQgetvalue(res,i,i_oprcanhash));
- oprinfo[i].oprlsortop = strdup(PQgetvalue(res,i,i_oprlsortop));
- oprinfo[i].oprrsortop = strdup(PQgetvalue(res,i,i_oprrsortop));
- oprinfo[i].usename = strdup(PQgetvalue(res,i,i_usename));
- }
-
- PQclear(res);
- res = PQexec(g_conn, "end");
- PQclear(res);
-
- return oprinfo;
+ PGresult *res;
+ int ntups;
+ int i;
+ char query[MAXQUERYLEN];
+
+ OprInfo *oprinfo;
+
+ int i_oid;
+ int i_oprname;
+ int i_oprkind;
+ int i_oprcode;
+ int i_oprleft;
+ int i_oprright;
+ int i_oprcom;
+ int i_oprnegate;
+ int i_oprrest;
+ int i_oprjoin;
+ int i_oprcanhash;
+ int i_oprlsortop;
+ int i_oprrsortop;
+ int i_usename;
+
+ /*
+ * find all operators, including builtin operators, filter out
+ * system-defined operators at dump-out time
+ */
+ res = PQexec(g_conn, "begin");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+
+ sprintf(query, "SELECT pg_operator.oid, oprname, oprkind, oprcode, "
+ "oprleft, oprright, oprcom, oprnegate, oprrest, oprjoin, "
+ "oprcanhash, oprlsortop, oprrsortop, usename "
+ "from pg_operator, pg_user "
+ "where oprowner = usesysid");
+
+ res = PQexec(g_conn, query);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "getOperators(): SELECT failed\n");
+ exit_nicely(g_conn);
+ }
+
+ ntups = PQntuples(res);
+ *numOprs = ntups;
+
+ oprinfo = (OprInfo *) malloc(ntups * sizeof(OprInfo));
+
+ i_oid = PQfnumber(res, "oid");
+ i_oprname = PQfnumber(res, "oprname");
+ i_oprkind = PQfnumber(res, "oprkind");
+ i_oprcode = PQfnumber(res, "oprcode");
+ i_oprleft = PQfnumber(res, "oprleft");
+ i_oprright = PQfnumber(res, "oprright");
+ i_oprcom = PQfnumber(res, "oprcom");
+ i_oprnegate = PQfnumber(res, "oprnegate");
+ i_oprrest = PQfnumber(res, "oprrest");
+ i_oprjoin = PQfnumber(res, "oprjoin");
+ i_oprcanhash = PQfnumber(res, "oprcanhash");
+ i_oprlsortop = PQfnumber(res, "oprlsortop");
+ i_oprrsortop = PQfnumber(res, "oprrsortop");
+ i_usename = PQfnumber(res, "usename");
+
+ for (i = 0; i < ntups; i++)
+ {
+ oprinfo[i].oid = strdup(PQgetvalue(res, i, i_oid));
+ oprinfo[i].oprname = strdup(PQgetvalue(res, i, i_oprname));
+ oprinfo[i].oprkind = strdup(PQgetvalue(res, i, i_oprkind));
+ oprinfo[i].oprcode = strdup(PQgetvalue(res, i, i_oprcode));
+ oprinfo[i].oprleft = strdup(PQgetvalue(res, i, i_oprleft));
+ oprinfo[i].oprright = strdup(PQgetvalue(res, i, i_oprright));
+ oprinfo[i].oprcom = strdup(PQgetvalue(res, i, i_oprcom));
+ oprinfo[i].oprnegate = strdup(PQgetvalue(res, i, i_oprnegate));
+ oprinfo[i].oprrest = strdup(PQgetvalue(res, i, i_oprrest));
+ oprinfo[i].oprjoin = strdup(PQgetvalue(res, i, i_oprjoin));
+ oprinfo[i].oprcanhash = strdup(PQgetvalue(res, i, i_oprcanhash));
+ oprinfo[i].oprlsortop = strdup(PQgetvalue(res, i, i_oprlsortop));
+ oprinfo[i].oprrsortop = strdup(PQgetvalue(res, i, i_oprrsortop));
+ oprinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+ }
+
+ PQclear(res);
+ res = PQexec(g_conn, "end");
+ PQclear(res);
+
+ return oprinfo;
}
void
-clearTypeInfo(TypeInfo *tp, int numTypes)
+clearTypeInfo(TypeInfo * tp, int numTypes)
{
- int i;
- for(i=0;i<numTypes;++i) {
- if(tp[i].oid) free(tp[i].oid);
- if(tp[i].typowner) free(tp[i].typowner);
- if(tp[i].typname) free(tp[i].typname);
- if(tp[i].typlen) free(tp[i].typlen);
- if(tp[i].typprtlen) free(tp[i].typprtlen);
- if(tp[i].typinput) free(tp[i].typinput);
- if(tp[i].typoutput) free(tp[i].typoutput);
- if(tp[i].typreceive) free(tp[i].typreceive);
- if(tp[i].typsend) free(tp[i].typsend);
- if(tp[i].typelem) free(tp[i].typelem);
- if(tp[i].typdelim) free(tp[i].typdelim);
- if(tp[i].typdefault) free(tp[i].typdefault);
- if(tp[i].typrelid) free(tp[i].typrelid);
- if(tp[i].usename) free(tp[i].usename);
- }
- free(tp);
+ int i;
+
+ for (i = 0; i < numTypes; ++i)
+ {
+ if (tp[i].oid)
+ free(tp[i].oid);
+ if (tp[i].typowner)
+ free(tp[i].typowner);
+ if (tp[i].typname)
+ free(tp[i].typname);
+ if (tp[i].typlen)
+ free(tp[i].typlen);
+ if (tp[i].typprtlen)
+ free(tp[i].typprtlen);
+ if (tp[i].typinput)
+ free(tp[i].typinput);
+ if (tp[i].typoutput)
+ free(tp[i].typoutput);
+ if (tp[i].typreceive)
+ free(tp[i].typreceive);
+ if (tp[i].typsend)
+ free(tp[i].typsend);
+ if (tp[i].typelem)
+ free(tp[i].typelem);
+ if (tp[i].typdelim)
+ free(tp[i].typdelim);
+ if (tp[i].typdefault)
+ free(tp[i].typdefault);
+ if (tp[i].typrelid)
+ free(tp[i].typrelid);
+ if (tp[i].usename)
+ free(tp[i].usename);
+ }
+ free(tp);
}
void
-clearFuncInfo (FuncInfo *fun, int numFuncs)
+clearFuncInfo(FuncInfo * fun, int numFuncs)
{
- int i,a;
- if(!fun) return;
- for(i=0;i<numFuncs;++i) {
- if(fun[i].oid) free(fun[i].oid);
- if(fun[i].proname) free(fun[i].proname);
- if(fun[i].usename) free(fun[i].usename);
- for(a=0;a<8;++a)
- if(fun[i].argtypes[a]) free(fun[i].argtypes[a]);
- if(fun[i].prorettype) free(fun[i].prorettype);
- if(fun[i].prosrc) free(fun[i].prosrc);
- if(fun[i].probin) free(fun[i].probin);
- }
- free(fun);
+ int i,
+ a;
+
+ if (!fun)
+ return;
+ for (i = 0; i < numFuncs; ++i)
+ {
+ if (fun[i].oid)
+ free(fun[i].oid);
+ if (fun[i].proname)
+ free(fun[i].proname);
+ if (fun[i].usename)
+ free(fun[i].usename);
+ for (a = 0; a < 8; ++a)
+ if (fun[i].argtypes[a])
+ free(fun[i].argtypes[a]);
+ if (fun[i].prorettype)
+ free(fun[i].prorettype);
+ if (fun[i].prosrc)
+ free(fun[i].prosrc);
+ if (fun[i].probin)
+ free(fun[i].probin);
+ }
+ free(fun);
}
static void
-clearTableInfo(TableInfo *tblinfo, int numTables)
+clearTableInfo(TableInfo * tblinfo, int numTables)
{
- int i,j;
- for(i=0;i<numTables;++i) {
-
- if(tblinfo[i].oid) free (tblinfo[i].oid);
- if(tblinfo[i].relarch) free (tblinfo[i].relarch);
- if(tblinfo[i].relacl) free (tblinfo[i].relacl);
- if(tblinfo[i].usename) free (tblinfo[i].usename);
-
- /* skip archive tables */
- if (isArchiveName(tblinfo[i].relname))
- {
- if(tblinfo[i].relname) free (tblinfo[i].relname);
- continue;
- }
- if(tblinfo[i].relname) free (tblinfo[i].relname);
-
- if ( tblinfo[i].sequence )
- continue;
-
- /* Process Attributes */
- for(j=0;j<tblinfo[i].numatts;j++) {
- if(tblinfo[i].attnames[j]) free (tblinfo[i].attnames[j]);
- if(tblinfo[i].typnames[j]) free (tblinfo[i].typnames[j]);
- }
- if(tblinfo[i].attlen) free((int *)tblinfo[i].attlen);
- if(tblinfo[i].inhAttrs) free((int *)tblinfo[i].inhAttrs);
- if(tblinfo[i].attnames) free (tblinfo[i].attnames);
- if(tblinfo[i].typnames) free (tblinfo[i].typnames);
- if(tblinfo[i].notnull) free (tblinfo[i].notnull);
-
- }
- free(tblinfo);
+ int i,
+ j;
+
+ for (i = 0; i < numTables; ++i)
+ {
+
+ if (tblinfo[i].oid)
+ free(tblinfo[i].oid);
+ if (tblinfo[i].relarch)
+ free(tblinfo[i].relarch);
+ if (tblinfo[i].relacl)
+ free(tblinfo[i].relacl);
+ if (tblinfo[i].usename)
+ free(tblinfo[i].usename);
+
+ /* skip archive tables */
+ if (isArchiveName(tblinfo[i].relname))
+ {
+ if (tblinfo[i].relname)
+ free(tblinfo[i].relname);
+ continue;
+ }
+ if (tblinfo[i].relname)
+ free(tblinfo[i].relname);
+
+ if (tblinfo[i].sequence)
+ continue;
+
+ /* Process Attributes */
+ for (j = 0; j < tblinfo[i].numatts; j++)
+ {
+ if (tblinfo[i].attnames[j])
+ free(tblinfo[i].attnames[j]);
+ if (tblinfo[i].typnames[j])
+ free(tblinfo[i].typnames[j]);
+ }
+ if (tblinfo[i].attlen)
+ free((int *) tblinfo[i].attlen);
+ if (tblinfo[i].inhAttrs)
+ free((int *) tblinfo[i].inhAttrs);
+ if (tblinfo[i].attnames)
+ free(tblinfo[i].attnames);
+ if (tblinfo[i].typnames)
+ free(tblinfo[i].typnames);
+ if (tblinfo[i].notnull)
+ free(tblinfo[i].notnull);
+
+ }
+ free(tblinfo);
}
-void
-clearInhInfo (InhInfo *inh, int numInherits) {
- int i;
- if(!inh) return;
- for(i=0;i<numInherits;++i) {
- if(inh[i].inhrel) free(inh[i].inhrel);
- if(inh[i].inhparent) free(inh[i].inhparent);
- }
- free(inh);
+void
+clearInhInfo(InhInfo * inh, int numInherits)
+{
+ int i;
+
+ if (!inh)
+ return;
+ for (i = 0; i < numInherits; ++i)
+ {
+ if (inh[i].inhrel)
+ free(inh[i].inhrel);
+ if (inh[i].inhparent)
+ free(inh[i].inhparent);
+ }
+ free(inh);
}
void
-clearOprInfo(OprInfo *opr, int numOprs){
- int i;
- if(!opr) return;
- for(i=0;i<numOprs;++i) {
- if(opr[i].oid) free(opr[i].oid);
- if(opr[i].oprname) free(opr[i].oprname);
- if(opr[i].oprkind) free(opr[i].oprkind);
- if(opr[i].oprcode) free(opr[i].oprcode);
- if(opr[i].oprleft) free(opr[i].oprleft);
- if(opr[i].oprright) free(opr[i].oprright);
- if(opr[i].oprcom) free(opr[i].oprcom);
- if(opr[i].oprnegate) free(opr[i].oprnegate);
- if(opr[i].oprrest) free(opr[i].oprrest);
- if(opr[i].oprjoin) free(opr[i].oprjoin);
- if(opr[i].oprcanhash) free(opr[i].oprcanhash);
- if(opr[i].oprlsortop) free(opr[i].oprlsortop);
- if(opr[i].oprrsortop) free(opr[i].oprrsortop);
- if(opr[i].usename) free(opr[i].usename);
- }
- free(opr);
+clearOprInfo(OprInfo * opr, int numOprs)
+{
+ int i;
+
+ if (!opr)
+ return;
+ for (i = 0; i < numOprs; ++i)
+ {
+ if (opr[i].oid)
+ free(opr[i].oid);
+ if (opr[i].oprname)
+ free(opr[i].oprname);
+ if (opr[i].oprkind)
+ free(opr[i].oprkind);
+ if (opr[i].oprcode)
+ free(opr[i].oprcode);
+ if (opr[i].oprleft)
+ free(opr[i].oprleft);
+ if (opr[i].oprright)
+ free(opr[i].oprright);
+ if (opr[i].oprcom)
+ free(opr[i].oprcom);
+ if (opr[i].oprnegate)
+ free(opr[i].oprnegate);
+ if (opr[i].oprrest)
+ free(opr[i].oprrest);
+ if (opr[i].oprjoin)
+ free(opr[i].oprjoin);
+ if (opr[i].oprcanhash)
+ free(opr[i].oprcanhash);
+ if (opr[i].oprlsortop)
+ free(opr[i].oprlsortop);
+ if (opr[i].oprrsortop)
+ free(opr[i].oprrsortop);
+ if (opr[i].usename)
+ free(opr[i].usename);
+ }
+ free(opr);
}
void
-clearIndInfo(IndInfo *ind, int numIndices)
+clearIndInfo(IndInfo * ind, int numIndices)
{
- int i,a;
- if(!ind) return;
- for(i=0;i<numIndices;++i) {
- if(ind[i].indexrelname) free(ind[i].indexrelname);
- if(ind[i].indrelname) free(ind[i].indrelname);
- if(ind[i].indamname) free(ind[i].indamname);
- if(ind[i].indproc) free(ind[i].indproc);
- if(ind[i].indisunique) free(ind[i].indisunique);
- for(a=0;a<INDEX_MAX_KEYS;++a) {
- if(ind[i].indkey[a]) free(ind[i].indkey[a]);
- if(ind[i].indclass[a]) free(ind[i].indclass[a]);
- }
- }
- free(ind);
+ int i,
+ a;
+
+ if (!ind)
+ return;
+ for (i = 0; i < numIndices; ++i)
+ {
+ if (ind[i].indexrelname)
+ free(ind[i].indexrelname);
+ if (ind[i].indrelname)
+ free(ind[i].indrelname);
+ if (ind[i].indamname)
+ free(ind[i].indamname);
+ if (ind[i].indproc)
+ free(ind[i].indproc);
+ if (ind[i].indisunique)
+ free(ind[i].indisunique);
+ for (a = 0; a < INDEX_MAX_KEYS; ++a)
+ {
+ if (ind[i].indkey[a])
+ free(ind[i].indkey[a]);
+ if (ind[i].indclass[a])
+ free(ind[i].indclass[a]);
+ }
+ }
+ free(ind);
}
void
-clearAggInfo(AggInfo *agginfo, int numArgs)
+clearAggInfo(AggInfo * agginfo, int numArgs)
{
- int i;
- if(!agginfo) return;
- for(i=0;i<numArgs;++i) {
- if(agginfo[i].oid) free (agginfo[i].oid);
- if(agginfo[i].aggname) free (agginfo[i].aggname);
- if(agginfo[i].aggtransfn1) free (agginfo[i].aggtransfn1);
- if(agginfo[i].aggtransfn2) free (agginfo[i].aggtransfn2);
- if(agginfo[i].aggfinalfn) free (agginfo[i].aggfinalfn);
- if(agginfo[i].aggtranstype1) free (agginfo[i].aggtranstype1);
- if(agginfo[i].aggbasetype) free (agginfo[i].aggbasetype);
- if(agginfo[i].aggtranstype2) free (agginfo[i].aggtranstype2);
- if(agginfo[i].agginitval1) free (agginfo[i].agginitval1);
- if(agginfo[i].agginitval2) free (agginfo[i].agginitval2);
- if(agginfo[i].usename) free (agginfo[i].usename);
- }
- free (agginfo);
+ int i;
+
+ if (!agginfo)
+ return;
+ for (i = 0; i < numArgs; ++i)
+ {
+ if (agginfo[i].oid)
+ free(agginfo[i].oid);
+ if (agginfo[i].aggname)
+ free(agginfo[i].aggname);
+ if (agginfo[i].aggtransfn1)
+ free(agginfo[i].aggtransfn1);
+ if (agginfo[i].aggtransfn2)
+ free(agginfo[i].aggtransfn2);
+ if (agginfo[i].aggfinalfn)
+ free(agginfo[i].aggfinalfn);
+ if (agginfo[i].aggtranstype1)
+ free(agginfo[i].aggtranstype1);
+ if (agginfo[i].aggbasetype)
+ free(agginfo[i].aggbasetype);
+ if (agginfo[i].aggtranstype2)
+ free(agginfo[i].aggtranstype2);
+ if (agginfo[i].agginitval1)
+ free(agginfo[i].agginitval1);
+ if (agginfo[i].agginitval2)
+ free(agginfo[i].agginitval2);
+ if (agginfo[i].usename)
+ free(agginfo[i].usename);
+ }
+ free(agginfo);
}
/*
* getAggregates:
- * read all the user-defined aggregates in the system catalogs and
+ * read all the user-defined aggregates in the system catalogs and
* return them in the AggInfo* structure
*
- * numAggs is set to the number of aggregates read in
- *
+ * numAggs is set to the number of aggregates read in
+ *
*
*/
-AggInfo*
+AggInfo *
getAggregates(int *numAggs)
{
- PGresult* res;
- int ntups;
- int i;
- char query[MAXQUERYLEN];
- AggInfo *agginfo;
-
- int i_oid;
- int i_aggname;
- int i_aggtransfn1;
- int i_aggtransfn2;
- int i_aggfinalfn;
- int i_aggtranstype1;
- int i_aggbasetype;
- int i_aggtranstype2;
- int i_agginitval1;
- int i_agginitval2;
- int i_usename;
-
- /* find all user-defined aggregates */
-
- res = PQexec(g_conn, "begin");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
-
- sprintf(query,
- "SELECT pg_aggregate.oid, aggname, aggtransfn1, aggtransfn2, "
- "aggfinalfn, aggtranstype1, aggbasetype, aggtranstype2, "
- "agginitval1, agginitval2, usename from pg_aggregate, pg_user "
- "where aggowner = usesysid");
-
- res = PQexec(g_conn, query);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"getAggregates(): SELECT failed\n");
- exit_nicely(g_conn);
- }
-
- ntups = PQntuples(res);
- *numAggs = ntups;
-
- agginfo = (AggInfo*)malloc(ntups * sizeof(AggInfo));
-
- i_oid = PQfnumber(res,"oid");
- i_aggname = PQfnumber(res,"aggname");
- i_aggtransfn1 = PQfnumber(res,"aggtransfn1");
- i_aggtransfn2 = PQfnumber(res,"aggtransfn2");
- i_aggfinalfn = PQfnumber(res,"aggfinalfn");
- i_aggtranstype1 = PQfnumber(res,"aggtranstype1");
- i_aggbasetype = PQfnumber(res,"aggbasetype");
- i_aggtranstype2 = PQfnumber(res,"aggtranstype2");
- i_agginitval1 = PQfnumber(res,"agginitval1");
- i_agginitval2 = PQfnumber(res,"agginitval2");
- i_usename = PQfnumber(res,"usename");
-
- for (i=0;i<ntups;i++) {
- agginfo[i].oid = strdup(PQgetvalue(res,i,i_oid));
- agginfo[i].aggname = strdup(PQgetvalue(res,i,i_aggname));
- agginfo[i].aggtransfn1 = strdup(PQgetvalue(res,i,i_aggtransfn1));
- agginfo[i].aggtransfn2 = strdup(PQgetvalue(res,i,i_aggtransfn2));
- agginfo[i].aggfinalfn = strdup(PQgetvalue(res,i,i_aggfinalfn));
- agginfo[i].aggtranstype1 = strdup(PQgetvalue(res,i,i_aggtranstype1));
- agginfo[i].aggbasetype = strdup(PQgetvalue(res,i,i_aggbasetype));
- agginfo[i].aggtranstype2 = strdup(PQgetvalue(res,i,i_aggtranstype2));
- agginfo[i].agginitval1 = strdup(PQgetvalue(res,i,i_agginitval1));
- agginfo[i].agginitval2 = strdup(PQgetvalue(res,i,i_agginitval2));
- agginfo[i].usename = strdup(PQgetvalue(res,i,i_usename));
- }
-
- PQclear(res);
-
- res = PQexec(g_conn, "end");
- PQclear(res);
- return agginfo;
+ PGresult *res;
+ int ntups;
+ int i;
+ char query[MAXQUERYLEN];
+ AggInfo *agginfo;
+
+ int i_oid;
+ int i_aggname;
+ int i_aggtransfn1;
+ int i_aggtransfn2;
+ int i_aggfinalfn;
+ int i_aggtranstype1;
+ int i_aggbasetype;
+ int i_aggtranstype2;
+ int i_agginitval1;
+ int i_agginitval2;
+ int i_usename;
+
+ /* find all user-defined aggregates */
+
+ res = PQexec(g_conn, "begin");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+
+ sprintf(query,
+ "SELECT pg_aggregate.oid, aggname, aggtransfn1, aggtransfn2, "
+ "aggfinalfn, aggtranstype1, aggbasetype, aggtranstype2, "
+ "agginitval1, agginitval2, usename from pg_aggregate, pg_user "
+ "where aggowner = usesysid");
+
+ res = PQexec(g_conn, query);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "getAggregates(): SELECT failed\n");
+ exit_nicely(g_conn);
+ }
+
+ ntups = PQntuples(res);
+ *numAggs = ntups;
+
+ agginfo = (AggInfo *) malloc(ntups * sizeof(AggInfo));
+
+ i_oid = PQfnumber(res, "oid");
+ i_aggname = PQfnumber(res, "aggname");
+ i_aggtransfn1 = PQfnumber(res, "aggtransfn1");
+ i_aggtransfn2 = PQfnumber(res, "aggtransfn2");
+ i_aggfinalfn = PQfnumber(res, "aggfinalfn");
+ i_aggtranstype1 = PQfnumber(res, "aggtranstype1");
+ i_aggbasetype = PQfnumber(res, "aggbasetype");
+ i_aggtranstype2 = PQfnumber(res, "aggtranstype2");
+ i_agginitval1 = PQfnumber(res, "agginitval1");
+ i_agginitval2 = PQfnumber(res, "agginitval2");
+ i_usename = PQfnumber(res, "usename");
+
+ for (i = 0; i < ntups; i++)
+ {
+ agginfo[i].oid = strdup(PQgetvalue(res, i, i_oid));
+ agginfo[i].aggname = strdup(PQgetvalue(res, i, i_aggname));
+ agginfo[i].aggtransfn1 = strdup(PQgetvalue(res, i, i_aggtransfn1));
+ agginfo[i].aggtransfn2 = strdup(PQgetvalue(res, i, i_aggtransfn2));
+ agginfo[i].aggfinalfn = strdup(PQgetvalue(res, i, i_aggfinalfn));
+ agginfo[i].aggtranstype1 = strdup(PQgetvalue(res, i, i_aggtranstype1));
+ agginfo[i].aggbasetype = strdup(PQgetvalue(res, i, i_aggbasetype));
+ agginfo[i].aggtranstype2 = strdup(PQgetvalue(res, i, i_aggtranstype2));
+ agginfo[i].agginitval1 = strdup(PQgetvalue(res, i, i_agginitval1));
+ agginfo[i].agginitval2 = strdup(PQgetvalue(res, i, i_agginitval2));
+ agginfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+ }
+
+ PQclear(res);
+
+ res = PQexec(g_conn, "end");
+ PQclear(res);
+ return agginfo;
}
/*
* getFuncs:
- * read all the user-defined functions in the system catalogs and
+ * read all the user-defined functions in the system catalogs and
* return them in the FuncInfo* structure
*
- * numFuncs is set to the number of functions read in
- *
+ * numFuncs is set to the number of functions read in
+ *
*
*/
-FuncInfo*
+FuncInfo *
getFuncs(int *numFuncs)
{
- PGresult *res;
- int ntups;
- int i;
- char query[MAXQUERYLEN];
- FuncInfo *finfo;
-
- int i_oid;
- int i_proname;
- int i_prolang;
- int i_pronargs;
- int i_proargtypes;
- int i_prorettype;
- int i_proretset;
- int i_prosrc;
- int i_probin;
- int i_usename;
-
- /* find all user-defined funcs */
-
- res = PQexec(g_conn, "begin");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
-
- sprintf(query,
- "SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
- "proretset, proargtypes, prosrc, probin, usename "
- "from pg_proc, pg_user "
- "where pg_proc.oid > '%d'::oid and proowner = usesysid",
- g_last_builtin_oid);
-
- res = PQexec(g_conn, query);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"getFuncs(): SELECT failed\n");
- exit_nicely(g_conn);
- }
-
- ntups = PQntuples(res);
-
- *numFuncs = ntups;
-
- finfo = (FuncInfo*)malloc(ntups * sizeof(FuncInfo));
-
- i_oid = PQfnumber(res,"oid");
- i_proname = PQfnumber(res,"proname");
- i_prolang = PQfnumber(res,"prolang");
- i_pronargs = PQfnumber(res,"pronargs");
- i_proargtypes = PQfnumber(res,"proargtypes");
- i_prorettype = PQfnumber(res,"prorettype");
- i_proretset = PQfnumber(res,"proretset");
- i_prosrc = PQfnumber(res,"prosrc");
- i_probin = PQfnumber(res,"probin");
- i_usename = PQfnumber(res,"usename");
-
- for (i=0;i<ntups;i++) {
- finfo[i].oid = strdup(PQgetvalue(res,i,i_oid));
- finfo[i].proname = strdup(PQgetvalue(res,i,i_proname));
-
- finfo[i].prosrc = checkForQuote(PQgetvalue(res,i,i_prosrc));
- finfo[i].probin = strdup(PQgetvalue(res,i,i_probin));
-
- finfo[i].prorettype = strdup(PQgetvalue(res,i,i_prorettype));
- finfo[i].retset = (strcmp(PQgetvalue(res,i,i_proretset),"t") == 0);
- finfo[i].nargs = atoi(PQgetvalue(res,i,i_pronargs));
- finfo[i].lang = (atoi(PQgetvalue(res,i,i_prolang)) == C_PROLANG_OID);
-
- finfo[i].usename = strdup(PQgetvalue(res,i,i_usename));
-
- parseArgTypes(finfo[i].argtypes, PQgetvalue(res,i,i_proargtypes));
-
- finfo[i].dumped = 0;
- }
-
- PQclear(res);
- res = PQexec(g_conn, "end");
- PQclear(res);
-
- return finfo;
+ PGresult *res;
+ int ntups;
+ int i;
+ char query[MAXQUERYLEN];
+ FuncInfo *finfo;
+
+ int i_oid;
+ int i_proname;
+ int i_prolang;
+ int i_pronargs;
+ int i_proargtypes;
+ int i_prorettype;
+ int i_proretset;
+ int i_prosrc;
+ int i_probin;
+ int i_usename;
+
+ /* find all user-defined funcs */
+
+ res = PQexec(g_conn, "begin");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+
+ sprintf(query,
+ "SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
+ "proretset, proargtypes, prosrc, probin, usename "
+ "from pg_proc, pg_user "
+ "where pg_proc.oid > '%d'::oid and proowner = usesysid",
+ g_last_builtin_oid);
+
+ res = PQexec(g_conn, query);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "getFuncs(): SELECT failed\n");
+ exit_nicely(g_conn);
+ }
+
+ ntups = PQntuples(res);
+
+ *numFuncs = ntups;
+
+ finfo = (FuncInfo *) malloc(ntups * sizeof(FuncInfo));
+
+ i_oid = PQfnumber(res, "oid");
+ i_proname = PQfnumber(res, "proname");
+ i_prolang = PQfnumber(res, "prolang");
+ i_pronargs = PQfnumber(res, "pronargs");
+ i_proargtypes = PQfnumber(res, "proargtypes");
+ i_prorettype = PQfnumber(res, "prorettype");
+ i_proretset = PQfnumber(res, "proretset");
+ i_prosrc = PQfnumber(res, "prosrc");
+ i_probin = PQfnumber(res, "probin");
+ i_usename = PQfnumber(res, "usename");
+
+ for (i = 0; i < ntups; i++)
+ {
+ finfo[i].oid = strdup(PQgetvalue(res, i, i_oid));
+ finfo[i].proname = strdup(PQgetvalue(res, i, i_proname));
+
+ finfo[i].prosrc = checkForQuote(PQgetvalue(res, i, i_prosrc));
+ finfo[i].probin = strdup(PQgetvalue(res, i, i_probin));
+
+ finfo[i].prorettype = strdup(PQgetvalue(res, i, i_prorettype));
+ finfo[i].retset = (strcmp(PQgetvalue(res, i, i_proretset), "t") == 0);
+ finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
+ finfo[i].lang = (atoi(PQgetvalue(res, i, i_prolang)) == C_PROLANG_OID);
+
+ finfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+
+ parseArgTypes(finfo[i].argtypes, PQgetvalue(res, i, i_proargtypes));
+
+ finfo[i].dumped = 0;
+ }
+
+ PQclear(res);
+ res = PQexec(g_conn, "end");
+ PQclear(res);
+
+ return finfo;
}
/*
* getTables
- * read all the user-defined tables (no indices, no catalogs)
+ * read all the user-defined tables (no indices, no catalogs)
* in the system catalogs return them in the TableInfo* structure
*
- * numTables is set to the number of tables read in
- *
+ * numTables is set to the number of tables read in
+ *
*
*/
-TableInfo*
+TableInfo *
getTables(int *numTables)
{
- PGresult *res;
- int ntups;
- int i;
- char query[MAXQUERYLEN];
- TableInfo *tblinfo;
-
- int i_oid;
- int i_relname;
- int i_relarch;
- int i_relkind;
- int i_relacl;
- int i_usename;
-
- /* find all the user-defined tables (no indices and no catalogs),
- ordering by oid is important so that we always process the parent
- tables before the child tables when traversing the tblinfo*
-
- we ignore tables that start with xinv */
-
- res = PQexec(g_conn, "begin");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
-
- sprintf(query,
- "SELECT pg_class.oid, relname, relarch, relkind, relacl, usename "
- "from pg_class, pg_user "
- "where relowner = usesysid and "
- "(relkind = 'r' or relkind = 'S') and relname !~ '^pg_' "
- "and relname !~ '^xin[xv][0-9]+' order by oid");
-
- res = PQexec(g_conn, query);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"getTables(): SELECT failed\n");
- exit_nicely(g_conn);
- }
-
- ntups = PQntuples(res);
-
- *numTables = ntups;
-
- tblinfo = (TableInfo*)malloc(ntups * sizeof(TableInfo));
-
- i_oid = PQfnumber(res,"oid");
- i_relname = PQfnumber(res,"relname");
- i_relarch = PQfnumber(res,"relarch");
- i_relkind = PQfnumber(res,"relkind");
- i_relacl = PQfnumber(res,"relacl");
- i_usename = PQfnumber(res,"usename");
-
- for (i=0;i<ntups;i++) {
- tblinfo[i].oid = strdup(PQgetvalue(res,i,i_oid));
- tblinfo[i].relname = strdup(PQgetvalue(res,i,i_relname));
- tblinfo[i].relarch = strdup(PQgetvalue(res,i,i_relarch));
- tblinfo[i].relacl = strdup(PQgetvalue(res,i,i_relacl));
- tblinfo[i].sequence = (strcmp (PQgetvalue(res,i,i_relkind), "S") == 0);
- tblinfo[i].usename = strdup(PQgetvalue(res,i,i_usename));
- }
-
- PQclear(res);
- res = PQexec(g_conn, "end");
- PQclear(res);
-
- return tblinfo;
+ PGresult *res;
+ int ntups;
+ int i;
+ char query[MAXQUERYLEN];
+ TableInfo *tblinfo;
+
+ int i_oid;
+ int i_relname;
+ int i_relarch;
+ int i_relkind;
+ int i_relacl;
+ int i_usename;
+
+ /*
+ * find all the user-defined tables (no indices and no catalogs),
+ * ordering by oid is important so that we always process the parent
+ * tables before the child tables when traversing the tblinfo*
+ *
+ * we ignore tables that start with xinv
+ */
+
+ res = PQexec(g_conn, "begin");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+
+ sprintf(query,
+ "SELECT pg_class.oid, relname, relarch, relkind, relacl, usename "
+ "from pg_class, pg_user "
+ "where relowner = usesysid and "
+ "(relkind = 'r' or relkind = 'S') and relname !~ '^pg_' "
+ "and relname !~ '^xin[xv][0-9]+' order by oid");
+
+ res = PQexec(g_conn, query);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "getTables(): SELECT failed\n");
+ exit_nicely(g_conn);
+ }
+
+ ntups = PQntuples(res);
+
+ *numTables = ntups;
+
+ tblinfo = (TableInfo *) malloc(ntups * sizeof(TableInfo));
+
+ i_oid = PQfnumber(res, "oid");
+ i_relname = PQfnumber(res, "relname");
+ i_relarch = PQfnumber(res, "relarch");
+ i_relkind = PQfnumber(res, "relkind");
+ i_relacl = PQfnumber(res, "relacl");
+ i_usename = PQfnumber(res, "usename");
+
+ for (i = 0; i < ntups; i++)
+ {
+ tblinfo[i].oid = strdup(PQgetvalue(res, i, i_oid));
+ tblinfo[i].relname = strdup(PQgetvalue(res, i, i_relname));
+ tblinfo[i].relarch = strdup(PQgetvalue(res, i, i_relarch));
+ tblinfo[i].relacl = strdup(PQgetvalue(res, i, i_relacl));
+ tblinfo[i].sequence = (strcmp(PQgetvalue(res, i, i_relkind), "S") == 0);
+ tblinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+ }
+
+ PQclear(res);
+ res = PQexec(g_conn, "end");
+ PQclear(res);
+
+ return tblinfo;
}
/*
* getInherits
- * read all the inheritance information
+ * read all the inheritance information
* from the system catalogs return them in the InhInfo* structure
*
- * numInherits is set to the number of tables read in
- *
+ * numInherits is set to the number of tables read in
+ *
*
*/
-InhInfo*
+InhInfo *
getInherits(int *numInherits)
{
- PGresult *res;
- int ntups;
- int i;
- char query[MAXQUERYLEN];
- InhInfo *inhinfo;
-
- int i_inhrel;
- int i_inhparent;
-
- /* find all the inheritance information */
- res = PQexec(g_conn, "begin");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
-
- sprintf(query, "SELECT inhrel, inhparent from pg_inherits");
-
- res = PQexec(g_conn, query);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"getInherits(): SELECT failed\n");
- exit_nicely(g_conn);
- }
-
- ntups = PQntuples(res);
-
- *numInherits = ntups;
-
- inhinfo = (InhInfo*)malloc(ntups * sizeof(InhInfo));
-
- i_inhrel = PQfnumber(res,"inhrel");
- i_inhparent = PQfnumber(res,"inhparent");
-
- for (i=0;i<ntups;i++) {
- inhinfo[i].inhrel = strdup(PQgetvalue(res,i,i_inhrel));
- inhinfo[i].inhparent = strdup(PQgetvalue(res,i,i_inhparent));
- }
-
- PQclear(res);
- res = PQexec(g_conn, "end");
- PQclear(res);
- return inhinfo;
+ PGresult *res;
+ int ntups;
+ int i;
+ char query[MAXQUERYLEN];
+ InhInfo *inhinfo;
+
+ int i_inhrel;
+ int i_inhparent;
+
+ /* find all the inheritance information */
+ res = PQexec(g_conn, "begin");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+
+ sprintf(query, "SELECT inhrel, inhparent from pg_inherits");
+
+ res = PQexec(g_conn, query);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "getInherits(): SELECT failed\n");
+ exit_nicely(g_conn);
+ }
+
+ ntups = PQntuples(res);
+
+ *numInherits = ntups;
+
+ inhinfo = (InhInfo *) malloc(ntups * sizeof(InhInfo));
+
+ i_inhrel = PQfnumber(res, "inhrel");
+ i_inhparent = PQfnumber(res, "inhparent");
+
+ for (i = 0; i < ntups; i++)
+ {
+ inhinfo[i].inhrel = strdup(PQgetvalue(res, i, i_inhrel));
+ inhinfo[i].inhparent = strdup(PQgetvalue(res, i, i_inhparent));
+ }
+
+ PQclear(res);
+ res = PQexec(g_conn, "end");
+ PQclear(res);
+ return inhinfo;
}
/*
* getTableAttrs -
- * for each table in tblinfo, read its attributes types and names
- *
+ * for each table in tblinfo, read its attributes types and names
+ *
* this is implemented in a very inefficient way right now, looping
- * through the tblinfo and doing a join per table to find the attrs and their
+ * through the tblinfo and doing a join per table to find the attrs and their
* types
*
- * modifies tblinfo
+ * modifies tblinfo
*/
void
-getTableAttrs(TableInfo* tblinfo, int numTables)
+getTableAttrs(TableInfo * tblinfo, int numTables)
{
- int i,j;
- char q[MAXQUERYLEN];
- int i_attname;
- int i_typname;
- int i_attlen;
- int i_attnotnull;
- PGresult *res;
- int ntups;
-
- for (i=0;i<numTables;i++) {
-
- /* skip archive tables */
- if (isArchiveName(tblinfo[i].relname))
- continue;
-
- if ( tblinfo[i].sequence )
- continue;
-
- /* find all the user attributes and their types*/
- /* we must read the attribute names in attribute number order! */
- /* because we will use the attnum to index into the attnames array
- later */
- if (g_verbose)
- fprintf(stderr,"%s finding the attrs and types for table: %s %s\n",
- g_comment_start,
- tblinfo[i].relname,
- g_comment_end);
-
- sprintf(q,"SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull "
- "from pg_attribute a, pg_type t "
- "where a.attrelid = '%s'::oid and a.atttypid = t.oid "
- "and a.attnum > 0 order by attnum",
- tblinfo[i].oid);
- res = PQexec(g_conn, q);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"getTableAttrs(): SELECT failed\n");
- exit_nicely(g_conn);
- }
-
- ntups = PQntuples(res);
-
- i_attname = PQfnumber(res,"attname");
- i_typname = PQfnumber(res,"typname");
- i_attlen = PQfnumber(res,"attlen");
- i_attnotnull = PQfnumber(res,"attnotnull");
-
- tblinfo[i].numatts = ntups;
- tblinfo[i].attnames = (char**) malloc( ntups * sizeof(char*));
- tblinfo[i].typnames = (char**) malloc( ntups * sizeof(char*));
- tblinfo[i].attlen = (int*) malloc(ntups * sizeof(int));
- tblinfo[i].inhAttrs = (int*) malloc (ntups * sizeof(int));
- tblinfo[i].notnull = (bool*) malloc (ntups * sizeof(bool));
- tblinfo[i].parentRels = NULL;
- tblinfo[i].numParents = 0;
- for (j=0;j<ntups;j++) {
- tblinfo[i].attnames[j] = strdup(PQgetvalue(res,j,i_attname));
- tblinfo[i].typnames[j] = strdup(PQgetvalue(res,j,i_typname));
- tblinfo[i].attlen[j] = atoi(PQgetvalue(res,j,i_attlen));
- if (tblinfo[i].attlen[j] > 0)
- tblinfo[i].attlen[j] = tblinfo[i].attlen[j] - 4;
- tblinfo[i].inhAttrs[j] = 0; /* this flag is set in flagInhAttrs()*/
- tblinfo[i].notnull[j] = (PQgetvalue(res,j,i_attnotnull)[0]=='t')?true:false;
- }
- PQclear(res);
- }
+ int i,
+ j;
+ char q[MAXQUERYLEN];
+ int i_attname;
+ int i_typname;
+ int i_attlen;
+ int i_attnotnull;
+ PGresult *res;
+ int ntups;
+
+ for (i = 0; i < numTables; i++)
+ {
+
+ /* skip archive tables */
+ if (isArchiveName(tblinfo[i].relname))
+ continue;
+
+ if (tblinfo[i].sequence)
+ continue;
+
+ /* find all the user attributes and their types */
+ /* we must read the attribute names in attribute number order! */
+
+ /*
+ * because we will use the attnum to index into the attnames array
+ * later
+ */
+ if (g_verbose)
+ fprintf(stderr, "%s finding the attrs and types for table: %s %s\n",
+ g_comment_start,
+ tblinfo[i].relname,
+ g_comment_end);
+
+ sprintf(q, "SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull "
+ "from pg_attribute a, pg_type t "
+ "where a.attrelid = '%s'::oid and a.atttypid = t.oid "
+ "and a.attnum > 0 order by attnum",
+ tblinfo[i].oid);
+ res = PQexec(g_conn, q);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "getTableAttrs(): SELECT failed\n");
+ exit_nicely(g_conn);
+ }
+
+ ntups = PQntuples(res);
+
+ i_attname = PQfnumber(res, "attname");
+ i_typname = PQfnumber(res, "typname");
+ i_attlen = PQfnumber(res, "attlen");
+ i_attnotnull = PQfnumber(res, "attnotnull");
+
+ tblinfo[i].numatts = ntups;
+ tblinfo[i].attnames = (char **) malloc(ntups * sizeof(char *));
+ tblinfo[i].typnames = (char **) malloc(ntups * sizeof(char *));
+ tblinfo[i].attlen = (int *) malloc(ntups * sizeof(int));
+ tblinfo[i].inhAttrs = (int *) malloc(ntups * sizeof(int));
+ tblinfo[i].notnull = (bool *) malloc(ntups * sizeof(bool));
+ tblinfo[i].parentRels = NULL;
+ tblinfo[i].numParents = 0;
+ for (j = 0; j < ntups; j++)
+ {
+ tblinfo[i].attnames[j] = strdup(PQgetvalue(res, j, i_attname));
+ tblinfo[i].typnames[j] = strdup(PQgetvalue(res, j, i_typname));
+ tblinfo[i].attlen[j] = atoi(PQgetvalue(res, j, i_attlen));
+ if (tblinfo[i].attlen[j] > 0)
+ tblinfo[i].attlen[j] = tblinfo[i].attlen[j] - 4;
+ tblinfo[i].inhAttrs[j] = 0; /* this flag is set in
+ * flagInhAttrs() */
+ tblinfo[i].notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't') ? true : false;
+ }
+ PQclear(res);
+ }
}
/*
* getIndices
- * read all the user-defined indices information
+ * read all the user-defined indices information
* from the system catalogs return them in the InhInfo* structure
*
- * numIndices is set to the number of indices read in
- *
+ * numIndices is set to the number of indices read in
+ *
*
*/
-IndInfo*
+IndInfo *
getIndices(int *numIndices)
{
- int i;
- char query[MAXQUERYLEN];
- PGresult *res;
- int ntups;
- IndInfo *indinfo;
-
- int i_indexrelname;
- int i_indrelname;
- int i_indamname;
- int i_indproc;
- int i_indkey;
- int i_indclass;
- int i_indisunique;
-
- /*
- find all the user-defined indices.
- We do not handle partial indices.
-
- skip 'Xinx*' - indices on inversion objects
-
- this is a 4-way join !!
- */
-
- res = PQexec(g_conn, "begin");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
-
- sprintf(query,
- "SELECT t1.relname as indexrelname, t2.relname as indrelname, "
- "i.indproc, i.indkey, i.indclass, "
- "a.amname as indamname, i.indisunique "
- "from pg_index i, pg_class t1, pg_class t2, pg_am a "
- "where t1.oid = i.indexrelid and t2.oid = i.indrelid "
- "and t1.relam = a.oid and i.indexrelid > '%d'::oid "
- "and t2.relname !~ '^pg_' and t1.relname !~ '^Xinx'",
- g_last_builtin_oid);
-
- res = PQexec(g_conn, query);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"getIndices(): SELECT failed\n");
- exit_nicely(g_conn);
- }
-
- ntups = PQntuples(res);
-
- *numIndices = ntups;
-
- indinfo = (IndInfo*)malloc(ntups * sizeof (IndInfo));
-
- i_indexrelname = PQfnumber(res,"indexrelname");
- i_indrelname = PQfnumber(res,"indrelname");
- i_indamname = PQfnumber(res,"indamname");
- i_indproc = PQfnumber(res,"indproc");
- i_indkey = PQfnumber(res,"indkey");
- i_indclass = PQfnumber(res,"indclass");
- i_indisunique = PQfnumber(res,"indisunique");
-
- for (i=0;i<ntups;i++) {
- indinfo[i].indexrelname = strdup(PQgetvalue(res,i,i_indexrelname));
- indinfo[i].indrelname = strdup(PQgetvalue(res,i,i_indrelname));
- indinfo[i].indamname = strdup(PQgetvalue(res,i,i_indamname));
- indinfo[i].indproc = strdup(PQgetvalue(res,i,i_indproc));
- parseArgTypes ((char **)indinfo[i].indkey,
- (const char*)PQgetvalue(res,i,i_indkey));
- parseArgTypes ((char **)indinfo[i].indclass,
- (const char*)PQgetvalue(res,i,i_indclass));
- indinfo[i].indisunique = strdup(PQgetvalue(res,i,i_indisunique));
- }
- PQclear(res);
- res = PQexec(g_conn,"end");
- if(res) PQclear(res);
- return indinfo;
+ int i;
+ char query[MAXQUERYLEN];
+ PGresult *res;
+ int ntups;
+ IndInfo *indinfo;
+
+ int i_indexrelname;
+ int i_indrelname;
+ int i_indamname;
+ int i_indproc;
+ int i_indkey;
+ int i_indclass;
+ int i_indisunique;
+
+ /*
+ * find all the user-defined indices. We do not handle partial
+ * indices.
+ *
+ * skip 'Xinx*' - indices on inversion objects
+ *
+ * this is a 4-way join !!
+ */
+
+ res = PQexec(g_conn, "begin");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+
+ sprintf(query,
+ "SELECT t1.relname as indexrelname, t2.relname as indrelname, "
+ "i.indproc, i.indkey, i.indclass, "
+ "a.amname as indamname, i.indisunique "
+ "from pg_index i, pg_class t1, pg_class t2, pg_am a "
+ "where t1.oid = i.indexrelid and t2.oid = i.indrelid "
+ "and t1.relam = a.oid and i.indexrelid > '%d'::oid "
+ "and t2.relname !~ '^pg_' and t1.relname !~ '^Xinx'",
+ g_last_builtin_oid);
+
+ res = PQexec(g_conn, query);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "getIndices(): SELECT failed\n");
+ exit_nicely(g_conn);
+ }
+
+ ntups = PQntuples(res);
+
+ *numIndices = ntups;
+
+ indinfo = (IndInfo *) malloc(ntups * sizeof(IndInfo));
+
+ i_indexrelname = PQfnumber(res, "indexrelname");
+ i_indrelname = PQfnumber(res, "indrelname");
+ i_indamname = PQfnumber(res, "indamname");
+ i_indproc = PQfnumber(res, "indproc");
+ i_indkey = PQfnumber(res, "indkey");
+ i_indclass = PQfnumber(res, "indclass");
+ i_indisunique = PQfnumber(res, "indisunique");
+
+ for (i = 0; i < ntups; i++)
+ {
+ indinfo[i].indexrelname = strdup(PQgetvalue(res, i, i_indexrelname));
+ indinfo[i].indrelname = strdup(PQgetvalue(res, i, i_indrelname));
+ indinfo[i].indamname = strdup(PQgetvalue(res, i, i_indamname));
+ indinfo[i].indproc = strdup(PQgetvalue(res, i, i_indproc));
+ parseArgTypes((char **) indinfo[i].indkey,
+ (const char *) PQgetvalue(res, i, i_indkey));
+ parseArgTypes((char **) indinfo[i].indclass,
+ (const char *) PQgetvalue(res, i, i_indclass));
+ indinfo[i].indisunique = strdup(PQgetvalue(res, i, i_indisunique));
+ }
+ PQclear(res);
+ res = PQexec(g_conn, "end");
+ if (res)
+ PQclear(res);
+ return indinfo;
}
/*
* dumpTypes
- * writes out to fout the queries to recreate all the user-defined types
+ * writes out to fout the queries to recreate all the user-defined types
*
*/
void
-dumpTypes(FILE* fout, FuncInfo* finfo, int numFuncs,
- TypeInfo* tinfo, int numTypes)
+dumpTypes(FILE * fout, FuncInfo * finfo, int numFuncs,
+ TypeInfo * tinfo, int numTypes)
{
- int i;
- char q[MAXQUERYLEN];
- int funcInd;
-
- for (i=0;i<numTypes;i++) {
-
- /* skip all the builtin types */
- if (atoi(tinfo[i].oid) < g_last_builtin_oid)
- continue;
-
- /* skip relation types */
- if (atoi(tinfo[i].typrelid) != 0)
- continue;
-
- /* skip all array types that start w/ underscore */
- if ( (tinfo[i].typname[0] == '_') &&
- (strcmp(tinfo[i].typinput, "array_in") == 0))
- continue;
-
- /* before we create a type, we need to create the input and
- output functions for it, if they haven't been created already */
- funcInd = findFuncByName(finfo, numFuncs, tinfo[i].typinput);
- if (funcInd != -1)
- dumpOneFunc(fout,finfo,funcInd,tinfo,numTypes);
-
- funcInd = findFuncByName(finfo, numFuncs, tinfo[i].typoutput);
- if (funcInd != -1)
- dumpOneFunc(fout,finfo,funcInd,tinfo,numTypes);
-
- fprintf(fout,"\\connect - %s\n",tinfo[i].usename);
-
- sprintf(q,
- "CREATE TYPE %s "
- "( internallength = %s, externallength = %s, input = %s, "
- "output = %s, send = %s, receive = %s, default = '%s'",
- tinfo[i].typname,
- tinfo[i].typlen,
- tinfo[i].typprtlen,
- tinfo[i].typinput,
- tinfo[i].typoutput,
- tinfo[i].typsend,
- tinfo[i].typreceive,
- tinfo[i].typdefault);
-
- if (tinfo[i].isArray) {
- char* elemType;
-
- elemType = findTypeByOid(tinfo, numTypes, tinfo[i].typelem);
-
- sprintf(q,"%s, element = %s, delimiter = '%s'",
- q, elemType,tinfo[i].typdelim);
- }
- if (tinfo[i].passedbyvalue)
- strcat(q,",passedbyvalue);\n");
- else
- strcat(q,");\n");
-
- fputs(q,fout);
- }
+ int i;
+ char q[MAXQUERYLEN];
+ int funcInd;
+
+ for (i = 0; i < numTypes; i++)
+ {
+
+ /* skip all the builtin types */
+ if (atoi(tinfo[i].oid) < g_last_builtin_oid)
+ continue;
+
+ /* skip relation types */
+ if (atoi(tinfo[i].typrelid) != 0)
+ continue;
+
+ /* skip all array types that start w/ underscore */
+ if ((tinfo[i].typname[0] == '_') &&
+ (strcmp(tinfo[i].typinput, "array_in") == 0))
+ continue;
+
+ /*
+ * before we create a type, we need to create the input and output
+ * functions for it, if they haven't been created already
+ */
+ funcInd = findFuncByName(finfo, numFuncs, tinfo[i].typinput);
+ if (funcInd != -1)
+ dumpOneFunc(fout, finfo, funcInd, tinfo, numTypes);
+
+ funcInd = findFuncByName(finfo, numFuncs, tinfo[i].typoutput);
+ if (funcInd != -1)
+ dumpOneFunc(fout, finfo, funcInd, tinfo, numTypes);
+
+ fprintf(fout, "\\connect - %s\n", tinfo[i].usename);
+
+ sprintf(q,
+ "CREATE TYPE %s "
+ "( internallength = %s, externallength = %s, input = %s, "
+ "output = %s, send = %s, receive = %s, default = '%s'",
+ tinfo[i].typname,
+ tinfo[i].typlen,
+ tinfo[i].typprtlen,
+ tinfo[i].typinput,
+ tinfo[i].typoutput,
+ tinfo[i].typsend,
+ tinfo[i].typreceive,
+ tinfo[i].typdefault);
+
+ if (tinfo[i].isArray)
+ {
+ char *elemType;
+
+ elemType = findTypeByOid(tinfo, numTypes, tinfo[i].typelem);
+
+ sprintf(q, "%s, element = %s, delimiter = '%s'",
+ q, elemType, tinfo[i].typdelim);
+ }
+ if (tinfo[i].passedbyvalue)
+ strcat(q, ",passedbyvalue);\n");
+ else
+ strcat(q, ");\n");
+
+ fputs(q, fout);
+ }
}
/*
* dumpFuncs
- * writes out to fout the queries to recreate all the user-defined functions
+ * writes out to fout the queries to recreate all the user-defined functions
*
*/
void
-dumpFuncs(FILE* fout, FuncInfo* finfo, int numFuncs,
- TypeInfo *tinfo, int numTypes)
+dumpFuncs(FILE * fout, FuncInfo * finfo, int numFuncs,
+ TypeInfo * tinfo, int numTypes)
{
- int i;
- for (i=0;i<numFuncs;i++) {
- dumpOneFunc(fout,finfo,i,tinfo,numTypes);
- }
+ int i;
+
+ for (i = 0; i < numFuncs; i++)
+ {
+ dumpOneFunc(fout, finfo, i, tinfo, numTypes);
+ }
}
/*
* dumpOneFunc:
- * dump out only one function, the index of which is given in the third
- * argument
+ * dump out only one function, the index of which is given in the third
+ * argument
*
*/
static void
-dumpOneFunc(FILE* fout, FuncInfo* finfo, int i,
- TypeInfo *tinfo, int numTypes)
+dumpOneFunc(FILE * fout, FuncInfo * finfo, int i,
+ TypeInfo * tinfo, int numTypes)
{
- char q[MAXQUERYLEN];
- int j;
-
- if (finfo[i].dumped)
- return;
- else
- finfo[i].dumped = 1;
-
- fprintf(fout,"\\connect - %s\n",finfo[i].usename);
-
- sprintf(q,"CREATE FUNCTION %s (",finfo[i].proname);
- for (j=0;j<finfo[i].nargs;j++) {
- char* typname;
- typname = findTypeByOid(tinfo, numTypes, finfo[i].argtypes[j]);
- sprintf(q, "%s%s%s",
- q,
- (j > 0) ? "," : "",
- typname);
- }
- sprintf(q,"%s ) RETURNS %s%s AS '%s' LANGUAGE '%s';\n",
- q,
- (finfo[i].retset) ? " SETOF " : "",
- findTypeByOid(tinfo, numTypes, finfo[i].prorettype),
- (finfo[i].lang) ? finfo[i].probin : finfo[i].prosrc,
- (finfo[i].lang) ? "C" : "SQL");
-
- fputs(q,fout);
+ char q[MAXQUERYLEN];
+ int j;
+
+ if (finfo[i].dumped)
+ return;
+ else
+ finfo[i].dumped = 1;
+
+ fprintf(fout, "\\connect - %s\n", finfo[i].usename);
+
+ sprintf(q, "CREATE FUNCTION %s (", finfo[i].proname);
+ for (j = 0; j < finfo[i].nargs; j++)
+ {
+ char *typname;
+
+ typname = findTypeByOid(tinfo, numTypes, finfo[i].argtypes[j]);
+ sprintf(q, "%s%s%s",
+ q,
+ (j > 0) ? "," : "",
+ typname);
+ }
+ sprintf(q, "%s ) RETURNS %s%s AS '%s' LANGUAGE '%s';\n",
+ q,
+ (finfo[i].retset) ? " SETOF " : "",
+ findTypeByOid(tinfo, numTypes, finfo[i].prorettype),
+ (finfo[i].lang) ? finfo[i].probin : finfo[i].prosrc,
+ (finfo[i].lang) ? "C" : "SQL");
+
+ fputs(q, fout);
}
/*
* dumpOprs
- * writes out to fout the queries to recreate all the user-defined operators
+ * writes out to fout the queries to recreate all the user-defined operators
*
*/
-void
-dumpOprs(FILE* fout, OprInfo* oprinfo, int numOperators,
- TypeInfo *tinfo, int numTypes)
+void
+dumpOprs(FILE * fout, OprInfo * oprinfo, int numOperators,
+ TypeInfo * tinfo, int numTypes)
{
- int i;
- char q[MAXQUERYLEN];
- char leftarg[MAXQUERYLEN];
- char rightarg[MAXQUERYLEN];
- char commutator[MAXQUERYLEN];
- char negator[MAXQUERYLEN];
- char restrict[MAXQUERYLEN];
- char join[MAXQUERYLEN];
- char sortop[MAXQUERYLEN];
-
- for (i=0;i<numOperators;i++) {
-
- /* skip all the builtin oids */
- if (atoi(oprinfo[i].oid) < g_last_builtin_oid)
- continue;
-
- /* some operator are invalid because they were the result
- of user defining operators before commutators exist */
- if (strcmp(oprinfo[i].oprcode, "-") == 0)
- continue;
-
- leftarg[0] = '\0';
- rightarg[0] = '\0';
- /* right unary means there's a left arg
- and left unary means there's a right arg */
- if (strcmp(oprinfo[i].oprkind, "r") == 0 ||
- strcmp(oprinfo[i].oprkind, "b") == 0 ) {
- sprintf(leftarg, ", LEFTARG = %s ",
- findTypeByOid(tinfo, numTypes, oprinfo[i].oprleft));
- }
- if (strcmp(oprinfo[i].oprkind, "l") == 0 ||
- strcmp(oprinfo[i].oprkind, "b") == 0 ) {
- sprintf(rightarg, ", RIGHTARG = %s ",
- findTypeByOid(tinfo, numTypes, oprinfo[i].oprright));
- }
- if (strcmp(oprinfo[i].oprcom, "0") == 0)
- commutator[0] = '\0';
- else
- sprintf(commutator,", COMMUTATOR = %s ",
- findOprByOid(oprinfo, numOperators, oprinfo[i].oprcom));
-
- if (strcmp(oprinfo[i].oprnegate, "0") == 0)
- negator[0] = '\0';
- else
- sprintf(negator,", NEGATOR = %s ",
- findOprByOid(oprinfo, numOperators, oprinfo[i].oprnegate));
-
- if (strcmp(oprinfo[i].oprrest, "-") == 0)
- restrict[0] = '\0';
- else
- sprintf(restrict,", RESTRICT = %s ", oprinfo[i].oprrest);
-
- if (strcmp(oprinfo[i].oprjoin,"-") == 0)
- join[0] = '\0';
- else
- sprintf(join,", JOIN = %s ", oprinfo[i].oprjoin);
-
- if (strcmp(oprinfo[i].oprlsortop, "0") == 0)
- sortop[0] = '\0';
- else
- {
- sprintf(sortop,", SORT = %s ",
- findOprByOid(oprinfo, numOperators,
- oprinfo[i].oprlsortop));
- if (strcmp(oprinfo[i].oprrsortop, "0") != 0)
- sprintf(sortop, "%s , %s", sortop,
- findOprByOid(oprinfo, numOperators,
- oprinfo[i].oprlsortop));
- }
-
- fprintf(fout,"\\connect - %s\n", oprinfo[i].usename);
-
- sprintf(q,
- "CREATE OPERATOR %s "
- "(PROCEDURE = %s %s %s %s %s %s %s %s %s);\n ",
- oprinfo[i].oprname,
- oprinfo[i].oprcode,
- leftarg,
- rightarg,
- commutator,
- negator,
- restrict,
- (strcmp(oprinfo[i].oprcanhash, "t")) ? ", HASHES" : "",
- join,
- sortop);
-
- fputs(q,fout);
- }
+ int i;
+ char q[MAXQUERYLEN];
+ char leftarg[MAXQUERYLEN];
+ char rightarg[MAXQUERYLEN];
+ char commutator[MAXQUERYLEN];
+ char negator[MAXQUERYLEN];
+ char restrict[MAXQUERYLEN];
+ char join[MAXQUERYLEN];
+ char sortop[MAXQUERYLEN];
+
+ for (i = 0; i < numOperators; i++)
+ {
+
+ /* skip all the builtin oids */
+ if (atoi(oprinfo[i].oid) < g_last_builtin_oid)
+ continue;
+
+ /*
+ * some operator are invalid because they were the result of user
+ * defining operators before commutators exist
+ */
+ if (strcmp(oprinfo[i].oprcode, "-") == 0)
+ continue;
+
+ leftarg[0] = '\0';
+ rightarg[0] = '\0';
+
+ /*
+ * right unary means there's a left arg and left unary means
+ * there's a right arg
+ */
+ if (strcmp(oprinfo[i].oprkind, "r") == 0 ||
+ strcmp(oprinfo[i].oprkind, "b") == 0)
+ {
+ sprintf(leftarg, ", LEFTARG = %s ",
+ findTypeByOid(tinfo, numTypes, oprinfo[i].oprleft));
+ }
+ if (strcmp(oprinfo[i].oprkind, "l") == 0 ||
+ strcmp(oprinfo[i].oprkind, "b") == 0)
+ {
+ sprintf(rightarg, ", RIGHTARG = %s ",
+ findTypeByOid(tinfo, numTypes, oprinfo[i].oprright));
+ }
+ if (strcmp(oprinfo[i].oprcom, "0") == 0)
+ commutator[0] = '\0';
+ else
+ sprintf(commutator, ", COMMUTATOR = %s ",
+ findOprByOid(oprinfo, numOperators, oprinfo[i].oprcom));
+
+ if (strcmp(oprinfo[i].oprnegate, "0") == 0)
+ negator[0] = '\0';
+ else
+ sprintf(negator, ", NEGATOR = %s ",
+ findOprByOid(oprinfo, numOperators, oprinfo[i].oprnegate));
+
+ if (strcmp(oprinfo[i].oprrest, "-") == 0)
+ restrict[0] = '\0';
+ else
+ sprintf(restrict, ", RESTRICT = %s ", oprinfo[i].oprrest);
+
+ if (strcmp(oprinfo[i].oprjoin, "-") == 0)
+ join[0] = '\0';
+ else
+ sprintf(join, ", JOIN = %s ", oprinfo[i].oprjoin);
+
+ if (strcmp(oprinfo[i].oprlsortop, "0") == 0)
+ sortop[0] = '\0';
+ else
+ {
+ sprintf(sortop, ", SORT = %s ",
+ findOprByOid(oprinfo, numOperators,
+ oprinfo[i].oprlsortop));
+ if (strcmp(oprinfo[i].oprrsortop, "0") != 0)
+ sprintf(sortop, "%s , %s", sortop,
+ findOprByOid(oprinfo, numOperators,
+ oprinfo[i].oprlsortop));
+ }
+
+ fprintf(fout, "\\connect - %s\n", oprinfo[i].usename);
+
+ sprintf(q,
+ "CREATE OPERATOR %s "
+ "(PROCEDURE = %s %s %s %s %s %s %s %s %s);\n ",
+ oprinfo[i].oprname,
+ oprinfo[i].oprcode,
+ leftarg,
+ rightarg,
+ commutator,
+ negator,
+ restrict,
+ (strcmp(oprinfo[i].oprcanhash, "t")) ? ", HASHES" : "",
+ join,
+ sortop);
+
+ fputs(q, fout);
+ }
}
/*
* dumpAggs
- * writes out to fout the queries to create all the user-defined aggregates
+ * writes out to fout the queries to create all the user-defined aggregates
*
*/
void
-dumpAggs(FILE* fout, AggInfo* agginfo, int numAggs,
- TypeInfo *tinfo, int numTypes)
+dumpAggs(FILE * fout, AggInfo * agginfo, int numAggs,
+ TypeInfo * tinfo, int numTypes)
{
- int i;
- char q[MAXQUERYLEN];
- char sfunc1[MAXQUERYLEN];
- char sfunc2[MAXQUERYLEN];
- char finalfunc[MAXQUERYLEN];
- char comma1[2], comma2[2];
-
- for (i=0;i<numAggs;i++) {
- /* skip all the builtin oids */
- if (atoi(agginfo[i].oid) < g_last_builtin_oid)
- continue;
-
- if ( strcmp(agginfo[i].aggtransfn1, "-") == 0)
- sfunc1[0] = '\0';
- else {
- sprintf(sfunc1,
- "SFUNC1 = %s, BASETYPE = %s, STYPE1 = %s",
- agginfo[i].aggtransfn1,
- findTypeByOid(tinfo,numTypes,agginfo[i].aggbasetype),
- findTypeByOid(tinfo,numTypes,agginfo[i].aggtranstype1));
- if (agginfo[i].agginitval1)
- sprintf(sfunc1, "%s ,INITCOND1 = '%s'",
- sfunc1, agginfo[i].agginitval1);
-
- }
-
- if ( strcmp(agginfo[i].aggtransfn2, "-") == 0)
- sfunc2[0] = '\0';
- else {
- sprintf(sfunc2,
- "SFUNC2 = %s, STYPE2 = %s",
- agginfo[i].aggtransfn2,
- findTypeByOid(tinfo,numTypes,agginfo[i].aggtranstype2));
- if (agginfo[i].agginitval2)
- sprintf(sfunc2,"%s ,INITCOND2 = '%s'",
- sfunc2, agginfo[i].agginitval2);
- }
-
- if ( strcmp(agginfo[i].aggfinalfn, "-") == 0)
- finalfunc[0] = '\0';
- else {
- sprintf(finalfunc, "FINALFUNC = %s", agginfo[i].aggfinalfn);
- }
- if (sfunc1[0] != '\0' && sfunc2[0] != '\0') {
- comma1[0] = ','; comma1[1] = '\0';
- } else
- comma1[0] = '\0';
-
- if (finalfunc[0] != '\0' && (sfunc1[0] != '\0' || sfunc2[0] != '\0')) {
- comma2[0] = ',';comma2[1] = '\0';
- } else
- comma2[0] = '\0';
-
- fprintf(fout,"\\connect - %s\n", agginfo[i].usename);
-
- sprintf(q,"CREATE AGGREGATE %s ( %s %s %s %s %s );\n",
- agginfo[i].aggname,
- sfunc1,
- comma1,
- sfunc2,
- comma2,
- finalfunc);
-
- fputs(q,fout);
- }
+ int i;
+ char q[MAXQUERYLEN];
+ char sfunc1[MAXQUERYLEN];
+ char sfunc2[MAXQUERYLEN];
+ char finalfunc[MAXQUERYLEN];
+ char comma1[2],
+ comma2[2];
+
+ for (i = 0; i < numAggs; i++)
+ {
+ /* skip all the builtin oids */
+ if (atoi(agginfo[i].oid) < g_last_builtin_oid)
+ continue;
+
+ if (strcmp(agginfo[i].aggtransfn1, "-") == 0)
+ sfunc1[0] = '\0';
+ else
+ {
+ sprintf(sfunc1,
+ "SFUNC1 = %s, BASETYPE = %s, STYPE1 = %s",
+ agginfo[i].aggtransfn1,
+ findTypeByOid(tinfo, numTypes, agginfo[i].aggbasetype),
+ findTypeByOid(tinfo, numTypes, agginfo[i].aggtranstype1));
+ if (agginfo[i].agginitval1)
+ sprintf(sfunc1, "%s ,INITCOND1 = '%s'",
+ sfunc1, agginfo[i].agginitval1);
+
+ }
+
+ if (strcmp(agginfo[i].aggtransfn2, "-") == 0)
+ sfunc2[0] = '\0';
+ else
+ {
+ sprintf(sfunc2,
+ "SFUNC2 = %s, STYPE2 = %s",
+ agginfo[i].aggtransfn2,
+ findTypeByOid(tinfo, numTypes, agginfo[i].aggtranstype2));
+ if (agginfo[i].agginitval2)
+ sprintf(sfunc2, "%s ,INITCOND2 = '%s'",
+ sfunc2, agginfo[i].agginitval2);
+ }
+
+ if (strcmp(agginfo[i].aggfinalfn, "-") == 0)
+ finalfunc[0] = '\0';
+ else
+ {
+ sprintf(finalfunc, "FINALFUNC = %s", agginfo[i].aggfinalfn);
+ }
+ if (sfunc1[0] != '\0' && sfunc2[0] != '\0')
+ {
+ comma1[0] = ',';
+ comma1[1] = '\0';
+ }
+ else
+ comma1[0] = '\0';
+
+ if (finalfunc[0] != '\0' && (sfunc1[0] != '\0' || sfunc2[0] != '\0'))
+ {
+ comma2[0] = ',';
+ comma2[1] = '\0';
+ }
+ else
+ comma2[0] = '\0';
+
+ fprintf(fout, "\\connect - %s\n", agginfo[i].usename);
+
+ sprintf(q, "CREATE AGGREGATE %s ( %s %s %s %s %s );\n",
+ agginfo[i].aggname,
+ sfunc1,
+ comma1,
+ sfunc2,
+ comma2,
+ finalfunc);
+
+ fputs(q, fout);
+ }
}
/*
* dumpTables:
- * write out to fout all the user-define tables
+ * write out to fout all the user-define tables
*/
-void dumpTables(FILE* fout, TableInfo *tblinfo, int numTables,
- InhInfo *inhinfo, int numInherits,
- TypeInfo *tinfo, int numTypes, const char *tablename,
- const bool acls)
+void
+dumpTables(FILE * fout, TableInfo * tblinfo, int numTables,
+ InhInfo * inhinfo, int numInherits,
+ TypeInfo * tinfo, int numTypes, const char *tablename,
+ const bool acls)
{
- int i,j,k;
- char q[MAXQUERYLEN];
- char **parentRels; /* list of names of parent relations */
- int numParents;
- int actual_atts; /* number of attrs in this CREATE statment */
- const char *archiveMode;
-
- for (i=0;i<numTables;i++) {
-
- if (!tablename || (!strcmp(tblinfo[i].relname,tablename))) {
-
- /* Skip VIEW relations */
- if (isViewRule(tblinfo[i].relname))
- continue;
-
- /* skip archive names*/
- if (isArchiveName(tblinfo[i].relname))
- continue;
-
- if ( tblinfo[i].sequence )
- {
- dumpSequence (fout, tblinfo[i]);
- continue;
- }
-
- parentRels = tblinfo[i].parentRels;
- numParents = tblinfo[i].numParents;
-
- fprintf(fout, "\\connect - %s\n", tblinfo[i].usename);
-
- sprintf(q, "CREATE TABLE %s (", tblinfo[i].relname);
- actual_atts = 0;
- for (j=0;j<tblinfo[i].numatts;j++) {
- if (tblinfo[i].inhAttrs[j] == 0) {
-
- /* Show lengths on bpchar and varchar */
- if (!strcmp(tblinfo[i].typnames[j],"bpchar")) {
- sprintf(q, "%s%s%s char",
- q,
- (actual_atts > 0) ? ", " : "",
- tblinfo[i].attnames[j]);
-
- /* stored length can be -1 (variable) */
- if (tblinfo[i].attlen[j] > 0)
- sprintf(q, "%s(%d)",
- q,
- tblinfo[i].attlen[j]);
- actual_atts++;
- }
- else if (!strcmp(tblinfo[i].typnames[j],"varchar")) {
- sprintf(q, "%s%s%s %s",
- q,
- (actual_atts > 0) ? ", " : "",
- tblinfo[i].attnames[j],
- tblinfo[i].typnames[j]);
-
- /* stored length can be -1 (variable) */
- if (tblinfo[i].attlen[j] > 0)
- sprintf(q, "%s(%d)",
- q,
- tblinfo[i].attlen[j]);
- actual_atts++;
- }
- else {
- sprintf(q, "%s%s%s %s",
- q,
- (actual_atts > 0) ? ", " : "",
- tblinfo[i].attnames[j],
- tblinfo[i].typnames[j]);
- actual_atts++;
- }
- if (tblinfo[i].notnull[j])
- sprintf(q, "%s NOT NULL", q);
- }
- }
-
- strcat(q,")");
-
- if (numParents > 0) {
- sprintf(q, "%s inherits ( ",q);
- for (k=0;k<numParents;k++){
- sprintf(q, "%s%s%s",
- q,
- (k>0) ? ", " : "",
- parentRels[k]);
- }
- strcat(q,")");
- }
-
- switch(tblinfo[i].relarch[0]) {
- case 'n':
- archiveMode = "none";
- break;
- case 'h':
- archiveMode = "heavy";
- break;
- case 'l':
- archiveMode = "light";
- break;
- default:
- fprintf(stderr, "unknown archive mode\n");
- archiveMode = "none";
- break;
- }
-
- sprintf(q, "%s archive = %s;\n",
- q,
- archiveMode);
- fputs(q,fout);
-
- if(acls)
- fprintf(fout,
- "UPDATE pg_class SET relacl='%s' where relname='%s';\n",
- tblinfo[i].relacl, tblinfo[i].relname);
- }
- }
+ int i,
+ j,
+ k;
+ char q[MAXQUERYLEN];
+ char **parentRels; /* list of names of parent relations */
+ int numParents;
+ int actual_atts;/* number of attrs in this CREATE statment */
+ const char *archiveMode;
+
+ for (i = 0; i < numTables; i++)
+ {
+
+ if (!tablename || (!strcmp(tblinfo[i].relname, tablename)))
+ {
+
+ /* Skip VIEW relations */
+ if (isViewRule(tblinfo[i].relname))
+ continue;
+
+ /* skip archive names */
+ if (isArchiveName(tblinfo[i].relname))
+ continue;
+
+ if (tblinfo[i].sequence)
+ {
+ dumpSequence(fout, tblinfo[i]);
+ continue;
+ }
+
+ parentRels = tblinfo[i].parentRels;
+ numParents = tblinfo[i].numParents;
+
+ fprintf(fout, "\\connect - %s\n", tblinfo[i].usename);
+
+ sprintf(q, "CREATE TABLE %s (", tblinfo[i].relname);
+ actual_atts = 0;
+ for (j = 0; j < tblinfo[i].numatts; j++)
+ {
+ if (tblinfo[i].inhAttrs[j] == 0)
+ {
+
+ /* Show lengths on bpchar and varchar */
+ if (!strcmp(tblinfo[i].typnames[j], "bpchar"))
+ {
+ sprintf(q, "%s%s%s char",
+ q,
+ (actual_atts > 0) ? ", " : "",
+ tblinfo[i].attnames[j]);
+
+ /* stored length can be -1 (variable) */
+ if (tblinfo[i].attlen[j] > 0)
+ sprintf(q, "%s(%d)",
+ q,
+ tblinfo[i].attlen[j]);
+ actual_atts++;
+ }
+ else if (!strcmp(tblinfo[i].typnames[j], "varchar"))
+ {
+ sprintf(q, "%s%s%s %s",
+ q,
+ (actual_atts > 0) ? ", " : "",
+ tblinfo[i].attnames[j],
+ tblinfo[i].typnames[j]);
+
+ /* stored length can be -1 (variable) */
+ if (tblinfo[i].attlen[j] > 0)
+ sprintf(q, "%s(%d)",
+ q,
+ tblinfo[i].attlen[j]);
+ actual_atts++;
+ }
+ else
+ {
+ sprintf(q, "%s%s%s %s",
+ q,
+ (actual_atts > 0) ? ", " : "",
+ tblinfo[i].attnames[j],
+ tblinfo[i].typnames[j]);
+ actual_atts++;
+ }
+ if (tblinfo[i].notnull[j])
+ sprintf(q, "%s NOT NULL", q);
+ }
+ }
+
+ strcat(q, ")");
+
+ if (numParents > 0)
+ {
+ sprintf(q, "%s inherits ( ", q);
+ for (k = 0; k < numParents; k++)
+ {
+ sprintf(q, "%s%s%s",
+ q,
+ (k > 0) ? ", " : "",
+ parentRels[k]);
+ }
+ strcat(q, ")");
+ }
+
+ switch (tblinfo[i].relarch[0])
+ {
+ case 'n':
+ archiveMode = "none";
+ break;
+ case 'h':
+ archiveMode = "heavy";
+ break;
+ case 'l':
+ archiveMode = "light";
+ break;
+ default:
+ fprintf(stderr, "unknown archive mode\n");
+ archiveMode = "none";
+ break;
+ }
+
+ sprintf(q, "%s archive = %s;\n",
+ q,
+ archiveMode);
+ fputs(q, fout);
+
+ if (acls)
+ fprintf(fout,
+ "UPDATE pg_class SET relacl='%s' where relname='%s';\n",
+ tblinfo[i].relacl, tblinfo[i].relname);
+ }
+ }
}
/*
* dumpIndices:
- * write out to fout all the user-define indices
+ * write out to fout all the user-define indices
*/
-void
-dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices,
- TableInfo* tblinfo, int numTables, const char *tablename)
+void
+dumpIndices(FILE * fout, IndInfo * indinfo, int numIndices,
+ TableInfo * tblinfo, int numTables, const char *tablename)
{
- int i, k;
- int tableInd;
- char attlist[1000];
- char *classname[INDEX_MAX_KEYS];
- char *funcname; /* the name of the function to comput the index key from*/
- int indkey, indclass;
- int nclass;
-
- char q[MAXQUERYLEN];
- PGresult *res;
-
- for (i=0;i<numIndices;i++) {
- tableInd = findTableByName(tblinfo, numTables,
- indinfo[i].indrelname);
-
- if (strcmp(indinfo[i].indproc,"0") == 0) {
- funcname = NULL;
- } else {
- /* the funcname is an oid which we use to
- find the name of the pg_proc. We need to do this
- because getFuncs() only reads in the user-defined funcs
- not all the funcs. We might not find what we want
- by looking in FuncInfo**/
- sprintf(q,
- "SELECT proname from pg_proc "
- "where pg_proc.oid = '%s'::oid",
- indinfo[i].indproc);
- res = PQexec(g_conn, q);
- if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK )
- {
- fprintf(stderr,"dumpIndices(): SELECT (funcname) failed\n");
- exit_nicely(g_conn);
- }
- funcname = strdup(PQgetvalue(res, 0,
- PQfnumber(res,"proname")));
- PQclear(res);
- }
-
- /* convert opclass oid(s) into names */
- for (nclass = 0; nclass < INDEX_MAX_KEYS; nclass++)
- {
- indclass = atoi(indinfo[i].indclass[nclass]);
- if ( indclass == 0 )
- break;
- sprintf(q,
- "SELECT opcname from pg_opclass "
- "where pg_opclass.oid = '%u'::oid",
- indclass);
- res = PQexec(g_conn, q);
- if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK )
- {
- fprintf(stderr,"dumpIndices(): SELECT (classname) failed\n");
- exit_nicely(g_conn);
- }
- classname[nclass] = strdup(PQgetvalue(res, 0,
- PQfnumber(res,"opcname")));
- PQclear(res);
- }
-
- if ( funcname && nclass != 1 )
- {
- fprintf(stderr,"dumpIndices(): Must be exactly one OpClass "
- "for functional index %s\n", indinfo[i].indexrelname);
- exit_nicely(g_conn);
- }
-
- /* convert attribute numbers into attribute list */
- for (k = 0, attlist[0] = 0; k < INDEX_MAX_KEYS; k++)
- {
- char * attname;
-
- indkey = atoi(indinfo[i].indkey[k]);
- if ( indkey == 0 )
- break;
- indkey--;
- if (indkey == ObjectIdAttributeNumber - 1)
- attname = "oid";
- else
- attname = tblinfo[tableInd].attnames[indkey];
- if ( funcname )
- sprintf (attlist + strlen(attlist), "%s%s",
- ( k == 0 ) ? "" : ", ", attname);
- else
- {
- if ( k >= nclass )
- {
- fprintf(stderr,"dumpIndices(): OpClass not found for "
- "attribute %s of index %s\n",
- attname, indinfo[i].indexrelname);
- exit_nicely(g_conn);
- }
- sprintf (attlist + strlen(attlist), "%s%s %s",
- ( k == 0 ) ? "" : ", ", attname, classname[k]);
- free (classname[k]);
- }
- }
-
- if (!tablename || (!strcmp(indinfo[i].indrelname,tablename))) {
-
- sprintf(q,"CREATE %s INDEX %s on %s using %s (",
- (strcmp(indinfo[i].indisunique, "t") == 0) ? "UNIQUE" : "",
- indinfo[i].indexrelname,
- indinfo[i].indrelname,
- indinfo[i].indamname);
- if (funcname) {
- sprintf(q, "%s %s (%s) %s );\n",
- q, funcname, attlist, classname[0]);
- free(funcname);
- free(classname[0]);
- } else
- sprintf(q, "%s %s );\n",
- q, attlist);
-
- fputs(q,fout);
- }
- }
+ int i,
+ k;
+ int tableInd;
+ char attlist[1000];
+ char *classname[INDEX_MAX_KEYS];
+ char *funcname; /* the name of the function to comput the
+ * index key from */
+ int indkey,
+ indclass;
+ int nclass;
+
+ char q[MAXQUERYLEN];
+ PGresult *res;
+
+ for (i = 0; i < numIndices; i++)
+ {
+ tableInd = findTableByName(tblinfo, numTables,
+ indinfo[i].indrelname);
+
+ if (strcmp(indinfo[i].indproc, "0") == 0)
+ {
+ funcname = NULL;
+ }
+ else
+ {
+
+ /*
+ * the funcname is an oid which we use to find the name of the
+ * pg_proc. We need to do this because getFuncs() only reads
+ * in the user-defined funcs not all the funcs. We might not
+ * find what we want by looking in FuncInfo*
+ */
+ sprintf(q,
+ "SELECT proname from pg_proc "
+ "where pg_proc.oid = '%s'::oid",
+ indinfo[i].indproc);
+ res = PQexec(g_conn, q);
+ if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "dumpIndices(): SELECT (funcname) failed\n");
+ exit_nicely(g_conn);
+ }
+ funcname = strdup(PQgetvalue(res, 0,
+ PQfnumber(res, "proname")));
+ PQclear(res);
+ }
+
+ /* convert opclass oid(s) into names */
+ for (nclass = 0; nclass < INDEX_MAX_KEYS; nclass++)
+ {
+ indclass = atoi(indinfo[i].indclass[nclass]);
+ if (indclass == 0)
+ break;
+ sprintf(q,
+ "SELECT opcname from pg_opclass "
+ "where pg_opclass.oid = '%u'::oid",
+ indclass);
+ res = PQexec(g_conn, q);
+ if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "dumpIndices(): SELECT (classname) failed\n");
+ exit_nicely(g_conn);
+ }
+ classname[nclass] = strdup(PQgetvalue(res, 0,
+ PQfnumber(res, "opcname")));
+ PQclear(res);
+ }
+
+ if (funcname && nclass != 1)
+ {
+ fprintf(stderr, "dumpIndices(): Must be exactly one OpClass "
+ "for functional index %s\n", indinfo[i].indexrelname);
+ exit_nicely(g_conn);
+ }
+
+ /* convert attribute numbers into attribute list */
+ for (k = 0, attlist[0] = 0; k < INDEX_MAX_KEYS; k++)
+ {
+ char *attname;
+
+ indkey = atoi(indinfo[i].indkey[k]);
+ if (indkey == 0)
+ break;
+ indkey--;
+ if (indkey == ObjectIdAttributeNumber - 1)
+ attname = "oid";
+ else
+ attname = tblinfo[tableInd].attnames[indkey];
+ if (funcname)
+ sprintf(attlist + strlen(attlist), "%s%s",
+ (k == 0) ? "" : ", ", attname);
+ else
+ {
+ if (k >= nclass)
+ {
+ fprintf(stderr, "dumpIndices(): OpClass not found for "
+ "attribute %s of index %s\n",
+ attname, indinfo[i].indexrelname);
+ exit_nicely(g_conn);
+ }
+ sprintf(attlist + strlen(attlist), "%s%s %s",
+ (k == 0) ? "" : ", ", attname, classname[k]);
+ free(classname[k]);
+ }
+ }
+
+ if (!tablename || (!strcmp(indinfo[i].indrelname, tablename)))
+ {
+
+ sprintf(q, "CREATE %s INDEX %s on %s using %s (",
+ (strcmp(indinfo[i].indisunique, "t") == 0) ? "UNIQUE" : "",
+ indinfo[i].indexrelname,
+ indinfo[i].indrelname,
+ indinfo[i].indamname);
+ if (funcname)
+ {
+ sprintf(q, "%s %s (%s) %s );\n",
+ q, funcname, attlist, classname[0]);
+ free(funcname);
+ free(classname[0]);
+ }
+ else
+ sprintf(q, "%s %s );\n",
+ q, attlist);
+
+ fputs(q, fout);
+ }
+ }
}
+
/*
* dumpTuples --
- * prints out the tuples in ASCII representation. The output is a valid
- * input to COPY FROM stdin.
+ * prints out the tuples in ASCII representation. The output is a valid
+ * input to COPY FROM stdin.
+ *
+ * We only need to do this for POSTGRES 4.2 databases since the
+ * COPY TO statment doesn't escape newlines properly. It's been fixed
+ * in Postgres95.
*
- * We only need to do this for POSTGRES 4.2 databases since the
- * COPY TO statment doesn't escape newlines properly. It's been fixed
- * in Postgres95.
- *
* the attrmap passed in tells how to map the attributes copied in to the
* attributes copied out
*/
#ifdef NOT_USED
void
-dumpTuples(PGresult *res, FILE *fout, int* attrmap)
+dumpTuples(PGresult * res, FILE * fout, int *attrmap)
{
- int j, k;
- int m, n;
- char **outVals = NULL; /* values to copy out */
-
- n = PQntuples(res);
- m = PQnfields(res);
-
- if ( m > 0 ) {
- /*
- * Print out the tuples but only print tuples with at least
- * 1 field.
- */
- outVals = (char**)malloc(m * sizeof(char*));
-
- for (j = 0; j < n; j++) {
- for (k = 0; k < m; k++) {
- outVals[attrmap[k]] = PQgetvalue(res, j, k);
- }
- for (k = 0; k < m; k++) {
- char *pval = outVals[k];
-
- if (k!=0)
- fputc('\t', fout); /* delimiter for attribute */
-
- if (pval) {
- while (*pval != '\0') {
- /* escape tabs, newlines and backslashes */
- if (*pval=='\t' || *pval=='\n' || *pval=='\\')
- fputc('\\', fout);
- fputc(*pval, fout);
- pval++;
- }
- }
- }
- fputc('\n', fout); /* delimiter for a tuple */
- }
- free (outVals);
- }
+ int j,
+ k;
+ int m,
+ n;
+ char **outVals = NULL; /* values to copy out */
+
+ n = PQntuples(res);
+ m = PQnfields(res);
+
+ if (m > 0)
+ {
+
+ /*
+ * Print out the tuples but only print tuples with at least 1
+ * field.
+ */
+ outVals = (char **) malloc(m * sizeof(char *));
+
+ for (j = 0; j < n; j++)
+ {
+ for (k = 0; k < m; k++)
+ {
+ outVals[attrmap[k]] = PQgetvalue(res, j, k);
+ }
+ for (k = 0; k < m; k++)
+ {
+ char *pval = outVals[k];
+
+ if (k != 0)
+ fputc('\t', fout); /* delimiter for attribute */
+
+ if (pval)
+ {
+ while (*pval != '\0')
+ {
+ /* escape tabs, newlines and backslashes */
+ if (*pval == '\t' || *pval == '\n' || *pval == '\\')
+ fputc('\\', fout);
+ fputc(*pval, fout);
+ pval++;
+ }
+ }
+ }
+ fputc('\n', fout); /* delimiter for a tuple */
+ }
+ free(outVals);
+ }
}
+
#endif
/*
@@ -2015,173 +2271,187 @@ dumpTuples(PGresult *res, FILE *fout, int* attrmap)
*/
static void
-setMaxOid(FILE *fout)
+setMaxOid(FILE * fout)
{
- PGresult *res;
- Oid max_oid;
-
- res = PQexec(g_conn, "CREATE TABLE pgdump_oid (dummy int4)");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"Can not create pgdump_oid table\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
- res = PQexec(g_conn, "INSERT INTO pgdump_oid VALUES (0)");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"Can not insert into pgdump_oid table\n");
- exit_nicely(g_conn);
- }
- max_oid = atol(PQoidStatus(res));
- if (max_oid == 0) {
- fprintf(stderr,"Invalid max id in setMaxOid\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
- res = PQexec(g_conn, "DROP TABLE pgdump_oid;");
- if (!res ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"Can not drop pgdump_oid table\n");
- exit_nicely(g_conn);
- }
- PQclear(res);
- if (g_verbose)
- fprintf(stderr, "%s maximum system oid is %d %s\n",
- g_comment_start, max_oid, g_comment_end);
- fprintf(fout, "CREATE TABLE pgdump_oid (dummy int4);\n");
- fprintf(fout, "COPY pgdump_oid WITH OIDS FROM stdin;\n");
- fprintf(fout, "%-d\t0\n", max_oid);
- fprintf(fout, "\\.\n");
- fprintf(fout, "DROP TABLE pgdump_oid;\n");
-}
+ PGresult *res;
+ Oid max_oid;
+
+ res = PQexec(g_conn, "CREATE TABLE pgdump_oid (dummy int4)");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "Can not create pgdump_oid table\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+ res = PQexec(g_conn, "INSERT INTO pgdump_oid VALUES (0)");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "Can not insert into pgdump_oid table\n");
+ exit_nicely(g_conn);
+ }
+ max_oid = atol(PQoidStatus(res));
+ if (max_oid == 0)
+ {
+ fprintf(stderr, "Invalid max id in setMaxOid\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+ res = PQexec(g_conn, "DROP TABLE pgdump_oid;");
+ if (!res ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "Can not drop pgdump_oid table\n");
+ exit_nicely(g_conn);
+ }
+ PQclear(res);
+ if (g_verbose)
+ fprintf(stderr, "%s maximum system oid is %d %s\n",
+ g_comment_start, max_oid, g_comment_end);
+ fprintf(fout, "CREATE TABLE pgdump_oid (dummy int4);\n");
+ fprintf(fout, "COPY pgdump_oid WITH OIDS FROM stdin;\n");
+ fprintf(fout, "%-d\t0\n", max_oid);
+ fprintf(fout, "\\.\n");
+ fprintf(fout, "DROP TABLE pgdump_oid;\n");
+}
/*
* findLastBuiltInOid -
- * find the last built in oid
+ * find the last built in oid
* we do this by looking up the oid of 'template1' in pg_database,
- * this is probably not foolproof but comes close
+ * this is probably not foolproof but comes close
*/
static int
findLastBuiltinOid(void)
{
- PGresult* res;
- int ntups;
- int last_oid;
-
- res = PQexec(g_conn,
- "SELECT oid from pg_database where datname = 'template1'");
- if (res == NULL ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"pg_dump error in finding the template1 database\n");
- exit_nicely(g_conn);
- }
- ntups = PQntuples(res);
- if (ntups != 1) {
- fprintf(stderr,"pg_dump: couldn't find the template1 database. "
- "You are really hosed.\nGiving up.\n");
- exit_nicely(g_conn);
- }
- last_oid = atoi(PQgetvalue(res, 0, PQfnumber(res, "oid")));
- PQclear(res);
- return last_oid;
+ PGresult *res;
+ int ntups;
+ int last_oid;
+
+ res = PQexec(g_conn,
+ "SELECT oid from pg_database where datname = 'template1'");
+ if (res == NULL ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "pg_dump error in finding the template1 database\n");
+ exit_nicely(g_conn);
+ }
+ ntups = PQntuples(res);
+ if (ntups != 1)
+ {
+ fprintf(stderr, "pg_dump: couldn't find the template1 database. "
+ "You are really hosed.\nGiving up.\n");
+ exit_nicely(g_conn);
+ }
+ last_oid = atoi(PQgetvalue(res, 0, PQfnumber(res, "oid")));
+ PQclear(res);
+ return last_oid;
}
/*
* checkForQuote:
- * checks a string for quote characters and quotes them
+ * checks a string for quote characters and quotes them
*/
-static char*
-checkForQuote(const char* s)
+static char *
+checkForQuote(const char *s)
{
- char *r;
- char c;
- char *result;
+ char *r;
+ char c;
+ char *result;
- int j = 0;
+ int j = 0;
- r = malloc(strlen(s)*3 + 1); /* definitely long enough */
+ r = malloc(strlen(s) * 3 + 1); /* definitely long enough */
- while ( (c = *s) != '\0') {
+ while ((c = *s) != '\0')
+ {
- if (c == '\'') {
- r[j++] = '\''; /* quote the single quotes */
- }
- r[j++] = c;
- s++;
- }
- r[j] = '\0';
+ if (c == '\'')
+ {
+ r[j++] = '\''; /* quote the single quotes */
+ }
+ r[j++] = c;
+ s++;
+ }
+ r[j] = '\0';
+
+ result = strdup(r);
+ free(r);
- result = strdup(r);
- free(r);
+ return result;
- return result;
-
}
-static void dumpSequence (FILE* fout, TableInfo tbinfo)
+static void
+dumpSequence(FILE * fout, TableInfo tbinfo)
{
- PGresult *res;
- int4 last, incby, maxv, minv, cache;
- char cycled, called, *t;
- char query[MAXQUERYLEN];
-
- sprintf (query,
- "SELECT sequence_name, last_value, increment_by, max_value, "
- "min_value, cache_value, is_cycled, is_called from %s",
- tbinfo.relname);
-
- res = PQexec (g_conn, query);
- if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK )
- {
- fprintf (stderr,"dumpSequence(%s): SELECT failed\n", tbinfo.relname);
- exit_nicely (g_conn);
- }
-
- if ( PQntuples (res) != 1 )
- {
- fprintf (stderr,"dumpSequence(%s): %d (!= 1) tuples returned by SELECT\n",
- tbinfo.relname, PQntuples(res));
- exit_nicely (g_conn);
- }
-
- if ( strcmp (PQgetvalue (res,0,0), tbinfo.relname) != 0 )
- {
- fprintf (stderr, "dumpSequence(%s): different sequence name "
- "returned by SELECT: %s\n",
- tbinfo.relname, PQgetvalue (res,0,0));
- exit_nicely (g_conn);
- }
-
-
- last = atoi (PQgetvalue (res,0,1));
- incby = atoi (PQgetvalue (res,0,2));
- maxv = atoi (PQgetvalue (res,0,3));
- minv = atoi (PQgetvalue (res,0,4));
- cache = atoi (PQgetvalue (res,0,5));
- t = PQgetvalue (res,0,6);
- cycled = *t;
- t = PQgetvalue (res,0,7);
- called = *t;
-
- PQclear (res);
-
- sprintf (query,
- "CREATE SEQUENCE %s start %d increment %d maxvalue %d "
- "minvalue %d cache %d %s;\n",
- tbinfo.relname, last, incby, maxv, minv, cache,
- (cycled == 't') ? "cycle" : "");
-
- fputs (query, fout);
-
- if ( called == 'f' )
- return; /* nothing to do more */
-
- sprintf (query, "SELECT nextval ('%s');\n", tbinfo.relname);
- fputs (query, fout);
+ PGresult *res;
+ int4 last,
+ incby,
+ maxv,
+ minv,
+ cache;
+ char cycled,
+ called,
+ *t;
+ char query[MAXQUERYLEN];
+
+ sprintf(query,
+ "SELECT sequence_name, last_value, increment_by, max_value, "
+ "min_value, cache_value, is_cycled, is_called from %s",
+ tbinfo.relname);
+
+ res = PQexec(g_conn, query);
+ if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "dumpSequence(%s): SELECT failed\n", tbinfo.relname);
+ exit_nicely(g_conn);
+ }
+
+ if (PQntuples(res) != 1)
+ {
+ fprintf(stderr, "dumpSequence(%s): %d (!= 1) tuples returned by SELECT\n",
+ tbinfo.relname, PQntuples(res));
+ exit_nicely(g_conn);
+ }
+
+ if (strcmp(PQgetvalue(res, 0, 0), tbinfo.relname) != 0)
+ {
+ fprintf(stderr, "dumpSequence(%s): different sequence name "
+ "returned by SELECT: %s\n",
+ tbinfo.relname, PQgetvalue(res, 0, 0));
+ exit_nicely(g_conn);
+ }
+
+
+ last = atoi(PQgetvalue(res, 0, 1));
+ incby = atoi(PQgetvalue(res, 0, 2));
+ maxv = atoi(PQgetvalue(res, 0, 3));
+ minv = atoi(PQgetvalue(res, 0, 4));
+ cache = atoi(PQgetvalue(res, 0, 5));
+ t = PQgetvalue(res, 0, 6);
+ cycled = *t;
+ t = PQgetvalue(res, 0, 7);
+ called = *t;
+
+ PQclear(res);
+
+ sprintf(query,
+ "CREATE SEQUENCE %s start %d increment %d maxvalue %d "
+ "minvalue %d cache %d %s;\n",
+ tbinfo.relname, last, incby, maxv, minv, cache,
+ (cycled == 't') ? "cycle" : "");
+
+ fputs(query, fout);
+
+ if (called == 'f')
+ return; /* nothing to do more */
+
+ sprintf(query, "SELECT nextval ('%s');\n", tbinfo.relname);
+ fputs(query, fout);
}
-
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index a537a3ff6ba..b59e4d82997 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* pg_dump.h
- * header file for the pg_dump utility
+ * header file for the pg_dump utility
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_dump.h,v 1.19 1997/08/19 21:36:45 momjian Exp $
+ * $Id: pg_dump.h,v 1.20 1997/09/07 04:54:42 momjian Exp $
*
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
*
- * - Fixed dumpTable output to output lengths for char and varchar types!
- * - Added single. quote to twin single quote expansion for 'insert' string
- * mode.
+ * - Fixed dumpTable output to output lengths for char and varchar types!
+ * - Added single. quote to twin single quote expansion for 'insert' string
+ * mode.
*
* Modifications - 6/1/97 - igor@sba.miami.edu
* - Added extern's for the functions that clear allocated memory
- * in pg_dump.c
+ * in pg_dump.c
*-------------------------------------------------------------------------
*/
@@ -23,192 +23,218 @@
/* The *Info data structures run-time C structures used to store
system catalog information */
-
-typedef struct _typeInfo {
- char* oid;
- char* typowner;
- char* typname;
- char* typlen;
- char* typprtlen;
- char* typinput;
- char* typoutput;
- char* typreceive;
- char* typsend;
- char* typelem;
- char* typdelim;
- char* typdefault;
- char* typrelid;
- char* usename;
- int passedbyvalue;
- int isArray;
-} TypeInfo;
-
-typedef struct _funcInfo {
- char* oid;
- char* proname;
- char* proowner;
- int lang; /* 1 if C, else SQL */
- int nargs;
- char* argtypes[8]; /* should be derived from obj/fmgr.h instead of hardwired*/
- char* prorettype;
- int retset; /* 1 if the function returns a set, 0 otherwise */
- char* prosrc;
- char* probin;
- char* usename;
- int dumped; /* 1 if already dumped */
-} FuncInfo;
-
-typedef struct _tableInfo {
- char *oid;
- char *relname;
- char *relarch;
- char *relacl;
- bool sequence;
- int numatts; /* number of attributes */
- int *inhAttrs; /* an array of flags, one for each attribute
- if the value is 1, then this attribute is
- an inherited attribute */
- char **attnames; /* the attribute names */
- char **typnames; /* fill out attributes */
- bool *notnull; /* Not null constraints of an attribute */
- int numParents; /* number of (immediate) parent supertables */
- char **parentRels; /* names of parent relations, NULL
- if numParents == 0 */
- char **out_attnames; /* the attribute names, in the order they would
- be in, when the table is created in the
- target query language.
- this is needed because the SQL tables will
- not have the same order of attributes as
- the POSTQUEL tables */
- int *attlen; /* attribute lengths */
- char* usename;
-
-} TableInfo;
-
-typedef struct _inhInfo {
- char *inhrel;
- char *inhparent;
-} InhInfo;
-
-typedef struct _indInfo {
- char *indexrelname; /* name of the secondary index class */
- char *indrelname; /* name of the indexed heap class */
- char *indamname; /* name of the access method (e.g. btree, rtree, etc.) */
- char *indproc; /* oid of the function to compute the index, 0 if none*/
- char *indkey[INDEX_MAX_KEYS]; /* attribute numbers of the key attributes */
- char *indclass[INDEX_MAX_KEYS]; /* opclass of the keys */
- char *indisunique; /* is this index unique? */
-} IndInfo;
-
-typedef struct _aggInfo {
- char *oid;
- char *aggname;
- char *aggtransfn1;
- char *aggtransfn2;
- char *aggfinalfn;
- char *aggtranstype1;
- char *aggbasetype;
- char *aggtranstype2;
- char *agginitval1;
- char *agginitval2;
- char* usename;
-} AggInfo;
-
-typedef struct _oprInfo {
- char *oid;
- char *oprname;
- char *oprkind; /* "b" = binary, "l" = left unary, "r" = right unary */
- char *oprcode; /* operator function name */
- char *oprleft; /* left operand type */
- char *oprright; /* right operand type */
- char *oprcom; /* oid of the commutator operator */
- char *oprnegate; /* oid of the negator operator */
- char *oprrest; /* name of the function to calculate operator restriction
- selectivity */
- char *oprjoin; /* name of the function to calculate operator join
- selectivity */
- char *oprcanhash; /* can we use hash join strategy ? */
- char *oprlsortop; /* oid's of the left and right sort operators */
- char *oprrsortop;
- char* usename;
-} OprInfo;
+
+typedef struct _typeInfo
+{
+ char *oid;
+ char *typowner;
+ char *typname;
+ char *typlen;
+ char *typprtlen;
+ char *typinput;
+ char *typoutput;
+ char *typreceive;
+ char *typsend;
+ char *typelem;
+ char *typdelim;
+ char *typdefault;
+ char *typrelid;
+ char *usename;
+ int passedbyvalue;
+ int isArray;
+} TypeInfo;
+
+typedef struct _funcInfo
+{
+ char *oid;
+ char *proname;
+ char *proowner;
+ int lang; /* 1 if C, else SQL */
+ int nargs;
+ char *argtypes[8];/* should be derived from obj/fmgr.h
+ * instead of hardwired */
+ char *prorettype;
+ int retset; /* 1 if the function returns a set, 0
+ * otherwise */
+ char *prosrc;
+ char *probin;
+ char *usename;
+ int dumped; /* 1 if already dumped */
+} FuncInfo;
+
+typedef struct _tableInfo
+{
+ char *oid;
+ char *relname;
+ char *relarch;
+ char *relacl;
+ bool sequence;
+ int numatts; /* number of attributes */
+ int *inhAttrs; /* an array of flags, one for each
+ * attribute if the value is 1, then this
+ * attribute is an inherited attribute */
+ char **attnames; /* the attribute names */
+ char **typnames; /* fill out attributes */
+ bool *notnull; /* Not null constraints of an attribute */
+ int numParents; /* number of (immediate) parent
+ * supertables */
+ char **parentRels; /* names of parent relations, NULL if
+ * numParents == 0 */
+ char **out_attnames; /* the attribute names, in the
+ * order they would be in, when
+ * the table is created in the
+ * target query language. this is
+ * needed because the SQL tables
+ * will not have the same order of
+ * attributes as the POSTQUEL
+ * tables */
+ int *attlen; /* attribute lengths */
+ char *usename;
+
+} TableInfo;
+
+typedef struct _inhInfo
+{
+ char *inhrel;
+ char *inhparent;
+} InhInfo;
+
+typedef struct _indInfo
+{
+ char *indexrelname; /* name of the secondary index
+ * class */
+ char *indrelname; /* name of the indexed heap class */
+ char *indamname; /* name of the access method (e.g. btree,
+ * rtree, etc.) */
+ char *indproc; /* oid of the function to compute the
+ * index, 0 if none */
+ char *indkey[INDEX_MAX_KEYS]; /* attribute numbers of
+ * the key attributes */
+ char *indclass[INDEX_MAX_KEYS]; /* opclass of the keys */
+ char *indisunique;/* is this index unique? */
+} IndInfo;
+
+typedef struct _aggInfo
+{
+ char *oid;
+ char *aggname;
+ char *aggtransfn1;
+ char *aggtransfn2;
+ char *aggfinalfn;
+ char *aggtranstype1;
+ char *aggbasetype;
+ char *aggtranstype2;
+ char *agginitval1;
+ char *agginitval2;
+ char *usename;
+} AggInfo;
+
+typedef struct _oprInfo
+{
+ char *oid;
+ char *oprname;
+ char *oprkind; /* "b" = binary, "l" = left unary, "r" =
+ * right unary */
+ char *oprcode; /* operator function name */
+ char *oprleft; /* left operand type */
+ char *oprright; /* right operand type */
+ char *oprcom; /* oid of the commutator operator */
+ char *oprnegate; /* oid of the negator operator */
+ char *oprrest; /* name of the function to calculate
+ * operator restriction selectivity */
+ char *oprjoin; /* name of the function to calculate
+ * operator join selectivity */
+ char *oprcanhash; /* can we use hash join strategy ? */
+ char *oprlsortop; /* oid's of the left and right sort
+ * operators */
+ char *oprrsortop;
+ char *usename;
+} OprInfo;
/* global decls */
-extern bool g_verbose; /* verbose flag */
-extern int g_last_builtin_oid; /* value of the last builtin oid */
-extern FILE *g_fout; /* the script file */
+extern bool g_verbose; /* verbose flag */
+extern int g_last_builtin_oid; /* value of the last builtin oid */
+extern FILE *g_fout; /* the script file */
/* placeholders for comment starting and ending delimiters */
-extern char g_comment_start[10];
-extern char g_comment_end[10];
+extern char g_comment_start[10];
+extern char g_comment_end[10];
-extern char g_opaque_type[10]; /* name for the opaque type */
+extern char g_opaque_type[10]; /* name for the opaque type */
/* pg_dump is really two programs in one
- one version works with postgres v4r2
- and the other works with postgres95
- the common routines are declared here
+ one version works with postgres v4r2
+ and the other works with postgres95
+ the common routines are declared here
*/
/*
- * common utility functions
+ * common utility functions
*/
-extern TableInfo* dumpSchema(FILE* fout,
- int *numTablesPtr,
- const char *tablename,
- const bool acls);
-extern void dumpSchemaIdx(FILE* fout,
- int *numTablesPtr,
+extern TableInfo *
+dumpSchema(FILE * fout,
+ int *numTablesPtr,
+ const char *tablename,
+ const bool acls);
+extern void
+dumpSchemaIdx(FILE * fout,
+ int *numTablesPtr,
const char *tablename,
- TableInfo* tblinfo,
+ TableInfo * tblinfo,
int numTables);
-extern char* findTypeByOid(TypeInfo* tinfo, int numTypes, const char* oid);
-extern char* findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid);
-extern int findFuncByName(FuncInfo* finfo, int numFuncs, const char* name);
-extern int findTableByName(TableInfo *tbinfo, int numTables, const char *relname);
+extern char *findTypeByOid(TypeInfo * tinfo, int numTypes, const char *oid);
+extern char *findOprByOid(OprInfo * oprinfo, int numOprs, const char *oid);
+extern int findFuncByName(FuncInfo * finfo, int numFuncs, const char *name);
+extern int findTableByName(TableInfo * tbinfo, int numTables, const char *relname);
-extern void check_conn_and_db(void);
-extern void parseArgTypes(char **argtypes, const char* str);
-extern int isArchiveName(const char*);
+extern void check_conn_and_db(void);
+extern void parseArgTypes(char **argtypes, const char *str);
+extern int isArchiveName(const char *);
/*
- * version specific routines
+ * version specific routines
*/
-extern TypeInfo* getTypes(int *numTypes);
-extern FuncInfo* getFuncs(int *numFuncs);
-extern AggInfo* getAggregates(int *numAggregates);
-
-extern void clearAggInfo(AggInfo*, int);
-extern void clearFuncInfo(FuncInfo*, int);
-extern void clearInhInfo(InhInfo*, int);
-extern void clearIndInfo(IndInfo*, int);
-extern void clearOprInfo(OprInfo*, int);
-extern void clearTypeInfo(TypeInfo*, int);
-
-extern OprInfo* getOperators(int *numOperators);
-extern TableInfo* getTables(int *numTables);
-extern InhInfo* getInherits(int *numInherits);
-extern void getTableAttrs(TableInfo* tbinfo, int numTables);
-extern IndInfo* getIndices(int *numIndices);
-extern void dumpTypes(FILE* fout, FuncInfo* finfo, int numFuncs,
- TypeInfo* tinfo, int numTypes);
-extern void dumpFuncs(FILE* fout, FuncInfo* finfo, int numFuncs,
- TypeInfo *tinfo, int numTypes);
-extern void dumpAggs(FILE* fout, AggInfo* agginfo, int numAggregates,
- TypeInfo *tinfo, int numTypes);
-extern void dumpOprs(FILE* fout, OprInfo* agginfo, int numOperators,
- TypeInfo *tinfo, int numTypes);
-extern void dumpTables(FILE* fout, TableInfo* tbinfo, int numTables,
- InhInfo *inhinfo, int numInherits,
- TypeInfo *tinfo, int numTypes, const char *tablename,
- const bool acls);
-extern void dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices,
- TableInfo* tbinfo, int numTables, const char *tablename);
+extern TypeInfo *getTypes(int *numTypes);
+extern FuncInfo *getFuncs(int *numFuncs);
+extern AggInfo *getAggregates(int *numAggregates);
+
+extern void clearAggInfo(AggInfo *, int);
+extern void clearFuncInfo(FuncInfo *, int);
+extern void clearInhInfo(InhInfo *, int);
+extern void clearIndInfo(IndInfo *, int);
+extern void clearOprInfo(OprInfo *, int);
+extern void clearTypeInfo(TypeInfo *, int);
+
+extern OprInfo *getOperators(int *numOperators);
+extern TableInfo *getTables(int *numTables);
+extern InhInfo *getInherits(int *numInherits);
+extern void getTableAttrs(TableInfo * tbinfo, int numTables);
+extern IndInfo *getIndices(int *numIndices);
+extern void
+dumpTypes(FILE * fout, FuncInfo * finfo, int numFuncs,
+ TypeInfo * tinfo, int numTypes);
+extern void
+dumpFuncs(FILE * fout, FuncInfo * finfo, int numFuncs,
+ TypeInfo * tinfo, int numTypes);
+extern void
+dumpAggs(FILE * fout, AggInfo * agginfo, int numAggregates,
+ TypeInfo * tinfo, int numTypes);
+extern void
+dumpOprs(FILE * fout, OprInfo * agginfo, int numOperators,
+ TypeInfo * tinfo, int numTypes);
+extern void
+dumpTables(FILE * fout, TableInfo * tbinfo, int numTables,
+ InhInfo * inhinfo, int numInherits,
+ TypeInfo * tinfo, int numTypes, const char *tablename,
+ const bool acls);
+extern void
+dumpIndices(FILE * fout, IndInfo * indinfo, int numIndices,
+ TableInfo * tbinfo, int numTables, const char *tablename);
/* largest query string size */
#define MAXQUERYLEN 5000
/* these voodoo constants are from the backend */
-#define C_PROLANG_OID 13
+#define C_PROLANG_OID 13
diff --git a/src/bin/pg_id/pg_id.c b/src/bin/pg_id/pg_id.c
index 4364fc1cf29..b782b091a3e 100644
--- a/src/bin/pg_id/pg_id.c
+++ b/src/bin/pg_id/pg_id.c
@@ -1,15 +1,15 @@
/*-------------------------------------------------------------------------
*
* pg_id.c--
- * Print the user ID for the login name passed as argument,
- * or the real user ID of the caller if no argument. If the
- * login name doesn't exist, print "NOUSER" and exit 1.
+ * Print the user ID for the login name passed as argument,
+ * or the real user ID of the caller if no argument. If the
+ * login name doesn't exist, print "NOUSER" and exit 1.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_id/Attic/pg_id.c,v 1.3 1996/11/08 06:01:12 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_id/Attic/pg_id.c,v 1.4 1997/09/07 04:54:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,33 +23,39 @@
int
main(int argc, char **argv)
{
- struct passwd *pw;
- int ch;
- extern int optind;
+ struct passwd *pw;
+ int ch;
+ extern int optind;
- while ((ch = getopt(argc, argv, "")) != EOF)
- switch (ch) {
- case '?':
- default:
- fprintf(stderr, "usage: pg_id [login]\n");
- exit(1);
- }
- argc -= optind;
- argv += optind;
+ while ((ch = getopt(argc, argv, "")) != EOF)
+ switch (ch)
+ {
+ case '?':
+ default:
+ fprintf(stderr, "usage: pg_id [login]\n");
+ exit(1);
+ }
+ argc -= optind;
+ argv += optind;
- if (argc > 0) {
- if (argc > 1) {
- fprintf(stderr, "usage: pg_id [login]\n");
- exit(1);
+ if (argc > 0)
+ {
+ if (argc > 1)
+ {
+ fprintf(stderr, "usage: pg_id [login]\n");
+ exit(1);
+ }
+ if ((pw = getpwnam(argv[0])) == NULL)
+ {
+ printf("NOUSER\n");
+ exit(1);
+ }
+ printf("%ld\n", (long) pw->pw_uid);
}
- if ((pw = getpwnam(argv[0])) == NULL) {
- printf("NOUSER\n");
- exit(1);
+ else
+ {
+ printf("%ld\n", (long) getuid());
}
- printf("%ld\n", (long)pw->pw_uid);
- } else {
- printf("%ld\n", (long)getuid());
- }
- exit(0);
+ exit(0);
}
diff --git a/src/bin/pg_passwd/pg_passwd.c b/src/bin/pg_passwd/pg_passwd.c
index c1e752a586f..9a99b45b69e 100644
--- a/src/bin/pg_passwd/pg_passwd.c
+++ b/src/bin/pg_passwd/pg_passwd.c
@@ -1,5 +1,5 @@
/*
- * @(#) pg_passwd.c 1.8 09:13:16 97/07/02 Y. Ichikawa
+ * @(#) pg_passwd.c 1.8 09:13:16 97/07/02 Y. Ichikawa
*/
#include <stdio.h>
@@ -19,309 +19,364 @@
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#else
-extern char *crypt(const char *, const char *);
-#endif
+extern char *crypt(const char *, const char *);
-char *comname;
-void usage(FILE *stream);
-void read_pwd_file(char *filename);
-void write_pwd_file(char *filename, char *bkname);
-void encrypt_pwd(char key[9], char salt[3], char passwd[14]);
-int check_pwd(char key[9], char passwd[14]);
-void prompt_for_username(char *username);
-void prompt_for_password(char *prompt, char *password);
+#endif
-void usage(FILE *stream)
+char *comname;
+void usage(FILE * stream);
+void read_pwd_file(char *filename);
+void write_pwd_file(char *filename, char *bkname);
+void encrypt_pwd(char key[9], char salt[3], char passwd[14]);
+int check_pwd(char key[9], char passwd[14]);
+void prompt_for_username(char *username);
+void prompt_for_password(char *prompt, char *password);
+
+void
+usage(FILE * stream)
{
fprintf(stream, "Usage: %s <password file>\n", comname);
}
-typedef struct {
- char *uname;
- char *pwd;
- char *rest;
-} pg_pwd;
+typedef struct
+{
+ char *uname;
+ char *pwd;
+ char *rest;
+} pg_pwd;
-#define MAXPWDS 1024
+#define MAXPWDS 1024
-pg_pwd pwds[MAXPWDS];
-int npwds = 0;
+pg_pwd pwds[MAXPWDS];
+int npwds = 0;
-void read_pwd_file(char *filename)
+void
+read_pwd_file(char *filename)
{
- FILE *fp;
- static char line[512];
- static char ans[128];
- int i;
-
- try_again:
- fp = fopen(filename, "r");
- if (fp == NULL) {
- if (errno == ENOENT) {
- printf("File \"%s\" does not exist. Create? (y/n): ", filename);
- fflush(stdout);
- fgets(ans, 128, stdin);
- switch (ans[0]) {
- case 'y': case 'Y':
- fp = fopen(filename, "w");
- if (fp == NULL) {
- perror(filename);
- exit(1);
+ FILE *fp;
+ static char line[512];
+ static char ans[128];
+ int i;
+
+try_again:
+ fp = fopen(filename, "r");
+ if (fp == NULL)
+ {
+ if (errno == ENOENT)
+ {
+ printf("File \"%s\" does not exist. Create? (y/n): ", filename);
+ fflush(stdout);
+ fgets(ans, 128, stdin);
+ switch (ans[0])
+ {
+ case 'y':
+ case 'Y':
+ fp = fopen(filename, "w");
+ if (fp == NULL)
+ {
+ perror(filename);
+ exit(1);
+ }
+ fclose(fp);
+ goto try_again;
+ default:
+ /* cannot continue */
+ exit(1);
+ }
+ }
+ else
+ {
+ perror(filename);
+ exit(1);
}
- fclose(fp);
- goto try_again;
- default:
- /* cannot continue */
- exit(1);
- }
- } else {
- perror(filename);
- exit(1);
- }
- }
-
- /* read all the entries */
- for (npwds = 0; npwds < MAXPWDS && fgets(line, 512, fp) != NULL; ++npwds) {
- int l;
- char *p, *q;
- l = strlen(line);
- if (line[l-1] == '\n')
- line[l-1] = '\0';
- else { /* too long */
- fprintf(stderr, "%s: line %d: line too long.\n",
- filename, npwds + 1);
- exit(1);
}
- /* get user name */
- p = line;
- if ((q = index(p, ':')) == NULL) {
- fprintf(stderr, "%s: line %d: illegal format.\n",
- filename, npwds + 1);
- exit(1);
- }
- *(q++) = '\0';
- if (strlen(p) == 0) {
- fprintf(stderr, "%s: line %d: null user name.\n",
- filename, npwds + 1);
- exit(1);
+ /* read all the entries */
+ for (npwds = 0; npwds < MAXPWDS && fgets(line, 512, fp) != NULL; ++npwds)
+ {
+ int l;
+ char *p,
+ *q;
+
+ l = strlen(line);
+ if (line[l - 1] == '\n')
+ line[l - 1] = '\0';
+ else
+ { /* too long */
+ fprintf(stderr, "%s: line %d: line too long.\n",
+ filename, npwds + 1);
+ exit(1);
+ }
+
+ /* get user name */
+ p = line;
+ if ((q = index(p, ':')) == NULL)
+ {
+ fprintf(stderr, "%s: line %d: illegal format.\n",
+ filename, npwds + 1);
+ exit(1);
+ }
+ *(q++) = '\0';
+ if (strlen(p) == 0)
+ {
+ fprintf(stderr, "%s: line %d: null user name.\n",
+ filename, npwds + 1);
+ exit(1);
+ }
+ pwds[npwds].uname = strdup(p);
+
+ /* check duplicate */
+ for (i = 0; i < npwds; ++i)
+ {
+ if (strcmp(pwds[i].uname, pwds[npwds].uname) == 0)
+ {
+ fprintf(stderr, "%s: duplicated entry.\n", pwds[npwds].uname);
+ exit(1);
+ }
+ }
+
+ /* get password field */
+ p = q;
+ q = index(p, ':');
+
+ /*
+ * --- don't care ----- if ((q = index(p, ':')) == NULL) {
+ * fprintf(stderr, "%s: line %d: illegal format.\n", filename,
+ * npwds + 1); exit(1); }
+ */
+
+ if (q != NULL)
+ *(q++) = '\0';
+ if (strlen(p) != 13)
+ {
+ fprintf(stderr, "WARNING: %s: line %d: illegal password length.\n",
+ filename, npwds + 1);
+ }
+ pwds[npwds].pwd = strdup(p);
+
+ /* rest of the line is treated as is */
+ if (q == NULL)
+ pwds[npwds].rest = NULL;
+ else
+ pwds[npwds].rest = strdup(q);
}
- pwds[npwds].uname = strdup(p);
- /* check duplicate */
- for (i = 0; i < npwds; ++i) {
- if (strcmp(pwds[i].uname, pwds[npwds].uname) == 0) {
- fprintf(stderr, "%s: duplicated entry.\n", pwds[npwds].uname);
+ fclose(fp);
+}
+
+void
+write_pwd_file(char *filename, char *bkname)
+{
+ FILE *fp;
+ int i;
+
+ /* make the backup file */
+link_again:
+ if (link(filename, bkname))
+ {
+ if (errno == EEXIST)
+ {
+ unlink(bkname);
+ goto link_again;
+ }
+ perror(bkname);
exit(1);
- }
}
-
- /* get password field */
- p = q;
- q = index(p, ':');
- /*
- * --- don't care -----
- if ((q = index(p, ':')) == NULL) {
- fprintf(stderr, "%s: line %d: illegal format.\n",
- filename, npwds + 1);
- exit(1);
+ if (unlink(filename))
+ {
+ perror(filename);
+ exit(1);
}
- */
- if (q != NULL) *(q++) = '\0';
- if (strlen(p) != 13) {
- fprintf(stderr, "WARNING: %s: line %d: illegal password length.\n",
- filename, npwds + 1);
+ /* open file */
+ if ((fp = fopen(filename, "w")) == NULL)
+ {
+ perror(filename);
+ exit(1);
}
- pwds[npwds].pwd = strdup(p);
- /* rest of the line is treated as is */
- if (q == NULL)
- pwds[npwds].rest = NULL;
- else
- pwds[npwds].rest = strdup(q);
- }
+ /* write file */
+ for (i = 0; i < npwds; ++i)
+ {
+ fprintf(fp, "%s:%s%s%s\n", pwds[i].uname, pwds[i].pwd,
+ pwds[i].rest ? ":" : "",
+ pwds[i].rest ? pwds[i].rest : "");
+ }
- fclose(fp);
+ fclose(fp);
}
-void write_pwd_file(char *filename, char *bkname)
+void
+encrypt_pwd(char key[9], char salt[3], char passwd[14])
{
- FILE* fp;
- int i;
-
- /* make the backup file */
- link_again:
- if (link(filename, bkname)) {
- if (errno == EEXIST) {
- unlink(bkname);
- goto link_again;
+ int n;
+
+ /* get encrypted password */
+ if (salt[0] == '\0')
+ {
+ struct timeval tm;
+
+ gettimeofday(&tm, NULL);
+ srand(tm.tv_sec ? tm.tv_sec : 1);
+ do
+ {
+ n = rand() % 256;
+ } while (!issaltchar(n));
+ salt[0] = n;
+ do
+ {
+ n = rand() % 256;
+ } while (!issaltchar(n));
+ salt[1] = n;
+ salt[2] = '\0';
}
- perror(bkname);
- exit(1);
- }
- if (unlink(filename)) {
- perror(filename);
- exit(1);
- }
-
- /* open file */
- if ((fp = fopen(filename, "w")) == NULL) {
- perror(filename);
- exit(1);
- }
-
- /* write file */
- for (i = 0; i < npwds; ++i) {
- fprintf(fp, "%s:%s%s%s\n", pwds[i].uname, pwds[i].pwd,
- pwds[i].rest ? ":" : "",
- pwds[i].rest ? pwds[i].rest : "");
- }
-
- fclose(fp);
+ strcpy(passwd, crypt(key, salt));
+
+ /* show it */
+
+ /*
+ * fprintf(stderr, "key = %s, salt = %s, password = %s\n", key, salt,
+ * passwd);
+ */
}
-void encrypt_pwd(char key[9], char salt[3], char passwd[14])
+int
+check_pwd(char key[9], char passwd[14])
{
- int n;
-
- /* get encrypted password */
- if (salt[0] == '\0') {
- struct timeval tm;
- gettimeofday(&tm, NULL);
- srand(tm.tv_sec ? tm.tv_sec : 1);
- do {
- n = rand() % 256;
- } while (! issaltchar(n));
- salt[0] = n;
- do {
- n = rand() % 256;
- } while (! issaltchar(n));
- salt[1] = n;
+ char shouldbe[14];
+ char salt[3];
+
+ salt[0] = passwd[0];
+ salt[1] = passwd[1];
salt[2] = '\0';
- }
- strcpy(passwd, crypt(key, salt));
+ encrypt_pwd(key, salt, shouldbe);
- /* show it */
- /* fprintf(stderr, "key = %s, salt = %s, password = %s\n",
- key, salt, passwd); */
+ return strncmp(shouldbe, passwd, 13) == 0 ? 1 : 0;
}
-int check_pwd(char key[9], char passwd[14])
+void
+prompt_for_username(char *username)
{
- char shouldbe[14];
- char salt[3];
+ int length;
- salt[0] = passwd[0];
- salt[1] = passwd[1];
- salt[2] = '\0';
- encrypt_pwd(key, salt, shouldbe);
+ printf("Username: ");
+ fgets(username, 9, stdin);
+ length = strlen(username);
- return strncmp(shouldbe, passwd, 13) == 0 ? 1 : 0;
-}
+ /* skip rest of the line */
+ if (length > 0 && username[length - 1] != '\n')
+ {
+ static char buf[512];
-void prompt_for_username(char *username)
-{
- int length;
-
- printf("Username: ");
- fgets(username, 9, stdin);
- length = strlen(username);
-
- /* skip rest of the line */
- if (length > 0 && username[length-1] != '\n') {
- static char buf[512];
- do {
- fgets(buf, 512, stdin);
- } while (buf[strlen(buf)-1] != '\n');
- }
- if(length > 0 && username[length-1] == '\n') username[length-1] = '\0';
+ do
+ {
+ fgets(buf, 512, stdin);
+ } while (buf[strlen(buf) - 1] != '\n');
+ }
+ if (length > 0 && username[length - 1] == '\n')
+ username[length - 1] = '\0';
}
-void prompt_for_password(char *prompt, char *password)
+void
+prompt_for_password(char *prompt, char *password)
{
- int length;
+ int length;
+
#ifdef HAVE_TERMIOS_H
- struct termios t_orig, t;
+ struct termios t_orig,
+ t;
+
#endif
- printf(prompt);
+ printf(prompt);
#ifdef HAVE_TERMIOS_H
- tcgetattr(0, &t);
- t_orig = t;
- t.c_lflag &= ~ECHO;
- tcsetattr(0, TCSADRAIN, &t);
+ tcgetattr(0, &t);
+ t_orig = t;
+ t.c_lflag &= ~ECHO;
+ tcsetattr(0, TCSADRAIN, &t);
#endif
- fgets(password, 9, stdin);
+ fgets(password, 9, stdin);
#ifdef HAVE_TERMIOS_H
- tcsetattr(0, TCSADRAIN, &t_orig);
+ tcsetattr(0, TCSADRAIN, &t_orig);
#endif
- length = strlen(password);
- /* skip rest of the line */
- if (length > 0 && password[length-1] != '\n') {
- static char buf[512];
- do {
- fgets(buf, 512, stdin);
- } while (buf[strlen(buf)-1] != '\n');
- }
- if(length > 0 && password[length-1] == '\n') password[length-1] = '\0';
- printf("\n");
+ length = strlen(password);
+ /* skip rest of the line */
+ if (length > 0 && password[length - 1] != '\n')
+ {
+ static char buf[512];
+
+ do
+ {
+ fgets(buf, 512, stdin);
+ } while (buf[strlen(buf) - 1] != '\n');
+ }
+ if (length > 0 && password[length - 1] == '\n')
+ password[length - 1] = '\0';
+ printf("\n");
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- static char bkname[512];
- char username[9];
- char salt[3];
- char key[9], key2[9];
- char e_passwd[14];
- int i;
-
- comname = argv[0];
- if (argc != 2) {
- usage(stderr);
- exit(1);
- }
-
-
- /* open file */
- read_pwd_file(argv[1]);
-
- /* ask for the user name and the password */
- prompt_for_username(username);
- prompt_for_password("New password: ", key);
- prompt_for_password("Re-enter new password: ", key2);
- if (strncmp(key, key2, 8) != 0) {
- fprintf(stderr, "Password mismatch.\n");
- exit(1);
- }
- salt[0] = '\0';
- encrypt_pwd(key, salt, e_passwd);
-
- /* check password entry */
- for (i = 0; i < npwds; ++i) {
- if (strcmp(pwds[i].uname, username) == 0) { /* found */
- pwds[i].pwd = strdup(e_passwd);
- break;
+ static char bkname[512];
+ char username[9];
+ char salt[3];
+ char key[9],
+ key2[9];
+ char e_passwd[14];
+ int i;
+
+ comname = argv[0];
+ if (argc != 2)
+ {
+ usage(stderr);
+ exit(1);
}
- }
- if (i == npwds) { /* did not exist */
- if (npwds == MAXPWDS) {
- fprintf(stderr, "%s: cannot handle so may entries.\n", comname);
- exit(1);
+
+
+ /* open file */
+ read_pwd_file(argv[1]);
+
+ /* ask for the user name and the password */
+ prompt_for_username(username);
+ prompt_for_password("New password: ", key);
+ prompt_for_password("Re-enter new password: ", key2);
+ if (strncmp(key, key2, 8) != 0)
+ {
+ fprintf(stderr, "Password mismatch.\n");
+ exit(1);
+ }
+ salt[0] = '\0';
+ encrypt_pwd(key, salt, e_passwd);
+
+ /* check password entry */
+ for (i = 0; i < npwds; ++i)
+ {
+ if (strcmp(pwds[i].uname, username) == 0)
+ { /* found */
+ pwds[i].pwd = strdup(e_passwd);
+ break;
+ }
+ }
+ if (i == npwds)
+ { /* did not exist */
+ if (npwds == MAXPWDS)
+ {
+ fprintf(stderr, "%s: cannot handle so may entries.\n", comname);
+ exit(1);
+ }
+ pwds[npwds].uname = strdup(username);
+ pwds[npwds].pwd = strdup(e_passwd);
+ pwds[npwds].rest = NULL;
+ ++npwds;
}
- pwds[npwds].uname = strdup(username);
- pwds[npwds].pwd = strdup(e_passwd);
- pwds[npwds].rest = NULL;
- ++npwds;
- }
- /* write back the file */
- sprintf(bkname, "%s.bk", argv[1]);
- write_pwd_file(argv[1], bkname);
+ /* write back the file */
+ sprintf(bkname, "%s.bk", argv[1]);
+ write_pwd_file(argv[1], bkname);
- return 0;
+ return 0;
}
diff --git a/src/bin/pg_version/pg_version.c b/src/bin/pg_version/pg_version.c
index 5cdf3cad5d0..314ddddeb2d 100644
--- a/src/bin/pg_version/pg_version.c
+++ b/src/bin/pg_version/pg_version.c
@@ -1,40 +1,45 @@
/*-------------------------------------------------------------------------
*
* pg_version.c--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_version/Attic/pg_version.c,v 1.6 1996/11/12 06:47:00 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_version/Attic/pg_version.c,v 1.7 1997/09/07 04:54:56 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
-#include <version.h> /* interface to SetPgVersion */
+#include <version.h> /* interface to SetPgVersion */
int
main(int argc, char **argv)
{
- int retcode; /* our eventual return code */
- char *reason; /* Reason that SetPgVersion failed, NULL if it didn't. */
+ int retcode; /* our eventual return code */
+ char *reason; /* Reason that SetPgVersion failed, NULL
+ * if it didn't. */
- if (argc < 2) {
- fprintf(stderr, "pg_version: missing argument\n");
- exit(1);
- }
- SetPgVersion(argv[1], &reason);
- if (reason) {
- fprintf(stderr,
- "pg_version is unable to create the PG_VERSION file. "
- "SetPgVersion gave this reason: %s\n",
- reason);
- retcode = 10;
- } else retcode = 0;
- return(retcode);
+ if (argc < 2)
+ {
+ fprintf(stderr, "pg_version: missing argument\n");
+ exit(1);
+ }
+ SetPgVersion(argv[1], &reason);
+ if (reason)
+ {
+ fprintf(stderr,
+ "pg_version is unable to create the PG_VERSION file. "
+ "SetPgVersion gave this reason: %s\n",
+ reason);
+ retcode = 10;
+ }
+ else
+ retcode = 0;
+ return (retcode);
}
diff --git a/src/bin/pgtclsh/pgtclAppInit.c b/src/bin/pgtclsh/pgtclAppInit.c
index b44a46f6811..1c9040fbd53 100644
--- a/src/bin/pgtclsh/pgtclAppInit.c
+++ b/src/bin/pgtclsh/pgtclAppInit.c
@@ -1,8 +1,8 @@
-/*
+/*
* pgtclAppInit.c --
*
- * a skeletal Tcl_AppInit that provides pgtcl initialization
- * to create a tclsh that can talk to pglite backends
+ * a skeletal Tcl_AppInit that provides pgtcl initialization
+ * to create a tclsh that can talk to pglite backends
*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
@@ -21,23 +21,25 @@
*/
#ifdef NEED_MATHERR
-extern int matherr();
-int *tclDummyMathPtr = (int *) matherr;
+extern int matherr();
+int *tclDummyMathPtr = (int *) matherr;
+
#endif
-
+
+
/*
*----------------------------------------------------------------------
*
* main --
*
- * This is the main program for the application.
+ * This is the main program for the application.
*
* Results:
- * None: Tcl_Main never returns here, so this procedure never
- * returns either.
+ * None: Tcl_Main never returns here, so this procedure never
+ * returns either.
*
* Side effects:
- * Whatever the application does.
+ * Whatever the application does.
*
*----------------------------------------------------------------------
*/
@@ -45,68 +47,71 @@ int *tclDummyMathPtr = (int *) matherr;
int
main(int argc, char **argv)
{
- Tcl_Main(argc, argv, Tcl_AppInit);
- return 0; /* Needed only to prevent compiler warning. */
+ Tcl_Main(argc, argv, Tcl_AppInit);
+ return 0; /* Needed only to prevent compiler
+ * warning. */
}
-
+
+
/*
*----------------------------------------------------------------------
*
* Tcl_AppInit --
*
- * This procedure performs application-specific initialization.
- * Most applications, especially those that incorporate additional
- * packages, will have their own version of this procedure.
+ * This procedure performs application-specific initialization.
+ * Most applications, especially those that incorporate additional
+ * packages, will have their own version of this procedure.
*
* Results:
- * Returns a standard Tcl completion code, and leaves an error
- * message in interp->result if an error occurs.
+ * Returns a standard Tcl completion code, and leaves an error
+ * message in interp->result if an error occurs.
*
* Side effects:
- * Depends on the startup script.
+ * Depends on the startup script.
*
*----------------------------------------------------------------------
*/
int
-Tcl_AppInit(Tcl_Interp *interp)
+Tcl_AppInit(Tcl_Interp * interp)
{
- if (Tcl_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
-
- /*
- * Call the init procedures for included packages. Each call should
- * look like this:
- *
- * if (Mod_Init(interp) == TCL_ERROR) {
- * return TCL_ERROR;
- * }
- *
- * where "Mod" is the name of the module.
- */
-
- if (Pgtcl_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
-
- /*
- * Call Tcl_CreateCommand for application-specific commands, if
- * they weren't already created by the init procedures called above.
- */
-
- /*
- * Specify a user-specific startup file to invoke if the application
- * is run interactively. Typically the startup file is "~/.apprc"
- * where "app" is the name of the application. If this line is deleted
- * then no user-specific startup file will be run under any conditions.
- */
+ if (Tcl_Init(interp) == TCL_ERROR)
+ {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Call the init procedures for included packages. Each call should
+ * look like this:
+ *
+ * if (Mod_Init(interp) == TCL_ERROR) { return TCL_ERROR; }
+ *
+ * where "Mod" is the name of the module.
+ */
+
+ if (Pgtcl_Init(interp) == TCL_ERROR)
+ {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if they
+ * weren't already created by the init procedures called above.
+ */
+
+ /*
+ * Specify a user-specific startup file to invoke if the application
+ * is run interactively. Typically the startup file is "~/.apprc"
+ * where "app" is the name of the application. If this line is
+ * deleted then no user-specific startup file will be run under any
+ * conditions.
+ */
#if (TCL_MAJOR_VERSION <= 7) && (TCL_MINOR_VERSION < 5)
- tcl_RcFileName = "~/.tclshrc";
+ tcl_RcFileName = "~/.tclshrc";
#else
- Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY);
+ Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY);
#endif
- return TCL_OK;
+ return TCL_OK;
}
diff --git a/src/bin/pgtclsh/pgtkAppInit.c b/src/bin/pgtclsh/pgtkAppInit.c
index 5be20ec589c..fbca4cca2e5 100644
--- a/src/bin/pgtclsh/pgtkAppInit.c
+++ b/src/bin/pgtclsh/pgtkAppInit.c
@@ -1,8 +1,8 @@
-/*
+/*
* pgtkAppInit.c --
*
- * a skeletal Tcl_AppInit that provides pgtcl initialization
- * to create a tclsh that can talk to pglite backends
+ * a skeletal Tcl_AppInit that provides pgtcl initialization
+ * to create a tclsh that can talk to pglite backends
*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
@@ -20,23 +20,25 @@
*/
#ifdef NEED_MATHERR
-extern int matherr();
-int *tclDummyMathPtr = (int *) matherr;
+extern int matherr();
+int *tclDummyMathPtr = (int *) matherr;
+
#endif
-
+
+
/*
*----------------------------------------------------------------------
*
* main --
*
- * This is the main program for the application.
+ * This is the main program for the application.
*
* Results:
- * None: Tk_Main never returns here, so this procedure never
- * returns either.
+ * None: Tk_Main never returns here, so this procedure never
+ * returns either.
*
* Side effects:
- * Whatever the application does.
+ * Whatever the application does.
*
*----------------------------------------------------------------------
*/
@@ -44,70 +46,75 @@ int *tclDummyMathPtr = (int *) matherr;
int
main(int argc, char **argv)
{
- Tk_Main(argc, argv, Tcl_AppInit);
- return 0; /* Needed only to prevent compiler warning. */
+ Tk_Main(argc, argv, Tcl_AppInit);
+ return 0; /* Needed only to prevent compiler
+ * warning. */
}
-
+
+
/*
*----------------------------------------------------------------------
*
* Tcl_AppInit --
*
- * This procedure performs application-specific initialization.
- * Most applications, especially those that incorporate additional
- * packages, will have their own version of this procedure.
+ * This procedure performs application-specific initialization.
+ * Most applications, especially those that incorporate additional
+ * packages, will have their own version of this procedure.
*
* Results:
- * Returns a standard Tcl completion code, and leaves an error
- * message in interp->result if an error occurs.
+ * Returns a standard Tcl completion code, and leaves an error
+ * message in interp->result if an error occurs.
*
* Side effects:
- * Depends on the startup script.
+ * Depends on the startup script.
*
*----------------------------------------------------------------------
*/
int
-Tcl_AppInit(Tcl_Interp *interp)
+Tcl_AppInit(Tcl_Interp * interp)
{
- if (Tcl_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
- if (Tk_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
-
- /*
- * Call the init procedures for included packages. Each call should
- * look like this:
- *
- * if (Mod_Init(interp) == TCL_ERROR) {
- * return TCL_ERROR;
- * }
- *
- * where "Mod" is the name of the module.
- */
-
- if (Pgtcl_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
- /*
- * Call Tcl_CreateCommand for application-specific commands, if
- * they weren't already created by the init procedures called above.
- */
-
- /*
- * Specify a user-specific startup file to invoke if the application
- * is run interactively. Typically the startup file is "~/.apprc"
- * where "app" is the name of the application. If this line is deleted
- * then no user-specific startup file will be run under any conditions.
- */
+ if (Tcl_Init(interp) == TCL_ERROR)
+ {
+ return TCL_ERROR;
+ }
+ if (Tk_Init(interp) == TCL_ERROR)
+ {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Call the init procedures for included packages. Each call should
+ * look like this:
+ *
+ * if (Mod_Init(interp) == TCL_ERROR) { return TCL_ERROR; }
+ *
+ * where "Mod" is the name of the module.
+ */
+
+ if (Pgtcl_Init(interp) == TCL_ERROR)
+ {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if they
+ * weren't already created by the init procedures called above.
+ */
+
+ /*
+ * Specify a user-specific startup file to invoke if the application
+ * is run interactively. Typically the startup file is "~/.apprc"
+ * where "app" is the name of the application. If this line is
+ * deleted then no user-specific startup file will be run under any
+ * conditions.
+ */
#if (TCL_MAJOR_VERSION <= 7) && (TCL_MINOR_VERSION < 5)
- tcl_RcFileName = "~/.wishrc";
+ tcl_RcFileName = "~/.wishrc";
#else
- Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY);
+ Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY);
#endif
- return TCL_OK;
+ return TCL_OK;
}
diff --git a/src/bin/psql/psql.c b/src/bin/psql/psql.c
index 0b77a3ff5f1..3a58f8ad321 100644
--- a/src/bin/psql/psql.c
+++ b/src/bin/psql/psql.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* psql.c--
- * an interactive front-end to postgreSQL
+ * an interactive front-end to postgreSQL
*
* Copyright (c) 1996, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.90 1997/09/05 00:09:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.91 1997/09/07 04:55:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,7 @@
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
-#include <sys/param.h> /* for MAXPATHLEN */
+#include <sys/param.h> /* for MAXPATHLEN */
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
@@ -35,17 +35,17 @@
#endif
#ifdef HAVE_LIBREADLINE
-# ifdef HAVE_READLINE_H
-# include <readline.h>
-# if defined(HAVE_HISTORY)
-# include <history.h>
-# endif
-# else
-# include <readline/readline.h>
-# if defined(HAVE_READLINE_HISTORY_H)
-# include <readline/history.h>
-# endif
-# endif
+#ifdef HAVE_READLINE_H
+#include <readline.h>
+#if defined(HAVE_HISTORY)
+#include <history.h>
+#endif
+#else
+#include <readline/readline.h>
+#if defined(HAVE_READLINE_HISTORY_H)
+#include <readline/history.h>
+#endif
+#endif
#endif
/* This prompt string is assumed to have at least 3 characters by code in MainLoop().
@@ -54,80 +54,84 @@
#define PROMPT "=> "
#define PROMPT_READY '='
-#define PROMPT_CONTINUE '-'
+#define PROMPT_CONTINUE '-'
#define PROMPT_COMMENT '*'
#define PROMPT_QUOTE '\''
/* Backslash command handling:
- * 0 - send currently constructed query to backend (i.e. we got a \g)
- * 1 - skip processing of this line, continue building up query
- * 2 - terminate processing of this query entirely
- * 3 - new query supplied by edit
+ * 0 - send currently constructed query to backend (i.e. we got a \g)
+ * 1 - skip processing of this line, continue building up query
+ * 2 - terminate processing of this query entirely
+ * 3 - new query supplied by edit
*/
-#define CMD_UNKNOWN -1
-#define CMD_SEND 0
+#define CMD_UNKNOWN -1
+#define CMD_SEND 0
#define CMD_SKIP_LINE 1
#define CMD_TERMINATE 2
-#define CMD_NEWEDIT 3
+#define CMD_NEWEDIT 3
#define MAX_QUERY_BUFFER 20000
-#define COPYBUFSIZ 8192
+#define COPYBUFSIZ 8192
#define DEFAULT_FIELD_SEP "|"
-#define DEFAULT_EDITOR "vi"
+#define DEFAULT_EDITOR "vi"
#define DEFAULT_SHELL "/bin/sh"
-typedef struct _psqlSettings {
- PGconn *db; /* connection to backend */
- FILE *queryFout; /* where to send the query results */
- PQprintOpt opt; /* options to be passed to PQprint */
- char *prompt; /* prompt to display */
- char *gfname; /* one-shot file output argument for \g */
- bool notty; /* input or output is not a tty */
- bool pipe; /* queryFout is from a popen() */
- bool echoQuery; /* echo the query before sending it */
- bool quiet; /* run quietly, no messages, no promt */
- bool singleStep; /* prompt before for each query */
- bool singleLineMode; /* query terminated by newline */
- bool useReadline;/* use libreadline routines */
- bool getPassword;/* prompt the user for a username and password */
-} PsqlSettings;
+typedef struct _psqlSettings
+{
+ PGconn *db; /* connection to backend */
+ FILE *queryFout; /* where to send the query results */
+ PQprintOpt opt; /* options to be passed to PQprint */
+ char *prompt; /* prompt to display */
+ char *gfname; /* one-shot file output argument for \g */
+ bool notty; /* input or output is not a tty */
+ bool pipe; /* queryFout is from a popen() */
+ bool echoQuery; /* echo the query before sending it */
+ bool quiet; /* run quietly, no messages, no promt */
+ bool singleStep; /* prompt before for each query */
+ bool singleLineMode; /* query terminated by newline */
+ bool useReadline;/* use libreadline routines */
+ bool getPassword;/* prompt the user for a username and
+ * password */
+} PsqlSettings;
/* declarations for functions in this file */
-static void usage(char *progname);
-static void slashUsage();
-static void handleCopyOut(PGresult * res, bool quiet, FILE * copystream);
+static void usage(char *progname);
+static void slashUsage();
+static void handleCopyOut(PGresult * res, bool quiet, FILE * copystream);
static void
handleCopyIn(PGresult * res, const bool mustprompt,
- FILE * copystream);
-static int tableList(PsqlSettings * ps, bool deep_tablelist, char info_type);
-static int tableDesc(PsqlSettings * ps, char *table);
-static int rightsList(PsqlSettings * ps);
-static void prompt_for_password(char *username, char *password);
-static char * make_connect_string(char *host, char *port, char *dbname,
- char *username, char *password);
-
-static char *gets_noreadline(char *prompt, FILE * source);
-static char *gets_readline(char *prompt, FILE * source);
-static char *gets_fromFile(char *prompt, FILE * source);
-static int listAllDbs(PsqlSettings * settings);
+ FILE * copystream);
+static int tableList(PsqlSettings * ps, bool deep_tablelist, char info_type);
+static int tableDesc(PsqlSettings * ps, char *table);
+static int rightsList(PsqlSettings * ps);
+static void prompt_for_password(char *username, char *password);
+static char *
+make_connect_string(char *host, char *port, char *dbname,
+ char *username, char *password);
+
+static char *gets_noreadline(char *prompt, FILE * source);
+static char *gets_readline(char *prompt, FILE * source);
+static char *gets_fromFile(char *prompt, FILE * source);
+static int listAllDbs(PsqlSettings * settings);
static void
SendQuery(bool * success_p, PsqlSettings * settings, const char *query,
- const bool copy_in, const bool copy_out, FILE * copystream);
+ const bool copy_in, const bool copy_out, FILE * copystream);
static int
HandleSlashCmds(PsqlSettings * settings,
- char *line,
- char *query);
-static int MainLoop(PsqlSettings * settings, FILE * source);
+ char *line,
+ char *query);
+static int MainLoop(PsqlSettings * settings, FILE * source);
+
/* probably should move this into libpq */
void
PQprint(FILE * fp,
- PGresult * res,
- PQprintOpt * po
+ PGresult * res,
+ PQprintOpt * po
);
-static FILE *setFout(PsqlSettings * ps, char *fname);
+static FILE *setFout(PsqlSettings * ps, char *fname);
/*
* usage print out usage for command line arguments
@@ -136,28 +140,28 @@ static FILE *setFout(PsqlSettings * ps, char *fname);
static void
usage(char *progname)
{
- fprintf(stderr, "Usage: %s [options] [dbname]\n", progname);
- fprintf(stderr, "\t -a authsvc set authentication service\n");
- fprintf(stderr, "\t -A turn off alignment when printing out attributes\n");
- fprintf(stderr, "\t -c query run single query (slash commands too)\n");
- fprintf(stderr, "\t -d dbName specify database name\n");
- fprintf(stderr, "\t -e echo the query sent to the backend\n");
- fprintf(stderr, "\t -f filename use file as a source of queries\n");
- fprintf(stderr, "\t -F sep set the field separator (default is '|')\n");
- fprintf(stderr, "\t -h host set database server host\n");
- fprintf(stderr, "\t -H turn on html3.0 table output\n");
- fprintf(stderr, "\t -l list available databases\n");
- fprintf(stderr, "\t -n don't use readline library\n");
- fprintf(stderr, "\t -o filename send output to filename or (|pipe)\n");
- fprintf(stderr, "\t -p port set port number\n");
- fprintf(stderr, "\t -q run quietly (no messages, no prompts)\n");
- fprintf(stderr, "\t -s single step mode (prompts for each query)\n");
- fprintf(stderr, "\t -S single line mode (i.e. query terminated by newline)\n");
- fprintf(stderr, "\t -t turn off printing of headings and row count\n");
- fprintf(stderr, "\t -T html set html3.0 table command options (cf. -H)\n");
- fprintf(stderr, "\t -u ask for a username and password for authentication\n");
- fprintf(stderr, "\t -x turn on expanded output (field names on left)\n");
- exit(1);
+ fprintf(stderr, "Usage: %s [options] [dbname]\n", progname);
+ fprintf(stderr, "\t -a authsvc set authentication service\n");
+ fprintf(stderr, "\t -A turn off alignment when printing out attributes\n");
+ fprintf(stderr, "\t -c query run single query (slash commands too)\n");
+ fprintf(stderr, "\t -d dbName specify database name\n");
+ fprintf(stderr, "\t -e echo the query sent to the backend\n");
+ fprintf(stderr, "\t -f filename use file as a source of queries\n");
+ fprintf(stderr, "\t -F sep set the field separator (default is '|')\n");
+ fprintf(stderr, "\t -h host set database server host\n");
+ fprintf(stderr, "\t -H turn on html3.0 table output\n");
+ fprintf(stderr, "\t -l list available databases\n");
+ fprintf(stderr, "\t -n don't use readline library\n");
+ fprintf(stderr, "\t -o filename send output to filename or (|pipe)\n");
+ fprintf(stderr, "\t -p port set port number\n");
+ fprintf(stderr, "\t -q run quietly (no messages, no prompts)\n");
+ fprintf(stderr, "\t -s single step mode (prompts for each query)\n");
+ fprintf(stderr, "\t -S single line mode (i.e. query terminated by newline)\n");
+ fprintf(stderr, "\t -t turn off printing of headings and row count\n");
+ fprintf(stderr, "\t -T html set html3.0 table command options (cf. -H)\n");
+ fprintf(stderr, "\t -u ask for a username and password for authentication\n");
+ fprintf(stderr, "\t -x turn on expanded output (field names on left)\n");
+ exit(1);
}
/*
@@ -167,412 +171,458 @@ usage(char *progname)
static char *
on(bool f)
{
- return f ? "on" : "off";
+ return f ? "on" : "off";
}
static void
slashUsage(PsqlSettings * ps)
{
- int usePipe = 0;
- char *pagerenv;
- FILE *fout;
-
- if (ps->notty == 0 &&
- (pagerenv = getenv("PAGER")) &&
- (pagerenv[0] != '\0') &&
- (fout = popen(pagerenv, "w")))
- {
- usePipe = 1;
- pqsignal(SIGPIPE, SIG_IGN);
- }
- else
- fout = stdout;
-
- fprintf(fout, " \\? -- help\n");
- fprintf(fout, " \\a -- toggle field-alignment (currenty %s)\n", on(ps->opt.align));
- fprintf(fout, " \\C [<captn>] -- set html3 caption (currently '%s')\n", ps->opt.caption ? ps->opt.caption : "");
- fprintf(fout, " \\connect <dbname|-> <user> -- connect to new database (currently '%s')\n", PQdb(ps->db));
- fprintf(fout, " \\copy table {from | to} <fname>\n");
- fprintf(fout, " \\d [<table>] -- list tables and indices in database or columns in <table>, * for all\n");
- fprintf(fout, " \\di -- list only indices in database\n");
- fprintf(fout, " \\ds -- list only sequences in database\n");
- fprintf(fout, " \\dt -- list only tables in database\n");
- fprintf(fout, " \\e [<fname>] -- edit the current query buffer or <fname>, \\E execute too\n");
- fprintf(fout, " \\f [<sep>] -- change field separater (currently '%s')\n", ps->opt.fieldSep);
- fprintf(fout, " \\g [<fname>] [|<cmd>] -- send query to backend [and results in <fname> or pipe]\n");
- fprintf(fout, " \\h [<cmd>] -- help on syntax of sql commands, * for all commands\n");
- fprintf(fout, " \\H -- toggle html3 output (currently %s)\n", on(ps->opt.html3));
- fprintf(fout, " \\i <fname> -- read and execute queries from filename\n");
- fprintf(fout, " \\l -- list all databases\n");
- fprintf(fout, " \\m -- toggle monitor-like table display (currently %s)\n", on(ps->opt.standard));
- fprintf(fout, " \\o [<fname>] [|<cmd>] -- send all query results to stdout, <fname>, or pipe\n");
- fprintf(fout, " \\p -- print the current query buffer\n");
- fprintf(fout, " \\q -- quit\n");
- fprintf(fout, " \\r -- reset(clear) the query buffer\n");
- fprintf(fout, " \\s [<fname>] -- print history or save it in <fname>\n");
- fprintf(fout, " \\t -- toggle table headings and row count (currently %s)\n", on(ps->opt.header));
- fprintf(fout, " \\T [<html>] -- set html3.0 <table ...> options (currently '%s')\n", ps->opt.tableOpt ? ps->opt.tableOpt : "");
- fprintf(fout, " \\x -- toggle expanded output (currently %s)\n", on(ps->opt.expanded));
- fprintf(fout, " \\z -- list current grant/revoke permissions\n");
- fprintf(fout, " \\! [<cmd>] -- shell escape or command\n");
-
- if (usePipe)
- {
- pclose(fout);
- pqsignal(SIGPIPE, SIG_DFL);
- }
+ int usePipe = 0;
+ char *pagerenv;
+ FILE *fout;
+
+ if (ps->notty == 0 &&
+ (pagerenv = getenv("PAGER")) &&
+ (pagerenv[0] != '\0') &&
+ (fout = popen(pagerenv, "w")))
+ {
+ usePipe = 1;
+ pqsignal(SIGPIPE, SIG_IGN);
+ }
+ else
+ fout = stdout;
+
+ fprintf(fout, " \\? -- help\n");
+ fprintf(fout, " \\a -- toggle field-alignment (currenty %s)\n", on(ps->opt.align));
+ fprintf(fout, " \\C [<captn>] -- set html3 caption (currently '%s')\n", ps->opt.caption ? ps->opt.caption : "");
+ fprintf(fout, " \\connect <dbname|-> <user> -- connect to new database (currently '%s')\n", PQdb(ps->db));
+ fprintf(fout, " \\copy table {from | to} <fname>\n");
+ fprintf(fout, " \\d [<table>] -- list tables and indices in database or columns in <table>, * for all\n");
+ fprintf(fout, " \\di -- list only indices in database\n");
+ fprintf(fout, " \\ds -- list only sequences in database\n");
+ fprintf(fout, " \\dt -- list only tables in database\n");
+ fprintf(fout, " \\e [<fname>] -- edit the current query buffer or <fname>, \\E execute too\n");
+ fprintf(fout, " \\f [<sep>] -- change field separater (currently '%s')\n", ps->opt.fieldSep);
+ fprintf(fout, " \\g [<fname>] [|<cmd>] -- send query to backend [and results in <fname> or pipe]\n");
+ fprintf(fout, " \\h [<cmd>] -- help on syntax of sql commands, * for all commands\n");
+ fprintf(fout, " \\H -- toggle html3 output (currently %s)\n", on(ps->opt.html3));
+ fprintf(fout, " \\i <fname> -- read and execute queries from filename\n");
+ fprintf(fout, " \\l -- list all databases\n");
+ fprintf(fout, " \\m -- toggle monitor-like table display (currently %s)\n", on(ps->opt.standard));
+ fprintf(fout, " \\o [<fname>] [|<cmd>] -- send all query results to stdout, <fname>, or pipe\n");
+ fprintf(fout, " \\p -- print the current query buffer\n");
+ fprintf(fout, " \\q -- quit\n");
+ fprintf(fout, " \\r -- reset(clear) the query buffer\n");
+ fprintf(fout, " \\s [<fname>] -- print history or save it in <fname>\n");
+ fprintf(fout, " \\t -- toggle table headings and row count (currently %s)\n", on(ps->opt.header));
+ fprintf(fout, " \\T [<html>] -- set html3.0 <table ...> options (currently '%s')\n", ps->opt.tableOpt ? ps->opt.tableOpt : "");
+ fprintf(fout, " \\x -- toggle expanded output (currently %s)\n", on(ps->opt.expanded));
+ fprintf(fout, " \\z -- list current grant/revoke permissions\n");
+ fprintf(fout, " \\! [<cmd>] -- shell escape or command\n");
+
+ if (usePipe)
+ {
+ pclose(fout);
+ pqsignal(SIGPIPE, SIG_DFL);
+ }
}
static PGresult *
PSQLexec(PsqlSettings * ps, char *query)
{
- PGresult *res;
- res = PQexec(ps->db, query);
- if (!res)
- fputs(PQerrorMessage(ps->db), stderr);
- else {
- if (PQresultStatus(res) == PGRES_COMMAND_OK ||
- PQresultStatus(res) == PGRES_TUPLES_OK)
- return res;
- if (!ps->quiet)
- fputs(PQerrorMessage(ps->db), stderr);
- PQclear(res);
- }
- return NULL;
+ PGresult *res;
+
+ res = PQexec(ps->db, query);
+ if (!res)
+ fputs(PQerrorMessage(ps->db), stderr);
+ else
+ {
+ if (PQresultStatus(res) == PGRES_COMMAND_OK ||
+ PQresultStatus(res) == PGRES_TUPLES_OK)
+ return res;
+ if (!ps->quiet)
+ fputs(PQerrorMessage(ps->db), stderr);
+ PQclear(res);
+ }
+ return NULL;
}
+
/*
* listAllDbs
- *
+ *
* list all the databases in the system returns 0 if all went well
- *
- *
+ *
+ *
*/
static int
listAllDbs(PsqlSettings * ps)
{
- PGresult *results;
- char *query = "select * from pg_database;";
-
- if (!(results = PSQLexec(ps, query)))
- return 1;
- else {
- PQprint(ps->queryFout,
- results,
- &ps->opt);
- PQclear(results);
- return 0;
- }
+ PGresult *results;
+ char *query = "select * from pg_database;";
+
+ if (!(results = PSQLexec(ps, query)))
+ return 1;
+ else
+ {
+ PQprint(ps->queryFout,
+ results,
+ &ps->opt);
+ PQclear(results);
+ return 0;
+ }
}
/*
* List The Database Tables returns 0 if all went well
- *
+ *
*/
int
tableList(PsqlSettings * ps, bool deep_tablelist, char info_type)
{
- char listbuf[256];
- int nColumns;
- int i;
- char *rk;
- char *rr;
-
- PGresult *res;
-
- listbuf[0] = '\0';
- strcat(listbuf, "SELECT usename, relname, relkind, relhasrules");
- strcat(listbuf, " FROM pg_class, pg_user ");
- switch (info_type) {
- case 't': strcat(listbuf, "WHERE ( relkind = 'r') ");
- break;
- case 'i': strcat(listbuf, "WHERE ( relkind = 'i') ");
- break;
- case 'S': strcat(listbuf, "WHERE ( relkind = 'S') ");
- break;
- case 'b':
- default: strcat(listbuf, "WHERE ( relkind = 'r' OR relkind = 'i' OR relkind = 'S') ");
- break;
- }
+ char listbuf[256];
+ int nColumns;
+ int i;
+ char *rk;
+ char *rr;
+
+ PGresult *res;
+
+ listbuf[0] = '\0';
+ strcat(listbuf, "SELECT usename, relname, relkind, relhasrules");
+ strcat(listbuf, " FROM pg_class, pg_user ");
+ switch (info_type)
+ {
+ case 't':
+ strcat(listbuf, "WHERE ( relkind = 'r') ");
+ break;
+ case 'i':
+ strcat(listbuf, "WHERE ( relkind = 'i') ");
+ break;
+ case 'S':
+ strcat(listbuf, "WHERE ( relkind = 'S') ");
+ break;
+ case 'b':
+ default:
+ strcat(listbuf, "WHERE ( relkind = 'r' OR relkind = 'i' OR relkind = 'S') ");
+ break;
+ }
strcat(listbuf, " and relname !~ '^pg_'");
strcat(listbuf, " and relname !~ '^xin[vx][0-9]+'");
- /*
- * the usesysid = relowner won't work on stock 1.0 dbs, need to add in
- * the int4oideq function
- */
- strcat(listbuf, " and usesysid = relowner");
- strcat(listbuf, " ORDER BY relname ");
- if (!(res = PSQLexec(ps, listbuf)))
- return -1;
- /* first, print out the attribute names */
- nColumns = PQntuples(res);
- if (nColumns > 0) {
- if (deep_tablelist) {
- /* describe everything here */
- char **table;
- table = (char **) malloc(nColumns * sizeof(char *));
- if (table == NULL)
- perror("malloc");
- /* load table table */
- for (i = 0; i < nColumns; i++) {
- table[i] = (char *) malloc(PQgetlength(res, i, 1) * sizeof(char) + 1);
- if (table[i] == NULL)
- perror("malloc");
- strcpy(table[i], PQgetvalue(res, i, 1));
- }
-
- PQclear(res); /* PURIFY */
- for (i = 0; i < nColumns; i++) {
- tableDesc(ps, table[i]);
- }
- free(table);
- } else {
- /* Display the information */
-
- printf("\nDatabase = %s\n", PQdb(ps->db));
- printf(" +------------------+----------------------------------+----------+\n");
- printf(" | Owner | Relation | Type |\n");
- printf(" +------------------+----------------------------------+----------+\n");
-
- /* next, print out the instances */
- for (i = 0; i < PQntuples(res); i++) {
- printf(" | %-16.16s", PQgetvalue(res, i, 0));
- printf(" | %-32.32s | ", PQgetvalue(res, i, 1));
- rk = PQgetvalue(res, i, 2);
- rr = PQgetvalue(res, i, 3);
- if (strcmp(rk, "r") == 0)
- printf("%-8.8s |", (rr[0] == 't') ? "view?" : "table");
+ /*
+ * the usesysid = relowner won't work on stock 1.0 dbs, need to add in
+ * the int4oideq function
+ */
+ strcat(listbuf, " and usesysid = relowner");
+ strcat(listbuf, " ORDER BY relname ");
+ if (!(res = PSQLexec(ps, listbuf)))
+ return -1;
+ /* first, print out the attribute names */
+ nColumns = PQntuples(res);
+ if (nColumns > 0)
+ {
+ if (deep_tablelist)
+ {
+ /* describe everything here */
+ char **table;
+
+ table = (char **) malloc(nColumns * sizeof(char *));
+ if (table == NULL)
+ perror("malloc");
+
+ /* load table table */
+ for (i = 0; i < nColumns; i++)
+ {
+ table[i] = (char *) malloc(PQgetlength(res, i, 1) * sizeof(char) + 1);
+ if (table[i] == NULL)
+ perror("malloc");
+ strcpy(table[i], PQgetvalue(res, i, 1));
+ }
+
+ PQclear(res); /* PURIFY */
+ for (i = 0; i < nColumns; i++)
+ {
+ tableDesc(ps, table[i]);
+ }
+ free(table);
+ }
else
- if (strcmp(rk, "i") == 0)
- printf("%-8.8s |", "index");
- else
- printf("%-8.8s |", "sequence");
- printf("\n");
- }
- printf(" +------------------+----------------------------------+----------+\n");
- PQclear(res);
+ {
+ /* Display the information */
+
+ printf("\nDatabase = %s\n", PQdb(ps->db));
+ printf(" +------------------+----------------------------------+----------+\n");
+ printf(" | Owner | Relation | Type |\n");
+ printf(" +------------------+----------------------------------+----------+\n");
+
+ /* next, print out the instances */
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ printf(" | %-16.16s", PQgetvalue(res, i, 0));
+ printf(" | %-32.32s | ", PQgetvalue(res, i, 1));
+ rk = PQgetvalue(res, i, 2);
+ rr = PQgetvalue(res, i, 3);
+ if (strcmp(rk, "r") == 0)
+ printf("%-8.8s |", (rr[0] == 't') ? "view?" : "table");
+ else if (strcmp(rk, "i") == 0)
+ printf("%-8.8s |", "index");
+ else
+ printf("%-8.8s |", "sequence");
+ printf("\n");
+ }
+ printf(" +------------------+----------------------------------+----------+\n");
+ PQclear(res);
+ }
+ return (0);
+
+ }
+ else
+ {
+ PQclear(res); /* PURIFY */
+ switch (info_type)
+ {
+ case 't':
+ fprintf(stderr, "Couldn't find any tables!\n");
+ break;
+ case 'i':
+ fprintf(stderr, "Couldn't find any indices!\n");
+ break;
+ case 'S':
+ fprintf(stderr, "Couldn't find any sequences!\n");
+ break;
+ case 'b':
+ default:
+ fprintf(stderr, "Couldn't find any tables, sequences or indices!\n");
+ break;
+ }
+ return (-1);
}
- return (0);
-
- } else {
- PQclear(res); /* PURIFY */
- switch (info_type) {
- case 't': fprintf(stderr, "Couldn't find any tables!\n");
- break;
- case 'i': fprintf(stderr, "Couldn't find any indices!\n");
- break;
- case 'S': fprintf(stderr, "Couldn't find any sequences!\n");
- break;
- case 'b':
- default: fprintf(stderr, "Couldn't find any tables, sequences or indices!\n");
- break;
- }
- return (-1);
- }
}
/*
* List Tables Grant/Revoke Permissions returns 0 if all went well
- *
+ *
*/
int
rightsList(PsqlSettings * ps)
{
- char listbuf[256];
- int nColumns;
- int i;
-
- PGresult *res;
-
- listbuf[0] = '\0';
- strcat(listbuf, "SELECT relname, relacl");
- strcat(listbuf, " FROM pg_class, pg_user ");
- strcat(listbuf, "WHERE ( relkind = 'r' OR relkind = 'i') ");
- strcat(listbuf, " and relname !~ '^pg_'");
- strcat(listbuf, " and relname !~ '^xin[vx][0-9]+'");
- strcat(listbuf, " and usesysid = relowner");
- strcat(listbuf, " ORDER BY relname ");
- if (!(res = PSQLexec(ps, listbuf)))
- return -1;
-
- nColumns = PQntuples(res);
- if(nColumns > 0) {
- /* Display the information */
-
- printf("\nDatabase = %s\n", PQdb(ps->db));
- printf(" +------------------+----------------------------------------------------+\n");
- printf(" | Relation | Grant/Revoke Permissions |\n");
- printf(" +------------------+----------------------------------------------------+\n");
-
- /* next, print out the instances */
- for (i = 0; i < PQntuples(res); i++) {
- printf(" | %-16.16s", PQgetvalue(res, i, 0));
- printf(" | %-50.50s | ", PQgetvalue(res, i, 1));
- printf("\n");
- }
- printf(" +------------------+----------------------------------------------------+\n");
- PQclear(res);
- return (0);
- } else {
- fprintf(stderr, "Couldn't find any tables!\n");
- return (-1);
- }
+ char listbuf[256];
+ int nColumns;
+ int i;
+
+ PGresult *res;
+
+ listbuf[0] = '\0';
+ strcat(listbuf, "SELECT relname, relacl");
+ strcat(listbuf, " FROM pg_class, pg_user ");
+ strcat(listbuf, "WHERE ( relkind = 'r' OR relkind = 'i') ");
+ strcat(listbuf, " and relname !~ '^pg_'");
+ strcat(listbuf, " and relname !~ '^xin[vx][0-9]+'");
+ strcat(listbuf, " and usesysid = relowner");
+ strcat(listbuf, " ORDER BY relname ");
+ if (!(res = PSQLexec(ps, listbuf)))
+ return -1;
+
+ nColumns = PQntuples(res);
+ if (nColumns > 0)
+ {
+ /* Display the information */
+
+ printf("\nDatabase = %s\n", PQdb(ps->db));
+ printf(" +------------------+----------------------------------------------------+\n");
+ printf(" | Relation | Grant/Revoke Permissions |\n");
+ printf(" +------------------+----------------------------------------------------+\n");
+
+ /* next, print out the instances */
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ printf(" | %-16.16s", PQgetvalue(res, i, 0));
+ printf(" | %-50.50s | ", PQgetvalue(res, i, 1));
+ printf("\n");
+ }
+ printf(" +------------------+----------------------------------------------------+\n");
+ PQclear(res);
+ return (0);
+ }
+ else
+ {
+ fprintf(stderr, "Couldn't find any tables!\n");
+ return (-1);
+ }
}
+
/*
* Describe a table
- *
+ *
* Describe the columns in a database table. returns 0 if all went well
- *
- *
+ *
+ *
*/
int
tableDesc(PsqlSettings * ps, char *table)
{
- char descbuf[256];
- int nColumns;
- char *rtype;
- int i;
- int rsize;
-
- PGresult *res;
-
- /* Build the query */
-
- for(i = strlen(table); i >= 0; i--)
- if (isupper(table[i]))
- table[i] = tolower(table[i]);
-
- descbuf[0] = '\0';
- strcat(descbuf, "SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull");
- strcat(descbuf, " FROM pg_class c, pg_attribute a, pg_type t ");
- strcat(descbuf, " WHERE c.relname = '");
- strcat(descbuf, table);
- strcat(descbuf, "'");
- strcat(descbuf, " and a.attnum > 0 ");
- strcat(descbuf, " and a.attrelid = c.oid ");
- strcat(descbuf, " and a.atttypid = t.oid ");
- strcat(descbuf, " ORDER BY attnum ");
- if (!(res = PSQLexec(ps, descbuf)))
- return -1;
- /* first, print out the attribute names */
- nColumns = PQntuples(res);
- if (nColumns > 0) {
- /*
- * * Display the information
- */
+ char descbuf[256];
+ int nColumns;
+ char *rtype;
+ int i;
+ int rsize;
+
+ PGresult *res;
+
+ /* Build the query */
+
+ for (i = strlen(table); i >= 0; i--)
+ if (isupper(table[i]))
+ table[i] = tolower(table[i]);
+
+ descbuf[0] = '\0';
+ strcat(descbuf, "SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull");
+ strcat(descbuf, " FROM pg_class c, pg_attribute a, pg_type t ");
+ strcat(descbuf, " WHERE c.relname = '");
+ strcat(descbuf, table);
+ strcat(descbuf, "'");
+ strcat(descbuf, " and a.attnum > 0 ");
+ strcat(descbuf, " and a.attrelid = c.oid ");
+ strcat(descbuf, " and a.atttypid = t.oid ");
+ strcat(descbuf, " ORDER BY attnum ");
+ if (!(res = PSQLexec(ps, descbuf)))
+ return -1;
+ /* first, print out the attribute names */
+ nColumns = PQntuples(res);
+ if (nColumns > 0)
+ {
- printf("\nTable = %s\n", table);
- printf("+----------------------------------+----------------------------------+-------+\n");
- printf("| Field | Type | Length|\n");
- printf("+----------------------------------+----------------------------------+-------+\n");
-
- /* next, print out the instances */
- for (i = 0; i < PQntuples(res); i++) {
- printf("| %-32.32s | ", PQgetvalue(res, i, 1));
- rtype = PQgetvalue(res, i, 2);
- rsize = atoi(PQgetvalue(res, i, 3));
- if (strcmp(rtype, "text") == 0) {
- printf("%-32.32s |", rtype);
- printf("%6s |", "var");
- } else if (strcmp(rtype, "bpchar") == 0) {
- printf("%-32.32s |", "(bp)char");
- printf("%6i |", rsize > 0 ? rsize - 4 : 0);
- } else if (strcmp(rtype, "varchar") == 0) {
- printf("%-32.32s |", rtype);
- printf("%6i |", rsize > 0 ? rsize - 4 : 0);
- } else {
- /* array types start with an underscore */
- if (rtype[0] != '_')
- printf("%-32.32s |", rtype);
- else {
- char *newname;
- newname = malloc(strlen(rtype) + 2);
- strcpy(newname, rtype + 1);
- strcat(newname, "[]");
- printf("%-32.32s |", newname);
- free(newname);
- }
- if (rsize > 0)
- printf("%6i |", rsize);
- else
- printf("%6s |", "var");
- }
- printf("\n");
- }
- printf("+----------------------------------+----------------------------------+-------+\n");
+ /*
+ * * Display the information
+ */
+
+ printf("\nTable = %s\n", table);
+ printf("+----------------------------------+----------------------------------+-------+\n");
+ printf("| Field | Type | Length|\n");
+ printf("+----------------------------------+----------------------------------+-------+\n");
+
+ /* next, print out the instances */
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ printf("| %-32.32s | ", PQgetvalue(res, i, 1));
+ rtype = PQgetvalue(res, i, 2);
+ rsize = atoi(PQgetvalue(res, i, 3));
+ if (strcmp(rtype, "text") == 0)
+ {
+ printf("%-32.32s |", rtype);
+ printf("%6s |", "var");
+ }
+ else if (strcmp(rtype, "bpchar") == 0)
+ {
+ printf("%-32.32s |", "(bp)char");
+ printf("%6i |", rsize > 0 ? rsize - 4 : 0);
+ }
+ else if (strcmp(rtype, "varchar") == 0)
+ {
+ printf("%-32.32s |", rtype);
+ printf("%6i |", rsize > 0 ? rsize - 4 : 0);
+ }
+ else
+ {
+ /* array types start with an underscore */
+ if (rtype[0] != '_')
+ printf("%-32.32s |", rtype);
+ else
+ {
+ char *newname;
+
+ newname = malloc(strlen(rtype) + 2);
+ strcpy(newname, rtype + 1);
+ strcat(newname, "[]");
+ printf("%-32.32s |", newname);
+ free(newname);
+ }
+ if (rsize > 0)
+ printf("%6i |", rsize);
+ else
+ printf("%6s |", "var");
+ }
+ printf("\n");
+ }
+ printf("+----------------------------------+----------------------------------+-------+\n");
- PQclear(res);
- return (0);
+ PQclear(res);
+ return (0);
- } else {
- fprintf(stderr, "Couldn't find table %s!\n", table);
- return (-1);
- }
+ }
+ else
+ {
+ fprintf(stderr, "Couldn't find table %s!\n", table);
+ return (-1);
+ }
}
typedef char *(*READ_ROUTINE) (char *prompt, FILE * source);
/*
- * gets_noreadline prompt source gets a line of input without calling
+ * gets_noreadline prompt source gets a line of input without calling
* readline, the source is ignored
*/
-static char *
+static char *
gets_noreadline(char *prompt, FILE * source)
{
- fputs(prompt, stdout);
- fflush(stdout);
- return (gets_fromFile(prompt, stdin));
+ fputs(prompt, stdout);
+ fflush(stdout);
+ return (gets_fromFile(prompt, stdin));
}
/*
* gets_readline prompt source the routine to get input from GNU readline(),
* the source is ignored the prompt argument is used as the prompting string
*/
-static char *
+static char *
gets_readline(char *prompt, FILE * source)
{
- char *s;
+ char *s;
+
#ifdef HAVE_LIBREADLINE
- s = readline(prompt);
+ s = readline(prompt);
#else
- char buf[500];
- printf("%s", prompt);
- s = fgets(buf, 500, stdin);
+ char buf[500];
+
+ printf("%s", prompt);
+ s = fgets(buf, 500, stdin);
#endif
- fputc('\r', stdout);
- fflush(stdout);
- return s;
+ fputc('\r', stdout);
+ fflush(stdout);
+ return s;
}
/*
* gets_fromFile prompt source
- *
+ *
* the routine to read from a file, the prompt argument is ignored the source
* argument is a FILE *
*/
-static char *
+static char *
gets_fromFile(char *prompt, FILE * source)
{
- char *line;
- int len;
+ char *line;
+ int len;
- line = malloc(MAX_QUERY_BUFFER + 1);
+ line = malloc(MAX_QUERY_BUFFER + 1);
- /* read up to MAX_QUERY_BUFFER characters */
- if (fgets(line, MAX_QUERY_BUFFER, source) == NULL)
+ /* read up to MAX_QUERY_BUFFER characters */
+ if (fgets(line, MAX_QUERY_BUFFER, source) == NULL)
{
- free(line);
- return NULL;
+ free(line);
+ return NULL;
}
- line[MAX_QUERY_BUFFER - 1] = '\0';
- len = strlen(line);
- if (len == MAX_QUERY_BUFFER) {
- fprintf(stderr, "line read exceeds maximum length. Truncating at %d\n",
- MAX_QUERY_BUFFER);
- }
- return line;
+ line[MAX_QUERY_BUFFER - 1] = '\0';
+ len = strlen(line);
+ if (len == MAX_QUERY_BUFFER)
+ {
+ fprintf(stderr, "line read exceeds maximum length. Truncating at %d\n",
+ MAX_QUERY_BUFFER);
+ }
+ return line;
}
/*
@@ -581,113 +631,131 @@ gets_fromFile(char *prompt, FILE * source)
*/
static void
SendQuery(bool * success_p, PsqlSettings * settings, const char *query,
- const bool copy_in, const bool copy_out, FILE * copystream)
+ const bool copy_in, const bool copy_out, FILE * copystream)
{
- PGresult *results;
- PGnotify *notify;
+ PGresult *results;
+ PGnotify *notify;
- if (settings->singleStep)
- fprintf(stdout, "\n**************************************"
- "*****************************************\n");
+ if (settings->singleStep)
+ fprintf(stdout, "\n**************************************"
+ "*****************************************\n");
- if (settings->echoQuery || settings->singleStep) {
- fprintf(stderr, "QUERY: %s\n", query);
- fflush(stderr);
- }
- if (settings->singleStep) {
- fprintf(stdout, "\n**************************************"
- "*****************************************\n");
- fflush(stdout);
- printf("\npress return to continue ..\n");
- gets_fromFile("", stdin);
- }
- results = PQexec(settings->db, query);
- if (results == NULL) {
- fprintf(stderr, "%s", PQerrorMessage(settings->db));
- *success_p = false;
- } else {
- switch (PQresultStatus(results)) {
- case PGRES_TUPLES_OK:
- if (settings->gfname) {
- PsqlSettings ps = *settings;
- FILE *fp;
- ps.queryFout = stdout;
- fp = setFout(&ps, settings->gfname);
- if (!fp || fp == stdout) {
- *success_p = false;
- break;
- } else
- *success_p = true;
- PQprint(fp,
- results,
- &(settings->opt));
- if (ps.pipe)
- pclose(fp);
- else
- fclose(fp);
- free(settings->gfname);
- settings->gfname = NULL;
- break;
- } else {
- *success_p = true;
- PQprint(settings->queryFout,
- results,
- &(settings->opt));
- fflush(settings->queryFout);
- }
- break;
- case PGRES_EMPTY_QUERY:
- *success_p = true;
- break;
- case PGRES_COMMAND_OK:
- *success_p = true;
- if (!settings->quiet)
- printf("%s\n", PQcmdStatus(results));
- break;
- case PGRES_COPY_OUT:
- *success_p = true;
- if (copy_out) {
- handleCopyOut(results, settings->quiet, copystream);
- } else {
- if (!settings->quiet)
- printf("Copy command returns...\n");
-
- handleCopyOut(results, settings->quiet, stdout);
- }
- break;
- case PGRES_COPY_IN:
- *success_p = true;
- if (copy_in)
- handleCopyIn(results, false, copystream);
- else
- handleCopyIn(results, !settings->quiet, stdin);
- break;
- case PGRES_NONFATAL_ERROR:
- case PGRES_FATAL_ERROR:
- case PGRES_BAD_RESPONSE:
- *success_p = false;
- fprintf(stderr, "%s", PQerrorMessage(settings->db));
- break;
+ if (settings->echoQuery || settings->singleStep)
+ {
+ fprintf(stderr, "QUERY: %s\n", query);
+ fflush(stderr);
}
-
- if (PQstatus(settings->db) == CONNECTION_BAD) {
- fprintf(stderr,
- "We have lost the connection to the backend, so "
- "further processing is impossible. "
- "Terminating.\n");
- exit(2); /* we are out'ta here */
+ if (settings->singleStep)
+ {
+ fprintf(stdout, "\n**************************************"
+ "*****************************************\n");
+ fflush(stdout);
+ printf("\npress return to continue ..\n");
+ gets_fromFile("", stdin);
}
- /* check for asynchronous returns */
- notify = PQnotifies(settings->db);
- if (notify) {
- fprintf(stderr,
- "ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
- notify->relname, notify->be_pid);
- free(notify);
+ results = PQexec(settings->db, query);
+ if (results == NULL)
+ {
+ fprintf(stderr, "%s", PQerrorMessage(settings->db));
+ *success_p = false;
+ }
+ else
+ {
+ switch (PQresultStatus(results))
+ {
+ case PGRES_TUPLES_OK:
+ if (settings->gfname)
+ {
+ PsqlSettings ps = *settings;
+ FILE *fp;
+
+ ps.queryFout = stdout;
+ fp = setFout(&ps, settings->gfname);
+ if (!fp || fp == stdout)
+ {
+ *success_p = false;
+ break;
+ }
+ else
+ *success_p = true;
+ PQprint(fp,
+ results,
+ &(settings->opt));
+ if (ps.pipe)
+ pclose(fp);
+ else
+ fclose(fp);
+ free(settings->gfname);
+ settings->gfname = NULL;
+ break;
+ }
+ else
+ {
+ *success_p = true;
+ PQprint(settings->queryFout,
+ results,
+ &(settings->opt));
+ fflush(settings->queryFout);
+ }
+ break;
+ case PGRES_EMPTY_QUERY:
+ *success_p = true;
+ break;
+ case PGRES_COMMAND_OK:
+ *success_p = true;
+ if (!settings->quiet)
+ printf("%s\n", PQcmdStatus(results));
+ break;
+ case PGRES_COPY_OUT:
+ *success_p = true;
+ if (copy_out)
+ {
+ handleCopyOut(results, settings->quiet, copystream);
+ }
+ else
+ {
+ if (!settings->quiet)
+ printf("Copy command returns...\n");
+
+ handleCopyOut(results, settings->quiet, stdout);
+ }
+ break;
+ case PGRES_COPY_IN:
+ *success_p = true;
+ if (copy_in)
+ handleCopyIn(results, false, copystream);
+ else
+ handleCopyIn(results, !settings->quiet, stdin);
+ break;
+ case PGRES_NONFATAL_ERROR:
+ case PGRES_FATAL_ERROR:
+ case PGRES_BAD_RESPONSE:
+ *success_p = false;
+ fprintf(stderr, "%s", PQerrorMessage(settings->db));
+ break;
+ }
+
+ if (PQstatus(settings->db) == CONNECTION_BAD)
+ {
+ fprintf(stderr,
+ "We have lost the connection to the backend, so "
+ "further processing is impossible. "
+ "Terminating.\n");
+ exit(2); /* we are out'ta here */
+ }
+ /* check for asynchronous returns */
+ notify = PQnotifies(settings->db);
+ if (notify)
+ {
+ fprintf(stderr,
+ "ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
+ notify->relname, notify->be_pid);
+ free(notify);
+ }
+ if (results)
+ PQclear(results);
}
- if(results) PQclear(results);
- }
}
@@ -695,28 +763,30 @@ SendQuery(bool * success_p, PsqlSettings * settings, const char *query,
static void
editFile(char *fname)
{
- char *editorName;
- char *sys;
- editorName = getenv("EDITOR");
- if (!editorName)
- editorName = DEFAULT_EDITOR;
- sys = malloc(strlen(editorName) + strlen(fname) + 32 + 1);
- if (!sys) {
- perror("malloc");
- exit(1);
- }
- sprintf(sys, "exec '%s' '%s'", editorName, fname);
- system(sys);
- free(sys);
+ char *editorName;
+ char *sys;
+
+ editorName = getenv("EDITOR");
+ if (!editorName)
+ editorName = DEFAULT_EDITOR;
+ sys = malloc(strlen(editorName) + strlen(fname) + 32 + 1);
+ if (!sys)
+ {
+ perror("malloc");
+ exit(1);
+ }
+ sprintf(sys, "exec '%s' '%s'", editorName, fname);
+ system(sys);
+ free(sys);
}
-static bool
+static bool
toggle(PsqlSettings * settings, bool * sw, char *msg)
{
- *sw = !*sw;
- if (!settings->quiet)
- printf("turned %s %s\n", on(*sw), msg);
- return *sw;
+ *sw = !*sw;
+ if (!settings->quiet)
+ printf("turned %s %s\n", on(*sw), msg);
+ return *sw;
}
@@ -724,117 +794,138 @@ toggle(PsqlSettings * settings, bool * sw, char *msg)
static void
unescape(char *dest, const char *source)
{
- /*-----------------------------------------------------------------------------
- Return as the string <dest> the value of string <source> with escape
- sequences turned into the bytes they represent.
- -----------------------------------------------------------------------------*/
- char *p;
- bool esc; /* Last character we saw was the escape
- * character (/) */
-
- esc = false; /* Haven't seen escape character yet */
- for (p = (char *) source; *p; p++) {
- char c; /* Our output character */
-
- if (esc) {
- switch (*p) {
- case 'n':
- c = '\n';
- break;
- case 'r':
- c = '\r';
- break;
- case 't':
- c = '\t';
- break;
- case 'f':
- c = '\f';
- break;
- case '\\':
- c = '\\';
- break;
- default:
- c = *p;
- }
- esc = false;
- } else if (*p == '\\') {
- esc = true;
- c = ' '; /* meaningless, but compiler doesn't know
- * that */
- } else {
- c = *p;
- esc = false;
+ /*-----------------------------------------------------------------------------
+ Return as the string <dest> the value of string <source> with escape
+ sequences turned into the bytes they represent.
+ -----------------------------------------------------------------------------*/
+ char *p;
+ bool esc; /* Last character we saw was the escape
+ * character (/) */
+
+ esc = false; /* Haven't seen escape character yet */
+ for (p = (char *) source; *p; p++)
+ {
+ char c; /* Our output character */
+
+ if (esc)
+ {
+ switch (*p)
+ {
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ case 'f':
+ c = '\f';
+ break;
+ case '\\':
+ c = '\\';
+ break;
+ default:
+ c = *p;
+ }
+ esc = false;
+ }
+ else if (*p == '\\')
+ {
+ esc = true;
+ c = ' '; /* meaningless, but compiler doesn't know
+ * that */
+ }
+ else
+ {
+ c = *p;
+ esc = false;
+ }
+ if (!esc)
+ *dest++ = c;
}
- if (!esc)
- *dest++ = c;
- }
- *dest = '\0'; /* Terminating null character */
+ *dest = '\0'; /* Terminating null character */
}
static void
parse_slash_copy(const char *args, char *table, const int table_len,
- char *file, const int file_len,
- bool * from_p, bool * error_p)
+ char *file, const int file_len,
+ bool * from_p, bool * error_p)
{
- char work_args[200];
- /*
- * A copy of the \copy command arguments, except that we modify it as we
- * parse to suit our parsing needs.
- */
- char *table_tok, *fromto_tok;
-
- strncpy(work_args, args, sizeof(work_args));
- work_args[sizeof(work_args) - 1] = '\0';
-
- *error_p = false; /* initial assumption */
-
- table_tok = strtok(work_args, " ");
- if (table_tok == NULL) {
- fprintf(stderr, "\\copy needs arguments.\n");
- *error_p = true;
- } else {
- strncpy(table, table_tok, table_len);
- file[table_len - 1] = '\0';
-
- fromto_tok = strtok(NULL, " ");
- if (fromto_tok == NULL) {
- fprintf(stderr, "'FROM' or 'TO' must follow table name.\n");
- *error_p = true;
- } else {
- if (strcasecmp(fromto_tok, "from") == 0)
- *from_p = true;
- else if (strcasecmp(fromto_tok, "to") == 0)
- *from_p = false;
- else {
- fprintf(stderr,
- "Unrecognized token found where "
- "'FROM' or 'TO' expected: '%s'.\n",
- fromto_tok);
+ char work_args[200];
+
+ /*
+ * A copy of the \copy command arguments, except that we modify it as
+ * we parse to suit our parsing needs.
+ */
+ char *table_tok,
+ *fromto_tok;
+
+ strncpy(work_args, args, sizeof(work_args));
+ work_args[sizeof(work_args) - 1] = '\0';
+
+ *error_p = false; /* initial assumption */
+
+ table_tok = strtok(work_args, " ");
+ if (table_tok == NULL)
+ {
+ fprintf(stderr, "\\copy needs arguments.\n");
*error_p = true;
- }
- if (!*error_p) {
- char *file_tok;
-
- file_tok = strtok(NULL, " ");
- if (file_tok == NULL) {
- fprintf(stderr, "A file pathname must follow '%s'.\n",
- fromto_tok);
- *error_p = true;
- } else {
- strncpy(file, file_tok, file_len);
- file[file_len - 1] = '\0';
- if (strtok(NULL, " ") != NULL) {
- fprintf(stderr,
- "You have extra tokens after the filename.\n");
+ }
+ else
+ {
+ strncpy(table, table_tok, table_len);
+ file[table_len - 1] = '\0';
+
+ fromto_tok = strtok(NULL, " ");
+ if (fromto_tok == NULL)
+ {
+ fprintf(stderr, "'FROM' or 'TO' must follow table name.\n");
*error_p = true;
- }
}
- }
+ else
+ {
+ if (strcasecmp(fromto_tok, "from") == 0)
+ *from_p = true;
+ else if (strcasecmp(fromto_tok, "to") == 0)
+ *from_p = false;
+ else
+ {
+ fprintf(stderr,
+ "Unrecognized token found where "
+ "'FROM' or 'TO' expected: '%s'.\n",
+ fromto_tok);
+ *error_p = true;
+ }
+ if (!*error_p)
+ {
+ char *file_tok;
+
+ file_tok = strtok(NULL, " ");
+ if (file_tok == NULL)
+ {
+ fprintf(stderr, "A file pathname must follow '%s'.\n",
+ fromto_tok);
+ *error_p = true;
+ }
+ else
+ {
+ strncpy(file, file_tok, file_len);
+ file[file_len - 1] = '\0';
+ if (strtok(NULL, " ") != NULL)
+ {
+ fprintf(stderr,
+ "You have extra tokens after the filename.\n");
+ *error_p = true;
+ }
+ }
+ }
+ }
}
- }
}
@@ -842,120 +933,140 @@ parse_slash_copy(const char *args, char *table, const int table_len,
static void
do_copy(const char *args, PsqlSettings * settings)
{
- /*---------------------------------------------------------------------------
- Execute a \copy command (frontend copy). We have to open a file, then
- submit a COPY query to the backend and either feed it data from the
- file or route its response into the file.
-
- We do a text copy with default (tab) column delimiters. Some day, we
- should do all the things a backend copy can do.
-
- ----------------------------------------------------------------------------*/
- char query[200];
- /* The COPY command we send to the back end */
- bool from;
- /* The direction of the copy is from a file to a table. */
- char file[MAXPATHLEN + 1];
- /* The pathname of the file from/to which we copy */
- char table[NAMEDATALEN];
- /* The name of the table from/to which we copy */
- bool syntax_error;
- /* The \c command has invalid syntax */
- FILE *copystream;
-
- parse_slash_copy(args, table, sizeof(table), file, sizeof(file),
- &from, &syntax_error);
-
- if (!syntax_error) {
- strcpy(query, "COPY ");
- strcat(query, table);
-
- if (from)
- strcat(query, " FROM stdin");
- else
- strcat(query, " TO stdout");
+ /*---------------------------------------------------------------------------
+ Execute a \copy command (frontend copy). We have to open a file, then
+ submit a COPY query to the backend and either feed it data from the
+ file or route its response into the file.
- if (from) {
- copystream = fopen(file, "r");
- } else {
- copystream = fopen(file, "w");
- }
- if (copystream == NULL)
- fprintf(stderr,
- "Unable to open file %s which to copy, errno = %s (%d).",
- from ? "from" : "to", strerror(errno), errno);
- else {
- bool success; /* The query succeeded at the backend */
-
- SendQuery(&success, settings, query, from, !from, copystream);
- fclose(copystream);
- if (!settings->quiet) {
- if (success)
- printf("Successfully copied.\n");
+ We do a text copy with default (tab) column delimiters. Some day, we
+ should do all the things a backend copy can do.
+
+ ----------------------------------------------------------------------------*/
+ char query[200];
+
+ /* The COPY command we send to the back end */
+ bool from;
+
+ /* The direction of the copy is from a file to a table. */
+ char file[MAXPATHLEN + 1];
+
+ /* The pathname of the file from/to which we copy */
+ char table[NAMEDATALEN];
+
+ /* The name of the table from/to which we copy */
+ bool syntax_error;
+
+ /* The \c command has invalid syntax */
+ FILE *copystream;
+
+ parse_slash_copy(args, table, sizeof(table), file, sizeof(file),
+ &from, &syntax_error);
+
+ if (!syntax_error)
+ {
+ strcpy(query, "COPY ");
+ strcat(query, table);
+
+ if (from)
+ strcat(query, " FROM stdin");
+ else
+ strcat(query, " TO stdout");
+
+ if (from)
+ {
+ copystream = fopen(file, "r");
+ }
else
- printf("Copy failed.\n");
- }
+ {
+ copystream = fopen(file, "w");
+ }
+ if (copystream == NULL)
+ fprintf(stderr,
+ "Unable to open file %s which to copy, errno = %s (%d).",
+ from ? "from" : "to", strerror(errno), errno);
+ else
+ {
+ bool success; /* The query succeeded at the
+ * backend */
+
+ SendQuery(&success, settings, query, from, !from, copystream);
+ fclose(copystream);
+ if (!settings->quiet)
+ {
+ if (success)
+ printf("Successfully copied.\n");
+ else
+ printf("Copy failed.\n");
+ }
+ }
}
- }
}
static void
do_connect(const char *new_dbname,
- const char *new_user,
- PsqlSettings *settings)
+ const char *new_user,
+ PsqlSettings * settings)
{
- if (!new_dbname)
- fprintf(stderr, "\\connect must be followed by a database name\n");
- else {
- PGconn *olddb = settings->db;
- static char *userenv = NULL;
- char *old_userenv = NULL;
- const char *dbparam;
-
- if (new_user != NULL) {
- /*
- PQsetdb() does not allow us to specify the user,
- so we have to do it via PGUSER
- */
- if (userenv != NULL)
- old_userenv = userenv;
- userenv = malloc(strlen("PGUSER=") + strlen(new_user) + 1);
- sprintf(userenv,"PGUSER=%s",new_user);
- /* putenv() may continue to use memory as part of environment */
- putenv(userenv);
- /* can delete old memory if we malloc'ed it */
- if (old_userenv != NULL)
- free(old_userenv);
- }
+ if (!new_dbname)
+ fprintf(stderr, "\\connect must be followed by a database name\n");
+ else
+ {
+ PGconn *olddb = settings->db;
+ static char *userenv = NULL;
+ char *old_userenv = NULL;
+ const char *dbparam;
+
+ if (new_user != NULL)
+ {
+
+ /*
+ * PQsetdb() does not allow us to specify the user, so we have
+ * to do it via PGUSER
+ */
+ if (userenv != NULL)
+ old_userenv = userenv;
+ userenv = malloc(strlen("PGUSER=") + strlen(new_user) + 1);
+ sprintf(userenv, "PGUSER=%s", new_user);
+ /* putenv() may continue to use memory as part of environment */
+ putenv(userenv);
+ /* can delete old memory if we malloc'ed it */
+ if (old_userenv != NULL)
+ free(old_userenv);
+ }
- if (strcmp(new_dbname,"-") != 0)
- dbparam = new_dbname;
- else dbparam = PQdb(olddb);
-
- settings->db = PQsetdb(PQhost(olddb), PQport(olddb),
- NULL, NULL, dbparam);
- if (!settings->quiet) {
- if (!new_user)
- printf("connecting to new database: %s\n", dbparam);
- else if (dbparam != new_dbname)
- printf("connecting as new user: %s\n", new_user);
- else
- printf("connecting to new database: %s as user: %s\n",
- dbparam,new_user);
- }
+ if (strcmp(new_dbname, "-") != 0)
+ dbparam = new_dbname;
+ else
+ dbparam = PQdb(olddb);
- if (PQstatus(settings->db) == CONNECTION_BAD) {
- fprintf(stderr, "%s\n", PQerrorMessage(settings->db));
- fprintf(stderr,"Could not connect to new database. exiting\n");
- exit(2);
- } else {
- PQfinish(olddb);
- free(settings->prompt);
- settings->prompt = malloc(strlen(PQdb(settings->db)) + 10);
- sprintf(settings->prompt, "%s%s", PQdb(settings->db), PROMPT);
+ settings->db = PQsetdb(PQhost(olddb), PQport(olddb),
+ NULL, NULL, dbparam);
+ if (!settings->quiet)
+ {
+ if (!new_user)
+ printf("connecting to new database: %s\n", dbparam);
+ else if (dbparam != new_dbname)
+ printf("connecting as new user: %s\n", new_user);
+ else
+ printf("connecting to new database: %s as user: %s\n",
+ dbparam, new_user);
+ }
+
+ if (PQstatus(settings->db) == CONNECTION_BAD)
+ {
+ fprintf(stderr, "%s\n", PQerrorMessage(settings->db));
+ fprintf(stderr, "Could not connect to new database. exiting\n");
+ exit(2);
+ }
+ else
+ {
+ PQfinish(olddb);
+ free(settings->prompt);
+ settings->prompt = malloc(strlen(PQdb(settings->db)) + 10);
+ sprintf(settings->prompt, "%s%s", PQdb(settings->db), PROMPT);
+ }
}
- }
}
@@ -963,66 +1074,83 @@ static void
do_edit(const char *filename_arg, char *query, int *status_p)
{
- int fd;
- char tmp[64];
- char *fname;
- int cc;
- const int ql = strlen(query);
- bool error;
-
- if (filename_arg) {
- fname = (char *) filename_arg;
- error = false;
- } else {
- sprintf(tmp, "/tmp/psql.%ld.%ld", (long) geteuid(), (long) getpid());
- fname = tmp;
- unlink(tmp);
- if (ql > 0) {
- if ((fd = open(tmp, O_EXCL | O_CREAT | O_WRONLY, 0600)) == -1) {
- perror(tmp);
- error = true;
- } else {
- if (query[ql - 1] != '\n')
- strcat(query, "\n");
- if (write(fd, query, ql) != ql) {
- perror(tmp);
- close(fd);
- unlink(tmp);
- error = true;
- } else
- error = false;
- close(fd);
- }
- } else
- error = false;
- }
-
- if (error)
- *status_p = CMD_SKIP_LINE;
- else {
- editFile(fname);
- if ((fd = open(fname, O_RDONLY)) == -1) {
- perror(fname);
- if (!filename_arg)
- unlink(fname);
- *status_p = CMD_SKIP_LINE;
- } else {
- if ((cc = read(fd, query, MAX_QUERY_BUFFER)) == -1) {
- perror(fname);
- close(fd);
- if (!filename_arg)
- unlink(fname);
+ int fd;
+ char tmp[64];
+ char *fname;
+ int cc;
+ const int ql = strlen(query);
+ bool error;
+
+ if (filename_arg)
+ {
+ fname = (char *) filename_arg;
+ error = false;
+ }
+ else
+ {
+ sprintf(tmp, "/tmp/psql.%ld.%ld", (long) geteuid(), (long) getpid());
+ fname = tmp;
+ unlink(tmp);
+ if (ql > 0)
+ {
+ if ((fd = open(tmp, O_EXCL | O_CREAT | O_WRONLY, 0600)) == -1)
+ {
+ perror(tmp);
+ error = true;
+ }
+ else
+ {
+ if (query[ql - 1] != '\n')
+ strcat(query, "\n");
+ if (write(fd, query, ql) != ql)
+ {
+ perror(tmp);
+ close(fd);
+ unlink(tmp);
+ error = true;
+ }
+ else
+ error = false;
+ close(fd);
+ }
+ }
+ else
+ error = false;
+ }
+
+ if (error)
*status_p = CMD_SKIP_LINE;
- } else {
- query[cc] = '\0';
- close(fd);
- if (!filename_arg)
- unlink(fname);
- rightTrim(query);
- *status_p = CMD_NEWEDIT;
- }
+ else
+ {
+ editFile(fname);
+ if ((fd = open(fname, O_RDONLY)) == -1)
+ {
+ perror(fname);
+ if (!filename_arg)
+ unlink(fname);
+ *status_p = CMD_SKIP_LINE;
+ }
+ else
+ {
+ if ((cc = read(fd, query, MAX_QUERY_BUFFER)) == -1)
+ {
+ perror(fname);
+ close(fd);
+ if (!filename_arg)
+ unlink(fname);
+ *status_p = CMD_SKIP_LINE;
+ }
+ else
+ {
+ query[cc] = '\0';
+ close(fd);
+ if (!filename_arg)
+ unlink(fname);
+ rightTrim(query);
+ *status_p = CMD_NEWEDIT;
+ }
+ }
}
- }
}
@@ -1031,78 +1159,85 @@ static void
do_help(PsqlSettings * ps, const char *topic)
{
- if (!topic) {
- char left_center_right; /* Which column we're
- * displaying */
- int i; /* Index into QL_HELP[] */
-
- printf("type \\h <cmd> where <cmd> is one of the following:\n");
-
- left_center_right = 'L';/* Start with left column */
- i = 0;
- while (QL_HELP[i].cmd != NULL) {
- switch (left_center_right) {
- case 'L':
- printf(" %-25s", QL_HELP[i].cmd);
- left_center_right = 'C';
- break;
- case 'C':
- printf("%-25s", QL_HELP[i].cmd);
- left_center_right = 'R';
- break;
- case 'R':
- printf("%-25s\n", QL_HELP[i].cmd);
- left_center_right = 'L';
- break;
- };
- i++;
- }
- if (left_center_right != 'L')
- puts("\n");
- printf("type \\h * for a complete description of all commands\n");
- } else {
- int i; /* Index into QL_HELP[] */
- bool help_found; /* We found the help he asked for */
-
- int usePipe = 0;
- char *pagerenv;
- FILE *fout;
-
- if (strcmp(topic, "*") == 0 &&
- (ps->notty == 0) &&
- (pagerenv = getenv("PAGER")) &&
- (pagerenv[0] != '\0') &&
- (fout = popen(pagerenv, "w")))
+ if (!topic)
{
- usePipe = 1;
- pqsignal(SIGPIPE, SIG_IGN);
+ char left_center_right; /* Which column we're
+ * displaying */
+ int i; /* Index into QL_HELP[] */
+
+ printf("type \\h <cmd> where <cmd> is one of the following:\n");
+
+ left_center_right = 'L';/* Start with left column */
+ i = 0;
+ while (QL_HELP[i].cmd != NULL)
+ {
+ switch (left_center_right)
+ {
+ case 'L':
+ printf(" %-25s", QL_HELP[i].cmd);
+ left_center_right = 'C';
+ break;
+ case 'C':
+ printf("%-25s", QL_HELP[i].cmd);
+ left_center_right = 'R';
+ break;
+ case 'R':
+ printf("%-25s\n", QL_HELP[i].cmd);
+ left_center_right = 'L';
+ break;
+ };
+ i++;
+ }
+ if (left_center_right != 'L')
+ puts("\n");
+ printf("type \\h * for a complete description of all commands\n");
}
else
- fout = stdout;
-
- help_found = false; /* Haven't found it yet */
- for (i = 0; QL_HELP[i].cmd; i++) {
- if (strcmp(QL_HELP[i].cmd, topic) == 0 ||
- strcmp(topic, "*") == 0) {
- help_found = true;
- fprintf(fout, "Command: %s\n", QL_HELP[i].cmd);
- fprintf(fout, "Description: %s\n", QL_HELP[i].help);
- fprintf(fout, "Syntax:\n");
- fprintf(fout, "%s\n", QL_HELP[i].syntax);
- fprintf(fout, "\n");
- }
- }
-
- if (usePipe)
{
- pclose(fout);
- pqsignal(SIGPIPE, SIG_DFL);
- }
+ int i; /* Index into QL_HELP[] */
+ bool help_found; /* We found the help he asked for */
+
+ int usePipe = 0;
+ char *pagerenv;
+ FILE *fout;
+
+ if (strcmp(topic, "*") == 0 &&
+ (ps->notty == 0) &&
+ (pagerenv = getenv("PAGER")) &&
+ (pagerenv[0] != '\0') &&
+ (fout = popen(pagerenv, "w")))
+ {
+ usePipe = 1;
+ pqsignal(SIGPIPE, SIG_IGN);
+ }
+ else
+ fout = stdout;
+
+ help_found = false; /* Haven't found it yet */
+ for (i = 0; QL_HELP[i].cmd; i++)
+ {
+ if (strcmp(QL_HELP[i].cmd, topic) == 0 ||
+ strcmp(topic, "*") == 0)
+ {
+ help_found = true;
+ fprintf(fout, "Command: %s\n", QL_HELP[i].cmd);
+ fprintf(fout, "Description: %s\n", QL_HELP[i].help);
+ fprintf(fout, "Syntax:\n");
+ fprintf(fout, "%s\n", QL_HELP[i].syntax);
+ fprintf(fout, "\n");
+ }
+ }
+
+ if (usePipe)
+ {
+ pclose(fout);
+ pqsignal(SIGPIPE, SIG_DFL);
+ }
- if (!help_found)
- fprintf(stderr,"command not found, "
- "try \\h with no arguments to see available help\n");
- }
+ if (!help_found)
+ fprintf(stderr, "command not found, "
+ "try \\h with no arguments to see available help\n");
+ }
}
@@ -1111,813 +1246,955 @@ static void
do_shell(const char *command)
{
- if (!command) {
- char *sys;
- char *shellName;
-
- shellName = getenv("SHELL");
- if (shellName == NULL)
- shellName = DEFAULT_SHELL;
- sys = malloc(strlen(shellName) + 16);
- if (!sys) {
- perror("malloc");
- exit(1);
+ if (!command)
+ {
+ char *sys;
+ char *shellName;
+
+ shellName = getenv("SHELL");
+ if (shellName == NULL)
+ shellName = DEFAULT_SHELL;
+ sys = malloc(strlen(shellName) + 16);
+ if (!sys)
+ {
+ perror("malloc");
+ exit(1);
+ }
+ sprintf(sys, "exec %s", shellName);
+ system(sys);
+ free(sys);
}
- sprintf(sys, "exec %s", shellName);
- system(sys);
- free(sys);
- } else
- system(command);
+ else
+ system(command);
}
/*
* HandleSlashCmds:
- *
+ *
* Handles all the different commands that start with \ db_ptr is a pointer to
* the TgDb* structure line is the current input line prompt_ptr is a pointer
* to the prompt string, a pointer is used because the prompt can be used
* with a connection to a new database.
* Returns a status:
- * 0 - send currently constructed query to backend (i.e. we got a \g)
- * 1 - skip processing of this line, continue building up query
- * 2 - terminate processing of this query entirely
- * 3 - new query supplied by edit
+ * 0 - send currently constructed query to backend (i.e. we got a \g)
+ * 1 - skip processing of this line, continue building up query
+ * 2 - terminate processing of this query entirely
+ * 3 - new query supplied by edit
*/
static int
HandleSlashCmds(PsqlSettings * settings,
- char *line,
- char *query)
+ char *line,
+ char *query)
{
- int status = CMD_SKIP_LINE;
- char *optarg;
- /*
- * Pointer inside the <cmd> string to the argument of the slash command,
- * assuming it is a one-character slash command. If it's not a
- * one-character command, this is meaningless.
- */
- char *optarg2;
- /*
- * Pointer inside the <cmd> string to the argument of the slash command
- * assuming it's not a one-character command. If it's a one-character
- * command, this is meaningless.
- */
- char *cmd;
- /*
- * String: value of the slash command, less the slash and with escape
- * sequences decoded.
- */
- int blank_loc;
- /* Offset within <cmd> of first blank */
-
- cmd = malloc(strlen(line)); /* unescaping better not make string grow. */
-
- unescape(cmd, line + 1); /* sets cmd string */
-
- if (strlen(cmd) >= 1 && cmd[strlen(cmd)-1] == ';') /* strip trailing ; */
- cmd[strlen(cmd)-1] = '\0';
-
- /*
- * Originally, there were just single character commands. Now, we define
- * some longer, friendly commands, but we have to keep the old single
- * character commands too. \c used to be what \connect is now.
- * Complicating matters is the fact that with the single-character
- * commands, you can start the argument right after the single character,
- * so "\copy" would mean "connect to database named 'opy'".
- */
-
- if (strlen(cmd) > 1)
- optarg = cmd + 1 + strspn(cmd + 1, " \t");
- else
- optarg = NULL;
-
- blank_loc = strcspn(cmd, " \t");
- if (blank_loc == 0 || !cmd[blank_loc])
- optarg2 = NULL;
- else
- optarg2 = cmd + blank_loc + strspn(cmd + blank_loc, " \t");
-
- switch (cmd[0]) {
- case 'a': /* toggles to align fields on output */
- toggle(settings, &settings->opt.align, "field alignment");
- break;
- case 'C': /* define new caption */
- if (settings->opt.caption)
- {
- free(settings->opt.caption);
- settings->opt.caption = NULL;
- }
- if (optarg && !(settings->opt.caption = strdup(optarg))) {
- perror("malloc");
- exit(CMD_TERMINATE);
- }
- break;
- case 'c':{
- if (strncmp(cmd, "copy ", strlen("copy ")) == 0)
- do_copy(optarg2, settings);
- else if (strncmp(cmd, "connect ", strlen("connect ")) == 0 ||
- strcmp(cmd, "connect") == 0 /* issue error message */) {
- char *optarg3 = NULL;
- int blank_loc2;
-
- if (optarg2) {
- blank_loc2 = strcspn(optarg2, " \t");
- if (blank_loc2 == 0 || *(optarg2 + blank_loc2) == '\0')
- optarg3 = NULL;
- else {
- optarg3 = optarg2 + blank_loc2 +
- strspn(optarg2 + blank_loc2, " \t");
- *(optarg2 + blank_loc2) = '\0';
- }
- }
- do_connect(optarg2, optarg3, settings);
- }
- else {
- char *optarg3 = NULL;
- int blank_loc2;
-
- if (optarg) {
- blank_loc2 = strcspn(optarg, " \t");
- if (blank_loc2 == 0 || *(optarg + blank_loc2) == '\0')
- optarg3 = NULL;
- else {
- optarg3 = optarg + blank_loc2 +
- strspn(optarg + blank_loc2, " \t");
- *(optarg + blank_loc2) = '\0';
- }
- }
- do_connect(optarg, optarg3, settings);
- }
- }
- break;
- case 'd': /* \d describe tables or columns in a table */
- if (strncmp(cmd, "dt", 2) == 0) { /* only tables */
- tableList(settings, 0, 't');
- } else if (strncmp(cmd, "di", 2) == 0) { /* only indices */
- tableList(settings, 0, 'i');
- } else if (strncmp(cmd, "ds", 2) == 0) { /* only sequences */
- tableList(settings, 0, 'S');
- } else if (!optarg) { /* show tables, sequences and indices */
- tableList(settings, 0, 'b');
- } else if (strcmp(optarg, "*") == 0) { /* show everything */
- if (tableList(settings, 0, 'b') == 0)
- tableList(settings, 1, 'b');
- } else { /* describe the specified table */
- tableDesc(settings, optarg);
- }
- break;
- case 'e': /* edit */
- {
- do_edit(optarg, query, &status);
- break;
- }
- case 'E':
+ int status = CMD_SKIP_LINE;
+ char *optarg;
+
+ /*
+ * Pointer inside the <cmd> string to the argument of the slash
+ * command, assuming it is a one-character slash command. If it's not
+ * a one-character command, this is meaningless.
+ */
+ char *optarg2;
+
+ /*
+ * Pointer inside the <cmd> string to the argument of the slash
+ * command assuming it's not a one-character command. If it's a
+ * one-character command, this is meaningless.
+ */
+ char *cmd;
+
+ /*
+ * String: value of the slash command, less the slash and with escape
+ * sequences decoded.
+ */
+ int blank_loc;
+
+ /* Offset within <cmd> of first blank */
+
+ cmd = malloc(strlen(line)); /* unescaping better not make string grow. */
+
+ unescape(cmd, line + 1); /* sets cmd string */
+
+ if (strlen(cmd) >= 1 && cmd[strlen(cmd) - 1] == ';') /* strip trailing ; */
+ cmd[strlen(cmd) - 1] = '\0';
+
+ /*
+ * Originally, there were just single character commands. Now, we
+ * define some longer, friendly commands, but we have to keep the old
+ * single character commands too. \c used to be what \connect is now.
+ * Complicating matters is the fact that with the single-character
+ * commands, you can start the argument right after the single
+ * character, so "\copy" would mean "connect to database named 'opy'".
+ */
+
+ if (strlen(cmd) > 1)
+ optarg = cmd + 1 + strspn(cmd + 1, " \t");
+ else
+ optarg = NULL;
+
+ blank_loc = strcspn(cmd, " \t");
+ if (blank_loc == 0 || !cmd[blank_loc])
+ optarg2 = NULL;
+ else
+ optarg2 = cmd + blank_loc + strspn(cmd + blank_loc, " \t");
+
+ switch (cmd[0])
{
- FILE *fd;
- static char *lastfile;
- struct stat st, st2;
- if (optarg) {
- if (lastfile)
- free(lastfile);
- lastfile = malloc(strlen(optarg + 1));
- if (!lastfile) {
- perror("malloc");
- exit(CMD_TERMINATE);
- }
- strcpy(lastfile, optarg);
- } else if (!lastfile) {
- fprintf(stderr, "\\r must be followed by a file name initially\n");
+ case 'a': /* toggles to align fields on output */
+ toggle(settings, &settings->opt.align, "field alignment");
break;
- }
- stat(lastfile, &st);
- editFile(lastfile);
- if ((stat(lastfile, &st2) == -1) || ((fd = fopen(lastfile, "r")) == NULL)) {
- perror(lastfile);
+ case 'C': /* define new caption */
+ if (settings->opt.caption)
+ {
+ free(settings->opt.caption);
+ settings->opt.caption = NULL;
+ }
+ if (optarg && !(settings->opt.caption = strdup(optarg)))
+ {
+ perror("malloc");
+ exit(CMD_TERMINATE);
+ }
break;
- }
- if (st2.st_mtime == st.st_mtime) {
- if (!settings->quiet)
- fprintf(stderr, "warning: %s not modified. query not executed\n", lastfile);
- fclose(fd);
+ case 'c':
+ {
+ if (strncmp(cmd, "copy ", strlen("copy ")) == 0)
+ do_copy(optarg2, settings);
+ else if (strncmp(cmd, "connect ", strlen("connect ")) == 0 ||
+ strcmp(cmd, "connect") == 0 /* issue error message */ )
+ {
+ char *optarg3 = NULL;
+ int blank_loc2;
+
+ if (optarg2)
+ {
+ blank_loc2 = strcspn(optarg2, " \t");
+ if (blank_loc2 == 0 || *(optarg2 + blank_loc2) == '\0')
+ optarg3 = NULL;
+ else
+ {
+ optarg3 = optarg2 + blank_loc2 +
+ strspn(optarg2 + blank_loc2, " \t");
+ *(optarg2 + blank_loc2) = '\0';
+ }
+ }
+ do_connect(optarg2, optarg3, settings);
+ }
+ else
+ {
+ char *optarg3 = NULL;
+ int blank_loc2;
+
+ if (optarg)
+ {
+ blank_loc2 = strcspn(optarg, " \t");
+ if (blank_loc2 == 0 || *(optarg + blank_loc2) == '\0')
+ optarg3 = NULL;
+ else
+ {
+ optarg3 = optarg + blank_loc2 +
+ strspn(optarg + blank_loc2, " \t");
+ *(optarg + blank_loc2) = '\0';
+ }
+ }
+ do_connect(optarg, optarg3, settings);
+ }
+ }
break;
- }
- MainLoop(settings, fd);
- fclose(fd);
- break;
- }
- case 'f':
- {
- char *fs = DEFAULT_FIELD_SEP;
- if (optarg)
- fs = optarg;
- if (settings->opt.fieldSep)
- free(settings->opt.fieldSep);
- if (!(settings->opt.fieldSep = strdup(fs))) {
- perror("malloc");
- exit(CMD_TERMINATE);
- }
- if (!settings->quiet)
- printf("field separator changed to '%s'\n", settings->opt.fieldSep);
- break;
- }
- case 'g': /* \g means send query */
- if (!optarg)
- settings->gfname = NULL;
- else if (!(settings->gfname = strdup(optarg))) {
- perror("malloc");
- exit(CMD_TERMINATE);
- }
- status = CMD_SEND;
- break;
- case 'h': /* help */
- {
- do_help(settings, optarg);
- break;
- }
- case 'i': /* \i is include file */
- {
- FILE *fd;
+ case 'd': /* \d describe tables or columns in a
+ * table */
+ if (strncmp(cmd, "dt", 2) == 0)
+ { /* only tables */
+ tableList(settings, 0, 't');
+ }
+ else if (strncmp(cmd, "di", 2) == 0)
+ { /* only indices */
+ tableList(settings, 0, 'i');
+ }
+ else if (strncmp(cmd, "ds", 2) == 0)
+ { /* only sequences */
+ tableList(settings, 0, 'S');
+ }
+ else if (!optarg)
+ { /* show tables, sequences and indices */
+ tableList(settings, 0, 'b');
+ }
+ else if (strcmp(optarg, "*") == 0)
+ { /* show everything */
+ if (tableList(settings, 0, 'b') == 0)
+ tableList(settings, 1, 'b');
+ }
+ else
+ { /* describe the specified table */
+ tableDesc(settings, optarg);
+ }
+ break;
+ case 'e': /* edit */
+ {
+ do_edit(optarg, query, &status);
+ break;
+ }
+ case 'E':
+ {
+ FILE *fd;
+ static char *lastfile;
+ struct stat st,
+ st2;
+
+ if (optarg)
+ {
+ if (lastfile)
+ free(lastfile);
+ lastfile = malloc(strlen(optarg + 1));
+ if (!lastfile)
+ {
+ perror("malloc");
+ exit(CMD_TERMINATE);
+ }
+ strcpy(lastfile, optarg);
+ }
+ else if (!lastfile)
+ {
+ fprintf(stderr, "\\r must be followed by a file name initially\n");
+ break;
+ }
+ stat(lastfile, &st);
+ editFile(lastfile);
+ if ((stat(lastfile, &st2) == -1) || ((fd = fopen(lastfile, "r")) == NULL))
+ {
+ perror(lastfile);
+ break;
+ }
+ if (st2.st_mtime == st.st_mtime)
+ {
+ if (!settings->quiet)
+ fprintf(stderr, "warning: %s not modified. query not executed\n", lastfile);
+ fclose(fd);
+ break;
+ }
+ MainLoop(settings, fd);
+ fclose(fd);
+ break;
+ }
+ case 'f':
+ {
+ char *fs = DEFAULT_FIELD_SEP;
+
+ if (optarg)
+ fs = optarg;
+ if (settings->opt.fieldSep)
+ free(settings->opt.fieldSep);
+ if (!(settings->opt.fieldSep = strdup(fs)))
+ {
+ perror("malloc");
+ exit(CMD_TERMINATE);
+ }
+ if (!settings->quiet)
+ printf("field separator changed to '%s'\n", settings->opt.fieldSep);
+ break;
+ }
+ case 'g': /* \g means send query */
+ if (!optarg)
+ settings->gfname = NULL;
+ else if (!(settings->gfname = strdup(optarg)))
+ {
+ perror("malloc");
+ exit(CMD_TERMINATE);
+ }
+ status = CMD_SEND;
+ break;
+ case 'h': /* help */
+ {
+ do_help(settings, optarg);
+ break;
+ }
+ case 'i': /* \i is include file */
+ {
+ FILE *fd;
- if (!optarg) {
- fprintf(stderr, "\\i must be followed by a file name\n");
+ if (!optarg)
+ {
+ fprintf(stderr, "\\i must be followed by a file name\n");
+ break;
+ }
+ if ((fd = fopen(optarg, "r")) == NULL)
+ {
+ fprintf(stderr, "file named %s could not be opened\n", optarg);
+ break;
+ }
+ MainLoop(settings, fd);
+ fclose(fd);
+ break;
+ }
+ case 'l': /* \l is list database */
+ listAllDbs(settings);
break;
- }
- if ((fd = fopen(optarg, "r")) == NULL) {
- fprintf(stderr, "file named %s could not be opened\n", optarg);
+ case 'H':
+ if (toggle(settings, &settings->opt.html3, "HTML3.0 tabular output"))
+ settings->opt.standard = 0;
break;
- }
- MainLoop(settings, fd);
- fclose(fd);
- break;
- }
- case 'l': /* \l is list database */
- listAllDbs(settings);
- break;
- case 'H':
- if (toggle(settings, &settings->opt.html3, "HTML3.0 tabular output"))
- settings->opt.standard = 0;
- break;
- case 'o':
- setFout(settings, optarg);
- break;
- case 'p':
- if (query) {
- fputs(query, stdout);
- fputc('\n', stdout);
- }
- break;
- case 'q': /* \q is quit */
- status = CMD_TERMINATE;
- break;
- case 'r': /* reset(clear) the buffer */
- query[0] = '\0';
- if (!settings->quiet)
- printf("buffer reset(cleared)\n");
- break;
- case 's': /* \s is save history to a file */
- if (!optarg)
- optarg = "/dev/tty";
+ case 'o':
+ setFout(settings, optarg);
+ break;
+ case 'p':
+ if (query)
+ {
+ fputs(query, stdout);
+ fputc('\n', stdout);
+ }
+ break;
+ case 'q': /* \q is quit */
+ status = CMD_TERMINATE;
+ break;
+ case 'r': /* reset(clear) the buffer */
+ query[0] = '\0';
+ if (!settings->quiet)
+ printf("buffer reset(cleared)\n");
+ break;
+ case 's': /* \s is save history to a file */
+ if (!optarg)
+ optarg = "/dev/tty";
#ifdef HAVE_HISTORY
- if (write_history(optarg) != 0)
- fprintf(stderr, "cannot write history to %s\n", optarg);
+ if (write_history(optarg) != 0)
+ fprintf(stderr, "cannot write history to %s\n", optarg);
#endif
- break;
- case 'm': /* monitor like type-setting */
- if (toggle(settings, &settings->opt.standard, "standard SQL separaters and padding")) {
- settings->opt.html3 = settings->opt.expanded = 0;
- settings->opt.align = settings->opt.header = 1;
- if (settings->opt.fieldSep)
- free(settings->opt.fieldSep);
- settings->opt.fieldSep = strdup("|");
- if (!settings->quiet)
- printf("field separator changed to '%s'\n", settings->opt.fieldSep);
- } else {
- if (settings->opt.fieldSep)
- free(settings->opt.fieldSep);
- settings->opt.fieldSep = strdup(DEFAULT_FIELD_SEP);
- if (!settings->quiet)
- printf("field separator changed to '%s'\n", settings->opt.fieldSep);
- }
- break;
- case 'z': /* list table rights (grant/revoke) */
- rightsList(settings);
- break;
- case 't': /* toggle headers */
- toggle(settings, &settings->opt.header, "output headings and row count");
- break;
- case 'T': /* define html <table ...> option */
- if (settings->opt.tableOpt)
- free(settings->opt.tableOpt);
- if (!optarg)
- settings->opt.tableOpt = NULL;
- else if (!(settings->opt.tableOpt = strdup(optarg))) {
- perror("malloc");
- exit(CMD_TERMINATE);
+ break;
+ case 'm': /* monitor like type-setting */
+ if (toggle(settings, &settings->opt.standard, "standard SQL separaters and padding"))
+ {
+ settings->opt.html3 = settings->opt.expanded = 0;
+ settings->opt.align = settings->opt.header = 1;
+ if (settings->opt.fieldSep)
+ free(settings->opt.fieldSep);
+ settings->opt.fieldSep = strdup("|");
+ if (!settings->quiet)
+ printf("field separator changed to '%s'\n", settings->opt.fieldSep);
+ }
+ else
+ {
+ if (settings->opt.fieldSep)
+ free(settings->opt.fieldSep);
+ settings->opt.fieldSep = strdup(DEFAULT_FIELD_SEP);
+ if (!settings->quiet)
+ printf("field separator changed to '%s'\n", settings->opt.fieldSep);
+ }
+ break;
+ case 'z': /* list table rights (grant/revoke) */
+ rightsList(settings);
+ break;
+ case 't': /* toggle headers */
+ toggle(settings, &settings->opt.header, "output headings and row count");
+ break;
+ case 'T': /* define html <table ...> option */
+ if (settings->opt.tableOpt)
+ free(settings->opt.tableOpt);
+ if (!optarg)
+ settings->opt.tableOpt = NULL;
+ else if (!(settings->opt.tableOpt = strdup(optarg)))
+ {
+ perror("malloc");
+ exit(CMD_TERMINATE);
+ }
+ break;
+ case 'x':
+ toggle(settings, &settings->opt.expanded, "expanded table representation");
+ break;
+ case '!':
+ do_shell(optarg);
+ break;
+ default:
+ case '?': /* \? is help */
+ slashUsage(settings);
+ break;
}
- break;
- case 'x':
- toggle(settings, &settings->opt.expanded, "expanded table representation");
- break;
- case '!':
- do_shell(optarg);
- break;
- default:
- case '?': /* \? is help */
- slashUsage(settings);
- break;
- }
- free(cmd);
- return status;
-} /* HandleSlashCmds() */
+ free(cmd);
+ return status;
+} /* HandleSlashCmds() */
/* MainLoop()
* Main processing loop for reading lines of input
- * and sending them to the backend.
- *
+ * and sending them to the backend.
+ *
* This loop is re-entrant. May be called by \i command
- * which reads input from a file.
+ * which reads input from a file.
* db_ptr must be initialized and set.
*/
static int
MainLoop(PsqlSettings * settings, FILE * source)
{
- char *line; /* line of input */
- char *xcomment; /* start of extended comment */
- int len; /* length of the line */
- char query[MAX_QUERY_BUFFER]; /* multi-line query storage */
- int successResult = 1;
- int slashCmdStatus = CMD_SEND;
- /*
- * slashCmdStatus can be:
- * CMD_UNKNOWN - send currently constructed query to backend (i.e. we got a \g)
- * CMD_SEND - send currently constructed query to backend (i.e. we got a \g)
- * CMD_SKIP_LINE - skip processing of this line, continue building up query
- * CMD_TERMINATE - terminate processing of this query entirely
- * CMD_NEWEDIT - new query supplied by edit
- */
-
- bool querySent = false;
- bool interactive;
- READ_ROUTINE GetNextLine;
- bool eof = 0;
- /* We've reached the end of our command input. */
- bool success;
- bool in_quote;
- int paren_level;
- char *query_start;
-
- interactive = ((source == stdin) && !settings->notty);
- if (interactive) {
- if (settings->prompt)
- free(settings->prompt);
- settings->prompt =
- malloc(strlen(PQdb(settings->db)) + strlen(PROMPT) + 1);
- if (settings->quiet)
- settings->prompt[0] = '\0';
- else
- sprintf(settings->prompt, "%s%s", PQdb(settings->db), PROMPT);
- if (settings->useReadline) {
-#ifdef HAVE_HISTORY
- using_history();
-#endif
- GetNextLine = gets_readline;
- } else
- GetNextLine = gets_noreadline;
- } else
- GetNextLine = gets_fromFile;
-
- query[0] = '\0';
- xcomment = NULL;
- in_quote = false;
- paren_level = 0;
- slashCmdStatus = CMD_UNKNOWN; /* set default */
-
- /* main loop to get queries and execute them */
- while (!eof) {
- /* just returned from editing the line? then just copy to the input buffer */
- if (slashCmdStatus == CMD_NEWEDIT) {
- paren_level = 0;
- line = strdup(query);
- query[0] = '\0';
-
- /* otherwise, get another line and set interactive prompt if necessary */
- } else {
- if (interactive && !settings->quiet) {
- if (in_quote)
- settings->prompt[strlen(settings->prompt)-3] = PROMPT_QUOTE;
- else if (xcomment != NULL)
- settings->prompt[strlen(settings->prompt)-3] = PROMPT_COMMENT;
- else if (query[0] != '\0' && !querySent)
- settings->prompt[strlen(settings->prompt)-3] = PROMPT_CONTINUE;
+ char *line; /* line of input */
+ char *xcomment; /* start of extended comment */
+ int len; /* length of the line */
+ char query[MAX_QUERY_BUFFER]; /* multi-line query
+ * storage */
+ int successResult = 1;
+ int slashCmdStatus = CMD_SEND;
+
+ /*
+ * slashCmdStatus can be: CMD_UNKNOWN - send currently constructed
+ * query to backend (i.e. we got a \g) CMD_SEND - send
+ * currently constructed query to backend (i.e. we got a \g)
+ * CMD_SKIP_LINE - skip processing of this line, continue building
+ * up query CMD_TERMINATE - terminate processing of this query
+ * entirely CMD_NEWEDIT - new query supplied by edit
+ */
+
+ bool querySent = false;
+ bool interactive;
+ READ_ROUTINE GetNextLine;
+ bool eof = 0;
+
+ /* We've reached the end of our command input. */
+ bool success;
+ bool in_quote;
+ int paren_level;
+ char *query_start;
+
+ interactive = ((source == stdin) && !settings->notty);
+ if (interactive)
+ {
+ if (settings->prompt)
+ free(settings->prompt);
+ settings->prompt =
+ malloc(strlen(PQdb(settings->db)) + strlen(PROMPT) + 1);
+ if (settings->quiet)
+ settings->prompt[0] = '\0';
else
- settings->prompt[strlen(settings->prompt)-3] = PROMPT_READY;
- }
- line = GetNextLine(settings->prompt, source);
+ sprintf(settings->prompt, "%s%s", PQdb(settings->db), PROMPT);
+ if (settings->useReadline)
+ {
#ifdef HAVE_HISTORY
- if (interactive && settings->useReadline && line != NULL)
- add_history(line); /* save non-empty lines in history */
+ using_history();
#endif
+ GetNextLine = gets_readline;
+ }
+ else
+ GetNextLine = gets_noreadline;
}
+ else
+ GetNextLine = gets_fromFile;
- /* query - pointer to current command
- * query_start - placeholder for next command
- */
+ query[0] = '\0';
+ xcomment = NULL;
+ in_quote = false;
+ paren_level = 0;
+ slashCmdStatus = CMD_UNKNOWN; /* set default */
- /* not currently inside an extended comment? */
- if (xcomment == NULL) {
- query_start = line;
-
- /* otherwise, continue the extended comment... */
- } else {
- query_start = line;
- xcomment = line;
- };
-
- if (line == NULL) { /* No more input. Time to quit */
- if (!settings->quiet)
- printf("EOF\n"); /* Goes on prompt line */
- eof = true;
- } else {
- /* remove whitespaces on the right, incl. \n's */
- line = rightTrim(line);
-
- /* echo back if input is from file */
- if (!interactive && !settings->singleStep && !settings->quiet)
- fprintf(stderr, "%s\n", line);
-
- /* nothing on line after trimming? then ignore */
- if (line[0] == '\0') {
- free(line);
- continue;
- }
+ /* main loop to get queries and execute them */
+ while (!eof)
+ {
- len = strlen(line);
+ /*
+ * just returned from editing the line? then just copy to the
+ * input buffer
+ */
+ if (slashCmdStatus == CMD_NEWEDIT)
+ {
+ paren_level = 0;
+ line = strdup(query);
+ query[0] = '\0';
- if (settings->singleLineMode) {
- SendQuery(&success, settings, line, false, false, 0);
- successResult &= success;
- querySent = true;
+ /*
+ * otherwise, get another line and set interactive prompt if
+ * necessary
+ */
+ }
+ else
+ {
+ if (interactive && !settings->quiet)
+ {
+ if (in_quote)
+ settings->prompt[strlen(settings->prompt) - 3] = PROMPT_QUOTE;
+ else if (xcomment != NULL)
+ settings->prompt[strlen(settings->prompt) - 3] = PROMPT_COMMENT;
+ else if (query[0] != '\0' && !querySent)
+ settings->prompt[strlen(settings->prompt) - 3] = PROMPT_CONTINUE;
+ else
+ settings->prompt[strlen(settings->prompt) - 3] = PROMPT_READY;
+ }
+ line = GetNextLine(settings->prompt, source);
+#ifdef HAVE_HISTORY
+ if (interactive && settings->useReadline && line != NULL)
+ add_history(line); /* save non-empty lines in history */
+#endif
+ }
- } else {
- int i;
+ /*
+ * query - pointer to current command query_start - placeholder
+ * for next command
+ */
- for (i = 0; i < len; i++) {
- if (querySent && !isspace(line[i])) {
- query[0] = '\0';
- querySent = false;
- }
-
- /* inside a quote? */
- if (in_quote && (line[i] != '\'')) {
- continue;
-
- /* inside an extended comment? */
- } else if (xcomment != NULL) {
- if (line[i] == '*' && line[i+1] == '/') {
- xcomment = NULL;
- i++;
- };
- continue;
-
- /* possible backslash command? */
- } else if (line[i] == '\\') {
- char hold_char = line[i];
-
- line[i] = '\0';
- if (query_start[0] != '\0') {
- if (query[0] != '\0') {
- strcat(query, "\n");
- strcat(query, query_start);
- } else {
- strcpy(query, query_start);
- };
- }
- line[i] = hold_char;
- query_start = line + i;
- break; /* handle command */
+ /* not currently inside an extended comment? */
+ if (xcomment == NULL)
+ {
+ query_start = line;
- /* start an extended comment? */
- } else if (line[i] == '/' && line[i+1] == '*') {
- xcomment = line + i;
- i++;
- continue;
-
- /* single-line comment? truncate line */
- } else if ((line[i] == '-' && line[i+1] == '-') ||
- (line[i] == '/' && line[i+1] == '/')) {
- /* print comment at top of query */
- if (settings->singleStep)
- fprintf(stdout, "%s\n", line + i);
- line[i] = '\0'; /* remove comment */
- break;
+ /* otherwise, continue the extended comment... */
+ }
+ else
+ {
+ query_start = line;
+ xcomment = line;
+ };
+
+ if (line == NULL)
+ { /* No more input. Time to quit */
+ if (!settings->quiet)
+ printf("EOF\n");/* Goes on prompt line */
+ eof = true;
+ }
+ else
+ {
+ /* remove whitespaces on the right, incl. \n's */
+ line = rightTrim(line);
+
+ /* echo back if input is from file */
+ if (!interactive && !settings->singleStep && !settings->quiet)
+ fprintf(stderr, "%s\n", line);
+
+ /* nothing on line after trimming? then ignore */
+ if (line[0] == '\0')
+ {
+ free(line);
+ continue;
+ }
- } else if (line[i] == '\'') {
- in_quote ^= 1;
+ len = strlen(line);
- /* semi-colon? then send query now */
- } else if (!paren_level && line[i] == ';') {
- char hold_char = line[i + 1];
+ if (settings->singleLineMode)
+ {
+ SendQuery(&success, settings, line, false, false, 0);
+ successResult &= success;
+ querySent = true;
- line[i + 1] = '\0';
- if (query_start[0] != '\0') {
- if (query[0] != '\0') {
- strcat(query, "\n");
- strcat(query, query_start);
- } else
- strcpy(query, query_start);
}
- SendQuery(&success, settings, query, false, false, 0);
- successResult &= success;
- line[i + 1] = hold_char;
- query_start = line + i + 1;
- querySent = true;
+ else
+ {
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ if (querySent && !isspace(line[i]))
+ {
+ query[0] = '\0';
+ querySent = false;
+ }
+
+ /* inside a quote? */
+ if (in_quote && (line[i] != '\''))
+ {
+ continue;
+
+ /* inside an extended comment? */
+ }
+ else if (xcomment != NULL)
+ {
+ if (line[i] == '*' && line[i + 1] == '/')
+ {
+ xcomment = NULL;
+ i++;
+ };
+ continue;
+
+ /* possible backslash command? */
+ }
+ else if (line[i] == '\\')
+ {
+ char hold_char = line[i];
+
+ line[i] = '\0';
+ if (query_start[0] != '\0')
+ {
+ if (query[0] != '\0')
+ {
+ strcat(query, "\n");
+ strcat(query, query_start);
+ }
+ else
+ {
+ strcpy(query, query_start);
+ };
+ }
+ line[i] = hold_char;
+ query_start = line + i;
+ break; /* handle command */
+
+ /* start an extended comment? */
+ }
+ else if (line[i] == '/' && line[i + 1] == '*')
+ {
+ xcomment = line + i;
+ i++;
+ continue;
+
+ /* single-line comment? truncate line */
+ }
+ else if ((line[i] == '-' && line[i + 1] == '-') ||
+ (line[i] == '/' && line[i + 1] == '/'))
+ {
+ /* print comment at top of query */
+ if (settings->singleStep)
+ fprintf(stdout, "%s\n", line + i);
+ line[i] = '\0'; /* remove comment */
+ break;
+
+ }
+ else if (line[i] == '\'')
+ {
+ in_quote ^= 1;
+
+ /* semi-colon? then send query now */
+ }
+ else if (!paren_level && line[i] == ';')
+ {
+ char hold_char = line[i + 1];
+
+ line[i + 1] = '\0';
+ if (query_start[0] != '\0')
+ {
+ if (query[0] != '\0')
+ {
+ strcat(query, "\n");
+ strcat(query, query_start);
+ }
+ else
+ strcpy(query, query_start);
+ }
+ SendQuery(&success, settings, query, false, false, 0);
+ successResult &= success;
+ line[i + 1] = hold_char;
+ query_start = line + i + 1;
+ querySent = true;
+
+ }
+ else if (line[i] == '(')
+ {
+ paren_level++;
+
+ }
+ else if (paren_level && line[i] == ')')
+ {
+ paren_level--;
+ };
+ }
+ }
- } else if (line[i] == '(') {
- paren_level++;
+ /* nothing on line after trimming? then ignore */
+ if (line[0] == '\0')
+ {
+ free(line);
+ continue;
+ }
- } else if (paren_level && line[i] == ')') {
- paren_level--;
- };
- }
- }
+ slashCmdStatus = CMD_UNKNOWN;
+ if (!in_quote && query_start[0] == '\\')
+ {
+ slashCmdStatus = HandleSlashCmds(settings,
+ query_start,
+ query);
+ if (slashCmdStatus == CMD_SKIP_LINE)
+ {
+ if (query[0] == '\0')
+ paren_level = 0;
+ free(line);
+ continue;
+ }
+ if (slashCmdStatus == CMD_TERMINATE)
+ {
+ free(line);
+ break;
+ }
+ free(line);
+ }
+ else if (strlen(query) + strlen(query_start) > MAX_QUERY_BUFFER)
+ {
+ fprintf(stderr, "query buffer max length of %d exceeded\n",
+ MAX_QUERY_BUFFER);
+ fprintf(stderr, "query line ignored\n");
+ free(line);
+ }
+ else
+ {
+ if (query_start[0] != '\0')
+ {
+
+ querySent = false;
+ if (query[0] != '\0')
+ {
+ strcat(query, "\n");
+ strcat(query, query_start);
+ }
+ else
+ strcpy(query, query_start);
+ }
+ free(line); /* PURIFY */
+ }
- /* nothing on line after trimming? then ignore */
- if (line[0] == '\0') {
- free(line);
- continue;
- }
-
- slashCmdStatus = CMD_UNKNOWN;
- if (!in_quote && query_start[0] == '\\') {
- slashCmdStatus = HandleSlashCmds(settings,
- query_start,
- query);
- if (slashCmdStatus == CMD_SKIP_LINE) {
- if (query[0] == '\0')
- paren_level = 0;
- free(line);
- continue;
- }
- if (slashCmdStatus == CMD_TERMINATE) {
- free(line);
- break;
- }
- free(line);
- } else if (strlen(query) + strlen(query_start) > MAX_QUERY_BUFFER) {
- fprintf(stderr, "query buffer max length of %d exceeded\n",
- MAX_QUERY_BUFFER);
- fprintf(stderr, "query line ignored\n");
- free (line);
- } else {
- if (query_start[0] != '\0') {
-
- querySent = false;
- if (query[0] != '\0') {
- strcat(query, "\n");
- strcat(query, query_start);
- } else
- strcpy(query, query_start);
- }
- free(line); /* PURIFY */
- }
-
- /* had a backslash-g? force the query to be sent */
- if (slashCmdStatus == CMD_SEND) {
+ /* had a backslash-g? force the query to be sent */
+ if (slashCmdStatus == CMD_SEND)
+ {
#if FALSE
- if (! querySent) {
- SendQuery(&success, settings, query, false, false, 0);
- successResult &= success;
- }
+ if (!querySent)
+ {
+ SendQuery(&success, settings, query, false, false, 0);
+ successResult &= success;
+ }
#else
- SendQuery(&success, settings, query, false, false, 0);
- successResult &= success;
+ SendQuery(&success, settings, query, false, false, 0);
+ successResult &= success;
#endif
- querySent = true;
- }
- }
- } /* while */
- return successResult;
-} /* MainLoop() */
+ querySent = true;
+ }
+ }
+ } /* while */
+ return successResult;
+} /* MainLoop() */
int
main(int argc, char **argv)
{
- extern char *optarg;
- extern int optind;
-
- char *dbname = NULL;
- char *host = NULL;
- char *port = NULL;
- char *qfilename = NULL;
- char errbuf[ERROR_MSG_LENGTH];
-
- PsqlSettings settings;
-
- char *singleQuery = NULL;
-
- bool listDatabases = 0;
- int successResult = 1;
- bool singleSlashCmd = 0;
- int c;
-
- memset(&settings, 0, sizeof settings);
- settings.opt.align = 1;
- settings.opt.header = 1;
- settings.queryFout = stdout;
- settings.opt.fieldSep = strdup(DEFAULT_FIELD_SEP);
- settings.opt.pager = 1;
- if (!isatty(0) || !isatty(1))
- settings.quiet = settings.notty = 1;
+ extern char *optarg;
+ extern int optind;
+
+ char *dbname = NULL;
+ char *host = NULL;
+ char *port = NULL;
+ char *qfilename = NULL;
+ char errbuf[ERROR_MSG_LENGTH];
+
+ PsqlSettings settings;
+
+ char *singleQuery = NULL;
+
+ bool listDatabases = 0;
+ int successResult = 1;
+ bool singleSlashCmd = 0;
+ int c;
+
+ memset(&settings, 0, sizeof settings);
+ settings.opt.align = 1;
+ settings.opt.header = 1;
+ settings.queryFout = stdout;
+ settings.opt.fieldSep = strdup(DEFAULT_FIELD_SEP);
+ settings.opt.pager = 1;
+ if (!isatty(0) || !isatty(1))
+ settings.quiet = settings.notty = 1;
#ifdef HAVE_LIBREADLINE
- else
- settings.useReadline = 1;
+ else
+ settings.useReadline = 1;
#endif
#ifdef PSQL_ALWAYS_GET_PASSWORDS
- settings.getPassword = 1;
+ settings.getPassword = 1;
#else
- settings.getPassword = 0;
+ settings.getPassword = 0;
#endif
- while ((c = getopt(argc, argv, "Aa:c:d:ef:F:lh:Hnso:p:qStT:ux")) != EOF) {
- switch (c) {
- case 'A':
- settings.opt.align = 0;
- break;
- case 'a':
- fe_setauthsvc(optarg, errbuf);
- break;
- case 'c':
- singleQuery = strdup(optarg);
- if (singleQuery[0] == '\\') {
- singleSlashCmd = 1;
- }
- break;
- case 'd':
- dbname = optarg;
- break;
- case 'e':
- settings.echoQuery = 1;
- break;
- case 'f':
- qfilename = optarg;
- break;
- case 'F':
- settings.opt.fieldSep = strdup(optarg);
- break;
- case 'l':
- listDatabases = 1;
- break;
- case 'h':
- host = optarg;
- break;
- case 'H':
- settings.opt.html3 = 1;
- break;
- case 'n':
- settings.useReadline = 0;
- break;
- case 'o':
- setFout(&settings, optarg);
- break;
- case 'p':
- port = optarg;
- break;
- case 'q':
- settings.quiet = 1;
- break;
- case 's':
- settings.singleStep = 1;
- break;
- case 'S':
- settings.singleLineMode = 1;
- break;
- case 't':
- settings.opt.header = 0;
- break;
- case 'T':
- settings.opt.tableOpt = strdup(optarg);
- break;
- case 'u':
- settings.getPassword = 1;
- break;
- case 'x':
- settings.opt.expanded = 1;
- break;
- default:
- usage(argv[0]);
- break;
+ while ((c = getopt(argc, argv, "Aa:c:d:ef:F:lh:Hnso:p:qStT:ux")) != EOF)
+ {
+ switch (c)
+ {
+ case 'A':
+ settings.opt.align = 0;
+ break;
+ case 'a':
+ fe_setauthsvc(optarg, errbuf);
+ break;
+ case 'c':
+ singleQuery = strdup(optarg);
+ if (singleQuery[0] == '\\')
+ {
+ singleSlashCmd = 1;
+ }
+ break;
+ case 'd':
+ dbname = optarg;
+ break;
+ case 'e':
+ settings.echoQuery = 1;
+ break;
+ case 'f':
+ qfilename = optarg;
+ break;
+ case 'F':
+ settings.opt.fieldSep = strdup(optarg);
+ break;
+ case 'l':
+ listDatabases = 1;
+ break;
+ case 'h':
+ host = optarg;
+ break;
+ case 'H':
+ settings.opt.html3 = 1;
+ break;
+ case 'n':
+ settings.useReadline = 0;
+ break;
+ case 'o':
+ setFout(&settings, optarg);
+ break;
+ case 'p':
+ port = optarg;
+ break;
+ case 'q':
+ settings.quiet = 1;
+ break;
+ case 's':
+ settings.singleStep = 1;
+ break;
+ case 'S':
+ settings.singleLineMode = 1;
+ break;
+ case 't':
+ settings.opt.header = 0;
+ break;
+ case 'T':
+ settings.opt.tableOpt = strdup(optarg);
+ break;
+ case 'u':
+ settings.getPassword = 1;
+ break;
+ case 'x':
+ settings.opt.expanded = 1;
+ break;
+ default:
+ usage(argv[0]);
+ break;
+ }
}
- }
- /* if we still have an argument, use it as the database name */
- if (argc - optind == 1)
- dbname = argv[optind];
-
- if (listDatabases)
- dbname = "template1";
-
- if(settings.getPassword) {
- char username[9];
- char password[9];
- char *connect_string;
-
- prompt_for_password(username, password);
-
- /* now use PQconnectdb so we can pass these options */
- connect_string = make_connect_string(host, port, dbname, username, password);
- settings.db = PQconnectdb(connect_string);
- free(connect_string);
- } else {
- settings.db = PQsetdb(host, port, NULL, NULL, dbname);
- }
-
- dbname = PQdb(settings.db);
-
- if (PQstatus(settings.db) == CONNECTION_BAD) {
- fprintf(stderr, "Connection to database '%s' failed.\n", dbname);
- fprintf(stderr, "%s", PQerrorMessage(settings.db));
- PQfinish(settings.db);
- exit(1);
- }
- if (listDatabases) {
- exit(listAllDbs(&settings));
- }
- if (!settings.quiet && !singleQuery && !qfilename) {
- printf("Welcome to the POSTGRESQL interactive sql monitor:\n");
- printf(" Please read the file COPYRIGHT for copyright terms "
- "of POSTGRESQL\n\n");
- printf(" type \\? for help on slash commands\n");
- printf(" type \\q to quit\n");
- printf(" type \\g or terminate with semicolon to execute query\n");
- printf(" You are currently connected to the database: %s\n\n", dbname);
- }
- if (qfilename || singleSlashCmd) {
- /*
- * read in a file full of queries instead of reading in queries
- * interactively
- */
- char *line;
-
- if (singleSlashCmd) {
- /* Not really a query, but "Do what I mean, not what I say." */
- line = singleQuery;
- } else {
- line = malloc(strlen(qfilename) + 5);
- sprintf(line, "\\i %s", qfilename);
+ /* if we still have an argument, use it as the database name */
+ if (argc - optind == 1)
+ dbname = argv[optind];
+
+ if (listDatabases)
+ dbname = "template1";
+
+ if (settings.getPassword)
+ {
+ char username[9];
+ char password[9];
+ char *connect_string;
+
+ prompt_for_password(username, password);
+
+ /* now use PQconnectdb so we can pass these options */
+ connect_string = make_connect_string(host, port, dbname, username, password);
+ settings.db = PQconnectdb(connect_string);
+ free(connect_string);
}
- HandleSlashCmds(&settings, line, "");
- free (line); /* PURIFY */
- } else {
- if (singleQuery) {
- bool success; /* The query succeeded at the backend */
- SendQuery(&success, &settings, singleQuery, false, false, 0);
- successResult = success;
- } else
- successResult = MainLoop(&settings, stdin);
- }
-
- PQfinish(settings.db);
- free(settings.opt.fieldSep); /* PURIFY */
- if(settings.prompt) free(settings.prompt); /* PURIFY */
-
- return !successResult;
+ else
+ {
+ settings.db = PQsetdb(host, port, NULL, NULL, dbname);
+ }
+
+ dbname = PQdb(settings.db);
+
+ if (PQstatus(settings.db) == CONNECTION_BAD)
+ {
+ fprintf(stderr, "Connection to database '%s' failed.\n", dbname);
+ fprintf(stderr, "%s", PQerrorMessage(settings.db));
+ PQfinish(settings.db);
+ exit(1);
+ }
+ if (listDatabases)
+ {
+ exit(listAllDbs(&settings));
+ }
+ if (!settings.quiet && !singleQuery && !qfilename)
+ {
+ printf("Welcome to the POSTGRESQL interactive sql monitor:\n");
+ printf(" Please read the file COPYRIGHT for copyright terms "
+ "of POSTGRESQL\n\n");
+ printf(" type \\? for help on slash commands\n");
+ printf(" type \\q to quit\n");
+ printf(" type \\g or terminate with semicolon to execute query\n");
+ printf(" You are currently connected to the database: %s\n\n", dbname);
+ }
+ if (qfilename || singleSlashCmd)
+ {
+
+ /*
+ * read in a file full of queries instead of reading in queries
+ * interactively
+ */
+ char *line;
+
+ if (singleSlashCmd)
+ {
+ /* Not really a query, but "Do what I mean, not what I say." */
+ line = singleQuery;
+ }
+ else
+ {
+ line = malloc(strlen(qfilename) + 5);
+ sprintf(line, "\\i %s", qfilename);
+ }
+ HandleSlashCmds(&settings, line, "");
+ free(line); /* PURIFY */
+ }
+ else
+ {
+ if (singleQuery)
+ {
+ bool success; /* The query succeeded at the
+ * backend */
+
+ SendQuery(&success, &settings, singleQuery, false, false, 0);
+ successResult = success;
+ }
+ else
+ successResult = MainLoop(&settings, stdin);
+ }
+
+ PQfinish(settings.db);
+ free(settings.opt.fieldSep);/* PURIFY */
+ if (settings.prompt)
+ free(settings.prompt); /* PURIFY */
+
+ return !successResult;
}
-#define COPYBUFSIZ 8192
+#define COPYBUFSIZ 8192
static void
handleCopyOut(PGresult * res, bool quiet, FILE * copystream)
{
- bool copydone;
- char copybuf[COPYBUFSIZ];
- int ret;
-
- copydone = false; /* Can't be done; haven't started. */
-
- while (!copydone) {
- ret = PQgetline(res->conn, copybuf, COPYBUFSIZ);
-
- if (copybuf[0] == '\\' &&
- copybuf[1] == '.' &&
- copybuf[2] == '\0') {
- copydone = true; /* don't print this... */
- } else {
- fputs(copybuf, copystream);
- switch (ret) {
- case EOF:
- copydone = true;
- /* FALLTHROUGH */
- case 0:
- fputc('\n', copystream);
- break;
- case 1:
- break;
- }
+ bool copydone;
+ char copybuf[COPYBUFSIZ];
+ int ret;
+
+ copydone = false; /* Can't be done; haven't started. */
+
+ while (!copydone)
+ {
+ ret = PQgetline(res->conn, copybuf, COPYBUFSIZ);
+
+ if (copybuf[0] == '\\' &&
+ copybuf[1] == '.' &&
+ copybuf[2] == '\0')
+ {
+ copydone = true; /* don't print this... */
+ }
+ else
+ {
+ fputs(copybuf, copystream);
+ switch (ret)
+ {
+ case EOF:
+ copydone = true;
+ /* FALLTHROUGH */
+ case 0:
+ fputc('\n', copystream);
+ break;
+ case 1:
+ break;
+ }
+ }
}
- }
- fflush(copystream);
- PQendcopy(res->conn);
+ fflush(copystream);
+ PQendcopy(res->conn);
}
@@ -1925,51 +2202,59 @@ handleCopyOut(PGresult * res, bool quiet, FILE * copystream)
static void
handleCopyIn(PGresult * res, const bool mustprompt, FILE * copystream)
{
- bool copydone = false;
- bool firstload;
- bool linedone;
- char copybuf[COPYBUFSIZ];
- char *s;
- int buflen;
- int c;
-
- if (mustprompt) {
- fputs("Enter info followed by a newline\n", stdout);
- fputs("End with a backslash and a "
- "period on a line by itself.\n", stdout);
- }
- while (!copydone) { /* for each input line ... */
- if (mustprompt) {
- fputs(">> ", stdout);
- fflush(stdout);
+ bool copydone = false;
+ bool firstload;
+ bool linedone;
+ char copybuf[COPYBUFSIZ];
+ char *s;
+ int buflen;
+ int c;
+
+ if (mustprompt)
+ {
+ fputs("Enter info followed by a newline\n", stdout);
+ fputs("End with a backslash and a "
+ "period on a line by itself.\n", stdout);
}
- firstload = true;
- linedone = false;
- while (!linedone) { /* for each buffer ... */
- s = copybuf;
- buflen = COPYBUFSIZ;
- for (; buflen > 1 &&
- !(linedone = (c = getc(copystream)) == '\n' || c == EOF);
- --buflen) {
- *s++ = c;
- }
- if (c == EOF) {
- PQputline(res->conn, "\\.");
- copydone = true;
- break;
- }
- *s = '\0';
- PQputline(res->conn, copybuf);
- if (firstload) {
- if (!strcmp(copybuf, "\\.")) {
- copydone = true;
- }
- firstload = false;
- }
+ while (!copydone)
+ { /* for each input line ... */
+ if (mustprompt)
+ {
+ fputs(">> ", stdout);
+ fflush(stdout);
+ }
+ firstload = true;
+ linedone = false;
+ while (!linedone)
+ { /* for each buffer ... */
+ s = copybuf;
+ buflen = COPYBUFSIZ;
+ for (; buflen > 1 &&
+ !(linedone = (c = getc(copystream)) == '\n' || c == EOF);
+ --buflen)
+ {
+ *s++ = c;
+ }
+ if (c == EOF)
+ {
+ PQputline(res->conn, "\\.");
+ copydone = true;
+ break;
+ }
+ *s = '\0';
+ PQputline(res->conn, copybuf);
+ if (firstload)
+ {
+ if (!strcmp(copybuf, "\\."))
+ {
+ copydone = true;
+ }
+ firstload = false;
+ }
+ }
+ PQputline(res->conn, "\n");
}
- PQputline(res->conn, "\n");
- }
- PQendcopy(res->conn);
+ PQendcopy(res->conn);
}
@@ -1978,131 +2263,157 @@ handleCopyIn(PGresult * res, const bool mustprompt, FILE * copystream)
* try to open fname and return a FILE *, if it fails, use stdout, instead
*/
-static FILE *
+static FILE *
setFout(PsqlSettings * ps, char *fname)
{
- if (ps->queryFout && ps->queryFout != stdout) {
- if (ps->pipe)
- pclose(ps->queryFout);
- else
- fclose(ps->queryFout);
- }
- if (!fname) {
- ps->queryFout = stdout;
- pqsignal(SIGPIPE, SIG_DFL);
- }
- else {
- if (*fname == '|') {
- pqsignal(SIGPIPE, SIG_IGN);
- ps->queryFout = popen(fname + 1, "w");
- ps->pipe = 1;
- } else {
- ps->queryFout = fopen(fname, "w");
- pqsignal(SIGPIPE, SIG_DFL);
- ps->pipe = 0;
+ if (ps->queryFout && ps->queryFout != stdout)
+ {
+ if (ps->pipe)
+ pclose(ps->queryFout);
+ else
+ fclose(ps->queryFout);
}
- if (!ps->queryFout) {
- perror(fname);
- ps->queryFout = stdout;
+ if (!fname)
+ {
+ ps->queryFout = stdout;
+ pqsignal(SIGPIPE, SIG_DFL);
}
- }
- return ps->queryFout;
+ else
+ {
+ if (*fname == '|')
+ {
+ pqsignal(SIGPIPE, SIG_IGN);
+ ps->queryFout = popen(fname + 1, "w");
+ ps->pipe = 1;
+ }
+ else
+ {
+ ps->queryFout = fopen(fname, "w");
+ pqsignal(SIGPIPE, SIG_DFL);
+ ps->pipe = 0;
+ }
+ if (!ps->queryFout)
+ {
+ perror(fname);
+ ps->queryFout = stdout;
+ }
+ }
+ return ps->queryFout;
}
-static void prompt_for_password(char *username, char *password)
+static void
+prompt_for_password(char *username, char *password)
{
- int length;
+ int length;
+
#ifdef HAVE_TERMIOS_H
- struct termios t_orig, t;
+ struct termios t_orig,
+ t;
+
#endif
- printf("Username: ");
- fgets(username, 9, stdin);
- length = strlen(username);
- /* skip rest of the line */
- if (length > 0 && username[length-1] != '\n') {
- static char buf[512];
- do {
- fgets(buf, 512, stdin);
- } while (buf[strlen(buf)-1] != '\n');
- }
- if(length > 0 && username[length-1] == '\n') username[length-1] = '\0';
-
- printf("Password: ");
+ printf("Username: ");
+ fgets(username, 9, stdin);
+ length = strlen(username);
+ /* skip rest of the line */
+ if (length > 0 && username[length - 1] != '\n')
+ {
+ static char buf[512];
+
+ do
+ {
+ fgets(buf, 512, stdin);
+ } while (buf[strlen(buf) - 1] != '\n');
+ }
+ if (length > 0 && username[length - 1] == '\n')
+ username[length - 1] = '\0';
+
+ printf("Password: ");
#ifdef HAVE_TERMIOS_H
- tcgetattr(0, &t);
- t_orig = t;
- t.c_lflag &= ~ECHO;
- tcsetattr(0, TCSADRAIN, &t);
+ tcgetattr(0, &t);
+ t_orig = t;
+ t.c_lflag &= ~ECHO;
+ tcsetattr(0, TCSADRAIN, &t);
#endif
- fgets(password, 9, stdin);
+ fgets(password, 9, stdin);
#ifdef HAVE_TERMIOS_H
- tcsetattr(0, TCSADRAIN, &t_orig);
+ tcsetattr(0, TCSADRAIN, &t_orig);
#endif
- length = strlen(password);
- /* skip rest of the line */
- if (length > 0 && password[length-1] != '\n') {
- static char buf[512];
- do {
- fgets(buf, 512, stdin);
- } while (buf[strlen(buf)-1] != '\n');
- }
- if(length > 0 && password[length-1] == '\n') password[length-1] = '\0';
-
- printf("\n\n");
+ length = strlen(password);
+ /* skip rest of the line */
+ if (length > 0 && password[length - 1] != '\n')
+ {
+ static char buf[512];
+
+ do
+ {
+ fgets(buf, 512, stdin);
+ } while (buf[strlen(buf) - 1] != '\n');
+ }
+ if (length > 0 && password[length - 1] == '\n')
+ password[length - 1] = '\0';
+
+ printf("\n\n");
}
-static char *make_connect_string(char *host, char *port, char *dbname,
- char *username, char *password)
+static char *
+make_connect_string(char *host, char *port, char *dbname,
+ char *username, char *password)
{
- int connect_string_len = 0;
- char *connect_string;
-
- if(host)
- connect_string_len += 6 + strlen(host); /* 6 == "host=" + " " */
- if(username)
- connect_string_len += 6 + strlen(username); /* 6 == "user=" + " " */
- if(password)
- connect_string_len += 10 + strlen(password); /* 10 == "password=" + " " */
- if(port)
- connect_string_len += 6 + strlen(port); /* 6 == "port=" + " " */
- if(dbname)
- connect_string_len += 8 + strlen(dbname); /* 8 == "dbname=" + " " */
- connect_string_len += 18; /* "authtype=password" + null */
-
- connect_string = (char *)malloc(connect_string_len);
- if(!connect_string) {
- return 0;
- }
- connect_string[0] = '\0';
- if(host) {
- strcat(connect_string, "host=");
- strcat(connect_string, host);
- strcat(connect_string, " ");
- }
- if(username) {
- strcat(connect_string, "user=");
- strcat(connect_string, username);
- strcat(connect_string, " ");
- }
- if(password) {
- strcat(connect_string, "password=");
- strcat(connect_string, password);
- strcat(connect_string, " ");
- }
- if(port) {
- strcat(connect_string, "port=");
- strcat(connect_string, port);
- strcat(connect_string, " ");
- }
- if(dbname) {
- strcat(connect_string, "dbname=");
- strcat(connect_string, dbname);
- strcat(connect_string, " ");
- }
- strcat(connect_string, "authtype=password");
-
- return connect_string;
+ int connect_string_len = 0;
+ char *connect_string;
+
+ if (host)
+ connect_string_len += 6 + strlen(host); /* 6 == "host=" + " " */
+ if (username)
+ connect_string_len += 6 + strlen(username); /* 6 == "user=" + " " */
+ if (password)
+ connect_string_len += 10 + strlen(password); /* 10 == "password=" + "
+ * " */
+ if (port)
+ connect_string_len += 6 + strlen(port); /* 6 == "port=" + " " */
+ if (dbname)
+ connect_string_len += 8 + strlen(dbname); /* 8 == "dbname=" + " " */
+ connect_string_len += 18; /* "authtype=password" + null */
+
+ connect_string = (char *) malloc(connect_string_len);
+ if (!connect_string)
+ {
+ return 0;
+ }
+ connect_string[0] = '\0';
+ if (host)
+ {
+ strcat(connect_string, "host=");
+ strcat(connect_string, host);
+ strcat(connect_string, " ");
+ }
+ if (username)
+ {
+ strcat(connect_string, "user=");
+ strcat(connect_string, username);
+ strcat(connect_string, " ");
+ }
+ if (password)
+ {
+ strcat(connect_string, "password=");
+ strcat(connect_string, password);
+ strcat(connect_string, " ");
+ }
+ if (port)
+ {
+ strcat(connect_string, "port=");
+ strcat(connect_string, port);
+ strcat(connect_string, " ");
+ }
+ if (dbname)
+ {
+ strcat(connect_string, "dbname=");
+ strcat(connect_string, dbname);
+ strcat(connect_string, " ");
+ }
+ strcat(connect_string, "authtype=password");
+
+ return connect_string;
}
-
diff --git a/src/bin/psql/psqlHelp.h b/src/bin/psql/psqlHelp.h
index bff67dc665a..f9f372a8add 100644
--- a/src/bin/psql/psqlHelp.h
+++ b/src/bin/psql/psqlHelp.h
@@ -1,180 +1,182 @@
/*-------------------------------------------------------------------------
*
* psqlHelp.h--
- * Help for query language syntax
+ * Help for query language syntax
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: psqlHelp.h,v 1.22 1997/09/04 15:02:56 momjian Exp $
+ * $Id: psqlHelp.h,v 1.23 1997/09/07 04:55:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-struct _helpStruct {
- char *cmd; /* the command name */
- char *help; /* the help associated with it */
- char *syntax; /* the syntax associated with it */
-} ;
-
+struct _helpStruct
+{
+ char *cmd; /* the command name */
+ char *help; /* the help associated with it */
+ char *syntax; /* the syntax associated with it */
+};
+
static struct _helpStruct QL_HELP[] = {
- { "abort",
- "abort the current transaction",
- "abort [transaction];"},
- { "abort transaction",
- "abort the current transaction",
- "abort [transaction];"},
- { "alter table",
- "add/rename attributes, rename tables",
- "\talter table <class_name> [*] add column <attr> <type>;\n\talter table <class_name> [*] rename [column] <attr1> to <attr2>;\n\talter table <class_name1> rename to <class_name2>"},
- { "begin",
- "begin a new transaction",
- "begin [transaction|work];"},
- { "begin transaction",
- "begin a new transaction",
- "begin [transaction|work];"},
- { "begin work",
- "begin a new transaction",
- "begin [transaction|work];"},
- { "cluster",
- "create a clustered index (from an existing index)",
- "cluster <index_name> on <relation_name>"},
- { "close",
- "close an existing cursor (cursor)",
- "close <cursorname>;"},
- { "commit",
- "commit a transaction",
- "commit [work]"},
- { "commit work",
- "commit a transaction",
- "commit [work]"},
- { "copy",
- "copy data to and from a table",
- "copy [binary] <class_name> [with oids]\n\t{to|from} {<filename>|stdin|stdout} [using delimiters <delim>];"},
- { "create",
- "Please more be specific:",
- "\tcreate aggregate\n\tcreate database\n\tcreate function\n\tcreate index\n\tcreate operator\n\tcreate rule\n\tcreate sequence\n\tcreate table\n\tcreate type\n\tcreate view"},
- { "create aggregate",
- "define an aggregate function",
- "create aggregate <agg_name> [as] (basetype = <data_type>, \n\t[sfunc1 = <sfunc_1>, stype1 = <sfunc1_return_type>]\n\t[sfunc2 = <sfunc_2>, stype2 = <sfunc2_return_type>]\n\t[,finalfunc = <final-function>]\n\t[,initcond1 = <initial-cond1>][,initcond2 = <initial-cond2>]);"},
- { "create database",
- "create a database",
- "create database <dbname>"},
- { "create function",
- "create a user-defined function",
- "create function <function_name> ([<type1>,...<typeN>]) returns <return_type>\n\tas '<object_filename>'|'<sql-queries>'\n\tlanguage 'c'|'sql'|'internal';"},
- { "create index",
- "construct an index",
- "create [unique] index <indexname> on <class_name> [using <access_method>]\n( <attr1> [<type_class1>] [,...] | <funcname>(<attr1>,...) [<type_class>] );"},
- { "create operator",
- "create a user-defined operator",
- "create operator <operator_name> (\n\t[leftarg = <type1>][,rightarg = <type2>]\n\t,procedure = <func_name>,\n\t[,commutator = <com_op>][,negator = <neg_op>]\n\t[,restrict = <res_proc>][,hashes]\n\t[,join = <join_proc>][,sort = <sort_op1>...<sort_opN>]);"},
- { "create rule",
- "define a new rule",
- "create rule <rule_name> as on\n\t[select|update|delete|insert]\n\tto <object> [where <qual>]\n\tdo [instead] [<action>|nothing| [<actions>]];"},
- { "create sequence",
- "create a new sequence number generator",
- "create sequence <sequence_name>\n\t[increment <NUMBER>]\n\t[start <NUMBER>]\n\t[minvalue <NUMBER>]\n\t[maxvalue <NUMBER>]\n\t[cache <NUMBER>]\n\t[cycle];"},
- { "create table",
- "create a new table",
- "create table <class_name> ( <attr1> <type1> [[not] null],... <attrN> <typeN>)\n\t[inherits (<class_name1>,...<class_nameN>)\n\tarchive=<archive_mode>\n\tstore=<smgr_name>\n\tarch_store=<smgr_name>];"},
- { "create type",
- "create a new user-defined base data type",
- "create type <typename> (\n\tinternallength = (<number> | variable),\n\t[externallength = (<number>|variable),]\n\tinput=<input_function>, output = <output_function>\n\t[,element = <typename>][,delimiter=<character>][,default=\'<string>\']\n\t[,send = <send_function>][,receive = <receive_function>][,passedbyvalue]);"},
- { "create view",
- "create a view",
- "create view <view_name> as select <expr1>[as <attr1>][,... <exprN>[as <attrN>]] [from <from_list>] [where <qual>];"},
- { "declare",
- "set up a cursor",
- "declare <cursorname> [binary] cursor for\n\tselect [distinct]\n\t<expr1> [as <attr1>],...<exprN> [as <attrN>]\n\t[from <from_list>] [where <qual>]\n\t[order by <attr1> [using <op1>],... <attrN> [using <opN>]];"},
- { "delete",
- "delete tuples",
- "delete from <class_name> [where <qual>];"},
- { "drop",
- "Please more be specific:",
- "\tdrop aggregate\n\tdrop database\n\tdrop function\n\tdrop index\n\tdrop operator\n\tdrop rule\n\tdrop sequence\n\tdrop table\n\tdrop type\n\tdrop view"},
- { "drop aggregate",
- "remove an aggregate function",
- "drop aggregate <agg_name> <agg_type>|*;"},
- { "drop database",
- "remove a database",
- "drop database <dbname>"},
- { "drop function",
- "remove a user-defined function",
- "drop function <funcname> ([<type1>,....<typeN>]);"},
- { "drop index",
- "remove an existing index",
- "drop index <indexname>;"},
- { "drop operator",
- "remove a user-defined operator",
- "drop operator <operator_name> ([<ltype>|none],[<rtype>|none]);"},
- { "drop rule",
- "remove a rule",
- "drop rule <rulename>;"},
- { "drop table",
- "remove a table",
- "drop table <class_name>[,...<class_nameN];"},
- { "drop sequence",
- "remove a sequence number generator",
- "drop sequence <sequence_name>[,...<sequence_nameN];"},
- { "drop type",
- "remove a user-defined base type",
- "drop type <typename>;"},
- { "drop view",
- "remove a view",
- "drop view <view_name>"},
- { "end",
- "end the current transaction",
- "end [transaction];"},
- { "end transaction",
- "end the current transaction",
- "end [transaction];"},
- { "explain",
- "explain the query execution plan",
- "explain [verbose] <query>"},
- { "fetch",
- "retrieve tuples from a cursor",
- "fetch [forward|backward] [<number>|all] [in <cursorname>];"},
- { "grant",
- "grant access control to a user or group",
- "grant <privilege[,privilege,...]> on <rel1>[,...<reln>] to \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"},
- { "insert",
- "insert tuples",
- "insert into <class_name> [(<attr1>...<attrN>)]\n\t[values (<expr1>...<exprN>); |\n\tselect <expr1>,...<exprN> [from <from_clause>] [where <qual>];"},
- { "listen",
- "listen for notification on a relation",
- "listen <class_name>"},
- { "load",
- "dynamically load a module",
- "load <filename>;"},
- { "notify",
- "signal all frontends and backends listening on a relation",
- "notify <class_name>"},
- { "purge",
- "purge historical data",
- "purge <class_name> [before <abstime>] [after <reltime>];"},
- { "reset",
- "set run-time environment back to default",
- "reset {DateStyle | GEQO | R_PLANS}"},
- { "revoke",
- "revoke access control from a user or group",
- "revoke <privilege[,privilege,...]> on <rel1>[,...<reln>] from \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"},
- { "rollback",
- "abort a transaction",
- "rollback [transaction|work]"},
- { "select",
- "retrieve tuples",
- "select [distinct on <attr>] <expr1> [as <attr1>], ... <exprN> [as <attrN>]\n\t[into table <class_name>] [from <from_list>]\n\t[where <qual>]\n\t[order by <attr1>\n\t\t[using <op1>],..<attrN> [[using <opN>] | ASC | DESC]];" },
- { "set",
- "set run-time environment",
- "set DateStyle to {'ISO' | 'SQL' | 'Postgres' | 'European' | 'US' | 'NonEuropean'}\nset GEQO to {'ON[=#]' | 'OFF'}\nset R_PLANS to {'ON' | 'OFF'}"},
- { "show",
- "show current run-time environment",
- "show {DateStyle | GEQO | R_PLANS}"},
- { "update",
- "update tuples",
- "update <class_name> set <attr1>=<expr1>,...<attrN>=<exprN> [from <from_clause>] [where <qual>];"},
- { "vacuum",
- "vacuum the database, i.e. cleans out deleted records, updates statistics",
- "vacuum [verbose] [analyze]\n\tor\nvacuum [verbose] [analyze] table [analyze [(attr1, ... attrN)] ];"},
- { NULL, NULL, NULL} /* important to keep a NULL terminator here! */
+ {"abort",
+ "abort the current transaction",
+ "abort [transaction];"},
+ {"abort transaction",
+ "abort the current transaction",
+ "abort [transaction];"},
+ {"alter table",
+ "add/rename attributes, rename tables",
+ "\talter table <class_name> [*] add column <attr> <type>;\n\talter table <class_name> [*] rename [column] <attr1> to <attr2>;\n\talter table <class_name1> rename to <class_name2>"},
+ {"begin",
+ "begin a new transaction",
+ "begin [transaction|work];"},
+ {"begin transaction",
+ "begin a new transaction",
+ "begin [transaction|work];"},
+ {"begin work",
+ "begin a new transaction",
+ "begin [transaction|work];"},
+ {"cluster",
+ "create a clustered index (from an existing index)",
+ "cluster <index_name> on <relation_name>"},
+ {"close",
+ "close an existing cursor (cursor)",
+ "close <cursorname>;"},
+ {"commit",
+ "commit a transaction",
+ "commit [work]"},
+ {"commit work",
+ "commit a transaction",
+ "commit [work]"},
+ {"copy",
+ "copy data to and from a table",
+ "copy [binary] <class_name> [with oids]\n\t{to|from} {<filename>|stdin|stdout} [using delimiters <delim>];"},
+ {"create",
+ "Please more be specific:",
+ "\tcreate aggregate\n\tcreate database\n\tcreate function\n\tcreate index\n\tcreate operator\n\tcreate rule\n\tcreate sequence\n\tcreate table\n\tcreate type\n\tcreate view"},
+ {"create aggregate",
+ "define an aggregate function",
+ "create aggregate <agg_name> [as] (basetype = <data_type>, \n\t[sfunc1 = <sfunc_1>, stype1 = <sfunc1_return_type>]\n\t[sfunc2 = <sfunc_2>, stype2 = <sfunc2_return_type>]\n\t[,finalfunc = <final-function>]\n\t[,initcond1 = <initial-cond1>][,initcond2 = <initial-cond2>]);"},
+ {"create database",
+ "create a database",
+ "create database <dbname>"},
+ {"create function",
+ "create a user-defined function",
+ "create function <function_name> ([<type1>,...<typeN>]) returns <return_type>\n\tas '<object_filename>'|'<sql-queries>'\n\tlanguage 'c'|'sql'|'internal';"},
+ {"create index",
+ "construct an index",
+ "create [unique] index <indexname> on <class_name> [using <access_method>]\n( <attr1> [<type_class1>] [,...] | <funcname>(<attr1>,...) [<type_class>] );"},
+ {"create operator",
+ "create a user-defined operator",
+ "create operator <operator_name> (\n\t[leftarg = <type1>][,rightarg = <type2>]\n\t,procedure = <func_name>,\n\t[,commutator = <com_op>][,negator = <neg_op>]\n\t[,restrict = <res_proc>][,hashes]\n\t[,join = <join_proc>][,sort = <sort_op1>...<sort_opN>]);"},
+ {"create rule",
+ "define a new rule",
+ "create rule <rule_name> as on\n\t[select|update|delete|insert]\n\tto <object> [where <qual>]\n\tdo [instead] [<action>|nothing| [<actions>]];"},
+ {"create sequence",
+ "create a new sequence number generator",
+ "create sequence <sequence_name>\n\t[increment <NUMBER>]\n\t[start <NUMBER>]\n\t[minvalue <NUMBER>]\n\t[maxvalue <NUMBER>]\n\t[cache <NUMBER>]\n\t[cycle];"},
+ {"create table",
+ "create a new table",
+ "create table <class_name> ( <attr1> <type1> [[not] null],... <attrN> <typeN>)\n\t[inherits (<class_name1>,...<class_nameN>)\n\tarchive=<archive_mode>\n\tstore=<smgr_name>\n\tarch_store=<smgr_name>];"},
+ {"create type",
+ "create a new user-defined base data type",
+ "create type <typename> (\n\tinternallength = (<number> | variable),\n\t[externallength = (<number>|variable),]\n\tinput=<input_function>, output = <output_function>\n\t[,element = <typename>][,delimiter=<character>][,default=\'<string>\']\n\t[,send = <send_function>][,receive = <receive_function>][,passedbyvalue]);"},
+ {"create view",
+ "create a view",
+ "create view <view_name> as select <expr1>[as <attr1>][,... <exprN>[as <attrN>]] [from <from_list>] [where <qual>];"},
+ {"declare",
+ "set up a cursor",
+ "declare <cursorname> [binary] cursor for\n\tselect [distinct]\n\t<expr1> [as <attr1>],...<exprN> [as <attrN>]\n\t[from <from_list>] [where <qual>]\n\t[order by <attr1> [using <op1>],... <attrN> [using <opN>]];"},
+ {"delete",
+ "delete tuples",
+ "delete from <class_name> [where <qual>];"},
+ {"drop",
+ "Please more be specific:",
+ "\tdrop aggregate\n\tdrop database\n\tdrop function\n\tdrop index\n\tdrop operator\n\tdrop rule\n\tdrop sequence\n\tdrop table\n\tdrop type\n\tdrop view"},
+ {"drop aggregate",
+ "remove an aggregate function",
+ "drop aggregate <agg_name> <agg_type>|*;"},
+ {"drop database",
+ "remove a database",
+ "drop database <dbname>"},
+ {"drop function",
+ "remove a user-defined function",
+ "drop function <funcname> ([<type1>,....<typeN>]);"},
+ {"drop index",
+ "remove an existing index",
+ "drop index <indexname>;"},
+ {"drop operator",
+ "remove a user-defined operator",
+ "drop operator <operator_name> ([<ltype>|none],[<rtype>|none]);"},
+ {"drop rule",
+ "remove a rule",
+ "drop rule <rulename>;"},
+ {"drop table",
+ "remove a table",
+ "drop table <class_name>[,...<class_nameN];"},
+ {"drop sequence",
+ "remove a sequence number generator",
+ "drop sequence <sequence_name>[,...<sequence_nameN];"},
+ {"drop type",
+ "remove a user-defined base type",
+ "drop type <typename>;"},
+ {"drop view",
+ "remove a view",
+ "drop view <view_name>"},
+ {"end",
+ "end the current transaction",
+ "end [transaction];"},
+ {"end transaction",
+ "end the current transaction",
+ "end [transaction];"},
+ {"explain",
+ "explain the query execution plan",
+ "explain [verbose] <query>"},
+ {"fetch",
+ "retrieve tuples from a cursor",
+ "fetch [forward|backward] [<number>|all] [in <cursorname>];"},
+ {"grant",
+ "grant access control to a user or group",
+ "grant <privilege[,privilege,...]> on <rel1>[,...<reln>] to \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"},
+ {"insert",
+ "insert tuples",
+ "insert into <class_name> [(<attr1>...<attrN>)]\n\t[values (<expr1>...<exprN>); |\n\tselect <expr1>,...<exprN> [from <from_clause>] [where <qual>];"},
+ {"listen",
+ "listen for notification on a relation",
+ "listen <class_name>"},
+ {"load",
+ "dynamically load a module",
+ "load <filename>;"},
+ {"notify",
+ "signal all frontends and backends listening on a relation",
+ "notify <class_name>"},
+ {"purge",
+ "purge historical data",
+ "purge <class_name> [before <abstime>] [after <reltime>];"},
+ {"reset",
+ "set run-time environment back to default",
+ "reset {DateStyle | GEQO | R_PLANS}"},
+ {"revoke",
+ "revoke access control from a user or group",
+ "revoke <privilege[,privilege,...]> on <rel1>[,...<reln>] from \n[public | group <group> | <username>]\n\t privilege is {ALL | SELECT | INSERT | UPDATE | DELETE | RULE}"},
+ {"rollback",
+ "abort a transaction",
+ "rollback [transaction|work]"},
+ {"select",
+ "retrieve tuples",
+ "select [distinct on <attr>] <expr1> [as <attr1>], ... <exprN> [as <attrN>]\n\t[into table <class_name>] [from <from_list>]\n\t[where <qual>]\n\t[order by <attr1>\n\t\t[using <op1>],..<attrN> [[using <opN>] | ASC | DESC]];"},
+ {"set",
+ "set run-time environment",
+ "set DateStyle to {'ISO' | 'SQL' | 'Postgres' | 'European' | 'US' | 'NonEuropean'}\nset GEQO to {'ON[=#]' | 'OFF'}\nset R_PLANS to {'ON' | 'OFF'}"},
+ {"show",
+ "show current run-time environment",
+ "show {DateStyle | GEQO | R_PLANS}"},
+ {"update",
+ "update tuples",
+ "update <class_name> set <attr1>=<expr1>,...<attrN>=<exprN> [from <from_clause>] [where <qual>];"},
+ {"vacuum",
+ "vacuum the database, i.e. cleans out deleted records, updates statistics",
+ "vacuum [verbose] [analyze]\n\tor\nvacuum [verbose] [analyze] table [analyze [(attr1, ... attrN)] ];"},
+ {NULL, NULL, NULL} /* important to keep a NULL terminator
+ * here! */
};
diff --git a/src/bin/psql/stringutils.c b/src/bin/psql/stringutils.c
index cae0e7405be..cf34622209e 100644
--- a/src/bin/psql/stringutils.c
+++ b/src/bin/psql/stringutils.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* stringutils.c--
- * simple string manipulation routines
+ * simple string manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.10 1997/08/25 19:41:52 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.11 1997/09/07 04:55:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,70 +30,82 @@
/* MODIFIES the string passed in and returns the head of it */
#ifdef NOT_USED
-static char *leftTrim(char *s)
+static char *
+leftTrim(char *s)
{
- char *s2 = s;
- int shift=0;
- int j=0;
-
- while (isspace(*s))
- { s++; shift++;}
- if (shift > 0)
- {
- while ( (s2[j] = s2[j+shift]) !='\0')
- j++;
- }
-
- return s2;
+ char *s2 = s;
+ int shift = 0;
+ int j = 0;
+
+ while (isspace(*s))
+ {
+ s++;
+ shift++;
+ }
+ if (shift > 0)
+ {
+ while ((s2[j] = s2[j + shift]) != '\0')
+ j++;
+ }
+
+ return s2;
}
+
#endif
-char *rightTrim(char *s)
+char *
+rightTrim(char *s)
{
- char *sEnd;
- sEnd = s+strlen(s)-1;
- while (sEnd >= s && isspace(*sEnd))
- sEnd--;
- if (sEnd < s)
- s[0]='\0';
- else
- s[sEnd-s+1]='\0';
- return s;
+ char *sEnd;
+
+ sEnd = s + strlen(s) - 1;
+ while (sEnd >= s && isspace(*sEnd))
+ sEnd--;
+ if (sEnd < s)
+ s[0] = '\0';
+ else
+ s[sEnd - s + 1] = '\0';
+ return s;
}
#ifdef NOT_USED
-static char *doubleTrim(char *s)
+static char *
+doubleTrim(char *s)
{
- strcpy(s,leftTrim(rightTrim(s)));
- return s;
+ strcpy(s, leftTrim(rightTrim(s)));
+ return s;
}
+
#endif
#ifdef STRINGUTILS_TEST
-void testStringUtils()
+void
+testStringUtils()
{
- static char *tests[] = {" goodbye \n", /* space on both ends */
- "hello world", /* no spaces to trim */
- "", /* empty string */
- "a", /* string with one char*/
- " ", /* string with one whitespace*/
- NULL_STR};
-
- int i=0;
- while (tests[i]!=NULL_STR)
- {
- char *t;
- t = strdup(tests[i]);
- printf("leftTrim(%s) = ",t);
- printf("%sEND\n", leftTrim(t));
- t = strdup(tests[i]);
- printf("rightTrim(%s) = ",t);
- printf("%sEND\n", rightTrim(t));
- t = strdup(tests[i]);
- printf("doubleTrim(%s) = ",t);
- printf("%sEND\n", doubleTrim(t));
- i++;
- }
+ static char *tests[] = {" goodbye \n", /* space on both ends */
+ "hello world", /* no spaces to trim */
+ "", /* empty string */
+ "a", /* string with one char */
+ " ", /* string with one whitespace */
+ NULL_STR};
+
+ int i = 0;
+
+ while (tests[i] != NULL_STR)
+ {
+ char *t;
+
+ t = strdup(tests[i]);
+ printf("leftTrim(%s) = ", t);
+ printf("%sEND\n", leftTrim(t));
+ t = strdup(tests[i]);
+ printf("rightTrim(%s) = ", t);
+ printf("%sEND\n", rightTrim(t));
+ t = strdup(tests[i]);
+ printf("doubleTrim(%s) = ", t);
+ printf("%sEND\n", doubleTrim(t));
+ i++;
+ }
}
diff --git a/src/bin/psql/stringutils.h b/src/bin/psql/stringutils.h
index c6f037ec716..2bc8795f4c4 100644
--- a/src/bin/psql/stringutils.h
+++ b/src/bin/psql/stringutils.h
@@ -1,11 +1,11 @@
/*-------------------------------------------------------------------------
*
* stringutils.h--
- *
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: stringutils.h,v 1.4 1997/08/19 21:36:58 momjian Exp $
+ * $Id: stringutils.h,v 1.5 1997/09/07 04:55:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,10 +27,11 @@
/* removes whitespaces from the left, right and both sides of a string */
/* MODIFIES the string passed in and returns the head of it */
-extern char *rightTrim(char *s);
+extern char *rightTrim(char *s);
#ifdef STRINGUTILS_TEST
-extern void testStringUtils();
+extern void testStringUtils();
+
#endif
#ifndef NULL_STR
@@ -41,4 +42,4 @@ extern void testStringUtils();
#define NULL 0
#endif
-#endif /* STRINGUTILS_H */
+#endif /* STRINGUTILS_H */
diff --git a/src/include/access/attnum.h b/src/include/access/attnum.h
index b4111e16670..24a757ac3c7 100644
--- a/src/include/access/attnum.h
+++ b/src/include/access/attnum.h
@@ -1,60 +1,60 @@
/*-------------------------------------------------------------------------
*
* attnum.h--
- * POSTGRES attribute number definitions.
+ * POSTGRES attribute number definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: attnum.h,v 1.4 1996/10/31 09:46:35 scrappy Exp $
+ * $Id: attnum.h,v 1.5 1997/09/07 04:55:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef ATTNUM_H
+#ifndef ATTNUM_H
#define ATTNUM_H
/*
* user defined attribute numbers start at 1. -ay 2/95
*/
-typedef int16 AttrNumber;
+typedef int16 AttrNumber;
-#define InvalidAttrNumber 0
+#define InvalidAttrNumber 0
/* ----------------
- * support macros
+ * support macros
* ----------------
*/
/*
* AttributeNumberIsValid --
- * True iff the attribute number is valid.
+ * True iff the attribute number is valid.
*/
#define AttributeNumberIsValid(attributeNumber) \
- ((bool) ((attributeNumber) != InvalidAttrNumber))
+ ((bool) ((attributeNumber) != InvalidAttrNumber))
/*
* AttrNumberIsForUserDefinedAttr --
- * True iff the attribute number corresponds to an user defined attribute.
+ * True iff the attribute number corresponds to an user defined attribute.
*/
#define AttrNumberIsForUserDefinedAttr(attributeNumber) \
- ((bool) ((attributeNumber) > 0))
+ ((bool) ((attributeNumber) > 0))
/*
* AttrNumberGetAttrOffset --
- * Returns the attribute offset for an attribute number.
+ * Returns the attribute offset for an attribute number.
*
* Note:
- * Assumes the attribute number is for an user defined attribute.
+ * Assumes the attribute number is for an user defined attribute.
*/
#define AttrNumberGetAttrOffset(attNum) \
- (AssertMacro(AttrNumberIsForUserDefinedAttr(attNum)) ? \
- ((attNum - 1)) : 0)
+ (AssertMacro(AttrNumberIsForUserDefinedAttr(attNum)) ? \
+ ((attNum - 1)) : 0)
/*
* AttributeOffsetGetAttributeNumber --
- * Returns the attribute number for an attribute offset.
+ * Returns the attribute number for an attribute offset.
*/
#define AttrOffsetGetAttrNumber(attributeOffset) \
- ((AttrNumber) (1 + attributeOffset))
+ ((AttrNumber) (1 + attributeOffset))
-#endif /* ATTNUM_H */
+#endif /* ATTNUM_H */
diff --git a/src/include/access/funcindex.h b/src/include/access/funcindex.h
index a1e1aeacf3d..6257ab97916 100644
--- a/src/include/access/funcindex.h
+++ b/src/include/access/funcindex.h
@@ -1,26 +1,27 @@
/*-------------------------------------------------------------------------
*
* funcindex.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: funcindex.h,v 1.2 1996/08/28 01:56:16 scrappy Exp $
+ * $Id: funcindex.h,v 1.3 1997/09/07 04:55:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef _FUNC_INDEX_INCLUDED_
#define _FUNC_INDEX_INCLUDED_
-typedef struct {
- int nargs;
- Oid arglist[8];
- Oid procOid;
- NameData funcName;
-} FuncIndexInfo;
+typedef struct
+{
+ int nargs;
+ Oid arglist[8];
+ Oid procOid;
+ NameData funcName;
+} FuncIndexInfo;
-typedef FuncIndexInfo *FuncIndexInfoPtr;
+typedef FuncIndexInfo *FuncIndexInfoPtr;
/*
* some marginally useful macro definitions
@@ -38,4 +39,4 @@ typedef FuncIndexInfo *FuncIndexInfoPtr;
#define FIisFunctionalIndex(FINFO) (FINFO->procOid != InvalidOid)
-#endif /* FUNCINDEX_H */
+#endif /* FUNCINDEX_H */
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index a6a3fd9d2f7..6bb73416c5a 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* genam.h--
- * POSTGRES general access method definitions.
+ * POSTGRES general access method definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: genam.h,v 1.7 1997/08/19 21:37:13 momjian Exp $
+ * $Id: genam.h,v 1.8 1997/09/07 04:55:48 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef GENAM_H
+#ifndef GENAM_H
#define GENAM_H
#include <access/sdir.h>
@@ -19,33 +19,39 @@
#include <access/itup.h>
/* ----------------
- * generalized index_ interface routines
+ * generalized index_ interface routines
* ----------------
*/
extern Relation index_open(Oid relationId);
extern Relation index_openr(char *relationName);
-extern void index_close(Relation relation);
-extern InsertIndexResult index_insert(Relation relation,
- Datum *datum, char *nulls,
- ItemPointer heap_t_ctid,
- Relation heapRel);
-extern void index_delete(Relation relation, ItemPointer indexItem);
-extern IndexScanDesc index_beginscan(Relation relation, bool scanFromEnd,
- uint16 numberOfKeys, ScanKey key);
-extern void index_rescan(IndexScanDesc scan, bool scanFromEnd, ScanKey key);
-extern void index_endscan(IndexScanDesc scan);
-extern RetrieveIndexResult index_getnext(IndexScanDesc scan,
- ScanDirection direction);
-extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
- uint16 procnum);
-extern Datum GetIndexValue(HeapTuple tuple, TupleDesc hTupDesc,
- int attOff, AttrNumber attrNums[], FuncIndexInfo *fInfo,
- bool *attNull, Buffer buffer);
+extern void index_close(Relation relation);
+extern InsertIndexResult
+index_insert(Relation relation,
+ Datum * datum, char *nulls,
+ ItemPointer heap_t_ctid,
+ Relation heapRel);
+extern void index_delete(Relation relation, ItemPointer indexItem);
+extern IndexScanDesc
+index_beginscan(Relation relation, bool scanFromEnd,
+ uint16 numberOfKeys, ScanKey key);
+extern void index_rescan(IndexScanDesc scan, bool scanFromEnd, ScanKey key);
+extern void index_endscan(IndexScanDesc scan);
+extern RetrieveIndexResult
+index_getnext(IndexScanDesc scan,
+ ScanDirection direction);
+extern RegProcedure
+index_getprocid(Relation irel, AttrNumber attnum,
+ uint16 procnum);
+extern Datum
+GetIndexValue(HeapTuple tuple, TupleDesc hTupDesc,
+ int attOff, AttrNumber attrNums[], FuncIndexInfo * fInfo,
+ bool * attNull, Buffer buffer);
/* in genam.c */
-extern IndexScanDesc RelationGetIndexScan(Relation relation, bool scanFromEnd,
- uint16 numberOfKeys, ScanKey key);
-extern void IndexScanMarkPosition(IndexScanDesc scan);
-extern void IndexScanRestorePosition(IndexScanDesc scan);
+extern IndexScanDesc
+RelationGetIndexScan(Relation relation, bool scanFromEnd,
+ uint16 numberOfKeys, ScanKey key);
+extern void IndexScanMarkPosition(IndexScanDesc scan);
+extern void IndexScanRestorePosition(IndexScanDesc scan);
-#endif /* GENAM_H */
+#endif /* GENAM_H */
diff --git a/src/include/access/gist.h b/src/include/access/gist.h
index 1e8efc18e0f..ff21dd50cd1 100644
--- a/src/include/access/gist.h
+++ b/src/include/access/gist.h
@@ -1,11 +1,11 @@
/*-------------------------------------------------------------------------
*
* gist.h--
- * common declarations for the GiST access method code.
+ * common declarations for the GiST access method code.
+ *
*
*
*
- *
*
*-------------------------------------------------------------------------
*/
@@ -21,130 +21,136 @@
#include <utils/rel.h>
#include <storage/off.h>
-/*
+/*
** You can have as many strategies as you please in GiSTs, as
** long as your consistent method can handle them
**
-** But strat.h->StrategyEvaluationData->StrategyExpression expression[12]
+** But strat.h->StrategyEvaluationData->StrategyExpression expression[12]
** - so 12 is real max # of strategies, or StrategyEvaluationIsValid
-** crashes backend... - vadim 05/21/97
+** crashes backend... - vadim 05/21/97
-#define GISTNStrategies 100
+#define GISTNStrategies 100
*/
-#define GISTNStrategies 12
+#define GISTNStrategies 12
/*
** Helper routines
*/
-#define GISTNProcs 8
-#define GIST_CONSISTENT_PROC 1
-#define GIST_UNION_PROC 2
-#define GIST_COMPRESS_PROC 3
-#define GIST_DECOMPRESS_PROC 4
-#define GIST_PENALTY_PROC 5
-#define GIST_PICKSPLIT_PROC 6
-#define GIST_EQUAL_PROC 7
-#define GIST_INFO_PROC 8
+#define GISTNProcs 8
+#define GIST_CONSISTENT_PROC 1
+#define GIST_UNION_PROC 2
+#define GIST_COMPRESS_PROC 3
+#define GIST_DECOMPRESS_PROC 4
+#define GIST_PENALTY_PROC 5
+#define GIST_PICKSPLIT_PROC 6
+#define GIST_EQUAL_PROC 7
+#define GIST_INFO_PROC 8
-#define F_LEAF (1 << 0)
+#define F_LEAF (1 << 0)
-typedef struct GISTPageOpaqueData {
- uint32 flags;
-} GISTPageOpaqueData;
+typedef struct GISTPageOpaqueData
+{
+ uint32 flags;
+} GISTPageOpaqueData;
-typedef GISTPageOpaqueData *GISTPageOpaque;
+typedef GISTPageOpaqueData *GISTPageOpaque;
#define GIST_LEAF(entry) (((GISTPageOpaque) PageGetSpecialPointer((entry)->page))->flags & F_LEAF)
/*
- * When we descend a tree, we keep a stack of parent pointers.
+ * When we descend a tree, we keep a stack of parent pointers.
*/
-typedef struct GISTSTACK {
+typedef struct GISTSTACK
+{
struct GISTSTACK *gs_parent;
OffsetNumber gs_child;
- BlockNumber gs_blk;
-} GISTSTACK;
-
-typedef struct GISTSTATE {
- func_ptr consistentFn;
- func_ptr unionFn;
- func_ptr compressFn;
- func_ptr decompressFn;
- func_ptr penaltyFn;
- func_ptr picksplitFn;
- func_ptr equalFn;
- bool haskeytype;
- bool keytypbyval;
-} GISTSTATE;
+ BlockNumber gs_blk;
+} GISTSTACK;
+
+typedef struct GISTSTATE
+{
+ func_ptr consistentFn;
+ func_ptr unionFn;
+ func_ptr compressFn;
+ func_ptr decompressFn;
+ func_ptr penaltyFn;
+ func_ptr picksplitFn;
+ func_ptr equalFn;
+ bool haskeytype;
+ bool keytypbyval;
+} GISTSTATE;
/*
-** When we're doing a scan, we need to keep track of the parent stack
-** for the marked and current items.
+** When we're doing a scan, we need to keep track of the parent stack
+** for the marked and current items.
*/
-typedef struct GISTScanOpaqueData {
- struct GISTSTACK *s_stack;
- struct GISTSTACK *s_markstk;
- uint16 s_flags;
- struct GISTSTATE *giststate;
-} GISTScanOpaqueData;
+typedef struct GISTScanOpaqueData
+{
+ struct GISTSTACK *s_stack;
+ struct GISTSTACK *s_markstk;
+ uint16 s_flags;
+ struct GISTSTATE *giststate;
+} GISTScanOpaqueData;
-typedef GISTScanOpaqueData *GISTScanOpaque;
+typedef GISTScanOpaqueData *GISTScanOpaque;
/*
-** When we're doing a scan and updating a tree at the same time, the
-** updates may affect the scan. We use the flags entry of the scan's
-** opaque space to record our actual position in response to updates
-** that we can't handle simply by adjusting pointers.
+** When we're doing a scan and updating a tree at the same time, the
+** updates may affect the scan. We use the flags entry of the scan's
+** opaque space to record our actual position in response to updates
+** that we can't handle simply by adjusting pointers.
*/
#define GS_CURBEFORE ((uint16) (1 << 0))
#define GS_MRKBEFORE ((uint16) (1 << 1))
/* root page of a gist */
-#define GISTP_ROOT 0
+#define GISTP_ROOT 0
/*
-** When we update a relation on which we're doing a scan, we need to
-** check the scan and fix it if the update affected any of the pages it
-** touches. Otherwise, we can miss records that we should see. The only
-** times we need to do this are for deletions and splits. See the code in
-** gistscan.c for how the scan is fixed. These two constants tell us what sort
-** of operation changed the index.
+** When we update a relation on which we're doing a scan, we need to
+** check the scan and fix it if the update affected any of the pages it
+** touches. Otherwise, we can miss records that we should see. The only
+** times we need to do this are for deletions and splits. See the code in
+** gistscan.c for how the scan is fixed. These two constants tell us what sort
+** of operation changed the index.
*/
-#define GISTOP_DEL 0
-#define GISTOP_SPLIT 1
+#define GISTOP_DEL 0
+#define GISTOP_SPLIT 1
/*
** This is the Split Vector to be returned by the PickSplit method.
*/
-typedef struct GIST_SPLITVEC {
- OffsetNumber *spl_left; /* array of entries that go left */
- int spl_nleft; /* size of this array */
- char *spl_ldatum; /* Union of keys in spl_left */
- OffsetNumber *spl_right; /* array of entries that go right */
- int spl_nright; /* size of the array */
- char *spl_rdatum; /* Union of keys in spl_right */
-} GIST_SPLITVEC;
+typedef struct GIST_SPLITVEC
+{
+ OffsetNumber *spl_left; /* array of entries that go left */
+ int spl_nleft; /* size of this array */
+ char *spl_ldatum; /* Union of keys in spl_left */
+ OffsetNumber *spl_right; /* array of entries that go right */
+ int spl_nright; /* size of the array */
+ char *spl_rdatum; /* Union of keys in spl_right */
+} GIST_SPLITVEC;
/*
-** An entry on a GiST node. Contains the key (pred), as well as
+** An entry on a GiST node. Contains the key (pred), as well as
** its own location (rel,page,offset) which can supply the matching
** pointer. The size of the pred is in bytes, and leafkey is a flag to
** tell us if the entry is in a leaf node.
*/
-typedef struct GISTENTRY {
- char *pred;
- Relation rel;
- Page page;
- OffsetNumber offset;
- int bytes;
- bool leafkey;
-} GISTENTRY;
+typedef struct GISTENTRY
+{
+ char *pred;
+ Relation rel;
+ Page page;
+ OffsetNumber offset;
+ int bytes;
+ bool leafkey;
+} GISTENTRY;
/*
** macro to initialize a GISTENTRY
@@ -156,40 +162,49 @@ typedef struct GISTENTRY {
#define TRLOWER(tr) (((tr)->bytes))
#define TRUPPER(tr) (&((tr)->bytes[MAXALIGN(VARSIZE(TRLOWER(tr)))]))
-typedef struct txtrange {
- /* flag: NINF means that lower is negative infinity; PINF means that
- ** upper is positive infinity. 0 means that both are numbers.
- */
- int32 vl_len;
- int32 flag;
- char bytes[2];
-} TXTRANGE;
-
-typedef struct intrange {
- int lower;
- int upper;
- /* flag: NINF means that lower is negative infinity; PINF means that
- ** upper is positive infinity. 0 means that both are numbers.
- */
- int flag;
-} INTRANGE;
-
-extern void gistbuild(Relation heap,
- Relation index, int natts,
- AttrNumber *attnum, IndexStrategy istrat,
- uint16 pint, Datum *params,
- FuncIndexInfo *finfo,
- PredInfo *predInfo);
-extern InsertIndexResult gistinsert(Relation r, Datum *datum,
- char *nulls,ItemPointer ht_ctid, Relation heapRel);
-extern void _gistdump(Relation r);
-extern void gistfreestack(GISTSTACK *s);
-extern void initGISTstate(GISTSTATE *giststate, Relation index);
-extern void gistdentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr,
- Relation r, Page pg, OffsetNumber o, int b, bool l) ;
+typedef struct txtrange
+{
+
+ /*
+ * flag: NINF means that lower is negative infinity; PINF means that *
+ * upper is positive infinity. 0 means that both are numbers.
+ */
+ int32 vl_len;
+ int32 flag;
+ char bytes[2];
+} TXTRANGE;
+
+typedef struct intrange
+{
+ int lower;
+ int upper;
+
+ /*
+ * flag: NINF means that lower is negative infinity; PINF means that *
+ * upper is positive infinity. 0 means that both are numbers.
+ */
+ int flag;
+} INTRANGE;
+
+extern void
+gistbuild(Relation heap,
+ Relation index, int natts,
+ AttrNumber * attnum, IndexStrategy istrat,
+ uint16 pint, Datum * params,
+ FuncIndexInfo * finfo,
+ PredInfo * predInfo);
+extern InsertIndexResult
+gistinsert(Relation r, Datum * datum,
+ char *nulls, ItemPointer ht_ctid, Relation heapRel);
+extern void _gistdump(Relation r);
+extern void gistfreestack(GISTSTACK * s);
+extern void initGISTstate(GISTSTATE * giststate, Relation index);
+extern void
+gistdentryinit(GISTSTATE * giststate, GISTENTRY * e, char *pr,
+ Relation r, Page pg, OffsetNumber o, int b, bool l);
extern StrategyNumber RelationGetGISTStrategy(Relation, AttrNumber, RegProcedure);
/* gistget.c */
extern RetrieveIndexResult gistgettuple(IndexScanDesc s, ScanDirection dir);
-#endif /* GIST_H */
+#endif /* GIST_H */
diff --git a/src/include/access/gistscan.h b/src/include/access/gistscan.h
index 9894e71b01b..46aa621631d 100644
--- a/src/include/access/gistscan.h
+++ b/src/include/access/gistscan.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* gistscan.h--
- * routines defined in access/gisr/gistscan.c
+ * routines defined in access/gisr/gistscan.c
*
*
*
@@ -16,12 +16,13 @@
#include <storage/block.h>
#include <utils/rel.h>
-extern IndexScanDesc gistbeginscan(Relation r, bool fromEnd,
- uint16 nkeys, ScanKey key);
-extern void gistrescan(IndexScanDesc s, bool fromEnd, ScanKey key);
-extern void gistmarkpos(IndexScanDesc s);
-extern void gistrestrpos(IndexScanDesc s);
-extern void gistendscan(IndexScanDesc s);
-extern void gistadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum);
+extern IndexScanDesc
+gistbeginscan(Relation r, bool fromEnd,
+ uint16 nkeys, ScanKey key);
+extern void gistrescan(IndexScanDesc s, bool fromEnd, ScanKey key);
+extern void gistmarkpos(IndexScanDesc s);
+extern void gistrestrpos(IndexScanDesc s);
+extern void gistendscan(IndexScanDesc s);
+extern void gistadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum);
-#endif /* GISTSCAN_H */
+#endif /* GISTSCAN_H */
diff --git a/src/include/access/giststrat.h b/src/include/access/giststrat.h
index 74f370b745d..1007dd3ec26 100644
--- a/src/include/access/giststrat.h
+++ b/src/include/access/giststrat.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* giststrat.h--
- * routines defined in access/gist/giststrat.c
+ * routines defined in access/gist/giststrat.c
*
*
*
@@ -15,7 +15,8 @@
#include <access/strat.h>
#include <utils/rel.h>
-extern StrategyNumber RelationGetGISTStrategy(Relation r,
- AttrNumber attnum, RegProcedure proc);
+extern StrategyNumber
+RelationGetGISTStrategy(Relation r,
+ AttrNumber attnum, RegProcedure proc);
-#endif /* GISTSTRAT_H */
+#endif /* GISTSTRAT_H */
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index c01bb55d45d..14fd50c34cf 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -1,15 +1,15 @@
/*-------------------------------------------------------------------------
*
* hash.h--
- * header file for postgres hash access method implementation
+ * header file for postgres hash access method implementation
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: hash.h,v 1.7 1997/08/19 21:37:27 momjian Exp $
+ * $Id: hash.h,v 1.8 1997/09/07 04:55:54 momjian Exp $
*
* NOTES
- * modeled after Margo Seltzer's hash implementation for unix.
+ * modeled after Margo Seltzer's hash implementation for unix.
*
*-------------------------------------------------------------------------
*/
@@ -22,44 +22,44 @@
#include <access/relscan.h>
#include <access/itup.h>
-/*
- * An overflow page is a spare page allocated for storing data whose
+/*
+ * An overflow page is a spare page allocated for storing data whose
* bucket doesn't have room to store it. We use overflow pages rather
* than just splitting the bucket because there is a linear order in
* the way we split buckets. In other words, if there isn't enough space
- * in the bucket itself, put it in an overflow page.
+ * in the bucket itself, put it in an overflow page.
*
* Overflow page addresses are stored in form: (Splitnumber, Page offset).
*
* A splitnumber is the number of the generation where the table doubles
* in size. The ovflpage's offset within the splitnumber; offsets start
- * at 1.
- *
+ * at 1.
+ *
* We convert the stored bitmap address into a page address with the
- * macro OADDR_OF(S, O) where S is the splitnumber and O is the page
- * offset.
+ * macro OADDR_OF(S, O) where S is the splitnumber and O is the page
+ * offset.
*/
-typedef uint32 Bucket;
+typedef uint32 Bucket;
typedef bits16 OverflowPageAddress;
typedef uint32 SplitNumber;
-typedef uint32 PageOffset;
+typedef uint32 PageOffset;
/* A valid overflow address will always have a page offset >= 1 */
-#define InvalidOvflAddress 0
-
-#define SPLITSHIFT 11
-#define SPLITMASK 0x7FF
-#define SPLITNUM(N) ((SplitNumber)(((uint32)(N)) >> SPLITSHIFT))
-#define OPAGENUM(N) ((PageOffset)((N) & SPLITMASK))
-#define OADDR_OF(S,O) ((OverflowPageAddress)((uint32)((uint32)(S) << SPLITSHIFT) + (O)))
+#define InvalidOvflAddress 0
+
+#define SPLITSHIFT 11
+#define SPLITMASK 0x7FF
+#define SPLITNUM(N) ((SplitNumber)(((uint32)(N)) >> SPLITSHIFT))
+#define OPAGENUM(N) ((PageOffset)((N) & SPLITMASK))
+#define OADDR_OF(S,O) ((OverflowPageAddress)((uint32)((uint32)(S) << SPLITSHIFT) + (O)))
#define BUCKET_TO_BLKNO(B) \
- ((Bucket) ((B) + ((B) ? metap->SPARES[_hash_log2((B)+1)-1] : 0)) + 1)
-#define OADDR_TO_BLKNO(B) \
- ((BlockNumber) \
- (BUCKET_TO_BLKNO ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B))));
+ ((Bucket) ((B) + ((B) ? metap->SPARES[_hash_log2((B)+1)-1] : 0)) + 1)
+#define OADDR_TO_BLKNO(B) \
+ ((BlockNumber) \
+ (BUCKET_TO_BLKNO ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B))));
-/*
+/*
* hasho_flag tells us which type of page we're looking at. For
* example, knowing overflow pages from bucket pages is necessary
* information when you're deleting tuples from a page. If all the
@@ -69,44 +69,47 @@ typedef uint32 PageOffset;
* necessary.
*/
-#define LH_UNUSED_PAGE (0)
-#define LH_OVERFLOW_PAGE (1 << 0)
-#define LH_BUCKET_PAGE (1 << 1)
-#define LH_BITMAP_PAGE (1 << 2)
-#define LH_META_PAGE (1 << 3)
+#define LH_UNUSED_PAGE (0)
+#define LH_OVERFLOW_PAGE (1 << 0)
+#define LH_BUCKET_PAGE (1 << 1)
+#define LH_BITMAP_PAGE (1 << 2)
+#define LH_META_PAGE (1 << 3)
-typedef struct HashPageOpaqueData {
- bits16 hasho_flag; /* is this page a bucket or ovfl */
- Bucket hasho_bucket; /* bucket number this pg belongs to */
- OverflowPageAddress hasho_oaddr; /* ovfl address of this ovfl pg */
- BlockNumber hasho_nextblkno; /* next ovfl blkno */
- BlockNumber hasho_prevblkno; /* previous ovfl (or bucket) blkno */
-} HashPageOpaqueData;
+typedef struct HashPageOpaqueData
+{
+ bits16 hasho_flag; /* is this page a bucket or ovfl */
+ Bucket hasho_bucket; /* bucket number this pg belongs
+ * to */
+ OverflowPageAddress hasho_oaddr; /* ovfl address of this ovfl pg */
+ BlockNumber hasho_nextblkno; /* next ovfl blkno */
+ BlockNumber hasho_prevblkno; /* previous ovfl (or bucket) blkno */
+} HashPageOpaqueData;
-typedef HashPageOpaqueData *HashPageOpaque;
+typedef HashPageOpaqueData *HashPageOpaque;
/*
- * ScanOpaqueData is used to remember which buffers we're currently
- * examining in the scan. We keep these buffers locked and pinned and
- * recorded in the opaque entry of the scan in order to avoid doing a
- * ReadBuffer() for every tuple in the index. This avoids semop() calls,
- * which are expensive.
+ * ScanOpaqueData is used to remember which buffers we're currently
+ * examining in the scan. We keep these buffers locked and pinned and
+ * recorded in the opaque entry of the scan in order to avoid doing a
+ * ReadBuffer() for every tuple in the index. This avoids semop() calls,
+ * which are expensive.
*/
-typedef struct HashScanOpaqueData {
- Buffer hashso_curbuf;
- Buffer hashso_mrkbuf;
-} HashScanOpaqueData;
+typedef struct HashScanOpaqueData
+{
+ Buffer hashso_curbuf;
+ Buffer hashso_mrkbuf;
+} HashScanOpaqueData;
-typedef HashScanOpaqueData *HashScanOpaque;
+typedef HashScanOpaqueData *HashScanOpaque;
-/*
+/*
* Definitions for metapage.
*/
#define HASH_METAPAGE 0 /* metapage is always block 0 */
-#define HASH_MAGIC 0x6440640
+#define HASH_MAGIC 0x6440640
#define HASH_VERSION 0
/*
@@ -116,168 +119,169 @@ typedef HashScanOpaqueData *HashScanOpaque;
* allocated at a certain splitpoint. For example, if spares[3] = 7
* then there are a maximum of 7 ovflpages available at splitpoint 3.
* The value in spares[] will change as ovflpages are added within
- * a splitpoint.
- *
+ * a splitpoint.
+ *
* Within a splitpoint, one can find which ovflpages are available and
* which are used by looking at a bitmaps that are stored on the ovfl
* pages themselves. There is at least one bitmap for every splitpoint's
- * ovflpages. Bitmaps[] contains the ovflpage addresses of the ovflpages
- * that hold the ovflpage bitmaps.
+ * ovflpages. Bitmaps[] contains the ovflpage addresses of the ovflpages
+ * that hold the ovflpage bitmaps.
*
* The reason that the size is restricted to NCACHED (32) is because
* the bitmaps are 16 bits: upper 5 represent the splitpoint, lower 11
- * indicate the page number within the splitpoint. Since there are
- * only 5 bits to store the splitpoint, there can only be 32 splitpoints.
+ * indicate the page number within the splitpoint. Since there are
+ * only 5 bits to store the splitpoint, there can only be 32 splitpoints.
* Both spares[] and bitmaps[] use splitpoints as there indices, so there
- * can only be 32 of them.
+ * can only be 32 of them.
*/
-#define NCACHED 32
-
-
-typedef struct HashMetaPageData {
- PageHeaderData hashm_phdr; /* pad for page header
- (do not use) */
- uint32 hashm_magic; /* magic no. for hash tables */
- uint32 hashm_version; /* version ID */
- uint32 hashm_nkeys; /* number of keys stored in
- the table */
- uint16 hashm_ffactor; /* fill factor */
- uint16 hashm_bsize; /* bucket size (bytes) -
- must be a power of 2 */
- uint16 hashm_bshift; /* bucket shift */
- uint16 hashm_bmsize; /* bitmap array size (bytes) -
- must be a power of 2 */
- uint32 hashm_maxbucket; /* ID of maximum bucket
- in use */
- uint32 hashm_highmask; /* mask to modulo into
- entire table */
- uint32 hashm_lowmask; /* mask to modulo into lower
- half of table */
- uint32 hashm_ovflpoint; /* pageno. from which ovflpgs
- being allocated */
- uint32 hashm_lastfreed; /* last ovflpage freed */
- uint32 hashm_nmaps; /* Initial number of bitmaps */
- uint32 hashm_spares[NCACHED]; /* spare pages available at
- splitpoints */
- BlockNumber hashm_mapp[NCACHED]; /* blknumbers of ovfl page
- maps */
- RegProcedure hashm_procid; /* hash procedure id from
- pg_proc */
-} HashMetaPageData;
+#define NCACHED 32
+
+
+typedef struct HashMetaPageData
+{
+ PageHeaderData hashm_phdr; /* pad for page header (do not use) */
+ uint32 hashm_magic;/* magic no. for hash tables */
+ uint32 hashm_version; /* version ID */
+ uint32 hashm_nkeys;/* number of keys stored in the table */
+ uint16 hashm_ffactor; /* fill factor */
+ uint16 hashm_bsize;/* bucket size (bytes) - must be a power
+ * of 2 */
+ uint16 hashm_bshift; /* bucket shift */
+ uint16 hashm_bmsize; /* bitmap array size (bytes) -
+ * must be a power of 2 */
+ uint32 hashm_maxbucket; /* ID of maximum bucket in use */
+ uint32 hashm_highmask; /* mask to modulo into entire
+ * table */
+ uint32 hashm_lowmask; /* mask to modulo into lower half
+ * of table */
+ uint32 hashm_ovflpoint; /* pageno. from which ovflpgs
+ * being allocated */
+ uint32 hashm_lastfreed; /* last ovflpage freed */
+ uint32 hashm_nmaps;/* Initial number of bitmaps */
+ uint32 hashm_spares[NCACHED]; /* spare pages available
+ * at splitpoints */
+ BlockNumber hashm_mapp[NCACHED]; /* blknumbers of ovfl page
+ * maps */
+ RegProcedure hashm_procid; /* hash procedure id from pg_proc */
+} HashMetaPageData;
typedef HashMetaPageData *HashMetaPage;
/* Short hands for accessing structure */
-#define BSHIFT hashm_bshift
-#define OVFL_POINT hashm_ovflpoint
-#define LAST_FREED hashm_lastfreed
-#define MAX_BUCKET hashm_maxbucket
-#define FFACTOR hashm_ffactor
-#define HIGH_MASK hashm_highmask
-#define LOW_MASK hashm_lowmask
-#define NKEYS hashm_nkeys
-#define SPARES hashm_spares
+#define BSHIFT hashm_bshift
+#define OVFL_POINT hashm_ovflpoint
+#define LAST_FREED hashm_lastfreed
+#define MAX_BUCKET hashm_maxbucket
+#define FFACTOR hashm_ffactor
+#define HIGH_MASK hashm_highmask
+#define LOW_MASK hashm_lowmask
+#define NKEYS hashm_nkeys
+#define SPARES hashm_spares
-extern bool BuildingHash;
+extern bool BuildingHash;
-typedef struct HashItemData {
- IndexTupleData hash_itup;
-} HashItemData;
+typedef struct HashItemData
+{
+ IndexTupleData hash_itup;
+} HashItemData;
-typedef HashItemData *HashItem;
+typedef HashItemData *HashItem;
/*
* Constants
*/
-#define DEFAULT_FFACTOR 300
-#define SPLITMAX 8
-#define BYTE_TO_BIT 3 /* 2^3 bits/byte */
-#define INT_TO_BYTE 2 /* 2^2 bytes/int */
-#define INT_TO_BIT 5 /* 2^5 bits/int */
-#define ALL_SET ((uint32) ~0)
+#define DEFAULT_FFACTOR 300
+#define SPLITMAX 8
+#define BYTE_TO_BIT 3 /* 2^3 bits/byte */
+#define INT_TO_BYTE 2 /* 2^2 bytes/int */
+#define INT_TO_BIT 5 /* 2^5 bits/int */
+#define ALL_SET ((uint32) ~0)
/*
- * bitmap pages do not contain tuples. they do contain the standard
+ * bitmap pages do not contain tuples. they do contain the standard
* page headers and trailers; however, everything in between is a
* giant bit array. the number of bits that fit on a page obviously
* depends on the page size and the header/trailer overhead.
*/
-#define BMPGSZ_BYTE(metap) ((metap)->hashm_bmsize)
-#define BMPGSZ_BIT(metap) ((metap)->hashm_bmsize << BYTE_TO_BIT)
-#define HashPageGetBitmap(pg) \
- ((uint32 *) (((char *) (pg)) + DOUBLEALIGN(sizeof(PageHeaderData))))
+#define BMPGSZ_BYTE(metap) ((metap)->hashm_bmsize)
+#define BMPGSZ_BIT(metap) ((metap)->hashm_bmsize << BYTE_TO_BIT)
+#define HashPageGetBitmap(pg) \
+ ((uint32 *) (((char *) (pg)) + DOUBLEALIGN(sizeof(PageHeaderData))))
/*
* The number of bits in an ovflpage bitmap which
* tells which ovflpages are empty versus in use (NOT the number of
- * bits in an overflow page *address* bitmap).
+ * bits in an overflow page *address* bitmap).
*/
-#define BITS_PER_MAP 32 /* Number of bits in ovflpage bitmap */
+#define BITS_PER_MAP 32 /* Number of bits in ovflpage bitmap */
/* Given the address of the beginning of a big map, clear/set the nth bit */
#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP)))
#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP)))
-#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP)))
+#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP)))
/*
* page locking modes
*/
-#define HASH_READ 0
-#define HASH_WRITE 1
+#define HASH_READ 0
+#define HASH_WRITE 1
-/*
- * In general, the hash code tries to localize its knowledge about page
- * layout to a couple of routines. However, we need a special value to
- * indicate "no page number" in those places where we expect page numbers.
+/*
+ * In general, the hash code tries to localize its knowledge about page
+ * layout to a couple of routines. However, we need a special value to
+ * indicate "no page number" in those places where we expect page numbers.
*/
-#define P_NONE 0
+#define P_NONE 0
/*
- * Strategy number. There's only one valid strategy for hashing: equality.
+ * Strategy number. There's only one valid strategy for hashing: equality.
*/
-#define HTEqualStrategyNumber 1
-#define HTMaxStrategyNumber 1
+#define HTEqualStrategyNumber 1
+#define HTMaxStrategyNumber 1
/*
- * When a new operator class is declared, we require that the user supply
- * us with an amproc procudure for hashing a key of the new type.
- * Since we only have one such proc in amproc, it's number 1.
+ * When a new operator class is declared, we require that the user supply
+ * us with an amproc procudure for hashing a key of the new type.
+ * Since we only have one such proc in amproc, it's number 1.
*/
-#define HASHPROC 1
+#define HASHPROC 1
/* public routines */
-extern void hashbuild(Relation heap, Relation index, int natts,
- AttrNumber *attnum, IndexStrategy istrat, uint16 pcount,
- Datum *params, FuncIndexInfo *finfo, PredInfo *predInfo);
-extern InsertIndexResult hashinsert(Relation rel, Datum *datum, char *nulls,
- ItemPointer ht_ctid, Relation heapRel);
-extern char *hashgettuple(IndexScanDesc scan, ScanDirection dir);
-extern char *hashbeginscan(Relation rel, bool fromEnd, uint16 keysz,
- ScanKey scankey);
-extern void hashrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey);
-extern void hashendscan(IndexScanDesc scan);
-extern void hashmarkpos(IndexScanDesc scan);
-extern void hashrestrpos(IndexScanDesc scan);
-extern void hashdelete(Relation rel, ItemPointer tid);
+extern void
+hashbuild(Relation heap, Relation index, int natts,
+ AttrNumber * attnum, IndexStrategy istrat, uint16 pcount,
+ Datum * params, FuncIndexInfo * finfo, PredInfo * predInfo);
+extern InsertIndexResult
+hashinsert(Relation rel, Datum * datum, char *nulls,
+ ItemPointer ht_ctid, Relation heapRel);
+extern char *hashgettuple(IndexScanDesc scan, ScanDirection dir);
+extern char *
+hashbeginscan(Relation rel, bool fromEnd, uint16 keysz,
+ ScanKey scankey);
+extern void hashrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey);
+extern void hashendscan(IndexScanDesc scan);
+extern void hashmarkpos(IndexScanDesc scan);
+extern void hashrestrpos(IndexScanDesc scan);
+extern void hashdelete(Relation rel, ItemPointer tid);
/* hashfunc.c */
-extern uint32 hashint2(int16 key);
-extern uint32 hashint4(uint32 key);
-extern uint32 hashfloat4(float32 keyp);
-extern uint32 hashfloat8(float64 keyp);
-extern uint32 hashoid(Oid key);
-extern uint32 hashchar(char key);
-extern uint32 hashchar2(uint16 intkey);
-extern uint32 hashchar4(uint32 intkey);
-extern uint32 hashchar8(char *key);
-extern uint32 hashchar16(char *key);
-extern uint32 hashtext(struct varlena *key);
-extern uint32 hashname(NameData *n);
+extern uint32 hashint2(int16 key);
+extern uint32 hashint4(uint32 key);
+extern uint32 hashfloat4(float32 keyp);
+extern uint32 hashfloat8(float64 keyp);
+extern uint32 hashoid(Oid key);
+extern uint32 hashchar(char key);
+extern uint32 hashchar2(uint16 intkey);
+extern uint32 hashchar4(uint32 intkey);
+extern uint32 hashchar8(char *key);
+extern uint32 hashchar16(char *key);
+extern uint32 hashtext(struct varlena * key);
+extern uint32 hashname(NameData * n);
/* private routines */
@@ -286,50 +290,56 @@ extern InsertIndexResult _hash_doinsert(Relation rel, HashItem hitem);
/* hashovfl.c */
-extern Buffer _hash_addovflpage(Relation rel, Buffer *metabufp, Buffer buf);
-extern Buffer _hash_freeovflpage(Relation rel, Buffer ovflbuf);
-extern int32 _hash_initbitmap(Relation rel, HashMetaPage metap, int32 pnum,
- int32 nbits, int32 ndx);
-extern void _hash_squeezebucket(Relation rel, HashMetaPage metap,
- Bucket bucket);
+extern Buffer _hash_addovflpage(Relation rel, Buffer * metabufp, Buffer buf);
+extern Buffer _hash_freeovflpage(Relation rel, Buffer ovflbuf);
+extern int32
+_hash_initbitmap(Relation rel, HashMetaPage metap, int32 pnum,
+ int32 nbits, int32 ndx);
+extern void
+_hash_squeezebucket(Relation rel, HashMetaPage metap,
+ Bucket bucket);
/* hashpage.c */
-extern void _hash_metapinit(Relation rel);
-extern Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access);
-extern void _hash_relbuf(Relation rel, Buffer buf, int access);
-extern void _hash_wrtbuf(Relation rel, Buffer buf);
-extern void _hash_wrtnorelbuf(Relation rel, Buffer buf);
-extern Page _hash_chgbufaccess(Relation rel, Buffer *bufp, int from_access,
- int to_access);
-extern void _hash_pageinit(Page page, Size size);
-extern void _hash_pagedel(Relation rel, ItemPointer tid);
-extern void _hash_expandtable(Relation rel, Buffer metabuf);
+extern void _hash_metapinit(Relation rel);
+extern Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access);
+extern void _hash_relbuf(Relation rel, Buffer buf, int access);
+extern void _hash_wrtbuf(Relation rel, Buffer buf);
+extern void _hash_wrtnorelbuf(Relation rel, Buffer buf);
+extern Page
+_hash_chgbufaccess(Relation rel, Buffer * bufp, int from_access,
+ int to_access);
+extern void _hash_pageinit(Page page, Size size);
+extern void _hash_pagedel(Relation rel, ItemPointer tid);
+extern void _hash_expandtable(Relation rel, Buffer metabuf);
/* hashscan.c */
-extern void _hash_regscan(IndexScanDesc scan);
-extern void _hash_dropscan(IndexScanDesc scan);
-extern void _hash_adjscans(Relation rel, ItemPointer tid);
+extern void _hash_regscan(IndexScanDesc scan);
+extern void _hash_dropscan(IndexScanDesc scan);
+extern void _hash_adjscans(Relation rel, ItemPointer tid);
/* hashsearch.c */
-extern void _hash_search(Relation rel, int keysz, ScanKey scankey,
- Buffer *bufP, HashMetaPage metap);
+extern void
+_hash_search(Relation rel, int keysz, ScanKey scankey,
+ Buffer * bufP, HashMetaPage metap);
extern RetrieveIndexResult _hash_next(IndexScanDesc scan, ScanDirection dir);
extern RetrieveIndexResult _hash_first(IndexScanDesc scan, ScanDirection dir);
-extern bool _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir,
- Buffer metabuf);
+extern bool
+_hash_step(IndexScanDesc scan, Buffer * bufP, ScanDirection dir,
+ Buffer metabuf);
/* hashutil.c */
-extern ScanKey _hash_mkscankey(Relation rel, IndexTuple itup,
- HashMetaPage metap);
-extern void _hash_freeskey(ScanKey skey);
-extern bool _hash_checkqual(IndexScanDesc scan, IndexTuple itup);
+extern ScanKey
+_hash_mkscankey(Relation rel, IndexTuple itup,
+ HashMetaPage metap);
+extern void _hash_freeskey(ScanKey skey);
+extern bool _hash_checkqual(IndexScanDesc scan, IndexTuple itup);
extern HashItem _hash_formitem(IndexTuple itup);
-extern Bucket _hash_call(Relation rel, HashMetaPage metap, Datum key);
-extern uint32 _hash_log2(uint32 num);
-extern void _hash_checkpage(Page page, int flags);
+extern Bucket _hash_call(Relation rel, HashMetaPage metap, Datum key);
+extern uint32 _hash_log2(uint32 num);
+extern void _hash_checkpage(Page page, int flags);
-#endif /* HASH_H */
+#endif /* HASH_H */
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 7666dc543f2..15f5685e86a 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* heapam.h--
- * POSTGRES heap access method definitions.
+ * POSTGRES heap access method definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: heapam.h,v 1.11 1997/09/04 16:20:55 momjian Exp $
+ * $Id: heapam.h,v 1.12 1997/09/07 04:55:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef HEAPAM_H
+#ifndef HEAPAM_H
#define HEAPAM_H
#include <access/htup.h>
@@ -19,142 +19,154 @@
#include <utils/rel.h>
/* ----------------------------------------------------------------
- * heap access method statistics
+ * heap access method statistics
* ----------------------------------------------------------------
*/
-typedef struct HeapAccessStatisticsData {
- time_t init_global_timestamp; /* time global statistics started */
- time_t local_reset_timestamp; /* last time local reset was done */
- time_t last_request_timestamp; /* last time stats were requested */
-
- int global_open;
- int global_openr;
- int global_close;
- int global_beginscan;
- int global_rescan;
- int global_endscan;
- int global_getnext;
- int global_fetch;
- int global_insert;
- int global_delete;
- int global_replace;
- int global_markpos;
- int global_restrpos;
- int global_BufferGetRelation;
- int global_RelationIdGetRelation;
- int global_RelationIdGetRelation_Buf;
- int global_RelationNameGetRelation;
- int global_getreldesc;
- int global_heapgettup;
- int global_RelationPutHeapTuple;
- int global_RelationPutLongHeapTuple;
-
- int local_open;
- int local_openr;
- int local_close;
- int local_beginscan;
- int local_rescan;
- int local_endscan;
- int local_getnext;
- int local_fetch;
- int local_insert;
- int local_delete;
- int local_replace;
- int local_markpos;
- int local_restrpos;
- int local_BufferGetRelation;
- int local_RelationIdGetRelation;
- int local_RelationIdGetRelation_Buf;
- int local_RelationNameGetRelation;
- int local_getreldesc;
- int local_heapgettup;
- int local_RelationPutHeapTuple;
- int local_RelationPutLongHeapTuple;
-} HeapAccessStatisticsData;
+typedef struct HeapAccessStatisticsData
+{
+ time_t init_global_timestamp; /* time global statistics
+ * started */
+ time_t local_reset_timestamp; /* last time local reset
+ * was done */
+ time_t last_request_timestamp; /* last time stats were
+ * requested */
+
+ int global_open;
+ int global_openr;
+ int global_close;
+ int global_beginscan;
+ int global_rescan;
+ int global_endscan;
+ int global_getnext;
+ int global_fetch;
+ int global_insert;
+ int global_delete;
+ int global_replace;
+ int global_markpos;
+ int global_restrpos;
+ int global_BufferGetRelation;
+ int global_RelationIdGetRelation;
+ int global_RelationIdGetRelation_Buf;
+ int global_RelationNameGetRelation;
+ int global_getreldesc;
+ int global_heapgettup;
+ int global_RelationPutHeapTuple;
+ int global_RelationPutLongHeapTuple;
+
+ int local_open;
+ int local_openr;
+ int local_close;
+ int local_beginscan;
+ int local_rescan;
+ int local_endscan;
+ int local_getnext;
+ int local_fetch;
+ int local_insert;
+ int local_delete;
+ int local_replace;
+ int local_markpos;
+ int local_restrpos;
+ int local_BufferGetRelation;
+ int local_RelationIdGetRelation;
+ int local_RelationIdGetRelation_Buf;
+ int local_RelationNameGetRelation;
+ int local_getreldesc;
+ int local_heapgettup;
+ int local_RelationPutHeapTuple;
+ int local_RelationPutLongHeapTuple;
+} HeapAccessStatisticsData;
typedef HeapAccessStatisticsData *HeapAccessStatistics;
#define IncrHeapAccessStat(x) \
- (heap_access_stats == NULL ? 0 : (heap_access_stats->x)++)
+ (heap_access_stats == NULL ? 0 : (heap_access_stats->x)++)
/* ----------------
- * heap_getattr
+ * heap_getattr
*
- * Find a particular field in a row represented as a heap tuple.
- * We return a pointer into that heap tuple, which points to the
- * first byte of the value of the field in question.
+ * Find a particular field in a row represented as a heap tuple.
+ * We return a pointer into that heap tuple, which points to the
+ * first byte of the value of the field in question.
*
- * If the field in question has a NULL value, we return a null
- * pointer and return <*isnull> == true. Otherwise, we return
- * <*isnull> == false.
+ * If the field in question has a NULL value, we return a null
+ * pointer and return <*isnull> == true. Otherwise, we return
+ * <*isnull> == false.
*
- * <tup> is the pointer to the heap tuple. <attnum> is the attribute
- * number of the column (field) caller wants. <tupleDesc> is a
- * pointer to the structure describing the row and all its fields.
+ * <tup> is the pointer to the heap tuple. <attnum> is the attribute
+ * number of the column (field) caller wants. <tupleDesc> is a
+ * pointer to the structure describing the row and all its fields.
* ---------------- */
#define heap_getattr(tup, b, attnum, tupleDesc, isnull) \
- (AssertMacro((tup) != NULL) ? \
- ((attnum) > (int) (tup)->t_natts) ? \
- (((isnull) ? (*(isnull) = true) : (char)NULL), (char *)NULL) : \
- ((attnum) > 0) ? \
- fastgetattr((tup), (attnum), (tupleDesc), (isnull)) : \
- (((isnull) ? (*(isnull) = false) : (char)NULL), heap_getsysattr((tup), (b), (attnum))) : \
- (char *)NULL)
+ (AssertMacro((tup) != NULL) ? \
+ ((attnum) > (int) (tup)->t_natts) ? \
+ (((isnull) ? (*(isnull) = true) : (char)NULL), (char *)NULL) : \
+ ((attnum) > 0) ? \
+ fastgetattr((tup), (attnum), (tupleDesc), (isnull)) : \
+ (((isnull) ? (*(isnull) = false) : (char)NULL), heap_getsysattr((tup), (b), (attnum))) : \
+ (char *)NULL)
extern HeapAccessStatistics heap_access_stats; /* in stats.c */
/* ----------------
- * function prototypes for heap access method
+ * function prototypes for heap access method
* ----------------
*/
/* heap_create, heap_creatr, and heap_destroy are declared in catalog/heap.h */
/* heapam.c */
-extern void doinsert(Relation relation, HeapTuple tup);
+extern void doinsert(Relation relation, HeapTuple tup);
extern Relation heap_open(Oid relationId);
extern Relation heap_openr(char *relationName);
-extern void heap_close(Relation relation);
-extern HeapScanDesc heap_beginscan(Relation relation, int atend,
- TimeQual timeQual, unsigned nkeys, ScanKey key);
-extern void heap_rescan(HeapScanDesc sdesc, bool scanFromEnd, ScanKey key);
-extern void heap_endscan(HeapScanDesc sdesc);
-extern HeapTuple heap_getnext(HeapScanDesc scandesc, int backw, Buffer *b);
-extern HeapTuple heap_fetch(Relation relation, TimeQual timeQual,
- ItemPointer tid, Buffer *b);
-extern Oid heap_insert(Relation relation, HeapTuple tup);
-extern int heap_delete(Relation relation, ItemPointer tid);
-extern int heap_replace(Relation relation, ItemPointer otid,
- HeapTuple tup);
-extern void heap_markpos(HeapScanDesc sdesc);
-extern void heap_restrpos(HeapScanDesc sdesc);
+extern void heap_close(Relation relation);
+extern HeapScanDesc
+heap_beginscan(Relation relation, int atend,
+ TimeQual timeQual, unsigned nkeys, ScanKey key);
+extern void heap_rescan(HeapScanDesc sdesc, bool scanFromEnd, ScanKey key);
+extern void heap_endscan(HeapScanDesc sdesc);
+extern HeapTuple heap_getnext(HeapScanDesc scandesc, int backw, Buffer * b);
+extern HeapTuple
+heap_fetch(Relation relation, TimeQual timeQual,
+ ItemPointer tid, Buffer * b);
+extern Oid heap_insert(Relation relation, HeapTuple tup);
+extern int heap_delete(Relation relation, ItemPointer tid);
+extern int
+heap_replace(Relation relation, ItemPointer otid,
+ HeapTuple tup);
+extern void heap_markpos(HeapScanDesc sdesc);
+extern void heap_restrpos(HeapScanDesc sdesc);
/* in common/heaptuple.c */
-extern Size ComputeDataSize(TupleDesc tupleDesc, Datum value[], char nulls[]);
-extern void DataFill(char *data, TupleDesc tupleDesc,
- Datum value[], char nulls[], char *infomask,
- bits8 *bit);
-extern int heap_attisnull(HeapTuple tup, int attnum);
-extern int heap_sysattrlen(AttrNumber attno);
-extern bool heap_sysattrbyval(AttrNumber attno);
-extern char *heap_getsysattr(HeapTuple tup, Buffer b, int attnum);
-extern char *fastgetattr(HeapTuple tup, int attnum,
- TupleDesc att, bool *isnull);
+extern Size ComputeDataSize(TupleDesc tupleDesc, Datum value[], char nulls[]);
+extern void
+DataFill(char *data, TupleDesc tupleDesc,
+ Datum value[], char nulls[], char *infomask,
+ bits8 * bit);
+extern int heap_attisnull(HeapTuple tup, int attnum);
+extern int heap_sysattrlen(AttrNumber attno);
+extern bool heap_sysattrbyval(AttrNumber attno);
+extern char *heap_getsysattr(HeapTuple tup, Buffer b, int attnum);
+extern char *
+fastgetattr(HeapTuple tup, int attnum,
+ TupleDesc att, bool * isnull);
extern HeapTuple heap_copytuple(HeapTuple tuple);
-extern HeapTuple heap_formtuple(TupleDesc tupleDescriptor,
- Datum value[], char nulls[]);
-extern HeapTuple heap_modifytuple(HeapTuple tuple, Buffer buffer,
- Relation relation, Datum replValue[], char replNull[], char repl[]);
-HeapTuple heap_addheader(uint32 natts, int structlen, char *structure);
+extern HeapTuple
+heap_formtuple(TupleDesc tupleDescriptor,
+ Datum value[], char nulls[]);
+extern HeapTuple
+heap_modifytuple(HeapTuple tuple, Buffer buffer,
+ Relation relation, Datum replValue[], char replNull[], char repl[]);
+HeapTuple heap_addheader(uint32 natts, int structlen, char *structure);
/* in common/heap/stats.c */
-extern void PrintHeapAccessStatistics(HeapAccessStatistics stats);
-extern void initam(void);
+extern void PrintHeapAccessStatistics(HeapAccessStatistics stats);
+extern void initam(void);
/* hio.c */
-extern void RelationPutHeapTuple(Relation relation, BlockNumber blockIndex,
- HeapTuple tuple);
-extern void RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple);
+extern void
+RelationPutHeapTuple(Relation relation, BlockNumber blockIndex,
+ HeapTuple tuple);
+extern void RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple);
-#endif /* HEAPAM_H */
+#endif /* HEAPAM_H */
diff --git a/src/include/access/hio.h b/src/include/access/hio.h
index 27a3bdb1812..05c9dc330c9 100644
--- a/src/include/access/hio.h
+++ b/src/include/access/hio.h
@@ -1,24 +1,25 @@
/*-------------------------------------------------------------------------
*
* hio.h--
- * POSTGRES heap access method input/output definitions.
+ * POSTGRES heap access method input/output definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: hio.h,v 1.3 1996/11/05 10:37:05 scrappy Exp $
+ * $Id: hio.h,v 1.4 1997/09/07 04:55:56 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef HIO_H
+#ifndef HIO_H
#define HIO_H
#include <access/htup.h>
#include <utils/rel.h>
-extern void RelationPutHeapTuple(Relation relation, BlockNumber blockIndex,
- HeapTuple tuple);
-extern void RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple);
+extern void
+RelationPutHeapTuple(Relation relation, BlockNumber blockIndex,
+ HeapTuple tuple);
+extern void RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple);
-#endif /* HIO_H */
+#endif /* HIO_H */
diff --git a/src/include/access/htup.h b/src/include/access/htup.h
index 2dedd873eae..02d708bb0ad 100644
--- a/src/include/access/htup.h
+++ b/src/include/access/htup.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* htup.h--
- * POSTGRES heap tuple definitions.
+ * POSTGRES heap tuple definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: htup.h,v 1.3 1996/11/04 07:18:11 scrappy Exp $
+ * $Id: htup.h,v 1.4 1997/09/07 04:55:58 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef HTUP_H
+#ifndef HTUP_H
#define HTUP_H
#include <utils/nabstime.h>
@@ -20,94 +20,95 @@
/* check these, they are likely to be more severely limited by t_hoff */
-#define MaxHeapAttributeNumber 1600 /* 8 * 200 */
+#define MaxHeapAttributeNumber 1600 /* 8 * 200 */
/*
* to avoid wasting space, the attributes should be layed out in such a
* way to reduce structure padding.
*/
-typedef struct HeapTupleData {
+typedef struct HeapTupleData
+{
- unsigned int t_len; /* length of entire tuple */
+ unsigned int t_len; /* length of entire tuple */
- ItemPointerData t_ctid; /* current TID of this tuple */
+ ItemPointerData t_ctid; /* current TID of this tuple */
- ItemPointerData t_chain; /* replaced tuple TID */
+ ItemPointerData t_chain; /* replaced tuple TID */
- Oid t_oid; /* OID of this tuple -- 4 bytes */
+ Oid t_oid; /* OID of this tuple -- 4 bytes */
- CommandId t_cmin; /* insert CID stamp -- 2 bytes each */
- CommandId t_cmax; /* delete CommandId stamp */
+ CommandId t_cmin; /* insert CID stamp -- 2 bytes each */
+ CommandId t_cmax; /* delete CommandId stamp */
- TransactionId t_xmin; /* insert XID stamp -- 4 bytes each */
- TransactionId t_xmax; /* delete XID stamp */
+ TransactionId t_xmin; /* insert XID stamp -- 4 bytes each */
+ TransactionId t_xmax; /* delete XID stamp */
- AbsoluteTime t_tmin; /* time stamps -- 4 bytes each */
- AbsoluteTime t_tmax;
+ AbsoluteTime t_tmin; /* time stamps -- 4 bytes each */
+ AbsoluteTime t_tmax;
- int16 t_natts; /* number of attributes */
- char t_vtype; /* not used - padding */
+ int16 t_natts; /* number of attributes */
+ char t_vtype; /* not used - padding */
- char t_infomask; /* whether tuple as null or variable
- * length attributes
- */
+ char t_infomask; /* whether tuple as null or variable
+ * length attributes */
- uint8 t_hoff; /* sizeof tuple header */
+ uint8 t_hoff; /* sizeof tuple header */
- bits8 t_bits[MinHeapTupleBitmapSize / 8];
- /* bit map of domains */
+ bits8 t_bits[MinHeapTupleBitmapSize / 8];
+ /* bit map of domains */
- /* MORE DATA FOLLOWS AT END OF STRUCT */
-} HeapTupleData;
+ /* MORE DATA FOLLOWS AT END OF STRUCT */
+} HeapTupleData;
-typedef HeapTupleData *HeapTuple;
+typedef HeapTupleData *HeapTuple;
-#define SelfItemPointerAttributeNumber (-1)
-#define ObjectIdAttributeNumber (-2)
-#define MinTransactionIdAttributeNumber (-3)
-#define MinCommandIdAttributeNumber (-4)
-#define MaxTransactionIdAttributeNumber (-5)
-#define MaxCommandIdAttributeNumber (-6)
-#define ChainItemPointerAttributeNumber (-7)
-#define AnchorItemPointerAttributeNumber (-8)
-#define MinAbsoluteTimeAttributeNumber (-9)
-#define MaxAbsoluteTimeAttributeNumber (-10)
-#define VersionTypeAttributeNumber (-11)
-#define FirstLowInvalidHeapAttributeNumber (-12)
+#define SelfItemPointerAttributeNumber (-1)
+#define ObjectIdAttributeNumber (-2)
+#define MinTransactionIdAttributeNumber (-3)
+#define MinCommandIdAttributeNumber (-4)
+#define MaxTransactionIdAttributeNumber (-5)
+#define MaxCommandIdAttributeNumber (-6)
+#define ChainItemPointerAttributeNumber (-7)
+#define AnchorItemPointerAttributeNumber (-8)
+#define MinAbsoluteTimeAttributeNumber (-9)
+#define MaxAbsoluteTimeAttributeNumber (-10)
+#define VersionTypeAttributeNumber (-11)
+#define FirstLowInvalidHeapAttributeNumber (-12)
/* ----------------
- * support macros
+ * support macros
* ----------------
*/
#define GETSTRUCT(TUP) (((char *)(TUP)) + ((HeapTuple)(TUP))->t_hoff)
/*
- * BITMAPLEN(NATTS) -
- * Computes minimum size of bitmap given number of domains.
+ * BITMAPLEN(NATTS) -
+ * Computes minimum size of bitmap given number of domains.
*/
#define BITMAPLEN(NATTS) \
- ((((((int)(NATTS) - 1) >> 3) + 4 - (MinHeapTupleBitmapSize >> 3)) \
- & ~03) + (MinHeapTupleBitmapSize >> 3))
+ ((((((int)(NATTS) - 1) >> 3) + 4 - (MinHeapTupleBitmapSize >> 3)) \
+ & ~03) + (MinHeapTupleBitmapSize >> 3))
/*
* HeapTupleIsValid
- * True iff the heap tuple is valid.
+ * True iff the heap tuple is valid.
*/
-#define HeapTupleIsValid(tuple) PointerIsValid(tuple)
+#define HeapTupleIsValid(tuple) PointerIsValid(tuple)
/*
* information stored in t_infomask:
*/
-#define HEAP_HASNULL 0x01 /* has null attribute(s) */
-#define HEAP_HASVARLENA 0x02 /* has variable length attribute(s) */
+#define HEAP_HASNULL 0x01 /* has null attribute(s) */
+#define HEAP_HASVARLENA 0x02 /* has variable length
+ * attribute(s) */
#define HeapTupleNoNulls(tuple) \
- (!(((HeapTuple) (tuple))->t_infomask & HEAP_HASNULL))
+ (!(((HeapTuple) (tuple))->t_infomask & HEAP_HASNULL))
#define HeapTupleAllFixed(tuple) \
- (!(((HeapTuple) (tuple))->t_infomask & HEAP_HASVARLENA))
+ (!(((HeapTuple) (tuple))->t_infomask & HEAP_HASVARLENA))
-#endif /* HTUP_H */
+#endif /* HTUP_H */
diff --git a/src/include/access/ibit.h b/src/include/access/ibit.h
index 8cb17221608..87e2fec53fd 100644
--- a/src/include/access/ibit.h
+++ b/src/include/access/ibit.h
@@ -1,33 +1,34 @@
/*-------------------------------------------------------------------------
*
* ibit.h--
- * POSTGRES index valid attribute bit map definitions.
+ * POSTGRES index valid attribute bit map definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: ibit.h,v 1.4 1996/11/05 07:24:03 scrappy Exp $
+ * $Id: ibit.h,v 1.5 1997/09/07 04:56:01 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef IBIT_H
+#ifndef IBIT_H
#define IBIT_H
#include <utils/memutils.h>
-typedef struct IndexAttributeBitMapData {
- char bits[(MaxIndexAttributeNumber + MaxBitsPerByte - 1)
- / MaxBitsPerByte];
-} IndexAttributeBitMapData;
+typedef struct IndexAttributeBitMapData
+{
+ char bits[(MaxIndexAttributeNumber + MaxBitsPerByte - 1)
+ / MaxBitsPerByte];
+} IndexAttributeBitMapData;
-typedef IndexAttributeBitMapData *IndexAttributeBitMap;
+typedef IndexAttributeBitMapData *IndexAttributeBitMap;
-#define IndexAttributeBitMapSize sizeof(IndexAttributeBitMapData)
+#define IndexAttributeBitMapSize sizeof(IndexAttributeBitMapData)
/*
* IndexAttributeBitMapIsValid --
- * True iff attribute bit map is valid.
+ * True iff attribute bit map is valid.
*/
-#define IndexAttributeBitMapIsValid(bits) PointerIsValid(bits)
+#define IndexAttributeBitMapIsValid(bits) PointerIsValid(bits)
-#endif /* IBIT_H */
+#endif /* IBIT_H */
diff --git a/src/include/access/iqual.h b/src/include/access/iqual.h
index 492c24732f0..233c2f61f87 100644
--- a/src/include/access/iqual.h
+++ b/src/include/access/iqual.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* iqual.h--
- * Index scan key qualification definitions.
+ * Index scan key qualification definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: iqual.h,v 1.4 1996/11/05 10:37:03 scrappy Exp $
+ * $Id: iqual.h,v 1.5 1997/09/07 04:56:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef IQUAL_H
+#ifndef IQUAL_H
#define IQUAL_H
#include <access/skey.h>
@@ -18,13 +18,14 @@
/* ----------------
- * index tuple qualification support
+ * index tuple qualification support
* ----------------
*/
-extern int NIndexTupleProcessed;
+extern int NIndexTupleProcessed;
-extern bool index_keytest(IndexTuple tuple, TupleDesc tupdesc,
+extern bool
+index_keytest(IndexTuple tuple, TupleDesc tupdesc,
int scanKeySize, ScanKey key);
-#endif /* IQUAL_H */
+#endif /* IQUAL_H */
diff --git a/src/include/access/istrat.h b/src/include/access/istrat.h
index 59b4bffa5b1..377a8463446 100644
--- a/src/include/access/istrat.h
+++ b/src/include/access/istrat.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* istrat.h--
- * POSTGRES index strategy definitions.
+ * POSTGRES index strategy definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: istrat.h,v 1.5 1997/08/19 21:37:31 momjian Exp $
+ * $Id: istrat.h,v 1.6 1997/09/07 04:56:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef ISTRAT_H
+#ifndef ISTRAT_H
#define ISTRAT_H
#include <utils/rel.h>
@@ -18,51 +18,55 @@
/*
* StrategyNumberIsValid --
- * True iff the strategy number is valid.
+ * True iff the strategy number is valid.
*/
#define StrategyNumberIsValid(strategyNumber) \
- ((bool) ((strategyNumber) != InvalidStrategy))
+ ((bool) ((strategyNumber) != InvalidStrategy))
/*
* StrategyNumberIsInBounds --
- * True iff strategy number is within given bounds.
+ * True iff strategy number is within given bounds.
*
* Note:
- * Assumes StrategyNumber is an unsigned type.
- * Assumes the bounded interval to be (0,max].
+ * Assumes StrategyNumber is an unsigned type.
+ * Assumes the bounded interval to be (0,max].
*/
#define StrategyNumberIsInBounds(strategyNumber, maxStrategyNumber) \
- ((bool)(InvalidStrategy < (strategyNumber) && \
- (strategyNumber) <= (maxStrategyNumber)))
+ ((bool)(InvalidStrategy < (strategyNumber) && \
+ (strategyNumber) <= (maxStrategyNumber)))
/*
* StrategyMapIsValid --
- * True iff the index strategy mapping is valid.
+ * True iff the index strategy mapping is valid.
*/
-#define StrategyMapIsValid(map) PointerIsValid(map)
+#define StrategyMapIsValid(map) PointerIsValid(map)
/*
* IndexStrategyIsValid --
- * True iff the index strategy is valid.
+ * True iff the index strategy is valid.
*/
-#define IndexStrategyIsValid(s) PointerIsValid(s)
+#define IndexStrategyIsValid(s) PointerIsValid(s)
-extern StrategyMap IndexStrategyGetStrategyMap(IndexStrategy indexStrategy,
- StrategyNumber maxStrategyNum, AttrNumber attrNum);
+extern StrategyMap
+IndexStrategyGetStrategyMap(IndexStrategy indexStrategy,
+ StrategyNumber maxStrategyNum, AttrNumber attrNum);
-extern Size
+extern Size
AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber,
- StrategyNumber maxStrategyNumber);
-extern StrategyNumber RelationGetStrategy(Relation relation,
- AttrNumber attributeNumber, StrategyEvaluation evaluation,
- RegProcedure procedure);
-extern bool RelationInvokeStrategy(Relation relation,
- StrategyEvaluation evaluation, AttrNumber attributeNumber,
- StrategyNumber strategy, Datum left, Datum right);
-extern void IndexSupportInitialize(IndexStrategy indexStrategy,
- RegProcedure *indexSupport, Oid indexObjectId,
- Oid accessMethodObjectId, StrategyNumber maxStrategyNumber,
- StrategyNumber maxSupportNumber, AttrNumber maxAttributeNumber);
+ StrategyNumber maxStrategyNumber);
+extern StrategyNumber
+RelationGetStrategy(Relation relation,
+ AttrNumber attributeNumber, StrategyEvaluation evaluation,
+ RegProcedure procedure);
+extern bool
+RelationInvokeStrategy(Relation relation,
+ StrategyEvaluation evaluation, AttrNumber attributeNumber,
+ StrategyNumber strategy, Datum left, Datum right);
+extern void
+IndexSupportInitialize(IndexStrategy indexStrategy,
+ RegProcedure * indexSupport, Oid indexObjectId,
+ Oid accessMethodObjectId, StrategyNumber maxStrategyNumber,
+ StrategyNumber maxSupportNumber, AttrNumber maxAttributeNumber);
-#endif /* ISTRAT_H */
+#endif /* ISTRAT_H */
diff --git a/src/include/access/itup.h b/src/include/access/itup.h
index 45e19fd8494..742078a3bd1 100644
--- a/src/include/access/itup.h
+++ b/src/include/access/itup.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* itup.h--
- * POSTGRES index tuple definitions.
+ * POSTGRES index tuple definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: itup.h,v 1.5 1997/08/19 21:37:33 momjian Exp $
+ * $Id: itup.h,v 1.6 1997/09/07 04:56:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,69 +16,72 @@
#include <access/tupdesc.h>
#include <storage/itemptr.h>
-#define MaxIndexAttributeNumber 7
+#define MaxIndexAttributeNumber 7
-typedef struct IndexTupleData {
- ItemPointerData t_tid; /* reference TID to base tuple */
+typedef struct IndexTupleData
+{
+ ItemPointerData t_tid; /* reference TID to base tuple */
- /*
- * t_info is layed out in the following fashion:
- *
- * 15th (leftmost) bit: "has nulls" bit
- * 14th bit: "has varlenas" bit
- * 13th bit: "has rules" bit - (removed ay 11/94)
- * bits 12-0 bit: size of tuple.
- */
+ /*
+ * t_info is layed out in the following fashion:
+ *
+ * 15th (leftmost) bit: "has nulls" bit 14th bit: "has varlenas" bit 13th
+ * bit: "has rules" bit - (removed ay 11/94) bits 12-0 bit: size of
+ * tuple.
+ */
- unsigned short t_info; /* various info about tuple */
+ unsigned short t_info; /* various info about tuple */
- /*
- * please make sure sizeof(IndexTupleData) is MAXALIGN'ed.
- * See IndexInfoFindDataOffset() for the reason.
- */
-
-} IndexTupleData; /* MORE DATA FOLLOWS AT END OF STRUCT */
+ /*
+ * please make sure sizeof(IndexTupleData) is MAXALIGN'ed. See
+ * IndexInfoFindDataOffset() for the reason.
+ */
-typedef IndexTupleData *IndexTuple;
+} IndexTupleData; /* MORE DATA FOLLOWS AT END OF STRUCT */
+typedef IndexTupleData *IndexTuple;
-typedef struct InsertIndexResultData {
- ItemPointerData pointerData;
-} InsertIndexResultData;
+
+typedef struct InsertIndexResultData
+{
+ ItemPointerData pointerData;
+} InsertIndexResultData;
typedef InsertIndexResultData *InsertIndexResult;
-typedef struct RetrieveIndexResultData {
- ItemPointerData index_iptr;
- ItemPointerData heap_iptr;
-} RetrieveIndexResultData;
+typedef struct RetrieveIndexResultData
+{
+ ItemPointerData index_iptr;
+ ItemPointerData heap_iptr;
+} RetrieveIndexResultData;
-typedef RetrieveIndexResultData *RetrieveIndexResult;
+typedef RetrieveIndexResultData *RetrieveIndexResult;
/*-----------------
* PredInfo -
- * used for partial indices
+ * used for partial indices
*-----------------
*/
-typedef struct PredInfo {
- Node *pred;
- Node *oldPred;
-} PredInfo;
+typedef struct PredInfo
+{
+ Node *pred;
+ Node *oldPred;
+} PredInfo;
/* ----------------
- * externs
+ * externs
* ----------------
*/
#define INDEX_SIZE_MASK 0x1FFF
#define INDEX_NULL_MASK 0x8000
-#define INDEX_VAR_MASK 0x4000
+#define INDEX_VAR_MASK 0x4000
-#define IndexTupleSize(itup) (((IndexTuple) (itup))->t_info & 0x1FFF)
-#define IndexTupleDSize(itup) ((itup).t_info & 0x1FFF)
+#define IndexTupleSize(itup) (((IndexTuple) (itup))->t_info & 0x1FFF)
+#define IndexTupleDSize(itup) ((itup).t_info & 0x1FFF)
#define IndexTupleNoNulls(itup) (!(((IndexTuple) (itup))->t_info & 0x8000))
#define IndexTupleAllFixed(itup) (!(((IndexTuple) (itup))->t_info & 0x4000))
@@ -86,15 +89,16 @@ typedef struct PredInfo {
/* indextuple.h */
-extern IndexTuple index_formtuple(TupleDesc tupleDescriptor,
- Datum value[], char null[]);
-extern Datum index_getattr(IndexTuple tuple, AttrNumber attNum,
- TupleDesc tupDesc, bool *isNullOutP);
-extern RetrieveIndexResult
+extern IndexTuple
+index_formtuple(TupleDesc tupleDescriptor,
+ Datum value[], char null[]);
+extern Datum
+index_getattr(IndexTuple tuple, AttrNumber attNum,
+ TupleDesc tupDesc, bool * isNullOutP);
+extern RetrieveIndexResult
FormRetrieveIndexResult(ItemPointer indexItemPointer,
- ItemPointer heapItemPointer);
-extern void CopyIndexTuple(IndexTuple source, IndexTuple *target);
-
+ ItemPointer heapItemPointer);
+extern void CopyIndexTuple(IndexTuple source, IndexTuple * target);
-#endif /* ITUP_H */
+#endif /* ITUP_H */
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index 89f1085929a..0062431d6cb 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* nbtree.h--
- * header file for postgres btree access method implementation.
+ * header file for postgres btree access method implementation.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nbtree.h,v 1.14 1997/08/19 21:37:35 momjian Exp $
+ * $Id: nbtree.h,v 1.15 1997/09/07 04:56:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NBTREE_H
-#define NBTREE_H
+#ifndef NBTREE_H
+#define NBTREE_H
#include <access/sdir.h>
#include <access/relscan.h>
@@ -23,184 +23,189 @@
#include <storage/itemptr.h>
/*
- * BTPageOpaqueData -- At the end of every page, we store a pointer
- * to both siblings in the tree. See Lehman and Yao's paper for more
- * info. In addition, we need to know what sort of page this is
- * (leaf or internal), and whether the page is available for reuse.
+ * BTPageOpaqueData -- At the end of every page, we store a pointer
+ * to both siblings in the tree. See Lehman and Yao's paper for more
+ * info. In addition, we need to know what sort of page this is
+ * (leaf or internal), and whether the page is available for reuse.
*
- * Lehman and Yao's algorithm requires a ``high key'' on every page.
- * The high key on a page is guaranteed to be greater than or equal
- * to any key that appears on this page. Our insertion algorithm
- * guarantees that we can use the initial least key on our right
- * sibling as the high key. We allocate space for the line pointer
- * to the high key in the opaque data at the end of the page.
+ * Lehman and Yao's algorithm requires a ``high key'' on every page.
+ * The high key on a page is guaranteed to be greater than or equal
+ * to any key that appears on this page. Our insertion algorithm
+ * guarantees that we can use the initial least key on our right
+ * sibling as the high key. We allocate space for the line pointer
+ * to the high key in the opaque data at the end of the page.
*
- * Rightmost pages in the tree have no high key.
+ * Rightmost pages in the tree have no high key.
*/
-typedef struct BTPageOpaqueData {
- BlockNumber btpo_prev;
- BlockNumber btpo_next;
- uint16 btpo_flags;
+typedef struct BTPageOpaqueData
+{
+ BlockNumber btpo_prev;
+ BlockNumber btpo_next;
+ uint16 btpo_flags;
-#define BTP_LEAF (1 << 0)
-#define BTP_ROOT (1 << 1)
-#define BTP_FREE (1 << 2)
-#define BTP_META (1 << 3)
-#define BTP_CHAIN (1 << 4)
+#define BTP_LEAF (1 << 0)
+#define BTP_ROOT (1 << 1)
+#define BTP_FREE (1 << 2)
+#define BTP_META (1 << 3)
+#define BTP_CHAIN (1 << 4)
-} BTPageOpaqueData;
+} BTPageOpaqueData;
-typedef BTPageOpaqueData *BTPageOpaque;
+typedef BTPageOpaqueData *BTPageOpaque;
/*
- * ScanOpaqueData is used to remember which buffers we're currently
- * examining in the scan. We keep these buffers locked and pinned
- * and recorded in the opaque entry of the scan in order to avoid
- * doing a ReadBuffer() for every tuple in the index. This avoids
- * semop() calls, which are expensive.
+ * ScanOpaqueData is used to remember which buffers we're currently
+ * examining in the scan. We keep these buffers locked and pinned
+ * and recorded in the opaque entry of the scan in order to avoid
+ * doing a ReadBuffer() for every tuple in the index. This avoids
+ * semop() calls, which are expensive.
*
- * And it's used to remember actual scankey info (we need in it
- * if some scankeys evaled at runtime.
+ * And it's used to remember actual scankey info (we need in it
+ * if some scankeys evaled at runtime.
*/
-typedef struct BTScanOpaqueData {
- Buffer btso_curbuf;
- Buffer btso_mrkbuf;
- uint16 qual_ok; /* 0 for quals like key == 1 && key > 2 */
- uint16 numberOfKeys; /* number of keys */
- uint16 numberOfFirstKeys; /* number of keys for 1st attribute */
- ScanKey keyData; /* key descriptor */
-} BTScanOpaqueData;
+typedef struct BTScanOpaqueData
+{
+ Buffer btso_curbuf;
+ Buffer btso_mrkbuf;
+ uint16 qual_ok; /* 0 for quals like key == 1 && key > 2 */
+ uint16 numberOfKeys; /* number of keys */
+ uint16 numberOfFirstKeys; /* number of keys for 1st
+ * attribute */
+ ScanKey keyData; /* key descriptor */
+} BTScanOpaqueData;
-typedef BTScanOpaqueData *BTScanOpaque;
+typedef BTScanOpaqueData *BTScanOpaque;
/*
- * BTItems are what we store in the btree. Each item has an index
- * tuple, including key and pointer values. In addition, we must
- * guarantee that all tuples in the index are unique, in order to
- * satisfy some assumptions in Lehman and Yao. The way that we do
- * this is by generating a new OID for every insertion that we do in
- * the tree. This adds eight bytes to the size of btree index
- * tuples. Note that we do not use the OID as part of a composite
- * key; the OID only serves as a unique identifier for a given index
- * tuple (logical position within a page).
+ * BTItems are what we store in the btree. Each item has an index
+ * tuple, including key and pointer values. In addition, we must
+ * guarantee that all tuples in the index are unique, in order to
+ * satisfy some assumptions in Lehman and Yao. The way that we do
+ * this is by generating a new OID for every insertion that we do in
+ * the tree. This adds eight bytes to the size of btree index
+ * tuples. Note that we do not use the OID as part of a composite
+ * key; the OID only serves as a unique identifier for a given index
+ * tuple (logical position within a page).
*
- * New comments:
- * actually, we must guarantee that all tuples in A LEVEL
- * are unique, not in ALL INDEX. So, we can use bti_itup->t_tid
- * as unique identifier for a given index tuple (logical position
- * within a level). - vadim 04/09/97
+ * New comments:
+ * actually, we must guarantee that all tuples in A LEVEL
+ * are unique, not in ALL INDEX. So, we can use bti_itup->t_tid
+ * as unique identifier for a given index tuple (logical position
+ * within a level). - vadim 04/09/97
*/
-typedef struct BTItemData {
+typedef struct BTItemData
+{
#ifndef BTREE_VERSION_1
- Oid bti_oid;
- int32 bti_dummy; /* padding to make bti_itup
- * align at 8-byte boundary
- */
+ Oid bti_oid;
+ int32 bti_dummy; /* padding to make bti_itup align at
+ * 8-byte boundary */
#endif
- IndexTupleData bti_itup;
-} BTItemData;
+ IndexTupleData bti_itup;
+} BTItemData;
-typedef BTItemData *BTItem;
+typedef BTItemData *BTItem;
#ifdef BTREE_VERSION_1
-#define BTItemSame(i1, i2) ( i1->bti_itup.t_tid.ip_blkid.bi_hi == \
- i2->bti_itup.t_tid.ip_blkid.bi_hi && \
- i1->bti_itup.t_tid.ip_blkid.bi_lo == \
- i2->bti_itup.t_tid.ip_blkid.bi_lo && \
- i1->bti_itup.t_tid.ip_posid == \
- i2->bti_itup.t_tid.ip_posid )
+#define BTItemSame(i1, i2) ( i1->bti_itup.t_tid.ip_blkid.bi_hi == \
+ i2->bti_itup.t_tid.ip_blkid.bi_hi && \
+ i1->bti_itup.t_tid.ip_blkid.bi_lo == \
+ i2->bti_itup.t_tid.ip_blkid.bi_lo && \
+ i1->bti_itup.t_tid.ip_posid == \
+ i2->bti_itup.t_tid.ip_posid )
#else
-#define BTItemSame(i1, i2) ( i1->bti_oid == i2->bti_oid )
+#define BTItemSame(i1, i2) ( i1->bti_oid == i2->bti_oid )
#endif
/*
- * BTStackData -- As we descend a tree, we push the (key, pointer)
- * pairs from internal nodes onto a private stack. If we split a
- * leaf, we use this stack to walk back up the tree and insert data
- * into parent nodes (and possibly to split them, too). Lehman and
- * Yao's update algorithm guarantees that under no circumstances can
- * our private stack give us an irredeemably bad picture up the tree.
- * Again, see the paper for details.
+ * BTStackData -- As we descend a tree, we push the (key, pointer)
+ * pairs from internal nodes onto a private stack. If we split a
+ * leaf, we use this stack to walk back up the tree and insert data
+ * into parent nodes (and possibly to split them, too). Lehman and
+ * Yao's update algorithm guarantees that under no circumstances can
+ * our private stack give us an irredeemably bad picture up the tree.
+ * Again, see the paper for details.
*/
-typedef struct BTStackData {
- BlockNumber bts_blkno;
- OffsetNumber bts_offset;
- BTItem bts_btitem;
- struct BTStackData *bts_parent;
-} BTStackData;
-
-typedef BTStackData *BTStack;
-
-typedef struct BTPageState {
- Buffer btps_buf;
- Page btps_page;
- BTItem btps_lastbti;
- OffsetNumber btps_lastoff;
- OffsetNumber btps_firstoff;
- int btps_level;
- bool btps_doupper;
- struct BTPageState *btps_next;
-} BTPageState;
+typedef struct BTStackData
+{
+ BlockNumber bts_blkno;
+ OffsetNumber bts_offset;
+ BTItem bts_btitem;
+ struct BTStackData *bts_parent;
+} BTStackData;
+
+typedef BTStackData *BTStack;
+
+typedef struct BTPageState
+{
+ Buffer btps_buf;
+ Page btps_page;
+ BTItem btps_lastbti;
+ OffsetNumber btps_lastoff;
+ OffsetNumber btps_firstoff;
+ int btps_level;
+ bool btps_doupper;
+ struct BTPageState *btps_next;
+} BTPageState;
/*
- * We need to be able to tell the difference between read and write
- * requests for pages, in order to do locking correctly.
+ * We need to be able to tell the difference between read and write
+ * requests for pages, in order to do locking correctly.
*/
-#define BT_READ 0
-#define BT_WRITE 1
+#define BT_READ 0
+#define BT_WRITE 1
/*
- * Similarly, the difference between insertion and non-insertion binary
- * searches on a given page makes a difference when we're descending the
- * tree.
+ * Similarly, the difference between insertion and non-insertion binary
+ * searches on a given page makes a difference when we're descending the
+ * tree.
*/
#define BT_INSERTION 0
-#define BT_DESCENT 1
+#define BT_DESCENT 1
/*
- * We must classify index modification types for the benefit of
- * _bt_adjscans.
+ * We must classify index modification types for the benefit of
+ * _bt_adjscans.
*/
-#define BT_INSERT 0
-#define BT_DELETE 1
+#define BT_INSERT 0
+#define BT_DELETE 1
/*
- * In general, the btree code tries to localize its knowledge about
- * page layout to a couple of routines. However, we need a special
- * value to indicate "no page number" in those places where we expect
- * page numbers.
+ * In general, the btree code tries to localize its knowledge about
+ * page layout to a couple of routines. However, we need a special
+ * value to indicate "no page number" in those places where we expect
+ * page numbers.
*/
-#define P_NONE 0
-#define P_LEFTMOST(opaque) ((opaque)->btpo_prev == P_NONE)
-#define P_RIGHTMOST(opaque) ((opaque)->btpo_next == P_NONE)
+#define P_NONE 0
+#define P_LEFTMOST(opaque) ((opaque)->btpo_prev == P_NONE)
+#define P_RIGHTMOST(opaque) ((opaque)->btpo_next == P_NONE)
-#define P_HIKEY ((OffsetNumber) 1)
-#define P_FIRSTKEY ((OffsetNumber) 2)
+#define P_HIKEY ((OffsetNumber) 1)
+#define P_FIRSTKEY ((OffsetNumber) 2)
/*
- * Strategy numbers -- ordering of these is <, <=, =, >=, >
+ * Strategy numbers -- ordering of these is <, <=, =, >=, >
*/
-#define BTLessStrategyNumber 1
-#define BTLessEqualStrategyNumber 2
-#define BTEqualStrategyNumber 3
+#define BTLessStrategyNumber 1
+#define BTLessEqualStrategyNumber 2
+#define BTEqualStrategyNumber 3
#define BTGreaterEqualStrategyNumber 4
-#define BTGreaterStrategyNumber 5
-#define BTMaxStrategyNumber 5
+#define BTGreaterStrategyNumber 5
+#define BTMaxStrategyNumber 5
/*
- * When a new operator class is declared, we require that the user
- * supply us with an amproc procedure for determining whether, for
- * two keys a and b, a < b, a = b, or a > b. This routine must
- * return < 0, 0, > 0, respectively, in these three cases. Since we
- * only have one such proc in amproc, it's number 1.
+ * When a new operator class is declared, we require that the user
+ * supply us with an amproc procedure for determining whether, for
+ * two keys a and b, a < b, a = b, or a > b. This routine must
+ * return < 0, 0, > 0, respectively, in these three cases. Since we
+ * only have one such proc in amproc, it's number 1.
*/
#define BTORDER_PROC 1
@@ -208,94 +213,105 @@ typedef struct BTPageState {
/*
* prototypes for functions in nbtinsert.c
*/
-extern InsertIndexResult _bt_doinsert(Relation rel, BTItem btitem,
- bool index_is_unique, Relation heapRel);
+extern InsertIndexResult
+_bt_doinsert(Relation rel, BTItem btitem,
+ bool index_is_unique, Relation heapRel);
- /* default is to allow duplicates */
-extern bool _bt_itemcmp(Relation rel, Size keysz, BTItem item1, BTItem item2,
+ /* default is to allow duplicates */
+extern bool
+_bt_itemcmp(Relation rel, Size keysz, BTItem item1, BTItem item2,
StrategyNumber strat);
/*
* prototypes for functions in nbtpage.c
*/
-extern void _bt_metapinit(Relation rel);
-extern Buffer _bt_getroot(Relation rel, int access);
-extern Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access);
-extern void _bt_relbuf(Relation rel, Buffer buf, int access);
-extern void _bt_wrtbuf(Relation rel, Buffer buf);
-extern void _bt_wrtnorelbuf(Relation rel, Buffer buf);
-extern void _bt_pageinit(Page page, Size size);
-extern void _bt_metaproot(Relation rel, BlockNumber rootbknum, int level);
-extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, int access);
-extern void _bt_pagedel(Relation rel, ItemPointer tid);
+extern void _bt_metapinit(Relation rel);
+extern Buffer _bt_getroot(Relation rel, int access);
+extern Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access);
+extern void _bt_relbuf(Relation rel, Buffer buf, int access);
+extern void _bt_wrtbuf(Relation rel, Buffer buf);
+extern void _bt_wrtnorelbuf(Relation rel, Buffer buf);
+extern void _bt_pageinit(Page page, Size size);
+extern void _bt_metaproot(Relation rel, BlockNumber rootbknum, int level);
+extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, int access);
+extern void _bt_pagedel(Relation rel, ItemPointer tid);
/*
* prototypes for functions in nbtree.c
*/
-extern bool BuildingBtree; /* in nbtree.c */
-
-extern void btbuild(Relation heap, Relation index, int natts,
- AttrNumber *attnum, IndexStrategy istrat, uint16 pcount,
- Datum *params, FuncIndexInfo *finfo, PredInfo *predInfo);
-extern InsertIndexResult btinsert(Relation rel, Datum *datum, char *nulls,
- ItemPointer ht_ctid, Relation heapRel);
-extern char *btgettuple(IndexScanDesc scan, ScanDirection dir);
-extern char *btbeginscan(Relation rel, bool fromEnd, uint16 keysz,
- ScanKey scankey);
-
-extern void btrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey);
-extern void btmovescan(IndexScanDesc scan, Datum v);
-extern void btendscan(IndexScanDesc scan);
-extern void btmarkpos(IndexScanDesc scan);
-extern void btrestrpos(IndexScanDesc scan);
-extern void btdelete(Relation rel, ItemPointer tid);
+extern bool BuildingBtree; /* in nbtree.c */
+
+extern void
+btbuild(Relation heap, Relation index, int natts,
+ AttrNumber * attnum, IndexStrategy istrat, uint16 pcount,
+ Datum * params, FuncIndexInfo * finfo, PredInfo * predInfo);
+extern InsertIndexResult
+btinsert(Relation rel, Datum * datum, char *nulls,
+ ItemPointer ht_ctid, Relation heapRel);
+extern char *btgettuple(IndexScanDesc scan, ScanDirection dir);
+extern char *
+btbeginscan(Relation rel, bool fromEnd, uint16 keysz,
+ ScanKey scankey);
+
+extern void btrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey);
+extern void btmovescan(IndexScanDesc scan, Datum v);
+extern void btendscan(IndexScanDesc scan);
+extern void btmarkpos(IndexScanDesc scan);
+extern void btrestrpos(IndexScanDesc scan);
+extern void btdelete(Relation rel, ItemPointer tid);
/*
* prototypes for functions in nbtscan.c
*/
-extern void _bt_regscan(IndexScanDesc scan);
-extern void _bt_dropscan(IndexScanDesc scan);
-extern void _bt_adjscans(Relation rel, ItemPointer tid, int op);
+extern void _bt_regscan(IndexScanDesc scan);
+extern void _bt_dropscan(IndexScanDesc scan);
+extern void _bt_adjscans(Relation rel, ItemPointer tid, int op);
/*
* prototypes for functions in nbtsearch.c
*/
-extern BTStack _bt_search(Relation rel, int keysz, ScanKey scankey,
- Buffer *bufP);
-extern Buffer _bt_moveright(Relation rel, Buffer buf, int keysz,
- ScanKey scankey, int access);
-extern bool _bt_skeycmp(Relation rel, Size keysz, ScanKey scankey,
+extern BTStack
+_bt_search(Relation rel, int keysz, ScanKey scankey,
+ Buffer * bufP);
+extern Buffer
+_bt_moveright(Relation rel, Buffer buf, int keysz,
+ ScanKey scankey, int access);
+extern bool
+_bt_skeycmp(Relation rel, Size keysz, ScanKey scankey,
Page page, ItemId itemid, StrategyNumber strat);
-extern OffsetNumber _bt_binsrch(Relation rel, Buffer buf, int keysz,
- ScanKey scankey, int srchtype);
+extern OffsetNumber
+_bt_binsrch(Relation rel, Buffer buf, int keysz,
+ ScanKey scankey, int srchtype);
extern RetrieveIndexResult _bt_next(IndexScanDesc scan, ScanDirection dir);
extern RetrieveIndexResult _bt_first(IndexScanDesc scan, ScanDirection dir);
-extern bool _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir);
+extern bool _bt_step(IndexScanDesc scan, Buffer * bufP, ScanDirection dir);
/*
* prototypes for functions in nbtstrat.c
*/
-extern StrategyNumber _bt_getstrat(Relation rel, AttrNumber attno,
- RegProcedure proc);
-extern bool _bt_invokestrat(Relation rel, AttrNumber attno,
- StrategyNumber strat, Datum left, Datum right);
+extern StrategyNumber
+_bt_getstrat(Relation rel, AttrNumber attno,
+ RegProcedure proc);
+extern bool
+_bt_invokestrat(Relation rel, AttrNumber attno,
+ StrategyNumber strat, Datum left, Datum right);
/*
* prototypes for functions in nbtutils.c
*/
-extern ScanKey _bt_mkscankey(Relation rel, IndexTuple itup);
-extern void _bt_freeskey(ScanKey skey);
-extern void _bt_freestack(BTStack stack);
-extern void _bt_orderkeys(Relation relation, BTScanOpaque so);
-extern bool _bt_checkkeys (IndexScanDesc scan, IndexTuple tuple, Size *keysok);
-extern BTItem _bt_formitem(IndexTuple itup);
+extern ScanKey _bt_mkscankey(Relation rel, IndexTuple itup);
+extern void _bt_freeskey(ScanKey skey);
+extern void _bt_freestack(BTStack stack);
+extern void _bt_orderkeys(Relation relation, BTScanOpaque so);
+extern bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, Size * keysok);
+extern BTItem _bt_formitem(IndexTuple itup);
/*
* prototypes for functions in nbtsort.c
*/
-extern void *_bt_spoolinit(Relation index, int ntapes, bool isunique);
-extern void _bt_spooldestroy(void *spool);
-extern void _bt_spool(Relation index, BTItem btitem, void *spool);
-extern void _bt_leafbuild(Relation index, void *spool);
+extern void *_bt_spoolinit(Relation index, int ntapes, bool isunique);
+extern void _bt_spooldestroy(void *spool);
+extern void _bt_spool(Relation index, BTItem btitem, void *spool);
+extern void _bt_leafbuild(Relation index, void *spool);
-#endif /* NBTREE_H */
+#endif /* NBTREE_H */
diff --git a/src/include/access/printtup.h b/src/include/access/printtup.h
index 81321c6ca6f..65994dbe7ef 100644
--- a/src/include/access/printtup.h
+++ b/src/include/access/printtup.h
@@ -1,26 +1,26 @@
/*-------------------------------------------------------------------------
*
* printtup.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: printtup.h,v 1.2 1996/11/06 08:52:04 scrappy Exp $
+ * $Id: printtup.h,v 1.3 1997/09/07 04:56:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef PRINTTUP_H
+#ifndef PRINTTUP_H
#define PRINTTUP_H
#include <access/htup.h>
#include <access/tupdesc.h>
-extern Oid typtoout(Oid type);
-extern void printtup(HeapTuple tuple, TupleDesc typeinfo);
-extern void showatts(char *name, TupleDesc attinfo);
-extern void debugtup(HeapTuple tuple, TupleDesc typeinfo);
-extern void printtup_internal(HeapTuple tuple, TupleDesc typeinfo);
-extern Oid gettypelem(Oid type);
+extern Oid typtoout(Oid type);
+extern void printtup(HeapTuple tuple, TupleDesc typeinfo);
+extern void showatts(char *name, TupleDesc attinfo);
+extern void debugtup(HeapTuple tuple, TupleDesc typeinfo);
+extern void printtup_internal(HeapTuple tuple, TupleDesc typeinfo);
+extern Oid gettypelem(Oid type);
-#endif /* PRINTTUP_H */
+#endif /* PRINTTUP_H */
diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h
index 60a2be58dea..356bcefc529 100644
--- a/src/include/access/relscan.h
+++ b/src/include/access/relscan.h
@@ -1,80 +1,82 @@
/*-------------------------------------------------------------------------
*
* relscan.h--
- * POSTGRES internal relation scan descriptor definitions.
+ * POSTGRES internal relation scan descriptor definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: relscan.h,v 1.5 1996/11/04 08:52:41 scrappy Exp $
+ * $Id: relscan.h,v 1.6 1997/09/07 04:56:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef RELSCAN_H
+#ifndef RELSCAN_H
#define RELSCAN_H
#include <utils/tqual.h>
#include <storage/buf.h>
#include <utils/rel.h>
-typedef ItemPointerData MarkData;
+typedef ItemPointerData MarkData;
-typedef struct HeapScanDescData {
- Relation rs_rd; /* pointer to relation descriptor */
- HeapTuple rs_ptup; /* previous tuple in scan */
- HeapTuple rs_ctup; /* current tuple in scan */
- HeapTuple rs_ntup; /* next tuple in scan */
- Buffer rs_pbuf; /* previous buffer in scan */
- Buffer rs_cbuf; /* current buffer in scan */
- Buffer rs_nbuf; /* next buffer in scan */
- ItemPointerData rs_mptid; /* marked previous tid */
- ItemPointerData rs_mctid; /* marked current tid */
- ItemPointerData rs_mntid; /* marked next tid */
- ItemPointerData rs_mcd; /* marked current delta XXX ??? */
- bool rs_atend; /* restart scan at end? */
- TimeQual rs_tr; /* time qualification */
- uint16 rs_cdelta; /* current delta in chain */
- uint16 rs_nkeys; /* number of attributes in keys */
- ScanKey rs_key; /* key descriptors */
-} HeapScanDescData;
+typedef struct HeapScanDescData
+{
+ Relation rs_rd; /* pointer to relation descriptor */
+ HeapTuple rs_ptup; /* previous tuple in scan */
+ HeapTuple rs_ctup; /* current tuple in scan */
+ HeapTuple rs_ntup; /* next tuple in scan */
+ Buffer rs_pbuf; /* previous buffer in scan */
+ Buffer rs_cbuf; /* current buffer in scan */
+ Buffer rs_nbuf; /* next buffer in scan */
+ ItemPointerData rs_mptid; /* marked previous tid */
+ ItemPointerData rs_mctid; /* marked current tid */
+ ItemPointerData rs_mntid; /* marked next tid */
+ ItemPointerData rs_mcd; /* marked current delta XXX ??? */
+ bool rs_atend; /* restart scan at end? */
+ TimeQual rs_tr; /* time qualification */
+ uint16 rs_cdelta; /* current delta in chain */
+ uint16 rs_nkeys; /* number of attributes in keys */
+ ScanKey rs_key; /* key descriptors */
+} HeapScanDescData;
typedef HeapScanDescData *HeapScanDesc;
-typedef struct IndexScanDescData {
- Relation relation; /* relation descriptor */
- void *opaque; /* am-specific slot */
- ItemPointerData previousItemData; /* previous index pointer */
- ItemPointerData currentItemData; /* current index pointer */
- ItemPointerData nextItemData; /* next index pointer */
- MarkData previousMarkData; /* marked previous pointer */
- MarkData currentMarkData; /* marked current pointer */
- MarkData nextMarkData; /* marked next pointer */
- uint8 flags; /* scan position flags */
- bool scanFromEnd; /* restart scan at end? */
- uint16 numberOfKeys; /* number of key attributes */
- ScanKey keyData; /* key descriptor */
-} IndexScanDescData;
+typedef struct IndexScanDescData
+{
+ Relation relation; /* relation descriptor */
+ void *opaque; /* am-specific slot */
+ ItemPointerData previousItemData; /* previous index pointer */
+ ItemPointerData currentItemData; /* current index pointer */
+ ItemPointerData nextItemData; /* next index pointer */
+ MarkData previousMarkData; /* marked previous pointer */
+ MarkData currentMarkData; /* marked current pointer */
+ MarkData nextMarkData; /* marked next pointer */
+ uint8 flags; /* scan position flags */
+ bool scanFromEnd;/* restart scan at end? */
+ uint16 numberOfKeys; /* number of key attributes */
+ ScanKey keyData; /* key descriptor */
+} IndexScanDescData;
-typedef IndexScanDescData *IndexScanDesc;
+typedef IndexScanDescData *IndexScanDesc;
/* ----------------
- * IndexScanDescPtr is used in the executor where we have to
- * keep track of several index scans when using several indices
- * - cim 9/10/89
+ * IndexScanDescPtr is used in the executor where we have to
+ * keep track of several index scans when using several indices
+ * - cim 9/10/89
* ----------------
*/
-typedef IndexScanDesc *IndexScanDescPtr;
+typedef IndexScanDesc *IndexScanDescPtr;
/*
* HeapScanIsValid --
- * True iff the heap scan is valid.
+ * True iff the heap scan is valid.
*/
-#define HeapScanIsValid(scan) PointerIsValid(scan)
+#define HeapScanIsValid(scan) PointerIsValid(scan)
/*
* IndexScanIsValid --
- * True iff the index scan is valid.
+ * True iff the index scan is valid.
*/
#define IndexScanIsValid(scan) PointerIsValid(scan)
-#endif /* RELSCAN_H */
+#endif /* RELSCAN_H */
diff --git a/src/include/access/rtree.h b/src/include/access/rtree.h
index c134d3dbbed..98699eba37f 100644
--- a/src/include/access/rtree.h
+++ b/src/include/access/rtree.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* rtree.h--
- * common declarations for the rtree access method code.
+ * common declarations for the rtree access method code.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rtree.h,v 1.6 1997/08/19 21:37:36 momjian Exp $
+ * $Id: rtree.h,v 1.7 1997/09/07 04:56:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,116 +23,125 @@
#include <storage/off.h>
/* see rtstrat.c for what all this is about */
-#define RTNStrategies 8
-#define RTLeftStrategyNumber 1
-#define RTOverLeftStrategyNumber 2
-#define RTOverlapStrategyNumber 3
-#define RTOverRightStrategyNumber 4
-#define RTRightStrategyNumber 5
-#define RTSameStrategyNumber 6
-#define RTContainsStrategyNumber 7
-#define RTContainedByStrategyNumber 8
-
-#define RTNProcs 3
-#define RT_UNION_PROC 1
-#define RT_INTER_PROC 2
-#define RT_SIZE_PROC 3
-
-#define F_LEAF (1 << 0)
-
-typedef struct RTreePageOpaqueData {
- uint32 flags;
-} RTreePageOpaqueData;
-
-typedef RTreePageOpaqueData *RTreePageOpaque;
+#define RTNStrategies 8
+#define RTLeftStrategyNumber 1
+#define RTOverLeftStrategyNumber 2
+#define RTOverlapStrategyNumber 3
+#define RTOverRightStrategyNumber 4
+#define RTRightStrategyNumber 5
+#define RTSameStrategyNumber 6
+#define RTContainsStrategyNumber 7
+#define RTContainedByStrategyNumber 8
+
+#define RTNProcs 3
+#define RT_UNION_PROC 1
+#define RT_INTER_PROC 2
+#define RT_SIZE_PROC 3
+
+#define F_LEAF (1 << 0)
+
+typedef struct RTreePageOpaqueData
+{
+ uint32 flags;
+} RTreePageOpaqueData;
+
+typedef RTreePageOpaqueData *RTreePageOpaque;
/*
- * When we descend a tree, we keep a stack of parent pointers.
+ * When we descend a tree, we keep a stack of parent pointers.
*/
-typedef struct RTSTACK {
- struct RTSTACK *rts_parent;
+typedef struct RTSTACK
+{
+ struct RTSTACK *rts_parent;
OffsetNumber rts_child;
- BlockNumber rts_blk;
-} RTSTACK;
+ BlockNumber rts_blk;
+} RTSTACK;
/*
- * When we're doing a scan, we need to keep track of the parent stack
- * for the marked and current items. Also, rtrees have the following
- * property: if you're looking for the box (1,1,2,2), on the internal
- * nodes you have to search for all boxes that *contain* (1,1,2,2), and
- * not the ones that match it. We have a private scan key for internal
- * nodes in the opaque structure for rtrees for this reason. See
- * access/index-rtree/rtscan.c and rtstrat.c for how it gets initialized.
+ * When we're doing a scan, we need to keep track of the parent stack
+ * for the marked and current items. Also, rtrees have the following
+ * property: if you're looking for the box (1,1,2,2), on the internal
+ * nodes you have to search for all boxes that *contain* (1,1,2,2), and
+ * not the ones that match it. We have a private scan key for internal
+ * nodes in the opaque structure for rtrees for this reason. See
+ * access/index-rtree/rtscan.c and rtstrat.c for how it gets initialized.
*/
-typedef struct RTreeScanOpaqueData {
- struct RTSTACK *s_stack;
- struct RTSTACK *s_markstk;
- uint16 s_flags;
- uint16 s_internalNKey;
- ScanKey s_internalKey;
-} RTreeScanOpaqueData;
+typedef struct RTreeScanOpaqueData
+{
+ struct RTSTACK *s_stack;
+ struct RTSTACK *s_markstk;
+ uint16 s_flags;
+ uint16 s_internalNKey;
+ ScanKey s_internalKey;
+} RTreeScanOpaqueData;
-typedef RTreeScanOpaqueData *RTreeScanOpaque;
+typedef RTreeScanOpaqueData *RTreeScanOpaque;
/*
- * When we're doing a scan and updating a tree at the same time, the
- * updates may affect the scan. We use the flags entry of the scan's
- * opaque space to record our actual position in response to updates
- * that we can't handle simply by adjusting pointers.
+ * When we're doing a scan and updating a tree at the same time, the
+ * updates may affect the scan. We use the flags entry of the scan's
+ * opaque space to record our actual position in response to updates
+ * that we can't handle simply by adjusting pointers.
*/
#define RTS_CURBEFORE ((uint16) (1 << 0))
#define RTS_MRKBEFORE ((uint16) (1 << 1))
/* root page of an rtree */
-#define P_ROOT 0
+#define P_ROOT 0
/*
- * When we update a relation on which we're doing a scan, we need to
- * check the scan and fix it if the update affected any of the pages it
- * touches. Otherwise, we can miss records that we should see. The only
- * times we need to do this are for deletions and splits. See the code in
- * rtscan.c for how the scan is fixed. These two contants tell us what sort
- * of operation changed the index.
+ * When we update a relation on which we're doing a scan, we need to
+ * check the scan and fix it if the update affected any of the pages it
+ * touches. Otherwise, we can miss records that we should see. The only
+ * times we need to do this are for deletions and splits. See the code in
+ * rtscan.c for how the scan is fixed. These two contants tell us what sort
+ * of operation changed the index.
*/
-#define RTOP_DEL 0
-#define RTOP_SPLIT 1
+#define RTOP_DEL 0
+#define RTOP_SPLIT 1
/* defined in rtree.c */
-extern void freestack(RTSTACK *s);
+extern void freestack(RTSTACK * s);
/* rget.c */
extern RetrieveIndexResult rtgettuple(IndexScanDesc s, ScanDirection dir);
/*
- * RTree code.
- * Defined in access/index-rtree/
+ * RTree code.
+ * Defined in access/index-rtree/
*/
-extern InsertIndexResult rtinsert(Relation r, Datum *datum, char *nulls,
- ItemPointer ht_ctid, Relation heapRel);
-extern char *rtdelete(Relation r, ItemPointer tid);
+extern InsertIndexResult
+rtinsert(Relation r, Datum * datum, char *nulls,
+ ItemPointer ht_ctid, Relation heapRel);
+extern char *rtdelete(Relation r, ItemPointer tid);
extern RetrieveIndexResult rtgettuple(IndexScanDesc s, ScanDirection dir);
-extern IndexScanDesc rtbeginscan(Relation r, bool fromEnd, uint16 nkeys,
- ScanKey key);
-
-extern void rtendscan(IndexScanDesc s);
-extern void rtmarkpos(IndexScanDesc s);
-extern void rtrestrpos(IndexScanDesc s);
-extern void rtrescan(IndexScanDesc s, bool fromEnd, ScanKey key);
-extern void rtbuild(Relation heap, Relation index, int natts,
- AttrNumber *attnum, IndexStrategy istrat, uint16 pcount,
- Datum *params, FuncIndexInfo *finfo, PredInfo *predInfo);
-extern void _rtdump(Relation r);
+extern IndexScanDesc
+rtbeginscan(Relation r, bool fromEnd, uint16 nkeys,
+ ScanKey key);
+
+extern void rtendscan(IndexScanDesc s);
+extern void rtmarkpos(IndexScanDesc s);
+extern void rtrestrpos(IndexScanDesc s);
+extern void rtrescan(IndexScanDesc s, bool fromEnd, ScanKey key);
+extern void
+rtbuild(Relation heap, Relation index, int natts,
+ AttrNumber * attnum, IndexStrategy istrat, uint16 pcount,
+ Datum * params, FuncIndexInfo * finfo, PredInfo * predInfo);
+extern void _rtdump(Relation r);
/* rtscan.c */
-extern void rtadjscans(Relation r, int op, BlockNumber blkno,
- OffsetNumber offnum);
+extern void
+rtadjscans(Relation r, int op, BlockNumber blkno,
+ OffsetNumber offnum);
+
/* rtstrat.h */
-extern RegProcedure RTMapOperator(Relation r, AttrNumber attnum,
- RegProcedure proc);
+extern RegProcedure
+RTMapOperator(Relation r, AttrNumber attnum,
+ RegProcedure proc);
-#endif /* RTREE_H */
+#endif /* RTREE_H */
diff --git a/src/include/access/rtscan.h b/src/include/access/rtscan.h
index 88d36c6e226..b91fc2fa066 100644
--- a/src/include/access/rtscan.h
+++ b/src/include/access/rtscan.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* rtscan.h--
- * routines defined in access/rtree/rtscan.c
+ * routines defined in access/rtree/rtscan.c
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rtscan.h,v 1.1 1996/08/27 21:50:22 scrappy Exp $
+ * $Id: rtscan.h,v 1.2 1997/09/07 04:56:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef RTSCAN_H
-void rtadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum);
+void rtadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum);
-#endif /* RTSCAN_H */
+#endif /* RTSCAN_H */
diff --git a/src/include/access/rtstrat.h b/src/include/access/rtstrat.h
index 7f2b88a721f..3f33f04e914 100644
--- a/src/include/access/rtstrat.h
+++ b/src/include/access/rtstrat.h
@@ -1,18 +1,19 @@
/*-------------------------------------------------------------------------
*
* rtstrat.h--
- * routines defined in access/rtree/rtstrat.c
+ * routines defined in access/rtree/rtstrat.c
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rtstrat.h,v 1.1 1996/08/27 21:50:23 scrappy Exp $
+ * $Id: rtstrat.h,v 1.2 1997/09/07 04:56:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef RTSTRAT_H
-extern RegProcedure RTMapOperator(Relation r, AttrNumber attnum,
- RegProcedure proc);
+extern RegProcedure
+RTMapOperator(Relation r, AttrNumber attnum,
+ RegProcedure proc);
-#endif /* RTSTRAT_H */
+#endif /* RTSTRAT_H */
diff --git a/src/include/access/sdir.h b/src/include/access/sdir.h
index 9d60e2dd3d3..cc8826c528c 100644
--- a/src/include/access/sdir.h
+++ b/src/include/access/sdir.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* sdir.h--
- * POSTGRES scan direction definitions.
+ * POSTGRES scan direction definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: sdir.h,v 1.2 1996/10/31 09:46:42 scrappy Exp $
+ * $Id: sdir.h,v 1.3 1997/09/07 04:56:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef SDIR_H
+#ifndef SDIR_H
#define SDIR_H
@@ -18,39 +18,40 @@
* ScanDirection was an int8 for no apparent reason. I kept the original
* values because I'm not sure if I'll break anything otherwise. -ay 2/95
*/
-typedef enum ScanDirection {
- BackwardScanDirection = -1,
- NoMovementScanDirection = 0,
- ForwardScanDirection = 1
+typedef enum ScanDirection
+{
+ BackwardScanDirection = -1,
+ NoMovementScanDirection = 0,
+ ForwardScanDirection = 1
} ScanDirection;
/*
* ScanDirectionIsValid --
- * True iff scan direction is valid.
+ * True iff scan direction is valid.
*/
#define ScanDirectionIsValid(direction) \
- ((bool) (BackwardScanDirection <= direction && \
- direction <= ForwardScanDirection))
+ ((bool) (BackwardScanDirection <= direction && \
+ direction <= ForwardScanDirection))
/*
* ScanDirectionIsBackward --
- * True iff scan direction is backward.
+ * True iff scan direction is backward.
*/
#define ScanDirectionIsBackward(direction) \
- ((bool) (direction == BackwardScanDirection))
+ ((bool) (direction == BackwardScanDirection))
/*
* ScanDirectionIsNoMovement --
- * True iff scan direction indicates no movement.
+ * True iff scan direction indicates no movement.
*/
#define ScanDirectionIsNoMovement(direction) \
- ((bool) (direction == NoMovementScanDirection))
+ ((bool) (direction == NoMovementScanDirection))
/*
* ScanDirectionIsForward --
- * True iff scan direction is forward.
+ * True iff scan direction is forward.
*/
#define ScanDirectionIsForward(direction) \
- ((bool) (direction == ForwardScanDirection))
+ ((bool) (direction == ForwardScanDirection))
-#endif /* SDIR_H */
+#endif /* SDIR_H */
diff --git a/src/include/access/skey.h b/src/include/access/skey.h
index d392bfef0d7..44c43c88758 100644
--- a/src/include/access/skey.h
+++ b/src/include/access/skey.h
@@ -1,50 +1,52 @@
/*-------------------------------------------------------------------------
*
* skey.h--
- * POSTGRES scan key definitions.
+ * POSTGRES scan key definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: skey.h,v 1.3 1996/11/04 07:45:26 scrappy Exp $
+ * $Id: skey.h,v 1.4 1997/09/07 04:56:13 momjian Exp $
*
*
* Note:
- * Needs more accessor/assignment routines.
+ * Needs more accessor/assignment routines.
*-------------------------------------------------------------------------
*/
-#ifndef SKEY_H
+#ifndef SKEY_H
#define SKEY_H
#include <access/attnum.h>
-typedef struct ScanKeyData {
- bits16 sk_flags; /* flags */
- AttrNumber sk_attno; /* domain number */
- RegProcedure sk_procedure; /* procedure OID */
- func_ptr sk_func;
- int32 sk_nargs;
- Datum sk_argument; /* data to compare */
-} ScanKeyData;
+typedef struct ScanKeyData
+{
+ bits16 sk_flags; /* flags */
+ AttrNumber sk_attno; /* domain number */
+ RegProcedure sk_procedure; /* procedure OID */
+ func_ptr sk_func;
+ int32 sk_nargs;
+ Datum sk_argument;/* data to compare */
+} ScanKeyData;
-typedef ScanKeyData *ScanKey;
+typedef ScanKeyData *ScanKey;
-#define SK_ISNULL 0x1
-#define SK_UNARY 0x2
-#define SK_NEGATE 0x4
-#define SK_COMMUTE 0x8
+#define SK_ISNULL 0x1
+#define SK_UNARY 0x2
+#define SK_NEGATE 0x4
+#define SK_COMMUTE 0x8
-#define ScanUnmarked 0x01
+#define ScanUnmarked 0x01
#define ScanUncheckedPrevious 0x02
-#define ScanUncheckedNext 0x04
+#define ScanUncheckedNext 0x04
/*
* prototypes for functions in access/common/scankey.c
*/
-extern void ScanKeyEntrySetIllegal(ScanKey entry);
-extern void ScanKeyEntryInitialize(ScanKey entry, bits16 flags,
- AttrNumber attributeNumber, RegProcedure procedure, Datum argument);
+extern void ScanKeyEntrySetIllegal(ScanKey entry);
+extern void
+ScanKeyEntryInitialize(ScanKey entry, bits16 flags,
+ AttrNumber attributeNumber, RegProcedure procedure, Datum argument);
-#endif /* SKEY_H */
+#endif /* SKEY_H */
diff --git a/src/include/access/strat.h b/src/include/access/strat.h
index 5cd23255efa..035582ef766 100644
--- a/src/include/access/strat.h
+++ b/src/include/access/strat.h
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* strat.h--
- * index strategy type definitions
- * (separated out from original istrat.h to avoid circular refs)
+ * index strategy type definitions
+ * (separated out from original istrat.h to avoid circular refs)
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: strat.h,v 1.4 1996/11/04 07:45:27 scrappy Exp $
+ * $Id: strat.h,v 1.5 1997/09/07 04:56:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,67 +18,76 @@
typedef uint16 StrategyNumber;
-#define InvalidStrategy 0
+#define InvalidStrategy 0
-typedef struct StrategyTransformMapData {
- StrategyNumber strategy[1]; /* VARIABLE LENGTH ARRAY */
-} StrategyTransformMapData; /* VARIABLE LENGTH STRUCTURE */
+typedef struct StrategyTransformMapData
+{
+ StrategyNumber strategy[1];/* VARIABLE LENGTH ARRAY */
+} StrategyTransformMapData; /* VARIABLE LENGTH
-typedef StrategyTransformMapData *StrategyTransformMap;
+ * STRUCTURE */
-typedef struct StrategyOperatorData {
- StrategyNumber strategy;
- bits16 flags; /* scan qualification flags h/skey.h */
-} StrategyOperatorData;
+typedef StrategyTransformMapData *StrategyTransformMap;
-typedef StrategyOperatorData *StrategyOperator;
+typedef struct StrategyOperatorData
+{
+ StrategyNumber strategy;
+ bits16 flags; /* scan qualification flags h/skey.h */
+} StrategyOperatorData;
-typedef struct StrategyTermData { /* conjunctive term */
- uint16 degree;
- StrategyOperatorData operatorData[1]; /* VARIABLE LENGTH */
-} StrategyTermData; /* VARIABLE LENGTH STRUCTURE */
+typedef StrategyOperatorData *StrategyOperator;
-typedef StrategyTermData *StrategyTerm;
+typedef struct StrategyTermData
+{ /* conjunctive term */
+ uint16 degree;
+ StrategyOperatorData operatorData[1]; /* VARIABLE LENGTH */
+} StrategyTermData; /* VARIABLE LENGTH STRUCTURE */
-typedef struct StrategyExpressionData { /* disjunctive normal form */
- StrategyTerm term[1]; /* VARIABLE LENGTH ARRAY */
-} StrategyExpressionData; /* VARIABLE LENGTH STRUCTURE */
+typedef StrategyTermData *StrategyTerm;
-typedef StrategyExpressionData *StrategyExpression;
+typedef struct StrategyExpressionData
+{ /* disjunctive normal form */
+ StrategyTerm term[1]; /* VARIABLE LENGTH ARRAY */
+} StrategyExpressionData; /* VARIABLE LENGTH STRUCTURE */
-typedef struct StrategyEvaluationData {
- StrategyNumber maxStrategy;
- StrategyTransformMap negateTransform;
- StrategyTransformMap commuteTransform;
- StrategyTransformMap negateCommuteTransform;
- StrategyExpression expression[12]; /* XXX VARIABLE LENGTH */
-} StrategyEvaluationData; /* VARIABLE LENGTH STRUCTURE */
+typedef StrategyExpressionData *StrategyExpression;
-typedef StrategyEvaluationData *StrategyEvaluation;
+typedef struct StrategyEvaluationData
+{
+ StrategyNumber maxStrategy;
+ StrategyTransformMap negateTransform;
+ StrategyTransformMap commuteTransform;
+ StrategyTransformMap negateCommuteTransform;
+ StrategyExpression expression[12]; /* XXX VARIABLE LENGTH */
+} StrategyEvaluationData; /* VARIABLE LENGTH STRUCTURE */
+
+typedef StrategyEvaluationData *StrategyEvaluation;
/*
* StrategyTransformMapIsValid --
- * Returns true iff strategy transformation map is valid.
+ * Returns true iff strategy transformation map is valid.
*/
-#define StrategyTransformMapIsValid(transform) PointerIsValid(transform)
+#define StrategyTransformMapIsValid(transform) PointerIsValid(transform)
-#ifndef CorrectStrategies /* XXX this should be removable */
-#define AMStrategies(foo) 12
-#else /* !defined(CorrectStrategies) */
-#define AMStrategies(foo) (foo)
-#endif /* !defined(CorrectStrategies) */
+#ifndef CorrectStrategies /* XXX this should be removable */
+#define AMStrategies(foo) 12
+#else /* !defined(CorrectStrategies) */
+#define AMStrategies(foo) (foo)
+#endif /* !defined(CorrectStrategies) */
-typedef struct StrategyMapData {
+typedef struct StrategyMapData
+{
ScanKeyData entry[1]; /* VARIABLE LENGTH ARRAY */
-} StrategyMapData; /* VARIABLE LENGTH STRUCTURE */
+} StrategyMapData;/* VARIABLE LENGTH STRUCTURE */
-typedef StrategyMapData *StrategyMap;
+typedef StrategyMapData *StrategyMap;
-typedef struct IndexStrategyData {
- StrategyMapData strategyMapData[1]; /* VARIABLE LENGTH ARRAY */
-} IndexStrategyData; /* VARIABLE LENGTH STRUCTURE */
+typedef struct IndexStrategyData
+{
+ StrategyMapData strategyMapData[1]; /* VARIABLE LENGTH ARRAY */
+} IndexStrategyData; /* VARIABLE LENGTH STRUCTURE */
-typedef IndexStrategyData *IndexStrategy;
+typedef IndexStrategyData *IndexStrategy;
-#endif /*STRAT_H */
+#endif /* STRAT_H */
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index 1d794594872..98a07aad102 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* transam.h--
- * postgres transaction access method support code header
+ * postgres transaction access method support code header
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: transam.h,v 1.7 1997/08/19 21:37:38 momjian Exp $
+ * $Id: transam.h,v 1.8 1997/09/07 04:56:14 momjian Exp $
*
- * NOTES
- * Transaction System Version 101 now support proper oid
- * generation and recording in the variable relation.
+ * NOTES
+ * Transaction System Version 101 now support proper oid
+ * generation and recording in the variable relation.
*
*-------------------------------------------------------------------------
*/
@@ -21,119 +21,122 @@
#include <utils/nabstime.h>
/* ----------------
- * transaction system version id
+ * transaction system version id
*
- * this is stored on the first page of the log, time and variable
- * relations on the first 4 bytes. This is so that if we improve
- * the format of the transaction log after postgres version 2, then
- * people won't have to rebuild their databases.
+ * this is stored on the first page of the log, time and variable
+ * relations on the first 4 bytes. This is so that if we improve
+ * the format of the transaction log after postgres version 2, then
+ * people won't have to rebuild their databases.
*
- * TRANS_SYSTEM_VERSION 100 means major version 1 minor version 0.
- * Two databases with the same major version should be compatible,
- * even if their minor versions differ.
+ * TRANS_SYSTEM_VERSION 100 means major version 1 minor version 0.
+ * Two databases with the same major version should be compatible,
+ * even if their minor versions differ.
* ----------------
*/
#define TRANS_SYSTEM_VERSION 101
/* ----------------
- * transaction id status values
+ * transaction id status values
*
- * someday we will use "11" = 3 = XID_INVALID to mean the
- * starting of run-length encoded log data.
+ * someday we will use "11" = 3 = XID_INVALID to mean the
+ * starting of run-length encoded log data.
* ----------------
*/
-#define XID_COMMIT 2 /* transaction commited */
-#define XID_ABORT 1 /* transaction aborted */
-#define XID_INPROGRESS 0 /* transaction in progress */
-#define XID_INVALID 3 /* other */
+#define XID_COMMIT 2 /* transaction commited */
+#define XID_ABORT 1 /* transaction aborted */
+#define XID_INPROGRESS 0 /* transaction in progress */
+#define XID_INVALID 3 /* other */
-typedef unsigned char XidStatus; /* (2 bits) */
+typedef unsigned char XidStatus;/* (2 bits) */
/* ----------
- * note: we reserve the first 16384 object ids for internal use.
- * oid's less than this appear in the .bki files. the choice of
- * 16384 is completely arbitrary.
+ * note: we reserve the first 16384 object ids for internal use.
+ * oid's less than this appear in the .bki files. the choice of
+ * 16384 is completely arbitrary.
* ----------
*/
#define BootstrapObjectIdData 16384
/* ----------------
- * BitIndexOf computes the index of the Nth xid on a given block
+ * BitIndexOf computes the index of the Nth xid on a given block
* ----------------
*/
-#define BitIndexOf(N) ((N) * 2)
+#define BitIndexOf(N) ((N) * 2)
/* ----------------
- * transaction page definitions
+ * transaction page definitions
* ----------------
*/
-#define TP_DataSize BLCKSZ
-#define TP_NumXidStatusPerBlock (TP_DataSize * 4)
-#define TP_NumTimePerBlock (TP_DataSize / 4)
+#define TP_DataSize BLCKSZ
+#define TP_NumXidStatusPerBlock (TP_DataSize * 4)
+#define TP_NumTimePerBlock (TP_DataSize / 4)
/* ----------------
- * LogRelationContents structure
+ * LogRelationContents structure
*
- * This structure describes the storage of the data in the
- * first 128 bytes of the log relation. This storage is never
- * used for transaction status because transaction id's begin
- * their numbering at 512.
+ * This structure describes the storage of the data in the
+ * first 128 bytes of the log relation. This storage is never
+ * used for transaction status because transaction id's begin
+ * their numbering at 512.
*
- * The first 4 bytes of this relation store the version
- * number of the transction system.
+ * The first 4 bytes of this relation store the version
+ * number of the transction system.
* ----------------
*/
-typedef struct LogRelationContentsData {
- int TransSystemVersion;
-} LogRelationContentsData;
+typedef struct LogRelationContentsData
+{
+ int TransSystemVersion;
+} LogRelationContentsData;
typedef LogRelationContentsData *LogRelationContents;
/* ----------------
- * TimeRelationContents structure
+ * TimeRelationContents structure
*
- * This structure describes the storage of the data in the
- * first 2048 bytes of the time relation. This storage is never
- * used for transaction commit times because transaction id's begin
- * their numbering at 512.
+ * This structure describes the storage of the data in the
+ * first 2048 bytes of the time relation. This storage is never
+ * used for transaction commit times because transaction id's begin
+ * their numbering at 512.
*
- * The first 4 bytes of this relation store the version
- * number of the transction system.
+ * The first 4 bytes of this relation store the version
+ * number of the transction system.
* ----------------
*/
-typedef struct TimeRelationContentsData {
- int TransSystemVersion;
-} TimeRelationContentsData;
+typedef struct TimeRelationContentsData
+{
+ int TransSystemVersion;
+} TimeRelationContentsData;
typedef TimeRelationContentsData *TimeRelationContents;
/* ----------------
- * VariableRelationContents structure
+ * VariableRelationContents structure
*
- * The variable relation is a special "relation" which
- * is used to store various system "variables" persistantly.
- * Unlike other relations in the system, this relation
- * is updated in place whenever the variables change.
+ * The variable relation is a special "relation" which
+ * is used to store various system "variables" persistantly.
+ * Unlike other relations in the system, this relation
+ * is updated in place whenever the variables change.
*
- * The first 4 bytes of this relation store the version
- * number of the transction system.
+ * The first 4 bytes of this relation store the version
+ * number of the transction system.
*
- * Currently, the relation has only one page and the next
- * available xid, the last committed xid and the next
- * available oid are stored there.
+ * Currently, the relation has only one page and the next
+ * available xid, the last committed xid and the next
+ * available oid are stored there.
* ----------------
*/
-typedef struct VariableRelationContentsData {
- int TransSystemVersion;
- TransactionId nextXidData;
- TransactionId lastXidData;
- Oid nextOid;
-} VariableRelationContentsData;
+typedef struct VariableRelationContentsData
+{
+ int TransSystemVersion;
+ TransactionId nextXidData;
+ TransactionId lastXidData;
+ Oid nextOid;
+} VariableRelationContentsData;
typedef VariableRelationContentsData *VariableRelationContents;
/* ----------------
- * extern declarations
+ * extern declarations
* ----------------
*/
@@ -141,59 +144,64 @@ typedef VariableRelationContentsData *VariableRelationContents;
* prototypes for functions in transam/transam.c
*/
extern AbsoluteTime TransactionIdGetCommitTime(TransactionId transactionId);
-extern void InitializeTransactionLog(void);
-extern bool TransactionIdDidCommit(TransactionId transactionId);
-extern bool TransactionIdDidAbort(TransactionId transactionId);
-extern void TransactionIdCommit(TransactionId transactionId);
-extern void TransactionIdAbort(TransactionId transactionId);
+extern void InitializeTransactionLog(void);
+extern bool TransactionIdDidCommit(TransactionId transactionId);
+extern bool TransactionIdDidAbort(TransactionId transactionId);
+extern void TransactionIdCommit(TransactionId transactionId);
+extern void TransactionIdAbort(TransactionId transactionId);
/* in transam/transsup.c */
-extern void AmiTransactionOverride(bool flag);
-extern void TransComputeBlockNumber(Relation relation,
- TransactionId transactionId, BlockNumber *blockNumberOutP);
-extern XidStatus TransBlockNumberGetXidStatus(Relation relation,
- BlockNumber blockNumber, TransactionId xid, bool *failP);
-extern void TransBlockNumberSetXidStatus(Relation relation,
- BlockNumber blockNumber, TransactionId xid, XidStatus xstatus,
- bool *failP);
-extern AbsoluteTime TransBlockNumberGetCommitTime(Relation relation,
- BlockNumber blockNumber, TransactionId xid, bool *failP);
-extern void TransBlockNumberSetCommitTime(Relation relation,
- BlockNumber blockNumber, TransactionId xid, AbsoluteTime xtime,
- bool *failP);
+extern void AmiTransactionOverride(bool flag);
+extern void
+TransComputeBlockNumber(Relation relation,
+ TransactionId transactionId, BlockNumber * blockNumberOutP);
+extern XidStatus
+TransBlockNumberGetXidStatus(Relation relation,
+ BlockNumber blockNumber, TransactionId xid, bool * failP);
+extern void
+TransBlockNumberSetXidStatus(Relation relation,
+ BlockNumber blockNumber, TransactionId xid, XidStatus xstatus,
+ bool * failP);
+extern AbsoluteTime
+TransBlockNumberGetCommitTime(Relation relation,
+ BlockNumber blockNumber, TransactionId xid, bool * failP);
+extern void
+TransBlockNumberSetCommitTime(Relation relation,
+ BlockNumber blockNumber, TransactionId xid, AbsoluteTime xtime,
+ bool * failP);
/* in transam/varsup.c */
-extern void VariableRelationPutNextXid(TransactionId xid);
-extern void GetNewTransactionId(TransactionId *xid);
-extern void UpdateLastCommittedXid(TransactionId xid);
-extern void GetNewObjectId(Oid *oid_return);
-extern void CheckMaxObjectId(Oid assigned_oid);
+extern void VariableRelationPutNextXid(TransactionId xid);
+extern void GetNewTransactionId(TransactionId * xid);
+extern void UpdateLastCommittedXid(TransactionId xid);
+extern void GetNewObjectId(Oid * oid_return);
+extern void CheckMaxObjectId(Oid assigned_oid);
/* ----------------
- * global variable extern declarations
+ * global variable extern declarations
* ----------------
*/
/* in transam.c */
-extern Relation LogRelation;
-extern Relation TimeRelation;
-extern Relation VariableRelation;
+extern Relation LogRelation;
+extern Relation TimeRelation;
+extern Relation VariableRelation;
-extern TransactionId cachedGetCommitTimeXid;
-extern AbsoluteTime cachedGetCommitTime;
-extern TransactionId cachedTestXid;
-extern XidStatus cachedTestXidStatus;
+extern TransactionId cachedGetCommitTimeXid;
+extern AbsoluteTime cachedGetCommitTime;
+extern TransactionId cachedTestXid;
+extern XidStatus cachedTestXidStatus;
extern TransactionId NullTransactionId;
extern TransactionId AmiTransactionId;
extern TransactionId FirstTransactionId;
-extern int RecoveryCheckingEnableState;
+extern int RecoveryCheckingEnableState;
/* in transsup.c */
-extern bool AMI_OVERRIDE;
+extern bool AMI_OVERRIDE;
/* in varsup.c */
-extern int OidGenLockId;
+extern int OidGenLockId;
-#endif /* TRAMSAM_H */
+#endif /* TRAMSAM_H */
diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h
index f27bdc7f0a5..4196e6b955c 100644
--- a/src/include/access/tupdesc.h
+++ b/src/include/access/tupdesc.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* tupdesc.h--
- * POSTGRES tuple descriptor definitions.
+ * POSTGRES tuple descriptor definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: tupdesc.h,v 1.8 1997/08/22 03:55:39 vadim Exp $
+ * $Id: tupdesc.h,v 1.9 1997/09/07 04:56:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef TUPDESC_H
+#ifndef TUPDESC_H
#define TUPDESC_H
#include <nodes/pg_list.h>
@@ -18,56 +18,61 @@
#include <catalog/pg_attribute.h>
-typedef struct attrDefault {
- AttrNumber adnum;
- char *adbin;
- char *adsrc;
-} AttrDefault;
+typedef struct attrDefault
+{
+ AttrNumber adnum;
+ char *adbin;
+ char *adsrc;
+} AttrDefault;
-typedef struct constrCheck {
- char *ccname;
- char *ccbin;
- char *ccsrc;
-} ConstrCheck;
+typedef struct constrCheck
+{
+ char *ccname;
+ char *ccbin;
+ char *ccsrc;
+} ConstrCheck;
/* This structure contains constraints of a tuple */
-typedef struct tupleConstr {
- AttrDefault *defval;
- ConstrCheck *check;
- uint16 num_defval;
- uint16 num_check;
- bool has_not_null;
-} TupleConstr;
+typedef struct tupleConstr
+{
+ AttrDefault *defval;
+ ConstrCheck *check;
+ uint16 num_defval;
+ uint16 num_check;
+ bool has_not_null;
+} TupleConstr;
/*
* This structure contains all information (i.e. from Classes
- * pg_attribute, pg_attrdef, pg_relcheck) for a tuple.
+ * pg_attribute, pg_attrdef, pg_relcheck) for a tuple.
*/
-typedef struct tupleDesc {
- int natts;
- /* Number of attributes in the tuple */
- AttributeTupleForm *attrs;
- /* attrs[N] is a pointer to the description of Attribute Number N+1. */
- TupleConstr *constr;
-} *TupleDesc;
+typedef struct tupleDesc
+{
+ int natts;
+ /* Number of attributes in the tuple */
+ AttributeTupleForm *attrs;
+ /* attrs[N] is a pointer to the description of Attribute Number N+1. */
+ TupleConstr *constr;
+} *TupleDesc;
extern TupleDesc CreateTemplateTupleDesc(int natts);
-extern TupleDesc CreateTupleDesc(int natts, AttributeTupleForm *attrs);
+extern TupleDesc CreateTupleDesc(int natts, AttributeTupleForm * attrs);
extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc);
extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc);
-extern void FreeTupleDesc(TupleDesc tupdesc);
+extern void FreeTupleDesc(TupleDesc tupdesc);
-extern bool TupleDescInitEntry(TupleDesc desc,
- AttrNumber attributeNumber,
- char *attributeName,
- char *typeName,
- int attdim,
- bool attisset);
+extern bool
+TupleDescInitEntry(TupleDesc desc,
+ AttrNumber attributeNumber,
+ char *attributeName,
+ char *typeName,
+ int attdim,
+ bool attisset);
-extern TupleDesc BuildDescForRelation(List *schema, char *relname);
+extern TupleDesc BuildDescForRelation(List * schema, char *relname);
-#endif /* TUPDESC_H */
+#endif /* TUPDESC_H */
diff --git a/src/include/access/tupmacs.h b/src/include/access/tupmacs.h
index 23e8ea1686a..39d3004d561 100644
--- a/src/include/access/tupmacs.h
+++ b/src/include/access/tupmacs.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* tupmacs.h--
- * Tuple macros used by both index tuples and heap tuples.
+ * Tuple macros used by both index tuples and heap tuples.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: tupmacs.h,v 1.1 1996/08/27 21:50:27 scrappy Exp $
+ * $Id: tupmacs.h,v 1.2 1997/09/07 04:56:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,7 +22,7 @@
* given a AttributeTupleForm and a pointer into a tuple's data
* area, return the correct value or pointer.
*
- * We return a 4 byte (char *) value in all cases. If the attribute has
+ * We return a 4 byte (char *) value in all cases. If the attribute has
* "byval" false or has variable length, we return the same pointer
* into the tuple data area that we're passed. Otherwise, we return
* the 1, 2, or 4 bytes pointed to by it, properly extended to 4
@@ -31,7 +31,7 @@
* note that T must already be properly LONGALIGN/SHORTALIGN'd for
* this to work correctly.
*
- * the double-cast is to stop gcc from (correctly) complaining about
+ * the double-cast is to stop gcc from (correctly) complaining about
* casting integer types with size < sizeof(char *) to (char *).
* sign-extension may get weird if you use an integer type that
* isn't the same size as (char *) for the first cast. (on the other
@@ -39,17 +39,17 @@
*
* attbyval seems to be fairly redundant. We have to return a pointer if
* the value is longer than 4 bytes or has variable length; returning the
- * value would be useless. In fact, for at least the variable length case,
+ * value would be useless. In fact, for at least the variable length case,
* the caller assumes we return a pointer regardless of attbyval.
* I would eliminate attbyval altogether, but I don't know how. -BRYANH.
*/
#define fetchatt(A, T) \
((*(A))->attbyval && (*(A))->attlen != -1 \
? ((*(A))->attlen > sizeof(int16) \
- ? (char *) (long) *((int32 *)(T)) \
- : ((*(A))->attlen < sizeof(int16) \
- ? (char *) (long) *((char *)(T)) \
- : (char *) (long) *((int16 *)(T)))) \
+ ? (char *) (long) *((int32 *)(T)) \
+ : ((*(A))->attlen < sizeof(int16) \
+ ? (char *) (long) *((char *)(T)) \
+ : (char *) (long) *((int16 *)(T)))) \
: (char *) (T))
-
+
#endif
diff --git a/src/include/access/valid.h b/src/include/access/valid.h
index ca209a16e5a..7eb639230ab 100644
--- a/src/include/access/valid.h
+++ b/src/include/access/valid.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* valid.h--
- * POSTGRES tuple qualification validity definitions.
+ * POSTGRES tuple qualification validity definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: valid.h,v 1.4 1997/03/28 07:05:54 scrappy Exp $
+ * $Id: valid.h,v 1.5 1997/09/07 04:56:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef VALID_H
+#ifndef VALID_H
#define VALID_H
#include <utils/tqual.h>
@@ -18,18 +18,20 @@
#include <utils/rel.h>
/* ----------------
- * extern decl's
+ * extern decl's
* ----------------
*/
-extern bool heap_keytest(HeapTuple t, TupleDesc tupdesc,
+extern bool
+heap_keytest(HeapTuple t, TupleDesc tupdesc,
int nkeys, ScanKey keys);
-extern HeapTuple heap_tuple_satisfies(ItemId itemId, Relation relation,
- Buffer buffer, PageHeader disk_page,
- TimeQual qual, int nKeys,
- ScanKey key);
+extern HeapTuple
+heap_tuple_satisfies(ItemId itemId, Relation relation,
+ Buffer buffer, PageHeader disk_page,
+ TimeQual qual, int nKeys,
+ ScanKey key);
-extern bool TupleUpdatedByCurXactAndCmd(HeapTuple t);
+extern bool TupleUpdatedByCurXactAndCmd(HeapTuple t);
-#endif /* VALID_H */
+#endif /* VALID_H */
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 0aec4bccb82..e8ed4123f06 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* xact.h--
- * postgres transaction system header
+ * postgres transaction system header
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: xact.h,v 1.6 1997/08/29 09:05:25 vadim Exp $
+ * $Id: xact.h,v 1.7 1997/09/07 04:56:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,83 +16,85 @@
#include <utils/nabstime.h>
/* ----------------
- * transaction state structure
+ * transaction state structure
* ----------------
*/
-typedef struct TransactionStateData {
- TransactionId transactionIdData;
- CommandId commandId;
- CommandId scanCommandId;
- AbsoluteTime startTime;
- int state;
- int blockState;
-} TransactionStateData;
+typedef struct TransactionStateData
+{
+ TransactionId transactionIdData;
+ CommandId commandId;
+ CommandId scanCommandId;
+ AbsoluteTime startTime;
+ int state;
+ int blockState;
+} TransactionStateData;
/* ----------------
- * transaction states
+ * transaction states
* ----------------
*/
-#define TRANS_DEFAULT 0
-#define TRANS_START 1
-#define TRANS_INPROGRESS 2
-#define TRANS_COMMIT 3
-#define TRANS_ABORT 4
-#define TRANS_DISABLED 5
+#define TRANS_DEFAULT 0
+#define TRANS_START 1
+#define TRANS_INPROGRESS 2
+#define TRANS_COMMIT 3
+#define TRANS_ABORT 4
+#define TRANS_DISABLED 5
/* ----------------
- * transaction block states
+ * transaction block states
* ----------------
*/
-#define TBLOCK_DEFAULT 0
-#define TBLOCK_BEGIN 1
-#define TBLOCK_INPROGRESS 2
-#define TBLOCK_END 3
-#define TBLOCK_ABORT 4
-#define TBLOCK_ENDABORT 5
+#define TBLOCK_DEFAULT 0
+#define TBLOCK_BEGIN 1
+#define TBLOCK_INPROGRESS 2
+#define TBLOCK_END 3
+#define TBLOCK_ABORT 4
+#define TBLOCK_ENDABORT 5
typedef TransactionStateData *TransactionState;
/* ----------------
- * extern definitions
+ * extern definitions
* ----------------
*/
-extern int TransactionFlushEnabled(void);
-extern void SetTransactionFlushEnabled(bool state);
+extern int TransactionFlushEnabled(void);
+extern void SetTransactionFlushEnabled(bool state);
-extern bool IsTransactionState(void);
-extern bool IsAbortedTransactionBlockState(void);
-extern void OverrideTransactionSystem(bool flag);
+extern bool IsTransactionState(void);
+extern bool IsAbortedTransactionBlockState(void);
+extern void OverrideTransactionSystem(bool flag);
extern TransactionId GetCurrentTransactionId(void);
extern CommandId GetCurrentCommandId(void);
extern CommandId GetScanCommandId(void);
-extern void SetScanCommandId(CommandId);
+extern void SetScanCommandId(CommandId);
extern AbsoluteTime GetCurrentTransactionStartTime(void);
-extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
-extern bool CommandIdIsCurrentCommandId(CommandId cid);
-extern bool CommandIdGEScanCommandId(CommandId cid);
-extern void CommandCounterIncrement(void);
-extern void InitializeTransactionSystem(void);
-extern bool CurrentXactInProgress(void);
-extern void StartTransactionCommand(void);
-extern void CommitTransactionCommand(void);
-extern void AbortCurrentTransaction(void);
-extern void BeginTransactionBlock(void);
-extern void EndTransactionBlock(void);
-extern bool IsTransactionBlock(void);
-extern void UserAbortTransactionBlock(void);
+extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
+extern bool CommandIdIsCurrentCommandId(CommandId cid);
+extern bool CommandIdGEScanCommandId(CommandId cid);
+extern void CommandCounterIncrement(void);
+extern void InitializeTransactionSystem(void);
+extern bool CurrentXactInProgress(void);
+extern void StartTransactionCommand(void);
+extern void CommitTransactionCommand(void);
+extern void AbortCurrentTransaction(void);
+extern void BeginTransactionBlock(void);
+extern void EndTransactionBlock(void);
+extern bool IsTransactionBlock(void);
+extern void UserAbortTransactionBlock(void);
extern TransactionId DisabledTransactionId;
/* defined in xid.c */
extern TransactionId xidin(char *representation);
-extern char *xidout(TransactionId transactionId);
-extern bool xideq(TransactionId xid1, TransactionId xid2);
-extern bool TransactionIdIsValid(TransactionId transactionId);
-extern void StoreInvalidTransactionId(TransactionId *destination);
-extern void TransactionIdStore(TransactionId transactionId,
- TransactionId *destination);
-extern bool TransactionIdEquals(TransactionId id1, TransactionId id2);
-extern bool TransactionIdIsLessThan(TransactionId id1, TransactionId id2);
-extern void TransactionIdAdd(TransactionId *xid, int value);
+extern char *xidout(TransactionId transactionId);
+extern bool xideq(TransactionId xid1, TransactionId xid2);
+extern bool TransactionIdIsValid(TransactionId transactionId);
+extern void StoreInvalidTransactionId(TransactionId * destination);
+extern void
+TransactionIdStore(TransactionId transactionId,
+ TransactionId * destination);
+extern bool TransactionIdEquals(TransactionId id1, TransactionId id2);
+extern bool TransactionIdIsLessThan(TransactionId id1, TransactionId id2);
+extern void TransactionIdAdd(TransactionId * xid, int value);
-#endif /* XACT_H */
+#endif /* XACT_H */
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index 12e28495e40..3adecdcdbd3 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* bootstrap.h--
- * include file for the bootstrapping code
+ * include file for the bootstrapping code
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: bootstrap.h,v 1.5 1997/08/19 21:37:42 momjian Exp $
+ * $Id: bootstrap.h,v 1.6 1997/09/07 04:56:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,42 +17,44 @@
#include <access/itup.h>
#include <utils/rel.h>
-#define MAXATTR 40 /* max. number of attributes in a relation */
+#define MAXATTR 40 /* max. number of attributes in a relation */
-typedef struct hashnode {
- int strnum; /* Index into string table */
- struct hashnode *next;
-} hashnode;
+typedef struct hashnode
+{
+ int strnum; /* Index into string table */
+ struct hashnode *next;
+} hashnode;
#define EMITPROMPT printf("> ")
extern Relation reldesc;
extern AttributeTupleForm attrtypes[MAXATTR];
-extern int numattr;
-extern int DebugMode;
+extern int numattr;
+extern int DebugMode;
-extern int BootstrapMain(int ac, char *av[]);
-extern void index_register(char *heap,
+extern int BootstrapMain(int ac, char *av[]);
+extern void
+index_register(char *heap,
char *ind,
int natts,
- AttrNumber *attnos,
+ AttrNumber * attnos,
uint16 nparams,
- Datum *params,
- FuncIndexInfo *finfo,
- PredInfo *predInfo);
-
-extern void err_out(void);
-extern void InsertOneTuple(Oid objectid);
-extern void closerel(char *name);
-extern void boot_openrel(char *name);
-extern char *LexIDStr(int ident_num);
-
-extern void DefineAttr(char *name, char *type, int attnum);
-extern void InsertOneValue(Oid objectid, char *value, int i);
-extern void InsertOneNull(int i);
-extern char* MapArrayTypeName(char *s);
-extern char* CleanUpStr(char *s);
-extern int EnterString (char *str);
-extern void build_indices(void);
-
-#endif /* BOOTSTRAP_H */
+ Datum * params,
+ FuncIndexInfo * finfo,
+ PredInfo * predInfo);
+
+extern void err_out(void);
+extern void InsertOneTuple(Oid objectid);
+extern void closerel(char *name);
+extern void boot_openrel(char *name);
+extern char *LexIDStr(int ident_num);
+
+extern void DefineAttr(char *name, char *type, int attnum);
+extern void InsertOneValue(Oid objectid, char *value, int i);
+extern void InsertOneNull(int i);
+extern char *MapArrayTypeName(char *s);
+extern char *CleanUpStr(char *s);
+extern int EnterString(char *str);
+extern void build_indices(void);
+
+#endif /* BOOTSTRAP_H */
diff --git a/src/include/c.h b/src/include/c.h
index 9a4bad2b7bf..cf9367c0fd1 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1,46 +1,46 @@
/*-------------------------------------------------------------------------
*
* c.h--
- * Fundamental C definitions. This is included by every .c file in
- * postgres.
+ * Fundamental C definitions. This is included by every .c file in
+ * postgres.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: c.h,v 1.16 1997/08/25 04:15:40 momjian Exp $
+ * $Id: c.h,v 1.17 1997/09/07 04:55:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * TABLE OF CONTENTS
+ * TABLE OF CONTENTS
*
- * When adding stuff to this file, please try and put stuff
- * into the relevant section, or add new sections as appropriate.
+ * When adding stuff to this file, please try and put stuff
+ * into the relevant section, or add new sections as appropriate.
*
- * section description
- * ------- ------------------------------------------------
- * 1) bool, true, false, TRUE, FALSE
- * 2) __STDC__, non-ansi C definitions:
- * Pointer typedef, NULL
- * cpp magic macros
- * type prefixes: const, signed, volatile, inline
- * 3) standard system types
- * 4) datum type
- * 5) IsValid macros for system types
- * 6) offsetof, lengthof, endof
- * 7) exception handling definitions, Assert, Trap, etc macros
- * 8) Min, Max, Abs, strNcpy macros
- * 9) externs
- * 10) Berkeley-specific defs
- * 11) system-specific hacks
+ * section description
+ * ------- ------------------------------------------------
+ * 1) bool, true, false, TRUE, FALSE
+ * 2) __STDC__, non-ansi C definitions:
+ * Pointer typedef, NULL
+ * cpp magic macros
+ * type prefixes: const, signed, volatile, inline
+ * 3) standard system types
+ * 4) datum type
+ * 5) IsValid macros for system types
+ * 6) offsetof, lengthof, endof
+ * 7) exception handling definitions, Assert, Trap, etc macros
+ * 8) Min, Max, Abs, strNcpy macros
+ * 9) externs
+ * 10) Berkeley-specific defs
+ * 11) system-specific hacks
*
- * NOTES
+ * NOTES
*
- * This file is MACHINE AND COMPILER dependent!!! (For now.)
+ * This file is MACHINE AND COMPILER dependent!!! (For now.)
*
* ----------------------------------------------------------------
*/
-#ifndef C_H
+#ifndef C_H
#define C_H
/* We have to include stdlib.h here because it defines many of these macros
@@ -50,410 +50,413 @@
#include <stdlib.h>
/* ----------------------------------------------------------------
- * Section 1: bool, true, false, TRUE, FALSE
+ * Section 1: bool, true, false, TRUE, FALSE
* ----------------------------------------------------------------
*/
/*
* bool --
- * Boolean value, either true or false.
+ * Boolean value, either true or false.
*
*/
#define false ((char) 0)
#define true ((char) 1)
#ifndef __cplusplus
typedef char bool;
-#endif /* not C++ */
-typedef bool *BoolPtr;
+
+#endif /* not C++ */
+typedef bool *BoolPtr;
#ifndef TRUE
#define TRUE 1
-#endif /* TRUE */
+#endif /* TRUE */
#ifndef FALSE
#define FALSE 0
-#endif /* FALSE */
+#endif /* FALSE */
/* ----------------------------------------------------------------
- * Section 2: __STDC__, non-ansi C definitions:
+ * Section 2: __STDC__, non-ansi C definitions:
*
- * cpp magic macros
- * Pointer typedef, NULL
- * type prefixes: const, signed, volatile, inline
+ * cpp magic macros
+ * Pointer typedef, NULL
+ * type prefixes: const, signed, volatile, inline
* ----------------------------------------------------------------
*/
-#ifdef __STDC__ /* ANSI C */
+#ifdef __STDC__ /* ANSI C */
/*
* Pointer --
- * Variable holding address of any memory resident object.
+ * Variable holding address of any memory resident object.
*/
/*
- * XXX Pointer arithmetic is done with this, so it can't be void *
- * under "true" ANSI compilers.
+ * XXX Pointer arithmetic is done with this, so it can't be void *
+ * under "true" ANSI compilers.
*/
-typedef char *Pointer;
+typedef char *Pointer;
-#ifndef NULL
+#ifndef NULL
/*
* NULL --
- * Null pointer.
+ * Null pointer.
*/
#define NULL ((void *) 0)
-#endif /* !defined(NULL) */
+#endif /* !defined(NULL) */
-#define HAVE_ANSI_CPP /* all ANSI C compilers must have this! */
+#define HAVE_ANSI_CPP /* all ANSI C compilers must have this! */
#if defined(NEED_STD_HDRS)
-#undef NEED_STD_HDRS /* all ANSI systems must have stddef/stdlib */
-#endif /* NEED_STD_HDRS */
+#undef NEED_STD_HDRS /* all ANSI systems must have
+ * stddef/stdlib */
+#endif /* NEED_STD_HDRS */
-#else /* !defined(__STDC__) */ /* NOT ANSI C */
+#else /* !defined(__STDC__) *//* NOT ANSI C */
/*
* Pointer --
- * Variable containing address of any memory resident object.
+ * Variable containing address of any memory resident object.
*/
-typedef char *Pointer;
+typedef char *Pointer;
-#ifndef NULL
+#ifndef NULL
/*
* NULL --
- * Null pointer.
+ * Null pointer.
*/
#define NULL 0
-#endif /* !defined(NULL) */
+#endif /* !defined(NULL) */
/*
* const --
- * Type modifier. Identifies read only variables.
+ * Type modifier. Identifies read only variables.
*
* Example:
- * extern const Version RomVersion;
+ * extern const Version RomVersion;
*/
-#define const /* const */
+#define const /* const */
/*
* signed --
- * Type modifier. Identifies signed integral types.
+ * Type modifier. Identifies signed integral types.
*/
-#define signed /* signed */
+#define signed /* signed */
/*
* volatile --
- * Type modifier. Identifies variables which may change in ways not
- * noticeable by the compiler, e.g. via asynchronous interrupts.
+ * Type modifier. Identifies variables which may change in ways not
+ * noticeable by the compiler, e.g. via asynchronous interrupts.
*
* Example:
- * extern volatile unsigned int NumberOfInterrupts;
+ * extern volatile unsigned int NumberOfInterrupts;
*/
-#define volatile /* volatile */
+#define volatile /* volatile */
-#endif /* !defined(__STDC__) */ /* NOT ANSI C */
+#endif /* !defined(__STDC__) *//* NOT ANSI C */
/*
* CppAsString --
- * Convert the argument to a string, using the C preprocessor.
+ * Convert the argument to a string, using the C preprocessor.
* CppConcat --
- * Concatenate two arguments together, using the C preprocessor.
+ * Concatenate two arguments together, using the C preprocessor.
*/
#if defined(HAVE_ANSI_CPP)
-#define CppAsString(identifier) #identifier
-#define CppConcat(x, y) x##y
+#define CppAsString(identifier) #identifier
+#define CppConcat(x, y) x##y
-#else /* !HAVE_ANSI_CPP */
+#else /* !HAVE_ANSI_CPP */
-#define CppAsString(identifier) "identifier"
+#define CppAsString(identifier) "identifier"
/*
* CppIdentity -- On Reiser based cpp's this is used to concatenate
- * two tokens. That is
- * CppIdentity(A)B ==> AB
- * We renamed it to _private_CppIdentity because it should not
- * be referenced outside this file. On other cpp's it
- * produces A B.
+ * two tokens. That is
+ * CppIdentity(A)B ==> AB
+ * We renamed it to _private_CppIdentity because it should not
+ * be referenced outside this file. On other cpp's it
+ * produces A B.
*/
#define _priv_CppIdentity(x)x
-#define CppConcat(x, y) _priv_CppIdentity(x)y
+#define CppConcat(x, y) _priv_CppIdentity(x)y
-#endif /* !HAVE_ANSI_CPP */
+#endif /* !HAVE_ANSI_CPP */
-#ifndef __GNUC__ /* GNU cc */
-# define inline
+#ifndef __GNUC__ /* GNU cc */
+#define inline
#endif
#if defined(NEED_STD_HDRS)
/*
- * You're doomed. We've removed almost all of our own C library
+ * You're doomed. We've removed almost all of our own C library
* extern declarations because they conflict on the different
* systems. You'll have to write your own stdlib.h.
*/
#include "stdlib.h"
-#else /* NEED_STD_HDRS */
+#else /* NEED_STD_HDRS */
#include <stddef.h>
#include <stdlib.h>
-#endif /* NEED_STD_HDRS */
+#endif /* NEED_STD_HDRS */
/* ----------------------------------------------------------------
- * Section 3: standard system types
+ * Section 3: standard system types
* ----------------------------------------------------------------
*/
/*
* intN --
- * Signed integer, AT LEAST N BITS IN SIZE,
- * used for numerical computations.
+ * Signed integer, AT LEAST N BITS IN SIZE,
+ * used for numerical computations.
*/
-typedef signed char int8; /* >= 8 bits */
-typedef signed short int16; /* >= 16 bits */
-typedef signed int int32; /* >= 32 bits */
+typedef signed char int8; /* >= 8 bits */
+typedef signed short int16; /* >= 16 bits */
+typedef signed int int32; /* >= 32 bits */
/*
* uintN --
- * Unsigned integer, AT LEAST N BITS IN SIZE,
- * used for numerical computations.
+ * Unsigned integer, AT LEAST N BITS IN SIZE,
+ * used for numerical computations.
*/
-typedef unsigned char uint8; /* >= 8 bits */
-typedef unsigned short uint16; /* >= 16 bits */
-typedef unsigned int uint32; /* >= 32 bits */
+typedef unsigned char uint8; /* >= 8 bits */
+typedef unsigned short uint16; /* >= 16 bits */
+typedef unsigned int uint32; /* >= 32 bits */
/*
* floatN --
- * Floating point number, AT LEAST N BITS IN SIZE,
- * used for numerical computations.
+ * Floating point number, AT LEAST N BITS IN SIZE,
+ * used for numerical computations.
*
- * Since sizeof(floatN) may be > sizeof(char *), always pass
- * floatN by reference.
+ * Since sizeof(floatN) may be > sizeof(char *), always pass
+ * floatN by reference.
*/
-typedef float float32data;
-typedef double float64data;
-typedef float *float32;
-typedef double *float64;
+typedef float float32data;
+typedef double float64data;
+typedef float *float32;
+typedef double *float64;
/*
* boolN --
- * Boolean value, AT LEAST N BITS IN SIZE.
+ * Boolean value, AT LEAST N BITS IN SIZE.
*/
-typedef uint8 bool8; /* >= 8 bits */
-typedef uint16 bool16; /* >= 16 bits */
-typedef uint32 bool32; /* >= 32 bits */
+typedef uint8 bool8; /* >= 8 bits */
+typedef uint16 bool16; /* >= 16 bits */
+typedef uint32 bool32; /* >= 32 bits */
/*
* bitsN --
- * Unit of bitwise operation, AT LEAST N BITS IN SIZE.
+ * Unit of bitwise operation, AT LEAST N BITS IN SIZE.
*/
-typedef uint8 bits8; /* >= 8 bits */
-typedef uint16 bits16; /* >= 16 bits */
-typedef uint32 bits32; /* >= 32 bits */
+typedef uint8 bits8; /* >= 8 bits */
+typedef uint16 bits16; /* >= 16 bits */
+typedef uint32 bits32; /* >= 32 bits */
/*
* wordN --
- * Unit of storage, AT LEAST N BITS IN SIZE,
- * used to fetch/store data.
+ * Unit of storage, AT LEAST N BITS IN SIZE,
+ * used to fetch/store data.
*/
-typedef uint8 word8; /* >= 8 bits */
-typedef uint16 word16; /* >= 16 bits */
-typedef uint32 word32; /* >= 32 bits */
+typedef uint8 word8; /* >= 8 bits */
+typedef uint16 word16; /* >= 16 bits */
+typedef uint32 word32; /* >= 32 bits */
/*
* Size --
- * Size of any memory resident object, as returned by sizeof.
+ * Size of any memory resident object, as returned by sizeof.
*/
-typedef unsigned int Size;
+typedef unsigned int Size;
/*
* Index --
- * Index into any memory resident array.
+ * Index into any memory resident array.
*
* Note:
- * Indices are non negative.
+ * Indices are non negative.
*/
-typedef unsigned int Index;
+typedef unsigned int Index;
#define MAXDIM 6
-typedef struct {
- int indx[MAXDIM];
-} IntArray;
+typedef struct
+{
+ int indx[MAXDIM];
+} IntArray;
/*
* Offset --
- * Offset into any memory resident array.
+ * Offset into any memory resident array.
*
* Note:
- * This differs from an Index in that an Index is always
- * non negative, whereas Offset may be negative.
+ * This differs from an Index in that an Index is always
+ * non negative, whereas Offset may be negative.
*/
-typedef signed int Offset;
+typedef signed int Offset;
/* ----------------------------------------------------------------
- * Section 4: datum type + support macros
+ * Section 4: datum type + support macros
* ----------------------------------------------------------------
*/
/*
* datum.h --
- * POSTGRES abstract data type datum representation definitions.
+ * POSTGRES abstract data type datum representation definitions.
*
* Note:
*
* Port Notes:
- * Postgres makes the following assumption about machines:
+ * Postgres makes the following assumption about machines:
*
- * sizeof(Datum) == sizeof(long) >= sizeof(void *) >= 4
+ * sizeof(Datum) == sizeof(long) >= sizeof(void *) >= 4
*
- * Postgres also assumes that
+ * Postgres also assumes that
*
- * sizeof(char) == 1
+ * sizeof(char) == 1
*
- * and that
+ * and that
*
- * sizeof(short) == 2
+ * sizeof(short) == 2
*
- * If your machine meets these requirements, Datums should also be checked
- * to see if the positioning is correct.
+ * If your machine meets these requirements, Datums should also be checked
+ * to see if the positioning is correct.
*
- * This file is MACHINE AND COMPILER dependent!!!
+ * This file is MACHINE AND COMPILER dependent!!!
*/
typedef unsigned long Datum; /* XXX sizeof(long) >= sizeof(void *) */
-typedef Datum * DatumPtr;
+typedef Datum *DatumPtr;
-#define GET_1_BYTE(datum) (((Datum) (datum)) & 0x000000ff)
-#define GET_2_BYTES(datum) (((Datum) (datum)) & 0x0000ffff)
-#define GET_4_BYTES(datum) (((Datum) (datum)) & 0xffffffff)
-#define SET_1_BYTE(value) (((Datum) (value)) & 0x000000ff)
-#define SET_2_BYTES(value) (((Datum) (value)) & 0x0000ffff)
-#define SET_4_BYTES(value) (((Datum) (value)) & 0xffffffff)
+#define GET_1_BYTE(datum) (((Datum) (datum)) & 0x000000ff)
+#define GET_2_BYTES(datum) (((Datum) (datum)) & 0x0000ffff)
+#define GET_4_BYTES(datum) (((Datum) (datum)) & 0xffffffff)
+#define SET_1_BYTE(value) (((Datum) (value)) & 0x000000ff)
+#define SET_2_BYTES(value) (((Datum) (value)) & 0x0000ffff)
+#define SET_4_BYTES(value) (((Datum) (value)) & 0xffffffff)
/*
* DatumGetChar --
- * Returns character value of a datum.
+ * Returns character value of a datum.
*/
#define DatumGetChar(X) ((char) GET_1_BYTE(X))
/*
* CharGetDatum --
- * Returns datum representation for a character.
+ * Returns datum representation for a character.
*/
#define CharGetDatum(X) ((Datum) SET_1_BYTE(X))
/*
* Int8GetDatum --
- * Returns datum representation for an 8-bit integer.
+ * Returns datum representation for an 8-bit integer.
*/
#define Int8GetDatum(X) ((Datum) SET_1_BYTE(X))
/*
* DatumGetUInt8 --
- * Returns 8-bit unsigned integer value of a datum.
+ * Returns 8-bit unsigned integer value of a datum.
*/
#define DatumGetUInt8(X) ((uint8) GET_1_BYTE(X))
/*
* UInt8GetDatum --
- * Returns datum representation for an 8-bit unsigned integer.
+ * Returns datum representation for an 8-bit unsigned integer.
*/
#define UInt8GetDatum(X) ((Datum) SET_1_BYTE(X))
/*
* DatumGetInt16 --
- * Returns 16-bit integer value of a datum.
+ * Returns 16-bit integer value of a datum.
*/
#define DatumGetInt16(X) ((int16) GET_2_BYTES(X))
/*
* Int16GetDatum --
- * Returns datum representation for a 16-bit integer.
+ * Returns datum representation for a 16-bit integer.
*/
#define Int16GetDatum(X) ((Datum) SET_2_BYTES(X))
/*
* DatumGetUInt16 --
- * Returns 16-bit unsigned integer value of a datum.
+ * Returns 16-bit unsigned integer value of a datum.
*/
#define DatumGetUInt16(X) ((uint16) GET_2_BYTES(X))
/*
* UInt16GetDatum --
- * Returns datum representation for a 16-bit unsigned integer.
+ * Returns datum representation for a 16-bit unsigned integer.
*/
#define UInt16GetDatum(X) ((Datum) SET_2_BYTES(X))
/*
* DatumGetInt32 --
- * Returns 32-bit integer value of a datum.
+ * Returns 32-bit integer value of a datum.
*/
#define DatumGetInt32(X) ((int32) GET_4_BYTES(X))
/*
* Int32GetDatum --
- * Returns datum representation for a 32-bit integer.
+ * Returns datum representation for a 32-bit integer.
*/
#define Int32GetDatum(X) ((Datum) SET_4_BYTES(X))
/*
* DatumGetUInt32 --
- * Returns 32-bit unsigned integer value of a datum.
+ * Returns 32-bit unsigned integer value of a datum.
*/
#define DatumGetUInt32(X) ((uint32) GET_4_BYTES(X))
/*
* UInt32GetDatum --
- * Returns datum representation for a 32-bit unsigned integer.
+ * Returns datum representation for a 32-bit unsigned integer.
*/
#define UInt32GetDatum(X) ((Datum) SET_4_BYTES(X))
/*
* DatumGetObjectId --
- * Returns object identifier value of a datum.
+ * Returns object identifier value of a datum.
*/
#define DatumGetObjectId(X) ((Oid) GET_4_BYTES(X))
/*
* ObjectIdGetDatum --
- * Returns datum representation for an object identifier.
+ * Returns datum representation for an object identifier.
*/
#define ObjectIdGetDatum(X) ((Datum) SET_4_BYTES(X))
/*
* DatumGetPointer --
- * Returns pointer value of a datum.
+ * Returns pointer value of a datum.
*/
#define DatumGetPointer(X) ((Pointer) X)
/*
* PointerGetDatum --
- * Returns datum representation for a pointer.
+ * Returns datum representation for a pointer.
*/
#define PointerGetDatum(X) ((Datum) X)
/*
* DatumGetName --
- * Returns name value of a datum.
+ * Returns name value of a datum.
*/
#define DatumGetName(X) ((Name) DatumGetPointer((Datum) X))
/*
* NameGetDatum --
- * Returns datum representation for a name.
+ * Returns datum representation for a name.
*/
#define NameGetDatum(X) PointerGetDatum((Pointer) X)
@@ -461,143 +464,144 @@ typedef Datum * DatumPtr;
/*
* DatumGetFloat32 --
- * Returns 32-bit floating point value of a datum.
- * This is really a pointer, of course.
+ * Returns 32-bit floating point value of a datum.
+ * This is really a pointer, of course.
*/
#define DatumGetFloat32(X) ((float32) DatumGetPointer((Datum) X))
/*
* Float32GetDatum --
- * Returns datum representation for a 32-bit floating point number.
- * This is really a pointer, of course.
+ * Returns datum representation for a 32-bit floating point number.
+ * This is really a pointer, of course.
*/
#define Float32GetDatum(X) PointerGetDatum((Pointer) X)
/*
* DatumGetFloat64 --
- * Returns 64-bit floating point value of a datum.
- * This is really a pointer, of course.
+ * Returns 64-bit floating point value of a datum.
+ * This is really a pointer, of course.
*/
#define DatumGetFloat64(X) ((float64) DatumGetPointer(X))
/*
* Float64GetDatum --
- * Returns datum representation for a 64-bit floating point number.
- * This is really a pointer, of course.
+ * Returns datum representation for a 64-bit floating point number.
+ * This is really a pointer, of course.
*/
#define Float64GetDatum(X) PointerGetDatum((Pointer) X)
/* ----------------------------------------------------------------
- * Section 5: IsValid macros for system types
+ * Section 5: IsValid macros for system types
* ----------------------------------------------------------------
*/
/*
* BoolIsValid --
- * True iff bool is valid.
+ * True iff bool is valid.
*/
-#define BoolIsValid(boolean) ((boolean) == false || (boolean) == true)
+#define BoolIsValid(boolean) ((boolean) == false || (boolean) == true)
/*
* PointerIsValid --
- * True iff pointer is valid.
+ * True iff pointer is valid.
*/
-#define PointerIsValid(pointer) (bool)((void*)(pointer) != NULL)
+#define PointerIsValid(pointer) (bool)((void*)(pointer) != NULL)
/*
* PointerIsInBounds --
- * True iff pointer is within given bounds.
+ * True iff pointer is within given bounds.
*
* Note:
- * Assumes the bounded interval to be [min,max),
- * i.e. closed on the left and open on the right.
+ * Assumes the bounded interval to be [min,max),
+ * i.e. closed on the left and open on the right.
*/
#define PointerIsInBounds(pointer, min, max) \
- ((min) <= (pointer) && (pointer) < (max))
+ ((min) <= (pointer) && (pointer) < (max))
/*
* PointerIsAligned --
- * True iff pointer is properly aligned to point to the given type.
+ * True iff pointer is properly aligned to point to the given type.
*/
-#define PointerIsAligned(pointer, type) \
- (((long)(pointer) % (sizeof (type))) == 0)
+#define PointerIsAligned(pointer, type) \
+ (((long)(pointer) % (sizeof (type))) == 0)
/* ----------------------------------------------------------------
- * Section 6: offsetof, lengthof, endof
+ * Section 6: offsetof, lengthof, endof
* ----------------------------------------------------------------
*/
/*
* offsetof --
- * Offset of a structure/union field within that structure/union.
+ * Offset of a structure/union field within that structure/union.
*
- * XXX This is supposed to be part of stddef.h, but isn't on
- * some systems (like SunOS 4).
+ * XXX This is supposed to be part of stddef.h, but isn't on
+ * some systems (like SunOS 4).
*/
#ifndef offsetof
#define offsetof(type, field) ((long) &((type *)0)->field)
-#endif /* offsetof */
+#endif /* offsetof */
/*
* lengthof --
- * Number of elements in an array.
+ * Number of elements in an array.
*/
-#define lengthof(array) (sizeof (array) / sizeof ((array)[0]))
+#define lengthof(array) (sizeof (array) / sizeof ((array)[0]))
/*
* endof --
- * Address of the element one past the last in an array.
+ * Address of the element one past the last in an array.
*/
#define endof(array) (&array[lengthof(array)])
/* ----------------------------------------------------------------
- * Section 7: exception handling definitions
- * Assert, Trap, etc macros
+ * Section 7: exception handling definitions
+ * Assert, Trap, etc macros
* ----------------------------------------------------------------
*/
/*
* Exception Handling definitions
*/
-typedef char *ExcMessage;
-typedef struct Exception {
- ExcMessage message;
-} Exception;
+typedef char *ExcMessage;
+typedef struct Exception
+{
+ ExcMessage message;
+} Exception;
/*
* NO_ASSERT_CHECKING, if defined, turns off all the assertions.
* - plai 9/5/90
*
* It should _NOT_ be undef'ed in releases or in benchmark copies
- *
+ *
* #undef NO_ASSERT_CHECKING
*/
/*
* Trap --
- * Generates an exception if the given condition is true.
+ * Generates an exception if the given condition is true.
*
*/
#define Trap(condition, exception) \
- { if (condition) \
- ExceptionalCondition(CppAsString(condition), &(exception), \
- (char*)NULL, __FILE__, __LINE__); }
+ { if (condition) \
+ ExceptionalCondition(CppAsString(condition), &(exception), \
+ (char*)NULL, __FILE__, __LINE__); }
-/*
- * TrapMacro is the same as Trap but it's intended for use in macros:
+/*
+ * TrapMacro is the same as Trap but it's intended for use in macros:
*
- * #define foo(x) (AssertM(x != 0) && bar(x))
+ * #define foo(x) (AssertM(x != 0) && bar(x))
*
- * Isn't CPP fun?
+ * Isn't CPP fun?
*/
#define TrapMacro(condition, exception) \
- ((bool) ((! condition) || \
- (ExceptionalCondition(CppAsString(condition), \
- &(exception), \
- (char*) NULL, __FILE__, __LINE__))))
-
+ ((bool) ((! condition) || \
+ (ExceptionalCondition(CppAsString(condition), \
+ &(exception), \
+ (char*) NULL, __FILE__, __LINE__))))
+
#ifdef NO_ASSERT_CHECKING
#define Assert(condition)
#define AssertMacro(condition) true
@@ -605,40 +609,40 @@ typedef struct Exception {
#define AssertState(condition)
#else
#define Assert(condition) \
- Trap(!(condition), FailedAssertion)
+ Trap(!(condition), FailedAssertion)
#define AssertMacro(condition) \
- TrapMacro(!(condition), FailedAssertion)
+ TrapMacro(!(condition), FailedAssertion)
#define AssertArg(condition) \
- Trap(!(condition), BadArg)
+ Trap(!(condition), BadArg)
#define AssertState(condition) \
- Trap(!(condition), BadState)
+ Trap(!(condition), BadState)
-#endif /* NO_ASSERT_CHECKING */
+#endif /* NO_ASSERT_CHECKING */
/*
* LogTrap --
- * Generates an exception with a message if the given condition is true.
+ * Generates an exception with a message if the given condition is true.
*
*/
#define LogTrap(condition, exception, printArgs) \
- { if (condition) \
- ExceptionalCondition(CppAsString(condition), &(exception), \
- form printArgs, __FILE__, __LINE__); }
+ { if (condition) \
+ ExceptionalCondition(CppAsString(condition), &(exception), \
+ form printArgs, __FILE__, __LINE__); }
-/*
- * LogTrapMacro is the same as LogTrap but it's intended for use in macros:
+/*
+ * LogTrapMacro is the same as LogTrap but it's intended for use in macros:
*
- * #define foo(x) (LogAssertMacro(x != 0, "yow!") && bar(x))
+ * #define foo(x) (LogAssertMacro(x != 0, "yow!") && bar(x))
*/
#define LogTrapMacro(condition, exception, printArgs) \
- ((bool) ((! condition) || \
- (ExceptionalCondition(CppAsString(condition), \
- &(exception), \
- form printArgs, __FILE__, __LINE__))))
-
+ ((bool) ((! condition) || \
+ (ExceptionalCondition(CppAsString(condition), \
+ &(exception), \
+ form printArgs, __FILE__, __LINE__))))
+
#ifdef NO_ASSERT_CHECKING
#define LogAssert(condition, printArgs)
#define LogAssertMacro(condition, printArgs) true
@@ -646,73 +650,74 @@ typedef struct Exception {
#define LogAssertState(condition, printArgs)
#else
#define LogAssert(condition, printArgs) \
- LogTrap(!(condition), FailedAssertion, printArgs)
+ LogTrap(!(condition), FailedAssertion, printArgs)
#define LogAssertMacro(condition, printArgs) \
- LogTrapMacro(!(condition), FailedAssertion, printArgs)
+ LogTrapMacro(!(condition), FailedAssertion, printArgs)
#define LogAssertArg(condition, printArgs) \
- LogTrap(!(condition), BadArg, printArgs)
+ LogTrap(!(condition), BadArg, printArgs)
#define LogAssertState(condition, printArgs) \
- LogTrap(!(condition), BadState, printArgs)
+ LogTrap(!(condition), BadState, printArgs)
-#endif /* NO_ASSERT_CHECKING */
+#endif /* NO_ASSERT_CHECKING */
/* ----------------------------------------------------------------
- * Section 8: Min, Max, Abs macros
+ * Section 8: Min, Max, Abs macros
* ----------------------------------------------------------------
*/
/*
* Max --
- * Return the maximum of two numbers.
+ * Return the maximum of two numbers.
*/
-#define Max(x, y) ((x) > (y) ? (x) : (y))
+#define Max(x, y) ((x) > (y) ? (x) : (y))
/*
* Min --
- * Return the minimum of two numbers.
+ * Return the minimum of two numbers.
*/
-#define Min(x, y) ((x) < (y) ? (x) : (y))
+#define Min(x, y) ((x) < (y) ? (x) : (y))
/*
* Abs --
- * Return the absolute value of the argument.
+ * Return the absolute value of the argument.
*/
-#define Abs(x) ((x) >= 0 ? (x) : -(x))
+#define Abs(x) ((x) >= 0 ? (x) : -(x))
/*
* strNcpy --
- * Does string copy, and forces terminating NULL
+ * Does string copy, and forces terminating NULL
*/
/* we do this so if the macro is used in an if action, it will work */
#define strNcpy(dst,src,len) (strncpy((dst),(src),(len)),*((dst)+(len))='\0')
/* ----------------------------------------------------------------
- * Section 9: externs
+ * Section 9: externs
* ----------------------------------------------------------------
*/
-extern Exception FailedAssertion;
-extern Exception BadArg;
-extern Exception BadState;
+extern Exception FailedAssertion;
+extern Exception BadArg;
+extern Exception BadState;
/* in utils/error/assert.c */
-extern int ExceptionalCondition(char *conditionName,
- Exception *exceptionP, char *details,
- char *fileName, int lineNumber);
+extern int
+ExceptionalCondition(char *conditionName,
+ Exception * exceptionP, char *details,
+ char *fileName, int lineNumber);
/* ----------------
- * form is used by assert and the exception handling stuff
+ * form is used by assert and the exception handling stuff
* ----------------
*/
-extern char *form(const char *fmt, ...);
+extern char *form(const char *fmt,...);
/* ----------------------------------------------------------------
- * Section 10: berkeley-specific configuration
+ * Section 10: berkeley-specific configuration
*
* this section contains settings which are only relevant to the UC Berkeley
* sites. Other sites can ignore this
@@ -720,10 +725,10 @@ extern char *form(const char *fmt, ...);
*/
/* ----------------
- * storage managers
+ * storage managers
*
- * These are experimental and are not supported in the code that
- * we distribute to other sites.
+ * These are experimental and are not supported in the code that
+ * we distribute to other sites.
* ----------------
*/
#ifdef SEQUOIA
@@ -733,33 +738,33 @@ extern char *form(const char *fmt, ...);
/* ----------------------------------------------------------------
- * Section 11: system-specific hacks
+ * Section 11: system-specific hacks
*
- * This should be limited to things that absolutely have to be
- * included in every source file. The changes should be factored
- * into a separate file so that changes to one port don't require
- * changes to c.h (and everyone recompiling their whole system).
+ * This should be limited to things that absolutely have to be
+ * included in every source file. The changes should be factored
+ * into a separate file so that changes to one port don't require
+ * changes to c.h (and everyone recompiling their whole system).
* ----------------------------------------------------------------
*/
#ifdef FIXADE
-#if defined(hpux)
-#include "port/hpux/fixade.h" /* for unaligned access fixup */
-#endif /* hpux */
+#if defined(hpux)
+#include "port/hpux/fixade.h" /* for unaligned access fixup */
+#endif /* hpux */
#endif
#if defined(sunos4)
-#define memmove(d, s, l) bcopy(s, d, l)
+#define memmove(d, s, l) bcopy(s, d, l)
#include <unistd.h>
#endif
/* These are for things that are one way on Unix and another on NT */
-#define NULL_DEV "/dev/null"
-#define COPY_CMD "cp"
-#define SEP_CHAR '/'
+#define NULL_DEV "/dev/null"
+#define COPY_CMD "cp"
+#define SEP_CHAR '/'
/* ----------------
- * end of c.h
+ * end of c.h
* ----------------
*/
-#endif /* C_H */
+#endif /* C_H */
diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h
index b183180c604..c888d8648de 100644
--- a/src/include/catalog/catalog.h
+++ b/src/include/catalog/catalog.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* catalog.h--
- * prototypes for functions in lib/catalog/catalog.c
+ * prototypes for functions in lib/catalog/catalog.c
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: catalog.h,v 1.2 1996/11/05 10:37:14 scrappy Exp $
+ * $Id: catalog.h,v 1.3 1997/09/07 04:56:25 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,10 +15,10 @@
#include <access/tupdesc.h>
-extern char *relpath(char relname[]);
-extern bool IsSystemRelationName(char *relname);
-extern bool IsSharedSystemRelationName(char *relname);
-extern Oid newoid(void);
-extern void fillatt(TupleDesc att);
+extern char *relpath(char relname[]);
+extern bool IsSystemRelationName(char *relname);
+extern bool IsSharedSystemRelationName(char *relname);
+extern Oid newoid(void);
+extern void fillatt(TupleDesc att);
-#endif /* CATALOG_H */
+#endif /* CATALOG_H */
diff --git a/src/include/catalog/catname.h b/src/include/catalog/catname.h
index 988e186492f..8dcf95b45ab 100644
--- a/src/include/catalog/catname.h
+++ b/src/include/catalog/catname.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* catname.h--
- * POSTGRES system catalog relation name definitions.
+ * POSTGRES system catalog relation name definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: catname.h,v 1.4 1997/09/01 08:09:09 vadim Exp $
+ * $Id: catname.h,v 1.5 1997/09/07 04:56:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef CATNAME_H
+#ifndef CATNAME_H
#define CATNAME_H
@@ -49,6 +49,6 @@
#define RelCheckRelationName "pg_relcheck"
#define TriggerRelationName "pg_trigger"
-extern char *SharedSystemRelationNames[];
+extern char *SharedSystemRelationNames[];
-#endif /* CATNAME_H */
+#endif /* CATNAME_H */
diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h
index 643b5198f09..616aa9e42ef 100644
--- a/src/include/catalog/heap.h
+++ b/src/include/catalog/heap.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* heap.h--
- * prototypes for functions in lib/catalog/heap.c
+ * prototypes for functions in lib/catalog/heap.c
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: heap.h,v 1.4 1997/08/19 21:37:47 momjian Exp $
+ * $Id: heap.h,v 1.5 1997/09/07 04:56:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,15 +17,16 @@
extern Relation heap_creatr(char *relname, unsigned smgr, TupleDesc att);
-extern Oid heap_create(char relname[],
- char *typename,
- int arch,
- unsigned smgr, TupleDesc tupdesc);
+extern Oid
+heap_create(char relname[],
+ char *typename,
+ int arch,
+ unsigned smgr, TupleDesc tupdesc);
-extern void heap_destroy(char relname[]);
-extern void heap_destroyr(Relation r);
-
-extern void InitTempRelList(void);
-extern void DestroyTempRels(void);
+extern void heap_destroy(char relname[]);
+extern void heap_destroyr(Relation r);
-#endif /* HEAP_H */
+extern void InitTempRelList(void);
+extern void DestroyTempRels(void);
+
+#endif /* HEAP_H */
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index 70f37d32f30..5ce47e90168 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* index.h--
- * prototypes for index.c.
+ * prototypes for index.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: index.h,v 1.5 1997/03/19 07:36:35 vadim Exp $
+ * $Id: index.h,v 1.6 1997/09/07 04:56:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef INDEX_H
+#ifndef INDEX_H
#define INDEX_H
#include <nodes/execnodes.h>
@@ -18,48 +18,53 @@
#include <access/itup.h>
#include <access/funcindex.h>
-extern Form_pg_am
-AccessMethodObjectIdGetAccessMethodTupleForm(Oid accessMethodObjectId);
+extern Form_pg_am
+ AccessMethodObjectIdGetAccessMethodTupleForm(Oid accessMethodObjectId);
extern void
-UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate);
+ UpdateIndexPredicate(Oid indexoid, Node * oldPred, Node * predicate);
-extern void InitIndexStrategy(int numatts,
- Relation indexRelation,
- Oid accessMethodObjectId);
+extern void
+InitIndexStrategy(int numatts,
+ Relation indexRelation,
+ Oid accessMethodObjectId);
-extern void index_create(char *heapRelationName,
- char* indexRelationName,
- FuncIndexInfo *funcInfo,
- List *attributeList,
+extern void
+index_create(char *heapRelationName,
+ char *indexRelationName,
+ FuncIndexInfo * funcInfo,
+ List * attributeList,
Oid accessMethodObjectId,
- int numatts,
+ int numatts,
AttrNumber attNums[],
- Oid classObjectId[],
+ Oid classObjectId[],
uint16 parameterCount,
- Datum *parameter,
- Node *predicate,
+ Datum * parameter,
+ Node * predicate,
bool islossy,
bool unique);
-extern void index_destroy(Oid indexId);
+extern void index_destroy(Oid indexId);
-extern void FormIndexDatum(int numberOfAttributes,
- AttrNumber attributeNumber[], HeapTuple heapTuple,
- TupleDesc heapDescriptor, Buffer buffer, Datum *datum,
- char *nullv, FuncIndexInfoPtr fInfo);
+extern void
+FormIndexDatum(int numberOfAttributes,
+ AttrNumber attributeNumber[], HeapTuple heapTuple,
+ TupleDesc heapDescriptor, Buffer buffer, Datum * datum,
+ char *nullv, FuncIndexInfoPtr fInfo);
-extern void UpdateStats(Oid relid, long reltuples, bool hasindex);
+extern void UpdateStats(Oid relid, long reltuples, bool hasindex);
-extern void FillDummyExprContext(ExprContext *econtext, TupleTableSlot *slot,
- TupleDesc tupdesc, Buffer buffer);
+extern void
+FillDummyExprContext(ExprContext * econtext, TupleTableSlot * slot,
+ TupleDesc tupdesc, Buffer buffer);
-extern void index_build(Relation heapRelation, Relation indexRelation,
- int numberOfAttributes, AttrNumber attributeNumber[],
- uint16 parameterCount, Datum *parameter, FuncIndexInfo *funcInfo,
- PredInfo *predInfo);
+extern void
+index_build(Relation heapRelation, Relation indexRelation,
+ int numberOfAttributes, AttrNumber attributeNumber[],
+ uint16 parameterCount, Datum * parameter, FuncIndexInfo * funcInfo,
+ PredInfo * predInfo);
-extern bool IndexIsUnique(Oid indexId);
-extern bool IndexIsUniqueNoCache(Oid indexId);
+extern bool IndexIsUnique(Oid indexId);
+extern bool IndexIsUniqueNoCache(Oid indexId);
-#endif /* INDEX_H */
+#endif /* INDEX_H */
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index d79e1581bd8..c428aec8a22 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* indexing.h--
- * This include provides some definitions to support indexing
- * on system catalogs
+ * This include provides some definitions to support indexing
+ * on system catalogs
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: indexing.h,v 1.4 1997/08/31 09:55:20 vadim Exp $
+ * $Id: indexing.h,v 1.5 1997/09/07 04:56:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,12 +20,12 @@
/*
* Some definitions for indices on pg_attribute
*/
-#define Num_pg_attr_indices 3
-#define Num_pg_proc_indices 3
-#define Num_pg_type_indices 2
+#define Num_pg_attr_indices 3
+#define Num_pg_proc_indices 3
+#define Num_pg_type_indices 2
#define Num_pg_class_indices 2
#define Num_pg_attrdef_indices 1
-#define Num_pg_relcheck_indices 1
+#define Num_pg_relcheck_indices 1
#define Num_pg_trigger_indices 1
@@ -38,48 +38,52 @@
#define ProcedureNameIndex "pg_procnameind"
#define ProcedureOidIndex "pg_procidind"
#define ProcedureSrcIndex "pg_procsrcind"
-#define TypeNameIndex "pg_typenameind"
-#define TypeOidIndex "pg_typeidind"
-#define ClassNameIndex "pg_classnameind"
-#define ClassOidIndex "pg_classoidind"
+#define TypeNameIndex "pg_typenameind"
+#define TypeOidIndex "pg_typeidind"
+#define ClassNameIndex "pg_classnameind"
+#define ClassOidIndex "pg_classoidind"
#define AttrDefaultIndex "pg_attrdefind"
-#define RelCheckIndex "pg_relcheckind"
+#define RelCheckIndex "pg_relcheckind"
#define TriggerRelidIndex "pg_trigrelidind"
-extern char *Name_pg_attr_indices[];
-extern char *Name_pg_proc_indices[];
-extern char *Name_pg_type_indices[];
-extern char *Name_pg_class_indices[];
-extern char *Name_pg_attrdef_indices[];
-extern char *Name_pg_relcheck_indices[];
-extern char *Name_pg_trigger_indices[];
+extern char *Name_pg_attr_indices[];
+extern char *Name_pg_proc_indices[];
+extern char *Name_pg_type_indices[];
+extern char *Name_pg_class_indices[];
+extern char *Name_pg_attrdef_indices[];
+extern char *Name_pg_relcheck_indices[];
+extern char *Name_pg_trigger_indices[];
-extern char *IndexedCatalogNames[];
+extern char *IndexedCatalogNames[];
/*
- * indexing.c prototypes
+ * indexing.c prototypes
*
* Functions for each index to perform the necessary scan on a cache miss.
*/
-extern void CatalogOpenIndices(int nIndices, char *names[], Relation idescs[]);
-extern void CatalogCloseIndices(int nIndices, Relation *idescs);
-extern void CatalogIndexInsert(Relation *idescs,
- int nIndices,
- Relation heapRelation,
- HeapTuple heapTuple);
-extern bool CatalogHasIndex(char *catName, Oid catId);
-
-extern HeapTuple AttributeNameIndexScan(Relation heapRelation,
- Oid relid,
- char *attname);
-
-extern HeapTuple AttributeNumIndexScan(Relation heapRelation,
- Oid relid,
- AttrNumber attnum);
+extern void CatalogOpenIndices(int nIndices, char *names[], Relation idescs[]);
+extern void CatalogCloseIndices(int nIndices, Relation * idescs);
+extern void
+CatalogIndexInsert(Relation * idescs,
+ int nIndices,
+ Relation heapRelation,
+ HeapTuple heapTuple);
+extern bool CatalogHasIndex(char *catName, Oid catId);
+
+extern HeapTuple
+AttributeNameIndexScan(Relation heapRelation,
+ Oid relid,
+ char *attname);
+
+extern HeapTuple
+AttributeNumIndexScan(Relation heapRelation,
+ Oid relid,
+ AttrNumber attnum);
extern HeapTuple ProcedureOidIndexScan(Relation heapRelation, Oid procId);
-extern HeapTuple ProcedureNameIndexScan(Relation heapRelation,
- char *procName, int nargs, Oid *argTypes);
-extern HeapTuple ProcedureSrcIndexScan(Relation heapRelation, text *procSrc);
+extern HeapTuple
+ProcedureNameIndexScan(Relation heapRelation,
+ char *procName, int nargs, Oid * argTypes);
+extern HeapTuple ProcedureSrcIndexScan(Relation heapRelation, text * procSrc);
extern HeapTuple TypeOidIndexScan(Relation heapRelation, Oid typeId);
extern HeapTuple TypeNameIndexScan(Relation heapRelation, char *typeName);
extern HeapTuple ClassNameIndexScan(Relation heapRelation, char *relName);
@@ -93,26 +97,26 @@ extern HeapTuple ClassOidIndexScan(Relation heapRelation, Oid relId);
* The keyword is DECLARE_INDEX every thing after that is just like in a
* normal specification of the 'define index' POSTQUEL command.
*/
-DECLARE_INDEX(pg_attnameind on pg_attribute using btree (mkoidname(attrelid, attname) oidname_ops));
-DECLARE_INDEX(pg_attnumind on pg_attribute using btree (mkoidint2(attrelid, attnum) oidint2_ops));
-DECLARE_INDEX(pg_attrelidind on pg_attribute using btree (attrelid oid_ops));
+DECLARE_INDEX(pg_attnameind on pg_attribute using btree(mkoidname(attrelid, attname) oidname_ops));
+DECLARE_INDEX(pg_attnumind on pg_attribute using btree(mkoidint2(attrelid, attnum) oidint2_ops));
+DECLARE_INDEX(pg_attrelidind on pg_attribute using btree(attrelid oid_ops));
-DECLARE_INDEX(pg_procidind on pg_proc using btree (Oid oid_ops));
-DECLARE_INDEX(pg_procnameind on pg_proc using btree (proname name_ops));
-DECLARE_INDEX(pg_procsrcind on pg_proc using btree (prosrc text_ops));
+DECLARE_INDEX(pg_procidind on pg_proc using btree(Oid oid_ops));
+DECLARE_INDEX(pg_procnameind on pg_proc using btree(proname name_ops));
+DECLARE_INDEX(pg_procsrcind on pg_proc using btree(prosrc text_ops));
-DECLARE_INDEX(pg_typeidind on pg_type using btree (Oid oid_ops));
-DECLARE_INDEX(pg_typenameind on pg_type using btree (typname name_ops));
+DECLARE_INDEX(pg_typeidind on pg_type using btree(Oid oid_ops));
+DECLARE_INDEX(pg_typenameind on pg_type using btree(typname name_ops));
-DECLARE_INDEX(pg_classnameind on pg_class using btree (relname name_ops));
-DECLARE_INDEX(pg_classoidind on pg_class using btree (Oid oid_ops));
+DECLARE_INDEX(pg_classnameind on pg_class using btree(relname name_ops));
+DECLARE_INDEX(pg_classoidind on pg_class using btree(Oid oid_ops));
-DECLARE_INDEX(pg_attrdefind on pg_attrdef using btree (adrelid oid_ops));
-DECLARE_INDEX(pg_relcheckind on pg_relcheck using btree (rcrelid oid_ops));
+DECLARE_INDEX(pg_attrdefind on pg_attrdef using btree(adrelid oid_ops));
+DECLARE_INDEX(pg_relcheckind on pg_relcheck using btree(rcrelid oid_ops));
-DECLARE_INDEX(pg_trigrelidind on pg_trigger using btree (tgrelid oid_ops));
+DECLARE_INDEX(pg_trigrelidind on pg_trigger using btree(tgrelid oid_ops));
/* now build indices in the initialization scripts */
BUILD_INDICES
-#endif /* INDEXING_H */
+#endif /* INDEXING_H */
diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index f951e1e5d8c..39f8c5d697a 100644
--- a/src/include/catalog/pg_aggregate.h
+++ b/src/include/catalog/pg_aggregate.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_aggregate.h--
- * definition of the system "aggregate" relation (pg_aggregate)
- * along with the relation's initial contents.
+ * definition of the system "aggregate" relation (pg_aggregate)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_aggregate.h,v 1.8 1997/08/21 23:56:45 momjian Exp $
+ * $Id: pg_aggregate.h,v 1.9 1997/09/07 04:56:36 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,64 +19,65 @@
#define PG_AGGREGATE_H
/* ----------------
- * postgres.h contains the system type definitions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definitions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------------------------------------------------------
- * pg_aggregate definition.
+ * pg_aggregate definition.
*
- * cpp turns this into typedef struct FormData_pg_aggregate
+ * cpp turns this into typedef struct FormData_pg_aggregate
*
- * aggname name of the aggregate
- * aggtransfn1 transition function 1
- * aggtransfn2 transition function 2
- * aggfinalfn final function
- * aggbasetype type of data on which aggregate operates
- * aggtranstype1 output types for transition func 1
- * aggtranstype2 output types for transition func 2
- * aggfinaltype output type for final function
- * agginitval1 initial aggregate value
- * agginitval2 initial value for transition state 2
+ * aggname name of the aggregate
+ * aggtransfn1 transition function 1
+ * aggtransfn2 transition function 2
+ * aggfinalfn final function
+ * aggbasetype type of data on which aggregate operates
+ * aggtranstype1 output types for transition func 1
+ * aggtranstype2 output types for transition func 2
+ * aggfinaltype output type for final function
+ * agginitval1 initial aggregate value
+ * agginitval2 initial value for transition state 2
* ----------------------------------------------------------------
- */
-CATALOG(pg_aggregate) {
- NameData aggname;
- Oid aggowner;
- regproc aggtransfn1;
- regproc aggtransfn2;
- regproc aggfinalfn;
- Oid aggbasetype;
- Oid aggtranstype1;
- Oid aggtranstype2;
- Oid aggfinaltype;
- text agginitval1; /* VARIABLE LENGTH FIELD */
- text agginitval2; /* VARIABLE LENGTH FIELD */
+ */
+CATALOG(pg_aggregate)
+{
+ NameData aggname;
+ Oid aggowner;
+ regproc aggtransfn1;
+ regproc aggtransfn2;
+ regproc aggfinalfn;
+ Oid aggbasetype;
+ Oid aggtranstype1;
+ Oid aggtranstype2;
+ Oid aggfinaltype;
+ text agginitval1;/* VARIABLE LENGTH FIELD */
+ text agginitval2;/* VARIABLE LENGTH FIELD */
} FormData_pg_aggregate;
/* ----------------
- * Form_pg_aggregate corresponds to a pointer to a tuple with
- * the format of pg_aggregate relation.
+ * Form_pg_aggregate corresponds to a pointer to a tuple with
+ * the format of pg_aggregate relation.
* ----------------
*/
-typedef FormData_pg_aggregate *Form_pg_aggregate;
+typedef FormData_pg_aggregate *Form_pg_aggregate;
/* ----------------
- * compiler constants for pg_aggregate
+ * compiler constants for pg_aggregate
* ----------------
*/
-#define Natts_pg_aggregate 11
-#define Anum_pg_aggregate_aggname 1
-#define Anum_pg_aggregate_aggowner 2
+#define Natts_pg_aggregate 11
+#define Anum_pg_aggregate_aggname 1
+#define Anum_pg_aggregate_aggowner 2
#define Anum_pg_aggregate_aggtransfn1 3
#define Anum_pg_aggregate_aggtransfn2 4
#define Anum_pg_aggregate_aggfinalfn 5
#define Anum_pg_aggregate_aggbasetype 6
-#define Anum_pg_aggregate_aggtranstype1 7
-#define Anum_pg_aggregate_aggtranstype2 8
+#define Anum_pg_aggregate_aggtranstype1 7
+#define Anum_pg_aggregate_aggtranstype2 8
#define Anum_pg_aggregate_aggfinaltype 9
#define Anum_pg_aggregate_agginitval1 10
#define Anum_pg_aggregate_agginitval2 11
@@ -87,57 +88,59 @@ typedef FormData_pg_aggregate *Form_pg_aggregate;
* ---------------
*/
-DATA(insert OID = 0 ( avg PGUID int4pl int4inc int4div 23 23 23 23 _null_ 0 ));
-DATA(insert OID = 0 ( avg PGUID int2pl int2inc int2div 21 21 21 21 _null_ 0 ));
-DATA(insert OID = 0 ( avg PGUID float4pl float4inc float4div 700 700 700 700 _null_ 0.0 ));
-DATA(insert OID = 0 ( avg PGUID float8pl float8inc float8div 701 701 701 701 _null_ 0.0 ));
-DATA(insert OID = 0 ( avg PGUID cash_pl float8inc cash_div 790 790 701 790 _null_ 0.0 ));
-DATA(insert OID = 0 ( avg PGUID timespan_pl float8inc timespan_div 1186 1186 701 1186 _null_ 0.0 ));
+DATA(insert OID = 0 ( avg PGUID int4pl int4inc int4div 23 23 23 23 _null_ 0 ));
+DATA(insert OID = 0 ( avg PGUID int2pl int2inc int2div 21 21 21 21 _null_ 0 ));
+DATA(insert OID = 0 ( avg PGUID float4pl float4inc float4div 700 700 700 700 _null_ 0.0 ));
+DATA(insert OID = 0 ( avg PGUID float8pl float8inc float8div 701 701 701 701 _null_ 0.0 ));
+DATA(insert OID = 0 ( avg PGUID cash_pl float8inc cash_div 790 790 701 790 _null_ 0.0 ));
+DATA(insert OID = 0 ( avg PGUID timespan_pl float8inc timespan_div 1186 1186 701 1186 _null_ 0.0 ));
-DATA(insert OID = 0 ( sum PGUID int4pl - - 23 23 0 23 _null_ _null_ ));
-DATA(insert OID = 0 ( sum PGUID int2pl - - 21 21 0 21 _null_ _null_ ));
-DATA(insert OID = 0 ( sum PGUID float4pl - - 700 700 0 700 _null_ _null_ ));
-DATA(insert OID = 0 ( sum PGUID float8pl - - 701 701 0 701 _null_ _null_ ));
-DATA(insert OID = 0 ( sum PGUID cash_pl - - 790 790 0 790 _null_ _null_ ));
-DATA(insert OID = 0 ( sum PGUID timespan_pl - - 1186 1186 0 1186 _null_ _null_ ));
+DATA(insert OID = 0 ( sum PGUID int4pl - - 23 23 0 23 _null_ _null_ ));
+DATA(insert OID = 0 ( sum PGUID int2pl - - 21 21 0 21 _null_ _null_ ));
+DATA(insert OID = 0 ( sum PGUID float4pl - - 700 700 0 700 _null_ _null_ ));
+DATA(insert OID = 0 ( sum PGUID float8pl - - 701 701 0 701 _null_ _null_ ));
+DATA(insert OID = 0 ( sum PGUID cash_pl - - 790 790 0 790 _null_ _null_ ));
+DATA(insert OID = 0 ( sum PGUID timespan_pl - - 1186 1186 0 1186 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID int4larger - - 23 23 0 23 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID int2larger - - 21 21 0 21 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID float4larger - - 700 700 0 700 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID float8larger - - 701 701 0 701 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID int4larger - - 702 702 0 702 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID date_larger - - 1082 1082 0 1082 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID float8larger - - 1084 1084 0 1084 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID cashlarger - - 790 790 0 790 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID datetime_larger - - 1184 1184 0 1184 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID timespan_larger - - 1186 1186 0 1186 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID int4larger - - 23 23 0 23 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID int2larger - - 21 21 0 21 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID float4larger - - 700 700 0 700 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID float8larger - - 701 701 0 701 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID int4larger - - 702 702 0 702 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID date_larger - - 1082 1082 0 1082 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID float8larger - - 1084 1084 0 1084 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID cashlarger - - 790 790 0 790 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID datetime_larger - - 1184 1184 0 1184 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID timespan_larger - - 1186 1186 0 1186 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID int4smaller - - 23 23 0 23 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID int2smaller - - 21 21 0 21 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID float4smaller - - 700 700 0 700 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID float8smaller - - 701 701 0 701 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID int4smaller - - 702 702 0 702 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID date_smaller - - 1082 1082 0 1082 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID float8smaller - - 1084 1084 0 1084 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID cashsmaller - - 790 790 0 790 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID datetime_smaller - - 1184 1184 0 1184 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID timespan_smaller - - 1186 1186 0 1186 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID int4smaller - - 23 23 0 23 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID int2smaller - - 21 21 0 21 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID float4smaller - - 700 700 0 700 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID float8smaller - - 701 701 0 701 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID int4smaller - - 702 702 0 702 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID date_smaller - - 1082 1082 0 1082 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID float8smaller - - 1084 1084 0 1084 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID cashsmaller - - 790 790 0 790 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID datetime_smaller - - 1184 1184 0 1184 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID timespan_smaller - - 1186 1186 0 1186 _null_ _null_ ));
DATA(insert OID = 0 ( count PGUID - int4inc - 0 0 23 23 _null_ 0 ));
/*
* prototypes for functions in pg_aggregate.c
*/
-extern void AggregateCreate(char *aggName,
- char *aggtransfn1Name,
- char *aggtransfn2Name,
- char *aggfinalfnName,
- char *aggbasetypeName,
- char *aggtransfn1typeName,
- char *aggtransfn2typeName,
- char *agginitval1,
- char *agginitval2);
-extern char *AggNameGetInitVal(char *aggName, Oid basetype,
- int xfuncno, bool *isNull);
+extern void
+AggregateCreate(char *aggName,
+ char *aggtransfn1Name,
+ char *aggtransfn2Name,
+ char *aggfinalfnName,
+ char *aggbasetypeName,
+ char *aggtransfn1typeName,
+ char *aggtransfn2typeName,
+ char *agginitval1,
+ char *agginitval2);
+extern char *
+AggNameGetInitVal(char *aggName, Oid basetype,
+ int xfuncno, bool * isNull);
-#endif /* PG_AGGREGATE_H */
+#endif /* PG_AGGREGATE_H */
diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h
index aca3de4f80b..361c102b502 100644
--- a/src/include/catalog/pg_am.h
+++ b/src/include/catalog/pg_am.h
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* pg_am.h--
- * definition of the system "am" relation (pg_am)
- * along with the relation's initial contents.
+ * definition of the system "am" relation (pg_am)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_am.h,v 1.2 1996/10/31 09:47:07 scrappy Exp $
+ * $Id: pg_am.h,v 1.3 1997/09/07 04:56:37 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
- * XXX do NOT break up DATA() statements into multiple lines!
- * the scripts are not as smart as you might think...
+ * XXX do NOT break up DATA() statements into multiple lines!
+ * the scripts are not as smart as you might think...
*
*-------------------------------------------------------------------------
*/
@@ -22,79 +22,80 @@
#define PG_AM_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_am definition. cpp turns this into
- * typedef struct FormData_pg_am
+ * pg_am definition. cpp turns this into
+ * typedef struct FormData_pg_am
* ----------------
- */
-CATALOG(pg_am) {
- NameData amname;
- Oid amowner;
- char amkind;
- int2 amstrategies;
- int2 amsupport;
- regproc amgettuple;
- regproc aminsert;
- regproc amdelete;
- regproc amgetattr;
- regproc amsetlock;
- regproc amsettid;
- regproc amfreetuple;
- regproc ambeginscan;
- regproc amrescan;
- regproc amendscan;
- regproc ammarkpos;
- regproc amrestrpos;
- regproc amopen;
- regproc amclose;
- regproc ambuild;
- regproc amcreate;
- regproc amdestroy;
+ */
+CATALOG(pg_am)
+{
+ NameData amname;
+ Oid amowner;
+ char amkind;
+ int2 amstrategies;
+ int2 amsupport;
+ regproc amgettuple;
+ regproc aminsert;
+ regproc amdelete;
+ regproc amgetattr;
+ regproc amsetlock;
+ regproc amsettid;
+ regproc amfreetuple;
+ regproc ambeginscan;
+ regproc amrescan;
+ regproc amendscan;
+ regproc ammarkpos;
+ regproc amrestrpos;
+ regproc amopen;
+ regproc amclose;
+ regproc ambuild;
+ regproc amcreate;
+ regproc amdestroy;
} FormData_pg_am;
/* ----------------
- * Form_pg_am corresponds to a pointer to a tuple with
- * the format of pg_am relation.
+ * Form_pg_am corresponds to a pointer to a tuple with
+ * the format of pg_am relation.
* ----------------
*/
-typedef FormData_pg_am *Form_pg_am;
+typedef FormData_pg_am *Form_pg_am;
/* ----------------
- * compiler constants for pg_am
+ * compiler constants for pg_am
* ----------------
*/
-#define Natts_pg_am 22
-#define Anum_pg_am_amname 1
-#define Anum_pg_am_amowner 2
-#define Anum_pg_am_amkind 3
-#define Anum_pg_am_amstrategies 4
-#define Anum_pg_am_amsupport 5
-#define Anum_pg_am_amgettuple 6
-#define Anum_pg_am_aminsert 7
-#define Anum_pg_am_amdelete 8
-#define Anum_pg_am_amgetattr 9
-#define Anum_pg_am_amsetlock 10
-#define Anum_pg_am_amsettid 11
-#define Anum_pg_am_amfreetuple 12
-#define Anum_pg_am_ambeginscan 13
-#define Anum_pg_am_amrescan 14
-#define Anum_pg_am_amendscan 15
-#define Anum_pg_am_ammarkpos 16
-#define Anum_pg_am_amrestrpos 17
-#define Anum_pg_am_amopen 18
-#define Anum_pg_am_amclose 19
-#define Anum_pg_am_ambuild 20
-#define Anum_pg_am_amcreate 21
-#define Anum_pg_am_amdestroy 22
+#define Natts_pg_am 22
+#define Anum_pg_am_amname 1
+#define Anum_pg_am_amowner 2
+#define Anum_pg_am_amkind 3
+#define Anum_pg_am_amstrategies 4
+#define Anum_pg_am_amsupport 5
+#define Anum_pg_am_amgettuple 6
+#define Anum_pg_am_aminsert 7
+#define Anum_pg_am_amdelete 8
+#define Anum_pg_am_amgetattr 9
+#define Anum_pg_am_amsetlock 10
+#define Anum_pg_am_amsettid 11
+#define Anum_pg_am_amfreetuple 12
+#define Anum_pg_am_ambeginscan 13
+#define Anum_pg_am_amrescan 14
+#define Anum_pg_am_amendscan 15
+#define Anum_pg_am_ammarkpos 16
+#define Anum_pg_am_amrestrpos 17
+#define Anum_pg_am_amopen 18
+#define Anum_pg_am_amclose 19
+#define Anum_pg_am_ambuild 20
+#define Anum_pg_am_amcreate 21
+#define Anum_pg_am_amdestroy 22
/* ----------------
- * initial contents of pg_am
+ * initial contents of pg_am
* ----------------
*/
@@ -109,7 +110,7 @@ BKI_BEGIN
BKI_END
DATA(insert OID = 404 ( nobtree PGUID "o" 5 1 nobtgettuple nobtinsert nobtdelete - - - - nobtbeginscan nobtrescan nobtendscan nobtmarkpos nobtrestrpos - - nobtbuild - - ));
BKI_BEGIN
-#endif /* NOBTREE */
+#endif /* NOBTREE */
BKI_END
-#endif /* PG_AM_H */
+#endif /* PG_AM_H */
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index 8385db08462..7e42e0f4f0f 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_amop.h--
- * definition of the system "amop" relation (pg_amop)
- * along with the relation's initial contents.
+ * definition of the system "amop" relation (pg_amop)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_amop.h,v 1.5 1997/09/04 18:43:57 thomas Exp $
+ * $Id: pg_amop.h,v 1.6 1997/09/07 04:56:37 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,53 +19,54 @@
#define PG_AMOP_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_amop definition. cpp turns this into
- * typedef struct FormData_pg_amop
+ * pg_amop definition. cpp turns this into
+ * typedef struct FormData_pg_amop
* ----------------
- */
-CATALOG(pg_amop) {
- Oid amopid;
- Oid amopclaid;
- Oid amopopr;
- int2 amopstrategy;
- regproc amopselect;
- regproc amopnpages;
+ */
+CATALOG(pg_amop)
+{
+ Oid amopid;
+ Oid amopclaid;
+ Oid amopopr;
+ int2 amopstrategy;
+ regproc amopselect;
+ regproc amopnpages;
} FormData_pg_amop;
/* ----------------
- * Form_pg_amop corresponds to a pointer to a tuple with
- * the format of pg_amop relation.
+ * Form_pg_amop corresponds to a pointer to a tuple with
+ * the format of pg_amop relation.
* ----------------
*/
-typedef FormData_pg_amop *Form_pg_amop;
+typedef FormData_pg_amop *Form_pg_amop;
/* ----------------
- * compiler constants for pg_amop
+ * compiler constants for pg_amop
* ----------------
*/
-/* #define Name_pg_amop "pg_amop" */
-#define Natts_pg_amop 6
-#define Anum_pg_amop_amopid 1
-#define Anum_pg_amop_amopclaid 2
-#define Anum_pg_amop_amopopr 3
-#define Anum_pg_amop_amopstrategy 4
-#define Anum_pg_amop_amopselect 5
-#define Anum_pg_amop_amopnpages 6
+/* #define Name_pg_amop "pg_amop" */
+#define Natts_pg_amop 6
+#define Anum_pg_amop_amopid 1
+#define Anum_pg_amop_amopclaid 2
+#define Anum_pg_amop_amopopr 3
+#define Anum_pg_amop_amopstrategy 4
+#define Anum_pg_amop_amopselect 5
+#define Anum_pg_amop_amopnpages 6
/* ----------------
- * initial contents of pg_amop
+ * initial contents of pg_amop
* ----------------
*/
/*
- * rtree box_ops
+ * rtree box_ops
*/
DATA(insert OID = 0 ( 402 422 493 1 rtsel rtnpage ));
@@ -78,7 +79,7 @@ DATA(insert OID = 0 ( 402 422 498 7 rtsel rtnpage ));
DATA(insert OID = 0 ( 402 422 497 8 rtsel rtnpage ));
/*
- * rtree bigbox_ops
+ * rtree bigbox_ops
*/
DATA(insert OID = 0 ( 402 433 493 1 rtsel rtnpage ));
@@ -91,7 +92,7 @@ DATA(insert OID = 0 ( 402 433 498 7 rtsel rtnpage ));
DATA(insert OID = 0 ( 402 433 497 8 rtsel rtnpage ));
/*
- * rtree poly_ops (supports polygons)
+ * rtree poly_ops (supports polygons)
*/
DATA(insert OID = 0 ( 402 434 485 1 rtsel rtnpage ));
@@ -104,7 +105,7 @@ DATA(insert OID = 0 ( 402 434 491 7 rtsel rtnpage ));
DATA(insert OID = 0 ( 402 434 492 8 rtsel rtnpage ));
/*
- * rtree circle_ops (supports circles)
+ * rtree circle_ops (supports circles)
*/
DATA(insert OID = 0 ( 402 714 1506 1 rtsel rtnpage ));
@@ -117,17 +118,17 @@ DATA(insert OID = 0 ( 402 714 1512 7 rtsel rtnpage ));
DATA(insert OID = 0 ( 402 714 1513 8 rtsel rtnpage ));
/*
- * nbtree int2_ops
+ * nbtree int2_ops
*/
-DATA(insert OID = 0 ( 403 421 95 1 btreesel btreenpage ));
+DATA(insert OID = 0 ( 403 421 95 1 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 421 522 2 btreesel btreenpage ));
-DATA(insert OID = 0 ( 403 421 94 3 btreesel btreenpage ));
+DATA(insert OID = 0 ( 403 421 94 3 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 421 524 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 421 520 5 btreesel btreenpage ));
/*
- * nbtree float8_ops
+ * nbtree float8_ops
*/
DATA(insert OID = 0 ( 403 423 672 1 btreesel btreenpage ));
@@ -137,7 +138,7 @@ DATA(insert OID = 0 ( 403 423 675 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 423 674 5 btreesel btreenpage ));
/*
- * nbtree int24_ops
+ * nbtree int24_ops
*/
DATA(insert OID = 0 ( 403 424 534 1 btreesel btreenpage ));
@@ -147,7 +148,7 @@ DATA(insert OID = 0 ( 403 424 542 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 424 536 5 btreesel btreenpage ));
/*
- * nbtree int42_ops
+ * nbtree int42_ops
*/
DATA(insert OID = 0 ( 403 425 535 1 btreesel btreenpage ));
@@ -157,17 +158,17 @@ DATA(insert OID = 0 ( 403 425 543 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 425 537 5 btreesel btreenpage ));
/*
- * nbtree int4_ops
+ * nbtree int4_ops
*/
-DATA(insert OID = 0 ( 403 426 97 1 btreesel btreenpage ));
+DATA(insert OID = 0 ( 403 426 97 1 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 426 523 2 btreesel btreenpage ));
-DATA(insert OID = 0 ( 403 426 96 3 btreesel btreenpage ));
+DATA(insert OID = 0 ( 403 426 96 3 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 426 525 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 426 521 5 btreesel btreenpage ));
/*
- * nbtree oid_ops
+ * nbtree oid_ops
*/
DATA(insert OID = 0 ( 403 427 609 1 btreesel btreenpage ));
@@ -177,7 +178,7 @@ DATA(insert OID = 0 ( 403 427 612 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 427 610 5 btreesel btreenpage ));
/*
- * nbtree float4_ops
+ * nbtree float4_ops
*/
DATA(insert OID = 0 ( 403 428 622 1 btreesel btreenpage ));
@@ -187,7 +188,7 @@ DATA(insert OID = 0 ( 403 428 625 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 428 623 5 btreesel btreenpage ));
/*
- * nbtree char_ops
+ * nbtree char_ops
*/
DATA(insert OID = 0 ( 403 429 631 1 btreesel btreenpage ));
@@ -197,7 +198,7 @@ DATA(insert OID = 0 ( 403 429 634 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 429 633 5 btreesel btreenpage ));
/*
- * nbtree char2_ops
+ * nbtree char2_ops
*/
DATA(insert OID = 0 ( 403 406 418 1 btreesel btreenpage ));
@@ -207,7 +208,7 @@ DATA(insert OID = 0 ( 403 406 463 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 406 460 5 btreesel btreenpage ));
/*
- * nbtree char4_ops
+ * nbtree char4_ops
*/
DATA(insert OID = 0 ( 403 407 419 1 btreesel btreenpage ));
@@ -217,7 +218,7 @@ DATA(insert OID = 0 ( 403 407 464 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 407 461 5 btreesel btreenpage ));
/*
- * nbtree char8_ops
+ * nbtree char8_ops
*/
DATA(insert OID = 0 ( 403 408 420 1 btreesel btreenpage ));
@@ -227,7 +228,7 @@ DATA(insert OID = 0 ( 403 408 465 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 408 462 5 btreesel btreenpage ));
/*
- * nbtree name_ops
+ * nbtree name_ops
*/
DATA(insert OID = 0 ( 403 1181 660 1 btreesel btreenpage ));
@@ -237,7 +238,7 @@ DATA(insert OID = 0 ( 403 1181 663 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 1181 662 5 btreesel btreenpage ));
/*
- * nbtree char16_ops
+ * nbtree char16_ops
*/
DATA(insert OID = 0 ( 403 430 645 1 btreesel btreenpage ));
@@ -247,7 +248,7 @@ DATA(insert OID = 0 ( 403 430 648 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 430 647 5 btreesel btreenpage ));
/*
- * nbtree text_ops
+ * nbtree text_ops
*/
DATA(insert OID = 0 ( 403 431 664 1 btreesel btreenpage ));
@@ -257,7 +258,7 @@ DATA(insert OID = 0 ( 403 431 667 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 431 666 5 btreesel btreenpage ));
/*
- * nbtree abstime_ops
+ * nbtree abstime_ops
*/
DATA(insert OID = 0 ( 403 432 562 1 btreesel btreenpage ));
@@ -267,7 +268,7 @@ DATA(insert OID = 0 ( 403 432 565 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 432 563 5 btreesel btreenpage ));
/*
- * nbtree oidint4_ops
+ * nbtree oidint4_ops
*/
DATA(insert OID = 0 ( 403 435 930 1 btreesel btreenpage ));
@@ -277,7 +278,7 @@ DATA(insert OID = 0 ( 403 435 933 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 435 934 5 btreesel btreenpage ));
/*
- * nbtree oidint2_ops
+ * nbtree oidint2_ops
*/
DATA(insert OID = 0 ( 403 437 830 1 btreesel btreenpage ));
@@ -287,7 +288,7 @@ DATA(insert OID = 0 ( 403 437 833 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 437 834 5 btreesel btreenpage ));
/*
- * nbtree oidname_ops
+ * nbtree oidname_ops
*/
DATA(insert OID = 0 ( 403 436 676 1 btreesel btreenpage ));
@@ -297,7 +298,7 @@ DATA(insert OID = 0 ( 403 436 679 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 436 680 5 btreesel btreenpage ));
/*
- * nbtree bpchar_ops
+ * nbtree bpchar_ops
*/
DATA(insert OID = 0 ( 403 1076 1058 1 btreesel btreenpage ));
@@ -307,7 +308,7 @@ DATA(insert OID = 0 ( 403 1076 1061 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 1076 1060 5 btreesel btreenpage ));
/*
- * nbtree varchar_ops
+ * nbtree varchar_ops
*/
DATA(insert OID = 0 ( 403 1077 1066 1 btreesel btreenpage ));
@@ -317,7 +318,7 @@ DATA(insert OID = 0 ( 403 1077 1069 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 1077 1068 5 btreesel btreenpage ));
/*
- * nbtree date_ops
+ * nbtree date_ops
*/
DATA(insert OID = 0 ( 403 1114 1095 1 btreesel btreenpage ));
@@ -328,7 +329,7 @@ DATA(insert OID = 0 ( 403 1114 1097 5 btreesel btreenpage ));
/*
- * nbtree time_ops
+ * nbtree time_ops
*/
DATA(insert OID = 0 ( 403 1115 1110 1 btreesel btreenpage ));
@@ -338,7 +339,7 @@ DATA(insert OID = 0 ( 403 1115 1113 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 1115 1112 5 btreesel btreenpage ));
/*
- * nbtree datetime_ops
+ * nbtree datetime_ops
*/
DATA(insert OID = 0 ( 403 1312 1322 1 btreesel btreenpage ));
@@ -348,7 +349,7 @@ DATA(insert OID = 0 ( 403 1312 1325 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 403 1312 1324 5 btreesel btreenpage ));
/*
- * nbtree timespan_ops
+ * nbtree timespan_ops
*/
DATA(insert OID = 0 ( 403 1313 1332 1 btreesel btreenpage ));
@@ -361,17 +362,17 @@ BKI_BEGIN
#ifdef NOBTREE
BKI_END
/*
- * nobtree int2_ops
+ * nobtree int2_ops
*/
-DATA(insert OID = 0 ( 404 421 95 1 btreesel btreenpage ));
+DATA(insert OID = 0 ( 404 421 95 1 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 421 522 2 btreesel btreenpage ));
-DATA(insert OID = 0 ( 404 421 94 3 btreesel btreenpage ));
+DATA(insert OID = 0 ( 404 421 94 3 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 421 524 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 421 520 5 btreesel btreenpage ));
/*
- * nobtree float8_ops
+ * nobtree float8_ops
*/
DATA(insert OID = 0 ( 404 423 672 1 btreesel btreenpage ));
@@ -381,7 +382,7 @@ DATA(insert OID = 0 ( 404 423 675 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 423 674 5 btreesel btreenpage ));
/*
- * nobtree int24_ops
+ * nobtree int24_ops
*/
DATA(insert OID = 0 ( 404 424 534 1 btreesel btreenpage ));
@@ -391,7 +392,7 @@ DATA(insert OID = 0 ( 404 424 542 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 424 536 5 btreesel btreenpage ));
/*
- * nobtree int42_ops
+ * nobtree int42_ops
*/
DATA(insert OID = 0 ( 404 425 535 1 btreesel btreenpage ));
@@ -401,17 +402,17 @@ DATA(insert OID = 0 ( 404 425 543 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 425 537 5 btreesel btreenpage ));
/*
- * nobtree int4_ops
+ * nobtree int4_ops
*/
-DATA(insert OID = 0 ( 404 426 97 1 btreesel btreenpage ));
+DATA(insert OID = 0 ( 404 426 97 1 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 426 523 2 btreesel btreenpage ));
-DATA(insert OID = 0 ( 404 426 96 3 btreesel btreenpage ));
+DATA(insert OID = 0 ( 404 426 96 3 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 426 525 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 426 521 5 btreesel btreenpage ));
/*
- * nobtree oid_ops
+ * nobtree oid_ops
*/
DATA(insert OID = 0 ( 404 427 609 1 btreesel btreenpage ));
@@ -421,7 +422,7 @@ DATA(insert OID = 0 ( 404 427 612 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 427 610 5 btreesel btreenpage ));
/*
- * nobtree float4_ops
+ * nobtree float4_ops
*/
DATA(insert OID = 0 ( 404 428 622 1 btreesel btreenpage ));
@@ -431,7 +432,7 @@ DATA(insert OID = 0 ( 404 428 625 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 428 623 5 btreesel btreenpage ));
/*
- * nobtree char_ops
+ * nobtree char_ops
*/
DATA(insert OID = 0 ( 404 429 631 1 btreesel btreenpage ));
@@ -441,7 +442,7 @@ DATA(insert OID = 0 ( 404 429 634 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 429 633 5 btreesel btreenpage ));
/*
- * nobtree char2_ops
+ * nobtree char2_ops
*/
DATA(insert OID = 0 ( 404 406 418 1 btreesel btreenpage ));
@@ -451,7 +452,7 @@ DATA(insert OID = 0 ( 404 406 463 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 406 460 5 btreesel btreenpage ));
/*
- * nobtree char4_ops
+ * nobtree char4_ops
*/
DATA(insert OID = 0 ( 404 407 419 1 btreesel btreenpage ));
@@ -461,7 +462,7 @@ DATA(insert OID = 0 ( 404 407 464 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 407 461 5 btreesel btreenpage ));
/*
- * nobtree char8_ops
+ * nobtree char8_ops
*/
DATA(insert OID = 0 ( 404 408 420 1 btreesel btreenpage ));
@@ -471,7 +472,7 @@ DATA(insert OID = 0 ( 404 408 465 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 408 462 5 btreesel btreenpage ));
/*
- * nobtree char16_ops
+ * nobtree char16_ops
*/
DATA(insert OID = 0 ( 404 430 645 1 btreesel btreenpage ));
@@ -481,7 +482,7 @@ DATA(insert OID = 0 ( 404 430 648 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 430 647 5 btreesel btreenpage ));
/*
- * nobtree name_ops
+ * nobtree name_ops
*/
DATA(insert OID = 0 ( 404 1181 660 1 btreesel btreenpage ));
@@ -491,7 +492,7 @@ DATA(insert OID = 0 ( 404 1181 663 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 1181 662 5 btreesel btreenpage ));
/*
- * nobtree text_ops
+ * nobtree text_ops
*/
DATA(insert OID = 0 ( 404 431 664 1 btreesel btreenpage ));
@@ -501,7 +502,7 @@ DATA(insert OID = 0 ( 404 431 667 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 431 666 5 btreesel btreenpage ));
/*
- * nobtree abstime_ops
+ * nobtree abstime_ops
*/
DATA(insert OID = 0 ( 404 432 562 1 btreesel btreenpage ));
@@ -511,7 +512,7 @@ DATA(insert OID = 0 ( 404 432 565 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 432 563 5 btreesel btreenpage ));
/*
- * nobtree datetime_ops
+ * nobtree datetime_ops
*/
DATA(insert OID = 0 ( 404 1312 1322 1 btreesel btreenpage ));
@@ -521,7 +522,7 @@ DATA(insert OID = 0 ( 404 1312 1325 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 1312 1324 5 btreesel btreenpage ));
/*
- * nobtree timespan_ops
+ * nobtree timespan_ops
*/
DATA(insert OID = 0 ( 404 1313 1332 1 btreesel btreenpage ));
@@ -531,48 +532,48 @@ DATA(insert OID = 0 ( 404 1313 1335 4 btreesel btreenpage ));
DATA(insert OID = 0 ( 404 1313 1334 5 btreesel btreenpage ));
BKI_BEGIN
-#endif /* NOBTREE */
+#endif /* NOBTREE */
BKI_END
/*
- * hash table _ops
+ * hash table _ops
*/
-/* hash table int2_ops */
-DATA(insert OID = 0 ( 405 421 94 1 btreesel btreenpage ));
-/* hash table float8_ops */
+/* hash table int2_ops */
+DATA(insert OID = 0 ( 405 421 94 1 btreesel btreenpage ));
+/* hash table float8_ops */
DATA(insert OID = 0 ( 405 423 670 1 btreesel btreenpage ));
-/* hash table int4_ops */
-DATA(insert OID = 0 ( 405 426 96 1 hashsel hashnpage ));
-/* hash table oid_ops */
+/* hash table int4_ops */
+DATA(insert OID = 0 ( 405 426 96 1 hashsel hashnpage ));
+/* hash table oid_ops */
DATA(insert OID = 0 ( 405 427 607 1 hashsel hashnpage ));
-/* hash table float4_ops */
+/* hash table float4_ops */
DATA(insert OID = 0 ( 405 428 620 1 hashsel hashnpage ));
-/* hash table char_ops */
+/* hash table char_ops */
DATA(insert OID = 0 ( 405 429 92 1 hashsel hashnpage ));
-/* hash table char2_ops */
+/* hash table char2_ops */
DATA(insert OID = 0 ( 405 406 412 1 hashsel hashnpage ));
-/* hash table char4_ops */
+/* hash table char4_ops */
DATA(insert OID = 0 ( 405 407 413 1 hashsel hashnpage ));
-/* hash table char8_ops */
+/* hash table char8_ops */
DATA(insert OID = 0 ( 405 408 414 1 hashsel hashnpage ));
-/* hash table char16_ops */
+/* hash table char16_ops */
DATA(insert OID = 0 ( 405 430 1267 1 hashsel hashnpage ));
-/* hash table name_ops */
+/* hash table name_ops */
DATA(insert OID = 0 ( 405 1181 93 1 hashsel hashnpage ));
-/* hash table text_ops */
+/* hash table text_ops */
DATA(insert OID = 0 ( 405 431 98 1 hashsel hashnpage ));
-/* hash table bpchar_ops */
+/* hash table bpchar_ops */
DATA(insert OID = 0 ( 405 1076 1054 1 hashsel hashnpage ));
-/* hash table varchar_ops */
+/* hash table varchar_ops */
DATA(insert OID = 0 ( 405 1077 1062 1 hashsel hashnpage ));
-/* hash table date_ops */
+/* hash table date_ops */
DATA(insert OID = 0 ( 405 1114 1093 1 hashsel hashnpage ));
-/* hash table time_ops */
+/* hash table time_ops */
DATA(insert OID = 0 ( 405 1115 1108 1 hashsel hashnpage ));
-/* hash table datetime_ops */
+/* hash table datetime_ops */
DATA(insert OID = 0 ( 405 1312 1320 1 hashsel hashnpage ));
-/* hash table timespan_ops */
+/* hash table timespan_ops */
DATA(insert OID = 0 ( 405 1313 1330 1 hashsel hashnpage ));
-#endif /* PG_AMOP_H */
+#endif /* PG_AMOP_H */
diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h
index e1353fbcd5d..e9aca5c73e7 100644
--- a/src/include/catalog/pg_amproc.h
+++ b/src/include/catalog/pg_amproc.h
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* pg_amproc.h--
- * definition of the system "amproc" relation (pg_amproce)
- * along with the relation's initial contents. The amproc
- * catalog is used to store procedures used by indexed access
- * methods that aren't associated with operators.
+ * definition of the system "amproc" relation (pg_amproce)
+ * along with the relation's initial contents. The amproc
+ * catalog is used to store procedures used by indexed access
+ * methods that aren't associated with operators.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_amproc.h,v 1.4 1997/09/04 18:43:57 thomas Exp $
+ * $Id: pg_amproc.h,v 1.5 1997/09/07 04:56:39 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -21,43 +21,44 @@
#define PG_AMPROC_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_amproc definition. cpp turns this into
- * typedef struct FormData_pg_amproc
+ * pg_amproc definition. cpp turns this into
+ * typedef struct FormData_pg_amproc
* ----------------
- */
-CATALOG(pg_amproc) {
- Oid amid;
- Oid amopclaid;
- Oid amproc;
- int2 amprocnum;
+ */
+CATALOG(pg_amproc)
+{
+ Oid amid;
+ Oid amopclaid;
+ Oid amproc;
+ int2 amprocnum;
} FormData_pg_amproc;
/* ----------------
- * Form_pg_amproc corresponds to a pointer to a tuple with
- * the format of pg_amproc relation.
+ * Form_pg_amproc corresponds to a pointer to a tuple with
+ * the format of pg_amproc relation.
* ----------------
*/
-typedef FormData_pg_amproc *Form_pg_amproc;
+typedef FormData_pg_amproc *Form_pg_amproc;
/* ----------------
- * compiler constants for pg_amproc
+ * compiler constants for pg_amproc
* ----------------
*/
-#define Natts_pg_amproc 4
-#define Anum_pg_amproc_amid 1
-#define Anum_pg_amproc_amopclaid 2
-#define Anum_pg_amproc_amproc 3
-#define Anum_pg_amproc_amprocnum 4
+#define Natts_pg_amproc 4
+#define Anum_pg_amproc_amid 1
+#define Anum_pg_amproc_amopclaid 2
+#define Anum_pg_amproc_amproc 3
+#define Anum_pg_amproc_amprocnum 4
/* ----------------
- * initial contents of pg_amproc
+ * initial contents of pg_amproc
* ----------------
*/
@@ -114,7 +115,7 @@ DATA(insert OID = 0 (404 430 1274 1));
DATA(insert OID = 0 (404 431 360 1));
DATA(insert OID = 0 (404 432 357 1));
BKI_BEGIN
-#endif /* NOBTREE */
+#endif /* NOBTREE */
BKI_END
DATA(insert OID = 0 (405 421 449 1));
@@ -134,4 +135,4 @@ DATA(insert OID = 0 (405 1077 1081 1));
DATA(insert OID = 0 (405 1114 450 1));
DATA(insert OID = 0 (405 1115 694 1));
-#endif /* PG_AMPROC_H */
+#endif /* PG_AMPROC_H */
diff --git a/src/include/catalog/pg_attrdef.h b/src/include/catalog/pg_attrdef.h
index 2c42788fa46..9fc546f05b2 100644
--- a/src/include/catalog/pg_attrdef.h
+++ b/src/include/catalog/pg_attrdef.h
@@ -6,8 +6,8 @@
* Copyright (c) 1994, Regents of the University of California
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -15,40 +15,41 @@
#define PG_ATTRDEF_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_attrdef definition. cpp turns this into
- * typedef struct FormData_pg_attrdef
+ * pg_attrdef definition. cpp turns this into
+ * typedef struct FormData_pg_attrdef
* ----------------
- */
-CATALOG(pg_attrdef) BOOTSTRAP {
- Oid adrelid;
- int2 adnum;
- text adbin;
- text adsrc;
+ */
+CATALOG(pg_attrdef) BOOTSTRAP
+{
+ Oid adrelid;
+ int2 adnum;
+ text adbin;
+ text adsrc;
} FormData_pg_attrdef;
/* ----------------
- * Form_pg_attrdef corresponds to a pointer to a tuple with
- * the format of pg_attrdef relation.
+ * Form_pg_attrdef corresponds to a pointer to a tuple with
+ * the format of pg_attrdef relation.
* ----------------
*/
-typedef FormData_pg_attrdef *Form_pg_attrdef;
+typedef FormData_pg_attrdef *Form_pg_attrdef;
/* ----------------
- * compiler constants for pg_attrdef
+ * compiler constants for pg_attrdef
* ----------------
*/
-#define Natts_pg_attrdef 4
-#define Anum_pg_attrdef_adrelid 1
-#define Anum_pg_attrdef_adnum 2
-#define Anum_pg_attrdef_adbin 3
-#define Anum_pg_attrdef_adsrc 4
+#define Natts_pg_attrdef 4
+#define Anum_pg_attrdef_adrelid 1
+#define Anum_pg_attrdef_adnum 2
+#define Anum_pg_attrdef_adbin 3
+#define Anum_pg_attrdef_adsrc 4
-#endif /* PG_ATTRDEF_H */
+#endif /* PG_ATTRDEF_H */
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index da07ebcacbe..5150463c324 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -1,97 +1,110 @@
/*-------------------------------------------------------------------------
*
* pg_attribute.h--
- * definition of the system "attribute" relation (pg_attribute)
- * along with the relation's initial contents.
+ * definition of the system "attribute" relation (pg_attribute)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_attribute.h,v 1.14 1997/09/04 13:25:08 vadim Exp $
+ * $Id: pg_attribute.h,v 1.15 1997/09/07 04:56:41 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
- * utils/cache/relcache.c requires some hard-coded tuple descriptors
- * for some of the system catalogs so if the schema for any of
- * these changes, be sure and change the appropriate Schema_xxx
- * macros! -cim 2/5/91
+ * utils/cache/relcache.c requires some hard-coded tuple descriptors
+ * for some of the system catalogs so if the schema for any of
+ * these changes, be sure and change the appropriate Schema_xxx
+ * macros! -cim 2/5/91
*
*-------------------------------------------------------------------------
*/
#ifndef PG_ATTRIBUTE_H
#define PG_ATTRIBUTE_H
-
+
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_attribute definition. cpp turns this into
- * typedef struct FormData_pg_attribute
+ * pg_attribute definition. cpp turns this into
+ * typedef struct FormData_pg_attribute
*
- * If you change the following, make sure you change the structs for
- * system attributes in heap.c and index.c also.
+ * If you change the following, make sure you change the structs for
+ * system attributes in heap.c and index.c also.
* ----------------
*/
-CATALOG(pg_attribute) BOOTSTRAP {
- Oid attrelid;
- NameData attname;
- Oid atttypid;
- /* atttypid is the OID of the instance in Catalog Class pg_type that
- defines the data type of this attribute (e.g. int4). Information in
- that instance is redundant with the attlen, attbyval, and attalign
- attributes of this instance, so they had better match or Postgres
- will fail.
- */
- float4 attdisbursion;
- int2 attlen;
- /* attlen is a copy of the typlen field from pg_type for this
- attribute. See atttypid above. See struct TypeTupleFormData for
- definition.
- */
- int2 attnum;
- /* attnum is the "attribute number" for the attribute: A
- value that uniquely identifies this attribute within its class.
- For user attributes, Attribute numbers are greater than 0 and
- not greater than the number of attributes in the class.
- I.e. if the Class pg_class says that Class XYZ has 10
- attributes, then the user attribute numbers in Class
- pg_attribute must be 1-10.
-
- System attributes have attribute numbers less than 0 that are
- unique within the class, but not constrained to any particular range.
-
- Note that (attnum - 1) is often used as the index to an array.
- */
- int4 attnelems;
- int4 attcacheoff;
- /* fastgetattr() uses attcacheoff to cache byte offsets of
- attributes in heap tuples. The data actually stored in
- pg_attribute (-1) indicates no cached value. But when we
- copy these tuples into a tuple descriptor, we may then update
- attcacheoff in the copies. This speeds up the attribute
- walking process.
- */
- bool attbyval;
- /* attbyval is a copy of the typbyval field from pg_type for this
- attribute. See atttypid above. See struct TypeTupleFormData for
- definition.
- */
- bool attisset;
- char attalign;
- /* attalign is a copy of the typalign field from pg_type for this
- attribute. See atttypid above. See struct TypeTupleFormData for
- definition.
- */
- bool attnotnull;
- /* This flag represents the "NOT NULL" constraint */
- bool atthasdef;
- /* Has DEFAULT value or not */
+CATALOG(pg_attribute) BOOTSTRAP
+{
+ Oid attrelid;
+ NameData attname;
+ Oid atttypid;
+
+ /*
+ * atttypid is the OID of the instance in Catalog Class pg_type that
+ * defines the data type of this attribute (e.g. int4). Information
+ * in that instance is redundant with the attlen, attbyval, and
+ * attalign attributes of this instance, so they had better match or
+ * Postgres will fail.
+ */
+ float4 attdisbursion;
+ int2 attlen;
+
+ /*
+ * attlen is a copy of the typlen field from pg_type for this
+ * attribute. See atttypid above. See struct TypeTupleFormData for
+ * definition.
+ */
+ int2 attnum;
+
+ /*
+ * attnum is the "attribute number" for the attribute: A value that
+ * uniquely identifies this attribute within its class. For user
+ * attributes, Attribute numbers are greater than 0 and not greater
+ * than the number of attributes in the class. I.e. if the Class
+ * pg_class says that Class XYZ has 10 attributes, then the user
+ * attribute numbers in Class pg_attribute must be 1-10.
+ *
+ * System attributes have attribute numbers less than 0 that are unique
+ * within the class, but not constrained to any particular range.
+ *
+ * Note that (attnum - 1) is often used as the index to an array.
+ */
+ int4 attnelems;
+ int4 attcacheoff;
+
+ /*
+ * fastgetattr() uses attcacheoff to cache byte offsets of attributes
+ * in heap tuples. The data actually stored in pg_attribute (-1)
+ * indicates no cached value. But when we copy these tuples into a
+ * tuple descriptor, we may then update attcacheoff in the copies.
+ * This speeds up the attribute walking process.
+ */
+ bool attbyval;
+
+ /*
+ * attbyval is a copy of the typbyval field from pg_type for this
+ * attribute. See atttypid above. See struct TypeTupleFormData for
+ * definition.
+ */
+ bool attisset;
+ char attalign;
+
+ /*
+ * attalign is a copy of the typalign field from pg_type for this
+ * attribute. See atttypid above. See struct TypeTupleFormData for
+ * definition.
+ */
+ bool attnotnull;
+
+ /* This flag represents the "NOT NULL" constraint */
+ bool atthasdef;
+
+ /* Has DEFAULT value or not */
} FormData_pg_attribute;
/*
@@ -99,499 +112,499 @@ CATALOG(pg_attribute) BOOTSTRAP {
* the size of the C struct is not the same as the size of the tuple.)
*/
#define ATTRIBUTE_TUPLE_SIZE \
- (offsetof(FormData_pg_attribute,atthasdef) + sizeof(char))
+ (offsetof(FormData_pg_attribute,atthasdef) + sizeof(char))
/* ----------------
- * Form_pg_attribute corresponds to a pointer to a tuple with
- * the format of pg_attribute relation.
+ * Form_pg_attribute corresponds to a pointer to a tuple with
+ * the format of pg_attribute relation.
* ----------------
*/
-typedef FormData_pg_attribute *AttributeTupleForm;
+typedef FormData_pg_attribute *AttributeTupleForm;
/* ----------------
- * compiler constants for pg_attribute
+ * compiler constants for pg_attribute
* ----------------
*/
-#define Natts_pg_attribute 13
-#define Anum_pg_attribute_attrelid 1
-#define Anum_pg_attribute_attname 2
-#define Anum_pg_attribute_atttypid 3
+#define Natts_pg_attribute 13
+#define Anum_pg_attribute_attrelid 1
+#define Anum_pg_attribute_attname 2
+#define Anum_pg_attribute_atttypid 3
-#define Anum_pg_attribute_attdisbursion 4
+#define Anum_pg_attribute_attdisbursion 4
-#define Anum_pg_attribute_attlen 5
-#define Anum_pg_attribute_attnum 6
+#define Anum_pg_attribute_attlen 5
+#define Anum_pg_attribute_attnum 6
-#define Anum_pg_attribute_attnelems 7
+#define Anum_pg_attribute_attnelems 7
#define Anum_pg_attribute_attcacheoff 8
-#define Anum_pg_attribute_attbyval 9
-#define Anum_pg_attribute_attisset 10
-#define Anum_pg_attribute_attalign 11
-#define Anum_pg_attribute_attnotnull 12
-#define Anum_pg_attribute_atthasdef 13
+#define Anum_pg_attribute_attbyval 9
+#define Anum_pg_attribute_attisset 10
+#define Anum_pg_attribute_attalign 11
+#define Anum_pg_attribute_attnotnull 12
+#define Anum_pg_attribute_atthasdef 13
/* ----------------
- * SCHEMA_ macros for declaring hardcoded tuple descriptors.
- * these are used in utils/cache/relcache.c
+ * SCHEMA_ macros for declaring hardcoded tuple descriptors.
+ * these are used in utils/cache/relcache.c
* ----------------
#define SCHEMA_NAME(x) CppConcat(Name_,x)
#define SCHEMA_DESC(x) CppConcat(Desc_,x)
#define SCHEMA_NATTS(x) CppConcat(Natts_,x)
#define SCHEMA_DEF(x) \
- FormData_pg_attribute \
- SCHEMA_DESC(x) [ SCHEMA_NATTS(x) ] = \
- { \
- CppConcat(Schema_,x) \
- }
+ FormData_pg_attribute \
+ SCHEMA_DESC(x) [ SCHEMA_NATTS(x) ] = \
+ { \
+ CppConcat(Schema_,x) \
+ }
*/
/* ----------------
- * initial contents of pg_attribute
+ * initial contents of pg_attribute
* ----------------
*/
/* ----------------
- * pg_type schema
+ * pg_type schema
* ----------------
*/
#define Schema_pg_type \
-{ 1247l, {"typname"}, 19l, 0l, NAMEDATALEN, 1, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
-{ 1247l, {"typowner"}, 26l, 0l, 4, 2, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1247l, {"typlen"}, 21l, 0l, 2, 3, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
+{ 1247l, {"typname"}, 19l, 0l, NAMEDATALEN, 1, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
+{ 1247l, {"typowner"}, 26l, 0l, 4, 2, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1247l, {"typlen"}, 21l, 0l, 2, 3, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
{ 1247l, {"typprtlen"}, 21l, 0l, 2, 4, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
-{ 1247l, {"typbyval"}, 16l, 0l, 1, 5, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1247l, {"typtype"}, 18l, 0l, 1, 6, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1247l, {"typbyval"}, 16l, 0l, 1, 5, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1247l, {"typtype"}, 18l, 0l, 1, 6, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
{ 1247l, {"typisdefined"}, 16l, 0l, 1, 7, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1247l, {"typdelim"}, 18l, 0l, 1, 8, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1247l, {"typrelid"}, 26l, 0l, 4, 9, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1247l, {"typelem"}, 26l, 0l, 4, 10, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1247l, {"typinput"}, 24l, 0l, 4, 11, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1247l, {"typdelim"}, 18l, 0l, 1, 8, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1247l, {"typrelid"}, 26l, 0l, 4, 9, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1247l, {"typelem"}, 26l, 0l, 4, 10, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1247l, {"typinput"}, 24l, 0l, 4, 11, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
{ 1247l, {"typoutput"}, 24l, 0l, 4, 12, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
{ 1247l, {"typreceive"}, 24l, 0l, 4, 13, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1247l, {"typsend"}, 24l, 0l, 4, 14, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1247l, {"typalign"}, 18l, 0l, 1, 15, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1247l, {"typsend"}, 24l, 0l, 4, 14, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1247l, {"typalign"}, 18l, 0l, 1, 15, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
{ 1247l, {"typdefault"}, 25l, 0l, -1, 16, 0l, -1l, '\0' , '\0', 'i', '\0', '\0' }
-DATA(insert OID = 0 ( 1247 typname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1247 typowner 26 0 4 2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1247 typlen 21 0 2 3 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1247 typprtlen 21 0 2 4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1247 typbyval 16 0 1 5 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1247 typtype 18 0 1 6 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1247 typisdefined 16 0 1 7 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1247 typdelim 18 0 1 8 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1247 typrelid 26 0 4 9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1247 typelem 26 0 4 10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1247 typinput 24 0 4 11 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1247 typoutput 24 0 4 12 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1247 typreceive 24 0 4 13 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1247 typsend 24 0 4 14 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1247 typalign 18 0 1 15 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1247 typdefault 25 0 -1 16 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1247 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1247 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1247 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1247 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1247 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1247 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1247 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1247 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1247 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1247 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1247 vtype 18 0 1 -11 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1247 typname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1247 typowner 26 0 4 2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1247 typlen 21 0 2 3 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1247 typprtlen 21 0 2 4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1247 typbyval 16 0 1 5 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1247 typtype 18 0 1 6 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1247 typisdefined 16 0 1 7 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1247 typdelim 18 0 1 8 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1247 typrelid 26 0 4 9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1247 typelem 26 0 4 10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1247 typinput 24 0 4 11 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1247 typoutput 24 0 4 12 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1247 typreceive 24 0 4 13 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1247 typsend 24 0 4 14 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1247 typalign 18 0 1 15 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1247 typdefault 25 0 -1 16 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1247 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1247 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1247 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1247 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1247 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1247 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1247 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1247 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1247 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1247 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1247 vtype 18 0 1 -11 0 -1 t f c f f));
/* ----------------
- * pg_database
+ * pg_database
* ----------------
*/
-DATA(insert OID = 0 ( 1262 datname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1262 datdba 23 0 4 2 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1262 datpath 25 0 -1 3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1262 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1262 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1262 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1262 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1262 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1262 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1262 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1262 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1262 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1262 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1262 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1262 datname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1262 datdba 23 0 4 2 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1262 datpath 25 0 -1 3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1262 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1262 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1262 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1262 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1262 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1262 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1262 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1262 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1262 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1262 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1262 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_demon
+ * pg_demon
* ----------------
*/
-DATA(insert OID = 0 ( 1251 demserid 26 0 4 1 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1251 demname 19 0 NAMEDATALEN 2 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1251 demowner 26 0 4 3 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1251 demcode 24 0 4 4 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1251 ctid 27 0 6 -1 0 -1 f f i f f));
-
-DATA(insert OID = 0 ( 1251 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1251 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1251 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1251 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1251 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1251 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1251 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1251 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1251 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1251 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1251 demserid 26 0 4 1 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1251 demname 19 0 NAMEDATALEN 2 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1251 demowner 26 0 4 3 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1251 demcode 24 0 4 4 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1251 ctid 27 0 6 -1 0 -1 f f i f f));
+
+DATA(insert OID = 0 ( 1251 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1251 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1251 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1251 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1251 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1251 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1251 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1251 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1251 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1251 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_proc
+ * pg_proc
* ----------------
*/
#define Schema_pg_proc \
-{ 1255l, {"proname"}, 19l, 0l, NAMEDATALEN, 1, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
-{ 1255l, {"proowner"}, 26l, 0l, 4, 2, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1255l, {"prolang"}, 26l, 0l, 4, 3, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1255l, {"proisinh"}, 16l, 0l, 1, 4, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1255l, {"proistrusted"}, 16l, 0l, 1, 5, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1255l, {"proname"}, 19l, 0l, NAMEDATALEN, 1, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
+{ 1255l, {"proowner"}, 26l, 0l, 4, 2, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1255l, {"prolang"}, 26l, 0l, 4, 3, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1255l, {"proisinh"}, 16l, 0l, 1, 4, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1255l, {"proistrusted"}, 16l, 0l, 1, 5, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
{ 1255l, {"proiscachable"}, 16l, 0l, 1, 6, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1255l, {"pronargs"}, 21l, 0l, 2, 7, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
-{ 1255l, {"proretset"}, 16l, 0l, 1, 8, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1255l, {"prorettype"}, 26l, 0l, 4, 9, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1255l, {"proargtypes"}, 30l, 0l, 32, 10, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
-{ 1255l, {"probyte_pct"}, 23l, 0l, 4, 11, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1255l, {"pronargs"}, 21l, 0l, 2, 7, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
+{ 1255l, {"proretset"}, 16l, 0l, 1, 8, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1255l, {"prorettype"}, 26l, 0l, 4, 9, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1255l, {"proargtypes"}, 30l, 0l, 32, 10, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
+{ 1255l, {"probyte_pct"}, 23l, 0l, 4, 11, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
{ 1255l, {"properbyte_cpu"}, 23l, 0l, 4, 12, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
{ 1255l, {"propercall_cpu"}, 23l, 0l, 4, 13, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
{ 1255l, {"prooutin_ratio"}, 23l, 0l, 4, 14, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1255l, {"prosrc"}, 25l, 0l, -1, 15, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
-{ 1255l, {"probin"}, 17l, 0l, -1, 16, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }
-
-DATA(insert OID = 0 ( 1255 proname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1255 proowner 26 0 4 2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1255 prolang 26 0 4 3 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1255 proisinh 16 0 1 4 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1255 proistrusted 16 0 1 5 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1255 proiscachable 16 0 1 6 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1255 pronargs 21 0 2 7 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1255 proretset 16 0 1 8 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1255 prorettype 26 0 4 9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1255 proargtypes 30 0 32 10 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1255 probyte_pct 23 0 4 11 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1255 properbyte_cpu 23 0 4 12 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1255 propercall_cpu 23 0 4 13 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1255 prooutin_ratio 23 0 4 14 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1255 prosrc 25 0 -1 15 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1255 probin 17 0 -1 16 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1255 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1255 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1255 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1255 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1255 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1255 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1255 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1255 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1255 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1255 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1255 vtype 18 0 1 -11 0 -1 t f c f f));
-
+{ 1255l, {"prosrc"}, 25l, 0l, -1, 15, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
+{ 1255l, {"probin"}, 17l, 0l, -1, 16, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }
+
+DATA(insert OID = 0 ( 1255 proname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1255 proowner 26 0 4 2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1255 prolang 26 0 4 3 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1255 proisinh 16 0 1 4 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1255 proistrusted 16 0 1 5 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1255 proiscachable 16 0 1 6 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1255 pronargs 21 0 2 7 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1255 proretset 16 0 1 8 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1255 prorettype 26 0 4 9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1255 proargtypes 30 0 32 10 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1255 probyte_pct 23 0 4 11 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1255 properbyte_cpu 23 0 4 12 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1255 propercall_cpu 23 0 4 13 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1255 prooutin_ratio 23 0 4 14 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1255 prosrc 25 0 -1 15 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1255 probin 17 0 -1 16 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1255 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1255 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1255 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1255 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1255 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1255 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1255 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1255 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1255 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1255 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1255 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_server
+ * pg_server
* ----------------
*/
-DATA(insert OID = 0 ( 1257 sername 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1257 serpid 21 0 2 2 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1257 serport 21 0 2 3 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1257 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1257 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1257 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1257 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1257 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1257 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1257 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1257 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1257 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1257 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1257 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1257 sername 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1257 serpid 21 0 2 2 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1257 serport 21 0 2 3 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1257 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1257 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1257 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1257 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1257 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1257 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1257 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1257 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1257 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1257 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1257 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_user
+ * pg_user
* ----------------
*/
-DATA(insert OID = 0 ( 1260 usename 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1260 usesysid 23 0 4 2 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1260 usecreatedb 16 0 1 3 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1260 usetrace 16 0 1 4 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1260 usesuper 16 0 1 5 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1260 usecatupd 16 0 1 6 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1260 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1260 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1260 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1260 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1260 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1260 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1260 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1260 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1260 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1260 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1260 vtype 18 0 1 -11 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1260 usename 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1260 usesysid 23 0 4 2 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1260 usecreatedb 16 0 1 3 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1260 usetrace 16 0 1 4 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1260 usesuper 16 0 1 5 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1260 usecatupd 16 0 1 6 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1260 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1260 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1260 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1260 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1260 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1260 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1260 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1260 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1260 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1260 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1260 vtype 18 0 1 -11 0 -1 t f c f f));
/* ----------------
- * pg_group
+ * pg_group
* ----------------
*/
-DATA(insert OID = 0 ( 1261 groname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1261 grosysid 23 0 4 2 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1261 grolist 1007 0 -1 3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1261 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1261 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1261 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1261 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1261 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1261 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1261 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1261 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1261 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1261 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1261 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1261 groname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1261 grosysid 23 0 4 2 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1261 grolist 1007 0 -1 3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1261 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1261 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1261 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1261 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1261 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1261 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1261 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1261 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1261 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1261 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1261 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_attribute
+ * pg_attribute
* ----------------
*/
#define Schema_pg_attribute \
-{ 1249l, {"attrelid"}, 26l, 0l, 4, 1, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1249l, {"attname"}, 19l, 0l, NAMEDATALEN, 2, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
-{ 1249l, {"atttypid"}, 26l, 0l, 4, 3, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1249l, {"attrelid"}, 26l, 0l, 4, 1, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1249l, {"attname"}, 19l, 0l, NAMEDATALEN, 2, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
+{ 1249l, {"atttypid"}, 26l, 0l, 4, 3, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
{ 1249l, {"attdisbursion"}, 700l, 0l, 4, 4, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
-{ 1249l, {"attlen"}, 21l, 0l, 2, 5, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
-{ 1249l, {"attnum"}, 21l, 0l, 2, 6, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
-{ 1249l, {"attnelems"}, 23l, 0l, 4, 7, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1249l, {"attcacheoff"}, 23l, 0l, 4, 8, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1249l, {"attbyval"}, 16l, 0l, 1, 9, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1249l, {"attisset"}, 16l, 0l, 1, 10, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1249l, {"attalign"}, 18l, 0l, 1, 11, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 12491, {"attnotnull"}, 16l, 0l, 1, 12, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 12491, {"atthasdef"}, 16l, 0l, 1, 13, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }
-
-DATA(insert OID = 0 ( 1249 attrelid 26 0 4 1 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1249 attname 19 0 NAMEDATALEN 2 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1249 atttypid 26 0 4 3 0 -1 t f i f f));
+{ 1249l, {"attlen"}, 21l, 0l, 2, 5, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
+{ 1249l, {"attnum"}, 21l, 0l, 2, 6, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
+{ 1249l, {"attnelems"}, 23l, 0l, 4, 7, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1249l, {"attcacheoff"}, 23l, 0l, 4, 8, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1249l, {"attbyval"}, 16l, 0l, 1, 9, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1249l, {"attisset"}, 16l, 0l, 1, 10, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1249l, {"attalign"}, 18l, 0l, 1, 11, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 12491, {"attnotnull"}, 16l, 0l, 1, 12, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 12491, {"atthasdef"}, 16l, 0l, 1, 13, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }
+
+DATA(insert OID = 0 ( 1249 attrelid 26 0 4 1 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1249 attname 19 0 NAMEDATALEN 2 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1249 atttypid 26 0 4 3 0 -1 t f i f f));
DATA(insert OID = 0 ( 1249 attdisbursion 700 0 4 4 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1249 attlen 21 0 2 5 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1249 attnum 21 0 2 6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1249 attnelems 23 0 4 7 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1249 attcacheoff 23 0 4 8 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1249 attbyval 16 0 1 9 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1249 attisset 16 0 1 10 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1249 attalign 18 0 1 11 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1249 attnotnull 16 0 1 12 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1249 atthasdef 16 0 1 13 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1249 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1249 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1249 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1249 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1249 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1249 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1249 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1249 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1249 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1249 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1249 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1249 attlen 21 0 2 5 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1249 attnum 21 0 2 6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1249 attnelems 23 0 4 7 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1249 attcacheoff 23 0 4 8 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1249 attbyval 16 0 1 9 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1249 attisset 16 0 1 10 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1249 attalign 18 0 1 11 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1249 attnotnull 16 0 1 12 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1249 atthasdef 16 0 1 13 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1249 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1249 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1249 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1249 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1249 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1249 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1249 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1249 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1249 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1249 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1249 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_class
+ * pg_class
* ----------------
*/
#define Schema_pg_class \
-{ 1259l, {"relname"}, 19l, 0l, NAMEDATALEN, 1, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
-{ 1259l, {"reltype"}, 26l, 0l, 4, 2, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1259l, {"relowner"}, 26l, 0l, 4, 2, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1259l, {"relam"}, 26l, 0l, 4, 3, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1259l, {"relpages"}, 23, 0l, 4, 4, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1259l, {"reltuples"}, 23, 0l, 4, 5, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1259l, {"relname"}, 19l, 0l, NAMEDATALEN, 1, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }, \
+{ 1259l, {"reltype"}, 26l, 0l, 4, 2, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1259l, {"relowner"}, 26l, 0l, 4, 2, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1259l, {"relam"}, 26l, 0l, 4, 3, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1259l, {"relpages"}, 23, 0l, 4, 4, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
+{ 1259l, {"reltuples"}, 23, 0l, 4, 5, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
{ 1259l, {"relexpires"}, 702, 0l, 4, 6, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
{ 1259l, {"relpreserved"}, 703, 0l, 4, 7, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }, \
-{ 1259l, {"relhasindex"}, 16, 0l, 1, 8, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1259l, {"relisshared"}, 16, 0l, 1, 9, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1259l, {"relkind"}, 18, 0l, 1, 10, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1259l, {"relarch"}, 18, 0l, 1, 11, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1259l, {"relnatts"}, 21, 0l, 2, 12, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
-{ 1259l, {"relsmgr"}, 210l, 0l, 2, 13, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
+{ 1259l, {"relhasindex"}, 16, 0l, 1, 8, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1259l, {"relisshared"}, 16, 0l, 1, 9, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1259l, {"relkind"}, 18, 0l, 1, 10, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1259l, {"relarch"}, 18, 0l, 1, 11, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1259l, {"relnatts"}, 21, 0l, 2, 12, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
+{ 1259l, {"relsmgr"}, 210l, 0l, 2, 13, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
{ 1259l, {"relchecks"}, 21l, 0l, 2, 14, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
{ 1259l, {"reltriggers"}, 21l, 0l, 2, 15, 0l, -1l, '\001', '\0', 's', '\0', '\0' }, \
-{ 1259l, {"relhasrules"}, 16, 0l, 1, 16, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
-{ 1259l, {"relacl"}, 1034l, 0l, -1, 17, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }
-
-DATA(insert OID = 0 ( 1259 relname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1259 reltype 26 0 4 2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1259 relowner 26 0 4 2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1259 relam 26 0 4 3 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1259 relpages 23 0 4 4 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1259 reltuples 23 0 4 5 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1259 relexpires 702 0 4 6 0 -1 t f i f f));
+{ 1259l, {"relhasrules"}, 16, 0l, 1, 16, 0l, -1l, '\001', '\0', 'c', '\0', '\0' }, \
+{ 1259l, {"relacl"}, 1034l, 0l, -1, 17, 0l, -1l, '\0', '\0', 'i', '\0', '\0' }
+
+DATA(insert OID = 0 ( 1259 relname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1259 reltype 26 0 4 2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1259 relowner 26 0 4 2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1259 relam 26 0 4 3 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1259 relpages 23 0 4 4 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1259 reltuples 23 0 4 5 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1259 relexpires 702 0 4 6 0 -1 t f i f f));
DATA(insert OID = 0 ( 1259 relpreserved 702 0 4 7 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1259 relhasindex 16 0 1 8 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1259 relisshared 16 0 1 9 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1259 relkind 18 0 1 10 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1259 relarch 18 0 1 11 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1259 relnatts 21 0 2 12 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1259 relsmgr 210 0 2 13 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1259 relchecks 21 0 2 14 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1259 reltriggers 21 0 2 15 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1259 relhasrules 16 0 1 16 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1259 relacl 1034 0 -1 17 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1259 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1259 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1259 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1259 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1259 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1259 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1259 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1259 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1259 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1259 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1259 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1259 relhasindex 16 0 1 8 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1259 relisshared 16 0 1 9 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1259 relkind 18 0 1 10 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1259 relarch 18 0 1 11 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1259 relnatts 21 0 2 12 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1259 relsmgr 210 0 2 13 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1259 relchecks 21 0 2 14 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1259 reltriggers 21 0 2 15 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1259 relhasrules 16 0 1 16 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1259 relacl 1034 0 -1 17 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1259 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1259 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1259 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1259 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1259 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1259 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1259 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1259 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1259 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1259 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1259 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_magic
+ * pg_magic
* ----------------
*/
-DATA(insert OID = 0 ( 1253 magname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1253 magvalue 19 0 NAMEDATALEN 2 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1253 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1253 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1253 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1253 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1253 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1253 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1253 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1253 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1253 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1253 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1253 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1253 magname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1253 magvalue 19 0 NAMEDATALEN 2 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1253 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1253 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1253 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1253 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1253 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1253 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1253 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1253 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1253 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1253 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1253 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_defaults
+ * pg_defaults
* ----------------
*/
-DATA(insert OID = 0 ( 1263 defname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1263 defvalue 19 0 NAMEDATALEN 2 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1263 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1263 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1263 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1263 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1263 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1263 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1263 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1263 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1263 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1263 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1263 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1263 defname 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1263 defvalue 19 0 NAMEDATALEN 2 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1263 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1263 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1263 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1263 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1263 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1263 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1263 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1263 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1263 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1263 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1263 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_attrdef
+ * pg_attrdef
* ----------------
*/
-DATA(insert OID = 0 ( 1215 adrelid 26 0 4 1 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1215 adnum 21 0 2 2 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1215 adbin 25 0 -1 3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1215 adsrc 25 0 -1 4 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1215 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1215 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1215 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1215 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1215 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1215 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1215 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1215 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1215 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1215 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1215 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1215 adrelid 26 0 4 1 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1215 adnum 21 0 2 2 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1215 adbin 25 0 -1 3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1215 adsrc 25 0 -1 4 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1215 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1215 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1215 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1215 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1215 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1215 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1215 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1215 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1215 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1215 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1215 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_relcheck
+ * pg_relcheck
* ----------------
*/
-DATA(insert OID = 0 ( 1216 rcrelid 26 0 4 1 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1216 rcname 19 0 NAMEDATALEN 2 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1216 rcbin 25 0 -1 3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1216 rcsrc 25 0 -1 4 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1216 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1216 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1216 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1216 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1216 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1216 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1216 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1216 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1216 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1216 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1216 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1216 rcrelid 26 0 4 1 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1216 rcname 19 0 NAMEDATALEN 2 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1216 rcbin 25 0 -1 3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1216 rcsrc 25 0 -1 4 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1216 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1216 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1216 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1216 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1216 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1216 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1216 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1216 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1216 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1216 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1216 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_trigger
+ * pg_trigger
* ----------------
*/
-DATA(insert OID = 0 ( 1219 tgrelid 26 0 4 1 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1219 tgname 19 0 NAMEDATALEN 2 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1219 tgfoid 26 0 4 3 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1219 tgtype 21 0 2 4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1219 tgnargs 21 0 2 5 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1219 tgattr 22 0 16 6 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1219 tgargs 17 0 -1 7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1219 ctid 27 0 6 -1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1219 oid 26 0 4 -2 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1219 xmin 28 0 4 -3 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1219 cmin 29 0 2 -4 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1219 xmax 28 0 4 -5 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1219 cmax 29 0 2 -6 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1219 chain 27 0 6 -7 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1219 anchor 27 0 6 -8 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1219 tmin 702 0 4 -9 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1219 tmax 702 0 4 -10 0 -1 t f i f f));
-DATA(insert OID = 0 ( 1219 vtype 18 0 1 -11 0 -1 t f c f f));
-
+DATA(insert OID = 0 ( 1219 tgrelid 26 0 4 1 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1219 tgname 19 0 NAMEDATALEN 2 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1219 tgfoid 26 0 4 3 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1219 tgtype 21 0 2 4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1219 tgnargs 21 0 2 5 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1219 tgattr 22 0 16 6 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1219 tgargs 17 0 -1 7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1219 ctid 27 0 6 -1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1219 oid 26 0 4 -2 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1219 xmin 28 0 4 -3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1219 cmin 29 0 2 -4 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1219 xmax 28 0 4 -5 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1219 cmax 29 0 2 -6 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1219 chain 27 0 6 -7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1219 anchor 27 0 6 -8 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1219 tmin 702 0 4 -9 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1219 tmax 702 0 4 -10 0 -1 t f i f f));
+DATA(insert OID = 0 ( 1219 vtype 18 0 1 -11 0 -1 t f c f f));
+
/* ----------------
- * pg_hosts - this relation is used to store host based authentication
- * info
- *
+ * pg_hosts - this relation is used to store host based authentication
+ * info
+ *
* ----------------
*/
-DATA(insert OID = 0 ( 1273 dbName 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1273 address 25 0 -1 2 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1273 mask 25 0 -1 3 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1273 dbName 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1273 address 25 0 -1 2 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1273 mask 25 0 -1 3 0 -1 f f i f f));
/* ----------------
- * pg_variable - this relation is modified by special purpose access
- * method code. The following is garbage but is needed
- * so that the reldesc code works properly.
+ * pg_variable - this relation is modified by special purpose access
+ * method code. The following is garbage but is needed
+ * so that the reldesc code works properly.
* ----------------
*/
#define Schema_pg_variable \
{ 1264l, {"varfoo"}, 26l, 0l, 4, 1, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }
-
-DATA(insert OID = 0 ( 1264 varfoo 26 0 4 1 0 -1 t f i f f));
-
+
+DATA(insert OID = 0 ( 1264 varfoo 26 0 4 1 0 -1 t f i f f));
+
/* ----------------
- * pg_log - this relation is modified by special purpose access
- * method code. The following is garbage but is needed
- * so that the reldesc code works properly.
+ * pg_log - this relation is modified by special purpose access
+ * method code. The following is garbage but is needed
+ * so that the reldesc code works properly.
* ----------------
*/
#define Schema_pg_log \
{ 1269l, {"logfoo"}, 26l, 0l, 4, 1, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }
-DATA(insert OID = 0 ( 1269 logfoo 26 0 4 1 0 -1 t f i f f));
-
+DATA(insert OID = 0 ( 1269 logfoo 26 0 4 1 0 -1 t f i f f));
+
/* ----------------
- * pg_time - this relation is modified by special purpose access
- * method code. The following is garbage but is needed
- * so that the reldesc code works properly.
+ * pg_time - this relation is modified by special purpose access
+ * method code. The following is garbage but is needed
+ * so that the reldesc code works properly.
* ----------------
*/
#define Schema_pg_time \
{ 1271l, {"timefoo"}, 26l, 0l, 4, 1, 0l, -1l, '\001', '\0', 'i', '\0', '\0' }
-DATA(insert OID = 0 ( 1271 timefoo 26 0 4 1 0 -1 t f i f f));
-
-#endif /* PG_ATTRIBUTE_H */
+DATA(insert OID = 0 ( 1271 timefoo 26 0 4 1 0 -1 t f i f f));
+
+#endif /* PG_ATTRIBUTE_H */
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index e595f8fbbc6..2be1ebd90b5 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -1,22 +1,22 @@
/*-------------------------------------------------------------------------
*
* pg_class.h--
- * definition of the system "relation" relation (pg_class)
- * along with the relation's initial contents.
+ * definition of the system "relation" relation (pg_class)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_class.h,v 1.9 1997/09/04 13:25:13 vadim Exp $
+ * $Id: pg_class.h,v 1.10 1997/09/07 04:56:42 momjian Exp $
*
* NOTES
- * ``pg_relation'' is being replaced by ``pg_class''. currently
- * we are only changing the name in the catalogs but someday the
- * code will be changed too. -cim 2/26/90
- * [it finally happens. -ay 11/5/94]
+ * ``pg_relation'' is being replaced by ``pg_class''. currently
+ * we are only changing the name in the catalogs but someday the
+ * code will be changed too. -cim 2/26/90
+ * [it finally happens. -ay 11/5/94]
*
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -24,149 +24,155 @@
#define PG_RELATION_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_class definition. cpp turns this into
- * typedef struct FormData_pg_class
+ * pg_class definition. cpp turns this into
+ * typedef struct FormData_pg_class
*
- * Note: the #if 0, #endif around the BKI_BEGIN.. END block
- * below keeps cpp from seeing what is meant for the
- * genbki script: pg_relation is now called pg_class, but
- * only in the catalogs -cim 2/26/90
+ * Note: the #if 0, #endif around the BKI_BEGIN.. END block
+ * below keeps cpp from seeing what is meant for the
+ * genbki script: pg_relation is now called pg_class, but
+ * only in the catalogs -cim 2/26/90
* ----------------
*/
/* ----------------
- * This structure is actually variable-length (the last attribute is
- * a POSTGRES array). Hence, sizeof(FormData_pg_class) does not
- * describe the fixed-length or actual size of the structure.
- * FormData_pg_class.relacl may not be correctly aligned, either,
- * if aclitem and struct varlena don't align together. Hence,
- * you MUST use heap_getattr() to get the relacl field.
+ * This structure is actually variable-length (the last attribute is
+ * a POSTGRES array). Hence, sizeof(FormData_pg_class) does not
+ * describe the fixed-length or actual size of the structure.
+ * FormData_pg_class.relacl may not be correctly aligned, either,
+ * if aclitem and struct varlena don't align together. Hence,
+ * you MUST use heap_getattr() to get the relacl field.
* ----------------
*/
-CATALOG(pg_class) BOOTSTRAP {
- NameData relname;
- Oid reltype;
- Oid relowner;
- Oid relam;
- int4 relpages;
- int4 reltuples;
- int4 relexpires; /* really used as a abstime, but fudge it for now*/
- int4 relpreserved;/*really used as a reltime, but fudge it for now*/
- bool relhasindex;
- bool relisshared;
- char relkind;
- char relarch; /* 'h' = heavy, 'l' = light, 'n' = no archival*/
- int2 relnatts;
- /* relnatts is the number of user attributes this class has. There
- must be exactly this many instances in Class pg_attribute for this
- class which have attnum > 0 (= user attribute).
- */
- int2 relsmgr;
- int2 relchecks; /* # of CHECK constraints */
- int2 reltriggers; /* # of TRIGGERs */
- bool relhasrules;
- aclitem relacl[1]; /* this is here for the catalog */
+CATALOG(pg_class) BOOTSTRAP
+{
+ NameData relname;
+ Oid reltype;
+ Oid relowner;
+ Oid relam;
+ int4 relpages;
+ int4 reltuples;
+ int4 relexpires; /* really used as a abstime, but fudge it
+ * for now */
+ int4 relpreserved; /* really used as a reltime, but
+ * fudge it for now */
+ bool relhasindex;
+ bool relisshared;
+ char relkind;
+ char relarch; /* 'h' = heavy, 'l' = light, 'n' = no
+ * archival */
+ int2 relnatts;
+
+ /*
+ * relnatts is the number of user attributes this class has. There
+ * must be exactly this many instances in Class pg_attribute for this
+ * class which have attnum > 0 (= user attribute).
+ */
+ int2 relsmgr;
+ int2 relchecks; /* # of CHECK constraints */
+ int2 reltriggers;/* # of TRIGGERs */
+ bool relhasrules;
+ aclitem relacl[1]; /* this is here for the catalog */
} FormData_pg_class;
#define CLASS_TUPLE_SIZE \
- (offsetof(FormData_pg_class,relhasrules) + sizeof(bool))
+ (offsetof(FormData_pg_class,relhasrules) + sizeof(bool))
/* ----------------
- * Form_pg_class corresponds to a pointer to a tuple with
- * the format of pg_class relation.
+ * Form_pg_class corresponds to a pointer to a tuple with
+ * the format of pg_class relation.
* ----------------
*/
-typedef FormData_pg_class *Form_pg_class;
+typedef FormData_pg_class *Form_pg_class;
/* ----------------
- * compiler constants for pg_class
+ * compiler constants for pg_class
* ----------------
*/
/* ----------------
- * Natts_pg_class_fixed is used to tell routines that insert new
- * pg_class tuples (as opposed to replacing old ones) that there's no
- * relacl field.
+ * Natts_pg_class_fixed is used to tell routines that insert new
+ * pg_class tuples (as opposed to replacing old ones) that there's no
+ * relacl field.
* ----------------
*/
-#define Natts_pg_class_fixed 17
-#define Natts_pg_class 18
-#define Anum_pg_class_relname 1
-#define Anum_pg_class_reltype 2
-#define Anum_pg_class_relowner 3
-#define Anum_pg_class_relam 4
-#define Anum_pg_class_relpages 5
-#define Anum_pg_class_reltuples 6
-#define Anum_pg_class_relexpires 7
-#define Anum_pg_class_relpreserved 8
-#define Anum_pg_class_relhasindex 9
-#define Anum_pg_class_relisshared 10
-#define Anum_pg_class_relkind 11
-#define Anum_pg_class_relarch 12
-#define Anum_pg_class_relnatts 13
-#define Anum_pg_class_relsmgr 14
-#define Anum_pg_class_relchecks 15
-#define Anum_pg_class_reltriggers 16
-#define Anum_pg_class_relhasrules 17
-#define Anum_pg_class_relacl 18
+#define Natts_pg_class_fixed 17
+#define Natts_pg_class 18
+#define Anum_pg_class_relname 1
+#define Anum_pg_class_reltype 2
+#define Anum_pg_class_relowner 3
+#define Anum_pg_class_relam 4
+#define Anum_pg_class_relpages 5
+#define Anum_pg_class_reltuples 6
+#define Anum_pg_class_relexpires 7
+#define Anum_pg_class_relpreserved 8
+#define Anum_pg_class_relhasindex 9
+#define Anum_pg_class_relisshared 10
+#define Anum_pg_class_relkind 11
+#define Anum_pg_class_relarch 12
+#define Anum_pg_class_relnatts 13
+#define Anum_pg_class_relsmgr 14
+#define Anum_pg_class_relchecks 15
+#define Anum_pg_class_reltriggers 16
+#define Anum_pg_class_relhasrules 17
+#define Anum_pg_class_relacl 18
/* ----------------
- * initial contents of pg_class
+ * initial contents of pg_class
* ----------------
*/
-DATA(insert OID = 1247 ( pg_type 71 PGUID 0 0 0 0 0 f f r n 16 0 0 0 f _null_ ));
-DATA(insert OID = 1249 ( pg_attribute 75 PGUID 0 0 0 0 0 f f r n 16 0 0 0 f _null_ ));
-DATA(insert OID = 1251 ( pg_demon 76 PGUID 0 0 0 0 0 f t r n 4 0 0 0 f _null_ ));
-DATA(insert OID = 1253 ( pg_magic 80 PGUID 0 0 0 0 0 f t r n 2 0 0 0 f _null_ ));
-DATA(insert OID = 1255 ( pg_proc 81 PGUID 0 0 0 0 0 f f r n 16 0 0 0 f _null_ ));
-DATA(insert OID = 1257 ( pg_server 82 PGUID 0 0 0 0 0 f t r n 3 0 0 0 f _null_ ));
-DATA(insert OID = 1259 ( pg_class 83 PGUID 0 0 0 0 0 f f r n 18 0 0 0 f _null_ ));
-DATA(insert OID = 1260 ( pg_user 86 PGUID 0 0 0 0 0 f t r n 6 0 0 0 f _null_ ));
-DATA(insert OID = 1261 ( pg_group 87 PGUID 0 0 0 0 0 f t s n 3 0 0 0 f _null_ ));
-DATA(insert OID = 1262 ( pg_database 88 PGUID 0 0 0 0 0 f t r n 3 0 0 0 f _null_ ));
-DATA(insert OID = 1263 ( pg_defaults 89 PGUID 0 0 0 0 0 f t r n 2 0 0 0 f _null_ ));
-DATA(insert OID = 1264 ( pg_variable 90 PGUID 0 0 0 0 0 f t s n 2 0 0 0 f _null_ ));
-DATA(insert OID = 1269 ( pg_log 99 PGUID 0 0 0 0 0 f t s n 1 0 0 0 f _null_ ));
-DATA(insert OID = 1271 ( pg_time 100 PGUID 0 0 0 0 0 f t s n 1 0 0 0 f _null_ ));
-DATA(insert OID = 1273 ( pg_hosts 101 PGUID 0 0 0 0 0 f t s n 3 0 0 0 f _null_ ));
-DATA(insert OID = 1215 ( pg_attrdef 109 PGUID 0 0 0 0 0 t t r n 4 0 0 0 f _null_ ));
-DATA(insert OID = 1216 ( pg_relcheck 110 PGUID 0 0 0 0 0 t t r n 4 0 0 0 f _null_ ));
-DATA(insert OID = 1219 ( pg_trigger 111 PGUID 0 0 0 0 0 t t r n 7 0 0 0 f _null_ ));
+DATA(insert OID = 1247 ( pg_type 71 PGUID 0 0 0 0 0 f f r n 16 0 0 0 f _null_ ));
+DATA(insert OID = 1249 ( pg_attribute 75 PGUID 0 0 0 0 0 f f r n 16 0 0 0 f _null_ ));
+DATA(insert OID = 1251 ( pg_demon 76 PGUID 0 0 0 0 0 f t r n 4 0 0 0 f _null_ ));
+DATA(insert OID = 1253 ( pg_magic 80 PGUID 0 0 0 0 0 f t r n 2 0 0 0 f _null_ ));
+DATA(insert OID = 1255 ( pg_proc 81 PGUID 0 0 0 0 0 f f r n 16 0 0 0 f _null_ ));
+DATA(insert OID = 1257 ( pg_server 82 PGUID 0 0 0 0 0 f t r n 3 0 0 0 f _null_ ));
+DATA(insert OID = 1259 ( pg_class 83 PGUID 0 0 0 0 0 f f r n 18 0 0 0 f _null_ ));
+DATA(insert OID = 1260 ( pg_user 86 PGUID 0 0 0 0 0 f t r n 6 0 0 0 f _null_ ));
+DATA(insert OID = 1261 ( pg_group 87 PGUID 0 0 0 0 0 f t s n 3 0 0 0 f _null_ ));
+DATA(insert OID = 1262 ( pg_database 88 PGUID 0 0 0 0 0 f t r n 3 0 0 0 f _null_ ));
+DATA(insert OID = 1263 ( pg_defaults 89 PGUID 0 0 0 0 0 f t r n 2 0 0 0 f _null_ ));
+DATA(insert OID = 1264 ( pg_variable 90 PGUID 0 0 0 0 0 f t s n 2 0 0 0 f _null_ ));
+DATA(insert OID = 1269 ( pg_log 99 PGUID 0 0 0 0 0 f t s n 1 0 0 0 f _null_ ));
+DATA(insert OID = 1271 ( pg_time 100 PGUID 0 0 0 0 0 f t s n 1 0 0 0 f _null_ ));
+DATA(insert OID = 1273 ( pg_hosts 101 PGUID 0 0 0 0 0 f t s n 3 0 0 0 f _null_ ));
+DATA(insert OID = 1215 ( pg_attrdef 109 PGUID 0 0 0 0 0 t t r n 4 0 0 0 f _null_ ));
+DATA(insert OID = 1216 ( pg_relcheck 110 PGUID 0 0 0 0 0 t t r n 4 0 0 0 f _null_ ));
+DATA(insert OID = 1219 ( pg_trigger 111 PGUID 0 0 0 0 0 t t r n 7 0 0 0 f _null_ ));
+
+#define RelOid_pg_type 1247
+#define RelOid_pg_demon 1251
+#define RelOid_pg_attribute 1249
+#define RelOid_pg_magic 1253
+#define RelOid_pg_proc 1255
+#define RelOid_pg_server 1257
+#define RelOid_pg_class 1259
+#define RelOid_pg_user 1260
+#define RelOid_pg_group 1261
+#define RelOid_pg_database 1262
+#define RelOid_pg_defaults 1263
+#define RelOid_pg_variable 1264
+#define RelOid_pg_log 1269
+#define RelOid_pg_time 1271
+#define RelOid_pg_hosts 1273
+#define RelOid_pg_attrdef 1215
+#define RelOid_pg_relcheck 1216
+#define RelOid_pg_trigger 1219
-#define RelOid_pg_type 1247
-#define RelOid_pg_demon 1251
-#define RelOid_pg_attribute 1249
-#define RelOid_pg_magic 1253
-#define RelOid_pg_proc 1255
-#define RelOid_pg_server 1257
-#define RelOid_pg_class 1259
-#define RelOid_pg_user 1260
-#define RelOid_pg_group 1261
-#define RelOid_pg_database 1262
-#define RelOid_pg_defaults 1263
-#define RelOid_pg_variable 1264
-#define RelOid_pg_log 1269
-#define RelOid_pg_time 1271
-#define RelOid_pg_hosts 1273
-#define RelOid_pg_attrdef 1215
-#define RelOid_pg_relcheck 1216
-#define RelOid_pg_trigger 1219
-
-#define MAX_SYSTEM_RELOID 1273 /* this does not seem to be used */
- /* anywhere */
+#define MAX_SYSTEM_RELOID 1273 /* this does not seem to be used */
+ /* anywhere */
-#define RELKIND_INDEX 'i' /* secondary index */
-#define RELKIND_RELATION 'r' /* cataloged heap */
-#define RELKIND_SPECIAL 's' /* special (non-heap) */
-#define RELKIND_SEQUENCE 'S' /* SEQUENCE relation */
-#define RELKIND_UNCATALOGED 'u' /* temporary heap */
+#define RELKIND_INDEX 'i' /* secondary index */
+#define RELKIND_RELATION 'r' /* cataloged heap */
+#define RELKIND_SPECIAL 's' /* special (non-heap) */
+#define RELKIND_SEQUENCE 'S' /* SEQUENCE relation */
+#define RELKIND_UNCATALOGED 'u' /* temporary heap */
-#endif /* PG_RELATION_H */
+#endif /* PG_RELATION_H */
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index 56536f811bd..bd77e23a5df 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_database.h--
- * definition of the system "database" relation (pg_database)
- * along with the relation's initial contents.
+ * definition of the system "database" relation (pg_database)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_database.h,v 1.3 1997/08/21 02:28:55 momjian Exp $
+ * $Id: pg_database.h,v 1.4 1997/09/07 04:56:43 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,38 +19,39 @@
#define PG_DATABASE_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_database definition. cpp turns this into
- * typedef struct FormData_pg_database
+ * pg_database definition. cpp turns this into
+ * typedef struct FormData_pg_database
* ----------------
- */
-CATALOG(pg_database) BOOTSTRAP {
- NameData datname;
- int4 datdba;
- text datpath; /* VARIABLE LENGTH FIELD */
+ */
+CATALOG(pg_database) BOOTSTRAP
+{
+ NameData datname;
+ int4 datdba;
+ text datpath; /* VARIABLE LENGTH FIELD */
} FormData_pg_database;
/* ----------------
- * Form_pg_database corresponds to a pointer to a tuple with
- * the format of pg_database relation.
+ * Form_pg_database corresponds to a pointer to a tuple with
+ * the format of pg_database relation.
* ----------------
*/
-typedef FormData_pg_database *Form_pg_database;
+typedef FormData_pg_database *Form_pg_database;
/* ----------------
- * compiler constants for pg_database
+ * compiler constants for pg_database
* ----------------
*/
-#define Natts_pg_database 3
-#define Anum_pg_database_datname 1
-#define Anum_pg_database_datdba 2
-#define Anum_pg_database_datpath 3
+#define Natts_pg_database 3
+#define Anum_pg_database_datname 1
+#define Anum_pg_database_datdba 2
+#define Anum_pg_database_datpath 3
-#endif /* PG_DATABASE_H */
+#endif /* PG_DATABASE_H */
diff --git a/src/include/catalog/pg_defaults.h b/src/include/catalog/pg_defaults.h
index 554c4457a3c..a35c06c4db8 100644
--- a/src/include/catalog/pg_defaults.h
+++ b/src/include/catalog/pg_defaults.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_defaults.h--
- * definition of the system "defaults" relation (pg_defaults)
- * along with the relation's initial contents.
+ * definition of the system "defaults" relation (pg_defaults)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_defaults.h,v 1.2 1996/10/31 09:47:24 scrappy Exp $
+ * $Id: pg_defaults.h,v 1.3 1997/09/07 04:56:44 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,36 +19,37 @@
#define PG_DEFAULTS_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_defaults definition. cpp turns this into
- * typedef struct FormData_pg_defaults
+ * pg_defaults definition. cpp turns this into
+ * typedef struct FormData_pg_defaults
* ----------------
- */
-CATALOG(pg_defaults) BOOTSTRAP {
- NameData defname;
- NameData defvalue;
+ */
+CATALOG(pg_defaults) BOOTSTRAP
+{
+ NameData defname;
+ NameData defvalue;
} FormData_pg_defaults;
/* ----------------
- * Form_pg_defaults corresponds to a pointer to a tuple with
- * the format of pg_defaults relation.
+ * Form_pg_defaults corresponds to a pointer to a tuple with
+ * the format of pg_defaults relation.
* ----------------
*/
-typedef FormData_pg_defaults *Form_pg_defaults;
+typedef FormData_pg_defaults *Form_pg_defaults;
/* ----------------
- * compiler constants for pg_defaults
+ * compiler constants for pg_defaults
* ----------------
*/
-#define Natts_pg_defaults 2
-#define Anum_pg_defaults_defname 1
-#define Anum_pg_defaults_defvalue 2
+#define Natts_pg_defaults 2
+#define Anum_pg_defaults_defname 1
+#define Anum_pg_defaults_defvalue 2
-#endif /* PG_DEFAULTS_H */
+#endif /* PG_DEFAULTS_H */
diff --git a/src/include/catalog/pg_demon.h b/src/include/catalog/pg_demon.h
index a0511ee362c..0bdb0151aa1 100644
--- a/src/include/catalog/pg_demon.h
+++ b/src/include/catalog/pg_demon.h
@@ -1,57 +1,58 @@
/*-------------------------------------------------------------------------
*
* pg_demon.h--
- * definition of the system "demon" relation (pg_demon)
- * along with the relation's initial contents.
+ * definition of the system "demon" relation (pg_demon)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_demon.h,v 1.2 1996/10/31 09:47:26 scrappy Exp $
+ * $Id: pg_demon.h,v 1.3 1997/09/07 04:56:45 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
-#ifndef PG_DEMON_H
-#define PG_DEMON_H
+#ifndef PG_DEMON_H
+#define PG_DEMON_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_demon definition. cpp turns this into
- * typedef struct FormData_pg_demon
+ * pg_demon definition. cpp turns this into
+ * typedef struct FormData_pg_demon
* ----------------
- */
-CATALOG(pg_demon) BOOTSTRAP {
- Oid demserid;
- NameData demname;
- Oid demowner;
- regproc demcode;
+ */
+CATALOG(pg_demon) BOOTSTRAP
+{
+ Oid demserid;
+ NameData demname;
+ Oid demowner;
+ regproc demcode;
} FormData_pg_demon;
/* ----------------
- * Form_pg_demon corresponds to a pointer to a tuple with
- * the format of pg_demon relation.
+ * Form_pg_demon corresponds to a pointer to a tuple with
+ * the format of pg_demon relation.
* ----------------
*/
-typedef FormData_pg_demon *Form_pg_demon;
+typedef FormData_pg_demon *Form_pg_demon;
/* ----------------
- * compiler constants for pg_demon
+ * compiler constants for pg_demon
* ----------------
*/
-#define Natts_pg_demon 4
-#define Anum_pg_demon_demserid 1
-#define Anum_pg_demon_demname 2
-#define Anum_pg_demon_demowner 3
-#define Anum_pg_demon_demcode 4
+#define Natts_pg_demon 4
+#define Anum_pg_demon_demserid 1
+#define Anum_pg_demon_demname 2
+#define Anum_pg_demon_demowner 3
+#define Anum_pg_demon_demcode 4
-#endif /* PG_DEMON_H */
+#endif /* PG_DEMON_H */
diff --git a/src/include/catalog/pg_group.h b/src/include/catalog/pg_group.h
index b54a960b06b..3661b5149fe 100644
--- a/src/include/catalog/pg_group.h
+++ b/src/include/catalog/pg_group.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* pg_group.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_group.h,v 1.2 1996/10/31 09:47:28 scrappy Exp $
+ * $Id: pg_group.h,v 1.3 1997/09/07 04:56:46 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -18,24 +18,26 @@
#define PG_GROUP_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
-CATALOG(pg_group) BOOTSTRAP {
- NameData groname;
- int4 grosysid;
- int4 grolist[1];
+CATALOG(pg_group) BOOTSTRAP
+{
+ NameData groname;
+ int4 grosysid;
+ int4 grolist[1];
} FormData_pg_group;
+
/* VARIABLE LENGTH STRUCTURE */
-typedef FormData_pg_group *Form_pg_group;
+typedef FormData_pg_group *Form_pg_group;
-#define Natts_pg_group 1
+#define Natts_pg_group 1
#define Anum_pg_group_groname 1
#define Anum_pg_group_grosysid 2
#define Anum_pg_group_grolist 3
-#endif /* PG_GROUP_H */
+#endif /* PG_GROUP_H */
diff --git a/src/include/catalog/pg_hosts.h b/src/include/catalog/pg_hosts.h
index f192310f2c7..633b28579b6 100644
--- a/src/include/catalog/pg_hosts.h
+++ b/src/include/catalog/pg_hosts.h
@@ -2,19 +2,19 @@
*
* pg_hosts.h--
*
- * the pg_hosts system catalog provides host-based access to the
- * backend. Only those hosts that are in the pg_hosts
+ * the pg_hosts system catalog provides host-based access to the
+ * backend. Only those hosts that are in the pg_hosts
*
- * currently, this table is not used, instead file-based host authentication
+ * currently, this table is not used, instead file-based host authentication
* is used
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_hosts.h,v 1.2 1996/10/31 09:47:30 scrappy Exp $
+ * $Id: pg_hosts.h,v 1.3 1997/09/07 04:56:46 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*-------------------------------------------------------------------------
*/
@@ -22,22 +22,24 @@
#define PG_HOSTS_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
-CATALOG(pg_hosts) BOOTSTRAP {
- NameData dbName;
- text address;
- text mask;
+CATALOG(pg_hosts) BOOTSTRAP
+{
+ NameData dbName;
+ text address;
+ text mask;
} FormData_pg_hosts;
-typedef FormData_pg_hosts *Form_pg_hosts;
-#define Natts_pg_hosts 3
+typedef FormData_pg_hosts *Form_pg_hosts;
+
+#define Natts_pg_hosts 3
#define Anum_pg_hosts_dbName 1
#define Anum_pg_hosts_address 2
-#define Anum_pg_hosts_mask 3
+#define Anum_pg_hosts_mask 3
-#endif /* PG_HOSTS_H */
+#endif /* PG_HOSTS_H */
diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h
index 91f472422a8..0ebaea1c76a 100644
--- a/src/include/catalog/pg_index.h
+++ b/src/include/catalog/pg_index.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_index.h--
- * definition of the system "index" relation (pg_index)
- * along with the relation's initial contents.
+ * definition of the system "index" relation (pg_index)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_index.h,v 1.3 1996/11/13 20:50:57 scrappy Exp $
+ * $Id: pg_index.h,v 1.4 1997/09/07 04:56:47 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,64 +19,69 @@
#define PG_INDEX_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_index definition. cpp turns this into
- * typedef struct FormData_pg_index. The oid of the index relation
- * is stored in indexrelid; the oid of the indexed relation is stored
- * in indrelid.
+ * pg_index definition. cpp turns this into
+ * typedef struct FormData_pg_index. The oid of the index relation
+ * is stored in indexrelid; the oid of the indexed relation is stored
+ * in indrelid.
* ----------------
- */
+ */
-/*
+/*
* it seems that all variable length fields should go at the _end_,
* because the system cache routines only copy the fields up to the
* first variable length field. so I moved indislossy, indhaskeytype,
- * and indisunique before indpred. --djm 8/20/96
+ * and indisunique before indpred. --djm 8/20/96
*/
-CATALOG(pg_index) {
- Oid indexrelid;
- Oid indrelid;
- Oid indproc; /* registered procedure for functional index */
- int28 indkey;
- oid8 indclass;
- bool indisclustered;
- bool indisarchived;
- bool indislossy; /* do we fetch false tuples (lossy compression)? */
- bool indhaskeytype; /* does key type != attribute type? */
- bool indisunique; /* is this a unique index? */
- text indpred; /* query plan for partial index predicate */
+CATALOG(pg_index)
+{
+ Oid indexrelid;
+ Oid indrelid;
+ Oid indproc; /* registered procedure for functional
+ * index */
+ int28 indkey;
+ oid8 indclass;
+ bool indisclustered;
+ bool indisarchived;
+ bool indislossy; /* do we fetch false tuples (lossy
+ * compression)? */
+ bool indhaskeytype; /* does key type != attribute
+ * type? */
+ bool indisunique;/* is this a unique index? */
+ text indpred; /* query plan for partial index predicate */
} FormData_pg_index;
-#define INDEX_MAX_KEYS 8 /* maximum number of keys in an index definition */
+#define INDEX_MAX_KEYS 8 /* maximum number of keys in an index
+ * definition */
/* ----------------
- * Form_pg_index corresponds to a pointer to a tuple with
- * the format of pg_index relation.
+ * Form_pg_index corresponds to a pointer to a tuple with
+ * the format of pg_index relation.
* ----------------
*/
-typedef FormData_pg_index *IndexTupleForm;
+typedef FormData_pg_index *IndexTupleForm;
/* ----------------
- * compiler constants for pg_index
+ * compiler constants for pg_index
* ----------------
*/
-#define Natts_pg_index 11
-#define Anum_pg_index_indexrelid 1
-#define Anum_pg_index_indrelid 2
-#define Anum_pg_index_indproc 3
-#define Anum_pg_index_indkey 4
-#define Anum_pg_index_indclass 5
+#define Natts_pg_index 11
+#define Anum_pg_index_indexrelid 1
+#define Anum_pg_index_indrelid 2
+#define Anum_pg_index_indproc 3
+#define Anum_pg_index_indkey 4
+#define Anum_pg_index_indclass 5
#define Anum_pg_index_indisclustered 6
-#define Anum_pg_index_indisarchived 7
-#define Anum_pg_index_indislossy 8
-#define Anum_pg_index_indhaskeytype 9
-#define Anum_pg_index_indisunique 10
-#define Anum_pg_index_indpred 11
+#define Anum_pg_index_indisarchived 7
+#define Anum_pg_index_indislossy 8
+#define Anum_pg_index_indhaskeytype 9
+#define Anum_pg_index_indisunique 10
+#define Anum_pg_index_indpred 11
-#endif /* PG_INDEX_H */
+#endif /* PG_INDEX_H */
diff --git a/src/include/catalog/pg_inheritproc.h b/src/include/catalog/pg_inheritproc.h
index 5357c7ebfa5..f53561a51ca 100644
--- a/src/include/catalog/pg_inheritproc.h
+++ b/src/include/catalog/pg_inheritproc.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_inheritproc.h--
- * definition of the system "inheritproc" relation (pg_inheritproc)
- * along with the relation's initial contents.
+ * definition of the system "inheritproc" relation (pg_inheritproc)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_inheritproc.h,v 1.2 1996/10/31 09:47:33 scrappy Exp $
+ * $Id: pg_inheritproc.h,v 1.3 1997/09/07 04:56:50 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,40 +19,41 @@
#define PG_INHERITPROC_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_inheritproc definition. cpp turns this into
- * typedef struct FormData_pg_inheritproc
+ * pg_inheritproc definition. cpp turns this into
+ * typedef struct FormData_pg_inheritproc
* ----------------
- */
-CATALOG(pg_inheritproc) {
- NameData inhproname;
- Oid inhargrel;
- Oid inhdefrel;
- Oid inhproc;
+ */
+CATALOG(pg_inheritproc)
+{
+ NameData inhproname;
+ Oid inhargrel;
+ Oid inhdefrel;
+ Oid inhproc;
} FormData_pg_inheritproc;
/* ----------------
- * Form_pg_inheritproc corresponds to a pointer to a tuple with
- * the format of pg_inheritproc relation.
+ * Form_pg_inheritproc corresponds to a pointer to a tuple with
+ * the format of pg_inheritproc relation.
* ----------------
*/
-typedef FormData_pg_inheritproc *Form_pg_inheritproc;
+typedef FormData_pg_inheritproc *Form_pg_inheritproc;
/* ----------------
- * compiler constants for pg_inheritproc
+ * compiler constants for pg_inheritproc
* ----------------
*/
-#define Natts_pg_inheritproc 4
+#define Natts_pg_inheritproc 4
#define Anum_pg_inheritproc_inhproname 1
#define Anum_pg_inheritproc_inhargrel 2
#define Anum_pg_inheritproc_inhdefrel 3
-#define Anum_pg_inheritproc_inhproc 4
+#define Anum_pg_inheritproc_inhproc 4
-#endif /* PG_INHERITPROC_H */
+#endif /* PG_INHERITPROC_H */
diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h
index 66c6f933914..8913b613ed0 100644
--- a/src/include/catalog/pg_inherits.h
+++ b/src/include/catalog/pg_inherits.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_inherits.h--
- * definition of the system "inherits" relation (pg_inherits)
- * along with the relation's initial contents.
+ * definition of the system "inherits" relation (pg_inherits)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_inherits.h,v 1.2 1996/10/31 09:47:35 scrappy Exp $
+ * $Id: pg_inherits.h,v 1.3 1997/09/07 04:56:51 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,38 +19,39 @@
#define PG_INHERITS_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_inherits definition. cpp turns this into
- * typedef struct FormData_pg_inherits
+ * pg_inherits definition. cpp turns this into
+ * typedef struct FormData_pg_inherits
* ----------------
- */
-CATALOG(pg_inherits) {
- Oid inhrel;
- Oid inhparent;
- int4 inhseqno;
+ */
+CATALOG(pg_inherits)
+{
+ Oid inhrel;
+ Oid inhparent;
+ int4 inhseqno;
} FormData_pg_inherits;
/* ----------------
- * Form_pg_inherits corresponds to a pointer to a tuple with
- * the format of pg_inherits relation.
+ * Form_pg_inherits corresponds to a pointer to a tuple with
+ * the format of pg_inherits relation.
* ----------------
*/
-typedef FormData_pg_inherits *InheritsTupleForm;
+typedef FormData_pg_inherits *InheritsTupleForm;
/* ----------------
- * compiler constants for pg_inherits
+ * compiler constants for pg_inherits
* ----------------
*/
-#define Natts_pg_inherits 3
-#define Anum_pg_inherits_inhrel 1
-#define Anum_pg_inherits_inhparent 2
-#define Anum_pg_inherits_inhseqno 3
+#define Natts_pg_inherits 3
+#define Anum_pg_inherits_inhrel 1
+#define Anum_pg_inherits_inhparent 2
+#define Anum_pg_inherits_inhseqno 3
-#endif /* PG_INHERITS_H */
+#endif /* PG_INHERITS_H */
diff --git a/src/include/catalog/pg_ipl.h b/src/include/catalog/pg_ipl.h
index 7242c8fc672..4e735f8dc33 100644
--- a/src/include/catalog/pg_ipl.h
+++ b/src/include/catalog/pg_ipl.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_ipl.h--
- * definition of the system "ipl" relation (pg_ipl)
- * along with the relation's initial contents.
+ * definition of the system "ipl" relation (pg_ipl)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_ipl.h,v 1.2 1996/10/31 09:47:36 scrappy Exp $
+ * $Id: pg_ipl.h,v 1.3 1997/09/07 04:56:52 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,38 +19,39 @@
#define PG_IPL_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_ipl definition. cpp turns this into
- * typedef struct FormData_pg_ipl
+ * pg_ipl definition. cpp turns this into
+ * typedef struct FormData_pg_ipl
* ----------------
- */
-CATALOG(pg_ipl) {
- Oid iplrel;
- Oid iplipl;
- int4 iplseqno;
+ */
+CATALOG(pg_ipl)
+{
+ Oid iplrel;
+ Oid iplipl;
+ int4 iplseqno;
} FormData_pg_ipl;
/* ----------------
- * Form_pg_ipl corresponds to a pointer to a tuple with
- * the format of pg_ipl relation.
+ * Form_pg_ipl corresponds to a pointer to a tuple with
+ * the format of pg_ipl relation.
* ----------------
*/
-typedef FormData_pg_ipl *Form_pg_ipl;
+typedef FormData_pg_ipl *Form_pg_ipl;
/* ----------------
- * compiler constants for pg_ipl
+ * compiler constants for pg_ipl
* ----------------
*/
-#define Natts_pg_ipl 3
-#define Anum_pg_ipl_iplrel 1
-#define Anum_pg_ipl_iplipl 2
+#define Natts_pg_ipl 3
+#define Anum_pg_ipl_iplrel 1
+#define Anum_pg_ipl_iplipl 2
#define Anum_pg_ipl_iplseqno 3
-#endif /* PG_IPL_H */
+#endif /* PG_IPL_H */
diff --git a/src/include/catalog/pg_language.h b/src/include/catalog/pg_language.h
index 35e53d7dc18..1a1ac577aad 100644
--- a/src/include/catalog/pg_language.h
+++ b/src/include/catalog/pg_language.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_language.h--
- * definition of the system "language" relation (pg_language)
- * along with the relation's initial contents.
+ * definition of the system "language" relation (pg_language)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_language.h,v 1.2 1996/10/31 09:47:38 scrappy Exp $
+ * $Id: pg_language.h,v 1.3 1997/09/07 04:56:53 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,39 +19,40 @@
#define PG_LANGUAGE_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_language definition. cpp turns this into
- * typedef struct FormData_pg_language
+ * pg_language definition. cpp turns this into
+ * typedef struct FormData_pg_language
* ----------------
- */
-CATALOG(pg_language) {
- NameData lanname;
- text lancompiler; /* VARIABLE LENGTH FIELD */
+ */
+CATALOG(pg_language)
+{
+ NameData lanname;
+ text lancompiler;/* VARIABLE LENGTH FIELD */
} FormData_pg_language;
/* ----------------
- * Form_pg_language corresponds to a pointer to a tuple with
- * the format of pg_language relation.
+ * Form_pg_language corresponds to a pointer to a tuple with
+ * the format of pg_language relation.
* ----------------
*/
-typedef FormData_pg_language *Form_pg_language;
+typedef FormData_pg_language *Form_pg_language;
/* ----------------
- * compiler constants for pg_language
+ * compiler constants for pg_language
* ----------------
*/
-#define Natts_pg_language 2
-#define Anum_pg_language_lanname 1
+#define Natts_pg_language 2
+#define Anum_pg_language_lanname 1
#define Anum_pg_language_lancompiler 2
/* ----------------
- * initial contents of pg_language
+ * initial contents of pg_language
* ----------------
*/
@@ -63,12 +64,5 @@ DATA(insert OID = 13 ( "C" "/bin/cc" ));
DATA(insert OID = 14 ( "sql" "postgres"));
#define SQLlanguageId 14
-
-#endif /* PG_LANGUAGE_H */
-
-
-
-
-
-
+#endif /* PG_LANGUAGE_H */
diff --git a/src/include/catalog/pg_listener.h b/src/include/catalog/pg_listener.h
index 64749d3e334..c1826a317a4 100644
--- a/src/include/catalog/pg_listener.h
+++ b/src/include/catalog/pg_listener.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* pg_listener.h--
- * Asynchronous notification
+ * Asynchronous notification
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_listener.h,v 1.2 1996/10/31 09:47:40 scrappy Exp $
+ * $Id: pg_listener.h,v 1.3 1997/09/07 04:56:54 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -18,38 +18,39 @@
#define PG_LISTENER_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------------------------------------------------------
- * pg_listener definition.
+ * pg_listener definition.
*
- * cpp turns this into typedef struct FormData_pg_listener
+ * cpp turns this into typedef struct FormData_pg_listener
* ----------------------------------------------------------------
*/
-CATALOG(pg_listener) {
- NameData relname;
- int4 listenerpid;
- int4 notification;
+CATALOG(pg_listener)
+{
+ NameData relname;
+ int4 listenerpid;
+ int4 notification;
} FormData_pg_listener;
/* ----------------
- * compiler constants for pg_listener
+ * compiler constants for pg_listener
* ----------------
*/
-#define Natts_pg_listener 3
-#define Anum_pg_listener_relname 1
-#define Anum_pg_listener_pid 2
-#define Anum_pg_listener_notify 3
+#define Natts_pg_listener 3
+#define Anum_pg_listener_relname 1
+#define Anum_pg_listener_pid 2
+#define Anum_pg_listener_notify 3
/* ----------------
- * initial contents of pg_listener are NOTHING.
+ * initial contents of pg_listener are NOTHING.
* ----------------
*/
-#endif /* PG_LISTENER_H */
+#endif /* PG_LISTENER_H */
diff --git a/src/include/catalog/pg_log.h b/src/include/catalog/pg_log.h
index 7aa4240762d..977b1f9cccf 100644
--- a/src/include/catalog/pg_log.h
+++ b/src/include/catalog/pg_log.h
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* pg_log.h--
- * the system log relation "pg_log" is not a "heap" relation.
- * it is automatically created by the transam/ code and the
- * information here is all bogus and is just here to make the
- * relcache code happy.
+ * the system log relation "pg_log" is not a "heap" relation.
+ * it is automatically created by the transam/ code and the
+ * information here is all bogus and is just here to make the
+ * relcache code happy.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_log.h,v 1.2 1996/10/31 09:47:42 scrappy Exp $
+ * $Id: pg_log.h,v 1.3 1997/09/07 04:56:55 momjian Exp $
*
* NOTES
- * The structures and macros used by the transam/ code
- * to access pg_log should some day go here -cim 6/18/90
+ * The structures and macros used by the transam/ code
+ * to access pg_log should some day go here -cim 6/18/90
*
*-------------------------------------------------------------------------
*/
@@ -21,19 +21,20 @@
#define PG_LOG_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
-CATALOG(pg_log) BOOTSTRAP {
- Oid logfoo;
+CATALOG(pg_log) BOOTSTRAP
+{
+ Oid logfoo;
} FormData_pg_log;
-typedef FormData_pg_log *Form_pg_log;
+typedef FormData_pg_log *Form_pg_log;
-#define Natts_pg_log 1
-#define Anum_pg_log_logfoo 1
+#define Natts_pg_log 1
+#define Anum_pg_log_logfoo 1
-#endif /* PG_LOG_H */
+#endif /* PG_LOG_H */
diff --git a/src/include/catalog/pg_magic.h b/src/include/catalog/pg_magic.h
index 83f53d73d1b..7c92c2e3c55 100644
--- a/src/include/catalog/pg_magic.h
+++ b/src/include/catalog/pg_magic.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_magic.h--
- * definition of the system "magic" relation (pg_magic)
- * along with the relation's initial contents.
+ * definition of the system "magic" relation (pg_magic)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_magic.h,v 1.2 1996/10/31 09:47:45 scrappy Exp $
+ * $Id: pg_magic.h,v 1.3 1997/09/07 04:56:57 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,35 +19,36 @@
#define PG_MAGIC_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_magic definition. cpp turns this into
- * typedef struct FormData_pg_magic
+ * pg_magic definition. cpp turns this into
+ * typedef struct FormData_pg_magic
* ----------------
- */
-CATALOG(pg_magic) BOOTSTRAP {
- NameData magname;
- NameData magvalue;
+ */
+CATALOG(pg_magic) BOOTSTRAP
+{
+ NameData magname;
+ NameData magvalue;
} FormData_pg_magic;
/* ----------------
- * Form_pg_magic corresponds to a pointer to a tuple with
- * the format of pg_magic relation.
+ * Form_pg_magic corresponds to a pointer to a tuple with
+ * the format of pg_magic relation.
* ----------------
*/
-typedef FormData_pg_magic *Form_pg_magic;
+typedef FormData_pg_magic *Form_pg_magic;
/* ----------------
- * compiler constants for pg_magic
+ * compiler constants for pg_magic
* ----------------
*/
-#define Natts_pg_magic 2
-#define Anum_pg_magic_magname 1
-#define Anum_pg_magic_magvalue 2
+#define Natts_pg_magic 2
+#define Anum_pg_magic_magname 1
+#define Anum_pg_magic_magvalue 2
-#endif /* PG_MAGIC_H */
+#endif /* PG_MAGIC_H */
diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h
index ba267a10ccc..f047de2c890 100644
--- a/src/include/catalog/pg_opclass.h
+++ b/src/include/catalog/pg_opclass.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_opclass.h--
- * definition of the system "opclass" relation (pg_opclass)
- * along with the relation's initial contents.
+ * definition of the system "opclass" relation (pg_opclass)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_opclass.h,v 1.3 1997/09/04 18:43:58 thomas Exp $
+ * $Id: pg_opclass.h,v 1.4 1997/09/07 04:56:58 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,40 +19,41 @@
#define PG_OPCLASS_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_opclass definition. cpp turns this into
- * typedef struct FormData_pg_opclass
+ * pg_opclass definition. cpp turns this into
+ * typedef struct FormData_pg_opclass
* ----------------
- */
+ */
-CATALOG(pg_opclass) {
- NameData opcname;
- Oid opcdeftype;
+CATALOG(pg_opclass)
+{
+ NameData opcname;
+ Oid opcdeftype;
} FormData_pg_opclass;
/* ----------------
- * Form_pg_opclass corresponds to a pointer to a tuple with
- * the format of pg_opclass relation.
+ * Form_pg_opclass corresponds to a pointer to a tuple with
+ * the format of pg_opclass relation.
* ----------------
*/
-typedef FormData_pg_opclass *Form_pg_opclass;
+typedef FormData_pg_opclass *Form_pg_opclass;
/* ----------------
- * compiler constants for pg_opclass
+ * compiler constants for pg_opclass
* ----------------
*/
-#define Natts_pg_opclass 2
-#define Anum_pg_opclass_opcname 1
-#define Anum_pg_opclass_opcdeftype 2
+#define Natts_pg_opclass 2
+#define Anum_pg_opclass_opcname 1
+#define Anum_pg_opclass_opcdeftype 2
/* ----------------
- * initial contents of pg_opclass
+ * initial contents of pg_opclass
* ----------------
*/
@@ -61,34 +62,34 @@ typedef FormData_pg_opclass *Form_pg_opclass;
* (see the README in this directory), so just put zeros
* in, which are invalid OID's anyway. --djm
*/
-DATA(insert OID = 406 ( char2_ops 409 ));
-DATA(insert OID = 407 ( char4_ops 410 ));
-DATA(insert OID = 408 ( char8_ops 411 ));
-DATA(insert OID = 1181 ( name_ops 19 ));
-DATA(insert OID = 421 ( int2_ops 21 ));
-DATA(insert OID = 422 ( box_ops 603 ));
-DATA(insert OID = 423 ( float8_ops 701 ));
-DATA(insert OID = 424 ( int24_ops 0 ));
-DATA(insert OID = 425 ( int42_ops 0 ));
-DATA(insert OID = 426 ( int4_ops 23 ));
+DATA(insert OID = 406 ( char2_ops 409 ));
+DATA(insert OID = 407 ( char4_ops 410 ));
+DATA(insert OID = 408 ( char8_ops 411 ));
+DATA(insert OID = 1181 ( name_ops 19 ));
+DATA(insert OID = 421 ( int2_ops 21 ));
+DATA(insert OID = 422 ( box_ops 603 ));
+DATA(insert OID = 423 ( float8_ops 701 ));
+DATA(insert OID = 424 ( int24_ops 0 ));
+DATA(insert OID = 425 ( int42_ops 0 ));
+DATA(insert OID = 426 ( int4_ops 23 ));
#define INT4_OPS_OID 426
-DATA(insert OID = 427 ( oid_ops 26 ));
-DATA(insert OID = 428 ( float4_ops 700 ));
-DATA(insert OID = 429 ( char_ops 18 ));
-DATA(insert OID = 430 ( char16_ops 20 ));
-DATA(insert OID = 431 ( text_ops 25 ));
-DATA(insert OID = 432 ( abstime_ops 702 ));
-DATA(insert OID = 433 ( bigbox_ops 0 ));
-DATA(insert OID = 434 ( poly_ops 604 ));
-DATA(insert OID = 435 ( oidint4_ops 910 ));
-DATA(insert OID = 436 ( oidname_ops 911 ));
-DATA(insert OID = 437 ( oidint2_ops 810 ));
-DATA(insert OID = 714 ( circle_ops 718 ));
-DATA(insert OID = 1076 ( bpchar_ops 1042 ));
-DATA(insert OID = 1077 ( varchar_ops 1043 ));
-DATA(insert OID = 1114 ( date_ops 1082 ));
-DATA(insert OID = 1115 ( time_ops 1083 ));
-DATA(insert OID = 1312 ( datetime_ops 1184 ));
-DATA(insert OID = 1313 ( timespan_ops 1186 ));
+DATA(insert OID = 427 ( oid_ops 26 ));
+DATA(insert OID = 428 ( float4_ops 700 ));
+DATA(insert OID = 429 ( char_ops 18 ));
+DATA(insert OID = 430 ( char16_ops 20 ));
+DATA(insert OID = 431 ( text_ops 25 ));
+DATA(insert OID = 432 ( abstime_ops 702 ));
+DATA(insert OID = 433 ( bigbox_ops 0 ));
+DATA(insert OID = 434 ( poly_ops 604 ));
+DATA(insert OID = 435 ( oidint4_ops 910 ));
+DATA(insert OID = 436 ( oidname_ops 911 ));
+DATA(insert OID = 437 ( oidint2_ops 810 ));
+DATA(insert OID = 714 ( circle_ops 718 ));
+DATA(insert OID = 1076 ( bpchar_ops 1042 ));
+DATA(insert OID = 1077 ( varchar_ops 1043 ));
+DATA(insert OID = 1114 ( date_ops 1082 ));
+DATA(insert OID = 1115 ( time_ops 1083 ));
+DATA(insert OID = 1312 ( datetime_ops 1184 ));
+DATA(insert OID = 1313 ( timespan_ops 1186 ));
-#endif /* PG_OPCLASS_H */
+#endif /* PG_OPCLASS_H */
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index 6e7f9284018..111974e4722 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* pg_operator.h--
- * definition of the system "operator" relation (pg_operator)
- * along with the relation's initial contents.
+ * definition of the system "operator" relation (pg_operator)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_operator.h,v 1.13 1997/08/21 23:56:48 momjian Exp $
+ * $Id: pg_operator.h,v 1.14 1997/09/07 04:57:00 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
- * XXX do NOT break up DATA() statements into multiple lines!
- * the scripts are not as smart as you might think...
+ * XXX do NOT break up DATA() statements into multiple lines!
+ * the scripts are not as smart as you might think...
*
*-------------------------------------------------------------------------
*/
@@ -22,622 +22,624 @@
#define PG_OPERATOR_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_operator definition. cpp turns this into
- * typedef struct FormData_pg_operator
+ * pg_operator definition. cpp turns this into
+ * typedef struct FormData_pg_operator
* ----------------
*/
-CATALOG(pg_operator) {
- NameData oprname;
- Oid oprowner;
- int2 oprprec;
- char oprkind;
- bool oprisleft;
- bool oprcanhash;
- Oid oprleft;
- Oid oprright;
- Oid oprresult;
- Oid oprcom;
- Oid oprnegate;
- Oid oprlsortop;
- Oid oprrsortop;
- regproc oprcode;
- regproc oprrest;
- regproc oprjoin;
+CATALOG(pg_operator)
+{
+ NameData oprname;
+ Oid oprowner;
+ int2 oprprec;
+ char oprkind;
+ bool oprisleft;
+ bool oprcanhash;
+ Oid oprleft;
+ Oid oprright;
+ Oid oprresult;
+ Oid oprcom;
+ Oid oprnegate;
+ Oid oprlsortop;
+ Oid oprrsortop;
+ regproc oprcode;
+ regproc oprrest;
+ regproc oprjoin;
} FormData_pg_operator;
/* ----------------
- * Form_pg_operator corresponds to a pointer to a tuple with
- * the format of pg_operator relation.
+ * Form_pg_operator corresponds to a pointer to a tuple with
+ * the format of pg_operator relation.
* ----------------
*/
-typedef FormData_pg_operator *OperatorTupleForm;
+typedef FormData_pg_operator *OperatorTupleForm;
/* ----------------
- * compiler constants for pg_operator
+ * compiler constants for pg_operator
* ----------------
*/
-#define Natts_pg_operator 16
-#define Anum_pg_operator_oprname 1
-#define Anum_pg_operator_oprowner 2
-#define Anum_pg_operator_oprprec 3
-#define Anum_pg_operator_oprkind 4
-#define Anum_pg_operator_oprisleft 5
-#define Anum_pg_operator_oprcanhash 6
-#define Anum_pg_operator_oprleft 7
-#define Anum_pg_operator_oprright 8
-#define Anum_pg_operator_oprresult 9
-#define Anum_pg_operator_oprcom 10
-#define Anum_pg_operator_oprnegate 11
-#define Anum_pg_operator_oprlsortop 12
-#define Anum_pg_operator_oprrsortop 13
-#define Anum_pg_operator_oprcode 14
-#define Anum_pg_operator_oprrest 15
-#define Anum_pg_operator_oprjoin 16
+#define Natts_pg_operator 16
+#define Anum_pg_operator_oprname 1
+#define Anum_pg_operator_oprowner 2
+#define Anum_pg_operator_oprprec 3
+#define Anum_pg_operator_oprkind 4
+#define Anum_pg_operator_oprisleft 5
+#define Anum_pg_operator_oprcanhash 6
+#define Anum_pg_operator_oprleft 7
+#define Anum_pg_operator_oprright 8
+#define Anum_pg_operator_oprresult 9
+#define Anum_pg_operator_oprcom 10
+#define Anum_pg_operator_oprnegate 11
+#define Anum_pg_operator_oprlsortop 12
+#define Anum_pg_operator_oprrsortop 13
+#define Anum_pg_operator_oprcode 14
+#define Anum_pg_operator_oprrest 15
+#define Anum_pg_operator_oprjoin 16
/* ----------------
- * initial contents of pg_operator
+ * initial contents of pg_operator
* ----------------
*/
-DATA(insert OID = 58 ( "<" PGUID 0 b t f 16 16 16 85 91 0 0 boollt intltsel intltjoinsel ));
-DATA(insert OID = 59 ( ">" PGUID 0 b t f 16 16 16 85 91 0 0 boolgt intltsel intltjoinsel ));
-DATA(insert OID = 85 ( "<>" PGUID 0 b t f 16 16 16 85 91 0 0 boolne neqsel neqjoinsel ));
-DATA(insert OID = 91 ( "=" PGUID 0 b t t 16 16 16 91 85 0 0 booleq eqsel eqjoinsel ));
+DATA(insert OID = 58 ( "<" PGUID 0 b t f 16 16 16 85 91 0 0 boollt intltsel intltjoinsel ));
+DATA(insert OID = 59 ( ">" PGUID 0 b t f 16 16 16 85 91 0 0 boolgt intltsel intltjoinsel ));
+DATA(insert OID = 85 ( "<>" PGUID 0 b t f 16 16 16 85 91 0 0 boolne neqsel neqjoinsel ));
+DATA(insert OID = 91 ( "=" PGUID 0 b t t 16 16 16 91 85 0 0 booleq eqsel eqjoinsel ));
#define BooleanEqualOperator 91
-DATA(insert OID = 92 ( "=" PGUID 0 b t t 18 18 16 92 630 631 631 chareq eqsel eqjoinsel ));
-DATA(insert OID = 93 ( "=" PGUID 0 b t t 19 19 16 93 643 660 660 nameeq eqsel eqjoinsel ));
-DATA(insert OID = 94 ( "=" PGUID 0 b t t 21 21 16 94 519 95 95 int2eq eqsel eqjoinsel ));
-DATA(insert OID = 95 ( "<" PGUID 0 b t f 21 21 16 520 524 0 0 int2lt intltsel intltjoinsel ));
-DATA(insert OID = 96 ( "=" PGUID 0 b t t 23 23 16 96 518 97 97 int4eq eqsel eqjoinsel ));
-DATA(insert OID = 97 ( "<" PGUID 0 b t f 23 23 16 521 525 0 0 int4lt intltsel intltjoinsel ));
-DATA(insert OID = 98 ( "=" PGUID 0 b t t 25 25 16 98 531 664 664 texteq eqsel eqjoinsel ));
-
-DATA(insert OID = 1267 ( "=" PGUID 0 b t t 20 20 16 1267 644 645 645 char16eq eqsel eqjoinsel ));
-DATA(insert OID = 329 ( "=" PGUID 0 b t t 1000 1000 16 329 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 349 ( "=" PGUID 0 b t t 1001 1001 16 349 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 374 ( "=" PGUID 0 b t t 1002 1002 16 374 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 375 ( "=" PGUID 0 b t t 1003 1003 16 375 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 376 ( "=" PGUID 0 b t t 1004 1004 16 376 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 377 ( "=" PGUID 0 b t t 1005 1005 16 377 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 378 ( "=" PGUID 0 b t t 1006 1006 16 378 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 379 ( "=" PGUID 0 b t t 1007 1007 16 379 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 380 ( "=" PGUID 0 b t t 1008 1008 16 380 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 381 ( "=" PGUID 0 b t t 1009 1009 16 381 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 382 ( "=" PGUID 0 b t t 1028 1028 16 382 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 383 ( "=" PGUID 0 b t t 1010 1010 16 383 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 384 ( "=" PGUID 0 b t t 1011 1011 16 384 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 385 ( "=" PGUID 0 b t t 1012 1012 16 385 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 386 ( "=" PGUID 0 b t t 1013 1013 16 386 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 92 ( "=" PGUID 0 b t t 18 18 16 92 630 631 631 chareq eqsel eqjoinsel ));
+DATA(insert OID = 93 ( "=" PGUID 0 b t t 19 19 16 93 643 660 660 nameeq eqsel eqjoinsel ));
+DATA(insert OID = 94 ( "=" PGUID 0 b t t 21 21 16 94 519 95 95 int2eq eqsel eqjoinsel ));
+DATA(insert OID = 95 ( "<" PGUID 0 b t f 21 21 16 520 524 0 0 int2lt intltsel intltjoinsel ));
+DATA(insert OID = 96 ( "=" PGUID 0 b t t 23 23 16 96 518 97 97 int4eq eqsel eqjoinsel ));
+DATA(insert OID = 97 ( "<" PGUID 0 b t f 23 23 16 521 525 0 0 int4lt intltsel intltjoinsel ));
+DATA(insert OID = 98 ( "=" PGUID 0 b t t 25 25 16 98 531 664 664 texteq eqsel eqjoinsel ));
+
+DATA(insert OID = 1267 ( "=" PGUID 0 b t t 20 20 16 1267 644 645 645 char16eq eqsel eqjoinsel ));
+DATA(insert OID = 329 ( "=" PGUID 0 b t t 1000 1000 16 329 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 349 ( "=" PGUID 0 b t t 1001 1001 16 349 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 374 ( "=" PGUID 0 b t t 1002 1002 16 374 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 375 ( "=" PGUID 0 b t t 1003 1003 16 375 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 376 ( "=" PGUID 0 b t t 1004 1004 16 376 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 377 ( "=" PGUID 0 b t t 1005 1005 16 377 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 378 ( "=" PGUID 0 b t t 1006 1006 16 378 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 379 ( "=" PGUID 0 b t t 1007 1007 16 379 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 380 ( "=" PGUID 0 b t t 1008 1008 16 380 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 381 ( "=" PGUID 0 b t t 1009 1009 16 381 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 382 ( "=" PGUID 0 b t t 1028 1028 16 382 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 383 ( "=" PGUID 0 b t t 1010 1010 16 383 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 384 ( "=" PGUID 0 b t t 1011 1011 16 384 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 385 ( "=" PGUID 0 b t t 1012 1012 16 385 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 386 ( "=" PGUID 0 b t t 1013 1013 16 386 0 0 0 array_eq eqsel eqjoinsel ));
/*
-DATA(insert OID = 387 ( "=" PGUID 0 b t t 1014 1014 16 387 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 387 ( "=" PGUID 0 b t t 1014 1014 16 387 0 0 0 array_eq eqsel eqjoinsel ));
*/
-DATA(insert OID = 388 ( "=" PGUID 0 b t t 1015 1015 16 388 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 389 ( "=" PGUID 0 b t t 1016 1016 16 389 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 390 ( "=" PGUID 0 b t t 1017 1017 16 390 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 391 ( "=" PGUID 0 b t t 1018 1018 16 391 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 392 ( "=" PGUID 0 b t t 1019 1019 16 392 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 393 ( "=" PGUID 0 b t t 1020 1020 16 393 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 394 ( "=" PGUID 0 b t t 1021 1021 16 394 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 395 ( "=" PGUID 0 b t t 1022 1022 16 395 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 396 ( "=" PGUID 0 b t t 1023 1023 16 396 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 397 ( "=" PGUID 0 b t t 1024 1024 16 397 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 398 ( "=" PGUID 0 b t t 1025 1025 16 398 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 399 ( "=" PGUID 0 b t t 1026 1026 16 399 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 400 ( "=" PGUID 0 b t t 1027 1027 16 400 0 0 0 array_eq eqsel eqjoinsel ));
-DATA(insert OID = 401 ( "=" PGUID 0 b t t 1034 1034 16 401 0 0 0 array_eq eqsel eqjoinsel ));
-
-DATA(insert OID = 412 ( "=" PGUID 0 b t t 409 409 16 412 415 418 418 char2eq eqsel eqjoinsel ));
-DATA(insert OID = 413 ( "=" PGUID 0 b t t 410 410 16 413 416 419 419 char4eq eqsel eqjoinsel ));
-DATA(insert OID = 414 ( "=" PGUID 0 b t t 411 411 16 414 417 420 420 char8eq eqsel eqjoinsel ));
-
-DATA(insert OID = 415 ( "<>" PGUID 0 b t f 409 409 16 415 412 0 0 char2ne neqsel neqjoinsel ));
-DATA(insert OID = 416 ( "<>" PGUID 0 b t f 410 410 16 416 413 0 0 char4ne neqsel neqjoinsel ));
-DATA(insert OID = 417 ( "<>" PGUID 0 b t f 411 411 16 417 414 0 0 char8ne neqsel neqjoinsel ));
-DATA(insert OID = 418 ( "<" PGUID 0 b t f 409 409 16 460 463 0 0 char2lt intltsel intltjoinsel ));
-DATA(insert OID = 419 ( "<" PGUID 0 b t f 410 410 16 461 464 0 0 char4lt intltsel intltjoinsel ));
-DATA(insert OID = 420 ( "<" PGUID 0 b t f 411 411 16 462 465 0 0 char8lt intltsel intltjoinsel ));
-
-DATA(insert OID = 457 ( "<=" PGUID 0 b t f 409 409 16 463 460 0 0 char2le intltsel intltjoinsel ));
-DATA(insert OID = 458 ( "<=" PGUID 0 b t f 410 410 16 464 461 0 0 char4le intltsel intltjoinsel ));
-DATA(insert OID = 459 ( "<=" PGUID 0 b t f 411 411 16 465 462 0 0 char8le intltsel intltjoinsel ));
-DATA(insert OID = 460 ( ">" PGUID 0 b t f 409 409 16 418 457 0 0 char2gt intltsel intltjoinsel ));
-DATA(insert OID = 461 ( ">" PGUID 0 b t f 410 410 16 419 458 0 0 char4gt intltsel intltjoinsel ));
-DATA(insert OID = 462 ( ">" PGUID 0 b t f 411 411 16 420 459 0 0 char8gt intltsel intltjoinsel ));
-DATA(insert OID = 463 ( ">=" PGUID 0 b t f 409 409 16 457 418 0 0 char2ge intltsel intltjoinsel ));
-DATA(insert OID = 464 ( ">=" PGUID 0 b t f 410 410 16 458 418 0 0 char4ge intltsel intltjoinsel ));
-DATA(insert OID = 465 ( ">=" PGUID 0 b t f 411 411 16 459 420 0 0 char8ge intltsel intltjoinsel ));
-
-DATA(insert OID = 485 ( "<<" PGUID 0 b t f 604 604 16 0 0 0 0 poly_left intltsel intltjoinsel ));
-DATA(insert OID = 486 ( "&<" PGUID 0 b t f 604 604 16 0 0 0 0 poly_overleft intltsel intltjoinsel ));
-DATA(insert OID = 487 ( "&>" PGUID 0 b t f 604 604 16 0 0 0 0 poly_overright intltsel intltjoinsel ));
-DATA(insert OID = 488 ( ">>" PGUID 0 b t f 604 604 16 0 0 0 0 poly_right intltsel intltjoinsel ));
-DATA(insert OID = 489 ( "@" PGUID 0 b t f 604 604 16 490 0 0 0 poly_contained intltsel intltjoinsel ));
-DATA(insert OID = 490 ( "~" PGUID 0 b t f 604 604 16 489 0 0 0 poly_contain intltsel intltjoinsel ));
-DATA(insert OID = 491 ( "~=" PGUID 0 b t f 604 604 16 491 0 0 0 poly_same intltsel intltjoinsel ));
-DATA(insert OID = 492 ( "&&" PGUID 0 b t f 604 604 16 0 0 0 0 poly_overlap intltsel intltjoinsel ));
-DATA(insert OID = 493 ( "<<" PGUID 0 b t f 603 603 16 0 0 0 0 box_left intltsel intltjoinsel ));
-DATA(insert OID = 494 ( "&<" PGUID 0 b t f 603 603 16 0 0 0 0 box_overleft intltsel intltjoinsel ));
-DATA(insert OID = 495 ( "&>" PGUID 0 b t f 603 603 16 0 0 0 0 box_overright intltsel intltjoinsel ));
-DATA(insert OID = 496 ( ">>" PGUID 0 b t f 603 603 16 0 0 0 0 box_right intltsel intltjoinsel ));
-DATA(insert OID = 497 ( "@" PGUID 0 b t f 603 603 16 498 0 0 0 box_contained intltsel intltjoinsel ));
-DATA(insert OID = 498 ( "~" PGUID 0 b t f 603 603 16 497 0 0 0 box_contain intltsel intltjoinsel ));
-DATA(insert OID = 499 ( "~=" PGUID 0 b t f 603 603 16 499 0 0 0 box_same intltsel intltjoinsel ));
-DATA(insert OID = 500 ( "&&" PGUID 0 b t f 603 603 16 0 0 0 0 box_overlap intltsel intltjoinsel ));
-DATA(insert OID = 501 ( ">=" PGUID 0 b t f 603 603 16 505 504 0 0 box_ge areasel areajoinsel ));
-DATA(insert OID = 502 ( ">" PGUID 0 b t f 603 603 16 504 505 0 0 box_gt areasel areajoinsel ));
-DATA(insert OID = 503 ( "=" PGUID 0 b t t 603 603 16 503 0 0 0 box_eq areasel areajoinsel ));
-DATA(insert OID = 504 ( "<" PGUID 0 b t f 603 603 16 502 501 0 0 box_lt areasel areajoinsel ));
-DATA(insert OID = 505 ( "<=" PGUID 0 b t f 603 603 16 501 502 0 0 box_le areasel areajoinsel ));
-DATA(insert OID = 506 ( ">^" PGUID 0 b t f 600 600 16 0 0 0 0 point_above intltsel intltjoinsel ));
-DATA(insert OID = 507 ( "<<" PGUID 0 b t f 600 600 16 0 0 0 0 point_left intltsel intltjoinsel ));
-DATA(insert OID = 508 ( ">>" PGUID 0 b t f 600 600 16 0 0 0 0 point_right intltsel intltjoinsel ));
-DATA(insert OID = 509 ( "<^" PGUID 0 b t f 600 600 16 0 0 0 0 point_below intltsel intltjoinsel ));
-DATA(insert OID = 510 ( "~=" PGUID 0 b t f 600 600 16 510 0 0 0 point_eq intltsel intltjoinsel ));
-DATA(insert OID = 511 ( "@" PGUID 0 b t f 600 603 16 0 0 0 0 on_pb intltsel intltjoinsel ));
-DATA(insert OID = 512 ( "@" PGUID 0 b t f 600 602 16 0 0 0 0 on_ppath intltsel intltjoinsel ));
-DATA(insert OID = 513 ( "@@" PGUID 0 l t f 0 603 600 0 0 0 0 box_center intltsel intltjoinsel ));
-DATA(insert OID = 514 ( "*" PGUID 0 b t f 23 23 23 514 0 0 0 int4mul intltsel intltjoinsel ));
-DATA(insert OID = 515 ( "!" PGUID 0 r t f 23 0 23 0 0 0 0 int4fac intltsel intltjoinsel ));
-DATA(insert OID = 516 ( "!!" PGUID 0 l t f 0 23 23 0 0 0 0 int4fac intltsel intltjoinsel ));
-DATA(insert OID = 517 ( "<->" PGUID 0 b t f 600 600 701 517 0 0 0 point_distance intltsel intltjoinsel ));
-DATA(insert OID = 518 ( "<>" PGUID 0 b t f 23 23 16 518 96 0 0 int4ne neqsel neqjoinsel ));
-DATA(insert OID = 519 ( "<>" PGUID 0 b t f 21 21 16 519 94 0 0 int2ne neqsel neqjoinsel ));
-DATA(insert OID = 520 ( ">" PGUID 0 b t f 21 21 16 95 0 0 0 int2gt intgtsel intgtjoinsel ));
-DATA(insert OID = 521 ( ">" PGUID 0 b t f 23 23 16 97 0 0 0 int4gt intgtsel intgtjoinsel ));
-DATA(insert OID = 522 ( "<=" PGUID 0 b t f 21 21 16 524 520 0 0 int2le intltsel intltjoinsel ));
-DATA(insert OID = 523 ( "<=" PGUID 0 b t f 23 23 16 525 521 0 0 int4le intltsel intltjoinsel ));
-DATA(insert OID = 524 ( ">=" PGUID 0 b t f 21 21 16 522 95 0 0 int2ge intgtsel intgtjoinsel ));
-DATA(insert OID = 525 ( ">=" PGUID 0 b t f 23 23 16 523 97 0 0 int4ge intgtsel intgtjoinsel ));
-DATA(insert OID = 526 ( "*" PGUID 0 b t f 21 21 21 526 0 0 0 int2mul intltsel intltjoinsel ));
-DATA(insert OID = 527 ( "/" PGUID 0 b t f 21 21 21 0 0 0 0 int2div intltsel intltjoinsel ));
-DATA(insert OID = 528 ( "/" PGUID 0 b t f 23 23 23 0 0 0 0 int4div intltsel intltjoinsel ));
-DATA(insert OID = 529 ( "%" PGUID 0 b t f 21 21 21 6 0 0 0 int2mod intltsel intltjoinsel ));
-DATA(insert OID = 530 ( "%" PGUID 0 b t f 23 23 23 6 0 0 0 int4mod intltsel intltjoinsel ));
-DATA(insert OID = 531 ( "<>" PGUID 0 b t f 25 25 16 531 98 0 0 textne neqsel neqjoinsel ));
-DATA(insert OID = 532 ( "=" PGUID 0 b t t 21 23 16 533 538 95 97 int24eq eqsel eqjoinsel ));
-DATA(insert OID = 533 ( "=" PGUID 0 b t t 23 21 16 532 539 97 95 int42eq eqsel eqjoinsel ));
-DATA(insert OID = 534 ( "<" PGUID 0 b t f 21 23 16 537 542 0 0 int24lt intltsel intltjoinsel ));
-DATA(insert OID = 535 ( "<" PGUID 0 b t f 23 21 16 536 543 0 0 int42lt intltsel intltjoinsel ));
-DATA(insert OID = 536 ( ">" PGUID 0 b t f 21 23 16 535 540 0 0 int24gt intgtsel intgtjoinsel ));
-DATA(insert OID = 537 ( ">" PGUID 0 b t f 23 21 16 534 541 0 0 int42gt intgtsel intgtjoinsel ));
-DATA(insert OID = 538 ( "<>" PGUID 0 b t f 21 23 16 539 532 0 0 int24ne neqsel neqjoinsel ));
-DATA(insert OID = 539 ( "<>" PGUID 0 b t f 23 21 16 538 533 0 0 int42ne neqsel neqjoinsel ));
-DATA(insert OID = 540 ( "<=" PGUID 0 b t f 21 23 16 543 536 0 0 int24le intltsel intltjoinsel ));
-DATA(insert OID = 541 ( "<=" PGUID 0 b t f 23 21 16 542 537 0 0 int42le intltsel intltjoinsel ));
-DATA(insert OID = 542 ( ">=" PGUID 0 b t f 21 23 16 541 534 0 0 int24ge intgtsel intgtjoinsel ));
-DATA(insert OID = 543 ( ">=" PGUID 0 b t f 23 21 16 540 535 0 0 int42ge intgtsel intgtjoinsel ));
-DATA(insert OID = 544 ( "*" PGUID 0 b t f 21 23 23 545 0 0 0 int24mul intltsel intltjoinsel ));
-DATA(insert OID = 545 ( "*" PGUID 0 b t f 23 21 23 544 0 0 0 int42mul intltsel intltjoinsel ));
-DATA(insert OID = 546 ( "/" PGUID 0 b t f 21 23 23 0 0 0 0 int24div intltsel intltjoinsel ));
-DATA(insert OID = 547 ( "/" PGUID 0 b t f 23 21 23 0 0 0 0 int42div intltsel intltjoinsel ));
-DATA(insert OID = 548 ( "%" PGUID 0 b t f 21 23 23 6 0 0 0 int24mod intltsel intltjoinsel ));
-DATA(insert OID = 549 ( "%" PGUID 0 b t f 23 21 23 6 0 0 0 int42mod intltsel intltjoinsel ));
-DATA(insert OID = 550 ( "+" PGUID 0 b t f 21 21 21 550 0 0 0 int2pl intltsel intltjoinsel ));
-DATA(insert OID = 551 ( "+" PGUID 0 b t f 23 23 23 551 0 0 0 int4pl intltsel intltjoinsel ));
-DATA(insert OID = 552 ( "+" PGUID 0 b t f 21 23 23 553 0 0 0 int24pl intltsel intltjoinsel ));
-DATA(insert OID = 553 ( "+" PGUID 0 b t f 23 21 23 552 0 0 0 int42pl intltsel intltjoinsel ));
-DATA(insert OID = 554 ( "-" PGUID 0 b t f 21 21 21 0 0 0 0 int2mi intltsel intltjoinsel ));
-DATA(insert OID = 555 ( "-" PGUID 0 b t f 23 23 23 0 0 0 0 int4mi intltsel intltjoinsel ));
-DATA(insert OID = 556 ( "-" PGUID 0 b t f 21 23 23 0 0 0 0 int24mi intltsel intltjoinsel ));
-DATA(insert OID = 557 ( "-" PGUID 0 b t f 23 21 23 0 0 0 0 int42mi intltsel intltjoinsel ));
-DATA(insert OID = 558 ( "-" PGUID 0 l t f 0 23 23 0 0 0 0 int4um intltsel intltjoinsel ));
-DATA(insert OID = 559 ( "-" PGUID 0 l t f 0 21 21 0 0 0 0 int2um intltsel intltjoinsel ));
-DATA(insert OID = 560 ( "=" PGUID 0 b t t 702 702 16 560 561 562 562 abstimeeq eqsel eqjoinsel ));
-DATA(insert OID = 561 ( "<>" PGUID 0 b t f 702 702 16 561 560 0 0 abstimene neqsel neqjoinsel ));
-DATA(insert OID = 562 ( "<" PGUID 0 b t f 702 702 16 563 565 0 0 abstimelt intltsel intltjoinsel ));
-DATA(insert OID = 563 ( ">" PGUID 0 b t f 702 702 16 562 564 0 0 abstimegt intltsel intltjoinsel ));
-DATA(insert OID = 564 ( "<=" PGUID 0 b t f 702 702 16 565 563 0 0 abstimele intltsel intltjoinsel ));
-DATA(insert OID = 565 ( ">=" PGUID 0 b t f 702 702 16 564 562 0 0 abstimege intltsel intltjoinsel ));
-DATA(insert OID = 566 ( "=" PGUID 0 b t t 703 703 16 566 567 568 568 reltimeeq - - ));
-DATA(insert OID = 567 ( "<>" PGUID 0 b t f 703 703 16 567 566 0 0 reltimene - - ));
-DATA(insert OID = 568 ( "<" PGUID 0 b t f 703 703 16 569 571 0 0 reltimelt - - ));
-DATA(insert OID = 569 ( ">" PGUID 0 b t f 703 703 16 568 570 0 0 reltimegt - - ));
-DATA(insert OID = 570 ( "<=" PGUID 0 b t f 703 703 16 571 569 0 0 reltimele - - ));
-DATA(insert OID = 571 ( ">=" PGUID 0 b t f 703 703 16 570 568 0 0 reltimege - - ));
-DATA(insert OID = 572 ( "=" PGUID 0 b t t 704 704 16 572 0 0 0 intervaleq - - ));
-DATA(insert OID = 573 ( "<<" PGUID 0 b t f 704 704 16 0 0 0 0 intervalct - - ));
-DATA(insert OID = 574 ( "&&" PGUID 0 b t f 704 704 16 0 0 0 0 intervalov - - ));
-DATA(insert OID = 575 ( "#=" PGUID 0 b t f 704 703 16 0 576 0 568 intervalleneq - - ));
-DATA(insert OID = 576 ( "#<>" PGUID 0 b t f 704 703 16 0 575 0 568 intervallenne - - ));
-DATA(insert OID = 577 ( "#<" PGUID 0 b t f 704 703 16 0 580 0 568 intervallenlt - - ));
-DATA(insert OID = 578 ( "#>" PGUID 0 b t f 704 703 16 0 579 0 568 intervallengt - - ));
-DATA(insert OID = 579 ( "#<=" PGUID 0 b t f 704 703 16 0 578 0 568 intervallenle - - ));
-DATA(insert OID = 580 ( "#>=" PGUID 0 b t f 704 703 16 0 577 0 568 intervallenge - - ));
-DATA(insert OID = 581 ( "+" PGUID 0 b t f 702 703 702 581 0 0 0 timepl - - ));
-DATA(insert OID = 582 ( "-" PGUID 0 b t f 702 703 702 0 0 0 0 timemi - - ));
-DATA(insert OID = 583 ( "<?>" PGUID 0 b t f 702 704 16 0 0 562 0 ininterval - - ));
-DATA(insert OID = 584 ( "-" PGUID 0 l t f 0 700 700 0 0 0 0 float4um - - ));
-DATA(insert OID = 585 ( "-" PGUID 0 l t f 0 701 701 0 0 0 0 float8um - - ));
-DATA(insert OID = 586 ( "+" PGUID 0 b t f 700 700 700 586 0 0 0 float4pl - - ));
-DATA(insert OID = 587 ( "-" PGUID 0 b t f 700 700 700 0 0 0 0 float4mi - - ));
-DATA(insert OID = 588 ( "/" PGUID 0 b t f 700 700 700 0 0 0 0 float4div - - ));
-DATA(insert OID = 589 ( "*" PGUID 0 b t f 700 700 700 589 0 0 0 float4mul - - ));
-DATA(insert OID = 590 ( "@" PGUID 0 l t f 0 700 700 0 0 0 0 float4abs - - ));
-DATA(insert OID = 591 ( "+" PGUID 0 b t f 701 701 701 591 0 0 0 float8pl - - ));
-DATA(insert OID = 592 ( "-" PGUID 0 b t f 701 701 701 0 0 0 0 float8mi - - ));
-DATA(insert OID = 593 ( "/" PGUID 0 b t f 701 701 701 0 0 0 0 float8div - - ));
-DATA(insert OID = 594 ( "*" PGUID 0 b t f 701 701 701 594 0 0 0 float8mul - - ));
-DATA(insert OID = 595 ( "@" PGUID 0 l t f 0 701 701 0 0 0 0 float8abs - - ));
-DATA(insert OID = 596 ( "|/" PGUID 0 l t f 0 701 701 0 0 0 0 dsqrt - - ));
-DATA(insert OID = 597 ( "||/" PGUID 0 l t f 0 701 701 0 0 0 0 dcbrt - - ));
-DATA(insert OID = 598 ( "%" PGUID 0 l t f 0 701 701 0 0 0 0 dtrunc - - ));
-DATA(insert OID = 599 ( "%" PGUID 0 r t f 701 0 701 0 0 0 0 dround - - ));
-DATA(insert OID = 1282 ( ":" PGUID 0 l t f 0 701 701 0 0 0 0 dexp - - ));
-DATA(insert OID = 1283 ( ";" PGUID 0 l t f 0 701 701 0 0 0 0 dlog1 - - ));
-DATA(insert OID = 1284 ( "|" PGUID 0 l t f 0 704 702 0 0 0 0 intervalstart - - ));
-DATA(insert OID = 606 ( "<#>" PGUID 0 b t f 702 702 704 0 0 0 0 mktinterval - - ));
-DATA(insert OID = 607 ( "=" PGUID 0 b t t 26 26 16 607 608 97 97 oideq eqsel eqjoinsel ));
-#define OIDEqualOperator 607 /* XXX planner/prep/semanopt.c crock */
-DATA(insert OID = 608 ( "<>" PGUID 0 b t f 26 26 16 608 607 0 0 oidne neqsel neqjoinsel ));
-DATA(insert OID = 609 ( "<" PGUID 0 b t f 26 26 16 610 612 0 0 int4lt intltsel intltjoinsel ));
-DATA(insert OID = 610 ( ">" PGUID 0 b t f 26 26 16 609 611 0 0 int4gt intgtsel intgtjoinsel ));
-DATA(insert OID = 611 ( "<=" PGUID 0 b t f 26 26 16 612 610 0 0 int4le intltsel intltjoinsel ));
-DATA(insert OID = 612 ( ">=" PGUID 0 b t f 26 26 16 611 609 0 0 int4ge intgtsel intgtjoinsel ));
-
-DATA(insert OID = 613 ( "<->" PGUID 0 b t f 600 603 701 0 0 0 0 dist_pl - - ));
-DATA(insert OID = 614 ( "<->" PGUID 0 b t f 600 601 701 0 0 0 0 dist_ps - - ));
-DATA(insert OID = 615 ( "<->" PGUID 0 b t f 600 603 701 0 0 0 0 dist_pb - - ));
-DATA(insert OID = 616 ( "<->" PGUID 0 b t f 601 628 701 0 0 0 0 dist_sl - - ));
-DATA(insert OID = 617 ( "<->" PGUID 0 b t f 601 603 701 0 0 0 0 dist_sb - - ));
-DATA(insert OID = 618 ( "<->" PGUID 0 b t f 600 602 701 0 0 0 0 dist_ppath - - ));
-
-DATA(insert OID = 619 ( "<" PGUID 0 b t f 704 704 16 0 0 0 0 intervalct - - ));
-
-DATA(insert OID = 620 ( "=" PGUID 0 b t t 700 700 16 620 621 622 622 float4eq eqsel eqjoinsel ));
-DATA(insert OID = 621 ( "<>" PGUID 0 b t f 700 700 16 621 620 0 0 float4ne neqsel neqjoinsel ));
-DATA(insert OID = 622 ( "<" PGUID 0 b t f 700 700 16 623 625 0 0 float4lt intltsel intltjoinsel ));
-DATA(insert OID = 623 ( ">" PGUID 0 b t f 700 700 16 622 624 0 0 float4gt intgtsel intgtjoinsel ));
-DATA(insert OID = 624 ( "<=" PGUID 0 b t f 700 700 16 625 623 0 0 float4le intltsel intltjoinsel ));
-DATA(insert OID = 625 ( ">=" PGUID 0 b t f 700 700 16 624 622 0 0 float4ge intgtsel intgtjoinsel ));
-DATA(insert OID = 626 ( "!!=" PGUID 0 b t f 23 19 16 0 0 0 0 int4notin "-" "-"));
-DATA(insert OID = 627 ( "!!=" PGUID 0 b t f 26 19 16 0 0 0 0 oidnotin "-" "-"));
+DATA(insert OID = 388 ( "=" PGUID 0 b t t 1015 1015 16 388 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 389 ( "=" PGUID 0 b t t 1016 1016 16 389 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 390 ( "=" PGUID 0 b t t 1017 1017 16 390 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 391 ( "=" PGUID 0 b t t 1018 1018 16 391 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 392 ( "=" PGUID 0 b t t 1019 1019 16 392 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 393 ( "=" PGUID 0 b t t 1020 1020 16 393 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 394 ( "=" PGUID 0 b t t 1021 1021 16 394 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 395 ( "=" PGUID 0 b t t 1022 1022 16 395 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 396 ( "=" PGUID 0 b t t 1023 1023 16 396 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 397 ( "=" PGUID 0 b t t 1024 1024 16 397 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 398 ( "=" PGUID 0 b t t 1025 1025 16 398 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 399 ( "=" PGUID 0 b t t 1026 1026 16 399 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 400 ( "=" PGUID 0 b t t 1027 1027 16 400 0 0 0 array_eq eqsel eqjoinsel ));
+DATA(insert OID = 401 ( "=" PGUID 0 b t t 1034 1034 16 401 0 0 0 array_eq eqsel eqjoinsel ));
+
+DATA(insert OID = 412 ( "=" PGUID 0 b t t 409 409 16 412 415 418 418 char2eq eqsel eqjoinsel ));
+DATA(insert OID = 413 ( "=" PGUID 0 b t t 410 410 16 413 416 419 419 char4eq eqsel eqjoinsel ));
+DATA(insert OID = 414 ( "=" PGUID 0 b t t 411 411 16 414 417 420 420 char8eq eqsel eqjoinsel ));
+
+DATA(insert OID = 415 ( "<>" PGUID 0 b t f 409 409 16 415 412 0 0 char2ne neqsel neqjoinsel ));
+DATA(insert OID = 416 ( "<>" PGUID 0 b t f 410 410 16 416 413 0 0 char4ne neqsel neqjoinsel ));
+DATA(insert OID = 417 ( "<>" PGUID 0 b t f 411 411 16 417 414 0 0 char8ne neqsel neqjoinsel ));
+DATA(insert OID = 418 ( "<" PGUID 0 b t f 409 409 16 460 463 0 0 char2lt intltsel intltjoinsel ));
+DATA(insert OID = 419 ( "<" PGUID 0 b t f 410 410 16 461 464 0 0 char4lt intltsel intltjoinsel ));
+DATA(insert OID = 420 ( "<" PGUID 0 b t f 411 411 16 462 465 0 0 char8lt intltsel intltjoinsel ));
+
+DATA(insert OID = 457 ( "<=" PGUID 0 b t f 409 409 16 463 460 0 0 char2le intltsel intltjoinsel ));
+DATA(insert OID = 458 ( "<=" PGUID 0 b t f 410 410 16 464 461 0 0 char4le intltsel intltjoinsel ));
+DATA(insert OID = 459 ( "<=" PGUID 0 b t f 411 411 16 465 462 0 0 char8le intltsel intltjoinsel ));
+DATA(insert OID = 460 ( ">" PGUID 0 b t f 409 409 16 418 457 0 0 char2gt intltsel intltjoinsel ));
+DATA(insert OID = 461 ( ">" PGUID 0 b t f 410 410 16 419 458 0 0 char4gt intltsel intltjoinsel ));
+DATA(insert OID = 462 ( ">" PGUID 0 b t f 411 411 16 420 459 0 0 char8gt intltsel intltjoinsel ));
+DATA(insert OID = 463 ( ">=" PGUID 0 b t f 409 409 16 457 418 0 0 char2ge intltsel intltjoinsel ));
+DATA(insert OID = 464 ( ">=" PGUID 0 b t f 410 410 16 458 418 0 0 char4ge intltsel intltjoinsel ));
+DATA(insert OID = 465 ( ">=" PGUID 0 b t f 411 411 16 459 420 0 0 char8ge intltsel intltjoinsel ));
+
+DATA(insert OID = 485 ( "<<" PGUID 0 b t f 604 604 16 0 0 0 0 poly_left intltsel intltjoinsel ));
+DATA(insert OID = 486 ( "&<" PGUID 0 b t f 604 604 16 0 0 0 0 poly_overleft intltsel intltjoinsel ));
+DATA(insert OID = 487 ( "&>" PGUID 0 b t f 604 604 16 0 0 0 0 poly_overright intltsel intltjoinsel ));
+DATA(insert OID = 488 ( ">>" PGUID 0 b t f 604 604 16 0 0 0 0 poly_right intltsel intltjoinsel ));
+DATA(insert OID = 489 ( "@" PGUID 0 b t f 604 604 16 490 0 0 0 poly_contained intltsel intltjoinsel ));
+DATA(insert OID = 490 ( "~" PGUID 0 b t f 604 604 16 489 0 0 0 poly_contain intltsel intltjoinsel ));
+DATA(insert OID = 491 ( "~=" PGUID 0 b t f 604 604 16 491 0 0 0 poly_same intltsel intltjoinsel ));
+DATA(insert OID = 492 ( "&&" PGUID 0 b t f 604 604 16 0 0 0 0 poly_overlap intltsel intltjoinsel ));
+DATA(insert OID = 493 ( "<<" PGUID 0 b t f 603 603 16 0 0 0 0 box_left intltsel intltjoinsel ));
+DATA(insert OID = 494 ( "&<" PGUID 0 b t f 603 603 16 0 0 0 0 box_overleft intltsel intltjoinsel ));
+DATA(insert OID = 495 ( "&>" PGUID 0 b t f 603 603 16 0 0 0 0 box_overright intltsel intltjoinsel ));
+DATA(insert OID = 496 ( ">>" PGUID 0 b t f 603 603 16 0 0 0 0 box_right intltsel intltjoinsel ));
+DATA(insert OID = 497 ( "@" PGUID 0 b t f 603 603 16 498 0 0 0 box_contained intltsel intltjoinsel ));
+DATA(insert OID = 498 ( "~" PGUID 0 b t f 603 603 16 497 0 0 0 box_contain intltsel intltjoinsel ));
+DATA(insert OID = 499 ( "~=" PGUID 0 b t f 603 603 16 499 0 0 0 box_same intltsel intltjoinsel ));
+DATA(insert OID = 500 ( "&&" PGUID 0 b t f 603 603 16 0 0 0 0 box_overlap intltsel intltjoinsel ));
+DATA(insert OID = 501 ( ">=" PGUID 0 b t f 603 603 16 505 504 0 0 box_ge areasel areajoinsel ));
+DATA(insert OID = 502 ( ">" PGUID 0 b t f 603 603 16 504 505 0 0 box_gt areasel areajoinsel ));
+DATA(insert OID = 503 ( "=" PGUID 0 b t t 603 603 16 503 0 0 0 box_eq areasel areajoinsel ));
+DATA(insert OID = 504 ( "<" PGUID 0 b t f 603 603 16 502 501 0 0 box_lt areasel areajoinsel ));
+DATA(insert OID = 505 ( "<=" PGUID 0 b t f 603 603 16 501 502 0 0 box_le areasel areajoinsel ));
+DATA(insert OID = 506 ( ">^" PGUID 0 b t f 600 600 16 0 0 0 0 point_above intltsel intltjoinsel ));
+DATA(insert OID = 507 ( "<<" PGUID 0 b t f 600 600 16 0 0 0 0 point_left intltsel intltjoinsel ));
+DATA(insert OID = 508 ( ">>" PGUID 0 b t f 600 600 16 0 0 0 0 point_right intltsel intltjoinsel ));
+DATA(insert OID = 509 ( "<^" PGUID 0 b t f 600 600 16 0 0 0 0 point_below intltsel intltjoinsel ));
+DATA(insert OID = 510 ( "~=" PGUID 0 b t f 600 600 16 510 0 0 0 point_eq intltsel intltjoinsel ));
+DATA(insert OID = 511 ( "@" PGUID 0 b t f 600 603 16 0 0 0 0 on_pb intltsel intltjoinsel ));
+DATA(insert OID = 512 ( "@" PGUID 0 b t f 600 602 16 0 0 0 0 on_ppath intltsel intltjoinsel ));
+DATA(insert OID = 513 ( "@@" PGUID 0 l t f 0 603 600 0 0 0 0 box_center intltsel intltjoinsel ));
+DATA(insert OID = 514 ( "*" PGUID 0 b t f 23 23 23 514 0 0 0 int4mul intltsel intltjoinsel ));
+DATA(insert OID = 515 ( "!" PGUID 0 r t f 23 0 23 0 0 0 0 int4fac intltsel intltjoinsel ));
+DATA(insert OID = 516 ( "!!" PGUID 0 l t f 0 23 23 0 0 0 0 int4fac intltsel intltjoinsel ));
+DATA(insert OID = 517 ( "<->" PGUID 0 b t f 600 600 701 517 0 0 0 point_distance intltsel intltjoinsel ));
+DATA(insert OID = 518 ( "<>" PGUID 0 b t f 23 23 16 518 96 0 0 int4ne neqsel neqjoinsel ));
+DATA(insert OID = 519 ( "<>" PGUID 0 b t f 21 21 16 519 94 0 0 int2ne neqsel neqjoinsel ));
+DATA(insert OID = 520 ( ">" PGUID 0 b t f 21 21 16 95 0 0 0 int2gt intgtsel intgtjoinsel ));
+DATA(insert OID = 521 ( ">" PGUID 0 b t f 23 23 16 97 0 0 0 int4gt intgtsel intgtjoinsel ));
+DATA(insert OID = 522 ( "<=" PGUID 0 b t f 21 21 16 524 520 0 0 int2le intltsel intltjoinsel ));
+DATA(insert OID = 523 ( "<=" PGUID 0 b t f 23 23 16 525 521 0 0 int4le intltsel intltjoinsel ));
+DATA(insert OID = 524 ( ">=" PGUID 0 b t f 21 21 16 522 95 0 0 int2ge intgtsel intgtjoinsel ));
+DATA(insert OID = 525 ( ">=" PGUID 0 b t f 23 23 16 523 97 0 0 int4ge intgtsel intgtjoinsel ));
+DATA(insert OID = 526 ( "*" PGUID 0 b t f 21 21 21 526 0 0 0 int2mul intltsel intltjoinsel ));
+DATA(insert OID = 527 ( "/" PGUID 0 b t f 21 21 21 0 0 0 0 int2div intltsel intltjoinsel ));
+DATA(insert OID = 528 ( "/" PGUID 0 b t f 23 23 23 0 0 0 0 int4div intltsel intltjoinsel ));
+DATA(insert OID = 529 ( "%" PGUID 0 b t f 21 21 21 6 0 0 0 int2mod intltsel intltjoinsel ));
+DATA(insert OID = 530 ( "%" PGUID 0 b t f 23 23 23 6 0 0 0 int4mod intltsel intltjoinsel ));
+DATA(insert OID = 531 ( "<>" PGUID 0 b t f 25 25 16 531 98 0 0 textne neqsel neqjoinsel ));
+DATA(insert OID = 532 ( "=" PGUID 0 b t t 21 23 16 533 538 95 97 int24eq eqsel eqjoinsel ));
+DATA(insert OID = 533 ( "=" PGUID 0 b t t 23 21 16 532 539 97 95 int42eq eqsel eqjoinsel ));
+DATA(insert OID = 534 ( "<" PGUID 0 b t f 21 23 16 537 542 0 0 int24lt intltsel intltjoinsel ));
+DATA(insert OID = 535 ( "<" PGUID 0 b t f 23 21 16 536 543 0 0 int42lt intltsel intltjoinsel ));
+DATA(insert OID = 536 ( ">" PGUID 0 b t f 21 23 16 535 540 0 0 int24gt intgtsel intgtjoinsel ));
+DATA(insert OID = 537 ( ">" PGUID 0 b t f 23 21 16 534 541 0 0 int42gt intgtsel intgtjoinsel ));
+DATA(insert OID = 538 ( "<>" PGUID 0 b t f 21 23 16 539 532 0 0 int24ne neqsel neqjoinsel ));
+DATA(insert OID = 539 ( "<>" PGUID 0 b t f 23 21 16 538 533 0 0 int42ne neqsel neqjoinsel ));
+DATA(insert OID = 540 ( "<=" PGUID 0 b t f 21 23 16 543 536 0 0 int24le intltsel intltjoinsel ));
+DATA(insert OID = 541 ( "<=" PGUID 0 b t f 23 21 16 542 537 0 0 int42le intltsel intltjoinsel ));
+DATA(insert OID = 542 ( ">=" PGUID 0 b t f 21 23 16 541 534 0 0 int24ge intgtsel intgtjoinsel ));
+DATA(insert OID = 543 ( ">=" PGUID 0 b t f 23 21 16 540 535 0 0 int42ge intgtsel intgtjoinsel ));
+DATA(insert OID = 544 ( "*" PGUID 0 b t f 21 23 23 545 0 0 0 int24mul intltsel intltjoinsel ));
+DATA(insert OID = 545 ( "*" PGUID 0 b t f 23 21 23 544 0 0 0 int42mul intltsel intltjoinsel ));
+DATA(insert OID = 546 ( "/" PGUID 0 b t f 21 23 23 0 0 0 0 int24div intltsel intltjoinsel ));
+DATA(insert OID = 547 ( "/" PGUID 0 b t f 23 21 23 0 0 0 0 int42div intltsel intltjoinsel ));
+DATA(insert OID = 548 ( "%" PGUID 0 b t f 21 23 23 6 0 0 0 int24mod intltsel intltjoinsel ));
+DATA(insert OID = 549 ( "%" PGUID 0 b t f 23 21 23 6 0 0 0 int42mod intltsel intltjoinsel ));
+DATA(insert OID = 550 ( "+" PGUID 0 b t f 21 21 21 550 0 0 0 int2pl intltsel intltjoinsel ));
+DATA(insert OID = 551 ( "+" PGUID 0 b t f 23 23 23 551 0 0 0 int4pl intltsel intltjoinsel ));
+DATA(insert OID = 552 ( "+" PGUID 0 b t f 21 23 23 553 0 0 0 int24pl intltsel intltjoinsel ));
+DATA(insert OID = 553 ( "+" PGUID 0 b t f 23 21 23 552 0 0 0 int42pl intltsel intltjoinsel ));
+DATA(insert OID = 554 ( "-" PGUID 0 b t f 21 21 21 0 0 0 0 int2mi intltsel intltjoinsel ));
+DATA(insert OID = 555 ( "-" PGUID 0 b t f 23 23 23 0 0 0 0 int4mi intltsel intltjoinsel ));
+DATA(insert OID = 556 ( "-" PGUID 0 b t f 21 23 23 0 0 0 0 int24mi intltsel intltjoinsel ));
+DATA(insert OID = 557 ( "-" PGUID 0 b t f 23 21 23 0 0 0 0 int42mi intltsel intltjoinsel ));
+DATA(insert OID = 558 ( "-" PGUID 0 l t f 0 23 23 0 0 0 0 int4um intltsel intltjoinsel ));
+DATA(insert OID = 559 ( "-" PGUID 0 l t f 0 21 21 0 0 0 0 int2um intltsel intltjoinsel ));
+DATA(insert OID = 560 ( "=" PGUID 0 b t t 702 702 16 560 561 562 562 abstimeeq eqsel eqjoinsel ));
+DATA(insert OID = 561 ( "<>" PGUID 0 b t f 702 702 16 561 560 0 0 abstimene neqsel neqjoinsel ));
+DATA(insert OID = 562 ( "<" PGUID 0 b t f 702 702 16 563 565 0 0 abstimelt intltsel intltjoinsel ));
+DATA(insert OID = 563 ( ">" PGUID 0 b t f 702 702 16 562 564 0 0 abstimegt intltsel intltjoinsel ));
+DATA(insert OID = 564 ( "<=" PGUID 0 b t f 702 702 16 565 563 0 0 abstimele intltsel intltjoinsel ));
+DATA(insert OID = 565 ( ">=" PGUID 0 b t f 702 702 16 564 562 0 0 abstimege intltsel intltjoinsel ));
+DATA(insert OID = 566 ( "=" PGUID 0 b t t 703 703 16 566 567 568 568 reltimeeq - - ));
+DATA(insert OID = 567 ( "<>" PGUID 0 b t f 703 703 16 567 566 0 0 reltimene - - ));
+DATA(insert OID = 568 ( "<" PGUID 0 b t f 703 703 16 569 571 0 0 reltimelt - - ));
+DATA(insert OID = 569 ( ">" PGUID 0 b t f 703 703 16 568 570 0 0 reltimegt - - ));
+DATA(insert OID = 570 ( "<=" PGUID 0 b t f 703 703 16 571 569 0 0 reltimele - - ));
+DATA(insert OID = 571 ( ">=" PGUID 0 b t f 703 703 16 570 568 0 0 reltimege - - ));
+DATA(insert OID = 572 ( "=" PGUID 0 b t t 704 704 16 572 0 0 0 intervaleq - - ));
+DATA(insert OID = 573 ( "<<" PGUID 0 b t f 704 704 16 0 0 0 0 intervalct - - ));
+DATA(insert OID = 574 ( "&&" PGUID 0 b t f 704 704 16 0 0 0 0 intervalov - - ));
+DATA(insert OID = 575 ( "#=" PGUID 0 b t f 704 703 16 0 576 0 568 intervalleneq - - ));
+DATA(insert OID = 576 ( "#<>" PGUID 0 b t f 704 703 16 0 575 0 568 intervallenne - - ));
+DATA(insert OID = 577 ( "#<" PGUID 0 b t f 704 703 16 0 580 0 568 intervallenlt - - ));
+DATA(insert OID = 578 ( "#>" PGUID 0 b t f 704 703 16 0 579 0 568 intervallengt - - ));
+DATA(insert OID = 579 ( "#<=" PGUID 0 b t f 704 703 16 0 578 0 568 intervallenle - - ));
+DATA(insert OID = 580 ( "#>=" PGUID 0 b t f 704 703 16 0 577 0 568 intervallenge - - ));
+DATA(insert OID = 581 ( "+" PGUID 0 b t f 702 703 702 581 0 0 0 timepl - - ));
+DATA(insert OID = 582 ( "-" PGUID 0 b t f 702 703 702 0 0 0 0 timemi - - ));
+DATA(insert OID = 583 ( "<?>" PGUID 0 b t f 702 704 16 0 0 562 0 ininterval - - ));
+DATA(insert OID = 584 ( "-" PGUID 0 l t f 0 700 700 0 0 0 0 float4um - - ));
+DATA(insert OID = 585 ( "-" PGUID 0 l t f 0 701 701 0 0 0 0 float8um - - ));
+DATA(insert OID = 586 ( "+" PGUID 0 b t f 700 700 700 586 0 0 0 float4pl - - ));
+DATA(insert OID = 587 ( "-" PGUID 0 b t f 700 700 700 0 0 0 0 float4mi - - ));
+DATA(insert OID = 588 ( "/" PGUID 0 b t f 700 700 700 0 0 0 0 float4div - - ));
+DATA(insert OID = 589 ( "*" PGUID 0 b t f 700 700 700 589 0 0 0 float4mul - - ));
+DATA(insert OID = 590 ( "@" PGUID 0 l t f 0 700 700 0 0 0 0 float4abs - - ));
+DATA(insert OID = 591 ( "+" PGUID 0 b t f 701 701 701 591 0 0 0 float8pl - - ));
+DATA(insert OID = 592 ( "-" PGUID 0 b t f 701 701 701 0 0 0 0 float8mi - - ));
+DATA(insert OID = 593 ( "/" PGUID 0 b t f 701 701 701 0 0 0 0 float8div - - ));
+DATA(insert OID = 594 ( "*" PGUID 0 b t f 701 701 701 594 0 0 0 float8mul - - ));
+DATA(insert OID = 595 ( "@" PGUID 0 l t f 0 701 701 0 0 0 0 float8abs - - ));
+DATA(insert OID = 596 ( "|/" PGUID 0 l t f 0 701 701 0 0 0 0 dsqrt - - ));
+DATA(insert OID = 597 ( "||/" PGUID 0 l t f 0 701 701 0 0 0 0 dcbrt - - ));
+DATA(insert OID = 598 ( "%" PGUID 0 l t f 0 701 701 0 0 0 0 dtrunc - - ));
+DATA(insert OID = 599 ( "%" PGUID 0 r t f 701 0 701 0 0 0 0 dround - - ));
+DATA(insert OID = 1282 ( ":" PGUID 0 l t f 0 701 701 0 0 0 0 dexp - - ));
+DATA(insert OID = 1283 ( ";" PGUID 0 l t f 0 701 701 0 0 0 0 dlog1 - - ));
+DATA(insert OID = 1284 ( "|" PGUID 0 l t f 0 704 702 0 0 0 0 intervalstart - - ));
+DATA(insert OID = 606 ( "<#>" PGUID 0 b t f 702 702 704 0 0 0 0 mktinterval - - ));
+DATA(insert OID = 607 ( "=" PGUID 0 b t t 26 26 16 607 608 97 97 oideq eqsel eqjoinsel ));
+#define OIDEqualOperator 607 /* XXX planner/prep/semanopt.c crock */
+DATA(insert OID = 608 ( "<>" PGUID 0 b t f 26 26 16 608 607 0 0 oidne neqsel neqjoinsel ));
+DATA(insert OID = 609 ( "<" PGUID 0 b t f 26 26 16 610 612 0 0 int4lt intltsel intltjoinsel ));
+DATA(insert OID = 610 ( ">" PGUID 0 b t f 26 26 16 609 611 0 0 int4gt intgtsel intgtjoinsel ));
+DATA(insert OID = 611 ( "<=" PGUID 0 b t f 26 26 16 612 610 0 0 int4le intltsel intltjoinsel ));
+DATA(insert OID = 612 ( ">=" PGUID 0 b t f 26 26 16 611 609 0 0 int4ge intgtsel intgtjoinsel ));
+
+DATA(insert OID = 613 ( "<->" PGUID 0 b t f 600 603 701 0 0 0 0 dist_pl - - ));
+DATA(insert OID = 614 ( "<->" PGUID 0 b t f 600 601 701 0 0 0 0 dist_ps - - ));
+DATA(insert OID = 615 ( "<->" PGUID 0 b t f 600 603 701 0 0 0 0 dist_pb - - ));
+DATA(insert OID = 616 ( "<->" PGUID 0 b t f 601 628 701 0 0 0 0 dist_sl - - ));
+DATA(insert OID = 617 ( "<->" PGUID 0 b t f 601 603 701 0 0 0 0 dist_sb - - ));
+DATA(insert OID = 618 ( "<->" PGUID 0 b t f 600 602 701 0 0 0 0 dist_ppath - - ));
+
+DATA(insert OID = 619 ( "<" PGUID 0 b t f 704 704 16 0 0 0 0 intervalct - - ));
+
+DATA(insert OID = 620 ( "=" PGUID 0 b t t 700 700 16 620 621 622 622 float4eq eqsel eqjoinsel ));
+DATA(insert OID = 621 ( "<>" PGUID 0 b t f 700 700 16 621 620 0 0 float4ne neqsel neqjoinsel ));
+DATA(insert OID = 622 ( "<" PGUID 0 b t f 700 700 16 623 625 0 0 float4lt intltsel intltjoinsel ));
+DATA(insert OID = 623 ( ">" PGUID 0 b t f 700 700 16 622 624 0 0 float4gt intgtsel intgtjoinsel ));
+DATA(insert OID = 624 ( "<=" PGUID 0 b t f 700 700 16 625 623 0 0 float4le intltsel intltjoinsel ));
+DATA(insert OID = 625 ( ">=" PGUID 0 b t f 700 700 16 624 622 0 0 float4ge intgtsel intgtjoinsel ));
+DATA(insert OID = 626 ( "!!=" PGUID 0 b t f 23 19 16 0 0 0 0 int4notin "-" "-"));
+DATA(insert OID = 627 ( "!!=" PGUID 0 b t f 26 19 16 0 0 0 0 oidnotin "-" "-"));
#define OIDNotInOperator 627 /* XXX planner/prep/semanopt.c crock */
-DATA(insert OID = 630 ( "<>" PGUID 0 b t f 18 18 16 630 92 0 0 charne neqsel neqjoinsel ));
-
-DATA(insert OID = 631 ( "<" PGUID 0 b t f 18 18 16 633 634 0 0 charlt intltsel intltjoinsel ));
-DATA(insert OID = 632 ( "<=" PGUID 0 b t f 18 18 16 634 633 0 0 charle intltsel intltjoinsel ));
-DATA(insert OID = 633 ( ">" PGUID 0 b t f 18 18 16 631 632 0 0 chargt intltsel intltjoinsel ));
-DATA(insert OID = 634 ( ">=" PGUID 0 b t f 18 18 16 632 631 0 0 charge intltsel intltjoinsel ));
-
-DATA(insert OID = 635 ( "+" PGUID 0 b t f 18 18 18 0 0 0 0 charpl eqsel eqjoinsel ));
-DATA(insert OID = 636 ( "-" PGUID 0 b t f 18 18 18 0 0 0 0 charmi eqsel eqjoinsel ));
-DATA(insert OID = 637 ( "*" PGUID 0 b t f 18 18 18 0 0 0 0 charmul eqsel eqjoinsel ));
-DATA(insert OID = 638 ( "/" PGUID 0 b t f 18 18 18 0 0 0 0 chardiv eqsel eqjoinsel ));
-
-DATA(insert OID = 639 ( "~" PGUID 0 b t f 19 25 16 0 640 0 0 nameregexeq eqsel eqjoinsel ));
-DATA(insert OID = 640 ( "!~" PGUID 0 b t f 19 25 16 0 639 0 0 nameregexne neqsel neqjoinsel ));
-DATA(insert OID = 641 ( "~" PGUID 0 b t f 25 25 16 0 642 0 0 textregexeq eqsel eqjoinsel ));
-DATA(insert OID = 642 ( "!~" PGUID 0 b t f 25 25 16 0 641 0 0 textregexne eqsel eqjoinsel ));
-DATA(insert OID = 643 ( "<>" PGUID 0 b t f 19 19 16 643 93 0 0 namene neqsel neqjoinsel ));
-DATA(insert OID = 644 ( "<>" PGUID 0 b t f 20 20 16 644 1267 0 0 char16ne neqsel neqjoinsel ));
-DATA(insert OID = 645 ( "<" PGUID 0 b t f 20 20 16 647 648 0 0 char16lt intltsel intltjoinsel ));
-DATA(insert OID = 646 ( "<=" PGUID 0 b t f 20 20 16 648 647 0 0 char16le intltsel intltjoinsel ));
-DATA(insert OID = 647 ( ">" PGUID 0 b t f 20 20 16 645 646 0 0 char16gt intltsel intltjoinsel ));
-DATA(insert OID = 648 ( ">=" PGUID 0 b t f 20 20 16 646 645 0 0 char16ge intltsel intltjoinsel ));
-DATA(insert OID = 649 ( "~" PGUID 0 b t f 20 25 16 0 650 0 0 char16regexeq intltsel intltjoinsel ));
-DATA(insert OID = 650 ( "!~" PGUID 0 b t f 20 25 16 650 0 0 0 char16regexne intltsel intltjoinsel ));
-DATA(insert OID = 651 ( "~~" PGUID 0 b t f 20 25 16 0 651 0 0 char16like eqsel eqjoinsel ));
-DATA(insert OID = 652 ( "!~~" PGUID 0 b t f 20 25 16 651 0 0 0 char16nlike neqsel neqjoinsel ));
-DATA(insert OID = 654 ( "||" PGUID 0 b t f 25 25 25 0 0 0 0 textcat - - ));
-
-DATA(insert OID = 660 ( "<" PGUID 0 b t f 19 19 16 662 663 0 0 namelt intltsel intltjoinsel ));
-DATA(insert OID = 661 ( "<=" PGUID 0 b t f 19 19 16 663 662 0 0 namele intltsel intltjoinsel ));
-DATA(insert OID = 662 ( ">" PGUID 0 b t f 19 19 16 660 661 0 0 namegt intltsel intltjoinsel ));
-DATA(insert OID = 663 ( ">=" PGUID 0 b t f 19 19 16 661 660 0 0 namege intltsel intltjoinsel ));
-DATA(insert OID = 664 ( "<" PGUID 0 b t f 25 25 16 666 667 0 0 text_lt intltsel intltjoinsel ));
-DATA(insert OID = 665 ( "<=" PGUID 0 b t f 25 25 16 667 666 0 0 text_le intltsel intltjoinsel ));
-DATA(insert OID = 666 ( ">" PGUID 0 b t f 25 25 16 664 665 0 0 text_gt intltsel intltjoinsel ));
-DATA(insert OID = 667 ( ">=" PGUID 0 b t f 25 25 16 665 664 0 0 text_ge intltsel intltjoinsel ));
-
-DATA(insert OID = 670 ( "=" PGUID 0 b t f 701 701 16 670 671 0 0 float8eq eqsel eqjoinsel ));
-DATA(insert OID = 671 ( "<>" PGUID 0 b t f 701 701 16 671 670 0 0 float8ne neqsel neqjoinsel ));
-DATA(insert OID = 672 ( "<" PGUID 0 b t f 701 701 16 674 675 0 0 float8lt intltsel intltjoinsel ));
-DATA(insert OID = 673 ( "<=" PGUID 0 b t f 701 701 16 675 674 0 0 float8le intltsel intltjoinsel ));
-DATA(insert OID = 674 ( ">" PGUID 0 b t f 701 701 16 672 673 0 0 float8gt intltsel intltjoinsel ));
-DATA(insert OID = 675 ( ">=" PGUID 0 b t f 701 701 16 673 672 0 0 float8ge intltsel intltjoinsel ));
-
-DATA(insert OID = 676 ( "<" PGUID 0 b t f 911 911 16 680 679 0 0 oidnamelt intltsel intltjoinsel ));
-DATA(insert OID = 677 ( "<=" PGUID 0 b t f 911 911 16 679 680 0 0 oidnamele intltsel intltjoinsel ));
-DATA(insert OID = 678 ( "=" PGUID 0 b t f 911 911 16 678 681 0 0 oidnameeq intltsel intltjoinsel ));
-DATA(insert OID = 679 ( ">=" PGUID 0 b t f 911 911 16 677 676 0 0 oidnamege intltsel intltjoinsel ));
-DATA(insert OID = 680 ( ">" PGUID 0 b t f 911 911 16 676 677 0 0 oidnamegt intltsel intltjoinsel ));
-DATA(insert OID = 681 ( "<>" PGUID 0 b t f 911 911 16 681 678 0 0 oidnamene intltsel intltjoinsel ));
-
-DATA(insert OID = 697 ( "~" PGUID 0 b t f 411 25 16 0 698 0 0 char8regexeq eqsel eqjoinsel ));
-DATA(insert OID = 698 ( "!~" PGUID 0 b t f 411 25 16 0 697 0 0 char8regexne neqsel neqjoinsel ));
-
-DATA(insert OID = 706 ( "<->" PGUID 0 b t f 603 603 701 706 0 0 0 box_distance intltsel intltjoinsel ));
-DATA(insert OID = 707 ( "<->" PGUID 0 b t f 602 602 701 707 0 0 0 path_distance intltsel intltjoinsel ));
-DATA(insert OID = 708 ( "<->" PGUID 0 b t f 628 628 701 708 0 0 0 line_distance intltsel intltjoinsel ));
-DATA(insert OID = 709 ( "<->" PGUID 0 b t f 601 601 701 709 0 0 0 lseg_distance intltsel intltjoinsel ));
-DATA(insert OID = 712 ( "<->" PGUID 0 b t f 604 604 701 712 0 0 0 poly_distance intltsel intltjoinsel ));
+DATA(insert OID = 630 ( "<>" PGUID 0 b t f 18 18 16 630 92 0 0 charne neqsel neqjoinsel ));
+
+DATA(insert OID = 631 ( "<" PGUID 0 b t f 18 18 16 633 634 0 0 charlt intltsel intltjoinsel ));
+DATA(insert OID = 632 ( "<=" PGUID 0 b t f 18 18 16 634 633 0 0 charle intltsel intltjoinsel ));
+DATA(insert OID = 633 ( ">" PGUID 0 b t f 18 18 16 631 632 0 0 chargt intltsel intltjoinsel ));
+DATA(insert OID = 634 ( ">=" PGUID 0 b t f 18 18 16 632 631 0 0 charge intltsel intltjoinsel ));
+
+DATA(insert OID = 635 ( "+" PGUID 0 b t f 18 18 18 0 0 0 0 charpl eqsel eqjoinsel ));
+DATA(insert OID = 636 ( "-" PGUID 0 b t f 18 18 18 0 0 0 0 charmi eqsel eqjoinsel ));
+DATA(insert OID = 637 ( "*" PGUID 0 b t f 18 18 18 0 0 0 0 charmul eqsel eqjoinsel ));
+DATA(insert OID = 638 ( "/" PGUID 0 b t f 18 18 18 0 0 0 0 chardiv eqsel eqjoinsel ));
+
+DATA(insert OID = 639 ( "~" PGUID 0 b t f 19 25 16 0 640 0 0 nameregexeq eqsel eqjoinsel ));
+DATA(insert OID = 640 ( "!~" PGUID 0 b t f 19 25 16 0 639 0 0 nameregexne neqsel neqjoinsel ));
+DATA(insert OID = 641 ( "~" PGUID 0 b t f 25 25 16 0 642 0 0 textregexeq eqsel eqjoinsel ));
+DATA(insert OID = 642 ( "!~" PGUID 0 b t f 25 25 16 0 641 0 0 textregexne eqsel eqjoinsel ));
+DATA(insert OID = 643 ( "<>" PGUID 0 b t f 19 19 16 643 93 0 0 namene neqsel neqjoinsel ));
+DATA(insert OID = 644 ( "<>" PGUID 0 b t f 20 20 16 644 1267 0 0 char16ne neqsel neqjoinsel ));
+DATA(insert OID = 645 ( "<" PGUID 0 b t f 20 20 16 647 648 0 0 char16lt intltsel intltjoinsel ));
+DATA(insert OID = 646 ( "<=" PGUID 0 b t f 20 20 16 648 647 0 0 char16le intltsel intltjoinsel ));
+DATA(insert OID = 647 ( ">" PGUID 0 b t f 20 20 16 645 646 0 0 char16gt intltsel intltjoinsel ));
+DATA(insert OID = 648 ( ">=" PGUID 0 b t f 20 20 16 646 645 0 0 char16ge intltsel intltjoinsel ));
+DATA(insert OID = 649 ( "~" PGUID 0 b t f 20 25 16 0 650 0 0 char16regexeq intltsel intltjoinsel ));
+DATA(insert OID = 650 ( "!~" PGUID 0 b t f 20 25 16 650 0 0 0 char16regexne intltsel intltjoinsel ));
+DATA(insert OID = 651 ( "~~" PGUID 0 b t f 20 25 16 0 651 0 0 char16like eqsel eqjoinsel ));
+DATA(insert OID = 652 ( "!~~" PGUID 0 b t f 20 25 16 651 0 0 0 char16nlike neqsel neqjoinsel ));
+DATA(insert OID = 654 ( "||" PGUID 0 b t f 25 25 25 0 0 0 0 textcat - - ));
+
+DATA(insert OID = 660 ( "<" PGUID 0 b t f 19 19 16 662 663 0 0 namelt intltsel intltjoinsel ));
+DATA(insert OID = 661 ( "<=" PGUID 0 b t f 19 19 16 663 662 0 0 namele intltsel intltjoinsel ));
+DATA(insert OID = 662 ( ">" PGUID 0 b t f 19 19 16 660 661 0 0 namegt intltsel intltjoinsel ));
+DATA(insert OID = 663 ( ">=" PGUID 0 b t f 19 19 16 661 660 0 0 namege intltsel intltjoinsel ));
+DATA(insert OID = 664 ( "<" PGUID 0 b t f 25 25 16 666 667 0 0 text_lt intltsel intltjoinsel ));
+DATA(insert OID = 665 ( "<=" PGUID 0 b t f 25 25 16 667 666 0 0 text_le intltsel intltjoinsel ));
+DATA(insert OID = 666 ( ">" PGUID 0 b t f 25 25 16 664 665 0 0 text_gt intltsel intltjoinsel ));
+DATA(insert OID = 667 ( ">=" PGUID 0 b t f 25 25 16 665 664 0 0 text_ge intltsel intltjoinsel ));
+
+DATA(insert OID = 670 ( "=" PGUID 0 b t f 701 701 16 670 671 0 0 float8eq eqsel eqjoinsel ));
+DATA(insert OID = 671 ( "<>" PGUID 0 b t f 701 701 16 671 670 0 0 float8ne neqsel neqjoinsel ));
+DATA(insert OID = 672 ( "<" PGUID 0 b t f 701 701 16 674 675 0 0 float8lt intltsel intltjoinsel ));
+DATA(insert OID = 673 ( "<=" PGUID 0 b t f 701 701 16 675 674 0 0 float8le intltsel intltjoinsel ));
+DATA(insert OID = 674 ( ">" PGUID 0 b t f 701 701 16 672 673 0 0 float8gt intltsel intltjoinsel ));
+DATA(insert OID = 675 ( ">=" PGUID 0 b t f 701 701 16 673 672 0 0 float8ge intltsel intltjoinsel ));
+
+DATA(insert OID = 676 ( "<" PGUID 0 b t f 911 911 16 680 679 0 0 oidnamelt intltsel intltjoinsel ));
+DATA(insert OID = 677 ( "<=" PGUID 0 b t f 911 911 16 679 680 0 0 oidnamele intltsel intltjoinsel ));
+DATA(insert OID = 678 ( "=" PGUID 0 b t f 911 911 16 678 681 0 0 oidnameeq intltsel intltjoinsel ));
+DATA(insert OID = 679 ( ">=" PGUID 0 b t f 911 911 16 677 676 0 0 oidnamege intltsel intltjoinsel ));
+DATA(insert OID = 680 ( ">" PGUID 0 b t f 911 911 16 676 677 0 0 oidnamegt intltsel intltjoinsel ));
+DATA(insert OID = 681 ( "<>" PGUID 0 b t f 911 911 16 681 678 0 0 oidnamene intltsel intltjoinsel ));
+
+DATA(insert OID = 697 ( "~" PGUID 0 b t f 411 25 16 0 698 0 0 char8regexeq eqsel eqjoinsel ));
+DATA(insert OID = 698 ( "!~" PGUID 0 b t f 411 25 16 0 697 0 0 char8regexne neqsel neqjoinsel ));
+
+DATA(insert OID = 706 ( "<->" PGUID 0 b t f 603 603 701 706 0 0 0 box_distance intltsel intltjoinsel ));
+DATA(insert OID = 707 ( "<->" PGUID 0 b t f 602 602 701 707 0 0 0 path_distance intltsel intltjoinsel ));
+DATA(insert OID = 708 ( "<->" PGUID 0 b t f 628 628 701 708 0 0 0 line_distance intltsel intltjoinsel ));
+DATA(insert OID = 709 ( "<->" PGUID 0 b t f 601 601 701 709 0 0 0 lseg_distance intltsel intltjoinsel ));
+DATA(insert OID = 712 ( "<->" PGUID 0 b t f 604 604 701 712 0 0 0 poly_distance intltsel intltjoinsel ));
/* add translation/rotation/scaling operators for geometric types. - thomas 97/05/10 */
-DATA(insert OID = 731 ( "+" PGUID 0 b t f 600 600 600 731 0 0 0 point_add - - ));
-DATA(insert OID = 732 ( "-" PGUID 0 b t f 600 600 600 0 0 0 0 point_sub - - ));
-DATA(insert OID = 733 ( "*" PGUID 0 b t f 600 600 600 733 0 0 0 point_mul - - ));
-DATA(insert OID = 734 ( "/" PGUID 0 b t f 600 600 600 0 0 0 0 point_div - - ));
-DATA(insert OID = 735 ( "+" PGUID 0 b t f 602 602 602 735 0 0 0 path_add - - ));
-DATA(insert OID = 736 ( "+" PGUID 0 b t f 602 600 602 736 0 0 0 path_add_pt - - ));
-DATA(insert OID = 737 ( "-" PGUID 0 b t f 602 600 602 0 0 0 0 path_sub_pt - - ));
-DATA(insert OID = 738 ( "*" PGUID 0 b t f 602 600 602 738 0 0 0 path_mul_pt - - ));
-DATA(insert OID = 739 ( "/" PGUID 0 b t f 602 600 602 0 0 0 0 path_div_pt - - ));
-DATA(insert OID = 754 ( "@" PGUID 0 b t f 600 602 16 755 0 0 0 pt_contained_path - - ));
-DATA(insert OID = 755 ( "~" PGUID 0 b t f 602 600 16 754 0 0 0 path_contain_pt - - ));
-DATA(insert OID = 756 ( "@" PGUID 0 b t f 600 604 16 757 0 0 0 pt_contained_poly - - ));
-DATA(insert OID = 757 ( "~" PGUID 0 b t f 604 600 16 756 0 0 0 poly_contain_pt - - ));
-DATA(insert OID = 758 ( "@" PGUID 0 b t f 600 718 16 759 0 0 0 pt_contained_circle - - ));
-DATA(insert OID = 759 ( "~" PGUID 0 b t f 718 600 16 758 0 0 0 circle_contain_pt - - ));
+DATA(insert OID = 731 ( "+" PGUID 0 b t f 600 600 600 731 0 0 0 point_add - - ));
+DATA(insert OID = 732 ( "-" PGUID 0 b t f 600 600 600 0 0 0 0 point_sub - - ));
+DATA(insert OID = 733 ( "*" PGUID 0 b t f 600 600 600 733 0 0 0 point_mul - - ));
+DATA(insert OID = 734 ( "/" PGUID 0 b t f 600 600 600 0 0 0 0 point_div - - ));
+DATA(insert OID = 735 ( "+" PGUID 0 b t f 602 602 602 735 0 0 0 path_add - - ));
+DATA(insert OID = 736 ( "+" PGUID 0 b t f 602 600 602 736 0 0 0 path_add_pt - - ));
+DATA(insert OID = 737 ( "-" PGUID 0 b t f 602 600 602 0 0 0 0 path_sub_pt - - ));
+DATA(insert OID = 738 ( "*" PGUID 0 b t f 602 600 602 738 0 0 0 path_mul_pt - - ));
+DATA(insert OID = 739 ( "/" PGUID 0 b t f 602 600 602 0 0 0 0 path_div_pt - - ));
+DATA(insert OID = 754 ( "@" PGUID 0 b t f 600 602 16 755 0 0 0 pt_contained_path - - ));
+DATA(insert OID = 755 ( "~" PGUID 0 b t f 602 600 16 754 0 0 0 path_contain_pt - - ));
+DATA(insert OID = 756 ( "@" PGUID 0 b t f 600 604 16 757 0 0 0 pt_contained_poly - - ));
+DATA(insert OID = 757 ( "~" PGUID 0 b t f 604 600 16 756 0 0 0 poly_contain_pt - - ));
+DATA(insert OID = 758 ( "@" PGUID 0 b t f 600 718 16 759 0 0 0 pt_contained_circle - - ));
+DATA(insert OID = 759 ( "~" PGUID 0 b t f 718 600 16 758 0 0 0 circle_contain_pt - - ));
/* additional operators for geometric types - thomas 1997-07-09 */
-DATA(insert OID = 792 ( "=" PGUID 0 b t f 602 602 701 792 0 0 0 path_n_eq intltsel intltjoinsel ));
-DATA(insert OID = 793 ( "<" PGUID 0 b t f 602 602 701 796 0 0 0 path_n_lt intltsel intltjoinsel ));
-DATA(insert OID = 794 ( ">" PGUID 0 b t f 602 602 701 795 0 0 0 path_n_gt intltsel intltjoinsel ));
-DATA(insert OID = 795 ( "<=" PGUID 0 b t f 602 602 701 794 0 0 0 path_n_le intltsel intltjoinsel ));
-DATA(insert OID = 796 ( ">=" PGUID 0 b t f 602 602 701 793 0 0 0 path_n_ge intltsel intltjoinsel ));
-DATA(insert OID = 797 ( "#" PGUID 0 l t f 0 602 23 0 0 0 0 path_npoints - - ));
-DATA(insert OID = 798 ( "?#" PGUID 0 b t f 602 602 16 0 0 0 0 path_inter - - ));
-DATA(insert OID = 799 ( "??" PGUID 0 l t f 0 602 701 0 0 0 0 path_length - - ));
-DATA(insert OID = 800 ( ">^" PGUID 0 b t f 603 603 16 0 0 0 0 box_above intltsel intltjoinsel ));
-DATA(insert OID = 801 ( "<^" PGUID 0 b t f 603 603 16 0 0 0 0 box_below intltsel intltjoinsel ));
-DATA(insert OID = 802 ( "?#" PGUID 0 b t f 603 603 16 0 0 0 0 box_overlap - - ));
-DATA(insert OID = 803 ( "#" PGUID 0 b t f 603 603 603 0 0 0 0 box_intersect - - ));
-DATA(insert OID = 804 ( "+" PGUID 0 b t f 603 600 603 804 0 0 0 box_add - - ));
-DATA(insert OID = 805 ( "-" PGUID 0 b t f 603 600 603 0 0 0 0 box_sub - - ));
-DATA(insert OID = 806 ( "*" PGUID 0 b t f 603 600 603 806 0 0 0 box_mul - - ));
-DATA(insert OID = 807 ( "/" PGUID 0 b t f 603 600 603 0 0 0 0 box_div - - ));
-DATA(insert OID = 808 ( "?-" PGUID 0 b t f 600 600 16 808 0 0 0 point_horiz - - ));
-DATA(insert OID = 809 ( "?|" PGUID 0 b t f 600 600 16 809 0 0 0 point_vert - - ));
-
-DATA(insert OID = 830 ( "<" PGUID 0 b t f 810 810 16 834 833 0 0 oidint2lt intltsel intltjoinsel ));
-DATA(insert OID = 831 ( "<=" PGUID 0 b t f 810 810 16 833 834 0 0 oidint2le intltsel intltjoinsel ));
-DATA(insert OID = 832 ( "=" PGUID 0 b t f 810 810 16 832 835 0 0 oidint2eq intltsel intltjoinsel ));
-DATA(insert OID = 833 ( ">=" PGUID 0 b t f 810 810 16 831 830 0 0 oidint2ge intltsel intltjoinsel ));
-DATA(insert OID = 834 ( ">" PGUID 0 b t f 810 810 16 830 831 0 0 oidint2gt intltsel intltjoinsel ));
-DATA(insert OID = 835 ( "<>" PGUID 0 b t f 810 810 16 835 832 0 0 oidint2ne intltsel intltjoinsel ));
-
-DATA(insert OID = 839 ( "~" PGUID 0 b t f 409 25 16 0 841 0 0 char2regexeq eqsel eqjoinsel ));
-DATA(insert OID = 841 ( "!~" PGUID 0 b t f 409 25 16 0 839 0 0 char2regexne neqsel neqjoinsel ));
-DATA(insert OID = 840 ( "~" PGUID 0 b t f 410 25 16 0 842 0 0 char4regexeq eqsel eqjoinsel ));
-DATA(insert OID = 842 ( "!~" PGUID 0 b t f 410 25 16 0 840 0 0 char4regexne neqsel neqjoinsel ));
-
-DATA(insert OID = 900 ( "=" PGUID 0 b t t 790 790 16 900 901 902 902 cash_eq eqsel eqjoinsel ));
-DATA(insert OID = 901 ( "<>" PGUID 0 b t f 790 790 16 901 900 0 0 cash_ne neqsel neqjoinsel ));
-DATA(insert OID = 902 ( "<" PGUID 0 b t f 790 790 16 903 905 0 0 cash_lt intltsel intltjoinsel ));
-DATA(insert OID = 903 ( ">" PGUID 0 b t f 790 790 16 902 904 0 0 cash_gt intgtsel intgtjoinsel ));
-DATA(insert OID = 904 ( "<=" PGUID 0 b t f 790 790 16 905 903 0 0 cash_le intltsel intltjoinsel ));
-DATA(insert OID = 905 ( ">=" PGUID 0 b t f 790 790 16 904 902 0 0 cash_ge intgtsel intgtjoinsel ));
-DATA(insert OID = 906 ( "+" PGUID 0 b t f 790 790 790 906 0 0 0 cash_pl - - ));
-DATA(insert OID = 907 ( "-" PGUID 0 b t f 790 790 790 0 0 0 0 cash_mi - - ));
-DATA(insert OID = 908 ( "*" PGUID 0 b t f 790 701 790 909 0 0 0 cash_mul - - ));
-DATA(insert OID = 909 ( "/" PGUID 0 b t f 790 701 790 0 0 0 0 cash_div - - ));
-
-DATA(insert OID = 930 ( "<" PGUID 0 b t f 910 910 16 934 933 0 0 oidint4lt intltsel intltjoinsel ));
-DATA(insert OID = 931 ( "<=" PGUID 0 b t f 910 910 16 933 934 0 0 oidint4le intltsel intltjoinsel ));
-DATA(insert OID = 932 ( "=" PGUID 0 b t f 910 910 16 932 935 0 0 oidint4eq intltsel intltjoinsel ));
-DATA(insert OID = 933 ( ">=" PGUID 0 b t f 910 910 16 931 930 0 0 oidint4ge intltsel intltjoinsel ));
-DATA(insert OID = 934 ( ">" PGUID 0 b t f 910 910 16 930 931 0 0 oidint4gt intltsel intltjoinsel ));
-DATA(insert OID = 935 ( "<>" PGUID 0 b t f 910 910 16 935 932 0 0 oidint4ne intltsel intltjoinsel ));
-
-DATA(insert OID = 965 ( "^" PGUID 0 b t f 701 701 701 0 0 0 0 dpow - - ));
-DATA(insert OID = 966 ( "+" PGUID 0 b t f 1034 1033 1034 0 0 0 0 aclinsert intltsel intltjoinsel ));
-DATA(insert OID = 967 ( "-" PGUID 0 b t f 1034 1033 1034 0 0 0 0 aclremove intltsel intltjoinsel ));
-DATA(insert OID = 968 ( "~" PGUID 0 b t f 1034 1033 16 0 0 0 0 aclcontains intltsel intltjoinsel ));
+DATA(insert OID = 792 ( "=" PGUID 0 b t f 602 602 701 792 0 0 0 path_n_eq intltsel intltjoinsel ));
+DATA(insert OID = 793 ( "<" PGUID 0 b t f 602 602 701 796 0 0 0 path_n_lt intltsel intltjoinsel ));
+DATA(insert OID = 794 ( ">" PGUID 0 b t f 602 602 701 795 0 0 0 path_n_gt intltsel intltjoinsel ));
+DATA(insert OID = 795 ( "<=" PGUID 0 b t f 602 602 701 794 0 0 0 path_n_le intltsel intltjoinsel ));
+DATA(insert OID = 796 ( ">=" PGUID 0 b t f 602 602 701 793 0 0 0 path_n_ge intltsel intltjoinsel ));
+DATA(insert OID = 797 ( "#" PGUID 0 l t f 0 602 23 0 0 0 0 path_npoints - - ));
+DATA(insert OID = 798 ( "?#" PGUID 0 b t f 602 602 16 0 0 0 0 path_inter - - ));
+DATA(insert OID = 799 ( "??" PGUID 0 l t f 0 602 701 0 0 0 0 path_length - - ));
+DATA(insert OID = 800 ( ">^" PGUID 0 b t f 603 603 16 0 0 0 0 box_above intltsel intltjoinsel ));
+DATA(insert OID = 801 ( "<^" PGUID 0 b t f 603 603 16 0 0 0 0 box_below intltsel intltjoinsel ));
+DATA(insert OID = 802 ( "?#" PGUID 0 b t f 603 603 16 0 0 0 0 box_overlap - - ));
+DATA(insert OID = 803 ( "#" PGUID 0 b t f 603 603 603 0 0 0 0 box_intersect - - ));
+DATA(insert OID = 804 ( "+" PGUID 0 b t f 603 600 603 804 0 0 0 box_add - - ));
+DATA(insert OID = 805 ( "-" PGUID 0 b t f 603 600 603 0 0 0 0 box_sub - - ));
+DATA(insert OID = 806 ( "*" PGUID 0 b t f 603 600 603 806 0 0 0 box_mul - - ));
+DATA(insert OID = 807 ( "/" PGUID 0 b t f 603 600 603 0 0 0 0 box_div - - ));
+DATA(insert OID = 808 ( "?-" PGUID 0 b t f 600 600 16 808 0 0 0 point_horiz - - ));
+DATA(insert OID = 809 ( "?|" PGUID 0 b t f 600 600 16 809 0 0 0 point_vert - - ));
+
+DATA(insert OID = 830 ( "<" PGUID 0 b t f 810 810 16 834 833 0 0 oidint2lt intltsel intltjoinsel ));
+DATA(insert OID = 831 ( "<=" PGUID 0 b t f 810 810 16 833 834 0 0 oidint2le intltsel intltjoinsel ));
+DATA(insert OID = 832 ( "=" PGUID 0 b t f 810 810 16 832 835 0 0 oidint2eq intltsel intltjoinsel ));
+DATA(insert OID = 833 ( ">=" PGUID 0 b t f 810 810 16 831 830 0 0 oidint2ge intltsel intltjoinsel ));
+DATA(insert OID = 834 ( ">" PGUID 0 b t f 810 810 16 830 831 0 0 oidint2gt intltsel intltjoinsel ));
+DATA(insert OID = 835 ( "<>" PGUID 0 b t f 810 810 16 835 832 0 0 oidint2ne intltsel intltjoinsel ));
+
+DATA(insert OID = 839 ( "~" PGUID 0 b t f 409 25 16 0 841 0 0 char2regexeq eqsel eqjoinsel ));
+DATA(insert OID = 841 ( "!~" PGUID 0 b t f 409 25 16 0 839 0 0 char2regexne neqsel neqjoinsel ));
+DATA(insert OID = 840 ( "~" PGUID 0 b t f 410 25 16 0 842 0 0 char4regexeq eqsel eqjoinsel ));
+DATA(insert OID = 842 ( "!~" PGUID 0 b t f 410 25 16 0 840 0 0 char4regexne neqsel neqjoinsel ));
+
+DATA(insert OID = 900 ( "=" PGUID 0 b t t 790 790 16 900 901 902 902 cash_eq eqsel eqjoinsel ));
+DATA(insert OID = 901 ( "<>" PGUID 0 b t f 790 790 16 901 900 0 0 cash_ne neqsel neqjoinsel ));
+DATA(insert OID = 902 ( "<" PGUID 0 b t f 790 790 16 903 905 0 0 cash_lt intltsel intltjoinsel ));
+DATA(insert OID = 903 ( ">" PGUID 0 b t f 790 790 16 902 904 0 0 cash_gt intgtsel intgtjoinsel ));
+DATA(insert OID = 904 ( "<=" PGUID 0 b t f 790 790 16 905 903 0 0 cash_le intltsel intltjoinsel ));
+DATA(insert OID = 905 ( ">=" PGUID 0 b t f 790 790 16 904 902 0 0 cash_ge intgtsel intgtjoinsel ));
+DATA(insert OID = 906 ( "+" PGUID 0 b t f 790 790 790 906 0 0 0 cash_pl - - ));
+DATA(insert OID = 907 ( "-" PGUID 0 b t f 790 790 790 0 0 0 0 cash_mi - - ));
+DATA(insert OID = 908 ( "*" PGUID 0 b t f 790 701 790 909 0 0 0 cash_mul - - ));
+DATA(insert OID = 909 ( "/" PGUID 0 b t f 790 701 790 0 0 0 0 cash_div - - ));
+
+DATA(insert OID = 930 ( "<" PGUID 0 b t f 910 910 16 934 933 0 0 oidint4lt intltsel intltjoinsel ));
+DATA(insert OID = 931 ( "<=" PGUID 0 b t f 910 910 16 933 934 0 0 oidint4le intltsel intltjoinsel ));
+DATA(insert OID = 932 ( "=" PGUID 0 b t f 910 910 16 932 935 0 0 oidint4eq intltsel intltjoinsel ));
+DATA(insert OID = 933 ( ">=" PGUID 0 b t f 910 910 16 931 930 0 0 oidint4ge intltsel intltjoinsel ));
+DATA(insert OID = 934 ( ">" PGUID 0 b t f 910 910 16 930 931 0 0 oidint4gt intltsel intltjoinsel ));
+DATA(insert OID = 935 ( "<>" PGUID 0 b t f 910 910 16 935 932 0 0 oidint4ne intltsel intltjoinsel ));
+
+DATA(insert OID = 965 ( "^" PGUID 0 b t f 701 701 701 0 0 0 0 dpow - - ));
+DATA(insert OID = 966 ( "+" PGUID 0 b t f 1034 1033 1034 0 0 0 0 aclinsert intltsel intltjoinsel ));
+DATA(insert OID = 967 ( "-" PGUID 0 b t f 1034 1033 1034 0 0 0 0 aclremove intltsel intltjoinsel ));
+DATA(insert OID = 968 ( "~" PGUID 0 b t f 1034 1033 16 0 0 0 0 aclcontains intltsel intltjoinsel ));
/* additional geometric operators - thomas 1997-07-09 */
-DATA(insert OID = 969 ( "@@" PGUID 0 l t f 0 601 600 0 0 0 0 lseg_center - - ));
-DATA(insert OID = 970 ( "@@" PGUID 0 l t f 0 602 600 0 0 0 0 path_center - - ));
-DATA(insert OID = 971 ( "@@" PGUID 0 l t f 0 604 600 0 0 0 0 poly_center - - ));
-
-DATA(insert OID = 974 ( "||" PGUID 0 b t f 1042 1042 1042 0 0 0 0 textcat - - ));
-DATA(insert OID = 979 ( "||" PGUID 0 b t f 1043 1043 1043 0 0 0 0 textcat - - ));
-
-DATA(insert OID = 1054 ( "=" PGUID 0 b t t 1042 1042 16 1054 1057 1058 1058 bpchareq eqsel eqjoinsel ));
-DATA(insert OID = 1055 ( "~" PGUID 0 b t f 1042 25 16 0 1056 0 0 textregexeq eqsel eqjoinsel ));
-DATA(insert OID = 1056 ( "!~" PGUID 0 b t f 1042 25 16 0 1055 0 0 textregexne neqsel neqjoinsel ));
-DATA(insert OID = 1057 ( "<>" PGUID 0 b t f 1042 1042 16 1057 1054 0 0 bpcharne neqsel neqjoinsel ));
-DATA(insert OID = 1058 ( "<" PGUID 0 b t f 1042 1042 16 1060 1061 0 0 bpcharlt intltsel intltjoinsel ));
-DATA(insert OID = 1059 ( "<=" PGUID 0 b t f 1042 1042 16 1061 1060 0 0 bpcharle intltsel intltjoinsel ));
-DATA(insert OID = 1060 ( ">" PGUID 0 b t f 1042 1042 16 1058 1059 0 0 bpchargt intltsel intltjoinsel ));
-DATA(insert OID = 1061 ( ">=" PGUID 0 b t f 1042 1042 16 1059 1058 0 0 bpcharge intltsel intltjoinsel ));
-
-DATA(insert OID = 1062 ( "=" PGUID 0 b t t 1043 1043 16 1062 1065 1066 1066 varchareq eqsel eqjoinsel ));
-DATA(insert OID = 1063 ( "~" PGUID 0 b t f 1043 25 16 0 1064 0 0 textregexeq eqsel eqjoinsel ));
-DATA(insert OID = 1064 ( "!~" PGUID 0 b t f 1043 25 16 0 1063 0 0 textregexne neqsel neqjoinsel ));
-DATA(insert OID = 1065 ( "<>" PGUID 0 b t f 1043 1043 16 1065 1062 0 0 varcharne neqsel neqjoinsel ));
-DATA(insert OID = 1066 ( "<" PGUID 0 b t f 1043 1043 16 1068 1069 0 0 varcharlt intltsel intltjoinsel ));
-DATA(insert OID = 1067 ( "<=" PGUID 0 b t f 1043 1043 16 1069 1068 0 0 varcharle intltsel intltjoinsel ));
-DATA(insert OID = 1068 ( ">" PGUID 0 b t f 1043 1043 16 1066 1067 0 0 varchargt intltsel intltjoinsel ));
-DATA(insert OID = 1069 ( ">=" PGUID 0 b t f 1043 1043 16 1067 1066 0 0 varcharge intltsel intltjoinsel ));
+DATA(insert OID = 969 ( "@@" PGUID 0 l t f 0 601 600 0 0 0 0 lseg_center - - ));
+DATA(insert OID = 970 ( "@@" PGUID 0 l t f 0 602 600 0 0 0 0 path_center - - ));
+DATA(insert OID = 971 ( "@@" PGUID 0 l t f 0 604 600 0 0 0 0 poly_center - - ));
+
+DATA(insert OID = 974 ( "||" PGUID 0 b t f 1042 1042 1042 0 0 0 0 textcat - - ));
+DATA(insert OID = 979 ( "||" PGUID 0 b t f 1043 1043 1043 0 0 0 0 textcat - - ));
+
+DATA(insert OID = 1054 ( "=" PGUID 0 b t t 1042 1042 16 1054 1057 1058 1058 bpchareq eqsel eqjoinsel ));
+DATA(insert OID = 1055 ( "~" PGUID 0 b t f 1042 25 16 0 1056 0 0 textregexeq eqsel eqjoinsel ));
+DATA(insert OID = 1056 ( "!~" PGUID 0 b t f 1042 25 16 0 1055 0 0 textregexne neqsel neqjoinsel ));
+DATA(insert OID = 1057 ( "<>" PGUID 0 b t f 1042 1042 16 1057 1054 0 0 bpcharne neqsel neqjoinsel ));
+DATA(insert OID = 1058 ( "<" PGUID 0 b t f 1042 1042 16 1060 1061 0 0 bpcharlt intltsel intltjoinsel ));
+DATA(insert OID = 1059 ( "<=" PGUID 0 b t f 1042 1042 16 1061 1060 0 0 bpcharle intltsel intltjoinsel ));
+DATA(insert OID = 1060 ( ">" PGUID 0 b t f 1042 1042 16 1058 1059 0 0 bpchargt intltsel intltjoinsel ));
+DATA(insert OID = 1061 ( ">=" PGUID 0 b t f 1042 1042 16 1059 1058 0 0 bpcharge intltsel intltjoinsel ));
+
+DATA(insert OID = 1062 ( "=" PGUID 0 b t t 1043 1043 16 1062 1065 1066 1066 varchareq eqsel eqjoinsel ));
+DATA(insert OID = 1063 ( "~" PGUID 0 b t f 1043 25 16 0 1064 0 0 textregexeq eqsel eqjoinsel ));
+DATA(insert OID = 1064 ( "!~" PGUID 0 b t f 1043 25 16 0 1063 0 0 textregexne neqsel neqjoinsel ));
+DATA(insert OID = 1065 ( "<>" PGUID 0 b t f 1043 1043 16 1065 1062 0 0 varcharne neqsel neqjoinsel ));
+DATA(insert OID = 1066 ( "<" PGUID 0 b t f 1043 1043 16 1068 1069 0 0 varcharlt intltsel intltjoinsel ));
+DATA(insert OID = 1067 ( "<=" PGUID 0 b t f 1043 1043 16 1069 1068 0 0 varcharle intltsel intltjoinsel ));
+DATA(insert OID = 1068 ( ">" PGUID 0 b t f 1043 1043 16 1066 1067 0 0 varchargt intltsel intltjoinsel ));
+DATA(insert OID = 1069 ( ">=" PGUID 0 b t f 1043 1043 16 1067 1066 0 0 varcharge intltsel intltjoinsel ));
/* date operators */
-DATA(insert OID = 1093 ( "=" PGUID 0 b t t 1082 1082 16 1093 1094 1095 1095 date_eq eqsel eqjoinsel ));
-DATA(insert OID = 1094 ( "<>" PGUID 0 b t f 1082 1082 16 1094 1093 0 0 date_ne neqsel neqjoinsel ));
-DATA(insert OID = 1095 ( "<" PGUID 0 b t f 1082 1082 16 1097 1098 0 0 date_lt intltsel intltjoinsel ));
-DATA(insert OID = 1096 ( "<=" PGUID 0 b t f 1082 1082 16 1098 1097 0 0 date_le intltsel intltjoinsel ));
-DATA(insert OID = 1097 ( ">" PGUID 0 b t f 1082 1082 16 1095 1096 0 0 date_gt intltsel intltjoinsel ));
-DATA(insert OID = 1098 ( ">=" PGUID 0 b t f 1082 1082 16 1096 1065 0 0 date_ge intltsel intltjoinsel ));
-DATA(insert OID = 1099 ( "-" PGUID 0 b t f 1082 1082 23 0 0 0 0 date_mi - - ));
-DATA(insert OID = 1100 ( "+" PGUID 0 b t f 1082 23 1082 0 0 0 0 date_pli - - ));
-DATA(insert OID = 1101 ( "-" PGUID 0 b t f 1082 23 1082 0 0 0 0 date_mii - - ));
+DATA(insert OID = 1093 ( "=" PGUID 0 b t t 1082 1082 16 1093 1094 1095 1095 date_eq eqsel eqjoinsel ));
+DATA(insert OID = 1094 ( "<>" PGUID 0 b t f 1082 1082 16 1094 1093 0 0 date_ne neqsel neqjoinsel ));
+DATA(insert OID = 1095 ( "<" PGUID 0 b t f 1082 1082 16 1097 1098 0 0 date_lt intltsel intltjoinsel ));
+DATA(insert OID = 1096 ( "<=" PGUID 0 b t f 1082 1082 16 1098 1097 0 0 date_le intltsel intltjoinsel ));
+DATA(insert OID = 1097 ( ">" PGUID 0 b t f 1082 1082 16 1095 1096 0 0 date_gt intltsel intltjoinsel ));
+DATA(insert OID = 1098 ( ">=" PGUID 0 b t f 1082 1082 16 1096 1065 0 0 date_ge intltsel intltjoinsel ));
+DATA(insert OID = 1099 ( "-" PGUID 0 b t f 1082 1082 23 0 0 0 0 date_mi - - ));
+DATA(insert OID = 1100 ( "+" PGUID 0 b t f 1082 23 1082 0 0 0 0 date_pli - - ));
+DATA(insert OID = 1101 ( "-" PGUID 0 b t f 1082 23 1082 0 0 0 0 date_mii - - ));
/* time operators */
-DATA(insert OID = 1108 ( "=" PGUID 0 b t t 1083 1083 16 1108 1109 1110 1110 time_eq eqsel eqjoinsel ));
-DATA(insert OID = 1109 ( "<>" PGUID 0 b t f 1083 1083 16 1109 1108 0 0 time_ne neqsel neqjoinsel ));
-DATA(insert OID = 1110 ( "<" PGUID 0 b t f 1083 1083 16 1112 1113 0 0 time_lt intltsel intltjoinsel ));
-DATA(insert OID = 1111 ( "<=" PGUID 0 b t f 1083 1083 16 1113 1112 0 0 time_le intltsel intltjoinsel ));
-DATA(insert OID = 1112 ( ">" PGUID 0 b t f 1083 1083 16 1110 1111 0 0 time_gt intltsel intltjoinsel ));
-DATA(insert OID = 1113 ( ">=" PGUID 0 b t f 1083 1083 16 1111 1065 0 0 time_ge intltsel intltjoinsel ));
+DATA(insert OID = 1108 ( "=" PGUID 0 b t t 1083 1083 16 1108 1109 1110 1110 time_eq eqsel eqjoinsel ));
+DATA(insert OID = 1109 ( "<>" PGUID 0 b t f 1083 1083 16 1109 1108 0 0 time_ne neqsel neqjoinsel ));
+DATA(insert OID = 1110 ( "<" PGUID 0 b t f 1083 1083 16 1112 1113 0 0 time_lt intltsel intltjoinsel ));
+DATA(insert OID = 1111 ( "<=" PGUID 0 b t f 1083 1083 16 1113 1112 0 0 time_le intltsel intltjoinsel ));
+DATA(insert OID = 1112 ( ">" PGUID 0 b t f 1083 1083 16 1110 1111 0 0 time_gt intltsel intltjoinsel ));
+DATA(insert OID = 1113 ( ">=" PGUID 0 b t f 1083 1083 16 1111 1065 0 0 time_ge intltsel intltjoinsel ));
/* datetime operators */
/* name, owner, prec, kind, isleft, canhash, left, right, result, com, negate, lsortop, rsortop, oprcode, operrest, oprjoin */
-DATA(insert OID = 1320 ( "=" PGUID 0 b t f 1184 1184 16 1320 1321 1322 1322 datetime_eq eqsel eqjoinsel ));
-DATA(insert OID = 1321 ( "<>" PGUID 0 b t f 1184 1184 16 1321 1320 0 0 datetime_ne neqsel neqjoinsel ));
-DATA(insert OID = 1322 ( "<" PGUID 0 b t f 1184 1184 16 1325 1325 0 0 datetime_lt intltsel intltjoinsel ));
-DATA(insert OID = 1323 ( "<=" PGUID 0 b t f 1184 1184 16 1324 1324 0 0 datetime_le intltsel intltjoinsel ));
-DATA(insert OID = 1324 ( ">" PGUID 0 b t f 1184 1184 16 1323 1323 0 0 datetime_gt intltsel intltjoinsel ));
-DATA(insert OID = 1325 ( ">=" PGUID 0 b t f 1184 1184 16 1322 1322 0 0 datetime_ge intltsel intltjoinsel ));
+DATA(insert OID = 1320 ( "=" PGUID 0 b t f 1184 1184 16 1320 1321 1322 1322 datetime_eq eqsel eqjoinsel ));
+DATA(insert OID = 1321 ( "<>" PGUID 0 b t f 1184 1184 16 1321 1320 0 0 datetime_ne neqsel neqjoinsel ));
+DATA(insert OID = 1322 ( "<" PGUID 0 b t f 1184 1184 16 1325 1325 0 0 datetime_lt intltsel intltjoinsel ));
+DATA(insert OID = 1323 ( "<=" PGUID 0 b t f 1184 1184 16 1324 1324 0 0 datetime_le intltsel intltjoinsel ));
+DATA(insert OID = 1324 ( ">" PGUID 0 b t f 1184 1184 16 1323 1323 0 0 datetime_gt intltsel intltjoinsel ));
+DATA(insert OID = 1325 ( ">=" PGUID 0 b t f 1184 1184 16 1322 1322 0 0 datetime_ge intltsel intltjoinsel ));
-DATA(insert OID = 1327 ( "+" PGUID 0 b t f 1184 1186 1184 1327 0 0 0 datetime_pl_span - - ));
-DATA(insert OID = 1328 ( "-" PGUID 0 b t f 1184 1184 1186 0 0 0 0 datetime_mi - - ));
-DATA(insert OID = 1329 ( "-" PGUID 0 b t f 1184 1186 1184 0 0 0 0 datetime_mi_span - - ));
+DATA(insert OID = 1327 ( "+" PGUID 0 b t f 1184 1186 1184 1327 0 0 0 datetime_pl_span - - ));
+DATA(insert OID = 1328 ( "-" PGUID 0 b t f 1184 1184 1186 0 0 0 0 datetime_mi - - ));
+DATA(insert OID = 1329 ( "-" PGUID 0 b t f 1184 1186 1184 0 0 0 0 datetime_mi_span - - ));
/* timespan operators */
-DATA(insert OID = 1330 ( "=" PGUID 0 b t f 1186 1186 16 1330 1331 1332 1332 timespan_eq eqsel eqjoinsel ));
-DATA(insert OID = 1331 ( "<>" PGUID 0 b t f 1186 1186 16 1331 1330 0 0 timespan_ne neqsel neqjoinsel ));
-DATA(insert OID = 1332 ( "<" PGUID 0 b t f 1186 1186 16 1335 1335 0 0 timespan_lt intltsel intltjoinsel ));
-DATA(insert OID = 1333 ( "<=" PGUID 0 b t f 1186 1186 16 1334 1334 0 0 timespan_le intltsel intltjoinsel ));
-DATA(insert OID = 1334 ( ">" PGUID 0 b t f 1186 1186 16 1333 1333 0 0 timespan_gt intltsel intltjoinsel ));
-DATA(insert OID = 1335 ( ">=" PGUID 0 b t f 1186 1186 16 1332 1332 0 0 timespan_ge intltsel intltjoinsel ));
+DATA(insert OID = 1330 ( "=" PGUID 0 b t f 1186 1186 16 1330 1331 1332 1332 timespan_eq eqsel eqjoinsel ));
+DATA(insert OID = 1331 ( "<>" PGUID 0 b t f 1186 1186 16 1331 1330 0 0 timespan_ne neqsel neqjoinsel ));
+DATA(insert OID = 1332 ( "<" PGUID 0 b t f 1186 1186 16 1335 1335 0 0 timespan_lt intltsel intltjoinsel ));
+DATA(insert OID = 1333 ( "<=" PGUID 0 b t f 1186 1186 16 1334 1334 0 0 timespan_le intltsel intltjoinsel ));
+DATA(insert OID = 1334 ( ">" PGUID 0 b t f 1186 1186 16 1333 1333 0 0 timespan_gt intltsel intltjoinsel ));
+DATA(insert OID = 1335 ( ">=" PGUID 0 b t f 1186 1186 16 1332 1332 0 0 timespan_ge intltsel intltjoinsel ));
-DATA(insert OID = 1336 ( "-" PGUID 0 l t f 0 1186 1186 0 0 0 0 timespan_um 0 0 ));
-DATA(insert OID = 1337 ( "+" PGUID 0 b t f 1186 1186 1186 1337 0 0 0 timespan_pl - - ));
-DATA(insert OID = 1338 ( "-" PGUID 0 b t f 1186 1186 1186 0 0 0 0 timespan_mi - - ));
+DATA(insert OID = 1336 ( "-" PGUID 0 l t f 0 1186 1186 0 0 0 0 timespan_um 0 0 ));
+DATA(insert OID = 1337 ( "+" PGUID 0 b t f 1186 1186 1186 1337 0 0 0 timespan_pl - - ));
+DATA(insert OID = 1338 ( "-" PGUID 0 b t f 1186 1186 1186 0 0 0 0 timespan_mi - - ));
/* float48 operators */
-DATA(insert OID = 1116 ( "+" PGUID 0 b t f 700 701 701 1116 0 0 0 float48pl - - ));
-DATA(insert OID = 1117 ( "-" PGUID 0 b t f 700 701 701 0 0 0 0 float48mi - - ));
-DATA(insert OID = 1118 ( "/" PGUID 0 b t f 700 701 701 0 0 0 0 float48div - - ));
-DATA(insert OID = 1119 ( "*" PGUID 0 b t f 700 701 701 1119 0 0 0 float48mul - - ));
-DATA(insert OID = 1120 ( "=" PGUID 0 b t t 700 701 16 1120 1121 1122 1122 float48eq eqsel eqjoinsel ));
-DATA(insert OID = 1121 ( "<>" PGUID 0 b t f 700 701 16 1121 1120 0 0 float48ne neqsel neqjoinsel ));
-DATA(insert OID = 1122 ( "<" PGUID 0 b t f 700 701 16 1123 1125 0 0 float48lt intltsel intltjoinsel ));
-DATA(insert OID = 1123 ( ">" PGUID 0 b t f 700 701 16 1122 1124 0 0 float48gt intgtsel intgtjoinsel ));
-DATA(insert OID = 1124 ( "<=" PGUID 0 b t f 700 701 16 1125 1123 0 0 float48le intltsel intltjoinsel ));
-DATA(insert OID = 1125 ( ">=" PGUID 0 b t f 700 701 16 1124 1122 0 0 float48ge intgtsel intgtjoinsel ));
+DATA(insert OID = 1116 ( "+" PGUID 0 b t f 700 701 701 1116 0 0 0 float48pl - - ));
+DATA(insert OID = 1117 ( "-" PGUID 0 b t f 700 701 701 0 0 0 0 float48mi - - ));
+DATA(insert OID = 1118 ( "/" PGUID 0 b t f 700 701 701 0 0 0 0 float48div - - ));
+DATA(insert OID = 1119 ( "*" PGUID 0 b t f 700 701 701 1119 0 0 0 float48mul - - ));
+DATA(insert OID = 1120 ( "=" PGUID 0 b t t 700 701 16 1120 1121 1122 1122 float48eq eqsel eqjoinsel ));
+DATA(insert OID = 1121 ( "<>" PGUID 0 b t f 700 701 16 1121 1120 0 0 float48ne neqsel neqjoinsel ));
+DATA(insert OID = 1122 ( "<" PGUID 0 b t f 700 701 16 1123 1125 0 0 float48lt intltsel intltjoinsel ));
+DATA(insert OID = 1123 ( ">" PGUID 0 b t f 700 701 16 1122 1124 0 0 float48gt intgtsel intgtjoinsel ));
+DATA(insert OID = 1124 ( "<=" PGUID 0 b t f 700 701 16 1125 1123 0 0 float48le intltsel intltjoinsel ));
+DATA(insert OID = 1125 ( ">=" PGUID 0 b t f 700 701 16 1124 1122 0 0 float48ge intgtsel intgtjoinsel ));
/* float84 operators */
-DATA(insert OID = 1126 ( "+" PGUID 0 b t f 701 700 701 1126 0 0 0 float84pl - - ));
-DATA(insert OID = 1127 ( "-" PGUID 0 b t f 701 700 701 0 0 0 0 float84mi - - ));
-DATA(insert OID = 1128 ( "/" PGUID 0 b t f 701 700 701 0 0 0 0 float84div - - ));
-DATA(insert OID = 1129 ( "*" PGUID 0 b t f 701 700 701 1129 0 0 0 float84mul - - ));
-DATA(insert OID = 1130 ( "=" PGUID 0 b t t 701 700 16 1130 1131 1132 1132 float84eq eqsel eqjoinsel ));
-DATA(insert OID = 1131 ( "<>" PGUID 0 b t f 701 700 16 1131 1130 0 0 float84ne neqsel neqjoinsel ));
-DATA(insert OID = 1132 ( "<" PGUID 0 b t f 701 700 16 1133 1135 0 0 float84lt intltsel intltjoinsel ));
-DATA(insert OID = 1133 ( ">" PGUID 0 b t f 701 700 16 1132 1134 0 0 float84gt intgtsel intgtjoinsel ));
-DATA(insert OID = 1134 ( "<=" PGUID 0 b t f 701 700 16 1135 1133 0 0 float84le intltsel intltjoinsel ));
-DATA(insert OID = 1135 ( ">=" PGUID 0 b t f 701 700 16 1134 1132 0 0 float84ge intgtsel intgtjoinsel ));
+DATA(insert OID = 1126 ( "+" PGUID 0 b t f 701 700 701 1126 0 0 0 float84pl - - ));
+DATA(insert OID = 1127 ( "-" PGUID 0 b t f 701 700 701 0 0 0 0 float84mi - - ));
+DATA(insert OID = 1128 ( "/" PGUID 0 b t f 701 700 701 0 0 0 0 float84div - - ));
+DATA(insert OID = 1129 ( "*" PGUID 0 b t f 701 700 701 1129 0 0 0 float84mul - - ));
+DATA(insert OID = 1130 ( "=" PGUID 0 b t t 701 700 16 1130 1131 1132 1132 float84eq eqsel eqjoinsel ));
+DATA(insert OID = 1131 ( "<>" PGUID 0 b t f 701 700 16 1131 1130 0 0 float84ne neqsel neqjoinsel ));
+DATA(insert OID = 1132 ( "<" PGUID 0 b t f 701 700 16 1133 1135 0 0 float84lt intltsel intltjoinsel ));
+DATA(insert OID = 1133 ( ">" PGUID 0 b t f 701 700 16 1132 1134 0 0 float84gt intgtsel intgtjoinsel ));
+DATA(insert OID = 1134 ( "<=" PGUID 0 b t f 701 700 16 1135 1133 0 0 float84le intltsel intltjoinsel ));
+DATA(insert OID = 1135 ( ">=" PGUID 0 b t f 701 700 16 1134 1132 0 0 float84ge intgtsel intgtjoinsel ));
/* int4 and oid equality */
-DATA(insert OID = 1136 ( "=" PGUID 0 b t t 23 26 16 1137 0 0 0 int4eqoid eqsel eqjoinsel ));
-DATA(insert OID = 1137 ( "=" PGUID 0 b t t 26 23 16 1136 0 0 0 oideqint4 eqsel eqjoinsel ));
+DATA(insert OID = 1136 ( "=" PGUID 0 b t t 23 26 16 1137 0 0 0 int4eqoid eqsel eqjoinsel ));
+DATA(insert OID = 1137 ( "=" PGUID 0 b t t 26 23 16 1136 0 0 0 oideqint4 eqsel eqjoinsel ));
/* LIKE hacks by Keith Parks. */
-DATA(insert OID = 1201 ( "~~" PGUID 0 b t f 409 25 16 0 1202 0 0 char2like eqsel eqjoinsel ));
+DATA(insert OID = 1201 ( "~~" PGUID 0 b t f 409 25 16 0 1202 0 0 char2like eqsel eqjoinsel ));
DATA(insert OID = 1202 ( "!~~" PGUID 0 b t f 409 25 16 0 1201 0 0 char2nlike neqsel neqjoinsel ));
-DATA(insert OID = 1203 ( "~~" PGUID 0 b t f 410 25 16 0 1204 0 0 char4like eqsel eqjoinsel ));
+DATA(insert OID = 1203 ( "~~" PGUID 0 b t f 410 25 16 0 1204 0 0 char4like eqsel eqjoinsel ));
DATA(insert OID = 1204 ( "!~~" PGUID 0 b t f 410 25 16 0 1203 0 0 char4nlike neqsel neqjoinsel ));
-DATA(insert OID = 1205 ( "~~" PGUID 0 b t f 411 25 16 0 1206 0 0 char8like eqsel eqjoinsel ));
+DATA(insert OID = 1205 ( "~~" PGUID 0 b t f 411 25 16 0 1206 0 0 char8like eqsel eqjoinsel ));
DATA(insert OID = 1206 ( "!~~" PGUID 0 b t f 411 25 16 0 1205 0 0 char8nlike neqsel neqjoinsel ));
-DATA(insert OID = 1207 ( "~~" PGUID 0 b t f 19 25 16 0 1208 0 0 namelike eqsel eqjoinsel ));
+DATA(insert OID = 1207 ( "~~" PGUID 0 b t f 19 25 16 0 1208 0 0 namelike eqsel eqjoinsel ));
DATA(insert OID = 1208 ( "!~~" PGUID 0 b t f 19 25 16 0 1207 0 0 namenlike neqsel neqjoinsel ));
-DATA(insert OID = 1209 ( "~~" PGUID 0 b t f 25 25 16 0 1210 0 0 textlike eqsel eqjoinsel ));
+DATA(insert OID = 1209 ( "~~" PGUID 0 b t f 25 25 16 0 1210 0 0 textlike eqsel eqjoinsel ));
DATA(insert OID = 1210 ( "!~~" PGUID 0 b t f 25 25 16 0 1209 0 0 textnlike neqsel neqjoinsel ));
-DATA(insert OID = 1211 ( "~~" PGUID 0 b t f 1042 25 16 0 1212 0 0 textlike eqsel eqjoinsel ));
+DATA(insert OID = 1211 ( "~~" PGUID 0 b t f 1042 25 16 0 1212 0 0 textlike eqsel eqjoinsel ));
DATA(insert OID = 1212 ( "!~~" PGUID 0 b t f 1042 25 16 0 1211 0 0 textnlike neqsel neqjoinsel ));
-DATA(insert OID = 1213 ( "~~" PGUID 0 b t f 1043 25 16 0 1214 0 0 textlike eqsel eqjoinsel ));
+DATA(insert OID = 1213 ( "~~" PGUID 0 b t f 1043 25 16 0 1214 0 0 textlike eqsel eqjoinsel ));
DATA(insert OID = 1214 ( "!~~" PGUID 0 b t f 1043 25 16 0 1213 0 0 textnlike neqsel neqjoinsel ));
/* case-insensitive LIKE hacks */
-DATA(insert OID = 1220 ( "~*" PGUID 0 b t f 409 25 16 0 1221 0 0 char2icregexeq eqsel eqjoinsel ));
-DATA(insert OID = 1221 ( "!~*" PGUID 0 b t f 409 25 16 0 1220 0 0 char2icregexne neqsel neqjoinsel ));
-DATA(insert OID = 1222 ( "~*" PGUID 0 b t f 410 25 16 0 1223 0 0 char4icregexeq eqsel eqjoinsel ));
-DATA(insert OID = 1223 ( "!~*" PGUID 0 b t f 410 25 16 0 1222 0 0 char4icregexne neqsel neqjoinsel ));
-DATA(insert OID = 1224 ( "~*" PGUID 0 b t f 411 25 16 0 1225 0 0 char8icregexeq eqsel eqjoinsel ));
-DATA(insert OID = 1225 ( "!~*" PGUID 0 b t f 411 25 16 0 1224 0 0 char8icregexne neqsel neqjoinsel ));
-DATA(insert OID = 1226 ( "~*" PGUID 0 b t f 19 25 16 0 1227 0 0 nameicregexeq eqsel eqjoinsel ));
-DATA(insert OID = 1227 ( "!~*" PGUID 0 b t f 19 25 16 0 1226 0 0 nameicregexne neqsel neqjoinsel ));
-DATA(insert OID = 1228 ( "~*" PGUID 0 b t f 25 25 16 0 1229 0 0 texticregexeq eqsel eqjoinsel ));
-DATA(insert OID = 1229 ( "!~*" PGUID 0 b t f 25 25 16 0 1228 0 0 texticregexne eqsel eqjoinsel ));
-DATA(insert OID = 1230 ( "~*" PGUID 0 b t f 20 25 16 0 1231 0 0 char16icregexeq eqsel eqjoinsel ));
-DATA(insert OID = 1231 ( "!~*" PGUID 0 b t f 20 25 16 0 1230 0 0 char16icregexne neqsel neqjoinsel ));
-DATA(insert OID = 1232 ( "~*" PGUID 0 b t f 1043 25 16 0 1233 0 0 texticregexeq eqsel eqjoinsel ));
-DATA(insert OID = 1233 ( "!~*" PGUID 0 b t f 1043 25 16 0 1232 0 0 texticregexne neqsel neqjoinsel ));
-DATA(insert OID = 1234 ( "~*" PGUID 0 b t f 1042 25 16 0 1235 0 0 texticregexeq eqsel eqjoinsel ));
-DATA(insert OID = 1235 ( "!~*" PGUID 0 b t f 1042 25 16 0 1234 0 0 texticregexne neqsel neqjoinsel ));
-
-DATA(insert OID = 1300 ( "=" PGUID 0 b t t 1296 1296 16 1300 1301 1302 1302 timestampeq eqsel eqjoinsel ));
-DATA(insert OID = 1301 ( "<>" PGUID 0 b t f 1296 1296 16 1301 1300 0 0 timestampne neqsel neqjoinsel ));
-DATA(insert OID = 1302 ( "<" PGUID 0 b t f 1296 1296 16 1303 1305 0 0 timestamplt intltsel intltjoinsel ));
-DATA(insert OID = 1303 ( ">" PGUID 0 b t f 1296 1296 16 1302 1304 0 0 timestampgt intltsel intltjoinsel ));
-DATA(insert OID = 1304 ( "<=" PGUID 0 b t f 1296 1296 16 1305 1303 0 0 timestample intltsel intltjoinsel ));
-DATA(insert OID = 1305 ( ">=" PGUID 0 b t f 1296 1296 16 1304 1302 0 0 timestampge intltsel intltjoinsel ));
+DATA(insert OID = 1220 ( "~*" PGUID 0 b t f 409 25 16 0 1221 0 0 char2icregexeq eqsel eqjoinsel ));
+DATA(insert OID = 1221 ( "!~*" PGUID 0 b t f 409 25 16 0 1220 0 0 char2icregexne neqsel neqjoinsel ));
+DATA(insert OID = 1222 ( "~*" PGUID 0 b t f 410 25 16 0 1223 0 0 char4icregexeq eqsel eqjoinsel ));
+DATA(insert OID = 1223 ( "!~*" PGUID 0 b t f 410 25 16 0 1222 0 0 char4icregexne neqsel neqjoinsel ));
+DATA(insert OID = 1224 ( "~*" PGUID 0 b t f 411 25 16 0 1225 0 0 char8icregexeq eqsel eqjoinsel ));
+DATA(insert OID = 1225 ( "!~*" PGUID 0 b t f 411 25 16 0 1224 0 0 char8icregexne neqsel neqjoinsel ));
+DATA(insert OID = 1226 ( "~*" PGUID 0 b t f 19 25 16 0 1227 0 0 nameicregexeq eqsel eqjoinsel ));
+DATA(insert OID = 1227 ( "!~*" PGUID 0 b t f 19 25 16 0 1226 0 0 nameicregexne neqsel neqjoinsel ));
+DATA(insert OID = 1228 ( "~*" PGUID 0 b t f 25 25 16 0 1229 0 0 texticregexeq eqsel eqjoinsel ));
+DATA(insert OID = 1229 ( "!~*" PGUID 0 b t f 25 25 16 0 1228 0 0 texticregexne eqsel eqjoinsel ));
+DATA(insert OID = 1230 ( "~*" PGUID 0 b t f 20 25 16 0 1231 0 0 char16icregexeq eqsel eqjoinsel ));
+DATA(insert OID = 1231 ( "!~*" PGUID 0 b t f 20 25 16 0 1230 0 0 char16icregexne neqsel neqjoinsel ));
+DATA(insert OID = 1232 ( "~*" PGUID 0 b t f 1043 25 16 0 1233 0 0 texticregexeq eqsel eqjoinsel ));
+DATA(insert OID = 1233 ( "!~*" PGUID 0 b t f 1043 25 16 0 1232 0 0 texticregexne neqsel neqjoinsel ));
+DATA(insert OID = 1234 ( "~*" PGUID 0 b t f 1042 25 16 0 1235 0 0 texticregexeq eqsel eqjoinsel ));
+DATA(insert OID = 1235 ( "!~*" PGUID 0 b t f 1042 25 16 0 1234 0 0 texticregexne neqsel neqjoinsel ));
+
+DATA(insert OID = 1300 ( "=" PGUID 0 b t t 1296 1296 16 1300 1301 1302 1302 timestampeq eqsel eqjoinsel ));
+DATA(insert OID = 1301 ( "<>" PGUID 0 b t f 1296 1296 16 1301 1300 0 0 timestampne neqsel neqjoinsel ));
+DATA(insert OID = 1302 ( "<" PGUID 0 b t f 1296 1296 16 1303 1305 0 0 timestamplt intltsel intltjoinsel ));
+DATA(insert OID = 1303 ( ">" PGUID 0 b t f 1296 1296 16 1302 1304 0 0 timestampgt intltsel intltjoinsel ));
+DATA(insert OID = 1304 ( "<=" PGUID 0 b t f 1296 1296 16 1305 1303 0 0 timestample intltsel intltjoinsel ));
+DATA(insert OID = 1305 ( ">=" PGUID 0 b t f 1296 1296 16 1304 1302 0 0 timestampge intltsel intltjoinsel ));
/* additional geometric operators - thomas 97/04/18 */
-DATA(insert OID = 1420 ( "@@" PGUID 0 l t f 0 718 600 0 0 0 0 circle_center - - ));
-DATA(insert OID = 1500 ( "=" PGUID 0 b t t 718 718 16 1500 1501 1502 1502 circle_eq eqsel eqjoinsel ));
-DATA(insert OID = 1501 ( "<>" PGUID 0 b t f 718 718 16 1501 1500 0 0 circle_ne neqsel neqjoinsel ));
-DATA(insert OID = 1502 ( "<" PGUID 0 b t f 718 718 16 0 0 0 0 circle_lt areasel areajoinsel ));
-DATA(insert OID = 1503 ( ">" PGUID 0 b t f 718 718 16 0 0 0 0 circle_gt areasel areajoinsel ));
-DATA(insert OID = 1504 ( "<=" PGUID 0 b t f 718 718 16 0 0 0 0 circle_le areasel areajoinsel ));
-DATA(insert OID = 1505 ( ">=" PGUID 0 b t f 718 718 16 0 0 0 0 circle_ge areasel areajoinsel ));
-
-DATA(insert OID = 1506 ( "<<" PGUID 0 b t f 718 718 16 0 0 0 0 circle_left intltsel intltjoinsel ));
-DATA(insert OID = 1507 ( "&<" PGUID 0 b t f 718 718 16 0 0 0 0 circle_overleft intltsel intltjoinsel ));
-DATA(insert OID = 1508 ( "&>" PGUID 0 b t f 718 718 16 0 0 0 0 circle_overright intltsel intltjoinsel ));
-DATA(insert OID = 1509 ( ">>" PGUID 0 b t f 718 718 16 0 0 0 0 circle_right intltsel intltjoinsel ));
-DATA(insert OID = 1510 ( "@" PGUID 0 b t f 718 718 16 1511 0 0 0 circle_contained intltsel intltjoinsel ));
-DATA(insert OID = 1511 ( "~" PGUID 0 b t f 718 718 16 1510 0 0 0 circle_contain intltsel intltjoinsel ));
-DATA(insert OID = 1512 ( "~=" PGUID 0 b t f 718 718 16 1512 0 0 0 circle_same intltsel intltjoinsel ));
-DATA(insert OID = 1513 ( "&&" PGUID 0 b t f 718 718 16 0 0 0 0 circle_overlap intltsel intltjoinsel ));
-DATA(insert OID = 1514 ( ">^" PGUID 0 b t f 718 718 16 0 0 0 0 circle_above intltsel intltjoinsel ));
-DATA(insert OID = 1515 ( "<^" PGUID 0 b t f 718 718 16 0 0 0 0 circle_below intltsel intltjoinsel ));
-
-DATA(insert OID = 1516 ( "+" PGUID 0 b t f 718 600 718 1516 0 0 0 circle_add_pt - - ));
-DATA(insert OID = 1517 ( "-" PGUID 0 b t f 718 600 718 0 0 0 0 circle_sub_pt - - ));
-DATA(insert OID = 1518 ( "*" PGUID 0 b t f 718 600 718 1518 0 0 0 circle_mul_pt - - ));
-DATA(insert OID = 1519 ( "/" PGUID 0 b t f 718 600 718 0 0 0 0 circle_div_pt - - ));
-
-DATA(insert OID = 1520 ( "<->" PGUID 0 b t f 718 718 701 1520 0 0 0 circle_distance intltsel intltjoinsel ));
-DATA(insert OID = 1521 ( "#" PGUID 0 l t f 0 604 23 0 0 0 0 poly_npoints - - ));
-DATA(insert OID = 1522 ( "<->" PGUID 0 b t f 600 718 701 1522 0 0 0 dist_pc intltsel intltjoinsel ));
-DATA(insert OID = 1523 ( "<->" PGUID 0 b t f 718 604 701 1523 0 0 0 dist_cpoly intltsel intltjoinsel ));
+DATA(insert OID = 1420 ( "@@" PGUID 0 l t f 0 718 600 0 0 0 0 circle_center - - ));
+DATA(insert OID = 1500 ( "=" PGUID 0 b t t 718 718 16 1500 1501 1502 1502 circle_eq eqsel eqjoinsel ));
+DATA(insert OID = 1501 ( "<>" PGUID 0 b t f 718 718 16 1501 1500 0 0 circle_ne neqsel neqjoinsel ));
+DATA(insert OID = 1502 ( "<" PGUID 0 b t f 718 718 16 0 0 0 0 circle_lt areasel areajoinsel ));
+DATA(insert OID = 1503 ( ">" PGUID 0 b t f 718 718 16 0 0 0 0 circle_gt areasel areajoinsel ));
+DATA(insert OID = 1504 ( "<=" PGUID 0 b t f 718 718 16 0 0 0 0 circle_le areasel areajoinsel ));
+DATA(insert OID = 1505 ( ">=" PGUID 0 b t f 718 718 16 0 0 0 0 circle_ge areasel areajoinsel ));
+
+DATA(insert OID = 1506 ( "<<" PGUID 0 b t f 718 718 16 0 0 0 0 circle_left intltsel intltjoinsel ));
+DATA(insert OID = 1507 ( "&<" PGUID 0 b t f 718 718 16 0 0 0 0 circle_overleft intltsel intltjoinsel ));
+DATA(insert OID = 1508 ( "&>" PGUID 0 b t f 718 718 16 0 0 0 0 circle_overright intltsel intltjoinsel ));
+DATA(insert OID = 1509 ( ">>" PGUID 0 b t f 718 718 16 0 0 0 0 circle_right intltsel intltjoinsel ));
+DATA(insert OID = 1510 ( "@" PGUID 0 b t f 718 718 16 1511 0 0 0 circle_contained intltsel intltjoinsel ));
+DATA(insert OID = 1511 ( "~" PGUID 0 b t f 718 718 16 1510 0 0 0 circle_contain intltsel intltjoinsel ));
+DATA(insert OID = 1512 ( "~=" PGUID 0 b t f 718 718 16 1512 0 0 0 circle_same intltsel intltjoinsel ));
+DATA(insert OID = 1513 ( "&&" PGUID 0 b t f 718 718 16 0 0 0 0 circle_overlap intltsel intltjoinsel ));
+DATA(insert OID = 1514 ( ">^" PGUID 0 b t f 718 718 16 0 0 0 0 circle_above intltsel intltjoinsel ));
+DATA(insert OID = 1515 ( "<^" PGUID 0 b t f 718 718 16 0 0 0 0 circle_below intltsel intltjoinsel ));
+
+DATA(insert OID = 1516 ( "+" PGUID 0 b t f 718 600 718 1516 0 0 0 circle_add_pt - - ));
+DATA(insert OID = 1517 ( "-" PGUID 0 b t f 718 600 718 0 0 0 0 circle_sub_pt - - ));
+DATA(insert OID = 1518 ( "*" PGUID 0 b t f 718 600 718 1518 0 0 0 circle_mul_pt - - ));
+DATA(insert OID = 1519 ( "/" PGUID 0 b t f 718 600 718 0 0 0 0 circle_div_pt - - ));
+
+DATA(insert OID = 1520 ( "<->" PGUID 0 b t f 718 718 701 1520 0 0 0 circle_distance intltsel intltjoinsel ));
+DATA(insert OID = 1521 ( "#" PGUID 0 l t f 0 604 23 0 0 0 0 poly_npoints - - ));
+DATA(insert OID = 1522 ( "<->" PGUID 0 b t f 600 718 701 1522 0 0 0 dist_pc intltsel intltjoinsel ));
+DATA(insert OID = 1523 ( "<->" PGUID 0 b t f 718 604 701 1523 0 0 0 dist_cpoly intltsel intltjoinsel ));
/* additional geometric operators - thomas 1997-07-09 */
DATA(insert OID = 1524 ( "<->" PGUID 0 b t f 628 603 701 1524 0 0 0 dist_lb - - ));
-DATA(insert OID = 1525 ( "?#" PGUID 0 b t f 601 601 16 1525 0 0 0 lseg_intersect - - ));
-DATA(insert OID = 1526 ( "?||" PGUID 0 b t f 601 601 16 1526 0 0 0 lseg_parallel - - ));
-DATA(insert OID = 1527 ( "?-|" PGUID 0 b t f 601 601 16 1527 0 0 0 lseg_perp - - ));
-DATA(insert OID = 1528 ( "?-" PGUID 0 l t f 0 601 16 1528 0 0 0 lseg_horizontal - - ));
-DATA(insert OID = 1529 ( "?|" PGUID 0 l t f 0 601 16 1529 0 0 0 lseg_vertical - - ));
-DATA(insert OID = 1535 ( "=" PGUID 0 b t f 601 601 16 1535 0 0 0 lseg_eq intltsel - ));
-DATA(insert OID = 1536 ( "#" PGUID 0 b t f 601 601 600 1536 0 0 0 lseg_interpt - - ));
-DATA(insert OID = 1537 ( "?#" PGUID 0 b t f 601 628 16 1537 0 0 0 inter_sl - - ));
-DATA(insert OID = 1538 ( "?#" PGUID 0 b t f 601 603 16 1538 0 0 0 inter_sb - - ));
-DATA(insert OID = 1539 ( "?#" PGUID 0 b t f 628 603 16 1539 0 0 0 inter_lb - - ));
-
-DATA(insert OID = 1546 ( "@" PGUID 0 b t f 600 628 16 0 0 0 0 on_pl - - ));
-DATA(insert OID = 1547 ( "@" PGUID 0 b t f 600 601 16 0 0 0 0 on_ps - - ));
-DATA(insert OID = 1548 ( "@" PGUID 0 b t f 601 628 16 0 0 0 0 on_sl - - ));
-DATA(insert OID = 1549 ( "@" PGUID 0 b t f 601 603 16 0 0 0 0 on_sb - - ));
-
-DATA(insert OID = 1557 ( "##" PGUID 0 b t f 600 628 600 0 0 0 0 close_pl - - ));
-DATA(insert OID = 1558 ( "##" PGUID 0 b t f 600 601 600 0 0 0 0 close_ps - - ));
-DATA(insert OID = 1559 ( "##" PGUID 0 b t f 600 603 600 0 0 0 0 close_pb - - ));
-
-DATA(insert OID = 1566 ( "##" PGUID 0 b t f 601 628 600 0 0 0 0 close_sl - - ));
-DATA(insert OID = 1567 ( "##" PGUID 0 b t f 601 603 600 0 0 0 0 close_sb - - ));
-DATA(insert OID = 1568 ( "##" PGUID 0 b t f 628 603 600 0 0 0 0 close_lb - - ));
-DATA(insert OID = 1585 ( "/" PGUID 0 b t f 1186 1186 1186 0 0 0 0 timespan_div - - ));
+DATA(insert OID = 1525 ( "?#" PGUID 0 b t f 601 601 16 1525 0 0 0 lseg_intersect - - ));
+DATA(insert OID = 1526 ( "?||" PGUID 0 b t f 601 601 16 1526 0 0 0 lseg_parallel - - ));
+DATA(insert OID = 1527 ( "?-|" PGUID 0 b t f 601 601 16 1527 0 0 0 lseg_perp - - ));
+DATA(insert OID = 1528 ( "?-" PGUID 0 l t f 0 601 16 1528 0 0 0 lseg_horizontal - - ));
+DATA(insert OID = 1529 ( "?|" PGUID 0 l t f 0 601 16 1529 0 0 0 lseg_vertical - - ));
+DATA(insert OID = 1535 ( "=" PGUID 0 b t f 601 601 16 1535 0 0 0 lseg_eq intltsel - ));
+DATA(insert OID = 1536 ( "#" PGUID 0 b t f 601 601 600 1536 0 0 0 lseg_interpt - - ));
+DATA(insert OID = 1537 ( "?#" PGUID 0 b t f 601 628 16 1537 0 0 0 inter_sl - - ));
+DATA(insert OID = 1538 ( "?#" PGUID 0 b t f 601 603 16 1538 0 0 0 inter_sb - - ));
+DATA(insert OID = 1539 ( "?#" PGUID 0 b t f 628 603 16 1539 0 0 0 inter_lb - - ));
+
+DATA(insert OID = 1546 ( "@" PGUID 0 b t f 600 628 16 0 0 0 0 on_pl - - ));
+DATA(insert OID = 1547 ( "@" PGUID 0 b t f 600 601 16 0 0 0 0 on_ps - - ));
+DATA(insert OID = 1548 ( "@" PGUID 0 b t f 601 628 16 0 0 0 0 on_sl - - ));
+DATA(insert OID = 1549 ( "@" PGUID 0 b t f 601 603 16 0 0 0 0 on_sb - - ));
+
+DATA(insert OID = 1557 ( "##" PGUID 0 b t f 600 628 600 0 0 0 0 close_pl - - ));
+DATA(insert OID = 1558 ( "##" PGUID 0 b t f 600 601 600 0 0 0 0 close_ps - - ));
+DATA(insert OID = 1559 ( "##" PGUID 0 b t f 600 603 600 0 0 0 0 close_pb - - ));
+
+DATA(insert OID = 1566 ( "##" PGUID 0 b t f 601 628 600 0 0 0 0 close_sl - - ));
+DATA(insert OID = 1567 ( "##" PGUID 0 b t f 601 603 600 0 0 0 0 close_sb - - ));
+DATA(insert OID = 1568 ( "##" PGUID 0 b t f 628 603 600 0 0 0 0 close_lb - - ));
+DATA(insert OID = 1585 ( "/" PGUID 0 b t f 1186 1186 1186 0 0 0 0 timespan_div - - ));
/*
* function prototypes
*/
-extern void OperatorCreate(char *operatorName,
+extern void
+OperatorCreate(char *operatorName,
char *leftTypeName,
char *rightTypeName,
char *procedureName,
- uint16 precedence,
+ uint16 precedence,
bool isLeftAssociative,
char *commutatorName,
char *negatorName,
@@ -647,4 +649,4 @@ extern void OperatorCreate(char *operatorName,
char *leftSortName,
char *rightSortName);
-#endif /* PG_OPERATOR_H */
+#endif /* PG_OPERATOR_H */
diff --git a/src/include/catalog/pg_parg.h b/src/include/catalog/pg_parg.h
index caecdfa37fa..f5423f70862 100644
--- a/src/include/catalog/pg_parg.h
+++ b/src/include/catalog/pg_parg.h
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* pg_parg.h--
- * definition of the system "parg" relation (pg_parg)
- * along with the relation's initial contents.
+ * definition of the system "parg" relation (pg_parg)
+ * along with the relation's initial contents.
*
* [whatever this relation was, it doesn't seem to be used anymore --djm]
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_parg.h,v 1.3 1996/11/13 20:51:00 scrappy Exp $
+ * $Id: pg_parg.h,v 1.4 1997/09/07 04:57:01 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -20,43 +20,44 @@
#define PG_PARG_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_parg definition. cpp turns this into
- * typedef struct FormData_pg_parg
+ * pg_parg definition. cpp turns this into
+ * typedef struct FormData_pg_parg
* ----------------
- */
-CATALOG(pg_parg) {
- Oid parproid;
- int2 parnum;
- char parbound;
- Oid partype;
+ */
+CATALOG(pg_parg)
+{
+ Oid parproid;
+ int2 parnum;
+ char parbound;
+ Oid partype;
} FormData_pg_parg;
/* ----------------
- * Form_pg_parg corresponds to a pointer to a tuple with
- * the format of pg_parg relation.
+ * Form_pg_parg corresponds to a pointer to a tuple with
+ * the format of pg_parg relation.
* ----------------
*/
-typedef FormData_pg_parg *Form_pg_parg;
+typedef FormData_pg_parg *Form_pg_parg;
/* ----------------
- * compiler constants for pg_parg
+ * compiler constants for pg_parg
* ----------------
*/
-#define Natts_pg_parg 4
-#define Anum_pg_parg_parproid 1
-#define Anum_pg_parg_parnum 2
-#define Anum_pg_parg_parbound 3
-#define Anum_pg_parg_partype 4
+#define Natts_pg_parg 4
+#define Anum_pg_parg_parproid 1
+#define Anum_pg_parg_parnum 2
+#define Anum_pg_parg_parbound 3
+#define Anum_pg_parg_partype 4
/* ----------------
- * initial contents of pg_parg
+ * initial contents of pg_parg
* ----------------
*/
@@ -113,4 +114,4 @@ DATA(insert OID = 0 ( 66 2 - 23 ));
DATA(insert OID = 0 ( 67 1 - 25 ));
DATA(insert OID = 0 ( 67 2 - 25 ));
-#endif /* PG_PARG_H */
+#endif /* PG_PARG_H */
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 0663d78a5ff..2c9dfc9710e 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* pg_proc.h--
- * definition of the system "procedure" relation (pg_proc)
- * along with the relation's initial contents.
+ * definition of the system "procedure" relation (pg_proc)
+ * along with the relation's initial contents.
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_proc.h,v 1.27 1997/09/04 18:43:59 thomas Exp $
+ * $Id: pg_proc.h,v 1.28 1997/09/07 04:57:03 momjian Exp $
*
* NOTES
- * The script catalog/genbki.sh reads this file and generates .bki
- * information from the DATA() statements. utils/Gen_fmgrtab.sh
- * generates fmgr.h and fmgrtab.c the same way.
+ * The script catalog/genbki.sh reads this file and generates .bki
+ * information from the DATA() statements. utils/Gen_fmgrtab.sh
+ * generates fmgr.h and fmgrtab.c the same way.
*
- * XXX do NOT break up DATA() statements into multiple lines!
- * the scripts are not as smart as you might think...
- * XXX (eg. #if 0 #endif won't do what you think)
+ * XXX do NOT break up DATA() statements into multiple lines!
+ * the scripts are not as smart as you might think...
+ * XXX (eg. #if 0 #endif won't do what you think)
*
*-------------------------------------------------------------------------
*/
@@ -25,67 +25,68 @@
#include <tcop/dest.h>
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_proc definition. cpp turns this into
- * typedef struct FormData_pg_proc
+ * pg_proc definition. cpp turns this into
+ * typedef struct FormData_pg_proc
* ----------------
*/
-CATALOG(pg_proc) BOOTSTRAP {
- NameData proname;
- Oid proowner;
- Oid prolang;
- bool proisinh;
- bool proistrusted;
- bool proiscachable;
- int2 pronargs;
- bool proretset;
- Oid prorettype;
- oid8 proargtypes;
- int4 probyte_pct;
- int4 properbyte_cpu;
- int4 propercall_cpu;
- int4 prooutin_ratio;
- text prosrc; /* VARIABLE LENGTH FIELD */
- bytea probin; /* VARIABLE LENGTH FIELD */
+CATALOG(pg_proc) BOOTSTRAP
+{
+ NameData proname;
+ Oid proowner;
+ Oid prolang;
+ bool proisinh;
+ bool proistrusted;
+ bool proiscachable;
+ int2 pronargs;
+ bool proretset;
+ Oid prorettype;
+ oid8 proargtypes;
+ int4 probyte_pct;
+ int4 properbyte_cpu;
+ int4 propercall_cpu;
+ int4 prooutin_ratio;
+ text prosrc; /* VARIABLE LENGTH FIELD */
+ bytea probin; /* VARIABLE LENGTH FIELD */
} FormData_pg_proc;
/* ----------------
- * Form_pg_proc corresponds to a pointer to a tuple with
- * the format of pg_proc relation.
+ * Form_pg_proc corresponds to a pointer to a tuple with
+ * the format of pg_proc relation.
* ----------------
*/
-typedef FormData_pg_proc *Form_pg_proc;
+typedef FormData_pg_proc *Form_pg_proc;
/* ----------------
- * compiler constants for pg_proc
+ * compiler constants for pg_proc
* ----------------
*/
-#define Natts_pg_proc 16
-#define Anum_pg_proc_proname 1
-#define Anum_pg_proc_proowner 2
-#define Anum_pg_proc_prolang 3
-#define Anum_pg_proc_proisinh 4
-#define Anum_pg_proc_proistrusted 5
-#define Anum_pg_proc_proiscachable 6
-#define Anum_pg_proc_pronargs 7
-#define Anum_pg_proc_proretset 8
-#define Anum_pg_proc_prorettype 9
-#define Anum_pg_proc_proargtypes 10
-#define Anum_pg_proc_probyte_pct 11
-#define Anum_pg_proc_properbyte_cpu 12
-#define Anum_pg_proc_propercall_cpu 13
-#define Anum_pg_proc_prooutin_ratio 14
-#define Anum_pg_proc_prosrc 15
-#define Anum_pg_proc_probin 16
+#define Natts_pg_proc 16
+#define Anum_pg_proc_proname 1
+#define Anum_pg_proc_proowner 2
+#define Anum_pg_proc_prolang 3
+#define Anum_pg_proc_proisinh 4
+#define Anum_pg_proc_proistrusted 5
+#define Anum_pg_proc_proiscachable 6
+#define Anum_pg_proc_pronargs 7
+#define Anum_pg_proc_proretset 8
+#define Anum_pg_proc_prorettype 9
+#define Anum_pg_proc_proargtypes 10
+#define Anum_pg_proc_probyte_pct 11
+#define Anum_pg_proc_properbyte_cpu 12
+#define Anum_pg_proc_propercall_cpu 13
+#define Anum_pg_proc_prooutin_ratio 14
+#define Anum_pg_proc_prosrc 15
+#define Anum_pg_proc_probin 16
/* ----------------
- * initial contents of pg_proc
+ * initial contents of pg_proc
* ----------------
*/
@@ -93,470 +94,470 @@ typedef FormData_pg_proc *Form_pg_proc;
/* OIDS 1 - 99 */
-DATA(insert OID = 1242 ( boolin PGUID 11 f t f 1 f 16 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1243 ( boolout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1244 ( byteain PGUID 11 f t f 1 f 17 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 31 ( byteaout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1245 ( charin PGUID 11 f t f 1 f 18 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 33 ( charout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 34 ( namein PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 35 ( nameout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 36 ( char16in PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 37 ( char16out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 38 ( int2in PGUID 11 f t f 1 f 21 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 39 ( int2out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 40 ( int28in PGUID 11 f t f 1 f 22 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 41 ( int28out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 42 ( int4in PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 43 ( int4out PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 44 ( regprocin PGUID 11 f t f 1 f 24 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 45 ( regprocout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 46 ( textin PGUID 11 f t f 1 f 25 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1242 ( boolin PGUID 11 f t f 1 f 16 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1243 ( boolout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1244 ( byteain PGUID 11 f t f 1 f 17 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 31 ( byteaout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1245 ( charin PGUID 11 f t f 1 f 18 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 33 ( charout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 34 ( namein PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 35 ( nameout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 36 ( char16in PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 37 ( char16out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 38 ( int2in PGUID 11 f t f 1 f 21 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 39 ( int2out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 40 ( int28in PGUID 11 f t f 1 f 22 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 41 ( int28out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 42 ( int4in PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 43 ( int4out PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 44 ( regprocin PGUID 11 f t f 1 f 24 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 45 ( regprocout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 46 ( textin PGUID 11 f t f 1 f 25 "0" 100 0 0 100 foo bar ));
#define TextInRegProcedure 46
-DATA(insert OID = 47 ( textout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 48 ( tidin PGUID 11 f t f 1 f 27 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 49 ( tidout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 50 ( xidin PGUID 11 f t f 1 f 28 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 51 ( xidout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 52 ( cidin PGUID 11 f t f 1 f 29 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 53 ( cidout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 54 ( oid8in PGUID 11 f t f 1 f 30 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 55 ( oid8out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 56 ( boollt PGUID 11 f t f 2 f 16 "16 16" 100 0 0 100 foo bar ));
-DATA(insert OID = 57 ( boolgt PGUID 11 f t f 2 f 16 "16 16" 100 0 0 100 foo bar ));
-DATA(insert OID = 60 ( booleq PGUID 11 f t f 2 f 16 "16 16" 100 0 0 100 foo bar ));
-DATA(insert OID = 61 ( chareq PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
-#define CharacterEqualRegProcedure 61
-
-DATA(insert OID = 62 ( nameeq PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-#define NameEqualRegProcedure 62
-
-DATA(insert OID = 63 ( int2eq PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
-#define Integer16EqualRegProcedure 63
-
-DATA(insert OID = 64 ( int2lt PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 65 ( int4eq PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
-#define Integer32EqualRegProcedure 65
-
-DATA(insert OID = 66 ( int4lt PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 67 ( texteq PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
-#define TextEqualRegProcedure 67
-
-DATA(insert OID = 68 ( xideq PGUID 11 f t f 2 f 16 "28 28" 100 0 0 100 foo bar ));
-DATA(insert OID = 69 ( cideq PGUID 11 f t f 2 f 16 "29 29" 100 0 0 100 foo bar ));
-DATA(insert OID = 70 ( charne PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 1246 ( charlt PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 72 ( charle PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 73 ( chargt PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 74 ( charge PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 1248 ( charpl PGUID 11 f t f 2 f 18 "18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 1250 ( charmi PGUID 11 f t f 2 f 18 "18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 77 ( charmul PGUID 11 f t f 2 f 18 "18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 78 ( chardiv PGUID 11 f t f 2 f 18 "18 18" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 79 ( nameregexeq PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 1252 ( nameregexne PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 1254 ( textregexeq PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
-DATA(insert OID = 1256 ( textregexne PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
-DATA(insert OID = 1258 ( textcat PGUID 11 f t f 2 f 25 "25 25" 100 0 1 0 foo bar ));
-DATA(insert OID = 84 ( boolne PGUID 11 f t f 2 f 16 "16 16" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 1265 ( rtsel PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
-DATA(insert OID = 1266 ( rtnpage PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
-DATA(insert OID = 1268 ( btreesel PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 47 ( textout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 48 ( tidin PGUID 11 f t f 1 f 27 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 49 ( tidout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 50 ( xidin PGUID 11 f t f 1 f 28 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 51 ( xidout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 52 ( cidin PGUID 11 f t f 1 f 29 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 53 ( cidout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 54 ( oid8in PGUID 11 f t f 1 f 30 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 55 ( oid8out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 56 ( boollt PGUID 11 f t f 2 f 16 "16 16" 100 0 0 100 foo bar ));
+DATA(insert OID = 57 ( boolgt PGUID 11 f t f 2 f 16 "16 16" 100 0 0 100 foo bar ));
+DATA(insert OID = 60 ( booleq PGUID 11 f t f 2 f 16 "16 16" 100 0 0 100 foo bar ));
+DATA(insert OID = 61 ( chareq PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
+#define CharacterEqualRegProcedure 61
+
+DATA(insert OID = 62 ( nameeq PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+#define NameEqualRegProcedure 62
+
+DATA(insert OID = 63 ( int2eq PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
+#define Integer16EqualRegProcedure 63
+
+DATA(insert OID = 64 ( int2lt PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 65 ( int4eq PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
+#define Integer32EqualRegProcedure 65
+
+DATA(insert OID = 66 ( int4lt PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 67 ( texteq PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
+#define TextEqualRegProcedure 67
+
+DATA(insert OID = 68 ( xideq PGUID 11 f t f 2 f 16 "28 28" 100 0 0 100 foo bar ));
+DATA(insert OID = 69 ( cideq PGUID 11 f t f 2 f 16 "29 29" 100 0 0 100 foo bar ));
+DATA(insert OID = 70 ( charne PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 1246 ( charlt PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 72 ( charle PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 73 ( chargt PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 74 ( charge PGUID 11 f t f 2 f 16 "18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 1248 ( charpl PGUID 11 f t f 2 f 18 "18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 1250 ( charmi PGUID 11 f t f 2 f 18 "18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 77 ( charmul PGUID 11 f t f 2 f 18 "18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 78 ( chardiv PGUID 11 f t f 2 f 18 "18 18" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 79 ( nameregexeq PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1252 ( nameregexne PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1254 ( textregexeq PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
+DATA(insert OID = 1256 ( textregexne PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
+DATA(insert OID = 1258 ( textcat PGUID 11 f t f 2 f 25 "25 25" 100 0 1 0 foo bar ));
+DATA(insert OID = 84 ( boolne PGUID 11 f t f 2 f 16 "16 16" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 1265 ( rtsel PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 1266 ( rtnpage PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 1268 ( btreesel PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
/* OIDS 100 - 199 */
-DATA(insert OID = 1270 ( btreenpage PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
-DATA(insert OID = 1272 ( eqsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 1270 ( btreenpage PGUID 11 f t f 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 1272 ( eqsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
#define EqualSelectivityProcedure 1272
-DATA(insert OID = 102 ( neqsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 103 ( intltsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 104 ( intgtsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 105 ( eqjoinsel PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 106 ( neqjoinsel PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 107 ( intltjoinsel PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 108 ( intgtjoinsel PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 115 ( box_above PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
-DATA(insert OID = 116 ( box_below PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
-
-DATA(insert OID = 117 ( point_in PGUID 11 f t f 1 f 600 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 118 ( point_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 119 ( lseg_in PGUID 11 f t f 1 f 601 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 120 ( lseg_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 121 ( path_in PGUID 11 f t f 1 f 602 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 122 ( path_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 123 ( box_in PGUID 11 f t f 1 f 603 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 124 ( box_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 125 ( box_overlap PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
-DATA(insert OID = 126 ( box_ge PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
-DATA(insert OID = 127 ( box_gt PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
-DATA(insert OID = 128 ( box_eq PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
-DATA(insert OID = 129 ( box_lt PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
-DATA(insert OID = 130 ( box_le PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
-DATA(insert OID = 131 ( point_above PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 132 ( point_left PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 133 ( point_right PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 134 ( point_below PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 135 ( point_eq PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 136 ( on_pb PGUID 11 f t f 2 f 16 "600 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 137 ( on_ppath PGUID 11 f t f 2 f 16 "600 602" 100 0 1 0 foo bar ));
-DATA(insert OID = 138 ( box_center PGUID 11 f t f 1 f 600 "603" 100 1 0 100 foo bar ));
-DATA(insert OID = 139 ( areasel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 140 ( areajoinsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 141 ( int4mul PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 142 ( int4fac PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 143 ( pointdist PGUID 11 f t f 2 f 23 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 144 ( int4ne PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 145 ( int2ne PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 146 ( int2gt PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 147 ( int4gt PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 148 ( int2le PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 149 ( int4le PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 150 ( int4ge PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 102 ( neqsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 103 ( intltsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 104 ( intgtsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 105 ( eqjoinsel PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 106 ( neqjoinsel PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 107 ( intltjoinsel PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 108 ( intgtjoinsel PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 115 ( box_above PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
+DATA(insert OID = 116 ( box_below PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
+
+DATA(insert OID = 117 ( point_in PGUID 11 f t f 1 f 600 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 118 ( point_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 119 ( lseg_in PGUID 11 f t f 1 f 601 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 120 ( lseg_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 121 ( path_in PGUID 11 f t f 1 f 602 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 122 ( path_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 123 ( box_in PGUID 11 f t f 1 f 603 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 124 ( box_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 125 ( box_overlap PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
+DATA(insert OID = 126 ( box_ge PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
+DATA(insert OID = 127 ( box_gt PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
+DATA(insert OID = 128 ( box_eq PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
+DATA(insert OID = 129 ( box_lt PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
+DATA(insert OID = 130 ( box_le PGUID 11 f t f 2 f 16 "603 603" 100 1 0 100 foo bar ));
+DATA(insert OID = 131 ( point_above PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 132 ( point_left PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 133 ( point_right PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 134 ( point_below PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 135 ( point_eq PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 136 ( on_pb PGUID 11 f t f 2 f 16 "600 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 137 ( on_ppath PGUID 11 f t f 2 f 16 "600 602" 100 0 1 0 foo bar ));
+DATA(insert OID = 138 ( box_center PGUID 11 f t f 1 f 600 "603" 100 1 0 100 foo bar ));
+DATA(insert OID = 139 ( areasel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 140 ( areajoinsel PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 141 ( int4mul PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 142 ( int4fac PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 143 ( pointdist PGUID 11 f t f 2 f 23 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 144 ( int4ne PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 145 ( int2ne PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 146 ( int2gt PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 147 ( int4gt PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 148 ( int2le PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 149 ( int4le PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 150 ( int4ge PGUID 11 f t f 2 f 16 "23 23" 100 0 0 100 foo bar ));
#define INT4GE_PROC_OID 150
-DATA(insert OID = 151 ( int2ge PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 152 ( int2mul PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 153 ( int2div PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 154 ( int4div PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 155 ( int2mod PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 156 ( int4mod PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 157 ( textne PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
-DATA(insert OID = 158 ( int24eq PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 159 ( int42eq PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 160 ( int24lt PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 161 ( int42lt PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 162 ( int24gt PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 163 ( int42gt PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 164 ( int24ne PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 165 ( int42ne PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 166 ( int24le PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 167 ( int42le PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 168 ( int24ge PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 169 ( int42ge PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 170 ( int24mul PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 171 ( int42mul PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 172 ( int24div PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 173 ( int42div PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 174 ( int24mod PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 175 ( int42mod PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 176 ( int2pl PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 177 ( int4pl PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 178 ( int24pl PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 179 ( int42pl PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 180 ( int2mi PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 181 ( int4mi PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 182 ( int24mi PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 183 ( int42mi PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 184 ( oideq PGUID 11 f t f 2 f 16 "26 26" 100 0 0 100 foo bar ));
-#define ObjectIdEqualRegProcedure 184
-
-DATA(insert OID = 185 ( oidne PGUID 11 f t f 2 f 16 "26 26" 100 0 0 100 foo bar ));
-DATA(insert OID = 186 ( box_same PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 187 ( box_contain PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 188 ( box_left PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 189 ( box_overleft PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 190 ( box_overright PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 191 ( box_right PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 192 ( box_contained PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 193 ( rt_box_union PGUID 11 f t f 2 f 603 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 194 ( rt_box_inter PGUID 11 f t f 2 f 603 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 195 ( rt_box_size PGUID 11 f t f 2 f 700 "603 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 151 ( int2ge PGUID 11 f t f 2 f 16 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 152 ( int2mul PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 153 ( int2div PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 154 ( int4div PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 155 ( int2mod PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 156 ( int4mod PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 157 ( textne PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
+DATA(insert OID = 158 ( int24eq PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 159 ( int42eq PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 160 ( int24lt PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 161 ( int42lt PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 162 ( int24gt PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 163 ( int42gt PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 164 ( int24ne PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 165 ( int42ne PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 166 ( int24le PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 167 ( int42le PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 168 ( int24ge PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 169 ( int42ge PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 170 ( int24mul PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 171 ( int42mul PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 172 ( int24div PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 173 ( int42div PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 174 ( int24mod PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 175 ( int42mod PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 176 ( int2pl PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 177 ( int4pl PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 178 ( int24pl PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 179 ( int42pl PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 180 ( int2mi PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 181 ( int4mi PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 182 ( int24mi PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 183 ( int42mi PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 184 ( oideq PGUID 11 f t f 2 f 16 "26 26" 100 0 0 100 foo bar ));
+#define ObjectIdEqualRegProcedure 184
+
+DATA(insert OID = 185 ( oidne PGUID 11 f t f 2 f 16 "26 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 186 ( box_same PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 187 ( box_contain PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 188 ( box_left PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 189 ( box_overleft PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 190 ( box_overright PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 191 ( box_right PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 192 ( box_contained PGUID 11 f t f 2 f 16 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 193 ( rt_box_union PGUID 11 f t f 2 f 603 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 194 ( rt_box_inter PGUID 11 f t f 2 f 603 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 195 ( rt_box_size PGUID 11 f t f 2 f 700 "603 700" 100 0 0 100 foo bar ));
DATA(insert OID = 196 ( rt_bigbox_size PGUID 11 f t f 2 f 700 "603 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 197 ( rt_poly_union PGUID 11 f t f 2 f 604 "604 604" 100 0 0 100 foo bar ));
-DATA(insert OID = 198 ( rt_poly_inter PGUID 11 f t f 2 f 604 "604 604" 100 0 0 100 foo bar ));
-DATA(insert OID = 199 ( rt_poly_size PGUID 11 f t f 2 f 23 "604 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 197 ( rt_poly_union PGUID 11 f t f 2 f 604 "604 604" 100 0 0 100 foo bar ));
+DATA(insert OID = 198 ( rt_poly_inter PGUID 11 f t f 2 f 604 "604 604" 100 0 0 100 foo bar ));
+DATA(insert OID = 199 ( rt_poly_size PGUID 11 f t f 2 f 23 "604 23" 100 0 0 100 foo bar ));
/* OIDS 200 - 299 */
-DATA(insert OID = 200 ( float4in PGUID 11 f t f 1 f 700 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 201 ( float4out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 202 ( float4mul PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 203 ( float4div PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 204 ( float4pl PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 205 ( float4mi PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 206 ( float4um PGUID 11 f t f 1 f 700 "700" 100 0 0 100 foo bar ));
-DATA(insert OID = 207 ( float4abs PGUID 11 f t f 1 f 700 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 208 ( float4inc PGUID 11 f t f 1 f 700 "700" 100 0 0 100 foo bar ));
-DATA(insert OID = 209 ( float4larger PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 211 ( float4smaller PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 212 ( int4um PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 213 ( int2um PGUID 11 f t f 1 f 21 "21" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 214 ( float8in PGUID 11 f t f 1 f 701 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 215 ( float8out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 216 ( float8mul PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 217 ( float8div PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 218 ( float8pl PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 219 ( float8mi PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 220 ( float8um PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 221 ( float8abs PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 222 ( float8inc PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 223 ( float8larger PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 224 ( float8smaller PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 225 ( lseg_center PGUID 11 f t f 1 f 600 "601" 100 0 0 100 foo bar ));
-DATA(insert OID = 226 ( path_center PGUID 11 f t f 1 f 600 "602" 100 0 0 100 foo bar ));
-DATA(insert OID = 227 ( poly_center PGUID 11 f t f 1 f 600 "604" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 228 ( dround PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 229 ( dtrunc PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 230 ( dsqrt PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 231 ( dcbrt PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 232 ( dpow PGUID 11 f t f 2 f 701 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 233 ( dexp PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 234 ( dlog1 PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 235 ( i2tod PGUID 11 f t f 1 f 701 "21" 100 0 0 100 foo bar ));
-DATA(insert OID = 236 ( i2tof PGUID 11 f t f 1 f 700 "21" 100 0 0 100 foo bar ));
-DATA(insert OID = 237 ( dtoi2 PGUID 11 f t f 1 f 21 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 238 ( ftoi2 PGUID 11 f t f 1 f 21 "700" 100 0 0 100 foo bar ));
-DATA(insert OID = 239 ( line_distance PGUID 11 f t f 2 f 701 "628 628" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 240 ( nabstimein PGUID 11 f t f 1 f 702 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 241 ( nabstimeout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 242 ( reltimein PGUID 11 f t f 1 f 703 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 243 ( reltimeout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 244 ( timepl PGUID 11 f t f 2 f 702 "702 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 245 ( timemi PGUID 11 f t f 2 f 702 "702 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 246 ( tintervalin PGUID 11 f t f 1 f 704 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 247 ( tintervalout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 248 ( ininterval PGUID 11 f t f 2 f 16 "702 704" 100 0 0 100 foo bar ));
-DATA(insert OID = 249 ( intervalrel PGUID 11 f t f 1 f 703 "704" 100 0 0 100 foo bar ));
-DATA(insert OID = 250 ( timenow PGUID 11 f t f 0 f 702 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 251 ( abstimeeq PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
-DATA(insert OID = 252 ( abstimene PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
-DATA(insert OID = 253 ( abstimelt PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
-DATA(insert OID = 254 ( abstimegt PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
-DATA(insert OID = 255 ( abstimele PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
-DATA(insert OID = 256 ( abstimege PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
-DATA(insert OID = 257 ( reltimeeq PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 258 ( reltimene PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 259 ( reltimelt PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 260 ( reltimegt PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 261 ( reltimele PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 262 ( reltimege PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 263 ( intervaleq PGUID 11 f t f 2 f 16 "704 704" 100 0 0 100 foo bar ));
-DATA(insert OID = 264 ( intervalct PGUID 11 f t f 2 f 16 "704 704" 100 0 0 100 foo bar ));
-DATA(insert OID = 265 ( intervalov PGUID 11 f t f 2 f 16 "704 704" 100 0 0 100 foo bar ));
-DATA(insert OID = 266 ( intervalleneq PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 267 ( intervallenne PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 268 ( intervallenlt PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 269 ( intervallengt PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 270 ( intervallenle PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 271 ( intervallenge PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
-DATA(insert OID = 272 ( intervalstart PGUID 11 f t f 1 f 702 "704" 100 0 0 100 foo bar ));
-DATA(insert OID = 273 ( intervalend PGUID 11 f t f 1 f 702 "704" 100 0 0 100 foo bar ));
-DATA(insert OID = 274 ( timeofday PGUID 11 f t f 0 f 25 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 275 ( abstime_finite PGUID 11 f t f 1 f 16 "702" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 276 ( int2fac PGUID 11 f t f 1 f 21 "21" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 277 ( inter_sl PGUID 11 f t f 2 f 16 "601 628" 100 0 0 100 foo bar ));
-DATA(insert OID = 278 ( inter_lb PGUID 11 f t f 2 f 16 "628 603" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 279 ( float48mul PGUID 11 f t f 2 f 701 "700 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 280 ( float48div PGUID 11 f t f 2 f 701 "700 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 281 ( float48pl PGUID 11 f t f 2 f 701 "700 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 282 ( float48mi PGUID 11 f t f 2 f 701 "700 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 283 ( float84mul PGUID 11 f t f 2 f 701 "701 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 284 ( float84div PGUID 11 f t f 2 f 701 "701 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 285 ( float84pl PGUID 11 f t f 2 f 701 "701 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 286 ( float84mi PGUID 11 f t f 2 f 701 "701 700" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 287 ( float4eq PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 288 ( float4ne PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 289 ( float4lt PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 290 ( float4le PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 291 ( float4gt PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 292 ( float4ge PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 293 ( float8eq PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 294 ( float8ne PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 295 ( float8lt PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 296 ( float8le PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 297 ( float8gt PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 298 ( float8ge PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 299 ( float48eq PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 200 ( float4in PGUID 11 f t f 1 f 700 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 201 ( float4out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 202 ( float4mul PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 203 ( float4div PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 204 ( float4pl PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 205 ( float4mi PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 206 ( float4um PGUID 11 f t f 1 f 700 "700" 100 0 0 100 foo bar ));
+DATA(insert OID = 207 ( float4abs PGUID 11 f t f 1 f 700 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 208 ( float4inc PGUID 11 f t f 1 f 700 "700" 100 0 0 100 foo bar ));
+DATA(insert OID = 209 ( float4larger PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 211 ( float4smaller PGUID 11 f t f 2 f 700 "700 700" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 212 ( int4um PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 213 ( int2um PGUID 11 f t f 1 f 21 "21" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 214 ( float8in PGUID 11 f t f 1 f 701 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 215 ( float8out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 216 ( float8mul PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 217 ( float8div PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 218 ( float8pl PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 219 ( float8mi PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 220 ( float8um PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 221 ( float8abs PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 222 ( float8inc PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 223 ( float8larger PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 224 ( float8smaller PGUID 11 f t f 2 f 701 "701 701" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 225 ( lseg_center PGUID 11 f t f 1 f 600 "601" 100 0 0 100 foo bar ));
+DATA(insert OID = 226 ( path_center PGUID 11 f t f 1 f 600 "602" 100 0 0 100 foo bar ));
+DATA(insert OID = 227 ( poly_center PGUID 11 f t f 1 f 600 "604" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 228 ( dround PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 229 ( dtrunc PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 230 ( dsqrt PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 231 ( dcbrt PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 232 ( dpow PGUID 11 f t f 2 f 701 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 233 ( dexp PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 234 ( dlog1 PGUID 11 f t f 1 f 701 "701" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 235 ( i2tod PGUID 11 f t f 1 f 701 "21" 100 0 0 100 foo bar ));
+DATA(insert OID = 236 ( i2tof PGUID 11 f t f 1 f 700 "21" 100 0 0 100 foo bar ));
+DATA(insert OID = 237 ( dtoi2 PGUID 11 f t f 1 f 21 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 238 ( ftoi2 PGUID 11 f t f 1 f 21 "700" 100 0 0 100 foo bar ));
+DATA(insert OID = 239 ( line_distance PGUID 11 f t f 2 f 701 "628 628" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 240 ( nabstimein PGUID 11 f t f 1 f 702 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 241 ( nabstimeout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 242 ( reltimein PGUID 11 f t f 1 f 703 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 243 ( reltimeout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 244 ( timepl PGUID 11 f t f 2 f 702 "702 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 245 ( timemi PGUID 11 f t f 2 f 702 "702 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 246 ( tintervalin PGUID 11 f t f 1 f 704 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 247 ( tintervalout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 248 ( ininterval PGUID 11 f t f 2 f 16 "702 704" 100 0 0 100 foo bar ));
+DATA(insert OID = 249 ( intervalrel PGUID 11 f t f 1 f 703 "704" 100 0 0 100 foo bar ));
+DATA(insert OID = 250 ( timenow PGUID 11 f t f 0 f 702 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 251 ( abstimeeq PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
+DATA(insert OID = 252 ( abstimene PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
+DATA(insert OID = 253 ( abstimelt PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
+DATA(insert OID = 254 ( abstimegt PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
+DATA(insert OID = 255 ( abstimele PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
+DATA(insert OID = 256 ( abstimege PGUID 11 f t f 2 f 16 "702 702" 100 0 0 100 foo bar ));
+DATA(insert OID = 257 ( reltimeeq PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 258 ( reltimene PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 259 ( reltimelt PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 260 ( reltimegt PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 261 ( reltimele PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 262 ( reltimege PGUID 11 f t f 2 f 16 "703 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 263 ( intervaleq PGUID 11 f t f 2 f 16 "704 704" 100 0 0 100 foo bar ));
+DATA(insert OID = 264 ( intervalct PGUID 11 f t f 2 f 16 "704 704" 100 0 0 100 foo bar ));
+DATA(insert OID = 265 ( intervalov PGUID 11 f t f 2 f 16 "704 704" 100 0 0 100 foo bar ));
+DATA(insert OID = 266 ( intervalleneq PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 267 ( intervallenne PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 268 ( intervallenlt PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 269 ( intervallengt PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 270 ( intervallenle PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 271 ( intervallenge PGUID 11 f t f 2 f 16 "704 703" 100 0 0 100 foo bar ));
+DATA(insert OID = 272 ( intervalstart PGUID 11 f t f 1 f 702 "704" 100 0 0 100 foo bar ));
+DATA(insert OID = 273 ( intervalend PGUID 11 f t f 1 f 702 "704" 100 0 0 100 foo bar ));
+DATA(insert OID = 274 ( timeofday PGUID 11 f t f 0 f 25 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 275 ( abstime_finite PGUID 11 f t f 1 f 16 "702" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 276 ( int2fac PGUID 11 f t f 1 f 21 "21" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 277 ( inter_sl PGUID 11 f t f 2 f 16 "601 628" 100 0 0 100 foo bar ));
+DATA(insert OID = 278 ( inter_lb PGUID 11 f t f 2 f 16 "628 603" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 279 ( float48mul PGUID 11 f t f 2 f 701 "700 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 280 ( float48div PGUID 11 f t f 2 f 701 "700 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 281 ( float48pl PGUID 11 f t f 2 f 701 "700 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 282 ( float48mi PGUID 11 f t f 2 f 701 "700 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 283 ( float84mul PGUID 11 f t f 2 f 701 "701 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 284 ( float84div PGUID 11 f t f 2 f 701 "701 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 285 ( float84pl PGUID 11 f t f 2 f 701 "701 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 286 ( float84mi PGUID 11 f t f 2 f 701 "701 700" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 287 ( float4eq PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 288 ( float4ne PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 289 ( float4lt PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 290 ( float4le PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 291 ( float4gt PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 292 ( float4ge PGUID 11 f t f 2 f 16 "700 700" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 293 ( float8eq PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 294 ( float8ne PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 295 ( float8lt PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 296 ( float8le PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 297 ( float8gt PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 298 ( float8ge PGUID 11 f t f 2 f 16 "701 701" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 299 ( float48eq PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
/* OIDS 300 - 399 */
-DATA(insert OID = 300 ( float48ne PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 301 ( float48lt PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 302 ( float48le PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 303 ( float48gt PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 304 ( float48ge PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 305 ( float84eq PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 306 ( float84ne PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 307 ( float84lt PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 308 ( float84le PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 309 ( float84gt PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 310 ( float84ge PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 311 ( ftod PGUID 11 f t f 2 f 701 "700" 100 0 0 100 foo bar ));
-DATA(insert OID = 312 ( dtof PGUID 11 f t f 2 f 700 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 313 ( i2toi4 PGUID 11 f t f 1 f 23 "21" 100 0 0 100 foo bar ));
-DATA(insert OID = 314 ( i4toi2 PGUID 11 f t f 1 f 21 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 315 ( keyfirsteq PGUID 11 f t f 2 f 16 "0 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 316 ( i4tod PGUID 11 f t f 1 f 701 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 317 ( dtoi4 PGUID 11 f t f 1 f 23 "701" 100 0 0 100 foo bar ));
-DATA(insert OID = 318 ( i4tof PGUID 11 f t f 1 f 700 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 319 ( ftoi4 PGUID 11 f t f 1 f 23 "700" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 320 ( rtinsert PGUID 11 f t f 5 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 321 ( rtdelete PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 322 ( rtgettuple PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 323 ( rtbuild PGUID 11 f t f 9 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 324 ( rtbeginscan PGUID 11 f t f 4 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 325 ( rtendscan PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 326 ( rtmarkpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 327 ( rtrestrpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 328 ( rtrescan PGUID 11 f t f 3 f 23 "0" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 330 ( btgettuple PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 331 ( btinsert PGUID 11 f t f 5 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 332 ( btdelete PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 333 ( btbeginscan PGUID 11 f t f 4 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 334 ( btrescan PGUID 11 f t f 3 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 335 ( btendscan PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 336 ( btmarkpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 337 ( btrestrpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 338 ( btbuild PGUID 11 f t f 9 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 339 ( poly_same PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
-DATA(insert OID = 340 ( poly_contain PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
-DATA(insert OID = 341 ( poly_left PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
-DATA(insert OID = 342 ( poly_overleft PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
+DATA(insert OID = 300 ( float48ne PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 301 ( float48lt PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 302 ( float48le PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 303 ( float48gt PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 304 ( float48ge PGUID 11 f t f 2 f 16 "700 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 305 ( float84eq PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 306 ( float84ne PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 307 ( float84lt PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 308 ( float84le PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 309 ( float84gt PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 310 ( float84ge PGUID 11 f t f 2 f 16 "701 700" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 311 ( ftod PGUID 11 f t f 2 f 701 "700" 100 0 0 100 foo bar ));
+DATA(insert OID = 312 ( dtof PGUID 11 f t f 2 f 700 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 313 ( i2toi4 PGUID 11 f t f 1 f 23 "21" 100 0 0 100 foo bar ));
+DATA(insert OID = 314 ( i4toi2 PGUID 11 f t f 1 f 21 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 315 ( keyfirsteq PGUID 11 f t f 2 f 16 "0 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 316 ( i4tod PGUID 11 f t f 1 f 701 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 317 ( dtoi4 PGUID 11 f t f 1 f 23 "701" 100 0 0 100 foo bar ));
+DATA(insert OID = 318 ( i4tof PGUID 11 f t f 1 f 700 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 319 ( ftoi4 PGUID 11 f t f 1 f 23 "700" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 320 ( rtinsert PGUID 11 f t f 5 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 321 ( rtdelete PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 322 ( rtgettuple PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 323 ( rtbuild PGUID 11 f t f 9 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 324 ( rtbeginscan PGUID 11 f t f 4 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 325 ( rtendscan PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 326 ( rtmarkpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 327 ( rtrestrpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 328 ( rtrescan PGUID 11 f t f 3 f 23 "0" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 330 ( btgettuple PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 331 ( btinsert PGUID 11 f t f 5 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 332 ( btdelete PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 333 ( btbeginscan PGUID 11 f t f 4 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 334 ( btrescan PGUID 11 f t f 3 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 335 ( btendscan PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 336 ( btmarkpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 337 ( btrestrpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 338 ( btbuild PGUID 11 f t f 9 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 339 ( poly_same PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
+DATA(insert OID = 340 ( poly_contain PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
+DATA(insert OID = 341 ( poly_left PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
+DATA(insert OID = 342 ( poly_overleft PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
DATA(insert OID = 343 ( poly_overright PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
-DATA(insert OID = 344 ( poly_right PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
+DATA(insert OID = 344 ( poly_right PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
DATA(insert OID = 345 ( poly_contained PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
-DATA(insert OID = 346 ( poly_overlap PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
-DATA(insert OID = 347 ( poly_in PGUID 11 f t f 1 f 604 "0" 100 0 1 0 foo bar ));
-DATA(insert OID = 348 ( poly_out PGUID 11 f t f 1 f 23 "0" 100 0 1 0 foo bar ));
-
-DATA(insert OID = 350 ( btint2cmp PGUID 11 f t f 2 f 23 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 351 ( btint4cmp PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 352 ( btint42cmp PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 353 ( btint24cmp PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 354 ( btfloat4cmp PGUID 11 f t f 2 f 23 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 355 ( btfloat8cmp PGUID 11 f t f 2 f 23 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 356 ( btoidcmp PGUID 11 f t f 2 f 23 "26 26" 100 0 0 100 foo bar ));
-DATA(insert OID = 357 ( btabstimecmp PGUID 11 f t f 2 f 23 "702 702" 100 0 0 100 foo bar ));
-DATA(insert OID = 358 ( btcharcmp PGUID 11 f t f 2 f 23 "18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 359 ( btnamecmp PGUID 11 f t f 2 f 23 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 360 ( bttextcmp PGUID 11 f t f 2 f 23 "25 25" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 361 ( lseg_distance PGUID 11 f t f 2 f 701 "601 601" 100 0 0 100 foo bar ));
-DATA(insert OID = 362 ( lseg_interpt PGUID 11 f t f 2 f 600 "601 601" 100 0 0 100 foo bar ));
-DATA(insert OID = 363 ( dist_ps PGUID 11 f t f 2 f 701 "600 601" 100 0 0 100 foo bar ));
-DATA(insert OID = 364 ( dist_pb PGUID 11 f t f 2 f 701 "600 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 365 ( dist_sb PGUID 11 f t f 2 f 701 "601 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 366 ( close_ps PGUID 11 f t f 2 f 600 "600 601" 100 0 0 100 foo bar ));
-DATA(insert OID = 367 ( close_pb PGUID 11 f t f 2 f 600 "600 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 368 ( close_sb PGUID 11 f t f 2 f 600 "601 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 369 ( on_ps PGUID 11 f t f 2 f 16 "600 601" 100 0 0 100 foo bar ));
-DATA(insert OID = 370 ( path_distance PGUID 11 f t f 2 f 701 "602 602" 100 0 1 0 foo bar ));
-DATA(insert OID = 371 ( dist_ppath PGUID 11 f t f 2 f 701 "600 602" 100 0 1 0 foo bar ));
-DATA(insert OID = 372 ( on_sb PGUID 11 f t f 2 f 16 "601 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 373 ( inter_sb PGUID 11 f t f 2 f 16 "601 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 1274 ( btchar16cmp PGUID 11 f t f 2 f 23 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 346 ( poly_overlap PGUID 11 f t f 2 f 16 "604 604" 100 0 1 0 foo bar ));
+DATA(insert OID = 347 ( poly_in PGUID 11 f t f 1 f 604 "0" 100 0 1 0 foo bar ));
+DATA(insert OID = 348 ( poly_out PGUID 11 f t f 1 f 23 "0" 100 0 1 0 foo bar ));
+
+DATA(insert OID = 350 ( btint2cmp PGUID 11 f t f 2 f 23 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 351 ( btint4cmp PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 352 ( btint42cmp PGUID 11 f t f 2 f 23 "23 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 353 ( btint24cmp PGUID 11 f t f 2 f 23 "21 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 354 ( btfloat4cmp PGUID 11 f t f 2 f 23 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 355 ( btfloat8cmp PGUID 11 f t f 2 f 23 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 356 ( btoidcmp PGUID 11 f t f 2 f 23 "26 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 357 ( btabstimecmp PGUID 11 f t f 2 f 23 "702 702" 100 0 0 100 foo bar ));
+DATA(insert OID = 358 ( btcharcmp PGUID 11 f t f 2 f 23 "18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 359 ( btnamecmp PGUID 11 f t f 2 f 23 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 360 ( bttextcmp PGUID 11 f t f 2 f 23 "25 25" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 361 ( lseg_distance PGUID 11 f t f 2 f 701 "601 601" 100 0 0 100 foo bar ));
+DATA(insert OID = 362 ( lseg_interpt PGUID 11 f t f 2 f 600 "601 601" 100 0 0 100 foo bar ));
+DATA(insert OID = 363 ( dist_ps PGUID 11 f t f 2 f 701 "600 601" 100 0 0 100 foo bar ));
+DATA(insert OID = 364 ( dist_pb PGUID 11 f t f 2 f 701 "600 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 365 ( dist_sb PGUID 11 f t f 2 f 701 "601 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 366 ( close_ps PGUID 11 f t f 2 f 600 "600 601" 100 0 0 100 foo bar ));
+DATA(insert OID = 367 ( close_pb PGUID 11 f t f 2 f 600 "600 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 368 ( close_sb PGUID 11 f t f 2 f 600 "601 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 369 ( on_ps PGUID 11 f t f 2 f 16 "600 601" 100 0 0 100 foo bar ));
+DATA(insert OID = 370 ( path_distance PGUID 11 f t f 2 f 701 "602 602" 100 0 1 0 foo bar ));
+DATA(insert OID = 371 ( dist_ppath PGUID 11 f t f 2 f 701 "600 602" 100 0 1 0 foo bar ));
+DATA(insert OID = 372 ( on_sb PGUID 11 f t f 2 f 16 "601 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 373 ( inter_sb PGUID 11 f t f 2 f 16 "601 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 1274 ( btchar16cmp PGUID 11 f t f 2 f 23 "19 19" 100 0 0 100 foo bar ));
/* OIDS 400 - 499 */
-DATA(insert OID = 438 ( hashsel PGUID 11 f t t 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
-DATA(insert OID = 439 ( hashnpage PGUID 11 f t t 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 440 ( hashgettuple PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 441 ( hashinsert PGUID 11 f t f 5 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 442 ( hashdelete PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 443 ( hashbeginscan PGUID 11 f t f 4 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 444 ( hashrescan PGUID 11 f t f 3 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 445 ( hashendscan PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 446 ( hashmarkpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 447 ( hashrestrpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 448 ( hashbuild PGUID 11 f t f 9 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 449 ( hashint2 PGUID 11 f t f 2 f 23 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 450 ( hashint4 PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 451 ( hashfloat4 PGUID 11 f t f 2 f 23 "700 700" 100 0 0 100 foo bar ));
-DATA(insert OID = 452 ( hashfloat8 PGUID 11 f t f 2 f 23 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 453 ( hashoid PGUID 11 f t f 2 f 23 "26 26" 100 0 0 100 foo bar ));
-DATA(insert OID = 454 ( hashchar PGUID 11 f t f 2 f 23 "18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 455 ( hashname PGUID 11 f t f 2 f 23 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 456 ( hashtext PGUID 11 f t f 2 f 23 "25 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 466 ( char2in PGUID 11 f t f 1 f 409 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 467 ( char4in PGUID 11 f t f 1 f 410 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 468 ( char8in PGUID 11 f t f 1 f 411 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 469 ( char2out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 470 ( char4out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 471 ( char8out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 472 ( char2eq PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
-DATA(insert OID = 473 ( char4eq PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
-DATA(insert OID = 474 ( char8eq PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
-DATA(insert OID = 475 ( char2lt PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
-DATA(insert OID = 476 ( char4lt PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
-DATA(insert OID = 477 ( char8lt PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
-DATA(insert OID = 478 ( char2le PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
-DATA(insert OID = 479 ( char4le PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
-DATA(insert OID = 480 ( char8le PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
-DATA(insert OID = 481 ( char2gt PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
-DATA(insert OID = 482 ( char4gt PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
-DATA(insert OID = 483 ( char8gt PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
-DATA(insert OID = 484 ( char2ge PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
-DATA(insert OID = 1275 ( char16eq PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 438 ( hashsel PGUID 11 f t t 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 439 ( hashnpage PGUID 11 f t t 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 440 ( hashgettuple PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 441 ( hashinsert PGUID 11 f t f 5 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 442 ( hashdelete PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 443 ( hashbeginscan PGUID 11 f t f 4 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 444 ( hashrescan PGUID 11 f t f 3 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 445 ( hashendscan PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 446 ( hashmarkpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 447 ( hashrestrpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 448 ( hashbuild PGUID 11 f t f 9 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 449 ( hashint2 PGUID 11 f t f 2 f 23 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 450 ( hashint4 PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 451 ( hashfloat4 PGUID 11 f t f 2 f 23 "700 700" 100 0 0 100 foo bar ));
+DATA(insert OID = 452 ( hashfloat8 PGUID 11 f t f 2 f 23 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 453 ( hashoid PGUID 11 f t f 2 f 23 "26 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 454 ( hashchar PGUID 11 f t f 2 f 23 "18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 455 ( hashname PGUID 11 f t f 2 f 23 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 456 ( hashtext PGUID 11 f t f 2 f 23 "25 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 466 ( char2in PGUID 11 f t f 1 f 409 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 467 ( char4in PGUID 11 f t f 1 f 410 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 468 ( char8in PGUID 11 f t f 1 f 411 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 469 ( char2out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 470 ( char4out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 471 ( char8out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 472 ( char2eq PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
+DATA(insert OID = 473 ( char4eq PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
+DATA(insert OID = 474 ( char8eq PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
+DATA(insert OID = 475 ( char2lt PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
+DATA(insert OID = 476 ( char4lt PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
+DATA(insert OID = 477 ( char8lt PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
+DATA(insert OID = 478 ( char2le PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
+DATA(insert OID = 479 ( char4le PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
+DATA(insert OID = 480 ( char8le PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
+DATA(insert OID = 481 ( char2gt PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
+DATA(insert OID = 482 ( char4gt PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
+DATA(insert OID = 483 ( char8gt PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
+DATA(insert OID = 484 ( char2ge PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
+DATA(insert OID = 1275 ( char16eq PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
#define Character16EqualRegProcedure 1275
-DATA(insert OID = 1276 ( char16lt PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 1277 ( char16le PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 1278 ( char16gt PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 1279 ( char16ge PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 1280 ( char16ne PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 1276 ( char16lt PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 1277 ( char16le PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 1278 ( char16gt PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 1279 ( char16ge PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 1280 ( char16ne PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 1281 ( hashchar16 PGUID 11 f t f 2 f 23 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 1281 ( hashchar16 PGUID 11 f t f 2 f 23 "19 19" 100 0 0 100 foo bar ));
/* OIDS 500 - 599 */
/* OIDS 600 - 699 */
-DATA(insert OID = 1285 ( int4notin PGUID 11 f t f 2 f 16 "21 0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1286 ( oidnotin PGUID 11 f t f 2 f 16 "26 0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1287 ( int44in PGUID 11 f t f 1 f 22 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 653 ( int44out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 655 ( namelt PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 656 ( namele PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 657 ( namegt PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 658 ( namege PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 659 ( namene PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
-DATA(insert OID = 682 ( mktinterval PGUID 11 f t f 2 f 704 "702 702" 100 0 0 100 foo bar ));
-DATA(insert OID = 683 ( oid8eq PGUID 11 f t f 2 f 16 "30 30" 100 0 0 100 foo bar ));
-DATA(insert OID = 684 ( char4ge PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
-DATA(insert OID = 685 ( char8ge PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
-DATA(insert OID = 686 ( char2ne PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
-DATA(insert OID = 687 ( char4ne PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
-DATA(insert OID = 688 ( char8ne PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
-DATA(insert OID = 689 ( btchar2cmp PGUID 11 f t f 2 f 23 "409 409" 100 0 0 100 foo bar ));
-DATA(insert OID = 690 ( btchar4cmp PGUID 11 f t f 2 f 23 "410 410" 100 0 0 100 foo bar ));
-DATA(insert OID = 691 ( btchar8cmp PGUID 11 f t f 2 f 23 "411 411" 100 0 0 100 foo bar ));
-DATA(insert OID = 692 ( hashchar2 PGUID 11 f t f 2 f 23 "409 409" 100 0 0 100 foo bar ));
-DATA(insert OID = 693 ( hashchar4 PGUID 11 f t f 2 f 23 "410 410" 100 0 0 100 foo bar ));
-DATA(insert OID = 694 ( hashchar8 PGUID 11 f t f 2 f 23 "411 411" 100 0 0 100 foo bar ));
-DATA(insert OID = 695 ( char8regexeq PGUID 11 f t f 2 f 16 "411 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 696 ( char8regexne PGUID 11 f t f 2 f 16 "411 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 699 ( char2regexeq PGUID 11 f t f 2 f 16 "409 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1285 ( int4notin PGUID 11 f t f 2 f 16 "21 0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1286 ( oidnotin PGUID 11 f t f 2 f 16 "26 0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1287 ( int44in PGUID 11 f t f 1 f 22 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 653 ( int44out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 655 ( namelt PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 656 ( namele PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 657 ( namegt PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 658 ( namege PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 659 ( namene PGUID 11 f t f 2 f 16 "19 19" 100 0 0 100 foo bar ));
+DATA(insert OID = 682 ( mktinterval PGUID 11 f t f 2 f 704 "702 702" 100 0 0 100 foo bar ));
+DATA(insert OID = 683 ( oid8eq PGUID 11 f t f 2 f 16 "30 30" 100 0 0 100 foo bar ));
+DATA(insert OID = 684 ( char4ge PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
+DATA(insert OID = 685 ( char8ge PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
+DATA(insert OID = 686 ( char2ne PGUID 11 f t f 2 f 16 "409 409" 100 0 0 100 foo bar ));
+DATA(insert OID = 687 ( char4ne PGUID 11 f t f 2 f 16 "410 410" 100 0 0 100 foo bar ));
+DATA(insert OID = 688 ( char8ne PGUID 11 f t f 2 f 16 "411 411" 100 0 0 100 foo bar ));
+DATA(insert OID = 689 ( btchar2cmp PGUID 11 f t f 2 f 23 "409 409" 100 0 0 100 foo bar ));
+DATA(insert OID = 690 ( btchar4cmp PGUID 11 f t f 2 f 23 "410 410" 100 0 0 100 foo bar ));
+DATA(insert OID = 691 ( btchar8cmp PGUID 11 f t f 2 f 23 "411 411" 100 0 0 100 foo bar ));
+DATA(insert OID = 692 ( hashchar2 PGUID 11 f t f 2 f 23 "409 409" 100 0 0 100 foo bar ));
+DATA(insert OID = 693 ( hashchar4 PGUID 11 f t f 2 f 23 "410 410" 100 0 0 100 foo bar ));
+DATA(insert OID = 694 ( hashchar8 PGUID 11 f t f 2 f 23 "411 411" 100 0 0 100 foo bar ));
+DATA(insert OID = 695 ( char8regexeq PGUID 11 f t f 2 f 16 "411 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 696 ( char8regexne PGUID 11 f t f 2 f 16 "411 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 699 ( char2regexeq PGUID 11 f t f 2 f 16 "409 25" 100 0 0 100 foo bar ));
/* OIDS 700 - 799 */
DATA(insert OID = 1288 ( char16regexeq PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
DATA(insert OID = 1289 ( char16regexne PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 710 ( getpgusername PGUID 11 f t f 0 f 19 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 711 ( userfntest PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 713 ( oidrand PGUID 11 f t f 2 f 16 "26 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 715 ( oidsrand PGUID 11 f t f 1 f 16 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 716 ( oideqint4 PGUID 11 f t f 2 f 16 "26 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 717 ( int4eqoid PGUID 11 f t f 2 f 16 "23 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 710 ( getpgusername PGUID 11 f t f 0 f 19 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 711 ( userfntest PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 713 ( oidrand PGUID 11 f t f 2 f 16 "26 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 715 ( oidsrand PGUID 11 f t f 1 f 16 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 716 ( oideqint4 PGUID 11 f t f 2 f 16 "26 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 717 ( int4eqoid PGUID 11 f t f 2 f 16 "23 26" 100 0 0 100 foo bar ));
DATA(insert OID = 720 ( byteaGetSize PGUID 11 f t f 1 f 23 "17" 100 0 0 100 foo bar ));
DATA(insert OID = 721 ( byteaGetByte PGUID 11 f t f 2 f 23 "17 23" 100 0 0 100 foo bar ));
@@ -564,300 +565,300 @@ DATA(insert OID = 722 ( byteaSetByte PGUID 11 f t f 3 f 17 "17 23 23" 100 0
DATA(insert OID = 723 ( byteaGetBit PGUID 11 f t f 2 f 23 "17 23" 100 0 0 100 foo bar ));
DATA(insert OID = 724 ( byteaSetBit PGUID 11 f t f 3 f 17 "17 23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 725 ( dist_pl PGUID 11 f t f 2 f 701 "600 628" 100 0 0 100 foo bar ));
-DATA(insert OID = 726 ( dist_lb PGUID 11 f t f 2 f 701 "628 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 727 ( dist_sl PGUID 11 f t f 2 f 701 "601 628" 100 0 0 100 foo bar ));
-DATA(insert OID = 728 ( dist_cpoly PGUID 11 f t f 2 f 701 "718 604" 100 0 0 100 foo bar ));
-DATA(insert OID = 729 ( poly_distance PGUID 11 f t f 2 f 701 "604 604" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 730 ( pqtest PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 740 ( text_lt PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
-DATA(insert OID = 741 ( text_le PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
-DATA(insert OID = 742 ( text_gt PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
-DATA(insert OID = 743 ( text_ge PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
-
-DATA(insert OID = 744 ( array_eq PGUID 11 f t f 2 f 16 "0 0" 100 0 0 100 foo bar));
-DATA(insert OID = 745 ( array_assgn PGUID 11 f t f 8 f 23 "0 23 0 0 0 23 23 0" 100 0 0 100 foo bar));
-DATA(insert OID = 746 ( array_clip PGUID 11 f t f 7 f 23 "0 23 0 0 23 23 0" 100 0 0 100 foo bar));
-DATA(insert OID = 747 ( array_dims PGUID 11 f t f 1 f 25 "0" 100 0 0 100 foo bar));
-DATA(insert OID = 748 ( array_set PGUID 11 f t f 8 f 23 "0 23 0 0 23 23 23 0" 100 0 0 100 foo bar));
-DATA(insert OID = 749 ( array_ref PGUID 11 f t f 7 f 23 "0 23 0 23 23 23 0" 100 0 0 100 foo bar));
-DATA(insert OID = 750 ( array_in PGUID 11 f t f 2 f 23 "0 0" 100 0 0 100 foo bar ));
-DATA(insert OID = 751 ( array_out PGUID 11 f t f 2 f 23 "0 0" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 752 ( filename_in PGUID 11 f t f 2 f 605 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 753 ( filename_out PGUID 11 f t f 2 f 19 "0" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 760 ( smgrin PGUID 11 f t f 1 f 210 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 761 ( smgrout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 762 ( smgreq PGUID 11 f t f 2 f 16 "210 210" 100 0 0 100 foo bar ));
-DATA(insert OID = 763 ( smgrne PGUID 11 f t f 2 f 16 "210 210" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 764 ( lo_import PGUID 11 f t f 1 f 26 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 765 ( lo_export PGUID 11 f t f 2 f 23 "26 25" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 766 ( int4inc PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 767 ( int2inc PGUID 11 f t f 1 f 21 "21" 100 0 0 100 foo bar ));
-DATA(insert OID = 768 ( int4larger PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 769 ( int4smaller PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 770 ( int2larger PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 771 ( int2smaller PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
-DATA(insert OID = 772 ( gistsel PGUID 11 f t t 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
-DATA(insert OID = 773 ( gistnpage PGUID 11 f t t 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
-DATA(insert OID = 774 ( gistgettuple PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 775 ( gistinsert PGUID 11 f t f 5 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 776 ( gistdelete PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 777 ( gistbeginscan PGUID 11 f t f 4 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 778 ( gistrescan PGUID 11 f t f 3 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 779 ( gistendscan PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 780 ( gistmarkpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 781 ( gistrestrpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 782 ( gistbuild PGUID 11 f t f 9 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 725 ( dist_pl PGUID 11 f t f 2 f 701 "600 628" 100 0 0 100 foo bar ));
+DATA(insert OID = 726 ( dist_lb PGUID 11 f t f 2 f 701 "628 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 727 ( dist_sl PGUID 11 f t f 2 f 701 "601 628" 100 0 0 100 foo bar ));
+DATA(insert OID = 728 ( dist_cpoly PGUID 11 f t f 2 f 701 "718 604" 100 0 0 100 foo bar ));
+DATA(insert OID = 729 ( poly_distance PGUID 11 f t f 2 f 701 "604 604" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 730 ( pqtest PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 740 ( text_lt PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
+DATA(insert OID = 741 ( text_le PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
+DATA(insert OID = 742 ( text_gt PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
+DATA(insert OID = 743 ( text_ge PGUID 11 f t f 2 f 16 "25 25" 100 0 0 0 foo bar ));
+
+DATA(insert OID = 744 ( array_eq PGUID 11 f t f 2 f 16 "0 0" 100 0 0 100 foo bar));
+DATA(insert OID = 745 ( array_assgn PGUID 11 f t f 8 f 23 "0 23 0 0 0 23 23 0" 100 0 0 100 foo bar));
+DATA(insert OID = 746 ( array_clip PGUID 11 f t f 7 f 23 "0 23 0 0 23 23 0" 100 0 0 100 foo bar));
+DATA(insert OID = 747 ( array_dims PGUID 11 f t f 1 f 25 "0" 100 0 0 100 foo bar));
+DATA(insert OID = 748 ( array_set PGUID 11 f t f 8 f 23 "0 23 0 0 23 23 23 0" 100 0 0 100 foo bar));
+DATA(insert OID = 749 ( array_ref PGUID 11 f t f 7 f 23 "0 23 0 23 23 23 0" 100 0 0 100 foo bar));
+DATA(insert OID = 750 ( array_in PGUID 11 f t f 2 f 23 "0 0" 100 0 0 100 foo bar ));
+DATA(insert OID = 751 ( array_out PGUID 11 f t f 2 f 23 "0 0" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 752 ( filename_in PGUID 11 f t f 2 f 605 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 753 ( filename_out PGUID 11 f t f 2 f 19 "0" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 760 ( smgrin PGUID 11 f t f 1 f 210 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 761 ( smgrout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 762 ( smgreq PGUID 11 f t f 2 f 16 "210 210" 100 0 0 100 foo bar ));
+DATA(insert OID = 763 ( smgrne PGUID 11 f t f 2 f 16 "210 210" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 764 ( lo_import PGUID 11 f t f 1 f 26 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 765 ( lo_export PGUID 11 f t f 2 f 23 "26 25" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 766 ( int4inc PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 767 ( int2inc PGUID 11 f t f 1 f 21 "21" 100 0 0 100 foo bar ));
+DATA(insert OID = 768 ( int4larger PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 769 ( int4smaller PGUID 11 f t f 2 f 23 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 770 ( int2larger PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 771 ( int2smaller PGUID 11 f t f 2 f 21 "21 21" 100 0 0 100 foo bar ));
+DATA(insert OID = 772 ( gistsel PGUID 11 f t t 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 773 ( gistnpage PGUID 11 f t t 7 f 701 "26 26 21 0 23 23 26" 100 0 0 100 foo bar ));
+DATA(insert OID = 774 ( gistgettuple PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 775 ( gistinsert PGUID 11 f t f 5 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 776 ( gistdelete PGUID 11 f t f 2 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 777 ( gistbeginscan PGUID 11 f t f 4 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 778 ( gistrescan PGUID 11 f t f 3 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 779 ( gistendscan PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 780 ( gistmarkpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 781 ( gistrestrpos PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 782 ( gistbuild PGUID 11 f t f 9 f 23 "0" 100 0 0 100 foo bar ));
/* OIDS 800 - 899 */
-DATA(insert OID = 820 ( oidint2in PGUID 11 f t f 1 f 810 "0" 100 0 0 100 foo bar));
-DATA(insert OID = 821 ( oidint2out PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar));
-DATA(insert OID = 822 ( oidint2lt PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
-DATA(insert OID = 823 ( oidint2le PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
-DATA(insert OID = 824 ( oidint2eq PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
+DATA(insert OID = 820 ( oidint2in PGUID 11 f t f 1 f 810 "0" 100 0 0 100 foo bar));
+DATA(insert OID = 821 ( oidint2out PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar));
+DATA(insert OID = 822 ( oidint2lt PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
+DATA(insert OID = 823 ( oidint2le PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
+DATA(insert OID = 824 ( oidint2eq PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
#define OidInt2EqRegProcedure 824
-DATA(insert OID = 825 ( oidint2ge PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
-DATA(insert OID = 826 ( oidint2gt PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
-DATA(insert OID = 827 ( oidint2ne PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
-DATA(insert OID = 828 ( oidint2cmp PGUID 11 f t f 2 f 21 "810 810" 100 0 0 100 foo bar));
-DATA(insert OID = 829 ( mkoidint2 PGUID 11 f t f 2 f 810 "26 21" 100 0 0 100 foo bar));
-
-DATA(insert OID = 837 ( char2regexne PGUID 11 f t f 2 f 16 "409 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 836 ( char4regexeq PGUID 11 f t f 2 f 16 "410 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 838 ( char4regexne PGUID 11 f t f 2 f 16 "410 25" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 849 ( textpos PGUID 11 f t f 2 f 23 "25 25" 100 0 1 0 foo bar ));
-DATA(insert OID = 850 ( textlike PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
-DATA(insert OID = 851 ( textnlike PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
-DATA(insert OID = 852 ( char2like PGUID 11 f t f 2 f 16 "409 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 853 ( char2nlike PGUID 11 f t f 2 f 16 "409 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 854 ( char4like PGUID 11 f t f 2 f 16 "410 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 855 ( char4nlike PGUID 11 f t f 2 f 16 "410 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 856 ( char8like PGUID 11 f t f 2 f 16 "411 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 857 ( char8nlike PGUID 11 f t f 2 f 16 "411 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 858 ( namelike PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 859 ( namenlike PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 860 ( char16like PGUID 11 f t f 2 f 16 "20 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 861 ( char16nlike PGUID 11 f t f 2 f 16 "20 25" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 886 ( cash_in PGUID 11 f t f 1 f 790 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 887 ( cash_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 888 ( cash_eq PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
-DATA(insert OID = 889 ( cash_ne PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
-DATA(insert OID = 890 ( cash_lt PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
-DATA(insert OID = 891 ( cash_le PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
-DATA(insert OID = 892 ( cash_gt PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
-DATA(insert OID = 893 ( cash_ge PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
-DATA(insert OID = 894 ( cash_pl PGUID 11 f t f 2 f 790 "790 790" 100 0 0 100 foo bar ));
-DATA(insert OID = 895 ( cash_mi PGUID 11 f t f 2 f 790 "790 790" 100 0 0 100 foo bar ));
-DATA(insert OID = 896 ( cash_mul PGUID 11 f t f 2 f 790 "790 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 897 ( cash_div PGUID 11 f t f 2 f 790 "790 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 898 ( cashlarger PGUID 11 f t f 2 f 790 "790 790" 100 0 0 100 foo bar ));
-DATA(insert OID = 899 ( cashsmaller PGUID 11 f t f 2 f 790 "790 790" 100 0 0 100 foo bar ));
+DATA(insert OID = 825 ( oidint2ge PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
+DATA(insert OID = 826 ( oidint2gt PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
+DATA(insert OID = 827 ( oidint2ne PGUID 11 f t f 2 f 16 "810 810" 100 0 0 100 foo bar));
+DATA(insert OID = 828 ( oidint2cmp PGUID 11 f t f 2 f 21 "810 810" 100 0 0 100 foo bar));
+DATA(insert OID = 829 ( mkoidint2 PGUID 11 f t f 2 f 810 "26 21" 100 0 0 100 foo bar));
+
+DATA(insert OID = 837 ( char2regexne PGUID 11 f t f 2 f 16 "409 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 836 ( char4regexeq PGUID 11 f t f 2 f 16 "410 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 838 ( char4regexne PGUID 11 f t f 2 f 16 "410 25" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 849 ( textpos PGUID 11 f t f 2 f 23 "25 25" 100 0 1 0 foo bar ));
+DATA(insert OID = 850 ( textlike PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
+DATA(insert OID = 851 ( textnlike PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
+DATA(insert OID = 852 ( char2like PGUID 11 f t f 2 f 16 "409 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 853 ( char2nlike PGUID 11 f t f 2 f 16 "409 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 854 ( char4like PGUID 11 f t f 2 f 16 "410 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 855 ( char4nlike PGUID 11 f t f 2 f 16 "410 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 856 ( char8like PGUID 11 f t f 2 f 16 "411 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 857 ( char8nlike PGUID 11 f t f 2 f 16 "411 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 858 ( namelike PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 859 ( namenlike PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 860 ( char16like PGUID 11 f t f 2 f 16 "20 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 861 ( char16nlike PGUID 11 f t f 2 f 16 "20 25" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 886 ( cash_in PGUID 11 f t f 1 f 790 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 887 ( cash_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 888 ( cash_eq PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
+DATA(insert OID = 889 ( cash_ne PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
+DATA(insert OID = 890 ( cash_lt PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
+DATA(insert OID = 891 ( cash_le PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
+DATA(insert OID = 892 ( cash_gt PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
+DATA(insert OID = 893 ( cash_ge PGUID 11 f t f 2 f 16 "790 790" 100 0 0 100 foo bar ));
+DATA(insert OID = 894 ( cash_pl PGUID 11 f t f 2 f 790 "790 790" 100 0 0 100 foo bar ));
+DATA(insert OID = 895 ( cash_mi PGUID 11 f t f 2 f 790 "790 790" 100 0 0 100 foo bar ));
+DATA(insert OID = 896 ( cash_mul PGUID 11 f t f 2 f 790 "790 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 897 ( cash_div PGUID 11 f t f 2 f 790 "790 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 898 ( cashlarger PGUID 11 f t f 2 f 790 "790 790" 100 0 0 100 foo bar ));
+DATA(insert OID = 899 ( cashsmaller PGUID 11 f t f 2 f 790 "790 790" 100 0 0 100 foo bar ));
/* OIDS 900 - 999 */
-DATA(insert OID = 920 ( oidint4in PGUID 11 f t f 1 f 910 "0" 100 0 0 100 foo bar));
-DATA(insert OID = 921 ( oidint4out PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar));
-DATA(insert OID = 922 ( oidint4lt PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
-DATA(insert OID = 923 ( oidint4le PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
-DATA(insert OID = 924 ( oidint4eq PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
+DATA(insert OID = 920 ( oidint4in PGUID 11 f t f 1 f 910 "0" 100 0 0 100 foo bar));
+DATA(insert OID = 921 ( oidint4out PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar));
+DATA(insert OID = 922 ( oidint4lt PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
+DATA(insert OID = 923 ( oidint4le PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
+DATA(insert OID = 924 ( oidint4eq PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
#define OidInt4EqRegProcedure 924
-DATA(insert OID = 925 ( oidint4ge PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
-DATA(insert OID = 926 ( oidint4gt PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
-DATA(insert OID = 927 ( oidint4ne PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
-DATA(insert OID = 928 ( oidint4cmp PGUID 11 f t f 2 f 23 "910 910" 100 0 0 100 foo bar));
-DATA(insert OID = 929 ( mkoidint4 PGUID 11 f t f 2 f 910 "26 23" 100 0 0 100 foo bar));
+DATA(insert OID = 925 ( oidint4ge PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
+DATA(insert OID = 926 ( oidint4gt PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
+DATA(insert OID = 927 ( oidint4ne PGUID 11 f t f 2 f 16 "910 910" 100 0 0 100 foo bar));
+DATA(insert OID = 928 ( oidint4cmp PGUID 11 f t f 2 f 23 "910 910" 100 0 0 100 foo bar));
+DATA(insert OID = 929 ( mkoidint4 PGUID 11 f t f 2 f 910 "26 23" 100 0 0 100 foo bar));
/* isoldpath, upgradepath, upgradepoly, revertpoly are used to update pre-v6.1 to v6.1 - tgl 97/06/03 */
-DATA(insert OID = 936 ( isoldpath PGUID 11 f t f 1 f 16 "602" 100 0 0 100 foo bar ));
-DATA(insert OID = 937 ( upgradepath PGUID 11 f t f 1 f 602 "602" 100 0 0 100 foo bar ));
-DATA(insert OID = 938 ( upgradepoly PGUID 11 f t f 1 f 604 "604" 100 0 0 100 foo bar ));
-DATA(insert OID = 939 ( revertpoly PGUID 11 f t f 1 f 604 "604" 100 0 0 100 foo bar ));
+DATA(insert OID = 936 ( isoldpath PGUID 11 f t f 1 f 16 "602" 100 0 0 100 foo bar ));
+DATA(insert OID = 937 ( upgradepath PGUID 11 f t f 1 f 602 "602" 100 0 0 100 foo bar ));
+DATA(insert OID = 938 ( upgradepoly PGUID 11 f t f 1 f 604 "604" 100 0 0 100 foo bar ));
+DATA(insert OID = 939 ( revertpoly PGUID 11 f t f 1 f 604 "604" 100 0 0 100 foo bar ));
-DATA(insert OID = 940 ( oidnamein PGUID 11 f t f 1 f 911 "0" 100 0 0 100 foo bar));
-DATA(insert OID = 941 ( oidnameout PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar));
-DATA(insert OID = 942 ( oidnamelt PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
-DATA(insert OID = 943 ( oidnamele PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
-DATA(insert OID = 944 ( oidnameeq PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
+DATA(insert OID = 940 ( oidnamein PGUID 11 f t f 1 f 911 "0" 100 0 0 100 foo bar));
+DATA(insert OID = 941 ( oidnameout PGUID 11 f t f 1 f 19 "0" 100 0 0 100 foo bar));
+DATA(insert OID = 942 ( oidnamelt PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
+DATA(insert OID = 943 ( oidnamele PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
+DATA(insert OID = 944 ( oidnameeq PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
#define OidNameEqRegProcedure 944
-DATA(insert OID = 945 ( oidnamege PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
-DATA(insert OID = 946 ( oidnamegt PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
-DATA(insert OID = 947 ( oidnamene PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
-DATA(insert OID = 948 ( oidnamecmp PGUID 11 f t f 2 f 23 "911 911" 100 0 0 100 foo bar));
-DATA(insert OID = 949 ( mkoidname PGUID 11 f t f 2 f 911 "26 19" 100 0 0 100 foo bar));
-
-DATA(insert OID = 952 ( lo_open PGUID 11 f t f 2 f 23 "26 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 953 ( lo_close PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 954 ( loread PGUID 11 f t f 2 f 17 "23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 955 ( lowrite PGUID 11 f t f 2 f 23 "23 17" 100 0 0 100 foo bar ));
-DATA(insert OID = 956 ( lo_lseek PGUID 11 f t f 3 f 23 "23 23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 957 ( lo_creat PGUID 11 f t f 1 f 26 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 958 ( lo_tell PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 959 ( on_pl PGUID 11 f t f 2 f 16 "600 628" 100 0 10 100 foo bar ));
-DATA(insert OID = 960 ( on_sl PGUID 11 f t f 2 f 16 "601 628" 100 0 10 100 foo bar ));
-DATA(insert OID = 961 ( close_pl PGUID 11 f t f 2 f 600 "600 628" 100 0 10 100 foo bar ));
-DATA(insert OID = 962 ( close_sl PGUID 11 f t f 2 f 600 "601 628" 100 0 10 100 foo bar ));
-DATA(insert OID = 963 ( close_lb PGUID 11 f t f 2 f 600 "628 603" 100 0 10 100 foo bar ));
-
-DATA(insert OID = 964 ( lo_unlink PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
-DATA(insert OID = 972 ( regproctooid PGUID 11 f t f 1 f 26 "24" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 973 ( path_inter PGUID 11 f t f 2 f 16 "602 602" 100 0 10 100 foo bar ));
-DATA(insert OID = 975 ( box_area PGUID 11 f t f 1 f 701 "603" 100 0 0 100 foo bar ));
-DATA(insert OID = 976 ( box_width PGUID 11 f t f 1 f 701 "603" 100 0 0 100 foo bar ));
-DATA(insert OID = 977 ( box_height PGUID 11 f t f 1 f 701 "603" 100 0 0 100 foo bar ));
-DATA(insert OID = 978 ( box_distance PGUID 11 f t f 2 f 701 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 980 ( box_intersect PGUID 11 f t f 2 f 603 "603 603" 100 0 0 100 foo bar ));
-DATA(insert OID = 981 ( box_diagonal PGUID 11 f t f 1 f 601 "603" 100 0 0 100 foo bar ));
-DATA(insert OID = 982 ( path_n_lt PGUID 11 f t f 2 f 16 "602 602" 100 0 0 100 foo bar ));
-DATA(insert OID = 983 ( path_n_gt PGUID 11 f t f 2 f 16 "602 602" 100 0 0 100 foo bar ));
-DATA(insert OID = 984 ( path_n_eq PGUID 11 f t f 2 f 16 "602 602" 100 0 0 100 foo bar ));
-DATA(insert OID = 985 ( path_n_le PGUID 11 f t f 2 f 16 "602 602" 100 0 0 100 foo bar ));
-DATA(insert OID = 986 ( path_n_ge PGUID 11 f t f 2 f 16 "602 602" 100 0 0 100 foo bar ));
-DATA(insert OID = 987 ( path_length PGUID 11 f t f 1 f 701 "602" 100 0 1 0 foo bar ));
-DATA(insert OID = 989 ( point_vert PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 990 ( point_horiz PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 945 ( oidnamege PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
+DATA(insert OID = 946 ( oidnamegt PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
+DATA(insert OID = 947 ( oidnamene PGUID 11 f t f 2 f 16 "911 911" 100 0 0 100 foo bar));
+DATA(insert OID = 948 ( oidnamecmp PGUID 11 f t f 2 f 23 "911 911" 100 0 0 100 foo bar));
+DATA(insert OID = 949 ( mkoidname PGUID 11 f t f 2 f 911 "26 19" 100 0 0 100 foo bar));
+
+DATA(insert OID = 952 ( lo_open PGUID 11 f t f 2 f 23 "26 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 953 ( lo_close PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 954 ( loread PGUID 11 f t f 2 f 17 "23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 955 ( lowrite PGUID 11 f t f 2 f 23 "23 17" 100 0 0 100 foo bar ));
+DATA(insert OID = 956 ( lo_lseek PGUID 11 f t f 3 f 23 "23 23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 957 ( lo_creat PGUID 11 f t f 1 f 26 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 958 ( lo_tell PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 959 ( on_pl PGUID 11 f t f 2 f 16 "600 628" 100 0 10 100 foo bar ));
+DATA(insert OID = 960 ( on_sl PGUID 11 f t f 2 f 16 "601 628" 100 0 10 100 foo bar ));
+DATA(insert OID = 961 ( close_pl PGUID 11 f t f 2 f 600 "600 628" 100 0 10 100 foo bar ));
+DATA(insert OID = 962 ( close_sl PGUID 11 f t f 2 f 600 "601 628" 100 0 10 100 foo bar ));
+DATA(insert OID = 963 ( close_lb PGUID 11 f t f 2 f 600 "628 603" 100 0 10 100 foo bar ));
+
+DATA(insert OID = 964 ( lo_unlink PGUID 11 f t f 1 f 23 "23" 100 0 0 100 foo bar ));
+DATA(insert OID = 972 ( regproctooid PGUID 11 f t f 1 f 26 "24" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 973 ( path_inter PGUID 11 f t f 2 f 16 "602 602" 100 0 10 100 foo bar ));
+DATA(insert OID = 975 ( box_area PGUID 11 f t f 1 f 701 "603" 100 0 0 100 foo bar ));
+DATA(insert OID = 976 ( box_width PGUID 11 f t f 1 f 701 "603" 100 0 0 100 foo bar ));
+DATA(insert OID = 977 ( box_height PGUID 11 f t f 1 f 701 "603" 100 0 0 100 foo bar ));
+DATA(insert OID = 978 ( box_distance PGUID 11 f t f 2 f 701 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 980 ( box_intersect PGUID 11 f t f 2 f 603 "603 603" 100 0 0 100 foo bar ));
+DATA(insert OID = 981 ( box_diagonal PGUID 11 f t f 1 f 601 "603" 100 0 0 100 foo bar ));
+DATA(insert OID = 982 ( path_n_lt PGUID 11 f t f 2 f 16 "602 602" 100 0 0 100 foo bar ));
+DATA(insert OID = 983 ( path_n_gt PGUID 11 f t f 2 f 16 "602 602" 100 0 0 100 foo bar ));
+DATA(insert OID = 984 ( path_n_eq PGUID 11 f t f 2 f 16 "602 602" 100 0 0 100 foo bar ));
+DATA(insert OID = 985 ( path_n_le PGUID 11 f t f 2 f 16 "602 602" 100 0 0 100 foo bar ));
+DATA(insert OID = 986 ( path_n_ge PGUID 11 f t f 2 f 16 "602 602" 100 0 0 100 foo bar ));
+DATA(insert OID = 987 ( path_length PGUID 11 f t f 1 f 701 "602" 100 0 1 0 foo bar ));
+DATA(insert OID = 989 ( point_vert PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 990 ( point_horiz PGUID 11 f t f 2 f 16 "600 600" 100 0 0 100 foo bar ));
DATA(insert OID = 991 ( point_distance PGUID 11 f t f 2 f 701 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 992 ( point_slope PGUID 11 f t f 2 f 701 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 992 ( point_slope PGUID 11 f t f 2 f 701 "600 600" 100 0 0 100 foo bar ));
DATA(insert OID = 993 ( lseg_construct PGUID 11 f t f 2 f 601 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 994 ( lseg_intersect PGUID 11 f t f 2 f 16 "601 601" 100 0 0 100 foo bar ));
-DATA(insert OID = 995 ( lseg_parallel PGUID 11 f t f 2 f 16 "601 601" 100 0 0 100 foo bar ));
-DATA(insert OID = 996 ( lseg_perp PGUID 11 f t f 2 f 16 "601 601" 100 0 0 100 foo bar ));
-DATA(insert OID = 997 ( lseg_vertical PGUID 11 f t f 1 f 16 "601" 100 0 0 100 foo bar ));
-DATA(insert OID = 998 ( lseg_horizontal PGUID 11 f t f 1 f 16 "601" 100 0 0 100 foo bar ));
-DATA(insert OID = 999 ( lseg_eq PGUID 11 f t f 2 f 16 "601 601" 100 0 0 100 foo bar ));
+DATA(insert OID = 994 ( lseg_intersect PGUID 11 f t f 2 f 16 "601 601" 100 0 0 100 foo bar ));
+DATA(insert OID = 995 ( lseg_parallel PGUID 11 f t f 2 f 16 "601 601" 100 0 0 100 foo bar ));
+DATA(insert OID = 996 ( lseg_perp PGUID 11 f t f 2 f 16 "601 601" 100 0 0 100 foo bar ));
+DATA(insert OID = 997 ( lseg_vertical PGUID 11 f t f 1 f 16 "601" 100 0 0 100 foo bar ));
+DATA(insert OID = 998 ( lseg_horizontal PGUID 11 f t f 1 f 16 "601" 100 0 0 100 foo bar ));
+DATA(insert OID = 999 ( lseg_eq PGUID 11 f t f 2 f 16 "601 601" 100 0 0 100 foo bar ));
/* OIDS 1000 - 1999 */
-DATA(insert OID = 1029 ( nullvalue PGUID 11 f t f 1 f 16 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1029 ( nullvalue PGUID 11 f t f 1 f 16 "0" 100 0 0 100 foo bar ));
#define NullValueRegProcedure 1029
-DATA(insert OID = 1030 ( nonnullvalue PGUID 11 f t f 1 f 16 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1030 ( nonnullvalue PGUID 11 f t f 1 f 16 "0" 100 0 0 100 foo bar ));
#define NonNullValueRegProcedure 1030
-DATA(insert OID = 1031 ( aclitemin PGUID 11 f t f 1 f 1033 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1032 ( aclitemout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1035 ( aclinsert PGUID 11 f t f 2 f 1034 "1034 1033" 100 0 0 100 foo bar ));
-DATA(insert OID = 1036 ( aclremove PGUID 11 f t f 2 f 1034 "1034 1033" 100 0 0 100 foo bar ));
-DATA(insert OID = 1037 ( aclcontains PGUID 11 f t f 2 f 16 "1034 1033" 100 0 0 100 foo bar ));
-DATA(insert OID = 1038 ( seteval PGUID 11 f t f 1 f 23 "26" 100 0 0 100 foo bar ));
+DATA(insert OID = 1031 ( aclitemin PGUID 11 f t f 1 f 1033 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1032 ( aclitemout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1035 ( aclinsert PGUID 11 f t f 2 f 1034 "1034 1033" 100 0 0 100 foo bar ));
+DATA(insert OID = 1036 ( aclremove PGUID 11 f t f 2 f 1034 "1034 1033" 100 0 0 100 foo bar ));
+DATA(insert OID = 1037 ( aclcontains PGUID 11 f t f 2 f 16 "1034 1033" 100 0 0 100 foo bar ));
+DATA(insert OID = 1038 ( seteval PGUID 11 f t f 1 f 23 "26" 100 0 0 100 foo bar ));
#define SetEvalRegProcedure 1038
-DATA(insert OID = 1044 ( bpcharin PGUID 11 f t f 3 f 1042 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1045 ( bpcharout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1046 ( varcharin PGUID 11 f t f 3 f 1043 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1047 ( varcharout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1048 ( bpchareq PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
-DATA(insert OID = 1049 ( bpcharlt PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
-DATA(insert OID = 1050 ( bpcharle PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
-DATA(insert OID = 1051 ( bpchargt PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
-DATA(insert OID = 1052 ( bpcharge PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
-DATA(insert OID = 1053 ( bpcharne PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
-DATA(insert OID = 1070 ( varchareq PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
-DATA(insert OID = 1071 ( varcharlt PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
-DATA(insert OID = 1072 ( varcharle PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
-DATA(insert OID = 1073 ( varchargt PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
-DATA(insert OID = 1074 ( varcharge PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
-DATA(insert OID = 1075 ( varcharne PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
-DATA(insert OID = 1078 ( bpcharcmp PGUID 11 f t f 2 f 23 "1042 1042" 100 0 0 100 foo bar ));
-DATA(insert OID = 1079 ( varcharcmp PGUID 11 f t f 2 f 23 "1043 1043" 100 0 0 100 foo bar ));
-DATA(insert OID = 1080 ( hashbpchar PGUID 11 f t f 1 f 23 "1042" 100 0 0 100 foo bar ));
-DATA(insert OID = 1081 ( hashvarchar PGUID 11 f t f 1 f 23 "1043" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 1084 ( date_in PGUID 11 f t f 1 f 1082 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1085 ( date_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1086 ( date_eq PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
-DATA(insert OID = 1087 ( date_lt PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
-DATA(insert OID = 1088 ( date_le PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
-DATA(insert OID = 1089 ( date_gt PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
-DATA(insert OID = 1090 ( date_ge PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
-DATA(insert OID = 1091 ( date_ne PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
-DATA(insert OID = 1092 ( date_cmp PGUID 11 f t f 2 f 23 "1082 1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1044 ( bpcharin PGUID 11 f t f 3 f 1042 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1045 ( bpcharout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1046 ( varcharin PGUID 11 f t f 3 f 1043 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1047 ( varcharout PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1048 ( bpchareq PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
+DATA(insert OID = 1049 ( bpcharlt PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
+DATA(insert OID = 1050 ( bpcharle PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
+DATA(insert OID = 1051 ( bpchargt PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
+DATA(insert OID = 1052 ( bpcharge PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
+DATA(insert OID = 1053 ( bpcharne PGUID 11 f t f 2 f 16 "1042 1042" 100 0 0 100 foo bar ));
+DATA(insert OID = 1070 ( varchareq PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
+DATA(insert OID = 1071 ( varcharlt PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
+DATA(insert OID = 1072 ( varcharle PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
+DATA(insert OID = 1073 ( varchargt PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
+DATA(insert OID = 1074 ( varcharge PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
+DATA(insert OID = 1075 ( varcharne PGUID 11 f t f 2 f 16 "1043 1043" 100 0 0 100 foo bar ));
+DATA(insert OID = 1078 ( bpcharcmp PGUID 11 f t f 2 f 23 "1042 1042" 100 0 0 100 foo bar ));
+DATA(insert OID = 1079 ( varcharcmp PGUID 11 f t f 2 f 23 "1043 1043" 100 0 0 100 foo bar ));
+DATA(insert OID = 1080 ( hashbpchar PGUID 11 f t f 1 f 23 "1042" 100 0 0 100 foo bar ));
+DATA(insert OID = 1081 ( hashvarchar PGUID 11 f t f 1 f 23 "1043" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 1084 ( date_in PGUID 11 f t f 1 f 1082 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1085 ( date_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1086 ( date_eq PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1087 ( date_lt PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1088 ( date_le PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1089 ( date_gt PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1090 ( date_ge PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1091 ( date_ne PGUID 11 f t f 2 f 16 "1082 1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1092 ( date_cmp PGUID 11 f t f 2 f 23 "1082 1082" 100 0 0 100 foo bar ));
/* OIDS 1100 - 1199 */
-DATA(insert OID = 1102 ( time_lt PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
-DATA(insert OID = 1103 ( time_le PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
-DATA(insert OID = 1104 ( time_gt PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
-DATA(insert OID = 1105 ( time_ge PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
-DATA(insert OID = 1106 ( time_ne PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
-DATA(insert OID = 1107 ( time_cmp PGUID 11 f t f 2 f 23 "1083 1083" 100 0 0 100 foo bar ));
-DATA(insert OID = 1138 ( date_larger PGUID 11 f t f 2 f 1082 "1082 1082" 100 0 0 100 foo bar ));
-DATA(insert OID = 1139 ( date_smaller PGUID 11 f t f 2 f 1082 "1082 1082" 100 0 0 100 foo bar ));
-DATA(insert OID = 1140 ( date_mi PGUID 11 f t f 2 f 23 "1082 1082" 100 0 0 100 foo bar ));
-DATA(insert OID = 1141 ( date_pli PGUID 11 f t f 2 f 1082 "1082 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 1142 ( date_mii PGUID 11 f t f 2 f 1082 "1082 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 1143 ( time_in PGUID 11 f t f 1 f 1083 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1144 ( time_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1145 ( time_eq PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
+DATA(insert OID = 1102 ( time_lt PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
+DATA(insert OID = 1103 ( time_le PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
+DATA(insert OID = 1104 ( time_gt PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
+DATA(insert OID = 1105 ( time_ge PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
+DATA(insert OID = 1106 ( time_ne PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
+DATA(insert OID = 1107 ( time_cmp PGUID 11 f t f 2 f 23 "1083 1083" 100 0 0 100 foo bar ));
+DATA(insert OID = 1138 ( date_larger PGUID 11 f t f 2 f 1082 "1082 1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1139 ( date_smaller PGUID 11 f t f 2 f 1082 "1082 1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1140 ( date_mi PGUID 11 f t f 2 f 23 "1082 1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1141 ( date_pli PGUID 11 f t f 2 f 1082 "1082 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 1142 ( date_mii PGUID 11 f t f 2 f 1082 "1082 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 1143 ( time_in PGUID 11 f t f 1 f 1083 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1144 ( time_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1145 ( time_eq PGUID 11 f t f 2 f 16 "1083 1083" 100 0 0 100 foo bar ));
DATA(insert OID = 1146 ( circle_add_pt PGUID 11 f t f 2 f 718 "718 600" 100 0 0 100 foo bar ));
DATA(insert OID = 1147 ( circle_sub_pt PGUID 11 f t f 2 f 718 "718 600" 100 0 0 100 foo bar ));
DATA(insert OID = 1148 ( circle_mul_pt PGUID 11 f t f 2 f 718 "718 600" 100 0 0 100 foo bar ));
DATA(insert OID = 1149 ( circle_div_pt PGUID 11 f t f 2 f 718 "718 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1150 ( datetime_in PGUID 11 f t f 1 f 1184 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1151 ( datetime_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1152 ( datetime_eq PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1153 ( datetime_ne PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1154 ( datetime_lt PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1155 ( datetime_le PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1156 ( datetime_ge PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1157 ( datetime_gt PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1158 ( datetime_finite PGUID 11 f t f 1 f 16 "1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1159 ( datetime_zone PGUID 11 f t f 2 f 25 "25 1184" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 1160 ( timespan_in PGUID 11 f t f 1 f 1186 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1161 ( timespan_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1162 ( timespan_eq PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1163 ( timespan_ne PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1164 ( timespan_lt PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1165 ( timespan_le PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1166 ( timespan_ge PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1167 ( timespan_gt PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1168 ( timespan_um PGUID 11 f t f 1 f 1186 "1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1169 ( timespan_pl PGUID 11 f t f 2 f 1186 "1186 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1170 ( timespan_mi PGUID 11 f t f 2 f 1186 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1150 ( datetime_in PGUID 11 f t f 1 f 1184 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1151 ( datetime_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1152 ( datetime_eq PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1153 ( datetime_ne PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1154 ( datetime_lt PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1155 ( datetime_le PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1156 ( datetime_ge PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1157 ( datetime_gt PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1158 ( datetime_finite PGUID 11 f t f 1 f 16 "1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1159 ( datetime_zone PGUID 11 f t f 2 f 25 "25 1184" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 1160 ( timespan_in PGUID 11 f t f 1 f 1186 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1161 ( timespan_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1162 ( timespan_eq PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1163 ( timespan_ne PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1164 ( timespan_lt PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1165 ( timespan_le PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1166 ( timespan_ge PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1167 ( timespan_gt PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1168 ( timespan_um PGUID 11 f t f 1 f 1186 "1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1169 ( timespan_pl PGUID 11 f t f 2 f 1186 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1170 ( timespan_mi PGUID 11 f t f 2 f 1186 "1186 1186" 100 0 0 100 foo bar ));
DATA(insert OID = 1171 ( datetime_part PGUID 11 f t f 2 f 701 "25 1184" 100 0 0 100 foo bar ));
DATA(insert OID = 1172 ( timespan_part PGUID 11 f t f 2 f 701 "25 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1173 ( abstime_datetime PGUID 11 f t f 1 f 1184 "702" 100 0 0 100 foo bar ));
-DATA(insert OID = 1174 ( date_datetime PGUID 11 f t f 1 f 1184 "1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1173 ( abstime_datetime PGUID 11 f t f 1 f 1184 "702" 100 0 0 100 foo bar ));
+DATA(insert OID = 1174 ( date_datetime PGUID 11 f t f 1 f 1184 "1082" 100 0 0 100 foo bar ));
DATA(insert OID = 1175 ( timestamp_datetime PGUID 11 f t f 1 f 1184 "1296" 100 0 0 100 foo bar ));
DATA(insert OID = 1176 ( datetime_datetime PGUID 11 f t f 2 f 1184 "1082 1083" 100 0 0 100 foo bar ));
-DATA(insert OID = 1177 ( reltime_timespan PGUID 11 f t f 1 f 1186 "703" 100 0 0 100 foo bar ));
-DATA(insert OID = 1178 ( datetime_date PGUID 11 f t f 1 f 1082 "1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1179 ( abstime_date PGUID 11 f t f 1 f 1082 "702" 100 0 0 100 foo bar ));
-DATA(insert OID = 1180 ( datetime_abstime PGUID 11 f t f 1 f 702 "1184" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 1188 ( datetime_mi PGUID 11 f t f 2 f 1186 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1189 ( datetime_pl_span PGUID 11 f t f 2 f 1184 "1184 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1190 ( datetime_mi_span PGUID 11 f t f 2 f 1184 "1184 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1191 ( text_datetime PGUID 11 f t f 1 f 1184 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 1192 ( datetime_text PGUID 11 f t f 1 f 25 "1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1193 ( timespan_text PGUID 11 f t f 1 f 1186 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 1194 ( timespan_reltime PGUID 11 f t f 1 f 703 "1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1195 ( datetime_smaller PGUID 11 f t f 2 f 1184 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1196 ( datetime_larger PGUID 11 f t f 2 f 1184 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1197 ( timespan_smaller PGUID 11 f t f 2 f 1186 "1186 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1198 ( timespan_larger PGUID 11 f t f 2 f 1186 "1186 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1199 ( datetime_age PGUID 11 f t f 2 f 1186 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1177 ( reltime_timespan PGUID 11 f t f 1 f 1186 "703" 100 0 0 100 foo bar ));
+DATA(insert OID = 1178 ( datetime_date PGUID 11 f t f 1 f 1082 "1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1179 ( abstime_date PGUID 11 f t f 1 f 1082 "702" 100 0 0 100 foo bar ));
+DATA(insert OID = 1180 ( datetime_abstime PGUID 11 f t f 1 f 702 "1184" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 1188 ( datetime_mi PGUID 11 f t f 2 f 1186 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1189 ( datetime_pl_span PGUID 11 f t f 2 f 1184 "1184 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1190 ( datetime_mi_span PGUID 11 f t f 2 f 1184 "1184 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1191 ( text_datetime PGUID 11 f t f 1 f 1184 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1192 ( datetime_text PGUID 11 f t f 1 f 25 "1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1193 ( timespan_text PGUID 11 f t f 1 f 1186 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1194 ( timespan_reltime PGUID 11 f t f 1 f 703 "1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1195 ( datetime_smaller PGUID 11 f t f 2 f 1184 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1196 ( datetime_larger PGUID 11 f t f 2 f 1184 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1197 ( timespan_smaller PGUID 11 f t f 2 f 1186 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1198 ( timespan_larger PGUID 11 f t f 2 f 1186 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1199 ( datetime_age PGUID 11 f t f 2 f 1186 "1184 1184" 100 0 0 100 foo bar ));
/* OIDS 1200 - 1299 */
-DATA(insert OID = 1200 ( int42reltime PGUID 11 f t f 1 f 703 "21" 100 0 0 100 foo bar ));
+DATA(insert OID = 1200 ( int42reltime PGUID 11 f t f 1 f 703 "21" 100 0 0 100 foo bar ));
DATA(insert OID = 1217 ( datetime_trunc PGUID 11 f t f 2 f 1184 "25 1184" 100 0 0 100 foo bar ));
DATA(insert OID = 1218 ( timespan_trunc PGUID 11 f t f 2 f 1186 "25 1186" 100 0 0 100 foo bar ));
@@ -870,51 +871,51 @@ DATA(insert OID = 1294 ( char8icregexeq PGUID 11 f t f 2 f 16 "411 25" 100 0
DATA(insert OID = 1295 ( char8icregexne PGUID 11 f t f 2 f 16 "411 25" 100 0 0 100 foo bar ));
DATA(insert OID = 1236 ( char16icregexeq PGUID 11 f t f 2 f 16 "20 25" 100 0 0 100 foo bar ));
DATA(insert OID = 1237 ( char16icregexne PGUID 11 f t f 2 f 16 "20 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 1238 ( texticregexeq PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
-DATA(insert OID = 1239 ( texticregexne PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
+DATA(insert OID = 1238 ( texticregexeq PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
+DATA(insert OID = 1239 ( texticregexne PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
DATA(insert OID = 1240 ( nameicregexeq PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
DATA(insert OID = 1241 ( nameicregexne PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 1297 ( timestamp_in PGUID 11 f t f 1 f 1296 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1297 ( timestamp_in PGUID 11 f t f 1 f 1296 "0" 100 0 0 100 foo bar ));
DATA(insert OID = 1298 ( timestamp_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
-DATA(insert OID = 1299 ( now PGUID 11 f t f 0 f 1296 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 1299 ( now PGUID 11 f t f 0 f 1296 "0" 100 0 0 100 foo bar ));
/* OIDS 1300 - 1399 */
-DATA(insert OID = 1306 ( timestampeq PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
-DATA(insert OID = 1307 ( timestampne PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
-DATA(insert OID = 1308 ( timestamplt PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
-DATA(insert OID = 1309 ( timestampgt PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
-DATA(insert OID = 1310 ( timestample PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
-DATA(insert OID = 1311 ( timestampge PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
+DATA(insert OID = 1306 ( timestampeq PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
+DATA(insert OID = 1307 ( timestampne PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
+DATA(insert OID = 1308 ( timestamplt PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
+DATA(insert OID = 1309 ( timestampgt PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
+DATA(insert OID = 1310 ( timestample PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
+DATA(insert OID = 1311 ( timestampge PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
/* reserve OIDs 1312-1319 for additional date/time conversion routines! tgl 97/04/01 */
-DATA(insert OID = 1314 ( datetime_cmp PGUID 11 f t f 2 f 23 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1315 ( timespan_cmp PGUID 11 f t f 2 f 23 "1186 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1314 ( datetime_cmp PGUID 11 f t f 2 f 23 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1315 ( timespan_cmp PGUID 11 f t f 2 f 23 "1186 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1339 ( date_zone PGUID 14 f t f 2 f 25 "25 1184" 100 0 0 100 "select datetime_zone($1, $2)" - ));
-DATA(insert OID = 1340 ( text PGUID 14 f t f 1 f 25 "1184" 100 0 0 100 "select datetime_text($1)" - ));
-DATA(insert OID = 1341 ( text PGUID 14 f t f 1 f 25 "1186" 100 0 0 100 "select timespan_text($1)" - ));
+DATA(insert OID = 1339 ( date_zone PGUID 14 f t f 2 f 25 "25 1184" 100 0 0 100 "select datetime_zone($1, $2)" - ));
+DATA(insert OID = 1340 ( text PGUID 14 f t f 1 f 25 "1184" 100 0 0 100 "select datetime_text($1)" - ));
+DATA(insert OID = 1341 ( text PGUID 14 f t f 1 f 25 "1186" 100 0 0 100 "select timespan_text($1)" - ));
/* reserve OIDs 1339-1349 for additional date/time conversion routines! tgl 97/04/01 */
-DATA(insert OID = 1350 ( datetime PGUID 14 f t f 1 f 1184 "1184" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1351 ( datetime PGUID 14 f t f 1 f 1184 "25" 100 0 0 100 "select text_datetime($1)" - ));
-DATA(insert OID = 1352 ( datetime PGUID 14 f t f 1 f 1184 "702" 100 0 0 100 "select abstime_datetime($1)" - ));
-DATA(insert OID = 1353 ( datetime PGUID 14 f t f 1 f 1184 "1082" 100 0 0 100 "select date_datetime($1)" - ));
-DATA(insert OID = 1354 ( datetime PGUID 14 f t f 1 f 1184 "1296" 100 0 0 100 "select timestamp_datetime($1)" - ));
-DATA(insert OID = 1355 ( datetime PGUID 14 f t f 2 f 1184 "1082 1083" 100 0 0 100 "select datetime_datetime($1, $2)" - ));
-DATA(insert OID = 1356 ( timespan PGUID 14 f t f 1 f 1186 "1186" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1357 ( timespan PGUID 14 f t f 1 f 1186 "703" 100 0 0 100 "select reltime_timespan($1)" - ));
-DATA(insert OID = 1358 ( timespan PGUID 14 f t f 1 f 1186 "1083" 100 0 0 100 "select time_timespan($1)" - ));
-DATA(insert OID = 1359 ( date PGUID 14 f t f 1 f 1082 "1082" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1360 ( date PGUID 14 f t f 1 f 1082 "1184" 100 0 0 100 "select datetime_date($1)" - ));
-DATA(insert OID = 1361 ( date PGUID 14 f t f 1 f 1082 "702" 100 0 0 100 "select abstime_date($1)" - ));
-DATA(insert OID = 1362 ( time PGUID 14 f t f 1 f 1083 "1083" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1363 ( time PGUID 14 f t f 1 f 1083 "1184" 100 0 0 100 "select datetime_time($1)" - ));
-DATA(insert OID = 1364 ( time PGUID 14 f t f 1 f 1083 "702" 100 0 0 100 "select abstime_time($1)" - ));
-DATA(insert OID = 1365 ( abstime PGUID 14 f t f 1 f 702 "702" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1366 ( abstime PGUID 14 f t f 1 f 702 "1184" 100 0 0 100 "select datetime_abstime($1)" - ));
-DATA(insert OID = 1367 ( reltime PGUID 14 f t f 1 f 703 "703" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1368 ( reltime PGUID 14 f t f 1 f 703 "1186" 100 0 0 100 "select timespan_reltime($1)" - ));
+DATA(insert OID = 1350 ( datetime PGUID 14 f t f 1 f 1184 "1184" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1351 ( datetime PGUID 14 f t f 1 f 1184 "25" 100 0 0 100 "select text_datetime($1)" - ));
+DATA(insert OID = 1352 ( datetime PGUID 14 f t f 1 f 1184 "702" 100 0 0 100 "select abstime_datetime($1)" - ));
+DATA(insert OID = 1353 ( datetime PGUID 14 f t f 1 f 1184 "1082" 100 0 0 100 "select date_datetime($1)" - ));
+DATA(insert OID = 1354 ( datetime PGUID 14 f t f 1 f 1184 "1296" 100 0 0 100 "select timestamp_datetime($1)" - ));
+DATA(insert OID = 1355 ( datetime PGUID 14 f t f 2 f 1184 "1082 1083" 100 0 0 100 "select datetime_datetime($1, $2)" - ));
+DATA(insert OID = 1356 ( timespan PGUID 14 f t f 1 f 1186 "1186" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1357 ( timespan PGUID 14 f t f 1 f 1186 "703" 100 0 0 100 "select reltime_timespan($1)" - ));
+DATA(insert OID = 1358 ( timespan PGUID 14 f t f 1 f 1186 "1083" 100 0 0 100 "select time_timespan($1)" - ));
+DATA(insert OID = 1359 ( date PGUID 14 f t f 1 f 1082 "1082" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1360 ( date PGUID 14 f t f 1 f 1082 "1184" 100 0 0 100 "select datetime_date($1)" - ));
+DATA(insert OID = 1361 ( date PGUID 14 f t f 1 f 1082 "702" 100 0 0 100 "select abstime_date($1)" - ));
+DATA(insert OID = 1362 ( time PGUID 14 f t f 1 f 1083 "1083" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1363 ( time PGUID 14 f t f 1 f 1083 "1184" 100 0 0 100 "select datetime_time($1)" - ));
+DATA(insert OID = 1364 ( time PGUID 14 f t f 1 f 1083 "702" 100 0 0 100 "select abstime_time($1)" - ));
+DATA(insert OID = 1365 ( abstime PGUID 14 f t f 1 f 702 "702" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1366 ( abstime PGUID 14 f t f 1 f 702 "1184" 100 0 0 100 "select datetime_abstime($1)" - ));
+DATA(insert OID = 1367 ( reltime PGUID 14 f t f 1 f 703 "703" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1368 ( reltime PGUID 14 f t f 1 f 703 "1186" 100 0 0 100 "select timespan_reltime($1)" - ));
DATA(insert OID = 1369 ( timestamp PGUID 14 f t f 1 f 1296 "1296" 100 0 0 100 "select $1" - ));
DATA(insert OID = 1370 ( timestamp PGUID 14 f t f 1 f 1296 "1184" 100 0 0 100 "select datetime_timestamp($1)" - ));
@@ -926,196 +927,197 @@ DATA(insert OID = 1384 ( date_part PGUID 14 f t f 2 f 701 "25 1082" 100 0 0
DATA(insert OID = 1385 ( date_part PGUID 14 f t f 2 f 701 "25 1083" 100 0 0 100 "select timespan_part($1, timespan($2))" - ));
DATA(insert OID = 1386 ( date_trunc PGUID 14 f t f 2 f 1184 "25 1184" 100 0 0 100 "select datetime_trunc($1, $2)" - ));
DATA(insert OID = 1387 ( date_trunc PGUID 14 f t f 2 f 1186 "25 1186" 100 0 0 100 "select timespan_trunc($1, $2)" - ));
-DATA(insert OID = 1388 ( age PGUID 14 f t f 2 f 1186 "1184 1184" 100 0 0 100 "select datetime_age($1, $2)" - ));
-DATA(insert OID = 1389 ( age PGUID 14 f t f 1 f 1186 "1184" 100 0 0 100 "select datetime_age(\'today\', $1)" - ));
+DATA(insert OID = 1388 ( age PGUID 14 f t f 2 f 1186 "1184 1184" 100 0 0 100 "select datetime_age($1, $2)" - ));
+DATA(insert OID = 1389 ( age PGUID 14 f t f 1 f 1186 "1184" 100 0 0 100 "select datetime_age(\'today\', $1)" - ));
-DATA(insert OID = 1390 ( isfinite PGUID 14 f t f 1 f 16 "1184" 100 0 0 100 "select datetime_finite($1)" - ));
-DATA(insert OID = 1391 ( isfinite PGUID 14 f t f 1 f 16 "1186" 100 0 0 100 "select timespan_finite($1)" - ));
-DATA(insert OID = 1392 ( isfinite PGUID 14 f t f 1 f 16 "702" 100 0 0 100 "select abstime_finite($1)" - ));
+DATA(insert OID = 1390 ( isfinite PGUID 14 f t f 1 f 16 "1184" 100 0 0 100 "select datetime_finite($1)" - ));
+DATA(insert OID = 1391 ( isfinite PGUID 14 f t f 1 f 16 "1186" 100 0 0 100 "select timespan_finite($1)" - ));
+DATA(insert OID = 1392 ( isfinite PGUID 14 f t f 1 f 16 "702" 100 0 0 100 "select abstime_finite($1)" - ));
/* reserve OIDs 1370-1399 for additional date/time conversion routines! tgl 97/04/01 */
/* OIDS 1400 - 1499 */
-DATA(insert OID = 1400 ( float PGUID 14 f t f 1 f 701 "701" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1401 ( float PGUID 14 f t f 1 f 701 "700" 100 0 0 100 "select ftod($1)" - ));
-DATA(insert OID = 1402 ( float4 PGUID 14 f t f 1 f 700 "700" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1403 ( float4 PGUID 14 f t f 1 f 700 "701" 100 0 0 100 "select dtof($1)" - ));
-DATA(insert OID = 1404 ( int PGUID 14 f t f 1 f 23 "23" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1405 ( int2 PGUID 14 f t f 1 f 21 "21" 100 0 0 100 "select $1" - ));
-
-DATA(insert OID = 1406 ( float8 PGUID 14 f t f 1 f 701 "701" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1407 ( float8 PGUID 14 f t f 1 f 701 "700" 100 0 0 100 "select ftod($1)" - ));
-DATA(insert OID = 1408 ( float8 PGUID 14 f t f 1 f 701 "23" 100 0 0 100 "select i4tod($1)" - ));
-DATA(insert OID = 1409 ( float8 PGUID 14 f t f 1 f 701 "21" 100 0 0 100 "select i2tod($1)" - ));
-DATA(insert OID = 1410 ( float4 PGUID 14 f t f 1 f 700 "23" 100 0 0 100 "select i4tof($1)" - ));
-DATA(insert OID = 1411 ( float4 PGUID 14 f t f 1 f 700 "21" 100 0 0 100 "select i2tof($1)" - ));
-DATA(insert OID = 1412 ( int4 PGUID 14 f t f 1 f 23 "23" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1413 ( int4 PGUID 14 f t f 1 f 23 "701" 100 0 0 100 "select dtoi4($1)" - ));
-DATA(insert OID = 1414 ( int4 PGUID 14 f t f 1 f 23 "21" 100 0 0 100 "select i2toi4($1)" - ));
-DATA(insert OID = 1415 ( int4 PGUID 14 f t f 1 f 23 "700" 100 0 0 100 "select ftoi4($1)" - ));
-DATA(insert OID = 1416 ( int2 PGUID 14 f t f 1 f 21 "21" 100 0 0 100 "select $1" - ));
-DATA(insert OID = 1417 ( int2 PGUID 14 f t f 1 f 21 "23" 100 0 0 100 "select i4toi2($1)" - ));
-DATA(insert OID = 1418 ( int2 PGUID 14 f t f 1 f 21 "701" 100 0 0 100 "select dtoi2($1)" - ));
-DATA(insert OID = 1419 ( int2 PGUID 14 f t f 1 f 21 "700" 100 0 0 100 "select ftoi2($1)" - ));
-
-DATA(insert OID = 1421 ( box PGUID 11 f t f 2 f 603 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1422 ( box_add PGUID 11 f t f 2 f 603 "603 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1423 ( box_sub PGUID 11 f t f 2 f 603 "603 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1424 ( box_mul PGUID 11 f t f 2 f 603 "603 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1425 ( box_div PGUID 11 f t f 2 f 603 "603 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1426 ( path_contain_pt PGUID 11 f t f 2 f 16 "601 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1427 ( pt_contained_path PGUID 11 f t f 2 f 16 "600 601" 100 0 0 100 foo bar ));
-DATA(insert OID = 1428 ( poly_contain_pt PGUID 11 f t f 2 f 16 "604 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1429 ( pt_contained_poly PGUID 11 f t f 2 f 16 "600 604" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 1430 ( path_isclosed PGUID 11 f t f 1 f 16 "602" 100 0 0 100 foo bar ));
-DATA(insert OID = 1431 ( path_isopen PGUID 11 f t f 1 f 16 "602" 100 0 0 100 foo bar ));
-DATA(insert OID = 1432 ( path_npoints PGUID 11 f t f 1 f 23 "602" 100 0 0 100 foo bar ));
-DATA(insert OID = 1433 ( path_close PGUID 11 f t f 1 f 602 "602" 100 0 0 100 foo bar ));
-DATA(insert OID = 1434 ( path_open PGUID 11 f t f 1 f 602 "602" 100 0 0 100 foo bar ));
-DATA(insert OID = 1435 ( path_add PGUID 11 f t f 2 f 602 "602 602" 100 0 0 100 foo bar ));
-DATA(insert OID = 1436 ( path_add_pt PGUID 11 f t f 2 f 602 "602 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1437 ( path_sub_pt PGUID 11 f t f 2 f 602 "602 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1438 ( path_mul_pt PGUID 11 f t f 2 f 602 "602 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1439 ( path_div_pt PGUID 11 f t f 2 f 602 "602 600" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 1440 ( point PGUID 11 f t f 2 f 600 "701 701" 100 0 0 100 foo bar ));
-DATA(insert OID = 1441 ( point_add PGUID 11 f t f 2 f 600 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1442 ( point_sub PGUID 11 f t f 2 f 600 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1443 ( point_mul PGUID 11 f t f 2 f 600 "600 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1444 ( point_div PGUID 11 f t f 2 f 600 "600 600" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 1445 ( poly_npoints PGUID 11 f t f 1 f 23 "604" 100 0 0 100 foo bar ));
-DATA(insert OID = 1446 ( poly_box PGUID 11 f t f 1 f 603 "604" 100 0 0 100 foo bar ));
-DATA(insert OID = 1447 ( poly_path PGUID 11 f t f 1 f 602 "604" 100 0 0 100 foo bar ));
-DATA(insert OID = 1448 ( box_poly PGUID 11 f t f 1 f 604 "603" 100 0 0 100 foo bar ));
-DATA(insert OID = 1449 ( path_poly PGUID 11 f t f 1 f 604 "602" 100 0 0 100 foo bar ));
-
-DATA(insert OID = 1450 ( circle_in PGUID 11 f t f 1 f 718 "0" 100 0 1 0 foo bar ));
-DATA(insert OID = 1451 ( circle_out PGUID 11 f t f 1 f 23 "0" 100 0 1 0 foo bar ));
-DATA(insert OID = 1452 ( circle_same PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1453 ( circle_contain PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1454 ( circle_left PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1455 ( circle_overleft PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1456 ( circle_overright PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1457 ( circle_right PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1458 ( circle_contained PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1459 ( circle_overlap PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1460 ( circle_below PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1461 ( circle_above PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1462 ( circle_eq PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1463 ( circle_ne PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1464 ( circle_lt PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1465 ( circle_gt PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1466 ( circle_le PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1467 ( circle_ge PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1468 ( circle_area PGUID 11 f t f 1 f 701 "718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1469 ( circle_diameter PGUID 11 f t f 1 f 701 "718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1470 ( circle_radius PGUID 11 f t f 1 f 701 "718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1471 ( circle_distance PGUID 11 f t f 2 f 701 "718 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1472 ( circle_center PGUID 11 f t f 1 f 600 "718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1473 ( circle PGUID 11 f t f 2 f 718 "600 701" 100 0 1 0 foo bar ));
-DATA(insert OID = 1474 ( poly_circle PGUID 11 f t f 1 f 718 "604" 100 0 1 0 foo bar ));
-DATA(insert OID = 1475 ( circle_poly PGUID 11 f t f 2 f 604 "23 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1476 ( dist_pc PGUID 11 f t f 2 f 604 "600 718" 100 0 1 0 foo bar ));
-DATA(insert OID = 1477 ( circle_contain_pt PGUID 11 f t f 2 f 16 "718 600" 100 0 0 100 foo bar ));
-DATA(insert OID = 1478 ( pt_contained_circle PGUID 11 f t f 2 f 16 "600 718" 100 0 0 100 foo bar ));
-DATA(insert OID = 1479 ( box_circle PGUID 11 f t f 1 f 718 "603" 100 0 1 0 foo bar ));
-DATA(insert OID = 1480 ( circle_box PGUID 11 f t f 1 f 603 "718" 100 0 1 0 foo bar ));
-
-DATA(insert OID = 1530 ( point PGUID 14 f t f 2 f 600 "601 601" 100 0 0 100 "select lseg_interpt($1, $2)" - ));
-DATA(insert OID = 1531 ( point PGUID 14 f t f 1 f 600 "718" 100 0 0 100 "select circle_center($1)" - ));
-DATA(insert OID = 1532 ( isvertical PGUID 14 f t f 2 f 16 "600 600" 100 0 0 100 "select point_vert($1, $2)" - ));
-DATA(insert OID = 1533 ( ishorizontal PGUID 14 f t f 2 f 16 "600 600" 100 0 0 100 "select point_horiz($1, $2)" - ));
-DATA(insert OID = 1534 ( slope PGUID 14 f t f 2 f 701 "600 600" 100 0 0 100 "select point_slope($1, $2)" - ));
-
-DATA(insert OID = 1540 ( lseg PGUID 14 f t f 2 f 601 "600 600" 100 0 0 100 "select lseg_construct($1, $2)" - ));
-DATA(insert OID = 1541 ( lseg PGUID 14 f t f 1 f 601 "603" 100 0 0 100 "select box_diagonal($1)" - ));
-DATA(insert OID = 1542 ( isparallel PGUID 14 f t f 2 f 16 "601 601" 100 0 0 100 "select lseg_parallel($1, $2)" - ));
-DATA(insert OID = 1543 ( isperpendicular PGUID 14 f t f 2 f 16 "601 601" 100 0 0 100 "select lseg_perp($1, $2)" - ));
-DATA(insert OID = 1544 ( isvertical PGUID 14 f t f 1 f 16 "601" 100 0 0 100 "select lseg_vertical($1)" - ));
-DATA(insert OID = 1545 ( ishorizontal PGUID 14 f t f 1 f 16 "601" 100 0 0 100 "select lseg_horizontal($1)" - ));
+DATA(insert OID = 1400 ( float PGUID 14 f t f 1 f 701 "701" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1401 ( float PGUID 14 f t f 1 f 701 "700" 100 0 0 100 "select ftod($1)" - ));
+DATA(insert OID = 1402 ( float4 PGUID 14 f t f 1 f 700 "700" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1403 ( float4 PGUID 14 f t f 1 f 700 "701" 100 0 0 100 "select dtof($1)" - ));
+DATA(insert OID = 1404 ( int PGUID 14 f t f 1 f 23 "23" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1405 ( int2 PGUID 14 f t f 1 f 21 "21" 100 0 0 100 "select $1" - ));
+
+DATA(insert OID = 1406 ( float8 PGUID 14 f t f 1 f 701 "701" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1407 ( float8 PGUID 14 f t f 1 f 701 "700" 100 0 0 100 "select ftod($1)" - ));
+DATA(insert OID = 1408 ( float8 PGUID 14 f t f 1 f 701 "23" 100 0 0 100 "select i4tod($1)" - ));
+DATA(insert OID = 1409 ( float8 PGUID 14 f t f 1 f 701 "21" 100 0 0 100 "select i2tod($1)" - ));
+DATA(insert OID = 1410 ( float4 PGUID 14 f t f 1 f 700 "23" 100 0 0 100 "select i4tof($1)" - ));
+DATA(insert OID = 1411 ( float4 PGUID 14 f t f 1 f 700 "21" 100 0 0 100 "select i2tof($1)" - ));
+DATA(insert OID = 1412 ( int4 PGUID 14 f t f 1 f 23 "23" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1413 ( int4 PGUID 14 f t f 1 f 23 "701" 100 0 0 100 "select dtoi4($1)" - ));
+DATA(insert OID = 1414 ( int4 PGUID 14 f t f 1 f 23 "21" 100 0 0 100 "select i2toi4($1)" - ));
+DATA(insert OID = 1415 ( int4 PGUID 14 f t f 1 f 23 "700" 100 0 0 100 "select ftoi4($1)" - ));
+DATA(insert OID = 1416 ( int2 PGUID 14 f t f 1 f 21 "21" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1417 ( int2 PGUID 14 f t f 1 f 21 "23" 100 0 0 100 "select i4toi2($1)" - ));
+DATA(insert OID = 1418 ( int2 PGUID 14 f t f 1 f 21 "701" 100 0 0 100 "select dtoi2($1)" - ));
+DATA(insert OID = 1419 ( int2 PGUID 14 f t f 1 f 21 "700" 100 0 0 100 "select ftoi2($1)" - ));
+
+DATA(insert OID = 1421 ( box PGUID 11 f t f 2 f 603 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1422 ( box_add PGUID 11 f t f 2 f 603 "603 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1423 ( box_sub PGUID 11 f t f 2 f 603 "603 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1424 ( box_mul PGUID 11 f t f 2 f 603 "603 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1425 ( box_div PGUID 11 f t f 2 f 603 "603 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1426 ( path_contain_pt PGUID 11 f t f 2 f 16 "601 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1427 ( pt_contained_path PGUID 11 f t f 2 f 16 "600 601" 100 0 0 100 foo bar ));
+DATA(insert OID = 1428 ( poly_contain_pt PGUID 11 f t f 2 f 16 "604 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1429 ( pt_contained_poly PGUID 11 f t f 2 f 16 "600 604" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 1430 ( path_isclosed PGUID 11 f t f 1 f 16 "602" 100 0 0 100 foo bar ));
+DATA(insert OID = 1431 ( path_isopen PGUID 11 f t f 1 f 16 "602" 100 0 0 100 foo bar ));
+DATA(insert OID = 1432 ( path_npoints PGUID 11 f t f 1 f 23 "602" 100 0 0 100 foo bar ));
+DATA(insert OID = 1433 ( path_close PGUID 11 f t f 1 f 602 "602" 100 0 0 100 foo bar ));
+DATA(insert OID = 1434 ( path_open PGUID 11 f t f 1 f 602 "602" 100 0 0 100 foo bar ));
+DATA(insert OID = 1435 ( path_add PGUID 11 f t f 2 f 602 "602 602" 100 0 0 100 foo bar ));
+DATA(insert OID = 1436 ( path_add_pt PGUID 11 f t f 2 f 602 "602 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1437 ( path_sub_pt PGUID 11 f t f 2 f 602 "602 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1438 ( path_mul_pt PGUID 11 f t f 2 f 602 "602 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1439 ( path_div_pt PGUID 11 f t f 2 f 602 "602 600" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 1440 ( point PGUID 11 f t f 2 f 600 "701 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 1441 ( point_add PGUID 11 f t f 2 f 600 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1442 ( point_sub PGUID 11 f t f 2 f 600 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1443 ( point_mul PGUID 11 f t f 2 f 600 "600 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1444 ( point_div PGUID 11 f t f 2 f 600 "600 600" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 1445 ( poly_npoints PGUID 11 f t f 1 f 23 "604" 100 0 0 100 foo bar ));
+DATA(insert OID = 1446 ( poly_box PGUID 11 f t f 1 f 603 "604" 100 0 0 100 foo bar ));
+DATA(insert OID = 1447 ( poly_path PGUID 11 f t f 1 f 602 "604" 100 0 0 100 foo bar ));
+DATA(insert OID = 1448 ( box_poly PGUID 11 f t f 1 f 604 "603" 100 0 0 100 foo bar ));
+DATA(insert OID = 1449 ( path_poly PGUID 11 f t f 1 f 604 "602" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 1450 ( circle_in PGUID 11 f t f 1 f 718 "0" 100 0 1 0 foo bar ));
+DATA(insert OID = 1451 ( circle_out PGUID 11 f t f 1 f 23 "0" 100 0 1 0 foo bar ));
+DATA(insert OID = 1452 ( circle_same PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1453 ( circle_contain PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1454 ( circle_left PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1455 ( circle_overleft PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1456 ( circle_overright PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1457 ( circle_right PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1458 ( circle_contained PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1459 ( circle_overlap PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1460 ( circle_below PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1461 ( circle_above PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1462 ( circle_eq PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1463 ( circle_ne PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1464 ( circle_lt PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1465 ( circle_gt PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1466 ( circle_le PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1467 ( circle_ge PGUID 11 f t f 2 f 16 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1468 ( circle_area PGUID 11 f t f 1 f 701 "718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1469 ( circle_diameter PGUID 11 f t f 1 f 701 "718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1470 ( circle_radius PGUID 11 f t f 1 f 701 "718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1471 ( circle_distance PGUID 11 f t f 2 f 701 "718 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1472 ( circle_center PGUID 11 f t f 1 f 600 "718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1473 ( circle PGUID 11 f t f 2 f 718 "600 701" 100 0 1 0 foo bar ));
+DATA(insert OID = 1474 ( poly_circle PGUID 11 f t f 1 f 718 "604" 100 0 1 0 foo bar ));
+DATA(insert OID = 1475 ( circle_poly PGUID 11 f t f 2 f 604 "23 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1476 ( dist_pc PGUID 11 f t f 2 f 604 "600 718" 100 0 1 0 foo bar ));
+DATA(insert OID = 1477 ( circle_contain_pt PGUID 11 f t f 2 f 16 "718 600" 100 0 0 100 foo bar ));
+DATA(insert OID = 1478 ( pt_contained_circle PGUID 11 f t f 2 f 16 "600 718" 100 0 0 100 foo bar ));
+DATA(insert OID = 1479 ( box_circle PGUID 11 f t f 1 f 718 "603" 100 0 1 0 foo bar ));
+DATA(insert OID = 1480 ( circle_box PGUID 11 f t f 1 f 603 "718" 100 0 1 0 foo bar ));
+
+DATA(insert OID = 1530 ( point PGUID 14 f t f 2 f 600 "601 601" 100 0 0 100 "select lseg_interpt($1, $2)" - ));
+DATA(insert OID = 1531 ( point PGUID 14 f t f 1 f 600 "718" 100 0 0 100 "select circle_center($1)" - ));
+DATA(insert OID = 1532 ( isvertical PGUID 14 f t f 2 f 16 "600 600" 100 0 0 100 "select point_vert($1, $2)" - ));
+DATA(insert OID = 1533 ( ishorizontal PGUID 14 f t f 2 f 16 "600 600" 100 0 0 100 "select point_horiz($1, $2)" - ));
+DATA(insert OID = 1534 ( slope PGUID 14 f t f 2 f 701 "600 600" 100 0 0 100 "select point_slope($1, $2)" - ));
+
+DATA(insert OID = 1540 ( lseg PGUID 14 f t f 2 f 601 "600 600" 100 0 0 100 "select lseg_construct($1, $2)" - ));
+DATA(insert OID = 1541 ( lseg PGUID 14 f t f 1 f 601 "603" 100 0 0 100 "select box_diagonal($1)" - ));
+DATA(insert OID = 1542 ( isparallel PGUID 14 f t f 2 f 16 "601 601" 100 0 0 100 "select lseg_parallel($1, $2)" - ));
+DATA(insert OID = 1543 ( isperpendicular PGUID 14 f t f 2 f 16 "601 601" 100 0 0 100 "select lseg_perp($1, $2)" - ));
+DATA(insert OID = 1544 ( isvertical PGUID 14 f t f 1 f 16 "601" 100 0 0 100 "select lseg_vertical($1)" - ));
+DATA(insert OID = 1545 ( ishorizontal PGUID 14 f t f 1 f 16 "601" 100 0 0 100 "select lseg_horizontal($1)" - ));
/* pclose and popen might better be named close and open, but that crashes initdb.
* - tgl 97/04/20
*/
-DATA(insert OID = 1550 ( path PGUID 14 f t f 1 f 602 "604" 100 0 0 100 "select poly_path($1)" - ));
-DATA(insert OID = 1551 ( length PGUID 14 f t f 1 f 701 "602" 100 0 1 0 "select path_length($1)" - ));
-DATA(insert OID = 1552 ( points PGUID 14 f t f 1 f 23 "602" 100 0 0 100 "select path_npoints($1)" - ));
-DATA(insert OID = 1553 ( pclose PGUID 14 f t f 1 f 602 "602" 100 0 0 100 "select path_close($1)" - ));
-DATA(insert OID = 1554 ( popen PGUID 14 f t f 1 f 602 "602" 100 0 0 100 "select path_open($1)" - ));
-DATA(insert OID = 1555 ( isopen PGUID 14 f t f 1 f 16 "602" 100 0 0 100 "select path_isopen($1)" - ));
-DATA(insert OID = 1556 ( isclosed PGUID 14 f t f 1 f 16 "602" 100 0 0 100 "select path_isclosed($1)" - ));
-
-DATA(insert OID = 1560 ( box PGUID 14 f t f 2 f 603 "603 603" 100 0 0 100 "select box_intersect($1, $2)" - ));
-DATA(insert OID = 1561 ( box PGUID 14 f t f 1 f 603 "604" 100 0 0 100 "select poly_box($1)" - ));
-DATA(insert OID = 1562 ( width PGUID 14 f t f 1 f 701 "603" 100 0 0 100 "select box_width($1)" - ));
-DATA(insert OID = 1563 ( height PGUID 14 f t f 1 f 701 "603" 100 0 0 100 "select box_height($1)" - ));
-DATA(insert OID = 1564 ( center PGUID 14 f t f 1 f 600 "603" 100 0 0 100 "select box_center($1)" - ));
-DATA(insert OID = 1565 ( area PGUID 14 f t f 1 f 701 "603" 100 0 0 100 "select box_area($1)" - ));
-DATA(insert OID = 1569 ( box PGUID 14 f t f 1 f 603 "718" 100 0 0 100 "select circle_box($1)" - ));
-
-DATA(insert OID = 1570 ( polygon PGUID 14 f t f 1 f 604 "602" 100 0 0 100 "select path_poly($1)" - ));
-DATA(insert OID = 1571 ( polygon PGUID 14 f t f 1 f 604 "603" 100 0 0 100 "select box_poly($1)" - ));
-DATA(insert OID = 1572 ( polygon PGUID 14 f t f 2 f 604 "23 718" 100 0 0 100 "select circle_poly($1, $2)" - ));
-DATA(insert OID = 1573 ( polygon PGUID 14 f t f 1 f 604 "718" 100 0 0 100 "select circle_poly(12, $1)" - ));
-DATA(insert OID = 1574 ( points PGUID 14 f t f 1 f 23 "604" 100 0 0 100 "select poly_npoints($1)" - ));
-DATA(insert OID = 1575 ( center PGUID 14 f t f 1 f 600 "604" 100 0 0 100 "select poly_center($1)" - ));
-
-DATA(insert OID = 1579 ( circle PGUID 14 f t f 1 f 718 "603" 100 0 0 100 "select box_circle($1)" - ));
-DATA(insert OID = 1580 ( circle PGUID 14 f t f 1 f 718 "604" 100 0 0 100 "select poly_circle($1)" - ));
-DATA(insert OID = 1581 ( center PGUID 14 f t f 1 f 600 "718" 100 0 0 100 "select circle_center($1)" - ));
-DATA(insert OID = 1582 ( radius PGUID 14 f t f 1 f 701 "718" 100 0 0 100 "select circle_radius($1)" - ));
-DATA(insert OID = 1583 ( diameter PGUID 14 f t f 1 f 701 "718" 100 0 0 100 "select circle_diameter($1)" - ));
-DATA(insert OID = 1584 ( area PGUID 14 f t f 1 f 701 "718" 100 0 0 100 "select circle_area($1)" - ));
+DATA(insert OID = 1550 ( path PGUID 14 f t f 1 f 602 "604" 100 0 0 100 "select poly_path($1)" - ));
+DATA(insert OID = 1551 ( length PGUID 14 f t f 1 f 701 "602" 100 0 1 0 "select path_length($1)" - ));
+DATA(insert OID = 1552 ( points PGUID 14 f t f 1 f 23 "602" 100 0 0 100 "select path_npoints($1)" - ));
+DATA(insert OID = 1553 ( pclose PGUID 14 f t f 1 f 602 "602" 100 0 0 100 "select path_close($1)" - ));
+DATA(insert OID = 1554 ( popen PGUID 14 f t f 1 f 602 "602" 100 0 0 100 "select path_open($1)" - ));
+DATA(insert OID = 1555 ( isopen PGUID 14 f t f 1 f 16 "602" 100 0 0 100 "select path_isopen($1)" - ));
+DATA(insert OID = 1556 ( isclosed PGUID 14 f t f 1 f 16 "602" 100 0 0 100 "select path_isclosed($1)" - ));
+
+DATA(insert OID = 1560 ( box PGUID 14 f t f 2 f 603 "603 603" 100 0 0 100 "select box_intersect($1, $2)" - ));
+DATA(insert OID = 1561 ( box PGUID 14 f t f 1 f 603 "604" 100 0 0 100 "select poly_box($1)" - ));
+DATA(insert OID = 1562 ( width PGUID 14 f t f 1 f 701 "603" 100 0 0 100 "select box_width($1)" - ));
+DATA(insert OID = 1563 ( height PGUID 14 f t f 1 f 701 "603" 100 0 0 100 "select box_height($1)" - ));
+DATA(insert OID = 1564 ( center PGUID 14 f t f 1 f 600 "603" 100 0 0 100 "select box_center($1)" - ));
+DATA(insert OID = 1565 ( area PGUID 14 f t f 1 f 701 "603" 100 0 0 100 "select box_area($1)" - ));
+DATA(insert OID = 1569 ( box PGUID 14 f t f 1 f 603 "718" 100 0 0 100 "select circle_box($1)" - ));
+
+DATA(insert OID = 1570 ( polygon PGUID 14 f t f 1 f 604 "602" 100 0 0 100 "select path_poly($1)" - ));
+DATA(insert OID = 1571 ( polygon PGUID 14 f t f 1 f 604 "603" 100 0 0 100 "select box_poly($1)" - ));
+DATA(insert OID = 1572 ( polygon PGUID 14 f t f 2 f 604 "23 718" 100 0 0 100 "select circle_poly($1, $2)" - ));
+DATA(insert OID = 1573 ( polygon PGUID 14 f t f 1 f 604 "718" 100 0 0 100 "select circle_poly(12, $1)" - ));
+DATA(insert OID = 1574 ( points PGUID 14 f t f 1 f 23 "604" 100 0 0 100 "select poly_npoints($1)" - ));
+DATA(insert OID = 1575 ( center PGUID 14 f t f 1 f 600 "604" 100 0 0 100 "select poly_center($1)" - ));
+
+DATA(insert OID = 1579 ( circle PGUID 14 f t f 1 f 718 "603" 100 0 0 100 "select box_circle($1)" - ));
+DATA(insert OID = 1580 ( circle PGUID 14 f t f 1 f 718 "604" 100 0 0 100 "select poly_circle($1)" - ));
+DATA(insert OID = 1581 ( center PGUID 14 f t f 1 f 600 "718" 100 0 0 100 "select circle_center($1)" - ));
+DATA(insert OID = 1582 ( radius PGUID 14 f t f 1 f 701 "718" 100 0 0 100 "select circle_radius($1)" - ));
+DATA(insert OID = 1583 ( diameter PGUID 14 f t f 1 f 701 "718" 100 0 0 100 "select circle_diameter($1)" - ));
+DATA(insert OID = 1584 ( area PGUID 14 f t f 1 f 701 "718" 100 0 0 100 "select circle_area($1)" - ));
/* Oracle Compatibility Related Functions - By Edmund Mergl <E.Mergl@bawue.de> */
-DATA(insert OID = 868 ( strpos PGUID 14 f t f 2 f 23 "25 25" 100 0 0 100 "select textpos($1, $2)" - ));
-
-DATA(insert OID = 869 ( trim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select btrim($1, \' \')" - ));
-DATA(insert OID = 870 ( lower PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 871 ( upper PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 872 ( initcap PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 873 ( lpad PGUID 11 f t f 3 f 25 "25 23 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 874 ( rpad PGUID 11 f t f 3 f 25 "25 23 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 875 ( ltrim PGUID 11 f t f 2 f 25 "25 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 876 ( rtrim PGUID 11 f t f 2 f 25 "25 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 877 ( substr PGUID 11 f t f 3 f 25 "25 23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 868 ( strpos PGUID 14 f t f 2 f 23 "25 25" 100 0 0 100 "select textpos($1, $2)" - ));
+
+DATA(insert OID = 869 ( trim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select btrim($1, \' \')" - ));
+DATA(insert OID = 870 ( lower PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 871 ( upper PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 872 ( initcap PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 873 ( lpad PGUID 11 f t f 3 f 25 "25 23 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 874 ( rpad PGUID 11 f t f 3 f 25 "25 23 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 875 ( ltrim PGUID 11 f t f 2 f 25 "25 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 876 ( rtrim PGUID 11 f t f 2 f 25 "25 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 877 ( substr PGUID 11 f t f 3 f 25 "25 23 23" 100 0 0 100 foo bar ));
DATA(insert OID = 878 ( translate PGUID 11 f t f 3 f 25 "25 18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 879 ( lpad PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select lpad($1, $2, \' \')" - ));
-DATA(insert OID = 880 ( rpad PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select rpad($1, $2, \' \')" - ));
-DATA(insert OID = 881 ( ltrim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select ltrim($1, \' \')" - ));
-DATA(insert OID = 882 ( rtrim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select rtrim($1, \' \')" - ));
-DATA(insert OID = 883 ( substr PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select substr($1, $2, 10000)" - ));
-DATA(insert OID = 884 ( btrim PGUID 11 f t f 2 f 25 "25 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 885 ( btrim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select btrim($1, \' \')" - ));
+DATA(insert OID = 879 ( lpad PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select lpad($1, $2, \' \')" - ));
+DATA(insert OID = 880 ( rpad PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select rpad($1, $2, \' \')" - ));
+DATA(insert OID = 881 ( ltrim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select ltrim($1, \' \')" - ));
+DATA(insert OID = 882 ( rtrim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select rtrim($1, \' \')" - ));
+DATA(insert OID = 883 ( substr PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select substr($1, $2, 10000)" - ));
+DATA(insert OID = 884 ( btrim PGUID 11 f t f 2 f 25 "25 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 885 ( btrim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select btrim($1, \' \')" - ));
/* XXX Help, where should I go to */
-DATA(insert OID = 1586 ( timespan_div PGUID 11 f t f 2 f 1186 "1186 701" 100 0 0 100 foo bar ));
+DATA(insert OID = 1586 ( timespan_div PGUID 11 f t f 2 f 1186 "1186 701" 100 0 0 100 foo bar ));
/* SEQUENCEs nextval & currval functions */
-DATA(insert OID = 1317 ( nextval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 1319 ( currval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1317 ( nextval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1319 ( currval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
#define SeqNextValueRegProcedure 1317
#define SeqCurrValueRegProcedure 1319
-/*
- * prototypes for functions pg_proc.c
+/*
+ * prototypes for functions pg_proc.c
*/
-extern Oid ProcedureCreate(char* procedureName,
- bool returnsSet,
- char *returnTypeName,
- char *languageName,
- char *prosrc,
- char *probin,
- bool canCache,
- bool trusted,
- int32 byte_pct,
- int32 perbyte_cpu,
- int32 percall_cpu,
- int32 outin_ratio,
- List *argList,
- CommandDest dest);
-
-
-#endif /* PG_PROC_H */
+extern Oid
+ProcedureCreate(char *procedureName,
+ bool returnsSet,
+ char *returnTypeName,
+ char *languageName,
+ char *prosrc,
+ char *probin,
+ bool canCache,
+ bool trusted,
+ int32 byte_pct,
+ int32 perbyte_cpu,
+ int32 percall_cpu,
+ int32 outin_ratio,
+ List * argList,
+ CommandDest dest);
+
+
+#endif /* PG_PROC_H */
diff --git a/src/include/catalog/pg_relcheck.h b/src/include/catalog/pg_relcheck.h
index 1609f142673..c0ca6604756 100644
--- a/src/include/catalog/pg_relcheck.h
+++ b/src/include/catalog/pg_relcheck.h
@@ -6,8 +6,8 @@
* Copyright (c) 1994, Regents of the University of California
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -15,39 +15,40 @@
#define PG_RELCHECK_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_relcheck definition. cpp turns this into
- * typedef struct FormData_pg_relcheck
+ * pg_relcheck definition. cpp turns this into
+ * typedef struct FormData_pg_relcheck
* ----------------
- */
-CATALOG(pg_relcheck) BOOTSTRAP {
- Oid rcrelid;
- NameData rcname;
- text rcbin;
- text rcsrc;
+ */
+CATALOG(pg_relcheck) BOOTSTRAP
+{
+ Oid rcrelid;
+ NameData rcname;
+ text rcbin;
+ text rcsrc;
} FormData_pg_relcheck;
/* ----------------
- * Form_pg_relcheck corresponds to a pointer to a tuple with
- * the format of pg_relcheck relation.
+ * Form_pg_relcheck corresponds to a pointer to a tuple with
+ * the format of pg_relcheck relation.
* ----------------
*/
-typedef FormData_pg_relcheck *Form_pg_relcheck;
+typedef FormData_pg_relcheck *Form_pg_relcheck;
/* ----------------
- * compiler constants for pg_relcheck
+ * compiler constants for pg_relcheck
* ----------------
*/
-#define Natts_pg_relcheck 4
-#define Anum_pg_relcheck_rcrelid 1
-#define Anum_pg_relcheck_rcname 2
-#define Anum_pg_relcheck_rcbin 3
-#define Anum_pg_relcheck_rcsrc 4
+#define Natts_pg_relcheck 4
+#define Anum_pg_relcheck_rcrelid 1
+#define Anum_pg_relcheck_rcname 2
+#define Anum_pg_relcheck_rcbin 3
+#define Anum_pg_relcheck_rcsrc 4
-#endif /* PG_RELCHECK_H */
+#endif /* PG_RELCHECK_H */
diff --git a/src/include/catalog/pg_rewrite.h b/src/include/catalog/pg_rewrite.h
index 04c59255962..8491d238954 100644
--- a/src/include/catalog/pg_rewrite.h
+++ b/src/include/catalog/pg_rewrite.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_rewrite.h--
- * definition of the system "rewrite-rule" relation (pg_rewrite)
- * along with the relation's initial contents.
+ * definition of the system "rewrite-rule" relation (pg_rewrite)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_rewrite.h,v 1.2 1996/10/31 09:47:54 scrappy Exp $
+ * $Id: pg_rewrite.h,v 1.3 1997/09/07 04:57:08 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,45 +19,46 @@
#define PG_REWRITE_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_rewrite definition. cpp turns this into
- * typedef struct FormData_pg_rewrite
+ * pg_rewrite definition. cpp turns this into
+ * typedef struct FormData_pg_rewrite
* ----------------
- */
-CATALOG(pg_rewrite) {
- NameData rulename;
- char ev_type;
- Oid ev_class;
- int2 ev_attr;
- bool is_instead;
- text ev_qual; /* VARLENA */
- text action; /* VARLENA */
+ */
+CATALOG(pg_rewrite)
+{
+ NameData rulename;
+ char ev_type;
+ Oid ev_class;
+ int2 ev_attr;
+ bool is_instead;
+ text ev_qual; /* VARLENA */
+ text action; /* VARLENA */
} FormData_pg_rewrite;
/* ----------------
- * Form_pg_rewrite corresponds to a pointer to a tuple with
- * the format of pg_rewrite relation.
+ * Form_pg_rewrite corresponds to a pointer to a tuple with
+ * the format of pg_rewrite relation.
* ----------------
*/
typedef FormData_pg_rewrite *Form_pg_rewrite;
/* ----------------
- * compiler constants for pg_rewrite
+ * compiler constants for pg_rewrite
* ----------------
*/
-#define Natts_pg_rewrite 7
-#define Anum_pg_rewrite_rulename 1
-#define Anum_pg_rewrite_ev_type 2
-#define Anum_pg_rewrite_ev_class 3
-#define Anum_pg_rewrite_ev_attr 4
-#define Anum_pg_rewrite_is_instead 5
-#define Anum_pg_rewrite_ev_qual 6
-#define Anum_pg_rewrite_action 7
+#define Natts_pg_rewrite 7
+#define Anum_pg_rewrite_rulename 1
+#define Anum_pg_rewrite_ev_type 2
+#define Anum_pg_rewrite_ev_class 3
+#define Anum_pg_rewrite_ev_attr 4
+#define Anum_pg_rewrite_is_instead 5
+#define Anum_pg_rewrite_ev_qual 6
+#define Anum_pg_rewrite_action 7
-#endif /* PG_REWRITE_H */
+#endif /* PG_REWRITE_H */
diff --git a/src/include/catalog/pg_server.h b/src/include/catalog/pg_server.h
index 87d917903a7..8c0c642dc13 100644
--- a/src/include/catalog/pg_server.h
+++ b/src/include/catalog/pg_server.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_server.h--
- * definition of the system "server" relation (pg_server)
- * along with the relation's initial contents.
+ * definition of the system "server" relation (pg_server)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_server.h,v 1.2 1996/10/31 09:47:55 scrappy Exp $
+ * $Id: pg_server.h,v 1.3 1997/09/07 04:57:09 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,37 +19,38 @@
#define PG_SERVER_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_server definition. cpp turns this into
- * typedef struct FormData_pg_server
+ * pg_server definition. cpp turns this into
+ * typedef struct FormData_pg_server
* ----------------
- */
-CATALOG(pg_server) BOOTSTRAP {
- NameData sername;
- int2 serpid;
- int2 serport;
+ */
+CATALOG(pg_server) BOOTSTRAP
+{
+ NameData sername;
+ int2 serpid;
+ int2 serport;
} FormData_pg_server;
/* ----------------
- * Form_pg_server corresponds to a pointer to a tuple with
- * the format of pg_server relation.
+ * Form_pg_server corresponds to a pointer to a tuple with
+ * the format of pg_server relation.
* ----------------
*/
-typedef FormData_pg_server *Form_pg_server;
+typedef FormData_pg_server *Form_pg_server;
/* ----------------
- * compiler constants for pg_server
+ * compiler constants for pg_server
* ----------------
*/
-#define Natts_pg_server 3
-#define Anum_pg_server_sername 1
-#define Anum_pg_server_serpid 2
-#define Anum_pg_server_serport 3
+#define Natts_pg_server 3
+#define Anum_pg_server_sername 1
+#define Anum_pg_server_serpid 2
+#define Anum_pg_server_serport 3
-#endif /* PG_SERVER_H */
+#endif /* PG_SERVER_H */
diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h
index cc76e5d893c..6059bbd477c 100644
--- a/src/include/catalog/pg_statistic.h
+++ b/src/include/catalog/pg_statistic.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_statistic.h--
- * definition of the system "statistic" relation (pg_statistic)
- * along with the relation's initial contents.
+ * definition of the system "statistic" relation (pg_statistic)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_statistic.h,v 1.2 1996/10/31 09:47:57 scrappy Exp $
+ * $Id: pg_statistic.h,v 1.3 1997/09/07 04:57:10 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,41 +19,42 @@
#define PG_STATISTIC_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_statistic definition. cpp turns this into
- * typedef struct FormData_pg_statistic
+ * pg_statistic definition. cpp turns this into
+ * typedef struct FormData_pg_statistic
* ----------------
- */
-CATALOG(pg_statistic) {
- Oid starelid;
- int2 staattnum;
- Oid staop;
- text stalokey; /* VARIABLE LENGTH FIELD */
- text stahikey; /* VARIABLE LENGTH FIELD */
+ */
+CATALOG(pg_statistic)
+{
+ Oid starelid;
+ int2 staattnum;
+ Oid staop;
+ text stalokey; /* VARIABLE LENGTH FIELD */
+ text stahikey; /* VARIABLE LENGTH FIELD */
} FormData_pg_statistic;
/* ----------------
- * Form_pg_statistic corresponds to a pointer to a tuple with
- * the format of pg_statistic relation.
+ * Form_pg_statistic corresponds to a pointer to a tuple with
+ * the format of pg_statistic relation.
* ----------------
*/
-typedef FormData_pg_statistic *Form_pg_statistic;
+typedef FormData_pg_statistic *Form_pg_statistic;
/* ----------------
- * compiler constants for pg_statistic
+ * compiler constants for pg_statistic
* ----------------
*/
-#define Natts_pg_statistic 5
-#define Anum_pg_statistic_starelid 1
-#define Anum_pg_statistic_staattnum 2
-#define Anum_pg_statistic_staop 3
-#define Anum_pg_statistic_stalokey 4
-#define Anum_pg_statistic_stahikey 5
+#define Natts_pg_statistic 5
+#define Anum_pg_statistic_starelid 1
+#define Anum_pg_statistic_staattnum 2
+#define Anum_pg_statistic_staop 3
+#define Anum_pg_statistic_stalokey 4
+#define Anum_pg_statistic_stahikey 5
-#endif /* PG_STATISTIC_H */
+#endif /* PG_STATISTIC_H */
diff --git a/src/include/catalog/pg_time.h b/src/include/catalog/pg_time.h
index 5b35d73f25b..f1955930f06 100644
--- a/src/include/catalog/pg_time.h
+++ b/src/include/catalog/pg_time.h
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* pg_time.h--
- * the system commit-time relation "pg_time" is not a "heap" relation.
- * it is automatically created by the transam/ code and the
- * information here is all bogus and is just here to make the
- * relcache code happy.
+ * the system commit-time relation "pg_time" is not a "heap" relation.
+ * it is automatically created by the transam/ code and the
+ * information here is all bogus and is just here to make the
+ * relcache code happy.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_time.h,v 1.2 1996/10/31 09:47:58 scrappy Exp $
+ * $Id: pg_time.h,v 1.3 1997/09/07 04:57:10 momjian Exp $
*
* NOTES
- * The structures and macros used by the transam/ code
- * to access pg_time should some day go here -cim 6/18/90
+ * The structures and macros used by the transam/ code
+ * to access pg_time should some day go here -cim 6/18/90
*
*-------------------------------------------------------------------------
*/
@@ -21,20 +21,21 @@
#define PG_TIME_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
-CATALOG(pg_time) BOOTSTRAP {
- Oid timefoo;
+CATALOG(pg_time) BOOTSTRAP
+{
+ Oid timefoo;
} FormData_pg_time;
-typedef FormData_pg_time *Form_pg_time;
+typedef FormData_pg_time *Form_pg_time;
-#define Natts_pg_time 1
+#define Natts_pg_time 1
#define Anum_pg_time_timefoo 1
-#endif /* PG_TIME_H */
+#endif /* PG_TIME_H */
diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h
index 7c675b73db3..08472839ef0 100644
--- a/src/include/catalog/pg_trigger.h
+++ b/src/include/catalog/pg_trigger.h
@@ -6,8 +6,8 @@
* Copyright (c) 1994, Regents of the University of California
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -15,65 +15,67 @@
#define PG_TRIGGER_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_trigger definition. cpp turns this into
- * typedef struct FormData_pg_trigger
+ * pg_trigger definition. cpp turns this into
+ * typedef struct FormData_pg_trigger
* ----------------
- */
-CATALOG(pg_trigger) BOOTSTRAP {
- Oid tgrelid; /* triggered relation */
- NameData tgname; /* trigger' name */
- Oid tgfoid; /* OID of function to be called */
- int2 tgtype; /* BEFORE/AFTER UPDATE/DELETE/INSERT ROW/STATEMENT */
- int2 tgnargs; /* # of extra arguments in tgargs */
- int28 tgattr; /* UPDATE of attr1, attr2 ... (NI) */
- bytea tgargs; /* first\000second\000tgnargs\000 */
+ */
+CATALOG(pg_trigger) BOOTSTRAP
+{
+ Oid tgrelid; /* triggered relation */
+ NameData tgname; /* trigger' name */
+ Oid tgfoid; /* OID of function to be called */
+ int2 tgtype; /* BEFORE/AFTER UPDATE/DELETE/INSERT
+ * ROW/STATEMENT */
+ int2 tgnargs; /* # of extra arguments in tgargs */
+ int28 tgattr; /* UPDATE of attr1, attr2 ... (NI) */
+ bytea tgargs; /* first\000second\000tgnargs\000 */
} FormData_pg_trigger;
/* ----------------
- * Form_pg_trigger corresponds to a pointer to a tuple with
- * the format of pg_trigger relation.
+ * Form_pg_trigger corresponds to a pointer to a tuple with
+ * the format of pg_trigger relation.
* ----------------
*/
-typedef FormData_pg_trigger *Form_pg_trigger;
+typedef FormData_pg_trigger *Form_pg_trigger;
/* ----------------
- * compiler constants for pg_trigger
+ * compiler constants for pg_trigger
* ----------------
*/
-#define Natts_pg_trigger 7
-#define Anum_pg_trigger_tgrelid 1
-#define Anum_pg_trigger_tgname 2
-#define Anum_pg_trigger_tgfoid 3
-#define Anum_pg_trigger_tgtype 4
-#define Anum_pg_trigger_tgnargs 5
-#define Anum_pg_trigger_tgattr 6
-#define Anum_pg_trigger_tgargs 7
+#define Natts_pg_trigger 7
+#define Anum_pg_trigger_tgrelid 1
+#define Anum_pg_trigger_tgname 2
+#define Anum_pg_trigger_tgfoid 3
+#define Anum_pg_trigger_tgtype 4
+#define Anum_pg_trigger_tgnargs 5
+#define Anum_pg_trigger_tgattr 6
+#define Anum_pg_trigger_tgargs 7
-#define TRIGGER_TYPE_ROW (1 << 0)
-#define TRIGGER_TYPE_BEFORE (1 << 1)
-#define TRIGGER_TYPE_INSERT (1 << 2)
-#define TRIGGER_TYPE_DELETE (1 << 3)
-#define TRIGGER_TYPE_UPDATE (1 << 4)
+#define TRIGGER_TYPE_ROW (1 << 0)
+#define TRIGGER_TYPE_BEFORE (1 << 1)
+#define TRIGGER_TYPE_INSERT (1 << 2)
+#define TRIGGER_TYPE_DELETE (1 << 3)
+#define TRIGGER_TYPE_UPDATE (1 << 4)
-#define TRIGGER_CLEAR_TYPE(type) (type = 0)
+#define TRIGGER_CLEAR_TYPE(type) (type = 0)
-#define TRIGGER_SETT_ROW(type) (type |= TRIGGER_TYPE_ROW)
-#define TRIGGER_SETT_BEFORE(type) (type |= TRIGGER_TYPE_BEFORE)
-#define TRIGGER_SETT_INSERT(type) (type |= TRIGGER_TYPE_INSERT)
-#define TRIGGER_SETT_DELETE(type) (type |= TRIGGER_TYPE_DELETE)
-#define TRIGGER_SETT_UPDATE(type) (type |= TRIGGER_TYPE_UPDATE)
+#define TRIGGER_SETT_ROW(type) (type |= TRIGGER_TYPE_ROW)
+#define TRIGGER_SETT_BEFORE(type) (type |= TRIGGER_TYPE_BEFORE)
+#define TRIGGER_SETT_INSERT(type) (type |= TRIGGER_TYPE_INSERT)
+#define TRIGGER_SETT_DELETE(type) (type |= TRIGGER_TYPE_DELETE)
+#define TRIGGER_SETT_UPDATE(type) (type |= TRIGGER_TYPE_UPDATE)
-#define TRIGGER_FOR_ROW(type) (type & TRIGGER_TYPE_ROW)
-#define TRIGGER_FOR_BEFORE(type) (type & TRIGGER_TYPE_BEFORE)
-#define TRIGGER_FOR_INSERT(type) (type & TRIGGER_TYPE_INSERT)
-#define TRIGGER_FOR_DELETE(type) (type & TRIGGER_TYPE_DELETE)
-#define TRIGGER_FOR_UPDATE(type) (type & TRIGGER_TYPE_UPDATE)
+#define TRIGGER_FOR_ROW(type) (type & TRIGGER_TYPE_ROW)
+#define TRIGGER_FOR_BEFORE(type) (type & TRIGGER_TYPE_BEFORE)
+#define TRIGGER_FOR_INSERT(type) (type & TRIGGER_TYPE_INSERT)
+#define TRIGGER_FOR_DELETE(type) (type & TRIGGER_TYPE_DELETE)
+#define TRIGGER_FOR_UPDATE(type) (type & TRIGGER_TYPE_UPDATE)
-#endif /* PG_TRIGGER_H */
+#endif /* PG_TRIGGER_H */
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 14a3983ce07..9083dad4452 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_type.h--
- * definition of the system "type" relation (pg_type)
- * along with the relation's initial contents.
+ * definition of the system "type" relation (pg_type)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_type.h,v 1.16 1997/08/31 09:55:24 vadim Exp $
+ * $Id: pg_type.h,v 1.17 1997/09/07 04:57:12 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -21,212 +21,220 @@
#include <utils/rel.h>
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_type definition. cpp turns this into
- * typedef struct FormData_pg_type
+ * pg_type definition. cpp turns this into
+ * typedef struct FormData_pg_type
*
- * Some of the values in a pg_type instance are copied into
- * pg_attribute instances. Some parts of Postgres use the pg_type copy,
- * while others use the pg_attribute copy, so they must match.
- * See struct FormData_pg_attribute for details.
+ * Some of the values in a pg_type instance are copied into
+ * pg_attribute instances. Some parts of Postgres use the pg_type copy,
+ * while others use the pg_attribute copy, so they must match.
+ * See struct FormData_pg_attribute for details.
* ----------------
*/
-CATALOG(pg_type) BOOTSTRAP {
- NameData typname;
- Oid typowner;
- int2 typlen;
- /* typlen is the number of bytes we use to represent a value of
- this type, e.g. 4 for an int4. But for a variable length
- type, typlen is -1.
- */
- int2 typprtlen;
- bool typbyval;
- /* typbyval determines whether internal Postgres routines pass a value
- of this type by value or by reference. Postgres uses a 4 byte
- area for passing a field value info, so if the value is not 1, 2,
- or 4 bytes long, Postgres does not have the option of passing by
- value and ignores typbyval.
-
- (I don't understand why this column exists. The above description
- may be an oversimplification. Also, there appear to be bugs in which
- Postgres doesn't ignore typbyval when it should, but I'm
- afraid to change them until I see proof of damage. -BRYANH 96.08).
-
- (Postgres crashes if typbyval is true, the declared length is 8,
- and the I/O routines are written to expect pass by reference.
- Note that float4 is written for pass by reference and has a declared length
- of 4 bytes, so it looks like pass by reference must be consistant
- with the declared length, and typbyval is used somewhere. - tgl 97/03/20)
- */
- char typtype;
- bool typisdefined;
- char typdelim;
- Oid typrelid;
- Oid typelem;
- /* typelem is NULL if this is not an array type. If this is an array
- type, typelem is the OID of the type of the elements of the array
- (it identifies another row in Table pg_type).
-
- (Note that zero ("0") rather than _null_ is used
- in the declarations. - tgl 97/03/20)
- */
- regproc typinput;
- regproc typoutput;
- regproc typreceive;
- regproc typsend;
- char typalign;
- /* typalign is the alignment required when storing a value of this
- type. It applies to storage on disk as well as most representations
- of the value inside Postgres. When multiple values are stored
- consecutively, such as in the representation of a complete row
- on disk, padding is inserted before a datum of this type so that it
- begins on the specified boundary. The alignment reference is the
- beginning of the first datum in the sequence.
-
- 'c' = 1 byte alignment.
- 's' = 2 byte alignment.
- 'i' = 4 byte alignment.
- 'd' = 8 byte alignment.
-
- (This might actually be flexible depending on machine architecture,
- but I doubt it - BRYANH 96.08).
- */
- text typdefault; /* VARIABLE LENGTH FIELD */
+CATALOG(pg_type) BOOTSTRAP
+{
+ NameData typname;
+ Oid typowner;
+ int2 typlen;
+
+ /*
+ * typlen is the number of bytes we use to represent a value of this
+ * type, e.g. 4 for an int4. But for a variable length type, typlen
+ * is -1.
+ */
+ int2 typprtlen;
+ bool typbyval;
+
+ /*
+ * typbyval determines whether internal Postgres routines pass a value
+ * of this type by value or by reference. Postgres uses a 4 byte area
+ * for passing a field value info, so if the value is not 1, 2, or 4
+ * bytes long, Postgres does not have the option of passing by value
+ * and ignores typbyval.
+ *
+ * (I don't understand why this column exists. The above description may
+ * be an oversimplification. Also, there appear to be bugs in which
+ * Postgres doesn't ignore typbyval when it should, but I'm afraid to
+ * change them until I see proof of damage. -BRYANH 96.08).
+ *
+ * (Postgres crashes if typbyval is true, the declared length is 8, and
+ * the I/O routines are written to expect pass by reference. Note that
+ * float4 is written for pass by reference and has a declared length
+ * of 4 bytes, so it looks like pass by reference must be consistant
+ * with the declared length, and typbyval is used somewhere. - tgl
+ * 97/03/20)
+ */
+ char typtype;
+ bool typisdefined;
+ char typdelim;
+ Oid typrelid;
+ Oid typelem;
+
+ /*
+ * typelem is NULL if this is not an array type. If this is an array
+ * type, typelem is the OID of the type of the elements of the array
+ * (it identifies another row in Table pg_type).
+ *
+ * (Note that zero ("0") rather than _null_ is used in the declarations.
+ * - tgl 97/03/20)
+ */
+ regproc typinput;
+ regproc typoutput;
+ regproc typreceive;
+ regproc typsend;
+ char typalign;
+
+ /*
+ * typalign is the alignment required when storing a value of this
+ * type. It applies to storage on disk as well as most
+ * representations of the value inside Postgres. When multiple values
+ * are stored consecutively, such as in the representation of a
+ * complete row on disk, padding is inserted before a datum of this
+ * type so that it begins on the specified boundary. The alignment
+ * reference is the beginning of the first datum in the sequence.
+ *
+ * 'c' = 1 byte alignment. 's' = 2 byte alignment. 'i' = 4 byte
+ * alignment. 'd' = 8 byte alignment.
+ *
+ * (This might actually be flexible depending on machine architecture,
+ * but I doubt it - BRYANH 96.08).
+ */
+ text typdefault; /* VARIABLE LENGTH FIELD */
} TypeTupleFormData;
/* ----------------
- * Form_pg_type corresponds to a pointer to a row with
- * the format of pg_type relation.
+ * Form_pg_type corresponds to a pointer to a row with
+ * the format of pg_type relation.
* ----------------
*/
-typedef TypeTupleFormData *TypeTupleForm;
+typedef TypeTupleFormData *TypeTupleForm;
/* ----------------
- * compiler constants for pg_type
+ * compiler constants for pg_type
* ----------------
*/
-#define Natts_pg_type 16
-#define Anum_pg_type_typname 1
-#define Anum_pg_type_typowner 2
-#define Anum_pg_type_typlen 3
-#define Anum_pg_type_typprtlen 4
-#define Anum_pg_type_typbyval 5
-#define Anum_pg_type_typtype 6
-#define Anum_pg_type_typisdefined 7
-#define Anum_pg_type_typdelim 8
-#define Anum_pg_type_typrelid 9
-#define Anum_pg_type_typelem 10
-#define Anum_pg_type_typinput 11
-#define Anum_pg_type_typoutput 12
-#define Anum_pg_type_typreceive 13
-#define Anum_pg_type_typsend 14
-#define Anum_pg_type_typalign 15
-#define Anum_pg_type_typdefault 16
+#define Natts_pg_type 16
+#define Anum_pg_type_typname 1
+#define Anum_pg_type_typowner 2
+#define Anum_pg_type_typlen 3
+#define Anum_pg_type_typprtlen 4
+#define Anum_pg_type_typbyval 5
+#define Anum_pg_type_typtype 6
+#define Anum_pg_type_typisdefined 7
+#define Anum_pg_type_typdelim 8
+#define Anum_pg_type_typrelid 9
+#define Anum_pg_type_typelem 10
+#define Anum_pg_type_typinput 11
+#define Anum_pg_type_typoutput 12
+#define Anum_pg_type_typreceive 13
+#define Anum_pg_type_typsend 14
+#define Anum_pg_type_typalign 15
+#define Anum_pg_type_typdefault 16
/* ----------------
- * initial contents of pg_type
+ * initial contents of pg_type
* ----------------
*/
/* keep the following ordered by OID so that later changes can be made easier*/
/* Make sure the typlen, typbyval, and typalign values here match the initial
- values for attlen, attbyval, and attalign in both places in pg_attribute.h
+ values for attlen, attbyval, and attalign in both places in pg_attribute.h
for every instance.
*/
/* OIDS 1 - 99 */
-DATA(insert OID = 16 ( bool PGUID 1 1 t b t \054 0 0 boolin boolout boolin boolout c _null_ ));
-#define BOOLOID 16
+DATA(insert OID = 16 ( bool PGUID 1 1 t b t \054 0 0 boolin boolout boolin boolout c _null_ ));
+#define BOOLOID 16
-DATA(insert OID = 17 ( bytea PGUID -1 -1 f b t \054 0 18 byteain byteaout byteain byteaout i _null_ ));
-DATA(insert OID = 18 ( char PGUID 1 1 t b t \054 0 0 charin charout charin charout c _null_ ));
+DATA(insert OID = 17 ( bytea PGUID -1 -1 f b t \054 0 18 byteain byteaout byteain byteaout i _null_ ));
+DATA(insert OID = 18 ( char PGUID 1 1 t b t \054 0 0 charin charout charin charout c _null_ ));
#define CHAROID 18
-DATA(insert OID = 19 ( name PGUID NAMEDATALEN NAMEDATALEN f b t \054 0 18 namein nameout namein nameout d _null_ ));
+DATA(insert OID = 19 ( name PGUID NAMEDATALEN NAMEDATALEN f b t \054 0 18 namein nameout namein nameout d _null_ ));
#define NAMEOID 19
-DATA(insert OID = 20 ( char16 PGUID 16 16 f b t \054 0 18 char16in char16out char16in char16out i _null_ ));
-DATA(insert OID = 21 ( int2 PGUID 2 5 t b t \054 0 0 int2in int2out int2in int2out s _null_ ));
-#define INT2OID 21
+DATA(insert OID = 20 ( char16 PGUID 16 16 f b t \054 0 18 char16in char16out char16in char16out i _null_ ));
+DATA(insert OID = 21 ( int2 PGUID 2 5 t b t \054 0 0 int2in int2out int2in int2out s _null_ ));
+#define INT2OID 21
-DATA(insert OID = 22 ( int28 PGUID 16 50 f b t \054 0 21 int28in int28out int28in int28out i _null_ ));
+DATA(insert OID = 22 ( int28 PGUID 16 50 f b t \054 0 21 int28in int28out int28in int28out i _null_ ));
/*
* XXX -- the implementation of int28's in postgres is a hack, and will
- * go away someday. until that happens, there is a case (in the
- * catalog cache management code) where we need to step gingerly
- * over piles of int28's on the sidewalk. in order to do so, we
- * need the OID of the int28 row from pg_type.
+ * go away someday. until that happens, there is a case (in the
+ * catalog cache management code) where we need to step gingerly
+ * over piles of int28's on the sidewalk. in order to do so, we
+ * need the OID of the int28 row from pg_type.
*/
-#define INT28OID 22
+#define INT28OID 22
-DATA(insert OID = 23 ( int4 PGUID 4 10 t b t \054 0 0 int4in int4out int4in int4out i _null_ ));
-#define INT4OID 23
+DATA(insert OID = 23 ( int4 PGUID 4 10 t b t \054 0 0 int4in int4out int4in int4out i _null_ ));
+#define INT4OID 23
-DATA(insert OID = 24 ( regproc PGUID 4 16 t b t \054 0 0 regprocin regprocout regprocin regprocout i _null_ ));
-DATA(insert OID = 25 ( text PGUID -1 -1 f b t \054 0 18 textin textout textin textout i _null_ ));
+DATA(insert OID = 24 ( regproc PGUID 4 16 t b t \054 0 0 regprocin regprocout regprocin regprocout i _null_ ));
+DATA(insert OID = 25 ( text PGUID -1 -1 f b t \054 0 18 textin textout textin textout i _null_ ));
#define TEXTOID 25
-DATA(insert OID = 26 ( oid PGUID 4 10 t b t \054 0 0 int4in int4out int4in int4out i _null_ ));
-#define OIDOID 26
-
-DATA(insert OID = 27 ( tid PGUID 6 19 f b t \054 0 0 tidin tidout tidin tidout i _null_ ));
-DATA(insert OID = 28 ( xid PGUID 4 12 t b t \054 0 0 xidin xidout xidin xidout i _null_ ));
-DATA(insert OID = 29 ( cid PGUID 2 3 t b t \054 0 0 cidin cidout cidin cidout s _null_ ));
-DATA(insert OID = 30 ( oid8 PGUID 32 89 f b t \054 0 26 oid8in oid8out oid8in oid8out i _null_ ));
-DATA(insert OID = 32 ( SET PGUID -1 -1 f r t \054 0 -1 textin textout textin textout i _null_ ));
-
-DATA(insert OID = 71 ( pg_type PGUID 1 1 t b t \054 1247 0 foo bar foo bar c _null_));
-DATA(insert OID = 75 ( pg_attribute PGUID 1 1 t b t \054 1249 0 foo bar foo bar c _null_));
-DATA(insert OID = 76 ( pg_demon PGUID 1 1 t b t \054 1251 0 foo bar foo bar c _null_));
-DATA(insert OID = 80 ( pg_magic PGUID 1 1 t b t \054 1253 0 foo bar foo bar c _null_));
-DATA(insert OID = 81 ( pg_proc PGUID 1 1 t b t \054 1255 0 foo bar foo bar c _null_));
-DATA(insert OID = 82 ( pg_server PGUID 1 1 t b t \054 1257 0 foo bar foo bar c _null_));
-DATA(insert OID = 83 ( pg_class PGUID 1 1 t b t \054 1259 0 foo bar foo bar c _null_));
-DATA(insert OID = 86 ( pg_user PGUID 1 1 t b t \054 1260 0 foo bar foo bar c _null_));
-DATA(insert OID = 87 ( pg_group PGUID 1 1 t b t \054 1261 0 foo bar foo bar c _null_));
-DATA(insert OID = 88 ( pg_database PGUID 1 1 t b t \054 1262 0 foo bar foo bar c _null_));
-DATA(insert OID = 89 ( pg_defaults PGUID 1 1 t b t \054 1263 0 foo bar foo bar c _null_));
-DATA(insert OID = 90 ( pg_variable PGUID 1 1 t b t \054 1264 0 foo bar foo bar c _null_));
-DATA(insert OID = 99 ( pg_log PGUID 1 1 t b t \054 1269 0 foo bar foo bar c _null_));
+DATA(insert OID = 26 ( oid PGUID 4 10 t b t \054 0 0 int4in int4out int4in int4out i _null_ ));
+#define OIDOID 26
+
+DATA(insert OID = 27 ( tid PGUID 6 19 f b t \054 0 0 tidin tidout tidin tidout i _null_ ));
+DATA(insert OID = 28 ( xid PGUID 4 12 t b t \054 0 0 xidin xidout xidin xidout i _null_ ));
+DATA(insert OID = 29 ( cid PGUID 2 3 t b t \054 0 0 cidin cidout cidin cidout s _null_ ));
+DATA(insert OID = 30 ( oid8 PGUID 32 89 f b t \054 0 26 oid8in oid8out oid8in oid8out i _null_ ));
+DATA(insert OID = 32 ( SET PGUID -1 -1 f r t \054 0 -1 textin textout textin textout i _null_ ));
+
+DATA(insert OID = 71 ( pg_type PGUID 1 1 t b t \054 1247 0 foo bar foo bar c _null_));
+DATA(insert OID = 75 ( pg_attribute PGUID 1 1 t b t \054 1249 0 foo bar foo bar c _null_));
+DATA(insert OID = 76 ( pg_demon PGUID 1 1 t b t \054 1251 0 foo bar foo bar c _null_));
+DATA(insert OID = 80 ( pg_magic PGUID 1 1 t b t \054 1253 0 foo bar foo bar c _null_));
+DATA(insert OID = 81 ( pg_proc PGUID 1 1 t b t \054 1255 0 foo bar foo bar c _null_));
+DATA(insert OID = 82 ( pg_server PGUID 1 1 t b t \054 1257 0 foo bar foo bar c _null_));
+DATA(insert OID = 83 ( pg_class PGUID 1 1 t b t \054 1259 0 foo bar foo bar c _null_));
+DATA(insert OID = 86 ( pg_user PGUID 1 1 t b t \054 1260 0 foo bar foo bar c _null_));
+DATA(insert OID = 87 ( pg_group PGUID 1 1 t b t \054 1261 0 foo bar foo bar c _null_));
+DATA(insert OID = 88 ( pg_database PGUID 1 1 t b t \054 1262 0 foo bar foo bar c _null_));
+DATA(insert OID = 89 ( pg_defaults PGUID 1 1 t b t \054 1263 0 foo bar foo bar c _null_));
+DATA(insert OID = 90 ( pg_variable PGUID 1 1 t b t \054 1264 0 foo bar foo bar c _null_));
+DATA(insert OID = 99 ( pg_log PGUID 1 1 t b t \054 1269 0 foo bar foo bar c _null_));
/* OIDS 100 - 199 */
-DATA(insert OID = 100 ( pg_time PGUID 1 1 t b t \054 1271 0 foo bar foo bar c _null_));
-DATA(insert OID = 101 ( pg_hosts PGUID 1 1 t b t \054 1273 0 foo bar foo bar c _null_));
+DATA(insert OID = 100 ( pg_time PGUID 1 1 t b t \054 1271 0 foo bar foo bar c _null_));
+DATA(insert OID = 101 ( pg_hosts PGUID 1 1 t b t \054 1273 0 foo bar foo bar c _null_));
DATA(insert OID = 109 ( pg_attrdef PGUID 1 1 t b t \054 1215 0 foo bar foo bar c _null_));
DATA(insert OID = 110 ( pg_relcheck PGUID 1 1 t b t \054 1216 0 foo bar foo bar c _null_));
DATA(insert OID = 111 ( pg_trigger PGUID 1 1 t b t \054 1219 0 foo bar foo bar c _null_));
/* OIDS 200 - 299 */
-DATA(insert OID = 210 ( smgr PGUID 2 12 t b t \054 0 -1 smgrin smgrout smgrin smgrout s _null_ ));
+DATA(insert OID = 210 ( smgr PGUID 2 12 t b t \054 0 -1 smgrin smgrout smgrin smgrout s _null_ ));
/* OIDS 300 - 399 */
/* OIDS 400 - 499 */
-DATA(insert OID = 409 ( char2 PGUID 2 2 t b t \054 0 18 char2in char2out char2in char2out s _null_ ));
-DATA(insert OID = 410 ( char4 PGUID 4 4 t b t \054 0 18 char4in char4out char4in char4out i _null_ ));
-DATA(insert OID = 411 ( char8 PGUID 8 8 f b t \054 0 18 char8in char8out char8in char8out i _null_ ));
+DATA(insert OID = 409 ( char2 PGUID 2 2 t b t \054 0 18 char2in char2out char2in char2out s _null_ ));
+DATA(insert OID = 410 ( char4 PGUID 4 4 t b t \054 0 18 char4in char4out char4in char4out i _null_ ));
+DATA(insert OID = 411 ( char8 PGUID 8 8 f b t \054 0 18 char8in char8out char8in char8out i _null_ ));
/* OIDS 500 - 599 */
/* OIDS 600 - 699 */
-DATA(insert OID = 600 ( point PGUID 16 24 f b t \054 0 701 point_in point_out point_in point_out d _null_ ));
-DATA(insert OID = 601 ( lseg PGUID 32 48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d _null_ ));
-DATA(insert OID = 602 ( path PGUID -1 -1 f b t \054 0 600 path_in path_out path_in path_out d _null_ ));
-DATA(insert OID = 603 ( box PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d _null_ ));
+DATA(insert OID = 600 ( point PGUID 16 24 f b t \054 0 701 point_in point_out point_in point_out d _null_ ));
+DATA(insert OID = 601 ( lseg PGUID 32 48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d _null_ ));
+DATA(insert OID = 602 ( path PGUID -1 -1 f b t \054 0 600 path_in path_out path_in path_out d _null_ ));
+DATA(insert OID = 603 ( box PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d _null_ ));
DATA(insert OID = 604 ( polygon PGUID -1 -1 f b t \054 0 -1 poly_in poly_out poly_in poly_out d _null_ ));
DATA(insert OID = 605 ( filename PGUID 256 -1 f b t \054 0 18 filename_in filename_out filename_in filename_out i _null_ ));
-DATA(insert OID = 628 ( line PGUID 32 48 f b t \054 0 701 line_in line_out line_in line_out d _null_ ));
-DATA(insert OID = 629 ( _line PGUID -1 -1 f b t \054 0 628 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 628 ( line PGUID 32 48 f b t \054 0 701 line_in line_out line_in line_out d _null_ ));
+DATA(insert OID = 629 ( _line PGUID -1 -1 f b t \054 0 628 array_in array_out array_in array_out d _null_ ));
/* OIDS 700 - 799 */
@@ -238,11 +246,11 @@ DATA(insert OID = 702 ( abstime PGUID 4 20 t b t \054 0 0 nabstimein nabs
DATA(insert OID = 703 ( reltime PGUID 4 20 t b t \054 0 0 reltimein reltimeout reltimein reltimeout i _null_ ));
DATA(insert OID = 704 ( tinterval PGUID 12 47 f b t \054 0 0 tintervalin tintervalout tintervalin tintervalout i _null_ ));
DATA(insert OID = 705 ( unknown PGUID -1 -1 f b t \054 0 18 textin textout textin textout i _null_ ));
-#define UNKNOWNOID 705
+#define UNKNOWNOID 705
-DATA(insert OID = 718 ( circle PGUID 24 47 f b t \054 0 0 circle_in circle_out circle_in circle_out d _null_ ));
+DATA(insert OID = 718 ( circle PGUID 24 47 f b t \054 0 0 circle_in circle_out circle_in circle_out d _null_ ));
DATA(insert OID = 719 ( _circle PGUID -1 -1 f b t \054 0 718 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 790 ( money PGUID 4 24 f b t \054 0 0 cash_in cash_out cash_in cash_out i _null_ ));
+DATA(insert OID = 790 ( money PGUID 4 24 f b t \054 0 0 cash_in cash_out cash_in cash_out i _null_ ));
#define CASHOID 790
DATA(insert OID = 791 ( _money PGUID -1 -1 f b t \054 0 790 array_in array_out array_in array_out i _null_ ));
@@ -254,87 +262,88 @@ DATA(insert OID = 910 ( oidint4 PGUID 8 20 f b t \054 0 0 oidint4in oidin
DATA(insert OID = 911 ( oidname PGUID OIDNAMELEN OIDNAMELEN f b t \054 0 0 oidnamein oidnameout oidnamein oidnameout i _null_ ));
/* OIDS 1000 - 1099 */
-DATA(insert OID = 1000 ( _bool PGUID -1 -1 f b t \054 0 16 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1001 ( _bytea PGUID -1 -1 f b t \054 0 17 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1002 ( _char PGUID -1 -1 f b t \054 0 18 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1003 ( _name PGUID -1 -1 f b t \054 0 19 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1004 ( _char16 PGUID -1 -1 f b t \054 0 20 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1005 ( _int2 PGUID -1 -1 f b t \054 0 21 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1006 ( _int28 PGUID -1 -1 f b t \054 0 22 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1007 ( _int4 PGUID -1 -1 f b t \054 0 23 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1008 ( _regproc PGUID -1 -1 f b t \054 0 24 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1009 ( _text PGUID -1 -1 f b t \054 0 25 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1028 ( _oid PGUID -1 -1 f b t \054 0 26 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1010 ( _tid PGUID -1 -1 f b t \054 0 27 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1011 ( _xid PGUID -1 -1 f b t \054 0 28 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1012 ( _cid PGUID -1 -1 f b t \054 0 29 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1013 ( _oid8 PGUID -1 -1 f b t \054 0 30 array_in array_out array_in array_out i _null_ ));
-/*DATA(insert OID = 1014 ( _lock PGUID -1 -1 f b t \054 0 31 array_in array_out array_in array_out i _null_ ));*/
-DATA(insert OID = 1015 ( _stub PGUID -1 -1 f b t \054 0 33 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1016 ( _ref PGUID -1 -1 f b t \054 0 591 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1017 ( _point PGUID -1 -1 f b t \054 0 600 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1018 ( _lseg PGUID -1 -1 f b t \054 0 601 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1019 ( _path PGUID -1 -1 f b t \054 0 602 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1020 ( _box PGUID -1 -1 f b t \073 0 603 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1021 ( _float4 PGUID -1 -1 f b t \054 0 700 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1022 ( _float8 PGUID -1 -1 f b t \054 0 701 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1023 ( _abstime PGUID -1 -1 f b t \054 0 702 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1024 ( _reltime PGUID -1 -1 f b t \054 0 703 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1000 ( _bool PGUID -1 -1 f b t \054 0 16 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1001 ( _bytea PGUID -1 -1 f b t \054 0 17 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1002 ( _char PGUID -1 -1 f b t \054 0 18 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1003 ( _name PGUID -1 -1 f b t \054 0 19 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1004 ( _char16 PGUID -1 -1 f b t \054 0 20 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1005 ( _int2 PGUID -1 -1 f b t \054 0 21 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1006 ( _int28 PGUID -1 -1 f b t \054 0 22 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1007 ( _int4 PGUID -1 -1 f b t \054 0 23 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1008 ( _regproc PGUID -1 -1 f b t \054 0 24 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1009 ( _text PGUID -1 -1 f b t \054 0 25 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1028 ( _oid PGUID -1 -1 f b t \054 0 26 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1010 ( _tid PGUID -1 -1 f b t \054 0 27 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1011 ( _xid PGUID -1 -1 f b t \054 0 28 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1012 ( _cid PGUID -1 -1 f b t \054 0 29 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1013 ( _oid8 PGUID -1 -1 f b t \054 0 30 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1014 ( _lock PGUID -1 -1 f b t \054 0 31 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1015 ( _stub PGUID -1 -1 f b t \054 0 33 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1016 ( _ref PGUID -1 -1 f b t \054 0 591 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1017 ( _point PGUID -1 -1 f b t \054 0 600 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1018 ( _lseg PGUID -1 -1 f b t \054 0 601 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1019 ( _path PGUID -1 -1 f b t \054 0 602 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1020 ( _box PGUID -1 -1 f b t \073 0 603 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1021 ( _float4 PGUID -1 -1 f b t \054 0 700 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1022 ( _float8 PGUID -1 -1 f b t \054 0 701 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1023 ( _abstime PGUID -1 -1 f b t \054 0 702 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1024 ( _reltime PGUID -1 -1 f b t \054 0 703 array_in array_out array_in array_out i _null_ ));
DATA(insert OID = 1025 ( _tinterval PGUID -1 -1 f b t \054 0 704 array_in array_out array_in array_out i _null_ ));
DATA(insert OID = 1026 ( _filename PGUID -1 -1 f b t \054 0 605 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1027 ( _polygon PGUID -1 -1 f b t \054 0 604 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1027 ( _polygon PGUID -1 -1 f b t \054 0 604 array_in array_out array_in array_out d _null_ ));
/* Note: the size of an aclitem needs to match sizeof(AclItem) in acl.h */
-DATA(insert OID = 1033 ( aclitem PGUID 8 -1 f b t \054 0 0 aclitemin aclitemout aclitemin aclitemout i _null_ ));
-DATA(insert OID = 1034 ( _aclitem PGUID -1 -1 f b t \054 0 1033 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1033 ( aclitem PGUID 8 -1 f b t \054 0 0 aclitemin aclitemout aclitemin aclitemout i _null_ ));
+DATA(insert OID = 1034 ( _aclitem PGUID -1 -1 f b t \054 0 1033 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1039 ( _char2 PGUID -1 -1 f b t \054 0 409 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1040 ( _char4 PGUID -1 -1 f b t \054 0 410 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1041 ( _char8 PGUID -1 -1 f b t \054 0 411 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1039 ( _char2 PGUID -1 -1 f b t \054 0 409 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1040 ( _char4 PGUID -1 -1 f b t \054 0 410 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1041 ( _char8 PGUID -1 -1 f b t \054 0 411 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1042 ( bpchar PGUID -1 -1 f b t \054 0 18 bpcharin bpcharout bpcharin bpcharout i _null_ ));
-#define BPCHAROID 1042
-DATA(insert OID = 1043 ( varchar PGUID -1 -1 f b t \054 0 18 varcharin varcharout varcharin varcharout i _null_ ));
-#define VARCHAROID 1043
+DATA(insert OID = 1042 ( bpchar PGUID -1 -1 f b t \054 0 18 bpcharin bpcharout bpcharin bpcharout i _null_ ));
+#define BPCHAROID 1042
+DATA(insert OID = 1043 ( varchar PGUID -1 -1 f b t \054 0 18 varcharin varcharout varcharin varcharout i _null_ ));
+#define VARCHAROID 1043
-DATA(insert OID = 1082 ( date PGUID 4 10 t b t \054 0 0 date_in date_out date_in date_out i _null_ ));
-#define DATEOID 1082
-DATA(insert OID = 1083 ( time PGUID 8 16 f b t \054 0 0 time_in time_out time_in time_out d _null_ ));
-#define TIMEOID 1083
+DATA(insert OID = 1082 ( date PGUID 4 10 t b t \054 0 0 date_in date_out date_in date_out i _null_ ));
+#define DATEOID 1082
+DATA(insert OID = 1083 ( time PGUID 8 16 f b t \054 0 0 time_in time_out time_in time_out d _null_ ));
+#define TIMEOID 1083
/* OIDS 1100 - 1199 */
-DATA(insert OID = 1182 ( _date PGUID -1 -1 f b t \054 0 1082 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1183 ( _time PGUID -1 -1 f b t \054 0 1083 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1184 ( datetime PGUID 8 47 f b t \054 0 0 datetime_in datetime_out datetime_in datetime_out d _null_ ));
-#define DATETIMEOID 1184
-DATA(insert OID = 1185 ( _datetime PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1186 ( timespan PGUID 12 47 f b t \054 0 0 timespan_in timespan_out timespan_in timespan_out d _null_ ));
-#define TIMESPANOID 1186
-DATA(insert OID = 1187 ( _timespan PGUID -1 -1 f b t \054 0 1186 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1182 ( _date PGUID -1 -1 f b t \054 0 1082 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1183 ( _time PGUID -1 -1 f b t \054 0 1083 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1184 ( datetime PGUID 8 47 f b t \054 0 0 datetime_in datetime_out datetime_in datetime_out d _null_ ));
+#define DATETIMEOID 1184
+DATA(insert OID = 1185 ( _datetime PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1186 ( timespan PGUID 12 47 f b t \054 0 0 timespan_in timespan_out timespan_in timespan_out d _null_ ));
+#define TIMESPANOID 1186
+DATA(insert OID = 1187 ( _timespan PGUID -1 -1 f b t \054 0 1186 array_in array_out array_in array_out d _null_ ));
/* OIDS 1200 - 1299 */
-DATA(insert OID = 1296 ( timestamp PGUID 4 19 t b t \054 0 0 timestamp_in timestamp_out timestamp_in timestamp_out i _null_ ));
+DATA(insert OID = 1296 ( timestamp PGUID 4 19 t b t \054 0 0 timestamp_in timestamp_out timestamp_in timestamp_out i _null_ ));
#define TIMESTAMPOID 1296
/*
- * prototypes for functions in pg_type.c
+ * prototypes for functions in pg_type.c
*/
-extern Oid TypeGet(char *typeName, bool *defined);
-extern Oid TypeShellMake(char *typeName);
-extern Oid TypeCreate(char *typeName,
- Oid relationOid,
- int16 internalSize,
- int16 externalSize,
- char typeType,
- char typDelim,
- char *inputProcedure,
- char *outputProcedure,
- char *sendProcedure,
- char *receiveProcedure,
- char *elementTypeName,
- char *defaultTypeValue,
- bool passedByValue, char alignment);
-extern void TypeRename(char *oldTypeName, char *newTypeName);
-extern char *makeArrayTypeName(char *typeName);
-
-
-#endif /* PG_TYPE_H */
+extern Oid TypeGet(char *typeName, bool * defined);
+extern Oid TypeShellMake(char *typeName);
+extern Oid
+TypeCreate(char *typeName,
+ Oid relationOid,
+ int16 internalSize,
+ int16 externalSize,
+ char typeType,
+ char typDelim,
+ char *inputProcedure,
+ char *outputProcedure,
+ char *sendProcedure,
+ char *receiveProcedure,
+ char *elementTypeName,
+ char *defaultTypeValue,
+ bool passedByValue, char alignment);
+extern void TypeRename(char *oldTypeName, char *newTypeName);
+extern char *makeArrayTypeName(char *typeName);
+
+
+#endif /* PG_TYPE_H */
diff --git a/src/include/catalog/pg_user.h b/src/include/catalog/pg_user.h
index 5cfc6984520..904e35cd15d 100644
--- a/src/include/catalog/pg_user.h
+++ b/src/include/catalog/pg_user.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_user.h--
- * definition of the system "user" relation (pg_user)
- * along with the relation's initial contents.
+ * definition of the system "user" relation (pg_user)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_user.h,v 1.3 1996/11/03 23:49:07 scrappy Exp $
+ * $Id: pg_user.h,v 1.4 1997/09/07 04:57:13 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -21,43 +21,44 @@
/* Prototype required for superuser() from superuser.c */
-bool superuser(void);
+bool superuser(void);
/* ----------------
- * pg_user definition. cpp turns this into
- * typedef struct FormData_pg_user
+ * pg_user definition. cpp turns this into
+ * typedef struct FormData_pg_user
* ----------------
- */
-CATALOG(pg_user) BOOTSTRAP {
- NameData usename;
- int4 usesysid;
- bool usecreatedb;
- bool usetrace;
- bool usesuper;
- bool usecatupd;
+ */
+CATALOG(pg_user) BOOTSTRAP
+{
+ NameData usename;
+ int4 usesysid;
+ bool usecreatedb;
+ bool usetrace;
+ bool usesuper;
+ bool usecatupd;
} FormData_pg_user;
/* ----------------
- * Form_pg_user corresponds to a pointer to a tuple with
- * the format of pg_user relation.
+ * Form_pg_user corresponds to a pointer to a tuple with
+ * the format of pg_user relation.
* ----------------
*/
-typedef FormData_pg_user *Form_pg_user;
+typedef FormData_pg_user *Form_pg_user;
/* ----------------
- * compiler constants for pg_user
+ * compiler constants for pg_user
* ----------------
*/
-#define Natts_pg_user 6
-#define Anum_pg_user_usename 1
-#define Anum_pg_user_usesysid 2
-#define Anum_pg_user_usecreatedb 3
-#define Anum_pg_user_usetrace 4
-#define Anum_pg_user_usesuper 5
-#define Anum_pg_user_usecatupd 6
+#define Natts_pg_user 6
+#define Anum_pg_user_usename 1
+#define Anum_pg_user_usesysid 2
+#define Anum_pg_user_usecreatedb 3
+#define Anum_pg_user_usetrace 4
+#define Anum_pg_user_usesuper 5
+#define Anum_pg_user_usecatupd 6
/* ----------------
- * initial contents of pg_user
+ * initial contents of pg_user
* ----------------
*/
DATA(insert OID = 0 ( postgres PGUID t t t t ));
@@ -88,9 +89,9 @@ DATA(insert OID = 0 ( marcel 31113 t t t t ));
DATA(insert OID = 0 ( ginger 3692 t t t t ));
DATA(insert OID = 0 ( woodruff 31026 t t t t ));
DATA(insert OID = 0 ( searcher 8261 t t t t ));
-
+
BKI_BEGIN
-#endif /* ALLOW_PG_GROUP */
+#endif /* ALLOW_PG_GROUP */
BKI_END
-#endif /* PG_USER_H */
+#endif /* PG_USER_H */
diff --git a/src/include/catalog/pg_variable.h b/src/include/catalog/pg_variable.h
index d7b753357bb..ef685f35719 100644
--- a/src/include/catalog/pg_variable.h
+++ b/src/include/catalog/pg_variable.h
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* pg_variable.h--
- * the system variable relation "pg_variable" is not a "heap" relation.
- * it is automatically created by the transam/ code and the
- * information here is all bogus and is just here to make the
- * relcache code happy.
+ * the system variable relation "pg_variable" is not a "heap" relation.
+ * it is automatically created by the transam/ code and the
+ * information here is all bogus and is just here to make the
+ * relcache code happy.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_variable.h,v 1.2 1996/10/31 09:48:02 scrappy Exp $
+ * $Id: pg_variable.h,v 1.3 1997/09/07 04:57:15 momjian Exp $
*
* NOTES
- * The structures and macros used by the transam/ code
- * to access pg_variable should someday go here -cim 6/18/90
+ * The structures and macros used by the transam/ code
+ * to access pg_variable should someday go here -cim 6/18/90
*
*-------------------------------------------------------------------------
*/
@@ -21,19 +21,20 @@
#define PG_VARIABLE_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
-CATALOG(pg_variable) BOOTSTRAP {
- Oid varfoo;
+CATALOG(pg_variable) BOOTSTRAP
+{
+ Oid varfoo;
} FormData_pg_variable;
-typedef FormData_pg_variable *Form_pg_variable;
+typedef FormData_pg_variable *Form_pg_variable;
-#define Natts_pg_variable 1
-#define Anum_pg_variable_varfoo 1
+#define Natts_pg_variable 1
+#define Anum_pg_variable_varfoo 1
-#endif /* PG_VARIABLE_H */
+#endif /* PG_VARIABLE_H */
diff --git a/src/include/catalog/pg_version.h b/src/include/catalog/pg_version.h
index 4602199466d..ba1249ab04e 100644
--- a/src/include/catalog/pg_version.h
+++ b/src/include/catalog/pg_version.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* pg_version.h--
- * definition of the system "version" relation (pg_version)
- * along with the relation's initial contents.
+ * definition of the system "version" relation (pg_version)
+ * along with the relation's initial contents.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_version.h,v 1.3 1996/11/06 10:29:23 scrappy Exp $
+ * $Id: pg_version.h,v 1.4 1997/09/07 04:57:17 momjian Exp $
*
* NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
@@ -19,38 +19,39 @@
#define PG_VERSION_H
/* ----------------
- * postgres.h contains the system type definintions and the
- * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
+ * postgres.h contains the system type definintions and the
+ * CATALOG(), BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
- * pg_version definition. cpp turns this into
- * typedef struct FormData_pg_version
+ * pg_version definition. cpp turns this into
+ * typedef struct FormData_pg_version
* ----------------
- */
-CATALOG(pg_version) {
- Oid verrelid;
- Oid verbaseid;
- int4 vertime; /* really should be some abstime */
+ */
+CATALOG(pg_version)
+{
+ Oid verrelid;
+ Oid verbaseid;
+ int4 vertime; /* really should be some abstime */
} FormData_pg_version;
/* ----------------
- * Form_pg_version corresponds to a pointer to a tuple with
- * the format of pg_version relation.
+ * Form_pg_version corresponds to a pointer to a tuple with
+ * the format of pg_version relation.
* ----------------
*/
-typedef FormData_pg_version *VersionTupleForm;
+typedef FormData_pg_version *VersionTupleForm;
/* ----------------
- * compiler constants for pg_version
+ * compiler constants for pg_version
* ----------------
*/
-#define Natts_pg_version 3
-#define Anum_pg_version_verrelid 1
-#define Anum_pg_version_verbaseid 2
-#define Anum_pg_version_vertime 3
+#define Natts_pg_version 3
+#define Anum_pg_version_verrelid 1
+#define Anum_pg_version_verbaseid 2
+#define Anum_pg_version_vertime 3
-#endif /* PG_VERSION_H */
+#endif /* PG_VERSION_H */
diff --git a/src/include/commands/async.h b/src/include/commands/async.h
index 7bae5c6f4b4..4f63c7fde71 100644
--- a/src/include/commands/async.h
+++ b/src/include/commands/async.h
@@ -1,26 +1,26 @@
/*-------------------------------------------------------------------------
*
* async.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: async.h,v 1.5 1997/08/19 21:38:03 momjian Exp $
+ * $Id: async.h,v 1.6 1997/09/07 04:57:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef ASYNC_H
-#define ASYNC_H
+#ifndef ASYNC_H
+#define ASYNC_H
#include <nodes/memnodes.h>
-extern void Async_NotifyHandler(SIGNAL_ARGS);
-extern void Async_Notify(char *relname);
-extern void Async_NotifyAtCommit(void);
-extern void Async_NotifyAtAbort(void);
-extern void Async_Listen(char *relname, int pid);
+extern void Async_NotifyHandler(SIGNAL_ARGS);
+extern void Async_Notify(char *relname);
+extern void Async_NotifyAtCommit(void);
+extern void Async_NotifyAtAbort(void);
+extern void Async_Listen(char *relname, int pid);
extern GlobalMemory notifyContext;
-#endif /* ASYNC_H */
+#endif /* ASYNC_H */
diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h
index 45ba116212e..7f305c60144 100644
--- a/src/include/commands/cluster.h
+++ b/src/include/commands/cluster.h
@@ -1,27 +1,27 @@
/*-------------------------------------------------------------------------
*
* cluster.h--
- * header file for postgres cluster command stuff
+ * header file for postgres cluster command stuff
*
* Copyright (c) 1994-5, Regents of the University of California
*
- * $Id: cluster.h,v 1.2 1997/08/19 21:38:06 momjian Exp $
+ * $Id: cluster.h,v 1.3 1997/09/07 04:57:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef CLUSTER_H
-#define CLUSTER_H
+#ifndef CLUSTER_H
+#define CLUSTER_H
/*
* defines for contant stuff
*/
-#define _TEMP_RELATION_KEY_ "clXXXXXXXX"
-#define _SIZE_OF_TEMP_RELATION_KEY_ 11
+#define _TEMP_RELATION_KEY_ "clXXXXXXXX"
+#define _SIZE_OF_TEMP_RELATION_KEY_ 11
/*
* functions
*/
-extern void cluster(char oldrelname[], char oldindexname[]);
+extern void cluster(char oldrelname[], char oldindexname[]);
-#endif /* CLUSTER_H */
+#endif /* CLUSTER_H */
diff --git a/src/include/commands/command.h b/src/include/commands/command.h
index d91d7b3a913..78c4aa5ea0e 100644
--- a/src/include/commands/command.h
+++ b/src/include/commands/command.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* command.h--
- * prototypes for command.c.
+ * prototypes for command.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: command.h,v 1.4 1997/08/19 21:38:07 momjian Exp $
+ * $Id: command.h,v 1.5 1997/09/07 04:57:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,29 +19,31 @@ extern MemoryContext PortalExecutorHeapMemory;
/*
* PerformPortalFetch --
- * Performs the POSTQUEL function FETCH. Fetches count (or all if 0)
+ * Performs the POSTQUEL function FETCH. Fetches count (or all if 0)
* tuples in portal with name in the forward direction iff goForward.
*
* Exceptions:
- * BadArg if forward invalid.
- * "WARN" if portal not found.
+ * BadArg if forward invalid.
+ * "WARN" if portal not found.
*/
-extern void PerformPortalFetch(char *name, bool forward, int count,
- char *tag, CommandDest dest);
+extern void
+PerformPortalFetch(char *name, bool forward, int count,
+ char *tag, CommandDest dest);
/*
* PerformPortalClose --
- * Performs the POSTQUEL function CLOSE.
+ * Performs the POSTQUEL function CLOSE.
*/
-extern void PerformPortalClose(char *name, CommandDest dest);
+extern void PerformPortalClose(char *name, CommandDest dest);
-extern void PortalCleanup(Portal portal);
+extern void PortalCleanup(Portal portal);
/*
* PerformAddAttribute --
- * Performs the POSTQUEL function ADD.
+ * Performs the POSTQUEL function ADD.
*/
-extern void PerformAddAttribute(char *relationName, char *userName,
- bool inh, ColumnDef *colDef);
+extern void
+PerformAddAttribute(char *relationName, char *userName,
+ bool inh, ColumnDef * colDef);
-#endif /* COMMAND_H */
+#endif /* COMMAND_H */
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index 1a1228b142d..e1fb6a37838 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -1,20 +1,21 @@
/*-------------------------------------------------------------------------
*
* copy.h--
- * Definitions for using the POSTGRES copy command.
+ * Definitions for using the POSTGRES copy command.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: copy.h,v 1.2 1996/10/31 09:48:12 scrappy Exp $
+ * $Id: copy.h,v 1.3 1997/09/07 04:57:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef COPY_H
-#define COPY_H
+#define COPY_H
-void DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, char *filename,
- char *delim);
+void
+DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, char *filename,
+ char *delim);
-#endif /* COPY_H */
+#endif /* COPY_H */
diff --git a/src/include/commands/creatinh.h b/src/include/commands/creatinh.h
index 1728a577a92..52926dbe9f8 100644
--- a/src/include/commands/creatinh.h
+++ b/src/include/commands/creatinh.h
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* creatinh.h--
- * prototypes for creatinh.c.
+ * prototypes for creatinh.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: creatinh.h,v 1.1 1996/08/28 07:21:45 scrappy Exp $
+ * $Id: creatinh.h,v 1.2 1997/09/07 04:57:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef CREATINH_H
#define CREATINH_H
-extern void DefineRelation(CreateStmt *stmt);
-extern void RemoveRelation(char *name);
-extern char* MakeArchiveName(Oid relid);
+extern void DefineRelation(CreateStmt * stmt);
+extern void RemoveRelation(char *name);
+extern char *MakeArchiveName(Oid relid);
-#endif /* CREATINH_H */
+#endif /* CREATINH_H */
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index f47e7a343ea..8d916477380 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* defrem.h--
- * POSTGRES define and remove utility definitions.
+ * POSTGRES define and remove utility definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: defrem.h,v 1.7 1997/05/22 00:15:47 scrappy Exp $
+ * $Id: defrem.h,v 1.8 1997/09/07 04:57:25 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef DEFREM_H
+#ifndef DEFREM_H
#define DEFREM_H
#include <tcop/dest.h>
@@ -19,35 +19,38 @@
/*
* prototypes in defind.c
*/
-extern void DefineIndex(char *heapRelationName,
+extern void
+DefineIndex(char *heapRelationName,
char *indexRelationName,
char *accessMethodName,
- List *attributeList,
- List *parameterList,
+ List * attributeList,
+ List * parameterList,
bool unique,
- Expr *predicate,
- List *rangetable);
-extern void ExtendIndex(char *indexRelationName,
- Expr *predicate,
- List *rangetable);
-extern void RemoveIndex(char *name);
+ Expr * predicate,
+ List * rangetable);
+extern void
+ExtendIndex(char *indexRelationName,
+ Expr * predicate,
+ List * rangetable);
+extern void RemoveIndex(char *name);
/*
* prototypes in define.c
*/
-extern void CreateFunction(ProcedureStmt *stmt, CommandDest dest);
-extern void DefineOperator(char *name, List *parameters);
-extern void DefineAggregate(char *name, List *parameters);
-extern void DefineType(char *name, List *parameters);
-extern void CreateFunction(ProcedureStmt *stmt, CommandDest dest);
+extern void CreateFunction(ProcedureStmt * stmt, CommandDest dest);
+extern void DefineOperator(char *name, List * parameters);
+extern void DefineAggregate(char *name, List * parameters);
+extern void DefineType(char *name, List * parameters);
+extern void CreateFunction(ProcedureStmt * stmt, CommandDest dest);
/*
* prototypes in remove.c
*/
-extern void RemoveFunction(char *functionName, int nargs, List *argNameList);
-extern void RemoveOperator(char *operatorName,
+extern void RemoveFunction(char *functionName, int nargs, List * argNameList);
+extern void
+RemoveOperator(char *operatorName,
char *typeName1, char *typeName2);
-extern void RemoveType(char *typeName);
-extern void RemoveAggregate(char *aggName, char *aggType);
+extern void RemoveType(char *typeName);
+extern void RemoveAggregate(char *aggName, char *aggType);
-#endif /* DEFREM_H */
+#endif /* DEFREM_H */
diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h
index cac3c59999c..f41f4dfa885 100644
--- a/src/include/commands/explain.h
+++ b/src/include/commands/explain.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* explain.h--
- * prototypes for explain.c
+ * prototypes for explain.c
*
* Copyright (c) 1994-5, Regents of the University of California
*
- * $Id: explain.h,v 1.2 1997/01/16 14:56:34 momjian Exp $
+ * $Id: explain.h,v 1.3 1997/09/07 04:57:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef EXPLAIN_H
-#define EXPLAIN_H
+#ifndef EXPLAIN_H
+#define EXPLAIN_H
-extern void ExplainQuery(Query *query, bool verbose, CommandDest dest);
+extern void ExplainQuery(Query * query, bool verbose, CommandDest dest);
-#endif /* EXPLAIN_H*/
+#endif /* EXPLAIN_H */
diff --git a/src/include/commands/purge.h b/src/include/commands/purge.h
index 5f483b26385..7c4d276afdb 100644
--- a/src/include/commands/purge.h
+++ b/src/include/commands/purge.h
@@ -1,20 +1,21 @@
/*-------------------------------------------------------------------------
*
* purge.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: purge.h,v 1.1 1996/08/28 07:21:48 scrappy Exp $
+ * $Id: purge.h,v 1.2 1997/09/07 04:57:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef PURGE_H
-#define PURGE_H
+#ifndef PURGE_H
+#define PURGE_H
-extern int32 RelationPurge(char *relationName,
- char *absoluteTimeString,
- char *relativeTimeString);
+extern int32
+RelationPurge(char *relationName,
+ char *absoluteTimeString,
+ char *relativeTimeString);
-#endif /* PURGE_H */
+#endif /* PURGE_H */
diff --git a/src/include/commands/recipe.h b/src/include/commands/recipe.h
index 3c8615abb9c..82a3e01cae0 100644
--- a/src/include/commands/recipe.h
+++ b/src/include/commands/recipe.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* recipe.h--
- * recipe handling routines
+ * recipe handling routines
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: recipe.h,v 1.1 1996/08/28 07:21:50 scrappy Exp $
+ * $Id: recipe.h,v 1.2 1997/09/07 04:57:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef RECIPE_H
#define RECIPE_H
-extern void beginRecipe(RecipeStmt* stmt);
+extern void beginRecipe(RecipeStmt * stmt);
-#endif /* RECIPE_H */
+#endif /* RECIPE_H */
diff --git a/src/include/commands/rename.h b/src/include/commands/rename.h
index f559a5c76ee..3675011dbd6 100644
--- a/src/include/commands/rename.h
+++ b/src/include/commands/rename.h
@@ -1,24 +1,26 @@
/*-------------------------------------------------------------------------
*
* rename.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rename.h,v 1.1 1996/08/28 07:21:51 scrappy Exp $
+ * $Id: rename.h,v 1.2 1997/09/07 04:57:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef RENAME_H
-#define RENAME_H
+#ifndef RENAME_H
+#define RENAME_H
-extern void renameatt(char *relname,
- char *oldattname,
- char *newattname,
- char *userName, int recurse);
+extern void
+renameatt(char *relname,
+ char *oldattname,
+ char *newattname,
+ char *userName, int recurse);
-extern void renamerel(char *oldrelname,
- char *newrelname);
+extern void
+renamerel(char *oldrelname,
+ char *newrelname);
-#endif /* RENAME_H */
+#endif /* RENAME_H */
diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h
index 4e341e9277d..88497253b32 100644
--- a/src/include/commands/sequence.h
+++ b/src/include/commands/sequence.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* sequence.h--
- * prototypes for sequence.c.
+ * prototypes for sequence.c.
*
*
*-------------------------------------------------------------------------
@@ -9,25 +9,25 @@
#ifndef SEQUENCE_H
#define SEQUENCE_H
-/*
+/*
* Columns of a sequnece relation
*/
-
-#define SEQ_COL_NAME 1
-#define SEQ_COL_LASTVAL 2
-#define SEQ_COL_INCBY 3
-#define SEQ_COL_MAXVALUE 4
-#define SEQ_COL_MINVALUE 5
-#define SEQ_COL_CACHE 6
-#define SEQ_COL_CYCLE 7
-#define SEQ_COL_CALLED 8
-#define SEQ_COL_FIRSTCOL SEQ_COL_NAME
-#define SEQ_COL_LASTCOL SEQ_COL_CALLED
+#define SEQ_COL_NAME 1
+#define SEQ_COL_LASTVAL 2
+#define SEQ_COL_INCBY 3
+#define SEQ_COL_MAXVALUE 4
+#define SEQ_COL_MINVALUE 5
+#define SEQ_COL_CACHE 6
+#define SEQ_COL_CYCLE 7
+#define SEQ_COL_CALLED 8
-extern void DefineSequence (CreateSeqStmt *stmt);
-extern int4 nextval (struct varlena *seqname);
-extern int4 currval (struct varlena *seqname);
-extern void CloseSequences (void);
+#define SEQ_COL_FIRSTCOL SEQ_COL_NAME
+#define SEQ_COL_LASTCOL SEQ_COL_CALLED
-#endif /* SEQUENCE_H */
+extern void DefineSequence(CreateSeqStmt * stmt);
+extern int4 nextval(struct varlena * seqname);
+extern int4 currval(struct varlena * seqname);
+extern void CloseSequences(void);
+
+#endif /* SEQUENCE_H */
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index 8cbfe0c5a1b..0f125a0de6a 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* trigger.h--
- * prototypes for trigger.c.
+ * prototypes for trigger.c.
*
*
*-------------------------------------------------------------------------
@@ -13,59 +13,60 @@
#include "access/htup.h"
#include "utils/rel.h"
-typedef uint32 TriggerEvent;
+typedef uint32 TriggerEvent;
-typedef struct TriggerData {
- TriggerEvent tg_event;
- Relation tg_relation;
- HeapTuple tg_trigtuple;
- HeapTuple tg_newtuple;
- Trigger *tg_trigger;
-} TriggerData;
+typedef struct TriggerData
+{
+ TriggerEvent tg_event;
+ Relation tg_relation;
+ HeapTuple tg_trigtuple;
+ HeapTuple tg_newtuple;
+ Trigger *tg_trigger;
+} TriggerData;
extern TriggerData *CurrentTriggerData;
-#define TRIGGER_EVENT_INSERT 0x00000000
-#define TRIGGER_EVENT_DELETE 0x00000001
-#define TRIGGER_EVENT_UPDATE 0x00000002
-#define TRIGGER_EVENT_OPMASK 0x00000003
-#define TRIGGER_EVENT_ROW 0x00000004
-#define TRIGGER_EVENT_BEFORE 0x00000008
+#define TRIGGER_EVENT_INSERT 0x00000000
+#define TRIGGER_EVENT_DELETE 0x00000001
+#define TRIGGER_EVENT_UPDATE 0x00000002
+#define TRIGGER_EVENT_OPMASK 0x00000003
+#define TRIGGER_EVENT_ROW 0x00000004
+#define TRIGGER_EVENT_BEFORE 0x00000008
#define TRIGGER_FIRED_BY_INSERT(event) \
- (((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \
- TRIGGER_EVENT_INSERT)
+ (((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \
+ TRIGGER_EVENT_INSERT)
#define TRIGGER_FIRED_BY_DELETE(event) \
- (((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \
- TRIGGER_EVENT_DELETE)
+ (((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \
+ TRIGGER_EVENT_DELETE)
#define TRIGGER_FIRED_BY_UPDATE(event) \
- (((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \
- TRIGGER_EVENT_UPDATE)
+ (((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \
+ TRIGGER_EVENT_UPDATE)
-#define TRIGGER_FIRED_FOR_ROW(event) \
- ((TriggerEvent) (event) & TRIGGER_EVENT_ROW)
+#define TRIGGER_FIRED_FOR_ROW(event) \
+ ((TriggerEvent) (event) & TRIGGER_EVENT_ROW)
-#define TRIGGER_FIRED_FOR_STATEMENT(event) \
- (!TRIGGER_FIRED_FOR_ROW (event))
+#define TRIGGER_FIRED_FOR_STATEMENT(event) \
+ (!TRIGGER_FIRED_FOR_ROW (event))
-#define TRIGGER_FIRED_BEFORE(event) \
- ((TriggerEvent) (event) & TRIGGER_EVENT_BEFORE)
+#define TRIGGER_FIRED_BEFORE(event) \
+ ((TriggerEvent) (event) & TRIGGER_EVENT_BEFORE)
-#define TRIGGER_FIRED_AFTER(event) \
- (!TRIGGER_FIRED_BEFORE (event))
+#define TRIGGER_FIRED_AFTER(event) \
+ (!TRIGGER_FIRED_BEFORE (event))
-extern void CreateTrigger (CreateTrigStmt *stmt);
-extern void DropTrigger (DropTrigStmt *stmt);
-extern void RelationRemoveTriggers (Relation rel);
+extern void CreateTrigger(CreateTrigStmt * stmt);
+extern void DropTrigger(DropTrigStmt * stmt);
+extern void RelationRemoveTriggers(Relation rel);
-extern HeapTuple ExecBRInsertTriggers (Relation rel, HeapTuple tuple);
-extern void ExecARInsertTriggers (Relation rel, HeapTuple tuple);
-extern bool ExecBRDeleteTriggers (Relation rel, ItemPointer tupleid);
-extern void ExecARDeleteTriggers (Relation rel, ItemPointer tupleid);
-extern HeapTuple ExecBRUpdateTriggers (Relation rel, ItemPointer tupleid, HeapTuple tuple);
-extern void ExecARUpdateTriggers (Relation rel, ItemPointer tupleid, HeapTuple tuple);
+extern HeapTuple ExecBRInsertTriggers(Relation rel, HeapTuple tuple);
+extern void ExecARInsertTriggers(Relation rel, HeapTuple tuple);
+extern bool ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid);
+extern void ExecARDeleteTriggers(Relation rel, ItemPointer tupleid);
+extern HeapTuple ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple);
+extern void ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple);
-#endif /* TRIGGER_H */
+#endif /* TRIGGER_H */
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 6ed66f6bc81..59863f2d574 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -1,87 +1,110 @@
/*-------------------------------------------------------------------------
*
* vacuum.h--
- * header file for postgres vacuum cleaner
+ * header file for postgres vacuum cleaner
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: vacuum.h,v 1.7 1997/04/23 06:28:48 vadim Exp $
+ * $Id: vacuum.h,v 1.8 1997/09/07 04:57:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef VACUUM_H
-#define VACUUM_H
+#ifndef VACUUM_H
+#define VACUUM_H
#include <access/funcindex.h>
#include <catalog/pg_index.h>
-typedef struct VAttListData {
- int val_dummy;
- struct VAttListData *val_next;
-} VAttListData;
-
-typedef VAttListData *VAttList;
-
-typedef struct VPageDescrData {
- BlockNumber vpd_blkno; /* BlockNumber of this Page */
- Size vpd_free; /* FreeSpace on this Page */
- uint16 vpd_nusd; /* Number of OffNums used by vacuum */
- uint16 vpd_noff; /* Number of OffNums free or to be free */
- OffsetNumber vpd_voff[1]; /* Array of its OffNums */
-} VPageDescrData;
-
-typedef VPageDescrData *VPageDescr;
-
-typedef struct VPageListData {
- int vpl_nemend; /* Number of "empty" end-pages */
- int vpl_npages; /* Number of pages in vpl_pgdesc */
- VPageDescr *vpl_pgdesc; /* Descriptions of pages */
-} VPageListData;
-
-typedef VPageListData *VPageList;
-
-typedef struct {
- FuncIndexInfo finfo;
- FuncIndexInfo *finfoP;
- IndexTupleForm tform;
- int natts;
-} IndDesc;
-
-typedef struct {
- AttributeTupleForm attr;
- Datum best, guess1, guess2, max, min;
- int16 best_len, guess1_len, guess2_len, max_len, min_len;
- int32 best_cnt, guess1_cnt, guess1_hits, guess2_hits, null_cnt,nonnull_cnt;
- int32 max_cnt, min_cnt;
- func_ptr f_cmpeq, f_cmplt, f_cmpgt;
- regproc outfunc;
- bool initialized;
-} VacAttrStats;
-
-typedef struct VRelListData {
- Oid vrl_relid;
- struct VRelListData *vrl_next;
-} VRelListData;
-
-typedef VRelListData *VRelList;
-
-typedef struct VRelStats {
- Oid relid;
- int ntups;
- int npages;
- Size min_tlen;
- Size max_tlen;
- bool hasindex;
- int va_natts; /* number of attrs being analyzed */
- VacAttrStats *vacattrstats;
-} VRelStats;
-
-extern bool VacuumRunning;
-
-extern void vc_abort(void);
-extern void vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec);
-
-#define ATTNVALS_SCALE 1000000000 /* XXX so it can act as a float4 */
-
-#endif /* VACUUM_H */
+typedef struct VAttListData
+{
+ int val_dummy;
+ struct VAttListData *val_next;
+} VAttListData;
+
+typedef VAttListData *VAttList;
+
+typedef struct VPageDescrData
+{
+ BlockNumber vpd_blkno; /* BlockNumber of this Page */
+ Size vpd_free; /* FreeSpace on this Page */
+ uint16 vpd_nusd; /* Number of OffNums used by vacuum */
+ uint16 vpd_noff; /* Number of OffNums free or to be free */
+ OffsetNumber vpd_voff[1];/* Array of its OffNums */
+} VPageDescrData;
+
+typedef VPageDescrData *VPageDescr;
+
+typedef struct VPageListData
+{
+ int vpl_nemend; /* Number of "empty" end-pages */
+ int vpl_npages; /* Number of pages in vpl_pgdesc */
+ VPageDescr *vpl_pgdesc; /* Descriptions of pages */
+} VPageListData;
+
+typedef VPageListData *VPageList;
+
+typedef struct
+{
+ FuncIndexInfo finfo;
+ FuncIndexInfo *finfoP;
+ IndexTupleForm tform;
+ int natts;
+} IndDesc;
+
+typedef struct
+{
+ AttributeTupleForm attr;
+ Datum best,
+ guess1,
+ guess2,
+ max,
+ min;
+ int16 best_len,
+ guess1_len,
+ guess2_len,
+ max_len,
+ min_len;
+ int32 best_cnt,
+ guess1_cnt,
+ guess1_hits,
+ guess2_hits,
+ null_cnt,
+ nonnull_cnt;
+ int32 max_cnt,
+ min_cnt;
+ func_ptr f_cmpeq,
+ f_cmplt,
+ f_cmpgt;
+ regproc outfunc;
+ bool initialized;
+} VacAttrStats;
+
+typedef struct VRelListData
+{
+ Oid vrl_relid;
+ struct VRelListData *vrl_next;
+} VRelListData;
+
+typedef VRelListData *VRelList;
+
+typedef struct VRelStats
+{
+ Oid relid;
+ int ntups;
+ int npages;
+ Size min_tlen;
+ Size max_tlen;
+ bool hasindex;
+ int va_natts; /* number of attrs being analyzed */
+ VacAttrStats *vacattrstats;
+} VRelStats;
+
+extern bool VacuumRunning;
+
+extern void vc_abort(void);
+extern void vacuum(char *vacrel, bool verbose, bool analyze, List * va_spec);
+
+#define ATTNVALS_SCALE 1000000000 /* XXX so it can act as a float4 */
+
+#endif /* VACUUM_H */
diff --git a/src/include/commands/version.h b/src/include/commands/version.h
index 1b3e5169d99..7365a829629 100644
--- a/src/include/commands/version.h
+++ b/src/include/commands/version.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* version.h--
- * Header file for versions.
+ * Header file for versions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: version.h,v 1.4 1997/08/19 21:38:10 momjian Exp $
+ * $Id: version.h,v 1.5 1997/09/07 04:57:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef VERSION_H
#define VERSION_H
-
-#endif /* VERSION_H */
+
+#endif /* VERSION_H */
diff --git a/src/include/commands/view.h b/src/include/commands/view.h
index da37d3fe2b9..2e46fb6f4df 100644
--- a/src/include/commands/view.h
+++ b/src/include/commands/view.h
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* view.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: view.h,v 1.1 1996/08/28 07:21:54 scrappy Exp $
+ * $Id: view.h,v 1.2 1997/09/07 04:57:40 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef VIEW_H
-#define VIEW_H
+#ifndef VIEW_H
+#define VIEW_H
-extern char *MakeRetrieveViewRuleName(char *view_name);
-extern void DefineView(char *view_name, Query *view_parse);
-extern void RemoveView(char *view_name);
+extern char *MakeRetrieveViewRuleName(char *view_name);
+extern void DefineView(char *view_name, Query * view_parse);
+extern void RemoveView(char *view_name);
-#endif /* VIEW_H */
+#endif /* VIEW_H */
diff --git a/src/include/executor/execFlatten.h b/src/include/executor/execFlatten.h
index 6a7f26a729b..d51864edf0e 100644
--- a/src/include/executor/execFlatten.h
+++ b/src/include/executor/execFlatten.h
@@ -1,24 +1,21 @@
/*-------------------------------------------------------------------------
*
* execFlatten.h--
- * prototypes for execFlatten.c.
+ * prototypes for execFlatten.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: execFlatten.h,v 1.2 1997/08/19 21:38:12 momjian Exp $
+ * $Id: execFlatten.h,v 1.3 1997/09/07 04:57:41 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef EXECFLATTEN_H
#define EXECFLATTEN_H
-extern Datum ExecEvalIter(Iter *iterNode, ExprContext *econtext, bool *resultIsNull, bool *iterIsDone);
-
-extern void ExecEvalFjoin(TargetEntry *tlist, ExprContext *econtext, bool *isNullVect, bool *fj_isDone);
-
-
-#endif /* EXECFLATTEN_H */
+extern Datum ExecEvalIter(Iter * iterNode, ExprContext * econtext, bool * resultIsNull, bool * iterIsDone);
+extern void ExecEvalFjoin(TargetEntry * tlist, ExprContext * econtext, bool * isNullVect, bool * fj_isDone);
+#endif /* EXECFLATTEN_H */
diff --git a/src/include/executor/execdebug.h b/src/include/executor/execdebug.h
index 3a47ef01aa1..61d298403b3 100644
--- a/src/include/executor/execdebug.h
+++ b/src/include/executor/execdebug.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* execdebug.h--
- * #defines governing debugging behaviour in the executor
+ * #defines governing debugging behaviour in the executor
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: execdebug.h,v 1.2 1996/11/08 00:46:14 scrappy Exp $
+ * $Id: execdebug.h,v 1.3 1997/09/07 04:57:44 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,368 +16,368 @@
#include "access/printtup.h"
/* ----------------------------------------------------------------
- * debugging defines.
+ * debugging defines.
*
- * If you want certain debugging behaviour, then #define
- * the variable to 1, else #undef it. -cim 10/26/89
+ * If you want certain debugging behaviour, then #define
+ * the variable to 1, else #undef it. -cim 10/26/89
* ----------------------------------------------------------------
*/
/* ----------------
- * EXEC_DEBUGSTORETUP is for tuple table debugging - this
- * will print a message every time we call ExecStoreTuple.
- * -cim 3/20/91
+ * EXEC_DEBUGSTORETUP is for tuple table debugging - this
+ * will print a message every time we call ExecStoreTuple.
+ * -cim 3/20/91
* ----------------
*/
#undef EXEC_DEBUGSTORETUP
/* ----------------
- * EXEC_TUPLECOUNT is a #define which causes the
- * executor keep track of tuple counts. This might be
- * causing some problems with the decstation stuff so
- * you might want to undefine this if you are doing work
- * on the decs - cim 10/20/89
+ * EXEC_TUPLECOUNT is a #define which causes the
+ * executor keep track of tuple counts. This might be
+ * causing some problems with the decstation stuff so
+ * you might want to undefine this if you are doing work
+ * on the decs - cim 10/20/89
* ----------------
*/
#undef EXEC_TUPLECOUNT
/* ----------------
- * EXEC_SHOWBUFSTATS controls whether or not buffer statistics
- * are shown for each query. -cim 2/9/89
+ * EXEC_SHOWBUFSTATS controls whether or not buffer statistics
+ * are shown for each query. -cim 2/9/89
* ----------------
*/
#undef EXEC_SHOWBUFSTATS
/* ----------------
- * EXEC_CONTEXTDEBUG turns on the printing of debugging information
- * by CXT_printf() calls regarding which memory context is the
- * CurrentMemoryContext for palloc() calls.
+ * EXEC_CONTEXTDEBUG turns on the printing of debugging information
+ * by CXT_printf() calls regarding which memory context is the
+ * CurrentMemoryContext for palloc() calls.
* ----------------
*/
#undef EXEC_CONTEXTDEBUG
/* ----------------
- * EXEC_RETURNSIZE is a compile flag governing the
- * behaviour of lispFmgr.. See ExecMakeFunctionResult().
- * Undefining this avoids a problem in the system cache.
+ * EXEC_RETURNSIZE is a compile flag governing the
+ * behaviour of lispFmgr.. See ExecMakeFunctionResult().
+ * Undefining this avoids a problem in the system cache.
*
- * Note: undefining this means that there is incorrect
- * information in the const nodes corresponding
- * to function (or operator) results. The thing is,
- * 99% of the time this is fine because when you do
- * something like x = emp.sal + 1, you already know
- * the type and size of x so the fact that + didn't
- * return the correct size doesn't matter.
- * With variable length stuff the size is stored in
- * the first few bytes of the data so again, it's
- * not likely to matter.
+ * Note: undefining this means that there is incorrect
+ * information in the const nodes corresponding
+ * to function (or operator) results. The thing is,
+ * 99% of the time this is fine because when you do
+ * something like x = emp.sal + 1, you already know
+ * the type and size of x so the fact that + didn't
+ * return the correct size doesn't matter.
+ * With variable length stuff the size is stored in
+ * the first few bytes of the data so again, it's
+ * not likely to matter.
* ----------------
*/
#undef EXEC_RETURNSIZE
/* ----------------
- * EXEC_UTILSDEBUG is a flag which turns on debugging of the
- * executor utilities by EU_printf() in eutils.c
+ * EXEC_UTILSDEBUG is a flag which turns on debugging of the
+ * executor utilities by EU_printf() in eutils.c
* ----------------
*/
#undef EXEC_UTILSDEBUG
/* ----------------
- * EXEC_NESTLOOPDEBUG is a flag which turns on debugging of the
- * nest loop node by NL_printf() and ENL_printf() in nestloop.c
+ * EXEC_NESTLOOPDEBUG is a flag which turns on debugging of the
+ * nest loop node by NL_printf() and ENL_printf() in nestloop.c
* ----------------
*/
#undef EXEC_NESTLOOPDEBUG
/* ----------------
- * EXEC_PROCDEBUG is a flag which turns on debugging of
- * ExecProcNode() by PN_printf() in procnode.c
+ * EXEC_PROCDEBUG is a flag which turns on debugging of
+ * ExecProcNode() by PN_printf() in procnode.c
* ----------------
*/
#undef EXEC_PROCDEBUG
/* ----------------
- * EXEC_EVALDEBUG is a flag which turns on debugging of
- * ExecEval and ExecTargetList() stuff by EV_printf() in qual.c
+ * EXEC_EVALDEBUG is a flag which turns on debugging of
+ * ExecEval and ExecTargetList() stuff by EV_printf() in qual.c
* ----------------
*/
#undef EXEC_EVALDEBUG
/* ----------------
- * EXEC_SCANDEBUG is a flag which turns on debugging of
- * the ExecSeqScan() stuff by S_printf() in seqscan.c
+ * EXEC_SCANDEBUG is a flag which turns on debugging of
+ * the ExecSeqScan() stuff by S_printf() in seqscan.c
* ----------------
*/
#undef EXEC_SCANDEBUG
/* ----------------
- * EXEC_SORTDEBUG is a flag which turns on debugging of
- * the ExecSort() stuff by SO_printf() in sort.c
+ * EXEC_SORTDEBUG is a flag which turns on debugging of
+ * the ExecSort() stuff by SO_printf() in sort.c
* ----------------
*/
#undef EXEC_SORTDEBUG
/* ----------------
- * EXEC_MERGEJOINDEBUG is a flag which turns on debugging of
- * the ExecMergeJoin() stuff by MJ_printf() in mergejoin.c
+ * EXEC_MERGEJOINDEBUG is a flag which turns on debugging of
+ * the ExecMergeJoin() stuff by MJ_printf() in mergejoin.c
* ----------------
*/
#undef EXEC_MERGEJOINDEBUG
/* ----------------
- * EXEC_MERGEJOINPFREE is a flag which causes merge joins
- * to pfree intermittant tuples (which is the proper thing)
- * Not defining this means we avoid menory management problems
- * at the cost of doing deallocation of stuff only at the
- * end of the transaction
+ * EXEC_MERGEJOINPFREE is a flag which causes merge joins
+ * to pfree intermittant tuples (which is the proper thing)
+ * Not defining this means we avoid menory management problems
+ * at the cost of doing deallocation of stuff only at the
+ * end of the transaction
* ----------------
*/
#undef EXEC_MERGEJOINPFREE
/* ----------------
- * EXEC_DEBUGINTERACTIVE is a flag which enables the
- * user to issue "DEBUG" commands from an interactive
- * backend.
+ * EXEC_DEBUGINTERACTIVE is a flag which enables the
+ * user to issue "DEBUG" commands from an interactive
+ * backend.
* ----------------
*/
#undef EXEC_DEBUGINTERACTIVE
/* ----------------
- * EXEC_DEBUGVARIABLEFILE is string, which if defined will
- * be loaded when the executor is initialized. If this
- * string is not defined then nothing will be loaded..
+ * EXEC_DEBUGVARIABLEFILE is string, which if defined will
+ * be loaded when the executor is initialized. If this
+ * string is not defined then nothing will be loaded..
*
- * Example:
+ * Example:
*
* #define EXEC_DEBUGVARIABLEFILE "/a/postgres/cimarron/.pg_debugvars"
#
- * Note: since these variables are read at execution time,
- * they can't affect the first query.. this hack should be
- * replaced by something better sometime. -cim 11/2/89
+ * Note: since these variables are read at execution time,
+ * they can't affect the first query.. this hack should be
+ * replaced by something better sometime. -cim 11/2/89
* ----------------
*/
#undef EXEC_DEBUGVARIABLEFILE
/* ----------------------------------------------------------------
- * #defines controlled by above definitions
+ * #defines controlled by above definitions
*
- * Note: most of these are "incomplete" because I didn't
- * need the ones not defined. More should be added
- * only as necessary -cim 10/26/89
+ * Note: most of these are "incomplete" because I didn't
+ * need the ones not defined. More should be added
+ * only as necessary -cim 10/26/89
* ----------------------------------------------------------------
*/
-#define T_OR_F(b) (b ? "true" : "false")
-#define NULL_OR_TUPLE(slot) (TupIsNull(slot) ? "null" : "a tuple")
+#define T_OR_F(b) (b ? "true" : "false")
+#define NULL_OR_TUPLE(slot) (TupIsNull(slot) ? "null" : "a tuple")
/* #define EXEC_TUPLECOUNT - XXX take out for now for executor stubbing -- jolly*/
/* ----------------
- * tuple count debugging defines
+ * tuple count debugging defines
* ----------------
*/
#ifdef EXEC_TUPLECOUNT
-extern int NTupleProcessed;
-extern int NTupleRetrieved;
-extern int NTupleReplaced;
-extern int NTupleAppended;
-extern int NTupleDeleted;
-extern int NIndexTupleProcessed;
-extern int NIndexTupleInserted;
-
-#define IncrRetrieved() NTupleRetrieved++
-#define IncrAppended() NTupleAppended++
-#define IncrDeleted() NTupleDeleted++
-#define IncrReplaced() NTupleReplaced++
-#define IncrInserted() NTupleInserted++
-#define IncrProcessed() NTupleProcessed++
+extern int NTupleProcessed;
+extern int NTupleRetrieved;
+extern int NTupleReplaced;
+extern int NTupleAppended;
+extern int NTupleDeleted;
+extern int NIndexTupleProcessed;
+extern int NIndexTupleInserted;
+
+#define IncrRetrieved() NTupleRetrieved++
+#define IncrAppended() NTupleAppended++
+#define IncrDeleted() NTupleDeleted++
+#define IncrReplaced() NTupleReplaced++
+#define IncrInserted() NTupleInserted++
+#define IncrProcessed() NTupleProcessed++
#define IncrIndexProcessed() NIndexTupleProcessed++
-#define IncrIndexInserted() NIndexTupleInserted++
+#define IncrIndexInserted() NIndexTupleInserted++
#else
#define IncrRetrieved()
-#define IncrAppended()
-#define IncrDeleted()
-#define IncrReplaced()
-#define IncrInserted()
+#define IncrAppended()
+#define IncrDeleted()
+#define IncrReplaced()
+#define IncrInserted()
#define IncrProcessed()
#define IncrIndexProcessed()
#define IncrIndexInserted()
-#endif /* EXEC_TUPLECOUNT */
+#endif /* EXEC_TUPLECOUNT */
/* ----------------
- * memory context debugging defines
+ * memory context debugging defines
* ----------------
*/
#ifdef EXEC_CONTEXTDEBUG
-#define CXT_printf(s) printf(s)
-#define CXT1_printf(s, a) printf(s, a)
+#define CXT_printf(s) printf(s)
+#define CXT1_printf(s, a) printf(s, a)
#else
-#define CXT_printf(s)
-#define CXT1_printf(s, a)
-#endif /* EXEC_CONTEXTDEBUG */
+#define CXT_printf(s)
+#define CXT1_printf(s, a)
+#endif /* EXEC_CONTEXTDEBUG */
/* ----------------
- * eutils debugging defines
+ * eutils debugging defines
* ----------------
*/
#ifdef EXEC_UTILSDEBUG
-#define EU_nodeDisplay(l) nodeDisplay(l, 0)
-#define EU_printf(s) printf(s)
-#define EU1_printf(s, a) printf(s, a)
-#define EU2_printf(s, a) printf(s, a, b)
-#define EU3_printf(s, a) printf(s, a, b, c)
-#define EU4_printf(s, a, b, c, d) printf(s, a, b, c, d)
+#define EU_nodeDisplay(l) nodeDisplay(l, 0)
+#define EU_printf(s) printf(s)
+#define EU1_printf(s, a) printf(s, a)
+#define EU2_printf(s, a) printf(s, a, b)
+#define EU3_printf(s, a) printf(s, a, b, c)
+#define EU4_printf(s, a, b, c, d) printf(s, a, b, c, d)
#else
-#define EU_nodeDisplay(l)
-#define EU_printf(s)
-#define EU1_printf(s, a)
+#define EU_nodeDisplay(l)
+#define EU_printf(s)
+#define EU1_printf(s, a)
#define EU2_printf(s, a, b)
#define EU3_printf(s, a, b, c)
-#define EU4_printf(s, a, b, c, d)
-#endif /* EXEC_UTILSDEBUG */
+#define EU4_printf(s, a, b, c, d)
+#endif /* EXEC_UTILSDEBUG */
/* ----------------
- * nest loop debugging defines
+ * nest loop debugging defines
* ----------------
*/
#ifdef EXEC_NESTLOOPDEBUG
-#define NL_nodeDisplay(l) nodeDisplay(l, 0)
-#define NL_printf(s) printf(s)
-#define NL1_printf(s, a) printf(s, a)
-#define NL4_printf(s, a, b, c, d) printf(s, a, b, c, d)
-#define ENL1_printf(message) printf("ExecNestLoop: %s\n", message)
+#define NL_nodeDisplay(l) nodeDisplay(l, 0)
+#define NL_printf(s) printf(s)
+#define NL1_printf(s, a) printf(s, a)
+#define NL4_printf(s, a, b, c, d) printf(s, a, b, c, d)
+#define ENL1_printf(message) printf("ExecNestLoop: %s\n", message)
#else
-#define NL_nodeDisplay(l)
-#define NL_printf(s)
-#define NL1_printf(s, a)
-#define NL4_printf(s, a, b, c, d)
+#define NL_nodeDisplay(l)
+#define NL_printf(s)
+#define NL1_printf(s, a)
+#define NL4_printf(s, a, b, c, d)
#define ENL1_printf(message)
-#endif /* EXEC_NESTLOOPDEBUG */
+#endif /* EXEC_NESTLOOPDEBUG */
/* ----------------
- * proc node debugging defines
+ * proc node debugging defines
* ----------------
*/
#ifdef EXEC_PROCDEBUG
-#define PN_printf(s) printf(s)
-#define PN1_printf(s, p) printf(s, p)
+#define PN_printf(s) printf(s)
+#define PN1_printf(s, p) printf(s, p)
#else
-#define PN_printf(s)
-#define PN1_printf(s, p)
-#endif /* EXEC_PROCDEBUG */
+#define PN_printf(s)
+#define PN1_printf(s, p)
+#endif /* EXEC_PROCDEBUG */
/* ----------------
- * exec eval / target list debugging defines
+ * exec eval / target list debugging defines
* ----------------
*/
#ifdef EXEC_EVALDEBUG
-#define EV_nodeDisplay(l) nodeDisplay(l, 0)
-#define EV_printf(s) printf(s)
-#define EV1_printf(s, a) printf(s, a)
+#define EV_nodeDisplay(l) nodeDisplay(l, 0)
+#define EV_printf(s) printf(s)
+#define EV1_printf(s, a) printf(s, a)
#define EV5_printf(s, a, b, c, d, e) printf(s, a, b, c, d, e)
#else
-#define EV_nodeDisplay(l)
-#define EV_printf(s)
-#define EV1_printf(s, a)
-#define EV5_printf(s, a, b, c, d, e)
-#endif /* EXEC_EVALDEBUG */
+#define EV_nodeDisplay(l)
+#define EV_printf(s)
+#define EV1_printf(s, a)
+#define EV5_printf(s, a, b, c, d, e)
+#endif /* EXEC_EVALDEBUG */
/* ----------------
- * scan debugging defines
+ * scan debugging defines
* ----------------
*/
#ifdef EXEC_SCANDEBUG
-#define S_nodeDisplay(l) nodeDisplay(l, 0)
-#define S_printf(s) printf(s)
-#define S1_printf(s, p) printf(s, p)
+#define S_nodeDisplay(l) nodeDisplay(l, 0)
+#define S_printf(s) printf(s)
+#define S1_printf(s, p) printf(s, p)
#else
-#define S_nodeDisplay(l)
-#define S_printf(s)
-#define S1_printf(s, p)
-#endif /* EXEC_SCANDEBUG */
-
+#define S_nodeDisplay(l)
+#define S_printf(s)
+#define S1_printf(s, p)
+#endif /* EXEC_SCANDEBUG */
+
/* ----------------
- * sort node debugging defines
+ * sort node debugging defines
* ----------------
*/
#ifdef EXEC_SORTDEBUG
-#define SO_nodeDisplay(l) nodeDisplay(l, 0)
-#define SO_printf(s) printf(s)
-#define SO1_printf(s, p) printf(s, p)
+#define SO_nodeDisplay(l) nodeDisplay(l, 0)
+#define SO_printf(s) printf(s)
+#define SO1_printf(s, p) printf(s, p)
#else
-#define SO_nodeDisplay(l)
-#define SO_printf(s)
-#define SO1_printf(s, p)
-#endif /* EXEC_SORTDEBUG */
+#define SO_nodeDisplay(l)
+#define SO_printf(s)
+#define SO1_printf(s, p)
+#endif /* EXEC_SORTDEBUG */
/* ----------------
- * merge join debugging defines
+ * merge join debugging defines
* ----------------
*/
#ifdef EXEC_MERGEJOINDEBUG
-#define MJ_nodeDisplay(l) nodeDisplay(l, 0)
-#define MJ_printf(s) printf(s)
-#define MJ1_printf(s, p) printf(s, p)
-#define MJ2_printf(s, p1, p2) printf(s, p1, p2)
-#define MJ_debugtup(tuple, type) debugtup(tuple, type)
-#define MJ_dump(context, state) ExecMergeTupleDump(econtext, state)
+#define MJ_nodeDisplay(l) nodeDisplay(l, 0)
+#define MJ_printf(s) printf(s)
+#define MJ1_printf(s, p) printf(s, p)
+#define MJ2_printf(s, p1, p2) printf(s, p1, p2)
+#define MJ_debugtup(tuple, type) debugtup(tuple, type)
+#define MJ_dump(context, state) ExecMergeTupleDump(econtext, state)
#define MJ_DEBUG_QUAL(clause, res) \
MJ2_printf(" ExecQual(%s, econtext) returns %s\n", \
- CppAsString(clause), T_OR_F(res));
-
+ CppAsString(clause), T_OR_F(res));
+
#define MJ_DEBUG_MERGE_COMPARE(qual, res) \
MJ2_printf(" MergeCompare(mergeclauses, %s, ..) returns %s\n", \
- CppAsString(qual), T_OR_F(res));
+ CppAsString(qual), T_OR_F(res));
#define MJ_DEBUG_PROC_NODE(slot) \
MJ2_printf(" %s = ExecProcNode(innerPlan) returns %s\n", \
- CppAsString(slot), NULL_OR_TUPLE(slot));
+ CppAsString(slot), NULL_OR_TUPLE(slot));
#else
#define MJ_nodeDisplay(l)
-#define MJ_printf(s)
-#define MJ1_printf(s, p)
+#define MJ_printf(s)
+#define MJ1_printf(s, p)
#define MJ2_printf(s, p1, p2)
#define MJ_debugtup(tuple, type)
#define MJ_dump(context, state)
#define MJ_DEBUG_QUAL(clause, res)
#define MJ_DEBUG_MERGE_COMPARE(qual, res)
#define MJ_DEBUG_PROC_NODE(slot)
-#endif /* EXEC_MERGEJOINDEBUG */
+#endif /* EXEC_MERGEJOINDEBUG */
/* ----------------------------------------------------------------
- * DO NOT DEFINE THESE EVER OR YOU WILL BURN!
+ * DO NOT DEFINE THESE EVER OR YOU WILL BURN!
* ----------------------------------------------------------------
*/
/* ----------------
- * DOESNOTWORK is currently placed around memory manager
- * code that is known to cause problems. Code in between
- * is likely not converted and probably won't work anyways.
+ * DOESNOTWORK is currently placed around memory manager
+ * code that is known to cause problems. Code in between
+ * is likely not converted and probably won't work anyways.
* ----------------
*/
#undef DOESNOTWORK
/* ----------------
- * PERHAPSNEVER is placed around the "scan attribute"
- * support code for the rule manager because for now we
- * do things inefficiently. The correct solution to our
- * problem is to add code to the parser/planner to save
- * attribute information for the rule manager rather than
- * have the executor have to grope through the entire plan
- * for it so if we ever decide to make things better,
- * we should probably delete the stuff in between PERHAPSNEVER..
+ * PERHAPSNEVER is placed around the "scan attribute"
+ * support code for the rule manager because for now we
+ * do things inefficiently. The correct solution to our
+ * problem is to add code to the parser/planner to save
+ * attribute information for the rule manager rather than
+ * have the executor have to grope through the entire plan
+ * for it so if we ever decide to make things better,
+ * we should probably delete the stuff in between PERHAPSNEVER..
* ----------------
*/
#undef PERHAPSNEVER
/* ----------------
- * NOTYET is placed around any code not yet implemented
- * in the executor. Only remove these when actually implementing
- * said code.
+ * NOTYET is placed around any code not yet implemented
+ * in the executor. Only remove these when actually implementing
+ * said code.
* ----------------
*/
#undef NOTYET
-extern long NDirectFileRead;
-extern long NDirectFileWrite;
+extern long NDirectFileRead;
+extern long NDirectFileWrite;
-#endif /* ExecDebugIncluded */
+#endif /* ExecDebugIncluded */
diff --git a/src/include/executor/execdefs.h b/src/include/executor/execdefs.h
index 2d6db792d8d..59748cfe9be 100644
--- a/src/include/executor/execdefs.h
+++ b/src/include/executor/execdefs.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* execdefs.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: execdefs.h,v 1.1 1996/08/28 07:22:07 scrappy Exp $
+ * $Id: execdefs.h,v 1.2 1997/09/07 04:57:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,34 +14,34 @@
#define EXECDEFS_H
/* ----------------
- * ExecutePlan() tuplecount definitions
+ * ExecutePlan() tuplecount definitions
* ----------------
*/
-#define ALL_TUPLES 0 /* return all tuples */
-#define ONE_TUPLE 1 /* return only one tuple */
+#define ALL_TUPLES 0 /* return all tuples */
+#define ONE_TUPLE 1 /* return only one tuple */
/* ----------------
- * constants used by ExecMain
+ * constants used by ExecMain
* ----------------
*/
-#define EXEC_RUN 3
-#define EXEC_FOR 4
-#define EXEC_BACK 5
-#define EXEC_RETONE 6
-#define EXEC_RESULT 7
+#define EXEC_RUN 3
+#define EXEC_FOR 4
+#define EXEC_BACK 5
+#define EXEC_RETONE 6
+#define EXEC_RESULT 7
/* ----------------
- * Merge Join states
+ * Merge Join states
* ----------------
*/
-#define EXEC_MJ_INITIALIZE 1
-#define EXEC_MJ_JOINMARK 2
-#define EXEC_MJ_JOINTEST 3
-#define EXEC_MJ_JOINTUPLES 4
-#define EXEC_MJ_NEXTOUTER 5
-#define EXEC_MJ_TESTOUTER 6
-#define EXEC_MJ_NEXTINNER 7
-#define EXEC_MJ_SKIPINNER 8
-#define EXEC_MJ_SKIPOUTER 9
+#define EXEC_MJ_INITIALIZE 1
+#define EXEC_MJ_JOINMARK 2
+#define EXEC_MJ_JOINTEST 3
+#define EXEC_MJ_JOINTUPLES 4
+#define EXEC_MJ_NEXTOUTER 5
+#define EXEC_MJ_TESTOUTER 6
+#define EXEC_MJ_NEXTINNER 7
+#define EXEC_MJ_SKIPINNER 8
+#define EXEC_MJ_SKIPOUTER 9
-#endif /* EXECDEFS_H */
+#endif /* EXECDEFS_H */
diff --git a/src/include/executor/execdesc.h b/src/include/executor/execdesc.h
index 2fb13bb9094..7f24b7630f0 100644
--- a/src/include/executor/execdesc.h
+++ b/src/include/executor/execdesc.h
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* execdesc.h--
- * plan and query descriptor accessor macros used by the executor
- * and related modules.
+ * plan and query descriptor accessor macros used by the executor
+ * and related modules.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: execdesc.h,v 1.3 1996/11/05 08:18:31 scrappy Exp $
+ * $Id: execdesc.h,v 1.4 1997/09/07 04:57:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,20 +19,22 @@
#include <nodes/parsenodes.h>
/* ----------------
- * query descriptor:
- * a QueryDesc encapsulates everything that the executor
- * needs to execute the query
+ * query descriptor:
+ * a QueryDesc encapsulates everything that the executor
+ * needs to execute the query
* ---------------------
*/
-typedef struct QueryDesc {
- CmdType operation; /* CMD_SELECT, CMD_UPDATE, etc. */
- Query *parsetree;
- Plan *plantree;
- CommandDest dest; /* the destination output of the execution */
-} QueryDesc;
+typedef struct QueryDesc
+{
+ CmdType operation; /* CMD_SELECT, CMD_UPDATE, etc. */
+ Query *parsetree;
+ Plan *plantree;
+ CommandDest dest; /* the destination output of the execution */
+} QueryDesc;
/* in pquery.c */
-extern QueryDesc *CreateQueryDesc(Query *parsetree, Plan *plantree,
- CommandDest dest);
+extern QueryDesc *
+CreateQueryDesc(Query * parsetree, Plan * plantree,
+ CommandDest dest);
-#endif /* EXECDESC_H */
+#endif /* EXECDESC_H */
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index ec7e61a523d..c96f7439b6c 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* executor.h--
- * support for the POSTGRES executor module
+ * support for the POSTGRES executor module
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: executor.h,v 1.10 1997/08/22 14:39:33 vadim Exp $
+ * $Id: executor.h,v 1.11 1997/09/07 04:57:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,127 +26,146 @@
/*
* prototypes from functions in execAmi.c
*/
-extern void ExecOpenScanR(Oid relOid, int nkeys, ScanKey skeys, bool isindex,
- ScanDirection dir, TimeQual timeRange,
- Relation *returnRelation, Pointer *returnScanDesc);
-extern void ExecCloseR(Plan *node);
-extern void ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent);
-extern HeapScanDesc ExecReScanR(Relation relDesc, HeapScanDesc scanDesc,
- ScanDirection direction, int nkeys, ScanKey skeys);
-extern void ExecMarkPos(Plan *node);
-extern void ExecRestrPos(Plan *node);
+extern void
+ExecOpenScanR(Oid relOid, int nkeys, ScanKey skeys, bool isindex,
+ ScanDirection dir, TimeQual timeRange,
+ Relation * returnRelation, Pointer * returnScanDesc);
+extern void ExecCloseR(Plan * node);
+extern void ExecReScan(Plan * node, ExprContext * exprCtxt, Plan * parent);
+extern HeapScanDesc
+ExecReScanR(Relation relDesc, HeapScanDesc scanDesc,
+ ScanDirection direction, int nkeys, ScanKey skeys);
+extern void ExecMarkPos(Plan * node);
+extern void ExecRestrPos(Plan * node);
extern Relation ExecCreatR(TupleDesc tupType, Oid relationOid);
/*
* prototypes from functions in execJunk.c
*/
-extern JunkFilter *ExecInitJunkFilter(List *targetList);
-extern bool ExecGetJunkAttribute(JunkFilter *junkfilter, TupleTableSlot *slot,
- char *attrName, Datum *value, bool *isNull);
-extern HeapTuple ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot);
+extern JunkFilter *ExecInitJunkFilter(List * targetList);
+extern bool
+ExecGetJunkAttribute(JunkFilter * junkfilter, TupleTableSlot * slot,
+ char *attrName, Datum * value, bool * isNull);
+extern HeapTuple ExecRemoveJunk(JunkFilter * junkfilter, TupleTableSlot * slot);
/*
* prototypes from functions in execMain.c
*/
-extern TupleDesc ExecutorStart(QueryDesc *queryDesc, EState *estate);
-extern TupleTableSlot* ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count);
-extern void ExecutorEnd(QueryDesc *queryDesc, EState *estate);
-extern HeapTuple ExecConstraints (char *caller, Relation rel, HeapTuple tuple);
+extern TupleDesc ExecutorStart(QueryDesc * queryDesc, EState * estate);
+extern TupleTableSlot *ExecutorRun(QueryDesc * queryDesc, EState * estate, int feature, int count);
+extern void ExecutorEnd(QueryDesc * queryDesc, EState * estate);
+extern HeapTuple ExecConstraints(char *caller, Relation rel, HeapTuple tuple);
/*
* prototypes from functions in execProcnode.c
*/
-extern bool ExecInitNode(Plan *node, EState *estate, Plan *parent);
-extern TupleTableSlot *ExecProcNode(Plan *node, Plan *parent);
-extern int ExecCountSlotsNode(Plan *node);
-extern void ExecEndNode(Plan *node, Plan *parent);
+extern bool ExecInitNode(Plan * node, EState * estate, Plan * parent);
+extern TupleTableSlot *ExecProcNode(Plan * node, Plan * parent);
+extern int ExecCountSlotsNode(Plan * node);
+extern void ExecEndNode(Plan * node, Plan * parent);
/*
* prototypes from functions in execQual.c
*/
-extern bool execConstByVal;
-extern int execConstLen;
+extern bool execConstByVal;
+extern int execConstLen;
+
+extern Datum
+ExecExtractResult(TupleTableSlot * slot, AttrNumber attnum,
+ bool * isNull);
+extern Datum
+ExecEvalParam(Param * expression, ExprContext * econtext,
+ bool * isNull);
-extern Datum ExecExtractResult(TupleTableSlot *slot, AttrNumber attnum,
- bool *isNull);
-extern Datum ExecEvalParam(Param *expression, ExprContext *econtext,
- bool *isNull);
/* stop here */
-extern char *GetAttributeByName(TupleTableSlot *slot, char *attname,
- bool *isNull);
-extern Datum ExecEvalExpr(Node *expression, ExprContext *econtext, bool *isNull,
- bool *isDone);
-extern bool ExecQual(List *qual, ExprContext *econtext);
-extern int ExecTargetListLength(List *targetlist);
-extern TupleTableSlot *ExecProject(ProjectionInfo *projInfo, bool *isDone);
+extern char *
+GetAttributeByName(TupleTableSlot * slot, char *attname,
+ bool * isNull);
+extern Datum
+ExecEvalExpr(Node * expression, ExprContext * econtext, bool * isNull,
+ bool * isDone);
+extern bool ExecQual(List * qual, ExprContext * econtext);
+extern int ExecTargetListLength(List * targetlist);
+extern TupleTableSlot *ExecProject(ProjectionInfo * projInfo, bool * isDone);
/*
* prototypes from functions in execScan.c
*/
-extern TupleTableSlot *ExecScan(Scan *node, TupleTableSlot* (*accessMtd)());
+extern TupleTableSlot *ExecScan(Scan * node, TupleTableSlot * (*accessMtd) ());
/*
* prototypes from functions in execTuples.c
*/
extern TupleTable ExecCreateTupleTable(int initialSize);
-extern void ExecDestroyTupleTable(TupleTable table, bool shouldFree);
-extern TupleTableSlot* ExecAllocTableSlot(TupleTable table);
-extern TupleTableSlot* ExecStoreTuple(HeapTuple tuple,
- TupleTableSlot *slot,
- Buffer buffer,
- bool shouldFree);
-extern TupleTableSlot* ExecClearTuple(TupleTableSlot* slot);
-extern bool ExecSetSlotPolicy(TupleTableSlot *slot, bool shouldFree);
-extern TupleDesc ExecSetSlotDescriptor(TupleTableSlot *slot,
- TupleDesc tupdesc);
-extern void ExecSetSlotDescriptorIsNew(TupleTableSlot *slot, bool isNew);
-extern void ExecIncrSlotBufferRefcnt(TupleTableSlot *slot);
-extern bool TupIsNull(TupleTableSlot* slot);
-extern void ExecInitResultTupleSlot(EState *estate, CommonState *commonstate);
-extern void ExecInitScanTupleSlot(EState *estate,
- CommonScanState *commonscanstate);
-extern void ExecInitMarkedTupleSlot(EState *estate, MergeJoinState *mergestate);
-extern void ExecInitOuterTupleSlot(EState *estate, HashJoinState *hashstate);
-
-extern TupleDesc ExecGetTupType(Plan *node);
-extern TupleDesc ExecTypeFromTL(List *targetList);
+extern void ExecDestroyTupleTable(TupleTable table, bool shouldFree);
+extern TupleTableSlot *ExecAllocTableSlot(TupleTable table);
+extern TupleTableSlot *
+ExecStoreTuple(HeapTuple tuple,
+ TupleTableSlot * slot,
+ Buffer buffer,
+ bool shouldFree);
+extern TupleTableSlot *ExecClearTuple(TupleTableSlot * slot);
+extern bool ExecSetSlotPolicy(TupleTableSlot * slot, bool shouldFree);
+extern TupleDesc
+ExecSetSlotDescriptor(TupleTableSlot * slot,
+ TupleDesc tupdesc);
+extern void ExecSetSlotDescriptorIsNew(TupleTableSlot * slot, bool isNew);
+extern void ExecIncrSlotBufferRefcnt(TupleTableSlot * slot);
+extern bool TupIsNull(TupleTableSlot * slot);
+extern void ExecInitResultTupleSlot(EState * estate, CommonState * commonstate);
+extern void
+ExecInitScanTupleSlot(EState * estate,
+ CommonScanState * commonscanstate);
+extern void ExecInitMarkedTupleSlot(EState * estate, MergeJoinState * mergestate);
+extern void ExecInitOuterTupleSlot(EState * estate, HashJoinState * hashstate);
+
+extern TupleDesc ExecGetTupType(Plan * node);
+extern TupleDesc ExecTypeFromTL(List * targetList);
/*
* prototypes from functions in execTuples.c
*/
-extern void ResetTupleCount(void);
-extern void ExecAssignNodeBaseInfo(EState *estate, CommonState *basenode,
- Plan *parent);
-extern void ExecAssignExprContext(EState *estate, CommonState *commonstate);
-extern void ExecAssignResultType(CommonState *commonstate,
- TupleDesc tupDesc);
-extern void ExecAssignResultTypeFromOuterPlan(Plan *node,
- CommonState *commonstate);
-extern void ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate);
-extern TupleDesc ExecGetResultType(CommonState *commonstate);
-extern void ExecAssignProjectionInfo(Plan *node, CommonState *commonstate);
-extern void ExecFreeProjectionInfo(CommonState *commonstate);
-extern TupleDesc ExecGetScanType(CommonScanState *csstate);
-extern void ExecAssignScanType(CommonScanState *csstate,
- TupleDesc tupDesc);
-extern void ExecAssignScanTypeFromOuterPlan(Plan *node,
- CommonScanState *csstate);
+extern void ResetTupleCount(void);
+extern void
+ExecAssignNodeBaseInfo(EState * estate, CommonState * basenode,
+ Plan * parent);
+extern void ExecAssignExprContext(EState * estate, CommonState * commonstate);
+extern void
+ExecAssignResultType(CommonState * commonstate,
+ TupleDesc tupDesc);
+extern void
+ExecAssignResultTypeFromOuterPlan(Plan * node,
+ CommonState * commonstate);
+extern void ExecAssignResultTypeFromTL(Plan * node, CommonState * commonstate);
+extern TupleDesc ExecGetResultType(CommonState * commonstate);
+extern void ExecAssignProjectionInfo(Plan * node, CommonState * commonstate);
+extern void ExecFreeProjectionInfo(CommonState * commonstate);
+extern TupleDesc ExecGetScanType(CommonScanState * csstate);
+extern void
+ExecAssignScanType(CommonScanState * csstate,
+ TupleDesc tupDesc);
+extern void
+ExecAssignScanTypeFromOuterPlan(Plan * node,
+ CommonScanState * csstate);
extern AttributeTupleForm ExecGetTypeInfo(Relation relDesc);
-extern void ExecOpenIndices(Oid resultRelationOid,
- RelationInfo *resultRelationInfo);
-extern void ExecCloseIndices(RelationInfo *resultRelationInfo);
-extern void ExecInsertIndexTuples(TupleTableSlot *slot, ItemPointer tupleid,
- EState *estate, bool is_update);
-extern void resetVarAttrLenForCreateTable(TupleDesc tupType);
-extern void setVarAttrLenForCreateTable(TupleDesc tupType,
- List *targetList, List *rangeTable);
+extern void
+ExecOpenIndices(Oid resultRelationOid,
+ RelationInfo * resultRelationInfo);
+extern void ExecCloseIndices(RelationInfo * resultRelationInfo);
+extern void
+ExecInsertIndexTuples(TupleTableSlot * slot, ItemPointer tupleid,
+ EState * estate, bool is_update);
+extern void resetVarAttrLenForCreateTable(TupleDesc tupType);
+extern void
+setVarAttrLenForCreateTable(TupleDesc tupType,
+ List * targetList, List * rangeTable);
/* ----------------------------------------------------------------
- * the end
+ * the end
* ----------------------------------------------------------------
*/
-#endif /* EXECUTOR_H */
+#endif /* EXECUTOR_H */
diff --git a/src/include/executor/functions.h b/src/include/executor/functions.h
index e404b0cbe42..475f9309b8c 100644
--- a/src/include/executor/functions.h
+++ b/src/include/executor/functions.h
@@ -1,22 +1,24 @@
/*-------------------------------------------------------------------------
*
* functions.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: functions.h,v 1.1 1996/08/28 07:22:12 scrappy Exp $
+ * $Id: functions.h,v 1.2 1997/09/07 04:57:48 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef FUNCTIONS_H
+#ifndef FUNCTIONS_H
#define FUNCTIONS_H
-extern Datum ProjectAttribute(TupleDesc TD, TargetEntry *tlist,
- HeapTuple tup, bool *isnullP);
+extern Datum
+ProjectAttribute(TupleDesc TD, TargetEntry * tlist,
+ HeapTuple tup, bool * isnullP);
-extern Datum postquel_function(Func *funcNode, char **args,
- bool *isNull, bool *isDone);
+extern Datum
+postquel_function(Func * funcNode, char **args,
+ bool * isNull, bool * isDone);
-#endif /* FUNCTIONS_H */
+#endif /* FUNCTIONS_H */
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 6bee61ef766..e705c5c77d6 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -1,81 +1,84 @@
/*-------------------------------------------------------------------------
*
* hashjoin.h--
- * internal structures for hash table and buckets
+ * internal structures for hash table and buckets
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: hashjoin.h,v 1.3 1996/11/04 08:52:46 scrappy Exp $
+ * $Id: hashjoin.h,v 1.4 1997/09/07 04:57:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef HASHJOIN_H
+#ifndef HASHJOIN_H
#define HASHJOIN_H
#include <storage/ipc.h>
/* -----------------
- * have to use relative address as pointers in the hashtable
- * because the hashtable may reallocate in difference processes
+ * have to use relative address as pointers in the hashtable
+ * because the hashtable may reallocate in difference processes
* -----------------
*/
-typedef int RelativeAddr;
+typedef int RelativeAddr;
/* ------------------
- * the relative addresses are always relative to the head of the
- * hashtable, the following macro converts them to absolute address.
+ * the relative addresses are always relative to the head of the
+ * hashtable, the following macro converts them to absolute address.
* ------------------
*/
-#define ABSADDR(X) ((X) < 0 ? NULL: (char*)hashtable + X)
-#define RELADDR(X) (RelativeAddr)((char*)(X) - (char*)hashtable)
+#define ABSADDR(X) ((X) < 0 ? NULL: (char*)hashtable + X)
+#define RELADDR(X) (RelativeAddr)((char*)(X) - (char*)hashtable)
-typedef char **charPP;
-typedef int *intP;
+typedef char **charPP;
+typedef int *intP;
/* ----------------------------------------------------------------
- * hash-join hash table structures
+ * hash-join hash table structures
* ----------------------------------------------------------------
*/
-typedef struct HashTableData {
- int nbuckets;
- int totalbuckets;
- int bucketsize;
- IpcMemoryId shmid;
- RelativeAddr top; /* char* */
- RelativeAddr bottom; /* char* */
- RelativeAddr overflownext; /* char* */
- RelativeAddr batch; /* char* */
- RelativeAddr readbuf; /* char* */
- int nbatch;
- RelativeAddr outerbatchNames; /* RelativeAddr* */
- RelativeAddr outerbatchPos; /* RelativeAddr* */
- RelativeAddr innerbatchNames; /* RelativeAddr* */
- RelativeAddr innerbatchPos; /* RelativeAddr* */
- RelativeAddr innerbatchSizes; /* int* */
- int curbatch;
- int nprocess;
- int pcount;
-} HashTableData; /* real hash table follows here */
+typedef struct HashTableData
+{
+ int nbuckets;
+ int totalbuckets;
+ int bucketsize;
+ IpcMemoryId shmid;
+ RelativeAddr top; /* char* */
+ RelativeAddr bottom; /* char* */
+ RelativeAddr overflownext; /* char* */
+ RelativeAddr batch; /* char* */
+ RelativeAddr readbuf; /* char* */
+ int nbatch;
+ RelativeAddr outerbatchNames; /* RelativeAddr* */
+ RelativeAddr outerbatchPos; /* RelativeAddr* */
+ RelativeAddr innerbatchNames; /* RelativeAddr* */
+ RelativeAddr innerbatchPos; /* RelativeAddr* */
+ RelativeAddr innerbatchSizes; /* int* */
+ int curbatch;
+ int nprocess;
+ int pcount;
+} HashTableData; /* real hash table follows here */
-typedef HashTableData *HashJoinTable;
+typedef HashTableData *HashJoinTable;
-typedef struct OverflowTupleData {
- RelativeAddr tuple; /* HeapTuple */
- RelativeAddr next; /* struct OverflowTupleData * */
-} OverflowTupleData; /* real tuple follows here */
+typedef struct OverflowTupleData
+{
+ RelativeAddr tuple; /* HeapTuple */
+ RelativeAddr next; /* struct OverflowTupleData * */
+} OverflowTupleData; /* real tuple follows here */
typedef OverflowTupleData *OverflowTuple;
-typedef struct HashBucketData {
- RelativeAddr top; /* HeapTuple */
- RelativeAddr bottom; /* HeapTuple */
- RelativeAddr firstotuple; /* OverflowTuple */
- RelativeAddr lastotuple; /* OverflowTuple */
-} HashBucketData; /* real bucket follows here */
+typedef struct HashBucketData
+{
+ RelativeAddr top; /* HeapTuple */
+ RelativeAddr bottom; /* HeapTuple */
+ RelativeAddr firstotuple;/* OverflowTuple */
+ RelativeAddr lastotuple; /* OverflowTuple */
+} HashBucketData; /* real bucket follows here */
-typedef HashBucketData *HashBucket;
+typedef HashBucketData *HashBucket;
-#define HASH_PERMISSION 0700
+#define HASH_PERMISSION 0700
-#endif /* HASHJOIN_H */
+#endif /* HASHJOIN_H */
diff --git a/src/include/executor/nodeAgg.h b/src/include/executor/nodeAgg.h
index 9c46a03e207..bae4f1bc726 100644
--- a/src/include/executor/nodeAgg.h
+++ b/src/include/executor/nodeAgg.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nodeAgg.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeAgg.h,v 1.1 1996/08/28 07:22:14 scrappy Exp $
+ * $Id: nodeAgg.h,v 1.2 1997/09/07 04:57:50 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODEAGG_H
-#define NODEAGG_H
+#ifndef NODEAGG_H
+#define NODEAGG_H
-extern TupleTableSlot *ExecAgg(Agg *node);
-extern bool ExecInitAgg(Agg *node, EState *estate, Plan *parent);
-extern int ExecCountSlotsAgg(Agg *node);
-extern void ExecEndAgg(Agg *node);
+extern TupleTableSlot *ExecAgg(Agg * node);
+extern bool ExecInitAgg(Agg * node, EState * estate, Plan * parent);
+extern int ExecCountSlotsAgg(Agg * node);
+extern void ExecEndAgg(Agg * node);
-#endif /* NODEAGG_H */
+#endif /* NODEAGG_H */
diff --git a/src/include/executor/nodeAppend.h b/src/include/executor/nodeAppend.h
index f2ac25c2aee..2aa98a67c5b 100644
--- a/src/include/executor/nodeAppend.h
+++ b/src/include/executor/nodeAppend.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nodeAppend.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeAppend.h,v 1.2 1997/08/19 21:38:19 momjian Exp $
+ * $Id: nodeAppend.h,v 1.3 1997/09/07 04:57:51 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODEAPPEND_H
-#define NODEAPPEND_H
+#ifndef NODEAPPEND_H
+#define NODEAPPEND_H
-extern bool ExecInitAppend(Append *node, EState *estate, Plan *parent);
-extern int ExecCountSlotsAppend(Append *node);
-extern TupleTableSlot *ExecProcAppend(Append *node);
-extern void ExecEndAppend(Append *node);
+extern bool ExecInitAppend(Append * node, EState * estate, Plan * parent);
+extern int ExecCountSlotsAppend(Append * node);
+extern TupleTableSlot *ExecProcAppend(Append * node);
+extern void ExecEndAppend(Append * node);
-#endif /* NODEAPPEND_H */
+#endif /* NODEAPPEND_H */
diff --git a/src/include/executor/nodeGroup.h b/src/include/executor/nodeGroup.h
index 6a6da53ce8e..ddf32d766a5 100644
--- a/src/include/executor/nodeGroup.h
+++ b/src/include/executor/nodeGroup.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nodeGroup.h--
- * prototypes for nodeGroup.c
+ * prototypes for nodeGroup.c
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeGroup.h,v 1.1 1996/08/28 07:22:17 scrappy Exp $
+ * $Id: nodeGroup.h,v 1.2 1997/09/07 04:57:52 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODEGROUP_H
-#define NODEGROUP_H
+#ifndef NODEGROUP_H
+#define NODEGROUP_H
-extern TupleTableSlot *ExecGroup(Group *node);
-extern bool ExecInitGroup(Group *node, EState *estate, Plan *parent);
-extern int ExecCountSlotsGroup(Group *node);
-extern void ExecEndGroup(Group *node);
+extern TupleTableSlot *ExecGroup(Group * node);
+extern bool ExecInitGroup(Group * node, EState * estate, Plan * parent);
+extern int ExecCountSlotsGroup(Group * node);
+extern void ExecEndGroup(Group * node);
-#endif /* NODEGROUP_H */
+#endif /* NODEGROUP_H */
diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h
index b588b44531b..561e192aaf5 100644
--- a/src/include/executor/nodeHash.h
+++ b/src/include/executor/nodeHash.h
@@ -1,31 +1,34 @@
/*-------------------------------------------------------------------------
*
* nodeHash.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeHash.h,v 1.2 1997/08/19 21:38:20 momjian Exp $
+ * $Id: nodeHash.h,v 1.3 1997/09/07 04:57:52 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODEHASH_H
-#define NODEHASH_H
+#ifndef NODEHASH_H
+#define NODEHASH_H
-extern TupleTableSlot *ExecHash(Hash *node);
-extern bool ExecInitHash(Hash *node, EState *estate, Plan *parent);
-extern int ExecCountSlotsHash(Hash *node);
-extern void ExecEndHash(Hash *node);
-extern HashJoinTable ExecHashTableCreate(Hash *node);
-extern void ExecHashTableInsert(HashJoinTable hashtable, ExprContext *econtext,
- Var *hashkey, File *batches);
-extern void ExecHashTableDestroy(HashJoinTable hashtable);
-extern int ExecHashGetBucket(HashJoinTable hashtable, ExprContext *econtext,
- Var *hashkey);
-extern HeapTuple ExecScanHashBucket(HashJoinState *hjstate, HashBucket bucket,
- HeapTuple curtuple, List *hjclauses,
- ExprContext *econtext);
-extern void ExecHashTableReset(HashJoinTable hashtable, int ntuples);
+extern TupleTableSlot *ExecHash(Hash * node);
+extern bool ExecInitHash(Hash * node, EState * estate, Plan * parent);
+extern int ExecCountSlotsHash(Hash * node);
+extern void ExecEndHash(Hash * node);
+extern HashJoinTable ExecHashTableCreate(Hash * node);
+extern void
+ExecHashTableInsert(HashJoinTable hashtable, ExprContext * econtext,
+ Var * hashkey, File * batches);
+extern void ExecHashTableDestroy(HashJoinTable hashtable);
+extern int
+ExecHashGetBucket(HashJoinTable hashtable, ExprContext * econtext,
+ Var * hashkey);
+extern HeapTuple
+ExecScanHashBucket(HashJoinState * hjstate, HashBucket bucket,
+ HeapTuple curtuple, List * hjclauses,
+ ExprContext * econtext);
+extern void ExecHashTableReset(HashJoinTable hashtable, int ntuples);
-#endif /* NODEHASH_H */
+#endif /* NODEHASH_H */
diff --git a/src/include/executor/nodeHashjoin.h b/src/include/executor/nodeHashjoin.h
index 62f02c976c6..17d88862432 100644
--- a/src/include/executor/nodeHashjoin.h
+++ b/src/include/executor/nodeHashjoin.h
@@ -1,28 +1,29 @@
/*-------------------------------------------------------------------------
*
* nodeHashjoin.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeHashjoin.h,v 1.2 1997/08/19 21:38:22 momjian Exp $
+ * $Id: nodeHashjoin.h,v 1.3 1997/09/07 04:57:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODEHASHJOIN_H
-#define NODEHASHJOIN_H
+#ifndef NODEHASHJOIN_H
+#define NODEHASHJOIN_H
-extern TupleTableSlot *ExecHashJoin(HashJoin *node);
+extern TupleTableSlot *ExecHashJoin(HashJoin * node);
-extern bool ExecInitHashJoin(HashJoin *node, EState *estate, Plan *parent);
+extern bool ExecInitHashJoin(HashJoin * node, EState * estate, Plan * parent);
-extern int ExecCountSlotsHashJoin(HashJoin *node);
+extern int ExecCountSlotsHashJoin(HashJoin * node);
-extern void ExecEndHashJoin(HashJoin *node);
+extern void ExecEndHashJoin(HashJoin * node);
-extern char *ExecHashJoinSaveTuple(HeapTuple heapTuple, char *buffer,
- File file, char *position);
+extern char *
+ExecHashJoinSaveTuple(HeapTuple heapTuple, char *buffer,
+ File file, char *position);
-#endif /* NODEHASHJOIN_H */
+#endif /* NODEHASHJOIN_H */
diff --git a/src/include/executor/nodeIndexscan.h b/src/include/executor/nodeIndexscan.h
index 5e55948ad91..e111f7ed2ee 100644
--- a/src/include/executor/nodeIndexscan.h
+++ b/src/include/executor/nodeIndexscan.h
@@ -1,33 +1,34 @@
/*-------------------------------------------------------------------------
*
* nodeIndexscan.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeIndexscan.h,v 1.2 1996/10/23 07:41:34 scrappy Exp $
+ * $Id: nodeIndexscan.h,v 1.3 1997/09/07 04:57:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODEINDEXSCAN_H
-#define NODEINDEXSCAN_H
+#ifndef NODEINDEXSCAN_H
+#define NODEINDEXSCAN_H
+
+extern TupleTableSlot *ExecIndexScan(IndexScan * node);
-extern TupleTableSlot *ExecIndexScan(IndexScan *node);
+extern void ExecIndexReScan(IndexScan * node, ExprContext * exprCtxt, Plan * parent);
-extern void ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent);
+extern void ExecEndIndexScan(IndexScan * node);
-extern void ExecEndIndexScan(IndexScan *node);
+extern void ExecIndexMarkPos(IndexScan * node);
-extern void ExecIndexMarkPos(IndexScan *node);
+extern void ExecIndexRestrPos(IndexScan * node);
-extern void ExecIndexRestrPos(IndexScan *node);
+extern void ExecUpdateIndexScanKeys(IndexScan * node, ExprContext * econtext);
-extern void ExecUpdateIndexScanKeys(IndexScan *node, ExprContext *econtext);
+extern bool ExecInitIndexScan(IndexScan * node, EState * estate, Plan * parent);
-extern bool ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent);
+extern int ExecCountSlotsIndexScan(IndexScan * node);
-extern int ExecCountSlotsIndexScan(IndexScan *node);
+extern void ExecIndexReScan(IndexScan * node, ExprContext * exprCtxt, Plan * parent);
-extern void ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan* parent);
-#endif /* NODEINDEXSCAN_H */
+#endif /* NODEINDEXSCAN_H */
diff --git a/src/include/executor/nodeMaterial.h b/src/include/executor/nodeMaterial.h
index 3560315c533..c1833b11594 100644
--- a/src/include/executor/nodeMaterial.h
+++ b/src/include/executor/nodeMaterial.h
@@ -1,23 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeMaterial.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeMaterial.h,v 1.1 1996/08/28 07:22:21 scrappy Exp $
+ * $Id: nodeMaterial.h,v 1.2 1997/09/07 04:57:55 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODEMATERIAL_H
-#define NODEMATERIAL_H
+#ifndef NODEMATERIAL_H
+#define NODEMATERIAL_H
-extern TupleTableSlot *ExecMaterial(Material *node);
-extern bool ExecInitMaterial(Material *node, EState *estate, Plan *parent);
-extern int ExecCountSlotsMaterial(Material *node);
-extern void ExecEndMaterial(Material *node);
-extern List ExecMaterialMarkPos(Material *node);
-extern void ExecMaterialRestrPos(Material *node);
+extern TupleTableSlot *ExecMaterial(Material * node);
+extern bool ExecInitMaterial(Material * node, EState * estate, Plan * parent);
+extern int ExecCountSlotsMaterial(Material * node);
+extern void ExecEndMaterial(Material * node);
+extern List ExecMaterialMarkPos(Material * node);
+extern void ExecMaterialRestrPos(Material * node);
-#endif /* NODEMATERIAL_H */
+#endif /* NODEMATERIAL_H */
diff --git a/src/include/executor/nodeMergejoin.h b/src/include/executor/nodeMergejoin.h
index 3b96ac50c5c..7e496734b44 100644
--- a/src/include/executor/nodeMergejoin.h
+++ b/src/include/executor/nodeMergejoin.h
@@ -1,24 +1,24 @@
/*-------------------------------------------------------------------------
*
* nodeMergejoin.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeMergejoin.h,v 1.3 1997/08/19 21:38:22 momjian Exp $
+ * $Id: nodeMergejoin.h,v 1.4 1997/09/07 04:57:56 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODEMERGEJOIN_H
-#define NODEMERGEJOIN_H
+#ifndef NODEMERGEJOIN_H
+#define NODEMERGEJOIN_H
-extern TupleTableSlot *ExecMergeJoin(MergeJoin *node);
+extern TupleTableSlot *ExecMergeJoin(MergeJoin * node);
-extern bool ExecInitMergeJoin(MergeJoin *node, EState *estate, Plan *parent);
+extern bool ExecInitMergeJoin(MergeJoin * node, EState * estate, Plan * parent);
-extern int ExecCountSlotsMergeJoin(MergeJoin *node);
+extern int ExecCountSlotsMergeJoin(MergeJoin * node);
-extern void ExecEndMergeJoin(MergeJoin *node);
+extern void ExecEndMergeJoin(MergeJoin * node);
-#endif /* NODEMERGEJOIN_H; */
+#endif /* NODEMERGEJOIN_H; */
diff --git a/src/include/executor/nodeNestloop.h b/src/include/executor/nodeNestloop.h
index 1fe271c0702..8b387841e60 100644
--- a/src/include/executor/nodeNestloop.h
+++ b/src/include/executor/nodeNestloop.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nodeNestloop.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeNestloop.h,v 1.1 1996/08/28 07:22:23 scrappy Exp $
+ * $Id: nodeNestloop.h,v 1.2 1997/09/07 04:57:57 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODENESTLOOP_H
-#define NODENESTLOOP_H
+#ifndef NODENESTLOOP_H
+#define NODENESTLOOP_H
-extern TupleTableSlot *ExecNestLoop(NestLoop *node, Plan *parent);
-extern bool ExecInitNestLoop(NestLoop *node, EState *estate, Plan *parent);
-extern int ExecCountSlotsNestLoop(NestLoop *node);
-extern void ExecEndNestLoop(NestLoop *node);
+extern TupleTableSlot *ExecNestLoop(NestLoop * node, Plan * parent);
+extern bool ExecInitNestLoop(NestLoop * node, EState * estate, Plan * parent);
+extern int ExecCountSlotsNestLoop(NestLoop * node);
+extern void ExecEndNestLoop(NestLoop * node);
-#endif /* NODENESTLOOP_H */
+#endif /* NODENESTLOOP_H */
diff --git a/src/include/executor/nodeResult.h b/src/include/executor/nodeResult.h
index ba100ffa54c..40ef4a7b4da 100644
--- a/src/include/executor/nodeResult.h
+++ b/src/include/executor/nodeResult.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nodeResult.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeResult.h,v 1.1 1996/08/28 07:22:24 scrappy Exp $
+ * $Id: nodeResult.h,v 1.2 1997/09/07 04:57:58 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODERESULT_H
-#define NODERESULT_H
+#ifndef NODERESULT_H
+#define NODERESULT_H
-extern TupleTableSlot *ExecResult(Result *node);
-extern bool ExecInitResult(Result *node, EState *estate, Plan *parent);
-extern int ExecCountSlotsResult(Result *node);
-extern void ExecEndResult(Result *node);
+extern TupleTableSlot *ExecResult(Result * node);
+extern bool ExecInitResult(Result * node, EState * estate, Plan * parent);
+extern int ExecCountSlotsResult(Result * node);
+extern void ExecEndResult(Result * node);
-#endif /* NODERESULT_H */
+#endif /* NODERESULT_H */
diff --git a/src/include/executor/nodeSeqscan.h b/src/include/executor/nodeSeqscan.h
index 99cb83e431c..56237dc80d4 100644
--- a/src/include/executor/nodeSeqscan.h
+++ b/src/include/executor/nodeSeqscan.h
@@ -1,24 +1,24 @@
/*-------------------------------------------------------------------------
*
* nodeSeqscan.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeSeqscan.h,v 1.2 1997/08/19 21:38:23 momjian Exp $
+ * $Id: nodeSeqscan.h,v 1.3 1997/09/07 04:57:59 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODESEQSCAN_H
-#define NODESEQSCAN_H
+#ifndef NODESEQSCAN_H
+#define NODESEQSCAN_H
-extern TupleTableSlot *ExecSeqScan(SeqScan *node);
-extern bool ExecInitSeqScan(SeqScan *node, EState *estate, Plan *parent);
-extern int ExecCountSlotsSeqScan(SeqScan *node);
-extern void ExecEndSeqScan(SeqScan *node);
-extern void ExecSeqReScan(SeqScan *node, ExprContext *exprCtxt, Plan* parent);
-extern void ExecSeqMarkPos(SeqScan *node);
-extern void ExecSeqRestrPos(SeqScan *node);
+extern TupleTableSlot *ExecSeqScan(SeqScan * node);
+extern bool ExecInitSeqScan(SeqScan * node, EState * estate, Plan * parent);
+extern int ExecCountSlotsSeqScan(SeqScan * node);
+extern void ExecEndSeqScan(SeqScan * node);
+extern void ExecSeqReScan(SeqScan * node, ExprContext * exprCtxt, Plan * parent);
+extern void ExecSeqMarkPos(SeqScan * node);
+extern void ExecSeqRestrPos(SeqScan * node);
-#endif /* NODESEQSCAN_H */
+#endif /* NODESEQSCAN_H */
diff --git a/src/include/executor/nodeSort.h b/src/include/executor/nodeSort.h
index a95d9dc0522..428805702eb 100644
--- a/src/include/executor/nodeSort.h
+++ b/src/include/executor/nodeSort.h
@@ -1,23 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeSort.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeSort.h,v 1.1 1996/08/28 07:22:25 scrappy Exp $
+ * $Id: nodeSort.h,v 1.2 1997/09/07 04:58:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODESORT_H
-#define NODESORT_H
+#ifndef NODESORT_H
+#define NODESORT_H
-extern TupleTableSlot *ExecSort(Sort *node);
-extern bool ExecInitSort(Sort *node, EState *estate, Plan *parent);
-extern int ExecCountSlotsSort(Sort *node);
-extern void ExecEndSort(Sort *node);
-extern void ExecSortMarkPos(Sort *node);
-extern void ExecSortRestrPos(Sort *node);
+extern TupleTableSlot *ExecSort(Sort * node);
+extern bool ExecInitSort(Sort * node, EState * estate, Plan * parent);
+extern int ExecCountSlotsSort(Sort * node);
+extern void ExecEndSort(Sort * node);
+extern void ExecSortMarkPos(Sort * node);
+extern void ExecSortRestrPos(Sort * node);
-#endif /* NODESORT_H */
+#endif /* NODESORT_H */
diff --git a/src/include/executor/nodeTee.h b/src/include/executor/nodeTee.h
index d70a5984698..7235030d670 100644
--- a/src/include/executor/nodeTee.h
+++ b/src/include/executor/nodeTee.h
@@ -1,22 +1,22 @@
/*-------------------------------------------------------------------------
*
* nodeTee.h--
- * support functions for a Tee executor node
+ * support functions for a Tee executor node
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeTee.h,v 1.1 1996/08/28 07:22:26 scrappy Exp $
+ * $Id: nodeTee.h,v 1.2 1997/09/07 04:58:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODETEE_H
-#define NODETEE_H
+#ifndef NODETEE_H
+#define NODETEE_H
-extern TupleTableSlot* ExecTee(Tee* node, Plan* parent);
-extern bool ExecInitTee(Tee* node, EState* estate, Plan* parent);
-extern void ExecTeeReScan(Tee *node, ExprContext *exprCtxt, Plan *parent);
-extern void ExecEndTee(Tee* node, Plan* parent);
-extern int ExecCountSlotsTee(Tee* node);
+extern TupleTableSlot *ExecTee(Tee * node, Plan * parent);
+extern bool ExecInitTee(Tee * node, EState * estate, Plan * parent);
+extern void ExecTeeReScan(Tee * node, ExprContext * exprCtxt, Plan * parent);
+extern void ExecEndTee(Tee * node, Plan * parent);
+extern int ExecCountSlotsTee(Tee * node);
-#endif /* NODETEE_H */
+#endif /* NODETEE_H */
diff --git a/src/include/executor/nodeUnique.h b/src/include/executor/nodeUnique.h
index a3c143e3459..c66fa827cab 100644
--- a/src/include/executor/nodeUnique.h
+++ b/src/include/executor/nodeUnique.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nodeUnique.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeUnique.h,v 1.1 1996/08/28 07:22:27 scrappy Exp $
+ * $Id: nodeUnique.h,v 1.2 1997/09/07 04:58:01 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef NODEUNIQUE_H
-#define NODEUNIQUE_H
+#ifndef NODEUNIQUE_H
+#define NODEUNIQUE_H
-extern TupleTableSlot *ExecUnique(Unique *node);
-extern bool ExecInitUnique(Unique *node, EState *estate, Plan *parent);
-extern int ExecCountSlotsUnique(Unique *node);
-extern void ExecEndUnique(Unique *node);
+extern TupleTableSlot *ExecUnique(Unique * node);
+extern bool ExecInitUnique(Unique * node, EState * estate, Plan * parent);
+extern int ExecCountSlotsUnique(Unique * node);
+extern void ExecEndUnique(Unique * node);
-#endif /* NODEUNIQUE_H */
+#endif /* NODEUNIQUE_H */
diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h
index 8ab7b34b0c8..fee2056f9f8 100644
--- a/src/include/executor/spi.h
+++ b/src/include/executor/spi.h
@@ -1,11 +1,11 @@
/*-------------------------------------------------------------------------
*
* spi.h--
- *
+ *
*
*-------------------------------------------------------------------------
*/
-#ifndef SPI_H
+#ifndef SPI_H
#define SPI_H
#include <string.h>
@@ -34,52 +34,53 @@
#include "executor/executor.h"
#include "executor/execdefs.h"
-typedef struct {
- uint32 alloced; /* # of alloced vals */
- uint32 free; /* # of free vals */
- TupleDesc tupdesc; /* tuple descriptor */
- HeapTuple *vals; /* tuples */
-} SPITupleTable;
+typedef struct
+{
+ uint32 alloced; /* # of alloced vals */
+ uint32 free; /* # of free vals */
+ TupleDesc tupdesc; /* tuple descriptor */
+ HeapTuple *vals; /* tuples */
+} SPITupleTable;
-#define SPI_ERROR_CONNECT -1
-#define SPI_ERROR_COPY -2
-#define SPI_ERROR_OPUNKNOWN -3
+#define SPI_ERROR_CONNECT -1
+#define SPI_ERROR_COPY -2
+#define SPI_ERROR_OPUNKNOWN -3
#define SPI_ERROR_UNCONNECTED -4
-#define SPI_ERROR_CURSOR -5
-#define SPI_ERROR_ARGUMENT -6
-#define SPI_ERROR_PARAM -7
+#define SPI_ERROR_CURSOR -5
+#define SPI_ERROR_ARGUMENT -6
+#define SPI_ERROR_PARAM -7
#define SPI_ERROR_TRANSACTION -8
#define SPI_ERROR_NOATTRIBUTE -9
-#define SPI_ERROR_NOOUTFUNC -10
+#define SPI_ERROR_NOOUTFUNC -10
#define SPI_ERROR_TYPUNKNOWN -11
-#define SPI_OK_CONNECT 1
-#define SPI_OK_FINISH 2
-#define SPI_OK_FETCH 3
-#define SPI_OK_UTILITY 4
-#define SPI_OK_SELECT 5
-#define SPI_OK_SELINTO 6
-#define SPI_OK_INSERT 7
-#define SPI_OK_DELETE 8
-#define SPI_OK_UPDATE 9
-#define SPI_OK_CURSOR 10
+#define SPI_OK_CONNECT 1
+#define SPI_OK_FINISH 2
+#define SPI_OK_FETCH 3
+#define SPI_OK_UTILITY 4
+#define SPI_OK_SELECT 5
+#define SPI_OK_SELINTO 6
+#define SPI_OK_INSERT 7
+#define SPI_OK_DELETE 8
+#define SPI_OK_UPDATE 9
+#define SPI_OK_CURSOR 10
-extern uint32 SPI_processed;
+extern uint32 SPI_processed;
extern SPITupleTable *SPI_tuptable;
-extern int SPI_result;
+extern int SPI_result;
-extern int SPI_connect (void);
-extern int SPI_finish (void);
-extern int SPI_exec (char *src, int tcount);
-extern int SPI_execp (void *plan, char **values, char *Nulls, int tcount);
-extern void *SPI_prepare (char *src, int nargs, Oid *argtypes);
-extern void *SPI_saveplan (void *plan);
+extern int SPI_connect(void);
+extern int SPI_finish(void);
+extern int SPI_exec(char *src, int tcount);
+extern int SPI_execp(void *plan, char **values, char *Nulls, int tcount);
+extern void *SPI_prepare(char *src, int nargs, Oid * argtypes);
+extern void *SPI_saveplan(void *plan);
-extern int SPI_fnumber (TupleDesc tupdesc, char *fname);
-extern char *SPI_getvalue (HeapTuple tuple, TupleDesc tupdesc, int fnumber);
-extern char *SPI_getbinval (HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull);
-extern char *SPI_gettype (TupleDesc tupdesc, int fnumber);
-extern Oid SPI_gettypeid (TupleDesc tupdesc, int fnumber);
-extern char *SPI_getrelname (Relation rel);
+extern int SPI_fnumber(TupleDesc tupdesc, char *fname);
+extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber);
+extern char *SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull);
+extern char *SPI_gettype(TupleDesc tupdesc, int fnumber);
+extern Oid SPI_gettypeid(TupleDesc tupdesc, int fnumber);
+extern char *SPI_getrelname(Relation rel);
-#endif /* SPI_H */
+#endif /* SPI_H */
diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h
index 4357e1240de..fcef30cd8e4 100644
--- a/src/include/executor/tuptable.h
+++ b/src/include/executor/tuptable.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* tuptable.h--
- * tuple table support stuff
+ * tuple table support stuff
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: tuptable.h,v 1.4 1996/11/04 08:52:47 scrappy Exp $
+ * $Id: tuptable.h,v 1.5 1997/09/07 04:58:03 momjian Exp $
*
* NOTES
- * The tuple table interface is getting pretty ugly.
- * It should be redesigned soon.
+ * The tuple table interface is getting pretty ugly.
+ * It should be redesigned soon.
*
*-------------------------------------------------------------------------
*/
@@ -22,55 +22,57 @@
#include <access/htup.h>
/* ----------------
- * Note: the executor tuple table is managed and manipulated by special
- * code and macros in executor/execTuples.c and tupTable.h
+ * Note: the executor tuple table is managed and manipulated by special
+ * code and macros in executor/execTuples.c and tupTable.h
*
- * TupleTableSlot information
+ * TupleTableSlot information
*
- * shouldFree boolean - should we call pfree() on tuple
- * descIsNew boolean - true when tupleDescriptor changes
- * tupleDescriptor type information kept regarding the tuple data
- * buffer the buffer for tuples pointing to disk pages
+ * shouldFree boolean - should we call pfree() on tuple
+ * descIsNew boolean - true when tupleDescriptor changes
+ * tupleDescriptor type information kept regarding the tuple data
+ * buffer the buffer for tuples pointing to disk pages
*
- * The executor stores pointers to tuples in a ``tuple table''
- * which is composed of TupleTableSlot's. Some of the tuples
- * are pointers to buffer pages and others are pointers to
- * palloc'ed memory and the shouldFree variable tells us when
- * we may call pfree() on a tuple. -cim 9/23/90
+ * The executor stores pointers to tuples in a ``tuple table''
+ * which is composed of TupleTableSlot's. Some of the tuples
+ * are pointers to buffer pages and others are pointers to
+ * palloc'ed memory and the shouldFree variable tells us when
+ * we may call pfree() on a tuple. -cim 9/23/90
*
- * In the implementation of nested-dot queries such as
- * "retrieve (EMP.hobbies.all)", a single scan may return tuples
- * of many types, so now we return pointers to tuple descriptors
- * along with tuples returned via the tuple table. -cim 1/18/90
+ * In the implementation of nested-dot queries such as
+ * "retrieve (EMP.hobbies.all)", a single scan may return tuples
+ * of many types, so now we return pointers to tuple descriptors
+ * along with tuples returned via the tuple table. -cim 1/18/90
* ----------------
*/
-typedef struct TupleTableSlot {
- NodeTag type;
- HeapTuple val;
- bool ttc_shouldFree;
- bool ttc_descIsNew;
- TupleDesc ttc_tupleDescriptor;
- Buffer ttc_buffer;
- int ttc_whichplan;
-} TupleTableSlot;
+typedef struct TupleTableSlot
+{
+ NodeTag type;
+ HeapTuple val;
+ bool ttc_shouldFree;
+ bool ttc_descIsNew;
+ TupleDesc ttc_tupleDescriptor;
+ Buffer ttc_buffer;
+ int ttc_whichplan;
+} TupleTableSlot;
/* ----------------
- * tuple table data structure
+ * tuple table data structure
* ----------------
*/
-typedef struct TupleTableData {
- int size; /* size of the table */
- int next; /* next available slot number */
- TupleTableSlot *array; /* array of TupleTableSlot's */
-} TupleTableData;
+typedef struct TupleTableData
+{
+ int size; /* size of the table */
+ int next; /* next available slot number */
+ TupleTableSlot *array; /* array of TupleTableSlot's */
+} TupleTableData;
typedef TupleTableData *TupleTable;
-/*
+/*
tuple table macros are all excised from the system now
see executor.h for decls of functions defined in execTuples.c
- jolly
*/
-#endif /* TUPTABLE_H */
+#endif /* TUPTABLE_H */
diff --git a/src/include/lib/dllist.h b/src/include/lib/dllist.h
index 4c4534b974c..15a18d88c6f 100644
--- a/src/include/lib/dllist.h
+++ b/src/include/lib/dllist.h
@@ -1,32 +1,32 @@
/*-------------------------------------------------------------------------
*
* dllist.h--
- * simple doubly linked list primitives
- * the elements of the list are void* so the lists can contain
- * anything
- * Dlelem can only be in one list at a time
- *
+ * simple doubly linked list primitives
+ * the elements of the list are void* so the lists can contain
+ * anything
+ * Dlelem can only be in one list at a time
*
- * Here's a small example of how to use Dllist's :
- *
- * Dllist *lst;
- * Dlelem *elt;
- * void *in_stuff; -- stuff to stick in the list
- * void *out_stuff
*
- * lst = DLNewList(); -- make a new dllist
- * DLAddHead(lst, DLNewElem(in_stuff)); -- add a new element to the list
- * with in_stuff as the value
- * ...
- * elt = DLGetHead(lst); -- retrieve the head element
- * out_stuff = (void*)DLE_VAL(elt); -- get the stuff out
- * DLRemove(elt); -- removes the element from its list
- * DLFreeElem(elt); -- free the element since we don't
- * use it anymore
+ * Here's a small example of how to use Dllist's :
+ *
+ * Dllist *lst;
+ * Dlelem *elt;
+ * void *in_stuff; -- stuff to stick in the list
+ * void *out_stuff
+ *
+ * lst = DLNewList(); -- make a new dllist
+ * DLAddHead(lst, DLNewElem(in_stuff)); -- add a new element to the list
+ * with in_stuff as the value
+ * ...
+ * elt = DLGetHead(lst); -- retrieve the head element
+ * out_stuff = (void*)DLE_VAL(elt); -- get the stuff out
+ * DLRemove(elt); -- removes the element from its list
+ * DLFreeElem(elt); -- free the element since we don't
+ * use it anymore
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: dllist.h,v 1.4 1997/08/19 21:38:28 momjian Exp $
+ * $Id: dllist.h,v 1.5 1997/09/07 04:58:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,32 +38,36 @@
struct Dllist;
struct Dlelem;
-typedef struct Dlelem {
- struct Dlelem *dle_next; /* next element */
- struct Dlelem *dle_prev; /* previous element */
- void *dle_val; /* value of the element */
- struct Dllist *dle_list; /* what list this element is in */
-} Dlelem;
+typedef struct Dlelem
+{
+ struct Dlelem *dle_next; /* next element */
+ struct Dlelem *dle_prev; /* previous element */
+ void *dle_val; /* value of the element */
+ struct Dllist *dle_list; /* what list this element is in */
+} Dlelem;
+
+typedef struct Dllist
+{
+ Dlelem *dll_head;
+ Dlelem *dll_tail;
+} Dllist;
-typedef struct Dllist {
- Dlelem *dll_head;
- Dlelem *dll_tail;
-} Dllist;
-
-extern Dllist* DLNewList(void); /* initialize a new list */
-extern void DLFreeList(Dllist*); /* free up a list and all the nodes in it*/
-extern Dlelem* DLNewElem(void* val);
-extern void DLFreeElem(Dlelem*);
-extern Dlelem* DLGetHead(Dllist*);
-extern Dlelem* DLGetTail(Dllist*);
-extern Dlelem* DLRemTail(Dllist* l);
-extern Dlelem* DLGetPred(Dlelem*); /* get predecessor */
-extern Dlelem* DLGetSucc(Dlelem*); /* get successor */
-extern void DLRemove(Dlelem*); /* removes node from list*/
-extern void DLAddHead(Dllist* list, Dlelem* node);
-extern void DLAddTail(Dllist* list, Dlelem* node);
-extern Dlelem* DLRemHead(Dllist* list); /* remove and return the head */
+extern Dllist *DLNewList(void);/* initialize a new list */
+extern void DLFreeList(Dllist *); /* free up a list and all the
+ * nodes in it */
+extern Dlelem *DLNewElem(void *val);
+extern void DLFreeElem(Dlelem *);
+extern Dlelem *DLGetHead(Dllist *);
+extern Dlelem *DLGetTail(Dllist *);
+extern Dlelem *DLRemTail(Dllist * l);
+extern Dlelem *DLGetPred(Dlelem *); /* get predecessor */
+extern Dlelem *DLGetSucc(Dlelem *); /* get successor */
+extern void DLRemove(Dlelem *); /* removes node from list */
+extern void DLAddHead(Dllist * list, Dlelem * node);
+extern void DLAddTail(Dllist * list, Dlelem * node);
+extern Dlelem *DLRemHead(Dllist * list); /* remove and return the
+ * head */
-#define DLE_VAL(x) (x->dle_val)
+#define DLE_VAL(x) (x->dle_val)
-#endif /* DLLIST_H */
+#endif /* DLLIST_H */
diff --git a/src/include/lib/fstack.h b/src/include/lib/fstack.h
index de2868142a3..99f10b9006c 100644
--- a/src/include/lib/fstack.h
+++ b/src/include/lib/fstack.h
@@ -1,112 +1,114 @@
/*-------------------------------------------------------------------------
*
* fstack.h--
- * Fixed format stack definitions.
+ * Fixed format stack definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: fstack.h,v 1.2 1996/10/31 09:48:46 scrappy Exp $
+ * $Id: fstack.h,v 1.3 1997/09/07 04:58:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* Note:
- * Fixed format stacks assist in the construction of FIFO stacks of
- * fixed format structures. Structures which are to be stackable
- * should contain a FixedItemData component. A stack is initilized
- * with the offset of the FixedItemData component of the structure
- * it will hold. By doing so, push and pop operations are simplified
- * for the callers. All references to stackable items are pointers
- * to the base of the structure instead of pointers to the
- * FixedItemData component.
+ * Fixed format stacks assist in the construction of FIFO stacks of
+ * fixed format structures. Structures which are to be stackable
+ * should contain a FixedItemData component. A stack is initilized
+ * with the offset of the FixedItemData component of the structure
+ * it will hold. By doing so, push and pop operations are simplified
+ * for the callers. All references to stackable items are pointers
+ * to the base of the structure instead of pointers to the
+ * FixedItemData component.
*
*/
-#ifndef FSTACK_H
+#ifndef FSTACK_H
#define FSTACK_H
/*
* FixedItem --
- * Fixed format stackable item chain component.
+ * Fixed format stackable item chain component.
*
* Note:
- * Structures must contain one FixedItemData component per stack in
- * which it will be an item.
+ * Structures must contain one FixedItemData component per stack in
+ * which it will be an item.
*/
-typedef struct FixedItemData FixedItemData;
-typedef FixedItemData *FixedItem;
+typedef struct FixedItemData FixedItemData;
+typedef FixedItemData *FixedItem;
-struct FixedItemData {
- FixedItem next; /* next item or NULL */
+struct FixedItemData
+{
+ FixedItem next; /* next item or NULL */
};
/*
* FixedStack --
- * Fixed format stack.
+ * Fixed format stack.
*/
-typedef struct FixedStackData {
- FixedItem top; /* Top item on the stack or NULL */
- Offset offset; /* Offset from struct base to item */
+typedef struct FixedStackData
+{
+ FixedItem top; /* Top item on the stack or NULL */
+ Offset offset; /* Offset from struct base to item */
/* this could be signed short int! */
-} FixedStackData;
+} FixedStackData;
-typedef FixedStackData *FixedStack;
+typedef FixedStackData *FixedStack;
/*
* FixedStackInit --
- * Iniitializes stack for structures with given fixed component offset.
+ * Iniitializes stack for structures with given fixed component offset.
*
* Exceptions:
- * BadArg if stack is invalid pointer.
+ * BadArg if stack is invalid pointer.
*/
-extern void FixedStackInit(FixedStack stack, Offset offset);
+extern void FixedStackInit(FixedStack stack, Offset offset);
/*
* FixedStackPop --
- * Returns pointer to top structure on stack or NULL if empty stack.
+ * Returns pointer to top structure on stack or NULL if empty stack.
*
* Exceptions:
- * BadArg if stack is invalid.
+ * BadArg if stack is invalid.
*/
-Pointer FixedStackPop(FixedStack stack);
+Pointer FixedStackPop(FixedStack stack);
/*
* FixedStackPush --
- * Places structure associated with pointer onto top of stack.
+ * Places structure associated with pointer onto top of stack.
*
* Exceptions:
- * BadArg if stack is invalid.
- * BadArg if pointer is invalid.
+ * BadArg if stack is invalid.
+ * BadArg if pointer is invalid.
*/
-extern void FixedStackPush(FixedStack stack, Pointer pointer);
+extern void FixedStackPush(FixedStack stack, Pointer pointer);
/*
* FixedStackGetTop --
- * Returns pointer to top structure of a stack. This item is not poped.
+ * Returns pointer to top structure of a stack. This item is not poped.
*
* Note:
- * This is not part of the normal stack interface. It is intended for
- * debugging use only.
+ * This is not part of the normal stack interface. It is intended for
+ * debugging use only.
*
* Exceptions:
- * BadArg if stack is invalid.
+ * BadArg if stack is invalid.
*/
-extern Pointer FixedStackGetTop(FixedStack stack);
+extern Pointer FixedStackGetTop(FixedStack stack);
/*
* FixedStackGetNext --
- * Returns pointer to next structure after pointer of a stack.
+ * Returns pointer to next structure after pointer of a stack.
*
* Note:
- * This is not part of the normal stack interface. It is intended for
- * debugging use only.
+ * This is not part of the normal stack interface. It is intended for
+ * debugging use only.
*
* Exceptions:
- * BadArg if stack is invalid.
- * BadArg if pointer is invalid.
- * BadArg if stack does not contain pointer.
+ * BadArg if stack is invalid.
+ * BadArg if pointer is invalid.
+ * BadArg if stack does not contain pointer.
*/
-extern Pointer FixedStackGetNext(FixedStack stack, Pointer pointer);
+extern Pointer FixedStackGetNext(FixedStack stack, Pointer pointer);
-#endif /* FSTACK_H */
+#endif /* FSTACK_H */
diff --git a/src/include/lib/hasht.h b/src/include/lib/hasht.h
index 20f562e1136..1d28c2ca28f 100644
--- a/src/include/lib/hasht.h
+++ b/src/include/lib/hasht.h
@@ -1,23 +1,23 @@
/*-------------------------------------------------------------------------
*
* hasht.h--
- * hash table related functions that are not directly supported
- * under utils/hash.
+ * hash table related functions that are not directly supported
+ * under utils/hash.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: hasht.h,v 1.2 1996/11/05 11:29:45 scrappy Exp $
+ * $Id: hasht.h,v 1.3 1997/09/07 04:58:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef HASHT_H
+#ifndef HASHT_H
#define HASHT_H
#include <utils/hsearch.h>
-typedef void (*HashtFunc)();
+typedef void (*HashtFunc) ();
-extern void HashTableWalk(HTAB *hashtable, HashtFunc function, int arg);
+extern void HashTableWalk(HTAB * hashtable, HashtFunc function, int arg);
-#endif /* HASHT_H */
+#endif /* HASHT_H */
diff --git a/src/include/lib/lispsort.h b/src/include/lib/lispsort.h
index 872b14959a3..d4d074ba54d 100644
--- a/src/include/lib/lispsort.h
+++ b/src/include/lib/lispsort.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* lispsort.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: lispsort.h,v 1.2 1997/08/19 21:38:30 momjian Exp $
+ * $Id: lispsort.h,v 1.3 1997/09/07 04:58:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef LISPSORT_H
-#define LISPSORT_H
+#ifndef LISPSORT_H
+#define LISPSORT_H
-#endif /* LISPSORT_H */
+#endif /* LISPSORT_H */
diff --git a/src/include/lib/qsort.h b/src/include/lib/qsort.h
index 3382d0b34e8..d321ed7fb2c 100644
--- a/src/include/lib/qsort.h
+++ b/src/include/lib/qsort.h
@@ -1,23 +1,23 @@
/*-------------------------------------------------------------------------
*
* qsort.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: qsort.h,v 1.2 1996/11/06 10:29:46 scrappy Exp $
+ * $Id: qsort.h,v 1.3 1997/09/07 04:58:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef QSORT_H
-#define QSORT_H
+#ifndef QSORT_H
+#define QSORT_H
-extern void pg_qsort(void *bot,
- size_t nmemb,
- size_t size,
- int (*compar)(void *, void *));
+extern void
+pg_qsort(void *bot,
+ size_t nmemb,
+ size_t size,
+ int (*compar) (void *, void *));
-#endif /* QSORT_H */
-
+#endif /* QSORT_H */
diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h
index 39863fcbcae..f127d8cdd01 100644
--- a/src/include/lib/stringinfo.h
+++ b/src/include/lib/stringinfo.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* stringinfo.h--
- * Declarations/definitons for "string" functions.
+ * Declarations/definitons for "string" functions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: stringinfo.h,v 1.2 1996/10/31 09:48:52 scrappy Exp $
+ * $Id: stringinfo.h,v 1.3 1997/09/07 04:58:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,18 +16,19 @@
/*-------------------------
* StringInfoData holds information about a string.
- * 'data' is the string.
- * 'len' is the current string length (as returned by 'strlen')
- * 'maxlen' is the size in bytes of 'data', i.e. the maximum string
- * size (includeing the terminating '\0' char) that we can
- * currently store in 'data' without having to reallocate
- * more space.
+ * 'data' is the string.
+ * 'len' is the current string length (as returned by 'strlen')
+ * 'maxlen' is the size in bytes of 'data', i.e. the maximum string
+ * size (includeing the terminating '\0' char) that we can
+ * currently store in 'data' without having to reallocate
+ * more space.
*/
-typedef struct StringInfoData {
- char *data;
- int maxlen;
- int len;
-} StringInfoData;
+typedef struct StringInfoData
+{
+ char *data;
+ int maxlen;
+ int len;
+} StringInfoData;
typedef StringInfoData *StringInfo;
@@ -41,6 +42,6 @@ extern StringInfo makeStringInfo(void);
* appendStringInfo
* similar to 'strcat' but reallocates more space if necessary...
*/
-extern void appendStringInfo(StringInfo str, char *buffer);
+extern void appendStringInfo(StringInfo str, char *buffer);
-#endif /* STRINGINFO_H */
+#endif /* STRINGINFO_H */
diff --git a/src/include/libpq/auth.h b/src/include/libpq/auth.h
index 40a97cdfb44..a159b7a5ebd 100644
--- a/src/include/libpq/auth.h
+++ b/src/include/libpq/auth.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* auth.h--
- * Definitions for network authentication routines
+ * Definitions for network authentication routines
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: auth.h,v 1.4 1997/08/19 21:38:34 momjian Exp $
+ * $Id: auth.h,v 1.5 1997/09/07 04:58:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef AUTH_H
-#define AUTH_H
+#define AUTH_H
#include <libpq/pqcomm.h>
@@ -21,27 +21,27 @@
*/
/* what we call "no authentication system" */
-#define UNAUTHNAME "unauth"
+#define UNAUTHNAME "unauth"
/* what a frontend uses by default */
#if !defined(KRB4) && !defined(KRB5)
-#define DEFAULT_CLIENT_AUTHSVC UNAUTHNAME
-#else /* KRB4 || KRB5 */
-#define DEFAULT_CLIENT_AUTHSVC "kerberos"
-#endif /* KRB4 || KRB5 */
-
-extern int fe_sendauth(MsgType msgtype, Port *port, char *hostname);
-extern void fe_setauthsvc(char *name);
-extern MsgType fe_getauthsvc();
-extern char *fe_getauthname(void);
-extern int be_recvauth(MsgType msgtype, Port *port, char *username, StartupInfo* sp);
-extern void be_setauthsvc(char *name);
+#define DEFAULT_CLIENT_AUTHSVC UNAUTHNAME
+#else /* KRB4 || KRB5 */
+#define DEFAULT_CLIENT_AUTHSVC "kerberos"
+#endif /* KRB4 || KRB5 */
+
+extern int fe_sendauth(MsgType msgtype, Port * port, char *hostname);
+extern void fe_setauthsvc(char *name);
+extern MsgType fe_getauthsvc();
+extern char *fe_getauthname(void);
+extern int be_recvauth(MsgType msgtype, Port * port, char *username, StartupInfo * sp);
+extern void be_setauthsvc(char *name);
/* the value that matches any dbName value when doing
host based authentication*/
-#define ALL_DBNAME "*"
+#define ALL_DBNAME "*"
-#define PG_KRB4_VERSION "PGVER4.1" /* at most KRB_SENDAUTH_VLEN chars */
-#define PG_KRB5_VERSION "PGVER5.1"
+#define PG_KRB4_VERSION "PGVER4.1" /* at most KRB_SENDAUTH_VLEN chars */
+#define PG_KRB5_VERSION "PGVER5.1"
-#endif /* AUTH_H */
+#endif /* AUTH_H */
diff --git a/src/include/libpq/be-fsstubs.h b/src/include/libpq/be-fsstubs.h
index 34fda6fd60e..2ea347a9b3e 100644
--- a/src/include/libpq/be-fsstubs.h
+++ b/src/include/libpq/be-fsstubs.h
@@ -1,40 +1,40 @@
/*-------------------------------------------------------------------------
*
* be-fsstubs.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: be-fsstubs.h,v 1.2 1997/05/06 07:14:34 thomas Exp $
+ * $Id: be-fsstubs.h,v 1.3 1997/09/07 04:58:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef BE_FSSTUBS_H
-#define BE_FSSTUBS_H
+#ifndef BE_FSSTUBS_H
+#define BE_FSSTUBS_H
/* Redefine names LOread() and LOwrite() to be lowercase to allow calling
- * using the new v6.1 case-insensitive SQL parser. Define macros to allow
- * the existing code to stay the same. - tgl 97/05/03
+ * using the new v6.1 case-insensitive SQL parser. Define macros to allow
+ * the existing code to stay the same. - tgl 97/05/03
*/
#define LOread(f,l) loread(f,l)
#define LOwrite(f,b) lowrite(f,b)
-extern Oid lo_import(text *filename);
-extern int4 lo_export(Oid lobjId, text *filename);
+extern Oid lo_import(text * filename);
+extern int4 lo_export(Oid lobjId, text * filename);
-extern Oid lo_creat(int mode);
+extern Oid lo_creat(int mode);
-extern int lo_open(Oid lobjId, int mode);
-extern int lo_close(int fd);
-extern int lo_read(int fd, char *buf, int len);
-extern int lo_write(int fd, char *buf, int len);
-extern int lo_lseek(int fd, int offset, int whence);
-extern int lo_tell(int fd);
-extern int lo_unlink(Oid lobjId);
+extern int lo_open(Oid lobjId, int mode);
+extern int lo_close(int fd);
+extern int lo_read(int fd, char *buf, int len);
+extern int lo_write(int fd, char *buf, int len);
+extern int lo_lseek(int fd, int offset, int whence);
+extern int lo_tell(int fd);
+extern int lo_unlink(Oid lobjId);
extern struct varlena *loread(int fd, int len);
-extern int lowrite(int fd, struct varlena *wbuf);
+extern int lowrite(int fd, struct varlena * wbuf);
-#endif /* BE_FSSTUBS_H */
+#endif /* BE_FSSTUBS_H */
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index 14847438b0d..c54b9938ce4 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -1,49 +1,53 @@
/*-------------------------------------------------------------------------
*
* hba.h--
- * Interface to hba.c
+ * Interface to hba.c
*
*
- * $Id: hba.h,v 1.3 1997/03/12 21:22:16 scrappy Exp $
+ * $Id: hba.h,v 1.4 1997/09/07 04:58:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef HBA_H
-#define HBA_H
+#define HBA_H
#include <libpq/pqcomm.h>
-#define CONF_FILE "pg_hba.conf"
- /* Name of the config file */
+#define CONF_FILE "pg_hba.conf"
+ /* Name of the config file */
#define MAP_FILE "pg_ident.conf"
- /* Name of the usermap file */
+ /* Name of the usermap file */
#define OLD_CONF_FILE "pg_hba"
- /* Name of the config file in prior releases of Postgres. */
+ /* Name of the config file in prior releases of Postgres. */
-#define MAX_LINES 255
- /* Maximum number of config lines that can apply to one database */
+#define MAX_LINES 255
+ /* Maximum number of config lines that can apply to one database */
-#define MAX_TOKEN 80
-/* Maximum size of one token in the configuration file */
+#define MAX_TOKEN 80
+/* Maximum size of one token in the configuration file */
-#define USERMAP_NAME_SIZE 16 /* Max size of a usermap name */
+#define USERMAP_NAME_SIZE 16 /* Max size of a usermap name */
#define IDENT_PORT 113
- /* Standard TCP port number for Ident service. Assigned by IANA */
+ /* Standard TCP port number for Ident service. Assigned by IANA */
-#define IDENT_USERNAME_MAX 512
- /* Max size of username ident server can return */
+#define IDENT_USERNAME_MAX 512
+ /* Max size of username ident server can return */
-enum Userauth {Trust, Ident, Password};
+enum Userauth
+{
+ Trust, Ident, Password
+};
extern int
-hba_recvauth(const Port *port, const char database[], const char user[],
- const char DataDir[]);
-void find_hba_entry(const char DataDir[], const struct in_addr ip_addr,
- const char database[],
- bool *host_ok_p, enum Userauth *userauth_p,
- char usermap_name[], bool find_password_entries);
+hba_recvauth(const Port * port, const char database[], const char user[],
+ const char DataDir[]);
+void
+find_hba_entry(const char DataDir[], const struct in_addr ip_addr,
+ const char database[],
+ bool * host_ok_p, enum Userauth * userauth_p,
+ char usermap_name[], bool find_password_entries);
#endif
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 1d87f17421d..4550461d06e 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* libpq-be.h--
- * This file contains definitions for structures and
- * externs for functions used by the POSTGRES backend.
+ * This file contains definitions for structures and
+ * externs for functions used by the POSTGRES backend.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-be.h,v 1.4 1997/08/19 21:38:37 momjian Exp $
+ * $Id: libpq-be.h,v 1.5 1997/09/07 04:58:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,33 +19,35 @@
#include <libpq/libpq.h>
/* ----------------
- * include stuff common to fe and be
+ * include stuff common to fe and be
* ----------------
*/
/* ----------------
- * declarations for backend libpq support routines
+ * declarations for backend libpq support routines
* ----------------
*/
/* in be-dumpdata.c */
-extern void be_portalinit(void);
-extern void be_portalpush(PortalEntry *entry);
+extern void be_portalinit(void);
+extern void be_portalpush(PortalEntry * entry);
extern PortalEntry *be_portalpop(void);
extern PortalEntry *be_currentportal(void);
extern PortalEntry *be_newportal(void);
-extern void be_typeinit(PortalEntry *entry, TupleDesc attrs,
+extern void
+be_typeinit(PortalEntry * entry, TupleDesc attrs,
int natts);
-extern void be_printtup(HeapTuple tuple, TupleDesc typeinfo);
+extern void be_printtup(HeapTuple tuple, TupleDesc typeinfo);
/* in be-pqexec.c */
-extern char *PQfn(int fnid, int *result_buf, int result_len, int result_is_int,
- PQArgBlock *args, int nargs);
-extern char *PQexec(char *query);
-extern int pqtest_PQexec(char *q);
-extern int pqtest_PQfn(char *q);
-extern int32 pqtest(struct varlena *vlena);
-
-#endif /* LIBPQ_BE_H */
+extern char *
+PQfn(int fnid, int *result_buf, int result_len, int result_is_int,
+ PQArgBlock * args, int nargs);
+extern char *PQexec(char *query);
+extern int pqtest_PQexec(char *q);
+extern int pqtest_PQfn(char *q);
+extern int32 pqtest(struct varlena * vlena);
+
+#endif /* LIBPQ_BE_H */
diff --git a/src/include/libpq/libpq-fs.h b/src/include/libpq/libpq-fs.h
index 4bb37e71492..4e7f4e37a2e 100644
--- a/src/include/libpq/libpq-fs.h
+++ b/src/include/libpq/libpq-fs.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* libpq-fs.h--
- * definitions for using Inversion file system routines
+ * definitions for using Inversion file system routines
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-fs.h,v 1.3 1997/02/14 04:18:33 momjian Exp $
+ * $Id: libpq-fs.h,v 1.4 1997/09/07 04:58:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,59 +18,60 @@
#ifndef MAXNAMLEN
#define MAXNAMLEN 255
-#endif /* MAXNAMLEN */
+#endif /* MAXNAMLEN */
-struct pgdirent {
- unsigned long d_ino;
- unsigned short d_namlen;
- char d_name[MAXNAMLEN+1];
+struct pgdirent
+{
+ unsigned long d_ino;
+ unsigned short d_namlen;
+ char d_name[MAXNAMLEN + 1];
};
/*
* SysV struct dirent doesn't have d_namlen.
- * This counts on d_name being last, which is moderately safe (ha) since
+ * This counts on d_name being last, which is moderately safe (ha) since
* it's the variable-length part of the structure.
*/
#ifdef SYSV_DIRENT
-#define D_NAMLEN(dp) \
- ((dp)->d_reclen - offsetof(struct dirent, d_name[0]))
-#else /* SYSV_DIRENT */
-#define D_NAMLEN(dp) \
- ((dp)->d_namlen)
-#endif /* SYSV_DIRENT */
+#define D_NAMLEN(dp) \
+ ((dp)->d_reclen - offsetof(struct dirent, d_name[0]))
+#else /* SYSV_DIRENT */
+#define D_NAMLEN(dp) \
+ ((dp)->d_namlen)
+#endif /* SYSV_DIRENT */
/* for stat(2) */
#ifndef S_IRUSR
/* file modes */
-#define S_IRWXU 00700 /* read, write, execute: owner */
-#define S_IRUSR 00400 /* read permission: owner */
-#define S_IWUSR 00200 /* write permission: owner */
-#define S_IXUSR 00100 /* execute permission: owner */
+#define S_IRWXU 00700 /* read, write, execute: owner */
+#define S_IRUSR 00400 /* read permission: owner */
+#define S_IWUSR 00200 /* write permission: owner */
+#define S_IXUSR 00100 /* execute permission: owner */
-#define S_IRWXG 00070 /* read, write, execute: group */
-#define S_IRGRP 00040 /* read permission: group */
-#define S_IWGRP 00020 /* write permission: group */
-#define S_IXGRP 00010 /* execute permission: group */
+#define S_IRWXG 00070 /* read, write, execute: group */
+#define S_IRGRP 00040 /* read permission: group */
+#define S_IWGRP 00020 /* write permission: group */
+#define S_IXGRP 00010 /* execute permission: group */
-#define S_IRWXO 00007 /* read, write, execute: other */
-#define S_IROTH 00004 /* read permission: other */
-#define S_IWOTH 00002 /* write permission: other */
-#define S_IXOTH 00001 /* execute permission: other */
+#define S_IRWXO 00007 /* read, write, execute: other */
+#define S_IROTH 00004 /* read permission: other */
+#define S_IWOTH 00002 /* write permission: other */
+#define S_IXOTH 00001 /* execute permission: other */
-#define _S_IFMT 0170000 /* type of file; sync with S_IFMT */
-#define _S_IFBLK 0060000 /* block special; sync with S_IFBLK */
-#define _S_IFCHR 0020000 /* character special sync with S_IFCHR */
-#define _S_IFDIR 0040000 /* directory; sync with S_IFDIR */
-#define _S_IFIFO 0010000 /* FIFO - named pipe; sync with S_IFIFO */
-#define _S_IFREG 0100000 /* regular; sync with S_IFREG */
+#define _S_IFMT 0170000 /* type of file; sync with S_IFMT */
+#define _S_IFBLK 0060000 /* block special; sync with S_IFBLK */
+#define _S_IFCHR 0020000 /* character special sync with S_IFCHR */
+#define _S_IFDIR 0040000 /* directory; sync with S_IFDIR */
+#define _S_IFIFO 0010000 /* FIFO - named pipe; sync with S_IFIFO */
+#define _S_IFREG 0100000 /* regular; sync with S_IFREG */
#define S_IFDIR _S_IFDIR
#define S_IFREG _S_IFREG
-#define S_ISDIR( mode ) (((mode) & _S_IFMT) == _S_IFDIR)
+#define S_ISDIR( mode ) (((mode) & _S_IFMT) == _S_IFDIR)
-#endif /* S_IRUSR */
+#endif /* S_IRUSR */
/*
* Inversion doesn't have links.
@@ -80,28 +81,28 @@ struct pgdirent {
#endif
/*
- * Flags for inversion file system large objects. Normally, creat()
- * takes mode arguments, but we don't use them in inversion, since
- * you get postgres protections. Instead, we use the low sixteen bits
- * of the integer mode argument to store the number of the storage
- * manager to be used, and the high sixteen bits for flags.
+ * Flags for inversion file system large objects. Normally, creat()
+ * takes mode arguments, but we don't use them in inversion, since
+ * you get postgres protections. Instead, we use the low sixteen bits
+ * of the integer mode argument to store the number of the storage
+ * manager to be used, and the high sixteen bits for flags.
*/
#define INV_SMGRMASK 0x0000ffff
-#define INV_ARCHIVE 0x00010000
-#define INV_WRITE 0x00020000
-#define INV_READ 0x00040000
+#define INV_ARCHIVE 0x00010000
+#define INV_WRITE 0x00020000
+#define INV_READ 0x00040000
/* Error values for p_errno */
-#define PEPERM 1 /* Not owner */
-#define PENOENT 2 /* No such file or directory */
-#define PEACCES 13 /* Permission denied */
-#define PEEXIST 17 /* File exists */
-#define PENOTDIR 20 /* Not a directory*/
-#define PEISDIR 21 /* Is a directory */
-#define PEINVAL 22 /* Invalid argument */
-#define PENAMETOOLONG 63 /* File name too long */
-#define PENOTEMPTY 66 /* Directory not empty */
-#define PEPGIO 99 /* postgres backend had problems */
-
-#endif /* LIBPQ_FS_H */
+#define PEPERM 1 /* Not owner */
+#define PENOENT 2 /* No such file or directory */
+#define PEACCES 13 /* Permission denied */
+#define PEEXIST 17 /* File exists */
+#define PENOTDIR 20 /* Not a directory */
+#define PEISDIR 21 /* Is a directory */
+#define PEINVAL 22 /* Invalid argument */
+#define PENAMETOOLONG 63 /* File name too long */
+#define PENOTEMPTY 66 /* Directory not empty */
+#define PEPGIO 99 /* postgres backend had problems */
+
+#endif /* LIBPQ_FS_H */
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index 080a1052deb..1b074cba118 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* libpq.h--
- * POSTGRES LIBPQ buffer structure definitions.
+ * POSTGRES LIBPQ buffer structure definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq.h,v 1.5 1996/11/05 07:38:17 scrappy Exp $
+ * $Id: libpq.h,v 1.6 1997/09/07 04:58:24 momjian Exp $
*
* NOTES
- * This file contains definitions for structures and
- * externs for functions used by both frontend applications
- * and the POSTGRES backend. See the files libpq-fe.h and
- * libpq-be.h for frontend/backend specific information
+ * This file contains definitions for structures and
+ * externs for functions used by both frontend applications
+ * and the POSTGRES backend. See the files libpq-fe.h and
+ * libpq-be.h for frontend/backend specific information
*
*-------------------------------------------------------------------------
*/
@@ -23,118 +23,130 @@
/* ----------------
* PQArgBlock --
- * Information (pointer to array of this structure) required
- * for the PQfn() call.
+ * Information (pointer to array of this structure) required
+ * for the PQfn() call.
* ----------------
*/
-typedef struct {
- int len;
- int isint;
- union {
- int *ptr; /* can't use void (dec compiler barfs) */
- int integer;
- } u;
-} PQArgBlock;
+typedef struct
+{
+ int len;
+ int isint;
+ union
+ {
+ int *ptr; /* can't use void (dec compiler barfs) */
+ int integer;
+ } u;
+} PQArgBlock;
/* ----------------
* TypeBlock --
- * Information about an attribute.
+ * Information about an attribute.
* ----------------
*/
#define NameLength 16
-typedef struct TypeBlock {
- char name[NAMEDATALEN]; /* name of the attribute */
- int adtid; /* adtid of the type */
- int adtsize; /* adtsize of the type */
-} TypeBlock;
+typedef struct TypeBlock
+{
+ char name[NAMEDATALEN]; /* name of the attribute */
+ int adtid; /* adtid of the type */
+ int adtsize; /* adtsize of the type */
+} TypeBlock;
/* ----------------
* TupleBlock --
- * Data of a tuple.
+ * Data of a tuple.
* ----------------
*/
#define TupleBlockSize 100
-typedef struct TupleBlock {
- char **values[TupleBlockSize]; /* an array of tuples */
- int *lengths[TupleBlockSize]; /* an array of length vec. foreach
- tuple */
- struct TupleBlock *next; /* next tuple block */
- int tuple_index; /* current tuple index */
-} TupleBlock;
+typedef struct TupleBlock
+{
+ char **values[TupleBlockSize]; /* an array of tuples */
+ int *lengths[TupleBlockSize]; /* an array of length vec.
+ * foreach tuple */
+ struct TupleBlock *next; /* next tuple block */
+ int tuple_index;/* current tuple index */
+} TupleBlock;
/* ----------------
* GroupBuffer --
- * A group of tuples with the same attributes.
+ * A group of tuples with the same attributes.
* ----------------
*/
-typedef struct GroupBuffer {
- int no_tuples; /* number of tuples in this group */
- int no_fields; /* number of attributes */
- TypeBlock *types; /* types of the attributes */
- TupleBlock *tuples; /* tuples in this group */
- struct GroupBuffer *next; /* next group */
-} GroupBuffer;
+typedef struct GroupBuffer
+{
+ int no_tuples; /* number of tuples in this group */
+ int no_fields; /* number of attributes */
+ TypeBlock *types; /* types of the attributes */
+ TupleBlock *tuples; /* tuples in this group */
+ struct GroupBuffer *next; /* next group */
+} GroupBuffer;
/* ----------------
* PortalBuffer --
- * Data structure of a portal buffer.
+ * Data structure of a portal buffer.
* ----------------
*/
-typedef struct PortalBuffer {
- int rule_p; /* 1 if this is an asynchronized portal. */
- int no_tuples; /* number of tuples in this portal buffer */
- int no_groups; /* number of tuple groups */
- GroupBuffer *groups; /* linked list of tuple groups */
-} PortalBuffer;
+typedef struct PortalBuffer
+{
+ int rule_p; /* 1 if this is an asynchronized portal. */
+ int no_tuples; /* number of tuples in this portal buffer */
+ int no_groups; /* number of tuple groups */
+ GroupBuffer *groups; /* linked list of tuple groups */
+} PortalBuffer;
/* ----------------
* PortalEntry --
- * an entry in the global portal table
+ * an entry in the global portal table
*
* Note: the portalcxt is only meaningful for PQcalls made from
- * within a postgres backend. frontend apps should ignore it.
+ * within a postgres backend. frontend apps should ignore it.
* ----------------
*/
#define PortalNameLength 32
-typedef struct PortalEntry {
- char name[PortalNameLength]; /* name of this portal */
- PortalBuffer *portal; /* tuples contained in this portal */
- Pointer portalcxt; /* memory context (for backend) */
- Pointer result; /* result for PQexec */
-} PortalEntry;
+typedef struct PortalEntry
+{
+ char name[PortalNameLength]; /* name of this portal */
+ PortalBuffer *portal; /* tuples contained in this portal */
+ Pointer portalcxt; /* memory context (for backend) */
+ Pointer result; /* result for PQexec */
+} PortalEntry;
#define PORTALS_INITIAL_SIZE 32
-#define PORTALS_GROW_BY 32
+#define PORTALS_GROW_BY 32
/* in portalbuf.c */
-extern PortalEntry** portals;
-extern size_t portals_array_size;
+extern PortalEntry **portals;
+extern size_t portals_array_size;
/*
- * Asynchronous notification
+ * Asynchronous notification
*/
-typedef struct PQNotifyList {
- char relname[NAMEDATALEN]; /* name of relation containing data */
- int be_pid; /* process id of backend */
- int valid; /* has this already been handled by user. */
-/* SLNode Node; */
-} PQNotifyList;
+typedef struct PQNotifyList
+{
+ char relname[NAMEDATALEN]; /* name of relation
+ * containing data */
+ int be_pid; /* process id of backend */
+ int valid; /* has this already been handled by user. */
+/* SLNode Node; */
+} PQNotifyList;
/*
* Exceptions.
*/
#define libpq_raise(X, Y) ExcRaise((Exception *)(X), (ExcDetail) (Y),\
- (ExcData)0, (ExcMessage) 0)
+ (ExcData)0, (ExcMessage) 0)
/* in portal.c */
-extern Exception MemoryError, PortalError, PostquelError, ProtocolError;
+extern Exception MemoryError,
+ PortalError,
+ PostquelError,
+ ProtocolError;
-/*
- * POSTGRES backend dependent Constants.
+/*
+ * POSTGRES backend dependent Constants.
*/
/* ERROR_MSG_LENGTH should really be the same as ELOG_MAXLEN in utils/elog.h*/
@@ -142,107 +154,111 @@ extern Exception MemoryError, PortalError, PostquelError, ProtocolError;
#define COMMAND_LENGTH 20
#define REMARK_LENGTH 80
-extern char PQerrormsg[ERROR_MSG_LENGTH]; /* in portal.c */
+extern char PQerrormsg[ERROR_MSG_LENGTH]; /* in portal.c */
/*
* External functions.
*/
-/*
- * prototypes for functions in portal.c
+/*
+ * prototypes for functions in portal.c
*/
-extern void pqdebug(char *target, char *msg);
-extern void pqdebug2(char *target, char *msg1, char *msg2);
-extern void PQtrace(void);
-extern void PQuntrace(void);
-extern int PQnportals(int rule_p);
-extern void PQpnames(char **pnames, int rule_p);
+extern void pqdebug(char *target, char *msg);
+extern void pqdebug2(char *target, char *msg1, char *msg2);
+extern void PQtrace(void);
+extern void PQuntrace(void);
+extern int PQnportals(int rule_p);
+extern void PQpnames(char **pnames, int rule_p);
extern PortalBuffer *PQparray(char *pname);
-extern int PQrulep(PortalBuffer *portal);
-extern int PQntuples(PortalBuffer *portal);
-extern int PQninstances(PortalBuffer *portal);
-extern int PQngroups(PortalBuffer *portal);
-extern int PQntuplesGroup(PortalBuffer *portal, int group_index);
-extern int PQninstancesGroup(PortalBuffer *portal, int group_index);
-extern int PQnfieldsGroup(PortalBuffer *portal, int group_index);
-extern int PQfnumberGroup(PortalBuffer *portal, int group_index, char *field_name);
-extern char *PQfnameGroup(PortalBuffer *portal, int group_index, int field_number);
-extern int PQftypeGroup(PortalBuffer *portal, int group_index,
- int field_number);
-extern int PQfsizeGroup(PortalBuffer *portal, int group_index,
- int field_number);
-extern GroupBuffer *PQgroup(PortalBuffer *portal, int tuple_index);
-extern int PQgetgroup(PortalBuffer *portal, int tuple_index);
-extern int PQnfields(PortalBuffer *portal, int tuple_index);
-extern int PQfnumber(PortalBuffer *portal, int tuple_index, char *field_name);
- extern char *PQfname(PortalBuffer *portal, int tuple_index, int field_number);
-extern int PQftype(PortalBuffer *portal, int tuple_index, int field_number);
-extern int PQfsize(PortalBuffer *portal, int tuple_index, int field_number);
-extern int PQsametype(PortalBuffer *portal, int tuple_index1, int tuple_index2);
-extern char *PQgetvalue(PortalBuffer *portal, int tuple_index, int field_number);
-extern char *PQgetAttr(PortalBuffer *portal, int tuple_index, int field_number);
-extern int PQgetlength(PortalBuffer *portal, int tuple_index, int field_number);
-extern void PQclear(char *pname);
-extern void PQcleanNotify(void);
-extern void PQnotifies_init(void);
+extern int PQrulep(PortalBuffer * portal);
+extern int PQntuples(PortalBuffer * portal);
+extern int PQninstances(PortalBuffer * portal);
+extern int PQngroups(PortalBuffer * portal);
+extern int PQntuplesGroup(PortalBuffer * portal, int group_index);
+extern int PQninstancesGroup(PortalBuffer * portal, int group_index);
+extern int PQnfieldsGroup(PortalBuffer * portal, int group_index);
+extern int PQfnumberGroup(PortalBuffer * portal, int group_index, char *field_name);
+extern char *PQfnameGroup(PortalBuffer * portal, int group_index, int field_number);
+extern int
+PQftypeGroup(PortalBuffer * portal, int group_index,
+ int field_number);
+extern int
+PQfsizeGroup(PortalBuffer * portal, int group_index,
+ int field_number);
+extern GroupBuffer *PQgroup(PortalBuffer * portal, int tuple_index);
+extern int PQgetgroup(PortalBuffer * portal, int tuple_index);
+extern int PQnfields(PortalBuffer * portal, int tuple_index);
+extern int PQfnumber(PortalBuffer * portal, int tuple_index, char *field_name);
+extern char *PQfname(PortalBuffer * portal, int tuple_index, int field_number);
+extern int PQftype(PortalBuffer * portal, int tuple_index, int field_number);
+extern int PQfsize(PortalBuffer * portal, int tuple_index, int field_number);
+extern int PQsametype(PortalBuffer * portal, int tuple_index1, int tuple_index2);
+extern char *PQgetvalue(PortalBuffer * portal, int tuple_index, int field_number);
+extern char *PQgetAttr(PortalBuffer * portal, int tuple_index, int field_number);
+extern int PQgetlength(PortalBuffer * portal, int tuple_index, int field_number);
+extern void PQclear(char *pname);
+extern void PQcleanNotify(void);
+extern void PQnotifies_init(void);
extern PQNotifyList *PQnotifies(void);
-extern void PQremoveNotify(PQNotifyList *nPtr);
-extern void PQappendNotify(char *relname, int pid);
-/*
- * prototypes for functions in portalbuf.c
+extern void PQremoveNotify(PQNotifyList * nPtr);
+extern void PQappendNotify(char *relname, int pid);
+
+/*
+ * prototypes for functions in portalbuf.c
*/
-extern caddr_t pbuf_alloc(size_t size);
-extern void pbuf_free(caddr_t pointer);
+extern caddr_t pbuf_alloc(size_t size);
+extern void pbuf_free(caddr_t pointer);
extern PortalBuffer *pbuf_addPortal(void);
-extern GroupBuffer *pbuf_addGroup(PortalBuffer *portal);
+extern GroupBuffer *pbuf_addGroup(PortalBuffer * portal);
extern TypeBlock *pbuf_addTypes(int n);
extern TupleBlock *pbuf_addTuples(void);
-extern char **pbuf_addTuple(int n);
-extern int *pbuf_addTupleValueLengths(int n);
-extern char *pbuf_addValues(int n);
+extern char **pbuf_addTuple(int n);
+extern int *pbuf_addTupleValueLengths(int n);
+extern char *pbuf_addValues(int n);
extern PortalEntry *pbuf_addEntry(void);
-extern void pbuf_freeEntry(int i);
-extern void pbuf_freeTypes(TypeBlock *types);
-extern void pbuf_freeTuples(TupleBlock *tuples, int no_tuples, int no_fields);
-extern void pbuf_freeGroup(GroupBuffer *group);
-extern void pbuf_freePortal(PortalBuffer *portal);
-extern int pbuf_getIndex(char *pname);
-extern void pbuf_setportalinfo(PortalEntry *entry, char *pname);
+extern void pbuf_freeEntry(int i);
+extern void pbuf_freeTypes(TypeBlock * types);
+extern void pbuf_freeTuples(TupleBlock * tuples, int no_tuples, int no_fields);
+extern void pbuf_freeGroup(GroupBuffer * group);
+extern void pbuf_freePortal(PortalBuffer * portal);
+extern int pbuf_getIndex(char *pname);
+extern void pbuf_setportalinfo(PortalEntry * entry, char *pname);
extern PortalEntry *pbuf_setup(char *pname);
-extern void pbuf_close(char *pname);
-extern GroupBuffer *pbuf_findGroup(PortalBuffer *portal, int group_index);
-extern int pbuf_findFnumber(GroupBuffer *group, char *field_name);
-extern void pbuf_checkFnumber(GroupBuffer *group, int field_number);
-extern char *pbuf_findFname(GroupBuffer *group, int field_number);
-
-/*
- * prototypes for functions in pqcomm.c
+extern void pbuf_close(char *pname);
+extern GroupBuffer *pbuf_findGroup(PortalBuffer * portal, int group_index);
+extern int pbuf_findFnumber(GroupBuffer * group, char *field_name);
+extern void pbuf_checkFnumber(GroupBuffer * group, int field_number);
+extern char *pbuf_findFname(GroupBuffer * group, int field_number);
+
+/*
+ * prototypes for functions in pqcomm.c
*/
-extern void pq_init(int fd);
-extern void pq_gettty(char *tp);
-extern int pq_getport(void);
-extern void pq_close(void);
-extern void pq_flush(void);
-extern int pq_getstr(char *s, int maxlen);
-extern int PQgetline(char *s, int maxlen);
-extern int PQputline(char *s);
-extern int pq_getnchar(char *s, int off, int maxlen);
-extern int pq_getint(int b);
-extern void pq_putstr(char *s);
-extern void pq_putnchar(char *s, int n);
-extern void pq_putint(int i, int b);
-extern int pq_sendoob(char *msg, int len);
-extern int pq_recvoob(char *msgPtr, int *lenPtr);
-extern int pq_getinaddr(struct sockaddr_in *sin, char *host, int port);
-extern int pq_getinserv(struct sockaddr_in *sin, char *host, char *serv);
-extern int pq_connect(char *dbname, char *user, char *args, char *hostName,
- char *debugTty, char *execFile, short portName);
-extern int StreamOpen(char *hostName, short portName, Port *port);
-extern void pq_regoob(void (*fptr)());
-extern void pq_unregoob(void);
-extern void pq_async_notify(void);
-extern int StreamServerPort(char *hostName, short portName, int *fdP);
-extern int StreamConnection(int server_fd, Port *port);
-extern void StreamClose(int sock);
-
-#endif /* LIBPQ_H */
+extern void pq_init(int fd);
+extern void pq_gettty(char *tp);
+extern int pq_getport(void);
+extern void pq_close(void);
+extern void pq_flush(void);
+extern int pq_getstr(char *s, int maxlen);
+extern int PQgetline(char *s, int maxlen);
+extern int PQputline(char *s);
+extern int pq_getnchar(char *s, int off, int maxlen);
+extern int pq_getint(int b);
+extern void pq_putstr(char *s);
+extern void pq_putnchar(char *s, int n);
+extern void pq_putint(int i, int b);
+extern int pq_sendoob(char *msg, int len);
+extern int pq_recvoob(char *msgPtr, int *lenPtr);
+extern int pq_getinaddr(struct sockaddr_in * sin, char *host, int port);
+extern int pq_getinserv(struct sockaddr_in * sin, char *host, char *serv);
+extern int
+pq_connect(char *dbname, char *user, char *args, char *hostName,
+ char *debugTty, char *execFile, short portName);
+extern int StreamOpen(char *hostName, short portName, Port * port);
+extern void pq_regoob(void (*fptr) ());
+extern void pq_unregoob(void);
+extern void pq_async_notify(void);
+extern int StreamServerPort(char *hostName, short portName, int *fdP);
+extern int StreamConnection(int server_fd, Port * port);
+extern void StreamClose(int sock);
+
+#endif /* LIBPQ_H */
diff --git a/src/include/libpq/password.h b/src/include/libpq/password.h
index f6b62140950..2b933553d59 100644
--- a/src/include/libpq/password.h
+++ b/src/include/libpq/password.h
@@ -6,7 +6,8 @@
#define PWFILE_NAME_SIZE USERMAP_NAME_SIZE
-int verify_password(char *user, char *password, Port *port,
- char *database, char *DataDir);
+int
+verify_password(char *user, char *password, Port * port,
+ char *database, char *DataDir);
#endif
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 53f0b970eb5..3aceb3de5b4 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* pqcomm.h--
- * Parameters for the communication module
+ * Parameters for the communication module
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pqcomm.h,v 1.10 1997/03/20 18:23:03 scrappy Exp $
+ * $Id: pqcomm.h,v 1.11 1997/09/07 04:58:26 momjian Exp $
*
* NOTES
- * Some of this should move to libpq.h
+ * Some of this should move to libpq.h
*
*-------------------------------------------------------------------------
*/
#ifndef PQCOMM_H
-#define PQCOMM_H
+#define PQCOMM_H
#include <stdio.h>
#include <sys/types.h>
@@ -24,126 +24,137 @@
/*
* startup msg parameters: path length, argument string length
*/
-#define PATH_SIZE 64
-#define ARGV_SIZE 64
+#define PATH_SIZE 64
+#define ARGV_SIZE 64
-/* The various kinds of startup messages are for the various kinds of
+/* The various kinds of startup messages are for the various kinds of
user authentication systems. In the beginning, there was only
STARTUP_MSG and all connections were unauthenticated. Now, there are
- several choices of authentication method (the client picks one, but
+ several choices of authentication method (the client picks one, but
the server needn't necessarily accept it). So now, the STARTUP_MSG
message means to start either an unauthenticated or a host-based
- authenticated connection, depending on what the server prefers. This
+ authenticated connection, depending on what the server prefers. This
is possible because the protocol between server and client is the same
in both cases (basically, no negotiation is required at all).
*/
-typedef enum _MsgType {
- ACK_MSG = 0, /* acknowledge a message */
- ERROR_MSG=1, /* error response to client from server */
- RESET_MSG=2, /* client must reset connection */
- PRINT_MSG=3, /* tuples for client from server */
- NET_ERROR=4, /* error in net system call */
- FUNCTION_MSG=5, /* fastpath call (unused) */
- QUERY_MSG=6, /* client query to server */
- STARTUP_MSG=7, /* initialize a connection with a backend */
- DUPLICATE_MSG=8, /* duplicate msg arrived (errors msg only) */
- INVALID_MSG=9, /* for some control functions */
- STARTUP_KRB4_MSG=10, /* krb4 session follows startup packet */
- STARTUP_KRB5_MSG=11, /* krb5 session follows startup packet */
- STARTUP_HBA_MSG=12, /* use host-based authentication */
- STARTUP_UNAUTH_MSG=13, /* use unauthenticated connection */
- STARTUP_PASSWORD_MSG=14 /* use plaintext password authentication */
- /* insert new values here -- DO NOT REORDER OR DELETE ENTRIES */
- /* also change LAST_AUTHENTICATION_TYPE below and add to the */
- /* authentication_type_name[] array in pqcomm.c */
+typedef enum _MsgType
+{
+ ACK_MSG = 0, /* acknowledge a message */
+ ERROR_MSG = 1, /* error response to client from server */
+ RESET_MSG = 2, /* client must reset connection */
+ PRINT_MSG = 3, /* tuples for client from server */
+ NET_ERROR = 4, /* error in net system call */
+ FUNCTION_MSG = 5, /* fastpath call (unused) */
+ QUERY_MSG = 6, /* client query to server */
+ STARTUP_MSG = 7, /* initialize a connection with a backend */
+ DUPLICATE_MSG = 8, /* duplicate msg arrived (errors msg only) */
+ INVALID_MSG = 9, /* for some control functions */
+ STARTUP_KRB4_MSG = 10, /* krb4 session follows startup packet */
+ STARTUP_KRB5_MSG = 11, /* krb5 session follows startup packet */
+ STARTUP_HBA_MSG = 12, /* use host-based authentication */
+ STARTUP_UNAUTH_MSG = 13, /* use unauthenticated connection */
+ STARTUP_PASSWORD_MSG = 14 /* use plaintext password authentication */
+ /* insert new values here -- DO NOT REORDER OR DELETE ENTRIES */
+ /* also change LAST_AUTHENTICATION_TYPE below and add to the */
+ /* authentication_type_name[] array in pqcomm.c */
} MsgType;
#define LAST_AUTHENTICATION_TYPE 14
-typedef char *Addr;
-typedef int PacketLen; /* packet length */
+typedef char *Addr;
+typedef int PacketLen; /* packet length */
-typedef struct StartupInfo {
-/* PacketHdr hdr; */
- char database[PATH_SIZE]; /* database name */
- char user[NAMEDATALEN]; /* user name */
- char options[ARGV_SIZE]; /* possible additional args */
- char execFile[ARGV_SIZE]; /* possible backend to use */
- char tty[PATH_SIZE]; /* possible tty for debug output*/
-} StartupInfo;
+typedef struct StartupInfo
+{
+/* PacketHdr hdr; */
+ char database[PATH_SIZE]; /* database name */
+ char user[NAMEDATALEN]; /* user name */
+ char options[ARGV_SIZE]; /* possible additional args */
+ char execFile[ARGV_SIZE]; /* possible backend to use */
+ char tty[PATH_SIZE]; /* possible tty for debug output */
+} StartupInfo;
/* amount of available data in a packet buffer */
-#define MESSAGE_SIZE sizeof(StartupInfo) + 5 /* why 5? BJM 2/11/97 */
+#define MESSAGE_SIZE sizeof(StartupInfo) + 5 /* why 5? BJM 2/11/97 */
/* I/O can be blocking or non-blocking */
-#define BLOCKING (FALSE)
+#define BLOCKING (FALSE)
#define NON_BLOCKING (TRUE)
/* a PacketBuf gets shipped from client to server so be careful
- of differences in representation.
+ of differences in representation.
Be sure to use htonl() and ntohl() on the len and msgtype fields! */
-typedef struct PacketBuf {
- int len;
- MsgType msgtype;
- char data[MESSAGE_SIZE];
-} PacketBuf;
-
-/* update the conversion routines
+typedef struct PacketBuf
+{
+ int len;
+ MsgType msgtype;
+ char data[MESSAGE_SIZE];
+} PacketBuf;
+
+/* update the conversion routines
StartupInfo2PacketBuf() and PacketBuf2StartupInfo() (decl. below)
if StartupInfo or PacketBuf structs ever change */
/*
- * socket descriptor port
- * we need addresses of both sides to do authentication calls
+ * socket descriptor port
+ * we need addresses of both sides to do authentication calls
*/
-typedef struct Port {
- int sock; /* file descriptor */
- int mask; /* select mask */
- int nBytes; /* nBytes read in so far */
- struct sockaddr_in laddr; /* local addr (us) */
- struct sockaddr_in raddr; /* remote addr (them) */
-/* PacketBufId id;*/ /* id of packet buf currently in use */
- PacketBuf buf; /* stream implementation (curr pack buf) */
-} Port;
+typedef struct Port
+{
+ int sock; /* file descriptor */
+ int mask; /* select mask */
+ int nBytes; /* nBytes read in so far */
+ struct sockaddr_in laddr; /* local addr (us) */
+ struct sockaddr_in raddr; /* remote addr (them) */
+
+ /*
+ * PacketBufId id;*//* id of packet buf currently in
+ * use
+ */
+ PacketBuf buf; /* stream implementation (curr pack buf) */
+} Port;
/* invalid socket descriptor */
#define INVALID_SOCK (-1)
#define INVALID_ID (-1)
-#define MAX_CONNECTIONS 10
-#define N_PACK_BUFS 20
+#define MAX_CONNECTIONS 10
+#define N_PACK_BUFS 20
/* no multi-packet messages yet */
-#define MAX_PACKET_BACKLOG 1
+#define MAX_PACKET_BACKLOG 1
-#define DEFAULT_STRING ""
+#define DEFAULT_STRING ""
-extern FILE *Pfout, *Pfin;
-extern int PQAsyncNotifyWaiting;
+extern FILE *Pfout,
+ *Pfin;
+extern int PQAsyncNotifyWaiting;
/* in pqcompriv.c */
-int pqGetShort(int *, FILE *);
-int pqGetLong(int *, FILE *);
-int pqGetNBytes(char *, size_t, FILE *);
-int pqGetString(char *, size_t, FILE *);
-int pqGetByte(FILE *);
-
-int pqPutShort(int, FILE *);
-int pqPutLong(int, FILE *);
-int pqPutNBytes(const char *, size_t, FILE *);
-int pqPutString(const char *, FILE *);
-int pqPutByte(int, FILE *);
+int pqGetShort(int *, FILE *);
+int pqGetLong(int *, FILE *);
+int pqGetNBytes(char *, size_t, FILE *);
+int pqGetString(char *, size_t, FILE *);
+int pqGetByte(FILE *);
+
+int pqPutShort(int, FILE *);
+int pqPutLong(int, FILE *);
+int pqPutNBytes(const char *, size_t, FILE *);
+int pqPutString(const char *, FILE *);
+int pqPutByte(int, FILE *);
/*
* prototypes for functions in pqpacket.c
*/
-extern int PacketReceive(Port *port, PacketBuf *buf, char nonBlocking);
-extern int PacketSend(Port *port, PacketBuf *buf,
- PacketLen len, char nonBlocking);
+extern int PacketReceive(Port * port, PacketBuf * buf, char nonBlocking);
+extern int
+PacketSend(Port * port, PacketBuf * buf,
+ PacketLen len, char nonBlocking);
+
/* extern PacketBuf* StartupInfo2PacketBuf(StartupInfo*); */
/* extern StartupInfo* PacketBuf2StartupInfo(PacketBuf*); */
-extern char *name_of_authentication_type(int type);
+extern char *name_of_authentication_type(int type);
-#endif /* PQCOMM_H */
+#endif /* PQCOMM_H */
diff --git a/src/include/libpq/pqsignal.h b/src/include/libpq/pqsignal.h
index 389667c859d..69bdb21df7e 100644
--- a/src/include/libpq/pqsignal.h
+++ b/src/include/libpq/pqsignal.h
@@ -1,24 +1,24 @@
/*-------------------------------------------------------------------------
*
* pqsignal.h--
- * prototypes for the reliable BSD-style signal(2) routine.
+ * prototypes for the reliable BSD-style signal(2) routine.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pqsignal.h,v 1.5 1996/12/26 22:08:13 momjian Exp $
+ * $Id: pqsignal.h,v 1.6 1997/09/07 04:58:27 momjian Exp $
*
* NOTES
- * This shouldn't be in libpq, but the monitor and some other
- * things need it...
+ * This shouldn't be in libpq, but the monitor and some other
+ * things need it...
*
*-------------------------------------------------------------------------
*/
#ifndef PQSIGNAL_H
#define PQSIGNAL_H
-typedef void (*pqsigfunc)(int);
+typedef void (*pqsigfunc) (int);
extern pqsigfunc pqsignal(int signo, pqsigfunc func);
-#endif /* PQSIGNAL_H */
+#endif /* PQSIGNAL_H */
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index e3566638832..3738bd739cd 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* miscadmin.h--
- * this file contains general postgres administration and initialization
- * stuff that used to be spread out between the following files:
- * globals.h global variables
- * pdir.h directory path crud
- * pinit.h postgres initialization
- * pmod.h processing modes
+ * this file contains general postgres administration and initialization
+ * stuff that used to be spread out between the following files:
+ * globals.h global variables
+ * pdir.h directory path crud
+ * pinit.h postgres initialization
+ * pmod.h processing modes
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: miscadmin.h,v 1.11 1997/08/19 21:37:03 momjian Exp $
+ * $Id: miscadmin.h,v 1.12 1997/09/07 04:55:37 momjian Exp $
*
* NOTES
- * some of the information in this file will be moved to
- * other files.
+ * some of the information in this file will be moved to
+ * other files.
*
*-------------------------------------------------------------------------
*/
@@ -23,24 +23,24 @@
#define MISCADMIN_H
/*****************************************************************************
- * globals.h -- *
+ * globals.h -- *
*****************************************************************************/
/*
* from postmaster/postmaster.c
*/
-extern int PostmasterMain(int argc, char* argv[]);
+extern int PostmasterMain(int argc, char *argv[]);
/*
* from utils/init/globals.c
*/
-extern int Portfd;
-extern int Noversion;
-extern int MasterPid;
-extern int Quiet;
-extern char *DataDir;
+extern int Portfd;
+extern int Noversion;
+extern int MasterPid;
+extern int Quiet;
+extern char *DataDir;
-extern char OutputFileName[];
+extern char OutputFileName[];
/*
* done in storage/backendid.h for now.
@@ -48,21 +48,21 @@ extern char OutputFileName[];
* extern BackendId MyBackendId;
* extern BackendTag MyBackendTag;
*/
-extern bool MyDatabaseIdIsInitialized;
-extern Oid MyDatabaseId;
-extern bool TransactionInitWasProcessed;
+extern bool MyDatabaseIdIsInitialized;
+extern Oid MyDatabaseId;
+extern bool TransactionInitWasProcessed;
-extern bool IsUnderPostmaster;
-extern bool IsPostmaster;
+extern bool IsUnderPostmaster;
+extern bool IsPostmaster;
-extern short DebugLvl;
+extern short DebugLvl;
/* Date/Time Configuration
*
* Constants to pass info from runtime environment:
- * USE_POSTGRES_DATES specifies traditional postgres format for output.
- * USE_ISO_DATES specifies ISO-compliant format for output.
- * USE_SQL_DATES specified Oracle/Ingres-compliant format for output.
+ * USE_POSTGRES_DATES specifies traditional postgres format for output.
+ * USE_ISO_DATES specifies ISO-compliant format for output.
+ * USE_SQL_DATES specified Oracle/Ingres-compliant format for output.
*
* DateStyle specifies preference for date formatting for output.
* EuroDates if client prefers dates interpreted and written w/European conventions.
@@ -73,120 +73,121 @@ extern short DebugLvl;
* CTZName is the timezone label.
*/
-#define MAXTZLEN 7
+#define MAXTZLEN 7
-#define USE_POSTGRES_DATES 0
-#define USE_ISO_DATES 1
-#define USE_SQL_DATES 2
+#define USE_POSTGRES_DATES 0
+#define USE_ISO_DATES 1
+#define USE_SQL_DATES 2
-extern int DateStyle;
-extern bool EuroDates;
-extern bool HasCTZSet;
-extern bool CDayLight;
-extern int CTimeZone;
-extern char CTZName[];
+extern int DateStyle;
+extern bool EuroDates;
+extern bool HasCTZSet;
+extern bool CDayLight;
+extern int CTimeZone;
+extern char CTZName[];
-extern char FloatFormat[];
-extern char DateFormat[];
+extern char FloatFormat[];
+extern char DateFormat[];
-extern int fsyncOff;
-extern int SortMem;
+extern int fsyncOff;
+extern int SortMem;
-extern Oid LastOidProcessed; /* for query rewrite */
+extern Oid LastOidProcessed; /* for query rewrite */
#define MAX_PARSE_BUFFER 8192
-/*
- * default number of buffers in buffer pool
- *
+/*
+ * default number of buffers in buffer pool
+ *
*/
#define NDBUFS 64
/*****************************************************************************
- * pdir.h -- *
- * POSTGRES directory path definitions. *
+ * pdir.h -- *
+ * POSTGRES directory path definitions. *
*****************************************************************************/
/* now in utils/init/miscinit.c */
-extern char *GetDatabasePath(void);
-extern char *GetDatabaseName(void);
-extern void SetDatabaseName(char *name);
-extern void SetDatabasePath(char *path);
-extern char *getpgusername(void);
-extern void SetPgUserName(void);
-extern Oid GetUserId(void);
-extern void SetUserId(void);
-extern int ValidateBackend(char *path);
-extern int FindBackend(char *backend, char *argv0);
-extern int CheckPathAccess(char *path, char *name, int open_mode);
+extern char *GetDatabasePath(void);
+extern char *GetDatabaseName(void);
+extern void SetDatabaseName(char *name);
+extern void SetDatabasePath(char *path);
+extern char *getpgusername(void);
+extern void SetPgUserName(void);
+extern Oid GetUserId(void);
+extern void SetUserId(void);
+extern int ValidateBackend(char *path);
+extern int FindBackend(char *backend, char *argv0);
+extern int CheckPathAccess(char *path, char *name, int open_mode);
/* lower case version for case-insensitive SQL referenced in pg_proc.h */
#define GetPgUserName() getpgusername()
/*****************************************************************************
- * pmod.h -- *
- * POSTGRES processing mode definitions. *
+ * pmod.h -- *
+ * POSTGRES processing mode definitions. *
*****************************************************************************/
/*
* Description:
- * There are four processing modes in POSTGRES. They are NoProcessing
+ * There are four processing modes in POSTGRES. They are NoProcessing
* or "none," BootstrapProcessing or "bootstrap," InitProcessing or
* "initialization," and NormalProcessing or "normal."
*
- * If a POSTGRES binary is in normal mode, then all code may be executed
+ * If a POSTGRES binary is in normal mode, then all code may be executed
* normally. In the none mode, only bookkeeping code may be called. In
* particular, access method calls may not occur in this mode since the
* execution state is outside a transaction.
*
- * The final two processing modes are used during special times. When the
+ * The final two processing modes are used during special times. When the
* system state indicates bootstrap processing, transactions are all given
- * transaction id "one" and are consequently guarenteed to commit. This mode
+ * transaction id "one" and are consequently guarenteed to commit. This mode
* is used during the initial generation of template databases.
*
* Finally, the execution state is in initialization mode until all normal
- * initialization is complete. Some code behaves differently when executed in
+ * initialization is complete. Some code behaves differently when executed in
* this mode to enable system bootstrapping.
*/
-typedef enum ProcessingMode {
- NoProcessing, /* "nothing" can be done */
- BootstrapProcessing, /* bootstrap creation of template database */
- InitProcessing, /* initializing system */
- NormalProcessing /* normal processing */
-} ProcessingMode;
+typedef enum ProcessingMode
+{
+ NoProcessing, /* "nothing" can be done */
+ BootstrapProcessing, /* bootstrap creation of template database */
+ InitProcessing, /* initializing system */
+ NormalProcessing /* normal processing */
+} ProcessingMode;
/*****************************************************************************
- * pinit.h -- *
- * POSTGRES initialization and cleanup definitions. *
+ * pinit.h -- *
+ * POSTGRES initialization and cleanup definitions. *
*****************************************************************************/
/*
* Note:
- * XXX AddExitHandler not defined yet.
+ * XXX AddExitHandler not defined yet.
*/
-typedef int16 ExitStatus;
+typedef int16 ExitStatus;
-#define NormalExitStatus (0)
-#define FatalExitStatus (127)
+#define NormalExitStatus (0)
+#define FatalExitStatus (127)
/* XXX are there any other meaningful exit codes? */
/* in utils/init/postinit.c */
-extern bool PostgresIsInitialized;
+extern bool PostgresIsInitialized;
-extern void InitPostgres(char *name);
+extern void InitPostgres(char *name);
/* in miscinit.c */
-extern void ExitPostgres(ExitStatus status);
-extern void StatusBackendExit(int status);
-extern void StatusPostmasterExit(int status);
-
-extern bool IsNoProcessingMode(void);
-extern bool IsBootstrapProcessingMode(void);
-extern bool IsInitProcessingMode(void);
-extern bool IsNormalProcessingMode(void);
-extern void SetProcessingMode(ProcessingMode mode);
+extern void ExitPostgres(ExitStatus status);
+extern void StatusBackendExit(int status);
+extern void StatusPostmasterExit(int status);
+
+extern bool IsNoProcessingMode(void);
+extern bool IsBootstrapProcessingMode(void);
+extern bool IsInitProcessingMode(void);
+extern bool IsNormalProcessingMode(void);
+extern void SetProcessingMode(ProcessingMode mode);
extern ProcessingMode GetProcessingMode(void);
-#endif /* MISCADMIN_H */
+#endif /* MISCADMIN_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 7cf450785c9..870bdd80186 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* execnodes.h--
- * definitions for executor state nodes
+ * definitions for executor state nodes
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: execnodes.h,v 1.8 1997/08/27 09:04:52 vadim Exp $
+ * $Id: execnodes.h,v 1.9 1997/09/07 04:58:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,660 +23,680 @@
#include <access/funcindex.h>
/* ----------------
- * IndexInfo information
+ * IndexInfo information
*
- * this class holds the information saying what attributes
- * are the key attributes for this index. -cim 10/15/89
+ * this class holds the information saying what attributes
+ * are the key attributes for this index. -cim 10/15/89
*
- * NumKeyAttributes number of key attributes for this index
- * KeyAttributeNumbers array of attribute numbers used as keys
- * Predicate partial-index predicate for this index
+ * NumKeyAttributes number of key attributes for this index
+ * KeyAttributeNumbers array of attribute numbers used as keys
+ * Predicate partial-index predicate for this index
* ----------------
*/
-typedef struct IndexInfo {
- NodeTag type;
- int ii_NumKeyAttributes;
- AttrNumber *ii_KeyAttributeNumbers;
- FuncIndexInfoPtr ii_FuncIndexInfo;
- Node *ii_Predicate;
-} IndexInfo;
+typedef struct IndexInfo
+{
+ NodeTag type;
+ int ii_NumKeyAttributes;
+ AttrNumber *ii_KeyAttributeNumbers;
+ FuncIndexInfoPtr ii_FuncIndexInfo;
+ Node *ii_Predicate;
+} IndexInfo;
/* ----------------
- * RelationInfo information
- *
- * whenever we update an existing relation, we have to
- * update indices on the relation. The RelationInfo class
- * is used to hold all the information on result relations,
- * including indices.. -cim 10/15/89
- *
- * RangeTableIndex result relation's range table index
- * RelationDesc relation descriptor for result relation
- * NumIndices number indices existing on result relation
- * IndexRelationDescs array of relation descriptors for indices
- * IndexRelationInfo array of key/attr info for indices
+ * RelationInfo information
+ *
+ * whenever we update an existing relation, we have to
+ * update indices on the relation. The RelationInfo class
+ * is used to hold all the information on result relations,
+ * including indices.. -cim 10/15/89
+ *
+ * RangeTableIndex result relation's range table index
+ * RelationDesc relation descriptor for result relation
+ * NumIndices number indices existing on result relation
+ * IndexRelationDescs array of relation descriptors for indices
+ * IndexRelationInfo array of key/attr info for indices
* ----------------
*/
-typedef struct RelationInfo {
- NodeTag type;
- Index ri_RangeTableIndex;
- Relation ri_RelationDesc;
- int ri_NumIndices;
- RelationPtr ri_IndexRelationDescs;
- IndexInfo **ri_IndexRelationInfo;
-} RelationInfo;
+typedef struct RelationInfo
+{
+ NodeTag type;
+ Index ri_RangeTableIndex;
+ Relation ri_RelationDesc;
+ int ri_NumIndices;
+ RelationPtr ri_IndexRelationDescs;
+ IndexInfo **ri_IndexRelationInfo;
+} RelationInfo;
/* ----------------
- * ExprContext
- *
- * This class holds the "current context" information
- * needed to evaluate expressions for doing tuple qualifications
- * and tuple projections. For example, if an expression refers
- * to an attribute in the current inner tuple then we need to know
- * what the current inner tuple is and so we look at the expression
- * context.
+ * ExprContext
+ *
+ * This class holds the "current context" information
+ * needed to evaluate expressions for doing tuple qualifications
+ * and tuple projections. For example, if an expression refers
+ * to an attribute in the current inner tuple then we need to know
+ * what the current inner tuple is and so we look at the expression
+ * context.
* ----------------
*/
-typedef struct ExprContext {
- NodeTag type;
- TupleTableSlot *ecxt_scantuple;
- TupleTableSlot *ecxt_innertuple;
- TupleTableSlot *ecxt_outertuple;
- Relation ecxt_relation;
- Index ecxt_relid;
- ParamListInfo ecxt_param_list_info;
- List *ecxt_range_table;
- Datum *ecxt_values; /* precomputed values for aggreg */
- char *ecxt_nulls; /* null flags for aggreg values */
-} ExprContext;
+typedef struct ExprContext
+{
+ NodeTag type;
+ TupleTableSlot *ecxt_scantuple;
+ TupleTableSlot *ecxt_innertuple;
+ TupleTableSlot *ecxt_outertuple;
+ Relation ecxt_relation;
+ Index ecxt_relid;
+ ParamListInfo ecxt_param_list_info;
+ List *ecxt_range_table;
+ Datum *ecxt_values;/* precomputed values for aggreg */
+ char *ecxt_nulls; /* null flags for aggreg values */
+} ExprContext;
/* ----------------
- * ProjectionInfo node information
- *
- * This is all the information needed to preform projections
- * on a tuple. Nodes which need to do projections create one
- * of these. In theory, when a node wants to preform a projection
- * it should just update this information as necessary and then
- * call ExecProject(). -cim 6/3/91
- *
- * targetlist target list for projection
- * len length of target list
- * tupValue array of pointers to projection results
- * exprContext expression context for ExecTargetList
- * slot slot to place projection result in
+ * ProjectionInfo node information
+ *
+ * This is all the information needed to preform projections
+ * on a tuple. Nodes which need to do projections create one
+ * of these. In theory, when a node wants to preform a projection
+ * it should just update this information as necessary and then
+ * call ExecProject(). -cim 6/3/91
+ *
+ * targetlist target list for projection
+ * len length of target list
+ * tupValue array of pointers to projection results
+ * exprContext expression context for ExecTargetList
+ * slot slot to place projection result in
* ----------------
*/
-typedef struct ProjectionInfo {
- NodeTag type;
- List *pi_targetlist;
- int pi_len;
- Datum *pi_tupValue;
- ExprContext *pi_exprContext;
- TupleTableSlot *pi_slot;
-} ProjectionInfo;
+typedef struct ProjectionInfo
+{
+ NodeTag type;
+ List *pi_targetlist;
+ int pi_len;
+ Datum *pi_tupValue;
+ ExprContext *pi_exprContext;
+ TupleTableSlot *pi_slot;
+} ProjectionInfo;
/* ----------------
- * JunkFilter
- *
- * this class is used to store information regarding junk attributes.
- * A junk attribute is an attribute in a tuple that is needed only for
- * storing intermediate information in the executor, and does not belong
- * in the tuple proper. For example, when we do a delete or replace
- * query, the planner adds an entry to the targetlist so that the tuples
- * returned to ExecutePlan() contain an extra attribute: the t_ctid of
- * the tuple to be deleted/replaced. This is needed for amdelete() and
- * amreplace(). In doing a delete this does not make much of a
- * difference, but in doing a replace we have to make sure we disgard
- * all the junk in a tuple before calling amreplace(). Otherwise the
- * inserted tuple will not have the correct schema. This solves a
- * problem with hash-join and merge-sort replace plans. -cim 10/10/90
- *
- * targetList: the original target list (including junk attributes).
- * length: the length of 'targetList'.
- * tupType: the tuple descriptor for the "original" tuple
- * (including the junk attributes).
- * cleanTargetList: the "clean" target list (junk attributes removed).
- * cleanLength: the length of 'cleanTargetList'
- * cleanTupTyp: the tuple descriptor of the "clean" tuple (with
- * junk attributes removed).
- * cleanMap: A map with the correspondance between the non junk
- * attributes of the "original" tuple and the
- * attributes of the "clean" tuple.
+ * JunkFilter
+ *
+ * this class is used to store information regarding junk attributes.
+ * A junk attribute is an attribute in a tuple that is needed only for
+ * storing intermediate information in the executor, and does not belong
+ * in the tuple proper. For example, when we do a delete or replace
+ * query, the planner adds an entry to the targetlist so that the tuples
+ * returned to ExecutePlan() contain an extra attribute: the t_ctid of
+ * the tuple to be deleted/replaced. This is needed for amdelete() and
+ * amreplace(). In doing a delete this does not make much of a
+ * difference, but in doing a replace we have to make sure we disgard
+ * all the junk in a tuple before calling amreplace(). Otherwise the
+ * inserted tuple will not have the correct schema. This solves a
+ * problem with hash-join and merge-sort replace plans. -cim 10/10/90
+ *
+ * targetList: the original target list (including junk attributes).
+ * length: the length of 'targetList'.
+ * tupType: the tuple descriptor for the "original" tuple
+ * (including the junk attributes).
+ * cleanTargetList: the "clean" target list (junk attributes removed).
+ * cleanLength: the length of 'cleanTargetList'
+ * cleanTupTyp: the tuple descriptor of the "clean" tuple (with
+ * junk attributes removed).
+ * cleanMap: A map with the correspondance between the non junk
+ * attributes of the "original" tuple and the
+ * attributes of the "clean" tuple.
* ----------------
*/
-typedef struct JunkFilter {
- NodeTag type;
- List *jf_targetList;
- int jf_length;
- TupleDesc jf_tupType;
- List *jf_cleanTargetList;
- int jf_cleanLength;
- TupleDesc jf_cleanTupType;
- AttrNumber *jf_cleanMap;
-} JunkFilter;
+typedef struct JunkFilter
+{
+ NodeTag type;
+ List *jf_targetList;
+ int jf_length;
+ TupleDesc jf_tupType;
+ List *jf_cleanTargetList;
+ int jf_cleanLength;
+ TupleDesc jf_cleanTupType;
+ AttrNumber *jf_cleanMap;
+} JunkFilter;
/* ----------------
- * EState information
+ * EState information
*
- * direction direction of the scan
+ * direction direction of the scan
*
- * range_table array of scan relation information
+ * range_table array of scan relation information
*
- * result_relation_information for update queries
+ * result_relation_information for update queries
*
- * into_relation_descriptor relation being retrieved "into"
+ * into_relation_descriptor relation being retrieved "into"
*
- * param_list_info information needed to transform
- * Param nodes into Const nodes
+ * param_list_info information needed to transform
+ * Param nodes into Const nodes
*
- * BaseId during InitPlan(), each node is
- * given a number. this is the next
- * number to be assigned.
+ * BaseId during InitPlan(), each node is
+ * given a number. this is the next
+ * number to be assigned.
*
- * tupleTable this is a pointer to an array
- * of pointers to tuples used by
- * the executor at any given moment.
+ * tupleTable this is a pointer to an array
+ * of pointers to tuples used by
+ * the executor at any given moment.
*
- * junkFilter contains information used to
- * extract junk attributes from a tuple.
- * (see JunkFilter above)
+ * junkFilter contains information used to
+ * extract junk attributes from a tuple.
+ * (see JunkFilter above)
*
- * refcount local buffer refcounts used in
- * an ExecMain cycle. this is introduced
- * to avoid ExecStart's unpinning each
- * other's buffers when called recursively
- * ----------------
+ * refcount local buffer refcounts used in
+ * an ExecMain cycle. this is introduced
+ * to avoid ExecStart's unpinning each
+ * other's buffers when called recursively
+ * ----------------
*/
-typedef struct EState {
- NodeTag type;
- ScanDirection es_direction;
- List *es_range_table;
- RelationInfo *es_result_relation_info;
- Relation es_into_relation_descriptor;
- ParamListInfo es_param_list_info;
- int es_BaseId;
- TupleTable es_tupleTable;
- JunkFilter *es_junkFilter;
- int *es_refcount;
- uint32 es_processed; /* # of tuples processed */
- Oid es_lastoid; /* last oid processed (by INSERT) */
-} EState;
+typedef struct EState
+{
+ NodeTag type;
+ ScanDirection es_direction;
+ List *es_range_table;
+ RelationInfo *es_result_relation_info;
+ Relation es_into_relation_descriptor;
+ ParamListInfo es_param_list_info;
+ int es_BaseId;
+ TupleTable es_tupleTable;
+ JunkFilter *es_junkFilter;
+ int *es_refcount;
+ uint32 es_processed; /* # of tuples processed */
+ Oid es_lastoid; /* last oid processed (by INSERT) */
+} EState;
/* ----------------
- * Executor Type information needed by plannodes.h
- *
- *| Note: the bogus classes CommonState and CommonScanState exist only
- *| because our inheritance system only allows single inheritance
- *| and we have to have unique slot names. Hence two or more
- *| classes which want to have a common slot must ALL inherit
- *| the slot from some other class. (This is a big hack to
- *| allow our classes to share slot names..)
+ * Executor Type information needed by plannodes.h
+ *
+ *| Note: the bogus classes CommonState and CommonScanState exist only
+ *| because our inheritance system only allows single inheritance
+ *| and we have to have unique slot names. Hence two or more
+ *| classes which want to have a common slot must ALL inherit
+ *| the slot from some other class. (This is a big hack to
+ *| allow our classes to share slot names..)
*|
- *| Example:
- *| the class Result and the class NestLoop nodes both want
- *| a slot called "OuterTuple" so they both have to inherit
- *| it from some other class. In this case they inherit
- *| it from CommonState. "CommonState" and "CommonScanState" are
- *| the best names I could come up with for this sort of
- *| stuff.
+ *| Example:
+ *| the class Result and the class NestLoop nodes both want
+ *| a slot called "OuterTuple" so they both have to inherit
+ *| it from some other class. In this case they inherit
+ *| it from CommonState. "CommonState" and "CommonScanState" are
+ *| the best names I could come up with for this sort of
+ *| stuff.
*|
- *| As a result, many classes have extra slots which they
- *| don't use. These slots are denoted (unused) in the
- *| comment preceeding the class definition. If you
- *| comes up with a better idea of a way of doing things
- *| along these lines, then feel free to make your idea
- *| known to me.. -cim 10/15/89
+ *| As a result, many classes have extra slots which they
+ *| don't use. These slots are denoted (unused) in the
+ *| comment preceeding the class definition. If you
+ *| comes up with a better idea of a way of doing things
+ *| along these lines, then feel free to make your idea
+ *| known to me.. -cim 10/15/89
* ----------------
*/
/* ----------------------------------------------------------------
- * Common Executor State Information
+ * Common Executor State Information
* ----------------------------------------------------------------
*/
-/* BaseNode removed -- base_id moved into CommonState - jolly */
+/* BaseNode removed -- base_id moved into CommonState - jolly */
/* ----------------
- * CommonState information
+ * CommonState information
*
- *| this is a bogus class used to hold slots so other
- *| nodes can inherit them...
+ *| this is a bogus class used to hold slots so other
+ *| nodes can inherit them...
*
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
*
* ----------------
*/
-typedef struct CommonState {
- NodeTag type; /* its first field is NodeTag */
- int cs_base_id;
- TupleTableSlot *cs_OuterTupleSlot;
- TupleTableSlot *cs_ResultTupleSlot;
- ExprContext *cs_ExprContext;
- ProjectionInfo *cs_ProjInfo;
- bool cs_TupFromTlist;
-} CommonState;
+typedef struct CommonState
+{
+ NodeTag type; /* its first field is NodeTag */
+ int cs_base_id;
+ TupleTableSlot *cs_OuterTupleSlot;
+ TupleTableSlot *cs_ResultTupleSlot;
+ ExprContext *cs_ExprContext;
+ ProjectionInfo *cs_ProjInfo;
+ bool cs_TupFromTlist;
+} CommonState;
/* ----------------------------------------------------------------
- * Control Node State Information
+ * Control Node State Information
* ----------------------------------------------------------------
*/
/* ----------------
- * ResultState information
+ * ResultState information
*
- * done flag which tells us to quit when we
- * have already returned a constant tuple.
+ * done flag which tells us to quit when we
+ * have already returned a constant tuple.
*
- * CommonState information
+ * CommonState information
*
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef struct ResultState {
- CommonState cstate; /* its first field is NodeTag */
- int rs_done;
-} ResultState;
+typedef struct ResultState
+{
+ CommonState cstate; /* its first field is NodeTag */
+ int rs_done;
+} ResultState;
/* ----------------
- * AppendState information
- *
- * append nodes have this field "unionplans" which is this
- * list of plans to execute in sequence.. these variables
- * keep track of things..
- *
- * whichplan which plan is being executed
- * nplans how many plans are in the list
- * initialized array of ExecInitNode() results
- * rtentries range table for the current plan
- * result_relation_info_list array of each subplan's result relation info
- * junkFilter_list array of each subplan's junk filter
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * AppendState information
+ *
+ * append nodes have this field "unionplans" which is this
+ * list of plans to execute in sequence.. these variables
+ * keep track of things..
+ *
+ * whichplan which plan is being executed
+ * nplans how many plans are in the list
+ * initialized array of ExecInitNode() results
+ * rtentries range table for the current plan
+ * result_relation_info_list array of each subplan's result relation info
+ * junkFilter_list array of each subplan's junk filter
+ *
+ * CommonState information
+ *
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef struct AppendState {
- CommonState cstate; /* its first field is NodeTag */
- int as_whichplan;
- int as_nplans;
- bool *as_initialized;
- List *as_rtentries;
- List *as_result_relation_info_list;
- List *as_junkFilter_list;
-} AppendState;
+typedef struct AppendState
+{
+ CommonState cstate; /* its first field is NodeTag */
+ int as_whichplan;
+ int as_nplans;
+ bool *as_initialized;
+ List *as_rtentries;
+ List *as_result_relation_info_list;
+ List *as_junkFilter_list;
+} AppendState;
/* ----------------------------------------------------------------
- * Scan State Information
+ * Scan State Information
* ----------------------------------------------------------------
*/
/* ----------------
- * CommonScanState information
+ * CommonScanState information
*
- * CommonScanState is a class like CommonState, but is used more
- * by the nodes like SeqScan and Sort which want to
- * keep track of an underlying relation.
+ * CommonScanState is a class like CommonState, but is used more
+ * by the nodes like SeqScan and Sort which want to
+ * keep track of an underlying relation.
*
- * currentRelation relation being scanned
- * currentScanDesc current scan descriptor for scan
- * ScanTupleSlot pointer to slot in tuple table holding scan tuple
+ * currentRelation relation being scanned
+ * currentScanDesc current scan descriptor for scan
+ * ScanTupleSlot pointer to slot in tuple table holding scan tuple
*
- * CommonState information
+ * CommonState information
*
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef struct CommonScanState {
- CommonState cstate; /* its first field is NodeTag */
- Relation css_currentRelation;
- HeapScanDesc css_currentScanDesc;
- TupleTableSlot *css_ScanTupleSlot;
-} CommonScanState;
+typedef struct CommonScanState
+{
+ CommonState cstate; /* its first field is NodeTag */
+ Relation css_currentRelation;
+ HeapScanDesc css_currentScanDesc;
+ TupleTableSlot *css_ScanTupleSlot;
+} CommonScanState;
/* ----------------
- * IndexScanState information
- *
- *| index scans don't use CommonScanState because
- *| the underlying AM abstractions for heap scans and
- *| index scans are too different.. It would be nice
- *| if the current abstraction was more useful but ... -cim 10/15/89
- *
- * IndexPtr current index in use
- * NumIndices number of indices in this scan
- * ScanKeys Skey structures to scan index rels
- * NumScanKeys array of no of keys in each Skey struct
- * RuntimeKeyInfo array of array of flags for Skeys evaled at runtime
- * RelationDescs ptr to array of relation descriptors
- * ScanDescs ptr to array of scan descriptors
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * IndexScanState information
+ *
+ *| index scans don't use CommonScanState because
+ *| the underlying AM abstractions for heap scans and
+ *| index scans are too different.. It would be nice
+ *| if the current abstraction was more useful but ... -cim 10/15/89
+ *
+ * IndexPtr current index in use
+ * NumIndices number of indices in this scan
+ * ScanKeys Skey structures to scan index rels
+ * NumScanKeys array of no of keys in each Skey struct
+ * RuntimeKeyInfo array of array of flags for Skeys evaled at runtime
+ * RelationDescs ptr to array of relation descriptors
+ * ScanDescs ptr to array of scan descriptors
+ *
+ * CommonState information
+ *
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef struct IndexScanState {
- CommonState cstate; /* its first field is NodeTag */
- int iss_NumIndices;
- int iss_IndexPtr;
- ScanKey *iss_ScanKeys;
- int *iss_NumScanKeys;
- Pointer iss_RuntimeKeyInfo;
- RelationPtr iss_RelationDescs;
- IndexScanDescPtr iss_ScanDescs;
-} IndexScanState;
+typedef struct IndexScanState
+{
+ CommonState cstate; /* its first field is NodeTag */
+ int iss_NumIndices;
+ int iss_IndexPtr;
+ ScanKey *iss_ScanKeys;
+ int *iss_NumScanKeys;
+ Pointer iss_RuntimeKeyInfo;
+ RelationPtr iss_RelationDescs;
+ IndexScanDescPtr iss_ScanDescs;
+} IndexScanState;
/* ----------------------------------------------------------------
- * Join State Information
+ * Join State Information
* ----------------------------------------------------------------
*/
/* ----------------
- * JoinState information
+ * JoinState information
*
- * CommonState information
+ * CommonState information
*
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef CommonState JoinState;
+typedef CommonState JoinState;
/* ----------------
- * NestLoopState information
+ * NestLoopState information
*
- * PortalFlag Set to enable portals to work.
+ * PortalFlag Set to enable portals to work.
*
- * JoinState information
+ * JoinState information
*
- * CommonState information
+ * CommonState information
*
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef struct NestLoopState {
- JoinState jstate; /* its first field is NodeTag */
- bool nl_PortalFlag;
-} NestLoopState;
+typedef struct NestLoopState
+{
+ JoinState jstate; /* its first field is NodeTag */
+ bool nl_PortalFlag;
+} NestLoopState;
/* ----------------
- * MergeJoinState information
+ * MergeJoinState information
*
- * OSortopI outerKey1 sortOp innerKey1 ...
- * ISortopO innerkey1 sortOp outerkey1 ...
- * JoinState current "state" of join. see executor.h
- * MarkedTupleSlot pointer to slot in tuple table for marked tuple
+ * OSortopI outerKey1 sortOp innerKey1 ...
+ * ISortopO innerkey1 sortOp outerkey1 ...
+ * JoinState current "state" of join. see executor.h
+ * MarkedTupleSlot pointer to slot in tuple table for marked tuple
*
- * JoinState information
+ * JoinState information
*
- * CommonState information
+ * CommonState information
*
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef struct MergeJoinState {
- JoinState jstate; /* its first field is NodeTag */
- List *mj_OSortopI;
- List *mj_ISortopO;
- int mj_JoinState;
- TupleTableSlot *mj_MarkedTupleSlot;
-} MergeJoinState;
+typedef struct MergeJoinState
+{
+ JoinState jstate; /* its first field is NodeTag */
+ List *mj_OSortopI;
+ List *mj_ISortopO;
+ int mj_JoinState;
+ TupleTableSlot *mj_MarkedTupleSlot;
+} MergeJoinState;
/* ----------------
- * HashJoinState information
- *
- * hj_HashTable address of the hash table for the hashjoin
- * hj_HashTableShmId shared memory id of hash table
- * hj_CurBucket the current hash bucket that we are searching
- * for matches of the current outer tuple
- * hj_CurTuple the current matching inner tuple in the
- * current hash bucket
- * hj_CurOTuple the current matching inner tuple in the
- * current hash overflow chain
- * hj_InnerHashKey the inner hash key in the hashjoin condition
- * hj_OuterBatches file descriptors for outer batches
- * hj_InnerBatches file descriptors for inner batches
- * hj_OuterReadPos current read position of outer batch
- * hj_OuterReadBlk current read block of outer batch
- * hj_OuterTupleSlot tuple slot for outer tuples
- * hj_HashTupleSlot tuple slot for hashed tuples
- *
- *
- *
- * JoinState information
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * HashJoinState information
+ *
+ * hj_HashTable address of the hash table for the hashjoin
+ * hj_HashTableShmId shared memory id of hash table
+ * hj_CurBucket the current hash bucket that we are searching
+ * for matches of the current outer tuple
+ * hj_CurTuple the current matching inner tuple in the
+ * current hash bucket
+ * hj_CurOTuple the current matching inner tuple in the
+ * current hash overflow chain
+ * hj_InnerHashKey the inner hash key in the hashjoin condition
+ * hj_OuterBatches file descriptors for outer batches
+ * hj_InnerBatches file descriptors for inner batches
+ * hj_OuterReadPos current read position of outer batch
+ * hj_OuterReadBlk current read block of outer batch
+ * hj_OuterTupleSlot tuple slot for outer tuples
+ * hj_HashTupleSlot tuple slot for hashed tuples
+ *
+ *
+ *
+ * JoinState information
+ *
+ * CommonState information
+ *
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef struct HashJoinState {
- JoinState jstate; /* its first field is NodeTag */
- HashJoinTable hj_HashTable;
- IpcMemoryId hj_HashTableShmId;
- HashBucket hj_CurBucket;
- HeapTuple hj_CurTuple;
- OverflowTuple hj_CurOTuple;
- Var *hj_InnerHashKey;
- File *hj_OuterBatches;
- File *hj_InnerBatches;
- char *hj_OuterReadPos;
- int hj_OuterReadBlk;
- TupleTableSlot *hj_OuterTupleSlot;
- TupleTableSlot *hj_HashTupleSlot;
-} HashJoinState;
+typedef struct HashJoinState
+{
+ JoinState jstate; /* its first field is NodeTag */
+ HashJoinTable hj_HashTable;
+ IpcMemoryId hj_HashTableShmId;
+ HashBucket hj_CurBucket;
+ HeapTuple hj_CurTuple;
+ OverflowTuple hj_CurOTuple;
+ Var *hj_InnerHashKey;
+ File *hj_OuterBatches;
+ File *hj_InnerBatches;
+ char *hj_OuterReadPos;
+ int hj_OuterReadBlk;
+ TupleTableSlot *hj_OuterTupleSlot;
+ TupleTableSlot *hj_HashTupleSlot;
+} HashJoinState;
/* ----------------------------------------------------------------
- * Materialization State Information
+ * Materialization State Information
* ----------------------------------------------------------------
*/
/* ----------------
- * MaterialState information
+ * MaterialState information
*
- * materialize nodes are used to materialize the results
- * of a subplan into a temporary relation.
+ * materialize nodes are used to materialize the results
+ * of a subplan into a temporary relation.
*
- * Flag indicated whether subplan has been materialized
- * TempRelation temporary relation containing result of executing
- * the subplan.
+ * Flag indicated whether subplan has been materialized
+ * TempRelation temporary relation containing result of executing
+ * the subplan.
*
- * CommonScanState information
+ * CommonScanState information
*
- * currentRelation relation descriptor of sorted relation
- * currentScanDesc current scan descriptor for scan
- * ScanTupleSlot pointer to slot in tuple table holding scan tuple
+ * currentRelation relation descriptor of sorted relation
+ * currentScanDesc current scan descriptor for scan
+ * ScanTupleSlot pointer to slot in tuple table holding scan tuple
*
- * CommonState information
+ * CommonState information
*
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef struct MaterialState {
- CommonScanState csstate; /* its first field is NodeTag */
- bool mat_Flag;
- Relation mat_TempRelation;
-} MaterialState;
+typedef struct MaterialState
+{
+ CommonScanState csstate; /* its first field is NodeTag */
+ bool mat_Flag;
+ Relation mat_TempRelation;
+} MaterialState;
/* ---------------------
- * AggregateState information
+ * AggregateState information
*
- * done indicated whether aggregate has been materialized
+ * done indicated whether aggregate has been materialized
* -------------------------
*/
-typedef struct AggState {
- CommonScanState csstate; /* its first field is NodeTag */
- bool agg_done;
-} AggState;
+typedef struct AggState
+{
+ CommonScanState csstate; /* its first field is NodeTag */
+ bool agg_done;
+} AggState;
/* ---------------------
- * GroupState information
+ * GroupState information
*
* -------------------------
*/
-typedef struct GroupState {
- CommonScanState csstate; /* its first field is NodeTag */
- bool grp_useLastTuple; /* last tuple not processed yet */
- bool grp_done;
- TupleTableSlot *grp_lastSlot;
-} GroupState;
+typedef struct GroupState
+{
+ CommonScanState csstate; /* its first field is NodeTag */
+ bool grp_useLastTuple; /* last tuple not processed yet */
+ bool grp_done;
+ TupleTableSlot *grp_lastSlot;
+} GroupState;
/* ----------------
- * SortState information
- *
- *| sort nodes are really just a kind of a scan since
- *| we implement sorts by retrieveing the entire subplan
- *| into a temp relation, sorting the temp relation into
- *| another sorted relation, and then preforming a simple
- *| unqualified sequential scan on the sorted relation..
- *| -cim 10/15/89
- *
- * Flag indicated whether relation has been sorted
- * Keys scan key structures used to keep info on sort keys
- * TempRelation temporary relation containing result of executing
- * the subplan.
- *
- * CommonScanState information
- *
- * currentRelation relation descriptor of sorted relation
- * currentScanDesc current scan descriptor for scan
- * ScanTupleSlot pointer to slot in tuple table holding scan tuple
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * SortState information
+ *
+ *| sort nodes are really just a kind of a scan since
+ *| we implement sorts by retrieveing the entire subplan
+ *| into a temp relation, sorting the temp relation into
+ *| another sorted relation, and then preforming a simple
+ *| unqualified sequential scan on the sorted relation..
+ *| -cim 10/15/89
+ *
+ * Flag indicated whether relation has been sorted
+ * Keys scan key structures used to keep info on sort keys
+ * TempRelation temporary relation containing result of executing
+ * the subplan.
+ *
+ * CommonScanState information
+ *
+ * currentRelation relation descriptor of sorted relation
+ * currentScanDesc current scan descriptor for scan
+ * ScanTupleSlot pointer to slot in tuple table holding scan tuple
+ *
+ * CommonState information
+ *
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef struct SortState {
- CommonScanState csstate; /* its first field is NodeTag */
- bool sort_Flag;
- ScanKey sort_Keys;
- bool cleaned;
-} SortState;
+typedef struct SortState
+{
+ CommonScanState csstate; /* its first field is NodeTag */
+ bool sort_Flag;
+ ScanKey sort_Keys;
+ bool cleaned;
+} SortState;
/* ----------------
- * UniqueState information
- *
- * Unique nodes are used "on top of" sort nodes to discard
- * duplicate tuples returned from the sort phase. Basically
- * all it does is compare the current tuple from the subplan
- * with the previously fetched tuple stored in OuterTuple and
- * if the two are identical, then we just fetch another tuple
- * from the sort and try again.
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * UniqueState information
+ *
+ * Unique nodes are used "on top of" sort nodes to discard
+ * duplicate tuples returned from the sort phase. Basically
+ * all it does is compare the current tuple from the subplan
+ * with the previously fetched tuple stored in OuterTuple and
+ * if the two are identical, then we just fetch another tuple
+ * from the sort and try again.
+ *
+ * CommonState information
+ *
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef CommonState UniqueState;
+typedef CommonState UniqueState;
/* ----------------
- * HashState information
+ * HashState information
*
- * hashBatches file descriptors for the batches
+ * hashBatches file descriptors for the batches
*
- * CommonState information
+ * CommonState information
*
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * OuterTupleSlot pointer to slot containing current "outer" tuple
+ * ResultTupleSlot pointer to slot in tuple table for projected tuple
+ * ExprContext node's current expression context
+ * ProjInfo info this node uses to form tuple projections
+ * NumScanAttributes size of ScanAttributes array
+ * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
-typedef struct HashState {
- CommonState cstate; /* its first field is NodeTag */
- File *hashBatches;
-} HashState;
+typedef struct HashState
+{
+ CommonState cstate; /* its first field is NodeTag */
+ File *hashBatches;
+} HashState;
/* -----------------------
- * TeeState information
- * leftPlace : next item in the queue unseen by the left parent
- * rightPlace : next item in the queue unseen by the right parent
- * lastPlace : last item in the queue
- * bufferRelname : name of the relation used as the buffer queue
- * bufferRel : the relation used as the buffer queue
- * mcxt : for now, tee's have their own memory context
- * may be cleaned up later if portals are cleaned up
- *
- * initially, a Tee starts with [left/right]Place variables set to -1.
+ * TeeState information
+ * leftPlace : next item in the queue unseen by the left parent
+ * rightPlace : next item in the queue unseen by the right parent
+ * lastPlace : last item in the queue
+ * bufferRelname : name of the relation used as the buffer queue
+ * bufferRel : the relation used as the buffer queue
+ * mcxt : for now, tee's have their own memory context
+ * may be cleaned up later if portals are cleaned up
+ *
+ * initially, a Tee starts with [left/right]Place variables set to -1.
* on cleanup, queue is free'd when both leftPlace and rightPlace = -1
- * -------------------------
+ * -------------------------
*/
-typedef struct TeeState {
- CommonState cstate; /* its first field is NodeTag */
- int tee_leftPlace;
- int tee_rightPlace;
- int tee_lastPlace;
- char *tee_bufferRelname;
- Relation tee_bufferRel;
- MemoryContext tee_mcxt;
- HeapScanDesc tee_leftScanDesc;
- HeapScanDesc tee_rightScanDesc;
-} TeeState;
-
-#endif /* EXECNODES_H */
+typedef struct TeeState
+{
+ CommonState cstate; /* its first field is NodeTag */
+ int tee_leftPlace;
+ int tee_rightPlace;
+ int tee_lastPlace;
+ char *tee_bufferRelname;
+ Relation tee_bufferRel;
+ MemoryContext tee_mcxt;
+ HeapScanDesc tee_leftScanDesc;
+ HeapScanDesc tee_rightScanDesc;
+} TeeState;
+
+#endif /* EXECNODES_H */
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index a10182a33ee..04b2c10c442 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* makefuncs.h--
- * prototypes for the creator functions (for primitive nodes)
+ * prototypes for the creator functions (for primitive nodes)
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: makefuncs.h,v 1.3 1997/01/22 01:43:41 momjian Exp $
+ * $Id: makefuncs.h,v 1.4 1997/09/07 04:58:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,32 +16,36 @@
#include <nodes/primnodes.h>
#include <utils/fcache.h>
-extern Oper *makeOper(Oid opno,
- Oid opid,
- Oid opresulttype,
- int opsize,
- FunctionCachePtr op_fcache);
+extern Oper *
+makeOper(Oid opno,
+ Oid opid,
+ Oid opresulttype,
+ int opsize,
+ FunctionCachePtr op_fcache);
-extern Var *makeVar(Index varno,
- AttrNumber varattno,
- Oid vartype,
- Index varnoold,
- AttrNumber varoattno);
+extern Var *
+makeVar(Index varno,
+ AttrNumber varattno,
+ Oid vartype,
+ Index varnoold,
+ AttrNumber varoattno);
-extern Resdom *makeResdom(AttrNumber resno,
- Oid restype,
- int reslen,
- char *resname,
- Index reskey,
- Oid reskeyop,
- int resjunk);
-
-extern Const *makeConst(Oid consttype,
- Size constlen,
- Datum constvalue,
- bool constisnull,
- bool constbyval,
- bool constisset,
- bool constiscast);
+extern Resdom *
+makeResdom(AttrNumber resno,
+ Oid restype,
+ int reslen,
+ char *resname,
+ Index reskey,
+ Oid reskeyop,
+ int resjunk);
-#endif /* MAKEFUNC_H */
+extern Const *
+makeConst(Oid consttype,
+ Size constlen,
+ Datum constvalue,
+ bool constisnull,
+ bool constbyval,
+ bool constisset,
+ bool constiscast);
+
+#endif /* MAKEFUNC_H */
diff --git a/src/include/nodes/memnodes.h b/src/include/nodes/memnodes.h
index 594bff6db42..1d5bced1f3c 100644
--- a/src/include/nodes/memnodes.h
+++ b/src/include/nodes/memnodes.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* memnodes.h--
- * POSTGRES memory context node definitions.
+ * POSTGRES memory context node definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: memnodes.h,v 1.4 1996/11/04 07:59:34 scrappy Exp $
+ * $Id: memnodes.h,v 1.5 1997/09/07 04:58:35 momjian Exp $
*
* XXX the typedefs in this file are different from the other ???nodes.h;
- * they are pointers to structures instead of the structures themselves.
- * If you're wondering, this is plain laziness. I don't want to touch
- * the memory context code which should be revamped altogether some day.
- * - ay 10/94
+ * they are pointers to structures instead of the structures themselves.
+ * If you're wondering, this is plain laziness. I don't want to touch
+ * the memory context code which should be revamped altogether some day.
+ * - ay 10/94
*-------------------------------------------------------------------------
*/
-#ifndef MEMNODES_H
+#ifndef MEMNODES_H
#define MEMNODES_H
#include <lib/fstack.h>
@@ -24,75 +24,78 @@
/*
* MemoryContext --
- * A logical context in which memory allocations occur.
+ * A logical context in which memory allocations occur.
*
* The types of memory contexts can be thought of as members of the
* following inheritance hierarchy with properties summarized below.
*
- * Node
- * |
- * MemoryContext___
- * / \
- * GlobalMemory PortalMemoryContext
- * / \
- * PortalVariableMemory PortalHeapMemory
+ * Node
+ * |
+ * MemoryContext___
+ * / \
+ * GlobalMemory PortalMemoryContext
+ * / \
+ * PortalVariableMemory PortalHeapMemory
*
- * Flushed at Flushed at Checkpoints
- * Transaction Portal
- * Commit Close
+ * Flushed at Flushed at Checkpoints
+ * Transaction Portal
+ * Commit Close
*
- * GlobalMemory n n n
- * PortalVariableMemory n y n
- * PortalHeapMemory y y y
+ * GlobalMemory n n n
+ * PortalVariableMemory n y n
+ * PortalHeapMemory y y y
*/
-typedef struct MemoryContextMethodsData {
- Pointer (*alloc)();
- void (*free_p)(); /* need to use free as a #define,
- so can't use free */
- Pointer (*realloc)();
- char* (*getName)();
- void (*dump)();
-} *MemoryContextMethods;
+typedef struct MemoryContextMethodsData
+{
+ Pointer(*alloc) ();
+ void (*free_p) (); /* need to use free as a #define,
+ * so can't use free */
+ Pointer(*realloc) ();
+ char *(*getName) ();
+ void (*dump) ();
+} *MemoryContextMethods;
-typedef struct MemoryContext {
- NodeTag type;
- MemoryContextMethods method;
-} *MemoryContext;
+typedef struct MemoryContext
+{
+ NodeTag type;
+ MemoryContextMethods method;
+} *MemoryContext;
/* think about doing this right some time but we'll have explicit fields
for now -ay 10/94 */
-typedef struct GlobalMemory {
- NodeTag type;
- MemoryContextMethods method;
- AllocSetData setData;
- char *name;
- OrderedElemData elemData;
-} *GlobalMemory;
+typedef struct GlobalMemory
+{
+ NodeTag type;
+ MemoryContextMethods method;
+ AllocSetData setData;
+ char *name;
+ OrderedElemData elemData;
+} *GlobalMemory;
typedef MemoryContext *PortalMemoryContext;
-typedef struct PortalVariableMemory {
- NodeTag type;
- MemoryContextMethods method;
- AllocSetData setData;
-} *PortalVariableMemory;
+typedef struct PortalVariableMemory
+{
+ NodeTag type;
+ MemoryContextMethods method;
+ AllocSetData setData;
+} *PortalVariableMemory;
-typedef struct PortalHeapMemory {
- NodeTag type;
- MemoryContextMethods method;
- Pointer block;
- FixedStackData stackData;
-} *PortalHeapMemory;
+typedef struct PortalHeapMemory
+{
+ NodeTag type;
+ MemoryContextMethods method;
+ Pointer block;
+ FixedStackData stackData;
+} *PortalHeapMemory;
/*
* MemoryContextIsValid --
- * True iff memory context is valid.
+ * True iff memory context is valid.
*/
#define MemoryContextIsValid(context) \
- (IsA(context,MemoryContext) || IsA(context,GlobalMemory) || \
- IsA(context,PortalVariableMemory) || IsA(context,PortalHeapMemory))
-
-#endif /* MEMNODES_H */
-
+ (IsA(context,MemoryContext) || IsA(context,GlobalMemory) || \
+ IsA(context,PortalVariableMemory) || IsA(context,PortalHeapMemory))
+#endif /* MEMNODES_H */
diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h
index 12a0ca97813..3edc598a833 100644
--- a/src/include/nodes/nodeFuncs.h
+++ b/src/include/nodes/nodeFuncs.h
@@ -1,22 +1,22 @@
/*-------------------------------------------------------------------------
*
* nodeFuncs.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodeFuncs.h,v 1.2 1997/08/19 21:38:43 momjian Exp $
+ * $Id: nodeFuncs.h,v 1.3 1997/09/07 04:58:37 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef NODEFUNCS_H
#define NODEFUNCS_H
-extern bool single_node(Node *node);
-extern bool var_is_outer(Var *var);
-extern bool var_is_rel(Var *var);
-extern Oper *replace_opid(Oper *oper);
-extern bool non_null(Expr *c);
+extern bool single_node(Node * node);
+extern bool var_is_outer(Var * var);
+extern bool var_is_rel(Var * var);
+extern Oper *replace_opid(Oper * oper);
+extern bool non_null(Expr * c);
-#endif /* NODEFUNCS_H */
+#endif /* NODEFUNCS_H */
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 66c1b1812ce..944ed7453f2 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* nodes.h--
- * Definitions for tagged nodes.
+ * Definitions for tagged nodes.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodes.h,v 1.11 1997/09/01 06:04:57 thomas Exp $
+ * $Id: nodes.h,v 1.12 1997/09/07 04:58:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef NODES_H
-#define NODES_H
+#define NODES_H
/*
* The first field of every node is NodeTag. Each node created (with makeNode)
@@ -20,195 +20,196 @@
* Note that the number of the node tags are not contiguous. We left holes
* here so that we can add more tags without changing the existing enum's.
*/
-typedef enum NodeTag {
- T_Invalid = 0,
+typedef enum NodeTag
+{
+ T_Invalid = 0,
- /*---------------------
- * TAGS FOR PLAN NODES (plannodes.h)
- *---------------------
- */
- T_Plan = 10,
- T_Existential,
- T_Result,
- T_Append,
- T_Scan,
- T_SeqScan,
- T_IndexScan,
- T_Join,
- T_NestLoop,
- T_MergeJoin,
- T_HashJoin,
- T_Temp,
- T_Material,
- T_Sort,
- T_Agg,
- T_Unique,
- T_Hash,
- T_Choose,
- T_Tee,
- T_Group,
+ /*---------------------
+ * TAGS FOR PLAN NODES (plannodes.h)
+ *---------------------
+ */
+ T_Plan = 10,
+ T_Existential,
+ T_Result,
+ T_Append,
+ T_Scan,
+ T_SeqScan,
+ T_IndexScan,
+ T_Join,
+ T_NestLoop,
+ T_MergeJoin,
+ T_HashJoin,
+ T_Temp,
+ T_Material,
+ T_Sort,
+ T_Agg,
+ T_Unique,
+ T_Hash,
+ T_Choose,
+ T_Tee,
+ T_Group,
- /*---------------------
- * TAGS FOR PRIMITIVE NODES (primnodes.h)
- *---------------------
- */
- T_Resdom = 100,
- T_Fjoin,
- T_Expr,
- T_Var,
- T_Oper,
- T_Const,
- T_Param,
- T_Aggreg,
- T_Func,
- T_Array,
- T_ArrayRef,
+ /*---------------------
+ * TAGS FOR PRIMITIVE NODES (primnodes.h)
+ *---------------------
+ */
+ T_Resdom = 100,
+ T_Fjoin,
+ T_Expr,
+ T_Var,
+ T_Oper,
+ T_Const,
+ T_Param,
+ T_Aggreg,
+ T_Func,
+ T_Array,
+ T_ArrayRef,
- /*---------------------
- * TAGS FOR INNER PLAN NODES (relation.h)
- *---------------------
- */
- T_Rel = 200,
- T_Path,
- T_IndexPath,
- T_JoinPath,
- T_MergePath,
- T_HashPath,
- T_OrderKey,
- T_JoinKey,
- T_MergeOrder,
- T_CInfo,
- T_JoinMethod,
- T_HInfo,
- T_MInfo,
- T_JInfo,
- T_Iter,
- T_Stream,
+ /*---------------------
+ * TAGS FOR INNER PLAN NODES (relation.h)
+ *---------------------
+ */
+ T_Rel = 200,
+ T_Path,
+ T_IndexPath,
+ T_JoinPath,
+ T_MergePath,
+ T_HashPath,
+ T_OrderKey,
+ T_JoinKey,
+ T_MergeOrder,
+ T_CInfo,
+ T_JoinMethod,
+ T_HInfo,
+ T_MInfo,
+ T_JInfo,
+ T_Iter,
+ T_Stream,
- /*---------------------
- * TAGS FOR EXECUTOR NODES (execnodes.h)
- *---------------------
- */
- T_IndexInfo = 300,
- T_RelationInfo,
- T_TupleCount,
- T_TupleTableSlot,
- T_ExprContext,
- T_ProjectionInfo,
- T_JunkFilter,
- T_EState,
- T_BaseNode,
- T_CommonState,
- T_ResultState,
- T_AppendState,
- T_CommonScanState,
- T_ScanState,
- T_IndexScanState,
- T_JoinState,
- T_NestLoopState,
- T_MergeJoinState,
- T_HashJoinState,
- T_MaterialState,
- T_AggState,
- T_GroupState,
- T_SortState,
- T_UniqueState,
- T_HashState,
- T_TeeState,
+ /*---------------------
+ * TAGS FOR EXECUTOR NODES (execnodes.h)
+ *---------------------
+ */
+ T_IndexInfo = 300,
+ T_RelationInfo,
+ T_TupleCount,
+ T_TupleTableSlot,
+ T_ExprContext,
+ T_ProjectionInfo,
+ T_JunkFilter,
+ T_EState,
+ T_BaseNode,
+ T_CommonState,
+ T_ResultState,
+ T_AppendState,
+ T_CommonScanState,
+ T_ScanState,
+ T_IndexScanState,
+ T_JoinState,
+ T_NestLoopState,
+ T_MergeJoinState,
+ T_HashJoinState,
+ T_MaterialState,
+ T_AggState,
+ T_GroupState,
+ T_SortState,
+ T_UniqueState,
+ T_HashState,
+ T_TeeState,
- /*---------------------
- * TAGS FOR MEMORY NODES (memnodes.h)
- *---------------------
- */
- T_MemoryContext = 400,
- T_GlobalMemory,
- T_PortalMemoryContext,
- T_PortalVariableMemory,
- T_PortalHeapMemory,
+ /*---------------------
+ * TAGS FOR MEMORY NODES (memnodes.h)
+ *---------------------
+ */
+ T_MemoryContext = 400,
+ T_GlobalMemory,
+ T_PortalMemoryContext,
+ T_PortalVariableMemory,
+ T_PortalHeapMemory,
- /*---------------------
- * TAGS FOR VALUE NODES (pg_list.h)
- *---------------------
- */
- T_Value = 500,
- T_List,
- T_Integer,
- T_Float,
- T_String,
- T_Null,
-
- /*---------------------
- * TAGS FOR PARSE TREE NODES (parsenode.h)
- *---------------------
- */
- T_Query = 600,
- T_AppendStmt,
- T_DeleteStmt,
- T_ReplaceStmt,
- T_CursorStmt,
- T_RetrieveStmt,
- T_AddAttrStmt,
- T_AggregateStmt,
- T_ChangeACLStmt,
- T_ClosePortalStmt,
- T_ClusterStmt,
- T_CopyStmt,
- T_CreateStmt,
- T_VersionStmt,
- T_DefineStmt,
- T_DestroyStmt,
- T_ExtendStmt,
- T_FetchStmt,
- T_IndexStmt,
- T_MoveStmt,
- T_ProcedureStmt,
- T_PurgeStmt,
- T_RecipeStmt,
- T_RemoveAggrStmt,
- T_RemoveFuncStmt,
- T_RemoveOperStmt,
- T_RemoveStmt,
- T_RenameStmt,
- T_RuleStmt,
- T_NotifyStmt,
- T_ListenStmt,
- T_TransactionStmt,
- T_ViewStmt,
- T_LoadStmt,
- T_CreatedbStmt,
- T_DestroydbStmt,
- T_VacuumStmt,
- T_ExplainStmt,
- T_CreateSeqStmt,
- T_VariableSetStmt,
- T_VariableShowStmt,
- T_VariableResetStmt,
- T_CreateTrigStmt,
- T_DropTrigStmt,
+ /*---------------------
+ * TAGS FOR VALUE NODES (pg_list.h)
+ *---------------------
+ */
+ T_Value = 500,
+ T_List,
+ T_Integer,
+ T_Float,
+ T_String,
+ T_Null,
- T_A_Expr = 700,
- T_Attr,
- T_A_Const,
- T_ParamNo,
- T_Ident,
- T_FuncCall,
- T_A_Indices,
- T_ResTarget,
- T_ParamString,
- T_TimeRange,
- T_RelExpr,
- T_SortGroupBy,
- T_RangeVar,
- T_TypeName,
- T_IndexElem,
- T_ColumnDef,
- T_DefElem,
- T_TargetEntry,
- T_RangeTblEntry,
- T_SortClause,
- T_GroupClause,
- T_SubSelect
-} NodeTag;
+ /*---------------------
+ * TAGS FOR PARSE TREE NODES (parsenode.h)
+ *---------------------
+ */
+ T_Query = 600,
+ T_AppendStmt,
+ T_DeleteStmt,
+ T_ReplaceStmt,
+ T_CursorStmt,
+ T_RetrieveStmt,
+ T_AddAttrStmt,
+ T_AggregateStmt,
+ T_ChangeACLStmt,
+ T_ClosePortalStmt,
+ T_ClusterStmt,
+ T_CopyStmt,
+ T_CreateStmt,
+ T_VersionStmt,
+ T_DefineStmt,
+ T_DestroyStmt,
+ T_ExtendStmt,
+ T_FetchStmt,
+ T_IndexStmt,
+ T_MoveStmt,
+ T_ProcedureStmt,
+ T_PurgeStmt,
+ T_RecipeStmt,
+ T_RemoveAggrStmt,
+ T_RemoveFuncStmt,
+ T_RemoveOperStmt,
+ T_RemoveStmt,
+ T_RenameStmt,
+ T_RuleStmt,
+ T_NotifyStmt,
+ T_ListenStmt,
+ T_TransactionStmt,
+ T_ViewStmt,
+ T_LoadStmt,
+ T_CreatedbStmt,
+ T_DestroydbStmt,
+ T_VacuumStmt,
+ T_ExplainStmt,
+ T_CreateSeqStmt,
+ T_VariableSetStmt,
+ T_VariableShowStmt,
+ T_VariableResetStmt,
+ T_CreateTrigStmt,
+ T_DropTrigStmt,
+
+ T_A_Expr = 700,
+ T_Attr,
+ T_A_Const,
+ T_ParamNo,
+ T_Ident,
+ T_FuncCall,
+ T_A_Indices,
+ T_ResTarget,
+ T_ParamString,
+ T_TimeRange,
+ T_RelExpr,
+ T_SortGroupBy,
+ T_RangeVar,
+ T_TypeName,
+ T_IndexElem,
+ T_ColumnDef,
+ T_DefElem,
+ T_TargetEntry,
+ T_RangeTblEntry,
+ T_SortClause,
+ T_GroupClause,
+ T_SubSelect
+} NodeTag;
/*
* The first field of a node of any type is gauranteed to be the NodeTag.
@@ -216,90 +217,93 @@ typedef enum NodeTag {
* a variable to be of Node * (instead of void *) can also facilitate
* debugging.
*/
-typedef struct Node {
- NodeTag type;
-} Node;
+typedef struct Node
+{
+ NodeTag type;
+} Node;
-#define nodeTag(_node_) ((Node*)_node_)->type
+#define nodeTag(_node_) ((Node*)_node_)->type
-#define makeNode(_node_) (_node_*)newNode(sizeof(_node_),T_##_node_)
-#define NodeSetTag(n, t) ((Node *)n)->type = t
+#define makeNode(_node_) (_node_*)newNode(sizeof(_node_),T_##_node_)
+#define NodeSetTag(n, t) ((Node *)n)->type = t
-#define IsA(_node_,_tag_) (nodeTag(_node_) == T_##_tag_)
+#define IsA(_node_,_tag_) (nodeTag(_node_) == T_##_tag_)
/* ----------------------------------------------------------------
- * IsA functions (no inheritence any more)
+ * IsA functions (no inheritence any more)
* ----------------------------------------------------------------
*/
#define IsA_JoinPath(jp) \
- (nodeTag(jp)==T_JoinPath || nodeTag(jp)==T_MergePath || \
- nodeTag(jp)==T_HashPath)
+ (nodeTag(jp)==T_JoinPath || nodeTag(jp)==T_MergePath || \
+ nodeTag(jp)==T_HashPath)
#define IsA_Join(j) \
- (nodeTag(j)==T_Join || nodeTag(j)==T_NestLoop || \
- nodeTag(j)==T_MergeJoin || nodeTag(j)==T_HashJoin)
+ (nodeTag(j)==T_Join || nodeTag(j)==T_NestLoop || \
+ nodeTag(j)==T_MergeJoin || nodeTag(j)==T_HashJoin)
#define IsA_Temp(t) \
- (nodeTag(t)==T_Temp || nodeTag(t)==T_Material || nodeTag(t)==T_Sort || \
- nodeTag(t)==T_Unique)
+ (nodeTag(t)==T_Temp || nodeTag(t)==T_Material || nodeTag(t)==T_Sort || \
+ nodeTag(t)==T_Unique)
/* ----------------------------------------------------------------
- * extern declarations follow
+ * extern declarations follow
* ----------------------------------------------------------------
*/
/*
* nodes/nodes.c
*/
-extern Node *newNode(Size size, NodeTag tag);
+extern Node *newNode(Size size, NodeTag tag);
/*
* nodes/{outfuncs.c,print.c}
*/
-#define nodeDisplay pprint
+#define nodeDisplay pprint
-extern char *nodeToString(void *obj);
-extern void print(void *obj);
+extern char *nodeToString(void *obj);
+extern void print(void *obj);
/*
* nodes/{readfuncs.c,read.c}
*/
-extern void *stringToNode(char *str);
+extern void *stringToNode(char *str);
/*
* nodes/copyfuncs.c
*/
-extern void *copyObject(void *obj);
+extern void *copyObject(void *obj);
/*
* nodes/equalfuncs.c
*/
-extern bool equal(void *a, void *b);
+extern bool equal(void *a, void *b);
/* ----------------
- * I don't know why this is here. Most likely a hack..
- * -cim 6/3/90
+ * I don't know why this is here. Most likely a hack..
+ * -cim 6/3/90
* ----------------
*/
-typedef float Cost;
+typedef float Cost;
/*
* CmdType -
- * enums for type of operation to aid debugging
+ * enums for type of operation to aid debugging
*
* ??? could have put this in parsenodes.h but many files not in the
- * optimizer also need this...
+ * optimizer also need this...
*/
-typedef enum CmdType {
- CMD_UNKNOWN,
- CMD_SELECT, /* select stmt (formerly retrieve) */
- CMD_UPDATE, /* update stmt (formerly replace) */
- CMD_INSERT, /* insert stmt (formerly append) */
- CMD_DELETE,
- CMD_NOTIFY,
- CMD_UTILITY /* cmds like create, destroy, copy, vacuum, etc. */
-} CmdType;
-
+typedef enum CmdType
+{
+ CMD_UNKNOWN,
+ CMD_SELECT, /* select stmt (formerly retrieve) */
+ CMD_UPDATE, /* update stmt (formerly replace) */
+ CMD_INSERT, /* insert stmt (formerly append) */
+ CMD_DELETE,
+ CMD_NOTIFY,
+ CMD_UTILITY /* cmds like create, destroy, copy,
+ * vacuum, etc. */
+} CmdType;
+
-#endif /* NODES_H */
+#endif /* NODES_H */
diff --git a/src/include/nodes/params.h b/src/include/nodes/params.h
index 93e79268123..78f0d1cd64b 100644
--- a/src/include/nodes/params.h
+++ b/src/include/nodes/params.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* params.h--
- * Declarations/definitions of stuff needed to handle parameterized plans.
+ * Declarations/definitions of stuff needed to handle parameterized plans.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: params.h,v 1.3 1996/11/04 08:52:57 scrappy Exp $
+ * $Id: params.h,v 1.4 1997/09/07 04:58:40 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,71 +19,72 @@
*
* The following are the possible values for the 'paramkind'
* field of a Param node.
- *
+ *
* PARAM_NAMED: The parameter has a name, i.e. something
- * like `$.salary' or `$.foobar'.
- * In this case field `paramname' must be a valid Name.
- * and field `paramid' must be == 0.
+ * like `$.salary' or `$.foobar'.
+ * In this case field `paramname' must be a valid Name.
+ * and field `paramid' must be == 0.
+ *
+ * PARAM_NUM: The parameter has only a numeric identifier,
+ * i.e. something like `$1', `$2' etc.
+ * The number is contained in the `parmid' field.
*
- * PARAM_NUM: The parameter has only a numeric identifier,
- * i.e. something like `$1', `$2' etc.
- * The number is contained in the `parmid' field.
+ * PARAM_NEW: Used in PRS2 rule, similar to PARAM_NAMED.
+ * The `paramname' & `paramid' refer to the "NEW" tuple
+ * `paramname' is the attribute name and `paramid' its
+ * attribute number.
*
- * PARAM_NEW: Used in PRS2 rule, similar to PARAM_NAMED.
- * The `paramname' & `paramid' refer to the "NEW" tuple
- * `paramname' is the attribute name and `paramid' its
- * attribute number.
- *
- * PARAM_OLD: Same as PARAM_NEW, but in this case we refer to
- * the "OLD" tuple.
+ * PARAM_OLD: Same as PARAM_NEW, but in this case we refer to
+ * the "OLD" tuple.
*/
-#define PARAM_NAMED 11
-#define PARAM_NUM 12
-#define PARAM_NEW 13
-#define PARAM_OLD 14
-#define PARAM_INVALID 100
+#define PARAM_NAMED 11
+#define PARAM_NUM 12
+#define PARAM_NEW 13
+#define PARAM_OLD 14
+#define PARAM_INVALID 100
/* ----------------------------------------------------------------
- * ParamListInfo
+ * ParamListInfo
*
- * Information needed in order for the executor to handle
- * parameterized plans (you know, $.salary, $.name etc. stuff...).
+ * Information needed in order for the executor to handle
+ * parameterized plans (you know, $.salary, $.name etc. stuff...).
*
- * ParamListInfoData contains information needed when substituting a
- * Param node with a Const node.
+ * ParamListInfoData contains information needed when substituting a
+ * Param node with a Const node.
*
- * kind : the kind of parameter.
- * name : the parameter name (valid if kind == PARAM_NAMED,
- * PARAM_NEW or PARAM_OLD)
- * id : the parameter id (valid if kind == PARAM_NUM)
- * or the attrno (if kind == PARAM_NEW or PARAM_OLD)
- * type : PG_TYPE OID of the value
- * length : length in bytes of the value
- * isnull : true if & only if the value is null (if true then
- * the fields 'length' and 'value' are undefined).
- * value : the value that has to be substituted in the place
- * of the parameter.
+ * kind : the kind of parameter.
+ * name : the parameter name (valid if kind == PARAM_NAMED,
+ * PARAM_NEW or PARAM_OLD)
+ * id : the parameter id (valid if kind == PARAM_NUM)
+ * or the attrno (if kind == PARAM_NEW or PARAM_OLD)
+ * type : PG_TYPE OID of the value
+ * length : length in bytes of the value
+ * isnull : true if & only if the value is null (if true then
+ * the fields 'length' and 'value' are undefined).
+ * value : the value that has to be substituted in the place
+ * of the parameter.
*
- * ParamListInfo is to be used as an array of ParamListInfoData
- * records. An 'InvalidName' in the name field of such a record
- * indicates that this is the last record in the array.
+ * ParamListInfo is to be used as an array of ParamListInfoData
+ * records. An 'InvalidName' in the name field of such a record
+ * indicates that this is the last record in the array.
*
* ----------------------------------------------------------------
*/
-typedef struct ParamListInfoData {
- int kind;
- char *name;
- AttrNumber id;
- Oid type;
- Size length;
- bool isnull;
- bool byval;
- Datum value;
-} ParamListInfoData;
+typedef struct ParamListInfoData
+{
+ int kind;
+ char *name;
+ AttrNumber id;
+ Oid type;
+ Size length;
+ bool isnull;
+ bool byval;
+ Datum value;
+} ParamListInfoData;
typedef ParamListInfoData *ParamListInfo;
-#endif /* PARAMS_H */
+#endif /* PARAMS_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 8492dcde1d8..c24d27918c2 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1,844 +1,914 @@
/*-------------------------------------------------------------------------
*
* parsenodes.h--
- * definitions for parse tree nodes
+ * definitions for parse tree nodes
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: parsenodes.h,v 1.23 1997/09/01 08:11:57 vadim Exp $
+ * $Id: parsenodes.h,v 1.24 1997/09/07 04:58:44 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef PARSENODES_H
-#define PARSENODES_H
+#ifndef PARSENODES_H
+#define PARSENODES_H
#include <utils/tqual.h>
#include <nodes/primnodes.h>
/*****************************************************************************
- * Query Tree
+ * Query Tree
*****************************************************************************/
/*
* Query -
- * all statments are turned into a Query tree (via transformStmt)
- * for further processing by the optimizer
- * utility statements (i.e. non-optimizable statements)
- * have the *utilityStmt field set.
+ * all statments are turned into a Query tree (via transformStmt)
+ * for further processing by the optimizer
+ * utility statements (i.e. non-optimizable statements)
+ * have the *utilityStmt field set.
*
* we need the isPortal flag because portal names can be null too; can
* get rid of it if we support CURSOR as a commandType.
*
*/
-typedef struct Query {
- NodeTag type;
-
- CmdType commandType; /* select|insert|update|delete|utility */
-
- Node *utilityStmt; /* non-null if this is a non-optimizable
- statement */
-
- int resultRelation; /* target relation (index to rtable) */
- char *into; /* portal (cursor) name */
- bool isPortal; /* is this a retrieve into portal? */
- bool isBinary; /* binary portal? */
-
- char *uniqueFlag; /* NULL, '*', or Unique attribute name */
- List *sortClause; /* a list of SortClause's */
-
- List *rtable; /* list of range table entries */
- List *targetList; /* target list (of TargetEntry) */
- Node *qual; /* qualifications */
-
- List *groupClause; /* list of columns to specified in GROUP BY */
- Node *havingQual; /* qualification of each group */
-
- int qry_numAgg; /* number of aggregates in the target list */
- Aggreg **qry_aggs; /* the aggregates */
-
- /* internal to planner */
- List *base_relation_list_; /* base relation list */
- List *join_relation_list_; /* list of relations generated by joins */
- bool query_is_archival_; /* archival query flag */
-} Query;
+typedef struct Query
+{
+ NodeTag type;
+
+ CmdType commandType;/* select|insert|update|delete|utility */
+
+ Node *utilityStmt;/* non-null if this is a non-optimizable
+ * statement */
+
+ int resultRelation; /* target relation (index to
+ * rtable) */
+ char *into; /* portal (cursor) name */
+ bool isPortal; /* is this a retrieve into portal? */
+ bool isBinary; /* binary portal? */
+
+ char *uniqueFlag; /* NULL, '*', or Unique attribute name */
+ List *sortClause; /* a list of SortClause's */
+
+ List *rtable; /* list of range table entries */
+ List *targetList; /* target list (of TargetEntry) */
+ Node *qual; /* qualifications */
+
+ List *groupClause;/* list of columns to specified in GROUP
+ * BY */
+ Node *havingQual; /* qualification of each group */
+
+ int qry_numAgg; /* number of aggregates in the target list */
+ Aggreg **qry_aggs; /* the aggregates */
+
+ /* internal to planner */
+ List *base_relation_list_; /* base relation list */
+ List *join_relation_list_; /* list of relations
+ * generated by joins */
+ bool query_is_archival_; /* archival query flag */
+} Query;
/*****************************************************************************
- * Other Statements (no optimizations required)
+ * Other Statements (no optimizations required)
*
- * Some of them require a little bit of transformation (which is also
- * done by transformStmt). The whole structure is then passed on to
- * ProcessUtility (by-passing the optimization step) as the utilityStmt
- * field in Query.
+ * Some of them require a little bit of transformation (which is also
+ * done by transformStmt). The whole structure is then passed on to
+ * ProcessUtility (by-passing the optimization step) as the utilityStmt
+ * field in Query.
*****************************************************************************/
/* ----------------------
- * Add Column Statement
+ * Add Column Statement
* ----------------------
*/
-typedef struct AddAttrStmt {
- NodeTag type;
- char *relname; /* the relation to add attr */
- bool inh; /* add recursively to children? */
- struct ColumnDef *colDef; /* the attribute definition */
-} AddAttrStmt;
+typedef struct AddAttrStmt
+{
+ NodeTag type;
+ char *relname; /* the relation to add attr */
+ bool inh; /* add recursively to children? */
+ struct ColumnDef *colDef; /* the attribute definition */
+} AddAttrStmt;
/* ----------------------
- * Change ACL Statement
+ * Change ACL Statement
* ----------------------
*/
-typedef struct ChangeACLStmt {
- NodeTag type;
- struct AclItem *aclitem;
- unsigned modechg;
- List *relNames;
-} ChangeACLStmt;
+typedef struct ChangeACLStmt
+{
+ NodeTag type;
+ struct AclItem *aclitem;
+ unsigned modechg;
+ List *relNames;
+} ChangeACLStmt;
/* ----------------------
- * Close Portal Statement
+ * Close Portal Statement
* ----------------------
*/
-typedef struct ClosePortalStmt {
- NodeTag type;
- char *portalname; /* name of the portal (cursor) */
-} ClosePortalStmt;
+typedef struct ClosePortalStmt
+{
+ NodeTag type;
+ char *portalname; /* name of the portal (cursor) */
+} ClosePortalStmt;
/* ----------------------
- * Copy Statement
+ * Copy Statement
* ----------------------
*/
-typedef struct CopyStmt {
- NodeTag type;
- bool binary; /* is a binary copy? */
- char *relname; /* the relation to copy */
- bool oids; /* copy oid's? */
- int direction; /* TO or FROM */
- char *filename; /* if NULL, use stdin/stdout */
- char *delimiter; /* delimiter character, \t by default*/
-} CopyStmt;
+typedef struct CopyStmt
+{
+ NodeTag type;
+ bool binary; /* is a binary copy? */
+ char *relname; /* the relation to copy */
+ bool oids; /* copy oid's? */
+ int direction; /* TO or FROM */
+ char *filename; /* if NULL, use stdin/stdout */
+ char *delimiter; /* delimiter character, \t by default */
+} CopyStmt;
/* ----------------------
- * Create Table Statement
+ * Create Table Statement
* ----------------------
*/
-typedef enum ArchType {
- ARCH_NONE, ARCH_LIGHT, ARCH_HEAVY /* archive mode */
-} ArchType;
+typedef enum ArchType
+{
+ ARCH_NONE, ARCH_LIGHT, ARCH_HEAVY /* archive mode */
+} ArchType;
-typedef struct CreateStmt {
- NodeTag type;
- char *relname; /* the relation to create */
- List *tableElts; /* column definitions
- list of ColumnDef */
- List *inhRelnames; /* relations to inherit from
- list of Value (string) */
- ArchType archiveType; /* archive mode (ARCH_NONE if none */
- int location; /* smgrid (-1 if none) */
- int archiveLoc; /* smgrid (-1 if none) */
- List *constraints; /* list of constraints (ConstaintDef) */
-} CreateStmt;
+typedef struct CreateStmt
+{
+ NodeTag type;
+ char *relname; /* the relation to create */
+ List *tableElts; /* column definitions list of ColumnDef */
+ List *inhRelnames;/* relations to inherit from list of Value
+ * (string) */
+ ArchType archiveType;/* archive mode (ARCH_NONE if none */
+ int location; /* smgrid (-1 if none) */
+ int archiveLoc; /* smgrid (-1 if none) */
+ List *constraints;/* list of constraints (ConstaintDef) */
+} CreateStmt;
-typedef enum ConstrType {
- CONSTR_NONE, CONSTR_CHECK /* type of constaints */
-} ConstrType;
+typedef enum ConstrType
+{
+ CONSTR_NONE, CONSTR_CHECK /* type of constaints */
+} ConstrType;
-typedef struct ConstraintDef {
- ConstrType type;
- char *name; /* name */
- void *def; /* definition */
-} ConstraintDef;
+typedef struct ConstraintDef
+{
+ ConstrType type;
+ char *name; /* name */
+ void *def; /* definition */
+} ConstraintDef;
/* ----------------------
- * Create/Drop TRIGGER Statements
+ * Create/Drop TRIGGER Statements
* ----------------------
*/
-typedef struct CreateTrigStmt {
- NodeTag type;
- char *trigname; /* TRIGGER' name */
- char *relname; /* triggered relation */
- char *funcname; /* function to call (or NULL) */
- List *args; /* list of (T_String) Values or NULL */
- bool before; /* BEFORE/AFTER */
- bool row; /* ROW/STATEMENT */
- char actions[4]; /* Insert, Update, Delete */
- char *lang; /* NULL (which means Clanguage) */
- char *text; /* AS 'text' */
- List *attr; /* UPDATE OF a, b,... (NI) or NULL */
- char *when; /* WHEN 'a > 10 ...' (NI) or NULL */
-} CreateTrigStmt;
+typedef struct CreateTrigStmt
+{
+ NodeTag type;
+ char *trigname; /* TRIGGER' name */
+ char *relname; /* triggered relation */
+ char *funcname; /* function to call (or NULL) */
+ List *args; /* list of (T_String) Values or NULL */
+ bool before; /* BEFORE/AFTER */
+ bool row; /* ROW/STATEMENT */
+ char actions[4]; /* Insert, Update, Delete */
+ char *lang; /* NULL (which means Clanguage) */
+ char *text; /* AS 'text' */
+ List *attr; /* UPDATE OF a, b,... (NI) or NULL */
+ char *when; /* WHEN 'a > 10 ...' (NI) or NULL */
+} CreateTrigStmt;
-typedef struct DropTrigStmt {
- NodeTag type;
- char *trigname; /* TRIGGER' name */
- char *relname; /* triggered relation */
-} DropTrigStmt;
+typedef struct DropTrigStmt
+{
+ NodeTag type;
+ char *trigname; /* TRIGGER' name */
+ char *relname; /* triggered relation */
+} DropTrigStmt;
/* ----------------------
- * Create SEQUENCE Statement
+ * Create SEQUENCE Statement
* ----------------------
*/
-typedef struct CreateSeqStmt {
- NodeTag type;
- char *seqname; /* the relation to create */
- List *options;
-} CreateSeqStmt;
+typedef struct CreateSeqStmt
+{
+ NodeTag type;
+ char *seqname; /* the relation to create */
+ List *options;
+} CreateSeqStmt;
/* ----------------------
- * Create Version Statement
+ * Create Version Statement
* ----------------------
*/
-typedef struct VersionStmt {
- NodeTag type;
- char *relname; /* the new relation */
- int direction; /* FORWARD | BACKWARD */
- char *fromRelname; /* relation to create a version */
- char *date; /* date of the snapshot */
-} VersionStmt;
+typedef struct VersionStmt
+{
+ NodeTag type;
+ char *relname; /* the new relation */
+ int direction; /* FORWARD | BACKWARD */
+ char *fromRelname;/* relation to create a version */
+ char *date; /* date of the snapshot */
+} VersionStmt;
/* ----------------------
- * Create {Operator|Type|Aggregate} Statement
+ * Create {Operator|Type|Aggregate} Statement
* ----------------------
*/
-typedef struct DefineStmt {
- NodeTag type;
- int defType; /* OPERATOR|P_TYPE|AGGREGATE*/
- char *defname;
- List *definition; /* a list of DefElem */
-} DefineStmt;
+typedef struct DefineStmt
+{
+ NodeTag type;
+ int defType; /* OPERATOR|P_TYPE|AGGREGATE */
+ char *defname;
+ List *definition; /* a list of DefElem */
+} DefineStmt;
/* ----------------------
- * Drop Table Statement
+ * Drop Table Statement
* ----------------------
*/
-typedef struct DestroyStmt {
- NodeTag type;
- List *relNames; /* relations to be dropped */
- bool sequence;
-} DestroyStmt;
+typedef struct DestroyStmt
+{
+ NodeTag type;
+ List *relNames; /* relations to be dropped */
+ bool sequence;
+} DestroyStmt;
/* ----------------------
- * Extend Index Statement
+ * Extend Index Statement
* ----------------------
*/
-typedef struct ExtendStmt {
- NodeTag type;
- char *idxname; /* name of the index */
- Node *whereClause; /* qualifications */
- List *rangetable; /* range table, filled in
- by transformStmt() */
-} ExtendStmt;
+typedef struct ExtendStmt
+{
+ NodeTag type;
+ char *idxname; /* name of the index */
+ Node *whereClause;/* qualifications */
+ List *rangetable; /* range table, filled in by
+ * transformStmt() */
+} ExtendStmt;
/* ----------------------
- * Begin Recipe Statement
+ * Begin Recipe Statement
* ----------------------
*/
-typedef struct RecipeStmt {
- NodeTag type;
- char *recipeName; /* name of the recipe*/
-} RecipeStmt;
+typedef struct RecipeStmt
+{
+ NodeTag type;
+ char *recipeName; /* name of the recipe */
+} RecipeStmt;
/* ----------------------
- * Fetch Statement
+ * Fetch Statement
* ----------------------
*/
-typedef struct FetchStmt {
- NodeTag type;
- int direction; /* FORWARD or BACKWARD */
- int howMany; /* amount to fetch ("ALL" --> 0) */
- char *portalname; /* name of portal (cursor) */
-} FetchStmt;
+typedef struct FetchStmt
+{
+ NodeTag type;
+ int direction; /* FORWARD or BACKWARD */
+ int howMany; /* amount to fetch ("ALL" --> 0) */
+ char *portalname; /* name of portal (cursor) */
+} FetchStmt;
/* ----------------------
- * Create Index Statement
+ * Create Index Statement
* ----------------------
*/
-typedef struct IndexStmt {
- NodeTag type;
- char *idxname; /* name of the index */
- char *relname; /* name of relation to index on */
- char *accessMethod; /* name of acess methood (eg. btree) */
- List *indexParams; /* a list of IndexElem */
- List *withClause; /* a list of ParamString */
- Node *whereClause; /* qualifications */
- List *rangetable; /* range table, filled in
- by transformStmt() */
- bool *lossy; /* is index lossy? */
- bool unique; /* is index unique? */
-} IndexStmt;
+typedef struct IndexStmt
+{
+ NodeTag type;
+ char *idxname; /* name of the index */
+ char *relname; /* name of relation to index on */
+ char *accessMethod; /* name of acess methood (eg.
+ * btree) */
+ List *indexParams;/* a list of IndexElem */
+ List *withClause; /* a list of ParamString */
+ Node *whereClause;/* qualifications */
+ List *rangetable; /* range table, filled in by
+ * transformStmt() */
+ bool *lossy; /* is index lossy? */
+ bool unique; /* is index unique? */
+} IndexStmt;
/* ----------------------
- * Move Statement (Not implemented)
+ * Move Statement (Not implemented)
* ----------------------
*/
-typedef struct MoveStmt {
- NodeTag type;
- int direction; /* FORWARD or BACKWARD */
- bool to;
- int where;
- char *portalname;
-} MoveStmt;
+typedef struct MoveStmt
+{
+ NodeTag type;
+ int direction; /* FORWARD or BACKWARD */
+ bool to;
+ int where;
+ char *portalname;
+} MoveStmt;
/* ----------------------
- * Create Function Statement
+ * Create Function Statement
* ----------------------
*/
-typedef struct ProcedureStmt {
- NodeTag type;
- char *funcname; /* name of function to create */
- List *defArgs; /* list of definitions
- a list of strings (as Value *) */
- Node *returnType; /* the return type (as a string or
- a TypeName (ie.setof) */
- List *withClause; /* a list of ParamString */
- char *as; /* the SQL statement or filename */
- char *language; /* C or SQL */
-} ProcedureStmt;
+typedef struct ProcedureStmt
+{
+ NodeTag type;
+ char *funcname; /* name of function to create */
+ List *defArgs; /* list of definitions a list of strings
+ * (as Value *) */
+ Node *returnType; /* the return type (as a string or a
+ * TypeName (ie.setof) */
+ List *withClause; /* a list of ParamString */
+ char *as; /* the SQL statement or filename */
+ char *language; /* C or SQL */
+} ProcedureStmt;
/* ----------------------
- * Purge Statement
+ * Purge Statement
* ----------------------
*/
-typedef struct PurgeStmt {
- NodeTag type;
- char *relname; /* relation to purge */
- char *beforeDate; /* purge before this date */
- char *afterDate; /* purge after this date */
-} PurgeStmt;
+typedef struct PurgeStmt
+{
+ NodeTag type;
+ char *relname; /* relation to purge */
+ char *beforeDate; /* purge before this date */
+ char *afterDate; /* purge after this date */
+} PurgeStmt;
/* ----------------------
- * Drop Aggregate Statement
+ * Drop Aggregate Statement
* ----------------------
*/
-typedef struct RemoveAggrStmt {
- NodeTag type;
- char *aggname; /* aggregate to drop */
- char *aggtype; /* for this type */
-} RemoveAggrStmt;
+typedef struct RemoveAggrStmt
+{
+ NodeTag type;
+ char *aggname; /* aggregate to drop */
+ char *aggtype; /* for this type */
+} RemoveAggrStmt;
/* ----------------------
- * Drop Function Statement
+ * Drop Function Statement
* ----------------------
*/
-typedef struct RemoveFuncStmt {
- NodeTag type;
- char *funcname; /* function to drop */
- List *args; /* types of the arguments */
-} RemoveFuncStmt;
+typedef struct RemoveFuncStmt
+{
+ NodeTag type;
+ char *funcname; /* function to drop */
+ List *args; /* types of the arguments */
+} RemoveFuncStmt;
/* ----------------------
- * Drop Operator Statement
+ * Drop Operator Statement
* ----------------------
*/
-typedef struct RemoveOperStmt {
- NodeTag type;
- char *opname; /* operator to drop */
- List *args; /* types of the arguments */
-} RemoveOperStmt;
+typedef struct RemoveOperStmt
+{
+ NodeTag type;
+ char *opname; /* operator to drop */
+ List *args; /* types of the arguments */
+} RemoveOperStmt;
/* ----------------------
- * Drop {Type|Index|Rule|View} Statement
+ * Drop {Type|Index|Rule|View} Statement
* ----------------------
*/
-typedef struct RemoveStmt {
- NodeTag type;
- int removeType; /* P_TYPE|INDEX|RULE|VIEW */
- char *name; /* name to drop */
-} RemoveStmt;
+typedef struct RemoveStmt
+{
+ NodeTag type;
+ int removeType; /* P_TYPE|INDEX|RULE|VIEW */
+ char *name; /* name to drop */
+} RemoveStmt;
/* ----------------------
- * Alter Table Statement
+ * Alter Table Statement
* ----------------------
*/
-typedef struct RenameStmt {
- NodeTag type;
- char *relname; /* relation to be altered */
- bool inh; /* recursively alter children? */
- char *column; /* if NULL, rename the relation name
- to the new name. Otherwise, rename
- this column name. */
- char *newname; /* the new name */
-} RenameStmt;
+typedef struct RenameStmt
+{
+ NodeTag type;
+ char *relname; /* relation to be altered */
+ bool inh; /* recursively alter children? */
+ char *column; /* if NULL, rename the relation name to
+ * the new name. Otherwise, rename this
+ * column name. */
+ char *newname; /* the new name */
+} RenameStmt;
/* ----------------------
- * Create Rule Statement
+ * Create Rule Statement
* ----------------------
*/
-typedef struct RuleStmt {
- NodeTag type;
- char *rulename; /* name of the rule */
- Node *whereClause; /* qualifications */
- CmdType event; /* RETRIEVE */
- struct Attr *object; /* object affected */
- bool instead; /* is a 'do instead'? */
- List *actions; /* the action statements */
-} RuleStmt;
+typedef struct RuleStmt
+{
+ NodeTag type;
+ char *rulename; /* name of the rule */
+ Node *whereClause;/* qualifications */
+ CmdType event; /* RETRIEVE */
+ struct Attr *object; /* object affected */
+ bool instead; /* is a 'do instead'? */
+ List *actions; /* the action statements */
+} RuleStmt;
/* ----------------------
- * Notify Statement
+ * Notify Statement
* ----------------------
*/
-typedef struct NotifyStmt {
- NodeTag type;
- char *relname; /* relation to notify */
-} NotifyStmt;
+typedef struct NotifyStmt
+{
+ NodeTag type;
+ char *relname; /* relation to notify */
+} NotifyStmt;
/* ----------------------
- * Listen Statement
+ * Listen Statement
* ----------------------
*/
-typedef struct ListenStmt {
- NodeTag type;
- char *relname; /* relation to listen on */
-} ListenStmt;
+typedef struct ListenStmt
+{
+ NodeTag type;
+ char *relname; /* relation to listen on */
+} ListenStmt;
/* ----------------------
- * {Begin|Abort|End} Transaction Statement
+ * {Begin|Abort|End} Transaction Statement
* ----------------------
*/
-typedef struct TransactionStmt {
- NodeTag type;
- int command; /* BEGIN|END|ABORT */
-} TransactionStmt;
+typedef struct TransactionStmt
+{
+ NodeTag type;
+ int command; /* BEGIN|END|ABORT */
+} TransactionStmt;
/* ----------------------
- * Create View Statement
+ * Create View Statement
* ----------------------
*/
-typedef struct ViewStmt {
- NodeTag type;
- char *viewname; /* name of the view */
- Query *query; /* the SQL statement */
-} ViewStmt;
+typedef struct ViewStmt
+{
+ NodeTag type;
+ char *viewname; /* name of the view */
+ Query *query; /* the SQL statement */
+} ViewStmt;
/* ----------------------
- * Load Statement
+ * Load Statement
* ----------------------
*/
-typedef struct LoadStmt {
- NodeTag type;
- char *filename; /* file to load */
-} LoadStmt;
+typedef struct LoadStmt
+{
+ NodeTag type;
+ char *filename; /* file to load */
+} LoadStmt;
/* ----------------------
- * Createdb Statement
+ * Createdb Statement
* ----------------------
*/
-typedef struct CreatedbStmt {
- NodeTag type;
- char *dbname; /* database to create */
-} CreatedbStmt;
+typedef struct CreatedbStmt
+{
+ NodeTag type;
+ char *dbname; /* database to create */
+} CreatedbStmt;
/* ----------------------
- * Destroydb Statement
+ * Destroydb Statement
* ----------------------
*/
-typedef struct DestroydbStmt {
- NodeTag type;
- char *dbname; /* database to drop */
-} DestroydbStmt;
+typedef struct DestroydbStmt
+{
+ NodeTag type;
+ char *dbname; /* database to drop */
+} DestroydbStmt;
/* ----------------------
- * Cluster Statement (support pbrown's cluster index implementation)
+ * Cluster Statement (support pbrown's cluster index implementation)
* ----------------------
*/
-typedef struct ClusterStmt {
- NodeTag type;
- char *relname; /* relation being indexed */
- char *indexname; /* original index defined */
-} ClusterStmt;
+typedef struct ClusterStmt
+{
+ NodeTag type;
+ char *relname; /* relation being indexed */
+ char *indexname; /* original index defined */
+} ClusterStmt;
/* ----------------------
- * Vacuum Statement
+ * Vacuum Statement
* ----------------------
*/
-typedef struct VacuumStmt {
- NodeTag type;
- bool verbose; /* print status info */
- bool analyze; /* analyze data */
- char *vacrel; /* table to vacuum */
- List *va_spec; /* columns to analyse */
-} VacuumStmt;
+typedef struct VacuumStmt
+{
+ NodeTag type;
+ bool verbose; /* print status info */
+ bool analyze; /* analyze data */
+ char *vacrel; /* table to vacuum */
+ List *va_spec; /* columns to analyse */
+} VacuumStmt;
/* ----------------------
- * Explain Statement
+ * Explain Statement
* ----------------------
*/
-typedef struct ExplainStmt {
- NodeTag type;
- Query *query; /* the query */
- bool verbose; /* print plan info */
-} ExplainStmt;
+typedef struct ExplainStmt
+{
+ NodeTag type;
+ Query *query; /* the query */
+ bool verbose; /* print plan info */
+} ExplainStmt;
/* ----------------------
* Set Statement
* ----------------------
*/
-typedef struct VariableSetStmt {
- NodeTag type;
- char *name;
- char *value;
-} VariableSetStmt;
+typedef struct VariableSetStmt
+{
+ NodeTag type;
+ char *name;
+ char *value;
+} VariableSetStmt;
/* ----------------------
* Show Statement
* ----------------------
*/
-typedef struct VariableShowStmt {
- NodeTag type;
- char *name;
-} VariableShowStmt;
+typedef struct VariableShowStmt
+{
+ NodeTag type;
+ char *name;
+} VariableShowStmt;
/* ----------------------
* Reset Statement
* ----------------------
*/
-typedef struct VariableResetStmt {
- NodeTag type;
- char *name;
-} VariableResetStmt;
+typedef struct VariableResetStmt
+{
+ NodeTag type;
+ char *name;
+} VariableResetStmt;
/*****************************************************************************
- * Optimizable Statements
+ * Optimizable Statements
*****************************************************************************/
/* ----------------------
- * Insert Statement
+ * Insert Statement
* ----------------------
*/
-typedef struct AppendStmt {
- NodeTag type;
- char *relname; /* relation to insert into */
- List *cols; /* names of the columns */
- List *targetList; /* the target list (of ResTarget) */
- List *fromClause; /* the from clause */
- Node *whereClause; /* qualifications */
-} AppendStmt;
+typedef struct AppendStmt
+{
+ NodeTag type;
+ char *relname; /* relation to insert into */
+ List *cols; /* names of the columns */
+ List *targetList; /* the target list (of ResTarget) */
+ List *fromClause; /* the from clause */
+ Node *whereClause;/* qualifications */
+} AppendStmt;
/* ----------------------
- * Delete Statement
+ * Delete Statement
* ----------------------
*/
-typedef struct DeleteStmt {
- NodeTag type;
- char *relname; /* relation to delete from */
- Node *whereClause; /* qualifications */
-} DeleteStmt;
+typedef struct DeleteStmt
+{
+ NodeTag type;
+ char *relname; /* relation to delete from */
+ Node *whereClause;/* qualifications */
+} DeleteStmt;
/* ----------------------
- * Update Statement
+ * Update Statement
* ----------------------
*/
-typedef struct ReplaceStmt {
- NodeTag type;
- char *relname; /* relation to update */
- List *targetList; /* the target list (of ResTarget) */
- Node *whereClause; /* qualifications */
- List *fromClause; /* the from clause */
-} ReplaceStmt;
+typedef struct ReplaceStmt
+{
+ NodeTag type;
+ char *relname; /* relation to update */
+ List *targetList; /* the target list (of ResTarget) */
+ Node *whereClause;/* qualifications */
+ List *fromClause; /* the from clause */
+} ReplaceStmt;
/* ----------------------
- * Create Cursor Statement
+ * Create Cursor Statement
* ----------------------
*/
-typedef struct CursorStmt {
- NodeTag type;
- char *portalname; /* the portal (cursor) to create */
- bool binary; /* a binary (internal) portal? */
- char *unique; /* NULL, "*", or unique attribute name */
- List *targetList; /* the target list (of ResTarget) */
- List *fromClause; /* the from clause */
- Node *whereClause; /* qualifications */
- List *groupClause; /* group by clause */
- List *sortClause; /* sort clause (a list of SortGroupBy's) */
-} CursorStmt;
+typedef struct CursorStmt
+{
+ NodeTag type;
+ char *portalname; /* the portal (cursor) to create */
+ bool binary; /* a binary (internal) portal? */
+ char *unique; /* NULL, "*", or unique attribute name */
+ List *targetList; /* the target list (of ResTarget) */
+ List *fromClause; /* the from clause */
+ Node *whereClause;/* qualifications */
+ List *groupClause;/* group by clause */
+ List *sortClause; /* sort clause (a list of SortGroupBy's) */
+} CursorStmt;
/* ----------------------
- * Select Statement
+ * Select Statement
* ----------------------
*/
-typedef struct RetrieveStmt {
- NodeTag type;
- char *unique; /* NULL, '*', or unique attribute name */
- char *into; /* name of table (for select into table) */
- List *targetList; /* the target list (of ResTarget) */
- List *fromClause; /* the from clause */
- Node *whereClause; /* qualifications */
- List *groupClause; /* group by clause */
- Node *havingClause; /* having conditional-expression */
- List *selectClause; /* subselect parameters */
- List *sortClause; /* sort clause (a list of SortGroupBy's) */
-} RetrieveStmt;
+typedef struct RetrieveStmt
+{
+ NodeTag type;
+ char *unique; /* NULL, '*', or unique attribute name */
+ char *into; /* name of table (for select into table) */
+ List *targetList; /* the target list (of ResTarget) */
+ List *fromClause; /* the from clause */
+ Node *whereClause;/* qualifications */
+ List *groupClause;/* group by clause */
+ Node *havingClause; /* having conditional-expression */
+ List *selectClause; /* subselect parameters */
+ List *sortClause; /* sort clause (a list of SortGroupBy's) */
+} RetrieveStmt;
/****************************************************************************
- * Supporting data structures for Parse Trees
+ * Supporting data structures for Parse Trees
****************************************************************************/
/*
* SubSelect - specifies subselect parameters
*/
-typedef struct SubSelect {
- NodeTag type;
- char *unique; /* NULL, '*', or unique attribute name */
- List *targetList; /* the target list (of ResTarget) */
- List *fromClause; /* the from clause */
- Node *whereClause; /* qualifications */
- List *groupClause; /* group by clause */
- Node *havingClause; /* having conditional-expression */
-} SubSelect;
+typedef struct SubSelect
+{
+ NodeTag type;
+ char *unique; /* NULL, '*', or unique attribute name */
+ List *targetList; /* the target list (of ResTarget) */
+ List *fromClause; /* the from clause */
+ Node *whereClause;/* qualifications */
+ List *groupClause;/* group by clause */
+ Node *havingClause; /* having conditional-expression */
+} SubSelect;
/*
* TypeName - specifies a type in definitions
*/
-typedef struct TypeName {
- NodeTag type;
- char *name; /* name of the type */
- bool timezone; /* timezone specified? */
- bool setof; /* is a set? */
- List *arrayBounds; /* array bounds */
- int typlen; /* length for char() and varchar() */
-} TypeName;
+typedef struct TypeName
+{
+ NodeTag type;
+ char *name; /* name of the type */
+ bool timezone; /* timezone specified? */
+ bool setof; /* is a set? */
+ List *arrayBounds;/* array bounds */
+ int typlen; /* length for char() and varchar() */
+} TypeName;
/*
* ParamNo - specifies a parameter reference
*/
-typedef struct ParamNo {
- NodeTag type;
- int number; /* the number of the parameter */
- TypeName *typename; /* the typecast */
-} ParamNo;
+typedef struct ParamNo
+{
+ NodeTag type;
+ int number; /* the number of the parameter */
+ TypeName *typename; /* the typecast */
+} ParamNo;
/*
* A_Expr - binary expressions
*/
-typedef struct A_Expr {
- NodeTag type;
- int oper; /* type of operation
- {OP,OR,AND,NOT,ISNULL,NOTNULL} */
- char *opname; /* name of operator/function */
- Node *lexpr; /* left argument */
- Node *rexpr; /* right argument */
-} A_Expr;
+typedef struct A_Expr
+{
+ NodeTag type;
+ int oper; /* type of operation
+ * {OP,OR,AND,NOT,ISNULL,NOTNULL} */
+ char *opname; /* name of operator/function */
+ Node *lexpr; /* left argument */
+ Node *rexpr; /* right argument */
+} A_Expr;
/*
* Attr -
- * specifies an Attribute (ie. a Column); could have nested dots or
- * array references.
+ * specifies an Attribute (ie. a Column); could have nested dots or
+ * array references.
*
*/
-typedef struct Attr {
- NodeTag type;
- char *relname; /* name of relation (can be "*") */
- ParamNo *paramNo; /* or a parameter */
- List *attrs; /* attributes (possibly nested);
- list of Values (strings) */
- List *indirection; /* array refs (list of A_Indices') */
-} Attr;
+typedef struct Attr
+{
+ NodeTag type;
+ char *relname; /* name of relation (can be "*") */
+ ParamNo *paramNo; /* or a parameter */
+ List *attrs; /* attributes (possibly nested); list of
+ * Values (strings) */
+ List *indirection;/* array refs (list of A_Indices') */
+} Attr;
/*
* A_Const - a constant expression
*/
-typedef struct A_Const {
- NodeTag type;
- Value val; /* the value (with the tag) */
- TypeName *typename; /* typecast */
-} A_Const;
+typedef struct A_Const
+{
+ NodeTag type;
+ Value val; /* the value (with the tag) */
+ TypeName *typename; /* typecast */
+} A_Const;
/*
* ColumnDef - column definition (used in various creates)
*/
-typedef struct ColumnDef {
- NodeTag type;
- char *colname; /* name of column */
- TypeName *typename; /* type of column */
- bool is_not_null; /* flag to NOT NULL constraint */
- char *defval; /* default value of column */
-} ColumnDef;
+typedef struct ColumnDef
+{
+ NodeTag type;
+ char *colname; /* name of column */
+ TypeName *typename; /* type of column */
+ bool is_not_null;/* flag to NOT NULL constraint */
+ char *defval; /* default value of column */
+} ColumnDef;
/*
- * Ident -
- * an identifier (could be an attribute or a relation name). Depending
- * on the context at transformStmt time, the identifier is treated as
- * either a relation name (in which case, isRel will be set) or an
- * attribute (in which case, it will be transformed into an Attr).
- */
-typedef struct Ident {
- NodeTag type;
- char *name; /* its name */
- List *indirection; /* array references */
- bool isRel; /* is a relation - filled in by
- transformExpr() */
-} Ident;
+ * Ident -
+ * an identifier (could be an attribute or a relation name). Depending
+ * on the context at transformStmt time, the identifier is treated as
+ * either a relation name (in which case, isRel will be set) or an
+ * attribute (in which case, it will be transformed into an Attr).
+ */
+typedef struct Ident
+{
+ NodeTag type;
+ char *name; /* its name */
+ List *indirection;/* array references */
+ bool isRel; /* is a relation - filled in by
+ * transformExpr() */
+} Ident;
/*
* FuncCall - a function/aggregate invocation
*/
-typedef struct FuncCall {
- NodeTag type;
- char *funcname; /* name of function */
- List *args; /* the arguments (list of exprs) */
-} FuncCall;
+typedef struct FuncCall
+{
+ NodeTag type;
+ char *funcname; /* name of function */
+ List *args; /* the arguments (list of exprs) */
+} FuncCall;
/*
* A_Indices - array reference or bounds ([lidx:uidx] or [uidx])
*/
-typedef struct A_Indices {
- NodeTag type;
- Node *lidx; /* could be NULL */
- Node *uidx;
-} A_Indices;
+typedef struct A_Indices
+{
+ NodeTag type;
+ Node *lidx; /* could be NULL */
+ Node *uidx;
+} A_Indices;
/*
- * ResTarget -
- * result target (used in target list of pre-transformed Parse trees)
- */
-typedef struct ResTarget {
- NodeTag type;
- char *name; /* name of the result column */
- List *indirection; /* array references */
- Node *val; /* the value of the result
- (A_Expr or Attr) (or A_Const) */
-} ResTarget;
+ * ResTarget -
+ * result target (used in target list of pre-transformed Parse trees)
+ */
+typedef struct ResTarget
+{
+ NodeTag type;
+ char *name; /* name of the result column */
+ List *indirection;/* array references */
+ Node *val; /* the value of the result (A_Expr or
+ * Attr) (or A_Const) */
+} ResTarget;
/*
* ParamString - used in with clauses
*/
-typedef struct ParamString {
- NodeTag type;
- char *name;
- char *val;
-} ParamString;
+typedef struct ParamString
+{
+ NodeTag type;
+ char *name;
+ char *val;
+} ParamString;
/*
* TimeRange - specifies a time range
*/
-typedef struct TimeRange {
- NodeTag type;
- char *startDate;
- char *endDate; /* snapshot if NULL */
-} TimeRange;
+typedef struct TimeRange
+{
+ NodeTag type;
+ char *startDate;
+ char *endDate; /* snapshot if NULL */
+} TimeRange;
/*
* RelExpr - relation expressions
*/
-typedef struct RelExpr {
- NodeTag type;
- char *relname; /* the relation name */
- bool inh; /* inheritance query */
- TimeRange *timeRange; /* the time range */
-} RelExpr;
+typedef struct RelExpr
+{
+ NodeTag type;
+ char *relname; /* the relation name */
+ bool inh; /* inheritance query */
+ TimeRange *timeRange; /* the time range */
+} RelExpr;
/*
* SortGroupBy - for order by clause
*/
-typedef struct SortGroupBy {
- NodeTag type;
- int resno; /* target number */
- char *range;
- char *name; /* name of column to sort on */
- char *useOp; /* operator to use */
-} SortGroupBy;
+typedef struct SortGroupBy
+{
+ NodeTag type;
+ int resno; /* target number */
+ char *range;
+ char *name; /* name of column to sort on */
+ char *useOp; /* operator to use */
+} SortGroupBy;
/*
* RangeVar - range variable, used in from clauses
*/
-typedef struct RangeVar {
- NodeTag type;
- RelExpr *relExpr; /* the relation expression */
- char *name; /* the name to be referenced
- (optional) */
-} RangeVar;
+typedef struct RangeVar
+{
+ NodeTag type;
+ RelExpr *relExpr; /* the relation expression */
+ char *name; /* the name to be referenced (optional) */
+} RangeVar;
/*
* IndexElem - index parameters (used in create index)
*/
-typedef struct IndexElem {
- NodeTag type;
- char *name; /* name of index */
- List *args; /* if not NULL, function index */
- char *class;
- TypeName *tname; /* type of index's keys (optional) */
-} IndexElem;
+typedef struct IndexElem
+{
+ NodeTag type;
+ char *name; /* name of index */
+ List *args; /* if not NULL, function index */
+ char *class;
+ TypeName *tname; /* type of index's keys (optional) */
+} IndexElem;
/*
* DefElem -
- * a definition (used in definition lists in the form of defname = arg)
+ * a definition (used in definition lists in the form of defname = arg)
*/
-typedef struct DefElem {
- NodeTag type;
- char *defname;
- Node *arg; /* a (Value *) or a (TypeName *) */
-} DefElem;
+typedef struct DefElem
+{
+ NodeTag type;
+ char *defname;
+ Node *arg; /* a (Value *) or a (TypeName *) */
+} DefElem;
/****************************************************************************
- * Nodes for a Query tree
+ * Nodes for a Query tree
****************************************************************************/
/*
* TargetEntry -
- * a target entry (used in the transformed target list)
+ * a target entry (used in the transformed target list)
*
* one of resdom or fjoin is not NULL. a target list is
- * ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
+ * ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
*/
-typedef struct TargetEntry {
- NodeTag type;
- Resdom *resdom; /* fjoin overload this to be a list??*/
- Fjoin *fjoin;
- Node *expr; /* can be a list too */
-} TargetEntry;
+typedef struct TargetEntry
+{
+ NodeTag type;
+ Resdom *resdom; /* fjoin overload this to be a list?? */
+ Fjoin *fjoin;
+ Node *expr; /* can be a list too */
+} TargetEntry;
/*
* RangeTblEntry -
- * used in range tables. Some of the following are only used in one of
- * the parsing, optimizing, execution stages.
+ * used in range tables. Some of the following are only used in one of
+ * the parsing, optimizing, execution stages.
*
- * inFromCl marks those range variables that are listed in the from clause.
- * In SQL, the targetlist can only refer to range variables listed in the
- * from clause but POSTQUEL allows you to refer to tables not specified, in
- * which case a range table entry will be generated. We use POSTQUEL
- * semantics which is more powerful. However, we need SQL semantics in
- * some cases (eg. when expanding a '*')
- */
-typedef struct RangeTblEntry {
- NodeTag type;
- char *relname; /* real name of the relation */
- TimeRange *timeRange; /* time range */
- char *refname; /* the reference name (specified in
- the from clause) */
- Oid relid;
- bool inh; /* inheritance? */
- bool archive; /* filled in by plan_archive */
- bool inFromCl; /* comes from From Clause */
- TimeQual timeQual; /* filled in by pg_plan */
-} RangeTblEntry;
+ * inFromCl marks those range variables that are listed in the from clause.
+ * In SQL, the targetlist can only refer to range variables listed in the
+ * from clause but POSTQUEL allows you to refer to tables not specified, in
+ * which case a range table entry will be generated. We use POSTQUEL
+ * semantics which is more powerful. However, we need SQL semantics in
+ * some cases (eg. when expanding a '*')
+ */
+typedef struct RangeTblEntry
+{
+ NodeTag type;
+ char *relname; /* real name of the relation */
+ TimeRange *timeRange; /* time range */
+ char *refname; /* the reference name (specified in the
+ * from clause) */
+ Oid relid;
+ bool inh; /* inheritance? */
+ bool archive; /* filled in by plan_archive */
+ bool inFromCl; /* comes from From Clause */
+ TimeQual timeQual; /* filled in by pg_plan */
+} RangeTblEntry;
/*
* SortClause -
- * used in the sort clause for retrieves and cursors
+ * used in the sort clause for retrieves and cursors
*/
-typedef struct SortClause {
- NodeTag type;
- Resdom *resdom; /* attributes in tlist to be sorted */
- Oid opoid; /* sort operators */
-} SortClause;
+typedef struct SortClause
+{
+ NodeTag type;
+ Resdom *resdom; /* attributes in tlist to be sorted */
+ Oid opoid; /* sort operators */
+} SortClause;
/*
* GroupClause -
- * used in the GROUP BY clause
+ * used in the GROUP BY clause
*/
-typedef struct GroupClause {
- NodeTag type;
- TargetEntry *entry; /* attributes to group on */
- Oid grpOpoid; /* the sort operator to use */
-} GroupClause;
+typedef struct GroupClause
+{
+ NodeTag type;
+ TargetEntry *entry; /* attributes to group on */
+ Oid grpOpoid; /* the sort operator to use */
+} GroupClause;
-#endif /* PARSENODES_H */
+#endif /* PARSENODES_H */
diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h
index b3848fb59fa..9afe6dfac5e 100644
--- a/src/include/nodes/pg_list.h
+++ b/src/include/nodes/pg_list.h
@@ -1,116 +1,120 @@
/*-------------------------------------------------------------------------
*
* pg_list.h--
- * POSTGRES generic list package
+ * POSTGRES generic list package
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_list.h,v 1.5 1997/08/19 21:38:51 momjian Exp $
+ * $Id: pg_list.h,v 1.6 1997/09/07 04:58:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef PG_LIST_H
-#define PG_LIST_H
+#ifndef PG_LIST_H
+#define PG_LIST_H
#include <nodes/nodes.h>
/* ----------------------------------------------------------------
- * node definitions
+ * node definitions
* ----------------------------------------------------------------
*/
/*----------------------
- * Value node
+ * Value node
*----------------------
*/
-typedef struct Value {
- NodeTag type; /* tag appropriately (eg. T_String) */
- union ValUnion {
- char *str; /* string */
- long ival;
- double dval;
- } val;
-} Value;
-
-#define intVal(v) (((Value *)v)->val.ival)
-#define floatVal(v) (((Value *)v)->val.dval)
-#define strVal(v) (((Value *)v)->val.str)
+typedef struct Value
+{
+ NodeTag type; /* tag appropriately (eg. T_String) */
+ union ValUnion
+ {
+ char *str; /* string */
+ long ival;
+ double dval;
+ } val;
+} Value;
+
+#define intVal(v) (((Value *)v)->val.ival)
+#define floatVal(v) (((Value *)v)->val.dval)
+#define strVal(v) (((Value *)v)->val.str)
/*----------------------
- * List node
+ * List node
*----------------------
*/
-typedef struct List {
- NodeTag type;
- union {
- void *ptr_value;
- int int_value;
- } elem;
- struct List *next;
-} List;
-
-#define NIL ((List *) NULL)
+typedef struct List
+{
+ NodeTag type;
+ union
+ {
+ void *ptr_value;
+ int int_value;
+ } elem;
+ struct List *next;
+} List;
+
+#define NIL ((List *) NULL)
/* ----------------
- * accessor macros
+ * accessor macros
* ----------------
*/
/* anything that doesn't end in 'i' is assumed to be referring to the */
-/* pointer version of the list (where it makes a difference) */
-#define lfirst(l) ((l)->elem.ptr_value)
-#define lnext(l) ((l)->next)
-#define lsecond(l) (lfirst(lnext(l)))
+/* pointer version of the list (where it makes a difference) */
+#define lfirst(l) ((l)->elem.ptr_value)
+#define lnext(l) ((l)->next)
+#define lsecond(l) (lfirst(lnext(l)))
-#define lfirsti(l) ((l)->elem.int_value)
+#define lfirsti(l) ((l)->elem.int_value)
/*
* foreach -
- * a convenience macro which loops through the list
+ * a convenience macro which loops through the list
*/
-#define foreach(_elt_,_list_) \
- for(_elt_=_list_; _elt_!=NIL;_elt_=lnext(_elt_))
+#define foreach(_elt_,_list_) \
+ for(_elt_=_list_; _elt_!=NIL;_elt_=lnext(_elt_))
/*
* function prototypes in nodes/list.c
*/
-extern int length(List *list);
-extern List *append(List *list1, List *list2);
-extern List *nconc(List *list1, List *list2);
-extern List *lcons(void *datum, List *list);
-extern bool member(void *foo, List *bar);
-extern Value *makeInteger(long i);
-extern Value *makeFloat(double d);
-extern Value *makeString(char *str);
-extern List *makeList(void *elem, ...);
-extern List *lappend(List *list, void *obj);
-extern List *lremove(void *elem, List *list);
-extern void freeList(List *list);
-extern List *LispRemove(void *elem, List *list);
-
-extern void *nth(int n, List *l);
-extern void set_nth(List *l, int n, void *elem);
-
-List *lconsi(int datum, List *list);
-List *lappendi(List *list, int datum);
-extern bool intMember(int, List *);
-extern List *intAppend(List *list1, List *list2);
-
-extern int nthi(int n, List *l);
-
-extern List *nreverse(List *);
-extern List *set_difference(List *, List *);
-extern List *set_differencei(List *, List *);
-extern List *LispUnion(List *foo, List *bar);
-extern List *LispUnioni(List *foo, List *bar);
-extern bool same(List *foo, List *bar);
+extern int length(List * list);
+extern List *append(List * list1, List * list2);
+extern List *nconc(List * list1, List * list2);
+extern List *lcons(void *datum, List * list);
+extern bool member(void *foo, List * bar);
+extern Value *makeInteger(long i);
+extern Value *makeFloat(double d);
+extern Value *makeString(char *str);
+extern List *makeList(void *elem,...);
+extern List *lappend(List * list, void *obj);
+extern List *lremove(void *elem, List * list);
+extern void freeList(List * list);
+extern List *LispRemove(void *elem, List * list);
+
+extern void *nth(int n, List * l);
+extern void set_nth(List * l, int n, void *elem);
+
+List *lconsi(int datum, List * list);
+List *lappendi(List * list, int datum);
+extern bool intMember(int, List *);
+extern List *intAppend(List * list1, List * list2);
+
+extern int nthi(int n, List * l);
+
+extern List *nreverse(List *);
+extern List *set_difference(List *, List *);
+extern List *set_differencei(List *, List *);
+extern List *LispUnion(List * foo, List * bar);
+extern List *LispUnioni(List * foo, List * bar);
+extern bool same(List * foo, List * bar);
/* should be in nodes.h but needs List */
/* in copyfuncs.c */
-extern List *listCopy(List *);
+extern List *listCopy(List *);
-#endif /* PG_LIST_H */
+#endif /* PG_LIST_H */
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 6e786c34f0e..3353602e02c 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -1,90 +1,91 @@
/*-------------------------------------------------------------------------
*
* plannodes.h--
- * definitions for query plan nodes
+ * definitions for query plan nodes
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: plannodes.h,v 1.6 1997/08/06 03:42:04 momjian Exp $
+ * $Id: plannodes.h,v 1.7 1997/09/07 04:58:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PLANNODES_H
-#define PLANNODES_H
+#define PLANNODES_H
#include <nodes/execnodes.h>
/* ----------------------------------------------------------------
- * Executor State types are used in the plannode structures
- * so we have to include their definitions too.
+ * Executor State types are used in the plannode structures
+ * so we have to include their definitions too.
*
- * Node Type node information used by executor
+ * Node Type node information used by executor
*
* control nodes
*
- * Existential ExistentialState exstate;
- * Result ResultState resstate;
- * Append AppendState unionstate;
+ * Existential ExistentialState exstate;
+ * Result ResultState resstate;
+ * Append AppendState unionstate;
*
* scan nodes
*
- * Scan *** CommonScanState scanstate;
- * IndexScan IndexScanState indxstate;
+ * Scan *** CommonScanState scanstate;
+ * IndexScan IndexScanState indxstate;
*
- * (*** nodes which inherit Scan also inherit scanstate)
+ * (*** nodes which inherit Scan also inherit scanstate)
*
* join nodes
*
- * NestLoop NestLoopState nlstate;
- * MergeJoin MergeJoinState mergestate;
- * HashJoin HashJoinState hashjoinstate;
+ * NestLoop NestLoopState nlstate;
+ * MergeJoin MergeJoinState mergestate;
+ * HashJoin HashJoinState hashjoinstate;
*
* materialize nodes
*
- * Material MaterialState matstate;
- * Sort SortState sortstate;
- * Unique UniqueState uniquestate;
- * Hash HashState hashstate;
+ * Material MaterialState matstate;
+ * Sort SortState sortstate;
+ * Unique UniqueState uniquestate;
+ * Hash HashState hashstate;
*
* ----------------------------------------------------------------
*/
/* ----------------------------------------------------------------
- * node definitions
+ * node definitions
* ----------------------------------------------------------------
*/
/* ----------------
- * Plan node
+ * Plan node
* ----------------
*/
-typedef struct Plan {
- NodeTag type;
- Cost cost;
- int plan_size;
- int plan_width;
- int plan_tupperpage;
- EState *state; /* at execution time, state's of individual
- nodes point to one EState for the
- whole top-level plan */
- List *targetlist;
- List *qual; /* Node* or List* ?? */
- struct Plan *lefttree;
- struct Plan *righttree;
-} Plan;
+typedef struct Plan
+{
+ NodeTag type;
+ Cost cost;
+ int plan_size;
+ int plan_width;
+ int plan_tupperpage;
+ EState *state; /* at execution time, state's of
+ * individual nodes point to one EState
+ * for the whole top-level plan */
+ List *targetlist;
+ List *qual; /* Node* or List* ?? */
+ struct Plan *lefttree;
+ struct Plan *righttree;
+} Plan;
/* ----------------
- * these are are defined to avoid confusion problems with "left"
- * and "right" and "inner" and "outer". The convention is that
- * the "left" plan is the "outer" plan and the "right" plan is
- * the inner plan, but these make the code more readable.
+ * these are are defined to avoid confusion problems with "left"
+ * and "right" and "inner" and "outer". The convention is that
+ * the "left" plan is the "outer" plan and the "right" plan is
+ * the inner plan, but these make the code more readable.
* ----------------
*/
-#define innerPlan(node) (((Plan *)(node))->righttree)
-#define outerPlan(node) (((Plan *)(node))->lefttree)
+#define innerPlan(node) (((Plan *)(node))->righttree)
+#define outerPlan(node) (((Plan *)(node))->lefttree)
/*
@@ -100,61 +101,65 @@ typedef struct Plan {
/* ----------------
- * existential node
+ * existential node
* ----------------
*/
typedef Plan Existential;
/* ----------------
- * result node -
- * returns tuples from outer plan that satisfy the qualifications
+ * result node -
+ * returns tuples from outer plan that satisfy the qualifications
* ----------------
*/
-typedef struct Result {
- Plan plan;
- Node *resconstantqual;
- ResultState *resstate;
-} Result;
+typedef struct Result
+{
+ Plan plan;
+ Node *resconstantqual;
+ ResultState *resstate;
+} Result;
/* ----------------
- * append node
+ * append node
* ----------------
*/
-typedef struct Append {
- Plan plan;
- List *unionplans;
- Index unionrelid;
- List *unionrtentries;
- AppendState *unionstate;
-} Append;
+typedef struct Append
+{
+ Plan plan;
+ List *unionplans;
+ Index unionrelid;
+ List *unionrtentries;
+ AppendState *unionstate;
+} Append;
/*
* ==========
* Scan nodes
* ==========
*/
-typedef struct Scan {
- Plan plan;
- Index scanrelid; /* relid is index into the range table */
- CommonScanState *scanstate;
-} Scan;
+typedef struct Scan
+{
+ Plan plan;
+ Index scanrelid; /* relid is index into the range table */
+ CommonScanState *scanstate;
+} Scan;
/* ----------------
- * sequential scan node
+ * sequential scan node
* ----------------
*/
typedef Scan SeqScan;
/* ----------------
- * index scan node
+ * index scan node
* ----------------
*/
-typedef struct IndexScan {
- Scan scan;
- List *indxid;
- List *indxqual;
- IndexScanState *indxstate;
-} IndexScan;
+typedef struct IndexScan
+{
+ Scan scan;
+ List *indxid;
+ List *indxqual;
+ IndexScanState *indxstate;
+} IndexScan;
/*
* ==========
@@ -163,165 +168,179 @@ typedef struct IndexScan {
*/
/* ----------------
- * Join node
+ * Join node
* ----------------
*/
-typedef Plan Join;
+typedef Plan Join;
/* ----------------
- * nest loop join node
+ * nest loop join node
* ----------------
*/
-typedef struct NestLoop {
- Join join;
- NestLoopState *nlstate;
-} NestLoop;
+typedef struct NestLoop
+{
+ Join join;
+ NestLoopState *nlstate;
+} NestLoop;
/* ----------------
- * merge join node
+ * merge join node
* ----------------
*/
-typedef struct MergeJoin {
- Join join;
- List *mergeclauses;
- Oid mergesortop;
- Oid *mergerightorder; /* inner sort operator */
- Oid *mergeleftorder; /* outer sort operator */
- MergeJoinState *mergestate;
-} MergeJoin;
+typedef struct MergeJoin
+{
+ Join join;
+ List *mergeclauses;
+ Oid mergesortop;
+ Oid *mergerightorder; /* inner sort operator */
+ Oid *mergeleftorder; /* outer sort operator */
+ MergeJoinState *mergestate;
+} MergeJoin;
/* ----------------
- * hash join (probe) node
+ * hash join (probe) node
* ----------------
*/
-typedef struct HashJoin {
- Join join;
- List *hashclauses;
- Oid hashjoinop;
- HashJoinState *hashjoinstate;
- HashJoinTable hashjointable;
- IpcMemoryKey hashjointablekey;
- int hashjointablesize;
- bool hashdone;
-} HashJoin;
+typedef struct HashJoin
+{
+ Join join;
+ List *hashclauses;
+ Oid hashjoinop;
+ HashJoinState *hashjoinstate;
+ HashJoinTable hashjointable;
+ IpcMemoryKey hashjointablekey;
+ int hashjointablesize;
+ bool hashdone;
+} HashJoin;
/* ---------------
- * aggregate node
+ * aggregate node
* ---------------
*/
-typedef struct Agg {
- Plan plan;
- int numAgg;
- Aggreg **aggs;
- AggState *aggstate;
-} Agg;
+typedef struct Agg
+{
+ Plan plan;
+ int numAgg;
+ Aggreg **aggs;
+ AggState *aggstate;
+} Agg;
/* ---------------
- * group node -
- * use for queries with GROUP BY specified.
+ * group node -
+ * use for queries with GROUP BY specified.
*
- * If tuplePerGroup is true, one tuple (with group columns only) is
- * returned for each group and NULL is returned when there are no more
- * groups. Otherwise, all the tuples of a group are returned with a
- * NULL returned at the end of each group. (see nodeGroup.c for details)
+ * If tuplePerGroup is true, one tuple (with group columns only) is
+ * returned for each group and NULL is returned when there are no more
+ * groups. Otherwise, all the tuples of a group are returned with a
+ * NULL returned at the end of each group. (see nodeGroup.c for details)
* ---------------
*/
-typedef struct Group {
- Plan plan;
- bool tuplePerGroup; /* what tuples to return (see above) */
- int numCols; /* number of group columns */
- AttrNumber *grpColIdx; /* index into the target list */
- GroupState *grpstate;
-} Group;
+typedef struct Group
+{
+ Plan plan;
+ bool tuplePerGroup; /* what tuples to return (see
+ * above) */
+ int numCols; /* number of group columns */
+ AttrNumber *grpColIdx; /* index into the target list */
+ GroupState *grpstate;
+} Group;
/*
* ==========
* Temp nodes
* ==========
*/
-typedef struct Temp {
- Plan plan;
- Oid tempid;
- int keycount;
-} Temp;
+typedef struct Temp
+{
+ Plan plan;
+ Oid tempid;
+ int keycount;
+} Temp;
/* ----------------
- * materialization node
+ * materialization node
* ----------------
*/
-typedef struct Material {
- Plan plan; /* temp node flattened out */
- Oid tempid;
- int keycount;
- MaterialState *matstate;
-} Material;
+typedef struct Material
+{
+ Plan plan; /* temp node flattened out */
+ Oid tempid;
+ int keycount;
+ MaterialState *matstate;
+} Material;
/* ----------------
- * sort node
+ * sort node
* ----------------
*/
-typedef struct Sort {
- Plan plan; /* temp node flattened out */
- Oid tempid;
- int keycount;
- SortState *sortstate;
- void *psortstate;
- bool cleaned;
-} Sort;
+typedef struct Sort
+{
+ Plan plan; /* temp node flattened out */
+ Oid tempid;
+ int keycount;
+ SortState *sortstate;
+ void *psortstate;
+ bool cleaned;
+} Sort;
/* ----------------
- * unique node
+ * unique node
* ----------------
*/
-typedef struct Unique {
- Plan plan; /* temp node flattened out */
- Oid tempid;
- int keycount;
- char *uniqueAttr; /* NULL if all attrs,
- or unique attribute name */
- AttrNumber uniqueAttrNum; /* attribute number of attribute
- to select distinct on */
- UniqueState *uniquestate;
-} Unique;
+typedef struct Unique
+{
+ Plan plan; /* temp node flattened out */
+ Oid tempid;
+ int keycount;
+ char *uniqueAttr; /* NULL if all attrs, or unique attribute
+ * name */
+ AttrNumber uniqueAttrNum; /* attribute number of attribute
+ * to select distinct on */
+ UniqueState *uniquestate;
+} Unique;
/* ----------------
- * hash build node
+ * hash build node
* ----------------
*/
-typedef struct Hash {
- Plan plan;
- Var *hashkey;
- HashState *hashstate;
- HashJoinTable hashtable;
- IpcMemoryKey hashtablekey;
- int hashtablesize;
-} Hash;
+typedef struct Hash
+{
+ Plan plan;
+ Var *hashkey;
+ HashState *hashstate;
+ HashJoinTable hashtable;
+ IpcMemoryKey hashtablekey;
+ int hashtablesize;
+} Hash;
/* ---------------------
- * choose node
+ * choose node
* ---------------------
*/
-typedef struct Choose {
- Plan plan;
- List *chooseplanlist;
-} Choose;
+typedef struct Choose
+{
+ Plan plan;
+ List *chooseplanlist;
+} Choose;
/* -------------------
- * Tee node information
+ * Tee node information
*
- * leftParent : the left parent of this node
- * rightParent: the right parent of this node
+ * leftParent : the left parent of this node
+ * rightParent: the right parent of this node
* -------------------
*/
-typedef struct Tee {
- Plan plan;
- Plan* leftParent;
- Plan* rightParent;
- TeeState *teestate;
- char *teeTableName; /* the name of the table to materialize
- the tee into */
- List *rtentries; /* the range table for the plan below the Tee
- may be different than the parent plans */
-} Tee;
-
-#endif /* PLANNODES_H */
+typedef struct Tee
+{
+ Plan plan;
+ Plan *leftParent;
+ Plan *rightParent;
+ TeeState *teestate;
+ char *teeTableName; /* the name of the table to
+ * materialize the tee into */
+ List *rtentries; /* the range table for the plan below the
+ * Tee may be different than the parent
+ * plans */
+} Tee;
+
+#endif /* PLANNODES_H */
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index cd30f229c9c..66d5a52a17e 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1,312 +1,324 @@
/*-------------------------------------------------------------------------
*
* primnodes.h--
- * Definitions for parse tree/query tree ("primitive") nodes.
+ * Definitions for parse tree/query tree ("primitive") nodes.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: primnodes.h,v 1.7 1997/01/22 01:43:44 momjian Exp $
+ * $Id: primnodes.h,v 1.8 1997/09/07 04:58:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PRIMNODES_H
-#define PRIMNODES_H
+#define PRIMNODES_H
#include <utils/fcache.h>
#include <access/attnum.h>
#include <nodes/pg_list.h>
/* ----------------------------------------------------------------
- * node definitions
+ * node definitions
* ----------------------------------------------------------------
*/
/* ----------------
* Resdom (Result Domain)
- * resno - attribute number
- * restype - type of the resdom
- * reslen - length (in bytes) of the result
- * resname - name of the resdom (could be NULL)
- * reskey - order of key in a sort (for those > 0)
- * reskeyop - sort operator Oid
- * resjunk - set to nonzero to eliminate the attribute
- * from final target list e.g., ctid for replace
- * and delete
+ * resno - attribute number
+ * restype - type of the resdom
+ * reslen - length (in bytes) of the result
+ * resname - name of the resdom (could be NULL)
+ * reskey - order of key in a sort (for those > 0)
+ * reskeyop - sort operator Oid
+ * resjunk - set to nonzero to eliminate the attribute
+ * from final target list e.g., ctid for replace
+ * and delete
*
* ----------------
*/
-typedef struct Resdom {
- NodeTag type;
- AttrNumber resno;
- Oid restype;
- int reslen;
- char *resname;
- Index reskey;
- Oid reskeyop;
- int resjunk;
-} Resdom;
+typedef struct Resdom
+{
+ NodeTag type;
+ AttrNumber resno;
+ Oid restype;
+ int reslen;
+ char *resname;
+ Index reskey;
+ Oid reskeyop;
+ int resjunk;
+} Resdom;
/* -------------
* Fjoin
- * initialized - true if the Fjoin has already been initialized for
- * the current target list evaluation
- * nNodes - The number of Iter nodes returning sets that the
- * node will flatten
- * outerList - 1 or more Iter nodes
- * inner - exactly one Iter node. We eval every node in the
- * outerList once then eval the inner node to completion
- * pair the outerList result vector with each inner
- * result to form the full result. When the inner has
- * been exhausted, we get the next outer result vector
- * and reset the inner.
- * results - The complete (flattened) result vector
- * alwaysNull - a null vector to indicate sets with a cardinality of
- * 0, we treat them as the set {NULL}.
+ * initialized - true if the Fjoin has already been initialized for
+ * the current target list evaluation
+ * nNodes - The number of Iter nodes returning sets that the
+ * node will flatten
+ * outerList - 1 or more Iter nodes
+ * inner - exactly one Iter node. We eval every node in the
+ * outerList once then eval the inner node to completion
+ * pair the outerList result vector with each inner
+ * result to form the full result. When the inner has
+ * been exhausted, we get the next outer result vector
+ * and reset the inner.
+ * results - The complete (flattened) result vector
+ * alwaysNull - a null vector to indicate sets with a cardinality of
+ * 0, we treat them as the set {NULL}.
*/
-typedef struct Fjoin {
- NodeTag type;
- bool fj_initialized;
- int fj_nNodes;
- List *fj_innerNode;
- DatumPtr fj_results;
- BoolPtr fj_alwaysDone;
-} Fjoin;
+typedef struct Fjoin
+{
+ NodeTag type;
+ bool fj_initialized;
+ int fj_nNodes;
+ List *fj_innerNode;
+ DatumPtr fj_results;
+ BoolPtr fj_alwaysDone;
+} Fjoin;
/* ----------------
* Expr
- * typeOid - oid of the type of this expression
- * opType - type of this expression
- * oper - the Oper node if it is an OPER_EXPR or the
- * Func node if it is a FUNC_EXPR
- * args - arguments to this expression
+ * typeOid - oid of the type of this expression
+ * opType - type of this expression
+ * oper - the Oper node if it is an OPER_EXPR or the
+ * Func node if it is a FUNC_EXPR
+ * args - arguments to this expression
* ----------------
*/
-typedef enum OpType {
- OP_EXPR, FUNC_EXPR, OR_EXPR, AND_EXPR, NOT_EXPR
-} OpType;
+typedef enum OpType
+{
+ OP_EXPR, FUNC_EXPR, OR_EXPR, AND_EXPR, NOT_EXPR
+} OpType;
-typedef struct Expr {
- NodeTag type;
- Oid typeOid; /* oid of the type of this expr */
- OpType opType; /* type of the op */
- Node *oper; /* could be Oper or Func */
- List *args; /* list of argument nodes */
-} Expr;
+typedef struct Expr
+{
+ NodeTag type;
+ Oid typeOid; /* oid of the type of this expr */
+ OpType opType; /* type of the op */
+ Node *oper; /* could be Oper or Func */
+ List *args; /* list of argument nodes */
+} Expr;
/* ----------------
* Var
- * varno - index of this var's relation in the range table
- * (could be INNER or OUTER)
- * varattno - attribute number of this var, or zero for all
- * vartype - pg_type tuple oid for the type of this var
- * varnoold - keep varno around in case it got changed to INNER/
- * OUTER (see match_varid)
- * varoattno - attribute number of this var
- * [ '(varnoold varoattno) was varid -ay 2/95]
+ * varno - index of this var's relation in the range table
+ * (could be INNER or OUTER)
+ * varattno - attribute number of this var, or zero for all
+ * vartype - pg_type tuple oid for the type of this var
+ * varnoold - keep varno around in case it got changed to INNER/
+ * OUTER (see match_varid)
+ * varoattno - attribute number of this var
+ * [ '(varnoold varoattno) was varid -ay 2/95]
* ----------------
*/
-#define INNER 65000
-#define OUTER 65001
+#define INNER 65000
+#define OUTER 65001
-#define PRS2_CURRENT_VARNO 1
-#define PRS2_NEW_VARNO 2
+#define PRS2_CURRENT_VARNO 1
+#define PRS2_NEW_VARNO 2
-typedef struct Var {
- NodeTag type;
- Index varno;
- AttrNumber varattno;
- Oid vartype;
- Index varnoold; /* only used by optimizer */
- AttrNumber varoattno; /* only used by optimizer */
-} Var;
+typedef struct Var
+{
+ NodeTag type;
+ Index varno;
+ AttrNumber varattno;
+ Oid vartype;
+ Index varnoold; /* only used by optimizer */
+ AttrNumber varoattno; /* only used by optimizer */
+} Var;
/* ----------------
* Oper
- * opno - PG_OPERATOR OID of the operator
- * opid - PG_PROC OID for the operator
- * opresulttype - PG_TYPE OID of the operator's return value
- * opsize - size of return result (cached by executor)
- * op_fcache - XXX comment me.
+ * opno - PG_OPERATOR OID of the operator
+ * opid - PG_PROC OID for the operator
+ * opresulttype - PG_TYPE OID of the operator's return value
+ * opsize - size of return result (cached by executor)
+ * op_fcache - XXX comment me.
*
* ----
* NOTE: in the good old days 'opno' used to be both (or either, or
- * neither) the pg_operator oid, and/or the pg_proc oid depending
+ * neither) the pg_operator oid, and/or the pg_proc oid depending
* on the postgres module in question (parser->pg_operator,
* executor->pg_proc, planner->both), the mood of the programmer,
* and the phase of the moon (rumors that it was also depending on the day
* of the week are probably false). To make things even more postgres-like
* (i.e. a mess) some comments were referring to 'opno' using the name
* 'opid'. Anyway, now we have two separate fields, and of course that
- * immediately removes all bugs from the code... [ sp :-) ].
+ * immediately removes all bugs from the code... [ sp :-) ].
* ----------------
*/
-typedef struct Oper {
- NodeTag type;
- Oid opno;
- Oid opid;
- Oid opresulttype;
- int opsize;
- FunctionCachePtr op_fcache;
-} Oper;
+typedef struct Oper
+{
+ NodeTag type;
+ Oid opno;
+ Oid opid;
+ Oid opresulttype;
+ int opsize;
+ FunctionCachePtr op_fcache;
+} Oper;
/* ----------------
* Const
- * consttype - PG_TYPE OID of the constant's value
- * constlen - length in bytes of the constant's value
- * constvalue - the constant's value
- * constisnull - whether the constant is null
- * (if true, the other fields are undefined)
- * constbyval - whether the information in constvalue
- * if passed by value. If true, then all the information
- * is stored in the datum. If false, then the datum
- * contains a pointer to the information.
- * constisset - whether the const represents a set. The const
- * value corresponding will be the query that defines
- * the set.
+ * consttype - PG_TYPE OID of the constant's value
+ * constlen - length in bytes of the constant's value
+ * constvalue - the constant's value
+ * constisnull - whether the constant is null
+ * (if true, the other fields are undefined)
+ * constbyval - whether the information in constvalue
+ * if passed by value. If true, then all the information
+ * is stored in the datum. If false, then the datum
+ * contains a pointer to the information.
+ * constisset - whether the const represents a set. The const
+ * value corresponding will be the query that defines
+ * the set.
* ----------------
*/
-typedef struct Const {
- NodeTag type;
- Oid consttype;
- Size constlen;
- Datum constvalue;
- bool constisnull;
- bool constbyval;
- bool constisset;
- bool constiscast;
-} Const;
+typedef struct Const
+{
+ NodeTag type;
+ Oid consttype;
+ Size constlen;
+ Datum constvalue;
+ bool constisnull;
+ bool constbyval;
+ bool constisset;
+ bool constiscast;
+} Const;
/* ----------------
* Param
- * paramkind - specifies the kind of parameter. The possible values
- * for this field are specified in "params.h", and they are:
+ * paramkind - specifies the kind of parameter. The possible values
+ * for this field are specified in "params.h", and they are:
*
- * PARAM_NAMED: The parameter has a name, i.e. something
- * like `$.salary' or `$.foobar'.
- * In this case field `paramname' must be a valid Name.
+ * PARAM_NAMED: The parameter has a name, i.e. something
+ * like `$.salary' or `$.foobar'.
+ * In this case field `paramname' must be a valid Name.
*
- * PARAM_NUM: The parameter has only a numeric identifier,
- * i.e. something like `$1', `$2' etc.
- * The number is contained in the `paramid' field.
+ * PARAM_NUM: The parameter has only a numeric identifier,
+ * i.e. something like `$1', `$2' etc.
+ * The number is contained in the `paramid' field.
*
- * PARAM_NEW: Used in PRS2 rule, similar to PARAM_NAMED.
- * The `paramname' and `paramid' refer to the "NEW" tuple
- * The `pramname' is the attribute name and `paramid'
- * is the attribute number.
+ * PARAM_NEW: Used in PRS2 rule, similar to PARAM_NAMED.
+ * The `paramname' and `paramid' refer to the "NEW" tuple
+ * The `pramname' is the attribute name and `paramid'
+ * is the attribute number.
*
- * PARAM_OLD: Same as PARAM_NEW, but in this case we refer to
- * the "OLD" tuple.
+ * PARAM_OLD: Same as PARAM_NEW, but in this case we refer to
+ * the "OLD" tuple.
*
- * paramid - numeric identifier for literal-constant parameters ("$1")
- * paramname - attribute name for tuple-substitution parameters ("$.foo")
- * paramtype - PG_TYPE OID of the parameter's value
- * param_tlist - allows for projection in a param node.
+ * paramid - numeric identifier for literal-constant parameters ("$1")
+ * paramname - attribute name for tuple-substitution parameters ("$.foo")
+ * paramtype - PG_TYPE OID of the parameter's value
+ * param_tlist - allows for projection in a param node.
* ----------------
*/
-typedef struct Param {
- NodeTag type;
- int paramkind;
- AttrNumber paramid;
- char *paramname;
- Oid paramtype;
- List *param_tlist;
-} Param;
+typedef struct Param
+{
+ NodeTag type;
+ int paramkind;
+ AttrNumber paramid;
+ char *paramname;
+ Oid paramtype;
+ List *param_tlist;
+} Param;
/* ----------------
* Func
- * funcid - PG_FUNCTION OID of the function
- * functype - PG_TYPE OID of the function's return value
- * funcisindex - the function can be evaluated by scanning an index
- * (set during query optimization)
- * funcsize - size of return result (cached by executor)
- * func_fcache - runtime state while running this function. Where
- * we are in the execution of the function if it
- * returns more than one value, etc.
- * See utils/fcache.h
- * func_tlist - projection of functions returning tuples
- * func_planlist - result of planning this func, if it's a PQ func
+ * funcid - PG_FUNCTION OID of the function
+ * functype - PG_TYPE OID of the function's return value
+ * funcisindex - the function can be evaluated by scanning an index
+ * (set during query optimization)
+ * funcsize - size of return result (cached by executor)
+ * func_fcache - runtime state while running this function. Where
+ * we are in the execution of the function if it
+ * returns more than one value, etc.
+ * See utils/fcache.h
+ * func_tlist - projection of functions returning tuples
+ * func_planlist - result of planning this func, if it's a PQ func
* ----------------
*/
-typedef struct Func {
- NodeTag type;
- Oid funcid;
- Oid functype;
- bool funcisindex;
- int funcsize;
- FunctionCachePtr func_fcache;
- List *func_tlist;
- List *func_planlist;
-} Func;
+typedef struct Func
+{
+ NodeTag type;
+ Oid funcid;
+ Oid functype;
+ bool funcisindex;
+ int funcsize;
+ FunctionCachePtr func_fcache;
+ List *func_tlist;
+ List *func_planlist;
+} Func;
/* ----------------
* Aggreg
- * aggname - name of the aggregate
- * basetype - base type Oid of the aggregate
- * aggtype - type Oid of final result of the aggregate
- * query - XXX comment me
- * target - XXX comment me
+ * aggname - name of the aggregate
+ * basetype - base type Oid of the aggregate
+ * aggtype - type Oid of final result of the aggregate
+ * query - XXX comment me
+ * target - XXX comment me
* ----------------
*/
-typedef struct Aggreg {
- NodeTag type;
- char *aggname;
- Oid basetype; /* base type of the aggregate */
- Oid aggtype; /* type of final result */
- Node *target; /* attribute to aggreg on */
- int aggno; /* index to ecxt_values */
-} Aggreg;
+typedef struct Aggreg
+{
+ NodeTag type;
+ char *aggname;
+ Oid basetype; /* base type of the aggregate */
+ Oid aggtype; /* type of final result */
+ Node *target; /* attribute to aggreg on */
+ int aggno; /* index to ecxt_values */
+} Aggreg;
/* ----------------
* Array
- * arrayelemtype - base type of the array's elements (homogenous!)
- * arrayelemlength - length of that type
- * arrayelembyval - can you pass this element by value?
- * arrayndim - number of dimensions of the array
- * arraylow - base for array indexing
- * arrayhigh - limit for array indexing
- * arraylen -
+ * arrayelemtype - base type of the array's elements (homogenous!)
+ * arrayelemlength - length of that type
+ * arrayelembyval - can you pass this element by value?
+ * arrayndim - number of dimensions of the array
+ * arraylow - base for array indexing
+ * arrayhigh - limit for array indexing
+ * arraylen -
* ----------------
*
- * memo from mao: the array support we inherited from 3.1 is just
- * wrong. when time exists, we should redesign this stuff to get
- * around a bunch of unfortunate implementation decisions made there.
+ * memo from mao: the array support we inherited from 3.1 is just
+ * wrong. when time exists, we should redesign this stuff to get
+ * around a bunch of unfortunate implementation decisions made there.
*/
-typedef struct Array {
- NodeTag type;
- Oid arrayelemtype;
- int arrayelemlength;
- bool arrayelembyval;
- int arrayndim;
- IntArray arraylow;
- IntArray arrayhigh;
- int arraylen;
-} Array;
+typedef struct Array
+{
+ NodeTag type;
+ Oid arrayelemtype;
+ int arrayelemlength;
+ bool arrayelembyval;
+ int arrayndim;
+ IntArray arraylow;
+ IntArray arrayhigh;
+ int arraylen;
+} Array;
/* ----------------
- * ArrayRef:
- * refelemtype - type of the element referenced here
- * refelemlength - length of that type
- * refelembyval - can you pass this element type by value?
- * refupperindexpr - expressions that evaluate to upper array index
- * reflowerexpr- the expressions that evaluate to a lower array index
- * refexpr - the expression that evaluates to an array
- * refassignexpr- the expression that evaluates to the new value
- * to be assigned to the array in case of replace.
+ * ArrayRef:
+ * refelemtype - type of the element referenced here
+ * refelemlength - length of that type
+ * refelembyval - can you pass this element type by value?
+ * refupperindexpr - expressions that evaluate to upper array index
+ * reflowerexpr- the expressions that evaluate to a lower array index
+ * refexpr - the expression that evaluates to an array
+ * refassignexpr- the expression that evaluates to the new value
+ * to be assigned to the array in case of replace.
* ----------------
*/
-typedef struct ArrayRef {
- NodeTag type;
- int refattrlength;
- int refelemlength;
- Oid refelemtype;
- bool refelembyval;
- List *refupperindexpr;
- List *reflowerindexpr;
- Node *refexpr;
- Node *refassgnexpr;
-} ArrayRef;
+typedef struct ArrayRef
+{
+ NodeTag type;
+ int refattrlength;
+ int refelemlength;
+ Oid refelemtype;
+ bool refelembyval;
+ List *refupperindexpr;
+ List *reflowerindexpr;
+ Node *refexpr;
+ Node *refassgnexpr;
+} ArrayRef;
-#endif /* PRIMNODES_H */
+#endif /* PRIMNODES_H */
diff --git a/src/include/nodes/print.h b/src/include/nodes/print.h
index 0e2585f1de1..8e1a80267d0 100644
--- a/src/include/nodes/print.h
+++ b/src/include/nodes/print.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* execnodes.h--
- * definitions for executor state nodes
+ * definitions for executor state nodes
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: print.h,v 1.2 1997/08/19 21:38:54 momjian Exp $
+ * $Id: print.h,v 1.3 1997/09/07 04:58:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,15 +19,16 @@
#include "nodes/relation.h"
#include "executor/tuptable.h"
-extern void print(void *obj);
-extern void pprint(void *obj);
-extern void print_rt(List *rtable);
-extern void print_expr(Node *expr, List *rtable);
-extern void print_keys(List *keys, List *rtable);
-extern void print_tl(List *tlist, List *rtable);
-extern void print_slot(TupleTableSlot *slot);
-extern void print_plan_recursive (Plan* p, Query *parsetree,
- int indentLevel, char* label);
-extern void print_plan (Plan* p, Query* parsetree);
+extern void print(void *obj);
+extern void pprint(void *obj);
+extern void print_rt(List * rtable);
+extern void print_expr(Node * expr, List * rtable);
+extern void print_keys(List * keys, List * rtable);
+extern void print_tl(List * tlist, List * rtable);
+extern void print_slot(TupleTableSlot * slot);
+extern void
+print_plan_recursive(Plan * p, Query * parsetree,
+ int indentLevel, char *label);
+extern void print_plan(Plan * p, Query * parsetree);
-#endif /* PRINT_H */
+#endif /* PRINT_H */
diff --git a/src/include/nodes/readfuncs.h b/src/include/nodes/readfuncs.h
index 79e18ff61b7..8a23d550a90 100644
--- a/src/include/nodes/readfuncs.h
+++ b/src/include/nodes/readfuncs.h
@@ -1,27 +1,27 @@
/*-------------------------------------------------------------------------
*
* readfuncs.h--
- * header file for read.c and readfuncs.c. These functions are internal
- * to the stringToNode interface and should not be used by anyone else.
+ * header file for read.c and readfuncs.c. These functions are internal
+ * to the stringToNode interface and should not be used by anyone else.
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: readfuncs.h,v 1.2 1996/11/10 03:05:30 momjian Exp $
+ * $Id: readfuncs.h,v 1.3 1997/09/07 04:58:48 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef READFUNCS_H
-#define READFUNCS_H
+#ifndef READFUNCS_H
+#define READFUNCS_H
/*
* prototypes for functions in read.c (the lisp token parser)
*/
-extern char *lsptok(char *string, int *length);
-extern void *nodeRead(bool read_car_only);
+extern char *lsptok(char *string, int *length);
+extern void *nodeRead(bool read_car_only);
/*
- * prototypes for functions in readfuncs.c
+ * prototypes for functions in readfuncs.c
*/
-extern Node *parsePlanString(void);
+extern Node *parsePlanString(void);
-#endif /* READFUNCS_H */
+#endif /* READFUNCS_H */
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 16c7dd29955..7acbc3d466c 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* relation.h--
- * Definitions for internal planner nodes.
+ * Definitions for internal planner nodes.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: relation.h,v 1.4 1997/03/18 18:41:37 scrappy Exp $
+ * $Id: relation.h,v 1.5 1997/09/07 04:58:48 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,260 +18,280 @@
/*
* Relid
- * List of relation identifiers (indexes into the rangetable).
+ * List of relation identifiers (indexes into the rangetable).
*/
-typedef List *Relid;
+typedef List *Relid;
/*
* Rel
- * Per-base-relation information
+ * Per-base-relation information
*
- * Parts of this data structure are specific to various scan and join
- * mechanisms. It didn't seem worth creating new node types for them.
+ * Parts of this data structure are specific to various scan and join
+ * mechanisms. It didn't seem worth creating new node types for them.
*
- * relids - List of relation indentifiers
- * indexed - true if the relation has secondary indices
- * pages - number of pages in the relation
- * tuples - number of tuples in the relation
- * size - number of tuples in the relation after restrictions clauses
- * have been applied
- * width - number of bytes per tuple in the relation after the
- * appropriate projections have been done
- * targetlist - List of TargetList nodes
- * pathlist - List of Path nodes, one for each possible method of
- * generating the relation
- * unorderedpath - a Path node generating this relation whose resulting
- * tuples are unordered (this isn't necessarily a
- * sequential scan path, e.g., scanning with a hash index
- * leaves the tuples unordered)
- * cheapestpath - least expensive Path (regardless of final order)
- * pruneable - flag to let the planner know whether it can prune the plan
- * space of this Rel or not. -- JMH, 11/11/92
+ * relids - List of relation indentifiers
+ * indexed - true if the relation has secondary indices
+ * pages - number of pages in the relation
+ * tuples - number of tuples in the relation
+ * size - number of tuples in the relation after restrictions clauses
+ * have been applied
+ * width - number of bytes per tuple in the relation after the
+ * appropriate projections have been done
+ * targetlist - List of TargetList nodes
+ * pathlist - List of Path nodes, one for each possible method of
+ * generating the relation
+ * unorderedpath - a Path node generating this relation whose resulting
+ * tuples are unordered (this isn't necessarily a
+ * sequential scan path, e.g., scanning with a hash index
+ * leaves the tuples unordered)
+ * cheapestpath - least expensive Path (regardless of final order)
+ * pruneable - flag to let the planner know whether it can prune the plan
+ * space of this Rel or not. -- JMH, 11/11/92
*
- * * If the relation is a (secondary) index it will have the following
- * three fields:
+ * * If the relation is a (secondary) index it will have the following
+ * three fields:
*
- * classlist - List of PG_AMOPCLASS OIDs for the index
- * indexkeys - List of base-relation attribute numbers that are index keys
- * ordering - List of PG_OPERATOR OIDs which order the indexscan result
- * relam - the OID of the pg_am of the index
+ * classlist - List of PG_AMOPCLASS OIDs for the index
+ * indexkeys - List of base-relation attribute numbers that are index keys
+ * ordering - List of PG_OPERATOR OIDs which order the indexscan result
+ * relam - the OID of the pg_am of the index
*
- * * The presence of the remaining fields depends on the restrictions
- * and joins which the relation participates in:
+ * * The presence of the remaining fields depends on the restrictions
+ * and joins which the relation participates in:
*
- * clauseinfo - List of ClauseInfo nodes, containing info about each
- * qualification clause in which this relation participates
- * joininfo - List of JoinInfo nodes, containing info about each join
- * clause in which this relation participates
- * innerjoin - List of Path nodes that represent indices that may be used
- * as inner paths of nestloop joins
+ * clauseinfo - List of ClauseInfo nodes, containing info about each
+ * qualification clause in which this relation participates
+ * joininfo - List of JoinInfo nodes, containing info about each join
+ * clause in which this relation participates
+ * innerjoin - List of Path nodes that represent indices that may be used
+ * as inner paths of nestloop joins
*
* NB. the last element of the arrays classlist, indexkeys and ordering
- * is always 0. 2/95 - ay
+ * is always 0. 2/95 - ay
*/
-typedef struct Rel {
- NodeTag type;
-
- /* all relations: */
- Relid relids;
-
- /* catalog statistics information */
- bool indexed;
- int pages;
- int tuples;
- int size;
- int width;
-
- /* materialization information */
- List *targetlist;
- List *pathlist;
- struct Path *unorderedpath;
- struct Path *cheapestpath;
- bool pruneable;
-
- /* used solely by indices: */
- Oid *classlist; /* classes of AM operators */
- int *indexkeys; /* keys over which we're indexing */
- Oid relam; /* OID of the access method (in pg_am) */
-
- Oid indproc;
- List *indpred;
-
- /* used by various scans and joins: */
- Oid *ordering; /* OID of operators in sort order */
- List *clauseinfo; /* restriction clauses */
- List *joininfo; /* join clauses */
- List *innerjoin;
- List *superrels;
-} Rel;
-
-extern Var *get_expr(TargetEntry *foo);
-
-typedef struct MergeOrder {
- NodeTag type;
- Oid join_operator;
- Oid left_operator;
- Oid right_operator;
- Oid left_type;
- Oid right_type;
-} MergeOrder;
-
-typedef enum OrderType {
- MERGE_ORDER, SORTOP_ORDER
-} OrderType;
-
-typedef struct PathOrder {
- OrderType ordtype;
- union {
- Oid *sortop;
- MergeOrder *merge;
- } ord;
-} PathOrder;
-
-typedef struct Path {
- NodeTag type;
-
- Rel *parent;
- Cost path_cost;
-
- NodeTag pathtype;
-
- PathOrder p_ordering;
-
- List *keys;
- Cost outerjoincost;
- Relid joinid;
- List *locclauseinfo;
-} Path;
-
-typedef struct IndexPath {
- Path path;
- List *indexid;
- List *indexqual;
- int *indexkeys; /* to transform heap attnos into index ones */
-} IndexPath;
-
-typedef struct JoinPath {
- Path path;
- List *pathclauseinfo;
- Path *outerjoinpath;
- Path *innerjoinpath;
-} JoinPath;
-
-typedef struct MergePath {
- JoinPath jpath;
- List *path_mergeclauses;
- List *outersortkeys;
- List *innersortkeys;
-} MergePath;
-
-typedef struct HashPath {
- JoinPath jpath;
- List *path_hashclauses;
- List *outerhashkeys;
- List *innerhashkeys;
-} HashPath;
+typedef struct Rel
+{
+ NodeTag type;
+
+ /* all relations: */
+ Relid relids;
+
+ /* catalog statistics information */
+ bool indexed;
+ int pages;
+ int tuples;
+ int size;
+ int width;
+
+ /* materialization information */
+ List *targetlist;
+ List *pathlist;
+ struct Path *unorderedpath;
+ struct Path *cheapestpath;
+ bool pruneable;
+
+ /* used solely by indices: */
+ Oid *classlist; /* classes of AM operators */
+ int *indexkeys; /* keys over which we're indexing */
+ Oid relam; /* OID of the access method (in pg_am) */
+
+ Oid indproc;
+ List *indpred;
+
+ /* used by various scans and joins: */
+ Oid *ordering; /* OID of operators in sort order */
+ List *clauseinfo; /* restriction clauses */
+ List *joininfo; /* join clauses */
+ List *innerjoin;
+ List *superrels;
+} Rel;
+
+extern Var *get_expr(TargetEntry * foo);
+
+typedef struct MergeOrder
+{
+ NodeTag type;
+ Oid join_operator;
+ Oid left_operator;
+ Oid right_operator;
+ Oid left_type;
+ Oid right_type;
+} MergeOrder;
+
+typedef enum OrderType
+{
+ MERGE_ORDER, SORTOP_ORDER
+} OrderType;
+
+typedef struct PathOrder
+{
+ OrderType ordtype;
+ union
+ {
+ Oid *sortop;
+ MergeOrder *merge;
+ } ord;
+} PathOrder;
+
+typedef struct Path
+{
+ NodeTag type;
+
+ Rel *parent;
+ Cost path_cost;
+
+ NodeTag pathtype;
+
+ PathOrder p_ordering;
+
+ List *keys;
+ Cost outerjoincost;
+ Relid joinid;
+ List *locclauseinfo;
+} Path;
+
+typedef struct IndexPath
+{
+ Path path;
+ List *indexid;
+ List *indexqual;
+ int *indexkeys; /* to transform heap attnos into index
+ * ones */
+} IndexPath;
+
+typedef struct JoinPath
+{
+ Path path;
+ List *pathclauseinfo;
+ Path *outerjoinpath;
+ Path *innerjoinpath;
+} JoinPath;
+
+typedef struct MergePath
+{
+ JoinPath jpath;
+ List *path_mergeclauses;
+ List *outersortkeys;
+ List *innersortkeys;
+} MergePath;
+
+typedef struct HashPath
+{
+ JoinPath jpath;
+ List *path_hashclauses;
+ List *outerhashkeys;
+ List *innerhashkeys;
+} HashPath;
/******
* Keys
******/
-typedef struct OrderKey {
- NodeTag type;
- int attribute_number;
- Index array_index;
-} OrderKey;
+typedef struct OrderKey
+{
+ NodeTag type;
+ int attribute_number;
+ Index array_index;
+} OrderKey;
-typedef struct JoinKey {
- NodeTag type;
- Var *outer;
- Var *inner;
-} JoinKey;
+typedef struct JoinKey
+{
+ NodeTag type;
+ Var *outer;
+ Var *inner;
+} JoinKey;
/*******
* clause info
*******/
-typedef struct CInfo {
- NodeTag type;
- Expr *clause; /* should be an OP clause */
- Cost selectivity;
- bool notclause;
- List *indexids;
-
- /* mergesort only */
- MergeOrder *mergesortorder;
-
- /* hashjoin only */
- Oid hashjoinoperator;
- Relid cinfojoinid;
-} CInfo;
-
-typedef struct JoinMethod {
- NodeTag type;
- List *jmkeys;
- List *clauses;
-} JoinMethod;
-
-typedef struct HInfo {
- JoinMethod jmethod;
- Oid hashop;
-} HInfo;
-
-typedef struct MInfo {
- JoinMethod jmethod;
- MergeOrder *m_ordering;
-} MInfo;
-
-typedef struct JInfo {
- NodeTag type;
- List *otherrels;
- List *jinfoclauseinfo;
- bool mergesortable;
- bool hashjoinable;
- bool inactive;
-} JInfo;
-
-typedef struct Iter {
- NodeTag type;
- Node *iterexpr;
- Oid itertype; /* type of the iter expr (use for type
- checking) */
-} Iter;
+typedef struct CInfo
+{
+ NodeTag type;
+ Expr *clause; /* should be an OP clause */
+ Cost selectivity;
+ bool notclause;
+ List *indexids;
+
+ /* mergesort only */
+ MergeOrder *mergesortorder;
+
+ /* hashjoin only */
+ Oid hashjoinoperator;
+ Relid cinfojoinid;
+} CInfo;
+
+typedef struct JoinMethod
+{
+ NodeTag type;
+ List *jmkeys;
+ List *clauses;
+} JoinMethod;
+
+typedef struct HInfo
+{
+ JoinMethod jmethod;
+ Oid hashop;
+} HInfo;
+
+typedef struct MInfo
+{
+ JoinMethod jmethod;
+ MergeOrder *m_ordering;
+} MInfo;
+
+typedef struct JInfo
+{
+ NodeTag type;
+ List *otherrels;
+ List *jinfoclauseinfo;
+ bool mergesortable;
+ bool hashjoinable;
+ bool inactive;
+} JInfo;
+
+typedef struct Iter
+{
+ NodeTag type;
+ Node *iterexpr;
+ Oid itertype; /* type of the iter expr (use for type
+ * checking) */
+} Iter;
/*
** Stream:
-** A stream represents a root-to-leaf path in a plan tree (i.e. a tree of
+** A stream represents a root-to-leaf path in a plan tree (i.e. a tree of
** JoinPaths and Paths). The stream includes pointers to all Path nodes,
-** as well as to any clauses that reside above Path nodes. This structure
+** as well as to any clauses that reside above Path nodes. This structure
** is used to make Path nodes and clauses look similar, so that Predicate
** Migration can run.
**
-** pathptr -- pointer to the current path node
-** cinfo -- if NULL, this stream node referes to the path node.
-** Otherwise this is a pointer to the current clause.
-** clausetype -- whether cinfo is in locclauseinfo or pathclauseinfo in the
-** path node
-** upstream -- linked list pointer upwards
-** downstream -- ditto, downwards
-** groupup -- whether or not this node is in a group with the node upstream
-** groupcost -- total cost of the group that node is in
-** groupsel -- total selectivity of the group that node is in
+** pathptr -- pointer to the current path node
+** cinfo -- if NULL, this stream node referes to the path node.
+** Otherwise this is a pointer to the current clause.
+** clausetype -- whether cinfo is in locclauseinfo or pathclauseinfo in the
+** path node
+** upstream -- linked list pointer upwards
+** downstream -- ditto, downwards
+** groupup -- whether or not this node is in a group with the node upstream
+** groupcost -- total cost of the group that node is in
+** groupsel -- total selectivity of the group that node is in
*/
typedef struct Stream *StreamPtr;
-typedef struct Stream {
- NodeTag type;
- Path *pathptr;
- CInfo *cinfo;
- int *clausetype;
- struct Stream *upstream;
- struct Stream *downstream;
- bool groupup;
- Cost groupcost;
- Cost groupsel;
-} Stream;
-
-#endif /* RELATION_H */
+typedef struct Stream
+{
+ NodeTag type;
+ Path *pathptr;
+ CInfo *cinfo;
+ int *clausetype;
+ struct Stream *upstream;
+ struct Stream *downstream;
+ bool groupup;
+ Cost groupcost;
+ Cost groupsel;
+} Stream;
+
+#endif /* RELATION_H */
diff --git a/src/include/optimizer/clauseinfo.h b/src/include/optimizer/clauseinfo.h
index 922571aa07a..028979eeb11 100644
--- a/src/include/optimizer/clauseinfo.h
+++ b/src/include/optimizer/clauseinfo.h
@@ -1,24 +1,26 @@
/*-------------------------------------------------------------------------
*
* clauseinfo.h--
- * prototypes for clauseinfo.c.
+ * prototypes for clauseinfo.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: clauseinfo.h,v 1.1 1996/08/28 07:23:10 scrappy Exp $
+ * $Id: clauseinfo.h,v 1.2 1997/09/07 04:58:52 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef CLAUSEINFO_H
#define CLAUSEINFO_H
-extern bool valid_or_clause(CInfo *clauseinfo);
-extern List *get_actual_clauses(List *clauseinfo_list);
-extern void get_relattvals(List *clauseinfo_list, List **attnos,
- List **values, List **flags);
-extern void get_joinvars(Oid relid, List *clauseinfo_list,
- List **attnos, List **values, List **flags);
-extern List *get_opnos(List *clauseinfo_list);
+extern bool valid_or_clause(CInfo * clauseinfo);
+extern List *get_actual_clauses(List * clauseinfo_list);
+extern void
+get_relattvals(List * clauseinfo_list, List ** attnos,
+ List ** values, List ** flags);
+extern void
+get_joinvars(Oid relid, List * clauseinfo_list,
+ List ** attnos, List ** values, List ** flags);
+extern List *get_opnos(List * clauseinfo_list);
-#endif /* CLAUSEINFO_H */
+#endif /* CLAUSEINFO_H */
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index c9a880b030b..bb8d09a4da4 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* clauses.h--
- * prototypes for clauses.c.
+ * prototypes for clauses.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: clauses.h,v 1.3 1997/08/19 21:39:01 momjian Exp $
+ * $Id: clauses.h,v 1.4 1997/09/07 04:58:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,37 +15,39 @@
#include <nodes/primnodes.h>
-extern Expr *make_clause(int type, Node *oper, List *args);
-extern bool is_opclause(Node *clause);
-extern Expr *make_opclause(Oper *op, Var *leftop, Var *rightop);
-extern Var *get_leftop(Expr *clause);
-extern Var *get_rightop(Expr *clause);
-
-extern bool is_funcclause(Node *clause);
-extern Expr *make_funcclause(Func *func, List *funcargs);
-
-extern bool or_clause(Node *clause);
-extern Expr *make_orclause(List *orclauses);
-
-extern bool not_clause(Node *clause);
-extern Expr *make_notclause(Expr *notclause);
-extern Expr *get_notclausearg(Expr *notclause);
-
-extern bool and_clause(Node *clause);
-extern Expr *make_andclause(List *andclauses);
-
-extern List *pull_constant_clauses(List *quals, List **constantQual);
-extern void clause_relids_vars(Node *clause, List **relids, List **vars);
-extern int NumRelids(Node *clause);
-extern bool contains_not(Node *clause);
-extern bool join_clause_p(Node *clause);
-extern bool qual_clause_p(Node *clause);
-extern void fix_opid(Node *clause);
-extern List *fix_opids(List *clauses);
-extern void get_relattval(Node *clause, int *relid,
- AttrNumber *attno, Datum *constval, int *flag);
-extern void get_rels_atts(Node *clause, int *relid1,
- AttrNumber *attno1, int *relid2, AttrNumber *attno2);
-extern void CommuteClause(Node *clause);
-
-#endif /* CLAUSES_H */
+extern Expr *make_clause(int type, Node * oper, List * args);
+extern bool is_opclause(Node * clause);
+extern Expr *make_opclause(Oper * op, Var * leftop, Var * rightop);
+extern Var *get_leftop(Expr * clause);
+extern Var *get_rightop(Expr * clause);
+
+extern bool is_funcclause(Node * clause);
+extern Expr *make_funcclause(Func * func, List * funcargs);
+
+extern bool or_clause(Node * clause);
+extern Expr *make_orclause(List * orclauses);
+
+extern bool not_clause(Node * clause);
+extern Expr *make_notclause(Expr * notclause);
+extern Expr *get_notclausearg(Expr * notclause);
+
+extern bool and_clause(Node * clause);
+extern Expr *make_andclause(List * andclauses);
+
+extern List *pull_constant_clauses(List * quals, List ** constantQual);
+extern void clause_relids_vars(Node * clause, List ** relids, List ** vars);
+extern int NumRelids(Node * clause);
+extern bool contains_not(Node * clause);
+extern bool join_clause_p(Node * clause);
+extern bool qual_clause_p(Node * clause);
+extern void fix_opid(Node * clause);
+extern List *fix_opids(List * clauses);
+extern void
+get_relattval(Node * clause, int *relid,
+ AttrNumber * attno, Datum * constval, int *flag);
+extern void
+get_rels_atts(Node * clause, int *relid1,
+ AttrNumber * attno1, int *relid2, AttrNumber * attno2);
+extern void CommuteClause(Node * clause);
+
+#endif /* CLAUSES_H */
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index f045e47b0bf..bb50d92948c 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* cost.h--
- * prototypes for costsize.c and clausesel.c.
+ * prototypes for costsize.c and clausesel.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: cost.h,v 1.2 1997/08/19 21:39:18 momjian Exp $
+ * $Id: cost.h,v 1.3 1997/09/07 04:58:56 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,43 +15,48 @@
/*
* prototypes for costsize.c--
- * routines to compute costs and sizes
- */
-extern bool _enable_seqscan_;
-extern bool _enable_indexscan_;
-extern bool _enable_sort_;
-extern bool _enable_hash_;
-extern bool _enable_nestloop_;
-extern bool _enable_mergesort_;
-extern bool _enable_hashjoin_;
+ * routines to compute costs and sizes
+ */
+extern bool _enable_seqscan_;
+extern bool _enable_indexscan_;
+extern bool _enable_sort_;
+extern bool _enable_hash_;
+extern bool _enable_nestloop_;
+extern bool _enable_mergesort_;
+extern bool _enable_hashjoin_;
-extern Cost cost_seqscan(int relid, int relpages, int reltuples);
-extern Cost cost_index(Oid indexid, int expected_indexpages, Cost selec,
- int relpages, int reltuples, int indexpages,
- int indextuples, bool is_injoin);
-extern Cost cost_sort(List *keys, int tuples, int width, bool noread);
-extern Cost cost_nestloop(Cost outercost, Cost innercost, int outertuples,
- int innertuples, int outerpages, bool is_indexjoin);
-extern Cost cost_mergesort(Cost outercost, Cost innercost,
- List *outersortkeys, List *innersortkeys,
- int outersize, int innersize, int outerwidth, int innerwidth);
-extern Cost cost_hashjoin(Cost outercost, Cost innercost, List *outerkeys,
- List *innerkeys, int outersize, int innersize,
- int outerwidth, int innerwidth);
-extern int compute_rel_size(Rel *rel);
-extern int compute_rel_width(Rel *rel);
-extern int compute_joinrel_size(JoinPath *joinpath);
-extern int page_size(int tuples, int width);
+extern Cost cost_seqscan(int relid, int relpages, int reltuples);
+extern Cost
+cost_index(Oid indexid, int expected_indexpages, Cost selec,
+ int relpages, int reltuples, int indexpages,
+ int indextuples, bool is_injoin);
+extern Cost cost_sort(List * keys, int tuples, int width, bool noread);
+extern Cost
+cost_nestloop(Cost outercost, Cost innercost, int outertuples,
+ int innertuples, int outerpages, bool is_indexjoin);
+extern Cost
+cost_mergesort(Cost outercost, Cost innercost,
+ List * outersortkeys, List * innersortkeys,
+ int outersize, int innersize, int outerwidth, int innerwidth);
+extern Cost
+cost_hashjoin(Cost outercost, Cost innercost, List * outerkeys,
+ List * innerkeys, int outersize, int innersize,
+ int outerwidth, int innerwidth);
+extern int compute_rel_size(Rel * rel);
+extern int compute_rel_width(Rel * rel);
+extern int compute_joinrel_size(JoinPath * joinpath);
+extern int page_size(int tuples, int width);
/*
* prototypes for fuctions in clausesel.h--
- * routines to compute clause selectivities
+ * routines to compute clause selectivities
*/
-extern void set_clause_selectivities(List *clauseinfo_list, Cost new_selectivity);
-extern Cost product_selec(List *clauseinfo_list);
-extern void set_rest_relselec(Query *root, List *rel_list);
-extern void set_rest_selec(Query *root,List *clauseinfo_list);
-extern Cost compute_clause_selec(Query *root,
- Node *clause, List *or_selectivities);
+extern void set_clause_selectivities(List * clauseinfo_list, Cost new_selectivity);
+extern Cost product_selec(List * clauseinfo_list);
+extern void set_rest_relselec(Query * root, List * rel_list);
+extern void set_rest_selec(Query * root, List * clauseinfo_list);
+extern Cost
+compute_clause_selec(Query * root,
+ Node * clause, List * or_selectivities);
-#endif /* COST_H */
+#endif /* COST_H */
diff --git a/src/include/optimizer/geqo.h b/src/include/optimizer/geqo.h
index 3a566522f7a..28f2dd086f7 100644
--- a/src/include/optimizer/geqo.h
+++ b/src/include/optimizer/geqo.h
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* geqo.h--
- * prototypes for various files in optimizer/geqo
+ * prototypes for various files in optimizer/geqo
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo.h,v 1.3 1997/06/02 11:19:31 vadim Exp $
+ * $Id: geqo.h,v 1.4 1997/09/07 04:58:57 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
-#ifndef GEQO_H
-#define GEQO_H
+#ifndef GEQO_H
+#define GEQO_H
/* GEQO debug flag */
@@ -40,38 +40,39 @@
/* genetic algorithm parameters */
-#define GEQO_FILE "pg_geqo" /* Name of the ga config file */
+#define GEQO_FILE "pg_geqo" /* Name of the ga config file */
-#define MIN_POOL 128 /* minimum number of individuals */
-#define MAX_POOL 1024 /* maximum number of individuals */
+#define MIN_POOL 128 /* minimum number of individuals */
+#define MAX_POOL 1024 /* maximum number of individuals */
-#define LOW_EFFORT 1 /* optimization effort values */
-#define MEDIUM_EFFORT 40 /* are multipliers for computed */
-#define HIGH_EFFORT 80 /* number of generations */
+#define LOW_EFFORT 1 /* optimization effort values */
+#define MEDIUM_EFFORT 40 /* are multipliers for computed */
+#define HIGH_EFFORT 80 /* number of generations */
-#define SELECTION_BIAS 2.0 /* selective pressure within population */
- /* should be 1.5 <= SELECTION_BIAS <= 2.0 */
+#define SELECTION_BIAS 2.0 /* selective pressure within population */
+ /* should be 1.5 <= SELECTION_BIAS <= 2.0 */
- int PoolSize;
- int Generations;
+int PoolSize;
+int Generations;
- long RandomSeed; /* defaults to (long) time(NULL) in geqo_params.c */
- double SelectionBias;
+long RandomSeed; /* defaults to (long) time(NULL) in
+ * geqo_params.c */
+double SelectionBias;
/* logarithmic base for rel->size decrease in case of long
queries that cause an integer overflow; used in geqo_eval.c */
-#define GEQO_LOG_BASE 1.5 /* should be 1.0 < GEQO_LOG_BASE <= 2.0 */
- /* ^^^ */
+#define GEQO_LOG_BASE 1.5 /* should be 1.0 < GEQO_LOG_BASE <= 2.0 */
+ /* ^^^ */
/* geqo prototypes */
-extern Rel *geqo(Query *root);
+extern Rel *geqo(Query * root);
-extern void geqo_params(int string_length);
+extern void geqo_params(int string_length);
-extern Cost geqo_eval (Query *root, Gene *tour, int num_gene);
-double geqo_log(double x, double b);
-extern Rel *gimme_tree(Query *root, Gene *tour, int rel_count, int num_gene, Rel *outer_rel);
+extern Cost geqo_eval(Query * root, Gene * tour, int num_gene);
+double geqo_log(double x, double b);
+extern Rel *gimme_tree(Query * root, Gene * tour, int rel_count, int num_gene, Rel * outer_rel);
-#endif /* GEQO_H */
+#endif /* GEQO_H */
diff --git a/src/include/optimizer/geqo_copy.h b/src/include/optimizer/geqo_copy.h
index fcc61791689..5e1d2f931e1 100644
--- a/src/include/optimizer/geqo_copy.h
+++ b/src/include/optimizer/geqo_copy.h
@@ -1,27 +1,27 @@
/*-------------------------------------------------------------------------
*
* geqo_copy.h--
- * prototypes for copy functions in optimizer/geqo
+ * prototypes for copy functions in optimizer/geqo
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_copy.h,v 1.1 1997/02/19 12:58:32 scrappy Exp $
+ * $Id: geqo_copy.h,v 1.2 1997/09/07 04:58:58 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
-#ifndef GEQO_COPY_H
-#define GEQO_COPY_H
+#ifndef GEQO_COPY_H
+#define GEQO_COPY_H
-extern void geqo_copy (Chromosome *chromo1, Chromosome *chromo2, int string_length);
+extern void geqo_copy(Chromosome * chromo1, Chromosome * chromo2, int string_length);
-#endif /* GEQO_COPY_H */
+#endif /* GEQO_COPY_H */
diff --git a/src/include/optimizer/geqo_gene.h b/src/include/optimizer/geqo_gene.h
index 3d38bd26f8a..b3a685e0d77 100644
--- a/src/include/optimizer/geqo_gene.h
+++ b/src/include/optimizer/geqo_gene.h
@@ -1,42 +1,44 @@
/*-------------------------------------------------------------------------
*
* geqo_gene.h--
- * genome representation in optimizer/geqo
+ * genome representation in optimizer/geqo
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_gene.h,v 1.1 1997/02/19 12:58:37 scrappy Exp $
+ * $Id: geqo_gene.h,v 1.2 1997/09/07 04:58:59 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
-#ifndef GEQO_GENE_H
-#define GEQO_GENE_H
+#ifndef GEQO_GENE_H
+#define GEQO_GENE_H
/* we presume that int instead of Relid
is o.k. for Gene; so don't change it! */
typedef
-int Gene;
-
-typedef struct Chromosome {
- Gene *string;
- Cost worth;
-} Chromosome;
-
-typedef struct Pool {
- Chromosome *data;
- int size;
- int string_length;
-} Pool;
-
-#endif /* GEQO_GENE_H */
+int Gene;
+
+typedef struct Chromosome
+{
+ Gene *string;
+ Cost worth;
+} Chromosome;
+
+typedef struct Pool
+{
+ Chromosome *data;
+ int size;
+ int string_length;
+} Pool;
+
+#endif /* GEQO_GENE_H */
diff --git a/src/include/optimizer/geqo_misc.h b/src/include/optimizer/geqo_misc.h
index 904b85123e3..d3b72cb3028 100644
--- a/src/include/optimizer/geqo_misc.h
+++ b/src/include/optimizer/geqo_misc.h
@@ -1,34 +1,34 @@
/*-------------------------------------------------------------------------
*
* geqo_misc.h--
- * prototypes for printout routines in optimizer/geqo
+ * prototypes for printout routines in optimizer/geqo
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_misc.h,v 1.1 1997/02/19 12:58:41 scrappy Exp $
+ * $Id: geqo_misc.h,v 1.2 1997/09/07 04:59:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
-#ifndef GEQO_MISC_H
-#define GEQO_MISC_H
+#ifndef GEQO_MISC_H
+#define GEQO_MISC_H
#include <stdio.h>
-extern void print_pool (FILE *fp, Pool *pool, int start, int stop);
-extern void print_gen(FILE *fp, Pool *pool, int generation);
-extern void print_edge_table (FILE *fp, Edge *edge_table, int num_gene);
+extern void print_pool(FILE * fp, Pool * pool, int start, int stop);
+extern void print_gen(FILE * fp, Pool * pool, int generation);
+extern void print_edge_table(FILE * fp, Edge * edge_table, int num_gene);
-extern void geqo_print_rel(Query *root, Rel *rel);
-extern void geqo_print_path(Query *root, Path *path, int indent);
-extern void geqo_print_joinclauses(Query *root, List *clauses);
+extern void geqo_print_rel(Query * root, Rel * rel);
+extern void geqo_print_path(Query * root, Path * path, int indent);
+extern void geqo_print_joinclauses(Query * root, List * clauses);
-#endif /* GEQO_MISC_H */
+#endif /* GEQO_MISC_H */
diff --git a/src/include/optimizer/geqo_mutation.h b/src/include/optimizer/geqo_mutation.h
index 91e4b4b5386..cc3f613c780 100644
--- a/src/include/optimizer/geqo_mutation.h
+++ b/src/include/optimizer/geqo_mutation.h
@@ -1,27 +1,27 @@
/*-------------------------------------------------------------------------
*
* geqo_mutation.h--
- * prototypes for mutation functions in optimizer/geqo
+ * prototypes for mutation functions in optimizer/geqo
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_mutation.h,v 1.1 1997/02/19 12:58:49 scrappy Exp $
+ * $Id: geqo_mutation.h,v 1.2 1997/09/07 04:59:01 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
-#ifndef GEQO_MUTATION_H
-#define GEQO_MUTATION_H
+#ifndef GEQO_MUTATION_H
+#define GEQO_MUTATION_H
-extern void geqo_mutation (Gene *tour, int num_gene);
+extern void geqo_mutation(Gene * tour, int num_gene);
-#endif /* GEQO_MUTATION_H */
+#endif /* GEQO_MUTATION_H */
diff --git a/src/include/optimizer/geqo_paths.h b/src/include/optimizer/geqo_paths.h
index c4b890a3dbd..123367ad7e7 100644
--- a/src/include/optimizer/geqo_paths.h
+++ b/src/include/optimizer/geqo_paths.h
@@ -1,28 +1,28 @@
/*-------------------------------------------------------------------------
*
* geqo_paths.h--
- * prototypes for various subroutines in geqo_path.c
+ * prototypes for various subroutines in geqo_path.c
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_paths.h,v 1.1 1997/02/19 12:58:55 scrappy Exp $
+ * $Id: geqo_paths.h,v 1.2 1997/09/07 04:59:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
-#ifndef GEQO_PATHS_H
-#define GEQO_PATHS_H
+#ifndef GEQO_PATHS_H
+#define GEQO_PATHS_H
-extern List *geqo_prune_rels(List *rel_list);
-extern void geqo_rel_paths(Rel *rel);
+extern List *geqo_prune_rels(List * rel_list);
+extern void geqo_rel_paths(Rel * rel);
-#endif /* GEQO_PATHS_H */
+#endif /* GEQO_PATHS_H */
diff --git a/src/include/optimizer/geqo_pool.h b/src/include/optimizer/geqo_pool.h
index ba7cb529726..ffcdc0c50bc 100644
--- a/src/include/optimizer/geqo_pool.h
+++ b/src/include/optimizer/geqo_pool.h
@@ -1,37 +1,37 @@
/*-------------------------------------------------------------------------
*
* geqo_pool.h--
- * pool representation in optimizer/geqo
+ * pool representation in optimizer/geqo
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_pool.h,v 1.1 1997/02/19 12:58:59 scrappy Exp $
+ * $Id: geqo_pool.h,v 1.2 1997/09/07 04:59:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
-#ifndef GEQO_POOL_H
-#define GEQO_POOL_H
+#ifndef GEQO_POOL_H
+#define GEQO_POOL_H
-extern Pool *alloc_pool(int pool_size, int string_length);
-extern void free_pool(Pool *pool);
+extern Pool *alloc_pool(int pool_size, int string_length);
+extern void free_pool(Pool * pool);
-extern void random_init_pool(Query *root, Pool *pool, int strt, int stop);
+extern void random_init_pool(Query * root, Pool * pool, int strt, int stop);
extern Chromosome *alloc_chromo(int string_length);
-extern void free_chromo(Chromosome *chromo);
+extern void free_chromo(Chromosome * chromo);
-extern void spread_chromo(Chromosome *chromo, Pool *pool);
+extern void spread_chromo(Chromosome * chromo, Pool * pool);
-extern void sort_pool (Pool *pool);
+extern void sort_pool(Pool * pool);
-#endif /* GEQO_POOL_H */
+#endif /* GEQO_POOL_H */
diff --git a/src/include/optimizer/geqo_random.h b/src/include/optimizer/geqo_random.h
index 9bb3affe725..73a9d37e53b 100644
--- a/src/include/optimizer/geqo_random.h
+++ b/src/include/optimizer/geqo_random.h
@@ -1,27 +1,27 @@
/*-------------------------------------------------------------------------
*
* geqo_random.h--
- * random number generator
+ * random number generator
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_random.h,v 1.1 1997/02/19 12:59:02 scrappy Exp $
+ * $Id: geqo_random.h,v 1.2 1997/09/07 04:59:03 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
/* -- parts of this are adapted from D. Whitley's Genitor algorithm -- */
-#ifndef GEQO_RANDOM_H
-#define GEQO_RANDOM_H
+#ifndef GEQO_RANDOM_H
+#define GEQO_RANDOM_H
#include <math.h>
@@ -32,6 +32,6 @@
/* geqo_randint returns integer value
between lower and upper inclusive */
-#define geqo_randint(upper,lower) ( (int) floor( geqo_rand()*((upper-lower)+0.999999) ) + lower )
+#define geqo_randint(upper,lower) ( (int) floor( geqo_rand()*((upper-lower)+0.999999) ) + lower )
-#endif /* GEQO_RANDOM_H */
+#endif /* GEQO_RANDOM_H */
diff --git a/src/include/optimizer/geqo_recombination.h b/src/include/optimizer/geqo_recombination.h
index baa7fc24fa4..adcd9343f79 100644
--- a/src/include/optimizer/geqo_recombination.h
+++ b/src/include/optimizer/geqo_recombination.h
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* geqo_recombination.h--
- * prototypes for recombination in the genetic query optimizer
+ * prototypes for recombination in the genetic query optimizer
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_recombination.h,v 1.1 1997/02/19 12:59:04 scrappy Exp $
+ * $Id: geqo_recombination.h,v 1.2 1997/09/07 04:59:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
@@ -24,54 +24,56 @@
#define GEQO_RECOMBINATION_H
-extern void init_tour(Gene *tour, int num_gene);
+extern void init_tour(Gene * tour, int num_gene);
/* edge recombination crossover [ERX] */
-typedef struct Edge {
- Gene edge_list[4]; /* list of edges */
- int total_edges;
- int unused_edges;
-} Edge;
+typedef struct Edge
+{
+ Gene edge_list[4]; /* list of edges */
+ int total_edges;
+ int unused_edges;
+} Edge;
-extern Edge *alloc_edge_table(int num_gene);
-extern void free_edge_table(Edge *edge_table);
+extern Edge *alloc_edge_table(int num_gene);
+extern void free_edge_table(Edge * edge_table);
-extern float gimme_edge_table (Gene *tour1, Gene *tour2, int num_gene, Edge *edge_table);
+extern float gimme_edge_table(Gene * tour1, Gene * tour2, int num_gene, Edge * edge_table);
-extern int gimme_tour(Edge *edge_table, Gene *new_gene, int num_gene);
+extern int gimme_tour(Edge * edge_table, Gene * new_gene, int num_gene);
/* partially matched crossover [PMX] */
-#define DAD 1 /* indicator for gene from dad */
-#define MOM 0 /* indicator for gene from mom */
-
-extern void pmx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene);
+#define DAD 1 /* indicator for gene from dad */
+#define MOM 0 /* indicator for gene from mom */
+extern void pmx(Gene * tour1, Gene * tour2, Gene * offspring, int num_gene);
-typedef struct City {
- int tour2_position;
- int tour1_position;
- int used;
- int select_list;
-} City;
-extern City *alloc_city_table(int num_gene);
-extern void free_city_table(City *city_table);
+typedef struct City
+{
+ int tour2_position;
+ int tour1_position;
+ int used;
+ int select_list;
+} City;
+
+extern City *alloc_city_table(int num_gene);
+extern void free_city_table(City * city_table);
/* cycle crossover [CX] */
-extern int cx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table);
+extern int cx(Gene * tour1, Gene * tour2, Gene * offspring, int num_gene, City * city_table);
/* position crossover [PX] */
-extern void px(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table);
+extern void px(Gene * tour1, Gene * tour2, Gene * offspring, int num_gene, City * city_table);
/* order crossover [OX1] according to Davis */
-extern void ox1(Gene *mom, Gene *dad, Gene *offspring, int num_gene, City *city_table);
+extern void ox1(Gene * mom, Gene * dad, Gene * offspring, int num_gene, City * city_table);
/* order crossover [OX2] according to Syswerda */
-extern void ox2(Gene *mom, Gene *dad, Gene *offspring, int num_gene, City *city_table);
+extern void ox2(Gene * mom, Gene * dad, Gene * offspring, int num_gene, City * city_table);
-#endif /* GEQO_RECOMBINATION_H */
+#endif /* GEQO_RECOMBINATION_H */
diff --git a/src/include/optimizer/geqo_selection.h b/src/include/optimizer/geqo_selection.h
index 8f3c22170f1..289fb73083f 100644
--- a/src/include/optimizer/geqo_selection.h
+++ b/src/include/optimizer/geqo_selection.h
@@ -1,28 +1,28 @@
/*-------------------------------------------------------------------------
*
* geqo_selection.h--
- * prototypes for selection routines in optimizer/geqo
+ * prototypes for selection routines in optimizer/geqo
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_selection.h,v 1.1 1997/02/19 12:59:07 scrappy Exp $
+ * $Id: geqo_selection.h,v 1.2 1997/09/07 04:59:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- * Martin Utesch * Institute of Automatic Control *
- = = University of Mining and Technology =
- * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
-#ifndef GEQO_SELECTION_H
-#define GEQO_SELECTION_H
+#ifndef GEQO_SELECTION_H
+#define GEQO_SELECTION_H
-extern void geqo_selection (Chromosome *momma, Chromosome *daddy, Pool *pool, double bias);
+extern void geqo_selection(Chromosome * momma, Chromosome * daddy, Pool * pool, double bias);
-#endif /* GEQO_SELECTION_H */
+#endif /* GEQO_SELECTION_H */
diff --git a/src/include/optimizer/internal.h b/src/include/optimizer/internal.h
index 68d1f7d71d1..3180f2e3a89 100644
--- a/src/include/optimizer/internal.h
+++ b/src/include/optimizer/internal.h
@@ -1,72 +1,74 @@
/*-------------------------------------------------------------------------
*
* internal.h--
- * Definitions required throughout the query optimizer.
+ * Definitions required throughout the query optimizer.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: internal.h,v 1.7 1997/06/03 03:15:50 vadim Exp $
+ * $Id: internal.h,v 1.8 1997/09/07 04:59:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef INTERNAL_H
#define INTERNAL_H
-/*
- * ---------- SHARED MACROS
- *
- * Macros common to modules for creating, accessing, and modifying
- * query tree and query plan components.
- * Shared with the executor.
- *
+/*
+ * ---------- SHARED MACROS
+ *
+ * Macros common to modules for creating, accessing, and modifying
+ * query tree and query plan components.
+ * Shared with the executor.
+ *
*/
/*
- * System-dependent tuning constants
- *
+ * System-dependent tuning constants
+ *
*/
-#define _CPU_PAGE_WEIGHT_ 0.033 /* CPU-heap-to-page cost weighting factor */
-#define _CPU_INDEX_PAGE_WEIGHT_ 0.017 /* CPU-index-to-page cost weighting factor */
-#define _MAX_KEYS_ INDEX_MAX_KEYS /* maximum number of keys in an index */
-#define _TID_SIZE_ 6 /* sizeof(itemid) (from ../h/itemid.h) */
-
-/*
- * Size estimates
- *
+#define _CPU_PAGE_WEIGHT_ 0.033/* CPU-heap-to-page cost weighting factor */
+#define _CPU_INDEX_PAGE_WEIGHT_ 0.017 /* CPU-index-to-page cost
+ * weighting factor */
+#define _MAX_KEYS_ INDEX_MAX_KEYS /* maximum number of keys in an
+ * index */
+#define _TID_SIZE_ 6 /* sizeof(itemid) (from ../h/itemid.h) */
+
+/*
+ * Size estimates
+ *
*/
-/* The cost of sequentially scanning a materialized temporary relation
+/* The cost of sequentially scanning a materialized temporary relation
*/
-#define _TEMP_SCAN_COST_ 10
+#define _TEMP_SCAN_COST_ 10
-/* The number of pages and tuples in a materialized relation
+/* The number of pages and tuples in a materialized relation
*/
-#define _TEMP_RELATION_PAGES_ 1
-#define _TEMP_RELATION_TUPLES_ 10
+#define _TEMP_RELATION_PAGES_ 1
+#define _TEMP_RELATION_TUPLES_ 10
-/* The length of a variable-length field in bytes
+/* The length of a variable-length field in bytes
*/
#define _DEFAULT_ATTRIBUTE_WIDTH_ (2 * _TID_SIZE_)
-/*
- * Flags and identifiers
- *
+/*
+ * Flags and identifiers
+ *
*/
-/* Identifier for (sort) temp relations */
+/* Identifier for (sort) temp relations */
/* used to be -1 */
-#define _TEMP_RELATION_ID_ InvalidOid
+#define _TEMP_RELATION_ID_ InvalidOid
-/* Identifier for invalid relation OIDs and attribute numbers for use by
- * selectivity functions
+/* Identifier for invalid relation OIDs and attribute numbers for use by
+ * selectivity functions
*/
-#define _SELEC_VALUE_UNKNOWN_ -1
+#define _SELEC_VALUE_UNKNOWN_ -1
-/* Flag indicating that a clause constant is really a parameter (or other
- * non-constant?), a non-parameter, or a constant on the right side
- * of the clause.
+/* Flag indicating that a clause constant is really a parameter (or other
+ * non-constant?), a non-parameter, or a constant on the right side
+ * of the clause.
*/
#define _SELEC_NOT_CONSTANT_ 0
#define _SELEC_IS_CONSTANT_ 1
@@ -78,11 +80,12 @@
#define FLOAT_EQUAL(X,Y) ((X) - (Y) < TOLERANCE)
#define FLOAT_IS_ZERO(X) (FLOAT_EQUAL(X,0.0))
-extern int BushyPlanFlag;
-/* #define deactivate_joininfo(joininfo) joininfo->inactive=true*/
+extern int BushyPlanFlag;
+
+/* #define deactivate_joininfo(joininfo) joininfo->inactive=true*/
/*#define joininfo_inactive(joininfo) joininfo->inactive */
/* GEQO switch according to number of relations in a query */
#define GEQO_RELS 6
-#endif /* INTERNAL_H */
+#endif /* INTERNAL_H */
diff --git a/src/include/optimizer/joininfo.h b/src/include/optimizer/joininfo.h
index 5c3a7ee2910..8294e6cb648 100644
--- a/src/include/optimizer/joininfo.h
+++ b/src/include/optimizer/joininfo.h
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* joininfo.h--
- * prototypes for joininfo.c.
+ * prototypes for joininfo.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: joininfo.h,v 1.1 1996/08/28 07:23:14 scrappy Exp $
+ * $Id: joininfo.h,v 1.2 1997/09/07 04:59:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef JOININFO_H
#define JOININFO_H
-extern JInfo *joininfo_member(List *join_relids, List *joininfo_list);
-extern JInfo *find_joininfo_node(Rel *this_rel, List *join_relids);
-extern Var *other_join_clause_var(Var *var, Expr *clause);
+extern JInfo *joininfo_member(List * join_relids, List * joininfo_list);
+extern JInfo *find_joininfo_node(Rel * this_rel, List * join_relids);
+extern Var *other_join_clause_var(Var * var, Expr * clause);
-#endif /* JOININFO_H */
+#endif /* JOININFO_H */
diff --git a/src/include/optimizer/keys.h b/src/include/optimizer/keys.h
index 29c16d5cbb0..e267777c210 100644
--- a/src/include/optimizer/keys.h
+++ b/src/include/optimizer/keys.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* keys.h--
- * prototypes for keys.c.
+ * prototypes for keys.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: keys.h,v 1.2 1997/08/19 21:39:25 momjian Exp $
+ * $Id: keys.h,v 1.3 1997/09/07 04:59:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef KEYS_H
#define KEYS_H
-extern bool match_indexkey_operand(int indexkey, Var *operand, Rel *rel);
-extern Var *extract_subkey(JoinKey *jk, int which_subkey);
-extern bool samekeys(List *keys1, List *keys2);
-extern List *collect_index_pathkeys(int *index_keys, List *tlist);
+extern bool match_indexkey_operand(int indexkey, Var * operand, Rel * rel);
+extern Var *extract_subkey(JoinKey * jk, int which_subkey);
+extern bool samekeys(List * keys1, List * keys2);
+extern List *collect_index_pathkeys(int *index_keys, List * tlist);
-#endif /* KEYS_H */
+#endif /* KEYS_H */
diff --git a/src/include/optimizer/ordering.h b/src/include/optimizer/ordering.h
index 098691a2d18..7ed360098b7 100644
--- a/src/include/optimizer/ordering.h
+++ b/src/include/optimizer/ordering.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* ordering.h--
- * prototypes for ordering.c.
+ * prototypes for ordering.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: ordering.h,v 1.3 1997/08/19 21:39:29 momjian Exp $
+ * $Id: ordering.h,v 1.4 1997/09/07 04:59:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,10 +15,14 @@
#include <nodes/relation.h>
-extern bool equal_path_path_ordering(PathOrder *path_ordering1,
- PathOrder *path_ordering2);
-extern bool equal_path_merge_ordering(Oid *path_ordering,
- MergeOrder *merge_ordering);
-extern bool equal_merge_merge_ordering(MergeOrder *merge_ordering1,
- MergeOrder *merge_ordering2);
-#endif /* ORDERING_H */
+extern bool
+equal_path_path_ordering(PathOrder * path_ordering1,
+ PathOrder * path_ordering2);
+extern bool
+equal_path_merge_ordering(Oid * path_ordering,
+ MergeOrder * merge_ordering);
+extern bool
+equal_merge_merge_ordering(MergeOrder * merge_ordering1,
+ MergeOrder * merge_ordering2);
+
+#endif /* ORDERING_H */
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index b1353cc971c..9474e1ea8d9 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* pathnode.h--
- * prototypes for pathnode.c, indexnode.c, relnode.c.
+ * prototypes for pathnode.c, indexnode.c, relnode.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pathnode.h,v 1.1 1996/08/28 07:23:18 scrappy Exp $
+ * $Id: pathnode.h,v 1.2 1997/09/07 04:59:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,35 +16,40 @@
/*
* prototypes for pathnode.c
*/
-extern bool path_is_cheaper(Path *path1, Path *path2);
-extern Path *set_cheapest(Rel *parent_rel, List *pathlist);
-extern List *add_pathlist(Rel *parent_rel, List *unique_paths,
- List *new_paths);
-extern Path *create_seqscan_path(Rel *rel);
-extern IndexPath *create_index_path(Query *root, Rel *rel, Rel *index,
- List *restriction_clauses, bool is_join_scan);
-extern JoinPath *create_nestloop_path(Rel *joinrel, Rel *outer_rel,
- Path *outer_path, Path *inner_path, List *keys);
-extern MergePath *create_mergesort_path(Rel *joinrel, int outersize,
- int innersize, int outerwidth, int innerwidth, Path *outer_path,
- Path *inner_path, List *keys, MergeOrder *order,
- List *mergeclauses, List *outersortkeys, List *innersortkeys);
+extern bool path_is_cheaper(Path * path1, Path * path2);
+extern Path *set_cheapest(Rel * parent_rel, List * pathlist);
+extern List *
+add_pathlist(Rel * parent_rel, List * unique_paths,
+ List * new_paths);
+extern Path *create_seqscan_path(Rel * rel);
+extern IndexPath *
+create_index_path(Query * root, Rel * rel, Rel * index,
+ List * restriction_clauses, bool is_join_scan);
+extern JoinPath *
+create_nestloop_path(Rel * joinrel, Rel * outer_rel,
+ Path * outer_path, Path * inner_path, List * keys);
+extern MergePath *
+create_mergesort_path(Rel * joinrel, int outersize,
+ int innersize, int outerwidth, int innerwidth, Path * outer_path,
+ Path * inner_path, List * keys, MergeOrder * order,
+ List * mergeclauses, List * outersortkeys, List * innersortkeys);
-extern HashPath *create_hashjoin_path(Rel *joinrel, int outersize,
- int innersize, int outerwidth, int innerwidth, Path *outer_path,
- Path *inner_path, List *keys, Oid operator, List *hashclauses,
- List *outerkeys, List *innerkeys);
+extern HashPath *
+create_hashjoin_path(Rel * joinrel, int outersize,
+ int innersize, int outerwidth, int innerwidth, Path * outer_path,
+ Path * inner_path, List * keys, Oid operator, List * hashclauses,
+ List * outerkeys, List * innerkeys);
/*
* prototypes for rel.c
*/
-extern Rel *rel_member(List *relid, List *rels);
-extern Rel *get_base_rel(Query* root, int relid);
-extern Rel *get_join_rel(Query* root, List *relid);
+extern Rel *rel_member(List * relid, List * rels);
+extern Rel *get_base_rel(Query * root, int relid);
+extern Rel *get_join_rel(Query * root, List * relid);
/*
* prototypes for indexnode.h
*/
-extern List *find_relation_indices(Query *root,Rel *rel);
+extern List *find_relation_indices(Query * root, Rel * rel);
-#endif /* PATHNODE_H */
+#endif /* PATHNODE_H */
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index 9f76e65ce51..841c4983311 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -1,89 +1,97 @@
/*-------------------------------------------------------------------------
*
* paths.h--
- * prototypes for various files in optimizer/paths (were separate
- * header files
+ * prototypes for various files in optimizer/paths (were separate
+ * header files
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: paths.h,v 1.1 1996/08/28 07:23:19 scrappy Exp $
+ * $Id: paths.h,v 1.2 1997/09/07 04:59:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef PATHS_H
-#define PATHS_H
+#ifndef PATHS_H
+#define PATHS_H
/*
* allpaths.h
*/
-extern List *find_paths(Query *root, List *rels);
+extern List *find_paths(Query * root, List * rels);
/*
* indxpath.h
- * routines to generate index paths
+ * routines to generate index paths
*/
-extern List *find_index_paths(Query *root, Rel *rel, List *indices,
- List *clauseinfo_list,
- List *joininfo_list);
+extern List *
+find_index_paths(Query * root, Rel * rel, List * indices,
+ List * clauseinfo_list,
+ List * joininfo_list);
/*
* joinpath.h
- * routines to create join paths
+ * routines to create join paths
*/
-extern void find_all_join_paths(Query *root, List *joinrels);
-
+extern void find_all_join_paths(Query * root, List * joinrels);
+
/*
* orindxpath.h
*/
-extern List *create_or_index_paths(Query *root, Rel *rel, List *clauses);
+extern List *create_or_index_paths(Query * root, Rel * rel, List * clauses);
/*
* hashutils.h
- * routines to deal with hash keys and clauses
+ * routines to deal with hash keys and clauses
*/
-extern List *group_clauses_by_hashop(List *clauseinfo_list,
- int inner_relid);
+extern List *
+group_clauses_by_hashop(List * clauseinfo_list,
+ int inner_relid);
/*
* joinutils.h
- * generic join method key/clause routines
+ * generic join method key/clause routines
*/
-extern List *match_pathkeys_joinkeys(List *pathkeys,
- List *joinkeys, List *joinclauses, int which_subkey,
- List **matchedJoinClausesPtr);
-extern List *extract_path_keys(List *joinkeys, List *tlist,
- int which_subkey);
-extern Path *match_paths_joinkeys(List *joinkeys, PathOrder *ordering,
- List *paths, int which_subkey);
-extern List *new_join_pathkeys(List *outer_pathkeys,
- List *join_rel_tlist, List *joinclauses);
+extern List *
+match_pathkeys_joinkeys(List * pathkeys,
+ List * joinkeys, List * joinclauses, int which_subkey,
+ List ** matchedJoinClausesPtr);
+extern List *
+extract_path_keys(List * joinkeys, List * tlist,
+ int which_subkey);
+extern Path *
+match_paths_joinkeys(List * joinkeys, PathOrder * ordering,
+ List * paths, int which_subkey);
+extern List *
+new_join_pathkeys(List * outer_pathkeys,
+ List * join_rel_tlist, List * joinclauses);
/*
* mergeutils.h
- * routines to deal with merge keys and clauses
+ * routines to deal with merge keys and clauses
*/
-extern List *group_clauses_by_order(List *clauseinfo_list,
- int inner_relid);
-extern MInfo *match_order_mergeinfo(PathOrder *ordering,
- List *mergeinfo_list);
+extern List *
+group_clauses_by_order(List * clauseinfo_list,
+ int inner_relid);
+extern MInfo *
+match_order_mergeinfo(PathOrder * ordering,
+ List * mergeinfo_list);
/*
* joinrels.h
- * routines to determine which relations to join
+ * routines to determine which relations to join
*/
-extern List *find_join_rels(Query *root, List *outer_rels);
-extern void add_new_joininfos(Query *root, List *joinrels, List *outerrels);
-extern List *final_join_rels(List *join_rel_list);
+extern List *find_join_rels(Query * root, List * outer_rels);
+extern void add_new_joininfos(Query * root, List * joinrels, List * outerrels);
+extern List *final_join_rels(List * join_rel_list);
/*
* prototypes for path/prune.c
*/
-extern List *prune_joinrels(List *rel_list);
-extern void prune_rel_paths(List *rel_list);
-extern Path *prune_rel_path(Rel *rel, Path *unorderedpath);
-extern List *merge_joinrels(List *rel_list1, List *rel_list2);
-extern List *prune_oldrels(List *old_rels);
+extern List *prune_joinrels(List * rel_list);
+extern void prune_rel_paths(List * rel_list);
+extern Path *prune_rel_path(Rel * rel, Path * unorderedpath);
+extern List *merge_joinrels(List * rel_list1, List * rel_list2);
+extern List *prune_oldrels(List * old_rels);
-#endif /* PATHS_H */
+#endif /* PATHS_H */
diff --git a/src/include/optimizer/plancat.h b/src/include/optimizer/plancat.h
index ce752b57366..1b57c575e15 100644
--- a/src/include/optimizer/plancat.h
+++ b/src/include/optimizer/plancat.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* plancat.h--
- * prototypes for plancat.c.
+ * prototypes for plancat.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: plancat.h,v 1.3 1996/11/06 09:24:57 scrappy Exp $
+ * $Id: plancat.h,v 1.4 1997/09/07 04:59:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,47 +19,50 @@
* transient data structure to hold return value of index_info. Note that
* indexkeys, orderOprs and classlist is "null-terminated".
*/
-typedef struct IdxInfoRetval {
- Oid relid; /* OID of the index relation (not the OID
- * of the relation being indexed)
- */
- Oid relam; /* OID of the pg_am of this index */
- int pages; /* number of pages in the index relation */
- int tuples; /* number of tuples in the index relation */
- int *indexkeys; /* keys over which we're indexing */
- Oid *orderOprs; /* operators used for ordering purposes */
- Oid *classlist; /* classes of AM operators */
- Oid indproc;
- Node *indpred;
-} IdxInfoRetval;
+typedef struct IdxInfoRetval
+{
+ Oid relid; /* OID of the index relation (not the OID
+ * of the relation being indexed) */
+ Oid relam; /* OID of the pg_am of this index */
+ int pages; /* number of pages in the index relation */
+ int tuples; /* number of tuples in the index relation */
+ int *indexkeys; /* keys over which we're indexing */
+ Oid *orderOprs; /* operators used for ordering purposes */
+ Oid *classlist; /* classes of AM operators */
+ Oid indproc;
+ Node *indpred;
+} IdxInfoRetval;
-extern void relation_info(Query *root,
- Oid relid,
- bool *hashindex, int *pages,
+extern void
+relation_info(Query * root,
+ Oid relid,
+ bool * hashindex, int *pages,
int *tuples);
-extern bool index_info(Query *root,
- bool first, int relid, IdxInfoRetval *info);
+extern bool
+index_info(Query * root,
+ bool first, int relid, IdxInfoRetval * info);
-extern Cost
+extern Cost
restriction_selectivity(Oid functionObjectId,
- Oid operatorObjectId,
- Oid relationObjectId,
- AttrNumber attributeNumber,
- char *constValue,
- int32 constFlag);
+ Oid operatorObjectId,
+ Oid relationObjectId,
+ AttrNumber attributeNumber,
+ char *constValue,
+ int32 constFlag);
extern void
-index_selectivity(Oid indid, Oid *classes, List *opnos,
- Oid relid, List *attnos, List *values, List *flags,
- int32 nkeys, float *idxPages, float *idxSelec);
+index_selectivity(Oid indid, Oid * classes, List * opnos,
+ Oid relid, List * attnos, List * values, List * flags,
+ int32 nkeys, float *idxPages, float *idxSelec);
-extern Cost join_selectivity(Oid functionObjectId, Oid operatorObjectId,
- Oid relationObjectId1, AttrNumber attributeNumber1,
- Oid relationObjectId2, AttrNumber attributeNumber2);
+extern Cost
+join_selectivity(Oid functionObjectId, Oid operatorObjectId,
+ Oid relationObjectId1, AttrNumber attributeNumber1,
+ Oid relationObjectId2, AttrNumber attributeNumber2);
-extern List *find_inheritance_children(Oid inhparent);
-extern List *VersionGetParents(Oid verrelid);
+extern List *find_inheritance_children(Oid inhparent);
+extern List *VersionGetParents(Oid verrelid);
-#endif /* PLANCAT_H */
+#endif /* PLANCAT_H */
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index e0aec7ec635..9c8abc450d2 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* planmain.h--
- * prototypes for various files in optimizer/plan
+ * prototypes for various files in optimizer/plan
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: planmain.h,v 1.1 1996/08/28 07:23:23 scrappy Exp $
+ * $Id: planmain.h,v 1.2 1997/09/07 04:59:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,44 +17,50 @@
/*
* prototypes for plan/planmain.c
*/
-extern Plan *query_planner(Query *root,
- int command_type, List *tlist, List *qual);
+extern Plan *
+query_planner(Query * root,
+ int command_type, List * tlist, List * qual);
/*
* prototypes for plan/createplan.c
*/
-extern Plan *create_plan(Path *best_path);
-extern SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid,
- Plan *lefttree);
-extern Sort *make_sort(List *tlist, Oid tempid, Plan *lefttree,
- int keycount);
-extern Agg *make_agg(List *tlist, int nagg, Aggreg **aggs);
-extern Group *make_group(List *tlist, bool tuplePerGroup, int ngrp,
- AttrNumber *grpColIdx, Sort *lefttree);
-extern Unique *make_unique(List *tlist, Plan *lefttree, char *uniqueAttr);
-extern List *generate_fjoin(List *tlist);
+extern Plan *create_plan(Path * best_path);
+extern SeqScan *
+make_seqscan(List * qptlist, List * qpqual, Index scanrelid,
+ Plan * lefttree);
+extern Sort *
+make_sort(List * tlist, Oid tempid, Plan * lefttree,
+ int keycount);
+extern Agg *make_agg(List * tlist, int nagg, Aggreg ** aggs);
+extern Group *
+make_group(List * tlist, bool tuplePerGroup, int ngrp,
+ AttrNumber * grpColIdx, Sort * lefttree);
+extern Unique *make_unique(List * tlist, Plan * lefttree, char *uniqueAttr);
+extern List *generate_fjoin(List * tlist);
/*
* prototypes for plan/initsplan.c
*/
-extern void initialize_base_rels_list(Query *root, List *tlist);
-extern void initialize_base_rels_jinfo(Query *root, List *clauses);
-extern void initialize_join_clause_info(List *rel_list);
-extern void add_missing_vars_to_base_rels(Query *root, List *tlist);
+extern void initialize_base_rels_list(Query * root, List * tlist);
+extern void initialize_base_rels_jinfo(Query * root, List * clauses);
+extern void initialize_join_clause_info(List * rel_list);
+extern void add_missing_vars_to_base_rels(Query * root, List * tlist);
/*
* prototypes for plan/setrefs.c
*/
-extern void set_tlist_references(Plan *plan);
-extern List *join_references(List *clauses, List *outer_tlist,
- List *inner_tlist);
-extern List *index_outerjoin_references(List *inner_indxqual,
- List *outer_tlist, Index inner_relid);
-extern void set_result_tlist_references(Result *resultNode);
-extern void set_agg_tlist_references(Agg *aggNode);
-extern void set_agg_agglist_references(Agg *aggNode);
+extern void set_tlist_references(Plan * plan);
+extern List *
+join_references(List * clauses, List * outer_tlist,
+ List * inner_tlist);
+extern List *
+index_outerjoin_references(List * inner_indxqual,
+ List * outer_tlist, Index inner_relid);
+extern void set_result_tlist_references(Result * resultNode);
+extern void set_agg_tlist_references(Agg * aggNode);
+extern void set_agg_agglist_references(Agg * aggNode);
-#endif /* PLANMAIN_H */
+#endif /* PLANMAIN_H */
diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h
index 649974cb5ff..d8f7be50e6f 100644
--- a/src/include/optimizer/planner.h
+++ b/src/include/optimizer/planner.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* planner.h--
- * prototypes for planner.c.
+ * prototypes for planner.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: planner.h,v 1.2 1996/11/06 10:30:20 scrappy Exp $
+ * $Id: planner.h,v 1.3 1997/09/07 04:59:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,7 +16,7 @@
/*
*/
-extern Plan *planner(Query *parse);
-extern void pg_checkretval(Oid rettype, QueryTreeList *querytree_list);
+extern Plan *planner(Query * parse);
+extern void pg_checkretval(Oid rettype, QueryTreeList * querytree_list);
-#endif /* PLANNER_H */
+#endif /* PLANNER_H */
diff --git a/src/include/optimizer/prep.h b/src/include/optimizer/prep.h
index b6c6ae549fd..6e408a84173 100644
--- a/src/include/optimizer/prep.h
+++ b/src/include/optimizer/prep.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* prep.h--
- * prototypes for files in prep.c
+ * prototypes for files in prep.c
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: prep.h,v 1.2 1996/11/06 09:17:31 scrappy Exp $
+ * $Id: prep.h,v 1.3 1997/09/07 04:59:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PREP_H
-#define PREP_H
+#define PREP_H
#include <nodes/plannodes.h>
#include <nodes/parsenodes.h>
@@ -19,33 +19,38 @@
/*
* prototypes for archive.h
*/
-extern void plan_archive(List *rt);
-extern List *find_archive_rels(Oid relid);
+extern void plan_archive(List * rt);
+extern List *find_archive_rels(Oid relid);
/*
* prototypes for prepqual.h
*/
-extern List *preprocess_qualification(Expr *qual, List *tlist,
- List **existentialQualPtr);
-extern List *cnfify(Expr *qual, bool removeAndFlag);
+extern List *
+preprocess_qualification(Expr * qual, List * tlist,
+ List ** existentialQualPtr);
+extern List *cnfify(Expr * qual, bool removeAndFlag);
/*
* prototypes for preptlist.h
*/
-extern List *preprocess_targetlist(List *tlist, int command_type,
- Index result_relation, List *range_table);
+extern List *
+preprocess_targetlist(List * tlist, int command_type,
+ Index result_relation, List * range_table);
/*
* prototypes for prepunion.h
*/
-typedef enum UnionFlag {
- INHERITS_FLAG, ARCHIVE_FLAG, VERSION_FLAG
-} UnionFlag;
+typedef enum UnionFlag
+{
+ INHERITS_FLAG, ARCHIVE_FLAG, VERSION_FLAG
+} UnionFlag;
-extern List *find_all_inheritors(List *unexamined_relids,
- List *examined_relids);
-extern int first_matching_rt_entry(List *rangetable, UnionFlag flag);
-extern Append *plan_union_queries(Index rt_index, Query *parse,
- UnionFlag flag);
+extern List *
+find_all_inheritors(List * unexamined_relids,
+ List * examined_relids);
+extern int first_matching_rt_entry(List * rangetable, UnionFlag flag);
+extern Append *
+plan_union_queries(Index rt_index, Query * parse,
+ UnionFlag flag);
-#endif /* PREP_H */
+#endif /* PREP_H */
diff --git a/src/include/optimizer/tlist.h b/src/include/optimizer/tlist.h
index efffa8b444e..e83c1d10677 100644
--- a/src/include/optimizer/tlist.h
+++ b/src/include/optimizer/tlist.h
@@ -1,34 +1,36 @@
/*-------------------------------------------------------------------------
*
* tlist.h--
- * prototypes for tlist.c.
+ * prototypes for tlist.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: tlist.h,v 1.2 1997/08/19 21:39:31 momjian Exp $
+ * $Id: tlist.h,v 1.3 1997/09/07 04:59:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef TLIST_H
#define TLIST_H
-extern int exec_tlist_length(List *targelist);
-extern TargetEntry *tlistentry_member(Var *var, List *targetlist);
-extern Expr *matching_tlvar(Var *var, List *targetlist);
-extern void add_tl_element(Rel *rel, Var *var);
-extern TargetEntry *create_tl_element(Var *var, int resdomno);
-extern List *get_actual_tlist(List *tlist);
-extern Resdom *tlist_member(Var *var, List *tlist);
-extern Resdom *tlist_resdom(List *tlist, Resdom *resnode);
+extern int exec_tlist_length(List * targelist);
+extern TargetEntry *tlistentry_member(Var * var, List * targetlist);
+extern Expr *matching_tlvar(Var * var, List * targetlist);
+extern void add_tl_element(Rel * rel, Var * var);
+extern TargetEntry *create_tl_element(Var * var, int resdomno);
+extern List *get_actual_tlist(List * tlist);
+extern Resdom *tlist_member(Var * var, List * tlist);
+extern Resdom *tlist_resdom(List * tlist, Resdom * resnode);
-extern TargetEntry *MakeTLE(Resdom *resdom, Node *expr);
-extern Var *get_expr(TargetEntry *tle);
+extern TargetEntry *MakeTLE(Resdom * resdom, Node * expr);
+extern Var *get_expr(TargetEntry * tle);
-extern TargetEntry *match_varid(Var *test_var, List *tlist);
-extern List *new_unsorted_tlist(List *targetlist);
-extern List *copy_vars(List *target, List *source);
-extern List *flatten_tlist(List *tlist);
-extern List *flatten_tlist_vars(List *full_tlist,
- List *flat_tlist);
-#endif /* TLIST_H */
+extern TargetEntry *match_varid(Var * test_var, List * tlist);
+extern List *new_unsorted_tlist(List * targetlist);
+extern List *copy_vars(List * target, List * source);
+extern List *flatten_tlist(List * tlist);
+extern List *
+flatten_tlist_vars(List * full_tlist,
+ List * flat_tlist);
+
+#endif /* TLIST_H */
diff --git a/src/include/optimizer/var.h b/src/include/optimizer/var.h
index 2df81e086d7..519b6957249 100644
--- a/src/include/optimizer/var.h
+++ b/src/include/optimizer/var.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* var.h--
- * prototypes for var.c.
+ * prototypes for var.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: var.h,v 1.1 1996/08/28 07:23:29 scrappy Exp $
+ * $Id: var.h,v 1.2 1997/09/07 04:59:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef VAR_H
#define VAR_H
-extern List *pull_varnos(Node *me);
-extern bool contain_var_clause(Node *clause);
-extern List *pull_var_clause(Node *clause);
-extern bool var_equal(Var *var1, Var *var2);
+extern List *pull_varnos(Node * me);
+extern bool contain_var_clause(Node * clause);
+extern List *pull_var_clause(Node * clause);
+extern bool var_equal(Var * var1, Var * var2);
-#endif /* VAR_H */
+#endif /* VAR_H */
diff --git a/src/include/optimizer/xfunc.h b/src/include/optimizer/xfunc.h
index a1715bb544c..a608771effb 100644
--- a/src/include/optimizer/xfunc.h
+++ b/src/include/optimizer/xfunc.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* xfunc.h--
- * prototypes for xfunc.c and predmig.c.
+ * prototypes for xfunc.c and predmig.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: xfunc.h,v 1.2 1996/11/06 07:44:13 scrappy Exp $
+ * $Id: xfunc.h,v 1.3 1997/09/07 04:59:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,19 +17,21 @@
#include <nodes/relation.h>
/* command line arg flags */
-#define XFUNC_OFF -1 /* do no optimization of expensive preds */
-#define XFUNC_NOR 2 /* do no optimization of OR clauses */
-#define XFUNC_NOPULL 4 /* never pull restrictions above joins */
-#define XFUNC_NOPM 8 /* don't do predicate migration */
-#define XFUNC_WAIT 16 /* don't do pullup until predicate migration */
-#define XFUNC_PULLALL 32 /* pull all expensive restrictions up, always */
+#define XFUNC_OFF -1 /* do no optimization of expensive preds */
+#define XFUNC_NOR 2 /* do no optimization of OR clauses */
+#define XFUNC_NOPULL 4 /* never pull restrictions above joins */
+#define XFUNC_NOPM 8 /* don't do predicate migration */
+#define XFUNC_WAIT 16 /* don't do pullup until predicate
+ * migration */
+#define XFUNC_PULLALL 32 /* pull all expensive restrictions up,
+ * always */
/* constants for local and join predicates */
#define XFUNC_LOCPRD 1
#define XFUNC_JOINPRD 2
#define XFUNC_UNKNOWN 0
-extern int XfuncMode; /* defined in tcop/postgres.c */
+extern int XfuncMode; /* defined in tcop/postgres.c */
/* defaults for function attributes used for expensive function calculations */
#define BYTE_PCT 100
@@ -47,39 +49,42 @@ extern int XfuncMode; /* defined in tcop/postgres.c */
#define is_join(pathnode) (length(get_relids(get_parent(pathnode))) > 1 ? 1 : 0)
/* function prototypes from planner/path/xfunc.c */
-extern void xfunc_trypullup(Rel *rel);
-extern int xfunc_shouldpull(Path *childpath, JoinPath *parentpath,
- int whichchild, CInfo *maxcinfopt);
-extern CInfo *xfunc_pullup(Path *childpath, JoinPath *parentpath, CInfo *cinfo,
- int whichchild, int clausetype);
-extern Cost xfunc_rank(Expr *clause);
-extern Cost xfunc_expense(Query* queryInfo, Expr *clause);
-extern Cost xfunc_join_expense(JoinPath *path, int whichchild);
-extern Cost xfunc_local_expense(Expr *clause);
-extern Cost xfunc_func_expense(Expr *node, List *args);
-extern int xfunc_width(Expr *clause);
+extern void xfunc_trypullup(Rel * rel);
+extern int
+xfunc_shouldpull(Path * childpath, JoinPath * parentpath,
+ int whichchild, CInfo * maxcinfopt);
+extern CInfo *
+xfunc_pullup(Path * childpath, JoinPath * parentpath, CInfo * cinfo,
+ int whichchild, int clausetype);
+extern Cost xfunc_rank(Expr * clause);
+extern Cost xfunc_expense(Query * queryInfo, Expr * clause);
+extern Cost xfunc_join_expense(JoinPath * path, int whichchild);
+extern Cost xfunc_local_expense(Expr * clause);
+extern Cost xfunc_func_expense(Expr * node, List * args);
+extern int xfunc_width(Expr * clause);
+
/* static, moved to xfunc.c */
/* extern int xfunc_card_unreferenced(Expr *clause, Relid referenced); */
-extern int xfunc_card_product(Relid relids);
-extern List *xfunc_find_references(List *clause);
-extern List *xfunc_primary_join(JoinPath *pathnode);
-extern Cost xfunc_get_path_cost(Path *pathnode);
-extern Cost xfunc_total_path_cost(JoinPath *pathnode);
-extern Cost xfunc_expense_per_tuple(JoinPath *joinnode, int whichchild);
-extern void xfunc_fixvars(Expr *clause, Rel *rel, int varno);
-extern int xfunc_cinfo_compare(void *arg1, void *arg2);
-extern int xfunc_clause_compare(void *arg1, void *arg2);
-extern void xfunc_disjunct_sort(List *clause_list);
-extern int xfunc_disjunct_compare(void *arg1, void *arg2);
-extern int xfunc_func_width(RegProcedure funcid, List *args);
-extern int xfunc_tuple_width(Relation rd);
-extern int xfunc_num_join_clauses(JoinPath *path);
-extern List *xfunc_LispRemove(List *foo, List *bar);
-extern bool xfunc_copyrel(Rel *from, Rel **to);
+extern int xfunc_card_product(Relid relids);
+extern List *xfunc_find_references(List * clause);
+extern List *xfunc_primary_join(JoinPath * pathnode);
+extern Cost xfunc_get_path_cost(Path * pathnode);
+extern Cost xfunc_total_path_cost(JoinPath * pathnode);
+extern Cost xfunc_expense_per_tuple(JoinPath * joinnode, int whichchild);
+extern void xfunc_fixvars(Expr * clause, Rel * rel, int varno);
+extern int xfunc_cinfo_compare(void *arg1, void *arg2);
+extern int xfunc_clause_compare(void *arg1, void *arg2);
+extern void xfunc_disjunct_sort(List * clause_list);
+extern int xfunc_disjunct_compare(void *arg1, void *arg2);
+extern int xfunc_func_width(RegProcedure funcid, List * args);
+extern int xfunc_tuple_width(Relation rd);
+extern int xfunc_num_join_clauses(JoinPath * path);
+extern List *xfunc_LispRemove(List * foo, List * bar);
+extern bool xfunc_copyrel(Rel * from, Rel ** to);
/*
* function prototypes for path/predmig.c
*/
-extern bool xfunc_do_predmig(Path root);
+extern bool xfunc_do_predmig(Path root);
-#endif /* XFUNC_H */
+#endif /* XFUNC_H */
diff --git a/src/include/parser/catalog_utils.h b/src/include/parser/catalog_utils.h
index dc4a7f90fa5..dd2241e19e0 100644
--- a/src/include/parser/catalog_utils.h
+++ b/src/include/parser/catalog_utils.h
@@ -1,53 +1,54 @@
/*-------------------------------------------------------------------------
*
* catalog_utils.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: catalog_utils.h,v 1.10 1997/08/19 21:39:33 momjian Exp $
+ * $Id: catalog_utils.h,v 1.11 1997/09/07 04:59:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef CATALOG_UTILS_H
-#define CATALOG_UTILS_H
+#ifndef CATALOG_UTILS_H
+#define CATALOG_UTILS_H
#include <catalog/pg_type.h>
#include <access/htup.h>
-
-typedef HeapTuple Type;
-typedef HeapTuple Operator;
-extern Type get_id_type(Oid id);
-extern char *get_id_typname(Oid id);
-extern Type type(char *);
-extern Oid att_typeid(Relation rd, int attid);
-extern int att_attnelems(Relation rd, int attid);
-extern Oid typeid(Type tp);
-extern int16 tlen(Type t);
-extern bool tbyval(Type t);
-extern char *tname(Type t);
-extern int tbyvalue(Type t);
-extern Oid oprid(Operator op);
+typedef HeapTuple Type;
+typedef HeapTuple Operator;
+
+extern Type get_id_type(Oid id);
+extern char *get_id_typname(Oid id);
+extern Type type(char *);
+extern Oid att_typeid(Relation rd, int attid);
+extern int att_attnelems(Relation rd, int attid);
+extern Oid typeid(Type tp);
+extern int16 tlen(Type t);
+extern bool tbyval(Type t);
+extern char *tname(Type t);
+extern int tbyvalue(Type t);
+extern Oid oprid(Operator op);
extern Operator oper(char *op, Oid arg1, Oid arg2, bool noWarnings);
extern Operator right_oper(char *op, Oid arg);
extern Operator left_oper(char *op, Oid arg);
-extern int varattno(Relation rd, char *a);
-extern bool varisset(Relation rd, char *name);
-extern int nf_varattno(Relation rd, char *a);
-extern char *getAttrName(Relation rd, int attrno);
-extern char *instr2(Type tp, char *string, int typlen);
-extern Oid GetArrayElementType(Oid typearray);
-extern Oid funcid_get_rettype(Oid funcid);
-extern bool func_get_detail(char *funcname, int nargs, Oid *oid_array,
- Oid *funcid, Oid *rettype, bool *retset, Oid **true_typeids);
-extern Oid typeid_get_retinfunc(Oid type_id);
-extern Oid typeid_get_retoutfunc(Oid type_id);
-extern Oid typeid_get_relid(Oid type_id);
-extern Oid get_typrelid(Type typ);
-extern Oid get_typelem(Oid type_id);
-extern void func_error(char *caller, char *funcname, int nargs, Oid *argtypes);
-extern void agg_error(char *caller, char *aggname, Oid basetypeID);
+extern int varattno(Relation rd, char *a);
+extern bool varisset(Relation rd, char *name);
+extern int nf_varattno(Relation rd, char *a);
+extern char *getAttrName(Relation rd, int attrno);
+extern char *instr2(Type tp, char *string, int typlen);
+extern Oid GetArrayElementType(Oid typearray);
+extern Oid funcid_get_rettype(Oid funcid);
+extern bool
+func_get_detail(char *funcname, int nargs, Oid * oid_array,
+ Oid * funcid, Oid * rettype, bool * retset, Oid ** true_typeids);
+extern Oid typeid_get_retinfunc(Oid type_id);
+extern Oid typeid_get_retoutfunc(Oid type_id);
+extern Oid typeid_get_relid(Oid type_id);
+extern Oid get_typrelid(Type typ);
+extern Oid get_typelem(Oid type_id);
+extern void func_error(char *caller, char *funcname, int nargs, Oid * argtypes);
+extern void agg_error(char *caller, char *aggname, Oid basetypeID);
-#endif /* CATALOG_UTILS_H */
+#endif /* CATALOG_UTILS_H */
diff --git a/src/include/parser/dbcommands.h b/src/include/parser/dbcommands.h
index 86a0b47fd6b..4a7f32225ca 100644
--- a/src/include/parser/dbcommands.h
+++ b/src/include/parser/dbcommands.h
@@ -1,27 +1,26 @@
/*-------------------------------------------------------------------------
*
* dbcommands.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: dbcommands.h,v 1.2 1997/08/19 21:39:35 momjian Exp $
+ * $Id: dbcommands.h,v 1.3 1997/09/07 04:59:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef DBCOMMANDS_H
-#define DBCOMMANDS_H
+#ifndef DBCOMMANDS_H
+#define DBCOMMANDS_H
/*
* Originally from tmp/daemon.h. The functions declared in daemon.h does not
- * exist; hence removed. -- AY 7/29/94
+ * exist; hence removed. -- AY 7/29/94
*/
-#define SIGKILLDAEMON1 SIGINT
-#define SIGKILLDAEMON2 SIGTERM
-
-extern void createdb(char *dbname);
-extern void destroydb(char *dbname);
+#define SIGKILLDAEMON1 SIGINT
+#define SIGKILLDAEMON2 SIGTERM
-#endif /* DBCOMMANDS_H */
+extern void createdb(char *dbname);
+extern void destroydb(char *dbname);
+#endif /* DBCOMMANDS_H */
diff --git a/src/include/parser/gramparse.h b/src/include/parser/gramparse.h
index 11cfa97019d..67ed5940f27 100644
--- a/src/include/parser/gramparse.h
+++ b/src/include/parser/gramparse.h
@@ -1,24 +1,24 @@
/*-------------------------------------------------------------------------
*
* gramparse.h--
- * scanner support routines. used by both the bootstrap lexer
+ * scanner support routines. used by both the bootstrap lexer
* as well as the normal lexer
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: gramparse.h,v 1.2 1996/11/10 03:05:41 momjian Exp $
+ * $Id: gramparse.h,v 1.3 1997/09/07 04:59:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef GRAMPARSE_H
-#define GRAMPARSE_H /* include once only */
+#define GRAMPARSE_H /* include once only */
/* from scan.l */
-extern void init_io(void);
+extern void init_io(void);
/* from gram.y */
-extern void parser_init(Oid *typev, int nargs);
-extern int yyparse(void);
+extern void parser_init(Oid * typev, int nargs);
+extern int yyparse(void);
-#endif /* GRAMPARSE_H */
+#endif /* GRAMPARSE_H */
diff --git a/src/include/parser/keywords.h b/src/include/parser/keywords.h
index 66e113496a2..1453d60e1a4 100644
--- a/src/include/parser/keywords.h
+++ b/src/include/parser/keywords.h
@@ -1,25 +1,26 @@
/*-------------------------------------------------------------------------
*
* keywords.h--
- * string,atom lookup thingy, reduces strcmp traffic greatly
- * in the bowels of the system. Look for actual defs in lib/C/atoms.c
+ * string,atom lookup thingy, reduces strcmp traffic greatly
+ * in the bowels of the system. Look for actual defs in lib/C/atoms.c
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: keywords.h,v 1.1 1996/08/28 07:23:55 scrappy Exp $
+ * $Id: keywords.h,v 1.2 1997/09/07 04:59:34 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef KEYWORDS_H
-#define KEYWORDS_H
+#ifndef KEYWORDS_H
+#define KEYWORDS_H
-typedef struct ScanKeyword {
- char *name;
- int value;
-} ScanKeyword;
+typedef struct ScanKeyword
+{
+ char *name;
+ int value;
+} ScanKeyword;
extern ScanKeyword *ScanKeywordLookup(char *text);
-extern char* AtomValueGetString(int atomval);
+extern char *AtomValueGetString(int atomval);
-#endif /* KEYWORDS_H */
+#endif /* KEYWORDS_H */
diff --git a/src/include/parser/parse_query.h b/src/include/parser/parse_query.h
index dc6f16dbc47..decf425ca92 100644
--- a/src/include/parser/parse_query.h
+++ b/src/include/parser/parse_query.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* parse_query.h--
- * prototypes for parse_query.c.
+ * prototypes for parse_query.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: parse_query.h,v 1.9 1997/08/20 14:54:26 momjian Exp $
+ * $Id: parse_query.h,v 1.10 1997/09/07 04:59:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,55 +17,62 @@
#include <parser/parse_state.h>
#include <nodes/parsenodes.h>
-typedef struct QueryTreeList {
- int len; /* number of queries */
- Query** qtrees;
-} QueryTreeList;
+typedef struct QueryTreeList
+{
+ int len; /* number of queries */
+ Query **qtrees;
+} QueryTreeList;
-extern RangeTblEntry *refnameRangeTableEntry(List *rtable, char *refname);
-extern RangeTblEntry *colnameRangeTableEntry(ParseState *pstate, char *colname);
-extern int refnameRangeTablePosn(List *rtable, char *refname);
-extern RangeTblEntry *addRangeTableEntry(ParseState *pstate,
- char *relname, char *refname,
- bool inh, bool inFromCl,
- TimeRange *timeRange);
-extern List *expandAll(ParseState *pstate, char *relname, char *refname,
- int *this_resno);
-extern TimeQual makeTimeRange(char *datestring1, char *datestring2,
- int timecode);
-extern Expr *make_op(char *opname, Node *ltree, Node *rtree);
+extern RangeTblEntry *refnameRangeTableEntry(List * rtable, char *refname);
+extern RangeTblEntry *colnameRangeTableEntry(ParseState * pstate, char *colname);
+extern int refnameRangeTablePosn(List * rtable, char *refname);
+extern RangeTblEntry *
+addRangeTableEntry(ParseState * pstate,
+ char *relname, char *refname,
+ bool inh, bool inFromCl,
+ TimeRange * timeRange);
+extern List *
+expandAll(ParseState * pstate, char *relname, char *refname,
+ int *this_resno);
+extern TimeQual
+makeTimeRange(char *datestring1, char *datestring2,
+ int timecode);
+extern Expr *make_op(char *opname, Node * ltree, Node * rtree);
-extern Oid find_atttype(Oid relid, char *attrname);
-extern Var *make_var(ParseState *pstate,
- char *relname, char *attrname, Oid *type_id);
-extern ArrayRef *make_array_ref(Node *array, List *indirection);
-extern ArrayRef *make_array_set(Expr *target_expr, List *upperIndexpr,
- List *lowerIndexpr, Expr *expr);
-extern Const *make_const(Value *value);
+extern Oid find_atttype(Oid relid, char *attrname);
+extern Var *
+make_var(ParseState * pstate,
+ char *relname, char *attrname, Oid * type_id);
+extern ArrayRef *make_array_ref(Node * array, List * indirection);
+extern ArrayRef *
+make_array_set(Expr * target_expr, List * upperIndexpr,
+ List * lowerIndexpr, Expr * expr);
+extern Const *make_const(Value * value);
-extern void param_type_init(Oid* typev, int nargs);
-extern Oid param_type(int t);
+extern void param_type_init(Oid * typev, int nargs);
+extern Oid param_type(int t);
/* parser.c (was ylib.c) */
-extern QueryTreeList *parser(char *str, Oid *typev, int nargs);
-extern Node *parser_typecast(Value *expr, TypeName *typename, int typlen);
-extern Node *parser_typecast2(Node *expr, Oid exprType, Type tp, int typlen);
-extern Aggreg *ParseAgg(char *aggname, Oid basetype, Node *target);
-extern void handleTargetColname(ParseState *pstate, char **resname,
+extern QueryTreeList *parser(char *str, Oid * typev, int nargs);
+extern Node *parser_typecast(Value * expr, TypeName * typename, int typlen);
+extern Node *parser_typecast2(Node * expr, Oid exprType, Type tp, int typlen);
+extern Aggreg *ParseAgg(char *aggname, Oid basetype, Node * target);
+extern void
+handleTargetColname(ParseState * pstate, char **resname,
char *refname, char *colname);
/*
* analyze.c
*/
-Oid exprType(Node *expr);
-QueryTreeList *parse_analyze(List *querytree_list);
+Oid exprType(Node * expr);
+QueryTreeList *parse_analyze(List * querytree_list);
/* define in parse_query.c, used in gram.y */
-extern Oid *param_type_info;
-extern int pfunc_num_args;
+extern Oid *param_type_info;
+extern int pfunc_num_args;
/* useful macros */
#define ISCOMPLEX(type) (typeid_get_relid(type) ? true : false)
-#endif /* PARSE_QUERY_H */
+#endif /* PARSE_QUERY_H */
diff --git a/src/include/parser/parse_state.h b/src/include/parser/parse_state.h
index c2f900e81f3..05f860290fb 100644
--- a/src/include/parser/parse_state.h
+++ b/src/include/parser/parse_state.h
@@ -4,7 +4,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: parse_state.h,v 1.5 1996/11/04 12:12:52 scrappy Exp $
+ * $Id: parse_state.h,v 1.6 1997/09/07 04:59:37 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -12,22 +12,23 @@
#ifndef PARSE_STATE_H
#define PARSE_STATE_H
-#include <nodes/parsenodes.h>
+#include <nodes/parsenodes.h>
#include <utils/rel.h>
/* state information used during parse analysis */
-typedef struct ParseState {
- int p_last_resno;
- List *p_rtable;
- int p_numAgg;
- List *p_aggs;
- bool p_is_insert;
- List *p_insert_columns;
- bool p_is_update;
- bool p_is_rule;
- Relation p_target_relation;
- RangeTblEntry *p_target_rangetblentry;
-} ParseState;
+typedef struct ParseState
+{
+ int p_last_resno;
+ List *p_rtable;
+ int p_numAgg;
+ List *p_aggs;
+ bool p_is_insert;
+ List *p_insert_columns;
+ bool p_is_update;
+ bool p_is_rule;
+ Relation p_target_relation;
+ RangeTblEntry *p_target_rangetblentry;
+} ParseState;
-#endif /*PARSE_QUERY_H*/
+#endif /* PARSE_QUERY_H */
diff --git a/src/include/parser/parsetree.h b/src/include/parser/parsetree.h
index b51cc0f3057..a5662cd9d79 100644
--- a/src/include/parser/parsetree.h
+++ b/src/include/parser/parsetree.h
@@ -1,78 +1,77 @@
/*-------------------------------------------------------------------------
*
* parsetree.h--
- * Routines to access various components and subcomponents of
- * parse trees.
+ * Routines to access various components and subcomponents of
+ * parse trees.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: parsetree.h,v 1.2 1996/11/06 10:30:39 scrappy Exp $
+ * $Id: parsetree.h,v 1.3 1997/09/07 04:59:38 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PARSETREE_H
-#define PARSETREE_H /* include once only */
+#define PARSETREE_H /* include once only */
/* ----------------
- * need pg_list.h for definitions of CAR(), etc. macros
+ * need pg_list.h for definitions of CAR(), etc. macros
* ----------------
*/
/* ----------------
- * range table macros
+ * range table macros
*
- * parse tree:
- * (root targetlist qual)
- * ^^^^
- * parse root:
- * (numlevels cmdtype resrel rangetable priority ruleinfo nestdotinfo)
- * ^^^^^^^^^^
- * range table:
- * (rtentry ...)
+ * parse tree:
+ * (root targetlist qual)
+ * ^^^^
+ * parse root:
+ * (numlevels cmdtype resrel rangetable priority ruleinfo nestdotinfo)
+ * ^^^^^^^^^^
+ * range table:
+ * (rtentry ...)
*
- * rtentry:
- * note: this might be wrong, I don't understand how
- * rt_time / rt_archive_time work together. anyways it
- * looks something like:
+ * rtentry:
+ * note: this might be wrong, I don't understand how
+ * rt_time / rt_archive_time work together. anyways it
+ * looks something like:
*
- * (relname ? relid timestuff flags rulelocks)
- * or (new/cur relname relid timestuff flags rulelocks)
+ * (relname ? relid timestuff flags rulelocks)
+ * or (new/cur relname relid timestuff flags rulelocks)
*
- * someone who knows more should correct this -cim 6/9/91
+ * someone who knows more should correct this -cim 6/9/91
* ----------------
*/
#define rt_relname(rt_entry) \
- ((!strcmp(((rt_entry)->refname),"*CURRENT*") ||\
- !strcmp(((rt_entry)->refname),"*NEW*")) ? ((rt_entry)->refname) : \
- ((char *)(rt_entry)->relname))
+ ((!strcmp(((rt_entry)->refname),"*CURRENT*") ||\
+ !strcmp(((rt_entry)->refname),"*NEW*")) ? ((rt_entry)->refname) : \
+ ((char *)(rt_entry)->relname))
/*
- * rt_fetch
- * rt_store
+ * rt_fetch
+ * rt_store
*
- * Access and (destructively) replace rangetable entries.
+ * Access and (destructively) replace rangetable entries.
*
*/
#define rt_fetch(rangetable_index, rangetable) \
- ((RangeTblEntry*)nth((rangetable_index)-1, rangetable))
+ ((RangeTblEntry*)nth((rangetable_index)-1, rangetable))
#define rt_store(rangetable_index, rangetable, rt) \
- set_nth(rangetable, (rangetable_index)-1, rt)
+ set_nth(rangetable, (rangetable_index)-1, rt)
/*
- * getrelid
- * getrelname
+ * getrelid
+ * getrelname
*
- * Given the range index of a relation, return the corresponding
- * relation id or relation name.
+ * Given the range index of a relation, return the corresponding
+ * relation id or relation name.
*/
#define getrelid(rangeindex,rangetable) \
- ((RangeTblEntry*)nth((rangeindex)-1, rangetable))->relid
+ ((RangeTblEntry*)nth((rangeindex)-1, rangetable))->relid
#define getrelname(rangeindex, rangetable) \
- rt_relname((RangeTblEntry*)nth((rangeindex)-1, rangetable))
+ rt_relname((RangeTblEntry*)nth((rangeindex)-1, rangetable))
-#endif /* PARSETREE_H */
-
+#endif /* PARSETREE_H */
diff --git a/src/include/parser/scansup.h b/src/include/parser/scansup.h
index 4c955bc43e1..e3dd13a6064 100644
--- a/src/include/parser/scansup.h
+++ b/src/include/parser/scansup.h
@@ -1,17 +1,14 @@
/*-------------------------------------------------------------------------
*
* scansup.h--
- * scanner support routines. used by both the bootstrap lexer
+ * scanner support routines. used by both the bootstrap lexer
* as well as the normal lexer
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: scansup.h,v 1.1 1996/08/28 07:23:58 scrappy Exp $
+ * $Id: scansup.h,v 1.2 1997/09/07 04:59:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-extern char* scanstr(char *s);
-
-
-
+extern char *scanstr(char *s);
diff --git a/src/include/parser/sysfunc.h b/src/include/parser/sysfunc.h
index b0761d4c351..2a1f87d8590 100644
--- a/src/include/parser/sysfunc.h
+++ b/src/include/parser/sysfunc.h
@@ -1,10 +1,9 @@
/*-------------------------------------------------------------------------
- *
+ *
* sysfunc.h--
- * support for system functions
- *
+ * support for system functions
+ *
* -------------------------------------------------------------------------
*/
-extern char *SystemFunctionHandler(char *funct);
-
+extern char *SystemFunctionHandler(char *funct);
diff --git a/src/include/port/BSD44_derived.h b/src/include/port/BSD44_derived.h
index e89c0094170..867246f3b86 100644
--- a/src/include/port/BSD44_derived.h
+++ b/src/include/port/BSD44_derived.h
@@ -1,15 +1,15 @@
-# define USE_POSIX_TIME
-# if defined(i386)
-# define NEED_I386_TAS_ASM
-# endif
-# if defined(sparc)
-# define NEED_SPARC_TAS_ASM
-# endif
-# if defined(ns32k)
-# define NEED_NS32k_TAS_ASM
-# endif
-# define HAS_TEST_AND_SET
-# if defined(__mips__)
-/* # undef HAS_TEST_AND_SET */
-# endif
- typedef unsigned char slock_t;
+#define USE_POSIX_TIME
+#if defined(i386)
+#define NEED_I386_TAS_ASM
+#endif
+#if defined(sparc)
+#define NEED_SPARC_TAS_ASM
+#endif
+#if defined(ns32k)
+#define NEED_NS32k_TAS_ASM
+#endif
+#define HAS_TEST_AND_SET
+#if defined(__mips__)
+/* # undef HAS_TEST_AND_SET */
+#endif
+typedef unsigned char slock_t;
diff --git a/src/include/port/aix.h b/src/include/port/aix.h
index 25d33eb87b8..a329e967f43 100644
--- a/src/include/port/aix.h
+++ b/src/include/port/aix.h
@@ -1,8 +1,10 @@
-# define USE_POSIX_TIME
-# define USE_POSIX_SIGNALS
-# define CLASS_CONFLICT
-# define DISABLE_XOPEN_NLS
-# define HAVE_ANSI_CPP
-# define HAS_TEST_AND_SET
- typedef unsigned int slock_t;
-#include <sys/machine.h> /* ENDIAN definitions for network communication */
+#define USE_POSIX_TIME
+#define USE_POSIX_SIGNALS
+#define CLASS_CONFLICT
+#define DISABLE_XOPEN_NLS
+#define HAVE_ANSI_CPP
+#define HAS_TEST_AND_SET
+typedef unsigned int slock_t;
+
+#include <sys/machine.h> /* ENDIAN definitions for network
+ * communication */
diff --git a/src/include/port/alpha.h b/src/include/port/alpha.h
index 5ac7ba167a0..40dfbfa9496 100644
--- a/src/include/port/alpha.h
+++ b/src/include/port/alpha.h
@@ -1,7 +1,7 @@
-# define USE_POSIX_TIME
-# define USE_POSIX_SIGNALS
-# define DISABLE_XOPEN_NLS
-# define HAS_LONG_LONG
-# define HAS_TEST_AND_SET
-# include <sys/mman.h> /* for msemaphore */
- typedef msemaphore slock_t;
+#define USE_POSIX_TIME
+#define USE_POSIX_SIGNALS
+#define DISABLE_XOPEN_NLS
+#define HAS_LONG_LONG
+#define HAS_TEST_AND_SET
+#include <sys/mman.h> /* for msemaphore */
+typedef msemaphore slock_t;
diff --git a/src/include/port/bsdi.h b/src/include/port/bsdi.h
index 022c41dbd6a..617ef6768ae 100644
--- a/src/include/port/bsdi.h
+++ b/src/include/port/bsdi.h
@@ -1,9 +1,9 @@
-# if defined(i386)
-# define NEED_I386_TAS_ASM
-# endif
-# if defined(sparc)
-# define NEED_SPARC_TAS_ASM
-# endif
-# define USE_POSIX_TIME
-# define HAS_TEST_AND_SET
- typedef unsigned char slock_t;
+#if defined(i386)
+#define NEED_I386_TAS_ASM
+#endif
+#if defined(sparc)
+#define NEED_SPARC_TAS_ASM
+#endif
+#define USE_POSIX_TIME
+#define HAS_TEST_AND_SET
+typedef unsigned char slock_t;
diff --git a/src/include/port/dgux.h b/src/include/port/dgux.h
index 4d95ea3160f..447d16f77df 100644
--- a/src/include/port/dgux.h
+++ b/src/include/port/dgux.h
@@ -2,16 +2,15 @@
#define USE_POSIX_SIGNALS
#define USE_POSIX_TIME
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
#endif
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
#endif
-#ifndef PDP_ENDIAN
-#define PDP_ENDIAN 3412
+#ifndef PDP_ENDIAN
+#define PDP_ENDIAN 3412
#endif
-#ifndef BYTE_ORDER
-#define BYTE_ORDER BIG_ENDIAN
+#ifndef BYTE_ORDER
+#define BYTE_ORDER BIG_ENDIAN
#endif
-
diff --git a/src/include/port/hpux.h b/src/include/port/hpux.h
index 0315f79d629..ec0859e521c 100644
--- a/src/include/port/hpux.h
+++ b/src/include/port/hpux.h
@@ -1,18 +1,20 @@
-# define JMP_BUF
-# define USE_POSIX_TIME
-# define HAS_TEST_AND_SET
- typedef struct { int sem[4]; } slock_t;
+#define JMP_BUF
+#define USE_POSIX_TIME
+#define HAS_TEST_AND_SET
+typedef struct
+{
+ int sem[4];
+} slock_t;
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
#endif
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
#endif
-#ifndef PDP_ENDIAN
-#define PDP_ENDIAN 3412
+#ifndef PDP_ENDIAN
+#define PDP_ENDIAN 3412
#endif
-#ifndef BYTE_ORDER
-#define BYTE_ORDER BIG_ENDIAN
+#ifndef BYTE_ORDER
+#define BYTE_ORDER BIG_ENDIAN
#endif
-
diff --git a/src/include/port/i386_solaris.h b/src/include/port/i386_solaris.h
index 92d276985d0..b2df1ba5e2c 100644
--- a/src/include/port/i386_solaris.h
+++ b/src/include/port/i386_solaris.h
@@ -1,42 +1,42 @@
-# define USE_POSIX_TIME
-# define USE_POSIX_SIGNALS
-# define NO_EMPTY_STMTS
-# define SYSV_DIRENT
-# define HAS_TEST_AND_SET
- typedef unsigned char slock_t;
+#define USE_POSIX_TIME
+#define USE_POSIX_SIGNALS
+#define NO_EMPTY_STMTS
+#define SYSV_DIRENT
+#define HAS_TEST_AND_SET
+typedef unsigned char slock_t;
#include <sys/isa_defs.h>
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
#endif
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
#endif
-#ifndef PDP_ENDIAN
-#define PDP_ENDIAN 3412
+#ifndef PDP_ENDIAN
+#define PDP_ENDIAN 3412
#endif
-#ifndef BYTE_ORDER
-#define BYTE_ORDER LITTLE_ENDIAN
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
#endif
-#ifndef NAN
+#ifndef NAN
-#ifndef __nan_bytes
-#define __nan_bytes { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }
-#endif /* __nan_bytes */
+#ifndef __nan_bytes
+#define __nan_bytes { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }
+#endif /* __nan_bytes */
-#ifdef __GNUC__
+#ifdef __GNUC__
#define NAN \
- (__extension__ ((union { unsigned char __c[8]; \
- double __d; }) \
- { __nan_bytes }).__d)
+ (__extension__ ((union { unsigned char __c[8]; \
+ double __d; }) \
+ { __nan_bytes }).__d)
-#else /* Not GCC. */
-#define NAN (*(__const double *) __nan)
-#endif /* GCC. */
-#endif /* NAN */
+#else /* Not GCC. */
+#define NAN (*(__const double *) __nan)
+#endif /* GCC. */
+#endif /* NAN */
-#ifndef index
+#ifndef index
#define index strchr
#endif
diff --git a/src/include/port/irix5.h b/src/include/port/irix5.h
index c995eb671fb..83c7837584f 100644
--- a/src/include/port/irix5.h
+++ b/src/include/port/irix5.h
@@ -1,7 +1,7 @@
-# define USE_POSIX_TIME
-# define USE_POSIX_SIGNALS
-# define NO_EMPTY_STMTS
-# define SYSV_DIRENT
-# define HAS_TEST_AND_SET
-# include <abi_mutex.h>
- typedef abilock_t slock_t;
+#define USE_POSIX_TIME
+#define USE_POSIX_SIGNALS
+#define NO_EMPTY_STMTS
+#define SYSV_DIRENT
+#define HAS_TEST_AND_SET
+#include <abi_mutex.h>
+typedef abilock_t slock_t;
diff --git a/src/include/port/linux.h b/src/include/port/linux.h
index 99d8eb65aef..b04e45bebab 100644
--- a/src/include/port/linux.h
+++ b/src/include/port/linux.h
@@ -4,31 +4,34 @@
__USE_BSD is set by bsd/signal.h, and __USE_BSD_SIGNAL appears not to
be used.
*/
-# define JMP_BUF
-# define USE_POSIX_TIME
-# define USE_POSIX_SIGNALS
-# define NEED_I386_TAS_ASM
-# define HAS_TEST_AND_SET
-
-# if defined(PPC)
- typedef unsigned int slock_t;
-# endif
-
-# if defined(PPC)
-# undef NEED_I386_TAS_ASM
-# undef HAVE_INT_TIMEZONE
-# endif
-
-# if defined(sparc)
-# undef NEED_I386_TAS_ASM
-# endif
-
-
-# if defined(__alpha__)
-# undef NEED_I386_TAS_ASM
-# endif
-# if defined(__alpha__)
- typedef long int slock_t;
-# else
- typedef unsigned char slock_t;
-# endif
+#define JMP_BUF
+#define USE_POSIX_TIME
+#define USE_POSIX_SIGNALS
+#define NEED_I386_TAS_ASM
+#define HAS_TEST_AND_SET
+
+#if defined(PPC)
+typedef unsigned int slock_t;
+
+#endif
+
+#if defined(PPC)
+#undef NEED_I386_TAS_ASM
+#undef HAVE_INT_TIMEZONE
+#endif
+
+#if defined(sparc)
+#undef NEED_I386_TAS_ASM
+#endif
+
+
+#if defined(__alpha__)
+#undef NEED_I386_TAS_ASM
+#endif
+#if defined(__alpha__)
+typedef long int slock_t;
+
+#else
+typedef unsigned char slock_t;
+
+#endif
diff --git a/src/include/port/nextstep.h b/src/include/port/nextstep.h
index ca078ab10d4..f893b48b03c 100644
--- a/src/include/port/nextstep.h
+++ b/src/include/port/nextstep.h
@@ -1,18 +1,20 @@
-# include <libc.h>
-# include <sys/ioctl.h>
-# if defined(__STRICT_ANSI__)
-# define isascii(c) ((unsigned)(c)<=0177)
-# endif
- extern char* strdup (const char* string);
-# ifndef _POSIX_SOURCE
- typedef unsigned short mode_t;
- typedef int sigset_t;
-# define SIG_BLOCK 00
-# define SIG_UNBLOCK 01
-# define SIG_SETMASK 02
-# define NEED_SIG_JMP
-# endif
+#include <libc.h>
+#include <sys/ioctl.h>
+#if defined(__STRICT_ANSI__)
+#define isascii(c) ((unsigned)(c)<=0177)
+#endif
+extern char *strdup(const char *string);
-# define JMP_BUF
-# define NO_WAITPID
- typedef struct mutex slock_t;
+#ifndef _POSIX_SOURCE
+typedef unsigned short mode_t;
+typedef int sigset_t;
+
+#define SIG_BLOCK 00
+#define SIG_UNBLOCK 01
+#define SIG_SETMASK 02
+#define NEED_SIG_JMP
+#endif
+
+#define JMP_BUF
+#define NO_WAITPID
+typedef struct mutex slock_t;
diff --git a/src/include/port/sco.h b/src/include/port/sco.h
index 0792d7d4e27..5bc74f7279c 100644
--- a/src/include/port/sco.h
+++ b/src/include/port/sco.h
@@ -1,6 +1,6 @@
-#include <limits.h> /* For _POSIX_PATH_MAX */
+#include <limits.h> /* For _POSIX_PATH_MAX */
-#define MAXPATHLEN _POSIX_PATH_MAX
-#define SIGURG SIGUSR1
+#define MAXPATHLEN _POSIX_PATH_MAX
+#define SIGURG SIGUSR1
-#define NOFILE NOFILES_MIN
+#define NOFILE NOFILES_MIN
diff --git a/src/include/port/sparc_solaris.h b/src/include/port/sparc_solaris.h
index 9e7a6b7775c..8383215b708 100644
--- a/src/include/port/sparc_solaris.h
+++ b/src/include/port/sparc_solaris.h
@@ -1,19 +1,19 @@
-# define USE_POSIX_TIME
-# define USE_POSIX_SIGNALS
-# define NO_EMPTY_STMTS
-# define SYSV_DIRENT
-# define HAS_TEST_AND_SET
- typedef unsigned char slock_t;
+#define USE_POSIX_TIME
+#define USE_POSIX_SIGNALS
+#define NO_EMPTY_STMTS
+#define SYSV_DIRENT
+#define HAS_TEST_AND_SET
+typedef unsigned char slock_t;
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
#endif
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
#endif
-#ifndef PDP_ENDIAN
-#define PDP_ENDIAN 3412
+#ifndef PDP_ENDIAN
+#define PDP_ENDIAN 3412
#endif
-#ifndef BYTE_ORDER
-#define BYTE_ORDER BIG_ENDIAN
+#ifndef BYTE_ORDER
+#define BYTE_ORDER BIG_ENDIAN
#endif
diff --git a/src/include/port/sunos4.h b/src/include/port/sunos4.h
index d395cbdbe12..f08580cfafc 100644
--- a/src/include/port/sunos4.h
+++ b/src/include/port/sunos4.h
@@ -1,14 +1,14 @@
#define USE_POSIX_TIME
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
#endif
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
#endif
-#ifndef PDP_ENDIAN
-#define PDP_ENDIAN 3412
+#ifndef PDP_ENDIAN
+#define PDP_ENDIAN 3412
#endif
-#ifndef BYTE_ORDER
-#define BYTE_ORDER BIG_ENDIAN
+#ifndef BYTE_ORDER
+#define BYTE_ORDER BIG_ENDIAN
#endif
diff --git a/src/include/port/svr4.h b/src/include/port/svr4.h
index 0910fe2d298..56e7dbd9e2d 100644
--- a/src/include/port/svr4.h
+++ b/src/include/port/svr4.h
@@ -1,10 +1,10 @@
-# define USE_POSIX_TIME
-# define USE_POSIX_SIGNALS
-# define NO_EMPTY_STMTS
-# define SYSV_DIRENT
+#define USE_POSIX_TIME
+#define USE_POSIX_SIGNALS
+#define NO_EMPTY_STMTS
+#define SYSV_DIRENT
-#ifndef BYTE_ORDER
-#ifdef MIPSEB
-#define BYTE_ORDER BIG_ENDIAN
+#ifndef BYTE_ORDER
+#ifdef MIPSEB
+#define BYTE_ORDER BIG_ENDIAN
+#endif
#endif
-#endif
diff --git a/src/include/port/ultrix4.h b/src/include/port/ultrix4.h
index 38cce4d257f..87678df9ba2 100644
--- a/src/include/port/ultrix4.h
+++ b/src/include/port/ultrix4.h
@@ -1,17 +1,17 @@
-# define USE_POSIX_TIME
-# define NEED_STRDUP
+#define USE_POSIX_TIME
+#define NEED_STRDUP
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
#endif
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
#endif
-#ifndef PDP_ENDIAN
-#define PDP_ENDIAN 3412
+#ifndef PDP_ENDIAN
+#define PDP_ENDIAN 3412
#endif
-#ifndef BYTE_ORDER
-#define BYTE_ORDER LITTLE_ENDIAN
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
#endif
/*
@@ -23,50 +23,51 @@
* warning-free compilation.
*/
-#include <sys/types.h> /* Declare various types, e.g. size_t, fd_set */
+#include <sys/types.h> /* Declare various types, e.g. size_t,
+ * fd_set */
-extern int strcasecmp(const char *, const char *);
-extern void bzero(void *, size_t);
+extern int strcasecmp(const char *, const char *);
+extern void bzero(void *, size_t);
-extern int fp_class_d(double);
-extern long random(void);
+extern int fp_class_d(double);
+extern long random(void);
struct rusage;
-extern int getrusage(int, struct rusage *);
+extern int getrusage(int, struct rusage *);
-extern int ioctl(int, unsigned long, ...);
+extern int ioctl(int, unsigned long,...);
-extern int socket(int, int, int);
+extern int socket(int, int, int);
struct sockaddr;
-extern int connect(int, const struct sockaddr *, int);
-typedef int ssize_t;
-extern ssize_t send(int, const void *, size_t, int);
-extern ssize_t recv(int, void*, size_t, int);
-extern int setsockopt(int, int, int, const void *, int);
-extern int bind(int, const struct sockaddr *, int);
-extern int listen(int, int);
-extern int accept(int, struct sockaddr *, int *);
-extern int getsockname(int, struct sockaddr *, int *);
-extern ssize_t recvfrom(int, void *, size_t, int, struct sockaddr *, int *);
-extern ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, int);
+extern int connect(int, const struct sockaddr *, int);
+typedef int ssize_t;
+extern ssize_t send(int, const void *, size_t, int);
+extern ssize_t recv(int, void *, size_t, int);
+extern int setsockopt(int, int, int, const void *, int);
+extern int bind(int, const struct sockaddr *, int);
+extern int listen(int, int);
+extern int accept(int, struct sockaddr *, int *);
+extern int getsockname(int, struct sockaddr *, int *);
+extern ssize_t recvfrom(int, void *, size_t, int, struct sockaddr *, int *);
+extern ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, int);
struct timeval;
-extern int select(int, fd_set*, fd_set*, fd_set*, struct timeval *);
+extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
-extern int gethostname(char *, int);
+extern int gethostname(char *, int);
-extern int getopt(int, char * const *, const char *);
-extern int putenv(const char *);
+extern int getopt(int, char *const *, const char *);
+extern int putenv(const char *);
-extern pid_t vfork(void);
+extern pid_t vfork(void);
struct itimerval;
-extern int setitimer(int, const struct itimerval*, struct itimerval *);
+extern int setitimer(int, const struct itimerval *, struct itimerval *);
struct timezone;
-extern int gettimeofday(struct timeval *, struct timezone *);
+extern int gettimeofday(struct timeval *, struct timezone *);
-extern int fsync(int);
-extern int ftruncate(int, off_t);
+extern int fsync(int);
+extern int ftruncate(int, off_t);
-extern char *crypt(char *, char *);
+extern char *crypt(char *, char *);
/* End of ultrix4.h */
diff --git a/src/include/port/univel.h b/src/include/port/univel.h
index 9ce1fef1ccd..c0bc9821867 100644
--- a/src/include/port/univel.h
+++ b/src/include/port/univel.h
@@ -1,28 +1,28 @@
-# define USE_POSIX_TIME
-# define NO_EMPTY_STMTS
-# define USE_POSIX_SIGNALS
-# define SYSV_DIRENT
+#define USE_POSIX_TIME
+#define NO_EMPTY_STMTS
+#define USE_POSIX_SIGNALS
+#define SYSV_DIRENT
#if 0
-# define HAS_TEST_AND_SET
- typedef unsigned char slock_t;
+#define HAS_TEST_AND_SET
+typedef unsigned char slock_t;
+
#endif
-extern long random(void);
-extern void srandom(int seed);
-extern int strcasecmp(char *s1,char *s2);
-extern int gethostname(char *name,int namelen);
+extern long random(void);
+extern void srandom(int seed);
+extern int strcasecmp(char *s1, char *s2);
+extern int gethostname(char *name, int namelen);
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
#endif
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
#endif
-#ifndef PDP_ENDIAN
-#define PDP_ENDIAN 3412
+#ifndef PDP_ENDIAN
+#define PDP_ENDIAN 3412
#endif
-#ifndef BYTE_ORDER
-#define BYTE_ORDER LITTLE_ENDIAN
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
#endif
-
diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index 7f4c97c582e..d343f606924 100644
--- a/src/include/port/win32.h
+++ b/src/include/port/win32.h
@@ -1,8 +1,8 @@
-# define JMP_BUF
-# define NEED_SIG_JMP
-# define NO_UNISTD_H
-# define USES_WINSOCK
-# define NOFILE 100
-# ifndef MAXPATHLEN
-# define MAXPATHLEN 250
-# endif
+#define JMP_BUF
+#define NEED_SIG_JMP
+#define NO_UNISTD_H
+#define USES_WINSOCK
+#define NOFILE 100
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 250
+#endif
diff --git a/src/include/postgres.h b/src/include/postgres.h
index 541da6413b1..2e37eb95fd7 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -1,35 +1,35 @@
/*-------------------------------------------------------------------------
*
* postgres.h--
- * definition of (and support for) postgres system types.
+ * definition of (and support for) postgres system types.
* this file is included by almost every .c in the system
*
* Copyright (c) 1995, Regents of the University of California
*
- * $Id: postgres.h,v 1.6 1997/07/11 14:09:00 thomas Exp $
+ * $Id: postgres.h,v 1.7 1997/09/07 04:55:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * NOTES
- * this file will eventually contain the definitions for the
- * following (and perhaps other) system types:
+ * NOTES
+ * this file will eventually contain the definitions for the
+ * following (and perhaps other) system types:
*
- * int2 int4 float4 float8
- * Oid regproc RegProcedure
- * aclitem
- * struct varlena
- * char8 char16 int28 oid8
- * bytea text
- * NameData Name
- * oidint4 oidint2 oidname
+ * int2 int4 float4 float8
+ * Oid regproc RegProcedure
+ * aclitem
+ * struct varlena
+ * char8 char16 int28 oid8
+ * bytea text
+ * NameData Name
+ * oidint4 oidint2 oidname
*
- * TABLE OF CONTENTS
- * 1) simple type definitions
- * 2) varlena and array types
- * 3) TransactionId and CommandId
- * 4) genbki macros used by catalog/pg_xxx.h files
- * 5) random CSIGNBIT, MAXPGPATH, STATUS macros
+ * TABLE OF CONTENTS
+ * 1) simple type definitions
+ * 2) varlena and array types
+ * 3) TransactionId and CommandId
+ * 4) genbki macros used by catalog/pg_xxx.h files
+ * 5) random CSIGNBIT, MAXPGPATH, STATUS macros
*
* ----------------------------------------------------------------
*/
@@ -43,128 +43,137 @@
#include "utils/palloc.h"
/* ----------------------------------------------------------------
- * Section 1: simple type definitions
+ * Section 1: simple type definitions
* ----------------------------------------------------------------
*/
-typedef int16 int2;
+typedef int16 int2;
typedef int32 int4;
typedef float float4;
typedef double float8;
typedef int4 aclitem;
-#define InvalidOid 0
+#define InvalidOid 0
#define OidIsValid(objectId) ((bool) (objectId != InvalidOid))
/* unfortunately, both regproc and RegProcedure are used */
-typedef Oid regproc;
-typedef Oid RegProcedure;
+typedef Oid regproc;
+typedef Oid RegProcedure;
/* ptr to func returning (char *) */
-typedef char * ((*func_ptr)());
+typedef char *((*func_ptr) ());
-#define RegProcedureIsValid(p) OidIsValid(p)
+#define RegProcedureIsValid(p) OidIsValid(p)
/* ----------------------------------------------------------------
- * Section 2: variable length and array types
+ * Section 2: variable length and array types
* ----------------------------------------------------------------
*/
/* ----------------
- * struct varlena
+ * struct varlena
* ----------------
*/
-struct varlena {
- int32 vl_len;
- char vl_dat[1];
+struct varlena
+{
+ int32 vl_len;
+ char vl_dat[1];
};
-#define VARSIZE(PTR) (((struct varlena *)(PTR))->vl_len)
-#define VARDATA(PTR) (((struct varlena *)(PTR))->vl_dat)
-#define VARHDRSZ sizeof(int32)
+#define VARSIZE(PTR) (((struct varlena *)(PTR))->vl_len)
+#define VARDATA(PTR) (((struct varlena *)(PTR))->vl_dat)
+#define VARHDRSZ sizeof(int32)
typedef struct varlena bytea;
typedef struct varlena text;
-typedef struct char8 {
- char data[8];
-} char8;
+typedef struct char8
+{
+ char data[8];
+} char8;
/* ----------------
- * char16
+ * char16
* ----------------
*/
-typedef struct char16 {
- char data[16];
-} char16;
+typedef struct char16
+{
+ char data[16];
+} char16;
-typedef char16 *Char16;
+typedef char16 *Char16;
-typedef int2 int28[8];
-typedef Oid oid8[8];
+typedef int2 int28[8];
+typedef Oid oid8[8];
-typedef struct nameData {
- char data[NAMEDATALEN];
-} NameData;
-typedef NameData *Name;
+typedef struct nameData
+{
+ char data[NAMEDATALEN];
+} NameData;
+typedef NameData *Name;
/* ----------------
- * oidint4
+ * oidint4
*
- * this is a new system type used by the file interface.
+ * this is a new system type used by the file interface.
* ----------------
*/
-typedef struct OidInt4Data {
- Oid oi_oid;
- int32 oi_int4;
-} OidInt4Data;
+typedef struct OidInt4Data
+{
+ Oid oi_oid;
+ int32 oi_int4;
+} OidInt4Data;
-typedef struct OidInt4Data *OidInt4;
+typedef struct OidInt4Data *OidInt4;
/* ----------------
- * oidint2
+ * oidint2
*
- * this is a new system type used to define indices on two attrs.
+ * this is a new system type used to define indices on two attrs.
* ----------------
*/
-typedef struct OidInt2Data {
- Oid oi_oid;
- int16 oi_int2;
-} OidInt2Data;
+typedef struct OidInt2Data
+{
+ Oid oi_oid;
+ int16 oi_int2;
+} OidInt2Data;
-typedef struct OidInt2Data *OidInt2;
+typedef struct OidInt2Data *OidInt2;
/* ----------------
- * oidname
+ * oidname
*
- * this is a new system type used to define indices on two attrs.
+ * this is a new system type used to define indices on two attrs.
* ----------------
*/
-typedef struct OidNameData {
- Oid id;
- NameData name;
-} OidNameData;
+typedef struct OidNameData
+{
+ Oid id;
+ NameData name;
+} OidNameData;
-typedef struct OidNameData *OidName;
+typedef struct OidNameData *OidName;
/* ----------------------------------------------------------------
- * Section 3: TransactionId and CommandId
+ * Section 3: TransactionId and CommandId
* ----------------------------------------------------------------
*/
-typedef uint32 TransactionId;
+typedef uint32 TransactionId;
+
#define InvalidTransactionId 0
-typedef uint16 CommandId;
+typedef uint16 CommandId;
+
#define FirstCommandId 0
/* ----------------------------------------------------------------
- * Section 4: genbki macros used by the
- * catalog/pg_xxx.h files
+ * Section 4: genbki macros used by the
+ * catalog/pg_xxx.h files
* ----------------------------------------------------------------
*/
#define CATALOG(x) \
- typedef struct CppConcat(FormData_,x)
+ typedef struct CppConcat(FormData_,x)
#define DATA(x) extern int errno
#define DECLARE_INDEX(x) extern int errno
@@ -176,32 +185,32 @@ typedef uint16 CommandId;
#define BKI_END
/* ----------------------------------------------------------------
- * Section 5: random stuff
- * CSIGNBIT, MAXPGPATH, STATUS...
+ * Section 5: random stuff
+ * CSIGNBIT, MAXPGPATH, STATUS...
* ----------------------------------------------------------------
*/
/* msb for int/unsigned */
-#define ISIGNBIT (0x80000000)
-#define WSIGNBIT (0x8000)
+#define ISIGNBIT (0x80000000)
+#define WSIGNBIT (0x8000)
/* msb for char */
-#define CSIGNBIT (0x80)
+#define CSIGNBIT (0x80)
/* ----------------
- * global variables which should probably go someplace else.
+ * global variables which should probably go someplace else.
* ----------------
*/
-#define MAXPGPATH 128
-
-#define STATUS_OK (0)
-#define STATUS_ERROR (-1)
-#define STATUS_NOT_FOUND (-2)
-#define STATUS_INVALID (-3)
-#define STATUS_UNCATALOGUED (-4)
-#define STATUS_REPLACED (-5)
-#define STATUS_NOT_DONE (-6)
-#define STATUS_BAD_PACKET (-7)
-#define STATUS_FOUND (1)
-
-#endif /* POSTGRES_H */
+#define MAXPGPATH 128
+
+#define STATUS_OK (0)
+#define STATUS_ERROR (-1)
+#define STATUS_NOT_FOUND (-2)
+#define STATUS_INVALID (-3)
+#define STATUS_UNCATALOGUED (-4)
+#define STATUS_REPLACED (-5)
+#define STATUS_NOT_DONE (-6)
+#define STATUS_BAD_PACKET (-7)
+#define STATUS_FOUND (1)
+
+#endif /* POSTGRES_H */
diff --git a/src/include/postgres_ext.h b/src/include/postgres_ext.h
index b79b11fe1f3..3a4554aee0f 100644
--- a/src/include/postgres_ext.h
+++ b/src/include/postgres_ext.h
@@ -1,22 +1,22 @@
/*-------------------------------------------------------------------------
*
* postgres_ext.h--
- *
- * This file contains declarations of things that are visible
- * external to Postgres. For example, the Oid type is part of a
- * structure that is passed to the front end via libpq, and is
- * accordingly referenced in libpq-fe.h.
*
- * Declarations which are specific to a particular interface should
- * go in the header file for that interface (such as libpq-fe.h). This
- * file is only for fundamental Postgres declarations.
+ * This file contains declarations of things that are visible
+ * external to Postgres. For example, the Oid type is part of a
+ * structure that is passed to the front end via libpq, and is
+ * accordingly referenced in libpq-fe.h.
*
- * User-written C functions don't count as "external to Postgres."
- * Those function much as local modifications to the backend itself, and
- * use header files that are otherwise internal to Postgres to interface
- * with the backend.
+ * Declarations which are specific to a particular interface should
+ * go in the header file for that interface (such as libpq-fe.h). This
+ * file is only for fundamental Postgres declarations.
*
- * $Id: postgres_ext.h,v 1.1 1996/12/10 07:03:43 bryanh Exp $
+ * User-written C functions don't count as "external to Postgres."
+ * Those function much as local modifications to the backend itself, and
+ * use header files that are otherwise internal to Postgres to interface
+ * with the backend.
+ *
+ * $Id: postgres_ext.h,v 1.2 1997/09/07 04:55:41 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,10 +30,10 @@ typedef unsigned int Oid;
* attribute names, function names, etc.)
*
* NOTE that databases with different NAMEDATALEN's cannot interoperate!
- */
+ */
#define NAMEDATALEN 32
/* OIDNAMELEN should be set to NAMEDATALEN + sizeof(Oid) */
-#define OIDNAMELEN 36
+#define OIDNAMELEN 36
#endif
diff --git a/src/include/regex/cclass.h b/src/include/regex/cclass.h
index cabe7faf223..271d1e418e6 100644
--- a/src/include/regex/cclass.h
+++ b/src/include/regex/cclass.h
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,37 +34,66 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)cclass.h 8.3 (Berkeley) 3/20/94
+ * @(#)cclass.h 8.3 (Berkeley) 3/20/94
*/
/* character-class table */
-static struct cclass {
- char *name;
- char *chars;
- char *multis;
-} cclasses[] = {
- {"alnum", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
-0123456789", ""},
- {"alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
- ""},
- {"blank", " \t", ""},
- {"cntrl", "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\
-\25\26\27\30\31\32\33\34\35\36\37\177", ""},
- {"digit", "0123456789", ""},
- {"graph", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+static struct cclass
+{
+ char *name;
+ char *chars;
+ char *multis;
+} cclasses[] =
+
+{
+ {
+ "alnum", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789", ""
+ },
+ {
+ "alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
+ ""
+ },
+ {
+ "blank", " \t", ""
+ },
+ {
+ "cntrl", "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\
+\25\26\27\30\31\32\33\34\35\36\37\177", ""
+ },
+ {
+ "digit", "0123456789", ""
+ },
+ {
+ "graph", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
- ""},
- {"lower", "abcdefghijklmnopqrstuvwxyz",
- ""},
- {"print", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+ ""
+ },
+ {
+ "lower", "abcdefghijklmnopqrstuvwxyz",
+ ""
+ },
+ {
+ "print", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",
- ""},
- {"punct", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
- ""},
- {"space", "\t\n\v\f\r ", ""},
- {"upper", "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
- ""},
- {"xdigit", "0123456789ABCDEFabcdef",
- ""},
- {NULL, 0, ""}
+ ""
+ },
+ {
+ "punct", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
+ ""
+ },
+ {
+ "space", "\t\n\v\f\r ", ""
+ },
+ {
+ "upper", "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ ""
+ },
+ {
+ "xdigit", "0123456789ABCDEFabcdef",
+ ""
+ },
+ {
+ NULL, 0, ""
+ }
};
diff --git a/src/include/regex/cdefs.h b/src/include/regex/cdefs.h
index 3a548f3ea15..8493c2563c7 100644
--- a/src/include/regex/cdefs.h
+++ b/src/include/regex/cdefs.h
@@ -2,28 +2,28 @@
* ++Copyright++ 1991, 1993
* -
* Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
+ * The Regents of the University of California. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -33,17 +33,17 @@
* SUCH DAMAGE.
* -
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ *
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that
* the name of Digital Equipment Corporation not be used in advertising or
* publicity pertaining to distribution of the document or software without
* specific, written prior permission.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
@@ -54,19 +54,19 @@
*/
/*
- * @(#)cdefs.h 8.1 (Berkeley) 6/2/93
- * $Id: cdefs.h,v 1.2 1996/09/21 06:31:13 scrappy Exp $
+ * @(#)cdefs.h 8.1 (Berkeley) 6/2/93
+ * $Id: cdefs.h,v 1.3 1997/09/07 05:00:14 momjian Exp $
*/
-#ifndef _CDEFS_H_
-#define _CDEFS_H_
+#ifndef _CDEFS_H_
+#define _CDEFS_H_
#if defined(__cplusplus)
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
+#define __BEGIN_DECLS extern "C" {
+#define __END_DECLS };
#else
-#define __BEGIN_DECLS
-#define __END_DECLS
+#define __BEGIN_DECLS
+#define __END_DECLS
#endif
/*
@@ -77,38 +77,38 @@
* strings produced by the __STRING macro, but this only works with ANSI C.
*/
#if defined(__STDC__) || defined(__cplusplus)
-/*
+/*
* Some headers in the Linux C library define __P the same as here,
* but with different argument variable name. This causes a compiler
* warning! So we avoid the redefinition.
*/
#if !defined(__P)
-#define __P(protos) protos /* full-blown ANSI C */
+#define __P(protos) protos /* full-blown ANSI C */
#endif
-#define __CONCAT(x,y) x ## y
-#define __STRING(x) #x
+#define __CONCAT(x,y) x ## y
+#define __STRING(x) #x
-#define __const const /* define reserved names to standard */
-#define __signed signed
-#define __volatile volatile
+#define __const const /* define reserved names to standard */
+#define __signed signed
+#define __volatile volatile
#if defined(__cplusplus)
-#define __inline inline /* convert to C++ keyword */
+#define __inline inline /* convert to C++ keyword */
#else
#ifndef __GNUC__
-#define __inline /* delete GCC keyword */
-#endif /* !__GNUC__ */
-#endif /* !__cplusplus */
+#define __inline /* delete GCC keyword */
+#endif /* !__GNUC__ */
+#endif /* !__cplusplus */
-#else /* !(__STDC__ || __cplusplus) */
-#define __P(protos) () /* traditional C preprocessor */
-#define __CONCAT(x,y) x/**/y
-#define __STRING(x) "x"
+#else /* !(__STDC__ || __cplusplus) */
+#define __P(protos) () /* traditional C preprocessor */
+#define __CONCAT(x,y) x/**/y
+#define __STRING(x) "x"
#ifndef __GNUC__
-#define __const /* delete pseudo-ANSI C keywords */
-#define __inline
-#define __signed
-#define __volatile
+#define __const /* delete pseudo-ANSI C keywords */
+#define __inline
+#define __signed
+#define __volatile
/*
* In non-ANSI C environments, new programs will want ANSI-only C keywords
* deleted from the program and old programs will want them left alone.
@@ -117,35 +117,35 @@
* When using "gcc -traditional", we assume that this is the intent; if
* __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
*/
-#ifndef NO_ANSI_KEYWORDS
-#define const /* delete ANSI C keywords */
-#define inline
-#define signed
-#define volatile
+#ifndef NO_ANSI_KEYWORDS
+#define const /* delete ANSI C keywords */
+#define inline
+#define signed
+#define volatile
#endif
-#endif /* !__GNUC__ */
-#endif /* !(__STDC__ || __cplusplus) */
+#endif /* !__GNUC__ */
+#endif /* !(__STDC__ || __cplusplus) */
/*
* GCC1 and some versions of GCC2 declare dead (non-returning) and
* pure (no side effects) functions using "volatile" and "const";
* unfortunately, these then cause warnings under "-ansi -pedantic".
- * GCC2 uses a new, peculiar __attribute__((attrs)) style. All of
+ * GCC2 uses a new, peculiar __attribute__((attrs)) style. All of
* these work for GNU C++ (modulo a slight glitch in the C++ grammar
* in the distribution version of 2.5.5).
*/
#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 5
-#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */
+#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-#define __dead __volatile
-#define __pure __const
+#define __dead __volatile
+#define __pure __const
#endif
#endif
/* Delete pseudo-keywords wherever they are not available or needed. */
#ifndef __dead
-#define __dead
-#define __pure
+#define __dead
+#define __pure
#endif
-#endif /* !_CDEFS_H_ */
+#endif /* !_CDEFS_H_ */
diff --git a/src/include/regex/cname.h b/src/include/regex/cname.h
index c6ba15bdc36..8cf78f7cbe5 100644
--- a/src/include/regex/cname.h
+++ b/src/include/regex/cname.h
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,108 +34,303 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)cname.h 8.3 (Berkeley) 3/20/94
+ * @(#)cname.h 8.3 (Berkeley) 3/20/94
*/
/* character-name table */
-static struct cname {
- char *name;
- char code;
-} cnames[] = {
- {"NUL", '\0'},
- {"SOH", '\001'},
- {"STX", '\002'},
- {"ETX", '\003'},
- {"EOT", '\004'},
- {"ENQ", '\005'},
- {"ACK", '\006'},
- {"BEL", '\007'},
- {"alert", '\007'},
- {"BS", '\010'},
- {"backspace", '\b'},
- {"HT", '\011'},
- {"tab", '\t'},
- {"LF", '\012'},
- {"newline", '\n'},
- {"VT", '\013'},
- {"vertical-tab", '\v'},
- {"FF", '\014'},
- {"form-feed", '\f'},
- {"CR", '\015'},
- {"carriage-return", '\r'},
- {"SO", '\016'},
- {"SI", '\017'},
- {"DLE", '\020'},
- {"DC1", '\021'},
- {"DC2", '\022'},
- {"DC3", '\023'},
- {"DC4", '\024'},
- {"NAK", '\025'},
- {"SYN", '\026'},
- {"ETB", '\027'},
- {"CAN", '\030'},
- {"EM", '\031'},
- {"SUB", '\032'},
- {"ESC", '\033'},
- {"IS4", '\034'},
- {"FS", '\034'},
- {"IS3", '\035'},
- {"GS", '\035'},
- {"IS2", '\036'},
- {"RS", '\036'},
- {"IS1", '\037'},
- {"US", '\037'},
- {"space", ' '},
- {"exclamation-mark", '!'},
- {"quotation-mark", '"'},
- {"number-sign", '#'},
- {"dollar-sign", '$'},
- {"percent-sign", '%'},
- {"ampersand", '&'},
- {"apostrophe", '\''},
- {"left-parenthesis", '('},
- {"right-parenthesis", ')'},
- {"asterisk", '*'},
- {"plus-sign", '+'},
- {"comma", ','},
- {"hyphen", '-'},
- {"hyphen-minus", '-'},
- {"period", '.'},
- {"full-stop", '.'},
- {"slash", '/'},
- {"solidus", '/'},
- {"zero", '0'},
- {"one", '1'},
- {"two", '2'},
- {"three", '3'},
- {"four", '4'},
- {"five", '5'},
- {"six", '6'},
- {"seven", '7'},
- {"eight", '8'},
- {"nine", '9'},
- {"colon", ':'},
- {"semicolon", ';'},
- {"less-than-sign", '<'},
- {"equals-sign", '='},
- {"greater-than-sign", '>'},
- {"question-mark", '?'},
- {"commercial-at", '@'},
- {"left-square-bracket", '['},
- {"backslash", '\\'},
- {"reverse-solidus", '\\'},
- {"right-square-bracket", ']'},
- {"circumflex", '^'},
- {"circumflex-accent", '^'},
- {"underscore", '_'},
- {"low-line", '_'},
- {"grave-accent", '`'},
- {"left-brace", '{'},
- {"left-curly-bracket", '{'},
- {"vertical-line", '|'},
- {"right-brace", '}'},
- {"right-curly-bracket", '}'},
- {"tilde", '~'},
- {"DEL", '\177'},
- {NULL, 0}
+static struct cname
+{
+ char *name;
+ char code;
+} cnames[] =
+
+{
+ {
+ "NUL", '\0'
+ },
+ {
+ "SOH", '\001'
+ },
+ {
+ "STX", '\002'
+ },
+ {
+ "ETX", '\003'
+ },
+ {
+ "EOT", '\004'
+ },
+ {
+ "ENQ", '\005'
+ },
+ {
+ "ACK", '\006'
+ },
+ {
+ "BEL", '\007'
+ },
+ {
+ "alert", '\007'
+ },
+ {
+ "BS", '\010'
+ },
+ {
+ "backspace", '\b'
+ },
+ {
+ "HT", '\011'
+ },
+ {
+ "tab", '\t'
+ },
+ {
+ "LF", '\012'
+ },
+ {
+ "newline", '\n'
+ },
+ {
+ "VT", '\013'
+ },
+ {
+ "vertical-tab", '\v'
+ },
+ {
+ "FF", '\014'
+ },
+ {
+ "form-feed", '\f'
+ },
+ {
+ "CR", '\015'
+ },
+ {
+ "carriage-return", '\r'
+ },
+ {
+ "SO", '\016'
+ },
+ {
+ "SI", '\017'
+ },
+ {
+ "DLE", '\020'
+ },
+ {
+ "DC1", '\021'
+ },
+ {
+ "DC2", '\022'
+ },
+ {
+ "DC3", '\023'
+ },
+ {
+ "DC4", '\024'
+ },
+ {
+ "NAK", '\025'
+ },
+ {
+ "SYN", '\026'
+ },
+ {
+ "ETB", '\027'
+ },
+ {
+ "CAN", '\030'
+ },
+ {
+ "EM", '\031'
+ },
+ {
+ "SUB", '\032'
+ },
+ {
+ "ESC", '\033'
+ },
+ {
+ "IS4", '\034'
+ },
+ {
+ "FS", '\034'
+ },
+ {
+ "IS3", '\035'
+ },
+ {
+ "GS", '\035'
+ },
+ {
+ "IS2", '\036'
+ },
+ {
+ "RS", '\036'
+ },
+ {
+ "IS1", '\037'
+ },
+ {
+ "US", '\037'
+ },
+ {
+ "space", ' '
+ },
+ {
+ "exclamation-mark", '!'
+ },
+ {
+ "quotation-mark", '"'
+ },
+ {
+ "number-sign", '#'
+ },
+ {
+ "dollar-sign", '$'
+ },
+ {
+ "percent-sign", '%'
+ },
+ {
+ "ampersand", '&'
+ },
+ {
+ "apostrophe", '\''
+ },
+ {
+ "left-parenthesis", '('
+ },
+ {
+ "right-parenthesis", ')'
+ },
+ {
+ "asterisk", '*'
+ },
+ {
+ "plus-sign", '+'
+ },
+ {
+ "comma", ','
+ },
+ {
+ "hyphen", '-'
+ },
+ {
+ "hyphen-minus", '-'
+ },
+ {
+ "period", '.'
+ },
+ {
+ "full-stop", '.'
+ },
+ {
+ "slash", '/'
+ },
+ {
+ "solidus", '/'
+ },
+ {
+ "zero", '0'
+ },
+ {
+ "one", '1'
+ },
+ {
+ "two", '2'
+ },
+ {
+ "three", '3'
+ },
+ {
+ "four", '4'
+ },
+ {
+ "five", '5'
+ },
+ {
+ "six", '6'
+ },
+ {
+ "seven", '7'
+ },
+ {
+ "eight", '8'
+ },
+ {
+ "nine", '9'
+ },
+ {
+ "colon", ':'
+ },
+ {
+ "semicolon", ';'
+ },
+ {
+ "less-than-sign", '<'
+ },
+ {
+ "equals-sign", '='
+ },
+ {
+ "greater-than-sign", '>'
+ },
+ {
+ "question-mark", '?'
+ },
+ {
+ "commercial-at", '@'
+ },
+ {
+ "left-square-bracket", '['
+ },
+ {
+ "backslash", '\\'
+ },
+ {
+ "reverse-solidus", '\\'
+ },
+ {
+ "right-square-bracket", ']'
+ },
+ {
+ "circumflex", '^'
+ },
+ {
+ "circumflex-accent", '^'
+ },
+ {
+ "underscore", '_'
+ },
+ {
+ "low-line", '_'
+ },
+ {
+ "grave-accent", '`'
+ },
+ {
+ "left-brace", '{'
+ },
+ {
+ "left-curly-bracket", '{'
+ },
+ {
+ "vertical-line", '|'
+ },
+ {
+ "right-brace", '}'
+ },
+ {
+ "right-curly-bracket", '}'
+ },
+ {
+ "tilde", '~'
+ },
+ {
+ "DEL", '\177'
+ },
+ {
+ NULL, 0
+ }
};
diff --git a/src/include/regex/regex.h b/src/include/regex/regex.h
index 08f561d4132..18b39768849 100644
--- a/src/include/regex/regex.h
+++ b/src/include/regex/regex.h
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992 Henry Spencer.
* Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer of the University of Toronto.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)regex.h 8.2 (Berkeley) 1/3/94
+ * @(#)regex.h 8.2 (Berkeley) 1/3/94
*/
#ifndef _REGEX_H_
@@ -43,62 +43,65 @@
#include <sys/types.h>
/* types */
-typedef off_t regoff_t;
+typedef off_t regoff_t;
-typedef struct {
- int re_magic;
- size_t re_nsub; /* number of parenthesized subexpressions */
- const char *re_endp; /* end pointer for REG_PEND */
- struct re_guts *re_g; /* none of your business :-) */
-} regex_t;
+typedef struct
+{
+ int re_magic;
+ size_t re_nsub; /* number of parenthesized subexpressions */
+ const char *re_endp; /* end pointer for REG_PEND */
+ struct re_guts *re_g; /* none of your business :-) */
+} regex_t;
-typedef struct {
- regoff_t rm_so; /* start of match */
- regoff_t rm_eo; /* end of match */
-} regmatch_t;
+typedef struct
+{
+ regoff_t rm_so; /* start of match */
+ regoff_t rm_eo; /* end of match */
+} regmatch_t;
/* regcomp() flags */
-#define REG_BASIC 0000
-#define REG_EXTENDED 0001
-#define REG_ICASE 0002
-#define REG_NOSUB 0004
-#define REG_NEWLINE 0010
-#define REG_NOSPEC 0020
-#define REG_PEND 0040
-#define REG_DUMP 0200
+#define REG_BASIC 0000
+#define REG_EXTENDED 0001
+#define REG_ICASE 0002
+#define REG_NOSUB 0004
+#define REG_NEWLINE 0010
+#define REG_NOSPEC 0020
+#define REG_PEND 0040
+#define REG_DUMP 0200
/* regerror() flags */
-#define REG_NOMATCH 1
-#define REG_BADPAT 2
-#define REG_ECOLLATE 3
-#define REG_ECTYPE 4
-#define REG_EESCAPE 5
-#define REG_ESUBREG 6
-#define REG_EBRACK 7
-#define REG_EPAREN 8
-#define REG_EBRACE 9
-#define REG_BADBR 10
-#define REG_ERANGE 11
-#define REG_ESPACE 12
-#define REG_BADRPT 13
-#define REG_EMPTY 14
-#define REG_ASSERT 15
-#define REG_INVARG 16
-#define REG_ATOI 255 /* convert name to number (!) */
-#define REG_ITOA 0400 /* convert number to name (!) */
+#define REG_NOMATCH 1
+#define REG_BADPAT 2
+#define REG_ECOLLATE 3
+#define REG_ECTYPE 4
+#define REG_EESCAPE 5
+#define REG_ESUBREG 6
+#define REG_EBRACK 7
+#define REG_EPAREN 8
+#define REG_EBRACE 9
+#define REG_BADBR 10
+#define REG_ERANGE 11
+#define REG_ESPACE 12
+#define REG_BADRPT 13
+#define REG_EMPTY 14
+#define REG_ASSERT 15
+#define REG_INVARG 16
+#define REG_ATOI 255 /* convert name to number (!) */
+#define REG_ITOA 0400 /* convert number to name (!) */
/* regexec() flags */
-#define REG_NOTBOL 00001
-#define REG_NOTEOL 00002
-#define REG_STARTEND 00004
-#define REG_TRACE 00400 /* tracing of execution */
-#define REG_LARGE 01000 /* force large representation */
-#define REG_BACKR 02000 /* force use of backref code */
+#define REG_NOTBOL 00001
+#define REG_NOTEOL 00002
+#define REG_STARTEND 00004
+#define REG_TRACE 00400 /* tracing of execution */
+#define REG_LARGE 01000 /* force large representation */
+#define REG_BACKR 02000 /* force use of backref code */
-int pg95_regcomp(regex_t *, const char *, int);
-size_t pg95_regerror(int, const regex_t *, char *, size_t);
-int pg95_regexec (const regex_t *,
- const char *, size_t, regmatch_t [], int);
-void pg95_regfree (regex_t *);
+int pg95_regcomp(regex_t *, const char *, int);
+size_t pg95_regerror(int, const regex_t *, char *, size_t);
+int
+pg95_regexec(const regex_t *,
+ const char *, size_t, regmatch_t[], int);
+void pg95_regfree(regex_t *);
-#endif /* !_REGEX_H_ */
+#endif /* !_REGEX_H_ */
diff --git a/src/include/regex/regex2.h b/src/include/regex/regex2.h
index 34d3f63663d..960a6d1dfce 100644
--- a/src/include/regex/regex2.h
+++ b/src/include/regex/regex2.h
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)regex2.h 8.4 (Berkeley) 3/20/94
+ * @(#)regex2.h 8.4 (Berkeley) 3/20/94
*/
/*
@@ -43,70 +43,73 @@
/*
typedef off_t regoff_t;
typedef struct {
- int re_magic;
- size_t re_nsub; // number of parenthesized subexpressions
- const char *re_endp; // end pointer for REG_PEND
- struct re_guts *re_g; // none of your business :-)
+ int re_magic;
+ size_t re_nsub; // number of parenthesized subexpressions
+ const char *re_endp; // end pointer for REG_PEND
+ struct re_guts *re_g; // none of your business :-)
} regex_t;
typedef struct {
- regoff_t rm_so; // start of match
- regoff_t rm_eo; // end of match
+ regoff_t rm_so; // start of match
+ regoff_t rm_eo; // end of match
} regmatch_t;
*/
/*
* internals of regex_t
*/
-#define MAGIC1 ((('r'^0200)<<8) | 'e')
+#define MAGIC1 ((('r'^0200)<<8) | 'e')
/*
* The internal representation is a *strip*, a sequence of
- * operators ending with an endmarker. (Some terminology etc. is a
+ * operators ending with an endmarker. (Some terminology etc. is a
* historical relic of earlier versions which used multiple strips.)
* Certain oddities in the representation are there to permit running
* the machinery backwards; in particular, any deviation from sequential
- * flow must be marked at both its source and its destination. Some
+ * flow must be marked at both its source and its destination. Some
* fine points:
*
* - OPLUS_ and O_PLUS are *inside* the loop they create.
* - OQUEST_ and O_QUEST are *outside* the bypass they create.
* - OCH_ and O_CH are *outside* the multi-way branch they create, while
- * OOR1 and OOR2 are respectively the end and the beginning of one of
- * the branches. Note that there is an implicit OOR2 following OCH_
- * and an implicit OOR1 preceding O_CH.
+ * OOR1 and OOR2 are respectively the end and the beginning of one of
+ * the branches. Note that there is an implicit OOR2 following OCH_
+ * and an implicit OOR1 preceding O_CH.
*
* In state representations, an operator's bit is on to signify a state
* immediately *preceding* "execution" of that operator.
*/
-typedef unsigned long sop; /* strip operator */
-typedef long sopno;
-#define OPRMASK 0xf8000000
-#define OPDMASK 0x07ffffff
-#define OPSHIFT ((unsigned)27)
-#define OP(n) ((n)&OPRMASK)
-#define OPND(n) ((n)&OPDMASK)
-#define SOP(op, opnd) ((op)|(opnd))
-/* operators meaning operand */
-/* (back, fwd are offsets) */
-#define OEND ((size_t)1<<OPSHIFT) /* endmarker - */
-#define OCHAR ((size_t)2<<OPSHIFT) /* character unsigned char */
-#define OBOL ((size_t)3<<OPSHIFT) /* left anchor - */
-#define OEOL ((size_t)4<<OPSHIFT) /* right anchor - */
-#define OANY ((size_t)5<<OPSHIFT) /* . - */
-#define OANYOF ((size_t)6<<OPSHIFT) /* [...] set number */
-#define OBACK_ ((size_t)7<<OPSHIFT) /* begin \d paren number */
-#define O_BACK ((size_t)8<<OPSHIFT) /* end \d paren number */
-#define OPLUS_ ((size_t)9<<OPSHIFT) /* + prefix fwd to suffix */
-#define O_PLUS ((size_t)10<<OPSHIFT) /* + suffix back to prefix */
-#define OQUEST_ ((size_t)11<<OPSHIFT) /* ? prefix fwd to suffix */
-#define O_QUEST ((size_t)12<<OPSHIFT) /* ? suffix back to prefix */
-#define OLPAREN ((size_t)13<<OPSHIFT) /* ( fwd to ) */
-#define ORPAREN ((size_t)14<<OPSHIFT) /* ) back to ( */
-#define OCH_ ((size_t)15<<OPSHIFT) /* begin choice fwd to OOR2 */
-#define OOR1 ((size_t)16<<OPSHIFT) /* | pt. 1 back to OOR1 or OCH_ */
-#define OOR2 ((size_t)17<<OPSHIFT) /* | pt. 2 fwd to OOR2 or O_CH */
-#define O_CH ((size_t)18<<OPSHIFT) /* end choice back to OOR1 */
-#define OBOW ((size_t)19<<OPSHIFT) /* begin word - */
-#define OEOW ((size_t)20<<OPSHIFT) /* end word - */
+typedef unsigned long sop; /* strip operator */
+typedef long sopno;
+
+#define OPRMASK 0xf8000000
+#define OPDMASK 0x07ffffff
+#define OPSHIFT ((unsigned)27)
+#define OP(n) ((n)&OPRMASK)
+#define OPND(n) ((n)&OPDMASK)
+#define SOP(op, opnd) ((op)|(opnd))
+/* operators meaning operand */
+/* (back, fwd are offsets) */
+#define OEND ((size_t)1<<OPSHIFT) /* endmarker - */
+#define OCHAR ((size_t)2<<OPSHIFT) /* character unsigned char */
+#define OBOL ((size_t)3<<OPSHIFT) /* left anchor - */
+#define OEOL ((size_t)4<<OPSHIFT) /* right anchor - */
+#define OANY ((size_t)5<<OPSHIFT) /* . - */
+#define OANYOF ((size_t)6<<OPSHIFT) /* [...] set number */
+#define OBACK_ ((size_t)7<<OPSHIFT) /* begin \d paren number */
+#define O_BACK ((size_t)8<<OPSHIFT) /* end \d paren number */
+#define OPLUS_ ((size_t)9<<OPSHIFT) /* + prefix fwd to suffix */
+#define O_PLUS ((size_t)10<<OPSHIFT) /* + suffix back to prefix */
+#define OQUEST_ ((size_t)11<<OPSHIFT) /* ? prefix fwd to suffix */
+#define O_QUEST ((size_t)12<<OPSHIFT) /* ? suffix back to prefix */
+#define OLPAREN ((size_t)13<<OPSHIFT) /* ( fwd to ) */
+#define ORPAREN ((size_t)14<<OPSHIFT) /* ) back to ( */
+#define OCH_ ((size_t)15<<OPSHIFT) /* begin choice fwd to OOR2 */
+#define OOR1 ((size_t)16<<OPSHIFT) /* | pt. 1 back to OOR1 or
+ * OCH_ */
+#define OOR2 ((size_t)17<<OPSHIFT) /* | pt. 2 fwd to OOR2 or
+ * O_CH */
+#define O_CH ((size_t)18<<OPSHIFT) /* end choice back to OOR1 */
+#define OBOW ((size_t)19<<OPSHIFT) /* begin word - */
+#define OEOW ((size_t)20<<OPSHIFT) /* end word - */
/*
* Structure for [] character-set representation. Character sets are
@@ -120,20 +123,23 @@ typedef long sopno;
* a string of multi-character elements, and decide the size of the
* vectors at run time.
*/
-typedef struct {
- uch *ptr; /* -> uch [csetsize] */
- uch mask; /* bit within array */
- uch hash; /* hash code */
- size_t smultis;
- char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */
-} cset;
+typedef struct
+{
+ uch *ptr; /* -> uch [csetsize] */
+ uch mask; /* bit within array */
+ uch hash; /* hash code */
+ size_t smultis;
+ char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */
+} cset;
+
/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */
-#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c))
-#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c))
-#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask)
-#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* regcomp() internal fns */
-#define MCsub(p, cs, cp) mcsub(p, cs, cp)
-#define MCin(p, cs, cp) mcin(p, cs, cp)
+#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c))
+#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c))
+#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask)
+#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* regcomp() internal
+ * fns */
+#define MCsub(p, cs, cp) mcsub(p, cs, cp)
+#define MCin(p, cs, cp) mcin(p, cs, cp)
/* stuff for character categories */
typedef unsigned char cat_t;
@@ -141,35 +147,36 @@ typedef unsigned char cat_t;
/*
* main compiled-expression structure
*/
-struct re_guts {
- int magic;
-# define MAGIC2 ((('R'^0200)<<8)|'E')
- sop *strip; /* malloced area for strip */
- int csetsize; /* number of bits in a cset vector */
- int ncsets; /* number of csets in use */
- cset *sets; /* -> cset [ncsets] */
- uch *setbits; /* -> uch[csetsize][ncsets/CHAR_BIT] */
- int cflags; /* copy of regcomp() cflags argument */
- sopno nstates; /* = number of sops */
- sopno firststate; /* the initial OEND (normally 0) */
- sopno laststate; /* the final OEND */
- int iflags; /* internal flags */
-# define USEBOL 01 /* used ^ */
-# define USEEOL 02 /* used $ */
-# define BAD 04 /* something wrong */
- int nbol; /* number of ^ used */
- int neol; /* number of $ used */
- int ncategories; /* how many character categories */
- cat_t *categories; /* ->catspace[-CHAR_MIN] */
- char *must; /* match must contain this string */
- int mlen; /* length of must */
- size_t nsub; /* copy of re_nsub */
- int backrefs; /* does it use back references? */
- sopno nplus; /* how deep does it nest +s? */
+struct re_guts
+{
+ int magic;
+#define MAGIC2 ((('R'^0200)<<8)|'E')
+ sop *strip; /* malloced area for strip */
+ int csetsize; /* number of bits in a cset vector */
+ int ncsets; /* number of csets in use */
+ cset *sets; /* -> cset [ncsets] */
+ uch *setbits; /* -> uch[csetsize][ncsets/CHAR_BIT] */
+ int cflags; /* copy of regcomp() cflags argument */
+ sopno nstates; /* = number of sops */
+ sopno firststate; /* the initial OEND (normally 0) */
+ sopno laststate; /* the final OEND */
+ int iflags; /* internal flags */
+#define USEBOL 01 /* used ^ */
+#define USEEOL 02 /* used $ */
+#define BAD 04 /* something wrong */
+ int nbol; /* number of ^ used */
+ int neol; /* number of $ used */
+ int ncategories;/* how many character categories */
+ cat_t *categories; /* ->catspace[-CHAR_MIN] */
+ char *must; /* match must contain this string */
+ int mlen; /* length of must */
+ size_t nsub; /* copy of re_nsub */
+ int backrefs; /* does it use back references? */
+ sopno nplus; /* how deep does it nest +s? */
/* catspace must be last */
- cat_t catspace[1]; /* actually [NC] */
+ cat_t catspace[1];/* actually [NC] */
};
/* misc utilities */
-#define OUT (CHAR_MAX+1) /* a non-character value */
-#define ISWORD(c) (isalnum(c) || (c) == '_')
+#define OUT (CHAR_MAX+1) /* a non-character value */
+#define ISWORD(c) (isalnum(c) || (c) == '_')
diff --git a/src/include/regex/regexp.h b/src/include/regex/regexp.h
index 25438e3f37d..cbbb26367df 100644
--- a/src/include/regex/regexp.h
+++ b/src/include/regex/regexp.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) 1986 by University of Toronto.
* Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley
* by Henry Spencer.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,36 +34,38 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)regexp.h 8.1 (Berkeley) 6/2/93
+ * @(#)regexp.h 8.1 (Berkeley) 6/2/93
*/
-#ifndef _REGEXP_H_
-#define _REGEXP_H_
+#ifndef _REGEXP_H_
+#define _REGEXP_H_
/*
* Definitions etc. for regexp(3) routines.
*
- * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
+ * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
* not the System V one.
*/
#define NSUBEXP 10
-typedef struct regexp {
- char *startp[NSUBEXP];
- char *endp[NSUBEXP];
- char regstart; /* Internal use only. */
- char reganch; /* Internal use only. */
- char *regmust; /* Internal use only. */
- int regmlen; /* Internal use only. */
- char program[1]; /* Unwarranted chumminess with compiler. */
-} regexp;
+typedef struct regexp
+{
+ char *startp[NSUBEXP];
+ char *endp[NSUBEXP];
+ char regstart; /* Internal use only. */
+ char reganch; /* Internal use only. */
+ char *regmust; /* Internal use only. */
+ int regmlen; /* Internal use only. */
+ char program[1]; /* Unwarranted chumminess with compiler. */
+} regexp;
/* since not all systems have cdefs.h, we'll use our own here - jolly */
__BEGIN_DECLS
-regexp *pg95_regcomp __P((const char *));
-int pg95_regexec __P((const regexp *, const char *));
-void pg95_regsub __P((const regexp *, const char *, char *));
+regexp * pg95_regcomp __P((const char *));
+int pg95_regexec __P((const regexp *, const char *));
+void pg95_regsub __P((const regexp *, const char *, char *));
void pg95_regerror __P((const char *));
+
__END_DECLS
-#endif /* !_REGEXP_H_ */
+#endif /* !_REGEXP_H_ */
diff --git a/src/include/regex/utils.h b/src/include/regex/utils.h
index 98857d0977c..a7cae06919c 100644
--- a/src/include/regex/utils.h
+++ b/src/include/regex/utils.h
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
* Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
@@ -10,22 +10,22 @@
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -34,25 +34,25 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)utils.h 8.3 (Berkeley) 3/20/94
+ * @(#)utils.h 8.3 (Berkeley) 3/20/94
*/
-#include "config.h" /* HAVE_MEMMOVE */
+#include "config.h" /* HAVE_MEMMOVE */
/* utility definitions */
-#define DUPMAX 100000000 /* xxx is this right? */
-#define INFINITY (DUPMAX + 1)
-#define NC (CHAR_MAX - CHAR_MIN + 1)
+#define DUPMAX 100000000 /* xxx is this right? */
+#define INFINITY (DUPMAX + 1)
+#define NC (CHAR_MAX - CHAR_MIN + 1)
typedef unsigned char uch;
/* switch off assertions (if not already off) if no REDEBUG */
#ifndef REDEBUG
#ifndef NDEBUG
-#define NDEBUG /* no assertions please */
+#define NDEBUG /* no assertions please */
#endif
#endif
/* for old systems with bcopy() but no memmove() */
#if !defined(HAVE_MEMMOVE)
-#define memmove(d, s, c) bcopy(s, d, c)
+#define memmove(d, s, c) bcopy(s, d, c)
#endif
diff --git a/src/include/rewrite/locks.h b/src/include/rewrite/locks.h
index 04c5f5db10f..f01f5a713b2 100644
--- a/src/include/rewrite/locks.h
+++ b/src/include/rewrite/locks.h
@@ -1,23 +1,24 @@
/*-------------------------------------------------------------------------
*
* locks.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: locks.h,v 1.3 1996/11/08 06:02:00 momjian Exp $
+ * $Id: locks.h,v 1.4 1997/09/07 05:00:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef LOCKS_H
-#define LOCKS_H
+#ifndef LOCKS_H
+#define LOCKS_H
#include "nodes/nodes.h"
#include "nodes/parsenodes.h"
#include "rewrite/prs2lock.h"
-extern List *matchLocks(CmdType event, RuleLock *rulelocks, int varno,
- Query *parsetree);
+extern List *
+matchLocks(CmdType event, RuleLock * rulelocks, int varno,
+ Query * parsetree);
-#endif /* LOCKS_H */
+#endif /* LOCKS_H */
diff --git a/src/include/rewrite/prs2lock.h b/src/include/rewrite/prs2lock.h
index d7be60641ae..0bf8a258867 100644
--- a/src/include/rewrite/prs2lock.h
+++ b/src/include/rewrite/prs2lock.h
@@ -1,11 +1,11 @@
/*-------------------------------------------------------------------------
*
* prs2lock.h--
- * data structures for POSTGRES Rule System II (rewrite rules only)
+ * data structures for POSTGRES Rule System II (rewrite rules only)
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: prs2lock.h,v 1.4 1996/11/04 07:45:46 scrappy Exp $
+ * $Id: prs2lock.h,v 1.5 1997/09/07 05:00:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,27 +17,29 @@
/*
* RewriteRule -
- * holds a info for a rewrite rule
+ * holds a info for a rewrite rule
*
*/
-typedef struct RewriteRule {
- Oid ruleId;
- CmdType event;
- AttrNumber attrno;
- Node *qual;
- List *actions;
- bool isInstead;
-} RewriteRule;
+typedef struct RewriteRule
+{
+ Oid ruleId;
+ CmdType event;
+ AttrNumber attrno;
+ Node *qual;
+ List *actions;
+ bool isInstead;
+} RewriteRule;
/*
* RuleLock -
- * all rules that apply to a particular relation. Even though we only
- * have the rewrite rule system left and these are not really "locks",
- * the name is kept for historical reasons.
+ * all rules that apply to a particular relation. Even though we only
+ * have the rewrite rule system left and these are not really "locks",
+ * the name is kept for historical reasons.
*/
-typedef struct RuleLock {
- int numLocks;
- RewriteRule **rules;
-} RuleLock;
+typedef struct RuleLock
+{
+ int numLocks;
+ RewriteRule **rules;
+} RuleLock;
-#endif /* REWRITE_H */
+#endif /* REWRITE_H */
diff --git a/src/include/rewrite/rewriteDefine.h b/src/include/rewrite/rewriteDefine.h
index f661fff8527..214daa85f56 100644
--- a/src/include/rewrite/rewriteDefine.h
+++ b/src/include/rewrite/rewriteDefine.h
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* rewriteDefine.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rewriteDefine.h,v 1.1 1996/08/28 07:24:06 scrappy Exp $
+ * $Id: rewriteDefine.h,v 1.2 1997/09/07 05:00:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef REWRITEDEFINE_H
-#define REWRITEDEFINE_H
+#ifndef REWRITEDEFINE_H
+#define REWRITEDEFINE_H
-extern void DefineQueryRewrite(RuleStmt *args);
+extern void DefineQueryRewrite(RuleStmt * args);
-#endif /* REWRITEDEFINE_H */
+#endif /* REWRITEDEFINE_H */
diff --git a/src/include/rewrite/rewriteHandler.h b/src/include/rewrite/rewriteHandler.h
index 43291e07b5c..3d03f29ba17 100644
--- a/src/include/rewrite/rewriteHandler.h
+++ b/src/include/rewrite/rewriteHandler.h
@@ -1,35 +1,36 @@
/*-------------------------------------------------------------------------
*
* rewriteHandler.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rewriteHandler.h,v 1.1 1996/08/28 07:24:07 scrappy Exp $
+ * $Id: rewriteHandler.h,v 1.2 1997/09/07 05:00:34 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef REWRITEHANDLER_H
-#define REWRITEHANDLER_H
+#ifndef REWRITEHANDLER_H
+#define REWRITEHANDLER_H
-struct _rewrite_meta_knowledge {
- List *rt;
- int rt_index;
- bool instead_flag;
- int event;
- CmdType action;
- int current_varno;
- int new_varno;
- Query *rule_action;
- Node *rule_qual;
- bool nothing;
+struct _rewrite_meta_knowledge
+{
+ List *rt;
+ int rt_index;
+ bool instead_flag;
+ int event;
+ CmdType action;
+ int current_varno;
+ int new_varno;
+ Query *rule_action;
+ Node *rule_qual;
+ bool nothing;
};
typedef struct _rewrite_meta_knowledge RewriteInfo;
-extern List *QueryRewrite(Query *parsetree);
+extern List *QueryRewrite(Query * parsetree);
-#endif /*REWRITEHANDLER_H */
+#endif /* REWRITEHANDLER_H */
diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h
index 0b9135c1c79..4c8b09e9889 100644
--- a/src/include/rewrite/rewriteManip.h
+++ b/src/include/rewrite/rewriteManip.h
@@ -1,31 +1,32 @@
/*-------------------------------------------------------------------------
*
* rewriteManip.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rewriteManip.h,v 1.1 1996/08/28 07:24:08 scrappy Exp $
+ * $Id: rewriteManip.h,v 1.2 1997/09/07 05:00:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef REWRITEMANIP_H
-#define REWRITEMANIP_H
+#ifndef REWRITEMANIP_H
+#define REWRITEMANIP_H
/* RewriteManip.c */
-void OffsetVarNodes(Node *node, int offset);
-void ChangeVarNodes(Node *node, int old_varno, int new_varno);
-void AddQual(Query *parsetree, Node *qual);
-void AddNotQual(Query *parsetree, Node *qual);
-void FixResdomTypes(List *user_tlist);
-void FixNew(RewriteInfo *info, Query *parsetree);
-
-void HandleRIRAttributeRule(Query *parsetree, List *rtable, List *targetlist,
- int rt_index, int attr_num, int *modified,
- int *badpostquel);
-void HandleViewRule(Query *parsetree, List *rtable, List *targetlist,
- int rt_index, int *modified);
+void OffsetVarNodes(Node * node, int offset);
+void ChangeVarNodes(Node * node, int old_varno, int new_varno);
+void AddQual(Query * parsetree, Node * qual);
+void AddNotQual(Query * parsetree, Node * qual);
+void FixResdomTypes(List * user_tlist);
+void FixNew(RewriteInfo * info, Query * parsetree);
-#endif /* REWRITEMANIP_H */
+void
+HandleRIRAttributeRule(Query * parsetree, List * rtable, List * targetlist,
+ int rt_index, int attr_num, int *modified,
+ int *badpostquel);
+void
+HandleViewRule(Query * parsetree, List * rtable, List * targetlist,
+ int rt_index, int *modified);
+#endif /* REWRITEMANIP_H */
diff --git a/src/include/rewrite/rewriteRemove.h b/src/include/rewrite/rewriteRemove.h
index 11d97c96d64..947a5815eae 100644
--- a/src/include/rewrite/rewriteRemove.h
+++ b/src/include/rewrite/rewriteRemove.h
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* rewriteRemove.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rewriteRemove.h,v 1.1 1996/08/28 07:24:12 scrappy Exp $
+ * $Id: rewriteRemove.h,v 1.2 1997/09/07 05:00:37 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef REWRITEREMOVE_H
-#define REWRITEREMOVE_H
+#ifndef REWRITEREMOVE_H
+#define REWRITEREMOVE_H
-extern char *RewriteGetRuleEventRel(char *rulename);
-extern void RemoveRewriteRule(char *ruleName);
-extern void RelationRemoveRules(Oid relid);
+extern char *RewriteGetRuleEventRel(char *rulename);
+extern void RemoveRewriteRule(char *ruleName);
+extern void RelationRemoveRules(Oid relid);
-#endif /* REWRITEREMOVE_H */
+#endif /* REWRITEREMOVE_H */
diff --git a/src/include/rewrite/rewriteSupport.h b/src/include/rewrite/rewriteSupport.h
index 36d03f6a61b..7f517ae4ccd 100644
--- a/src/include/rewrite/rewriteSupport.h
+++ b/src/include/rewrite/rewriteSupport.h
@@ -1,26 +1,26 @@
/*-------------------------------------------------------------------------
*
* rewriteSupport.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rewriteSupport.h,v 1.2 1996/11/06 10:31:02 scrappy Exp $
+ * $Id: rewriteSupport.h,v 1.3 1997/09/07 05:00:38 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef REWRITESUPPORT_H
-#define REWRITESUPPORT_H
-
+#ifndef REWRITESUPPORT_H
+#define REWRITESUPPORT_H
-extern int IsDefinedRewriteRule(char *ruleName);
-extern void prs2_addToRelation(Oid relid, Oid ruleId, CmdType event_type,
- AttrNumber attno, bool isInstead, Node *qual,
- List *actions);
-extern void prs2_deleteFromRelation(Oid relid, Oid ruleId);
+extern int IsDefinedRewriteRule(char *ruleName);
+extern void
+prs2_addToRelation(Oid relid, Oid ruleId, CmdType event_type,
+ AttrNumber attno, bool isInstead, Node * qual,
+ List * actions);
+extern void prs2_deleteFromRelation(Oid relid, Oid ruleId);
-#endif /* REWRITESUPPORT_H */
+#endif /* REWRITESUPPORT_H */
diff --git a/src/include/storage/backendid.h b/src/include/storage/backendid.h
index c631d9c38ce..5abdd770e8c 100644
--- a/src/include/storage/backendid.h
+++ b/src/include/storage/backendid.h
@@ -1,31 +1,32 @@
/*-------------------------------------------------------------------------
*
* backendid.h--
- * POSTGRES backend id communication definitions
+ * POSTGRES backend id communication definitions
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: backendid.h,v 1.2 1996/11/05 06:10:52 scrappy Exp $
+ * $Id: backendid.h,v 1.3 1997/09/07 05:00:40 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef BACKENDID_H
+#ifndef BACKENDID_H
#define BACKENDID_H
/* ----------------
- * -cim 8/17/90
+ * -cim 8/17/90
* ----------------
*/
-typedef int16 BackendId; /* unique currently active backend identifier */
+typedef int16 BackendId; /* unique currently active backend
+ * identifier */
-#define InvalidBackendId (-1)
+#define InvalidBackendId (-1)
-typedef int32 BackendTag; /* unique backend identifier */
+typedef int32 BackendTag; /* unique backend identifier */
-#define InvalidBackendTag (-1)
+#define InvalidBackendTag (-1)
-extern BackendId MyBackendId; /* backend id of this backend */
-extern BackendTag MyBackendTag; /* backend tag of this backend */
+extern BackendId MyBackendId; /* backend id of this backend */
+extern BackendTag MyBackendTag; /* backend tag of this backend */
-#endif /* BACKENDID_H */
+#endif /* BACKENDID_H */
diff --git a/src/include/storage/block.h b/src/include/storage/block.h
index 993d7f8257e..9702b53e2eb 100644
--- a/src/include/storage/block.h
+++ b/src/include/storage/block.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* block.h--
- * POSTGRES disk block definitions.
+ * POSTGRES disk block definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: block.h,v 1.2 1996/10/31 09:49:40 scrappy Exp $
+ * $Id: block.h,v 1.3 1997/09/07 05:00:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef BLOCK_H
+#ifndef BLOCK_H
#define BLOCK_H
/*
@@ -29,12 +29,12 @@
*/
typedef uint32 BlockNumber;
-#define InvalidBlockNumber ((BlockNumber) 0xFFFFFFFF)
+#define InvalidBlockNumber ((BlockNumber) 0xFFFFFFFF)
/*
* BlockId:
*
- * this is a storage type for BlockNumber. in other words, this type
+ * this is a storage type for BlockNumber. in other words, this type
* is used for on-disk structures (e.g., in HeapTupleData) whereas
* BlockNumber is the type on which calculations are performed (e.g.,
* in access method code).
@@ -47,66 +47,67 @@ typedef uint32 BlockNumber;
* page and the header of each heap or index tuple, so it doesn't seem
* wise to change this without good reason.
*/
-typedef struct BlockIdData {
- uint16 bi_hi;
- uint16 bi_lo;
-} BlockIdData;
+typedef struct BlockIdData
+{
+ uint16 bi_hi;
+ uint16 bi_lo;
+} BlockIdData;
-typedef BlockIdData *BlockId; /* block identifier */
+typedef BlockIdData *BlockId; /* block identifier */
/* ----------------
- * support macros
+ * support macros
* ----------------
*/
/*
* BlockNumberIsValid --
- * True iff blockNumber is valid.
+ * True iff blockNumber is valid.
*/
#define BlockNumberIsValid(blockNumber) \
- ((bool) ((int32) (blockNumber) != InvalidBlockNumber))
+ ((bool) ((int32) (blockNumber) != InvalidBlockNumber))
/*
* BlockIdIsValid --
- * True iff the block identifier is valid.
+ * True iff the block identifier is valid.
*/
#define BlockIdIsValid(blockId) \
- ((bool) PointerIsValid(blockId))
+ ((bool) PointerIsValid(blockId))
/*
* BlockIdSet --
- * Sets a block identifier to the specified value.
+ * Sets a block identifier to the specified value.
*/
#define BlockIdSet(blockId, blockNumber) \
- Assert(PointerIsValid(blockId)); \
- (blockId)->bi_hi = (blockNumber) >> 16; \
- (blockId)->bi_lo = (blockNumber) & 0xffff
+ Assert(PointerIsValid(blockId)); \
+ (blockId)->bi_hi = (blockNumber) >> 16; \
+ (blockId)->bi_lo = (blockNumber) & 0xffff
/*
* BlockIdCopy --
- * Copy a block identifier.
+ * Copy a block identifier.
*/
#define BlockIdCopy(toBlockId, fromBlockId) \
- Assert(PointerIsValid(toBlockId)); \
- Assert(PointerIsValid(fromBlockId)); \
- (toBlockId)->bi_hi = (fromBlockId)->bi_hi; \
- (toBlockId)->bi_lo = (fromBlockId)->bi_lo
+ Assert(PointerIsValid(toBlockId)); \
+ Assert(PointerIsValid(fromBlockId)); \
+ (toBlockId)->bi_hi = (fromBlockId)->bi_hi; \
+ (toBlockId)->bi_lo = (fromBlockId)->bi_lo
/*
* BlockIdEquals --
- * Check for block number equality.
+ * Check for block number equality.
*/
#define BlockIdEquals(blockId1, blockId2) \
- ((blockId1)->bi_hi == (blockId2)->bi_hi && \
- (blockId1)->bi_lo == (blockId2)->bi_lo)
+ ((blockId1)->bi_hi == (blockId2)->bi_hi && \
+ (blockId1)->bi_lo == (blockId2)->bi_lo)
/*
* BlockIdGetBlockNumber --
- * Retrieve the block number from a block identifier.
+ * Retrieve the block number from a block identifier.
*/
#define BlockIdGetBlockNumber(blockId) \
- (AssertMacro(BlockIdIsValid(blockId)) ? \
- (BlockNumber) (((blockId)->bi_hi << 16) | ((uint16) (blockId)->bi_lo)) : \
- (BlockNumber) InvalidBlockNumber)
+ (AssertMacro(BlockIdIsValid(blockId)) ? \
+ (BlockNumber) (((blockId)->bi_hi << 16) | ((uint16) (blockId)->bi_lo)) : \
+ (BlockNumber) InvalidBlockNumber)
-#endif /* BLOCK_H */
+#endif /* BLOCK_H */
diff --git a/src/include/storage/buf.h b/src/include/storage/buf.h
index 439cb58ec9b..481033c4a73 100644
--- a/src/include/storage/buf.h
+++ b/src/include/storage/buf.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* buf.h--
- * Basic buffer manager data types.
+ * Basic buffer manager data types.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: buf.h,v 1.1 1996/08/28 01:57:57 scrappy Exp $
+ * $Id: buf.h,v 1.2 1997/09/07 05:00:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef BUF_H
+#ifndef BUF_H
#define BUF_H
#define InvalidBuffer (0)
@@ -20,28 +20,28 @@ typedef long Buffer;
/*
* BufferIsInvalid --
- * True iff the buffer is invalid.
+ * True iff the buffer is invalid.
*/
-#define BufferIsInvalid(buffer) ((buffer) == InvalidBuffer)
+#define BufferIsInvalid(buffer) ((buffer) == InvalidBuffer)
/*
* BufferIsUnknown --
- * True iff the buffer is unknown.
+ * True iff the buffer is unknown.
*/
-#define BufferIsUnknown(buffer) ((buffer) == UnknownBuffer)
+#define BufferIsUnknown(buffer) ((buffer) == UnknownBuffer)
/*
* BufferIsLocal --
- * True iff the buffer is local (not visible to other servers).
+ * True iff the buffer is local (not visible to other servers).
*/
#define BufferIsLocal(buffer) ((buffer) < 0)
/*
* If NO_BUFFERISVALID is defined, all error checking using BufferIsValid()
- * are suppressed. Decision-making using BufferIsValid is not affected.
+ * are suppressed. Decision-making using BufferIsValid is not affected.
* This should be set only if one is sure there will be no errors.
* - plai 9/10/90
*/
#undef NO_BUFFERISVALID
-#endif /* BUF_H */
+#endif /* BUF_H */
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index 24d22bd9c9a..aea48e15cb1 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -1,20 +1,20 @@
/*-------------------------------------------------------------------------
*
* buf_internals.h--
- * Internal definitions.
+ * Internal definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: buf_internals.h,v 1.14 1997/08/19 21:39:41 momjian Exp $
+ * $Id: buf_internals.h,v 1.15 1997/09/07 05:00:52 momjian Exp $
*
* NOTE
- * If BUFFERPAGE0 is defined, then 0 will be used as a
- * valid buffer page number.
+ * If BUFFERPAGE0 is defined, then 0 will be used as a
+ * valid buffer page number.
*
*-------------------------------------------------------------------------
*/
-#ifndef BUFMGR_INTERNALS_H
+#ifndef BUFMGR_INTERNALS_H
#define BUFMGR_INTERNALS_H
#include <storage/lmgr.h>
@@ -22,35 +22,37 @@
/* Buf Mgr constants */
/* in bufmgr.c */
-extern int NBuffers;
-extern int Data_Descriptors;
-extern int Free_List_Descriptor;
-extern int Lookup_List_Descriptor;
-extern int Num_Descriptors;
+extern int NBuffers;
+extern int Data_Descriptors;
+extern int Free_List_Descriptor;
+extern int Lookup_List_Descriptor;
+extern int Num_Descriptors;
/*
* Flags for buffer descriptors
*/
-#define BM_DIRTY (1 << 0)
-#define BM_PRIVATE (1 << 1)
-#define BM_VALID (1 << 2)
-#define BM_DELETED (1 << 3)
-#define BM_FREE (1 << 4)
-#define BM_IO_IN_PROGRESS (1 << 5)
-#define BM_IO_ERROR (1 << 6)
-#define BM_JUST_DIRTIED (1 << 7)
+#define BM_DIRTY (1 << 0)
+#define BM_PRIVATE (1 << 1)
+#define BM_VALID (1 << 2)
+#define BM_DELETED (1 << 3)
+#define BM_FREE (1 << 4)
+#define BM_IO_IN_PROGRESS (1 << 5)
+#define BM_IO_ERROR (1 << 6)
+#define BM_JUST_DIRTIED (1 << 7)
-typedef bits16 BufFlags;
+typedef bits16 BufFlags;
typedef struct sbufdesc BufferDesc;
typedef struct sbufdesc BufferHdr;
typedef struct buftag BufferTag;
+
/* long * so alignment will be correct */
-typedef long **BufferBlock;
+typedef long **BufferBlock;
-struct buftag{
- LRelId relId;
- BlockNumber blockNum; /* blknum relative to begin of reln */
+struct buftag
+{
+ LRelId relId;
+ BlockNumber blockNum; /* blknum relative to begin of reln */
};
#define CLEAR_BUFFERTAG(a)\
@@ -79,154 +81,162 @@ struct buftag{
#define INVALID_DESCRIPTOR (-3)
/*
- * bletch hack -- anyplace that we declare space for relation or
- * database names, we just use '16', not a symbolic constant, to
- * specify their lengths. BM_NAMESIZE is the length of these names,
- * and is used in the buffer manager code. somebody with lots of
- * spare time should do this for all the other modules, too.
+ * bletch hack -- anyplace that we declare space for relation or
+ * database names, we just use '16', not a symbolic constant, to
+ * specify their lengths. BM_NAMESIZE is the length of these names,
+ * and is used in the buffer manager code. somebody with lots of
+ * spare time should do this for all the other modules, too.
*/
-#define BM_NAMESIZE 16
+#define BM_NAMESIZE 16
/*
- * struct sbufdesc -- shared buffer cache metadata for a single
- * shared buffer descriptor.
+ * struct sbufdesc -- shared buffer cache metadata for a single
+ * shared buffer descriptor.
*
- * We keep the name of the database and relation in which this
- * buffer appears in order to avoid a catalog lookup on cache
- * flush if we don't have the reldesc in the cache. It is also
- * possible that the relation to which this buffer belongs is
- * not visible to all backends at the time that it gets flushed.
- * Dbname, relname, dbid, and relid are enough to determine where
- * to put the buffer, for all storage managers.
+ * We keep the name of the database and relation in which this
+ * buffer appears in order to avoid a catalog lookup on cache
+ * flush if we don't have the reldesc in the cache. It is also
+ * possible that the relation to which this buffer belongs is
+ * not visible to all backends at the time that it gets flushed.
+ * Dbname, relname, dbid, and relid are enough to determine where
+ * to put the buffer, for all storage managers.
*/
-#define PADDED_SBUFDESC_SIZE 128
+#define PADDED_SBUFDESC_SIZE 128
/* DO NOT CHANGE THIS NEXT STRUCTURE:
It is used only to get padding information for the real sbufdesc structure
It should match the sbufdesc structure exactly except for a missing sb_pad
*/
-struct sbufdesc_unpadded {
- Buffer freeNext;
- Buffer freePrev;
- SHMEM_OFFSET data;
- BufferTag tag;
- int buf_id;
- BufFlags flags;
- int16 bufsmgr;
- unsigned refcount;
+struct sbufdesc_unpadded
+{
+ Buffer freeNext;
+ Buffer freePrev;
+ SHMEM_OFFSET data;
+ BufferTag tag;
+ int buf_id;
+ BufFlags flags;
+ int16 bufsmgr;
+ unsigned refcount;
#ifdef HAS_TEST_AND_SET
- slock_t io_in_progress_lock;
-#endif /* HAS_TEST_AND_SET */
- char sb_dbname[NAMEDATALEN];
+ slock_t io_in_progress_lock;
+#endif /* HAS_TEST_AND_SET */
+ char sb_dbname[NAMEDATALEN];
- /* NOTE NO PADDING OF THE MEMBER HERE */
- char sb_relname[NAMEDATALEN];
+ /* NOTE NO PADDING OF THE MEMBER HERE */
+ char sb_relname[NAMEDATALEN];
};
/* THE REAL STRUCTURE - the structure above must match it, minus sb_pad */
-struct sbufdesc {
- Buffer freeNext; /* link for freelist chain */
- Buffer freePrev;
- SHMEM_OFFSET data; /* pointer to data in buf pool */
+struct sbufdesc
+{
+ Buffer freeNext; /* link for freelist chain */
+ Buffer freePrev;
+ SHMEM_OFFSET data; /* pointer to data in buf pool */
- /* tag and id must be together for table lookup to work */
- BufferTag tag; /* file/block identifier */
- int buf_id; /* maps global desc to local desc */
+ /* tag and id must be together for table lookup to work */
+ BufferTag tag; /* file/block identifier */
+ int buf_id; /* maps global desc to local desc */
- BufFlags flags; /* described below */
- int16 bufsmgr; /* storage manager id for buffer */
- unsigned refcount; /* # of times buffer is pinned */
+ BufFlags flags; /* described below */
+ int16 bufsmgr; /* storage manager id for buffer */
+ unsigned refcount; /* # of times buffer is pinned */
#ifdef HAS_TEST_AND_SET
- /* can afford a dedicated lock if test-and-set locks are available */
- slock_t io_in_progress_lock;
-#endif /* HAS_TEST_AND_SET */
-
- char sb_dbname[NAMEDATALEN]; /* name of db in which buf belongs */
-
- /*
- * I padded this structure to a power of 2 (PADDED_SBUFDESC_SIZE) because
- * BufferDescriptorGetBuffer is called a billion times and it does an
- * C pointer subtraction (i.e., "x - y" -> array index of x relative
- * to y, which is calculated using division by struct size). Integer
- * ".div" hits you for 35 cycles, as opposed to a 1-cycle "sra" ...
- * this hack cut 10% off of the time to create the Wisconsin database!
- * It eats up more shared memory, of course, but we're (allegedly)
- * going to make some of these types bigger soon anyway... -pma 1/2/93
- */
-
- /* please, don't take the sizeof() this member and use it for
- something important */
-
- char sb_relname[NAMEDATALEN+ /* name of reln */
- PADDED_SBUFDESC_SIZE-sizeof(struct sbufdesc_unpadded)];
+ /* can afford a dedicated lock if test-and-set locks are available */
+ slock_t io_in_progress_lock;
+#endif /* HAS_TEST_AND_SET */
+
+ char sb_dbname[NAMEDATALEN]; /* name of db in which buf
+ * belongs */
+
+ /*
+ * I padded this structure to a power of 2 (PADDED_SBUFDESC_SIZE)
+ * because BufferDescriptorGetBuffer is called a billion times and it
+ * does an C pointer subtraction (i.e., "x - y" -> array index of x
+ * relative to y, which is calculated using division by struct size).
+ * Integer ".div" hits you for 35 cycles, as opposed to a 1-cycle
+ * "sra" ... this hack cut 10% off of the time to create the Wisconsin
+ * database! It eats up more shared memory, of course, but we're
+ * (allegedly) going to make some of these types bigger soon anyway...
+ * -pma 1/2/93
+ */
+
+ /*
+ * please, don't take the sizeof() this member and use it for
+ * something important
+ */
+
+ char sb_relname[NAMEDATALEN + /* name of reln */
+ PADDED_SBUFDESC_SIZE - sizeof(struct sbufdesc_unpadded)];
};
/*
- * mao tracing buffer allocation
+ * mao tracing buffer allocation
*/
/*#define BMTRACE*/
#ifdef BMTRACE
-typedef struct _bmtrace {
- int bmt_pid;
- long bmt_buf;
- long bmt_dbid;
- long bmt_relid;
- int bmt_blkno;
- int bmt_op;
+typedef struct _bmtrace
+{
+ int bmt_pid;
+ long bmt_buf;
+ long bmt_dbid;
+ long bmt_relid;
+ int bmt_blkno;
+ int bmt_op;
-#define BMT_NOTUSED 0
+#define BMT_NOTUSED 0
#define BMT_ALLOCFND 1
-#define BMT_ALLOCNOTFND 2
-#define BMT_DEALLOC 3
+#define BMT_ALLOCNOTFND 2
+#define BMT_DEALLOC 3
-} bmtrace;
+} bmtrace;
-#endif /* BMTRACE */
+#endif /* BMTRACE */
-/*
+/*
* Bufmgr Interface:
*/
/* Internal routines: only called by buf.c */
/*freelist.c*/
-extern void AddBufferToFreelist(BufferDesc *bf);
-extern void PinBuffer(BufferDesc *buf);
-extern void PinBuffer_Debug(char *file, int line, BufferDesc *buf);
-extern void UnpinBuffer(BufferDesc *buf);
+extern void AddBufferToFreelist(BufferDesc * bf);
+extern void PinBuffer(BufferDesc * buf);
+extern void PinBuffer_Debug(char *file, int line, BufferDesc * buf);
+extern void UnpinBuffer(BufferDesc * buf);
extern BufferDesc *GetFreeBuffer(void);
-extern void InitFreeList(bool init);
+extern void InitFreeList(bool init);
/* buf_table.c */
-extern void InitBufTable(void);
-extern BufferDesc *BufTableLookup(BufferTag *tagPtr);
-extern bool BufTableDelete(BufferDesc *buf);
-extern bool BufTableInsert(BufferDesc *buf);
+extern void InitBufTable(void);
+extern BufferDesc *BufTableLookup(BufferTag * tagPtr);
+extern bool BufTableDelete(BufferDesc * buf);
+extern bool BufTableInsert(BufferDesc * buf);
/* bufmgr.c */
-extern BufferDesc *BufferDescriptors;
-extern BufferBlock BufferBlocks;
-extern long *PrivateRefCount;
-extern long *LastRefCount;
-extern long *CommitInfoNeedsSave;
-extern SPINLOCK BufMgrLock;
+extern BufferDesc *BufferDescriptors;
+extern BufferBlock BufferBlocks;
+extern long *PrivateRefCount;
+extern long *LastRefCount;
+extern long *CommitInfoNeedsSave;
+extern SPINLOCK BufMgrLock;
/* localbuf.c */
-extern long *LocalRefCount;
+extern long *LocalRefCount;
extern BufferDesc *LocalBufferDescriptors;
-extern int NLocBuffer;
-
-extern BufferDesc *LocalBufferAlloc(Relation reln, BlockNumber blockNum,
- bool *foundPtr);
-extern int WriteLocalBuffer(Buffer buffer, bool release);
-extern int FlushLocalBuffer(Buffer buffer, bool release);
-extern void InitLocalBuffer(void);
-extern void LocalBufferSync(void);
-extern void ResetLocalBufferPool(void);
-
-#endif /* BUFMGR_INTERNALS_H */
+extern int NLocBuffer;
+
+extern BufferDesc *
+LocalBufferAlloc(Relation reln, BlockNumber blockNum,
+ bool * foundPtr);
+extern int WriteLocalBuffer(Buffer buffer, bool release);
+extern int FlushLocalBuffer(Buffer buffer, bool release);
+extern void InitLocalBuffer(void);
+extern void LocalBufferSync(void);
+extern void ResetLocalBufferPool(void);
+
+#endif /* BUFMGR_INTERNALS_H */
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index c0ec42ddb83..d432506c7cb 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* bufmgr.h--
- * POSTGRES buffer manager definitions.
+ * POSTGRES buffer manager definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: bufmgr.h,v 1.11 1997/08/19 21:39:45 momjian Exp $
+ * $Id: bufmgr.h,v 1.12 1997/09/07 05:01:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef BUFMGR_H
+#ifndef BUFMGR_H
#define BUFMGR_H
#include <stdio.h>
@@ -27,13 +27,13 @@
* limited to 2^13 bytes because we have limited ItemIdData.lp_off and
* ItemIdData.lp_len to 13 bits (see itemid.h).
*/
-#define MAXBLCKSZ 8192
+#define MAXBLCKSZ 8192
-typedef void *Block;
+typedef void *Block;
/* special pageno for bget */
-#define P_NEW InvalidBlockNumber /* grow the file to get a new page */
+#define P_NEW InvalidBlockNumber /* grow the file to get a new page */
typedef bits16 BufferLock;
@@ -51,57 +51,58 @@ typedef bits16 BufferLock;
/*
* BufferIsPinned --
- * True iff the buffer is pinned (and therefore valid)
+ * True iff the buffer is pinned (and therefore valid)
*
* Note:
- * Smenatics are identical to BufferIsValid
- * XXX - need to remove either one eventually.
+ * Smenatics are identical to BufferIsValid
+ * XXX - need to remove either one eventually.
*/
#define BufferIsPinned BufferIsValid
-extern int ShowPinTrace;
+extern int ShowPinTrace;
/*
* BufferWriteModes (settable via SetBufferWriteMode)
*/
-#define BUFFER_FLUSH_WRITE 0 /* immediate write */
-#define BUFFER_LATE_WRITE 1 /* delayed write: mark as DIRTY */
+#define BUFFER_FLUSH_WRITE 0 /* immediate write */
+#define BUFFER_LATE_WRITE 1 /* delayed write: mark as DIRTY */
/*
- * prototypes for functions in bufmgr.c
+ * prototypes for functions in bufmgr.c
*/
-extern Buffer RelationGetBufferWithBuffer(Relation relation,
- BlockNumber blockNumber, Buffer buffer);
-extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
-extern int WriteBuffer(Buffer buffer);
-extern int WriteNoReleaseBuffer(Buffer buffer);
-extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
- BlockNumber blockNum);
-
-extern void InitBufferPool(IPCKey key);
-extern void PrintBufferUsage(FILE *statfp);
-extern void ResetBufferUsage(void);
-extern void ResetBufferPool(void);
-extern int BufferPoolCheckLeak(void);
-extern void FlushBufferPool(int StableMainMemoryFlag);
-extern bool BufferIsValid(Buffer bufnum);
+extern Buffer
+RelationGetBufferWithBuffer(Relation relation,
+ BlockNumber blockNumber, Buffer buffer);
+extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
+extern int WriteBuffer(Buffer buffer);
+extern int WriteNoReleaseBuffer(Buffer buffer);
+extern Buffer
+ReleaseAndReadBuffer(Buffer buffer, Relation relation,
+ BlockNumber blockNum);
+
+extern void InitBufferPool(IPCKey key);
+extern void PrintBufferUsage(FILE * statfp);
+extern void ResetBufferUsage(void);
+extern void ResetBufferPool(void);
+extern int BufferPoolCheckLeak(void);
+extern void FlushBufferPool(int StableMainMemoryFlag);
+extern bool BufferIsValid(Buffer bufnum);
extern BlockNumber BufferGetBlockNumber(Buffer buffer);
extern Relation BufferGetRelation(Buffer buffer);
extern BlockNumber RelationGetNumberOfBlocks(Relation relation);
-extern Block BufferGetBlock(Buffer buffer);
-extern void ReleaseRelationBuffers(Relation rdesc);
-extern void DropBuffers(Oid dbid);
-extern void PrintBufferDescs(void);
-extern void PrintPinnedBufs(void);
-extern int BufferShmemSize(void);
-extern void IncrBufferRefCount(Buffer buffer);
-extern int ReleaseBuffer(Buffer buffer);
-
-extern void BufferRefCountReset(int *refcountsave);
-extern void BufferRefCountRestore(int *refcountsave);
-extern int SetBufferWriteMode (int mode);
-extern void SetBufferCommitInfoNeedsSave(Buffer buffer);
-
-#endif /* !defined(BufMgrIncluded) */
-
+extern Block BufferGetBlock(Buffer buffer);
+extern void ReleaseRelationBuffers(Relation rdesc);
+extern void DropBuffers(Oid dbid);
+extern void PrintBufferDescs(void);
+extern void PrintPinnedBufs(void);
+extern int BufferShmemSize(void);
+extern void IncrBufferRefCount(Buffer buffer);
+extern int ReleaseBuffer(Buffer buffer);
+
+extern void BufferRefCountReset(int *refcountsave);
+extern void BufferRefCountRestore(int *refcountsave);
+extern int SetBufferWriteMode(int mode);
+extern void SetBufferCommitInfoNeedsSave(Buffer buffer);
+
+#endif /* !defined(BufMgrIncluded) */
diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h
index 3607e4e25e2..a252ccc3e44 100644
--- a/src/include/storage/bufpage.h
+++ b/src/include/storage/bufpage.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* bufpage.h--
- * Standard POSTGRES buffer page definitions.
+ * Standard POSTGRES buffer page definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: bufpage.h,v 1.10 1997/08/26 23:31:58 momjian Exp $
+ * $Id: bufpage.h,v 1.11 1997/09/07 05:01:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef BUFPAGE_H
+#ifndef BUFPAGE_H
#define BUFPAGE_H
#include <storage/off.h>
@@ -27,19 +27,19 @@
* disk page is always a slotted page of the form:
*
* +----------------+---------------------------------+
- * | PageHeaderData | linp0 linp1 linp2 ... |
+ * | PageHeaderData | linp0 linp1 linp2 ... |
* +-----------+----+---------------------------------+
- * | ... linpN | |
+ * | ... linpN | |
* +-----------+--------------------------------------+
- * | ^ pd_lower |
- * | |
- * | v pd_upper |
+ * | ^ pd_lower |
+ * | |
+ * | v pd_upper |
* +-------------+------------------------------------+
- * | | tupleN ... |
+ * | | tupleN ... |
* +-------------+------------------+-----------------+
- * | ... tuple2 tuple1 tuple0 | "special space" |
+ * | ... tuple2 tuple1 tuple0 | "special space" |
* +--------------------------------+-----------------+
- * ^ pd_special
+ * ^ pd_special
*
* a page is full when nothing can be added between pd_lower and
* pd_upper.
@@ -66,19 +66,19 @@
* whenever the need arises.
*
* AM-generic per-page information is kept in the pd_opaque field of
- * the PageHeaderData. (this is currently only the page size.)
+ * the PageHeaderData. (this is currently only the page size.)
* AM-specific per-page data is kept in the area marked "special
* space"; each AM has an "opaque" structure defined somewhere that is
- * stored as the page trailer. an access method should always
+ * stored as the page trailer. an access method should always
* initialize its pages with PageInit and then set its own opaque
* fields.
*/
/*
* PageIsValid --
- * True iff page is valid.
+ * True iff page is valid.
*/
-#define PageIsValid(page) PointerIsValid(page)
+#define PageIsValid(page) PointerIsValid(page)
/*
@@ -93,39 +93,42 @@ typedef uint16 LocationIndex;
/*
* space management information generic to any page
*
- * od_pagesize - size in bytes.
- * in reality, we need at least 64B to fit the
- * page header, opaque space and a minimal tuple;
- * on the high end, we can only support pages up
- * to 8KB because lp_off/lp_len are 13 bits.
+ * od_pagesize - size in bytes.
+ * in reality, we need at least 64B to fit the
+ * page header, opaque space and a minimal tuple;
+ * on the high end, we can only support pages up
+ * to 8KB because lp_off/lp_len are 13 bits.
*/
-typedef struct OpaqueData {
- uint16 od_pagesize;
-} OpaqueData;
-
-typedef OpaqueData *Opaque;
+typedef struct OpaqueData
+{
+ uint16 od_pagesize;
+} OpaqueData;
+
+typedef OpaqueData *Opaque;
/*
* disk page organization
*/
-typedef struct PageHeaderData {
- LocationIndex pd_lower; /* offset to start of free space */
- LocationIndex pd_upper; /* offset to end of free space */
- LocationIndex pd_special; /* offset to start of special space */
- OpaqueData pd_opaque; /* AM-generic information */
- ItemIdData pd_linp[1]; /* line pointers */
-} PageHeaderData;
-
-typedef PageHeaderData *PageHeader;
-
-typedef enum {
- ShufflePageManagerMode,
- OverwritePageManagerMode
-} PageManagerMode;
+typedef struct PageHeaderData
+{
+ LocationIndex pd_lower; /* offset to start of free space */
+ LocationIndex pd_upper; /* offset to end of free space */
+ LocationIndex pd_special; /* offset to start of special space */
+ OpaqueData pd_opaque; /* AM-generic information */
+ ItemIdData pd_linp[1]; /* line pointers */
+} PageHeaderData;
+
+typedef PageHeaderData *PageHeader;
+
+typedef enum
+{
+ ShufflePageManagerMode,
+ OverwritePageManagerMode
+} PageManagerMode;
/* ----------------
- * misc support macros
+ * misc support macros
* ----------------
*/
@@ -134,10 +137,10 @@ typedef enum {
* AM-specific opaque space at the end of the page (as in btrees), ...
* however, it at least serves as an upper bound for heap pages.
*/
-#define MAXTUPLEN (BLCKSZ - sizeof (PageHeaderData))
+#define MAXTUPLEN (BLCKSZ - sizeof (PageHeaderData))
/* ----------------------------------------------------------------
- * page support macros
+ * page support macros
* ----------------------------------------------------------------
*/
/*
@@ -146,146 +149,147 @@ typedef enum {
/*
* PageIsUsed --
- * True iff the page size is used.
+ * True iff the page size is used.
*
* Note:
- * Assumes page is valid.
+ * Assumes page is valid.
*/
#define PageIsUsed(page) \
- (AssertMacro(PageIsValid(page)) ? \
- ((bool) (((PageHeader) (page))->pd_lower != 0)) : false)
+ (AssertMacro(PageIsValid(page)) ? \
+ ((bool) (((PageHeader) (page))->pd_lower != 0)) : false)
/*
* PageIsEmpty --
- * returns true iff no itemid has been allocated on the page
+ * returns true iff no itemid has been allocated on the page
*/
#define PageIsEmpty(page) \
- (((PageHeader) (page))->pd_lower == \
- (sizeof(PageHeaderData) - sizeof(ItemIdData)) ? true : false)
+ (((PageHeader) (page))->pd_lower == \
+ (sizeof(PageHeaderData) - sizeof(ItemIdData)) ? true : false)
/*
- * PageIsNew --
- * returns true iff page is not initialized (by PageInit)
+ * PageIsNew --
+ * returns true iff page is not initialized (by PageInit)
*/
-#define PageIsNew(page) (((PageHeader) (page))->pd_upper == 0)
+#define PageIsNew(page) (((PageHeader) (page))->pd_upper == 0)
/*
* PageGetItemId --
- * Returns an item identifier of a page.
+ * Returns an item identifier of a page.
*/
#define PageGetItemId(page, offsetNumber) \
- ((ItemId) (&((PageHeader) (page))->pd_linp[(-1) + (offsetNumber)]))
+ ((ItemId) (&((PageHeader) (page))->pd_linp[(-1) + (offsetNumber)]))
/* ----------------
- * macros to access opaque space
+ * macros to access opaque space
* ----------------
*/
/*
* PageSizeIsValid --
- * True iff the page size is valid.
+ * True iff the page size is valid.
*
* XXX currently all page sizes are "valid" but we only actually
- * use BLCKSZ.
+ * use BLCKSZ.
*/
#define PageSizeIsValid(pageSize) 1
/*
* PageGetPageSize --
- * Returns the page size of a page.
+ * Returns the page size of a page.
*
* this can only be called on a formatted page (unlike
* BufferGetPageSize, which can be called on an unformatted page).
* however, it can be called on a page for which there is no buffer.
*/
#define PageGetPageSize(page) \
- ((Size) ((PageHeader) (page))->pd_opaque.od_pagesize)
+ ((Size) ((PageHeader) (page))->pd_opaque.od_pagesize)
/*
* PageSetPageSize --
- * Sets the page size of a page.
+ * Sets the page size of a page.
*/
#define PageSetPageSize(page, size) \
- ((PageHeader) (page))->pd_opaque.od_pagesize = (size)
+ ((PageHeader) (page))->pd_opaque.od_pagesize = (size)
/* ----------------
- * page special data macros
+ * page special data macros
* ----------------
*/
/*
* PageGetSpecialSize --
- * Returns size of special space on a page.
+ * Returns size of special space on a page.
*
* Note:
- * Assumes page is locked.
+ * Assumes page is locked.
*/
#define PageGetSpecialSize(page) \
- ((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special))
+ ((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special))
/*
* PageGetSpecialPointer --
- * Returns pointer to special space on a page.
+ * Returns pointer to special space on a page.
*
* Note:
- * Assumes page is locked.
+ * Assumes page is locked.
*/
#define PageGetSpecialPointer(page) \
- (AssertMacro(PageIsValid(page)) ? \
- (char *) ((char *) (page) + ((PageHeader) (page))->pd_special) \
- : (char *)0 )
+ (AssertMacro(PageIsValid(page)) ? \
+ (char *) ((char *) (page) + ((PageHeader) (page))->pd_special) \
+ : (char *)0 )
/*
* PageGetItem --
- * Retrieves an item on the given page.
+ * Retrieves an item on the given page.
*
* Note:
- * This does change the status of any of the resources passed.
- * The semantics may change in the future.
+ * This does change the status of any of the resources passed.
+ * The semantics may change in the future.
*/
#define PageGetItem(page, itemId) \
- (AssertMacro(PageIsValid(page)) ? \
- AssertMacro((itemId)->lp_flags & LP_USED) ? \
- (Item)(((char *)(page)) + (itemId)->lp_off) : false : false)
+ (AssertMacro(PageIsValid(page)) ? \
+ AssertMacro((itemId)->lp_flags & LP_USED) ? \
+ (Item)(((char *)(page)) + (itemId)->lp_off) : false : false)
/*
* BufferGetPageSize --
- * Returns the page size within a buffer.
+ * Returns the page size within a buffer.
*
* Notes:
- * Assumes buffer is valid.
+ * Assumes buffer is valid.
*
- * The buffer can be a raw disk block and need not contain a valid
- * (formatted) disk page.
+ * The buffer can be a raw disk block and need not contain a valid
+ * (formatted) disk page.
*/
/* XXX dig out of buffer descriptor */
#define BufferGetPageSize(buffer) \
- (AssertMacro(BufferIsValid(buffer)) ? \
- AssertMacro(PageSizeIsValid(pageSize)) ? \
- ((Size)BLCKSZ) : false : false)
+ (AssertMacro(BufferIsValid(buffer)) ? \
+ AssertMacro(PageSizeIsValid(pageSize)) ? \
+ ((Size)BLCKSZ) : false : false)
/*
* BufferGetPage --
- * Returns the page associated with a buffer.
+ * Returns the page associated with a buffer.
*/
#define BufferGetPage(buffer) ((Page)BufferGetBlock(buffer))
-
+
/* ----------------------------------------------------------------
- * extern declarations
+ * extern declarations
* ----------------------------------------------------------------
*/
-extern void PageInit(Page page, Size pageSize, Size specialSize);
-extern OffsetNumber PageAddItem(Page page, Item item, Size size,
- OffsetNumber offsetNumber, ItemIdFlags flags);
-extern Page PageGetTempPage(Page page, Size specialSize);
-extern void PageRestoreTempPage(Page tempPage, Page oldPage);
+extern void PageInit(Page page, Size pageSize, Size specialSize);
+extern OffsetNumber
+PageAddItem(Page page, Item item, Size size,
+ OffsetNumber offsetNumber, ItemIdFlags flags);
+extern Page PageGetTempPage(Page page, Size specialSize);
+extern void PageRestoreTempPage(Page tempPage, Page oldPage);
extern OffsetNumber PageGetMaxOffsetNumber(Page page);
-extern void PageRepairFragmentation(Page page);
-extern Size PageGetFreeSpace(Page page);
-extern void PageManagerModeSet(PageManagerMode mode);
-extern void PageIndexTupleDelete(Page page, OffsetNumber offset);
+extern void PageRepairFragmentation(Page page);
+extern Size PageGetFreeSpace(Page page);
+extern void PageManagerModeSet(PageManagerMode mode);
+extern void PageIndexTupleDelete(Page page, OffsetNumber offset);
-#endif /* BUFPAGE_H */
+#endif /* BUFPAGE_H */
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index bd76109ac0e..9fbe004d4a3 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -1,37 +1,37 @@
/*-------------------------------------------------------------------------
*
* fd.h--
- * Virtual file descriptor definitions.
+ * Virtual file descriptor definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: fd.h,v 1.8 1997/08/19 21:39:48 momjian Exp $
+ * $Id: fd.h,v 1.9 1997/09/07 05:01:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* calls:
- *
- * File {Close, Read, Write, Seek, Tell, Sync}
- * {File Name Open, Allocate, Free} File
+ *
+ * File {Close, Read, Write, Seek, Tell, Sync}
+ * {File Name Open, Allocate, Free} File
*
* These are NOT JUST RENAMINGS OF THE UNIX ROUTINES.
* use them for all file activity...
*
- * fd = FilePathOpenFile("foo", O_RDONLY);
- * File fd;
+ * fd = FilePathOpenFile("foo", O_RDONLY);
+ * File fd;
*
* use AllocateFile if you need a file descriptor in some other context.
* it will make sure that there is a file descriptor free
*
- * use FreeFile to let the virtual file descriptor package know that
+ * use FreeFile to let the virtual file descriptor package know that
* there is now a free fd (when you are done with it)
*
- * AllocateFile();
- * FreeFile();
+ * AllocateFile();
+ * FreeFile();
*/
-#ifndef FD_H
+#ifndef FD_H
#define FD_H
#include <stdio.h>
@@ -42,37 +42,39 @@
typedef char *FileName;
-typedef int File;
+typedef int File;
/* originally in libpq-fs.h */
-struct pgstat { /* just the fields we need from stat structure */
- int st_ino;
- int st_mode;
- unsigned int st_size;
- unsigned int st_sizehigh; /* high order bits */
+struct pgstat
+{ /* just the fields we need from stat
+ * structure */
+ int st_ino;
+ int st_mode;
+ unsigned int st_size;
+ unsigned int st_sizehigh;/* high order bits */
/* 2^64 == 1.8 x 10^20 bytes */
- int st_uid;
- int st_atime_s; /* just the seconds */
- int st_mtime_s; /* since SysV and the new BSD both have */
- int st_ctime_s; /* usec fields.. */
+ int st_uid;
+ int st_atime_s; /* just the seconds */
+ int st_mtime_s; /* since SysV and the new BSD both have */
+ int st_ctime_s; /* usec fields.. */
};
/*
* prototypes for functions in fd.c
*/
-extern File FileNameOpenFile(FileName fileName, int fileFlags, int fileMode);
-extern File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode);
-extern void FileClose(File file);
-extern void FileUnlink(File file);
-extern int FileRead(File file, char *buffer, int amount);
-extern int FileWrite(File file, char *buffer, int amount);
-extern long FileSeek(File file, long offset, int whence);
-extern int FileTruncate(File file, int offset);
-extern int FileSync(File file);
-extern int FileNameUnlink(char *filename);
-extern FILE *AllocateFile(char *name, char *mode);
-extern void FreeFile(FILE *);
-extern void closeAllVfds(void);
-extern int pg_fsync(int fd);
+extern File FileNameOpenFile(FileName fileName, int fileFlags, int fileMode);
+extern File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode);
+extern void FileClose(File file);
+extern void FileUnlink(File file);
+extern int FileRead(File file, char *buffer, int amount);
+extern int FileWrite(File file, char *buffer, int amount);
+extern long FileSeek(File file, long offset, int whence);
+extern int FileTruncate(File file, int offset);
+extern int FileSync(File file);
+extern int FileNameUnlink(char *filename);
+extern FILE *AllocateFile(char *name, char *mode);
+extern void FreeFile(FILE *);
+extern void closeAllVfds(void);
+extern int pg_fsync(int fd);
-#endif /* FD_H */
+#endif /* FD_H */
diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h
index 69f8b2ba862..9e08d6b94ee 100644
--- a/src/include/storage/ipc.h
+++ b/src/include/storage/ipc.h
@@ -1,171 +1,181 @@
/*-------------------------------------------------------------------------
*
* ipc.h--
- * POSTGRES inter-process communication definitions.
+ * POSTGRES inter-process communication definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: ipc.h,v 1.17 1997/08/19 21:39:50 momjian Exp $
+ * $Id: ipc.h,v 1.18 1997/09/07 05:01:14 momjian Exp $
*
* NOTES
- * This file is very architecture-specific. This stuff should actually
- * be factored into the port/ directories.
+ * This file is very architecture-specific. This stuff should actually
+ * be factored into the port/ directories.
*
- * Some files that would normally need to include only sys/ipc.h must
+ * Some files that would normally need to include only sys/ipc.h must
* instead included this file because on Ultrix, sys/ipc.h is not designed
* to be included multiple times. This file (by virtue of the ifndef IPC_H)
* is.
*-------------------------------------------------------------------------
*/
-#ifndef IPC_H
+#ifndef IPC_H
#define IPC_H
#include <sys/types.h>
-#include <sys/ipc.h> /* For IPC_PRIVATE */
+#include <sys/ipc.h> /* For IPC_PRIVATE */
#include <config.h>
#if defined(HAS_TEST_AND_SET)
-extern void S_LOCK(slock_t *lock);
-extern void S_UNLOCK(slock_t *lock);
-extern void S_INIT_LOCK(slock_t *lock);
+extern void S_LOCK(slock_t * lock);
+extern void S_UNLOCK(slock_t * lock);
+extern void S_INIT_LOCK(slock_t * lock);
#if (defined(alpha) && !defined(linuxalpha)) || \
- defined(hpux) || \
- defined(irix5) || \
- defined(nextstep)
-extern int S_LOCK_FREE(slock_t *lock);
+ defined(hpux) || \
+ defined(irix5) || \
+ defined(nextstep)
+extern int S_LOCK_FREE(slock_t * lock);
+
#else
-#define S_LOCK_FREE(lock) ((*lock) == 0)
+#define S_LOCK_FREE(lock) ((*lock) == 0)
#endif
-#endif /* HAS_TEST_AND_SET */
+#endif /* HAS_TEST_AND_SET */
#ifndef HAVE_UNION_SEMUN
-union semun {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
+union semun
+{
+ int val;
+ struct semid_ds *buf;
+ unsigned short *array;
};
+
#endif
typedef uint16 SystemPortAddress;
/* semaphore definitions */
-#define IPCProtection (0600) /* access/modify by user only */
+#define IPCProtection (0600) /* access/modify by user only */
-#define IPC_NMAXSEM 25 /* maximum number of semaphores */
+#define IPC_NMAXSEM 25 /* maximum number of semaphores */
#define IpcSemaphoreDefaultStartValue 255
-#define IpcSharedLock (-1)
-#define IpcExclusiveLock (-255)
+#define IpcSharedLock (-1)
+#define IpcExclusiveLock (-255)
-#define IpcUnknownStatus (-1)
-#define IpcInvalidArgument (-2)
-#define IpcSemIdExist (-3)
-#define IpcSemIdNotExist (-4)
+#define IpcUnknownStatus (-1)
+#define IpcInvalidArgument (-2)
+#define IpcSemIdExist (-3)
+#define IpcSemIdNotExist (-4)
-typedef uint32 IpcSemaphoreKey; /* semaphore key */
-typedef int IpcSemaphoreId;
+typedef uint32 IpcSemaphoreKey;/* semaphore key */
+typedef int IpcSemaphoreId;
-/* shared memory definitions */
+/* shared memory definitions */
#define IpcMemCreationFailed (-1)
-#define IpcMemIdGetFailed (-2)
-#define IpcMemAttachFailed 0
+#define IpcMemIdGetFailed (-2)
+#define IpcMemAttachFailed 0
typedef uint32 IPCKey;
+
#define PrivateIPCKey IPC_PRIVATE
#define DefaultIPCKey 17317
-typedef uint32 IpcMemoryKey; /* shared memory key */
-typedef int IpcMemoryId;
+typedef uint32 IpcMemoryKey; /* shared memory key */
+typedef int IpcMemoryId;
/* ipc.c */
-extern void exitpg(int code);
-extern void quasi_exitpg(void);
-extern int on_exitpg(void (*function)(), caddr_t arg);
-
-extern IpcSemaphoreId IpcSemaphoreCreate(IpcSemaphoreKey semKey,
- int semNum, int permission, int semStartValue,
- int removeOnExit, int *status);
-extern void IpcSemaphoreKill(IpcSemaphoreKey key);
-extern void IpcSemaphoreLock(IpcSemaphoreId semId, int sem, int lock);
-extern void IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem, int lock);
-extern int IpcSemaphoreGetCount(IpcSemaphoreId semId, int sem);
-extern int IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem);
-extern IpcMemoryId IpcMemoryCreate(IpcMemoryKey memKey, uint32 size,
- int permission);
+extern void exitpg(int code);
+extern void quasi_exitpg(void);
+extern int on_exitpg(void (*function) (), caddr_t arg);
+
+extern IpcSemaphoreId
+IpcSemaphoreCreate(IpcSemaphoreKey semKey,
+ int semNum, int permission, int semStartValue,
+ int removeOnExit, int *status);
+extern void IpcSemaphoreKill(IpcSemaphoreKey key);
+extern void IpcSemaphoreLock(IpcSemaphoreId semId, int sem, int lock);
+extern void IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem, int lock);
+extern int IpcSemaphoreGetCount(IpcSemaphoreId semId, int sem);
+extern int IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem);
+extern IpcMemoryId
+IpcMemoryCreate(IpcMemoryKey memKey, uint32 size,
+ int permission);
extern IpcMemoryId IpcMemoryIdGet(IpcMemoryKey memKey, uint32 size);
-extern char *IpcMemoryAttach(IpcMemoryId memId);
-extern void IpcMemoryKill(IpcMemoryKey memKey);
-extern void CreateAndInitSLockMemory(IPCKey key);
-extern void AttachSLockMemory(IPCKey key);
+extern char *IpcMemoryAttach(IpcMemoryId memId);
+extern void IpcMemoryKill(IpcMemoryKey memKey);
+extern void CreateAndInitSLockMemory(IPCKey key);
+extern void AttachSLockMemory(IPCKey key);
#ifdef HAS_TEST_AND_SET
-#define NSLOCKS 2048
-#define NOLOCK 0
-#define SHAREDLOCK 1
+#define NSLOCKS 2048
+#define NOLOCK 0
+#define SHAREDLOCK 1
#define EXCLUSIVELOCK 2
-typedef enum _LockId_ {
- BUFMGRLOCKID,
- LOCKLOCKID,
- OIDGENLOCKID,
- SHMEMLOCKID,
- BINDINGLOCKID,
- LOCKMGRLOCKID,
- SINVALLOCKID,
+typedef enum _LockId_
+{
+ BUFMGRLOCKID,
+ LOCKLOCKID,
+ OIDGENLOCKID,
+ SHMEMLOCKID,
+ BINDINGLOCKID,
+ LOCKMGRLOCKID,
+ SINVALLOCKID,
#ifdef MAIN_MEMORY
- MMCACHELOCKID,
-#endif /* MAIN_MEMORY */
-
- PROCSTRUCTLOCKID,
- FIRSTFREELOCKID
-} _LockId_;
-
-#define MAX_SPINS FIRSTFREELOCKID
-
-typedef struct slock {
- slock_t locklock;
- unsigned char flag;
- short nshlocks;
- slock_t shlock;
- slock_t exlock;
- slock_t comlock;
- struct slock *next;
-} SLock;
-
-extern void ExclusiveLock(int lockid);
-extern void ExclusiveUnlock(int lockid);
-extern bool LockIsFree(int lockid);
-#else /* HAS_TEST_AND_SET */
-
-typedef enum _LockId_ {
- SHMEMLOCKID,
- BINDINGLOCKID,
- BUFMGRLOCKID,
- LOCKMGRLOCKID,
- SINVALLOCKID,
+ MMCACHELOCKID,
+#endif /* MAIN_MEMORY */
+
+ PROCSTRUCTLOCKID,
+ FIRSTFREELOCKID
+} _LockId_;
+
+#define MAX_SPINS FIRSTFREELOCKID
+
+typedef struct slock
+{
+ slock_t locklock;
+ unsigned char flag;
+ short nshlocks;
+ slock_t shlock;
+ slock_t exlock;
+ slock_t comlock;
+ struct slock *next;
+} SLock;
+
+extern void ExclusiveLock(int lockid);
+extern void ExclusiveUnlock(int lockid);
+extern bool LockIsFree(int lockid);
+
+#else /* HAS_TEST_AND_SET */
+
+typedef enum _LockId_
+{
+ SHMEMLOCKID,
+ BINDINGLOCKID,
+ BUFMGRLOCKID,
+ LOCKMGRLOCKID,
+ SINVALLOCKID,
#ifdef MAIN_MEMORY
- MMCACHELOCKID,
-#endif /* MAIN_MEMORY */
+ MMCACHELOCKID,
+#endif /* MAIN_MEMORY */
- PROCSTRUCTLOCKID,
- OIDGENLOCKID,
- FIRSTFREELOCKID
-} _LockId_;
+ PROCSTRUCTLOCKID,
+ OIDGENLOCKID,
+ FIRSTFREELOCKID
+} _LockId_;
-#define MAX_SPINS FIRSTFREELOCKID
+#define MAX_SPINS FIRSTFREELOCKID
-#endif /* HAS_TEST_AND_SET */
+#endif /* HAS_TEST_AND_SET */
/*
* the following are originally in ipci.h but the prototypes have circular
@@ -176,42 +186,42 @@ typedef enum _LockId_ {
/*
* Note:
- * These must not hash to DefaultIPCKey or PrivateIPCKey.
+ * These must not hash to DefaultIPCKey or PrivateIPCKey.
*/
#define SystemPortAddressGetIPCKey(address) \
- (28597 * (address) + 17491)
+ (28597 * (address) + 17491)
/*
* these keys are originally numbered from 1 to 12 consecutively but not
- * all are used. The unused ones are removed. - ay 4/95.
+ * all are used. The unused ones are removed. - ay 4/95.
*/
#define IPCKeyGetBufferMemoryKey(key) \
- ((key == PrivateIPCKey) ? key : 1 + (key))
+ ((key == PrivateIPCKey) ? key : 1 + (key))
#define IPCKeyGetSIBufferMemoryBlock(key) \
- ((key == PrivateIPCKey) ? key : 7 + (key))
+ ((key == PrivateIPCKey) ? key : 7 + (key))
#define IPCKeyGetSLockSharedMemoryKey(key) \
- ((key == PrivateIPCKey) ? key : 10 + (key))
+ ((key == PrivateIPCKey) ? key : 10 + (key))
#define IPCKeyGetSpinLockSemaphoreKey(key) \
- ((key == PrivateIPCKey) ? key : 11 + (key))
+ ((key == PrivateIPCKey) ? key : 11 + (key))
#define IPCKeyGetWaitIOSemaphoreKey(key) \
- ((key == PrivateIPCKey) ? key : 12 + (key))
+ ((key == PrivateIPCKey) ? key : 12 + (key))
/* --------------------------
* NOTE: This macro must always give the highest numbered key as every backend
* process forked off by the postmaster will be trying to acquire a semaphore
- * with a unique key value starting at key+14 and incrementing up. Each
+ * with a unique key value starting at key+14 and incrementing up. Each
* backend uses the current key value then increments it by one.
* --------------------------
*/
#define IPCGetProcessSemaphoreInitKey(key) \
- ((key == PrivateIPCKey) ? key : 14 + (key))
+ ((key == PrivateIPCKey) ? key : 14 + (key))
/* ipci.c */
-extern IPCKey SystemPortAddressCreateIPCKey(SystemPortAddress address);
-extern void CreateSharedMemoryAndSemaphores(IPCKey key);
-extern void AttachSharedMemoryAndSemaphores(IPCKey key);
+extern IPCKey SystemPortAddressCreateIPCKey(SystemPortAddress address);
+extern void CreateSharedMemoryAndSemaphores(IPCKey key);
+extern void AttachSharedMemoryAndSemaphores(IPCKey key);
-#endif /* IPC_H */
+#endif /* IPC_H */
diff --git a/src/include/storage/item.h b/src/include/storage/item.h
index c943fc33f00..6541a717f9f 100644
--- a/src/include/storage/item.h
+++ b/src/include/storage/item.h
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* item.h--
- * POSTGRES disk item definitions.
+ * POSTGRES disk item definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: item.h,v 1.2 1996/10/31 09:49:49 scrappy Exp $
+ * $Id: item.h,v 1.3 1997/09/07 05:01:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef ITEM_H
+#ifndef ITEM_H
#define ITEM_H
-typedef Pointer Item;
+typedef Pointer Item;
-#endif /* ITEM_H */
+#endif /* ITEM_H */
diff --git a/src/include/storage/itemid.h b/src/include/storage/itemid.h
index 7e4fc5e28d6..9e5e6f94d4a 100644
--- a/src/include/storage/itemid.h
+++ b/src/include/storage/itemid.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* itemid.h--
- * Standard POSTGRES buffer page item identifier definitions.
+ * Standard POSTGRES buffer page item identifier definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: itemid.h,v 1.1 1996/08/28 01:58:08 scrappy Exp $
+ * $Id: itemid.h,v 1.2 1997/09/07 05:01:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef ITEMID_H
+#ifndef ITEMID_H
#define ITEMID_H
typedef uint16 ItemOffset;
@@ -20,56 +20,57 @@ typedef bits16 ItemIdFlags;
-typedef struct ItemIdData { /* line pointers */
- unsigned lp_off:13, /* offset to find tup */
- /* can be reduced by 2 if necc. */
- lp_flags:6, /* flags on tuple */
- lp_len:13; /* length of tuple */
-} ItemIdData;
+typedef struct ItemIdData
+{ /* line pointers */
+ unsigned lp_off:13, /* offset to find tup */
+ /* can be reduced by 2 if necc. */
+ lp_flags:6, /* flags on tuple */
+ lp_len:13; /* length of tuple */
+} ItemIdData;
-typedef struct ItemIdData *ItemId;
+typedef struct ItemIdData *ItemId;
-#ifndef LP_USED
-#define LP_USED 0x01 /* this line pointer is being used */
+#ifndef LP_USED
+#define LP_USED 0x01 /* this line pointer is being used */
#endif
/* ----------------
- * support macros
+ * support macros
* ----------------
*/
-/*
- * ItemIdGetLength
+/*
+ * ItemIdGetLength
*/
#define ItemIdGetLength(itemId) \
((itemId)->lp_len)
-/*
- * ItemIdGetOffset
+/*
+ * ItemIdGetOffset
*/
#define ItemIdGetOffset(itemId) \
((itemId)->lp_off)
-/*
- * ItemIdGetFlags
+/*
+ * ItemIdGetFlags
*/
#define ItemIdGetFlags(itemId) \
((itemId)->lp_flags)
/*
* ItemIdIsValid --
- * True iff disk item identifier is valid.
+ * True iff disk item identifier is valid.
*/
-#define ItemIdIsValid(itemId) PointerIsValid(itemId)
+#define ItemIdIsValid(itemId) PointerIsValid(itemId)
/*
* ItemIdIsUsed --
- * True iff disk item identifier is in use.
+ * True iff disk item identifier is in use.
*
* Note:
- * Assumes disk item identifier is valid.
+ * Assumes disk item identifier is valid.
*/
#define ItemIdIsUsed(itemId) \
- (AssertMacro(ItemIdIsValid(itemId)) ? \
- (bool) (((itemId)->lp_flags & LP_USED) != 0) : false)
+ (AssertMacro(ItemIdIsValid(itemId)) ? \
+ (bool) (((itemId)->lp_flags & LP_USED) != 0) : false)
-#endif /* ITEMID_H */
+#endif /* ITEMID_H */
diff --git a/src/include/storage/itempos.h b/src/include/storage/itempos.h
index fc847df4ec9..bea9cd64746 100644
--- a/src/include/storage/itempos.h
+++ b/src/include/storage/itempos.h
@@ -1,43 +1,44 @@
/*-------------------------------------------------------------------------
*
* itempos.h--
- * Standard POSTGRES buffer page long item subposition definitions.
+ * Standard POSTGRES buffer page long item subposition definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: itempos.h,v 1.3 1996/11/05 06:10:58 scrappy Exp $
+ * $Id: itempos.h,v 1.4 1997/09/07 05:01:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef ITEMPOS_H
+#ifndef ITEMPOS_H
#define ITEMPOS_H
#include <storage/itemid.h>
#include <storage/buf.h>
-typedef struct ItemSubpositionData {
- Buffer op_db;
- ItemId op_lpp;
- char *op_cp; /* XXX */
- uint32 op_len;
-} ItemSubpositionData;
+typedef struct ItemSubpositionData
+{
+ Buffer op_db;
+ ItemId op_lpp;
+ char *op_cp; /* XXX */
+ uint32 op_len;
+} ItemSubpositionData;
-typedef ItemSubpositionData *ItemSubposition;
+typedef ItemSubpositionData *ItemSubposition;
/*
- * PNOBREAK(OBJP, LEN)
- * struct objpos *OBJP;
- * unsigned LEN;
+ * PNOBREAK(OBJP, LEN)
+ * struct objpos *OBJP;
+ * unsigned LEN;
*/
-#define PNOBREAK(OBJP, LEN) ((OBJP)->op_len >= LEN)
+#define PNOBREAK(OBJP, LEN) ((OBJP)->op_len >= LEN)
/*
- * PSKIP(OBJP, LEN)
- * struct objpos *OBJP;
- * unsigned LEN;
+ * PSKIP(OBJP, LEN)
+ * struct objpos *OBJP;
+ * unsigned LEN;
*/
#define PSKIP(OBJP, LEN)\
- { (OBJP)->op_cp += (LEN); (OBJP)->op_len -= (LEN); }
+ { (OBJP)->op_cp += (LEN); (OBJP)->op_len -= (LEN); }
-#endif /* ITEMPOS_H */
+#endif /* ITEMPOS_H */
diff --git a/src/include/storage/itemptr.h b/src/include/storage/itemptr.h
index f794141a6e0..3460cd19f9e 100644
--- a/src/include/storage/itemptr.h
+++ b/src/include/storage/itemptr.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* itemptr.h--
- * POSTGRES disk item pointer definitions.
+ * POSTGRES disk item pointer definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: itemptr.h,v 1.4 1996/11/04 07:18:29 scrappy Exp $
+ * $Id: itemptr.h,v 1.5 1997/09/07 05:01:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef ITEMPTR_H
+#ifndef ITEMPTR_H
#define ITEMPTR_H
#include <storage/off.h>
@@ -23,91 +23,91 @@
* blkid tells us which block, posid tells us which entry in the linp
* (ItemIdData) array we want.
*/
-typedef struct ItemPointerData {
- BlockIdData ip_blkid;
- OffsetNumber ip_posid;
-} ItemPointerData;
+typedef struct ItemPointerData
+{
+ BlockIdData ip_blkid;
+ OffsetNumber ip_posid;
+} ItemPointerData;
-typedef ItemPointerData *ItemPointer;
+typedef ItemPointerData *ItemPointer;
/* ----------------
- * support macros
+ * support macros
* ----------------
*/
/*
* ItemPointerIsValid --
- * True iff the disk item pointer is not NULL.
+ * True iff the disk item pointer is not NULL.
*/
#define ItemPointerIsValid(pointer) \
- ((bool) (PointerIsValid(pointer) && ((pointer)->ip_posid != 0)))
+ ((bool) (PointerIsValid(pointer) && ((pointer)->ip_posid != 0)))
/*
* ItemPointerGetBlockNumber --
- * Returns the block number of a disk item pointer.
+ * Returns the block number of a disk item pointer.
*/
#define ItemPointerGetBlockNumber(pointer) \
- (AssertMacro(ItemPointerIsValid(pointer)) ? \
- BlockIdGetBlockNumber(&(pointer)->ip_blkid) : (BlockNumber) 0)
+ (AssertMacro(ItemPointerIsValid(pointer)) ? \
+ BlockIdGetBlockNumber(&(pointer)->ip_blkid) : (BlockNumber) 0)
/*
* ItemPointerGetOffsetNumber --
- * Returns the offset number of a disk item pointer.
+ * Returns the offset number of a disk item pointer.
*/
#define ItemPointerGetOffsetNumber(pointer) \
- (AssertMacro(ItemPointerIsValid(pointer)) ? \
- (pointer)->ip_posid : \
- InvalidOffsetNumber)
+ (AssertMacro(ItemPointerIsValid(pointer)) ? \
+ (pointer)->ip_posid : \
+ InvalidOffsetNumber)
/*
* ItemPointerSet --
- * Sets a disk item pointer to the specified block and offset.
+ * Sets a disk item pointer to the specified block and offset.
*/
#define ItemPointerSet(pointer, blockNumber, offNum) \
- Assert(PointerIsValid(pointer)); \
- BlockIdSet(&((pointer)->ip_blkid), blockNumber); \
- (pointer)->ip_posid = offNum
+ Assert(PointerIsValid(pointer)); \
+ BlockIdSet(&((pointer)->ip_blkid), blockNumber); \
+ (pointer)->ip_posid = offNum
/*
* ItemPointerSetBlockNumber --
- * Sets a disk item pointer to the specified block.
+ * Sets a disk item pointer to the specified block.
*/
#define ItemPointerSetBlockNumber(pointer, blockNumber) \
- Assert(PointerIsValid(pointer)); \
- BlockIdSet(&((pointer)->ip_blkid), blockNumber)
+ Assert(PointerIsValid(pointer)); \
+ BlockIdSet(&((pointer)->ip_blkid), blockNumber)
/*
* ItemPointerSetOffsetNumber --
- * Sets a disk item pointer to the specified offset.
+ * Sets a disk item pointer to the specified offset.
*/
#define ItemPointerSetOffsetNumber(pointer, offsetNumber) \
- AssertMacro(PointerIsValid(pointer)); \
- (pointer)->ip_posid = (offsetNumber)
+ AssertMacro(PointerIsValid(pointer)); \
+ (pointer)->ip_posid = (offsetNumber)
/*
* ItemPointerCopy --
- * Copies the contents of one disk item pointer to another.
+ * Copies the contents of one disk item pointer to another.
*/
#define ItemPointerCopy(fromPointer, toPointer) \
- Assert(PointerIsValid(toPointer)); \
- Assert(PointerIsValid(fromPointer)); \
- *(toPointer) = *(fromPointer)
+ Assert(PointerIsValid(toPointer)); \
+ Assert(PointerIsValid(fromPointer)); \
+ *(toPointer) = *(fromPointer)
/*
* ItemPointerSetInvalid --
- * Sets a disk item pointer to be invalid.
+ * Sets a disk item pointer to be invalid.
*/
#define ItemPointerSetInvalid(pointer) \
- Assert(PointerIsValid(pointer)); \
- BlockIdSet(&((pointer)->ip_blkid), InvalidBlockNumber); \
- (pointer)->ip_posid = InvalidOffsetNumber
+ Assert(PointerIsValid(pointer)); \
+ BlockIdSet(&((pointer)->ip_blkid), InvalidBlockNumber); \
+ (pointer)->ip_posid = InvalidOffsetNumber
/* ----------------
- * externs
+ * externs
* ----------------
*/
-extern bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2);
-
-#endif /* ITEMPTR_H */
+extern bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2);
+#endif /* ITEMPTR_H */
diff --git a/src/include/storage/large_object.h b/src/include/storage/large_object.h
index b5ee9cc068a..1144d1ca02d 100644
--- a/src/include/storage/large_object.h
+++ b/src/include/storage/large_object.h
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* large_object.h--
- * file of info for Postgres large objects. POSTGRES 4.2 supports
- * zillions of large objects (internal, external, jaquith, inversion).
- * Now we only support inversion.
+ * file of info for Postgres large objects. POSTGRES 4.2 supports
+ * zillions of large objects (internal, external, jaquith, inversion).
+ * Now we only support inversion.
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: large_object.h,v 1.4 1997/08/19 21:39:52 momjian Exp $
+ * $Id: large_object.h,v 1.5 1997/09/07 05:01:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef LARGE_OBJECT_H
-#define LARGE_OBJECT_H
+#ifndef LARGE_OBJECT_H
+#define LARGE_OBJECT_H
#include <sys/types.h>
@@ -23,22 +23,22 @@
*/
typedef struct LargeObjectDesc
{
- Relation heap_r; /* heap relation */
- Relation index_r; /* index relation on seqno attribute */
- IndexScanDesc iscan; /* index scan we're using */
- TupleDesc hdesc; /* heap relation tuple desc */
- TupleDesc idesc; /* index relation tuple desc */
- uint32 lowbyte; /* low byte on the current page */
- uint32 highbyte; /* high byte on the current page */
- uint32 offset; /* current seek pointer */
- ItemPointerData htid; /* tid of current heap tuple */
-
-#define IFS_RDLOCK (1 << 0)
-#define IFS_WRLOCK (1 << 1)
-#define IFS_ATEOF (1 << 2)
-
- u_long flags; /* locking info, etc */
-} LargeObjectDesc;
+ Relation heap_r; /* heap relation */
+ Relation index_r; /* index relation on seqno attribute */
+ IndexScanDesc iscan; /* index scan we're using */
+ TupleDesc hdesc; /* heap relation tuple desc */
+ TupleDesc idesc; /* index relation tuple desc */
+ uint32 lowbyte; /* low byte on the current page */
+ uint32 highbyte; /* high byte on the current page */
+ uint32 offset; /* current seek pointer */
+ ItemPointerData htid; /* tid of current heap tuple */
+
+#define IFS_RDLOCK (1 << 0)
+#define IFS_WRLOCK (1 << 1)
+#define IFS_ATEOF (1 << 2)
+
+ u_long flags; /* locking info, etc */
+} LargeObjectDesc;
/*
* Function definitions...
@@ -47,11 +47,11 @@ typedef struct LargeObjectDesc
/* inversion stuff in inv_api.c */
extern LargeObjectDesc *inv_create(int flags);
extern LargeObjectDesc *inv_open(Oid lobjId, int flags);
-extern void inv_close(LargeObjectDesc *obj_desc);
-extern int inv_destroy(Oid lobjId);
-extern int inv_seek(LargeObjectDesc *obj_desc, int offset, int whence);
-extern int inv_tell(LargeObjectDesc *obj_desc);
-extern int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes);
-extern int inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes);
-
-#endif /* LARGE_OBJECT_H */
+extern void inv_close(LargeObjectDesc * obj_desc);
+extern int inv_destroy(Oid lobjId);
+extern int inv_seek(LargeObjectDesc * obj_desc, int offset, int whence);
+extern int inv_tell(LargeObjectDesc * obj_desc);
+extern int inv_read(LargeObjectDesc * obj_desc, char *buf, int nbytes);
+extern int inv_write(LargeObjectDesc * obj_desc, char *buf, int nbytes);
+
+#endif /* LARGE_OBJECT_H */
diff --git a/src/include/storage/lmgr.h b/src/include/storage/lmgr.h
index 0d65b29ba0b..debe950c7c5 100644
--- a/src/include/storage/lmgr.h
+++ b/src/include/storage/lmgr.h
@@ -1,75 +1,83 @@
/*-------------------------------------------------------------------------
*
* lmgr.h--
- * POSTGRES lock manager definitions.
+ * POSTGRES lock manager definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: lmgr.h,v 1.5 1997/08/19 21:39:54 momjian Exp $
+ * $Id: lmgr.h,v 1.6 1997/09/07 05:01:25 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef LMGR_H
+#ifndef LMGR_H
#define LMGR_H
#include <storage/lock.h>
#include <utils/rel.h>
-/*
+/*
* This was moved from pladt.h for the new lock manager. Want to obsolete
* all of the old code.
*/
-typedef struct LRelId {
- Oid relId; /* a relation identifier */
- Oid dbId; /* a database identifier */
-} LRelId;
+typedef struct LRelId
+{
+ Oid relId; /* a relation identifier */
+ Oid dbId; /* a database identifier */
+} LRelId;
-typedef struct LockInfoData {
- bool initialized;
- LRelId lRelId;
- TransactionId transactionIdData;
- uint16 flags;
-} LockInfoData;
-typedef LockInfoData *LockInfo;
+typedef struct LockInfoData
+{
+ bool initialized;
+ LRelId lRelId;
+ TransactionId transactionIdData;
+ uint16 flags;
+} LockInfoData;
+typedef LockInfoData *LockInfo;
#define LockInfoIsValid(linfo) \
- ((PointerIsValid(linfo)) && ((LockInfo) linfo)->initialized)
+ ((PointerIsValid(linfo)) && ((LockInfo) linfo)->initialized)
-extern LRelId RelationGetLRelId(Relation relation);
-extern Oid LRelIdGetRelationId(LRelId lRelId);
-extern void RelationInitLockInfo(Relation relation);
-extern void RelationSetLockForDescriptorOpen(Relation relation);
-extern void RelationSetLockForRead(Relation relation);
-extern void RelationUnsetLockForRead(Relation relation);
-extern void RelationSetLockForWrite(Relation relation);
-extern void RelationUnsetLockForWrite(Relation relation);
+extern LRelId RelationGetLRelId(Relation relation);
+extern Oid LRelIdGetRelationId(LRelId lRelId);
+extern void RelationInitLockInfo(Relation relation);
+extern void RelationSetLockForDescriptorOpen(Relation relation);
+extern void RelationSetLockForRead(Relation relation);
+extern void RelationUnsetLockForRead(Relation relation);
+extern void RelationSetLockForWrite(Relation relation);
+extern void RelationUnsetLockForWrite(Relation relation);
/* used in vaccum.c */
-extern void RelationSetLockForWritePage(Relation relation,
- ItemPointer itemPointer);
+extern void
+RelationSetLockForWritePage(Relation relation,
+ ItemPointer itemPointer);
/* used in nbtpage.c, hashpage.c */
-extern void RelationSetSingleWLockPage(Relation relation,
- ItemPointer itemPointer);
-extern void RelationUnsetSingleWLockPage(Relation relation,
- ItemPointer itemPointer);
-extern void RelationSetSingleRLockPage(Relation relation,
- ItemPointer itemPointer);
-extern void RelationUnsetSingleRLockPage(Relation relation,
- ItemPointer itemPointer);
-extern void RelationSetRIntentLock(Relation relation);
-extern void RelationUnsetRIntentLock(Relation relation);
-extern void RelationSetWIntentLock(Relation relation);
-extern void RelationUnsetWIntentLock(Relation relation);
+extern void
+RelationSetSingleWLockPage(Relation relation,
+ ItemPointer itemPointer);
+extern void
+RelationUnsetSingleWLockPage(Relation relation,
+ ItemPointer itemPointer);
+extern void
+RelationSetSingleRLockPage(Relation relation,
+ ItemPointer itemPointer);
+extern void
+RelationUnsetSingleRLockPage(Relation relation,
+ ItemPointer itemPointer);
+extern void RelationSetRIntentLock(Relation relation);
+extern void RelationUnsetRIntentLock(Relation relation);
+extern void RelationSetWIntentLock(Relation relation);
+extern void RelationUnsetWIntentLock(Relation relation);
/* single.c */
-extern bool SingleLockReln(LockInfo linfo, LOCKT lockt, int action);
-extern bool SingleLockPage(LockInfo linfo, ItemPointer tidPtr,
+extern bool SingleLockReln(LockInfo linfo, LOCKT lockt, int action);
+extern bool
+SingleLockPage(LockInfo linfo, ItemPointer tidPtr,
LOCKT lockt, int action);
/* proc.c */
-extern void InitProcGlobal(IPCKey key);
+extern void InitProcGlobal(IPCKey key);
-#endif /* LMGR_H */
+#endif /* LMGR_H */
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 25b851dac3d..2b0f76649b4 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* lock.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: lock.h,v 1.5 1997/08/19 21:39:55 momjian Exp $
+ * $Id: lock.h,v 1.6 1997/09/07 05:01:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,16 +17,16 @@
#include <storage/itemptr.h>
extern SPINLOCK LockMgrLock;
-typedef int MASK;
+typedef int MASK;
-#define INIT_TABLE_SIZE 100
-#define MAX_TABLE_SIZE 1000
+#define INIT_TABLE_SIZE 100
+#define MAX_TABLE_SIZE 1000
/* ----------------------
* The following defines are used to estimate how much shared
- * memory the lock manager is going to require.
- *
+ * memory the lock manager is going to require.
+ *
* NBACKENDS - The number of concurrently running backends
* NLOCKS_PER_XACT - The number of unique locks acquired in a transaction
* NLOCKENTS - The maximum number of lock entries in the lock table.
@@ -36,9 +36,9 @@ typedef int MASK;
#define NLOCKS_PER_XACT 40
#define NLOCKENTS NLOCKS_PER_XACT*NBACKENDS
-typedef int LOCK_TYPE;
-typedef int LOCKT;
-typedef int LockTableId;
+typedef int LOCK_TYPE;
+typedef int LOCKT;
+typedef int LockTableId;
/* MAX_LOCKTYPES cannot be larger than the bits in MASK */
#define MAX_LOCKTYPES 6
@@ -55,53 +55,56 @@ typedef int LockTableId;
/*typedef struct LOCK LOCK; */
-typedef struct ltag {
- Oid relId;
- Oid dbId;
- ItemPointerData tupleId;
-} LOCKTAG;
+typedef struct ltag
+{
+ Oid relId;
+ Oid dbId;
+ ItemPointerData tupleId;
+} LOCKTAG;
#define TAGSIZE (sizeof(LOCKTAG))
-/* This is the control structure for a lock table. It
+/* This is the control structure for a lock table. It
* lives in shared memory:
*
* tableID -- the handle used by the lock table's clients to
- * refer to the table.
+ * refer to the table.
*
* nLockTypes -- number of lock types (READ,WRITE,etc) that
- * are defined on this lock table
+ * are defined on this lock table
*
* conflictTab -- this is an array of bitmasks showing lock
- * type conflicts. conflictTab[i] is a mask with the j-th bit
- * turned on if lock types i and j conflict.
+ * type conflicts. conflictTab[i] is a mask with the j-th bit
+ * turned on if lock types i and j conflict.
*
* prio -- each locktype has a priority, so, for example, waiting
- * writers can be given priority over readers (to avoid
- * starvation).
+ * writers can be given priority over readers (to avoid
+ * starvation).
*
* masterlock -- synchronizes access to the table
*
*/
-typedef struct lockctl {
- LockTableId tableId;
- int nLockTypes;
- int conflictTab[MAX_LOCKTYPES];
- int prio[MAX_LOCKTYPES];
- SPINLOCK masterLock;
-} LOCKCTL;
+typedef struct lockctl
+{
+ LockTableId tableId;
+ int nLockTypes;
+ int conflictTab[MAX_LOCKTYPES];
+ int prio[MAX_LOCKTYPES];
+ SPINLOCK masterLock;
+} LOCKCTL;
/*
* lockHash -- hash table on lock Ids,
* xidHash -- hash on xid and lockId in case
- * multiple processes are holding the lock
+ * multiple processes are holding the lock
* ctl - control structure described above.
*/
-typedef struct ltable {
- HTAB *lockHash;
- HTAB *xidHash;
- LOCKCTL *ctl;
-} LOCKTAB;
+typedef struct ltable
+{
+ HTAB *lockHash;
+ HTAB *xidHash;
+ LOCKCTL *ctl;
+} LOCKTAB;
/* -----------------------
* A transaction never conflicts with its own locks. Hence, if
@@ -132,29 +135,32 @@ typedef struct ltable {
* -----------------------
*/
-typedef struct XIDTAG {
- SHMEM_OFFSET lock;
- int pid;
- TransactionId xid;
-} XIDTAG;
+typedef struct XIDTAG
+{
+ SHMEM_OFFSET lock;
+ int pid;
+ TransactionId xid;
+} XIDTAG;
-typedef struct XIDLookupEnt {
- /* tag */
- XIDTAG tag;
+typedef struct XIDLookupEnt
+{
+ /* tag */
+ XIDTAG tag;
- /* data */
- int holders[MAX_LOCKTYPES];
- int nHolding;
- SHM_QUEUE queue;
-} XIDLookupEnt;
+ /* data */
+ int holders[MAX_LOCKTYPES];
+ int nHolding;
+ SHM_QUEUE queue;
+} XIDLookupEnt;
#define XID_TAGSIZE (sizeof(XIDTAG))
/* originally in procq.h */
-typedef struct procQueue {
- SHM_QUEUE links;
- int size;
-} PROC_QUEUE;
+typedef struct procQueue
+{
+ SHM_QUEUE links;
+ int size;
+} PROC_QUEUE;
/*
@@ -162,24 +168,25 @@ typedef struct procQueue {
*
* tag -- uniquely identifies the object being locked
* mask -- union of the conflict masks of all lock types
- * currently held on this object.
+ * currently held on this object.
* waitProcs -- queue of processes waiting for this lock
* holders -- count of each lock type currently held on the
- * lock.
+ * lock.
* nHolding -- total locks of all types.
*/
-typedef struct Lock {
- /* hash key */
- LOCKTAG tag;
-
- /* data */
- int mask;
- PROC_QUEUE waitProcs;
- int holders[MAX_LOCKTYPES];
- int nHolding;
- int activeHolders[MAX_LOCKTYPES];
- int nActive;
-} LOCK;
+typedef struct Lock
+{
+ /* hash key */
+ LOCKTAG tag;
+
+ /* data */
+ int mask;
+ PROC_QUEUE waitProcs;
+ int holders[MAX_LOCKTYPES];
+ int nHolding;
+ int activeHolders[MAX_LOCKTYPES];
+ int nActive;
+} LOCK;
#define LockGetLock_nHolders(l) l->nHolders
@@ -195,21 +202,24 @@ extern SPINLOCK LockMgrLock;
/*
* function prototypes
*/
-extern void InitLocks(void);
-extern void LockDisable(int status);
-extern LockTableId LockTabInit(char *tabName, MASK *conflictsP, int *prioP,
- int ntypes);
-extern bool LockAcquire(LockTableId tableId, LOCKTAG *lockName, LOCKT lockt);
-extern int LockResolveConflicts(LOCKTAB *ltable, LOCK *lock, LOCKT lockt,
- TransactionId xid);
-extern bool LockRelease(LockTableId tableId, LOCKTAG *lockName, LOCKT lockt);
-extern void GrantLock(LOCK *lock, LOCKT lockt);
-extern bool LockReleaseAll(LockTableId tableId, SHM_QUEUE *lockQueue);
-extern int LockShmemSize(void);
-extern bool LockingDisabled(void);
+extern void InitLocks(void);
+extern void LockDisable(int status);
+extern LockTableId
+LockTabInit(char *tabName, MASK * conflictsP, int *prioP,
+ int ntypes);
+extern bool LockAcquire(LockTableId tableId, LOCKTAG * lockName, LOCKT lockt);
+extern int
+LockResolveConflicts(LOCKTAB * ltable, LOCK * lock, LOCKT lockt,
+ TransactionId xid);
+extern bool LockRelease(LockTableId tableId, LOCKTAG * lockName, LOCKT lockt);
+extern void GrantLock(LOCK * lock, LOCKT lockt);
+extern bool LockReleaseAll(LockTableId tableId, SHM_QUEUE * lockQueue);
+extern int LockShmemSize(void);
+extern bool LockingDisabled(void);
#ifdef DEADLOCK_DEBUG
-extern void DumpLocks(void);
+extern void DumpLocks(void);
+
#endif
-#endif /* LOCK_H */
+#endif /* LOCK_H */
diff --git a/src/include/storage/multilev.h b/src/include/storage/multilev.h
index d077455d872..befc6227ae9 100644
--- a/src/include/storage/multilev.h
+++ b/src/include/storage/multilev.h
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* multilev.h--
- * multi level lock table consts/defs for single.c and multi.c and their
- * clients
+ * multi level lock table consts/defs for single.c and multi.c and their
+ * clients
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: multilev.h,v 1.3 1997/08/19 21:39:56 momjian Exp $
+ * $Id: multilev.h,v 1.4 1997/09/07 05:01:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,30 +16,30 @@
#include <storage/lmgr.h>
-#define READ_LOCK 2
-#define WRITE_LOCK 1
+#define READ_LOCK 2
+#define WRITE_LOCK 1
-/* any time a small granularity READ/WRITE lock is set.
+/* any time a small granularity READ/WRITE lock is set.
* Higher granularity READ_INTENT/WRITE_INTENT locks must
* also be set. A read intent lock is has value READ+INTENT.
* in this implementation.
*/
-#define NO_LOCK 0
-#define INTENT 2
-#define READ_INTENT (READ_LOCK+INTENT)
+#define NO_LOCK 0
+#define INTENT 2
+#define READ_INTENT (READ_LOCK+INTENT)
#define WRITE_INTENT (WRITE_LOCK+INTENT)
-#define EXTEND_LOCK 5
+#define EXTEND_LOCK 5
-#define SHORT_TERM 1
-#define LONG_TERM 2
-#define UNLOCK 0
+#define SHORT_TERM 1
+#define LONG_TERM 2
+#define UNLOCK 0
#define N_LEVELS 3
#define RELN_LEVEL 0
#define PAGE_LEVEL 1
#define TUPLE_LEVEL 2
-typedef int LOCK_LEVEL;
+typedef int LOCK_LEVEL;
/* multi.c */
@@ -50,9 +50,9 @@ extern LockTableId ShortTermTableId;
* function prototypes
*/
extern LockTableId InitMultiLevelLockm(void);
-extern bool MultiLockReln(LockInfo linfo, LOCKT lockt);
-extern bool MultiLockTuple(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt);
-extern bool MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt);
-extern bool MultiReleaseReln(LockInfo linfo, LOCKT lockt);
+extern bool MultiLockReln(LockInfo linfo, LOCKT lockt);
+extern bool MultiLockTuple(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt);
+extern bool MultiLockPage(LockInfo linfo, ItemPointer tidPtr, LOCKT lockt);
+extern bool MultiReleaseReln(LockInfo linfo, LOCKT lockt);
-#endif /* MULTILEV_H */
+#endif /* MULTILEV_H */
diff --git a/src/include/storage/off.h b/src/include/storage/off.h
index 759b30278a3..3eadb842a78 100644
--- a/src/include/storage/off.h
+++ b/src/include/storage/off.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* off.h--
- * POSTGRES disk "offset" definitions.
+ * POSTGRES disk "offset" definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: off.h,v 1.2 1996/10/31 09:49:58 scrappy Exp $
+ * $Id: off.h,v 1.3 1997/09/07 05:01:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef OFF_H
+#ifndef OFF_H
#define OFF_H
/*
@@ -19,38 +19,38 @@
* this is a 1-based index into the linp (ItemIdData) array in the
* header of each disk page.
*/
-typedef uint16 OffsetNumber;
+typedef uint16 OffsetNumber;
-#define InvalidOffsetNumber ((OffsetNumber) 0)
-#define FirstOffsetNumber ((OffsetNumber) 1)
-#define MaxOffsetNumber ((OffsetNumber) (BLCKSZ / sizeof(ItemIdData)))
-#define OffsetNumberMask (0xffff) /* valid uint16 bits */
+#define InvalidOffsetNumber ((OffsetNumber) 0)
+#define FirstOffsetNumber ((OffsetNumber) 1)
+#define MaxOffsetNumber ((OffsetNumber) (BLCKSZ / sizeof(ItemIdData)))
+#define OffsetNumberMask (0xffff) /* valid uint16 bits */
/* ----------------
- * support macros
+ * support macros
* ----------------
*/
/*
* OffsetNumberIsValid --
- * True iff the offset number is valid.
+ * True iff the offset number is valid.
*/
#define OffsetNumberIsValid(offsetNumber) \
- ((bool) ((offsetNumber != InvalidOffsetNumber) && \
- (offsetNumber <= MaxOffsetNumber)))
+ ((bool) ((offsetNumber != InvalidOffsetNumber) && \
+ (offsetNumber <= MaxOffsetNumber)))
/*
* OffsetNumberNext --
* OffsetNumberPrev --
- * Increments/decrements the argument. These macros look pointless
- * but they help us disambiguate the different manipulations on
- * OffsetNumbers (e.g., sometimes we substract one from an
- * OffsetNumber to move back, and sometimes we do so to form a
- * real C array index).
+ * Increments/decrements the argument. These macros look pointless
+ * but they help us disambiguate the different manipulations on
+ * OffsetNumbers (e.g., sometimes we substract one from an
+ * OffsetNumber to move back, and sometimes we do so to form a
+ * real C array index).
*/
#define OffsetNumberNext(offsetNumber) \
- ((OffsetNumber) (1 + (offsetNumber)))
+ ((OffsetNumber) (1 + (offsetNumber)))
#define OffsetNumberPrev(offsetNumber) \
- ((OffsetNumber) (-1 + (offsetNumber)))
+ ((OffsetNumber) (-1 + (offsetNumber)))
-#endif /* OFF_H */
+#endif /* OFF_H */
diff --git a/src/include/storage/page.h b/src/include/storage/page.h
index f2f6c1fcba5..17d29746c9c 100644
--- a/src/include/storage/page.h
+++ b/src/include/storage/page.h
@@ -1,24 +1,24 @@
/*-------------------------------------------------------------------------
*
* page.h--
- * POSTGRES buffer page abstraction definitions.
+ * POSTGRES buffer page abstraction definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: page.h,v 1.2 1996/10/31 09:49:59 scrappy Exp $
+ * $Id: page.h,v 1.3 1997/09/07 05:01:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef PAGE_H
+#ifndef PAGE_H
#define PAGE_H
-typedef Pointer Page;
+typedef Pointer Page;
/*
* PageIsValid --
- * True iff page is valid.
+ * True iff page is valid.
*/
-#define PageIsValid(page) PointerIsValid(page)
+#define PageIsValid(page) PointerIsValid(page)
-#endif /* PAGE_H */
+#endif /* PAGE_H */
diff --git a/src/include/storage/pagenum.h b/src/include/storage/pagenum.h
index 1e4ff7b2120..edd0dc116be 100644
--- a/src/include/storage/pagenum.h
+++ b/src/include/storage/pagenum.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* pagenum.h--
- * POSTGRES page number definitions.
+ * POSTGRES page number definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pagenum.h,v 1.3 1996/11/05 06:11:02 scrappy Exp $
+ * $Id: pagenum.h,v 1.4 1997/09/07 05:01:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef PAGENUM_H
+#ifndef PAGENUM_H
#define PAGENUM_H
@@ -18,14 +18,14 @@ typedef uint16 PageNumber;
typedef uint32 LogicalPageNumber;
-#define InvalidLogicalPageNumber 0
+#define InvalidLogicalPageNumber 0
/*
* LogicalPageNumberIsValid --
- * True iff the logical page number is valid.
+ * True iff the logical page number is valid.
*/
#define LogicalPageNumberIsValid(pageNumber) \
- ((bool)((pageNumber) != InvalidLogicalPageNumber))
+ ((bool)((pageNumber) != InvalidLogicalPageNumber))
-#endif /* PAGENUM_H */
+#endif /* PAGENUM_H */
diff --git a/src/include/storage/pos.h b/src/include/storage/pos.h
index b08faa481fd..c5611ba0c12 100644
--- a/src/include/storage/pos.h
+++ b/src/include/storage/pos.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* pos.h--
- * POSTGRES "position" definitions.
+ * POSTGRES "position" definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pos.h,v 1.2 1996/10/31 09:50:04 scrappy Exp $
+ * $Id: pos.h,v 1.3 1997/09/07 05:01:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef POS_H
+#ifndef POS_H
#define POS_H
/*
@@ -18,45 +18,45 @@
* been changed to just <offset> as the notion of having multiple pages
* within a block has been removed.
*
- * the 'offset' abstraction is somewhat confusing. it is NOT a byte
+ * the 'offset' abstraction is somewhat confusing. it is NOT a byte
* offset within the page; instead, it is an offset into the line
* pointer array contained on every page that store (heap or index)
* tuples.
*/
-typedef bits16 PositionIdData;
-typedef PositionIdData *PositionId;
+typedef bits16 PositionIdData;
+typedef PositionIdData *PositionId;
/* ----------------
- * support macros
+ * support macros
* ----------------
*/
/*
* PositionIdIsValid --
- * True iff the position identifier is valid.
+ * True iff the position identifier is valid.
*/
#define PositionIdIsValid(positionId) \
- PointerIsValid(positionId)
+ PointerIsValid(positionId)
/*
* PositionIdSetInvalid --
- * Make an invalid position.
+ * Make an invalid position.
*/
#define PositionIdSetInvalid(positionId) \
- *(positionId) = (bits16) 0
+ *(positionId) = (bits16) 0
/*
* PositionIdSet --
- * Sets a position identifier to the specified value.
+ * Sets a position identifier to the specified value.
*/
#define PositionIdSet(positionId, offsetNumber) \
- *(positionId) = (offsetNumber)
+ *(positionId) = (offsetNumber)
/*
* PositionIdGetOffsetNumber --
- * Retrieve the offset number from a position identifier.
+ * Retrieve the offset number from a position identifier.
*/
#define PositionIdGetOffsetNumber(positionId) \
- ((OffsetNumber) *(positionId))
+ ((OffsetNumber) *(positionId))
-#endif /* POS_H */
+#endif /* POS_H */
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 4e0b9b27806..92829732714 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* proc.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: proc.h,v 1.5 1997/08/19 21:39:58 momjian Exp $
+ * $Id: proc.h,v 1.6 1997/09/07 05:01:34 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,46 +15,46 @@
#include <storage/lock.h>
-typedef struct {
- int sleeplock;
- int semNum;
- IpcSemaphoreId semId;
- IpcSemaphoreKey semKey;
-} SEMA;
+typedef struct
+{
+ int sleeplock;
+ int semNum;
+ IpcSemaphoreId semId;
+ IpcSemaphoreKey semKey;
+} SEMA;
/*
* Each backend has:
*/
-typedef struct proc {
+typedef struct proc
+{
- /* proc->links MUST BE THE FIRST ELEMENT OF STRUCT (see ProcWakeup()) */
+ /* proc->links MUST BE THE FIRST ELEMENT OF STRUCT (see ProcWakeup()) */
- SHM_QUEUE links; /* proc can be waiting for one event(lock) */
- SEMA sem; /* ONE semaphore to sleep on */
- int errType; /* error code tells why we woke up */
+ SHM_QUEUE links; /* proc can be waiting for one event(lock) */
+ SEMA sem; /* ONE semaphore to sleep on */
+ int errType; /* error code tells why we woke up */
- int procId; /* unique number for this structure
- * NOT unique per backend, these things
- * are reused after the backend dies.
- */
+ int procId; /* unique number for this structure NOT
+ * unique per backend, these things are
+ * reused after the backend dies. */
- int critSects; /* If critSects > 0, we are in sensitive
- * routines that cannot be recovered when
- * the process fails.
- */
+ int critSects; /* If critSects > 0, we are in sensitive
+ * routines that cannot be recovered when
+ * the process fails. */
- int prio; /* priority for sleep queue */
+ int prio; /* priority for sleep queue */
- TransactionId xid; /* transaction currently being executed
- * by this proc
- */
+ TransactionId xid; /* transaction currently being executed by
+ * this proc */
- LOCK * waitLock; /* Lock we're sleeping on */
- int token; /* info for proc wakeup routines */
- int pid; /* This procs process id */
- short sLocks[MAX_SPINS]; /* Spin lock stats */
- SHM_QUEUE lockQueue; /* locks associated with current transaction */
-} PROC;
+ LOCK *waitLock; /* Lock we're sleeping on */
+ int token; /* info for proc wakeup routines */
+ int pid; /* This procs process id */
+ short sLocks[MAX_SPINS]; /* Spin lock stats */
+ SHM_QUEUE lockQueue; /* locks associated with current
+ * transaction */
+} PROC;
/*
@@ -63,17 +63,18 @@ typedef struct proc {
* of semaphores in each (sys-V) semaphore set allocated. (Be careful not
* to set it to greater 32. Otherwise, the bitmap will overflow.)
*/
-#define MAX_PROC_SEMS 128
-#define PROC_NSEMS_PER_SET 16
+#define MAX_PROC_SEMS 128
+#define PROC_NSEMS_PER_SET 16
-typedef struct procglobal {
- SHMEM_OFFSET freeProcs;
- int numProcs;
- IPCKey currKey;
- int32 freeSemMap[MAX_PROC_SEMS/PROC_NSEMS_PER_SET];
-} PROC_HDR;
+typedef struct procglobal
+{
+ SHMEM_OFFSET freeProcs;
+ int numProcs;
+ IPCKey currKey;
+ int32 freeSemMap[MAX_PROC_SEMS / PROC_NSEMS_PER_SET];
+} PROC_HDR;
-extern PROC *MyProc;
+extern PROC *MyProc;
#define PROC_INCR_SLOCK(lock) if (MyProc) (MyProc->sLocks[(lock)])++
#define PROC_DECR_SLOCK(lock) if (MyProc) (MyProc->sLocks[(lock)])--
@@ -81,30 +82,32 @@ extern PROC *MyProc;
/*
* flags explaining why process woke up
*/
-#define NO_ERROR 0
-#define ERR_TIMEOUT 1
+#define NO_ERROR 0
+#define ERR_TIMEOUT 1
#define ERR_BUFFER_IO 2
-#define MAX_PRIO 50
-#define MIN_PRIO (-1)
+#define MAX_PRIO 50
+#define MIN_PRIO (-1)
extern SPINLOCK ProcStructLock;
/*
* Function Prototypes
*/
-extern void InitProcess(IPCKey key);
-extern void ProcReleaseLocks(void);
-extern bool ProcRemove(int pid);
+extern void InitProcess(IPCKey key);
+extern void ProcReleaseLocks(void);
+extern bool ProcRemove(int pid);
+
/* extern bool ProcKill(int exitStatus, int pid); */
/* make static in storage/lmgr/proc.c -- jolly */
-extern void ProcQueueInit(PROC_QUEUE *queue);
-extern int ProcSleep(PROC_QUEUE *queue, SPINLOCK spinlock, int token,
- int prio, LOCK *lock);
-extern int ProcLockWakeup(PROC_QUEUE *queue, char * ltable, char * lock);
-extern void ProcAddLock(SHM_QUEUE *elem);
-extern void ProcReleaseSpins(PROC *proc);
-extern void ProcFreeAllSemaphores(void);
+extern void ProcQueueInit(PROC_QUEUE * queue);
+extern int
+ProcSleep(PROC_QUEUE * queue, SPINLOCK spinlock, int token,
+ int prio, LOCK * lock);
+extern int ProcLockWakeup(PROC_QUEUE * queue, char *ltable, char *lock);
+extern void ProcAddLock(SHM_QUEUE * elem);
+extern void ProcReleaseSpins(PROC * proc);
+extern void ProcFreeAllSemaphores(void);
-#endif /* PROC_H */
+#endif /* PROC_H */
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index fb52742d362..5812a718717 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* shmem.h--
- * shared memory management structures
+ * shared memory management structures
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: shmem.h,v 1.5 1997/08/19 21:40:01 momjian Exp $
+ * $Id: shmem.h,v 1.6 1997/09/07 05:01:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef SHMEM_H
+#ifndef SHMEM_H
#define SHMEM_H
#include <utils/hsearch.h>
@@ -22,11 +22,12 @@
* offsets relative to the start of the shared memory region(s).
*/
typedef unsigned long SHMEM_OFFSET;
+
#define INVALID_OFFSET (-1)
#define BAD_LOCATION (-1)
/* start of the lowest shared memory region. For now, assume that
- * there is only one shared memory region
+ * there is only one shared memory region
*/
extern SHMEM_OFFSET ShmemBase;
@@ -51,54 +52,57 @@ extern SPINLOCK ShmemLock;
extern SPINLOCK BindingLock;
/* shmemqueue.c */
-typedef struct SHM_QUEUE {
- SHMEM_OFFSET prev;
- SHMEM_OFFSET next;
-} SHM_QUEUE;
+typedef struct SHM_QUEUE
+{
+ SHMEM_OFFSET prev;
+ SHMEM_OFFSET next;
+} SHM_QUEUE;
/* shmem.c */
-extern void ShmemBindingTabReset(void);
-extern void ShmemCreate(unsigned int key, unsigned int size);
-extern int InitShmem(unsigned int key, unsigned int size);
-extern long *ShmemAlloc(unsigned long size);
-extern int ShmemIsValid(unsigned long addr);
-extern HTAB *ShmemInitHash(char *name, long init_size, long max_size,
- HASHCTL *infoP, int hash_flags);
-extern bool ShmemPIDLookup(int pid, SHMEM_OFFSET* locationPtr);
+extern void ShmemBindingTabReset(void);
+extern void ShmemCreate(unsigned int key, unsigned int size);
+extern int InitShmem(unsigned int key, unsigned int size);
+extern long *ShmemAlloc(unsigned long size);
+extern int ShmemIsValid(unsigned long addr);
+extern HTAB *
+ShmemInitHash(char *name, long init_size, long max_size,
+ HASHCTL * infoP, int hash_flags);
+extern bool ShmemPIDLookup(int pid, SHMEM_OFFSET * locationPtr);
extern SHMEM_OFFSET ShmemPIDDestroy(int pid);
-extern long *ShmemInitStruct(char *name, unsigned long size,
- bool *foundPtr);
-extern bool TransactionIdIsInProgress (TransactionId xid);
+extern long *
+ShmemInitStruct(char *name, unsigned long size,
+ bool * foundPtr);
+extern bool TransactionIdIsInProgress(TransactionId xid);
-typedef int TableID;
+typedef int TableID;
/* size constants for the binding table */
- /* max size of data structure string name */
-#define BTABLE_KEYSIZE (50)
- /* data in binding table hash bucket */
+ /* max size of data structure string name */
+#define BTABLE_KEYSIZE (50)
+ /* data in binding table hash bucket */
#define BTABLE_DATASIZE (sizeof(BindingEnt) - BTABLE_KEYSIZE)
- /* maximum size of the binding table */
-#define BTABLE_SIZE (100)
+ /* maximum size of the binding table */
+#define BTABLE_SIZE (100)
/* this is a hash bucket in the binding table */
-typedef struct {
- char key[BTABLE_KEYSIZE]; /* string name */
- unsigned long location; /* location in shared mem */
- unsigned long size; /* numbytes allocated for the
- * structure
- */
-} BindingEnt;
+typedef struct
+{
+ char key[BTABLE_KEYSIZE]; /* string name */
+ unsigned long location; /* location in shared mem */
+ unsigned long size; /* numbytes allocated for the structure */
+} BindingEnt;
/*
* prototypes for functions in shmqueue.c
*/
-extern void SHMQueueInit(SHM_QUEUE *queue);
-extern void SHMQueueElemInit(SHM_QUEUE *queue);
-extern void SHMQueueDelete(SHM_QUEUE *queue);
-extern void SHMQueueInsertTL(SHM_QUEUE *queue, SHM_QUEUE *elem);
-extern void SHMQueueFirst(SHM_QUEUE *queue, Pointer *nextPtrPtr,
- SHM_QUEUE *nextQueue);
-extern bool SHMQueueEmpty(SHM_QUEUE *queue);
-
-#endif /* SHMEM_H */
+extern void SHMQueueInit(SHM_QUEUE * queue);
+extern void SHMQueueElemInit(SHM_QUEUE * queue);
+extern void SHMQueueDelete(SHM_QUEUE * queue);
+extern void SHMQueueInsertTL(SHM_QUEUE * queue, SHM_QUEUE * elem);
+extern void
+SHMQueueFirst(SHM_QUEUE * queue, Pointer * nextPtrPtr,
+ SHM_QUEUE * nextQueue);
+extern bool SHMQueueEmpty(SHM_QUEUE * queue);
+
+#endif /* SHMEM_H */
diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h
index 87f8e00ba6e..fd9025e875f 100644
--- a/src/include/storage/sinval.h
+++ b/src/include/storage/sinval.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* sinval.h--
- * POSTGRES shared cache invalidation communication definitions.
+ * POSTGRES shared cache invalidation communication definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: sinval.h,v 1.4 1996/11/10 03:06:00 momjian Exp $
+ * $Id: sinval.h,v 1.5 1997/09/07 05:01:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef SINVAL_H
+#ifndef SINVAL_H
#define SINVAL_H
#include <storage/itemptr.h>
@@ -18,13 +18,14 @@
extern SPINLOCK SInvalLock;
-extern void CreateSharedInvalidationState(IPCKey key);
-extern void AttachSharedInvalidationState(IPCKey key);
-extern void InitSharedInvalidationState(void);
-extern void RegisterSharedInvalid(int cacheId, Index hashIndex,
- ItemPointer pointer);
-extern void InvalidateSharedInvalid(void (*invalFunction)(),
- void (*resetFunction)());
+extern void CreateSharedInvalidationState(IPCKey key);
+extern void AttachSharedInvalidationState(IPCKey key);
+extern void InitSharedInvalidationState(void);
+extern void
+RegisterSharedInvalid(int cacheId, Index hashIndex,
+ ItemPointer pointer);
+extern void InvalidateSharedInvalid(void (*invalFunction) (),
+ void (*resetFunction) ());
-#endif /* SINVAL_H */
+#endif /* SINVAL_H */
diff --git a/src/include/storage/sinvaladt.h b/src/include/storage/sinvaladt.h
index 9735cb476b1..12efeb2c8b8 100644
--- a/src/include/storage/sinvaladt.h
+++ b/src/include/storage/sinvaladt.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* sinvaladt.h--
- * POSTGRES shared cache invalidation segment definitions.
+ * POSTGRES shared cache invalidation segment definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: sinvaladt.h,v 1.3 1996/11/05 06:11:06 scrappy Exp $
+ * $Id: sinvaladt.h,v 1.4 1997/09/07 05:01:37 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,109 +15,119 @@
#include <storage/itemptr.h>
#include <storage/ipc.h>
-
+
/*
* The structure of the shared cache invaidation segment
*
*/
/*
A------------- Header info --------------
- criticalSectionSemaphoreId
- generalSemaphoreId
- startEntrySection (offset a)
- endEntrySection (offset a + b)
- startFreeSpace (offset relative to B)
- startEntryChain (offset relatiev to B)
- endEntryChain (offset relative to B)
- numEntries
- maxNumEntries
- procState[MaxBackendId] --> limit
- resetState (bool)
-a tag (POSTID)
+ criticalSectionSemaphoreId
+ generalSemaphoreId
+ startEntrySection (offset a)
+ endEntrySection (offset a + b)
+ startFreeSpace (offset relative to B)
+ startEntryChain (offset relatiev to B)
+ endEntryChain (offset relative to B)
+ numEntries
+ maxNumEntries
+ procState[MaxBackendId] --> limit
+ resetState (bool)
+a tag (POSTID)
B------------- Start entry section -------
- SISegEntry --> entryData --> ... (see SharedInvalidData!)
- isfree (bool)
- next (offset to next entry in chain )
-b .... (dynamically growing down)
-C----------------End shared segment -------
+ SISegEntry --> entryData --> ... (see SharedInvalidData!)
+ isfree (bool)
+ next (offset to next entry in chain )
+b .... (dynamically growing down)
+C----------------End shared segment -------
*/
/* Parameters (configurable) *******************************************/
-#define MaxBackendId 32 /* maximum number of backends */
-#define MAXNUMMESSAGES 1000 /* maximum number of messages in seg*/
-
-
-#define InvalidOffset 1000000000 /* a invalid offset (End of chain) */
-
-typedef struct ProcState {
- int limit; /* the number of read messages */
- bool resetState; /* true, if backend has to reset its state */
- int tag; /* special tag, recieved from the postmaster */
-} ProcState;
-
-
-typedef struct SISeg {
- IpcSemaphoreId criticalSectionSemaphoreId; /* semaphore id */
- IpcSemaphoreId generalSemaphoreId; /* semaphore id */
- Offset startEntrySection; /* (offset a) */
- Offset endEntrySection; /* (offset a + b) */
- Offset startFreeSpace; /* (offset relative to B) */
- Offset startEntryChain; /* (offset relative to B) */
- Offset endEntryChain; /* (offset relative to B) */
- int numEntries;
- int maxNumEntries;
- ProcState procState[MaxBackendId]; /* reflects the invalidation state */
- /* here starts the entry section, controlled by offsets */
-} SISeg;
-#define SizeSISeg sizeof(SISeg)
-
-typedef struct SharedInvalidData {
- int cacheId; /* XXX */
- Index hashIndex;
- ItemPointerData pointerData;
-} SharedInvalidData;
-
-typedef SharedInvalidData *SharedInvalid;
-
-
-typedef struct SISegEntry {
- SharedInvalidData entryData; /* the message data */
- bool isfree; /* entry free? */
- Offset next; /* offset to next entry*/
-} SISegEntry;
+#define MaxBackendId 32 /* maximum number of backends */
+#define MAXNUMMESSAGES 1000 /* maximum number of messages in seg */
+
+
+#define InvalidOffset 1000000000 /* a invalid offset (End of
+ * chain) */
+
+typedef struct ProcState
+{
+ int limit; /* the number of read messages */
+ bool resetState; /* true, if backend has to reset its state */
+ int tag; /* special tag, recieved from the
+ * postmaster */
+} ProcState;
+
+
+typedef struct SISeg
+{
+ IpcSemaphoreId criticalSectionSemaphoreId; /* semaphore id */
+ IpcSemaphoreId generalSemaphoreId; /* semaphore id */
+ Offset startEntrySection; /* (offset a) */
+ Offset endEntrySection; /* (offset a + b) */
+ Offset startFreeSpace; /* (offset relative to B) */
+ Offset startEntryChain; /* (offset relative to B) */
+ Offset endEntryChain; /* (offset relative to B) */
+ int numEntries;
+ int maxNumEntries;
+ ProcState procState[MaxBackendId]; /* reflects the
+ * invalidation state */
+ /* here starts the entry section, controlled by offsets */
+} SISeg;
+
+#define SizeSISeg sizeof(SISeg)
+
+typedef struct SharedInvalidData
+{
+ int cacheId; /* XXX */
+ Index hashIndex;
+ ItemPointerData pointerData;
+} SharedInvalidData;
+
+typedef SharedInvalidData *SharedInvalid;
+
+
+typedef struct SISegEntry
+{
+ SharedInvalidData entryData;/* the message data */
+ bool isfree; /* entry free? */
+ Offset next; /* offset to next entry */
+} SISegEntry;
#define SizeOfOneSISegEntry sizeof(SISegEntry)
-
-typedef struct SISegOffsets {
- Offset startSegment; /* always 0 (for now) */
- Offset offsetToFirstEntry; /* A + a = B */
- Offset offsetToEndOfSegemnt; /* A + a + b */
-} SISegOffsets;
+
+typedef struct SISegOffsets
+{
+ Offset startSegment; /* always 0 (for now) */
+ Offset offsetToFirstEntry; /* A + a = B */
+ Offset offsetToEndOfSegemnt; /* A + a + b */
+} SISegOffsets;
/****************************************************************************/
-/* synchronization of the shared buffer access */
-/* access to the buffer is synchronized by the lock manager !! */
+/* synchronization of the shared buffer access */
+/* access to the buffer is synchronized by the lock manager !! */
/****************************************************************************/
#define SI_LockStartValue 255
-#define SI_SharedLock (-1)
+#define SI_SharedLock (-1)
#define SI_ExclusiveLock (-255)
-extern SISeg *shmInvalBuffer;
+extern SISeg *shmInvalBuffer;
/*
* prototypes for functions in sinvaladt.c
*/
-extern int SIBackendInit(SISeg *segInOutP);
-extern int SISegmentInit(bool killExistingSegment, IPCKey key);
-
-extern bool SISetDataEntry(SISeg *segP, SharedInvalidData *data);
-extern void SISetProcStateInvalid(SISeg *segP);
-extern bool SIDelDataEntry(SISeg *segP);
-extern void SIReadEntryData(SISeg *segP, int backendId,
- void (*invalFunction)(), void (*resetFunction)());
-extern void SIDelExpiredDataEntries(SISeg *segP);
-
-#endif /* SINVALADT_H */
+extern int SIBackendInit(SISeg * segInOutP);
+extern int SISegmentInit(bool killExistingSegment, IPCKey key);
+
+extern bool SISetDataEntry(SISeg * segP, SharedInvalidData * data);
+extern void SISetProcStateInvalid(SISeg * segP);
+extern bool SIDelDataEntry(SISeg * segP);
+extern void
+SIReadEntryData(SISeg * segP, int backendId,
+ void (*invalFunction) (), void (*resetFunction) ());
+extern void SIDelExpiredDataEntries(SISeg * segP);
+
+#endif /* SINVALADT_H */
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index 32f4be36357..38c2164f891 100644
--- a/src/include/storage/smgr.h
+++ b/src/include/storage/smgr.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* smgr.h--
- * storage manager switch public interface declarations.
+ * storage manager switch public interface declarations.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: smgr.h,v 1.7 1997/08/19 21:40:03 momjian Exp $
+ * $Id: smgr.h,v 1.8 1997/09/07 05:01:38 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,75 +17,81 @@
#include <storage/block.h>
#include <utils/rel.h>
-#define SM_FAIL 0
-#define SM_SUCCESS 1
+#define SM_FAIL 0
+#define SM_SUCCESS 1
-#define DEFAULT_SMGR 0
+#define DEFAULT_SMGR 0
-extern int smgrinit(void);
-extern int smgrcreate(int16 which, Relation reln);
-extern int smgrunlink(int16 which, Relation reln);
-extern int smgrextend(int16 which, Relation reln, char *buffer);
-extern int smgropen(int16 which, Relation reln);
-extern int smgrclose(int16 which, Relation reln);
-extern int smgrread(int16 which, Relation reln, BlockNumber blocknum,
- char *buffer);
-extern int smgrwrite(int16 which, Relation reln, BlockNumber blocknum,
- char *buffer);
-extern int smgrflush(int16 which, Relation reln, BlockNumber blocknum,
- char *buffer);
-extern int smgrblindwrt(int16 which, char *dbname, char *relname, Oid dbid,
- Oid relid, BlockNumber blkno, char *buffer);
-extern int smgrnblocks(int16 which, Relation reln);
-extern int smgrtruncate(int16 which, Relation reln, int nblocks);
-extern int smgrcommit(void);
-extern bool smgriswo(int16 smgrno);
+extern int smgrinit(void);
+extern int smgrcreate(int16 which, Relation reln);
+extern int smgrunlink(int16 which, Relation reln);
+extern int smgrextend(int16 which, Relation reln, char *buffer);
+extern int smgropen(int16 which, Relation reln);
+extern int smgrclose(int16 which, Relation reln);
+extern int
+smgrread(int16 which, Relation reln, BlockNumber blocknum,
+ char *buffer);
+extern int
+smgrwrite(int16 which, Relation reln, BlockNumber blocknum,
+ char *buffer);
+extern int
+smgrflush(int16 which, Relation reln, BlockNumber blocknum,
+ char *buffer);
+extern int
+smgrblindwrt(int16 which, char *dbname, char *relname, Oid dbid,
+ Oid relid, BlockNumber blkno, char *buffer);
+extern int smgrnblocks(int16 which, Relation reln);
+extern int smgrtruncate(int16 which, Relation reln, int nblocks);
+extern int smgrcommit(void);
+extern bool smgriswo(int16 smgrno);
/* internals: move me elsewhere -- ay 7/94 */
/* in md.c */
-extern int mdinit(void);
-extern int mdcreate(Relation reln);
-extern int mdunlink(Relation reln);
-extern int mdextend(Relation reln, char *buffer);
-extern int mdopen(Relation reln);
-extern int mdclose(Relation reln);
-extern int mdread(Relation reln, BlockNumber blocknum, char *buffer);
-extern int mdwrite(Relation reln, BlockNumber blocknum, char *buffer);
-extern int mdflush(Relation reln, BlockNumber blocknum, char *buffer);
-extern int mdblindwrt(char *dbstr, char *relstr, Oid dbid, Oid relid,
- BlockNumber blkno, char *buffer);
-extern int mdnblocks(Relation reln);
-extern int mdtruncate(Relation reln, int nblocks);
-extern int mdcommit(void);
-extern int mdabort(void);
+extern int mdinit(void);
+extern int mdcreate(Relation reln);
+extern int mdunlink(Relation reln);
+extern int mdextend(Relation reln, char *buffer);
+extern int mdopen(Relation reln);
+extern int mdclose(Relation reln);
+extern int mdread(Relation reln, BlockNumber blocknum, char *buffer);
+extern int mdwrite(Relation reln, BlockNumber blocknum, char *buffer);
+extern int mdflush(Relation reln, BlockNumber blocknum, char *buffer);
+extern int
+mdblindwrt(char *dbstr, char *relstr, Oid dbid, Oid relid,
+ BlockNumber blkno, char *buffer);
+extern int mdnblocks(Relation reln);
+extern int mdtruncate(Relation reln, int nblocks);
+extern int mdcommit(void);
+extern int mdabort(void);
/* mm.c */
extern SPINLOCK MMCacheLock;
-extern int mminit(void);
-extern int mmshutdown(void);
-extern int mmcreate(Relation reln);
-extern int mmunlink(Relation reln);
-extern int mmextend(Relation reln, char *buffer);
-extern int mmopen(Relation reln);
-extern int mmclose(Relation reln);
-extern int mmread(Relation reln, BlockNumber blocknum, char *buffer);
-extern int mmwrite(Relation reln, BlockNumber blocknum, char *buffer);
-extern int mmflush(Relation reln, BlockNumber blocknum, char *buffer);
-extern int mmblindwrt(char *dbstr, char *relstr, Oid dbid, Oid relid,
- BlockNumber blkno, char *buffer);
-extern int mmnblocks(Relation reln);
-extern int mmcommit(void);
-extern int mmabort(void);
-extern int MMShmemSize(void);
+extern int mminit(void);
+extern int mmshutdown(void);
+extern int mmcreate(Relation reln);
+extern int mmunlink(Relation reln);
+extern int mmextend(Relation reln, char *buffer);
+extern int mmopen(Relation reln);
+extern int mmclose(Relation reln);
+extern int mmread(Relation reln, BlockNumber blocknum, char *buffer);
+extern int mmwrite(Relation reln, BlockNumber blocknum, char *buffer);
+extern int mmflush(Relation reln, BlockNumber blocknum, char *buffer);
+extern int
+mmblindwrt(char *dbstr, char *relstr, Oid dbid, Oid relid,
+ BlockNumber blkno, char *buffer);
+extern int mmnblocks(Relation reln);
+extern int mmcommit(void);
+extern int mmabort(void);
+extern int MMShmemSize(void);
/* smgrtype.c */
-extern char *smgrout(int2 i);
-extern int2 smgrin(char *s);
-extern bool smgreq(int2 a, int2 b);
-extern bool smgrne(int2 a, int2 b);
+extern char *smgrout(int2 i);
+extern int2 smgrin(char *s);
+extern bool smgreq(int2 a, int2 b);
+extern bool smgrne(int2 a, int2 b);
-#endif /* SMGR_H */
+#endif /* SMGR_H */
diff --git a/src/include/storage/spin.h b/src/include/storage/spin.h
index 0000af883b1..0ee24b5ab4b 100644
--- a/src/include/storage/spin.h
+++ b/src/include/storage/spin.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* spin.h--
- * synchronization routines
+ * synchronization routines
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: spin.h,v 1.3 1997/08/19 21:40:03 momjian Exp $
+ * $Id: spin.h,v 1.4 1997/09/07 05:01:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef SPIN_H
+#ifndef SPIN_H
#define SPIN_H
#include <storage/ipc.h>
-/*
+/*
* two implementations of spin locks
*
* sequent, sparc, sun3: real spin locks. uses a TAS instruction; see
@@ -25,11 +25,11 @@
*
*/
-typedef int SPINLOCK;
+typedef int SPINLOCK;
-extern bool CreateSpinlocks(IPCKey key);
-extern bool InitSpinLocks(int init, IPCKey key);
-extern void SpinAcquire(SPINLOCK lock);
-extern void SpinRelease(SPINLOCK lock);
+extern bool CreateSpinlocks(IPCKey key);
+extern bool InitSpinLocks(int init, IPCKey key);
+extern void SpinAcquire(SPINLOCK lock);
+extern void SpinRelease(SPINLOCK lock);
-#endif /* SPIN_H */
+#endif /* SPIN_H */
diff --git a/src/include/strdup.h b/src/include/strdup.h
index 9e07a0f18b8..038446494c7 100644
--- a/src/include/strdup.h
+++ b/src/include/strdup.h
@@ -5,4 +5,4 @@
The Postgres strdup() is in src/utils/strdup.c.
*/
-extern char* strdup(char const*);
+extern char *strdup(char const *);
diff --git a/src/include/tcop/dest.h b/src/include/tcop/dest.h
index 7878ed9d41e..aa74fafbfe7 100644
--- a/src/include/tcop/dest.h
+++ b/src/include/tcop/dest.h
@@ -1,32 +1,32 @@
/*-------------------------------------------------------------------------
*
* dest.h--
- * Whenever the backend is submitted a query, the results
- * have to go someplace - either to the standard output,
- * to a local portal buffer or to a remote portal buffer.
+ * Whenever the backend is submitted a query, the results
+ * have to go someplace - either to the standard output,
+ * to a local portal buffer or to a remote portal buffer.
*
- * - stdout is the destination only when we are running a
- * backend without a postmaster and are returning results
- * back to the user.
+ * - stdout is the destination only when we are running a
+ * backend without a postmaster and are returning results
+ * back to the user.
*
- * - a local portal buffer is the destination when a backend
- * executes a user-defined function which calls PQexec() or
- * PQfn(). In this case, the results are collected into a
- * PortalBuffer which the user's function may diddle with.
+ * - a local portal buffer is the destination when a backend
+ * executes a user-defined function which calls PQexec() or
+ * PQfn(). In this case, the results are collected into a
+ * PortalBuffer which the user's function may diddle with.
*
- * - a remote portal buffer is the destination when we are
- * running a backend with a frontend and the frontend executes
- * PQexec() or PQfn(). In this case, the results are sent
- * to the frontend via the pq_ functions.
+ * - a remote portal buffer is the destination when we are
+ * running a backend with a frontend and the frontend executes
+ * PQexec() or PQfn(). In this case, the results are sent
+ * to the frontend via the pq_ functions.
+ *
+ * - None is the destination when the system executes
+ * a query internally. This is not used now but it may be
+ * useful for the parallel optimiser/executor.
*
- * - None is the destination when the system executes
- * a query internally. This is not used now but it may be
- * useful for the parallel optimiser/executor.
- *
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: dest.h,v 1.8 1997/08/29 09:06:27 vadim Exp $
+ * $Id: dest.h,v 1.9 1997/09/07 05:01:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -36,40 +36,44 @@
#include <access/tupdesc.h>
/* ----------------
- * CommandDest is used to allow the results of calling
- * pg_eval() to go to the right place.
+ * CommandDest is used to allow the results of calling
+ * pg_eval() to go to the right place.
* ----------------
*/
-typedef enum {
- None, /* results are discarded */
- Debug, /* results go to debugging output */
- Local, /* results go in local portal buffer */
- Remote, /* results sent to frontend process */
- CopyBegin, /* results sent to frontend process but are strings */
- CopyEnd, /* results sent to frontend process but are strings */
- RemoteInternal, /* results sent to frontend process in internal
- (binary) form */
- SPI /* results sent to SPI manager */
-} CommandDest;
+typedef enum
+{
+ None, /* results are discarded */
+ Debug, /* results go to debugging output */
+ Local, /* results go in local portal buffer */
+ Remote, /* results sent to frontend process */
+ CopyBegin, /* results sent to frontend process but
+ * are strings */
+ CopyEnd, /* results sent to frontend process but
+ * are strings */
+ RemoteInternal, /* results sent to frontend process in
+ * internal (binary) form */
+ SPI /* results sent to SPI manager */
+} CommandDest;
/* AttrInfo* replaced with TupleDesc, now that TupleDesc also has within it
the number of attributes
typedef struct AttrInfo {
- int numAttr;
- AttributeTupleForm *attrs;
+ int numAttr;
+ AttributeTupleForm *attrs;
} AttrInfo;
*/
-extern void (*DestToFunction(CommandDest dest))();
-extern void EndCommand(char *commandTag, CommandDest dest);
-extern void SendCopyBegin(void);
-extern void ReceiveCopyBegin(void);
-extern void NullCommand(CommandDest dest);
-extern void BeginCommand(char *pname, int operation, TupleDesc attinfo,
+extern void (*DestToFunction(CommandDest dest)) ();
+extern void EndCommand(char *commandTag, CommandDest dest);
+extern void SendCopyBegin(void);
+extern void ReceiveCopyBegin(void);
+extern void NullCommand(CommandDest dest);
+extern void
+BeginCommand(char *pname, int operation, TupleDesc attinfo,
bool isIntoRel, bool isIntoPortal, char *tag,
CommandDest dest);
-extern void UpdateCommandInfo (int operation, Oid lastoid, uint32 tuples);
+extern void UpdateCommandInfo(int operation, Oid lastoid, uint32 tuples);
-#endif /* DEST_H */
+#endif /* DEST_H */
diff --git a/src/include/tcop/fastpath.h b/src/include/tcop/fastpath.h
index a46d6f2d6f1..96b5f598eac 100644
--- a/src/include/tcop/fastpath.h
+++ b/src/include/tcop/fastpath.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* fastpath.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: fastpath.h,v 1.1 1996/08/28 07:27:50 scrappy Exp $
+ * $Id: fastpath.h,v 1.2 1997/09/07 05:01:46 momjian Exp $
*
* NOTES
- * This information pulled out of tcop/fastpath.c and put
- * here so that the PQfn() in be-pqexec.c could access it.
- * -cim 2/26/91
+ * This information pulled out of tcop/fastpath.c and put
+ * here so that the PQfn() in be-pqexec.c could access it.
+ * -cim 2/26/91
*
*-------------------------------------------------------------------------
*/
@@ -19,13 +19,13 @@
#define FASTPATH_H
/* ----------------
- * fastpath #defines
+ * fastpath #defines
* ----------------
*/
-#define VAR_LENGTH_RESULT (-1)
-#define VAR_LENGTH_ARG (-5)
-#define MAX_STRING_LENGTH 256
+#define VAR_LENGTH_RESULT (-1)
+#define VAR_LENGTH_ARG (-5)
+#define MAX_STRING_LENGTH 256
-extern int HandleFunctionRequest(void);
+extern int HandleFunctionRequest(void);
-#endif /* FASTPATH_H */
+#endif /* FASTPATH_H */
diff --git a/src/include/tcop/pquery.h b/src/include/tcop/pquery.h
index 9f45684c5b5..9d9117315b8 100644
--- a/src/include/tcop/pquery.h
+++ b/src/include/tcop/pquery.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* pquery.h--
- * prototypes for pquery.c.
+ * prototypes for pquery.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pquery.h,v 1.4 1997/08/19 21:40:09 momjian Exp $
+ * $Id: pquery.h,v 1.5 1997/09/07 05:01:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,19 +15,21 @@
#include <executor/execdesc.h>
-/* moved to execdesc.h
+/* moved to execdesc.h
extern QueryDesc *CreateQueryDesc(Query *parsetree, Plan *plantree,
- CommandDest dest);
+ CommandDest dest);
*/
-extern EState *CreateExecutorState(void);
+extern EState *CreateExecutorState(void);
-extern void ProcessPortal(char *portalName, Query *parseTree,
- Plan *plan, EState *state, TupleDesc attinfo,
+extern void
+ProcessPortal(char *portalName, Query * parseTree,
+ Plan * plan, EState * state, TupleDesc attinfo,
CommandDest dest);
-extern void ProcessQuery(Query *parsetree, Plan *plan, char *argv[],
- Oid *typev, int nargs, CommandDest dest);
+extern void
+ProcessQuery(Query * parsetree, Plan * plan, char *argv[],
+ Oid * typev, int nargs, CommandDest dest);
-#endif /* pqueryIncluded */
+#endif /* pqueryIncluded */
diff --git a/src/include/tcop/tcopdebug.h b/src/include/tcop/tcopdebug.h
index ecec82c652f..a4512f6686c 100644
--- a/src/include/tcop/tcopdebug.h
+++ b/src/include/tcop/tcopdebug.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* tcopdebug.h--
- * #defines governing debugging behaviour in the traffic cop
+ * #defines governing debugging behaviour in the traffic cop
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: tcopdebug.h,v 1.1 1996/08/28 07:27:52 scrappy Exp $
+ * $Id: tcopdebug.h,v 1.2 1997/09/07 05:01:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,30 +14,30 @@
#define TCOPDEBUG_H
/* ----------------------------------------------------------------
- * debugging defines.
+ * debugging defines.
*
- * If you want certain debugging behaviour, then #define
- * the variable to 1, else #undef it. -cim 10/26/89
+ * If you want certain debugging behaviour, then #define
+ * the variable to 1, else #undef it. -cim 10/26/89
* ----------------------------------------------------------------
*/
/* ----------------
- * TCOP_SHOWSTATS controls whether or not buffer and
- * access method statistics are shown for each query. -cim 2/9/89
+ * TCOP_SHOWSTATS controls whether or not buffer and
+ * access method statistics are shown for each query. -cim 2/9/89
* ----------------
*/
#undef TCOP_SHOWSTATS
/* ----------------
- * TCOP_DONTUSENEWLINE controls the default setting of
- * the UseNewLine variable in postgres.c
+ * TCOP_DONTUSENEWLINE controls the default setting of
+ * the UseNewLine variable in postgres.c
* ----------------
*/
#undef TCOP_DONTUSENEWLINE
/* ----------------------------------------------------------------
- * #defines controlled by above definitions
+ * #defines controlled by above definitions
* ----------------------------------------------------------------
*/
-#endif /* TCOPDEBUG_H */
+#endif /* TCOPDEBUG_H */
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 15af78b84fd..07a3cff98d0 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* tcopprot.h--
- * prototypes for postgres.c.
+ * prototypes for postgres.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: tcopprot.h,v 1.4 1997/08/19 21:40:10 momjian Exp $
+ * $Id: tcopprot.h,v 1.5 1997/09/07 05:01:56 momjian Exp $
*
* OLD COMMENTS
- * This file was created so that other c files could get the two
- * function prototypes without having to include tcop.h which single
- * handedly includes the whole f*cking tree -- mer 5 Nov. 1991
+ * This file was created so that other c files could get the two
+ * function prototypes without having to include tcop.h which single
+ * handedly includes the whole f*cking tree -- mer 5 Nov. 1991
*
*-------------------------------------------------------------------------
*/
@@ -22,17 +22,20 @@
#include <parser/parse_query.h>
#ifndef BOOTSTRAP_INCLUDE
-extern List *pg_plan(char *query_string, Oid *typev, int nargs,
- QueryTreeList **queryListP, CommandDest dest);
-extern void pg_eval(char *query_string, char **argv, Oid *typev, int nargs);
-extern void pg_eval_dest(char *query_string, char **argv, Oid *typev,
+extern List *
+pg_plan(char *query_string, Oid * typev, int nargs,
+ QueryTreeList ** queryListP, CommandDest dest);
+extern void pg_eval(char *query_string, char **argv, Oid * typev, int nargs);
+extern void
+pg_eval_dest(char *query_string, char **argv, Oid * typev,
int nargs, CommandDest dest);
-#endif /* BOOTSTRAP_HEADER */
-extern void handle_warn(SIGNAL_ARGS);
-extern void die(SIGNAL_ARGS);
-extern int PostgresMain(int argc, char *argv[]);
-extern void ResetUsage(void);
-extern void ShowUsage(void);
+#endif /* BOOTSTRAP_HEADER */
-#endif /* tcopprotIncluded */
+extern void handle_warn(SIGNAL_ARGS);
+extern void die(SIGNAL_ARGS);
+extern int PostgresMain(int argc, char *argv[]);
+extern void ResetUsage(void);
+extern void ShowUsage(void);
+
+#endif /* tcopprotIncluded */
diff --git a/src/include/tcop/utility.h b/src/include/tcop/utility.h
index ec0842dd3a3..f5242ff4738 100644
--- a/src/include/tcop/utility.h
+++ b/src/include/tcop/utility.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* utility.h--
- * prototypes for utility.c.
+ * prototypes for utility.c.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: utility.h,v 1.2 1996/11/04 12:07:05 scrappy Exp $
+ * $Id: utility.h,v 1.3 1997/09/07 05:01:58 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,6 +15,6 @@
#include <executor/execdesc.h>
-extern void ProcessUtility(Node *parsetree, CommandDest dest);
+extern void ProcessUtility(Node * parsetree, CommandDest dest);
-#endif /* UTILITY_H */
+#endif /* UTILITY_H */
diff --git a/src/include/tcop/variable.h b/src/include/tcop/variable.h
index a0f10801eac..a687d8fed6f 100644
--- a/src/include/tcop/variable.h
+++ b/src/include/tcop/variable.h
@@ -1,26 +1,29 @@
/*
- * Headers for handling of 'SET var TO', 'SHOW var' and 'RESET var'
+ * Headers for handling of 'SET var TO', 'SHOW var' and 'RESET var'
* statements
*
- * $Id: variable.h,v 1.4 1997/04/23 05:52:32 vadim Exp $
+ * $Id: variable.h,v 1.5 1997/09/07 05:02:01 momjian Exp $
*
*/
-enum DateFormat { Date_Postgres, Date_SQL, Date_ISO };
+enum DateFormat
+{
+ Date_Postgres, Date_SQL, Date_ISO
+};
/*-----------------------------------------------------------------------*/
struct PGVariables
- {
+{
struct
- {
- bool euro;
+ {
+ bool euro;
enum DateFormat format;
- } date;
- };
+ } date;
+};
extern struct PGVariables PGVariables;
/*-----------------------------------------------------------------------*/
-bool SetPGVariable(const char *, const char *);
-bool GetPGVariable(const char *);
-bool ResetPGVariable(const char *);
+bool SetPGVariable(const char *, const char *);
+bool GetPGVariable(const char *);
+bool ResetPGVariable(const char *);
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 5d9451d9689..f6e6a75ab5d 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* acl.h--
- * Definition of (and support for) access control list data structures.
+ * Definition of (and support for) access control list data structures.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: acl.h,v 1.7 1997/08/19 21:40:18 momjian Exp $
+ * $Id: acl.h,v 1.8 1997/09/07 05:02:05 momjian Exp $
*
* NOTES
- * For backward-compatability purposes we have to allow there
- * to be a null ACL in a pg_class tuple. This will be defined as
- * meaning "no protection" (i.e., old catalogs get old semantics).
+ * For backward-compatability purposes we have to allow there
+ * to be a null ACL in a pg_class tuple. This will be defined as
+ * meaning "no protection" (i.e., old catalogs get old semantics).
*
- * The AclItems in an ACL array are currently kept in sorted order.
- * Things will break hard if you change that without changing the
- * code wherever this is included.
+ * The AclItems in an ACL array are currently kept in sorted order.
+ * Things will break hard if you change that without changing the
+ * code wherever this is included.
*
*-------------------------------------------------------------------------
*/
@@ -26,99 +26,106 @@
#include <utils/array.h>
/*
- * AclId system identifier for the user, group, etc.
- * XXX currently UNIX uid for users...
+ * AclId system identifier for the user, group, etc.
+ * XXX currently UNIX uid for users...
*/
-typedef uint32 AclId;
-#define ACL_ID_WORLD 0 /* XXX only idtype should be checked */
+typedef uint32 AclId;
+
+#define ACL_ID_WORLD 0 /* XXX only idtype should be checked */
/*
* AclIdType tag that describes if the AclId is a user, group, etc.
*/
-typedef uint8 AclIdType;
-#define ACL_IDTYPE_WORLD 0x00
-#define ACL_IDTYPE_UID 0x01 /* user id - from pg_user */
-#define ACL_IDTYPE_GID 0x02 /* group id - from pg_group */
+typedef uint8 AclIdType;
+
+#define ACL_IDTYPE_WORLD 0x00
+#define ACL_IDTYPE_UID 0x01 /* user id - from pg_user */
+#define ACL_IDTYPE_GID 0x02 /* group id - from pg_group */
/*
- * AclMode the actual permissions
- * XXX should probably use bit.h routines.
- * XXX should probably also stuff the modechg cruft in the
- * high bits, too.
+ * AclMode the actual permissions
+ * XXX should probably use bit.h routines.
+ * XXX should probably also stuff the modechg cruft in the
+ * high bits, too.
*/
-typedef uint8 AclMode;
-#define ACL_NO 0 /* no permissions */
-#define ACL_AP (1<<0) /* append */
-#define ACL_RD (1<<1) /* read */
-#define ACL_WR (1<<2) /* write (append/delete/replace) */
-#define ACL_RU (1<<3) /* place rules */
-#define N_ACL_MODES 4
-
-#define ACL_MODECHG_ADD 1
-#define ACL_MODECHG_DEL 2
-#define ACL_MODECHG_EQL 3
+typedef uint8 AclMode;
+
+#define ACL_NO 0 /* no permissions */
+#define ACL_AP (1<<0) /* append */
+#define ACL_RD (1<<1) /* read */
+#define ACL_WR (1<<2) /* write (append/delete/replace) */
+#define ACL_RU (1<<3) /* place rules */
+#define N_ACL_MODES 4
+
+#define ACL_MODECHG_ADD 1
+#define ACL_MODECHG_DEL 2
+#define ACL_MODECHG_EQL 3
/* change this line if you want to set the default acl permission */
-#define ACL_WORLD_DEFAULT (ACL_RD)
-/* #define ACL_WORLD_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU) */
-#define ACL_OWNER_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU)
+#define ACL_WORLD_DEFAULT (ACL_RD)
+/* #define ACL_WORLD_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU) */
+#define ACL_OWNER_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU)
/*
* AclItem
*/
-typedef struct AclItem {
- AclId ai_id;
- AclIdType ai_idtype;
- AclMode ai_mode;
-} AclItem;
-/* Note: if the size of AclItem changes,
+typedef struct AclItem
+{
+ AclId ai_id;
+ AclIdType ai_idtype;
+ AclMode ai_mode;
+} AclItem;
+
+/* Note: if the size of AclItem changes,
change the aclitem typlen in pg_type.h */
/*
- * The value of the first dimension-array element. Since these arrays
+ * The value of the first dimension-array element. Since these arrays
* always have a lower-bound of 0, this is the same as the number of
* elements in the array.
*/
-#define ARR_DIM0(a) (((unsigned *) (((char *) a) + sizeof(ArrayType)))[0])
+#define ARR_DIM0(a) (((unsigned *) (((char *) a) + sizeof(ArrayType)))[0])
/*
- * Acl a one-dimensional POSTGRES array of AclItem
+ * Acl a one-dimensional POSTGRES array of AclItem
*/
typedef ArrayType Acl;
-#define ACL_NUM(ACL) ARR_DIM0(ACL)
-#define ACL_DAT(ACL) ((AclItem *) ARR_DATA_PTR(ACL))
-#define ACL_N_SIZE(N) \
- ((unsigned) (ARR_OVERHEAD(1) + ((N) * sizeof(AclItem))))
-#define ACL_SIZE(ACL) ARR_SIZE(ACL)
+
+#define ACL_NUM(ACL) ARR_DIM0(ACL)
+#define ACL_DAT(ACL) ((AclItem *) ARR_DATA_PTR(ACL))
+#define ACL_N_SIZE(N) \
+ ((unsigned) (ARR_OVERHEAD(1) + ((N) * sizeof(AclItem))))
+#define ACL_SIZE(ACL) ARR_SIZE(ACL)
/*
- * IdList a one-dimensional POSTGRES array of AclId
+ * IdList a one-dimensional POSTGRES array of AclId
*/
typedef ArrayType IdList;
-#define IDLIST_NUM(IDL) ARR_DIM0(IDL)
-#define IDLIST_DAT(IDL) ((AclId *) ARR_DATA_PTR(IDL))
-#define IDLIST_N_SIZE(N) \
- ((unsigned) (ARR_OVERHEAD(1) + ((N) * sizeof(AclId))))
-#define IDLIST_SIZE(IDL) ARR_SIZE(IDL)
-
-#define ACL_MODECHG_STR "+-=" /* list of valid characters */
-#define ACL_MODECHG_ADD_CHR '+'
-#define ACL_MODECHG_DEL_CHR '-'
-#define ACL_MODECHG_EQL_CHR '='
-#define ACL_MODE_STR "arwR" /* list of valid characters */
-#define ACL_MODE_AP_CHR 'a'
-#define ACL_MODE_RD_CHR 'r'
-#define ACL_MODE_WR_CHR 'w'
-#define ACL_MODE_RU_CHR 'R'
+
+#define IDLIST_NUM(IDL) ARR_DIM0(IDL)
+#define IDLIST_DAT(IDL) ((AclId *) ARR_DATA_PTR(IDL))
+#define IDLIST_N_SIZE(N) \
+ ((unsigned) (ARR_OVERHEAD(1) + ((N) * sizeof(AclId))))
+#define IDLIST_SIZE(IDL) ARR_SIZE(IDL)
+
+#define ACL_MODECHG_STR "+-=" /* list of valid characters */
+#define ACL_MODECHG_ADD_CHR '+'
+#define ACL_MODECHG_DEL_CHR '-'
+#define ACL_MODECHG_EQL_CHR '='
+#define ACL_MODE_STR "arwR" /* list of valid characters */
+#define ACL_MODE_AP_CHR 'a'
+#define ACL_MODE_RD_CHR 'r'
+#define ACL_MODE_WR_CHR 'w'
+#define ACL_MODE_RU_CHR 'R'
/* result codes for pg_aclcheck */
-#define ACLCHECK_OK 0
-#define ACLCHECK_NO_PRIV 1
-#define ACLCHECK_NO_CLASS 2
-#define ACLCHECK_NOT_OWNER 3
+#define ACLCHECK_OK 0
+#define ACLCHECK_NO_PRIV 1
+#define ACLCHECK_NO_CLASS 2
+#define ACLCHECK_NOT_OWNER 3
/* warning messages. set these in aclchk.c. */
-extern char *aclcheck_error_strings[];
+extern char *aclcheck_error_strings[];
/*
* Enable ACL execution tracing and table dumps
@@ -126,41 +133,43 @@ extern char *aclcheck_error_strings[];
/*#define ACLDEBUG_TRACE*/
/*
- * routines used internally (parser, etc.)
+ * routines used internally (parser, etc.)
*/
-extern Acl *aclownerdefault(AclId ownerid);
-extern Acl *acldefault(void);
-extern Acl *aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg);
+extern Acl *aclownerdefault(AclId ownerid);
+extern Acl *acldefault(void);
+extern Acl *aclinsert3(Acl * old_acl, AclItem * mod_aip, unsigned modechg);
-extern char* aclmakepriv(char* old_privlist, char new_priv);
-extern char* aclmakeuser(char* user_type, char* user);
-extern ChangeACLStmt* makeAclStmt(char* privs, List* rel_list, char* grantee,
- char grant_or_revoke);
+extern char *aclmakepriv(char *old_privlist, char new_priv);
+extern char *aclmakeuser(char *user_type, char *user);
+extern ChangeACLStmt *
+makeAclStmt(char *privs, List * rel_list, char *grantee,
+ char grant_or_revoke);
/*
* exported routines (from acl.c)
*/
-extern Acl *makeacl(int n);
+extern Acl *makeacl(int n);
extern AclItem *aclitemin(char *s);
-extern char *aclitemout(AclItem *aip);
-extern Acl *aclinsert(Acl *old_acl, AclItem *mod_aip);
-extern Acl *aclremove(Acl *old_acl, AclItem *mod_aip);
-extern int32 aclcontains(Acl *acl, AclItem *aip);
+extern char *aclitemout(AclItem * aip);
+extern Acl *aclinsert(Acl * old_acl, AclItem * mod_aip);
+extern Acl *aclremove(Acl * old_acl, AclItem * mod_aip);
+extern int32 aclcontains(Acl * acl, AclItem * aip);
/*
* prototypes for functions in aclchk.c
*/
-extern void ChangeAcl(char *relname, AclItem *mod_aip, unsigned modechg);
-extern AclId get_grosysid(char *groname);
-extern char *get_groname(AclId grosysid);
+extern void ChangeAcl(char *relname, AclItem * mod_aip, unsigned modechg);
+extern AclId get_grosysid(char *groname);
+extern char *get_groname(AclId grosysid);
/* XXX move these elsewhere -pma */
-extern int32 pg_aclcheck(char *relname, char *usename, AclMode mode);
-extern int32 pg_ownercheck(char *usename, char *value, int cacheid);
-extern int32 pg_func_ownercheck(char *usename, char *funcname,
- int nargs, Oid *arglist);
-extern int32 pg_aggr_ownercheck(char *usename, char *aggname,
- Oid basetypeID);
-
-#endif /* ACL_H */
-
+extern int32 pg_aclcheck(char *relname, char *usename, AclMode mode);
+extern int32 pg_ownercheck(char *usename, char *value, int cacheid);
+extern int32
+pg_func_ownercheck(char *usename, char *funcname,
+ int nargs, Oid * arglist);
+extern int32
+pg_aggr_ownercheck(char *usename, char *aggname,
+ Oid basetypeID);
+
+#endif /* ACL_H */
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 2e574323637..e2cd808cbf9 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* array.h--
- * Utilities for the new array code. Contain prototypes from the
- * following files:
- * utils/adt/arrayfuncs.c
- * utils/adt/arrayutils.c
- * utils/adt/chunk.c
+ * Utilities for the new array code. Contain prototypes from the
+ * following files:
+ * utils/adt/arrayfuncs.c
+ * utils/adt/arrayutils.c
+ * utils/adt/chunk.c
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: array.h,v 1.4 1997/08/19 21:40:21 momjian Exp $
+ * $Id: array.h,v 1.5 1997/09/07 05:02:07 momjian Exp $
*
* NOTES
- * XXX the data array should be LONGALIGN'd -- notice that the array
- * allocation code does not allocate the extra space required for this,
- * even though the array-packing code does the LONGALIGNs.
+ * XXX the data array should be LONGALIGN'd -- notice that the array
+ * allocation code does not allocate the extra space required for this,
+ * even though the array-packing code does the LONGALIGNs.
*
*-------------------------------------------------------------------------
*/
@@ -24,11 +24,12 @@
#include <stdio.h>
-typedef struct {
- int size; /* total array size (in bytes) */
- int ndim; /* # of dimensions */
- int flags; /* implementation flags */
-} ArrayType;
+typedef struct
+{
+ int size; /* total array size (in bytes) */
+ int ndim; /* # of dimensions */
+ int flags; /* implementation flags */
+} ArrayType;
/*
* bitmask of ArrayType flags field:
@@ -36,30 +37,30 @@ typedef struct {
* 2nd bit - chunk flag (array is chunked if set)
* 3rd,4th,&5th bit - large object type (used only if bit 1 is set)
*/
-#define ARR_LOB_FLAG (0x1)
-#define ARR_CHK_FLAG (0x2)
-#define ARR_OBJ_MASK (0x1c)
+#define ARR_LOB_FLAG (0x1)
+#define ARR_CHK_FLAG (0x2)
+#define ARR_OBJ_MASK (0x1c)
-#define ARR_FLAGS(a) ((ArrayType *) a)->flags
-#define ARR_SIZE(a) (((ArrayType *) a)->size)
+#define ARR_FLAGS(a) ((ArrayType *) a)->flags
+#define ARR_SIZE(a) (((ArrayType *) a)->size)
-#define ARR_NDIM(a) (((ArrayType *) a)->ndim)
-#define ARR_NDIM_PTR(a) (&(((ArrayType *) a)->ndim))
+#define ARR_NDIM(a) (((ArrayType *) a)->ndim)
+#define ARR_NDIM_PTR(a) (&(((ArrayType *) a)->ndim))
#define ARR_IS_LO(a) \
- (((ArrayType *) a)->flags & ARR_LOB_FLAG)
+ (((ArrayType *) a)->flags & ARR_LOB_FLAG)
#define SET_LO_FLAG(f,a) \
- (((ArrayType *) a)->flags |= ((f) ? ARR_LOB_FLAG : 0x0))
+ (((ArrayType *) a)->flags |= ((f) ? ARR_LOB_FLAG : 0x0))
#define ARR_IS_CHUNKED(a) \
- (((ArrayType *) a)->flags & ARR_CHK_FLAG)
+ (((ArrayType *) a)->flags & ARR_CHK_FLAG)
#define SET_CHUNK_FLAG(f,a) \
- (((ArrayType *) a)->flags |= ((f) ? ARR_CHK_FLAG : 0x0))
+ (((ArrayType *) a)->flags |= ((f) ? ARR_CHK_FLAG : 0x0))
#define ARR_OBJ_TYPE(a) \
- ((ARR_FLAGS(a) & ARR_OBJ_MASK) >> 2)
+ ((ARR_FLAGS(a) & ARR_OBJ_MASK) >> 2)
#define SET_OBJ_TYPE(f,a) \
- ((ARR_FLAGS(a)&= ~ARR_OBJ_MASK), (ARR_FLAGS(a)|=((f<<2)&ARR_OBJ_MASK)))
+ ((ARR_FLAGS(a)&= ~ARR_OBJ_MASK), (ARR_FLAGS(a)|=((f<<2)&ARR_OBJ_MASK)))
/*
* ARR_DIMS returns a pointer to an array of array dimensions (number of
@@ -73,23 +74,23 @@ typedef struct {
* Unlike C, the default lower bound is 1.
*/
#define ARR_DIMS(a) \
- ((int *) (((char *) a) + sizeof(ArrayType)))
+ ((int *) (((char *) a) + sizeof(ArrayType)))
#define ARR_LBOUND(a) \
- ((int *) (((char *) a) + sizeof(ArrayType) + \
- (sizeof(int) * (((ArrayType *) a)->ndim))))
+ ((int *) (((char *) a) + sizeof(ArrayType) + \
+ (sizeof(int) * (((ArrayType *) a)->ndim))))
/*
* Returns a pointer to the actual array data.
*/
#define ARR_DATA_PTR(a) \
- (((char *) a) + \
- DOUBLEALIGN(sizeof(ArrayType) + 2 * (sizeof(int) * (a)->ndim)))
+ (((char *) a) + \
+ DOUBLEALIGN(sizeof(ArrayType) + 2 * (sizeof(int) * (a)->ndim)))
/*
* The total array header size for an array of dimension n (in bytes).
*/
-#define ARR_OVERHEAD(n) \
- (DOUBLEALIGN(sizeof(ArrayType) + 2 * (n) * sizeof(int)))
+#define ARR_OVERHEAD(n) \
+ (DOUBLEALIGN(sizeof(ArrayType) + 2 * (n) * sizeof(int)))
/*------------------------------------------------------------------------
* Miscellaneous helper definitions and routines for arrayfuncs.c
@@ -98,37 +99,43 @@ typedef struct {
/* #if defined(irix5) */
/* #define RETURN_NULL {*isNull = true; return(0); }*/
-/* #else*/ /* irix5 */
+ /* #else*//* irix5 */
#define RETURN_NULL {*isNull = true; return(0); }
-/* #endif */ /* irix5 */
-#define NAME_LEN 30
+ /* #endif *//* irix5 */
+#define NAME_LEN 30
#define MAX_BUFF_SIZE (1 << 13)
-typedef struct {
- char lo_name[NAME_LEN];
- int C[MAXDIM];
-} CHUNK_INFO;
+typedef struct
+{
+ char lo_name[NAME_LEN];
+ int C[MAXDIM];
+} CHUNK_INFO;
/*
* prototypes for functions defined in arrayfuncs.c
*/
-extern char *array_in(char *string, Oid element_type);
-extern char *array_out(ArrayType *v, Oid element_type);
-extern char *array_dims(ArrayType *v, bool *isNull);
-extern Datum array_ref(ArrayType *array, int n, int indx[], int reftype,
- int elmlen, int arraylen, bool *isNull);
-extern Datum array_clip(ArrayType *array, int n, int upperIndx[],
- int lowerIndx[], int reftype, int len, bool *isNull);
-extern char *array_set(ArrayType *array, int n, int indx[], char *dataPtr,
- int reftype, int elmlen, int arraylen, bool *isNull);
-extern char *array_assgn(ArrayType *array, int n, int upperIndx[],
- int lowerIndx[], ArrayType *newArr, int reftype,
- int len, bool *isNull);
-extern int array_eq (ArrayType *array1, ArrayType *array2);
-extern int _LOtransfer(char **destfd, int size, int nitems, char **srcfd,
- int isSrcLO, int isDestLO);
-
-extern char * _array_newLO(int *fd, int flag);
+extern char *array_in(char *string, Oid element_type);
+extern char *array_out(ArrayType * v, Oid element_type);
+extern char *array_dims(ArrayType * v, bool * isNull);
+extern Datum
+array_ref(ArrayType * array, int n, int indx[], int reftype,
+ int elmlen, int arraylen, bool * isNull);
+extern Datum
+array_clip(ArrayType * array, int n, int upperIndx[],
+ int lowerIndx[], int reftype, int len, bool * isNull);
+extern char *
+array_set(ArrayType * array, int n, int indx[], char *dataPtr,
+ int reftype, int elmlen, int arraylen, bool * isNull);
+extern char *
+array_assgn(ArrayType * array, int n, int upperIndx[],
+ int lowerIndx[], ArrayType * newArr, int reftype,
+ int len, bool * isNull);
+extern int array_eq(ArrayType * array1, ArrayType * array2);
+extern int
+_LOtransfer(char **destfd, int size, int nitems, char **srcfd,
+ int isSrcLO, int isDestLO);
+
+extern char *_array_newLO(int *fd, int flag);
/*
@@ -136,25 +143,28 @@ extern char * _array_newLO(int *fd, int flag);
* [these names seem to be too generic. Add prefix for arrays? -- AY]
*/
-extern int GetOffset(int n, int dim[], int lb[], int indx[]);
-extern int getNitems(int n, int a[]);
-extern int compute_size(int st[], int endp[], int n, int base);
-extern void mda_get_offset_values(int n, int dist[], int PC[], int span[]);
-extern void mda_get_range(int n, int span[], int st[], int endp[]);
-extern void mda_get_prod(int n, int range[], int P[]);
-extern int tuple2linear(int n, int tup[], int scale[]);
-extern void array2chunk_coord(int n, int C[], int a_coord[], int c_coord[]);
-extern int next_tuple(int n, int curr[], int span[]);
+extern int GetOffset(int n, int dim[], int lb[], int indx[]);
+extern int getNitems(int n, int a[]);
+extern int compute_size(int st[], int endp[], int n, int base);
+extern void mda_get_offset_values(int n, int dist[], int PC[], int span[]);
+extern void mda_get_range(int n, int span[], int st[], int endp[]);
+extern void mda_get_prod(int n, int range[], int P[]);
+extern int tuple2linear(int n, int tup[], int scale[]);
+extern void array2chunk_coord(int n, int C[], int a_coord[], int c_coord[]);
+extern int next_tuple(int n, int curr[], int span[]);
/*
* prototypes for functions defined in chunk.c
*/
-extern char * _ChunkArray(int fd, FILE *afd, int ndim, int dim[], int baseSize,
- int *nbytes, char *chunkfile);
-extern int _ReadChunkArray(int st[], int endp[], int bsize, int fp,
- char *destfp, ArrayType *array, int isDestLO, bool *isNull);
-extern struct varlena *_ReadChunkArray1El(int st[], int bsize, int fp,
- ArrayType *array, bool *isNull);
-
-
-#endif /* ARRAY_H */
+extern char *
+_ChunkArray(int fd, FILE * afd, int ndim, int dim[], int baseSize,
+ int *nbytes, char *chunkfile);
+extern int
+_ReadChunkArray(int st[], int endp[], int bsize, int fp,
+ char *destfp, ArrayType * array, int isDestLO, bool * isNull);
+extern struct varlena *
+_ReadChunkArray1El(int st[], int bsize, int fp,
+ ArrayType * array, bool * isNull);
+
+
+#endif /* ARRAY_H */
diff --git a/src/include/utils/bit.h b/src/include/utils/bit.h
index dc190accc6b..ab68c0d6087 100644
--- a/src/include/utils/bit.h
+++ b/src/include/utils/bit.h
@@ -1,39 +1,39 @@
/*-------------------------------------------------------------------------
*
* bit.h--
- * Standard bit array definitions.
+ * Standard bit array definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: bit.h,v 1.1 1996/08/28 01:58:43 scrappy Exp $
+ * $Id: bit.h,v 1.2 1997/09/07 05:02:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef BIT_H
+#ifndef BIT_H
#define BIT_H
-typedef bits8 *BitArray;
+typedef bits8 *BitArray;
typedef uint32 BitIndex;
-#define BitsPerByte 8
+#define BitsPerByte 8
/*
* BitArraySetBit --
- * Sets (to 1) the value of a bit in a bit array.
+ * Sets (to 1) the value of a bit in a bit array.
*/
-extern void BitArraySetBit(BitArray bitArray, BitIndex bitIndex);
+extern void BitArraySetBit(BitArray bitArray, BitIndex bitIndex);
/*
* BitArrayClearBit --
- * Clears (to 0) the value of a bit in a bit array.
+ * Clears (to 0) the value of a bit in a bit array.
*/
-extern void BitArrayClearBit(BitArray bitArray, BitIndex bitIndex);
+extern void BitArrayClearBit(BitArray bitArray, BitIndex bitIndex);
/*
* BitArrayBitIsSet --
- * True iff the bit is set (1) in a bit array.
+ * True iff the bit is set (1) in a bit array.
*/
-extern bool BitArrayBitIsSet(BitArray bitArray, BitIndex bitIndex);
+extern bool BitArrayBitIsSet(BitArray bitArray, BitIndex bitIndex);
-#endif /* BIT_H */
+#endif /* BIT_H */
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 9a28e1f3ca6..05252ca01e9 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* builtins.h--
- * Declarations for operations on built-in types.
+ * Declarations for operations on built-in types.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: builtins.h,v 1.21 1997/08/19 21:40:26 momjian Exp $
+ * $Id: builtins.h,v 1.22 1997/09/07 05:02:11 momjian Exp $
*
* NOTES
- * This should normally only be included by fmgr.h.
- * Under no circumstances should it ever be included before
- * including fmgr.h!
+ * This should normally only be included by fmgr.h.
+ * Under no circumstances should it ever be included before
+ * including fmgr.h!
*
*-------------------------------------------------------------------------
*/
@@ -26,161 +26,161 @@
#include <utils/rel.h>
/*
- * Defined in adt/
+ * Defined in adt/
*/
/* bool.c */
-extern bool boolin(char *b);
-extern char *boolout(long b);
-extern bool booleq(int8 arg1, int8 arg2);
-extern bool boolne(int8 arg1, int8 arg2);
-extern bool boollt(int8 arg1, int8 arg2);
-extern bool boolgt(int8 arg1, int8 arg2);
+extern bool boolin(char *b);
+extern char *boolout(long b);
+extern bool booleq(int8 arg1, int8 arg2);
+extern bool boolne(int8 arg1, int8 arg2);
+extern bool boollt(int8 arg1, int8 arg2);
+extern bool boolgt(int8 arg1, int8 arg2);
/* char.c */
-extern int32 charin(char *ch);
-extern char *charout(int32 ch);
-extern int32 cidin(char *s);
-extern char *cidout(int32 c);
-extern char *char16in(char *s);
-extern char *char16out(char *s);
-extern bool chareq(int8 arg1, int8 arg2);
-extern bool charne(int8 arg1, int8 arg2);
-extern bool charlt(int8 arg1, int8 arg2);
-extern bool charle(int8 arg1, int8 arg2);
-extern bool chargt(int8 arg1, int8 arg2);
-extern bool charge(int8 arg1, int8 arg2);
-extern int8 charpl(int8 arg1, int8 arg2);
-extern int8 charmi(int8 arg1, int8 arg2);
-extern int8 charmul(int8 arg1, int8 arg2);
-extern int8 chardiv(int8 arg1, int8 arg2);
-extern bool cideq(int8 arg1, int8 arg2);
-extern bool char16eq(char *arg1, char *arg2);
-extern bool char16ne(char *arg1, char *arg2);
-extern bool char16lt(char *arg1, char *arg2);
-extern bool char16le(char *arg1, char *arg2);
-extern bool char16gt(char *arg1, char *arg2);
-extern bool char16ge(char *arg1, char *arg2);
-extern uint16 char2in(char *s);
-extern char *char2out(uint16 s);
-extern bool char2eq(uint16 a, uint16 b);
-extern bool char2ne(uint16 a, uint16 b);
-extern bool char2lt(uint16 a, uint16 b);
-extern bool char2le(uint16 a, uint16 b);
-extern bool char2gt(uint16 a, uint16 b);
-extern bool char2ge(uint16 a, uint16 b);
-extern int32 char2cmp(uint16 a, uint16 b);
-extern uint32 char4in(char *s);
-extern char *char4out(uint32 s);
-extern bool char4eq(uint32 a, uint32 b);
-extern bool char4ne(uint32 a, uint32 b);
-extern bool char4lt(uint32 a, uint32 b);
-extern bool char4le(uint32 a, uint32 b);
-extern bool char4gt(uint32 a, uint32 b);
-extern bool char4ge(uint32 a, uint32 b);
-extern int32 char4cmp(uint32 a, uint32 b);
-extern char *char8in(char *s);
-extern char *char8out(char *s);
-extern bool char8eq(char *arg1, char *arg2);
-extern bool char8ne(char *arg1, char *arg2);
-extern bool char8lt(char *arg1, char *arg2);
-extern bool char8le(char *arg1, char *arg2);
-extern bool char8gt(char *arg1, char *arg2);
-extern bool char8ge(char *arg1, char *arg2);
-extern int32 char8cmp(char *arg1, char *arg2);
+extern int32 charin(char *ch);
+extern char *charout(int32 ch);
+extern int32 cidin(char *s);
+extern char *cidout(int32 c);
+extern char *char16in(char *s);
+extern char *char16out(char *s);
+extern bool chareq(int8 arg1, int8 arg2);
+extern bool charne(int8 arg1, int8 arg2);
+extern bool charlt(int8 arg1, int8 arg2);
+extern bool charle(int8 arg1, int8 arg2);
+extern bool chargt(int8 arg1, int8 arg2);
+extern bool charge(int8 arg1, int8 arg2);
+extern int8 charpl(int8 arg1, int8 arg2);
+extern int8 charmi(int8 arg1, int8 arg2);
+extern int8 charmul(int8 arg1, int8 arg2);
+extern int8 chardiv(int8 arg1, int8 arg2);
+extern bool cideq(int8 arg1, int8 arg2);
+extern bool char16eq(char *arg1, char *arg2);
+extern bool char16ne(char *arg1, char *arg2);
+extern bool char16lt(char *arg1, char *arg2);
+extern bool char16le(char *arg1, char *arg2);
+extern bool char16gt(char *arg1, char *arg2);
+extern bool char16ge(char *arg1, char *arg2);
+extern uint16 char2in(char *s);
+extern char *char2out(uint16 s);
+extern bool char2eq(uint16 a, uint16 b);
+extern bool char2ne(uint16 a, uint16 b);
+extern bool char2lt(uint16 a, uint16 b);
+extern bool char2le(uint16 a, uint16 b);
+extern bool char2gt(uint16 a, uint16 b);
+extern bool char2ge(uint16 a, uint16 b);
+extern int32 char2cmp(uint16 a, uint16 b);
+extern uint32 char4in(char *s);
+extern char *char4out(uint32 s);
+extern bool char4eq(uint32 a, uint32 b);
+extern bool char4ne(uint32 a, uint32 b);
+extern bool char4lt(uint32 a, uint32 b);
+extern bool char4le(uint32 a, uint32 b);
+extern bool char4gt(uint32 a, uint32 b);
+extern bool char4ge(uint32 a, uint32 b);
+extern int32 char4cmp(uint32 a, uint32 b);
+extern char *char8in(char *s);
+extern char *char8out(char *s);
+extern bool char8eq(char *arg1, char *arg2);
+extern bool char8ne(char *arg1, char *arg2);
+extern bool char8lt(char *arg1, char *arg2);
+extern bool char8le(char *arg1, char *arg2);
+extern bool char8gt(char *arg1, char *arg2);
+extern bool char8ge(char *arg1, char *arg2);
+extern int32 char8cmp(char *arg1, char *arg2);
/* int.c */
-extern int32 int2in(char *num);
-extern char *int2out(int16 sh);
-extern int16 *int28in(char *shs);
-extern char *int28out(int16 (*shs)[]);
-extern int32 *int44in(char *input_string);
-extern char *int44out(int32 an_array[]);
-extern int32 int4in(char *num);
-extern char *int4out(int32 l);
-extern int32 i2toi4(int16 arg1);
-extern int16 i4toi2(int32 arg1);
-extern bool int4eq(int32 arg1, int32 arg2);
-extern bool int4ne(int32 arg1, int32 arg2);
-extern bool int4lt(int32 arg1, int32 arg2);
-extern bool int4le(int32 arg1, int32 arg2);
-extern bool int4gt(int32 arg1, int32 arg2);
-extern bool int4ge(int32 arg1, int32 arg2);
-extern bool int2eq(int16 arg1, int16 arg2);
-extern bool int2ne(int16 arg1, int16 arg2);
-extern bool int2lt(int16 arg1, int16 arg2);
-extern bool int2le(int16 arg1, int16 arg2);
-extern bool int2gt(int16 arg1, int16 arg2);
-extern bool int2ge(int16 arg1, int16 arg2);
-extern bool int24eq(int32 arg1, int32 arg2);
-extern bool int24ne(int32 arg1, int32 arg2);
-extern bool int24lt(int32 arg1, int32 arg2);
-extern bool int24le(int32 arg1, int32 arg2);
-extern bool int24gt(int32 arg1, int32 arg2);
-extern bool int24ge(int32 arg1, int32 arg2);
-extern bool int42eq(int32 arg1, int32 arg2);
-extern bool int42ne(int32 arg1, int32 arg2);
-extern bool int42lt(int32 arg1, int32 arg2);
-extern bool int42le(int32 arg1, int32 arg2);
-extern bool int42gt(int32 arg1, int32 arg2);
-extern bool int42ge(int32 arg1, int32 arg2);
-extern bool keyfirsteq(int16 *arg1, int16 arg2);
-extern int32 int4um(int32 arg);
-extern int32 int4pl(int32 arg1, int32 arg2);
-extern int32 int4mi(int32 arg1, int32 arg2);
-extern int32 int4mul(int32 arg1, int32 arg2);
-extern int32 int4div(int32 arg1, int32 arg2);
-extern int32 int4inc(int32 arg);
-extern int16 int2um(int16 arg);
-extern int16 int2pl(int16 arg1, int16 arg2);
-extern int16 int2mi(int16 arg1, int16 arg2);
-extern int16 int2mul(int16 arg1, int16 arg2);
-extern int16 int2div(int16 arg1, int16 arg2);
-extern int16 int2inc(int16 arg);
-extern int32 int24pl(int32 arg1, int32 arg2);
-extern int32 int24mi(int32 arg1, int32 arg2);
-extern int32 int24mul(int32 arg1, int32 arg2);
-extern int32 int24div(int32 arg1, int32 arg2);
-extern int32 int42pl(int32 arg1, int32 arg2);
-extern int32 int42mi(int32 arg1, int32 arg2);
-extern int32 int42mul(int32 arg1, int32 arg2);
-extern int32 int42div(int32 arg1, int32 arg2);
-extern int32 int4mod(int32 arg1, int32 arg2);
-extern int32 int2mod(int16 arg1, int16 arg2);
-extern int32 int24mod(int32 arg1, int32 arg2);
-extern int32 int42mod(int32 arg1, int32 arg2);
-extern int32 int4fac(int32 arg1);
-extern int32 int2fac(int16 arg1);
-extern int16 int2larger(int16 arg1, int16 arg2);
-extern int16 int2smaller(int16 arg1, int16 arg2);
-extern int32 int4larger(int32 arg1, int32 arg2);
-extern int32 int4smaller(int32 arg1, int32 arg2);
+extern int32 int2in(char *num);
+extern char *int2out(int16 sh);
+extern int16 *int28in(char *shs);
+extern char *int28out(int16(*shs)[]);
+extern int32 *int44in(char *input_string);
+extern char *int44out(int32 an_array[]);
+extern int32 int4in(char *num);
+extern char *int4out(int32 l);
+extern int32 i2toi4(int16 arg1);
+extern int16 i4toi2(int32 arg1);
+extern bool int4eq(int32 arg1, int32 arg2);
+extern bool int4ne(int32 arg1, int32 arg2);
+extern bool int4lt(int32 arg1, int32 arg2);
+extern bool int4le(int32 arg1, int32 arg2);
+extern bool int4gt(int32 arg1, int32 arg2);
+extern bool int4ge(int32 arg1, int32 arg2);
+extern bool int2eq(int16 arg1, int16 arg2);
+extern bool int2ne(int16 arg1, int16 arg2);
+extern bool int2lt(int16 arg1, int16 arg2);
+extern bool int2le(int16 arg1, int16 arg2);
+extern bool int2gt(int16 arg1, int16 arg2);
+extern bool int2ge(int16 arg1, int16 arg2);
+extern bool int24eq(int32 arg1, int32 arg2);
+extern bool int24ne(int32 arg1, int32 arg2);
+extern bool int24lt(int32 arg1, int32 arg2);
+extern bool int24le(int32 arg1, int32 arg2);
+extern bool int24gt(int32 arg1, int32 arg2);
+extern bool int24ge(int32 arg1, int32 arg2);
+extern bool int42eq(int32 arg1, int32 arg2);
+extern bool int42ne(int32 arg1, int32 arg2);
+extern bool int42lt(int32 arg1, int32 arg2);
+extern bool int42le(int32 arg1, int32 arg2);
+extern bool int42gt(int32 arg1, int32 arg2);
+extern bool int42ge(int32 arg1, int32 arg2);
+extern bool keyfirsteq(int16 * arg1, int16 arg2);
+extern int32 int4um(int32 arg);
+extern int32 int4pl(int32 arg1, int32 arg2);
+extern int32 int4mi(int32 arg1, int32 arg2);
+extern int32 int4mul(int32 arg1, int32 arg2);
+extern int32 int4div(int32 arg1, int32 arg2);
+extern int32 int4inc(int32 arg);
+extern int16 int2um(int16 arg);
+extern int16 int2pl(int16 arg1, int16 arg2);
+extern int16 int2mi(int16 arg1, int16 arg2);
+extern int16 int2mul(int16 arg1, int16 arg2);
+extern int16 int2div(int16 arg1, int16 arg2);
+extern int16 int2inc(int16 arg);
+extern int32 int24pl(int32 arg1, int32 arg2);
+extern int32 int24mi(int32 arg1, int32 arg2);
+extern int32 int24mul(int32 arg1, int32 arg2);
+extern int32 int24div(int32 arg1, int32 arg2);
+extern int32 int42pl(int32 arg1, int32 arg2);
+extern int32 int42mi(int32 arg1, int32 arg2);
+extern int32 int42mul(int32 arg1, int32 arg2);
+extern int32 int42div(int32 arg1, int32 arg2);
+extern int32 int4mod(int32 arg1, int32 arg2);
+extern int32 int2mod(int16 arg1, int16 arg2);
+extern int32 int24mod(int32 arg1, int32 arg2);
+extern int32 int42mod(int32 arg1, int32 arg2);
+extern int32 int4fac(int32 arg1);
+extern int32 int2fac(int16 arg1);
+extern int16 int2larger(int16 arg1, int16 arg2);
+extern int16 int2smaller(int16 arg1, int16 arg2);
+extern int32 int4larger(int32 arg1, int32 arg2);
+extern int32 int4smaller(int32 arg1, int32 arg2);
/* name.c */
extern NameData *namein(char *s);
-extern char *nameout(NameData *s);
-extern bool nameeq(NameData *arg1, NameData *arg2);
-extern bool namene(NameData *arg1, NameData *arg2);
-extern bool namelt(NameData *arg1, NameData *arg2);
-extern bool namele(NameData *arg1, NameData *arg2);
-extern bool namegt(NameData *arg1, NameData *arg2);
-extern bool namege(NameData *arg1, NameData *arg2);
-extern int namecmp(Name n1, Name n2);
-extern int namecpy(Name n1, Name n2);
-extern int namestrcpy(Name name, char *str);
-extern int namestrcmp(Name name, char *str);
+extern char *nameout(NameData * s);
+extern bool nameeq(NameData * arg1, NameData * arg2);
+extern bool namene(NameData * arg1, NameData * arg2);
+extern bool namelt(NameData * arg1, NameData * arg2);
+extern bool namele(NameData * arg1, NameData * arg2);
+extern bool namegt(NameData * arg1, NameData * arg2);
+extern bool namege(NameData * arg1, NameData * arg2);
+extern int namecmp(Name n1, Name n2);
+extern int namecpy(Name n1, Name n2);
+extern int namestrcpy(Name name, char *str);
+extern int namestrcmp(Name name, char *str);
/* numutils.c */
/* XXX hack. HP-UX has a ltoa (with different arguments) already. */
#ifdef hpux
#define ltoa pg_ltoa
-#endif /* hpux */
-extern int32 pg_atoi(char *s, int size, int c);
-extern void itoa(int i, char *a);
-extern void ltoa(int32 l, char *a);
+#endif /* hpux */
+extern int32 pg_atoi(char *s, int size, int c);
+extern void itoa(int i, char *a);
+extern void ltoa(int32 l, char *a);
/*
- * Per-opclass comparison functions for new btrees. These are
- * stored in pg_amproc and defined in nbtree/
+ * Per-opclass comparison functions for new btrees. These are
+ * stored in pg_amproc and defined in nbtree/
*/
extern int32 btint2cmp(int16 a, int16 b);
extern int32 btint4cmp(int32 a, int32 b);
@@ -195,343 +195,344 @@ extern int32 btchar2cmp(uint16 a, uint16 b);
extern int32 btchar4cmp(uint32 a, uint32 b);
extern int32 btchar8cmp(char *a, char *b);
extern int32 btchar16cmp(char *a, char *b);
-extern int32 btnamecmp(NameData *a, NameData *b);
-extern int32 bttextcmp(struct varlena *a, struct varlena *b);
+extern int32 btnamecmp(NameData * a, NameData * b);
+extern int32 bttextcmp(struct varlena * a, struct varlena * b);
/* support routines for the rtree access method, by opclass */
-extern BOX *rt_box_union(BOX *a,BOX *b);
-extern BOX *rt_box_inter(BOX *a, BOX *b);
-extern void rt_box_size(BOX *a, float *size);
-extern void rt_bigbox_size(BOX *a,float *size);
-extern void rt_poly_size(POLYGON *a, float *size);
-extern POLYGON *rt_poly_union(POLYGON *a, POLYGON *b);
-extern POLYGON *rt_poly_inter(POLYGON *a, POLYGON *b);
+extern BOX *rt_box_union(BOX * a, BOX * b);
+extern BOX *rt_box_inter(BOX * a, BOX * b);
+extern void rt_box_size(BOX * a, float *size);
+extern void rt_bigbox_size(BOX * a, float *size);
+extern void rt_poly_size(POLYGON * a, float *size);
+extern POLYGON *rt_poly_union(POLYGON * a, POLYGON * b);
+extern POLYGON *rt_poly_inter(POLYGON * a, POLYGON * b);
/* projection utilities */
-/* extern char *GetAttributeByName();
+/* extern char *GetAttributeByName();
extern char *GetAttributeByNum(); ,
in executor/executor.h*/
-extern int32 pqtest(struct varlena *vlena);
+extern int32 pqtest(struct varlena * vlena);
/* arrayfuncs.c */
/* date.c */
-extern int32 reltimein(char *timestring);
-extern char *reltimeout(int32 timevalue);
+extern int32 reltimein(char *timestring);
+extern char *reltimeout(int32 timevalue);
extern TimeInterval tintervalin(char *intervalstr);
-extern char *tintervalout(TimeInterval interval);
-extern RelativeTime timespan_reltime(TimeSpan *timespan);
+extern char *tintervalout(TimeInterval interval);
+extern RelativeTime timespan_reltime(TimeSpan * timespan);
extern TimeSpan *reltime_timespan(RelativeTime reltime);
extern TimeInterval mktinterval(AbsoluteTime t1, AbsoluteTime t2);
extern AbsoluteTime timepl(AbsoluteTime t1, RelativeTime t2);
extern AbsoluteTime timemi(AbsoluteTime t1, RelativeTime t2);
+
/* extern RelativeTime abstimemi(AbsoluteTime t1, AbsoluteTime t2); static*/
-extern int ininterval(AbsoluteTime t, TimeInterval interval);
+extern int ininterval(AbsoluteTime t, TimeInterval interval);
extern RelativeTime intervalrel(TimeInterval interval);
extern AbsoluteTime timenow(void);
-extern bool reltimeeq(RelativeTime t1, RelativeTime t2);
-extern bool reltimene(RelativeTime t1, RelativeTime t2);
-extern bool reltimelt(RelativeTime t1, RelativeTime t2);
-extern bool reltimegt(RelativeTime t1, RelativeTime t2);
-extern bool reltimele(RelativeTime t1, RelativeTime t2);
-extern bool reltimege(RelativeTime t1, RelativeTime t2);
-extern bool intervaleq(TimeInterval i1, TimeInterval i2);
-extern bool intervalleneq(TimeInterval i, RelativeTime t);
-extern bool intervallenne(TimeInterval i, RelativeTime t);
-extern bool intervallenlt(TimeInterval i, RelativeTime t);
-extern bool intervallengt(TimeInterval i, RelativeTime t);
-extern bool intervallenle(TimeInterval i, RelativeTime t);
-extern bool intervallenge(TimeInterval i, RelativeTime t);
-extern bool intervalct(TimeInterval i1, TimeInterval i2);
-extern bool intervalov(TimeInterval i1, TimeInterval i2);
+extern bool reltimeeq(RelativeTime t1, RelativeTime t2);
+extern bool reltimene(RelativeTime t1, RelativeTime t2);
+extern bool reltimelt(RelativeTime t1, RelativeTime t2);
+extern bool reltimegt(RelativeTime t1, RelativeTime t2);
+extern bool reltimele(RelativeTime t1, RelativeTime t2);
+extern bool reltimege(RelativeTime t1, RelativeTime t2);
+extern bool intervaleq(TimeInterval i1, TimeInterval i2);
+extern bool intervalleneq(TimeInterval i, RelativeTime t);
+extern bool intervallenne(TimeInterval i, RelativeTime t);
+extern bool intervallenlt(TimeInterval i, RelativeTime t);
+extern bool intervallengt(TimeInterval i, RelativeTime t);
+extern bool intervallenle(TimeInterval i, RelativeTime t);
+extern bool intervallenge(TimeInterval i, RelativeTime t);
+extern bool intervalct(TimeInterval i1, TimeInterval i2);
+extern bool intervalov(TimeInterval i1, TimeInterval i2);
extern AbsoluteTime intervalstart(TimeInterval i);
extern AbsoluteTime intervalend(TimeInterval i);
-extern int isreltime(char *timestring);
-extern text *timeofday(void);
+extern int isreltime(char *timestring);
+extern text *timeofday(void);
/* dt.c */
extern DateTime *datetime_in(char *str);
-extern char *datetime_out(DateTime *datetime);
+extern char *datetime_out(DateTime * datetime);
extern TimeSpan *timespan_in(char *str);
-extern char *timespan_out(TimeSpan *timespan);
-extern int datetime2tm( DateTime dt, int *tzp, struct tm *tm, double *fsec, char **tzn);
+extern char *timespan_out(TimeSpan * timespan);
+extern int datetime2tm(DateTime dt, int *tzp, struct tm * tm, double *fsec, char **tzn);
/* filename.c */
-extern char *filename_in(char *file);
-extern char *filename_out(char *s);
+extern char *filename_in(char *file);
+extern char *filename_out(char *s);
/* float.c */
-extern void CheckFloat8Val(double val); /* used by lex */
-extern float32 float4in(char *num);
-extern char *float4out(float32 num);
-extern float64 float8in(char *num);
-extern char *float8out(float64 num);
-extern float32 float4abs(float32 arg1);
-extern float32 float4um(float32 arg1);
-extern float32 float4larger(float32 arg1, float32 arg2);
-extern float32 float4smaller(float32 arg1, float32 arg2);
-extern float64 float8abs(float64 arg1);
-extern float64 float8um(float64 arg1);
-extern float64 float8larger(float64 arg1, float64 arg2);
-extern float64 float8smaller(float64 arg1, float64 arg2);
-extern float32 float4pl(float32 arg1, float32 arg2);
-extern float32 float4mi(float32 arg1, float32 arg2);
-extern float32 float4mul(float32 arg1, float32 arg2);
-extern float32 float4div(float32 arg1, float32 arg2);
-extern float32 float4inc(float32 arg1);
-extern float64 float8pl(float64 arg1, float64 arg2);
-extern float64 float8mi(float64 arg1, float64 arg2);
-extern float64 float8mul(float64 arg1, float64 arg2);
-extern float64 float8div(float64 arg1, float64 arg2);
-extern float64 float8inc(float64 arg1);
-extern bool float4eq(float32 arg1, float32 arg2);
-extern bool float4ne(float32 arg1, float32 arg2);
-extern bool float4lt(float32 arg1, float32 arg2);
-extern bool float4le(float32 arg1, float32 arg2);
-extern bool float4gt(float32 arg1, float32 arg2);
-extern bool float4ge(float32 arg1, float32 arg2);
-extern bool float8eq(float64 arg1, float64 arg2);
-extern bool float8ne(float64 arg1, float64 arg2);
-extern bool float8lt(float64 arg1, float64 arg2);
-extern bool float8le(float64 arg1, float64 arg2);
-extern bool float8gt(float64 arg1, float64 arg2);
-extern bool float8ge(float64 arg1, float64 arg2);
-extern float64 ftod(float32 num);
-extern float64 i4tod(int32 num);
-extern float64 i2tod(int16 num);
-extern float32 dtof(float64 num);
-extern int32 dtoi4(float64 num);
-extern int16 dtoi2(float64 num);
-extern float32 i4tof(int32 num);
-extern float32 i2tof(int16 num);
-extern int32 ftoi4(float32 num);
-extern int16 ftoi2(float32 num);
-extern float64 dround(float64 arg1);
-extern float64 dtrunc(float64 arg1);
-extern float64 dsqrt(float64 arg1);
-extern float64 dcbrt(float64 arg1);
-extern float64 dpow(float64 arg1, float64 arg2);
-extern float64 dexp(float64 arg1);
-extern float64 dlog1(float64 arg1);
-extern float64 float48pl(float32 arg1, float64 arg2);
-extern float64 float48mi(float32 arg1, float64 arg2);
-extern float64 float48mul(float32 arg1, float64 arg2);
-extern float64 float48div(float32 arg1, float64 arg2);
-extern float64 float84pl(float64 arg1, float32 arg2);
-extern float64 float84mi(float64 arg1, float32 arg2);
-extern float64 float84mul(float64 arg1, float32 arg2);
-extern float64 float84div(float64 arg1, float32 arg2);
-extern bool float48eq(float32 arg1, float64 arg2);
-extern bool float48ne(float32 arg1, float64 arg2);
-extern bool float48lt(float32 arg1, float64 arg2);
-extern bool float48le(float32 arg1, float64 arg2);
-extern bool float48gt(float32 arg1, float64 arg2);
-extern bool float48ge(float32 arg1, float64 arg2);
-extern bool float84eq(float64 arg1, float32 arg2);
-extern bool float84ne(float64 arg1, float32 arg2);
-extern bool float84lt(float64 arg1, float32 arg2);
-extern bool float84le(float64 arg1, float32 arg2);
-extern bool float84gt(float64 arg1, float32 arg2);
-extern bool float84ge(float64 arg1, float32 arg2);
+extern void CheckFloat8Val(double val); /* used by lex */
+extern float32 float4in(char *num);
+extern char *float4out(float32 num);
+extern float64 float8in(char *num);
+extern char *float8out(float64 num);
+extern float32 float4abs(float32 arg1);
+extern float32 float4um(float32 arg1);
+extern float32 float4larger(float32 arg1, float32 arg2);
+extern float32 float4smaller(float32 arg1, float32 arg2);
+extern float64 float8abs(float64 arg1);
+extern float64 float8um(float64 arg1);
+extern float64 float8larger(float64 arg1, float64 arg2);
+extern float64 float8smaller(float64 arg1, float64 arg2);
+extern float32 float4pl(float32 arg1, float32 arg2);
+extern float32 float4mi(float32 arg1, float32 arg2);
+extern float32 float4mul(float32 arg1, float32 arg2);
+extern float32 float4div(float32 arg1, float32 arg2);
+extern float32 float4inc(float32 arg1);
+extern float64 float8pl(float64 arg1, float64 arg2);
+extern float64 float8mi(float64 arg1, float64 arg2);
+extern float64 float8mul(float64 arg1, float64 arg2);
+extern float64 float8div(float64 arg1, float64 arg2);
+extern float64 float8inc(float64 arg1);
+extern bool float4eq(float32 arg1, float32 arg2);
+extern bool float4ne(float32 arg1, float32 arg2);
+extern bool float4lt(float32 arg1, float32 arg2);
+extern bool float4le(float32 arg1, float32 arg2);
+extern bool float4gt(float32 arg1, float32 arg2);
+extern bool float4ge(float32 arg1, float32 arg2);
+extern bool float8eq(float64 arg1, float64 arg2);
+extern bool float8ne(float64 arg1, float64 arg2);
+extern bool float8lt(float64 arg1, float64 arg2);
+extern bool float8le(float64 arg1, float64 arg2);
+extern bool float8gt(float64 arg1, float64 arg2);
+extern bool float8ge(float64 arg1, float64 arg2);
+extern float64 ftod(float32 num);
+extern float64 i4tod(int32 num);
+extern float64 i2tod(int16 num);
+extern float32 dtof(float64 num);
+extern int32 dtoi4(float64 num);
+extern int16 dtoi2(float64 num);
+extern float32 i4tof(int32 num);
+extern float32 i2tof(int16 num);
+extern int32 ftoi4(float32 num);
+extern int16 ftoi2(float32 num);
+extern float64 dround(float64 arg1);
+extern float64 dtrunc(float64 arg1);
+extern float64 dsqrt(float64 arg1);
+extern float64 dcbrt(float64 arg1);
+extern float64 dpow(float64 arg1, float64 arg2);
+extern float64 dexp(float64 arg1);
+extern float64 dlog1(float64 arg1);
+extern float64 float48pl(float32 arg1, float64 arg2);
+extern float64 float48mi(float32 arg1, float64 arg2);
+extern float64 float48mul(float32 arg1, float64 arg2);
+extern float64 float48div(float32 arg1, float64 arg2);
+extern float64 float84pl(float64 arg1, float32 arg2);
+extern float64 float84mi(float64 arg1, float32 arg2);
+extern float64 float84mul(float64 arg1, float32 arg2);
+extern float64 float84div(float64 arg1, float32 arg2);
+extern bool float48eq(float32 arg1, float64 arg2);
+extern bool float48ne(float32 arg1, float64 arg2);
+extern bool float48lt(float32 arg1, float64 arg2);
+extern bool float48le(float32 arg1, float64 arg2);
+extern bool float48gt(float32 arg1, float64 arg2);
+extern bool float48ge(float32 arg1, float64 arg2);
+extern bool float84eq(float64 arg1, float32 arg2);
+extern bool float84ne(float64 arg1, float32 arg2);
+extern bool float84lt(float64 arg1, float32 arg2);
+extern bool float84le(float64 arg1, float32 arg2);
+extern bool float84gt(float64 arg1, float32 arg2);
+extern bool float84ge(float64 arg1, float32 arg2);
/* geo_ops.c, geo_selfuncs.c */
-extern double *box_area(BOX *box);
+extern double *box_area(BOX * box);
/* misc.c */
-extern bool nullvalue(Datum value, bool *isNull);
-extern bool nonnullvalue(Datum value, bool *isNull);
-extern bool oidrand(Oid o, int32 X);
-extern bool oidsrand(int32 X);
-extern int32 userfntest(int i);
+extern bool nullvalue(Datum value, bool * isNull);
+extern bool nonnullvalue(Datum value, bool * isNull);
+extern bool oidrand(Oid o, int32 X);
+extern bool oidsrand(int32 X);
+extern int32 userfntest(int i);
/* define macros to replace mixed-case function calls - tgl 97/04/27 */
#define NullValue(v,b) nullvalue(v,b)
#define NonNullValue(v,b) nonnullvalue(v,b)
/* not_in.c */
-extern bool int4notin(int16 not_in_arg, char *relation_and_attr);
-extern bool oidnotin(Oid the_oid, char *compare);
+extern bool int4notin(int16 not_in_arg, char *relation_and_attr);
+extern bool oidnotin(Oid the_oid, char *compare);
/* oid.c */
-extern Oid *oid8in(char *oidString);
-extern char *oid8out(Oid (*oidArray)[]);
-extern Oid oidin(char *s);
-extern char *oidout(Oid o);
-extern bool oideq(Oid arg1, Oid arg2);
-extern bool oidne(Oid arg1, Oid arg2);
-extern bool oid8eq(Oid arg1[], Oid arg2[]);
-extern bool oideqint4(Oid arg1, int32 arg2);
-extern bool int4eqoid(int32 arg1, Oid arg2);
+extern Oid *oid8in(char *oidString);
+extern char *oid8out(Oid(*oidArray)[]);
+extern Oid oidin(char *s);
+extern char *oidout(Oid o);
+extern bool oideq(Oid arg1, Oid arg2);
+extern bool oidne(Oid arg1, Oid arg2);
+extern bool oid8eq(Oid arg1[], Oid arg2[]);
+extern bool oideqint4(Oid arg1, int32 arg2);
+extern bool int4eqoid(int32 arg1, Oid arg2);
/* regexp.c */
-extern bool char2regexeq(uint16 arg1, struct varlena *p);
-extern bool char2regexne(uint16 arg1, struct varlena *p);
-extern bool char4regexeq(uint32 arg1, struct varlena *p);
-extern bool char4regexne(uint32 arg1, struct varlena *p);
-extern bool char8regexeq(char *s, struct varlena *p);
-extern bool char8regexne(char *s, struct varlena *p);
-extern bool char16regexeq(char *s, struct varlena *p);
-extern bool char16regexne(char *s, struct varlena *p);
-extern bool nameregexeq(NameData *n, struct varlena *p);
-extern bool nameregexne(NameData *s, struct varlena *p);
-extern bool textregexeq(struct varlena *s, struct varlena *p);
-extern bool textregexne(struct varlena *s, struct varlena *p);
-extern bool char2icregexeq(uint16 arg1, struct varlena *p);
-extern bool char2icregexne(uint16 arg1, struct varlena *p);
-extern bool char4icregexeq(uint32 arg1, struct varlena *p);
-extern bool char4icregexne(uint32 arg1, struct varlena *p);
-extern bool char8icregexeq(char *s, struct varlena *p);
-extern bool char8icregexne(char *s, struct varlena *p);
-extern bool char16icregexeq(char *s, struct varlena *p);
-extern bool char16icregexne(char *s, struct varlena *p);
-extern bool nameicregexeq(NameData *s, struct varlena *p);
-extern bool nameicregexne(NameData *s, struct varlena *p);
-extern bool texticregexeq(struct varlena *s, struct varlena *p);
-extern bool texticregexne(struct varlena *s, struct varlena *p);
+extern bool char2regexeq(uint16 arg1, struct varlena * p);
+extern bool char2regexne(uint16 arg1, struct varlena * p);
+extern bool char4regexeq(uint32 arg1, struct varlena * p);
+extern bool char4regexne(uint32 arg1, struct varlena * p);
+extern bool char8regexeq(char *s, struct varlena * p);
+extern bool char8regexne(char *s, struct varlena * p);
+extern bool char16regexeq(char *s, struct varlena * p);
+extern bool char16regexne(char *s, struct varlena * p);
+extern bool nameregexeq(NameData * n, struct varlena * p);
+extern bool nameregexne(NameData * s, struct varlena * p);
+extern bool textregexeq(struct varlena * s, struct varlena * p);
+extern bool textregexne(struct varlena * s, struct varlena * p);
+extern bool char2icregexeq(uint16 arg1, struct varlena * p);
+extern bool char2icregexne(uint16 arg1, struct varlena * p);
+extern bool char4icregexeq(uint32 arg1, struct varlena * p);
+extern bool char4icregexne(uint32 arg1, struct varlena * p);
+extern bool char8icregexeq(char *s, struct varlena * p);
+extern bool char8icregexne(char *s, struct varlena * p);
+extern bool char16icregexeq(char *s, struct varlena * p);
+extern bool char16icregexne(char *s, struct varlena * p);
+extern bool nameicregexeq(NameData * s, struct varlena * p);
+extern bool nameicregexne(NameData * s, struct varlena * p);
+extern bool texticregexeq(struct varlena * s, struct varlena * p);
+extern bool texticregexne(struct varlena * s, struct varlena * p);
/* regproc.c */
-extern int32 regprocin(char *proname);
-extern char *regprocout(RegProcedure proid);
-extern Oid regproctooid(RegProcedure rp);
+extern int32 regprocin(char *proname);
+extern char *regprocout(RegProcedure proid);
+extern Oid regproctooid(RegProcedure rp);
/* define macro to replace mixed-case function call - tgl 97/04/27 */
#define RegprocToOid(rp) regproctooid(rp)
/* selfuncs.c */
-extern float64 eqsel(Oid opid, Oid relid, AttrNumber attno, char *value, int32 flag);
-extern float64 neqsel(Oid opid, Oid relid, AttrNumber attno, char *value, int32 flag);
-extern float64 intltsel(Oid opid, Oid relid, AttrNumber attno, int32 value, int32 flag);
-extern float64 intgtsel(Oid opid, Oid relid, AttrNumber attno, int32 value, int32 flag);
-extern float64 eqjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
-extern float64 neqjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
-extern float64 intltjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
-extern float64 intgtjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
-extern float64 btreesel(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
-extern float64 btreenpage(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
-extern float64 hashsel(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
-extern float64 hashnpage(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
-extern float64 rtsel(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
-extern float64 rtnpage(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
-extern float64 gistsel(Oid operatorObjectId, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
-extern float64 gistnpage(Oid operatorObjectId, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
+extern float64 eqsel(Oid opid, Oid relid, AttrNumber attno, char *value, int32 flag);
+extern float64 neqsel(Oid opid, Oid relid, AttrNumber attno, char *value, int32 flag);
+extern float64 intltsel(Oid opid, Oid relid, AttrNumber attno, int32 value, int32 flag);
+extern float64 intgtsel(Oid opid, Oid relid, AttrNumber attno, int32 value, int32 flag);
+extern float64 eqjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
+extern float64 neqjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
+extern float64 intltjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
+extern float64 intgtjoinsel(Oid opid, Oid relid1, AttrNumber attno1, Oid relid2, AttrNumber attno2);
+extern float64 btreesel(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
+extern float64 btreenpage(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
+extern float64 hashsel(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
+extern float64 hashnpage(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
+extern float64 rtsel(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
+extern float64 rtnpage(Oid operatorOid, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
+extern float64 gistsel(Oid operatorObjectId, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
+extern float64 gistnpage(Oid operatorObjectId, Oid indrelid, AttrNumber attributeNumber, char *constValue, int32 constFlag, int32 nIndexKeys, Oid indexrelid);
/* tid.c */
extern ItemPointer tidin(char *str);
-extern char *tidout(ItemPointer itemPtr);
+extern char *tidout(ItemPointer itemPtr);
/* timestamp.c */
-extern time_t timestamp_in(const char *timestamp_str);
-extern char *timestamp_out(time_t timestamp);
-extern time_t now(void);
-bool timestampeq(time_t t1, time_t t2);
-bool timestampne(time_t t1, time_t t2);
-bool timestamplt(time_t t1, time_t t2);
-bool timestampgt(time_t t1, time_t t2);
-bool timestample(time_t t1, time_t t2);
-bool timestampge(time_t t1, time_t t2);
-DateTime *timestamp_datetime(time_t timestamp);
+extern time_t timestamp_in(const char *timestamp_str);
+extern char *timestamp_out(time_t timestamp);
+extern time_t now(void);
+bool timestampeq(time_t t1, time_t t2);
+bool timestampne(time_t t1, time_t t2);
+bool timestamplt(time_t t1, time_t t2);
+bool timestampgt(time_t t1, time_t t2);
+bool timestample(time_t t1, time_t t2);
+bool timestampge(time_t t1, time_t t2);
+DateTime *timestamp_datetime(time_t timestamp);
/* varchar.c */
-extern char *bpcharin(char *s, int dummy, int typlen);
-extern char *bpcharout(char *s);
-extern char *varcharin(char *s, int dummy, int typlen);
-extern char *varcharout(char *s);
-extern bool bpchareq(char *arg1, char *arg2);
-extern bool bpcharne(char *arg1, char *arg2);
-extern bool bpcharlt(char *arg1, char *arg2);
-extern bool bpcharle(char *arg1, char *arg2);
-extern bool bpchargt(char *arg1, char *arg2);
-extern bool bpcharge(char *arg1, char *arg2);
-extern int32 bpcharcmp(char *arg1, char *arg2);
-extern bool varchareq(char *arg1, char *arg2);
-extern bool varcharne(char *arg1, char *arg2);
-extern bool varcharlt(char *arg1, char *arg2);
-extern bool varcharle(char *arg1, char *arg2);
-extern bool varchargt(char *arg1, char *arg2);
-extern bool varcharge(char *arg1, char *arg2);
-extern int32 varcharcmp(char *arg1, char *arg2);
-extern uint32 hashbpchar(struct varlena *key);
-extern uint32 hashvarchar(struct varlena *key);
+extern char *bpcharin(char *s, int dummy, int typlen);
+extern char *bpcharout(char *s);
+extern char *varcharin(char *s, int dummy, int typlen);
+extern char *varcharout(char *s);
+extern bool bpchareq(char *arg1, char *arg2);
+extern bool bpcharne(char *arg1, char *arg2);
+extern bool bpcharlt(char *arg1, char *arg2);
+extern bool bpcharle(char *arg1, char *arg2);
+extern bool bpchargt(char *arg1, char *arg2);
+extern bool bpcharge(char *arg1, char *arg2);
+extern int32 bpcharcmp(char *arg1, char *arg2);
+extern bool varchareq(char *arg1, char *arg2);
+extern bool varcharne(char *arg1, char *arg2);
+extern bool varcharlt(char *arg1, char *arg2);
+extern bool varcharle(char *arg1, char *arg2);
+extern bool varchargt(char *arg1, char *arg2);
+extern bool varcharge(char *arg1, char *arg2);
+extern int32 varcharcmp(char *arg1, char *arg2);
+extern uint32 hashbpchar(struct varlena * key);
+extern uint32 hashvarchar(struct varlena * key);
/* varlena.c */
extern struct varlena *byteain(char *inputText);
-extern char *byteaout(struct varlena *vlena);
+extern char *byteaout(struct varlena * vlena);
extern struct varlena *textin(char *inputText);
-extern char *textout(struct varlena *vlena);
-extern text *textcat(text* t1, text* t2);
-extern bool texteq(struct varlena *arg1, struct varlena *arg2);
-extern bool textne(struct varlena *arg1, struct varlena *arg2);
-extern bool text_lt(struct varlena *arg1, struct varlena *arg2);
-extern bool text_le(struct varlena *arg1, struct varlena *arg2);
-extern bool text_gt(struct varlena *arg1, struct varlena *arg2);
-extern bool text_ge(struct varlena *arg1, struct varlena *arg2);
-extern int32 textpos(text* t1, text* t2);
-extern int32 byteaGetSize(struct varlena *v);
-extern int32 byteaGetByte(struct varlena *v, int32 n);
-extern int32 byteaGetBit(struct varlena *v, int32 n);
-extern struct varlena *byteaSetByte(struct varlena *v, int32 n, int32 newByte);
-extern struct varlena *byteaSetBit(struct varlena *v, int32 n, int32 newBit);
+extern char *textout(struct varlena * vlena);
+extern text *textcat(text * t1, text * t2);
+extern bool texteq(struct varlena * arg1, struct varlena * arg2);
+extern bool textne(struct varlena * arg1, struct varlena * arg2);
+extern bool text_lt(struct varlena * arg1, struct varlena * arg2);
+extern bool text_le(struct varlena * arg1, struct varlena * arg2);
+extern bool text_gt(struct varlena * arg1, struct varlena * arg2);
+extern bool text_ge(struct varlena * arg1, struct varlena * arg2);
+extern int32 textpos(text * t1, text * t2);
+extern int32 byteaGetSize(struct varlena * v);
+extern int32 byteaGetByte(struct varlena * v, int32 n);
+extern int32 byteaGetBit(struct varlena * v, int32 n);
+extern struct varlena *byteaSetByte(struct varlena * v, int32 n, int32 newByte);
+extern struct varlena *byteaSetBit(struct varlena * v, int32 n, int32 newBit);
/* datetime.c */
-extern DateADT date_in(char *datestr);
-extern char *date_out(DateADT dateVal);
-extern bool date_eq(DateADT dateVal1, DateADT dateVal2);
-extern bool date_ne(DateADT dateVal1, DateADT dateVal2);
-extern bool date_lt(DateADT dateVal1, DateADT dateVal2);
-extern bool date_le(DateADT dateVal1, DateADT dateVal2);
-extern bool date_gt(DateADT dateVal1, DateADT dateVal2);
-extern bool date_ge(DateADT dateVal1, DateADT dateVal2);
-extern int date_cmp(DateADT dateVal1, DateADT dateVal2);
-extern DateADT date_larger(DateADT dateVal1, DateADT dateVal2);
-extern DateADT date_smaller(DateADT dateVal1, DateADT dateVal2);
-extern int32 date_mi(DateADT dateVal1, DateADT dateVal2);
-extern DateADT date_pli(DateADT dateVal, int32 days);
-extern DateADT date_mii(DateADT dateVal, int32 days);
+extern DateADT date_in(char *datestr);
+extern char *date_out(DateADT dateVal);
+extern bool date_eq(DateADT dateVal1, DateADT dateVal2);
+extern bool date_ne(DateADT dateVal1, DateADT dateVal2);
+extern bool date_lt(DateADT dateVal1, DateADT dateVal2);
+extern bool date_le(DateADT dateVal1, DateADT dateVal2);
+extern bool date_gt(DateADT dateVal1, DateADT dateVal2);
+extern bool date_ge(DateADT dateVal1, DateADT dateVal2);
+extern int date_cmp(DateADT dateVal1, DateADT dateVal2);
+extern DateADT date_larger(DateADT dateVal1, DateADT dateVal2);
+extern DateADT date_smaller(DateADT dateVal1, DateADT dateVal2);
+extern int32 date_mi(DateADT dateVal1, DateADT dateVal2);
+extern DateADT date_pli(DateADT dateVal, int32 days);
+extern DateADT date_mii(DateADT dateVal, int32 days);
extern DateTime *date_datetime(DateADT date);
-extern DateADT datetime_date(DateTime *datetime);
-extern DateTime *datetime_datetime(DateADT date, TimeADT *time);
-extern DateADT abstime_date(AbsoluteTime abstime);
+extern DateADT datetime_date(DateTime * datetime);
+extern DateTime *datetime_datetime(DateADT date, TimeADT * time);
+extern DateADT abstime_date(AbsoluteTime abstime);
extern TimeADT *time_in(char *timestr);
-extern char *time_out(TimeADT *time);
-extern bool time_eq(TimeADT *time1, TimeADT *time2);
-extern bool time_ne(TimeADT *time1, TimeADT *time2);
-extern bool time_lt(TimeADT *time1, TimeADT *time2);
-extern bool time_le(TimeADT *time1, TimeADT *time2);
-extern bool time_gt(TimeADT *time1, TimeADT *time2);
-extern bool time_ge(TimeADT *time1, TimeADT *time2);
-extern int time_cmp(TimeADT *time1, TimeADT *time2);
-extern int32 int42reltime(int32 timevalue);
+extern char *time_out(TimeADT * time);
+extern bool time_eq(TimeADT * time1, TimeADT * time2);
+extern bool time_ne(TimeADT * time1, TimeADT * time2);
+extern bool time_lt(TimeADT * time1, TimeADT * time2);
+extern bool time_le(TimeADT * time1, TimeADT * time2);
+extern bool time_gt(TimeADT * time1, TimeADT * time2);
+extern bool time_ge(TimeADT * time1, TimeADT * time2);
+extern int time_cmp(TimeADT * time1, TimeADT * time2);
+extern int32 int42reltime(int32 timevalue);
/* like.c */
-extern bool char2like(uint16 arg1, struct varlena *p);
-extern bool char2nlike(uint16 arg1, struct varlena *p);
-extern bool char4like(uint32 arg1, struct varlena *p);
-extern bool char4nlike(uint32 arg1, struct varlena *p);
-extern bool char8like(char *s, struct varlena *p);
-extern bool char8nlike(char *s, struct varlena *p);
-extern bool char16like(char *s, struct varlena *p);
-extern bool char16nlike(char *s, struct varlena *p);
-extern bool namelike(NameData *n, struct varlena *p);
-extern bool namenlike(NameData *s, struct varlena *p);
-extern bool textlike(struct varlena *s, struct varlena *p);
-extern bool textnlike(struct varlena *s, struct varlena *p);
+extern bool char2like(uint16 arg1, struct varlena * p);
+extern bool char2nlike(uint16 arg1, struct varlena * p);
+extern bool char4like(uint32 arg1, struct varlena * p);
+extern bool char4nlike(uint32 arg1, struct varlena * p);
+extern bool char8like(char *s, struct varlena * p);
+extern bool char8nlike(char *s, struct varlena * p);
+extern bool char16like(char *s, struct varlena * p);
+extern bool char16nlike(char *s, struct varlena * p);
+extern bool namelike(NameData * n, struct varlena * p);
+extern bool namenlike(NameData * s, struct varlena * p);
+extern bool textlike(struct varlena * s, struct varlena * p);
+extern bool textnlike(struct varlena * s, struct varlena * p);
/* oracle_compat.c */
-extern text *lower(text *string);
-extern text *upper(text *string);
-extern text *initcap(text *string);
-extern text *lpad(text *string1, int4 len, text *string2);
-extern text *rpad(text *string1, int4 len, text *string2);
-extern text *ltrim(text *string, text *set);
-extern text *rtrim(text *string, text *set);
-extern text *substr(text *string, int4 m, int4 n);
-extern text *translate(text *string, char from, char to);
+extern text *lower(text * string);
+extern text *upper(text * string);
+extern text *initcap(text * string);
+extern text *lpad(text * string1, int4 len, text * string2);
+extern text *rpad(text * string1, int4 len, text * string2);
+extern text *ltrim(text * string, text * set);
+extern text *rtrim(text * string, text * set);
+extern text *substr(text * string, int4 m, int4 n);
+extern text *translate(text * string, char from, char to);
/* acl.c */
-#endif /* BUILTINS_H */
+#endif /* BUILTINS_H */
diff --git a/src/include/utils/cash.h b/src/include/utils/cash.h
index 9307654315a..2e5f82c093b 100644
--- a/src/include/utils/cash.h
+++ b/src/include/utils/cash.h
@@ -3,7 +3,7 @@
* Written by D'Arcy J.M. Cain
*
* Functions to allow input and output of money normally but store
- * and handle it as int4.
+ * and handle it as int4.
*/
#ifndef CASH_H
@@ -12,24 +12,24 @@
/* if we store this as 4 bytes, we better make it int, not long, bjm */
typedef signed int Cash;
-extern const char *cash_out(Cash *value);
-extern Cash *cash_in(const char *str);
+extern const char *cash_out(Cash * value);
+extern Cash *cash_in(const char *str);
-extern bool cash_eq(Cash *c1, Cash *c2);
-extern bool cash_ne(Cash *c1, Cash *c2);
-extern bool cash_lt(Cash *c1, Cash *c2);
-extern bool cash_le(Cash *c1, Cash *c2);
-extern bool cash_gt(Cash *c1, Cash *c2);
-extern bool cash_ge(Cash *c1, Cash *c2);
+extern bool cash_eq(Cash * c1, Cash * c2);
+extern bool cash_ne(Cash * c1, Cash * c2);
+extern bool cash_lt(Cash * c1, Cash * c2);
+extern bool cash_le(Cash * c1, Cash * c2);
+extern bool cash_gt(Cash * c1, Cash * c2);
+extern bool cash_ge(Cash * c1, Cash * c2);
-extern Cash *cash_pl(Cash *c1, Cash *c2);
-extern Cash *cash_mi(Cash *c1, Cash *c2);
-extern Cash *cash_mul(Cash *c, float8 *f);
-extern Cash *cash_div(Cash *c, float8 *f);
+extern Cash *cash_pl(Cash * c1, Cash * c2);
+extern Cash *cash_mi(Cash * c1, Cash * c2);
+extern Cash *cash_mul(Cash * c, float8 * f);
+extern Cash *cash_div(Cash * c, float8 * f);
-extern Cash *cashlarger(Cash *c1, Cash *c2);
-extern Cash *cashsmaller(Cash *c1, Cash *c2);
+extern Cash *cashlarger(Cash * c1, Cash * c2);
+extern Cash *cashsmaller(Cash * c1, Cash * c2);
-extern const char *cash_words_out(Cash *value);
+extern const char *cash_words_out(Cash * value);
-#endif /* CASH_H */
+#endif /* CASH_H */
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index 70a40c3e0a5..6b33ef89b11 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -1,19 +1,19 @@
/*-------------------------------------------------------------------------
*
* catcache.h--
- * Low-level catalog cache definitions.
+ * Low-level catalog cache definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: catcache.h,v 1.5 1997/08/19 21:40:28 momjian Exp $
+ * $Id: catcache.h,v 1.6 1997/09/07 05:02:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef CATCACHE_H
+#ifndef CATCACHE_H
#define CATCACHE_H
-/* #define CACHEDEBUG turns DEBUG elogs on */
+/* #define CACHEDEBUG turns DEBUG elogs on */
#include <access/htup.h>
#include <lib/dllist.h>
@@ -21,54 +21,60 @@
#include <utils/rel.h>
/*
- * struct catctup: tuples in the cache.
- * struct catcache: information for managing a cache.
+ * struct catctup: tuples in the cache.
+ * struct catcache: information for managing a cache.
*/
-typedef struct catctup {
- HeapTuple ct_tup; /* A pointer to a tuple */
- Dlelem *ct_node; /* points to LRU list is the CatCTup is in the cache,
- else, points to the cache if the CatCTup is in
- LRU list */
-} CatCTup;
+typedef struct catctup
+{
+ HeapTuple ct_tup; /* A pointer to a tuple */
+ Dlelem *ct_node; /* points to LRU list is the CatCTup is in
+ * the cache, else, points to the cache if
+ * the CatCTup is in LRU list */
+} CatCTup;
/* voodoo constants */
-#define NCCBUCK 500 /* CatCache buckets*/
-#define MAXTUP 300 /* Maximum # of tuples cached per cache */
+#define NCCBUCK 500 /* CatCache buckets */
+#define MAXTUP 300 /* Maximum # of tuples cached per cache */
-typedef struct catcache {
- Oid relationId;
- Oid indexId;
- char *cc_relname; /* relation name for defered open */
- char *cc_indname; /* index name for defered open */
- HeapTuple (*cc_iscanfunc)(); /* index scanfunction */
- TupleDesc cc_tupdesc; /* tuple descriptor from reldesc */
- int id; /* XXX could be improved -hirohama */
- short cc_ntup; /* # of tuples in this cache */
- short cc_maxtup; /* max # of tuples allowed (LRU)*/
- short cc_nkeys;
- short cc_size;
- short cc_key[4];
- short cc_klen[4];
- ScanKeyData cc_skey[4];
- struct catcache *cc_next;
- Dllist *cc_lrulist; /* LRU list, most recent first */
- Dllist *cc_cache[NCCBUCK+1];
-} CatCache;
+typedef struct catcache
+{
+ Oid relationId;
+ Oid indexId;
+ char *cc_relname; /* relation name for defered open */
+ char *cc_indname; /* index name for defered open */
+ HeapTuple(*cc_iscanfunc) (); /* index scanfunction */
+ TupleDesc cc_tupdesc; /* tuple descriptor from reldesc */
+ int id; /* XXX could be improved -hirohama */
+ short cc_ntup; /* # of tuples in this cache */
+ short cc_maxtup; /* max # of tuples allowed (LRU) */
+ short cc_nkeys;
+ short cc_size;
+ short cc_key[4];
+ short cc_klen[4];
+ ScanKeyData cc_skey[4];
+ struct catcache *cc_next;
+ Dllist *cc_lrulist; /* LRU list, most recent first */
+ Dllist *cc_cache[NCCBUCK + 1];
+} CatCache;
-#define InvalidCatalogCacheId (-1)
+#define InvalidCatalogCacheId (-1)
-extern struct catcache *Caches;
-extern GlobalMemory CacheCxt;
+extern struct catcache *Caches;
+extern GlobalMemory CacheCxt;
-extern void CatalogCacheIdInvalidate(int cacheId, Index hashIndex,
- ItemPointer pointer);
-extern void ResetSystemCache(void);
-extern CatCache *InitSysCache(char *relname, char *indname, int id, int nkeys,
- int key[], HeapTuple (*iScanfuncP)());
-extern HeapTuple SearchSysCache(struct catcache *cache, Datum v1, Datum v2,
- Datum v3, Datum v4);
-extern void RelationInvalidateCatalogCacheTuple(Relation relation,
- HeapTuple tuple, void (*function)());
+extern void
+CatalogCacheIdInvalidate(int cacheId, Index hashIndex,
+ ItemPointer pointer);
+extern void ResetSystemCache(void);
+extern CatCache *
+InitSysCache(char *relname, char *indname, int id, int nkeys,
+ int key[], HeapTuple(*iScanfuncP) ());
+extern HeapTuple
+SearchSysCache(struct catcache * cache, Datum v1, Datum v2,
+ Datum v3, Datum v4);
+extern void
+RelationInvalidateCatalogCacheTuple(Relation relation,
+ HeapTuple tuple, void (*function) ());
-#endif /* CATCACHE_H */
+#endif /* CATCACHE_H */
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index fd9546362f3..79e6fb7ff57 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* datetime.h--
- * Definitions for the datetime
+ * Definitions for the datetime
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: datetime.h,v 1.3 1997/06/23 15:03:41 thomas Exp $
+ * $Id: datetime.h,v 1.4 1997/09/07 05:02:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,4 +19,4 @@ typedef int32 DateADT;
typedef float8 TimeADT;
-#endif /* DATETIME_H */
+#endif /* DATETIME_H */
diff --git a/src/include/utils/datum.h b/src/include/utils/datum.h
index 009141e9cba..5409c8ddfe3 100644
--- a/src/include/utils/datum.h
+++ b/src/include/utils/datum.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* datum.h--
- * POSTGRES abstract data type datum representation definitions.
+ * POSTGRES abstract data type datum representation definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: datum.h,v 1.2 1996/10/31 09:51:11 scrappy Exp $
+ * $Id: datum.h,v 1.3 1997/09/07 05:02:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef DATUM_H
-#define DATUM_H
+#ifndef DATUM_H
+#define DATUM_H
/*--------------------------------------------------------
@@ -38,26 +38,27 @@
* datumGetSize
* find the "real" length of a datum
*/
-extern Size datumGetSize(Datum value, Oid type, bool byVal, Size len);
+extern Size datumGetSize(Datum value, Oid type, bool byVal, Size len);
/*---------------
* datumCopy
* make a copy of a datum.
*/
-extern Datum datumCopy(Datum value, Oid type, bool byVal, Size len);
+extern Datum datumCopy(Datum value, Oid type, bool byVal, Size len);
/*---------------
* datumFree
* free space that *might* have been palloced by "datumCopy"
*/
-extern void datumFree(Datum value, Oid type, bool byVal, Size len);
+extern void datumFree(Datum value, Oid type, bool byVal, Size len);
/*---------------
* datumIsEqual
* return true if thwo datums are equal, false otherwise.
* XXX : See comments in the code for restrictions!
*/
-extern bool datumIsEqual(Datum value1, Datum value2, Oid type,
+extern bool
+datumIsEqual(Datum value1, Datum value2, Oid type,
bool byVal, Size len);
-#endif /* DATUM_H */
+#endif /* DATUM_H */
diff --git a/src/include/utils/dt.h b/src/include/utils/dt.h
index 2065e62d05f..b30e3a18627 100644
--- a/src/include/utils/dt.h
+++ b/src/include/utils/dt.h
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* dt.h--
- * Definitions for the date/time and other date/time support code.
- * The support code is shared with other date data types,
- * including abstime, reltime, date, and time.
+ * Definitions for the date/time and other date/time support code.
+ * The support code is shared with other date data types,
+ * including abstime, reltime, date, and time.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: dt.h,v 1.18 1997/09/04 18:44:29 thomas Exp $
+ * $Id: dt.h,v 1.19 1997/09/07 05:02:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,23 +21,26 @@
/*
* DateTime represents absolute time.
* TimeSpan represents delta time. Keep track of months (and years)
- * separately since the elapsed time spanned is unknown until instantiated
- * relative to an absolute time.
+ * separately since the elapsed time spanned is unknown until instantiated
+ * relative to an absolute time.
*
* Note that Postgres uses "time interval" to mean a bounded interval,
- * consisting of a beginning and ending time, not a time span - tgl 97/03/20
+ * consisting of a beginning and ending time, not a time span - tgl 97/03/20
*/
-typedef double DateTime;
+typedef double DateTime;
-typedef struct {
- double time; /* all time units other than months and years */
- int4 month; /* months and years, after time for alignment */
-} TimeSpan;
+typedef struct
+{
+ double time; /* all time units other than months and
+ * years */
+ int4 month; /* months and years, after time for
+ * alignment */
+} TimeSpan;
/* ----------------------------------------------------------------
- * time types + support macros
+ * time types + support macros
*
* String definitions for standard time quantities.
*
@@ -46,196 +49,202 @@ typedef struct {
* ----------------------------------------------------------------
*/
-#define DAGO "ago"
-#define DCURRENT "current"
-#define EPOCH "epoch"
-#define INVALID "invalid"
-#define EARLY "-infinity"
-#define LATE "infinity"
-#define NOW "now"
-#define TODAY "today"
-#define TOMORROW "tomorrow"
-#define YESTERDAY "yesterday"
-#define ZULU "zulu"
-
-#define DMICROSEC "usecond"
-#define DMILLISEC "msecond"
-#define DSECOND "second"
-#define DMINUTE "minute"
-#define DHOUR "hour"
-#define DDAY "day"
-#define DWEEK "week"
-#define DMONTH "month"
-#define DQUARTER "quarter"
-#define DYEAR "year"
-#define DDECADE "decade"
-#define DCENTURY "century"
-#define DMILLENIUM "millenium"
-#define DA_D "ad"
-#define DB_C "bc"
-#define DTIMEZONE "timezone"
+#define DAGO "ago"
+#define DCURRENT "current"
+#define EPOCH "epoch"
+#define INVALID "invalid"
+#define EARLY "-infinity"
+#define LATE "infinity"
+#define NOW "now"
+#define TODAY "today"
+#define TOMORROW "tomorrow"
+#define YESTERDAY "yesterday"
+#define ZULU "zulu"
+
+#define DMICROSEC "usecond"
+#define DMILLISEC "msecond"
+#define DSECOND "second"
+#define DMINUTE "minute"
+#define DHOUR "hour"
+#define DDAY "day"
+#define DWEEK "week"
+#define DMONTH "month"
+#define DQUARTER "quarter"
+#define DYEAR "year"
+#define DDECADE "decade"
+#define DCENTURY "century"
+#define DMILLENIUM "millenium"
+#define DA_D "ad"
+#define DB_C "bc"
+#define DTIMEZONE "timezone"
/*
* Fundamental time field definitions for parsing.
*
- * Meridian: am, pm, or 24-hour style.
- * Millenium: ad, bc
+ * Meridian: am, pm, or 24-hour style.
+ * Millenium: ad, bc
*/
-#define AM 0
-#define PM 1
+#define AM 0
+#define PM 1
#define HR24 2
-#define AD 0
-#define BC 1
+#define AD 0
+#define BC 1
/*
* Fields for time decoding.
* Can't have more of these than there are bits in an unsigned int
- * since these are turned into bit masks during parsing and decoding.
+ * since these are turned into bit masks during parsing and decoding.
*/
#define RESERV 0
#define MONTH 1
#define YEAR 2
-#define DAY 3
-#define TIMES 4 /* not used - thomas 1997-07-14 */
-#define TZ 5
-#define DTZ 6
+#define DAY 3
+#define TIMES 4 /* not used - thomas 1997-07-14 */
+#define TZ 5
+#define DTZ 6
#define DTZMOD 7
#define IGNORE 8
#define AMPM 9
#define HOUR 10
#define MINUTE 11
#define SECOND 12
-#define DOY 13
-#define DOW 14
+#define DOY 13
+#define DOW 14
#define UNITS 15
#define ADBC 16
/* these are only for relative dates */
-#define AGO 17
-#define ABS_BEFORE 18
-#define ABS_AFTER 19
+#define AGO 17
+#define ABS_BEFORE 18
+#define ABS_AFTER 19
/*
* Token field definitions for time parsing and decoding.
* These need to fit into the datetkn table type.
* At the moment, that means keep them within [-127,127].
* These are also used for bit masks in DecodeDateDelta()
- * so actually restrict them to within [0,31] for now.
+ * so actually restrict them to within [0,31] for now.
* - tgl 97/06/19
*/
-#define DTK_NUMBER 0
-#define DTK_STRING 1
-
-#define DTK_DATE 2
-#define DTK_TIME 3
-#define DTK_TZ 4
-#define DTK_AGO 5
-
-#define DTK_SPECIAL 6
-#define DTK_INVALID 7
-#define DTK_CURRENT 8
-#define DTK_EARLY 9
-#define DTK_LATE 10
-#define DTK_EPOCH 11
-#define DTK_NOW 12
+#define DTK_NUMBER 0
+#define DTK_STRING 1
+
+#define DTK_DATE 2
+#define DTK_TIME 3
+#define DTK_TZ 4
+#define DTK_AGO 5
+
+#define DTK_SPECIAL 6
+#define DTK_INVALID 7
+#define DTK_CURRENT 8
+#define DTK_EARLY 9
+#define DTK_LATE 10
+#define DTK_EPOCH 11
+#define DTK_NOW 12
#define DTK_YESTERDAY 13
-#define DTK_TODAY 14
+#define DTK_TODAY 14
#define DTK_TOMORROW 15
-#define DTK_ZULU 16
-
-#define DTK_DELTA 17
-#define DTK_SECOND 18
-#define DTK_MINUTE 19
-#define DTK_HOUR 20
-#define DTK_DAY 21
-#define DTK_WEEK 22
-#define DTK_MONTH 23
-#define DTK_QUARTER 24
-#define DTK_YEAR 25
-#define DTK_DECADE 26
-#define DTK_CENTURY 27
+#define DTK_ZULU 16
+
+#define DTK_DELTA 17
+#define DTK_SECOND 18
+#define DTK_MINUTE 19
+#define DTK_HOUR 20
+#define DTK_DAY 21
+#define DTK_WEEK 22
+#define DTK_MONTH 23
+#define DTK_QUARTER 24
+#define DTK_YEAR 25
+#define DTK_DECADE 26
+#define DTK_CENTURY 27
#define DTK_MILLENIUM 28
#define DTK_MILLISEC 29
#define DTK_MICROSEC 30
-#define DTK_DOW 31
+#define DTK_DOW 31
/*
* Bit mask definitions for time parsing.
*/
-#define DTK_M(t) (0x01 << (t))
+#define DTK_M(t) (0x01 << (t))
-#define DTK_DATE_M (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
-#define DTK_TIME_M (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_M(SECOND))
+#define DTK_DATE_M (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
+#define DTK_TIME_M (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_M(SECOND))
-#define MAXDATELEN 47 /* maximum possible length of an input date string */
-#define MAXDATEFIELDS 25 /* maximum possible number of fields in a date string */
-#define TOKMAXLEN 10 /* only this many chars are stored in datetktbl */
+#define MAXDATELEN 47 /* maximum possible length of an input
+ * date string */
+#define MAXDATEFIELDS 25 /* maximum possible number of fields in a
+ * date string */
+#define TOKMAXLEN 10 /* only this many chars are stored in
+ * datetktbl */
/* keep this struct small; it gets used a lot */
-typedef struct {
+typedef struct
+{
#if defined(aix)
- char *token;
+ char *token;
#else
- char token[TOKMAXLEN];
-#endif /* aix */
- char type;
- char value; /* this may be unsigned, alas */
-} datetkn;
+ char token[TOKMAXLEN];
+#endif /* aix */
+ char type;
+ char value; /* this may be unsigned, alas */
+} datetkn;
#ifdef NAN
-#define DT_INVALID (NAN)
+#define DT_INVALID (NAN)
#else
-#define DT_INVALID (DBL_MIN+DBL_MIN)
+#define DT_INVALID (DBL_MIN+DBL_MIN)
#endif
#ifdef HUGE_VAL
-#define DT_NOBEGIN (-HUGE_VAL)
-#define DT_NOEND (HUGE_VAL)
+#define DT_NOBEGIN (-HUGE_VAL)
+#define DT_NOEND (HUGE_VAL)
#else
-#define DT_NOBEGIN (-DBL_MAX)
-#define DT_NOEND (DBL_MAX)
+#define DT_NOBEGIN (-DBL_MAX)
+#define DT_NOEND (DBL_MAX)
#endif
-#define DT_CURRENT (DBL_MIN)
-#define DT_EPOCH (-DBL_MIN)
+#define DT_CURRENT (DBL_MIN)
+#define DT_EPOCH (-DBL_MIN)
-#define DATETIME_INVALID(j) {j = DT_INVALID;}
+#define DATETIME_INVALID(j) {j = DT_INVALID;}
#ifdef NAN
#define DATETIME_IS_INVALID(j) (isnan(j))
#else
#define DATETIME_IS_INVALID(j) (j == DT_INVALID)
#endif
-#define DATETIME_NOBEGIN(j) {j = DT_NOBEGIN;}
+#define DATETIME_NOBEGIN(j) {j = DT_NOBEGIN;}
#define DATETIME_IS_NOBEGIN(j) (j == DT_NOBEGIN)
-#define DATETIME_NOEND(j) {j = DT_NOEND;}
+#define DATETIME_NOEND(j) {j = DT_NOEND;}
#define DATETIME_IS_NOEND(j) (j == DT_NOEND)
-#define DATETIME_CURRENT(j) {j = DT_CURRENT;}
+#define DATETIME_CURRENT(j) {j = DT_CURRENT;}
#if defined(linux) && defined(PPC)
-extern int datetime_is_current(double j);
+extern int datetime_is_current(double j);
+
#define DATETIME_IS_CURRENT(j) datetime_is_current(j)
#else
#define DATETIME_IS_CURRENT(j) (j == DT_CURRENT)
#endif
-#define DATETIME_EPOCH(j) {j = DT_EPOCH;}
+#define DATETIME_EPOCH(j) {j = DT_EPOCH;}
#if defined(linux) && defined(PPC)
-extern int datetime_is_epoch(double j);
+extern int datetime_is_epoch(double j);
+
#define DATETIME_IS_EPOCH(j) datetime_is_epoch(j)
#else
#define DATETIME_IS_EPOCH(j) (j == DT_EPOCH)
#endif
-#define DATETIME_IS_RELATIVE(j) (DATETIME_IS_CURRENT(j) || DATETIME_IS_EPOCH(j))
+#define DATETIME_IS_RELATIVE(j) (DATETIME_IS_CURRENT(j) || DATETIME_IS_EPOCH(j))
#define DATETIME_NOT_FINITE(j) (DATETIME_IS_INVALID(j) \
- || DATETIME_IS_NOBEGIN(j) || DATETIME_IS_NOEND(j))
+ || DATETIME_IS_NOBEGIN(j) || DATETIME_IS_NOEND(j))
#define DATETIME_IS_RESERVED(j) (DATETIME_IS_RELATIVE(j) || DATETIME_NOT_FINITE(j))
-#define TIMESPAN_INVALID(j) {(j).time = DT_INVALID;}
+#define TIMESPAN_INVALID(j) {(j).time = DT_INVALID;}
#ifdef NAN
#define TIMESPAN_IS_INVALID(j) (isnan((j).time))
#else
@@ -247,76 +256,80 @@ extern int datetime_is_epoch(double j);
#define JROUND(j) (rint(((double) (j))/TIME_PREC)*TIME_PREC)
/*
- * dt.c prototypes
+ * dt.c prototypes
*/
-extern DateTime *datetime_in( char *str);
-extern char *datetime_out( DateTime *dt);
-extern bool datetime_eq(DateTime *dt1, DateTime *dt2);
-extern bool datetime_ne(DateTime *dt1, DateTime *dt2);
-extern bool datetime_lt(DateTime *dt1, DateTime *dt2);
-extern bool datetime_le(DateTime *dt1, DateTime *dt2);
-extern bool datetime_ge(DateTime *dt1, DateTime *dt2);
-extern bool datetime_gt(DateTime *dt1, DateTime *dt2);
-extern bool datetime_finite(DateTime *datetime);
-extern int datetime_cmp(DateTime *dt1, DateTime *dt2);
-extern DateTime *datetime_smaller(DateTime *dt1, DateTime *dt2);
-extern DateTime *datetime_larger(DateTime *dt1, DateTime *dt2);
+extern DateTime *datetime_in(char *str);
+extern char *datetime_out(DateTime * dt);
+extern bool datetime_eq(DateTime * dt1, DateTime * dt2);
+extern bool datetime_ne(DateTime * dt1, DateTime * dt2);
+extern bool datetime_lt(DateTime * dt1, DateTime * dt2);
+extern bool datetime_le(DateTime * dt1, DateTime * dt2);
+extern bool datetime_ge(DateTime * dt1, DateTime * dt2);
+extern bool datetime_gt(DateTime * dt1, DateTime * dt2);
+extern bool datetime_finite(DateTime * datetime);
+extern int datetime_cmp(DateTime * dt1, DateTime * dt2);
+extern DateTime *datetime_smaller(DateTime * dt1, DateTime * dt2);
+extern DateTime *datetime_larger(DateTime * dt1, DateTime * dt2);
extern TimeSpan *timespan_in(char *str);
-extern char *timespan_out(TimeSpan *span);
-extern bool timespan_eq(TimeSpan *span1, TimeSpan *span2);
-extern bool timespan_ne(TimeSpan *span1, TimeSpan *span2);
-extern bool timespan_lt(TimeSpan *span1, TimeSpan *span2);
-extern bool timespan_le(TimeSpan *span1, TimeSpan *span2);
-extern bool timespan_ge(TimeSpan *span1, TimeSpan *span2);
-extern bool timespan_gt(TimeSpan *span1, TimeSpan *span2);
-extern int timespan_cmp(TimeSpan *span1, TimeSpan *span2);
-extern TimeSpan *timespan_smaller(TimeSpan *span1, TimeSpan *span2);
-extern TimeSpan *timespan_larger(TimeSpan *span1, TimeSpan *span2);
-
-extern text *datetime_text(DateTime *datetime);
-extern DateTime *text_datetime(text *str);
-extern text *timespan_text(TimeSpan *timespan);
-extern DateTime *datetime_trunc(text *units, DateTime *datetime);
-extern TimeSpan *timespan_trunc(text *units, TimeSpan *timespan);
-extern float64 datetime_part(text *units, DateTime *datetime);
-extern float64 timespan_part(text *units, TimeSpan *timespan);
-extern text *datetime_zone(text *zone, DateTime *datetime);
-
-extern TimeSpan *timespan_um(TimeSpan *span);
-extern TimeSpan *timespan_pl(TimeSpan *span1, TimeSpan *span2);
-extern TimeSpan *timespan_mi(TimeSpan *span1, TimeSpan *span2);
-extern TimeSpan *timespan_div(TimeSpan *span1, float8 *arg2);
-
-extern TimeSpan *datetime_mi(DateTime *dt1, DateTime *dt2);
-extern DateTime *datetime_pl_span(DateTime *dt, TimeSpan *span);
-extern DateTime *datetime_mi_span(DateTime *dt, TimeSpan *span);
-extern TimeSpan *datetime_age(DateTime *dt1, DateTime *dt2);
-
-extern void GetCurrentTime(struct tm *tm);
+extern char *timespan_out(TimeSpan * span);
+extern bool timespan_eq(TimeSpan * span1, TimeSpan * span2);
+extern bool timespan_ne(TimeSpan * span1, TimeSpan * span2);
+extern bool timespan_lt(TimeSpan * span1, TimeSpan * span2);
+extern bool timespan_le(TimeSpan * span1, TimeSpan * span2);
+extern bool timespan_ge(TimeSpan * span1, TimeSpan * span2);
+extern bool timespan_gt(TimeSpan * span1, TimeSpan * span2);
+extern int timespan_cmp(TimeSpan * span1, TimeSpan * span2);
+extern TimeSpan *timespan_smaller(TimeSpan * span1, TimeSpan * span2);
+extern TimeSpan *timespan_larger(TimeSpan * span1, TimeSpan * span2);
+
+extern text *datetime_text(DateTime * datetime);
+extern DateTime *text_datetime(text * str);
+extern text *timespan_text(TimeSpan * timespan);
+extern DateTime *datetime_trunc(text * units, DateTime * datetime);
+extern TimeSpan *timespan_trunc(text * units, TimeSpan * timespan);
+extern float64 datetime_part(text * units, DateTime * datetime);
+extern float64 timespan_part(text * units, TimeSpan * timespan);
+extern text *datetime_zone(text * zone, DateTime * datetime);
+
+extern TimeSpan *timespan_um(TimeSpan * span);
+extern TimeSpan *timespan_pl(TimeSpan * span1, TimeSpan * span2);
+extern TimeSpan *timespan_mi(TimeSpan * span1, TimeSpan * span2);
+extern TimeSpan *timespan_div(TimeSpan * span1, float8 * arg2);
+
+extern TimeSpan *datetime_mi(DateTime * dt1, DateTime * dt2);
+extern DateTime *datetime_pl_span(DateTime * dt, TimeSpan * span);
+extern DateTime *datetime_mi_span(DateTime * dt, TimeSpan * span);
+extern TimeSpan *datetime_age(DateTime * dt1, DateTime * dt2);
+
+extern void GetCurrentTime(struct tm * tm);
extern DateTime SetDateTime(DateTime datetime);
-extern int tm2datetime(struct tm *tm, double fsec, int *tzp, DateTime *dt);
+extern int tm2datetime(struct tm * tm, double fsec, int *tzp, DateTime * dt);
-extern void j2date( int jd, int *year, int *month, int *day);
-extern int date2j( int year, int month, int day);
+extern void j2date(int jd, int *year, int *month, int *day);
+extern int date2j(int year, int month, int day);
-extern double time2t(const int hour, const int min, const double sec);
+extern double time2t(const int hour, const int min, const double sec);
-extern int ParseDateTime( char *timestr, char *lowstr,
- char *field[], int ftype[], int maxfields, int *numfields);
-extern int DecodeDateTime( char *field[], int ftype[],
- int nf, int *dtype, struct tm *tm, double *fsec, int *tzp);
+extern int
+ParseDateTime(char *timestr, char *lowstr,
+ char *field[], int ftype[], int maxfields, int *numfields);
+extern int
+DecodeDateTime(char *field[], int ftype[],
+ int nf, int *dtype, struct tm * tm, double *fsec, int *tzp);
-extern int DecodeTimeOnly( char *field[], int ftype[], int nf,
- int *dtype, struct tm *tm, double *fsec);
+extern int
+DecodeTimeOnly(char *field[], int ftype[], int nf,
+ int *dtype, struct tm * tm, double *fsec);
-extern int DecodeDateDelta( char *field[], int ftype[],
- int nf, int *dtype, struct tm *tm, double *fsec);
+extern int
+DecodeDateDelta(char *field[], int ftype[],
+ int nf, int *dtype, struct tm * tm, double *fsec);
-extern int EncodeDateOnly(struct tm *tm, int style, char *str);
-extern int EncodeTimeOnly(struct tm *tm, double fsec, int style, char *str);
-extern int EncodeDateTime(struct tm *tm, double fsec, int *tzp, char **tzn, int style, char *str);
-extern int EncodeTimeSpan(struct tm *tm, double fsec, int style, char *str);
+extern int EncodeDateOnly(struct tm * tm, int style, char *str);
+extern int EncodeTimeOnly(struct tm * tm, double fsec, int style, char *str);
+extern int EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, char *str);
+extern int EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str);
-#endif /* DT_H */
+#endif /* DT_H */
diff --git a/src/include/utils/dynahash.h b/src/include/utils/dynahash.h
index fe9a51d3f1b..bf04ef10739 100644
--- a/src/include/utils/dynahash.h
+++ b/src/include/utils/dynahash.h
@@ -1,19 +1,18 @@
/*-------------------------------------------------------------------------
*
* dynahash--
- * POSTGRES dynahash.h file definitions
+ * POSTGRES dynahash.h file definitions
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: dynahash.h,v 1.2 1996/11/14 20:06:39 scrappy Exp $
+ * $Id: dynahash.h,v 1.3 1997/09/07 05:02:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef DYNAHASH_H
+#ifndef DYNAHASH_H
#define DYNAHASH_H
-extern int my_log2(long num);
-
-#endif /* DYNAHASH_H */
+extern int my_log2(long num);
+#endif /* DYNAHASH_H */
diff --git a/src/include/utils/dynamic_loader.h b/src/include/utils/dynamic_loader.h
index dd346a85df9..fe8e189ff35 100644
--- a/src/include/utils/dynamic_loader.h
+++ b/src/include/utils/dynamic_loader.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* dynamic_loader.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: dynamic_loader.h,v 1.5 1997/02/14 04:18:56 momjian Exp $
+ * $Id: dynamic_loader.h,v 1.6 1997/09/07 05:02:22 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,30 +14,31 @@
#define DYNAMIC_LOADER_H
#include <sys/types.h>
-#include <sys/param.h> /* For MAXPATHLEN */
+#include <sys/param.h> /* For MAXPATHLEN */
#include <postgres.h>
#ifdef MIN
#undef MIN
#undef MAX
-#endif /* MIN */
+#endif /* MIN */
/*
* List of dynamically loaded files.
*/
-typedef struct df_files {
- char filename[MAXPATHLEN]; /* Full pathname of file */
- dev_t device; /* Device file is on */
- ino_t inode; /* Inode number of file */
- void *handle; /* a handle for pg_dl* functions */
- struct df_files *next;
-} DynamicFileList;
+typedef struct df_files
+{
+ char filename[MAXPATHLEN]; /* Full pathname of file */
+ dev_t device; /* Device file is on */
+ ino_t inode; /* Inode number of file */
+ void *handle; /* a handle for pg_dl* functions */
+ struct df_files *next;
+} DynamicFileList;
-extern void *pg_dlopen(char *filename);
+extern void *pg_dlopen(char *filename);
extern func_ptr pg_dlsym(void *handle, char *funcname);
-extern void pg_dlclose(void *handle);
-extern char *pg_dlerror(void);
+extern void pg_dlclose(void *handle);
+extern char *pg_dlerror(void);
-#endif /* DYNAMIC_LOADER_H */
+#endif /* DYNAMIC_LOADER_H */
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 3673b2bd27f..fc9305d9a0e 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -1,31 +1,31 @@
/*-------------------------------------------------------------------------
*
* elog.h--
- * POSTGRES error logging definitions.
+ * POSTGRES error logging definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: elog.h,v 1.3 1996/11/10 03:06:24 momjian Exp $
+ * $Id: elog.h,v 1.4 1997/09/07 05:02:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef ELOG_H
+#ifndef ELOG_H
#define ELOG_H
-#define NOTICE 0 /* random info - no special action */
-#define WARN -1 /* Warning error - return to known state */
-#define FATAL 1 /* Fatal error - abort process */
-#define DEBUG -2 /* debug message */
-#define NOIND -3 /* debug message, don't indent as far */
+#define NOTICE 0 /* random info - no special action */
+#define WARN -1 /* Warning error - return to known state */
+#define FATAL 1 /* Fatal error - abort process */
+#define DEBUG -2 /* debug message */
+#define NOIND -3 /* debug message, don't indent as far */
-#define PTIME 0x100 /* prepend time to message */
-#define POS 0x200 /* prepend source position to message */
-#define USERMSG 0x400 /* send message to user */
-#define TERM 0x800 /* send message to terminal */
-#define DBLOG 0x1000 /* put message in per db log */
-#define SLOG 0x2000 /* put message in system log */
-#define ABORT 0x4000 /* abort process after logging */
+#define PTIME 0x100 /* prepend time to message */
+#define POS 0x200 /* prepend source position to message */
+#define USERMSG 0x400 /* send message to user */
+#define TERM 0x800 /* send message to terminal */
+#define DBLOG 0x1000 /* put message in per db log */
+#define SLOG 0x2000 /* put message in system log */
+#define ABORT 0x4000 /* abort process after logging */
#define ELOG_MAXLEN 4096
@@ -33,9 +33,11 @@
/* uncomment the following if you want your elog's to be timestamped */
/* #define ELOG_TIMESTAMPS */
-extern void elog(int lev, const char *fmt, ...);
+extern void elog(int lev, const char *fmt,...);
+
#ifndef PG_STANDALONE
-int DebugFileOpen(void);
+int DebugFileOpen(void);
+
#endif
-#endif /* ELOG_H */
+#endif /* ELOG_H */
diff --git a/src/include/utils/exc.h b/src/include/utils/exc.h
index 12bfdfc4c80..5c240eeaa5d 100644
--- a/src/include/utils/exc.h
+++ b/src/include/utils/exc.h
@@ -1,90 +1,95 @@
/*-------------------------------------------------------------------------
*
* exc.h--
- * POSTGRES exception handling definitions.
+ * POSTGRES exception handling definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: exc.h,v 1.7 1997/08/19 21:40:32 momjian Exp $
+ * $Id: exc.h,v 1.8 1997/09/07 05:02:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef EXC_H
+#ifndef EXC_H
#define EXC_H
#include <setjmp.h>
#include "config.h"
-extern char *ExcFileName;
-extern Index ExcLineNumber;
+extern char *ExcFileName;
+extern Index ExcLineNumber;
/*
* ExcMessage and Exception are now defined in c.h
*/
#if defined(JMP_BUF)
-typedef jmp_buf ExcContext;
+typedef jmp_buf ExcContext;
+
#else
-typedef sigjmp_buf ExcContext;
+typedef sigjmp_buf ExcContext;
+
#endif
-typedef Exception* ExcId;
-typedef long ExcDetail;
-typedef char* ExcData;
-
-typedef struct ExcFrame {
- struct ExcFrame *link;
- ExcContext context;
- ExcId id;
- ExcDetail detail;
- ExcData data;
- ExcMessage message;
-} ExcFrame;
-
-extern ExcFrame* ExcCurFrameP;
-
-#define ExcBegin() \
- { \
- ExcFrame exception; \
- \
- exception.link = ExcCurFrameP; \
- if (sigsetjmp(exception.context, 1) == 0) { \
- ExcCurFrameP = &exception; \
- {
-#define ExcExcept() \
- } \
- ExcCurFrameP = exception.link; \
- } else { \
- {
-#define ExcEnd() \
- } \
- } \
- }
+typedef Exception *ExcId;
+typedef long ExcDetail;
+typedef char *ExcData;
+
+typedef struct ExcFrame
+{
+ struct ExcFrame *link;
+ ExcContext context;
+ ExcId id;
+ ExcDetail detail;
+ ExcData data;
+ ExcMessage message;
+} ExcFrame;
+
+extern ExcFrame *ExcCurFrameP;
+
+#define ExcBegin() \
+ { \
+ ExcFrame exception; \
+ \
+ exception.link = ExcCurFrameP; \
+ if (sigsetjmp(exception.context, 1) == 0) { \
+ ExcCurFrameP = &exception; \
+ {
+#define ExcExcept() \
+ } \
+ ExcCurFrameP = exception.link; \
+ } else { \
+ {
+#define ExcEnd() \
+ } \
+ } \
+ }
#define raise4(x, t, d, message) \
- ExcRaise(&(x), (ExcDetail)(t), (ExcData)(d), (ExcMessage)(message))
+ ExcRaise(&(x), (ExcDetail)(t), (ExcData)(d), (ExcMessage)(message))
-#define reraise() \
- raise4(*exception.id,exception.detail,exception.data,exception.message)
+#define reraise() \
+ raise4(*exception.id,exception.detail,exception.data,exception.message)
-typedef void ExcProc(Exception*, ExcDetail, ExcData, ExcMessage);
+typedef void ExcProc(Exception *, ExcDetail, ExcData, ExcMessage);
/*
* prototypes for functions in exc.c
*/
-extern void EnableExceptionHandling(bool on);
-extern void ExcRaise(Exception *excP,
- ExcDetail detail,
- ExcData data,
- ExcMessage message);
+extern void EnableExceptionHandling(bool on);
+extern void
+ExcRaise(Exception * excP,
+ ExcDetail detail,
+ ExcData data,
+ ExcMessage message);
/*
* prototypes for functions in excabort.c
*/
-extern void ExcAbort(const Exception *excP, ExcDetail detail, ExcData data,
- ExcMessage message);
+extern void
+ExcAbort(const Exception * excP, ExcDetail detail, ExcData data,
+ ExcMessage message);
-#endif /* EXC_H */
+#endif /* EXC_H */
diff --git a/src/include/utils/excid.h b/src/include/utils/excid.h
index be411334142..69636540746 100644
--- a/src/include/utils/excid.h
+++ b/src/include/utils/excid.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* excid.h--
- * POSTGRES known exception identifier definitions.
+ * POSTGRES known exception identifier definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: excid.h,v 1.3 1996/11/04 11:51:16 scrappy Exp $
+ * $Id: excid.h,v 1.4 1997/09/07 05:02:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef EXCID_H
+#ifndef EXCID_H
#define EXCID_H
@@ -21,9 +21,9 @@ extern Exception BadAllocSize;
extern Exception ExhaustedMemory;
extern Exception Unimplemented;
-extern Exception CatalogFailure; /* XXX inconsistent naming style */
-extern Exception InternalError; /* XXX inconsistent naming style */
-extern Exception SemanticError; /* XXX inconsistent naming style */
-extern Exception SystemError; /* XXX inconsistent naming style */
+extern Exception CatalogFailure;/* XXX inconsistent naming style */
+extern Exception InternalError; /* XXX inconsistent naming style */
+extern Exception SemanticError; /* XXX inconsistent naming style */
+extern Exception SystemError; /* XXX inconsistent naming style */
-#endif /* EXCID_H */
+#endif /* EXCID_H */
diff --git a/src/include/utils/fcache.h b/src/include/utils/fcache.h
index 9ce6e857e9d..27c3269b0e4 100644
--- a/src/include/utils/fcache.h
+++ b/src/include/utils/fcache.h
@@ -1,54 +1,54 @@
/*-------------------------------------------------------------------------
*
* fcache.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: fcache.h,v 1.2 1996/11/04 07:18:42 scrappy Exp $
+ * $Id: fcache.h,v 1.3 1997/09/07 05:02:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef FCACHE_H
-#define FCACHE_H
+#ifndef FCACHE_H
+#define FCACHE_H
typedef struct
{
- int typlen; /* length of the return type */
- int typbyval; /* true if return type is pass by value */
- func_ptr func; /* address of function to call (for c funcs) */
- Oid foid; /* oid of the function in pg_proc */
- Oid language; /* oid of the language in pg_language */
- int nargs; /* number of arguments */
-
- /* Might want to make these two arrays of size MAXFUNCARGS */
-
- Oid *argOidVect; /* oids of all the arguments */
- bool *nullVect; /* keep track of null arguments */
-
- char *src; /* source code of the function */
- char *bin; /* binary object code ?? */
- char *func_state; /* fuction_state struct for execution */
-
- bool oneResult; /* true we only want 1 result from the
- * function
- */
- bool hasSetArg; /* true if func is part of a nested dot expr
- * whose argument is func returning a set ugh!
- */
-
- Pointer funcSlot; /* if one result we need to copy it before we
- * end execution of the function and free stuff
- */
-
- char *setArg; /* current argument for nested dot execution
- * Nested dot expressions mean we have funcs
- * whose argument is a set of tuples
- */
-
- bool istrusted; /* trusted fn? */
-} FunctionCache, *FunctionCachePtr;
-
-#endif /* FCACHE_H */
+ int typlen; /* length of the return type */
+ int typbyval; /* true if return type is pass by value */
+ func_ptr func; /* address of function to call (for c
+ * funcs) */
+ Oid foid; /* oid of the function in pg_proc */
+ Oid language; /* oid of the language in pg_language */
+ int nargs; /* number of arguments */
+
+ /* Might want to make these two arrays of size MAXFUNCARGS */
+
+ Oid *argOidVect; /* oids of all the arguments */
+ bool *nullVect; /* keep track of null arguments */
+
+ char *src; /* source code of the function */
+ char *bin; /* binary object code ?? */
+ char *func_state; /* fuction_state struct for execution */
+
+ bool oneResult; /* true we only want 1 result from the
+ * function */
+ bool hasSetArg; /* true if func is part of a nested dot
+ * expr whose argument is func returning a
+ * set ugh! */
+
+ Pointer funcSlot; /* if one result we need to copy it before
+ * we end execution of the function and
+ * free stuff */
+
+ char *setArg; /* current argument for nested dot
+ * execution Nested dot expressions mean
+ * we have funcs whose argument is a set
+ * of tuples */
+
+ bool istrusted; /* trusted fn? */
+} FunctionCache, *FunctionCachePtr;
+
+#endif /* FCACHE_H */
diff --git a/src/include/utils/fcache2.h b/src/include/utils/fcache2.h
index 7c48406a966..781ff241393 100644
--- a/src/include/utils/fcache2.h
+++ b/src/include/utils/fcache2.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* fcache2.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: fcache2.h,v 1.2 1996/11/04 08:53:07 scrappy Exp $
+ * $Id: fcache2.h,v 1.3 1997/09/07 05:02:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,6 +16,6 @@
#include <nodes/execnodes.h>
extern void
-setFcache(Node *node, Oid foid, List *argList, ExprContext *econtext);
+ setFcache(Node * node, Oid foid, List * argList, ExprContext * econtext);
-#endif /* FCACHE2_H */
+#endif /* FCACHE2_H */
diff --git a/src/include/utils/fmgrtab.h b/src/include/utils/fmgrtab.h
index eac11a76802..e23f7c79266 100644
--- a/src/include/utils/fmgrtab.h
+++ b/src/include/utils/fmgrtab.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* fmgrtab.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: fmgrtab.h,v 1.4 1996/11/10 03:06:27 momjian Exp $
+ * $Id: fmgrtab.h,v 1.5 1997/09/07 05:02:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,15 +14,16 @@
#define FMGRTAB_H
-typedef struct {
- Oid proid;
- uint16 nargs;
- func_ptr func;
- char* funcName;
-} FmgrCall;
+typedef struct
+{
+ Oid proid;
+ uint16 nargs;
+ func_ptr func;
+ char *funcName;
+} FmgrCall;
-extern FmgrCall *fmgr_isbuiltin(Oid id);
-extern func_ptr fmgr_lookupByName(char* name);
-extern void load_file(char *filename);
+extern FmgrCall *fmgr_isbuiltin(Oid id);
+extern func_ptr fmgr_lookupByName(char *name);
+extern void load_file(char *filename);
-#endif /* FMGRTAB_H */
+#endif /* FMGRTAB_H */
diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h
index 782d71fed4a..4cbbeca3b82 100644
--- a/src/include/utils/geo_decls.h
+++ b/src/include/utils/geo_decls.h
@@ -5,19 +5,19 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geo_decls.h,v 1.8 1997/08/21 01:40:30 vadim Exp $
+ * $Id: geo_decls.h,v 1.9 1997/09/07 05:02:34 momjian Exp $
*
* NOTE
- * These routines do *not* use the float types from adt/.
+ * These routines do *not* use the float types from adt/.
*
- * XXX These routines were not written by a numerical analyst.
- * XXX I have made some attempt to flesh out the operators
- * and data types. There are still some more to do. - tgl 97/04/19
+ * XXX These routines were not written by a numerical analyst.
+ * XXX I have made some attempt to flesh out the operators
+ * and data types. There are still some more to do. - tgl 97/04/19
*
*-------------------------------------------------------------------------
*/
-#ifndef GEO_DECLS_H
-#define GEO_DECLS_H
+#ifndef GEO_DECLS_H
+#define GEO_DECLS_H
#include "access/attnum.h"
@@ -28,321 +28,334 @@
*-------------------------------------------------------------------*/
-#define EPSILON 1.0E-06
+#define EPSILON 1.0E-06
#ifdef EPSILON
-#define FPzero(A) (fabs(A) <= EPSILON)
-#define FPeq(A,B) (fabs((A) - (B)) <= EPSILON)
-#define FPlt(A,B) ((B) - (A) > EPSILON)
-#define FPle(A,B) ((A) - (B) <= EPSILON)
-#define FPgt(A,B) ((A) - (B) > EPSILON)
-#define FPge(A,B) ((B) - (A) <= EPSILON)
+#define FPzero(A) (fabs(A) <= EPSILON)
+#define FPeq(A,B) (fabs((A) - (B)) <= EPSILON)
+#define FPlt(A,B) ((B) - (A) > EPSILON)
+#define FPle(A,B) ((A) - (B) <= EPSILON)
+#define FPgt(A,B) ((A) - (B) > EPSILON)
+#define FPge(A,B) ((B) - (A) <= EPSILON)
#else
-#define FPzero(A) (A == 0)
-#define FPnzero(A) (A != 0)
-#define FPeq(A,B) (A == B)
-#define FPne(A,B) (A != B)
-#define FPlt(A,B) (A < B)
-#define FPle(A,B) (A <= B)
-#define FPgt(A,B) (A > B)
-#define FPge(A,B) (A >= B)
+#define FPzero(A) (A == 0)
+#define FPnzero(A) (A != 0)
+#define FPeq(A,B) (A == B)
+#define FPne(A,B) (A != B)
+#define FPlt(A,B) (A < B)
+#define FPle(A,B) (A <= B)
+#define FPgt(A,B) (A > B)
+#define FPge(A,B) (A >= B)
#endif
-#define HYPOT(A, B) sqrt((A) * (A) + (B) * (B))
+#define HYPOT(A, B) sqrt((A) * (A) + (B) * (B))
/*--------------------------------------------------------------------
* Memory management.
*-------------------------------------------------------------------*/
-#define PALLOC(SIZE) palloc(SIZE)
-#define PFREE(P) pfree(P)
-#define PALLOCTYPE(TYPE) (TYPE *) PALLOC(sizeof(TYPE))
+#define PALLOC(SIZE) palloc(SIZE)
+#define PFREE(P) pfree(P)
+#define PALLOCTYPE(TYPE) (TYPE *) PALLOC(sizeof(TYPE))
/*#endif !FmgrIncluded */
/*---------------------------------------------------------------------
* Point - (x,y)
*-------------------------------------------------------------------*/
-typedef struct {
- double x, y;
-} Point;
+typedef struct
+{
+ double x,
+ y;
+} Point;
/*---------------------------------------------------------------------
- * LSEG - A straight line, specified by endpoints.
+ * LSEG - A straight line, specified by endpoints.
*-------------------------------------------------------------------*/
-typedef struct {
- Point p[2];
+typedef struct
+{
+ Point p[2];
- double m; /* precomputed to save time, not in tuple */
-} LSEG;
+ double m; /* precomputed to save time, not in tuple */
+} LSEG;
/*---------------------------------------------------------------------
- * PATH - Specified by vertex points.
+ * PATH - Specified by vertex points.
*-------------------------------------------------------------------*/
-typedef struct {
- int32 size; /* XXX varlena */
- int32 npts;
- int32 closed; /* is this a closed polygon? */
- int32 dummy; /* padding to make it double align */
- Point p[1]; /* variable length array of POINTs */
-} PATH;
+typedef struct
+{
+ int32 size; /* XXX varlena */
+ int32 npts;
+ int32 closed; /* is this a closed polygon? */
+ int32 dummy; /* padding to make it double align */
+ Point p[1]; /* variable length array of POINTs */
+} PATH;
/*---------------------------------------------------------------------
- * LINE - Specified by its general equation (Ax+By+C=0).
- * If there is a y-intercept, it is C, which
- * incidentally gives a freebie point on the line
- * (if B=0, then C is the x-intercept).
- * Slope m is precalculated to save time; if
- * the line is not vertical, m == A.
+ * LINE - Specified by its general equation (Ax+By+C=0).
+ * If there is a y-intercept, it is C, which
+ * incidentally gives a freebie point on the line
+ * (if B=0, then C is the x-intercept).
+ * Slope m is precalculated to save time; if
+ * the line is not vertical, m == A.
*-------------------------------------------------------------------*/
-typedef struct {
- double A, B, C;
+typedef struct
+{
+ double A,
+ B,
+ C;
- double m;
-} LINE;
+ double m;
+} LINE;
/*---------------------------------------------------------------------
* BOX - Specified by two corner points, which are
- * sorted to save calculation time later.
+ * sorted to save calculation time later.
*-------------------------------------------------------------------*/
-typedef struct {
- Point high, low; /* corner POINTs */
-} BOX;
+typedef struct
+{
+ Point high,
+ low; /* corner POINTs */
+} BOX;
/*---------------------------------------------------------------------
- * POLYGON - Specified by an array of doubles defining the points,
- * keeping the number of points and the bounding box for
- * speed purposes.
+ * POLYGON - Specified by an array of doubles defining the points,
+ * keeping the number of points and the bounding box for
+ * speed purposes.
*-------------------------------------------------------------------*/
-typedef struct {
- int32 size; /* XXX varlena */
- int32 npts;
- BOX boundbox;
- Point p[1]; /* variable length array of POINTs */
-} POLYGON;
+typedef struct
+{
+ int32 size; /* XXX varlena */
+ int32 npts;
+ BOX boundbox;
+ Point p[1]; /* variable length array of POINTs */
+} POLYGON;
/*---------------------------------------------------------------------
* CIRCLE - Specified by a center point and radius.
*-------------------------------------------------------------------*/
-typedef struct {
- Point center;
- double radius;
-} CIRCLE;
+typedef struct
+{
+ Point center;
+ double radius;
+} CIRCLE;
-/*
+/*
* in geo_ops.h
*/
/* public point routines */
-extern Point *point_in(char *str);
-extern char *point_out(Point *pt);
-extern bool point_left(Point *pt1, Point *pt2);
-extern bool point_right(Point *pt1, Point *pt2);
-extern bool point_above(Point *pt1, Point *pt2);
-extern bool point_below(Point *pt1, Point *pt2);
-extern bool point_vert(Point *pt1, Point *pt2);
-extern bool point_horiz(Point *pt1, Point *pt2);
-extern bool point_eq(Point *pt1, Point *pt2);
-extern int32 pointdist(Point *p1, Point *p2);
-extern double *point_distance(Point *pt1, Point *pt2);
-extern double *point_slope(Point *pt1, Point *pt2);
+extern Point *point_in(char *str);
+extern char *point_out(Point * pt);
+extern bool point_left(Point * pt1, Point * pt2);
+extern bool point_right(Point * pt1, Point * pt2);
+extern bool point_above(Point * pt1, Point * pt2);
+extern bool point_below(Point * pt1, Point * pt2);
+extern bool point_vert(Point * pt1, Point * pt2);
+extern bool point_horiz(Point * pt1, Point * pt2);
+extern bool point_eq(Point * pt1, Point * pt2);
+extern int32 pointdist(Point * p1, Point * p2);
+extern double *point_distance(Point * pt1, Point * pt2);
+extern double *point_slope(Point * pt1, Point * pt2);
/* private routines */
-extern double point_dt(Point *pt1, Point *pt2);
-extern double point_sl(Point *pt1, Point *pt2);
+extern double point_dt(Point * pt1, Point * pt2);
+extern double point_sl(Point * pt1, Point * pt2);
-extern Point *point(float8 *x, float8 *y);
-extern Point *point_add(Point *p1, Point *p2);
-extern Point *point_sub(Point *p1, Point *p2);
-extern Point *point_mul(Point *p1, Point *p2);
-extern Point *point_div(Point *p1, Point *p2);
+extern Point *point(float8 * x, float8 * y);
+extern Point *point_add(Point * p1, Point * p2);
+extern Point *point_sub(Point * p1, Point * p2);
+extern Point *point_mul(Point * p1, Point * p2);
+extern Point *point_div(Point * p1, Point * p2);
/* public lseg routines */
-extern LSEG *lseg_in(char *str);
-extern char *lseg_out(LSEG *ls);
-extern bool lseg_intersect(LSEG *l1, LSEG *l2);
-extern bool lseg_parallel(LSEG *l1, LSEG *l2);
-extern bool lseg_perp(LSEG *l1, LSEG *l2);
-extern bool lseg_vertical(LSEG *lseg);
-extern bool lseg_horizontal(LSEG *lseg);
-extern bool lseg_eq(LSEG *l1, LSEG *l2);
-extern double *lseg_distance(LSEG *l1, LSEG *l2);
-extern Point *lseg_center(LSEG *lseg);
-extern Point *lseg_interpt(LSEG *l1, LSEG *l2);
-extern double *dist_pl(Point *pt, LINE *line);
-extern double *dist_ps(Point *pt, LSEG *lseg);
-extern double *dist_ppath(Point *pt, PATH *path);
-extern double *dist_pb(Point *pt, BOX *box);
-extern double *dist_sl(LSEG *lseg, LINE *line);
-extern double *dist_sb(LSEG *lseg, BOX *box);
-extern double *dist_lb(LINE *line, BOX *box);
-extern Point *close_pl(Point *pt, LINE *line);
-extern Point *close_ps(Point *pt, LSEG *lseg);
-extern Point *close_pb(Point *pt, BOX *box);
-extern Point *close_sl(LSEG *lseg, LINE *line);
-extern Point *close_sb(LSEG *lseg, BOX *box);
-extern Point *close_lb(LINE *line, BOX *box);
-extern bool on_pl(Point *pt, LINE *line);
-extern bool on_ps(Point *pt, LSEG *lseg);
-extern bool on_pb(Point *pt, BOX *box);
-extern bool on_ppath(Point *pt, PATH *path);
-extern bool on_sl(LSEG *lseg, LINE *line);
-extern bool on_sb(LSEG *lseg, BOX *box);
-extern bool inter_sl(LSEG *lseg, LINE *line);
-extern bool inter_sb(LSEG *lseg, BOX *box);
-extern bool inter_lb(LINE *line, BOX *box);
+extern LSEG *lseg_in(char *str);
+extern char *lseg_out(LSEG * ls);
+extern bool lseg_intersect(LSEG * l1, LSEG * l2);
+extern bool lseg_parallel(LSEG * l1, LSEG * l2);
+extern bool lseg_perp(LSEG * l1, LSEG * l2);
+extern bool lseg_vertical(LSEG * lseg);
+extern bool lseg_horizontal(LSEG * lseg);
+extern bool lseg_eq(LSEG * l1, LSEG * l2);
+extern double *lseg_distance(LSEG * l1, LSEG * l2);
+extern Point *lseg_center(LSEG * lseg);
+extern Point *lseg_interpt(LSEG * l1, LSEG * l2);
+extern double *dist_pl(Point * pt, LINE * line);
+extern double *dist_ps(Point * pt, LSEG * lseg);
+extern double *dist_ppath(Point * pt, PATH * path);
+extern double *dist_pb(Point * pt, BOX * box);
+extern double *dist_sl(LSEG * lseg, LINE * line);
+extern double *dist_sb(LSEG * lseg, BOX * box);
+extern double *dist_lb(LINE * line, BOX * box);
+extern Point *close_pl(Point * pt, LINE * line);
+extern Point *close_ps(Point * pt, LSEG * lseg);
+extern Point *close_pb(Point * pt, BOX * box);
+extern Point *close_sl(LSEG * lseg, LINE * line);
+extern Point *close_sb(LSEG * lseg, BOX * box);
+extern Point *close_lb(LINE * line, BOX * box);
+extern bool on_pl(Point * pt, LINE * line);
+extern bool on_ps(Point * pt, LSEG * lseg);
+extern bool on_pb(Point * pt, BOX * box);
+extern bool on_ppath(Point * pt, PATH * path);
+extern bool on_sl(LSEG * lseg, LINE * line);
+extern bool on_sb(LSEG * lseg, BOX * box);
+extern bool inter_sl(LSEG * lseg, LINE * line);
+extern bool inter_sb(LSEG * lseg, BOX * box);
+extern bool inter_lb(LINE * line, BOX * box);
/* private routines */
-extern LSEG *lseg_construct(Point *pt1, Point *pt2);
+extern LSEG *lseg_construct(Point * pt1, Point * pt2);
/* public box routines */
-extern BOX *box_in(char *str);
-extern char *box_out(BOX *box);
-extern bool box_same(BOX *box1, BOX *box2);
-extern bool box_overlap(BOX *box1, BOX *box2);
-extern bool box_overleft(BOX *box1, BOX *box2);
-extern bool box_left(BOX *box1, BOX *box2);
-extern bool box_right(BOX *box1, BOX *box2);
-extern bool box_overright(BOX *box1, BOX *box2);
-extern bool box_contained(BOX *box1, BOX *box2);
-extern bool box_contain(BOX *box1, BOX *box2);
-extern bool box_below(BOX *box1, BOX *box2);
-extern bool box_above(BOX *box1, BOX *box2);
-extern bool box_lt(BOX *box1, BOX *box2);
-extern bool box_gt(BOX *box1, BOX *box2);
-extern bool box_eq(BOX *box1, BOX *box2);
-extern bool box_le(BOX *box1, BOX *box2);
-extern bool box_ge(BOX *box1, BOX *box2);
-extern Point *box_center(BOX *box);
-extern double *box_area(BOX *box);
-extern double *box_width(BOX *box);
-extern double *box_height(BOX *box);
-extern double *box_distance(BOX *box1, BOX *box2);
-extern Point *box_center(BOX *box);
-extern BOX *box_intersect(BOX *box1, BOX *box2);
-extern LSEG *box_diagonal(BOX *box);
+extern BOX *box_in(char *str);
+extern char *box_out(BOX * box);
+extern bool box_same(BOX * box1, BOX * box2);
+extern bool box_overlap(BOX * box1, BOX * box2);
+extern bool box_overleft(BOX * box1, BOX * box2);
+extern bool box_left(BOX * box1, BOX * box2);
+extern bool box_right(BOX * box1, BOX * box2);
+extern bool box_overright(BOX * box1, BOX * box2);
+extern bool box_contained(BOX * box1, BOX * box2);
+extern bool box_contain(BOX * box1, BOX * box2);
+extern bool box_below(BOX * box1, BOX * box2);
+extern bool box_above(BOX * box1, BOX * box2);
+extern bool box_lt(BOX * box1, BOX * box2);
+extern bool box_gt(BOX * box1, BOX * box2);
+extern bool box_eq(BOX * box1, BOX * box2);
+extern bool box_le(BOX * box1, BOX * box2);
+extern bool box_ge(BOX * box1, BOX * box2);
+extern Point *box_center(BOX * box);
+extern double *box_area(BOX * box);
+extern double *box_width(BOX * box);
+extern double *box_height(BOX * box);
+extern double *box_distance(BOX * box1, BOX * box2);
+extern Point *box_center(BOX * box);
+extern BOX *box_intersect(BOX * box1, BOX * box2);
+extern LSEG *box_diagonal(BOX * box);
/* private routines */
-extern double box_dt(BOX *box1, BOX *box2);
+extern double box_dt(BOX * box1, BOX * box2);
-extern BOX *box(Point *p1, Point *p2);
-extern BOX *box_add(BOX *box, Point *p);
-extern BOX *box_sub(BOX *box, Point *p);
-extern BOX *box_mul(BOX *box, Point *p);
-extern BOX *box_div(BOX *box, Point *p);
+extern BOX *box(Point * p1, Point * p2);
+extern BOX *box_add(BOX * box, Point * p);
+extern BOX *box_sub(BOX * box, Point * p);
+extern BOX *box_mul(BOX * box, Point * p);
+extern BOX *box_div(BOX * box, Point * p);
/* private line routines */
-extern double *line_distance(LINE *l1, LINE *l2);
+extern double *line_distance(LINE * l1, LINE * l2);
/* public path routines */
-extern PATH *path_in(char *str);
-extern char *path_out(PATH *path);
-extern bool path_n_lt(PATH *p1, PATH *p2);
-extern bool path_n_gt(PATH *p1, PATH *p2);
-extern bool path_n_eq(PATH *p1, PATH *p2);
-extern bool path_n_le(PATH *p1, PATH *p2);
-extern bool path_n_ge(PATH *p1, PATH *p2);
-extern bool path_inter(PATH *p1, PATH *p2);
-extern double *path_distance(PATH *p1, PATH *p2);
-extern double *path_length(PATH *path);
-
-extern bool path_isclosed(PATH *path);
-extern bool path_isopen(PATH *path);
-extern int4 path_npoints(PATH *path);
-
-extern PATH *path_close(PATH *path);
-extern PATH *path_open(PATH *path);
-extern PATH *path_add(PATH *p1, PATH *p2);
-extern PATH *path_add_pt(PATH *path, Point *point);
-extern PATH *path_sub_pt(PATH *path, Point *point);
-extern PATH *path_mul_pt(PATH *path, Point *point);
-extern PATH *path_div_pt(PATH *path, Point *point);
-extern bool path_contain_pt( PATH *path, Point *p);
-extern bool pt_contained_path( Point *p, PATH *path);
-
-extern Point *path_center(PATH *path);
-extern POLYGON *path_poly(PATH *path);
-
-extern PATH *upgradepath(PATH *path);
-extern bool isoldpath(PATH *path);
+extern PATH *path_in(char *str);
+extern char *path_out(PATH * path);
+extern bool path_n_lt(PATH * p1, PATH * p2);
+extern bool path_n_gt(PATH * p1, PATH * p2);
+extern bool path_n_eq(PATH * p1, PATH * p2);
+extern bool path_n_le(PATH * p1, PATH * p2);
+extern bool path_n_ge(PATH * p1, PATH * p2);
+extern bool path_inter(PATH * p1, PATH * p2);
+extern double *path_distance(PATH * p1, PATH * p2);
+extern double *path_length(PATH * path);
+
+extern bool path_isclosed(PATH * path);
+extern bool path_isopen(PATH * path);
+extern int4 path_npoints(PATH * path);
+
+extern PATH *path_close(PATH * path);
+extern PATH *path_open(PATH * path);
+extern PATH *path_add(PATH * p1, PATH * p2);
+extern PATH *path_add_pt(PATH * path, Point * point);
+extern PATH *path_sub_pt(PATH * path, Point * point);
+extern PATH *path_mul_pt(PATH * path, Point * point);
+extern PATH *path_div_pt(PATH * path, Point * point);
+extern bool path_contain_pt(PATH * path, Point * p);
+extern bool pt_contained_path(Point * p, PATH * path);
+
+extern Point *path_center(PATH * path);
+extern POLYGON *path_poly(PATH * path);
+
+extern PATH *upgradepath(PATH * path);
+extern bool isoldpath(PATH * path);
/* public polygon routines */
extern POLYGON *poly_in(char *s);
-extern char *poly_out(POLYGON *poly);
-extern bool poly_left(POLYGON *polya, POLYGON *polyb);
-extern bool poly_overleft(POLYGON *polya, POLYGON *polyb);
-extern bool poly_right(POLYGON *polya, POLYGON *polyb);
-extern bool poly_overright(POLYGON *polya, POLYGON *polyb);
-extern bool poly_same(POLYGON *polya, POLYGON *polyb);
-extern bool poly_overlap(POLYGON *polya, POLYGON *polyb);
-extern bool poly_contain(POLYGON *polya, POLYGON *polyb);
-extern bool poly_contained(POLYGON *polya, POLYGON *polyb);
-extern bool poly_contain_pt( POLYGON *poly, Point *p);
-extern bool pt_contained_poly( Point *p, POLYGON *poly);
-
-extern double *poly_distance(POLYGON *polya, POLYGON *polyb);
-extern int4 poly_npoints(POLYGON *poly);
-extern Point *poly_center(POLYGON *poly);
-extern BOX *poly_box(POLYGON *poly);
-extern PATH *poly_path(POLYGON *poly);
-extern POLYGON *box_poly(BOX *box);
-
-extern POLYGON *upgradepoly(POLYGON *poly);
-extern POLYGON *revertpoly(POLYGON *poly);
+extern char *poly_out(POLYGON * poly);
+extern bool poly_left(POLYGON * polya, POLYGON * polyb);
+extern bool poly_overleft(POLYGON * polya, POLYGON * polyb);
+extern bool poly_right(POLYGON * polya, POLYGON * polyb);
+extern bool poly_overright(POLYGON * polya, POLYGON * polyb);
+extern bool poly_same(POLYGON * polya, POLYGON * polyb);
+extern bool poly_overlap(POLYGON * polya, POLYGON * polyb);
+extern bool poly_contain(POLYGON * polya, POLYGON * polyb);
+extern bool poly_contained(POLYGON * polya, POLYGON * polyb);
+extern bool poly_contain_pt(POLYGON * poly, Point * p);
+extern bool pt_contained_poly(Point * p, POLYGON * poly);
+
+extern double *poly_distance(POLYGON * polya, POLYGON * polyb);
+extern int4 poly_npoints(POLYGON * poly);
+extern Point *poly_center(POLYGON * poly);
+extern BOX *poly_box(POLYGON * poly);
+extern PATH *poly_path(POLYGON * poly);
+extern POLYGON *box_poly(BOX * box);
+
+extern POLYGON *upgradepoly(POLYGON * poly);
+extern POLYGON *revertpoly(POLYGON * poly);
/* private polygon routines */
/* public circle routines */
-extern CIRCLE *circle_in(char *str);
-extern char *circle_out(CIRCLE *circle);
-extern bool circle_same(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_overlap(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_overleft(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_left(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_right(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_overright(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_contained(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_contain(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_below(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_above(CIRCLE *circle1, CIRCLE *circle2);
-
-extern bool circle_eq(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_ne(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_lt(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_gt(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_le(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_ge(CIRCLE *circle1, CIRCLE *circle2);
-extern bool circle_contain_pt(CIRCLE *circle, Point *point);
-extern bool pt_contained_circle(Point *point, CIRCLE *circle);
-extern CIRCLE *circle_add_pt(CIRCLE *circle, Point *point);
-extern CIRCLE *circle_sub_pt(CIRCLE *circle, Point *point);
-extern CIRCLE *circle_mul_pt(CIRCLE *circle, Point *point);
-extern CIRCLE *circle_div_pt(CIRCLE *circle, Point *point);
-extern double *circle_diameter(CIRCLE *circle);
-extern double *circle_radius(CIRCLE *circle);
-extern double *circle_distance(CIRCLE *circle1, CIRCLE *circle2);
-extern double *dist_pc(Point *point, CIRCLE *circle);
-extern double *dist_cpoly(CIRCLE *circle, POLYGON *poly);
-extern Point *circle_center(CIRCLE *circle);
-extern CIRCLE *circle(Point *center, float8 *radius);
-extern CIRCLE *box_circle(BOX *box);
-extern BOX *circle_box(CIRCLE *circle);
-extern CIRCLE *poly_circle(POLYGON *poly);
-extern POLYGON *circle_poly(int npts, CIRCLE *circle);
+extern CIRCLE *circle_in(char *str);
+extern char *circle_out(CIRCLE * circle);
+extern bool circle_same(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_overlap(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_overleft(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_left(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_right(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_overright(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_contained(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_contain(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_below(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_above(CIRCLE * circle1, CIRCLE * circle2);
+
+extern bool circle_eq(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_ne(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_lt(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_gt(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_le(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_ge(CIRCLE * circle1, CIRCLE * circle2);
+extern bool circle_contain_pt(CIRCLE * circle, Point * point);
+extern bool pt_contained_circle(Point * point, CIRCLE * circle);
+extern CIRCLE *circle_add_pt(CIRCLE * circle, Point * point);
+extern CIRCLE *circle_sub_pt(CIRCLE * circle, Point * point);
+extern CIRCLE *circle_mul_pt(CIRCLE * circle, Point * point);
+extern CIRCLE *circle_div_pt(CIRCLE * circle, Point * point);
+extern double *circle_diameter(CIRCLE * circle);
+extern double *circle_radius(CIRCLE * circle);
+extern double *circle_distance(CIRCLE * circle1, CIRCLE * circle2);
+extern double *dist_pc(Point * point, CIRCLE * circle);
+extern double *dist_cpoly(CIRCLE * circle, POLYGON * poly);
+extern Point *circle_center(CIRCLE * circle);
+extern CIRCLE *circle(Point * center, float8 * radius);
+extern CIRCLE *box_circle(BOX * box);
+extern BOX *circle_box(CIRCLE * circle);
+extern CIRCLE *poly_circle(POLYGON * poly);
+extern POLYGON *circle_poly(int npts, CIRCLE * circle);
/* private routines */
-extern double *circle_area(CIRCLE *circle);
-extern double circle_dt(CIRCLE *circle1, CIRCLE *circle2);
+extern double *circle_area(CIRCLE * circle);
+extern double circle_dt(CIRCLE * circle1, CIRCLE * circle2);
/* geo_selfuncs.c */
-extern float64 areasel(Oid opid, Oid relid, AttrNumber attno,
- char *value, int32 flag);
-extern float64 areajoinsel(Oid opid, Oid relid, AttrNumber attno,
- char *value, int32 flag);
-
-#endif /* GEO_DECLS_H */
+extern float64
+areasel(Oid opid, Oid relid, AttrNumber attno,
+ char *value, int32 flag);
+extern float64
+areajoinsel(Oid opid, Oid relid, AttrNumber attno,
+ char *value, int32 flag);
+
+#endif /* GEO_DECLS_H */
diff --git a/src/include/utils/hsearch.h b/src/include/utils/hsearch.h
index 3f5727fba0f..577e6edfcdc 100644
--- a/src/include/utils/hsearch.h
+++ b/src/include/utils/hsearch.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* hsearch.h--
- * for hashing in the new buffer manager
+ * for hashing in the new buffer manager
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: hsearch.h,v 1.3 1997/08/19 21:40:35 momjian Exp $
+ * $Id: hsearch.h,v 1.4 1997/09/07 05:02:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,123 +17,131 @@
/*
* Constants
*/
-# define DEF_BUCKET_SIZE 256
-# define DEF_BUCKET_SHIFT 8 /* log2(BUCKET) */
-# define DEF_SEGSIZE 256
-# define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
-# define DEF_DIRSIZE 256
-# define PRIME1 37
-# define PRIME2 1048583
-# define DEF_FFACTOR 1
-# define SPLTMAX 8
+#define DEF_BUCKET_SIZE 256
+#define DEF_BUCKET_SHIFT 8/* log2(BUCKET) */
+#define DEF_SEGSIZE 256
+#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
+#define DEF_DIRSIZE 256
+#define PRIME1 37
+#define PRIME2 1048583
+#define DEF_FFACTOR 1
+#define SPLTMAX 8
/*
* Hash bucket is actually bigger than this. Key field can have
* variable length and a variable length data field follows it.
*/
-typedef struct element {
- unsigned long next; /* secret from user */
- long key;
-} ELEMENT;
+typedef struct element
+{
+ unsigned long next; /* secret from user */
+ long key;
+} ELEMENT;
typedef unsigned long BUCKET_INDEX;
+
/* segment is an array of bucket pointers */
typedef BUCKET_INDEX *SEGMENT;
typedef unsigned long SEG_OFFSET;
-typedef struct hashhdr {
- long bsize; /* Bucket/Page Size */
- long bshift; /* Bucket shift */
- long dsize; /* Directory Size */
- long ssize; /* Segment Size */
- long sshift; /* Segment shift */
- long max_bucket; /* ID of Maximum bucket in use */
- long high_mask; /* Mask to modulo into entire table */
- long low_mask; /* Mask to modulo into lower half of table */
- long ffactor; /* Fill factor */
- long nkeys; /* Number of keys in hash table */
- long nsegs; /* Number of allocated segments */
- long keysize; /* hash key length in bytes */
- long datasize; /* elem data length in bytes */
- long max_dsize; /* 'dsize' limit if directory is fixed size */
- BUCKET_INDEX freeBucketIndex;
- /* index of first free bucket */
+typedef struct hashhdr
+{
+ long bsize; /* Bucket/Page Size */
+ long bshift; /* Bucket shift */
+ long dsize; /* Directory Size */
+ long ssize; /* Segment Size */
+ long sshift; /* Segment shift */
+ long max_bucket; /* ID of Maximum bucket in use */
+ long high_mask; /* Mask to modulo into entire table */
+ long low_mask; /* Mask to modulo into lower half of table */
+ long ffactor; /* Fill factor */
+ long nkeys; /* Number of keys in hash table */
+ long nsegs; /* Number of allocated segments */
+ long keysize; /* hash key length in bytes */
+ long datasize; /* elem data length in bytes */
+ long max_dsize; /* 'dsize' limit if directory is fixed
+ * size */
+ BUCKET_INDEX freeBucketIndex;
+ /* index of first free bucket */
#ifdef HASH_STATISTICS
- long accesses;
- long collisions;
+ long accesses;
+ long collisions;
#endif
-} HHDR;
-
-typedef struct htab {
- HHDR *hctl; /* shared control information */
- long (*hash)(); /* Hash Function */
- char *segbase; /* segment base address for
- * calculating pointer values
- */
- SEG_OFFSET *dir; /* 'directory' of segm starts */
- long *(*alloc)(); /* memory allocator
- * (long * for alignment reasons)
- */
-
-} HTAB;
-
-typedef struct hashctl {
- long bsize; /* Bucket Size */
- long ssize; /* Segment Size */
- long dsize; /* Dirsize Size */
- long ffactor; /* Fill factor */
- long (*hash)(); /* Hash Function */
- long keysize; /* hash key length in bytes */
- long datasize; /* elem data length in bytes */
- long max_size; /* limit to dsize if directory size is limited */
- long *segbase; /* base for calculating bucket + seg ptrs */
- long * (*alloc)(); /* memory allocation function */
- long *dir; /* directory if allocated already */
- long *hctl; /* location of header information in shd mem */
-} HASHCTL;
+} HHDR;
+
+typedef struct htab
+{
+ HHDR *hctl; /* shared control information */
+ long (*hash) (); /* Hash Function */
+ char *segbase; /* segment base address for calculating
+ * pointer values */
+ SEG_OFFSET *dir; /* 'directory' of segm starts */
+ long *(*alloc) ();/* memory allocator (long * for alignment
+ * reasons) */
+
+} HTAB;
+
+typedef struct hashctl
+{
+ long bsize; /* Bucket Size */
+ long ssize; /* Segment Size */
+ long dsize; /* Dirsize Size */
+ long ffactor; /* Fill factor */
+ long (*hash) (); /* Hash Function */
+ long keysize; /* hash key length in bytes */
+ long datasize; /* elem data length in bytes */
+ long max_size; /* limit to dsize if directory size is
+ * limited */
+ long *segbase; /* base for calculating bucket + seg ptrs */
+ long *(*alloc) ();/* memory allocation function */
+ long *dir; /* directory if allocated already */
+ long *hctl; /* location of header information in shd
+ * mem */
+} HASHCTL;
/* Flags to indicate action for hctl */
-#define HASH_BUCKET 0x001 /* Setting bucket size */
+#define HASH_BUCKET 0x001 /* Setting bucket size */
#define HASH_SEGMENT 0x002 /* Setting segment size */
#define HASH_DIRSIZE 0x004 /* Setting directory size */
#define HASH_FFACTOR 0x008 /* Setting fill factor */
#define HASH_FUNCTION 0x010 /* Set user defined hash function */
-#define HASH_ELEM 0x020 /* Setting key/data size */
-#define HASH_SHARED_MEM 0x040 /* Setting shared mem const */
-#define HASH_ATTACH 0x080 /* Do not initialize hctl */
-#define HASH_ALLOC 0x100 /* Setting memory allocator */
+#define HASH_ELEM 0x020 /* Setting key/data size */
+#define HASH_SHARED_MEM 0x040 /* Setting shared mem const */
+#define HASH_ATTACH 0x080 /* Do not initialize hctl */
+#define HASH_ALLOC 0x100 /* Setting memory allocator */
/* seg_alloc assumes that INVALID_INDEX is 0*/
-#define INVALID_INDEX (0)
-#define NO_MAX_DSIZE (-1)
+#define INVALID_INDEX (0)
+#define NO_MAX_DSIZE (-1)
/* number of hash buckets allocated at once */
-#define BUCKET_ALLOC_INCR (30)
+#define BUCKET_ALLOC_INCR (30)
/* hash_search operations */
-typedef enum {
- HASH_FIND,
- HASH_ENTER,
- HASH_REMOVE,
- HASH_FIND_SAVE,
- HASH_REMOVE_SAVED
-} HASHACTION;
-
-/*
+typedef enum
+{
+ HASH_FIND,
+ HASH_ENTER,
+ HASH_REMOVE,
+ HASH_FIND_SAVE,
+ HASH_REMOVE_SAVED
+} HASHACTION;
+
+/*
* prototypes from functions in dynahash.c
*/
-extern HTAB *hash_create(int nelem, HASHCTL *info, int flags);
-extern void hash_destroy(HTAB *hashp);
-extern void hash_stats(char *where, HTAB *hashp);
-extern long *hash_search(HTAB *hashp, char *keyPtr, HASHACTION action,
- bool *foundPtr);
-extern long *hash_seq(HTAB *hashp);
-
-/*
+extern HTAB *hash_create(int nelem, HASHCTL * info, int flags);
+extern void hash_destroy(HTAB * hashp);
+extern void hash_stats(char *where, HTAB * hashp);
+extern long *
+hash_search(HTAB * hashp, char *keyPtr, HASHACTION action,
+ bool * foundPtr);
+extern long *hash_seq(HTAB * hashp);
+
+/*
* prototypes from functions in hashfn.c
*/
-extern long string_hash(char *key, int keysize);
-extern long tag_hash(int *key, int keysize);
+extern long string_hash(char *key, int keysize);
+extern long tag_hash(int *key, int keysize);
-#endif /* HSEARCH_H */
+#endif /* HSEARCH_H */
diff --git a/src/include/utils/inval.h b/src/include/utils/inval.h
index 0c993f5964b..21ea8eefb6b 100644
--- a/src/include/utils/inval.h
+++ b/src/include/utils/inval.h
@@ -1,46 +1,47 @@
/*-------------------------------------------------------------------------
*
* inval.h--
- * POSTGRES cache invalidation dispatcher definitions.
+ * POSTGRES cache invalidation dispatcher definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: inval.h,v 1.4 1997/08/19 21:40:37 momjian Exp $
+ * $Id: inval.h,v 1.5 1997/09/07 05:02:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef INVAL_H
+#ifndef INVAL_H
#define INVAL_H
#include <access/htup.h>
#include <utils/rel.h>
-extern void DiscardInvalid(void);
+extern void DiscardInvalid(void);
-extern void RegisterInvalid(bool send);
+extern void RegisterInvalid(bool send);
-extern void SetRefreshWhenInvalidate(bool on);
+extern void SetRefreshWhenInvalidate(bool on);
-extern void RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple);
+extern void RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple);
/*
* POSTGRES local cache invalidation definitions. (originates from linval.h)
*/
-typedef struct InvalidationUserData {
- struct InvalidationUserData *dataP[1]; /* VARIABLE LENGTH */
-} InvalidationUserData; /* VARIABLE LENGTH STRUCTURE */
+typedef struct InvalidationUserData
+{
+ struct InvalidationUserData *dataP[1]; /* VARIABLE LENGTH */
+} InvalidationUserData; /* VARIABLE LENGTH STRUCTURE */
-typedef struct InvalidationEntryData {
- InvalidationUserData *nextP;
- InvalidationUserData userData; /* VARIABLE LENGTH ARRAY */
-} InvalidationEntryData; /* VARIABLE LENGTH STRUCTURE */
+typedef struct InvalidationEntryData
+{
+ InvalidationUserData *nextP;
+ InvalidationUserData userData; /* VARIABLE LENGTH ARRAY */
+} InvalidationEntryData; /* VARIABLE LENGTH STRUCTURE */
typedef Pointer InvalidationEntry;
-typedef InvalidationEntry LocalInvalid;
+typedef InvalidationEntry LocalInvalid;
-#define EmptyLocalInvalid NULL
-
-#endif /* INVAL_H */
+#define EmptyLocalInvalid NULL
+#endif /* INVAL_H */
diff --git a/src/include/utils/lselect.h b/src/include/utils/lselect.h
index 048ea932e28..d5498df779a 100644
--- a/src/include/utils/lselect.h
+++ b/src/include/utils/lselect.h
@@ -1,49 +1,55 @@
/*-------------------------------------------------------------------------
*
* lselect.h--
- * definitions for the replacement selection algorithm.
+ * definitions for the replacement selection algorithm.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: lselect.h,v 1.4 1997/08/06 03:42:07 momjian Exp $
- *
+ * $Id: lselect.h,v 1.5 1997/09/07 05:02:38 momjian Exp $
+ *
*-------------------------------------------------------------------------
*/
-#ifndef LSELECT_H
-#define LSELECT_H
+#ifndef LSELECT_H
+#define LSELECT_H
#include <stdio.h>
#include "access/htup.h"
-struct leftist {
- short lt_dist; /* distance to leaf/empty node */
- short lt_devnum; /* device number of tuple */
- HeapTuple lt_tuple;
- struct leftist *lt_left;
- struct leftist *lt_right;
+struct leftist
+{
+ short lt_dist; /* distance to leaf/empty node */
+ short lt_devnum; /* device number of tuple */
+ HeapTuple lt_tuple;
+ struct leftist *lt_left;
+ struct leftist *lt_right;
};
/* replaces global variables in lselect.c to make it reentrant */
-typedef struct {
- TupleDesc tupDesc;
- int nKeys;
- ScanKey scanKeys;
- int sortMem; /* needed for psort */
-} LeftistContextData;
+typedef struct
+{
+ TupleDesc tupDesc;
+ int nKeys;
+ ScanKey scanKeys;
+ int sortMem; /* needed for psort */
+} LeftistContextData;
typedef LeftistContextData *LeftistContext;
-extern struct leftist *lmerge(struct leftist *pt, struct leftist *qt,
- LeftistContext context);
-extern HeapTuple gettuple(struct leftist **treep, short *devnum,
- LeftistContext context);
-extern void puttuple(struct leftist **treep, HeapTuple newtuple, short devnum,
- LeftistContext context);
-extern int tuplecmp(HeapTuple ltup, HeapTuple rtup, LeftistContext context);
+extern struct leftist *
+lmerge(struct leftist * pt, struct leftist * qt,
+ LeftistContext context);
+extern HeapTuple
+gettuple(struct leftist ** treep, short *devnum,
+ LeftistContext context);
+extern void
+puttuple(struct leftist ** treep, HeapTuple newtuple, short devnum,
+ LeftistContext context);
+extern int tuplecmp(HeapTuple ltup, HeapTuple rtup, LeftistContext context);
#ifdef EBUG
-extern void checktree(struct leftist *tree, LeftistContext context);
-extern int checktreer(struct leftist *tree, int level, LeftistContext context);
-#endif /* EBUG */
+extern void checktree(struct leftist * tree, LeftistContext context);
+extern int checktreer(struct leftist * tree, int level, LeftistContext context);
+
+#endif /* EBUG */
-#endif /* LSELECT_H */
+#endif /* LSELECT_H */
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 82f465814e3..5abc26912cd 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -1,44 +1,44 @@
/*-------------------------------------------------------------------------
*
* lsyscache.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: lsyscache.h,v 1.3 1997/08/19 21:40:40 momjian Exp $
+ * $Id: lsyscache.h,v 1.4 1997/09/07 05:02:39 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef LSYSCACHE_H
-#define LSYSCACHE_H
+#ifndef LSYSCACHE_H
+#define LSYSCACHE_H
#include <access/attnum.h>
#include <access/htup.h>
-extern bool op_class(Oid opid, int32 opclass, Oid amopid);
-extern char *get_attname(Oid relid, AttrNumber attnum);
+extern bool op_class(Oid opid, int32 opclass, Oid amopid);
+extern char *get_attname(Oid relid, AttrNumber attnum);
extern AttrNumber get_attnum(Oid relid, char *attname);
-extern Oid get_atttype(Oid relid, AttrNumber attnum);
-extern bool get_attisset(Oid relid, char *attname);
+extern Oid get_atttype(Oid relid, AttrNumber attnum);
+extern bool get_attisset(Oid relid, char *attname);
extern RegProcedure get_opcode(Oid opid);
-extern char *get_opname(Oid opid);
-extern bool op_mergesortable(Oid opid, Oid ltype, Oid rtype,
- Oid *leftOp, Oid *rightOp);
-extern Oid op_hashjoinable(Oid opid, Oid ltype, Oid rtype);
-extern Oid get_commutator(Oid opid);
+extern char *get_opname(Oid opid);
+extern bool
+op_mergesortable(Oid opid, Oid ltype, Oid rtype,
+ Oid * leftOp, Oid * rightOp);
+extern Oid op_hashjoinable(Oid opid, Oid ltype, Oid rtype);
+extern Oid get_commutator(Oid opid);
extern HeapTuple get_operator_tuple(Oid opno);
-extern Oid get_negator(Oid opid);
+extern Oid get_negator(Oid opid);
extern RegProcedure get_oprrest(Oid opid);
extern RegProcedure get_oprjoin(Oid opid);
-extern int get_relnatts(Oid relid);
-extern char *get_rel_name(Oid relid);
-extern struct varlena * get_relstub(Oid relid, int no, bool *islast);
-extern Oid get_ruleid(char *rulename);
-extern Oid get_eventrelid(Oid ruleid);
-extern int16 get_typlen(Oid typid);
-extern bool get_typbyval(Oid typid);
+extern int get_relnatts(Oid relid);
+extern char *get_rel_name(Oid relid);
+extern struct varlena *get_relstub(Oid relid, int no, bool * islast);
+extern Oid get_ruleid(char *rulename);
+extern Oid get_eventrelid(Oid ruleid);
+extern int16 get_typlen(Oid typid);
+extern bool get_typbyval(Oid typid);
extern struct varlena *get_typdefault(Oid typid);
-#endif /* LSYSCACHE_H */
-
+#endif /* LSYSCACHE_H */
diff --git a/src/include/utils/mcxt.h b/src/include/utils/mcxt.h
index 9d0b649f40e..b7dfcc7cda6 100644
--- a/src/include/utils/mcxt.h
+++ b/src/include/utils/mcxt.h
@@ -1,51 +1,52 @@
/*-------------------------------------------------------------------------
*
* mcxt.h--
- * POSTGRES memory context definitions.
+ * POSTGRES memory context definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: mcxt.h,v 1.5 1997/08/19 21:40:41 momjian Exp $
+ * $Id: mcxt.h,v 1.6 1997/09/07 05:02:40 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef MCXT_H
+#ifndef MCXT_H
#define MCXT_H
#include <nodes/memnodes.h>
-extern MemoryContext CurrentMemoryContext;
-extern MemoryContext TopMemoryContext;
+extern MemoryContext CurrentMemoryContext;
+extern MemoryContext TopMemoryContext;
/*
* MaxAllocSize --
- * Arbitrary limit on size of allocations.
+ * Arbitrary limit on size of allocations.
*
* Note:
- * There is no guarantee that allocations smaller than MaxAllocSize
- * will succeed. Allocation requests larger than MaxAllocSize will
- * be summarily denied.
+ * There is no guarantee that allocations smaller than MaxAllocSize
+ * will succeed. Allocation requests larger than MaxAllocSize will
+ * be summarily denied.
*
- * This value should not be referenced except in one place in the code.
+ * This value should not be referenced except in one place in the code.
*
* XXX This should be defined in a file of tunable constants.
*/
-#define MaxAllocSize (0xfffffff) /* 16G - 1 */
+#define MaxAllocSize (0xfffffff) /* 16G - 1 */
/*
* prototypes for functions in mcxt.c
*/
-extern void EnableMemoryContext(bool on);
-extern Pointer MemoryContextAlloc(MemoryContext context, Size size);
-extern Pointer MemoryContextRealloc(MemoryContext context,
- Pointer pointer,
- Size size);
-extern void MemoryContextFree(MemoryContext context, Pointer pointer);
+extern void EnableMemoryContext(bool on);
+extern Pointer MemoryContextAlloc(MemoryContext context, Size size);
+extern Pointer
+MemoryContextRealloc(MemoryContext context,
+ Pointer pointer,
+ Size size);
+extern void MemoryContextFree(MemoryContext context, Pointer pointer);
extern MemoryContext MemoryContextSwitchTo(MemoryContext context);
extern GlobalMemory CreateGlobalMemory(char *name);
-extern void GlobalMemoryDestroy(GlobalMemory context);
+extern void GlobalMemoryDestroy(GlobalMemory context);
-#endif /* MCXT_H */
+#endif /* MCXT_H */
diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h
index 01dfc067970..b87c331a1d7 100644
--- a/src/include/utils/memutils.h
+++ b/src/include/utils/memutils.h
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* memutils.h--
- * this file contains general memory alignment, allocation
- * and manipulation stuff that used to be spread out
- * between the following files:
+ * this file contains general memory alignment, allocation
+ * and manipulation stuff that used to be spread out
+ * between the following files:
*
- * align.h alignment macros
- * aset.h memory allocation set stuff
- * oset.h (used by aset.h)
- * (bit.h bit array type / extern)
- * clib.h mem routines
- * limit.h max bits/byte, etc.
+ * align.h alignment macros
+ * aset.h memory allocation set stuff
+ * oset.h (used by aset.h)
+ * (bit.h bit array type / extern)
+ * clib.h mem routines
+ * limit.h max bits/byte, etc.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: memutils.h,v 1.8 1997/08/20 14:54:35 momjian Exp $
+ * $Id: memutils.h,v 1.9 1997/09/07 05:02:42 momjian Exp $
*
* NOTES
- * some of the information in this file will be moved to
- * other files, (like MaxHeapTupleSize and MaxAttributeSize).
+ * some of the information in this file will be moved to
+ * other files, (like MaxHeapTupleSize and MaxAttributeSize).
*
*-------------------------------------------------------------------------
*/
@@ -29,238 +29,245 @@
#ifdef NOT_USED
/*****************************************************************************
- * align.h - alignment macros *
+ * align.h - alignment macros *
****************************************************************************
- [TRH] Let the compiler decide what alignment it uses instead of
+ [TRH] Let the compiler decide what alignment it uses instead of
tending
we know better.
GCC (at least v2.5.8 and up) has an __alignof__ keyword.
However, we cannot use it here since on some architectures it reports
just a _recommended_ alignment instead of the actual alignment used in
- padding structures (or at least, this is how I understand gcc's
+ padding structures (or at least, this is how I understand gcc's
s...)
So define a macro that gives us the _actual_ alignment inside a struct.
{{note: assumes that alignment size is always a power of 2.}}
*/
-#define _ALIGNSIZE(TYPE) offsetof(struct { char __c; TYPE __t;}, __t)
+#define _ALIGNSIZE(TYPE) offsetof(struct { char __c; TYPE __t;}, __t)
#define _ALIGN(TYPE, LEN) \
- (((long)(LEN) + (_ALIGNSIZE(TYPE) - 1)) & ~(_ALIGNSIZE(TYPE) - 1))
-#define SHORTALIGN(LEN) _ALIGN(short, (LEN))
-#define INTALIGN(LEN) _ALIGN(int, (LEN))
-#define LONGALIGN(LEN) _ALIGN(long, (LEN))
-#define DOUBLEALIGN(LEN) _ALIGN(double, (LEN))
-#define MAXALIGN(LEN) _ALIGN(double, (LEN))
+ (((long)(LEN) + (_ALIGNSIZE(TYPE) - 1)) & ~(_ALIGNSIZE(TYPE) - 1))
+#define SHORTALIGN(LEN) _ALIGN(short, (LEN))
+#define INTALIGN(LEN) _ALIGN(int, (LEN))
+#define LONGALIGN(LEN) _ALIGN(long, (LEN))
+#define DOUBLEALIGN(LEN) _ALIGN(double, (LEN))
+#define MAXALIGN(LEN) _ALIGN(double, (LEN))
-#endif /* 0 */
+#endif /* 0 */
/*
- * SHORTALIGN(LEN) - length (or address) aligned for shorts
+ * SHORTALIGN(LEN) - length (or address) aligned for shorts
*/
-#define SHORTALIGN(LEN)\
- (((long)(LEN) + (sizeof (short) - 1)) & ~(sizeof (short) - 1))
+#define SHORTALIGN(LEN)\
+ (((long)(LEN) + (sizeof (short) - 1)) & ~(sizeof (short) - 1))
#define INTALIGN(LEN)\
- (((long)(LEN) + (sizeof (int) - 1)) & ~(sizeof (int) -1))
+ (((long)(LEN) + (sizeof (int) - 1)) & ~(sizeof (int) -1))
/*
- * LONGALIGN(LEN) - length (or address) aligned for longs
+ * LONGALIGN(LEN) - length (or address) aligned for longs
*/
#if defined(sun) && ! defined(sparc)
-#define LONGALIGN(LEN) SHORTALIGN(LEN)
+#define LONGALIGN(LEN) SHORTALIGN(LEN)
#elif defined (alpha) || defined(linuxalpha)
- /* even though "long alignment" should really be on 8-byte boundaries
- * for linuxalpha, we want the strictest alignment to be on 4-byte (int)
- * boundaries, because otherwise things break when they try to use the
- * FormData_pg_* structures. --djm 12/12/96
- */
-#define LONGALIGN(LEN)\
- (((long)(LEN) + (sizeof (int) - 1)) & ~(sizeof (int) -1))
+
+ /*
+ * even though "long alignment" should really be on 8-byte boundaries for
+ * linuxalpha, we want the strictest alignment to be on 4-byte (int)
+ * boundaries, because otherwise things break when they try to use the
+ * FormData_pg_* structures. --djm 12/12/96
+ */
+#define LONGALIGN(LEN)\
+ (((long)(LEN) + (sizeof (int) - 1)) & ~(sizeof (int) -1))
#else
-#define LONGALIGN(LEN)\
- (((long)(LEN) + (sizeof (long) - 1)) & ~(sizeof (long) -1))
+#define LONGALIGN(LEN)\
+ (((long)(LEN) + (sizeof (long) - 1)) & ~(sizeof (long) -1))
#endif
#define DOUBLEALIGN(LEN)\
- (((long)(LEN) + (sizeof (double) - 1)) & ~(sizeof (double) -1))
+ (((long)(LEN) + (sizeof (double) - 1)) & ~(sizeof (double) -1))
#define MAXALIGN(LEN)\
- (((long)(LEN) + (sizeof (double) - 1)) & ~(sizeof (double) -1))
+ (((long)(LEN) + (sizeof (double) - 1)) & ~(sizeof (double) -1))
/*****************************************************************************
- * oset.h -- Fixed format ordered set definitions. *
+ * oset.h -- Fixed format ordered set definitions. *
*****************************************************************************/
/* Note:
- * Fixed format ordered sets are <EXPLAIN>.
- * XXX This is a preliminary version. Work is needed to explain
- * XXX semantics of the external definitions. Otherwise, the
- * XXX functional interface should not change.
+ * Fixed format ordered sets are <EXPLAIN>.
+ * XXX This is a preliminary version. Work is needed to explain
+ * XXX semantics of the external definitions. Otherwise, the
+ * XXX functional interface should not change.
*
*/
typedef struct OrderedElemData OrderedElemData;
-typedef OrderedElemData* OrderedElem;
+typedef OrderedElemData *OrderedElem;
typedef struct OrderedSetData OrderedSetData;
-typedef OrderedSetData* OrderedSet;
+typedef OrderedSetData *OrderedSet;
-struct OrderedElemData {
- OrderedElem next; /* Next elem or &this->set->dummy */
- OrderedElem prev; /* Previous elem or &this->set->head */
- OrderedSet set; /* Parent set */
+struct OrderedElemData
+{
+ OrderedElem next; /* Next elem or &this->set->dummy */
+ OrderedElem prev; /* Previous elem or &this->set->head */
+ OrderedSet set; /* Parent set */
};
-struct OrderedSetData {
- OrderedElem head; /* First elem or &this->dummy */
- OrderedElem dummy; /* (hack) Terminator == NULL */
- OrderedElem tail; /* Last elem or &this->head */
- Offset offset; /* Offset from struct base to elem */
- /* this could be signed short int! */
+struct OrderedSetData
+{
+ OrderedElem head; /* First elem or &this->dummy */
+ OrderedElem dummy; /* (hack) Terminator == NULL */
+ OrderedElem tail; /* Last elem or &this->head */
+ Offset offset; /* Offset from struct base to elem */
+ /* this could be signed short int! */
};
-extern void OrderedSetInit(OrderedSet set, Offset offset);
-extern bool OrderedSetContains(OrderedSet set, OrderedElem elem);
-extern Pointer OrderedSetGetHead(OrderedSet set);
-extern Pointer OrderedElemGetPredecessor(OrderedElem elem);
-extern Pointer OrderedElemGetSuccessor(OrderedElem elem);
-extern void OrderedElemPop(OrderedElem elem);
-extern void OrderedElemPushInto(OrderedElem elem, OrderedSet Set);
+extern void OrderedSetInit(OrderedSet set, Offset offset);
+extern bool OrderedSetContains(OrderedSet set, OrderedElem elem);
+extern Pointer OrderedSetGetHead(OrderedSet set);
+extern Pointer OrderedElemGetPredecessor(OrderedElem elem);
+extern Pointer OrderedElemGetSuccessor(OrderedElem elem);
+extern void OrderedElemPop(OrderedElem elem);
+extern void OrderedElemPushInto(OrderedElem elem, OrderedSet Set);
/*****************************************************************************
- * aset.h -- Allocation set definitions. *
+ * aset.h -- Allocation set definitions. *
*****************************************************************************/
/*
* Description:
- * An allocation set is a set containing allocated elements. When
- * an allocation is requested for a set, memory is allocated and a
- * pointer is returned. Subsequently, this memory may be freed or
- * reallocated. In addition, an allocation set may be reset which
- * will cause all allocated memory to be freed.
+ * An allocation set is a set containing allocated elements. When
+ * an allocation is requested for a set, memory is allocated and a
+ * pointer is returned. Subsequently, this memory may be freed or
+ * reallocated. In addition, an allocation set may be reset which
+ * will cause all allocated memory to be freed.
*
- * Allocations may occur in four different modes. The mode of
- * allocation does not affect the behavior of allocations except in
- * terms of performance. The allocation mode is set at the time of
- * set initialization. Once the mode is chosen, it cannot be changed
- * unless the set is reinitialized.
+ * Allocations may occur in four different modes. The mode of
+ * allocation does not affect the behavior of allocations except in
+ * terms of performance. The allocation mode is set at the time of
+ * set initialization. Once the mode is chosen, it cannot be changed
+ * unless the set is reinitialized.
*
- * "Dynamic" mode forces all allocations to occur in a heap. This
- * is a good mode to use when small memory segments are allocated
- * and freed very frequently. This is a good choice when allocation
- * characteristics are unknown. This is the default mode.
+ * "Dynamic" mode forces all allocations to occur in a heap. This
+ * is a good mode to use when small memory segments are allocated
+ * and freed very frequently. This is a good choice when allocation
+ * characteristics are unknown. This is the default mode.
*
- * "Static" mode attemts to allocate space as efficiently as possible
- * without regard to freeing memory. This mode should be chosen only
- * when it is known that many allocations will occur but that very
- * little of the allocated memory will be explicitly freed.
+ * "Static" mode attemts to allocate space as efficiently as possible
+ * without regard to freeing memory. This mode should be chosen only
+ * when it is known that many allocations will occur but that very
+ * little of the allocated memory will be explicitly freed.
*
- * "Tunable" mode is a hybrid of dynamic and static modes. The
- * tunable mode will use static mode allocation except when the
- * allocation request exceeds a size limit supplied at the time of set
- * initialization. "Big" objects are allocated using dynamic mode.
+ * "Tunable" mode is a hybrid of dynamic and static modes. The
+ * tunable mode will use static mode allocation except when the
+ * allocation request exceeds a size limit supplied at the time of set
+ * initialization. "Big" objects are allocated using dynamic mode.
*
- * "Bounded" mode attempts to allocate space efficiently given a limit
- * on space consumed by the allocation set. This restriction can be
- * considered a "soft" restriction, because memory segments will
- * continue to be returned after the limit is exceeded. The limit is
- * specified at the time of set initialization like for tunable mode.
+ * "Bounded" mode attempts to allocate space efficiently given a limit
+ * on space consumed by the allocation set. This restriction can be
+ * considered a "soft" restriction, because memory segments will
+ * continue to be returned after the limit is exceeded. The limit is
+ * specified at the time of set initialization like for tunable mode.
*
* Note:
- * Allocation sets are not automatically reset on a system reset.
- * Higher level code is responsible for cleaning up.
+ * Allocation sets are not automatically reset on a system reset.
+ * Higher level code is responsible for cleaning up.
*
- * There may other modes in the future.
+ * There may other modes in the future.
*/
/*
* AllocPointer --
- * Aligned pointer which may be a member of an allocation set.
+ * Aligned pointer which may be a member of an allocation set.
*/
typedef Pointer AllocPointer;
/*
* AllocMode --
- * Mode of allocation for an allocation set.
+ * Mode of allocation for an allocation set.
*
* Note:
- * See above for a description of the various nodes.
+ * See above for a description of the various nodes.
*/
-typedef enum AllocMode {
- DynamicAllocMode, /* always dynamically allocate */
- StaticAllocMode, /* always "statically" allocate */
- TunableAllocMode, /* allocations are "tuned" */
- BoundedAllocMode /* allocations bounded to fixed usage */
-} AllocMode;
+typedef enum AllocMode
+{
+ DynamicAllocMode, /* always dynamically allocate */
+ StaticAllocMode, /* always "statically" allocate */
+ TunableAllocMode, /* allocations are "tuned" */
+ BoundedAllocMode /* allocations bounded to fixed usage */
+} AllocMode;
-#define DefaultAllocMode DynamicAllocMode
+#define DefaultAllocMode DynamicAllocMode
/*
* AllocSet --
- * Allocation set.
+ * Allocation set.
*/
-typedef struct AllocSetData {
- OrderedSetData setData;
+typedef struct AllocSetData
+{
+ OrderedSetData setData;
/* Note: this will change in the future to support other modes */
-} AllocSetData;
+} AllocSetData;
typedef AllocSetData *AllocSet;
/*
* AllocPointerIsValid --
- * True iff pointer is valid allocation pointer.
+ * True iff pointer is valid allocation pointer.
*/
#define AllocPointerIsValid(pointer) PointerIsValid(pointer)
/*
* AllocSetIsValid --
- * True iff set is valid allocation set.
+ * True iff set is valid allocation set.
*/
-#define AllocSetIsValid(set) PointerIsValid(set)
+#define AllocSetIsValid(set) PointerIsValid(set)
-extern void AllocSetInit(AllocSet set, AllocMode mode, Size limit);
+extern void AllocSetInit(AllocSet set, AllocMode mode, Size limit);
-extern void AllocSetReset(AllocSet set);
+extern void AllocSetReset(AllocSet set);
-extern bool AllocSetContains(AllocSet set, AllocPointer pointer);
+extern bool AllocSetContains(AllocSet set, AllocPointer pointer);
extern AllocPointer AllocSetAlloc(AllocSet set, Size size);
-extern void AllocSetFree(AllocSet set, AllocPointer pointer);
-extern AllocPointer AllocSetRealloc(AllocSet set, AllocPointer pointer,
- Size size);
+extern void AllocSetFree(AllocSet set, AllocPointer pointer);
+extern AllocPointer
+AllocSetRealloc(AllocSet set, AllocPointer pointer,
+ Size size);
-extern void AllocSetDump(AllocSet set);
+extern void AllocSetDump(AllocSet set);
/*****************************************************************************
- * clib.h -- Standard C library definitions *
+ * clib.h -- Standard C library definitions *
*****************************************************************************/
/*
* Note:
- * This file is OPERATING SYSTEM dependent!!!
+ * This file is OPERATING SYSTEM dependent!!!
*
*/
-/*
- * LibCCopyLength is only used within this file. -cim 6/12/90
- *
+/*
+ * LibCCopyLength is only used within this file. -cim 6/12/90
+ *
*/
-typedef int LibCCopyLength;
+typedef int LibCCopyLength;
/*
* MemoryCopy --
- * Copies fixed length block of memory to another.
+ * Copies fixed length block of memory to another.
*/
#define MemoryCopy(toBuffer, fromBuffer, length)\
- memcpy(toBuffer, fromBuffer, length)
+ memcpy(toBuffer, fromBuffer, length)
/*****************************************************************************
- * limit.h -- POSTGRES limit definitions. *
+ * limit.h -- POSTGRES limit definitions. *
*****************************************************************************/
#define MaxBitsPerByte 8
typedef uint32 AttributeSize; /* XXX should be defined elsewhere */
-#define MaxHeapTupleSize 0x7fffffff
-#define MaxAttributeSize 0x7fffffff
+#define MaxHeapTupleSize 0x7fffffff
+#define MaxAttributeSize 0x7fffffff
-#define MaxIndexAttributeNumber 7
+#define MaxIndexAttributeNumber 7
-#endif /* MEMUTILS_H */
+#endif /* MEMUTILS_H */
diff --git a/src/include/utils/module.h b/src/include/utils/module.h
index 6c5d77d6ada..cadff1aa6c3 100644
--- a/src/include/utils/module.h
+++ b/src/include/utils/module.h
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* module.h--
- * this file contains general "module" stuff that used to be
- * spread out between the following files:
+ * this file contains general "module" stuff that used to be
+ * spread out between the following files:
*
- * enbl.h module enable stuff
- * trace.h module trace stuff (now gone)
+ * enbl.h module enable stuff
+ * trace.h module trace stuff (now gone)
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: module.h,v 1.1 1996/08/28 01:59:12 scrappy Exp $
+ * $Id: module.h,v 1.2 1997/09/07 05:02:44 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef MODULE_H
#define MODULE_H
-/*
- * prototypes for functions in init/enbl.c
+/*
+ * prototypes for functions in init/enbl.c
*/
-extern bool BypassEnable(int *enableCountInOutP, bool on);
+extern bool BypassEnable(int *enableCountInOutP, bool on);
-#endif /* MODULE_H */
+#endif /* MODULE_H */
diff --git a/src/include/utils/nabstime.h b/src/include/utils/nabstime.h
index 4db0fefa50c..5372501bcb0 100644
--- a/src/include/utils/nabstime.h
+++ b/src/include/utils/nabstime.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* nabstime.h--
- * Definitions for the "new" abstime code.
+ * Definitions for the "new" abstime code.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nabstime.h,v 1.10 1997/08/19 21:40:47 momjian Exp $
+ * $Id: nabstime.h,v 1.11 1997/09/07 05:02:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,7 +18,7 @@
/* ----------------------------------------------------------------
- * time types + support macros
+ * time types + support macros
*
*
* ----------------------------------------------------------------
@@ -26,92 +26,98 @@
typedef int32 AbsoluteTime;
typedef int32 RelativeTime;
-typedef struct {
- int32 status;
- AbsoluteTime data[2];
-} TimeIntervalData;
+typedef struct
+{
+ int32 status;
+ AbsoluteTime data[2];
+} TimeIntervalData;
typedef TimeIntervalData *TimeInterval;
/*
* Reserved values
* Epoch is Unix system time zero, but needs to be kept as a reserved
- * value rather than converting to time since timezone calculations
- * might move it away from 1970-01-01 00:00:00Z - tgl 97/02/20
+ * value rather than converting to time since timezone calculations
+ * might move it away from 1970-01-01 00:00:00Z - tgl 97/02/20
*
* Pre-v6.1 code had large decimal numbers for reserved values.
* These were chosen as special 32-bit bit patterns,
- * so redefine them explicitly using these bit patterns. - tgl 97/02/24
+ * so redefine them explicitly using these bit patterns. - tgl 97/02/24
*/
#define EPOCH_ABSTIME ((AbsoluteTime) 0)
-#define INVALID_ABSTIME ((AbsoluteTime) 0x7FFFFFFE) /* 2147483647 == 2^31 - 1 */
-#define CURRENT_ABSTIME ((AbsoluteTime) 0x7FFFFFFD) /* 2147483646 == 2^31 - 2 */
-#define NOEND_ABSTIME ((AbsoluteTime) 0x7FFFFFFC) /* 2147483645 == 2^31 - 3 */
-#define BIG_ABSTIME ((AbsoluteTime) 0x7FFFFFFB) /* 2147483644 == 2^31 - 4 */
+#define INVALID_ABSTIME ((AbsoluteTime) 0x7FFFFFFE) /* 2147483647 == 2^31 -
+ * 1 */
+#define CURRENT_ABSTIME ((AbsoluteTime) 0x7FFFFFFD) /* 2147483646 == 2^31 -
+ * 2 */
+#define NOEND_ABSTIME ((AbsoluteTime) 0x7FFFFFFC) /* 2147483645 == 2^31 -
+ * 3 */
+#define BIG_ABSTIME ((AbsoluteTime) 0x7FFFFFFB) /* 2147483644 == 2^31 -
+ * 4 */
#if defined(aix)
/*
* AIX considers 2147483648 == -2147483648 (since they have the same bit
- * representation) but uses a different sign sense in a comparison to
- * these integer constants depending on whether the constant is signed
+ * representation) but uses a different sign sense in a comparison to
+ * these integer constants depending on whether the constant is signed
* or not!
*/
-#define NOSTART_ABSTIME ((AbsoluteTime) INT_MIN)
+#define NOSTART_ABSTIME ((AbsoluteTime) INT_MIN)
#else
-#define NOSTART_ABSTIME ((AbsoluteTime) 0x80000001) /* -2147483647 == - 2^31 */
-#endif /* aix */
+#define NOSTART_ABSTIME ((AbsoluteTime) 0x80000001) /* -2147483647 == - 2^31 */
+#endif /* aix */
-#define INVALID_RELTIME ((RelativeTime) 0x7FFFFFFE) /* 2147483647 == 2^31 - 1 */
+#define INVALID_RELTIME ((RelativeTime) 0x7FFFFFFE) /* 2147483647 == 2^31 -
+ * 1 */
#define AbsoluteTimeIsValid(time) \
- ((bool) ((time) != INVALID_ABSTIME))
+ ((bool) ((time) != INVALID_ABSTIME))
#define AbsoluteTimeIsReal(time) \
- ((bool) (((AbsoluteTime) time) < NOEND_ABSTIME && \
- ((AbsoluteTime) time) > NOSTART_ABSTIME))
+ ((bool) (((AbsoluteTime) time) < NOEND_ABSTIME && \
+ ((AbsoluteTime) time) > NOSTART_ABSTIME))
/* have to include this because EPOCH_ABSTIME used to be invalid - yuk */
#define AbsoluteTimeIsBackwardCompatiblyValid(time) \
- ((bool) (((AbsoluteTime) time) != INVALID_ABSTIME && \
- ((AbsoluteTime) time) > EPOCH_ABSTIME))
+ ((bool) (((AbsoluteTime) time) != INVALID_ABSTIME && \
+ ((AbsoluteTime) time) > EPOCH_ABSTIME))
#define AbsoluteTimeIsBackwardCompatiblyReal(time) \
- ((bool) (((AbsoluteTime) time) < NOEND_ABSTIME && \
- ((AbsoluteTime) time) > NOSTART_ABSTIME && \
- ((AbsoluteTime) time) > EPOCH_ABSTIME))
+ ((bool) (((AbsoluteTime) time) < NOEND_ABSTIME && \
+ ((AbsoluteTime) time) > NOSTART_ABSTIME && \
+ ((AbsoluteTime) time) > EPOCH_ABSTIME))
#define RelativeTimeIsValid(time) \
- ((bool) (((RelativeTime) time) != INVALID_RELTIME))
+ ((bool) (((RelativeTime) time) != INVALID_RELTIME))
extern AbsoluteTime GetCurrentAbsoluteTime(void);
/*
* getSystemTime --
- * Returns system time.
+ * Returns system time.
*/
#define getSystemTime() \
- ((time_t) (time(0l)))
+ ((time_t) (time(0l)))
/*
- * nabstime.c prototypes
+ * nabstime.c prototypes
*/
extern AbsoluteTime nabstimein(char *timestr);
-extern char *nabstimeout(AbsoluteTime time);
+extern char *nabstimeout(AbsoluteTime time);
-extern bool abstimeeq(AbsoluteTime t1, AbsoluteTime t2);
-extern bool abstimene(AbsoluteTime t1, AbsoluteTime t2);
-extern bool abstimelt(AbsoluteTime t1, AbsoluteTime t2);
-extern bool abstimegt(AbsoluteTime t1, AbsoluteTime t2);
-extern bool abstimele(AbsoluteTime t1, AbsoluteTime t2);
-extern bool abstimege(AbsoluteTime t1, AbsoluteTime t2);
-extern bool abstime_finite(AbsoluteTime time);
+extern bool abstimeeq(AbsoluteTime t1, AbsoluteTime t2);
+extern bool abstimene(AbsoluteTime t1, AbsoluteTime t2);
+extern bool abstimelt(AbsoluteTime t1, AbsoluteTime t2);
+extern bool abstimegt(AbsoluteTime t1, AbsoluteTime t2);
+extern bool abstimele(AbsoluteTime t1, AbsoluteTime t2);
+extern bool abstimege(AbsoluteTime t1, AbsoluteTime t2);
+extern bool abstime_finite(AbsoluteTime time);
-extern AbsoluteTime datetime_abstime(DateTime *datetime);
+extern AbsoluteTime datetime_abstime(DateTime * datetime);
extern DateTime *abstime_datetime(AbsoluteTime abstime);
-extern bool AbsoluteTimeIsBefore(AbsoluteTime time1, AbsoluteTime time2);
-extern bool AbsoluteTimeIsAfter(AbsoluteTime time1, AbsoluteTime time2);
+extern bool AbsoluteTimeIsBefore(AbsoluteTime time1, AbsoluteTime time2);
+extern bool AbsoluteTimeIsAfter(AbsoluteTime time1, AbsoluteTime time2);
-extern void abstime2tm(AbsoluteTime time, int *tzp, struct tm *tm, char *tzn);
+extern void abstime2tm(AbsoluteTime time, int *tzp, struct tm * tm, char *tzn);
-#endif /* NABSTIME_H */
+#endif /* NABSTIME_H */
diff --git a/src/include/utils/oidcompos.h b/src/include/utils/oidcompos.h
index 290fb08ee65..f4980051f05 100644
--- a/src/include/utils/oidcompos.h
+++ b/src/include/utils/oidcompos.h
@@ -1,52 +1,52 @@
/*-------------------------------------------------------------------------
*
* oidcompos.h--
- * prototype file for the oid {char16,int4} composite type functions.
+ * prototype file for the oid {char16,int4} composite type functions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: oidcompos.h,v 1.1 1996/08/28 01:59:15 scrappy Exp $
+ * $Id: oidcompos.h,v 1.2 1997/09/07 05:02:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef OIDCOMPOS_H
+#ifndef OIDCOMPOS_H
#define OIDCOMPOS_H
/* oidint4.c */
-OidInt4 oidint4in(char *o);
-char *oidint4out(OidInt4 o);
-bool oidint4lt(OidInt4 o1, OidInt4 o2);
-bool oidint4le(OidInt4 o1, OidInt4 o2);
-bool oidint4eq(OidInt4 o1, OidInt4 o2);
-bool oidint4ge(OidInt4 o1, OidInt4 o2);
-bool oidint4gt(OidInt4 o1, OidInt4 o2);
-bool oidint4ne(OidInt4 o1, OidInt4 o2);
-int oidint4cmp(OidInt4 o1, OidInt4 o2);
-OidInt4 mkoidint4(Oid v_oid, uint32 v_int4);
+OidInt4 oidint4in(char *o);
+char *oidint4out(OidInt4 o);
+bool oidint4lt(OidInt4 o1, OidInt4 o2);
+bool oidint4le(OidInt4 o1, OidInt4 o2);
+bool oidint4eq(OidInt4 o1, OidInt4 o2);
+bool oidint4ge(OidInt4 o1, OidInt4 o2);
+bool oidint4gt(OidInt4 o1, OidInt4 o2);
+bool oidint4ne(OidInt4 o1, OidInt4 o2);
+int oidint4cmp(OidInt4 o1, OidInt4 o2);
+OidInt4 mkoidint4(Oid v_oid, uint32 v_int4);
/* oidint2.c */
-OidInt2 oidint2in(char *o);
-char *oidint2out(OidInt2 o);
-bool oidint2lt(OidInt2 o1, OidInt2 o2);
-bool oidint2le(OidInt2 o1, OidInt2 o2);
-bool oidint2eq(OidInt2 o1, OidInt2 o2);
-bool oidint2ge(OidInt2 o1, OidInt2 o2);
-bool oidint2gt(OidInt2 o1, OidInt2 o2);
-bool oidint2ne(OidInt2 o1, OidInt2 o2);
-int oidint2cmp(OidInt2 o1, OidInt2 o2);
-OidInt2 mkoidint2(Oid v_oid, uint16 v_int2);
+OidInt2 oidint2in(char *o);
+char *oidint2out(OidInt2 o);
+bool oidint2lt(OidInt2 o1, OidInt2 o2);
+bool oidint2le(OidInt2 o1, OidInt2 o2);
+bool oidint2eq(OidInt2 o1, OidInt2 o2);
+bool oidint2ge(OidInt2 o1, OidInt2 o2);
+bool oidint2gt(OidInt2 o1, OidInt2 o2);
+bool oidint2ne(OidInt2 o1, OidInt2 o2);
+int oidint2cmp(OidInt2 o1, OidInt2 o2);
+OidInt2 mkoidint2(Oid v_oid, uint16 v_int2);
/* oidname.c */
-OidName oidnamein(char *inStr);
-char *oidnameout(OidName oidname);
-bool oidnamelt(OidName o1, OidName o2);
-bool oidnamele(OidName o1, OidName o2);
-bool oidnameeq(OidName o1, OidName o2);
-bool oidnamene(OidName o1, OidName o2);
-bool oidnamege(OidName o1, OidName o2);
-bool oidnamegt(OidName o1, OidName o2);
-int oidnamecmp(OidName o1, OidName o2);
-OidName mkoidname(Oid id, char *name);
+OidName oidnamein(char *inStr);
+char *oidnameout(OidName oidname);
+bool oidnamelt(OidName o1, OidName o2);
+bool oidnamele(OidName o1, OidName o2);
+bool oidnameeq(OidName o1, OidName o2);
+bool oidnamene(OidName o1, OidName o2);
+bool oidnamege(OidName o1, OidName o2);
+bool oidnamegt(OidName o1, OidName o2);
+int oidnamecmp(OidName o1, OidName o2);
+OidName mkoidname(Oid id, char *name);
-#endif /* OIDCOMPOS_H */
+#endif /* OIDCOMPOS_H */
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index 02c7b9ab257..b4a35db9795 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -1,26 +1,25 @@
/*-------------------------------------------------------------------------
*
* palloc.h--
- * POSTGRES memory allocator definitions.
+ * POSTGRES memory allocator definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: palloc.h,v 1.3 1996/11/26 03:20:23 bryanh Exp $
+ * $Id: palloc.h,v 1.4 1997/09/07 05:02:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef PALLOC_H
+#ifndef PALLOC_H
#define PALLOC_H
#include <c.h>
-extern void* palloc(Size size);
-extern void pfree(void *pointer);
-extern void *repalloc(void *pointer, Size size);
+extern void *palloc(Size size);
+extern void pfree(void *pointer);
+extern void *repalloc(void *pointer, Size size);
/* like strdup except uses palloc */
-extern char* pstrdup(char* pointer);
-
-#endif /* PALLOC_H */
+extern char *pstrdup(char *pointer);
+#endif /* PALLOC_H */
diff --git a/src/include/utils/portal.h b/src/include/utils/portal.h
index 49f907c3f0b..07edce974ef 100644
--- a/src/include/utils/portal.h
+++ b/src/include/utils/portal.h
@@ -1,28 +1,28 @@
/*-------------------------------------------------------------------------
*
* portal.h--
- * POSTGRES portal definitions.
+ * POSTGRES portal definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: portal.h,v 1.4 1997/08/19 21:40:48 momjian Exp $
+ * $Id: portal.h,v 1.5 1997/09/07 05:02:51 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* Note:
- * A portal is an abstraction which represents the execution state of
+ * A portal is an abstraction which represents the execution state of
* a running query (or a fixed sequence of queries). The "blank portal" is
* a portal with an InvalidName. This blank portal is in existance except
* between calls to BlankPortalAssignName and GetPortalByName(NULL).
*
* Note:
- * now that PQ calls can be made from within a backend, a portal
- * may also be used to keep track of the tuples resulting
- * from the execution of a query. In this case, entryIndex
+ * now that PQ calls can be made from within a backend, a portal
+ * may also be used to keep track of the tuples resulting
+ * from the execution of a query. In this case, entryIndex
*/
-#ifndef PORTAL_H
+#ifndef PORTAL_H
#define PORTAL_H
#include <executor/execdesc.h>
@@ -30,58 +30,61 @@
#include <nodes/memnodes.h>
#include <utils/memutils.h>
-typedef struct PortalBlockData {
- AllocSetData setData;
- FixedItemData itemData;
-} PortalBlockData;
+typedef struct PortalBlockData
+{
+ AllocSetData setData;
+ FixedItemData itemData;
+} PortalBlockData;
-typedef PortalBlockData *PortalBlock;
+typedef PortalBlockData *PortalBlock;
-typedef struct PortalD PortalD;
-typedef PortalD *Portal;
+typedef struct PortalD PortalD;
+typedef PortalD *Portal;
-struct PortalD {
- char *name; /* XXX PortalName */
- struct PortalVariableMemory variable;
- struct PortalHeapMemory heap;
- QueryDesc *queryDesc;
- TupleDesc attinfo;
- EState *state;
- void (*cleanup)(Portal);
+struct PortalD
+{
+ char *name; /* XXX PortalName */
+ struct PortalVariableMemory variable;
+ struct PortalHeapMemory heap;
+ QueryDesc *queryDesc;
+ TupleDesc attinfo;
+ EState *state;
+ void (*cleanup) (Portal);
};
/*
* PortalIsValid --
- * True iff portal is valid.
+ * True iff portal is valid.
*/
-#define PortalIsValid(p) PointerIsValid(p)
+#define PortalIsValid(p) PointerIsValid(p)
/*
* Special portals (well, their names anyway)
*/
-#define VACPNAME "<vacuum>"
+#define VACPNAME "<vacuum>"
-extern bool PortalNameIsSpecial(char *pname);
-extern void AtEOXact_portals(void);
-extern void EnablePortalManager(bool on);
-extern Portal GetPortalByName(char *name);
-extern Portal BlankPortalAssignName(char *name);
-extern void PortalSetQuery(Portal portal, QueryDesc *queryDesc,
- TupleDesc attinfo, EState *state,
- void (*cleanup)(Portal portal));
+extern bool PortalNameIsSpecial(char *pname);
+extern void AtEOXact_portals(void);
+extern void EnablePortalManager(bool on);
+extern Portal GetPortalByName(char *name);
+extern Portal BlankPortalAssignName(char *name);
+extern void
+PortalSetQuery(Portal portal, QueryDesc * queryDesc,
+ TupleDesc attinfo, EState * state,
+ void (*cleanup) (Portal portal));
extern QueryDesc *PortalGetQueryDesc(Portal portal);
-extern EState *PortalGetState(Portal portal);
-extern Portal CreatePortal(char *name);
-extern void PortalDestroy(Portal *portalP);
-extern void StartPortalAllocMode(AllocMode mode, Size limit);
-extern void EndPortalAllocMode(void);
+extern EState *PortalGetState(Portal portal);
+extern Portal CreatePortal(char *name);
+extern void PortalDestroy(Portal * portalP);
+extern void StartPortalAllocMode(AllocMode mode, Size limit);
+extern void EndPortalAllocMode(void);
extern PortalVariableMemory PortalGetVariableMemory(Portal portal);
extern PortalHeapMemory PortalGetHeapMemory(Portal portal);
/* estimate of the maximum number of open portals a user would have,
- * used in initially sizing the PortalHashTable in EnablePortalManager()
+ * used in initially sizing the PortalHashTable in EnablePortalManager()
*/
-#define PORTALS_PER_USER 10
+#define PORTALS_PER_USER 10
-#endif /* PORTAL_H */
+#endif /* PORTAL_H */
diff --git a/src/include/utils/psort.h b/src/include/utils/psort.h
index d7f979c8ff7..fe5e0b2f357 100644
--- a/src/include/utils/psort.h
+++ b/src/include/utils/psort.h
@@ -1,67 +1,71 @@
/*-------------------------------------------------------------------------
*
* psort.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: psort.h,v 1.7 1997/08/19 21:40:48 momjian Exp $
+ * $Id: psort.h,v 1.8 1997/09/07 05:02:53 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef PSORT_H
-#define PSORT_H
+#ifndef PSORT_H
+#define PSORT_H
#include <stdio.h>
#include "access/relscan.h"
#include "utils/lselect.h"
#include "nodes/plannodes.h"
-#define MAXTAPES 7 /* 7--See Fig. 70, p273 */
-#define TAPEEXTLEN strlen("pg_psort.xxxxx.xxx") /* TEMPDIR/TAPEEXT */
-#define FREE(x) pfree((char *) x)
+#define MAXTAPES 7 /* 7--See Fig. 70, p273 */
+#define TAPEEXTLEN strlen("pg_psort.xxxxx.xxx") /* TEMPDIR/TAPEEXT */
+#define FREE(x) pfree((char *) x)
-struct tape {
- int tp_dummy; /* (D) */
- int tp_fib; /* (A) */
- FILE *tp_file; /* (TAPE) */
- struct tape *tp_prev;
+struct tape
+{
+ int tp_dummy; /* (D) */
+ int tp_fib; /* (A) */
+ FILE *tp_file; /* (TAPE) */
+ struct tape *tp_prev;
};
-struct cmplist {
- int cp_attn; /* attribute number */
- int cp_num; /* comparison function code */
- int cp_rev; /* invert comparison flag */
- struct cmplist *cp_next; /* next in chain */
+struct cmplist
+{
+ int cp_attn; /* attribute number */
+ int cp_num; /* comparison function code */
+ int cp_rev; /* invert comparison flag */
+ struct cmplist *cp_next; /* next in chain */
};
/* This structure preserves the state of psort between calls from different
* nodes to its interface functions. Basically, it includes all of the global
* variables in psort. In case you were wondering, pointers to these structures
- * are included in Sort node structures. -Rex 2.6.1995
+ * are included in Sort node structures. -Rex 2.6.1995
*/
-typedef struct Psortstate {
- LeftistContextData treeContext;
+typedef struct Psortstate
+{
+ LeftistContextData treeContext;
- int TapeRange;
- int Level;
- int TotalDummy;
- struct tape Tape[MAXTAPES];
+ int TapeRange;
+ int Level;
+ int TotalDummy;
+ struct tape Tape[MAXTAPES];
- int BytesRead;
- int BytesWritten;
- int tupcount;
+ int BytesRead;
+ int BytesWritten;
+ int tupcount;
- struct leftist *Tuples;
+ struct leftist *Tuples;
- FILE *psort_grab_file;
- long psort_current; /* could be file offset, or array index */
- long psort_saved; /* could be file offset, or array index */
- bool using_tape_files;
+ FILE *psort_grab_file;
+ long psort_current; /* could be file offset, or array
+ * index */
+ long psort_saved;/* could be file offset, or array index */
+ bool using_tape_files;
- HeapTuple *memtuples;
-} Psortstate;
+ HeapTuple *memtuples;
+} Psortstate;
#ifdef EBUG
#include <stdio.h>
@@ -69,36 +73,36 @@ typedef struct Psortstate {
#include "storage/buf.h"
#include "storage/bufmgr.h"
-#define PDEBUG(PROC, S1)\
+#define PDEBUG(PROC, S1)\
elog(DEBUG, "%s:%d>> PROC: %s.", __FILE__, __LINE__, S1)
-#define PDEBUG2(PROC, S1, D1)\
+#define PDEBUG2(PROC, S1, D1)\
elog(DEBUG, "%s:%d>> PROC: %s %d.", __FILE__, __LINE__, S1, D1)
-#define PDEBUG4(PROC, S1, D1, S2, D2)\
+#define PDEBUG4(PROC, S1, D1, S2, D2)\
elog(DEBUG, "%s:%d>> PROC: %s %d, %s %d.", __FILE__, __LINE__, S1, D1, S2, D2)
-#define VDEBUG(VAR, FMT)\
+#define VDEBUG(VAR, FMT)\
elog(DEBUG, "%s:%d>> VAR =FMT", __FILE__, __LINE__, VAR)
-#define ASSERT(EXPR, STR)\
+#define ASSERT(EXPR, STR)\
if (!(EXPR)) elog(FATAL, "%s:%d>> %s", __FILE__, __LINE__, STR)
-#define TRACE(VAL, CODE)\
+#define TRACE(VAL, CODE)\
if (1) CODE; else
#else
-#define PDEBUG(MSG)
-#define VDEBUG(VAR, FMT)
-#define ASSERT(EXPR, MSG)
-#define TRACE(VAL, CODE)
+#define PDEBUG(MSG)
+#define VDEBUG(VAR, FMT)
+#define ASSERT(EXPR, MSG)
+#define TRACE(VAL, CODE)
#endif
/* psort.c */
-extern bool psort_begin(Sort *node, int nkeys, ScanKey key);
-extern HeapTuple psort_grabtuple(Sort *node);
-extern void psort_markpos(Sort *node);
-extern void psort_restorepos(Sort *node);
-extern void psort_end(Sort *node);
+extern bool psort_begin(Sort * node, int nkeys, ScanKey key);
+extern HeapTuple psort_grabtuple(Sort * node);
+extern void psort_markpos(Sort * node);
+extern void psort_restorepos(Sort * node);
+extern void psort_end(Sort * node);
-#endif /* PSORT_H */
+#endif /* PSORT_H */
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 19f9ab138d2..31dcb7401ab 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* rel.h--
- * POSTGRES relation descriptor definitions.
+ * POSTGRES relation descriptor definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rel.h,v 1.9 1997/09/04 13:26:45 vadim Exp $
+ * $Id: rel.h,v 1.10 1997/09/07 05:02:54 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef REL_H
+#ifndef REL_H
#define REL_H
#include <catalog/pg_am.h>
@@ -20,134 +20,137 @@
#include <rewrite/prs2lock.h>
#include <storage/fd.h>
-typedef struct Trigger {
- char *tgname;
- Oid tgfoid;
- func_ptr tgfunc;
- int16 tgtype;
- int16 tgnargs;
- int16 tgattr[8];
- char **tgargs;
-} Trigger;
-
-typedef struct TriggerDesc {
- uint16 n_before_statement[4];
- uint16 n_before_row[4];
- uint16 n_after_row[4];
- uint16 n_after_statement[4];
- Trigger **tg_before_statement[4];
- Trigger **tg_before_row[4];
- Trigger **tg_after_row[4];
- Trigger **tg_after_statement[4];
- Trigger *triggers;
-} TriggerDesc;
-
-typedef struct RelationData {
- File rd_fd; /* open file descriptor */
- int rd_nblocks; /* number of blocks in rel */
- uint16 rd_refcnt; /* reference count */
- bool rd_islocal; /* uses the local buffer mgr */
- bool rd_isnailed; /* rel is nailed in cache */
- bool rd_istemp; /* rel is a temp rel */
- bool rd_tmpunlinked; /* temp rel already unlinked */
- Form_pg_am rd_am; /* AM tuple */
- Form_pg_class rd_rel; /* RELATION tuple */
- Oid rd_id; /* relations's object id */
- Pointer lockInfo; /* ptr. to misc. info. */
- TupleDesc rd_att; /* tuple desciptor */
- RuleLock *rd_rules; /* rewrite rules */
- IndexStrategy rd_istrat;
- RegProcedure* rd_support;
- TriggerDesc *trigdesc;
-} RelationData;
-
-typedef RelationData *Relation;
+typedef struct Trigger
+{
+ char *tgname;
+ Oid tgfoid;
+ func_ptr tgfunc;
+ int16 tgtype;
+ int16 tgnargs;
+ int16 tgattr[8];
+ char **tgargs;
+} Trigger;
+
+typedef struct TriggerDesc
+{
+ uint16 n_before_statement[4];
+ uint16 n_before_row[4];
+ uint16 n_after_row[4];
+ uint16 n_after_statement[4];
+ Trigger **tg_before_statement[4];
+ Trigger **tg_before_row[4];
+ Trigger **tg_after_row[4];
+ Trigger **tg_after_statement[4];
+ Trigger *triggers;
+} TriggerDesc;
+
+typedef struct RelationData
+{
+ File rd_fd; /* open file descriptor */
+ int rd_nblocks; /* number of blocks in rel */
+ uint16 rd_refcnt; /* reference count */
+ bool rd_islocal; /* uses the local buffer mgr */
+ bool rd_isnailed;/* rel is nailed in cache */
+ bool rd_istemp; /* rel is a temp rel */
+ bool rd_tmpunlinked; /* temp rel already unlinked */
+ Form_pg_am rd_am; /* AM tuple */
+ Form_pg_class rd_rel; /* RELATION tuple */
+ Oid rd_id; /* relations's object id */
+ Pointer lockInfo; /* ptr. to misc. info. */
+ TupleDesc rd_att; /* tuple desciptor */
+ RuleLock *rd_rules; /* rewrite rules */
+ IndexStrategy rd_istrat;
+ RegProcedure *rd_support;
+ TriggerDesc *trigdesc;
+} RelationData;
+
+typedef RelationData *Relation;
/* ----------------
- * RelationPtr is used in the executor to support index scans
- * where we have to keep track of several index relations in an
- * array. -cim 9/10/89
+ * RelationPtr is used in the executor to support index scans
+ * where we have to keep track of several index relations in an
+ * array. -cim 9/10/89
* ----------------
*/
-typedef Relation *RelationPtr;
+typedef Relation *RelationPtr;
-#define InvalidRelation ((Relation)NULL)
+#define InvalidRelation ((Relation)NULL)
typedef char ArchiveMode;
/*
* RelationIsValid --
- * True iff relation descriptor is valid.
+ * True iff relation descriptor is valid.
*/
-#define RelationIsValid(relation) PointerIsValid(relation)
+#define RelationIsValid(relation) PointerIsValid(relation)
/*
* RelationGetSystemPort --
- * Returns system port of a relation.
+ * Returns system port of a relation.
*
* Note:
- * Assumes relation descriptor is valid.
+ * Assumes relation descriptor is valid.
*/
#define RelationGetSystemPort(relation) ((relation)->rd_fd)
/*
* RelationGetLockInfo --
- * Returns the lock information structure in the reldesc
+ * Returns the lock information structure in the reldesc
*
*/
#define RelationGetLockInfo(relation) ((relation)->lockInfo)
/*
* RelationHasReferenceCountZero --
- * True iff relation reference count is zero.
+ * True iff relation reference count is zero.
*
* Note:
- * Assumes relation descriptor is valid.
+ * Assumes relation descriptor is valid.
*/
#define RelationHasReferenceCountZero(relation) \
- ((bool)((relation)->rd_refcnt == 0))
+ ((bool)((relation)->rd_refcnt == 0))
/*
* RelationSetReferenceCount --
- * Sets relation reference count.
+ * Sets relation reference count.
*/
#define RelationSetReferenceCount(relation,count) ((relation)->rd_refcnt = count)
/*
* RelationIncrementReferenceCount --
- * Increments relation reference count.
+ * Increments relation reference count.
*/
#define RelationIncrementReferenceCount(relation) ((relation)->rd_refcnt += 1);
/*
* RelationDecrementReferenceCount --
- * Decrements relation reference count.
+ * Decrements relation reference count.
*/
#define RelationDecrementReferenceCount(relation) ((relation)->rd_refcnt -= 1)
/*
* RelationGetAccessMethodTupleForm --
- * Returns access method attribute values for a relation.
+ * Returns access method attribute values for a relation.
*
* Note:
- * Assumes relation descriptor is valid.
+ * Assumes relation descriptor is valid.
*/
#define RelationGetAccessMethodTupleForm(relation) ((relation)->rd_am)
/*
* RelationGetRelationTupleForm --
- * Returns relation attribute values for a relation.
+ * Returns relation attribute values for a relation.
*
* Note:
- * Assumes relation descriptor is valid.
+ * Assumes relation descriptor is valid.
*/
#define RelationGetRelationTupleForm(relation) ((relation)->rd_rel)
-/*
+/*
* RelationGetRelationId --
*
- * returns the object id of the relation
+ * returns the object id of the relation
*
*/
#define RelationGetRelationId(relation) ((relation)->rd_id)
@@ -155,7 +158,7 @@ typedef char ArchiveMode;
/*
* RelationGetFile --
*
- * Returns the open File decscriptor
+ * Returns the open File decscriptor
*/
#define RelationGetFile(relation) ((relation)->rd_fd)
@@ -163,28 +166,30 @@ typedef char ArchiveMode;
/*
* RelationGetRelationName --
*
- * Returns a Relation Name
+ * Returns a Relation Name
*/
#define RelationGetRelationName(relation) (&(relation)->rd_rel->relname)
/*
* RelationGetRelationName --
*
- * Returns a the number of attributes.
+ * Returns a the number of attributes.
*/
#define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts)
/*
* RelationGetTupleDescriptor --
- * Returns tuple descriptor for a relation.
+ * Returns tuple descriptor for a relation.
*
* Note:
- * Assumes relation descriptor is valid.
+ * Assumes relation descriptor is valid.
*/
#define RelationGetTupleDescriptor(relation) ((relation)->rd_att)
extern IndexStrategy RelationGetIndexStrategy(Relation relation);
-extern void RelationSetIndexSupport(Relation relation, IndexStrategy strategy,
- RegProcedure *support);
-#endif /* REL_H */
+extern void
+RelationSetIndexSupport(Relation relation, IndexStrategy strategy,
+ RegProcedure * support);
+
+#endif /* REL_H */
diff --git a/src/include/utils/rel2.h b/src/include/utils/rel2.h
index bee0c78b8fb..19873d34e28 100644
--- a/src/include/utils/rel2.h
+++ b/src/include/utils/rel2.h
@@ -1,23 +1,24 @@
/*-------------------------------------------------------------------------
*
* rel2.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rel2.h,v 1.2 1996/11/04 11:51:25 scrappy Exp $
+ * $Id: rel2.h,v 1.3 1997/09/07 05:02:58 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef TMP_REL2_H
-#define TMP_REL2_H
+#ifndef TMP_REL2_H
+#define TMP_REL2_H
#include <utils/rel.h>
extern IndexStrategy RelationGetIndexStrategy(Relation relation);
-extern void RelationSetIndexSupport(Relation relation, IndexStrategy strategy,
- RegProcedure *support);
+extern void
+RelationSetIndexSupport(Relation relation, IndexStrategy strategy,
+ RegProcedure * support);
-#endif /* TMP_REL2_H */
+#endif /* TMP_REL2_H */
diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
index 7b1a0c2196b..984d0cc63ae 100644
--- a/src/include/utils/relcache.h
+++ b/src/include/utils/relcache.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* relcache.h--
- * Relation descriptor cache definitions.
+ * Relation descriptor cache definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: relcache.h,v 1.6 1997/08/19 21:40:49 momjian Exp $
+ * $Id: relcache.h,v 1.7 1997/09/07 05:03:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef RELCACHE_H
+#ifndef RELCACHE_H
#define RELCACHE_H
#include <utils/rel.h>
@@ -22,17 +22,17 @@ extern Relation RelationIdCacheGetRelation(Oid relationId);
extern Relation RelationIdGetRelation(Oid relationId);
extern Relation RelationNameGetRelation(char *relationName);
-extern void RelationClose(Relation relation);
-extern void RelationForgetRelation(Oid rid);
-extern void RelationIdInvalidateRelationCacheByRelationId(Oid relationId);
+extern void RelationClose(Relation relation);
+extern void RelationForgetRelation(Oid rid);
+extern void RelationIdInvalidateRelationCacheByRelationId(Oid relationId);
-extern void
-RelationIdInvalidateRelationCacheByAccessMethodId(Oid accessMethodId);
+extern void
+ RelationIdInvalidateRelationCacheByAccessMethodId(Oid accessMethodId);
-extern void RelationCacheInvalidate(bool onlyFlushReferenceCountZero);
+extern void RelationCacheInvalidate(bool onlyFlushReferenceCountZero);
-extern void RelationRegisterRelation(Relation relation);
-extern void RelationPurgeLocalRelation(bool xactComitted);
-extern void RelationInitialize(void);
+extern void RelationRegisterRelation(Relation relation);
+extern void RelationPurgeLocalRelation(bool xactComitted);
+extern void RelationInitialize(void);
-#endif /* RELCACHE_H */
+#endif /* RELCACHE_H */
diff --git a/src/include/utils/sets.h b/src/include/utils/sets.h
index 4580f15a3dd..717989bdfe3 100644
--- a/src/include/utils/sets.h
+++ b/src/include/utils/sets.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* sets.h--
- *
+ *
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: sets.h,v 1.1 1996/08/28 01:59:25 scrappy Exp $
+ * $Id: sets.h,v 1.2 1997/09/07 05:03:01 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,7 +16,7 @@
/* Temporary name of set, before SetDefine changes it. */
#define GENERICSETNAME "zyxset"
-extern Oid SetDefine(char *querystr, char *typename);
-extern int seteval(Oid funcoid);
+extern Oid SetDefine(char *querystr, char *typename);
+extern int seteval(Oid funcoid);
-#endif /* SETS_H */
+#endif /* SETS_H */
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 9de2b9d40a3..db830e3cd2f 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -1,90 +1,97 @@
/*-------------------------------------------------------------------------
*
* syscache.h--
- * System catalog cache definitions.
+ * System catalog cache definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: syscache.h,v 1.4 1996/11/04 11:51:27 scrappy Exp $
+ * $Id: syscache.h,v 1.5 1997/09/07 05:03:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-#ifndef SYSCACHE_H
+#ifndef SYSCACHE_H
#define SYSCACHE_H
#include <access/attnum.h>
#include <access/htup.h>
-/*#define CACHEDEBUG*/ /* turns DEBUG elogs on */
+ /*#define CACHEDEBUG*//* turns DEBUG elogs on */
/*
- * Declarations for util/syscache.c.
+ * Declarations for util/syscache.c.
*
- * SysCache identifiers.
+ * SysCache identifiers.
*
- * The order of these must match the order
- * they are entered into the structure cacheinfo[] in syscache.c
- * The best thing to do is to add yours at the END, because some
- * code assumes that certain caches are at certain places in this
- * array.
+ * The order of these must match the order
+ * they are entered into the structure cacheinfo[] in syscache.c
+ * The best thing to do is to add yours at the END, because some
+ * code assumes that certain caches are at certain places in this
+ * array.
*/
-#define AMOPOPID 0
-#define AMOPSTRATEGY 1
-#define ATTNAME 2
-#define ATTNUM 3
-#define INDEXRELID 4
-#define LANNAME 5
-#define OPRNAME 6
-#define OPROID 7
-#define PRONAME 8
-#define PROOID 9
-#define RELNAME 10
-#define RELOID 11
-#define TYPNAME 12
-#define TYPOID 13
-#define AMNAME 14
-#define CLANAME 15
-#define INDRELIDKEY 16
-#define INHRELID 17
-#define RULOID 18
-#define AGGNAME 19
-#define LISTENREL 20
-#define USENAME 21
-#define USESYSID 22
-#define GRONAME 23
-#define GROSYSID 24
-#define REWRITENAME 25
-#define PROSRC 26
-#define CLADEFTYPE 27
+#define AMOPOPID 0
+#define AMOPSTRATEGY 1
+#define ATTNAME 2
+#define ATTNUM 3
+#define INDEXRELID 4
+#define LANNAME 5
+#define OPRNAME 6
+#define OPROID 7
+#define PRONAME 8
+#define PROOID 9
+#define RELNAME 10
+#define RELOID 11
+#define TYPNAME 12
+#define TYPOID 13
+#define AMNAME 14
+#define CLANAME 15
+#define INDRELIDKEY 16
+#define INHRELID 17
+#define RULOID 18
+#define AGGNAME 19
+#define LISTENREL 20
+#define USENAME 21
+#define USESYSID 22
+#define GRONAME 23
+#define GROSYSID 24
+#define REWRITENAME 25
+#define PROSRC 26
+#define CLADEFTYPE 27
/* ----------------
- * struct cachedesc: information needed for a call to InitSysCache()
+ * struct cachedesc: information needed for a call to InitSysCache()
* ----------------
*/
-struct cachedesc {
- char *name; /* this is Name * so that we can initialize it */
- int nkeys;
- int key[4];
- int size; /* sizeof(appropriate struct) */
- char *indname; /* index relation for this cache, if exists */
- HeapTuple (*iScanFunc)(); /* function to handle index scans */
+struct cachedesc
+{
+ char *name; /* this is Name * so that we can
+ * initialize it */
+ int nkeys;
+ int key[4];
+ int size; /* sizeof(appropriate struct) */
+ char *indname; /* index relation for this cache, if
+ * exists */
+ HeapTuple(*iScanFunc) (); /* function to handle
+ * index scans */
};
-extern void zerocaches(void);
-extern void InitCatalogCache(void);
-extern HeapTuple SearchSysCacheTuple(int cacheId, Datum key1, Datum key2,
- Datum key3, Datum key4);
-extern int32 SearchSysCacheStruct(int cacheId, char *returnStruct,
- Datum key1, Datum key2, Datum key3, Datum key4);
-extern void *SearchSysCacheGetAttribute(int cacheId,
- AttrNumber attributeNumber,
- Datum key1,
- Datum key2,
- Datum key3,
- Datum key4);
-extern void *TypeDefaultRetrieve(Oid typId);
+extern void zerocaches(void);
+extern void InitCatalogCache(void);
+extern HeapTuple
+SearchSysCacheTuple(int cacheId, Datum key1, Datum key2,
+ Datum key3, Datum key4);
+extern int32
+SearchSysCacheStruct(int cacheId, char *returnStruct,
+ Datum key1, Datum key2, Datum key3, Datum key4);
+extern void *
+SearchSysCacheGetAttribute(int cacheId,
+ AttrNumber attributeNumber,
+ Datum key1,
+ Datum key2,
+ Datum key3,
+ Datum key4);
+extern void *TypeDefaultRetrieve(Oid typId);
-#endif /* SYSCACHE_H */
+#endif /* SYSCACHE_H */
diff --git a/src/include/utils/tqual.h b/src/include/utils/tqual.h
index 9c45ce0650c..a32ccb2ab13 100644
--- a/src/include/utils/tqual.h
+++ b/src/include/utils/tqual.h
@@ -1,43 +1,45 @@
/*-------------------------------------------------------------------------
*
* tqual.h--
- * POSTGRES time qualification definitions.
+ * POSTGRES time qualification definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: tqual.h,v 1.6 1997/08/19 21:40:50 momjian Exp $
+ * $Id: tqual.h,v 1.7 1997/09/07 05:03:03 momjian Exp $
*
* NOTE
- * It may be desirable to allow time qualifications to indicate
- * relative times.
+ * It may be desirable to allow time qualifications to indicate
+ * relative times.
*
*-------------------------------------------------------------------------
*/
-#ifndef TQUAL_H
+#ifndef TQUAL_H
#define TQUAL_H
#include <access/htup.h>
-typedef struct TimeQualSpace {
- char data[12];
-} TimeQualSpace;
+typedef struct TimeQualSpace
+{
+ char data[12];
+} TimeQualSpace;
-typedef Pointer TimeQual;
+typedef Pointer TimeQual;
/* Tuples valid as of StartTransactionCommand */
-#define NowTimeQual ((TimeQual) NULL)
+#define NowTimeQual ((TimeQual) NULL)
/* As above, plus updates in this command */
-extern TimeQual SelfTimeQual;
+extern TimeQual SelfTimeQual;
-extern void setheapoverride(bool on);
-extern bool heapisoverride(void);
+extern void setheapoverride(bool on);
+extern bool heapisoverride(void);
extern TimeQual TimeFormSnapshotTimeQual(AbsoluteTime time);
-extern TimeQual TimeFormRangedTimeQual(AbsoluteTime startTime,
- AbsoluteTime endTime);
-extern bool HeapTupleSatisfiesTimeQual(HeapTuple tuple, TimeQual qual);
+extern TimeQual
+TimeFormRangedTimeQual(AbsoluteTime startTime,
+ AbsoluteTime endTime);
+extern bool HeapTupleSatisfiesTimeQual(HeapTuple tuple, TimeQual qual);
-#endif /* TQUAL_H */
+#endif /* TQUAL_H */
diff --git a/src/include/version.h b/src/include/version.h
index 927c11170d5..14920ffd378 100644
--- a/src/include/version.h
+++ b/src/include/version.h
@@ -1,10 +1,10 @@
/*-------------------------------------------------------------------------
*
* version.h--
- * this file contains the interface to version.c.
- * Also some parameters.
+ * this file contains the interface to version.c.
+ * Also some parameters.
*
- * $Id: version.h,v 1.2 1997/04/26 05:07:12 scrappy Exp $
+ * $Id: version.h,v 1.3 1997/09/07 04:55:43 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -12,13 +12,13 @@
#define VERSION_H
void
-ValidatePgVersion(const char *path, char **reason_p);
+ ValidatePgVersion(const char *path, char **reason_p);
void
-SetPgVersion(const char *path, char **reason_p);
+ SetPgVersion(const char *path, char **reason_p);
-#define PG_RELEASE 6
-#define PG_VERSION 1
-#define PG_VERFILE "PG_VERSION"
+#define PG_RELEASE 6
+#define PG_VERSION 1
+#define PG_VERFILE "PG_VERSION"
#endif
diff --git a/src/interfaces/libpgtcl/libpgtcl.h b/src/interfaces/libpgtcl/libpgtcl.h
index 7a5fa0364c1..4ee2848c991 100644
--- a/src/interfaces/libpgtcl/libpgtcl.h
+++ b/src/interfaces/libpgtcl/libpgtcl.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* libpgtcl.h--
- * libpgtcl is a tcl package for front-ends to interface with pglite
- * It's the tcl equivalent of the old libpq C interface.
+ * libpgtcl is a tcl package for front-ends to interface with pglite
+ * It's the tcl equivalent of the old libpq C interface.
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpgtcl.h,v 1.2 1996/10/30 06:18:37 scrappy Exp $
+ * $Id: libpgtcl.h,v 1.3 1997/09/07 05:03:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,7 +16,7 @@
#include "tcl.h"
-extern int Pgtcl_Init (Tcl_Interp *interp);
-extern int Pgtcl_SafeInit (Tcl_Interp *interp);
+extern int Pgtcl_Init(Tcl_Interp * interp);
+extern int Pgtcl_SafeInit(Tcl_Interp * interp);
-#endif /* LIBPGTCL_H */
+#endif /* LIBPGTCL_H */
diff --git a/src/interfaces/libpgtcl/pgtcl.c b/src/interfaces/libpgtcl/pgtcl.c
index 8df0c42105c..75c8ec5ddad 100644
--- a/src/interfaces/libpgtcl/pgtcl.c
+++ b/src/interfaces/libpgtcl/pgtcl.c
@@ -1,15 +1,15 @@
/*-------------------------------------------------------------------------
*
* pgtcl.c--
- *
- * libpgtcl is a tcl package for front-ends to interface with pglite
- * It's the tcl equivalent of the old libpq C interface.
+ *
+ * libpgtcl is a tcl package for front-ends to interface with pglite
+ * It's the tcl equivalent of the old libpq C interface.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.7 1997/01/03 18:48:28 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtcl.c,v 1.8 1997/09/07 05:03:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,8 +23,8 @@
#include "pgtclId.h"
/*
- * Pgtcl_Init
- * initialization package for the PGLITE Tcl package
+ * Pgtcl_Init
+ * initialization package for the PGLITE Tcl package
*
*/
@@ -32,153 +32,154 @@
* Tidy up forgotten postgres connection at Tcl_Exit
*/
static void
-Pgtcl_AtExit (ClientData cData)
+Pgtcl_AtExit(ClientData cData)
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- Tcl_HashEntry *hent;
- Tcl_HashSearch hsearch;
- Pg_ConnectionId *connid;
- PGconn *conn;
-
- while((hent = Tcl_FirstHashEntry(&(cd->dbh_hash), &hsearch)) != NULL) {
- connid = (Pg_ConnectionId *)Tcl_GetHashValue(hent);
- conn = connid->conn;
- PgDelConnectionId(cd, connid->id);
- PQfinish(conn);
- }
-
- Tcl_DeleteHashTable(&(cd->dbh_hash));
- Tcl_DeleteHashTable(&(cd->res_hash));
- Tcl_DeleteHashTable(&(cd->notify_hash));
-
- Tcl_DeleteExitHandler(Pgtcl_AtExit, cData);
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ Tcl_HashEntry *hent;
+ Tcl_HashSearch hsearch;
+ Pg_ConnectionId *connid;
+ PGconn *conn;
+
+ while ((hent = Tcl_FirstHashEntry(&(cd->dbh_hash), &hsearch)) != NULL)
+ {
+ connid = (Pg_ConnectionId *) Tcl_GetHashValue(hent);
+ conn = connid->conn;
+ PgDelConnectionId(cd, connid->id);
+ PQfinish(conn);
+ }
+
+ Tcl_DeleteHashTable(&(cd->dbh_hash));
+ Tcl_DeleteHashTable(&(cd->res_hash));
+ Tcl_DeleteHashTable(&(cd->notify_hash));
+
+ Tcl_DeleteExitHandler(Pgtcl_AtExit, cData);
}
/*
* Tidy up forgotten postgres connections on Interpreter deletion
*/
static void
-Pgtcl_Shutdown (ClientData cData, Tcl_Interp *interp)
+Pgtcl_Shutdown(ClientData cData, Tcl_Interp * interp)
{
- Pgtcl_AtExit(cData);
+ Pgtcl_AtExit(cData);
}
int
-Pgtcl_Init (Tcl_Interp *interp)
+Pgtcl_Init(Tcl_Interp * interp)
{
- Pg_clientData *cd;
-
- /* Create and initialize the client data area */
- cd = (Pg_clientData *)ckalloc(sizeof(Pg_clientData));
- Tcl_InitHashTable(&(cd->dbh_hash), TCL_STRING_KEYS);
- Tcl_InitHashTable(&(cd->res_hash), TCL_STRING_KEYS);
- Tcl_InitHashTable(&(cd->notify_hash), TCL_STRING_KEYS);
- cd->dbh_count = 0L;
- cd->res_count = 0L;
-
- /* Arrange for tidy up when interpreter is deleted or Tcl exits */
- Tcl_CallWhenDeleted(interp, Pgtcl_Shutdown, (ClientData)cd);
- Tcl_CreateExitHandler(Pgtcl_AtExit, (ClientData)cd);
-
- /* register all pgtcl commands */
- Tcl_CreateCommand(interp,
- "pg_conndefaults",
- Pg_conndefaults,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_connect",
- Pg_connect,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_disconnect",
- Pg_disconnect,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_exec",
- Pg_exec,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_select",
- Pg_select,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_result",
- Pg_result,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_lo_open",
- Pg_lo_open,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_lo_close",
- Pg_lo_close,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_lo_read",
- Pg_lo_read,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_lo_write",
- Pg_lo_write,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_lo_lseek",
- Pg_lo_lseek,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_lo_creat",
- Pg_lo_creat,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_lo_tell",
- Pg_lo_tell,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_lo_unlink",
- Pg_lo_unlink,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_lo_import",
- Pg_lo_import,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_lo_export",
- Pg_lo_export,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_listen",
- Pg_listen,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_CreateCommand(interp,
- "pg_notifies",
- Pg_notifies,
- (ClientData)cd, (Tcl_CmdDeleteProc*)NULL);
-
- Tcl_PkgProvide(interp, "Pgtcl", "1.0");
-
- return TCL_OK;
+ Pg_clientData *cd;
+
+ /* Create and initialize the client data area */
+ cd = (Pg_clientData *) ckalloc(sizeof(Pg_clientData));
+ Tcl_InitHashTable(&(cd->dbh_hash), TCL_STRING_KEYS);
+ Tcl_InitHashTable(&(cd->res_hash), TCL_STRING_KEYS);
+ Tcl_InitHashTable(&(cd->notify_hash), TCL_STRING_KEYS);
+ cd->dbh_count = 0L;
+ cd->res_count = 0L;
+
+ /* Arrange for tidy up when interpreter is deleted or Tcl exits */
+ Tcl_CallWhenDeleted(interp, Pgtcl_Shutdown, (ClientData) cd);
+ Tcl_CreateExitHandler(Pgtcl_AtExit, (ClientData) cd);
+
+ /* register all pgtcl commands */
+ Tcl_CreateCommand(interp,
+ "pg_conndefaults",
+ Pg_conndefaults,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_connect",
+ Pg_connect,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_disconnect",
+ Pg_disconnect,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_exec",
+ Pg_exec,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_select",
+ Pg_select,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_result",
+ Pg_result,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_lo_open",
+ Pg_lo_open,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_lo_close",
+ Pg_lo_close,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_lo_read",
+ Pg_lo_read,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_lo_write",
+ Pg_lo_write,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_lo_lseek",
+ Pg_lo_lseek,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_lo_creat",
+ Pg_lo_creat,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_lo_tell",
+ Pg_lo_tell,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_lo_unlink",
+ Pg_lo_unlink,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_lo_import",
+ Pg_lo_import,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_lo_export",
+ Pg_lo_export,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_listen",
+ Pg_listen,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_CreateCommand(interp,
+ "pg_notifies",
+ Pg_notifies,
+ (ClientData) cd, (Tcl_CmdDeleteProc *) NULL);
+
+ Tcl_PkgProvide(interp, "Pgtcl", "1.0");
+
+ return TCL_OK;
}
int
-Pgtcl_SafeInit (Tcl_Interp *interp)
+Pgtcl_SafeInit(Tcl_Interp * interp)
{
- return Pgtcl_Init(interp);
+ return Pgtcl_Init(interp);
}
diff --git a/src/interfaces/libpgtcl/pgtclCmds.c b/src/interfaces/libpgtcl/pgtclCmds.c
index 6ad9ca17673..834938487d4 100644
--- a/src/interfaces/libpgtcl/pgtclCmds.c
+++ b/src/interfaces/libpgtcl/pgtclCmds.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* pgtclCmds.c--
- * C functions which implement pg_* tcl commands
+ * C functions which implement pg_* tcl commands
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.13 1997/04/02 18:16:49 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.14 1997/09/07 05:03:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,8 +25,8 @@
#include "pgtclId.h"
#ifdef TCL_ARRAYS
-#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
-#define DIGIT(c) ((c) - '0')
+#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
+#define DIGIT(c) ((c) - '0')
/*
* translate_escape() --
@@ -38,97 +38,107 @@
* just before the rest of the buffer).
*/
-static inline char*
+static inline char *
translate_escape(char *p, int isArray)
{
- register char c, *q, *s;
+ register char c,
+ *q,
+ *s;
#ifdef TCL_ARRAYS_DEBUG_ESCAPE
- printf(" escape = '%s'\n", p);
+ printf(" escape = '%s'\n", p);
#endif
- /* Address of the first character after the escape sequence */
- s = p+2;
- switch (c = *(p+1)) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- c = DIGIT(c);
- if (ISOCTAL(*s)) {
- c = (c<<3) + DIGIT(*s++);
- }
- if (ISOCTAL(*s)) {
- c = (c<<3) + DIGIT(*s++);
- }
- *p = c;
- break;
- case 'b':
- *p = '\b';
- break;
- case 'f':
- *p = '\f';
- break;
- case 'n':
- *p = '\n';
- break;
- case 'r':
- *p = '\r';
- break;
- case 't':
- *p = '\t';
- break;
- case 'v':
- *p = '\v';
- break;
- case '\\':
- case '{':
- case '}':
- case '"':
- /*
- * Backslahes, curly braces and double-quotes are left
- * escaped if they appear inside an array. They will be
- * unescaped by Tcl in Tcl_AppendElement.
- * The buffer position is advanced by 1 so that the this
- * character is not processed again by the caller.
- */
- if (isArray) {
- return p+1;
- } else {
- *p = c;
+ /* Address of the first character after the escape sequence */
+ s = p + 2;
+ switch (c = *(p + 1))
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ c = DIGIT(c);
+ if (ISOCTAL(*s))
+ {
+ c = (c << 3) + DIGIT(*s++);
+ }
+ if (ISOCTAL(*s))
+ {
+ c = (c << 3) + DIGIT(*s++);
+ }
+ *p = c;
+ break;
+ case 'b':
+ *p = '\b';
+ break;
+ case 'f':
+ *p = '\f';
+ break;
+ case 'n':
+ *p = '\n';
+ break;
+ case 'r':
+ *p = '\r';
+ break;
+ case 't':
+ *p = '\t';
+ break;
+ case 'v':
+ *p = '\v';
+ break;
+ case '\\':
+ case '{':
+ case '}':
+ case '"':
+
+ /*
+ * Backslahes, curly braces and double-quotes are left escaped if
+ * they appear inside an array. They will be unescaped by Tcl in
+ * Tcl_AppendElement. The buffer position is advanced by 1 so that
+ * the this character is not processed again by the caller.
+ */
+ if (isArray)
+ {
+ return p + 1;
+ }
+ else
+ {
+ *p = c;
+ }
+ break;
+ case '\0':
+
+ /*
+ * This means a backslash at the end of the string. It should
+ * never happen but in that case replace the \ with a \0 but don't
+ * shift the rest of the buffer so that the caller can see the end
+ * of the string and terminate.
+ */
+ *p = c;
+ return p;
+ break;
+ default:
+
+ /*
+ * Default case, store the escaped character over the backslash
+ * and shift the buffer over itself.
+ */
+ *p = c;
}
- break;
- case '\0':
- /*
- * This means a backslash at the end of the string.
- * It should never happen but in that case replace
- * the \ with a \0 but don't shift the rest of the
- * buffer so that the caller can see the end of the
- * string and terminate.
- */
- *p = c;
- return p;
- break;
- default:
- /*
- * Default case, store the escaped character over the backslash
- * and shift the buffer over itself.
- */
- *p = c;
- }
- /* Shift the rest of the buffer over itself after the current char */
- q = p+1;
- for ( ; *s ; ) {
- *q++ = *s++;
- }
- *q = '\0';
+ /* Shift the rest of the buffer over itself after the current char */
+ q = p + 1;
+ for (; *s;)
+ {
+ *q++ = *s++;
+ }
+ *q = '\0';
#ifdef TCL_ARRAYS_DEBUG_ESCAPE
- printf(" after = '%s'\n", p);
+ printf(" after = '%s'\n", p);
#endif
- return p;
+ return p;
}
/*
@@ -139,299 +149,339 @@ translate_escape(char *p, int isArray)
* representation of a postgres array.
*/
-static char *
-tcl_value (char *value)
+static char *
+tcl_value(char *value)
{
- int literal, last;
- register char *p;
+ int literal,
+ last;
+ register char *p;
- if (!value) {
- return ((char *) NULL);
- }
+ if (!value)
+ {
+ return ((char *) NULL);
+ }
#ifdef TCL_ARRAYS_DEBUG
- printf("pq_value = '%s'\n", value);
+ printf("pq_value = '%s'\n", value);
#endif
- last = strlen(value)-1;
- if ((last >= 1) && (value[0] == '{') && (value[last] == '}')) {
- /* Looks like an array, replace ',' with spaces */
- /* Remove the outer pair of { }, the last first! */
- value[last] = '\0';
- value++;
- literal = 0;
- for (p=value; *p; p++) {
- if (!literal) {
- /* We are at the list level, look for ',' and '"' */
- switch (*p) {
- case '"': /* beginning of literal */
- literal = 1;
- break;
- case ',': /* replace the ',' with space */
- *p = ' ';
- break;
- }
- } else {
- /* We are inside a C string */
- switch (*p) {
- case '"': /* end of literal */
- literal = 0;
- break;
- case '\\':
- /*
- * escape sequence, translate it
- */
- p = translate_escape(p,1);
- break;
+ last = strlen(value) - 1;
+ if ((last >= 1) && (value[0] == '{') && (value[last] == '}'))
+ {
+ /* Looks like an array, replace ',' with spaces */
+ /* Remove the outer pair of { }, the last first! */
+ value[last] = '\0';
+ value++;
+ literal = 0;
+ for (p = value; *p; p++)
+ {
+ if (!literal)
+ {
+ /* We are at the list level, look for ',' and '"' */
+ switch (*p)
+ {
+ case '"': /* beginning of literal */
+ literal = 1;
+ break;
+ case ',': /* replace the ',' with space */
+ *p = ' ';
+ break;
+ }
+ }
+ else
+ {
+ /* We are inside a C string */
+ switch (*p)
+ {
+ case '"': /* end of literal */
+ literal = 0;
+ break;
+ case '\\':
+
+ /*
+ * escape sequence, translate it
+ */
+ p = translate_escape(p, 1);
+ break;
+ }
+ }
+ if (!*p)
+ {
+ break;
+ }
}
- }
- if (!*p) {
- break;
- }
}
- } else {
- /* Looks like a normal scalar value */
- for (p=value; *p; p++) {
- if (*p == '\\') {
- /*
- * escape sequence, translate it
- */
- p = translate_escape(p,0);
- }
- if (!*p) {
- break;
- }
+ else
+ {
+ /* Looks like a normal scalar value */
+ for (p = value; *p; p++)
+ {
+ if (*p == '\\')
+ {
+
+ /*
+ * escape sequence, translate it
+ */
+ p = translate_escape(p, 0);
+ }
+ if (!*p)
+ {
+ break;
+ }
+ }
}
- }
#ifdef TCL_ARRAYS_DEBUG
- printf("tcl_value = '%s'\n\n", value);
+ printf("tcl_value = '%s'\n\n", value);
#endif
- return (value);
+ return (value);
}
#endif
/**********************************
* pg_conndefaults
-
+
syntax:
pg_conndefaults
-
+
the return result is a list describing the possible options and their
current default values for a call to pg_connect with the new -conninfo
syntax. Each entry in the list is a sublist of the format:
- {optname label dispchar dispsize value}
-
+ {optname label dispchar dispsize value}
+
**********************************/
int
-Pg_conndefaults(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
+Pg_conndefaults(ClientData cData, Tcl_Interp * interp, int argc, char **argv)
{
- PQconninfoOption *option;
- char buf[8192];
-
- Tcl_ResetResult(interp);
- for(option = PQconndefaults(); option->keyword != NULL; option++) {
- if(option->val == NULL) {
- option->val = "";
- }
- sprintf(buf, "{%s} {%s} {%s} %d {%s}",
- option->keyword,
- option->label,
- option->dispchar,
- option->dispsize,
- option->val);
- Tcl_AppendElement(interp, buf);
- }
-
- return TCL_OK;
+ PQconninfoOption *option;
+ char buf[8192];
+
+ Tcl_ResetResult(interp);
+ for (option = PQconndefaults(); option->keyword != NULL; option++)
+ {
+ if (option->val == NULL)
+ {
+ option->val = "";
+ }
+ sprintf(buf, "{%s} {%s} {%s} %d {%s}",
+ option->keyword,
+ option->label,
+ option->dispchar,
+ option->dispsize,
+ option->val);
+ Tcl_AppendElement(interp, buf);
+ }
+
+ return TCL_OK;
}
/**********************************
* pg_connect
- make a connection to a backend.
-
+ make a connection to a backend.
+
syntax:
pg_connect dbName [-host hostName] [-port portNumber] [-tty pqtty]]
-
+
the return result is either an error message or a handle for a database
connection. Handles start with the prefix "pgp"
-
+
**********************************/
int
-Pg_connect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_connect(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- char *pghost = NULL;
- char *pgtty = NULL;
- char *pgport = NULL;
- char *pgoptions = NULL;
- char *dbName;
- int i;
- PGconn *conn;
-
- if (argc == 1) {
- Tcl_AppendResult(interp, "pg_connect: database name missing\n", 0);
- Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]\n", 0);
- Tcl_AppendResult(interp, "pg_connect -conninfo <conninfo-string>", 0);
- return TCL_ERROR;
-
- }
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ char *pghost = NULL;
+ char *pgtty = NULL;
+ char *pgport = NULL;
+ char *pgoptions = NULL;
+ char *dbName;
+ int i;
+ PGconn *conn;
+
+ if (argc == 1)
+ {
+ Tcl_AppendResult(interp, "pg_connect: database name missing\n", 0);
+ Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]\n", 0);
+ Tcl_AppendResult(interp, "pg_connect -conninfo <conninfo-string>", 0);
+ return TCL_ERROR;
- if (!strcmp("-conninfo", argv[1])) {
- /*
- * Establish a connection using the new PQconnectdb() interface
- */
- if (argc != 3) {
- Tcl_AppendResult(interp, "pg_connect: syntax error\n", 0);
- Tcl_AppendResult(interp, "pg_connect -conninfo <conninfo-string>", 0);
- return TCL_ERROR;
}
- conn = PQconnectdb(argv[2]);
- } else {
- /*
- * Establish a connection using the old PQsetdb() interface
- */
- if (argc > 2) {
- /* parse for pg environment settings */
- i = 2;
- while (i+1 < argc) {
- if (strcmp(argv[i], "-host") == 0) {
- pghost = argv[i+1];
- i += 2;
+
+ if (!strcmp("-conninfo", argv[1]))
+ {
+
+ /*
+ * Establish a connection using the new PQconnectdb() interface
+ */
+ if (argc != 3)
+ {
+ Tcl_AppendResult(interp, "pg_connect: syntax error\n", 0);
+ Tcl_AppendResult(interp, "pg_connect -conninfo <conninfo-string>", 0);
+ return TCL_ERROR;
}
- else
- if (strcmp(argv[i], "-port") == 0) {
- pgport = argv[i+1];
- i += 2;
- }
- else
- if (strcmp(argv[i], "-tty") == 0) {
- pgtty = argv[i+1];
- i += 2;
- }
- else if (strcmp(argv[i], "-options") == 0) {
- pgoptions = argv[i+1];
- i += 2;
- }
- else {
- Tcl_AppendResult(interp, "Bad option to pg_connect : \n",
- argv[i], 0);
- Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]",0);
- return TCL_ERROR;
+ conn = PQconnectdb(argv[2]);
+ }
+ else
+ {
+
+ /*
+ * Establish a connection using the old PQsetdb() interface
+ */
+ if (argc > 2)
+ {
+ /* parse for pg environment settings */
+ i = 2;
+ while (i + 1 < argc)
+ {
+ if (strcmp(argv[i], "-host") == 0)
+ {
+ pghost = argv[i + 1];
+ i += 2;
+ }
+ else if (strcmp(argv[i], "-port") == 0)
+ {
+ pgport = argv[i + 1];
+ i += 2;
+ }
+ else if (strcmp(argv[i], "-tty") == 0)
+ {
+ pgtty = argv[i + 1];
+ i += 2;
+ }
+ else if (strcmp(argv[i], "-options") == 0)
+ {
+ pgoptions = argv[i + 1];
+ i += 2;
+ }
+ else
+ {
+ Tcl_AppendResult(interp, "Bad option to pg_connect : \n",
+ argv[i], 0);
+ Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]", 0);
+ return TCL_ERROR;
+ }
+ } /* while */
+ if ((i % 2 != 0) || i != argc)
+ {
+ Tcl_AppendResult(interp, "wrong # of arguments to pg_connect\n", argv[i], 0);
+ Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]", 0);
+ return TCL_ERROR;
}
- } /* while */
- if ((i % 2 != 0) || i != argc) {
- Tcl_AppendResult(interp, "wrong # of arguments to pg_connect\n", argv[i],0);
- Tcl_AppendResult(interp, "pg_connect databaseName [-host hostName] [-port portNumber] [-tty pgtty]]",0);
- return TCL_ERROR;
- }
+ }
+ dbName = argv[1];
+ conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
}
- dbName = argv[1];
- conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
- }
- if (conn->status == CONNECTION_OK) {
- PgSetConnectionId(cd, interp->result, conn);
- return TCL_OK;
- }
- else {
- Tcl_AppendResult(interp, "Connection to database failed\n", 0);
- Tcl_AppendResult(interp, conn->errorMessage, 0);
- PQfinish(conn);
- return TCL_ERROR;
- }
+ if (conn->status == CONNECTION_OK)
+ {
+ PgSetConnectionId(cd, interp->result, conn);
+ return TCL_OK;
+ }
+ else
+ {
+ Tcl_AppendResult(interp, "Connection to database failed\n", 0);
+ Tcl_AppendResult(interp, conn->errorMessage, 0);
+ PQfinish(conn);
+ return TCL_ERROR;
+ }
}
/**********************************
* pg_disconnect
close a backend connection
-
+
syntax:
pg_disconnect connection
-
+
The argument passed in must be a connection pointer.
-
+
**********************************/
int
-Pg_disconnect(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_disconnect(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
- if (argc != 2) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n", "pg_disconnect connection", 0);
- return TCL_ERROR;
- }
+ if (argc != 2)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n", "pg_disconnect connection", 0);
+ return TCL_ERROR;
+ }
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- PgDelConnectionId(cd, argv[1]);
- PQfinish(conn);
- return TCL_OK;
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
+
+ PgDelConnectionId(cd, argv[1]);
+ PQfinish(conn);
+ return TCL_OK;
}
/**********************************
* pg_exec
send a query string to the backend connection
-
+
syntax:
pg_exec connection query
-
+
the return result is either an error message or a handle for a query
result. Handles start with the prefix "pgp"
**********************************/
int
-Pg_exec(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_exec(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- PGresult *result;
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ PGresult *result;
- if (argc != 3) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_exec connection queryString", 0);
- return TCL_ERROR;
- }
+ if (argc != 3)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ "pg_exec connection queryString", 0);
+ return TCL_ERROR;
+ }
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- result = PQexec(conn, argv[2]);
- if (result) {
- PgSetResultId(cd, interp->result, argv[1], result);
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
+
+ result = PQexec(conn, argv[2]);
+ if (result)
+ {
+ PgSetResultId(cd, interp->result, argv[1], result);
+ return TCL_OK;
+ }
+ else
+ {
+ /* error occurred during the query */
+ Tcl_SetResult(interp, conn->errorMessage, TCL_STATIC);
+ return TCL_ERROR;
+ }
+ /* check return status of result */
return TCL_OK;
- }
- else {
- /* error occurred during the query */
- Tcl_SetResult(interp, conn->errorMessage, TCL_STATIC);
- return TCL_ERROR;
- }
- /* check return status of result */
- return TCL_OK;
}
/**********************************
* pg_result
get information about the results of a query
-
+
syntax:
- pg_result result ?option?
-
+ pg_result result ?option?
+
the options are:
- -status
+ -status
the status of the result
-conn
the connection that produced the result
@@ -451,291 +501,333 @@ Pg_exec(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
returns the number of attributes returned by the query
-getTuple tupleNumber
returns the values of the tuple in a list
- -clear
+ -clear
clear the result buffer. Do not reuse after this
**********************************/
int
-Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_result(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGresult *result;
- char *opt;
- int i;
- int tupno;
- char prearrayInd[MAX_MESSAGE_LEN];
- char arrayInd[MAX_MESSAGE_LEN];
- char *appendstr;
- char *arrVar;
-
- if (argc != 3 && argc != 4 && argc != 5) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",0);
- goto Pg_result_errReturn;
- }
-
- result = PgGetResultId(cd, argv[1]);
- if (result == (PGresult *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid query result\n", 0);
- return TCL_ERROR;
- }
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGresult *result;
+ char *opt;
+ int i;
+ int tupno;
+ char prearrayInd[MAX_MESSAGE_LEN];
+ char arrayInd[MAX_MESSAGE_LEN];
+ char *appendstr;
+ char *arrVar;
+
+ if (argc != 3 && argc != 4 && argc != 5)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n", 0);
+ goto Pg_result_errReturn;
+ }
+
+ result = PgGetResultId(cd, argv[1]);
+ if (result == (PGresult *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid query result\n", 0);
+ return TCL_ERROR;
+ }
- opt = argv[2];
+ opt = argv[2];
- if (strcmp(opt, "-status") == 0) {
- Tcl_AppendResult(interp, pgresStatus[PQresultStatus(result)], 0);
- return TCL_OK;
- }
- else if (strcmp(opt, "-oid") == 0) {
- Tcl_AppendResult(interp, PQoidStatus(result), 0);
- return TCL_OK;
- }
- else if (strcmp(opt, "-conn") == 0) {
- PgGetConnByResultId(cd, interp->result, argv[1]);
- return TCL_OK;
- }
- else if (strcmp(opt, "-clear") == 0) {
- PgDelResultId(cd, argv[1]);
- PQclear(result);
- return TCL_OK;
- }
- else if (strcmp(opt, "-numTuples") == 0) {
- sprintf(interp->result, "%d", PQntuples(result));
- return TCL_OK;
- }
- else if (strcmp(opt, "-assign") == 0) {
- if (argc != 4) {
- Tcl_AppendResult(interp, "-assign option must be followed by a variable name",0);
- return TCL_ERROR;
- }
- arrVar = argv[3];
- /* this assignment assigns the table of result tuples into a giant
- array with the name given in the argument,
- the indices of the array or (tupno,attrName)*/
- for (tupno = 0; tupno<PQntuples(result); tupno++) {
- for (i=0;i<PQnfields(result);i++) {
- sprintf(arrayInd, "%d,%s", tupno, PQfname(result,i));
- Tcl_SetVar2(interp, arrVar, arrayInd,
+ if (strcmp(opt, "-status") == 0)
+ {
+ Tcl_AppendResult(interp, pgresStatus[PQresultStatus(result)], 0);
+ return TCL_OK;
+ }
+ else if (strcmp(opt, "-oid") == 0)
+ {
+ Tcl_AppendResult(interp, PQoidStatus(result), 0);
+ return TCL_OK;
+ }
+ else if (strcmp(opt, "-conn") == 0)
+ {
+ PgGetConnByResultId(cd, interp->result, argv[1]);
+ return TCL_OK;
+ }
+ else if (strcmp(opt, "-clear") == 0)
+ {
+ PgDelResultId(cd, argv[1]);
+ PQclear(result);
+ return TCL_OK;
+ }
+ else if (strcmp(opt, "-numTuples") == 0)
+ {
+ sprintf(interp->result, "%d", PQntuples(result));
+ return TCL_OK;
+ }
+ else if (strcmp(opt, "-assign") == 0)
+ {
+ if (argc != 4)
+ {
+ Tcl_AppendResult(interp, "-assign option must be followed by a variable name", 0);
+ return TCL_ERROR;
+ }
+ arrVar = argv[3];
+
+ /*
+ * this assignment assigns the table of result tuples into a giant
+ * array with the name given in the argument, the indices of the
+ * array or (tupno,attrName)
+ */
+ for (tupno = 0; tupno < PQntuples(result); tupno++)
+ {
+ for (i = 0; i < PQnfields(result); i++)
+ {
+ sprintf(arrayInd, "%d,%s", tupno, PQfname(result, i));
+ Tcl_SetVar2(interp, arrVar, arrayInd,
#ifdef TCL_ARRAYS
- tcl_value(PQgetvalue(result,tupno,i)),
+ tcl_value(PQgetvalue(result, tupno, i)),
#else
- PQgetvalue(result,tupno,i),
+ PQgetvalue(result, tupno, i),
#endif
- TCL_LEAVE_ERR_MSG);
- }
+ TCL_LEAVE_ERR_MSG);
+ }
+ }
+ Tcl_AppendResult(interp, arrVar, 0);
+ return TCL_OK;
}
- Tcl_AppendResult(interp, arrVar, 0);
- return TCL_OK;
- }
- else if (strcmp(opt, "-assignbyidx") == 0) {
- if (argc !=4 && argc != 5) {
- Tcl_AppendResult(interp, "-assignbyidx requires the array name and takes one optional argument as an append string",0);
- return TCL_ERROR;
- }
- arrVar = argv[3];
- /* this assignment assigns the table of result tuples into a giant
- array with the name given in the argument,
- the indices of the array or (tupno,attrName)*/
- if (argc == 5) {
- appendstr = argv[4];
- } else {
- appendstr = "";
- }
- for (tupno = 0; tupno<PQntuples(result); tupno++) {
- sprintf(prearrayInd,"%s",PQgetvalue(result,tupno,0));
- for (i=1;i<PQnfields(result);i++) {
- sprintf(arrayInd, "%s,%s%s", prearrayInd, PQfname(result,i),
- appendstr);
- Tcl_SetVar2(interp, arrVar, arrayInd,
- PQgetvalue(result,tupno,i),
- TCL_LEAVE_ERR_MSG);
- }
- }
- Tcl_AppendResult(interp, arrVar, 0);
- return TCL_OK;
- }
- else if (strcmp(opt, "-getTuple") == 0) {
- if (argc != 4) {
- Tcl_AppendResult(interp, "-getTuple option must be followed by a tuple number",0);
- return TCL_ERROR;
- }
- tupno = atoi(argv[3]);
-
- if (tupno >= PQntuples(result)) {
- Tcl_AppendResult(interp, "argument to getTuple cannot exceed number of tuples - 1",0);
- return TCL_ERROR;
+ else if (strcmp(opt, "-assignbyidx") == 0)
+ {
+ if (argc != 4 && argc != 5)
+ {
+ Tcl_AppendResult(interp, "-assignbyidx requires the array name and takes one optional argument as an append string", 0);
+ return TCL_ERROR;
+ }
+ arrVar = argv[3];
+
+ /*
+ * this assignment assigns the table of result tuples into a giant
+ * array with the name given in the argument, the indices of the
+ * array or (tupno,attrName)
+ */
+ if (argc == 5)
+ {
+ appendstr = argv[4];
+ }
+ else
+ {
+ appendstr = "";
+ }
+ for (tupno = 0; tupno < PQntuples(result); tupno++)
+ {
+ sprintf(prearrayInd, "%s", PQgetvalue(result, tupno, 0));
+ for (i = 1; i < PQnfields(result); i++)
+ {
+ sprintf(arrayInd, "%s,%s%s", prearrayInd, PQfname(result, i),
+ appendstr);
+ Tcl_SetVar2(interp, arrVar, arrayInd,
+ PQgetvalue(result, tupno, i),
+ TCL_LEAVE_ERR_MSG);
+ }
+ }
+ Tcl_AppendResult(interp, arrVar, 0);
+ return TCL_OK;
}
+ else if (strcmp(opt, "-getTuple") == 0)
+ {
+ if (argc != 4)
+ {
+ Tcl_AppendResult(interp, "-getTuple option must be followed by a tuple number", 0);
+ return TCL_ERROR;
+ }
+ tupno = atoi(argv[3]);
+
+ if (tupno >= PQntuples(result))
+ {
+ Tcl_AppendResult(interp, "argument to getTuple cannot exceed number of tuples - 1", 0);
+ return TCL_ERROR;
+ }
#ifdef TCL_ARRAYS
- for (i=0; i<PQnfields(result); i++) {
- Tcl_AppendElement(interp, tcl_value(PQgetvalue(result,tupno,i)));
- }
+ for (i = 0; i < PQnfields(result); i++)
+ {
+ Tcl_AppendElement(interp, tcl_value(PQgetvalue(result, tupno, i)));
+ }
#else
-/* Tcl_AppendResult(interp, PQgetvalue(result,tupno,0),NULL); */
- Tcl_AppendElement(interp, PQgetvalue(result,tupno,0));
- for (i=1;i<PQnfields(result);i++) {
-/* Tcl_AppendResult(interp, " ", PQgetvalue(result,tupno,i),NULL);*/
- Tcl_AppendElement(interp, PQgetvalue(result,tupno,i));
- }
+/* Tcl_AppendResult(interp, PQgetvalue(result,tupno,0),NULL); */
+ Tcl_AppendElement(interp, PQgetvalue(result, tupno, 0));
+ for (i = 1; i < PQnfields(result); i++)
+ {
+/* Tcl_AppendResult(interp, " ", PQgetvalue(result,tupno,i),NULL);*/
+ Tcl_AppendElement(interp, PQgetvalue(result, tupno, i));
+ }
#endif
- return TCL_OK;
- }
- else if (strcmp(opt, "-attributes") == 0) {
- Tcl_AppendResult(interp, PQfname(result,0),NULL);
- for (i=1;i<PQnfields(result);i++) {
- Tcl_AppendResult(interp, " ", PQfname(result,i), NULL);
- }
- return TCL_OK;
- }
- else if (strcmp(opt, "-lAttributes") == 0) {
- char buf[512];
- Tcl_ResetResult(interp);
- for (i = 0; i < PQnfields(result); i++) {
- sprintf(buf, "{%s} %ld %d", PQfname(result, i),
- (long) PQftype(result, i),
- PQfsize(result, i));
- Tcl_AppendElement(interp, buf);
- }
- return TCL_OK;
- }
- else if (strcmp(opt, "-numAttrs") == 0) {
- sprintf(interp->result, "%d", PQnfields(result));
- return TCL_OK;
- }
- else {
- Tcl_AppendResult(interp, "Invalid option",0);
- goto Pg_result_errReturn;
- }
-
-
- Pg_result_errReturn:
- Tcl_AppendResult(interp,
- "pg_result result ?option? where ?option is\n",
- "\t-status\n",
- "\t-conn\n",
- "\t-assign arrayVarName\n",
- "\t-assignbyidx arrayVarName ?appendstr?\n",
- "\t-numTuples\n",
- "\t-attributes\n"
- "\t-lAttributes\n"
- "\t-numAttrs\n"
- "\t-getTuple tupleNumber\n",
- "\t-clear\n",
- "\t-oid\n",
- 0);
- return TCL_ERROR;
-
+ return TCL_OK;
+ }
+ else if (strcmp(opt, "-attributes") == 0)
+ {
+ Tcl_AppendResult(interp, PQfname(result, 0), NULL);
+ for (i = 1; i < PQnfields(result); i++)
+ {
+ Tcl_AppendResult(interp, " ", PQfname(result, i), NULL);
+ }
+ return TCL_OK;
+ }
+ else if (strcmp(opt, "-lAttributes") == 0)
+ {
+ char buf[512];
+
+ Tcl_ResetResult(interp);
+ for (i = 0; i < PQnfields(result); i++)
+ {
+ sprintf(buf, "{%s} %ld %d", PQfname(result, i),
+ (long) PQftype(result, i),
+ PQfsize(result, i));
+ Tcl_AppendElement(interp, buf);
+ }
+ return TCL_OK;
+ }
+ else if (strcmp(opt, "-numAttrs") == 0)
+ {
+ sprintf(interp->result, "%d", PQnfields(result));
+ return TCL_OK;
+ }
+ else
+ {
+ Tcl_AppendResult(interp, "Invalid option", 0);
+ goto Pg_result_errReturn;
+ }
+
+
+Pg_result_errReturn:
+ Tcl_AppendResult(interp,
+ "pg_result result ?option? where ?option is\n",
+ "\t-status\n",
+ "\t-conn\n",
+ "\t-assign arrayVarName\n",
+ "\t-assignbyidx arrayVarName ?appendstr?\n",
+ "\t-numTuples\n",
+ "\t-attributes\n"
+ "\t-lAttributes\n"
+ "\t-numAttrs\n"
+ "\t-getTuple tupleNumber\n",
+ "\t-clear\n",
+ "\t-oid\n",
+ 0);
+ return TCL_ERROR;
+
}
/**********************************
* pg_lo_open
- open a large object
-
+ open a large object
+
syntax:
- pg_lo_open conn objOid mode
+ pg_lo_open conn objOid mode
where mode can be either 'r', 'w', or 'rw'
**********************/
int
-Pg_lo_open(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_lo_open(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- int lobjId;
- int mode;
- int fd;
-
- if (argc != 4) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_lo_open connection lobjOid mode", 0);
- return TCL_ERROR;
- }
-
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- lobjId = atoi(argv[2]);
- if (strlen(argv[3]) < 1 ||
- strlen(argv[3]) > 2)
- {
- Tcl_AppendResult(interp,"mode argument must be 'r', 'w', or 'rw'",0);
- return TCL_ERROR;
- }
- switch (argv[3][0]) {
- case 'r':
- case 'R':
- mode = INV_READ;
- break;
- case 'w':
- case 'W':
- mode = INV_WRITE;
- break;
- default:
- Tcl_AppendResult(interp,"mode argument must be 'r', 'w', or 'rw'",0);
- return TCL_ERROR;
- }
- switch (argv[3][1]) {
- case '\0':
- break;
- case 'r':
- case 'R':
- mode = mode & INV_READ;
- break;
- case 'w':
- case 'W':
- mode = mode & INV_WRITE;
- break;
- default:
- Tcl_AppendResult(interp,"mode argument must be 'r', 'w', or 'rw'",0);
- return TCL_ERROR;
- }
-
- fd = lo_open(conn,lobjId,mode);
- sprintf(interp->result,"%d",fd);
- return TCL_OK;
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ int lobjId;
+ int mode;
+ int fd;
+
+ if (argc != 4)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ "pg_lo_open connection lobjOid mode", 0);
+ return TCL_ERROR;
+ }
+
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
+
+ lobjId = atoi(argv[2]);
+ if (strlen(argv[3]) < 1 ||
+ strlen(argv[3]) > 2)
+ {
+ Tcl_AppendResult(interp, "mode argument must be 'r', 'w', or 'rw'", 0);
+ return TCL_ERROR;
+ }
+ switch (argv[3][0])
+ {
+ case 'r':
+ case 'R':
+ mode = INV_READ;
+ break;
+ case 'w':
+ case 'W':
+ mode = INV_WRITE;
+ break;
+ default:
+ Tcl_AppendResult(interp, "mode argument must be 'r', 'w', or 'rw'", 0);
+ return TCL_ERROR;
+ }
+ switch (argv[3][1])
+ {
+ case '\0':
+ break;
+ case 'r':
+ case 'R':
+ mode = mode & INV_READ;
+ break;
+ case 'w':
+ case 'W':
+ mode = mode & INV_WRITE;
+ break;
+ default:
+ Tcl_AppendResult(interp, "mode argument must be 'r', 'w', or 'rw'", 0);
+ return TCL_ERROR;
+ }
+
+ fd = lo_open(conn, lobjId, mode);
+ sprintf(interp->result, "%d", fd);
+ return TCL_OK;
}
/**********************************
* pg_lo_close
- close a large object
-
+ close a large object
+
syntax:
- pg_lo_close conn fd
+ pg_lo_close conn fd
**********************/
int
-Pg_lo_close(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_lo_close(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- int fd;
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ int fd;
- if (argc != 3) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_lo_close connection fd", 0);
- return TCL_ERROR;
- }
+ if (argc != 3)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ "pg_lo_close connection fd", 0);
+ return TCL_ERROR;
+ }
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- fd = atoi(argv[2]);
- sprintf(interp->result,"%d",lo_close(conn,fd));
- return TCL_OK;
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
+
+ fd = atoi(argv[2]);
+ sprintf(interp->result, "%d", lo_close(conn, fd));
+ return TCL_OK;
}
/**********************************
* pg_lo_read
- reads at most len bytes from a large object into a variable named
+ reads at most len bytes from a large object into a variable named
bufVar
-
+
syntax:
pg_lo_read conn fd bufVar len
@@ -743,98 +835,104 @@ Pg_lo_close(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
**********************/
int
-Pg_lo_read(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_lo_read(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- int fd;
- int nbytes = 0;
- char *buf;
- char *bufVar;
- int len;
-
- if (argc != 5) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- " pg_lo_read conn fd bufVar len", 0);
- return TCL_ERROR;
- }
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ int fd;
+ int nbytes = 0;
+ char *buf;
+ char *bufVar;
+ int len;
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- fd = atoi(argv[2]);
+ if (argc != 5)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ " pg_lo_read conn fd bufVar len", 0);
+ return TCL_ERROR;
+ }
+
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
- bufVar = argv[3];
+ fd = atoi(argv[2]);
- len = atoi(argv[4]);
+ bufVar = argv[3];
- if (len <= 0) {
- sprintf(interp->result,"%d",nbytes);
- return TCL_OK;
- }
- buf = malloc(sizeof(len+1));
+ len = atoi(argv[4]);
+
+ if (len <= 0)
+ {
+ sprintf(interp->result, "%d", nbytes);
+ return TCL_OK;
+ }
+ buf = malloc(sizeof(len + 1));
- nbytes = lo_read(conn,fd,buf,len);
+ nbytes = lo_read(conn, fd, buf, len);
+
+ Tcl_SetVar(interp, bufVar, buf, TCL_LEAVE_ERR_MSG);
+ sprintf(interp->result, "%d", nbytes);
+ free(buf);
+ return TCL_OK;
- Tcl_SetVar(interp,bufVar,buf,TCL_LEAVE_ERR_MSG);
- sprintf(interp->result,"%d",nbytes);
- free(buf);
- return TCL_OK;
-
}
/***********************************
Pg_lo_write
- write at most len bytes to a large object
+ write at most len bytes to a large object
syntax:
pg_lo_write conn fd buf len
***********************************/
int
-Pg_lo_write(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_lo_write(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- char *buf;
- int fd;
- int nbytes = 0;
- int len;
-
- if (argc != 5) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_lo_write conn fd buf len", 0);
- return TCL_ERROR;
- }
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ char *buf;
+ int fd;
+ int nbytes = 0;
+ int len;
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- fd = atoi(argv[2]);
+ if (argc != 5)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ "pg_lo_write conn fd buf len", 0);
+ return TCL_ERROR;
+ }
+
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
- buf = argv[3];
+ fd = atoi(argv[2]);
- len = atoi(argv[4]);
+ buf = argv[3];
- if (len <= 0) {
- sprintf(interp->result,"%d",nbytes);
- return TCL_OK;
- }
+ len = atoi(argv[4]);
- nbytes = lo_write(conn,fd,buf,len);
- sprintf(interp->result,"%d",nbytes);
- return TCL_OK;
+ if (len <= 0)
+ {
+ sprintf(interp->result, "%d", nbytes);
+ return TCL_OK;
+ }
+
+ nbytes = lo_write(conn, fd, buf, len);
+ sprintf(interp->result, "%d", nbytes);
+ return TCL_OK;
}
/***********************************
Pg_lo_lseek
- seek to a certain position in a large object
+ seek to a certain position in a large object
syntax
pg_lo_lseek conn fd offset whence
@@ -843,44 +941,54 @@ whence can be either
"SEEK_CUR", "SEEK_END", or "SEEK_SET"
***********************************/
int
-Pg_lo_lseek(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_lo_lseek(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- int fd;
- char *whenceStr;
- int offset, whence;
-
- if (argc != 5) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_lo_lseek conn fd offset whence", 0);
- return TCL_ERROR;
- }
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ int fd;
+ char *whenceStr;
+ int offset,
+ whence;
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- fd = atoi(argv[2]);
-
- offset = atoi(argv[3]);
-
- whenceStr = argv[4];
- if (strcmp(whenceStr,"SEEK_SET") == 0) {
- whence = SEEK_SET;
- } else if (strcmp(whenceStr,"SEEK_CUR") == 0) {
- whence = SEEK_CUR;
- } else if (strcmp(whenceStr,"SEEK_END") == 0) {
- whence = SEEK_END;
- } else {
- Tcl_AppendResult(interp, "the whence argument to Pg_lo_lseek must be SEEK_SET, SEEK_CUR or SEEK_END",0);
- return TCL_ERROR;
- }
-
- sprintf(interp->result,"%d",lo_lseek(conn,fd,offset,whence));
- return TCL_OK;
+ if (argc != 5)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ "pg_lo_lseek conn fd offset whence", 0);
+ return TCL_ERROR;
+ }
+
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
+
+ fd = atoi(argv[2]);
+
+ offset = atoi(argv[3]);
+
+ whenceStr = argv[4];
+ if (strcmp(whenceStr, "SEEK_SET") == 0)
+ {
+ whence = SEEK_SET;
+ }
+ else if (strcmp(whenceStr, "SEEK_CUR") == 0)
+ {
+ whence = SEEK_CUR;
+ }
+ else if (strcmp(whenceStr, "SEEK_END") == 0)
+ {
+ whence = SEEK_END;
+ }
+ else
+ {
+ Tcl_AppendResult(interp, "the whence argument to Pg_lo_lseek must be SEEK_SET, SEEK_CUR or SEEK_END", 0);
+ return TCL_ERROR;
+ }
+
+ sprintf(interp->result, "%d", lo_lseek(conn, fd, offset, whence));
+ return TCL_OK;
}
@@ -896,97 +1004,116 @@ for now, we don't support any additional storage managers.
***********************************/
int
-Pg_lo_creat(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_lo_creat(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- char *modeStr;
- char *modeWord;
- int mode;
-
- if (argc != 3) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_lo_creat conn mode", 0);
- return TCL_ERROR;
- }
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ char *modeStr;
+ char *modeWord;
+ int mode;
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- modeStr = argv[2];
-
- modeWord = strtok(modeStr,"|");
- if (strcmp(modeWord,"INV_READ") == 0) {
- mode = INV_READ;
- } else if (strcmp(modeWord,"INV_WRITE") == 0) {
- mode = INV_WRITE;
- } else if (strcmp(modeWord,"INV_ARCHIVE") == 0) {
- mode = INV_ARCHIVE;
- } else {
- Tcl_AppendResult(interp,
- "invalid mode argument to Pg_lo_creat\nmode argument must be some OR'd combination of INV_READ, INV_WRITE, and INV_ARCHIVE",
- 0);
- return TCL_ERROR;
- }
-
- while ( (modeWord = strtok((char*)NULL, "|")) != NULL) {
- if (strcmp(modeWord,"INV_READ") == 0) {
- mode |= INV_READ;
- } else if (strcmp(modeWord,"INV_WRITE") == 0) {
- mode |= INV_WRITE;
- } else if (strcmp(modeWord,"INV_ARCHIVE") == 0) {
- mode |= INV_ARCHIVE;
- } else {
- Tcl_AppendResult(interp,
- "invalid mode argument to Pg_lo_creat\nmode argument must be some OR'd combination of INV_READ, INV_WRITE, and INV_ARCHIVE",
- 0);
- return TCL_ERROR;
- }
- }
- sprintf(interp->result,"%d",lo_creat(conn,mode));
- return TCL_OK;
+ if (argc != 3)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ "pg_lo_creat conn mode", 0);
+ return TCL_ERROR;
+ }
+
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
+
+ modeStr = argv[2];
+
+ modeWord = strtok(modeStr, "|");
+ if (strcmp(modeWord, "INV_READ") == 0)
+ {
+ mode = INV_READ;
+ }
+ else if (strcmp(modeWord, "INV_WRITE") == 0)
+ {
+ mode = INV_WRITE;
+ }
+ else if (strcmp(modeWord, "INV_ARCHIVE") == 0)
+ {
+ mode = INV_ARCHIVE;
+ }
+ else
+ {
+ Tcl_AppendResult(interp,
+ "invalid mode argument to Pg_lo_creat\nmode argument must be some OR'd combination of INV_READ, INV_WRITE, and INV_ARCHIVE",
+ 0);
+ return TCL_ERROR;
+ }
+
+ while ((modeWord = strtok((char *) NULL, "|")) != NULL)
+ {
+ if (strcmp(modeWord, "INV_READ") == 0)
+ {
+ mode |= INV_READ;
+ }
+ else if (strcmp(modeWord, "INV_WRITE") == 0)
+ {
+ mode |= INV_WRITE;
+ }
+ else if (strcmp(modeWord, "INV_ARCHIVE") == 0)
+ {
+ mode |= INV_ARCHIVE;
+ }
+ else
+ {
+ Tcl_AppendResult(interp,
+ "invalid mode argument to Pg_lo_creat\nmode argument must be some OR'd combination of INV_READ, INV_WRITE, and INV_ARCHIVE",
+ 0);
+ return TCL_ERROR;
+ }
+ }
+ sprintf(interp->result, "%d", lo_creat(conn, mode));
+ return TCL_OK;
}
/***********************************
Pg_lo_tell
- returns the current seek location of the large object
+ returns the current seek location of the large object
syntax:
pg_lo_tell conn fd
***********************************/
int
-Pg_lo_tell(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_lo_tell(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- int fd;
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ int fd;
- if (argc != 3) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_lo_tell conn fd", 0);
- return TCL_ERROR;
- }
+ if (argc != 3)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ "pg_lo_tell conn fd", 0);
+ return TCL_ERROR;
+ }
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- fd = atoi(argv[2]);
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
- sprintf(interp->result,"%d",lo_tell(conn,fd));
- return TCL_OK;
+ fd = atoi(argv[2]);
+
+ sprintf(interp->result, "%d", lo_tell(conn, fd));
+ return TCL_OK;
}
/***********************************
Pg_lo_unlink
- unlink a file based on lobject id
+ unlink a file based on lobject id
syntax:
pg_lo_unlink conn lobjId
@@ -994,40 +1121,43 @@ Pg_lo_unlink
***********************************/
int
-Pg_lo_unlink(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_lo_unlink(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- int lobjId;
- int retval;
-
- if (argc != 3) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_lo_tell conn fd", 0);
- return TCL_ERROR;
- }
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ int lobjId;
+ int retval;
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- lobjId = atoi(argv[2]);
+ if (argc != 3)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ "pg_lo_tell conn fd", 0);
+ return TCL_ERROR;
+ }
- retval = lo_unlink(conn,lobjId);
- if (retval == -1) {
- sprintf(interp->result,"Pg_lo_unlink of '%d' failed",lobjId);
- return TCL_ERROR;
- }
-
- sprintf(interp->result,"%d",retval);
- return TCL_OK;
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
+
+ lobjId = atoi(argv[2]);
+
+ retval = lo_unlink(conn, lobjId);
+ if (retval == -1)
+ {
+ sprintf(interp->result, "Pg_lo_unlink of '%d' failed", lobjId);
+ return TCL_ERROR;
+ }
+
+ sprintf(interp->result, "%d", retval);
+ return TCL_OK;
}
/***********************************
Pg_lo_import
- import a Unix file into an (inversion) large objct
+ import a Unix file into an (inversion) large objct
returns the oid of that object upon success
returns InvalidOid upon failure
@@ -1037,81 +1167,87 @@ Pg_lo_import
***********************************/
int
-Pg_lo_import(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_lo_import(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- char* filename;
- Oid lobjId;
-
- if (argc != 3) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_lo_import conn filename", 0);
- return TCL_ERROR;
- }
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ char *filename;
+ Oid lobjId;
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- filename = argv[2];
+ if (argc != 3)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ "pg_lo_import conn filename", 0);
+ return TCL_ERROR;
+ }
- lobjId = lo_import(conn,filename);
- if (lobjId == InvalidOid) {
- sprintf(interp->result, "Pg_lo_import of '%s' failed",filename);
- return TCL_ERROR;
- }
- sprintf(interp->result,"%d",lobjId);
- return TCL_OK;
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
+
+ filename = argv[2];
+
+ lobjId = lo_import(conn, filename);
+ if (lobjId == InvalidOid)
+ {
+ sprintf(interp->result, "Pg_lo_import of '%s' failed", filename);
+ return TCL_ERROR;
+ }
+ sprintf(interp->result, "%d", lobjId);
+ return TCL_OK;
}
/***********************************
Pg_lo_export
- export an Inversion large object to a Unix file
-
+ export an Inversion large object to a Unix file
+
syntax:
pg_lo_export conn lobjId filename
***********************************/
int
-Pg_lo_export(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_lo_export(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- char* filename;
- Oid lobjId;
- int retval;
-
- if (argc != 4) {
- Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_lo_export conn lobjId filename", 0);
- return TCL_ERROR;
- }
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ char *filename;
+ Oid lobjId;
+ int retval;
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- lobjId = atoi(argv[2]);
- filename = argv[3];
-
- retval = lo_export(conn,lobjId,filename);
- if (retval == -1) {
- sprintf(interp->result, "Pg_lo_export %d %s failed",lobjId, filename);
- return TCL_ERROR;
- }
- return TCL_OK;
+ if (argc != 4)
+ {
+ Tcl_AppendResult(interp, "Wrong # of arguments\n",
+ "pg_lo_export conn lobjId filename", 0);
+ return TCL_ERROR;
+ }
+
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
+
+ lobjId = atoi(argv[2]);
+ filename = argv[3];
+
+ retval = lo_export(conn, lobjId, filename);
+ if (retval == -1)
+ {
+ sprintf(interp->result, "Pg_lo_export %d %s failed", lobjId, filename);
+ return TCL_ERROR;
+ }
+ return TCL_OK;
}
/**********************************
* pg_select
send a select query string to the backend connection
-
+
syntax:
pg_select connection query var proc
@@ -1121,7 +1257,7 @@ Pg_lo_export(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
Originally I was also going to update changes but that has turned out
to be not so simple. Instead, the caller should get the OID of any
- table they want to update and update it themself in the loop. I may
+ table they want to update and update it themself in the loop. I may
try to write a simplified table lookup and update function to make
that task a little easier.
@@ -1130,41 +1266,45 @@ Pg_lo_export(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
**********************************/
int
-Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
+Pg_select(ClientData cData, Tcl_Interp * interp, int argc, char **argv)
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- PGconn *conn;
- PGresult *result;
- int r;
- size_t tupno, column, ncols;
- Tcl_DString headers;
- char buffer[2048];
- struct {
- char *cname;
- int change;
- } *info;
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ PGconn *conn;
+ PGresult *result;
+ int r;
+ size_t tupno,
+ column,
+ ncols;
+ Tcl_DString headers;
+ char buffer[2048];
+ struct
+ {
+ char *cname;
+ int change;
+ } *info;
if (argc != 5)
{
Tcl_AppendResult(interp, "Wrong # of arguments\n",
- "pg_select connection queryString var proc", 0);
+ "pg_select connection queryString var proc", 0);
+ return TCL_ERROR;
+ }
+
+ conn = PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR;
}
- conn = PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
if ((result = PQexec(conn, argv[2])) == 0)
- {
+ {
/* error occurred during the query */
Tcl_SetResult(interp, conn->errorMessage, TCL_STATIC);
return TCL_ERROR;
- }
+ }
- if ((info = malloc(sizeof(*info) * (ncols = PQnfields(result)))) == NULL)
+ if ((info = malloc(sizeof(*info) * (ncols = PQnfields(result)))) == NULL)
{
Tcl_AppendResult(interp, "Not enough memory", 0);
return TCL_ERROR;
@@ -1203,10 +1343,10 @@ Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
if (r == TCL_ERROR)
{
- char msg[60];
+ char msg[60];
sprintf(msg, "\n (\"pg_select\" body line %d)",
- interp->errorLine);
+ interp->errorLine);
Tcl_AddErrorInfo(interp, msg);
}
@@ -1221,142 +1361,160 @@ Pg_select(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
}
int
-Pg_listen(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_listen(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- int new;
- char *relname;
- char *callback = NULL;
- Tcl_HashEntry *entry;
- PGconn *conn;
- PGresult *result;
-
- if ((argc < 3) || (argc > 4)) {
- Tcl_AppendResult(interp, "wrong # args, should be \"",
- argv[0], " connection relname ?callback?\"", 0);
- return TCL_ERROR;
- }
-
- /*
- * Get the command arguments. Note that relname will copied by
- * Tcl_CreateHashEntry while callback must be allocated.
- */
- conn = (PGconn*)PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
- relname = argv[2];
- if ((argc > 3) && *argv[3]) {
- callback = (char *) ckalloc((unsigned) (strlen(argv[3])+1));
- strcpy(callback, argv[3]);
- }
-
- /*
- * Set or update a callback for a relation;
- */
- if (callback) {
- entry = Tcl_CreateHashEntry(&(cd->notify_hash), relname, &new);
- if (new) {
- /* New callback, execute a listen command on the relation */
- char *cmd = (char *) ckalloc((unsigned) (strlen(argv[2])+8));
- sprintf(cmd, "LISTEN %s", relname);
- result = PQexec(conn, cmd);
- ckfree(cmd);
- if (!result || (result->resultStatus != PGRES_COMMAND_OK)) {
- /* Error occurred during the execution of command */
- if (result) PQclear(result);
- ckfree(callback);
- Tcl_DeleteHashEntry(entry);
- Tcl_SetResult(interp, conn->errorMessage, TCL_STATIC);
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ int new;
+ char *relname;
+ char *callback = NULL;
+ Tcl_HashEntry *entry;
+ PGconn *conn;
+ PGresult *result;
+
+ if ((argc < 3) || (argc > 4))
+ {
+ Tcl_AppendResult(interp, "wrong # args, should be \"",
+ argv[0], " connection relname ?callback?\"", 0);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Get the command arguments. Note that relname will copied by
+ * Tcl_CreateHashEntry while callback must be allocated.
+ */
+ conn = (PGconn *) PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
return TCL_ERROR;
- }
- PQclear(result);
- } else {
- /* Free the old callback string */
- ckfree((char *) Tcl_GetHashValue(entry));
- }
- /* Store the new callback command */
- Tcl_SetHashValue(entry, callback);
- }
-
- /*
- * Remove a callback for a relation. There is no way to
- * un-listen a relation, simply remove the callback from
- * the notify hash table.
- */
- if (callback == NULL) {
- entry = Tcl_FindHashEntry(&(cd->notify_hash), relname);
- if (entry == NULL) {
- Tcl_AppendResult(interp, "not listening on ", relname, 0);
- return TCL_ERROR;
- }
- ckfree((char *) Tcl_GetHashValue(entry));
- Tcl_DeleteHashEntry(entry);
- }
-
- return TCL_OK;
+ }
+ relname = argv[2];
+ if ((argc > 3) && *argv[3])
+ {
+ callback = (char *) ckalloc((unsigned) (strlen(argv[3]) + 1));
+ strcpy(callback, argv[3]);
+ }
+
+ /*
+ * Set or update a callback for a relation;
+ */
+ if (callback)
+ {
+ entry = Tcl_CreateHashEntry(&(cd->notify_hash), relname, &new);
+ if (new)
+ {
+ /* New callback, execute a listen command on the relation */
+ char *cmd = (char *) ckalloc((unsigned) (strlen(argv[2]) + 8));
+
+ sprintf(cmd, "LISTEN %s", relname);
+ result = PQexec(conn, cmd);
+ ckfree(cmd);
+ if (!result || (result->resultStatus != PGRES_COMMAND_OK))
+ {
+ /* Error occurred during the execution of command */
+ if (result)
+ PQclear(result);
+ ckfree(callback);
+ Tcl_DeleteHashEntry(entry);
+ Tcl_SetResult(interp, conn->errorMessage, TCL_STATIC);
+ return TCL_ERROR;
+ }
+ PQclear(result);
+ }
+ else
+ {
+ /* Free the old callback string */
+ ckfree((char *) Tcl_GetHashValue(entry));
+ }
+ /* Store the new callback command */
+ Tcl_SetHashValue(entry, callback);
+ }
+
+ /*
+ * Remove a callback for a relation. There is no way to un-listen a
+ * relation, simply remove the callback from the notify hash table.
+ */
+ if (callback == NULL)
+ {
+ entry = Tcl_FindHashEntry(&(cd->notify_hash), relname);
+ if (entry == NULL)
+ {
+ Tcl_AppendResult(interp, "not listening on ", relname, 0);
+ return TCL_ERROR;
+ }
+ ckfree((char *) Tcl_GetHashValue(entry));
+ Tcl_DeleteHashEntry(entry);
+ }
+
+ return TCL_OK;
}
int
-Pg_notifies(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
+Pg_notifies(ClientData cData, Tcl_Interp * interp, int argc, char *argv[])
{
- Pg_clientData *cd = (Pg_clientData *)cData;
- int count;
- char buff[12];
- char *callback;
- Tcl_HashEntry *entry;
- PGconn *conn;
- PGresult *result;
- PGnotify *notify;
-
- if (argc != 2) {
- Tcl_AppendResult(interp, "wrong # args, should be \"",
- argv[0], " connection\"", 0);
- return TCL_ERROR;
- }
-
- /*
- * Get the connection argument.
- */
- conn = (PGconn*)PgGetConnectionId(cd, argv[1]);
- if (conn == (PGconn *)NULL) {
- Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
- return TCL_ERROR;
- }
-
- /* Execute an empty command to retrieve asynchronous notifications */
- result = PQexec(conn, " ");
- if (result == NULL) {
- /* Error occurred during the execution of command */
- Tcl_SetResult(interp, conn->errorMessage, TCL_STATIC);
- return TCL_ERROR;
- }
- PQclear(result);
-
- /*
- * Loop while there are pending notifies.
- */
- for (count=0; count < 999; count++) {
- /* See if there is a pending notification */
- notify = PQnotifies(conn);
- if (notify == NULL) {
- break;
- }
- entry = Tcl_FindHashEntry(&(cd->notify_hash), notify->relname);
- if (entry != NULL) {
- callback = Tcl_GetHashValue(entry);
- if (callback) {
- Tcl_Eval(interp, callback);
- }
- }
- free(notify);
- }
-
- /*
- * Return the number of notifications processed.
- */
- sprintf(buff, "%d", count);
- Tcl_SetResult(interp, buff, TCL_VOLATILE);
- return TCL_OK;
+ Pg_clientData *cd = (Pg_clientData *) cData;
+ int count;
+ char buff[12];
+ char *callback;
+ Tcl_HashEntry *entry;
+ PGconn *conn;
+ PGresult *result;
+ PGnotify *notify;
+
+ if (argc != 2)
+ {
+ Tcl_AppendResult(interp, "wrong # args, should be \"",
+ argv[0], " connection\"", 0);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Get the connection argument.
+ */
+ conn = (PGconn *) PgGetConnectionId(cd, argv[1]);
+ if (conn == (PGconn *) NULL)
+ {
+ Tcl_AppendResult(interp, "First argument is not a valid connection\n", 0);
+ return TCL_ERROR;
+ }
+
+ /* Execute an empty command to retrieve asynchronous notifications */
+ result = PQexec(conn, " ");
+ if (result == NULL)
+ {
+ /* Error occurred during the execution of command */
+ Tcl_SetResult(interp, conn->errorMessage, TCL_STATIC);
+ return TCL_ERROR;
+ }
+ PQclear(result);
+
+ /*
+ * Loop while there are pending notifies.
+ */
+ for (count = 0; count < 999; count++)
+ {
+ /* See if there is a pending notification */
+ notify = PQnotifies(conn);
+ if (notify == NULL)
+ {
+ break;
+ }
+ entry = Tcl_FindHashEntry(&(cd->notify_hash), notify->relname);
+ if (entry != NULL)
+ {
+ callback = Tcl_GetHashValue(entry);
+ if (callback)
+ {
+ Tcl_Eval(interp, callback);
+ }
+ }
+ free(notify);
+ }
+
+ /*
+ * Return the number of notifications processed.
+ */
+ sprintf(buff, "%d", count);
+ Tcl_SetResult(interp, buff, TCL_VOLATILE);
+ return TCL_OK;
}
diff --git a/src/interfaces/libpgtcl/pgtclCmds.h b/src/interfaces/libpgtcl/pgtclCmds.h
index de69ad2e14c..f1e5755641f 100644
--- a/src/interfaces/libpgtcl/pgtclCmds.h
+++ b/src/interfaces/libpgtcl/pgtclCmds.h
@@ -1,11 +1,11 @@
/*-------------------------------------------------------------------------
*
* pgtclCmds.h--
- * declarations for the C functions which implement pg_* tcl commands
+ * declarations for the C functions which implement pg_* tcl commands
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pgtclCmds.h,v 1.6 1997/01/03 18:48:31 scrappy Exp $
+ * $Id: pgtclCmds.h,v 1.7 1997/09/07 05:03:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,69 +18,89 @@
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
-typedef struct Pg_clientData_s {
- Tcl_HashTable dbh_hash;
- Tcl_HashTable res_hash;
- Tcl_HashTable notify_hash;
- long dbh_count;
- long res_count;
-} Pg_clientData;
+typedef struct Pg_clientData_s
+{
+ Tcl_HashTable dbh_hash;
+ Tcl_HashTable res_hash;
+ Tcl_HashTable notify_hash;
+ long dbh_count;
+ long res_count;
+} Pg_clientData;
-typedef struct Pg_ConnectionId_s {
- char id[32];
- PGconn *conn;
- Tcl_HashTable res_hash;
-} Pg_ConnectionId;
+typedef struct Pg_ConnectionId_s
+{
+ char id[32];
+ PGconn *conn;
+ Tcl_HashTable res_hash;
+} Pg_ConnectionId;
-typedef struct Pg_ResultId_s {
- char id[32];
- PGresult *result;
- Pg_ConnectionId *connection;
-} Pg_ResultId;
+typedef struct Pg_ResultId_s
+{
+ char id[32];
+ PGresult *result;
+ Pg_ConnectionId *connection;
+} Pg_ResultId;
/* **************************/
/* registered Tcl functions */
/* **************************/
-extern int Pg_conndefaults(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_connect(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_disconnect(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_exec(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_select(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_result(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_lo_open(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_lo_close(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_lo_read(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_lo_write(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_lo_lseek(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_lo_creat(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_lo_tell(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_lo_unlink(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_lo_import(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_lo_export(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_listen(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
-extern int Pg_notifies(
- ClientData cData, Tcl_Interp *interp, int argc, char* argv[]);
+extern int
+Pg_conndefaults(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_connect(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_disconnect(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_exec(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_select(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_result(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_lo_open(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_lo_close(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_lo_read(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_lo_write(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_lo_lseek(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_lo_creat(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_lo_tell(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_lo_unlink(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_lo_import(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_lo_export(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_listen(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
+extern int
+Pg_notifies(
+ ClientData cData, Tcl_Interp * interp, int argc, char *argv[]);
-#endif /*PGTCLCMDS_H*/
-
+#endif /* PGTCLCMDS_H */
diff --git a/src/interfaces/libpgtcl/pgtclId.c b/src/interfaces/libpgtcl/pgtclId.c
index f39342c002e..d6265974b43 100644
--- a/src/interfaces/libpgtcl/pgtclId.c
+++ b/src/interfaces/libpgtcl/pgtclId.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* pgtclId.c--
- * useful routines to convert between strings and pointers
- * Needed because everything in tcl is a string, but we want pointers
- * to data structures
+ * useful routines to convert between strings and pointers
+ * Needed because everything in tcl is a string, but we want pointers
+ * to data structures
*
- * ASSUMPTION: sizeof(long) >= sizeof(void*)
+ * ASSUMPTION: sizeof(long) >= sizeof(void*)
*
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.3 1996/11/11 12:14:45 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.4 1997/09/07 05:03:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,39 +29,40 @@
* Create the Id for a new connection and hash it
*/
void
-PgSetConnectionId(Pg_clientData *cd, char *id, PGconn *conn)
+PgSetConnectionId(Pg_clientData * cd, char *id, PGconn * conn)
{
- Tcl_HashEntry *hent;
- Pg_ConnectionId *connid;
- int hnew;
-
- connid = (Pg_ConnectionId *)ckalloc(sizeof(Pg_ConnectionId));
- connid->conn = conn;
- Tcl_InitHashTable(&(connid->res_hash), TCL_STRING_KEYS);
- sprintf(connid->id, "pgc%ld", cd->dbh_count++);
- strcpy(id, connid->id);
-
- hent = Tcl_CreateHashEntry(&(cd->dbh_hash), connid->id, &hnew);
- Tcl_SetHashValue(hent, (ClientData)connid);
+ Tcl_HashEntry *hent;
+ Pg_ConnectionId *connid;
+ int hnew;
+
+ connid = (Pg_ConnectionId *) ckalloc(sizeof(Pg_ConnectionId));
+ connid->conn = conn;
+ Tcl_InitHashTable(&(connid->res_hash), TCL_STRING_KEYS);
+ sprintf(connid->id, "pgc%ld", cd->dbh_count++);
+ strcpy(id, connid->id);
+
+ hent = Tcl_CreateHashEntry(&(cd->dbh_hash), connid->id, &hnew);
+ Tcl_SetHashValue(hent, (ClientData) connid);
}
/*
* Get back the connection from the Id
*/
-PGconn *
-PgGetConnectionId(Pg_clientData *cd, char *id)
+PGconn *
+PgGetConnectionId(Pg_clientData * cd, char *id)
{
- Tcl_HashEntry *hent;
- Pg_ConnectionId *connid;
+ Tcl_HashEntry *hent;
+ Pg_ConnectionId *connid;
- hent = Tcl_FindHashEntry(&(cd->dbh_hash), id);
- if(hent == NULL) {
- return (PGconn *)NULL;
- }
+ hent = Tcl_FindHashEntry(&(cd->dbh_hash), id);
+ if (hent == NULL)
+ {
+ return (PGconn *) NULL;
+ }
- connid = (Pg_ConnectionId *)Tcl_GetHashValue(hent);
- return connid->conn;
+ connid = (Pg_ConnectionId *) Tcl_GetHashValue(hent);
+ return connid->conn;
}
@@ -70,36 +71,39 @@ PgGetConnectionId(Pg_clientData *cd, char *id)
* close all portals the user forgot.
*/
void
-PgDelConnectionId(Pg_clientData *cd, char *id)
+PgDelConnectionId(Pg_clientData * cd, char *id)
{
- Tcl_HashEntry *hent;
- Tcl_HashEntry *hent2;
- Tcl_HashEntry *hent3;
- Tcl_HashSearch hsearch;
- Pg_ConnectionId *connid;
- Pg_ResultId *resid;
-
- hent = Tcl_FindHashEntry(&(cd->dbh_hash), id);
- if(hent == NULL) {
- return;
- }
-
- connid = (Pg_ConnectionId *)Tcl_GetHashValue(hent);
-
- hent2 = Tcl_FirstHashEntry(&(connid->res_hash), &hsearch);
- while(hent2 != NULL) {
- resid = (Pg_ResultId *)Tcl_GetHashValue(hent2);
- PQclear(resid->result);
- hent3 = Tcl_FindHashEntry(&(cd->res_hash), resid->id);
- if(hent3 != NULL) {
- Tcl_DeleteHashEntry(hent3);
+ Tcl_HashEntry *hent;
+ Tcl_HashEntry *hent2;
+ Tcl_HashEntry *hent3;
+ Tcl_HashSearch hsearch;
+ Pg_ConnectionId *connid;
+ Pg_ResultId *resid;
+
+ hent = Tcl_FindHashEntry(&(cd->dbh_hash), id);
+ if (hent == NULL)
+ {
+ return;
}
- ckfree(resid);
- hent2 = Tcl_NextHashEntry(&hsearch);
- }
- Tcl_DeleteHashTable(&(connid->res_hash));
- Tcl_DeleteHashEntry(hent);
- ckfree(connid);
+
+ connid = (Pg_ConnectionId *) Tcl_GetHashValue(hent);
+
+ hent2 = Tcl_FirstHashEntry(&(connid->res_hash), &hsearch);
+ while (hent2 != NULL)
+ {
+ resid = (Pg_ResultId *) Tcl_GetHashValue(hent2);
+ PQclear(resid->result);
+ hent3 = Tcl_FindHashEntry(&(cd->res_hash), resid->id);
+ if (hent3 != NULL)
+ {
+ Tcl_DeleteHashEntry(hent3);
+ }
+ ckfree(resid);
+ hent2 = Tcl_NextHashEntry(&hsearch);
+ }
+ Tcl_DeleteHashTable(&(connid->res_hash));
+ Tcl_DeleteHashEntry(hent);
+ ckfree(connid);
}
@@ -107,52 +111,57 @@ PgDelConnectionId(Pg_clientData *cd, char *id)
* Create a new result Id and hash it
*/
void
-PgSetResultId(Pg_clientData *cd, char *id, char *connid_c, PGresult *res)
+PgSetResultId(Pg_clientData * cd, char *id, char *connid_c, PGresult * res)
{
- Tcl_HashEntry *hent;
- Pg_ConnectionId *connid;
- Pg_ResultId *resid;
- int hnew;
-
- hent = Tcl_FindHashEntry(&(cd->dbh_hash), connid_c);
- if(hent == NULL) {
- connid = NULL;
- } else {
- connid = (Pg_ConnectionId *)Tcl_GetHashValue(hent);
- }
-
- resid = (Pg_ResultId *)ckalloc(sizeof(Pg_ResultId));
- resid->result = res;
- resid->connection = connid;
- sprintf(resid->id, "pgr%ld", cd->res_count++);
- strcpy(id, resid->id);
-
- hent = Tcl_CreateHashEntry(&(cd->res_hash), resid->id, &hnew);
- Tcl_SetHashValue(hent, (ClientData)resid);
-
- if(connid != NULL) {
- hent = Tcl_CreateHashEntry(&(connid->res_hash), resid->id, &hnew);
- Tcl_SetHashValue(hent, (ClientData)resid);
- }
+ Tcl_HashEntry *hent;
+ Pg_ConnectionId *connid;
+ Pg_ResultId *resid;
+ int hnew;
+
+ hent = Tcl_FindHashEntry(&(cd->dbh_hash), connid_c);
+ if (hent == NULL)
+ {
+ connid = NULL;
+ }
+ else
+ {
+ connid = (Pg_ConnectionId *) Tcl_GetHashValue(hent);
+ }
+
+ resid = (Pg_ResultId *) ckalloc(sizeof(Pg_ResultId));
+ resid->result = res;
+ resid->connection = connid;
+ sprintf(resid->id, "pgr%ld", cd->res_count++);
+ strcpy(id, resid->id);
+
+ hent = Tcl_CreateHashEntry(&(cd->res_hash), resid->id, &hnew);
+ Tcl_SetHashValue(hent, (ClientData) resid);
+
+ if (connid != NULL)
+ {
+ hent = Tcl_CreateHashEntry(&(connid->res_hash), resid->id, &hnew);
+ Tcl_SetHashValue(hent, (ClientData) resid);
+ }
}
/*
* Get back the result pointer from the Id
*/
-PGresult *
-PgGetResultId(Pg_clientData *cd, char *id)
+PGresult *
+PgGetResultId(Pg_clientData * cd, char *id)
{
- Tcl_HashEntry *hent;
- Pg_ResultId *resid;
+ Tcl_HashEntry *hent;
+ Pg_ResultId *resid;
- hent = Tcl_FindHashEntry(&(cd->res_hash), id);
- if(hent == NULL) {
- return (PGresult *)NULL;
- }
+ hent = Tcl_FindHashEntry(&(cd->res_hash), id);
+ if (hent == NULL)
+ {
+ return (PGresult *) NULL;
+ }
- resid = (Pg_ResultId *)Tcl_GetHashValue(hent);
- return resid->result;
+ resid = (Pg_ResultId *) Tcl_GetHashValue(hent);
+ return resid->result;
}
@@ -160,27 +169,30 @@ PgGetResultId(Pg_clientData *cd, char *id)
* Remove a result Id from the hash tables
*/
void
-PgDelResultId(Pg_clientData *cd, char *id)
+PgDelResultId(Pg_clientData * cd, char *id)
{
- Tcl_HashEntry *hent;
- Tcl_HashEntry *hent2;
- Pg_ResultId *resid;
-
- hent = Tcl_FindHashEntry(&(cd->res_hash), id);
- if(hent == NULL) {
- return;
- }
-
- resid = (Pg_ResultId *)Tcl_GetHashValue(hent);
- if (resid->connection != NULL) {
- hent2 = Tcl_FindHashEntry(&(resid->connection->res_hash), id);
- if(hent2 != NULL) {
- Tcl_DeleteHashEntry(hent2);
+ Tcl_HashEntry *hent;
+ Tcl_HashEntry *hent2;
+ Pg_ResultId *resid;
+
+ hent = Tcl_FindHashEntry(&(cd->res_hash), id);
+ if (hent == NULL)
+ {
+ return;
}
- }
- Tcl_DeleteHashEntry(hent);
- ckfree(resid);
+ resid = (Pg_ResultId *) Tcl_GetHashValue(hent);
+ if (resid->connection != NULL)
+ {
+ hent2 = Tcl_FindHashEntry(&(resid->connection->res_hash), id);
+ if (hent2 != NULL)
+ {
+ Tcl_DeleteHashEntry(hent2);
+ }
+ }
+
+ Tcl_DeleteHashEntry(hent);
+ ckfree(resid);
}
@@ -188,20 +200,20 @@ PgDelResultId(Pg_clientData *cd, char *id)
* Get the connection Id from the result Id
*/
void
-PgGetConnByResultId(Pg_clientData *cd, char *id, char *resid_c)
+PgGetConnByResultId(Pg_clientData * cd, char *id, char *resid_c)
{
- Tcl_HashEntry *hent;
- Pg_ResultId *resid;
-
- hent = Tcl_FindHashEntry(&(cd->res_hash), id);
- if(hent == NULL) {
- return;
- }
-
- resid = (Pg_ResultId *)Tcl_GetHashValue(hent);
- if (resid->connection != NULL) {
- strcpy(id, resid->connection->id);
- }
-}
+ Tcl_HashEntry *hent;
+ Pg_ResultId *resid;
+ hent = Tcl_FindHashEntry(&(cd->res_hash), id);
+ if (hent == NULL)
+ {
+ return;
+ }
+ resid = (Pg_ResultId *) Tcl_GetHashValue(hent);
+ if (resid->connection != NULL)
+ {
+ strcpy(id, resid->connection->id);
+ }
+}
diff --git a/src/interfaces/libpgtcl/pgtclId.h b/src/interfaces/libpgtcl/pgtclId.h
index 9cb431918aa..03856434d6b 100644
--- a/src/interfaces/libpgtcl/pgtclId.h
+++ b/src/interfaces/libpgtcl/pgtclId.h
@@ -1,22 +1,22 @@
/*-------------------------------------------------------------------------
*
* pgtclId.h--
- * useful routines to convert between strings and pointers
- * Needed because everything in tcl is a string, but often, pointers
- * to data structures are needed.
- *
+ * useful routines to convert between strings and pointers
+ * Needed because everything in tcl is a string, but often, pointers
+ * to data structures are needed.
+ *
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pgtclId.h,v 1.2 1996/10/30 06:18:42 scrappy Exp $
+ * $Id: pgtclId.h,v 1.3 1997/09/07 05:03:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-extern void PgSetConnectionId(Pg_clientData *cd, char *id, PGconn *conn);
-extern PGconn *PgGetConnectionId(Pg_clientData *cd, char *id);
-extern void PgDelConnectionId(Pg_clientData *cd, char *id);
-extern void PgSetResultId(Pg_clientData *cd, char *id, char *connid, PGresult *res);
-extern PGresult *PgGetResultId(Pg_clientData *cd, char *id);
-extern void PgDelResultId(Pg_clientData *cd, char *id);
-extern void PgGetConnByResultId(Pg_clientData *cd, char *id, char *resid);
+extern void PgSetConnectionId(Pg_clientData * cd, char *id, PGconn * conn);
+extern PGconn *PgGetConnectionId(Pg_clientData * cd, char *id);
+extern void PgDelConnectionId(Pg_clientData * cd, char *id);
+extern void PgSetResultId(Pg_clientData * cd, char *id, char *connid, PGresult * res);
+extern PGresult *PgGetResultId(Pg_clientData * cd, char *id);
+extern void PgDelResultId(Pg_clientData * cd, char *id);
+extern void PgGetConnByResultId(Pg_clientData * cd, char *id, char *resid);
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index d058ec8ab78..433cc65ded7 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -1,34 +1,34 @@
/*-------------------------------------------------------------------------
*
* fe-auth.c--
- * The front-end (client) authorization routines
+ * The front-end (client) authorization routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.8 1997/08/12 20:16:21 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.9 1997/09/07 05:03:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * frontend (client) routines:
- * fe_sendauth send authentication information
- * fe_getauthname get user's name according to the client side
- * of the authentication system
- * fe_setauthsvc set frontend authentication service
- * fe_getauthsvc get current frontend authentication service
+ * frontend (client) routines:
+ * fe_sendauth send authentication information
+ * fe_getauthname get user's name according to the client side
+ * of the authentication system
+ * fe_setauthsvc set frontend authentication service
+ * fe_getauthsvc get current frontend authentication service
*
*
*
*/
#include <stdio.h>
#include <string.h>
-#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
+#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
#ifndef MAXHOSTNAMELEN
-#include <netdb.h> /* for MAXHOSTNAMELEN on some */
+#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#endif
#include <unistd.h>
#include <sys/types.h>
@@ -47,12 +47,12 @@
*----------------------------------------------------------------
*/
-struct authsvc {
- char name[16]; /* service nickname (for command line) */
- MsgType msgtype; /* startup packet header type */
- int allowed; /* initially allowed (before command line
- * option parsing)?
- */
+struct authsvc
+{
+ char name[16]; /* service nickname (for command line) */
+ MsgType msgtype; /* startup packet header type */
+ int allowed; /* initially allowed (before command line
+ * option parsing)? */
};
/*
@@ -67,24 +67,24 @@ struct authsvc {
*/
static struct authsvc authsvcs[] = {
#ifdef KRB4
- { "krb4", STARTUP_KRB4_MSG, 1 },
- { "kerberos", STARTUP_KRB4_MSG, 1 },
-#endif /* KRB4 */
+ {"krb4", STARTUP_KRB4_MSG, 1},
+ {"kerberos", STARTUP_KRB4_MSG, 1},
+#endif /* KRB4 */
#ifdef KRB5
- { "krb5", STARTUP_KRB5_MSG, 1 },
- { "kerberos", STARTUP_KRB5_MSG, 1 },
-#endif /* KRB5 */
- { UNAUTHNAME, STARTUP_MSG,
+ {"krb5", STARTUP_KRB5_MSG, 1},
+ {"kerberos", STARTUP_KRB5_MSG, 1},
+#endif /* KRB5 */
+ {UNAUTHNAME, STARTUP_MSG,
#if defined(KRB4) || defined(KRB5)
- 0
-#else /* !(KRB4 || KRB5) */
- 1
-#endif /* !(KRB4 || KRB5) */
- },
- { "password", STARTUP_PASSWORD_MSG, 0 }
+ 0
+#else /* !(KRB4 || KRB5) */
+ 1
+#endif /* !(KRB4 || KRB5) */
+ },
+ {"password", STARTUP_PASSWORD_MSG, 0}
};
-static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
+static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
#ifdef KRB4
/*----------------------------------------------------------------
@@ -95,8 +95,8 @@ static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
#include "krb.h"
/* for some reason, this is not defined in krb.h ... */
-extern char *tkt_string(void);
-
+extern char *tkt_string(void);
+
/*
* pg_krb4_init -- initialization performed before any Kerberos calls are made
*
@@ -104,60 +104,63 @@ extern char *tkt_string(void);
* ticket file if we want them to see a special one. (They will open the file
* themselves.)
*/
-static void pg_krb4_init()
+static void
+pg_krb4_init()
{
- char *realm;
- static init_done = 0;
-
- if (init_done)
- return;
- init_done = 1;
-
- /*
- * If the user set PGREALM, then we use a ticket file with a special
- * name: <usual-ticket-file-name>@<PGREALM-value>
- */
- if (realm = getenv("PGREALM")) {
- char tktbuf[MAXPATHLEN];
-
- (void) sprintf(tktbuf, "%s@%s", tkt_string(), realm);
- krb_set_tkt_string(tktbuf);
- }
+ char *realm;
+ static init_done = 0;
+
+ if (init_done)
+ return;
+ init_done = 1;
+
+ /*
+ * If the user set PGREALM, then we use a ticket file with a special
+ * name: <usual-ticket-file-name>@<PGREALM-value>
+ */
+ if (realm = getenv("PGREALM"))
+ {
+ char tktbuf[MAXPATHLEN];
+
+ (void) sprintf(tktbuf, "%s@%s", tkt_string(), realm);
+ krb_set_tkt_string(tktbuf);
+ }
}
/*
* pg_krb4_authname -- returns a pointer to static space containing whatever
- * name the user has authenticated to the system
+ * name the user has authenticated to the system
*
* We obtain this information by digging around in the ticket file.
*/
-static char *
-pg_krb4_authname(char* PQerrormsg)
+static char *
+pg_krb4_authname(char *PQerrormsg)
{
- char instance[INST_SZ];
- char realm[REALM_SZ];
- int status;
- static char name[SNAME_SZ+1] = "";
-
- if (name[0])
- return(name);
-
- pg_krb4_init();
-
- name[SNAME_SZ] = '\0';
- status = krb_get_tf_fullname(tkt_string(), name, instance, realm);
- if (status != KSUCCESS) {
- (void) sprintf(PQerrormsg,
- "pg_krb4_authname: krb_get_tf_fullname: %s\n",
- krb_err_txt[status]);
- return((char *) NULL);
- }
- return(name);
+ char instance[INST_SZ];
+ char realm[REALM_SZ];
+ int status;
+ static char name[SNAME_SZ + 1] = "";
+
+ if (name[0])
+ return (name);
+
+ pg_krb4_init();
+
+ name[SNAME_SZ] = '\0';
+ status = krb_get_tf_fullname(tkt_string(), name, instance, realm);
+ if (status != KSUCCESS)
+ {
+ (void) sprintf(PQerrormsg,
+ "pg_krb4_authname: krb_get_tf_fullname: %s\n",
+ krb_err_txt[status]);
+ return ((char *) NULL);
+ }
+ return (name);
}
/*
* pg_krb4_sendauth -- client routine to send authentication information to
- * the server
+ * the server
*
* This routine does not do mutual authentication, nor does it return enough
* information to do encrypted connections. But then, if we want to do
@@ -170,48 +173,50 @@ pg_krb4_authname(char* PQerrormsg)
* (canonicalized to omit all domain suffixes).
*/
static int
-pg_krb4_sendauth(const char* PQerrormsg, int sock,
- struct sockaddr_in *laddr,
- struct sockaddr_in *raddr,
- const char *hostname)
+pg_krb4_sendauth(const char *PQerrormsg, int sock,
+ struct sockaddr_in * laddr,
+ struct sockaddr_in * raddr,
+ const char *hostname)
{
- long krbopts = 0; /* one-way authentication */
- KTEXT_ST clttkt;
- int status;
- char hostbuf[MAXHOSTNAMELEN];
- const char *realm = getenv("PGREALM"); /* NULL == current realm */
-
- if (!hostname || !(*hostname)) {
- if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
- strcpy(hostbuf, "localhost");
- hostname = hostbuf;
- }
-
- pg_krb4_init();
-
- status = krb_sendauth(krbopts,
- sock,
- &clttkt,
- PG_KRB_SRVNAM,
- hostname,
- realm,
- (u_long) 0,
- (MSG_DAT *) NULL,
- (CREDENTIALS *) NULL,
- (Key_schedule *) NULL,
- laddr,
- raddr,
- PG_KRB4_VERSION);
- if (status != KSUCCESS) {
- (void) sprintf(PQerrormsg,
- "pg_krb4_sendauth: kerberos error: %s\n",
- krb_err_txt[status]);
- return(STATUS_ERROR);
- }
- return(STATUS_OK);
+ long krbopts = 0;/* one-way authentication */
+ KTEXT_ST clttkt;
+ int status;
+ char hostbuf[MAXHOSTNAMELEN];
+ const char *realm = getenv("PGREALM"); /* NULL == current realm */
+
+ if (!hostname || !(*hostname))
+ {
+ if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
+ strcpy(hostbuf, "localhost");
+ hostname = hostbuf;
+ }
+
+ pg_krb4_init();
+
+ status = krb_sendauth(krbopts,
+ sock,
+ &clttkt,
+ PG_KRB_SRVNAM,
+ hostname,
+ realm,
+ (u_long) 0,
+ (MSG_DAT *) NULL,
+ (CREDENTIALS *) NULL,
+ (Key_schedule *) NULL,
+ laddr,
+ raddr,
+ PG_KRB4_VERSION);
+ if (status != KSUCCESS)
+ {
+ (void) sprintf(PQerrormsg,
+ "pg_krb4_sendauth: kerberos error: %s\n",
+ krb_err_txt[status]);
+ return (STATUS_ERROR);
+ }
+ return (STATUS_OK);
}
-#endif /* KRB4 */
+#endif /* KRB4 */
#ifdef KRB5
/*----------------------------------------------------------------
@@ -223,25 +228,25 @@ pg_krb4_sendauth(const char* PQerrormsg, int sock,
/*
* pg_an_to_ln -- return the local name corresponding to an authentication
- * name
+ * name
*
* XXX Assumes that the first aname component is the user name. This is NOT
- * necessarily so, since an aname can actually be something out of your
- * worst X.400 nightmare, like
- * ORGANIZATION=U. C. Berkeley/NAME=Paul M. Aoki@CS.BERKELEY.EDU
- * Note that the MIT an_to_ln code does the same thing if you don't
- * provide an aname mapping database...it may be a better idea to use
- * krb5_an_to_ln, except that it punts if multiple components are found,
- * and we can't afford to punt.
+ * necessarily so, since an aname can actually be something out of your
+ * worst X.400 nightmare, like
+ * ORGANIZATION=U. C. Berkeley/NAME=Paul M. Aoki@CS.BERKELEY.EDU
+ * Note that the MIT an_to_ln code does the same thing if you don't
+ * provide an aname mapping database...it may be a better idea to use
+ * krb5_an_to_ln, except that it punts if multiple components are found,
+ * and we can't afford to punt.
*/
-static char *
+static char *
pg_an_to_ln(const char *aname)
{
- char *p;
-
- if ((p = strchr(aname, '/')) || (p = strchr(aname, '@')))
- *p = '\0';
- return(aname);
+ char *p;
+
+ if ((p = strchr(aname, '/')) || (p = strchr(aname, '@')))
+ *p = '\0';
+ return (aname);
}
@@ -251,85 +256,92 @@ pg_an_to_ln(const char *aname)
* With v5, we can no longer set the ticket (credential cache) file name;
* we now have to provide a file handle for the open (well, "resolved")
* ticket file everywhere.
- *
+ *
*/
static int
-krb5_ccache pg_krb5_init(void)
+krb5_ccache
+pg_krb5_init(void)
{
- krb5_error_code code;
- char *realm, *defname;
- char tktbuf[MAXPATHLEN];
- static krb5_ccache ccache = (krb5_ccache) NULL;
-
- if (ccache)
- return(ccache);
-
- /*
- * If the user set PGREALM, then we use a ticket file with a special
- * name: <usual-ticket-file-name>@<PGREALM-value>
- */
- if (!(defname = krb5_cc_default_name())) {
- (void) sprintf(PQerrormsg,
- "pg_krb5_init: krb5_cc_default_name failed\n");
- return((krb5_ccache) NULL);
- }
- strcpy(tktbuf, defname);
- if (realm = getenv("PGREALM")) {
- strcat(tktbuf, "@");
- strcat(tktbuf, realm);
- }
-
- if (code = krb5_cc_resolve(tktbuf, &ccache)) {
- (void) sprintf(PQerrormsg,
- "pg_krb5_init: Kerberos error %d in krb5_cc_resolve\n",
- code);
- com_err("pg_krb5_init", code, "in krb5_cc_resolve");
- return((krb5_ccache) NULL);
- }
- return(ccache);
+ krb5_error_code code;
+ char *realm,
+ *defname;
+ char tktbuf[MAXPATHLEN];
+ static krb5_ccache ccache = (krb5_ccache) NULL;
+
+ if (ccache)
+ return (ccache);
+
+ /*
+ * If the user set PGREALM, then we use a ticket file with a special
+ * name: <usual-ticket-file-name>@<PGREALM-value>
+ */
+ if (!(defname = krb5_cc_default_name()))
+ {
+ (void) sprintf(PQerrormsg,
+ "pg_krb5_init: krb5_cc_default_name failed\n");
+ return ((krb5_ccache) NULL);
+ }
+ strcpy(tktbuf, defname);
+ if (realm = getenv("PGREALM"))
+ {
+ strcat(tktbuf, "@");
+ strcat(tktbuf, realm);
+ }
+
+ if (code = krb5_cc_resolve(tktbuf, &ccache))
+ {
+ (void) sprintf(PQerrormsg,
+ "pg_krb5_init: Kerberos error %d in krb5_cc_resolve\n",
+ code);
+ com_err("pg_krb5_init", code, "in krb5_cc_resolve");
+ return ((krb5_ccache) NULL);
+ }
+ return (ccache);
}
/*
* pg_krb5_authname -- returns a pointer to static space containing whatever
- * name the user has authenticated to the system
+ * name the user has authenticated to the system
*
* We obtain this information by digging around in the ticket file.
*/
static const char *
-pg_krb5_authname(const char* PQerrormsg)
+pg_krb5_authname(const char *PQerrormsg)
{
- krb5_ccache ccache;
- krb5_principal principal;
- krb5_error_code code;
- static char *authname = (char *) NULL;
-
- if (authname)
- return(authname);
-
- ccache = pg_krb5_init(); /* don't free this */
-
- if (code = krb5_cc_get_principal(ccache, &principal)) {
- (void) sprintf(PQerrormsg,
- "pg_krb5_authname: Kerberos error %d in krb5_cc_get_principal\n",
- code);
- com_err("pg_krb5_authname", code, "in krb5_cc_get_principal");
- return((char *) NULL);
- }
- if (code = krb5_unparse_name(principal, &authname)) {
- (void) sprintf(PQerrormsg,
- "pg_krb5_authname: Kerberos error %d in krb5_unparse_name\n",
- code);
- com_err("pg_krb5_authname", code, "in krb5_unparse_name");
+ krb5_ccache ccache;
+ krb5_principal principal;
+ krb5_error_code code;
+ static char *authname = (char *) NULL;
+
+ if (authname)
+ return (authname);
+
+ ccache = pg_krb5_init(); /* don't free this */
+
+ if (code = krb5_cc_get_principal(ccache, &principal))
+ {
+ (void) sprintf(PQerrormsg,
+ "pg_krb5_authname: Kerberos error %d in krb5_cc_get_principal\n",
+ code);
+ com_err("pg_krb5_authname", code, "in krb5_cc_get_principal");
+ return ((char *) NULL);
+ }
+ if (code = krb5_unparse_name(principal, &authname))
+ {
+ (void) sprintf(PQerrormsg,
+ "pg_krb5_authname: Kerberos error %d in krb5_unparse_name\n",
+ code);
+ com_err("pg_krb5_authname", code, "in krb5_unparse_name");
+ krb5_free_principal(principal);
+ return ((char *) NULL);
+ }
krb5_free_principal(principal);
- return((char *) NULL);
- }
- krb5_free_principal(principal);
- return(pg_an_to_ln(authname));
+ return (pg_an_to_ln(authname));
}
/*
* pg_krb5_sendauth -- client routine to send authentication information to
- * the server
+ * the server
*
* This routine does not do mutual authentication, nor does it return enough
* information to do encrypted connections. But then, if we want to do
@@ -337,159 +349,173 @@ pg_krb5_authname(const char* PQerrormsg)
* anyway.
*
* Server hostnames are canonicalized v4-style, i.e., all domain suffixes
- * are simply chopped off. Hence, we are assuming that you've entered your
+ * are simply chopped off. Hence, we are assuming that you've entered your
* server instances as
- * <value-of-PG_KRB_SRVNAM>/<canonicalized-hostname>
- * in the PGREALM (or local) database. This is probably a bad assumption.
+ * <value-of-PG_KRB_SRVNAM>/<canonicalized-hostname>
+ * in the PGREALM (or local) database. This is probably a bad assumption.
*/
static int
-pg_krb5_sendauth(const char* PQerrormsg,int sock,
- struct sockaddr_in *laddr,
- struct sockaddr_in *raddr,
- const char *hostname)
+pg_krb5_sendauth(const char *PQerrormsg, int sock,
+ struct sockaddr_in * laddr,
+ struct sockaddr_in * raddr,
+ const char *hostname)
{
- char servbuf[MAXHOSTNAMELEN + 1 +
- sizeof(PG_KRB_SRVNAM)];
- const char *hostp;
- const char *realm;
- krb5_error_code code;
- krb5_principal client, server;
- krb5_ccache ccache;
- krb5_error *error = (krb5_error *) NULL;
-
- ccache = pg_krb5_init(); /* don't free this */
-
- /*
- * set up client -- this is easy, we can get it out of the ticket
- * file.
- */
- if (code = krb5_cc_get_principal(ccache, &client)) {
- (void) sprintf(PQerrormsg,
- "pg_krb5_sendauth: Kerberos error %d in krb5_cc_get_principal\n",
- code);
- com_err("pg_krb5_sendauth", code, "in krb5_cc_get_principal");
- return(STATUS_ERROR);
- }
-
- /*
- * set up server -- canonicalize as described above
- */
- strcpy(servbuf, PG_KRB_SRVNAM);
- *(hostp = servbuf + (sizeof(PG_KRB_SRVNAM) - 1)) = '/';
- if (hostname || *hostname) {
- strncpy(++hostp, hostname, MAXHOSTNAMELEN);
- } else {
- if (gethostname(++hostp, MAXHOSTNAMELEN) < 0)
- strcpy(hostp, "localhost");
- }
- if (hostp = strchr(hostp, '.'))
- *hostp = '\0';
- if (realm = getenv("PGREALM")) {
- strcat(servbuf, "@");
- strcat(servbuf, realm);
- }
- if (code = krb5_parse_name(servbuf, &server)) {
- (void) sprintf(PQerrormsg,
- "pg_krb5_sendauth: Kerberos error %d in krb5_parse_name\n",
- code);
- com_err("pg_krb5_sendauth", code, "in krb5_parse_name");
- krb5_free_principal(client);
- return(STATUS_ERROR);
- }
-
- /*
- * The only thing we want back from krb5_sendauth is an error status
- * and any error messages.
- */
- if (code = krb5_sendauth((krb5_pointer) &sock,
- PG_KRB5_VERSION,
- client,
- server,
- (krb5_flags) 0,
- (krb5_checksum *) NULL,
- (krb5_creds *) NULL,
- ccache,
- (krb5_int32 *) NULL,
- (krb5_keyblock **) NULL,
- &error,
- (krb5_ap_rep_enc_part **) NULL)) {
- if ((code == KRB5_SENDAUTH_REJECTED) && error) {
- (void) sprintf(PQerrormsg,
- "pg_krb5_sendauth: authentication rejected: \"%*s\"\n",
- error->text.length, error->text.data);
- fputs(PQerrormsg, stderr);
- pqdebug("%s", PQerrormsg);
- } else {
- (void) sprintf(PQerrormsg,
- "pg_krb5_sendauth: Kerberos error %d in krb5_sendauth\n",
- code);
- com_err("pg_krb5_sendauth", code, "in krb5_sendauth");
+ char servbuf[MAXHOSTNAMELEN + 1 +
+ sizeof(PG_KRB_SRVNAM)];
+ const char *hostp;
+ const char *realm;
+ krb5_error_code code;
+ krb5_principal client,
+ server;
+ krb5_ccache ccache;
+ krb5_error *error = (krb5_error *) NULL;
+
+ ccache = pg_krb5_init(); /* don't free this */
+
+ /*
+ * set up client -- this is easy, we can get it out of the ticket
+ * file.
+ */
+ if (code = krb5_cc_get_principal(ccache, &client))
+ {
+ (void) sprintf(PQerrormsg,
+ "pg_krb5_sendauth: Kerberos error %d in krb5_cc_get_principal\n",
+ code);
+ com_err("pg_krb5_sendauth", code, "in krb5_cc_get_principal");
+ return (STATUS_ERROR);
+ }
+
+ /*
+ * set up server -- canonicalize as described above
+ */
+ strcpy(servbuf, PG_KRB_SRVNAM);
+ *(hostp = servbuf + (sizeof(PG_KRB_SRVNAM) - 1)) = '/';
+ if (hostname || *hostname)
+ {
+ strncpy(++hostp, hostname, MAXHOSTNAMELEN);
+ }
+ else
+ {
+ if (gethostname(++hostp, MAXHOSTNAMELEN) < 0)
+ strcpy(hostp, "localhost");
+ }
+ if (hostp = strchr(hostp, '.'))
+ *hostp = '\0';
+ if (realm = getenv("PGREALM"))
+ {
+ strcat(servbuf, "@");
+ strcat(servbuf, realm);
+ }
+ if (code = krb5_parse_name(servbuf, &server))
+ {
+ (void) sprintf(PQerrormsg,
+ "pg_krb5_sendauth: Kerberos error %d in krb5_parse_name\n",
+ code);
+ com_err("pg_krb5_sendauth", code, "in krb5_parse_name");
+ krb5_free_principal(client);
+ return (STATUS_ERROR);
+ }
+
+ /*
+ * The only thing we want back from krb5_sendauth is an error status
+ * and any error messages.
+ */
+ if (code = krb5_sendauth((krb5_pointer) & sock,
+ PG_KRB5_VERSION,
+ client,
+ server,
+ (krb5_flags) 0,
+ (krb5_checksum *) NULL,
+ (krb5_creds *) NULL,
+ ccache,
+ (krb5_int32 *) NULL,
+ (krb5_keyblock **) NULL,
+ &error,
+ (krb5_ap_rep_enc_part **) NULL))
+ {
+ if ((code == KRB5_SENDAUTH_REJECTED) && error)
+ {
+ (void) sprintf(PQerrormsg,
+ "pg_krb5_sendauth: authentication rejected: \"%*s\"\n",
+ error->text.length, error->text.data);
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ }
+ else
+ {
+ (void) sprintf(PQerrormsg,
+ "pg_krb5_sendauth: Kerberos error %d in krb5_sendauth\n",
+ code);
+ com_err("pg_krb5_sendauth", code, "in krb5_sendauth");
+ }
}
- }
- krb5_free_principal(client);
- krb5_free_principal(server);
- return(code ? STATUS_ERROR : STATUS_OK);
+ krb5_free_principal(client);
+ krb5_free_principal(server);
+ return (code ? STATUS_ERROR : STATUS_OK);
}
-#endif /* KRB5 */
+#endif /* KRB5 */
static int
-pg_password_sendauth(Port *port, const char *user, const char *password)
+pg_password_sendauth(Port * port, const char *user, const char *password)
{
- PacketBuf buf;
- char *tmp;
+ PacketBuf buf;
+ char *tmp;
- buf.len = htonl(sizeof(PacketBuf));
- buf.msgtype = STARTUP_PASSWORD_MSG;
- buf.data[0] = '\0';
+ buf.len = htonl(sizeof(PacketBuf));
+ buf.msgtype = STARTUP_PASSWORD_MSG;
+ buf.data[0] = '\0';
- tmp = buf.data;
- strncpy(tmp, user, strlen(user)+1);
- tmp += strlen(user)+1;
- strncpy(tmp, password, strlen(password)+1);
+ tmp = buf.data;
+ strncpy(tmp, user, strlen(user) + 1);
+ tmp += strlen(user) + 1;
+ strncpy(tmp, password, strlen(password) + 1);
- return packetSend(port, &buf, sizeof(PacketBuf), BLOCKING);
+ return packetSend(port, &buf, sizeof(PacketBuf), BLOCKING);
}
/*
* fe_sendauth -- client demux routine for outgoing authentication information
*/
int
-fe_sendauth(MsgType msgtype, Port *port, const char *hostname,
- const char *user, const char *password, const char* PQerrormsg)
+fe_sendauth(MsgType msgtype, Port * port, const char *hostname,
+ const char *user, const char *password, const char *PQerrormsg)
{
- switch (msgtype) {
+ switch (msgtype)
+ {
#ifdef KRB4
- case STARTUP_KRB4_MSG:
- if (pg_krb4_sendauth(PQerrormsg, port->sock, &port->laddr,
- &port->raddr,
- hostname) != STATUS_OK) {
- (void) sprintf(PQerrormsg,
- "fe_sendauth: krb4 authentication failed\n");
-/* fputs(PQerrormsg, stderr); */
- return(STATUS_ERROR);
- }
- break;
+ case STARTUP_KRB4_MSG:
+ if (pg_krb4_sendauth(PQerrormsg, port->sock, &port->laddr,
+ &port->raddr,
+ hostname) != STATUS_OK)
+ {
+ (void) sprintf(PQerrormsg,
+ "fe_sendauth: krb4 authentication failed\n");
+/* fputs(PQerrormsg, stderr); */
+ return (STATUS_ERROR);
+ }
+ break;
#endif
#ifdef KRB5
- case STARTUP_KRB5_MSG:
- if (pg_krb5_sendauth(PQerrormsg,port->sock, &port->laddr,
- &port->raddr,
- hostname) != STATUS_OK) {
- (void) sprintf(PQerrormsg,
- "fe_sendauth: krb5 authentication failed\n");
- return(STATUS_ERROR);
- }
- break;
+ case STARTUP_KRB5_MSG:
+ if (pg_krb5_sendauth(PQerrormsg, port->sock, &port->laddr,
+ &port->raddr,
+ hostname) != STATUS_OK)
+ {
+ (void) sprintf(PQerrormsg,
+ "fe_sendauth: krb5 authentication failed\n");
+ return (STATUS_ERROR);
+ }
+ break;
#endif
- case STARTUP_MSG:
- break;
- case STARTUP_PASSWORD_MSG:
- pg_password_sendauth(port, user, password);
- default:
- break;
- }
- return(STATUS_OK);
+ case STARTUP_MSG:
+ break;
+ case STARTUP_PASSWORD_MSG:
+ pg_password_sendauth(port, user, password);
+ default:
+ break;
+ }
+ return (STATUS_OK);
}
/*
@@ -499,74 +525,77 @@ fe_sendauth(MsgType msgtype, Port *port, const char *hostname,
* Set/return the authentication service currently selected for use by the
* frontend. (You can only use one in the frontend, obviously.)
*/
-static pg_authsvc = -1;
+static pg_authsvc = -1;
void
-fe_setauthsvc(const char *name, char* PQerrormsg)
+fe_setauthsvc(const char *name, char *PQerrormsg)
{
- int i;
-
- for (i = 0; i < n_authsvcs; ++i)
- if (!strcmp(name, authsvcs[i].name)) {
- pg_authsvc = i;
- break;
+ int i;
+
+ for (i = 0; i < n_authsvcs; ++i)
+ if (!strcmp(name, authsvcs[i].name))
+ {
+ pg_authsvc = i;
+ break;
+ }
+ if (i == n_authsvcs)
+ {
+ (void) sprintf(PQerrormsg,
+ "fe_setauthsvc: invalid name: %s, ignoring...\n",
+ name);
}
- if (i == n_authsvcs) {
- (void) sprintf(PQerrormsg,
- "fe_setauthsvc: invalid name: %s, ignoring...\n",
- name);
- }
- return;
+ return;
}
MsgType
-fe_getauthsvc(char* PQerrormsg)
+fe_getauthsvc(char *PQerrormsg)
{
- if (pg_authsvc < 0 || pg_authsvc >= n_authsvcs)
- fe_setauthsvc(DEFAULT_CLIENT_AUTHSVC,PQerrormsg);
- return(authsvcs[pg_authsvc].msgtype);
+ if (pg_authsvc < 0 || pg_authsvc >= n_authsvcs)
+ fe_setauthsvc(DEFAULT_CLIENT_AUTHSVC, PQerrormsg);
+ return (authsvcs[pg_authsvc].msgtype);
}
/*
* fe_getauthname -- returns a pointer to dynamic space containing whatever
- * name the user has authenticated to the system
+ * name the user has authenticated to the system
* if there is an error, return the error message in PQerrormsg
*/
-char*
-fe_getauthname(char* PQerrormsg)
+char *
+fe_getauthname(char *PQerrormsg)
{
- char *name = (char *) NULL;
- char *authn = (char *) NULL;
- MsgType authsvc;
-
- authsvc = fe_getauthsvc(PQerrormsg);
- switch ((int) authsvc) {
+ char *name = (char *) NULL;
+ char *authn = (char *) NULL;
+ MsgType authsvc;
+
+ authsvc = fe_getauthsvc(PQerrormsg);
+ switch ((int) authsvc)
+ {
#ifdef KRB4
- case STARTUP_KRB4_MSG:
- name = pg_krb4_authname(PQerrormsg);
- break;
+ case STARTUP_KRB4_MSG:
+ name = pg_krb4_authname(PQerrormsg);
+ break;
#endif
#ifdef KRB5
- case STARTUP_KRB5_MSG:
- name = pg_krb5_authname(PQerrormsg);
- break;
+ case STARTUP_KRB5_MSG:
+ name = pg_krb5_authname(PQerrormsg);
+ break;
#endif
- case STARTUP_MSG:
- {
- struct passwd *pw = getpwuid(geteuid());
- if (pw) name = pw->pw_name;
+ case STARTUP_MSG:
+ {
+ struct passwd *pw = getpwuid(geteuid());
+
+ if (pw)
+ name = pw->pw_name;
+ }
+ break;
+ default:
+ (void) sprintf(PQerrormsg,
+ "fe_getauthname: invalid authentication system: %d\n",
+ authsvc);
+ break;
}
- break;
- default:
- (void) sprintf(PQerrormsg,
- "fe_getauthname: invalid authentication system: %d\n",
- authsvc);
- break;
- }
-
- if(name && (authn = (char *) malloc(strlen(name) + 1)))
- strcpy(authn, name);
- return(authn);
-}
-
+ if (name && (authn = (char *) malloc(strlen(name) + 1)))
+ strcpy(authn, name);
+ return (authn);
+}
diff --git a/src/interfaces/libpq/fe-auth.h b/src/interfaces/libpq/fe-auth.h
index 646f93df37a..6ca83fe4e89 100644
--- a/src/interfaces/libpq/fe-auth.h
+++ b/src/interfaces/libpq/fe-auth.h
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
* fe-auth.h
- *
- * Definitions for network authentication routines
+ *
+ * Definitions for network authentication routines
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: fe-auth.h,v 1.3 1997/03/12 21:23:04 scrappy Exp $
+ * $Id: fe-auth.h,v 1.4 1997/09/07 05:03:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef FE_AUTH_H
-#define FE_AUTH_H
+#define FE_AUTH_H
/*----------------------------------------------------------------
* Common routines and definitions
@@ -19,22 +19,22 @@
*/
/* what we call "no authentication system" */
-#define UNAUTHNAME "unauth"
+#define UNAUTHNAME "unauth"
/* what a frontend uses by default */
#if !defined(KRB4) && !defined(KRB5)
-#define DEFAULT_CLIENT_AUTHSVC UNAUTHNAME
-#else /* KRB4 || KRB5 */
-#define DEFAULT_CLIENT_AUTHSVC "kerberos"
-#endif /* KRB4 || KRB5 */
-
-extern int fe_sendauth(MsgType msgtype, Port *port, const char *hostname,
- const char *user, const char *password,
- const char* PQerromsg);
-extern void fe_setauthsvc(const char *name, char* PQerrormsg);
+#define DEFAULT_CLIENT_AUTHSVC UNAUTHNAME
+#else /* KRB4 || KRB5 */
+#define DEFAULT_CLIENT_AUTHSVC "kerberos"
+#endif /* KRB4 || KRB5 */
-#define PG_KRB4_VERSION "PGVER4.1" /* at most KRB_SENDAUTH_VLEN chars */
-#define PG_KRB5_VERSION "PGVER5.1"
+extern int
+fe_sendauth(MsgType msgtype, Port * port, const char *hostname,
+ const char *user, const char *password,
+ const char *PQerromsg);
+extern void fe_setauthsvc(const char *name, char *PQerrormsg);
-#endif /* FE_AUTH_H */
+#define PG_KRB4_VERSION "PGVER4.1" /* at most KRB_SENDAUTH_VLEN chars */
+#define PG_KRB5_VERSION "PGVER5.1"
+#endif /* FE_AUTH_H */
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index cb9b10d8704..1b6a1c1243d 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* fe-connect.c--
- * functions related to setting up a connection to the backend
+ * functions related to setting up a connection to the backend
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.38 1997/09/05 00:09:43 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.39 1997/09/07 05:03:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,10 +24,11 @@
#include <netinet/tcp.h>
#include <errno.h>
#include <signal.h>
-#include <ctype.h> /* for isspace() */
+#include <ctype.h> /* for isspace() */
#include "postgres.h"
-#include "libpq/pqcomm.h" /* for decls of MsgType, PacketBuf, StartupInfo */
+#include "libpq/pqcomm.h" /* for decls of MsgType, PacketBuf,
+ * StartupInfo */
#include "fe-auth.h"
#include "fe-connect.h"
#include "libpq-fe.h"
@@ -38,14 +39,14 @@
/* use a local version instead of the one found in pqpacket.c */
-static ConnStatusType connectDB(PGconn *conn);
+static ConnStatusType connectDB(PGconn * conn);
-static void startup2PacketBuf(StartupInfo* s, PacketBuf* res);
-static void freePGconn(PGconn *conn);
-static void closePGconn(PGconn *conn);
-static int conninfo_parse(const char *conninfo, char *errorMessage);
-static char *conninfo_getval(char *keyword);
-static void conninfo_free(void);
+static void startup2PacketBuf(StartupInfo * s, PacketBuf * res);
+static void freePGconn(PGconn * conn);
+static void closePGconn(PGconn * conn);
+static int conninfo_parse(const char *conninfo, char *errorMessage);
+static char *conninfo_getval(char *keyword);
+static void conninfo_free(void);
#define NOTIFYLIST_INITIAL_SIZE 10
#define NOTIFYLIST_GROWBY 10
@@ -65,60 +66,66 @@ static void conninfo_free(void);
* The Label and Disp-Char entries are provided for applications that
* want to use PQconndefaults() to create a generic database connection
* dialog. Disp-Char is defined as follows:
- * "" Normal input field
+ * "" Normal input field
* ----------
*/
static PQconninfoOption PQconninfoOptions[] = {
-/* ----------------------------------------------------------------- */
-/* Option-name Environment-Var Compiled-in Current value */
-/* Label Disp-Char */
-/* ----------------- --------------- --------------- --------------- */
- { "authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
- "Database-Authtype", "", 20 },
+/* ----------------------------------------------------------------- */
+/* Option-name Environment-Var Compiled-in Current value */
+/* Label Disp-Char */
+/* ----------------- --------------- --------------- --------------- */
+ {"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
+ "Database-Authtype", "", 20},
- { "user", "PGUSER", NULL, NULL,
- "Database-User", "", 20 },
+ {"user", "PGUSER", NULL, NULL,
+ "Database-User", "", 20},
- { "password", "PGPASSWORD", DefaultPassword, NULL,
- "Database-Password", "", 20 },
+ {"password", "PGPASSWORD", DefaultPassword, NULL,
+ "Database-Password", "", 20},
- { "dbname", "PGDATABASE", NULL, NULL,
- "Database-Name", "", 20 },
+ {"dbname", "PGDATABASE", NULL, NULL,
+ "Database-Name", "", 20},
- { "host", "PGHOST", DefaultHost, NULL,
- "Database-Host", "", 40 },
+ {"host", "PGHOST", DefaultHost, NULL,
+ "Database-Host", "", 40},
- { "port", "PGPORT", DEF_PGPORT, NULL,
- "Database-Port", "", 6 },
+ {"port", "PGPORT", DEF_PGPORT, NULL,
+ "Database-Port", "", 6},
- { "tty", "PGTTY", DefaultTty, NULL,
- "Backend-Debug-TTY", "D", 40 },
+ {"tty", "PGTTY", DefaultTty, NULL,
+ "Backend-Debug-TTY", "D", 40},
- { "options", "PGOPTIONS", DefaultOption, NULL,
- "Backend-Debug-Options", "D", 40 },
-/* ----------------- --------------- --------------- --------------- */
- { NULL, NULL, NULL, NULL,
- NULL, NULL, 0 }
+ {"options", "PGOPTIONS", DefaultOption, NULL,
+ "Backend-Debug-Options", "D", 40},
+/* ----------------- --------------- --------------- --------------- */
+ {NULL, NULL, NULL, NULL,
+ NULL, NULL, 0}
};
struct EnvironmentOptions
+{
+ const char *envName,
+ *pgName;
+} EnvironmentOptions[] =
+
+{
{
- const char *envName, *pgName;
- } EnvironmentOptions[] =
+ "PG_DATESTYLE", "datestyle"
+ },
{
- { "PG_DATESTYLE", "datestyle" },
- { NULL }
- };
-
+ NULL
+ }
+};
+
/* ----------------
- * PQconnectdb
- *
+ * PQconnectdb
+ *
* establishes a connectin to a postgres backend through the postmaster
* using connection information in a string.
*
* The conninfo string is a list of
*
- * option = value
+ * option = value
*
* definitions. Value might be a single value containing no whitespaces
* or a single quoted string. If a single quote should appear everywhere
@@ -126,547 +133,624 @@ struct EnvironmentOptions
*
* Returns a PGconn* which is needed for all subsequent libpq calls
* if the status field of the connection returned is CONNECTION_BAD,
- * then some fields may be null'ed out instead of having valid values
+ * then some fields may be null'ed out instead of having valid values
* ----------------
*/
-PGconn*
+PGconn *
PQconnectdb(const char *conninfo)
{
- PGconn *conn;
- PQconninfoOption *option;
- char errorMessage[ERROR_MSG_LENGTH];
-
- /* ----------
- * Allocate memory for the conn structure
- * ----------
- */
- conn = (PGconn*)malloc(sizeof(PGconn));
- if (conn == NULL) {
- fprintf(stderr,
- "FATAL: PQsetdb() -- unable to allocate memory for a PGconn");
- return (PGconn*)NULL;
- }
- memset((char *)conn, 0, sizeof(PGconn));
-
- /* ----------
- * Parse the conninfo string and get the fallback resources
- * ----------
- */
- if(conninfo_parse(conninfo, errorMessage) < 0) {
- conn->status = CONNECTION_BAD;
- strcpy(conn->errorMessage, errorMessage);
- conninfo_free();
- return conn;
- }
+ PGconn *conn;
+ PQconninfoOption *option;
+ char errorMessage[ERROR_MSG_LENGTH];
- /* ----------
- * Check that we have all connection parameters
- * ----------
- */
- for(option = PQconninfoOptions; option->keyword != NULL; option++) {
- if(option->val != NULL) continue; /* Value was in conninfo */
+ /* ----------
+ * Allocate memory for the conn structure
+ * ----------
+ */
+ conn = (PGconn *) malloc(sizeof(PGconn));
+ if (conn == NULL)
+ {
+ fprintf(stderr,
+ "FATAL: PQsetdb() -- unable to allocate memory for a PGconn");
+ return (PGconn *) NULL;
+ }
+ memset((char *) conn, 0, sizeof(PGconn));
/* ----------
- * No value was found for this option. Return an error.
+ * Parse the conninfo string and get the fallback resources
* ----------
*/
- conn->status = CONNECTION_BAD;
- sprintf(conn->errorMessage,
- "ERROR: PQconnectdb(): Cannot determine a value for option '%s'.\n",
- option->keyword);
- strcat(conn->errorMessage,
- "Option not specified in conninfo string");
- if(option->environ) {
- strcat(conn->errorMessage,
- ", environment variable ");
- strcat(conn->errorMessage, option->environ);
- strcat(conn->errorMessage, "\nnot set");
+ if (conninfo_parse(conninfo, errorMessage) < 0)
+ {
+ conn->status = CONNECTION_BAD;
+ strcpy(conn->errorMessage, errorMessage);
+ conninfo_free();
+ return conn;
}
- strcat(conn->errorMessage, " and no compiled in default value.\n");
+
+ /* ----------
+ * Check that we have all connection parameters
+ * ----------
+ */
+ for (option = PQconninfoOptions; option->keyword != NULL; option++)
+ {
+ if (option->val != NULL)
+ continue; /* Value was in conninfo */
+
+ /* ----------
+ * No value was found for this option. Return an error.
+ * ----------
+ */
+ conn->status = CONNECTION_BAD;
+ sprintf(conn->errorMessage,
+ "ERROR: PQconnectdb(): Cannot determine a value for option '%s'.\n",
+ option->keyword);
+ strcat(conn->errorMessage,
+ "Option not specified in conninfo string");
+ if (option->environ)
+ {
+ strcat(conn->errorMessage,
+ ", environment variable ");
+ strcat(conn->errorMessage, option->environ);
+ strcat(conn->errorMessage, "\nnot set");
+ }
+ strcat(conn->errorMessage, " and no compiled in default value.\n");
+ conninfo_free();
+ return conn;
+ }
+
+ /* ----------
+ * Setup the conn structure
+ * ----------
+ */
+ conn->lobjfuncs = (PGlobjfuncs *) NULL;
+ conn->Pfout = NULL;
+ conn->Pfin = NULL;
+ conn->Pfdebug = NULL;
+ conn->port = NULL;
+ conn->notifyList = DLNewList();
+
+ conn->pghost = strdup(conninfo_getval("host"));
+ conn->pgport = strdup(conninfo_getval("port"));
+ conn->pgtty = strdup(conninfo_getval("tty"));
+ conn->pgoptions = strdup(conninfo_getval("options"));
+ conn->pguser = strdup(conninfo_getval("user"));
+ conn->pgpass = strdup(conninfo_getval("password"));
+ conn->pgauth = strdup(conninfo_getval("authtype"));
+ conn->dbName = strdup(conninfo_getval("dbname"));
+
+ /* ----------
+ * Free the connection info - all is in conn now
+ * ----------
+ */
conninfo_free();
+
+ /*
+ * try to set the auth service if one was specified
+ */
+ if (conn->pgauth)
+ {
+ fe_setauthsvc(conn->pgauth, conn->errorMessage);
+ }
+
+ /* ----------
+ * Connect to the database
+ * ----------
+ */
+ conn->status = connectDB(conn);
+ if (conn->status == CONNECTION_OK)
+ {
+ PGresult *res;
+
+ /*
+ * Send a blank query to make sure everything works; in
+ * particular, that the database exists.
+ */
+ res = PQexec(conn, " ");
+ if (res == NULL || res->resultStatus != PGRES_EMPTY_QUERY)
+ {
+ /* PQexec has put error message in conn->errorMessage */
+ closePGconn(conn);
+ }
+ PQclear(res);
+ }
+
return conn;
- }
-
- /* ----------
- * Setup the conn structure
- * ----------
- */
- conn->lobjfuncs = (PGlobjfuncs *) NULL;
- conn->Pfout = NULL;
- conn->Pfin = NULL;
- conn->Pfdebug = NULL;
- conn->port = NULL;
- conn->notifyList = DLNewList();
-
- conn->pghost = strdup(conninfo_getval("host"));
- conn->pgport = strdup(conninfo_getval("port"));
- conn->pgtty = strdup(conninfo_getval("tty"));
- conn->pgoptions = strdup(conninfo_getval("options"));
- conn->pguser = strdup(conninfo_getval("user"));
- conn->pgpass = strdup(conninfo_getval("password"));
- conn->pgauth = strdup(conninfo_getval("authtype"));
- conn->dbName = strdup(conninfo_getval("dbname"));
-
- /* ----------
- * Free the connection info - all is in conn now
- * ----------
- */
- conninfo_free();
-
- /*
- * try to set the auth service if one was specified
- */
- if(conn->pgauth) {
- fe_setauthsvc(conn->pgauth, conn->errorMessage);
- }
-
- /* ----------
- * Connect to the database
- * ----------
- */
- conn->status = connectDB(conn);
- if (conn->status == CONNECTION_OK) {
- PGresult *res;
- /* Send a blank query to make sure everything works; in particular, that
- the database exists.
- */
- res = PQexec(conn," ");
- if (res == NULL || res->resultStatus != PGRES_EMPTY_QUERY) {
- /* PQexec has put error message in conn->errorMessage */
- closePGconn(conn);
- }
- PQclear(res);
- }
-
- return conn;
}
/* ----------------
- * PQconndefaults
- *
+ * PQconndefaults
+ *
* Parse an empty string like PQconnectdb() would do and return the
* address of the connection options structure. Using this function
* an application might determine all possible options and their
* current default values.
* ----------------
*/
-PQconninfoOption*
+PQconninfoOption *
PQconndefaults(void)
{
- char errorMessage[ERROR_MSG_LENGTH];
+ char errorMessage[ERROR_MSG_LENGTH];
- conninfo_parse("", errorMessage);
- return PQconninfoOptions;
+ conninfo_parse("", errorMessage);
+ return PQconninfoOptions;
}
/* ----------------
- * PQsetdb
- *
+ * PQsetdb
+ *
* establishes a connection to a postgres backend through the postmaster
* at the specified host and port.
*
* returns a PGconn* which is needed for all subsequent libpq calls
* if the status field of the connection returned is CONNECTION_BAD,
- * then some fields may be null'ed out instead of having valid values
+ * then some fields may be null'ed out instead of having valid values
*
- * Uses these environment variables:
+ * Uses these environment variables:
*
- * PGHOST identifies host to which to connect if <pghost> argument
- * is NULL or a null string.
+ * PGHOST identifies host to which to connect if <pghost> argument
+ * is NULL or a null string.
*
- * PGPORT identifies TCP port to which to connect if <pgport> argument
- * is NULL or a null string.
+ * PGPORT identifies TCP port to which to connect if <pgport> argument
+ * is NULL or a null string.
*
- * PGTTY identifies tty to which to send messages if <pgtty> argument
- * is NULL or a null string.
+ * PGTTY identifies tty to which to send messages if <pgtty> argument
+ * is NULL or a null string.
*
- * PGOPTIONS identifies connection options if <pgoptions> argument is
- * NULL or a null string.
+ * PGOPTIONS identifies connection options if <pgoptions> argument is
+ * NULL or a null string.
*
- * PGUSER Postgres username to associate with the connection.
+ * PGUSER Postgres username to associate with the connection.
*
- * PGPASSWORD The user's password.
+ * PGPASSWORD The user's password.
*
- * PGDATABASE name of database to which to connect if <pgdatabase>
- * argument is NULL or a null string
+ * PGDATABASE name of database to which to connect if <pgdatabase>
+ * argument is NULL or a null string
*
- * None of the above need be defined. There are defaults for all of them.
+ * None of the above need be defined. There are defaults for all of them.
*
* ----------------
*/
-PGconn*
-PQsetdb(const char *pghost, const char* pgport, const char* pgoptions, const char* pgtty, const char* dbName)
+PGconn *
+PQsetdb(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName)
{
- PGconn *conn;
- char *tmp;
- char errorMessage[ERROR_MSG_LENGTH];
- /* An error message from some service we call. */
- bool error;
- /* We encountered an error that prevents successful completion */
- int i;
-
- conn = (PGconn*)malloc(sizeof(PGconn));
-
- if (conn == NULL)
- fprintf(stderr,
- "FATAL: PQsetdb() -- unable to allocate memory for a PGconn");
- else {
- conn->lobjfuncs = (PGlobjfuncs *) NULL;
- conn->Pfout = NULL;
- conn->Pfin = NULL;
- conn->Pfdebug = NULL;
- conn->port = NULL;
- conn->notifyList = DLNewList();
-
- if (!pghost || pghost[0] == '\0') {
- if (!(tmp = getenv("PGHOST"))) {
- tmp = DefaultHost;
- }
- conn->pghost = strdup(tmp);
- } else
- conn->pghost = strdup(pghost);
-
- if (!pgport || pgport[0] == '\0') {
- if (!(tmp = getenv("PGPORT"))) {
- tmp = DEF_PGPORT;
- }
- conn->pgport = strdup(tmp);
- } else
- conn->pgport = strdup(pgport);
-
- if (!pgtty || pgtty[0] == '\0') {
- if (!(tmp = getenv("PGTTY"))) {
- tmp = DefaultTty;
- }
- conn->pgtty = strdup(tmp);
- } else
- conn->pgtty = strdup(pgtty);
-
- if (!pgoptions || pgoptions[0] == '\0') {
- if (!(tmp = getenv("PGOPTIONS"))) {
- tmp = DefaultOption;
- }
- conn->pgoptions = strdup(tmp);
- } else
- conn->pgoptions = strdup(pgoptions);
-
- if ((tmp = getenv("PGUSER"))) {
- error = FALSE;
- conn->pguser = strdup(tmp);
- } else {
- tmp = fe_getauthname(errorMessage);
- if (tmp == 0) {
- error = TRUE;
- sprintf(conn->errorMessage,
- "FATAL: PQsetdb: Unable to determine a Postgres username!\n");
- } else {
- error = FALSE;
- conn->pguser = tmp;
- }
- }
-
- if((tmp = getenv("PGPASSWORD"))) {
- conn->pgpass = strdup(tmp);
- } else {
- conn->pgpass = 0;
- }
-
- if (!error) {
- if (((tmp = (char *)dbName) && (dbName[0] != '\0')) ||
- ((tmp = getenv("PGDATABASE")))) {
- conn->dbName = strdup(tmp);
- } else conn->dbName = strdup(conn->pguser);
- for(i = 0; conn->dbName[i]; i++)
- if (isupper(conn->dbName[i]))
- conn->dbName[i] = tolower(conn->dbName[i]);
- } else conn->dbName = NULL;
-
- if (error) conn->status = CONNECTION_BAD;
- else {
- conn->status = connectDB(conn);
- /* Puts message in conn->errorMessage */
- if (conn->status == CONNECTION_OK) {
- PGresult *res;
- /* Send a blank query to make sure everything works;
- in particular, that the database exists.
- */
- res = PQexec(conn," ");
- if (res == NULL || res->resultStatus != PGRES_EMPTY_QUERY) {
- /* PQexec has put error message in conn->errorMessage */
- closePGconn(conn);
- }
- PQclear(res);
- }
- }
- }
- return conn;
+ PGconn *conn;
+ char *tmp;
+ char errorMessage[ERROR_MSG_LENGTH];
+
+ /* An error message from some service we call. */
+ bool error;
+
+ /* We encountered an error that prevents successful completion */
+ int i;
+
+ conn = (PGconn *) malloc(sizeof(PGconn));
+
+ if (conn == NULL)
+ fprintf(stderr,
+ "FATAL: PQsetdb() -- unable to allocate memory for a PGconn");
+ else
+ {
+ conn->lobjfuncs = (PGlobjfuncs *) NULL;
+ conn->Pfout = NULL;
+ conn->Pfin = NULL;
+ conn->Pfdebug = NULL;
+ conn->port = NULL;
+ conn->notifyList = DLNewList();
+
+ if (!pghost || pghost[0] == '\0')
+ {
+ if (!(tmp = getenv("PGHOST")))
+ {
+ tmp = DefaultHost;
+ }
+ conn->pghost = strdup(tmp);
+ }
+ else
+ conn->pghost = strdup(pghost);
+
+ if (!pgport || pgport[0] == '\0')
+ {
+ if (!(tmp = getenv("PGPORT")))
+ {
+ tmp = DEF_PGPORT;
+ }
+ conn->pgport = strdup(tmp);
+ }
+ else
+ conn->pgport = strdup(pgport);
+
+ if (!pgtty || pgtty[0] == '\0')
+ {
+ if (!(tmp = getenv("PGTTY")))
+ {
+ tmp = DefaultTty;
+ }
+ conn->pgtty = strdup(tmp);
+ }
+ else
+ conn->pgtty = strdup(pgtty);
+
+ if (!pgoptions || pgoptions[0] == '\0')
+ {
+ if (!(tmp = getenv("PGOPTIONS")))
+ {
+ tmp = DefaultOption;
+ }
+ conn->pgoptions = strdup(tmp);
+ }
+ else
+ conn->pgoptions = strdup(pgoptions);
+
+ if ((tmp = getenv("PGUSER")))
+ {
+ error = FALSE;
+ conn->pguser = strdup(tmp);
+ }
+ else
+ {
+ tmp = fe_getauthname(errorMessage);
+ if (tmp == 0)
+ {
+ error = TRUE;
+ sprintf(conn->errorMessage,
+ "FATAL: PQsetdb: Unable to determine a Postgres username!\n");
+ }
+ else
+ {
+ error = FALSE;
+ conn->pguser = tmp;
+ }
+ }
+
+ if ((tmp = getenv("PGPASSWORD")))
+ {
+ conn->pgpass = strdup(tmp);
+ }
+ else
+ {
+ conn->pgpass = 0;
+ }
+
+ if (!error)
+ {
+ if (((tmp = (char *) dbName) && (dbName[0] != '\0')) ||
+ ((tmp = getenv("PGDATABASE"))))
+ {
+ conn->dbName = strdup(tmp);
+ }
+ else
+ conn->dbName = strdup(conn->pguser);
+ for (i = 0; conn->dbName[i]; i++)
+ if (isupper(conn->dbName[i]))
+ conn->dbName[i] = tolower(conn->dbName[i]);
+ }
+ else
+ conn->dbName = NULL;
+
+ if (error)
+ conn->status = CONNECTION_BAD;
+ else
+ {
+ conn->status = connectDB(conn);
+ /* Puts message in conn->errorMessage */
+ if (conn->status == CONNECTION_OK)
+ {
+ PGresult *res;
+
+ /*
+ * Send a blank query to make sure everything works; in
+ * particular, that the database exists.
+ */
+ res = PQexec(conn, " ");
+ if (res == NULL || res->resultStatus != PGRES_EMPTY_QUERY)
+ {
+ /* PQexec has put error message in conn->errorMessage */
+ closePGconn(conn);
+ }
+ PQclear(res);
+ }
+ }
+ }
+ return conn;
}
-
+
/*
* connectDB -
- * make a connection to the backend so it is ready to receive queries.
+ * make a connection to the backend so it is ready to receive queries.
* return CONNECTION_OK if successful, CONNECTION_BAD if not.
*
*/
-static ConnStatusType
-connectDB(PGconn *conn)
+static ConnStatusType
+connectDB(PGconn * conn)
{
- struct hostent *hp;
-
- StartupInfo startup;
- PacketBuf pacBuf;
- int status;
- MsgType msgtype;
- int laddrlen = sizeof(struct sockaddr);
- Port *port = conn->port;
- int portno;
-
- /*
- *
- * Initialize the startup packet.
- *
- * This data structure is used for the seq-packet protocol. It
- * describes the frontend-backend connection.
- *
- *
- */
- strncpy(startup.user,conn->pguser,sizeof(startup.user));
- strncpy(startup.database,conn->dbName,sizeof(startup.database));
- strncpy(startup.tty,conn->pgtty,sizeof(startup.tty));
- if (conn->pgoptions) {
- strncpy(startup.options,conn->pgoptions, sizeof(startup.options));
- }
- else
- startup.options[0]='\0';
- startup.execFile[0]='\0'; /* not used */
-
- /*
- *
- * Open a connection to postmaster/backend.
- *
- */
- port = (Port *) malloc(sizeof(Port));
- memset((char *) port, 0, sizeof(Port));
-
- if (!(hp = gethostbyname(conn->pghost)) || hp->h_addrtype != AF_INET) {
- (void) sprintf(conn->errorMessage,
- "connectDB() -- unknown hostname: %s\n",
- conn->pghost);
- goto connect_errReturn;
- }
- memset((char *) &port->raddr, 0, sizeof(port->raddr));
- memmove((char *) &(port->raddr.sin_addr),
- (char *) hp->h_addr,
- hp->h_length);
- port->raddr.sin_family = AF_INET;
- portno = atoi(conn->pgport);
- port->raddr.sin_port = htons((unsigned short)(portno));
-
- /* connect to the server */
- if ((port->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- (void) sprintf(conn->errorMessage,
- "connectDB() -- socket() failed: errno=%d\n%s\n",
- errno, strerror(errno));
- goto connect_errReturn;
- }
- if (connect(port->sock, (struct sockaddr *)&port->raddr,
- sizeof(port->raddr)) < 0) {
- (void) sprintf(conn->errorMessage,
- "connectDB() failed: Is the postmaster running at '%s' on port '%s'?\n",
- conn->pghost,conn->pgport);
- goto connect_errReturn;
- }
- {
- struct protoent *pe;
- int on=1;
-
- pe = getprotobyname ("TCP");
- if ( pe == NULL )
- {
- (void) sprintf(conn->errorMessage,
- "connectDB(): getprotobyname failed\n");
- goto connect_errReturn;
+ struct hostent *hp;
+
+ StartupInfo startup;
+ PacketBuf pacBuf;
+ int status;
+ MsgType msgtype;
+ int laddrlen = sizeof(struct sockaddr);
+ Port *port = conn->port;
+ int portno;
+
+ /*
+ * Initialize the startup packet.
+ *
+ * This data structure is used for the seq-packet protocol. It describes
+ * the frontend-backend connection.
+ *
+ *
+ */
+ strncpy(startup.user, conn->pguser, sizeof(startup.user));
+ strncpy(startup.database, conn->dbName, sizeof(startup.database));
+ strncpy(startup.tty, conn->pgtty, sizeof(startup.tty));
+ if (conn->pgoptions)
+ {
+ strncpy(startup.options, conn->pgoptions, sizeof(startup.options));
+ }
+ else
+ startup.options[0] = '\0';
+ startup.execFile[0] = '\0'; /* not used */
+
+ /*
+ * Open a connection to postmaster/backend.
+ *
+ */
+ port = (Port *) malloc(sizeof(Port));
+ memset((char *) port, 0, sizeof(Port));
+
+ if (!(hp = gethostbyname(conn->pghost)) || hp->h_addrtype != AF_INET)
+ {
+ (void) sprintf(conn->errorMessage,
+ "connectDB() -- unknown hostname: %s\n",
+ conn->pghost);
+ goto connect_errReturn;
+ }
+ memset((char *) &port->raddr, 0, sizeof(port->raddr));
+ memmove((char *) &(port->raddr.sin_addr),
+ (char *) hp->h_addr,
+ hp->h_length);
+ port->raddr.sin_family = AF_INET;
+ portno = atoi(conn->pgport);
+ port->raddr.sin_port = htons((unsigned short) (portno));
+
+ /* connect to the server */
+ if ((port->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ (void) sprintf(conn->errorMessage,
+ "connectDB() -- socket() failed: errno=%d\n%s\n",
+ errno, strerror(errno));
+ goto connect_errReturn;
+ }
+ if (connect(port->sock, (struct sockaddr *) & port->raddr,
+ sizeof(port->raddr)) < 0)
+ {
+ (void) sprintf(conn->errorMessage,
+ "connectDB() failed: Is the postmaster running at '%s' on port '%s'?\n",
+ conn->pghost, conn->pgport);
+ goto connect_errReturn;
+ }
+ {
+ struct protoent *pe;
+ int on = 1;
+
+ pe = getprotobyname("TCP");
+ if (pe == NULL)
+ {
+ (void) sprintf(conn->errorMessage,
+ "connectDB(): getprotobyname failed\n");
+ goto connect_errReturn;
+ }
+ if (setsockopt(port->sock, pe->p_proto, TCP_NODELAY,
+ &on, sizeof(on)) < 0)
+ {
+ (void) sprintf(conn->errorMessage,
+ "connectDB(): setsockopt failed\n");
+ goto connect_errReturn;
+ }
+ }
+
+ /* fill in the client address */
+ if (getsockname(port->sock, (struct sockaddr *) & port->laddr,
+ &laddrlen) < 0)
+ {
+ (void) sprintf(conn->errorMessage,
+ "connectDB() -- getsockname() failed: errno=%d\n%s\n",
+ errno, strerror(errno));
+ goto connect_errReturn;
+ }
+
+ /* by this point, connection has been opened */
+ msgtype = fe_getauthsvc(conn->errorMessage);
+
+/* pacBuf = startup2PacketBuf(&startup);*/
+ startup2PacketBuf(&startup, &pacBuf);
+ pacBuf.msgtype = (MsgType) htonl(msgtype);
+ status = packetSend(port, &pacBuf, sizeof(PacketBuf), BLOCKING);
+
+ if (status == STATUS_ERROR)
+ {
+ sprintf(conn->errorMessage,
+ "connectDB() -- couldn't send complete packet: errno=%d\n%s\n", errno, strerror(errno));
+ goto connect_errReturn;
}
- if ( setsockopt (port->sock, pe->p_proto, TCP_NODELAY,
- &on, sizeof (on)) < 0 )
- {
- (void) sprintf(conn->errorMessage,
- "connectDB(): setsockopt failed\n");
- goto connect_errReturn;
+
+ /* authenticate as required */
+ if (fe_sendauth(msgtype, port, conn->pghost,
+ conn->pguser, conn->pgpass,
+ conn->errorMessage) != STATUS_OK)
+ {
+ (void) sprintf(conn->errorMessage,
+ "connectDB() -- authentication failed with %s\n",
+ conn->pghost);
+ goto connect_errReturn;
}
- }
-
- /* fill in the client address */
- if (getsockname(port->sock, (struct sockaddr *) &port->laddr,
- &laddrlen) < 0) {
- (void) sprintf(conn->errorMessage,
- "connectDB() -- getsockname() failed: errno=%d\n%s\n",
- errno, strerror(errno));
- goto connect_errReturn;
- }
-
- /* by this point, connection has been opened */
- msgtype = fe_getauthsvc(conn->errorMessage);
-
-/* pacBuf = startup2PacketBuf(&startup);*/
- startup2PacketBuf(&startup, &pacBuf);
- pacBuf.msgtype = (MsgType) htonl(msgtype);
- status = packetSend(port, &pacBuf, sizeof(PacketBuf), BLOCKING);
-
- if (status == STATUS_ERROR)
+
+ /* free the password so it's not hanging out in memory forever */
+ if (conn->pgpass)
{
- sprintf(conn->errorMessage,
- "connectDB() -- couldn't send complete packet: errno=%d\n%s\n", errno,strerror(errno));
- goto connect_errReturn;
+ free(conn->pgpass);
}
- /* authenticate as required*/
- if (fe_sendauth(msgtype, port, conn->pghost,
- conn->pguser, conn->pgpass,
- conn->errorMessage) != STATUS_OK) {
- (void) sprintf(conn->errorMessage,
- "connectDB() -- authentication failed with %s\n",
- conn->pghost);
- goto connect_errReturn;
- }
-
- /* free the password so it's not hanging out in memory forever */
- if(conn->pgpass) {
- free(conn->pgpass);
- }
-
- /* set up the socket file descriptors */
- conn->Pfout = fdopen(port->sock, "w");
- conn->Pfin = fdopen(dup(port->sock), "r");
- if (!conn->Pfout || !conn->Pfin) {
- (void) sprintf(conn->errorMessage,
- "connectDB() -- fdopen() failed: errno=%d\n%s\n",
- errno, strerror(errno));
- goto connect_errReturn;
- }
-
- conn->port = port;
-
- {
+ /* set up the socket file descriptors */
+ conn->Pfout = fdopen(port->sock, "w");
+ conn->Pfin = fdopen(dup(port->sock), "r");
+ if (!conn->Pfout || !conn->Pfin)
+ {
+ (void) sprintf(conn->errorMessage,
+ "connectDB() -- fdopen() failed: errno=%d\n%s\n",
+ errno, strerror(errno));
+ goto connect_errReturn;
+ }
+
+ conn->port = port;
+
+ {
struct EnvironmentOptions *eo;
- char setQuery[80]; /* mjl: size okay? XXX */
-
- for(eo = EnvironmentOptions; eo->envName; eo++)
+ char setQuery[80]; /* mjl: size okay? XXX */
+
+ for (eo = EnvironmentOptions; eo->envName; eo++)
+ {
+ const char *val;
+
+ if ((val = getenv(eo->envName)))
{
- const char *val;
-
- if((val = getenv(eo->envName)))
- {
- PGresult *res;
-
+ PGresult *res;
+
sprintf(setQuery, "SET %s TO '%.60s'", eo->pgName, val);
res = PQexec(conn, setQuery);
PQclear(res); /* Don't care? */
- }
}
}
- return CONNECTION_OK;
+ }
+ return CONNECTION_OK;
connect_errReturn:
- /* Igor/6/3/97 - We need to free it here...otherwise the function
- returns without setting conn->port to port. Because of that
- any way of referencing this variable will be lost and it's allocated
- memory will not be freed. */
- free(port); /* PURIFY */
- return CONNECTION_BAD;
+ /*
+ * Igor/6/3/97 - We need to free it here...otherwise the function
+ * returns without setting conn->port to port. Because of that any way
+ * of referencing this variable will be lost and it's allocated memory
+ * will not be freed.
+ */
+ free(port); /* PURIFY */
+ return CONNECTION_BAD;
}
/*
* freePGconn
- * - free the PGconn data structure
+ * - free the PGconn data structure
*
*/
-static void
-freePGconn(PGconn *conn)
+static void
+freePGconn(PGconn * conn)
{
- if (!conn) return;
- if (conn->pghost) free(conn->pghost);
- if (conn->pgtty) free(conn->pgtty);
- if (conn->pgoptions) free(conn->pgoptions);
- if (conn->pgport) free(conn->pgport);
- if (conn->dbName) free(conn->dbName);
- if (conn->pguser) free(conn->pguser);
- if (conn->notifyList) DLFreeList(conn->notifyList);
- if (conn->port) free(conn->port);
- free(conn);
+ if (!conn)
+ return;
+ if (conn->pghost)
+ free(conn->pghost);
+ if (conn->pgtty)
+ free(conn->pgtty);
+ if (conn->pgoptions)
+ free(conn->pgoptions);
+ if (conn->pgport)
+ free(conn->pgport);
+ if (conn->dbName)
+ free(conn->dbName);
+ if (conn->pguser)
+ free(conn->pguser);
+ if (conn->notifyList)
+ DLFreeList(conn->notifyList);
+ if (conn->port)
+ free(conn->port);
+ free(conn);
}
/*
closePGconn
- - properly close a connection to the backend
+ - properly close a connection to the backend
*/
static void
-closePGconn(PGconn *conn)
+closePGconn(PGconn * conn)
{
/* GH: What to do for !USE_POSIX_SIGNALS ? */
#if defined(USE_POSIX_SIGNALS)
- struct sigaction ignore_action;
- /* This is used as a constant, but not declared as such because the
- sigaction structure is defined differently on different systems */
- struct sigaction oldaction;
-
- /* If connection is already gone, that's cool. No reason for kernel
- to kill us when we try to write to it. So ignore SIGPIPE signals.
- */
- ignore_action.sa_handler = SIG_IGN;
- sigemptyset(&ignore_action.sa_mask);
- ignore_action.sa_flags = 0;
- sigaction(SIGPIPE, (struct sigaction *) &ignore_action, &oldaction);
-
- fputs("X\0", conn->Pfout);
- fflush(conn->Pfout);
- sigaction(SIGPIPE, &oldaction, NULL);
+ struct sigaction ignore_action;
+
+ /*
+ * This is used as a constant, but not declared as such because the
+ * sigaction structure is defined differently on different systems
+ */
+ struct sigaction oldaction;
+
+ /*
+ * If connection is already gone, that's cool. No reason for kernel
+ * to kill us when we try to write to it. So ignore SIGPIPE signals.
+ */
+ ignore_action.sa_handler = SIG_IGN;
+ sigemptyset(&ignore_action.sa_mask);
+ ignore_action.sa_flags = 0;
+ sigaction(SIGPIPE, (struct sigaction *) & ignore_action, &oldaction);
+
+ fputs("X\0", conn->Pfout);
+ fflush(conn->Pfout);
+ sigaction(SIGPIPE, &oldaction, NULL);
#else
- signal(SIGPIPE, SIG_IGN);
- fputs("X\0", conn->Pfout);
- fflush(conn->Pfout);
- signal(SIGPIPE, SIG_DFL);
+ signal(SIGPIPE, SIG_IGN);
+ fputs("X\0", conn->Pfout);
+ fflush(conn->Pfout);
+ signal(SIGPIPE, SIG_DFL);
#endif
- if (conn->Pfout) fclose(conn->Pfout);
- if (conn->Pfin) fclose(conn->Pfin);
- if (conn->Pfdebug) fclose(conn->Pfdebug);
- conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */
+ if (conn->Pfout)
+ fclose(conn->Pfout);
+ if (conn->Pfin)
+ fclose(conn->Pfin);
+ if (conn->Pfdebug)
+ fclose(conn->Pfdebug);
+ conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just
+ * absent */
}
/*
PQfinish:
- properly close a connection to the backend
- also frees the PGconn data structure so it shouldn't be re-used
- after this
+ properly close a connection to the backend
+ also frees the PGconn data structure so it shouldn't be re-used
+ after this
*/
void
-PQfinish(PGconn *conn)
+PQfinish(PGconn * conn)
{
- if (!conn) {
- fprintf(stderr,"PQfinish() -- pointer to PGconn is null\n");
- } else {
- if (conn->status == CONNECTION_OK)
- closePGconn(conn);
- freePGconn(conn);
- }
+ if (!conn)
+ {
+ fprintf(stderr, "PQfinish() -- pointer to PGconn is null\n");
+ }
+ else
+ {
+ if (conn->status == CONNECTION_OK)
+ closePGconn(conn);
+ freePGconn(conn);
+ }
}
/* PQreset :
resets the connection to the backend
- closes the existing connection and makes a new one
+ closes the existing connection and makes a new one
*/
void
-PQreset(PGconn *conn)
+PQreset(PGconn * conn)
{
- if (!conn) {
- fprintf(stderr,"PQreset() -- pointer to PGconn is null\n");
- } else {
- closePGconn(conn);
- conn->status = connectDB(conn);
- }
+ if (!conn)
+ {
+ fprintf(stderr, "PQreset() -- pointer to PGconn is null\n");
+ }
+ else
+ {
+ closePGconn(conn);
+ conn->status = connectDB(conn);
+ }
}
/*
@@ -679,29 +763,30 @@ PQreset(PGconn *conn)
*
* RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
* SIDE_EFFECTS: may block.
- * NOTES: Non-blocking writes would significantly complicate
- * buffer management. For now, we're not going to do it.
+ * NOTES: Non-blocking writes would significantly complicate
+ * buffer management. For now, we're not going to do it.
*
*/
int
-packetSend(Port *port,
- PacketBuf *buf,
- PacketLen len,
- bool nonBlocking)
+packetSend(Port * port,
+ PacketBuf * buf,
+ PacketLen len,
+ bool nonBlocking)
{
- PacketLen totalLen;
- int addrLen = sizeof(struct sockaddr_in);
-
- totalLen = len;
-
- len = sendto(port->sock, (Addr) buf, totalLen, /* flags */ 0,
- (struct sockaddr *)&(port->raddr), addrLen);
-
- if (len < totalLen) {
- return(STATUS_ERROR);
- }
-
- return(STATUS_OK);
+ PacketLen totalLen;
+ int addrLen = sizeof(struct sockaddr_in);
+
+ totalLen = len;
+
+ len = sendto(port->sock, (Addr) buf, totalLen, /* flags */ 0,
+ (struct sockaddr *) & (port->raddr), addrLen);
+
+ if (len < totalLen)
+ {
+ return (STATUS_ERROR);
+ }
+
+ return (STATUS_OK);
}
/*
@@ -709,359 +794,412 @@ packetSend(Port *port,
*
* this is just like StartupInfo2Packet(), defined in backend/libpq/pqpacket.c
* but we repeat it here so we don't have to link in libpq.a
- *
+ *
* converts a StartupInfo structure to a PacketBuf
*/
static void
-startup2PacketBuf(StartupInfo* s, PacketBuf* res)
+startup2PacketBuf(StartupInfo * s, PacketBuf * res)
{
- char* tmp;
-
-/* res = (PacketBuf*)malloc(sizeof(PacketBuf)); */
- res->len = htonl(sizeof(PacketBuf));
- /* use \n to delimit the strings */
- res->data[0] = '\0';
-
- tmp= res->data;
-
- strncpy(tmp, s->database, sizeof(s->database));
- tmp += sizeof(s->database);
- strncpy(tmp, s->user, sizeof(s->user));
- tmp += sizeof(s->user);
- strncpy(tmp, s->options, sizeof(s->options));
- tmp += sizeof(s->options);
- strncpy(tmp, s->execFile, sizeof(s->execFile));
- tmp += sizeof(s->execFile);
- strncpy(tmp, s->tty, sizeof(s->tty));
+ char *tmp;
+
+/* res = (PacketBuf*)malloc(sizeof(PacketBuf)); */
+ res->len = htonl(sizeof(PacketBuf));
+ /* use \n to delimit the strings */
+ res->data[0] = '\0';
+
+ tmp = res->data;
+
+ strncpy(tmp, s->database, sizeof(s->database));
+ tmp += sizeof(s->database);
+ strncpy(tmp, s->user, sizeof(s->user));
+ tmp += sizeof(s->user);
+ strncpy(tmp, s->options, sizeof(s->options));
+ tmp += sizeof(s->options);
+ strncpy(tmp, s->execFile, sizeof(s->execFile));
+ tmp += sizeof(s->execFile);
+ strncpy(tmp, s->tty, sizeof(s->tty));
}
/* ----------------
* Conninfo parser routine
* ----------------
*/
-static int conninfo_parse(const char *conninfo, char *errorMessage)
+static int
+conninfo_parse(const char *conninfo, char *errorMessage)
{
- char *pname;
- char *pval;
- char *buf;
- char *tmp;
- char *cp;
- char *cp2;
- PQconninfoOption *option;
- char errortmp[ERROR_MSG_LENGTH];
-
- conninfo_free();
-
- if((buf = strdup(conninfo)) == NULL) {
- strcpy(errorMessage,
- "FATAL: cannot allocate memory for copy of conninfo string\n");
- return -1;
- }
- cp = buf;
-
- while(*cp) {
- /* Skip blanks before the parameter name */
- if(isspace(*cp)) {
- cp++;
- continue;
+ char *pname;
+ char *pval;
+ char *buf;
+ char *tmp;
+ char *cp;
+ char *cp2;
+ PQconninfoOption *option;
+ char errortmp[ERROR_MSG_LENGTH];
+
+ conninfo_free();
+
+ if ((buf = strdup(conninfo)) == NULL)
+ {
+ strcpy(errorMessage,
+ "FATAL: cannot allocate memory for copy of conninfo string\n");
+ return -1;
}
+ cp = buf;
- /* Get the parameter name */
- pname = cp;
- while(*cp) {
- if(*cp == '=') {
- break;
- }
- if(isspace(*cp)) {
- *cp++ = '\0';
- while(*cp) {
- if(!isspace(*cp)) {
- break;
- }
- cp++;
+ while (*cp)
+ {
+ /* Skip blanks before the parameter name */
+ if (isspace(*cp))
+ {
+ cp++;
+ continue;
}
- break;
- }
- cp++;
- }
- /* Check that there is a following '=' */
- if(*cp != '=') {
- sprintf(errorMessage,
- "ERROR: PQconnectdb() - Missing '=' after '%s' in conninfo\n",
- pname);
- free(buf);
- return -1;
- }
- *cp++ = '\0';
-
- /* Skip blanks after the '=' */
- while(*cp) {
- if(!isspace(*cp)) {
- break;
- }
- cp++;
- }
+ /* Get the parameter name */
+ pname = cp;
+ while (*cp)
+ {
+ if (*cp == '=')
+ {
+ break;
+ }
+ if (isspace(*cp))
+ {
+ *cp++ = '\0';
+ while (*cp)
+ {
+ if (!isspace(*cp))
+ {
+ break;
+ }
+ cp++;
+ }
+ break;
+ }
+ cp++;
+ }
- pval = cp;
+ /* Check that there is a following '=' */
+ if (*cp != '=')
+ {
+ sprintf(errorMessage,
+ "ERROR: PQconnectdb() - Missing '=' after '%s' in conninfo\n",
+ pname);
+ free(buf);
+ return -1;
+ }
+ *cp++ = '\0';
- if(*cp != '\'') {
- cp2 = pval;
- while(*cp) {
- if(isspace(*cp)) {
- *cp++ = '\0';
- break;
+ /* Skip blanks after the '=' */
+ while (*cp)
+ {
+ if (!isspace(*cp))
+ {
+ break;
+ }
+ cp++;
}
- if(*cp == '\\') {
- cp++;
- if(*cp != '\0') {
- *cp2++ = *cp++;
- }
- } else {
- *cp2++ = *cp++;
+
+ pval = cp;
+
+ if (*cp != '\'')
+ {
+ cp2 = pval;
+ while (*cp)
+ {
+ if (isspace(*cp))
+ {
+ *cp++ = '\0';
+ break;
+ }
+ if (*cp == '\\')
+ {
+ cp++;
+ if (*cp != '\0')
+ {
+ *cp2++ = *cp++;
+ }
+ }
+ else
+ {
+ *cp2++ = *cp++;
+ }
+ }
+ *cp2 = '\0';
}
- }
- *cp2 = '\0';
- } else {
- cp2 = pval;
- cp++;
- for(;;) {
- if(*cp == '\0') {
- sprintf(errorMessage,
- "ERROR: PQconnectdb() - unterminated quoted string in conninfo\n");
- free(buf);
- return -1;
+ else
+ {
+ cp2 = pval;
+ cp++;
+ for (;;)
+ {
+ if (*cp == '\0')
+ {
+ sprintf(errorMessage,
+ "ERROR: PQconnectdb() - unterminated quoted string in conninfo\n");
+ free(buf);
+ return -1;
+ }
+ if (*cp == '\\')
+ {
+ cp++;
+ if (*cp != '\0')
+ {
+ *cp2++ = *cp++;
+ }
+ continue;
+ }
+ if (*cp == '\'')
+ {
+ *cp2 = '\0';
+ cp++;
+ break;
+ }
+ *cp2++ = *cp++;
+ }
}
- if(*cp == '\\') {
- cp++;
- if(*cp != '\0') {
- *cp2++ = *cp++;
- }
- continue;
+
+ /* ----------
+ * Now we have the name and the value. Search
+ * for the param record.
+ * ----------
+ */
+ for (option = PQconninfoOptions; option->keyword != NULL; option++)
+ {
+ if (!strcmp(option->keyword, pname))
+ {
+ break;
+ }
}
- if(*cp == '\'') {
- *cp2 = '\0';
- cp++;
- break;
+ if (option->keyword == NULL)
+ {
+ sprintf(errorMessage,
+ "ERROR: PQconnectdb() - unknown option '%s'\n",
+ pname);
+ free(buf);
+ return -1;
}
- *cp2++ = *cp++;
- }
- }
- /* ----------
- * Now we have the name and the value. Search
- * for the param record.
- * ----------
- */
- for(option = PQconninfoOptions; option->keyword != NULL; option++) {
- if(!strcmp(option->keyword, pname)) {
- break;
- }
- }
- if(option->keyword == NULL) {
- sprintf(errorMessage,
- "ERROR: PQconnectdb() - unknown option '%s'\n",
- pname);
- free(buf);
- return -1;
+ /* ----------
+ * Store the value
+ * ----------
+ */
+ option->val = strdup(pval);
}
- /* ----------
- * Store the value
- * ----------
- */
- option->val = strdup(pval);
- }
-
- free(buf);
-
- /* ----------
- * Get the fallback resources for parameters not specified
- * in the conninfo string.
- * ----------
- */
- for(option = PQconninfoOptions; option->keyword != NULL; option++) {
- if(option->val != NULL) continue; /* Value was in conninfo */
+ free(buf);
/* ----------
- * Try to get the environment variable fallback
+ * Get the fallback resources for parameters not specified
+ * in the conninfo string.
* ----------
*/
- if(option->environ != NULL) {
- if((tmp = getenv(option->environ)) != NULL) {
- option->val = strdup(tmp);
- continue;
- }
- }
+ for (option = PQconninfoOptions; option->keyword != NULL; option++)
+ {
+ if (option->val != NULL)
+ continue; /* Value was in conninfo */
+
+ /* ----------
+ * Try to get the environment variable fallback
+ * ----------
+ */
+ if (option->environ != NULL)
+ {
+ if ((tmp = getenv(option->environ)) != NULL)
+ {
+ option->val = strdup(tmp);
+ continue;
+ }
+ }
- /* ----------
- * No environment variable specified or this one isn't set -
- * try compiled in
- * ----------
- */
- if(option->compiled != NULL) {
- option->val = strdup(option->compiled);
- continue;
- }
+ /* ----------
+ * No environment variable specified or this one isn't set -
+ * try compiled in
+ * ----------
+ */
+ if (option->compiled != NULL)
+ {
+ option->val = strdup(option->compiled);
+ continue;
+ }
- /* ----------
- * Special handling for user
- * ----------
- */
- if(!strcmp(option->keyword, "user")) {
- tmp = fe_getauthname(errortmp);
- if (tmp) {
- option->val = strdup(tmp);
- }
- }
+ /* ----------
+ * Special handling for user
+ * ----------
+ */
+ if (!strcmp(option->keyword, "user"))
+ {
+ tmp = fe_getauthname(errortmp);
+ if (tmp)
+ {
+ option->val = strdup(tmp);
+ }
+ }
- /* ----------
- * Special handling for dbname
- * ----------
- */
- if(!strcmp(option->keyword, "dbname")) {
- tmp = conninfo_getval("user");
- if (tmp) {
- option->val = strdup(tmp);
- }
+ /* ----------
+ * Special handling for dbname
+ * ----------
+ */
+ if (!strcmp(option->keyword, "dbname"))
+ {
+ tmp = conninfo_getval("user");
+ if (tmp)
+ {
+ option->val = strdup(tmp);
+ }
+ }
}
- }
- return 0;
+ return 0;
}
-static char*
+static char *
conninfo_getval(char *keyword)
{
- PQconninfoOption *option;
+ PQconninfoOption *option;
- for(option = PQconninfoOptions; option->keyword != NULL; option++) {
- if (!strcmp(option->keyword, keyword)) {
- return option->val;
+ for (option = PQconninfoOptions; option->keyword != NULL; option++)
+ {
+ if (!strcmp(option->keyword, keyword))
+ {
+ return option->val;
+ }
}
- }
- return NULL;
+ return NULL;
}
static void
conninfo_free()
{
- PQconninfoOption *option;
+ PQconninfoOption *option;
- for(option = PQconninfoOptions; option->keyword != NULL; option++) {
- if(option->val != NULL) {
- free(option->val);
- option->val = NULL;
+ for (option = PQconninfoOptions; option->keyword != NULL; option++)
+ {
+ if (option->val != NULL)
+ {
+ free(option->val);
+ option->val = NULL;
+ }
}
- }
}
/* =========== accessor functions for PGconn ========= */
-char*
-PQdb(PGconn* conn)
+char *
+PQdb(PGconn * conn)
{
- if (!conn) {
- fprintf(stderr,"PQdb() -- pointer to PGconn is null\n");
- return (char *)NULL;
- }
- return conn->dbName;
+ if (!conn)
+ {
+ fprintf(stderr, "PQdb() -- pointer to PGconn is null\n");
+ return (char *) NULL;
+ }
+ return conn->dbName;
}
-char*
-PQuser(PGconn* conn)
+char *
+PQuser(PGconn * conn)
{
- if (!conn) {
- fprintf(stderr,"PQuser() -- pointer to PGconn is null\n");
- return (char *)NULL;
- }
- return conn->pguser;
+ if (!conn)
+ {
+ fprintf(stderr, "PQuser() -- pointer to PGconn is null\n");
+ return (char *) NULL;
+ }
+ return conn->pguser;
}
-char*
-PQhost(PGconn* conn)
+char *
+PQhost(PGconn * conn)
{
- if (!conn) {
- fprintf(stderr,"PQhost() -- pointer to PGconn is null\n");
- return (char *)NULL;
- }
+ if (!conn)
+ {
+ fprintf(stderr, "PQhost() -- pointer to PGconn is null\n");
+ return (char *) NULL;
+ }
- return conn->pghost;
+ return conn->pghost;
}
-char*
-PQoptions(PGconn* conn)
+char *
+PQoptions(PGconn * conn)
{
- if (!conn) {
- fprintf(stderr,"PQoptions() -- pointer to PGconn is null\n");
- return (char *)NULL;
- }
- return conn->pgoptions;
+ if (!conn)
+ {
+ fprintf(stderr, "PQoptions() -- pointer to PGconn is null\n");
+ return (char *) NULL;
+ }
+ return conn->pgoptions;
}
-char*
-PQtty(PGconn* conn)
+char *
+PQtty(PGconn * conn)
{
- if (!conn) {
- fprintf(stderr,"PQtty() -- pointer to PGconn is null\n");
- return (char *)NULL;
- }
- return conn->pgtty;
+ if (!conn)
+ {
+ fprintf(stderr, "PQtty() -- pointer to PGconn is null\n");
+ return (char *) NULL;
+ }
+ return conn->pgtty;
}
-char*
-PQport(PGconn* conn)
+char *
+PQport(PGconn * conn)
{
- if (!conn) {
- fprintf(stderr,"PQport() -- pointer to PGconn is null\n");
- return (char *)NULL;
- }
- return conn->pgport;
+ if (!conn)
+ {
+ fprintf(stderr, "PQport() -- pointer to PGconn is null\n");
+ return (char *) NULL;
+ }
+ return conn->pgport;
}
ConnStatusType
-PQstatus(PGconn* conn)
+PQstatus(PGconn * conn)
{
- if (!conn) {
- fprintf(stderr,"PQstatus() -- pointer to PGconn is null\n");
- return CONNECTION_BAD;
- }
- return conn->status;
+ if (!conn)
+ {
+ fprintf(stderr, "PQstatus() -- pointer to PGconn is null\n");
+ return CONNECTION_BAD;
+ }
+ return conn->status;
}
-char*
-PQerrorMessage(PGconn* conn)
+char *
+PQerrorMessage(PGconn * conn)
{
- if (!conn) {
- fprintf(stderr,"PQerrorMessage() -- pointer to PGconn is null\n");
- return (char *)NULL;
- }
- return conn->errorMessage;
+ if (!conn)
+ {
+ fprintf(stderr, "PQerrorMessage() -- pointer to PGconn is null\n");
+ return (char *) NULL;
+ }
+ return conn->errorMessage;
}
void
-PQtrace(PGconn *conn, FILE* debug_port)
+PQtrace(PGconn * conn, FILE * debug_port)
{
- if (conn == NULL ||
- conn->status == CONNECTION_BAD) {
- return;
- }
- PQuntrace(conn);
- conn->Pfdebug = debug_port;
+ if (conn == NULL ||
+ conn->status == CONNECTION_BAD)
+ {
+ return;
+ }
+ PQuntrace(conn);
+ conn->Pfdebug = debug_port;
}
-void
-PQuntrace(PGconn *conn)
+void
+PQuntrace(PGconn * conn)
{
- if (conn == NULL ||
- conn->status == CONNECTION_BAD) {
- return;
- }
- if (conn->Pfdebug) {
- fflush(conn->Pfdebug);
- fclose(conn->Pfdebug);
- conn->Pfdebug = NULL;
- }
+ if (conn == NULL ||
+ conn->status == CONNECTION_BAD)
+ {
+ return;
+ }
+ if (conn->Pfdebug)
+ {
+ fflush(conn->Pfdebug);
+ fclose(conn->Pfdebug);
+ conn->Pfdebug = NULL;
+ }
}
diff --git a/src/interfaces/libpq/fe-connect.h b/src/interfaces/libpq/fe-connect.h
index ffa746473d3..5bd38084488 100644
--- a/src/interfaces/libpq/fe-connect.h
+++ b/src/interfaces/libpq/fe-connect.h
@@ -2,28 +2,28 @@
*
* fe-connect.h
*
- * Definitions related to setting up a connection to the backend
+ * Definitions related to setting up a connection to the backend
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: fe-connect.h,v 1.1 1997/03/16 19:06:04 scrappy Exp $
+ * $Id: fe-connect.h,v 1.2 1997/09/07 05:03:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef FE_CONNECT_H
-#define FE_CONNECT_H
+#define FE_CONNECT_H
/*----------------------------------------------------------------
* Common routines and definitions
*----------------------------------------------------------------
*/
-extern int packetSend(Port *port, PacketBuf *buf, PacketLen len, bool nonBlocking);
+extern int packetSend(Port * port, PacketBuf * buf, PacketLen len, bool nonBlocking);
-#endif /* FE_CONNECT_H */
+#endif /* FE_CONNECT_H */
#ifndef FE_CONNECT_H
#define FE_CONNECT_H
-int packetSend(Port *port, PacketBuf *buf, PacketLen len, bool nonBlocking);
+int packetSend(Port * port, PacketBuf * buf, PacketLen len, bool nonBlocking);
#endif
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 771e8c66e2b..be8913e7bf7 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* fe-exec.c--
- * functions related to sending a query down to the backend
+ * functions related to sending a query down to the backend
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.35 1997/09/05 00:09:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.36 1997/09/07 05:03:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,19 +23,22 @@
#include "libpq-fe.h"
#include <sys/ioctl.h>
#ifndef HAVE_TERMIOS_H
-# include <sys/termios.h>
+#include <sys/termios.h>
#else
-# include <termios.h>
+#include <termios.h>
#endif
#ifdef TIOCGWINSZ
-struct winsize screen_size;
+struct winsize screen_size;
+
#else
-struct winsize {
- int ws_row;
- int ws_col;
-} screen_size;
+struct winsize
+{
+ int ws_row;
+ int ws_col;
+} screen_size;
+
#endif
/* the rows array in a PGresGroup has to grow to accommodate the rows */
@@ -43,325 +46,358 @@ struct winsize {
#define TUPARR_GROW_BY 100
/* keep this in same order as ExecStatusType in pgtclCmds.h */
-const char* pgresStatus[] = {
- "PGRES_EMPTY_QUERY",
- "PGRES_COMMAND_OK",
- "PGRES_TUPLES_OK",
- "PGRES_BAD_RESPONSE",
- "PGRES_NONFATAL_ERROR",
- "PGRES_FATAL_ERROR"
+const char *pgresStatus[] = {
+ "PGRES_EMPTY_QUERY",
+ "PGRES_COMMAND_OK",
+ "PGRES_TUPLES_OK",
+ "PGRES_BAD_RESPONSE",
+ "PGRES_NONFATAL_ERROR",
+ "PGRES_FATAL_ERROR"
};
-static PGresult* makePGresult(PGconn *conn, char *pname);
-static void addTuple(PGresult *res, PGresAttValue *tup);
-static PGresAttValue* getTuple(PGconn *conn, PGresult *res, int binary);
-static PGresult* makeEmptyPGresult(PGconn *conn, ExecStatusType status);
-static void fill(int length, int max, char filler, FILE *fp);
-static char* do_header(FILE *fout, PQprintOpt *po, const int nFields,
- int fieldMax[], char *fieldNames[], unsigned char fieldNotNum[],
- const int fs_len, PGresult *res);
+static PGresult *makePGresult(PGconn * conn, char *pname);
+static void addTuple(PGresult * res, PGresAttValue * tup);
+static PGresAttValue *getTuple(PGconn * conn, PGresult * res, int binary);
+static PGresult *makeEmptyPGresult(PGconn * conn, ExecStatusType status);
+static void fill(int length, int max, char filler, FILE * fp);
+static char *
+do_header(FILE * fout, PQprintOpt * po, const int nFields,
+ int fieldMax[], char *fieldNames[], unsigned char fieldNotNum[],
+ const int fs_len, PGresult * res);
/*
* PQclear -
- * free's the memory associated with a PGresult
+ * free's the memory associated with a PGresult
*
*/
void
-PQclear(PGresult* res)
+PQclear(PGresult * res)
{
- int i,j;
-
- if (!res)
- return;
-
- /* free all the rows */
- for (i=0;i<res->ntups;i++) {
- for (j=0;j<res->numAttributes;j++) {
- if (res->tuples[i][j].value)
- free(res->tuples[i][j].value);
- }
- if (res->tuples[i]) free(res->tuples[i]);
- }
- if (res->tuples) free(res->tuples);
-
- /* free all the attributes */
- for (i=0;i<res->numAttributes;i++) {
- if (res->attDescs[i].name)
- free(res->attDescs[i].name);
- }
- if (res->attDescs) free(res->attDescs);
-
- /* free the structure itself */
- free(res);
+ int i,
+ j;
+
+ if (!res)
+ return;
+
+ /* free all the rows */
+ for (i = 0; i < res->ntups; i++)
+ {
+ for (j = 0; j < res->numAttributes; j++)
+ {
+ if (res->tuples[i][j].value)
+ free(res->tuples[i][j].value);
+ }
+ if (res->tuples[i])
+ free(res->tuples[i]);
+ }
+ if (res->tuples)
+ free(res->tuples);
+
+ /* free all the attributes */
+ for (i = 0; i < res->numAttributes; i++)
+ {
+ if (res->attDescs[i].name)
+ free(res->attDescs[i].name);
+ }
+ if (res->attDescs)
+ free(res->attDescs);
+
+ /* free the structure itself */
+ free(res);
}
/*
* PGresult -
- * returns a newly allocated, initialized PGresult
+ * returns a newly allocated, initialized PGresult
*
*/
-static PGresult*
-makeEmptyPGresult(PGconn *conn, ExecStatusType status)
+static PGresult *
+makeEmptyPGresult(PGconn * conn, ExecStatusType status)
{
- PGresult *result;
-
- result = (PGresult*)malloc(sizeof(PGresult));
-
- result->conn = conn;
- result->ntups = 0;
- result->numAttributes = 0;
- result->attDescs = NULL;
- result->tuples = NULL;
- result->tupArrSize = 0;
- result->resultStatus = status;
- result->cmdStatus[0] = '\0';
- result->binary = 0;
- return result;
+ PGresult *result;
+
+ result = (PGresult *) malloc(sizeof(PGresult));
+
+ result->conn = conn;
+ result->ntups = 0;
+ result->numAttributes = 0;
+ result->attDescs = NULL;
+ result->tuples = NULL;
+ result->tupArrSize = 0;
+ result->resultStatus = status;
+ result->cmdStatus[0] = '\0';
+ result->binary = 0;
+ return result;
}
/*
* getTuple -
- * get the next row from the stream
+ * get the next row from the stream
*
- * the CALLER is responsible from freeing the PGresAttValue returned
+ * the CALLER is responsible from freeing the PGresAttValue returned
*/
-static PGresAttValue*
-getTuple(PGconn *conn, PGresult* result, int binary)
+static PGresAttValue *
+getTuple(PGconn * conn, PGresult * result, int binary)
{
- char bitmap[MAX_FIELDS]; /* the backend sends us a bitmap of */
- /* which attributes are null */
- int bitmap_index = 0;
- int i;
- int nbytes; /* the number of bytes in bitmap */
- char bmap; /* One byte of the bitmap */
- int bitcnt = 0; /* number of bits examined in current byte */
- int vlen; /* length of the current field value */
- FILE *pfin = conn->Pfin;
- FILE *pfdebug = conn->Pfdebug;
-
- PGresAttValue* tup;
-
- int nfields = result->numAttributes;
-
- result->binary = binary;
-
- tup = (PGresAttValue*) malloc(nfields * sizeof(PGresAttValue));
-
- nbytes = nfields / BYTELEN;
- if ( (nfields % BYTELEN) > 0)
- nbytes++;
-
- if (pqGetnchar(bitmap, nbytes, pfin, pfdebug) == 1){
- sprintf(conn->errorMessage,
- "Error reading null-values bitmap from row data stream\n");
- return NULL;
- }
-
- bmap = bitmap[bitmap_index];
-
- for (i=0;i<nfields;i++) {
- if (!(bmap & 0200)) {
- /* if the field value is absent, make it '\0' */
- tup[i].value = (char*)malloc(1);
- tup[i].value[0] = '\0';
- tup[i].len = NULL_LEN;
- }
- else {
- /* get the value length (the first four bytes are for length) */
- pqGetInt(&vlen, VARHDRSZ, pfin, pfdebug);
- if (binary == 0) {
- vlen = vlen - VARHDRSZ;
- }
- if (vlen < 0)
- vlen = 0;
- tup[i].len = vlen;
- tup[i].value = (char*) malloc(vlen + 1);
- /* read in the value; */
- if (vlen > 0)
- pqGetnchar((char*)(tup[i].value), vlen, pfin, pfdebug);
- tup[i].value[vlen] = '\0';
- }
- /* get the appropriate bitmap */
- bitcnt++;
- if (bitcnt == BYTELEN) {
- bitmap_index++;
- bmap = bitmap[bitmap_index];
- bitcnt = 0;
- } else
- bmap <<= 1;
- }
-
- return tup;
+ char bitmap[MAX_FIELDS]; /* the backend sends us a bitmap
+ * of */
+
+ /* which attributes are null */
+ int bitmap_index = 0;
+ int i;
+ int nbytes; /* the number of bytes in bitmap */
+ char bmap; /* One byte of the bitmap */
+ int bitcnt = 0; /* number of bits examined in current byte */
+ int vlen; /* length of the current field value */
+ FILE *pfin = conn->Pfin;
+ FILE *pfdebug = conn->Pfdebug;
+
+ PGresAttValue *tup;
+
+ int nfields = result->numAttributes;
+
+ result->binary = binary;
+
+ tup = (PGresAttValue *) malloc(nfields * sizeof(PGresAttValue));
+
+ nbytes = nfields / BYTELEN;
+ if ((nfields % BYTELEN) > 0)
+ nbytes++;
+
+ if (pqGetnchar(bitmap, nbytes, pfin, pfdebug) == 1)
+ {
+ sprintf(conn->errorMessage,
+ "Error reading null-values bitmap from row data stream\n");
+ return NULL;
+ }
+
+ bmap = bitmap[bitmap_index];
+
+ for (i = 0; i < nfields; i++)
+ {
+ if (!(bmap & 0200))
+ {
+ /* if the field value is absent, make it '\0' */
+ tup[i].value = (char *) malloc(1);
+ tup[i].value[0] = '\0';
+ tup[i].len = NULL_LEN;
+ }
+ else
+ {
+ /* get the value length (the first four bytes are for length) */
+ pqGetInt(&vlen, VARHDRSZ, pfin, pfdebug);
+ if (binary == 0)
+ {
+ vlen = vlen - VARHDRSZ;
+ }
+ if (vlen < 0)
+ vlen = 0;
+ tup[i].len = vlen;
+ tup[i].value = (char *) malloc(vlen + 1);
+ /* read in the value; */
+ if (vlen > 0)
+ pqGetnchar((char *) (tup[i].value), vlen, pfin, pfdebug);
+ tup[i].value[vlen] = '\0';
+ }
+ /* get the appropriate bitmap */
+ bitcnt++;
+ if (bitcnt == BYTELEN)
+ {
+ bitmap_index++;
+ bmap = bitmap[bitmap_index];
+ bitcnt = 0;
+ }
+ else
+ bmap <<= 1;
+ }
+
+ return tup;
}
/*
* addTuple
- * add a row to the PGresult structure, growing it if necessary
- * to accommodate
+ * add a row to the PGresult structure, growing it if necessary
+ * to accommodate
*
*/
-static void
-addTuple(PGresult* res, PGresAttValue* tup)
+static void
+addTuple(PGresult * res, PGresAttValue * tup)
{
- if (res->ntups == res->tupArrSize) {
- /* grow the array */
- res->tupArrSize += TUPARR_GROW_BY;
-
- if (res->ntups == 0)
- res->tuples = (PGresAttValue**)
- malloc(res->tupArrSize * sizeof(PGresAttValue*));
- else
- /* we can use realloc because shallow copying of the structure is okay */
- res->tuples = (PGresAttValue**)
- realloc(res->tuples, res->tupArrSize * sizeof(PGresAttValue*));
- }
-
- res->tuples[res->ntups] = tup;
- res->ntups++;
+ if (res->ntups == res->tupArrSize)
+ {
+ /* grow the array */
+ res->tupArrSize += TUPARR_GROW_BY;
+
+ if (res->ntups == 0)
+ res->tuples = (PGresAttValue **)
+ malloc(res->tupArrSize * sizeof(PGresAttValue *));
+ else
+
+ /*
+ * we can use realloc because shallow copying of the structure
+ * is okay
+ */
+ res->tuples = (PGresAttValue **)
+ realloc(res->tuples, res->tupArrSize * sizeof(PGresAttValue *));
+ }
+
+ res->tuples[res->ntups] = tup;
+ res->ntups++;
}
/*
* PGresult
- * fill out the PGresult structure with result rows from the backend
- * this is called after query has been successfully run and we have
- * a portal name
+ * fill out the PGresult structure with result rows from the backend
+ * this is called after query has been successfully run and we have
+ * a portal name
*
- * ASSUMPTION: we assume only *1* row group is returned from the backend
+ * ASSUMPTION: we assume only *1* row group is returned from the backend
*
- * the CALLER is reponsible for free'ing the new PGresult allocated here
+ * the CALLER is reponsible for free'ing the new PGresult allocated here
*
*/
-static PGresult*
-makePGresult(PGconn* conn, char* pname)
+static PGresult *
+makePGresult(PGconn * conn, char *pname)
{
- PGresult* result;
- int id;
- int nfields;
- int i;
- int done = 0;
-
- PGresAttValue* newTup;
-
- FILE* pfin = conn->Pfin;
- FILE* pfdebug = conn->Pfdebug;
-
- result = makeEmptyPGresult(conn, PGRES_TUPLES_OK);
-
- /* makePGresult() should only be called when the */
- /* id of the stream is 'T' to start with */
-
- /* the next two bytes are the number of fields */
- if (pqGetInt(&nfields, 2, pfin, pfdebug) == 1) {
- sprintf(conn->errorMessage,
- "could not get the number of fields from the 'T' message\n");
- goto makePGresult_badResponse_return;
- }
- else
- result->numAttributes = nfields;
-
- /* allocate space for the attribute descriptors */
- if (nfields > 0) {
- result->attDescs = (PGresAttDesc*) malloc(nfields * sizeof(PGresAttDesc));
- }
-
- /* get type info */
- for (i=0;i<nfields;i++) {
- char typName[MAX_MESSAGE_LEN];
- int adtid;
- int adtsize;
-
- if ( pqGets(typName, MAX_MESSAGE_LEN, pfin, pfdebug) ||
- pqGetInt(&adtid, 4, pfin, pfdebug) ||
- pqGetInt(&adtsize, 2, pfin, pfdebug)) {
- sprintf(conn->errorMessage,
- "error reading type information from the 'T' message\n");
- goto makePGresult_badResponse_return;
- }
- result->attDescs[i].name = malloc(strlen(typName)+1);
- strcpy(result->attDescs[i].name,typName);
- result->attDescs[i].adtid = adtid;
- result->attDescs[i].adtsize = adtsize; /* casting from int to int2 here */
- }
-
- id = pqGetc(pfin,pfdebug);
-
- /* process the data stream until we're finished */
- while(!done) {
- switch (id) {
- case 'T': /* a new row group */
- sprintf(conn->errorMessage,
- "makePGresult() -- "
- "is not equipped to handle multiple row groups.\n");
- goto makePGresult_badResponse_return;
- case 'B': /* a row in binary format */
- case 'D': /* a row in ASCII format */
- newTup = getTuple(conn, result, (id == 'B'));
- if (newTup == NULL)
- goto makePGresult_badResponse_return;
- addTuple(result,newTup);
- break;
- case 'C': /* end of portal row stream */
- {
- char command[MAX_MESSAGE_LEN];
- pqGets(command,MAX_MESSAGE_LEN, pfin, pfdebug); /* read command tag */
- done = 1;
- }
- break;
- case 'E': /* errors */
- if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
- sprintf(conn->errorMessage,
- "Error return detected from backend, "
- "but error message cannot be read");
- }
- result->resultStatus = PGRES_FATAL_ERROR;
- return result;
- break;
- case 'N': /* notices from the backend */
- if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
- sprintf(conn->errorMessage,
- "Notice return detected from backend, "
- "but error message cannot be read");
- } else
- /* XXXX send Notices to stderr for now */
- fprintf(stderr, "%s\n", conn->errorMessage);
- break;
- default: /* uh-oh
- this should never happen but frequently does when the
- backend dumps core */
- sprintf(conn->errorMessage,
- "FATAL: unrecognized data from the backend. "
- "It probably dumped core.\n");
- fprintf(stderr, conn->errorMessage);
- result->resultStatus = PGRES_FATAL_ERROR;
- return result;
- break;
- }
- if (!done)
- id = getc(pfin);
- } /* while (1) */
-
- result->resultStatus = PGRES_TUPLES_OK;
- return result;
+ PGresult *result;
+ int id;
+ int nfields;
+ int i;
+ int done = 0;
+
+ PGresAttValue *newTup;
+
+ FILE *pfin = conn->Pfin;
+ FILE *pfdebug = conn->Pfdebug;
+
+ result = makeEmptyPGresult(conn, PGRES_TUPLES_OK);
+
+ /* makePGresult() should only be called when the */
+ /* id of the stream is 'T' to start with */
+
+ /* the next two bytes are the number of fields */
+ if (pqGetInt(&nfields, 2, pfin, pfdebug) == 1)
+ {
+ sprintf(conn->errorMessage,
+ "could not get the number of fields from the 'T' message\n");
+ goto makePGresult_badResponse_return;
+ }
+ else
+ result->numAttributes = nfields;
+
+ /* allocate space for the attribute descriptors */
+ if (nfields > 0)
+ {
+ result->attDescs = (PGresAttDesc *) malloc(nfields * sizeof(PGresAttDesc));
+ }
+
+ /* get type info */
+ for (i = 0; i < nfields; i++)
+ {
+ char typName[MAX_MESSAGE_LEN];
+ int adtid;
+ int adtsize;
+
+ if (pqGets(typName, MAX_MESSAGE_LEN, pfin, pfdebug) ||
+ pqGetInt(&adtid, 4, pfin, pfdebug) ||
+ pqGetInt(&adtsize, 2, pfin, pfdebug))
+ {
+ sprintf(conn->errorMessage,
+ "error reading type information from the 'T' message\n");
+ goto makePGresult_badResponse_return;
+ }
+ result->attDescs[i].name = malloc(strlen(typName) + 1);
+ strcpy(result->attDescs[i].name, typName);
+ result->attDescs[i].adtid = adtid;
+ result->attDescs[i].adtsize = adtsize; /* casting from int to
+ * int2 here */
+ }
+
+ id = pqGetc(pfin, pfdebug);
+
+ /* process the data stream until we're finished */
+ while (!done)
+ {
+ switch (id)
+ {
+ case 'T': /* a new row group */
+ sprintf(conn->errorMessage,
+ "makePGresult() -- "
+ "is not equipped to handle multiple row groups.\n");
+ goto makePGresult_badResponse_return;
+ case 'B': /* a row in binary format */
+ case 'D': /* a row in ASCII format */
+ newTup = getTuple(conn, result, (id == 'B'));
+ if (newTup == NULL)
+ goto makePGresult_badResponse_return;
+ addTuple(result, newTup);
+ break;
+ case 'C': /* end of portal row stream */
+ {
+ char command[MAX_MESSAGE_LEN];
+
+ pqGets(command, MAX_MESSAGE_LEN, pfin, pfdebug); /* read command tag */
+ done = 1;
+ }
+ break;
+ case 'E': /* errors */
+ if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1)
+ {
+ sprintf(conn->errorMessage,
+ "Error return detected from backend, "
+ "but error message cannot be read");
+ }
+ result->resultStatus = PGRES_FATAL_ERROR;
+ return result;
+ break;
+ case 'N': /* notices from the backend */
+ if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1)
+ {
+ sprintf(conn->errorMessage,
+ "Notice return detected from backend, "
+ "but error message cannot be read");
+ }
+ else
+ /* XXXX send Notices to stderr for now */
+ fprintf(stderr, "%s\n", conn->errorMessage);
+ break;
+ default: /* uh-oh this should never happen but
+ * frequently does when the backend dumps
+ * core */
+ sprintf(conn->errorMessage,
+ "FATAL: unrecognized data from the backend. "
+ "It probably dumped core.\n");
+ fprintf(stderr, conn->errorMessage);
+ result->resultStatus = PGRES_FATAL_ERROR;
+ return result;
+ break;
+ }
+ if (!done)
+ id = getc(pfin);
+ } /* while (1) */
+
+ result->resultStatus = PGRES_TUPLES_OK;
+ return result;
makePGresult_badResponse_return:
- result->resultStatus = PGRES_BAD_RESPONSE;
- return result;
+ result->resultStatus = PGRES_BAD_RESPONSE;
+ return result;
}
/*
- * Assuming that we just sent a query to the backend, read the backend's
+ * Assuming that we just sent a query to the backend, read the backend's
* response from stream <pfin> and respond accordingly.
*
* If <pfdebug> is non-null, write to that stream whatever we receive
* (it's a debugging trace).
- *
+ *
* Return as <result> a pointer to a proper final PGresult structure,
* newly allocated, for the query based on the response we get. If the
* response we get indicates that the query didn't execute, return a
@@ -370,450 +406,522 @@ makePGresult_badResponse_return:
*/
static void
-process_response_from_backend(FILE *pfin, FILE *pfout, FILE *pfdebug,
- PGconn *conn,
- PGresult **result_p, char * const reason) {
-
- int id;
- /* The protocol character received from the backend. The protocol
- character is the first character in the backend's response to our
- query. It defines the nature of the response.
- */
- PGnotify *newNotify;
- bool done;
- /* We're all done with the query and ready to return the result. */
- int emptiesSent;
- /* Number of empty queries we have sent in order to flush out multiple
- responses, less the number of corresponding responses we have
- received.
- */
- int errors;
- /* If an error is received, we must still drain out the empty
- queries sent. So we need another flag.
- */
- char cmdStatus[MAX_MESSAGE_LEN];
- char pname[MAX_MESSAGE_LEN]; /* portal name */
-
- /* loop because multiple messages, especially NOTICES,
- can come back from the backend. NOTICES are output directly to stderr
- */
-
- emptiesSent = 0; /* No empty queries sent yet */
- errors = 0; /* No errors received yet */
- pname[0] = '\0';
-
- done = false; /* initial value */
- while (!done) {
- /* read the result id */
- id = pqGetc(pfin, pfdebug);
- if (id == EOF) {
- /* hmm, no response from the backend-end, that's bad */
- (void) sprintf(reason,
- "PQexec() -- Request was sent to backend, but backend "
- "closed the channel before "
- "responding. This probably means the backend "
- "terminated abnormally before or while processing "
- "the request.\n");
- conn->status = CONNECTION_BAD; /* No more connection to backend */
- *result_p = (PGresult*)NULL;
- done = true;
- } else {
- switch (id) {
- case 'A':
- newNotify = (PGnotify*)malloc(sizeof(PGnotify));
- pqGetInt(&(newNotify->be_pid), 4, pfin, pfdebug);
- pqGets(newNotify->relname, NAMEDATALEN, pfin, pfdebug);
- DLAddTail(conn->notifyList, DLNewElem(newNotify));
- /* async messages are piggy'ed back on other messages,
- so we stay in the while loop for other messages */
- break;
- case 'C': /* portal query command, no rows returned */
- if (pqGets(cmdStatus, MAX_MESSAGE_LEN, pfin, pfdebug) == 1) {
- sprintf(reason,
- "PQexec() -- query command completed, "
- "but return message from backend cannot be read.");
- *result_p = (PGresult*)NULL;
- done = true;
- } else {
- /*
- * since backend may produce more than one result for some
- * commands need to poll until clear
- * send an empty query down, and keep reading out of the pipe
- * until an 'I' is received.
- */
- pqPuts("Q ", pfout, pfdebug); /* send an empty query */
- /*
- * Increment a flag and process messages in the usual way because
- * there may be async notifications pending. DZ - 31-8-1996
- */
- emptiesSent++;
- }
- break;
- case 'E': /* error return */
- if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
- (void) sprintf(reason,
- "PQexec() -- error return detected from backend, "
- "but attempt to read the error message failed.");
- }
- *result_p = (PGresult*)NULL;
- errors++;
- if (emptiesSent == 0) {
- done = true;
- }
- break;
- case 'I': { /* empty query */
- /* read and throw away the closing '\0' */
- int c;
- if ((c = pqGetc(pfin,pfdebug)) != '\0') {
- fprintf(stderr,"error!, unexpected character %c following 'I'\n", c);
- }
- if (emptiesSent) {
- if (--emptiesSent == 0) { /* is this the last one? */
- /*
- * If this is the result of a portal query command set the
- * command status and message accordingly. DZ - 31-8-1996
- */
- if (!errors) {
- *result_p = makeEmptyPGresult(conn,PGRES_COMMAND_OK);
- strncpy((*result_p)->cmdStatus, cmdStatus, CMDSTATUS_LEN-1);
- } else {
- *result_p = (PGresult*)NULL;
- }
- done = true;
- }
- }
- else {
- if (!errors) {
- *result_p = makeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
- } else {
- *result_p = (PGresult*)NULL;
- }
- done = true;
- }
- }
- break;
- case 'N': /* notices from the backend */
- if (pqGets(reason, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
- sprintf(reason,
- "PQexec() -- Notice detected from backend, "
- "but attempt to read the notice failed.");
- *result_p = (PGresult*)NULL;
- done = true;
- } else
- /* Should we really be doing this? These notices are not important
- enough for us to presume to put them on stderr. Maybe the caller
- should decide whether to put them on stderr or not. BJH 96.12.27
- */
- fprintf(stderr,"%s", reason);
- break;
- case 'P': /* synchronous (normal) portal */
- pqGets(pname, MAX_MESSAGE_LEN, pfin, pfdebug); /* read in portal name*/
- break;
- case 'T': /* actual row results: */
- *result_p = makePGresult(conn, pname);
- done = true;
- break;
- case 'D': /* copy command began successfully */
- *result_p = makeEmptyPGresult(conn, PGRES_COPY_IN);
- done = true;
- break;
- case 'B': /* copy command began successfully */
- *result_p = makeEmptyPGresult(conn, PGRES_COPY_OUT);
- done = true;
- break;
- default:
- sprintf(reason,
- "unknown protocol character '%c' read from backend. "
- "(The protocol character is the first character the "
- "backend sends in response to a query it receives).\n",
- id);
- *result_p = (PGresult*)NULL;
- done = true;
- } /* switch on protocol character */
- } /* if character was received */
- } /* while not done */
+process_response_from_backend(FILE * pfin, FILE * pfout, FILE * pfdebug,
+ PGconn * conn,
+ PGresult ** result_p, char *const reason)
+{
+
+ int id;
+
+ /*
+ * The protocol character received from the backend. The protocol
+ * character is the first character in the backend's response to our
+ * query. It defines the nature of the response.
+ */
+ PGnotify *newNotify;
+ bool done;
+
+ /* We're all done with the query and ready to return the result. */
+ int emptiesSent;
+
+ /*
+ * Number of empty queries we have sent in order to flush out multiple
+ * responses, less the number of corresponding responses we have
+ * received.
+ */
+ int errors;
+
+ /*
+ * If an error is received, we must still drain out the empty queries
+ * sent. So we need another flag.
+ */
+ char cmdStatus[MAX_MESSAGE_LEN];
+ char pname[MAX_MESSAGE_LEN]; /* portal name */
+
+ /*
+ * loop because multiple messages, especially NOTICES, can come back
+ * from the backend. NOTICES are output directly to stderr
+ */
+
+ emptiesSent = 0; /* No empty queries sent yet */
+ errors = 0; /* No errors received yet */
+ pname[0] = '\0';
+
+ done = false; /* initial value */
+ while (!done)
+ {
+ /* read the result id */
+ id = pqGetc(pfin, pfdebug);
+ if (id == EOF)
+ {
+ /* hmm, no response from the backend-end, that's bad */
+ (void) sprintf(reason,
+ "PQexec() -- Request was sent to backend, but backend "
+ "closed the channel before "
+ "responding. This probably means the backend "
+ "terminated abnormally before or while processing "
+ "the request.\n");
+ conn->status = CONNECTION_BAD; /* No more connection to
+ * backend */
+ *result_p = (PGresult *) NULL;
+ done = true;
+ }
+ else
+ {
+ switch (id)
+ {
+ case 'A':
+ newNotify = (PGnotify *) malloc(sizeof(PGnotify));
+ pqGetInt(&(newNotify->be_pid), 4, pfin, pfdebug);
+ pqGets(newNotify->relname, NAMEDATALEN, pfin, pfdebug);
+ DLAddTail(conn->notifyList, DLNewElem(newNotify));
+
+ /*
+ * async messages are piggy'ed back on other messages, so
+ * we stay in the while loop for other messages
+ */
+ break;
+ case 'C': /* portal query command, no rows returned */
+ if (pqGets(cmdStatus, MAX_MESSAGE_LEN, pfin, pfdebug) == 1)
+ {
+ sprintf(reason,
+ "PQexec() -- query command completed, "
+ "but return message from backend cannot be read.");
+ *result_p = (PGresult *) NULL;
+ done = true;
+ }
+ else
+ {
+
+ /*
+ * since backend may produce more than one result for
+ * some commands need to poll until clear send an
+ * empty query down, and keep reading out of the pipe
+ * until an 'I' is received.
+ */
+ pqPuts("Q ", pfout, pfdebug); /* send an empty query */
+
+ /*
+ * Increment a flag and process messages in the usual
+ * way because there may be async notifications
+ * pending. DZ - 31-8-1996
+ */
+ emptiesSent++;
+ }
+ break;
+ case 'E': /* error return */
+ if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1)
+ {
+ (void) sprintf(reason,
+ "PQexec() -- error return detected from backend, "
+ "but attempt to read the error message failed.");
+ }
+ *result_p = (PGresult *) NULL;
+ errors++;
+ if (emptiesSent == 0)
+ {
+ done = true;
+ }
+ break;
+ case 'I':
+ { /* empty query */
+ /* read and throw away the closing '\0' */
+ int c;
+
+ if ((c = pqGetc(pfin, pfdebug)) != '\0')
+ {
+ fprintf(stderr, "error!, unexpected character %c following 'I'\n", c);
+ }
+ if (emptiesSent)
+ {
+ if (--emptiesSent == 0)
+ { /* is this the last one? */
+
+ /*
+ * If this is the result of a portal query
+ * command set the command status and message
+ * accordingly. DZ - 31-8-1996
+ */
+ if (!errors)
+ {
+ *result_p = makeEmptyPGresult(conn, PGRES_COMMAND_OK);
+ strncpy((*result_p)->cmdStatus, cmdStatus, CMDSTATUS_LEN - 1);
+ }
+ else
+ {
+ *result_p = (PGresult *) NULL;
+ }
+ done = true;
+ }
+ }
+ else
+ {
+ if (!errors)
+ {
+ *result_p = makeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
+ }
+ else
+ {
+ *result_p = (PGresult *) NULL;
+ }
+ done = true;
+ }
+ }
+ break;
+ case 'N': /* notices from the backend */
+ if (pqGets(reason, ERROR_MSG_LENGTH, pfin, pfdebug) == 1)
+ {
+ sprintf(reason,
+ "PQexec() -- Notice detected from backend, "
+ "but attempt to read the notice failed.");
+ *result_p = (PGresult *) NULL;
+ done = true;
+ }
+ else
+
+ /*
+ * Should we really be doing this? These notices are
+ * not important enough for us to presume to put them
+ * on stderr. Maybe the caller should decide whether
+ * to put them on stderr or not. BJH 96.12.27
+ */
+ fprintf(stderr, "%s", reason);
+ break;
+ case 'P': /* synchronous (normal) portal */
+ pqGets(pname, MAX_MESSAGE_LEN, pfin, pfdebug); /* read in portal name */
+ break;
+ case 'T': /* actual row results: */
+ *result_p = makePGresult(conn, pname);
+ done = true;
+ break;
+ case 'D': /* copy command began successfully */
+ *result_p = makeEmptyPGresult(conn, PGRES_COPY_IN);
+ done = true;
+ break;
+ case 'B': /* copy command began successfully */
+ *result_p = makeEmptyPGresult(conn, PGRES_COPY_OUT);
+ done = true;
+ break;
+ default:
+ sprintf(reason,
+ "unknown protocol character '%c' read from backend. "
+ "(The protocol character is the first character the "
+ "backend sends in response to a query it receives).\n",
+ id);
+ *result_p = (PGresult *) NULL;
+ done = true;
+ } /* switch on protocol character */
+ } /* if character was received */
+ } /* while not done */
}
/*
* PQexec
- * send a query to the backend and package up the result in a Pgresult
+ * send a query to the backend and package up the result in a Pgresult
*
- * if the query failed, return NULL, conn->errorMessage is set to
+ * if the query failed, return NULL, conn->errorMessage is set to
* a relevant message
- * if query is successful, a new PGresult is returned
+ * if query is successful, a new PGresult is returned
* the use is responsible for freeing that structure when done with it
*
*/
-PGresult*
-PQexec(PGconn* conn, const char* query)
+PGresult *
+PQexec(PGconn * conn, const char *query)
{
- PGresult *result;
- char buffer[MAX_MESSAGE_LEN];
-
- if (!conn) return NULL;
- if (!query) {
- sprintf(conn->errorMessage, "PQexec() -- query pointer is null.");
- return NULL;
- }
-
- /*clear the error string */
- conn->errorMessage[0] = '\0';
-
- /* check to see if the query string is too long */
- if (strlen(query) > MAX_MESSAGE_LEN) {
- sprintf(conn->errorMessage, "PQexec() -- query is too long. "
- "Maximum length is %d\n", MAX_MESSAGE_LEN -2 );
- return NULL;
- }
-
- /* Don't try to send if we know there's no live connection. */
- if (conn->status != CONNECTION_OK) {
- sprintf(conn->errorMessage, "PQexec() -- There is no connection "
- "to the backend.\n");
- return NULL;
- }
-
- /* the frontend-backend protocol uses 'Q' to designate queries */
- sprintf(buffer,"Q%s",query);
-
- /* send the query to the backend; */
- if (pqPuts(buffer, conn->Pfout, conn->Pfdebug) == 1) {
- (void) sprintf(conn->errorMessage,
- "PQexec() -- while sending query: %s\n"
- "-- fprintf to Pfout failed: errno=%d\n%s\n",
- query, errno, strerror(errno));
- return NULL;
- }
-
- process_response_from_backend(conn->Pfin, conn->Pfout, conn->Pfdebug, conn,
- &result, conn->errorMessage);
- return(result);
+ PGresult *result;
+ char buffer[MAX_MESSAGE_LEN];
+
+ if (!conn)
+ return NULL;
+ if (!query)
+ {
+ sprintf(conn->errorMessage, "PQexec() -- query pointer is null.");
+ return NULL;
+ }
+
+ /* clear the error string */
+ conn->errorMessage[0] = '\0';
+
+ /* check to see if the query string is too long */
+ if (strlen(query) > MAX_MESSAGE_LEN)
+ {
+ sprintf(conn->errorMessage, "PQexec() -- query is too long. "
+ "Maximum length is %d\n", MAX_MESSAGE_LEN - 2);
+ return NULL;
+ }
+
+ /* Don't try to send if we know there's no live connection. */
+ if (conn->status != CONNECTION_OK)
+ {
+ sprintf(conn->errorMessage, "PQexec() -- There is no connection "
+ "to the backend.\n");
+ return NULL;
+ }
+
+ /* the frontend-backend protocol uses 'Q' to designate queries */
+ sprintf(buffer, "Q%s", query);
+
+ /* send the query to the backend; */
+ if (pqPuts(buffer, conn->Pfout, conn->Pfdebug) == 1)
+ {
+ (void) sprintf(conn->errorMessage,
+ "PQexec() -- while sending query: %s\n"
+ "-- fprintf to Pfout failed: errno=%d\n%s\n",
+ query, errno, strerror(errno));
+ return NULL;
+ }
+
+ process_response_from_backend(conn->Pfin, conn->Pfout, conn->Pfdebug, conn,
+ &result, conn->errorMessage);
+ return (result);
}
/*
* PQnotifies
- * returns a PGnotify* structure of the latest async notification
+ * returns a PGnotify* structure of the latest async notification
* that has not yet been handled
*
- * returns NULL, if there is currently
+ * returns NULL, if there is currently
* no unhandled async notification from the backend
*
* the CALLER is responsible for FREE'ing the structure returned
*/
-PGnotify*
-PQnotifies(PGconn *conn)
+PGnotify *
+PQnotifies(PGconn * conn)
{
- Dlelem *e;
-
- if (!conn) return NULL;
-
- if (conn->status != CONNECTION_OK)
- return NULL;
- /* RemHead returns NULL if list is empy */
- e = DLRemHead(conn->notifyList);
- if (e)
- return (PGnotify*)DLE_VAL(e);
- else
- return NULL;
+ Dlelem *e;
+
+ if (!conn)
+ return NULL;
+
+ if (conn->status != CONNECTION_OK)
+ return NULL;
+ /* RemHead returns NULL if list is empy */
+ e = DLRemHead(conn->notifyList);
+ if (e)
+ return (PGnotify *) DLE_VAL(e);
+ else
+ return NULL;
}
/*
* PQgetline - gets a newline-terminated string from the backend.
- *
+ *
* Chiefly here so that applications can use "COPY <rel> to stdout"
- * and read the output string. Returns a null-terminated string in s.
+ * and read the output string. Returns a null-terminated string in s.
*
* PQgetline reads up to maxlen-1 characters (like fgets(3)) but strips
* the terminating \n (like gets(3)).
*
* RETURNS:
- * EOF if it is detected or invalid arguments are given
- * 0 if EOL is reached (i.e., \n has been read)
- * (this is required for backward-compatibility -- this
- * routine used to always return EOF or 0, assuming that
- * the line ended within maxlen bytes.)
- * 1 in other cases
+ * EOF if it is detected or invalid arguments are given
+ * 0 if EOL is reached (i.e., \n has been read)
+ * (this is required for backward-compatibility -- this
+ * routine used to always return EOF or 0, assuming that
+ * the line ended within maxlen bytes.)
+ * 1 in other cases
*/
int
-PQgetline(PGconn *conn, char *s, int maxlen)
+PQgetline(PGconn * conn, char *s, int maxlen)
{
- int c = '\0';
-
- if (!conn) return EOF;
-
- if (!conn->Pfin || !s || maxlen <= 1)
- return(EOF);
-
- for (; maxlen > 1 &&
- (c = pqGetc(conn->Pfin, conn->Pfdebug)) != '\n' &&
- c != EOF;
- --maxlen) {
- *s++ = c;
- }
- *s = '\0';
-
- if (c == EOF) {
- return(EOF); /* error -- reached EOF before \n */
- } else if (c == '\n') {
- return(0); /* done with this line */
- }
- return(1); /* returning a full buffer */
+ int c = '\0';
+
+ if (!conn)
+ return EOF;
+
+ if (!conn->Pfin || !s || maxlen <= 1)
+ return (EOF);
+
+ for (; maxlen > 1 &&
+ (c = pqGetc(conn->Pfin, conn->Pfdebug)) != '\n' &&
+ c != EOF;
+ --maxlen)
+ {
+ *s++ = c;
+ }
+ *s = '\0';
+
+ if (c == EOF)
+ {
+ return (EOF); /* error -- reached EOF before \n */
+ }
+ else if (c == '\n')
+ {
+ return (0); /* done with this line */
+ }
+ return (1); /* returning a full buffer */
}
/*
* PQputline -- sends a string to the backend.
- *
+ *
* Chiefly here so that applications can use "COPY <rel> from stdin".
*
*/
void
-PQputline(PGconn *conn, const char *s)
+PQputline(PGconn * conn, const char *s)
{
- if (conn && (conn->Pfout)) {
- (void) fputs(s, conn->Pfout);
- fflush(conn->Pfout);
- }
+ if (conn && (conn->Pfout))
+ {
+ (void) fputs(s, conn->Pfout);
+ fflush(conn->Pfout);
+ }
}
/*
* PQendcopy
- * called while waiting for the backend to respond with success/failure
- * to a "copy".
+ * called while waiting for the backend to respond with success/failure
+ * to a "copy".
*
* RETURNS:
- * 0 on success
- * 1 on failure
+ * 0 on success
+ * 1 on failure
*/
int
-PQendcopy(PGconn *conn)
+PQendcopy(PGconn * conn)
{
- FILE *pfin, *pfdebug;
- bool valid = true;
-
- if (!conn) return (int)NULL;
-
- pfin = conn->Pfin;
- pfdebug = conn->Pfdebug;
-
- if ( pqGetc(pfin,pfdebug) == 'C')
- {
- char command[MAX_MESSAGE_LEN];
- pqGets(command,MAX_MESSAGE_LEN, pfin, pfdebug); /* read command tag */
- }
- else valid = false;
-
- if ( valid )
- return (0);
- else {
- sprintf(conn->errorMessage,
- "Error return detected from backend, "
- "but attempt to read the message failed.");
- fprintf(stderr,"resetting connection\n");
- PQreset(conn);
- return(1);
- }
+ FILE *pfin,
+ *pfdebug;
+ bool valid = true;
+
+ if (!conn)
+ return (int) NULL;
+
+ pfin = conn->Pfin;
+ pfdebug = conn->Pfdebug;
+
+ if (pqGetc(pfin, pfdebug) == 'C')
+ {
+ char command[MAX_MESSAGE_LEN];
+
+ pqGets(command, MAX_MESSAGE_LEN, pfin, pfdebug); /* read command tag */
+ }
+ else
+ valid = false;
+
+ if (valid)
+ return (0);
+ else
+ {
+ sprintf(conn->errorMessage,
+ "Error return detected from backend, "
+ "but attempt to read the message failed.");
+ fprintf(stderr, "resetting connection\n");
+ PQreset(conn);
+ return (1);
+ }
}
/* simply send out max-length number of filler characters to fp */
static void
-fill (int length, int max, char filler, FILE *fp)
+fill(int length, int max, char filler, FILE * fp)
{
- int count;
- char filltmp[2];
-
- filltmp[0] = filler;
- filltmp[1] = 0;
- count = max - length;
- while (count-- >= 0)
- {
- fprintf(fp, "%s", filltmp);
- }
- }
+ int count;
+ char filltmp[2];
+
+ filltmp[0] = filler;
+ filltmp[1] = 0;
+ count = max - length;
+ while (count-- >= 0)
+ {
+ fprintf(fp, "%s", filltmp);
+ }
+}
/*
* PQdisplayTuples()
* kept for backward compatibility
*/
void
-PQdisplayTuples(PGresult *res,
- FILE *fp, /* where to send the output */
- int fillAlign, /* pad the fields with spaces */
- const char *fieldSep, /* field separator */
- int printHeader, /* display headers? */
- int quiet
- )
+PQdisplayTuples(PGresult * res,
+ FILE * fp, /* where to send the output */
+ int fillAlign, /* pad the fields with spaces */
+ const char *fieldSep, /* field separator */
+ int printHeader,/* display headers? */
+ int quiet
+)
{
#define DEFAULT_FIELD_SEP " "
- int i, j;
- int nFields;
- int nTuples;
- int fLength[MAX_FIELDS];
-
- if (fieldSep == NULL)
- fieldSep = DEFAULT_FIELD_SEP;
-
- /* Get some useful info about the results */
- nFields = PQnfields(res);
- nTuples = PQntuples(res);
-
- if (fp == NULL)
- fp = stdout;
-
- /* Zero the initial field lengths */
- for (j=0 ; j < nFields; j++) {
- fLength[j] = strlen(PQfname(res,j));
- }
- /* Find the max length of each field in the result */
- /* will be somewhat time consuming for very large results */
- if (fillAlign) {
- for (i=0; i < nTuples; i++) {
- for (j=0 ; j < nFields; j++) {
- if (PQgetlength(res,i,j) > fLength[j])
- fLength[j] = PQgetlength(res,i,j);
- }
- }
- }
-
- if (printHeader) {
- /* first, print out the attribute names */
- for (i=0; i < nFields; i++) {
- fputs(PQfname(res,i), fp);
- if (fillAlign)
- fill (strlen (PQfname(res,i)), fLength[i], ' ', fp);
- fputs(fieldSep,fp);
- }
- fprintf(fp, "\n");
-
- /* Underline the attribute names */
- for (i=0; i < nFields; i++) {
- if (fillAlign)
- fill (0, fLength[i], '-', fp);
- fputs(fieldSep,fp);
- }
- fprintf(fp, "\n");
- }
-
- /* next, print out the instances */
- for (i=0; i < nTuples; i++) {
- for (j=0 ; j < nFields; j++) {
- fprintf(fp, "%s", PQgetvalue(res,i,j));
- if (fillAlign)
- fill (strlen (PQgetvalue(res,i,j)), fLength[j], ' ', fp);
- fputs(fieldSep,fp);
- }
- fprintf(fp, "\n");
- }
-
- if (!quiet)
- fprintf (fp, "\nQuery returned %d row%s.\n",PQntuples(res),
- (PQntuples(res) == 1) ? "" : "s");
-
- fflush(fp);
+ int i,
+ j;
+ int nFields;
+ int nTuples;
+ int fLength[MAX_FIELDS];
+
+ if (fieldSep == NULL)
+ fieldSep = DEFAULT_FIELD_SEP;
+
+ /* Get some useful info about the results */
+ nFields = PQnfields(res);
+ nTuples = PQntuples(res);
+
+ if (fp == NULL)
+ fp = stdout;
+
+ /* Zero the initial field lengths */
+ for (j = 0; j < nFields; j++)
+ {
+ fLength[j] = strlen(PQfname(res, j));
+ }
+ /* Find the max length of each field in the result */
+ /* will be somewhat time consuming for very large results */
+ if (fillAlign)
+ {
+ for (i = 0; i < nTuples; i++)
+ {
+ for (j = 0; j < nFields; j++)
+ {
+ if (PQgetlength(res, i, j) > fLength[j])
+ fLength[j] = PQgetlength(res, i, j);
+ }
+ }
+ }
+
+ if (printHeader)
+ {
+ /* first, print out the attribute names */
+ for (i = 0; i < nFields; i++)
+ {
+ fputs(PQfname(res, i), fp);
+ if (fillAlign)
+ fill(strlen(PQfname(res, i)), fLength[i], ' ', fp);
+ fputs(fieldSep, fp);
+ }
+ fprintf(fp, "\n");
+
+ /* Underline the attribute names */
+ for (i = 0; i < nFields; i++)
+ {
+ if (fillAlign)
+ fill(0, fLength[i], '-', fp);
+ fputs(fieldSep, fp);
+ }
+ fprintf(fp, "\n");
+ }
+
+ /* next, print out the instances */
+ for (i = 0; i < nTuples; i++)
+ {
+ for (j = 0; j < nFields; j++)
+ {
+ fprintf(fp, "%s", PQgetvalue(res, i, j));
+ if (fillAlign)
+ fill(strlen(PQgetvalue(res, i, j)), fLength[j], ' ', fp);
+ fputs(fieldSep, fp);
+ }
+ fprintf(fp, "\n");
+ }
+
+ if (!quiet)
+ fprintf(fp, "\nQuery returned %d row%s.\n", PQntuples(res),
+ (PQntuples(res) == 1) ? "" : "s");
+
+ fflush(fp);
}
@@ -825,260 +933,311 @@ PQdisplayTuples(PGresult *res,
*
*/
void
-PQprintTuples(PGresult *res,
- FILE* fout, /* output stream */
- int PrintAttNames,/* print attribute names or not*/
- int TerseOutput, /* delimiter bars or not?*/
- int colWidth /* width of column, if 0, use variable width */
- )
+PQprintTuples(PGresult * res,
+ FILE * fout, /* output stream */
+ int PrintAttNames,/* print attribute names or not */
+ int TerseOutput, /* delimiter bars or not? */
+ int colWidth /* width of column, if 0, use variable
+ * width */
+)
{
- int nFields;
- int nTups;
- int i,j;
- char formatString[80];
-
- char *tborder = NULL;
-
- nFields = PQnfields(res);
- nTups = PQntuples(res);
-
- if (colWidth > 0) {
- sprintf(formatString,"%%s %%-%ds",colWidth);
- } else
- sprintf(formatString,"%%s %%s");
-
- if ( nFields > 0 ) { /* only print rows with at least 1 field. */
-
- if (!TerseOutput)
- {
- int width;
- width = nFields * 14;
- tborder = malloc (width+1);
- for (i = 0; i <= width; i++)
- tborder[i] = '-';
- tborder[i] = '\0';
- fprintf(fout,"%s\n",tborder);
- }
-
- for (i=0; i < nFields; i++) {
- if (PrintAttNames) {
- fprintf(fout,formatString,
- TerseOutput ? "" : "|",
- PQfname(res, i));
- }
- }
-
- if (PrintAttNames) {
- if (TerseOutput)
- fprintf(fout,"\n");
- else
- fprintf(fout, "|\n%s\n",tborder);
- }
-
- for (i = 0; i < nTups; i++) {
- for (j = 0; j < nFields; j++) {
- char *pval = PQgetvalue(res,i,j);
- fprintf(fout, formatString,
- TerseOutput ? "" : "|",
- pval ? pval : "");
- }
- if (TerseOutput)
- fprintf(fout,"\n");
- else
- fprintf(fout, "|\n%s\n",tborder);
- }
- }
+ int nFields;
+ int nTups;
+ int i,
+ j;
+ char formatString[80];
+
+ char *tborder = NULL;
+
+ nFields = PQnfields(res);
+ nTups = PQntuples(res);
+
+ if (colWidth > 0)
+ {
+ sprintf(formatString, "%%s %%-%ds", colWidth);
+ }
+ else
+ sprintf(formatString, "%%s %%s");
+
+ if (nFields > 0)
+ { /* only print rows with at least 1 field. */
+
+ if (!TerseOutput)
+ {
+ int width;
+
+ width = nFields * 14;
+ tborder = malloc(width + 1);
+ for (i = 0; i <= width; i++)
+ tborder[i] = '-';
+ tborder[i] = '\0';
+ fprintf(fout, "%s\n", tborder);
+ }
+
+ for (i = 0; i < nFields; i++)
+ {
+ if (PrintAttNames)
+ {
+ fprintf(fout, formatString,
+ TerseOutput ? "" : "|",
+ PQfname(res, i));
+ }
+ }
+
+ if (PrintAttNames)
+ {
+ if (TerseOutput)
+ fprintf(fout, "\n");
+ else
+ fprintf(fout, "|\n%s\n", tborder);
+ }
+
+ for (i = 0; i < nTups; i++)
+ {
+ for (j = 0; j < nFields; j++)
+ {
+ char *pval = PQgetvalue(res, i, j);
+
+ fprintf(fout, formatString,
+ TerseOutput ? "" : "|",
+ pval ? pval : "");
+ }
+ if (TerseOutput)
+ fprintf(fout, "\n");
+ else
+ fprintf(fout, "|\n%s\n", tborder);
+ }
+ }
}
static void
-do_field(PQprintOpt *po, PGresult *res,
- const int i, const int j, char *buf, const int fs_len,
- char *fields[],
- const int nFields, char *fieldNames[],
- unsigned char fieldNotNum[], int fieldMax[],
- const int fieldMaxLen, FILE *fout
- ) {
-
- char *pval, *p, *o;
- int plen;
- bool skipit;
-
- plen=PQgetlength(res,i,j);
- pval=PQgetvalue(res,i,j);
-
- if (plen < 1 || !pval || !*pval) {
- if (po->align || po->expanded) skipit = true;
- else {
- skipit = false;
- goto efield;
- }
- } else skipit = false;
-
- if (!skipit) {
- for (p=pval, o=buf; *p; *(o++)=*(p++)) {
- if ((fs_len==1 && (*p==*(po->fieldSep))) || *p=='\\' || *p=='\n')
- *(o++)='\\';
- if (po->align && (*pval=='E' || *pval=='e' ||
- !((*p>='0' && *p<='9') ||
- *p=='.' ||
- *p=='E' ||
- *p=='e' ||
- *p==' ' ||
- *p=='-')))
- fieldNotNum[j]=1;
- }
- *o='\0';
- if (!po->expanded && (po->align || po->html3)) {
- int n=strlen(buf);
- if (n>fieldMax[j])
- fieldMax[j]=n;
- if (!(fields[i*nFields+j]=(char *)malloc(n+1))) {
- perror("malloc");
- exit(1);
- }
- strcpy(fields[i*nFields+j], buf);
- } else {
- if (po->expanded) {
- if (po->html3)
- fprintf(fout,
- "<tr><td align=left><b>%s</b></td>"
- "<td align=%s>%s</td></tr>\n",
- fieldNames[j],
- fieldNotNum[j] ? "left": "right",
- buf);
- else {
- if (po->align)
- fprintf(fout,
- "%-*s%s %s\n",
- fieldMaxLen-fs_len, fieldNames[j], po->fieldSep,
- buf);
- else
- fprintf(fout, "%s%s%s\n", fieldNames[j], po->fieldSep, buf);
- }
- } else {
- if (!po->html3) {
- fputs(buf, fout);
- efield:
- if ((j+1)<nFields)
- fputs(po->fieldSep, fout);
- else
- fputc('\n', fout);
- }
- }
- }
- }
+do_field(PQprintOpt * po, PGresult * res,
+ const int i, const int j, char *buf, const int fs_len,
+ char *fields[],
+ const int nFields, char *fieldNames[],
+ unsigned char fieldNotNum[], int fieldMax[],
+ const int fieldMaxLen, FILE * fout
+)
+{
+
+ char *pval,
+ *p,
+ *o;
+ int plen;
+ bool skipit;
+
+ plen = PQgetlength(res, i, j);
+ pval = PQgetvalue(res, i, j);
+
+ if (plen < 1 || !pval || !*pval)
+ {
+ if (po->align || po->expanded)
+ skipit = true;
+ else
+ {
+ skipit = false;
+ goto efield;
+ }
+ }
+ else
+ skipit = false;
+
+ if (!skipit)
+ {
+ for (p = pval, o = buf; *p; *(o++) = *(p++))
+ {
+ if ((fs_len == 1 && (*p == *(po->fieldSep))) || *p == '\\' || *p == '\n')
+ *(o++) = '\\';
+ if (po->align && (*pval == 'E' || *pval == 'e' ||
+ !((*p >= '0' && *p <= '9') ||
+ *p == '.' ||
+ *p == 'E' ||
+ *p == 'e' ||
+ *p == ' ' ||
+ *p == '-')))
+ fieldNotNum[j] = 1;
+ }
+ *o = '\0';
+ if (!po->expanded && (po->align || po->html3))
+ {
+ int n = strlen(buf);
+
+ if (n > fieldMax[j])
+ fieldMax[j] = n;
+ if (!(fields[i * nFields + j] = (char *) malloc(n + 1)))
+ {
+ perror("malloc");
+ exit(1);
+ }
+ strcpy(fields[i * nFields + j], buf);
+ }
+ else
+ {
+ if (po->expanded)
+ {
+ if (po->html3)
+ fprintf(fout,
+ "<tr><td align=left><b>%s</b></td>"
+ "<td align=%s>%s</td></tr>\n",
+ fieldNames[j],
+ fieldNotNum[j] ? "left" : "right",
+ buf);
+ else
+ {
+ if (po->align)
+ fprintf(fout,
+ "%-*s%s %s\n",
+ fieldMaxLen - fs_len, fieldNames[j], po->fieldSep,
+ buf);
+ else
+ fprintf(fout, "%s%s%s\n", fieldNames[j], po->fieldSep, buf);
+ }
+ }
+ else
+ {
+ if (!po->html3)
+ {
+ fputs(buf, fout);
+ efield:
+ if ((j + 1) < nFields)
+ fputs(po->fieldSep, fout);
+ else
+ fputc('\n', fout);
+ }
+ }
+ }
+ }
}
-static char*
-do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[],
- char *fieldNames[], unsigned char fieldNotNum[],
- const int fs_len, PGresult *res) {
-
- int j; /* for loop index */
- char *border=NULL;
-
- if (po->html3)
- fputs("<tr>", fout);
- else {
- int j; /* for loop index */
- int tot=0;
- int n=0;
- char *p=NULL;
- for (; n < nFields; n++)
- tot+=fieldMax[n]+fs_len+(po->standard? 2: 0);
- if (po->standard)
- tot+=fs_len*2+2;
- border=malloc(tot+1);
- if (!border) {
- perror("malloc");
- exit(1);
- }
- p=border;
- if (po->standard) {
- char *fs=po->fieldSep;
- while (*fs++)
- *p++='+';
- }
- for (j=0; j < nFields; j++) {
- int len;
- for (len=fieldMax[j] + (po->standard? 2:0) ; len--; *p++='-');
- if (po->standard || (j+1)<nFields) {
- char *fs=po->fieldSep;
- while (*fs++)
- *p++='+';
- }
- }
- *p='\0';
- if (po->standard)
- fprintf(fout, "%s\n", border);
- }
- if (po->standard)
- fputs(po->fieldSep, fout);
- for (j=0; j < nFields; j++) {
- char *s=PQfname(res, j);
- if (po->html3) {
- fprintf(fout, "<th align=%s>%s</th>",
- fieldNotNum[j]? "left": "right", fieldNames[j]);
- } else {
- int n=strlen(s);
- if (n>fieldMax[j])
- fieldMax[j]=n;
- if (po->standard)
- fprintf(fout,
- fieldNotNum[j] ? " %-*s ": " %*s ",
- fieldMax[j], s);
- else
- fprintf(fout, fieldNotNum[j] ? "%-*s": "%*s", fieldMax[j], s);
- if (po->standard || (j+1)<nFields)
- fputs(po->fieldSep, fout);
- }
- }
- if (po->html3)
- fputs("</tr>\n", fout);
- else
- fprintf(fout, "\n%s\n", border);
- return border;
+static char *
+do_header(FILE * fout, PQprintOpt * po, const int nFields, int fieldMax[],
+ char *fieldNames[], unsigned char fieldNotNum[],
+ const int fs_len, PGresult * res)
+{
+
+ int j; /* for loop index */
+ char *border = NULL;
+
+ if (po->html3)
+ fputs("<tr>", fout);
+ else
+ {
+ int j; /* for loop index */
+ int tot = 0;
+ int n = 0;
+ char *p = NULL;
+
+ for (; n < nFields; n++)
+ tot += fieldMax[n] + fs_len + (po->standard ? 2 : 0);
+ if (po->standard)
+ tot += fs_len * 2 + 2;
+ border = malloc(tot + 1);
+ if (!border)
+ {
+ perror("malloc");
+ exit(1);
+ }
+ p = border;
+ if (po->standard)
+ {
+ char *fs = po->fieldSep;
+
+ while (*fs++)
+ *p++ = '+';
+ }
+ for (j = 0; j < nFields; j++)
+ {
+ int len;
+
+ for (len = fieldMax[j] + (po->standard ? 2 : 0); len--; *p++ = '-');
+ if (po->standard || (j + 1) < nFields)
+ {
+ char *fs = po->fieldSep;
+
+ while (*fs++)
+ *p++ = '+';
+ }
+ }
+ *p = '\0';
+ if (po->standard)
+ fprintf(fout, "%s\n", border);
+ }
+ if (po->standard)
+ fputs(po->fieldSep, fout);
+ for (j = 0; j < nFields; j++)
+ {
+ char *s = PQfname(res, j);
+
+ if (po->html3)
+ {
+ fprintf(fout, "<th align=%s>%s</th>",
+ fieldNotNum[j] ? "left" : "right", fieldNames[j]);
+ }
+ else
+ {
+ int n = strlen(s);
+
+ if (n > fieldMax[j])
+ fieldMax[j] = n;
+ if (po->standard)
+ fprintf(fout,
+ fieldNotNum[j] ? " %-*s " : " %*s ",
+ fieldMax[j], s);
+ else
+ fprintf(fout, fieldNotNum[j] ? "%-*s" : "%*s", fieldMax[j], s);
+ if (po->standard || (j + 1) < nFields)
+ fputs(po->fieldSep, fout);
+ }
+ }
+ if (po->html3)
+ fputs("</tr>\n", fout);
+ else
+ fprintf(fout, "\n%s\n", border);
+ return border;
}
static void
-output_row(FILE *fout, PQprintOpt *po, const int nFields, char *fields[],
- unsigned char fieldNotNum[], int fieldMax[], char *border,
- const int row_index) {
-
- int field_index; /* for loop index */
-
- if (po->html3)
- fputs("<tr>", fout);
- else if (po->standard)
- fputs(po->fieldSep, fout);
- for (field_index = 0; field_index < nFields; field_index++) {
- char *p=fields[row_index*nFields+field_index];
- if (po->html3)
- fprintf(fout, "<td align=%s>%s</td>",
- fieldNotNum[field_index]? "left": "right", p? p: "");
- else {
- fprintf(fout,
- fieldNotNum[field_index] ?
- (po->standard ? " %-*s ": "%-*s") :
- (po->standard ? " %*s ": "%*s"),
- fieldMax[field_index],
- p ? p: "");
- if (po->standard || field_index+1 < nFields)
- fputs(po->fieldSep, fout);
- }
- if (p)
- free(p);
- }
- if (po->html3)
- fputs("</tr>", fout);
- else
- if (po->standard)
- fprintf(fout, "\n%s", border);
- fputc('\n', fout);
+output_row(FILE * fout, PQprintOpt * po, const int nFields, char *fields[],
+ unsigned char fieldNotNum[], int fieldMax[], char *border,
+ const int row_index)
+{
+
+ int field_index;/* for loop index */
+
+ if (po->html3)
+ fputs("<tr>", fout);
+ else if (po->standard)
+ fputs(po->fieldSep, fout);
+ for (field_index = 0; field_index < nFields; field_index++)
+ {
+ char *p = fields[row_index * nFields + field_index];
+
+ if (po->html3)
+ fprintf(fout, "<td align=%s>%s</td>",
+ fieldNotNum[field_index] ? "left" : "right", p ? p : "");
+ else
+ {
+ fprintf(fout,
+ fieldNotNum[field_index] ?
+ (po->standard ? " %-*s " : "%-*s") :
+ (po->standard ? " %*s " : "%*s"),
+ fieldMax[field_index],
+ p ? p : "");
+ if (po->standard || field_index + 1 < nFields)
+ fputs(po->fieldSep, fout);
+ }
+ if (p)
+ free(p);
+ }
+ if (po->html3)
+ fputs("</tr>", fout);
+ else if (po->standard)
+ fprintf(fout, "\n%s", border);
+ fputc('\n', fout);
}
@@ -1097,591 +1256,672 @@ output_row(FILE *fout, PQprintOpt *po, const int nFields, char *fields[],
*/
void
-PQprint(FILE *fout,
- PGresult *res,
- PQprintOpt *po
- )
+PQprint(FILE * fout,
+ PGresult * res,
+ PQprintOpt * po
+)
{
- int nFields;
-
- nFields = PQnfields(res);
-
- if ( nFields > 0 ) { /* only print rows with at least 1 field. */
- int i,j;
- int nTups;
- int *fieldMax=NULL; /* in case we don't use them */
- unsigned char *fieldNotNum=NULL;
- char *border=NULL;
- char **fields=NULL;
- char **fieldNames;
- int fieldMaxLen=0;
- int numFieldName;
- int fs_len=strlen(po->fieldSep);
- int total_line_length = 0;
- int usePipe = 0;
- char *pagerenv;
- char buf[8192*2+1];
-
- nTups = PQntuples(res);
- if (!(fieldNames=(char **)calloc(nFields, sizeof (char *)))) {
- perror("calloc");
- exit(1);
- }
- if (!(fieldNotNum=(unsigned char *)calloc(nFields, 1))) {
- perror("calloc");
- exit(1);
- }
- if (!(fieldMax=(int *)calloc(nFields, sizeof(int)))) {
- perror("calloc");
- exit(1);
- }
- for (numFieldName=0;
- po->fieldName && po->fieldName[numFieldName];
- numFieldName++)
- ;
- for (j=0; j < nFields; j++) {
- int len;
- char *s =
- (j<numFieldName && po->fieldName[j][0])?
- po->fieldName[j]: PQfname(res, j);
- fieldNames[j]=s;
- len=s ? strlen(s): 0;
- fieldMax[j] = len;
- len+=fs_len;
- if (len>fieldMaxLen)
- fieldMaxLen=len;
- total_line_length += len;
- }
-
- total_line_length += nFields * strlen(po->fieldSep) + 1;
-
- if (fout == NULL)
- fout = stdout;
- if (po->pager && fout == stdout &&
- isatty(fileno(stdin)) &&
- isatty(fileno(stdout))) {
- /* try to pipe to the pager program if possible */
+ int nFields;
+
+ nFields = PQnfields(res);
+
+ if (nFields > 0)
+ { /* only print rows with at least 1 field. */
+ int i,
+ j;
+ int nTups;
+ int *fieldMax = NULL; /* in case we don't use
+ * them */
+ unsigned char *fieldNotNum = NULL;
+ char *border = NULL;
+ char **fields = NULL;
+ char **fieldNames;
+ int fieldMaxLen = 0;
+ int numFieldName;
+ int fs_len = strlen(po->fieldSep);
+ int total_line_length = 0;
+ int usePipe = 0;
+ char *pagerenv;
+ char buf[8192 * 2 + 1];
+
+ nTups = PQntuples(res);
+ if (!(fieldNames = (char **) calloc(nFields, sizeof(char *))))
+ {
+ perror("calloc");
+ exit(1);
+ }
+ if (!(fieldNotNum = (unsigned char *) calloc(nFields, 1)))
+ {
+ perror("calloc");
+ exit(1);
+ }
+ if (!(fieldMax = (int *) calloc(nFields, sizeof(int))))
+ {
+ perror("calloc");
+ exit(1);
+ }
+ for (numFieldName = 0;
+ po->fieldName && po->fieldName[numFieldName];
+ numFieldName++)
+ ;
+ for (j = 0; j < nFields; j++)
+ {
+ int len;
+ char *s =
+ (j < numFieldName && po->fieldName[j][0]) ?
+ po->fieldName[j] : PQfname(res, j);
+
+ fieldNames[j] = s;
+ len = s ? strlen(s) : 0;
+ fieldMax[j] = len;
+ len += fs_len;
+ if (len > fieldMaxLen)
+ fieldMaxLen = len;
+ total_line_length += len;
+ }
+
+ total_line_length += nFields * strlen(po->fieldSep) + 1;
+
+ if (fout == NULL)
+ fout = stdout;
+ if (po->pager && fout == stdout &&
+ isatty(fileno(stdin)) &&
+ isatty(fileno(stdout)))
+ {
+ /* try to pipe to the pager program if possible */
#ifdef TIOCGWINSZ
- if (ioctl(fileno(stdout),TIOCGWINSZ,&screen_size) == -1 ||
- screen_size.ws_col == 0 ||
- screen_size.ws_row == 0) {
+ if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||
+ screen_size.ws_col == 0 ||
+ screen_size.ws_row == 0)
+ {
#endif
- screen_size.ws_row = 24;
- screen_size.ws_col = 80;
+ screen_size.ws_row = 24;
+ screen_size.ws_col = 80;
#ifdef TIOCGWINSZ
- }
+ }
#endif
- pagerenv=getenv("PAGER");
- if (pagerenv != NULL &&
- pagerenv[0] != '\0' &&
- !po->html3 &&
- ((po->expanded &&
- nTups * (nFields+1) >= screen_size.ws_row) ||
- (!po->expanded &&
- nTups * (total_line_length / screen_size.ws_col + 1) *
- ( 1 + (po->standard != 0)) >=
- screen_size.ws_row -
- (po->header != 0) *
- (total_line_length / screen_size.ws_col + 1) * 2
- - (po->header != 0) *2 /* row count and newline */
- ))) {
- fout = popen(pagerenv, "w");
- if (fout) {
- usePipe = 1;
- pqsignal(SIGPIPE, SIG_IGN);
- } else
- fout = stdout;
- }
- }
-
- if (!po->expanded && (po->align || po->html3)) {
- if (!(fields=(char **)calloc(nFields*(nTups+1), sizeof(char *)))) {
- perror("calloc");
- exit(1);
- }
- } else
- if (po->header && !po->html3) {
- if (po->expanded) {
- if (po->align)
- fprintf(fout, "%-*s%s Value\n",
- fieldMaxLen-fs_len, "Field", po->fieldSep);
- else
- fprintf(fout, "%s%sValue\n", "Field", po->fieldSep);
- } else {
- int len=0;
- for (j=0; j < nFields; j++) {
- char *s=fieldNames[j];
- fputs(s, fout);
- len+=strlen(s)+fs_len;
- if ((j+1)<nFields)
- fputs(po->fieldSep, fout);
- }
- fputc('\n', fout);
- for (len-=fs_len; len--; fputc('-', fout));
- fputc('\n', fout);
- }
- }
- if (po->expanded && po->html3) {
- if (po->caption)
- fprintf(fout, "<centre><h2>%s</h2></centre>\n", po->caption);
- else
- fprintf(fout,
- "<centre><h2>"
- "Query retrieved %d rows * %d fields"
- "</h2></centre>\n",
- nTups, nFields);
- }
- for (i = 0; i < nTups; i++) {
- if (po->expanded) {
- if (po->html3)
- fprintf(fout,
- "<table %s><caption align=high>%d</caption>\n",
- po->tableOpt? po->tableOpt: "", i);
- else
- fprintf(fout, "-- RECORD %d --\n", i);
- }
- for (j = 0; j < nFields; j++)
- do_field(po, res, i, j, buf, fs_len, fields, nFields,
- fieldNames, fieldNotNum,
- fieldMax, fieldMaxLen, fout);
- if (po->html3 && po->expanded)
- fputs("</table>\n", fout);
- }
- if (!po->expanded && (po->align || po->html3)) {
- if (po->html3) {
- if (po->header) {
- if (po->caption)
- fprintf(fout,
- "<table %s><caption align=high>%s</caption>\n",
- po->tableOpt? po->tableOpt: "",
- po->caption);
- else
- fprintf(fout,
- "<table %s><caption align=high>"
- "Retrieved %d rows * %d fields"
- "</caption>\n",
- po->tableOpt? po->tableOpt: "", nTups, nFields);
- } else
- fprintf(fout, "<table %s>", po->tableOpt? po->tableOpt: "");
- }
- if (po->header)
- border = do_header(fout, po, nFields, fieldMax, fieldNames,
- fieldNotNum, fs_len, res);
- for (i = 0; i < nTups; i++)
- output_row(fout, po, nFields, fields,
- fieldNotNum, fieldMax, border, i);
- free(fields);
- if (border)
- free(border);
- }
- if (po->header && !po->html3)
- fprintf (fout, "(%d row%s)\n\n",PQntuples(res),
- (PQntuples(res) == 1) ? "" : "s");
- free(fieldMax);
- free(fieldNotNum);
- free(fieldNames);
- if (usePipe) {
- pclose(fout);
- pqsignal(SIGPIPE, SIG_DFL);
- }
- if (po->html3 && !po->expanded)
- fputs("</table>\n", fout);
- }
+ pagerenv = getenv("PAGER");
+ if (pagerenv != NULL &&
+ pagerenv[0] != '\0' &&
+ !po->html3 &&
+ ((po->expanded &&
+ nTups * (nFields + 1) >= screen_size.ws_row) ||
+ (!po->expanded &&
+ nTups * (total_line_length / screen_size.ws_col + 1) *
+ (1 + (po->standard != 0)) >=
+ screen_size.ws_row -
+ (po->header != 0) *
+ (total_line_length / screen_size.ws_col + 1) * 2
+ - (po->header != 0) * 2 /* row count and newline */
+ )))
+ {
+ fout = popen(pagerenv, "w");
+ if (fout)
+ {
+ usePipe = 1;
+ pqsignal(SIGPIPE, SIG_IGN);
+ }
+ else
+ fout = stdout;
+ }
+ }
+
+ if (!po->expanded && (po->align || po->html3))
+ {
+ if (!(fields = (char **) calloc(nFields * (nTups + 1), sizeof(char *))))
+ {
+ perror("calloc");
+ exit(1);
+ }
+ }
+ else if (po->header && !po->html3)
+ {
+ if (po->expanded)
+ {
+ if (po->align)
+ fprintf(fout, "%-*s%s Value\n",
+ fieldMaxLen - fs_len, "Field", po->fieldSep);
+ else
+ fprintf(fout, "%s%sValue\n", "Field", po->fieldSep);
+ }
+ else
+ {
+ int len = 0;
+
+ for (j = 0; j < nFields; j++)
+ {
+ char *s = fieldNames[j];
+
+ fputs(s, fout);
+ len += strlen(s) + fs_len;
+ if ((j + 1) < nFields)
+ fputs(po->fieldSep, fout);
+ }
+ fputc('\n', fout);
+ for (len -= fs_len; len--; fputc('-', fout));
+ fputc('\n', fout);
+ }
+ }
+ if (po->expanded && po->html3)
+ {
+ if (po->caption)
+ fprintf(fout, "<centre><h2>%s</h2></centre>\n", po->caption);
+ else
+ fprintf(fout,
+ "<centre><h2>"
+ "Query retrieved %d rows * %d fields"
+ "</h2></centre>\n",
+ nTups, nFields);
+ }
+ for (i = 0; i < nTups; i++)
+ {
+ if (po->expanded)
+ {
+ if (po->html3)
+ fprintf(fout,
+ "<table %s><caption align=high>%d</caption>\n",
+ po->tableOpt ? po->tableOpt : "", i);
+ else
+ fprintf(fout, "-- RECORD %d --\n", i);
+ }
+ for (j = 0; j < nFields; j++)
+ do_field(po, res, i, j, buf, fs_len, fields, nFields,
+ fieldNames, fieldNotNum,
+ fieldMax, fieldMaxLen, fout);
+ if (po->html3 && po->expanded)
+ fputs("</table>\n", fout);
+ }
+ if (!po->expanded && (po->align || po->html3))
+ {
+ if (po->html3)
+ {
+ if (po->header)
+ {
+ if (po->caption)
+ fprintf(fout,
+ "<table %s><caption align=high>%s</caption>\n",
+ po->tableOpt ? po->tableOpt : "",
+ po->caption);
+ else
+ fprintf(fout,
+ "<table %s><caption align=high>"
+ "Retrieved %d rows * %d fields"
+ "</caption>\n",
+ po->tableOpt ? po->tableOpt : "", nTups, nFields);
+ }
+ else
+ fprintf(fout, "<table %s>", po->tableOpt ? po->tableOpt : "");
+ }
+ if (po->header)
+ border = do_header(fout, po, nFields, fieldMax, fieldNames,
+ fieldNotNum, fs_len, res);
+ for (i = 0; i < nTups; i++)
+ output_row(fout, po, nFields, fields,
+ fieldNotNum, fieldMax, border, i);
+ free(fields);
+ if (border)
+ free(border);
+ }
+ if (po->header && !po->html3)
+ fprintf(fout, "(%d row%s)\n\n", PQntuples(res),
+ (PQntuples(res) == 1) ? "" : "s");
+ free(fieldMax);
+ free(fieldNotNum);
+ free(fieldNames);
+ if (usePipe)
+ {
+ pclose(fout);
+ pqsignal(SIGPIPE, SIG_DFL);
+ }
+ if (po->html3 && !po->expanded)
+ fputs("</table>\n", fout);
+ }
}
/* ----------------
- * PQfn - Send a function call to the POSTGRES backend.
+ * PQfn - Send a function call to the POSTGRES backend.
*
- * conn : backend connection
- * fnid : function id
- * result_buf : pointer to result buffer (&int if integer)
- * result_len : length of return value.
- * actual_result_len: actual length returned. (differs from result_len
- * for varlena structures.)
- * result_type : If the result is an integer, this must be 1,
- * otherwise this should be 0
- * args : pointer to a NULL terminated arg array.
- * (length, if integer, and result-pointer)
- * nargs : # of arguments in args array.
+ * conn : backend connection
+ * fnid : function id
+ * result_buf : pointer to result buffer (&int if integer)
+ * result_len : length of return value.
+ * actual_result_len: actual length returned. (differs from result_len
+ * for varlena structures.)
+ * result_type : If the result is an integer, this must be 1,
+ * otherwise this should be 0
+ * args : pointer to a NULL terminated arg array.
+ * (length, if integer, and result-pointer)
+ * nargs : # of arguments in args array.
*
* RETURNS
- * NULL on failure. PQerrormsg will be set.
- * "G" if there is a return value.
- * "V" if there is no return value.
+ * NULL on failure. PQerrormsg will be set.
+ * "G" if there is a return value.
+ * "V" if there is no return value.
* ----------------
*/
-PGresult*
-PQfn(PGconn *conn,
- int fnid,
- int *result_buf,
- int *actual_result_len,
- int result_is_int,
- PQArgBlock *args,
- int nargs)
+PGresult *
+PQfn(PGconn * conn,
+ int fnid,
+ int *result_buf,
+ int *actual_result_len,
+ int result_is_int,
+ PQArgBlock * args,
+ int nargs)
{
- FILE *pfin, *pfout, *pfdebug;
- int id;
- int i;
-
- if (!conn) return NULL;
-
- pfin = conn->Pfin;
- pfout = conn->Pfout;
- pfdebug = conn->Pfdebug;
-
- /* clear the error string */
- conn->errorMessage[0] = '\0';
-
- pqPuts("F ",pfout,pfdebug); /* function */
- pqPutInt(fnid, 4, pfout, pfdebug); /* function id */
- pqPutInt(nargs, 4, pfout, pfdebug); /* # of args */
-
- for (i = 0; i < nargs; ++i) { /* len.int4 + contents */
- pqPutInt(args[i].len, 4, pfout, pfdebug);
- if (args[i].isint) {
- pqPutInt(args[i].u.integer, 4, pfout, pfdebug);
- } else {
- pqPutnchar((char *)args[i].u.ptr, args[i].len, pfout, pfdebug);
- }
- }
- pqFlush(pfout, pfdebug);
-
- id = pqGetc(pfin, pfdebug);
- if (id != 'V') {
- if (id == 'E') {
- pqGets(conn->errorMessage,ERROR_MSG_LENGTH,pfin,pfdebug);
- } else
- sprintf(conn->errorMessage,
- "PQfn: expected a 'V' from the backend. Got '%c' instead",
- id);
- return makeEmptyPGresult(conn,PGRES_FATAL_ERROR);
- }
-
- id = pqGetc(pfin, pfdebug);
- for (;;) {
- int c;
- switch (id) {
- case 'G': /* function returned properly */
- pqGetInt(actual_result_len,4,pfin,pfdebug);
- if (result_is_int) {
- pqGetInt(result_buf,4,pfin,pfdebug);
- } else {
- pqGetnchar((char *) result_buf, *actual_result_len,
- pfin, pfdebug);
- }
- c = pqGetc(pfin, pfdebug); /* get the last '0'*/
- return makeEmptyPGresult(conn,PGRES_COMMAND_OK);
- case 'E':
- sprintf(conn->errorMessage,
- "PQfn: returned an error");
- return makeEmptyPGresult(conn,PGRES_FATAL_ERROR);
- case 'N':
- /* print notice and go back to processing return values */
- if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug)
- == 1) {
- sprintf(conn->errorMessage,
- "Notice return detected from backend, but message "
- "cannot be read");
- } else
- fprintf(stderr, "%s\n", conn->errorMessage);
- /* keep iterating */
- break;
- case '0': /* no return value */
- return makeEmptyPGresult(conn,PGRES_COMMAND_OK);
- default:
- /* The backend violates the protocol. */
- sprintf(conn->errorMessage,
- "FATAL: PQfn: protocol error: id=%x\n", id);
- return makeEmptyPGresult(conn,PGRES_FATAL_ERROR);
- }
- }
+ FILE *pfin,
+ *pfout,
+ *pfdebug;
+ int id;
+ int i;
+
+ if (!conn)
+ return NULL;
+
+ pfin = conn->Pfin;
+ pfout = conn->Pfout;
+ pfdebug = conn->Pfdebug;
+
+ /* clear the error string */
+ conn->errorMessage[0] = '\0';
+
+ pqPuts("F ", pfout, pfdebug); /* function */
+ pqPutInt(fnid, 4, pfout, pfdebug); /* function id */
+ pqPutInt(nargs, 4, pfout, pfdebug); /* # of args */
+
+ for (i = 0; i < nargs; ++i)
+ { /* len.int4 + contents */
+ pqPutInt(args[i].len, 4, pfout, pfdebug);
+ if (args[i].isint)
+ {
+ pqPutInt(args[i].u.integer, 4, pfout, pfdebug);
+ }
+ else
+ {
+ pqPutnchar((char *) args[i].u.ptr, args[i].len, pfout, pfdebug);
+ }
+ }
+ pqFlush(pfout, pfdebug);
+
+ id = pqGetc(pfin, pfdebug);
+ if (id != 'V')
+ {
+ if (id == 'E')
+ {
+ pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug);
+ }
+ else
+ sprintf(conn->errorMessage,
+ "PQfn: expected a 'V' from the backend. Got '%c' instead",
+ id);
+ return makeEmptyPGresult(conn, PGRES_FATAL_ERROR);
+ }
+
+ id = pqGetc(pfin, pfdebug);
+ for (;;)
+ {
+ int c;
+
+ switch (id)
+ {
+ case 'G': /* function returned properly */
+ pqGetInt(actual_result_len, 4, pfin, pfdebug);
+ if (result_is_int)
+ {
+ pqGetInt(result_buf, 4, pfin, pfdebug);
+ }
+ else
+ {
+ pqGetnchar((char *) result_buf, *actual_result_len,
+ pfin, pfdebug);
+ }
+ c = pqGetc(pfin, pfdebug); /* get the last '0' */
+ return makeEmptyPGresult(conn, PGRES_COMMAND_OK);
+ case 'E':
+ sprintf(conn->errorMessage,
+ "PQfn: returned an error");
+ return makeEmptyPGresult(conn, PGRES_FATAL_ERROR);
+ case 'N':
+ /* print notice and go back to processing return values */
+ if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug)
+ == 1)
+ {
+ sprintf(conn->errorMessage,
+ "Notice return detected from backend, but message "
+ "cannot be read");
+ }
+ else
+ fprintf(stderr, "%s\n", conn->errorMessage);
+ /* keep iterating */
+ break;
+ case '0': /* no return value */
+ return makeEmptyPGresult(conn, PGRES_COMMAND_OK);
+ default:
+ /* The backend violates the protocol. */
+ sprintf(conn->errorMessage,
+ "FATAL: PQfn: protocol error: id=%x\n", id);
+ return makeEmptyPGresult(conn, PGRES_FATAL_ERROR);
+ }
+ }
}
/* ====== accessor funcs for PGresult ======== */
-ExecStatusType
-PQresultStatus(PGresult* res)
-{
- if (!res) {
- fprintf(stderr, "PQresultStatus() -- pointer to PQresult is null");
- return PGRES_NONFATAL_ERROR;
- }
+ExecStatusType
+PQresultStatus(PGresult * res)
+{
+ if (!res)
+ {
+ fprintf(stderr, "PQresultStatus() -- pointer to PQresult is null");
+ return PGRES_NONFATAL_ERROR;
+ }
- return res->resultStatus;
+ return res->resultStatus;
}
-int
-PQntuples(PGresult *res)
+int
+PQntuples(PGresult * res)
{
- if (!res) {
- fprintf(stderr, "PQntuples() -- pointer to PQresult is null");
- return (int)NULL;
- }
- return res->ntups;
+ if (!res)
+ {
+ fprintf(stderr, "PQntuples() -- pointer to PQresult is null");
+ return (int) NULL;
+ }
+ return res->ntups;
}
int
-PQnfields(PGresult *res)
+PQnfields(PGresult * res)
{
- if (!res) {
- fprintf(stderr, "PQnfields() -- pointer to PQresult is null");
- return (int)NULL;
- }
- return res->numAttributes;
+ if (!res)
+ {
+ fprintf(stderr, "PQnfields() -- pointer to PQresult is null");
+ return (int) NULL;
+ }
+ return res->numAttributes;
}
/*
returns NULL if the field_num is invalid
*/
-char*
-PQfname(PGresult *res, int field_num)
+char *
+PQfname(PGresult * res, int field_num)
{
- if (!res) {
- fprintf(stderr, "PQfname() -- pointer to PQresult is null");
- return NULL;
- }
-
- if (field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQfname: ERROR! name of field %d(of %d) is not available",
- field_num, res->numAttributes -1);
- return NULL;
- }
- if (res->attDescs) {
- return res->attDescs[field_num].name;
- } else
- return NULL;
+ if (!res)
+ {
+ fprintf(stderr, "PQfname() -- pointer to PQresult is null");
+ return NULL;
+ }
+
+ if (field_num > (res->numAttributes - 1))
+ {
+ fprintf(stderr,
+ "PQfname: ERROR! name of field %d(of %d) is not available",
+ field_num, res->numAttributes - 1);
+ return NULL;
+ }
+ if (res->attDescs)
+ {
+ return res->attDescs[field_num].name;
+ }
+ else
+ return NULL;
}
/*
returns -1 on a bad field name
*/
int
-PQfnumber(PGresult *res, const char* field_name)
+PQfnumber(PGresult * res, const char *field_name)
{
- int i;
+ int i;
- if (!res) {
- fprintf(stderr, "PQfnumber() -- pointer to PQresult is null");
- return -1;
- }
+ if (!res)
+ {
+ fprintf(stderr, "PQfnumber() -- pointer to PQresult is null");
+ return -1;
+ }
- if (field_name == NULL ||
- field_name[0] == '\0' ||
- res->attDescs == NULL)
- return -1;
+ if (field_name == NULL ||
+ field_name[0] == '\0' ||
+ res->attDescs == NULL)
+ return -1;
- for (i=0;i<res->numAttributes;i++) {
- if ( strcasecmp(field_name, res->attDescs[i].name) == 0 )
- return i;
- }
- return -1;
+ for (i = 0; i < res->numAttributes; i++)
+ {
+ if (strcasecmp(field_name, res->attDescs[i].name) == 0)
+ return i;
+ }
+ return -1;
}
Oid
-PQftype(PGresult *res, int field_num)
+PQftype(PGresult * res, int field_num)
{
- if (!res) {
- fprintf(stderr, "PQftype() -- pointer to PQresult is null");
- return InvalidOid;
- }
-
- if (field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQftype: ERROR! type of field %d(of %d) is not available",
- field_num, res->numAttributes -1);
- }
- if (res->attDescs) {
- return res->attDescs[field_num].adtid;
- } else
- return InvalidOid;
+ if (!res)
+ {
+ fprintf(stderr, "PQftype() -- pointer to PQresult is null");
+ return InvalidOid;
+ }
+
+ if (field_num > (res->numAttributes - 1))
+ {
+ fprintf(stderr,
+ "PQftype: ERROR! type of field %d(of %d) is not available",
+ field_num, res->numAttributes - 1);
+ }
+ if (res->attDescs)
+ {
+ return res->attDescs[field_num].adtid;
+ }
+ else
+ return InvalidOid;
}
int2
-PQfsize(PGresult *res, int field_num)
+PQfsize(PGresult * res, int field_num)
{
- if (!res) {
- fprintf(stderr, "PQfsize() -- pointer to PQresult is null");
- return (int2)NULL;
- }
-
- if (field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQfsize: ERROR! size of field %d(of %d) is not available",
- field_num, res->numAttributes -1);
- }
- if (res->attDescs) {
- return res->attDescs[field_num].adtsize;
- } else
- return 0;
+ if (!res)
+ {
+ fprintf(stderr, "PQfsize() -- pointer to PQresult is null");
+ return (int2) NULL;
+ }
+
+ if (field_num > (res->numAttributes - 1))
+ {
+ fprintf(stderr,
+ "PQfsize: ERROR! size of field %d(of %d) is not available",
+ field_num, res->numAttributes - 1);
+ }
+ if (res->attDescs)
+ {
+ return res->attDescs[field_num].adtsize;
+ }
+ else
+ return 0;
}
-char* PQcmdStatus(PGresult *res) {
- if (!res) {
- fprintf(stderr, "PQcmdStatus() -- pointer to PQresult is null");
- return NULL;
- }
- return res->cmdStatus;
+char *
+PQcmdStatus(PGresult * res)
+{
+ if (!res)
+ {
+ fprintf(stderr, "PQcmdStatus() -- pointer to PQresult is null");
+ return NULL;
+ }
+ return res->cmdStatus;
}
/*
PQoidStatus -
- if the last command was an INSERT, return the oid string
- if not, return ""
+ if the last command was an INSERT, return the oid string
+ if not, return ""
*/
-static char oidStatus[32] = {0};
-const char* PQoidStatus (PGresult *res)
+static char oidStatus[32] = {0};
+const char *
+PQoidStatus(PGresult * res)
{
- if (!res)
- {
- fprintf (stderr, "PQoidStatus () -- pointer to PQresult is null");
- return NULL;
- }
-
- oidStatus[0] = 0;
- if ( !res->cmdStatus )
- return oidStatus;
-
- if ( strncmp (res->cmdStatus, "INSERT", 6) == 0 )
- {
- char *p = res->cmdStatus + 7;
- char *e;
-
- for (e = p; *e != ' ' && *e; ) e++;
- sprintf (oidStatus, "%.*s", e - p, p);
- }
- return oidStatus;
+ if (!res)
+ {
+ fprintf(stderr, "PQoidStatus () -- pointer to PQresult is null");
+ return NULL;
+ }
+
+ oidStatus[0] = 0;
+ if (!res->cmdStatus)
+ return oidStatus;
+
+ if (strncmp(res->cmdStatus, "INSERT", 6) == 0)
+ {
+ char *p = res->cmdStatus + 7;
+ char *e;
+
+ for (e = p; *e != ' ' && *e;)
+ e++;
+ sprintf(oidStatus, "%.*s", e - p, p);
+ }
+ return oidStatus;
}
/*
PQcmdTuples -
- if the last command was an INSERT/UPDATE/DELETE, return number
- of inserted/affected tuples, if not, return ""
+ if the last command was an INSERT/UPDATE/DELETE, return number
+ of inserted/affected tuples, if not, return ""
*/
-const char* PQcmdTuples (PGresult *res)
+const char *
+PQcmdTuples(PGresult * res)
{
- if (!res)
- {
- fprintf (stderr, "PQcmdTuples () -- pointer to PQresult is null");
- return NULL;
- }
-
- if ( !res->cmdStatus )
- return "";
-
- if ( strncmp (res->cmdStatus, "INSERT", 6) == 0 ||
- strncmp (res->cmdStatus, "DELETE", 6) == 0 ||
- strncmp (res->cmdStatus, "UPDATE", 6) == 0 )
- {
- char *p = res->cmdStatus + 6;
-
- if ( *p == 0 )
- {
- fprintf (stderr, "PQcmdTuples (%s) -- short input from server",
- res->cmdStatus);
- return NULL;
- }
- p++;
- if ( *(res->cmdStatus) != 'I' ) /* UPDATE/DELETE */
- return (p);
- while ( *p != ' ' && *p ) p++; /* INSERT: skip oid */
- if ( *p == 0 )
- {
- fprintf (stderr, "PQcmdTuples (INSERT) -- there's no # of tuples");
- return NULL;
- }
- p++;
- return (p);
- }
- return "";
+ if (!res)
+ {
+ fprintf(stderr, "PQcmdTuples () -- pointer to PQresult is null");
+ return NULL;
+ }
+
+ if (!res->cmdStatus)
+ return "";
+
+ if (strncmp(res->cmdStatus, "INSERT", 6) == 0 ||
+ strncmp(res->cmdStatus, "DELETE", 6) == 0 ||
+ strncmp(res->cmdStatus, "UPDATE", 6) == 0)
+ {
+ char *p = res->cmdStatus + 6;
+
+ if (*p == 0)
+ {
+ fprintf(stderr, "PQcmdTuples (%s) -- short input from server",
+ res->cmdStatus);
+ return NULL;
+ }
+ p++;
+ if (*(res->cmdStatus) != 'I') /* UPDATE/DELETE */
+ return (p);
+ while (*p != ' ' && *p)
+ p++; /* INSERT: skip oid */
+ if (*p == 0)
+ {
+ fprintf(stderr, "PQcmdTuples (INSERT) -- there's no # of tuples");
+ return NULL;
+ }
+ p++;
+ return (p);
+ }
+ return "";
}
/*
PQgetvalue:
- return the value of field 'field_num' of row 'tup_num'
+ return the value of field 'field_num' of row 'tup_num'
- If res is binary, then the value returned is NOT a null-terminated
- ASCII string, but the binary representation in the server's native
- format.
+ If res is binary, then the value returned is NOT a null-terminated
+ ASCII string, but the binary representation in the server's native
+ format.
- if res is not binary, a null-terminated ASCII string is returned.
+ if res is not binary, a null-terminated ASCII string is returned.
*/
-char*
-PQgetvalue(PGresult *res, int tup_num, int field_num)
+char *
+PQgetvalue(PGresult * res, int tup_num, int field_num)
{
- if (!res) {
- fprintf(stderr, "PQgetvalue: pointer to PQresult is null\n");
- return NULL;
- } else if (tup_num > (res->ntups - 1)) {
- fprintf(stderr,
- "PQgetvalue: There is no row %d in the query results. "
- "The highest numbered row is %d.\n",
- tup_num, res->ntups - 1);
- return NULL;
- } else if (field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQgetvalue: There is no field %d in the query results. "
- "The highest numbered field is %d.\n",
- field_num, res->numAttributes - 1);
- return NULL;
- }
-
- return res->tuples[tup_num][field_num].value;
+ if (!res)
+ {
+ fprintf(stderr, "PQgetvalue: pointer to PQresult is null\n");
+ return NULL;
+ }
+ else if (tup_num > (res->ntups - 1))
+ {
+ fprintf(stderr,
+ "PQgetvalue: There is no row %d in the query results. "
+ "The highest numbered row is %d.\n",
+ tup_num, res->ntups - 1);
+ return NULL;
+ }
+ else if (field_num > (res->numAttributes - 1))
+ {
+ fprintf(stderr,
+ "PQgetvalue: There is no field %d in the query results. "
+ "The highest numbered field is %d.\n",
+ field_num, res->numAttributes - 1);
+ return NULL;
+ }
+
+ return res->tuples[tup_num][field_num].value;
}
/* PQgetlength:
- returns the length of a field value in bytes. If res is binary,
- i.e. a result of a binary portal, then the length returned does
- NOT include the size field of the varlena.
+ returns the length of a field value in bytes. If res is binary,
+ i.e. a result of a binary portal, then the length returned does
+ NOT include the size field of the varlena.
*/
int
-PQgetlength(PGresult *res, int tup_num, int field_num)
+PQgetlength(PGresult * res, int tup_num, int field_num)
{
- if (!res) {
- fprintf(stderr, "PQgetlength() -- pointer to PQresult is null");
- return (int)NULL;
- }
-
- if (tup_num > (res->ntups - 1 )||
- field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQgetlength: ERROR! field %d(of %d) of row %d(of %d) "
- "is not available",
- field_num, res->numAttributes - 1, tup_num, res->ntups);
- }
-
- if (res->tuples[tup_num][field_num].len != NULL_LEN)
- return res->tuples[tup_num][field_num].len;
- else
- return 0;
- }
+ if (!res)
+ {
+ fprintf(stderr, "PQgetlength() -- pointer to PQresult is null");
+ return (int) NULL;
+ }
+
+ if (tup_num > (res->ntups - 1) ||
+ field_num > (res->numAttributes - 1))
+ {
+ fprintf(stderr,
+ "PQgetlength: ERROR! field %d(of %d) of row %d(of %d) "
+ "is not available",
+ field_num, res->numAttributes - 1, tup_num, res->ntups);
+ }
+
+ if (res->tuples[tup_num][field_num].len != NULL_LEN)
+ return res->tuples[tup_num][field_num].len;
+ else
+ return 0;
+}
/* PQgetisnull:
- returns the null status of a field value.
+ returns the null status of a field value.
*/
int
-PQgetisnull(PGresult *res, int tup_num, int field_num)
+PQgetisnull(PGresult * res, int tup_num, int field_num)
{
- if (!res) {
- fprintf(stderr, "PQgetisnull() -- pointer to PQresult is null");
- return (int)NULL;
- }
-
- if (tup_num > (res->ntups - 1 )||
- field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQgetisnull: ERROR! field %d(of %d) of row %d(of %d) "
- "is not available",
- field_num, res->numAttributes - 1, tup_num, res->ntups);
- }
-
- if (res->tuples[tup_num][field_num].len == NULL_LEN)
- return 1;
- else
- return 0;
+ if (!res)
+ {
+ fprintf(stderr, "PQgetisnull() -- pointer to PQresult is null");
+ return (int) NULL;
+ }
+
+ if (tup_num > (res->ntups - 1) ||
+ field_num > (res->numAttributes - 1))
+ {
+ fprintf(stderr,
+ "PQgetisnull: ERROR! field %d(of %d) of row %d(of %d) "
+ "is not available",
+ field_num, res->numAttributes - 1, tup_num, res->ntups);
+ }
+
+ if (res->tuples[tup_num][field_num].len == NULL_LEN)
+ return 1;
+ else
+ return 0;
}
diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index 9b566cea339..1636edc7f42 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* fe-lobj.c--
- * Front-end large object interface
+ * Front-end large object interface
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.7 1997/05/06 07:19:04 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.8 1997/09/07 05:03:34 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,207 +21,227 @@
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
-#define LO_BUFSIZE 1024
+#define LO_BUFSIZE 1024
-static int lo_initialize(PGconn *conn);
+static int lo_initialize(PGconn * conn);
/*
* lo_open
- * opens an existing large object
+ * opens an existing large object
*
* returns the file descriptor for use in later lo_* calls
* return -1 upon failure.
*/
int
-lo_open(PGconn* conn, Oid lobjId, int mode)
+lo_open(PGconn * conn, Oid lobjId, int mode)
{
- int fd;
- int result_len;
- PQArgBlock argv[2];
- PGresult *res;
-
- argv[0].isint = 1;
- argv[0].len = 4;
- argv[0].u.integer = lobjId;
-
- argv[1].isint = 1;
- argv[1].len = 4;
- argv[1].u.integer = mode;
-
- if(conn->lobjfuncs == (PGlobjfuncs *)NULL) {
- if(lo_initialize(conn) < 0) {
- return -1;
- }
- }
-
- res = PQfn(conn, conn->lobjfuncs->fn_lo_open,&fd,&result_len,1,argv,2);
- if (PQresultStatus(res) == PGRES_COMMAND_OK) {
- PQclear(res);
+ int fd;
+ int result_len;
+ PQArgBlock argv[2];
+ PGresult *res;
+
+ argv[0].isint = 1;
+ argv[0].len = 4;
+ argv[0].u.integer = lobjId;
+
+ argv[1].isint = 1;
+ argv[1].len = 4;
+ argv[1].u.integer = mode;
+
+ if (conn->lobjfuncs == (PGlobjfuncs *) NULL)
+ {
+ if (lo_initialize(conn) < 0)
+ {
+ return -1;
+ }
+ }
+
+ res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2);
+ if (PQresultStatus(res) == PGRES_COMMAND_OK)
+ {
+ PQclear(res);
- /* have to do this to reset offset in shared fd cache */
- /* but only if fd is valid */
- if (fd >= 0 && lo_lseek(conn, fd, 0L, SEEK_SET) < 0)
- return -1;
- return fd;
- } else
- return -1;
+ /* have to do this to reset offset in shared fd cache */
+ /* but only if fd is valid */
+ if (fd >= 0 && lo_lseek(conn, fd, 0L, SEEK_SET) < 0)
+ return -1;
+ return fd;
+ }
+ else
+ return -1;
}
/*
* lo_close
- * closes an existing large object
+ * closes an existing large object
*
* returns 0 upon success
* returns -1 upon failure.
*/
int
-lo_close(PGconn *conn, int fd)
+lo_close(PGconn * conn, int fd)
{
- PQArgBlock argv[1];
- PGresult *res;
- int retval;
- int result_len;
-
- if(conn->lobjfuncs == (PGlobjfuncs *)NULL) {
- if(lo_initialize(conn) < 0) {
- return -1;
- }
- }
-
- argv[0].isint = 1;
- argv[0].len = 4;
- argv[0].u.integer = fd;
- res = PQfn(conn, conn->lobjfuncs->fn_lo_close,
- &retval,&result_len,1,argv,1);
- if (PQresultStatus(res) == PGRES_COMMAND_OK) {
- PQclear(res);
- return retval;
- } else
- return -1;
+ PQArgBlock argv[1];
+ PGresult *res;
+ int retval;
+ int result_len;
+
+ if (conn->lobjfuncs == (PGlobjfuncs *) NULL)
+ {
+ if (lo_initialize(conn) < 0)
+ {
+ return -1;
+ }
+ }
+
+ argv[0].isint = 1;
+ argv[0].len = 4;
+ argv[0].u.integer = fd;
+ res = PQfn(conn, conn->lobjfuncs->fn_lo_close,
+ &retval, &result_len, 1, argv, 1);
+ if (PQresultStatus(res) == PGRES_COMMAND_OK)
+ {
+ PQclear(res);
+ return retval;
+ }
+ else
+ return -1;
}
/*
* lo_read
- * read len bytes of the large object into buf
+ * read len bytes of the large object into buf
*
* returns the length of bytes read.
* the CALLER must have allocated enough space to hold the result returned
*/
int
-lo_read(PGconn *conn, int fd, char *buf, int len)
+lo_read(PGconn * conn, int fd, char *buf, int len)
{
- PQArgBlock argv[2];
- PGresult *res;
- int result_len;
-
- if(conn->lobjfuncs == (PGlobjfuncs *)NULL) {
- if(lo_initialize(conn) < 0) {
- return -1;
- }
- }
-
- argv[0].isint = 1;
- argv[0].len = 4;
- argv[0].u.integer = fd;
-
- argv[1].isint = 1;
- argv[1].len = 4;
- argv[1].u.integer = len;
-
- res = PQfn(conn, conn->lobjfuncs->fn_lo_read,
- (int*)buf,&result_len,0,argv,2);
- if (PQresultStatus(res) == PGRES_COMMAND_OK) {
- PQclear(res);
- return result_len;
- } else
- return -1;
+ PQArgBlock argv[2];
+ PGresult *res;
+ int result_len;
+
+ if (conn->lobjfuncs == (PGlobjfuncs *) NULL)
+ {
+ if (lo_initialize(conn) < 0)
+ {
+ return -1;
+ }
+ }
+
+ argv[0].isint = 1;
+ argv[0].len = 4;
+ argv[0].u.integer = fd;
+
+ argv[1].isint = 1;
+ argv[1].len = 4;
+ argv[1].u.integer = len;
+
+ res = PQfn(conn, conn->lobjfuncs->fn_lo_read,
+ (int *) buf, &result_len, 0, argv, 2);
+ if (PQresultStatus(res) == PGRES_COMMAND_OK)
+ {
+ PQclear(res);
+ return result_len;
+ }
+ else
+ return -1;
}
/*
* lo_write
- * write len bytes of buf into the large object fd
+ * write len bytes of buf into the large object fd
*
*/
int
-lo_write(PGconn *conn, int fd, char *buf, int len)
+lo_write(PGconn * conn, int fd, char *buf, int len)
{
- PQArgBlock argv[2];
- PGresult *res;
- int result_len;
- int retval;
-
- if(conn->lobjfuncs == (PGlobjfuncs *)NULL) {
- if(lo_initialize(conn) < 0) {
- return -1;
- }
- }
-
- if (len <= 0)
- return 0;
+ PQArgBlock argv[2];
+ PGresult *res;
+ int result_len;
+ int retval;
+
+ if (conn->lobjfuncs == (PGlobjfuncs *) NULL)
+ {
+ if (lo_initialize(conn) < 0)
+ {
+ return -1;
+ }
+ }
- argv[0].isint = 1;
- argv[0].len = 4;
- argv[0].u.integer = fd;
+ if (len <= 0)
+ return 0;
- argv[1].isint = 0;
- argv[1].len = len;
- argv[1].u.ptr = (int*)buf;
+ argv[0].isint = 1;
+ argv[0].len = 4;
+ argv[0].u.integer = fd;
- res = PQfn(conn, conn->lobjfuncs->fn_lo_write,
- &retval,&result_len,1,argv,2);
- if (PQresultStatus(res) == PGRES_COMMAND_OK) {
- PQclear(res);
- return retval;
- } else
- return -1;
+ argv[1].isint = 0;
+ argv[1].len = len;
+ argv[1].u.ptr = (int *) buf;
+
+ res = PQfn(conn, conn->lobjfuncs->fn_lo_write,
+ &retval, &result_len, 1, argv, 2);
+ if (PQresultStatus(res) == PGRES_COMMAND_OK)
+ {
+ PQclear(res);
+ return retval;
+ }
+ else
+ return -1;
}
/*
* lo_lseek
- * change the current read or write location on a large object
+ * change the current read or write location on a large object
* currently, only L_SET is a legal value for whence
*
*/
int
-lo_lseek(PGconn *conn, int fd, int offset, int whence)
+lo_lseek(PGconn * conn, int fd, int offset, int whence)
{
- PQArgBlock argv[3];
- PGresult *res;
- int retval;
- int result_len;
-
- if(conn->lobjfuncs == (PGlobjfuncs *)NULL) {
- if(lo_initialize(conn) < 0) {
- return -1;
- }
- }
-
- argv[0].isint = 1;
- argv[0].len = 4;
- argv[0].u.integer = fd;
-
- argv[1].isint = 1;
- argv[1].len = 4;
- argv[1].u.integer = offset;
-
- argv[2].isint = 1;
- argv[2].len = 4;
- argv[2].u.integer = whence;
-
- res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek,
- &retval,&result_len,1,argv,3);
- if (PQresultStatus(res) == PGRES_COMMAND_OK) {
- PQclear(res);
- return retval;
- } else
- return -1;
+ PQArgBlock argv[3];
+ PGresult *res;
+ int retval;
+ int result_len;
+
+ if (conn->lobjfuncs == (PGlobjfuncs *) NULL)
+ {
+ if (lo_initialize(conn) < 0)
+ {
+ return -1;
+ }
+ }
+
+ argv[0].isint = 1;
+ argv[0].len = 4;
+ argv[0].u.integer = fd;
+
+ argv[1].isint = 1;
+ argv[1].len = 4;
+ argv[1].u.integer = offset;
+
+ argv[2].isint = 1;
+ argv[2].len = 4;
+ argv[2].u.integer = whence;
+
+ res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek,
+ &retval, &result_len, 1, argv, 3);
+ if (PQresultStatus(res) == PGRES_COMMAND_OK)
+ {
+ PQclear(res);
+ return retval;
+ }
+ else
+ return -1;
}
/*
* lo_creat
- * create a new large object
+ * create a new large object
* the mode is a bitmask describing different attributes of the new object
*
* returns the oid of the large object created or
@@ -229,209 +249,233 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
*/
Oid
-lo_creat(PGconn *conn, int mode)
+lo_creat(PGconn * conn, int mode)
{
- PQArgBlock argv[1];
- PGresult *res;
- int retval;
- int result_len;
-
- if(conn->lobjfuncs == (PGlobjfuncs *)NULL) {
- if(lo_initialize(conn) < 0) {
- return -1;
- }
- }
-
- argv[0].isint = 1;
- argv[0].len = 4;
- argv[0].u.integer = mode;
- res = PQfn(conn, conn->lobjfuncs->fn_lo_creat,
- &retval,&result_len,1,argv,1);
- if (PQresultStatus(res) == PGRES_COMMAND_OK) {
- PQclear(res);
- return (Oid)retval;
- } else
- return InvalidOid;
+ PQArgBlock argv[1];
+ PGresult *res;
+ int retval;
+ int result_len;
+
+ if (conn->lobjfuncs == (PGlobjfuncs *) NULL)
+ {
+ if (lo_initialize(conn) < 0)
+ {
+ return -1;
+ }
+ }
+
+ argv[0].isint = 1;
+ argv[0].len = 4;
+ argv[0].u.integer = mode;
+ res = PQfn(conn, conn->lobjfuncs->fn_lo_creat,
+ &retval, &result_len, 1, argv, 1);
+ if (PQresultStatus(res) == PGRES_COMMAND_OK)
+ {
+ PQclear(res);
+ return (Oid) retval;
+ }
+ else
+ return InvalidOid;
}
/*
* lo_tell
- * returns the current seek location of the large object
+ * returns the current seek location of the large object
*
*/
int
-lo_tell(PGconn *conn, int fd)
+lo_tell(PGconn * conn, int fd)
{
- int retval;
- PQArgBlock argv[1];
- PGresult *res;
- int result_len;
-
- if(conn->lobjfuncs == (PGlobjfuncs *)NULL) {
- if(lo_initialize(conn) < 0) {
- return -1;
- }
- }
-
- argv[0].isint = 1;
- argv[0].len = 4;
- argv[0].u.integer = fd;
-
- res = PQfn(conn, conn->lobjfuncs->fn_lo_tell,
- &retval,&result_len,1,argv,1);
- if (PQresultStatus(res) == PGRES_COMMAND_OK) {
- PQclear(res);
- return retval;
- } else
- return -1;
+ int retval;
+ PQArgBlock argv[1];
+ PGresult *res;
+ int result_len;
+
+ if (conn->lobjfuncs == (PGlobjfuncs *) NULL)
+ {
+ if (lo_initialize(conn) < 0)
+ {
+ return -1;
+ }
+ }
+
+ argv[0].isint = 1;
+ argv[0].len = 4;
+ argv[0].u.integer = fd;
+
+ res = PQfn(conn, conn->lobjfuncs->fn_lo_tell,
+ &retval, &result_len, 1, argv, 1);
+ if (PQresultStatus(res) == PGRES_COMMAND_OK)
+ {
+ PQclear(res);
+ return retval;
+ }
+ else
+ return -1;
}
/*
* lo_unlink
- * delete a file
+ * delete a file
*
*/
int
-lo_unlink(PGconn *conn, Oid lobjId)
+lo_unlink(PGconn * conn, Oid lobjId)
{
- PQArgBlock argv[1];
- PGresult *res;
- int result_len;
- int retval;
-
- if(conn->lobjfuncs == (PGlobjfuncs *)NULL) {
- if(lo_initialize(conn) < 0) {
- return -1;
- }
- }
-
- argv[0].isint = 1;
- argv[0].len = 4;
- argv[0].u.integer = lobjId;
-
- res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink,
- &retval,&result_len,1,argv,1);
- if (PQresultStatus(res) == PGRES_COMMAND_OK) {
- PQclear(res);
- return retval;
- } else
- return -1;
+ PQArgBlock argv[1];
+ PGresult *res;
+ int result_len;
+ int retval;
+
+ if (conn->lobjfuncs == (PGlobjfuncs *) NULL)
+ {
+ if (lo_initialize(conn) < 0)
+ {
+ return -1;
+ }
+ }
+
+ argv[0].isint = 1;
+ argv[0].len = 4;
+ argv[0].u.integer = lobjId;
+
+ res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink,
+ &retval, &result_len, 1, argv, 1);
+ if (PQresultStatus(res) == PGRES_COMMAND_OK)
+ {
+ PQclear(res);
+ return retval;
+ }
+ else
+ return -1;
}
/*
* lo_import -
- * imports a file as an (inversion) large object.
- * returns the oid of that object upon success,
+ * imports a file as an (inversion) large object.
+ * returns the oid of that object upon success,
* returns InvalidOid upon failure
*
*/
Oid
-lo_import(PGconn *conn, char* filename)
+lo_import(PGconn * conn, char *filename)
{
- int fd;
- int nbytes, tmp;
- char buf[LO_BUFSIZE];
- Oid lobjOid;
- int lobj;
-
- /*
- * open the file to be read in
- */
- fd = open(filename, O_RDONLY, 0666);
- if (fd < 0) { /* error */
- sprintf(conn->errorMessage,
- "lo_import: can't open unix file\"%s\"\n", filename);
- return InvalidOid;
- }
-
- /*
- * create an inversion "object"
- */
- lobjOid = lo_creat(conn, INV_READ|INV_WRITE);
- if (lobjOid == InvalidOid) {
- sprintf(conn->errorMessage,
- "lo_import: can't create inv object for \"%s\"", filename);
- return InvalidOid;
- }
-
- lobj = lo_open(conn, lobjOid, INV_WRITE);
- if (lobj == -1) {
- sprintf(conn->errorMessage,
- "lo_import: could not open inv object oid %d",lobjOid);
- return InvalidOid;
- }
- /*
- * read in from the Unix file and write to the inversion file
- */
- while ((nbytes = read(fd, buf, LO_BUFSIZE)) > 0) {
- tmp = lo_write(conn,lobj, buf, nbytes);
- if (tmp < nbytes) {
- sprintf(conn->errorMessage,
- "lo_import: error while reading \"%s\"",filename);
- return InvalidOid;
- }
- }
-
- (void) close(fd);
- (void) lo_close(conn, lobj);
-
- return lobjOid;
+ int fd;
+ int nbytes,
+ tmp;
+ char buf[LO_BUFSIZE];
+ Oid lobjOid;
+ int lobj;
+
+ /*
+ * open the file to be read in
+ */
+ fd = open(filename, O_RDONLY, 0666);
+ if (fd < 0)
+ { /* error */
+ sprintf(conn->errorMessage,
+ "lo_import: can't open unix file\"%s\"\n", filename);
+ return InvalidOid;
+ }
+
+ /*
+ * create an inversion "object"
+ */
+ lobjOid = lo_creat(conn, INV_READ | INV_WRITE);
+ if (lobjOid == InvalidOid)
+ {
+ sprintf(conn->errorMessage,
+ "lo_import: can't create inv object for \"%s\"", filename);
+ return InvalidOid;
+ }
+
+ lobj = lo_open(conn, lobjOid, INV_WRITE);
+ if (lobj == -1)
+ {
+ sprintf(conn->errorMessage,
+ "lo_import: could not open inv object oid %d", lobjOid);
+ return InvalidOid;
+ }
+
+ /*
+ * read in from the Unix file and write to the inversion file
+ */
+ while ((nbytes = read(fd, buf, LO_BUFSIZE)) > 0)
+ {
+ tmp = lo_write(conn, lobj, buf, nbytes);
+ if (tmp < nbytes)
+ {
+ sprintf(conn->errorMessage,
+ "lo_import: error while reading \"%s\"", filename);
+ return InvalidOid;
+ }
+ }
+
+ (void) close(fd);
+ (void) lo_close(conn, lobj);
+
+ return lobjOid;
}
/*
* lo_export -
- * exports an (inversion) large object.
+ * exports an (inversion) large object.
* returns -1 upon failure, 1 otherwise
*/
int
-lo_export(PGconn *conn, Oid lobjId, char *filename)
+lo_export(PGconn * conn, Oid lobjId, char *filename)
{
- int fd;
- int nbytes, tmp;
- char buf[LO_BUFSIZE];
- int lobj;
-
- /*
- * create an inversion "object"
- */
- lobj = lo_open(conn, lobjId, INV_READ);
- if (lobj == -1) {
- sprintf(conn->errorMessage,
- "lo_export: can't open inv object %d",lobjId);
- return -1;
- }
-
- /*
- * open the file to be written to
- */
- fd = open(filename, O_CREAT|O_WRONLY, 0666);
- if (fd < 0) { /* error */
- sprintf(conn->errorMessage,
- "lo_export: can't open unix file\"%s\"",filename);
- return 0;
- }
+ int fd;
+ int nbytes,
+ tmp;
+ char buf[LO_BUFSIZE];
+ int lobj;
+
+ /*
+ * create an inversion "object"
+ */
+ lobj = lo_open(conn, lobjId, INV_READ);
+ if (lobj == -1)
+ {
+ sprintf(conn->errorMessage,
+ "lo_export: can't open inv object %d", lobjId);
+ return -1;
+ }
+
+ /*
+ * open the file to be written to
+ */
+ fd = open(filename, O_CREAT | O_WRONLY, 0666);
+ if (fd < 0)
+ { /* error */
+ sprintf(conn->errorMessage,
+ "lo_export: can't open unix file\"%s\"", filename);
+ return 0;
+ }
- /*
- * read in from the Unix file and write to the inversion file
- */
- while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0) {
- tmp = write(fd, buf, nbytes);
- if (tmp < nbytes) {
- sprintf(conn->errorMessage,
- "lo_export: error while writing \"%s\"",
- filename);
- return -1;
+ /*
+ * read in from the Unix file and write to the inversion file
+ */
+ while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0)
+ {
+ tmp = write(fd, buf, nbytes);
+ if (tmp < nbytes)
+ {
+ sprintf(conn->errorMessage,
+ "lo_export: error while writing \"%s\"",
+ filename);
+ return -1;
+ }
}
- }
- (void) lo_close(conn,lobj);
- (void) close(fd);
+ (void) lo_close(conn, lobj);
+ (void) close(fd);
- return 1;
+ return 1;
}
@@ -443,31 +487,33 @@ lo_export(PGconn *conn, Oid lobjId, char *filename)
* functions that are required for large object operations.
* ----------------
*/
-static int lo_initialize(PGconn *conn)
+static int
+lo_initialize(PGconn * conn)
{
- PGresult *res;
- PGlobjfuncs *lobjfuncs;
- int n;
- char *fname;
- Oid foid;
-
- /* ----------------
- * Allocate the structure to hold the functions OID's
- * ----------------
- */
- lobjfuncs = (PGlobjfuncs *)malloc(sizeof(PGlobjfuncs));
- if (lobjfuncs == (PGlobjfuncs *)NULL) {
- strcpy(conn->errorMessage,
- "FATAL: malloc() failed in lo_initialize()\n");
- return -1;
- }
- memset((char *)lobjfuncs, 0, sizeof(PGlobjfuncs));
-
- /* ----------------
- * Execute the query to get all the functions at once
- * ----------------
- */
- res = PQexec(conn, "select proname, oid from pg_proc \
+ PGresult *res;
+ PGlobjfuncs *lobjfuncs;
+ int n;
+ char *fname;
+ Oid foid;
+
+ /* ----------------
+ * Allocate the structure to hold the functions OID's
+ * ----------------
+ */
+ lobjfuncs = (PGlobjfuncs *) malloc(sizeof(PGlobjfuncs));
+ if (lobjfuncs == (PGlobjfuncs *) NULL)
+ {
+ strcpy(conn->errorMessage,
+ "FATAL: malloc() failed in lo_initialize()\n");
+ return -1;
+ }
+ memset((char *) lobjfuncs, 0, sizeof(PGlobjfuncs));
+
+ /* ----------------
+ * Execute the query to get all the functions at once
+ * ----------------
+ */
+ res = PQexec(conn, "select proname, oid from pg_proc \
where proname = 'lo_open' \
or proname = 'lo_close' \
or proname = 'lo_creat' \
@@ -476,114 +522,131 @@ static int lo_initialize(PGconn *conn)
or proname = 'lo_tell' \
or proname = 'loread' \
or proname = 'lowrite'");
- if (res == (PGresult *)NULL) {
- free(lobjfuncs);
- return -1;
- }
+ if (res == (PGresult *) NULL)
+ {
+ free(lobjfuncs);
+ return -1;
+ }
+
+ if (res->resultStatus != PGRES_TUPLES_OK)
+ {
+ free(lobjfuncs);
+ PQclear(res);
+ strcpy(conn->errorMessage,
+ "ERROR: SELECT didn't return data in lo_initialize()\n");
+ return -1;
+ }
+
+ /* ----------------
+ * Examine the result and put the OID's into the struct
+ * ----------------
+ */
+ for (n = 0; n < PQntuples(res); n++)
+ {
+ fname = PQgetvalue(res, n, 0);
+ foid = (Oid) atoi(PQgetvalue(res, n, 1));
+ if (!strcmp(fname, "lo_open"))
+ {
+ lobjfuncs->fn_lo_open = foid;
+ }
+ else if (!strcmp(fname, "lo_close"))
+ {
+ lobjfuncs->fn_lo_close = foid;
+ }
+ else if (!strcmp(fname, "lo_creat"))
+ {
+ lobjfuncs->fn_lo_creat = foid;
+ }
+ else if (!strcmp(fname, "lo_unlink"))
+ {
+ lobjfuncs->fn_lo_unlink = foid;
+ }
+ else if (!strcmp(fname, "lo_lseek"))
+ {
+ lobjfuncs->fn_lo_lseek = foid;
+ }
+ else if (!strcmp(fname, "lo_tell"))
+ {
+ lobjfuncs->fn_lo_tell = foid;
+ }
+ else if (!strcmp(fname, "loread"))
+ {
+ lobjfuncs->fn_lo_read = foid;
+ }
+ else if (!strcmp(fname, "lowrite"))
+ {
+ lobjfuncs->fn_lo_write = foid;
+ }
+ }
- if (res->resultStatus != PGRES_TUPLES_OK) {
- free(lobjfuncs);
PQclear(res);
- strcpy(conn->errorMessage,
- "ERROR: SELECT didn't return data in lo_initialize()\n");
- return -1;
- }
-
- /* ----------------
- * Examine the result and put the OID's into the struct
- * ----------------
- */
- for(n = 0; n < PQntuples(res); n++) {
- fname = PQgetvalue(res, n, 0);
- foid = (Oid)atoi(PQgetvalue(res, n, 1));
- if(!strcmp(fname, "lo_open")) {
- lobjfuncs->fn_lo_open = foid;
- } else
- if(!strcmp(fname, "lo_close")) {
- lobjfuncs->fn_lo_close = foid;
- } else
- if(!strcmp(fname, "lo_creat")) {
- lobjfuncs->fn_lo_creat = foid;
- } else
- if(!strcmp(fname, "lo_unlink")) {
- lobjfuncs->fn_lo_unlink = foid;
- } else
- if(!strcmp(fname, "lo_lseek")) {
- lobjfuncs->fn_lo_lseek = foid;
- } else
- if(!strcmp(fname, "lo_tell")) {
- lobjfuncs->fn_lo_tell = foid;
- } else
- if(!strcmp(fname, "loread")) {
- lobjfuncs->fn_lo_read = foid;
- } else
- if(!strcmp(fname, "lowrite")) {
- lobjfuncs->fn_lo_write = foid;
- }
- }
-
- PQclear(res);
-
- /* ----------------
- * Finally check that we really got all large object
- * interface functions.
- * ----------------
- */
- if(lobjfuncs->fn_lo_open == 0) {
- strcpy(conn->errorMessage,
- "ERROR: Cannot determine OID for function lo_open\n");
- free(lobjfuncs);
- return -1;
- }
- if(lobjfuncs->fn_lo_close == 0) {
- strcpy(conn->errorMessage,
- "ERROR: Cannot determine OID for function lo_close\n");
- free(lobjfuncs);
- return -1;
- }
- if(lobjfuncs->fn_lo_creat == 0) {
- strcpy(conn->errorMessage,
- "ERROR: Cannot determine OID for function lo_creat\n");
- free(lobjfuncs);
- return -1;
- }
- if(lobjfuncs->fn_lo_unlink == 0) {
- strcpy(conn->errorMessage,
- "ERROR: Cannot determine OID for function lo_unlink\n");
- free(lobjfuncs);
- return -1;
- }
- if(lobjfuncs->fn_lo_lseek == 0) {
- strcpy(conn->errorMessage,
- "ERROR: Cannot determine OID for function lo_lseek\n");
- free(lobjfuncs);
- return -1;
- }
- if(lobjfuncs->fn_lo_tell == 0) {
- strcpy(conn->errorMessage,
- "ERROR: Cannot determine OID for function lo_tell\n");
- free(lobjfuncs);
- return -1;
- }
- if(lobjfuncs->fn_lo_read == 0) {
- strcpy(conn->errorMessage,
- "ERROR: Cannot determine OID for function loread\n");
- free(lobjfuncs);
- return -1;
- }
- if(lobjfuncs->fn_lo_write == 0) {
- strcpy(conn->errorMessage,
- "ERROR: Cannot determine OID for function lowrite\n");
- free(lobjfuncs);
- return -1;
- }
-
- /* ----------------
- * Put the structure into the connection control
- * ----------------
- */
- conn->lobjfuncs = lobjfuncs;
- return 0;
-}
+ /* ----------------
+ * Finally check that we really got all large object
+ * interface functions.
+ * ----------------
+ */
+ if (lobjfuncs->fn_lo_open == 0)
+ {
+ strcpy(conn->errorMessage,
+ "ERROR: Cannot determine OID for function lo_open\n");
+ free(lobjfuncs);
+ return -1;
+ }
+ if (lobjfuncs->fn_lo_close == 0)
+ {
+ strcpy(conn->errorMessage,
+ "ERROR: Cannot determine OID for function lo_close\n");
+ free(lobjfuncs);
+ return -1;
+ }
+ if (lobjfuncs->fn_lo_creat == 0)
+ {
+ strcpy(conn->errorMessage,
+ "ERROR: Cannot determine OID for function lo_creat\n");
+ free(lobjfuncs);
+ return -1;
+ }
+ if (lobjfuncs->fn_lo_unlink == 0)
+ {
+ strcpy(conn->errorMessage,
+ "ERROR: Cannot determine OID for function lo_unlink\n");
+ free(lobjfuncs);
+ return -1;
+ }
+ if (lobjfuncs->fn_lo_lseek == 0)
+ {
+ strcpy(conn->errorMessage,
+ "ERROR: Cannot determine OID for function lo_lseek\n");
+ free(lobjfuncs);
+ return -1;
+ }
+ if (lobjfuncs->fn_lo_tell == 0)
+ {
+ strcpy(conn->errorMessage,
+ "ERROR: Cannot determine OID for function lo_tell\n");
+ free(lobjfuncs);
+ return -1;
+ }
+ if (lobjfuncs->fn_lo_read == 0)
+ {
+ strcpy(conn->errorMessage,
+ "ERROR: Cannot determine OID for function loread\n");
+ free(lobjfuncs);
+ return -1;
+ }
+ if (lobjfuncs->fn_lo_write == 0)
+ {
+ strcpy(conn->errorMessage,
+ "ERROR: Cannot determine OID for function lowrite\n");
+ free(lobjfuncs);
+ return -1;
+ }
+ /* ----------------
+ * Put the structure into the connection control
+ * ----------------
+ */
+ conn->lobjfuncs = lobjfuncs;
+ return 0;
+}
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index 62062184ca8..b7e8a1b1c69 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -1,17 +1,17 @@
/*-------------------------------------------------------------------------
*
- * FILE
- * fe-misc.c
+ * FILE
+ * fe-misc.c
*
- * DESCRIPTION
- * miscellaneous useful functions
- * these routines are analogous to the ones in libpq/pqcomm.c
+ * DESCRIPTION
+ * miscellaneous useful functions
+ * these routines are analogous to the ones in libpq/pqcomm.c
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.5 1997/03/16 18:51:29 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.6 1997/09/07 05:03:35 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,80 +29,84 @@
if debug is set, also echo the character fetched
*/
-int pqGetc(FILE* fin, FILE* debug)
+int
+pqGetc(FILE * fin, FILE * debug)
{
- int c;
+ int c;
- c = getc(fin);
+ c = getc(fin);
- if (debug && c != EOF)
- fprintf(debug, "From backend> %c\n", c);
-
- return c;
+ if (debug && c != EOF)
+ fprintf(debug, "From backend> %c\n", c);
+
+ return c;
}
/* --------------------------------------------------------------------- */
/* pqPutnchar:
- send a string of exactly len length into stream f
+ send a string of exactly len length into stream f
returns 1 if there was an error, 0 otherwise.
*/
-int pqPutnchar(const char* s, int len, FILE *f, FILE *debug)
+int
+pqPutnchar(const char *s, int len, FILE * f, FILE * debug)
{
- if (f == NULL)
- return 1;
+ if (f == NULL)
+ return 1;
- if(debug)
- fprintf(debug, "To backend> %s\n", s);
+ if (debug)
+ fprintf(debug, "To backend> %s\n", s);
- if(fwrite(s, 1, len, f) != len)
- return 1;
+ if (fwrite(s, 1, len, f) != len)
+ return 1;
- return 0;
+ return 0;
}
/* --------------------------------------------------------------------- */
/* pqGetnchar:
- get a string of exactly len length from stream f
+ get a string of exactly len length from stream f
*/
-int pqGetnchar(char* s, int len, FILE *f, FILE *debug)
+int
+pqGetnchar(char *s, int len, FILE * f, FILE * debug)
{
- int cnt;
+ int cnt;
+
+ if (f == NULL)
+ return 1;
- if (f == NULL)
- return 1;
-
- cnt = fread(s, 1, len, f);
- s[cnt] = '\0';
- /* mjl: actually needs up to len+1 bytes, is this okay? XXX */
+ cnt = fread(s, 1, len, f);
+ s[cnt] = '\0';
+ /* mjl: actually needs up to len+1 bytes, is this okay? XXX */
- if (debug)
- fprintf(debug, "From backend (%d)> %s\n", len, s);
+ if (debug)
+ fprintf(debug, "From backend (%d)> %s\n", len, s);
- return 0;
+ return 0;
}
/* --------------------------------------------------------------------- */
/* pqGets:
get a string of up to length len from stream f
*/
-int pqGets(char* s, int len, FILE *f, FILE *debug)
+int
+pqGets(char *s, int len, FILE * f, FILE * debug)
{
- int c;
- const char *str = s;
+ int c;
+ const char *str = s;
+
+ if (f == NULL)
+ return 1;
- if (f == NULL)
- return 1;
-
- while (len-- && (c = getc(f)) != EOF && c)
- *s++ = c;
- *s = '\0';
- /* mjl: actually needs up to len+1 bytes, is this okay? XXX */
+ while (len-- && (c = getc(f)) != EOF && c)
+ *s++ = c;
+ *s = '\0';
+ /* mjl: actually needs up to len+1 bytes, is this okay? XXX */
- if (debug)
- fprintf(debug, "From backend> \"%s\"\n", str);
+ if (debug)
+ fprintf(debug, "From backend> \"%s\"\n", str);
- return 0;
+ return 0;
}
/* --------------------------------------------------------------------- */
@@ -111,84 +115,91 @@ int pqGets(char* s, int len, FILE *f, FILE *debug)
for host endianness.
returns 0 if successful, 1 otherwise
*/
-int pqPutInt(const int integer, int bytes, FILE* f, FILE *debug)
+int
+pqPutInt(const int integer, int bytes, FILE * f, FILE * debug)
{
- int retval = 0;
-
- switch(bytes)
- {
- case 2:
- retval = pqPutShort(integer, f);
- break;
- case 4:
- retval = pqPutLong(integer, f);
- break;
- default:
- fprintf(stderr, "** int size %d not supported\n", bytes);
- retval = 1;
- }
-
- if (debug) fprintf(debug, "To backend (%d#)> %d\n", bytes, integer);
-
- return retval;
+ int retval = 0;
+
+ switch (bytes)
+ {
+ case 2:
+ retval = pqPutShort(integer, f);
+ break;
+ case 4:
+ retval = pqPutLong(integer, f);
+ break;
+ default:
+ fprintf(stderr, "** int size %d not supported\n", bytes);
+ retval = 1;
+ }
+
+ if (debug)
+ fprintf(debug, "To backend (%d#)> %d\n", bytes, integer);
+
+ return retval;
}
/* --------------------------------------------------------------------- */
-/* pgGetInt
+/* pgGetInt
read a 2 or 4 byte integer from the stream and swab it around
to compensate for different endianness
- returns 0 if successful
+ returns 0 if successful
*/
-int pqGetInt(int* result, int bytes, FILE* f, FILE *debug)
+int
+pqGetInt(int *result, int bytes, FILE * f, FILE * debug)
{
- int retval = 0;
-
- switch(bytes)
- {
- case 2:
- retval = pqGetShort(result, f);
- break;
- case 4:
- retval = pqGetLong(result, f);
- break;
- default:
- fprintf(stderr, "** int size %d not supported\n", bytes);
- retval = 1;
- }
-
- if (debug)
- fprintf(debug,"From backend (#%d)> %d\n", bytes, *result);
-
- return retval;
+ int retval = 0;
+
+ switch (bytes)
+ {
+ case 2:
+ retval = pqGetShort(result, f);
+ break;
+ case 4:
+ retval = pqGetLong(result, f);
+ break;
+ default:
+ fprintf(stderr, "** int size %d not supported\n", bytes);
+ retval = 1;
+ }
+
+ if (debug)
+ fprintf(debug, "From backend (#%d)> %d\n", bytes, *result);
+
+ return retval;
}
/* --------------------------------------------------------------------- */
-int pqPuts(const char* s, FILE *f, FILE *debug)
+int
+pqPuts(const char *s, FILE * f, FILE * debug)
{
- if (f == NULL)
- return 1;
-
- if (fputs(s, f) == EOF)
- return 1;
-
- fputc('\0', f); /* important to send an ending \0 since backend expects it */
- fflush(f);
-
- if (debug) {
- fprintf(debug, "To backend> %s\n", s);
- }
-
- return 0;
+ if (f == NULL)
+ return 1;
+
+ if (fputs(s, f) == EOF)
+ return 1;
+
+ fputc('\0', f); /* important to send an ending \0 since
+ * backend expects it */
+ fflush(f);
+
+ if (debug)
+ {
+ fprintf(debug, "To backend> %s\n", s);
+ }
+
+ return 0;
}
/* --------------------------------------------------------------------- */
-void pqFlush(FILE *f, FILE *debug)
+void
+pqFlush(FILE * f, FILE * debug)
{
- if (f)
- fflush(f);
+ if (f)
+ fflush(f);
- if (debug)
- fflush(debug);
+ if (debug)
+ fflush(debug);
}
/* --------------------------------------------------------------------- */
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index fdd29fe42d2..3013d5a2bfc 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* libpq-fe.h--
- * This file contains definitions for structures and
- * externs for functions used by frontend postgres applications.
+ * This file contains definitions for structures and
+ * externs for functions used by frontend postgres applications.
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-fe.h,v 1.20 1997/08/27 09:05:24 vadim Exp $
+ * $Id: libpq-fe.h,v 1.21 1997/09/07 05:03:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,41 +15,47 @@
#define LIBPQ_FE_H
#ifdef __cplusplus
-extern "C" {
+extern "C"
+{
#endif
#include <stdio.h>
/* ----------------
- * include stuff common to fe and be
+ * include stuff common to fe and be
* ----------------
*/
#include "postgres_ext.h"
#include "libpq/pqcomm.h"
#include "lib/dllist.h"
-typedef enum {CONNECTION_OK,
- CONNECTION_BAD} ConnStatusType;
-
-typedef enum {
- PGRES_EMPTY_QUERY = 0,
- PGRES_COMMAND_OK, /* a query command that doesn't return */
- /* anything was executed properly by the backend */
- PGRES_TUPLES_OK, /* a query command that returns tuples */
- /* was executed properly by the backend, PGresult */
- /* contains the resulttuples */
- PGRES_COPY_OUT,
- PGRES_COPY_IN,
- PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the backend */
- PGRES_NONFATAL_ERROR,
- PGRES_FATAL_ERROR
-
-} ExecStatusType;
+ typedef enum
+ {
+ CONNECTION_OK,
+ CONNECTION_BAD
+ } ConnStatusType;
+
+ typedef enum
+ {
+ PGRES_EMPTY_QUERY = 0,
+ PGRES_COMMAND_OK, /* a query command that doesn't return */
+ /* anything was executed properly by the backend */
+ PGRES_TUPLES_OK, /* a query command that returns tuples */
+ /* was executed properly by the backend, PGresult */
+ /* contains the resulttuples */
+ PGRES_COPY_OUT,
+ PGRES_COPY_IN,
+ PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from
+ * the backend */
+ PGRES_NONFATAL_ERROR,
+ PGRES_FATAL_ERROR
+
+ } ExecStatusType;
/* string descriptions of the ExecStatusTypes */
-extern const char* pgresStatus[];
+ extern const char *pgresStatus[];
-/*
- * POSTGRES backend dependent Constants.
+/*
+ * POSTGRES backend dependent Constants.
*/
/* ERROR_MSG_LENGTH should really be the same as ELOG_MAXLEN in utils/elog.h*/
@@ -60,236 +66,273 @@ extern const char* pgresStatus[];
/* ----------------
* PQArgBlock --
- * Information (pointer to array of this structure) required
- * for the PQfn() call.
+ * Information (pointer to array of this structure) required
+ * for the PQfn() call.
* ----------------
*/
-typedef struct {
- int len;
- int isint;
- union {
- int *ptr; /* can't use void (dec compiler barfs) */
- int integer;
- } u;
-} PQArgBlock;
-
-typedef struct pgresAttDesc {
- char* name; /* type name */
- Oid adtid; /* type id */
- short adtsize; /* type size */
-} PGresAttDesc;
+ typedef struct
+ {
+ int len;
+ int isint;
+ union
+ {
+ int *ptr;/* can't use void (dec compiler barfs) */
+ int integer;
+ } u;
+ } PQArgBlock;
+
+ typedef struct pgresAttDesc
+ {
+ char *name; /* type name */
+ Oid adtid; /* type id */
+ short adtsize;/* type size */
+ } PGresAttDesc;
/* use char* for Attribute values,
ASCII tuples are guaranteed to be null-terminated
For binary tuples, the first four bytes of the value is the size,
- and the bytes afterwards are the value. The binary value is
+ and the bytes afterwards are the value. The binary value is
not guaranteed to be null-terminated. In fact, it can have embedded nulls*/
-#define NULL_LEN (-1) /* pg_result len for NULL value */
-
-typedef struct pgresAttValue {
- int len; /* length in bytes of the value */
- char *value; /* actual value */
-} PGresAttValue;
-
-typedef struct pgNotify {
- char relname[NAMEDATALEN]; /* name of relation containing data */
- int be_pid; /* process id of backend */
-} PGnotify;
-
-typedef struct pgLobjfuncs {
- Oid fn_lo_open; /* OID of backend function lo_open */
- Oid fn_lo_close; /* OID of backend function lo_close */
- Oid fn_lo_creat; /* OID of backend function lo_creat */
- Oid fn_lo_unlink; /* OID of backend function lo_unlink */
- Oid fn_lo_lseek; /* OID of backend function lo_lseek */
- Oid fn_lo_tell; /* OID of backend function lo_tell */
- Oid fn_lo_read; /* OID of backend function LOread */
- Oid fn_lo_write; /* OID of backend function LOwrite */
-} PGlobjfuncs;
+#define NULL_LEN (-1) /* pg_result len for NULL value */
+
+ typedef struct pgresAttValue
+ {
+ int len; /* length in bytes of the value */
+ char *value; /* actual value */
+ } PGresAttValue;
+
+ typedef struct pgNotify
+ {
+ char relname[NAMEDATALEN]; /* name of relation
+ * containing data */
+ int be_pid; /* process id of backend */
+ } PGnotify;
+
+ typedef struct pgLobjfuncs
+ {
+ Oid fn_lo_open; /* OID of backend function lo_open */
+ Oid fn_lo_close; /* OID of backend function
+ * lo_close */
+ Oid fn_lo_creat; /* OID of backend function
+ * lo_creat */
+ Oid fn_lo_unlink; /* OID of backend function
+ * lo_unlink */
+ Oid fn_lo_lseek; /* OID of backend function
+ * lo_lseek */
+ Oid fn_lo_tell; /* OID of backend function lo_tell */
+ Oid fn_lo_read; /* OID of backend function LOread */
+ Oid fn_lo_write; /* OID of backend function LOwrite */
+ } PGlobjfuncs;
/* PGconn encapsulates a connection to the backend */
-typedef struct pg_conn{
- char *pghost; /* the machine on which the server is running */
- char *pgtty; /* tty on which the backend messages is displayed */
- char *pgport; /* the communication port with the backend */
- char *pgoptions; /* options to start the backend with */
- char *dbName; /* database name */
- ConnStatusType status;
- char errorMessage[ERROR_MSG_LENGTH];
- /* pipes for be/fe communication */
- FILE *Pfin;
- FILE *Pfout;
- FILE *Pfdebug;
- void *port; /* really a Port* */
- int asyncNotifyWaiting;
- Dllist* notifyList;
- char *pguser; /* Postgres username of user who is connected */
- char *pgpass;
- char *pgauth;
- PGlobjfuncs *lobjfuncs; /* Backend function OID's for large object access */
-} PGconn;
+ typedef struct pg_conn
+ {
+ char *pghost; /* the machine on which the server is
+ * running */
+ char *pgtty; /* tty on which the backend messages is
+ * displayed */
+ char *pgport; /* the communication port with the backend */
+ char *pgoptions; /* options to start the backend
+ * with */
+ char *dbName; /* database name */
+ ConnStatusType status;
+ char errorMessage[ERROR_MSG_LENGTH];
+ /* pipes for be/fe communication */
+ FILE *Pfin;
+ FILE *Pfout;
+ FILE *Pfdebug;
+ void *port; /* really a Port* */
+ int asyncNotifyWaiting;
+ Dllist *notifyList;
+ char *pguser; /* Postgres username of user who is
+ * connected */
+ char *pgpass;
+ char *pgauth;
+ PGlobjfuncs *lobjfuncs; /* Backend function OID's for
+ * large object access */
+ } PGconn;
#define CMDSTATUS_LEN 40
/* PGresult encapsulates the result of a query */
/* unlike the old libpq, we assume that queries only return in one group */
-typedef struct pg_result{
- int ntups;
- int numAttributes;
- PGresAttDesc *attDescs;
- PGresAttValue* *tuples; /* each PGresTuple is an array of PGresAttValue's */
- int tupArrSize; /* size of tuples array allocated */
- ExecStatusType resultStatus;
- char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the last insert query*/
- int binary; /* binary tuple values if binary == 1, otherwise ASCII */
- PGconn* conn;
-} PGresult;
-
-typedef char pqbool;
- /* We can't use the conventional "bool", because we are designed to be
- included in a user's program, and user may already have that type
- defined. Pqbool, on the other hand, is unlikely to be used.
- */
-
-struct _PQprintOpt {
- pqbool header; /* print output field headings and row count */
- pqbool align; /* fill align the fields */
- pqbool standard; /* old brain dead format */
- pqbool html3; /* output html tables */
- pqbool expanded; /* expand tables */
- pqbool pager; /* use pager for output if needed */
- char *fieldSep; /* field separator */
- char *tableOpt; /* insert to HTML <table ...> */
- char *caption; /* HTML <caption> */
- char **fieldName; /* null terminated array of repalcement field names */
-};
-
-typedef struct _PQprintOpt PQprintOpt;
+ typedef struct pg_result
+ {
+ int ntups;
+ int numAttributes;
+ PGresAttDesc *attDescs;
+ PGresAttValue **tuples;/* each PGresTuple is an array of
+ * PGresAttValue's */
+ int tupArrSize; /* size of tuples array allocated */
+ ExecStatusType resultStatus;
+ char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the
+ * last insert query */
+ int binary; /* binary tuple values if binary == 1,
+ * otherwise ASCII */
+ PGconn *conn;
+ } PGresult;
+
+ typedef char pqbool;
+
+ /*
+ * We can't use the conventional "bool", because we are designed to be
+ * included in a user's program, and user may already have that type
+ * defined. Pqbool, on the other hand, is unlikely to be used.
+ */
+
+ struct _PQprintOpt
+ {
+ pqbool header; /* print output field headings and row
+ * count */
+ pqbool align; /* fill align the fields */
+ pqbool standard; /* old brain dead format */
+ pqbool html3; /* output html tables */
+ pqbool expanded; /* expand tables */
+ pqbool pager; /* use pager for output if needed */
+ char *fieldSep; /* field separator */
+ char *tableOpt; /* insert to HTML <table ...> */
+ char *caption;/* HTML <caption> */
+ char **fieldName; /* null terminated array of
+ * repalcement field names */
+ };
+
+ typedef struct _PQprintOpt PQprintOpt;
/* ----------------
* Structure for the conninfo parameter definitions of PQconnectdb()
* ----------------
*/
-struct _PQconninfoOption {
- char *keyword; /* The keyword of the option */
- char *environ; /* Fallback environment variable name */
- char *compiled; /* Fallback compiled in default value */
- char *val; /* Options value */
- char *label; /* Label for field in connect dialog */
- char *dispchar; /* Character to display for this field */
- /* in a connect dialog. Values are: */
- /* "" Display entered value as is */
- /* "*" Password field - hide value */
- /* "D" Debug options - don't */
- /* create a field by default */
- int dispsize; /* Field size in characters for dialog */
-};
-
-typedef struct _PQconninfoOption PQconninfoOption;
-
-/* === in fe-connect.c === */
- /* make a new client connection to the backend */
-extern PGconn* PQconnectdb(const char* conninfo);
-extern PQconninfoOption *PQconndefaults(void);
-extern PGconn* PQsetdb(const char* pghost, const char* pgport, const char* pgoptions,
- const char* pgtty, const char* dbName);
- /* close the current connection and free the PGconn data structure */
-extern void PQfinish(PGconn* conn);
- /* close the current connection and restablish a new one with the same
- parameters */
-extern void PQreset(PGconn* conn);
-
-extern char* PQdb(PGconn* conn);
-extern char* PQuser(PGconn* conn);
-extern char* PQhost(PGconn* conn);
-extern char* PQoptions(PGconn* conn);
-extern char* PQport(PGconn* conn);
-extern char* PQtty(PGconn* conn);
-extern ConnStatusType PQstatus(PGconn* conn);
-extern char* PQerrorMessage(PGconn* conn);
-extern void PQtrace(PGconn *conn, FILE* debug_port);
-extern void PQuntrace(PGconn *conn);
+ struct _PQconninfoOption
+ {
+ char *keyword;/* The keyword of the option */
+ char *environ;/* Fallback environment variable name */
+ char *compiled; /* Fallback compiled in default
+ * value */
+ char *val; /* Options value */
+ char *label; /* Label for field in connect dialog */
+ char *dispchar; /* Character to display for this
+ * field */
+ /* in a connect dialog. Values are: */
+ /* "" Display entered value as is */
+ /* "*" Password field - hide value */
+ /* "D" Debug options - don't */
+ /* create a field by default */
+ int dispsize; /* Field size in characters for
+ * dialog */
+ };
+
+ typedef struct _PQconninfoOption PQconninfoOption;
+
+/* === in fe-connect.c === */
+ /* make a new client connection to the backend */
+ extern PGconn *PQconnectdb(const char *conninfo);
+ extern PQconninfoOption *PQconndefaults(void);
+ extern PGconn *PQsetdb(const char *pghost, const char *pgport, const char *pgoptions,
+ const char *pgtty, const char *dbName);
+ /* close the current connection and free the PGconn data structure */
+ extern void PQfinish(PGconn * conn);
+
+ /*
+ * close the current connection and restablish a new one with the same
+ * parameters
+ */
+ extern void PQreset(PGconn * conn);
+
+ extern char *PQdb(PGconn * conn);
+ extern char *PQuser(PGconn * conn);
+ extern char *PQhost(PGconn * conn);
+ extern char *PQoptions(PGconn * conn);
+ extern char *PQport(PGconn * conn);
+ extern char *PQtty(PGconn * conn);
+ extern ConnStatusType PQstatus(PGconn * conn);
+ extern char *PQerrorMessage(PGconn * conn);
+ extern void PQtrace(PGconn * conn, FILE * debug_port);
+ extern void PQuntrace(PGconn * conn);
/* === in fe-exec.c === */
-extern PGresult* PQexec(PGconn* conn, const char* query);
-extern int PQgetline(PGconn *conn, char* string, int length);
-extern int PQendcopy(PGconn *conn);
-extern void PQputline(PGconn *conn, const char* string);
-extern ExecStatusType PQresultStatus(PGresult* res);
-extern int PQntuples(PGresult *res);
-extern int PQnfields(PGresult *res);
-extern char* PQfname(PGresult *res, int field_num);
-extern int PQfnumber(PGresult *res, const char* field_name);
-extern Oid PQftype(PGresult *res, int field_num);
-extern short PQfsize(PGresult *res, int field_num);
-extern char* PQcmdStatus(PGresult *res);
-extern const char* PQoidStatus(PGresult *res);
-extern const char* PQcmdTuples(PGresult *res);
-extern char* PQgetvalue(PGresult *res, int tup_num, int field_num);
-extern int PQgetlength(PGresult *res, int tup_num, int field_num);
-extern int PQgetisnull(PGresult *res, int tup_num, int field_num);
-extern void PQclear(PGresult* res);
+ extern PGresult *PQexec(PGconn * conn, const char *query);
+ extern int PQgetline(PGconn * conn, char *string, int length);
+ extern int PQendcopy(PGconn * conn);
+ extern void PQputline(PGconn * conn, const char *string);
+ extern ExecStatusType PQresultStatus(PGresult * res);
+ extern int PQntuples(PGresult * res);
+ extern int PQnfields(PGresult * res);
+ extern char *PQfname(PGresult * res, int field_num);
+ extern int PQfnumber(PGresult * res, const char *field_name);
+ extern Oid PQftype(PGresult * res, int field_num);
+ extern short PQfsize(PGresult * res, int field_num);
+ extern char *PQcmdStatus(PGresult * res);
+ extern const char *PQoidStatus(PGresult * res);
+ extern const char *PQcmdTuples(PGresult * res);
+ extern char *PQgetvalue(PGresult * res, int tup_num, int field_num);
+ extern int PQgetlength(PGresult * res, int tup_num, int field_num);
+ extern int PQgetisnull(PGresult * res, int tup_num, int field_num);
+ extern void PQclear(PGresult * res);
/* PQdisplayTuples() is a better version of PQprintTuples() */
-extern void PQdisplayTuples(PGresult *res,
- FILE *fp, /* where to send the output */
- int fillAlign, /* pad the fields with spaces */
- const char *fieldSep, /* field separator */
- int printHeader, /* display headers? */
- int quiet);
-extern void PQprintTuples(PGresult* res,
- FILE* fout, /* output stream */
- int printAttName,/* print attribute names or not*/
- int terseOutput, /* delimiter bars or not?*/
- int width /* width of column,
- if 0, use variable width */
- );
-extern void PQprint(FILE* fout, /* output stream */
- PGresult* res,
- PQprintOpt *ps /* option structure */
- );
-extern PGnotify* PQnotifies(PGconn *conn);
-extern PGresult* PQfn(PGconn* conn,
- int fnid,
- int *result_buf,
- int *result_len,
- int result_is_int,
- PQArgBlock *args,
- int nargs);
+ extern void PQdisplayTuples(PGresult * res,
+ FILE * fp, /* where to send the
+ * output */
+ int fillAlign, /* pad the fields with
+ * spaces */
+ const char *fieldSep, /* field separator */
+ int printHeader, /* display headers? */
+ int quiet);
+ extern void PQprintTuples(PGresult * res,
+ FILE * fout, /* output stream */
+ int printAttName, /* print attribute names
+ * or not */
+ int terseOutput, /* delimiter bars or
+ * not? */
+ int width /* width of column, if
+ * 0, use variable width */
+ );
+ extern void PQprint(FILE * fout, /* output stream */
+ PGresult * res,
+ PQprintOpt * ps /* option structure */
+ );
+ extern PGnotify *PQnotifies(PGconn * conn);
+ extern PGresult *PQfn(PGconn * conn,
+ int fnid,
+ int *result_buf,
+ int *result_len,
+ int result_is_int,
+ PQArgBlock * args,
+ int nargs);
/* === in fe-auth.c === */
-extern MsgType fe_getauthsvc(char* PQerrormsg);
-extern void fe_setauthsvc(const char *name, char* PQerrormsg);
-extern char *fe_getauthname(char* PQerrormsg);
+ extern MsgType fe_getauthsvc(char *PQerrormsg);
+ extern void fe_setauthsvc(const char *name, char *PQerrormsg);
+ extern char *fe_getauthname(char *PQerrormsg);
/* === in fe-misc.c === */
/* pqGets and pqPuts gets and sends strings to the file stream
- returns 0 if successful
- if debug is non-null, debugging output is sent to that stream
+ returns 0 if successful
+ if debug is non-null, debugging output is sent to that stream
*/
-extern int pqGets(char* s, int maxlen, FILE* stream, FILE* debug);
-extern int pqGetnchar(char* s, int maxlen, FILE* stream, FILE* debug);
-extern int pqPutnchar(const char* s, int maxlen, FILE* stream, FILE* debug);
-extern int pqPuts(const char* s, FILE* stream, FILE* debug );
-extern int pqGetc(FILE* stream, FILE *debug);
+ extern int pqGets(char *s, int maxlen, FILE * stream, FILE * debug);
+ extern int pqGetnchar(char *s, int maxlen, FILE * stream, FILE * debug);
+ extern int pqPutnchar(const char *s, int maxlen, FILE * stream, FILE * debug);
+ extern int pqPuts(const char *s, FILE * stream, FILE * debug);
+ extern int pqGetc(FILE * stream, FILE * debug);
/* get a n-byte integer from the stream into result */
/* returns 0 if successful */
-extern int pqGetInt(int* result, int bytes, FILE* stream, FILE *debug );
+ extern int pqGetInt(int *result, int bytes, FILE * stream, FILE * debug);
/* put a n-byte integer into the stream */
/* returns 0 if successful */
-extern int pqPutInt(const int n, int bytes, FILE* stream, FILE *debug );
-extern void pqFlush(FILE* stream, FILE* debug);
+ extern int pqPutInt(const int n, int bytes, FILE * stream, FILE * debug);
+ extern void pqFlush(FILE * stream, FILE * debug);
/* === in fe-lobj.c === */
-int lo_open(PGconn* conn, Oid lobjId, int mode);
-int lo_close(PGconn *conn, int fd);
-int lo_read(PGconn *conn, int fd, char *buf, int len);
-int lo_write(PGconn *conn, int fd, char *buf, int len);
-int lo_lseek(PGconn *conn, int fd, int offset, int whence);
-Oid lo_creat(PGconn *conn, int mode);
-int lo_tell(PGconn *conn, int fd);
-int lo_unlink(PGconn *conn, Oid lobjId);
-Oid lo_import(PGconn *conn, char *filename);
-int lo_export(PGconn *conn, Oid lobjId, char *filename);
+ int lo_open(PGconn * conn, Oid lobjId, int mode);
+ int lo_close(PGconn * conn, int fd);
+ int lo_read(PGconn * conn, int fd, char *buf, int len);
+ int lo_write(PGconn * conn, int fd, char *buf, int len);
+ int lo_lseek(PGconn * conn, int fd, int offset, int whence);
+ Oid lo_creat(PGconn * conn, int mode);
+ int lo_tell(PGconn * conn, int fd);
+ int lo_unlink(PGconn * conn, Oid lobjId);
+ Oid lo_import(PGconn * conn, char *filename);
+ int lo_export(PGconn * conn, Oid lobjId, char *filename);
/* max length of message to send */
#define MAX_MESSAGE_LEN 8193
@@ -299,25 +342,25 @@ int lo_export(PGconn *conn, Oid lobjId, char *filename);
/* fall back options if they are not specified by arguments or defined
by environment variables */
-#define DefaultHost "localhost"
-#define DefaultTty ""
+#define DefaultHost "localhost"
+#define DefaultTty ""
#define DefaultOption ""
-#define DefaultAuthtype ""
-#define DefaultPassword ""
+#define DefaultAuthtype ""
+#define DefaultPassword ""
-typedef void *TUPLE;
+ typedef void *TUPLE;
#define palloc malloc
#define pfree free
#if defined(sunos4)
-extern char *sys_errlist[];
+ extern char *sys_errlist[];
#define strerror(A) (sys_errlist[(A)])
-#endif /* sunos4 */
+#endif /* sunos4 */
#ifdef __cplusplus
};
-#endif
-#endif /* LIBPQ_FE_H */
+#endif
+#endif /* LIBPQ_FE_H */
diff --git a/src/interfaces/libpq/pqsignal.c b/src/interfaces/libpq/pqsignal.c
index a177012051a..c004704ba45 100644
--- a/src/interfaces/libpq/pqsignal.c
+++ b/src/interfaces/libpq/pqsignal.c
@@ -1,18 +1,18 @@
/*-------------------------------------------------------------------------
*
* pqsignal.c--
- * reliable BSD-style signal(2) routine stolen from RWW who stole it
- * from Stevens...
+ * reliable BSD-style signal(2) routine stolen from RWW who stole it
+ * from Stevens...
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/pqsignal.c,v 1.3 1996/12/26 22:08:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/pqsignal.c,v 1.4 1997/09/07 05:03:37 momjian Exp $
*
* NOTES
- * This shouldn't be in libpq, but the monitor and some other
- * things need it...
+ * This shouldn't be in libpq, but the monitor and some other
+ * things need it...
*
*-------------------------------------------------------------------------
*/
@@ -26,18 +26,20 @@ pqsigfunc
pqsignal(int signo, pqsigfunc func)
{
#if !defined(USE_POSIX_SIGNALS)
- return signal(signo, func);
+ return signal(signo, func);
#else
- struct sigaction act, oact;
-
- act.sa_handler = func;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- if (signo != SIGALRM) {
- act.sa_flags |= SA_RESTART;
- }
- if (sigaction(signo, &act, &oact) < 0)
- return(SIG_ERR);
- return(oact.sa_handler);
-#endif /* !USE_POSIX_SIGNALS */
+ struct sigaction act,
+ oact;
+
+ act.sa_handler = func;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ if (signo != SIGALRM)
+ {
+ act.sa_flags |= SA_RESTART;
+ }
+ if (sigaction(signo, &act, &oact) < 0)
+ return (SIG_ERR);
+ return (oact.sa_handler);
+#endif /* !USE_POSIX_SIGNALS */
}
diff --git a/src/interfaces/libpq/pqsignal.h b/src/interfaces/libpq/pqsignal.h
index 4d57549443f..e2f6d7a973b 100644
--- a/src/interfaces/libpq/pqsignal.h
+++ b/src/interfaces/libpq/pqsignal.h
@@ -1,16 +1,16 @@
/*-------------------------------------------------------------------------
*
* pqsignal.h--
- * prototypes for the reliable BSD-style signal(2) routine.
+ * prototypes for the reliable BSD-style signal(2) routine.
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pqsignal.h,v 1.2 1996/12/26 22:08:34 momjian Exp $
+ * $Id: pqsignal.h,v 1.3 1997/09/07 05:03:39 momjian Exp $
*
* NOTES
- * This shouldn't be in libpq, but the monitor and some other
- * things need it...
+ * This shouldn't be in libpq, but the monitor and some other
+ * things need it...
*
*-------------------------------------------------------------------------
*/
@@ -19,8 +19,8 @@
#include "c.h"
-typedef void (*pqsigfunc)(int);
+typedef void (*pqsigfunc) (int);
extern pqsigfunc pqsignal(int signo, pqsigfunc func);
-#endif /* PQSIGNAL_H */
+#endif /* PQSIGNAL_H */
diff --git a/src/lextest/lextest.c b/src/lextest/lextest.c
index 29542c89506..ccd8feb2b35 100644
--- a/src/lextest/lextest.c
+++ b/src/lextest/lextest.c
@@ -4,13 +4,15 @@
** tests for flex 2.5.3 bug
*/
-int main()
+int
+main()
{
yylex();
return 0;
}
-int yywrap()
+int
+yywrap()
{
return 1;
};
diff --git a/src/test/examples/testlibpq.c b/src/test/examples/testlibpq.c
index f3b9964416c..97c1a1043e7 100644
--- a/src/test/examples/testlibpq.c
+++ b/src/test/examples/testlibpq.c
@@ -1,118 +1,137 @@
/*
* testlibpq.c
- * Test the C version of LIBPQ, the POSTGRES frontend library.
+ * Test the C version of LIBPQ, the POSTGRES frontend library.
*
*
*/
#include <stdio.h>
#include "libpq-fe.h"
-void
-exit_nicely(PGconn* conn)
+void
+exit_nicely(PGconn * conn)
{
- PQfinish(conn);
- exit(1);
+ PQfinish(conn);
+ exit(1);
}
main()
{
- char *pghost, *pgport, *pgoptions, *pgtty;
- char* dbName;
- int nFields;
- int i,j;
+ char *pghost,
+ *pgport,
+ *pgoptions,
+ *pgtty;
+ char *dbName;
+ int nFields;
+ int i,
+ j;
#ifdef DEBUG
- FILE *debug;
-#endif /* DEBUG */
-
- PGconn* conn;
- PGresult* res;
-
- /* begin, by setting the parameters for a backend connection
- if the parameters are null, then the system will try to use
- reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants */
- pghost = NULL; /* host name of the backend server */
- pgport = NULL; /* port of the backend server */
- pgoptions = NULL; /* special options to start up the backend server */
- pgtty = NULL; /* debugging tty for the backend server */
- dbName = "template1";
-
- /* make a connection to the database */
- conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
-
- /* check to see that the backend connection was successfully made */
- if (PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", dbName);
- fprintf(stderr,"%s",PQerrorMessage(conn));
- exit_nicely(conn);
- }
+ FILE *debug;
+
+#endif /* DEBUG */
+
+ PGconn *conn;
+ PGresult *res;
+
+ /*
+ * begin, by setting the parameters for a backend connection if the
+ * parameters are null, then the system will try to use reasonable
+ * defaults by looking up environment variables or, failing that,
+ * using hardwired constants
+ */
+ pghost = NULL; /* host name of the backend server */
+ pgport = NULL; /* port of the backend server */
+ pgoptions = NULL; /* special options to start up the backend
+ * server */
+ pgtty = NULL; /* debugging tty for the backend server */
+ dbName = "template1";
+
+ /* make a connection to the database */
+ conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
+
+ /* check to see that the backend connection was successfully made */
+ if (PQstatus(conn) == CONNECTION_BAD)
+ {
+ fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
#ifdef DEBUG
- debug = fopen("/tmp/trace.out","w");
- PQtrace(conn, debug);
-#endif /* DEBUG */
-
- /* start a transaction block */
- res = PQexec(conn,"BEGIN");
- if (PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- PQclear(res);
- exit_nicely(conn);
- }
- /* should PQclear PGresult whenever it is no longer needed to avoid
- memory leaks */
- PQclear(res);
-
- /* fetch instances from the pg_database, the system catalog of databases*/
- res = PQexec(conn,"DECLARE myportal CURSOR FOR select * from pg_database");
- if (PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"DECLARE CURSOR command failed\n");
- PQclear(res);
- exit_nicely(conn);
- }
- PQclear(res);
-
- res = PQexec(conn,"FETCH ALL in myportal");
- if (PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
- PQclear(res);
- exit_nicely(conn);
- }
-
- /* first, print out the attribute names */
- nFields = PQnfields(res);
- for (i=0; i < nFields; i++) {
- printf("%-15s",PQfname(res,i));
- }
- printf("\n\n");
-
- /* next, print out the instances */
- for (i=0; i < PQntuples(res); i++) {
- for (j=0 ; j < nFields; j++) {
- printf("%-15s", PQgetvalue(res,i,j));
- }
- printf("\n");
- }
-
- PQclear(res);
-
- /* close the portal */
- res = PQexec(conn, "CLOSE myportal");
- PQclear(res);
-
- /* end the transaction */
- res = PQexec(conn, "END");
- PQclear(res);
-
- /* close the connection to the database and cleanup */
- PQfinish(conn);
+ debug = fopen("/tmp/trace.out", "w");
+ PQtrace(conn, debug);
+#endif /* DEBUG */
+
+ /* start a transaction block */
+ res = PQexec(conn, "BEGIN");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /*
+ * should PQclear PGresult whenever it is no longer needed to avoid
+ * memory leaks
+ */
+ PQclear(res);
+
+ /*
+ * fetch instances from the pg_database, the system catalog of
+ * databases
+ */
+ res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "DECLARE CURSOR command failed\n");
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ res = PQexec(conn, "FETCH ALL in myportal");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "FETCH ALL command didn't return tuples properly\n");
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /* first, print out the attribute names */
+ nFields = PQnfields(res);
+ for (i = 0; i < nFields; i++)
+ {
+ printf("%-15s", PQfname(res, i));
+ }
+ printf("\n\n");
+
+ /* next, print out the instances */
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ for (j = 0; j < nFields; j++)
+ {
+ printf("%-15s", PQgetvalue(res, i, j));
+ }
+ printf("\n");
+ }
+
+ PQclear(res);
+
+ /* close the portal */
+ res = PQexec(conn, "CLOSE myportal");
+ PQclear(res);
+
+ /* end the transaction */
+ res = PQexec(conn, "END");
+ PQclear(res);
+
+ /* close the connection to the database and cleanup */
+ PQfinish(conn);
#ifdef DEBUG
- fclose(debug);
-#endif /* DEBUG */
+ fclose(debug);
+#endif /* DEBUG */
- exit(0);
+ exit(0);
}
-
-
diff --git a/src/test/examples/testlibpq2.c b/src/test/examples/testlibpq2.c
index 801feec9bc8..d38ea1e906e 100644
--- a/src/test/examples/testlibpq2.c
+++ b/src/test/examples/testlibpq2.c
@@ -1,6 +1,6 @@
/*
* testlibpq2.c
- * Test of the asynchronous notification interface
+ * Test of the asynchronous notification interface
*
populate a database with the following:
@@ -21,73 +21,87 @@ INSERT INTO TBL1 values (10);
#include <stdio.h>
#include "libpq-fe.h"
-void exit_nicely(PGconn* conn)
+void
+exit_nicely(PGconn * conn)
{
- PQfinish(conn);
- exit(1);
+ PQfinish(conn);
+ exit(1);
}
main()
{
- char *pghost, *pgport, *pgoptions, *pgtty;
- char* dbName;
- int nFields;
- int i,j;
-
- PGconn* conn;
- PGresult* res;
- PGnotify* notify;
-
- /* begin, by setting the parameters for a backend connection
- if the parameters are null, then the system will try to use
- reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants */
- pghost = NULL; /* host name of the backend server */
- pgport = NULL; /* port of the backend server */
- pgoptions = NULL; /* special options to start up the backend server */
- pgtty = NULL; /* debugging tty for the backend server */
- dbName = getenv("USER"); /* change this to the name of your test database*/
-
- /* make a connection to the database */
- conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
-
- /* check to see that the backend connection was successfully made */
- if (PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", dbName);
- fprintf(stderr,"%s",PQerrorMessage(conn));
- exit_nicely(conn);
- }
-
- res = PQexec(conn, "LISTEN TBL2");
- if (PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"LISTEN command failed\n");
- PQclear(res);
- exit_nicely(conn);
- }
- /* should PQclear PGresult whenever it is no longer needed to avoid
- memory leaks */
- PQclear(res);
-
- while (1) {
- /* async notification only come back as a result of a query*/
- /* we can send empty queries */
- res = PQexec(conn, " ");
-/* printf("res->status = %s\n", pgresStatus[PQresultStatus(res)]); */
- /* check for asynchronous returns */
- notify = PQnotifies(conn);
- if (notify) {
- fprintf(stderr,
- "ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
- notify->relname, notify->be_pid);
- free(notify);
- break;
- }
- PQclear(res);
- }
-
- /* close the connection to the database and cleanup */
- PQfinish(conn);
+ char *pghost,
+ *pgport,
+ *pgoptions,
+ *pgtty;
+ char *dbName;
+ int nFields;
+ int i,
+ j;
+
+ PGconn *conn;
+ PGresult *res;
+ PGnotify *notify;
+
+ /*
+ * begin, by setting the parameters for a backend connection if the
+ * parameters are null, then the system will try to use reasonable
+ * defaults by looking up environment variables or, failing that,
+ * using hardwired constants
+ */
+ pghost = NULL; /* host name of the backend server */
+ pgport = NULL; /* port of the backend server */
+ pgoptions = NULL; /* special options to start up the backend
+ * server */
+ pgtty = NULL; /* debugging tty for the backend server */
+ dbName = getenv("USER"); /* change this to the name of your test
+ * database */
+
+ /* make a connection to the database */
+ conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
+
+ /* check to see that the backend connection was successfully made */
+ if (PQstatus(conn) == CONNECTION_BAD)
+ {
+ fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ res = PQexec(conn, "LISTEN TBL2");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "LISTEN command failed\n");
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /*
+ * should PQclear PGresult whenever it is no longer needed to avoid
+ * memory leaks
+ */
+ PQclear(res);
+
+ while (1)
+ {
+ /* async notification only come back as a result of a query */
+ /* we can send empty queries */
+ res = PQexec(conn, " ");
+/* printf("res->status = %s\n", pgresStatus[PQresultStatus(res)]); */
+ /* check for asynchronous returns */
+ notify = PQnotifies(conn);
+ if (notify)
+ {
+ fprintf(stderr,
+ "ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
+ notify->relname, notify->be_pid);
+ free(notify);
+ break;
+ }
+ PQclear(res);
+ }
+
+ /* close the connection to the database and cleanup */
+ PQfinish(conn);
}
-
-
diff --git a/src/test/examples/testlibpq3.c b/src/test/examples/testlibpq3.c
index bab22b3b1b3..16035585fed 100644
--- a/src/test/examples/testlibpq3.c
+++ b/src/test/examples/testlibpq3.c
@@ -1,12 +1,12 @@
/*
* testlibpq3.c
- * Test the C version of LIBPQ, the POSTGRES frontend library.
- * tests the binary cursor interface
+ * Test the C version of LIBPQ, the POSTGRES frontend library.
+ * tests the binary cursor interface
*
*
*
populate a database by doing the following:
-
+
CREATE TABLE test1 (i int4, d float4, p polygon);
INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);
@@ -18,137 +18,162 @@ INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);
tuple 0: got
i = (4 bytes) 1,
d = (4 bytes) 3.567000,
- p = (4 bytes) 2 points boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
+ p = (4 bytes) 2 points boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
tuple 1: got
i = (4 bytes) 2,
d = (4 bytes) 89.050003,
- p = (4 bytes) 2 points boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)
+ p = (4 bytes) 2 points boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)
*
*/
#include <stdio.h>
#include "libpq-fe.h"
-#include "utils/geo-decls.h" /* for the POLYGON type */
+#include "utils/geo-decls.h" /* for the POLYGON type */
-void exit_nicely(PGconn* conn)
+void
+exit_nicely(PGconn * conn)
{
- PQfinish(conn);
- exit(1);
+ PQfinish(conn);
+ exit(1);
}
main()
{
- char *pghost, *pgport, *pgoptions, *pgtty;
- char* dbName;
- int nFields;
- int i,j;
- int i_fnum, d_fnum, p_fnum;
-
- PGconn* conn;
- PGresult* res;
-
- /* begin, by setting the parameters for a backend connection
- if the parameters are null, then the system will try to use
- reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants */
- pghost = NULL; /* host name of the backend server */
- pgport = NULL; /* port of the backend server */
- pgoptions = NULL; /* special options to start up the backend server */
- pgtty = NULL; /* debugging tty for the backend server */
-
- dbName = getenv("USER"); /* change this to the name of your test database*/
-
- /* make a connection to the database */
- conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
-
- /* check to see that the backend connection was successfully made */
- if (PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", dbName);
- fprintf(stderr,"%s",PQerrorMessage(conn));
- exit_nicely(conn);
- }
-
- /* start a transaction block */
- res = PQexec(conn,"BEGIN");
- if (PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- PQclear(res);
- exit_nicely(conn);
- }
- /* should PQclear PGresult whenever it is no longer needed to avoid
- memory leaks */
- PQclear(res);
-
- /* fetch instances from the pg_database, the system catalog of databases*/
- res = PQexec(conn,"DECLARE mycursor BINARY CURSOR FOR select * from test1");
- if (res == NULL ||
- PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"DECLARE CURSOR command failed\n");
- if (res)
+ char *pghost,
+ *pgport,
+ *pgoptions,
+ *pgtty;
+ char *dbName;
+ int nFields;
+ int i,
+ j;
+ int i_fnum,
+ d_fnum,
+ p_fnum;
+
+ PGconn *conn;
+ PGresult *res;
+
+ /*
+ * begin, by setting the parameters for a backend connection if the
+ * parameters are null, then the system will try to use reasonable
+ * defaults by looking up environment variables or, failing that,
+ * using hardwired constants
+ */
+ pghost = NULL; /* host name of the backend server */
+ pgport = NULL; /* port of the backend server */
+ pgoptions = NULL; /* special options to start up the backend
+ * server */
+ pgtty = NULL; /* debugging tty for the backend server */
+
+ dbName = getenv("USER"); /* change this to the name of your test
+ * database */
+
+ /* make a connection to the database */
+ conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
+
+ /* check to see that the backend connection was successfully made */
+ if (PQstatus(conn) == CONNECTION_BAD)
+ {
+ fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ /* start a transaction block */
+ res = PQexec(conn, "BEGIN");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /*
+ * should PQclear PGresult whenever it is no longer needed to avoid
+ * memory leaks
+ */
PQclear(res);
- exit_nicely(conn);
- }
- PQclear(res);
-
- res = PQexec(conn,"FETCH ALL in mycursor");
- if (res == NULL ||
- PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
- if (res)
+
+ /*
+ * fetch instances from the pg_database, the system catalog of
+ * databases
+ */
+ res = PQexec(conn, "DECLARE mycursor BINARY CURSOR FOR select * from test1");
+ if (res == NULL ||
+ PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "DECLARE CURSOR command failed\n");
+ if (res)
+ PQclear(res);
+ exit_nicely(conn);
+ }
PQclear(res);
- exit_nicely(conn);
- }
-
- i_fnum = PQfnumber(res,"i");
- d_fnum = PQfnumber(res,"d");
- p_fnum = PQfnumber(res,"p");
-
- for (i=0;i<3;i++) {
- printf("type[%d] = %d, size[%d] = %d\n",
- i, PQftype(res,i),
- i, PQfsize(res,i));
- }
- for (i=0; i < PQntuples(res); i++) {
- int *ival;
- float *dval;
- int plen;
- POLYGON* pval;
- /* we hard-wire this to the 3 fields we know about */
- ival = (int*)PQgetvalue(res,i,i_fnum);
- dval = (float*)PQgetvalue(res,i,d_fnum);
- plen = PQgetlength(res,i,p_fnum);
-
- /* plen doesn't include the length field so need to increment by VARHDSZ*/
- pval = (POLYGON*) malloc(plen + VARHDRSZ);
- pval->size = plen;
- memmove((char*)&pval->npts, PQgetvalue(res,i,p_fnum), plen);
- printf("tuple %d: got\n", i);
- printf(" i = (%d bytes) %d,\n",
- PQgetlength(res,i,i_fnum), *ival);
- printf(" d = (%d bytes) %f,\n",
- PQgetlength(res,i,d_fnum), *dval);
- printf(" p = (%d bytes) %d points \tboundbox = (hi=%f/%f, lo = %f,%f)\n",
- PQgetlength(res,i,d_fnum),
- pval->npts,
- pval->boundbox.xh,
- pval->boundbox.yh,
- pval->boundbox.xl,
- pval->boundbox.yl);
- }
-
- PQclear(res);
-
- /* close the portal */
- res = PQexec(conn, "CLOSE mycursor");
- PQclear(res);
-
- /* end the transaction */
- res = PQexec(conn, "END");
- PQclear(res);
-
- /* close the connection to the database and cleanup */
- PQfinish(conn);
-}
-
+ res = PQexec(conn, "FETCH ALL in mycursor");
+ if (res == NULL ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "FETCH ALL command didn't return tuples properly\n");
+ if (res)
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ i_fnum = PQfnumber(res, "i");
+ d_fnum = PQfnumber(res, "d");
+ p_fnum = PQfnumber(res, "p");
+
+ for (i = 0; i < 3; i++)
+ {
+ printf("type[%d] = %d, size[%d] = %d\n",
+ i, PQftype(res, i),
+ i, PQfsize(res, i));
+ }
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ int *ival;
+ float *dval;
+ int plen;
+ POLYGON *pval;
+
+ /* we hard-wire this to the 3 fields we know about */
+ ival = (int *) PQgetvalue(res, i, i_fnum);
+ dval = (float *) PQgetvalue(res, i, d_fnum);
+ plen = PQgetlength(res, i, p_fnum);
+
+ /*
+ * plen doesn't include the length field so need to increment by
+ * VARHDSZ
+ */
+ pval = (POLYGON *) malloc(plen + VARHDRSZ);
+ pval->size = plen;
+ memmove((char *) &pval->npts, PQgetvalue(res, i, p_fnum), plen);
+ printf("tuple %d: got\n", i);
+ printf(" i = (%d bytes) %d,\n",
+ PQgetlength(res, i, i_fnum), *ival);
+ printf(" d = (%d bytes) %f,\n",
+ PQgetlength(res, i, d_fnum), *dval);
+ printf(" p = (%d bytes) %d points \tboundbox = (hi=%f/%f, lo = %f,%f)\n",
+ PQgetlength(res, i, d_fnum),
+ pval->npts,
+ pval->boundbox.xh,
+ pval->boundbox.yh,
+ pval->boundbox.xl,
+ pval->boundbox.yl);
+ }
+ PQclear(res);
+
+ /* close the portal */
+ res = PQexec(conn, "CLOSE mycursor");
+ PQclear(res);
+
+ /* end the transaction */
+ res = PQexec(conn, "END");
+ PQclear(res);
+
+ /* close the connection to the database and cleanup */
+ PQfinish(conn);
+
+}
diff --git a/src/test/examples/testlibpq4.c b/src/test/examples/testlibpq4.c
index 5e040971192..1d6c8f78856 100644
--- a/src/test/examples/testlibpq4.c
+++ b/src/test/examples/testlibpq4.c
@@ -1,6 +1,6 @@
/*
* testlibpq4.c
- * this test programs shows to use LIBPQ to make multiple backend
+ * this test programs shows to use LIBPQ to make multiple backend
* connections
*
*
@@ -8,120 +8,142 @@
#include <stdio.h>
#include "libpq-fe.h"
-void
-exit_nicely(PGconn* conn1, PGconn* conn2)
+void
+exit_nicely(PGconn * conn1, PGconn * conn2)
{
- if (conn1)
- PQfinish(conn1);
- if (conn2)
- PQfinish(conn2);
- exit(1);
+ if (conn1)
+ PQfinish(conn1);
+ if (conn2)
+ PQfinish(conn2);
+ exit(1);
}
-void check_conn(PGconn* conn)
+void
+check_conn(PGconn * conn)
{
- /* check to see that the backend connection was successfully made */
- if (PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", dbName);
- fprintf(stderr,"%s",PQerrorMessage(conn));
- exit(1);
- }
+ /* check to see that the backend connection was successfully made */
+ if (PQstatus(conn) == CONNECTION_BAD)
+ {
+ fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit(1);
+ }
}
main()
{
- char *pghost, *pgport, *pgoptions, *pgtty;
- char* dbName1, dbName2;
- char* tblName;
- int nFields;
- int i,j;
-
- PGconn* conn1, conn2;
- PGresult* res1, res2;
-
- if (argc != 4)
- {
- fprintf(stderr,"usage: %s tableName dbName1 dbName2\n",argv[0]);
- fprintf(stderr," compares two tables in two databases\n");
- exit(1);
- }
- tblName = argv[1];
- dbName1 = argv[2];
- dbName2 = argv[3];
-
-
- /* begin, by setting the parameters for a backend connection
- if the parameters are null, then the system will try to use
- reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants */
- pghost = NULL; /* host name of the backend server */
- pgport = NULL; /* port of the backend server */
- pgoptions = NULL; /* special options to start up the backend server */
- pgtty = NULL; /* debugging tty for the backend server */
-
- /* make a connection to the database */
- conn1 = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName1);
- check_conn(conn1);
-
- conn2 = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName2);
- check_conn(conn2);
-
- /* start a transaction block */
- res1 = PQexec(conn1,"BEGIN");
- if (PQresultStatus(res1) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed\n");
- PQclear(res1);
- exit_nicely(conn1,conn2);
- }
- /* should PQclear PGresult whenever it is no longer needed to avoid
- memory leaks */
- PQclear(res1);
-
- /* fetch instances from the pg_database, the system catalog of databases*/
- res = PQexec(conn,"DECLARE myportal CURSOR FOR select * from pg_database");
- if (PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"DECLARE CURSOR command failed\n");
- PQclear(res);
- exit_nicely(conn);
- }
- PQclear(res);
-
- res = PQexec(conn,"FETCH ALL in myportal");
- if (PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"FETCH ALL command didn't return tuples properly\n");
- PQclear(res);
- exit_nicely(conn);
- }
-
- /* first, print out the attribute names */
- nFields = PQnfields(res);
- for (i=0; i < nFields; i++) {
- printf("%-15s",PQfname(res,i));
- }
- printf("\n\n");
-
- /* next, print out the instances */
- for (i=0; i < PQntuples(res); i++) {
- for (j=0 ; j < nFields; j++) {
- printf("%-15s", PQgetvalue(res,i,j));
- }
- printf("\n");
- }
-
- PQclear(res);
-
- /* close the portal */
- res = PQexec(conn, "CLOSE myportal");
- PQclear(res);
-
- /* end the transaction */
- res = PQexec(conn, "END");
- PQclear(res);
-
- /* close the connection to the database and cleanup */
- PQfinish(conn);
-
-/* fclose(debug); */
+ char *pghost,
+ *pgport,
+ *pgoptions,
+ *pgtty;
+ char *dbName1,
+ dbName2;
+ char *tblName;
+ int nFields;
+ int i,
+ j;
+
+ PGconn *conn1,
+ conn2;
+ PGresult *res1,
+ res2;
+
+ if (argc != 4)
+ {
+ fprintf(stderr, "usage: %s tableName dbName1 dbName2\n", argv[0]);
+ fprintf(stderr, " compares two tables in two databases\n");
+ exit(1);
+ }
+ tblName = argv[1];
+ dbName1 = argv[2];
+ dbName2 = argv[3];
+
+
+ /*
+ * begin, by setting the parameters for a backend connection if the
+ * parameters are null, then the system will try to use reasonable
+ * defaults by looking up environment variables or, failing that,
+ * using hardwired constants
+ */
+ pghost = NULL; /* host name of the backend server */
+ pgport = NULL; /* port of the backend server */
+ pgoptions = NULL; /* special options to start up the backend
+ * server */
+ pgtty = NULL; /* debugging tty for the backend server */
+
+ /* make a connection to the database */
+ conn1 = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName1);
+ check_conn(conn1);
+
+ conn2 = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName2);
+ check_conn(conn2);
+
+ /* start a transaction block */
+ res1 = PQexec(conn1, "BEGIN");
+ if (PQresultStatus(res1) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed\n");
+ PQclear(res1);
+ exit_nicely(conn1, conn2);
+ }
+
+ /*
+ * should PQclear PGresult whenever it is no longer needed to avoid
+ * memory leaks
+ */
+ PQclear(res1);
+
+ /*
+ * fetch instances from the pg_database, the system catalog of
+ * databases
+ */
+ res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "DECLARE CURSOR command failed\n");
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ res = PQexec(conn, "FETCH ALL in myportal");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "FETCH ALL command didn't return tuples properly\n");
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /* first, print out the attribute names */
+ nFields = PQnfields(res);
+ for (i = 0; i < nFields; i++)
+ {
+ printf("%-15s", PQfname(res, i));
+ }
+ printf("\n\n");
+
+ /* next, print out the instances */
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ for (j = 0; j < nFields; j++)
+ {
+ printf("%-15s", PQgetvalue(res, i, j));
+ }
+ printf("\n");
+ }
+
+ PQclear(res);
+
+ /* close the portal */
+ res = PQexec(conn, "CLOSE myportal");
+ PQclear(res);
+
+ /* end the transaction */
+ res = PQexec(conn, "END");
+ PQclear(res);
+
+ /* close the connection to the database and cleanup */
+ PQfinish(conn);
+
+/* fclose(debug); */
}
-
-
diff --git a/src/test/examples/testlo.c b/src/test/examples/testlo.c
index c9324f89426..ef207e373d3 100644
--- a/src/test/examples/testlo.c
+++ b/src/test/examples/testlo.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* testlo.c--
- * test using large objects with libpq
+ * test using large objects with libpq
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/test/examples/testlo.c,v 1.3 1997/08/12 22:55:19 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/test/examples/testlo.c,v 1.4 1997/09/07 05:04:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,225 +21,247 @@
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
-#define BUFSIZE 1024
+#define BUFSIZE 1024
/*
* importFile -
- * import file "in_filename" into database as large object "lobjOid"
+ * import file "in_filename" into database as large object "lobjOid"
*
*/
-Oid importFile(PGconn *conn, char *filename)
+Oid
+importFile(PGconn * conn, char *filename)
{
- Oid lobjId;
- int lobj_fd;
- char buf[BUFSIZE];
- int nbytes, tmp;
- int fd;
-
- /*
- * open the file to be read in
- */
- fd = open(filename, O_RDONLY, 0666);
- if (fd < 0) { /* error */
- fprintf(stderr, "can't open unix file\"%s\"\n", filename);
- }
-
- /*
- * create the large object
- */
- lobjId = lo_creat(conn, INV_READ|INV_WRITE);
- if (lobjId == 0) {
- fprintf(stderr, "can't create large object");
- }
-
- lobj_fd = lo_open(conn, lobjId, INV_WRITE);
- /*
- * read in from the Unix file and write to the inversion file
- */
- while ((nbytes = read(fd, buf, BUFSIZE)) > 0) {
- tmp = lo_write(conn, lobj_fd, buf, nbytes);
- if (tmp < nbytes) {
- fprintf(stderr, "error while reading \"%s\"", filename);
+ Oid lobjId;
+ int lobj_fd;
+ char buf[BUFSIZE];
+ int nbytes,
+ tmp;
+ int fd;
+
+ /*
+ * open the file to be read in
+ */
+ fd = open(filename, O_RDONLY, 0666);
+ if (fd < 0)
+ { /* error */
+ fprintf(stderr, "can't open unix file\"%s\"\n", filename);
+ }
+
+ /*
+ * create the large object
+ */
+ lobjId = lo_creat(conn, INV_READ | INV_WRITE);
+ if (lobjId == 0)
+ {
+ fprintf(stderr, "can't create large object");
}
- }
-
- close(fd);
- lo_close(conn, lobj_fd);
- return lobjId;
+ lobj_fd = lo_open(conn, lobjId, INV_WRITE);
+
+ /*
+ * read in from the Unix file and write to the inversion file
+ */
+ while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
+ {
+ tmp = lo_write(conn, lobj_fd, buf, nbytes);
+ if (tmp < nbytes)
+ {
+ fprintf(stderr, "error while reading \"%s\"", filename);
+ }
+ }
+
+ close(fd);
+ lo_close(conn, lobj_fd);
+
+ return lobjId;
}
-void pickout(PGconn *conn, Oid lobjId, int start, int len)
+void
+pickout(PGconn * conn, Oid lobjId, int start, int len)
{
- int lobj_fd;
- char* buf;
- int nbytes;
- int nread;
-
- lobj_fd = lo_open(conn, lobjId, INV_READ);
- if (lobj_fd < 0) {
- fprintf(stderr,"can't open large object %d",
- lobjId);
- }
-
- lo_lseek(conn, lobj_fd, start, SEEK_SET);
- buf = malloc(len+1);
-
- nread = 0;
- while (len - nread > 0) {
- nbytes = lo_read(conn, lobj_fd, buf, len - nread);
- buf[nbytes] = '\0';
- fprintf(stderr,">>> %s", buf);
- nread += nbytes;
- }
- fprintf(stderr,"\n");
- lo_close(conn, lobj_fd);
+ int lobj_fd;
+ char *buf;
+ int nbytes;
+ int nread;
+
+ lobj_fd = lo_open(conn, lobjId, INV_READ);
+ if (lobj_fd < 0)
+ {
+ fprintf(stderr, "can't open large object %d",
+ lobjId);
+ }
+
+ lo_lseek(conn, lobj_fd, start, SEEK_SET);
+ buf = malloc(len + 1);
+
+ nread = 0;
+ while (len - nread > 0)
+ {
+ nbytes = lo_read(conn, lobj_fd, buf, len - nread);
+ buf[nbytes] = '\0';
+ fprintf(stderr, ">>> %s", buf);
+ nread += nbytes;
+ }
+ fprintf(stderr, "\n");
+ lo_close(conn, lobj_fd);
}
-void overwrite(PGconn *conn, Oid lobjId, int start, int len)
+void
+overwrite(PGconn * conn, Oid lobjId, int start, int len)
{
- int lobj_fd;
- char* buf;
- int nbytes;
- int nwritten;
- int i;
-
- lobj_fd = lo_open(conn, lobjId, INV_READ);
- if (lobj_fd < 0) {
- fprintf(stderr,"can't open large object %d",
- lobjId);
- }
-
- lo_lseek(conn, lobj_fd, start, SEEK_SET);
- buf = malloc(len+1);
-
- for (i=0;i<len;i++)
- buf[i] = 'X';
- buf[i] = '\0';
-
- nwritten = 0;
- while (len - nwritten > 0) {
- nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
- nwritten += nbytes;
- }
- fprintf(stderr,"\n");
- lo_close(conn, lobj_fd);
+ int lobj_fd;
+ char *buf;
+ int nbytes;
+ int nwritten;
+ int i;
+
+ lobj_fd = lo_open(conn, lobjId, INV_READ);
+ if (lobj_fd < 0)
+ {
+ fprintf(stderr, "can't open large object %d",
+ lobjId);
+ }
+
+ lo_lseek(conn, lobj_fd, start, SEEK_SET);
+ buf = malloc(len + 1);
+
+ for (i = 0; i < len; i++)
+ buf[i] = 'X';
+ buf[i] = '\0';
+
+ nwritten = 0;
+ while (len - nwritten > 0)
+ {
+ nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
+ nwritten += nbytes;
+ }
+ fprintf(stderr, "\n");
+ lo_close(conn, lobj_fd);
}
/*
* exportFile -
- * export large object "lobjOid" to file "out_filename"
+ * export large object "lobjOid" to file "out_filename"
*
*/
-void exportFile(PGconn *conn, Oid lobjId, char *filename)
+void
+exportFile(PGconn * conn, Oid lobjId, char *filename)
{
- int lobj_fd;
- char buf[BUFSIZE];
- int nbytes, tmp;
- int fd;
-
- /*
- * create an inversion "object"
- */
- lobj_fd = lo_open(conn, lobjId, INV_READ);
- if (lobj_fd < 0) {
- fprintf(stderr,"can't open large object %d",
- lobjId);
- }
-
- /*
- * open the file to be written to
- */
- fd = open(filename, O_CREAT|O_WRONLY, 0666);
- if (fd < 0) { /* error */
- fprintf(stderr, "can't open unix file\"%s\"",
- filename);
- }
-
- /*
- * read in from the Unix file and write to the inversion file
- */
- while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) {
- tmp = write(fd, buf, nbytes);
- if (tmp < nbytes) {
- fprintf(stderr,"error while writing \"%s\"",
- filename);
+ int lobj_fd;
+ char buf[BUFSIZE];
+ int nbytes,
+ tmp;
+ int fd;
+
+ /*
+ * create an inversion "object"
+ */
+ lobj_fd = lo_open(conn, lobjId, INV_READ);
+ if (lobj_fd < 0)
+ {
+ fprintf(stderr, "can't open large object %d",
+ lobjId);
+ }
+
+ /*
+ * open the file to be written to
+ */
+ fd = open(filename, O_CREAT | O_WRONLY, 0666);
+ if (fd < 0)
+ { /* error */
+ fprintf(stderr, "can't open unix file\"%s\"",
+ filename);
+ }
+
+ /*
+ * read in from the Unix file and write to the inversion file
+ */
+ while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
+ {
+ tmp = write(fd, buf, nbytes);
+ if (tmp < nbytes)
+ {
+ fprintf(stderr, "error while writing \"%s\"",
+ filename);
+ }
}
- }
- lo_close(conn, lobj_fd);
- close(fd);
+ lo_close(conn, lobj_fd);
+ close(fd);
- return;
+ return;
}
-void
-exit_nicely(PGconn* conn)
+void
+exit_nicely(PGconn * conn)
{
- PQfinish(conn);
- exit(1);
+ PQfinish(conn);
+ exit(1);
}
int
main(int argc, char **argv)
{
- char *in_filename, *out_filename;
- char *database;
- Oid lobjOid;
- PGconn *conn;
- PGresult *res;
-
- if (argc != 4) {
- fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
- argv[0]);
- exit(1);
- }
-
- database = argv[1];
- in_filename = argv[2];
- out_filename = argv[3];
-
- /*
- * set up the connection
- */
- conn = PQsetdb(NULL, NULL, NULL, NULL, database);
-
- /* check to see that the backend connection was successfully made */
- if (PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", database);
- fprintf(stderr,"%s",PQerrorMessage(conn));
- exit_nicely(conn);
- }
-
- res = PQexec(conn, "begin");
- PQclear(res);
- printf("importing file \"%s\" ...\n", in_filename);
-/* lobjOid = importFile(conn, in_filename); */
- lobjOid = lo_import(conn, in_filename);
- if (lobjOid == 0)
- {
- fprintf(stderr,"%s\n",PQerrorMessage(conn));
- }
+ char *in_filename,
+ *out_filename;
+ char *database;
+ Oid lobjOid;
+ PGconn *conn;
+ PGresult *res;
+
+ if (argc != 4)
+ {
+ fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
+ argv[0]);
+ exit(1);
+ }
+
+ database = argv[1];
+ in_filename = argv[2];
+ out_filename = argv[3];
+
+ /*
+ * set up the connection
+ */
+ conn = PQsetdb(NULL, NULL, NULL, NULL, database);
+
+ /* check to see that the backend connection was successfully made */
+ if (PQstatus(conn) == CONNECTION_BAD)
+ {
+ fprintf(stderr, "Connection to database '%s' failed.\n", database);
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ res = PQexec(conn, "begin");
+ PQclear(res);
+ printf("importing file \"%s\" ...\n", in_filename);
+/* lobjOid = importFile(conn, in_filename); */
+ lobjOid = lo_import(conn, in_filename);
+ if (lobjOid == 0)
+ {
+ fprintf(stderr, "%s\n", PQerrorMessage(conn));
+ }
/*
- printf("\tas large object %d.\n", lobjOid);
+ printf("\tas large object %d.\n", lobjOid);
- printf("picking out bytes 1000-2000 of the large object\n");
- pickout(conn, lobjOid, 1000, 1000);
+ printf("picking out bytes 1000-2000 of the large object\n");
+ pickout(conn, lobjOid, 1000, 1000);
- printf("overwriting bytes 1000-2000 of the large object with X's\n");
- overwrite(conn, lobjOid, 1000, 1000);
+ printf("overwriting bytes 1000-2000 of the large object with X's\n");
+ overwrite(conn, lobjOid, 1000, 1000);
*/
- printf("exporting large object to file \"%s\" ...\n", out_filename);
-/* exportFile(conn, lobjOid, out_filename); */
- if (!lo_export(conn, lobjOid,out_filename))
- {
- fprintf(stderr,"%s\n",PQerrorMessage(conn));
- }
-
- res = PQexec(conn, "end");
- PQclear(res);
- PQfinish(conn);
- exit(0);
+ printf("exporting large object to file \"%s\" ...\n", out_filename);
+/* exportFile(conn, lobjOid, out_filename); */
+ if (!lo_export(conn, lobjOid, out_filename))
+ {
+ fprintf(stderr, "%s\n", PQerrorMessage(conn));
+ }
+
+ res = PQexec(conn, "end");
+ PQclear(res);
+ PQfinish(conn);
+ exit(0);
}
diff --git a/src/test/examples/testlo2.c b/src/test/examples/testlo2.c
index 36a5ce4fa44..f915a3ba3eb 100644
--- a/src/test/examples/testlo2.c
+++ b/src/test/examples/testlo2.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* lotest.c--
- * test using large objects with libpq
+ * test using large objects with libpq
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/test/examples/Attic/testlo2.c,v 1.2 1997/08/12 22:55:21 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/test/examples/Attic/testlo2.c,v 1.3 1997/09/07 05:04:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,219 +15,241 @@
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
-#define BUFSIZE 1024
+#define BUFSIZE 1024
/*
* importFile -
- * import file "in_filename" into database as large object "lobjOid"
+ * import file "in_filename" into database as large object "lobjOid"
*
*/
-Oid importFile(PGconn *conn, char *filename)
+Oid
+importFile(PGconn * conn, char *filename)
{
- Oid lobjId;
- int lobj_fd;
- char buf[BUFSIZE];
- int nbytes, tmp;
- int fd;
-
- /*
- * open the file to be read in
- */
- fd = open(filename, O_RDONLY, 0666);
- if (fd < 0) { /* error */
- fprintf(stderr, "can't open unix file\"%s\"\n", filename);
- }
-
- /*
- * create the large object
- */
- lobjId = lo_creat(conn, INV_READ|INV_WRITE);
- if (lobjId == 0) {
- fprintf(stderr, "can't create large object");
- }
-
- lobj_fd = lo_open(conn, lobjId, INV_WRITE);
- /*
- * read in from the Unix file and write to the inversion file
- */
- while ((nbytes = read(fd, buf, BUFSIZE)) > 0) {
- tmp = lo_write(conn, lobj_fd, buf, nbytes);
- if (tmp < nbytes) {
- fprintf(stderr, "error while reading \"%s\"", filename);
+ Oid lobjId;
+ int lobj_fd;
+ char buf[BUFSIZE];
+ int nbytes,
+ tmp;
+ int fd;
+
+ /*
+ * open the file to be read in
+ */
+ fd = open(filename, O_RDONLY, 0666);
+ if (fd < 0)
+ { /* error */
+ fprintf(stderr, "can't open unix file\"%s\"\n", filename);
}
- }
-
- close(fd);
- lo_close(conn, lobj_fd);
- return lobjId;
+ /*
+ * create the large object
+ */
+ lobjId = lo_creat(conn, INV_READ | INV_WRITE);
+ if (lobjId == 0)
+ {
+ fprintf(stderr, "can't create large object");
+ }
+
+ lobj_fd = lo_open(conn, lobjId, INV_WRITE);
+
+ /*
+ * read in from the Unix file and write to the inversion file
+ */
+ while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
+ {
+ tmp = lo_write(conn, lobj_fd, buf, nbytes);
+ if (tmp < nbytes)
+ {
+ fprintf(stderr, "error while reading \"%s\"", filename);
+ }
+ }
+
+ close(fd);
+ lo_close(conn, lobj_fd);
+
+ return lobjId;
}
-void pickout(PGconn *conn, Oid lobjId, int start, int len)
+void
+pickout(PGconn * conn, Oid lobjId, int start, int len)
{
- int lobj_fd;
- char* buf;
- int nbytes;
- int nread;
-
- lobj_fd = lo_open(conn, lobjId, INV_READ);
- if (lobj_fd < 0) {
- fprintf(stderr,"can't open large object %d",
- lobjId);
- }
-
- lo_lseek(conn, lobj_fd, start, SEEK_SET);
- buf = malloc(len+1);
-
- nread = 0;
- while (len - nread > 0) {
- nbytes = lo_read(conn, lobj_fd, buf, len - nread);
- buf[nbytes] = '\0';
- fprintf(stderr,">>> %s", buf);
- nread += nbytes;
- }
- fprintf(stderr,"\n");
- lo_close(conn, lobj_fd);
+ int lobj_fd;
+ char *buf;
+ int nbytes;
+ int nread;
+
+ lobj_fd = lo_open(conn, lobjId, INV_READ);
+ if (lobj_fd < 0)
+ {
+ fprintf(stderr, "can't open large object %d",
+ lobjId);
+ }
+
+ lo_lseek(conn, lobj_fd, start, SEEK_SET);
+ buf = malloc(len + 1);
+
+ nread = 0;
+ while (len - nread > 0)
+ {
+ nbytes = lo_read(conn, lobj_fd, buf, len - nread);
+ buf[nbytes] = '\0';
+ fprintf(stderr, ">>> %s", buf);
+ nread += nbytes;
+ }
+ fprintf(stderr, "\n");
+ lo_close(conn, lobj_fd);
}
-void overwrite(PGconn *conn, Oid lobjId, int start, int len)
+void
+overwrite(PGconn * conn, Oid lobjId, int start, int len)
{
- int lobj_fd;
- char* buf;
- int nbytes;
- int nwritten;
- int i;
-
- lobj_fd = lo_open(conn, lobjId, INV_READ);
- if (lobj_fd < 0) {
- fprintf(stderr,"can't open large object %d",
- lobjId);
- }
-
- lo_lseek(conn, lobj_fd, start, SEEK_SET);
- buf = malloc(len+1);
-
- for (i=0;i<len;i++)
- buf[i] = 'X';
- buf[i] = '\0';
-
- nwritten = 0;
- while (len - nwritten > 0) {
- nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
- nwritten += nbytes;
- }
- fprintf(stderr,"\n");
- lo_close(conn, lobj_fd);
+ int lobj_fd;
+ char *buf;
+ int nbytes;
+ int nwritten;
+ int i;
+
+ lobj_fd = lo_open(conn, lobjId, INV_READ);
+ if (lobj_fd < 0)
+ {
+ fprintf(stderr, "can't open large object %d",
+ lobjId);
+ }
+
+ lo_lseek(conn, lobj_fd, start, SEEK_SET);
+ buf = malloc(len + 1);
+
+ for (i = 0; i < len; i++)
+ buf[i] = 'X';
+ buf[i] = '\0';
+
+ nwritten = 0;
+ while (len - nwritten > 0)
+ {
+ nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
+ nwritten += nbytes;
+ }
+ fprintf(stderr, "\n");
+ lo_close(conn, lobj_fd);
}
/*
* exportFile -
- * export large object "lobjOid" to file "out_filename"
+ * export large object "lobjOid" to file "out_filename"
*
*/
-void exportFile(PGconn *conn, Oid lobjId, char *filename)
+void
+exportFile(PGconn * conn, Oid lobjId, char *filename)
{
- int lobj_fd;
- char buf[BUFSIZE];
- int nbytes, tmp;
- int fd;
-
- /*
- * create an inversion "object"
- */
- lobj_fd = lo_open(conn, lobjId, INV_READ);
- if (lobj_fd < 0) {
- fprintf(stderr,"can't open large object %d",
- lobjId);
- }
-
- /*
- * open the file to be written to
- */
- fd = open(filename, O_CREAT|O_WRONLY, 0666);
- if (fd < 0) { /* error */
- fprintf(stderr, "can't open unix file\"%s\"",
- filename);
- }
-
- /*
- * read in from the Unix file and write to the inversion file
- */
- while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) {
- tmp = write(fd, buf, nbytes);
- if (tmp < nbytes) {
- fprintf(stderr,"error while writing \"%s\"",
- filename);
+ int lobj_fd;
+ char buf[BUFSIZE];
+ int nbytes,
+ tmp;
+ int fd;
+
+ /*
+ * create an inversion "object"
+ */
+ lobj_fd = lo_open(conn, lobjId, INV_READ);
+ if (lobj_fd < 0)
+ {
+ fprintf(stderr, "can't open large object %d",
+ lobjId);
+ }
+
+ /*
+ * open the file to be written to
+ */
+ fd = open(filename, O_CREAT | O_WRONLY, 0666);
+ if (fd < 0)
+ { /* error */
+ fprintf(stderr, "can't open unix file\"%s\"",
+ filename);
}
- }
- lo_close(conn, lobj_fd);
- close(fd);
+ /*
+ * read in from the Unix file and write to the inversion file
+ */
+ while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
+ {
+ tmp = write(fd, buf, nbytes);
+ if (tmp < nbytes)
+ {
+ fprintf(stderr, "error while writing \"%s\"",
+ filename);
+ }
+ }
+
+ lo_close(conn, lobj_fd);
+ close(fd);
- return;
+ return;
}
-void
-exit_nicely(PGconn* conn)
+void
+exit_nicely(PGconn * conn)
{
- PQfinish(conn);
- exit(1);
+ PQfinish(conn);
+ exit(1);
}
int
main(int argc, char **argv)
{
- char *in_filename, *out_filename;
- char *database;
- Oid lobjOid;
- PGconn *conn;
- PGresult *res;
-
- if (argc != 4) {
- fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
- argv[0]);
- exit(1);
- }
-
- database = argv[1];
- in_filename = argv[2];
- out_filename = argv[3];
-
- /*
- * set up the connection
- */
- conn = PQsetdb(NULL, NULL, NULL, NULL, database);
-
- /* check to see that the backend connection was successfully made */
- if (PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.\n", database);
- fprintf(stderr,"%s",PQerrorMessage(conn));
- exit_nicely(conn);
- }
-
- res = PQexec(conn, "begin");
- PQclear(res);
-
- printf("importing file \"%s\" ...\n", in_filename);
-/* lobjOid = importFile(conn, in_filename); */
- lobjOid = lo_import(conn, in_filename);
+ char *in_filename,
+ *out_filename;
+ char *database;
+ Oid lobjOid;
+ PGconn *conn;
+ PGresult *res;
+
+ if (argc != 4)
+ {
+ fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
+ argv[0]);
+ exit(1);
+ }
+
+ database = argv[1];
+ in_filename = argv[2];
+ out_filename = argv[3];
+
+ /*
+ * set up the connection
+ */
+ conn = PQsetdb(NULL, NULL, NULL, NULL, database);
+
+ /* check to see that the backend connection was successfully made */
+ if (PQstatus(conn) == CONNECTION_BAD)
+ {
+ fprintf(stderr, "Connection to database '%s' failed.\n", database);
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ res = PQexec(conn, "begin");
+ PQclear(res);
+
+ printf("importing file \"%s\" ...\n", in_filename);
+/* lobjOid = importFile(conn, in_filename); */
+ lobjOid = lo_import(conn, in_filename);
/*
- printf("\tas large object %d.\n", lobjOid);
+ printf("\tas large object %d.\n", lobjOid);
- printf("picking out bytes 1000-2000 of the large object\n");
- pickout(conn, lobjOid, 1000, 1000);
+ printf("picking out bytes 1000-2000 of the large object\n");
+ pickout(conn, lobjOid, 1000, 1000);
- printf("overwriting bytes 1000-2000 of the large object with X's\n");
- overwrite(conn, lobjOid, 1000, 1000);
+ printf("overwriting bytes 1000-2000 of the large object with X's\n");
+ overwrite(conn, lobjOid, 1000, 1000);
*/
- printf("exporting large object to file \"%s\" ...\n", out_filename);
-/* exportFile(conn, lobjOid, out_filename); */
- lo_export(conn, lobjOid,out_filename);
+ printf("exporting large object to file \"%s\" ...\n", out_filename);
+/* exportFile(conn, lobjOid, out_filename); */
+ lo_export(conn, lobjOid, out_filename);
- res = PQexec(conn, "end");
- PQclear(res);
- PQfinish(conn);
- exit(0);
+ res = PQexec(conn, "end");
+ PQclear(res);
+ PQfinish(conn);
+ exit(0);
}
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index f6937365889..ceace603781 100644
--- a/src/test/regress/regress.c
+++ b/src/test/regress/regress.c
@@ -1,283 +1,300 @@
/*
- * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.9 1997/08/19 21:40:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.10 1997/09/07 05:04:10 momjian Exp $
*/
-#include <float.h> /* faked on sunos */
+#include <float.h> /* faked on sunos */
#include <stdio.h>
-#include <string.h> /* for memset() */
+#include <string.h> /* for memset() */
#include <postgres.h>
#include "utils/geo_decls.h" /* includes <math.h> */
-#include "executor/executor.h" /* For GetAttributeByName */
+#include "executor/executor.h" /* For GetAttributeByName */
#define P_MAXDIG 12
-#define LDELIM '('
-#define RDELIM ')'
-#define DELIM ','
+#define LDELIM '('
+#define RDELIM ')'
+#define DELIM ','
-typedef void *TUPLE;
+typedef void *TUPLE;
-extern double *regress_dist_ptpath (Point *pt, PATH *path);
-extern double *regress_path_dist (PATH *p1, PATH *p2);
-extern PATH *poly2path (POLYGON *poly);
-extern Point *interpt_pp (PATH *p1, PATH *p2);
-extern void regress_lseg_construct (LSEG *lseg, Point *pt1, Point *pt2);
-extern char overpaid (TUPLE tuple);
-extern int boxarea (BOX *box);
-extern char *reverse_c16 (char *string);
+extern double *regress_dist_ptpath(Point * pt, PATH * path);
+extern double *regress_path_dist(PATH * p1, PATH * p2);
+extern PATH *poly2path(POLYGON * poly);
+extern Point *interpt_pp(PATH * p1, PATH * p2);
+extern void regress_lseg_construct(LSEG * lseg, Point * pt1, Point * pt2);
+extern char overpaid(TUPLE tuple);
+extern int boxarea(BOX * box);
+extern char *reverse_c16(char *string);
/*
-** Distance from a point to a path
+** Distance from a point to a path
*/
- double *
+double *
regress_dist_ptpath(pt, path)
- Point *pt;
- PATH *path;
+Point *pt;
+PATH *path;
{
- double *result;
- double *tmp;
- int i;
- LSEG lseg;
-
- switch (path->npts) {
- case 0:
- result = PALLOCTYPE(double);
- *result = Abs((double) DBL_MAX); /* +infinity */
- break;
- case 1:
- result = point_distance(pt, &path->p[0]);
- break;
- default:
- /*
- * the distance from a point to a path is the smallest distance
- * from the point to any of its constituent segments.
- */
- Assert(path->npts > 1);
- result = PALLOCTYPE(double);
- for (i = 0; i < path->npts - 1; ++i) {
- regress_lseg_construct(&lseg, &path->p[i], &path->p[i+1]);
- tmp = dist_ps(pt, &lseg);
- if (i == 0 || *tmp < *result)
- *result = *tmp;
- PFREE(tmp);
-
+ double *result;
+ double *tmp;
+ int i;
+ LSEG lseg;
+
+ switch (path->npts)
+ {
+ case 0:
+ result = PALLOCTYPE(double);
+ *result = Abs((double) DBL_MAX); /* +infinity */
+ break;
+ case 1:
+ result = point_distance(pt, &path->p[0]);
+ break;
+ default:
+
+ /*
+ * the distance from a point to a path is the smallest distance
+ * from the point to any of its constituent segments.
+ */
+ Assert(path->npts > 1);
+ result = PALLOCTYPE(double);
+ for (i = 0; i < path->npts - 1; ++i)
+ {
+ regress_lseg_construct(&lseg, &path->p[i], &path->p[i + 1]);
+ tmp = dist_ps(pt, &lseg);
+ if (i == 0 || *tmp < *result)
+ *result = *tmp;
+ PFREE(tmp);
+
+ }
+ break;
}
- break;
- }
- return(result);
+ return (result);
}
/* this essentially does a cartesian product of the lsegs in the
two paths, and finds the min distance between any two lsegs */
- double *
+double *
regress_path_dist(p1, p2)
- PATH *p1;
- PATH *p2;
+PATH *p1;
+PATH *p2;
{
- double *min, *tmp;
- int i,j;
- LSEG seg1, seg2;
-
- regress_lseg_construct(&seg1, &p1->p[0], &p1->p[1]);
- regress_lseg_construct(&seg2, &p2->p[0], &p2->p[1]);
- min = lseg_distance(&seg1, &seg2);
-
- for (i = 0; i < p1->npts - 1; i++)
- for (j = 0; j < p2->npts - 1; j++)
- {
- regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i+1]);
- regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j+1]);
-
- if (*min < *(tmp = lseg_distance(&seg1, &seg2)))
- *min = *tmp;
- PFREE(tmp);
- }
-
- return(min);
+ double *min,
+ *tmp;
+ int i,
+ j;
+ LSEG seg1,
+ seg2;
+
+ regress_lseg_construct(&seg1, &p1->p[0], &p1->p[1]);
+ regress_lseg_construct(&seg2, &p2->p[0], &p2->p[1]);
+ min = lseg_distance(&seg1, &seg2);
+
+ for (i = 0; i < p1->npts - 1; i++)
+ for (j = 0; j < p2->npts - 1; j++)
+ {
+ regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);
+ regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);
+
+ if (*min < *(tmp = lseg_distance(&seg1, &seg2)))
+ *min = *tmp;
+ PFREE(tmp);
+ }
+
+ return (min);
}
- PATH *
+PATH *
poly2path(poly)
- POLYGON *poly;
+POLYGON *poly;
{
- int i;
- char *output = (char *)PALLOC(2*(P_MAXDIG + 1)*poly->npts + 64);
- char buf[2*(P_MAXDIG)+20];
+ int i;
+ char *output = (char *) PALLOC(2 * (P_MAXDIG + 1) * poly->npts + 64);
+ char buf[2 * (P_MAXDIG) + 20];
- sprintf(output, "(1, %*d", P_MAXDIG, poly->npts);
+ sprintf(output, "(1, %*d", P_MAXDIG, poly->npts);
- for (i=0; i<poly->npts; i++)
- {
- sprintf(buf, ",%*g,%*g", P_MAXDIG, poly->p[i].x, P_MAXDIG, poly->p[i].y);
- strcat(output, buf);
- }
+ for (i = 0; i < poly->npts; i++)
+ {
+ sprintf(buf, ",%*g,%*g", P_MAXDIG, poly->p[i].x, P_MAXDIG, poly->p[i].y);
+ strcat(output, buf);
+ }
- sprintf(buf, "%c", RDELIM);
- strcat(output, buf);
- return(path_in(output));
+ sprintf(buf, "%c", RDELIM);
+ strcat(output, buf);
+ return (path_in(output));
}
-/* return the point where two paths intersect. Assumes that they do. */
- Point *
-interpt_pp(p1,p2)
- PATH *p1;
- PATH *p2;
+/* return the point where two paths intersect. Assumes that they do. */
+Point *
+interpt_pp(p1, p2)
+PATH *p1;
+PATH *p2;
{
-
- Point *retval;
- int i,j;
- LSEG seg1, seg2;
+
+ Point *retval;
+ int i,
+ j;
+ LSEG seg1,
+ seg2;
+
#if FALSE
- LINE *ln;
+ LINE *ln;
+
#endif
- bool found; /* We've found the intersection */
+ bool found; /* We've found the intersection */
- found = false; /* Haven't found it yet */
+ found = false; /* Haven't found it yet */
- for (i = 0; i < p1->npts - 1 && !found; i++)
- for (j = 0; j < p2->npts - 1 && !found; j++)
- {
- regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i+1]);
- regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j+1]);
- if (lseg_intersect(&seg1, &seg2)) found = true;
- }
+ for (i = 0; i < p1->npts - 1 && !found; i++)
+ for (j = 0; j < p2->npts - 1 && !found; j++)
+ {
+ regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);
+ regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);
+ if (lseg_intersect(&seg1, &seg2))
+ found = true;
+ }
#if FALSE
- ln = line_construct_pp(&seg2.p[0], &seg2.p[1]);
- retval = interpt_sl(&seg1, ln);
+ ln = line_construct_pp(&seg2.p[0], &seg2.p[1]);
+ retval = interpt_sl(&seg1, ln);
#endif
- retval = lseg_interpt( &seg1, &seg2);
-
- return(retval);
+ retval = lseg_interpt(&seg1, &seg2);
+
+ return (retval);
}
/* like lseg_construct, but assume space already allocated */
- void
+void
regress_lseg_construct(lseg, pt1, pt2)
- LSEG *lseg;
- Point *pt1;
- Point *pt2;
+LSEG *lseg;
+Point *pt1;
+Point *pt2;
{
- lseg->p[0].x = pt1->x;
- lseg->p[0].y = pt1->y;
- lseg->p[1].x = pt2->x;
- lseg->p[1].y = pt2->y;
- lseg->m = point_sl(pt1, pt2);
+ lseg->p[0].x = pt1->x;
+ lseg->p[0].y = pt1->y;
+ lseg->p[1].x = pt2->x;
+ lseg->p[1].y = pt2->y;
+ lseg->m = point_sl(pt1, pt2);
}
- char overpaid(tuple)
- TUPLE tuple;
+char
+overpaid(tuple)
+TUPLE tuple;
{
- bool isnull;
- long salary;
+ bool isnull;
+ long salary;
- salary = (long)GetAttributeByName(tuple, "salary", &isnull);
- return(salary > 699);
+ salary = (long) GetAttributeByName(tuple, "salary", &isnull);
+ return (salary > 699);
}
/* New type "widget"
* This used to be "circle", but I added circle to builtins,
- * so needed to make sure the names do not collide. - tgl 97/04/21
+ * so needed to make sure the names do not collide. - tgl 97/04/21
*/
-typedef struct {
- Point center;
- double radius;
-} WIDGET;
+typedef struct
+{
+ Point center;
+ double radius;
+} WIDGET;
- WIDGET *widget_in (char *str);
- char *widget_out (WIDGET *widget);
- int pt_in_widget (Point *point, WIDGET *widget);
+WIDGET *widget_in(char *str);
+char *widget_out(WIDGET * widget);
+int pt_in_widget(Point * point, WIDGET * widget);
#define NARGS 3
- WIDGET *
+WIDGET *
widget_in(str)
-char *str;
+char *str;
{
- char *p, *coord[NARGS], buf2[1000];
- int i;
- WIDGET *result;
+ char *p,
+ *coord[NARGS],
+ buf2[1000];
+ int i;
+ WIDGET *result;
if (str == NULL)
- return(NULL);
+ return (NULL);
for (i = 0, p = str; *p && i < NARGS && *p != RDELIM; p++)
if (*p == ',' || (*p == LDELIM && !i))
coord[i++] = p + 1;
if (i < NARGS - 1)
- return(NULL);
+ return (NULL);
result = (WIDGET *) palloc(sizeof(WIDGET));
result->center.x = atof(coord[0]);
result->center.y = atof(coord[1]);
result->radius = atof(coord[2]);
sprintf(buf2, "widget_in: read (%f, %f, %f)\n", result->center.x,
- result->center.y,result->radius);
- return(result);
+ result->center.y, result->radius);
+ return (result);
}
- char *
+char *
widget_out(widget)
- WIDGET *widget;
+WIDGET *widget;
{
- char *result;
+ char *result;
- if (widget == NULL)
- return(NULL);
+ if (widget == NULL)
+ return (NULL);
- result = (char *) palloc(60);
- sprintf(result, "(%g,%g,%g)",
- widget->center.x, widget->center.y, widget->radius);
- return(result);
+ result = (char *) palloc(60);
+ sprintf(result, "(%g,%g,%g)",
+ widget->center.x, widget->center.y, widget->radius);
+ return (result);
}
- int
+int
pt_in_widget(point, widget)
- Point *point;
- WIDGET *widget;
+Point *point;
+WIDGET *widget;
{
extern double point_dt();
- return( point_dt(point, &widget->center) < widget->radius );
+ return (point_dt(point, &widget->center) < widget->radius);
}
#define ABS(X) ((X) > 0 ? (X) : -(X))
- int
+int
boxarea(box)
-BOX *box;
+BOX *box;
{
- int width, height;
+ int width,
+ height;
- width = ABS(box->high.x - box->low.x);
+ width = ABS(box->high.x - box->low.x);
height = ABS(box->high.y - box->low.y);
return (width * height);
}
- char *
+char *
reverse_c16(string)
- char *string;
+char *string;
{
- register i;
- int len;
- char *new_string;
-
- if (!(new_string = palloc(16))) {
- fprintf(stderr, "reverse_c16: palloc failed\n");
- return(NULL);
- }
- memset(new_string, 0, 16);
- for (i = 0; i < 16 && string[i]; ++i)
- ;
- if (i == 16 || !string[i])
- --i;
- len = i;
- for (; i >= 0; --i)
- new_string[len-i] = string[i];
- return(new_string);
+ register i;
+ int len;
+ char *new_string;
+
+ if (!(new_string = palloc(16)))
+ {
+ fprintf(stderr, "reverse_c16: palloc failed\n");
+ return (NULL);
+ }
+ memset(new_string, 0, 16);
+ for (i = 0; i < 16 && string[i]; ++i)
+ ;
+ if (i == 16 || !string[i])
+ --i;
+ len = i;
+ for (; i >= 0; --i)
+ new_string[len - i] = string[i];
+ return (new_string);
}
diff --git a/src/tools/entab/entab.c b/src/tools/entab/entab.c
index 25526582280..b11b84989e9 100644
--- a/src/tools/entab/entab.c
+++ b/src/tools/entab/entab.c
@@ -1,10 +1,10 @@
/*
-** entab.c - add tabs to a text file
-** by Bruce Momjian (root@candle.pha.pa.us)
+** entab.c - add tabs to a text file
+** by Bruce Momjian (root@candle.pha.pa.us)
**
-** version 1.3
+** version 1.3
**
-** tabsize = 4
+** tabsize = 4
**
*/
@@ -12,78 +12,90 @@
#include <stdlib.h>
#include <string.h>
-#define NUL '\0'
+#define NUL '\0'
#ifndef TRUE
-#define TRUE 1
+#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
-void halt();
-
-extern char *optarg;
-extern int optind;
+void halt();
-int main(argc, argv)
-int argc;
-char **argv;
+extern char *optarg;
+extern int optind;
+
+int
+main(argc, argv)
+int argc;
+char **argv;
{
- int tab_size = 8,
- min_spaces = 2,
- protect_quotes = FALSE,
- del_tabs = FALSE,
- clip_lines = FALSE,
- prv_spaces,
- col_in_tab,
- escaped,
- nxt_spaces;
- char in_line[BUFSIZ],
- out_line[BUFSIZ],
- *src,
- *dst,
- quote_char,
- ch,
- *cp;
- FILE *in_file;
-
- if ((cp = strrchr(argv[0],'/')) != NULL)
+ int tab_size = 8,
+ min_spaces = 2,
+ protect_quotes = FALSE,
+ del_tabs = FALSE,
+ clip_lines = FALSE,
+ prv_spaces,
+ col_in_tab,
+ escaped,
+ nxt_spaces;
+ char in_line[BUFSIZ],
+ out_line[BUFSIZ],
+ *src,
+ *dst,
+ quote_char,
+ ch,
+ *cp;
+ FILE *in_file;
+
+ if ((cp = strrchr(argv[0], '/')) != NULL)
++cp;
else
cp = argv[0];
- if (strcmp(cp,"detab") == 0)
+ if (strcmp(cp, "detab") == 0)
del_tabs = 1;
-
+
while ((ch = getopt(argc, argv, "cdhqs:t:")) != -1)
switch (ch)
{
- case 'c' : clip_lines = TRUE; break;
- case 'd' : del_tabs = TRUE; break;
- case 'q' : protect_quotes = TRUE; break;
- case 's' : min_spaces = atoi(optarg); break;
- case 't' : tab_size = atoi(optarg); break;
- case 'h' :
- case '?' :
- halt("USAGE: %s [ -cdqst ] [file ...]\n\
+ case 'c':
+ clip_lines = TRUE;
+ break;
+ case 'd':
+ del_tabs = TRUE;
+ break;
+ case 'q':
+ protect_quotes = TRUE;
+ break;
+ case 's':
+ min_spaces = atoi(optarg);
+ break;
+ case 't':
+ tab_size = atoi(optarg);
+ break;
+ case 'h':
+ case '?':
+ halt("USAGE: %s [ -cdqst ] [file ...]\n\
-c (clip trailing whitespace)\n\
-d (delete tabs)\n\
-q (protect quotes)\n\
-s minimum_spaces\n\
-t tab_width\n",
- cp);
+ cp);
}
argv += optind;
argc -= optind;
-
- do {
+
+ do
+ {
if (argc < 1)
in_file = stdin;
else
{
- if ( (in_file=fopen(*argv,"r")) == NULL)
- halt("PERROR: Can not open file %s\n",argv[0]);
+ if ((in_file = fopen(*argv, "r")) == NULL)
+ halt("PERROR: Can not open file %s\n", argv[0]);
argv++;
}
@@ -114,30 +126,30 @@ char **argv;
if (col_in_tab == tab_size)
{
+
/*
- Is the next character going to be a tab?
- Needed to do tab replacement in current spot
- if next char is going to be a tab, ignoring
- min_spaces
+ * Is the next character going to be a tab? Needed
+ * to do tab replacement in current spot if next
+ * char is going to be a tab, ignoring min_spaces
*/
nxt_spaces = 0;
while (1)
{
- if ( *(src+nxt_spaces+1) == NUL ||
- (*(src+nxt_spaces+1) != ' ' &&
- *(src+nxt_spaces+1) != '\t'))
+ if (*(src + nxt_spaces + 1) == NUL ||
+ (*(src + nxt_spaces + 1) != ' ' &&
+ *(src + nxt_spaces + 1) != '\t'))
break;
- if (*(src+nxt_spaces+1) == ' ')
+ if (*(src + nxt_spaces + 1) == ' ')
++nxt_spaces;
- if (*(src+nxt_spaces+1) == '\t' ||
- nxt_spaces == tab_size)
+ if (*(src + nxt_spaces + 1) == '\t' ||
+ nxt_spaces == tab_size)
{
nxt_spaces = tab_size;
break;
}
}
if ((prv_spaces >= min_spaces ||
- nxt_spaces == tab_size) &&
+ nxt_spaces == tab_size) &&
del_tabs == FALSE)
{
*(dst++) = '\t';
@@ -154,7 +166,7 @@ char **argv;
{
for (; prv_spaces > 0; prv_spaces--)
*(dst++) = ' ';
- if (*src == '\t') /* only when in quote */
+ if (*src == '\t') /* only when in quote */
col_in_tab = 0;
if (*src == '\b')
col_in_tab -= 2;
@@ -164,22 +176,21 @@ char **argv;
escaped = TRUE;
if (*src == '"' || *src == '\'')
if (quote_char == ' ')
- quote_char = *src;
+ quote_char = *src;
else if (*src == quote_char)
- quote_char = ' ';
+ quote_char = ' ';
}
- else
- if (*src != '\r' && *src != '\n')
- escaped = FALSE;
-
- if (( *src == '\r' || *src == '\n') &&
+ else if (*src != '\r' && *src != '\n')
+ escaped = FALSE;
+
+ if ((*src == '\r' || *src == '\n') &&
quote_char == ' ' &&
clip_lines == TRUE &&
escaped == FALSE)
{
while (dst > out_line &&
- (*(dst-1) == ' ' || *(dst-1) == '\t'))
- dst--;
+ (*(dst - 1) == ' ' || *(dst - 1) == '\t'))
+ dst--;
prv_spaces = 0;
}
*(dst++) = *src;
@@ -191,14 +202,14 @@ char **argv;
if (clip_lines == TRUE && escaped == FALSE)
{
while (dst > out_line &&
- (*(dst-1) == ' ' || *(dst-1) == '\t'))
- dst--;
+ (*(dst - 1) == ' ' || *(dst - 1) == '\t'))
+ dst--;
prv_spaces = 0;
}
for (; prv_spaces > 0; prv_spaces--)
*(dst++) = ' ';
*dst = NUL;
- if (fputs(out_line,stdout) == EOF)
+ if (fputs(out_line, stdout) == EOF)
halt("PERROR: Error writing output.\n");
}
} while (--argc > 0);
diff --git a/src/tools/entab/halt.c b/src/tools/entab/halt.c
index 7df7a45c0ef..5d48f58152e 100644
--- a/src/tools/entab/halt.c
+++ b/src/tools/entab/halt.c
@@ -1,8 +1,8 @@
/*
**
-** halt.c
+** halt.c
**
-** This is used to print out error messages and exit
+** This is used to print out error messages and exit
*/
#include <varargs.h>
@@ -13,44 +13,46 @@
/*-------------------------------------------------------------------------
**
-** halt - print error message, and call clean up routine or exit
+** halt - print error message, and call clean up routine or exit
**
**------------------------------------------------------------------------*/
/*VARARGS*/
-void halt(va_alist)
+void
+halt(va_alist)
va_dcl
{
- va_list arg_ptr;
- char *format, *pstr;
- void (*sig_func)();
+ va_list arg_ptr;
+ char *format,
+ *pstr;
+ void (*sig_func) ();
va_start(arg_ptr);
- format = va_arg(arg_ptr,char *);
- if (strncmp(format,"PERROR", 6) != 0)
- vfprintf(stderr,format,arg_ptr);
+ format = va_arg(arg_ptr, char *);
+ if (strncmp(format, "PERROR", 6) != 0)
+ vfprintf(stderr, format, arg_ptr);
else
{
- for (pstr=format+6; *pstr == ' ' || *pstr == ':'; pstr++)
+ for (pstr = format + 6; *pstr == ' ' || *pstr == ':'; pstr++)
;
- vfprintf(stderr,pstr,arg_ptr);
+ vfprintf(stderr, pstr, arg_ptr);
perror("");
- }
+ }
va_end(arg_ptr);
fflush(stderr);
- /* call one clean up function if defined */
- if ( (sig_func = signal(SIGTERM, SIG_DFL)) != SIG_DFL &&
- sig_func != SIG_IGN)
- (*sig_func)(0);
- else if ( (sig_func = signal(SIGHUP, SIG_DFL)) != SIG_DFL &&
- sig_func != SIG_IGN)
- (*sig_func)(0);
- else if ( (sig_func = signal(SIGINT, SIG_DFL)) != SIG_DFL &&
- sig_func != SIG_IGN)
- (*sig_func)(0);
- else if ( (sig_func = signal(SIGQUIT, SIG_DFL)) != SIG_DFL &&
- sig_func != SIG_IGN)
- (*sig_func)(0);
+ /* call one clean up function if defined */
+ if ((sig_func = signal(SIGTERM, SIG_DFL)) != SIG_DFL &&
+ sig_func != SIG_IGN)
+ (*sig_func) (0);
+ else if ((sig_func = signal(SIGHUP, SIG_DFL)) != SIG_DFL &&
+ sig_func != SIG_IGN)
+ (*sig_func) (0);
+ else if ((sig_func = signal(SIGINT, SIG_DFL)) != SIG_DFL &&
+ sig_func != SIG_IGN)
+ (*sig_func) (0);
+ else if ((sig_func = signal(SIGQUIT, SIG_DFL)) != SIG_DFL &&
+ sig_func != SIG_IGN)
+ (*sig_func) (0);
exit(1);
}
diff --git a/src/tutorial/C-code/beard.c b/src/tutorial/C-code/beard.c
index 0fe289c8d2b..31b83e97e87 100644
--- a/src/tutorial/C-code/beard.c
+++ b/src/tutorial/C-code/beard.c
@@ -1,64 +1,64 @@
/*-------------------------------------------------------------------------
*
* beard.c--
- * sample routines to use large objects
+ * sample routines to use large objects
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/tutorial/C-code/Attic/beard.c,v 1.1.1.1 1996/07/09 06:22:34 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/tutorial/C-code/Attic/beard.c,v 1.2 1997/09/07 05:04:34 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-typedef struct ImageHdr {
- int size;
-} ImageHdr;
+typedef struct ImageHdr
+{
+ int size;
+} ImageHdr;
#define BUFSIZE 10
/*
* beard -
- * clips lower 1/3 of picture and return as large object
+ * clips lower 1/3 of picture and return as large object
*/
Oid
beard(Oid picture)
{
- Oid beard;
- int pic_fd, beard_fd;
- ImageHdr ihdr;
- char buf[BUFSIZE];
- int cc;
+ Oid beard;
+ int pic_fd,
+ beard_fd;
+ ImageHdr ihdr;
+ char buf[BUFSIZE];
+ int cc;
- if ((pic_fd = lo_open(picture, INV_READ)) == -1)
- elog(WARN, "Cannot access picture large object");
+ if ((pic_fd = lo_open(picture, INV_READ)) == -1)
+ elog(WARN, "Cannot access picture large object");
- if (lo_read(pic_fd, (char*)&ihdr, sizeof(ihdr)) != sizeof(ihdr))
- elog(WARN, "Picture large object corrupted");
+ if (lo_read(pic_fd, (char *) &ihdr, sizeof(ihdr)) != sizeof(ihdr))
+ elog(WARN, "Picture large object corrupted");
- beardOffset = (ihdr.size / 3) * 2;
+ beardOffset = (ihdr.size / 3) * 2;
- /*
- * new large object
- */
- if ((beard = lo_creat(INV_MD)) == 0) /* ?? is this right? */
- elog(WARN, "Cannot create new large object");
+ /*
+ * new large object
+ */
+ if ((beard = lo_creat(INV_MD)) == 0) /* ?? is this right? */
+ elog(WARN, "Cannot create new large object");
- if ((beard_fd = lo_open(beard, INV_WRITE)) == -1)
- elog(WARN, "Cannot access beard large object");
+ if ((beard_fd = lo_open(beard, INV_WRITE)) == -1)
+ elog(WARN, "Cannot access beard large object");
- lo_lseek(pic_fd, beardOffset, SET_CUR);
- while ((cc = lo_read(pic_fd, buf, BUFSIZE)) > 0) {
- if (lo_write(beard_fd, buf, cc) != cc)
- elog(WARN, "error while writing large object");
- }
+ lo_lseek(pic_fd, beardOffset, SET_CUR);
+ while ((cc = lo_read(pic_fd, buf, BUFSIZE)) > 0)
+ {
+ if (lo_write(beard_fd, buf, cc) != cc)
+ elog(WARN, "error while writing large object");
+ }
- lo_close(pic_fd);
- lo_close(beard_fd);
+ lo_close(pic_fd);
+ lo_close(beard_fd);
- return beard;
+ return beard;
}
-
-
-
diff --git a/src/tutorial/C-code/complex.c b/src/tutorial/C-code/complex.c
index 8c83665c803..1041ff5ff71 100644
--- a/src/tutorial/C-code/complex.c
+++ b/src/tutorial/C-code/complex.c
@@ -12,79 +12,82 @@
#include "utils/palloc.h"
#include "utils/mcxt.h"
-typedef struct Complex {
- double x;
- double y;
-} Complex;
+typedef struct Complex
+{
+ double x;
+ double y;
+} Complex;
/* These prototypes declare the requirements that Postgres places on these
user written functions.
*/
-Complex * complex_in(char *str);
-char * complex_out(Complex *complex);
-Complex * complex_add(Complex *a, Complex *b);
-bool complex_abs_lt(Complex *a, Complex *b);
-bool complex_abs_le(Complex *a, Complex *b);
-bool complex_abs_eq(Complex *a, Complex *b);
-bool complex_abs_ge(Complex *a, Complex *b);
-bool complex_abs_gt(Complex *a, Complex *b);
-int4 complex_abs_cmp(Complex *a, Complex *b);
+Complex *complex_in(char *str);
+char *complex_out(Complex * complex);
+Complex *complex_add(Complex * a, Complex * b);
+bool complex_abs_lt(Complex * a, Complex * b);
+bool complex_abs_le(Complex * a, Complex * b);
+bool complex_abs_eq(Complex * a, Complex * b);
+bool complex_abs_ge(Complex * a, Complex * b);
+bool complex_abs_gt(Complex * a, Complex * b);
+int4 complex_abs_cmp(Complex * a, Complex * b);
/*****************************************************************************
* Input/Output functions
*****************************************************************************/
-Complex *
+Complex *
complex_in(char *str)
{
- double x, y;
- Complex *result;
-
- if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) {
- elog(WARN, "complex_in: error in parsing \"%s\"", str);
- return NULL;
- }
- result = (Complex *)palloc(sizeof(Complex));
- result->x = x;
- result->y = y;
- return (result);
+ double x,
+ y;
+ Complex *result;
+
+ if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
+ {
+ elog(WARN, "complex_in: error in parsing \"%s\"", str);
+ return NULL;
+ }
+ result = (Complex *) palloc(sizeof(Complex));
+ result->x = x;
+ result->y = y;
+ return (result);
}
/*
* You might have noticed a slight inconsistency between the following
* declaration and the SQL definition:
- * CREATE FUNCTION complex_out(opaque) RETURNS opaque ...
+ * CREATE FUNCTION complex_out(opaque) RETURNS opaque ...
* The reason is that the argument pass into complex_out is really just a
* pointer. POSTGRES thinks all output functions are:
- * char *out_func(char *);
+ * char *out_func(char *);
*/
-char *
-complex_out(Complex *complex)
+char *
+complex_out(Complex * complex)
{
- char *result;
+ char *result;
- if (complex == NULL)
- return(NULL);
+ if (complex == NULL)
+ return (NULL);
- result = (char *) palloc(60);
- sprintf(result, "(%g,%g)", complex->x, complex->y);
- return(result);
+ result = (char *) palloc(60);
+ sprintf(result, "(%g,%g)", complex->x, complex->y);
+ return (result);
}
/*****************************************************************************
* New Operators
*****************************************************************************/
-Complex *
-complex_add(Complex *a, Complex *b)
+Complex *
+complex_add(Complex * a, Complex * b)
{
- Complex *result;
-
- result = (Complex *)palloc(sizeof(Complex));
- result->x = a->x + b->x;
- result->y = a->y + b->y;
- return (result);
+ Complex *result;
+
+ result = (Complex *) palloc(sizeof(Complex));
+ result->x = a->x + b->x;
+ result->y = a->y + b->y;
+ return (result);
}
@@ -95,50 +98,62 @@ complex_add(Complex *a, Complex *b)
#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
bool
-complex_abs_lt(Complex *a, Complex *b)
+complex_abs_lt(Complex * a, Complex * b)
{
- double amag = Mag(a), bmag = Mag(b);
- return (amag<bmag);
+ double amag = Mag(a),
+ bmag = Mag(b);
+
+ return (amag < bmag);
}
bool
-complex_abs_le(Complex *a, Complex *b)
+complex_abs_le(Complex * a, Complex * b)
{
- double amag = Mag(a), bmag = Mag(b);
- return (amag<=bmag);
+ double amag = Mag(a),
+ bmag = Mag(b);
+
+ return (amag <= bmag);
}
bool
-complex_abs_eq(Complex *a, Complex *b)
+complex_abs_eq(Complex * a, Complex * b)
{
- double amag = Mag(a), bmag = Mag(b);
- return (amag==bmag);
+ double amag = Mag(a),
+ bmag = Mag(b);
+
+ return (amag == bmag);
}
bool
-complex_abs_ge(Complex *a, Complex *b)
+complex_abs_ge(Complex * a, Complex * b)
{
- double amag = Mag(a), bmag = Mag(b);
- return (amag>=bmag);
+ double amag = Mag(a),
+ bmag = Mag(b);
+
+ return (amag >= bmag);
}
bool
-complex_abs_gt(Complex *a, Complex *b)
+complex_abs_gt(Complex * a, Complex * b)
{
- double amag = Mag(a), bmag = Mag(b);
- return (amag>bmag);
+ double amag = Mag(a),
+ bmag = Mag(b);
+
+ return (amag > bmag);
}
int4
-complex_abs_cmp(Complex *a, Complex *b)
+complex_abs_cmp(Complex * a, Complex * b)
{
- double amag = Mag(a), bmag = Mag(b);
- if (amag < bmag)
- return -1;
- else if (amag > bmag)
- return 1;
- else
- return 0;
+ double amag = Mag(a),
+ bmag = Mag(b);
+
+ if (amag < bmag)
+ return -1;
+ else if (amag > bmag)
+ return 1;
+ else
+ return 0;
}
/*****************************************************************************
@@ -151,21 +166,21 @@ complex_abs_cmp(Complex *a, Complex *b)
* POSTGRES crashing, it is impossible to tell whether the bug is in your
* code or POSTGRES's.
*/
-void test_main(void);
+void test_main(void);
void
test_main()
{
- Complex *a;
- Complex *b;
-
- a = complex_in("(4.01, 3.77 )");
- printf("a = %s\n", complex_out(a));
- b = complex_in("(1.0,2.0)");
- printf("b = %s\n", complex_out(b));
- printf("a + b = %s\n", complex_out(complex_add(a,b)));
- printf("a < b = %d\n", complex_abs_lt(a,b));
- printf("a <= b = %d\n", complex_abs_le(a,b));
- printf("a = b = %d\n", complex_abs_eq(a,b));
- printf("a >= b = %d\n", complex_abs_ge(a,b));
- printf("a > b = %d\n", complex_abs_gt(a,b));
+ Complex *a;
+ Complex *b;
+
+ a = complex_in("(4.01, 3.77 )");
+ printf("a = %s\n", complex_out(a));
+ b = complex_in("(1.0,2.0)");
+ printf("b = %s\n", complex_out(b));
+ printf("a + b = %s\n", complex_out(complex_add(a, b)));
+ printf("a < b = %d\n", complex_abs_lt(a, b));
+ printf("a <= b = %d\n", complex_abs_le(a, b));
+ printf("a = b = %d\n", complex_abs_eq(a, b));
+ printf("a >= b = %d\n", complex_abs_ge(a, b));
+ printf("a > b = %d\n", complex_abs_gt(a, b));
}
diff --git a/src/tutorial/C-code/funcs.c b/src/tutorial/C-code/funcs.c
index 10e541a2249..989787e45ea 100644
--- a/src/tutorial/C-code/funcs.c
+++ b/src/tutorial/C-code/funcs.c
@@ -8,70 +8,73 @@
#include <string.h>
#include <stdio.h>
-#include "postgres.h" /* for char16, etc. */
-#include "utils/palloc.h" /* for palloc */
-#include "libpq-fe.h" /* for TUPLE */
-#include "executor/executor.h" /* for GetAttributeByName() */
+#include "postgres.h" /* for char16, etc. */
+#include "utils/palloc.h" /* for palloc */
+#include "libpq-fe.h" /* for TUPLE */
+#include "executor/executor.h" /* for GetAttributeByName() */
-/* The following prototypes declare what we assume the user declares to
+/* The following prototypes declare what we assume the user declares to
Postgres in his CREATE FUNCTION statement.
*/
-int add_one(int arg);
-char16 * concat16(char16 *arg1, char16 *arg2);
-text * copytext(text *t);
-bool c_overpaid(TUPLE t, /* the current instance of EMP */
- int4 limit);
+int add_one(int arg);
+char16 *concat16(char16 * arg1, char16 * arg2);
+text *copytext(text * t);
+bool
+c_overpaid(TUPLE t, /* the current instance of EMP */
+ int4 limit);
int
add_one(int arg)
{
- return(arg + 1);
+ return (arg + 1);
}
-char16 *
-concat16(char16 *arg1, char16 *arg2)
+char16 *
+concat16(char16 * arg1, char16 * arg2)
{
- char16 *new_c16 = (char16 *) palloc(sizeof(char16));
+ char16 *new_c16 = (char16 *) palloc(sizeof(char16));
- memset(new_c16, 0, sizeof(char16));
- strncpy((char*)new_c16, (char*)arg1, 16);
- return (char16 *)(strncat((char*)new_c16, (char*)arg2, 16));
+ memset(new_c16, 0, sizeof(char16));
+ strncpy((char *) new_c16, (char *) arg1, 16);
+ return (char16 *) (strncat((char *) new_c16, (char *) arg2, 16));
}
-text *
-copytext(text *t)
+text *
+copytext(text * t)
{
- /*
- * VARSIZE is the total size of the struct in bytes.
- */
- text *new_t = (text *) palloc(VARSIZE(t));
-
- memset(new_t, 0, VARSIZE(t));
-
- VARSIZE(new_t) = VARSIZE(t);
- /*
- * VARDATA is a pointer to the data region of the struct.
- */
- memcpy((void *) VARDATA(new_t), /* destination */
- (void *) VARDATA(t), /* source */
- VARSIZE(t)-VARHDRSZ); /* how many bytes */
-
- return(new_t);
+
+ /*
+ * VARSIZE is the total size of the struct in bytes.
+ */
+ text *new_t = (text *) palloc(VARSIZE(t));
+
+ memset(new_t, 0, VARSIZE(t));
+
+ VARSIZE(new_t) = VARSIZE(t);
+
+ /*
+ * VARDATA is a pointer to the data region of the struct.
+ */
+ memcpy((void *) VARDATA(new_t), /* destination */
+ (void *) VARDATA(t), /* source */
+ VARSIZE(t) - VARHDRSZ); /* how many bytes */
+
+ return (new_t);
}
bool
-c_overpaid(TUPLE t, /* the current instance of EMP */
- int4 limit)
+c_overpaid(TUPLE t, /* the current instance of EMP */
+ int4 limit)
{
- bool isnull = false;
- int4 salary;
+ bool isnull = false;
+ int4 salary;
- salary = (int4) GetAttributeByName(t, "salary", &isnull);
+ salary = (int4) GetAttributeByName(t, "salary", &isnull);
- if (isnull)
- return (false);
- return(salary > limit);
+ if (isnull)
+ return (false);
+ return (salary > limit);
}
diff --git a/src/utils/strdup.c b/src/utils/strdup.c
index 85d20814cae..762e2365c75 100644
--- a/src/utils/strdup.c
+++ b/src/utils/strdup.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* strdup.c--
- * copies a null-terminated string.
+ * copies a null-terminated string.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/utils/Attic/strdup.c,v 1.2 1996/11/28 03:32:18 bryanh Exp $
+ * $Header: /cvsroot/pgsql/src/utils/Attic/strdup.c,v 1.3 1997/09/07 05:04:45 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,11 +15,11 @@
#include <stdlib.h>
#include "strdup.h"
-char *
-strdup(char const *string)
+char *
+strdup(char const * string)
{
- char *nstr;
+ char *nstr;
- nstr = strcpy((char *)malloc(strlen(string)+1), string);
- return nstr;
+ nstr = strcpy((char *) malloc(strlen(string) + 1), string);
+ return nstr;
}
diff --git a/src/utils/version.c b/src/utils/version.c
index 45e5f7a51ab..9d7c75556b9 100644
--- a/src/utils/version.c
+++ b/src/utils/version.c
@@ -1,25 +1,25 @@
/*-------------------------------------------------------------------------
*
* version.c--
- * Routines to handle Postgres version number.
+ * Routines to handle Postgres version number.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/utils/Attic/version.c,v 1.6 1997/08/27 03:48:50 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/utils/Attic/version.c,v 1.7 1997/09/07 05:04:48 momjian Exp $
*
* NOTES
- * XXX eventually, should be able to handle version identifiers
- * of length != 4.
+ * XXX eventually, should be able to handle version identifiers
+ * of length != 4.
*
- * STANDALONE CODE - do not use error routines as this code is linked with
- * stuff that does not cinterface.a
+ * STANDALONE CODE - do not use error routines as this code is linked with
+ * stuff that does not cinterface.a
*-------------------------------------------------------------------------
*/
#include <sys/types.h>
#include <sys/file.h>
-#include <fcntl.h> /* For open() flags */
+#include <fcntl.h> /* For open() flags */
#include <sys/stat.h>
#include <ctype.h>
#include <string.h>
@@ -29,109 +29,127 @@
#include "postgres.h"
-#include "storage/fd.h" /* for O_ */
+#include "storage/fd.h" /* for O_ */
-#include "version.h"
+#include "version.h"
static void
-PathSetVersionFilePath(const char *path, char *filepathbuf) {
+PathSetVersionFilePath(const char *path, char *filepathbuf)
+{
/*----------------------------------------------------------------------------
PathSetVersionFilePath
-
+
Destructively change "filepathbuf" to contain the concatenation of "path"
and the name of the version file name.
----------------------------------------------------------------------------*/
- if (strlen(path) > (MAXPGPATH - sizeof(PG_VERFILE) - 1))
- *filepathbuf = '\0';
- else
- sprintf(filepathbuf, "%s%c%s", path, SEP_CHAR, PG_VERFILE);
+ if (strlen(path) > (MAXPGPATH - sizeof(PG_VERFILE) - 1))
+ *filepathbuf = '\0';
+ else
+ sprintf(filepathbuf, "%s%c%s", path, SEP_CHAR, PG_VERFILE);
}
void
-ValidatePgVersion(const char *path, char **reason_p) {
+ValidatePgVersion(const char *path, char **reason_p)
+{
/*----------------------------------------------------------------------------
- Determine whether the PG_VERSION file in directory <path> indicates
- a data version compatible with the version of this program.
-
- If compatible, return <*reason_p> == NULL. Otherwise, malloc space,
- fill it with a text string explaining how it isn't compatible (or why
- we can't tell), and return a pointer to that space as <*reason_p>.
+ Determine whether the PG_VERSION file in directory <path> indicates
+ a data version compatible with the version of this program.
+
+ If compatible, return <*reason_p> == NULL. Otherwise, malloc space,
+ fill it with a text string explaining how it isn't compatible (or why
+ we can't tell), and return a pointer to that space as <*reason_p>.
-----------------------------------------------------------------------------*/
- int fd;
- char version[4];
- char full_path[MAXPGPATH+1];
-
- PathSetVersionFilePath(path, full_path);
-
- if ((fd = open(full_path, O_RDONLY,0)) == -1) {
- *reason_p = malloc(200);
- sprintf(*reason_p, "File '%s' does not exist or no read permission.", full_path);
- } else {
- if (read(fd, version, 4) < 4 ||
- !isascii(version[0]) || !isdigit(version[0]) ||
- version[1] != '.' ||
- !isascii(version[2]) || !isdigit(version[2]) ||
- version[3] != '\n') {
-
- *reason_p = malloc(200);
- sprintf(*reason_p, "File '%s' does not have a valid format "
- "for a PG_VERSION file.", full_path);
- } else {
- if (version[2] != '0' + PG_VERSION ||
- version[0] != '0' + PG_RELEASE) {
- *reason_p = malloc(200);
- sprintf(*reason_p,
- "Version number in file '%s' should be %d.%d, "
- "not %c.%c.",
- full_path,
- PG_RELEASE, PG_VERSION, version[0], version[2]);
- } else *reason_p = NULL;
- }
- close(fd);
- }
+ int fd;
+ char version[4];
+ char full_path[MAXPGPATH + 1];
+
+ PathSetVersionFilePath(path, full_path);
+
+ if ((fd = open(full_path, O_RDONLY, 0)) == -1)
+ {
+ *reason_p = malloc(200);
+ sprintf(*reason_p, "File '%s' does not exist or no read permission.", full_path);
+ }
+ else
+ {
+ if (read(fd, version, 4) < 4 ||
+ !isascii(version[0]) || !isdigit(version[0]) ||
+ version[1] != '.' ||
+ !isascii(version[2]) || !isdigit(version[2]) ||
+ version[3] != '\n')
+ {
+
+ *reason_p = malloc(200);
+ sprintf(*reason_p, "File '%s' does not have a valid format "
+ "for a PG_VERSION file.", full_path);
+ }
+ else
+ {
+ if (version[2] != '0' + PG_VERSION ||
+ version[0] != '0' + PG_RELEASE)
+ {
+ *reason_p = malloc(200);
+ sprintf(*reason_p,
+ "Version number in file '%s' should be %d.%d, "
+ "not %c.%c.",
+ full_path,
+ PG_RELEASE, PG_VERSION, version[0], version[2]);
+ }
+ else
+ *reason_p = NULL;
+ }
+ close(fd);
+ }
}
void
-SetPgVersion(const char *path, char **reason_p) {
+SetPgVersion(const char *path, char **reason_p)
+{
/*---------------------------------------------------------------------------
Create the PG_VERSION file in the directory <path>.
-
+
If we fail, allocate storage, fill it with a text string explaining why,
- and return a pointer to that storage as <*reason_p>. If we succeed,
+ and return a pointer to that storage as <*reason_p>. If we succeed,
return *reason_p = NULL.
---------------------------------------------------------------------------*/
- int fd;
- char version[4];
- char full_path[MAXPGPATH+1];
-
- PathSetVersionFilePath(path, full_path);
-
- fd = open(full_path, O_WRONLY|O_CREAT|O_EXCL, 0666);
- if (fd < 0) {
- *reason_p = malloc(100 + strlen(full_path));
- sprintf(*reason_p,
- "Unable to create file '%s', errno from open(): %s (%d).",
- full_path, strerror(errno), errno);
- } else {
- int rc; /* return code from some function we call */
-
- version[0] = '0' + PG_RELEASE;
- version[1] = '.';
- version[2] = '0' + PG_VERSION;
- version[3] = '\n';
- rc = write(fd, version, 4);
- if (rc != 4) {
- *reason_p = malloc(100 + strlen(full_path));
- sprintf(*reason_p,
- "Failed to write to file '%s', after it was already "
- "open. Errno from write(): %s (%d)",
- full_path, strerror(errno), errno);
- } else *reason_p = NULL;
- close(fd);
- }
+ int fd;
+ char version[4];
+ char full_path[MAXPGPATH + 1];
+
+ PathSetVersionFilePath(path, full_path);
+
+ fd = open(full_path, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ if (fd < 0)
+ {
+ *reason_p = malloc(100 + strlen(full_path));
+ sprintf(*reason_p,
+ "Unable to create file '%s', errno from open(): %s (%d).",
+ full_path, strerror(errno), errno);
+ }
+ else
+ {
+ int rc; /* return code from some function we call */
+
+ version[0] = '0' + PG_RELEASE;
+ version[1] = '.';
+ version[2] = '0' + PG_VERSION;
+ version[3] = '\n';
+ rc = write(fd, version, 4);
+ if (rc != 4)
+ {
+ *reason_p = malloc(100 + strlen(full_path));
+ sprintf(*reason_p,
+ "Failed to write to file '%s', after it was already "
+ "open. Errno from write(): %s (%d)",
+ full_path, strerror(errno), errno);
+ }
+ else
+ *reason_p = NULL;
+ close(fd);
+ }
}